diff --git a/.devcontainer/__build_all.sh__ b/.devcontainer/__build_all.sh__ index 50a2bdf374..9ea30b9afc 100644 --- a/.devcontainer/__build_all.sh__ +++ b/.devcontainer/__build_all.sh__ @@ -1,5 +1,5 @@ cd build emcmake cmake .. emmake make -j$(nproc) -echo "Built succesfully, opening index.html" +echo "Built successfully, opening index.html" code index.html \ No newline at end of file diff --git a/.github/workflows/arduino.yml b/.github/workflows/arduino.yml index de90ba4a30..ae772c0cc7 100644 --- a/.github/workflows/arduino.yml +++ b/.github/workflows/arduino.yml @@ -16,7 +16,7 @@ jobs: if: ${{ github.event_name != 'pull_request' || github.repository != github.event.pull_request.head.repo.full_name }} runs-on: ubuntu-24.04 steps: - - uses: actions/checkout@v4 + - uses: actions/checkout@v5 - uses: arduino/arduino-lint-action@v2 with: library-manager: update diff --git a/.github/workflows/build_examples_with_cxx_compiler.yml b/.github/workflows/build_examples_with_cxx_compiler.yml index ac306149e2..f34f82261a 100644 --- a/.github/workflows/build_examples_with_cxx_compiler.yml +++ b/.github/workflows/build_examples_with_cxx_compiler.yml @@ -14,10 +14,9 @@ jobs: build-examples: runs-on: ubuntu-24.04 steps: - - uses: actions/checkout@v4 + - uses: actions/checkout@v5 - name: Generate lv_conf.h run: | - cp lv_conf_template.h lv_conf.h python ./scripts/generate_lv_conf.py \ --template lv_conf_template.h \ --config lv_conf.h \ diff --git a/.github/workflows/build_hardware.yml b/.github/workflows/build_hardware.yml new file mode 100644 index 0000000000..9fbcb499f8 --- /dev/null +++ b/.github/workflows/build_hardware.yml @@ -0,0 +1,40 @@ +name: Hardware Build Test + +# No point on running this on pushes to master +# as we already dispatch a run job for that event +on: + pull_request: + branches: 'master' + +jobs: + run_benchmark: + runs-on: self-hosted + name: Hardware Build Test + steps: + - name: Install Rust toolchain + uses: dtolnay/rust-toolchain@stable + + - name: Install Dependencies + run: | + sudo apt update -y + sudo apt install -y libfontconfig-dev + + - name: Install EJ dispatcher tool + run: | + cargo install ejlv + + - name: Dispatch job + run: | + if [ "${{ github.event_name }}" == "pull_request" ]; then + REPO_URL="${{ github.event.pull_request.head.repo.clone_url }}" + COMMIT_REF="${{ github.event.pull_request.head.sha }}" + else + REPO_URL="${{ github.server_url }}/${{ github.repository }}" + COMMIT_REF="${{ github.sha }}" + fi + + ejlv dispatch-build \ + --socket /ejd/ejd.sock \ + --commit-hash $COMMIT_REF \ + --remote-url $REPO_URL \ + --seconds 1800 diff --git a/.github/workflows/build_micropython.yml b/.github/workflows/build_micropython.yml index 7ba52f68df..db8ecdd4ef 100644 --- a/.github/workflows/build_micropython.yml +++ b/.github/workflows/build_micropython.yml @@ -21,7 +21,7 @@ jobs: port: ['unix', 'stm32', 'rp2', 'esp32'] steps: - uses: ammaraskar/gcc-problem-matcher@master - - uses: actions/setup-python@v5 + - uses: actions/setup-python@v6 with: python-version: '3.12' diff --git a/.github/workflows/ccpp.yml b/.github/workflows/ccpp.yml index 45996b12e1..dd9416582b 100644 --- a/.github/workflows/ccpp.yml +++ b/.github/workflows/ccpp.yml @@ -25,20 +25,21 @@ jobs: 'OPTIONS_16BIT', 'OPTIONS_24BIT', 'OPTIONS_FULL_32BIT', - 'OPTIONS_VG_LITE', 'OPTIONS_SDL'] name: Build ${{ matrix.build_option }} - Ubuntu steps: - - uses: actions/checkout@v4 + - uses: actions/checkout@v5 - uses: ammaraskar/gcc-problem-matcher@master - name: Setup Python - uses: actions/setup-python@v5 + uses: actions/setup-python@v6 with: python-version: '3.12' - name: Install prerequisites run: scripts/install-prerequisites.sh - name: Install pngquant run: scripts/install_pngquant.sh + - name: Verify the environment dependency installation + run: scripts/run_tests.sh --skip-tests - name: Building ${{ matrix.build_option }} run: python tests/main.py --build-option=${{ matrix.build_option }} build --auto-clean @@ -50,8 +51,7 @@ jobs: # See BUILD_OPTIONS in tests/CMakeLists.txt. build_option: ['OPTIONS_16BIT', 'OPTIONS_24BIT', - 'OPTIONS_FULL_32BIT', - 'OPTIONS_VG_LITE'] + 'OPTIONS_FULL_32BIT'] compiler: [gcc, cl] name: Build ${{ matrix.build_option }} - ${{matrix.compiler }} - Windows @@ -60,7 +60,7 @@ jobs: - name: patch freetype vcpkg URL run: (Get-Content C:\vcpkg\ports\freetype\portfile.cmake) -replace 'freedesktop.org', 'com' | Out-File -encoding ASCII C:\vcpkg\ports\freetype\portfile.cmake - - uses: actions/checkout@v4 + - uses: actions/checkout@v5 - name: Install prerequisites run: scripts\install-prerequisites.bat @@ -89,11 +89,11 @@ jobs: container: espressif/idf:v5.3.1 steps: - name: Setup Python - uses: actions/setup-python@v5 + uses: actions/setup-python@v6 with: python-version: '3.12' - name: Clone LVGL as a Component - uses: actions/checkout@v4 + uses: actions/checkout@v5 with: path: components/lvgl - name: Copy IDF Project Example @@ -113,16 +113,18 @@ jobs: '32bit build'] name: Run tests with ${{ matrix.build_config }} steps: - - uses: actions/checkout@v4 + - uses: actions/checkout@v5 - uses: ammaraskar/gcc-problem-matcher@master - name: Setup Python - uses: actions/setup-python@v5 + uses: actions/setup-python@v6 with: python-version: '3.12' - name: Install prerequisites run: scripts/install-prerequisites.sh - name: Install pngquant run: scripts/install_pngquant.sh + - name: Verify the environment dependency installation + run: scripts/run_tests.sh --skip-tests - name: Fix kernel mmap rnd bits # Asan in llvm 14 provided in ubuntu 22.04 is incompatible with # high-entropy ASLR in much newer kernels that GitHub runners are @@ -172,3 +174,9 @@ jobs: echo "Failing the build due to newly generated reference images." exit 1 + - name: Upload coverage reports as artifacts + if: always() + uses: actions/upload-artifact@v4 + with: + name: coverage-reports-${{ matrix.build_config }} + path: tests/report/ diff --git a/.github/workflows/check_bom.yml b/.github/workflows/check_bom.yml index 613e758de5..08b4518b1b 100644 --- a/.github/workflows/check_bom.yml +++ b/.github/workflows/check_bom.yml @@ -16,7 +16,7 @@ jobs: runs-on: ubuntu-24.04 steps: - name: Checkout - uses: actions/checkout@v4 + uses: actions/checkout@v5 with: persist-credentials: false fetch-depth: 0 diff --git a/.github/workflows/check_conf.yml b/.github/workflows/check_conf.yml index 476d566ac2..607faf19bf 100644 --- a/.github/workflows/check_conf.yml +++ b/.github/workflows/check_conf.yml @@ -15,12 +15,12 @@ jobs: runs-on: ubuntu-24.04 steps: - name: Checkout - uses: actions/checkout@v4 + uses: actions/checkout@v5 with: persist-credentials: false fetch-depth: 0 - name: Setup Python - uses: actions/setup-python@v5 + uses: actions/setup-python@v6 with: python-version: 3.12 - name: Generate lv_conf_internal.h diff --git a/.github/workflows/check_properties.yml b/.github/workflows/check_properties.yml index 51f2028916..b43ddf96b9 100644 --- a/.github/workflows/check_properties.yml +++ b/.github/workflows/check_properties.yml @@ -15,7 +15,7 @@ jobs: runs-on: ubuntu-24.04 steps: - name: Checkout - uses: actions/checkout@v4 + uses: actions/checkout@v5 with: persist-credentials: false fetch-depth: 0 diff --git a/.github/workflows/check_style.yml b/.github/workflows/check_style.yml index f81469a1e0..0ae3215de7 100644 --- a/.github/workflows/check_style.yml +++ b/.github/workflows/check_style.yml @@ -15,12 +15,12 @@ jobs: runs-on: ubuntu-24.04 steps: - name: Checkout - uses: actions/checkout@v4 + uses: actions/checkout@v5 with: persist-credentials: false fetch-depth: 0 - name: Checkout astyle - uses: actions/checkout@v4 + uses: actions/checkout@v5 with: repository: lvgl/astyle path: astyle diff --git a/.github/workflows/check_templ.yml b/.github/workflows/check_templ.yml new file mode 100644 index 0000000000..090dfa7999 --- /dev/null +++ b/.github/workflows/check_templ.yml @@ -0,0 +1,28 @@ +name: Compare file templates with file names +on: + push: + pull_request: + +# https://docs.github.com/en/actions/writing-workflows/workflow-syntax-for-github-actions#concurrency +# Ensure that only one commit will be running tests at a time on each PR +concurrency: + group: ${{ github.ref }}-${{ github.workflow }} + cancel-in-progress: true + +jobs: + template-check: + runs-on: ubuntu-24.04 + steps: + - name: Checkout + uses: actions/checkout@v5 + with: + persist-credentials: false + fetch-depth: 0 + - name: Setup Python + uses: actions/setup-python@v6 + with: + python-version: 3.12 + - name: Compare file templates with file names + run: python scripts/lv_templ_check.py --fix + - name: Check that repository is clean + run: git diff --exit-code >/dev/null 2>&1 || (echo "Please fix template issues using scripts/lv_templ_check.py"; false) diff --git a/.github/workflows/close_old_issues.yml b/.github/workflows/close_old_issues.yml index 61ec5f29c1..a2a15eaceb 100644 --- a/.github/workflows/close_old_issues.yml +++ b/.github/workflows/close_old_issues.yml @@ -9,27 +9,33 @@ jobs: if: github.repository == 'lvgl/lvgl' runs-on: ubuntu-24.04 steps: - - uses: actions/stale@v9 + - uses: actions/stale@v10 with: repo-token: ${{ secrets.LVGL_BOT_TOKEN }} stale-issue-message: | We need some feedback on this issue. - Now we mark this as "Abandoned" because there was no activity here for 14 days. + Now we mark this as "Stale" because there was no activity here for 60 days. - Remove the "Stale" label or comment else this will be closed in 7 days. + Remove the "Stale" label or comment else this will be closed in 14 days. + + cc @kisvegabor, @liamHowatt, @uLipe, @AndreCostaaa stale-pr-message: | We need some feedback on this pull request. - Now we mark this as "Abandoned" because there was no activity here for 14 days. + Now we mark this as "Stale" because there was no activity here for 60 days. + + Remove the "Stale" label or comment else this will be closed in 14 days. - Remove the "Abandoned" label or comment else this will be closed in 7 days. + cc @kisvegabor, @liamHowatt, @uLipe, @AndreCostaaa close-issue-message: | As there was no activity here for a while we close this issue. But don't worry, the conversation is still here and you can get back to it at any time. Feel free to comment if you have remarks or ideas on this topic. - days-before-stale: 14 - days-before-close: 7 + + cc @kisvegabor, @liamHowatt, @uLipe, @AndreCostaaa + days-before-stale: 60 + days-before-close: 14 exempt-issue-labels: '🔥 Important' exempt-pr-labels: '🔥 Important' stale-issue-label: '💤 Stale' diff --git a/.github/workflows/compile_docs.yml b/.github/workflows/compile_docs.yml index 0d8552a94b..cd8a42250a 100644 --- a/.github/workflows/compile_docs.yml +++ b/.github/workflows/compile_docs.yml @@ -21,12 +21,12 @@ jobs: runs-on: ubuntu-24.04 steps: - name: Checkout - uses: actions/checkout@v4 + uses: actions/checkout@v5 with: persist-credentials: false fetch-depth: 0 - name: Setup Python - uses: actions/setup-python@v5 + uses: actions/setup-python@v6 with: python-version: '3.12' - name: Cache Python packages @@ -63,14 +63,12 @@ jobs: uses: hendrikmuhs/ccache-action@v1 - name: Build examples (with cache) run: | - if [ "${{ github.event_name }}" == "pull_request" ]; then - REPO_URL="${{ github.event.pull_request.head.repo.clone_url }}" - COMMIT_REF="${{ github.event.pull_request.head.sha }}" - else - REPO_URL="${{ github.server_url }}/${{ github.repository }}" - COMMIT_REF="${{ github.sha }}" - fi - ./scripts/build_html_examples.sh "$REPO_URL" "$COMMIT_REF" + # Grab the current name in case the LVGL folder is not called lvgl + # as it could be the case if this is running from a fork + LVGL_FOLDER=$(pwd) + # Move to the parent folder to fetch emscripten port. + cd .. + ./lvgl/scripts/build_html_examples.sh --symlink $LVGL_FOLDER - name: Build docs run: docs/build.py html - name: Remove .doctrees diff --git a/.github/workflows/esp_upload_component.yml b/.github/workflows/esp_upload_component.yml index ada8cfeb4a..7c783285e5 100644 --- a/.github/workflows/esp_upload_component.yml +++ b/.github/workflows/esp_upload_component.yml @@ -10,7 +10,7 @@ jobs: upload_components: runs-on: ubuntu-24.04 steps: - - uses: actions/checkout@v4 + - uses: actions/checkout@v5 with: submodules: "recursive" diff --git a/.github/workflows/gen_json.yml b/.github/workflows/gen_json.yml index f1879c0a98..ff652052f9 100644 --- a/.github/workflows/gen_json.yml +++ b/.github/workflows/gen_json.yml @@ -15,10 +15,10 @@ jobs: runs-on: ubuntu-24.04 name: Test API JSON steps: - - uses: actions/checkout@v4 + - uses: actions/checkout@v5 - name: Setup Python - uses: actions/setup-python@v5 + uses: actions/setup-python@v6 with: python-version: '3.12' diff --git a/.github/workflows/install.yml b/.github/workflows/install.yml new file mode 100644 index 0000000000..228c89fb84 --- /dev/null +++ b/.github/workflows/install.yml @@ -0,0 +1,48 @@ +name: Install LVGL using CMake + +on: + push: + branches: [ master ] + pull_request: + branches: [ master ] + +concurrency: + group: ${{ github.ref }}-${{ github.workflow }} + cancel-in-progress: true + +jobs: + build-examples: + runs-on: ubuntu-24.04 + steps: + - uses: actions/checkout@v5 + - name: Generate lv_conf.h + run: | + python3 ./scripts/generate_lv_conf.py \ + --template lv_conf_template.h \ + --config lv_conf.h \ + --defaults configs/ci/install/lv_conf.defaults + + - name: Build LVGL + run: | + cmake -B build -DCMAKE_INSTALL_PREFIX=$(pwd)/lvgl-install + cmake --build build -j$(nproc) + - name: Install LVGL + run: cmake --install build + + - name: Build an application with the installed version of LVGL + run: | + echo "#include + #include + #include + #include + int main(void) { + lv_init(); + lv_example_label_1(); + lv_demo_widgets(); + while(1) { + lv_timer_handler(); + } + return 0; + }" >> main.c + # We link with `g++` as thorvg (ThorVG library) contains C++ code that requires C++ runtime symbols + g++ main.c -o main -I$(pwd)/lvgl-install/include -L$(pwd)/lvgl-install/lib -llvgl_thorvg -llvgl_examples -llvgl_demos -llvgl -lm diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index a38f8fd200..2b3e3d4525 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -7,7 +7,7 @@ jobs: runs-on: ubuntu-24.04 steps: - name: Checkout - uses: actions/checkout@v4 + uses: actions/checkout@v5 - name: Automatically close issues that don't follow the issue template uses: lucasbento/auto-close-issues@v1.0.2 with: diff --git a/.github/workflows/makefile.yml b/.github/workflows/makefiles.yml similarity index 88% rename from .github/workflows/makefile.yml rename to .github/workflows/makefiles.yml index 97fc949f14..b98fefcb2c 100644 --- a/.github/workflows/makefile.yml +++ b/.github/workflows/makefiles.yml @@ -18,14 +18,14 @@ jobs: runs-on: ubuntu-24.04 name: Build using Makefile steps: - - uses: actions/checkout@v4 + - uses: actions/checkout@v5 - uses: ammaraskar/gcc-problem-matcher@master - name: Setup Python - uses: actions/setup-python@v5 + uses: actions/setup-python@v6 with: python-version: '3.12' - name: Install prerequisites run: scripts/install-prerequisites.sh - name: Build - working-directory: tests/makefile + working-directory: tests/makefiles run: make test_file diff --git a/.github/workflows/makefile_uefi.yml b/.github/workflows/makefiles_uefi.yml similarity index 88% rename from .github/workflows/makefile_uefi.yml rename to .github/workflows/makefiles_uefi.yml index f6cccb4cc1..e8275475e9 100644 --- a/.github/workflows/makefile_uefi.yml +++ b/.github/workflows/makefiles_uefi.yml @@ -18,10 +18,10 @@ jobs: runs-on: ubuntu-24.04 name: Build using Makefile for UEFI steps: - - uses: actions/checkout@v4 + - uses: actions/checkout@v5 - uses: ammaraskar/gcc-problem-matcher@master - name: Setup Python - uses: actions/setup-python@v5 + uses: actions/setup-python@v6 with: python-version: '3.12' - name: Install prerequisites @@ -29,5 +29,5 @@ jobs: - name: Install clang run: sudo apt-get install clang lld - name: Build - working-directory: tests/makefile_uefi + working-directory: tests/makefiles_uefi run: make -j diff --git a/.github/workflows/perf_emulation.yml b/.github/workflows/perf_emulation.yml new file mode 100644 index 0000000000..f0e1ad0722 --- /dev/null +++ b/.github/workflows/perf_emulation.yml @@ -0,0 +1,102 @@ +name: Emulated Performance Test + +on: + push: + branches: 'master' + pull_request: + branches: 'master' + +concurrency: + group: ${{ github.ref }}-${{ github.workflow }} + cancel-in-progress: true + +jobs: + check_scripts: + runs-on: ubuntu-24.04 + name: ARM Emulated Benchmark - Script Check + strategy: + fail-fast: false + matrix: + test_script: + - scripts/perf/tests/filter_docker_logs/test.sh + # These scripts aren't executed in this workflow directly. Instead, they're run + # by the `Emulated Performance Test Results Handler` workflow. + # That workflow runs in the context of the `master` branch, so this workflow ensures + # the scripts are tested in the PR context before merging. Helping to prevent CI failures in `master` + - scripts/perf/tests/benchmark_results_comment/test.sh + - scripts/perf/tests/serialize_results/test.sh + steps: + - name: Checkout + uses: actions/checkout@v5 + with: + fetch-depth: 0 + - name: Check Script + run: | + pip3 install msgpack==1.1.0 + ./${{ matrix.test_script }} + + run_benchmark: + runs-on: ubuntu-24.04 + name: ARM Emulated Benchmark ${{ matrix.image_type }} - ${{matrix.config }} + needs: check_scripts + strategy: + fail-fast: false + matrix: + include: + - image_type: 32b + image_version : | + main@sha256:61e287d63b19a503cc4505c13bd93f5e05e19513a947feb048d75662c398c862 + config : lv_conf_perf32b + - image_type: 64b + image_version: | + main@sha256:e8663d9c138e98b78d12cc8ad056b7d4b0cc4ad233c6f54202e40ce7606c2670 + config : lv_conf_perf64b + steps: + - name: Checkout + uses: actions/checkout@v5 + with: + fetch-depth: 0 + - name: Generate lv_conf.h + run: | + python scripts/generate_lv_conf.py \ + --template lv_conf_template.h \ + --config configs/ci/perf/lv_conf_perf.h \ + --defaults configs/ci/perf/${{matrix.config}}.defaults + - name: Run Benchmark Demo + run: | + # Mounts the current lvgl source code into the container and runs the demo benchmark + # To add additional build dependencies, modify the `lvperf_dependencies.sh` script + docker run -t --privileged \ + --name so3-lvperf \ + -v /dev:/dev \ + -v $(pwd)/configs/ci/perf/lv_conf_perf.h:/so3/usr/lib/lv_conf.h \ + -v $(pwd):/so3/usr/lib/lvgl \ + -v $(pwd)/scripts/perf/lvperf_dependencies.sh:/so3/install_dependencies.sh \ + ghcr.io/smartobjectoriented/so3-lvperf${{matrix.image_type}}:${{matrix.image_version}} + + - name: Collect Logs + run: | + sudo cat $(docker inspect --format='{{.LogPath}}' so3-lvperf) | python scripts/perf/filter_docker_benchmark_logs.py results-${{matrix.image_type}}-${{matrix.config}}.json + + - name: Upload Results + uses: actions/upload-artifact@v4 + with: + name: results-${{matrix.image_type}}-${{matrix.config}} + path: results-${{matrix.image_type}}-${{matrix.config}}.json + if-no-files-found: error + + save_pr_number: + runs-on: ubuntu-24.04 + if: ${{ github.event_name == 'pull_request' }} + name: ARM Emulated Benchmark - Save PR Number + needs: run_benchmark + steps: + - name: Save PR number + run: | + echo ${{ github.event.number }} > pr_number + + - name: Upload PR number as artifact + uses: actions/upload-artifact@v4 + with: + name: pr_number + path: pr_number diff --git a/.github/workflows/perf_emulation_handle_results.yml b/.github/workflows/perf_emulation_handle_results.yml new file mode 100644 index 0000000000..3fb0ba408e --- /dev/null +++ b/.github/workflows/perf_emulation_handle_results.yml @@ -0,0 +1,170 @@ +name: Emulated Performance Test Results Handler + +on: + workflow_run: + workflows: [Emulated Performance Test] + types: + - completed + +concurrency: + group: ${{ github.event.workflow_run.event }}-${{ github.event.workflow_run.head_branch }}-${{ github.workflow }} + cancel-in-progress: true + +permissions: + contents: write + pull-requests: write + +jobs: + check_scripts: + if: ${{ github.event.workflow_run.conclusion == 'success' }} + runs-on: ubuntu-24.04 + name: ARM Emulated Benchmark - Script Check + strategy: + fail-fast: false + matrix: + test_script: + - scripts/perf/tests/benchmark_results_comment/test.sh + - scripts/perf/tests/serialize_results/test.sh + steps: + - name: Checkout + uses: actions/checkout@v5 + with: + fetch-depth: 0 + - name: Check Script + run: | + pip3 install msgpack==1.1.0 + ./${{ matrix.test_script }} + + handle_results: + needs: check_scripts + if: ${{ github.event.workflow_run.conclusion == 'success' }} + runs-on: ubuntu-24.04 + name: ARM Emulated Benchmark - Handle Results + steps: + - name: Checkout + uses: actions/checkout@v5 + with: + fetch-depth: 0 + + - name: Download Results from master + if: ${{ github.event.workflow_run.event == 'push' && github.event.workflow_run.head_branch == 'master' }} + uses: dawidd6/action-download-artifact@v11 + with: + workflow: perf_emulation.yml + path: artifacts + allow_forks: false + + + - name: Download Results from PR + if: ${{ github.event.workflow_run.event == 'pull_request' }} + uses: dawidd6/action-download-artifact@v11 + with: + workflow: perf_emulation.yml + path: artifacts + # The artifact needs to be downloaded from a PR run that comes from a forked repository + allow_forks: true + + - name: Move JSON files to a single folder + run: | + mkdir input + find artifacts -name "*.json" -exec mv {} input/ \; + + - name: Collect 'master' Results + uses: robinraju/release-downloader@v1 + continue-on-error: true # The release may not exist yet + with: + preRelease: true + tag: emulated-benchmark-latest + fileName: results*.mpk + + - name: Move PR data files to current folder + if: ${{ github.event.workflow_run.event == 'pull_request' }} + run: | + mv artifacts/pr_number/pr_number . + + - name: Prepare Comment + if: ${{ github.event.workflow_run.event == 'pull_request' }} + run: | + pip3 install msgpack==1.1.0 + if ls results*.mpk 1> /dev/null 2>&1; then + python3 scripts/perf/benchmark_results_comment.py \ + --previous results*.mpk \ + --new input/results*.json \ + --output comment.md + else + echo "No previous results found, generating comment without comparison." + python3 scripts/perf/benchmark_results_comment.py \ + --new input/results*.json \ + --output comment.md + fi + - name: Comment PR + if: ${{ github.event.workflow_run.event == 'pull_request' }} + uses: actions/github-script@v8 + with: + script: | + const fs = require('fs'); + const commentPath = 'comment.md'; + const prPath = 'pr_number'; + + if (!fs.existsSync(commentPath)) { + throw new Error('Error: comment.md not found! Exiting.'); + } + if (!fs.existsSync(prPath)) { + throw new Error('Error: pr_number not found! Exiting.'); + } + + const commentBody = fs.readFileSync(commentPath, 'utf8').trim(); + const prNumber = Number(fs.readFileSync(prPath, 'utf8').trim()); + + // Try to find if a comment already exists so we avoid spamming the PR with comments + const { data: comments } = await github.rest.issues.listComments({ + issue_number: prNumber, + owner: context.repo.owner, + repo: context.repo.repo, + }); + const existingComment = comments.find(comment => + comment.body.includes(':robot: This comment was automatically generated by a bot.') + ); + + try { + // Now we either edit the already existing comment or we generate a new one + if (existingComment) { + await github.rest.issues.updateComment({ + comment_id: existingComment.id, + owner: context.repo.owner, + repo: context.repo.repo, + body: commentBody + }); + console.log(`Updated existing comment (ID: ${existingComment.id})`); + } else { + await github.rest.issues.createComment({ + issue_number: prNumber, + owner: context.repo.owner, + repo: context.repo.repo, + body: commentBody + }); + console.log('Created new comment'); + } + } catch (error) { + console.error("Error:", error.message); + } + + - name: Serialize Results + if: ${{ github.event.workflow_run.event == 'push' && github.event.workflow_run.head_branch == 'master' }} + run: | + # Here the input folder already exists from a previous step + pip3 install msgpack==1.1.0 + mkdir output + find . -maxdepth 1 \( -name "results*.mpk" \) -exec mv -t input {} + + python scripts/perf/serialize_results.py --input input --output output --commit-hash ${{ github.sha }} + + - name: Store Results in Benchmark Release + if: ${{ github.event.workflow_run.event == 'push' && github.event.workflow_run.head_branch == 'master' }} + uses: softprops/action-gh-release@v2 + with: + name: Emulated Benchmark Latest + files: output/results*.mpk + tag_name: emulated-benchmark-latest + prerelease: true + body: This pre-release is automatically generated and serves as a repository for benchmark results. + diff --git a/.github/workflows/perf_hardware.yml b/.github/workflows/perf_hardware.yml new file mode 100644 index 0000000000..6f1de85a41 --- /dev/null +++ b/.github/workflows/perf_hardware.yml @@ -0,0 +1,72 @@ +name: Hardware Performance Test + +on: + push: + branches: 'master' + pull_request: + types: [labeled] + +jobs: + run_benchmark: + runs-on: self-hosted + if: | + github.event_name == 'push' || + (github.event_name == 'pull_request' && contains(github.event.label.name, 'Run benchmarks on HW')) + + name: Hardware Performance Benchmark + steps: + - name: Install Rust toolchain + uses: dtolnay/rust-toolchain@stable + + - name: Install Dependencies + run: | + sudo apt update -y + sudo apt install -y libfontconfig-dev + + - name: Install EJ dispatcher tool + run: | + cargo install ejlv + + - name: Dispatch job + run: | + if [ "${{ github.event_name }}" == "pull_request" ]; then + REPO_URL="${{ github.event.pull_request.head.repo.clone_url }}" + COMMIT_REF="${{ github.event.pull_request.head.sha }}" + else + REPO_URL="${{ github.server_url }}/${{ github.repository }}" + COMMIT_REF="${{ github.sha }}" + fi + + ejlv dispatch-run \ + --socket /ejd/ejd.sock \ + --comment-path comment.md \ + --commit-hash $COMMIT_REF \ + --remote-url $REPO_URL \ + --seconds 1800 + + - name: Upload Comment + uses: actions/upload-artifact@v4 + with: + name: comment + path: comment.md + if-no-files-found: error + + - name: Delete Comment + run: | + rm -f comment.md + + save_pr_number: + runs-on: ubuntu-24.04 + if: ${{ github.event_name == 'pull_request' }} + name: HW Benchmark - Save PR Number + steps: + - name: Save PR number + run: | + echo ${{ github.event.number }} > pr_number + + - name: Upload PR number as artifact + uses: actions/upload-artifact@v4 + with: + name: pr_number + path: pr_number + diff --git a/.github/workflows/perf_hardware_comment_pr.yml b/.github/workflows/perf_hardware_comment_pr.yml new file mode 100644 index 0000000000..9c9e35c97c --- /dev/null +++ b/.github/workflows/perf_hardware_comment_pr.yml @@ -0,0 +1,91 @@ +name: Comment PR with Hardware performance tests results + +on: + workflow_run: + workflows: [Hardware Performance Test] + types: + - completed + +concurrency: + group: ${{ github.event.workflow_run.event }}-${{ github.event.workflow_run.head_branch }}-${{ github.workflow }} + cancel-in-progress: true + +permissions: + pull-requests: write + +jobs: + comment_pr: + if: | + github.event.workflow_run.conclusion == 'success' && + github.event.workflow_run.event == 'pull_request' + + runs-on: ubuntu-24.04 + name: Comment PR with HW Performance tests results + steps: + - name: Download Results from PR + uses: dawidd6/action-download-artifact@v11 + with: + workflow: perf_hardware.yml + path: artifacts + # The artifact needs to be downloaded from a PR run that comes from a forked repository + allow_forks: true + + - name: Move artifacts to current folder + if: ${{ github.event.workflow_run.event == 'pull_request' }} + run: | + if [ ! -f "artifacts/pr_number/pr_number" ] || [ ! -f "artifacts/comment/comment.md" ]; then + echo "Required artifact files not found." + echo "This probably means this run was triggered by a label other than 'Run Benchmark on HW'." + echo "Exiting workflow." + echo "results_exist=false" >> $GITHUB_ENV + exit 0 + fi + mv artifacts/pr_number/pr_number . + mv artifacts/comment/comment.md . + echo "results_exist=true" >> $GITHUB_ENV + + - name: Install Dependencies + if: ${{env.results_exist == 'true'}} + run: | + sudo apt update -y + sudo apt install -y libfontconfig-dev + + - name: Install EJ dispatcher tool + if: ${{env.results_exist == 'true'}} + run: | + cargo install ejlv + + - name: Comment PR + if: ${{env.results_exist == 'true'}} + run: | + ejlv comment-pr \ + --comment-path comment.md \ + --pr-number $(cat pr_number) \ + --gh-token "${{ secrets.GITHUB_TOKEN }}" \ + --signature "hw_performance_tests" + + - name: Remove trigger label + if: ${{env.results_exist == 'true'}} + uses: actions/github-script@v8 + with: + script: | + const fs = require('fs'); + const prPath = 'pr_number'; + + if (!fs.existsSync(prPath)) { + throw new Error('Error: pr_number not found! Exiting.'); + } + + const prNumber = Number(fs.readFileSync(prPath, 'utf8').trim()); + + try { + await github.rest.issues.removeLabel({ + owner: context.repo.owner, + repo: context.repo.repo, + issue_number: prNumber, + name: 'Run benchmarks on HW' + }); + console.log('Label removed successfully'); + } catch (error) { + console.log('Label may have already been removed:', error.message); + } diff --git a/.github/workflows/perf_tests.yml b/.github/workflows/perf_tests.yml new file mode 100644 index 0000000000..414c5e46c2 --- /dev/null +++ b/.github/workflows/perf_tests.yml @@ -0,0 +1,35 @@ +name: Performance Tests CI + +on: + push: + branches: [ master ] + pull_request: + branches: [ master ] + +# https://docs.github.com/en/actions/writing-workflows/workflow-syntax-for-github-actions#concurrency +# Ensure that only one commit will be running tests at a time on each PR +concurrency: + group: ${{ github.ref }}-${{ github.workflow }} + cancel-in-progress: true + +jobs: + test-perf: + runs-on: ubuntu-24.04 + strategy: + fail-fast: false + matrix: + # A valid option parameter to the cmake file. + # See BUILD_OPTIONS in tests/perf.py. + build_option: ['OPTIONS_TEST_PERF_32B', + 'OPTIONS_TEST_PERF_64B'] + + name: Perf Tests ${{ matrix.build_option }} - Ubuntu + steps: + - uses: actions/checkout@v5 + - uses: ammaraskar/gcc-problem-matcher@master + - name: Setup Python + uses: actions/setup-python@v6 + with: + python-version: '3.12' + - name: Building ${{ matrix.build_option }} + run: python tests/perf.py --build-option=${{ matrix.build_option }} test diff --git a/.github/workflows/platformio_publish.yaml b/.github/workflows/platformio_publish.yaml index 40dcbc95a6..93ad982390 100644 --- a/.github/workflows/platformio_publish.yaml +++ b/.github/workflows/platformio_publish.yaml @@ -4,14 +4,18 @@ on: - "v[0-9]+.[0-9]+.[0-9]+" # Push events to matching v*, i.e. v1.0, v20.15.10 name: PlatformIO Publish + +env: + PLATFORMIO_AUTH_TOKEN: ${{ secrets.PLATFORMIO_AUTH_TOKEN }} + jobs: build: runs-on: ubuntu-24.04 steps: - name: Checkout code - uses: actions/checkout@v4 + uses: actions/checkout@v5 - name: Install Python - uses: actions/setup-python@v5 + uses: actions/setup-python@v6 with: python-version: '3.12' - name: Install PlatformIO Core diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index cf8f33eeee..9ec37af486 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -12,7 +12,7 @@ jobs: runs-on: ubuntu-24.04 steps: - name: Checkout code - uses: actions/checkout@v4 + uses: actions/checkout@v5 - name: Create Release id: create_release uses: actions/create-release@v1 diff --git a/.github/workflows/release_branch_updater.yml b/.github/workflows/release_branch_updater.yml index fea2790a27..11a8e1b191 100644 --- a/.github/workflows/release_branch_updater.yml +++ b/.github/workflows/release_branch_updater.yml @@ -23,7 +23,7 @@ jobs: steps: - name: Checkout LVGL - uses: actions/checkout@v4 + uses: actions/checkout@v5 with: path: lvgl fetch-depth: 0 # fetch all diff --git a/.github/workflows/verify_font_license.yml b/.github/workflows/verify_font_license.yml index ef8975109b..b3eaba9b27 100644 --- a/.github/workflows/verify_font_license.yml +++ b/.github/workflows/verify_font_license.yml @@ -15,12 +15,12 @@ jobs: runs-on: ubuntu-24.04 steps: - name: Checkout - uses: actions/checkout@v4 + uses: actions/checkout@v5 with: persist-credentials: false fetch-depth: 0 - name: Setup Python - uses: actions/setup-python@v5 + uses: actions/setup-python@v6 with: python-version: 3.12 - name: Run font_license_verify.py diff --git a/.github/workflows/verify_kconfig.yml b/.github/workflows/verify_kconfig.yml index e8615c9fff..fb1998fa4a 100644 --- a/.github/workflows/verify_kconfig.yml +++ b/.github/workflows/verify_kconfig.yml @@ -15,12 +15,12 @@ jobs: runs-on: ubuntu-24.04 steps: - name: Checkout - uses: actions/checkout@v4 + uses: actions/checkout@v5 with: persist-credentials: false fetch-depth: 0 - name: Setup Python - uses: actions/setup-python@v5 + uses: actions/setup-python@v6 with: python-version: 3.12 - name: Check for leading spaces in Kconfig diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 3a2aa8d28b..f15e6f9c63 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -32,6 +32,16 @@ repos: tests/test_images ) types_or: ["c", "header"] + # If a file seems to match lv_templ.c/lv_templ.h, ensure that the parts + # that depend on the file name are correct. + - id: template-check + name: Comparing file templates with file names + entry: python scripts/lv_templ_check.py --fix --quiet + stages: [ commit ] + language: system + pass_filenames: false + verbose: true + types_or: ["c", "header"] - repo: https://github.com/crate-ci/typos rev: v1.16.20 hooks: diff --git a/.typos.toml b/.typos.toml index 6c48b8d7fd..19a61f4faa 100644 --- a/.typos.toml +++ b/.typos.toml @@ -1,10 +1,13 @@ [files] extend-exclude = [ ".git/", - "docs/_static/css/fontawesome.min.css", + "docs/src/_static/css/fontawesome.min.css", + "docs/CHANGELOG.rst", "docs/README_*", + "libs/", + "scripts/gen_json/create_fake_lib_c.py", "src/libs/", - "docs/CHANGELOG.rst" + "zephyr/Kconfig", ] ignore-hidden = false @@ -13,7 +16,6 @@ extend-ignore-re = [ "\\bser[^a-z]", "\\bfle[^a-z]", '"Lorem ipsum .*"', - 'ACI', "Nam consectetur", "U\\+[0-9A-F]{4}", '\{ "[a-z]+", "[^ -~]+" \},', @@ -21,9 +23,25 @@ extend-ignore-re = [ "Rename lv_chart_clear_serie", "rename LV_ROLLER_MODE_INIFINITE", "CARD_INFO_SET\\(&img_multilang_avatar_.*\\)", + "ist", "ACI\\)", + "ACI \\(", + "PNGs", + "STRUCT_FIELDs", +] + +extend-ignore-identifiers-re = [ + "sme_.+", ] [default.extend-words] # https://developer.apple.com/fonts/TrueType-Reference-Manual/RM06/Chap6loca.html "loca" = "loca" +"viewe" = "viewe" + +[default.extend-identifiers] +"aout_p" = "aout_p" +"PN" = "PN" +"thr_tick" = "thr_tick" +"VGLITE_BLIT_SPLIT_THR" = "VGLITE_BLIT_SPLIT_THR" +"yout" = "yout" diff --git a/CMakeLists.txt b/CMakeLists.txt index a3bdfc437a..8a5e49d33b 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -3,7 +3,12 @@ cmake_minimum_required(VERSION 3.12.4) set(CMAKE_WINDOWS_EXPORT_ALL_SYMBOLS ON) if(NOT ESP_PLATFORM) - project(lvgl LANGUAGES C HOMEPAGE_URL https://github.com/lvgl/lvgl) + if(CMAKE_SOURCE_DIR STREQUAL CMAKE_CURRENT_LIST_DIR) + project( + lvgl + LANGUAGES C + HOMEPAGE_URL https://github.com/lvgl/lvgl) + endif() if(NOT (CMAKE_C_COMPILER_ID STREQUAL "MSVC")) enable_language(CXX ASM) else() @@ -15,8 +20,6 @@ set(LVGL_ROOT_DIR ${CMAKE_CURRENT_LIST_DIR}) if(ESP_PLATFORM) include(${CMAKE_CURRENT_LIST_DIR}/env_support/cmake/esp.cmake) -elseif(ZEPHYR_BASE) - include(${CMAKE_CURRENT_LIST_DIR}/env_support/cmake/zephyr.cmake) elseif(MICROPY_DIR) include(${CMAKE_CURRENT_LIST_DIR}/env_support/cmake/micropython.cmake) else() @@ -24,7 +27,7 @@ else() endif() #[[ - unfortunately CMAKE_WINDOWS_EXPORT_ALL_SYMBOLS does not work for global data. + unfortunately CMAKE_WINDOWS_EXPORT_ALL_SYMBOLS does not work for global data. for global data we still need decl specs. Check out the docs to learn more about the limitations of CMAKE_WINDOWS_EXPORT_ALL_SYMBOLS https://cmake.org/cmake/help/latest/prop_tgt/WINDOWS_EXPORT_ALL_SYMBOLS.html#prop_tgt:WINDOWS_EXPORT_ALL_SYMBOLS @@ -33,9 +36,9 @@ endif() For all compiled sources from outside the library (i.e. files which include lvgl headers) we need to use dllimport. We can do this by using CMakes INTERFACE and PRIVATE keyword. ]] -if (MSVC) - target_compile_definitions(lvgl - INTERFACE LV_ATTRIBUTE_EXTERN_DATA=__declspec\(dllimport\) - PRIVATE LV_ATTRIBUTE_EXTERN_DATA=__declspec\(dllexport\) - ) +if(MSVC AND BUILD_SHARED_LIBS) + target_compile_definitions( + lvgl + INTERFACE "LV_ATTRIBUTE_EXTERN_DATA=__declspec(dllimport)" + PRIVATE "LV_ATTRIBUTE_EXTERN_DATA=__declspec(dllexport)") endif() diff --git a/COPYRIGHTS.md b/COPYRIGHTS.md index 0125b6e2c3..358d57b8e9 100644 --- a/COPYRIGHTS.md +++ b/COPYRIGHTS.md @@ -14,10 +14,6 @@ For the licenses, see the corresponding `LICENSE.txt` file in each library’s f - Source: https://github.com/freetype/freetype - Note: Only the interfaces are used; FreeType itself is not part of LVGL. -**GifDec (GIF decoder library)** -- Path: src/libs/gifdec -- Source: https://github.com/lecram/gifdec - **LodePNG (PNG decoder)** - Path: src/libs/lodepng - Source: https://github.com/lvandeve/lodepng @@ -52,3 +48,20 @@ For the licenses, see the corresponding `LICENSE.txt` file in each library’s f - Path: src/stdlib/builtin - Source: https://github.com/mpaland/printf +**LVGL's XML format** +- Path: + - docs/src/details/auxiliary-modules/xml + - src/others/xml + - xmls + +**FT800-FT813 (EVE GPU driver)** +- Path src/libs/FT800-FT813 +- Source: https://github.com/RudolphRiedel/FT800-FT813 + +**AnimatedGIF (GIF decoder library)** +- Path: src/libs/gif/AnimatedGIF +- Source: https://github.com/bitbank2/AnimatedGIF + +**FrogFS (read-only filesystem)** +- Path: src/libs/frogfs +- Source: https://github.com/jkent/frogfs diff --git a/Kconfig b/Kconfig index 3381015c61..5d05e0c844 100644 --- a/Kconfig +++ b/Kconfig @@ -1,4 +1,4 @@ -# Kconfig file for LVGL v9.3.0 +# Kconfig file for LVGL v9.4.0 menu "LVGL configuration" @@ -143,6 +143,8 @@ menu "LVGL configuration" bool "5: WINDOWS" config LV_OS_MQX bool "6: MQX" + config LV_OS_SDL2 + bool "7: SDL2" config LV_OS_CUSTOM bool "255: CUSTOM" endchoice @@ -255,6 +257,11 @@ menu "LVGL configuration" default y depends on LV_USE_DRAW_SW + config LV_DRAW_SW_SUPPORT_ARGB8888_PREMULTIPLIED + bool "Enable support for ARGB8888 premultiplied color format" + default y + depends on LV_USE_DRAW_SW + config LV_DRAW_SW_SUPPORT_L8 bool "Enable support for L8 color format" default y @@ -367,37 +374,6 @@ menu "LVGL configuration" default "" depends on LV_DRAW_SW_ASM_CUSTOM - config LV_USE_DRAW_VGLITE - bool "Use NXP's VG-Lite GPU on iMX RTxxx platforms" - default n - - config LV_USE_VGLITE_BLIT_SPLIT - bool "Enable blit quality degradation workaround recommended for screen's dimension > 352 pixels" - depends on LV_USE_DRAW_VGLITE - default n - - config LV_USE_VGLITE_DRAW_THREAD - bool "Use additional draw thread for VG-Lite processing" - depends on LV_USE_DRAW_VGLITE && !LV_OS_NONE - default y - - config LV_USE_VGLITE_DRAW_ASYNC - bool "Enable VGLite draw async" - depends on LV_USE_VGLITE_DRAW_THREAD - default y - help - Queue multiple tasks and flash them once to the GPU. The task ready state will be send asynchronous to dispatcher. - - config LV_USE_VGLITE_ASSERT - bool "Enable VGLite asserts" - depends on LV_USE_DRAW_VGLITE - default n - - config LV_USE_VGLITE_CHECK_ERROR - bool "Enable VGLite error checks" - depends on LV_USE_DRAW_VGLITE - default n - config LV_USE_PXP bool "Use NXP's PXP on iMX RTxxx platforms" default n @@ -421,14 +397,24 @@ menu "LVGL configuration" bool "Enable PXP asserts" depends on LV_USE_DRAW_PXP - config LV_USE_DRAW_G2D + config LV_USE_G2D bool "Use NXP's G2D on MPU platforms" default n + + config LV_USE_DRAW_G2D + bool "Use G2D for drawing." + depends on LV_USE_G2D + default y + + config LV_USE_ROTATE_G2D + bool "Use G2D to rotate display." + depends on LV_USE_G2D + default n config LV_G2D_HASH_TABLE_SIZE bool "Maximum number of buffers that can be stored for G2D draw unit." default 50 - depends on LV_USE_DRAW_G2D + depends on LV_USE_G2D help Includes the frame buffers and assets. @@ -439,7 +425,7 @@ menu "LVGL configuration" config LV_USE_G2D_ASSERT bool "Enable G2D asserts" - depends on LV_USE_DRAW_G2D + depends on LV_USE_G2D default n config LV_USE_DRAW_DAVE2D @@ -496,6 +482,16 @@ menu "LVGL configuration" default 8 depends on LV_USE_DRAW_VG_LITE + config LV_VG_LITE_DISABLE_VLC_OP_CLOSE + bool "Remove VLC_OP_CLOSE path instruction (Workaround for NXP)" + default n + depends on LV_USE_DRAW_VG_LITE + + config LV_VG_LITE_DISABLE_LINEAR_GRADIENT_EXT + bool "Disable linear gradient extension for some older versions of drivers." + default n + depends on LV_USE_DRAW_VG_LITE + config LV_USE_VECTOR_GRAPHIC bool "Use Vector Graphic APIs" default n @@ -527,6 +523,31 @@ menu "LVGL configuration" bool "Draw using cached OpenGLES textures" default n depends on LV_USE_OPENGLES + + config LV_USE_PPA + bool "Use Espressif's PPA accelerator for ESP SoCs" + default n + + config LV_USE_PPA_IMG + bool "Use Espressif's PPA accelerator for Image draw" + default n + depends on LV_USE_PPA + + config LV_USE_DRAW_EVE + bool "Use EVE FT81X GPU." + default n + + config LV_DRAW_EVE_EVE_GENERATION + int "EVE_GEN value" + default 4 + range 2 4 + depends on LV_USE_DRAW_EVE + + config LV_DRAW_EVE_WRITE_BUFFER_SIZE + int "Max bytes to buffer for each SPI transmission or 0 to disable buffering" + default 2048 + depends on LV_USE_DRAW_EVE + endmenu menu "Feature Configuration" @@ -876,10 +897,6 @@ menu "LVGL configuration" bool "Enable Montserrat 28 compressed" config LV_FONT_DEJAVU_16_PERSIAN_HEBREW bool "Enable Dejavu 16 Persian, Hebrew, Arabic letters" - config LV_FONT_SIMSUN_14_CJK - bool "Enable Simsun 14 CJK" - config LV_FONT_SIMSUN_16_CJK - bool "Enable Simsun 16 CJK" config LV_FONT_SOURCE_HAN_SANS_SC_14_CJK bool "Enable SourceHanSansSC 14 CJK" config LV_FONT_SOURCE_HAN_SANS_SC_16_CJK @@ -968,12 +985,6 @@ menu "LVGL configuration" config LV_FONT_DEFAULT_DEJAVU_16_PERSIAN_HEBREW bool "Dejavu 16 Persian, Hebrew, Arabic letters" select LV_FONT_DEJAVU_16_PERSIAN_HEBREW - config LV_FONT_DEFAULT_SIMSUN_14_CJK - bool "Simsun 14 CJK" - select LV_FONT_SIMSUN_14_CJK - config LV_FONT_DEFAULT_SIMSUN_16_CJK - bool "Simsun 16 CJK" - select LV_FONT_SIMSUN_16_CJK config LV_FONT_DEFAULT_SOURCE_HAN_SANS_SC_14_CJK bool "SourceHanSansSC 14 CJK" select LV_FONT_SOURCE_HAN_SANS_SC_14_CJK @@ -1298,7 +1309,7 @@ menu "LVGL configuration" config LV_USE_FS_STDIO bool "File system on top of stdio API" config LV_FS_STDIO_LETTER - int "Set an upper cased letter on which the drive will accessible (e.g. 65 for 'A')" + int "Set an upper-cased driver-identifier letter for this driver (e.g. 65 for 'A')" default 0 depends on LV_USE_FS_STDIO config LV_FS_STDIO_PATH @@ -1312,7 +1323,7 @@ menu "LVGL configuration" config LV_USE_FS_POSIX bool "File system on top of posix API" config LV_FS_POSIX_LETTER - int "Set an upper cased letter on which the drive will accessible (e.g. 65 for 'A')" + int "Set an upper-cased driver-identifier letter for this driver (e.g. 65 for 'A')" default 0 depends on LV_USE_FS_POSIX config LV_FS_POSIX_PATH @@ -1326,7 +1337,7 @@ menu "LVGL configuration" config LV_USE_FS_WIN32 bool "File system on top of Win32 API" config LV_FS_WIN32_LETTER - int "Set an upper cased letter on which the drive will accessible (e.g. 65 for 'A')" + int "Set an upper-cased driver-identifier letter for this driver (e.g. 65 for 'A')" default 0 depends on LV_USE_FS_WIN32 config LV_FS_WIN32_PATH @@ -1340,7 +1351,7 @@ menu "LVGL configuration" config LV_USE_FS_FATFS bool "File system on top of FatFS" config LV_FS_FATFS_LETTER - int "Set an upper cased letter on which the drive will accessible (e.g. 65 for 'A')" + int "Set an upper-cased driver-identifier letter for this driver (e.g. 65 for 'A')" default 0 depends on LV_USE_FS_FATFS config LV_FS_FATFS_PATH @@ -1354,14 +1365,14 @@ menu "LVGL configuration" config LV_USE_FS_MEMFS bool "File system on top of memory-mapped API" config LV_FS_MEMFS_LETTER - int "Set an upper cased letter on which the drive will accessible (e.g. 65 for 'A')" + int "Set an upper-cased driver-identifier letter for this driver (e.g. 65 for 'A')" default 0 depends on LV_USE_FS_MEMFS config LV_USE_FS_LITTLEFS bool "File system on top of littlefs API" config LV_FS_LITTLEFS_LETTER - int "Set an upper cased letter on which the drive will accessible (e.g. 65 for 'A')" + int "Set an upper-cased driver-identifier letter for this driver (e.g. 65 for 'A')" default 0 depends on LV_USE_FS_LITTLEFS config LV_FS_LITTLEFS_PATH @@ -1371,7 +1382,7 @@ menu "LVGL configuration" config LV_USE_FS_ARDUINO_ESP_LITTLEFS bool "File system on top of Arduino ESP littlefs API" config LV_FS_ARDUINO_ESP_LITTLEFS_LETTER - int "Set an upper cased letter on which the drive will accessible (e.g. 65 for 'A')" + int "Set an upper-cased driver-identifier letter for this driver (e.g. 65 for 'A')" default 0 depends on LV_USE_FS_ARDUINO_ESP_LITTLEFS config LV_FS_ARDUINO_ESP_LITTLEFS_PATH @@ -1381,7 +1392,7 @@ menu "LVGL configuration" config LV_USE_FS_ARDUINO_SD bool "File system on top of Arduino SD API" config LV_FS_ARDUINO_SD_LETTER - int "Set an upper cased letter on which the drive will accessible (e.g. 65 for 'A')" + int "Set an upper-cased driver-identifier letter for this driver (e.g. 65 for 'A')" default 0 depends on LV_USE_FS_ARDUINO_SD config LV_FS_ARDUINO_SD_PATH @@ -1391,10 +1402,17 @@ menu "LVGL configuration" config LV_USE_FS_UEFI bool "File system on top of the UEFI EFI_SIMPLE_FILE_SYSTEM_PROTOCOL" config LV_USE_FS_UEFI_LETTER - int "Set an upper cased letter on which the drive will accessible (e.g. 65 for 'A')" + int "Set an upper-cased driver-identifier letter for this driver (e.g. 65 for 'A')" default 0 depends on LV_USE_FS_UEFI + config LV_USE_FS_FROGFS + bool "FrogFS read-only filesystem" + config LV_FS_FROGFS_LETTER + int "Set an upper-cased driver-identifier letter for this driver (e.g. 65 for 'A')" + default 0 + depends on LV_USE_FS_FROGFS + config LV_USE_LODEPNG bool "PNG decoder library" @@ -1457,12 +1475,12 @@ menu "LVGL configuration" default n depends on LV_USE_TINY_TTF config LV_TINY_TTF_CACHE_GLYPH_CNT - bool "Tiny ttf cache entries count" + int "Tiny ttf cache entries count" default 128 depends on LV_USE_TINY_TTF config LV_TINY_TTF_CACHE_KERNING_CNT - bool "Tiny ttf kerning cache entries count" + int "Tiny ttf kerning cache entries count" default 256 depends on LV_USE_TINY_TTF @@ -1597,6 +1615,10 @@ menu "LVGL configuration" bool "Enable built-in profiler by default" depends on LV_USE_PROFILER_BUILTIN default y + config LV_USE_PROFILER_BUILTIN_POSIX + bool "Enable POSIX profiler port" + depends on LV_USE_PROFILER_BUILTIN + default n config LV_PROFILER_INCLUDE string "Header to include for the profiler" default "lvgl/src/misc/lv_profiler_builtin.h" @@ -1718,6 +1740,8 @@ menu "LVGL configuration" config LV_USE_TEST_SCREENSHOT_COMPARE bool "Enable `lv_test_screenshot_compare`. Requires libpng and a few MB of extra RAM." depends on LV_USE_TEST + config LV_USE_TRANSLATION + bool "Enable text translation support" config LV_USE_XML bool "Enable loading XML UIs runtime" config LV_USE_COLOR_FILTER @@ -1728,7 +1752,7 @@ menu "LVGL configuration" default 9 # LVGL_VERSION_MAJOR config LVGL_VERSION_MINOR int - default 3 # LVGL_VERSION_MINOR + default 4 # LVGL_VERSION_MINOR config LVGL_VERSION_PATCH int default 0 # LVGL_VERSION_PATCH @@ -1857,10 +1881,6 @@ menu "LVGL configuration" bool "Draw client side window decorations, only necessary on Mutter (GNOME)" depends on LV_USE_WAYLAND default n - config LV_WAYLAND_WL_SHELL - bool "Support the legacy wl_shell instead of the default XDG Shell protocol" - depends on LV_USE_WAYLAND - default n config LV_WAYLAND_BUF_COUNT int "Use 1 for single buffer with partial render mode or 2 for double buffer with full render mode" depends on LV_USE_WAYLAND @@ -1885,7 +1905,7 @@ menu "LVGL configuration" config LV_WAYLAND_USE_DMABUF bool "Use DMA buffers for frame buffers" - depends on LV_USE_WAYLAND && LV_USE_DRAW_G2D + depends on LV_USE_WAYLAND && LV_USE_G2D config LV_USE_LINUX_FBDEV bool "Use Linux framebuffer device" @@ -2021,6 +2041,30 @@ menu "LVGL configuration" help Set to 0 to disable cursor, or set to a value greater than 0 to set the cursor size in pixels. + config LV_USE_NUTTX_MOUSE + bool "Use NuttX mouse driver" + depends on LV_USE_NUTTX + default n + + config LV_USE_NUTTX_MOUSE_MOVE_STEP + int "Mouse movement step (pixels)" + depends on LV_USE_NUTTX_MOUSE + range 1 10 + default 1 + help + Set the step size of the mouse movement in pixels. + + config LV_USE_NUTTX_TRACE_FILE + bool "Use NuttX trace file" + depends on LV_USE_NUTTX + depends on LV_USE_PROFILER_BUILTIN + default n + + config LV_NUTTX_TRACE_FILE_PATH + depends on LV_USE_NUTTX_TRACE_FILE + string "NuttX trace file path" + default "/data/lvgl-trace.log" + config LV_USE_LINUX_DRM bool "Use Linux DRM device" default n @@ -2029,6 +2073,14 @@ menu "LVGL configuration" bool "Use TFT_eSPI driver" default n + config LV_USE_LOVYAN_GFX + bool "Use LovyanGFX driver" + default n + config LV_LGFX_USER_INCLUDE + string "Header for LovyanGFX user configuration" + default "lv_lgfx_user.hpp" + depends on LV_USE_LOVYAN_GFX + config LV_USE_EVDEV bool "Use evdev input driver" default n @@ -2067,6 +2119,10 @@ menu "LVGL configuration" bool "Generic MIPI driver" default y if LV_USE_ST7735 || LV_USE_ST7789 || LV_USE_ST7796 || LV_USE_ILI9341 + config LV_USE_NXP_ELCDIF + bool "Use NXP ELCDIF to generate display" + default n + config LV_USE_RENESAS_GLCDC bool "Use Renesas GLCDC driver" default n diff --git a/README.md b/README.md index cc3c1a9033..e02ca5f4bc 100644 --- a/README.md +++ b/README.md @@ -1,8 +1,5 @@ - - -

- English | 中文 | Português do Brasil | 日本語 + English | 中文 | Português do Brasil | 日本語 | עברית


@@ -11,87 +8,85 @@  

Light and Versatile Graphics Library


+

Light and Versatile Graphics Library

+ +
+
   
-
+ +
+

-Website | -Docs | -Forum | -Demos | + Website | + LVGL Pro Editor | + Docs | + Forum | + Demos | Services

-
-## :ledger: Overview +
+ +### Table of Contents +

+ Overview
+ Features
+ Platform Support
+ LVGL Pro Editor
+ Commercial Services
+ Integrating LVGL
+ Examples
+ Contributing +

+ +
+ +## 📒 Overview + +**LVGL** is a free and open-source UI library that enables you to create graphical user interfaces +for any MCUs and MPUs from any vendor on any platform. -**Mature and Well-known**
-LVGL is the most popular free and open source embedded graphics library to create beautiful UIs for any MCU, MPU and display type. It's supported by industry leading vendors and projects like  Arm, STM32, NXP, Espressif, Nuvoton, Arduino, RT-Thread, Zephyr, NuttX, Adafruit and many more. +**Requirements**: LVGL has no external dependencies, which makes it easy to compile for any modern target, +from small MCUs to multi-core Linux-based MPUs with 3D support. For a simple UI, you need only ~100kB RAM, +~200–300kB flash, and a buffer size of 1/10 of the screen for rendering. -**Feature Rich**
-It has all the features to create modern and beautiful GUIs: 30+ built-in widgets, a powerful style system, web inspired layout managers, and a typography system supporting many languages. To integrate LVGL into your platform, all you need is at least 32kB RAM and 128 kB Flash, a C compiler, a frame buffer, and at least an 1/10 screen sized buffer for rendering. +**To get started**, pick a ready-to-use VSCode, Eclipse, or any other project and try out LVGL +on your PC. The LVGL UI code is fully platform-independent, so you can use the same UI code +on embedded targets too. -**Services**
-Our team is ready to help you with graphics design, UI implementation and consulting services. Contact us if you need some support during the development of your next GUI project. +**LVGL Pro** is a complete toolkit to help you build, test, share, and ship UIs faster. +It comes with an XML Editor where you can quickly create and test reusable components, +export C code, or load the XMLs at runtime. Learn more here. -## :rocket: Features +## 💡 Features **Free and Portable** - A fully portable C (C++ compatible) library with no external dependencies. - - Can be compiled to any MCU or MPU, with any (RT)OS. - - Supports monochrome, ePaper, OLED or TFT displays, or even monitors. [Displays](https://docs.lvgl.io/master/details/main-modules/display/index.html) + - Can be compiled for any MCU or MPU, with any (RT)OS. Make, CMake, and simple globbing are all supported. + - Supports monochrome, ePaper, OLED, or TFT displays, or even monitors. [Displays](https://docs.lvgl.io/master/details/main-modules/display/index.html) - Distributed under the MIT license, so you can easily use it in commercial projects too. - - Needs only 32kB RAM and 128 kB Flash, a frame buffer, and at least an 1/10 screen sized buffer for rendering. - - OS, External memory and GPU are supported but not required. - -**Widgets, Styles, Layouts and more** - - 30+ built-in [Widgets](https://docs.lvgl.io/master/details/widgets/index.html):  Button, Label, Slider, Chart, Keyboard, Meter, Arc, Table and many more. - - Flexible [Style system](https://docs.lvgl.io/master/details/common-widget-features/styles/style.html) with  ~100 style properties to customize any part of the widgets in any state. - - [Flexbox](https://docs.lvgl.io/master/details/common-widget-features/layouts/flex.html) and [Grid](https://docs.lvgl.io/master/details/common-widget-features/layouts/grid.html)-like layouts engines to automatically size and position the widgets in a responsive way. - - Texts are rendered with UTF-8 encoding supporting CJK, Thai, Hindi, Arabic, Persian writing systems. - - Word wrapping, kerning, text scrolling, sub-pixel rendering, Pinyin-IME Chinese input, Emojis in texts. - - Rendering engine supporting animations, anti-aliasing, opacity, smooth scrolling, shadows, image transformation, etc   + - Needs only 32kB RAM and 128kB Flash, a frame buffer, and at least a 1/10 screen-sized buffer for rendering. + - OS, external memory, and GPU are supported but not required. + +**Widgets, Styles, Layouts, and More** + - 30+ built-in [Widgets](https://docs.lvgl.io/master/details/widgets/index.html): Button, Label, Slider, Chart, Keyboard, Meter, Arc, Table, and many more. + - Flexible [Style system](https://docs.lvgl.io/master/details/common-widget-features/styles/index.html) with ~100 style properties to customize any part of the widgets in any state. + - [Flexbox](https://docs.lvgl.io/master/details/common-widget-features/layouts/flex.html) and [Grid](https://docs.lvgl.io/master/details/common-widget-features/layouts/grid.html)-like layout engines to automatically size and position the widgets responsively. + - Text is rendered with UTF-8 encoding, supporting CJK, Thai, Hindi, Arabic, and Persian writing systems. + - [Data bindings](https://docs.lvgl.io/master/details/auxiliary-modules/observer/index.html) to easily connect the UI with the application. + - Rendering engine supports animations, anti-aliasing, opacity, smooth scrolling, shadows, image transformation, etc. + - [Powerful 3D rendering engine](https://docs.lvgl.io/master/details/libs/gltf.html) to show [glTF models](https://sketchfab.com/) with OpenGL. - Supports Mouse, Touchpad, Keypad, Keyboard, External buttons, Encoder [Input devices](https://docs.lvgl.io/master/details/main-modules/indev.html). - [Multiple display](https://docs.lvgl.io/master/details/main-modules/display/overview.html#how-many-displays-can-lvgl-use) support. -**Binding and Build Support** - - [MicroPython Binding](https://blog.lvgl.io/2019-02-20/micropython-bindings) exposes LVGL API - - [PikaScript Binding](https://blog.lvgl.io/2022-08-24/pikascript-and-lvgl) python on MCU lighter and easier. - - No custom build system is used. You can build LVGL as you build the other files of your project. - - Support for Make and [CMake](https://docs.lvgl.io/master/details/integration/building/cmake.html) is included out of the box. - - [Develop on PC](https://docs.lvgl.io/master/details/integration/ide/pc-simulator.html) and use the same UI code on embedded hardware. - - Convert the C UI code to HTML file with our [Emscripten port](https://github.com/lvgl/lv_web_emscripten). +## 📦️ Platform Support -**Docs, Tools, and Services** - - Detailed [Documentation](https://docs.lvgl.io/) with [100+ simple examples](https://docs.lvgl.io/master/examples.html) - - [Services](https://lvgl.io/services) such as User interface design, Implementation and Consulting to make UI development simpler and faster. +LVGL has no external dependencies, so it can be easily compiled for any devices and it's also available in many package managers and RTOSes: -## :heart: Sponsor - -If LVGL saved you a lot of time and money or you just had fun using it, consider [Supporting its Development](https://github.com/sponsors/lvgl). - -**How do we spend the donations?**
-Our goal is to provide financial compensation for people who do the most for LVGL. It means not only the maintainers but anyone who implements a great feature should get a payment from the accumulated money. We use the donations to cover our operational costs like servers and related services. - -**How to donate?**
-We use [GitHub Sponsors](https://github.com/sponsors/lvgl) where you can easily send one time or recurring donations. You can also see all of our expenses in a transparent way. - -**How to get paid for your contribution?**
-If someone implements or fixes an issue labeled as [Sponsored](https://github.com/lvgl/lvgl/labels/Sponsored) he or she will get a payment for that work. We estimate the required time, complexity and importance of the issue and set a price accordingly. To jump in just comment on a [Sponsored](https://github.com/lvgl/lvgl/labels/Sponsored) issue saying "Hi, I'd like to deal with it. This is how I'm planning to fix/implement it...". A work is considered ready when it's approved and merged by a maintainer. After that you can submit and expense at [opencollective.com](https://opencollective.com/lvgl) and you will receive the payment in a few days. - -**Organizations supporting LVGL**
-[![Sponsors of LVGL](https://opencollective.com/lvgl/organizations.svg?width=600)](https://opencollective.com/lvgl) - -**Individuals supporting LVGL**
-[![Backers of LVGL](https://contrib.rocks/image?repo=lvgl/lvgl&max=48)](https://opencollective.com/lvgl) - -## :package: Packages -LVGL is available as: - [Arduino library](https://docs.lvgl.io/master/details/integration/framework/arduino.html) - [PlatformIO package](https://registry.platformio.org/libraries/lvgl/lvgl) - [Zephyr library](https://docs.lvgl.io/master/details/integration/os/zephyr.html) @@ -102,367 +97,287 @@ LVGL is available as: - CMSIS-Pack - [RIOT OS package](https://doc.riot-os.org/group__pkg__lvgl.html#details) +## 🚀 LVGL Pro Editor -## :robot: Examples +LVGL Pro is a complete toolkit to build, test, share, and ship embedded UIs efficiently. -See some examples of creating widgets, using layouts and applying styles. You will find C and MicroPython code, and links to try out or edit the examples in an online MicroPython editor. +It consists of four tightly related tools: -For more examples check out the [Examples](https://github.com/lvgl/lvgl/tree/master/examples) folder. +1. **XML Editor**: The heart of LVGL Pro. A desktop app to build components and screens in XML, manage data bindings, translations, animations, tests, and more. Learn more about the [XML Format](https://docs.lvgl.io/master/details/xml/xml/index.html) and the [Editor](https://docs.lvgl.io/master/details/xml/editor/index.html). +2. **Online Viewer**: Run the Editor in your browser, open GitHub projects, and share easily without setting up a developer environment. Visit [https://viewer.lvgl.io](https://viewer.lvgl.io). +3. **CLI Tool**: Generate C code and run tests in CI/CD. See the details [here](https://docs.lvgl.io/master/details/xml/tools/cli.html). +4. **Figma Plugin**: Sync and extract styles directly from Figma. See how it works [here](https://docs.lvgl.io/master/details/xml/tools/figma.html). +Together, these tools let developers build UIs efficiently, test them reliably, and collaborate with team members and customers. -### Hello world label +Learn more at https://pro.lvgl.io -![Simple Hello world label example in LVGL](https://github.com/kisvegabor/test/raw/master/readme_example_1.png) +## 🤝 Commercial Services -
- C code +LVGL LLC provides several types of commercial services to help you with UI development. With 15+ years of experience in the user interface and graphics industry, we can help bring your UI to the next level. -```c -/*Change the active screen's background color*/ -lv_obj_set_style_bg_color(lv_screen_active(), lv_color_hex(0x003a57), LV_PART_MAIN); +- **Graphics design**: Our in-house graphic designers are experts in creating beautiful modern designs that fit your product and the capabilities of your hardware. +- **UI implementation**: We can implement your UI based on the design you or we have created. You can be sure that we will make the most of your hardware and LVGL. If a feature or widget is missing from LVGL, don't worry, we will implement it for you. +- **Consulting and Support**: We also offer consulting to help you avoid costly and time-consuming mistakes during UI development. +- **Board certification**: For companies offering development boards or production-ready kits, we provide board certification to show how the board can run LVGL. -/*Create a white label, set its text and align it to the center*/ -lv_obj_t * label = lv_label_create(lv_screen_active()); -lv_label_set_text(label, "Hello world"); -lv_obj_set_style_text_color(label, lv_color_hex(0xffffff), LV_PART_MAIN); -lv_obj_align(label, LV_ALIGN_CENTER, 0, 0); -``` -
+Check out our [Demos](https://lvgl.io/demos) as references. For more information, take a look at the [Services page](https://lvgl.io/services). -
- MicroPython code | Online Simulator - -```python -# Change the active screen's background color -scr = lv.screen_active() -scr.set_style_bg_color(lv.color_hex(0x003a57), lv.PART.MAIN) - -# Create a white label, set its text and align it to the center -label = lv.label(lv.screen_active()) -label.set_text("Hello world") -label.set_style_text_color(lv.color_hex(0xffffff), lv.PART.MAIN) -label.align(lv.ALIGN.CENTER, 0, 0) -``` -
-
+[Contact us](https://lvgl.io/#contact) and tell us how we can help. -### Button with Click Event +## 🧑‍💻 Integrating LVGL -![LVGL button with label example](https://github.com/kisvegabor/test/raw/master/readme_example_2.gif) +Integrating LVGL is very simple. Just drop it into any project and compile it as you would compile other files. +To configure LVGL, copy `lv_conf_template.h` as `lv_conf.h`, enable the first `#if 0`, and adjust the configs as needed. +(The default config is usually fine.) If available, LVGL can also be used with Kconfig. -
- C code +Once in the project, you can initialize LVGL and create display and input devices as follows: ```c -lv_obj_t * button = lv_button_create(lv_screen_active());                   /*Add a button to the current screen*/ -lv_obj_center(button);                                     /*Set its position*/ -lv_obj_set_size(button, 100, 50);                                  /*Set its size*/ -lv_obj_add_event_cb(button, button_event_cb, LV_EVENT_CLICKED, NULL); /*Assign a callback to the button*/ +#include "lvgl/lvgl.h" /*Define LV_LVGL_H_INCLUDE_SIMPLE to include as "lvgl.h"*/ -lv_obj_t * label = lv_label_create(button);                        /*Add a label to the button*/ -lv_label_set_text(label, "Button");                             /*Set the labels text*/ -lv_obj_center(label);                                           /*Align the label to the center*/ -... +#define TFT_HOR_RES 320 +#define TFT_VER_RES 240 -void button_event_cb(lv_event_t * e) +static uint32_t my_tick_cb(void) { -  printf("Clicked\n"); + return my_get_millisec(); } -``` -
- -
- MicroPython code | Online Simulator -```python -def button_event_cb(e): -  print("Clicked") +static void my_flush_cb(lv_display_t * disp, const lv_area_t * area, uint8_t * px_map) +{ + /*Write px_map to the area->x1, area->x2, area->y1, area->y2 area of the + *frame buffer or external display controller. */ +} -# Create a Button and a Label -button = lv.button(lv.screen_active()) -button.center() -button.set_size(100, 50) -button.add_event_cb(button_event_cb, lv.EVENT.CLICKED, None) +static void my_touch_read_cb(lv_indev_t * indev, lv_indev_data_t * data) +{ + if(my_touch_is_pressed()) { + data->point.x = touchpad_x; + data->point.y = touchpad_y; + data->state = LV_INDEV_STATE_PRESSED; + } else { + data->state = LV_INDEV_STATE_RELEASED; + } +} -label = lv.label(button) -label.set_text("Button") -label.center() -``` -
-
+void main(void) +{ + my_hardware_init(); -### Checkboxes with Layout -![Checkboxes with layout in LVGL](https://github.com/kisvegabor/test/raw/master/readme_example_3.gif) + /*Initialize LVGL*/ + lv_init(); -
- C code + /*Set millisecond-based tick source for LVGL so that it can track time.*/ + lv_tick_set_cb(my_tick_cb); -```c + /*Create a display where screens and widgets can be added*/ + lv_display_t * display = lv_display_create(TFT_HOR_RES, TFT_VER_RES); -lv_obj_set_flex_flow(lv_screen_active(), LV_FLEX_FLOW_COLUMN); -lv_obj_set_flex_align(lv_screen_active(), LV_FLEX_ALIGN_CENTER, LV_FLEX_ALIGN_START, LV_FLEX_ALIGN_CENTER); + /*Add rendering buffers to the screen. + *Here adding a smaller partial buffer assuming 16-bit (RGB565 color format)*/ + static uint8_t buf[TFT_HOR_RES * TFT_VER_RES / 10 * 2]; /* x2 because of 16-bit color depth */ + lv_display_set_buffers(display, buf, NULL, sizeof(buf), LV_DISPLAY_RENDER_MODE_PARTIAL); -lv_obj_t * cb; -cb = lv_checkbox_create(lv_screen_active()); -lv_checkbox_set_text(cb, "Apple"); -lv_obj_add_event_cb(cb, event_handler, LV_EVENT_ALL, NULL); + /*Add a callback that can flush the content from `buf` when it has been rendered*/ + lv_display_set_flush_cb(display, my_flush_cb); -cb = lv_checkbox_create(lv_screen_active()); -lv_checkbox_set_text(cb, "Banana"); -lv_obj_add_state(cb, LV_STATE_CHECKED); -lv_obj_add_event_cb(cb, event_handler, LV_EVENT_ALL, NULL); + /*Create an input device for touch handling*/ + lv_indev_t * indev = lv_indev_create(); + lv_indev_set_type(indev, LV_INDEV_TYPE_POINTER); + lv_indev_set_read_cb(indev, my_touch_read_cb); -cb = lv_checkbox_create(lv_screen_active()); -lv_checkbox_set_text(cb, "Lemon"); -lv_obj_add_state(cb, LV_STATE_DISABLED); -lv_obj_add_event_cb(cb, event_handler, LV_EVENT_ALL, NULL); + /*The drivers are in place; now we can create the UI*/ + lv_obj_t * label = lv_label_create(lv_screen_active()); + lv_label_set_text(label, "Hello world"); + lv_obj_center(label); -cb = lv_checkbox_create(lv_screen_active()); -lv_obj_add_state(cb, LV_STATE_CHECKED | LV_STATE_DISABLED); -lv_checkbox_set_text(cb, "Melon\nand a new line"); -lv_obj_add_event_cb(cb, event_handler, LV_EVENT_ALL, NULL); + /*Execute the LVGL-related tasks in a loop*/ + while(1) { + lv_timer_handler(); + my_sleep_ms(5); /*Wait a little to let the system breathe*/ + } +} ``` -
+## 🤖 Examples -
- MicroPython code | Online Simulator - -```python -def event_handler(e): - code = e.get_code() - obj = e.get_target_obj() - if code == lv.EVENT.VALUE_CHANGED: - txt = obj.get_text() - if obj.get_state() & lv.STATE.CHECKED: - state = "Checked" - else: - state = "Unchecked" - print(txt + ":" + state) - - -lv.screen_active().set_flex_flow(lv.FLEX_FLOW.COLUMN) -lv.screen_active().set_flex_align(lv.FLEX_ALIGN.CENTER, lv.FLEX_ALIGN.START, lv.FLEX_ALIGN.CENTER) - -cb = lv.checkbox(lv.screen_active()) -cb.set_text("Apple") -cb.add_event_cb(event_handler, lv.EVENT.ALL, None) - -cb = lv.checkbox(lv.screen_active()) -cb.set_text("Banana") -cb.add_state(lv.STATE.CHECKED) -cb.add_event_cb(event_handler, lv.EVENT.ALL, None) - -cb = lv.checkbox(lv.screen_active()) -cb.set_text("Lemon") -cb.add_state(lv.STATE.DISABLED) -cb.add_event_cb(event_handler, lv.EVENT.ALL, None) - -cb = lv.checkbox(lv.screen_active()) -cb.add_state(lv.STATE.CHECKED | lv.STATE.DISABLED) -cb.set_text("Melon") -cb.add_event_cb(event_handler, lv.EVENT.ALL, None) -``` +You can check out more than 100 examples at https://docs.lvgl.io/master/examples.html + +The Online Viewer also contains tutorials to easily learn XML: https://viewer.lvgl.io/ -
-
-### Styling a Slider -![Styling a slider with LVGL](https://github.com/kisvegabor/test/raw/master/readme_example_4.gif) +### Hello World Button with an Event +image
C code -```c -lv_obj_t * slider = lv_slider_create(lv_screen_active()); -lv_slider_set_value(slider, 70, LV_ANIM_OFF); -lv_obj_set_size(slider, 300, 20); -lv_obj_center(slider); + ```c +static void button_clicked_cb(lv_event_t * e) +{ + printf("Clicked\n"); +} -/*Add local styles to MAIN part (background rectangle)*/ -lv_obj_set_style_bg_color(slider, lv_color_hex(0x0F1215), LV_PART_MAIN); -lv_obj_set_style_bg_opa(slider, 255, LV_PART_MAIN); -lv_obj_set_style_border_color(slider, lv_color_hex(0x333943), LV_PART_MAIN); -lv_obj_set_style_border_width(slider, 5, LV_PART_MAIN); -lv_obj_set_style_pad_all(slider, 5, LV_PART_MAIN); - -/*Create a reusable style sheet for the INDICATOR part*/ -static lv_style_t style_indicator; -lv_style_init(&style_indicator); -lv_style_set_bg_color(&style_indicator, lv_color_hex(0x37B9F5)); -lv_style_set_bg_grad_color(&style_indicator, lv_color_hex(0x1464F0)); -lv_style_set_bg_grad_dir(&style_indicator, LV_GRAD_DIR_HOR); -lv_style_set_shadow_color(&style_indicator, lv_color_hex(0x37B9F5)); -lv_style_set_shadow_width(&style_indicator, 15); -lv_style_set_shadow_spread(&style_indicator, 5); -4 -/*Add the style sheet to the slider's INDICATOR part*/ -lv_obj_add_style(slider, &style_indicator, LV_PART_INDICATOR); - -/*Add the same style to the KNOB part too and locally overwrite some properties*/ -lv_obj_add_style(slider, &style_indicator, LV_PART_KNOB); - -lv_obj_set_style_outline_color(slider, lv_color_hex(0x0096FF), LV_PART_KNOB); -lv_obj_set_style_outline_width(slider, 3, LV_PART_KNOB); -lv_obj_set_style_outline_pad(slider, -5, LV_PART_KNOB); -lv_obj_set_style_shadow_spread(slider, 2, LV_PART_KNOB); -``` +[...] + + lv_obj_t * button = lv_button_create(lv_screen_active()); + lv_obj_center(button); + lv_obj_add_event_cb(button, button_clicked_cb, LV_EVENT_CLICKED, NULL); + lv_obj_t * label = lv_label_create(button); + lv_label_set_text(label, "Hello from LVGL!"); +```
- MicroPython code | -Online Simulator - - - -```python -# Create a slider and add the style -slider = lv.slider(lv.screen_active()) -slider.set_value(70, lv.ANIM.OFF) -slider.set_size(300, 20) -slider.center() - -# Add local styles to MAIN part (background rectangle) -slider.set_style_bg_color(lv.color_hex(0x0F1215), lv.PART.MAIN) -slider.set_style_bg_opa(255, lv.PART.MAIN) -slider.set_style_border_color(lv.color_hex(0x333943), lv.PART.MAIN) -slider.set_style_border_width(5, lv.PART.MAIN) -slider.set_style_pad_all(5, lv.PART.MAIN) - -# Create a reusable style sheet for the INDICATOR part -style_indicator = lv.style_t() -style_indicator.init() -style_indicator.set_bg_color(lv.color_hex(0x37B9F5)) -style_indicator.set_bg_grad_color(lv.color_hex(0x1464F0)) -style_indicator.set_bg_grad_dir(lv.GRAD_DIR.HOR) -style_indicator.set_shadow_color(lv.color_hex(0x37B9F5)) -style_indicator.set_shadow_width(15) -style_indicator.set_shadow_spread(5) - -# Add the style sheet to the slider's INDICATOR part -slider.add_style(style_indicator, lv.PART.INDICATOR) -slider.add_style(style_indicator, lv.PART.KNOB) - -# Add the same style to the KNOB part too and locally overwrite some properties -slider.set_style_outline_color(lv.color_hex(0x0096FF), lv.PART.KNOB) -slider.set_style_outline_width(3, lv.PART.KNOB) -slider.set_style_outline_pad(-5, lv.PART.KNOB) -slider.set_style_shadow_spread(2, lv.PART.KNOB) + In XML with LVGL Pro + +```xml + + + + + + + + ``` +
-
-### English, Hebrew (mixed LTR-RTL) and Chinese texts +### Styled Slider with Data-binding -![English, Hebrew and Chinese texts with LVGL](https://github.com/kisvegabor/test/raw/master/readme_example_5.png) +image
C code ```c -lv_obj_t * ltr_label = lv_label_create(lv_screen_active()); -lv_label_set_text(ltr_label, "In modern terminology, a microcontroller is similar to a system on a chip (SoC)."); -lv_obj_set_style_text_font(ltr_label, &lv_font_montserrat_16, 0); -lv_obj_set_width(ltr_label, 310); -lv_obj_align(ltr_label, LV_ALIGN_TOP_LEFT, 5, 5); - -lv_obj_t * rtl_label = lv_label_create(lv_screen_active()); -lv_label_set_text(rtl_label,"מעבד, או בשמו המלא יחידת עיבוד מרכזית (באנגלית: CPU - Central Processing Unit)."); -lv_obj_set_style_base_dir(rtl_label, LV_BASE_DIR_RTL, 0); -lv_obj_set_style_text_font(rtl_label, &lv_font_dejavu_16_persian_hebrew, 0); -lv_obj_set_width(rtl_label, 310); -lv_obj_align(rtl_label, LV_ALIGN_LEFT_MID, 5, 0); - -lv_obj_t * cz_label = lv_label_create(lv_screen_active()); -lv_label_set_text(cz_label, - "嵌入式系统(Embedded System),\n是一种嵌入机械或电气系统内部、具有专一功能和实时计算性能的计算机系统。"); -lv_obj_set_style_text_font(cz_label, &lv_font_source_han_sans_sc_16_cjk, 0); -lv_obj_set_width(cz_label, 310); -lv_obj_align(cz_label, LV_ALIGN_BOTTOM_LEFT, 5, -5); -``` - -
- -
- MicroPython code | Online Simulator - -```python -ltr_label = lv.label(lv.screen_active()) -ltr_label.set_text("In modern terminology, a microcontroller is similar to a system on a chip (SoC).") -ltr_label.set_style_text_font(lv.font_montserrat_16, 0); +static void my_observer_cb(lv_observer_t * observer, lv_subject_t * subject) +{ + printf("Slider value: %d\n", lv_subject_get_int(subject)); +} -ltr_label.set_width(310) -ltr_label.align(lv.ALIGN.TOP_LEFT, 5, 5) +[...] -rtl_label = lv.label(lv.screen_active()) -rtl_label.set_text("מעבד, או בשמו המלא יחידת עיבוד מרכזית (באנגלית: CPU - Central Processing Unit).") -rtl_label.set_style_base_dir(lv.BASE_DIR.RTL, 0) -rtl_label.set_style_text_font(lv.font_dejavu_16_persian_hebrew, 0) -rtl_label.set_width(310) -rtl_label.align(lv.ALIGN.LEFT_MID, 5, 0) +static lv_subject_t subject_value; +lv_subject_init_int(&subject_value, 35); +lv_subject_add_observer(&subject_value, my_observer_cb, NULL); -font_hans_sans_16_cjk = lv.font_load("S:../../assets/font/lv_font_source_han_sans_sc_16_cjk.fnt") +lv_style_t style_base; +lv_style_init(&style_base); +lv_style_set_bg_color(&style_base, lv_color_hex(0xff8800)); +lv_style_set_bg_opa(&style_base, 255); +lv_style_set_radius(&style_base, 4); -cz_label = lv.label(lv.screen_active()) -cz_label.set_style_text_font(font_hans_sans_16_cjk, 0) -cz_label.set_text("嵌入式系统(Embedded System),\n是一种嵌入机械或电气系统内部、具有专一功能和实时计算性能的计算机系统。") -cz_label.set_width(310) -cz_label.align(lv.ALIGN.BOTTOM_LEFT, 5, -5) +lv_obj_t * slider = lv_slider_create(lv_screen_active()); +lv_obj_center(slider); +lv_obj_set_size(slider, lv_pct(80), 16); +lv_obj_add_style(slider, &style_base, LV_PART_INDICATOR); +lv_obj_add_style(slider, &style_base, LV_PART_KNOB); +lv_obj_add_style(slider, &style_base, 0); +lv_obj_set_style_bg_opa(slider, LV_OPA_50, 0); +lv_obj_set_style_border_width(slider, 3, LV_PART_KNOB); +lv_obj_set_style_border_color(slider, lv_color_hex3(0xfff), LV_PART_KNOB); +lv_slider_bind_value(slider, &subject_value); +lv_obj_t * label = lv_label_create(lv_screen_active()); +lv_obj_align(label, LV_ALIGN_CENTER, 0, -30); +lv_label_bind_text(label, &subject_value, "Temperature: %d °C"); ``` -
- -## :arrow_forward: Get started -This list will guide you to get started with LVGL step-by-step. - -**Get Familiar with LVGL** - 1. Check the [Online demos](https://lvgl.io/demos) to see LVGL in action (3 minutes). - 2. Read the [Introduction](https://docs.lvgl.io/master/intro/index.html) page of the documentation (5 minutes). - 3. Get familiar with the basics on the [Quick overview](https://docs.lvgl.io/master/intro/getting_started.html#lvgl-basics) page (15 minutes). - -**Start to Use LVGL** + - 4. Set up a [Simulator](https://docs.lvgl.io/master/details/integration/ide/pc-simulator.html#simulator) (10 minutes). - 5. Try out some [Examples](https://github.com/lvgl/lvgl/tree/master/examples). - 6. Port LVGL to a board. See the [Porting](https://docs.lvgl.io/master/details/integration/adding-lvgl-to-your-project/index.html) guide or check out the ready-to-use [Projects](https://github.com/lvgl?q=lv_port_). +
+ In XML with LVGL Pro + +```xml + + + - - - - + + + + + + + + + + + + + - \ No newline at end of file diff --git a/examples/porting/lv_port_disp_template.c b/examples/porting/lv_port_disp_template.c index 5cb6ea5991..d53be0c109 100644 --- a/examples/porting/lv_port_disp_template.c +++ b/examples/porting/lv_port_disp_template.c @@ -1,5 +1,5 @@ /** - * @file lv_port_disp_templ.c + * @file lv_port_disp_template.c * */ diff --git a/examples/porting/lv_port_fs_template.c b/examples/porting/lv_port_fs_template.c index fab2cb39f0..c1cf06d700 100644 --- a/examples/porting/lv_port_fs_template.c +++ b/examples/porting/lv_port_fs_template.c @@ -1,5 +1,5 @@ /** - * @file lv_port_fs_templ.c + * @file lv_port_fs_template.c * */ diff --git a/examples/porting/lv_port_indev_template.c b/examples/porting/lv_port_indev_template.c index 6415c4f0e9..e6f66cad40 100644 --- a/examples/porting/lv_port_indev_template.c +++ b/examples/porting/lv_port_indev_template.c @@ -1,5 +1,5 @@ /** - * @file lv_port_indev_templ.c + * @file lv_port_indev_template.c * */ diff --git a/examples/porting/osal/lv_example_osal.c b/examples/porting/osal/lv_example_osal.c index 7d27b49ed8..0ad8965cb7 100644 --- a/examples/porting/osal/lv_example_osal.c +++ b/examples/porting/osal/lv_example_osal.c @@ -76,7 +76,7 @@ static void increment_thread_entry(void * user_data) uint32_t press_count = 0; lv_lock(); - counter_label = lv_label_create(lv_scr_act()); + counter_label = lv_label_create(lv_screen_active()); lv_obj_align(counter_label, LV_ALIGN_CENTER, 0, 0); lv_label_set_text_fmt(counter_label, "Pressed %" LV_PRIu32 " times", press_count); lv_unlock(); diff --git a/examples/scroll/lv_example_scroll_1.c b/examples/scroll/lv_example_scroll_1.c index 100376f947..28f4764613 100644 --- a/examples/scroll/lv_example_scroll_1.c +++ b/examples/scroll/lv_example_scroll_1.c @@ -78,8 +78,8 @@ void lv_example_scroll_1(void) lv_label_set_text(label, "Bottom"); lv_obj_center(label); - /* When LV_OBJ_FLAG_SCROLL_ELASTIC is cleared, scrolling does not go past edge bounaries. */ - /* lv_obj_clear_flag(panel, LV_OBJ_FLAG_SCROLL_ELASTIC); */ + /* When LV_OBJ_FLAG_SCROLL_ELASTIC is cleared, scrolling does not go past edge boundaries. */ + /* lv_obj_remove_flag(panel, LV_OBJ_FLAG_SCROLL_ELASTIC); */ /* Call `scroll_update_cb` while panel is being scrolled. */ lv_obj_add_event_cb(panel, scroll_update_cb, LV_EVENT_SCROLL, NULL); diff --git a/examples/scroll/lv_example_scroll_3.c b/examples/scroll/lv_example_scroll_3.c index 04c8d92c4a..c20a48e649 100644 --- a/examples/scroll/lv_example_scroll_3.c +++ b/examples/scroll/lv_example_scroll_3.c @@ -15,7 +15,8 @@ static void float_button_event_cb(lv_event_t * e) lv_obj_t * list_btn = lv_list_add_button(list, LV_SYMBOL_AUDIO, buf); btn_cnt++; - lv_obj_move_foreground(float_btn); + /* Move the button to the foreground*/ + lv_obj_move_to_index(float_btn, -1); lv_obj_scroll_to_view(list_btn, LV_ANIM_ON); } diff --git a/examples/scroll/lv_example_scroll_7.c b/examples/scroll/lv_example_scroll_7.c index bfb3d83340..8cdc591567 100644 --- a/examples/scroll/lv_example_scroll_7.c +++ b/examples/scroll/lv_example_scroll_7.c @@ -114,7 +114,7 @@ void lv_example_scroll_7(void) lv_obj_align(low_label, LV_ALIGN_BOTTOM_LEFT, 10, -10); load_item(obj, 3); - /* These counters hold the the highest/lowest number currently loaded. */ + /* These counters hold the highest/lowest number currently loaded. */ top_num = 3; bottom_num = 3; diff --git a/examples/scroll/lv_example_scroll_8.c b/examples/scroll/lv_example_scroll_8.c index cf4296bfeb..1f06bcf209 100644 --- a/examples/scroll/lv_example_scroll_8.c +++ b/examples/scroll/lv_example_scroll_8.c @@ -14,7 +14,7 @@ static int32_t get_content_width(lv_obj_t * cont) { int32_t w = 0; - int32_t pad_column = lv_obj_get_style_pad_column(cont, LV_PART_MAIN); // 列间距 + int32_t pad_column = lv_obj_get_style_pad_column(cont, LV_PART_MAIN); int32_t total = (int32_t)lv_obj_get_child_count(cont); for(int32_t i = 0; i < total; i++) { diff --git a/examples/styles/lv_example_style_19.c b/examples/styles/lv_example_style_19.c index c04dde1c6c..db841793d2 100644 --- a/examples/styles/lv_example_style_19.c +++ b/examples/styles/lv_example_style_19.c @@ -1,5 +1,5 @@ #include "../lv_examples.h" -#if LV_BUILD_EXAMPLES && LV_USE_SLIDER +#if LV_BUILD_EXAMPLES && LV_USE_SLIDER && LV_USE_LOG /** * Test between a full background modal and a recolor modal diff --git a/examples/widgets/arc/lv_example_arc_3.c b/examples/widgets/arc/lv_example_arc_3.c index 77550027ea..9bcc9d3a35 100644 --- a/examples/widgets/arc/lv_example_arc_3.c +++ b/examples/widgets/arc/lv_example_arc_3.c @@ -61,7 +61,7 @@ static void arc_click_cb(lv_event_t * e) lv_anim_init(&a); lv_anim_set_var(&a, anim_back); lv_anim_set_exec_cb(&a, anim_move_cb); - lv_anim_set_time(&a, 200); + lv_anim_set_duration(&a, 200); lv_anim_set_values(&a, 0, 100); lv_anim_set_deleted_cb(&a, anim_cleanup_cb); lv_anim_start(&a); @@ -94,7 +94,7 @@ static void arc_click_cb(lv_event_t * e) lv_anim_init(&a); lv_anim_set_var(&a, anim_data); lv_anim_set_exec_cb(&a, anim_move_cb); - lv_anim_set_time(&a, 200); + lv_anim_set_duration(&a, 200); lv_anim_set_values(&a, 0, 100); lv_anim_set_deleted_cb(&a, anim_cleanup_cb); lv_anim_start(&a); diff --git a/examples/widgets/arclabel/index.rst b/examples/widgets/arclabel/index.rst index cb2c0abd67..ccaa8e014f 100644 --- a/examples/widgets/arclabel/index.rst +++ b/examples/widgets/arclabel/index.rst @@ -2,5 +2,5 @@ Simple Arc Label ---------------- .. lv_example:: widgets/arclabel/lv_example_arclabel_1 -:language: c -:description: A simple example to demonstrate the use of an arc label. + :language: c + :description: A simple example to demonstrate the use of an arc label. diff --git a/examples/widgets/bar/lv_example_bar_7.c b/examples/widgets/bar/lv_example_bar_7.c index 86d1e037aa..618a1e9198 100644 --- a/examples/widgets/bar/lv_example_bar_7.c +++ b/examples/widgets/bar/lv_example_bar_7.c @@ -6,15 +6,13 @@ */ void lv_example_bar_7(void) { - lv_obj_t * label; - lv_obj_t * bar_tob = lv_bar_create(lv_screen_active()); - lv_obj_set_size(bar_tob, 20, 200); + lv_obj_set_size(bar_tob, 20, 180); lv_bar_set_range(bar_tob, 100, 0); lv_bar_set_value(bar_tob, 70, LV_ANIM_OFF); - lv_obj_align(bar_tob, LV_ALIGN_CENTER, 0, -30); + lv_obj_align(bar_tob, LV_ALIGN_CENTER, 0, 10); - label = lv_label_create(lv_screen_active()); + lv_obj_t * label = lv_label_create(lv_screen_active()); lv_label_set_text(label, "From top to bottom"); lv_obj_align_to(label, bar_tob, LV_ALIGN_OUT_TOP_MID, 0, -5); } diff --git a/examples/widgets/canvas/lv_example_canvas_8.c b/examples/widgets/canvas/lv_example_canvas_8.c index ef8675f782..878ae0ced4 100644 --- a/examples/widgets/canvas/lv_example_canvas_8.c +++ b/examples/widgets/canvas/lv_example_canvas_8.c @@ -24,7 +24,7 @@ void lv_example_canvas_8(void) lv_layer_t layer; lv_canvas_init_layer(canvas, &layer); - lv_vector_dsc_t * dsc = lv_vector_dsc_create(&layer); + lv_draw_vector_dsc_t * dsc = lv_draw_vector_dsc_create(&layer); lv_vector_path_t * path = lv_vector_path_create(LV_VECTOR_PATH_QUALITY_MEDIUM); lv_fpoint_t pts[] = {{10, 10}, {130, 130}, {10, 130}}; @@ -33,12 +33,12 @@ void lv_example_canvas_8(void) lv_vector_path_line_to(path, &pts[2]); lv_vector_path_close(path); - lv_vector_dsc_set_fill_color(dsc, lv_color_make(0x00, 0x80, 0xff)); - lv_vector_dsc_add_path(dsc, path); + lv_draw_vector_dsc_set_fill_color(dsc, lv_color_make(0x00, 0x80, 0xff)); + lv_draw_vector_dsc_add_path(dsc, path); lv_draw_vector(dsc); lv_vector_path_delete(path); - lv_vector_dsc_delete(dsc); + lv_draw_vector_dsc_delete(dsc); lv_canvas_finish_layer(canvas, &layer); } diff --git a/examples/widgets/chart/lv_example_chart_3.c b/examples/widgets/chart/lv_example_chart_3.c index e1e624d277..4e4458e75a 100644 --- a/examples/widgets/chart/lv_example_chart_3.c +++ b/examples/widgets/chart/lv_example_chart_3.c @@ -20,44 +20,49 @@ static void event_cb(lv_event_t * e) LV_LOG_USER("Selected point %d", (int)id); lv_chart_series_t * ser = lv_chart_get_series_next(chart, NULL); + int32_t value = 0; while(ser) { lv_point_t p; lv_chart_get_point_pos_by_id(chart, ser, id, &p); int32_t * y_array = lv_chart_get_series_y_array(chart, ser); - int32_t value = y_array[id]; + if(y_array[id] != LV_CHART_POINT_NONE && y_array[id] >= 0) { - /*Draw a rectangle above the clicked point*/ - lv_layer_t * layer = lv_event_get_layer(e); - lv_draw_rect_dsc_t draw_rect_dsc; - lv_draw_rect_dsc_init(&draw_rect_dsc); - draw_rect_dsc.bg_color = lv_color_black(); - draw_rect_dsc.bg_opa = LV_OPA_50; - draw_rect_dsc.radius = 3; + /*Accumulate the values to show the rectangles at the top of each segment*/ + value += y_array[id]; - lv_area_t chart_obj_coords; - lv_obj_get_coords(chart, &chart_obj_coords); - lv_area_t rect_area; - rect_area.x1 = chart_obj_coords.x1 + p.x - 20; - rect_area.x2 = chart_obj_coords.x1 + p.x + 20; - rect_area.y1 = chart_obj_coords.y1 + p.y - 30; - rect_area.y2 = chart_obj_coords.y1 + p.y - 10; - lv_draw_rect(layer, &draw_rect_dsc, &rect_area); + /*Draw a rectangle above the clicked point*/ + lv_layer_t * layer = lv_event_get_layer(e); + lv_draw_rect_dsc_t draw_rect_dsc; + lv_draw_rect_dsc_init(&draw_rect_dsc); + draw_rect_dsc.bg_color = lv_color_black(); + draw_rect_dsc.bg_opa = LV_OPA_50; + draw_rect_dsc.radius = 3; - /*Draw the value as label to the center of the rectangle*/ - char buf[16]; - lv_snprintf(buf, sizeof(buf), LV_SYMBOL_DUMMY"$%d", value); + lv_area_t chart_obj_coords; + lv_obj_get_coords(chart, &chart_obj_coords); + lv_area_t rect_area; + rect_area.x1 = chart_obj_coords.x1 + p.x - 20; + rect_area.x2 = chart_obj_coords.x1 + p.x + 20; + rect_area.y1 = chart_obj_coords.y1 + p.y - 10; + rect_area.y2 = chart_obj_coords.y1 + p.y + 10; + lv_draw_rect(layer, &draw_rect_dsc, &rect_area); - lv_draw_label_dsc_t draw_label_dsc; - lv_draw_label_dsc_init(&draw_label_dsc); - draw_label_dsc.color = lv_color_white(); - draw_label_dsc.text = buf; - draw_label_dsc.text_local = 1; - draw_label_dsc.align = LV_TEXT_ALIGN_CENTER; - lv_area_t label_area = rect_area; - lv_area_set_height(&label_area, lv_font_get_line_height(draw_label_dsc.font)); - lv_area_align(&rect_area, &label_area, LV_ALIGN_CENTER, 0, 0); - lv_draw_label(layer, &draw_label_dsc, &label_area); + /*Draw the value as label to the center of the rectangle*/ + char buf[16]; + lv_snprintf(buf, sizeof(buf), LV_SYMBOL_DUMMY"$%d", value); + + lv_draw_label_dsc_t draw_label_dsc; + lv_draw_label_dsc_init(&draw_label_dsc); + draw_label_dsc.color = lv_color_white(); + draw_label_dsc.text = buf; + draw_label_dsc.text_local = 1; + draw_label_dsc.align = LV_TEXT_ALIGN_CENTER; + lv_area_t label_area = rect_area; + lv_area_set_height(&label_area, lv_font_get_line_height(draw_label_dsc.font)); + lv_area_align(&rect_area, &label_area, LV_ALIGN_CENTER, 0, 0); + lv_draw_label(layer, &draw_label_dsc, &label_area); + } ser = lv_chart_get_series_next(chart, ser); } @@ -75,22 +80,23 @@ void lv_example_chart_3(void) /*Create a chart*/ lv_obj_t * chart; chart = lv_chart_create(lv_screen_active()); - lv_obj_set_size(chart, 200, 150); + lv_obj_set_size(chart, 280, 180); + lv_obj_set_style_pad_column(chart, 4, 0); lv_obj_center(chart); + lv_chart_set_type(chart, LV_CHART_TYPE_STACKED); lv_obj_add_event_cb(chart, event_cb, LV_EVENT_ALL, NULL); lv_obj_refresh_ext_draw_size(chart); - /*Zoom in a little in X*/ - // lv_chart_set_scale_x(chart, 800); - /*Add two data series*/ lv_chart_series_t * ser1 = lv_chart_add_series(chart, lv_palette_main(LV_PALETTE_RED), LV_CHART_AXIS_PRIMARY_Y); lv_chart_series_t * ser2 = lv_chart_add_series(chart, lv_palette_main(LV_PALETTE_GREEN), LV_CHART_AXIS_PRIMARY_Y); + lv_chart_series_t * ser3 = lv_chart_add_series(chart, lv_palette_main(LV_PALETTE_BLUE), LV_CHART_AXIS_PRIMARY_Y); uint32_t i; for(i = 0; i < 10; i++) { - lv_chart_set_next_value(chart, ser1, (int32_t)lv_rand(60, 90)); - lv_chart_set_next_value(chart, ser2, (int32_t)lv_rand(10, 40)); + lv_chart_set_next_value(chart, ser1, lv_rand(15, 30)); + lv_chart_set_next_value(chart, ser2, lv_rand(15, 30)); + lv_chart_set_next_value(chart, ser3, lv_rand(15, 30)); } } diff --git a/examples/widgets/checkbox/lv_example_checkbox_1.c b/examples/widgets/checkbox/lv_example_checkbox_1.c index ee4ffe80a8..7e47daad24 100644 --- a/examples/widgets/checkbox/lv_example_checkbox_1.c +++ b/examples/widgets/checkbox/lv_example_checkbox_1.c @@ -36,7 +36,8 @@ void lv_example_checkbox_1(void) lv_obj_add_event_cb(cb, event_handler, LV_EVENT_ALL, NULL); cb = lv_checkbox_create(lv_screen_active()); - lv_obj_add_state(cb, LV_STATE_CHECKED | LV_STATE_DISABLED); + lv_obj_add_state(cb, LV_STATE_CHECKED); + lv_obj_add_state(cb, LV_STATE_DISABLED); lv_checkbox_set_text(cb, "Melon\nand a new line"); lv_obj_add_event_cb(cb, event_handler, LV_EVENT_ALL, NULL); diff --git a/examples/widgets/keyboard/lv_example_keyboard_3.c b/examples/widgets/keyboard/lv_example_keyboard_3.c index bacce51e35..1899a32329 100644 --- a/examples/widgets/keyboard/lv_example_keyboard_3.c +++ b/examples/widgets/keyboard/lv_example_keyboard_3.c @@ -1,5 +1,5 @@ #include "../../lv_examples.h" -#if LV_USE_BUTTONMATRIX && LV_BUILD_EXAMPLES +#if LV_USE_KEYBOARD && LV_BUILD_EXAMPLES static void event_cb(lv_event_t * e) { diff --git a/examples/widgets/label/index.rst b/examples/widgets/label/index.rst index fc1dc21708..cbf48432cd 100644 --- a/examples/widgets/label/index.rst +++ b/examples/widgets/label/index.rst @@ -34,3 +34,10 @@ Monospace font .. lv_example:: widgets/label/lv_example_label_6 :language: c + +Assign a translation tag to a label +----------------------------------- + +.. lv_example:: widgets/label/lv_example_label_7 + :language: c + diff --git a/examples/widgets/label/lv_example_label_5.c b/examples/widgets/label/lv_example_label_5.c index 3d6e1d7add..46b5740e97 100644 --- a/examples/widgets/label/lv_example_label_5.c +++ b/examples/widgets/label/lv_example_label_5.c @@ -14,6 +14,7 @@ void lv_example_label_5(void) lv_anim_set_delay(&animation_template, 1000); /*Wait 1 second to start the first scroll*/ lv_anim_set_repeat_delay(&animation_template, 3000); /*Repeat the scroll 3 seconds after the label scrolls back to the initial position*/ + lv_anim_set_repeat_count(&animation_template, LV_ANIM_REPEAT_INFINITE); /*Initialize the label style with the animation template*/ lv_style_init(&label_style); diff --git a/examples/widgets/label/lv_example_label_7.c b/examples/widgets/label/lv_example_label_7.c new file mode 100644 index 0000000000..efd1de8ee6 --- /dev/null +++ b/examples/widgets/label/lv_example_label_7.c @@ -0,0 +1,59 @@ +#include "../../lv_examples.h" + +#if LV_USE_TRANSLATION && LV_USE_DROPDOWN && LV_USE_LABEL && LV_BUILD_EXAMPLES + +static const char * tags[] = {"tiger", "lion", "rabbit", "elephant", NULL}; +static const char * languages[] = {"English", "Deutsch", "Español", NULL}; + +static void add_static_translations(void) +{ + static const char * translations[] = { + "The Tiger", "Der Tiger", "El Tigre", + "The Lion", "Der Löwe", "El León", + "The Rabbit", "Das Kaninchen", "El Conejo", + "The Elephant", "Der Elefant", "El Elefante", + }; + + lv_translation_add_static(languages, tags, translations); +} + +static void language_change_cb(lv_event_t * e) +{ + static char selected_lang[20]; + + lv_obj_t * dropdown = lv_event_get_target_obj(e); + lv_dropdown_get_selected_str(dropdown, selected_lang, sizeof(selected_lang)); + lv_translation_set_language(selected_lang); +} + +/** + * Use a translation tag in labels + */ +void lv_example_label_7(void) +{ + lv_obj_set_flex_flow(lv_screen_active(), LV_FLEX_FLOW_COLUMN); + lv_obj_set_flex_align(lv_screen_active(), LV_FLEX_ALIGN_CENTER, LV_FLEX_ALIGN_CENTER, LV_FLEX_ALIGN_CENTER); + + add_static_translations(); + const size_t tag_count = sizeof(tags) / sizeof(tags[0]) - 1; + const size_t lang_count = sizeof(languages) / sizeof(languages[0]) - 1; + + /* Create a dropdown to be able to select the language */ + lv_obj_t * language_dropdown = lv_dropdown_create(lv_screen_active()); + lv_dropdown_clear_options(language_dropdown); + + for(size_t i = 0; i < lang_count; ++i) { + lv_dropdown_add_option(language_dropdown, languages[i], i); + } + + lv_obj_add_event_cb(language_dropdown, language_change_cb, LV_EVENT_VALUE_CHANGED, NULL); + lv_translation_set_language("English"); + + /* Create a label for each tag */ + for(size_t i = 0; i < tag_count; ++i) { + lv_obj_t * label = lv_label_create(lv_screen_active()); + lv_label_set_translation_tag(label, tags[i]); + } +} + +#endif /*LV_USE_TRANSLATION && LV_USE_DROPDOWN && LV_USE_LABEL && LV_BUILD_EXAMPLES*/ diff --git a/examples/widgets/list/lv_example_list_2.c b/examples/widgets/list/lv_example_list_2.c index 0a3fa23053..9ace1d26f1 100644 --- a/examples/widgets/list/lv_example_list_2.c +++ b/examples/widgets/list/lv_example_list_2.c @@ -38,7 +38,7 @@ static void event_handler_top(lv_event_t * e) lv_event_code_t code = lv_event_get_code(e); if(code == LV_EVENT_CLICKED) { if(currentButton == NULL) return; - lv_obj_move_background(currentButton); + lv_obj_move_to_index(currentButton, 0); lv_obj_scroll_to_view(currentButton, LV_ANIM_ON); } } @@ -87,7 +87,7 @@ static void event_handler_bottom(lv_event_t * e) const lv_event_code_t code = lv_event_get_code(e); if(code == LV_EVENT_CLICKED) { if(currentButton == NULL) return; - lv_obj_move_foreground(currentButton); + lv_obj_move_to_index(currentButton, -1); lv_obj_scroll_to_view(currentButton, LV_ANIM_ON); } } diff --git a/examples/widgets/lottie/lv_example_lottie_1.c b/examples/widgets/lottie/lv_example_lottie_1.c index af5ed6da60..fa4067ea37 100644 --- a/examples/widgets/lottie/lv_example_lottie_1.c +++ b/examples/widgets/lottie/lv_example_lottie_1.c @@ -20,7 +20,7 @@ void lv_example_lottie_1(void) lv_lottie_set_buffer(lottie, 64, 64, buf); #else /*For GPUs and special alignment/strid setting use a draw_buf instead*/ - LV_DRAW_BUF_DEFINE(draw_buf, 64, 64, LV_COLOR_FORMAT_ARGB8888_PREMULTIPLIED); + LV_DRAW_BUF_DEFINE_STATIC(draw_buf, 64, 64, LV_COLOR_FORMAT_ARGB8888_PREMULTIPLIED); lv_lottie_set_draw_buf(lottie, &draw_buf); #endif diff --git a/examples/widgets/lottie/lv_example_lottie_2.c b/examples/widgets/lottie/lv_example_lottie_2.c index 0a89b6bdaf..ad91c08c6c 100644 --- a/examples/widgets/lottie/lv_example_lottie_2.c +++ b/examples/widgets/lottie/lv_example_lottie_2.c @@ -18,7 +18,7 @@ void lv_example_lottie_2(void) lv_lottie_set_buffer(lottie, 64, 64, buf); #else /*For GPUs and special alignment/strid setting use a draw_buf instead*/ - LV_DRAW_BUF_DEFINE(draw_buf, 64, 64, LV_COLOR_FORMAT_ARGB8888_PREMULTIPLIED); + LV_DRAW_BUF_DEFINE_STATIC(draw_buf, 64, 64, LV_COLOR_FORMAT_ARGB8888_PREMULTIPLIED); lv_lottie_set_draw_buf(lottie, &draw_buf); #endif diff --git a/examples/widgets/lv_example_widgets.h b/examples/widgets/lv_example_widgets.h index b24e77e458..d8f80a349a 100644 --- a/examples/widgets/lv_example_widgets.h +++ b/examples/widgets/lv_example_widgets.h @@ -98,6 +98,7 @@ void lv_example_label_3(void); void lv_example_label_4(void); void lv_example_label_5(void); void lv_example_label_6(void); +void lv_example_label_7(void); void lv_example_led_1(void); @@ -137,6 +138,7 @@ void lv_example_scale_8(void); void lv_example_scale_9(void); void lv_example_scale_10(void); void lv_example_scale_11(void); +void lv_example_scale_12(void); void lv_example_slider_1(void); void lv_example_slider_2(void); @@ -175,4 +177,4 @@ void lv_example_win_1(void); } /*extern "C"*/ #endif -#endif /*LV_EX_WIDGETS_H*/ +#endif /*LV_EXAMPLE_WIDGETS_H*/ diff --git a/examples/widgets/menu/lv_example_menu_5.c b/examples/widgets/menu/lv_example_menu_5.c index f8ab367efa..c8057ed086 100644 --- a/examples/widgets/menu/lv_example_menu_5.c +++ b/examples/widgets/menu/lv_example_menu_5.c @@ -20,12 +20,12 @@ void lv_example_menu_5(void) { lv_obj_t * menu = lv_menu_create(lv_screen_active()); - lv_color_t bg_color = lv_obj_get_style_bg_color(menu, 0); + lv_color_t bg_color = lv_obj_get_style_bg_color(menu, LV_PART_MAIN); if(lv_color_brightness(bg_color) > 127) { - lv_obj_set_style_bg_color(menu, lv_color_darken(lv_obj_get_style_bg_color(menu, 0), 10), 0); + lv_obj_set_style_bg_color(menu, lv_color_darken(lv_obj_get_style_bg_color(menu, LV_PART_MAIN), 10), 0); } else { - lv_obj_set_style_bg_color(menu, lv_color_darken(lv_obj_get_style_bg_color(menu, 0), 50), 0); + lv_obj_set_style_bg_color(menu, lv_color_darken(lv_obj_get_style_bg_color(menu, LV_PART_MAIN), 50), 0); } lv_menu_set_mode_root_back_button(menu, LV_MENU_ROOT_BACK_BUTTON_ENABLED); lv_obj_add_event_cb(menu, back_event_handler, LV_EVENT_CLICKED, menu); @@ -37,7 +37,7 @@ void lv_example_menu_5(void) /*Create sub pages*/ lv_obj_t * sub_mechanics_page = lv_menu_page_create(menu, NULL); - lv_obj_set_style_pad_hor(sub_mechanics_page, lv_obj_get_style_pad_left(lv_menu_get_main_header(menu), 0), 0); + lv_obj_set_style_pad_hor(sub_mechanics_page, lv_obj_get_style_pad_left(lv_menu_get_main_header(menu), LV_PART_MAIN), 0); lv_menu_separator_create(sub_mechanics_page); section = lv_menu_section_create(sub_mechanics_page); create_slider(section, LV_SYMBOL_SETTINGS, "Velocity", 0, 150, 120); @@ -45,24 +45,26 @@ void lv_example_menu_5(void) create_slider(section, LV_SYMBOL_SETTINGS, "Weight limit", 0, 150, 80); lv_obj_t * sub_sound_page = lv_menu_page_create(menu, NULL); - lv_obj_set_style_pad_hor(sub_sound_page, lv_obj_get_style_pad_left(lv_menu_get_main_header(menu), 0), 0); + lv_obj_set_style_pad_hor(sub_sound_page, lv_obj_get_style_pad_left(lv_menu_get_main_header(menu), LV_PART_MAIN), 0); lv_menu_separator_create(sub_sound_page); section = lv_menu_section_create(sub_sound_page); create_switch(section, LV_SYMBOL_AUDIO, "Sound", false); lv_obj_t * sub_display_page = lv_menu_page_create(menu, NULL); - lv_obj_set_style_pad_hor(sub_display_page, lv_obj_get_style_pad_left(lv_menu_get_main_header(menu), 0), 0); + lv_obj_set_style_pad_hor(sub_display_page, lv_obj_get_style_pad_left(lv_menu_get_main_header(menu), LV_PART_MAIN), 0); lv_menu_separator_create(sub_display_page); section = lv_menu_section_create(sub_display_page); create_slider(section, LV_SYMBOL_SETTINGS, "Brightness", 0, 150, 100); lv_obj_t * sub_software_info_page = lv_menu_page_create(menu, NULL); - lv_obj_set_style_pad_hor(sub_software_info_page, lv_obj_get_style_pad_left(lv_menu_get_main_header(menu), 0), 0); + lv_obj_set_style_pad_hor(sub_software_info_page, lv_obj_get_style_pad_left(lv_menu_get_main_header(menu), LV_PART_MAIN), + 0); section = lv_menu_section_create(sub_software_info_page); create_text(section, NULL, "Version 1.0", LV_MENU_ITEM_BUILDER_VARIANT_1); lv_obj_t * sub_legal_info_page = lv_menu_page_create(menu, NULL); - lv_obj_set_style_pad_hor(sub_legal_info_page, lv_obj_get_style_pad_left(lv_menu_get_main_header(menu), 0), 0); + lv_obj_set_style_pad_hor(sub_legal_info_page, lv_obj_get_style_pad_left(lv_menu_get_main_header(menu), LV_PART_MAIN), + 0); section = lv_menu_section_create(sub_legal_info_page); for(uint32_t i = 0; i < 15; i++) { create_text(section, NULL, @@ -71,7 +73,7 @@ void lv_example_menu_5(void) } lv_obj_t * sub_about_page = lv_menu_page_create(menu, NULL); - lv_obj_set_style_pad_hor(sub_about_page, lv_obj_get_style_pad_left(lv_menu_get_main_header(menu), 0), 0); + lv_obj_set_style_pad_hor(sub_about_page, lv_obj_get_style_pad_left(lv_menu_get_main_header(menu), LV_PART_MAIN), 0); lv_menu_separator_create(sub_about_page); section = lv_menu_section_create(sub_about_page); cont = create_text(section, NULL, "Software information", LV_MENU_ITEM_BUILDER_VARIANT_1); @@ -80,7 +82,7 @@ void lv_example_menu_5(void) lv_menu_set_load_page_event(menu, cont, sub_legal_info_page); lv_obj_t * sub_menu_mode_page = lv_menu_page_create(menu, NULL); - lv_obj_set_style_pad_hor(sub_menu_mode_page, lv_obj_get_style_pad_left(lv_menu_get_main_header(menu), 0), 0); + lv_obj_set_style_pad_hor(sub_menu_mode_page, lv_obj_get_style_pad_left(lv_menu_get_main_header(menu), LV_PART_MAIN), 0); lv_menu_separator_create(sub_menu_mode_page); section = lv_menu_section_create(sub_menu_mode_page); cont = create_switch(section, LV_SYMBOL_AUDIO, "Sidebar enable", true); @@ -88,7 +90,7 @@ void lv_example_menu_5(void) /*Create a root page*/ root_page = lv_menu_page_create(menu, "Settings"); - lv_obj_set_style_pad_hor(root_page, lv_obj_get_style_pad_left(lv_menu_get_main_header(menu), 0), 0); + lv_obj_set_style_pad_hor(root_page, lv_obj_get_style_pad_left(lv_menu_get_main_header(menu), LV_PART_MAIN), 0); section = lv_menu_section_create(root_page); cont = create_text(section, LV_SYMBOL_SETTINGS, "Mechanics", LV_MENU_ITEM_BUILDER_VARIANT_1); lv_menu_set_load_page_event(menu, cont, sub_mechanics_page); @@ -193,7 +195,7 @@ static lv_obj_t * create_switch(lv_obj_t * parent, const char * icon, const char lv_obj_t * obj = create_text(parent, icon, txt, LV_MENU_ITEM_BUILDER_VARIANT_1); lv_obj_t * sw = lv_switch_create(obj); - lv_obj_add_state(sw, chk ? LV_STATE_CHECKED : 0); + lv_obj_add_state(sw, chk ? LV_STATE_CHECKED : LV_STATE_DEFAULT); return obj; } diff --git a/examples/widgets/scale/index.rst b/examples/widgets/scale/index.rst index 823add5d3c..98dcd9c534 100644 --- a/examples/widgets/scale/index.rst +++ b/examples/widgets/scale/index.rst @@ -64,6 +64,12 @@ A round scale style simulating a sunset/sunrise widget .. lv_example:: widgets/scale/lv_example_scale_11 :language: c +A round scale style simulating a compass +---------------------------------------- + +.. lv_example:: widgets/scale/lv_example_scale_12 + :language: c + Axis ticks and labels with scrolling on a chart ----------------------------------------------- .. lv_example:: widgets/chart/lv_example_chart_2 diff --git a/examples/widgets/scale/lv_example_scale_10.c b/examples/widgets/scale/lv_example_scale_10.c index b6a11152ac..9a72107acf 100644 --- a/examples/widgets/scale/lv_example_scale_10.c +++ b/examples/widgets/scale/lv_example_scale_10.c @@ -134,13 +134,13 @@ void lv_example_scale_10(void) lv_scale_set_line_needle_value(scale, needle_line, 0, current_hr); - lv_obj_t * circle = lv_obj_create(lv_scr_act()); + lv_obj_t * circle = lv_obj_create(lv_screen_active()); lv_obj_set_size(circle, 130, 130); lv_obj_center(circle); lv_obj_set_style_radius(circle, LV_RADIUS_CIRCLE, 0); - lv_obj_set_style_bg_color(circle, lv_obj_get_style_bg_color(lv_scr_act(), LV_PART_MAIN), 0); + lv_obj_set_style_bg_color(circle, lv_obj_get_style_bg_color(lv_screen_active(), LV_PART_MAIN), 0); lv_obj_set_style_bg_opa(circle, LV_OPA_COVER, 0); lv_obj_set_style_border_width(circle, 0, LV_PART_MAIN); diff --git a/examples/widgets/scale/lv_example_scale_12.c b/examples/widgets/scale/lv_example_scale_12.c new file mode 100644 index 0000000000..e38111921e --- /dev/null +++ b/examples/widgets/scale/lv_example_scale_12.c @@ -0,0 +1,109 @@ +#include "../../lv_examples.h" +#if LV_USE_SCALE && LV_BUILD_EXAMPLES + +static lv_obj_t * scale; +static lv_obj_t * label; + +static const char * heading_to_cardinal(int32_t heading) +{ + /* Normalize heading to range [0, 360) */ + while(heading < 0) heading += 360; + while(heading >= 360) heading -= 360; + + if(heading < 23) return "N"; + else if(heading < 68) return "NE"; + else if(heading < 113) return "E"; + else if(heading < 158) return "SE"; + else if(heading < 203) return "S"; + else if(heading < 248) return "SW"; + else if(heading < 293) return "W"; + else if(heading < 338) return "NW"; + + return "N"; +} + +static void set_heading_value(void * obj, int32_t v) +{ + LV_UNUSED(obj); + lv_scale_set_rotation(scale, 270 - v); + lv_label_set_text_fmt(label, "%d°\n%s", (int)v, heading_to_cardinal(v)); +} + +static void draw_event_cb(lv_event_t * e) +{ + lv_draw_task_t * draw_task = lv_event_get_draw_task(e); + lv_draw_dsc_base_t * base_dsc = (lv_draw_dsc_base_t *)lv_draw_task_get_draw_dsc(draw_task); + lv_draw_label_dsc_t * label_draw_dsc = lv_draw_task_get_label_dsc(draw_task); + lv_draw_line_dsc_t * line_draw_dsc = lv_draw_task_get_line_dsc(draw_task); + if(base_dsc->part == LV_PART_INDICATOR) { + if(label_draw_dsc) { + if(base_dsc->id1 == 0) { + label_draw_dsc->color = lv_palette_main(LV_PALETTE_RED); + } + } + if(line_draw_dsc) { + if(base_dsc->id1 == 60) { + line_draw_dsc->color = lv_palette_main(LV_PALETTE_RED); + } + } + } +} + +/** + * A round scale style simulating a compass + */ +void lv_example_scale_12(void) +{ + scale = lv_scale_create(lv_screen_active()); + + lv_obj_set_size(scale, 200, 200); + lv_scale_set_mode(scale, LV_SCALE_MODE_ROUND_INNER); + lv_obj_set_align(scale, LV_ALIGN_CENTER); + + lv_scale_set_total_tick_count(scale, 61); + lv_scale_set_major_tick_every(scale, 5); + + lv_obj_set_style_length(scale, 5, LV_PART_ITEMS); + lv_obj_set_style_length(scale, 10, LV_PART_INDICATOR); + lv_obj_set_style_line_width(scale, 3, LV_PART_INDICATOR); + lv_scale_set_range(scale, 0, 360); + + static const char * custom_labels[] = {"N", "30", "60", "E", "120", "150", "S", "210", "240", "W", "300", "330", NULL}; + lv_scale_set_text_src(scale, custom_labels); + + lv_scale_set_angle_range(scale, 360); + lv_scale_set_rotation(scale, 270); + + lv_obj_add_event_cb(scale, draw_event_cb, LV_EVENT_DRAW_TASK_ADDED, NULL); + lv_obj_add_flag(scale, LV_OBJ_FLAG_SEND_DRAW_TASK_EVENTS); + + label = lv_label_create(lv_screen_active()); + lv_obj_set_width(label, 100); + lv_obj_set_align(label, LV_ALIGN_CENTER); + lv_label_set_text(label, "0°\nN"); + lv_obj_set_style_text_align(label, LV_TEXT_ALIGN_CENTER, 0); + + set_heading_value(NULL, 0); + + lv_obj_t * symbol = lv_label_create(scale); + lv_obj_set_align(symbol, LV_ALIGN_TOP_MID); + lv_obj_set_y(symbol, 5); + lv_label_set_text(symbol, LV_SYMBOL_UP); + lv_obj_set_style_text_align(symbol, LV_TEXT_ALIGN_CENTER, 0); + lv_obj_set_style_text_color(symbol, lv_palette_main(LV_PALETTE_RED), 0); + + lv_anim_t anim_scale; + lv_anim_init(&anim_scale); + lv_anim_set_var(&anim_scale, scale); + lv_anim_set_exec_cb(&anim_scale, set_heading_value); + lv_anim_set_duration(&anim_scale, 5000); + lv_anim_set_repeat_delay(&anim_scale, 500); + lv_anim_set_repeat_count(&anim_scale, LV_ANIM_REPEAT_INFINITE); + lv_anim_set_reverse_duration(&anim_scale, 5000); + lv_anim_set_reverse_delay(&anim_scale, 500); + lv_anim_set_values(&anim_scale, 0, 360); + lv_anim_start(&anim_scale); + +} + +#endif diff --git a/examples/widgets/span/lv_example_span_1.c b/examples/widgets/span/lv_example_span_1.c index 78503a713e..93f877366b 100644 --- a/examples/widgets/span/lv_example_span_1.c +++ b/examples/widgets/span/lv_example_span_1.c @@ -3,13 +3,14 @@ static void click_event_cb(lv_event_t * e) { - lv_obj_t * spans = lv_event_get_target_obj(e); lv_indev_t * indev = lv_event_get_indev(e); lv_point_t point; lv_indev_get_point(indev, &point); +#if LV_USE_LOG + lv_obj_t * spans = lv_event_get_target_obj(e); lv_span_t * span = lv_spangroup_get_span_by_point(spans, &point); - LV_LOG_USER("%s", span ? lv_span_get_text(span) : "NULL"); +#endif } /** diff --git a/examples/widgets/spinbox/lv_example_spinbox_1.c b/examples/widgets/spinbox/lv_example_spinbox_1.c index 774c8f2765..47e8ac1620 100644 --- a/examples/widgets/spinbox/lv_example_spinbox_1.c +++ b/examples/widgets/spinbox/lv_example_spinbox_1.c @@ -23,7 +23,8 @@ void lv_example_spinbox_1(void) { spinbox = lv_spinbox_create(lv_screen_active()); lv_spinbox_set_range(spinbox, -1000, 25000); - lv_spinbox_set_digit_format(spinbox, 5, 2); + lv_spinbox_set_digit_count(spinbox, 5); + lv_spinbox_set_dec_point_pos(spinbox, 2); lv_spinbox_step_prev(spinbox); lv_obj_set_width(spinbox, 100); lv_obj_center(spinbox); diff --git a/examples/widgets/switch/lv_example_switch_1.c b/examples/widgets/switch/lv_example_switch_1.c index 6b1f640981..0cd13f473b 100644 --- a/examples/widgets/switch/lv_example_switch_1.c +++ b/examples/widgets/switch/lv_example_switch_1.c @@ -31,7 +31,8 @@ void lv_example_switch_1(void) lv_obj_add_event_cb(sw, event_handler, LV_EVENT_ALL, NULL); sw = lv_switch_create(lv_screen_active()); - lv_obj_add_state(sw, LV_STATE_CHECKED | LV_STATE_DISABLED); + lv_obj_add_state(sw, LV_STATE_CHECKED); + lv_obj_add_state(sw, LV_STATE_DISABLED); lv_obj_add_event_cb(sw, event_handler, LV_EVENT_ALL, NULL); } diff --git a/examples/widgets/textarea/lv_example_textarea_4.c b/examples/widgets/textarea/lv_example_textarea_4.c index 14851a9e80..27cfbcb4d1 100644 --- a/examples/widgets/textarea/lv_example_textarea_4.c +++ b/examples/widgets/textarea/lv_example_textarea_4.c @@ -1,7 +1,7 @@ #include "../../lv_examples.h" #if LV_USE_TEXTAREA && LV_USE_KEYBOARD && LV_BUILD_EXAMPLES -static void create_styled_textarea_cursor(const char * txt, lv_coord_t y_ofs, lv_style_t * cursor_style) +static void create_styled_textarea_cursor(const char * txt, int32_t y_ofs, lv_style_t * cursor_style) { lv_obj_t * ta = lv_textarea_create(lv_screen_active()); lv_textarea_set_text(ta, txt); diff --git a/library.json b/library.json index 7bd96af23b..609feb2572 100644 --- a/library.json +++ b/library.json @@ -1,6 +1,6 @@ { "name": "lvgl", - "version": "9.3.0", + "version": "9.4.0", "keywords": "graphics, gui, embedded, tft, lvgl", "description": "Graphics library to create embedded GUI with easy-to-use graphical elements, beautiful visual effects and low memory footprint. It offers anti-aliasing, opacity, and animations using only one frame buffer.", "repository": { diff --git a/library.properties b/library.properties index 911743009d..f57b5fa613 100644 --- a/library.properties +++ b/library.properties @@ -1,5 +1,5 @@ name=lvgl -version=9.3.0 +version=9.4.0 author=kisvegabor maintainer=kisvegabor,embeddedt,pete-pjb sentence=Full-featured Graphics Library for Embedded Systems diff --git a/libs/nema_gfx/lib/core/cortex_m33_NemaPVG/gcc/libnemagfx-float-abi-hard-wc16.a b/libs/nema_gfx/lib/core/cortex_m33_NemaPVG/gcc/libnemagfx-float-abi-hard-wc16.a new file mode 100644 index 0000000000..821510411a Binary files /dev/null and b/libs/nema_gfx/lib/core/cortex_m33_NemaPVG/gcc/libnemagfx-float-abi-hard-wc16.a differ diff --git a/libs/nema_gfx/lib/core/cortex_m33_NemaPVG/gcc/libnemagfx-float-abi-hard.a b/libs/nema_gfx/lib/core/cortex_m33_NemaPVG/gcc/libnemagfx-float-abi-hard.a new file mode 100644 index 0000000000..17f49effc2 Binary files /dev/null and b/libs/nema_gfx/lib/core/cortex_m33_NemaPVG/gcc/libnemagfx-float-abi-hard.a differ diff --git a/libs/nema_gfx/lib/core/cortex_m33_NemaPVG/gcc/libnemagfx-wc16.a b/libs/nema_gfx/lib/core/cortex_m33_NemaPVG/gcc/libnemagfx-wc16.a new file mode 100644 index 0000000000..138bb30b21 Binary files /dev/null and b/libs/nema_gfx/lib/core/cortex_m33_NemaPVG/gcc/libnemagfx-wc16.a differ diff --git a/libs/nema_gfx/lib/core/cortex_m33_NemaPVG/gcc/libnemagfx.a b/libs/nema_gfx/lib/core/cortex_m33_NemaPVG/gcc/libnemagfx.a new file mode 100644 index 0000000000..703e219b08 Binary files /dev/null and b/libs/nema_gfx/lib/core/cortex_m33_NemaPVG/gcc/libnemagfx.a differ diff --git a/lv_conf_template.h b/lv_conf_template.h index 6abfbb94ad..79d79ec5f8 100644 --- a/lv_conf_template.h +++ b/lv_conf_template.h @@ -1,6 +1,6 @@ /** * @file lv_conf.h - * Configuration file for v9.3.0 + * Configuration file for v9.4.0 */ /* @@ -250,30 +250,6 @@ #endif #endif -/** Use NXP's VG-Lite GPU on iMX RTxxx platforms. */ -#define LV_USE_DRAW_VGLITE 0 - -#if LV_USE_DRAW_VGLITE - /** Enable blit quality degradation workaround recommended for screen's dimension > 352 pixels. */ - #define LV_USE_VGLITE_BLIT_SPLIT 0 - - #if LV_USE_OS - /** Use additional draw thread for VG-Lite processing. */ - #define LV_USE_VGLITE_DRAW_THREAD 1 - - #if LV_USE_VGLITE_DRAW_THREAD - /** Enable VGLite draw async. Queue multiple tasks and flash them once to the GPU. */ - #define LV_USE_VGLITE_DRAW_ASYNC 1 - #endif - #endif - - /** Enable VGLite asserts. */ - #define LV_USE_VGLITE_ASSERT 0 - - /** Enable VGLite error checks. */ - #define LV_USE_VGLITE_CHECK_ERROR 0 -#endif - /** Use NXP's PXP on iMX RTxxx platforms. */ #define LV_USE_PXP 0 @@ -294,14 +270,20 @@ #endif /** Use NXP's G2D on MPU platforms. */ -#define LV_USE_DRAW_G2D 0 +#define LV_USE_G2D 0 + +#if LV_USE_G2D + /** Use G2D for drawing. **/ + #define LV_USE_DRAW_G2D 1 + + /** Use G2D to rotate display. **/ + #define LV_USE_ROTATE_G2D 0 -#if LV_USE_DRAW_G2D /** Maximum number of buffers that can be stored for G2D draw unit. * Includes the frame buffers and assets. */ #define LV_G2D_HASH_TABLE_SIZE 50 - #if LV_USE_OS + #if LV_USE_DRAW_G2D && LV_USE_OS /** Use additional draw thread for G2D processing.*/ #define LV_USE_G2D_DRAW_THREAD 1 #endif @@ -318,7 +300,6 @@ /** Use VG-Lite GPU. */ #define LV_USE_DRAW_VG_LITE 0 - #if LV_USE_DRAW_VG_LITE /** Enable VG-Lite custom external 'gpu_init()' function */ #define LV_VG_LITE_USE_GPU_INIT 0 @@ -340,11 +321,53 @@ /** VG-Lite stroke maximum cache number. */ #define LV_VG_LITE_STROKE_CACHE_CNT 32 + + /** Remove VLC_OP_CLOSE path instruction (Workaround for NXP) **/ + #define LV_VG_LITE_DISABLE_VLC_OP_CLOSE 0 + + /** Disable linear gradient extension for some older versions of drivers. */ + #define LV_VG_LITE_DISABLE_LINEAR_GRADIENT_EXT 0 + + /** Enable usage of the LVGL's built-in vg_lite driver */ + #define LV_USE_VG_LITE_DRIVER 0 + #if LV_USE_VG_LITE_DRIVER + /** Used to pick the correct GPU series folder valid options are gc255, gc355 and gc555*/ + #define LV_VG_LITE_HAL_GPU_SERIES gc255 + + /** Used to pick the correct GPU revision header it depends on the vendor */ + #define LV_VG_LITE_HAL_GPU_REVISION 0x40 + + /** Base memory address of the GPU IP it depends on SoC, + * default value is for NXP based devices */ + #define LV_VG_LITE_HAL_GPU_BASE_ADDRESS 0x40240000 + #endif /*LV_USE_VG_LITE_DRIVER*/ + + /** Use ThorVG (a software vector library) as VG-Lite driver to allow testing VGLite on PC + * Requires: LV_USE_THORVG_INTERNAL or LV_USE_THORVG_EXTERNAL */ + #define LV_USE_VG_LITE_THORVG 0 + #if LV_USE_VG_LITE_THORVG + /** Enable LVGL's blend mode support */ + #define LV_VG_LITE_THORVG_LVGL_BLEND_SUPPORT 0 + + /** Enable YUV color format support */ + #define LV_VG_LITE_THORVG_YUV_SUPPORT 0 + + /** Enable Linear gradient extension support */ + #define LV_VG_LITE_THORVG_LINEAR_GRADIENT_EXT_SUPPORT 0 + + /** Enable alignment on 16 pixels */ + #define LV_VG_LITE_THORVG_16PIXELS_ALIGN 1 + + /** Buffer address alignment */ + #define LV_VG_LITE_THORVG_BUF_ADDR_ALIGN 64 + + /** Enable multi-thread render */ + #define LV_VG_LITE_THORVG_THREAD_RENDER 0 + #endif /*LV_USE_VG_LITE_THORVG*/ #endif /** Accelerate blends, fills, etc. with STM32 DMA2D */ #define LV_USE_DRAW_DMA2D 0 - #if LV_USE_DRAW_DMA2D #define LV_DRAW_DMA2D_HAL_INCLUDE "stm32h7xx_hal.h" @@ -354,8 +377,29 @@ #define LV_USE_DRAW_DMA2D_INTERRUPT 0 #endif -/** Draw using cached OpenGLES textures */ +/** Draw using cached OpenGLES textures. Requires LV_USE_OPENGLES */ #define LV_USE_DRAW_OPENGLES 0 +#if LV_USE_DRAW_OPENGLES + #define LV_DRAW_OPENGLES_TEXTURE_CACHE_COUNT 64 +#endif + +/** Draw using espressif PPA accelerator */ +#define LV_USE_PPA 0 +#if LV_USE_PPA + #define LV_USE_PPA_IMG 0 +#endif + +/* Use EVE FT81X GPU. */ +#define LV_USE_DRAW_EVE 0 +#if LV_USE_DRAW_EVE + /* EVE_GEN value: 2, 3, or 4 */ + #define LV_DRAW_EVE_EVE_GENERATION 4 + + /* The maximum number of bytes to buffer before a single SPI transmission. + * Set it to 0 to disable write buffering. + */ + #define LV_DRAW_EVE_WRITE_BUFFER_SIZE 2048 +#endif /*======================= * FEATURE CONFIGURATION @@ -497,30 +541,6 @@ /** Enable property name support. */ #define LV_USE_OBJ_PROPERTY_NAME 1 -/* Use VG-Lite Simulator. - * - Requires: LV_USE_THORVG_INTERNAL or LV_USE_THORVG_EXTERNAL */ -#define LV_USE_VG_LITE_THORVG 0 - -#if LV_USE_VG_LITE_THORVG - /** Enable LVGL's blend mode support */ - #define LV_VG_LITE_THORVG_LVGL_BLEND_SUPPORT 0 - - /** Enable YUV color format support */ - #define LV_VG_LITE_THORVG_YUV_SUPPORT 0 - - /** Enable Linear gradient extension support */ - #define LV_VG_LITE_THORVG_LINEAR_GRADIENT_EXT_SUPPORT 0 - - /** Enable alignment on 16 pixels */ - #define LV_VG_LITE_THORVG_16PIXELS_ALIGN 1 - - /** Buffer address alignment */ - #define LV_VG_LITE_THORVG_BUF_ADDR_ALIGN 64 - - /** Enable multi-thread render */ - #define LV_VG_LITE_THORVG_THREAD_RENDER 0 -#endif - /* Enable the multi-touch gesture recognition feature */ /* Gesture recognition requires the use of floats */ #define LV_USE_GESTURE_RECOGNITION 0 @@ -608,8 +628,6 @@ /* Demonstrate special features */ #define LV_FONT_MONTSERRAT_28_COMPRESSED 0 /**< bpp = 3 */ #define LV_FONT_DEJAVU_16_PERSIAN_HEBREW 0 /**< Hebrew, Arabic, Persian letters and all their forms */ -#define LV_FONT_SIMSUN_14_CJK 0 /**< 1000 most common CJK radicals */ -#define LV_FONT_SIMSUN_16_CJK 0 /**< 1000 most common CJK radicals */ #define LV_FONT_SOURCE_HAN_SANS_SC_14_CJK 0 /**< 1338 most common CJK radicals */ #define LV_FONT_SOURCE_HAN_SANS_SC_16_CJK 0 /**< 1338 most common CJK radicals */ @@ -799,7 +817,7 @@ /*================== * THEMES *==================*/ -/* Documentation for themes can be found here: https://docs.lvgl.io/master/details/common-widget-features/styles/style.html#themes . */ +/* Documentation for themes can be found here: https://docs.lvgl.io/master/details/common-widget-features/styles/styles.html#themes . */ /** A simple, impressive and very complete theme */ #define LV_USE_THEME_DEFAULT 1 @@ -908,6 +926,11 @@ #define LV_FS_UEFI_LETTER '\0' /**< Set an upper-case driver-identifier letter for this driver (e.g. 'A'). */ #endif +#define LV_USE_FS_FROGFS 0 +#if LV_USE_FS_FROGFS + #define LV_FS_FROGFS_LETTER '\0' +#endif + /** LODEPNG decoder library */ #define LV_USE_LODEPNG 0 @@ -932,6 +955,8 @@ #define LV_GIF_CACHE_DECODE_DATA 0 #endif +/** GStreamer library */ +#define LV_USE_GSTREAMER 0 /** Decode bin images to RAM */ #define LV_BIN_DECODER_RAM_LOAD 0 @@ -968,14 +993,19 @@ /** Rlottie library */ #define LV_USE_RLOTTIE 0 +/** Requires `LV_USE_3DTEXTURE = 1` */ +#define LV_USE_GLTF 0 + /** Enable Vector Graphic APIs - * - Requires `LV_USE_MATRIX = 1` */ + * Requires `LV_USE_MATRIX = 1` */ #define LV_USE_VECTOR_GRAPHIC 0 -/** Enable ThorVG (vector graphics library) from the src/libs folder */ +/** Enable ThorVG (vector graphics library) from the src/libs folder. + * Requires LV_USE_VECTOR_GRAPHIC */ #define LV_USE_THORVG_INTERNAL 0 -/** Enable ThorVG by assuming that its installed and linked to the project */ +/** Enable ThorVG by assuming that its installed and linked to the project + * Requires LV_USE_VECTOR_GRAPHIC */ #define LV_USE_THORVG_EXTERNAL 0 /** Use lvgl built-in LZ4 lib */ @@ -1015,6 +1045,13 @@ #if LV_USE_SYSMON /** Get the idle percentage. E.g. uint32_t my_get_idle(void); */ #define LV_SYSMON_GET_IDLE lv_os_get_idle_percent + /** 1: Enable usage of lv_os_get_proc_idle_percent.*/ + #define LV_SYSMON_PROC_IDLE_AVAILABLE 0 + #if LV_SYSMON_PROC_IDLE_AVAILABLE + /** Get the applications idle percentage. + * - Requires `LV_USE_OS == LV_OS_PTHREAD` */ + #define LV_SYSMON_GET_PROC_IDLE lv_os_get_proc_idle_percent + #endif /** 1: Show CPU usage and FPS count. * - Requires `LV_USE_SYSMON = 1` */ @@ -1044,6 +1081,7 @@ /** Default profiler trace buffer size */ #define LV_PROFILER_BUILTIN_BUF_SIZE (16 * 1024) /**< [bytes] */ #define LV_PROFILER_BUILTIN_DEFAULT_ENABLE 1 + #define LV_USE_PROFILER_BUILTIN_POSIX 0 /**< Enable POSIX profiler port */ #endif /** Header to include for profiler */ @@ -1153,15 +1191,19 @@ #if LV_USE_TEST /** Enable `lv_test_screenshot_compare`. - * Requires libpng and a few MB of extra RAM. */ + * Requires lodepng and a few MB of extra RAM. */ #define LV_USE_TEST_SCREENSHOT_COMPARE 0 #endif /*LV_USE_TEST*/ /** Enable loading XML UIs runtime */ #define LV_USE_XML 0 +/** 1: Enable text translation support */ +#define LV_USE_TRANSLATION 0 + /*1: Enable color filter style*/ #define LV_USE_COLOR_FILTER 0 + /*================== * DEVICES *==================*/ @@ -1197,7 +1239,6 @@ #define LV_WAYLAND_RENDER_MODE LV_DISPLAY_RENDER_MODE_PARTIAL /**< DMABUF supports LV_DISPLAY_RENDER_MODE_FULL and LV_DISPLAY_RENDER_MODE_DIRECT*/ /**< When LV_WAYLAND_USE_DMABUF is disabled, only LV_DISPLAY_RENDER_MODE_PARTIAL is supported*/ #define LV_WAYLAND_WINDOW_DECORATIONS 0 /**< Draw client side window decorations only necessary on Mutter/GNOME. Not supported using DMABUF*/ - #define LV_WAYLAND_WL_SHELL 0 /**< Use the legacy wl_shell protocol instead of the default XDG shell*/ #endif /** Driver for /dev/fb */ @@ -1234,8 +1275,21 @@ /** Driver for /dev/input */ #define LV_USE_NUTTX_TOUCHSCREEN 0 - /*Touchscreen cursor size in pixels(<=0: disable cursor)*/ + /** Touchscreen cursor size in pixels(<=0: disable cursor) */ #define LV_NUTTX_TOUCHSCREEN_CURSOR_SIZE 0 + + /** Driver for /dev/mouse */ + #define LV_USE_NUTTX_MOUSE 0 + + /** Mouse movement step (pixels) */ + #define LV_USE_NUTTX_MOUSE_MOVE_STEP 1 + + /*NuttX trace file and its path*/ + #define LV_USE_NUTTX_TRACE_FILE 0 + #if LV_USE_NUTTX_TRACE_FILE + #define LV_NUTTX_TRACE_FILE_PATH "/data/lvgl-trace.log" + #endif + #endif /** Driver for /dev/dri/card */ @@ -1248,11 +1302,21 @@ * The GBM library aims to provide a platform independent memory management system * it supports the major GPU vendors - This option requires linking with libgbm */ #define LV_USE_LINUX_DRM_GBM_BUFFERS 0 + + #define LV_LINUX_DRM_USE_EGL 0 #endif /** Interface for TFT_eSPI */ #define LV_USE_TFT_ESPI 0 +/** Interface for Lovyan_GFX */ +#define LV_USE_LOVYAN_GFX 0 + +#if LV_USE_LOVYAN_GFX + #define LV_LGFX_USER_INCLUDE "lv_lgfx_user.hpp" + +#endif /*LV_USE_LOVYAN_GFX*/ + /** Driver for evdev input devices */ #define LV_USE_EVDEV 0 @@ -1276,8 +1340,9 @@ #define LV_USE_ST7796 0 #define LV_USE_ILI9341 0 #define LV_USE_FT81X 0 +#define LV_USE_NV3007 0 -#if (LV_USE_ST7735 | LV_USE_ST7789 | LV_USE_ST7796 | LV_USE_ILI9341) +#if (LV_USE_ST7735 | LV_USE_ST7789 | LV_USE_ST7796 | LV_USE_ILI9341 | LV_USE_NV3007) #define LV_USE_GENERIC_MIPI 1 #else #define LV_USE_GENERIC_MIPI 0 @@ -1293,6 +1358,9 @@ #define LV_ST_LTDC_USE_DMA2D_FLUSH 0 #endif +/** Driver for NXP ELCDIF */ +#define LV_USE_NXP_ELCDIF 0 + /** LVGL Windows backend */ #define LV_USE_WINDOWS 0 @@ -1303,12 +1371,16 @@ #define LV_UEFI_USE_MEMORY_SERVICES 0 /**< Use the memory functions from the boot services table */ #endif -/** Use OpenGL to open window on PC and handle mouse and keyboard */ +/** Use a generic OpenGL driver that can be used to embed in other applications or used with GLFW/EGL */ #define LV_USE_OPENGLES 0 #if LV_USE_OPENGLES #define LV_USE_OPENGLES_DEBUG 1 /**< Enable or disable debug for opengles */ #endif +/** Use GLFW to open window on PC and handle mouse and keyboard. Requires*/ +#define LV_USE_GLFW 0 + + /** QNX Screen display and input drivers */ #define LV_USE_QNX 0 #if LV_USE_QNX @@ -1332,10 +1404,10 @@ #if LV_BUILD_DEMOS /** Show some widgets. This might be required to increase `LV_MEM_SIZE`. */ #define LV_USE_DEMO_WIDGETS 0 - + /** Demonstrate usage of encoder and keyboard. */ #define LV_USE_DEMO_KEYPAD_AND_ENCODER 0 - + /** Benchmark your system */ #define LV_USE_DEMO_BENCHMARK 0 @@ -1347,10 +1419,10 @@ /** Render test for each primitive. * - Requires at least 480x272 display. */ #define LV_USE_DEMO_RENDER 0 - + /** Stress test for LVGL */ #define LV_USE_DEMO_STRESS 0 - + /** Music player demo */ #define LV_USE_DEMO_MUSIC 0 #if LV_USE_DEMO_MUSIC @@ -1360,38 +1432,41 @@ #define LV_DEMO_MUSIC_LARGE 0 #define LV_DEMO_MUSIC_AUTO_PLAY 0 #endif - + /** Vector graphic demo */ #define LV_USE_DEMO_VECTOR_GRAPHIC 0 - + + /** GLTF demo */ + #define LV_USE_DEMO_GLTF 0 + /*--------------------------- * Demos from lvgl/lv_demos ---------------------------*/ - + /** Flex layout demo */ #define LV_USE_DEMO_FLEX_LAYOUT 0 - + /** Smart-phone like multi-language demo */ #define LV_USE_DEMO_MULTILANG 0 - + /** Widget transformation demo */ #define LV_USE_DEMO_TRANSFORM 0 - + /** Demonstrate scroll settings */ #define LV_USE_DEMO_SCROLL 0 - + /*E-bike demo with Lottie animations (if LV_USE_LOTTIE is enabled)*/ #define LV_USE_DEMO_EBIKE 0 #if LV_USE_DEMO_EBIKE #define LV_DEMO_EBIKE_PORTRAIT 0 /*0: for 480x270..480x320, 1: for 480x800..720x1280*/ #endif - + /** High-resolution demo */ #define LV_USE_DEMO_HIGH_RES 0 - + /* Smart watch demo */ #define LV_USE_DEMO_SMARTWATCH 0 -#endif /* LV_BUILD_DEMOS */ +#endif /* LV_BUILD_DEMOS */ /*--END OF LV_CONF_H--*/ diff --git a/lv_version.h b/lv_version.h index 8bbd5506ef..eba90b1f62 100644 --- a/lv_version.h +++ b/lv_version.h @@ -3,12 +3,12 @@ * The current version of LVGL */ -#ifndef LVGL_VERSION_H -#define LVGL_VERSION_H +#ifndef LV_VERSION_H +#define LV_VERSION_H #define LVGL_VERSION_MAJOR 9 -#define LVGL_VERSION_MINOR 3 +#define LVGL_VERSION_MINOR 4 #define LVGL_VERSION_PATCH 0 #define LVGL_VERSION_INFO "" -#endif /* LVGL_VERSION_H */ +#endif /* LV_VERSION_H */ diff --git a/lvgl.h b/lvgl.h index 4dc19ac459..41b1ec99bd 100644 --- a/lvgl.h +++ b/lvgl.h @@ -36,7 +36,8 @@ extern "C" { #include "src/misc/lv_iter.h" #include "src/misc/lv_circle_buf.h" #include "src/misc/lv_tree.h" -#include "src/misc/cache/lv_cache.h" + +#include "src/osal/lv_os.h" #include "src/tick/lv_tick.h" @@ -96,8 +97,8 @@ extern "C" { #include "src/others/ime/lv_ime_pinyin.h" #include "src/others/file_explorer/lv_file_explorer.h" #include "src/others/font_manager/lv_font_manager.h" +#include "src/others/translation/lv_translation.h" #include "src/others/xml/lv_xml.h" -#include "src/others/xml/lv_xml_component.h" #include "src/others/test/lv_test.h" #include "src/libs/barcode/lv_barcode.h" @@ -107,7 +108,10 @@ extern "C" { #include "src/libs/fsdrv/lv_fsdrv.h" #include "src/libs/lodepng/lv_lodepng.h" #include "src/libs/libpng/lv_libpng.h" +#include "src/libs/gltf/gltf_data/lv_gltf_model.h" +#include "src/libs/gltf/gltf_view/lv_gltf.h" #include "src/libs/gif/lv_gif.h" +#include "src/libs/gstreamer/lv_gstreamer.h" #include "src/libs/qrcode/lv_qrcode.h" #include "src/libs/tjpgd/lv_tjpgd.h" #include "src/libs/libjpeg_turbo/lv_libjpeg_turbo.h" @@ -123,14 +127,21 @@ extern "C" { #include "src/draw/lv_draw_buf.h" #include "src/draw/lv_draw_vector.h" #include "src/draw/sw/lv_draw_sw_utils.h" +#include "src/draw/eve/lv_draw_eve_target.h" #include "src/themes/lv_theme.h" #include "src/drivers/lv_drivers.h" -#include "src/lv_api_map_v8.h" -#include "src/lv_api_map_v9_0.h" -#include "src/lv_api_map_v9_1.h" +/* Define LV_DISABLE_API_MAPPING using a compiler option + * to make sure your application is not using deprecated names */ +#ifndef LV_DISABLE_API_MAPPING + #include "src/lv_api_map_v8.h" + #include "src/lv_api_map_v9_0.h" + #include "src/lv_api_map_v9_1.h" + #include "src/lv_api_map_v9_2.h" + #include "src/lv_api_map_v9_3.h" +#endif /*LV_DISABLE_API_MAPPING*/ #if LV_USE_PRIVATE_API #include "src/lvgl_private.h" diff --git a/lvgl_private.h b/lvgl_private.h index 426a4ca418..9a4ee0f8da 100644 --- a/lvgl_private.h +++ b/lvgl_private.h @@ -18,6 +18,7 @@ extern "C" { #include "src/display/lv_display_private.h" #include "src/indev/lv_indev_private.h" #include "src/misc/lv_text_private.h" +#include "src/misc/cache/lv_cache.h" #include "src/misc/cache/lv_cache_entry_private.h" #include "src/misc/cache/lv_cache_private.h" #include "src/layouts/lv_layout_private.h" @@ -31,7 +32,6 @@ extern "C" { #include "src/others/xml/lv_xml_private.h" #include "src/libs/qrcode/lv_qrcode_private.h" #include "src/libs/barcode/lv_barcode_private.h" -#include "src/libs/gif/lv_gif_private.h" #include "src/draw/lv_draw_triangle_private.h" #include "src/draw/lv_draw_private.h" #include "src/draw/lv_draw_rect_private.h" diff --git a/scripts/LVGLImage.py b/scripts/LVGLImage.py index bc631a1e68..931cadabd2 100755 --- a/scripts/LVGLImage.py +++ b/scripts/LVGLImage.py @@ -615,7 +615,9 @@ def premultiply(self): if self.cf.is_indexed: - def multiply(r, g, b, a): + def multiply(b, g, r, a): + # The precision is reduced, the correct way would be to divide by 255, + # but this is consistent with the premultiply function in the code. r, g, b = (r * a) >> 8, (g * a) >> 8, (b * a) >> 8 return uint8_t(b) + uint8_t(g) + uint8_t(r) + uint8_t(a) @@ -1087,11 +1089,11 @@ def pack(r, g, b, a): self.rgb565_dither and cf in (ColorFormat.RGB565, ColorFormat.RGB565_SWAPPED, ColorFormat.RGB565A8, ColorFormat.ARGB8565) ): - treshold_id = ((y & 7) << 3) + (x & 7) + threshold_id = ((y & 7) << 3) + (x & 7) - r = min(r + red_thresh[treshold_id], 0xFF) & 0xF8 - g = min(g + green_thresh[treshold_id], 0xFF) & 0xFC - b = min(b + blue_thresh[treshold_id], 0xFF) & 0xF8 + r = min(r + red_thresh[threshold_id], 0xFF) & 0xF8 + g = min(g + green_thresh[threshold_id], 0xFF) & 0xFC + b = min(b + blue_thresh[threshold_id], 0xFF) & 0xF8 rawdata += pack(r, g, b, a) diff --git a/scripts/build_html_examples.sh b/scripts/build_html_examples.sh index bba1569909..b5a8edc0b1 100755 --- a/scripts/build_html_examples.sh +++ b/scripts/build_html_examples.sh @@ -5,32 +5,41 @@ set -e # These variables allow us to specify an alternate repository URL and commit reference # This is particularly useful when running in CI environments for pull requests # where we need to build from the contributor's forked repository -REPO_URL="${1:-}" -COMMIT_REF="${2:-}" +ARG_1="${1:-}" +ARG_2="${2:-}" export PATH="/usr/lib/ccache:/usr/local/opt/ccache/libexec:$PATH" rm -rf emscripten_builder git clone https://github.com/lvgl/lv_sim_emscripten.git emscripten_builder -scripts/genexamplelist.sh > emscripten_builder/examplelist.c cd emscripten_builder -git submodule update --init -- lvgl -cd lvgl -if [ -n "$REPO_URL" ] && [ -n "$COMMIT_REF" ]; then - echo "Using provided repo URL: $REPO_URL and commit ref: $COMMIT_REF for lvgl submodule" - git remote set-url origin "$REPO_URL" - git fetch origin - git checkout "$COMMIT_REF" +if [ "$ARG_1" != "--symlink" ]; then + REPO_URL="$ARG_1" + COMMIT_REF="$ARG_2" + git submodule update --init -- lvgl + if [ -n "$REPO_URL" ] && [ -n "$COMMIT_REF" ]; then + cd lvgl + echo "Using provided repo URL: $REPO_URL and commit ref: $COMMIT_REF for lvgl submodule" + git remote set-url origin "$REPO_URL" + git fetch origin + git checkout "$COMMIT_REF" + cd .. + fi else - CURRENT_REF="$(git rev-parse HEAD)" - echo "Using current commit ref: $CURRENT_REF for lvgl" - git checkout "$CURRENT_REF" + SYMLINK_TARGET="$ARG_2" + echo "Using provided symbolic link to LVGL directory (should be absolute): $SYMLINK_TARGET" + rmdir lvgl # remove the uninitialized submodule empty dir + ln -s -T "$SYMLINK_TARGET" lvgl fi + +# Grab the path to emscripten's port examplelist.c before changing to LVGL's directory +EXAMPLE_LIST_C=$(pwd)/examplelist.c +cd lvgl +scripts/genexamplelist.sh > $EXAMPLE_LIST_C cd .. # Generate lv_conf LV_CONF_PATH=`pwd`/lvgl/configs/ci/docs/lv_conf_docs.h -cp lvgl/lv_conf_template.h $LV_CONF_PATH python ./lvgl/scripts/generate_lv_conf.py \ --template lvgl/lv_conf_template.h \ --config $LV_CONF_PATH \ @@ -41,5 +50,10 @@ cd cmbuild emcmake cmake .. -DLV_BUILD_CONF_PATH=$LV_CONF_PATH -DLVGL_CHOSEN_DEMO=lv_example_noop -DCMAKE_C_COMPILER_LAUNCHER=ccache -DCMAKE_CXX_COMPILER_LAUNCHER=ccache emmake make -j$(nproc) rm -rf CMakeFiles -cd ../.. -cp -a emscripten_builder/cmbuild docs/src/_static/built_lv_examples +cd .. +if [ "$ARG_1" != "--symlink" ]; then + cp -a cmbuild ../docs/src/_static/built_lv_examples +else + cp -a cmbuild lvgl/docs/src/_static/built_lv_examples +fi +cd .. diff --git a/scripts/built_in_font/font_license/FontAwesome/LICENSE.txt b/scripts/built_in_font/font_license/FontAwesome/LICENSE.txt new file mode 100644 index 0000000000..e69c5e39a3 --- /dev/null +++ b/scripts/built_in_font/font_license/FontAwesome/LICENSE.txt @@ -0,0 +1,165 @@ +Fonticons, Inc. (https://fontawesome.com) + +-------------------------------------------------------------------------------- + +Font Awesome Free License + +Font Awesome Free is free, open source, and GPL friendly. You can use it for +commercial projects, open source projects, or really almost whatever you want. +Full Font Awesome Free license: https://fontawesome.com/license/free. + +-------------------------------------------------------------------------------- + +# Icons: CC BY 4.0 License (https://creativecommons.org/licenses/by/4.0/) + +The Font Awesome Free download is licensed under a Creative Commons +Attribution 4.0 International License and applies to all icons packaged +as SVG and JS file types. + +-------------------------------------------------------------------------------- + +# Fonts: SIL OFL 1.1 License + +In the Font Awesome Free download, the SIL OFL license applies to all icons +packaged as web and desktop font files. + +Copyright (c) 2024 Fonticons, Inc. (https://fontawesome.com) +with Reserved Font Name: "Font Awesome". + +This Font Software is licensed under the SIL Open Font License, Version 1.1. +This license is copied below, and is also available with a FAQ at: +http://scripts.sil.org/OFL + +SIL OPEN FONT LICENSE +Version 1.1 - 26 February 2007 + +PREAMBLE +The goals of the Open Font License (OFL) are to stimulate worldwide +development of collaborative font projects, to support the font creation +efforts of academic and linguistic communities, and to provide a free and +open framework in which fonts may be shared and improved in partnership +with others. + +The OFL allows the licensed fonts to be used, studied, modified and +redistributed freely as long as they are not sold by themselves. The +fonts, including any derivative works, can be bundled, embedded, +redistributed and/or sold with any software provided that any reserved +names are not used by derivative works. The fonts and derivatives, +however, cannot be released under any other type of license. The +requirement for fonts to remain under this license does not apply +to any document created using the fonts or their derivatives. + +DEFINITIONS +"Font Software" refers to the set of files released by the Copyright +Holder(s) under this license and clearly marked as such. This may +include source files, build scripts and documentation. + +"Reserved Font Name" refers to any names specified as such after the +copyright statement(s). + +"Original Version" refers to the collection of Font Software components as +distributed by the Copyright Holder(s). + +"Modified Version" refers to any derivative made by adding to, deleting, +or substituting — in part or in whole — any of the components of the +Original Version, by changing formats or by porting the Font Software to a +new environment. + +"Author" refers to any designer, engineer, programmer, technical +writer or other person who contributed to the Font Software. + +PERMISSION & CONDITIONS +Permission is hereby granted, free of charge, to any person obtaining +a copy of the Font Software, to use, study, copy, merge, embed, modify, +redistribute, and sell modified and unmodified copies of the Font +Software, subject to the following conditions: + +1) Neither the Font Software nor any of its individual components, +in Original or Modified Versions, may be sold by itself. + +2) Original or Modified Versions of the Font Software may be bundled, +redistributed and/or sold with any software, provided that each copy +contains the above copyright notice and this license. These can be +included either as stand-alone text files, human-readable headers or +in the appropriate machine-readable metadata fields within text or +binary files as long as those fields can be easily viewed by the user. + +3) No Modified Version of the Font Software may use the Reserved Font +Name(s) unless explicit written permission is granted by the corresponding +Copyright Holder. This restriction only applies to the primary font name as +presented to the users. + +4) The name(s) of the Copyright Holder(s) or the Author(s) of the Font +Software shall not be used to promote, endorse or advertise any +Modified Version, except to acknowledge the contribution(s) of the +Copyright Holder(s) and the Author(s) or with their explicit written +permission. + +5) The Font Software, modified or unmodified, in part or in whole, +must be distributed entirely under this license, and must not be +distributed under any other license. The requirement for fonts to +remain under this license does not apply to any document created +using the Font Software. + +TERMINATION +This license becomes null and void if any of the above conditions are +not met. + +DISCLAIMER +THE FONT SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT +OF COPYRIGHT, PATENT, TRADEMARK, OR OTHER RIGHT. IN NO EVENT SHALL THE +COPYRIGHT HOLDER BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, +INCLUDING ANY GENERAL, SPECIAL, INDIRECT, INCIDENTAL, OR CONSEQUENTIAL +DAMAGES, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +FROM, OUT OF THE USE OR INABILITY TO USE THE FONT SOFTWARE OR FROM +OTHER DEALINGS IN THE FONT SOFTWARE. + +-------------------------------------------------------------------------------- + +# Code: MIT License (https://opensource.org/licenses/MIT) + +In the Font Awesome Free download, the MIT license applies to all non-font and +non-icon files. + +Copyright 2024 Fonticons, Inc. + +Permission is hereby granted, free of charge, to any person obtaining a copy of +this software and associated documentation files (the "Software"), to deal in the +Software without restriction, including without limitation the rights to use, copy, +modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, +and to permit persons to whom the Software is furnished to do so, subject to the +following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, +INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A +PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT +HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE +SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +-------------------------------------------------------------------------------- + +# Attribution + +Attribution is required by MIT, SIL OFL, and CC BY licenses. Downloaded Font +Awesome Free files already contain embedded comments with sufficient +attribution, so you shouldn't need to do anything additional when using these +files normally. + +We've kept attribution comments terse, so we ask that you do not actively work +to remove them from files, especially code. They're a great way for folks to +learn about Font Awesome. + +-------------------------------------------------------------------------------- + +# Brand Icons + +All brand icons are trademarks of their respective owners. The use of these +trademarks does not indicate endorsement of the trademark holder by Font +Awesome, nor vice versa. **Please do not use brand logos for any purpose except +to represent the company, product, or service to which they refer.** diff --git a/scripts/built_in_font/font_license/Lato/OFL.txt b/scripts/built_in_font/font_license/Lato/OFL.txt new file mode 100644 index 0000000000..980a0ce5e3 --- /dev/null +++ b/scripts/built_in_font/font_license/Lato/OFL.txt @@ -0,0 +1,94 @@ +Copyright (c) 2010-2014 by tyPoland Lukasz Dziedzic (team@latofonts.com) with Reserved Font Name "Lato" + +This Font Software is licensed under the SIL Open Font License, Version 1.1. +This license is copied below, and is also available with a FAQ at: +https://openfontlicense.org + + +----------------------------------------------------------- +SIL OPEN FONT LICENSE Version 1.1 - 26 February 2007 +----------------------------------------------------------- + +PREAMBLE +The goals of the Open Font License (OFL) are to stimulate worldwide +development of collaborative font projects, to support the font creation +efforts of academic and linguistic communities, and to provide a free and +open framework in which fonts may be shared and improved in partnership +with others. + +The OFL allows the licensed fonts to be used, studied, modified and +redistributed freely as long as they are not sold by themselves. The +fonts, including any derivative works, can be bundled, embedded, +redistributed and/or sold with any software provided that any reserved +names are not used by derivative works. The fonts and derivatives, +however, cannot be released under any other type of license. The +requirement for fonts to remain under this license does not apply +to any document created using the fonts or their derivatives. + +DEFINITIONS +"Font Software" refers to the set of files released by the Copyright +Holder(s) under this license and clearly marked as such. This may +include source files, build scripts and documentation. + +"Reserved Font Name" refers to any names specified as such after the +copyright statement(s). + +"Original Version" refers to the collection of Font Software components as +distributed by the Copyright Holder(s). + +"Modified Version" refers to any derivative made by adding to, deleting, +or substituting -- in part or in whole -- any of the components of the +Original Version, by changing formats or by porting the Font Software to a +new environment. + +"Author" refers to any designer, engineer, programmer, technical +writer or other person who contributed to the Font Software. + +PERMISSION & CONDITIONS +Permission is hereby granted, free of charge, to any person obtaining +a copy of the Font Software, to use, study, copy, merge, embed, modify, +redistribute, and sell modified and unmodified copies of the Font +Software, subject to the following conditions: + +1) Neither the Font Software nor any of its individual components, +in Original or Modified Versions, may be sold by itself. + +2) Original or Modified Versions of the Font Software may be bundled, +redistributed and/or sold with any software, provided that each copy +contains the above copyright notice and this license. These can be +included either as stand-alone text files, human-readable headers or +in the appropriate machine-readable metadata fields within text or +binary files as long as those fields can be easily viewed by the user. + +3) No Modified Version of the Font Software may use the Reserved Font +Name(s) unless explicit written permission is granted by the corresponding +Copyright Holder. This restriction only applies to the primary font name as +presented to the users. + +4) The name(s) of the Copyright Holder(s) or the Author(s) of the Font +Software shall not be used to promote, endorse or advertise any +Modified Version, except to acknowledge the contribution(s) of the +Copyright Holder(s) and the Author(s) or with their explicit written +permission. + +5) The Font Software, modified or unmodified, in part or in whole, +must be distributed entirely under this license, and must not be +distributed under any other license. The requirement for fonts to +remain under this license does not apply to any document created +using the Font Software. + +TERMINATION +This license becomes null and void if any of the above conditions are +not met. + +DISCLAIMER +THE FONT SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT +OF COPYRIGHT, PATENT, TRADEMARK, OR OTHER RIGHT. IN NO EVENT SHALL THE +COPYRIGHT HOLDER BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, +INCLUDING ANY GENERAL, SPECIAL, INDIRECT, INCIDENTAL, OR CONSEQUENTIAL +DAMAGES, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +FROM, OUT OF THE USE OR INABILITY TO USE THE FONT SOFTWARE OR FROM +OTHER DEALINGS IN THE FONT SOFTWARE. + diff --git a/scripts/built_in_font/font_license/NotoColorEmoji/OFL.txt b/scripts/built_in_font/font_license/NotoColorEmoji/OFL.txt new file mode 100644 index 0000000000..e94bdd0ce4 --- /dev/null +++ b/scripts/built_in_font/font_license/NotoColorEmoji/OFL.txt @@ -0,0 +1,94 @@ +Copyright 2021 Google Inc. All Rights Reserved. + +This Font Software is licensed under the SIL Open Font License, Version 1.1. +This license is copied below, and is also available with a FAQ at: +https://openfontlicense.org + + +----------------------------------------------------------- +SIL OPEN FONT LICENSE Version 1.1 - 26 February 2007 +----------------------------------------------------------- + +PREAMBLE +The goals of the Open Font License (OFL) are to stimulate worldwide +development of collaborative font projects, to support the font creation +efforts of academic and linguistic communities, and to provide a free and +open framework in which fonts may be shared and improved in partnership +with others. + +The OFL allows the licensed fonts to be used, studied, modified and +redistributed freely as long as they are not sold by themselves. The +fonts, including any derivative works, can be bundled, embedded, +redistributed and/or sold with any software provided that any reserved +names are not used by derivative works. The fonts and derivatives, +however, cannot be released under any other type of license. The +requirement for fonts to remain under this license does not apply +to any document created using the fonts or their derivatives. + +DEFINITIONS +"Font Software" refers to the set of files released by the Copyright +Holder(s) under this license and clearly marked as such. This may +include source files, build scripts and documentation. + +"Reserved Font Name" refers to any names specified as such after the +copyright statement(s). + +"Original Version" refers to the collection of Font Software components as +distributed by the Copyright Holder(s). + +"Modified Version" refers to any derivative made by adding to, deleting, +or substituting -- in part or in whole -- any of the components of the +Original Version, by changing formats or by porting the Font Software to a +new environment. + +"Author" refers to any designer, engineer, programmer, technical +writer or other person who contributed to the Font Software. + +PERMISSION & CONDITIONS +Permission is hereby granted, free of charge, to any person obtaining +a copy of the Font Software, to use, study, copy, merge, embed, modify, +redistribute, and sell modified and unmodified copies of the Font +Software, subject to the following conditions: + +1) Neither the Font Software nor any of its individual components, +in Original or Modified Versions, may be sold by itself. + +2) Original or Modified Versions of the Font Software may be bundled, +redistributed and/or sold with any software, provided that each copy +contains the above copyright notice and this license. These can be +included either as stand-alone text files, human-readable headers or +in the appropriate machine-readable metadata fields within text or +binary files as long as those fields can be easily viewed by the user. + +3) No Modified Version of the Font Software may use the Reserved Font +Name(s) unless explicit written permission is granted by the corresponding +Copyright Holder. This restriction only applies to the primary font name as +presented to the users. + +4) The name(s) of the Copyright Holder(s) or the Author(s) of the Font +Software shall not be used to promote, endorse or advertise any +Modified Version, except to acknowledge the contribution(s) of the +Copyright Holder(s) and the Author(s) or with their explicit written +permission. + +5) The Font Software, modified or unmodified, in part or in whole, +must be distributed entirely under this license, and must not be +distributed under any other license. The requirement for fonts to +remain under this license does not apply to any document created +using the Font Software. + +TERMINATION +This license becomes null and void if any of the above conditions are +not met. + +DISCLAIMER +THE FONT SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT +OF COPYRIGHT, PATENT, TRADEMARK, OR OTHER RIGHT. IN NO EVENT SHALL THE +COPYRIGHT HOLDER BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, +INCLUDING ANY GENERAL, SPECIAL, INDIRECT, INCIDENTAL, OR CONSEQUENTIAL +DAMAGES, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +FROM, OUT OF THE USE OR INABILITY TO USE THE FONT SOFTWARE OR FROM +OTHER DEALINGS IN THE FONT SOFTWARE. + diff --git a/scripts/built_in_font/font_license/NotoSansSC/OFL.txt b/scripts/built_in_font/font_license/NotoSansSC/OFL.txt new file mode 100644 index 0000000000..fd9e002259 --- /dev/null +++ b/scripts/built_in_font/font_license/NotoSansSC/OFL.txt @@ -0,0 +1,94 @@ +Copyright 2014-2021 Adobe (http://www.adobe.com/), with Reserved Font Name 'Source' + +This Font Software is licensed under the SIL Open Font License, Version 1.1. +This license is copied below, and is also available with a FAQ at: +https://openfontlicense.org + + +----------------------------------------------------------- +SIL OPEN FONT LICENSE Version 1.1 - 26 February 2007 +----------------------------------------------------------- + +PREAMBLE +The goals of the Open Font License (OFL) are to stimulate worldwide +development of collaborative font projects, to support the font creation +efforts of academic and linguistic communities, and to provide a free and +open framework in which fonts may be shared and improved in partnership +with others. + +The OFL allows the licensed fonts to be used, studied, modified and +redistributed freely as long as they are not sold by themselves. The +fonts, including any derivative works, can be bundled, embedded, +redistributed and/or sold with any software provided that any reserved +names are not used by derivative works. The fonts and derivatives, +however, cannot be released under any other type of license. The +requirement for fonts to remain under this license does not apply +to any document created using the fonts or their derivatives. + +DEFINITIONS +"Font Software" refers to the set of files released by the Copyright +Holder(s) under this license and clearly marked as such. This may +include source files, build scripts and documentation. + +"Reserved Font Name" refers to any names specified as such after the +copyright statement(s). + +"Original Version" refers to the collection of Font Software components as +distributed by the Copyright Holder(s). + +"Modified Version" refers to any derivative made by adding to, deleting, +or substituting -- in part or in whole -- any of the components of the +Original Version, by changing formats or by porting the Font Software to a +new environment. + +"Author" refers to any designer, engineer, programmer, technical +writer or other person who contributed to the Font Software. + +PERMISSION & CONDITIONS +Permission is hereby granted, free of charge, to any person obtaining +a copy of the Font Software, to use, study, copy, merge, embed, modify, +redistribute, and sell modified and unmodified copies of the Font +Software, subject to the following conditions: + +1) Neither the Font Software nor any of its individual components, +in Original or Modified Versions, may be sold by itself. + +2) Original or Modified Versions of the Font Software may be bundled, +redistributed and/or sold with any software, provided that each copy +contains the above copyright notice and this license. These can be +included either as stand-alone text files, human-readable headers or +in the appropriate machine-readable metadata fields within text or +binary files as long as those fields can be easily viewed by the user. + +3) No Modified Version of the Font Software may use the Reserved Font +Name(s) unless explicit written permission is granted by the corresponding +Copyright Holder. This restriction only applies to the primary font name as +presented to the users. + +4) The name(s) of the Copyright Holder(s) or the Author(s) of the Font +Software shall not be used to promote, endorse or advertise any +Modified Version, except to acknowledge the contribution(s) of the +Copyright Holder(s) and the Author(s) or with their explicit written +permission. + +5) The Font Software, modified or unmodified, in part or in whole, +must be distributed entirely under this license, and must not be +distributed under any other license. The requirement for fonts to +remain under this license does not apply to any document created +using the Font Software. + +TERMINATION +This license becomes null and void if any of the above conditions are +not met. + +DISCLAIMER +THE FONT SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT +OF COPYRIGHT, PATENT, TRADEMARK, OR OTHER RIGHT. IN NO EVENT SHALL THE +COPYRIGHT HOLDER BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, +INCLUDING ANY GENERAL, SPECIAL, INDIRECT, INCIDENTAL, OR CONSEQUENTIAL +DAMAGES, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +FROM, OUT OF THE USE OR INABILITY TO USE THE FONT SOFTWARE OR FROM +OTHER DEALINGS IN THE FONT SOFTWARE. + diff --git a/scripts/built_in_font/font_license/UbuntuMedium/UFL.txt b/scripts/built_in_font/font_license/UbuntuMedium/UFL.txt new file mode 100644 index 0000000000..e78ac4a5a6 --- /dev/null +++ b/scripts/built_in_font/font_license/UbuntuMedium/UFL.txt @@ -0,0 +1,97 @@ +------------------------------- +UBUNTU FONT LICENCE Version 1.0 +------------------------------- + +PREAMBLE +This licence allows the licensed fonts to be used, studied, modified and +redistributed freely. The fonts, including any derivative works, can be +bundled, embedded, and redistributed provided the terms of this licence +are met. The fonts and derivatives, however, cannot be released under +any other licence. The requirement for fonts to remain under this +licence does not require any document created using the fonts or their +derivatives to be published under this licence, as long as the primary +purpose of the document is not to be a vehicle for the distribution of +the fonts. + +DEFINITIONS +"Font Software" refers to the set of files released by the Copyright +Holder(s) under this licence and clearly marked as such. This may +include source files, build scripts and documentation. + +"Original Version" refers to the collection of Font Software components +as received under this licence. + +"Modified Version" refers to any derivative made by adding to, deleting, +or substituting -- in part or in whole -- any of the components of the +Original Version, by changing formats or by porting the Font Software to +a new environment. + +"Copyright Holder(s)" refers to all individuals and companies who have a +copyright ownership of the Font Software. + +"Substantially Changed" refers to Modified Versions which can be easily +identified as dissimilar to the Font Software by users of the Font +Software comparing the Original Version with the Modified Version. + +To "Propagate" a work means to do anything with it that, without +permission, would make you directly or secondarily liable for +infringement under applicable copyright law, except executing it on a +computer or modifying a private copy. Propagation includes copying, +distribution (with or without modification and with or without charging +a redistribution fee), making available to the public, and in some +countries other activities as well. + +PERMISSION & CONDITIONS +This licence does not grant any rights under trademark law and all such +rights are reserved. + +Permission is hereby granted, free of charge, to any person obtaining a +copy of the Font Software, to propagate the Font Software, subject to +the below conditions: + +1) Each copy of the Font Software must contain the above copyright +notice and this licence. These can be included either as stand-alone +text files, human-readable headers or in the appropriate machine- +readable metadata fields within text or binary files as long as those +fields can be easily viewed by the user. + +2) The font name complies with the following: +(a) The Original Version must retain its name, unmodified. +(b) Modified Versions which are Substantially Changed must be renamed to +avoid use of the name of the Original Version or similar names entirely. +(c) Modified Versions which are not Substantially Changed must be +renamed to both (i) retain the name of the Original Version and (ii) add +additional naming elements to distinguish the Modified Version from the +Original Version. The name of such Modified Versions must be the name of +the Original Version, with "derivative X" where X represents the name of +the new work, appended to that name. + +3) The name(s) of the Copyright Holder(s) and any contributor to the +Font Software shall not be used to promote, endorse or advertise any +Modified Version, except (i) as required by this licence, (ii) to +acknowledge the contribution(s) of the Copyright Holder(s) or (iii) with +their explicit written permission. + +4) The Font Software, modified or unmodified, in part or in whole, must +be distributed entirely under this licence, and must not be distributed +under any other licence. The requirement for fonts to remain under this +licence does not affect any document created using the Font Software, +except any version of the Font Software extracted from a document +created using the Font Software may only be distributed under this +licence. + +TERMINATION +This licence becomes null and void if any of the above conditions are +not met. + +DISCLAIMER +THE FONT SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF +COPYRIGHT, PATENT, TRADEMARK, OR OTHER RIGHT. IN NO EVENT SHALL THE +COPYRIGHT HOLDER BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, +INCLUDING ANY GENERAL, SPECIAL, INDIRECT, INCIDENTAL, OR CONSEQUENTIAL +DAMAGES, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +FROM, OUT OF THE USE OR INABILITY TO USE THE FONT SOFTWARE OR FROM OTHER +DEALINGS IN THE FONT SOFTWARE. + diff --git a/scripts/code-format.cfg b/scripts/code-format.cfg index 53a3a8749b..e7a4de9ca4 100644 --- a/scripts/code-format.cfg +++ b/scripts/code-format.cfg @@ -37,8 +37,8 @@ --exclude=../src/lv_conf_internal.h --exclude=../src/core/lv_obj_style_gen.c --exclude=../src/core/lv_obj_style_gen.h ---exclude=../src/libs/gif/gifdec.c ---exclude=../src/libs/gif/gifdec.h +--exclude=../src/libs/gif/AnimatedGIF +--exclude=../src/libs/frogfs --exclude=../src/libs/lodepng/lodepng.c --exclude=../src/libs/lodepng/lodepng.h --exclude=../src/libs/qrcode/qrcodegen.c @@ -49,6 +49,8 @@ --exclude=../src/libs/thorvg --exclude=../src/libs/expat --exclude=../src/libs/lz4 +--exclude=../src/libs/FT800-FT813 +--exclude=../src/drivers/opengles/glad --exclude=../src/others/vg_lite_tvg/vg_lite.h --exclude=../demos/high_res/fonts --exclude=../tests/unity/unity.c @@ -58,3 +60,6 @@ --exclude=../tests/test_images --exclude=../tests/build_test_defheap --exclude=../tests/build_test_sysheap +--exclude=../tests/build_test_vg_lite +--exclude=../tests/build_test_perf32b +--exclude=../tests/build_test_perf64b diff --git a/scripts/font_license_verify.py b/scripts/font_license_verify.py index 7b01f29ad1..bff763d1e6 100644 --- a/scripts/font_license_verify.py +++ b/scripts/font_license_verify.py @@ -22,7 +22,11 @@ "Montserrat Medium": "Montserrat", "Montserrat SemiBold": "Montserrat", "Montserrat Bold": "Montserrat", + "Montserrat Regular": "Montserrat", "Source Han Sans SC Normal": "Source Han Sans SC", + "Font Awesome 5 Free Solid": "Font Awesome", + "Lato Regular": "Lato", + "Noto Sans SC Regular": "Noto Sans SC", } diff --git a/scripts/gdb/README.md b/scripts/gdb/README.md new file mode 100644 index 0000000000..2f5eb59e85 --- /dev/null +++ b/scripts/gdb/README.md @@ -0,0 +1,20 @@ +# lvglgdb + +lvglgdb is a GDB script for LVGL. + +# Structure + +```mermaid +graph TD + lvgl["lvgl
(mem→python object)"] + gdb_cmds["gdb_cmds
(gdb commands)"] + lvglgdb["lvglgdb"] + + lvglgdb --> lvgl + lvglgdb --> gdb_cmds + gdb_cmds --> lvgl + + classDef pkg fill:white,stroke:gray + classDef core fill:white,stroke:gray + class lvglgdb,lvgl,gdb_cmds pkg +``` diff --git a/scripts/gdb/lvglgdb/__init__.py b/scripts/gdb/lvglgdb/__init__.py index 7e1d9e17e9..d861c390a3 100644 --- a/scripts/gdb/lvglgdb/__init__.py +++ b/scripts/gdb/lvglgdb/__init__.py @@ -1,16 +1,13 @@ -from .lvgl import * -from .value import * -from .debugger import * - -# Debugger -Debugger() - -# Dumps -DumpObj() - -# Infos -InfoStyle() -InfoDrawUnit() - -# Set instance -set_lvgl_instance(None) +from .value import Value +from .lvgl import curr_inst, LVDisplay, LVDrawBuf, LVList, LVObject, dump_style_info +from . import cmds as cmds + +__all__ = [ + "curr_inst", + "LVDisplay", + "LVDrawBuf", + "LVList", + "LVObject", + "dump_style_info", + "Value", +] diff --git a/scripts/gdb/lvglgdb/cmds/__init__.py b/scripts/gdb/lvglgdb/cmds/__init__.py new file mode 100644 index 0000000000..aecc4e97aa --- /dev/null +++ b/scripts/gdb/lvglgdb/cmds/__init__.py @@ -0,0 +1,27 @@ +import gdb + +from .core import DumpObj +from .display import DumpDisplayBuf +from .draw import InfoDrawUnit +from .misc import InfoStyle +from .debugger import Debugger + +__all__ = [] + +# Set pagination off and python print-stack full +gdb.execute("set pagination off") +gdb.write("set pagination off\n") +gdb.execute("set python print-stack full") +gdb.write("set python print-stack full\n") + + +# Debugger +Debugger() + +# Dumps +DumpObj() +DumpDisplayBuf() + +# Infos +InfoStyle() +InfoDrawUnit() diff --git a/scripts/gdb/lvglgdb/cmds/core/__init__.py b/scripts/gdb/lvglgdb/cmds/core/__init__.py new file mode 100644 index 0000000000..854d087a70 --- /dev/null +++ b/scripts/gdb/lvglgdb/cmds/core/__init__.py @@ -0,0 +1,5 @@ +from .lv_obj import DumpObj + +__all__ = [ + "DumpObj", +] diff --git a/scripts/gdb/lvglgdb/cmds/core/lv_obj.py b/scripts/gdb/lvglgdb/cmds/core/lv_obj.py new file mode 100644 index 0000000000..9b98d58730 --- /dev/null +++ b/scripts/gdb/lvglgdb/cmds/core/lv_obj.py @@ -0,0 +1,63 @@ +import argparse +import gdb + +from lvglgdb.lvgl import curr_inst +from lvglgdb.lvgl import LVObject, dump_obj_info + + +class DumpObj(gdb.Command): + """dump obj tree from specified obj""" + + def __init__(self): + super(DumpObj, self).__init__( + "dump obj", gdb.COMMAND_USER, gdb.COMPLETE_EXPRESSION + ) + + def dump_obj(self, obj: LVObject, depth=0, limit=None): + if not obj: + return + + # dump self + print(" " * depth, end="") + dump_obj_info(obj) + + if limit is not None and depth >= limit: + return + + # dump children + for child in obj.children: + self.dump_obj(child, depth + 1, limit=limit) + + def invoke(self, args, from_tty): + parser = argparse.ArgumentParser(description="Dump lvgl obj tree.") + parser.add_argument( + "-L", + "--level", + type=int, + default=None, + help="Limit the depth of the tree.", + ) + parser.add_argument( + "root", + type=str, + nargs="?", + default=None, + help="Optional root obj to dump.", + ) + try: + args = parser.parse_args(gdb.string_to_argv(args)) + except SystemExit: + return + + if args.root: + root = gdb.parse_and_eval(args.root) + root = LVObject(root) + self.dump_obj(root, limit=args.level) + else: + # dump all displays + depth = 0 + for disp in curr_inst().displays(): + print(f"Display {hex(disp)}") + for screen in disp.screens: + print(f'{" " * (depth + 1)}Screen@{hex(screen)}') + self.dump_obj(screen, depth=depth + 1, limit=args.level) diff --git a/scripts/gdb/lvglgdb/debugger.py b/scripts/gdb/lvglgdb/cmds/debugger.py similarity index 93% rename from scripts/gdb/lvglgdb/debugger.py rename to scripts/gdb/lvglgdb/cmds/debugger.py index 235ecdcddb..b29b65d9e2 100644 --- a/scripts/gdb/lvglgdb/debugger.py +++ b/scripts/gdb/lvglgdb/cmds/debugger.py @@ -57,7 +57,9 @@ def connect_to_pycharm(self): print("pydevd_pycharm module not found. Please install it using pip.") return - pydevd_pycharm.settrace(self.__host, port=self.__port, stdoutToServer=True, stderrToServer=True) + pydevd_pycharm.settrace( + self.__host, port=self.__port, stdoutToServer=True, stderrToServer=True + ) def connect_to_vscode(self): try: diff --git a/scripts/gdb/lvglgdb/cmds/display/__init__.py b/scripts/gdb/lvglgdb/cmds/display/__init__.py new file mode 100644 index 0000000000..43360b4a2f --- /dev/null +++ b/scripts/gdb/lvglgdb/cmds/display/__init__.py @@ -0,0 +1,5 @@ +from .lv_display import DumpDisplayBuf + +__all__ = [ + "DumpDisplayBuf", +] diff --git a/scripts/gdb/lvglgdb/cmds/display/lv_display.py b/scripts/gdb/lvglgdb/cmds/display/lv_display.py new file mode 100644 index 0000000000..0009134ca9 --- /dev/null +++ b/scripts/gdb/lvglgdb/cmds/display/lv_display.py @@ -0,0 +1,54 @@ +import argparse +import gdb + +from lvglgdb.lvgl import curr_inst +from lvglgdb.lvgl import LVDrawBuf + + +class DumpDisplayBuf(gdb.Command): + """dump display buf to image""" + + def __init__(self): + super(DumpDisplayBuf, self).__init__( + "dump display", gdb.COMMAND_USER, gdb.COMPLETE_EXPRESSION + ) + + def invoke(self, args, from_tty): + parser = argparse.ArgumentParser(description="Dump display draw buffer.") + parser.add_argument( + "-p", + "--prefix", + type=str, + default="", + help="prefix of dump file path", + ) + parser.add_argument( + "-f", + "--format", + type=str, + choices=["bmp", "png"], + default=None, + help="dump file format (bmp or png)", + ) + + try: + args = parser.parse_args(gdb.string_to_argv(args)) + except SystemExit: + return + + display = curr_inst().disp_default() + if not display: + print("Error: Invalid display pointer") + return + buffers = { + "buf_1": display.buf_1, + "buf_2": display.buf_2, + } + + for buf_name, buf_ptr in buffers.items(): + if buf_ptr is not None: + draw_buf = LVDrawBuf(buf_ptr) + filename = f"{args.prefix}{buf_name}.{args.format.lower() if args.format else 'bmp'}" + draw_buf.data_dump(filename, args.format) + else: + print(f"Warning: {buf_name} buffer is None, skipping.") diff --git a/scripts/gdb/lvglgdb/cmds/draw/__init__.py b/scripts/gdb/lvglgdb/cmds/draw/__init__.py new file mode 100644 index 0000000000..9c31c8a938 --- /dev/null +++ b/scripts/gdb/lvglgdb/cmds/draw/__init__.py @@ -0,0 +1,5 @@ +from .lv_draw import InfoDrawUnit + +__all__ = [ + "InfoDrawUnit", +] diff --git a/scripts/gdb/lvglgdb/cmds/draw/lv_draw.py b/scripts/gdb/lvglgdb/cmds/draw/lv_draw.py new file mode 100644 index 0000000000..9530a1ef59 --- /dev/null +++ b/scripts/gdb/lvglgdb/cmds/draw/lv_draw.py @@ -0,0 +1,50 @@ +import gdb + +from lvglgdb.value import Value +from lvglgdb.lvgl import curr_inst + + +class InfoDrawUnit(gdb.Command): + """dump draw unit info""" + + def __init__(self): + super(InfoDrawUnit, self).__init__( + "info draw_unit", gdb.COMMAND_USER, gdb.COMPLETE_EXPRESSION + ) + + def dump_draw_unit(self, draw_unit: Value): + # Dereference to get the string content of the name from draw_unit + name = draw_unit.name.string() + + # Print draw_unit information and the name + print(f"Draw Unit: {draw_unit}, Name: {name}") + + # Handle different draw_units based on the name + def lookup_type(name): + try: + return gdb.lookup_type(name) + except gdb.error: + return None + + types = { + "DMA2D": lookup_type("lv_draw_dma2d_unit_t"), + "NEMA_GFX": lookup_type("lv_draw_nema_gfx_unit_t"), + "NXP_PXP": lookup_type("lv_draw_pxp_unit_t"), + "NXP_VGLITE": lookup_type("lv_draw_vglite_unit_t"), + "OPENGLES": lookup_type("lv_draw_opengles_unit_t"), + "DAVE2D": lookup_type("lv_draw_dave2d_unit_t"), + "SDL": lookup_type("lv_draw_sdl_unit_t"), + "SW": lookup_type("lv_draw_sw_unit_t"), + "VG_LITE": lookup_type("lv_draw_vg_lite_unit_t"), + } + + type = types.get(name, lookup_type("lv_draw_unit_t")) + print( + draw_unit.cast(type, ptr=True) + .dereference() + .format_string(pretty_structs=True, symbols=True) + ) + + def invoke(self, args, from_tty): + for unit in curr_inst().draw_units(): + self.dump_draw_unit(unit) diff --git a/scripts/gdb/lvglgdb/cmds/misc/__init__.py b/scripts/gdb/lvglgdb/cmds/misc/__init__.py new file mode 100644 index 0000000000..d8370d743a --- /dev/null +++ b/scripts/gdb/lvglgdb/cmds/misc/__init__.py @@ -0,0 +1,5 @@ +from .lv_style import InfoStyle + +__all__ = [ + "InfoStyle", +] diff --git a/scripts/gdb/lvglgdb/cmds/misc/lv_style.py b/scripts/gdb/lvglgdb/cmds/misc/lv_style.py new file mode 100644 index 0000000000..5d86772713 --- /dev/null +++ b/scripts/gdb/lvglgdb/cmds/misc/lv_style.py @@ -0,0 +1,40 @@ +import argparse +import gdb + +from lvglgdb.value import Value +from lvglgdb.lvgl import LVObject +from lvglgdb.lvgl import dump_style_info + + +class InfoStyle(gdb.Command): + """dump obj style value for specified obj""" + + def __init__(self): + super(InfoStyle, self).__init__( + "info style", gdb.COMMAND_USER, gdb.COMPLETE_EXPRESSION + ) + + def invoke(self, args, from_tty): + parser = argparse.ArgumentParser(description="Dump lvgl obj local style.") + parser.add_argument( + "obj", + type=str, + help="obj to show style.", + ) + + try: + args = parser.parse_args(gdb.string_to_argv(args)) + except SystemExit: + return + + obj = gdb.parse_and_eval(args.obj) + if not obj: + print("Invalid obj: ", args.obj) + return + + obj = Value(obj) + + # show all styles applied to this obj + for style in LVObject(obj).styles: + print(" ", end="") + dump_style_info(style) diff --git a/scripts/gdb/lvglgdb/lvgl.py b/scripts/gdb/lvglgdb/lvgl.py deleted file mode 100644 index 992503b0fb..0000000000 --- a/scripts/gdb/lvglgdb/lvgl.py +++ /dev/null @@ -1,335 +0,0 @@ -import argparse -from typing import Iterator, Union, Optional - -import gdb - -from .value import Value - -gdb.execute("set pagination off") -gdb.write("set pagination off\n") -gdb.execute("set python print-stack full") -gdb.write("set python print-stack full\n") - -g_lvgl_instance = None - - -class LVList(Value): - """LVGL linked list iterator""" - - def __init__(self, ll: Value, nodetype: Union[gdb.Type, str] = None): - if not ll: - raise ValueError("Invalid linked list") - super().__init__(ll) - - self.nodetype = ( - gdb.lookup_type(nodetype).pointer() - if isinstance(nodetype, str) - else nodetype - ) - self.lv_ll_node_t = gdb.lookup_type("lv_ll_node_t").pointer() - self.current = self.head - self._next_offset = self.n_size + self.lv_ll_node_t.sizeof - self._prev_offset = self.n_size - - def _next(self, node): - next_value = Value(int(node) + self._next_offset) - return next_value.cast(self.lv_ll_node_t, ptr=True).dereference() - - def _prev(self, node): - prev_value = Value(int(node) + self._prev_offset) - return prev_value.cast(self.lv_ll_node_t, ptr=True).dereference() - - def __iter__(self): - return self - - def __next__(self): - if not self.current: - raise StopIteration - - nodetype = self.nodetype if self.nodetype else self.lv_ll_node_t - node = self.current.cast(nodetype) - - self.current = self._next(self.current) - return node - - @property - def len(self): - len = 0 - node = self.head - while node: - len += 1 - node = self._next(node) - return len - - -class LVObject(Value): - """LVGL object""" - - def __init__(self, obj: Value): - super().__init__(obj.cast("lv_obj_t", ptr=True)) - - @property - def class_name(self): - name = self.class_p.name - return name.string() if name else "unknown" - - @property - def x1(self): - return int(self.coords.x1) - - @property - def y1(self): - return int(self.coords.y1) - - @property - def x2(self): - return int(self.coords.x2) - - @property - def y2(self): - return int(self.coords.y2) - - @property - def child_count(self): - return self.spec_attr.child_cnt if self.spec_attr else 0 - - @property - def childs(self): - if not self.spec_attr: - return - - for i in range(self.child_count): - child = self.spec_attr.children[i] - yield LVObject(child) - - @property - def styles(self): - LV_STYLE_PROP_INV = 0 - LV_STYLE_PROP_ANY = 0xFF - count = self.style_cnt - if count == 0: - return - - styles = self.super_value("styles") - for i in range(count): - style = styles[i].style - prop_cnt = style.prop_cnt - values_and_props = style.values_and_props.cast("lv_style_const_prop_t", ptr=True) - for j in range(prop_cnt): - prop = values_and_props[j].prop - if prop == LV_STYLE_PROP_INV or prop == LV_STYLE_PROP_ANY: - continue - yield values_and_props[j] - - def get_child(self, index: int): - return ( - self.spec_attr.children[index] if self.spec_attr else None - ) - - -class LVDisplay(Value): - """LVGL display""" - - def __init__(self, disp: Value): - super().__init__(disp) - - @property - def screens(self): - screens = self.super_value("screens") - for i in range(self.screen_cnt): - yield LVObject(screens[i]) - - -class LVGL: - """LVGL instance""" - - def __init__(self, lv_global: Value): - self.lv_global = lv_global.cast("lv_global_t", ptr=True) - - def displays(self) -> Iterator[LVDisplay]: - ll = self.lv_global.disp_ll - if not ll: - return - - for disp in LVList(ll, "lv_display_t"): - yield LVDisplay(disp) - - def screen_active(self): - disp = self.lv_global.disp_default - return disp.act_scr if disp else None - - def draw_units(self): - unit = self.lv_global.draw_info.unit_head - - # Iterate through all draw units - while unit: - yield unit - unit = unit.next - - -def set_lvgl_instance(lv_global: Union[gdb.Value, Value, None]): - global g_lvgl_instance - - if not lv_global: - try: - lv_global = Value(gdb.parse_and_eval("lv_global").address) - except gdb.error as e: - print(f"Failed to get lv_global: {e}") - return - - if not isinstance(lv_global, Value): - lv_global = Value(lv_global) - - inited = lv_global.inited - if not inited: - print("\x1b[31mlvgl is not initialized yet. Please call `set_lvgl_instance(None)` later.\x1b[0m") - return - - g_lvgl_instance = LVGL(lv_global) - - -def dump_obj_info(obj: LVObject): - clzname = obj.class_name - coords = f"{obj.x1},{obj.y1},{obj.x2},{obj.y2}" - print(f"{clzname}@{hex(obj)} {coords}") - - -# Dump lv_style_const_prop_t -def dump_style_info(style: Value): - prop = int(style.prop) - value = style.value - print(f"{prop} = {value}") - - -class DumpObj(gdb.Command): - """dump obj tree from specified obj""" - - def __init__(self): - super(DumpObj, self).__init__( - "dump obj", gdb.COMMAND_USER, gdb.COMPLETE_EXPRESSION - ) - - def dump_obj(self, obj: LVObject, depth=0, limit=None): - if not obj: - return - - # dump self - print(" " * depth, end="") - dump_obj_info(obj) - - if limit is not None and depth >= limit: - return - - # dump children - for child in obj.childs: - self.dump_obj(child, depth + 1, limit=limit) - - def invoke(self, args, from_tty): - parser = argparse.ArgumentParser(description="Dump lvgl obj tree.") - parser.add_argument( - "-L", - "--level", - type=int, - default=None, - help="Limit the depth of the tree.", - ) - parser.add_argument( - "root", - type=str, - nargs="?", - default=None, - help="Optional root obj to dump.", - ) - try: - args = parser.parse_args(gdb.string_to_argv(args)) - except SystemExit: - return - - if args.root: - root = gdb.parse_and_eval(args.root) - root = LVObject(root) - self.dump_obj(root, limit=args.level) - else: - # dump all displays - depth = 0 - for disp in g_lvgl_instance.displays(): - print(f"Display {hex(disp)}") - for screen in disp.screens: - print(f'{" " * (depth + 1)}Screen@{hex(screen)}') - self.dump_obj(screen, depth=depth + 1, limit=args.level) - - -class InfoStyle(gdb.Command): - """dump obj style value for specified obj""" - - def __init__(self): - super(InfoStyle, self).__init__( - "info style", gdb.COMMAND_USER, gdb.COMPLETE_EXPRESSION - ) - - def invoke(self, args, from_tty): - parser = argparse.ArgumentParser(description="Dump lvgl obj local style.") - parser.add_argument( - "obj", - type=str, - help="obj to show style.", - ) - - try: - args = parser.parse_args(gdb.string_to_argv(args)) - except SystemExit: - return - - obj = gdb.parse_and_eval(args.obj) - if not obj: - print("Invalid obj: ", args.obj) - return - - obj = Value(obj) - - # show all styles applied to this obj - for style in LVObject(obj).styles: - print(" ", end="") - dump_style_info(style) - - -class InfoDrawUnit(gdb.Command): - """dump draw unit info""" - - def __init__(self): - super(InfoDrawUnit, self).__init__( - "info draw_unit", gdb.COMMAND_USER, gdb.COMPLETE_EXPRESSION - ) - - def dump_draw_unit(self, draw_unit: Value): - # Dereference to get the string content of the name from draw_unit - name = draw_unit.name.string() - - # Print draw_unit information and the name - print(f"Draw Unit: {draw_unit}, Name: {name}") - - # Handle different draw_units based on the name - def lookup_type(name): - try: - return gdb.lookup_type(name) - except gdb.error: - return None - - types = { - "DMA2D": lookup_type("lv_draw_dma2d_unit_t"), - "NEMA_GFX": lookup_type("lv_draw_nema_gfx_unit_t"), - "NXP_PXP": lookup_type("lv_draw_pxp_unit_t"), - "NXP_VGLITE": lookup_type("lv_draw_vglite_unit_t"), - "OPENGLES": lookup_type("lv_draw_opengles_unit_t"), - "DAVE2D": lookup_type("lv_draw_dave2d_unit_t"), - "SDL": lookup_type("lv_draw_sdl_unit_t"), - "SW": lookup_type("lv_draw_sw_unit_t"), - "VG_LITE": lookup_type("lv_draw_vg_lite_unit_t"), - } - - type = types.get(name, lookup_type("lv_draw_unit_t")) - print(draw_unit.cast(type, ptr=True).dereference().format_string(pretty_structs=True, symbols=True)) - - def invoke(self, args, from_tty): - for unit in g_lvgl_instance.draw_units(): - self.dump_draw_unit(unit) diff --git a/scripts/gdb/lvglgdb/lvgl/__init__.py b/scripts/gdb/lvglgdb/lvgl/__init__.py new file mode 100644 index 0000000000..ac043bfbd5 --- /dev/null +++ b/scripts/gdb/lvglgdb/lvgl/__init__.py @@ -0,0 +1,14 @@ +from .core import LVObject, curr_inst, dump_obj_info +from .display import LVDisplay +from .draw import LVDrawBuf +from .misc import LVList, dump_style_info + +__all__ = [ + "LVObject", + "LVDisplay", + "LVDrawBuf", + "curr_inst", + "LVList", + "dump_style_info", + "dump_obj_info", +] diff --git a/scripts/gdb/lvglgdb/lvgl/core/__init__.py b/scripts/gdb/lvglgdb/lvgl/core/__init__.py new file mode 100644 index 0000000000..fa320a7fad --- /dev/null +++ b/scripts/gdb/lvglgdb/lvgl/core/__init__.py @@ -0,0 +1,8 @@ +from .lv_obj import LVObject, dump_obj_info +from .lv_global import curr_inst + +__all__ = [ + "LVObject", + "curr_inst", + "dump_obj_info", +] diff --git a/scripts/gdb/lvglgdb/lvgl/core/lv_global.py b/scripts/gdb/lvglgdb/lvgl/core/lv_global.py new file mode 100644 index 0000000000..e62739725a --- /dev/null +++ b/scripts/gdb/lvglgdb/lvgl/core/lv_global.py @@ -0,0 +1,107 @@ +import gdb +from typing import Optional, Union, Iterator, TYPE_CHECKING + +from lvglgdb.value import Value +from ..misc.lv_ll import LVList + +""" +LVGL global instance + +Note: + lv_global is the global instance of LVGL. + It will contain other components like display, draw unit, etc. + So if you want add a new component, please add it in this class. + And just import your component when you need it. Not expose to the whole file. +""" + +__all__ = ["curr_inst"] + +""" +Type hint for IDE, just imported at typechecking phase not in runtime. +""" +if TYPE_CHECKING: + from ..display.lv_display import LVDisplay + + +class LVGL: + """LVGL instance""" + + def __init__(self, lv_global: Value): + self.lv_global = lv_global.cast("lv_global_t", ptr=True) + + def displays(self) -> "Iterator[LVDisplay]": + ll = self.lv_global.disp_ll + if not ll: + return + + from ..display.lv_display import LVDisplay + + for disp in LVList(ll, "lv_display_t"): + yield LVDisplay(disp) + + def disp_default(self): + from ..display.lv_display import LVDisplay + + disp_default = self.lv_global.disp_default + return LVDisplay(disp_default) if disp_default else None + + def screen_active(self): + disp = self.lv_global.disp_default + return disp.act_scr if disp else None + + def draw_units(self): + unit = self.lv_global.draw_info.unit_head + + # Iterate through all draw units + while unit: + yield unit + unit = unit.next + + +class _LVGLSingleton: + __slots__ = ("_lvgl", "_ready") + + def __init__(self) -> None: + self._lvgl: Optional[object] = None + self._ready = False + + def ensure_init(self, lv_global: Union[gdb.Value, Value, None] = None) -> bool: + if self._ready: + return True + + if lv_global is None: + try: + lv_global = Value(gdb.parse_and_eval("lv_global").address) + except gdb.error as e: + print(f"Failed to get lv_global: {e}") + return False + elif not isinstance(lv_global, Value): + lv_global = Value(lv_global) + + if not lv_global.inited: + print( + "\x1b[31mlvgl is not initialized yet. " + "Please call `ensure_init()` later.\x1b[0m" + ) + return False + + self._lvgl = LVGL(lv_global) + self._ready = True + return True + + def __getattr__(self, name: str): + if not self._ready and not self.ensure_init(): + raise RuntimeError("LVGL singleton not ready") + return getattr(self._lvgl, name) + + def reset(self) -> None: + self._lvgl = None + self._ready = False + + +__curr_inst = _LVGLSingleton() + + +def curr_inst() -> _LVGLSingleton: + """Get the global instance of LVGL""" + return __curr_inst diff --git a/scripts/gdb/lvglgdb/lvgl/core/lv_obj.py b/scripts/gdb/lvglgdb/lvgl/core/lv_obj.py new file mode 100644 index 0000000000..7fbaccaedc --- /dev/null +++ b/scripts/gdb/lvglgdb/lvgl/core/lv_obj.py @@ -0,0 +1,72 @@ +from lvglgdb.value import Value + + +class LVObject(Value): + """LVGL object""" + + def __init__(self, obj: Value): + super().__init__(obj.cast("lv_obj_t", ptr=True)) + + @property + def class_name(self): + name = self.class_p.name + return name.string() if name else "unknown" + + @property + def x1(self): + return int(self.coords.x1) + + @property + def y1(self): + return int(self.coords.y1) + + @property + def x2(self): + return int(self.coords.x2) + + @property + def y2(self): + return int(self.coords.y2) + + @property + def child_count(self): + return self.spec_attr.child_cnt if self.spec_attr else 0 + + @property + def children(self): + if not self.spec_attr: + return + + for i in range(self.child_count): + child = self.spec_attr.children[i] + yield LVObject(child) + + @property + def styles(self): + LV_STYLE_PROP_INV = 0 + LV_STYLE_PROP_ANY = 0xFF + count = self.style_cnt + if count == 0: + return + + styles = self.super_value("styles") + for i in range(count): + style = styles[i].style + prop_cnt = style.prop_cnt + values_and_props = style.values_and_props.cast( + "lv_style_const_prop_t", ptr=True + ) + for j in range(prop_cnt): + prop = values_and_props[j].prop + if prop == LV_STYLE_PROP_INV or prop == LV_STYLE_PROP_ANY: + continue + yield values_and_props[j] + + def get_child(self, index: int): + return self.spec_attr.children[index] if self.spec_attr else None + + +def dump_obj_info(obj: LVObject): + clzname = obj.class_name + coords = f"{obj.x1},{obj.y1},{obj.x2},{obj.y2}" + print(f"{clzname}@{hex(obj)} {coords}") diff --git a/scripts/gdb/lvglgdb/lvgl/display/__init__.py b/scripts/gdb/lvglgdb/lvgl/display/__init__.py new file mode 100644 index 0000000000..136d6ea665 --- /dev/null +++ b/scripts/gdb/lvglgdb/lvgl/display/__init__.py @@ -0,0 +1,5 @@ +from .lv_display import LVDisplay + +__all__ = [ + "LVDisplay", +] diff --git a/scripts/gdb/lvglgdb/lvgl/display/lv_display.py b/scripts/gdb/lvglgdb/lvgl/display/lv_display.py new file mode 100644 index 0000000000..e6643c572d --- /dev/null +++ b/scripts/gdb/lvglgdb/lvgl/display/lv_display.py @@ -0,0 +1,45 @@ +from ..core.lv_obj import LVObject +from ..draw.lv_draw_buf import LVDrawBuf +from lvglgdb.value import Value + + +class LVDisplay(Value): + """LVGL display""" + + def __init__(self, disp: Value): + super().__init__(disp) + + @property + def hor_res(self) -> int: + """Get horizontal resolution in pixels""" + return int(self.super_value("hor_res")) + + @property + def ver_res(self) -> int: + """Get vertical resolution in pixels""" + return int(self.super_value("ver_res")) + + @property + def screens(self): + screens = self.super_value("screens") + for i in range(self.screen_cnt): + yield LVObject(screens[i]) + + # Buffer-related properties + @property + def buf_1(self): + """Get first draw buffer (may be None)""" + buf_ptr = self.super_value("buf_1") + return LVDrawBuf(buf_ptr) if buf_ptr else None + + @property + def buf_2(self): + """Get second draw buffer (may be None)""" + buf_ptr = self.super_value("buf_2") + return LVDrawBuf(buf_ptr) if buf_ptr else None + + @property + def buf_act(self): + """Get currently active draw buffer (may be None)""" + buf_ptr = self.super_value("buf_act") + return LVDrawBuf(buf_ptr) if buf_ptr else None diff --git a/scripts/gdb/lvglgdb/lvgl/draw/__init__.py b/scripts/gdb/lvglgdb/lvgl/draw/__init__.py new file mode 100644 index 0000000000..3cb93d1c11 --- /dev/null +++ b/scripts/gdb/lvglgdb/lvgl/draw/__init__.py @@ -0,0 +1,5 @@ +from .lv_draw_buf import LVDrawBuf + +__all__ = [ + "LVDrawBuf", +] diff --git a/scripts/gdb/lvglgdb/lvgl/draw/lv_draw.py b/scripts/gdb/lvglgdb/lvgl/draw/lv_draw.py new file mode 100644 index 0000000000..e69de29bb2 diff --git a/scripts/gdb/lvglgdb/lvgl/draw/lv_draw_buf.py b/scripts/gdb/lvglgdb/lvgl/draw/lv_draw_buf.py new file mode 100644 index 0000000000..a1c6840878 --- /dev/null +++ b/scripts/gdb/lvglgdb/lvgl/draw/lv_draw_buf.py @@ -0,0 +1,199 @@ +from pathlib import Path +from typing import Optional +import gdb + +import numpy as np +from PIL import Image + +from lvglgdb.value import Value + + +class LVDrawBuf(Value): + """LVGL draw buffer""" + + _color_formats = { + "RGB565": None, + "RGB888": None, + "ARGB8888": None, + "XRGB8888": None, + } + + _bpp = { + "RGB565": 16, + "RGB888": 24, + "ARGB8888": 32, + "XRGB8888": 32, + } + + def __init__(self, draw_buf: Value): + super().__init__(draw_buf) + self._init_color_formats() + + def _init_color_formats(self): + """init color formats from enum""" + for fmt in self._color_formats.keys(): + if self._color_formats[fmt] is None: + try: + self._color_formats[fmt] = int( + gdb.parse_and_eval(f"LV_COLOR_FORMAT_{fmt}") + ) + except gdb.error: + print(f"Warning: Failed to get LV_COLOR_FORMAT_{fmt}") + self._color_formats[fmt] = -1 + + def color_format_info(self) -> dict: + """get color format info""" + header = self.super_value("header") + cf = int(header["cf"]) + + fmt_name = "UNKNOWN" + for name, val in self._color_formats.items(): + if val == cf: + fmt_name = name + break + + return {"value": cf, "name": fmt_name, "bpp": self._bpp.get(fmt_name, 0)} + + @property + def header(self) -> dict: + """Get the image header information as a dictionary""" + header = self.super_value("header") + return { + "w": header["w"], + "h": header["h"], + "stride": header["stride"], + "cf": header["cf"], # Color format + } + + @property + def data_size(self) -> int: + """Get the total buffer size in bytes""" + return self.super_value("data_size") + + @property + def data(self) -> bytes: + """Get the buffer data ptr""" + return self.super_value("data") + + def data_dump(self, filename: str, format: str = None) -> bool: + """ + Dump the buffer data to an image file. + + Args: + filename: Output file path + format: Image format (None for auto-detection from filename) + + Returns: + bool: True if successful, False otherwise + """ + try: + # Validate input parameters + if not filename: + raise ValueError("Output filename cannot be empty") + + # Get buffer metadata + header = self.super_value("header") + stride = int(header["stride"]) + height = int(header["h"]) + cf_info = self.color_format_info() + data_ptr = self.super_value("data") + data_size = int(self.super_value("data_size")) + width = (stride * 8) // cf_info["bpp"] if cf_info["bpp"] else 0 + expected_data_size = stride * height + + # Validate buffer data + if not data_ptr: + raise ValueError("Data pointer is NULL") + if width <= 0 or height <= 0: + raise ValueError(f"Invalid dimensions: {width}x{height}") + if data_size <= 0: + raise ValueError(f"Invalid data size: {data_size}") + if data_size < expected_data_size: + raise ValueError(f"Data size mismatch: expected {expected_data_size}, got {data_size}") + elif data_size > expected_data_size: + gdb.write(f"\033[93mData size mismatch: expected {expected_data_size}, got {data_size}\033[0m\n") + + # Read pixel data + pixel_data = ( + gdb.selected_inferior().read_memory(int(data_ptr), expected_data_size).tobytes() + ) + if not pixel_data: + raise ValueError("Failed to read pixel data") + + # Process based on color format + img = self._convert_to_image(pixel_data, width, height, cf_info["value"]) + if img is None: + return False + + # Determine output format + output_format = ( + format.upper() if format else Path(filename).suffix[1:].upper() or "BMP" + ) + + # Save image + img.save(filename, format=output_format) + print( + f"Successfully saved {cf_info['name']} buffer as {output_format} to {filename}" + ) + return True + + except gdb.MemoryError: + print("Error: Failed to access memory") + return False + except ValueError as e: + print(f"Validation error: {str(e)}") + return False + except Exception as e: + print(f"Unexpected error: {str(e)}") + return False + + def _convert_to_image( + self, pixel_data: bytes, width: int, height: int, color_format: int + ) -> Optional[Image.Image]: + """ + Convert raw pixel data to PIL Image based on color format. + + Args: + pixel_data: Raw pixel bytes + width: Image width + height: Image height + color_format: LVGL color format value + + Returns: + PIL.Image or None if conversion fails + """ + try: + if color_format == self._color_formats["RGB565"]: + # Convert RGB565 to RGB888 + arr = np.frombuffer(pixel_data, dtype=np.uint8) + arr = arr.reshape((height, width, 2)) + rgb565 = np.frombuffer(pixel_data, dtype=np.uint16).reshape( + (height, width) + ) + r = (((rgb565 & 0xF800) >> 11) << 3).astype(np.uint8) + g = ((rgb565 & 0x07E0) >> 3).astype(np.uint8) + b = ((rgb565 & 0x001F) << 3).astype(np.uint8) + return Image.fromarray(np.dstack((r, g, b)), "RGB") + + elif color_format == self._color_formats["RGB888"]: + arr = np.frombuffer(pixel_data, dtype=np.uint8).reshape( + height, width, 3 + ) + rgb_arr = arr[:, :, [2, 1, 0]] # BGR -> RGB + return Image.fromarray(rgb_arr, "RGB") + + elif color_format == self._color_formats["ARGB8888"]: + arr = np.frombuffer(pixel_data, dtype=np.uint8).reshape(-1, 4) + rgba = np.column_stack((arr[:, 1:4], arr[:, 0])) # ARGB -> RGBA + return Image.frombytes("RGBA", (width, height), rgba.tobytes()) + + elif color_format == self._color_formats["XRGB8888"]: + arr = np.frombuffer(pixel_data, dtype=np.uint8).reshape(-1, 4) + rgb = arr[:, [2, 1, 0]] # BGR -> RGB + return Image.fromarray(rgb.reshape(height, width, 3), "RGB") + + raise ValueError(f"Unsupported color format: 0x{color_format:x}") + + except Exception as e: + print(f"Conversion error: {str(e)}") + return None diff --git a/scripts/gdb/lvglgdb/lvgl/misc/__init__.py b/scripts/gdb/lvglgdb/lvgl/misc/__init__.py new file mode 100644 index 0000000000..bce06ebf31 --- /dev/null +++ b/scripts/gdb/lvglgdb/lvgl/misc/__init__.py @@ -0,0 +1,7 @@ +from .lv_ll import LVList +from .lv_style import dump_style_info + +__all__ = [ + "LVList", + "dump_style_info", +] diff --git a/scripts/gdb/lvglgdb/lvgl/misc/lv_ll.py b/scripts/gdb/lvglgdb/lvgl/misc/lv_ll.py new file mode 100644 index 0000000000..abb038c88c --- /dev/null +++ b/scripts/gdb/lvglgdb/lvgl/misc/lv_ll.py @@ -0,0 +1,53 @@ +from typing import Union +import gdb + +from lvglgdb.value import Value + + +class LVList(Value): + """LVGL linked list iterator""" + + def __init__(self, ll: Value, nodetype: Union[gdb.Type, str] = None): + if not ll: + raise ValueError("Invalid linked list") + super().__init__(ll) + + self.nodetype = ( + gdb.lookup_type(nodetype).pointer() + if isinstance(nodetype, str) + else nodetype + ) + self.lv_ll_node_t = gdb.lookup_type("lv_ll_node_t").pointer() + self.current = self.head + self._next_offset = self.n_size + self.lv_ll_node_t.sizeof + self._prev_offset = self.n_size + + def _next(self, node): + next_value = Value(int(node) + self._next_offset) + return next_value.cast(self.lv_ll_node_t, ptr=True).dereference() + + def _prev(self, node): + prev_value = Value(int(node) + self._prev_offset) + return prev_value.cast(self.lv_ll_node_t, ptr=True).dereference() + + def __iter__(self): + return self + + def __next__(self): + if not self.current: + raise StopIteration + + nodetype = self.nodetype if self.nodetype else self.lv_ll_node_t + node = self.current.cast(nodetype) + + self.current = self._next(self.current) + return node + + @property + def len(self): + len = 0 + node = self.head + while node: + len += 1 + node = self._next(node) + return len diff --git a/scripts/gdb/lvglgdb/lvgl/misc/lv_style.py b/scripts/gdb/lvglgdb/lvgl/misc/lv_style.py new file mode 100644 index 0000000000..eb621c3a37 --- /dev/null +++ b/scripts/gdb/lvglgdb/lvgl/misc/lv_style.py @@ -0,0 +1,7 @@ +from lvglgdb.value import Value + + +def dump_style_info(style: Value): + prop = int(style.prop) + value = style.value + print(f"{prop} = {value}") diff --git a/scripts/gdb/lvglgdb/value.py b/scripts/gdb/lvglgdb/value.py index 0b2525de78..e215feab31 100644 --- a/scripts/gdb/lvglgdb/value.py +++ b/scripts/gdb/lvglgdb/value.py @@ -4,7 +4,7 @@ class Value(gdb.Value): - def __init__(self, value: Union[gdb.Value, 'Value']): + def __init__(self, value: Union[gdb.Value, "Value"]): super().__init__(value) def __getitem__(self, key): @@ -19,14 +19,18 @@ def __getattr__(self, key): return Value(super().__getattribute__(key)) return Value(super().__getitem__(key)) - def cast(self, type_name: str | gdb.Type, ptr: bool = False) -> Optional['Value']: + def cast( + self, type_name: Union[str, gdb.Type], ptr: bool = False + ) -> Optional["Value"]: try: - gdb_type = gdb.lookup_type(type_name) if isinstance(type_name, str) else type_name + gdb_type = ( + gdb.lookup_type(type_name) if isinstance(type_name, str) else type_name + ) if ptr: gdb_type = gdb_type.pointer() return Value(super().cast(gdb_type)) except gdb.error: return None - def super_value(self, attr: str) -> 'Value': + def super_value(self, attr: str) -> "Value": return self[attr] diff --git a/scripts/generate_cmake_variables.py b/scripts/generate_cmake_variables.py index 888545a7e0..52f9e4d05d 100755 --- a/scripts/generate_cmake_variables.py +++ b/scripts/generate_cmake_variables.py @@ -33,7 +33,7 @@ def get_args(): parser.add_argument("--debug", action="store_true", required=False, help="Show unhandled expressions") - parser.add_argument("--parentscope", action="store_true", required=False, help="Additionaly set the variables in the parent scope") + parser.add_argument("--parentscope", action="store_true", required=False, help="Additionally set the variables in the parent scope") args = parser.parse_args() @@ -58,11 +58,11 @@ def generate_cmake_variables(path_input: str, path_output: str, kconfig: bool, d # If we use Kconfig, we must check the CONFIG_LV_USE_* and # CONFIG_LV_BUILD_* defines if kconfig: - CONFIG_PATTERN="^#define +(CONFIG_LV_USE|CONFIG_LV_BUILD)" + CONFIG_PATTERN="^#define +(CONFIG_LV_USE|CONFIG_LV_BUILD|CONFIG_LV_[0-9A-Z_]+_USE)" CONFIG_PREFIX="" # Otherwise check the LV_USE_* and LV_BUILD_* defines else: - CONFIG_PATTERN="^#define +(LV_USE|LV_BUILD)" + CONFIG_PATTERN="^#define +(LV_USE|LV_BUILD|LV_[0-9A-Z_]+_USE)" CONFIG_PREFIX="CONFIG_" diff --git a/scripts/generate_lv_conf.py b/scripts/generate_lv_conf.py index 7dc88eda39..5e0bb1aa60 100755 --- a/scripts/generate_lv_conf.py +++ b/scripts/generate_lv_conf.py @@ -3,6 +3,7 @@ import os import re import argparse +from pathlib import Path DIR_SCRIPTS = os.path.dirname(__file__) REPO_ROOT = os.path.join(DIR_SCRIPTS, "..") @@ -48,7 +49,8 @@ def get_args(): if not os.path.exists(args.template): fatal(f"Template file not found at {args.template}") if not os.path.exists(args.config): - fatal(f"User config file not found at {args.config}") + print(f"{args.config} not found. Generating it") + Path(args.config).touch() if not os.path.exists(args.defaults): fatal(f"User defaults not found at {args.defaults}") @@ -99,7 +101,7 @@ def generate_config(path_destination: str, path_source: str, defaults: dict): if len(keys_used) != len(defaults): unused_keys = [k for k in defaults.keys() if k not in keys_used] - fatal('The following keys are deprecated:\n ' + '\n '.join(unused_keys)) + print('WARNING: The following keys are deprecated:\n ' + '\n '.join(unused_keys)) with open(path_destination, 'w', encoding='utf-8') as f_dst: for dst_line in dst_lines: diff --git a/scripts/kconfig_verify.py b/scripts/kconfig_verify.py old mode 100644 new mode 100755 index f4c9c12495..53a482df37 --- a/scripts/kconfig_verify.py +++ b/scripts/kconfig_verify.py @@ -21,9 +21,40 @@ def verify_kconfig(kconfig_file): print("No warnings found.") +def check_kconfig_spaces(file_path): + """Check for space-based indentation in a Kconfig file""" + try: + # Read file content to check for spaces + with open(file_path, "r", encoding="utf-8") as f: + lines = f.readlines() + + space_indent_lines = [] + for line_num, line in enumerate(lines, 1): + # Check for leading spaces (skip empty lines) + stripped_line = line.lstrip() + if stripped_line and len(line) > len(stripped_line): + # Extract the indentation part + indent = line[: -len(stripped_line)] if stripped_line else line + if " " in indent: + space_indent_lines.append((line_num, indent)) + + if space_indent_lines: + print(f"Space-based indentation found in file {file_path}:") + for line_num, indent in space_indent_lines: + print(f"Line {line_num}: Indent contains {indent.count(' ')} spaces") + + sys.exit(1) + else: + print(f"No space-based indentation found in file {file_path}") + + except Exception as e: + print(f"Error processing file {file_path}: {e}") + + if __name__ == "__main__": if len(sys.argv) != 2: - print("Usage: python check_kconfig.py ") + print(f"Usage: python {sys.argv[0]} ") sys.exit(1) verify_kconfig(sys.argv[1]) + check_kconfig_spaces(sys.argv[1]) diff --git a/scripts/lv_conf_internal_gen.py b/scripts/lv_conf_internal_gen.py index de7a032fbf..371b3b68a2 100755 --- a/scripts/lv_conf_internal_gen.py +++ b/scripts/lv_conf_internal_gen.py @@ -63,10 +63,10 @@ def check_for_tabs(file_path): #define LV_STDLIB_RTTHREAD 3 #define LV_STDLIB_CUSTOM 255 -#define LV_DRAW_SW_ASM_NONE 0 -#define LV_DRAW_SW_ASM_NEON 1 -#define LV_DRAW_SW_ASM_HELIUM 2 -#define LV_DRAW_SW_ASM_CUSTOM 255 +#define LV_DRAW_SW_ASM_NONE 0 +#define LV_DRAW_SW_ASM_NEON 1 +#define LV_DRAW_SW_ASM_HELIUM 2 +#define LV_DRAW_SW_ASM_CUSTOM 255 #define LV_NEMA_HAL_CUSTOM 0 #define LV_NEMA_HAL_STM32 1 @@ -196,6 +196,15 @@ def check_for_tabs(file_path): #undef LV_KCONFIG_PRESENT +/* Disable VGLite drivers if VGLite drawing is disabled */ +#ifndef LV_USE_VG_LITE_DRIVER + #define LV_USE_VG_LITE_DRIVER 0 +#endif + +#ifndef LV_USE_VG_LITE_THORVG + #define LV_USE_VG_LITE_THORVG 0 +#endif + /* Set some defines if a dependency is disabled. */ #if LV_USE_LOG == 0 #define LV_LOG_LEVEL LV_LOG_LEVEL_NONE @@ -212,12 +221,16 @@ def check_for_tabs(file_path): #if LV_USE_WAYLAND == 0 #define LV_WAYLAND_USE_DMABUF 0 #define LV_WAYLAND_WINDOW_DECORATIONS 0 - #define LV_WAYLAND_WL_SHELL 0 #endif /* LV_USE_WAYLAND */ +#if LV_USE_LINUX_DRM == 0 + #define LV_LINUX_DRM_USE_EGL 0 +#endif /*LV_USE_LINUX_DRM*/ + #if LV_USE_SYSMON == 0 #define LV_USE_PERF_MONITOR 0 #define LV_USE_MEM_MONITOR 0 + #define LV_SYSMON_PROC_IDLE_AVAILABLE 0 #endif /*LV_USE_SYSMON*/ #if LV_USE_PERF_MONITOR == 0 @@ -257,9 +270,13 @@ def check_for_tabs(file_path): #endif #endif +#ifndef LV_USE_EGL + #define LV_USE_EGL LV_LINUX_DRM_USE_EGL +#endif /* LV_USE_EGL */ + #if LV_USE_OS #if (LV_USE_FREETYPE || LV_USE_THORVG) && LV_DRAW_THREAD_STACK_SIZE < (32 * 1024) - #warning "Increase LV_DRAW_THREAD_STACK_SIZE to at least 32KB for FreeType or ThorVG." + #error "Increase LV_DRAW_THREAD_STACK_SIZE to at least 32KB for FreeType or ThorVG." #endif #if defined(LV_DRAW_THREAD_STACKSIZE) && !defined(LV_DRAW_THREAD_STACK_SIZE) diff --git a/scripts/lv_templ_check.py b/scripts/lv_templ_check.py new file mode 100644 index 0000000000..c8c107b8a5 --- /dev/null +++ b/scripts/lv_templ_check.py @@ -0,0 +1,190 @@ +import re +import argparse +import os +import traceback + +ignored_file_prefixes = { + "lv_conf_template.h", + "lv_conf_cmsis.h", + "lv_test_perf_conf.h", + "lv_font_" +} + +ignored_top_dirs = { + ".git", + "docs" +} + +h_filename_pattern = re.compile(r"lv_[\w.]*\.h") +h_pattern = re.compile( + r"\s*/\*\*.+?" + r"@file +(\S*).+?" + r"\*/\s+?#ifndef +(\w+_H)\s+#define +(\w+_H).+" + r"#endif */\* *([^*]+?) *\*/\s*", + flags=re.DOTALL +) + +c_filename_pattern = re.compile(r"lv_[\w.]*\.c") +c_pattern = re.compile( + r"\s*/\*\*.+?" + r"@file +(\S*)", + flags=re.DOTALL +) + +file_comment_help_f = """\ +'{0}' should have at the top: + /** + * @file {1} + * + */ +instead, has: + /** + * @file {2} + * + */ +""" + +guard_help_f = """\ +'{0}' should have include guards like: + #ifndef {1} + #define {1} + ... + #endif /*{1}*/ +instead, has: + #ifndef {2} + #define {3} + ... + #endif /*{4}*/ +""" + +# regex, arg parsing and other stuff skipped here. + +def ignore_file(basename): + result = False + + for pattern in ignored_file_prefixes: + if basename.startswith(pattern): + result = True + break + + return result + + +def ignore_dir(path): + result = False + + for top_dir in ignored_top_dirs: + sub_path = os.path.join('lvgl', top_dir) + if sub_path in path: + result = True + break + + return result + +def debug(*args_, **kwargs): + if args.verbose: + print(*args_, **kwargs) + +arg_parser = argparse.ArgumentParser() +arg_parser.add_argument("--fix", action="store_true", help="fix incorrect files") +arg_parser.add_argument("-q", "--quiet", action="store_true", help="don't print mismatch info") +arg_parser.add_argument("-v", "--verbose", action="store_true", help="print debug info") +args = arg_parser.parse_args() + +cfg_project_dir = '..' +base_dir = os.path.abspath(os.path.dirname(__file__)) +project_dir = os.path.abspath(os.path.join(base_dir, cfg_project_dir)) +debug(f'ignore dirs [{ignored_top_dirs}]') + +ok = True + +for root, dirs, basenames in os.walk(project_dir): + if ignore_dir(root): + continue + + debug(f'root [{root}]') + for basename in basenames: + if ignore_file(basename): + continue + + file_ok = True + a_file_was_processed = False + path = os.path.join(root, basename) + + # ------------------------------------------------------------- + # H File? + # ------------------------------------------------------------- + if h_filename_pattern.fullmatch(basename): + a_file_was_processed = True + debug(f'Opening H file [{path}]') + + try: + with open(path, 'rb') as f: + cont = f.read().decode('utf-8') + except: + print(f'Error attempting UTF-8 decode on [{path}].') + traceback.print_exc() + continue + + m = h_pattern.fullmatch(cont) + if m is not None: + debug(' Match.') + if m[1] != basename: + file_ok = False + if not args.quiet: + print(file_comment_help_f.format(path, basename, m[1])) + + guard_name = f"LV_{basename[3:-2].upper()}_H" + if any(m[i] != guard_name for i in range(2, 4+1)): + file_ok = False + if not args.quiet: + print(guard_help_f.format(path, guard_name, m[2], m[3], m[4])) + + replacements = (basename, guard_name, guard_name, guard_name) + else: + debug(f' No match with regex [{h_pattern.pattern}].') + + # ------------------------------------------------------------- + # C File? + # ------------------------------------------------------------- + elif c_filename_pattern.fullmatch(basename): + a_file_was_processed = True + debug(f'Opening C file [{path}]') + + try: + with open(path, 'rb') as f: + cont = f.read().decode('utf-8') + except: + print(f'Error attempting UTF-8 decode on [{path}].') + traceback.print_exc() + continue + + m = c_pattern.match(cont) + if m is not None: + debug(' Match.') + if m[1] != basename: + file_ok = False + if not args.quiet: + print(file_comment_help_f.format(path, basename, m[1])) + + replacements = (basename, ) + else: + debug(f' No match with regex [{c_pattern.pattern}].') + + if a_file_was_processed: + if not file_ok: + debug(f'NOT OK [{path}]') + ok = False + if args.fix: + for i in reversed(range(0, len(replacements))): + span = m.regs[i + 1] + repl = replacements[i] + cont = cont[:span[0]] + repl + cont[span[1]:] + with open(path, "w") as f: + f.write(cont) + else: + debug(f'OK [{path}]') + + +if not ok: + exit(1) diff --git a/scripts/perf/benchmark_results_comment.py b/scripts/perf/benchmark_results_comment.py new file mode 100644 index 0000000000..f8d7ddbc72 --- /dev/null +++ b/scripts/perf/benchmark_results_comment.py @@ -0,0 +1,237 @@ +""" +This script takes json and mpk input files and creates a PR comment in markdown format. + +An mpk (msgpack) file contains the benchmark result history for a specific config. +Unpacked, this file will have the following format: +```json +[ + { + "commit_hash": "" + "scenes": [ + { + "scene_name": "", + "avg_cpu": 0, + "avg_fps": 0, + "avg_time": 0, + "render_time": 0, + "flush_time": 0, + }, + ... + ] + }, + ... +] +``` + +A json file contains the benchmark result for a specific commit: + +```json +[ + { + "scene_name": "", + "avg_cpu": 0, + "avg_fps": 0, + "avg_time": 0, + "render_time": 0, + "flush_time": 0, + } + ... +] +``` + +This script reads the previous and new benchmark results, compares them and creates a comment. + +Example comment: + +``` +Hi :wave:, thank you for your PR! + +We've run benchmarks in an emulated environment. Here are the results: + +#### ARM Emulated 32b - lv_conf_perf32b + +| Scene Name | Avg CPU (%) | Avg FPS | Avg Time (ms) | Render Time (ms) | Flush Time (ms) | +|------------|------------|---------|--------------|----------------|--------------| +| All scenes avg. | 20 | 24 | 7 | 7 | 0 | + +
+ +Detailed Results Per Scene + + +| Scene Name | Avg CPU (%) | Avg FPS | Avg Time (ms) | Render Time (ms) | Flush Time (ms) | +|------------|------------|---------|--------------|----------------|--------------| +| Empty screen | 11 | 25 | 0 | 0 | 0 | +| Moving wallpaper | 1 | 25 | 0 | 0 | 0 | +| Single rectangle | 0 | 25 | 0 | 0 | 0 | +| Multiple rectangles | 0 | 25 | 0 | 0 | 0 | +| Multiple RGB images | 0 | 25 | 0 | 0 | 0 | +| Multiple ARGB images | 22 (-1)| 25 | 1 | 1 | 0 | +| Rotated ARGB images | 47 (-1)| 24 | 20 | 20 | 0 | +| Multiple labels | 2 (-2)| 25 | 0 | 0 | 0 | +| Screen sized text | 30 (+1)| 24 (-1)| 11 (-1)| 11 (-1)| 0 | +| Multiple arcs | 19 (+4)| 24 | 7 | 7 | 0 | +| Containers | 1 (-1)| 25 | 0 | 0 | 0 | +| Containers with overlay | 87 (-2)| 21 | 44 | 44 | 0 | +| Containers with opa | 23 (+1)| 25 | 4 | 4 | 0 | +| Containers with opa_layer | 22 (+1)| 25 | 8 | 8 | 0 | +| Containers with scrolling | 25 | 25 | 10 | 10 | 0 | +| Widgets demo | 34 | 24 (-1)| 13 | 13 | 0 | +| All scenes avg. | 20 | 24 | 7 | 7 | 0 | + + +
+ + +Disclaimer: These benchmarks were run in an emulated environment using QEMU with instruction counting mode. +The timing values represent relative performance metrics within this specific virtualized setup and should +not be interpreted as absolute real-world performance measurements. Values are deterministic and useful for +comparing different LVGL features and configurations, but may not correlate directly with performance on +physical hardware. The measurements are intended for comparative analysis only. + + +--- + +:robot: This comment was automatically generated by a bot. +``` +""" + +import argparse +import json +import os +import msgpack + + +DISCLAIMER = """ +Disclaimer: These benchmarks were run in an emulated environment using QEMU with instruction counting mode. +The timing values represent relative performance metrics within this specific virtualized setup and should +not be interpreted as absolute real-world performance measurements. Values are deterministic and useful for +comparing different LVGL features and configurations, but may not correlate directly with performance on +physical hardware. The measurements are intended for comparative analysis only. +""" + + +def format_table(results: list[dict], prev_results: list[dict]): + + table = "| Scene Name | Avg CPU (%) | Avg FPS | Avg Time (ms) | Render Time (ms) | Flush Time (ms) |\n" + table += "|------------|------------|---------|--------------|----------------|--------------|\n" + data_keys = ["avg_cpu", "avg_fps", "avg_time", "render_time", "flush_time"] + + for scene_results, prev_scene_results in zip(results, prev_results): + delta_p = { + key: ((scene_results[key] - prev_scene_results[key])) for key in data_keys + } + table += f"| {scene_results['scene_name']} |" + for key in data_keys: + if delta_p[key] == 0: + table += f" {scene_results[key]} |" + else: + table += f" {scene_results[key]} ({delta_p[key]:+})|" + table += "\n" + + return table + + +def main(): + parser = argparse.ArgumentParser( + description="Process previous and new results, and output a comment file." + ) + + parser.add_argument( + "--previous", + type=str, + nargs="+", + required=False, + help="Path to the previous results file (supports multiple, e.g., results*.mpk)", + ) + parser.add_argument( + "--new", + type=str, + nargs="+", + required=True, + help="Paths to new results files (supports multiple, e.g., results*.json)", + ) + parser.add_argument( + "-o", + "--output", + type=str, + required=True, + help="Output file path (e.g., comment.md)", + ) + + args = parser.parse_args() + previous_results_paths = args.previous + results_paths = args.new + output_path = args.output + + previous_results_map: dict[str, list[dict]] = {} + if previous_results_paths: + for results_path in previous_results_paths: + _, image_type, config = results_path.replace(".mpk", "").split("-") + + with open(results_path, "rb") as f: + previousb = f.read() + rs: list = msgpack.unpackb(previousb) + # We store the filename so it's easier to match with the related results + previous_results_map[os.path.basename(results_path)] = rs + + new_results: dict[str, list[dict]] = {} + for results_path in results_paths: + with open(results_path, "r") as f: + r: list[dict] = json.load(f) + # We store the filename so it's easier to match with the related results + new_results[os.path.basename(results_path)] = r + + comment = "Hi :wave:, thank you for your PR!\n\n" + comment += "We've run benchmarks in an emulated environment." + comment += " Here are the results:\n\n" + + for result_path, result in new_results.items(): + mpk_path = result_path.replace(".json", ".mpk") + + new_all_scene_avg = [ + scene for scene in result if scene["scene_name"] == "All scenes avg." + ] + + prev_results = previous_results_map.get(mpk_path, []) + + if len(prev_results) > 0: + prev_scenes = prev_results[-1]["scenes"] + prev_all_scene_avg = [ + [ + scene + for scene in prev_scenes + if scene["scene_name"] == "All scenes avg." + ][0] + ] + prev_results = prev_scenes + else: + # If there are no previous results, we use the current result as + # the previous aswell + # In this case, the difference will always be zero and we won't + # add any new information to the result table + prev_results = result + prev_all_scene_avg = new_all_scene_avg + + _, image_type, config = result_path.replace(".json", "").split("-") + comment += f"#### ARM Emulated {image_type} - {config}\n\n" + comment += format_table(new_all_scene_avg, prev_all_scene_avg) + comment += "\n
" + comment += "\n" + comment += "\nDetailed Results Per Scene" + comment += "\n\n\n" + comment += format_table(result, prev_results) + comment += "\n\n
\n\n" + + comment += DISCLAIMER + comment += "\n\n" + comment += "---" + comment += "\n\n" + comment += ":robot: This comment was automatically generated by a bot." + + with open(output_path, "w") as f: + f.write(comment) + + +if __name__ == "__main__": + main() diff --git a/scripts/perf/filter_docker_benchmark_logs.py b/scripts/perf/filter_docker_benchmark_logs.py new file mode 100644 index 0000000000..85bf15bbf2 --- /dev/null +++ b/scripts/perf/filter_docker_benchmark_logs.py @@ -0,0 +1,101 @@ +""" +This script parses a docker logs file for the lv_benchmark summary results + +The input looks something like: +``` +{"log":"SO3: starting the initial process ...\r\n","stream":"stdout","time":"2025-03-14T20:32:17.712134853Z"} +{"log":"\r\n","stream":"stdout","time":"2025-03-14T20:32:17.712146014Z"} +{"log":"\r\n","stream":"stdout","time":"2025-03-14T20:32:17.712150624Z"} +{"log":"Starting LVGL Benchmark\r\n","stream":"stdout","time":"2025-03-14T20:32:17.816299617Z"} +{"log":"Warning: The guest is now late by 0.0 to 1.0 seconds\r\n","stream":"stdout","time":"2025-03-14T20:32:19.129030996Z"} +{"log":"Warning: The guest is now late by 1.0 to 2.0 seconds\r\n","stream":"stdout","time":"2025-03-14T20:32:40.699491404Z"} +{"log":"Warning: The guest is now late by 2.0 to 3.0 seconds\r\n","stream":"stdout","time":"2025-03-14T20:33:02.966355127Z"} +{"log":"Warning: The guest is now late by 3.0 to 4.0 seconds\r\n","stream":"stdout","time":"2025-03-14T20:33:30.06251689Z"} +{"log":"Warning: The guest is now late by 4.0 to 5.0 seconds\r\n","stream":"stdout","time":"2025-03-14T20:33:38.253535255Z"} +{"log":"Warning: The guest is now late by 5.0 to 6.0 seconds\r\n","stream":"stdout","time":"2025-03-14T20:33:51.010250882Z"} +{"log":"Benchmark Summary (9.3.0 dev)\r\r\n","stream":"stdout","time":"2025-03-14T20:33:57.855785347Z"} +{"log":"Name, Avg. CPU, Avg. FPS, Avg. time, render time, flush time\r\r\n","stream":"stdout","time":"2025-03-14T20:33:57.855997881Z"} +{"log":"Empty screen, 11%, 25, 0, 0, 0\r\r\n","stream":"stdout","time":"2025-03-14T20:33:57.857828373Z"} +{"log":"Moving wallpaper, 2%, 25, 0, 0, 0\r\r\n","stream":"stdout","time":"2025-03-14T20:33:57.858455924Z"} +{"log":"Single rectangle, 0%, 25, 0, 0, 0\r\r\n","stream":"stdout","time":"2025-03-14T20:33:57.859125276Z"} +{"log":"Multiple rectangles, 0%, 25, 0, 0, 0\r\r\n","stream":"stdout","time":"2025-03-14T20:33:57.859847899Z"} +{"log":"Multiple RGB images, 0%, 25, 0, 0, 0\r\r\n","stream":"stdout","time":"2025-03-14T20:33:57.860658884Z"} +{"log":"Multiple ARGB images, 23%, 25, 1, 1, 0\r\r\n","stream":"stdout","time":"2025-03-14T20:33:57.86156999Z"} +{"log":"Rotated ARGB images, 48%, 24, 20, 20, 0\r\r\n","stream":"stdout","time":"2025-03-14T20:33:57.862511197Z"} +{"log":"Multiple labels, 3%, 25, 0, 0, 0\r\r\n","stream":"stdout","time":"2025-03-14T20:33:57.863549175Z"} +{"log":"Screen sized text, 30%, 24, 11, 11, 0\r\r\n","stream":"stdout","time":"2025-03-14T20:33:57.864642275Z"} +{"log":"Multiple arcs, 18%, 24, 7, 7, 0\r\r\n","stream":"stdout","time":"2025-03-14T20:33:57.865801475Z"} +{"log":"Containers, 3%, 25, 0, 0, 0\r\r\n","stream":"stdout","time":"2025-03-14T20:33:57.867039657Z"} +{"log":"Containers with overlay, 88%, 21, 44, 44, 0\r\r\n","stream":"stdout","time":"2025-03-14T20:33:57.868379231Z"} +{"log":"Containers with opa, 10%, 24, 3, 3, 0\r\r\n","stream":"stdout","time":"2025-03-14T20:33:57.869736765Z"} +{"log":"Containers with opa_layer, 22%, 24, 8, 8, 0\r\r\n","stream":"stdout","time":"2025-03-14T20:33:57.871269383Z"} +{"log":"Containers with scrolling, 25%, 25, 10, 10, 0\r\r\n","stream":"stdout","time":"2025-03-14T20:33:57.872899952Z"} +{"log":"Widgets demo, 34%, 25, 13, 13, 0\r\r\n","stream":"stdout","time":"2025-03-14T20:33:57.874447759Z"} +{"log":"All scenes avg.,19%, 24, 7, 7, 0\r\r\n","stream":"stdout","time":"2025-03-14T20:33:57.875031879Z"} +{"log":"LVGL Benchmark Over\r\n","stream":"stdout","time":"2025-03-14T20:33:57.933458479Z"} +```` + +Outpus a json file with the format: +```json +[ + { + "scene_name": "", + "avg_cpu": 0, + "avg_fps": 0, + "avg_time": 0, + "render_time": 0, + "flush_time": 0, + } + ... +] +``` +""" + +import sys +import json + + +def main(): + if len(sys.argv) < 2: + print("Missing output path") + return + + output_path = sys.argv[1] + found_start_of_results = False + found_header = False + results = [] + for line in sys.stdin: + if "Benchmark Summary" in line: + found_start_of_results = True + continue + if not found_start_of_results: + continue + + fmt_line: str = json.loads(line)["log"].strip() + cols = fmt_line.split(",") + if len(cols) < 6: + if fmt_line != "LVGL Benchmark Over": + print(f"Warning found invalid log line '{fmt_line}'. Skipping...") + continue + + if not found_header: + found_header = True + continue + + results.append( + { + "scene_name": cols[0], + "avg_cpu": int(cols[1].replace("%", "")), + "avg_fps": int(cols[2]), + "avg_time": int(cols[3]), + "render_time": int(cols[4]), + "flush_time": int(cols[5]), + } + ) + + with open(output_path, "w") as f: + json.dump(results, f) + + +if __name__ == "__main__": + main() diff --git a/scripts/perf/lvperf_dependencies.sh b/scripts/perf/lvperf_dependencies.sh new file mode 100755 index 0000000000..2019c84524 --- /dev/null +++ b/scripts/perf/lvperf_dependencies.sh @@ -0,0 +1,9 @@ +#!/bin/sh + +# This script installs extra dependencies for the lvperf Docker images used in the CI pipeline. +# The images are based on Alpine Linux and support runtime installation of dependencies, +# allowing you to extend functionality without rebuilding the image. +# +# For guidance on how dependencies are typically added, refer to the Dockerfiles: +# - https://github.com/smartobjectoriented/so3/blob/main/docker/Dockerfile.lvperf_32b +# - https://github.com/smartobjectoriented/so3/blob/main/docker/Dockerfile.lvperf_64b diff --git a/scripts/perf/serialize_results.py b/scripts/perf/serialize_results.py new file mode 100644 index 0000000000..85fd9d3d27 --- /dev/null +++ b/scripts/perf/serialize_results.py @@ -0,0 +1,151 @@ +""" +This script takes json and mpk input files and combines them + +An mpk (msgpack) file contains the benchmark result history for a specific config. +Unpacked, this file will have the following format: +```json +[ + { + "commit_hash": "" + "scenes": [ + { + "scene_name": "", + "avg_cpu": 0, + "avg_fps": 0, + "avg_time": 0, + "render_time": 0, + "flush_time": 0, + } + ... + ] + }, + ... +] +``` + +A json file contains the benchmark result for a specific commit: + +```json +[ + { + "scene_name": "", + "avg_cpu": 0, + "avg_fps": 0, + "avg_time": 0, + "render_time": 0, + "flush_time": 0, + } + ... +] +``` + +This script combines the json files with the mpk files and outputs new mpk files + +The files are expected to follow the format 'results--.[mpk|json]' + +There are 3 possibilities when handling these files + +1. The pair (`file1.mpk` `file1.json`) exists: Normal operation, we have a history file and some new results. + In this case we take the information inside the `file1.json` and append it to the `file1.mpk` before exporting it + +2. `file1.json` exists but `file1.mpk` doesn't: Happens when a new config and/or image type are added and there's no history yet + In this case we create a new `file1.mpk` with a single history entry. + +3. `file1.mpk` exists but `file1.json` doesn't: Happens when an old config isn't tested anymore for any reason. + In this case we simpyl copy the old `file1.mpk` +""" + +import argparse +import os +import shutil +import msgpack +import json + + +def save_mpk(mpk_path, mpk_data): + + with open(mpk_path, "wb") as f: + f.write(mpk_data) + + +def generate_new_mpk(json_path, output_path, commit_hash): + + with open(json_path, "r") as f: + json_data: list = json.load(f) + + mpk_data = msgpack.packb([{"commit_hash": commit_hash, "scenes": json_data}]) + save_mpk(output_path, mpk_data) + + +def append_json_to_mpk(mpk_path, json_path, output_path, commit_hash): + with open(mpk_path, "rb") as f: + mpk_data: list = msgpack.unpackb(f.read()) + + with open(json_path, "r") as f: + json_data = json.load(f) + + mpk_data.append({"commit_hash": commit_hash, "scenes": json_data}) + + save_mpk(output_path, msgpack.packb(mpk_data)) + + +def path(folder, filename): + return os.path.join(folder, filename) + + +def main(): + parser = argparse.ArgumentParser( + description="Merge new results into previous results" + ) + + parser.add_argument("--commit-hash", type=str, required=True, help="Commit Hash") + parser.add_argument( + "--input", + type=str, + required=True, + help="Input Folder", + ) + parser.add_argument( + "--output", + type=str, + required=True, + help="Output Folder", + ) + + args = parser.parse_args() + input_folder: str = args.input + output_folder: str = args.output + commit_hash: str = args.commit_hash + + input_files = os.listdir(input_folder) + input_mpk: set[str] = {file for file in input_files if ".mpk" in file} + input_json: list[str] = [file for file in input_files if ".json" in file] + + for json_file in input_json: + mpk_file = json_file.replace(".json", ".mpk") + json_path = path(input_folder, json_file) + output_path = path(output_folder, mpk_file) + + if mpk_file not in input_mpk: + # First time this config is being run + print( + f"Couldn't find pair for {json_file} - ({mpk_file} not found). Generating new mpk file" + ) + generate_new_mpk(json_path, output_path, commit_hash) + else: + print(f"Found pair ({mpk_file} {json_file}). Combining") + mpk_path = path(input_folder, mpk_file) + + append_json_to_mpk(mpk_path, json_path, output_path, commit_hash) + input_mpk.remove(mpk_file) + + # Keep old mpk files + for mpk_file in input_mpk: + print(f"Couldn't find new reults to add to {mpk_file}. Copying it") + mpk_path = path(input_folder, mpk_file) + output_path = path(output_folder, mpk_file) + shutil.copy2(mpk_path, output_path) + + +if __name__ == "__main__": + main() diff --git a/scripts/perf/tests/benchmark_results_comment/no_mpk/expected.md b/scripts/perf/tests/benchmark_results_comment/no_mpk/expected.md new file mode 100644 index 0000000000..0686f4ec82 --- /dev/null +++ b/scripts/perf/tests/benchmark_results_comment/no_mpk/expected.md @@ -0,0 +1,83 @@ +Hi :wave:, thank you for your PR! + +We've run benchmarks in an emulated environment. Here are the results: + +#### ARM Emulated 32b - lv_conf_perf32b + +| Scene Name | Avg CPU (%) | Avg FPS | Avg Time (ms) | Render Time (ms) | Flush Time (ms) | +|------------|------------|---------|--------------|----------------|--------------| +| All scenes avg. | 20 | 24 | 7 | 7 | 0 | + +
+ +Detailed Results Per Scene + + +| Scene Name | Avg CPU (%) | Avg FPS | Avg Time (ms) | Render Time (ms) | Flush Time (ms) | +|------------|------------|---------|--------------|----------------|--------------| +| Empty screen | 11 | 25 | 0 | 0 | 0 | +| Moving wallpaper | 1 | 25 | 0 | 0 | 0 | +| Single rectangle | 0 | 25 | 0 | 0 | 0 | +| Multiple rectangles | 0 | 25 | 0 | 0 | 0 | +| Multiple RGB images | 0 | 25 | 0 | 0 | 0 | +| Multiple ARGB images | 22 | 25 | 1 | 1 | 0 | +| Rotated ARGB images | 47 | 24 | 20 | 20 | 0 | +| Multiple labels | 2 | 25 | 0 | 0 | 0 | +| Screen sized text | 30 | 24 | 11 | 11 | 0 | +| Multiple arcs | 19 | 24 | 7 | 7 | 0 | +| Containers | 1 | 25 | 0 | 0 | 0 | +| Containers with overlay | 87 | 21 | 44 | 44 | 0 | +| Containers with opa | 23 | 25 | 4 | 4 | 0 | +| Containers with opa_layer | 22 | 25 | 8 | 8 | 0 | +| Containers with scrolling | 25 | 25 | 10 | 10 | 0 | +| Widgets demo | 34 | 24 | 13 | 13 | 0 | +| All scenes avg. | 20 | 24 | 7 | 7 | 0 | + + +
+ +#### ARM Emulated 64b - lv_conf_perf64b + +| Scene Name | Avg CPU (%) | Avg FPS | Avg Time (ms) | Render Time (ms) | Flush Time (ms) | +|------------|------------|---------|--------------|----------------|--------------| +| All scenes avg. | 16 | 24 | 6 | 6 | 0 | + +
+ +Detailed Results Per Scene + + +| Scene Name | Avg CPU (%) | Avg FPS | Avg Time (ms) | Render Time (ms) | Flush Time (ms) | +|------------|------------|---------|--------------|----------------|--------------| +| Empty screen | 11 | 25 | 0 | 0 | 0 | +| Moving wallpaper | 0 | 25 | 0 | 0 | 0 | +| Single rectangle | 0 | 25 | 0 | 0 | 0 | +| Multiple rectangles | 0 | 25 | 0 | 0 | 0 | +| Multiple RGB images | 0 | 25 | 0 | 0 | 0 | +| Multiple ARGB images | 1 | 25 | 0 | 0 | 0 | +| Rotated ARGB images | 23 | 25 | 10 | 10 | 0 | +| Multiple labels | 3 | 24 | 0 | 0 | 0 | +| Screen sized text | 23 | 24 | 10 | 10 | 0 | +| Multiple arcs | 15 | 24 | 6 | 6 | 0 | +| Containers | 3 | 25 | 0 | 0 | 0 | +| Containers with overlay | 90 | 23 | 41 | 41 | 0 | +| Containers with opa | 19 | 25 | 4 | 4 | 0 | +| Containers with opa_layer | 13 | 24 | 5 | 5 | 0 | +| Containers with scrolling | 25 | 25 | 10 | 10 | 0 | +| Widgets demo | 33 | 25 | 13 | 13 | 0 | +| All scenes avg. | 16 | 24 | 6 | 6 | 0 | + + +
+ + +Disclaimer: These benchmarks were run in an emulated environment using QEMU with instruction counting mode. +The timing values represent relative performance metrics within this specific virtualized setup and should +not be interpreted as absolute real-world performance measurements. Values are deterministic and useful for +comparing different LVGL features and configurations, but may not correlate directly with performance on +physical hardware. The measurements are intended for comparative analysis only. + + +--- + +:robot: This comment was automatically generated by a bot. \ No newline at end of file diff --git a/scripts/perf/tests/benchmark_results_comment/no_mpk/results-32b-lv_conf_perf32b.json b/scripts/perf/tests/benchmark_results_comment/no_mpk/results-32b-lv_conf_perf32b.json new file mode 100644 index 0000000000..31a0b23f4b --- /dev/null +++ b/scripts/perf/tests/benchmark_results_comment/no_mpk/results-32b-lv_conf_perf32b.json @@ -0,0 +1 @@ +[{"scene_name": "Empty screen", "avg_cpu": 11, "avg_fps": 25, "avg_time": 0, "render_time": 0, "flush_time": 0}, {"scene_name": "Moving wallpaper", "avg_cpu": 1, "avg_fps": 25, "avg_time": 0, "render_time": 0, "flush_time": 0}, {"scene_name": "Single rectangle", "avg_cpu": 0, "avg_fps": 25, "avg_time": 0, "render_time": 0, "flush_time": 0}, {"scene_name": "Multiple rectangles", "avg_cpu": 0, "avg_fps": 25, "avg_time": 0, "render_time": 0, "flush_time": 0}, {"scene_name": "Multiple RGB images", "avg_cpu": 0, "avg_fps": 25, "avg_time": 0, "render_time": 0, "flush_time": 0}, {"scene_name": "Multiple ARGB images", "avg_cpu": 22, "avg_fps": 25, "avg_time": 1, "render_time": 1, "flush_time": 0}, {"scene_name": "Rotated ARGB images", "avg_cpu": 47, "avg_fps": 24, "avg_time": 20, "render_time": 20, "flush_time": 0}, {"scene_name": "Multiple labels", "avg_cpu": 2, "avg_fps": 25, "avg_time": 0, "render_time": 0, "flush_time": 0}, {"scene_name": "Screen sized text", "avg_cpu": 30, "avg_fps": 24, "avg_time": 11, "render_time": 11, "flush_time": 0}, {"scene_name": "Multiple arcs", "avg_cpu": 19, "avg_fps": 24, "avg_time": 7, "render_time": 7, "flush_time": 0}, {"scene_name": "Containers", "avg_cpu": 1, "avg_fps": 25, "avg_time": 0, "render_time": 0, "flush_time": 0}, {"scene_name": "Containers with overlay", "avg_cpu": 87, "avg_fps": 21, "avg_time": 44, "render_time": 44, "flush_time": 0}, {"scene_name": "Containers with opa", "avg_cpu": 23, "avg_fps": 25, "avg_time": 4, "render_time": 4, "flush_time": 0}, {"scene_name": "Containers with opa_layer", "avg_cpu": 22, "avg_fps": 25, "avg_time": 8, "render_time": 8, "flush_time": 0}, {"scene_name": "Containers with scrolling", "avg_cpu": 25, "avg_fps": 25, "avg_time": 10, "render_time": 10, "flush_time": 0}, {"scene_name": "Widgets demo", "avg_cpu": 34, "avg_fps": 24, "avg_time": 13, "render_time": 13, "flush_time": 0}, {"scene_name": "All scenes avg.", "avg_cpu": 20, "avg_fps": 24, "avg_time": 7, "render_time": 7, "flush_time": 0}] \ No newline at end of file diff --git a/scripts/perf/tests/benchmark_results_comment/no_mpk/results-64b-lv_conf_perf64b.json b/scripts/perf/tests/benchmark_results_comment/no_mpk/results-64b-lv_conf_perf64b.json new file mode 100644 index 0000000000..f7fd438c4e --- /dev/null +++ b/scripts/perf/tests/benchmark_results_comment/no_mpk/results-64b-lv_conf_perf64b.json @@ -0,0 +1 @@ +[{"scene_name": "Empty screen", "avg_cpu": 11, "avg_fps": 25, "avg_time": 0, "render_time": 0, "flush_time": 0}, {"scene_name": "Moving wallpaper", "avg_cpu": 0, "avg_fps": 25, "avg_time": 0, "render_time": 0, "flush_time": 0}, {"scene_name": "Single rectangle", "avg_cpu": 0, "avg_fps": 25, "avg_time": 0, "render_time": 0, "flush_time": 0}, {"scene_name": "Multiple rectangles", "avg_cpu": 0, "avg_fps": 25, "avg_time": 0, "render_time": 0, "flush_time": 0}, {"scene_name": "Multiple RGB images", "avg_cpu": 0, "avg_fps": 25, "avg_time": 0, "render_time": 0, "flush_time": 0}, {"scene_name": "Multiple ARGB images", "avg_cpu": 1, "avg_fps": 25, "avg_time": 0, "render_time": 0, "flush_time": 0}, {"scene_name": "Rotated ARGB images", "avg_cpu": 23, "avg_fps": 25, "avg_time": 10, "render_time": 10, "flush_time": 0}, {"scene_name": "Multiple labels", "avg_cpu": 3, "avg_fps": 24, "avg_time": 0, "render_time": 0, "flush_time": 0}, {"scene_name": "Screen sized text", "avg_cpu": 23, "avg_fps": 24, "avg_time": 10, "render_time": 10, "flush_time": 0}, {"scene_name": "Multiple arcs", "avg_cpu": 15, "avg_fps": 24, "avg_time": 6, "render_time": 6, "flush_time": 0}, {"scene_name": "Containers", "avg_cpu": 3, "avg_fps": 25, "avg_time": 0, "render_time": 0, "flush_time": 0}, {"scene_name": "Containers with overlay", "avg_cpu": 90, "avg_fps": 23, "avg_time": 41, "render_time": 41, "flush_time": 0}, {"scene_name": "Containers with opa", "avg_cpu": 19, "avg_fps": 25, "avg_time": 4, "render_time": 4, "flush_time": 0}, {"scene_name": "Containers with opa_layer", "avg_cpu": 13, "avg_fps": 24, "avg_time": 5, "render_time": 5, "flush_time": 0}, {"scene_name": "Containers with scrolling", "avg_cpu": 25, "avg_fps": 25, "avg_time": 10, "render_time": 10, "flush_time": 0}, {"scene_name": "Widgets demo", "avg_cpu": 33, "avg_fps": 25, "avg_time": 13, "render_time": 13, "flush_time": 0}, {"scene_name": "All scenes avg.", "avg_cpu": 16, "avg_fps": 24, "avg_time": 6, "render_time": 6, "flush_time": 0}] \ No newline at end of file diff --git a/scripts/perf/tests/benchmark_results_comment/normal/expected.md b/scripts/perf/tests/benchmark_results_comment/normal/expected.md new file mode 100644 index 0000000000..9c4bc06c44 --- /dev/null +++ b/scripts/perf/tests/benchmark_results_comment/normal/expected.md @@ -0,0 +1,83 @@ +Hi :wave:, thank you for your PR! + +We've run benchmarks in an emulated environment. Here are the results: + +#### ARM Emulated 32b - lv_conf_perf32b + +| Scene Name | Avg CPU (%) | Avg FPS | Avg Time (ms) | Render Time (ms) | Flush Time (ms) | +|------------|------------|---------|--------------|----------------|--------------| +| All scenes avg. | 20 | 24 | 7 | 7 | 0 | + +
+ +Detailed Results Per Scene + + +| Scene Name | Avg CPU (%) | Avg FPS | Avg Time (ms) | Render Time (ms) | Flush Time (ms) | +|------------|------------|---------|--------------|----------------|--------------| +| Empty screen | 11 | 25 | 0 | 0 | 0 | +| Moving wallpaper | 1 | 25 | 0 | 0 | 0 | +| Single rectangle | 0 | 25 | 0 | 0 | 0 | +| Multiple rectangles | 0 | 25 | 0 | 0 | 0 | +| Multiple RGB images | 0 | 25 | 0 | 0 | 0 | +| Multiple ARGB images | 22 (-1)| 25 | 1 | 1 | 0 | +| Rotated ARGB images | 47 (-1)| 24 | 20 | 20 | 0 | +| Multiple labels | 2 (-2)| 25 | 0 | 0 | 0 | +| Screen sized text | 30 (+1)| 24 (-1)| 11 (-1)| 11 (-1)| 0 | +| Multiple arcs | 19 (+4)| 24 | 7 | 7 | 0 | +| Containers | 1 (-1)| 25 | 0 | 0 | 0 | +| Containers with overlay | 87 (-2)| 21 | 44 | 44 | 0 | +| Containers with opa | 23 (+1)| 25 | 4 | 4 | 0 | +| Containers with opa_layer | 22 (+1)| 25 | 8 | 8 | 0 | +| Containers with scrolling | 25 | 25 | 10 | 10 | 0 | +| Widgets demo | 34 | 24 (-1)| 13 | 13 | 0 | +| All scenes avg. | 20 | 24 | 7 | 7 | 0 | + + +
+ +#### ARM Emulated 64b - lv_conf_perf64b + +| Scene Name | Avg CPU (%) | Avg FPS | Avg Time (ms) | Render Time (ms) | Flush Time (ms) | +|------------|------------|---------|--------------|----------------|--------------| +| All scenes avg. | 16 | 24 | 6 | 6 | 0 | + +
+ +Detailed Results Per Scene + + +| Scene Name | Avg CPU (%) | Avg FPS | Avg Time (ms) | Render Time (ms) | Flush Time (ms) | +|------------|------------|---------|--------------|----------------|--------------| +| Empty screen | 11 | 25 | 0 | 0 | 0 | +| Moving wallpaper | 0 | 25 | 0 | 0 | 0 | +| Single rectangle | 0 | 25 | 0 | 0 | 0 | +| Multiple rectangles | 0 | 25 | 0 | 0 | 0 | +| Multiple RGB images | 0 | 25 | 0 | 0 | 0 | +| Multiple ARGB images | 1 | 25 | 0 | 0 | 0 | +| Rotated ARGB images | 23 | 25 | 10 | 10 | 0 | +| Multiple labels | 3 | 24 | 0 | 0 | 0 | +| Screen sized text | 23 | 24 | 10 | 10 | 0 | +| Multiple arcs | 15 | 24 | 6 | 6 | 0 | +| Containers | 3 (+1)| 25 (+1)| 0 | 0 | 0 | +| Containers with overlay | 90 (+2)| 23 | 41 | 41 | 0 | +| Containers with opa | 19 | 25 | 4 | 4 | 0 | +| Containers with opa_layer | 13 (-2)| 24 (-1)| 5 (-1)| 5 (-1)| 0 | +| Containers with scrolling | 25 | 25 (-1)| 10 | 10 | 0 | +| Widgets demo | 33 | 25 | 13 | 13 | 0 | +| All scenes avg. | 16 | 24 | 6 | 6 | 0 | + + +
+ + +Disclaimer: These benchmarks were run in an emulated environment using QEMU with instruction counting mode. +The timing values represent relative performance metrics within this specific virtualized setup and should +not be interpreted as absolute real-world performance measurements. Values are deterministic and useful for +comparing different LVGL features and configurations, but may not correlate directly with performance on +physical hardware. The measurements are intended for comparative analysis only. + + +--- + +:robot: This comment was automatically generated by a bot. \ No newline at end of file diff --git a/scripts/perf/tests/benchmark_results_comment/normal/results-32b-lv_conf_perf32b.json b/scripts/perf/tests/benchmark_results_comment/normal/results-32b-lv_conf_perf32b.json new file mode 100644 index 0000000000..31a0b23f4b --- /dev/null +++ b/scripts/perf/tests/benchmark_results_comment/normal/results-32b-lv_conf_perf32b.json @@ -0,0 +1 @@ +[{"scene_name": "Empty screen", "avg_cpu": 11, "avg_fps": 25, "avg_time": 0, "render_time": 0, "flush_time": 0}, {"scene_name": "Moving wallpaper", "avg_cpu": 1, "avg_fps": 25, "avg_time": 0, "render_time": 0, "flush_time": 0}, {"scene_name": "Single rectangle", "avg_cpu": 0, "avg_fps": 25, "avg_time": 0, "render_time": 0, "flush_time": 0}, {"scene_name": "Multiple rectangles", "avg_cpu": 0, "avg_fps": 25, "avg_time": 0, "render_time": 0, "flush_time": 0}, {"scene_name": "Multiple RGB images", "avg_cpu": 0, "avg_fps": 25, "avg_time": 0, "render_time": 0, "flush_time": 0}, {"scene_name": "Multiple ARGB images", "avg_cpu": 22, "avg_fps": 25, "avg_time": 1, "render_time": 1, "flush_time": 0}, {"scene_name": "Rotated ARGB images", "avg_cpu": 47, "avg_fps": 24, "avg_time": 20, "render_time": 20, "flush_time": 0}, {"scene_name": "Multiple labels", "avg_cpu": 2, "avg_fps": 25, "avg_time": 0, "render_time": 0, "flush_time": 0}, {"scene_name": "Screen sized text", "avg_cpu": 30, "avg_fps": 24, "avg_time": 11, "render_time": 11, "flush_time": 0}, {"scene_name": "Multiple arcs", "avg_cpu": 19, "avg_fps": 24, "avg_time": 7, "render_time": 7, "flush_time": 0}, {"scene_name": "Containers", "avg_cpu": 1, "avg_fps": 25, "avg_time": 0, "render_time": 0, "flush_time": 0}, {"scene_name": "Containers with overlay", "avg_cpu": 87, "avg_fps": 21, "avg_time": 44, "render_time": 44, "flush_time": 0}, {"scene_name": "Containers with opa", "avg_cpu": 23, "avg_fps": 25, "avg_time": 4, "render_time": 4, "flush_time": 0}, {"scene_name": "Containers with opa_layer", "avg_cpu": 22, "avg_fps": 25, "avg_time": 8, "render_time": 8, "flush_time": 0}, {"scene_name": "Containers with scrolling", "avg_cpu": 25, "avg_fps": 25, "avg_time": 10, "render_time": 10, "flush_time": 0}, {"scene_name": "Widgets demo", "avg_cpu": 34, "avg_fps": 24, "avg_time": 13, "render_time": 13, "flush_time": 0}, {"scene_name": "All scenes avg.", "avg_cpu": 20, "avg_fps": 24, "avg_time": 7, "render_time": 7, "flush_time": 0}] \ No newline at end of file diff --git a/scripts/perf/tests/benchmark_results_comment/normal/results-32b-lv_conf_perf32b.mpk b/scripts/perf/tests/benchmark_results_comment/normal/results-32b-lv_conf_perf32b.mpk new file mode 100644 index 0000000000..617676f3b3 Binary files /dev/null and b/scripts/perf/tests/benchmark_results_comment/normal/results-32b-lv_conf_perf32b.mpk differ diff --git a/scripts/perf/tests/benchmark_results_comment/normal/results-64b-lv_conf_perf64b.json b/scripts/perf/tests/benchmark_results_comment/normal/results-64b-lv_conf_perf64b.json new file mode 100644 index 0000000000..f7fd438c4e --- /dev/null +++ b/scripts/perf/tests/benchmark_results_comment/normal/results-64b-lv_conf_perf64b.json @@ -0,0 +1 @@ +[{"scene_name": "Empty screen", "avg_cpu": 11, "avg_fps": 25, "avg_time": 0, "render_time": 0, "flush_time": 0}, {"scene_name": "Moving wallpaper", "avg_cpu": 0, "avg_fps": 25, "avg_time": 0, "render_time": 0, "flush_time": 0}, {"scene_name": "Single rectangle", "avg_cpu": 0, "avg_fps": 25, "avg_time": 0, "render_time": 0, "flush_time": 0}, {"scene_name": "Multiple rectangles", "avg_cpu": 0, "avg_fps": 25, "avg_time": 0, "render_time": 0, "flush_time": 0}, {"scene_name": "Multiple RGB images", "avg_cpu": 0, "avg_fps": 25, "avg_time": 0, "render_time": 0, "flush_time": 0}, {"scene_name": "Multiple ARGB images", "avg_cpu": 1, "avg_fps": 25, "avg_time": 0, "render_time": 0, "flush_time": 0}, {"scene_name": "Rotated ARGB images", "avg_cpu": 23, "avg_fps": 25, "avg_time": 10, "render_time": 10, "flush_time": 0}, {"scene_name": "Multiple labels", "avg_cpu": 3, "avg_fps": 24, "avg_time": 0, "render_time": 0, "flush_time": 0}, {"scene_name": "Screen sized text", "avg_cpu": 23, "avg_fps": 24, "avg_time": 10, "render_time": 10, "flush_time": 0}, {"scene_name": "Multiple arcs", "avg_cpu": 15, "avg_fps": 24, "avg_time": 6, "render_time": 6, "flush_time": 0}, {"scene_name": "Containers", "avg_cpu": 3, "avg_fps": 25, "avg_time": 0, "render_time": 0, "flush_time": 0}, {"scene_name": "Containers with overlay", "avg_cpu": 90, "avg_fps": 23, "avg_time": 41, "render_time": 41, "flush_time": 0}, {"scene_name": "Containers with opa", "avg_cpu": 19, "avg_fps": 25, "avg_time": 4, "render_time": 4, "flush_time": 0}, {"scene_name": "Containers with opa_layer", "avg_cpu": 13, "avg_fps": 24, "avg_time": 5, "render_time": 5, "flush_time": 0}, {"scene_name": "Containers with scrolling", "avg_cpu": 25, "avg_fps": 25, "avg_time": 10, "render_time": 10, "flush_time": 0}, {"scene_name": "Widgets demo", "avg_cpu": 33, "avg_fps": 25, "avg_time": 13, "render_time": 13, "flush_time": 0}, {"scene_name": "All scenes avg.", "avg_cpu": 16, "avg_fps": 24, "avg_time": 6, "render_time": 6, "flush_time": 0}] \ No newline at end of file diff --git a/scripts/perf/tests/benchmark_results_comment/normal/results-64b-lv_conf_perf64b.mpk b/scripts/perf/tests/benchmark_results_comment/normal/results-64b-lv_conf_perf64b.mpk new file mode 100644 index 0000000000..083e685915 Binary files /dev/null and b/scripts/perf/tests/benchmark_results_comment/normal/results-64b-lv_conf_perf64b.mpk differ diff --git a/scripts/perf/tests/benchmark_results_comment/test.sh b/scripts/perf/tests/benchmark_results_comment/test.sh new file mode 100755 index 0000000000..724dad1dc2 --- /dev/null +++ b/scripts/perf/tests/benchmark_results_comment/test.sh @@ -0,0 +1,17 @@ +#!/bin/sh + +set -e + +ORIGINAL_PWD=$(pwd) +SCRIPT=$(readlink -f $0) +SCRIPT_PATH=$(dirname $SCRIPT) + +cd $SCRIPT_PATH +python3 ../../benchmark_results_comment.py --new no_mpk/results*.json -o no_mpk/actual.md +python3 ../../benchmark_results_comment.py --previous normal/results*.mpk --new normal/results*.json -o normal/actual.md +cd $ORIGINAL_PWD + + +cmp $SCRIPT_PATH/no_mpk/expected.md $SCRIPT_PATH/no_mpk/actual.md +cmp $SCRIPT_PATH/normal/expected.md $SCRIPT_PATH/normal/actual.md + diff --git a/scripts/perf/tests/filter_docker_logs/docker-logs-example.txt b/scripts/perf/tests/filter_docker_logs/docker-logs-example.txt new file mode 100644 index 0000000000..545812676e --- /dev/null +++ b/scripts/perf/tests/filter_docker_logs/docker-logs-example.txt @@ -0,0 +1,205 @@ +{"log":"Found existing rootfs image in /persistence/rootfs.fat.virt32.\r\n","stream":"stdout","time":"2025-03-14T20:32:14.707303831Z"} +{"log":"Found existing filesystem image in /persistence/sdcard.img.virt32.\r\n","stream":"stdout","time":"2025-03-14T20:32:14.713651764Z"} +{"log":"Platform is virt32\r\n","stream":"stdout","time":"2025-03-14T20:32:14.716038006Z"} +{"log":"Starting Release build\r\n","stream":"stdout","time":"2025-03-14T20:32:14.717227898Z"} +{"log":"Not searching for unused variables given on the command line.\r\n","stream":"stdout","time":"2025-03-14T20:32:14.745430299Z"} +{"log":"\u001b[0mSystem is unknown to cmake, create:\r\n","stream":"stdout","time":"2025-03-14T20:32:14.748807599Z"} +{"log":"Platform/SO3_usr to use this system, please post your config file on discourse.cmake.org so it can be added to cmake\u001b[0m\r\n","stream":"stdout","time":"2025-03-14T20:32:14.74881708Z"} +{"log":"\u001b[0mYour CMakeCache.txt file was copied to CopyOfCMakeCache.txt. Please post that file on discourse.cmake.org.\u001b[0m\r\n","stream":"stdout","time":"2025-03-14T20:32:14.749184826Z"} +{"log":"-- Configuring done (0.1s)\r\n","stream":"stdout","time":"2025-03-14T20:32:14.847438284Z"} +{"log":"-- Generating done (0.3s)\r\n","stream":"stdout","time":"2025-03-14T20:32:15.176738283Z"} +{"log":"-- Build files have been written to: /so3/usr/build\r\n","stream":"stdout","time":"2025-03-14T20:32:15.177012138Z"} +{"log":"[ 0%] Built target slv\r\n","stream":"stdout","time":"2025-03-14T20:32:15.230938018Z"} +{"log":"[ 16%] Built target c\r\n","stream":"stdout","time":"2025-03-14T20:32:15.259557577Z"} +{"log":"[ 16%] \u001b[32m\u001b[1mLinking C executable sh.elf\u001b[0m\r\n","stream":"stdout","time":"2025-03-14T20:32:15.273128278Z"} +{"log":"[ 16%] \u001b[32m\u001b[1mLinking C executable ls.elf\u001b[0m\r\n","stream":"stdout","time":"2025-03-14T20:32:15.273371483Z"} +{"log":"[ 16%] \u001b[32m\u001b[1mLinking C executable mydev_test.elf\u001b[0m\r\n","stream":"stdout","time":"2025-03-14T20:32:15.273527115Z"} +{"log":"[ 17%] \u001b[32m\u001b[1mLinking C executable time.elf\u001b[0m\r\n","stream":"stdout","time":"2025-03-14T20:32:15.273681218Z"} +{"log":"[ 17%] \u001b[32m\u001b[1mLinking C executable ping.elf\u001b[0m\r\n","stream":"stdout","time":"2025-03-14T20:32:15.274979851Z"} +{"log":"[ 17%] \u001b[32m\u001b[1mLinking C executable more.elf\u001b[0m\r\n","stream":"stdout","time":"2025-03-14T20:32:15.275235356Z"} +{"log":"arm-none-eabi-ld: warning: mydev_test.elf has a LOAD segment with RWX permissions\r\n","stream":"stdout","time":"2025-03-14T20:32:15.286865573Z"} +{"log":"arm-none-eabi-ld: warning: time.elf has a LOAD segment with RWX permissions\r\n","stream":"stdout","time":"2025-03-14T20:32:15.287133237Z"} +{"log":"arm-none-eabi-ld: warning: ls.elf has a LOAD segment with RWX permissions\r\n","stream":"stdout","time":"2025-03-14T20:32:15.287408832Z"} +{"log":"arm-none-eabi-ld: warning: more.elf has a LOAD segment with RWX permissions\r\n","stream":"stdout","time":"2025-03-14T20:32:15.288070604Z"} +{"log":"arm-none-eabi-ld: warning: ping.elf has a LOAD segment with RWX permissions\r\n","stream":"stdout","time":"2025-03-14T20:32:15.288727656Z"} +{"log":"arm-none-eabi-ld: warning: sh.elf has a LOAD segment with RWX permissions\r\n","stream":"stdout","time":"2025-03-14T20:32:15.289373017Z"} +{"log":"[ 17%] Built target time.elf\r\n","stream":"stdout","time":"2025-03-14T20:32:15.294744583Z"} +{"log":"[ 17%] Built target mydev_test.elf\r\n","stream":"stdout","time":"2025-03-14T20:32:15.295257472Z"} +{"log":"[ 17%] Built target ls.elf\r\n","stream":"stdout","time":"2025-03-14T20:32:15.295839172Z"} +{"log":"[ 17%] Built target more.elf\r\n","stream":"stdout","time":"2025-03-14T20:32:15.295856623Z"} +{"log":"[ 18%] Built target ping.elf\r\n","stream":"stdout","time":"2025-03-14T20:32:15.296507264Z"} +{"log":"[ 18%] Built target sh.elf\r\n","stream":"stdout","time":"2025-03-14T20:32:15.29684107Z"} +{"log":"[ 51%] Built target lvgl\r\n","stream":"stdout","time":"2025-03-14T20:32:15.679676932Z"} +{"log":"[ 55%] Built target lvgl_thorvg\r\n","stream":"stdout","time":"2025-03-14T20:32:15.700285078Z"} +{"log":"[ 74%] Built target lvgl_examples\r\n","stream":"stdout","time":"2025-03-14T20:32:16.438310259Z"} +{"log":"[ 99%] Built target lvgl_demos\r\n","stream":"stdout","time":"2025-03-14T20:32:16.548772835Z"} +{"log":"[ 99%] \u001b[32m\u001b[1mLinking C executable lvgl_benchmark.elf\u001b[0m\r\n","stream":"stdout","time":"2025-03-14T20:32:16.567263714Z"} +{"log":"[100%] \u001b[32m\u001b[1mLinking C executable lvgl_demo.elf\u001b[0m\r\n","stream":"stdout","time":"2025-03-14T20:32:16.567286834Z"} +{"log":"[100%] \u001b[32m\u001b[1mLinking C executable lvgl_perf.elf\u001b[0m\r\n","stream":"stdout","time":"2025-03-14T20:32:16.568622548Z"} +{"log":"arm-none-eabi-ld: warning: lvgl_perf.elf has a LOAD segment with RWX permissions\r\n","stream":"stdout","time":"2025-03-14T20:32:16.596923961Z"} +{"log":"arm-none-eabi-ld: warning: lvgl_benchmark.elf has a LOAD segment with RWX permissions\r\n","stream":"stdout","time":"2025-03-14T20:32:16.599814023Z"} +{"log":"arm-none-eabi-ld: warning: lvgl_demo.elf has a LOAD segment with RWX permissions\r\n","stream":"stdout","time":"2025-03-14T20:32:16.599829503Z"} +{"log":"[100%] Built target lvgl_perf.elf\r\n","stream":"stdout","time":"2025-03-14T20:32:16.611878347Z"} +{"log":"[100%] Built target lvgl_benchmark.elf\r\n","stream":"stdout","time":"2025-03-14T20:32:16.61540439Z"} +{"log":"[100%] Built target lvgl_demo.elf\r\n","stream":"stdout","time":"2025-03-14T20:32:16.615420571Z"} +{"log":"/so3/usr\r\n","stream":"stdout","time":"2025-03-14T20:32:16.624743276Z"} +{"log":"Installing out\r\n","stream":"stdout","time":"2025-03-14T20:32:16.625245525Z"} +{"log":"Installing \r\n","stream":"stdout","time":"2025-03-14T20:32:16.625911907Z"} +{"log":"FIT description: Kernel and rootfs components for virt32 environment\r\n","stream":"stdout","time":"2025-03-14T20:32:16.931786439Z"} +{"log":"Created: Fri Mar 14 20:32:16 2025\r\n","stream":"stdout","time":"2025-03-14T20:32:16.93183975Z"} +{"log":" Image 0 (so3)\r\n","stream":"stdout","time":"2025-03-14T20:32:16.93184516Z"} +{"log":" Description: SO3 OS kernel\r\n","stream":"stdout","time":"2025-03-14T20:32:16.9318507Z"} +{"log":" Created: Fri Mar 14 20:32:16 2025\r\n","stream":"stdout","time":"2025-03-14T20:32:16.931855601Z"} +{"log":" Type: Kernel Image\r\n","stream":"stdout","time":"2025-03-14T20:32:16.931860341Z"} +{"log":" Compression: uncompressed\r\n","stream":"stdout","time":"2025-03-14T20:32:16.931864181Z"} +{"log":" Data Size: 233544 Bytes = 228.07 KiB = 0.22 MiB\r\n","stream":"stdout","time":"2025-03-14T20:32:16.931867961Z"} +{"log":" Architecture: ARM\r\n","stream":"stdout","time":"2025-03-14T20:32:16.931871821Z"} +{"log":" OS: Linux\r\n","stream":"stdout","time":"2025-03-14T20:32:16.931875611Z"} +{"log":" Load Address: 0x41008000\r\n","stream":"stdout","time":"2025-03-14T20:32:16.931880061Z"} +{"log":" Entry Point: 0x41008000\r\n","stream":"stdout","time":"2025-03-14T20:32:16.931884561Z"} +{"log":" Image 1 (lvperf_fdt)\r\n","stream":"stdout","time":"2025-03-14T20:32:16.931888791Z"} +{"log":" Description: Flattened Device Tree blob\r\n","stream":"stdout","time":"2025-03-14T20:32:16.931893221Z"} +{"log":" Created: Fri Mar 14 20:32:16 2025\r\n","stream":"stdout","time":"2025-03-14T20:32:16.931897651Z"} +{"log":" Type: Flat Device Tree\r\n","stream":"stdout","time":"2025-03-14T20:32:16.931902121Z"} +{"log":" Compression: uncompressed\r\n","stream":"stdout","time":"2025-03-14T20:32:16.931905941Z"} +{"log":" Data Size: 1454 Bytes = 1.42 KiB = 0.00 MiB\r\n","stream":"stdout","time":"2025-03-14T20:32:16.931910192Z"} +{"log":" Architecture: ARM\r\n","stream":"stdout","time":"2025-03-14T20:32:16.931914132Z"} +{"log":" Load Address: 0x44a00000\r\n","stream":"stdout","time":"2025-03-14T20:32:16.931917882Z"} +{"log":" Image 2 (ramfs)\r\n","stream":"stdout","time":"2025-03-14T20:32:16.931921612Z"} +{"log":" Description: SO3 environment minimal rootfs\r\n","stream":"stdout","time":"2025-03-14T20:32:16.931925382Z"} +{"log":" Created: Fri Mar 14 20:32:16 2025\r\n","stream":"stdout","time":"2025-03-14T20:32:16.931931202Z"} +{"log":" Type: RAMDisk Image\r\n","stream":"stdout","time":"2025-03-14T20:32:16.931941882Z"} +{"log":" Compression: uncompressed\r\n","stream":"stdout","time":"2025-03-14T20:32:16.931949552Z"} +{"log":" Data Size: 17825792 Bytes = 17408.00 KiB = 17.00 MiB\r\n","stream":"stdout","time":"2025-03-14T20:32:16.931969373Z"} +{"log":" Architecture: ARM\r\n","stream":"stdout","time":"2025-03-14T20:32:16.931974473Z"} +{"log":" OS: Linux\r\n","stream":"stdout","time":"2025-03-14T20:32:16.931979023Z"} +{"log":" Load Address: 0x44c00000\r\n","stream":"stdout","time":"2025-03-14T20:32:16.931982833Z"} +{"log":" Entry Point: unavailable\r\n","stream":"stdout","time":"2025-03-14T20:32:16.931986583Z"} +{"log":" Default Configuration: 'so3_lvperf_ramfs'\r\n","stream":"stdout","time":"2025-03-14T20:32:16.931990363Z"} +{"log":" Configuration 0 (so3_lvperf_ramfs)\r\n","stream":"stdout","time":"2025-03-14T20:32:16.931994313Z"} +{"log":" Description: SO3 kernel image including device tree\r\n","stream":"stdout","time":"2025-03-14T20:32:16.931998103Z"} +{"log":" Kernel: so3\r\n","stream":"stdout","time":"2025-03-14T20:32:16.932001933Z"} +{"log":" Init Ramdisk: ramfs\r\n","stream":"stdout","time":"2025-03-14T20:32:16.932005693Z"} +{"log":" FDT: lvperf_fdt\r\n","stream":"stdout","time":"2025-03-14T20:32:16.932009463Z"} +{"log":"\r\r\n","stream":"stdout","time":"2025-03-14T20:32:17.141214715Z"} +{"log":"\r\r\n","stream":"stdout","time":"2025-03-14T20:32:17.141238796Z"} +{"log":"U-Boot 2022.04 (Mar 12 2025 - 21:28:47 +0000)\r\r\n","stream":"stdout","time":"2025-03-14T20:32:17.141320337Z"} +{"log":"\r\r\n","stream":"stdout","time":"2025-03-14T20:32:17.141343368Z"} +{"log":"DRAM: 1 GiB\r\r\n","stream":"stdout","time":"2025-03-14T20:32:17.142811464Z"} +{"log":"Core: 42 devices, 11 uclasses, devicetree: board\r\r\n","stream":"stdout","time":"2025-03-14T20:32:17.187948537Z"} +{"log":"Flash: 64 MiB\r\r\n","stream":"stdout","time":"2025-03-14T20:32:17.360854793Z"} +{"log":"Loading Environment from Flash... *** Warning - bad CRC, using default environment\r\r\n","stream":"stdout","time":"2025-03-14T20:32:17.364120671Z"} +{"log":"\r\r\n","stream":"stdout","time":"2025-03-14T20:32:17.364133852Z"} +{"log":"In: pl011@9000000\r\r\n","stream":"stdout","time":"2025-03-14T20:32:17.369442616Z"} +{"log":"Out: pl011@9000000\r\r\n","stream":"stdout","time":"2025-03-14T20:32:17.369521737Z"} +{"log":"Err: pl011@9000000\r\r\n","stream":"stdout","time":"2025-03-14T20:32:17.369630069Z"} +{"log":"Net: No ethernet found.\r\r\n","stream":"stdout","time":"2025-03-14T20:32:17.375946722Z"} +{"log":"Hit any key to stop autoboot: 0 \r\r\n","stream":"stdout","time":"2025-03-14T20:32:17.377595221Z"} +{"log":"99 bytes read in 0 ms\r\r\n","stream":"stdout","time":"2025-03-14T20:32:17.38541157Z"} +{"log":"## Warning: defaulting to text format\r\r\n","stream":"stdout","time":"2025-03-14T20:32:17.38593644Z"} +{"log":"## Info: input data size = 734 = 0x2DE\r\r\n","stream":"stdout","time":"2025-03-14T20:32:17.386195084Z"} +{"log":"18062712 bytes read in 6 ms (2.8 GiB/s)\r\r\n","stream":"stdout","time":"2025-03-14T20:32:17.397864982Z"} +{"log":"## Loading kernel from FIT Image at 70000000 ...\r\r\n","stream":"stdout","time":"2025-03-14T20:32:17.398653806Z"} +{"log":" Using 'so3_lvperf_ramfs' configuration\r\r\n","stream":"stdout","time":"2025-03-14T20:32:17.399347568Z"} +{"log":" Verifying Hash Integrity ... OK\r\r\n","stream":"stdout","time":"2025-03-14T20:32:17.399790356Z"} +{"log":" Trying 'so3' kernel subimage\r\r\n","stream":"stdout","time":"2025-03-14T20:32:17.400054021Z"} +{"log":" Description: SO3 OS kernel\r\r\n","stream":"stdout","time":"2025-03-14T20:32:17.400250634Z"} +{"log":" Created: 2025-03-14 20:32:16 UTC\r\r\n","stream":"stdout","time":"2025-03-14T20:32:17.400707812Z"} +{"log":" Type: Kernel Image\r\r\n","stream":"stdout","time":"2025-03-14T20:32:17.400981297Z"} +{"log":" Compression: uncompressed\r\r\n","stream":"stdout","time":"2025-03-14T20:32:17.40115414Z"} +{"log":" Data Start: 0x700000cc\r\r\n","stream":"stdout","time":"2025-03-14T20:32:17.401441475Z"} +{"log":" Data Size: 233544 Bytes = 228.1 KiB\r\r\n","stream":"stdout","time":"2025-03-14T20:32:17.401621409Z"} +{"log":" Architecture: ARM\r\r\n","stream":"stdout","time":"2025-03-14T20:32:17.401834352Z"} +{"log":" OS: Linux\r\r\n","stream":"stdout","time":"2025-03-14T20:32:17.401982385Z"} +{"log":" Load Address: 0x41008000\r\r\n","stream":"stdout","time":"2025-03-14T20:32:17.40225652Z"} +{"log":" Entry Point: 0x41008000\r\r\n","stream":"stdout","time":"2025-03-14T20:32:17.402359142Z"} +{"log":" Verifying Hash Integrity ... OK\r\r\n","stream":"stdout","time":"2025-03-14T20:32:17.402934512Z"} +{"log":"## Loading ramdisk from FIT Image at 70000000 ...\r\r\n","stream":"stdout","time":"2025-03-14T20:32:17.403726946Z"} +{"log":" Using 'so3_lvperf_ramfs' configuration\r\r\n","stream":"stdout","time":"2025-03-14T20:32:17.404009111Z"} +{"log":" Verifying Hash Integrity ... OK\r\r\n","stream":"stdout","time":"2025-03-14T20:32:17.404358757Z"} +{"log":" Trying 'ramfs' ramdisk subimage\r\r\n","stream":"stdout","time":"2025-03-14T20:32:17.40451006Z"} +{"log":" Description: SO3 environment minimal rootfs\r\r\n","stream":"stdout","time":"2025-03-14T20:32:17.404692053Z"} +{"log":" Created: 2025-03-14 20:32:16 UTC\r\r\n","stream":"stdout","time":"2025-03-14T20:32:17.404854176Z"} +{"log":" Type: RAMDisk Image\r\r\n","stream":"stdout","time":"2025-03-14T20:32:17.404994809Z"} +{"log":" Compression: uncompressed\r\r\n","stream":"stdout","time":"2025-03-14T20:32:17.405112601Z"} +{"log":" Data Start: 0x70039808\r\r\n","stream":"stdout","time":"2025-03-14T20:32:17.405224613Z"} +{"log":" Data Size: 17825792 Bytes = 17 MiB\r\r\n","stream":"stdout","time":"2025-03-14T20:32:17.405373045Z"} +{"log":" Architecture: ARM\r\r\n","stream":"stdout","time":"2025-03-14T20:32:17.405475037Z"} +{"log":" OS: Linux\r\r\n","stream":"stdout","time":"2025-03-14T20:32:17.405540908Z"} +{"log":" Load Address: 0x44c00000\r\r\n","stream":"stdout","time":"2025-03-14T20:32:17.40564666Z"} +{"log":" Entry Point: unavailable\r\r\n","stream":"stdout","time":"2025-03-14T20:32:17.405794883Z"} +{"log":" Verifying Hash Integrity ... OK\r\r\n","stream":"stdout","time":"2025-03-14T20:32:17.406170159Z"} +{"log":" Loading ramdisk from 0x70039808 to 0x44c00000\r\r\n","stream":"stdout","time":"2025-03-14T20:32:17.406457395Z"} +{"log":"## Loading fdt from FIT Image at 70000000 ...\r\r\n","stream":"stdout","time":"2025-03-14T20:32:17.417841727Z"} +{"log":" Using 'so3_lvperf_ramfs' configuration\r\r\n","stream":"stdout","time":"2025-03-14T20:32:17.418055241Z"} +{"log":" Verifying Hash Integrity ... OK\r\r\n","stream":"stdout","time":"2025-03-14T20:32:17.418439928Z"} +{"log":" Trying 'lvperf_fdt' fdt subimage\r\r\n","stream":"stdout","time":"2025-03-14T20:32:17.41857305Z"} +{"log":" Description: Flattened Device Tree blob\r\r\n","stream":"stdout","time":"2025-03-14T20:32:17.418728843Z"} +{"log":" Created: 2025-03-14 20:32:16 UTC\r\r\n","stream":"stdout","time":"2025-03-14T20:32:17.418925947Z"} +{"log":" Type: Flat Device Tree\r\r\n","stream":"stdout","time":"2025-03-14T20:32:17.419084659Z"} +{"log":" Compression: uncompressed\r\r\n","stream":"stdout","time":"2025-03-14T20:32:17.419173371Z"} +{"log":" Data Start: 0x700391c8\r\r\n","stream":"stdout","time":"2025-03-14T20:32:17.419289543Z"} +{"log":" Data Size: 1454 Bytes = 1.4 KiB\r\r\n","stream":"stdout","time":"2025-03-14T20:32:17.419426266Z"} +{"log":" Architecture: ARM\r\r\n","stream":"stdout","time":"2025-03-14T20:32:17.419506947Z"} +{"log":" Load Address: 0x44a00000\r\r\n","stream":"stdout","time":"2025-03-14T20:32:17.419641259Z"} +{"log":" Verifying Hash Integrity ... OK\r\r\n","stream":"stdout","time":"2025-03-14T20:32:17.420025906Z"} +{"log":" Loading fdt from 0x700391c8 to 0x44a00000\r\r\n","stream":"stdout","time":"2025-03-14T20:32:17.420210119Z"} +{"log":" Booting using the fdt blob at 0x44a00000\r\r\n","stream":"stdout","time":"2025-03-14T20:32:17.420773569Z"} +{"log":" Loading Kernel Image\r\r\n","stream":"stdout","time":"2025-03-14T20:32:17.42136626Z"} +{"log":" Using Device Tree in place at 44a00000, end 44a035ad\r\r\n","stream":"stdout","time":"2025-03-14T20:32:17.422625712Z"} +{"log":"\r\r\n","stream":"stdout","time":"2025-03-14T20:32:17.424265281Z"} +{"log":"Starting kernel ...\r\r\n","stream":"stdout","time":"2025-03-14T20:32:17.424312452Z"} +{"log":"\r\r\n","stream":"stdout","time":"2025-03-14T20:32:17.424321252Z"} +{"log":"setup_arch: CPU control register (CR) = c5387d\r\n","stream":"stdout","time":"2025-03-14T20:32:17.429470984Z"} +{"log":"\r\n","stream":"stdout","time":"2025-03-14T20:32:17.429544555Z"} +{"log":"\r\n","stream":"stdout","time":"2025-03-14T20:32:17.429552336Z"} +{"log":"********** Smart Object Oriented SO3 Operating System **********\r\n","stream":"stdout","time":"2025-03-14T20:32:17.429699368Z"} +{"log":"Copyright (c) 2014-2023 REDS Institute, HEIG-VD, Yverdon\r\n","stream":"stdout","time":"2025-03-14T20:32:17.429856331Z"} +{"log":"Version 2023.6.0\r\n","stream":"stdout","time":"2025-03-14T20:32:17.429931402Z"} +{"log":"\r\n","stream":"stdout","time":"2025-03-14T20:32:17.429942853Z"} +{"log":"\r\n","stream":"stdout","time":"2025-03-14T20:32:17.429949053Z"} +{"log":"\r\n","stream":"stdout","time":"2025-03-14T20:32:17.429958813Z"} +{"log":"Now bootstraping the kernel ...\r\n","stream":"stdout","time":"2025-03-14T20:32:17.430034164Z"} +{"log":"SO3: allocating a kernel heap of 33554404 bytes at address c0044000.\r\n","stream":"stdout","time":"2025-03-14T20:32:17.673343683Z"} +{"log":"memory_init: Device tree virt addr: c3a00000\r\n","stream":"stdout","time":"2025-03-14T20:32:17.673549157Z"} +{"log":"memory_init: relocating the device tree from 0xc3a00000 to 0xc21a4000 (size of 4224 bytes)\r\n","stream":"stdout","time":"2025-03-14T20:32:17.673910253Z"} +{"log":"SO3 Memory information:\r\n","stream":"stdout","time":"2025-03-14T20:32:17.674259929Z"} +{"log":" - Memory size : 536870912 bytes\r\n","stream":"stdout","time":"2025-03-14T20:32:17.674530184Z"} +{"log":" - Available pages: 122458 (1de5a)\r\n","stream":"stdout","time":"2025-03-14T20:32:17.674673837Z"} +{"log":" - Kernel size without frame table is: 35282944 (0x21a6000) bytes, 33 MB / 0x21a6 PFNs\r\n","stream":"stdout","time":"2025-03-14T20:32:17.675009963Z"} +{"log":" - Kernel size including frame table is: 36265984 (0x2296000) bytes, 34 MB / 0x2296 PFNs\r\n","stream":"stdout","time":"2025-03-14T20:32:17.677971645Z"} +{"log":" - Number of available page frames: 0x1de5a\r\n","stream":"stdout","time":"2025-03-14T20:32:17.678144519Z"} +{"log":" - Frame table size is: 979664 bytes meaning 240 (0xf0) page frames\r\n","stream":"stdout","time":"2025-03-14T20:32:17.678424433Z"} +{"log":" - Page frame number of the first available page: 0x431a6\r\n","stream":"stdout","time":"2025-03-14T20:32:17.678619197Z"} +{"log":"so3: rootfs in RAM detected (ramdev enabled) with size of 17825792 bytes...\r\n","stream":"stdout","time":"2025-03-14T20:32:17.68218061Z"} +{"log":"calibrate_delay: calibrating...done. jiffies_ref = a2be8\r\n","stream":"stdout","time":"2025-03-14T20:32:17.704849544Z"} +{"log":"SO3: starting the initial process ...\r\n","stream":"stdout","time":"2025-03-14T20:32:17.712134853Z"} +{"log":"\r\n","stream":"stdout","time":"2025-03-14T20:32:17.712146014Z"} +{"log":"\r\n","stream":"stdout","time":"2025-03-14T20:32:17.712150624Z"} +{"log":"Starting LVGL Benchmark\r\n","stream":"stdout","time":"2025-03-14T20:32:17.816299617Z"} +{"log":"Warning: The guest is now late by 0.0 to 1.0 seconds\r\n","stream":"stdout","time":"2025-03-14T20:32:19.129030996Z"} +{"log":"Warning: The guest is now late by 1.0 to 2.0 seconds\r\n","stream":"stdout","time":"2025-03-14T20:32:40.699491404Z"} +{"log":"Warning: The guest is now late by 2.0 to 3.0 seconds\r\n","stream":"stdout","time":"2025-03-14T20:33:02.966355127Z"} +{"log":"Warning: The guest is now late by 3.0 to 4.0 seconds\r\n","stream":"stdout","time":"2025-03-14T20:33:30.06251689Z"} +{"log":"Warning: The guest is now late by 4.0 to 5.0 seconds\r\n","stream":"stdout","time":"2025-03-14T20:33:38.253535255Z"} +{"log":"Warning: The guest is now late by 5.0 to 6.0 seconds\r\n","stream":"stdout","time":"2025-03-14T20:33:51.010250882Z"} +{"log":"Benchmark Summary (9.3.0 dev)\r\r\n","stream":"stdout","time":"2025-03-14T20:33:57.855785347Z"} +{"log":"Name, Avg. CPU, Avg. FPS, Avg. time, render time, flush time\r\r\n","stream":"stdout","time":"2025-03-14T20:33:57.855997881Z"} +{"log":"Empty screen, 11%, 25, 0, 0, 0\r\r\n","stream":"stdout","time":"2025-03-14T20:33:57.857828373Z"} +{"log":"Moving wallpaper, 2%, 25, 0, 0, 0\r\r\n","stream":"stdout","time":"2025-03-14T20:33:57.858455924Z"} +{"log":"Single rectangle, 0%, 25, 0, 0, 0\r\r\n","stream":"stdout","time":"2025-03-14T20:33:57.859125276Z"} +{"log":"Multiple rectangles, 0%, 25, 0, 0, 0\r\r\n","stream":"stdout","time":"2025-03-14T20:33:57.859847899Z"} +{"log":"Multiple RGB images, 0%, 25, 0, 0, 0\r\r\n","stream":"stdout","time":"2025-03-14T20:33:57.860658884Z"} +{"log":"Multiple ARGB images, 23%, 25, 1, 1, 0\r\r\n","stream":"stdout","time":"2025-03-14T20:33:57.86156999Z"} +{"log":"Rotated ARGB images, 48%, 24, 20, 20, 0\r\r\n","stream":"stdout","time":"2025-03-14T20:33:57.862511197Z"} +{"log":"Multiple labels, 3%, 25, 0, 0, 0\r\r\n","stream":"stdout","time":"2025-03-14T20:33:57.863549175Z"} +{"log":"Screen sized text, 30%, 24, 11, 11, 0\r\r\n","stream":"stdout","time":"2025-03-14T20:33:57.864642275Z"} +{"log":"Multiple arcs, 18%, 24, 7, 7, 0\r\r\n","stream":"stdout","time":"2025-03-14T20:33:57.865801475Z"} +{"log":"Containers, 3%, 25, 0, 0, 0\r\r\n","stream":"stdout","time":"2025-03-14T20:33:57.867039657Z"} +{"log":"Containers with overlay, 88%, 21, 44, 44, 0\r\r\n","stream":"stdout","time":"2025-03-14T20:33:57.868379231Z"} +{"log":"Containers with opa, 10%, 24, 3, 3, 0\r\r\n","stream":"stdout","time":"2025-03-14T20:33:57.869736765Z"} +{"log":"Containers with opa_layer, 22%, 24, 8, 8, 0\r\r\n","stream":"stdout","time":"2025-03-14T20:33:57.871269383Z"} +{"log":"Containers with scrolling, 25%, 25, 10, 10, 0\r\r\n","stream":"stdout","time":"2025-03-14T20:33:57.872899952Z"} +{"log":"Widgets demo, 34%, 25, 13, 13, 0\r\r\n","stream":"stdout","time":"2025-03-14T20:33:57.874447759Z"} +{"log":"All scenes avg.,19%, 24, 7, 7, 0\r\r\n","stream":"stdout","time":"2025-03-14T20:33:57.875031879Z"} +{"log":"LVGL Benchmark Over\r\n","stream":"stdout","time":"2025-03-14T20:33:57.933458479Z"} diff --git a/scripts/perf/tests/filter_docker_logs/expected.json b/scripts/perf/tests/filter_docker_logs/expected.json new file mode 100644 index 0000000000..e3d1438c47 --- /dev/null +++ b/scripts/perf/tests/filter_docker_logs/expected.json @@ -0,0 +1 @@ +[{"scene_name": "Empty screen", "avg_cpu": 11, "avg_fps": 25, "avg_time": 0, "render_time": 0, "flush_time": 0}, {"scene_name": "Moving wallpaper", "avg_cpu": 2, "avg_fps": 25, "avg_time": 0, "render_time": 0, "flush_time": 0}, {"scene_name": "Single rectangle", "avg_cpu": 0, "avg_fps": 25, "avg_time": 0, "render_time": 0, "flush_time": 0}, {"scene_name": "Multiple rectangles", "avg_cpu": 0, "avg_fps": 25, "avg_time": 0, "render_time": 0, "flush_time": 0}, {"scene_name": "Multiple RGB images", "avg_cpu": 0, "avg_fps": 25, "avg_time": 0, "render_time": 0, "flush_time": 0}, {"scene_name": "Multiple ARGB images", "avg_cpu": 23, "avg_fps": 25, "avg_time": 1, "render_time": 1, "flush_time": 0}, {"scene_name": "Rotated ARGB images", "avg_cpu": 48, "avg_fps": 24, "avg_time": 20, "render_time": 20, "flush_time": 0}, {"scene_name": "Multiple labels", "avg_cpu": 3, "avg_fps": 25, "avg_time": 0, "render_time": 0, "flush_time": 0}, {"scene_name": "Screen sized text", "avg_cpu": 30, "avg_fps": 24, "avg_time": 11, "render_time": 11, "flush_time": 0}, {"scene_name": "Multiple arcs", "avg_cpu": 18, "avg_fps": 24, "avg_time": 7, "render_time": 7, "flush_time": 0}, {"scene_name": "Containers", "avg_cpu": 3, "avg_fps": 25, "avg_time": 0, "render_time": 0, "flush_time": 0}, {"scene_name": "Containers with overlay", "avg_cpu": 88, "avg_fps": 21, "avg_time": 44, "render_time": 44, "flush_time": 0}, {"scene_name": "Containers with opa", "avg_cpu": 10, "avg_fps": 24, "avg_time": 3, "render_time": 3, "flush_time": 0}, {"scene_name": "Containers with opa_layer", "avg_cpu": 22, "avg_fps": 24, "avg_time": 8, "render_time": 8, "flush_time": 0}, {"scene_name": "Containers with scrolling", "avg_cpu": 25, "avg_fps": 25, "avg_time": 10, "render_time": 10, "flush_time": 0}, {"scene_name": "Widgets demo", "avg_cpu": 34, "avg_fps": 25, "avg_time": 13, "render_time": 13, "flush_time": 0}, {"scene_name": "All scenes avg.", "avg_cpu": 19, "avg_fps": 24, "avg_time": 7, "render_time": 7, "flush_time": 0}] \ No newline at end of file diff --git a/scripts/perf/tests/filter_docker_logs/test.sh b/scripts/perf/tests/filter_docker_logs/test.sh new file mode 100755 index 0000000000..89e087f99f --- /dev/null +++ b/scripts/perf/tests/filter_docker_logs/test.sh @@ -0,0 +1,15 @@ +#!/bin/sh + +set -e + +ORIGINAL_PWD=$(pwd) +SCRIPT=$(readlink -f $0) +SCRIPT_PATH=$(dirname $SCRIPT) + +cd $SCRIPT_PATH +cat docker-logs-example.txt | python3 ../../filter_docker_benchmark_logs.py actual.json +cd $ORIGINAL_PWD + + +cmp $SCRIPT_PATH/expected.json $SCRIPT_PATH/actual.json + diff --git a/scripts/perf/tests/serialize_results/expected_output/results-32b-lv_conf_perf32b.mpk b/scripts/perf/tests/serialize_results/expected_output/results-32b-lv_conf_perf32b.mpk new file mode 100644 index 0000000000..005677ed65 Binary files /dev/null and b/scripts/perf/tests/serialize_results/expected_output/results-32b-lv_conf_perf32b.mpk differ diff --git a/scripts/perf/tests/serialize_results/expected_output/results-32b-lv_conf_perf32b_a.mpk b/scripts/perf/tests/serialize_results/expected_output/results-32b-lv_conf_perf32b_a.mpk new file mode 100644 index 0000000000..ba089eadb9 Binary files /dev/null and b/scripts/perf/tests/serialize_results/expected_output/results-32b-lv_conf_perf32b_a.mpk differ diff --git a/scripts/perf/tests/serialize_results/expected_output/results-32b-lv_conf_perf32b_b.mpk b/scripts/perf/tests/serialize_results/expected_output/results-32b-lv_conf_perf32b_b.mpk new file mode 100644 index 0000000000..617676f3b3 Binary files /dev/null and b/scripts/perf/tests/serialize_results/expected_output/results-32b-lv_conf_perf32b_b.mpk differ diff --git a/scripts/perf/tests/serialize_results/expected_output/results-64b-lv_conf_perf64b.mpk b/scripts/perf/tests/serialize_results/expected_output/results-64b-lv_conf_perf64b.mpk new file mode 100644 index 0000000000..2fab3588d4 Binary files /dev/null and b/scripts/perf/tests/serialize_results/expected_output/results-64b-lv_conf_perf64b.mpk differ diff --git a/scripts/perf/tests/serialize_results/input/results-32b-lv_conf_perf32b.json b/scripts/perf/tests/serialize_results/input/results-32b-lv_conf_perf32b.json new file mode 100644 index 0000000000..31a0b23f4b --- /dev/null +++ b/scripts/perf/tests/serialize_results/input/results-32b-lv_conf_perf32b.json @@ -0,0 +1 @@ +[{"scene_name": "Empty screen", "avg_cpu": 11, "avg_fps": 25, "avg_time": 0, "render_time": 0, "flush_time": 0}, {"scene_name": "Moving wallpaper", "avg_cpu": 1, "avg_fps": 25, "avg_time": 0, "render_time": 0, "flush_time": 0}, {"scene_name": "Single rectangle", "avg_cpu": 0, "avg_fps": 25, "avg_time": 0, "render_time": 0, "flush_time": 0}, {"scene_name": "Multiple rectangles", "avg_cpu": 0, "avg_fps": 25, "avg_time": 0, "render_time": 0, "flush_time": 0}, {"scene_name": "Multiple RGB images", "avg_cpu": 0, "avg_fps": 25, "avg_time": 0, "render_time": 0, "flush_time": 0}, {"scene_name": "Multiple ARGB images", "avg_cpu": 22, "avg_fps": 25, "avg_time": 1, "render_time": 1, "flush_time": 0}, {"scene_name": "Rotated ARGB images", "avg_cpu": 47, "avg_fps": 24, "avg_time": 20, "render_time": 20, "flush_time": 0}, {"scene_name": "Multiple labels", "avg_cpu": 2, "avg_fps": 25, "avg_time": 0, "render_time": 0, "flush_time": 0}, {"scene_name": "Screen sized text", "avg_cpu": 30, "avg_fps": 24, "avg_time": 11, "render_time": 11, "flush_time": 0}, {"scene_name": "Multiple arcs", "avg_cpu": 19, "avg_fps": 24, "avg_time": 7, "render_time": 7, "flush_time": 0}, {"scene_name": "Containers", "avg_cpu": 1, "avg_fps": 25, "avg_time": 0, "render_time": 0, "flush_time": 0}, {"scene_name": "Containers with overlay", "avg_cpu": 87, "avg_fps": 21, "avg_time": 44, "render_time": 44, "flush_time": 0}, {"scene_name": "Containers with opa", "avg_cpu": 23, "avg_fps": 25, "avg_time": 4, "render_time": 4, "flush_time": 0}, {"scene_name": "Containers with opa_layer", "avg_cpu": 22, "avg_fps": 25, "avg_time": 8, "render_time": 8, "flush_time": 0}, {"scene_name": "Containers with scrolling", "avg_cpu": 25, "avg_fps": 25, "avg_time": 10, "render_time": 10, "flush_time": 0}, {"scene_name": "Widgets demo", "avg_cpu": 34, "avg_fps": 24, "avg_time": 13, "render_time": 13, "flush_time": 0}, {"scene_name": "All scenes avg.", "avg_cpu": 20, "avg_fps": 24, "avg_time": 7, "render_time": 7, "flush_time": 0}] \ No newline at end of file diff --git a/scripts/perf/tests/serialize_results/input/results-32b-lv_conf_perf32b.mpk b/scripts/perf/tests/serialize_results/input/results-32b-lv_conf_perf32b.mpk new file mode 100644 index 0000000000..617676f3b3 Binary files /dev/null and b/scripts/perf/tests/serialize_results/input/results-32b-lv_conf_perf32b.mpk differ diff --git a/scripts/perf/tests/serialize_results/input/results-32b-lv_conf_perf32b_a.json b/scripts/perf/tests/serialize_results/input/results-32b-lv_conf_perf32b_a.json new file mode 100644 index 0000000000..31a0b23f4b --- /dev/null +++ b/scripts/perf/tests/serialize_results/input/results-32b-lv_conf_perf32b_a.json @@ -0,0 +1 @@ +[{"scene_name": "Empty screen", "avg_cpu": 11, "avg_fps": 25, "avg_time": 0, "render_time": 0, "flush_time": 0}, {"scene_name": "Moving wallpaper", "avg_cpu": 1, "avg_fps": 25, "avg_time": 0, "render_time": 0, "flush_time": 0}, {"scene_name": "Single rectangle", "avg_cpu": 0, "avg_fps": 25, "avg_time": 0, "render_time": 0, "flush_time": 0}, {"scene_name": "Multiple rectangles", "avg_cpu": 0, "avg_fps": 25, "avg_time": 0, "render_time": 0, "flush_time": 0}, {"scene_name": "Multiple RGB images", "avg_cpu": 0, "avg_fps": 25, "avg_time": 0, "render_time": 0, "flush_time": 0}, {"scene_name": "Multiple ARGB images", "avg_cpu": 22, "avg_fps": 25, "avg_time": 1, "render_time": 1, "flush_time": 0}, {"scene_name": "Rotated ARGB images", "avg_cpu": 47, "avg_fps": 24, "avg_time": 20, "render_time": 20, "flush_time": 0}, {"scene_name": "Multiple labels", "avg_cpu": 2, "avg_fps": 25, "avg_time": 0, "render_time": 0, "flush_time": 0}, {"scene_name": "Screen sized text", "avg_cpu": 30, "avg_fps": 24, "avg_time": 11, "render_time": 11, "flush_time": 0}, {"scene_name": "Multiple arcs", "avg_cpu": 19, "avg_fps": 24, "avg_time": 7, "render_time": 7, "flush_time": 0}, {"scene_name": "Containers", "avg_cpu": 1, "avg_fps": 25, "avg_time": 0, "render_time": 0, "flush_time": 0}, {"scene_name": "Containers with overlay", "avg_cpu": 87, "avg_fps": 21, "avg_time": 44, "render_time": 44, "flush_time": 0}, {"scene_name": "Containers with opa", "avg_cpu": 23, "avg_fps": 25, "avg_time": 4, "render_time": 4, "flush_time": 0}, {"scene_name": "Containers with opa_layer", "avg_cpu": 22, "avg_fps": 25, "avg_time": 8, "render_time": 8, "flush_time": 0}, {"scene_name": "Containers with scrolling", "avg_cpu": 25, "avg_fps": 25, "avg_time": 10, "render_time": 10, "flush_time": 0}, {"scene_name": "Widgets demo", "avg_cpu": 34, "avg_fps": 24, "avg_time": 13, "render_time": 13, "flush_time": 0}, {"scene_name": "All scenes avg.", "avg_cpu": 20, "avg_fps": 24, "avg_time": 7, "render_time": 7, "flush_time": 0}] \ No newline at end of file diff --git a/scripts/perf/tests/serialize_results/input/results-32b-lv_conf_perf32b_b.mpk b/scripts/perf/tests/serialize_results/input/results-32b-lv_conf_perf32b_b.mpk new file mode 100644 index 0000000000..617676f3b3 Binary files /dev/null and b/scripts/perf/tests/serialize_results/input/results-32b-lv_conf_perf32b_b.mpk differ diff --git a/scripts/perf/tests/serialize_results/input/results-64b-lv_conf_perf64b.json b/scripts/perf/tests/serialize_results/input/results-64b-lv_conf_perf64b.json new file mode 100644 index 0000000000..f7fd438c4e --- /dev/null +++ b/scripts/perf/tests/serialize_results/input/results-64b-lv_conf_perf64b.json @@ -0,0 +1 @@ +[{"scene_name": "Empty screen", "avg_cpu": 11, "avg_fps": 25, "avg_time": 0, "render_time": 0, "flush_time": 0}, {"scene_name": "Moving wallpaper", "avg_cpu": 0, "avg_fps": 25, "avg_time": 0, "render_time": 0, "flush_time": 0}, {"scene_name": "Single rectangle", "avg_cpu": 0, "avg_fps": 25, "avg_time": 0, "render_time": 0, "flush_time": 0}, {"scene_name": "Multiple rectangles", "avg_cpu": 0, "avg_fps": 25, "avg_time": 0, "render_time": 0, "flush_time": 0}, {"scene_name": "Multiple RGB images", "avg_cpu": 0, "avg_fps": 25, "avg_time": 0, "render_time": 0, "flush_time": 0}, {"scene_name": "Multiple ARGB images", "avg_cpu": 1, "avg_fps": 25, "avg_time": 0, "render_time": 0, "flush_time": 0}, {"scene_name": "Rotated ARGB images", "avg_cpu": 23, "avg_fps": 25, "avg_time": 10, "render_time": 10, "flush_time": 0}, {"scene_name": "Multiple labels", "avg_cpu": 3, "avg_fps": 24, "avg_time": 0, "render_time": 0, "flush_time": 0}, {"scene_name": "Screen sized text", "avg_cpu": 23, "avg_fps": 24, "avg_time": 10, "render_time": 10, "flush_time": 0}, {"scene_name": "Multiple arcs", "avg_cpu": 15, "avg_fps": 24, "avg_time": 6, "render_time": 6, "flush_time": 0}, {"scene_name": "Containers", "avg_cpu": 3, "avg_fps": 25, "avg_time": 0, "render_time": 0, "flush_time": 0}, {"scene_name": "Containers with overlay", "avg_cpu": 90, "avg_fps": 23, "avg_time": 41, "render_time": 41, "flush_time": 0}, {"scene_name": "Containers with opa", "avg_cpu": 19, "avg_fps": 25, "avg_time": 4, "render_time": 4, "flush_time": 0}, {"scene_name": "Containers with opa_layer", "avg_cpu": 13, "avg_fps": 24, "avg_time": 5, "render_time": 5, "flush_time": 0}, {"scene_name": "Containers with scrolling", "avg_cpu": 25, "avg_fps": 25, "avg_time": 10, "render_time": 10, "flush_time": 0}, {"scene_name": "Widgets demo", "avg_cpu": 33, "avg_fps": 25, "avg_time": 13, "render_time": 13, "flush_time": 0}, {"scene_name": "All scenes avg.", "avg_cpu": 16, "avg_fps": 24, "avg_time": 6, "render_time": 6, "flush_time": 0}] \ No newline at end of file diff --git a/scripts/perf/tests/serialize_results/input/results-64b-lv_conf_perf64b.mpk b/scripts/perf/tests/serialize_results/input/results-64b-lv_conf_perf64b.mpk new file mode 100644 index 0000000000..083e685915 Binary files /dev/null and b/scripts/perf/tests/serialize_results/input/results-64b-lv_conf_perf64b.mpk differ diff --git a/scripts/perf/tests/serialize_results/test.sh b/scripts/perf/tests/serialize_results/test.sh new file mode 100755 index 0000000000..4b8b881a7e --- /dev/null +++ b/scripts/perf/tests/serialize_results/test.sh @@ -0,0 +1,43 @@ +#!/bin/sh + +set -e + +ORIGINAL_PWD=$(pwd) +SCRIPT=$(readlink -f $0) +SCRIPT_PATH=$(dirname $SCRIPT) + +cd $SCRIPT_PATH +rm -rf output +mkdir output +python3 ../../serialize_results.py --input input --output output --commit-hash abc123456 +cd $ORIGINAL_PWD + + +OUTPUT_DIR=$SCRIPT_PATH/output +EXPECTED_DIR=$SCRIPT_PATH/expected_output + +OUTPUT_COUNT=$(ls -1q "$OUTPUT_DIR" | wc -l) +EXPECTED_COUNT=$(ls -1q "$EXPECTED_DIR" | wc -l) + +if [ "$OUTPUT_COUNT" -ne "$EXPECTED_COUNT" ]; then + echo "[TEST] Mismatch in number of files: Expected $EXPECTED_COUNT. Found $OUTPUT_COUNT" + exit 1 +fi + +for file in "$EXPECTED_DIR"/*; do + filename=$(basename "$file") + output_file="$OUTPUT_DIR/$filename" + + if [ ! -f "$output_file" ]; then + echo "[TEST] Missing file: $filename in output directory" + exit 1 + fi + + if ! cmp -s "$file" "$output_file"; then + echo "[TEST] File mismatch: $filename" + exit 1 + fi +done + +echo "[TEST] Test Passed" +exit 0 diff --git a/scripts/preprocess_lv_conf_internal.py b/scripts/preprocess_lv_conf_internal.py index 93f47d3f67..7fc6e26d21 100755 --- a/scripts/preprocess_lv_conf_internal.py +++ b/scripts/preprocess_lv_conf_internal.py @@ -14,6 +14,7 @@ import os import argparse import re +import shutil import importlib.util @@ -22,7 +23,7 @@ def get_args(): parser.add_argument("--input", help="Path to the input C header file", required=True) parser.add_argument("--tmp_file", help="Path to save the preprocessed output", required=True) parser.add_argument("--output", help="Path to save the cleaned output with removed indentation", required=True) - parser.add_argument("--workfolder", help="Path used to create a python environnement", required=True) + parser.add_argument("--workfolder", help="Path used to create a python environment", required=True) parser.add_argument( "--defs", @@ -158,9 +159,10 @@ def main(): # Check if PCPP is already present on the system # if it's not - create a python venv inside the workfolder directory # and install it there - res = subprocess.run(["which", "pcpp"], capture_output=True) - if res.returncode == 0: - pcpp_exe = res.stdout.decode().replace("\n", "") + pcpp_path = shutil.which("pcpp") + + if pcpp_path: + pcpp_exe = pcpp_path print(f"Found PCPP: {pcpp_exe}") else: print("Failed to locate pcpp - installing it") diff --git a/scripts/prerequisites-apt.txt b/scripts/prerequisites-apt.txt index d1d6a1e553..3ba47d8685 100644 --- a/scripts/prerequisites-apt.txt +++ b/scripts/prerequisites-apt.txt @@ -5,13 +5,14 @@ g++-multilib ninja-build libpng-dev libjpeg-turbo8-dev -libfreetype6-dev +libfreetype-dev libglew-dev libglfw3-dev libsdl2-dev libpng-dev:i386 libjpeg-dev:i386 -libfreetype6-dev:i386 +libfreetype-dev:i386 +libsdl2-dev:i386 ruby-full gcovr cmake diff --git a/scripts/properties.py b/scripts/properties.py index 807e103882..2ab2c01ddc 100755 --- a/scripts/properties.py +++ b/scripts/properties.py @@ -46,7 +46,7 @@ def read_widget_properties(directory): def match_properties(file_path): pattern = r'^\s*LV_PROPERTY_ID2?\((\w+),\s*(\w+),\s*(\w+)(,\s*(\w+))?,\s*(\d+)\)' - with open(file_path, 'r') as file: + with open(file_path, 'r', encoding='utf-8') as file: for line in file.readlines(): match = re.match(pattern, line) if match: @@ -58,7 +58,7 @@ def match_properties(file_path): def match_styles(file_path): pattern = r'^\s+LV_STYLE_(\w+)\s*=\s*(\d+),' - with open(file_path, 'r') as file: + with open(file_path, 'r', encoding='utf-8') as file: for line in file.readlines(): match = re.match(pattern, line) if match: @@ -173,7 +173,7 @@ def write_style_header(output, properties_by_widget): /* *INDENT-OFF* */ -enum {{ +enum _lv_property_style_id_t {{ ''') for property in properties: @@ -190,6 +190,7 @@ def write_style_header(output, properties_by_widget): def main(directory, output): + """Generate property names""" property = read_widget_properties(directory) write_widget_properties(output, property) write_style_header(output, property) diff --git a/scripts/release_branch_updater.py b/scripts/release_branch_updater.py index b797ef2aa6..bf20088409 100755 --- a/scripts/release_branch_updater.py +++ b/scripts/release_branch_updater.py @@ -82,7 +82,7 @@ def main(): branches_to_update = lvgl_release_branches if not skip_master: - branches_to_update += [lvgl_default_branch] + branches_to_update = branches_to_update + [lvgl_default_branch] # from oldest to newest release... for lvgl_branch in branches_to_update: @@ -151,19 +151,28 @@ def main(): if "lvgl.path " in line ), None) + # check if the submodule is really in the index and not just a leftover in .gitmodules + out = subprocess.check_output(("git", "-C", port_clone_tmpdir, "submodule", "status")) + if not any( + line.split(maxsplit=1)[1].rsplit(maxsplit=1)[0] == port_lvgl_submodule_path + for line + in out.decode().strip().splitlines() + ): + port_lvgl_submodule_path = None + if port_lvgl_submodule_path is None: print(LOG, "this port has no LVGL submodule") else: print(LOG, "lvgl submodule found in port at:", port_lvgl_submodule_path) # get the SHA of LVGL in this release of LVGL - out = subprocess.check_output(("git", "-C", lvgl_path, "rev-parse", "--verify", "--quiet", "HEAD")) + out = subprocess.check_output(("git", "-C", lvgl_path, "rev-parse", "--verify", "HEAD")) lvgl_sha = out.decode().strip() print(LOG, "the SHA of LVGL in this release should be:", lvgl_sha) # get the SHA of LVGL this port wants to use in this release out = subprocess.check_output(("git", "-C", port_clone_tmpdir, "rev-parse", - "--verify", "--quiet", f"HEAD:{port_lvgl_submodule_path}")) + "--verify", f"HEAD:{port_lvgl_submodule_path}")) port_lvgl_submodule_sha = out.decode().strip() print(LOG, "the SHA of LVGL in the submodule of this port is:", port_lvgl_submodule_sha) @@ -233,7 +242,7 @@ def main(): def get_release_branches(working_dir): - out = subprocess.check_output(("git", "-C", working_dir, "branch", "--quiet", "--format", "%(refname)", "--all")) + out = subprocess.check_output(("git", "-C", working_dir, "branch", "--format", "%(refname)", "--all")) branches = out.decode().strip().splitlines() release_versions = [] diff --git a/scripts/release_branch_updater_port_urls.txt b/scripts/release_branch_updater_port_urls.txt index 6b6c130924..a4b2990412 100644 --- a/scripts/release_branch_updater_port_urls.txt +++ b/scripts/release_branch_updater_port_urls.txt @@ -2,8 +2,27 @@ https://github.com/lvgl/lv_port_linux https://github.com/lvgl/lv_port_pc_eclipse https://github.com/lvgl/lv_port_pc_vscode https://github.com/lvgl/lv_port_renesas_ek-ra8d1_gcc -https://github.com/lvgl/lv_port_riverdi_stm32u5 https://github.com/lvgl/lv_nuttx https://github.com/lvgl/lv_zephyr https://github.com/lvgl/lv_esp_idf https://github.com/lvgl/lv_port_actions_technology +https://github.com/lvgl/lv_port_icop_qec_ppc_m_090t +https://github.com/lvgl/lv_port_nxp_frdm_mcxn947 +https://github.com/lvgl/lv_port_nxp_imx_rt500_evk +https://github.com/lvgl/lv_port_nxp_mimxrt1064-evk +https://github.com/lvgl/lv_port_nxp_imxrt1170-evkb +https://github.com/lvgl/lv_port_raspberry_pi_pico_mdk +https://github.com/lvgl/lv_port_renesas_rz-g2ul-evkit +https://github.com/lvgl/lv_port_renesas_ek-ra6m3g +https://github.com/lvgl/lv_port_renesas_rz-g2l-evkit +https://github.com/lvgl/lv_port_renesas-ek-rz_a3m +https://github.com/lvgl/lv_port_renesas_ek_ra8p1 +https://github.com/lvgl/lv_port_riverdi_stm32u5 +https://github.com/lvgl/lv_port_riverdi_101-stm32h7 +https://github.com/lvgl/lv_port_riverdi_70-stm32h7 +https://github.com/lvgl/lv_port_stm32h7b3i_disco +https://github.com/lvgl/lv_port_stm32h745i_disco +https://github.com/lvgl/lv_port_stm32f746_disco +https://github.com/lvgl/lv_port_stm32f769_disco +https://github.com/lvgl/lv_port_stm32u5g9j-dk2 +https://github.com/lvgl/lv_port_stm_nucleo_g071rb diff --git a/scripts/run_tests.sh b/scripts/run_tests.sh new file mode 100755 index 0000000000..addc605bff --- /dev/null +++ b/scripts/run_tests.sh @@ -0,0 +1,146 @@ +#!/bin/bash + +start_time=$(date +%s) + +skip_tests=false + +while [ "$#" -gt 0 ]; do + case $1 in + --skip-tests) skip_tests=true ;; + *) echo "Unknown parameter passed: $1"; exit 1 ;; + esac + shift +done + +CUR_DIR=$(cd "$(dirname "$0")"; pwd) +cd ${CUR_DIR}/.. +echo "Current directory: $CUR_DIR" + +echo "Checking prerequisites..." + +# List of packages to install +apt_packages=$(cat scripts/prerequisites-apt.txt) +echo "Required packages: $apt_packages" + +missing_packages_count=0 + +# Check if each package is installed +for package in $apt_packages; do + if ! dpkg -l | grep -q "^ii $package"; then + echo "Package $package is not installed." + missing_packages_count=$((missing_packages_count + 1)) + else + echo "Package $package is already installed." + fi +done + +# List of Python packages to install +pip_packages=$(cat scripts/prerequisites-pip.txt) +echo "Required Python packages: $pip_packages" + +# Check if each Python package is installed +for package in $pip_packages; do + if ! pip3 show $package > /dev/null 2>&1; then + echo "Python package $package is not installed" + missing_packages_count=$((missing_packages_count + 1)) + else + echo "Python package $package is already installed." + fi +done + +if [ $missing_packages_count -gt 0 ]; then + echo "Missing $missing_packages_count packages detected. Please run 'scripts/install-prerequisites.sh' to install them." + echo "Current packages installed:" + apt list --installed + exit 1 +else + echo "All required packages are installed." +fi + +# Check gcovr version +gcovr_version=$(gcovr --version | grep -oP '\d+\.\d+') +required_version=7.0 + +if (( $(echo "$gcovr_version < $required_version" | bc -l) )); then + echo "gcovr version is $gcovr_version, which is lower than $required_version" + echo "Please run 'pip3 install --upgrade gcovr' to install a newer version." + exit 1 +else + echo "gcovr version is $gcovr_version, which meets the requirement." +fi + +# Get versions of g++, gcc, and gcov +gpp_version=$(g++ -dumpversion) +gcc_version=$(gcc -dumpversion) +gcov_version=$(gcov -dumpversion | grep -oP '\d+\.\d+.\d+' | head -n 1 | cut -d'.' -f1) # only major version + +# Check if g++, gcc, and gcov versions are the same +if [ "$gpp_version" != "$gcc_version" ] || [ "$gcc_version" != "$gcov_version" ]; then + echo "Versions mismatch detected:" + echo "g++ version: $gpp_version" + echo "gcc version: $gcc_version" + echo "gcov version: $gcov_version" + echo "g++, gcc, and gcov must have the same version." + exit 1 +else + echo "g++, gcc, and gcov versions match: $gpp_version" +fi + +if [ "$skip_tests" = true ]; then + echo "Skipping tests as --skip-tests was specified." + elapsed_time=$(($(date +%s) - start_time)) + minutes=$((elapsed_time / 60)) + seconds=$((elapsed_time % 60)) + echo "Prerequisites checked in $minutes minutes and $seconds seconds." + exit 0 +fi + +# Run tests for 32-bit build and test +echo "Running tests for 32-bit build and test..." + +export NON_AMD64_BUILD=1 +./tests/main.py --clean --report build test +if [ $? -eq 0 ]; then + echo "32-bit tests passed." + rm -rf ./tests/report-32bit + mv ./tests/report ./tests/report-32bit +else + echo "32-bit tests failed!" + exit 1 +fi + +# Run tests for 64-bit build and test +echo "Running tests for 64-bit build and test..." + +unset NON_AMD64_BUILD +./tests/main.py --clean --report build test +if [ $? -eq 0 ]; then + echo "64-bit tests passed." + rm -rf ./tests/report-64bit + mv ./tests/report ./tests/report-64bit +else + echo "64-bit tests failed!" + exit 1 +fi + +new_png_files=$(git status --porcelain | grep "\?\? .*\.png") +if [ -n "$new_png_files" ]; then + echo "New untracked PNG files detected:" + echo "$new_png_files" + echo "Please add them to the repository and commit them." + exit 1 +else + echo "No new untracked PNG files detected." +fi + +elapsed_time=$(($(date +%s) - start_time)) +minutes=$((elapsed_time / 60)) +seconds=$((elapsed_time % 60)) +echo "Tests completed in $minutes minutes and $seconds seconds." + +echo "See gcovr reports in:" +echo " $PWD/tests/report-32bit/index.html" +echo " $PWD/tests/report-64bit/index.html" + +echo "LVGL all tests passed." +exit 0 diff --git a/scripts/style_api_gen.py b/scripts/style_api_gen.py index 21acadcaf8..7a4006d206 100755 --- a/scripts/style_api_gen.py +++ b/scripts/style_api_gen.py @@ -273,6 +273,10 @@ 'style_type': 'num', 'var_type': 'lv_opa_t' , 'default':0, 'inherited': 0, 'layout': 0, 'ext_draw': 0, 'dsc': "Set intensity of color mixing. Value 0, `LV_OPA_0` or `LV_OPA_TRANSP` means fully transparent, 255, `LV_OPA_100` or `LV_OPA_COVER` means fully covering, other values or LV_OPA_10, LV_OPA_20, etc means semi transparency."}, +{'name': 'IMAGE_COLORKEY', + 'style_type': 'ptr', 'var_type': 'const lv_image_colorkey_t *', 'default':'`NULL`', 'inherited': 0, 'layout': 0, 'ext_draw': 0, + 'dsc': "Set image colorkey definition. The lv_image_colorkey_t contains two color values: `high_color` and `low_color`. the color of pixels ranging from `low_color` to `high_color` will be transparent."}, + {'section': 'Line', 'dsc':'Properties to describe line-like Widgets' }, {'name': 'LINE_WIDTH', 'style_type': 'num', 'var_type': 'int32_t' , 'default':0, 'inherited': 0, 'layout': 0, 'ext_draw': 1, @@ -371,7 +375,7 @@ {'name': 'CLIP_CORNER', 'style_type': 'num', 'var_type': 'bool', 'default':0, 'inherited': 0, 'layout': 0, 'ext_draw': 0, - 'dsc': "Enable to clip the overflowed content on the rounded corner. Can be `true` or `false`." }, + 'dsc': "Enable clipping of content that overflows rounded corners of parent Widget. Can be `true` or `false`." }, {'name': 'OPA', 'style_type': 'num', 'var_type': 'lv_opa_t', 'default':'`LV_OPA_COVER`', 'inherited': 1, 'layout': 0, 'ext_draw': 0, @@ -395,7 +399,7 @@ {'name': 'RECOLOR_OPA', 'style_type': 'num', 'var_type': 'lv_opa_t', 'default':'`LV_OPA_TRANSP`', 'inherited': 0, 'layout': 0, 'ext_draw': 0, - 'dsc': "Set intensity of color mixing. Value 0, `LV_OPA_0` or `LV_OPA_TRANSP` means fully transparent, 255, `LV_OPA_100` or `LV_OPA_COVER` means fully covering, other values or LV_OPA_10, LV_OPA_20, etc means semi transparency."}, + 'dsc': "Sets the intensity of color mixing. Value 0, `LV_OPA_0` or `LV_OPA_TRANSP` means fully transparent. A value of 255, `LV_OPA_100` or `LV_OPA_COVER` means fully opaque. Intermediate values like LV_OPA_10, LV_OPA_20, etc result in semi-transparency."}, {'name': 'ANIM', 'style_type': 'ptr', 'var_type': 'const lv_anim_t *', 'default':'`NULL`', 'inherited': 0, 'layout': 0, 'ext_draw': 0, @@ -478,7 +482,7 @@ 'dsc': "Defines how to distribute the rows."}, {'name': 'GRID_CELL_COLUMN_POS', - 'style_type': 'num', 'var_type': 'int32_t', 'default':'`LV_GRID_ALIGN_START`', 'inherited': 0, 'layout': 1, 'ext_draw': 0, + 'style_type': 'num', 'var_type': 'int32_t', 'default':0, 'inherited': 0, 'layout': 1, 'ext_draw': 0, 'dsc': "Set column in which Widget should be placed."}, {'name': 'GRID_CELL_X_ALIGN', @@ -486,11 +490,11 @@ 'dsc': "Set how to align Widget horizontally."}, {'name': 'GRID_CELL_COLUMN_SPAN', - 'style_type': 'num', 'var_type': 'int32_t', 'default':'`LV_GRID_ALIGN_START`', 'inherited': 0, 'layout': 1, 'ext_draw': 0, + 'style_type': 'num', 'var_type': 'int32_t', 'default':1, 'inherited': 0, 'layout': 1, 'ext_draw': 0, 'dsc': "Set how many columns Widget should span. Needs to be >= 1."}, {'name': 'GRID_CELL_ROW_POS', - 'style_type': 'num', 'var_type': 'int32_t', 'default':'`LV_GRID_ALIGN_START`', 'inherited': 0, 'layout': 1, 'ext_draw': 0, + 'style_type': 'num', 'var_type': 'int32_t', 'default':0, 'inherited': 0, 'layout': 1, 'ext_draw': 0, 'dsc': "Set row in which Widget should be placed."}, {'name': 'GRID_CELL_Y_ALIGN', @@ -498,7 +502,7 @@ 'dsc': "Set how to align Widget vertically."}, {'name': 'GRID_CELL_ROW_SPAN', - 'style_type': 'num', 'var_type': 'int32_t', 'default':'`LV_GRID_ALIGN_START`', 'inherited': 0, 'layout': 1, 'ext_draw': 0, + 'style_type': 'num', 'var_type': 'int32_t', 'default':1, 'inherited': 0, 'layout': 1, 'ext_draw': 0, 'dsc': "Set how many rows Widget should span. Needs to be >= 1."}, ] @@ -747,7 +751,7 @@ def guard_close(): ''') print('#endif /* LV_STYLE_GEN_H */') -sys.stdout = open(base_dir + '/../docs/details/base-widget/styles/style-properties.rst', 'w') +sys.stdout = open(base_dir + '/../docs/src/details/common-widget-features/styles/style-properties.rst', 'w') print('.. _style_properties:') print() diff --git a/src/core/lv_global.h b/src/core/lv_global.h index 4515c01c9b..da32f8ccc8 100644 --- a/src/core/lv_global.h +++ b/src/core/lv_global.h @@ -27,7 +27,7 @@ extern "C" { #include "../misc/lv_log.h" #include "../misc/lv_style.h" #include "../misc/lv_timer.h" -#include "../osal/lv_os.h" +#include "../osal/lv_os_private.h" #include "../others/sysmon/lv_sysmon.h" #include "../stdlib/builtin/lv_tlsf.h" @@ -35,10 +35,6 @@ extern "C" { #include "../font/lv_font_fmt_txt_private.h" #endif -#if LV_USE_OS != LV_OS_NONE && defined(__linux__) -#include "../osal/lv_linux_private.h" -#endif - #include "../tick/lv_tick.h" #include "../layouts/lv_layout.h" @@ -82,6 +78,14 @@ struct _lv_nuttx_ctx_t; #endif typedef struct _lv_global_t { + /** + * User data for the LVGL library. Move from the bottom of the struct + * to avoid breaking the ABI. E.g., if the user data is used by a + * closed-source library, this can help to avoid re-compiling the library + * when the lvgl-related configs are changed. + */ + void * user_data; + bool inited; bool deinit_in_progress; /**< Can be used e.g. in the LV_EVENT_DELETE to deinit the drivers too */ @@ -122,6 +126,10 @@ typedef struct _lv_global_t { * can be managed by image cache. */ lv_ll_t img_decoder_ll; +#if LV_USE_OS != LV_OS_NONE + lv_mutex_t img_decoder_info_lock; + lv_mutex_t img_decoder_open_lock; +#endif lv_cache_t * img_cache; lv_cache_t * img_header_cache; @@ -191,6 +199,10 @@ typedef struct _lv_global_t { lv_fs_drv_t arduino_sd_fs_drv; #endif +#if LV_USE_FS_FROGFS + lv_fs_drv_t frogfs_fs_drv; +#endif + #if LV_USE_FREETYPE struct _lv_freetype_context_t * ft_context; #endif @@ -207,8 +219,10 @@ typedef struct _lv_global_t { struct _lv_profiler_builtin_ctx_t * profiler_context; #endif -#if LV_USE_FILE_EXPLORER != 0 - lv_style_t fe_list_button_style; + +#if LV_USE_FILE_EXPLORER + lv_style_t file_explorer_quick_access_style; + size_t file_explorer_count; #endif #if LV_USE_MEM_MONITOR @@ -228,14 +242,24 @@ typedef struct _lv_global_t { lv_test_state_t test_state; #endif +#if LV_USE_TRANSLATION + lv_ll_t translation_packs_ll; + const char * translation_selected_lang; +#endif + #if LV_USE_NUTTX struct _lv_nuttx_ctx_t * nuttx_ctx; #endif #if LV_USE_OS != LV_OS_NONE lv_mutex_t lv_general_mutex; +#endif + #if defined(__linux__) - lv_proc_stat_t linux_last_proc_stat; + lv_linux_proc_stat_t linux_last_proc_stat; +#if LV_SYSMON_PROC_IDLE_AVAILABLE + uint64_t linux_last_self_proc_time_ticks; + lv_linux_proc_stat_t linux_last_system_total_ticks_stat; #endif #endif @@ -250,7 +274,15 @@ typedef struct _lv_global_t { lv_evdev_discovery_t * evdev_discovery; #endif - void * user_data; +#if LV_USE_XML + const char * xml_path_prefix; + uint32_t lv_event_xml_store_timeline; + lv_ll_t xml_loads; +#endif + +#if LV_USE_DRAW_EVE + lv_draw_eve_unit_t * draw_eve_unit; +#endif } lv_global_t; /********************** diff --git a/src/core/lv_obj.c b/src/core/lv_obj.c index fa19d4a980..fa0c81f443 100644 --- a/src/core/lv_obj.c +++ b/src/core/lv_obj.c @@ -23,6 +23,7 @@ #include "../misc/lv_math.h" #include "../misc/lv_log.h" #include "../misc/lv_types.h" +#include "../misc/lv_anim_timeline.h" #include "../tick/lv_tick.h" #include "../stdlib/lv_string.h" #include "lv_obj_draw_private.h" @@ -39,6 +40,22 @@ * TYPEDEFS **********************/ +typedef struct { + lv_screen_load_anim_t anim_type; + uint32_t duration; + uint32_t delay; + union { + lv_obj_t * screen; + lv_screen_create_cb_t create_cb; + } target; +} screen_load_anim_dsc_t; + +typedef struct { + lv_anim_timeline_t * at; + uint32_t delay; + bool reverse; +} timeline_play_dsc_t; + /********************** * STATIC PROTOTYPES **********************/ @@ -50,7 +67,13 @@ static void draw_scrollbar(lv_obj_t * obj, lv_layer_t * layer); static lv_result_t scrollbar_init_draw_dsc(lv_obj_t * obj, lv_draw_rect_dsc_t * dsc); static bool obj_valid_child(const lv_obj_t * parent, const lv_obj_t * obj_to_find); static void update_obj_state(lv_obj_t * obj, lv_state_t new_state); +static void lv_obj_children_add_state(lv_obj_t * obj, lv_state_t state); +static void lv_obj_children_remove_state(lv_obj_t * obj, lv_state_t state); static void null_on_delete_cb(lv_event_t * e); +static void screen_load_on_trigger_event_cb(lv_event_t * e); +static void screen_create_on_trigger_event_cb(lv_event_t * e); +static void play_timeline_on_trigger_event_cb(lv_event_t * e); +static void delete_on_screen_unloaded_event_cb(lv_event_t * e); #if LV_USE_OBJ_PROPERTY static lv_result_t lv_obj_set_any(lv_obj_t *, lv_prop_id_t, const lv_property_t *); @@ -308,6 +331,9 @@ void lv_obj_add_state(lv_obj_t * obj, lv_state_t state) lv_state_t new_state = obj->state | state; if(obj->state != new_state) { update_obj_state(obj, new_state); + if(lv_obj_has_flag(obj, LV_OBJ_FLAG_STATE_TRICKLE)) { + lv_obj_children_add_state(obj, state); + } } } @@ -318,6 +344,9 @@ void lv_obj_remove_state(lv_obj_t * obj, lv_state_t state) lv_state_t new_state = obj->state & (~state); if(obj->state != new_state) { update_obj_state(obj, new_state); + if(lv_obj_has_flag(obj, LV_OBJ_FLAG_STATE_TRICKLE)) { + lv_obj_children_remove_state(obj, state); + } } } @@ -461,6 +490,55 @@ lv_obj_t * lv_obj_find_by_id(const lv_obj_t * obj, const void * id) } #endif +void lv_obj_add_screen_load_event(lv_obj_t * obj, lv_event_code_t trigger, lv_obj_t * screen, + lv_screen_load_anim_t anim_type, uint32_t duration, uint32_t delay) +{ + if(screen == NULL) { + LV_LOG_WARN("`screen` is NULL, can't load a non existing screens"); + return; + } + + screen_load_anim_dsc_t * dsc = lv_malloc(sizeof(screen_load_anim_dsc_t)); + LV_ASSERT_MALLOC(dsc); + lv_memzero(dsc, sizeof(screen_load_anim_dsc_t)); + dsc->anim_type = anim_type; + dsc->duration = duration; + dsc->delay = delay; + dsc->target.screen = screen; + + lv_obj_add_event_cb(obj, screen_load_on_trigger_event_cb, trigger, dsc); + lv_obj_add_event_cb(obj, lv_event_free_user_data_cb, LV_EVENT_DELETE, dsc); +} + +void lv_obj_add_screen_create_event(lv_obj_t * obj, lv_event_code_t trigger, lv_screen_create_cb_t screen_create_cb, + lv_screen_load_anim_t anim_type, uint32_t duration, uint32_t delay) +{ + screen_load_anim_dsc_t * dsc = lv_malloc(sizeof(screen_load_anim_dsc_t)); + LV_ASSERT_MALLOC(dsc); + lv_memzero(dsc, sizeof(screen_load_anim_dsc_t)); + dsc->anim_type = anim_type; + dsc->duration = duration; + dsc->delay = delay; + dsc->target.create_cb = screen_create_cb; + + lv_obj_add_event_cb(obj, screen_create_on_trigger_event_cb, trigger, dsc); + lv_obj_add_event_cb(obj, lv_event_free_user_data_cb, LV_EVENT_DELETE, dsc); +} + +void lv_obj_add_play_timeline_event(lv_obj_t * obj, lv_event_code_t trigger, lv_anim_timeline_t * at, uint32_t delay, + bool reverse) +{ + timeline_play_dsc_t * dsc = lv_malloc(sizeof(timeline_play_dsc_t)); + LV_ASSERT_MALLOC(dsc); + lv_memzero(dsc, sizeof(timeline_play_dsc_t)); + dsc->at = at; + dsc->delay = delay; + dsc->reverse = reverse; + + lv_obj_add_event_cb(obj, play_timeline_on_trigger_event_cb, trigger, dsc); + lv_obj_add_event_cb(obj, lv_event_free_user_data_cb, LV_EVENT_DELETE, dsc); +} + void lv_obj_set_user_data(lv_obj_t * obj, void * user_data) { obj->user_data = user_data; @@ -592,14 +670,14 @@ static void lv_obj_draw(lv_event_t * e) return; } - if(lv_obj_get_style_bg_grad_dir(obj, 0) != LV_GRAD_DIR_NONE) { - if(lv_obj_get_style_bg_grad_opa(obj, 0) < LV_OPA_MAX || - lv_obj_get_style_bg_main_opa(obj, 0) < LV_OPA_MAX) { + if(lv_obj_get_style_bg_grad_dir(obj, LV_PART_MAIN) != LV_GRAD_DIR_NONE) { + if(lv_obj_get_style_bg_grad_opa(obj, LV_PART_MAIN) < LV_OPA_MAX || + lv_obj_get_style_bg_main_opa(obj, LV_PART_MAIN) < LV_OPA_MAX) { info->res = LV_COVER_RES_NOT_COVER; return; } } - const lv_grad_dsc_t * grad_dsc = lv_obj_get_style_bg_grad(obj, 0); + const lv_grad_dsc_t * grad_dsc = lv_obj_get_style_bg_grad(obj, LV_PART_MAIN); if(grad_dsc) { uint32_t i; for(i = 0; i < grad_dsc->stops_count; i++) { @@ -982,6 +1060,40 @@ static void update_obj_state(lv_obj_t * obj, lv_state_t new_state) } } +/** + * Apply the state to the children of the object + * @param obj pointer to an object + * @param state the state to apply + */ +static void lv_obj_children_add_state(lv_obj_t * obj, lv_state_t state) +{ + uint32_t child_count = lv_obj_get_child_count(obj); + + for(uint32_t i = 0; i < child_count; i++) { + lv_obj_t * child = lv_obj_get_child(obj, i); + if(child) { + lv_obj_add_state(child, state); + } + } +} + +/** + * Remove the state from the children of the object + * @param obj pointer to an object + * @param state the state to remove + */ +static void lv_obj_children_remove_state(lv_obj_t * obj, lv_state_t state) +{ + uint32_t child_count = lv_obj_get_child_count(obj); + + for(uint32_t i = 0; i < child_count; i++) { + lv_obj_t * child = lv_obj_get_child(obj, i); + if(child) { + lv_obj_remove_state(child, state); + } + } +} + static bool obj_valid_child(const lv_obj_t * parent, const lv_obj_t * obj_to_find) { /*Check all children of `parent`*/ @@ -1009,6 +1121,61 @@ static void null_on_delete_cb(lv_event_t * e) *obj_ptr = NULL; } +static void screen_load_on_trigger_event_cb(lv_event_t * e) +{ + screen_load_anim_dsc_t * dsc = lv_event_get_user_data(e); + LV_ASSERT_NULL(dsc); + lv_screen_load_anim(dsc->target.screen, dsc->anim_type, dsc->duration, dsc->delay, false); +} + +static void screen_create_on_trigger_event_cb(lv_event_t * e) +{ + screen_load_anim_dsc_t * dsc = lv_event_get_user_data(e); + LV_ASSERT_NULL(dsc); + + lv_obj_t * screen = dsc->target.create_cb(); + lv_screen_load_anim(screen, dsc->anim_type, dsc->duration, dsc->delay, false); + lv_obj_add_event_cb(screen, delete_on_screen_unloaded_event_cb, LV_EVENT_SCREEN_UNLOADED, NULL); +} + +static void play_timeline_on_trigger_event_cb(lv_event_t * e) +{ + timeline_play_dsc_t * dsc = lv_event_get_user_data(e); + LV_ASSERT_NULL(dsc); + + /*Reset the progress only if the animation was finished*/ + uint16_t progress = lv_anim_timeline_get_progress(dsc->at); + if(dsc->reverse) { + if(progress == 0) { + lv_anim_timeline_set_progress(dsc->at, LV_ANIM_TIMELINE_PROGRESS_MAX); + } + + if(lv_anim_timeline_get_progress(dsc->at) == LV_ANIM_TIMELINE_PROGRESS_MAX) { + lv_anim_timeline_set_delay(dsc->at, dsc->delay); + } + + lv_anim_timeline_set_reverse(dsc->at, true); + } + else { + if(progress == LV_ANIM_TIMELINE_PROGRESS_MAX) { + lv_anim_timeline_set_progress(dsc->at, 0); + } + + if(lv_anim_timeline_get_progress(dsc->at) == 0) { + lv_anim_timeline_set_delay(dsc->at, dsc->delay); + } + + lv_anim_timeline_set_reverse(dsc->at, false); + } + lv_anim_timeline_start(dsc->at); +} + + +static void delete_on_screen_unloaded_event_cb(lv_event_t * e) +{ + lv_obj_delete(lv_event_get_target_obj(e)); +} + #if LV_USE_OBJ_PROPERTY static lv_result_t lv_obj_set_any(lv_obj_t * obj, lv_prop_id_t id, const lv_property_t * prop) { diff --git a/src/core/lv_obj.h b/src/core/lv_obj.h index 49c71aac39..ead6ba5a5b 100644 --- a/src/core/lv_obj.h +++ b/src/core/lv_obj.h @@ -38,50 +38,6 @@ extern "C" { /********************** * TYPEDEFS **********************/ - -/** - * Possible states of a widget. - * OR-ed values are possible - */ -enum { - LV_STATE_DEFAULT = 0x0000, - LV_STATE_CHECKED = 0x0001, - LV_STATE_FOCUSED = 0x0002, - LV_STATE_FOCUS_KEY = 0x0004, - LV_STATE_EDITED = 0x0008, - LV_STATE_HOVERED = 0x0010, - LV_STATE_PRESSED = 0x0020, - LV_STATE_SCROLLED = 0x0040, - LV_STATE_DISABLED = 0x0080, - LV_STATE_USER_1 = 0x1000, - LV_STATE_USER_2 = 0x2000, - LV_STATE_USER_3 = 0x4000, - LV_STATE_USER_4 = 0x8000, - - LV_STATE_ANY = 0xFFFF, /**< Special value can be used in some functions to target all states*/ -}; - -/** - * The possible parts of widgets. - * The parts can be considered as the internal building block of the widgets. - * E.g. slider = background + indicator + knob - * Not all parts are used by every widget - */ - -enum { - LV_PART_MAIN = 0x000000, /**< A background like rectangle*/ - LV_PART_SCROLLBAR = 0x010000, /**< The scrollbar(s)*/ - LV_PART_INDICATOR = 0x020000, /**< Indicator, e.g. for slider, bar, switch, or the tick box of the checkbox*/ - LV_PART_KNOB = 0x030000, /**< Like handle to grab to adjust the value*/ - LV_PART_SELECTED = 0x040000, /**< Indicate the currently selected option or section*/ - LV_PART_ITEMS = 0x050000, /**< Used if the widget has multiple similar elements (e.g. table cells)*/ - LV_PART_CURSOR = 0x060000, /**< Mark a specific place e.g. for text area's cursor or on a chart*/ - - LV_PART_CUSTOM_FIRST = 0x080000, /**< Extension point for custom widgets*/ - - LV_PART_ANY = 0x0F0000, /**< Special value can be used in some functions to target all parts*/ -}; - /** * On/Off features controlling the object's behavior. * OR-ed values are possible @@ -112,12 +68,14 @@ typedef enum { LV_OBJ_FLAG_FLOATING = (1L << 18), /**< Do not scroll the object when the parent scrolls and ignore layout*/ LV_OBJ_FLAG_SEND_DRAW_TASK_EVENTS = (1L << 19), /**< Send `LV_EVENT_DRAW_TASK_ADDED` events*/ LV_OBJ_FLAG_OVERFLOW_VISIBLE = (1L << 20),/**< Do not clip the children to the parent's ext draw size*/ -#if LV_USE_FLEX - LV_OBJ_FLAG_FLEX_IN_NEW_TRACK = (1L << 21), /**< Start a new flex track on this item*/ -#endif + LV_OBJ_FLAG_EVENT_TRICKLE = (1L << 21), /**< Propagate the events to the children too*/ + LV_OBJ_FLAG_STATE_TRICKLE = (1L << 22), /**< Propagate the states to the children too*/ LV_OBJ_FLAG_LAYOUT_1 = (1L << 23), /**< Custom flag, free to use by layouts*/ LV_OBJ_FLAG_LAYOUT_2 = (1L << 24), /**< Custom flag, free to use by layouts*/ +#if LV_USE_FLEX + LV_OBJ_FLAG_FLEX_IN_NEW_TRACK = LV_OBJ_FLAG_LAYOUT_1, /**< Start a new flex track on this item*/ +#endif LV_OBJ_FLAG_WIDGET_1 = (1L << 25), /**< Custom flag, free to use by widget*/ LV_OBJ_FLAG_WIDGET_2 = (1L << 26), /**< Custom flag, free to use by widget*/ @@ -128,7 +86,7 @@ typedef enum { } lv_obj_flag_t; #if LV_USE_OBJ_PROPERTY -enum { +enum _lv_signed_prop_id_t { /*OBJ flag properties */ LV_PROPERTY_ID(OBJ, FLAG_START, LV_PROPERTY_TYPE_INT, 0), LV_PROPERTY_ID(OBJ, FLAG_HIDDEN, LV_PROPERTY_TYPE_INT, 0), @@ -152,9 +110,11 @@ enum { LV_PROPERTY_ID(OBJ, FLAG_FLOATING, LV_PROPERTY_TYPE_INT, 18), LV_PROPERTY_ID(OBJ, FLAG_SEND_DRAW_TASK_EVENTS, LV_PROPERTY_TYPE_INT, 19), LV_PROPERTY_ID(OBJ, FLAG_OVERFLOW_VISIBLE, LV_PROPERTY_TYPE_INT, 20), - LV_PROPERTY_ID(OBJ, FLAG_FLEX_IN_NEW_TRACK, LV_PROPERTY_TYPE_INT, 21), + LV_PROPERTY_ID(OBJ, FLAG_EVENT_TRICKLE, LV_PROPERTY_TYPE_INT, 21), + LV_PROPERTY_ID(OBJ, FLAG_STATE_TRICKLE, LV_PROPERTY_TYPE_INT, 22), LV_PROPERTY_ID(OBJ, FLAG_LAYOUT_1, LV_PROPERTY_TYPE_INT, 23), LV_PROPERTY_ID(OBJ, FLAG_LAYOUT_2, LV_PROPERTY_TYPE_INT, 24), + LV_PROPERTY_ID(OBJ, FLAG_FLEX_IN_NEW_TRACK, LV_PROPERTY_TYPE_INT, 23), /*Mapped to FLAG_LAYOUT_1*/ LV_PROPERTY_ID(OBJ, FLAG_WIDGET_1, LV_PROPERTY_TYPE_INT, 25), LV_PROPERTY_ID(OBJ, FLAG_WIDGET_2, LV_PROPERTY_TYPE_INT, 26), LV_PROPERTY_ID(OBJ, FLAG_USER_1, LV_PROPERTY_TYPE_INT, 27), @@ -383,6 +343,43 @@ bool lv_obj_is_valid(const lv_obj_t * obj); */ void lv_obj_null_on_delete(lv_obj_t ** obj_ptr); +/** + * Add an event handler to a widget that will load a screen on a trigger. + * @param obj pointer to widget which should load the screen + * @param trigger an event code, e.g. `LV_EVENT_CLICKED` + * @param screen the screen to load (must be a valid widget) + * @param anim_type element of `lv_screen_load_anim_t` the screen load animation + * @param duration duration of the animation in milliseconds + * @param delay delay before the screen load in milliseconds + */ +void lv_obj_add_screen_load_event(lv_obj_t * obj, lv_event_code_t trigger, lv_obj_t * screen, + lv_screen_load_anim_t anim_type, uint32_t duration, uint32_t delay); + +/** + * Add an event handler to a widget that will create a screen on a trigger. + * The created screen will be deleted when it's unloaded + * @param obj pointer to widget which should load the screen + * @param trigger an event code, e.g. `LV_EVENT_CLICKED` + * @param screen_create_cb a callback to create the screen, e.g. `lv_obj_t * myscreen_create(void)` + * @param anim_type element of `lv_screen_load_anim_t` the screen load animation + * @param duration duration of the animation in milliseconds + * @param delay delay before the screen load in milliseconds + */ +void lv_obj_add_screen_create_event(lv_obj_t * obj, lv_event_code_t trigger, lv_screen_create_cb_t screen_create_cb, + lv_screen_load_anim_t anim_type, uint32_t duration, uint32_t delay); + + +/** + * Play a timeline animation on a trigger + * @param obj pointer to widget which should trigger playing the animation + * @param trigger an event code, e.g. `LV_EVENT_CLICKED` + * @param at pointer to an animation timeline + * @param delay wait time before starting the animation + * @param reverse true: play in reverse + */ +void lv_obj_add_play_timeline_event(lv_obj_t * obj, lv_event_code_t trigger, lv_anim_timeline_t * at, uint32_t delay, + bool reverse); + #if LV_USE_OBJ_ID /** * Set an id for an object. diff --git a/src/core/lv_obj_draw.c b/src/core/lv_obj_draw.c index 56fa3f95ea..03f10aad4e 100644 --- a/src/core/lv_obj_draw.c +++ b/src/core/lv_obj_draw.c @@ -132,6 +132,8 @@ void lv_obj_init_draw_rect_dsc(lv_obj_t * obj, lv_part_t part, lv_draw_rect_dsc_ draw_dsc->bg_image_recolor = lv_color_make(result.red, result.green, result.blue); draw_dsc->bg_image_tiled = lv_obj_get_style_bg_image_tiled(obj, part); } + + draw_dsc->bg_image_colorkey = lv_obj_get_style_image_colorkey(obj, part); } } } @@ -234,6 +236,8 @@ void lv_obj_init_draw_image_dsc(lv_obj_t * obj, lv_part_t part, lv_draw_image_ds draw_dsc->recolor_opa = result.alpha; draw_dsc->recolor = lv_color_make(result.red, result.green, result.blue); + draw_dsc->colorkey = lv_obj_get_style_image_colorkey(obj, part); + if(part != LV_PART_MAIN) draw_dsc->blend_mode = lv_obj_get_style_blend_mode(obj, part); LV_PROFILER_DRAW_END; diff --git a/src/core/lv_obj_draw.h b/src/core/lv_obj_draw.h index 9df48c5eb7..4ad447c970 100644 --- a/src/core/lv_obj_draw.h +++ b/src/core/lv_obj_draw.h @@ -20,6 +20,7 @@ extern "C" { #include "../draw/lv_draw_line.h" #include "../draw/lv_draw_arc.h" #include "../draw/lv_draw_triangle.h" +#include "lv_obj_style.h" /********************* * DEFINES @@ -36,7 +37,7 @@ typedef enum { /**Simple layer means that the layer can be rendered in chunks. * For example with opa_layered = 140 it's possible to render only 10 lines - * from the layer. When it's ready go the the next 10 lines. + * from the layer. When it's ready go to the next 10 lines. * It avoids large memory allocations for the layer buffer. * The buffer size for a chunk can be set by `LV_DRAW_LAYER_SIMPLE_BUF_SIZE` in lv_conf.h.*/ LV_LAYER_TYPE_SIMPLE, diff --git a/src/core/lv_obj_event.c b/src/core/lv_obj_event.c index 05e01525e0..36fb7e1f78 100644 --- a/src/core/lv_obj_event.c +++ b/src/core/lv_obj_event.c @@ -27,6 +27,7 @@ **********************/ static lv_result_t event_send_core(lv_event_t * e); static bool event_is_bubbled(lv_event_t * e); +static bool event_is_trickled(lv_event_t * e); /********************** * STATIC VARIABLES @@ -60,6 +61,7 @@ lv_result_t lv_obj_send_event(lv_obj_t * obj, lv_event_code_t event_code, void * e.deleted = 0; e.stop_bubbling = 0; e.stop_processing = 0; + e.stop_trickling = 0; lv_event_push(&e); @@ -140,8 +142,11 @@ uint32_t lv_obj_remove_event_cb(lv_obj_t * obj, lv_event_cb_t event_cb) uint32_t event_cnt = lv_obj_get_event_count(obj); uint32_t removed_count = 0; - uint32_t i; - for(i = 0; i < event_cnt; i++) { + int32_t i; + + if(event_cnt == 0) return 0; + + for(i = event_cnt - 1; i >= 0; i--) { lv_event_dsc_t * dsc = lv_obj_get_event_dsc(obj, i); if(dsc && dsc->cb == event_cb) { lv_obj_remove_event(obj, i); @@ -352,7 +357,6 @@ static lv_result_t event_send_core(lv_event_t * e) { LV_TRACE_EVENT("Sending event %d to %p with %p param", e->code, (void *)e->original_target, e->param); - /*Call the input device's feedback callback if set*/ lv_indev_t * indev_act = lv_indev_active(); if(indev_act) { if(e->stop_processing) return LV_RESULT_OK; @@ -377,6 +381,27 @@ static lv_result_t event_send_core(lv_event_t * e) e->current_target = parent; res = event_send_core(e); } + if(res != LV_RESULT_OK) return res; + + /*Trickle down to children if enabled*/ + if(event_is_trickled(e)) { + uint32_t child_count = lv_obj_get_child_count(target); + + /* we don't want the event to bubble up again when trickling down */ + e->stop_bubbling = 1; + + for(uint32_t i = 0; i < child_count && res == LV_RESULT_OK && !e->stop_processing; i++) { + lv_obj_t * child = lv_obj_get_child(target, i); + if(child) { + e->current_target = child; + res = event_send_core(e); + if(res != LV_RESULT_OK) { + LV_LOG_WARN("Trickle down event %d to child %p failed", e->code, (void *)child); + break; + } + } + } + } return res; } @@ -421,3 +446,35 @@ static bool event_is_bubbled(lv_event_t * e) return true; } } + +static bool event_is_trickled(lv_event_t * e) +{ + if(e->stop_trickling) return false; + + /*Check other codes only if trickle is enabled*/ + if(lv_obj_has_flag(e->current_target, LV_OBJ_FLAG_EVENT_TRICKLE) == false) return false; + + switch(e->code) { + case LV_EVENT_HIT_TEST: + case LV_EVENT_COVER_CHECK: + case LV_EVENT_REFR_EXT_DRAW_SIZE: + case LV_EVENT_DRAW_MAIN_BEGIN: + case LV_EVENT_DRAW_MAIN: + case LV_EVENT_DRAW_MAIN_END: + case LV_EVENT_DRAW_POST_BEGIN: + case LV_EVENT_DRAW_POST: + case LV_EVENT_DRAW_POST_END: + case LV_EVENT_DRAW_TASK_ADDED: + case LV_EVENT_REFRESH: + case LV_EVENT_DELETE: + case LV_EVENT_CHILD_CREATED: + case LV_EVENT_CHILD_DELETED: + case LV_EVENT_CHILD_CHANGED: + case LV_EVENT_SIZE_CHANGED: + case LV_EVENT_STYLE_CHANGED: + case LV_EVENT_GET_SELF_SIZE: + return false; + default: + return true; + } +} diff --git a/src/core/lv_obj_id_builtin.c b/src/core/lv_obj_id_builtin.c index ed8f745ffa..f717760f38 100644 --- a/src/core/lv_obj_id_builtin.c +++ b/src/core/lv_obj_id_builtin.c @@ -1,5 +1,5 @@ /** - * @file lv_obj_id.c + * @file lv_obj_id_builtin.c * */ @@ -9,7 +9,7 @@ #include "lv_obj_class_private.h" #include "lv_obj_private.h" #include "lv_global.h" -#include "../osal/lv_os.h" +#include "../osal/lv_os_private.h" #include "../stdlib/lv_sprintf.h" /********************* diff --git a/src/core/lv_obj_pos.c b/src/core/lv_obj_pos.c index 708e3f4c61..a88ace3979 100644 --- a/src/core/lv_obj_pos.c +++ b/src/core/lv_obj_pos.c @@ -84,6 +84,56 @@ void lv_obj_set_y(lv_obj_t * obj, int32_t y) } } +static int32_t calc_dynamic_width(lv_obj_t * obj, int32_t width, int32_t * const content_width) +{ + if(width == LV_SIZE_CONTENT) { + if(*content_width < 0) { + *content_width = calc_content_width(obj); + } + width = *content_width; + } + else if(LV_COORD_IS_PCT(width)) { + lv_obj_t * parent = lv_obj_get_parent(obj); + if(parent->w_layout == 0 && lv_obj_get_style_width(parent, 0) == LV_SIZE_CONTENT) { + /*If parent has content size and the child has pct size + *a circular dependency will occur. To solve it keep child size at zero */ + width = lv_obj_get_style_space_left(obj, 0) + lv_obj_get_style_space_right(obj, 0); + } + else { + int32_t parent_w = lv_obj_get_content_width(parent); + width = (LV_COORD_GET_PCT(width) * parent_w) / 100; + width -= lv_obj_get_style_margin_left(obj, LV_PART_MAIN) + lv_obj_get_style_margin_right(obj, LV_PART_MAIN); + } + } + return width; +} + +static int32_t calc_dynamic_height(lv_obj_t * obj, int32_t height, int32_t * const content_height) +{ + if(height == LV_SIZE_CONTENT) { + if(*content_height < 0) { + *content_height = calc_content_height(obj); + } + height = *content_height; + } + else if(LV_COORD_IS_PCT(height)) { + lv_obj_t * parent = lv_obj_get_parent(obj); + if(parent->h_layout == 0 && lv_obj_get_style_height(parent, 0) == LV_SIZE_CONTENT) { + /*If parent has content size and the child has pct size + *a circular dependency will occur. To solve it keep child size at zero */ + height = lv_obj_get_style_space_top(obj, 0) + lv_obj_get_style_space_bottom(obj, 0); + } + + else { + int32_t parent_h = lv_obj_get_content_height(parent); + height = (LV_COORD_GET_PCT(height) * parent_h) / 100; + height -= + lv_obj_get_style_margin_top(obj, LV_PART_MAIN) + lv_obj_get_style_margin_bottom(obj, LV_PART_MAIN); + } + } + return height; +} + bool lv_obj_refr_size(lv_obj_t * obj) { LV_ASSERT_OBJ(obj, MY_CLASS); @@ -94,74 +144,34 @@ bool lv_obj_refr_size(lv_obj_t * obj) lv_obj_t * parent = lv_obj_get_parent(obj); if(parent == NULL) return false; - bool w_is_content = false; - bool w_is_pct = false; - int32_t w; if(obj->w_layout) { w = lv_obj_get_width(obj); } else { - w = lv_obj_get_style_width(obj, LV_PART_MAIN); - w_is_content = w == LV_SIZE_CONTENT; - w_is_pct = LV_COORD_IS_PCT(w); - int32_t parent_w = lv_obj_get_content_width(parent); - - if(w_is_content) { - w = calc_content_width(obj); - } - else if(w_is_pct) { - /*If parent has content size and the child has pct size - *a circular dependency will occur. To solve it keep child size at zero */ - if(parent->w_layout == 0 && lv_obj_get_style_width(parent, 0) == LV_SIZE_CONTENT) { - w = lv_obj_get_style_space_left(obj, 0) + lv_obj_get_style_space_right(obj, 0); - } - else { - w = (LV_COORD_GET_PCT(w) * parent_w) / 100; - w -= lv_obj_get_style_margin_left(obj, LV_PART_MAIN) + lv_obj_get_style_margin_right(obj, LV_PART_MAIN); - } - } - - int32_t minw = lv_obj_get_style_min_width(obj, LV_PART_MAIN); - int32_t maxw = lv_obj_get_style_max_width(obj, LV_PART_MAIN); - w = lv_clamp_width(w, minw, maxw, parent_w); + int32_t content_width = -1; + w = calc_dynamic_width(obj, lv_obj_get_style_width(obj, LV_PART_MAIN), &content_width); + int32_t minw = calc_dynamic_width(obj, lv_obj_get_style_min_width(obj, LV_PART_MAIN), &content_width); + int32_t maxw = calc_dynamic_width(obj, lv_obj_get_style_max_width(obj, LV_PART_MAIN), &content_width); + w = LV_CLAMP(minw, w, maxw); } int32_t h; - bool h_is_content = false; - bool h_is_pct = false; if(obj->h_layout) { h = lv_obj_get_height(obj); } else { - h = lv_obj_get_style_height(obj, LV_PART_MAIN); - h_is_content = h == LV_SIZE_CONTENT; - h_is_pct = LV_COORD_IS_PCT(h); - int32_t parent_h = lv_obj_get_content_height(parent); - - if(h_is_content) { - h = calc_content_height(obj); - } - else if(h_is_pct) { - /*If parent has content size and the child has pct size - *a circular dependency will occur. To solve it keep child size at zero */ - if(parent->h_layout == 0 && lv_obj_get_style_height(parent, 0) == LV_SIZE_CONTENT) { - h = lv_obj_get_style_space_top(obj, 0) + lv_obj_get_style_space_bottom(obj, 0); - } - else { - h = (LV_COORD_GET_PCT(h) * parent_h) / 100; - h -= lv_obj_get_style_margin_top(obj, LV_PART_MAIN) + lv_obj_get_style_margin_bottom(obj, LV_PART_MAIN); - } - } - - int32_t minh = lv_obj_get_style_min_height(obj, LV_PART_MAIN); - int32_t maxh = lv_obj_get_style_max_height(obj, LV_PART_MAIN); - h = lv_clamp_height(h, minh, maxh, parent_h); + int32_t content_height = -1; + h = calc_dynamic_height(obj, lv_obj_get_style_height(obj, LV_PART_MAIN), &content_height); + int32_t minh = calc_dynamic_height(obj, lv_obj_get_style_min_height(obj, LV_PART_MAIN), &content_height); + int32_t maxh = calc_dynamic_height(obj, lv_obj_get_style_max_height(obj, LV_PART_MAIN), &content_height); + h = LV_CLAMP(minh, h, maxh); } /*Do nothing if the size is not changed*/ /*It is very important else recursive resizing can occur without size change*/ - if(lv_obj_get_width(obj) == w && lv_obj_get_height(obj) == h) return false; + if(lv_obj_get_width(obj) == w && lv_obj_get_height(obj) == h) + return false; /*Invalidate the original area*/ lv_obj_invalidate(obj); @@ -177,7 +187,8 @@ bool lv_obj_refr_size(lv_obj_t * obj) /*If the object is already out of the parent and its position is changes *surely the scrollbars also changes so invalidate them*/ bool on1 = lv_area_is_in(&ori, &parent_fit_area, 0); - if(!on1) lv_obj_scrollbar_invalidate(parent); + if(!on1) + lv_obj_scrollbar_invalidate(parent); /*Set the length and height *Be sure the content is not scrolled in an invalid position on the new size*/ @@ -203,7 +214,8 @@ bool lv_obj_refr_size(lv_obj_t * obj) /*If the object was out of the parent invalidate the new scrollbar area too. *If it wasn't out of the parent but out now, also invalidate the scrollbars*/ bool on2 = lv_area_is_in(&obj->coords, &parent_fit_area, 0); - if(on1 || (!on1 && on2)) lv_obj_scrollbar_invalidate(parent); + if(on1 || (!on1 && on2)) + lv_obj_scrollbar_invalidate(parent); lv_obj_refresh_ext_draw_size(obj); @@ -627,12 +639,12 @@ void lv_obj_refr_pos(lv_obj_t * obj) int32_t pw = lv_obj_get_content_width(parent); int32_t ph = lv_obj_get_content_height(parent); if(LV_COORD_IS_PCT(x)) { - if(lv_obj_get_style_width(parent, 0) == LV_SIZE_CONTENT) x = 0; /*Avoid circular dependency*/ + if(lv_obj_get_style_width(parent, LV_PART_MAIN) == LV_SIZE_CONTENT) x = 0; /*Avoid circular dependency*/ else x = (pw * LV_COORD_GET_PCT(x)) / 100; } if(LV_COORD_IS_PCT(y)) { - if(lv_obj_get_style_height(parent, 0) == LV_SIZE_CONTENT) y = 0; /*Avoid circular dependency*/ + if(lv_obj_get_style_height(parent, LV_PART_MAIN) == LV_SIZE_CONTENT) y = 0; /*Avoid circular dependency*/ y = (ph * LV_COORD_GET_PCT(y)) / 100; } @@ -997,7 +1009,7 @@ void lv_obj_set_transform(lv_obj_t * obj, const lv_matrix_t * matrix) lv_obj_allocate_spec_attr(obj); if(!obj->spec_attr->matrix) { - obj->spec_attr->matrix = lv_malloc(sizeof(lv_matrix_t));; + obj->spec_attr->matrix = lv_malloc(sizeof(lv_matrix_t)); LV_ASSERT_MALLOC(obj->spec_attr->matrix); } @@ -1096,7 +1108,7 @@ static int32_t calc_content_width(lv_obj_t * obj) if(lv_obj_has_flag_any(child, LV_OBJ_FLAG_HIDDEN | LV_OBJ_FLAG_FLOATING)) continue; if(!lv_obj_is_layout_positioned(child)) { - lv_align_t align = lv_obj_get_style_align(child, 0); + lv_align_t align = lv_obj_get_style_align(child, LV_PART_MAIN); switch(align) { case LV_ALIGN_DEFAULT: case LV_ALIGN_TOP_RIGHT: @@ -1108,7 +1120,7 @@ static int32_t calc_content_width(lv_obj_t * obj) default: /* Consider other cases only if x=0 and use the width of the object. * With x!=0 circular dependency could occur. */ - if(lv_obj_get_style_x(child, 0) == 0) { + if(lv_obj_get_style_x(child, LV_PART_MAIN) == 0) { child_res_tmp = lv_area_get_width(&child->coords) + space_right; child_res_tmp += lv_obj_get_style_margin_left(child, LV_PART_MAIN); } @@ -1132,7 +1144,7 @@ static int32_t calc_content_width(lv_obj_t * obj) if(lv_obj_has_flag_any(child, LV_OBJ_FLAG_HIDDEN | LV_OBJ_FLAG_FLOATING)) continue; if(!lv_obj_is_layout_positioned(child)) { - lv_align_t align = lv_obj_get_style_align(child, 0); + lv_align_t align = lv_obj_get_style_align(child, LV_PART_MAIN); switch(align) { case LV_ALIGN_DEFAULT: case LV_ALIGN_TOP_LEFT: @@ -1144,7 +1156,7 @@ static int32_t calc_content_width(lv_obj_t * obj) default: /* Consider other cases only if x=0 and use the width of the object. * With x!=0 circular dependency could occur. */ - if(lv_obj_get_style_x(child, 0) == 0) { + if(lv_obj_get_style_x(child, LV_PART_MAIN) == 0) { child_res_tmp = lv_area_get_width(&child->coords) + space_left; child_res_tmp += lv_obj_get_style_margin_right(child, LV_PART_MAIN); } @@ -1189,7 +1201,7 @@ static int32_t calc_content_height(lv_obj_t * obj) if(lv_obj_has_flag_any(child, LV_OBJ_FLAG_HIDDEN | LV_OBJ_FLAG_FLOATING)) continue; if(!lv_obj_is_layout_positioned(child)) { - lv_align_t align = lv_obj_get_style_align(child, 0); + lv_align_t align = lv_obj_get_style_align(child, LV_PART_MAIN); switch(align) { case LV_ALIGN_DEFAULT: case LV_ALIGN_TOP_RIGHT: @@ -1201,7 +1213,7 @@ static int32_t calc_content_height(lv_obj_t * obj) default: /* Consider other cases only if y=0 and use the height of the object. * With y!=0 circular dependency could occur. */ - if(lv_obj_get_style_y(child, 0) == 0) { + if(lv_obj_get_style_y(child, LV_PART_MAIN) == 0) { child_res_tmp = lv_area_get_height(&child->coords) + space_top; child_res_tmp += lv_obj_get_style_margin_top(child, LV_PART_MAIN); } @@ -1273,17 +1285,17 @@ static void transform_point_array(const lv_obj_t * obj, lv_point_t * p, size_t p } #endif /* LV_DRAW_TRANSFORM_USE_MATRIX */ - int32_t angle = lv_obj_get_style_transform_rotation(obj, 0); - int32_t scale_x = lv_obj_get_style_transform_scale_x_safe(obj, 0); - int32_t scale_y = lv_obj_get_style_transform_scale_y_safe(obj, 0); + int32_t angle = lv_obj_get_style_transform_rotation(obj, LV_PART_MAIN); + int32_t scale_x = lv_obj_get_style_transform_scale_x_safe(obj, LV_PART_MAIN); + int32_t scale_y = lv_obj_get_style_transform_scale_y_safe(obj, LV_PART_MAIN); if(scale_x == 0) scale_x = 1; if(scale_y == 0) scale_y = 1; if(angle == 0 && scale_x == LV_SCALE_NONE && scale_y == LV_SCALE_NONE) return; lv_point_t pivot = { - .x = lv_obj_get_style_transform_pivot_x(obj, 0), - .y = lv_obj_get_style_transform_pivot_y(obj, 0) + .x = lv_obj_get_style_transform_pivot_x(obj, LV_PART_MAIN), + .y = lv_obj_get_style_transform_pivot_y(obj, LV_PART_MAIN) }; if(LV_COORD_IS_PCT(pivot.x)) { diff --git a/src/core/lv_obj_private.h b/src/core/lv_obj_private.h index 5b1100fb85..1a6540bf28 100644 --- a/src/core/lv_obj_private.h +++ b/src/core/lv_obj_private.h @@ -67,7 +67,7 @@ struct _lv_obj_t { #endif lv_area_t coords; lv_obj_flag_t flags; - lv_state_t state; + uint16_t state; uint16_t layout_inv : 1; uint16_t readjust_scroll_after_layout : 1; uint16_t scr_layout_inv : 1; @@ -78,7 +78,6 @@ struct _lv_obj_t { uint16_t is_deleting : 1; }; - /********************** * GLOBAL PROTOTYPES **********************/ diff --git a/src/core/lv_obj_property.c b/src/core/lv_obj_property.c index 7f45e6c7ff..60b0844013 100644 --- a/src/core/lv_obj_property.c +++ b/src/core/lv_obj_property.c @@ -1,5 +1,5 @@ /** - * @file lv_obj_id.c + * @file lv_obj_property.c * */ diff --git a/src/core/lv_obj_property.h b/src/core/lv_obj_property.h index 5cd16aa2df..35f55f1125 100644 --- a/src/core/lv_obj_property.h +++ b/src/core/lv_obj_property.h @@ -38,7 +38,19 @@ extern "C" { #define LV_PROPERTY_TYPE_SHIFT 28 #define LV_PROPERTY_TYPE2_SHIFT 24 -#define LV_PROPERTY_ID(clz, name, type, index) LV_PROPERTY_## clz ##_##name = (LV_PROPERTY_## clz ##_START + (index)) | ((type) << LV_PROPERTY_TYPE_SHIFT) + +/* Example: + * LV_PROPERTY_ID(OBJ, FLAG_CLICKABLE, LV_PROPERTY_TYPE_INT, 1), + * produces + * LV_PROPERTY_OBJ_FLAG_CLICKABLE = (LV_PROPERTY_OBJ_START + (1)) | ((LV_PROPERTY_TYPE_INT) << LV_PROPERTY_TYPE_SHIFT) + */ +#define LV_PROPERTY_ID(clz, name, type, index) LV_PROPERTY_## clz ##_##name = (LV_PROPERTY_## clz ##_START + ((int)index)) | ((type) << LV_PROPERTY_TYPE_SHIFT) + +/* Example: + * LV_PROPERTY_ID2(SLIDER, VALUE, LV_PROPERTY_TYPE_INT, LV_PROPERTY_TYPE_BOOL, 0) + * produces + * LV_PROPERTY_SLIDER_VALUE = (LV_PROPERTY_SLIDER_START + (0)) | ((LV_PROPERTY_TYPE_INT) << LV_PROPERTY_TYPE_SHIFT) | ((LV_PROPERTY_TYPE_BOOL) << LV_PROPERTY_TYPE2_SHIFT) + */ #define LV_PROPERTY_ID2(clz, name, type, type2, index) LV_PROPERTY_ID(clz, name, type, index) | ((type2) << LV_PROPERTY_TYPE2_SHIFT) #define LV_PROPERTY_ID_TYPE(id) ((id) >> LV_PROPERTY_TYPE_SHIFT) @@ -56,7 +68,7 @@ extern "C" { /** * Group of predefined widget ID start value. */ -enum { +enum _lv_prop_id_range_boundary_t { LV_PROPERTY_ID_INVALID = 0, /*ID 0x01 to 0xff are style ID, check lv_style_prop_t*/ diff --git a/src/core/lv_obj_style.c b/src/core/lv_obj_style.c index afffffa151..91cb91e8ee 100644 --- a/src/core/lv_obj_style.c +++ b/src/core/lv_obj_style.c @@ -36,14 +36,6 @@ typedef struct { lv_style_value_t end_value; } trans_t; -typedef enum { - CACHE_ZERO = 0, - CACHE_TRUE = 1, - CACHE_UNSET = 2, - CACHE_255 = 3, - CACHE_NEED_CHECK = 4, -} cache_t; - /********************** * GLOBAL PROTOTYPES **********************/ @@ -52,7 +44,7 @@ typedef enum { * STATIC PROTOTYPES **********************/ static lv_style_t * get_local_style(lv_obj_t * obj, lv_style_selector_t selector); -static lv_obj_style_t * get_trans_style(lv_obj_t * obj, lv_part_t part); +static lv_obj_style_t * get_trans_style(lv_obj_t * obj, lv_style_selector_t selector); static lv_style_res_t get_prop_core(const lv_obj_t * obj, lv_style_selector_t selector, lv_style_prop_t prop, lv_style_value_t * v); static void report_style_change_core(void * style, lv_obj_t * obj); @@ -272,7 +264,7 @@ void lv_obj_report_style_change(lv_style_t * style) } } -void lv_obj_refresh_style(lv_obj_t * obj, lv_style_selector_t selector, lv_style_prop_t prop) +void lv_obj_refresh_style(lv_obj_t * obj, lv_part_t part, lv_style_prop_t prop) { LV_ASSERT_OBJ(obj, MY_CLASS); @@ -282,8 +274,6 @@ void lv_obj_refresh_style(lv_obj_t * obj, lv_style_selector_t selector, lv_style lv_obj_invalidate(obj); - lv_part_t part = lv_obj_style_get_selector_part(selector); - bool is_layout_refr = lv_style_prop_has_flag(prop, LV_STYLE_PROP_FLAG_LAYOUT_UPDATE); bool is_ext_draw = lv_style_prop_has_flag(prop, LV_STYLE_PROP_FLAG_EXT_DRAW_UPDATE); bool is_inheritable = lv_style_prop_has_flag(prop, LV_STYLE_PROP_FLAG_INHERITABLE); @@ -292,8 +282,8 @@ void lv_obj_refresh_style(lv_obj_t * obj, lv_style_selector_t selector, lv_style if(is_layout_refr) { if(part == LV_PART_ANY || part == LV_PART_MAIN || - lv_obj_get_style_height(obj, 0) == LV_SIZE_CONTENT || - lv_obj_get_style_width(obj, 0) == LV_SIZE_CONTENT) { + lv_obj_get_style_height(obj, LV_PART_MAIN) == LV_SIZE_CONTENT || + lv_obj_get_style_width(obj, LV_PART_MAIN) == LV_SIZE_CONTENT) { lv_obj_send_event(obj, LV_EVENT_STYLE_CHANGED, NULL); lv_obj_mark_layout_as_dirty(obj); } @@ -322,6 +312,37 @@ void lv_obj_refresh_style(lv_obj_t * obj, lv_style_selector_t selector, lv_style LV_PROFILER_STYLE_END; } +void lv_obj_style_set_disabled(lv_obj_t * obj, const lv_style_t * style, lv_style_selector_t selector, bool dis) +{ + uint32_t i; + for(i = 0; i < obj->style_cnt; i++) { + if(obj->styles[i].style == style && obj->styles[i].selector == selector) { + if(dis == obj->styles[i].is_disabled) { + return; /*Already in the right state*/ + } + obj->styles[i].is_disabled = dis; + full_cache_refresh(obj, lv_obj_style_get_selector_part(selector)); + lv_obj_refresh_style(obj, selector, LV_STYLE_PROP_ANY); + return; + } + } + LV_LOG_WARN("%p style was not found on %p widget with %6" LV_PRIx32 " selector", (void *)style, (void *)obj, selector); +} + +bool lv_obj_style_get_disabled(lv_obj_t * obj, const lv_style_t * style, lv_style_selector_t selector) +{ + uint32_t i; + for(i = 0; i < obj->style_cnt; i++) { + if(obj->styles[i].style == style && obj->styles[i].selector == selector) { + return obj->styles[i].is_disabled; + } + } + + LV_LOG_WARN("%p style was not found on %p widget with %6" LV_PRIx32 " selector", (void *)style, (void *)obj, selector); + return false; +} + + void lv_obj_enable_style_refresh(bool en) { style_refr = en; @@ -573,7 +594,7 @@ void lv_obj_fade_out(lv_obj_t * obj, uint32_t time, uint32_t delay) lv_anim_t a; lv_anim_init(&a); lv_anim_set_var(&a, obj); - lv_anim_set_values(&a, lv_obj_get_style_opa(obj, 0), LV_OPA_TRANSP); + lv_anim_set_values(&a, lv_obj_get_style_opa(obj, LV_PART_MAIN), LV_OPA_TRANSP); lv_anim_set_exec_cb(&a, fade_anim_cb); lv_anim_set_duration(&a, time); lv_anim_set_delay(&a, delay); @@ -773,6 +794,7 @@ static lv_style_res_t get_prop_core(const lv_obj_t * obj, lv_style_selector_t se lv_obj_style_t * obj_style = &obj->styles[i]; if(obj_style->is_trans == false) break; if(skip_trans) continue; + if(obj_style->is_disabled) continue; lv_part_t part_act = lv_obj_style_get_selector_part(obj->styles[i].selector); @@ -786,6 +808,7 @@ static lv_style_res_t get_prop_core(const lv_obj_t * obj, lv_style_selector_t se for(; i < obj->style_cnt; i++) { if((obj->styles[i].style->has_group & group) == 0) continue; + if(obj->styles[i].is_disabled) continue; lv_obj_style_t * obj_style = &obj->styles[i]; lv_part_t part_act = lv_obj_style_get_selector_part(obj->styles[i].selector); if(part_act != part) continue; @@ -796,7 +819,7 @@ static lv_style_res_t get_prop_core(const lv_obj_t * obj, lv_style_selector_t se if((state_act & state_inv)) continue; /*Check only better candidates*/ - if(state_act <= weight) continue; + if((int32_t)state_act <= weight) continue; found = lv_style_get_prop_inlined(obj_style->style, prop, v); if(found == LV_STYLE_RES_FOUND) { @@ -1026,14 +1049,14 @@ static lv_layer_type_t calculate_layer_type(lv_obj_t * obj) #if LV_DRAW_TRANSFORM_USE_MATRIX if(lv_obj_get_transform(obj) != NULL) return LV_LAYER_TYPE_TRANSFORM; #endif - if(lv_obj_get_style_transform_rotation(obj, 0) != 0) return LV_LAYER_TYPE_TRANSFORM; - if(lv_obj_get_style_transform_scale_x(obj, 0) != 256) return LV_LAYER_TYPE_TRANSFORM; - if(lv_obj_get_style_transform_scale_y(obj, 0) != 256) return LV_LAYER_TYPE_TRANSFORM; - if(lv_obj_get_style_transform_skew_x(obj, 0) != 0) return LV_LAYER_TYPE_TRANSFORM; - if(lv_obj_get_style_transform_skew_y(obj, 0) != 0) return LV_LAYER_TYPE_TRANSFORM; - if(lv_obj_get_style_opa_layered(obj, 0) != LV_OPA_COVER) return LV_LAYER_TYPE_SIMPLE; - if(lv_obj_get_style_bitmap_mask_src(obj, 0) != NULL) return LV_LAYER_TYPE_SIMPLE; - if(lv_obj_get_style_blend_mode(obj, 0) != LV_BLEND_MODE_NORMAL) return LV_LAYER_TYPE_SIMPLE; + if(lv_obj_get_style_transform_rotation(obj, LV_PART_MAIN) != 0) return LV_LAYER_TYPE_TRANSFORM; + if(lv_obj_get_style_transform_scale_x(obj, LV_PART_MAIN) != 256) return LV_LAYER_TYPE_TRANSFORM; + if(lv_obj_get_style_transform_scale_y(obj, LV_PART_MAIN) != 256) return LV_LAYER_TYPE_TRANSFORM; + if(lv_obj_get_style_transform_skew_x(obj, LV_PART_MAIN) != 0) return LV_LAYER_TYPE_TRANSFORM; + if(lv_obj_get_style_transform_skew_y(obj, LV_PART_MAIN) != 0) return LV_LAYER_TYPE_TRANSFORM; + if(lv_obj_get_style_opa_layered(obj, LV_PART_MAIN) != LV_OPA_COVER) return LV_LAYER_TYPE_SIMPLE; + if(lv_obj_get_style_bitmap_mask_src(obj, LV_PART_MAIN) != NULL) return LV_LAYER_TYPE_SIMPLE; + if(lv_obj_get_style_blend_mode(obj, LV_PART_MAIN) != LV_BLEND_MODE_NORMAL) return LV_LAYER_TYPE_SIMPLE; return LV_LAYER_TYPE_NONE; } @@ -1045,6 +1068,7 @@ static void full_cache_refresh(lv_obj_t * obj, lv_part_t part) obj->style_main_prop_is_set = 0; for(i = 0; i < obj->style_cnt; i++) { if(lv_obj_style_get_selector_part(obj->styles[i].selector) != LV_PART_MAIN) continue; + if(obj->styles[i].is_disabled) continue; lv_style_t * style = (lv_style_t *)obj->styles[i].style; uint32_t j; if(lv_style_is_const(style)) { @@ -1065,6 +1089,8 @@ static void full_cache_refresh(lv_obj_t * obj, lv_part_t part) obj->style_other_prop_is_set = 0; for(i = 0; i < obj->style_cnt; i++) { if(lv_obj_style_get_selector_part(obj->styles[i].selector) == LV_PART_MAIN) continue; + if(obj->styles[i].is_disabled) continue; + lv_style_t * style = (lv_style_t *)obj->styles[i].style; uint32_t j; if(lv_style_is_const(style)) { diff --git a/src/core/lv_obj_style.h b/src/core/lv_obj_style.h index f94a63a49a..a5306d2440 100644 --- a/src/core/lv_obj_style.h +++ b/src/core/lv_obj_style.h @@ -25,6 +25,49 @@ extern "C" { * TYPEDEFS **********************/ +/** + * Possible states of a widget. + * OR-ed values are possible + */ +typedef enum { + LV_STATE_DEFAULT = 0x0000, + LV_STATE_CHECKED = 0x0001, + LV_STATE_FOCUSED = 0x0002, + LV_STATE_FOCUS_KEY = 0x0004, + LV_STATE_EDITED = 0x0008, + LV_STATE_HOVERED = 0x0010, + LV_STATE_PRESSED = 0x0020, + LV_STATE_SCROLLED = 0x0040, + LV_STATE_DISABLED = 0x0080, + LV_STATE_USER_1 = 0x1000, + LV_STATE_USER_2 = 0x2000, + LV_STATE_USER_3 = 0x4000, + LV_STATE_USER_4 = 0x8000, + + LV_STATE_ANY = 0xFFFF, /**< Special value can be used in some functions to target all states*/ +} lv_state_t; + +/** + * The possible parts of widgets. + * The parts can be considered as the internal building block of the widgets. + * E.g. slider = background + indicator + knob + * Not all parts are used by every widget + */ + +typedef enum { + LV_PART_MAIN = 0x000000, /**< A background like rectangle*/ + LV_PART_SCROLLBAR = 0x010000, /**< The scrollbar(s)*/ + LV_PART_INDICATOR = 0x020000, /**< Indicator, e.g. for slider, bar, switch, or the tick box of the checkbox*/ + LV_PART_KNOB = 0x030000, /**< Like handle to grab to adjust the value*/ + LV_PART_SELECTED = 0x040000, /**< Indicate the currently selected option or section*/ + LV_PART_ITEMS = 0x050000, /**< Used if the widget has multiple similar elements (e.g. table cells)*/ + LV_PART_CURSOR = 0x060000, /**< Mark a specific place e.g. for text area's cursor or on a chart*/ + + LV_PART_CUSTOM_FIRST = 0x080000, /**< Extension point for custom widgets*/ + + LV_PART_ANY = 0x0F0000, /**< Special value can be used in some functions to target all parts*/ +} lv_part_t; + typedef enum { LV_STYLE_STATE_CMP_SAME, /**< The style properties in the 2 states are identical */ LV_STYLE_STATE_CMP_DIFF_REDRAW, /**< The differences can be shown with a simple redraw */ @@ -32,6 +75,13 @@ typedef enum { LV_STYLE_STATE_CMP_DIFF_LAYOUT, /**< The differences can be shown with a simple redraw */ } lv_style_state_cmp_t; +/** + * A joint type for `lv_part_t` and `lv_state_t`. Example values + * - `0`: means `LV_PART_MAIN | LV_STATE_DEFAULT` + * - `LV_STATE_PRSSED` + * - `LV_PART_KNOB` + * - `LV_PART_KNOB | LV_STATE_PRESSED | LV_STATE_CHECKED` + */ typedef uint32_t lv_style_selector_t; /********************** @@ -110,6 +160,24 @@ void lv_obj_report_style_change(lv_style_t * style); */ void lv_obj_refresh_style(lv_obj_t * obj, lv_part_t part, lv_style_prop_t prop); +/** + * Temporary disable a style for a selector. It will look like is the style wasn't added + * @param obj pointer to an object + * @param style pointer to a style + * @param selector the selector of a style (e.g. LV_STATE_PRESSED | LV_PART_KNOB) + * @param dis true: disable the style, false: enable the style + */ +void lv_obj_style_set_disabled(lv_obj_t * obj, const lv_style_t * style, lv_style_selector_t selector, bool dis); + +/** + * Get if a given style is disabled on an object. + * @param obj pointer to an object + * @param style pointer to a style + * @param selector the selector of a style (e.g. LV_STATE_PRESSED | LV_PART_KNOB) + * @return true: disable the style, false: enable the style + */ +bool lv_obj_style_get_disabled(lv_obj_t * obj, const lv_style_t * style, lv_style_selector_t selector); + /** * Enable or disable automatic style refreshing when a new style is added/removed to/from an object * or any other style change happens. @@ -183,12 +251,12 @@ void lv_obj_fade_out(lv_obj_t * obj, uint32_t time, uint32_t delay); static inline lv_state_t lv_obj_style_get_selector_state(lv_style_selector_t selector) { - return selector & 0xFFFF; + return (lv_state_t)(selector & 0xFFFF); } static inline lv_part_t lv_obj_style_get_selector_part(lv_style_selector_t selector) { - return selector & 0xFF0000; + return (lv_part_t)(selector & 0xFF0000); } #include "lv_obj_style_gen.h" diff --git a/src/core/lv_obj_style_gen.c b/src/core/lv_obj_style_gen.c index 8910d9a0e3..4b73f5c721 100644 --- a/src/core/lv_obj_style_gen.c +++ b/src/core/lv_obj_style_gen.c @@ -530,6 +530,14 @@ void lv_obj_set_style_image_recolor_opa(lv_obj_t * obj, lv_opa_t value, lv_style lv_obj_set_local_style_prop(obj, LV_STYLE_IMAGE_RECOLOR_OPA, v, selector); } +void lv_obj_set_style_image_colorkey(lv_obj_t * obj, const lv_image_colorkey_t * value, lv_style_selector_t selector) +{ + lv_style_value_t v = { + .ptr = value + }; + lv_obj_set_local_style_prop(obj, LV_STYLE_IMAGE_COLORKEY, v, selector); +} + void lv_obj_set_style_line_width(lv_obj_t * obj, int32_t value, lv_style_selector_t selector) { lv_style_value_t v = { diff --git a/src/core/lv_obj_style_gen.h b/src/core/lv_obj_style_gen.h index ff85e38b92..5be2b89401 100644 --- a/src/core/lv_obj_style_gen.h +++ b/src/core/lv_obj_style_gen.h @@ -451,6 +451,12 @@ static inline lv_opa_t lv_obj_get_style_image_recolor_opa(const lv_obj_t * obj, return (lv_opa_t)v.num; } +static inline const lv_image_colorkey_t * lv_obj_get_style_image_colorkey(const lv_obj_t * obj, lv_part_t part) +{ + lv_style_value_t v = lv_obj_get_style_prop(obj, part, LV_STYLE_IMAGE_COLORKEY); + return (const lv_image_colorkey_t *)v.ptr; +} + static inline int32_t lv_obj_get_style_line_width(const lv_obj_t * obj, lv_part_t part) { lv_style_value_t v = lv_obj_get_style_prop(obj, part, LV_STYLE_LINE_WIDTH); @@ -864,6 +870,7 @@ void lv_obj_set_style_shadow_opa(lv_obj_t * obj, lv_opa_t value, lv_style_select void lv_obj_set_style_image_opa(lv_obj_t * obj, lv_opa_t value, lv_style_selector_t selector); void lv_obj_set_style_image_recolor(lv_obj_t * obj, lv_color_t value, lv_style_selector_t selector); void lv_obj_set_style_image_recolor_opa(lv_obj_t * obj, lv_opa_t value, lv_style_selector_t selector); +void lv_obj_set_style_image_colorkey(lv_obj_t * obj, const lv_image_colorkey_t * value, lv_style_selector_t selector); void lv_obj_set_style_line_width(lv_obj_t * obj, int32_t value, lv_style_selector_t selector); void lv_obj_set_style_line_dash_width(lv_obj_t * obj, int32_t value, lv_style_selector_t selector); void lv_obj_set_style_line_dash_gap(lv_obj_t * obj, int32_t value, lv_style_selector_t selector); diff --git a/src/core/lv_obj_style_private.h b/src/core/lv_obj_style_private.h index e6be1279e5..97bb607f71 100644 --- a/src/core/lv_obj_style_private.h +++ b/src/core/lv_obj_style_private.h @@ -29,6 +29,7 @@ struct _lv_obj_style_t { uint32_t selector : 24; uint32_t is_local : 1; uint32_t is_trans : 1; + uint32_t is_disabled : 1; }; struct _lv_obj_style_transition_dsc_t { diff --git a/src/core/lv_obj_tree.h b/src/core/lv_obj_tree.h index e869576345..9850b5ad10 100644 --- a/src/core/lv_obj_tree.h +++ b/src/core/lv_obj_tree.h @@ -40,7 +40,7 @@ typedef lv_obj_tree_walk_res_t (*lv_obj_tree_walk_cb_t)(lv_obj_t *, void *); /** * Delete an object and all of its children. * Also remove the objects from their group and remove all animations (if any). - * Send `LV_EVENT_DELETED` to deleted objects. + * Send `LV_EVENT_DELETE` to deleted objects. * @param obj pointer to an object */ void lv_obj_delete(lv_obj_t * obj); @@ -48,7 +48,7 @@ void lv_obj_delete(lv_obj_t * obj); /** * Delete all children of an object. * Also remove the objects from their group and remove all animations (if any). - * Send `LV_EVENT_DELETED` to deleted objects. + * Send `LV_EVENT_DELETE` to deleted objects. * @param obj pointer to an object */ void lv_obj_clean(lv_obj_t * obj); diff --git a/src/core/lv_refr.c b/src/core/lv_refr.c index 3d5860473b..9e546c8628 100644 --- a/src/core/lv_refr.c +++ b/src/core/lv_refr.c @@ -44,13 +44,18 @@ static void refr_invalid_areas(void); static void refr_sync_areas(void); static void refr_area(const lv_area_t * area_p, int32_t y_offset); static void refr_configured_layer(lv_layer_t * layer); -static lv_obj_t * lv_refr_get_top_obj(const lv_area_t * area_p, lv_obj_t * obj); static void refr_obj_and_children(lv_layer_t * layer, lv_obj_t * top_obj); -static void refr_obj(lv_layer_t * layer, lv_obj_t * obj); static uint32_t get_max_row(lv_display_t * disp, int32_t area_w, int32_t area_h); static void draw_buf_flush(lv_display_t * disp); static void call_flush_cb(lv_display_t * disp, const lv_area_t * area, uint8_t * px_map); static void wait_for_flushing(lv_display_t * disp); +static lv_result_t layer_get_area(lv_layer_t * layer, lv_obj_t * obj, lv_layer_type_t layer_type, + lv_area_t * layer_area_out, lv_area_t * obj_draw_size_out); +static bool alpha_test_area_on_obj(lv_obj_t * obj, const lv_area_t * area); +#if LV_DRAW_TRANSFORM_USE_MATRIX + static bool refr_check_obj_clip_overflow(lv_layer_t * layer, lv_obj_t * obj); + static void refr_obj_matrix(lv_layer_t * layer, lv_obj_t * obj); +#endif /********************** * STATIC VARIABLES @@ -167,7 +172,7 @@ void lv_obj_redraw(lv_layer_t * layer, lv_obj_t * obj) if(clip_corner == false) { for(i = 0; i < child_cnt; i++) { lv_obj_t * child = obj->spec_attr->children[i]; - refr_obj(layer, child); + lv_obj_refr(layer, child); } /*If the object was visible on the clip area call the post draw events too*/ @@ -196,7 +201,7 @@ void lv_obj_redraw(lv_layer_t * layer, lv_obj_t * obj) for(i = 0; i < child_cnt; i++) { lv_obj_t * child = obj->spec_attr->children[i]; - refr_obj(layer_children, child); + lv_obj_refr(layer_children, child); } /*If all the children are redrawn send 'post draw' draw*/ @@ -217,7 +222,7 @@ void lv_obj_redraw(lv_layer_t * layer, lv_obj_t * obj) for(i = 0; i < child_cnt; i++) { lv_obj_t * child = obj->spec_attr->children[i]; - refr_obj(layer_children, child); + lv_obj_refr(layer_children, child); } /*If all the children are redrawn send 'post draw' draw*/ @@ -239,7 +244,7 @@ void lv_obj_redraw(lv_layer_t * layer, lv_obj_t * obj) layer->_clip_area = mid; for(i = 0; i < child_cnt; i++) { lv_obj_t * child = obj->spec_attr->children[i]; - refr_obj(layer, child); + lv_obj_refr(layer, child); } /*If all the children are redrawn make 'post draw' draw*/ @@ -379,7 +384,12 @@ void lv_display_refr_timer(lv_timer_t * tmr) return; } - lv_display_send_event(disp_refr, LV_EVENT_REFR_START, NULL); + lv_result_t res = lv_display_send_event(disp_refr, LV_EVENT_REFR_START, NULL); + if(res == LV_RESULT_INVALID) { + LV_TRACE_REFR("deleted"); + LV_PROFILER_REFR_END; + return; + } /*Refresh the screen's layout if required*/ LV_PROFILER_LAYOUT_BEGIN_TAG("layout"); @@ -432,6 +442,162 @@ void lv_display_refr_timer(lv_timer_t * tmr) LV_PROFILER_REFR_END; } +/** + * Search the most top object which fully covers an area + * @param area_p pointer to an area + * @param obj the first object to start the searching (typically a screen) + * @return + */ +lv_obj_t * lv_refr_get_top_obj(const lv_area_t * area_p, lv_obj_t * obj) +{ + lv_obj_t * found_p = NULL; + + if(lv_area_is_in(area_p, &obj->coords, 0) == false) return NULL; + if(lv_obj_has_flag(obj, LV_OBJ_FLAG_HIDDEN)) return NULL; + if(lv_obj_get_layer_type(obj) != LV_LAYER_TYPE_NONE) return NULL; + if(lv_obj_get_style_opa(obj, LV_PART_MAIN) < LV_OPA_MAX) return NULL; + + /*If this object is fully cover the draw area then check the children too*/ + lv_cover_check_info_t info; + info.res = LV_COVER_RES_COVER; + info.area = area_p; + lv_obj_send_event(obj, LV_EVENT_COVER_CHECK, &info); + if(info.res == LV_COVER_RES_MASKED) return NULL; + + int32_t i; + int32_t child_cnt = lv_obj_get_child_count(obj); + for(i = child_cnt - 1; i >= 0; i--) { + lv_obj_t * child = obj->spec_attr->children[i]; + found_p = lv_refr_get_top_obj(area_p, child); + + /*If a children is ok then break*/ + if(found_p != NULL) { + break; + } + } + + /*If no better children use this object*/ + if(found_p == NULL && info.res == LV_COVER_RES_COVER) { + found_p = obj; + } + + return found_p; +} + + +void lv_obj_refr(lv_layer_t * layer, lv_obj_t * obj) +{ + LV_ASSERT_NULL(layer); + LV_ASSERT_NULL(obj); + if(lv_obj_has_flag(obj, LV_OBJ_FLAG_HIDDEN)) return; + + /*If `opa_layered != LV_OPA_COVER` draw the widget on a new layer and blend that layer with the given opacity.*/ + const lv_opa_t opa_layered = lv_obj_get_style_opa_layered(obj, LV_PART_MAIN); + if(opa_layered <= LV_OPA_MIN) return; + + const lv_opa_t layer_opa_ori = layer->opa; + const lv_color32_t layer_recolor = layer->recolor; + + /*Normal `opa` (not layered) will just scale down `bg_opa`, `text_opa`, etc, in the upcoming drawings.*/ + const lv_opa_t opa_main = lv_obj_get_style_opa(obj, LV_PART_MAIN); + if(opa_main < LV_OPA_MAX) { + layer->opa = LV_OPA_MIX2(layer_opa_ori, opa_main); + } + + layer->recolor = lv_obj_style_apply_recolor(obj, LV_PART_MAIN, layer->recolor); + + lv_layer_type_t layer_type = lv_obj_get_layer_type(obj); + if(layer_type == LV_LAYER_TYPE_NONE) { + lv_obj_redraw(layer, obj); + } +#if LV_DRAW_TRANSFORM_USE_MATRIX + /*If the layer opa is full then use the matrix transform*/ + else if(opa_layered >= LV_OPA_MAX && !refr_check_obj_clip_overflow(layer, obj)) { + refr_obj_matrix(layer, obj); + } +#endif /* LV_DRAW_TRANSFORM_USE_MATRIX */ + else { + lv_area_t layer_area_full; + lv_area_t obj_draw_size; + lv_result_t res = layer_get_area(layer, obj, layer_type, &layer_area_full, &obj_draw_size); + if(res != LV_RESULT_OK) return; + + /*Simple layers can be subdivided into smaller layers*/ + uint32_t max_rgb_row_height = lv_area_get_height(&layer_area_full); + uint32_t max_argb_row_height = lv_area_get_height(&layer_area_full); + if(layer_type == LV_LAYER_TYPE_SIMPLE) { + int32_t w = lv_area_get_width(&layer_area_full); + uint8_t px_size = lv_color_format_get_size(disp_refr->color_format); + max_rgb_row_height = LV_DRAW_LAYER_SIMPLE_BUF_SIZE / w / px_size; + max_argb_row_height = LV_DRAW_LAYER_SIMPLE_BUF_SIZE / w / sizeof(lv_color32_t); + } + + lv_area_t layer_area_act; + layer_area_act.x1 = layer_area_full.x1; + layer_area_act.x2 = layer_area_full.x2; + layer_area_act.y1 = layer_area_full.y1; + layer_area_act.y2 = layer_area_full.y1; + + while(layer_area_act.y2 < layer_area_full.y2) { + /* Test with an RGB layer size (which is larger than the ARGB layer size) + * If it really doesn't need alpha use it. Else switch to the ARGB size*/ + layer_area_act.y2 = layer_area_act.y1 + max_rgb_row_height - 1; + if(layer_area_act.y2 > layer_area_full.y2) layer_area_act.y2 = layer_area_full.y2; + + const void * bitmap_mask_src = lv_obj_get_style_bitmap_mask_src(obj, LV_PART_MAIN); + bool area_need_alpha = bitmap_mask_src || alpha_test_area_on_obj(obj, &layer_area_act); + + if(area_need_alpha) { + layer_area_act.y2 = layer_area_act.y1 + max_argb_row_height - 1; + if(layer_area_act.y2 > layer_area_full.y2) layer_area_act.y2 = layer_area_full.y2; + } + + lv_layer_t * new_layer = lv_draw_layer_create(layer, + area_need_alpha ? LV_COLOR_FORMAT_ARGB8888 : LV_COLOR_FORMAT_NATIVE, &layer_area_act); + lv_obj_redraw(new_layer, obj); + + lv_point_t pivot = { + .x = lv_obj_get_style_transform_pivot_x(obj, LV_PART_MAIN), + .y = lv_obj_get_style_transform_pivot_y(obj, LV_PART_MAIN) + }; + + if(LV_COORD_IS_PCT(pivot.x)) { + pivot.x = (LV_COORD_GET_PCT(pivot.x) * lv_area_get_width(&obj->coords)) / 100; + } + if(LV_COORD_IS_PCT(pivot.y)) { + pivot.y = (LV_COORD_GET_PCT(pivot.y) * lv_area_get_height(&obj->coords)) / 100; + } + + lv_draw_image_dsc_t layer_draw_dsc; + lv_draw_image_dsc_init(&layer_draw_dsc); + layer_draw_dsc.pivot.x = obj->coords.x1 + pivot.x - new_layer->buf_area.x1; + layer_draw_dsc.pivot.y = obj->coords.y1 + pivot.y - new_layer->buf_area.y1; + + layer_draw_dsc.opa = opa_layered; + layer_draw_dsc.rotation = lv_obj_get_style_transform_rotation(obj, LV_PART_MAIN); + while(layer_draw_dsc.rotation > 3600) layer_draw_dsc.rotation -= 3600; + while(layer_draw_dsc.rotation < 0) layer_draw_dsc.rotation += 3600; + layer_draw_dsc.scale_x = lv_obj_get_style_transform_scale_x(obj, LV_PART_MAIN); + layer_draw_dsc.scale_y = lv_obj_get_style_transform_scale_y(obj, LV_PART_MAIN); + layer_draw_dsc.skew_x = lv_obj_get_style_transform_skew_x(obj, LV_PART_MAIN); + layer_draw_dsc.skew_y = lv_obj_get_style_transform_skew_y(obj, LV_PART_MAIN); + layer_draw_dsc.blend_mode = lv_obj_get_style_blend_mode(obj, LV_PART_MAIN); + layer_draw_dsc.antialias = disp_refr->antialiasing; + layer_draw_dsc.bitmap_mask_src = bitmap_mask_src; + layer_draw_dsc.image_area = obj_draw_size; + layer_draw_dsc.src = new_layer; + + lv_draw_layer(layer, &layer_draw_dsc, &layer_area_act); + + layer_area_act.y1 = layer_area_act.y2 + 1; + } + } + + /* Restore the original layer opa and recolor */ + layer->opa = layer_opa_ori; + layer->recolor = layer_recolor; +} + /********************** * STATIC FUNCTIONS **********************/ @@ -585,6 +751,9 @@ static void refr_invalid_areas(void) if(disp_refr->inv_p == 0) return; LV_PROFILER_REFR_BEGIN; + /*Notify the display driven rendering has started*/ + lv_display_send_event(disp_refr, LV_EVENT_RENDER_START, NULL); + /*Find the last area which will be drawn*/ int32_t i; int32_t last_i = 0; @@ -595,9 +764,6 @@ static void refr_invalid_areas(void) } } - /*Notify the display driven rendering has started*/ - lv_display_send_event(disp_refr, LV_EVENT_RENDER_START, NULL); - disp_refr->last_area = 0; disp_refr->last_part = 0; disp_refr->rendering_in_progress = true; @@ -695,7 +861,7 @@ static void refr_area(const lv_area_t * area_p, int32_t y_offset) } else if(disp_refr->render_mode == LV_DISPLAY_RENDER_MODE_DIRECT || disp_refr->render_mode == LV_DISPLAY_RENDER_MODE_FULL) { - /*In direct mode and full mode the the buffer area is always the whole screen, not considering rotation*/ + /*In direct mode and full mode the buffer area is always the whole screen, not considering rotation*/ layer->buf_area.x1 = 0; layer->buf_area.y1 = 0; if(lv_display_get_matrix_rotation(disp_refr)) { @@ -713,7 +879,7 @@ static void refr_area(const lv_area_t * area_p, int32_t y_offset) uint32_t tile_cnt = 1; int32_t tile_h = lv_area_get_height(area_p); if(LV_COLOR_FORMAT_IS_INDEXED(layer->color_format) == false) { - /* Assume that the the buffer size (can be screen sized or smaller in case of partial mode) + /* Assume that the buffer size (can be screen sized or smaller in case of partial mode) * and max tile size are the optimal scenario. From this calculate the ideal tile size * and set the tile count and tile height accordingly. */ @@ -902,48 +1068,6 @@ static void refr_configured_layer(lv_layer_t * layer) LV_PROFILER_REFR_END; } -/** - * Search the most top object which fully covers an area - * @param area_p pointer to an area - * @param obj the first object to start the searching (typically a screen) - * @return - */ -static lv_obj_t * lv_refr_get_top_obj(const lv_area_t * area_p, lv_obj_t * obj) -{ - lv_obj_t * found_p = NULL; - - if(lv_area_is_in(area_p, &obj->coords, 0) == false) return NULL; - if(lv_obj_has_flag(obj, LV_OBJ_FLAG_HIDDEN)) return NULL; - if(lv_obj_get_layer_type(obj) != LV_LAYER_TYPE_NONE) return NULL; - if(lv_obj_get_style_opa(obj, LV_PART_MAIN) < LV_OPA_MAX) return NULL; - - /*If this object is fully cover the draw area then check the children too*/ - lv_cover_check_info_t info; - info.res = LV_COVER_RES_COVER; - info.area = area_p; - lv_obj_send_event(obj, LV_EVENT_COVER_CHECK, &info); - if(info.res == LV_COVER_RES_MASKED) return NULL; - - int32_t i; - int32_t child_cnt = lv_obj_get_child_count(obj); - for(i = child_cnt - 1; i >= 0; i--) { - lv_obj_t * child = obj->spec_attr->children[i]; - found_p = lv_refr_get_top_obj(area_p, child); - - /*If a children is ok then break*/ - if(found_p != NULL) { - break; - } - } - - /*If no better children use this object*/ - if(found_p == NULL && info.res == LV_COVER_RES_COVER) { - found_p = obj; - } - - return found_p; -} - /** * Make the refreshing from an object. Draw all its children and the youngers too. * @param top_p pointer to an objects. Start the drawing from it. @@ -970,7 +1094,7 @@ static void refr_obj_and_children(lv_layer_t * layer, lv_obj_t * top_obj) } /*Refresh the top object and its children*/ - refr_obj(layer, top_obj); + lv_obj_refr(layer, top_obj); /*Do until not reach the screen*/ while(parent != NULL) { @@ -984,7 +1108,7 @@ static void refr_obj_and_children(lv_layer_t * layer, lv_obj_t * top_obj) } else { /*Refresh the objects*/ - refr_obj(layer, child); + lv_obj_refr(layer, child); } } @@ -1075,18 +1199,18 @@ static bool obj_get_matrix(lv_obj_t * obj, lv_matrix_t * matrix) } lv_point_t pivot = { - .x = lv_obj_get_style_transform_pivot_x(obj, 0), - .y = lv_obj_get_style_transform_pivot_y(obj, 0) + .x = lv_obj_get_style_transform_pivot_x(obj, LV_PART_MAIN), + .y = lv_obj_get_style_transform_pivot_y(obj, LV_PART_MAIN) }; pivot.x = obj->coords.x1 + lv_pct_to_px(pivot.x, lv_area_get_width(&obj->coords)); pivot.y = obj->coords.y1 + lv_pct_to_px(pivot.y, lv_area_get_height(&obj->coords)); - int32_t rotation = lv_obj_get_style_transform_rotation(obj, 0); - int32_t scale_x = lv_obj_get_style_transform_scale_x(obj, 0); - int32_t scale_y = lv_obj_get_style_transform_scale_y(obj, 0); - int32_t skew_x = lv_obj_get_style_transform_skew_x(obj, 0); - int32_t skew_y = lv_obj_get_style_transform_skew_y(obj, 0); + int32_t rotation = lv_obj_get_style_transform_rotation(obj, LV_PART_MAIN); + int32_t scale_x = lv_obj_get_style_transform_scale_x(obj, LV_PART_MAIN); + int32_t scale_y = lv_obj_get_style_transform_scale_y(obj, LV_PART_MAIN); + int32_t skew_x = lv_obj_get_style_transform_skew_x(obj, LV_PART_MAIN); + int32_t skew_y = lv_obj_get_style_transform_skew_y(obj, LV_PART_MAIN); if(scale_x <= 0 || scale_y <= 0) { /* NOT draw if scale is negative or zero */ @@ -1162,7 +1286,7 @@ static void refr_obj_matrix(lv_layer_t * layer, lv_obj_t * obj) static bool refr_check_obj_clip_overflow(lv_layer_t * layer, lv_obj_t * obj) { - if(lv_obj_get_style_transform_rotation(obj, 0) == 0) { + if(lv_obj_get_style_transform_rotation(obj, LV_PART_MAIN) == 0) { return false; } @@ -1185,117 +1309,6 @@ static bool refr_check_obj_clip_overflow(lv_layer_t * layer, lv_obj_t * obj) #endif /* LV_DRAW_TRANSFORM_USE_MATRIX */ -static void refr_obj(lv_layer_t * layer, lv_obj_t * obj) -{ - if(lv_obj_has_flag(obj, LV_OBJ_FLAG_HIDDEN)) return; - - /*If `opa_layered != LV_OPA_COVER` draw the widget on a new layer and blend that layer with the given opacity.*/ - const lv_opa_t opa_layered = lv_obj_get_style_opa_layered(obj, LV_PART_MAIN); - if(opa_layered <= LV_OPA_MIN) return; - - const lv_opa_t layer_opa_ori = layer->opa; - const lv_color32_t layer_recolor = layer->recolor; - - /*Normal `opa` (not layered) will just scale down `bg_opa`, `text_opa`, etc, in the upcoming drawings.*/ - const lv_opa_t opa_main = lv_obj_get_style_opa(obj, LV_PART_MAIN); - if(opa_main < LV_OPA_MAX) { - layer->opa = LV_OPA_MIX2(layer_opa_ori, opa_main); - } - - layer->recolor = lv_obj_style_apply_recolor(obj, LV_PART_MAIN, layer->recolor); - - lv_layer_type_t layer_type = lv_obj_get_layer_type(obj); - if(layer_type == LV_LAYER_TYPE_NONE) { - lv_obj_redraw(layer, obj); - } -#if LV_DRAW_TRANSFORM_USE_MATRIX - /*If the layer opa is full then use the matrix transform*/ - else if(opa_layered >= LV_OPA_MAX && !refr_check_obj_clip_overflow(layer, obj)) { - refr_obj_matrix(layer, obj); - } -#endif /* LV_DRAW_TRANSFORM_USE_MATRIX */ - else { - lv_area_t layer_area_full; - lv_area_t obj_draw_size; - lv_result_t res = layer_get_area(layer, obj, layer_type, &layer_area_full, &obj_draw_size); - if(res != LV_RESULT_OK) return; - - /*Simple layers can be subdivided into smaller layers*/ - uint32_t max_rgb_row_height = lv_area_get_height(&layer_area_full); - uint32_t max_argb_row_height = lv_area_get_height(&layer_area_full); - if(layer_type == LV_LAYER_TYPE_SIMPLE) { - int32_t w = lv_area_get_width(&layer_area_full); - uint8_t px_size = lv_color_format_get_size(disp_refr->color_format); - max_rgb_row_height = LV_DRAW_LAYER_SIMPLE_BUF_SIZE / w / px_size; - max_argb_row_height = LV_DRAW_LAYER_SIMPLE_BUF_SIZE / w / sizeof(lv_color32_t); - } - - lv_area_t layer_area_act; - layer_area_act.x1 = layer_area_full.x1; - layer_area_act.x2 = layer_area_full.x2; - layer_area_act.y1 = layer_area_full.y1; - layer_area_act.y2 = layer_area_full.y1; - - while(layer_area_act.y2 < layer_area_full.y2) { - /* Test with an RGB layer size (which is larger than the ARGB layer size) - * If it really doesn't need alpha use it. Else switch to the ARGB size*/ - layer_area_act.y2 = layer_area_act.y1 + max_rgb_row_height - 1; - if(layer_area_act.y2 > layer_area_full.y2) layer_area_act.y2 = layer_area_full.y2; - - const void * bitmap_mask_src = lv_obj_get_style_bitmap_mask_src(obj, 0); - bool area_need_alpha = bitmap_mask_src || alpha_test_area_on_obj(obj, &layer_area_act); - - if(area_need_alpha) { - layer_area_act.y2 = layer_area_act.y1 + max_argb_row_height - 1; - if(layer_area_act.y2 > layer_area_full.y2) layer_area_act.y2 = layer_area_full.y2; - } - - lv_layer_t * new_layer = lv_draw_layer_create(layer, - area_need_alpha ? LV_COLOR_FORMAT_ARGB8888 : LV_COLOR_FORMAT_NATIVE, &layer_area_act); - lv_obj_redraw(new_layer, obj); - - lv_point_t pivot = { - .x = lv_obj_get_style_transform_pivot_x(obj, 0), - .y = lv_obj_get_style_transform_pivot_y(obj, 0) - }; - - if(LV_COORD_IS_PCT(pivot.x)) { - pivot.x = (LV_COORD_GET_PCT(pivot.x) * lv_area_get_width(&obj->coords)) / 100; - } - if(LV_COORD_IS_PCT(pivot.y)) { - pivot.y = (LV_COORD_GET_PCT(pivot.y) * lv_area_get_height(&obj->coords)) / 100; - } - - lv_draw_image_dsc_t layer_draw_dsc; - lv_draw_image_dsc_init(&layer_draw_dsc); - layer_draw_dsc.pivot.x = obj->coords.x1 + pivot.x - new_layer->buf_area.x1; - layer_draw_dsc.pivot.y = obj->coords.y1 + pivot.y - new_layer->buf_area.y1; - - layer_draw_dsc.opa = opa_layered; - layer_draw_dsc.rotation = lv_obj_get_style_transform_rotation(obj, 0); - while(layer_draw_dsc.rotation > 3600) layer_draw_dsc.rotation -= 3600; - while(layer_draw_dsc.rotation < 0) layer_draw_dsc.rotation += 3600; - layer_draw_dsc.scale_x = lv_obj_get_style_transform_scale_x(obj, 0); - layer_draw_dsc.scale_y = lv_obj_get_style_transform_scale_y(obj, 0); - layer_draw_dsc.skew_x = lv_obj_get_style_transform_skew_x(obj, 0); - layer_draw_dsc.skew_y = lv_obj_get_style_transform_skew_y(obj, 0); - layer_draw_dsc.blend_mode = lv_obj_get_style_blend_mode(obj, 0); - layer_draw_dsc.antialias = disp_refr->antialiasing; - layer_draw_dsc.bitmap_mask_src = bitmap_mask_src; - layer_draw_dsc.image_area = obj_draw_size; - layer_draw_dsc.src = new_layer; - - lv_draw_layer(layer, &layer_draw_dsc, &layer_area_act); - - layer_area_act.y1 = layer_area_act.y2 + 1; - } - } - - /* Restore the original layer opa and recolor */ - layer->opa = layer_opa_ori; - layer->recolor = layer_recolor; -} - static uint32_t get_max_row(lv_display_t * disp, int32_t area_w, int32_t area_h) { lv_color_format_t cf = disp->color_format; diff --git a/src/core/lv_refr_private.h b/src/core/lv_refr_private.h index 3b2985b70e..0519d65292 100644 --- a/src/core/lv_refr_private.h +++ b/src/core/lv_refr_private.h @@ -58,6 +58,21 @@ lv_display_t * lv_refr_get_disp_refreshing(void); */ void lv_refr_set_disp_refreshing(lv_display_t * disp); +/** + * Search the most top object which fully covers an area + * @param area_p pointer to an area + * @param obj the first object to start the searching (typically a screen) + * @return + */ +lv_obj_t * lv_refr_get_top_obj(const lv_area_t * area_p, lv_obj_t * obj); + +/** + * Render an object to a layer + * @param layer target drawing layer + * @param obj object to render + */ +void lv_obj_refr(lv_layer_t * layer, lv_obj_t * obj); + /********************** * MACROS **********************/ diff --git a/src/display/lv_display.c b/src/display/lv_display.c index c183b392f5..0a261f3e57 100644 --- a/src/display/lv_display.c +++ b/src/display/lv_display.c @@ -1,5 +1,5 @@ /** - * @file lv_disp.c + * @file lv_display.c * */ @@ -178,6 +178,7 @@ void lv_display_delete(lv_display_t * disp) if(disp == lv_refr_get_disp_refreshing()) was_refr = true; lv_display_send_event(disp, LV_EVENT_DELETE, NULL); + lv_event_mark_deleted(disp); lv_event_remove_all(&(disp->event_list)); /*Detach the input devices*/ @@ -592,6 +593,8 @@ uint32_t lv_display_get_tile_cnt(lv_display_t * disp) void lv_display_set_antialiasing(lv_display_t * disp, bool en) { + LV_LOG_WARN("Disabling anti-aliasing is not supported since v9. This function will be removed."); + if(disp == NULL) disp = lv_display_get_default(); if(disp == NULL) return; @@ -636,6 +639,17 @@ lv_obj_t * lv_display_get_screen_active(lv_display_t * disp) return disp->act_scr; } +lv_obj_t * lv_display_get_screen_loading(lv_display_t * disp) +{ + if(!disp) disp = lv_display_get_default(); + if(!disp) { + LV_LOG_WARN("no display registered to get the current screen being loaded"); + return NULL; + } + + return disp->scr_to_load; +} + lv_obj_t * lv_display_get_screen_prev(lv_display_t * disp) { if(!disp) disp = lv_display_get_default(); @@ -680,9 +694,31 @@ lv_obj_t * lv_display_get_layer_bottom(lv_display_t * disp) return disp->bottom_layer; } +#if LV_USE_OBJ_NAME + +lv_obj_t * lv_display_get_screen_by_name(const lv_display_t * disp, const char * screen_name) +{ + if(!disp) disp = lv_display_get_default(); + if(!disp) { + LV_LOG_WARN("no display registered to get a screen by name"); + return NULL; + } + + uint32_t i; + for(i = 0; i < disp->screen_cnt; i++) { + const char * n = lv_obj_get_name(disp->screens[i]); + if(n && lv_streq(screen_name, n)) return disp->screens[i]; + } + + return NULL; + +} + +#endif /*LV_USE_OBJ_NAME*/ + void lv_screen_load(struct _lv_obj_t * scr) { - lv_screen_load_anim(scr, LV_SCR_LOAD_ANIM_NONE, 0, 0, false); + lv_screen_load_anim(scr, LV_SCREEN_LOAD_ANIM_NONE, 0, 0, false); } void lv_screen_load_anim(lv_obj_t * new_scr, lv_screen_load_anim_t anim_type, uint32_t time, uint32_t delay, @@ -748,76 +784,76 @@ void lv_screen_load_anim(lv_obj_t * new_scr, lv_screen_load_anim_t anim_type, ui lv_anim_set_delay(&a_old, delay); switch(anim_type) { - case LV_SCR_LOAD_ANIM_NONE: + case LV_SCREEN_LOAD_ANIM_NONE: /*Create a dummy animation to apply the delay*/ lv_anim_set_exec_cb(&a_new, set_x_anim); lv_anim_set_values(&a_new, 0, 0); break; - case LV_SCR_LOAD_ANIM_OVER_LEFT: + case LV_SCREEN_LOAD_ANIM_OVER_LEFT: lv_anim_set_exec_cb(&a_new, set_x_anim); lv_anim_set_values(&a_new, lv_display_get_horizontal_resolution(d), 0); break; - case LV_SCR_LOAD_ANIM_OVER_RIGHT: + case LV_SCREEN_LOAD_ANIM_OVER_RIGHT: lv_anim_set_exec_cb(&a_new, set_x_anim); lv_anim_set_values(&a_new, -lv_display_get_horizontal_resolution(d), 0); break; - case LV_SCR_LOAD_ANIM_OVER_TOP: + case LV_SCREEN_LOAD_ANIM_OVER_TOP: lv_anim_set_exec_cb(&a_new, set_y_anim); lv_anim_set_values(&a_new, lv_display_get_vertical_resolution(d), 0); break; - case LV_SCR_LOAD_ANIM_OVER_BOTTOM: + case LV_SCREEN_LOAD_ANIM_OVER_BOTTOM: lv_anim_set_exec_cb(&a_new, set_y_anim); lv_anim_set_values(&a_new, -lv_display_get_vertical_resolution(d), 0); break; - case LV_SCR_LOAD_ANIM_MOVE_LEFT: + case LV_SCREEN_LOAD_ANIM_MOVE_LEFT: lv_anim_set_exec_cb(&a_new, set_x_anim); lv_anim_set_values(&a_new, lv_display_get_horizontal_resolution(d), 0); lv_anim_set_exec_cb(&a_old, set_x_anim); lv_anim_set_values(&a_old, 0, -lv_display_get_horizontal_resolution(d)); break; - case LV_SCR_LOAD_ANIM_MOVE_RIGHT: + case LV_SCREEN_LOAD_ANIM_MOVE_RIGHT: lv_anim_set_exec_cb(&a_new, set_x_anim); lv_anim_set_values(&a_new, -lv_display_get_horizontal_resolution(d), 0); lv_anim_set_exec_cb(&a_old, set_x_anim); lv_anim_set_values(&a_old, 0, lv_display_get_horizontal_resolution(d)); break; - case LV_SCR_LOAD_ANIM_MOVE_TOP: + case LV_SCREEN_LOAD_ANIM_MOVE_TOP: lv_anim_set_exec_cb(&a_new, set_y_anim); lv_anim_set_values(&a_new, lv_display_get_vertical_resolution(d), 0); lv_anim_set_exec_cb(&a_old, set_y_anim); lv_anim_set_values(&a_old, 0, -lv_display_get_vertical_resolution(d)); break; - case LV_SCR_LOAD_ANIM_MOVE_BOTTOM: + case LV_SCREEN_LOAD_ANIM_MOVE_BOTTOM: lv_anim_set_exec_cb(&a_new, set_y_anim); lv_anim_set_values(&a_new, -lv_display_get_vertical_resolution(d), 0); lv_anim_set_exec_cb(&a_old, set_y_anim); lv_anim_set_values(&a_old, 0, lv_display_get_vertical_resolution(d)); break; - case LV_SCR_LOAD_ANIM_FADE_IN: + case LV_SCREEN_LOAD_ANIM_FADE_IN: lv_anim_set_exec_cb(&a_new, opa_scale_anim); lv_anim_set_values(&a_new, LV_OPA_TRANSP, LV_OPA_COVER); break; - case LV_SCR_LOAD_ANIM_FADE_OUT: + case LV_SCREEN_LOAD_ANIM_FADE_OUT: lv_anim_set_exec_cb(&a_old, opa_scale_anim); lv_anim_set_values(&a_old, LV_OPA_COVER, LV_OPA_TRANSP); break; - case LV_SCR_LOAD_ANIM_OUT_LEFT: + case LV_SCREEN_LOAD_ANIM_OUT_LEFT: lv_anim_set_exec_cb(&a_old, set_x_anim); lv_anim_set_values(&a_old, 0, -lv_display_get_horizontal_resolution(d)); break; - case LV_SCR_LOAD_ANIM_OUT_RIGHT: + case LV_SCREEN_LOAD_ANIM_OUT_RIGHT: lv_anim_set_exec_cb(&a_old, set_x_anim); lv_anim_set_values(&a_old, 0, lv_display_get_horizontal_resolution(d)); break; - case LV_SCR_LOAD_ANIM_OUT_TOP: + case LV_SCREEN_LOAD_ANIM_OUT_TOP: lv_anim_set_exec_cb(&a_old, set_y_anim); lv_anim_set_values(&a_old, 0, -lv_display_get_vertical_resolution(d)); break; - case LV_SCR_LOAD_ANIM_OUT_BOTTOM: + case LV_SCREEN_LOAD_ANIM_OUT_BOTTOM: lv_anim_set_exec_cb(&a_old, set_y_anim); lv_anim_set_values(&a_old, 0, lv_display_get_vertical_resolution(d)); break; @@ -881,21 +917,7 @@ uint32_t lv_display_remove_event_cb_with_user_data(lv_display_t * disp, lv_event lv_result_t lv_display_send_event(lv_display_t * disp, lv_event_code_t code, void * param) { - - lv_event_t e; - lv_memzero(&e, sizeof(e)); - e.code = code; - e.current_target = disp; - e.original_target = disp; - e.param = param; - lv_result_t res; - res = lv_event_send(&disp->event_list, &e, true); - if(res != LV_RESULT_OK) return res; - - res = lv_event_send(&disp->event_list, &e, false); - if(res != LV_RESULT_OK) return res; - - return res; + return lv_event_push_and_send(&disp->event_list, code, disp, param); } lv_area_t * lv_event_get_invalidated_area(lv_event_t * e) @@ -1328,11 +1350,11 @@ static void scr_anim_completed(lv_anim_t * a) static bool is_out_anim(lv_screen_load_anim_t anim_type) { - return anim_type == LV_SCR_LOAD_ANIM_FADE_OUT || - anim_type == LV_SCR_LOAD_ANIM_OUT_LEFT || - anim_type == LV_SCR_LOAD_ANIM_OUT_RIGHT || - anim_type == LV_SCR_LOAD_ANIM_OUT_TOP || - anim_type == LV_SCR_LOAD_ANIM_OUT_BOTTOM; + return anim_type == LV_SCREEN_LOAD_ANIM_FADE_OUT || + anim_type == LV_SCREEN_LOAD_ANIM_OUT_LEFT || + anim_type == LV_SCREEN_LOAD_ANIM_OUT_RIGHT || + anim_type == LV_SCREEN_LOAD_ANIM_OUT_TOP || + anim_type == LV_SCREEN_LOAD_ANIM_OUT_BOTTOM; } static void disp_event_cb(lv_event_t * e) diff --git a/src/display/lv_display.h b/src/display/lv_display.h index ddcd1ee059..9ac4e10c21 100644 --- a/src/display/lv_display.h +++ b/src/display/lv_display.h @@ -60,22 +60,22 @@ typedef enum { } lv_display_render_mode_t; typedef enum { - LV_SCR_LOAD_ANIM_NONE, - LV_SCR_LOAD_ANIM_OVER_LEFT, - LV_SCR_LOAD_ANIM_OVER_RIGHT, - LV_SCR_LOAD_ANIM_OVER_TOP, - LV_SCR_LOAD_ANIM_OVER_BOTTOM, - LV_SCR_LOAD_ANIM_MOVE_LEFT, - LV_SCR_LOAD_ANIM_MOVE_RIGHT, - LV_SCR_LOAD_ANIM_MOVE_TOP, - LV_SCR_LOAD_ANIM_MOVE_BOTTOM, - LV_SCR_LOAD_ANIM_FADE_IN, - LV_SCR_LOAD_ANIM_FADE_ON = LV_SCR_LOAD_ANIM_FADE_IN, /*For backward compatibility*/ - LV_SCR_LOAD_ANIM_FADE_OUT, - LV_SCR_LOAD_ANIM_OUT_LEFT, - LV_SCR_LOAD_ANIM_OUT_RIGHT, - LV_SCR_LOAD_ANIM_OUT_TOP, - LV_SCR_LOAD_ANIM_OUT_BOTTOM, + LV_SCREEN_LOAD_ANIM_NONE, + LV_SCREEN_LOAD_ANIM_OVER_LEFT, + LV_SCREEN_LOAD_ANIM_OVER_RIGHT, + LV_SCREEN_LOAD_ANIM_OVER_TOP, + LV_SCREEN_LOAD_ANIM_OVER_BOTTOM, + LV_SCREEN_LOAD_ANIM_MOVE_LEFT, + LV_SCREEN_LOAD_ANIM_MOVE_RIGHT, + LV_SCREEN_LOAD_ANIM_MOVE_TOP, + LV_SCREEN_LOAD_ANIM_MOVE_BOTTOM, + LV_SCREEN_LOAD_ANIM_FADE_IN, + LV_SCREEN_LOAD_ANIM_FADE_ON = LV_SCREEN_LOAD_ANIM_FADE_IN, /*For backward compatibility*/ + LV_SCREEN_LOAD_ANIM_FADE_OUT, + LV_SCREEN_LOAD_ANIM_OUT_LEFT, + LV_SCREEN_LOAD_ANIM_OUT_RIGHT, + LV_SCREEN_LOAD_ANIM_OUT_TOP, + LV_SCREEN_LOAD_ANIM_OUT_BOTTOM, } lv_screen_load_anim_t; typedef void (*lv_display_flush_cb_t)(lv_display_t * disp, const lv_area_t * area, uint8_t * px_map); @@ -358,6 +358,7 @@ void lv_display_set_tile_cnt(lv_display_t * disp, uint32_t tile_cnt); uint32_t lv_display_get_tile_cnt(lv_display_t * disp); /** + * Disabling anti-aliasing is not supported since v9. This function will be removed. * Enable anti-aliasing for the render engine * @param disp pointer to a display * @param en true/false @@ -408,6 +409,13 @@ lv_obj_t * lv_display_get_screen_active(lv_display_t * disp); */ lv_obj_t * lv_display_get_screen_prev(lv_display_t * disp); +/** + * Return the screen that is currently being loaded by the display + * @param disp pointer to a display object (NULL to use the default screen) + * @return pointer to the screen being loaded or NULL if no screen is currently being loaded + */ +lv_obj_t * lv_display_get_screen_loading(lv_display_t * disp); + /** * Return the top layer. The top layer is the same on all screens and it is above the normal screen layer. * @param disp pointer to display which top layer should be get. (NULL to use the default screen) @@ -430,6 +438,20 @@ lv_obj_t * lv_display_get_layer_sys(lv_display_t * disp); */ lv_obj_t * lv_display_get_layer_bottom(lv_display_t * disp); + +#if LV_USE_OBJ_NAME + +/** + * Get screen by its name on a display. The name should be set by + * `lv_obj_set_name()` or `lv_obj_set_name_static()`. + * @param disp pointer to a display or NULL to use default display + * @param screen_name name of the screen to get + * @return pointer to the screen, or NULL if not found. + */ +lv_obj_t * lv_display_get_screen_by_name(const lv_display_t * disp, const char * screen_name); + +#endif /*LV_USE_OBJ_NAME*/ + /** * Load a screen on the default display * @param scr pointer to a screen @@ -439,7 +461,7 @@ void lv_screen_load(struct _lv_obj_t * scr); /** * Switch screen with animation * @param scr pointer to the new screen to load - * @param anim_type type of the animation from `lv_screen_load_anim_t`, e.g. `LV_SCR_LOAD_ANIM_MOVE_LEFT` + * @param anim_type type of the animation from `lv_screen_load_anim_t`, e.g. `LV_SCREEN_LOAD_ANIM_MOVE_LEFT` * @param time time of the animation * @param delay delay before the transition * @param auto_del true: automatically delete the old screen diff --git a/src/draw/convert/helium/lv_draw_buf_convert_helium.c b/src/draw/convert/helium/lv_draw_buf_convert_helium.c new file mode 100644 index 0000000000..ff5b8cd686 --- /dev/null +++ b/src/draw/convert/helium/lv_draw_buf_convert_helium.c @@ -0,0 +1,100 @@ +/** + * @file lv_draw_buf_convert_helium.c + * + */ + +/********************* + * INCLUDES + *********************/ +#include "../../../lv_conf_internal.h" + +#if LV_USE_DRAW_SW_ASM == LV_DRAW_SW_ASM_HELIUM +#include "lv_draw_buf_convert_helium.h" + +/********************* + * DEFINES + *********************/ + +/********************** + * STATIC PROTOTYPES + **********************/ + +/********************** + * STATIC FUNCTIONS + **********************/ + +/********************** + * MACROS + **********************/ + +/********************** + * GLOBAL FUNCTIONS + **********************/ + +lv_result_t _lv_draw_buf_convert_premultiply_indexed_helium(lv_draw_buf_t * buf) +{ + lv_draw_buf_t palette_draw_buf; + + LV_ASSERT_NULL(buf); + + if(!LV_COLOR_FORMAT_IS_INDEXED(buf->header.cf)) { + LV_LOG_WARN("Unsupported color format : %d", buf->header.cf); + return LV_RESULT_INVALID; + } + + lv_memcpy(&palette_draw_buf, buf, sizeof(lv_draw_buf_t)); + + palette_draw_buf.header.w = LV_COLOR_INDEXED_PALETTE_SIZE(buf->header.cf); + palette_draw_buf.header.h = 1; + palette_draw_buf.header.cf = LV_COLOR_FORMAT_ARGB8888; + palette_draw_buf.header.stride = 4 * palette_draw_buf.header.w; + + return _lv_draw_buf_convert_premultiply_argb8888_helium(&palette_draw_buf); +} + +lv_result_t _lv_draw_buf_convert_premultiply_argb8888_helium(lv_draw_buf_t * buf) +{ + LV_ASSERT_NULL(buf); + + uint32_t h = buf->header.h; + uint32_t w = buf->header.w; + uint32_t stride = buf->header.stride; + uint8_t * data = (uint8_t *)buf->data; + + if(buf->header.cf != LV_COLOR_FORMAT_ARGB8888) { + LV_LOG_WARN("Unsupported color format : %d", buf->header.cf); + return LV_RESULT_INVALID; + } + + __asm volatile( + " .p2align 2 \n" + " 1: \n" + " mov r0, %[pSource] \n" + " mov r1, %[pTarget] \n" + " wlstp.8 lr, %[w], 3f \n" + " 2: \n" + " vld40.u8 {q0, q1, q2, q3}, [r0] \n" + " vld41.u8 {q0, q1, q2, q3}, [r0] \n" + " vld42.u8 {q0, q1, q2, q3}, [r0] \n" + " vld43.u8 {q0, q1, q2, q3}, [r0]! \n" + " vrmulh.u8 q0, q0, q3 \n" + " vrmulh.u8 q1, q1, q3 \n" + " vrmulh.u8 q2, q2, q3 \n" + " vst40.u8 {q0, q1, q2, q3}, [r1] \n" + " vst41.u8 {q0, q1, q2, q3}, [r1] \n" + " vst42.u8 {q0, q1, q2, q3}, [r1] \n" + " vst43.u8 {q0, q1, q2, q3}, [r1]! \n" + " letp lr, 2b \n" + " 3: \n" + " adds %[pSource], %[src_stride] \n" + " adds %[pTarget], %[dst_stride] \n" + " subs %[h], #1 \n" + " bne 1b \n" + : [pSource] "+r"(data), [pTarget] "+r"(data), [h] "+r"(h) + : [w] "r"(w), [src_stride] "r"(stride), [dst_stride] "r"(stride) + : "q0", "q1", "q2", "q3", "r0", "r1", "lr", "memory"); + + return LV_RESULT_OK; +} + +#endif /* LV_USE_DRAW_SW_ASM == LV_DRAW_SW_ASM_HELIUM */ diff --git a/src/draw/convert/helium/lv_draw_buf_convert_helium.h b/src/draw/convert/helium/lv_draw_buf_convert_helium.h new file mode 100644 index 0000000000..3fb670d6c2 --- /dev/null +++ b/src/draw/convert/helium/lv_draw_buf_convert_helium.h @@ -0,0 +1,57 @@ +/** + * @file lv_draw_buf_convert_helium.h + * + */ + +#ifndef LV_DRAW_BUF_CONVERT_HELIUM_H +#define LV_DRAW_BUF_CONVERT_HELIUM_H + +#ifdef __cplusplus +extern "C" { +#endif + +#include "../../../misc/lv_color.h" +#include "../../lv_draw_buf.h" + +#if LV_USE_DRAW_SW_ASM == LV_DRAW_SW_ASM_HELIUM + +/********************* + * DEFINES + *********************/ + +/********************** + * TYPEDEFS + **********************/ + +#ifndef LV_DRAW_CONVERT_PREMULTIPLY_INDEXED +#define LV_DRAW_CONVERT_PREMULTIPLY_INDEXED(buf) \ + _lv_draw_buf_convert_premultiply_indexed_helium(buf) +#endif + +#ifndef LV_DRAW_CONVERT_PREMULTIPLY_ARGB8888 +#define LV_DRAW_CONVERT_PREMULTIPLY_ARGB8888(buf) \ + _lv_draw_buf_convert_premultiply_argb8888_helium(buf) +#endif + +/********************** + * GLOBAL PROTOTYPES + **********************/ + +/** + * Convert indexed draw_buf to premultiplied format with helium specific optimizations + * @param buf pointer to a draw buf + */ +lv_result_t _lv_draw_buf_convert_premultiply_indexed_helium(lv_draw_buf_t * buf); + +/** + * Convert argb8888 draw_buf to premultiplied format with helium specific optimizations + * @param buf pointer to a draw buf + */ +lv_result_t _lv_draw_buf_convert_premultiply_argb8888_helium(lv_draw_buf_t * buf); + +#endif /*LV_USE_DRAW_SW_ASM == LV_DRAW_SW_ASM_HELIUM*/ +#ifdef __cplusplus +} /* extern "C" */ +#endif + +#endif /* LV_DRAW_BUF_CONVERT_HELIUM_H */ diff --git a/src/draw/convert/lv_draw_buf_convert.c b/src/draw/convert/lv_draw_buf_convert.c new file mode 100644 index 0000000000..7e01b4eb33 --- /dev/null +++ b/src/draw/convert/lv_draw_buf_convert.c @@ -0,0 +1,130 @@ +/** + * @file lv_draw_buf_convert.c + * + */ + +/********************* + * INCLUDES + *********************/ +#include "lv_draw_buf_convert.h" + +#if LV_USE_DRAW_SW_ASM == LV_DRAW_SW_ASM_NEON + #include "neon/lv_draw_buf_convert_neon.h" +#elif LV_USE_DRAW_SW_ASM == LV_DRAW_SW_ASM_HELIUM + #include "helium/lv_draw_buf_convert_helium.h" +#elif LV_USE_DRAW_SW_ASM == LV_DRAW_SW_ASM_CUSTOM + #include LV_DRAW_SW_ASM_CUSTOM_INCLUDE +#endif + +/********************* + * DEFINES + *********************/ + +/********************** + * STATIC PROTOTYPES + **********************/ + +/********************** + * STATIC FUNCTIONS + **********************/ + +/********************** + * MACROS + **********************/ + +#ifndef LV_DRAW_CONVERT_PREMULTIPLY_INDEXED + #define LV_DRAW_CONVERT_PREMULTIPLY_INDEXED(...) LV_RESULT_INVALID +#endif + +#ifndef LV_DRAW_CONVERT_PREMULTIPLY_ARGB8888 + #define LV_DRAW_CONVERT_PREMULTIPLY_ARGB8888(...) LV_RESULT_INVALID +#endif + +#ifndef LV_DRAW_CONVERT_PREMULTIPLY_RGB565A8 + #define LV_DRAW_CONVERT_PREMULTIPLY_RGB565A8(...) LV_RESULT_INVALID +#endif + +#ifndef LV_DRAW_CONVERT_PREMULTIPLY_ARGB8565 + #define LV_DRAW_CONVERT_PREMULTIPLY_ARGB8565(...) LV_RESULT_INVALID +#endif + +/********************** + * GLOBAL FUNCTIONS + **********************/ + +lv_result_t lv_draw_buf_convert_premultiply(lv_draw_buf_t * draw_buf) +{ + LV_ASSERT_NULL(draw_buf); + + /*Premultiply color with alpha, do case by case by judging color format*/ + lv_color_format_t cf = draw_buf->header.cf; + if(LV_COLOR_FORMAT_IS_INDEXED(cf)) { + if(LV_RESULT_INVALID == LV_DRAW_CONVERT_PREMULTIPLY_INDEXED(draw_buf)) { + int size = LV_COLOR_INDEXED_PALETTE_SIZE(cf); + lv_color32_t * palette = (lv_color32_t *)draw_buf->data; + for(int i = 0; i < size; i++) { + lv_color_premultiply(&palette[i]); + } + } + } + else if(cf == LV_COLOR_FORMAT_ARGB8888) { + if(LV_RESULT_INVALID == LV_DRAW_CONVERT_PREMULTIPLY_ARGB8888(draw_buf)) { + uint32_t h = draw_buf->header.h; + uint32_t w = draw_buf->header.w; + uint32_t stride = draw_buf->header.stride; + uint8_t * line = (uint8_t *)draw_buf->data; + for(uint32_t y = 0; y < h; y++) { + lv_color32_t * pixel = (lv_color32_t *)line; + for(uint32_t x = 0; x < w; x++) { + lv_color_premultiply(pixel); + pixel++; + } + line += stride; + } + } + } + else if(cf == LV_COLOR_FORMAT_RGB565A8) { + if(LV_RESULT_INVALID == LV_DRAW_CONVERT_PREMULTIPLY_RGB565A8(draw_buf)) { + uint32_t h = draw_buf->header.h; + uint32_t w = draw_buf->header.w; + uint32_t stride = draw_buf->header.stride; + uint32_t alpha_stride = stride / 2; + uint8_t * line = (uint8_t *)draw_buf->data; + lv_opa_t * alpha = (lv_opa_t *)(line + stride * h); + for(uint32_t y = 0; y < h; y++) { + lv_color16_t * pixel = (lv_color16_t *)line; + for(uint32_t x = 0; x < w; x++) { + lv_color16_premultiply(pixel, alpha[x]); + pixel++; + } + line += stride; + alpha += alpha_stride; + } + } + } + else if(cf == LV_COLOR_FORMAT_ARGB8565) { + if(LV_RESULT_INVALID == LV_DRAW_CONVERT_PREMULTIPLY_ARGB8565(draw_buf)) { + uint32_t h = draw_buf->header.h; + uint32_t w = draw_buf->header.w; + uint32_t stride = draw_buf->header.stride; + uint8_t * line = (uint8_t *)draw_buf->data; + for(uint32_t y = 0; y < h; y++) { + uint8_t * pixel = line; + for(uint32_t x = 0; x < w; x++) { + uint8_t alpha = pixel[2]; + lv_color16_premultiply((lv_color16_t *)pixel, alpha); + pixel += 3; + } + line += stride; + } + } + } + else if(LV_COLOR_FORMAT_IS_ALPHA_ONLY(cf)) { + /*Pass*/ + } + else { + LV_LOG_WARN("draw buf has no alpha, cf: %d", cf); + } + + return LV_RESULT_OK; +} \ No newline at end of file diff --git a/src/draw/convert/lv_draw_buf_convert.h b/src/draw/convert/lv_draw_buf_convert.h new file mode 100644 index 0000000000..6c2d79e91a --- /dev/null +++ b/src/draw/convert/lv_draw_buf_convert.h @@ -0,0 +1,39 @@ +/** + * @file lv_draw_buf_convert.h + * + */ + +#ifndef LV_DRAW_BUF_CONVERT_H +#define LV_DRAW_BUF_CONVERT_H + +#ifdef __cplusplus +extern "C" { +#endif + +#include "../../misc/lv_color.h" +#include "../lv_draw_buf.h" + +/********************* + * DEFINES + *********************/ + +/********************** + * TYPEDEFS + **********************/ + +/********************** + * GLOBAL PROTOTYPES + **********************/ + +/** + * Convert draw_buf to premultiplied format + * @param buf pointer to a draw buf + */ +lv_result_t lv_draw_buf_convert_premultiply(lv_draw_buf_t * buf); + + +#ifdef __cplusplus +} /* extern "C" */ +#endif + +#endif /* LV_DRAW_BUF_CONVERT_H */ \ No newline at end of file diff --git a/src/draw/convert/neon/lv_draw_buf_convert_neon.c b/src/draw/convert/neon/lv_draw_buf_convert_neon.c new file mode 100644 index 0000000000..991f55fb29 --- /dev/null +++ b/src/draw/convert/neon/lv_draw_buf_convert_neon.c @@ -0,0 +1,132 @@ +/** + * @file lv_draw_buf_convert_neon.c + * + */ + +/********************* + * INCLUDES + *********************/ +#include "../../../lv_conf_internal.h" + +#if LV_USE_DRAW_SW_ASM == LV_DRAW_SW_ASM_NEON + +#include +#include "lv_draw_buf_convert_neon.h" + +/********************* + * DEFINES + *********************/ + +/********************** + * STATIC PROTOTYPES + **********************/ + +/********************** + * STATIC FUNCTIONS + **********************/ + +/********************** + * MACROS + **********************/ + +/********************** + * GLOBAL FUNCTIONS + **********************/ + +lv_result_t _lv_draw_buf_convert_premultiply_indexed_neon(lv_draw_buf_t * buf) +{ + lv_draw_buf_t palette_draw_buf; + + LV_ASSERT_NULL(buf); + + if(!LV_COLOR_FORMAT_IS_INDEXED(buf->header.cf)) { + LV_LOG_WARN("Unsupported color format : %d", buf->header.cf); + return LV_RESULT_INVALID; + } + + lv_memcpy(&palette_draw_buf, buf, sizeof(lv_draw_buf_t)); + + palette_draw_buf.header.w = LV_COLOR_INDEXED_PALETTE_SIZE(buf->header.cf); + palette_draw_buf.header.h = 1; + palette_draw_buf.header.cf = LV_COLOR_FORMAT_ARGB8888; + palette_draw_buf.header.stride = 4 * palette_draw_buf.header.w; + + return _lv_draw_buf_convert_premultiply_argb8888_neon(&palette_draw_buf); + +} + +lv_result_t _lv_draw_buf_convert_premultiply_argb8888_neon(lv_draw_buf_t * buf) +{ + LV_ASSERT_NULL(buf); + + uint32_t h = buf->header.h; + uint32_t w = buf->header.w; + uint32_t stride = buf->header.stride; + uint8_t * data = (uint8_t *)buf->data; + + if(buf->header.cf != LV_COLOR_FORMAT_ARGB8888) { + LV_LOG_WARN("Unsupported color format : %d", buf->header.cf); + return LV_RESULT_INVALID; + } + + for(uint32_t y = 0; y < h; y++) { + uint8_t * p = (uint8_t *)data; + uint32_t remaining_pixels = w; + + while(remaining_pixels >= 8) { + uint8x8x4_t rgba = vld4_u8(p); + + uint16x8_t r16 = vmovl_u8(rgba.val[0]); + uint16x8_t g16 = vmovl_u8(rgba.val[1]); + uint16x8_t b16 = vmovl_u8(rgba.val[2]); + uint16x8_t a16 = vmovl_u8(rgba.val[3]); + + rgba.val[0] = vshrn_n_u16(vmulq_u16(r16, a16), 8); + rgba.val[1] = vshrn_n_u16(vmulq_u16(g16, a16), 8); + rgba.val[2] = vshrn_n_u16(vmulq_u16(b16, a16), 8); + + vst4_u8(p, rgba); + + p += 8 * 4; + remaining_pixels -= 8; + } + + if(remaining_pixels >= 4) { + uint8x8x4_t rgba; + rgba = vld4_lane_u8(p, rgba, 0); + rgba = vld4_lane_u8(p + 4, rgba, 1); + rgba = vld4_lane_u8(p + 8, rgba, 2); + rgba = vld4_lane_u8(p + 12, rgba, 3); + + uint16x8_t r16 = vmovl_u8(rgba.val[0]); + uint16x8_t g16 = vmovl_u8(rgba.val[1]); + uint16x8_t b16 = vmovl_u8(rgba.val[2]); + uint16x8_t a16 = vmovl_u8(rgba.val[3]); + + rgba.val[0] = vshrn_n_u16(vmulq_u16(r16, a16), 8); + rgba.val[1] = vshrn_n_u16(vmulq_u16(g16, a16), 8); + rgba.val[2] = vshrn_n_u16(vmulq_u16(b16, a16), 8); + + vst4_lane_u8(p, rgba, 0); + vst4_lane_u8(p + 4, rgba, 1); + vst4_lane_u8(p + 8, rgba, 2); + vst4_lane_u8(p + 12, rgba, 3); + + p += 4 * 4; + remaining_pixels -= 4; + } + + while(remaining_pixels--) { + uint8_t a = p[3]; + p[0] = ((uint16_t)(p[0]) * a) >> 8; + p[1] = ((uint16_t)(p[1]) * a) >> 8; + p[2] = ((uint16_t)(p[2]) * a) >> 8; + p += 4; + } + + data += stride; + } + + return LV_RESULT_OK; +} +#endif /* LV_USE_DRAW_SW_ASM == LV_DRAW_SW_ASM_NEON */ diff --git a/src/draw/convert/neon/lv_draw_buf_convert_neon.h b/src/draw/convert/neon/lv_draw_buf_convert_neon.h new file mode 100644 index 0000000000..d97f61e3fa --- /dev/null +++ b/src/draw/convert/neon/lv_draw_buf_convert_neon.h @@ -0,0 +1,58 @@ +/** + * @file lv_draw_buf_convert_neon.h + * + */ + +#ifndef LV_DRAW_BUF_CONVERT_NEON_H +#define LV_DRAW_BUF_CONVERT_NEON_H + +#ifdef __cplusplus +extern "C" { +#endif + +#include "../../../misc/lv_color.h" +#include "../../lv_draw_buf.h" + +#if LV_USE_DRAW_SW_ASM == LV_DRAW_SW_ASM_NEON + +/********************* + * DEFINES + *********************/ + +/********************** + * TYPEDEFS + **********************/ + +#ifndef LV_DRAW_CONVERT_PREMULTIPLY_INDEXED +#define LV_DRAW_CONVERT_PREMULTIPLY_INDEXED(buf) \ + _lv_draw_buf_convert_premultiply_indexed_neon(buf) +#endif + +#ifndef LV_DRAW_CONVERT_PREMULTIPLY_ARGB8888 +#define LV_DRAW_CONVERT_PREMULTIPLY_ARGB8888(buf) \ + _lv_draw_buf_convert_premultiply_argb8888_neon(buf) +#endif + +/********************** + * GLOBAL PROTOTYPES + **********************/ + +/** + * Convert indexed draw_buf to premultiplied format with neon specific optimizations + * @param buf pointer to a draw buf + */ + +lv_result_t _lv_draw_buf_convert_premultiply_indexed_neon(lv_draw_buf_t * buf); + +/** + * Convert argb8888 draw_buf to premultiplied format with neon specific optimizations + * @param buf pointer to a draw buf + */ +lv_result_t _lv_draw_buf_convert_premultiply_argb8888_neon(lv_draw_buf_t * buf); +#endif /*LV_USE_DRAW_SW_ASM == LV_DRAW_SW_ASM_NEON*/ + +#ifdef __cplusplus +} /* extern "C" */ +#endif + +#endif /* LV_DRAW_BUF_CONVERT_NEON_H */ diff --git a/src/draw/dma2d/lv_draw_dma2d.c b/src/draw/dma2d/lv_draw_dma2d.c index 465de8c113..afac5121db 100644 --- a/src/draw/dma2d/lv_draw_dma2d.c +++ b/src/draw/dma2d/lv_draw_dma2d.c @@ -35,7 +35,7 @@ static int32_t evaluate_cb(lv_draw_unit_t * draw_unit, lv_draw_task_t * task); static int32_t dispatch_cb(lv_draw_unit_t * draw_unit, lv_layer_t * layer); static int32_t delete_cb(lv_draw_unit_t * draw_unit); #if LV_DRAW_DMA2D_ASYNC - static void thread_cb(void * arg); + static int32_t wait_finish_cb(lv_draw_unit_t * u); #endif #if !LV_DRAW_DMA2D_ASYNC static bool check_transfer_completion(void); @@ -64,22 +64,22 @@ void lv_draw_dma2d_init(void) draw_dma2d_unit->base_unit.evaluate_cb = evaluate_cb; draw_dma2d_unit->base_unit.dispatch_cb = dispatch_cb; draw_dma2d_unit->base_unit.delete_cb = delete_cb; +#if LV_DRAW_DMA2D_ASYNC + draw_dma2d_unit->base_unit.wait_for_finish_cb = wait_finish_cb; +#endif draw_dma2d_unit->base_unit.name = "DMA2D"; #if LV_DRAW_DMA2D_ASYNC g_unit = draw_dma2d_unit; - - lv_result_t res = lv_thread_init(&draw_dma2d_unit->thread, "dma2d", LV_DRAW_THREAD_PRIO, thread_cb, 2 * 1024, - draw_dma2d_unit); - LV_ASSERT(res == LV_RESULT_OK); + lv_thread_sync_init(&draw_dma2d_unit->interrupt_signal); #endif /* enable the DMA2D clock */ -#if defined(STM32F4) || defined(STM32F7) || defined(STM32U5) +#if defined(STM32F4) || defined(STM32F7) || defined(STM32U5) || defined(STM32L4) RCC->AHB1ENR |= RCC_AHB1ENR_DMA2DEN; #elif defined(STM32H7) RCC->AHB3ENR |= RCC_AHB3ENR_DMA2DEN; -#elif defined(STM32H7RS) +#elif defined(STM32H7RS) || defined(STM32N6) RCC->AHB5ENR |= RCC_AHB5ENR_DMA2DEN; #else #warning "LVGL can't enable the clock for DMA2D" @@ -102,15 +102,12 @@ void lv_draw_dma2d_deinit(void) RCC->AHB1ENR &= ~RCC_AHB1ENR_DMA2DEN; #elif defined(STM32H7) RCC->AHB3ENR &= ~RCC_AHB3ENR_DMA2DEN; -#elif defined(STM32H7RS) +#elif defined(STM32H7RS) || defined(STM32N6) RCC->AHB5ENR &= ~RCC_AHB5ENR_DMA2DEN; #endif #if LV_DRAW_DMA2D_ASYNC - lv_result_t res = lv_thread_delete(&g_unit->thread); - LV_ASSERT(res == LV_RESULT_OK); - - res = lv_thread_sync_delete(&g_unit->interrupt_signal); + lv_result_t res = lv_thread_sync_delete(&g_unit->interrupt_signal); LV_ASSERT(res == LV_RESULT_OK); g_unit = NULL; @@ -211,72 +208,16 @@ void lv_draw_dma2d_configure_and_start_transfer(const lv_draw_dma2d_configuratio #if LV_DRAW_DMA2D_CACHE void lv_draw_dma2d_invalidate_cache(const lv_draw_dma2d_cache_area_t * mem_area) { - if((SCB->CCR & SCB_CCR_DC_Msk) == 0) return; /* data cache is disabled */ - - uint32_t rows_remaining = mem_area->height; - uint32_t row_addr = (uint32_t)(uintptr_t) mem_area->first_byte; - uint32_t row_end_addr = 0; - - __DSB(); - - while(rows_remaining) { - uint32_t addr = row_addr & ~(__SCB_DCACHE_LINE_SIZE - 1U); - uint32_t cache_lines = ((((row_addr + mem_area->width_bytes - 1) & ~(__SCB_DCACHE_LINE_SIZE - 1U)) - addr) / - __SCB_DCACHE_LINE_SIZE) + 1; - - if(addr == row_end_addr) { - addr += __SCB_DCACHE_LINE_SIZE; - cache_lines--; - } - - while(cache_lines) { - SCB->DCIMVAC = addr; - addr += __SCB_DCACHE_LINE_SIZE; - cache_lines--; - } - - row_end_addr = addr - __SCB_DCACHE_LINE_SIZE; - row_addr += mem_area->stride; - rows_remaining--; - }; - - __DSB(); - __ISB(); + if(SCB->CCR & SCB_CCR_DC_Msk) { + SCB_InvalidateDCache(); + } } void lv_draw_dma2d_clean_cache(const lv_draw_dma2d_cache_area_t * mem_area) { - if((SCB->CCR & SCB_CCR_DC_Msk) == 0) return; /* data cache is disabled */ - - uint32_t rows_remaining = mem_area->height; - uint32_t row_addr = (uint32_t)(uintptr_t) mem_area->first_byte; - uint32_t row_end_addr = 0; - - __DSB(); - - while(rows_remaining) { - uint32_t addr = row_addr & ~(__SCB_DCACHE_LINE_SIZE - 1U); - uint32_t cache_lines = ((((row_addr + mem_area->width_bytes - 1) & ~(__SCB_DCACHE_LINE_SIZE - 1U)) - addr) / - __SCB_DCACHE_LINE_SIZE) + 1; - - if(addr == row_end_addr) { - addr += __SCB_DCACHE_LINE_SIZE; - cache_lines--; - } - - while(cache_lines) { - SCB->DCCMVAC = addr; - addr += __SCB_DCACHE_LINE_SIZE; - cache_lines--; - } - - row_end_addr = addr - __SCB_DCACHE_LINE_SIZE; - row_addr += mem_area->stride; - rows_remaining--; - }; - - __DSB(); - __ISB(); + if(SCB->CCR & SCB_CCR_DC_Msk) { + SCB_CleanDCache(); + } } #endif @@ -344,7 +285,7 @@ static int32_t dispatch_cb(lv_draw_unit_t * draw_unit, lv_layer_t * layer) if(draw_dma2d_unit->task_act) { #if LV_DRAW_DMA2D_ASYNC /*Return immediately if it's busy with draw task*/ - return 0; + return LV_DRAW_UNIT_IDLE; #else if(!check_transfer_completion()) { return LV_DRAW_UNIT_IDLE; @@ -402,29 +343,15 @@ static int32_t dispatch_cb(lv_draw_unit_t * draw_unit, lv_layer_t * layer) return LV_DRAW_UNIT_IDLE; } - void * dest = lv_draw_layer_go_to_xy(layer, - clipped_coords.x1 - layer->buf_area.x1, - clipped_coords.y1 - layer->buf_area.y1); - if(dsc->opa >= LV_OPA_MAX) { - lv_draw_dma2d_opaque_image( - t, - dest, - &clipped_coords, - lv_draw_buf_width_to_stride(lv_area_get_width(&layer->buf_area), dsc->base.layer->color_format)); + lv_draw_dma2d_opaque_image(t, dsc, &t->area); } else { - lv_draw_dma2d_image( - t, - dest, - &clipped_coords, - lv_draw_buf_width_to_stride(lv_area_get_width(&layer->buf_area), dsc->base.layer->color_format)); + lv_draw_dma2d_image(t, dsc, &t->area); } } -#if !LV_DRAW_DMA2D_ASYNC lv_draw_dispatch_request(); -#endif return 1; } @@ -435,23 +362,18 @@ static int32_t delete_cb(lv_draw_unit_t * draw_unit) } #if LV_DRAW_DMA2D_ASYNC -static void thread_cb(void * arg) +static int32_t wait_finish_cb(lv_draw_unit_t * draw_unit) { - lv_draw_dma2d_unit_t * u = arg; + lv_draw_dma2d_unit_t * u = (lv_draw_dma2d_unit_t *) draw_unit; - lv_thread_sync_init(&u->interrupt_signal); + /* If a DMA2D task has been dispatched, wait its interrupt */ + lv_thread_sync_wait(&u->interrupt_signal); - while(1) { - - do { - lv_thread_sync_wait(&u->interrupt_signal); - } while(u->task_act != NULL); - - post_transfer_tasks(u); - lv_draw_dispatch_request(); - } + /* Then cleanup the DMA2D draw unit to accept a new task */ + post_transfer_tasks(u); + return 0; } -#endif +#endif /*LV_DRAW_DMA2D_ASYNC*/ #if !LV_DRAW_DMA2D_ASYNC static bool check_transfer_completion(void) @@ -465,7 +387,7 @@ static void post_transfer_tasks(lv_draw_dma2d_unit_t * u) #if LV_DRAW_DMA2D_CACHE lv_draw_dma2d_invalidate_cache(&u->writing_area); #endif - u->task_act->state = LV_DRAW_TASK_STATE_READY; + u->task_act->state = LV_DRAW_TASK_STATE_FINISHED; u->task_act = NULL; } diff --git a/src/draw/dma2d/lv_draw_dma2d_fill.c b/src/draw/dma2d/lv_draw_dma2d_fill.c index 1c0b3a0fc7..d4ecdb36c1 100644 --- a/src/draw/dma2d/lv_draw_dma2d_fill.c +++ b/src/draw/dma2d/lv_draw_dma2d_fill.c @@ -93,8 +93,9 @@ void lv_draw_dma2d_fill(lv_draw_task_t * t, void * first_pixel, int32_t w, int32 #endif uint32_t output_offset = (stride / cf_size) - w; + lv_draw_dma2d_configuration_t conf = { - .mode = LV_DRAW_DMA2D_MODE_MEMORY_TO_MEMORY_WITH_BLENDING_AND_FIXED_COLOR_FG, + .mode = LV_DRAW_DMA2D_MODE_MEMORY_TO_MEMORY_WITH_BLENDING, .w = w, .h = h, @@ -103,11 +104,16 @@ void lv_draw_dma2d_fill(lv_draw_task_t * t, void * first_pixel, int32_t w, int32 .output_cf = output_cf, .fg_color = lv_color_to_u32(color), + .fg_address = first_pixel, + .fg_offset = output_offset, .fg_alpha_mode = LV_DRAW_DMA2D_ALPHA_MODE_REPLACE_ALPHA_CHANNEL, .fg_alpha = opa, + .fg_cf = LV_DRAW_DMA2D_FGBG_CF_A8, .bg_address = first_pixel, .bg_offset = output_offset, + .bg_alpha_mode = LV_DRAW_DMA2D_ALPHA_MODE_NO_MODIFY_IMAGE_ALPHA_CHANNEL, + .bg_alpha = opa, .bg_cf = (lv_draw_dma2d_fgbg_cf_t) output_cf }; diff --git a/src/draw/dma2d/lv_draw_dma2d_img.c b/src/draw/dma2d/lv_draw_dma2d_img.c index e78bc2b9ce..1b569c677b 100644 --- a/src/draw/dma2d/lv_draw_dma2d_img.c +++ b/src/draw/dma2d/lv_draw_dma2d_img.c @@ -1,5 +1,5 @@ /** - * @file lv_draw_dma2d_image.c + * @file lv_draw_dma2d_img.c * */ @@ -10,6 +10,10 @@ #include "lv_draw_dma2d_private.h" #if LV_USE_DRAW_DMA2D +#include "../lv_draw_image_private.h" +#include "../lv_image_decoder_private.h" +#include "../../misc/lv_area_private.h" + /********************* * DEFINES *********************/ @@ -22,6 +26,14 @@ * STATIC PROTOTYPES **********************/ +static void lv_draw_dma2d_opaque_image_core(lv_draw_task_t * t, const lv_draw_image_dsc_t * draw_dsc, + const lv_image_decoder_dsc_t * decoder_dsc, lv_draw_image_sup_t * sup, + const lv_area_t * img_coords, const lv_area_t * clipped_img_area); + +static void lv_draw_dma2d_image_core(lv_draw_task_t * t, const lv_draw_image_dsc_t * draw_dsc, + const lv_image_decoder_dsc_t * decoder_dsc, lv_draw_image_sup_t * sup, + const lv_area_t * img_coords, const lv_area_t * clipped_img_area); + /********************** * STATIC VARIABLES **********************/ @@ -34,25 +46,60 @@ * GLOBAL FUNCTIONS **********************/ -void lv_draw_dma2d_opaque_image(lv_draw_task_t * t, void * dest_first_pixel, lv_area_t * clipped_coords, - int32_t dest_stride) +void lv_draw_dma2d_opaque_image(lv_draw_task_t * t, const lv_draw_image_dsc_t * draw_dsc, + const lv_area_t * coords) +{ + if(!draw_dsc->tile) { + lv_draw_image_normal_helper(t, draw_dsc, coords, lv_draw_dma2d_opaque_image_core); + } + else { + lv_draw_image_tiled_helper(t, draw_dsc, coords, lv_draw_dma2d_opaque_image_core); + } +} + +void lv_draw_dma2d_image(lv_draw_task_t * t, const lv_draw_image_dsc_t * draw_dsc, + const lv_area_t * coords) { - int32_t w = lv_area_get_width(clipped_coords); - int32_t h = lv_area_get_height(clipped_coords); + if(!draw_dsc->tile) { + lv_draw_image_normal_helper(t, draw_dsc, coords, lv_draw_dma2d_image_core); + } + else { + lv_draw_image_tiled_helper(t, draw_dsc, coords, lv_draw_dma2d_image_core); + } +} - lv_draw_image_dsc_t * dsc = t->draw_dsc; - lv_color_format_t output_cf = dsc->base.layer->color_format; - lv_color_format_t image_cf = dsc->header.cf; +/********************** + * STATIC FUNCTIONS + **********************/ +static void lv_draw_dma2d_opaque_image_core(lv_draw_task_t * t, const lv_draw_image_dsc_t * draw_dsc, + const lv_image_decoder_dsc_t * decoder_dsc, lv_draw_image_sup_t * sup, + const lv_area_t * img_coords, const lv_area_t * clipped_img_area) +{ + LV_UNUSED(sup); + LV_UNUSED(img_coords); + + lv_layer_t * layer = t->target_layer; + + void * dest_first_pixel = lv_draw_layer_go_to_xy(layer, + clipped_img_area->x1 - layer->buf_area.x1, + clipped_img_area->y1 - layer->buf_area.y1); + int32_t dest_stride = lv_draw_buf_width_to_stride(lv_area_get_width(&layer->buf_area), layer->color_format); + + int32_t w = lv_area_get_width(clipped_img_area); + int32_t h = lv_area_get_height(clipped_img_area); + + lv_color_format_t output_cf = layer->color_format; + uint32_t output_cf_size = lv_color_format_get_size(output_cf); lv_draw_dma2d_output_cf_t output_cf_dma2d = lv_draw_dma2d_cf_to_dma2d_output_cf(output_cf); - uint32_t output_cf_size = LV_COLOR_FORMAT_GET_SIZE(output_cf); + const lv_draw_buf_t * decoded = decoder_dsc->decoded; + const uint8_t * src_buf = decoded->data; + uint32_t image_stride = decoded->header.stride; + lv_color_format_t image_cf = decoded->header.cf; lv_draw_dma2d_fgbg_cf_t image_cf_dma2d = (lv_draw_dma2d_fgbg_cf_t) lv_draw_dma2d_cf_to_dma2d_output_cf(image_cf); uint32_t image_cf_size = LV_COLOR_FORMAT_GET_SIZE(image_cf); - - const lv_image_dsc_t * img_dsc = dsc->src; - uint32_t image_stride = img_dsc->header.stride; - if(image_stride == 0) image_stride = image_cf_size * img_dsc->header.w; + if(image_stride == 0) image_stride = image_cf_size * decoded->header.w; #if LV_DRAW_DMA2D_CACHE lv_draw_dma2d_cache_area_t dest_area = { @@ -69,9 +116,9 @@ void lv_draw_dma2d_opaque_image(lv_draw_task_t * t, void * dest_first_pixel, lv_ } #endif - const void * image_first_byte = img_dsc->data - + (image_stride * (clipped_coords->y1 - dsc->image_area.y1)) - + (image_cf_size * (clipped_coords->x1 - dsc->image_area.x1)); + const void * image_first_byte = src_buf + + (image_stride * (clipped_img_area->y1 - draw_dsc->image_area.y1)) + + (image_cf_size * (clipped_img_area->x1 - draw_dsc->image_area.x1)); #if LV_DRAW_DMA2D_CACHE lv_draw_dma2d_cache_area_t src_area = { @@ -121,26 +168,35 @@ void lv_draw_dma2d_opaque_image(lv_draw_task_t * t, void * dest_first_pixel, lv_ lv_draw_dma2d_configure_and_start_transfer(&conf); } -void lv_draw_dma2d_image(lv_draw_task_t * t, void * dest_first_pixel, lv_area_t * clipped_coords, - int32_t dest_stride) +static void lv_draw_dma2d_image_core(lv_draw_task_t * t, const lv_draw_image_dsc_t * draw_dsc, + const lv_image_decoder_dsc_t * decoder_dsc, lv_draw_image_sup_t * sup, + const lv_area_t * img_coords, const lv_area_t * clipped_img_area) { - int32_t w = lv_area_get_width(clipped_coords); - int32_t h = lv_area_get_height(clipped_coords); + LV_UNUSED(sup); + LV_UNUSED(img_coords); + + lv_layer_t * layer = t->target_layer; - lv_draw_image_dsc_t * dsc = t->draw_dsc; - lv_color_format_t output_cf = dsc->base.layer->color_format; - lv_color_format_t image_cf = dsc->header.cf; - lv_opa_t opa = dsc->opa; + void * dest_first_pixel = lv_draw_layer_go_to_xy(layer, + clipped_img_area->x1 - layer->buf_area.x1, + clipped_img_area->y1 - layer->buf_area.y1); + int32_t dest_stride = lv_draw_buf_width_to_stride(lv_area_get_width(&layer->buf_area), layer->color_format); + int32_t w = lv_area_get_width(clipped_img_area); + int32_t h = lv_area_get_height(clipped_img_area); + + lv_color_format_t output_cf = layer->color_format; + uint32_t output_cf_size = lv_color_format_get_size(output_cf); lv_draw_dma2d_output_cf_t output_cf_dma2d = lv_draw_dma2d_cf_to_dma2d_output_cf(output_cf); - uint32_t output_cf_size = LV_COLOR_FORMAT_GET_SIZE(output_cf); + const lv_draw_buf_t * decoded = decoder_dsc->decoded; + const uint8_t * src_buf = decoded->data; + uint32_t image_stride = decoded->header.stride; + lv_color_format_t image_cf = decoded->header.cf; + lv_opa_t opa = draw_dsc->opa; lv_draw_dma2d_fgbg_cf_t image_cf_dma2d = (lv_draw_dma2d_fgbg_cf_t) lv_draw_dma2d_cf_to_dma2d_output_cf(image_cf); uint32_t image_cf_size = LV_COLOR_FORMAT_GET_SIZE(image_cf); - - const lv_image_dsc_t * img_dsc = dsc->src; - uint32_t image_stride = img_dsc->header.stride; - if(image_stride == 0) image_stride = image_cf_size * img_dsc->header.w; + if(image_stride == 0) image_stride = image_cf_size * decoded->header.w; #if LV_DRAW_DMA2D_CACHE lv_draw_dma2d_cache_area_t dest_area = { @@ -155,9 +211,9 @@ void lv_draw_dma2d_image(lv_draw_task_t * t, void * dest_first_pixel, lv_area_t lv_draw_dma2d_clean_cache(&dest_area); #endif - const void * image_first_byte = img_dsc->data - + (image_stride * (clipped_coords->y1 - dsc->image_area.y1)) - + (image_cf_size * (clipped_coords->x1 - dsc->image_area.x1)); + const void * image_first_byte = src_buf + + (image_stride * (clipped_img_area->y1 - draw_dsc->image_area.y1)) + + (image_cf_size * (clipped_img_area->x1 - draw_dsc->image_area.x1)); #if LV_DRAW_DMA2D_CACHE lv_draw_dma2d_cache_area_t src_area = { @@ -203,8 +259,4 @@ void lv_draw_dma2d_image(lv_draw_task_t * t, void * dest_first_pixel, lv_area_t lv_draw_dma2d_configure_and_start_transfer(&conf); } -/********************** - * STATIC FUNCTIONS - **********************/ - #endif /*LV_USE_DRAW_DMA2D*/ diff --git a/src/draw/dma2d/lv_draw_dma2d_private.h b/src/draw/dma2d/lv_draw_dma2d_private.h index 1326351cd3..1ba8d97d58 100644 --- a/src/draw/dma2d/lv_draw_dma2d_private.h +++ b/src/draw/dma2d/lv_draw_dma2d_private.h @@ -31,7 +31,7 @@ extern "C" { #define LV_DRAW_DMA2D_ASYNC 0 #endif -#if defined(__CORTEX_M) && (__CORTEX_M == 7) +#if defined(__CORTEX_M) && ((__CORTEX_M == 7) || (__CORTEX_M == 55)) #define LV_DRAW_DMA2D_CACHE 1 #else #define LV_DRAW_DMA2D_CACHE 0 @@ -120,7 +120,6 @@ typedef struct { lv_draw_dma2d_cache_area_t writing_area; #endif #if LV_DRAW_DMA2D_ASYNC - lv_thread_t thread; lv_thread_sync_t interrupt_signal; #endif } lv_draw_dma2d_unit_t; @@ -131,10 +130,10 @@ typedef struct { void lv_draw_dma2d_opaque_fill(lv_draw_task_t * t, void * first_pixel, int32_t w, int32_t h, int32_t stride); void lv_draw_dma2d_fill(lv_draw_task_t * t, void * first_pixel, int32_t w, int32_t h, int32_t stride); -void lv_draw_dma2d_opaque_image(lv_draw_task_t * t, void * dest_first_pixel, lv_area_t * clipped_coords, - int32_t dest_stride); -void lv_draw_dma2d_image(lv_draw_task_t * t, void * dest_first_pixel, lv_area_t * clipped_coords, - int32_t dest_stride); +void lv_draw_dma2d_opaque_image(lv_draw_task_t * t, const lv_draw_image_dsc_t * draw_dsc, + const lv_area_t * coords); +void lv_draw_dma2d_image(lv_draw_task_t * t, const lv_draw_image_dsc_t * draw_dsc, + const lv_area_t * coords); lv_draw_dma2d_output_cf_t lv_draw_dma2d_cf_to_dma2d_output_cf(lv_color_format_t cf); uint32_t lv_draw_dma2d_color_to_dma2d_color(lv_draw_dma2d_output_cf_t cf, lv_color_t color); void lv_draw_dma2d_configure_and_start_transfer(const lv_draw_dma2d_configuration_t * conf); diff --git a/src/draw/espressif/ppa/lv_draw_ppa.c b/src/draw/espressif/ppa/lv_draw_ppa.c new file mode 100644 index 0000000000..17a3945493 --- /dev/null +++ b/src/draw/espressif/ppa/lv_draw_ppa.c @@ -0,0 +1,255 @@ +/** + * @file lv_draw_ppa.c + * + */ + +/********************* +* INCLUDES +*********************/ + +#include "lv_draw_ppa_private.h" +#include "lv_draw_ppa.h" + +#if LV_USE_PPA + +/********************* +* DEFINES +*********************/ + +#define DRAW_UNIT_ID_PPA 80 +#define DRAW_UNIT_PPA_PREF_SCORE 70 + +/********************** +* STATIC PROTOTYPES +**********************/ + +static int32_t ppa_evaluate(lv_draw_unit_t * draw_unit, lv_draw_task_t * task); +static int32_t ppa_dispatch(lv_draw_unit_t * draw_unit, lv_layer_t * layer); +static int32_t ppa_delete(lv_draw_unit_t * draw_unit); +static void ppa_execute_drawing(lv_draw_ppa_unit_t * u); +static bool ppa_isr(ppa_client_handle_t ppa_client, ppa_event_data_t * event_data, void * user_data); + +#if LV_PPA_NONBLOCKING_OPS + static void ppa_thread(void * arg); +#endif + +static bool g_ppa_complete = true; + +/********************** +* GLOBAL FUNCTIONS +**********************/ + +void lv_draw_ppa_init(void) +{ + esp_err_t res; + ppa_client_config_t cfg = {0}; + ppa_event_callbacks_t ppa_cbs = { + .on_trans_done = ppa_isr, + + }; + + /* Create draw unit */ + lv_draw_buf_ppa_init_handlers(); + lv_draw_ppa_unit_t * draw_ppa_unit = lv_draw_create_unit(sizeof(lv_draw_ppa_unit_t)); + draw_ppa_unit->base_unit.evaluate_cb = ppa_evaluate; + draw_ppa_unit->base_unit.dispatch_cb = ppa_dispatch; + draw_ppa_unit->base_unit.delete_cb = ppa_delete; + draw_ppa_unit->base_unit.name = "ESP_PPA"; + + /* Register SRM client */ + cfg.oper_type = PPA_OPERATION_SRM; + cfg.max_pending_trans_num = 8; + cfg.data_burst_length = PPA_DATA_BURST_LENGTH_128; + + res = ppa_register_client(&cfg, &draw_ppa_unit->srm_client); + LV_ASSERT(res == ESP_OK); + + /* Register Fill client */ + cfg.oper_type = PPA_OPERATION_FILL; + cfg.data_burst_length = PPA_DATA_BURST_LENGTH_128; + res = ppa_register_client(&cfg, &draw_ppa_unit->fill_client); + LV_ASSERT(res == ESP_OK); + + /* Register Blend client */ + cfg.oper_type = PPA_OPERATION_BLEND; + cfg.data_burst_length = PPA_DATA_BURST_LENGTH_32; + + res = ppa_register_client(&cfg, &draw_ppa_unit->blend_client); + LV_ASSERT(res == ESP_OK); + + ppa_client_register_event_callbacks(draw_ppa_unit->srm_client, &ppa_cbs); + ppa_client_register_event_callbacks(draw_ppa_unit->fill_client, &ppa_cbs); + ppa_client_register_event_callbacks(draw_ppa_unit->blend_client, &ppa_cbs); + +#if LV_PPA_NONBLOCKING_OPS + lv_result_t lv_res = lv_thread_init(&draw_ppa_unit->thread, "ppa_thread", LV_DRAW_THREAD_PRIO, ppa_thread, 8192, + draw_ppa_unit); + LV_ASSERT(lv_res == LV_RESULT_OK); +#endif + +} + +void lv_draw_ppa_deinit(void) +{ + /* No global deinit required */ +} + +/********************** +* STATIC FUNCTIONS +**********************/ + +static bool ppa_isr(ppa_client_handle_t ppa_client, ppa_event_data_t * event_data, void * user_data) +{ + g_ppa_complete = true; + +#if LV_PPA_NONBLOCKING_OPS + lv_draw_ppa_unit_t * u = (lv_draw_ppa_unit_t *)user_data; + lv_thread_sync_signal_isr(&u->interrupt_signal); +#endif + + return false; +} + +static int32_t ppa_evaluate(lv_draw_unit_t * u, lv_draw_task_t * t) +{ + LV_UNUSED(u); + const lv_draw_dsc_base_t * base = (lv_draw_dsc_base_t *)t->draw_dsc; + + if(!ppa_dest_cf_supported(base->layer->color_format)) return 0; + + switch(t->type) { + case LV_DRAW_TASK_TYPE_FILL: { + const lv_draw_fill_dsc_t * dsc = (lv_draw_fill_dsc_t *)t->draw_dsc; + if((dsc->radius != 0 || dsc->grad.dir != LV_GRAD_DIR_NONE)) return 0; + if(dsc->opa <= (lv_opa_t)LV_OPA_MAX) return 0; + + if(t->preference_score > DRAW_UNIT_PPA_PREF_SCORE) { + t->preference_score = DRAW_UNIT_PPA_PREF_SCORE; + t->preferred_draw_unit_id = DRAW_UNIT_ID_PPA; + } + return 1; + } + +#if LV_USE_PPA_IMG + case LV_DRAW_TASK_TYPE_IMAGE: { + lv_draw_image_dsc_t * dsc = t->draw_dsc; + if(!(dsc->header.cf < LV_COLOR_FORMAT_PROPRIETARY_START + && dsc->clip_radius == 0 + && dsc->bitmap_mask_src == NULL + && dsc->sup == NULL + && dsc->tile == 0 + && dsc->blend_mode == LV_BLEND_MODE_NORMAL + && dsc->recolor_opa <= LV_OPA_MIN + && dsc->opa <= (lv_opa_t)LV_OPA_MAX + && dsc->skew_y == 0 + && dsc->skew_x == 0 + && dsc->scale_x == 256 + && dsc->scale_y == 256 + && dsc->rotation == 0 + && lv_image_src_get_type(dsc->src) == LV_IMAGE_SRC_VARIABLE + && (dsc->header.cf == LV_COLOR_FORMAT_RGB888 + || dsc->header.cf == LV_COLOR_FORMAT_RGB565) + && (dsc->base.layer->color_format == LV_COLOR_FORMAT_RGB888 + || dsc->base.layer->color_format == LV_COLOR_FORMAT_RGB565))) { + return 0; + } + + if(t->preference_score > DRAW_UNIT_PPA_PREF_SCORE) { + t->preference_score = DRAW_UNIT_PPA_PREF_SCORE; + t->preferred_draw_unit_id = DRAW_UNIT_ID_PPA; + } + return 1; + } +#endif + default: + return 0; + } +} + +static int32_t ppa_dispatch(lv_draw_unit_t * draw_unit, lv_layer_t * layer) +{ + lv_draw_ppa_unit_t * u = (lv_draw_ppa_unit_t *)draw_unit; + if(u->task_act) { + if(!g_ppa_complete) { + return LV_DRAW_UNIT_IDLE; + } + else { + u->task_act->state = LV_DRAW_TASK_STATE_FINISHED; + u->task_act = NULL; + } + } + + lv_draw_task_t * t = lv_draw_get_available_task(layer, NULL, DRAW_UNIT_ID_PPA); + if(!t || t->preferred_draw_unit_id != DRAW_UNIT_ID_PPA) return LV_DRAW_UNIT_IDLE; + if(!lv_draw_layer_alloc_buf(layer)) return LV_DRAW_UNIT_IDLE; + + t->state = LV_DRAW_TASK_STATE_IN_PROGRESS; + u->task_act = t; + u->task_act->draw_unit = draw_unit; + + ppa_execute_drawing(u); + +#if !LV_PPA_NONBLOCKING_OPS + u->task_act->state = LV_DRAW_TASK_STATE_FINISHED; + u->task_act = NULL; + lv_draw_dispatch_request(); +#endif + + return 1; +} + +static int32_t ppa_delete(lv_draw_unit_t * draw_unit) +{ + lv_draw_ppa_unit_t * u = (lv_draw_ppa_unit_t *)draw_unit; + ppa_unregister_client(u->srm_client); + ppa_unregister_client(u->fill_client); + ppa_unregister_client(u->blend_client); + return 0; +} + +static void ppa_execute_drawing(lv_draw_ppa_unit_t * u) +{ + lv_draw_task_t * t = u->task_act; + lv_layer_t * layer = t->target_layer; + lv_draw_buf_t * buf = layer->draw_buf; + lv_area_t area; + lv_area_t draw_area; + + if(!lv_area_intersect(&area, &t->area, &t->clip_area)) return; + + lv_area_move(&draw_area, -layer->buf_area.x1, -layer->buf_area.y1); + lv_draw_buf_invalidate_cache(buf, &draw_area); + + switch(t->type) { + case LV_DRAW_TASK_TYPE_FILL: + g_ppa_complete = false; + lv_draw_ppa_fill(t, (lv_draw_fill_dsc_t *)t->draw_dsc, &area); + break; + case LV_DRAW_TASK_TYPE_IMAGE: + g_ppa_complete = false; + lv_draw_ppa_img(t, (lv_draw_image_dsc_t *)t->draw_dsc, &area); + break; + default: + break; + } +} + +#if LV_PPA_NONBLOCKING_OPS +static void ppa_thread(void * arg) +{ + lv_draw_ppa_unit_t * u = arg; + lv_thread_sync_init(&u->interrupt_signal); + + while(1) { + do { + lv_thread_sync_wait(&u->interrupt_signal); + } while(u->task_act != NULL); + + u->task_act->state = LV_DRAW_TASK_STATE_FINISHED; + u->task_act = NULL; + lv_draw_dispatch_request(); + } +} +#endif + +#endif /*LV_USE_PPA*/ diff --git a/src/draw/espressif/ppa/lv_draw_ppa.h b/src/draw/espressif/ppa/lv_draw_ppa.h new file mode 100644 index 0000000000..542b0fed9e --- /dev/null +++ b/src/draw/espressif/ppa/lv_draw_ppa.h @@ -0,0 +1,57 @@ +/** + * @file lv_draw_ppa.h + * + */ + +#ifndef LV_DRAW_PPA_H +#define LV_DRAW_PPA_H + +#ifdef __cplusplus +extern "C" { +#endif + +/********************* + * INCLUDES + *********************/ + +#include "../../../lv_conf_internal.h" + +#if LV_USE_PPA + +#include "../../lv_draw_private.h" +#include "../../../display/lv_display_private.h" +#include "../../../misc/lv_area_private.h" + +/********************* + * DEFINES + *********************/ + +/********************** + * TYPEDEFS + **********************/ + +/********************** + * GLOBAL PROTOTYPES + **********************/ + +void lv_draw_ppa_init(void); +void lv_draw_ppa_deinit(void); +void lv_draw_buf_ppa_init_handlers(void); + +void lv_draw_ppa_fill(lv_draw_task_t * t, const lv_draw_fill_dsc_t * dsc, + const lv_area_t * coords); + +void lv_draw_ppa_img(lv_draw_task_t * t, const lv_draw_image_dsc_t * dsc, + const lv_area_t * coords); + +/********************** + * MACROS + **********************/ + +#endif /* LV_USE_PPA */ + +#ifdef __cplusplus +} /*extern "C"*/ +#endif + +#endif /* LV_DRAW_PPA_H */ diff --git a/src/draw/espressif/ppa/lv_draw_ppa_buf.c b/src/draw/espressif/ppa/lv_draw_ppa_buf.c new file mode 100644 index 0000000000..1ec6d59a64 --- /dev/null +++ b/src/draw/espressif/ppa/lv_draw_ppa_buf.c @@ -0,0 +1,52 @@ +/** + * @file lv_draw_ppa_buf.c + * + */ + +/********************* + * INCLUDES + *********************/ +#include "lv_draw_ppa_private.h" +#include "lv_draw_ppa.h" + +#if LV_USE_PPA +#include LV_STDINT_INCLUDE +#include "../../lv_draw_buf_private.h" + +/********************* + * DEFINES + *********************/ + +/********************** + * TYPEDEFS + *********************/ + +/********************** + * STATIC PROTOTYPES + *********************/ +static void invalidate_cache(const lv_draw_buf_t * draw_buf, const lv_area_t * area); + +/********************** + * GLOBAL FUNCTIONS + *********************/ + +void lv_draw_buf_ppa_init_handlers(void) +{ + lv_draw_buf_handlers_t * handlers = lv_draw_buf_get_handlers(); + lv_draw_buf_handlers_t * image_handlers = lv_draw_buf_get_image_handlers(); + + handlers->invalidate_cache_cb = invalidate_cache; + image_handlers->invalidate_cache_cb = invalidate_cache; +} + +/********************** + * STATIC FUNCTIONS + *********************/ + +static void invalidate_cache(const lv_draw_buf_t * draw_buf, const lv_area_t * area) +{ + esp_cache_msync((void *)PPA_PTR_ALIGN_DOWN(draw_buf->data, CONFIG_CACHE_L1_CACHE_LINE_SIZE), + PPA_ALIGN_DOWN(draw_buf->data_size, CONFIG_CACHE_L1_CACHE_LINE_SIZE), + ESP_CACHE_MSYNC_FLAG_DIR_C2M | ESP_CACHE_MSYNC_FLAG_TYPE_DATA); +} +#endif /* LV_USE_PPA */ diff --git a/src/draw/espressif/ppa/lv_draw_ppa_fill.c b/src/draw/espressif/ppa/lv_draw_ppa_fill.c new file mode 100644 index 0000000000..77e322a9dd --- /dev/null +++ b/src/draw/espressif/ppa/lv_draw_ppa_fill.c @@ -0,0 +1,48 @@ +/** + * @file lv_draw_ppa_fill.c + * + */ + +#include "lv_draw_ppa_private.h" +#include "lv_draw_ppa.h" + +#if LV_USE_PPA + +void lv_draw_ppa_fill(lv_draw_task_t * t, const lv_draw_fill_dsc_t * dsc, + const lv_area_t * coords) +{ + lv_draw_ppa_unit_t * u = (lv_draw_ppa_unit_t *)t->draw_unit; + lv_draw_buf_t * draw_buf = t->target_layer->draw_buf; + int width = lv_area_get_width(coords); + int height = lv_area_get_height(coords); + + if(width <= 0 || height <= 0) { + LV_LOG_WARN("Invalid draw area for filling!"); + return; + } + + ppa_fill_oper_config_t cfg = { + .fill_argb_color.val = lv_color_to_u32(dsc->color), + .fill_block_w = width, + .fill_block_h = height, + .out = { + .buffer = draw_buf->data, + .buffer_size = draw_buf->data_size, + .pic_w = width, + .pic_h = height, + .block_offset_x = 0, + .block_offset_y = 0, + .fill_cm = lv_color_format_to_ppa_fill(draw_buf->header.cf), + }, + + .mode = PPA_TRANS_MODE_NON_BLOCKING, + .user_data = u, + }; + + esp_err_t ret = ppa_do_fill(u->fill_client, &cfg); + if(ret != ESP_OK) { + LV_LOG_ERROR("PPA fill failed: %d", ret); + } +} + +#endif /* LV_USE_PPA */ diff --git a/src/draw/espressif/ppa/lv_draw_ppa_img.c b/src/draw/espressif/ppa/lv_draw_ppa_img.c new file mode 100644 index 0000000000..8235ad4ff4 --- /dev/null +++ b/src/draw/espressif/ppa/lv_draw_ppa_img.c @@ -0,0 +1,77 @@ +/** + * @file lv_draw_ppa_img.c + * + */ + +#include "lv_draw_ppa_private.h" +#include "lv_draw_ppa.h" + +#if LV_USE_PPA + +void lv_draw_ppa_img(lv_draw_task_t * t, const lv_draw_image_dsc_t * dsc, + const lv_area_t * coords) +{ + if(dsc->opa <= (lv_opa_t)LV_OPA_MIN) { + return; + } + + lv_draw_ppa_unit_t * u = (lv_draw_ppa_unit_t *)t->draw_unit; + lv_draw_buf_t * draw_buf = t->target_layer->draw_buf; + const lv_image_dsc_t * img_dsc = dsc->src; + int width = lv_area_get_width(coords); + int height = lv_area_get_height(coords); + + ppa_blend_oper_config_t cfg = { + .in_bg = { + .buffer = (void *)draw_buf->data, + .pic_w = draw_buf->header.w, + .pic_h = draw_buf->header.h, + .block_w = width, + .block_h = height, + .block_offset_x = 0, + .block_offset_y = 0, + .blend_cm = lv_color_format_to_ppa_blend(draw_buf->header.cf), + }, + .bg_rgb_swap = false, + .bg_byte_swap = false, + .bg_alpha_update_mode = PPA_ALPHA_NO_CHANGE, + .bg_alpha_fix_val = 0, + .bg_ck_en = false, + + .in_fg = { + .buffer = (void *)img_dsc->data, + .pic_w = width, + .pic_h = height, + .block_w = width, + .block_h = height, + .block_offset_x = 0, + .block_offset_y = 0, + .blend_cm = lv_color_format_to_ppa_blend(dsc->header.cf), + }, + .fg_rgb_swap = false, + .fg_byte_swap = false, + .fg_alpha_update_mode = PPA_ALPHA_NO_CHANGE, + .fg_alpha_fix_val = 0xFF, + .fg_ck_en = false, + + .out = { + .buffer = draw_buf->data, + .buffer_size = PPA_ALIGN_UP(draw_buf->data_size, CONFIG_CACHE_L1_CACHE_LINE_SIZE), + .pic_w = draw_buf->header.w, + .pic_h = draw_buf->header.h, + .block_offset_x = 0, + .block_offset_y = 0, + .blend_cm = lv_color_format_to_ppa_blend(draw_buf->header.cf), + }, + + .mode = PPA_TRANS_MODE_NON_BLOCKING, + .user_data = u, + }; + + esp_err_t ret = ppa_do_blend(u->blend_client, &cfg); + if(ret != ESP_OK) { + LV_LOG_WARN("PPA draw_img blend failed: %d", ret); + } +} + +#endif /* LV_USE_PPA */ diff --git a/src/draw/espressif/ppa/lv_draw_ppa_private.h b/src/draw/espressif/ppa/lv_draw_ppa_private.h new file mode 100644 index 0000000000..0e6a3cf1b5 --- /dev/null +++ b/src/draw/espressif/ppa/lv_draw_ppa_private.h @@ -0,0 +1,185 @@ +/** + * @file lv_draw_ppa_private.h + * + */ + +#ifndef LV_DRAW_PPA_PRIVATE_H +#define LV_DRAW_PPA_PRIVATE_H + +#ifdef __cplusplus +extern "C" { +#endif + +/********************* +* INCLUDES +*********************/ +#include "../../../lv_conf_internal.h" + +#if LV_USE_PPA +#if LV_PPA_NONBLOCKING_OPS +#error "PPA draw in nonblocking is experimental and not supported yet, please make it to 0!" +#endif + +#ifndef LV_PPA_NONBLOCKING_OPS +#define LV_PPA_NONBLOCKING_OPS 0 +#endif + +#include LV_STDDEF_INCLUDE +#include LV_STDBOOL_INCLUDE +#include LV_STDINT_INCLUDE + +#include "../../../misc/lv_color.h" +#include "../../../misc/lv_log.h" +#include "../../lv_draw_private.h" +#include "../../../display/lv_display_private.h" +#include "../../../misc/lv_area_private.h" + +/* The ppa driver depends heavily on the esp-idf headers*/ +#include "sdkconfig.h" + +#if CONFIG_LV_ATTRIBUTE_MEM_ALIGN_SIZE != CONFIG_CACHE_L1_CACHE_LINE_SIZE || CONFIG_LV_DRAW_BUF_ALIGN != CONFIG_CACHE_L1_CACHE_LINE_SIZE +#error "For using PPA buffers need to be aligned to 64-byte boundary!" +#endif + + +#ifndef CONFIG_SOC_PPA_SUPPORTED +#error "This SoC does not support PPA" +#endif + +#include "driver/ppa.h" +#include "esp_heap_caps.h" +#include "esp_err.h" +#include "hal/color_hal.h" +#include "esp_cache.h" +#include "esp_log.h" +/********************* +* DEFINES +*********************/ + +/********************** +* TYPEDEFS +**********************/ +typedef struct lv_draw_ppa_unit { + lv_draw_unit_t base_unit; + lv_draw_task_t * task_act; + ppa_client_handle_t srm_client; + ppa_client_handle_t fill_client; + ppa_client_handle_t blend_client; + uint8_t * buf; +#if LV_PPA_NONBLOCKING_OPS + lv_thread_t thread; + lv_thread_sync_t interrupt_signal; +#endif +} lv_draw_ppa_unit_t; + +/********************** +* STATIC PROTOTYPES +**********************/ + +/********************** +* GLOBAL PROTOTYPES +**********************/ + +/********************** +* MACROS +**********************/ + +/********************** +* STATIC FUNCTIONS +**********************/ + +static inline bool ppa_src_cf_supported(lv_color_format_t cf) +{ + bool is_cf_supported = false; + + switch(cf) { + case LV_COLOR_FORMAT_RGB565: + case LV_COLOR_FORMAT_ARGB8888: + case LV_COLOR_FORMAT_XRGB8888: + is_cf_supported = true; + break; + default: + break; + } + + return is_cf_supported; +} + +static inline bool ppa_dest_cf_supported(lv_color_format_t cf) +{ + bool is_cf_supported = false; + + switch(cf) { + case LV_COLOR_FORMAT_RGB565: + case LV_COLOR_FORMAT_RGB888: + case LV_COLOR_FORMAT_ARGB8888: + case LV_COLOR_FORMAT_XRGB8888: + is_cf_supported = true; + break; + default: + break; + } + + return is_cf_supported; +} + +static inline ppa_fill_color_mode_t lv_color_format_to_ppa_fill(lv_color_format_t lv_fmt) +{ + switch(lv_fmt) { + case LV_COLOR_FORMAT_RGB565: + return PPA_FILL_COLOR_MODE_RGB565; + case LV_COLOR_FORMAT_RGB888: + return PPA_FILL_COLOR_MODE_RGB888; + case LV_COLOR_FORMAT_ARGB8888: + case LV_COLOR_FORMAT_XRGB8888: + return PPA_FILL_COLOR_MODE_ARGB8888; + default: + return PPA_FILL_COLOR_MODE_RGB565; + } +} + +static inline ppa_blend_color_mode_t lv_color_format_to_ppa_blend(lv_color_format_t lv_fmt) +{ + switch(lv_fmt) { + case LV_COLOR_FORMAT_RGB565: + return PPA_BLEND_COLOR_MODE_RGB565; + case LV_COLOR_FORMAT_RGB888: + return PPA_BLEND_COLOR_MODE_RGB888; + case LV_COLOR_FORMAT_ARGB8888: + case LV_COLOR_FORMAT_XRGB8888: + return PPA_BLEND_COLOR_MODE_ARGB8888; + default: + return PPA_BLEND_COLOR_MODE_RGB565; + } +} + +static inline ppa_srm_color_mode_t lv_color_format_to_ppa_srm(lv_color_format_t lv_fmt) +{ + switch(lv_fmt) { + case LV_COLOR_FORMAT_RGB565: + return PPA_SRM_COLOR_MODE_RGB565; + case LV_COLOR_FORMAT_RGB888: + return PPA_SRM_COLOR_MODE_RGB888; + case LV_COLOR_FORMAT_XRGB8888: + case LV_COLOR_FORMAT_ARGB8888: + return PPA_SRM_COLOR_MODE_ARGB8888; + default: + return PPA_SRM_COLOR_MODE_RGB565; + } +} + +#define PPA_ALIGN_UP(x, align) ((((x) + (align) - 1) / (align)) * (align)) +#define PPA_PTR_ALIGN_UP(p, align) \ + ((void*)(((uintptr_t)(p) + (uintptr_t)((align) - 1)) & ~(uintptr_t)((align) - 1))) + +#define PPA_ALIGN_DOWN(x, align) ((((x) - (align) - 1) / (align)) * (align)) +#define PPA_PTR_ALIGN_DOWN(p, align) \ + ((void*)(((uintptr_t)(p) - (uintptr_t)((align) - 1)) & ~(uintptr_t)((align) - 1))) + +#endif /* LV_USE_PPA */ + +#ifdef __cplusplus +} /*extern "C"*/ +#endif + +#endif /* LV_DRAW_PPA_PRIVATE_H */ diff --git a/src/draw/eve/lv_draw_eve.c b/src/draw/eve/lv_draw_eve.c new file mode 100644 index 0000000000..2ba2074574 --- /dev/null +++ b/src/draw/eve/lv_draw_eve.c @@ -0,0 +1,164 @@ +/** + * @file lv_draw_eve.c + * + */ + +/* Created on: 3 dic 2023 + * Author: juanj + * + * Modified by LVGL + */ + +/********************* + * INCLUDES + *********************/ + +#include "lv_draw_eve_private.h" +#if LV_USE_DRAW_EVE + +#include "../../core/lv_refr.h" +#include "../../display/lv_display_private.h" +#include "../../stdlib/lv_string.h" +#include "lv_draw_eve_ram_g.h" +#include "lv_draw_eve.h" +#include "lv_eve.h" + +/********************* + * DEFINES + *********************/ + +#define DRAW_UNIT_ID_EVE 9 + +/********************** + * TYPEDEFS + **********************/ + +/********************** + * STATIC PROTOTYPES + **********************/ +static void eve_execute_drawing(lv_draw_eve_unit_t * u); + +static int32_t eve_dispatch(lv_draw_unit_t * draw_unit, lv_layer_t * layer); + +static int32_t eve_evaluate(lv_draw_unit_t * draw_unit, lv_draw_task_t * task); + +static void disp_delete_cb(lv_event_t * e); + +/********************** + * GLOBAL PROTOTYPES + **********************/ + +/********************** + * STATIC VARIABLES + **********************/ + +/********************** + * MACROS + **********************/ + +/********************** + * GLOBAL FUNCTIONS + **********************/ + +void lv_draw_eve_init(void) +{ + lv_draw_eve_unit_t * draw_eve_unit = lv_draw_create_unit(sizeof(lv_draw_eve_unit_t)); + draw_eve_unit->base_unit.dispatch_cb = eve_dispatch; + draw_eve_unit->base_unit.evaluate_cb = eve_evaluate; + + lv_draw_eve_unit_g = draw_eve_unit; +} + +void lv_draw_eve_set_display_data(lv_display_t * disp, const lv_draw_eve_parameters_t * params, + lv_draw_eve_operation_cb_t op_cb) +{ + if(lv_draw_eve_unit_g == NULL) { + LV_LOG_WARN("lv_draw_eve is not initialized."); + return; + } + + lv_draw_eve_unit_g->disp = disp; + lv_draw_eve_unit_g->params = *params; /* make a copy */ + lv_draw_eve_unit_g->op_cb = op_cb; + + lv_display_add_event_cb(disp, disp_delete_cb, LV_EVENT_DELETE, NULL); +} + +/********************** + * STATIC FUNCTIONS + **********************/ + +static int32_t eve_dispatch(lv_draw_unit_t * draw_unit, lv_layer_t * layer) +{ + lv_draw_eve_unit_t * draw_eve_unit = (lv_draw_eve_unit_t *) draw_unit; + + lv_draw_task_t * t = NULL; + t = lv_draw_get_next_available_task(layer, NULL, DRAW_UNIT_ID_EVE); + if(t == NULL) return LV_DRAW_UNIT_IDLE; + + + t->state = LV_DRAW_TASK_STATE_IN_PROGRESS; + draw_eve_unit->task_act = t; + + eve_execute_drawing(draw_eve_unit); + + draw_eve_unit->task_act->state = LV_DRAW_TASK_STATE_FINISHED; + draw_eve_unit->task_act = NULL; + + /*The draw unit is free now. Request a new dispatching as it can get a new task*/ + lv_draw_dispatch_request(); + + + return 1; +} + +static int32_t eve_evaluate(lv_draw_unit_t * draw_unit, lv_draw_task_t * task) +{ + LV_UNUSED(draw_unit); + + if(((lv_draw_dsc_base_t *)task->draw_dsc)->user_data == NULL) { + task->preference_score = 0; + task->preferred_draw_unit_id = DRAW_UNIT_ID_EVE; + } + return 0; +} + +static void eve_execute_drawing(lv_draw_eve_unit_t * u) +{ + lv_draw_task_t * t = u->task_act; + + switch(t->type) { + case LV_DRAW_TASK_TYPE_LINE: + lv_draw_eve_line(t, t->draw_dsc); + break; + case LV_DRAW_TASK_TYPE_BORDER: + lv_draw_eve_border(t, t->draw_dsc, &t->area); + break; + case LV_DRAW_TASK_TYPE_FILL: + lv_draw_eve_fill(t, t->draw_dsc, &t->area); + break; + case LV_DRAW_TASK_TYPE_IMAGE: + lv_draw_eve_image(t, t->draw_dsc, &t->area); + break; + case LV_DRAW_TASK_TYPE_LABEL: + lv_draw_eve_label(t, t->draw_dsc, &t->area); + break; + case LV_DRAW_TASK_TYPE_ARC: + lv_draw_eve_arc(t, t->draw_dsc, &t->area); + break; + case LV_DRAW_TASK_TYPE_TRIANGLE: + lv_draw_eve_triangle(t, t->draw_dsc); + break; + default: + break; + } +} + +static void disp_delete_cb(lv_event_t * e) +{ + lv_draw_eve_unit_g->disp = NULL; + lv_draw_eve_unit_g = NULL; +} + + +#endif /*LV_USE_DRAW_EVE*/ diff --git a/src/draw/eve/lv_draw_eve.h b/src/draw/eve/lv_draw_eve.h new file mode 100644 index 0000000000..003638ad4f --- /dev/null +++ b/src/draw/eve/lv_draw_eve.h @@ -0,0 +1,57 @@ +/** + * @file lv_draw_eve.h + * + */ + +/* Created on: 3 dic 2023 + * Author: juanj + * + * Modified by LVGL + */ + +#ifndef LV_DRAW_EVE_H +#define LV_DRAW_EVE_H + + +#ifdef __cplusplus +extern "C" { +#endif + +/********************* + * INCLUDES + *********************/ + +#include "../../lv_conf_internal.h" +#if LV_USE_DRAW_EVE + +#include "lv_draw_eve_target.h" + +/********************* + * DEFINES + *********************/ + +/********************** + * TYPEDEFS + **********************/ + +/********************** + * GLOBAL PROTOTYPES + **********************/ + +void lv_draw_eve_init(void); + +void lv_draw_eve_set_display_data(lv_display_t * disp, const lv_draw_eve_parameters_t * params, + lv_draw_eve_operation_cb_t op_cb); + +/********************** + * MACROS + **********************/ + +#endif /*LV_USE_DRAW_EVE*/ + +#ifdef __cplusplus +} /*extern "C"*/ +#endif + + +#endif /* LV_DRAW_EVE_H */ diff --git a/src/draw/eve/lv_draw_eve_arc.c b/src/draw/eve/lv_draw_eve_arc.c new file mode 100644 index 0000000000..2a19128c98 --- /dev/null +++ b/src/draw/eve/lv_draw_eve_arc.c @@ -0,0 +1,325 @@ +/** + * @file lv_draw_eve_arc.c + * + */ + +/* Created on: 11 dic 2023 + * Author: juanj + * + * Modified by LVGL + */ + +/********************* + * INCLUDES + *********************/ +#include "lv_draw_eve_private.h" +#if LV_USE_DRAW_EVE + +#include "../lv_draw_arc.h" +#include "lv_eve.h" + +/********************* + * DEFINES + *********************/ + +/********************** + * STATIC PROTOTYPES + **********************/ + +static void draw_eve_arc(lv_draw_task_t * t, const lv_draw_arc_dsc_t * dsc, const lv_area_t * coords); +static bool is_same_quadrant(int16_t start_angle, int16_t end_angle) ; +static void draw_rounded_end(lv_point_t center, int32_t radius, int32_t angle, int32_t width); +static void lv_draw_eve_mask_angle(const lv_draw_arc_dsc_t * dsc, int32_t vertex_x, int32_t vertex_y, + int32_t start_angle, int32_t end_angle); +static lv_eve_primitive_t get_mask_direction(int16_t angle); +static int32_t chord_length(int16_t radius, int16_t angle_degrees); + +/********************** + * GLOBAL FUNCTIONS + **********************/ + +void lv_draw_eve_arc(lv_draw_task_t * t, const lv_draw_arc_dsc_t * dsc, const lv_area_t * coords) +{ + draw_eve_arc(t, dsc, coords); +} + +/********************** + * STATIC FUNCTIONS + **********************/ + + +static int32_t chord_length(int16_t radius, int16_t angle_degrees) +{ + angle_degrees %= 360; + if(angle_degrees < 0) angle_degrees += 360; + int32_t sin_value = lv_trigo_sin(angle_degrees / 2); + int64_t chord_length = 2 * radius * sin_value / 32768.0; + return (int32_t)chord_length ; +} + + +static lv_eve_primitive_t get_mask_direction(int16_t angle) +{ + if(angle >= 315 || angle < 45) { + return LV_EVE_PRIMITIVE_EDGE_STRIP_R; + } + if(angle >= 45 && angle < 135) { + return LV_EVE_PRIMITIVE_EDGE_STRIP_B; + } + if(angle >= 135 && angle < 225) { + return LV_EVE_PRIMITIVE_EDGE_STRIP_L; + } + if(angle >= 225 && angle < 315) { + return LV_EVE_PRIMITIVE_EDGE_STRIP_A; + } + return 0; +} + + +static void draw_rounded_end(lv_point_t center, int32_t radius, int32_t angle, int32_t width) +{ + int32_t rounded_y = center.y + ((lv_trigo_sin(angle) * radius) >> LV_TRIGO_SHIFT); + int32_t rounded_x = center.x + ((lv_trigo_cos(angle) * radius) >> LV_TRIGO_SHIFT); + lv_eve_draw_circle_simple(rounded_x, rounded_y, width); +} + + + +static bool is_same_quadrant(int16_t start_angle, int16_t end_angle) +{ + if(start_angle > end_angle) { + if((start_angle >= 0 && start_angle < 90) && (end_angle >= 0 && end_angle < 90)) { + return true; + } + else if((start_angle >= 90 && start_angle < 180) && (end_angle >= 90 && end_angle < 180)) { + return true; + } + else if((start_angle >= 180 && start_angle < 270) && (end_angle >= 180 && end_angle < 270)) { + return true; + } + else if((start_angle >= 270 && start_angle < 360) && (end_angle >= 270 && end_angle < 360)) { + return true; + } + else { + return false; + } + } + else { + return false; + } +} + + + +static void lv_draw_eve_mask_angle(const lv_draw_arc_dsc_t * dsc, int32_t vertex_x, int32_t vertex_y, + int32_t start_angle, int32_t end_angle) +{ + + /*Constrain the input angles*/ + + + if(start_angle < 0) + start_angle = 0; + else if(start_angle > 359) + start_angle = 359; + + if(end_angle < 0) + end_angle = 0; + else if(end_angle > 359) + end_angle = 359; + + LV_ASSERT_MSG(start_angle >= 0 && start_angle <= 360, "Unexpected start angle"); + + int32_t mid_angle_op; + int32_t angle_range; + int32_t mask_dir_start; + int32_t mask_dir_end; + lv_point_t start; + lv_point_t end; + lv_point_t angle_range_op; + + if(end_angle > start_angle) { + angle_range = LV_ABS(end_angle - start_angle); + } + else { + angle_range = 360 - start_angle + end_angle; + } + + mid_angle_op = (angle_range / 2) + start_angle + 180; + mid_angle_op = mid_angle_op % 360; + + mask_dir_end = LV_ABS(((360 - angle_range) / 4) + end_angle); + mask_dir_start = LV_ABS(((360 - angle_range) / 4) + mid_angle_op); + + mask_dir_start = mask_dir_start % 360; + mask_dir_end = mask_dir_end % 360; + + start.y = (lv_trigo_sin(start_angle) >> 5) + vertex_y; + start.x = (lv_trigo_cos(start_angle) >> 5) + vertex_x; + + end.y = (lv_trigo_sin(end_angle) >> 5) + vertex_y; + end.x = (lv_trigo_cos(end_angle) >> 5) + vertex_x; + + angle_range_op.y = (lv_trigo_sin(mid_angle_op) >> 5) + vertex_y; + angle_range_op.x = (lv_trigo_cos(mid_angle_op) >> 5) + vertex_x; + + if(angle_range <= 180) { + /* Two sides mask and 6 vertex points */ + + /* Masking end angle */ + lv_eve_primitive_t edge = get_mask_direction(mask_dir_end); + lv_eve_primitive(edge); /* Side one */ + lv_eve_vertex_2f(angle_range_op.x, angle_range_op.y); + lv_eve_vertex_2f(vertex_x, vertex_y); + lv_eve_vertex_2f(end.x, end.y); + + /* Masking start angle */ + edge = get_mask_direction(mask_dir_start); + lv_eve_primitive(edge); /* Side two */ + lv_eve_vertex_2f(angle_range_op.x, angle_range_op.y); + lv_eve_vertex_2f(vertex_x, vertex_y); + lv_eve_vertex_2f(start.x, start.y); + + } + + else { + + if(is_same_quadrant(start_angle, + end_angle)) { /* "It is not an optimal implementation for the case where both angles (start and end) are in the same quadrant */ + /* todo */ + lv_point_t end_line_cntr; + lv_point_t start_line_cntr; + + lv_point_t end_line_brd; + lv_point_t start_line_brd; + + int16_t chord = chord_length(dsc->radius, 360 - angle_range); + int16_t w = ((chord / 4) < 1) ? 1 : chord / 4; + int16_t r_width = w; + + end_line_brd.y = vertex_y + ((lv_trigo_sin(end_angle) * dsc->radius) >> LV_TRIGO_SHIFT); + end_line_brd.x = vertex_x + ((lv_trigo_cos(end_angle) * dsc->radius) >> LV_TRIGO_SHIFT); + + start_line_brd.y = vertex_y + ((lv_trigo_sin(start_angle) * dsc->radius) >> LV_TRIGO_SHIFT); + start_line_brd.x = vertex_x + ((lv_trigo_cos(start_angle) * dsc->radius) >> LV_TRIGO_SHIFT); + + lv_eve_draw_rect_simple(start_line_brd.x, start_line_brd.y, end_line_brd.x, end_line_brd.y, 0); + + start_line_brd.y = start_line_brd.y + ((lv_trigo_sin(start_angle - 90) * r_width) >> LV_TRIGO_SHIFT); + start_line_brd.x = start_line_brd.x + ((lv_trigo_cos(start_angle - 90) * r_width) >> LV_TRIGO_SHIFT); + + end_line_brd.y = end_line_brd.y + ((lv_trigo_sin(end_angle + 90) * r_width) >> LV_TRIGO_SHIFT); + end_line_brd.x = end_line_brd.x + ((lv_trigo_cos(end_angle + 90) * r_width) >> LV_TRIGO_SHIFT); + + end_line_cntr.y = vertex_y + ((lv_trigo_sin(end_angle + 90) * r_width) >> LV_TRIGO_SHIFT); + end_line_cntr.x = vertex_x + ((lv_trigo_cos(end_angle + 90) * r_width) >> LV_TRIGO_SHIFT); + + start_line_cntr.y = vertex_y + ((lv_trigo_sin(start_angle + 270) * r_width) >> LV_TRIGO_SHIFT); + start_line_cntr.x = vertex_x + ((lv_trigo_cos(start_angle + 270) * r_width) >> LV_TRIGO_SHIFT); + + lv_eve_primitive(LV_EVE_PRIMITIVE_LINE_STRIP); + lv_eve_line_width(r_width * 16); + lv_eve_vertex_2f(start_line_cntr.x, start_line_cntr.y); + lv_eve_vertex_2f(start_line_brd.x, start_line_brd.y); + lv_eve_vertex_2f(end_line_brd.x, end_line_brd.y); + lv_eve_vertex_2f(end_line_cntr.x, end_line_cntr.y); + + } + else { /* One side mask and 3 vertex points */ + /* Masking end and start angles */ + lv_eve_primitive_t edge = get_mask_direction(mid_angle_op); + lv_eve_primitive(edge); + lv_eve_vertex_2f(end.x, end.y); + lv_eve_vertex_2f(vertex_x, vertex_y); + lv_eve_vertex_2f(start.x, start.y); + } + } + +} + + + +static void draw_eve_arc(lv_draw_task_t * t, const lv_draw_arc_dsc_t * dsc, const lv_area_t * coords) +{ + + if(dsc->opa <= LV_OPA_MIN) + return; + if(dsc->width == 0) + return; + if(dsc->start_angle == dsc->end_angle) + return; + + lv_color_t color = dsc->color; + lv_opa_t opa = dsc->opa; + lv_point_t center = dsc->center; + int32_t width = dsc->width; + uint16_t radius_out = dsc->radius; + uint16_t radius_in = dsc->radius - dsc->width; + int32_t start_angle = (int32_t) dsc->start_angle; + int32_t end_angle = (int32_t) dsc->end_angle; + + if(width > radius_out) + width = radius_out; + + while(start_angle >= 360) + start_angle -= 360; + while(end_angle >= 360) + end_angle -= 360; + + lv_eve_scissor(t->clip_area.x1, t->clip_area.y1, t->clip_area.x2, t->clip_area.y2); + + lv_eve_save_context(); + + lv_eve_color(color); + lv_eve_color_opa(opa); + + lv_eve_color_mask(0, 0, 0, 1); + lv_eve_stencil_func(EVE_ALWAYS, 0, 1); + lv_eve_stencil_op(EVE_REPLACE, EVE_REPLACE); + lv_eve_draw_circle_simple(center.x, center.y, radius_out); /* radius_out */ + + lv_eve_blend_func(EVE_ONE, EVE_ZERO); + lv_eve_draw_circle_simple(center.x, center.y, radius_in + 2); /* radius_in */ + + lv_eve_stencil_func(EVE_ALWAYS, 1, 1); + lv_eve_stencil_op(EVE_REPLACE, EVE_REPLACE); + lv_eve_blend_func(EVE_ZERO, EVE_ONE_MINUS_SRC_ALPHA); + lv_eve_color_opa(0XFF); + + /* Start masking arc */ + + lv_draw_eve_mask_angle(dsc, center.x, center.y, start_angle, end_angle); + + /* End masking arc */ + + lv_eve_draw_circle_simple(center.x, center.y, radius_in); /* radius_in */ + + lv_eve_color_mask(1, 1, 1, 1); + lv_eve_blend_func(EVE_DST_ALPHA, EVE_ONE_MINUS_DST_ALPHA); + lv_eve_draw_circle_simple(center.x, center.y, radius_in); /* radius_in */ + + lv_eve_stencil_func(EVE_NOTEQUAL, 1, 0XFF); + lv_eve_stencil_op(EVE_KEEP, EVE_KEEP); + lv_eve_blend_func(EVE_SRC_ALPHA, EVE_ONE_MINUS_SRC_ALPHA); + + lv_eve_color_opa(opa); + lv_eve_draw_circle_simple(center.x, center.y, radius_out); /* radius_out */ + + if(dsc->rounded) { + lv_eve_stencil_func(EVE_EQUAL, 1, 0XFF); + if(opa < 255) { + lv_eve_stencil_op(EVE_ZERO, EVE_ZERO); + } + + int32_t half_width = width / 2; + int32_t adjusted_radius = radius_out - half_width; + draw_rounded_end(center, adjusted_radius, end_angle, half_width); + draw_rounded_end(center, adjusted_radius, start_angle, half_width); + } + + lv_eve_restore_context(); +} + + + +#endif /*LV_USE_DRAW_EVE*/ diff --git a/src/draw/eve/lv_draw_eve_fill.c b/src/draw/eve/lv_draw_eve_fill.c new file mode 100644 index 0000000000..d0221a711f --- /dev/null +++ b/src/draw/eve/lv_draw_eve_fill.c @@ -0,0 +1,121 @@ +/** + * @file lv_draw_eve_fill.c + * + */ + +/* Created on: 27 mar 2023 + * Author: juanj + * + * Modified by LVGL + */ + +/********************* + * INCLUDES + *********************/ +#include "lv_draw_eve_private.h" +#if LV_USE_DRAW_EVE +#include "lv_eve.h" + + +/********************** + * STATIC PROTOTYPES + **********************/ + +/********************** + * GLOBAL FUNCTIONS + **********************/ + +void lv_draw_eve_fill(lv_draw_task_t * t, const lv_draw_fill_dsc_t * dsc, const lv_area_t * coords) +{ + + int32_t rad = dsc->radius; + int32_t bg_w = lv_area_get_width(coords); + int32_t bg_h = lv_area_get_height(coords); + int32_t real_radius = LV_MIN3(bg_w / 2, bg_h / 2, rad); + + lv_eve_scissor(t->clip_area.x1, t->clip_area.y1, t->clip_area.x2, t->clip_area.y2); + lv_eve_save_context(); + + lv_eve_color(dsc->color); + lv_eve_color_opa(dsc->opa); + + if(bg_w == bg_h && rad == LV_RADIUS_CIRCLE) { + lv_eve_draw_circle_simple(coords->x1 + (bg_w / 2), coords->y1 + (bg_h / 2), real_radius); + } + else { + lv_eve_draw_rect_simple(coords->x1, coords->y1, coords->x2, coords->y2, real_radius); + } + + lv_eve_restore_context(); +} + + +/********************** + * STATIC FUNCTIONS + **********************/ + + + +void lv_draw_eve_border(lv_draw_task_t * t, const lv_draw_border_dsc_t * dsc, const lv_area_t * coords) +{ + + if(dsc->opa <= LV_OPA_MIN) return; + if(dsc->width == 0) return; + if(dsc->side == LV_BORDER_SIDE_NONE) return; + + int32_t coords_w = lv_area_get_width(coords); + int32_t coords_h = lv_area_get_height(coords); + int32_t rout = dsc->radius; + int32_t short_side = LV_MIN(coords_w, coords_h); + if(rout > short_side >> 1) rout = short_side >> 1; + + /*Get the inner area*/ + lv_area_t area_inner; + lv_area_copy(&area_inner, coords); + area_inner.x1 += ((dsc->side & LV_BORDER_SIDE_LEFT) ? dsc->width : - (dsc->width)); + area_inner.x2 -= ((dsc->side & LV_BORDER_SIDE_RIGHT) ? dsc->width : - (dsc->width)); + area_inner.y1 += ((dsc->side & LV_BORDER_SIDE_TOP) ? dsc->width : - (dsc->width)); + area_inner.y2 -= ((dsc->side & LV_BORDER_SIDE_BOTTOM) ? dsc->width : - (dsc->width)); + + int32_t rin = rout - dsc->width; + if(rin < 0) rin = 0; + + lv_eve_save_context(); + + lv_eve_scissor(t->clip_area.x1, t->clip_area.y1, t->clip_area.x2, t->clip_area.y2); + + lv_eve_color(dsc->color); + lv_eve_color_opa(dsc->opa); + + lv_eve_color_mask(0, 0, 0, 1); + lv_eve_stencil_func(EVE_ALWAYS, 0, 1); + lv_eve_stencil_op(EVE_REPLACE, EVE_REPLACE); + lv_eve_draw_rect_simple(coords->x1, coords->y1, coords->x2, coords->y2, 0); + + lv_eve_blend_func(EVE_ONE, EVE_ZERO); + lv_eve_draw_rect_simple(area_inner.x1 - 2, area_inner.y1 - 1, area_inner.x2 + 1, area_inner.y2 + 2, rin); + + lv_eve_stencil_func(EVE_ALWAYS, 1, 1); + lv_eve_stencil_op(EVE_REPLACE, EVE_REPLACE); + lv_eve_blend_func(EVE_ZERO, EVE_ONE_MINUS_SRC_ALPHA); + lv_eve_color_opa(255); + lv_eve_draw_rect_simple(area_inner.x1, area_inner.y1, area_inner.x2, area_inner.y2, rin); + + lv_eve_color_mask(1, 1, 1, 1); + + if(dsc->side == LV_BORDER_SIDE_FULL) { + lv_eve_blend_func(EVE_DST_ALPHA, EVE_ONE_MINUS_DST_ALPHA); + lv_eve_draw_rect_simple(area_inner.x1, area_inner.y1, area_inner.x2, area_inner.y2, rin); + } + + lv_eve_stencil_func(EVE_NOTEQUAL, 1, 255); + lv_eve_blend_func(EVE_SRC_ALPHA, EVE_ONE_MINUS_SRC_ALPHA); + + lv_eve_color_opa(dsc->opa); + lv_eve_draw_rect_simple(coords->x1, coords->y1, coords->x2, coords->y2, rout); + + lv_eve_restore_context(); +} + +#endif /*LV_USE_DRAW_EVE*/ + diff --git a/src/draw/eve/lv_draw_eve_image.c b/src/draw/eve/lv_draw_eve_image.c new file mode 100644 index 0000000000..1c6d999dd1 --- /dev/null +++ b/src/draw/eve/lv_draw_eve_image.c @@ -0,0 +1,299 @@ +/** + * @file lv_draw_eve_image.c + * + */ + +/* Created on: 17 jun 2023 + * Author: juanj + * + * Modified by LVGL + */ + +/********************* + * INCLUDES + *********************/ +#include "lv_draw_eve_private.h" +#if LV_USE_DRAW_EVE + +#include "../lv_draw_image_private.h" +#include "lv_draw_eve_ram_g.h" +#include "lv_eve.h" + +/********************* + * DEFINES + *********************/ + + +/********************** + * TYPEDEFS + **********************/ + +/********************** + * STATIC PROTOTYPES + **********************/ +static void convert_row_rgb565a8_to_argb4444(const uint8_t * src, const uint8_t * src_alpha, uint8_t * dst, + uint32_t width); +static void convert_row_argb8888_to_argb4444(const uint8_t * src, uint8_t * dst, uint32_t width); + +/********************** + * STATIC VARIABLES + **********************/ + + + +/********************** + * MACROS + **********************/ + +#define F16_PIVOT_SHIFT(x) ((int32_t)((((x) >> 1)) * 65536L)) +#define F16_SCALE_DIV_256(x) ((int32_t)(((x) / 256.0f) * 65536L)) + +/********************** + * GLOBAL FUNCTIONS + **********************/ + +void lv_draw_eve_image(lv_draw_task_t * t, const lv_draw_image_dsc_t * draw_dsc, const lv_area_t * coords) +{ + if(!lv_draw_eve_image_src_check(draw_dsc->src)) { + return; + } + + const lv_image_dsc_t * img_dsc = draw_dsc->src; + + int32_t src_w = img_dsc->header.w; + int32_t src_h = img_dsc->header.h; + int32_t src_stride = img_dsc->header.stride; + lv_color_format_t src_cf = img_dsc->header.cf; + + if(src_stride == 0) { + src_stride = src_w * lv_color_format_get_size(src_cf); + } + + uint8_t eve_format; + int32_t eve_stride; + + switch(src_cf) { + case LV_COLOR_FORMAT_L8: + eve_format = EVE_L8; + eve_stride = src_stride; + break; + case LV_COLOR_FORMAT_RGB565: + eve_format = EVE_RGB565; + eve_stride = src_stride; + break; + case LV_COLOR_FORMAT_RGB565A8: + case LV_COLOR_FORMAT_ARGB8888: + eve_format = EVE_ARGB4; + eve_stride = src_w * 2; + break; + default : + LV_ASSERT(0); + } + + uint32_t ramg_addr = lv_draw_eve_image_upload_image(true, img_dsc); + if(ramg_addr == LV_DRAW_EVE_RAMG_OUT_OF_RAMG) { + LV_LOG_WARN("Could not load image because space could not be allocated in RAM_G."); + return; + } + + lv_eve_scissor(t->clip_area.x1, t->clip_area.y1, t->clip_area.x2, t->clip_area.y2); + + lv_eve_save_context(); + + lv_eve_color_opa(draw_dsc->opa); + + if(draw_dsc->recolor_opa > LV_OPA_MIN) { + lv_eve_color(lv_color_mix(draw_dsc->recolor, lv_color_white(), draw_dsc->recolor_opa)); + } + + lv_eve_primitive(LV_EVE_PRIMITIVE_BITMAPS); + lv_eve_bitmap_source(ramg_addr); + /*real height and width is mandatory for rotation and scale (Clip Area)*/ + lv_eve_bitmap_size(EVE_NEAREST, EVE_BORDER, EVE_BORDER, src_w, src_h); + + lv_eve_bitmap_layout(eve_format, eve_stride, src_h); + + if(draw_dsc->rotation || draw_dsc->scale_x != LV_SCALE_NONE || draw_dsc->scale_y != LV_SCALE_NONE) { + EVE_cmd_dl_burst(CMD_LOADIDENTITY); + + EVE_cmd_translate_burst(F16(coords->x1 - t->clip_area.x1 + draw_dsc->pivot.x), + F16(coords->y1 - t->clip_area.y1 + draw_dsc->pivot.y)); + if(draw_dsc->scale_x != LV_SCALE_NONE || draw_dsc->scale_y != LV_SCALE_NONE) { + /*Image Scale*/ + EVE_cmd_scale_burst(F16_SCALE_DIV_256(draw_dsc->scale_x), F16_SCALE_DIV_256(draw_dsc->scale_y)); + } + if(draw_dsc->rotation != 0) { + /*Image Rotate*/ + EVE_cmd_rotate_burst(DEGREES(draw_dsc->rotation)); + } + EVE_cmd_translate_burst(-F16(draw_dsc->pivot.x), -F16(draw_dsc->pivot.y)); + EVE_cmd_dl_burst(CMD_SETMATRIX); + EVE_cmd_dl_burst(CMD_LOADIDENTITY); + lv_eve_vertex_2f(t->clip_area.x1, t->clip_area.y1); + } + else { + lv_eve_vertex_2f(coords->x1, coords->y1); + } + lv_eve_restore_context(); +} + +bool lv_draw_eve_image_src_check(const void * src) +{ + if(lv_image_src_get_type(src) != LV_IMAGE_SRC_VARIABLE) { + LV_LOG_WARN("lv_draw_eve can only render images from variables (not files or symbols) for now."); + return false; + } + + const lv_image_dsc_t * img_dsc = src; + + switch(img_dsc->header.cf) { + case LV_COLOR_FORMAT_L8: + case LV_COLOR_FORMAT_RGB565: + case LV_COLOR_FORMAT_RGB565A8: + case LV_COLOR_FORMAT_ARGB8888: + break; + default : + LV_LOG_WARN("lv_draw_eve can only render L8, RGB565, RGB565A8, and ARGB8888 images for now."); + return false; + } + + return true; +} + +uint32_t lv_draw_eve_image_upload_image(bool burst_is_active, const lv_image_dsc_t * img_dsc) +{ + const uint8_t * src_buf = img_dsc->data; + int32_t src_w = img_dsc->header.w; + int32_t src_h = img_dsc->header.h; + int32_t src_stride = img_dsc->header.stride; + lv_color_format_t src_cf = img_dsc->header.cf; + + if(src_stride == 0) { + src_stride = src_w * lv_color_format_get_size(src_cf); + } + + int32_t eve_stride; + uint8_t eve_alignment; + + switch(src_cf) { + case LV_COLOR_FORMAT_L8: + eve_stride = src_stride; + eve_alignment = 1; + break; + case LV_COLOR_FORMAT_RGB565: + eve_stride = src_stride; + eve_alignment = 2; + break; + case LV_COLOR_FORMAT_RGB565A8: + case LV_COLOR_FORMAT_ARGB8888: + eve_stride = src_w * 2; + eve_alignment = 2; + break; + default : + LV_ASSERT(0); + } + + int32_t eve_size = eve_stride * src_h; + + uint32_t ramg_addr; + bool img_is_loaded = lv_draw_eve_ramg_get_addr(&ramg_addr, (uintptr_t) src_buf, eve_size, eve_alignment); + + /* New image to load */ + if(!img_is_loaded && ramg_addr != LV_DRAW_EVE_RAMG_OUT_OF_RAMG) { + + /* Load image to RAM_G */ + + if(burst_is_active) { + EVE_end_cmd_burst(); + } + + switch(src_cf) { + case LV_COLOR_FORMAT_L8: + case LV_COLOR_FORMAT_RGB565: + EVE_memWrite_flash_buffer(ramg_addr, src_buf, eve_size); + break; + case LV_COLOR_FORMAT_RGB565A8: { + uint8_t * tmp_buf = lv_malloc(eve_stride); + LV_ASSERT_MALLOC(tmp_buf); + const uint8_t * src_alpha_buf = src_buf + src_h * src_stride; + int32_t src_alpha_stride = src_stride / 2; + for(uint32_t y = 0; y < src_h; y++) { + convert_row_rgb565a8_to_argb4444(src_buf + y * src_stride, src_alpha_buf + y * src_alpha_stride, tmp_buf, src_w); + EVE_memWrite_flash_buffer(ramg_addr + y * eve_stride, tmp_buf, eve_stride); + } + lv_free(tmp_buf); + break; + } + case LV_COLOR_FORMAT_ARGB8888: { + uint8_t * tmp_buf = lv_malloc(eve_stride); + LV_ASSERT_MALLOC(tmp_buf); + for(uint32_t y = 0; y < src_h; y++) { + convert_row_argb8888_to_argb4444(src_buf + y * src_stride, tmp_buf, src_w); + EVE_memWrite_flash_buffer(ramg_addr + y * eve_stride, tmp_buf, eve_stride); + } + lv_free(tmp_buf); + break; + } + default: + LV_ASSERT(0); + } + + if(burst_is_active) { + EVE_start_cmd_burst(); + } + } + + return ramg_addr; +} + + + + +/********************** + * STATIC FUNCTIONS + **********************/ + +static void convert_row_rgb565a8_to_argb4444(const uint8_t * src, const uint8_t * src_alpha, uint8_t * dst, + uint32_t width) +{ + for(uint32_t x = 0; x < width; x++) { + uint16_t rgb565 = ((const uint16_t *) src)[x]; + + uint8_t r5 = (rgb565 >> 11) & 0x1F; + uint8_t g6 = (rgb565 >> 5) & 0x3F; + uint8_t b5 = rgb565 & 0x1F; + uint8_t alpha = src_alpha[x]; + + uint8_t r4 = r5 >> 1; + uint8_t g4 = g6 >> 2; + uint8_t b4 = b5 >> 1; + uint8_t a4 = alpha >> 4; + + uint16_t argb4444 = (a4 << 12) | (r4 << 8) | (g4 << 4) | b4; + + dst[2 * x] = argb4444 & 0xFF; + dst[2 * x + 1] = (argb4444 >> 8) & 0xFF; + } +} + +static void convert_row_argb8888_to_argb4444(const uint8_t * src, uint8_t * dst, uint32_t width) +{ + for(uint32_t x = 0; x < width; x++) { + uint8_t blue = src[4 * x]; + uint8_t green = src[4 * x + 1]; + uint8_t red = src[4 * x + 2]; + uint8_t alpha = src[4 * x + 3]; + + uint8_t r4 = red >> 4; + uint8_t g4 = green >> 4; + uint8_t b4 = blue >> 4; + uint8_t a4 = alpha >> 4; + + uint16_t argb4444 = (a4 << 12) | (r4 << 8) | (g4 << 4) | b4; + + dst[2 * x] = argb4444 & 0xFF; + dst[2 * x + 1] = (argb4444 >> 8) & 0xFF; + } +} + +#endif /*LV_USE_DRAW_EVE*/ diff --git a/src/draw/eve/lv_draw_eve_letter.c b/src/draw/eve/lv_draw_eve_letter.c new file mode 100644 index 0000000000..b7786e1409 --- /dev/null +++ b/src/draw/eve/lv_draw_eve_letter.c @@ -0,0 +1,233 @@ +/** + * @file lv_draw_eve_letter.c + * + */ + +/* Author: juanj + * + * Modified by LVGL + */ + +/********************* + * INCLUDES + *********************/ +#include "lv_draw_eve_private.h" +#if LV_USE_DRAW_EVE + +#include "../lv_draw_private.h" +#include "../lv_draw_label_private.h" +#include "../lv_draw_rect.h" +#include "lv_eve.h" + +/********************* + * DEFINES + *********************/ + +/********************** + * TYPEDEFS + **********************/ + +/********************** + * STATIC PROTOTYPES + **********************/ + +static void lv_draw_eve_letter_cb(lv_draw_task_t * t, lv_draw_glyph_dsc_t * glyph_draw_dsc, + lv_draw_fill_dsc_t * fill_draw_dsc, const lv_area_t * fill_area); +static void font_bitmap_to_ramg(uint32_t addr, const uint8_t * src, uint32_t width, + uint32_t height, uint8_t src_stride_align); + +/********************** + * STATIC VARIABLES + **********************/ + +/********************** + * MACROS + **********************/ + +#define GET_NIBBLE_1(w) ((uint8_t) ((w) >> 4)) +#define GET_NIBBLE_2(w) ((uint8_t) ((w) & 0xf)) + +/********************** + * GLOBAL FUNCTIONS + **********************/ + +void lv_draw_eve_label(lv_draw_task_t * t, const lv_draw_label_dsc_t * dsc, const lv_area_t * coords) +{ + if(dsc->opa <= LV_OPA_MIN) return; + + lv_eve_scissor(t->clip_area.x1, t->clip_area.y1, t->clip_area.x2, t->clip_area.y2); + lv_eve_save_context(); + lv_eve_primitive(LV_EVE_PRIMITIVE_BITMAPS); + lv_draw_label_iterate_characters(t, dsc, coords, lv_draw_eve_letter_cb); + lv_eve_restore_context(); +} + +bool lv_draw_eve_label_font_check(const lv_font_t * font) +{ + if(font->get_glyph_bitmap != lv_font_get_bitmap_fmt_txt) { + LV_LOG_WARN("lv_draw_eve can only render static fonts for now."); + return false; + } + + const lv_font_fmt_txt_dsc_t * font_dsc = font->dsc; + + /* Only 4 bpp is supported for now. Support for 1 and 8 bpp can be added. (EVE_L1, EVE_L8) */ + if(font_dsc->bpp != 4) { + LV_LOG_WARN("lv_draw_eve can only render static fonts for now."); + return false; + } + + return true; +} + +uint32_t lv_draw_eve_label_upload_glyph(bool burst_is_active, const lv_font_fmt_txt_dsc_t * font_dsc, + uint32_t gid_index) +{ + const lv_font_fmt_txt_glyph_dsc_t * glyph_dsc = &font_dsc->glyph_dsc[gid_index]; + const uint8_t * glyph_bitmap = &font_dsc->glyph_bitmap[glyph_dsc->bitmap_index]; + + uint16_t g_box_w = glyph_dsc->box_w; + uint16_t g_box_h = glyph_dsc->box_h; + + uint16_t g_aligned_stride = (g_box_w + 1) / 2; + + uint32_t glyph_ramg_size = g_aligned_stride * g_box_h; + + uint32_t ramg_addr; + uintptr_t glyph_ramg_key = (uintptr_t) glyph_bitmap; + bool font_is_loaded = lv_draw_eve_ramg_get_addr(&ramg_addr, glyph_ramg_key, glyph_ramg_size, 1); + + /* If the font is not yet loaded in ramG, load it */ + if(!font_is_loaded && ramg_addr != LV_DRAW_EVE_RAMG_OUT_OF_RAMG) { + if(burst_is_active) { + EVE_end_cmd_burst(); + } + + uint8_t glyph_bitmap_stride_align = font_dsc->stride; + font_bitmap_to_ramg(ramg_addr, glyph_bitmap, g_box_w, g_box_h, glyph_bitmap_stride_align); + + if(burst_is_active) { + EVE_start_cmd_burst(); + } + } + + return ramg_addr; +} + +/********************** + * STATIC FUNCTIONS + **********************/ + +static void lv_draw_eve_letter_cb(lv_draw_task_t * t, lv_draw_glyph_dsc_t * glyph_draw_dsc, + lv_draw_fill_dsc_t * fill_draw_dsc, const lv_area_t * fill_area) +{ + + if(fill_draw_dsc && fill_area) { + /* draw UNDERLINE and STRIKETHROUGH */ + lv_eve_draw_rect_simple(fill_area->x1, fill_area->y1, fill_area->x2, fill_area->y2, 0); + } + + if(glyph_draw_dsc == NULL) + return; /* Important */ + + const lv_font_t * font = glyph_draw_dsc->g->resolved_font; + + if(!lv_draw_eve_label_font_check(font)) { + return; + } + + const lv_font_fmt_txt_dsc_t * font_dsc = font->dsc; + uint32_t gid_index = glyph_draw_dsc->g->gid.index; + const lv_font_fmt_txt_glyph_dsc_t * glyph_dsc = &font_dsc->glyph_dsc[gid_index]; + + uint16_t g_box_w = glyph_dsc->box_w; + uint16_t g_box_h = glyph_dsc->box_h; + + uint16_t g_aligned_stride = (g_box_w + 1) / 2; + + uint8_t bpp_eve = EVE_L4; + + uint32_t ramg_addr = lv_draw_eve_label_upload_glyph(true, font_dsc, gid_index); + if(ramg_addr == LV_DRAW_EVE_RAMG_OUT_OF_RAMG) { + LV_LOG_WARN("Could not load glyph because space could not be allocated in RAM_G."); + return; + } + + lv_eve_color_opa(glyph_draw_dsc->opa); + lv_eve_color(glyph_draw_dsc->color); + + lv_eve_bitmap_source(ramg_addr); + + lv_eve_bitmap_size(EVE_NEAREST, EVE_BORDER, EVE_BORDER, g_box_w, g_box_h); + lv_eve_bitmap_layout(bpp_eve, g_aligned_stride, g_box_h); + + lv_eve_vertex_2f(glyph_draw_dsc->letter_coords->x1, glyph_draw_dsc->letter_coords->y1); +} + +static void font_bitmap_to_ramg(uint32_t addr, const uint8_t * src, uint32_t width, + uint32_t height, uint8_t src_stride_align) +{ + uint32_t stride = (width + 1) / 2; + + if(src_stride_align == 1 || (src_stride_align == 0 && width % 2 == 0)) { + uint32_t size = stride * height; + EVE_memWrite_flash_buffer(addr, src, size); + return; + } + + if(src_stride_align > 0) { + uint32_t src_stride = LV_ALIGN_UP(stride, src_stride_align); + for(uint32_t y = 0; y < height; y++) { + EVE_memWrite_sram_buffer(addr, src, stride); + addr += stride; + src += src_stride; + } + return; + } + + uint8_t * row_buf = lv_malloc(stride); + LV_ASSERT_MALLOC(row_buf); + + uint32_t src_i = 0; + uint8_t nibble_1; + uint8_t nibble_2; + uint8_t key = 0; + + /* Iterate through each row of the bitmap*/ + for(uint32_t y = 0; y < height; y++) { + /* Iterate through each byte of the row*/ + uint32_t row_i; + for(row_i = 0; row_i < (width / 2); ++row_i) { + /*Get the two nibbles from the current byte*/ + if(key == 0) { + nibble_1 = GET_NIBBLE_1(src[src_i]); + nibble_2 = GET_NIBBLE_2(src[src_i]); + } + else { + nibble_1 = GET_NIBBLE_2(src[src_i - 1]); + nibble_2 = GET_NIBBLE_1(src[src_i]); + } + + /*Combine the nibbles and assign the result to the output byte*/ + row_buf[row_i] = (nibble_1 << 4) | nibble_2; + + src_i++; + } + + /*process the last remaining nibble*/ + row_buf[row_i] = + (key == 0) ? + (GET_NIBBLE_1(src[src_i])) << 4 | 0x0 : (GET_NIBBLE_2(src[src_i - 1])) << 4 | 0x0; + key = (key == 0) ? 1 : 0; + src_i += (key == 1) ? 1 : 0; + + EVE_memWrite_sram_buffer(addr, row_buf, stride); + addr += stride; + } + + lv_free(row_buf); +} + + +#endif /*LV_USE_DRAW_EVE*/ + diff --git a/src/draw/eve/lv_draw_eve_line.c b/src/draw/eve/lv_draw_eve_line.c new file mode 100644 index 0000000000..c38357e285 --- /dev/null +++ b/src/draw/eve/lv_draw_eve_line.c @@ -0,0 +1,63 @@ +/** + * @file lv_draw_eve_line.c + * + */ + +/* Created on: 8 abr 2023 + * Author: juanj + * + * Modified by LVGL + */ + +/********************* + * INCLUDES + *********************/ + +#include "lv_draw_eve_private.h" +#if LV_USE_DRAW_EVE +#include "lv_eve.h" + + +void lv_draw_eve_line(lv_draw_task_t * t, const lv_draw_line_dsc_t * dsc) +{ + + if(dsc->width == 0) + return; + if(dsc->opa <= LV_OPA_MIN) + return; + if(dsc->p1.x == dsc->p2.x && dsc->p1.y == dsc->p2.y) + return; + + + + uint32_t line_w = dsc->width * 8; + lv_eve_scissor(t->clip_area.x1, t->clip_area.y1, t->clip_area.x2, t->clip_area.y2); + lv_eve_save_context(); + lv_eve_color_opa(dsc->opa); + lv_eve_color(dsc->color); + + if(dsc->dash_gap || dsc->dash_width) { + LV_LOG_WARN("line dash_gap and dash_width not implemented by EVE yet."); + } + /* Check if it's a vertical or horizontal line without rounding */ + bool is_vertical = (dsc->p1.x == dsc->p2.x); + bool is_horizontal = (dsc->p1.y == dsc->p2.y); + bool no_round = (!dsc->round_end || !dsc->round_start); + + if((is_vertical || is_horizontal) && no_round) { + lv_eve_primitive(LV_EVE_PRIMITIVE_RECTS); + lv_eve_vertex_2f(dsc->p1.x, dsc->p1.y); + lv_eve_vertex_2f(dsc->p2.x, dsc->p2.y); + } + else { + /* Draw inclined line or line with rounding (not possible without rounding)*/ + lv_eve_primitive(LV_EVE_PRIMITIVE_LINE_STRIP); + lv_eve_line_width(line_w); + lv_eve_vertex_2f(dsc->p1.x, dsc->p1.y); + lv_eve_vertex_2f(dsc->p2.x, dsc->p2.y); + } + + lv_eve_restore_context(); +} + +#endif /*LV_USE_DRAW_EVE*/ diff --git a/src/draw/eve/lv_draw_eve_private.h b/src/draw/eve/lv_draw_eve_private.h new file mode 100644 index 0000000000..c67719b21f --- /dev/null +++ b/src/draw/eve/lv_draw_eve_private.h @@ -0,0 +1,117 @@ +/** + * @file lv_draw_eve_private.h + * + */ + +/* Author: juanj + * + * Modified by LVGL + */ + +#ifndef LV_DRAW_EVE_PRIVATE_H +#define LV_DRAW_EVE_PRIVATE_H + +#ifdef __cplusplus +extern "C" { +#endif + +/********************* + * INCLUDES + *********************/ + +#include "lv_draw_eve.h" +#if LV_USE_DRAW_EVE + +#include "lv_draw_eve_target.h" +#include "lv_draw_eve_ram_g.h" +#include "../lv_draw_private.h" +#include "../../misc/lv_types.h" +#include "../../core/lv_global.h" +#include "../lv_draw_triangle.h" +#include "../lv_draw_line.h" +#include "../lv_draw_label.h" +#include "../../font/lv_font_fmt_txt.h" +#include "../lv_draw_arc.h" + +#if LV_DRAW_EVE_WRITE_BUFFER_SIZE != 0 && LV_DRAW_EVE_WRITE_BUFFER_SIZE < 4 +#warning LV_DRAW_EVE_WRITE_BUFFER_SIZE cannot be less than 4. Using 0 (buffering disabled). +#define LV_DRAW_EVE_WRITE_BUFFER_SIZE_INTERNAL 0 +#else +#define LV_DRAW_EVE_WRITE_BUFFER_SIZE_INTERNAL LV_DRAW_EVE_WRITE_BUFFER_SIZE +#endif + +/********************* + * DEFINES + *********************/ + +/********************** + * TYPEDEFS + **********************/ + +typedef struct { + uintptr_t key; + uint32_t addr; +} lv_draw_eve_ramg_hash_table_cell_t; + +typedef struct { + uint32_t ramg_addr_end; + uint32_t hash_table_cell_count; + uint32_t hash_table_cells_occupied; + lv_draw_eve_ramg_hash_table_cell_t * hash_table; +} lv_draw_eve_ramg_t; + +struct _lv_draw_eve_unit_t { + lv_draw_unit_t base_unit; + lv_draw_task_t * task_act; + lv_display_t * disp; + lv_draw_eve_ramg_t ramg; + lv_draw_eve_parameters_t params; + lv_draw_eve_operation_cb_t op_cb; +#if LV_DRAW_EVE_WRITE_BUFFER_SIZE_INTERNAL + uint32_t lv_eve_write_buf_len; + uint8_t lv_eve_write_buf[LV_DRAW_EVE_WRITE_BUFFER_SIZE_INTERNAL]; +#endif +}; + +/********************** + * GLOBAL PROTOTYPES + **********************/ + +void lv_draw_eve_image(lv_draw_task_t * t, const lv_draw_image_dsc_t * draw_dsc, + const lv_area_t * coords); +bool lv_draw_eve_image_src_check(const void * src); +uint32_t lv_draw_eve_image_upload_image(bool burst_is_active, const lv_image_dsc_t * img_dsc); + +void lv_draw_eve_fill(lv_draw_task_t * t, const lv_draw_fill_dsc_t * dsc, const lv_area_t * coords); + +void lv_draw_eve_border(lv_draw_task_t * t, const lv_draw_border_dsc_t * dsc, + const lv_area_t * coords); + +void lv_draw_eve_line(lv_draw_task_t * t, const lv_draw_line_dsc_t * dsc); + +void lv_draw_eve_label(lv_draw_task_t * t, const lv_draw_label_dsc_t * dsc, + const lv_area_t * coords); +bool lv_draw_eve_label_font_check(const lv_font_t * font); +uint32_t lv_draw_eve_label_upload_glyph(bool burst_is_active, const lv_font_fmt_txt_dsc_t * font_dsc, + uint32_t gid_index); + +void lv_draw_eve_arc(lv_draw_task_t * t, const lv_draw_arc_dsc_t * dsc, const lv_area_t * coords); + +void lv_draw_eve_triangle(lv_draw_task_t * t, const lv_draw_triangle_dsc_t * dsc); + +/********************** + * MACROS + **********************/ + +#define DEGREES(n) ((65536UL * (n)) / 3600) +#define F16(x) ((int32_t)((x) * 65536L)) + +#define lv_draw_eve_unit_g (LV_GLOBAL_DEFAULT()->draw_eve_unit) + +#endif /*LV_USE_DRAW_EVE*/ + +#ifdef __cplusplus +} /*extern "C"*/ +#endif + +#endif /*LV_DRAW_EVE_PRIVATE_H*/ diff --git a/src/draw/eve/lv_draw_eve_ram_g.c b/src/draw/eve/lv_draw_eve_ram_g.c new file mode 100644 index 0000000000..1ad544cd69 --- /dev/null +++ b/src/draw/eve/lv_draw_eve_ram_g.c @@ -0,0 +1,221 @@ +/** + * @file lv_draw_eve_ram_g.c + * + */ + +/* Created on: 19 nov 2023 + * Author: juanj + * + * Modified by LVGL + */ + +/********************* + * INCLUDES + *********************/ +#include "lv_draw_eve_private.h" +#if LV_USE_DRAW_EVE +#include "lv_draw_eve_ram_g.h" +#include "lv_eve.h" + +/********************* + * DEFINES + *********************/ + +#define RAMG_DEBUG 0 + +/********************** + * TYPEDEFS + **********************/ + +/********************** + * STATIC PROTOTYPES + **********************/ + +static void ramg_init(lv_draw_eve_ramg_t * ramg); +static uint32_t hash_key(uintptr_t key); +static uint32_t fnv_1a_hash(const void * src, size_t len); +static void grow_hash_table(lv_draw_eve_ramg_t * ramg); + +#if RAMG_DEBUG + static void ramg_debug(lv_draw_eve_ramg_t * ramg, uint32_t key_hash, uint32_t table_index); +#endif + +/********************** + * STATIC VARIABLES + **********************/ + +/********************** + * MACROS + **********************/ + +/********************** + * GLOBAL FUNCTIONS + **********************/ + +bool lv_draw_eve_ramg_get_addr(uint32_t * addr_dst, uintptr_t key, + uint32_t addr_size, uint32_t addr_align) +{ + LV_ASSERT(key != 0); + + lv_draw_eve_ramg_t * ramg = &lv_draw_eve_unit_g->ramg; + + if(ramg->hash_table_cell_count == 0) { + ramg_init(ramg); + } + + uint32_t key_hash = hash_key(key); + uint32_t table_index = key_hash % ramg->hash_table_cell_count; + lv_draw_eve_ramg_hash_table_cell_t * cell; + + while(1) { + cell = &ramg->hash_table[table_index]; + + if(cell->key == key) { +#if RAMG_DEBUG + ramg_debug(ramg, key_hash, table_index); +#endif + + *addr_dst = cell->addr; + return true; + } + + if(cell->key == 0) { + break; + } + + table_index++; + if(table_index >= ramg->hash_table_cell_count) table_index = 0; + } + + uint32_t addr_ret = LV_ALIGN_UP(ramg->ramg_addr_end, addr_align); + uint32_t addr_new_end = addr_ret + addr_size; + + if(addr_new_end > 1024 * 1024) { + LV_LOG_WARN("EVE on-chip 1 MB RAM_G for images and fonts has run out."); + *addr_dst = LV_DRAW_EVE_RAMG_OUT_OF_RAMG; + return false; + } + + ramg->ramg_addr_end = addr_new_end; + ramg->hash_table_cells_occupied++; + + cell->key = key; + cell->addr = addr_ret; + *addr_dst = addr_ret; + +#if RAMG_DEBUG + ramg_debug(ramg, key_hash, table_index); +#endif + + if(ramg->hash_table_cells_occupied > ramg->hash_table_cell_count / 4 * 3) { + grow_hash_table(ramg); + } + + return false; +} + +/********************** + * STATIC FUNCTIONS + **********************/ + +static void ramg_init(lv_draw_eve_ramg_t * ramg) +{ + ramg->hash_table_cell_count = 32; + ramg->hash_table = lv_calloc(32, sizeof(lv_draw_eve_ramg_hash_table_cell_t)); + LV_ASSERT_MALLOC(ramg->hash_table); +} + +static uint32_t hash_key(uintptr_t key) +{ + return fnv_1a_hash(&key, sizeof(key)); +} + +static uint32_t fnv_1a_hash(const void * src, size_t len) +{ + const uint8_t * src_u8 = src; + uint32_t hash = 2166136261u; + for(size_t i = 0; i < len; i++) { + hash ^= src_u8[i]; + hash *= 16777619u; + } + return hash; +} + +static void grow_hash_table(lv_draw_eve_ramg_t * ramg) +{ + uint32_t old_cell_count = ramg->hash_table_cell_count; + lv_draw_eve_ramg_hash_table_cell_t * old_hash_table = ramg->hash_table; + + ramg->hash_table_cell_count += ramg->hash_table_cell_count / 2; + ramg->hash_table = lv_calloc(ramg->hash_table_cell_count, + sizeof(lv_draw_eve_ramg_hash_table_cell_t)); + LV_ASSERT_MALLOC(ramg->hash_table); + + for(uint32_t i = 0; i < old_cell_count; i++) { + lv_draw_eve_ramg_hash_table_cell_t * old_cell = &old_hash_table[i]; + + if(old_cell->key == 0) continue; + + uint32_t key_hash = hash_key(old_cell->key); + uint32_t new_table_index = key_hash % ramg->hash_table_cell_count; + lv_draw_eve_ramg_hash_table_cell_t * new_cell_dst = &ramg->hash_table[new_table_index]; + + while(new_cell_dst->key != 0) { + new_table_index++; + if(new_table_index >= ramg->hash_table_cell_count) new_table_index = 0; + new_cell_dst = &ramg->hash_table[new_table_index]; + } + *new_cell_dst = *old_cell; + } + + lv_free(old_hash_table); +} + +#if RAMG_DEBUG +/* +Print tables like this: + 113 kB of RAM_G used + ================================-==-=====---=---===---=====-=-=-=-==--=======----=-==-==---=--===--=-=-========================= + ========^$==========--=-==-=-=--=--=========---=----========-------===--=====----=======--=====--====--=====-=--=-= + +'-' unoccupied cells +'=' occupied cells +'^' where the hash pointed to in the table initially and linear probing started +'$' where linear probing ended because a matching or unoccupied cell + was found. This symbol is not shown if the initial guess was correct. + +This example has 244 cells. Each cell uses 8 bytes of local RAM, so just under 2 kB. +Each cell represents an allocation in EVE RAM_G. The RAM_G allocation sizes are not +represented in this table, except for the overall "113 kB of RAM_G used" message. +*/ +static void ramg_debug(lv_draw_eve_ramg_t * ramg, uint32_t key_hash, uint32_t table_index) +{ + uint32_t table_index_initial_guess = key_hash % ramg->hash_table_cell_count; + + lv_log("%u kB of RAM_G used\n", (unsigned) ramg->ramg_addr_end / 1024); + + for(uint32_t i = 0; i < ramg->hash_table_cell_count; i++) { + if(i != 0 && i % 128 == 0) { + lv_log("\n"); + } + + if(i == table_index_initial_guess) { + lv_log("^"); + } + else if(i == table_index) { + lv_log("$"); + } + else if(ramg->hash_table[i].key) { + lv_log("="); + } + else { + lv_log("-"); + } + } + + lv_log("\n\n"); +} +#endif + +#endif/*LV_USE_EVE_DRAW*/ + diff --git a/src/draw/eve/lv_draw_eve_ram_g.h b/src/draw/eve/lv_draw_eve_ram_g.h new file mode 100644 index 0000000000..ec6ae75352 --- /dev/null +++ b/src/draw/eve/lv_draw_eve_ram_g.h @@ -0,0 +1,48 @@ +/** + * @file lv_draw_eve_ram_g.h + * + */ + +/* Created on: 19 nov 2023 + * Author: juanj + * + * Modified by LVGL + */ + +#ifndef LV_DRAW_EVE_RAM_G_H +#define LV_DRAW_EVE_RAM_G_H + +#ifdef __cplusplus +extern "C" { +#endif + +/********************* + * INCLUDES + *********************/ +#include "lv_draw_eve.h" +#if LV_USE_DRAW_EVE + +/********************* + * DEFINES + *********************/ + +#define LV_DRAW_EVE_RAMG_OUT_OF_RAMG UINT32_MAX + +/********************** + * TYPEDEFS + **********************/ + +/********************** + * GLOBAL PROTOTYPES + **********************/ + +bool lv_draw_eve_ramg_get_addr(uint32_t * addr_dst, uintptr_t key, + uint32_t addr_size, uint32_t addr_align); + +#endif/*LV_USE_DRAW_EVE*/ + +#ifdef __cplusplus +} /*extern "C"*/ +#endif + +#endif /* LV_DRAW_EVE_RAM_G_H */ diff --git a/src/draw/eve/lv_draw_eve_target.h b/src/draw/eve/lv_draw_eve_target.h new file mode 100644 index 0000000000..90e938bb37 --- /dev/null +++ b/src/draw/eve/lv_draw_eve_target.h @@ -0,0 +1,79 @@ +/** + * @file lv_draw_eve_target.h + * + */ + +#ifndef LV_DRAW_EVE_TARGET_H +#define LV_DRAW_EVE_TARGET_H + +#ifdef __cplusplus +extern "C" { +#endif + +/********************* + * INCLUDES + *********************/ + +#include "../../lv_conf_internal.h" +#if LV_USE_DRAW_EVE + +#include "../../misc/lv_types.h" +#include LV_STDBOOL_INCLUDE +#include LV_STDINT_INCLUDE + +typedef struct { + uint16_t hor_res; /**< active display width */ + uint16_t ver_res; /**< active display height */ + uint16_t hcycle; /**< total number of clocks per line, incl front/back porch */ + uint16_t hoffset; /**< start of active line */ + uint16_t hsync0; /**< start of horizontal sync pulse */ + uint16_t hsync1; /**< end of horizontal sync pulse */ + uint16_t vcycle; /**< total number of lines per screen, including pre/post */ + uint16_t voffset; /**< start of active screen */ + uint16_t vsync0; /**< start of vertical sync pulse */ + uint16_t vsync1; /**< end of vertical sync pulse */ + uint8_t swizzle; /**< FT8xx output to LCD - pin order */ + uint8_t pclkpol; /**< LCD data is clocked in on this PCLK edge */ + uint8_t cspread; /**< helps with noise, when set to 1 fewer signals are changed simultaneously, reset-default: 1 */ + uint8_t pclk; /**< 60MHz / pclk = pclk frequency */ + bool has_crystal; /**< has an external clock crystal */ + bool has_gt911; /**< has a touch controller */ + uint8_t backlight_pwm; /**< backlight PWM duty cycle 0 = off, 128 = max */ + uint16_t backlight_freq; /**< backlight PWM frequency. try 4000 if unsure */ +} lv_draw_eve_parameters_t; + +typedef enum { + LV_DRAW_EVE_OPERATION_POWERDOWN_SET, /**< set the "PD_N" pin low */ + LV_DRAW_EVE_OPERATION_POWERDOWN_CLEAR, /**< set the "PD_N" pin high */ + LV_DRAW_EVE_OPERATION_CS_ASSERT, /**< set the "CS_N" pin low */ + LV_DRAW_EVE_OPERATION_CS_DEASSERT, /**< set the "CS_N" pin high */ + LV_DRAW_EVE_OPERATION_SPI_SEND, /**< send `length` bytes of `data` over SPI */ + LV_DRAW_EVE_OPERATION_SPI_RECEIVE /**< receive `length` bytes into `data` from SPI */ +} lv_draw_eve_operation_t; + +typedef void (*lv_draw_eve_operation_cb_t)(lv_display_t * disp, lv_draw_eve_operation_t operation, void * data, + uint32_t length); + +/********************* + * DEFINES + *********************/ + +/********************** + * TYPEDEFS + **********************/ + +/********************** + * GLOBAL PROTOTYPES + **********************/ + +/********************** + * MACROS + **********************/ + +#endif /*LV_USE_DRAW_EVE*/ + +#ifdef __cplusplus +} /*extern "C"*/ +#endif + +#endif /*LV_DRAW_EVE_TARGET_H*/ diff --git a/src/draw/eve/lv_draw_eve_triangle.c b/src/draw/eve/lv_draw_eve_triangle.c new file mode 100644 index 0000000000..b48411f59e --- /dev/null +++ b/src/draw/eve/lv_draw_eve_triangle.c @@ -0,0 +1,127 @@ +/** + * @file lv_draw_eve_triangle.c + * + */ + +/* Created on: 10 ene 2024 + * Author: juanj + * + * Modified by LVGL + */ + +/********************* + * INCLUDES + *********************/ +#include "lv_draw_eve_private.h" +#if LV_USE_DRAW_EVE + +#include "../../misc/lv_math.h" +#include "../../stdlib/lv_mem.h" +#include "../../misc/lv_area_private.h" +#include "../../misc/lv_color.h" +#include "../../stdlib/lv_string.h" +#include "lv_eve.h" + +/********************* + * DEFINES + *********************/ + +/********************** + * TYPEDEFS + **********************/ + +/********************** + * STATIC PROTOTYPES + **********************/ + +/********************** + * STATIC VARIABLES + **********************/ + +/********************** + * MACROS + **********************/ + +/********************** + * GLOBAL FUNCTIONS + **********************/ + +void lv_draw_eve_triangle(lv_draw_task_t * t, const lv_draw_triangle_dsc_t * dsc) +{ + + lv_area_t tri_area; + tri_area.x1 = (int32_t)LV_MIN3(dsc->p[0].x, dsc->p[1].x, dsc->p[2].x); + tri_area.y1 = (int32_t)LV_MIN3(dsc->p[0].y, dsc->p[1].y, dsc->p[2].y); + tri_area.x2 = (int32_t)LV_MAX3(dsc->p[0].x, dsc->p[1].x, dsc->p[2].x); + tri_area.y2 = (int32_t)LV_MAX3(dsc->p[0].y, dsc->p[1].y, dsc->p[2].y); + + bool is_common; + lv_area_t draw_area; + is_common = lv_area_intersect(&draw_area, &tri_area, &t->clip_area); + if(!is_common) return; + + lv_point_t p[3]; + /*If there is a vertical side use it as p[0] and p[1]*/ + if(dsc->p[0].x == dsc->p[1].x) { + p[0] = lv_point_from_precise(&dsc->p[0]); + p[1] = lv_point_from_precise(&dsc->p[1]); + p[2] = lv_point_from_precise(&dsc->p[2]); + } + else if(dsc->p[0].x == dsc->p[2].x) { + p[0] = lv_point_from_precise(&dsc->p[0]); + p[1] = lv_point_from_precise(&dsc->p[2]); + p[2] = lv_point_from_precise(&dsc->p[1]); + } + else if(dsc->p[1].x == dsc->p[2].x) { + p[0] = lv_point_from_precise(&dsc->p[1]); + p[1] = lv_point_from_precise(&dsc->p[2]); + p[2] = lv_point_from_precise(&dsc->p[0]); + } + else { + p[0] = lv_point_from_precise(&dsc->p[0]); + p[1] = lv_point_from_precise(&dsc->p[1]); + p[2] = lv_point_from_precise(&dsc->p[2]); + + /*Set the smallest y as p[0]*/ + if(p[0].y > p[1].y) lv_point_swap(&p[0], &p[1]); + if(p[0].y > p[2].y) lv_point_swap(&p[0], &p[2]); + + /*Set the greatest y as p[1]*/ + if(p[1].y < p[2].y) lv_point_swap(&p[1], &p[2]); + } + + /*Be sure p[0] is on the top*/ + if(p[0].y > p[1].y) lv_point_swap(&p[0], &p[1]); + + lv_eve_save_context(); + + lv_eve_scissor(t->clip_area.x1, t->clip_area.y1, t->clip_area.x2, t->clip_area.y2); + + lv_eve_color(dsc->color); + lv_eve_color_opa(dsc->opa); + + lv_eve_color_mask(0, 0, 0, 0); + lv_eve_stencil_op(EVE_KEEP, EVE_INVERT); + lv_eve_stencil_func(EVE_ALWAYS, 255, 255); + lv_eve_primitive(LV_EVE_PRIMITIVE_EDGE_STRIP_A); + + lv_eve_vertex_2f(p[0].x, p[0].y); + lv_eve_vertex_2f(p[1].x, p[1].y); + lv_eve_vertex_2f(p[2].x, p[2].y); + + lv_eve_color_mask(1, 1, 1, 1); + lv_eve_stencil_func(EVE_EQUAL, 255, 255) ; + + lv_eve_vertex_2f(0, 0); + lv_eve_vertex_2f(1022, 0); + + lv_eve_restore_context(); +} + +/********************** + * STATIC FUNCTIONS + **********************/ + +#endif /*LV_USE_DRAW_EVE*/ + + diff --git a/src/draw/eve/lv_eve.c b/src/draw/eve/lv_eve.c new file mode 100644 index 0000000000..145c4c7f25 --- /dev/null +++ b/src/draw/eve/lv_eve.c @@ -0,0 +1,265 @@ +/** + * @file lv_eve.c + * + */ + +/* Created on: 8 jun 2023 + * Author: juanj + * + * Modified by LVGL + */ + +/********************* + * INCLUDES + *********************/ +#include "lv_draw_eve.h" +#if LV_USE_DRAW_EVE +#include "lv_eve.h" +#include "../../libs/FT800-FT813/EVE_commands.h" + + +/********************* + * DEFINES + *********************/ + +/********************** + * TYPEDEFS + **********************/ + +/********************** + * STATIC PROTOTYPES + **********************/ + +/********************** + * STATIC VARIABLES + **********************/ + +static uint16_t scissor_x1 = 0; +static uint16_t scissor_y1 = 0; +static uint16_t scissor_x2 = 0; +static uint16_t scissor_y2 = 0; + +static lv_eve_drawing_context_t ct = { + .primitive = LV_EVE_PRIMITIVE_ZERO_VALUE, + .color = {0xff, 0xff, 0xff}, + .opa = 255, + .line_width = 1, /* for format(0) */ + .point_size = 1, + .color_mask = {1, 1, 1, 1}, + .stencil_func = {EVE_ALWAYS, 0, 255}, + .stencil_op = {EVE_KEEP, EVE_KEEP}, + .blend_func = {EVE_SRC_ALPHA, EVE_ONE_MINUS_SRC_ALPHA}, + .scx = 0, + .scy = 0, +}; + +static lv_eve_drawing_context_t ct_temp; + +static lv_eve_drawing_state_t st; + +/********************** + * MACROS + **********************/ + +/********************** + * GLOBAL FUNCTIONS + **********************/ + +void lv_eve_save_context(void) +{ + EVE_cmd_dl_burst(DL_SAVE_CONTEXT); + ct_temp = ct; +} + +void lv_eve_restore_context(void) +{ + EVE_cmd_dl_burst(DL_RESTORE_CONTEXT); + ct = ct_temp; +} + + +void lv_eve_primitive(uint8_t context) +{ + if(context != ct.primitive && context != LV_EVE_PRIMITIVE_ZERO_VALUE) { + EVE_cmd_dl_burst(DL_BEGIN | context); + ct.primitive = context; + } +} + +void lv_eve_scissor(uint16_t x1, uint16_t y1, uint16_t x2, uint16_t y2) +{ + if(x1 != scissor_x1 || y1 != scissor_y1) { + int16_t adjusted_x1 = x1 > 0 ? x1 - 1 : 0; + int16_t adjusted_y1 = y1 > 0 ? y1 - 1 : 0; + EVE_cmd_dl_burst(SCISSOR_XY(adjusted_x1, adjusted_y1)); + scissor_x1 = x1; + scissor_y1 = y1; + } + + if(x2 != scissor_x2 || y2 != scissor_y2) { + uint16_t w = x2 - x1 + 3; + uint16_t h = y2 - y1 + 3; + EVE_cmd_dl_burst(SCISSOR_SIZE(w, h)); + scissor_x2 = x2; + scissor_y2 = y2; + } +} + +void lv_eve_color(lv_color_t color) +{ + if((ct.color.red != color.red) || (ct.color.green != color.green) || (ct.color.blue != color.blue)) { + EVE_cmd_dl_burst(COLOR_RGB(color.red, color.green, color.blue)); + ct.color = color; + } +} + +void lv_eve_color_mask(uint8_t r, uint8_t g, uint8_t b, uint8_t a) +{ + if((ct.color_mask[0] != r) || + (ct.color_mask[1] != g) || + (ct.color_mask[2] != b) || + (ct.color_mask[3] != a)) { + + EVE_cmd_dl_burst(COLOR_MASK(r, g, b, a)); + ct.color_mask[0] = r; + ct.color_mask[1] = g; + ct.color_mask[2] = b; + ct.color_mask[3] = a; + } +} + +void lv_eve_stencil_func(uint8_t func, uint8_t ref, uint8_t mask) +{ + if(func != ct.stencil_func[0] || ref != ct.stencil_func[1] || mask != ct.stencil_func[2]) { + + EVE_cmd_dl_burst(STENCIL_FUNC(func, ref, mask)); + ct.stencil_func[0] = func; + ct.stencil_func[1] = ref; + ct.stencil_func[2] = mask; + } +} + +void lv_eve_stencil_op(uint8_t sfail, uint8_t spass) +{ + if(sfail != ct.stencil_op[0] || spass != ct.stencil_op[1]) { + EVE_cmd_dl_burst(STENCIL_OP(sfail, spass)); + ct.stencil_op[0] = sfail; + ct.stencil_op[1] = spass; + + } +} + +void lv_eve_blend_func(uint8_t src, uint8_t dst) +{ + if(src != ct.blend_func[0] || dst != ct.blend_func[1]) { + EVE_cmd_dl_burst(BLEND_FUNC(src, dst)); + ct.blend_func[0] = src; + ct.blend_func[1] = dst; + } +} + +void lv_eve_color_opa(lv_opa_t opa) +{ + if(opa != ct.opa) { + EVE_cmd_dl_burst(COLOR_A(opa)); + ct.opa = opa; + } +} + +void lv_eve_line_width(int32_t width) +{ + if(width != ct.line_width) { + EVE_cmd_dl_burst(LINE_WIDTH(width)); + ct.line_width = width; + } +} + +void lv_eve_point_size(uint16_t radius) +{ + if(radius != ct.point_size) { + EVE_cmd_dl_burst(POINT_SIZE(radius * 16)); + ct.point_size = radius; + } +} + +void lv_eve_vertex_2f(int16_t x, int16_t y) +{ + EVE_cmd_dl_burst(VERTEX2F(x, y)); +} + +void lv_eve_draw_circle_simple(int16_t coord_x1, int16_t coord_y1, uint16_t radius_t) +{ + lv_eve_primitive(LV_EVE_PRIMITIVE_POINTS); + lv_eve_point_size(radius_t); + lv_eve_vertex_2f(coord_x1, coord_y1); +} + + +void lv_eve_draw_rect_simple(int16_t coord_x1, int16_t coord_y1, int16_t coord_x2, int16_t coord_y2, uint16_t radius) +{ + lv_eve_primitive(LV_EVE_PRIMITIVE_RECTS); + if(radius > 1) { + lv_eve_line_width(radius * 16); + } + + lv_eve_vertex_2f(coord_x1 + radius, coord_y1 + radius); + lv_eve_vertex_2f(coord_x2 - radius, coord_y2 - radius); +} + +void lv_eve_mask_round(int16_t coord_x1, int16_t coord_y1, int16_t coord_x2, int16_t coord_y2, int16_t radius) +{ + lv_eve_color_mask(0, 0, 0, 1); + EVE_cmd_dl_burst(CLEAR(1, 1, 1)); + + + lv_eve_draw_rect_simple(coord_x1, coord_y1, coord_x2, coord_y2, radius); + lv_eve_color_mask(1, 1, 1, 0); + lv_eve_blend_func(EVE_DST_ALPHA, EVE_ONE_MINUS_DST_ALPHA); +} + +void lv_eve_bitmap_source(uint32_t addr) +{ + uint32_t bitmap_source = BITMAP_SOURCE(addr); + if(st.bitmap_source != bitmap_source) { + EVE_cmd_dl_burst(bitmap_source); + st.bitmap_source = bitmap_source; + } +} + +void lv_eve_bitmap_size(uint8_t filter, uint8_t wrapx, uint8_t wrapy, uint16_t width, uint16_t height) +{ + uint32_t bitmap_size = BITMAP_SIZE(filter, wrapx, wrapy, width, height); + if(st.bitmap_size != bitmap_size) { + EVE_cmd_dl_burst(bitmap_size); + st.bitmap_size = bitmap_size; + } + /* set the high bits too, of the width and height */ + uint32_t bitmap_size_h = BITMAP_SIZE_H(width, height); + if(st.bitmap_size_h != bitmap_size_h) { + EVE_cmd_dl_burst(bitmap_size_h); + st.bitmap_size_h = bitmap_size_h; + } +} + +void lv_eve_bitmap_layout(uint8_t format, uint16_t linestride, uint16_t height) +{ + uint32_t bitmap_layout = BITMAP_LAYOUT(format, linestride, height); + if(st.bitmap_layout != bitmap_layout) { + EVE_cmd_dl_burst(bitmap_layout); + st.bitmap_layout = bitmap_layout; + } + /* set the high bits too, of the linestride and height */ + uint32_t bitmap_layout_h = BITMAP_LAYOUT_H(linestride, height); + if(st.bitmap_layout_h != bitmap_layout_h) { + EVE_cmd_dl_burst(bitmap_layout_h); + st.bitmap_layout_h = bitmap_layout_h; + } +} + + + +/********************** + * STATIC FUNCTIONS + **********************/ + +#endif /*LV_USE_DRAW_EVE*/ diff --git a/src/draw/eve/lv_eve.h b/src/draw/eve/lv_eve.h new file mode 100644 index 0000000000..b48bd11519 --- /dev/null +++ b/src/draw/eve/lv_eve.h @@ -0,0 +1,151 @@ +/** + * @file lv_eve.h + * + */ + +/* Created on: 8 jun 2023 + * Author: juanj + * + * Modified by LVGL + */ + +#ifndef LV_EVE_H +#define LV_EVE_H + +#ifdef __cplusplus +extern "C" { +#endif + +/********************* + * INCLUDES + *********************/ + +#include "lv_draw_eve.h" + +#if LV_USE_DRAW_EVE + +#include "../../misc/lv_types.h" +#include "../../misc/lv_color.h" +#include "../../libs/FT800-FT813/EVE.h" + +/********************* + * DEFINES + *********************/ + +/********************** + * TYPEDEFS + **********************/ +typedef enum { + LV_EVE_PRIMITIVE_ZERO_VALUE, + LV_EVE_PRIMITIVE_BITMAPS = 1UL, /* Bitmap drawing primitive */ + LV_EVE_PRIMITIVE_POINTS = 2UL, /* Point drawing primitive */ + LV_EVE_PRIMITIVE_LINES = 3UL, /* Line drawing primitive */ + LV_EVE_PRIMITIVE_LINE_STRIP = 4UL, /* Line strip drawing primitive */ + LV_EVE_PRIMITIVE_EDGE_STRIP_R = 5UL, /* Edge strip right side drawing primitive */ + LV_EVE_PRIMITIVE_EDGE_STRIP_L = 6UL, /* Edge strip left side drawing primitive */ + LV_EVE_PRIMITIVE_EDGE_STRIP_A = 7UL, /* Edge strip above drawing primitive */ + LV_EVE_PRIMITIVE_EDGE_STRIP_B = 8UL, /* Edge strip below side drawing primitive */ + LV_EVE_PRIMITIVE_RECTS = 9UL, /* Rectangle drawing primitive */ +} lv_eve_primitive_t; + + +typedef struct { + lv_eve_primitive_t primitive; + lv_color_t color; + lv_opa_t opa; + int32_t line_width; + uint16_t point_size; + uint8_t color_mask[4]; + uint8_t stencil_func[3]; + uint8_t stencil_op[2]; + uint8_t blend_func[2]; + uint16_t scx; + uint16_t scy; +} lv_eve_drawing_context_t; + +/* drawing context that is not saved and restored + * by SAVE_CONTEXT and RESTORE_CONTEXT + */ +typedef struct { + uint32_t bitmap_source; + uint32_t bitmap_size; + uint32_t bitmap_size_h; + uint32_t bitmap_layout; + uint32_t bitmap_layout_h; +} lv_eve_drawing_state_t; + +/********************** + * GLOBAL PROTOTYPES + **********************/ + +void lv_eve_save_context(void); +void lv_eve_restore_context(void); +void lv_eve_scissor(uint16_t x1, uint16_t y1, uint16_t x2, uint16_t y2); +void lv_eve_primitive(uint8_t context); +void lv_eve_color(lv_color_t color); +void lv_eve_color_opa(lv_opa_t opa); +void lv_eve_line_width(int32_t width); +void lv_eve_point_size(uint16_t radius); +void lv_eve_vertex_2f(int16_t x, int16_t y); +void lv_eve_color_mask(uint8_t r, uint8_t g, uint8_t b, uint8_t a); +void lv_eve_stencil_func(uint8_t func, uint8_t ref, uint8_t mask); +void lv_eve_stencil_op(uint8_t sfail, uint8_t spass); +void lv_eve_blend_func(uint8_t src, uint8_t dst); + +void lv_eve_draw_circle_simple(int16_t coord_x1, int16_t coord_y1, uint16_t radius_t); +void lv_eve_draw_rect_simple(int16_t coord_x1, int16_t coord_y1, int16_t coord_x2, int16_t coord_y2, + uint16_t radius); +void lv_eve_mask_round(int16_t coord_x1, int16_t coord_y1, int16_t coord_x2, int16_t coord_y2, int16_t radius); + +/** + * Set the bitmap source to `addr`. SPI transmission will occur unless it is already set to this value. + * The bitmap source is not part of the saved and restored context. + * @param addr the remote EVE memory address to set as the bitmap source + */ +void lv_eve_bitmap_source(uint32_t addr); + +/** + * Set the bitmap size and sampling parameters. SPI transmission will occur unless the currently set parameters are already these. + * The bitmap size is not part of the saved and restored context. + * @param filter the sampling method. Either EVE_NEAREST or EVE_BILINEAR + * @param wrapx the out of bounds sampling behavior in the X direction. Either EVE_BORDER or EVE_REPEAT + * @param wrapy the out of bounds sampling behavior in the Y direction. Either EVE_BORDER or EVE_REPEAT + * @param width the width of the bitmap in pixels + * @param height the height of the bitmap in pixels + */ +void lv_eve_bitmap_size(uint8_t filter, uint8_t wrapx, uint8_t wrapy, uint16_t width, uint16_t height); + +/** + * Set the bitmap format/layout parameters. SPI transmission will occur unless the currently set parameters are already these. + * The bitmap layout is not part of the saved and restored context. + * @param format an eve color format value like EVE_RGB565 + * @param linestride the stride of the bitmap rows in bytes + * @param height the number of rows in the bitmap + */ +void lv_eve_bitmap_layout(uint8_t format, uint16_t linestride, uint16_t height); + +/********************** + * EXTERN VARIABLES + **********************/ + + +/********************** + * MACROS + **********************/ + +/********************** + * INLINE FUNCTIONS + **********************/ + +/********************** + * STATIC FUNCTIONS + **********************/ + +#endif /*LV_USE_DRAW_EVE*/ + + +#ifdef __cplusplus +} /*extern "C"*/ +#endif + +#endif /* LV_EVE_H */ diff --git a/src/draw/lv_draw.c b/src/draw/lv_draw.c index a80ae196fc..24eecdadb6 100644 --- a/src/draw/lv_draw.c +++ b/src/draw/lv_draw.c @@ -12,6 +12,7 @@ *********************/ #include "../misc/lv_area_private.h" #include "../misc/lv_assert.h" +#include "../misc/lv_event_private.h" #include "lv_draw_private.h" #include "lv_draw_mask_private.h" #include "lv_draw_vector_private.h" @@ -34,7 +35,7 @@ /********************** * STATIC PROTOTYPES **********************/ -static bool is_independent(lv_layer_t * layer, lv_draw_task_t * t_check); +static bool is_independent(lv_layer_t * layer, lv_draw_task_t * t_check, uint8_t draw_unit_id); static void cleanup_task(lv_draw_task_t * t, lv_display_t * disp); static inline size_t get_draw_dsc_size(lv_draw_task_type_t type); static lv_draw_task_t * get_first_available_task(lv_layer_t * layer); @@ -110,9 +111,10 @@ lv_draw_task_t * lv_draw_add_task(lv_layer_t * layer, const lv_area_t * coords, #if LV_DRAW_TRANSFORM_USE_MATRIX new_task->matrix = layer->matrix; #endif + new_task->opa = layer->opa; new_task->type = type; new_task->draw_dsc = (uint8_t *)new_task + LV_ALIGN_UP(sizeof(lv_draw_task_t), 8); - new_task->state = LV_DRAW_TASK_STATE_QUEUED; + new_task->state = LV_DRAW_TASK_STATE_WAITING; /*Find the tail*/ if(layer->draw_task_head == NULL) { @@ -165,7 +167,7 @@ void lv_draw_finalize_task_creation(lv_layer_t * layer, lv_draw_task_t * t) } if(t->preferred_draw_unit_id == LV_DRAW_UNIT_NONE) { LV_LOG_WARN("the draw task was not taken by any units"); - t->state = LV_DRAW_TASK_STATE_READY; + t->state = LV_DRAW_TASK_STATE_FINISHED; } else { lv_draw_dispatch(); @@ -213,19 +215,18 @@ void lv_draw_dispatch(void) { LV_PROFILER_DRAW_BEGIN; bool task_dispatched = false; - lv_display_t * disp = lv_display_get_next(NULL); - while(disp) { + lv_display_t * disp = lv_refr_get_disp_refreshing(); + if(disp != NULL) { lv_layer_t * layer = disp->layer_head; while(layer) { if(lv_draw_dispatch_layer(disp, layer)) task_dispatched = true; layer = layer->next; } - if(!task_dispatched) { - lv_draw_wait_for_finish(); - lv_draw_dispatch_request(); - } - disp = lv_display_get_next(disp); + } + if(!task_dispatched) { + lv_draw_wait_for_finish(); + lv_draw_dispatch_request(); } LV_PROFILER_DRAW_END; } @@ -240,7 +241,7 @@ bool lv_draw_dispatch_layer(lv_display_t * disp, lv_layer_t * layer) bool remove_task = false; while(t) { t_next = t->next; - if(t->state == LV_DRAW_TASK_STATE_READY) { + if(t->state == LV_DRAW_TASK_STATE_FINISHED) { cleanup_task(t, disp); remove_task = true; if(t_prev != NULL) @@ -261,10 +262,10 @@ bool lv_draw_dispatch_layer(lv_display_t * disp, lv_layer_t * layer) /*Find a draw task with TYPE_LAYER in the layer where the src is this layer*/ lv_draw_task_t * t_src = layer->parent->draw_task_head; while(t_src) { - if(t_src->type == LV_DRAW_TASK_TYPE_LAYER && t_src->state == LV_DRAW_TASK_STATE_WAITING) { + if(t_src->type == LV_DRAW_TASK_TYPE_LAYER && t_src->state == LV_DRAW_TASK_STATE_BLOCKED) { lv_draw_image_dsc_t * draw_dsc = t_src->draw_dsc; if(draw_dsc->src == layer) { - t_src->state = LV_DRAW_TASK_STATE_QUEUED; + t_src->state = LV_DRAW_TASK_STATE_WAITING; lv_draw_dispatch_request(); break; } @@ -339,7 +340,7 @@ lv_draw_task_t * lv_draw_get_next_available_task(lv_layer_t * layer, lv_draw_tas int32_t hor_res = lv_display_get_horizontal_resolution(lv_refr_get_disp_refreshing()); int32_t ver_res = lv_display_get_vertical_resolution(lv_refr_get_disp_refreshing()); lv_draw_task_t * t = layer->draw_task_head; - if(t->state != LV_DRAW_TASK_STATE_QUEUED && + if(t->state != LV_DRAW_TASK_STATE_WAITING && t->area.x1 <= 0 && t->area.x2 >= hor_res - 1 && t->area.y1 <= 0 && t->area.y2 >= ver_res - 1) { LV_PROFILER_DRAW_END; @@ -349,13 +350,14 @@ lv_draw_task_t * lv_draw_get_next_available_task(lv_layer_t * layer, lv_draw_tas lv_draw_task_t * t = t_prev ? t_prev->next : layer->draw_task_head; while(t) { - /*Find a queued and independent task*/ - if(t->state == LV_DRAW_TASK_STATE_QUEUED && - (t->preferred_draw_unit_id == LV_DRAW_UNIT_NONE || t->preferred_draw_unit_id == draw_unit_id) && - is_independent(layer, t)) { + /*Find a draw task for this draw unit which is waiting and independent?*/ + if((t->preferred_draw_unit_id == draw_unit_id || t->preferred_draw_unit_id == LV_DRAW_UNIT_NONE) && + t->state == LV_DRAW_TASK_STATE_WAITING && + is_independent(layer, t, draw_unit_id)) { LV_PROFILER_DRAW_END; return t; } + t = t->next; } @@ -373,7 +375,7 @@ uint32_t lv_draw_get_dependent_count(lv_draw_task_t * t_check) lv_draw_task_t * t = t_check->next; while(t) { - if((t->state == LV_DRAW_TASK_STATE_QUEUED || t->state == LV_DRAW_TASK_STATE_WAITING) && + if((t->state == LV_DRAW_TASK_STATE_WAITING || t->state == LV_DRAW_TASK_STATE_BLOCKED) && lv_area_is_on(&t_check->area, &t->area)) { cnt++; } @@ -384,6 +386,29 @@ uint32_t lv_draw_get_dependent_count(lv_draw_task_t * t_check) return cnt; } +void lv_draw_unit_send_event(const char * name, lv_event_code_t code, void * param) +{ + LV_PROFILER_DRAW_BEGIN; + + lv_event_t event = { 0 }; + event.code = code; + event.param = param; + lv_draw_unit_t * u = _draw_info.unit_head; + while(u) { + if(u->event_cb && (!name || lv_strcmp(name, u->name) == 0)) { + event.current_target = event.original_target = u; + LV_PROFILER_DRAW_BEGIN_TAG("event_cb"); + LV_PROFILER_DRAW_BEGIN_TAG(u->name); + u->event_cb(&event); + LV_PROFILER_DRAW_END_TAG(u->name); + LV_PROFILER_DRAW_END_TAG("event_cb"); + } + u = u->next; + } + + LV_PROFILER_DRAW_END; +} + void lv_layer_init(lv_layer_t * layer) { LV_ASSERT_NULL(layer); @@ -518,23 +543,30 @@ void lv_draw_task_get_area(const lv_draw_task_t * t, lv_area_t * area) /** * Check if there are older draw task overlapping the area of `t_check` - * @param layer the draw ctx to search in + * @param layer the draw ctx to search in * @param t_check check this task if it overlaps with the older ones + * @param draw_unit_id draw unit ID for which the independence check is called * @return true: `t_check` is not overlapping with older tasks so it's independent */ -static bool is_independent(lv_layer_t * layer, lv_draw_task_t * t_check) +static bool is_independent(lv_layer_t * layer, lv_draw_task_t * t_check, uint8_t draw_unit_id) { LV_PROFILER_DRAW_BEGIN; lv_draw_task_t * t = layer->draw_task_head; /*If t_check is outside of the older tasks then it's independent*/ while(t && t != t_check) { - if(t->state != LV_DRAW_TASK_STATE_READY) { - lv_area_t a; - if(lv_area_intersect(&a, &t->_real_area, &t_check->_real_area)) { - LV_PROFILER_DRAW_END; - return false; - } + /*It's independent of finished draw tasks, and queued draw tasks of the same draw unit, + *so no need to check it*/ + if(t->state == LV_DRAW_TASK_STATE_FINISHED || + (t->state == LV_DRAW_TASK_STATE_QUEUED && t->preferred_draw_unit_id == draw_unit_id)) { + t = t->next; + continue; + } + + lv_area_t a; + if(lv_area_intersect(&a, &t->_real_area, &t_check->_real_area)) { + LV_PROFILER_DRAW_END; + return false; } t = t->next; } @@ -581,7 +613,7 @@ static inline size_t get_draw_dsc_size(lv_draw_task_type_t type) return 0; #if LV_USE_VECTOR_GRAPHIC case LV_DRAW_TASK_TYPE_VECTOR: - return sizeof(lv_draw_vector_task_dsc_t); + return sizeof(lv_draw_vector_dsc_t); #endif #if LV_USE_3DTEXTURE case LV_DRAW_TASK_TYPE_3D: @@ -662,16 +694,16 @@ static lv_draw_task_t * get_first_available_task(lv_layer_t * layer) * all its tasks are ready. As other areas might be on top of that * layer-to-blend don't skip it. Instead stop there, so that the * draw tasks of that layer can be consumed and can be finished. - * After that this layer-to-blenf will have `LV_DRAW_TASK_STATE_QUEUED` + * After that this layer-to-blenf will have `LV_DRAW_TASK_STATE_WAITING` * so it can be blended normally.*/ lv_draw_task_t * t = layer->draw_task_head; while(t) { - /*Not queued yet, leave this layer while the first task is queued*/ - if(t->state != LV_DRAW_TASK_STATE_QUEUED) { + /*Not waiting to be rendered, leave this layer while the first task is ready (i.e. not blocked)*/ + if(t->state != LV_DRAW_TASK_STATE_WAITING) { t = NULL; break; } - /*It's a supported and queued task, process it*/ + /*Waiting to be rendered, use it*/ else { break; } diff --git a/src/draw/lv_draw.h b/src/draw/lv_draw.h index d394de87c8..dd8291da5c 100644 --- a/src/draw/lv_draw.h +++ b/src/draw/lv_draw.h @@ -24,6 +24,7 @@ extern "C" { #include "../misc/lv_text.h" #include "../misc/lv_profiler.h" #include "../misc/lv_matrix.h" +#include "../misc/lv_event.h" #include "lv_image_decoder.h" #include "lv_draw_buf.h" @@ -66,22 +67,52 @@ typedef enum { } lv_draw_task_type_t; typedef enum { - LV_DRAW_TASK_STATE_WAITING, /*Waiting for something to be finished. E.g. rendering a layer*/ + /** Waiting for an other task to be finished. + * For example in case of `LV_DRAW_TASK_TYPE_LAYER` (used to blend a layer) + * is blocked until all the draw tasks of the layer is rendered. */ + LV_DRAW_TASK_STATE_BLOCKED, + + /** The draw task is added to the layers list and waits to be rendered. */ + LV_DRAW_TASK_STATE_WAITING, + + /** The draw task is added to the command queue of the draw unit. + * As the queued task are executed in order it's possible to queue multiple draw task + * (for the same draw unit) even if they are depending on each other. + * Therefore `lv_draw_get_available_task` and `lv_draw_get_next_available_task` can return + * draw task for the same draw unit even if a dependent draw task is not finished ready yet.*/ LV_DRAW_TASK_STATE_QUEUED, + + /** The draw task is being rendered. This draw task needs to be finished before + * `lv_draw_get_available_task` and `lv_draw_get_next_available_task` would + * return any depending draw tasks.*/ LV_DRAW_TASK_STATE_IN_PROGRESS, - LV_DRAW_TASK_STATE_READY, + + /** The draw task is rendered. It will be removed from the draw task list of the layer + * and freed automatically. */ + LV_DRAW_TASK_STATE_FINISHED, } lv_draw_task_state_t; struct _lv_layer_t { - - /** Target draw buffer of the layer*/ + /** Target draw buffer of the layer */ lv_draw_buf_t * draw_buf; + /** Linked list of draw tasks */ + lv_draw_task_t * draw_task_head; + + /** Parent layer */ + lv_layer_t * parent; + + /** Next layer */ + lv_layer_t * next; + + /** User data */ + void * user_data; + /** The absolute coordinates of the buffer */ lv_area_t buf_area; - /** The color format of the layer. LV_COLOR_FORMAT_... */ - lv_color_format_t color_format; + /** The physical clipping area relative to the display */ + lv_area_t phy_clip_area; /** * NEVER USE IT DRAW UNITS. USED INTERNALLY DURING DRAW TASK CREATION. @@ -93,32 +124,25 @@ struct _lv_layer_t { */ lv_area_t _clip_area; - /** - * The physical clipping area relative to the display. - */ - lv_area_t phy_clip_area; - #if LV_DRAW_TRANSFORM_USE_MATRIX /** Transform matrix to be applied when rendering the layer */ lv_matrix_t matrix; #endif - /** Opacity of the layer */ - lv_opa_t opa; - - /*Recolor of the layer*/ - lv_color32_t recolor; - /** Partial y offset */ int32_t partial_y_offset; - /** Linked list of draw tasks */ - lv_draw_task_t * draw_task_head; + /** Recolor of the layer */ + lv_color32_t recolor; - lv_layer_t * parent; - lv_layer_t * next; + /** The color format of the layer. LV_COLOR_FORMAT_... */ + lv_color_format_t color_format; + + /** Flag indicating all tasks are added */ bool all_tasks_added; - void * user_data; + + /** Opacity of the layer */ + lv_opa_t opa; }; typedef struct { @@ -126,7 +150,7 @@ typedef struct { lv_obj_t * obj; /**The widget part for which draw descriptor was created */ - lv_part_t part; + uint32_t part; /**A widget type specific ID (e.g. table row index). See the docs of the given widget.*/ uint32_t id1; @@ -248,6 +272,15 @@ lv_draw_task_t * lv_draw_get_next_available_task(lv_layer_t * layer, lv_draw_tas */ uint32_t lv_draw_get_dependent_count(lv_draw_task_t * t_check); + +/** + * Send an event to the draw units + * @param name the name of the draw unit to send the event to + * @param code the event code + * @param param the event parameter + */ +void lv_draw_unit_send_event(const char * name, lv_event_code_t code, void * param); + /** * Initialize a layer * @param layer pointer to a layer to initialize diff --git a/src/draw/lv_draw_3d.c b/src/draw/lv_draw_3d.c index 0ea6cbc759..110e0805ca 100644 --- a/src/draw/lv_draw_3d.c +++ b/src/draw/lv_draw_3d.c @@ -41,6 +41,8 @@ void lv_draw_3d_dsc_init(lv_draw_3d_dsc_t * dsc) lv_memzero(dsc, sizeof(lv_draw_3d_dsc_t)); dsc->base.dsc_size = sizeof(lv_draw_3d_dsc_t); dsc->tex_id = LV_3DTEXTURE_ID_NULL; + dsc->h_flip = false; + dsc->v_flip = false; dsc->opa = LV_OPA_COVER; } diff --git a/src/draw/lv_draw_3d.h b/src/draw/lv_draw_3d.h index 436be9a8f5..61bfb36229 100644 --- a/src/draw/lv_draw_3d.h +++ b/src/draw/lv_draw_3d.h @@ -30,6 +30,8 @@ extern "C" { typedef struct { lv_draw_dsc_base_t base; lv_3dtexture_id_t tex_id; + bool h_flip; + bool v_flip; lv_opa_t opa; } lv_draw_3d_dsc_t; diff --git a/src/draw/lv_draw_arc.h b/src/draw/lv_draw_arc.h index 1178ecb3ae..9041b24c18 100644 --- a/src/draw/lv_draw_arc.h +++ b/src/draw/lv_draw_arc.h @@ -45,12 +45,12 @@ typedef struct { /**The center point of the arc. */ lv_point_t center; - /**The outer radius of the arc*/ - uint16_t radius; - /**An image source to be used instead of `color`. `NULL` if unused*/ const void * img_src; + /**The outer radius of the arc*/ + uint16_t radius; + /**Opacity of the arc in 0...255 range. * LV_OPA_TRANSP, LV_OPA_10, LV_OPA_20, .. LV_OPA_COVER can be used as well*/ lv_opa_t opa; diff --git a/src/draw/lv_draw_buf.c b/src/draw/lv_draw_buf.c index 58562a86e5..8e942dd3a4 100644 --- a/src/draw/lv_draw_buf.c +++ b/src/draw/lv_draw_buf.c @@ -12,6 +12,7 @@ #include "../core/lv_global.h" #include "../misc/lv_math.h" #include "../misc/lv_area_private.h" +#include "convert/lv_draw_buf_convert.h" /********************* * DEFINES @@ -29,6 +30,8 @@ **********************/ static void * buf_malloc(size_t size, lv_color_format_t color_format); static void buf_free(void * buf); +static void buf_copy(lv_draw_buf_t * dest, const lv_area_t * dest_area, + const lv_draw_buf_t * src, const lv_area_t * src_area); static void * buf_align(void * buf, lv_color_format_t color_format); static void * draw_buf_malloc(const lv_draw_buf_handlers_t * handler, size_t size_bytes, lv_color_format_t color_format); @@ -58,20 +61,22 @@ void lv_draw_buf_init_handlers(void) void lv_draw_buf_init_with_default_handlers(lv_draw_buf_handlers_t * handlers) { - lv_draw_buf_handlers_init(handlers, buf_malloc, buf_free, buf_align, NULL, NULL, width_to_stride); + lv_draw_buf_handlers_init(handlers, buf_malloc, buf_free, buf_copy, buf_align, NULL, NULL, width_to_stride); } void lv_draw_buf_handlers_init(lv_draw_buf_handlers_t * handlers, - lv_draw_buf_malloc_cb buf_malloc_cb, - lv_draw_buf_free_cb buf_free_cb, - lv_draw_buf_align_cb align_pointer_cb, - lv_draw_buf_cache_operation_cb invalidate_cache_cb, - lv_draw_buf_cache_operation_cb flush_cache_cb, - lv_draw_buf_width_to_stride_cb width_to_stride_cb) + lv_draw_buf_malloc_cb_t buf_malloc_cb, + lv_draw_buf_free_cb_t buf_free_cb, + lv_draw_buf_copy_cb_t buf_copy_cb, + lv_draw_buf_align_cb_t align_pointer_cb, + lv_draw_buf_cache_operation_cb_t invalidate_cache_cb, + lv_draw_buf_cache_operation_cb_t flush_cache_cb, + lv_draw_buf_width_to_stride_cb_t width_to_stride_cb) { lv_memzero(handlers, sizeof(lv_draw_buf_handlers_t)); handlers->buf_malloc_cb = buf_malloc_cb; handlers->buf_free_cb = buf_free_cb; + handlers->buf_copy_cb = buf_copy_cb; handlers->align_pointer_cb = align_pointer_cb; handlers->invalidate_cache_cb = invalidate_cache_cb; handlers->flush_cache_cb = flush_cache_cb; @@ -210,64 +215,6 @@ void lv_draw_buf_clear(lv_draw_buf_t * draw_buf, const lv_area_t * a) LV_PROFILER_DRAW_END; } -void lv_draw_buf_copy(lv_draw_buf_t * dest, const lv_area_t * dest_area, - const lv_draw_buf_t * src, const lv_area_t * src_area) -{ - LV_PROFILER_DRAW_BEGIN; - uint8_t * dest_bufc; - uint8_t * src_bufc; - int32_t line_width; - - /*Source and dest color format must be same. Color conversion is not supported yet.*/ - LV_ASSERT_FORMAT_MSG(dest->header.cf == src->header.cf, "Color format mismatch: %d != %d", - dest->header.cf, src->header.cf); - - if(dest_area == NULL) line_width = dest->header.w; - else line_width = lv_area_get_width(dest_area); - - /* For indexed image, copy the palette if we are copying full image area*/ - if(dest_area == NULL || src_area == NULL) { - if(LV_COLOR_FORMAT_IS_INDEXED(dest->header.cf)) { - lv_memcpy(dest->data, src->data, LV_COLOR_INDEXED_PALETTE_SIZE(dest->header.cf) * sizeof(lv_color32_t)); - } - } - - /*Check source and dest area have same width*/ - if((src_area == NULL && line_width != src->header.w) || \ - (src_area != NULL && line_width != lv_area_get_width(src_area))) { - LV_ASSERT_MSG(0, "Source and destination areas have different width"); - LV_PROFILER_DRAW_END; - return; - } - - if(src_area) src_bufc = lv_draw_buf_goto_xy(src, src_area->x1, src_area->y1); - else src_bufc = lv_draw_buf_goto_xy(src, 0, 0); - - if(dest_area) dest_bufc = lv_draw_buf_goto_xy(dest, dest_area->x1, dest_area->y1); - else dest_bufc = lv_draw_buf_goto_xy(dest, 0, 0); - - int32_t start_y, end_y; - if(dest_area) { - start_y = dest_area->y1; - end_y = dest_area->y2; - } - else { - start_y = 0; - end_y = dest->header.h - 1; - } - - uint32_t dest_stride = dest->header.stride; - uint32_t src_stride = src->header.stride; - uint32_t line_bytes = (line_width * lv_color_format_get_bpp(dest->header.cf) + 7) >> 3; - - for(; start_y <= end_y; start_y++) { - lv_memcpy(dest_bufc, src_bufc, line_bytes); - dest_bufc += dest_stride; - src_bufc += src_stride; - } - LV_PROFILER_DRAW_END; -} - lv_result_t lv_draw_buf_init(lv_draw_buf_t * draw_buf, uint32_t w, uint32_t h, lv_color_format_t cf, uint32_t stride, void * data, uint32_t data_size) { @@ -416,11 +363,28 @@ void lv_draw_buf_destroy(lv_draw_buf_t * draw_buf) LV_PROFILER_DRAW_END; } +void lv_draw_buf_copy(lv_draw_buf_t * dest, const lv_area_t * dest_area, + const lv_draw_buf_t * src, const lv_area_t * src_area) +{ + LV_ASSERT_NULL(dest); + LV_ASSERT_NULL(dest->handlers); + LV_ASSERT_NULL(dest->handlers->buf_copy_cb); + LV_ASSERT_NULL(src); + + dest->handlers->buf_copy_cb(dest, dest_area, src, src_area); +} + void * lv_draw_buf_goto_xy(const lv_draw_buf_t * buf, uint32_t x, uint32_t y) { LV_ASSERT_NULL(buf); if(buf == NULL) return NULL; + if(x >= buf->header.w || y >= buf->header.h) { + LV_LOG_ERROR("coordinates out of range, x: %" LV_PRIu32 ", y: %"LV_PRIu32", w: %"LV_PRIu32", h: %"LV_PRIu32, x, y, + (uint32_t)buf->header.w, (uint32_t)buf->header.h); + return NULL; + } + uint8_t * data = buf->data; /*Skip palette*/ @@ -515,67 +479,7 @@ lv_result_t lv_draw_buf_premultiply(lv_draw_buf_t * draw_buf) } LV_PROFILER_DRAW_BEGIN; - /*Premultiply color with alpha, do case by case by judging color format*/ - lv_color_format_t cf = draw_buf->header.cf; - if(LV_COLOR_FORMAT_IS_INDEXED(cf)) { - int size = LV_COLOR_INDEXED_PALETTE_SIZE(cf); - lv_color32_t * palette = (lv_color32_t *)draw_buf->data; - for(int i = 0; i < size; i++) { - lv_color_premultiply(&palette[i]); - } - } - else if(cf == LV_COLOR_FORMAT_ARGB8888) { - uint32_t h = draw_buf->header.h; - uint32_t w = draw_buf->header.w; - uint32_t stride = draw_buf->header.stride; - uint8_t * line = (uint8_t *)draw_buf->data; - for(uint32_t y = 0; y < h; y++) { - lv_color32_t * pixel = (lv_color32_t *)line; - for(uint32_t x = 0; x < w; x++) { - lv_color_premultiply(pixel); - pixel++; - } - line += stride; - } - } - else if(cf == LV_COLOR_FORMAT_RGB565A8) { - uint32_t h = draw_buf->header.h; - uint32_t w = draw_buf->header.w; - uint32_t stride = draw_buf->header.stride; - uint32_t alpha_stride = stride / 2; - uint8_t * line = (uint8_t *)draw_buf->data; - lv_opa_t * alpha = (lv_opa_t *)(line + stride * h); - for(uint32_t y = 0; y < h; y++) { - lv_color16_t * pixel = (lv_color16_t *)line; - for(uint32_t x = 0; x < w; x++) { - lv_color16_premultiply(pixel, alpha[x]); - pixel++; - } - line += stride; - alpha += alpha_stride; - } - } - else if(cf == LV_COLOR_FORMAT_ARGB8565) { - uint32_t h = draw_buf->header.h; - uint32_t w = draw_buf->header.w; - uint32_t stride = draw_buf->header.stride; - uint8_t * line = (uint8_t *)draw_buf->data; - for(uint32_t y = 0; y < h; y++) { - uint8_t * pixel = line; - for(uint32_t x = 0; x < w; x++) { - uint8_t alpha = pixel[2]; - lv_color16_premultiply((lv_color16_t *)pixel, alpha); - pixel += 3; - } - line += stride; - } - } - else if(LV_COLOR_FORMAT_IS_ALPHA_ONLY(cf)) { - /*Pass*/ - } - else { - LV_LOG_WARN("draw buf has no alpha, cf: %d", cf); - } + lv_draw_buf_convert_premultiply(draw_buf); draw_buf->header.flags |= LV_IMAGE_FLAGS_PREMULTIPLIED; @@ -664,6 +568,64 @@ static void buf_free(void * buf) lv_free(buf); } +static void buf_copy(lv_draw_buf_t * dest, const lv_area_t * dest_area, + const lv_draw_buf_t * src, const lv_area_t * src_area) +{ + LV_PROFILER_DRAW_BEGIN; + uint8_t * dest_bufc; + uint8_t * src_bufc; + int32_t line_width; + + /*Source and dest color format must be same. Color conversion is not supported yet.*/ + LV_ASSERT_FORMAT_MSG(dest->header.cf == src->header.cf, "Color format mismatch: %d != %d", + dest->header.cf, src->header.cf); + + if(dest_area == NULL) line_width = dest->header.w; + else line_width = lv_area_get_width(dest_area); + + /* For indexed image, copy the palette if we are copying full image area*/ + if(dest_area == NULL || src_area == NULL) { + if(LV_COLOR_FORMAT_IS_INDEXED(dest->header.cf)) { + lv_memcpy(dest->data, src->data, LV_COLOR_INDEXED_PALETTE_SIZE(dest->header.cf) * sizeof(lv_color32_t)); + } + } + + /*Check source and dest area have same width*/ + if((src_area == NULL && line_width != src->header.w) || \ + (src_area != NULL && line_width != lv_area_get_width(src_area))) { + LV_ASSERT_MSG(0, "Source and destination areas have different width"); + LV_PROFILER_DRAW_END; + return; + } + + if(src_area) src_bufc = lv_draw_buf_goto_xy(src, src_area->x1, src_area->y1); + else src_bufc = lv_draw_buf_goto_xy(src, 0, 0); + + if(dest_area) dest_bufc = lv_draw_buf_goto_xy(dest, dest_area->x1, dest_area->y1); + else dest_bufc = lv_draw_buf_goto_xy(dest, 0, 0); + + int32_t start_y, end_y; + if(dest_area) { + start_y = dest_area->y1; + end_y = dest_area->y2; + } + else { + start_y = 0; + end_y = dest->header.h - 1; + } + + uint32_t dest_stride = dest->header.stride; + uint32_t src_stride = src->header.stride; + uint32_t line_bytes = (line_width * lv_color_format_get_bpp(dest->header.cf) + 7) >> 3; + + for(; start_y <= end_y; start_y++) { + lv_memcpy(dest_bufc, src_bufc, line_bytes); + dest_bufc += dest_stride; + src_bufc += src_stride; + } + LV_PROFILER_DRAW_END; +} + static void * buf_align(void * buf, lv_color_format_t color_format) { LV_UNUSED(color_format); diff --git a/src/draw/lv_draw_buf.h b/src/draw/lv_draw_buf.h index c36e0a612f..30d5a9e6d7 100644 --- a/src/draw/lv_draw_buf.h +++ b/src/draw/lv_draw_buf.h @@ -75,15 +75,18 @@ LV_EXPORT_CONST_INT(LV_STRIDE_AUTO); * TYPEDEFS **********************/ -typedef void * (*lv_draw_buf_malloc_cb)(size_t size, lv_color_format_t color_format); +typedef void * (*lv_draw_buf_malloc_cb_t)(size_t size, lv_color_format_t color_format); -typedef void (*lv_draw_buf_free_cb)(void * draw_buf); +typedef void (*lv_draw_buf_free_cb_t)(void * draw_buf); -typedef void * (*lv_draw_buf_align_cb)(void * buf, lv_color_format_t color_format); +typedef void (*lv_draw_buf_copy_cb_t)(lv_draw_buf_t * dest, const lv_area_t * dest_area, + const lv_draw_buf_t * src, const lv_area_t * src_area); -typedef void (*lv_draw_buf_cache_operation_cb)(const lv_draw_buf_t * draw_buf, const lv_area_t * area); +typedef void * (*lv_draw_buf_align_cb_t)(void * buf, lv_color_format_t color_format); -typedef uint32_t (*lv_draw_buf_width_to_stride_cb)(uint32_t w, lv_color_format_t color_format); +typedef void (*lv_draw_buf_cache_operation_cb_t)(const lv_draw_buf_t * draw_buf, const lv_area_t * area); + +typedef uint32_t (*lv_draw_buf_width_to_stride_cb_t)(uint32_t w, lv_color_format_t color_format); struct _lv_draw_buf_t { lv_image_header_t header; @@ -110,18 +113,20 @@ void lv_draw_buf_init_with_default_handlers(lv_draw_buf_handlers_t * handlers); * @param handlers the draw buffer handlers to set * @param buf_malloc_cb the callback to allocate memory for the buffer * @param buf_free_cb the callback to free memory of the buffer + * @param buf_copy_cb the callback to copy a draw buffer to an other * @param align_pointer_cb the callback to align the buffer * @param invalidate_cache_cb the callback to invalidate the cache of the buffer * @param flush_cache_cb the callback to flush buffer * @param width_to_stride_cb the callback to calculate the stride based on the width and color format */ void lv_draw_buf_handlers_init(lv_draw_buf_handlers_t * handlers, - lv_draw_buf_malloc_cb buf_malloc_cb, - lv_draw_buf_free_cb buf_free_cb, - lv_draw_buf_align_cb align_pointer_cb, - lv_draw_buf_cache_operation_cb invalidate_cache_cb, - lv_draw_buf_cache_operation_cb flush_cache_cb, - lv_draw_buf_width_to_stride_cb width_to_stride_cb); + lv_draw_buf_malloc_cb_t buf_malloc_cb, + lv_draw_buf_free_cb_t buf_free_cb, + lv_draw_buf_copy_cb_t buf_copy_cb, + lv_draw_buf_align_cb_t align_pointer_cb, + lv_draw_buf_cache_operation_cb_t invalidate_cache_cb, + lv_draw_buf_cache_operation_cb_t flush_cache_cb, + lv_draw_buf_width_to_stride_cb_t width_to_stride_cb); /** * Get the struct which holds the callbacks for draw buf management. @@ -192,17 +197,6 @@ uint32_t lv_draw_buf_width_to_stride_ex(const lv_draw_buf_handlers_t * handlers, */ void lv_draw_buf_clear(lv_draw_buf_t * draw_buf, const lv_area_t * a); -/** - * Copy an area from a buffer to another - * @param dest pointer to the destination draw buffer - * @param dest_area the area to copy from the destination buffer, if NULL, use the whole buffer - * @param src pointer to the source draw buffer - * @param src_area the area to copy from the destination buffer, if NULL, use the whole buffer - * @note `dest_area` and `src_area` should have the same width and height - * @note `dest` and `src` should have same color format. Color converting is not supported fow now. - */ -void lv_draw_buf_copy(lv_draw_buf_t * dest, const lv_area_t * dest_area, - const lv_draw_buf_t * src, const lv_area_t * src_area); /** * Note: Eventually, lv_draw_buf_malloc/free will be kept as private. @@ -285,6 +279,19 @@ lv_draw_buf_t * lv_draw_buf_reshape(lv_draw_buf_t * draw_buf, lv_color_format_t */ void lv_draw_buf_destroy(lv_draw_buf_t * draw_buf); +/** + * Copy an area from a buffer to another + * @param dest pointer to the destination draw buffer + * @param dest_area the area to copy from the destination buffer, if NULL, use the whole buffer + * @param src pointer to the source draw buffer + * @param src_area the area to copy from the destination buffer, if NULL, use the whole buffer + * @note `dest_area` and `src_area` should have the same width and height + * @note The default copy function required `dest` and `src` to have the same color format. + * Overwriting dest->handlers->buf_copy_cb can resolve this limitation. + */ +void lv_draw_buf_copy(lv_draw_buf_t * dest, const lv_area_t * dest_area, + const lv_draw_buf_t * src, const lv_area_t * src_area); + /** * Return pointer to the buffer at the given coordinates */ diff --git a/src/draw/lv_draw_buf_private.h b/src/draw/lv_draw_buf_private.h index a22640315e..9245cab1d5 100644 --- a/src/draw/lv_draw_buf_private.h +++ b/src/draw/lv_draw_buf_private.h @@ -25,12 +25,13 @@ extern "C" { **********************/ struct _lv_draw_buf_handlers_t { - lv_draw_buf_malloc_cb buf_malloc_cb; - lv_draw_buf_free_cb buf_free_cb; - lv_draw_buf_align_cb align_pointer_cb; - lv_draw_buf_cache_operation_cb invalidate_cache_cb; - lv_draw_buf_cache_operation_cb flush_cache_cb; - lv_draw_buf_width_to_stride_cb width_to_stride_cb; + lv_draw_buf_malloc_cb_t buf_malloc_cb; + lv_draw_buf_free_cb_t buf_free_cb; + lv_draw_buf_copy_cb_t buf_copy_cb; + lv_draw_buf_align_cb_t align_pointer_cb; + lv_draw_buf_cache_operation_cb_t invalidate_cache_cb; + lv_draw_buf_cache_operation_cb_t flush_cache_cb; + lv_draw_buf_width_to_stride_cb_t width_to_stride_cb; }; /********************** diff --git a/src/draw/lv_draw_image.c b/src/draw/lv_draw_image.c index ee29d6b7a0..6c0d65f00b 100644 --- a/src/draw/lv_draw_image.c +++ b/src/draw/lv_draw_image.c @@ -1,5 +1,5 @@ /** - * @file lv_draw_img.c + * @file lv_draw_image.c * */ @@ -76,7 +76,7 @@ void lv_draw_layer(lv_layer_t * layer, const lv_draw_image_dsc_t * dsc, const lv lv_draw_task_t * t = lv_draw_add_task(layer, coords, LV_DRAW_TASK_TYPE_LAYER); lv_draw_image_dsc_t * new_image_dsc = t->draw_dsc; lv_memcpy(new_image_dsc, dsc, sizeof(*dsc)); - t->state = LV_DRAW_TASK_STATE_WAITING; + t->state = LV_DRAW_TASK_STATE_BLOCKED; lv_image_buf_get_transformed_area(&t->_real_area, lv_area_get_width(coords), lv_area_get_height(coords), dsc->rotation, dsc->scale_x, dsc->scale_y, &dsc->pivot); @@ -180,6 +180,8 @@ void lv_draw_image(lv_layer_t * layer, const lv_draw_image_dsc_t * dsc, const lv } } + + lv_image_decoder_close(&decoder_dsc); } LV_PROFILER_DRAW_END; diff --git a/src/draw/lv_draw_image.h b/src/draw/lv_draw_image.h index de925e60ed..1f58f7e384 100644 --- a/src/draw/lv_draw_image.h +++ b/src/draw/lv_draw_image.h @@ -73,7 +73,7 @@ struct _lv_draw_image_dsc_t { */ lv_blend_mode_t blend_mode : 4; - /**1: perform the transformation with anti-alaising */ + /**1: perform the transformation with anti-aliasing */ uint16_t antialias : 1; /**If the image is smaller than the `image_area` field of `lv_draw_image_dsc_t` @@ -81,6 +81,8 @@ struct _lv_draw_image_dsc_t { * `image_area` area*/ uint16_t tile : 1; + const lv_image_colorkey_t * colorkey; + /**Used internally to store some information about the palette or the color of A8 images*/ lv_draw_image_sup_t * sup; diff --git a/src/draw/lv_draw_label.c b/src/draw/lv_draw_label.c index 8f37151319..1e953817b7 100644 --- a/src/draw/lv_draw_label.c +++ b/src/draw/lv_draw_label.c @@ -137,6 +137,7 @@ void LV_ATTRIBUTE_FAST_MEM lv_draw_character(lv_layer_t * layer, lv_draw_label_d LV_PROFILER_DRAW_BEGIN; lv_font_glyph_dsc_t g; + lv_font_get_glyph_dsc(dsc->font, &g, unicode_letter, 0); lv_area_t a; @@ -175,6 +176,7 @@ void LV_ATTRIBUTE_FAST_MEM lv_draw_letter(lv_layer_t * layer, lv_draw_letter_dsc LV_PROFILER_DRAW_BEGIN; lv_font_glyph_dsc_t g; + lv_font_get_glyph_dsc(font, &g, dsc->unicode, 0); font = g.resolved_font ? g.resolved_font : dsc->font; @@ -223,9 +225,15 @@ void lv_draw_label_iterate_characters(lv_draw_task_t * t, const lv_draw_label_ds w = dsc->text_size.x; } else { + lv_text_attributes_t attributes = {0}; + + attributes.letter_space = dsc->letter_space; + attributes.line_space = dsc->line_space; + attributes.max_width = LV_COORD_MAX; + attributes.text_flags = dsc->flag; + lv_point_t p; - lv_text_get_size(&p, dsc->text, dsc->font, dsc->letter_space, dsc->line_space, LV_COORD_MAX, - dsc->flag); + lv_text_get_size_attributes(&p, dsc->text, dsc->font, &attributes); w = p.x; } } @@ -263,15 +271,19 @@ void lv_draw_label_iterate_characters(lv_draw_task_t * t, const lv_draw_label_ds } uint32_t remaining_len = dsc->text_length; + lv_text_attributes_t attributes = {0}; + attributes.letter_space = dsc->letter_space; + attributes.text_flags = dsc->flag; + attributes.max_width = w; - uint32_t line_end = line_start + lv_text_get_next_line(&dsc->text[line_start], remaining_len, font, dsc->letter_space, - w, NULL, dsc->flag); + uint32_t line_end = line_start + lv_text_get_next_line(&dsc->text[line_start], remaining_len, font, NULL, &attributes); /*Go the first visible line*/ while(pos.y + line_height_font < t->clip_area.y1) { /*Go to next line*/ + remaining_len -= line_end - line_start; line_start = line_end; - line_end += lv_text_get_next_line(&dsc->text[line_start], remaining_len, font, dsc->letter_space, w, NULL, dsc->flag); + line_end += lv_text_get_next_line(&dsc->text[line_start], remaining_len, font, NULL, &attributes); pos.y += line_height; /*Save at the threshold coordinate*/ @@ -286,16 +298,13 @@ void lv_draw_label_iterate_characters(lv_draw_task_t * t, const lv_draw_label_ds /*Align to middle*/ if(align == LV_TEXT_ALIGN_CENTER) { - line_width = lv_text_get_width_with_flags(&dsc->text[line_start], line_end - line_start, font, dsc->letter_space, - dsc->flag); - + line_width = lv_text_get_width(&dsc->text[line_start], line_end - line_start, font, &attributes); pos.x += (lv_area_get_width(coords) - line_width) / 2; } /*Align to the right*/ else if(align == LV_TEXT_ALIGN_RIGHT) { - line_width = lv_text_get_width_with_flags(&dsc->text[line_start], line_end - line_start, font, dsc->letter_space, - dsc->flag); + line_width = lv_text_get_width(&dsc->text[line_start], line_end - line_start, font, &attributes); pos.x += lv_area_get_width(coords) - line_width; } @@ -309,11 +318,13 @@ void lv_draw_label_iterate_characters(lv_draw_task_t * t, const lv_draw_label_ds lv_area_t bg_coords; lv_draw_glyph_dsc_t draw_letter_dsc; + lv_font_glyph_dsc_t glyph_dsc; lv_draw_glyph_dsc_init(&draw_letter_dsc); draw_letter_dsc.opa = dsc->opa; draw_letter_dsc.bg_coords = &bg_coords; draw_letter_dsc.color = dsc->color; draw_letter_dsc.rotation = dsc->rotation; + draw_letter_dsc.g = &glyph_dsc; /* Set letter outline stroke attributes */ draw_letter_dsc.outline_stroke_width = dsc->outline_stroke_width; @@ -328,6 +339,7 @@ void lv_draw_label_iterate_characters(lv_draw_task_t * t, const lv_draw_label_ds uint32_t next_char_offset; uint32_t recolor_command_start_index = 0; int32_t letter_w; + cmd_state_t recolor_cmd_state = RECOLOR_CMD_STATE_WAIT_FOR_PARAMETER; lv_color_t recolor = lv_color_black(); /* Holds the selected color inside the recolor command */ uint8_t is_first_space_after_cmd = 0; @@ -338,7 +350,6 @@ void lv_draw_label_iterate_characters(lv_draw_task_t * t, const lv_draw_label_ds line_start_x = pos.x; /*Write all letter of a line*/ - recolor_cmd_state = RECOLOR_CMD_STATE_WAIT_FOR_PARAMETER; next_char_offset = 0; #if LV_USE_BIDI size_t bidi_size = line_end - line_start; @@ -455,12 +466,13 @@ void lv_draw_label_iterate_characters(lv_draw_task_t * t, const lv_draw_label_ds logical_char_pos -= (LABEL_RECOLOR_PAR_LENGTH + 1); } - letter_w = lv_font_get_glyph_width(font, letter, letter_next); + lv_font_get_glyph_dsc(font, &glyph_dsc, letter, letter_next); + letter_w = lv_text_is_marker(letter) ? 0 : glyph_dsc.adv_w; /*Always set the bg_coordinates for placeholder drawing*/ - bg_coords.x1 = pos.x; + bg_coords.x1 = pos.x - dsc->letter_space / 2; bg_coords.y1 = pos.y; - bg_coords.x2 = pos.x + letter_w - 1; + bg_coords.x2 = pos.x + letter_w - 1 + (dsc->letter_space + 1) / 2; bg_coords.y2 = pos.y + line_height - 1; if(next_char_offset >= line_end - line_start) { @@ -511,25 +523,31 @@ void lv_draw_label_iterate_characters(lv_draw_task_t * t, const lv_draw_label_ds lv_free(bidi_txt); bidi_txt = NULL; #endif + + lv_text_attributes_t text_attributes = {0}; + text_attributes.letter_space = dsc->letter_space; + text_attributes.text_flags = dsc->flag; + text_attributes.max_width = w; + /*Go to next line*/ remaining_len -= line_end - line_start; line_start = line_end; if(remaining_len) { - line_end += lv_text_get_next_line(&dsc->text[line_start], remaining_len, font, dsc->letter_space, w, NULL, dsc->flag); + line_end += lv_text_get_next_line(&dsc->text[line_start], remaining_len, font, NULL, &text_attributes); } pos.x = coords->x1; /*Align to middle*/ if(align == LV_TEXT_ALIGN_CENTER) { line_width = - lv_text_get_width_with_flags(&dsc->text[line_start], line_end - line_start, font, dsc->letter_space, dsc->flag); + lv_text_get_width(&dsc->text[line_start], line_end - line_start, font, &text_attributes); pos.x += (lv_area_get_width(coords) - line_width) / 2; } /*Align to the right*/ else if(align == LV_TEXT_ALIGN_RIGHT) { line_width = - lv_text_get_width_with_flags(&dsc->text[line_start], line_end - line_start, font, dsc->letter_space, dsc->flag); + lv_text_get_width(&dsc->text[line_start], line_end - line_start, font, &text_attributes); pos.x += lv_area_get_width(coords) - line_width; } @@ -569,16 +587,23 @@ void lv_draw_unit_draw_letter(lv_draw_task_t * t, lv_draw_glyph_dsc_t * dsc, co return; LV_PROFILER_DRAW_BEGIN; - bool g_ret = lv_font_get_glyph_dsc(font, &g, letter, '\0'); - if(g_ret == false) { - /*Add warning if the dsc is not found*/ - LV_LOG_WARN("lv_draw_letter: glyph dsc. not found for U+%" LV_PRIX32, letter); + if(dsc->g == NULL) { + dsc->g = &g; + /*If the glyph dsc is not set then get it from the font*/ + bool g_ret = lv_font_get_glyph_dsc(font, &g, letter, 0); + if(g_ret == false) { + /*Add warning if the dsc is not found*/ + LV_LOG_WARN("lv_draw_letter: glyph dsc. not found for U+%" LV_PRIX32, letter); + } + } + else { + /*If the glyph dsc is set then use it*/ + g = *dsc->g; } /*Don't draw anything if the character is empty. E.g. space*/ if((g.box_h == 0) || (g.box_w == 0)) { - LV_PROFILER_DRAW_END; - return; + goto exit; } lv_area_t letter_coords; @@ -592,8 +617,7 @@ void lv_draw_unit_draw_letter(lv_draw_task_t * t, lv_draw_glyph_dsc_t * dsc, co if(lv_area_is_out(&letter_coords, &t->clip_area, 0) && dsc->bg_coords && lv_area_is_out(dsc->bg_coords, &t->clip_area, 0)) { - LV_PROFILER_DRAW_END; - return; + goto exit; } if(g.resolved_font) { @@ -617,8 +641,7 @@ void lv_draw_unit_draw_letter(lv_draw_task_t * t, lv_draw_glyph_dsc_t * dsc, co if(g.format == LV_FONT_GLYPH_FORMAT_VECTOR) { /*Load the outline of the glyph, even if the function says bitmap*/ - g.outline_stroke_width = dsc->outline_stroke_width; - dsc->glyph_data = (void *) lv_font_get_glyph_bitmap(&g, draw_buf); + dsc->glyph_data = (void *) lv_font_get_glyph_bitmap(dsc->g, draw_buf); dsc->format = dsc->glyph_data ? g.format : LV_FONT_GLYPH_FORMAT_NONE; } } @@ -627,10 +650,14 @@ void lv_draw_unit_draw_letter(lv_draw_task_t * t, lv_draw_glyph_dsc_t * dsc, co } dsc->letter_coords = &letter_coords; - dsc->g = &g; cb(t, dsc, NULL, NULL); - lv_font_glyph_release_draw_data(&g); + lv_font_glyph_release_draw_data(dsc->g); +exit: + if(dsc->g == &g) { + /* If the glyph was created locally, we don't need to keep it */ + dsc->g = NULL; + } LV_PROFILER_DRAW_END; } diff --git a/src/draw/lv_draw_label.h b/src/draw/lv_draw_label.h index 3420bd5b26..7d5f4786c9 100644 --- a/src/draw/lv_draw_label.h +++ b/src/draw/lv_draw_label.h @@ -74,16 +74,19 @@ typedef struct { /**The number of characters to render. 0: means render until reaching the `\0` termination.*/ uint32_t text_length; - /**Opacity of the text in 0...255 range. - * LV_OPA_TRANSP, LV_OPA_10, LV_OPA_20, .. LV_OPA_COVER can be used as well*/ - lv_opa_t opa; - /**The alignment of the text `LV_TEXT_ALIGN_LEFT/RIGHT/CENTER`*/ lv_text_align_t align; /**The base direction. Used when type setting Right-to-left (e.g. Arabic) texts*/ lv_base_dir_t bidi_dir; + /**Opacity of the text in 0...255 range. + * LV_OPA_TRANSP, LV_OPA_10, LV_OPA_20, .. LV_OPA_COVER can be used as well*/ + lv_opa_t opa; + + /**Letter outline stroke opacity */ + lv_opa_t outline_stroke_opa; + /**Text decoration, e.g. underline*/ lv_text_decor_t decor : 3; @@ -105,7 +108,6 @@ typedef struct { lv_draw_label_hint_t * hint; /* Properties of the letter outlines */ - lv_opa_t outline_stroke_opa; lv_color_t outline_stroke_color; int32_t outline_stroke_width; @@ -127,7 +129,7 @@ typedef struct { lv_opa_t opa; lv_text_decor_t decor : 3; - lv_blend_mode_t blend_mode : 3; + lv_blend_mode_t blend_mode : 4; /* Properties of the letter outlines */ lv_opa_t outline_stroke_opa; diff --git a/src/draw/lv_draw_private.h b/src/draw/lv_draw_private.h index 057d4dd08a..682f8b4781 100644 --- a/src/draw/lv_draw_private.h +++ b/src/draw/lv_draw_private.h @@ -19,7 +19,7 @@ extern "C" { *********************/ #include "lv_draw.h" -#include "../osal/lv_os.h" +#include "../osal/lv_os_private.h" #include "../misc/cache/lv_cache.h" /********************* @@ -68,6 +68,9 @@ struct _lv_draw_task_t { void * draw_dsc; + /** Opacity of the layer */ + lv_opa_t opa; + /** * The ID of the draw_unit which should take this task */ @@ -171,6 +174,12 @@ struct _lv_draw_unit_t { * @return */ int32_t (*delete_cb)(lv_draw_unit_t * draw_unit); + + /** + * Called when an event is sent to the draw unit. + * @param event pointer to the event descriptor + */ + void (*event_cb)(lv_event_t * event); }; typedef struct { diff --git a/src/draw/lv_draw_rect.c b/src/draw/lv_draw_rect.c index 3ee299ac56..ec1af77201 100644 --- a/src/draw/lv_draw_rect.c +++ b/src/draw/lv_draw_rect.c @@ -10,6 +10,7 @@ #include "lv_draw_private.h" #include "../core/lv_obj.h" #include "../misc/lv_assert.h" +#include "../misc/lv_text_private.h" #include "../core/lv_obj_event.h" #include "../stdlib/lv_string.h" @@ -266,6 +267,7 @@ void lv_draw_rect(lv_layer_t * layer, const lv_draw_rect_dsc_t * dsc, const lv_a bg_image_dsc->recolor = dsc->bg_image_recolor; bg_image_dsc->recolor_opa = dsc->bg_image_recolor_opa; bg_image_dsc->tile = dsc->bg_image_tiled; + bg_image_dsc->colorkey = dsc->bg_image_colorkey; bg_image_dsc->header = header; bg_image_dsc->clip_radius = dsc->radius; bg_image_dsc->image_area = *coords; @@ -273,7 +275,14 @@ void lv_draw_rect(lv_layer_t * layer, const lv_draw_rect_dsc_t * dsc, const lv_a } else { lv_point_t s; - lv_text_get_size(&s, dsc->bg_image_src, dsc->bg_image_symbol_font, 0, 0, LV_COORD_MAX, LV_TEXT_FLAG_NONE); + + lv_text_attributes_t attributes = {0}; + attributes.text_flags = LV_TEXT_FLAG_NONE; + attributes.max_width = LV_COORD_MAX; + attributes.line_space = 0; + attributes.letter_space = 0; + + lv_text_get_size_attributes(&s, dsc->bg_image_src, dsc->bg_image_symbol_font, &attributes); lv_area_t a = {0, 0, s.x - 1, s.y - 1}; lv_area_align(coords, &a, LV_ALIGN_CENTER, 0, 0); diff --git a/src/draw/lv_draw_rect.h b/src/draw/lv_draw_rect.h index 85ec3af171..9c870d1b88 100644 --- a/src/draw/lv_draw_rect.h +++ b/src/draw/lv_draw_rect.h @@ -33,11 +33,6 @@ typedef struct { int32_t radius; - /*Background*/ - lv_opa_t bg_opa; - lv_color_t bg_color; /**< First element of a gradient is a color, so it maps well here*/ - lv_grad_dsc_t bg_grad; - /*Background img*/ const void * bg_image_src; const void * bg_image_symbol_font; @@ -45,11 +40,24 @@ typedef struct { lv_opa_t bg_image_opa; lv_opa_t bg_image_recolor_opa; uint8_t bg_image_tiled; + /*Background*/ + lv_opa_t bg_opa; + /*Border*/ + lv_opa_t border_opa; + /*Outline */ + lv_opa_t outline_opa; + /*Shadow*/ + lv_opa_t shadow_opa; + + /*Background*/ + lv_color_t bg_color; /**< First element of a gradient is a color, so it maps well here*/ + lv_grad_dsc_t bg_grad; + + const lv_image_colorkey_t * bg_image_colorkey; /*Border*/ lv_color_t border_color; int32_t border_width; - lv_opa_t border_opa; lv_border_side_t border_side : 5; uint8_t border_post : 1; /*The border will be drawn later*/ @@ -57,7 +65,6 @@ typedef struct { lv_color_t outline_color; int32_t outline_width; int32_t outline_pad; - lv_opa_t outline_opa; /*Shadow*/ lv_color_t shadow_color; @@ -65,7 +72,6 @@ typedef struct { int32_t shadow_offset_x; int32_t shadow_offset_y; int32_t shadow_spread; - lv_opa_t shadow_opa; } lv_draw_rect_dsc_t; typedef struct { @@ -116,7 +122,7 @@ typedef struct { /**Radius, LV_RADIUS_CIRCLE for max. radius */ int32_t radius; - /**Color of the the shadow */ + /**Color of shadow */ lv_color_t color; /**Width of the shadow. (radius of the blur)*/ diff --git a/src/draw/lv_draw_vector.c b/src/draw/lv_draw_vector.c index 5ed6477f62..089554dedb 100644 --- a/src/draw/lv_draw_vector.c +++ b/src/draw/lv_draw_vector.c @@ -12,12 +12,17 @@ #if LV_USE_VECTOR_GRAPHIC +#if !((LV_USE_DRAW_SW && LV_USE_THORVG) || LV_USE_DRAW_VG_LITE || (LV_USE_NEMA_GFX && LV_USE_NEMA_VG)) + #error "LV_USE_VECTOR_GRAPHIC requires (LV_USE_DRAW_SW and LV_USE_THORVG) or LV_USE_DRAW_VG_LITE or (LV_USE_NEMA_GFX and LV_USE_NEMA_VG)" +#endif + #include "../misc/lv_ll.h" #include "../misc/lv_types.h" #include "../stdlib/lv_string.h" #include #include +#define EPSILON 1e-6f #define MATH_PI 3.14159265358979323846f #define MATH_HALF_PI 1.57079632679489661923f @@ -49,16 +54,11 @@ * TYPEDEFS **********************/ -typedef struct { - lv_vector_path_t * path; - lv_vector_draw_dsc_t dsc; -} lv_vector_draw_task; - /********************** * STATIC PROTOTYPES **********************/ -static void _copy_draw_dsc(lv_vector_draw_dsc_t * dst, const lv_vector_draw_dsc_t * src) +static void _copy_draw_dsc(lv_vector_path_ctx_t * dst, const lv_vector_path_ctx_t * src) { lv_memcpy(&(dst->fill_dsc), &(src->fill_dsc), sizeof(lv_vector_fill_dsc_t)); @@ -70,11 +70,6 @@ static void _copy_draw_dsc(lv_vector_draw_dsc_t * dst, const lv_vector_draw_dsc_ dst->stroke_dsc.join = src->stroke_dsc.join; dst->stroke_dsc.miter_limit = src->stroke_dsc.miter_limit; lv_array_copy(&(dst->stroke_dsc.dash_pattern), &(src->stroke_dsc.dash_pattern)); - dst->stroke_dsc.gradient.style = src->stroke_dsc.gradient.style; - dst->stroke_dsc.gradient.cx = src->stroke_dsc.gradient.cx; - dst->stroke_dsc.gradient.cy = src->stroke_dsc.gradient.cy; - dst->stroke_dsc.gradient.cr = src->stroke_dsc.gradient.cr; - dst->stroke_dsc.gradient.spread = src->fill_dsc.gradient.spread; lv_memcpy(&(dst->stroke_dsc.gradient), &(src->stroke_dsc.gradient), sizeof(lv_vector_gradient_t)); lv_memcpy(&(dst->stroke_dsc.matrix), &(src->stroke_dsc.matrix), sizeof(lv_matrix_t)); @@ -82,6 +77,8 @@ static void _copy_draw_dsc(lv_vector_draw_dsc_t * dst, const lv_vector_draw_dsc_ lv_memcpy(&(dst->matrix), &(src->matrix), sizeof(lv_matrix_t)); lv_area_copy(&(dst->scissor_area), &(src->scissor_area)); } + + /********************** * GLOBAL FUNCTIONS **********************/ @@ -91,8 +88,8 @@ void lv_matrix_transform_point(const lv_matrix_t * matrix, lv_fpoint_t * point) float x = point->x; float y = point->y; - point->x = x * matrix->m[0][0] + y * matrix->m[1][0] + matrix->m[0][2]; - point->y = x * matrix->m[0][1] + y * matrix->m[1][1] + matrix->m[1][2]; + point->x = x * matrix->m[0][0] + y * matrix->m[0][1] + matrix->m[0][2]; + point->y = x * matrix->m[1][0] + y * matrix->m[1][1] + matrix->m[1][2]; } void lv_matrix_transform_path(const lv_matrix_t * matrix, lv_vector_path_t * path) @@ -191,6 +188,162 @@ void lv_vector_path_cubic_to(lv_vector_path_t * path, const lv_fpoint_t * p1, co lv_array_push_back(&path->points, p3); } +static lv_fpoint_t _point_on_ellipse(float rx, float ry, float cos_r, float sin_r, + float cx, float cy, float theta, float alpha) +{ + float cos_theta = cosf(theta); + float sin_theta = sinf(theta); + + float x = rx * cos_theta; + float y = ry * sin_theta; + + float x_rot = cos_r * x - sin_r * y; + float y_rot = sin_r * x + cos_r * y; + + if(fabsf(alpha) > EPSILON) { + float dx = -rx * sin_theta; + float dy = ry * cos_theta; + float dx_rot = cos_r * dx - sin_r * dy; + float dy_rot = sin_r * dx + cos_r * dy; + + x_rot += alpha * dx_rot; + y_rot += alpha * dy_rot; + } + + return (lv_fpoint_t) { + x_rot + cx, y_rot + cy + }; +} + +void lv_vector_path_arc_to(lv_vector_path_t * path, float rx, float ry, float rotate_angle, bool large_arc, + bool clockwise, const lv_fpoint_t * p) +{ + LV_ASSERT_NULL(path); + LV_ASSERT_NULL(p); + + if(lv_array_is_empty(&path->ops)) { + /*first op must be move_to*/ + return; + } + + if(rx <= 0 || ry <= 0) { + /*no needed to draw*/ + return; + } + + /*https://www.w3.org/TR/SVG/implnote.html#ArcImplementationNotes*/ + + lv_fpoint_t * cpt = lv_array_back(&path->points); + + float x0 = cpt->x; + float y0 = cpt->y; + + /*1. dealing with degradation*/ + if(fabsf(x0 - p->x) < EPSILON && fabsf(y0 - p->y) < EPSILON) { + /*same point*/ + return; + } + + float rotate = MATH_RADIANS(rotate_angle); + float sin_r = sinf(rotate); + float cos_r = cosf(rotate); + + /*2. transform point*/ + float dx = (x0 - p->x) * 0.5f; + float dy = (y0 - p->y) * 0.5f; + + float x1 = cos_r * dx + sin_r * dy; + float y1 = -sin_r * dx + cos_r * dy; + + /*3. adjust radius*/ + float lambda_val = (x1 * x1) / (rx * rx) + (y1 * y1) / (ry * ry); + if(lambda_val > 1.0f) { + rx *= sqrtf(lambda_val); + ry *= sqrtf(lambda_val); + } + + /*4. calc center point*/ + float rx_sq = rx * rx; + float ry_sq = ry * ry; + float x1_sq = x1 * x1; + float y1_sq = y1 * y1; + + float num = rx_sq * ry_sq - rx_sq * y1_sq - ry_sq * x1_sq; + float denom = rx_sq * y1_sq + ry_sq * x1_sq; + + float radicand = (denom > EPSILON) ? num / denom : 0.0f; + if(radicand < 0.0f) radicand = 0.0f; + + float sign = (large_arc == clockwise) ? -1.0f : 1.0f; + float coef = sign * sqrtf(radicand); + + float cx_prime = (coef * rx * y1) / ry; + float cy_prime = -(coef * ry * x1) / rx; + + float cx = cos_r * cx_prime - sin_r * cy_prime + (x0 + p->x) * 0.5f; + float cy = sin_r * cx_prime + cos_r * cy_prime + (y0 + p->y) * 0.5f; + + float ux = (x1 - cx_prime) / rx; + float uy = (y1 - cy_prime) / ry; + + /*5. calculate the starting angle and ending angle*/ + float n_sq = ux * ux + uy * uy; + float theta1 = 0.0f; + if(n_sq > EPSILON) { + theta1 = atan2f(uy, ux); + } + + float vx = (-x1 - cx_prime) / rx; + float vy = (-y1 - cy_prime) / ry; + + float n = sqrtf(n_sq * (vx * vx + vy * vy)); + float delta = 0.0f; + if(n > EPSILON) { + float cos_delta = (ux * vx + uy * vy) / n; + if(cos_delta > 1.0f) cos_delta = 1.0f; + else if(cos_delta < -1.0f) cos_delta = -1.0f; + + delta = acosf(cos_delta); + if(ux * vy - uy * vx < 0.0f) delta = -delta; + } + + if(!clockwise && delta > 0.0f) { + delta -= 2.0f * MATH_PI; + } + else if(clockwise && delta < 0.0f) { + delta += 2.0f * MATH_PI; + } + + /*6. split arc into segments within 90 degrees*/ + float angle_left = fabsf(delta); + int seg_count = (int)ceilf(angle_left / MATH_HALF_PI); + if(seg_count == 0) seg_count = 1; + + float segment_angle = delta / (float)seg_count; + + float current_angle = theta1; + for(int i = 0; i < seg_count; i++) { + float next_angle = current_angle + segment_angle; + + float alpha_val; + if(fabsf(segment_angle) < 0.1f) { + alpha_val = segment_angle / 6.0f; + } + else { + float tan_half = tanf(segment_angle * 0.5f); + alpha_val = sinf(segment_angle) * (sqrtf(4.0f + 3.0f * tan_half * tan_half) - 1.0f) / 3.0f; + } + + lv_fpoint_t p1 = _point_on_ellipse(rx, ry, cos_r, sin_r, cx, cy, current_angle, alpha_val); + lv_fpoint_t p2 = _point_on_ellipse(rx, ry, cos_r, sin_r, cx, cy, next_angle, -alpha_val); + lv_fpoint_t p3 = _point_on_ellipse(rx, ry, cos_r, sin_r, cx, cy, next_angle, 0.0f); + + lv_vector_path_cubic_to(path, &p1, &p2, &p3); + + current_angle = next_angle; + } +} + void lv_vector_path_close(lv_vector_path_t * path) { if(lv_array_is_empty(&path->ops)) { @@ -234,12 +387,9 @@ void lv_vector_path_get_bounding(const lv_vector_path_t * path, lv_area_t * area area->y2 = lroundf(y2); } -void lv_vector_path_append_rect(lv_vector_path_t * path, const lv_area_t * rect, float rx, float ry) +void lv_vector_path_append_rectangle(lv_vector_path_t * path, float x, float y, float w, float h, float rx, float ry) { - float x = rect->x1; - float y = rect->y1; - float w = (float)lv_area_get_width(rect); - float h = (float)lv_area_get_height(rect); + if(w <= 0.0f || h <= 0.0f) return; float hw = w * 0.5f; float hh = h * 0.5f; @@ -247,7 +397,7 @@ void lv_vector_path_append_rect(lv_vector_path_t * path, const lv_area_t * rect, if(rx > hw) rx = hw; if(ry > hh) ry = hh; - if(rx == 0 && ry == 0) { + if(rx <= 0.0f && ry <= 0.0f) { lv_fpoint_t pt = {x, y}; lv_vector_path_move_to(path, &pt); pt.x += w; @@ -257,69 +407,72 @@ void lv_vector_path_append_rect(lv_vector_path_t * path, const lv_area_t * rect, pt.x -= w; lv_vector_path_line_to(path, &pt); lv_vector_path_close(path); + return; } - else if(rx == hw && ry == hh) { - lv_fpoint_t pt = {x + w * 0.5f, y + h * 0.5f}; + + if(rx == hw && ry == hh) { + lv_fpoint_t pt = {x + hw, y + hh}; lv_vector_path_append_circle(path, &pt, rx, ry); + return; } - else { - float hrx = rx * 0.5f; - float hry = ry * 0.5f; - lv_fpoint_t pt, pt2, pt3; - pt.x = x + rx; - pt.y = y; - lv_vector_path_move_to(path, &pt); + float hrx = rx * 0.5f; + float hry = ry * 0.5f; + lv_fpoint_t pt, pt2, pt3; - pt.x = x + w - rx; - pt.y = y; - lv_vector_path_line_to(path, &pt); + pt.x = x + rx; + pt.y = y; + lv_vector_path_move_to(path, &pt); - pt.x = x + w - rx + hrx; - pt.y = y; - pt2.x = x + w; - pt2.y = y + ry - hry; - pt3.x = x + w; - pt3.y = y + ry; - lv_vector_path_cubic_to(path, &pt, &pt2, &pt3); + pt.x = x + w - rx; + pt.y = y; + lv_vector_path_line_to(path, &pt); - pt.x = x + w; - pt.y = y + h - ry; - lv_vector_path_line_to(path, &pt); + pt.x = x + w - rx + hrx; + pt.y = y; + pt2.x = x + w; + pt2.y = y + ry - hry; + pt3.x = x + w; + pt3.y = y + ry; + lv_vector_path_cubic_to(path, &pt, &pt2, &pt3); - pt.x = x + w; - pt.y = y + h - ry + hry; - pt2.x = x + w - rx + hrx; - pt2.y = y + h; - pt3.x = x + w - rx; - pt3.y = y + h; - lv_vector_path_cubic_to(path, &pt, &pt2, &pt3); + pt.x = x + w; + pt.y = y + h - ry; + lv_vector_path_line_to(path, &pt); - pt.x = x + rx; - pt.y = y + h; - lv_vector_path_line_to(path, &pt); + pt.x = x + w; + pt.y = y + h - ry + hry; + pt2.x = x + w - rx + hrx; + pt2.y = y + h; + pt3.x = x + w - rx; + pt3.y = y + h; + lv_vector_path_cubic_to(path, &pt, &pt2, &pt3); - pt.x = x + rx - hrx; - pt.y = y + h; - pt2.x = x; - pt2.y = y + h - ry + hry; - pt3.x = x; - pt3.y = y + h - ry; - lv_vector_path_cubic_to(path, &pt, &pt2, &pt3); + pt.x = x + rx; + pt.y = y + h; + lv_vector_path_line_to(path, &pt); - pt.x = x; - pt.y = y + ry; - lv_vector_path_line_to(path, &pt); + pt.x = x + rx - hrx; + pt.y = y + h; + pt2.x = x; + pt2.y = y + h - ry + hry; + pt3.x = x; + pt3.y = y + h - ry; + lv_vector_path_cubic_to(path, &pt, &pt2, &pt3); - pt.x = x; - pt.y = y + ry - hry; - pt2.x = x + rx - hrx; - pt2.y = y; - pt3.x = x + rx; - pt3.y = y; - lv_vector_path_cubic_to(path, &pt, &pt2, &pt3); - lv_vector_path_close(path); - } + pt.x = x; + pt.y = y + ry; + lv_vector_path_line_to(path, &pt); + + pt.x = x; + pt.y = y + ry - hry; + pt2.x = x + rx - hrx; + pt2.y = y; + pt3.x = x + rx; + pt3.y = y; + lv_vector_path_cubic_to(path, &pt, &pt2, &pt3); + + lv_vector_path_close(path); } void lv_vector_path_append_circle(lv_vector_path_t * path, const lv_fpoint_t * c, float rx, float ry) @@ -471,22 +624,33 @@ void lv_vector_path_append_path(lv_vector_path_t * path, const lv_vector_path_t /* draw dsc functions */ -lv_vector_dsc_t * lv_vector_dsc_create(lv_layer_t * layer) +lv_draw_vector_dsc_t * lv_draw_vector_dsc_create(lv_layer_t * layer) { - lv_vector_dsc_t * dsc = lv_malloc(sizeof(lv_vector_dsc_t)); + + lv_draw_vector_dsc_t * dsc = lv_zalloc(sizeof(lv_draw_vector_dsc_t)); LV_ASSERT_MALLOC(dsc); - lv_memzero(dsc, sizeof(lv_vector_dsc_t)); + if(dsc == NULL) { + LV_LOG_WARN("Couldn't allocate lv_draw_vector_dsc_t"); + return NULL; + } - dsc->layer = layer; + dsc->base.layer = layer; - lv_vector_fill_dsc_t * fill_dsc = &(dsc->current_dsc.fill_dsc); + dsc->ctx = lv_zalloc(sizeof(lv_vector_path_ctx_t)); + if(dsc->ctx == NULL) { + LV_LOG_WARN("Couldn't allocate vector path context"); + lv_free(dsc); + return NULL; + } + + lv_vector_fill_dsc_t * fill_dsc = &(dsc->ctx->fill_dsc); fill_dsc->style = LV_VECTOR_DRAW_STYLE_SOLID; fill_dsc->color = lv_color_to_32(lv_color_black(), 0xFF); fill_dsc->opa = LV_OPA_COVER; fill_dsc->fill_rule = LV_VECTOR_FILL_NONZERO; lv_matrix_identity(&(fill_dsc->matrix)); /*identity matrix*/ - lv_vector_stroke_dsc_t * stroke_dsc = &(dsc->current_dsc.stroke_dsc); + lv_vector_stroke_dsc_t * stroke_dsc = &(dsc->ctx->stroke_dsc); stroke_dsc->style = LV_VECTOR_DRAW_STYLE_SOLID; stroke_dsc->color = lv_color_to_32(lv_color_black(), 0xFF); stroke_dsc->opa = LV_OPA_0; /*default no stroke*/ @@ -496,138 +660,139 @@ lv_vector_dsc_t * lv_vector_dsc_create(lv_layer_t * layer) stroke_dsc->miter_limit = 4.0f; lv_matrix_identity(&(stroke_dsc->matrix)); /*identity matrix*/ - dsc->current_dsc.blend_mode = LV_VECTOR_BLEND_SRC_OVER; - dsc->current_dsc.scissor_area = layer->_clip_area; - lv_matrix_identity(&(dsc->current_dsc.matrix)); /*identity matrix*/ - dsc->tasks.task_list = NULL; + dsc->ctx->blend_mode = LV_VECTOR_BLEND_SRC_OVER; + dsc->ctx->scissor_area = layer->_clip_area; + lv_matrix_identity(&(dsc->ctx->matrix)); /*identity matrix*/ + dsc->task_list = NULL; return dsc; } -void lv_vector_dsc_delete(lv_vector_dsc_t * dsc) +void lv_draw_vector_dsc_delete(lv_draw_vector_dsc_t * dsc) { - if(dsc->tasks.task_list) { - lv_ll_t * task_list = dsc->tasks.task_list; + if(dsc->task_list) { + lv_ll_t * task_list = dsc->task_list; lv_vector_for_each_destroy_tasks(task_list, NULL, NULL); - dsc->tasks.task_list = NULL; + dsc->task_list = NULL; } - lv_array_deinit(&(dsc->current_dsc.stroke_dsc.dash_pattern)); + lv_array_deinit(&(dsc->ctx->stroke_dsc.dash_pattern)); + lv_free(dsc->ctx); lv_free(dsc); } -void lv_vector_dsc_set_blend_mode(lv_vector_dsc_t * dsc, lv_vector_blend_t blend) +void lv_draw_vector_dsc_set_blend_mode(lv_draw_vector_dsc_t * dsc, lv_vector_blend_t blend) { - dsc->current_dsc.blend_mode = blend; + dsc->ctx->blend_mode = blend; } -void lv_vector_dsc_set_transform(lv_vector_dsc_t * dsc, const lv_matrix_t * matrix) +void lv_draw_vector_dsc_set_transform(lv_draw_vector_dsc_t * dsc, const lv_matrix_t * matrix) { - lv_memcpy(&(dsc->current_dsc.matrix), matrix, sizeof(lv_matrix_t)); + lv_memcpy(&(dsc->ctx->matrix), matrix, sizeof(lv_matrix_t)); } -void lv_vector_dsc_set_fill_color(lv_vector_dsc_t * dsc, lv_color_t color) +void lv_draw_vector_dsc_set_fill_color(lv_draw_vector_dsc_t * dsc, lv_color_t color) { - dsc->current_dsc.fill_dsc.style = LV_VECTOR_DRAW_STYLE_SOLID; - dsc->current_dsc.fill_dsc.color = lv_color_to_32(color, 0xFF); + dsc->ctx->fill_dsc.style = LV_VECTOR_DRAW_STYLE_SOLID; + dsc->ctx->fill_dsc.color = lv_color_to_32(color, 0xFF); } -void lv_vector_dsc_set_fill_color32(lv_vector_dsc_t * dsc, lv_color32_t color) +void lv_draw_vector_dsc_set_fill_color32(lv_draw_vector_dsc_t * dsc, lv_color32_t color) { - dsc->current_dsc.fill_dsc.style = LV_VECTOR_DRAW_STYLE_SOLID; - dsc->current_dsc.fill_dsc.color = color; + dsc->ctx->fill_dsc.style = LV_VECTOR_DRAW_STYLE_SOLID; + dsc->ctx->fill_dsc.color = color; } -void lv_vector_dsc_set_fill_opa(lv_vector_dsc_t * dsc, lv_opa_t opa) +void lv_draw_vector_dsc_set_fill_opa(lv_draw_vector_dsc_t * dsc, lv_opa_t opa) { - dsc->current_dsc.fill_dsc.opa = opa; + dsc->ctx->fill_dsc.opa = opa; } -void lv_vector_dsc_set_fill_rule(lv_vector_dsc_t * dsc, lv_vector_fill_t rule) +void lv_draw_vector_dsc_set_fill_rule(lv_draw_vector_dsc_t * dsc, lv_vector_fill_t rule) { - dsc->current_dsc.fill_dsc.fill_rule = rule; + dsc->ctx->fill_dsc.fill_rule = rule; } -void lv_vector_dsc_set_fill_units(lv_vector_dsc_t * dsc, const lv_vector_fill_units_t units) +void lv_draw_vector_dsc_set_fill_units(lv_draw_vector_dsc_t * dsc, const lv_vector_fill_units_t units) { - dsc->current_dsc.fill_dsc.fill_units = units; + dsc->ctx->fill_dsc.fill_units = units; } -void lv_vector_dsc_set_fill_image(lv_vector_dsc_t * dsc, const lv_draw_image_dsc_t * img_dsc) +void lv_draw_vector_dsc_set_fill_image(lv_draw_vector_dsc_t * dsc, const lv_draw_image_dsc_t * img_dsc) { - dsc->current_dsc.fill_dsc.style = LV_VECTOR_DRAW_STYLE_PATTERN; - lv_memcpy(&(dsc->current_dsc.fill_dsc.img_dsc), img_dsc, sizeof(lv_draw_image_dsc_t)); + dsc->ctx->fill_dsc.style = LV_VECTOR_DRAW_STYLE_PATTERN; + lv_memcpy(&(dsc->ctx->fill_dsc.img_dsc), img_dsc, sizeof(lv_draw_image_dsc_t)); } -void lv_vector_dsc_set_fill_linear_gradient(lv_vector_dsc_t * dsc, float x1, float y1, float x2, float y2) +void lv_draw_vector_dsc_set_fill_linear_gradient(lv_draw_vector_dsc_t * dsc, float x1, float y1, float x2, float y2) { - dsc->current_dsc.fill_dsc.style = LV_VECTOR_DRAW_STYLE_GRADIENT; - dsc->current_dsc.fill_dsc.gradient.style = LV_VECTOR_GRADIENT_STYLE_LINEAR; - dsc->current_dsc.fill_dsc.gradient.x1 = x1; - dsc->current_dsc.fill_dsc.gradient.y1 = y1; - dsc->current_dsc.fill_dsc.gradient.x2 = x2; - dsc->current_dsc.fill_dsc.gradient.y2 = y2; + dsc->ctx->fill_dsc.style = LV_VECTOR_DRAW_STYLE_GRADIENT; + dsc->ctx->fill_dsc.gradient.style = LV_VECTOR_GRADIENT_STYLE_LINEAR; + dsc->ctx->fill_dsc.gradient.x1 = x1; + dsc->ctx->fill_dsc.gradient.y1 = y1; + dsc->ctx->fill_dsc.gradient.x2 = x2; + dsc->ctx->fill_dsc.gradient.y2 = y2; } -void lv_vector_dsc_set_fill_radial_gradient(lv_vector_dsc_t * dsc, float cx, float cy, float radius) +void lv_draw_vector_dsc_set_fill_radial_gradient(lv_draw_vector_dsc_t * dsc, float cx, float cy, float radius) { - dsc->current_dsc.fill_dsc.style = LV_VECTOR_DRAW_STYLE_GRADIENT; - dsc->current_dsc.fill_dsc.gradient.style = LV_VECTOR_GRADIENT_STYLE_RADIAL; - dsc->current_dsc.fill_dsc.gradient.cx = cx; - dsc->current_dsc.fill_dsc.gradient.cy = cy; - dsc->current_dsc.fill_dsc.gradient.cr = radius; + dsc->ctx->fill_dsc.style = LV_VECTOR_DRAW_STYLE_GRADIENT; + dsc->ctx->fill_dsc.gradient.style = LV_VECTOR_GRADIENT_STYLE_RADIAL; + dsc->ctx->fill_dsc.gradient.cx = cx; + dsc->ctx->fill_dsc.gradient.cy = cy; + dsc->ctx->fill_dsc.gradient.cr = radius; } -void lv_vector_dsc_set_fill_gradient_spread(lv_vector_dsc_t * dsc, lv_vector_gradient_spread_t spread) +void lv_draw_vector_dsc_set_fill_gradient_spread(lv_draw_vector_dsc_t * dsc, lv_vector_gradient_spread_t spread) { - dsc->current_dsc.fill_dsc.gradient.spread = spread; + dsc->ctx->fill_dsc.gradient.spread = spread; } -void lv_vector_dsc_set_fill_gradient_color_stops(lv_vector_dsc_t * dsc, const lv_grad_stop_t * stops, - uint16_t count) +void lv_draw_vector_dsc_set_fill_gradient_color_stops(lv_draw_vector_dsc_t * dsc, const lv_grad_stop_t * stops, + uint16_t count) { if(count > LV_GRADIENT_MAX_STOPS) { LV_LOG_WARN("Gradient stops limited: %d, max: %d", count, LV_GRADIENT_MAX_STOPS); count = LV_GRADIENT_MAX_STOPS; } - lv_memcpy(&(dsc->current_dsc.fill_dsc.gradient.stops), stops, sizeof(lv_grad_stop_t) * count); - dsc->current_dsc.fill_dsc.gradient.stops_count = count; + lv_memcpy(&(dsc->ctx->fill_dsc.gradient.stops), stops, sizeof(lv_grad_stop_t) * count); + dsc->ctx->fill_dsc.gradient.stops_count = count; } -void lv_vector_dsc_set_fill_transform(lv_vector_dsc_t * dsc, const lv_matrix_t * matrix) +void lv_draw_vector_dsc_set_fill_transform(lv_draw_vector_dsc_t * dsc, const lv_matrix_t * matrix) { - lv_memcpy(&(dsc->current_dsc.fill_dsc.matrix), matrix, sizeof(lv_matrix_t)); + lv_memcpy(&(dsc->ctx->fill_dsc.matrix), matrix, sizeof(lv_matrix_t)); } -void lv_vector_dsc_set_stroke_transform(lv_vector_dsc_t * dsc, const lv_matrix_t * matrix) +void lv_draw_vector_dsc_set_stroke_transform(lv_draw_vector_dsc_t * dsc, const lv_matrix_t * matrix) { - lv_memcpy(&(dsc->current_dsc.stroke_dsc.matrix), matrix, sizeof(lv_matrix_t)); + lv_memcpy(&(dsc->ctx->stroke_dsc.matrix), matrix, sizeof(lv_matrix_t)); } -void lv_vector_dsc_set_stroke_color32(lv_vector_dsc_t * dsc, lv_color32_t color) +void lv_draw_vector_dsc_set_stroke_color32(lv_draw_vector_dsc_t * dsc, lv_color32_t color) { - dsc->current_dsc.stroke_dsc.style = LV_VECTOR_DRAW_STYLE_SOLID; - dsc->current_dsc.stroke_dsc.color = color; + dsc->ctx->stroke_dsc.style = LV_VECTOR_DRAW_STYLE_SOLID; + dsc->ctx->stroke_dsc.color = color; } -void lv_vector_dsc_set_stroke_color(lv_vector_dsc_t * dsc, lv_color_t color) +void lv_draw_vector_dsc_set_stroke_color(lv_draw_vector_dsc_t * dsc, lv_color_t color) { - dsc->current_dsc.stroke_dsc.style = LV_VECTOR_DRAW_STYLE_SOLID; - dsc->current_dsc.stroke_dsc.color = lv_color_to_32(color, 0xFF); + dsc->ctx->stroke_dsc.style = LV_VECTOR_DRAW_STYLE_SOLID; + dsc->ctx->stroke_dsc.color = lv_color_to_32(color, 0xFF); } -void lv_vector_dsc_set_stroke_opa(lv_vector_dsc_t * dsc, lv_opa_t opa) +void lv_draw_vector_dsc_set_stroke_opa(lv_draw_vector_dsc_t * dsc, lv_opa_t opa) { - dsc->current_dsc.stroke_dsc.opa = opa; + dsc->ctx->stroke_dsc.opa = opa; } -void lv_vector_dsc_set_stroke_width(lv_vector_dsc_t * dsc, float width) +void lv_draw_vector_dsc_set_stroke_width(lv_draw_vector_dsc_t * dsc, float width) { - dsc->current_dsc.stroke_dsc.width = width; + dsc->ctx->stroke_dsc.width = width; } -void lv_vector_dsc_set_stroke_dash(lv_vector_dsc_t * dsc, float * dash_pattern, uint16_t dash_count) +void lv_draw_vector_dsc_set_stroke_dash(lv_draw_vector_dsc_t * dsc, float * dash_pattern, uint16_t dash_count) { - lv_array_t * dash_array = &(dsc->current_dsc.stroke_dsc.dash_pattern); + lv_array_t * dash_array = &(dsc->ctx->stroke_dsc.dash_pattern); if(dash_pattern) { lv_array_clear(dash_array); if(lv_array_capacity(dash_array) == 0) { @@ -645,90 +810,90 @@ void lv_vector_dsc_set_stroke_dash(lv_vector_dsc_t * dsc, float * dash_pattern, } } -void lv_vector_dsc_set_stroke_cap(lv_vector_dsc_t * dsc, lv_vector_stroke_cap_t cap) +void lv_draw_vector_dsc_set_stroke_cap(lv_draw_vector_dsc_t * dsc, lv_vector_stroke_cap_t cap) { - dsc->current_dsc.stroke_dsc.cap = cap; + dsc->ctx->stroke_dsc.cap = cap; } -void lv_vector_dsc_set_stroke_join(lv_vector_dsc_t * dsc, lv_vector_stroke_join_t join) +void lv_draw_vector_dsc_set_stroke_join(lv_draw_vector_dsc_t * dsc, lv_vector_stroke_join_t join) { - dsc->current_dsc.stroke_dsc.join = join; + dsc->ctx->stroke_dsc.join = join; } -void lv_vector_dsc_set_stroke_miter_limit(lv_vector_dsc_t * dsc, uint16_t miter_limit) +void lv_draw_vector_dsc_set_stroke_miter_limit(lv_draw_vector_dsc_t * dsc, uint16_t miter_limit) { - dsc->current_dsc.stroke_dsc.miter_limit = miter_limit; + dsc->ctx->stroke_dsc.miter_limit = miter_limit; } -void lv_vector_dsc_set_stroke_linear_gradient(lv_vector_dsc_t * dsc, float x1, float y1, float x2, float y2) +void lv_draw_vector_dsc_set_stroke_linear_gradient(lv_draw_vector_dsc_t * dsc, float x1, float y1, float x2, float y2) { - dsc->current_dsc.stroke_dsc.style = LV_VECTOR_DRAW_STYLE_GRADIENT; - dsc->current_dsc.stroke_dsc.gradient.style = LV_VECTOR_GRADIENT_STYLE_LINEAR; - dsc->current_dsc.stroke_dsc.gradient.x1 = x1; - dsc->current_dsc.stroke_dsc.gradient.y1 = y1; - dsc->current_dsc.stroke_dsc.gradient.x2 = x2; - dsc->current_dsc.stroke_dsc.gradient.y2 = y2; + dsc->ctx->stroke_dsc.style = LV_VECTOR_DRAW_STYLE_GRADIENT; + dsc->ctx->stroke_dsc.gradient.style = LV_VECTOR_GRADIENT_STYLE_LINEAR; + dsc->ctx->stroke_dsc.gradient.x1 = x1; + dsc->ctx->stroke_dsc.gradient.y1 = y1; + dsc->ctx->stroke_dsc.gradient.x2 = x2; + dsc->ctx->stroke_dsc.gradient.y2 = y2; } -void lv_vector_dsc_set_stroke_radial_gradient(lv_vector_dsc_t * dsc, float cx, float cy, float radius) +void lv_draw_vector_dsc_set_stroke_radial_gradient(lv_draw_vector_dsc_t * dsc, float cx, float cy, float radius) { - dsc->current_dsc.stroke_dsc.style = LV_VECTOR_DRAW_STYLE_GRADIENT; - dsc->current_dsc.stroke_dsc.gradient.style = LV_VECTOR_GRADIENT_STYLE_RADIAL; - dsc->current_dsc.stroke_dsc.gradient.cx = cx; - dsc->current_dsc.stroke_dsc.gradient.cy = cy; - dsc->current_dsc.stroke_dsc.gradient.cr = radius; + dsc->ctx->stroke_dsc.style = LV_VECTOR_DRAW_STYLE_GRADIENT; + dsc->ctx->stroke_dsc.gradient.style = LV_VECTOR_GRADIENT_STYLE_RADIAL; + dsc->ctx->stroke_dsc.gradient.cx = cx; + dsc->ctx->stroke_dsc.gradient.cy = cy; + dsc->ctx->stroke_dsc.gradient.cr = radius; } -void lv_vector_dsc_set_stroke_gradient_spread(lv_vector_dsc_t * dsc, lv_vector_gradient_spread_t spread) +void lv_draw_vector_dsc_set_stroke_gradient_spread(lv_draw_vector_dsc_t * dsc, lv_vector_gradient_spread_t spread) { - dsc->current_dsc.stroke_dsc.gradient.spread = spread; + dsc->ctx->stroke_dsc.gradient.spread = spread; } -void lv_vector_dsc_set_stroke_gradient_color_stops(lv_vector_dsc_t * dsc, const lv_grad_stop_t * stops, - uint16_t count) +void lv_draw_vector_dsc_set_stroke_gradient_color_stops(lv_draw_vector_dsc_t * dsc, const lv_grad_stop_t * stops, + uint16_t count) { if(count > LV_GRADIENT_MAX_STOPS) { LV_LOG_WARN("Gradient stops limited: %d, max: %d", count, LV_GRADIENT_MAX_STOPS); count = LV_GRADIENT_MAX_STOPS; } - lv_memcpy(&(dsc->current_dsc.stroke_dsc.gradient.stops), stops, sizeof(lv_grad_stop_t) * count); - dsc->current_dsc.stroke_dsc.gradient.stops_count = count; + lv_memcpy(&(dsc->ctx->stroke_dsc.gradient.stops), stops, sizeof(lv_grad_stop_t) * count); + dsc->ctx->stroke_dsc.gradient.stops_count = count; } /* draw functions */ -void lv_vector_dsc_add_path(lv_vector_dsc_t * dsc, const lv_vector_path_t * path) +void lv_draw_vector_dsc_add_path(lv_draw_vector_dsc_t * dsc, const lv_vector_path_t * path) { lv_area_t rect; - if(!lv_area_intersect(&rect, &(dsc->layer->_clip_area), &(dsc->current_dsc.scissor_area))) { + if(!lv_area_intersect(&rect, &(dsc->base.layer->_clip_area), &(dsc->ctx->scissor_area))) { return; } - if(dsc->current_dsc.fill_dsc.opa == 0 - && dsc->current_dsc.stroke_dsc.opa == 0) { + if(dsc->ctx->fill_dsc.opa == 0 + && dsc->ctx->stroke_dsc.opa == 0) { return; } - if(!dsc->tasks.task_list) { - dsc->tasks.task_list = lv_malloc(sizeof(lv_ll_t)); - LV_ASSERT_MALLOC(dsc->tasks.task_list); - lv_ll_init(dsc->tasks.task_list, sizeof(lv_vector_draw_task)); + if(!dsc->task_list) { + dsc->task_list = lv_malloc(sizeof(lv_ll_t)); + LV_ASSERT_MALLOC(dsc->task_list); + lv_ll_init(dsc->task_list, sizeof(lv_draw_vector_subtask_t)); } - lv_vector_draw_task * new_task = (lv_vector_draw_task *)lv_ll_ins_tail(dsc->tasks.task_list); - lv_memset(new_task, 0, sizeof(lv_vector_draw_task)); + lv_draw_vector_subtask_t * new_task = (lv_draw_vector_subtask_t *)lv_ll_ins_tail(dsc->task_list); + lv_memset(new_task, 0, sizeof(lv_draw_vector_subtask_t)); new_task->path = lv_vector_path_create(0); - _copy_draw_dsc(&(new_task->dsc), &(dsc->current_dsc)); + _copy_draw_dsc(&(new_task->ctx), dsc->ctx); lv_vector_path_copy(new_task->path, path); - new_task->dsc.scissor_area = rect; + new_task->ctx.scissor_area = rect; } -void lv_vector_clear_area(lv_vector_dsc_t * dsc, const lv_area_t * rect) +void lv_draw_vector_dsc_clear_area(lv_draw_vector_dsc_t * dsc, const lv_area_t * rect) { lv_area_t r; - if(!lv_area_intersect(&r, &(dsc->layer->_clip_area), &(dsc->current_dsc.scissor_area))) { + if(!lv_area_intersect(&r, &(dsc->base.layer->_clip_area), &(dsc->ctx->scissor_area))) { return; } @@ -737,83 +902,89 @@ void lv_vector_clear_area(lv_vector_dsc_t * dsc, const lv_area_t * rect) return; } - if(!dsc->tasks.task_list) { - dsc->tasks.task_list = lv_malloc(sizeof(lv_ll_t)); - LV_ASSERT_MALLOC(dsc->tasks.task_list); - lv_ll_init(dsc->tasks.task_list, sizeof(lv_vector_draw_task)); + if(!dsc->task_list) { + dsc->task_list = lv_malloc(sizeof(lv_ll_t)); + LV_ASSERT_MALLOC(dsc->task_list); + lv_ll_init(dsc->task_list, sizeof(lv_draw_vector_subtask_t)); } - lv_vector_draw_task * new_task = (lv_vector_draw_task *)lv_ll_ins_tail(dsc->tasks.task_list); - lv_memset(new_task, 0, sizeof(lv_vector_draw_task)); + lv_draw_vector_subtask_t * new_task = (lv_draw_vector_subtask_t *)lv_ll_ins_tail(dsc->task_list); + lv_memset(new_task, 0, sizeof(lv_draw_vector_subtask_t)); - new_task->dsc.fill_dsc.color = dsc->current_dsc.fill_dsc.color; - new_task->dsc.fill_dsc.opa = dsc->current_dsc.fill_dsc.opa; - lv_area_copy(&(new_task->dsc.scissor_area), &final_rect); + new_task->ctx.fill_dsc.color = dsc->ctx->fill_dsc.color; + new_task->ctx.fill_dsc.opa = dsc->ctx->fill_dsc.opa; + lv_area_copy(&(new_task->ctx.scissor_area), &final_rect); } -void lv_draw_vector(lv_vector_dsc_t * dsc) +void lv_draw_vector(lv_draw_vector_dsc_t * dsc) { - if(!dsc->tasks.task_list) { + if(!dsc->task_list) { return; } - lv_layer_t * layer = dsc->layer; + lv_layer_t * layer = dsc->base.layer; lv_draw_task_t * t = lv_draw_add_task(layer, &(layer->_clip_area), LV_DRAW_TASK_TYPE_VECTOR); - lv_memcpy(t->draw_dsc, &(dsc->tasks), sizeof(lv_draw_vector_task_dsc_t)); + lv_memcpy(t->draw_dsc, dsc, sizeof(lv_draw_vector_dsc_t)); lv_draw_finalize_task_creation(layer, t); - dsc->tasks.task_list = NULL; + dsc->task_list = NULL; } /* draw dsc transform */ -void lv_vector_dsc_identity(lv_vector_dsc_t * dsc) +void lv_draw_vector_dsc_identity(lv_draw_vector_dsc_t * dsc) { - lv_matrix_identity(&(dsc->current_dsc.matrix)); /*identity matrix*/ + lv_matrix_identity(&(dsc->ctx->matrix)); /*identity matrix*/ } -void lv_vector_dsc_scale(lv_vector_dsc_t * dsc, float scale_x, float scale_y) +void lv_draw_vector_dsc_scale(lv_draw_vector_dsc_t * dsc, float scale_x, float scale_y) { - lv_matrix_scale(&(dsc->current_dsc.matrix), scale_x, scale_y); + lv_matrix_scale(&(dsc->ctx->matrix), scale_x, scale_y); } -void lv_vector_dsc_rotate(lv_vector_dsc_t * dsc, float degree) +void lv_draw_vector_dsc_rotate(lv_draw_vector_dsc_t * dsc, float degree) { - lv_matrix_rotate(&(dsc->current_dsc.matrix), degree); + lv_matrix_rotate(&(dsc->ctx->matrix), degree); } -void lv_vector_dsc_translate(lv_vector_dsc_t * dsc, float tx, float ty) +void lv_draw_vector_dsc_translate(lv_draw_vector_dsc_t * dsc, float tx, float ty) { - lv_matrix_translate(&(dsc->current_dsc.matrix), tx, ty); + lv_matrix_translate(&(dsc->ctx->matrix), tx, ty); } -void lv_vector_dsc_skew(lv_vector_dsc_t * dsc, float skew_x, float skew_y) +void lv_draw_vector_dsc_skew(lv_draw_vector_dsc_t * dsc, float skew_x, float skew_y) { - lv_matrix_skew(&(dsc->current_dsc.matrix), skew_x, skew_y); + lv_matrix_skew(&(dsc->ctx->matrix), skew_x, skew_y); } void lv_vector_for_each_destroy_tasks(lv_ll_t * task_list, vector_draw_task_cb cb, void * data) { if(task_list == NULL) return; - lv_vector_draw_task * task = lv_ll_get_head(task_list); - lv_vector_draw_task * next_task = NULL; + lv_draw_vector_subtask_t * task = lv_ll_get_head(task_list); + lv_draw_vector_subtask_t * next_task = NULL; while(task != NULL) { next_task = lv_ll_get_next(task_list, task); lv_ll_remove(task_list, task); if(cb) { - cb(data, task->path, &(task->dsc)); + cb(data, task->path, &task->ctx); } if(task->path) { lv_vector_path_delete(task->path); } - lv_array_deinit(&(task->dsc.stroke_dsc.dash_pattern)); + lv_array_deinit(&(task->ctx.stroke_dsc.dash_pattern)); lv_free(task); task = next_task; } lv_free(task_list); } + +lv_draw_vector_dsc_t * lv_draw_task_get_vector_dsc(lv_draw_task_t * task) +{ + return task->type == LV_DRAW_TASK_TYPE_VECTOR ? (lv_draw_vector_dsc_t *)task->draw_dsc : NULL; +} + #endif /* LV_USE_VECTOR_GRAPHIC */ diff --git a/src/draw/lv_draw_vector.h b/src/draw/lv_draw_vector.h index ccb03df73a..c7e6d3bfee 100644 --- a/src/draw/lv_draw_vector.h +++ b/src/draw/lv_draw_vector.h @@ -172,6 +172,20 @@ void lv_vector_path_quad_to(lv_vector_path_t * path, const lv_fpoint_t * p1, con void lv_vector_path_cubic_to(lv_vector_path_t * path, const lv_fpoint_t * p1, const lv_fpoint_t * p2, const lv_fpoint_t * p3); +/** + * Add ellipse arc to the path from last point to the point + * @param path pointer to a path + * @param radius_x the x radius for ellipse arc + * @param radius_y the y radius for ellipse arc + * @param rotate_angle the rotate angle for arc + * @param large_arc true for large arc, otherwise small + * @param clockwise true for clockwise, otherwise anticlockwise + * @param p pointer to a `lv_fpoint_t` variable for end point + */ +void lv_vector_path_arc_to(lv_vector_path_t * path, float radius_x, float radius_y, float rotate_angle, + bool large_arc, + bool clockwise, const lv_fpoint_t * p); + /** * Close the sub path * @param path pointer to a path @@ -186,13 +200,32 @@ void lv_vector_path_close(lv_vector_path_t * path); void lv_vector_path_get_bounding(const lv_vector_path_t * path, lv_area_t * area); /** - * Add a rectangle to the path + * Add a rectangle to the path by x/y/w/h. rx/ry are corner radii + * @param path pointer to a path + * @param x the x coordinate of the top-left corner of the rectangle + * @param y the y coordinate of the top-left corner of the rectangle + * @param w the width of the rectangle + * @param h the height of the rectangle + * @param rx the horizontal radius for rounded rectangle + * @param ry the vertical radius for rounded rectangle + */ +void lv_vector_path_append_rectangle(lv_vector_path_t * path, float x, float y, float w, float h, float rx, float ry); + +/** + * Add a rectangle to the path (legacy api, recommend use lv_vector_path_append_rectangle instead) * @param path pointer to a path * @param rect pointer to a `lv_area_t` variable * @param rx the horizontal radius for rounded rectangle * @param ry the vertical radius for rounded rectangle */ -void lv_vector_path_append_rect(lv_vector_path_t * path, const lv_area_t * rect, float rx, float ry); +static inline void lv_vector_path_append_rect(lv_vector_path_t * path, const lv_area_t * rect, float rx, float ry) +{ + LV_ASSERT_NULL(path); + LV_ASSERT_NULL(rect); + + lv_vector_path_append_rectangle(path, rect->x1, rect->y1, (float)lv_area_get_width(rect), + (float)lv_area_get_height(rect), rx, ry); +} /** * Add a circle to the path @@ -227,272 +260,309 @@ void lv_vector_path_append_path(lv_vector_path_t * path, const lv_vector_path_t * @param layer pointer to a layer * @return pointer to the created descriptor */ -lv_vector_dsc_t * lv_vector_dsc_create(lv_layer_t * layer); +lv_draw_vector_dsc_t * lv_draw_vector_dsc_create(lv_layer_t * layer); /** * Delete the vector graphic descriptor * @param dsc pointer to a vector graphic descriptor */ -void lv_vector_dsc_delete(lv_vector_dsc_t * dsc); +void lv_draw_vector_dsc_delete(lv_draw_vector_dsc_t * dsc); /** - * Set a matrix to current transformation matrix + * Set a matrix to current transformation matrix. + * The new path shapes added by `lv_draw_vector_dsc_add_path` will use this matrix. * @param dsc pointer to a vector graphic descriptor * @param matrix pointer to a matrix */ -void lv_vector_dsc_set_transform(lv_vector_dsc_t * dsc, const lv_matrix_t * matrix); +void lv_draw_vector_dsc_set_transform(lv_draw_vector_dsc_t * dsc, const lv_matrix_t * matrix); /** - * Set blend mode for descriptor + * Set blend mode for descriptor. + * The new path shapes added by `lv_draw_vector_dsc_add_path` will use this blend mode. * @param dsc pointer to a vector graphic descriptor * @param blend the blend mode to be set in `lv_vector_blend_t` */ -void lv_vector_dsc_set_blend_mode(lv_vector_dsc_t * dsc, lv_vector_blend_t blend); +void lv_draw_vector_dsc_set_blend_mode(lv_draw_vector_dsc_t * dsc, lv_vector_blend_t blend); /** - * Set fill color for descriptor + * Set the fill color for descriptor. + * The new path shapes added by `lv_draw_vector_dsc_add_path` will use this color. * @param dsc pointer to a vector graphic descriptor * @param color the color to be set in lv_color32_t format */ -void lv_vector_dsc_set_fill_color32(lv_vector_dsc_t * dsc, lv_color32_t color); +void lv_draw_vector_dsc_set_fill_color32(lv_draw_vector_dsc_t * dsc, lv_color32_t color); /** - * Set fill color for descriptor + * Set fill color for descriptor. + * The new path shapes added by `lv_draw_vector_dsc_add_path` will use this color. * @param dsc pointer to a vector graphic descriptor * @param color the color to be set in lv_color_t format */ -void lv_vector_dsc_set_fill_color(lv_vector_dsc_t * dsc, lv_color_t color); +void lv_draw_vector_dsc_set_fill_color(lv_draw_vector_dsc_t * dsc, lv_color_t color); /** - * Set fill opacity for descriptor + * Set fill opacity for descriptor. + * The new path shapes added by `lv_draw_vector_dsc_add_path` will use this opacity. * @param dsc pointer to a vector graphic descriptor * @param opa the opacity to be set in lv_opa_t format */ -void lv_vector_dsc_set_fill_opa(lv_vector_dsc_t * dsc, lv_opa_t opa); +void lv_draw_vector_dsc_set_fill_opa(lv_draw_vector_dsc_t * dsc, lv_opa_t opa); /** - * Set fill rule for descriptor + * Set fill rule for descriptor. + * The new path shapes added by `lv_draw_vector_dsc_add_path` will use this fill rule. * @param dsc pointer to a vector graphic descriptor * @param rule the fill rule to be set in lv_vector_fill_t format */ -void lv_vector_dsc_set_fill_rule(lv_vector_dsc_t * dsc, lv_vector_fill_t rule); +void lv_draw_vector_dsc_set_fill_rule(lv_draw_vector_dsc_t * dsc, lv_vector_fill_t rule); /** * Set the fill units for descriptor. + * The new path shapes added by `lv_draw_vector_dsc_add_path` will use this fill units. * @param dsc pointer to a vector graphic descriptor * @param units the units to be set in lv_vector_fill_units_t format * @note The units can be either relative to the object bounding box or absolute in user space. * This API specifically affects the drawing position of the fill image and does not impact other elements. */ -void lv_vector_dsc_set_fill_units(lv_vector_dsc_t * dsc, const lv_vector_fill_units_t units); +void lv_draw_vector_dsc_set_fill_units(lv_draw_vector_dsc_t * dsc, const lv_vector_fill_units_t units); /** - * Set fill image for descriptor + * Set fill image for descriptor. + * The new path shapes added by `lv_draw_vector_dsc_add_path` will use this fill image. * @param dsc pointer to a vector graphic descriptor * @param img_dsc pointer to a `lv_draw_image_dsc_t` variable */ -void lv_vector_dsc_set_fill_image(lv_vector_dsc_t * dsc, const lv_draw_image_dsc_t * img_dsc); +void lv_draw_vector_dsc_set_fill_image(lv_draw_vector_dsc_t * dsc, const lv_draw_image_dsc_t * img_dsc); /** * Set fill linear gradient for descriptor + * The new path shapes added by `lv_draw_vector_dsc_add_path` will use this gradient. * @param dsc pointer to a vector graphic descriptor * @param x1 the x for start point * @param y1 the y for start point * @param x2 the x for end point * @param y2 the y for end point */ -void lv_vector_dsc_set_fill_linear_gradient(lv_vector_dsc_t * dsc, float x1, float y1, float x2, float y2); +void lv_draw_vector_dsc_set_fill_linear_gradient(lv_draw_vector_dsc_t * dsc, float x1, float y1, float x2, float y2); /** * Set fill radial gradient radius for descriptor + * The new path shapes added by `lv_draw_vector_dsc_add_path` will use this gradient. * @param dsc pointer to a vector graphic descriptor * @param cx the x for center of the circle * @param cy the y for center of the circle * @param radius the radius for circle */ -void lv_vector_dsc_set_fill_radial_gradient(lv_vector_dsc_t * dsc, float cx, float cy, float radius); +void lv_draw_vector_dsc_set_fill_radial_gradient(lv_draw_vector_dsc_t * dsc, float cx, float cy, float radius); /** * Set fill radial gradient spread for descriptor * @param dsc pointer to a vector graphic descriptor * @param spread the gradient spread to be set in lv_vector_gradient_spread_t format */ -void lv_vector_dsc_set_fill_gradient_spread(lv_vector_dsc_t * dsc, lv_vector_gradient_spread_t spread); +void lv_draw_vector_dsc_set_fill_gradient_spread(lv_draw_vector_dsc_t * dsc, lv_vector_gradient_spread_t spread); /** - * Set fill gradient color stops for descriptor + * Set fill gradient color stops for descriptor. + * The new path shapes added by `lv_draw_vector_dsc_add_path` will use this gradient color stops. * @param dsc pointer to a vector graphic descriptor * @param stops an array of `lv_grad_stop_t` variables * @param count the number of stops in the array, range: 0..LV_GRADIENT_MAX_STOPS */ -void lv_vector_dsc_set_fill_gradient_color_stops(lv_vector_dsc_t * dsc, const lv_grad_stop_t * stops, - uint16_t count); +void lv_draw_vector_dsc_set_fill_gradient_color_stops(lv_draw_vector_dsc_t * dsc, const lv_grad_stop_t * stops, + uint16_t count); /** * Set a matrix to current fill transformation matrix + * The new path shapes added by `lv_draw_vector_dsc_add_path` will use this matrix. * @param dsc pointer to a vector graphic descriptor * @param matrix pointer to a matrix */ -void lv_vector_dsc_set_fill_transform(lv_vector_dsc_t * dsc, const lv_matrix_t * matrix); +void lv_draw_vector_dsc_set_fill_transform(lv_draw_vector_dsc_t * dsc, const lv_matrix_t * matrix); /** - * Set stroke color for descriptor + * Set stroke color for descriptor. + * The new path shapes added by `lv_draw_vector_dsc_add_path` will use this color. * @param dsc pointer to a vector graphic descriptor * @param color the color to be set in lv_color32_t format */ -void lv_vector_dsc_set_stroke_color32(lv_vector_dsc_t * dsc, lv_color32_t color); +void lv_draw_vector_dsc_set_stroke_color32(lv_draw_vector_dsc_t * dsc, lv_color32_t color); /** - * Set stroke color for descriptor + * Set stroke color for descriptor. + * The new path shapes added by `lv_draw_vector_dsc_add_path` will use this color. * @param dsc pointer to a vector graphic descriptor * @param color the color to be set in lv_color_t format */ -void lv_vector_dsc_set_stroke_color(lv_vector_dsc_t * dsc, lv_color_t color); +void lv_draw_vector_dsc_set_stroke_color(lv_draw_vector_dsc_t * dsc, lv_color_t color); /** * Set stroke opacity for descriptor * @param dsc pointer to a vector graphic descriptor * @param opa the opacity to be set in lv_opa_t format */ -void lv_vector_dsc_set_stroke_opa(lv_vector_dsc_t * dsc, lv_opa_t opa); +void lv_draw_vector_dsc_set_stroke_opa(lv_draw_vector_dsc_t * dsc, lv_opa_t opa); /** - * Set stroke line width for descriptor + * Set stroke line width for descriptor. + * The new path shapes added by `lv_draw_vector_dsc_add_path` will use this stroke width. * @param dsc pointer to a vector graphic descriptor * @param width the stroke line width */ -void lv_vector_dsc_set_stroke_width(lv_vector_dsc_t * dsc, float width); +void lv_draw_vector_dsc_set_stroke_width(lv_draw_vector_dsc_t * dsc, float width); /** * Set stroke line dash pattern for descriptor + * The new path shapes added by `lv_draw_vector_dsc_add_path` will use this dash. * @param dsc pointer to a vector graphic descriptor * @param dash_pattern an array of values that specify the segments of dash line * @param dash_count the length of dash pattern array */ -void lv_vector_dsc_set_stroke_dash(lv_vector_dsc_t * dsc, float * dash_pattern, uint16_t dash_count); +void lv_draw_vector_dsc_set_stroke_dash(lv_draw_vector_dsc_t * dsc, float * dash_pattern, uint16_t dash_count); /** * Set stroke line cap style for descriptor + * The new path shapes added by `lv_draw_vector_dsc_add_path` will use this line cap. * @param dsc pointer to a vector graphic descriptor * @param cap the line cap to be set in lv_vector_stroke_cap_t format */ -void lv_vector_dsc_set_stroke_cap(lv_vector_dsc_t * dsc, lv_vector_stroke_cap_t cap); +void lv_draw_vector_dsc_set_stroke_cap(lv_draw_vector_dsc_t * dsc, lv_vector_stroke_cap_t cap); /** * Set stroke line join style for descriptor * @param dsc pointer to a vector graphic descriptor * @param join the line join to be set in lv_vector_stroke_join_t format */ -void lv_vector_dsc_set_stroke_join(lv_vector_dsc_t * dsc, lv_vector_stroke_join_t join); +void lv_draw_vector_dsc_set_stroke_join(lv_draw_vector_dsc_t * dsc, lv_vector_stroke_join_t join); /** * Set stroke miter limit for descriptor + * The new path shapes added by `lv_draw_vector_dsc_add_path` will use this miter limit. * @param dsc pointer to a vector graphic descriptor * @param miter_limit the stroke miter_limit */ -void lv_vector_dsc_set_stroke_miter_limit(lv_vector_dsc_t * dsc, uint16_t miter_limit); +void lv_draw_vector_dsc_set_stroke_miter_limit(lv_draw_vector_dsc_t * dsc, uint16_t miter_limit); /** * Set stroke linear gradient for descriptor + * The new path shapes added by `lv_draw_vector_dsc_add_path` will use this gradient. * @param dsc pointer to a vector graphic descriptor * @param x1 the x for start point * @param y1 the y for start point * @param x2 the x for end point * @param y2 the y for end point */ -void lv_vector_dsc_set_stroke_linear_gradient(lv_vector_dsc_t * dsc, float x1, float y1, float x2, float y2); +void lv_draw_vector_dsc_set_stroke_linear_gradient(lv_draw_vector_dsc_t * dsc, float x1, float y1, float x2, float y2); /** * Set stroke radial gradient for descriptor + * The new path shapes added by `lv_draw_vector_dsc_add_path` will use this gradient. * @param dsc pointer to a vector graphic descriptor * @param cx the x for center of the circle * @param cy the y for center of the circle * @param radius the radius for circle */ -void lv_vector_dsc_set_stroke_radial_gradient(lv_vector_dsc_t * dsc, float cx, float cy, float radius); +void lv_draw_vector_dsc_set_stroke_radial_gradient(lv_draw_vector_dsc_t * dsc, float cx, float cy, float radius); /** * Set stroke color stops for descriptor + * The new path shapes added by `lv_draw_vector_dsc_add_path` will use this gradient spread. * @param dsc pointer to a vector graphic descriptor * @param spread the gradient spread to be set in lv_vector_gradient_spread_t format */ -void lv_vector_dsc_set_stroke_gradient_spread(lv_vector_dsc_t * dsc, lv_vector_gradient_spread_t spread); +void lv_draw_vector_dsc_set_stroke_gradient_spread(lv_draw_vector_dsc_t * dsc, lv_vector_gradient_spread_t spread); /** * Set stroke color stops for descriptor + * The new path shapes added by `lv_draw_vector_dsc_add_path` will use this color stops. * @param dsc pointer to a vector graphic descriptor * @param stops an array of `lv_grad_stop_t` variables * @param count the number of stops in the array */ -void lv_vector_dsc_set_stroke_gradient_color_stops(lv_vector_dsc_t * dsc, const lv_grad_stop_t * stops, - uint16_t count); +void lv_draw_vector_dsc_set_stroke_gradient_color_stops(lv_draw_vector_dsc_t * dsc, const lv_grad_stop_t * stops, + uint16_t count); /** - * Set a matrix to current stroke transformation matrix + * Set a matrix to current stroke transformation matrix. + * The new path shapes added by `lv_draw_vector_dsc_add_path` will use this matrix. * @param dsc pointer to a vector graphic descriptor * @param matrix pointer to a matrix */ -void lv_vector_dsc_set_stroke_transform(lv_vector_dsc_t * dsc, const lv_matrix_t * matrix); +void lv_draw_vector_dsc_set_stroke_transform(lv_draw_vector_dsc_t * dsc, const lv_matrix_t * matrix); /** * Set current transformation matrix to identity matrix + * The new path shapes added by `lv_draw_vector_dsc_add_path` will use this matrix. * @param dsc pointer to a vector graphic descriptor */ -void lv_vector_dsc_identity(lv_vector_dsc_t * dsc); +void lv_draw_vector_dsc_identity(lv_draw_vector_dsc_t * dsc); /** * Change the scale factor of current transformation matrix + * The new path shapes added by `lv_draw_vector_dsc_add_path` will use this scale. * @param dsc pointer to a vector graphic descriptor * @param scale_x the scale factor for the X direction * @param scale_y the scale factor for the Y direction */ -void lv_vector_dsc_scale(lv_vector_dsc_t * dsc, float scale_x, float scale_y); +void lv_draw_vector_dsc_scale(lv_draw_vector_dsc_t * dsc, float scale_x, float scale_y); /** * Rotate current transformation matrix with origin + * The new path shapes added by `lv_draw_vector_dsc_add_path` will use this rotation. * @param dsc pointer to a vector graphic descriptor * @param degree angle to rotate */ -void lv_vector_dsc_rotate(lv_vector_dsc_t * dsc, float degree); +void lv_draw_vector_dsc_rotate(lv_draw_vector_dsc_t * dsc, float degree); /** * Translate current transformation matrix to new position + * The new path shapes added by `lv_draw_vector_dsc_add_path` will use this rotation. * @param dsc pointer to a vector graphic descriptor * @param tx the amount of translate in x direction - * @param tx the amount of translate in y direction + * @param ty the amount of translate in y direction */ -void lv_vector_dsc_translate(lv_vector_dsc_t * dsc, float tx, float ty); +void lv_draw_vector_dsc_translate(lv_draw_vector_dsc_t * dsc, float tx, float ty); /** * Change the skew factor of current transformation matrix + * The new path shapes added by `lv_draw_vector_dsc_add_path` will use this skew. * @param dsc pointer to a vector graphic descriptor * @param skew_x the skew factor for x direction * @param skew_y the skew factor for y direction */ -void lv_vector_dsc_skew(lv_vector_dsc_t * dsc, float skew_x, float skew_y); +void lv_draw_vector_dsc_skew(lv_draw_vector_dsc_t * dsc, float skew_x, float skew_y); /** - * Add a graphic path to the draw list + * Add a graphic path to the draw list. + * It will use colors, opacity, matrix and other parameters set + * by `lv_draw_vector_dsc_set_fill_color()` and similar functions. * @param dsc pointer to a vector graphic descriptor * @param path pointer to a path */ -void lv_vector_dsc_add_path(lv_vector_dsc_t * dsc, const lv_vector_path_t * path); +void lv_draw_vector_dsc_add_path(lv_draw_vector_dsc_t * dsc, const lv_vector_path_t * path); /** * Clear a rectangle area use current fill color * @param dsc pointer to a vector graphic descriptor * @param rect the area to clear in the buffer */ -void lv_vector_clear_area(lv_vector_dsc_t * dsc, const lv_area_t * rect); +void lv_draw_vector_dsc_clear_area(lv_draw_vector_dsc_t * dsc, const lv_area_t * rect); /** * Draw all the vector graphic paths * @param dsc pointer to a vector graphic descriptor */ -void lv_draw_vector(lv_vector_dsc_t * dsc); +void lv_draw_vector(lv_draw_vector_dsc_t * dsc); + +/** + * Try to get a vector draw descriptor from a draw task. + * @param task draw task + * @return the task's draw descriptor or NULL if the task is not of type LV_DRAW_TASK_TYPE_VECTOR + */ +lv_draw_vector_dsc_t * lv_draw_task_get_vector_dsc(lv_draw_task_t * task); /* Traverser for task list */ -typedef void (*vector_draw_task_cb)(void * ctx, const lv_vector_path_t * path, const lv_vector_draw_dsc_t * dsc); +typedef void (*vector_draw_task_cb)(void * ctx, const lv_vector_path_t * path, const lv_vector_path_ctx_t * dsc); #endif /* LV_USE_VECTOR_GRAPHIC */ diff --git a/src/draw/lv_draw_vector_private.h b/src/draw/lv_draw_vector_private.h index 7b2d4e04a8..10639cabb2 100644 --- a/src/draw/lv_draw_vector_private.h +++ b/src/draw/lv_draw_vector_private.h @@ -26,6 +26,13 @@ extern "C" { * TYPEDEFS **********************/ +/** + * Stores the shape of the path as arrays of operations and points. + * For example move to 10;20 then draw a line to 30;40 and draw an + * arc with 30 radius and 70° sweep. + * + * `lv_vector_path_ctx_t` is also required to describe how to fill and stroke the path. + */ struct _lv_vector_path_t { lv_vector_path_quality_t quality; lv_array_t ops; @@ -70,7 +77,10 @@ struct _lv_vector_stroke_dsc_t { lv_matrix_t matrix; }; -struct _lv_vector_draw_dsc_t { +/** + * Stores how to fill, stroke, transform etc a given path + */ +struct _lv_vector_path_ctx_t { lv_vector_fill_dsc_t fill_dsc; lv_vector_stroke_dsc_t stroke_dsc; lv_matrix_t matrix; @@ -78,23 +88,45 @@ struct _lv_vector_draw_dsc_t { lv_area_t scissor_area; }; -struct _lv_draw_vector_task_dsc_t { +struct _lv_draw_vector_dsc_t { lv_draw_dsc_base_t base; - lv_ll_t * task_list; /*draw task list.*/ -}; -struct _lv_vector_dsc_t { - lv_layer_t * layer; - lv_vector_draw_dsc_t current_dsc; - /* private data */ - lv_draw_vector_task_dsc_t tasks; + /** The current colors, opacities, matrix, etc for the next task to be added + * by */ + lv_vector_path_ctx_t * ctx; + + /** + * Store path shapes and their attributes + * in a list as `lv_draw_vector_subtask_t`. */ + lv_ll_t * task_list; }; + +/** + * Contains a path shape and its attributes together. + * It's a task that will be passed to the vector rendering engine. + * It's used in the `task_list` of `lv_draw_vector_dsc_t`. + */ +typedef struct { + lv_vector_path_t * path; + lv_vector_path_ctx_t ctx; +} lv_draw_vector_subtask_t; + + /********************** * GLOBAL PROTOTYPES **********************/ -void lv_vector_for_each_destroy_tasks(lv_ll_t * task_list, vector_draw_task_cb cb, void * data); +/** + * This is the main function to draw the accumulated vector tasks by passing them + * to a vector renderer callback. + * When the callback returns the processed vector task will be destroyed. + * @param task_list pointer to the linked list in `lv_draw_vector_dsc_t` that stores + * the path shapes and their attributes. + * @param cb the callback used to iterate through the task + * @param user_data a custom pointer that will be passed to the callback + */ +void lv_vector_for_each_destroy_tasks(lv_ll_t * task_list, vector_draw_task_cb cb, void * used_data); /********************** * MACROS diff --git a/src/draw/lv_image_decoder.c b/src/draw/lv_image_decoder.c index 48d62c89f7..ce4d25c0b9 100644 --- a/src/draw/lv_image_decoder.c +++ b/src/draw/lv_image_decoder.c @@ -21,6 +21,14 @@ #define img_header_cache_p (LV_GLOBAL_DEFAULT()->img_header_cache) #define image_cache_draw_buf_handlers &(LV_GLOBAL_DEFAULT()->image_cache_draw_buf_handlers) +#if LV_USE_OS != LV_OS_NONE + #define img_decoder_info_lock_p &(LV_GLOBAL_DEFAULT()->img_decoder_info_lock) + #define img_decoder_open_lock_p &(LV_GLOBAL_DEFAULT()->img_decoder_open_lock) +#else + #define img_decoder_info_lock_p NULL + #define img_decoder_open_lock_p NULL +#endif + /********************** * TYPEDEFS **********************/ @@ -63,6 +71,9 @@ void lv_image_decoder_init(uint32_t image_cache_size, uint32_t image_header_coun /*Initialize the cache*/ lv_image_cache_init(image_cache_size); lv_image_header_cache_init(image_header_count); + + lv_mutex_init(img_decoder_info_lock_p); + lv_mutex_init(img_decoder_open_lock_p); } /** @@ -73,6 +84,9 @@ void lv_image_decoder_deinit(void) lv_cache_destroy(img_cache_p, NULL); lv_cache_destroy(img_header_cache_p, NULL); + lv_mutex_delete(img_decoder_info_lock_p); + lv_mutex_delete(img_decoder_open_lock_p); + lv_ll_clear(img_decoder_ll_p); } @@ -83,7 +97,9 @@ lv_result_t lv_image_decoder_get_info(const void * src, lv_image_header_t * head dsc.src = src; dsc.src_type = lv_image_src_get_type(src); + lv_mutex_lock(img_decoder_info_lock_p); lv_image_decoder_t * decoder = image_decoder_get_info(&dsc, header); + lv_mutex_unlock(img_decoder_info_lock_p); if(decoder == NULL) return LV_RESULT_INVALID; return LV_RESULT_OK; @@ -97,6 +113,8 @@ lv_result_t lv_image_decoder_open(lv_image_decoder_dsc_t * dsc, const void * src dsc->src = src; dsc->src_type = lv_image_src_get_type(src); + lv_mutex_lock(img_decoder_open_lock_p); + if(lv_image_cache_is_enabled()) { dsc->cache = img_cache_p; /*Try cache first, unless we are told to ignore cache.*/ @@ -104,13 +122,19 @@ lv_result_t lv_image_decoder_open(lv_image_decoder_dsc_t * dsc, const void * src /* * Check the cache first * If the image is found in the cache, just return it.*/ - if(try_cache(dsc) == LV_RESULT_OK) return LV_RESULT_OK; + if(try_cache(dsc) == LV_RESULT_OK) { + lv_mutex_unlock(img_decoder_open_lock_p); + return LV_RESULT_OK; + } } } /*Find the decoder that can open the image source, and get the header info in the same time.*/ dsc->decoder = image_decoder_get_info(dsc, &dsc->header); - if(dsc->decoder == NULL) return LV_RESULT_INVALID; + if(dsc->decoder == NULL) { + lv_mutex_unlock(img_decoder_open_lock_p); + return LV_RESULT_INVALID; + } /*Make a copy of args*/ dsc->args = args ? *args : (lv_image_decoder_args_t) { @@ -144,6 +168,7 @@ lv_result_t lv_image_decoder_open(lv_image_decoder_dsc_t * dsc, const void * src } } + lv_mutex_unlock(img_decoder_open_lock_p); return res; } @@ -158,14 +183,20 @@ lv_result_t lv_image_decoder_get_area(lv_image_decoder_dsc_t * dsc, const lv_are void lv_image_decoder_close(lv_image_decoder_dsc_t * dsc) { - if(dsc->decoder) { - if(dsc->decoder->close_cb) dsc->decoder->close_cb(dsc->decoder, dsc); + if(!dsc->decoder) { + return; + } - if(lv_image_cache_is_enabled() && dsc->cache && dsc->cache_entry) { - /*Decoded data is in cache, release it from cache's callback*/ - lv_cache_release(dsc->cache, dsc->cache_entry, NULL); - } + lv_mutex_lock(img_decoder_open_lock_p); + + if(dsc->decoder->close_cb) dsc->decoder->close_cb(dsc->decoder, dsc); + + if(lv_image_cache_is_enabled() && dsc->cache && dsc->cache_entry) { + /*Decoded data is in cache, release it from cache's callback*/ + lv_cache_release(dsc->cache, dsc->cache_entry, NULL); } + + lv_mutex_unlock(img_decoder_open_lock_p); } /** @@ -269,7 +300,8 @@ lv_draw_buf_t * lv_image_decoder_post_process(lv_image_decoder_dsc_t * dsc, lv_d if(args->premultiply && !LV_COLOR_FORMAT_IS_ALPHA_ONLY(decoded->header.cf) && lv_color_format_has_alpha(decoded->header.cf) - && !lv_draw_buf_has_flag(decoded, LV_IMAGE_FLAGS_PREMULTIPLIED) /*Hasn't done yet*/ + && !lv_draw_buf_has_flag(decoded, LV_IMAGE_FLAGS_PREMULTIPLIED) + && decoded->header.cf != LV_COLOR_FORMAT_ARGB8888_PREMULTIPLIED /*Hasn't done yet*/ ) { LV_LOG_TRACE("Alpha premultiply."); if(lv_draw_buf_has_flag(decoded, LV_IMAGE_FLAGS_MODIFIABLE)) { diff --git a/src/draw/lv_image_dsc.h b/src/draw/lv_image_dsc.h index 922c65e909..6a6f7aff94 100644 --- a/src/draw/lv_image_dsc.h +++ b/src/draw/lv_image_dsc.h @@ -25,6 +25,11 @@ extern "C" { #define LV_IMAGE_HEADER_MAGIC (0x19) LV_EXPORT_CONST_INT(LV_IMAGE_HEADER_MAGIC); +/** + * Flags reserved for user, lvgl won't use these bits. + */ +#define LV_IMAGE_FLAGS_USER_MASK (0xFF00) + /********************** * TYPEDEFS **********************/ diff --git a/src/draw/nema_gfx/lv_draw_nema_gfx.c b/src/draw/nema_gfx/lv_draw_nema_gfx.c index fb0a3d67ed..a56420f223 100644 --- a/src/draw/nema_gfx/lv_draw_nema_gfx.c +++ b/src/draw/nema_gfx/lv_draw_nema_gfx.c @@ -243,12 +243,18 @@ static int32_t nema_gfx_evaluate(lv_draw_unit_t * draw_unit, lv_draw_task_t * ta } break; } +#if LV_USE_VECTOR_GRAPHIC && LV_USE_NEMA_VG + case LV_DRAW_TASK_TYPE_VECTOR: { + if(task->preference_score > 80) { + task->preference_score = 80; + task->preferred_draw_unit_id = DRAW_UNIT_ID_NEMA_GFX; + } + return 1; + } +#endif case LV_DRAW_TASK_TYPE_BOX_SHADOW: case LV_DRAW_TASK_TYPE_MASK_RECTANGLE: case LV_DRAW_TASK_TYPE_MASK_BITMAP: -#if LV_USE_VECTOR_GRAPHIC - case LV_DRAW_TASK_TYPE_VECTOR: -#endif default: break; } @@ -285,7 +291,7 @@ static int32_t nema_gfx_dispatch(lv_draw_unit_t * draw_unit, lv_layer_t * layer) #else nema_gfx_execute_drawing(draw_nema_gfx_unit); - draw_nema_gfx_unit->task_act->state = LV_DRAW_TASK_STATE_READY; + draw_nema_gfx_unit->task_act->state = LV_DRAW_TASK_STATE_FINISHED; draw_nema_gfx_unit->task_act = NULL; /* The draw unit is free now. Request a new dispatching as it can get a new task. */ @@ -328,6 +334,11 @@ static void nema_gfx_execute_drawing(lv_draw_nema_gfx_unit_t * u) case LV_DRAW_TASK_TYPE_BORDER: lv_draw_nema_gfx_border(t, t->draw_dsc, &t->area); break; +#if LV_USE_VECTOR_GRAPHIC && LV_USE_NEMA_VG + case LV_DRAW_TASK_TYPE_VECTOR: + lv_draw_nema_gfx_vector(t, t->draw_dsc, &t->area); + break; +#endif default: break; } @@ -388,7 +399,7 @@ static void nema_gfx_render_thread_cb(void * ptr) nema_gfx_execute_drawing(u); } /* Signal the ready state to dispatcher. */ - u->task_act->state = LV_DRAW_TASK_STATE_READY; + u->task_act->state = LV_DRAW_TASK_STATE_FINISHED; /* Cleanup. */ u->task_act = NULL; diff --git a/src/draw/nema_gfx/lv_draw_nema_gfx.h b/src/draw/nema_gfx/lv_draw_nema_gfx.h index 8197fab28e..5717e5be45 100644 --- a/src/draw/nema_gfx/lv_draw_nema_gfx.h +++ b/src/draw/nema_gfx/lv_draw_nema_gfx.h @@ -110,6 +110,11 @@ void lv_draw_nema_gfx_border(lv_draw_task_t * t, const lv_draw_border_dsc_t * ds void lv_draw_nema_gfx_arc(lv_draw_task_t * t, const lv_draw_arc_dsc_t * dsc, const lv_area_t * coords); +#if LV_USE_VECTOR_GRAPHIC && LV_USE_NEMA_VG +void lv_draw_nema_gfx_vector(lv_draw_task_t * t, const lv_draw_vector_dsc_t * dsc, + const lv_area_t * coords); +#endif + /********************** * MACROS diff --git a/src/draw/nema_gfx/lv_draw_nema_gfx_border.c b/src/draw/nema_gfx/lv_draw_nema_gfx_border.c index 31dec2c4b7..bed835e0dd 100644 --- a/src/draw/nema_gfx/lv_draw_nema_gfx_border.c +++ b/src/draw/nema_gfx/lv_draw_nema_gfx_border.c @@ -25,7 +25,7 @@ */ /** - * @file lv_draw_nema_gfx_fill.c + * @file lv_draw_nema_gfx_border.c * */ diff --git a/src/draw/nema_gfx/lv_draw_nema_gfx_fill.c b/src/draw/nema_gfx/lv_draw_nema_gfx_fill.c index 6199abf35e..e079277522 100644 --- a/src/draw/nema_gfx/lv_draw_nema_gfx_fill.c +++ b/src/draw/nema_gfx/lv_draw_nema_gfx_fill.c @@ -99,13 +99,12 @@ void lv_draw_nema_gfx_fill(lv_draw_task_t * t, const lv_draw_fill_dsc_t * dsc, c nema_vg_paint_clear(draw_nema_gfx_unit->paint); - nema_vg_paint_set_type(draw_nema_gfx_unit->paint, NEMA_VG_PAINT_GRAD_LINEAR); nema_vg_set_blend(NEMA_BL_SRC_OVER | NEMA_BLOP_SRC_PREMULT); float stops[LV_GRADIENT_MAX_STOPS]; color_var_t colors[LV_GRADIENT_MAX_STOPS]; - uint32_t cnt = LV_MAX(dsc->grad.stops_count, LV_GRADIENT_MAX_STOPS); + uint32_t cnt = LV_MIN(dsc->grad.stops_count, LV_GRADIENT_MAX_STOPS); for(uint8_t i = 0; i < cnt; i++) { stops[i] = (float)(dsc->grad.stops[i].frac) / 255.f; @@ -117,24 +116,58 @@ void lv_draw_nema_gfx_fill(lv_draw_task_t * t, const lv_draw_fill_dsc_t * dsc, c nema_vg_grad_set(draw_nema_gfx_unit->gradient, cnt, stops, colors); - float x0, y0, x1, y1; + nema_tex_mode_t extend_type; + switch(dsc->grad.extend) { + case LV_GRAD_EXTEND_REPEAT: + extend_type = NEMA_TEX_REPEAT; + break; + case LV_GRAD_EXTEND_REFLECT: + extend_type = NEMA_TEX_MIRROR; + break; + case LV_GRAD_EXTEND_PAD: + default: + extend_type = NEMA_TEX_CLAMP; + break; + } - if(dsc->grad.dir == LV_GRAD_DIR_HOR) { - x0 = rel_coords.x1; - x1 = rel_coords.x2; - y0 = rel_coords.y1; - y1 = rel_coords.y1; + if(dsc->grad.dir == LV_GRAD_DIR_VER || dsc->grad.dir == LV_GRAD_DIR_HOR + || dsc->grad.dir == LV_GRAD_DIR_LINEAR) { + nema_vg_paint_set_type(draw_nema_gfx_unit->paint, NEMA_VG_PAINT_GRAD_LINEAR); + + float x0, y0, x1, y1; + + if(dsc->grad.dir == LV_GRAD_DIR_HOR) { + x0 = rel_coords.x1; + x1 = rel_coords.x2; + y0 = rel_coords.y1; + y1 = rel_coords.y2; + } + else if(dsc->grad.dir == LV_GRAD_DIR_VER) { + x0 = rel_coords.x1; + x1 = rel_coords.x1; + y0 = rel_coords.y1; + y1 = rel_coords.y2; + } + else { + x0 = rel_coords.x1 + lv_pct_to_px(dsc->grad.params.linear.start.x, lv_area_get_width(coords)); + x1 = rel_coords.x1 + lv_pct_to_px(dsc->grad.params.linear.end.x, lv_area_get_width(coords)); + y0 = rel_coords.y1 + lv_pct_to_px(dsc->grad.params.linear.start.y, lv_area_get_height(coords)); + y1 = rel_coords.y1 + lv_pct_to_px(dsc->grad.params.linear.end.y, lv_area_get_height(coords)); + } + + nema_vg_paint_set_grad_linear(draw_nema_gfx_unit->paint, draw_nema_gfx_unit->gradient, x0, y0, x1, y1, + extend_type | NEMA_FILTER_BL); } - else { - x0 = rel_coords.x1; - x1 = rel_coords.x1; - y0 = rel_coords.y1; - y1 = rel_coords.y2; + else if(dsc->grad.dir == LV_GRAD_DIR_RADIAL) { + nema_vg_paint_set_type(draw_nema_gfx_unit->paint, NEMA_VG_PAINT_GRAD_RADIAL); + + nema_vg_paint_set_grad_radial(draw_nema_gfx_unit->paint, draw_nema_gfx_unit->gradient, + rel_coords.x1 + dsc->grad.params.radial.end.x, + rel_coords.y1 + dsc->grad.params.radial.end.y, + LV_ABS(dsc->grad.params.radial.end_extent.x - dsc->grad.params.radial.end.x), + extend_type | NEMA_FILTER_BL); } - nema_vg_paint_set_grad_linear(draw_nema_gfx_unit->paint, draw_nema_gfx_unit->gradient, x0, y0, x1, y1, - NEMA_TEX_CLAMP | NEMA_FILTER_BL); - if(radius > 0.f) nema_vg_draw_rounded_rect(rel_coords.x1, rel_coords.y1, coords_bg_w, coords_bg_h, radius, radius, NULL, draw_nema_gfx_unit->paint); diff --git a/src/draw/nema_gfx/lv_draw_nema_gfx_img.c b/src/draw/nema_gfx/lv_draw_nema_gfx_img.c index 88437806c3..619f4174f5 100644 --- a/src/draw/nema_gfx/lv_draw_nema_gfx_img.c +++ b/src/draw/nema_gfx/lv_draw_nema_gfx_img.c @@ -25,7 +25,7 @@ */ /** - * @file lv_draw_nema_gfx_fill.c + * @file lv_draw_nema_gfx_img.c * */ @@ -41,9 +41,9 @@ * STATIC PROTOTYPES **********************/ -static void _draw_nema_gfx_tile(lv_draw_task_t * t, const lv_draw_image_dsc_t * dsc, const lv_area_t * coords); - -static void _draw_nema_gfx_img(lv_draw_task_t * t, const lv_draw_image_dsc_t * dsc, const lv_area_t * coords); +static void _draw_nema_gfx_img(lv_draw_task_t * t, const lv_draw_image_dsc_t * dsc, + const lv_image_decoder_dsc_t * decoder_dsc, lv_draw_image_sup_t * sup, + const lv_area_t * img_coords, const lv_area_t * clipped_img_area); static uint32_t lv_nemagfx_mask_cf_to_nema(lv_color_format_t cf); @@ -51,80 +51,29 @@ static uint32_t lv_nemagfx_mask_cf_to_nema(lv_color_format_t cf); * STATIC FUNCTIONS **********************/ -static void _draw_nema_gfx_tile(lv_draw_task_t * t, const lv_draw_image_dsc_t * dsc, const lv_area_t * coords) -{ - - lv_image_decoder_dsc_t decoder_dsc; - lv_result_t res = lv_image_decoder_open(&decoder_dsc, dsc->src, NULL); - if(res != LV_RESULT_OK) { - LV_LOG_ERROR("Failed to open image"); - return; - } - - int32_t img_w = dsc->header.w; - int32_t img_h = dsc->header.h; - - lv_area_t tile_area; - if(lv_area_get_width(&dsc->image_area) >= 0) { - tile_area = dsc->image_area; - } - else { - tile_area = *coords; - } - lv_area_set_width(&tile_area, img_w); - lv_area_set_height(&tile_area, img_h); - - int32_t tile_x_start = tile_area.x1; - - while(tile_area.y1 <= t->clip_area.y2) { - while(tile_area.x1 <= t->clip_area.x2) { - - lv_area_t clipped_img_area; - if(lv_area_intersect(&clipped_img_area, &tile_area, &t->clip_area)) { - _draw_nema_gfx_img(t, dsc, &tile_area); - } - - tile_area.x1 += img_w; - tile_area.x2 += img_w; - } - - tile_area.y1 += img_h; - tile_area.y2 += img_h; - tile_area.x1 = tile_x_start; - tile_area.x2 = tile_x_start + img_w - 1; - } - - lv_image_decoder_close(&decoder_dsc); -} - -static void _draw_nema_gfx_img(lv_draw_task_t * t, const lv_draw_image_dsc_t * dsc, const lv_area_t * coords) +static void _draw_nema_gfx_img(lv_draw_task_t * t, const lv_draw_image_dsc_t * dsc, + const lv_image_decoder_dsc_t * decoder_dsc, lv_draw_image_sup_t * sup, + const lv_area_t * img_coords, const lv_area_t * clipped_img_area) { if(dsc->opa <= LV_OPA_MIN) return; lv_draw_nema_gfx_unit_t * draw_nema_gfx_unit = (lv_draw_nema_gfx_unit_t *)t->draw_unit; lv_layer_t * layer = t->target_layer; - const lv_image_dsc_t * img_dsc = dsc->src; + const lv_draw_buf_t * decoded = decoder_dsc->decoded; + const lv_image_header_t * header = &decoded->header; bool masked = dsc->bitmap_mask_src != NULL; - lv_area_t blend_area; - /*Let's get the blend area which is the intersection of the area to fill and the clip area.*/ - if(!lv_area_intersect(&blend_area, coords, &t->clip_area)) - return; /*Fully clipped, nothing to do*/ - lv_area_t rel_clip_area; - lv_area_copy(&rel_clip_area, &t->clip_area); + lv_area_copy(&rel_clip_area, clipped_img_area); lv_area_move(&rel_clip_area, -layer->buf_area.x1, -layer->buf_area.y1); bool has_transform = (dsc->rotation != 0 || dsc->scale_x != LV_SCALE_NONE || dsc->scale_y != LV_SCALE_NONE); bool recolor = (dsc->recolor_opa > LV_OPA_MIN); - /*Make the blend area relative to the buffer*/ - lv_area_move(&blend_area, -layer->buf_area.x1, -layer->buf_area.y1); - - uint32_t tex_w = lv_area_get_width(coords); - uint32_t tex_h = lv_area_get_height(coords); + uint32_t tex_w = header->w; + uint32_t tex_h = header->h; nema_set_clip(rel_clip_area.x1, rel_clip_area.y1, lv_area_get_width(&rel_clip_area), lv_area_get_height(&rel_clip_area)); @@ -132,11 +81,11 @@ static void _draw_nema_gfx_img(lv_draw_task_t * t, const lv_draw_image_dsc_t * d lv_color_format_t dst_cf = layer->draw_buf->header.cf; uint32_t dst_nema_cf = lv_nemagfx_cf_to_nema(dst_cf); - const void * src_buf = img_dsc->data; + const void * src_buf = decoded->data; uint32_t blending_mode = lv_nemagfx_blending_mode(dsc->blend_mode); - lv_color_format_t src_cf = img_dsc->header.cf; + lv_color_format_t src_cf = header->cf; /*Image contains Alpha*/ if(src_cf == LV_COLOR_FORMAT_ARGB8888 || src_cf == LV_COLOR_FORMAT_XRGB8888) { @@ -146,7 +95,7 @@ static void _draw_nema_gfx_img(lv_draw_task_t * t, const lv_draw_image_dsc_t * d uint32_t src_nema_cf = lv_nemagfx_cf_to_nema(src_cf); /* the stride should be computed internally for NEMA_TSC images and images missing a stride value */ int32_t src_stride = (src_cf >= LV_COLOR_FORMAT_NEMA_TSC_START && src_cf <= LV_COLOR_FORMAT_NEMA_TSC_END) - || img_dsc->header.stride == 0 ? -1 : (int32_t)img_dsc->header.stride; + || header->stride == 0 ? -1 : (int32_t)header->stride; int32_t stride = (dst_cf >= LV_COLOR_FORMAT_NEMA_TSC_START && dst_cf <= LV_COLOR_FORMAT_NEMA_TSC_END) ? -1 : lv_area_get_width(&(layer->buf_area)) * lv_color_format_get_size(dst_cf); @@ -189,13 +138,13 @@ static void _draw_nema_gfx_img(lv_draw_task_t * t, const lv_draw_image_dsc_t * d const lv_area_t * image_area; lv_area_t mask_area; - if(lv_area_get_width(&dsc->image_area) < 0) image_area = coords; + if(lv_area_get_width(&dsc->image_area) < 0) image_area = img_coords; else image_area = &dsc->image_area; lv_area_set(&mask_area, 0, 0, dsc->bitmap_mask_src->header.w - 1, dsc->bitmap_mask_src->header.h - 1); lv_area_align(image_area, &mask_area, LV_ALIGN_CENTER, 0, 0); - mask_buf += dsc->bitmap_mask_src->header.w * (coords->y1 - mask_area.y1) + (coords->x1 - mask_area.x1); + mask_buf += dsc->bitmap_mask_src->header.w * (img_coords->y1 - mask_area.y1) + (img_coords->x1 - mask_area.x1); nema_bind_tex(NEMA_TEX3, (uintptr_t)NEMA_VIRT2PHYS(mask_buf), mask->header.w, mask->header.h, lv_nemagfx_mask_cf_to_nema(mask->header.cf), @@ -206,13 +155,13 @@ static void _draw_nema_gfx_img(lv_draw_task_t * t, const lv_draw_image_dsc_t * d nema_set_blend_blit(blending_mode); if(!has_transform) { - nema_blit_rect((coords->x1 - layer->buf_area.x1), - (coords->y1 - layer->buf_area.y1), tex_w, tex_h); + nema_blit_rect((img_coords->x1 - layer->buf_area.x1), + (img_coords->y1 - layer->buf_area.y1), tex_w, tex_h); } else { /*Calculate the transformed points*/ - float x0 = (coords->x1 - layer->buf_area.x1); - float y0 = (coords->y1 - layer->buf_area.y1); + float x0 = (img_coords->x1 - layer->buf_area.x1); + float y0 = (img_coords->y1 - layer->buf_area.y1); float x1 = x0 + tex_w ; float y1 = y0; float x2 = x0 + tex_w ; @@ -273,10 +222,10 @@ void lv_draw_nema_gfx_img(lv_draw_task_t * t, const lv_draw_image_dsc_t * dsc, c { if(!dsc->tile) { - _draw_nema_gfx_img(t, dsc, coords); + lv_draw_image_normal_helper(t, dsc, coords, _draw_nema_gfx_img); } else { - _draw_nema_gfx_tile(t, dsc, coords); + lv_draw_image_tiled_helper(t, dsc, coords, _draw_nema_gfx_img); } } diff --git a/src/draw/nema_gfx/lv_draw_nema_gfx_label.c b/src/draw/nema_gfx/lv_draw_nema_gfx_label.c index 9275fe2cfa..e270ac7c83 100644 --- a/src/draw/nema_gfx/lv_draw_nema_gfx_label.c +++ b/src/draw/nema_gfx/lv_draw_nema_gfx_label.c @@ -25,7 +25,7 @@ */ /** - * @file lv_draw_nema_gfx_fill.c + * @file lv_draw_nema_gfx_label.c * */ @@ -414,7 +414,11 @@ static void _draw_label_iterate_characters(lv_draw_task_t * t, const lv_draw_lab const lv_area_t * coords) { const lv_font_t * font = dsc->font; - int32_t w; + lv_text_attributes_t attributes = {0}; + attributes.letter_space = dsc->letter_space; + attributes.line_space = dsc->line_space; + attributes.max_width = LV_COORD_MAX; + attributes.text_flags = dsc->flag; lv_area_t clipped_area; bool clip_ok = lv_area_intersect(&clipped_area, coords, &t->clip_area); @@ -427,14 +431,13 @@ static void _draw_label_iterate_characters(lv_draw_task_t * t, const lv_draw_lab if((dsc->flag & LV_TEXT_FLAG_EXPAND) == 0) { /*Normally use the label's width as width*/ - w = lv_area_get_width(coords); + attributes.max_width = lv_area_get_width(coords); } else { /*If EXPAND is enabled then not limit the text's width to the object's width*/ lv_point_t p; - lv_text_get_size(&p, dsc->text, dsc->font, dsc->letter_space, dsc->line_space, LV_COORD_MAX, - dsc->flag); - w = p.x; + lv_text_get_size_attributes(&p, dsc->text, dsc->font, &attributes); + attributes.max_width = p.x; } int32_t line_height_font = lv_font_get_line_height(font); @@ -471,14 +474,13 @@ static void _draw_label_iterate_characters(lv_draw_task_t * t, const lv_draw_lab uint32_t remaining_len = dsc->text_length; - uint32_t line_end = line_start + lv_text_get_next_line(&dsc->text[line_start], remaining_len, font, dsc->letter_space, - w, NULL, dsc->flag); + uint32_t line_end = line_start + lv_text_get_next_line(&dsc->text[line_start], remaining_len, font, NULL, &attributes); /*Go the first visible line*/ while(pos.y + line_height_font < t->clip_area.y1) { /*Go to next line*/ line_start = line_end; - line_end += lv_text_get_next_line(&dsc->text[line_start], remaining_len, font, dsc->letter_space, w, NULL, dsc->flag); + line_end += lv_text_get_next_line(&dsc->text[line_start], remaining_len, font, NULL, &attributes); pos.y += line_height; /*Save at the threshold coordinate*/ @@ -493,16 +495,14 @@ static void _draw_label_iterate_characters(lv_draw_task_t * t, const lv_draw_lab /*Align to middle*/ if(align == LV_TEXT_ALIGN_CENTER) { - line_width = lv_text_get_width_with_flags(&dsc->text[line_start], line_end - line_start, font, dsc->letter_space, - dsc->flag); + line_width = lv_text_get_width(&dsc->text[line_start], line_end - line_start, font, &attributes); pos.x += (lv_area_get_width(coords) - line_width) / 2; } /*Align to the right*/ else if(align == LV_TEXT_ALIGN_RIGHT) { - line_width = lv_text_get_width_with_flags(&dsc->text[line_start], line_end - line_start, font, dsc->letter_space, - dsc->flag); + line_width = lv_text_get_width(&dsc->text[line_start], line_end - line_start, font, &attributes); pos.x += lv_area_get_width(coords) - line_width; } @@ -530,6 +530,7 @@ static void _draw_label_iterate_characters(lv_draw_task_t * t, const lv_draw_lab uint32_t next_char_offset; uint32_t recolor_command_start_index = 0; int32_t letter_w; + cmd_state_t recolor_cmd_state = RECOLOR_CMD_STATE_WAIT_FOR_PARAMETER; lv_color_t recolor = lv_color_black(); /* Holds the selected color inside the recolor command */ uint8_t is_first_space_after_cmd = 0; @@ -553,7 +554,6 @@ static void _draw_label_iterate_characters(lv_draw_task_t * t, const lv_draw_lab line_start_x = pos.x; /*Write all letter of a line*/ - recolor_cmd_state = RECOLOR_CMD_STATE_WAIT_FOR_PARAMETER; next_char_offset = 0; #if LV_USE_BIDI char * bidi_txt = lv_malloc(line_end - line_start + 1); @@ -731,21 +731,21 @@ static void _draw_label_iterate_characters(lv_draw_task_t * t, const lv_draw_lab remaining_len -= line_end - line_start; line_start = line_end; if(remaining_len) { - line_end += lv_text_get_next_line(&dsc->text[line_start], remaining_len, font, dsc->letter_space, w, NULL, dsc->flag); + line_end += lv_text_get_next_line(&dsc->text[line_start], remaining_len, font, NULL, &attributes); } pos.x = coords->x1; /*Align to middle*/ if(align == LV_TEXT_ALIGN_CENTER) { line_width = - lv_text_get_width_with_flags(&dsc->text[line_start], line_end - line_start, font, dsc->letter_space, dsc->flag); + lv_text_get_width(&dsc->text[line_start], line_end - line_start, font, &attributes); pos.x += (lv_area_get_width(coords) - line_width) / 2; } /*Align to the right*/ else if(align == LV_TEXT_ALIGN_RIGHT) { line_width = - lv_text_get_width_with_flags(&dsc->text[line_start], line_end - line_start, font, dsc->letter_space, dsc->flag); + lv_text_get_width(&dsc->text[line_start], line_end - line_start, font, &attributes); pos.x += lv_area_get_width(coords) - line_width; } diff --git a/src/draw/nema_gfx/lv_draw_nema_gfx_layer.c b/src/draw/nema_gfx/lv_draw_nema_gfx_layer.c index 0c64564c64..14106ce5c6 100644 --- a/src/draw/nema_gfx/lv_draw_nema_gfx_layer.c +++ b/src/draw/nema_gfx/lv_draw_nema_gfx_layer.c @@ -25,7 +25,7 @@ */ /** - * @file lv_draw_nema_gfx_fill.c + * @file lv_draw_nema_gfx_layer.c * */ diff --git a/src/draw/nema_gfx/lv_draw_nema_gfx_line.c b/src/draw/nema_gfx/lv_draw_nema_gfx_line.c index ad6e24e012..5f5477c350 100644 --- a/src/draw/nema_gfx/lv_draw_nema_gfx_line.c +++ b/src/draw/nema_gfx/lv_draw_nema_gfx_line.c @@ -25,7 +25,7 @@ */ /** - * @file lv_draw_nema_gfx_fill.c + * @file lv_draw_nema_gfx_line.c * */ diff --git a/src/draw/nema_gfx/lv_draw_nema_gfx_stm32_hal.c b/src/draw/nema_gfx/lv_draw_nema_gfx_stm32_hal.c index cb6abaf33c..0d70b8e0c4 100644 --- a/src/draw/nema_gfx/lv_draw_nema_gfx_stm32_hal.c +++ b/src/draw/nema_gfx/lv_draw_nema_gfx_stm32_hal.c @@ -1,5 +1,5 @@ /** - * @file lv_draw_nema_gfx_hal.c + * @file lv_draw_nema_gfx_stm32_hal.c * * Global functions that implement some HAL functionality * which Nema will call directly. diff --git a/src/draw/nema_gfx/lv_draw_nema_gfx_triangle.c b/src/draw/nema_gfx/lv_draw_nema_gfx_triangle.c index 658da8da01..124b3e6be8 100644 --- a/src/draw/nema_gfx/lv_draw_nema_gfx_triangle.c +++ b/src/draw/nema_gfx/lv_draw_nema_gfx_triangle.c @@ -25,7 +25,7 @@ */ /** - * @file lv_draw_nema_gfx_fill.c + * @file lv_draw_nema_gfx_triangle.c * */ @@ -90,7 +90,9 @@ void lv_draw_nema_gfx_triangle(lv_draw_task_t * t, const lv_draw_triangle_dsc_t uint32_t bg_color = nema_rgba(col32.red, col32.green, col32.blue, col32.alpha); nema_enable_aa(1, 1, 1, 0); - nema_fill_triangle(dsc->p[0].x, dsc->p[0].y, dsc->p[1].x, dsc->p[1].y, dsc->p[2].x, dsc->p[2].y, bg_color); + nema_fill_triangle(dsc->p[0].x - layer->buf_area.x1, dsc->p[0].y - layer->buf_area.y1, + dsc->p[1].x - layer->buf_area.x1, dsc->p[1].y - layer->buf_area.y1, + dsc->p[2].x - layer->buf_area.x1, dsc->p[2].y - layer->buf_area.y1, bg_color); } #if LV_USE_NEMA_VG else { diff --git a/src/draw/nema_gfx/lv_draw_nema_gfx_utils.h b/src/draw/nema_gfx/lv_draw_nema_gfx_utils.h index a4f90b14c8..f47338b27a 100644 --- a/src/draw/nema_gfx/lv_draw_nema_gfx_utils.h +++ b/src/draw/nema_gfx/lv_draw_nema_gfx_utils.h @@ -25,7 +25,7 @@ */ /** - * @file lv_draw_nema_gfx.h + * @file lv_draw_nema_gfx_utils.h * */ diff --git a/src/draw/nema_gfx/lv_draw_nema_gfx_vector.c b/src/draw/nema_gfx/lv_draw_nema_gfx_vector.c new file mode 100644 index 0000000000..923f514c30 --- /dev/null +++ b/src/draw/nema_gfx/lv_draw_nema_gfx_vector.c @@ -0,0 +1,161 @@ +/** + * @file lv_draw_nema_gfx_vector.c + * + */ + +/********************* + * INCLUDES + *********************/ + +#include "lv_draw_nema_gfx.h" +#if LV_USE_NEMA_GFX && LV_USE_VECTOR_GRAPHIC && LV_USE_NEMA_VG + +#include "lv_nema_gfx_path.h" +#include "../lv_draw_vector_private.h" + +/********************* + * DEFINES + *********************/ + +/********************** + * TYPEDEFS + **********************/ + +typedef struct { + lv_draw_nema_gfx_unit_t * u; + float rel_translate_x; + float rel_translate_y; +} ctx_t; + +/********************** + * STATIC PROTOTYPES + **********************/ + +static void task_draw_cb(void * ctx, const lv_vector_path_t * path, const lv_vector_path_ctx_t * dsc); + +/********************** + * STATIC VARIABLES + **********************/ + +/********************** + * MACROS + **********************/ + +/********************** + * GLOBAL FUNCTIONS + **********************/ + +void lv_draw_nema_gfx_vector(lv_draw_task_t * t, const lv_draw_vector_dsc_t * dsc, + const lv_area_t * coords) +{ + ctx_t c; + c.u = (lv_draw_nema_gfx_unit_t *) t->draw_unit; + + lv_layer_t * layer = t->target_layer; + lv_area_t rel_clip_area; + lv_area_copy(&rel_clip_area, &t->clip_area); + lv_area_move(&rel_clip_area, -layer->buf_area.x1, -layer->buf_area.y1); + + c.rel_translate_x = -layer->buf_area.x1; + c.rel_translate_y = -layer->buf_area.y1; + + nema_set_clip(rel_clip_area.x1, rel_clip_area.y1, lv_area_get_width(&rel_clip_area), + lv_area_get_height(&rel_clip_area)); + + lv_color_format_t dst_cf = layer->draw_buf->header.cf; + uint32_t dst_nema_cf = lv_nemagfx_cf_to_nema(dst_cf); + + /* the stride should be computed internally for NEMA_TSC images and images missing a stride value */ + int32_t stride = (dst_cf >= LV_COLOR_FORMAT_NEMA_TSC_START && dst_cf <= LV_COLOR_FORMAT_NEMA_TSC_END) ? + -1 : lv_area_get_width(&(layer->buf_area)) * lv_color_format_get_size(dst_cf); + + nema_bind_dst_tex((uintptr_t)NEMA_VIRT2PHYS(layer->draw_buf->data), lv_area_get_width(&(layer->buf_area)), + lv_area_get_height(&(layer->buf_area)), dst_nema_cf, stride); + + nema_vg_set_blend(NEMA_BL_SRC_OVER | NEMA_BLOP_SRC_PREMULT); + + lv_vector_for_each_destroy_tasks(dsc->task_list, task_draw_cb, &c); +} + +/********************** + * STATIC FUNCTIONS + **********************/ + +static void task_draw_cb(void * ctx, const lv_vector_path_t * path, const lv_vector_path_ctx_t * dsc) +{ + ctx_t * c = ctx; + lv_draw_nema_gfx_unit_t * u = c->u; + + if(!path) return; + + nema_vg_path_clear(u->path); + nema_vg_paint_clear(u->paint); + + nema_vg_paint_set_type(u->paint, NEMA_VG_PAINT_COLOR); + + lv_matrix_t matrix = dsc->matrix; + matrix.m[0][2] += c->rel_translate_x; + matrix.m[1][2] += c->rel_translate_y; + nema_vg_path_set_matrix(c->u->path, (void *) &matrix); + + /* the path ops array needs to be translated to nema's opcodes */ + lv_vector_path_op_t * ops = lv_array_front(&path->ops); + uint32_t op_count = lv_array_size(&path->ops); + uint8_t * nema_ops = lv_malloc(op_count * sizeof(*nema_ops)); + LV_ASSERT_MALLOC(nema_ops); + for(uint32_t i = 0; i < op_count; i++) { + nema_ops[i] = ops[i] == LV_VECTOR_PATH_OP_MOVE_TO ? NEMA_VG_PRIM_MOVE : + ops[i] == LV_VECTOR_PATH_OP_LINE_TO ? NEMA_VG_PRIM_LINE : + ops[i] == LV_VECTOR_PATH_OP_QUAD_TO ? NEMA_VG_PRIM_BEZIER_QUAD : + ops[i] == LV_VECTOR_PATH_OP_CUBIC_TO ? NEMA_VG_PRIM_BEZIER_CUBIC : + /*LV_VECTOR_PATH_OP_CLOSE*/ NEMA_VG_PRIM_CLOSE; + } + + /* the path points array is in the right format for nema to use as-is */ + uint32_t point_count = lv_array_size(&path->points); + float * points = lv_array_front(&path->points); + + nema_vg_path_set_shape(u->path, op_count, nema_ops, point_count, points); + + nema_vg_set_quality(path->quality == LV_VECTOR_PATH_QUALITY_LOW ? NEMA_VG_QUALITY_FASTER : + path->quality == LV_VECTOR_PATH_QUALITY_MEDIUM ? NEMA_VG_QUALITY_BETTER : + /*LV_VECTOR_PATH_QUALITY_HIGH*/ NEMA_VG_QUALITY_MAXIMUM); + + if(dsc->fill_dsc.opa) { + nema_vg_set_fill_rule(dsc->fill_dsc.fill_rule == LV_VECTOR_FILL_NONZERO ? NEMA_VG_FILL_NON_ZERO : + /*LV_VECTOR_FILL_EVENODD*/ NEMA_VG_FILL_EVEN_ODD); + + uint32_t nema_dsc_color = nema_rgba(dsc->fill_dsc.color.red, dsc->fill_dsc.color.green, + dsc->fill_dsc.color.blue, dsc->fill_dsc.color.alpha); + nema_vg_paint_set_paint_color(u->paint, nema_dsc_color); + + nema_vg_draw_path(u->path, u->paint); + } + + if(dsc->stroke_dsc.opa) { + nema_vg_set_fill_rule(NEMA_VG_STROKE); + nema_vg_stroke_set_width(dsc->stroke_dsc.width); + uint8_t cap = dsc->stroke_dsc.cap == LV_VECTOR_STROKE_CAP_BUTT ? NEMA_VG_CAP_BUTT : + dsc->stroke_dsc.cap == LV_VECTOR_STROKE_CAP_SQUARE ? NEMA_VG_CAP_SQUARE : + /*LV_VECTOR_STROKE_CAP_ROUND*/ NEMA_VG_CAP_ROUND; + nema_vg_stroke_set_cap_style(cap, cap); + uint8_t join = dsc->stroke_dsc.join == LV_VECTOR_STROKE_JOIN_MITER ? NEMA_VG_JOIN_MITER : + dsc->stroke_dsc.join == LV_VECTOR_STROKE_JOIN_BEVEL ? NEMA_VG_JOIN_BEVEL : + /*LV_VECTOR_STROKE_JOIN_ROUND*/ NEMA_VG_JOIN_ROUND; + nema_vg_stroke_set_join_style(join); + nema_vg_stroke_set_miter_limit(dsc->stroke_dsc.miter_limit); + + uint32_t nema_dsc_color = nema_rgba(dsc->stroke_dsc.color.red, dsc->stroke_dsc.color.green, + dsc->stroke_dsc.color.blue, dsc->stroke_dsc.color.alpha); + nema_vg_paint_set_paint_color(u->paint, nema_dsc_color); + + nema_vg_draw_path(u->path, u->paint); + } + + nema_cl_submit(&c->u->cl); + nema_cl_wait(&u->cl); + + lv_free(nema_ops); +} + +#endif /*LV_USE_NEMA_GFX && LV_USE_VECTOR_GRAPHIC && LV_USE_NEMA_VG*/ diff --git a/src/draw/nxp/g2d/lv_draw_buf_g2d.c b/src/draw/nxp/g2d/lv_draw_buf_g2d.c index 8653ea5296..e729e9b08c 100644 --- a/src/draw/nxp/g2d/lv_draw_buf_g2d.c +++ b/src/draw/nxp/g2d/lv_draw_buf_g2d.c @@ -15,7 +15,8 @@ #include "lv_draw_g2d.h" -#if LV_USE_DRAW_G2D +#if LV_USE_G2D +#if LV_USE_DRAW_G2D || LV_USE_ROTATE_G2D #include "../../lv_draw_buf_private.h" #include "g2d.h" #include "lv_g2d_buf_map.h" @@ -89,4 +90,5 @@ static void _invalidate_cache(const lv_draw_buf_t * draw_buf, const lv_area_t * g2d_cache_op(buf, G2D_CACHE_FLUSH); } -#endif /*LV_USE_DRAW_G2D*/ +#endif /*LV_USE_DRAW_G2D || LV_USE_ROTATE_G2D*/ +#endif /*LV_USE_G2D*/ diff --git a/src/draw/nxp/g2d/lv_draw_g2d.c b/src/draw/nxp/g2d/lv_draw_g2d.c index 42c6e40ec8..0b670c8ab1 100644 --- a/src/draw/nxp/g2d/lv_draw_g2d.c +++ b/src/draw/nxp/g2d/lv_draw_g2d.c @@ -11,10 +11,11 @@ #include "lv_draw_g2d.h" -#if LV_USE_DRAW_G2D +#if LV_USE_G2D #include "../../../misc/lv_area_private.h" #include "g2d.h" #include "lv_g2d_buf_map.h" +#include "lv_g2d_utils.h" /********************* * DEFINES @@ -22,6 +23,15 @@ #define DRAW_UNIT_ID_G2D 8 +/** + * Enum name differs depending on g2d version (breaking API change, not handled in g2d.h) + * Note: enum value is the same in either case + * See https://github.com/nxp-imx/imx-g2d-pxp/commit/d7af84b5c8ad161b6898ffabe23918cb59fe2fe9 + */ +#if (G2D_VERSION_MAJOR >= 2) && (G2D_VERSION_MINOR < 3) + #define G2D_HARDWARE_PXP_V1 G2D_HARDWARE_PXP +#endif + /********************** * TYPEDEFS **********************/ @@ -57,6 +67,8 @@ static void _g2d_execute_drawing(lv_draw_task_t * t); * STATIC VARIABLES **********************/ +static int32_t is_hw_pxp = 0; + /********************** * MACROS **********************/ @@ -68,16 +80,13 @@ static void _g2d_execute_drawing(lv_draw_task_t * t); void lv_draw_g2d_init(void) { lv_draw_buf_g2d_init_handlers(); - +#if LV_USE_DRAW_G2D lv_draw_g2d_unit_t * draw_g2d_unit = lv_draw_create_unit(sizeof(lv_draw_g2d_unit_t)); draw_g2d_unit->base_unit.evaluate_cb = _g2d_evaluate; draw_g2d_unit->base_unit.dispatch_cb = _g2d_dispatch; draw_g2d_unit->base_unit.delete_cb = _g2d_delete; draw_g2d_unit->base_unit.name = "G2D"; - g2d_create_buf_map(); - if(g2d_open(&draw_g2d_unit->g2d_handle)) { - LV_LOG_ERROR("g2d_open fail.\n"); - } + #if LV_USE_G2D_DRAW_THREAD lv_draw_sw_thread_dsc_t * thread_dsc = &draw_g2d_unit->thread_dsc; thread_dsc->idx = 0; @@ -85,6 +94,12 @@ void lv_draw_g2d_init(void) lv_thread_init(&thread_dsc->thread, "g2ddraw", LV_DRAW_THREAD_PRIO, _g2d_render_thread_cb, LV_DRAW_THREAD_STACK_SIZE, thread_dsc); #endif +#endif + g2d_create_buf_map(); + void * handle; + LV_ASSERT_MSG(!g2d_open(&handle), "Cannot open G2D handle\r\n"); + g2d_query_hardware(handle, G2D_HARDWARE_PXP_V1, &is_hw_pxp); + g2d_set_handle(handle); } void lv_draw_g2d_deinit(void) @@ -95,7 +110,7 @@ void lv_draw_g2d_deinit(void) /********************** * STATIC FUNCTIONS **********************/ - +#if LV_USE_DRAW_G2D static inline bool _g2d_dest_cf_supported(lv_color_format_t cf) { bool is_cf_supported = false; @@ -105,6 +120,12 @@ static inline bool _g2d_dest_cf_supported(lv_color_format_t cf) case LV_COLOR_FORMAT_XRGB8888: is_cf_supported = true; break; + case LV_COLOR_FORMAT_RGB565: { + if(!is_hw_pxp) { + is_cf_supported = true; + } + } + break; default: break; } @@ -112,7 +133,7 @@ static inline bool _g2d_dest_cf_supported(lv_color_format_t cf) return is_cf_supported; } -static inline bool _g2d_src_cf_supported(lv_draw_unit_t * drawunit, lv_color_format_t cf) +static inline bool _g2d_src_cf_supported(lv_color_format_t cf) { bool is_cf_supported = false; @@ -122,10 +143,7 @@ static inline bool _g2d_src_cf_supported(lv_draw_unit_t * drawunit, lv_color_for is_cf_supported = true; break; case LV_COLOR_FORMAT_RGB565: { - int32_t hw_pxp = 0; - lv_draw_g2d_unit_t * u = (lv_draw_g2d_unit_t *)drawunit; - g2d_query_hardware(u->g2d_handle, G2D_HARDWARE_PXP, &hw_pxp); - if(!hw_pxp) { + if(!is_hw_pxp) { is_cf_supported = true; } } @@ -139,16 +157,13 @@ static inline bool _g2d_src_cf_supported(lv_draw_unit_t * drawunit, lv_color_for static bool _g2d_draw_img_supported(const lv_draw_image_dsc_t * draw_dsc) { - bool is_tiled = draw_dsc->tile; - /* Tiled image (repeat image) is currently not supported. */ - if(is_tiled) - return false; - bool has_recolor = (draw_dsc->recolor_opa > LV_OPA_MIN); - bool has_rotation = (draw_dsc->rotation != 0); + /* Recolor is not supported. */ + if(has_recolor) + return false; - /* Recolor or rotation are not supported. */ - if(has_recolor || has_rotation) + /* G2D can only rotate at 90x angles. */ + if(draw_dsc->rotation % 900) return false; return true; @@ -184,7 +199,7 @@ static int32_t _g2d_evaluate(lv_draw_unit_t * u, lv_draw_task_t * t) case LV_DRAW_TASK_TYPE_IMAGE: { const lv_draw_image_dsc_t * draw_dsc = (lv_draw_image_dsc_t *) t->draw_dsc; - if(!_g2d_src_cf_supported(u, draw_dsc->header.cf)) + if(!_g2d_src_cf_supported(draw_dsc->header.cf)) return 0; if(!_g2d_draw_img_supported(draw_dsc)) @@ -243,7 +258,7 @@ static int32_t _g2d_dispatch(lv_draw_unit_t * draw_unit, lv_layer_t * layer) _g2d_execute_drawing(t); - draw_g2d_unit->task_act->state = LV_DRAW_TASK_STATE_READY; + draw_g2d_unit->task_act->state = LV_DRAW_TASK_STATE_FINISHED; draw_g2d_unit->task_act = NULL; /* The draw unit is free now. Request a new dispatching as it can get a new task. */ @@ -255,10 +270,12 @@ static int32_t _g2d_dispatch(lv_draw_unit_t * draw_unit, lv_layer_t * layer) static int32_t _g2d_delete(lv_draw_unit_t * draw_unit) { - lv_draw_g2d_unit_t * draw_g2d_unit = (lv_draw_g2d_unit_t *) draw_unit; lv_result_t res = LV_RESULT_OK; -#if LV_USE_G2D_DRAW_THREAD +#if !LV_USE_G2D_DRAW_THREAD + LV_UNUSED(draw_unit); +#else + lv_draw_g2d_unit_t * draw_g2d_unit = (lv_draw_g2d_unit_t *) draw_unit; lv_draw_sw_thread_dsc_t * thread_dsc = &draw_g2d_unit->thread_dsc; LV_LOG_INFO("Cancel G2D draw thread."); thread_dsc->exit_status = true; @@ -268,7 +285,7 @@ static int32_t _g2d_delete(lv_draw_unit_t * draw_unit) res = lv_thread_delete(&thread_dsc->thread); #endif - g2d_close(draw_g2d_unit->g2d_handle); + g2d_close(g2d_get_handle()); return res; } @@ -318,7 +335,7 @@ static void _g2d_render_thread_cb(void * ptr) _g2d_execute_drawing(thread_dsc->task_act); /* Signal the ready state to dispatcher. */ - thread_dsc->task_act->state = LV_DRAW_TASK_STATE_READY; + thread_dsc->task_act->state = LV_DRAW_TASK_STATE_FINISHED; /* Cleanup. */ thread_dsc->task_act = NULL; @@ -333,4 +350,5 @@ static void _g2d_render_thread_cb(void * ptr) } #endif -#endif /*LV_USE_DRAW_G2D*/ +#endif /*LV_USE_DRAW_G2D || LV_USE_ROTATE_G2D*/ +#endif /*LV_USE_G2D*/ diff --git a/src/draw/nxp/g2d/lv_draw_g2d.h b/src/draw/nxp/g2d/lv_draw_g2d.h index 061aa3c316..59d9a62c51 100644 --- a/src/draw/nxp/g2d/lv_draw_g2d.h +++ b/src/draw/nxp/g2d/lv_draw_g2d.h @@ -22,7 +22,8 @@ extern "C" { #include "../../../lv_conf_internal.h" -#if LV_USE_DRAW_G2D +#if LV_USE_G2D +#if LV_USE_DRAW_G2D || LV_USE_ROTATE_G2D #include "../../sw/lv_draw_sw_private.h" /********************* @@ -40,8 +41,6 @@ typedef struct lv_draw_g2d_unit { #else lv_draw_task_t * task_act; #endif - - void * g2d_handle; } lv_draw_g2d_unit_t; /********************** @@ -62,7 +61,8 @@ void lv_draw_g2d_img(lv_draw_task_t * t); * MACROS **********************/ -#endif /*LV_USE_DRAW_G2D*/ +#endif /*LV_USE_DRAW_G2D || LV_USE_ROTATE_G2D*/ +#endif /*LV_USE_G2D*/ #ifdef __cplusplus } /*extern "C"*/ diff --git a/src/draw/nxp/g2d/lv_draw_g2d_fill.c b/src/draw/nxp/g2d/lv_draw_g2d_fill.c index 5863e4d6c6..73dda3fc68 100644 --- a/src/draw/nxp/g2d/lv_draw_g2d_fill.c +++ b/src/draw/nxp/g2d/lv_draw_g2d_fill.c @@ -15,6 +15,7 @@ #include "lv_draw_g2d.h" +#if LV_USE_G2D #if LV_USE_DRAW_G2D #include #include "g2d.h" @@ -35,14 +36,14 @@ **********************/ /* Blit simple w/ opa and alpha channel */ -static void _g2d_fill(void * g2d_handle, struct g2d_surface * dst_surf); -static void _g2d_fill_with_opa(void * g2d_handle, struct g2d_surface * dst_surf, struct g2d_surface * src_surf); +static void _g2d_fill(void * handle, struct g2d_surface * dst_surf); +static void _g2d_fill_with_opa(void * handle, struct g2d_surface * dst_surf, struct g2d_surface * src_surf); static void _g2d_set_src_surf(struct g2d_surface * src_surf, struct g2d_buf * buf, const lv_area_t * area, - lv_color_t color, lv_opa_t opa); + lv_color_t color, lv_opa_t opa, lv_color_format_t cf); static void _g2d_set_dst_surf(struct g2d_surface * dst_surf, struct g2d_buf * buf, const lv_area_t * area, - int32_t stride, lv_color_t color); + int32_t stride, lv_color_t color, lv_color_format_t cf); /********************** * STATIC VARIABLES @@ -63,7 +64,6 @@ void lv_draw_g2d_fill(lv_draw_task_t * t) if(dsc->opa <= (lv_opa_t)LV_OPA_MIN) return; - lv_draw_g2d_unit_t * u = (lv_draw_g2d_unit_t *)t->draw_unit; lv_layer_t * layer = t->target_layer; lv_draw_buf_t * draw_buf = layer->draw_buf; lv_area_t * coords = &t->area; @@ -88,19 +88,21 @@ void lv_draw_g2d_fill(lv_draw_task_t * t) bool has_opa = (dsc->opa < (lv_opa_t)LV_OPA_MAX); struct g2d_surface dst_surf; - _g2d_set_dst_surf(&dst_surf, dst_buf, &blend_area, stride, dsc->color); + _g2d_set_dst_surf(&dst_surf, dst_buf, &blend_area, stride, dsc->color, draw_buf->header.cf); + + void * handle = g2d_get_handle(); if(has_opa) { - struct g2d_buf * tmp_buf = g2d_alloc(lv_area_get_width(&blend_area) * lv_area_get_height(&blend_area) * sizeof( - lv_color32_t), 1); + struct g2d_buf * tmp_buf = g2d_alloc(lv_area_get_width(&blend_area) * lv_area_get_height( + &blend_area) * lv_color_format_get_size(draw_buf->header.cf), 1); G2D_ASSERT_MSG(tmp_buf, "Failed to alloc temporary buffer."); struct g2d_surface src_surf; - _g2d_set_src_surf(&src_surf, tmp_buf, &blend_area, dsc->color, dsc->opa); - _g2d_fill_with_opa(u->g2d_handle, &dst_surf, &src_surf); + _g2d_set_src_surf(&src_surf, tmp_buf, &blend_area, dsc->color, dsc->opa, draw_buf->header.cf); + _g2d_fill_with_opa(handle, &dst_surf, &src_surf); g2d_free(tmp_buf); } else { - _g2d_fill(u->g2d_handle, &dst_surf); + _g2d_fill(handle, &dst_surf); } } @@ -109,12 +111,12 @@ void lv_draw_g2d_fill(lv_draw_task_t * t) **********************/ static void _g2d_set_src_surf(struct g2d_surface * src_surf, struct g2d_buf * buf, const lv_area_t * area, - lv_color_t color, lv_opa_t opa) + lv_color_t color, lv_opa_t opa, lv_color_format_t cf) { int32_t width = lv_area_get_width(area); int32_t height = lv_area_get_height(area); - src_surf->format = G2D_RGBA8888; + src_surf->format = g2d_get_buf_format(cf); src_surf->left = 0; src_surf->top = 0; @@ -133,12 +135,12 @@ static void _g2d_set_src_surf(struct g2d_surface * src_surf, struct g2d_buf * bu } static void _g2d_set_dst_surf(struct g2d_surface * dst_surf, struct g2d_buf * buf, const lv_area_t * area, - int32_t stride, lv_color_t color) + int32_t stride, lv_color_t color, lv_color_format_t cf) { int32_t width = lv_area_get_width(area); int32_t height = lv_area_get_height(area); - dst_surf->format = G2D_RGBA8888; + dst_surf->format = g2d_get_buf_format(cf); dst_surf->left = area->x1; dst_surf->top = area->y1; @@ -156,23 +158,24 @@ static void _g2d_set_dst_surf(struct g2d_surface * dst_surf, struct g2d_buf * bu dst_surf->blendfunc = G2D_ONE_MINUS_SRC_ALPHA | G2D_PRE_MULTIPLIED_ALPHA; } -static void _g2d_fill_with_opa(void * g2d_handle, struct g2d_surface * dst_surf, struct g2d_surface * src_surf) +static void _g2d_fill_with_opa(void * handle, struct g2d_surface * dst_surf, struct g2d_surface * src_surf) { - g2d_clear(g2d_handle, src_surf); - - g2d_enable(g2d_handle, G2D_BLEND); - g2d_enable(g2d_handle, G2D_GLOBAL_ALPHA); - g2d_blit(g2d_handle, src_surf, dst_surf); - g2d_finish(g2d_handle); - g2d_disable(g2d_handle, G2D_GLOBAL_ALPHA); - g2d_disable(g2d_handle, G2D_BLEND); + g2d_clear(handle, src_surf); + + g2d_enable(handle, G2D_BLEND); + g2d_enable(handle, G2D_GLOBAL_ALPHA); + g2d_blit(handle, src_surf, dst_surf); + g2d_finish(handle); + g2d_disable(handle, G2D_GLOBAL_ALPHA); + g2d_disable(handle, G2D_BLEND); } -static void _g2d_fill(void * g2d_handle, struct g2d_surface * dst_surf) +static void _g2d_fill(void * handle, struct g2d_surface * dst_surf) { - g2d_clear(g2d_handle, dst_surf); + g2d_clear(handle, dst_surf); - g2d_finish(g2d_handle); + g2d_finish(handle); } -#endif /*LV_USE_DRAW_G2D*/ \ No newline at end of file +#endif /*LV_USE_DRAW_G2D*/ +#endif /*LV_USE_G2D*/ diff --git a/src/draw/nxp/g2d/lv_draw_g2d_img.c b/src/draw/nxp/g2d/lv_draw_g2d_img.c index 3b70934849..2e7d6bea49 100644 --- a/src/draw/nxp/g2d/lv_draw_g2d_img.c +++ b/src/draw/nxp/g2d/lv_draw_g2d_img.c @@ -15,11 +15,13 @@ #include "lv_draw_g2d.h" +#if LV_USE_G2D #if LV_USE_DRAW_G2D -#include #include #include "g2d.h" #include "../../../misc/lv_area_private.h" +#include "../../lv_draw_image_private.h" +#include "../../lv_image_decoder_private.h" #include "lv_g2d_utils.h" #include "lv_g2d_buf_map.h" @@ -35,16 +37,26 @@ * STATIC PROTOTYPES **********************/ -static struct g2d_buf * _g2d_handle_src_buf(const lv_image_dsc_t * data); +static void _g2d_draw_core_cb(lv_draw_task_t * t, const lv_draw_image_dsc_t * draw_dsc, + const lv_image_decoder_dsc_t * decoder_dsc, lv_draw_image_sup_t * sup, const lv_area_t * img_coords, + const lv_area_t * clipped_img_area); + +static struct g2d_buf * _g2d_handle_src_buf(const lv_draw_buf_t * data); static void _g2d_set_src_surf(struct g2d_surface * src_surf, struct g2d_buf * buf, const lv_area_t * area, - int32_t stride, lv_color_format_t cf, lv_opa_t opa); + int32_t stride, lv_color_format_t cf, const lv_draw_image_dsc_t * dsc); + +static void _g2d_set_tmp_surf(struct g2d_surface * tmp_surf, struct g2d_buf * buf, const lv_area_t * area, + lv_color_format_t cf); static void _g2d_set_dst_surf(struct g2d_surface * dst_surf, struct g2d_buf * buf, const lv_area_t * area, - int32_t stride, lv_color_format_t cf, const lv_draw_image_dsc_t * dsc); + lv_draw_buf_t * draw_buf); /* Blit simple w/ opa and alpha channel */ -static void _g2d_blit(void * g2d_handle, struct g2d_surface * dst_surf, struct g2d_surface * src_surf); +static void _g2d_blit(void * handle, struct g2d_surface * dst_surf, struct g2d_surface * src_surf); + +static void _g2d_blit_two_steps(void * handle, struct g2d_surface * dst_surf, struct g2d_surface * src_surf, + struct g2d_surface * tmp_surf); /********************** * STATIC VARIABLES @@ -65,59 +77,89 @@ void lv_draw_g2d_img(lv_draw_task_t * t) if(dsc->opa <= (lv_opa_t)LV_OPA_MIN) return; - lv_draw_g2d_unit_t * u = (lv_draw_g2d_unit_t *)t->draw_unit; - lv_layer_t * layer = t->target_layer; - lv_draw_buf_t * draw_buf = layer->draw_buf; - const lv_image_dsc_t * img_dsc = dsc->src; lv_area_t * coords = &t->area; - lv_area_t rel_coords; - lv_area_copy(&rel_coords, coords); - lv_area_move(&rel_coords, -layer->buf_area.x1, -layer->buf_area.y1); + bool is_tiled = (dsc->tile != 0); + + if(is_tiled) + lv_draw_image_tiled_helper(t, dsc, coords, _g2d_draw_core_cb); + else + lv_draw_image_normal_helper(t, dsc, coords, _g2d_draw_core_cb); +} + +/********************** + * STATIC FUNCTIONS + **********************/ + +static void _g2d_draw_core_cb(lv_draw_task_t * t, const lv_draw_image_dsc_t * draw_dsc, + const lv_image_decoder_dsc_t * decoder_dsc, lv_draw_image_sup_t * sup, const lv_area_t * img_coords, + const lv_area_t * clipped_img_area) +{ + LV_UNUSED(sup); + lv_draw_buf_t * draw_buf = t->target_layer->draw_buf; + + const lv_draw_buf_t * decoded = decoder_dsc->decoded; - lv_area_t clip_area; - lv_area_copy(&clip_area, &t->clip_area); - lv_area_move(&clip_area, -layer->buf_area.x1, -layer->buf_area.y1); + lv_area_t rel_clip_area; + lv_area_copy(&rel_clip_area, clipped_img_area); + lv_area_move(&rel_clip_area, -img_coords->x1, -img_coords->y1); - lv_area_t blend_area; - bool has_transform = (dsc->rotation != 0 || dsc->scale_x != LV_SCALE_NONE || dsc->scale_y != LV_SCALE_NONE); - if(has_transform) - lv_area_copy(&blend_area, &rel_coords); - else if(!lv_area_intersect(&blend_area, &rel_coords, &clip_area)) - return; /*Fully clipped, nothing to do*/ + lv_area_t rel_img_coords; + lv_area_copy(&rel_img_coords, img_coords); + lv_area_move(&rel_img_coords, -img_coords->x1, -img_coords->y1); lv_area_t src_area; - src_area.x1 = blend_area.x1 - (coords->x1 - layer->buf_area.x1); - src_area.y1 = blend_area.y1 - (coords->y1 - layer->buf_area.y1); - src_area.x2 = src_area.x1 + lv_area_get_width(&blend_area); - src_area.y2 = src_area.y1 + lv_area_get_height(&blend_area); - int32_t src_stride = img_dsc->header.stride / (lv_color_format_get_bpp(img_dsc->header.cf) / 8); - lv_color_format_t src_cf = img_dsc->header.cf; + if(!lv_area_intersect(&src_area, &rel_clip_area, &rel_img_coords)) + return; + + lv_color_format_t src_cf = draw_dsc->header.cf; + + /* G2D takes stride in pixels. */ + const uint8_t pixel_size = lv_color_format_get_size(src_cf); + + uint32_t src_stride = draw_dsc->header.stride == 0 ? + lv_color_format_get_size(draw_dsc->header.cf) * draw_dsc->header.w : + draw_dsc->header.stride; + LV_ASSERT(pixel_size != 0); + src_stride /= pixel_size; /* Source image */ - struct g2d_buf * src_buf = _g2d_handle_src_buf(img_dsc); + struct g2d_buf * src_buf = _g2d_handle_src_buf(decoded); /* Destination buffer */ struct g2d_buf * dst_buf = g2d_search_buf_map(draw_buf->data); - /* G2D takes stride in pixels. */ - int32_t dest_stride = draw_buf->header.stride / (lv_color_format_get_bpp(draw_buf->header.cf) / 8); - lv_color_format_t dest_cf = draw_buf->header.cf; + + void * handle = g2d_get_handle(); struct g2d_surface src_surf; struct g2d_surface dst_surf; - _g2d_set_src_surf(&src_surf, src_buf, &src_area, src_stride, src_cf, dsc->opa); - _g2d_set_dst_surf(&dst_surf, dst_buf, &blend_area, dest_stride, dest_cf, dsc); - - _g2d_blit(u->g2d_handle, &dst_surf, &src_surf); + _g2d_set_src_surf(&src_surf, src_buf, &src_area, src_stride, src_cf, draw_dsc); + _g2d_set_dst_surf(&dst_surf, dst_buf, clipped_img_area, draw_buf); + + bool has_rotation = (draw_dsc->rotation != 0); + + if(has_rotation) { + /** If the image has rotation, then blit in two steps: + * 1. Source with rotation to temporary surface. + * 2. Temporary with other transformations (if any) to destination (frame buffer). + */ + struct g2d_buf * tmp_buf = g2d_alloc(lv_area_get_width(&src_area) * lv_area_get_height( + &src_area) * lv_color_format_get_size(src_cf), 1); + G2D_ASSERT_MSG(tmp_buf, "Failed to alloc temporary buffer."); + struct g2d_surface tmp_surf; + _g2d_set_tmp_surf(&tmp_surf, tmp_buf, &src_area, src_cf); + _g2d_blit_two_steps(handle, &dst_surf, &src_surf, &tmp_surf); + g2d_free(tmp_buf); + } + else { + // If rotation is not involved, blit in one step. + _g2d_blit(handle, &dst_surf, &src_surf); + } } -/********************** - * STATIC FUNCTIONS - **********************/ - -static struct g2d_buf * _g2d_handle_src_buf(const lv_image_dsc_t * img_dsc) +static struct g2d_buf * _g2d_handle_src_buf(const lv_draw_buf_t * img_dsc) { struct g2d_buf * src_buf = g2d_search_buf_map((void *)img_dsc->data); @@ -133,66 +175,95 @@ static struct g2d_buf * _g2d_handle_src_buf(const lv_image_dsc_t * img_dsc) } static void _g2d_set_src_surf(struct g2d_surface * src_surf, struct g2d_buf * buf, const lv_area_t * area, - int32_t stride, lv_color_format_t cf, lv_opa_t opa) + int32_t stride, lv_color_format_t cf, const lv_draw_image_dsc_t * dsc) { src_surf->format = g2d_get_buf_format(cf); + int32_t src_w = lv_area_get_width(area); + int32_t src_h = lv_area_get_height(area); + + bool has_rotation = (dsc->rotation != 0); + enum g2d_rotation g2d_angle = G2D_ROTATION_0; + + if(has_rotation) { + switch(dsc->rotation) { + case 0: + g2d_angle = G2D_ROTATION_0; + break; + case 900: + g2d_angle = G2D_ROTATION_270; + break; + case 1800: + g2d_angle = G2D_ROTATION_180; + break; + case 2700: + g2d_angle = G2D_ROTATION_90; + break; + default: + g2d_angle = G2D_ROTATION_0; + } + } + src_surf->left = area->x1; src_surf->top = area->y1; - src_surf->right = area->x2; - src_surf->bottom = area->y2; + src_surf->right = area->x1 + src_w; + src_surf->bottom = area->y1 + src_h; src_surf->stride = stride; - src_surf->width = area->x2 - area->x1; - src_surf->height = area->y2 - area->y1; + src_surf->width = src_w; + src_surf->height = src_h; src_surf->planes[0] = buf->buf_paddr; - src_surf->rot = G2D_ROTATION_0; + src_surf->rot = g2d_angle; src_surf->clrcolor = g2d_rgba_to_u32(lv_color_black()); - src_surf->global_alpha = opa; + src_surf->global_alpha = dsc->opa; src_surf->blendfunc = G2D_ONE | G2D_PRE_MULTIPLIED_ALPHA; } +static void _g2d_set_tmp_surf(struct g2d_surface * tmp_surf, struct g2d_buf * buf, const lv_area_t * area, + lv_color_format_t cf) +{ + tmp_surf->format = g2d_get_buf_format(cf); + + int32_t dest_w = lv_area_get_width(area); + int32_t dest_h = lv_area_get_height(area); + + tmp_surf->left = area->x1; + tmp_surf->top = area->y1; + tmp_surf->right = area->x1 + dest_w; + tmp_surf->bottom = area->y1 + dest_h; + tmp_surf->stride = dest_w; + tmp_surf->width = dest_w; + tmp_surf->height = dest_h; + + tmp_surf->planes[0] = buf->buf_paddr; + tmp_surf->rot = G2D_ROTATION_0; + + tmp_surf->clrcolor = g2d_rgba_to_u32(lv_color_black()); + tmp_surf->global_alpha = 0x00; + tmp_surf->blendfunc = G2D_ONE_MINUS_SRC_ALPHA | G2D_PRE_MULTIPLIED_ALPHA; +} + static void _g2d_set_dst_surf(struct g2d_surface * dst_surf, struct g2d_buf * buf, const lv_area_t * area, - int32_t stride, lv_color_format_t cf, const lv_draw_image_dsc_t * dsc) + lv_draw_buf_t * draw_buf) { - int32_t width = lv_area_get_width(area); - int32_t height = lv_area_get_height(area); - - lv_point_t pivot = dsc->pivot; - /*The offsets are now relative to the transformation result with pivot ULC*/ - int32_t piv_offset_x = 0; - int32_t piv_offset_y = 0; - int32_t trim_x = 0; - int32_t trim_y = 0; - int32_t dest_w; - int32_t dest_h; - - float fp_scale_x = (float)dsc->scale_x / LV_SCALE_NONE; - float fp_scale_y = (float)dsc->scale_y / LV_SCALE_NONE; - int32_t int_scale_x = (int32_t)fp_scale_x; - int32_t int_scale_y = (int32_t)fp_scale_y; - - /*Any scale_factor in (k, k + 1] will result in a trim equal to k*/ - trim_x = (fp_scale_x == int_scale_x) ? int_scale_x - 1 : int_scale_x; - trim_y = (fp_scale_y == int_scale_y) ? int_scale_y - 1 : int_scale_y; - - dest_w = width * fp_scale_x + trim_x; - dest_h = height * fp_scale_y + trim_y; - - /*Final pivot offset = scale_factor * rotation_pivot_offset + scaling_pivot_offset*/ - piv_offset_x = floor(fp_scale_x * piv_offset_x) - floor((fp_scale_x - 1) * pivot.x); - piv_offset_y = floor(fp_scale_y * piv_offset_y) - floor((fp_scale_y - 1) * pivot.y); + int32_t stride = draw_buf->header.stride / (lv_color_format_get_bpp(draw_buf->header.cf) / 8); + lv_color_format_t cf = draw_buf->header.cf; + uint32_t width = draw_buf->header.w; + uint32_t height = draw_buf->header.h; + + int32_t blend_w = lv_area_get_width(area); + int32_t blend_h = lv_area_get_height(area); dst_surf->format = g2d_get_buf_format(cf); - dst_surf->left = area->x1 + piv_offset_x; - dst_surf->top = area->y1 + piv_offset_y; - dst_surf->right = area->x1 + piv_offset_x + dest_w - trim_x; - dst_surf->bottom = area->y1 + piv_offset_y + dest_h - trim_y; + dst_surf->left = area->x1; + dst_surf->top = area->y1; + dst_surf->right = area->x1 + blend_w; + dst_surf->bottom = area->y1 + blend_h; dst_surf->stride = stride; - dst_surf->width = dest_w - trim_x; - dst_surf->height = dest_h - trim_y; + dst_surf->width = width; + dst_surf->height = height; dst_surf->planes[0] = buf->buf_paddr; dst_surf->rot = G2D_ROTATION_0; @@ -202,13 +273,40 @@ static void _g2d_set_dst_surf(struct g2d_surface * dst_surf, struct g2d_buf * bu dst_surf->blendfunc = G2D_ONE_MINUS_SRC_ALPHA | G2D_PRE_MULTIPLIED_ALPHA; } -static void _g2d_blit(void * g2d_handle, struct g2d_surface * dst_surf, struct g2d_surface * src_surf) +static void _g2d_blit(void * handle, struct g2d_surface * dst_surf, struct g2d_surface * src_surf) +{ + g2d_enable(handle, G2D_BLEND); + g2d_enable(handle, G2D_GLOBAL_ALPHA); + g2d_blit(handle, src_surf, dst_surf); + g2d_finish(handle); + g2d_disable(handle, G2D_GLOBAL_ALPHA); + g2d_disable(handle, G2D_BLEND); +} + +static void _g2d_blit_two_steps(void * handle, struct g2d_surface * dst_surf, struct g2d_surface * src_surf, + struct g2d_surface * tmp_surf) { - g2d_enable(g2d_handle, G2D_BLEND); - g2d_enable(g2d_handle, G2D_GLOBAL_ALPHA); - g2d_blit(g2d_handle, src_surf, dst_surf); - g2d_finish(g2d_handle); - g2d_disable(g2d_handle, G2D_GLOBAL_ALPHA); - g2d_disable(g2d_handle, G2D_BLEND); + g2d_clear(handle, tmp_surf); + + g2d_enable(handle, G2D_BLEND); + g2d_enable(handle, G2D_GLOBAL_ALPHA); + g2d_blit(handle, src_surf, tmp_surf); + g2d_finish(handle); + g2d_disable(handle, G2D_GLOBAL_ALPHA); + g2d_disable(handle, G2D_BLEND); + + /**After first blit, change blending and global alpha for temporary surface + * since the surface now acts as source. + */ + tmp_surf->blendfunc = G2D_ONE | G2D_PRE_MULTIPLIED_ALPHA; + tmp_surf->global_alpha = 0xFF; + + g2d_enable(handle, G2D_BLEND); + g2d_enable(handle, G2D_GLOBAL_ALPHA); + g2d_blit(handle, tmp_surf, dst_surf); + g2d_finish(handle); + g2d_disable(handle, G2D_GLOBAL_ALPHA); + g2d_disable(handle, G2D_BLEND); } -#endif /*LV_USE_DRAW_G2D*/ \ No newline at end of file +#endif /*LV_USE_DRAW_G2D*/ +#endif /*LV_USE_G2D*/ diff --git a/src/draw/nxp/g2d/lv_g2d_buf_map.c b/src/draw/nxp/g2d/lv_g2d_buf_map.c index 00de516f6c..9a26a718bd 100644 --- a/src/draw/nxp/g2d/lv_g2d_buf_map.c +++ b/src/draw/nxp/g2d/lv_g2d_buf_map.c @@ -11,7 +11,8 @@ #include "lv_g2d_buf_map.h" -#if LV_USE_DRAW_G2D +#if LV_USE_G2D +#if LV_USE_DRAW_G2D || LV_USE_ROTATE_G2D #include #include "lv_g2d_utils.h" #include "g2d.h" @@ -36,6 +37,8 @@ static void _map_free_item(lv_map_item_t * item); static void _handle_collision(unsigned long index, lv_map_item_t * item); +static void _map_free_list(unsigned long index, lv_array_t * list); + /********************** * STATIC VARIABLES **********************/ @@ -82,14 +85,18 @@ void g2d_insert_buf_map(void * key, struct g2d_buf * value) lv_map_item_t * item = _map_create_item(key, value); int index = _map_hash_function(key); + if(table->count == table->size) { + /* Table is full. */ + _map_free_item(item); + G2D_ASSERT_MSG(false, "Hash table is full. Increase LV_G2D_HASH_TABLE_SIZE."); + return; + } + if(table->items[index] == NULL) { - /* Key not found. */ - if(table->count == table->size) { - /* Table is full. */ - _map_free_item(item); - G2D_ASSERT_MSG(false, "Hash table is full."); - return; - } + /* Key not found. Insert item. */ + table->items[index] = item; + table->count++; + return; } else { if(table->items[index]->key == key) { @@ -104,9 +111,6 @@ void g2d_insert_buf_map(void * key, struct g2d_buf * value) } } - /* Insert item. */ - table->items[index] = item; - table->count++; } struct g2d_buf * g2d_search_buf_map(void * key) @@ -140,22 +144,43 @@ void g2d_free_item(void * key) lv_map_item_t * item = table->items[index]; lv_array_t * list = (lv_array_t *)table->overflow_list[index]; + /* If there is no item, then nothing to do. */ if(item == NULL) { return; } - else if(list == NULL && item->key == key) { - /* No collision chain, just remove item. */ + else if(item->key == key) { + /* Remove the item. */ table->items[index] = NULL; _map_free_item(item); table->count--; + + /* If there is no collision chain, just return. */ + if(list == NULL) { + return; + } + + /* If a collision chain exists, promote the first item. */ + lv_map_item_t * promoted_item = (lv_map_item_t *)lv_array_at(list, 0); + table->items[index] = _map_create_item(promoted_item->key, promoted_item->value); + lv_array_remove(list, 0); + if(lv_array_size(list) == 0) { + _map_free_list(index, list); + } return; } - else if(list != NULL) { - /* Collision chain exists. */ + /* If the item is not the one we are searching, and there is no list, then return. */ + if(list == NULL) return; + else { + /* The item might be inside the list. */ for(uint32_t i = 0; i < lv_array_size(list); i++) { item = (lv_map_item_t *)lv_array_at(list, i); if(item->key == key) { + g2d_free(item->value); lv_array_remove(list, i); + table->count--; + if(lv_array_size(list) == 0) { + _map_free_list(index, list); + } return; } } @@ -203,10 +228,11 @@ static void _handle_collision(unsigned long index, lv_map_item_t * item) { if(table->overflow_list[index] == NULL) { /* Create the list. */ - lv_array_t * list = (lv_array_t *) lv_malloc(sizeof(lv_array_t));; + lv_array_t * list = (lv_array_t *) lv_malloc(sizeof(lv_array_t)); lv_array_init(list, LV_ARRAY_DEFAULT_CAPACITY, sizeof(lv_map_item_t)); lv_array_push_back(list, item); table->overflow_list[index] = list; + table->count++; return; } else { @@ -221,6 +247,7 @@ static void _handle_collision(unsigned long index, lv_map_item_t * item) } /* Insert to the list. */ lv_array_push_back(table->overflow_list[index], item); + table->count++; return; } } @@ -244,4 +271,12 @@ static void _map_free_item(lv_map_item_t * item) item = NULL; } -#endif /*LV_USE_DRAW_G2D*/ +static void _map_free_list(unsigned long index, lv_array_t * list) +{ + lv_array_deinit(list); + lv_free(list); + table->overflow_list[index] = NULL; +} + +#endif /*LV_USE_DRAW_G2D || LV_USE_ROTATE_G2D*/ +#endif /*LV_USE_G2D*/ diff --git a/src/draw/nxp/g2d/lv_g2d_buf_map.h b/src/draw/nxp/g2d/lv_g2d_buf_map.h index 6e2196d30d..c1d1f86343 100644 --- a/src/draw/nxp/g2d/lv_g2d_buf_map.h +++ b/src/draw/nxp/g2d/lv_g2d_buf_map.h @@ -23,7 +23,8 @@ extern "C" { #include "../../../lv_conf_internal.h" -#if LV_USE_DRAW_G2D +#if LV_USE_G2D +#if LV_USE_DRAW_G2D || LV_USE_ROTATE_G2D #include "../../../misc/lv_array.h" #include @@ -72,7 +73,8 @@ void g2d_print_table(void); * MACROS **********************/ -#endif /*LV_USE_DRAW_G2D*/ +#endif /*LV_USE_DRAW_G2D || LV_USE_ROTATE_G2D*/ +#endif /*LV_USE_G2D*/ #ifdef __cplusplus } /*extern "C"*/ diff --git a/src/draw/nxp/g2d/lv_g2d_utils.c b/src/draw/nxp/g2d/lv_g2d_utils.c index c353040d23..81ef9a5449 100644 --- a/src/draw/nxp/g2d/lv_g2d_utils.c +++ b/src/draw/nxp/g2d/lv_g2d_utils.c @@ -15,7 +15,8 @@ #include "lv_g2d_utils.h" -#if LV_USE_DRAW_G2D +#if LV_USE_G2D +#if LV_USE_DRAW_G2D || LV_USE_ROTATE_G2D #include "lv_g2d_buf_map.h" #include "lv_draw_g2d.h" @@ -30,7 +31,7 @@ /********************** * STATIC PROTOTYPES **********************/ - +static void * g2d_handle; /********************** * MACROS **********************/ @@ -90,8 +91,88 @@ int32_t g2d_get_buf_fd(const lv_draw_buf_t * draw_buf) return g2d_buf_export_fd(buf); } +void g2d_set_handle(void * handle) +{ + g2d_handle = handle; +} +void * g2d_get_handle(void) +{ + return g2d_handle; +} + +#if LV_USE_ROTATE_G2D +void g2d_rotate(lv_draw_buf_t * buf1, lv_draw_buf_t * buf2, int32_t width, int32_t height, uint32_t rotation, + lv_color_format_t cf) +{ + struct g2d_surface src_surf, dst_surf; + struct g2d_buf * src_buf = g2d_search_buf_map(buf1->data); + struct g2d_buf * dst_buf = g2d_search_buf_map(buf2->data); + bool has_rotation = (rotation != 0); + + int32_t src_width = width; + int32_t src_height = height; + if(has_rotation) { + if(rotation == LV_DISPLAY_ROTATION_90 || rotation == LV_DISPLAY_ROTATION_270) { + src_width = height; + src_height = width; + } + } + + src_surf.format = g2d_get_buf_format(cf); + + src_surf.left = 0; + src_surf.top = 0; + src_surf.right = src_width; + src_surf.bottom = src_height; + src_surf.stride = src_width; + src_surf.width = src_width; + src_surf.height = src_height; + + src_surf.planes[0] = src_buf->buf_paddr; + src_surf.rot = G2D_ROTATION_0; + + enum g2d_rotation g2d_angle = G2D_ROTATION_0; + if(has_rotation) { + switch(rotation) { + case LV_DISPLAY_ROTATION_0: + g2d_angle = G2D_ROTATION_0; + break; + case LV_DISPLAY_ROTATION_90: + g2d_angle = G2D_ROTATION_90; + break; + case LV_DISPLAY_ROTATION_180: + g2d_angle = G2D_ROTATION_180; + break; + case LV_DISPLAY_ROTATION_270: + g2d_angle = G2D_ROTATION_270; + break; + default: + g2d_angle = G2D_ROTATION_0; + } + } + + dst_surf.format = g2d_get_buf_format(cf); + + dst_surf.left = 0; + dst_surf.top = 0; + dst_surf.right = width; + dst_surf.bottom = height; + dst_surf.stride = width; + dst_surf.width = width; + dst_surf.height = height; + + dst_surf.planes[0] = dst_buf->buf_paddr; + dst_surf.rot = g2d_angle; + + void * handle = g2d_get_handle(); + g2d_blit(handle, &src_surf, &dst_surf); + g2d_finish(handle); +} +#endif + /********************** * STATIC FUNCTIONS **********************/ -#endif /*LV_USE_DRAW_G2D*/ \ No newline at end of file +#endif /*LV_USE_DRAW_G2D || LV_USE_ROTATE_G2D*/ +#endif /*LV_USE_G2D*/ diff --git a/src/draw/nxp/g2d/lv_g2d_utils.h b/src/draw/nxp/g2d/lv_g2d_utils.h index f3923e1503..af23b27dfd 100644 --- a/src/draw/nxp/g2d/lv_g2d_utils.h +++ b/src/draw/nxp/g2d/lv_g2d_utils.h @@ -21,7 +21,8 @@ extern "C" { *********************/ #include "../../../lv_conf_internal.h" -#if LV_USE_DRAW_G2D +#if LV_USE_G2D +#if LV_USE_DRAW_G2D || LV_USE_ROTATE_G2D #include "../../sw/lv_draw_sw_private.h" #include "g2d.h" #include "g2dExt.h" @@ -59,11 +60,21 @@ g2d_format_t g2d_get_buf_format(lv_color_format_t cf); uint32_t g2d_rgba_to_u32(lv_color_t color); int32_t g2d_get_buf_fd(const lv_draw_buf_t * draw_buf); + +void g2d_set_handle(void * handle); + +void * g2d_get_handle(void); + +#if LV_USE_ROTATE_G2D +void g2d_rotate(lv_draw_buf_t * buf1, lv_draw_buf_t * buf2, int32_t width, int32_t height, uint32_t rotation, + lv_color_format_t cf); +#endif /********************** * MACROS **********************/ -#endif /*LV_USE_DRAW_G2D*/ +#endif /*LV_USE_DRAW_G2D || LV_USE_ROTATE_G2D*/ +#endif /*LV_USE_G2D*/ #ifdef __cplusplus } /*extern "C"*/ diff --git a/src/draw/nxp/pxp/lv_draw_buf_pxp.c b/src/draw/nxp/pxp/lv_draw_buf_pxp.c index 9819cfc641..11600053cf 100644 --- a/src/draw/nxp/pxp/lv_draw_buf_pxp.c +++ b/src/draw/nxp/pxp/lv_draw_buf_pxp.c @@ -79,8 +79,8 @@ static void _invalidate_cache(const lv_draw_buf_t * draw_buf, const lv_area_t * } const uint8_t * buf_u8 = draw_buf->data; - /* ARM require a 32 byte aligned address. */ - uint8_t align_bytes = 32; + /*Cache management requires us to know the cache line size for proper alignment */ + uint8_t align_bytes = __SCB_DCACHE_LINE_SIZE; uint8_t bits_per_pixel = lv_color_format_get_bpp(cf); uint16_t align_pixels = align_bytes * 8 / bits_per_pixel; diff --git a/src/draw/nxp/pxp/lv_draw_pxp.c b/src/draw/nxp/pxp/lv_draw_pxp.c index 6bcbe82ac3..5ab12ce7a3 100644 --- a/src/draw/nxp/pxp/lv_draw_pxp.c +++ b/src/draw/nxp/pxp/lv_draw_pxp.c @@ -210,11 +210,6 @@ static bool _pxp_draw_img_supported(const lv_draw_image_dsc_t * draw_dsc) { const lv_image_dsc_t * img_dsc = draw_dsc->src; - bool is_tiled = draw_dsc->tile; - /* Tiled image (repeat image) is currently not supported. */ - if(is_tiled) - return false; - bool has_recolor = (draw_dsc->recolor_opa > LV_OPA_MIN); bool has_transform = (draw_dsc->rotation != 0 || draw_dsc->scale_x != LV_SCALE_NONE || draw_dsc->scale_y != LV_SCALE_NONE); @@ -350,7 +345,7 @@ static int32_t _pxp_dispatch(lv_draw_unit_t * draw_unit, lv_layer_t * layer) #else _pxp_execute_drawing(draw_pxp_unit); - draw_pxp_unit->task_act->state = LV_DRAW_TASK_STATE_READY; + draw_pxp_unit->task_act->state = LV_DRAW_TASK_STATE_FINISHED; draw_pxp_unit->task_act = NULL; /* The draw unit is free now. Request a new dispatching as it can get a new task. */ @@ -434,7 +429,7 @@ static void _pxp_execute_drawing(lv_draw_pxp_unit_t * u) lv_draw_sw_fill((lv_draw_unit_t *)u, &rect_dsc, &draw_area); lv_point_t txt_size; - lv_text_get_size(&txt_size, "W", LV_FONT_DEFAULT, 0, 0, 100, LV_TEXT_FLAG_NONE); + lv_text_get_size_attributes(&txt_size, "W", LV_FONT_DEFAULT, 0, 0, 100, LV_TEXT_FLAG_NONE); lv_area_t txt_area; txt_area.x1 = draw_area.x1; @@ -482,7 +477,7 @@ static void _pxp_render_thread_cb(void * ptr) _pxp_execute_drawing(u); /* Signal the ready state to dispatcher. */ - u->task_act->state = LV_DRAW_TASK_STATE_READY; + u->task_act->state = LV_DRAW_TASK_STATE_FINISHED; /* Cleanup. */ u->task_act = NULL; diff --git a/src/draw/nxp/pxp/lv_draw_pxp.h b/src/draw/nxp/pxp/lv_draw_pxp.h index 38b7e3ca7a..a6833b585f 100644 --- a/src/draw/nxp/pxp/lv_draw_pxp.h +++ b/src/draw/nxp/pxp/lv_draw_pxp.h @@ -36,7 +36,7 @@ extern "C" { * TYPEDEFS **********************/ -typedef struct lv_draw_pxp_unit_t { +typedef struct _lv_draw_pxp_unit_t { lv_draw_unit_t base_unit; lv_draw_task_t * task_act; #if LV_USE_OS diff --git a/src/draw/nxp/pxp/lv_draw_pxp_img.c b/src/draw/nxp/pxp/lv_draw_pxp_img.c index 320eaed2e7..2d1afccf2c 100644 --- a/src/draw/nxp/pxp/lv_draw_pxp_img.c +++ b/src/draw/nxp/pxp/lv_draw_pxp_img.c @@ -19,6 +19,8 @@ #if LV_USE_DRAW_PXP #include "lv_pxp_cfg.h" #include "lv_pxp_utils.h" +#include "../../lv_draw_image_private.h" +#include "../../lv_image_decoder_private.h" #include @@ -33,6 +35,9 @@ /********************** * STATIC PROTOTYPES **********************/ +static void _pxp_draw_core_cb(lv_draw_task_t * t, const lv_draw_image_dsc_t * draw_dsc, + const lv_image_decoder_dsc_t * decoder_dsc, lv_draw_image_sup_t * sup, + const lv_area_t * img_coords, const lv_area_t * clipped_img_area); /* Blit w/ recolor for images w/o opa and alpha channel */ static void _pxp_blit_recolor(uint8_t * dest_buf, const lv_area_t * dest_area, int32_t dest_stride, @@ -69,55 +74,59 @@ void lv_draw_pxp_img(lv_draw_task_t * t) if(dsc->opa <= (lv_opa_t)LV_OPA_MIN) return; + bool is_tiled = (dsc->tile != 0); + if(is_tiled) + lv_draw_image_tiled_helper(t, dsc, coords, _pxp_draw_core_cb); + else + lv_draw_image_normal_helper(t, dsc, coords, _pxp_draw_core_cb); +} + +/********************** + * STATIC FUNCTIONS + **********************/ +static void _pxp_draw_core_cb(lv_draw_task_t * t, const lv_draw_image_dsc_t * draw_dsc, + const lv_image_decoder_dsc_t * decoder_dsc, lv_draw_image_sup_t * sup, + const lv_area_t * img_coords, const lv_area_t * clipped_img_area) +{ lv_layer_t * layer = t->target_layer; lv_draw_buf_t * draw_buf = layer->draw_buf; - const lv_image_dsc_t * img_dsc = dsc->src; - - lv_area_t rel_coords; - lv_area_copy(&rel_coords, coords); - lv_area_move(&rel_coords, -layer->buf_area.x1, -layer->buf_area.y1); + const lv_draw_buf_t * decoded = decoder_dsc->decoded; lv_area_t rel_clip_area; - lv_area_copy(&rel_clip_area, &t->clip_area); - lv_area_move(&rel_clip_area, -layer->buf_area.x1, -layer->buf_area.y1); + lv_area_copy(&rel_clip_area, clipped_img_area); + lv_area_move(&rel_clip_area, -img_coords->x1, -img_coords->y1); - lv_area_t blend_area; - bool has_transform = (dsc->rotation != 0 || dsc->scale_x != LV_SCALE_NONE || dsc->scale_y != LV_SCALE_NONE); - if(has_transform) - lv_area_copy(&blend_area, &rel_coords); - else if(!lv_area_intersect(&blend_area, &rel_coords, &rel_clip_area)) - return; /*Fully clipped, nothing to do*/ + lv_area_t rel_img_coords; + lv_area_copy(&rel_img_coords, img_coords); + lv_area_move(&rel_img_coords, -img_coords->x1, -img_coords->y1); - const uint8_t * src_buf = img_dsc->data; + const uint8_t * src_buf = decoded->data; lv_area_t src_area; - src_area.x1 = blend_area.x1 - (coords->x1 - layer->buf_area.x1); - src_area.y1 = blend_area.y1 - (coords->y1 - layer->buf_area.y1); - src_area.x2 = src_area.x1 + lv_area_get_width(&blend_area) - 1; - src_area.y2 = src_area.y1 + lv_area_get_height(&blend_area) - 1; - int32_t src_stride = img_dsc->header.stride; - lv_color_format_t src_cf = img_dsc->header.cf; + if(!lv_area_intersect(&src_area, &rel_clip_area, &rel_img_coords)) + return; + + int32_t src_stride = draw_dsc->header.stride; + lv_color_format_t src_cf = draw_dsc->header.cf; uint8_t * dest_buf = draw_buf->data; int32_t dest_stride = draw_buf->header.stride; lv_color_format_t dest_cf = draw_buf->header.cf; - bool has_recolor = (dsc->recolor_opa > LV_OPA_MIN); + bool has_recolor = (draw_dsc->recolor_opa > LV_OPA_MIN); + bool has_transform = (draw_dsc->rotation != 0 || draw_dsc->scale_x != LV_SCALE_NONE || + draw_dsc->scale_y != LV_SCALE_NONE); if(has_recolor && !has_transform) - _pxp_blit_recolor(dest_buf, &blend_area, dest_stride, dest_cf, - src_buf, &src_area, src_stride, src_cf, dsc); + _pxp_blit_recolor(dest_buf, clipped_img_area, dest_stride, dest_cf, + src_buf, &src_area, src_stride, src_cf, draw_dsc); else if(has_transform) - _pxp_blit_transform(dest_buf, &blend_area, dest_stride, dest_cf, - src_buf, &src_area, src_stride, src_cf, dsc); + _pxp_blit_transform(dest_buf, clipped_img_area, dest_stride, dest_cf, + src_buf, &src_area, src_stride, src_cf, draw_dsc); else - _pxp_blit(dest_buf, &blend_area, dest_stride, dest_cf, - src_buf, &src_area, src_stride, src_cf, dsc->opa); + _pxp_blit(dest_buf, clipped_img_area, dest_stride, dest_cf, + src_buf, &src_area, src_stride, src_cf, draw_dsc->opa); } -/********************** - * STATIC FUNCTIONS - **********************/ - static void _pxp_blit_recolor(uint8_t * dest_buf, const lv_area_t * dest_area, int32_t dest_stride, lv_color_format_t dest_cf, const uint8_t * src_buf, const lv_area_t * src_area, int32_t src_stride, lv_color_format_t src_cf, const lv_draw_image_dsc_t * dsc) @@ -193,14 +202,6 @@ static void _pxp_blit_transform(uint8_t * dest_buf, const lv_area_t * dest_area, int32_t dest_w = lv_area_get_width(dest_area); int32_t dest_h = lv_area_get_height(dest_area); - lv_point_t pivot = dsc->pivot; - /*The offsets are now relative to the transformation result with pivot ULC*/ - int32_t piv_offset_x = 0; - int32_t piv_offset_y = 0; - - int32_t trim_x = 0; - int32_t trim_y = 0; - bool has_rotation = (dsc->rotation != 0); bool has_scale = (dsc->scale_x != LV_SCALE_NONE || dsc->scale_y != LV_SCALE_NONE); uint8_t src_px_size = lv_color_format_get_size(src_cf); @@ -214,51 +215,23 @@ static void _pxp_blit_transform(uint8_t * dest_buf, const lv_area_t * dest_area, switch(dsc->rotation) { case 0: pxp_angle = kPXP_Rotate0; - piv_offset_x = 0; - piv_offset_y = 0; break; case 900: pxp_angle = kPXP_Rotate90; - piv_offset_x = pivot.x + pivot.y - src_h; - piv_offset_y = pivot.y - pivot.x; break; case 1800: pxp_angle = kPXP_Rotate180; - piv_offset_x = 2 * pivot.x - src_w; - piv_offset_y = 2 * pivot.y - src_h; break; case 2700: pxp_angle = kPXP_Rotate270; - piv_offset_x = pivot.x - pivot.y; - piv_offset_y = pivot.x + pivot.y - src_w; break; default: pxp_angle = kPXP_Rotate0; - piv_offset_x = 0; - piv_offset_y = 0; } /*PS buffer rotation and decimation does not function at the same time*/ PXP_SetRotateConfig(PXP_ID, kPXP_RotateOutputBuffer, pxp_angle, kPXP_FlipDisable); } - if(has_scale) { - float fp_scale_x = (float)dsc->scale_x / LV_SCALE_NONE; - float fp_scale_y = (float)dsc->scale_y / LV_SCALE_NONE; - int32_t int_scale_x = (int32_t)fp_scale_x; - int32_t int_scale_y = (int32_t)fp_scale_y; - - /*Any scale_factor in (k, k + 1] will result in a trim equal to k*/ - trim_x = (fp_scale_x == int_scale_x) ? int_scale_x - 1 : int_scale_x; - trim_y = (fp_scale_y == int_scale_y) ? int_scale_y - 1 : int_scale_y; - - dest_w = src_w * fp_scale_x + trim_x; - dest_h = src_h * fp_scale_y + trim_y; - - /*Final pivot offset = scale_factor * rotation_pivot_offset + scaling_pivot_offset*/ - piv_offset_x = floorf(fp_scale_x * piv_offset_x) - floorf((fp_scale_x - 1) * pivot.x); - piv_offset_y = floorf(fp_scale_y * piv_offset_y) - floorf((fp_scale_y - 1) * pivot.y); - } - /*PS buffer - source image*/ pxp_ps_buffer_config_t psBufferConfig = { .pixelFormat = pxp_get_ps_px_format(src_cf), @@ -269,7 +242,7 @@ static void _pxp_blit_transform(uint8_t * dest_buf, const lv_area_t * dest_area, .pitchBytes = src_stride }; PXP_SetProcessSurfaceBufferConfig(PXP_ID, &psBufferConfig); - PXP_SetProcessSurfacePosition(PXP_ID, 0U, 0U, dest_w - trim_x - 1U, dest_h - trim_y - 1U); + PXP_SetProcessSurfacePosition(PXP_ID, 0U, 0U, dest_w - 1U, dest_h - 1U); if(has_scale) PXP_SetProcessSurfaceScaler(PXP_ID, src_w, src_h, dest_w, dest_h); @@ -281,11 +254,11 @@ static void _pxp_blit_transform(uint8_t * dest_buf, const lv_area_t * dest_area, pxp_output_buffer_config_t outputBufferConfig = { .pixelFormat = pxp_get_out_px_format(dest_cf), .interlacedMode = kPXP_OutputProgressive, - .buffer0Addr = (uint32_t)(dest_buf + dest_stride * (dest_area->y1 + piv_offset_y) + dest_px_size * (dest_area->x1 + piv_offset_x)), + .buffer0Addr = (uint32_t)(dest_buf + dest_stride * (dest_area->y1) + dest_px_size * (dest_area->x1)), .buffer1Addr = (uint32_t)0U, .pitchBytes = dest_stride, - .width = dest_w - trim_x, - .height = dest_h - trim_y + .width = dest_w, + .height = dest_h }; PXP_SetOutputBufferConfig(PXP_ID, &outputBufferConfig); diff --git a/src/draw/nxp/pxp/lv_draw_pxp_layer.c b/src/draw/nxp/pxp/lv_draw_pxp_layer.c index f515a20b50..2a153d6fee 100644 --- a/src/draw/nxp/pxp/lv_draw_pxp_layer.c +++ b/src/draw/nxp/pxp/lv_draw_pxp_layer.c @@ -131,7 +131,7 @@ void lv_draw_pxp_layer(lv_draw_task_t * t) lv_draw_sw_border(t, &border_dsc, &area_rot); lv_point_t txt_size; - lv_text_get_size(&txt_size, "W", LV_FONT_DEFAULT, 0, 0, 100, LV_TEXT_FLAG_NONE); + lv_text_get_size_attributes(&txt_size, "W", LV_FONT_DEFAULT, 0, 0, 100, LV_TEXT_FLAG_NONE); lv_area_t txt_area; txt_area.x1 = draw_area.x1; diff --git a/src/draw/nxp/pxp/lv_pxp_cfg.h b/src/draw/nxp/pxp/lv_pxp_cfg.h index 67d1358576..34dccbb2f8 100644 --- a/src/draw/nxp/pxp/lv_pxp_cfg.h +++ b/src/draw/nxp/pxp/lv_pxp_cfg.h @@ -27,6 +27,10 @@ extern "C" { #include "fsl_cache.h" #include "fsl_pxp.h" +#if ((LV_DRAW_BUF_ALIGN % 32) != 0) +#error "If PXP is enabled the draw buffers should be aligned to 32-byte boundary, please set LV_DRAW_BUF_ALIGN to a multiple of 32 in lv_conf.h" +#endif + #include "../../../misc/lv_log.h" /********************* diff --git a/src/draw/nxp/pxp/lv_pxp_osa.c b/src/draw/nxp/pxp/lv_pxp_osa.c index 43dd8155b6..861369dc32 100644 --- a/src/draw/nxp/pxp/lv_pxp_osa.c +++ b/src/draw/nxp/pxp/lv_pxp_osa.c @@ -19,7 +19,7 @@ #if LV_USE_DRAW_PXP || LV_USE_ROTATE_PXP #include "lv_pxp_utils.h" #include "../../../misc/lv_log.h" -#include "../../../osal/lv_os.h" +#include "../../../osal/lv_os_private.h" #include "fsl_pxp.h" #if defined(SDK_OS_FREE_RTOS) diff --git a/src/draw/nxp/vglite/lv_draw_buf_vglite.c b/src/draw/nxp/vglite/lv_draw_buf_vglite.c deleted file mode 100644 index f42bf6fb14..0000000000 --- a/src/draw/nxp/vglite/lv_draw_buf_vglite.c +++ /dev/null @@ -1,131 +0,0 @@ -/** - * @file lv_draw_buf_vglite.c - * - */ - -/** - * Copyright 2023-2024 NXP - * - * SPDX-License-Identifier: MIT - */ - -/********************* - * INCLUDES - *********************/ - -#include "lv_draw_vglite.h" - -#if LV_USE_DRAW_VGLITE -#include "../../lv_draw_buf_private.h" -#include "lv_vglite_buf.h" -#include "lv_vglite_utils.h" - -#include "lvgl_support.h" - -/********************* - * DEFINES - *********************/ - -/********************** - * TYPEDEFS - **********************/ - -/********************** - * STATIC PROTOTYPES - **********************/ - -static void _invalidate_cache(const lv_draw_buf_t * draw_buf, const lv_area_t * area); -static uint32_t _width_to_stride(uint32_t w, lv_color_format_t cf); - -/********************** - * STATIC VARIABLES - **********************/ - -/********************** - * MACROS - **********************/ - -/********************** - * GLOBAL FUNCTIONS - **********************/ - -void lv_draw_buf_vglite_init_handlers(void) -{ - lv_draw_buf_handlers_t * handlers = lv_draw_buf_get_handlers(); - lv_draw_buf_handlers_t * font_handlers = lv_draw_buf_get_font_handlers(); - lv_draw_buf_handlers_t * image_handlers = lv_draw_buf_get_image_handlers(); - - handlers->invalidate_cache_cb = _invalidate_cache; - font_handlers->invalidate_cache_cb = _invalidate_cache; - image_handlers->invalidate_cache_cb = _invalidate_cache; - - handlers->width_to_stride_cb = _width_to_stride; - font_handlers->width_to_stride_cb = _width_to_stride; - image_handlers->width_to_stride_cb = _width_to_stride; - -} - -/********************** - * STATIC FUNCTIONS - **********************/ - -static void _invalidate_cache(const lv_draw_buf_t * draw_buf, const lv_area_t * area) -{ - const lv_image_header_t * header = &draw_buf->header; - uint32_t stride = header->stride; - lv_color_format_t cf = header->cf; - - if(area->y1 == 0) { - uint32_t size = stride * lv_area_get_height(area); - - /* Invalidate full buffer. */ - DEMO_CleanInvalidateCacheByAddr((void *)draw_buf->data, size); - return; - } - - const uint8_t * buf_u8 = draw_buf->data; - /* ARM require a 32 byte aligned address. */ - uint8_t align_bytes = 32; - uint8_t bits_per_pixel = lv_color_format_get_bpp(cf); - - uint16_t align_pixels = align_bytes * 8 / bits_per_pixel; - uint16_t offset_x = 0; - - if(area->x1 >= (int32_t)(area->x1 % align_pixels)) { - uint16_t shift_x = area->x1 - (area->x1 % align_pixels); - - offset_x = area->x1 - shift_x; - buf_u8 += (shift_x * bits_per_pixel) / 8; - } - - if(area->y1) { - uint16_t shift_y = area->y1; - - buf_u8 += shift_y * stride; - } - - /* Area to clear can start from a different offset in buffer. - * Invalidate the area line by line. - */ - uint16_t line_pixels = offset_x + lv_area_get_width(area); - uint16_t line_size = (line_pixels * bits_per_pixel) / 8; - uint16_t area_height = lv_area_get_height(area); - - for(uint16_t y = 0; y < area_height; y++) { - const void * line_addr = buf_u8 + y * stride; - - DEMO_CleanInvalidateCacheByAddr((void *)line_addr, line_size); - } -} - -static uint32_t _width_to_stride(uint32_t w, lv_color_format_t cf) -{ - uint8_t bits_per_pixel = lv_color_format_get_bpp(cf); - uint32_t width_bits = LV_ROUND_UP(w * bits_per_pixel, 8); - uint32_t width_bytes = width_bits / 8; - uint8_t align_bytes = vglite_get_stride_alignment(cf); - - return LV_ROUND_UP(width_bytes, align_bytes); -} - -#endif /*LV_USE_DRAW_VGLITE*/ diff --git a/src/draw/nxp/vglite/lv_draw_vglite.c b/src/draw/nxp/vglite/lv_draw_vglite.c deleted file mode 100644 index 55f7112137..0000000000 --- a/src/draw/nxp/vglite/lv_draw_vglite.c +++ /dev/null @@ -1,638 +0,0 @@ -/** - * @file lv_draw_vglite.c - * - */ - -/** - * Copyright 2023-2024 NXP - * - * SPDX-License-Identifier: MIT - */ - -/********************* - * INCLUDES - *********************/ - -#include "lv_draw_vglite.h" - -#if LV_USE_DRAW_VGLITE -#include "lv_vglite_buf.h" -#include "lv_vglite_utils.h" - -#include "../../../core/lv_global.h" - -/********************* - * DEFINES - *********************/ - -#define DRAW_UNIT_ID_VGLITE 2 - -#if LV_USE_VGLITE_DRAW_ASYNC - #define VGLITE_TASK_BUF_SIZE 100 -#endif - -/********************** - * TYPEDEFS - **********************/ - -#if LV_USE_VGLITE_DRAW_ASYNC -/** - * Structure of pending vglite draw task - */ -typedef struct _vglite_flush_task { - vglite_draw_task_t * task; - bool flushed; -} vglite_flush_task_t; -#endif - -/********************** - * STATIC PROTOTYPES - **********************/ - -static inline void _vglite_cleanup_task(vglite_draw_task_t * task); - -/* - * Evaluate a task and set the score and preferred VGLite draw unit. - * Return 1 if task is preferred, 0 otherwise (task is not supported). - */ -static int32_t _vglite_evaluate(lv_draw_unit_t * draw_unit, lv_draw_task_t * task); - -/* - * Dispatch (assign) a task to VGLite draw unit (itself). - * Return 1 if task was dispatched, 0 otherwise (task not supported). - */ -static int32_t _vglite_dispatch(lv_draw_unit_t * draw_unit, lv_layer_t * layer); - -/* - * Wait for VG-Lite draw unit to finish. - */ -#if LV_USE_VGLITE_DRAW_ASYNC - static int32_t _vglite_wait_for_finish(lv_draw_unit_t * draw_unit); -#endif - -/* - * Delete the VGLite draw unit. - */ -static int32_t _vglite_delete(lv_draw_unit_t * draw_unit); - -#if LV_USE_VGLITE_DRAW_THREAD - static void _vglite_render_thread_cb(void * ptr); -#endif - -static void _vglite_execute_drawing(lv_draw_vglite_unit_t * u); - -/********************** - * STATIC VARIABLES - **********************/ - -#define _draw_info LV_GLOBAL_DEFAULT()->draw_info - -#if LV_USE_VGLITE_DRAW_ASYNC - /* - * Circular buffer to hold the queued and the flushed tasks. - * Two indexes, _head and _tail, are used to signal the beginning - * and the end of the valid tasks that are pending. - */ - static vglite_flush_task_t _draw_task_buf[VGLITE_TASK_BUF_SIZE]; - static volatile int _head = 0; - static volatile int _tail = 0; -#endif - -/********************** - * MACROS - **********************/ - -/********************** - * GLOBAL FUNCTIONS - **********************/ - -void lv_draw_vglite_init(void) -{ - lv_draw_buf_vglite_init_handlers(); - - lv_draw_vglite_unit_t * draw_vglite_unit = lv_draw_create_unit(sizeof(lv_draw_vglite_unit_t)); - draw_vglite_unit->base_unit.evaluate_cb = _vglite_evaluate; - draw_vglite_unit->base_unit.dispatch_cb = _vglite_dispatch; -#if LV_USE_VGLITE_DRAW_ASYNC - draw_vglite_unit->base_unit.wait_for_finish_cb = _vglite_wait_for_finish; -#endif - draw_vglite_unit->base_unit.delete_cb = _vglite_delete; - draw_vglite_unit->base_unit.name = "NXP_VGLITE"; - -#if LV_USE_VGLITE_DRAW_THREAD - lv_thread_init(&draw_vglite_unit->thread, "vglitedraw", LV_DRAW_THREAD_PRIO, _vglite_render_thread_cb, 4 * 1024, - draw_vglite_unit); -#endif -} - -void lv_draw_vglite_deinit(void) -{ -} - -/********************** - * STATIC FUNCTIONS - **********************/ - -static inline bool _vglite_src_cf_supported(lv_color_format_t cf) -{ - bool is_cf_supported = false; - - switch(cf) { -#if CHIPID == 0x255 || CHIPID == 0x555 - case LV_COLOR_FORMAT_I1: - case LV_COLOR_FORMAT_I2: - case LV_COLOR_FORMAT_I4: - case LV_COLOR_FORMAT_I8: -#endif - case LV_COLOR_FORMAT_A4: - case LV_COLOR_FORMAT_A8: - case LV_COLOR_FORMAT_L8: - case LV_COLOR_FORMAT_RGB565: -#if CHIPID == 0x555 - case LV_COLOR_FORMAT_ARGB8565: - case LV_COLOR_FORMAT_RGB888: -#endif - case LV_COLOR_FORMAT_ARGB8888: - case LV_COLOR_FORMAT_XRGB8888: - is_cf_supported = true; - break; - default: - break; - } - - return is_cf_supported; -} - -static inline bool _vglite_dest_cf_supported(lv_color_format_t cf) -{ - bool is_cf_supported = false; - - switch(cf) { - case LV_COLOR_FORMAT_A8: -#if CHIPID == 0x255 || CHIPID == 0x555 - case LV_COLOR_FORMAT_L8: -#endif - case LV_COLOR_FORMAT_RGB565: -#if CHIPID == 0x555 - case LV_COLOR_FORMAT_ARGB8565: - case LV_COLOR_FORMAT_RGB888: -#endif - case LV_COLOR_FORMAT_ARGB8888: - case LV_COLOR_FORMAT_XRGB8888: - is_cf_supported = true; - break; - default: - break; - } - - return is_cf_supported; -} - -static int32_t _vglite_evaluate(lv_draw_unit_t * u, lv_draw_task_t * t) -{ - LV_UNUSED(u); - - const lv_draw_dsc_base_t * draw_dsc_base = (lv_draw_dsc_base_t *) t->draw_dsc; - - if(!_vglite_dest_cf_supported(draw_dsc_base->layer->color_format)) - return 0; - - switch(t->type) { - case LV_DRAW_TASK_TYPE_FILL: - if(t->preference_score > 80) { - t->preference_score = 80; - t->preferred_draw_unit_id = DRAW_UNIT_ID_VGLITE; - } - return 1; - - case LV_DRAW_TASK_TYPE_LINE: - case LV_DRAW_TASK_TYPE_ARC: - case LV_DRAW_TASK_TYPE_TRIANGLE: - if(t->preference_score > 90) { - t->preference_score = 90; - t->preferred_draw_unit_id = DRAW_UNIT_ID_VGLITE; - } - return 1; - - case LV_DRAW_TASK_TYPE_LABEL: - if(t->preference_score > 95) { - t->preference_score = 95; - t->preferred_draw_unit_id = DRAW_UNIT_ID_VGLITE; - } - return 1; - - case LV_DRAW_TASK_TYPE_BORDER: { - if(t->preference_score > 90) { - t->preference_score = 90; - t->preferred_draw_unit_id = DRAW_UNIT_ID_VGLITE; - } - return 1; - } - - case LV_DRAW_TASK_TYPE_LAYER: { - const lv_draw_image_dsc_t * draw_dsc = (lv_draw_image_dsc_t *) t->draw_dsc; - lv_layer_t * layer_to_draw = (lv_layer_t *)draw_dsc->src; - -#if LV_USE_VGLITE_BLIT_SPLIT - bool has_transform = (draw_dsc->rotation != 0 || draw_dsc->scale_x != LV_SCALE_NONE || - draw_dsc->scale_y != LV_SCALE_NONE); -#endif - if(!_vglite_src_cf_supported(layer_to_draw->color_format) -#if LV_USE_VGLITE_BLIT_SPLIT - || has_transform -#endif - ) - return 0; - - if(t->preference_score > 80) { - t->preference_score = 80; - t->preferred_draw_unit_id = DRAW_UNIT_ID_VGLITE; - } - return 1; - } - - case LV_DRAW_TASK_TYPE_IMAGE: { - lv_draw_image_dsc_t * draw_dsc = (lv_draw_image_dsc_t *) t->draw_dsc; - const lv_image_dsc_t * img_dsc = draw_dsc->src; - - if(img_dsc->header.cf >= LV_COLOR_FORMAT_PROPRIETARY_START) { - return 0; - } - -#if CHIPID == 0x255 - if(draw_dsc->tile) - return 0; -#endif -#if LV_USE_VGLITE_BLIT_SPLIT - bool has_transform = (draw_dsc->rotation != 0 || draw_dsc->scale_x != LV_SCALE_NONE || - draw_dsc->scale_y != LV_SCALE_NONE); - bool is_tiled = draw_dsc->tile; -#endif - - if((!_vglite_src_cf_supported(img_dsc->header.cf)) -#if LV_USE_VGLITE_BLIT_SPLIT - || has_transform || is_tiled -#endif - || (!vglite_src_buf_aligned(img_dsc->data, img_dsc->header.stride, img_dsc->header.cf)) - ) - return 0; - - if(t->preference_score > 80) { - t->preference_score = 80; - t->preferred_draw_unit_id = DRAW_UNIT_ID_VGLITE; - } - return 1; - } - default: - return 0; - } - - return 0; -} - -static int32_t _vglite_dispatch(lv_draw_unit_t * draw_unit, lv_layer_t * layer) -{ - lv_draw_vglite_unit_t * draw_vglite_unit = (lv_draw_vglite_unit_t *) draw_unit; - - /* Return immediately if draw unit is busy. */ - if(draw_vglite_unit->task_act -#if LV_USE_VGLITE_DRAW_ASYNC - || draw_vglite_unit->wait_for_finish -#endif - ) - return 0; - - /* Try to get an ready to draw. */ - lv_draw_task_t * t = lv_draw_get_available_task(layer, NULL, DRAW_UNIT_ID_VGLITE); - - if(t == NULL) - return LV_DRAW_UNIT_IDLE; - - if(t->preferred_draw_unit_id != DRAW_UNIT_ID_VGLITE) { - /* Let the preferred known unit to draw this task. */ - if(t->preferred_draw_unit_id != LV_DRAW_UNIT_NONE) { - return LV_DRAW_UNIT_IDLE; - } - else { - /* Fake unsupported tasks as ready. */ - t->state = LV_DRAW_TASK_STATE_READY; - /* Request a new dispatching as it can get a new task. */ - lv_draw_dispatch_request(); - - return 1; - } - } - vglite_draw_task_t * vglite_task = lv_malloc_zeroed(sizeof(vglite_draw_task_t)); - LV_ASSERT_MALLOC(vglite_task); - - vglite_task->t = t; - - if(lv_draw_layer_alloc_buf(layer) == NULL) - return LV_DRAW_UNIT_IDLE; - t->state = LV_DRAW_TASK_STATE_IN_PROGRESS; - draw_vglite_unit->task_act = vglite_task; - -#if LV_USE_VGLITE_DRAW_THREAD - /* Let the render thread work. */ - if(draw_vglite_unit->inited) - lv_thread_sync_signal(&draw_vglite_unit->sync); -#else - _vglite_execute_drawing(draw_vglite_unit); - - draw_vglite_unit->task_act->t->state = LV_DRAW_TASK_STATE_READY; - _vglite_cleanup_task(draw_vglite_unit->task_act); - draw_vglite_unit->task_act = NULL; - - /* The draw unit is free now. Request a new dispatching as it can get a new task. */ - lv_draw_dispatch_request(); -#endif - - return 1; -} - -#if LV_USE_VGLITE_DRAW_ASYNC -static int32_t _vglite_wait_for_finish(lv_draw_unit_t * draw_unit) -{ - lv_draw_vglite_unit_t * draw_vglite_unit = (lv_draw_vglite_unit_t *) draw_unit; - draw_vglite_unit->wait_for_finish = true; - - /* Signal draw unit to finish its tasks and return READY state after completion. */ - if(draw_vglite_unit->inited) - lv_thread_sync_signal(&draw_vglite_unit->sync); - - /* Wait for finish now. */ - lv_draw_dispatch_wait_for_request(); - - return 1; -} -#endif - -static int32_t _vglite_delete(lv_draw_unit_t * draw_unit) -{ -#if LV_USE_VGLITE_DRAW_THREAD - lv_draw_vglite_unit_t * draw_vglite_unit = (lv_draw_vglite_unit_t *) draw_unit; - - LV_LOG_INFO("Cancel VGLite draw thread."); - draw_vglite_unit->exit_status = true; - - if(draw_vglite_unit->inited) - lv_thread_sync_signal(&draw_vglite_unit->sync); - - lv_result_t res = lv_thread_delete(&draw_vglite_unit->thread); - - return res; -#else - LV_UNUSED(draw_unit); - - return 1; -#endif -} - -static void _vglite_execute_drawing(lv_draw_vglite_unit_t * u) -{ - vglite_draw_task_t * vglite_task = u->task_act; - lv_layer_t * layer = vglite_task->t->target_layer; - lv_draw_buf_t * draw_buf = layer->draw_buf; - - /* Set target buffer */ - vglite_set_dest_buf(draw_buf->data, draw_buf->header.w, draw_buf->header.h, draw_buf->header.stride, - draw_buf->header.cf); - - lv_area_t clip_area; - lv_area_copy(&clip_area, &vglite_task->t->clip_area); - lv_area_move(&clip_area, -layer->buf_area.x1, -layer->buf_area.y1); - - lv_area_t draw_area; - lv_area_copy(&draw_area, &vglite_task->t->area); - lv_area_move(&draw_area, -layer->buf_area.x1, -layer->buf_area.y1); - - if(!lv_area_intersect(&draw_area, &draw_area, &clip_area)) - return; /*Fully clipped, nothing to do*/ - - if(_draw_info.unit_cnt > 1) - lv_draw_buf_invalidate_cache(draw_buf, &draw_area); - -#if LV_USE_PARALLEL_DRAW_DEBUG - /* remember draw unit for debug purposes */ - vglite_task->t->draw_unit = &u->base_unit; -#endif - - /* Set scissor area, excluding the split blit case */ -#if LV_USE_VGLITE_BLIT_SPLIT - if(vglite_task->t->type != LV_DRAW_TASK_TYPE_IMAGE || vglite_task->t->type != LV_DRAW_TASK_TYPE_LAYER) -#endif - vglite_set_scissor(&clip_area); - - switch(vglite_task->t->type) { - case LV_DRAW_TASK_TYPE_LABEL: - lv_draw_vglite_label(vglite_task); - break; - case LV_DRAW_TASK_TYPE_FILL: - lv_draw_vglite_fill(vglite_task); - break; - case LV_DRAW_TASK_TYPE_BORDER: - lv_draw_vglite_border(vglite_task); - break; - case LV_DRAW_TASK_TYPE_IMAGE: - lv_draw_vglite_img(vglite_task); - break; - case LV_DRAW_TASK_TYPE_ARC: - lv_draw_vglite_arc(vglite_task); - break; - case LV_DRAW_TASK_TYPE_LINE: - lv_draw_vglite_line(vglite_task); - break; - case LV_DRAW_TASK_TYPE_LAYER: - lv_draw_vglite_layer(vglite_task); - break; - case LV_DRAW_TASK_TYPE_TRIANGLE: - lv_draw_vglite_triangle(vglite_task); - break; - default: - break; - } - - /* Disable scissor */ - vglite_set_scissor(&layer->buf_area); - -#if LV_USE_PARALLEL_DRAW_DEBUG - /*Layers manage it for themselves*/ - if(vglite_task->t->type != LV_DRAW_TASK_TYPE_LAYER) { - lv_area_t draw_area; - if(!lv_area_intersect(&draw_area, &vglite_task->t->area, &vglite_task->t->clip_area)) - return; - - int32_t idx = u->base_unit.idx; - - lv_draw_rect_dsc_t rect_dsc; - lv_draw_rect_dsc_init(&rect_dsc); - rect_dsc.bg_color = lv_palette_main(idx % LV_PALETTE_LAST); - rect_dsc.border_color = rect_dsc.bg_color; - rect_dsc.bg_opa = LV_OPA_10; - rect_dsc.border_opa = LV_OPA_80; - rect_dsc.border_width = 1; - lv_draw_sw_fill(vglite_task->t, &rect_dsc, &draw_area); - - lv_point_t txt_size; - lv_text_get_size(&txt_size, "W", LV_FONT_DEFAULT, 0, 0, 100, LV_TEXT_FLAG_NONE); - - lv_area_t txt_area; - txt_area.x1 = draw_area.x1; - txt_area.y1 = draw_area.y1; - txt_area.x2 = draw_area.x1 + txt_size.x - 1; - txt_area.y2 = draw_area.y1 + txt_size.y - 1; - - lv_draw_rect_dsc_init(&rect_dsc); - rect_dsc.bg_color = lv_color_white(); - lv_draw_sw_fill(vglite_task->t, &rect_dsc, &txt_area); - - char buf[8]; - lv_snprintf(buf, sizeof(buf), "%d", idx); - lv_draw_label_dsc_t label_dsc; - lv_draw_label_dsc_init(&label_dsc); - label_dsc.color = lv_color_black(); - label_dsc.text = buf; - lv_draw_sw_label(vglite_task->t, &label_dsc, &txt_area); - } -#endif -} - -static inline void _vglite_cleanup_task(vglite_draw_task_t * task) -{ - if(task->path != NULL) { - VGLITE_CHECK_ERROR(vg_lite_clear_path(task->path)); - lv_free(task->path); - } - if(task->gradient != NULL) { - VGLITE_CHECK_ERROR(vg_lite_clear_grad(task->gradient)); - lv_free(task->gradient); - } - if(task->path_data != NULL) - lv_free(task->path_data); - - lv_free(task); -} - -#if LV_USE_VGLITE_DRAW_ASYNC -static inline void _vglite_queue_task(vglite_draw_task_t * task) -{ - VGLITE_ASSERT_MSG(((_tail + 1) % VGLITE_TASK_BUF_SIZE) != _head, "VGLite task buffer full."); - - _draw_task_buf[_tail].task = task; - _draw_task_buf[_tail].flushed = false; - _tail = (_tail + 1) % VGLITE_TASK_BUF_SIZE; -} - -static inline void _vglite_signal_task_ready(vglite_draw_task_t * task) -{ - /* Signal the ready state to dispatcher. */ - task->t->state = LV_DRAW_TASK_STATE_READY; - _head = (_head + 1) % VGLITE_TASK_BUF_SIZE; - - _vglite_cleanup_task(task); - /* No need to cleanup the tasks in buffer as we advance with the _head. */ -} - -static inline void _vglite_signal_all_task_ready(void) -{ - int end = (_head <= _tail) ? _tail : _tail + VGLITE_TASK_BUF_SIZE; - - for(int i = _head; i < end; i++) { - vglite_draw_task_t * task = _draw_task_buf[i % VGLITE_TASK_BUF_SIZE].task; - - _vglite_signal_task_ready(task); - } -} - -static inline void _vglite_signal_flushed_task_ready(void) -{ - if(vglite_cmd_buf_is_flushed()) { - int end = (_head <= _tail) ? _tail : _tail + VGLITE_TASK_BUF_SIZE; - - for(int i = _head; i < end; i++) { - if(_draw_task_buf[i % VGLITE_TASK_BUF_SIZE].flushed) { - vglite_draw_task_t * task = _draw_task_buf[i % VGLITE_TASK_BUF_SIZE].task; - - _vglite_signal_task_ready(task); - - } - else { - /* Those tasks have been flushed now. */ - _draw_task_buf[i % VGLITE_TASK_BUF_SIZE].flushed = true; - } - } - } -} -#endif - -#if LV_USE_VGLITE_DRAW_THREAD -static void _vglite_render_thread_cb(void * ptr) -{ - lv_draw_vglite_unit_t * u = ptr; - - lv_thread_sync_init(&u->sync); - u->inited = true; - - while(1) { - /* Wait for sync if there is no task set. */ - while(u->task_act == NULL -#if LV_USE_VGLITE_DRAW_ASYNC - /* - * Wait for sync if wait_for_finish is triggered. - * The thread will have to run and mark as complete any pending tasks. - */ - && !u->wait_for_finish -#endif - ) { - if(u->exit_status) - break; - - lv_thread_sync_wait(&u->sync); - } - - if(u->exit_status) { - LV_LOG_INFO("Ready to exit VGLite draw thread."); - break; - } - - if(u->task_act) { -#if LV_USE_VGLITE_DRAW_ASYNC - _vglite_queue_task((void *)u->task_act); -#endif - _vglite_execute_drawing(u); - } -#if LV_USE_VGLITE_DRAW_ASYNC - if(u->wait_for_finish) { - vglite_wait_for_finish(); - _vglite_signal_all_task_ready(); - } - else { /* u->task_act */ - _vglite_signal_flushed_task_ready(); - } -#else - /* Signal the ready state to dispatcher. */ - u->task_act->t->state = LV_DRAW_TASK_STATE_READY; - _vglite_cleanup_task(u->task_act); -#endif - - /* Cleanup draw unit running condition. */ -#if LV_USE_VGLITE_DRAW_ASYNC - if(u->wait_for_finish) - u->wait_for_finish = false; - else - u->task_act = NULL; -#else - u->task_act = NULL; -#endif - - /* The draw unit is free now. Request a new dispatching as it can get a new task. */ - lv_draw_dispatch_request(); - } - - u->inited = false; - lv_thread_sync_delete(&u->sync); - LV_LOG_INFO("Exit VGLite draw thread."); -} -#endif - -#endif /*LV_USE_DRAW_VGLITE*/ diff --git a/src/draw/nxp/vglite/lv_draw_vglite.h b/src/draw/nxp/vglite/lv_draw_vglite.h deleted file mode 100644 index 61dd1cd0d5..0000000000 --- a/src/draw/nxp/vglite/lv_draw_vglite.h +++ /dev/null @@ -1,101 +0,0 @@ -/** - * @file lv_draw_vglite.h - * - */ - -/** - * Copyright 2023-2024 NXP - * - * SPDX-License-Identifier: MIT - */ - -#ifndef LV_DRAW_VGLITE_H -#define LV_DRAW_VGLITE_H - -#ifdef __cplusplus -extern "C" { -#endif - -/********************* - * INCLUDES - *********************/ - -#include "../../../lv_conf_internal.h" - -#if LV_USE_DRAW_VGLITE -#include "../../lv_draw_private.h" -#include "../../../display/lv_display_private.h" -#include "../../../misc/lv_area_private.h" - -#include "../../lv_draw_triangle.h" -#include "../../lv_draw_label.h" -#include "../../lv_draw_image.h" -#include "../../lv_draw_line.h" -#include "../../lv_draw_arc.h" -#include "vg_lite.h" - -/********************* - * DEFINES - *********************/ - -/********************** - * TYPEDEFS - **********************/ - -typedef struct vglite_draw_task { - lv_draw_task_t * t; - vg_lite_path_t * path; - vg_lite_linear_gradient_t * gradient; - int32_t * path_data; -} vglite_draw_task_t; - -typedef struct lv_draw_vglite_unit { - lv_draw_unit_t base_unit; - vglite_draw_task_t * task_act; -#if LV_USE_OS - lv_thread_sync_t sync; - lv_thread_t thread; - volatile bool inited; - volatile bool exit_status; -#endif -#if LV_USE_VGLITE_DRAW_ASYNC - volatile bool wait_for_finish; -#endif -} lv_draw_vglite_unit_t; - -/********************** - * GLOBAL PROTOTYPES - **********************/ - -void lv_draw_buf_vglite_init_handlers(void); - -void lv_draw_vglite_init(void); - -void lv_draw_vglite_deinit(void); - -void lv_draw_vglite_arc(vglite_draw_task_t * vglite_task); - -void lv_draw_vglite_border(vglite_draw_task_t * vglite_task); - -void lv_draw_vglite_fill(vglite_draw_task_t * vglite_task); - -void lv_draw_vglite_img(vglite_draw_task_t * vglite_task); - -void lv_draw_vglite_label(vglite_draw_task_t * vglite_task); - -void lv_draw_vglite_layer(vglite_draw_task_t * vglite_task); - -void lv_draw_vglite_line(vglite_draw_task_t * vglite_task); - -void lv_draw_vglite_triangle(vglite_draw_task_t * vglite_task); - -/********************** - * MACROS - **********************/ -#endif /*LV_USE_DRAW_VGLITE*/ - -#ifdef __cplusplus -} /*extern "C"*/ -#endif - -#endif /*LV_DRAW_VGLITE_H*/ diff --git a/src/draw/nxp/vglite/lv_draw_vglite_arc.c b/src/draw/nxp/vglite/lv_draw_vglite_arc.c deleted file mode 100644 index d58a1bbecc..0000000000 --- a/src/draw/nxp/vglite/lv_draw_vglite_arc.c +++ /dev/null @@ -1,684 +0,0 @@ -/** - * @file lv_draw_vglite_arc.c - * - */ - -/** - * Copyright 2021-2024 NXP - * - * SPDX-License-Identifier: MIT - */ - -/********************* - * INCLUDES - *********************/ - -#include "lv_draw_vglite.h" - -#if LV_USE_DRAW_VGLITE -#include "lv_vglite_buf.h" -#include "lv_vglite_path.h" -#include "lv_vglite_utils.h" - -#include "../../../stdlib/lv_string.h" -#include - -/********************* - * DEFINES - *********************/ - -#define T_FRACTION 16384.0f - -#define DICHOTO_ITER 5 - -static const uint16_t TperDegree[90] = { - 0, 174, 348, 522, 697, 873, 1049, 1226, 1403, 1581, - 1759, 1938, 2117, 2297, 2477, 2658, 2839, 3020, 3202, 3384, - 3567, 3749, 3933, 4116, 4300, 4484, 4668, 4852, 5037, 5222, - 5407, 5592, 5777, 5962, 6148, 6334, 6519, 6705, 6891, 7077, - 7264, 7450, 7636, 7822, 8008, 8193, 8378, 8564, 8750, 8936, - 9122, 9309, 9495, 9681, 9867, 10052, 10238, 10424, 10609, 10794, - 10979, 11164, 11349, 11534, 11718, 11902, 12086, 12270, 12453, 12637, - 12819, 13002, 13184, 13366, 13547, 13728, 13909, 14089, 14269, 14448, - 14627, 14805, 14983, 15160, 15337, 15513, 15689, 15864, 16038, 16212 -}; - -/********************** - * TYPEDEFS - **********************/ - -/* intermediate arc params */ -typedef struct _vg_arc { - uint32_t angle; /* angle <90deg */ - int32_t quarter; /* 0-3 counter-clockwise */ - int32_t rad; /* radius */ - int32_t p0x; /* point P0 */ - int32_t p0y; - int32_t p1x; /* point P1 */ - int32_t p1y; - int32_t p2x; /* point P2 */ - int32_t p2y; - int32_t p3x; /* point P3 */ - int32_t p3y; -} vg_arc; - -typedef struct _cubic_cont_pt { - float p0; - float p1; - float p2; - float p3; -} cubic_cont_pt; - -/********************** - * STATIC PROTOTYPES - **********************/ - -/** - * Draw arc shape with effects - * - * @param[in] center Arc center with relative coordinates - * @param[in] clip_area Clip area with relative coordinates to dest buff - * @param[in] dsc Arc description structure (width, rounded ending, opacity) - * - */ -static void _vglite_draw_arc(vglite_draw_task_t * vglite_task, const lv_point_t * center, - const lv_area_t * clip_area, const lv_draw_arc_dsc_t * dsc); - -/********************** - * STATIC VARIABLES - **********************/ - -/********************** - * MACROS - **********************/ - -/********************** - * GLOBAL FUNCTIONS - **********************/ - -void lv_draw_vglite_arc(vglite_draw_task_t * vglite_task) -{ - lv_draw_task_t * t = vglite_task->t; - const lv_draw_arc_dsc_t * dsc = t->draw_dsc; - - if(dsc->opa <= (lv_opa_t)LV_OPA_MIN) - return; - if(dsc->width == 0) - return; - if(dsc->start_angle == dsc->end_angle) - return; - - lv_layer_t * layer = t->target_layer; - lv_point_t center = {dsc->center.x - layer->buf_area.x1, dsc->center.y - layer->buf_area.y1}; - - lv_area_t clip_area; - lv_area_copy(&clip_area, &t->clip_area); - lv_area_move(&clip_area, -layer->buf_area.x1, -layer->buf_area.y1); - - _vglite_draw_arc(vglite_task, ¢er, &clip_area, dsc); -} - -/********************** - * STATIC FUNCTIONS - **********************/ - -static void _copy_arc(vg_arc * dst, vg_arc * src) -{ - dst->quarter = src->quarter; - dst->rad = src->rad; - dst->angle = src->angle; - dst->p0x = src->p0x; - dst->p1x = src->p1x; - dst->p2x = src->p2x; - dst->p3x = src->p3x; - dst->p0y = src->p0y; - dst->p1y = src->p1y; - dst->p2y = src->p2y; - dst->p3y = src->p3y; -} - -/** - * Rotate the point according given rotation angle rotation center is 0,0 - */ -static void _rotate_point(int16_t angle, int32_t * x, int32_t * y) -{ - int32_t ori_x = *x; - int32_t ori_y = *y; - int16_t alpha = angle; - *x = ((lv_trigo_cos(alpha) * ori_x) / LV_TRIGO_SIN_MAX) - ((lv_trigo_sin(alpha) * ori_y) / LV_TRIGO_SIN_MAX); - *y = ((lv_trigo_sin(alpha) * ori_x) / LV_TRIGO_SIN_MAX) + ((lv_trigo_cos(alpha) * ori_y) / LV_TRIGO_SIN_MAX); -} - -/** - * Set full arc control points depending on quarter. - * Control points match the best approximation of a circle. - * Arc Quarter position is: - * Q2 | Q3 - * ---+--- - * Q1 | Q0 - */ -static void _set_full_arc(vg_arc * fullarc) -{ - /* the tangent length for the bezier circle approx */ - float tang = ((float)fullarc->rad) * BEZIER_OPTIM_CIRCLE; - switch(fullarc->quarter) { - case 0: - /* first quarter */ - fullarc->p0x = fullarc->rad; - fullarc->p0y = 0; - fullarc->p1x = fullarc->rad; - fullarc->p1y = (int32_t)tang; - fullarc->p2x = (int32_t)tang; - fullarc->p2y = fullarc->rad; - fullarc->p3x = 0; - fullarc->p3y = fullarc->rad; - break; - case 1: - /* second quarter */ - fullarc->p0x = 0; - fullarc->p0y = fullarc->rad; - fullarc->p1x = 0 - (int32_t)tang; - fullarc->p1y = fullarc->rad; - fullarc->p2x = 0 - fullarc->rad; - fullarc->p2y = (int32_t)tang; - fullarc->p3x = 0 - fullarc->rad; - fullarc->p3y = 0; - break; - case 2: - /* third quarter */ - fullarc->p0x = 0 - fullarc->rad; - fullarc->p0y = 0; - fullarc->p1x = 0 - fullarc->rad; - fullarc->p1y = 0 - (int32_t)tang; - fullarc->p2x = 0 - (int32_t)tang; - fullarc->p2y = 0 - fullarc->rad; - fullarc->p3x = 0; - fullarc->p3y = 0 - fullarc->rad; - break; - case 3: - /* fourth quarter */ - fullarc->p0x = 0; - fullarc->p0y = 0 - fullarc->rad; - fullarc->p1x = (int32_t)tang; - fullarc->p1y = 0 - fullarc->rad; - fullarc->p2x = fullarc->rad; - fullarc->p2y = 0 - (int32_t)tang; - fullarc->p3x = fullarc->rad; - fullarc->p3y = 0; - break; - default: - VGLITE_ASSERT_MSG(false, "Invalid arc quarter."); - break; - } -} - -/** - * Linear interpolation between two points 'a' and 'b' - * 't' parameter is the proportion ratio expressed in range [0 ; T_FRACTION ] - */ -static inline float _lerp(float coord_a, float coord_b, uint16_t t) -{ - float tf = (float)t; - return ((T_FRACTION - tf) * coord_a + tf * coord_b) / T_FRACTION; -} - -/** - * Computes a point of bezier curve given 't' param - */ -static inline float _comp_bezier_point(float t, cubic_cont_pt cp) -{ - float t_sq = t * t; - float inv_t_sq = (1.0f - t) * (1.0f - t); - float apt = (1.0f - t) * inv_t_sq * cp.p0 + 3.0f * inv_t_sq * t * cp.p1 + 3.0f * (1.0f - t) * t_sq * cp.p2 + t * t_sq * - cp.p3; - return apt; -} - -/** - * Find parameter 't' in curve at point 'pt' - * proceed by dichotomy on only 1 dimension, - * works only if the curve is monotonic - * bezier curve is defined by control points [p0 p1 p2 p3] - * 'dec' tells if curve is decreasing (true) or increasing (false) - */ -static uint16_t _get_bez_t_from_pos(float pt, cubic_cont_pt cp, bool dec) -{ - /* initialize dichotomy with boundary 't' values */ - float t_low = 0.0f; - float t_mid = 0.5f; - float t_hig = 1.0f; - float a_pt; - /* dichotomy loop */ - for(int i = 0; i < DICHOTO_ITER; i++) { - a_pt = _comp_bezier_point(t_mid, cp); - /* check mid-point position on bezier curve versus targeted point */ - if((a_pt > pt) != dec) { - t_hig = t_mid; - } - else { - t_low = t_mid; - } - /* define new 't' param for mid-point */ - t_mid = (t_low + t_hig) / 2.0f; - } - /* return parameter 't' in integer range [0 ; T_FRACTION] */ - return (uint16_t)floorf(t_mid * T_FRACTION + 0.5f); -} - -/** - * Gives relative coords of the control points - * for the sub-arc starting at angle with given angle span - */ -static void _get_subarc_control_points(vg_arc * arc, uint32_t span) -{ - vg_arc fullarc = {0}; - fullarc.angle = arc->angle; - fullarc.quarter = arc->quarter; - fullarc.rad = arc->rad; - _set_full_arc(&fullarc); - - /* special case of full arc */ - if(arc->angle == 90) { - _copy_arc(arc, &fullarc); - return; - } - - /* compute 1st arc using the geometric construction of curve */ - uint16_t t2 = TperDegree[arc->angle + span]; - - /* lerp for A */ - float a2x = _lerp((float)fullarc.p0x, (float)fullarc.p1x, t2); - float a2y = _lerp((float)fullarc.p0y, (float)fullarc.p1y, t2); - /* lerp for B */ - float b2x = _lerp((float)fullarc.p1x, (float)fullarc.p2x, t2); - float b2y = _lerp((float)fullarc.p1y, (float)fullarc.p2y, t2); - /* lerp for C */ - float c2x = _lerp((float)fullarc.p2x, (float)fullarc.p3x, t2); - float c2y = _lerp((float)fullarc.p2y, (float)fullarc.p3y, t2); - - /* lerp for D */ - float d2x = _lerp(a2x, b2x, t2); - float d2y = _lerp(a2y, b2y, t2); - /* lerp for E */ - float e2x = _lerp(b2x, c2x, t2); - float e2y = _lerp(b2y, c2y, t2); - - float pt2x = _lerp(d2x, e2x, t2); - float pt2y = _lerp(d2y, e2y, t2); - - /* compute sub-arc using the geometric construction of curve */ - uint16_t t1 = TperDegree[arc->angle]; - - /* lerp for A */ - float a1x = _lerp((float)fullarc.p0x, (float)fullarc.p1x, t1); - float a1y = _lerp((float)fullarc.p0y, (float)fullarc.p1y, t1); - /* lerp for B */ - float b1x = _lerp((float)fullarc.p1x, (float)fullarc.p2x, t1); - float b1y = _lerp((float)fullarc.p1y, (float)fullarc.p2y, t1); - /* lerp for C */ - float c1x = _lerp((float)fullarc.p2x, (float)fullarc.p3x, t1); - float c1y = _lerp((float)fullarc.p2y, (float)fullarc.p3y, t1); - - /* lerp for D */ - float d1x = _lerp(a1x, b1x, t1); - float d1y = _lerp(a1y, b1y, t1); - /* lerp for E */ - float e1x = _lerp(b1x, c1x, t1); - float e1y = _lerp(b1y, c1y, t1); - - float pt1x = _lerp(d1x, e1x, t1); - float pt1y = _lerp(d1y, e1y, t1); - - /* find the 't3' parameter for point P(t1) on the sub-arc [P0 A2 D2 P(t2)] using dichotomy - * use position of x axis only */ - uint16_t t3; - t3 = _get_bez_t_from_pos(pt1x, - (cubic_cont_pt) { - .p0 = ((float)fullarc.p0x), .p1 = a2x, .p2 = d2x, .p3 = pt2x - }, - (bool)(pt2x < (float)fullarc.p0x)); - - /* lerp for B */ - float b3x = _lerp(a2x, d2x, t3); - float b3y = _lerp(a2y, d2y, t3); - /* lerp for C */ - float c3x = _lerp(d2x, pt2x, t3); - float c3y = _lerp(d2y, pt2y, t3); - - /* lerp for E */ - float e3x = _lerp(b3x, c3x, t3); - float e3y = _lerp(b3y, c3y, t3); - - arc->p0x = (int32_t)floorf(0.5f + pt1x); - arc->p0y = (int32_t)floorf(0.5f + pt1y); - arc->p1x = (int32_t)floorf(0.5f + e3x); - arc->p1y = (int32_t)floorf(0.5f + e3y); - arc->p2x = (int32_t)floorf(0.5f + c3x); - arc->p2y = (int32_t)floorf(0.5f + c3y); - arc->p3x = (int32_t)floorf(0.5f + pt2x); - arc->p3y = (int32_t)floorf(0.5f + pt2y); -} - -/** - * Gives relative coords of the control points - */ -static void _get_arc_control_points(vg_arc * arc, bool start) -{ - vg_arc fullarc = {0}; - fullarc.angle = arc->angle; - fullarc.quarter = arc->quarter; - fullarc.rad = arc->rad; - _set_full_arc(&fullarc); - - /* special case of full arc */ - if(arc->angle == 90) { - _copy_arc(arc, &fullarc); - return; - } - - /* compute sub-arc using the geometric construction of curve */ - uint16_t t = TperDegree[arc->angle]; - /* lerp for A */ - float ax = _lerp((float)fullarc.p0x, (float)fullarc.p1x, t); - float ay = _lerp((float)fullarc.p0y, (float)fullarc.p1y, t); - /* lerp for B */ - float bx = _lerp((float)fullarc.p1x, (float)fullarc.p2x, t); - float by = _lerp((float)fullarc.p1y, (float)fullarc.p2y, t); - /* lerp for C */ - float cx = _lerp((float)fullarc.p2x, (float)fullarc.p3x, t); - float cy = _lerp((float)fullarc.p2y, (float)fullarc.p3y, t); - - /* lerp for D */ - float dx = _lerp(ax, bx, t); - float dy = _lerp(ay, by, t); - /* lerp for E */ - float ex = _lerp(bx, cx, t); - float ey = _lerp(by, cy, t); - - /* sub-arc's control points are tangents of DeCasteljau's algorithm */ - if(start) { - arc->p0x = (int32_t)floorf(0.5f + _lerp(dx, ex, t)); - arc->p0y = (int32_t)floorf(0.5f + _lerp(dy, ey, t)); - arc->p1x = (int32_t)floorf(0.5f + ex); - arc->p1y = (int32_t)floorf(0.5f + ey); - arc->p2x = (int32_t)floorf(0.5f + cx); - arc->p2y = (int32_t)floorf(0.5f + cy); - arc->p3x = fullarc.p3x; - arc->p3y = fullarc.p3y; - } - else { - arc->p0x = fullarc.p0x; - arc->p0y = fullarc.p0y; - arc->p1x = (int32_t)floorf(0.5f + ax); - arc->p1y = (int32_t)floorf(0.5f + ay); - arc->p2x = (int32_t)floorf(0.5f + dx); - arc->p2y = (int32_t)floorf(0.5f + dy); - arc->p3x = (int32_t)floorf(0.5f + _lerp(dx, ex, t)); - arc->p3y = (int32_t)floorf(0.5f + _lerp(dy, ey, t)); - } -} - -/** - * Add the arc control points into the path data for vglite, - * taking into account the real center of the arc (translation). - * arc_path: (in/out) the path data array for vglite - * pidx: (in/out) index of last element added in arc_path - * q_arc: (in) the arc data containing control points - * center: (in) the center of the circle in draw coordinates - * cw: (in) true if arc is clockwise - */ -static void _add_split_arc_path(int32_t * arc_path, uint32_t * pidx, vg_arc * q_arc, const lv_point_t * center, bool cw) -{ - /* assumes first control point already in array arc_path[] */ - uint32_t idx = *pidx; - if(cw) { -#if BEZIER_DBG_CONTROL_POINTS - arc_path[idx++] = VLC_OP_LINE; - arc_path[idx++] = q_arc->p1x + center->x; - arc_path[idx++] = q_arc->p1y + center->y; - arc_path[idx++] = VLC_OP_LINE; - arc_path[idx++] = q_arc->p2x + center->x; - arc_path[idx++] = q_arc->p2y + center->y; - arc_path[idx++] = VLC_OP_LINE; - arc_path[idx++] = q_arc->p3x + center->x; - arc_path[idx++] = q_arc->p3y + center->y; -#else - arc_path[idx++] = VLC_OP_CUBIC; - arc_path[idx++] = q_arc->p1x + center->x; - arc_path[idx++] = q_arc->p1y + center->y; - arc_path[idx++] = q_arc->p2x + center->x; - arc_path[idx++] = q_arc->p2y + center->y; - arc_path[idx++] = q_arc->p3x + center->x; - arc_path[idx++] = q_arc->p3y + center->y; -#endif - } - else { /* reverse points order when counter-clockwise */ -#if BEZIER_DBG_CONTROL_POINTS - arc_path[idx++] = VLC_OP_LINE; - arc_path[idx++] = q_arc->p2x + center->x; - arc_path[idx++] = q_arc->p2y + center->y; - arc_path[idx++] = VLC_OP_LINE; - arc_path[idx++] = q_arc->p1x + center->x; - arc_path[idx++] = q_arc->p1y + center->y; - arc_path[idx++] = VLC_OP_LINE; - arc_path[idx++] = q_arc->p0x + center->x; - arc_path[idx++] = q_arc->p0y + center->y; -#else - arc_path[idx++] = VLC_OP_CUBIC; - arc_path[idx++] = q_arc->p2x + center->x; - arc_path[idx++] = q_arc->p2y + center->y; - arc_path[idx++] = q_arc->p1x + center->x; - arc_path[idx++] = q_arc->p1y + center->y; - arc_path[idx++] = q_arc->p0x + center->x; - arc_path[idx++] = q_arc->p0y + center->y; -#endif - } - /* update index i n path array*/ - *pidx = idx; -} - -static void _add_arc_path(int32_t * arc_path, uint32_t * pidx, uint32_t radius, - int32_t start_angle, int32_t end_angle, const lv_point_t * center, bool cw) -{ - /* set number of arcs to draw */ - vg_arc q_arc; - uint32_t start_arc_angle = start_angle % 90; - uint32_t end_arc_angle = end_angle % 90; - uint32_t inv_start_arc_angle = (start_arc_angle > 0) ? (90 - start_arc_angle) : 0; - uint32_t nbarc = (end_angle - start_angle - inv_start_arc_angle - end_arc_angle) / 90; - q_arc.rad = radius; - - /* handle special case of start & end point in the same quarter */ - if(((start_angle / 90) == (end_angle / 90)) && (nbarc <= 0)) { - q_arc.quarter = (start_angle / 90) % 4; - q_arc.angle = start_arc_angle; - _get_subarc_control_points(&q_arc, end_arc_angle - start_arc_angle); - _add_split_arc_path(arc_path, pidx, &q_arc, center, cw); - return; - } - - if(cw) { - /* partial starting arc */ - if(start_arc_angle > 0) { - q_arc.quarter = (start_angle / 90) % 4; - q_arc.angle = start_arc_angle; - /* get cubic points relative to center */ - _get_arc_control_points(&q_arc, true); - /* put cubic points in arc_path */ - _add_split_arc_path(arc_path, pidx, &q_arc, center, cw); - } - /* full arcs */ - for(uint32_t q = 0; q < nbarc ; q++) { - q_arc.quarter = (q + ((start_angle + 89) / 90)) % 4; - q_arc.angle = 90; - /* get cubic points relative to center */ - _get_arc_control_points(&q_arc, true); /* 2nd parameter 'start' ignored */ - /* put cubic points in arc_path */ - _add_split_arc_path(arc_path, pidx, &q_arc, center, cw); - } - /* partial ending arc */ - if(end_arc_angle > 0) { - q_arc.quarter = (end_angle / 90) % 4; - q_arc.angle = end_arc_angle; - /* get cubic points relative to center */ - _get_arc_control_points(&q_arc, false); - /* put cubic points in arc_path */ - _add_split_arc_path(arc_path, pidx, &q_arc, center, cw); - } - - } - else { /* counter clockwise */ - - /* partial ending arc */ - if(end_arc_angle > 0) { - q_arc.quarter = (end_angle / 90) % 4; - q_arc.angle = end_arc_angle; - /* get cubic points relative to center */ - _get_arc_control_points(&q_arc, false); - /* put cubic points in arc_path */ - _add_split_arc_path(arc_path, pidx, &q_arc, center, cw); - } - /* full arcs */ - for(int32_t q = nbarc - 1; q >= 0; q--) { - q_arc.quarter = (q + ((start_angle + 89) / 90)) % 4; - q_arc.angle = 90; - /* get cubic points relative to center */ - _get_arc_control_points(&q_arc, true); /* 2nd parameter 'start' ignored */ - /* put cubic points in arc_path */ - _add_split_arc_path(arc_path, pidx, &q_arc, center, cw); - } - /* partial starting arc */ - if(start_arc_angle > 0) { - q_arc.quarter = (start_angle / 90) % 4; - q_arc.angle = start_arc_angle; - /* get cubic points relative to center */ - _get_arc_control_points(&q_arc, true); - /* put cubic points in arc_path */ - _add_split_arc_path(arc_path, pidx, &q_arc, center, cw); - } - } -} - -static void _vglite_draw_arc(vglite_draw_task_t * vglite_task, const lv_point_t * center, - const lv_area_t * clip_area, const lv_draw_arc_dsc_t * dsc) -{ - vg_lite_path_t * path = lv_malloc_zeroed(sizeof(vg_lite_path_t)); - LV_ASSERT_MALLOC(path); - vglite_task->path = path; - int16_t start_angle = dsc->start_angle; - int16_t end_angle = dsc->end_angle; - - /* be sure end_angle > start_angle */ - if(end_angle < start_angle) - end_angle += 360; - - bool donut = ((end_angle - start_angle) % 360 == 0) ? true : false; - vg_lite_buffer_t * dest_buf = vglite_get_dest_buf(); - - int32_t * arc_path = lv_malloc_zeroed(ARC_PATH_DATA_MAX_SIZE * sizeof(int32_t)); - LV_ASSERT_MALLOC(arc_path); - vglite_task->path_data = arc_path; - - /*** Init path ***/ - int32_t width = dsc->width; /* inner arc radius = outer arc radius - width */ - uint16_t radius = dsc->radius; - - if(width > radius) - width = radius; - - uint32_t pidx = 0; - int32_t cp_x, cp_y; /* control point coords */ - - /* first control point of curve */ - cp_x = radius; - cp_y = 0; - _rotate_point(start_angle, &cp_x, &cp_y); - arc_path[pidx++] = VLC_OP_MOVE; - arc_path[pidx++] = center->x + cp_x; - arc_path[pidx++] = center->y + cp_y; - - /* draw 1-5 outer quarters */ - _add_arc_path(arc_path, &pidx, radius, start_angle, end_angle, center, true); - - if(donut) { - /* close outer circle */ - cp_x = radius; - cp_y = 0; - _rotate_point(start_angle, &cp_x, &cp_y); - arc_path[pidx++] = VLC_OP_LINE; - arc_path[pidx++] = center->x + cp_x; - arc_path[pidx++] = center->y + cp_y; - /* start inner circle */ - cp_x = radius - width; - cp_y = 0; - _rotate_point(start_angle, &cp_x, &cp_y); - arc_path[pidx++] = VLC_OP_MOVE; - arc_path[pidx++] = center->x + cp_x; - arc_path[pidx++] = center->y + cp_y; - - } - else if(dsc->rounded != 0U) { /* 1st rounded arc ending */ - cp_x = radius - width / 2; - cp_y = 0; - _rotate_point(end_angle, &cp_x, &cp_y); - lv_point_t round_center = {center->x + cp_x, center->y + cp_y}; - _add_arc_path(arc_path, &pidx, width / 2, end_angle, (end_angle + 180), - &round_center, true); - - } - else { /* 1st flat ending */ - cp_x = radius - width; - cp_y = 0; - _rotate_point(end_angle, &cp_x, &cp_y); - arc_path[pidx++] = VLC_OP_LINE; - arc_path[pidx++] = center->x + cp_x; - arc_path[pidx++] = center->y + cp_y; - } - - /* draw 1-5 inner quarters */ - _add_arc_path(arc_path, &pidx, radius - width, start_angle, end_angle, center, false); - - /* last control point of curve */ - if(donut) { /* close the loop */ - cp_x = radius - width; - cp_y = 0; - _rotate_point(start_angle, &cp_x, &cp_y); - arc_path[pidx++] = VLC_OP_LINE; - arc_path[pidx++] = center->x + cp_x; - arc_path[pidx++] = center->y + cp_y; - - } - else if(dsc->rounded != 0U) { /* 2nd rounded arc ending */ - cp_x = radius - width / 2; - cp_y = 0; - _rotate_point(start_angle, &cp_x, &cp_y); - lv_point_t round_center = {center->x + cp_x, center->y + cp_y}; - _add_arc_path(arc_path, &pidx, width / 2, (start_angle + 180), (start_angle + 360), - &round_center, true); - - } - else { /* 2nd flat ending */ - cp_x = radius; - cp_y = 0; - _rotate_point(start_angle, &cp_x, &cp_y); - arc_path[pidx++] = VLC_OP_LINE; - arc_path[pidx++] = center->x + cp_x; - arc_path[pidx++] = center->y + cp_y; - } - - arc_path[pidx++] = VLC_OP_END; - - VGLITE_CHECK_ERROR(vg_lite_init_path(path, VG_LITE_S32, VG_LITE_HIGH, (uint32_t)pidx * sizeof(int32_t), arc_path, - (vg_lite_float_t)clip_area->x1, (vg_lite_float_t)clip_area->y1, - ((vg_lite_float_t)clip_area->x2) + 1.0f, ((vg_lite_float_t)clip_area->y2) + 1.0f)); - - lv_color32_t col32 = lv_color_to_32(dsc->color, dsc->opa); - vg_lite_color_t vgcol = vglite_get_color(col32, false); - - /*** Draw arc ***/ - VGLITE_CHECK_ERROR(vg_lite_draw(dest_buf, path, VG_LITE_FILL_NON_ZERO, NULL, VG_LITE_BLEND_SRC_OVER, vgcol)); - - vglite_run(); -} - -#endif /*LV_USE_DRAW_VGLITE*/ diff --git a/src/draw/nxp/vglite/lv_draw_vglite_border.c b/src/draw/nxp/vglite/lv_draw_vglite_border.c deleted file mode 100644 index c04c9926cf..0000000000 --- a/src/draw/nxp/vglite/lv_draw_vglite_border.c +++ /dev/null @@ -1,248 +0,0 @@ -/** - * @file lv_draw_vglite_border.c - * - */ - -/** - * Copyright 2022-2024 NXP - * - * SPDX-License-Identifier: MIT - */ - -/********************* - * INCLUDES - *********************/ - -#include "lv_draw_vglite.h" - -#if LV_USE_DRAW_VGLITE -#include "lv_vglite_buf.h" -#include "lv_vglite_path.h" -#include "lv_vglite_utils.h" - -#include - -/********************* - * DEFINES - *********************/ - -/********************* - * DEFINES - *********************/ - -/*** Define maximum numbers of rectangles needed to clip partial borders ***/ -#define MAX_NUM_RECTANGLES 4 - -/********************** - * TYPEDEFS - **********************/ - -typedef struct scissoring_rects { - vg_lite_rectangle_t rect[MAX_NUM_RECTANGLES]; - uint32_t num_rect; -} scissoring_rects_t ; - -/********************** - * STATIC PROTOTYPES - **********************/ - -/** - * Draw rectangle border/outline shape with effects (rounded corners, opacity) - * - * @param[in] coords Coordinates of the rectangle border/outline (relative to dest buff) - * @param[in] clip_area Clip area with relative coordinates to dest buff - * @param[in] dsc Description of the rectangle border/outline - * - */ -static void _vglite_draw_border(vglite_draw_task_t * task, const lv_area_t * coords, - const lv_area_t * clip_area, const lv_draw_border_dsc_t * dsc); - -/** - * Create scissor area based on the border side - * - * @param[in] coords Coordinates of the rectangle border/outline (relative to dest buff) - * @param[in] line_width Width of the line - * @param[in] border_side Sides of the border - * @param[in] radius Radius of the border - * @param[out] scissoring_rects Struct that contains the array of scissors - * - */ - -static void _border_set_scissoring(const lv_area_t * coords, int32_t line_width, - uint32_t border_side, int32_t radius, - scissoring_rects_t * scissoring_rects); - -/********************** - * STATIC VARIABLES - **********************/ - -/********************** - * MACROS - **********************/ - -/********************** - * GLOBAL FUNCTIONS - **********************/ - -void lv_draw_vglite_border(vglite_draw_task_t * vglite_task) -{ - const lv_draw_border_dsc_t * dsc = vglite_task->t->draw_dsc; - const lv_area_t * coords = &vglite_task->t->area; - - if(dsc->opa <= (lv_opa_t)LV_OPA_MIN) - return; - if(dsc->width == 0) - return; - if(dsc->side == (lv_border_side_t)LV_BORDER_SIDE_NONE) - return; - - lv_layer_t * layer = vglite_task->t->target_layer; - lv_area_t inward_coords; - int32_t width = dsc->width; - - /* Move border inwards to align with software rendered border */ - inward_coords.x1 = coords->x1 + ceil(width / 2.0f); - inward_coords.x2 = coords->x2 - floor(width / 2.0f); - inward_coords.y1 = coords->y1 + ceil(width / 2.0f); - inward_coords.y2 = coords->y2 - floor(width / 2.0f); - - lv_area_move(&inward_coords, -layer->buf_area.x1, -layer->buf_area.y1); - - lv_area_t clip_area; - lv_area_copy(&clip_area, &vglite_task->t->clip_area); - lv_area_move(&clip_area, -layer->buf_area.x1, -layer->buf_area.y1); - - lv_area_t clipped_coords; - if(!lv_area_intersect(&clipped_coords, &inward_coords, &clip_area)) - return; /*Fully clipped, nothing to do*/ - - _vglite_draw_border(vglite_task, &inward_coords, &clip_area, dsc); -} - -/********************** - * STATIC FUNCTIONS - **********************/ - -static void _border_set_scissoring(const lv_area_t * coords, int32_t line_width, - uint32_t border_side, int32_t radius, - scissoring_rects_t * scissoring_rects) -{ - int32_t rect_width = coords->x2 - coords->x1; - int32_t rect_height = coords->y2 - coords->y1; - int32_t shortest_side = LV_MIN(rect_width, rect_height); - int32_t final_radius = LV_MIN(radius, shortest_side / 2); - - if(border_side & LV_BORDER_SIDE_TOP) { - scissoring_rects->rect[scissoring_rects->num_rect].x = coords->x1 - ceil(line_width / 2.0f); - scissoring_rects->rect[scissoring_rects->num_rect].y = coords->y1 - ceil(line_width / 2.0f); - scissoring_rects->rect[scissoring_rects->num_rect].width = coords->x2 - coords->x1 + line_width; - scissoring_rects->rect[scissoring_rects->num_rect].height = final_radius + ceil(line_width / 2.0f); - scissoring_rects->num_rect++; - } - - if(border_side & LV_BORDER_SIDE_LEFT) { - scissoring_rects->rect[scissoring_rects->num_rect].x = coords->x1 - ceil(line_width / 2.0f); - scissoring_rects->rect[scissoring_rects->num_rect].y = coords->y1 - ceil(line_width / 2.0f); - scissoring_rects->rect[scissoring_rects->num_rect].width = final_radius + ceil(line_width / 2.0f); - scissoring_rects->rect[scissoring_rects->num_rect].height = coords->y2 - coords->y1 + line_width + 1; - scissoring_rects->num_rect++; - } - - if(border_side & LV_BORDER_SIDE_RIGHT) { - scissoring_rects->rect[scissoring_rects->num_rect].x = coords->x2 - final_radius + 1; - scissoring_rects->rect[scissoring_rects->num_rect].y = coords->y1 - ceil(line_width / 2.0f); - scissoring_rects->rect[scissoring_rects->num_rect].width = final_radius + ceil(line_width / 2.0f); - scissoring_rects->rect[scissoring_rects->num_rect].height = coords->y2 - coords->y1 + line_width + 1; - scissoring_rects->num_rect++; - } - - if(border_side & LV_BORDER_SIDE_BOTTOM) { - scissoring_rects->rect[scissoring_rects->num_rect].x = coords->x1 - ceil(line_width / 2.0f); - scissoring_rects->rect[scissoring_rects->num_rect].y = coords->y2 - final_radius + 1; - scissoring_rects->rect[scissoring_rects->num_rect].width = coords->x2 - coords->x1 + line_width; - scissoring_rects->rect[scissoring_rects->num_rect].height = final_radius + ceil(line_width / 2.0f); - scissoring_rects->num_rect++; - } -} - -static void _vglite_draw_border(vglite_draw_task_t * vglite_task, const lv_area_t * coords, - const lv_area_t * clip_area, const lv_draw_border_dsc_t * dsc) -{ - int32_t radius = dsc->radius; - vg_lite_buffer_t * buf = vglite_get_dest_buf(); - - if(radius < 0) - return; - - int32_t border_half = (int32_t)floor(dsc->width / 2.0f); - if(radius > border_half) - radius = radius - border_half; - - vg_lite_cap_style_t cap_style = (radius) ? VG_LITE_CAP_ROUND : VG_LITE_CAP_BUTT; - vg_lite_join_style_t join_style = (radius) ? VG_LITE_JOIN_ROUND : VG_LITE_JOIN_MITER; - - /*** Init path ***/ - int32_t * path_data = lv_malloc_zeroed(RECT_PATH_DATA_MAX_SIZE * sizeof(int32_t)); - LV_ASSERT_MALLOC(path_data); - vglite_task->path_data = path_data; - - uint32_t path_data_size; - vglite_create_rect_path_data(path_data, &path_data_size, radius, coords); - vg_lite_quality_t path_quality = radius > 0 ? VG_LITE_HIGH : VG_LITE_MEDIUM; - - vg_lite_path_t * path = lv_malloc_zeroed(sizeof(vg_lite_path_t)); - LV_ASSERT_MALLOC(path); - vglite_task->path = path; - VGLITE_CHECK_ERROR(vg_lite_init_path(path, VG_LITE_S32, path_quality, path_data_size, path_data, - (vg_lite_float_t)clip_area->x1, (vg_lite_float_t)clip_area->y1, - ((vg_lite_float_t)clip_area->x2) + 1.0f, ((vg_lite_float_t)clip_area->y2) + 1.0f)); - - lv_color32_t col32 = lv_color_to_32(dsc->color, dsc->opa); - vg_lite_color_t vgcol = vglite_get_color(col32, false); - - int32_t line_width = dsc->width; - lv_border_side_t border_side = dsc->side; - - scissoring_rects_t scissoring_rects; - scissoring_rects.num_rect = 0; - - bool has_vg_mask_feat = vg_lite_query_feature(gcFEATURE_BIT_VG_MASK); - - VGLITE_CHECK_ERROR(vg_lite_set_draw_path_type(path, VG_LITE_DRAW_STROKE_PATH)); - - VGLITE_CHECK_ERROR(vg_lite_set_stroke(path, cap_style, join_style, line_width, 8, NULL, 0, 0, vgcol)); - - VGLITE_CHECK_ERROR(vg_lite_update_stroke(path)); - - if(border_side != LV_BORDER_SIDE_FULL) { - _border_set_scissoring(coords, line_width, border_side, radius, &scissoring_rects); - - if(has_vg_mask_feat) { - /*** Enable scissor and apply scissor rects ***/ - VGLITE_CHECK_ERROR(vg_lite_enable_scissor()); - VGLITE_CHECK_ERROR(vg_lite_scissor_rects(buf, scissoring_rects.num_rect, scissoring_rects.rect)); - - /*** Draw border ***/ - VGLITE_CHECK_ERROR(vg_lite_draw(buf, path, VG_LITE_FILL_NON_ZERO, NULL, VG_LITE_BLEND_SRC_OVER, vgcol)); - - /*** Disable scissor ***/ - VGLITE_CHECK_ERROR(vg_lite_disable_scissor()); - } - else { - for(uint32_t i = 0; i < scissoring_rects.num_rect; i++) { - VGLITE_CHECK_ERROR(vg_lite_set_scissor(scissoring_rects.rect[i].x, scissoring_rects.rect[i].y, - scissoring_rects.rect[i].x + scissoring_rects.rect[i].width, - scissoring_rects.rect[i].y + scissoring_rects.rect[i].height)); - VGLITE_CHECK_ERROR(vg_lite_draw(buf, path, VG_LITE_FILL_NON_ZERO, NULL, VG_LITE_BLEND_SRC_OVER, vgcol)); - } - } - } - else { - /*** Draw border ***/ - VGLITE_CHECK_ERROR(vg_lite_draw(buf, path, VG_LITE_FILL_NON_ZERO, NULL, VG_LITE_BLEND_SRC_OVER, vgcol)); - } - - vglite_run(); -} - -#endif /*LV_USE_DRAW_VGLITE*/ diff --git a/src/draw/nxp/vglite/lv_draw_vglite_fill.c b/src/draw/nxp/vglite/lv_draw_vglite_fill.c deleted file mode 100644 index c58c09fce7..0000000000 --- a/src/draw/nxp/vglite/lv_draw_vglite_fill.c +++ /dev/null @@ -1,269 +0,0 @@ -/** - * @file lv_draw_vglite_fill.c - * - */ - -/** - * Copyright 2020-2024 NXP - * - * SPDX-License-Identifier: MIT - */ - -/********************* - * INCLUDES - *********************/ - -#include "lv_draw_vglite.h" - -#if LV_USE_DRAW_VGLITE -#include "lv_vglite_buf.h" -#include "lv_vglite_path.h" -#include "lv_vglite_utils.h" - -#include "../../../stdlib/lv_string.h" - -/********************* - * DEFINES - *********************/ - -/********************** - * TYPEDEFS - **********************/ - -/********************** - * STATIC PROTOTYPES - **********************/ - -/** - * Set rectangle path data - * - * @param[in/out] path_data Coordinates of the rectangle - * @param[in/out] path_data_size Size of path_data (bytes) - * @param[in] p Points of the rectangle - * - */ -static void _vglite_set_rectangle(int32_t * path_data, uint32_t * path_data_size, - const lv_area_t * dest_area); - -/** - * Fill area, with optional opacity. - * - * @param[in] dest_area Area with relative coordinates of destination buffer - * @param[in] dsc Description of the area to fill (color, opa) - * - */ -static void _vglite_fill(vglite_draw_task_t * task, const lv_area_t * dest_area, - const lv_draw_fill_dsc_t * dsc); - -/** - * Draw rectangle background with effects (rounded corners, gradient) - * - * @param[in] coords Coordinates of the rectangle background (relative to dest buff) - * @param[in] clip_area Clip area with relative coordinates to dest buff - * @param[in] dsc Description of the rectangle background - * - */ -static void _vglite_draw_rect(vglite_draw_task_t * task, const lv_area_t * coords, - const lv_area_t * clip_area, const lv_draw_fill_dsc_t * dsc); - -/********************** - * STATIC VARIABLES - **********************/ - -/********************** - * MACROS - **********************/ - -/********************** - * GLOBAL FUNCTIONS - **********************/ - -void lv_draw_vglite_fill(vglite_draw_task_t * vglite_task) -{ - const lv_draw_fill_dsc_t * dsc = vglite_task->t->draw_dsc; - const lv_area_t * coords = &vglite_task->t->area; - - if(dsc->opa <= (lv_opa_t)LV_OPA_MIN) - return; - - lv_layer_t * layer = vglite_task->t->target_layer; - lv_area_t relative_coords; - lv_area_copy(&relative_coords, coords); - lv_area_move(&relative_coords, -layer->buf_area.x1, -layer->buf_area.y1); - - lv_area_t clip_area; - lv_area_copy(&clip_area, &vglite_task->t->clip_area); - lv_area_move(&clip_area, -layer->buf_area.x1, -layer->buf_area.y1); - - lv_area_t clipped_coords; - if(!lv_area_intersect(&clipped_coords, &relative_coords, &clip_area)) - return; /*Fully clipped, nothing to do*/ - - /* - * Most simple case: just a plain rectangle (no radius, no gradient) - */ - if((dsc->radius == 0) && (dsc->grad.dir == (lv_grad_dir_t)LV_GRAD_DIR_NONE)) - _vglite_fill(vglite_task, &clipped_coords, dsc); - else - _vglite_draw_rect(vglite_task, &relative_coords, &clip_area, dsc); -} - -/********************** - * STATIC FUNCTIONS - **********************/ - -static void _vglite_set_rectangle(int32_t * path_data, uint32_t * path_data_size, const lv_area_t * dest_area) -{ - uint32_t pidx = 0; - path_data[pidx++] = VLC_OP_MOVE; - path_data[pidx++] = dest_area->x1; - path_data[pidx++] = dest_area->y1; - path_data[pidx++] = VLC_OP_LINE; - path_data[pidx++] = dest_area->x2 + 1; - path_data[pidx++] = dest_area->y1; - path_data[pidx++] = VLC_OP_LINE; - path_data[pidx++] = dest_area->x2 + 1; - path_data[pidx++] = dest_area->y2 + 1; - path_data[pidx++] = VLC_OP_LINE; - path_data[pidx++] = dest_area->x1; - path_data[pidx++] = dest_area->y2 + 1; - path_data[pidx++] = VLC_OP_LINE; - path_data[pidx++] = dest_area->x1; - path_data[pidx++] = dest_area->y1; - path_data[pidx++] = VLC_OP_END; - - *path_data_size = pidx * sizeof(int32_t); -} - -static void _vglite_fill(vglite_draw_task_t * vglite_task, const lv_area_t * dest_area, - const lv_draw_fill_dsc_t * dsc) -{ - vg_lite_buffer_t * dest_buf = vglite_get_dest_buf(); - - lv_color32_t col32 = lv_color_to_32(dsc->color, dsc->opa); - vg_lite_color_t vgcol = vglite_get_color(col32, false); - - if(dsc->opa >= (lv_opa_t)LV_OPA_MAX) { /*Opaque fill*/ - vg_lite_rectangle_t rect = { - .x = dest_area->x1, - .y = dest_area->y1, - .width = lv_area_get_width(dest_area), - .height = lv_area_get_height(dest_area) - }; - - VGLITE_CHECK_ERROR(vg_lite_clear(dest_buf, &rect, vgcol)); - - vglite_run(); - } - else { /*fill with transparency*/ - - vg_lite_path_t * path = lv_malloc_zeroed(sizeof(vg_lite_path_t)); - LV_ASSERT_MALLOC(path); - vglite_task->path = path; - - uint32_t path_data_size; - int32_t * path_data = lv_malloc_zeroed(16 * sizeof(int32_t)); - LV_ASSERT_MALLOC(path_data); - vglite_task->path_data = path_data; - _vglite_set_rectangle(path_data, &path_data_size, dest_area); - - VGLITE_CHECK_ERROR(vg_lite_init_path(path, VG_LITE_S32, VG_LITE_MEDIUM, path_data_size, path_data, - (vg_lite_float_t) dest_area->x1, (vg_lite_float_t) dest_area->y1, - ((vg_lite_float_t) dest_area->x2) + 1.0f, ((vg_lite_float_t) dest_area->y2) + 1.0f)); - - /*Draw rectangle*/ - VGLITE_CHECK_ERROR(vg_lite_draw(dest_buf, path, VG_LITE_FILL_EVEN_ODD, NULL, VG_LITE_BLEND_SRC_OVER, vgcol)); - - vglite_run(); - } -} - -static void _vglite_draw_rect(vglite_draw_task_t * vglite_task, const lv_area_t * coords, - const lv_area_t * clip_area, const lv_draw_fill_dsc_t * dsc) -{ - int32_t width = lv_area_get_width(coords); - int32_t height = lv_area_get_height(coords); - int32_t radius = dsc->radius; - lv_opa_t opa = dsc->opa; - vg_lite_buffer_t * dest_buf = vglite_get_dest_buf(); - - if(dsc->radius < 0) - return; - - /*** Init path ***/ - int32_t * path_data = lv_malloc_zeroed(RECT_PATH_DATA_MAX_SIZE * sizeof(int32_t)); - LV_ASSERT_MALLOC(path_data); - vglite_task->path_data = path_data; - - uint32_t path_data_size; - vglite_create_rect_path_data(path_data, &path_data_size, radius, coords); - vg_lite_quality_t path_quality = dsc->radius > 0 ? VG_LITE_HIGH : VG_LITE_MEDIUM; - - vg_lite_path_t * path = lv_malloc_zeroed(sizeof(vg_lite_path_t)); - LV_ASSERT_MALLOC(path); - vglite_task->path = path; - VGLITE_CHECK_ERROR(vg_lite_init_path(path, VG_LITE_S32, path_quality, path_data_size, path_data, - (vg_lite_float_t)clip_area->x1, (vg_lite_float_t)clip_area->y1, - ((vg_lite_float_t)clip_area->x2) + 1.0f, ((vg_lite_float_t)clip_area->y2) + 1.0f)); - - /*** Init Color ***/ - lv_color32_t col32 = lv_color_to_32(dsc->color, opa); - vg_lite_color_t vgcol = vglite_get_color(col32, false); - - vg_lite_linear_gradient_t * gradient; - bool has_gradient = (dsc->grad.dir != (lv_grad_dir_t)LV_GRAD_DIR_NONE); - - /*** Init Gradient ***/ - if(has_gradient) { - gradient = lv_malloc_zeroed(sizeof(vg_lite_linear_gradient_t)); - LV_ASSERT_MALLOC(gradient); - vglite_task->gradient = gradient; - - vg_lite_matrix_t * grad_matrix; - - vg_lite_uint32_t colors[LV_GRADIENT_MAX_STOPS]; - vg_lite_uint32_t stops[LV_GRADIENT_MAX_STOPS]; - lv_color32_t col32[LV_GRADIENT_MAX_STOPS]; - - /* Gradient setup */ - vg_lite_uint32_t cnt = LV_MIN(dsc->grad.stops_count, LV_GRADIENT_MAX_STOPS); - lv_opa_t opa; - - for(uint8_t i = 0; i < cnt; i++) { - stops[i] = dsc->grad.stops[i].frac; - - opa = LV_OPA_MIX2(dsc->grad.stops[i].opa, dsc->opa); - - col32[i] = lv_color_to_32(dsc->grad.stops[i].color, opa); - colors[i] = vglite_get_color(col32[i], true); - } - - VGLITE_CHECK_ERROR(vg_lite_init_grad(gradient)); - - VGLITE_CHECK_ERROR(vg_lite_set_grad(gradient, cnt, colors, stops)); - - VGLITE_CHECK_ERROR(vg_lite_update_grad(gradient)); - - grad_matrix = vg_lite_get_grad_matrix(gradient); - vg_lite_identity(grad_matrix); - vg_lite_translate((float)coords->x1, (float)coords->y1, grad_matrix); - - if(dsc->grad.dir == (lv_grad_dir_t)LV_GRAD_DIR_VER) { - vg_lite_scale(1.0f, (float)height / 256.0f, grad_matrix); - vg_lite_rotate(90.0f, grad_matrix); - } - else { /*LV_GRAD_DIR_HOR*/ - vg_lite_scale((float)width / 256.0f, 1.0f, grad_matrix); - } - - VGLITE_CHECK_ERROR(vg_lite_draw_gradient(dest_buf, path, VG_LITE_FILL_EVEN_ODD, NULL, gradient, - VG_LITE_BLEND_SRC_OVER)); - } - else { - VGLITE_CHECK_ERROR(vg_lite_draw(dest_buf, path, VG_LITE_FILL_EVEN_ODD, NULL, VG_LITE_BLEND_SRC_OVER, vgcol)); - } - - vglite_run(); -} - -#endif /*LV_USE_DRAW_VGLITE*/ diff --git a/src/draw/nxp/vglite/lv_draw_vglite_img.c b/src/draw/nxp/vglite/lv_draw_vglite_img.c deleted file mode 100644 index b01afe7299..0000000000 --- a/src/draw/nxp/vglite/lv_draw_vglite_img.c +++ /dev/null @@ -1,449 +0,0 @@ -/** - * @file lv_draw_vglite_blend.c - * - */ - -/** - * Copyright 2020-2024 NXP - * - * SPDX-License-Identifier: MIT - */ - -/********************* - * INCLUDES - *********************/ - -#include "lv_draw_vglite.h" - -#if LV_USE_DRAW_VGLITE -#include "lv_vglite_buf.h" -#include "lv_vglite_matrix.h" -#include "lv_vglite_utils.h" -#include "lv_vglite_path.h" - -#include "../../../misc/lv_log.h" - -/********************* - * DEFINES - *********************/ - -#if LV_USE_VGLITE_BLIT_SPLIT -/** -* BLIT split threshold - BLITs with width or height higher than this value will -* be done in multiple steps. Value must be multiple of stride alignment in px. -* For most color formats the alignment is 16px (except the index formats). -*/ -#define VGLITE_BLIT_SPLIT_THR 352 - -/* Enable for logging debug traces. */ -#define VGLITE_LOG_TRACE 0 - -#if VGLITE_LOG_TRACE -#define VGLITE_TRACE(fmt, ...) \ - do { \ - LV_LOG(fmt, ##__VA_ARGS__); \ - } while (0) -#else -#define VGLITE_TRACE(fmt, ...) \ - do { \ - } while (0) -#endif -#endif /*LV_USE_VGLITE_BLIT_SPLIT*/ - -/********************** - * TYPEDEFS - **********************/ - -/********************** - * STATIC PROTOTYPES - **********************/ - -#if LV_USE_VGLITE_BLIT_SPLIT -/** - * Move buffer pointer as close as possible to area, but with respect to alignment requirements. - * - * @param[in] buf Buffer address pointer - * @param[in] area Area with relative coordinates to the buffer - * @param[in] stride Stride of buffer in bytes - * @param[in] cf Color format of buffer - */ -static void _move_buf_close_to_area(void ** buf, lv_area_t * area, uint32_t stride, lv_color_format_t cf); - -/** - * BLock Image Transfer - copy rectangular image from src_buf to dest_buf with effects. - * By default, image is copied directly, with optional opacity. - * - * @param dest_buf Destination buffer - * @param[in] dest_area Destination area with relative coordinates to dest buffer - * @param[in] dest_stride Stride of destination buffer in bytes - * @param[in] dest_cf Color format of destination buffer - * @param[in] src_buf Source buffer - * @param[in] src_area Source area with relative coordinates to src buffer - * @param[in] src_stride Stride of source buffer in bytes - * @param[in] src_cf Color format of source buffer - * @param[in] dsc Image descriptor - * - */ -static void _vglite_blit_split(void * dest_buf, lv_area_t * dest_area, uint32_t dest_stride, lv_color_format_t dest_cf, - const void * src_buf, lv_area_t * src_area, uint32_t src_stride, lv_color_format_t src_cf, - const lv_draw_image_dsc_t * dsc); -#endif /*LV_USE_VGLITE_BLIT_SPLIT*/ - -/** - * VGlite blit - fill a path with an image pattern - * - * - * @param[in] dest_area Destination area with relative coordinates to dest buffer - * @param[in] clip_area Clip area with relative coordinates to dest buff - * @param[in] coords Coordinates of the image (relative to dest buff) - * @param[in] dsc Image descriptor - * - */ -static void _vglite_draw_pattern(vglite_draw_task_t * vglite_task, const lv_area_t * clip_area, - const lv_area_t * coords, - const lv_draw_image_dsc_t * dsc); - -/** - * BLock Image Transfer - copy rectangular image from src_buf to dest_buf with or without effects. - * - * @param[in] src_area Source area with relative coordinates to src buffer - * @param[in] dsc Image descriptor - * - */ -static void _vglite_blit(const lv_area_t * src_area, const lv_draw_image_dsc_t * dsc); - -static vg_lite_color_t _vglite_recolor(const lv_draw_image_dsc_t * dsc); - -/********************** - * STATIC VARIABLES - **********************/ - -/********************** - * MACROS - **********************/ - -/********************** - * GLOBAL FUNCTIONS - **********************/ - -void lv_draw_vglite_img(vglite_draw_task_t * vglite_task) -{ - const lv_draw_image_dsc_t * dsc = vglite_task->t->draw_dsc; - const lv_area_t * coords = &vglite_task->t->area; - - if(dsc->opa <= (lv_opa_t)LV_OPA_MIN) - return; - - lv_layer_t * layer = vglite_task->t->target_layer; - const lv_image_dsc_t * img_dsc = dsc->src; - - lv_area_t relative_coords; - lv_area_copy(&relative_coords, coords); - lv_area_move(&relative_coords, -layer->buf_area.x1, -layer->buf_area.y1); - - lv_area_t clip_area; - lv_area_copy(&clip_area, &vglite_task->t->clip_area); - lv_area_move(&clip_area, -layer->buf_area.x1, -layer->buf_area.y1); - - lv_area_t blend_area; - bool has_transform = (dsc->rotation != 0 || dsc->scale_x != LV_SCALE_NONE || dsc->scale_y != LV_SCALE_NONE); - if(has_transform) - lv_area_copy(&blend_area, &relative_coords); - else if(!lv_area_intersect(&blend_area, &relative_coords, &clip_area)) - return; /*Fully clipped, nothing to do*/ - - const void * src_buf = img_dsc->data; - - lv_area_t src_area; - src_area.x1 = blend_area.x1 - (coords->x1 - layer->buf_area.x1); - src_area.y1 = blend_area.y1 - (coords->y1 - layer->buf_area.y1); - src_area.x2 = img_dsc->header.w - 1; - src_area.y2 = img_dsc->header.h - 1; - - lv_color_format_t src_cf = img_dsc->header.cf; - uint32_t src_stride = img_dsc->header.stride; - - /* Set src_buf structure. */ - vglite_set_src_buf(src_buf, img_dsc->header.w, img_dsc->header.h, src_stride, src_cf); - -#if LV_USE_VGLITE_BLIT_SPLIT - void * dest_buf = layer->draw_buf->data; - uint32_t dest_stride = layer->draw_buf->header.stride; - lv_color_format_t dest_cf = layer->draw_buf->header.cf; - - if(!has_transform) - _vglite_blit_split(dest_buf, &blend_area, dest_stride, dest_cf, - src_buf, &src_area, src_stride, src_cf, dsc); -#else - vglite_set_transformation_matrix(&blend_area, dsc); - bool is_tiled = dsc->tile; - if(is_tiled) - _vglite_draw_pattern(vglite_task, &clip_area, &relative_coords, dsc); - else - _vglite_blit(&src_area, dsc); -#endif /*LV_USE_VGLITE_BLIT_SPLIT*/ -} - -/********************** - * STATIC FUNCTIONS - **********************/ -static void _vglite_blit(const lv_area_t * src_area, const lv_draw_image_dsc_t * dsc) -{ - vg_lite_buffer_t * dest_buf = vglite_get_dest_buf(); - vg_lite_buffer_t * src_buf = vglite_get_src_buf(); - - vg_lite_rectangle_t rect = { - .x = (vg_lite_int32_t)src_area->x1, - .y = (vg_lite_int32_t)src_area->y1, - .width = (vg_lite_int32_t)lv_area_get_width(src_area), - .height = (vg_lite_int32_t)lv_area_get_height(src_area) - }; - - src_buf->image_mode = VG_LITE_MULTIPLY_IMAGE_MODE; - src_buf->transparency_mode = VG_LITE_IMAGE_TRANSPARENT; - - vg_lite_color_t vgcol = _vglite_recolor(dsc); - - vg_lite_matrix_t * matrix = vglite_get_matrix(); - vg_lite_blend_t vgblend = vglite_get_blend_mode(dsc->blend_mode); - - VGLITE_CHECK_ERROR(vg_lite_blit_rect(dest_buf, src_buf, &rect, matrix, vgblend, vgcol, VG_LITE_FILTER_POINT)); - - vglite_run(); -} - -#if LV_USE_VGLITE_BLIT_SPLIT -static void _move_buf_close_to_area(void ** buf, lv_area_t * area, uint32_t stride, lv_color_format_t cf) -{ - uint8_t ** buf_u8 = (uint8_t **)buf; - uint8_t align_bytes = vglite_get_stride_alignment(cf); - uint8_t bits_per_pixel = lv_color_format_get_bpp(cf); - - uint16_t align_pixels = align_bytes * 8 / bits_per_pixel; - - if(area->x1 >= (int32_t)(area->x1 % align_pixels)) { - uint16_t shift_x = area->x1 - (area->x1 % align_pixels); - - area->x1 -= shift_x; - area->x2 -= shift_x; - *buf_u8 += (shift_x * bits_per_pixel) / 8; - } - - if(area->y1) { - uint16_t shift_y = area->y1; - - area->y1 -= shift_y; - area->y2 -= shift_y; - *buf_u8 += shift_y * stride; - } -} - -static void _vglite_blit_split(void * dest_buf, lv_area_t * dest_area, uint32_t dest_stride, lv_color_format_t dest_cf, - const void * src_buf, lv_area_t * src_area, uint32_t src_stride, lv_color_format_t src_cf, - const lv_draw_image_dsc_t * dsc) -{ - VGLITE_TRACE("Blit " - "Area: ([%d,%d], [%d,%d]) -> ([%d,%d], [%d,%d]) | " - "Size: ([%dx%d] -> [%dx%d]) | " - "Addr: (0x%x -> 0x%x)", - src_area->x1, src_area->y1, src_area->x2, src_area->y2, - dest_area->x1, dest_area->y1, dest_area->x2, dest_area->y2, - lv_area_get_width(src_area), lv_area_get_height(src_area), - lv_area_get_width(dest_area), lv_area_get_height(dest_area), - (uintptr_t)src_buf, (uintptr_t)dest_buf); - - /* Move starting pointers as close as possible to [x1, y1], so coordinates are as small as possible */ - _move_buf_close_to_area((void **)&src_buf, src_area, src_stride, src_cf); - _move_buf_close_to_area(&dest_buf, dest_area, dest_stride, dest_cf); - - /* Set clip area */ - vglite_set_scissor(dest_area); - - /* If we're in limit, do a single BLIT */ - if((src_area->x2 < VGLITE_BLIT_SPLIT_THR) && - (src_area->y2 < VGLITE_BLIT_SPLIT_THR)) { - - /* Set new dest_buf and src_buf memory addresses */ - vglite_set_dest_buf_ptr(dest_buf); - vglite_set_src_buf_ptr(src_buf); - - vglite_set_transformation_matrix(dest_area, dsc); - _vglite_blit(src_area, dsc); - - VGLITE_TRACE("Single " - "Area: ([%d,%d], [%d,%d]) -> ([%d,%d], [%d,%d]) | " - "Size: ([%dx%d] -> [%dx%d]) | " - "Addr: (0x%x -> 0x%x)", - src_area->x1, src_area->y1, src_area->x2, src_area->y2, - dest_area->x1, dest_area->y1, dest_area->x2, dest_area->y2, - lv_area_get_width(src_area), lv_area_get_height(src_area), - lv_area_get_width(dest_area), lv_area_get_height(dest_area), - (uintptr_t)src_buf, (uintptr_t)dest_buf); - - return; - }; - - /* Split the BLIT into multiple tiles */ - VGLITE_TRACE("Split " - "Area: ([%d,%d], [%d,%d]) -> ([%d,%d], [%d,%d]) | " - "Size: ([%dx%d] -> [%dx%d]) | " - "Addr: (0x%x -> 0x%x)", - src_area->x1, src_area->y1, src_area->x2, src_area->y2, - dest_area->x1, dest_area->y1, dest_area->x2, dest_area->y2, - lv_area_get_width(src_area), lv_area_get_height(src_area), - lv_area_get_width(dest_area), lv_area_get_height(dest_area), - (uintptr_t)src_buf, (uintptr_t)dest_buf); - - int32_t width = LV_MIN(lv_area_get_width(src_area), lv_area_get_width(dest_area)); - int32_t height = LV_MIN(lv_area_get_height(src_area), lv_area_get_height(dest_area)); - - /* Number of tiles needed */ - uint8_t total_tiles_x = (src_area->x1 + width + VGLITE_BLIT_SPLIT_THR - 1) / - VGLITE_BLIT_SPLIT_THR; - uint8_t total_tiles_y = (src_area->y1 + height + VGLITE_BLIT_SPLIT_THR - 1) / - VGLITE_BLIT_SPLIT_THR; - - uint16_t shift_src_x = src_area->x1; - uint16_t shift_dest_x = dest_area->x1; - - VGLITE_TRACE("X shift: src: %d, dst: %d", shift_src_x, shift_dest_x); - - uint8_t * tile_dest_buf; - lv_area_t tile_dest_area; - const uint8_t * tile_src_buf; - lv_area_t tile_src_area; - - for(uint8_t y = 0; y < total_tiles_y; y++) { - /* y1 always start from 0 */ - tile_src_area.y1 = 0; - - /* Calculate y2 coordinates */ - if(y < total_tiles_y - 1) - tile_src_area.y2 = VGLITE_BLIT_SPLIT_THR - 1; - else - tile_src_area.y2 = height - y * VGLITE_BLIT_SPLIT_THR - 1; - - /* No vertical shift, dest y is always in sync with src y */ - tile_dest_area.y1 = tile_src_area.y1; - tile_dest_area.y2 = tile_src_area.y2; - - /* Advance start pointer for every tile, except the first column (y = 0) */ - tile_src_buf = (uint8_t *)src_buf + y * VGLITE_BLIT_SPLIT_THR * src_stride; - tile_dest_buf = (uint8_t *)dest_buf + y * VGLITE_BLIT_SPLIT_THR * dest_stride; - - for(uint8_t x = 0; x < total_tiles_x; x++) { - /* x1 always start from the same shift */ - tile_src_area.x1 = shift_src_x; - tile_dest_area.x1 = shift_dest_x; - if(x > 0) { - /* Advance start pointer for every tile, except the first raw (x = 0) */ - tile_src_buf += VGLITE_BLIT_SPLIT_THR * lv_color_format_get_bpp(src_cf) / 8; - tile_dest_buf += VGLITE_BLIT_SPLIT_THR * lv_color_format_get_bpp(dest_cf) / 8; - } - - /* Calculate x2 coordinates */ - if(x < total_tiles_x - 1) - tile_src_area.x2 = VGLITE_BLIT_SPLIT_THR - 1; - else - tile_src_area.x2 = width - x * VGLITE_BLIT_SPLIT_THR - 1; - - tile_dest_area.x2 = tile_src_area.x2; - - /* Shift x2 coordinates */ - tile_src_area.x2 += shift_src_x; - tile_dest_area.x2 += shift_dest_x; - - /* Set new dest_buf and src_buf memory addresses */ - vglite_set_dest_buf_ptr(tile_dest_buf); - vglite_set_src_buf_ptr(tile_src_buf); - - vglite_set_transformation_matrix(&tile_dest_area, dsc); - _vglite_blit(&tile_src_area, dsc); - - VGLITE_TRACE("Tile [%d, %d] " - "Area: ([%d,%d], [%d,%d]) -> ([%d,%d], [%d,%d]) | " - "Size: ([%dx%d] -> [%dx%d]) | " - "Addr: (0x%x -> 0x%x)", - x, y, - tile_src_area.x1, tile_src_area.y1, tile_src_area.x2, tile_src_area.y2, - tile_dest_area.x1, tile_dest_area.y1, tile_dest_area.x2, tile_dest_area.y2, - lv_area_get_width(&tile_src_area), lv_area_get_height(&tile_src_area), - lv_area_get_width(&tile_dest_area), lv_area_get_height(&tile_dest_area), - (uintptr_t)tile_src_buf, (uintptr_t)tile_dest_buf); - } - } -} -#endif /*LV_USE_VGLITE_BLIT_SPLIT*/ - -static void _vglite_draw_pattern(vglite_draw_task_t * vglite_task, const lv_area_t * clip_area, - const lv_area_t * coords, - const lv_draw_image_dsc_t * dsc) -{ - /* Target buffer */ - vg_lite_buffer_t * dest_buf = vglite_get_dest_buf(); - - /* Path to draw */ - int32_t * path_data = lv_malloc_zeroed(RECT_PATH_DATA_MAX_SIZE * sizeof(int32_t)); - LV_ASSERT_MALLOC(path_data); - vglite_task->path_data = path_data; - - uint32_t path_data_size; - vglite_create_rect_path_data(path_data, &path_data_size, dsc->clip_radius, coords); - vg_lite_quality_t path_quality = VG_LITE_MEDIUM; - - vg_lite_path_t * path = lv_malloc_zeroed(sizeof(vg_lite_path_t)); - LV_ASSERT_MALLOC(path); - vglite_task->path = path; - VGLITE_CHECK_ERROR(vg_lite_init_path(path, VG_LITE_S32, path_quality, path_data_size, path_data, - (vg_lite_float_t)clip_area->x1, (vg_lite_float_t)clip_area->y1, - ((vg_lite_float_t)clip_area->x2) + 1.0f, ((vg_lite_float_t)clip_area->y2) + 1.0f)); - - /* Pattern Image */ - vg_lite_buffer_t * src_buf = vglite_get_src_buf(); - src_buf->image_mode = VG_LITE_MULTIPLY_IMAGE_MODE; - src_buf->transparency_mode = VG_LITE_IMAGE_TRANSPARENT; - - /* Pattern matrix */ - vg_lite_matrix_t matrix; - vg_lite_identity(&matrix); - vg_lite_translate((vg_lite_float_t)dsc->image_area.x1, (vg_lite_float_t)dsc->image_area.y1, &matrix); - - /* Blend mode */ - vg_lite_blend_t vgblend = vglite_get_blend_mode(dsc->blend_mode); - - vg_lite_color_t vgcol = _vglite_recolor(dsc); - - /* Filter */ - bool has_transform = (dsc->rotation != 0 || dsc->scale_x != LV_SCALE_NONE || dsc->scale_y != LV_SCALE_NONE); - vg_lite_filter_t filter = has_transform ? VG_LITE_FILTER_BI_LINEAR : VG_LITE_FILTER_POINT; - - /* Draw Pattern */ - VGLITE_CHECK_ERROR(vg_lite_draw_pattern(dest_buf, path, VG_LITE_FILL_NON_ZERO, NULL, - src_buf, &matrix, vgblend, VG_LITE_PATTERN_REPEAT, - 0, vgcol, filter)); - vglite_run(); -} - -static vg_lite_color_t _vglite_recolor(const lv_draw_image_dsc_t * dsc) -{ - lv_color_t color; - lv_opa_t opa; - - bool has_recolor = (dsc->recolor_opa > LV_OPA_MIN); - if(has_recolor) { - color = dsc->recolor; - opa = LV_OPA_MIX2(dsc->recolor_opa, dsc->opa); - } - else { - color.red = 0xFF; - color.green = 0xFF; - color.blue = 0xFF; - opa = dsc->opa; - } - - lv_color32_t col32 = lv_color_to_32(color, opa); - - return vglite_get_color(col32, false); -} - -#endif /*LV_USE_DRAW_VGLITE*/ diff --git a/src/draw/nxp/vglite/lv_draw_vglite_label.c b/src/draw/nxp/vglite/lv_draw_vglite_label.c deleted file mode 100644 index da6a6ce8e7..0000000000 --- a/src/draw/nxp/vglite/lv_draw_vglite_label.c +++ /dev/null @@ -1,270 +0,0 @@ -/** - * @file lv_draw_vglite_label.c - * - */ - -/** - * Copyright 2023-2024 NXP - * - * SPDX-License-Identifier: MIT - */ - -/********************* - * INCLUDES - *********************/ - -#include "lv_draw_vglite.h" - -#if LV_USE_DRAW_VGLITE -#include "lv_vglite_buf.h" -#include "lv_vglite_matrix.h" -#include "lv_vglite_utils.h" - -#include "../../lv_draw_label_private.h" -#include "../../../stdlib/lv_string.h" -#include "../../../font/lv_font_fmt_txt_private.h" - -/********************* - * DEFINES - *********************/ - -/********************** - * TYPEDEFS - **********************/ - -/********************** - * STATIC PROTOTYPES - **********************/ - -static void _draw_vglite_letter(lv_draw_task_t * t, lv_draw_glyph_dsc_t * glyph_draw_dsc, - lv_draw_fill_dsc_t * fill_draw_dsc, const lv_area_t * fill_area); - -/** - * Draw letter (character bitmap blend) with optional color and opacity - * - * @param[in] mask_area Mask area with relative coordinates of source buffer - * @param[in] color Color - * @param[in] opa Opacity - * - */ -static void _vglite_draw_letter(const lv_area_t * mask_area, lv_color_t color, lv_opa_t opa); - -/********************** - * STATIC VARIABLES - **********************/ - -static bool _use_static_bitmap = false; - -/********************** - * GLOBAL VARIABLES - **********************/ - -/********************** - * MACROS - **********************/ - -/********************** - * GLOBAL FUNCTIONS - **********************/ - -void lv_draw_vglite_label(vglite_draw_task_t * vglite_task) -{ - const lv_draw_label_dsc_t * dsc = vglite_task->t->draw_dsc; - const lv_area_t * coords = &vglite_task->t->area; - - if(dsc->opa <= LV_OPA_MIN) return; - - lv_font_fmt_txt_dsc_t * fdsc = (lv_font_fmt_txt_dsc_t *)dsc->font->dsc; - bool is_src_buf_aligned = vglite_src_buf_aligned(fdsc->glyph_bitmap, fdsc->stride, LV_COLOR_FORMAT_A8); - bool has_static_bitmap = lv_font_has_static_bitmap(dsc->font); - - _use_static_bitmap = is_src_buf_aligned & has_static_bitmap; - - lv_draw_label_iterate_characters(vglite_task->t, dsc, coords, _draw_vglite_letter); -} - -/********************** - * STATIC FUNCTIONS - **********************/ - -static void _draw_vglite_letter(lv_draw_task_t * t, lv_draw_glyph_dsc_t * glyph_draw_dsc, - lv_draw_fill_dsc_t * fill_draw_dsc, const lv_area_t * fill_area) -{ - if(glyph_draw_dsc) { - - switch(glyph_draw_dsc->format) { - - case LV_FONT_GLYPH_FORMAT_NONE: { -#if LV_USE_FONT_PLACEHOLDER - /* Draw a placeholder rectangle*/ - vglite_draw_task_t * vglite_task = lv_malloc_zeroed(sizeof(vglite_draw_task_t)); - LV_ASSERT_MALLOC(vglite_task); - - lv_draw_border_dsc_t border_draw_dsc; - - lv_draw_border_dsc_init(&border_draw_dsc); - border_draw_dsc.opa = glyph_draw_dsc->opa; - border_draw_dsc.color = glyph_draw_dsc->color; - border_draw_dsc.width = 1; - - vglite_task->t = t; - vglite_task->t->draw_dsc = &border_draw_dsc; - vglite_task->t->area = *glyph_draw_dsc->bg_coords; - - lv_draw_vglite_border(vglite_task); - - /** Cleanup for vglite_task */ - VGLITE_CHECK_ERROR(vg_lite_finish()); - if(vglite_task->path) { - VGLITE_CHECK_ERROR(vg_lite_clear_path(vglite_task->path)); - lv_free(vglite_task->path_data); - lv_free(vglite_task->path); - } - lv_free(vglite_task); -#endif - } - break; - case LV_FONT_GLYPH_FORMAT_A1 ... LV_FONT_GLYPH_FORMAT_A8: { - /*Do not draw transparent things*/ - if(glyph_draw_dsc->opa <= LV_OPA_MIN) - return; - - lv_layer_t * layer = t->target_layer; - - lv_area_t blend_area; - if(!lv_area_intersect(&blend_area, glyph_draw_dsc->letter_coords, &t->clip_area)) - return; - lv_area_move(&blend_area, -layer->buf_area.x1, -layer->buf_area.y1); - - const void * mask_buf = NULL; - const lv_draw_buf_t * draw_buf = NULL; - uint32_t mask_stride; - if(!_use_static_bitmap) { - draw_buf = lv_font_get_glyph_bitmap(glyph_draw_dsc->g, glyph_draw_dsc->_draw_buf); - if(draw_buf != NULL) { - mask_buf = draw_buf->data; - } - else { - return; - } - mask_stride = draw_buf->header.stride; - } - else { - glyph_draw_dsc->g->req_raw_bitmap = 1; - mask_buf = lv_font_get_glyph_static_bitmap(glyph_draw_dsc->g); - mask_stride = glyph_draw_dsc->g->stride; - } - - uint32_t mask_width = lv_area_get_width(glyph_draw_dsc->letter_coords); - uint32_t mask_height = lv_area_get_height(glyph_draw_dsc->letter_coords); - - lv_area_t mask_area; - mask_area.x1 = blend_area.x1 - (glyph_draw_dsc->letter_coords->x1 - layer->buf_area.x1); - mask_area.y1 = blend_area.y1 - (glyph_draw_dsc->letter_coords->y1 - layer->buf_area.y1); - mask_area.x2 = mask_width - 1; - mask_area.y2 = mask_height - 1; - - /* Set src_buf structure. */ - vglite_set_src_buf(mask_buf, mask_width, mask_height, mask_stride, LV_COLOR_FORMAT_A8); - - /* Set matrix. */ - vglite_set_translation_matrix(&blend_area); - - if(!_use_static_bitmap) - lv_draw_buf_invalidate_cache(draw_buf, &mask_area); - - _vglite_draw_letter(&mask_area, glyph_draw_dsc->color, glyph_draw_dsc->opa); - } - break; - case LV_FONT_GLYPH_FORMAT_IMAGE: { -#if LV_USE_IMGFONT - glyph_draw_dsc->glyph_data = lv_font_get_glyph_bitmap(glyph_draw_dsc->g, glyph_draw_dsc->_draw_buf); - vglite_draw_task_t * vglite_task = lv_malloc_zeroed(sizeof(vglite_draw_task_t)); - LV_ASSERT_MALLOC(vglite_task); - - lv_draw_image_dsc_t img_dsc; - lv_draw_image_dsc_init(&img_dsc); - img_dsc.opa = glyph_draw_dsc->opa; - img_dsc.src = glyph_draw_dsc->glyph_data; - - void * old_dsc = t->draw_dsc; - lv_area_t old_area = t->area; - - t->draw_dsc = &img_dsc; - t->area = *glyph_draw_dsc->letter_coords; - vglite_task->t = t; - - lv_draw_vglite_img(vglite_task); - - /** Cleanup for vglite_task */ - vg_lite_finish(); - if(vglite_task->path) { - VGLITE_CHECK_ERROR(vg_lite_clear_path(vglite_task->path)); - lv_free(vglite_task->path_data); - lv_free(vglite_task->path); - } - lv_free(vglite_task); - - t->draw_dsc = old_dsc; - t->area = old_area; -#endif - } - break; - default: - break; - } - } - - if(fill_draw_dsc && fill_area) { - vglite_draw_task_t * vglite_task = lv_malloc_zeroed(sizeof(vglite_draw_task_t)); - LV_ASSERT_MALLOC(vglite_task); - - t->draw_dsc = fill_draw_dsc; - t->area = *fill_area; - vglite_task->t = t; - - lv_draw_vglite_fill(vglite_task); - - /** Cleanup for vglite_task */ - vg_lite_finish(); - if(vglite_task->path) { - VGLITE_CHECK_ERROR(vg_lite_clear_path(vglite_task->path)); - lv_free(vglite_task->path_data); - lv_free(vglite_task->path); - } - if(vglite_task->gradient) { - VGLITE_CHECK_ERROR(vg_lite_clear_grad(vglite_task->gradient)); - lv_free(vglite_task->gradient); - } - lv_free(vglite_task); - } -} - -static void _vglite_draw_letter(const lv_area_t * mask_area, lv_color_t color, lv_opa_t opa) -{ - vg_lite_buffer_t * dest_buf = vglite_get_dest_buf(); - vg_lite_buffer_t * mask_buf = vglite_get_src_buf(); - - mask_buf->image_mode = VG_LITE_MULTIPLY_IMAGE_MODE; - mask_buf->transparency_mode = VG_LITE_IMAGE_TRANSPARENT; - - vg_lite_rectangle_t rect = { - .x = (vg_lite_int32_t)mask_area->x1, - .y = (vg_lite_int32_t)mask_area->y1, - .width = (vg_lite_int32_t)lv_area_get_width(mask_area), - .height = (vg_lite_int32_t)lv_area_get_height(mask_area) - }; - - lv_color32_t col32 = lv_color_to_32(color, opa); - vg_lite_color_t vgcol = vglite_get_color(col32, false); - - vg_lite_matrix_t * matrix = vglite_get_matrix(); - - /*Blit with font color as paint color*/ - VGLITE_CHECK_ERROR(vg_lite_blit_rect(dest_buf, mask_buf, &rect, matrix, VG_LITE_BLEND_SRC_OVER, vgcol, - VG_LITE_FILTER_POINT)); - - vglite_run(); -} - -#endif /*LV_USE_DRAW_VGLITE*/ diff --git a/src/draw/nxp/vglite/lv_draw_vglite_layer.c b/src/draw/nxp/vglite/lv_draw_vglite_layer.c deleted file mode 100644 index 559b1107c4..0000000000 --- a/src/draw/nxp/vglite/lv_draw_vglite_layer.c +++ /dev/null @@ -1,156 +0,0 @@ -/** - * @file lv_draw_vglite_layer.c - * - */ - -/** - * Copyright 2023-2024 NXP - * - * SPDX-License-Identifier: MIT - */ - -/********************* - * INCLUDES - *********************/ - -#include "lv_draw_vglite.h" - -#if LV_USE_DRAW_VGLITE - -#include "../../../stdlib/lv_string.h" -#include "../../../core/lv_global.h" - -/********************* - * DEFINES - *********************/ - -/********************** - * TYPEDEFS - **********************/ - -/********************** - * STATIC PROTOTYPES - **********************/ - -/********************** - * STATIC VARIABLES - **********************/ - -#define _draw_info LV_GLOBAL_DEFAULT()->draw_info - -/********************** - * MACROS - **********************/ - -/********************** - * GLOBAL FUNCTIONS - **********************/ - -void lv_draw_vglite_layer(vglite_draw_task_t * vglite_task) -{ - lv_draw_image_dsc_t * draw_dsc = vglite_task->t->draw_dsc; - - lv_layer_t * layer_to_draw = (lv_layer_t *)draw_dsc->src; - const lv_draw_buf_t * draw_buf = layer_to_draw->draw_buf; - - /* It can happen that nothing was draw on a layer and therefore its buffer is not allocated. - * In this case just return. - */ - if(draw_buf == NULL) - return; - - if(_draw_info.unit_cnt > 1) { - const lv_area_t area_to_draw = { - .x1 = 0, - .y1 = 0, - .x2 = draw_buf->header.w - 1, - .y2 = draw_buf->header.h - 1 - }; - lv_draw_buf_invalidate_cache(draw_buf, &area_to_draw); - } - - lv_draw_image_dsc_t new_draw_dsc = *draw_dsc; - new_draw_dsc.src = draw_buf; - vglite_task->t->draw_dsc = &new_draw_dsc; - lv_draw_vglite_img(vglite_task); - vglite_task->t->draw_dsc = draw_dsc; - -#if LV_USE_LAYER_DEBUG || LV_USE_PARALLEL_DRAW_DEBUG - const lv_area_t * coords = &vglite_task->t->area; - lv_area_t area_rot; - lv_area_copy(&area_rot, coords); - bool has_transform = (draw_dsc->rotation != 0 || draw_dsc->scale_x != LV_SCALE_NONE || - draw_dsc->scale_y != LV_SCALE_NONE); - - if(has_transform) { - int32_t w = lv_area_get_width(coords); - int32_t h = lv_area_get_height(coords); - - lv_image_buf_get_transformed_area(&area_rot, w, h, draw_dsc->rotation, draw_dsc->scale_x, draw_dsc->scale_y, - &draw_dsc->pivot); - - area_rot.x1 += coords->x1; - area_rot.y1 += coords->y1; - area_rot.x2 += coords->x1; - area_rot.y2 += coords->y1; - } - lv_area_t draw_area; - if(!lv_area_intersect(&draw_area, &area_rot, &vglite_task->t->clip_area)) return; -#endif - -#if LV_USE_LAYER_DEBUG - lv_draw_fill_dsc_t fill_dsc; - lv_draw_fill_dsc_init(&fill_dsc); - fill_dsc.color = lv_color_hex(layer_to_draw->color_format == LV_COLOR_FORMAT_ARGB8888 ? 0xff0000 : 0x00ff00); - fill_dsc.opa = LV_OPA_20; - lv_draw_sw_fill(vglite_task->t, &fill_dsc, &area_rot); - - lv_draw_border_dsc_t border_dsc; - lv_draw_border_dsc_init(&border_dsc); - border_dsc.color = fill_dsc.color; - border_dsc.opa = LV_OPA_60; - border_dsc.width = 2; - lv_draw_sw_border(vglite_task->t, &border_dsc, &area_rot); - -#endif - -#if LV_USE_PARALLEL_DRAW_DEBUG - int32_t idx = vglite_task->t->draw_unit->idx; - - lv_draw_fill_dsc_t fill_dsc; - lv_draw_rect_dsc_init(&fill_dsc); - fill_dsc.color = lv_palette_main(idx % LV_PALETTE_LAST); - fill_dsc.opa = LV_OPA_10; - lv_draw_sw_fill(vglite_task->t, &fill_dsc, &area_rot); - - lv_draw_border_dsc_t border_dsc; - lv_draw_border_dsc_init(&border_dsc); - border_dsc.color = lv_palette_main(idx % LV_PALETTE_LAST); - border_dsc.opa = LV_OPA_100; - border_dsc.width = 2; - lv_draw_sw_border(vglite_task->t, &border_dsc, &area_rot); - - lv_point_t txt_size; - lv_text_get_size(&txt_size, "W", LV_FONT_DEFAULT, 0, 0, 100, LV_TEXT_FLAG_NONE); - - lv_area_t txt_area; - txt_area.x1 = draw_area.x1; - txt_area.x2 = draw_area.x1 + txt_size.x - 1; - txt_area.y2 = draw_area.y2; - txt_area.y1 = draw_area.y2 - txt_size.y + 1; - - lv_draw_fill_dsc_init(&fill_dsc); - fill_dsc.color = lv_color_black(); - lv_draw_sw_fill(vglite_task->t, &fill_dsc, &txt_area); - - char buf[8]; - lv_snprintf(buf, sizeof(buf), "%d", idx); - lv_draw_label_dsc_t label_dsc; - lv_draw_label_dsc_init(&label_dsc); - label_dsc.color = lv_color_white(); - label_dsc.text = buf; - lv_draw_sw_label(vglite_task->t, &label_dsc, &txt_area); -#endif -} - -#endif /*LV_USE_DRAW_VGLITE*/ diff --git a/src/draw/nxp/vglite/lv_draw_vglite_line.c b/src/draw/nxp/vglite/lv_draw_vglite_line.c deleted file mode 100644 index 105b7add8a..0000000000 --- a/src/draw/nxp/vglite/lv_draw_vglite_line.c +++ /dev/null @@ -1,169 +0,0 @@ -/** - * @file lv_draw_vglite_line.c - * - */ - -/** - * Copyright 2022-2024 NXP - * - * SPDX-License-Identifier: MIT - */ - -/********************* - * INCLUDES - *********************/ - -#include "lv_draw_vglite.h" - -#if LV_USE_DRAW_VGLITE -#include "lv_vglite_buf.h" -#include "lv_vglite_utils.h" - -/********************* - * DEFINES - *********************/ - -/********************** - * TYPEDEFS - **********************/ - -/********************** - * STATIC PROTOTYPES - **********************/ - -/** - * Set line path data - * - * @param[in/out] line_path Coordinates of the line - * @param[in/out] path_data_size Size of path_data (bytes) - * @param[in] p1 First point of the line - * @patam[in] p2 Second point of the line - * - */ -static void _vglite_set_line(int32_t * line_path, uint32_t * path_data_size, - const lv_point_t * point1, const lv_point_t * point2); - -/** - * Draw line shape with effects - * - * @param[in] point1 Starting point with relative coordinates - * @param[in] point2 Ending point with relative coordinates - * @param[in] clip_area Clip area with relative coordinates to dest buff - * @param[in] dsc Line description structure (width, rounded ending, opacity, ...) - * - */ -static void _vglite_draw_line(vglite_draw_task_t * vglite_task, const lv_point_t * point1, const lv_point_t * point2, - const lv_area_t * clip_area, const lv_draw_line_dsc_t * dsc); - -/********************** - * STATIC VARIABLES - **********************/ - -/********************** - * MACROS - **********************/ - -/********************** - * GLOBAL FUNCTIONS - **********************/ - -void lv_draw_vglite_line(vglite_draw_task_t * vglite_task) -{ - const lv_draw_line_dsc_t * dsc = vglite_task->t->draw_dsc; - - if(dsc->width == 0) - return; - if(dsc->opa <= (lv_opa_t)LV_OPA_MIN) - return; - if(dsc->p1.x == dsc->p2.x && dsc->p1.y == dsc->p2.y) - return; - - lv_layer_t * layer = vglite_task->t->target_layer; - lv_area_t clip_area; - clip_area.x1 = LV_MIN(dsc->p1.x, dsc->p2.x) - dsc->width / 2; - clip_area.x2 = LV_MAX(dsc->p1.x, dsc->p2.x) + dsc->width / 2; - clip_area.y1 = LV_MIN(dsc->p1.y, dsc->p2.y) - dsc->width / 2; - clip_area.y2 = LV_MAX(dsc->p1.y, dsc->p2.y) + dsc->width / 2; - - if(!lv_area_intersect(&clip_area, &clip_area, &vglite_task->t->clip_area)) - return; /*Fully clipped, nothing to do*/ - - lv_area_move(&clip_area, -layer->buf_area.x1, -layer->buf_area.y1); - - lv_point_t point1 = {dsc->p1.x - layer->buf_area.x1, dsc->p1.y - layer->buf_area.y1}; - lv_point_t point2 = {dsc->p2.x - layer->buf_area.x1, dsc->p2.y - layer->buf_area.y1}; - - _vglite_draw_line(vglite_task, &point1, &point2, &clip_area, dsc); -} - -/********************** - * STATIC FUNCTIONS - **********************/ - -static void _vglite_set_line(int32_t * line_path, uint32_t * path_data_size, const lv_point_t * point1, - const lv_point_t * point2) -{ - uint32_t pidx = 0; - line_path[pidx++] = VLC_OP_MOVE; - line_path[pidx++] = point1->x; - line_path[pidx++] = point1->y; - line_path[pidx++] = VLC_OP_LINE; - line_path[pidx++] = point2->x; - line_path[pidx++] = point2->y; - line_path[pidx++] = VLC_OP_END; - - *path_data_size = pidx * sizeof(int32_t); -} - -static void _vglite_draw_line(vglite_draw_task_t * vglite_task, const lv_point_t * point1, const lv_point_t * point2, - const lv_area_t * clip_area, const lv_draw_line_dsc_t * dsc) -{ - vg_lite_path_t * path = lv_malloc_zeroed(sizeof(vg_lite_path_t)); - LV_ASSERT_MALLOC(path); - vglite_task->path = path; - vg_lite_buffer_t * dest_buf = vglite_get_dest_buf(); - vg_lite_cap_style_t cap_style = (dsc->round_start || dsc->round_end) ? VG_LITE_CAP_ROUND : VG_LITE_CAP_BUTT; - vg_lite_join_style_t join_style = (dsc->round_start || dsc->round_end) ? VG_LITE_JOIN_ROUND : VG_LITE_JOIN_MITER; - - bool is_dashed = (dsc->dash_width && dsc->dash_gap); - - vg_lite_float_t stroke_dash_pattern[2] = {0, 0}; - uint32_t stroke_dash_count = 0; - vg_lite_float_t stroke_dash_phase = 0; - if(is_dashed) { - stroke_dash_pattern[0] = (vg_lite_float_t)dsc->dash_width; - stroke_dash_pattern[1] = (vg_lite_float_t)dsc->dash_gap; - stroke_dash_count = sizeof(stroke_dash_pattern) / sizeof(vg_lite_float_t); - stroke_dash_phase = (vg_lite_float_t)dsc->dash_width / 2; - } - - /*** Init path ***/ - int32_t width = dsc->width; - - uint32_t path_data_size = 0; - int32_t * line_path = lv_malloc_zeroed(7 * sizeof(int32_t)); - LV_ASSERT_MALLOC(line_path); - vglite_task->path_data = line_path; - _vglite_set_line(line_path, &path_data_size, point1, point2); - - VGLITE_CHECK_ERROR(vg_lite_init_path(path, VG_LITE_S32, VG_LITE_HIGH, path_data_size, line_path, - (vg_lite_float_t)clip_area->x1, (vg_lite_float_t)clip_area->y1, - ((vg_lite_float_t)clip_area->x2) + 1.0f, ((vg_lite_float_t)clip_area->y2) + 1.0f)); - - lv_color32_t col32 = lv_color_to_32(dsc->color, dsc->opa); - vg_lite_color_t vgcol = vglite_get_color(col32, false); - - /*** Draw line ***/ - VGLITE_CHECK_ERROR(vg_lite_set_draw_path_type(path, VG_LITE_DRAW_STROKE_PATH)); - - VGLITE_CHECK_ERROR(vg_lite_set_stroke(path, cap_style, join_style, width, 8, stroke_dash_pattern, stroke_dash_count, - stroke_dash_phase, vgcol)); - - VGLITE_CHECK_ERROR(vg_lite_update_stroke(path)); - - VGLITE_CHECK_ERROR(vg_lite_draw(dest_buf, path, VG_LITE_FILL_NON_ZERO, NULL, VG_LITE_BLEND_SRC_OVER, vgcol)); - - vglite_run(); -} - -#endif /*LV_USE_DRAW_VGLITE*/ diff --git a/src/draw/nxp/vglite/lv_draw_vglite_triangle.c b/src/draw/nxp/vglite/lv_draw_vglite_triangle.c deleted file mode 100644 index 95da987909..0000000000 --- a/src/draw/nxp/vglite/lv_draw_vglite_triangle.c +++ /dev/null @@ -1,214 +0,0 @@ -/** - * @file lv_draw_vglite_triangle.c - * - */ - -/** - * Copyright 2023-2024 NXP - * - * SPDX-License-Identifier: MIT - */ - -/********************* - * INCLUDES - *********************/ - -#include "lv_draw_vglite.h" - -#if LV_USE_DRAW_VGLITE -#include "lv_vglite_buf.h" -#include "lv_vglite_path.h" -#include "lv_vglite_utils.h" - -#include "../../../stdlib/lv_string.h" - -/********************* - * DEFINES - *********************/ - -/********************** - * TYPEDEFS - **********************/ - -/********************** - * STATIC PROTOTYPES - **********************/ - -/** - * Set triangle path data - * - * @param[in/out] path_data Coordinates of the triangle - * @param[in/out] path_data_size Size of path_data (bytes) - * @param[in] p Points of the triangle - * - */ -static void _vglite_set_triangle(int32_t * path_data, uint32_t * path_data_size, - const lv_point_precise_t * p); - -/** - * Draw triangle shape with effects (opacity, gradient) - * - * @param[in] vglite_task The current vglite task - * @param[in] coords Coordinates of the triangle (relative to dest buff) - * @param[in] clip_area Clipping area with relative coordinates to dest buff - * @param[in] dsc Description of the triangle - * - */ -static void _vglite_draw_triangle(vglite_draw_task_t * vglite_task, const lv_area_t * coords, - const lv_area_t * clip_area, - const lv_draw_triangle_dsc_t * dsc); - -/********************** - * STATIC VARIABLES - **********************/ - -/********************** - * MACROS - **********************/ - -/********************** - * GLOBAL FUNCTIONS - **********************/ - -void lv_draw_vglite_triangle(vglite_draw_task_t * vglite_task) -{ - const lv_draw_triangle_dsc_t * dsc = vglite_task->t->draw_dsc; - - if(dsc->opa <= (lv_opa_t)LV_OPA_MIN) - return; - - lv_layer_t * layer = vglite_task->t->target_layer; - lv_area_t clip_area; - lv_area_copy(&clip_area, &vglite_task->t->clip_area); - lv_area_move(&clip_area, -layer->buf_area.x1, -layer->buf_area.y1); - - lv_area_t coords; - coords.x1 = (int32_t)LV_MIN3(dsc->p[0].x, dsc->p[1].x, dsc->p[2].x); - coords.y1 = (int32_t)LV_MIN3(dsc->p[0].y, dsc->p[1].y, dsc->p[2].y); - coords.x2 = (int32_t)LV_MAX3(dsc->p[0].x, dsc->p[1].x, dsc->p[2].x); - coords.y2 = (int32_t)LV_MAX3(dsc->p[0].y, dsc->p[1].y, dsc->p[2].y); - - lv_area_move(&coords, -layer->buf_area.x1, -layer->buf_area.y1); - - lv_area_t clipped_coords; - if(!lv_area_intersect(&clipped_coords, &coords, &clip_area)) - return; /* Fully clipped, nothing to do */ - - _vglite_draw_triangle(vglite_task, &coords, &clip_area, dsc); -} - -/********************** - * STATIC FUNCTIONS - **********************/ - -static void _vglite_set_triangle(int32_t * path_data, uint32_t * path_data_size, const lv_point_precise_t * p) -{ - uint32_t pidx = 0; - path_data[pidx++] = VLC_OP_MOVE; - path_data[pidx++] = p[0].x; - path_data[pidx++] = p[0].y; - path_data[pidx++] = VLC_OP_LINE; - path_data[pidx++] = p[1].x; - path_data[pidx++] = p[1].y; - path_data[pidx++] = VLC_OP_LINE; - path_data[pidx++] = p[2].x; - path_data[pidx++] = p[2].y; - path_data[pidx++] = VLC_OP_LINE; - path_data[pidx++] = p[0].x; - path_data[pidx++] = p[0].y; - path_data[pidx++] = VLC_OP_END; - - *path_data_size = pidx * sizeof(int32_t); -} - -static void _vglite_draw_triangle(vglite_draw_task_t * vglite_task, const lv_area_t * coords, - const lv_area_t * clip_area, - const lv_draw_triangle_dsc_t * dsc) -{ - vg_lite_buffer_t * dest_buf = vglite_get_dest_buf(); - - lv_area_t tri_area; - tri_area.x1 = (int32_t)LV_MIN3(dsc->p[0].x, dsc->p[1].x, dsc->p[2].x); - tri_area.y1 = (int32_t)LV_MIN3(dsc->p[0].y, dsc->p[1].y, dsc->p[2].y); - tri_area.x2 = (int32_t)LV_MAX3(dsc->p[0].x, dsc->p[1].x, dsc->p[2].x); - tri_area.y2 = (int32_t)LV_MAX3(dsc->p[0].y, dsc->p[1].y, dsc->p[2].y); - - uint32_t width = lv_area_get_width(&tri_area); - uint32_t height = lv_area_get_height(&tri_area); - - /* Init path */ - uint32_t path_data_size; - int32_t * triangle_path = lv_malloc_zeroed(13 * sizeof(int32_t)); - LV_ASSERT_MALLOC(triangle_path); - vglite_task->path_data = triangle_path; - _vglite_set_triangle(triangle_path, &path_data_size, dsc->p); - - - vg_lite_path_t * path = lv_malloc_zeroed(sizeof(vg_lite_path_t)); - LV_ASSERT_MALLOC(path); - vglite_task->path = path; - VGLITE_CHECK_ERROR(vg_lite_init_path(path, VG_LITE_S32, VG_LITE_HIGH, path_data_size, triangle_path, - (vg_lite_float_t)clip_area->x1, (vg_lite_float_t)clip_area->y1, - ((vg_lite_float_t)clip_area->x2) + 1.0f, ((vg_lite_float_t)clip_area->y2) + 1.0f)); - - /* Init Color */ - lv_color32_t col32 = lv_color_to_32(dsc->color, dsc->opa); - vg_lite_color_t vgcol = vglite_get_color(col32, false); - - vg_lite_linear_gradient_t * gradient; - - bool has_gradient = (dsc->grad.dir != (lv_grad_dir_t)LV_GRAD_DIR_NONE); - - /* Init Gradient*/ - if(has_gradient) { - gradient = lv_malloc_zeroed(sizeof(vg_lite_linear_gradient_t)); - LV_ASSERT_MALLOC(gradient); - vglite_task->gradient = gradient; - - vg_lite_matrix_t * grad_matrix; - - vg_lite_uint32_t colors[LV_GRADIENT_MAX_STOPS]; - vg_lite_uint32_t stops[LV_GRADIENT_MAX_STOPS]; - lv_color32_t col32[LV_GRADIENT_MAX_STOPS]; - - /* Gradient Setup */ - vg_lite_uint32_t cnt = LV_MIN(dsc->grad.stops_count, LV_GRADIENT_MAX_STOPS); - lv_opa_t opa; - - for(uint8_t i = 0; i < cnt; i++) { - stops[i] = dsc->grad.stops[i].frac; - opa = LV_OPA_MIX2(dsc->grad.stops[i].opa, dsc->opa); - - col32[i] = lv_color_to_32(dsc->grad.stops[i].color, opa); - colors[i] = vglite_get_color(col32[i], true); - } - - VGLITE_CHECK_ERROR(vg_lite_init_grad(gradient)); - - VGLITE_CHECK_ERROR(vg_lite_set_grad(gradient, cnt, colors, stops)); - - VGLITE_CHECK_ERROR(vg_lite_update_grad(gradient)); - - grad_matrix = vg_lite_get_grad_matrix(gradient); - VGLITE_CHECK_ERROR(vg_lite_identity(grad_matrix)); - VGLITE_CHECK_ERROR(vg_lite_translate((float)coords->x1, (float)coords->y1, grad_matrix)); - - if(dsc->grad.dir == (lv_grad_dir_t)LV_GRAD_DIR_VER) { - VGLITE_CHECK_ERROR(vg_lite_scale(1.0f, (float)height / 256.0f, grad_matrix)); - VGLITE_CHECK_ERROR(vg_lite_rotate(90.0f, grad_matrix)); - } - else { /*LV_GRAD_DIR_HOR*/ - VGLITE_CHECK_ERROR(vg_lite_scale((float)width / 256.0f, 1.0f, grad_matrix)); - } - - VGLITE_CHECK_ERROR(vg_lite_draw_gradient(dest_buf, path, VG_LITE_FILL_EVEN_ODD, NULL, gradient, - VG_LITE_BLEND_SRC_OVER)); - } - else { - VGLITE_CHECK_ERROR(vg_lite_draw(dest_buf, path, VG_LITE_FILL_EVEN_ODD, NULL, VG_LITE_BLEND_SRC_OVER, vgcol)); - } - - vglite_run(); -} - -#endif /*LV_USE_DRAW_VGLITE*/ diff --git a/src/draw/nxp/vglite/lv_vglite_buf.c b/src/draw/nxp/vglite/lv_vglite_buf.c deleted file mode 100644 index 76f9dc13ee..0000000000 --- a/src/draw/nxp/vglite/lv_vglite_buf.c +++ /dev/null @@ -1,116 +0,0 @@ -/** - * @file lv_vglite_buf.c - * - */ - -/** - * Copyright 2023 NXP - * - * SPDX-License-Identifier: MIT - */ - -/********************* - * INCLUDES - *********************/ - -#include "lv_vglite_buf.h" - -#if LV_USE_DRAW_VGLITE -#include "lv_vglite_utils.h" - -#include "../../../stdlib/lv_string.h" - -/********************* - * DEFINES - *********************/ - -/********************** - * TYPEDEFS - **********************/ - -/********************** - * STATIC PROTOTYPES - **********************/ - -static inline void _set_vgbuf_ptr(vg_lite_buffer_t * vgbuf, void * buf); - -/********************** - * STATIC VARIABLES - **********************/ - -static vg_lite_buffer_t _dest_buf; -static vg_lite_buffer_t _src_buf; - -/********************** - * MACROS - **********************/ - -/********************** - * GLOBAL FUNCTIONS - **********************/ - -vg_lite_buffer_t * vglite_get_dest_buf(void) -{ - return &_dest_buf; -} - -vg_lite_buffer_t * vglite_get_src_buf(void) -{ - return &_src_buf; -} - -void vglite_set_dest_buf_ptr(void * buf) -{ - _set_vgbuf_ptr(&_dest_buf, buf); -} - -void vglite_set_src_buf_ptr(const void * buf) -{ - _set_vgbuf_ptr(&_src_buf, (void *)buf); -} - -void vglite_set_dest_buf(const void * buf, uint32_t width, uint32_t height, uint32_t stride, - lv_color_format_t cf) -{ - vglite_set_buf(&_dest_buf, (void *)buf, width, height, stride, cf); -} - -void vglite_set_src_buf(const void * buf, uint32_t width, uint32_t height, uint32_t stride, - lv_color_format_t cf) -{ - vglite_set_buf(&_src_buf, (void *)buf, width, height, stride, cf); -} - -void vglite_set_buf(vg_lite_buffer_t * vgbuf, void * buf, - uint32_t width, uint32_t height, uint32_t stride, - lv_color_format_t cf) -{ - vg_lite_buffer_format_t vgformat = vglite_get_buf_format(cf); - - vgbuf->format = vgformat; - vgbuf->tiled = VG_LITE_LINEAR; - vgbuf->image_mode = VG_LITE_NORMAL_IMAGE_MODE; - vgbuf->transparency_mode = VG_LITE_IMAGE_OPAQUE; - - vgbuf->width = (int32_t)width; - vgbuf->height = (int32_t)height; - vgbuf->stride = (int32_t)stride; - - lv_memzero(&vgbuf->yuv, sizeof(vgbuf->yuv)); - - vgbuf->memory = buf; - vgbuf->address = (uint32_t)vgbuf->memory; - vgbuf->handle = NULL; -} - -/********************** - * STATIC FUNCTIONS - **********************/ - -static inline void _set_vgbuf_ptr(vg_lite_buffer_t * vgbuf, void * buf) -{ - vgbuf->memory = buf; - vgbuf->address = (uint32_t)vgbuf->memory; -} - -#endif /*LV_USE_DRAW_VGLITE*/ diff --git a/src/draw/nxp/vglite/lv_vglite_buf.h b/src/draw/nxp/vglite/lv_vglite_buf.h deleted file mode 100644 index c15d918d00..0000000000 --- a/src/draw/nxp/vglite/lv_vglite_buf.h +++ /dev/null @@ -1,124 +0,0 @@ -/** - * @file lv_vglite_buf.h - * - */ - -/** - * Copyright 2023 NXP - * - * SPDX-License-Identifier: MIT - */ - -#ifndef LV_VGLITE_BUF_H -#define LV_VGLITE_BUF_H - -#ifdef __cplusplus -extern "C" { -#endif - -/********************* - * INCLUDES - *********************/ -#include "../../../lv_conf_internal.h" - -#if LV_USE_DRAW_VGLITE -#include "../../lv_draw.h" - -#include "vg_lite.h" - -/********************* - * DEFINES - *********************/ - -/********************** - * TYPEDEFS - **********************/ - -/********************** - * GLOBAL PROTOTYPES - **********************/ - -/** - * Get vglite destination buffer pointer. - * - * @retval The vglite destination buffer - * - */ -vg_lite_buffer_t * vglite_get_dest_buf(void); - -/** - * Get vglite source buffer pointer. - * - * @retval The vglite source buffer - * - */ -vg_lite_buffer_t * vglite_get_src_buf(void); - -/** - * Set vglite destination buffer address only. - * - * @param[in] buf Destination buffer address (does not require alignment for VG_LITE_LINEAR mode) - * - */ -void vglite_set_dest_buf_ptr(void * buf); - -/** - * Set vglite source buffer address only. - * - * @param[in] buf Source buffer address - * - */ -void vglite_set_src_buf_ptr(const void * buf); - -/** - * Set vglite destination buffer. - * - * @param[in] buf Destination buffer address - * @param[in] width Destination buffer width - * @param[in] height Destination buffer height - * @param[in] stride Destination buffer stride in bytes - * @param[in] cf Destination buffer color format - * - */ -void vglite_set_dest_buf(const void * buf, uint32_t width, uint32_t height, uint32_t stride, - lv_color_format_t cf); - -/** - * Set vglite source buffer. - * - * @param[in] buf Source buffer address - * @param[in] width Source buffer width - * @param[in] height Source buffer height - * @param[in] stride Source buffer stride in bytes - * @param[in] cf Source buffer color format - * - */ -void vglite_set_src_buf(const void * buf, uint32_t width, uint32_t height, uint32_t stride, - lv_color_format_t cf); - -/** - * Set vglite buffer. - * - * @param[in] vgbuf Address of the VGLite buffer object - * @param[in] buf Address of the memory for the VGLite buffer - * @param[in] width Buffer width - * @param[in] height Buffer height - * @param[in] stride Buffer stride in bytes - * @param[in] cf Buffer color format - * - */ -void vglite_set_buf(vg_lite_buffer_t * vgbuf, void * buf, - uint32_t width, uint32_t height, uint32_t stride, - lv_color_format_t cf); - -/********************** - * MACROS - **********************/ - -#endif /*LV_USE_DRAW_VGLITE*/ - -#ifdef __cplusplus -} /*extern "C"*/ -#endif - -#endif /*LV_VGLITE_BUF_H*/ diff --git a/src/draw/nxp/vglite/lv_vglite_matrix.c b/src/draw/nxp/vglite/lv_vglite_matrix.c deleted file mode 100644 index f41ed37460..0000000000 --- a/src/draw/nxp/vglite/lv_vglite_matrix.c +++ /dev/null @@ -1,81 +0,0 @@ -/** - * @file lv_vglite_matrix.c - * - */ - -/** - * Copyright 2023 NXP - * - * SPDX-License-Identifier: MIT - */ - -/********************* - * INCLUDES - *********************/ - -#include "lv_vglite_matrix.h" - -#if LV_USE_DRAW_VGLITE - -/********************* - * DEFINES - *********************/ - -/********************** - * TYPEDEFS - **********************/ - -/********************** - * STATIC PROTOTYPES - **********************/ - -/********************** - * STATIC VARIABLES - **********************/ - -static vg_lite_matrix_t _matrix; - -/********************** - * MACROS - **********************/ - -/********************** - * GLOBAL FUNCTIONS - **********************/ - -vg_lite_matrix_t * vglite_get_matrix(void) -{ - return &_matrix; -} - -void vglite_set_translation_matrix(const lv_area_t * dest_area) -{ - vg_lite_identity(&_matrix); - vg_lite_translate((vg_lite_float_t)dest_area->x1, (vg_lite_float_t)dest_area->y1, &_matrix); -} - -void vglite_set_transformation_matrix(const lv_area_t * dest_area, const lv_draw_image_dsc_t * dsc) -{ - vglite_set_translation_matrix(dest_area); - - bool has_scale = (dsc->scale_x != LV_SCALE_NONE || dsc->scale_y != LV_SCALE_NONE); - bool has_rotation = (dsc->rotation != 0); - - if(has_scale || has_rotation) { - vg_lite_translate(dsc->pivot.x, dsc->pivot.y, &_matrix); - if(has_rotation) - vg_lite_rotate(dsc->rotation / 10.0f, &_matrix); /* angle is 1/10 degree */ - if(has_scale) { - vg_lite_float_t scale_x = 1.0f * dsc->scale_x / LV_SCALE_NONE; - vg_lite_float_t scale_y = 1.0f * dsc->scale_y / LV_SCALE_NONE; - vg_lite_scale(scale_x, scale_y, &_matrix); - } - vg_lite_translate(0.0f - dsc->pivot.x, 0.0f - dsc->pivot.y, &_matrix); - } -} - -/********************** - * STATIC FUNCTIONS - **********************/ - -#endif /*LV_USE_DRAW_VGLITE*/ diff --git a/src/draw/nxp/vglite/lv_vglite_matrix.h b/src/draw/nxp/vglite/lv_vglite_matrix.h deleted file mode 100644 index 0f735d69e2..0000000000 --- a/src/draw/nxp/vglite/lv_vglite_matrix.h +++ /dev/null @@ -1,80 +0,0 @@ -/** - * @file lv_vglite_matrix.h - * - */ - -/** - * Copyright 2023 NXP - * - * SPDX-License-Identifier: MIT - */ - -#ifndef LV_VGLITE_MATRIX_H -#define LV_VGLITE_MATRIX_H - -#ifdef __cplusplus -extern "C" { -#endif - -/********************* - * INCLUDES - *********************/ -#include "../../../lv_conf_internal.h" - -#if LV_USE_DRAW_VGLITE - -#include "../../lv_draw_image.h" -#include "../../lv_draw.h" - -#include "vg_lite.h" - -/********************* - * DEFINES - *********************/ - -/********************** - * TYPEDEFS - **********************/ - -/********************** - * STATIC PROTOTYPES - **********************/ - -/********************** - * GLOBAL PROTOTYPES - **********************/ - -vg_lite_matrix_t * vglite_get_matrix(void); - -/** - * Creates matrix that translates to origin of given destination area. - * - * @param[in] dest_area Area with relative coordinates of destination buffer - * - */ -void vglite_set_translation_matrix(const lv_area_t * dest_area); - -/** - * Creates matrix that translates to origin of given destination area with transformation (scale or rotate). - * - * @param[in] dest_area Area with relative coordinates of destination buffer - * @param[in] dsc Image descriptor - * - */ -void vglite_set_transformation_matrix(const lv_area_t * dest_area, const lv_draw_image_dsc_t * dsc); - -/********************** - * MACROS - **********************/ - -/********************** - * STATIC FUNCTIONS - **********************/ - -#endif /*LV_USE_DRAW_VGLITE*/ - -#ifdef __cplusplus -} /*extern "C"*/ -#endif - -#endif /*LV_VGLITE_MATRIX_H*/ diff --git a/src/draw/nxp/vglite/lv_vglite_path.c b/src/draw/nxp/vglite/lv_vglite_path.c deleted file mode 100644 index 6f8b759c82..0000000000 --- a/src/draw/nxp/vglite/lv_vglite_path.c +++ /dev/null @@ -1,217 +0,0 @@ -/** - * @file lv_vglite_path.c - * - */ - -/** - * Copyright 2023 NXP - * - * SPDX-License-Identifier: MIT - */ - -/********************* - * INCLUDES - *********************/ - -#include "lv_vglite_path.h" - -#if LV_USE_DRAW_VGLITE -#include "vg_lite.h" - -/********************* - * DEFINES - *********************/ - -/********************** - * TYPEDEFS - **********************/ - -/********************** - * STATIC PROTOTYPES - **********************/ - -/********************** - * STATIC VARIABLES - **********************/ - -/********************** - * MACROS - **********************/ - -/********************** - * GLOBAL FUNCTIONS - **********************/ - -void vglite_create_rect_path_data(int32_t * path_data, uint32_t * path_data_size, - int32_t radius, - const lv_area_t * coords) -{ - int32_t rect_width = lv_area_get_width(coords); - int32_t rect_height = lv_area_get_height(coords); - - /* Get the final radius. Can't be larger than the half of the shortest side */ - int32_t shortest_side = LV_MIN(rect_width, rect_height); - int32_t final_radius = LV_MIN(radius, shortest_side / 2); - - /* Path data element index */ - uint8_t pidx = 0; - - if((radius == (int32_t)LV_RADIUS_CIRCLE) && (rect_width == rect_height)) { - - /* Get the control point offset for rounded cases */ - int32_t cpoff = (int32_t)((float)final_radius * BEZIER_OPTIM_CIRCLE); - - /* Circle case */ - /* Starting point */ - path_data[pidx++] = VLC_OP_MOVE; - path_data[pidx++] = coords->x1 + final_radius; - path_data[pidx++] = coords->y1; - - /* Top-right arc */ - path_data[pidx++] = VLC_OP_CUBIC_REL; - path_data[pidx++] = cpoff; - path_data[pidx++] = 0; - path_data[pidx++] = final_radius; - path_data[pidx++] = final_radius - cpoff; - path_data[pidx++] = final_radius; - path_data[pidx++] = final_radius; - - /* Bottom-right arc*/ - path_data[pidx++] = VLC_OP_CUBIC_REL; - path_data[pidx++] = 0; - path_data[pidx++] = cpoff; - path_data[pidx++] = cpoff - final_radius; - path_data[pidx++] = final_radius; - path_data[pidx++] = 0 - final_radius; - path_data[pidx++] = final_radius; - - /* Bottom-left arc */ - path_data[pidx++] = VLC_OP_CUBIC_REL; - path_data[pidx++] = 0 - cpoff; - path_data[pidx++] = 0; - path_data[pidx++] = 0 - final_radius; - path_data[pidx++] = cpoff - final_radius; - path_data[pidx++] = 0 - final_radius; - path_data[pidx++] = 0 - final_radius; - - /* Top-left arc*/ - path_data[pidx++] = VLC_OP_CUBIC_REL; - path_data[pidx++] = 0; - path_data[pidx++] = 0 - cpoff; - path_data[pidx++] = final_radius - cpoff; - path_data[pidx++] = 0 - final_radius; - path_data[pidx++] = final_radius; - path_data[pidx++] = 0 - final_radius; - - /* Ending point */ - path_data[pidx++] = VLC_OP_END; - } - else if(radius > 0) { - /* Get the control point offset for rounded cases */ - int32_t cpoff = (int32_t)((float)final_radius * BEZIER_OPTIM_CIRCLE); - - /* Rounded rectangle case */ - /* Starting point */ - path_data[pidx++] = VLC_OP_MOVE; - path_data[pidx++] = coords->x1 + final_radius; - path_data[pidx++] = coords->y1; - - /* Top side */ - path_data[pidx++] = VLC_OP_LINE; - path_data[pidx++] = coords->x2 - final_radius + 1; /*Extended for VGLite*/ - path_data[pidx++] = coords->y1; - - /* Top-right corner */ - path_data[pidx++] = VLC_OP_CUBIC_REL; - path_data[pidx++] = cpoff; - path_data[pidx++] = 0; - path_data[pidx++] = final_radius; - path_data[pidx++] = final_radius - cpoff; - path_data[pidx++] = final_radius; - path_data[pidx++] = final_radius; - - /* Right side */ - path_data[pidx++] = VLC_OP_LINE; - path_data[pidx++] = coords->x2 + 1; /*Extended for VGLite*/ - path_data[pidx++] = coords->y2 - final_radius + 1; /*Extended for VGLite*/ - - /* Bottom-right corner*/ - path_data[pidx++] = VLC_OP_CUBIC_REL; - path_data[pidx++] = 0; - path_data[pidx++] = cpoff; - path_data[pidx++] = cpoff - final_radius; - path_data[pidx++] = final_radius; - path_data[pidx++] = 0 - final_radius; - path_data[pidx++] = final_radius; - - /* Bottom side */ - path_data[pidx++] = VLC_OP_LINE; - path_data[pidx++] = coords->x1 + final_radius; - path_data[pidx++] = coords->y2 + 1; /*Extended for VGLite*/ - - /* Bottom-left corner */ - path_data[pidx++] = VLC_OP_CUBIC_REL; - path_data[pidx++] = 0 - cpoff; - path_data[pidx++] = 0; - path_data[pidx++] = 0 - final_radius; - path_data[pidx++] = cpoff - final_radius; - path_data[pidx++] = 0 - final_radius; - path_data[pidx++] = 0 - final_radius; - - /* Left side*/ - path_data[pidx++] = VLC_OP_LINE; - path_data[pidx++] = coords->x1; - path_data[pidx++] = coords->y1 + final_radius; - - /* Top-left corner */ - path_data[pidx++] = VLC_OP_CUBIC_REL; - path_data[pidx++] = 0; - path_data[pidx++] = 0 - cpoff; - path_data[pidx++] = final_radius - cpoff; - path_data[pidx++] = 0 - final_radius; - path_data[pidx++] = final_radius; - path_data[pidx++] = 0 - final_radius; - - /* Ending point */ - path_data[pidx++] = VLC_OP_END; - } - else { - /* Non-rounded rectangle case */ - /* Starting point */ - path_data[pidx++] = VLC_OP_MOVE; - path_data[pidx++] = coords->x1; - path_data[pidx++] = coords->y1; - - /* Top side */ - path_data[pidx++] = VLC_OP_LINE; - path_data[pidx++] = coords->x2 + 1; /*Extended for VGLite*/ - path_data[pidx++] = coords->y1; - - /* Right side */ - path_data[pidx++] = VLC_OP_LINE; - path_data[pidx++] = coords->x2 + 1; /*Extended for VGLite*/ - path_data[pidx++] = coords->y2 + 1; /*Extended for VGLite*/ - - /* Bottom side */ - path_data[pidx++] = VLC_OP_LINE; - path_data[pidx++] = coords->x1; - path_data[pidx++] = coords->y2 + 1; /*Extended for VGLite*/ - - /* Left side*/ - path_data[pidx++] = VLC_OP_LINE; - path_data[pidx++] = coords->x1; - path_data[pidx++] = coords->y1; - - /* Ending point */ - path_data[pidx++] = VLC_OP_END; - } - - /* Resulting path size */ - *path_data_size = pidx * sizeof(int32_t); -} - -/********************** - * STATIC FUNCTIONS - **********************/ - -#endif /*LV_USE_DRAW_VGLITE*/ diff --git a/src/draw/nxp/vglite/lv_vglite_path.h b/src/draw/nxp/vglite/lv_vglite_path.h deleted file mode 100644 index a4cd21e586..0000000000 --- a/src/draw/nxp/vglite/lv_vglite_path.h +++ /dev/null @@ -1,98 +0,0 @@ -/** - * @file lv_vglite_path.h - * - */ - -/** - * Copyright 2023 NXP - * - * SPDX-License-Identifier: MIT - */ - -#ifndef LV_VGLITE_PATH_H -#define LV_VGLITE_PATH_H - -#ifdef __cplusplus -extern "C" { -#endif - -/********************* - * INCLUDES - *********************/ -#include "../../../lv_conf_internal.h" - -#if LV_USE_DRAW_VGLITE -#include "../../lv_draw.h" -#include "../../lv_draw_triangle.h" - -/********************* - * DEFINES - *********************/ - -/* The optimal Bezier control point offset for radial unit - * see: https://spencermortensen.com/articles/bezier-circle/ - **/ -#define BEZIER_OPTIM_CIRCLE 0.551915024494f - -/* Draw lines for control points of Bezier curves */ -#define BEZIER_DBG_CONTROL_POINTS 0 - -/* Path data sizes for different elements */ -#define CUBIC_PATH_DATA_SIZE 7 /* 1 opcode, 6 arguments */ -#define LINE_PATH_DATA_SIZE 3 /* 1 opcode, 2 arguments */ -#define MOVE_PATH_DATA_SIZE 3 /* 1 opcode, 2 arguments */ -#define END_PATH_DATA_SIZE 1 /* 1 opcode, 0 arguments */ -/* Maximum possible rectangle path size - * is in the rounded rectangle case: - * - 1 move for the path start - * - 4 cubics for the corners - * - 4 lines for the sides - * - 1 end for the path end */ -#define RECT_PATH_DATA_MAX_SIZE (1 * MOVE_PATH_DATA_SIZE + 4 * CUBIC_PATH_DATA_SIZE + 4 * LINE_PATH_DATA_SIZE + 1 * END_PATH_DATA_SIZE) - -/* Maximum possible arc path size - * is in the rounded arc case: - * - 1 move for the path start - * - 16 cubics for the arc (5 inner, 5 outer) and corners (3 per corner) - * - 1 end for the path end */ -#define ARC_PATH_DATA_MAX_SIZE (1 * MOVE_PATH_DATA_SIZE + 16 * CUBIC_PATH_DATA_SIZE + 1 * END_PATH_DATA_SIZE) -/********************** - * TYPEDEFS - **********************/ - -/********************** - * STATIC PROTOTYPES - **********************/ - -/********************** - * GLOBAL PROTOTYPES - **********************/ - -/** - * Generates path data for rectangle drawing. - * - * @param[in/out] path The path data to initialize - * @param[in/out] path_size The resulting size of the created path data - * @param[in] dsc The style descriptor for the rectangle to be drawn - * @param[in] coords The coordinates of the rectangle to be drawn - * - */ -void vglite_create_rect_path_data(int32_t * path_data, uint32_t * path_data_size, - int32_t radius, - const lv_area_t * coords); - -/********************** - * MACROS - **********************/ - -/********************** - * STATIC FUNCTIONS - **********************/ - -#endif /*LV_USE_DRAW_VGLITE*/ - -#ifdef __cplusplus -} /*extern "C"*/ -#endif - -#endif /*LV_VGLITE_PATH_H*/ diff --git a/src/draw/nxp/vglite/lv_vglite_utils.c b/src/draw/nxp/vglite/lv_vglite_utils.c deleted file mode 100644 index 5daa29ecd7..0000000000 --- a/src/draw/nxp/vglite/lv_vglite_utils.c +++ /dev/null @@ -1,286 +0,0 @@ -/** - * @file lv_vglite_utils.c - * - */ - -/** - * Copyright 2022-2024 NXP - * - * SPDX-License-Identifier: MIT - */ - -/********************* - * INCLUDES - *********************/ - -#include "lv_vglite_utils.h" - -#if LV_USE_DRAW_VGLITE -#include "lv_vglite_buf.h" - -#include "../../../core/lv_refr.h" - -/********************* - * DEFINES - *********************/ - -/********************** - * TYPEDEFS - **********************/ - -/********************** - * STATIC PROTOTYPES - **********************/ - -/********************** - * STATIC VARIABLES - **********************/ - -#if LV_USE_VGLITE_DRAW_ASYNC - static volatile bool _cmd_buf_flushed = false; -#endif - -/********************** - * MACROS - **********************/ - -/********************** - * GLOBAL FUNCTIONS - **********************/ - -const char * vglite_error_to_string(vg_lite_error_t error) -{ - switch(error) { - ENUM_TO_STRING(VG_LITE_SUCCESS); - ENUM_TO_STRING(VG_LITE_INVALID_ARGUMENT); - ENUM_TO_STRING(VG_LITE_OUT_OF_MEMORY); - ENUM_TO_STRING(VG_LITE_NO_CONTEXT); - ENUM_TO_STRING(VG_LITE_TIMEOUT); - ENUM_TO_STRING(VG_LITE_OUT_OF_RESOURCES); - ENUM_TO_STRING(VG_LITE_GENERIC_IO); - ENUM_TO_STRING(VG_LITE_NOT_SUPPORT); - ENUM_TO_STRING(VG_LITE_ALREADY_EXISTS); - ENUM_TO_STRING(VG_LITE_NOT_ALIGNED); - ENUM_TO_STRING(VG_LITE_FLEXA_TIME_OUT); - ENUM_TO_STRING(VG_LITE_FLEXA_HANDSHAKE_FAIL); - default: - break; - } - - return "VG_LITE_UKNOWN_ERROR"; -} - -#if LV_USE_VGLITE_DRAW_ASYNC -bool vglite_cmd_buf_is_flushed(void) -{ - return _cmd_buf_flushed; -} -#endif - -void vglite_run(void) -{ -#if LV_USE_VGLITE_DRAW_ASYNC - vg_lite_uint32_t gpu_idle = 0; - - VGLITE_CHECK_ERROR(vg_lite_get_parameter(VG_LITE_GPU_IDLE_STATE, 1, (vg_lite_pointer)&gpu_idle)); - - if(!gpu_idle) { - _cmd_buf_flushed = false; - - return; - } -#endif - - /* - * If LV_USE_VGLITE_DRAW_ASYNC is enabled, simply flush the command buffer and the - * vglite draw thread will signal asynchronous the dispatcher for completed tasks. - * Without draw async, process the tasks and signal them as complete one by one. - */ -#if LV_USE_VGLITE_DRAW_ASYNC - VGLITE_CHECK_ERROR(vg_lite_flush()); - _cmd_buf_flushed = true; -#else - VGLITE_CHECK_ERROR(vg_lite_finish()); -#endif -} - -#if LV_USE_VGLITE_DRAW_ASYNC -void vglite_wait_for_finish(void) -{ - VGLITE_CHECK_ERROR(vg_lite_finish()); -} -#endif - -vg_lite_color_t vglite_get_color(lv_color32_t lv_col32, bool gradient) -{ - vg_lite_color_t vg_col32; - - /* Pre-multiply alpha */ - lv_col32.red = LV_UDIV255(lv_col32.red * lv_col32.alpha); - lv_col32.green = LV_UDIV255(lv_col32.green * lv_col32.alpha); - lv_col32.blue = LV_UDIV255(lv_col32.blue * lv_col32.alpha); - - if(!gradient) - /* The color is in ABGR8888 format with red channel in the lower 8 bits. */ - vg_col32 = ((vg_lite_color_t)lv_col32.alpha << 24) | ((vg_lite_color_t)lv_col32.blue << 16) | - ((vg_lite_color_t)lv_col32.green << 8) | (vg_lite_color_t)lv_col32.red; - else - /* The gradient color is in ARGB8888 format with blue channel in the lower 8 bits. */ - vg_col32 = ((vg_lite_color_t)lv_col32.alpha << 24) | ((vg_lite_color_t)lv_col32.red << 16) | - ((vg_lite_color_t)lv_col32.green << 8) | (vg_lite_color_t)lv_col32.blue; - - return vg_col32; -} - -vg_lite_blend_t vglite_get_blend_mode(lv_blend_mode_t lv_blend_mode) -{ - vg_lite_blend_t vg_blend_mode = VG_LITE_BLEND_NONE; - - if(vg_lite_query_feature(gcFEATURE_BIT_VG_LVGL_SUPPORT)) { - switch(lv_blend_mode) { - case LV_BLEND_MODE_NORMAL: - vg_blend_mode = VG_LITE_BLEND_NORMAL_LVGL; - break; - case LV_BLEND_MODE_ADDITIVE: - vg_blend_mode = VG_LITE_BLEND_ADDITIVE_LVGL; - break; - case LV_BLEND_MODE_SUBTRACTIVE: - vg_blend_mode = VG_LITE_BLEND_SUBTRACT_LVGL; - break; - case LV_BLEND_MODE_MULTIPLY: - vg_blend_mode = VG_LITE_BLEND_MULTIPLY_LVGL; - break; - default: - VGLITE_ASSERT_MSG(false, "Unsupported blend mode."); - break; - } - } - else { - switch(lv_blend_mode) { - case LV_BLEND_MODE_NORMAL: - vg_blend_mode = VG_LITE_BLEND_SRC_OVER; - break; - case LV_BLEND_MODE_ADDITIVE: - vg_blend_mode = VG_LITE_BLEND_ADDITIVE; - break; - case LV_BLEND_MODE_SUBTRACTIVE: - vg_blend_mode = VG_LITE_BLEND_SUBTRACT; - break; - case LV_BLEND_MODE_MULTIPLY: - vg_blend_mode = VG_LITE_BLEND_MULTIPLY; - break; - default: - VGLITE_ASSERT_MSG(false, "Unsupported blend mode."); - break; - } - } - - return vg_blend_mode; -} - -vg_lite_buffer_format_t vglite_get_buf_format(lv_color_format_t cf) -{ - vg_lite_buffer_format_t vg_buffer_format = VG_LITE_BGR565; - - switch(cf) { - case LV_COLOR_FORMAT_L8: - vg_buffer_format = VG_LITE_L8; - break; - case LV_COLOR_FORMAT_A4: - vg_buffer_format = VG_LITE_A4; - break; - case LV_COLOR_FORMAT_A8: - vg_buffer_format = VG_LITE_A8; - break; - case LV_COLOR_FORMAT_I1: - vg_buffer_format = VG_LITE_INDEX_1; - break; - case LV_COLOR_FORMAT_I2: - vg_buffer_format = VG_LITE_INDEX_2; - break; - case LV_COLOR_FORMAT_I4: - vg_buffer_format = VG_LITE_INDEX_4; - break; - case LV_COLOR_FORMAT_I8: - vg_buffer_format = VG_LITE_INDEX_8; - break; - case LV_COLOR_FORMAT_RGB565: - vg_buffer_format = VG_LITE_BGR565; - break; - case LV_COLOR_FORMAT_ARGB8565: - vg_buffer_format = VG_LITE_BGRA5658; - break; - case LV_COLOR_FORMAT_RGB888: - vg_buffer_format = VG_LITE_BGR888; - break; - case LV_COLOR_FORMAT_ARGB8888: - vg_buffer_format = VG_LITE_BGRA8888; - break; - case LV_COLOR_FORMAT_XRGB8888: - vg_buffer_format = VG_LITE_BGRX8888; - break; - - default: - VGLITE_ASSERT_MSG(false, "Unsupported color format."); - break; - } - - return vg_buffer_format; -} - -uint8_t vglite_get_stride_alignment(lv_color_format_t cf) -{ - uint8_t align_bytes = LV_COLOR_DEPTH / 8 * 16; /*16 pixels*/ - - switch(cf) { - case LV_COLOR_FORMAT_I1: - case LV_COLOR_FORMAT_I2: - case LV_COLOR_FORMAT_I4: - case LV_COLOR_FORMAT_A4: - align_bytes = 8; - break; - case LV_COLOR_FORMAT_I8: - case LV_COLOR_FORMAT_A8: - case LV_COLOR_FORMAT_L8: - align_bytes = 16; - break; - case LV_COLOR_FORMAT_RGB565: - align_bytes = 32; - break; - case LV_COLOR_FORMAT_ARGB8565: - case LV_COLOR_FORMAT_RGB888: - align_bytes = 48; - break; - case LV_COLOR_FORMAT_ARGB8888: - case LV_COLOR_FORMAT_XRGB8888: - align_bytes = 64; - break; - - default: - VGLITE_ASSERT_MSG(false, "Unsupported buffer format."); - break; - } - - return align_bytes; -} - -bool vglite_src_buf_aligned(const void * buf, uint32_t stride, lv_color_format_t cf) -{ - /* No alignment requirement for destination buffer when using mode VG_LITE_LINEAR */ - - /* Test for pointer alignment */ - if((uintptr_t)buf % LV_ATTRIBUTE_MEM_ALIGN_SIZE) - return false; - - /* Test for stride alignment */ - if(stride == 0 || stride % vglite_get_stride_alignment(cf)) - return false; - - return true; -} - -/********************** - * STATIC FUNCTIONS - **********************/ - -#endif /*LV_USE_DRAW_VGLITE*/ diff --git a/src/draw/nxp/vglite/lv_vglite_utils.h b/src/draw/nxp/vglite/lv_vglite_utils.h deleted file mode 100644 index c61e04ecdf..0000000000 --- a/src/draw/nxp/vglite/lv_vglite_utils.h +++ /dev/null @@ -1,183 +0,0 @@ -/** - * @file lv_vglite_utils.h - * - */ - -/** - * Copyright 2022-2024 NXP - * - * SPDX-License-Identifier: MIT - */ - -#ifndef LV_VGLITE_UTILS_H -#define LV_VGLITE_UTILS_H - -#ifdef __cplusplus -extern "C" { -#endif - -/********************* - * INCLUDES - *********************/ -#include "../../../lv_conf_internal.h" - -#if LV_USE_DRAW_VGLITE -#include "../../lv_draw.h" - -#include "vg_lite.h" -#include "vg_lite_options.h" - -/********************* - * DEFINES - *********************/ - -#define ENUM_TO_STRING(e) \ - case (e): \ - return #e - -#if LV_USE_VGLITE_ASSERT -#define VGLITE_ASSERT(expr) LV_ASSERT(expr) -#else -#define VGLITE_ASSERT(expr) -#endif - -#define VGLITE_ASSERT_MSG(expr, msg) \ - do { \ - if(!(expr)) { \ - LV_LOG_ERROR(msg); \ - VGLITE_ASSERT(false); \ - } \ - } while(0) - -#if LV_USE_VGLITE_CHECK_ERROR -#define VGLITE_CHECK_ERROR(function) \ - do { \ - vg_lite_error_t error = function; \ - if(error != VG_LITE_SUCCESS) { \ - LV_LOG_ERROR("Execute '" #function "' error(%d): %s", \ - (int)error, vglite_error_to_string(error)); \ - VGLITE_ASSERT(false); \ - } \ - } while (0) -#else -#define VGLITE_CHECK_ERROR(function) function -#endif - -/********************** - * TYPEDEFS - **********************/ - -/********************** - * STATIC PROTOTYPES - **********************/ - -/** - * Set the clipping box. - * - * @param[in] clip_area Clip area with relative coordinates of destination buffer - * - */ -static inline void vglite_set_scissor(const lv_area_t * clip_area); - -/********************** - * GLOBAL PROTOTYPES - **********************/ - -const char * vglite_error_to_string(vg_lite_error_t error); - -#if LV_USE_VGLITE_DRAW_ASYNC -/** - * Get VG-Lite command buffer flushed status. - * - */ -bool vglite_cmd_buf_is_flushed(void); -#endif - -/** - * Flush command to VG-Lite. - * - */ -void vglite_run(void); - -/** - * Wait for VG-Lite finish. - * - */ -#if LV_USE_VGLITE_DRAW_ASYNC -void vglite_wait_for_finish(void); -#endif - -/** - * Get vglite color. Premultiplies (if not hw already) and swizzles the given - * LVGL 32bit color to obtain vglite color. - * - * @param[in] lv_col32 The initial LVGL 32bit color - * @param[in] gradient True for gradient color - * - * @retval The vglite 32-bit color value: - * - */ -vg_lite_color_t vglite_get_color(lv_color32_t lv_col32, bool gradient); - -/** - * Get vglite blend mode. - * - * @param[in] lv_blend_mode The LVGL blend mode - * - * @retval The vglite blend mode - * - */ -vg_lite_blend_t vglite_get_blend_mode(lv_blend_mode_t lv_blend_mode); - -/** - * Get vglite buffer format. - * - * @param[in] cf Color format - * - * @retval The vglite buffer format - * - */ -vg_lite_buffer_format_t vglite_get_buf_format(lv_color_format_t cf); - -/** - * Get vglite stride alignment. - * - * @param[in] cf Color format - * - * @retval Alignment requirement in bytes - * - */ -uint8_t vglite_get_stride_alignment(lv_color_format_t cf); - -/** - * Check source start address and stride alignment. - * - * @param[in] buf Buffer address - * @param[in] stride Stride of buffer in bytes - * @param[in] cf Color format - to calculate the expected alignment - * - * @retval true Alignment OK - * - */ -bool vglite_src_buf_aligned(const void * buf, uint32_t stride, lv_color_format_t cf); - -/********************** - * MACROS - **********************/ - -/********************** - * STATIC FUNCTIONS - **********************/ - -static inline void vglite_set_scissor(const lv_area_t * clip_area) -{ - vg_lite_set_scissor(clip_area->x1, clip_area->y1, clip_area->x2 + 1, clip_area->y2 + 1); -} - -#endif /*LV_USE_DRAW_VGLITE*/ - -#ifdef __cplusplus -} /*extern "C"*/ -#endif - -#endif /*LV_VGLITE_UTILS_H*/ diff --git a/src/draw/opengles/lv_draw_opengles.c b/src/draw/opengles/lv_draw_opengles.c index fac8bebcce..72ded26d0f 100644 --- a/src/draw/opengles/lv_draw_opengles.c +++ b/src/draw/opengles/lv_draw_opengles.c @@ -11,11 +11,10 @@ #if LV_USE_DRAW_OPENGLES #include "../lv_draw_private.h" #include "../../misc/cache/lv_cache_entry_private.h" -#include "../../drivers/glfw/lv_opengles_debug.h" -#include "../../drivers/glfw/lv_opengles_texture.h" -#include "../../drivers/glfw/lv_opengles_driver.h" -#include -#include +#include "../../drivers/opengles/lv_opengles_debug.h" +#include "../../drivers/opengles/lv_opengles_texture.h" +#include "../../drivers/opengles/lv_opengles_driver.h" +#include "../../drivers/opengles/lv_opengles_private.h" #include "../../draw/lv_draw_label.h" #include "../../draw/lv_draw_rect.h" #include "../../draw/lv_draw_arc.h" @@ -101,7 +100,7 @@ void lv_draw_opengles_init(void) draw_opengles_unit->base_unit.evaluate_cb = evaluate; draw_opengles_unit->base_unit.name = "OPENGLES"; draw_opengles_unit->texture_cache = lv_cache_create(&lv_cache_class_lru_rb_count, - sizeof(cache_data_t), 128, (lv_cache_ops_t) { + sizeof(cache_data_t), LV_DRAW_OPENGLES_TEXTURE_CACHE_COUNT, (lv_cache_ops_t) { .compare_cb = (lv_cache_compare_cb_t)opengles_texture_cache_compare_cb, .create_cb = (lv_cache_create_cb_t)opengles_texture_cache_create_cb, .free_cb = (lv_cache_free_cb_t)opengles_texture_cache_free_cb, @@ -130,17 +129,22 @@ void lv_draw_opengles_deinit(void) static bool opengles_texture_cache_create_cb(cache_data_t * cached_data, void * user_data) { - return draw_to_texture((lv_draw_opengles_unit_t *)user_data, cached_data); + LV_PROFILER_DRAW_BEGIN; + bool ret = draw_to_texture((lv_draw_opengles_unit_t *)user_data, cached_data); + LV_PROFILER_DRAW_END; + return ret; } static void opengles_texture_cache_free_cb(cache_data_t * cached_data, void * user_data) { LV_UNUSED(user_data); + LV_PROFILER_DRAW_BEGIN; lv_free(cached_data->draw_dsc); GL_CALL(glDeleteTextures(1, &cached_data->texture)); cached_data->draw_dsc = NULL; cached_data->texture = 0; + LV_PROFILER_DRAW_END; } static lv_cache_compare_res_t opengles_texture_cache_compare_cb(const cache_data_t * lhs, const cache_data_t * rhs) @@ -190,9 +194,6 @@ static int32_t dispatch(lv_draw_unit_t * draw_unit, lv_layer_t * layer) if(texture == 0) { lv_display_t * disp = lv_refr_get_disp_refreshing(); if(layer != disp->layer_head) { - void * buf = lv_draw_layer_alloc_buf(layer); - if(buf == NULL) return -1; - int32_t w = lv_area_get_width(&layer->buf_area); int32_t h = lv_area_get_height(&layer->buf_area); @@ -210,7 +211,7 @@ static int32_t dispatch(lv_draw_unit_t * draw_unit, lv_layer_t * layer) execute_drawing(draw_opengles_unit); - draw_opengles_unit->task_act->state = LV_DRAW_TASK_STATE_READY; + draw_opengles_unit->task_act->state = LV_DRAW_TASK_STATE_FINISHED; draw_opengles_unit->task_act = NULL; /*The draw unit is free now. Request a new dispatching as it can get a new task*/ @@ -240,6 +241,7 @@ static int32_t evaluate(lv_draw_unit_t * draw_unit, lv_draw_task_t * task) static bool draw_to_texture(lv_draw_opengles_unit_t * u, cache_data_t * cache_data) { + LV_PROFILER_DRAW_BEGIN; lv_draw_task_t * task = u->task_act; lv_layer_t dest_layer; @@ -361,6 +363,7 @@ static bool draw_to_texture(lv_draw_opengles_unit_t * u, cache_data_t * cache_da default: /*The malloced cache_data->draw_dsc will be freed automatically on failure *in opengles_texture_cache_free_cb*/ + LV_PROFILER_DRAW_END; return false; } @@ -381,11 +384,13 @@ static bool draw_to_texture(lv_draw_opengles_unit_t * u, cache_data_t * cache_da lv_obj_set_flag(obj, LV_OBJ_FLAG_SEND_DRAW_TASK_EVENTS, original_send_draw_task_event); } + LV_PROFILER_DRAW_END; return true; } static void blend_texture_layer(lv_draw_task_t * t) { + LV_PROFILER_DRAW_BEGIN; lv_draw_image_dsc_t * draw_dsc = t->draw_dsc; lv_draw_opengles_unit_t * u = (lv_draw_opengles_unit_t *)t->draw_unit; lv_area_t area; @@ -404,33 +409,52 @@ static void blend_texture_layer(lv_draw_task_t * t) lv_layer_t * dest_layer = t->target_layer; unsigned int target_texture = layer_get_texture(dest_layer); - LV_ASSERT(target_texture != 0); int32_t targ_tex_w = lv_area_get_width(&dest_layer->buf_area); int32_t targ_tex_h = lv_area_get_height(&dest_layer->buf_area); - GL_CALL(glBindTexture(GL_TEXTURE_2D, target_texture)); - - unsigned int framebuffer = get_framebuffer(u); - GL_CALL(glBindFramebuffer(GL_FRAMEBUFFER, framebuffer)); - GL_CALL(glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, target_texture, 0)); + if(target_texture) { + unsigned int framebuffer = get_framebuffer(u); + GL_CALL(glBindFramebuffer(GL_FRAMEBUFFER, framebuffer)); + GL_CALL(glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, target_texture, 0)); + } lv_opengles_viewport(0, 0, targ_tex_w, targ_tex_h); // TODO rotation - lv_opengles_render_texture(src_texture, &area, draw_dsc->opa, targ_tex_w, targ_tex_h, &t->clip_area, false); - - GL_CALL(glBindFramebuffer(GL_FRAMEBUFFER, 0)); + bool h_flip = false; + bool v_flip = false; +#if LV_USE_3DTEXTURE + if(t->type == LV_DRAW_TASK_TYPE_3D) { + lv_draw_3d_dsc_t * _3d_dsc = (lv_draw_3d_dsc_t *)t->draw_dsc; + h_flip = _3d_dsc->h_flip; + v_flip = _3d_dsc->v_flip; + } +#endif + lv_opengles_render_texture(src_texture, &area, draw_dsc->opa, targ_tex_w, targ_tex_h, &t->clip_area, h_flip, + !v_flip); + if(target_texture) { + GL_CALL(glBindFramebuffer(GL_FRAMEBUFFER, 0)); + } - GL_CALL(glBindTexture(GL_TEXTURE_2D, 0)); GL_CALL(glDeleteTextures(1, &src_texture)); + LV_PROFILER_DRAW_END; } static void draw_from_cached_texture(lv_draw_task_t * t) { + LV_PROFILER_DRAW_BEGIN; lv_draw_opengles_unit_t * u = (lv_draw_opengles_unit_t *)t->draw_unit; cache_data_t data_to_find; data_to_find.draw_dsc = (lv_draw_dsc_base_t *)t->draw_dsc; - + bool h_flip = false; + bool v_flip = false; +#if LV_USE_3DTEXTURE + if(t->type == LV_DRAW_TASK_TYPE_3D) { + lv_draw_3d_dsc_t * _3d_dsc = (lv_draw_3d_dsc_t *)t->draw_dsc; + h_flip = _3d_dsc->h_flip; + v_flip = _3d_dsc->v_flip; + } +#endif data_to_find.w = lv_area_get_width(&t->_real_area); data_to_find.h = lv_area_get_height(&t->_real_area); data_to_find.texture = 0; @@ -478,6 +502,7 @@ static void draw_from_cached_texture(lv_draw_task_t * t) lv_area_move(&t->_real_area, a.x1, a.y1); if(!entry_cached) { + LV_PROFILER_DRAW_END; return; } @@ -489,23 +514,24 @@ static void draw_from_cached_texture(lv_draw_task_t * t) lv_layer_t * dest_layer = t->target_layer; unsigned int target_texture = layer_get_texture(dest_layer); - LV_ASSERT(target_texture != 0); int32_t targ_tex_w = lv_area_get_width(&dest_layer->buf_area); int32_t targ_tex_h = lv_area_get_height(&dest_layer->buf_area); - GL_CALL(glBindTexture(GL_TEXTURE_2D, target_texture)); - - unsigned int framebuffer = get_framebuffer(u); - GL_CALL(glBindFramebuffer(GL_FRAMEBUFFER, framebuffer)); - GL_CALL(glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, target_texture, 0)); + if(target_texture) { + unsigned int framebuffer = get_framebuffer(u); + GL_CALL(glBindFramebuffer(GL_FRAMEBUFFER, framebuffer)); + GL_CALL(glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, target_texture, 0)); + } lv_opengles_viewport(0, 0, targ_tex_w, targ_tex_h); lv_area_move(&t->clip_area, -dest_layer->buf_area.x1, -dest_layer->buf_area.y1); lv_area_t render_area = t->_real_area; lv_area_move(&render_area, -dest_layer->buf_area.x1, -dest_layer->buf_area.y1); - lv_opengles_render_texture(texture, &render_area, 0xff, targ_tex_w, targ_tex_h, &t->clip_area, true); + lv_opengles_render_texture(texture, &render_area, 0xff, targ_tex_w, targ_tex_h, &t->clip_area, h_flip, v_flip); - GL_CALL(glBindFramebuffer(GL_FRAMEBUFFER, 0)); + if(target_texture) { + GL_CALL(glBindFramebuffer(GL_FRAMEBUFFER, 0)); + } lv_cache_release(u->texture_cache, entry_cached, u); @@ -517,6 +543,7 @@ static void draw_from_cached_texture(lv_draw_task_t * t) lv_cache_drop(u->texture_cache, &data_to_find, u); } } + LV_PROFILER_DRAW_END; } static void execute_drawing(lv_draw_opengles_unit_t * u) @@ -524,6 +551,7 @@ static void execute_drawing(lv_draw_opengles_unit_t * u) lv_draw_task_t * t = u->task_act; t->draw_unit = (lv_draw_unit_t *)u; + /* the shader-based fill is not working reliably with EGL. */ if(t->type == LV_DRAW_TASK_TYPE_FILL) { lv_draw_fill_dsc_t * fill_dsc = t->draw_dsc; if(fill_dsc->radius == 0 && fill_dsc->grad.dir == LV_GRAD_DIR_NONE) { @@ -533,18 +561,21 @@ static void execute_drawing(lv_draw_opengles_unit_t * u) lv_area_move(&fill_area, -layer->buf_area.x1, -layer->buf_area.y1); unsigned int target_texture = layer_get_texture(layer); - LV_ASSERT(target_texture != 0); int32_t targ_tex_w = lv_area_get_width(&layer->buf_area); int32_t targ_tex_h = lv_area_get_height(&layer->buf_area); - unsigned int framebuffer = get_framebuffer(u); - GL_CALL(glBindFramebuffer(GL_FRAMEBUFFER, framebuffer)); - GL_CALL(glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, target_texture, 0)); + if(target_texture) { + unsigned int framebuffer = get_framebuffer(u); + GL_CALL(glBindFramebuffer(GL_FRAMEBUFFER, framebuffer)); + GL_CALL(glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, target_texture, 0)); + } lv_opengles_viewport(0, 0, targ_tex_w, targ_tex_h); lv_opengles_render_fill(fill_dsc->color, &fill_area, fill_dsc->opa, targ_tex_w, targ_tex_h); - GL_CALL(glBindFramebuffer(GL_FRAMEBUFFER, 0)); + if(target_texture) { + GL_CALL(glBindFramebuffer(GL_FRAMEBUFFER, 0)); + } return; } @@ -580,54 +611,60 @@ static unsigned int get_framebuffer(lv_draw_opengles_unit_t * u) static unsigned int create_texture(int32_t w, int32_t h, const void * data) { + LV_PROFILER_DRAW_BEGIN; unsigned int texture; - GL_CALL(glGenTextures(1, &texture)); GL_CALL(glBindTexture(GL_TEXTURE_2D, texture)); - GL_CALL(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST)); - GL_CALL(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST)); GL_CALL(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE)); GL_CALL(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE)); GL_CALL(glPixelStorei(GL_UNPACK_ALIGNMENT, 1)); - /* LV_COLOR_DEPTH 32, 24, 16 are supported but the cached textures will always + /* LV_COLOR_DEPTH 32, 16 are supported but the cached textures will always * have full ARGB pixels since the alpha channel is required for blending. */ GL_CALL(glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, w, h, 0, GL_BGRA, GL_UNSIGNED_BYTE, data)); +#if 0 + GL_CALL(glGenerateMipmap(GL_TEXTURE_2D)); + GL_CALL(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, 20)); + GL_CALL(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST_MIPMAP_NEAREST)); +#endif - glGenerateMipmap(GL_TEXTURE_2D); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, 20); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST_MIPMAP_NEAREST); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); + GL_CALL(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST)); + GL_CALL(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST)); + GL_CALL(glBindTexture(GL_TEXTURE_2D, 0)); + LV_PROFILER_DRAW_END; return texture; } #if LV_USE_3DTEXTURE static void lv_draw_opengles_3d(lv_draw_task_t * t, const lv_draw_3d_dsc_t * dsc, const lv_area_t * coords) { + LV_PROFILER_DRAW_BEGIN; lv_draw_opengles_unit_t * u = (lv_draw_opengles_unit_t *) t->draw_unit; lv_layer_t * dest_layer = t->target_layer; unsigned int target_texture = layer_get_texture(dest_layer); - LV_ASSERT(target_texture != 0); int32_t targ_tex_w = lv_area_get_width(&dest_layer->buf_area); int32_t targ_tex_h = lv_area_get_height(&dest_layer->buf_area); - GL_CALL(glBindTexture(GL_TEXTURE_2D, target_texture)); - - unsigned int framebuffer = get_framebuffer(u); - GL_CALL(glBindFramebuffer(GL_FRAMEBUFFER, framebuffer)); - GL_CALL(glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, target_texture, 0)); + if(target_texture) { + unsigned int framebuffer = get_framebuffer(u); + GL_CALL(glBindFramebuffer(GL_FRAMEBUFFER, framebuffer)); + GL_CALL(glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, target_texture, 0)); + } lv_opengles_viewport(0, 0, targ_tex_w, targ_tex_h); lv_area_t clip_area = t->clip_area; lv_area_move(&clip_area, -dest_layer->buf_area.x1, -dest_layer->buf_area.y1); - lv_opengles_render_texture(dsc->tex_id, coords, dsc->opa, targ_tex_w, targ_tex_h, &clip_area, true); + lv_opengles_render_texture(dsc->tex_id, coords, dsc->opa, targ_tex_w, targ_tex_h, &clip_area, dsc->h_flip, + !dsc->v_flip); - GL_CALL(glBindFramebuffer(GL_FRAMEBUFFER, 0)); - GL_CALL(glBindTexture(GL_TEXTURE_2D, 0)); + if(target_texture) { + GL_CALL(glBindFramebuffer(GL_FRAMEBUFFER, 0)); + } + LV_PROFILER_DRAW_END; } #endif /*LV_USE_3DTEXTURE*/ diff --git a/src/draw/renesas/dave2d/lv_draw_dave2d.c b/src/draw/renesas/dave2d/lv_draw_dave2d.c index fca89756db..4f5b2276e4 100644 --- a/src/draw/renesas/dave2d/lv_draw_dave2d.c +++ b/src/draw/renesas/dave2d/lv_draw_dave2d.c @@ -14,8 +14,15 @@ /********************* * DEFINES *********************/ -#define DRAW_UNIT_ID_DAVE2D 4 +#define DRAW_UNIT_ID_DAVE2D 4 +/* The amount of tasks exercising pressure to the currrent to get finished + * This one is used as the main signal to start to render a block of tasks. + */ +#define DAVE2D_MAX_DRAW_PRESSURE 256 +#if (DAVE2D_MAX_DRAW_PRESSURE < 256) + #error "DRAW Pressure should be at least 256 otherwise the Dave engine may crash!" +#endif /********************** * TYPEDEFS **********************/ @@ -23,12 +30,8 @@ /********************** * STATIC PROTOTYPES **********************/ -#if LV_USE_OS - static void _dave2d_render_thread_cb(void * ptr); -#endif static void execute_drawing(lv_draw_dave2d_unit_t * u); - #if defined(RENESAS_CORTEX_M85) #if (BSP_CFG_DCACHE_ENABLED) static void _dave2d_buf_invalidate_cache_cb(const lv_draw_buf_t * draw_buf, const lv_area_t * area); @@ -36,13 +39,12 @@ static void execute_drawing(lv_draw_dave2d_unit_t * u); #endif static int32_t _dave2d_evaluate(lv_draw_unit_t * draw_unit, lv_draw_task_t * task); - +static int32_t _dave2d_wait_finish(lv_draw_unit_t * draw_unit); static int32_t lv_draw_dave2d_dispatch(lv_draw_unit_t * draw_unit, lv_layer_t * layer); static d2_s32 lv_dave2d_init(void); - static void lv_draw_buf_dave2d_init_handlers(void); - +static bool lv_draw_dave2d_image_color_format_supported(lv_color_format_t color_format); void dave2d_execute_dlist_and_flush(void); /********************** @@ -53,11 +55,16 @@ void dave2d_execute_dlist_and_flush(void); * STATIC VARIABLES **********************/ -d2_device * _d2_handle; -d2_renderbuffer * _renderbuffer; -d2_renderbuffer * _blit_renderbuffer; +static d2_device * _d2_handle; + +/* Main render buffer, used to carry the block of dave commands for any shape */ +static d2_renderbuffer * _renderbuffer; -lv_ll_t _ll_Dave2D_Tasks; +/* Label dedicated render buffer, used to carry only label related dave commands */ +static d2_renderbuffer * _label_renderbuffer; + +static lv_ll_t draw_tasks_on_dlist; +static uint32_t draw_pressure = 0; #if LV_USE_OS lv_mutex_t xd2Semaphore; @@ -80,6 +87,7 @@ void lv_draw_dave2d_init(void) lv_draw_dave2d_unit_t * draw_dave2d_unit = lv_draw_create_unit(sizeof(lv_draw_dave2d_unit_t)); draw_dave2d_unit->base_unit.dispatch_cb = lv_draw_dave2d_dispatch; draw_dave2d_unit->base_unit.evaluate_cb = _dave2d_evaluate; + draw_dave2d_unit->base_unit.wait_for_finish_cb = _dave2d_wait_finish; draw_dave2d_unit->base_unit.name = "DAVE2D"; draw_dave2d_unit->idx = DRAW_UNIT_ID_DAVE2D; @@ -90,19 +98,13 @@ void lv_draw_dave2d_init(void) lv_result_t res; res = lv_mutex_init(&xd2Semaphore); LV_ASSERT(LV_RESULT_OK == res); - draw_dave2d_unit->pd2Mutex = &xd2Semaphore; #endif draw_dave2d_unit->d2_handle = _d2_handle; draw_dave2d_unit->renderbuffer = _renderbuffer; - lv_ll_init(&_ll_Dave2D_Tasks, 4); - -#if LV_USE_OS - lv_thread_init(&draw_dave2d_unit->thread, "dave2d", LV_DRAW_THREAD_PRIO, _dave2d_render_thread_cb, 8 * 1024, - draw_dave2d_unit); -#endif - + draw_dave2d_unit->label_renderbuffer = _label_renderbuffer; + lv_ll_init(&draw_tasks_on_dlist, sizeof(uintptr_t)); } /********************** @@ -211,6 +213,26 @@ static void _dave2d_buf_copy(void * dest_buf, uint32_t dest_w, uint32_t dest_h, } #endif +static bool lv_draw_dave2d_image_color_format_supported(lv_color_format_t color_format) +{ + bool supported = false; + + switch(color_format) { + case LV_COLOR_FORMAT_A8: + case LV_COLOR_FORMAT_RGB565: + case LV_COLOR_FORMAT_ARGB1555: + case LV_COLOR_FORMAT_ARGB4444: + case LV_COLOR_FORMAT_ARGB8888: + case LV_COLOR_FORMAT_XRGB8888: + supported = true; + break; + default: + break; + } + + return supported; +} + #define USE_D2 (1) static int32_t _dave2d_evaluate(lv_draw_unit_t * u, lv_draw_task_t * t) @@ -251,8 +273,7 @@ static int32_t _dave2d_evaluate(lv_draw_unit_t * u, lv_draw_task_t * t) case LV_DRAW_TASK_TYPE_IMAGE: { lv_draw_image_dsc_t * dsc = t->draw_dsc; - if((dsc->header.cf >= LV_COLOR_FORMAT_PROPRIETARY_START) || (dsc->header.cf == LV_COLOR_FORMAT_RGB888) || - (dsc->header.cf == LV_COLOR_FORMAT_RGB565A8)) { + if(!lv_draw_dave2d_image_color_format_supported(dsc->header.cf)) { ret = 0; break; } @@ -345,103 +366,105 @@ static int32_t _dave2d_evaluate(lv_draw_unit_t * u, lv_draw_task_t * t) return ret; } -#define DAVE2D_REFERRING_WATERMARK 10 static int32_t lv_draw_dave2d_dispatch(lv_draw_unit_t * draw_unit, lv_layer_t * layer) { lv_draw_dave2d_unit_t * draw_dave2d_unit = (lv_draw_dave2d_unit_t *) draw_unit; -#if (0 == D2_RENDER_EACH_OPERATION) - static uint32_t ref_count = 0; -#endif + uint32_t deps = 0; - /*Return immediately if it's busy with draw task*/ - if(draw_dave2d_unit->task_act) return 0; - - lv_draw_task_t * t = NULL; - t = lv_draw_get_available_task(layer, NULL, DRAW_UNIT_ID_DAVE2D); - while(t && t->preferred_draw_unit_id != DRAW_UNIT_ID_DAVE2D) { - t->state = LV_DRAW_TASK_STATE_READY; - t = lv_draw_get_available_task(layer, NULL, DRAW_UNIT_ID_DAVE2D); + if(draw_dave2d_unit->task_act) { + /* Return immediately if it's busy with draw task */ + return LV_DRAW_UNIT_IDLE; } + lv_draw_task_t * t = NULL; + t = lv_draw_get_next_available_task(layer, NULL, DRAW_UNIT_ID_DAVE2D); if(t == NULL) { -#if (0 == D2_RENDER_EACH_OPERATION) - if(false == lv_ll_is_empty(&_ll_Dave2D_Tasks)) { - ref_count = 0; + /* No valid task, but there are tasks waiting to be rendered, + * start to draw then immediatelly. + */ + if(false == lv_ll_is_empty(&draw_tasks_on_dlist)) { + draw_pressure = 0; dave2d_execute_dlist_and_flush(); } -#endif - return LV_DRAW_UNIT_IDLE; /*Couldn't start rendering*/ + return LV_DRAW_UNIT_IDLE; /* This task is not for us. */ } - /* Return if target buffer format is not supported. */ - if(!lv_draw_dave2d_is_dest_cf_supported(layer->color_format)) { - return LV_DRAW_UNIT_IDLE; /*Couldn't start rendering*/ - } + if((t->preferred_draw_unit_id != DRAW_UNIT_ID_DAVE2D)) return LV_DRAW_UNIT_IDLE; + if(!lv_draw_dave2d_is_dest_cf_supported(layer->color_format)) return LV_DRAW_UNIT_IDLE; void * buf = lv_draw_layer_alloc_buf(layer); - if(buf == NULL) { - return LV_DRAW_UNIT_IDLE; /*Couldn't start rendering*/ + if(buf == NULL) return LV_DRAW_UNIT_IDLE; + + deps = lv_draw_get_dependent_count(t); + if(deps > 0 || draw_pressure > 0) { + draw_pressure += deps; + if(draw_pressure < DAVE2D_MAX_DRAW_PRESSURE) { + /* No other tasks are pressuring to get the current block + * of tasks including the latest one, just accumulate it + * and tells the drawing pipeline to send a new one if there is any + */ + lv_draw_task_t ** p_new_list_entry; + p_new_list_entry = lv_ll_ins_tail(&draw_tasks_on_dlist); + *p_new_list_entry = t; + + draw_dave2d_unit->task_act = t; + draw_dave2d_unit->task_act->state = LV_DRAW_TASK_STATE_IN_PROGRESS; + execute_drawing(draw_dave2d_unit); + + draw_dave2d_unit->task_act = NULL; + lv_draw_dispatch_request(); + + return 1; + } + /* If the pressure for drawing value was maxed-out, it is time to render + * return IDLE to force the drawing pipeline to wait while the Dave + * draw the block of tasks in a single row + */ + return LV_DRAW_UNIT_IDLE; } + else { + /* Handles a special case when there is no sufficient draw pressure + * But the actual task did not carry any extra pressure to get drew + * in this case, the drawing pipeline have a few set of tasks that + * don't make sense to accumulate them, just do a run to completion + * here, that is it, render the incoming task immediately. + */ + draw_dave2d_unit->task_act = t; + draw_dave2d_unit->task_act->state = LV_DRAW_TASK_STATE_IN_PROGRESS; + d2_selectrenderbuffer(_d2_handle, _renderbuffer); + execute_drawing(draw_dave2d_unit); + d2_executerenderbuffer(_d2_handle, _renderbuffer, 0); + d2_flushframe(_d2_handle); + + draw_dave2d_unit->task_act->state = LV_DRAW_TASK_STATE_FINISHED; + draw_dave2d_unit->task_act = NULL; + lv_draw_dispatch_request(); -#if (0 == D2_RENDER_EACH_OPERATION) - ref_count += lv_draw_get_dependent_count(t); - - if(DAVE2D_REFERRING_WATERMARK < ref_count) { - ref_count = 0; - dave2d_execute_dlist_and_flush(); + return 1; } - - lv_draw_task_t ** p_new_list_entry; - p_new_list_entry = lv_ll_ins_tail(&_ll_Dave2D_Tasks); - *p_new_list_entry = t; -#endif - - t->state = LV_DRAW_TASK_STATE_IN_PROGRESS; - draw_dave2d_unit->task_act = t; - -#if LV_USE_OS - /*Let the render thread work*/ - lv_thread_sync_signal(&draw_dave2d_unit->sync); -#else - execute_drawing(draw_dave2d_unit); -#if (D2_RENDER_EACH_OPERATION) - draw_dave2d_unit->task_act->state = LV_DRAW_TASK_STATE_READY; -#endif - draw_dave2d_unit->task_act = NULL; - - /*The draw unit is free now. Request a new dispatching as it can get a new task*/ - lv_draw_dispatch_request(); - -#endif - return 1; } -#if LV_USE_OS -static void _dave2d_render_thread_cb(void * ptr) +static int32_t _dave2d_wait_finish(lv_draw_unit_t * draw_unit) { - lv_draw_dave2d_unit_t * u = ptr; - - lv_thread_sync_init(&u->sync); - - while(1) { - while(u->task_act == NULL) { - lv_thread_sync_wait(&u->sync); - } - - execute_drawing(u); - - /*Cleanup*/ -#if (D2_RENDER_EACH_OPERATION) - u->task_act->state = LV_DRAW_TASK_STATE_READY; -#endif - u->task_act = NULL; + /* If the drawing pipeline is waiting it means the pressure for drawing + * has been maxed out, defer the block of tasks to be rendered by the + * Dave and wait for its interrupt. (Dave2D driver is RTOS aware, no need for semaphores); + */ + lv_draw_dave2d_unit_t * draw_dave2d_unit = (lv_draw_dave2d_unit_t *) draw_unit; - /*The draw unit is free now. Request a new dispatching as it can get a new task*/ - lv_draw_dispatch_request(); + if(!draw_pressure) { + /* It reached here because Dave2D Draw Unit was not suitable to take a task + * While there is nothing being rendered, prevent the dead lock + * by flushing the GPU command buffer empty and just return. + */ + return 0; } + dave2d_execute_dlist_and_flush(); + draw_pressure = 0; + + return 0; } -#endif static void execute_drawing(lv_draw_dave2d_unit_t * u) { @@ -510,6 +533,11 @@ static void execute_drawing(lv_draw_dave2d_unit_t * u) break; } +#if defined(RENESAS_CORTEX_M85) +#if (BSP_CFG_DCACHE_ENABLED) + lv_draw_buf_invalidate_cache(layer->draw_buf, &clipped_area); +#endif +#endif } static d2_s32 lv_dave2d_init(void) @@ -544,23 +572,23 @@ static d2_s32 lv_dave2d_init(void) result = d2_setlinejoin(_d2_handle, d2_lj_miter); /* set blocksize for default displaylist */ - result = d2_setdlistblocksize(_d2_handle, 25); + result = d2_setdlistblocksize(_d2_handle, 20); if(D2_OK != result) { LV_LOG_ERROR("Could NOT d2_setdlistblocksize"); d2_closedevice(_d2_handle); return result; } - _blit_renderbuffer = d2_newrenderbuffer(_d2_handle, 20, 20); - if(!_blit_renderbuffer) { + _renderbuffer = d2_newrenderbuffer(_d2_handle, 250, 25); + if(!_renderbuffer) { LV_LOG_ERROR("NO renderbuffer"); d2_closedevice(_d2_handle); return D2_NOMEMORY; } - _renderbuffer = d2_newrenderbuffer(_d2_handle, 20, 20); - if(!_renderbuffer) { + _label_renderbuffer = d2_newrenderbuffer(_d2_handle, 250, 25); + if(!_label_renderbuffer) { LV_LOG_ERROR("NO renderbuffer"); d2_closedevice(_d2_handle); @@ -578,6 +606,10 @@ static d2_s32 lv_dave2d_init(void) void dave2d_execute_dlist_and_flush(void) { + d2_s32 result; + lv_draw_task_t ** p_list_entry; + lv_draw_task_t * p_list_entry1; + #if LV_USE_OS lv_result_t status; @@ -585,11 +617,6 @@ void dave2d_execute_dlist_and_flush(void) LV_ASSERT(LV_RESULT_OK == status); #endif - d2_s32 result; - lv_draw_task_t ** p_list_entry; - lv_draw_task_t * p_list_entry1; - - // Execute render operations result = d2_executerenderbuffer(_d2_handle, _renderbuffer, 0); LV_ASSERT(D2_OK == result); @@ -599,11 +626,11 @@ void dave2d_execute_dlist_and_flush(void) result = d2_selectrenderbuffer(_d2_handle, _renderbuffer); LV_ASSERT(D2_OK == result); - while(false == lv_ll_is_empty(&_ll_Dave2D_Tasks)) { - p_list_entry = lv_ll_get_tail(&_ll_Dave2D_Tasks); + while(false == lv_ll_is_empty(&draw_tasks_on_dlist)) { + p_list_entry = lv_ll_get_tail(&draw_tasks_on_dlist); p_list_entry1 = *p_list_entry; - p_list_entry1->state = LV_DRAW_TASK_STATE_READY; - lv_ll_remove(&_ll_Dave2D_Tasks, p_list_entry); + p_list_entry1->state = LV_DRAW_TASK_STATE_FINISHED; + lv_ll_remove(&draw_tasks_on_dlist, p_list_entry); lv_free(p_list_entry); } diff --git a/src/draw/renesas/dave2d/lv_draw_dave2d.h b/src/draw/renesas/dave2d/lv_draw_dave2d.h index 6f29b70be7..53b613d448 100644 --- a/src/draw/renesas/dave2d/lv_draw_dave2d.h +++ b/src/draw/renesas/dave2d/lv_draw_dave2d.h @@ -17,7 +17,37 @@ extern "C" { #if LV_USE_DRAW_DAVE2D #include "../../lv_draw.h" #include "../../lv_draw_private.h" -#include "hal_data.h" +#include "bsp_api.h" +#include "dave_driver.h" + +#if LV_USE_FLOAT + +/* We need to redefine some of D2 fixed point math macros to deal with lv_precise_t being float now */ +#undef D2_FIX4 +#undef D2_INT4 +#undef D2_FLOOR4 +#undef D2_CEIL4 +#undef D2_FRAC4 +#undef D2_FIX16 +#undef D2_INT16 +#undef D2_FLOOR16 +#undef D2_CEIL16 +#undef D2_FRAC16 + +#define D2_FIX4(x) (((int32_t)(x)) << 4) +#define D2_INT4(x) (((int32_t)(x))(x) >> 4) +#define D2_FLOOR4(x) (((int32_t)(x))((d2_u32)(x)) & ~15u) +#define D2_CEIL4(x) ((((d2_u32)(x)) + 15u) & ~15u) +#define D2_FRAC4(x) (((d2_u32)(x)) & 15u) +#define D2_FIX16(x) (((int32_t)(x)) << 16) +#define D2_INT16(x) (((int32_t)(x)) >> 16) +#define D2_FLOOR16(x) (((d2_u32)(x)) & ~65535u) +#define D2_CEIL16(x) ((((d2_u32)(x)) + 65535u) & ~65535u) +#define D2_FRAC16(x) (((d2_u32)(x)) & 65535u) + +/* It also should be included here before the other LVGL Dave2D files */ +#endif + #include "lv_draw_dave2d_utils.h" #include "../../lv_draw_rect.h" #include "../../lv_draw_line.h" @@ -33,8 +63,6 @@ extern "C" { * DEFINES *********************/ -#define D2_RENDER_EACH_OPERATION (1) - /********************** * TYPEDEFS **********************/ @@ -49,6 +77,8 @@ typedef struct { uint32_t idx; d2_device * d2_handle; d2_renderbuffer * renderbuffer; + d2_renderbuffer * label_renderbuffer; + #if LV_USE_OS lv_mutex_t * pd2Mutex; #endif @@ -103,4 +133,4 @@ void lv_draw_dave2d_transform(lv_draw_task_t * t, const lv_area_t * dest_area, c } /*extern "C"*/ #endif -#endif /*LV_USE_DRAW_DAVE2D*/ +#endif /*LV_DRAW_DAVE2D_H*/ diff --git a/src/draw/renesas/dave2d/lv_draw_dave2d_arc.c b/src/draw/renesas/dave2d/lv_draw_dave2d_arc.c index 42a7c27d20..5f8774aacb 100644 --- a/src/draw/renesas/dave2d/lv_draw_dave2d_arc.c +++ b/src/draw/renesas/dave2d/lv_draw_dave2d_arc.c @@ -46,10 +46,6 @@ void lv_draw_dave2d_arc(lv_draw_task_t * t, const lv_draw_arc_dsc_t * dsc, const LV_ASSERT(LV_RESULT_OK == status); #endif -#if D2_RENDER_EACH_OPERATION - d2_selectrenderbuffer(u->d2_handle, u->renderbuffer); -#endif - // // Generate render operations // @@ -171,15 +167,6 @@ void lv_draw_dave2d_arc(lv_draw_task_t * t, const lv_draw_arc_dsc_t * dsc, const } } - // - // Execute render operations - // - -#if D2_RENDER_EACH_OPERATION - d2_executerenderbuffer(u->d2_handle, u->renderbuffer, 0); - d2_flushframe(u->d2_handle); -#endif - #if LV_USE_OS status = lv_mutex_unlock(u->pd2Mutex); LV_ASSERT(LV_RESULT_OK == status); diff --git a/src/draw/renesas/dave2d/lv_draw_dave2d_border.c b/src/draw/renesas/dave2d/lv_draw_dave2d_border.c index 8298c2a9a4..b3b91c89b9 100644 --- a/src/draw/renesas/dave2d/lv_draw_dave2d_border.c +++ b/src/draw/renesas/dave2d/lv_draw_dave2d_border.c @@ -78,13 +78,6 @@ static void dave2d_draw_border_simple(lv_draw_task_t * t, const lv_area_t * oute lv_area_move(&local_outer_area, x, y); lv_area_move(&local_inner_area, x, y); -#if D2_RENDER_EACH_OPERATION - d2_selectrenderbuffer(u->d2_handle, u->renderbuffer); -#endif - // - // Generate render operations - // - d2_framebuffer_from_layer(u->d2_handle, t->target_layer); d2_setcolor(u->d2_handle, 0, lv_draw_dave2d_lv_colour_to_d2_colour(color)); @@ -143,14 +136,6 @@ static void dave2d_draw_border_simple(lv_draw_task_t * t, const lv_area_t * oute (d2_point)D2_FIX4(lv_area_get_height(&a))); } - // - // Execute render operations - // -#if D2_RENDER_EACH_OPERATION - d2_executerenderbuffer(u->d2_handle, u->renderbuffer, 0); - d2_flushframe(u->d2_handle); -#endif - #if LV_USE_OS status = lv_mutex_unlock(u->pd2Mutex); LV_ASSERT(LV_RESULT_OK == status); @@ -190,9 +175,6 @@ static void dave2d_draw_border_complex(lv_draw_task_t * t, const lv_area_t * ori lv_area_move(&outer_area, x, y); lv_area_move(&inner_area, x, y); -#if D2_RENDER_EACH_OPERATION - d2_selectrenderbuffer(u->d2_handle, u->renderbuffer); -#endif // // Generate render operations // @@ -402,14 +384,6 @@ static void dave2d_draw_border_complex(lv_draw_task_t * t, const lv_area_t * ori d2_setantialiasing(u->d2_handle, aa); //restore original setting } - // - // Execute render operations - // -#if D2_RENDER_EACH_OPERATION - d2_executerenderbuffer(u->d2_handle, u->renderbuffer, 0); - d2_flushframe(u->d2_handle); -#endif - #if LV_USE_OS status = lv_mutex_unlock(u->pd2Mutex); LV_ASSERT(LV_RESULT_OK == status); diff --git a/src/draw/renesas/dave2d/lv_draw_dave2d_fill.c b/src/draw/renesas/dave2d/lv_draw_dave2d_fill.c index 8a0eec2a86..66c6d994cc 100644 --- a/src/draw/renesas/dave2d/lv_draw_dave2d_fill.c +++ b/src/draw/renesas/dave2d/lv_draw_dave2d_fill.c @@ -34,13 +34,6 @@ void lv_draw_dave2d_fill(lv_draw_task_t * t, const lv_draw_fill_dsc_t * dsc, con lv_area_move(&draw_area, x, y); lv_area_move(&coordinates, x, y); - // - // Generate render operations - // -#if D2_RENDER_EACH_OPERATION - d2_selectrenderbuffer(u->d2_handle, u->renderbuffer); -#endif - d2_framebuffer_from_layer(u->d2_handle, t->target_layer); if(LV_GRAD_DIR_NONE != dsc->grad.dir) { @@ -63,8 +56,6 @@ void lv_draw_dave2d_fill(lv_draw_task_t * t, const lv_draw_fill_dsc_t * dsc, con y2 = (float)LV_MAX(coordinates.y1, coordinates.y2); if(a1 < a2) { - /* TODO */ - LV_ASSERT(0); y0 = 0.0f;//silence the compiler warning y3 = 0.0f; @@ -81,8 +72,6 @@ void lv_draw_dave2d_fill(lv_draw_task_t * t, const lv_draw_fill_dsc_t * dsc, con (d2_point)D2_FIX4((y3_i - y0_i))); } else if(LV_GRAD_DIR_HOR == dsc->grad.dir) { - /* TODO */ - LV_ASSERT(0); float x1; float x2; @@ -99,8 +88,6 @@ void lv_draw_dave2d_fill(lv_draw_task_t * t, const lv_draw_fill_dsc_t * dsc, con x2 = (float)LV_MAX(coordinates.x1, coordinates.x2); if(a1 < a2) { - /* TODO */ - LV_ASSERT(0); x0 = 0.0f;//silence the compiler warning x3 = 0.0f; @@ -289,14 +276,6 @@ void lv_draw_dave2d_fill(lv_draw_task_t * t, const lv_draw_fill_dsc_t * dsc, con } } - // - // Execute render operations - // -#if D2_RENDER_EACH_OPERATION - d2_executerenderbuffer(u->d2_handle, u->renderbuffer, 0); - d2_flushframe(u->d2_handle); -#endif - if(LV_GRAD_DIR_NONE != dsc->grad.dir) { d2_setalphamode(u->d2_handle, current_alpha_mode); d2_setfillmode(u->d2_handle, d2_fm_color); //default diff --git a/src/draw/renesas/dave2d/lv_draw_dave2d_image.c b/src/draw/renesas/dave2d/lv_draw_dave2d_image.c index af7892e066..76e6d054ae 100644 --- a/src/draw/renesas/dave2d/lv_draw_dave2d_image.c +++ b/src/draw/renesas/dave2d/lv_draw_dave2d_image.c @@ -102,11 +102,6 @@ static void img_draw_core(lv_draw_task_t * t, const lv_draw_image_dsc_t * draw_d lv_area_move(&buffer_area, x, y); lv_area_move(&clipped_area, x, y); - /* Generate render operations*/ -#if D2_RENDER_EACH_OPERATION - d2_selectrenderbuffer(u->d2_handle, u->renderbuffer); -#endif - current_fill_mode = d2_getfillmode(u->d2_handle); a_texture_op = d2_gettextureoperationa(u->d2_handle); r_texture_op = d2_gettextureoperationr(u->d2_handle); @@ -302,14 +297,6 @@ static void img_draw_core(lv_draw_task_t * t, const lv_draw_image_dsc_t * draw_d (d2_point)D2_FIX4(p[3].y), 0); - // - // Execute render operations - // -#if D2_RENDER_EACH_OPERATION - d2_executerenderbuffer(u->d2_handle, u->renderbuffer, 0); - d2_flushframe(u->d2_handle); -#endif - d2_setfillmode(u->d2_handle, current_fill_mode); d2_settextureoperation(u->d2_handle, a_texture_op, r_texture_op, g_texture_op, b_texture_op); d2_setblendmode(u->d2_handle, src_blend_mode, dst_blend_mode); diff --git a/src/draw/renesas/dave2d/lv_draw_dave2d_label.c b/src/draw/renesas/dave2d/lv_draw_dave2d_label.c index f16b08b234..fa146b7386 100644 --- a/src/draw/renesas/dave2d/lv_draw_dave2d_label.c +++ b/src/draw/renesas/dave2d/lv_draw_dave2d_label.c @@ -7,8 +7,6 @@ static void lv_draw_dave2d_draw_letter_cb(lv_draw_task_t * t, lv_draw_glyph_dsc_t * glyph_draw_dsc, lv_draw_fill_dsc_t * fill_draw_dsc, const lv_area_t * fill_area); -static lv_draw_dave2d_unit_t * unit = NULL; - void lv_draw_dave2d_label(lv_draw_task_t * t, const lv_draw_label_dsc_t * dsc, const lv_area_t * coords) { if(dsc->opa <= LV_OPA_MIN) return; @@ -20,49 +18,46 @@ void lv_draw_dave2d_label(lv_draw_task_t * t, const lv_draw_label_dsc_t * dsc, c static void lv_draw_dave2d_draw_letter_cb(lv_draw_task_t * t, lv_draw_glyph_dsc_t * glyph_draw_dsc, lv_draw_fill_dsc_t * fill_draw_dsc, const lv_area_t * fill_area) { + if(glyph_draw_dsc) { + d2_u8 current_fillmode; + lv_area_t clip_area; + lv_area_t letter_coords; - d2_u8 current_fillmode; - lv_area_t clip_area; - lv_area_t letter_coords; - - int32_t x; - int32_t y; + int32_t x; + int32_t y; - letter_coords = *glyph_draw_dsc->letter_coords; - lv_draw_dave2d_unit_t * unit = (lv_draw_dave2d_unit_t *)t->draw_unit; + letter_coords = *glyph_draw_dsc->letter_coords; + lv_draw_dave2d_unit_t * unit = (lv_draw_dave2d_unit_t *)t->draw_unit; - bool is_common; - is_common = lv_area_intersect(&clip_area, glyph_draw_dsc->letter_coords, &t->clip_area); - if(!is_common) return; + bool is_common; + is_common = lv_area_intersect(&clip_area, glyph_draw_dsc->letter_coords, &t->clip_area); + if(!is_common) return; - x = 0 - t->target_layer->buf_area.x1; - y = 0 - t->target_layer->buf_area.y1; + x = 0 - t->target_layer->buf_area.x1; + y = 0 - t->target_layer->buf_area.y1; - lv_area_move(&clip_area, x, y); - lv_area_move(&letter_coords, x, y); + lv_area_move(&clip_area, x, y); + lv_area_move(&letter_coords, x, y); #if LV_USE_OS - lv_result_t status; - status = lv_mutex_lock(unit->pd2Mutex); - LV_ASSERT(LV_RESULT_OK == status); + lv_result_t status; + status = lv_mutex_lock(unit->pd2Mutex); + LV_ASSERT(LV_RESULT_OK == status); #endif + /* Labels use their own render buffer, select it first. */ + d2_selectrenderbuffer(unit->d2_handle, unit->label_renderbuffer); -#if D2_RENDER_EACH_OPERATION - d2_selectrenderbuffer(unit->d2_handle, unit->renderbuffer); -#endif + // + // Generate render operations + // - // - // Generate render operations - // + d2_framebuffer_from_layer(unit->d2_handle, t->target_layer); - d2_framebuffer_from_layer(unit->d2_handle, t->target_layer); + current_fillmode = d2_getfillmode(unit->d2_handle); - current_fillmode = d2_getfillmode(unit->d2_handle); + d2_cliprect(unit->d2_handle, (d2_border)clip_area.x1, (d2_border)clip_area.y1, (d2_border)clip_area.x2, + (d2_border)clip_area.y2); - d2_cliprect(unit->d2_handle, (d2_border)clip_area.x1, (d2_border)clip_area.y1, (d2_border)clip_area.x2, - (d2_border)clip_area.y2); - - if(glyph_draw_dsc) { switch(glyph_draw_dsc->format) { case LV_FONT_GLYPH_FORMAT_NONE: { #if LV_USE_FONT_PLACEHOLDER @@ -91,7 +86,7 @@ static void lv_draw_dave2d_draw_letter_cb(lv_draw_task_t * t, lv_draw_glyph_dsc_ // blend_dsc.mask_res = LV_DRAW_SW_MASK_RES_CHANGED; //lv_draw_sw_blend(u, &blend_dsc); - lv_draw_buf_t * draw_buf = glyph_draw_dsc->glyph_data; + const lv_draw_buf_t * draw_buf = glyph_draw_dsc->glyph_data; #if defined(RENESAS_CORTEX_M85) #if (BSP_CFG_DCACHE_ENABLED) @@ -140,25 +135,27 @@ static void lv_draw_dave2d_draw_letter_cb(lv_draw_task_t * t, lv_draw_glyph_dsc_ default: break; } - } - // - // Execute render operations - // -#if D2_RENDER_EACH_OPERATION - d2_executerenderbuffer(unit->d2_handle, unit->renderbuffer, 0); - d2_flushframe(unit->d2_handle); + /* Drawing labels is a special case, because its draw buffer is shared + * between all the glyphs, then using the global render bufeer to defer + * its drawing later with other shapes, will corrupt the text drawn, + * instead, pushes all the glyph commands and its dedicated draw buffer + * to a specific render buffer, and draw it immediately while the contents + * are valid. + */ + d2_executerenderbuffer(unit->d2_handle, unit->label_renderbuffer, 0); + d2_flushframe(unit->d2_handle); + d2_selectrenderbuffer(unit->d2_handle, unit->renderbuffer); + +#if LV_USE_OS + status = lv_mutex_unlock(unit->pd2Mutex); + LV_ASSERT(LV_RESULT_OK == status); #endif + } if(fill_draw_dsc && fill_area) { - //lv_draw_sw_fill(u, fill_draw_dsc, fill_area); - lv_draw_dave2d_fill(t, fill_draw_dsc, fill_area); + lv_draw_dave2d_fill_single(t, fill_draw_dsc, fill_area); } - -#if LV_USE_OS - status = lv_mutex_unlock(unit->pd2Mutex); - LV_ASSERT(LV_RESULT_OK == status); -#endif } #endif /*LV_USE_DRAW_DAVE2D*/ diff --git a/src/draw/renesas/dave2d/lv_draw_dave2d_line.c b/src/draw/renesas/dave2d/lv_draw_dave2d_line.c index b6e7008dfb..947b669672 100644 --- a/src/draw/renesas/dave2d/lv_draw_dave2d_line.c +++ b/src/draw/renesas/dave2d/lv_draw_dave2d_line.c @@ -46,14 +46,6 @@ void lv_draw_dave2d_line(lv_draw_task_t * t, const lv_draw_line_dsc_t * dsc) bool dashed = dsc->dash_gap && dsc->dash_width; - if(dashed) { - /* TODO */ - LV_ASSERT(0); - } - -#if D2_RENDER_EACH_OPERATION - d2_selectrenderbuffer(u->d2_handle, u->renderbuffer); -#endif // // Generate render operations // @@ -77,14 +69,6 @@ void lv_draw_dave2d_line(lv_draw_task_t * t, const lv_draw_line_dsc_t * dsc) d2_renderline(u->d2_handle, D2_FIX4(p1_x), D2_FIX4(p1_y), D2_FIX4(p2_x), D2_FIX4(p2_y), D2_FIX4(dsc->width), d2_le_exclude_none); - // - // Execute render operations - // -#if D2_RENDER_EACH_OPERATION - d2_executerenderbuffer(u->d2_handle, u->renderbuffer, 0); - d2_flushframe(u->d2_handle); -#endif - #if LV_USE_OS status = lv_mutex_unlock(u->pd2Mutex); LV_ASSERT(LV_RESULT_OK == status); diff --git a/src/draw/renesas/dave2d/lv_draw_dave2d_mask_rectangle.c b/src/draw/renesas/dave2d/lv_draw_dave2d_mask_rectangle.c index ea880509dd..ccbded6a20 100644 --- a/src/draw/renesas/dave2d/lv_draw_dave2d_mask_rectangle.c +++ b/src/draw/renesas/dave2d/lv_draw_dave2d_mask_rectangle.c @@ -29,10 +29,6 @@ void lv_draw_dave2d_mask_rect(lv_draw_task_t * t, const lv_draw_mask_rect_dsc_t LV_ASSERT(LV_RESULT_OK == status); #endif -#ifdef D2_RENDER_EACH_OPERATION - d2_selectrenderbuffer(u->d2_handle, u->renderbuffer); -#endif - d2_framebuffer_from_layer(u->d2_handle, t->target_layer); d2_cliprect(u->d2_handle, (d2_border)clipped_area.x1, (d2_border)clipped_area.y1, (d2_border)clipped_area.x2, @@ -44,14 +40,6 @@ void lv_draw_dave2d_mask_rect(lv_draw_task_t * t, const lv_draw_mask_rect_dsc_t (d2_width) D2_FIX4(lv_area_get_width(&coordinates)), (d2_width) D2_FIX4(lv_area_get_height(&coordinates))); - // - // Execute render operations - // -#ifdef D2_RENDER_EACH_OPERATION - d2_executerenderbuffer(u->d2_handle, u->renderbuffer, 0); - d2_flushframe(u->d2_handle); -#endif - #if LV_USE_OS status = lv_mutex_unlock(u->pd2Mutex); LV_ASSERT(LV_RESULT_OK == status); diff --git a/src/draw/renesas/dave2d/lv_draw_dave2d_triangle.c b/src/draw/renesas/dave2d/lv_draw_dave2d_triangle.c index 74fd5095a4..21f3cef407 100644 --- a/src/draw/renesas/dave2d/lv_draw_dave2d_triangle.c +++ b/src/draw/renesas/dave2d/lv_draw_dave2d_triangle.c @@ -31,10 +31,6 @@ void lv_draw_dave2d_triangle(lv_draw_task_t * t, const lv_draw_triangle_dsc_t * lv_area_move(&clipped_area, x, y); -#if D2_RENDER_EACH_OPERATION - d2_selectrenderbuffer(u->d2_handle, u->renderbuffer); -#endif - lv_point_precise_t p[3]; p[0] = dsc->p[0]; p[1] = dsc->p[1]; @@ -112,8 +108,6 @@ void lv_draw_dave2d_triangle(lv_draw_task_t * t, const lv_draw_triangle_dsc_t * y2 = LV_MAX3(p[0].y, p[1].y, p[2].y); if(a1 < a2) { - /* TODO */ - LV_ASSERT(0); y0 = 0.0f;//silence the compiler warning y3 = 0.0f; @@ -128,10 +122,7 @@ void lv_draw_dave2d_triangle(lv_draw_task_t * t, const lv_draw_triangle_dsc_t * d2_setalphagradient(u->d2_handle, 0, D2_FIX4(0), D2_FIX4(y0_i), D2_FIX4(0), D2_FIX4((y3_i - y0_i))); } - else if(LV_GRAD_DIR_HOR == dsc->grad.dir) { - /* TODO */ - LV_ASSERT(0); - } + d2_setcolor(u->d2_handle, 0, lv_draw_dave2d_lv_colour_to_d2_colour(dsc->grad.stops[0].color)); d2_setalphamode(u->d2_handle, d2_am_gradient1); @@ -157,14 +148,6 @@ void lv_draw_dave2d_triangle(lv_draw_task_t * t, const lv_draw_triangle_dsc_t * (d2_point) D2_FIX4(p[2].y), flags); - // - // Execute render operations - // -#if D2_RENDER_EACH_OPERATION - d2_executerenderbuffer(u->d2_handle, u->renderbuffer, 0); - d2_flushframe(u->d2_handle); -#endif - d2_setalphamode(u->d2_handle, current_alpha_mode); #if LV_USE_OS diff --git a/src/draw/renesas/dave2d/lv_draw_dave2d_utils.c b/src/draw/renesas/dave2d/lv_draw_dave2d_utils.c index 666a5c4164..e43ad4e7c2 100644 --- a/src/draw/renesas/dave2d/lv_draw_dave2d_utils.c +++ b/src/draw/renesas/dave2d/lv_draw_dave2d_utils.c @@ -64,36 +64,6 @@ d2_color lv_draw_dave2d_lv_colour_to_d2_colour(lv_color_t color) | (blue) << 0UL; } -d2_s32 lv_draw_dave2d_cf_fb_get(void) -{ - d2_s32 d2_fb_mode = 0; - switch(g_display0_cfg.input->format) { - case DISPLAY_IN_FORMAT_16BITS_RGB565: ///< RGB565, 16 bits - d2_fb_mode = d2_mode_rgb565; - break; - case DISPLAY_IN_FORMAT_32BITS_ARGB8888: ///< ARGB8888, 32 bits - d2_fb_mode = d2_mode_argb8888; - break; - case DISPLAY_IN_FORMAT_32BITS_RGB888: ///< RGB888, 32 bits - d2_fb_mode = d2_mode_argb8888; //GLCDC ignores Alpha when configured for RGB888 - break; - case DISPLAY_IN_FORMAT_16BITS_ARGB4444: ///< ARGB4444, 16 bits - d2_fb_mode = d2_mode_argb4444; - break; - case DISPLAY_IN_FORMAT_16BITS_ARGB1555: ///< ARGB1555, 16 bits - case DISPLAY_IN_FORMAT_CLUT8 : ///< CLUT8 - case DISPLAY_IN_FORMAT_CLUT4 : ///< CLUT4 - case DISPLAY_IN_FORMAT_CLUT1 : ///< CLUT1 - //Not supported as a FB format by Dave2D - break; - - default: - break; - } - - return d2_fb_mode; -} - d2_u32 lv_draw_dave2d_lv_colour_fmt_to_d2_fmt(lv_color_format_t colour_format) { d2_u32 d2_lvgl_mode = 0; diff --git a/src/draw/renesas/dave2d/lv_draw_dave2d_utils.h b/src/draw/renesas/dave2d/lv_draw_dave2d_utils.h index db9a178177..90a6fe4e96 100644 --- a/src/draw/renesas/dave2d/lv_draw_dave2d_utils.h +++ b/src/draw/renesas/dave2d/lv_draw_dave2d_utils.h @@ -28,8 +28,6 @@ extern "C" { d2_color lv_draw_dave2d_lv_colour_to_d2_colour(lv_color_t color); -d2_s32 lv_draw_dave2d_cf_fb_get(void); - d2_u32 lv_draw_dave2d_lv_colour_fmt_to_d2_fmt(lv_color_format_t colour_format); void d2_framebuffer_from_layer(d2_device * handle, lv_layer_t * layer); diff --git a/src/draw/sdl/lv_draw_sdl.c b/src/draw/sdl/lv_draw_sdl.c index 4b7d3dd77d..61113913d3 100644 --- a/src/draw/sdl/lv_draw_sdl.c +++ b/src/draw/sdl/lv_draw_sdl.c @@ -163,7 +163,7 @@ static int32_t dispatch(lv_draw_unit_t * draw_unit, lv_layer_t * layer) execute_drawing(draw_sdl_unit); - draw_sdl_unit->task_act->state = LV_DRAW_TASK_STATE_READY; + draw_sdl_unit->task_act->state = LV_DRAW_TASK_STATE_FINISHED; draw_sdl_unit->task_act = NULL; /*The draw unit is free now. Request a new dispatching as it can get a new task*/ diff --git a/src/draw/sdl/lv_draw_sdl.h b/src/draw/sdl/lv_draw_sdl.h index db1a4a8a32..90ff8de3a0 100644 --- a/src/draw/sdl/lv_draw_sdl.h +++ b/src/draw/sdl/lv_draw_sdl.h @@ -17,11 +17,10 @@ extern "C" { #if LV_USE_DRAW_SDL -#include "../../misc/cache/lv_cache.h" #include "../../misc/lv_area.h" #include "../../misc/lv_color.h" #include "../../display/lv_display.h" -#include "../../osal/lv_os.h" +#include "../../osal/lv_os_private.h" #include "../../draw/lv_draw_label.h" #include "../../draw/lv_draw_rect.h" #include "../../draw/lv_draw_arc.h" diff --git a/src/draw/sw/blend/helium/lv_blend_helium.S b/src/draw/sw/blend/helium/lv_blend_helium.S index bab4b72ac4..41edbb31ea 100644 --- a/src/draw/sw/blend/helium/lv_blend_helium.S +++ b/src/draw/sw/blend/helium/lv_blend_helium.S @@ -671,15 +671,15 @@ BITMASK .req q6 .macro export_set src, dst, src_bpp, dst_bpp, mode .ifc \src, color - export lv_\src\()_blend_to_\dst\()_helium, \src_bpp, \dst_bpp, 0, 0, \mode - export lv_\src\()_blend_to_\dst\()_with_opa_helium, \src_bpp, \dst_bpp, 0, 1, \mode - export lv_\src\()_blend_to_\dst\()_with_mask_helium, \src_bpp, \dst_bpp, 1, 0, \mode - export lv_\src\()_blend_to_\dst\()_mix_mask_opa_helium, \src_bpp, \dst_bpp, 1, 1, \mode + export _lv_\src\()_blend_to_\dst\()_helium, \src_bpp, \dst_bpp, 0, 0, \mode + export _lv_\src\()_blend_to_\dst\()_with_opa_helium, \src_bpp, \dst_bpp, 0, 1, \mode + export _lv_\src\()_blend_to_\dst\()_with_mask_helium, \src_bpp, \dst_bpp, 1, 0, \mode + export _lv_\src\()_blend_to_\dst\()_mix_mask_opa_helium, \src_bpp, \dst_bpp, 1, 1, \mode .else - export lv_\src\()_blend_\mode\()_to_\dst\()_helium, \src_bpp, \dst_bpp, 0, 0, \mode - export lv_\src\()_blend_\mode\()_to_\dst\()_with_opa_helium, \src_bpp, \dst_bpp, 0, 1, \mode - export lv_\src\()_blend_\mode\()_to_\dst\()_with_mask_helium, \src_bpp, \dst_bpp, 1, 0, \mode - export lv_\src\()_blend_\mode\()_to_\dst\()_mix_mask_opa_helium, \src_bpp, \dst_bpp, 1, 1, \mode + export _lv_\src\()_blend_\mode\()_to_\dst\()_helium, \src_bpp, \dst_bpp, 0, 0, \mode + export _lv_\src\()_blend_\mode\()_to_\dst\()_with_opa_helium, \src_bpp, \dst_bpp, 0, 1, \mode + export _lv_\src\()_blend_\mode\()_to_\dst\()_with_mask_helium, \src_bpp, \dst_bpp, 1, 0, \mode + export _lv_\src\()_blend_\mode\()_to_\dst\()_mix_mask_opa_helium, \src_bpp, \dst_bpp, 1, 1, \mode .endif .endm diff --git a/src/draw/sw/blend/helium/lv_blend_helium.h b/src/draw/sw/blend/helium/lv_blend_helium.h index 69b999efcc..ed45b2bc27 100644 --- a/src/draw/sw/blend/helium/lv_blend_helium.h +++ b/src/draw/sw/blend/helium/lv_blend_helium.h @@ -30,6 +30,12 @@ extern "C" { #if !defined(__ASSEMBLY__) +#if __GNUC__ >= 4 +#define LVGL_HIDDEN __attribute__((visibility("hidden"))) +#else +#define LVGL_HIDDEN +#endif + /* Use arm2d functions if present */ #include "../arm2d/lv_blend_arm2d.h" @@ -298,7 +304,7 @@ typedef struct { * GLOBAL PROTOTYPES **********************/ -extern void lv_color_blend_to_rgb565_helium(asm_dsc_t * dsc); +extern LVGL_HIDDEN void _lv_color_blend_to_rgb565_helium(asm_dsc_t * dsc); static inline lv_result_t lv_color_blend_to_rgb565_helium(lv_draw_sw_blend_fill_dsc_t * dsc) { asm_dsc_t asm_dsc = { @@ -309,11 +315,11 @@ static inline lv_result_t lv_color_blend_to_rgb565_helium(lv_draw_sw_blend_fill_ .src_buf = &dsc->color }; - lv_color_blend_to_rgb565_helium(&asm_dsc); + _lv_color_blend_to_rgb565_helium(&asm_dsc); return LV_RESULT_OK; } -extern void lv_color_blend_to_rgb565_with_opa_helium(asm_dsc_t * dsc); +extern LVGL_HIDDEN void _lv_color_blend_to_rgb565_with_opa_helium(asm_dsc_t * dsc); static inline lv_result_t lv_color_blend_to_rgb565_with_opa_helium(lv_draw_sw_blend_fill_dsc_t * dsc) { asm_dsc_t asm_dsc = { @@ -324,11 +330,11 @@ static inline lv_result_t lv_color_blend_to_rgb565_with_opa_helium(lv_draw_sw_bl .dst_stride = dsc->dest_stride, .src_buf = &dsc->color }; - lv_color_blend_to_rgb565_with_opa_helium(&asm_dsc); + _lv_color_blend_to_rgb565_with_opa_helium(&asm_dsc); return LV_RESULT_OK; } -extern void lv_color_blend_to_rgb565_with_mask_helium(asm_dsc_t * dsc); +extern LVGL_HIDDEN void _lv_color_blend_to_rgb565_with_mask_helium(asm_dsc_t * dsc); static inline lv_result_t lv_color_blend_to_rgb565_with_mask_helium(lv_draw_sw_blend_fill_dsc_t * dsc) { asm_dsc_t asm_dsc = { @@ -340,11 +346,11 @@ static inline lv_result_t lv_color_blend_to_rgb565_with_mask_helium(lv_draw_sw_b .mask_buf = dsc->mask_buf, .mask_stride = dsc->mask_stride }; - lv_color_blend_to_rgb565_with_mask_helium(&asm_dsc); + _lv_color_blend_to_rgb565_with_mask_helium(&asm_dsc); return LV_RESULT_OK; } -extern void lv_color_blend_to_rgb565_mix_mask_opa_helium(asm_dsc_t * dsc); +extern LVGL_HIDDEN void _lv_color_blend_to_rgb565_mix_mask_opa_helium(asm_dsc_t * dsc); static inline lv_result_t lv_color_blend_to_rgb565_mix_mask_opa_helium(lv_draw_sw_blend_fill_dsc_t * dsc) { asm_dsc_t asm_dsc = { @@ -357,11 +363,11 @@ static inline lv_result_t lv_color_blend_to_rgb565_mix_mask_opa_helium(lv_draw_s .mask_buf = dsc->mask_buf, .mask_stride = dsc->mask_stride }; - lv_color_blend_to_rgb565_mix_mask_opa_helium(&asm_dsc); + _lv_color_blend_to_rgb565_mix_mask_opa_helium(&asm_dsc); return LV_RESULT_OK; } -extern void lv_rgb565_blend_normal_to_rgb565_helium(asm_dsc_t * dsc); +extern LVGL_HIDDEN void _lv_rgb565_blend_normal_to_rgb565_helium(asm_dsc_t * dsc); static inline lv_result_t lv_rgb565_blend_normal_to_rgb565_helium(lv_draw_sw_blend_image_dsc_t * dsc) { asm_dsc_t asm_dsc = { @@ -372,11 +378,11 @@ static inline lv_result_t lv_rgb565_blend_normal_to_rgb565_helium(lv_draw_sw_ble .src_buf = dsc->src_buf, .src_stride = dsc->src_stride }; - lv_rgb565_blend_normal_to_rgb565_helium(&asm_dsc); + _lv_rgb565_blend_normal_to_rgb565_helium(&asm_dsc); return LV_RESULT_OK; } -extern void lv_rgb565_blend_normal_to_rgb565_with_opa_helium(asm_dsc_t * dsc); +extern LVGL_HIDDEN void _lv_rgb565_blend_normal_to_rgb565_with_opa_helium(asm_dsc_t * dsc); static inline lv_result_t lv_rgb565_blend_normal_to_rgb565_with_opa_helium(lv_draw_sw_blend_image_dsc_t * dsc) { asm_dsc_t asm_dsc = { @@ -388,11 +394,11 @@ static inline lv_result_t lv_rgb565_blend_normal_to_rgb565_with_opa_helium(lv_dr .src_buf = dsc->src_buf, .src_stride = dsc->src_stride }; - lv_rgb565_blend_normal_to_rgb565_with_opa_helium(&asm_dsc); + _lv_rgb565_blend_normal_to_rgb565_with_opa_helium(&asm_dsc); return LV_RESULT_OK; } -extern void lv_rgb565_blend_normal_to_rgb565_with_mask_helium(asm_dsc_t * dsc); +extern LVGL_HIDDEN void _lv_rgb565_blend_normal_to_rgb565_with_mask_helium(asm_dsc_t * dsc); static inline lv_result_t lv_rgb565_blend_normal_to_rgb565_with_mask_helium(lv_draw_sw_blend_image_dsc_t * dsc) { asm_dsc_t asm_dsc = { @@ -405,11 +411,11 @@ static inline lv_result_t lv_rgb565_blend_normal_to_rgb565_with_mask_helium(lv_d .mask_buf = dsc->mask_buf, .mask_stride = dsc->mask_stride }; - lv_rgb565_blend_normal_to_rgb565_with_mask_helium(&asm_dsc); + _lv_rgb565_blend_normal_to_rgb565_with_mask_helium(&asm_dsc); return LV_RESULT_OK; } -extern void lv_rgb565_blend_normal_to_rgb565_mix_mask_opa_helium(asm_dsc_t * dsc); +extern LVGL_HIDDEN void _lv_rgb565_blend_normal_to_rgb565_mix_mask_opa_helium(asm_dsc_t * dsc); static inline lv_result_t lv_rgb565_blend_normal_to_rgb565_mix_mask_opa_helium(lv_draw_sw_blend_image_dsc_t * dsc) { asm_dsc_t asm_dsc = { @@ -423,12 +429,12 @@ static inline lv_result_t lv_rgb565_blend_normal_to_rgb565_mix_mask_opa_helium(l .mask_buf = dsc->mask_buf, .mask_stride = dsc->mask_stride }; - lv_rgb565_blend_normal_to_rgb565_mix_mask_opa_helium(&asm_dsc); + _lv_rgb565_blend_normal_to_rgb565_mix_mask_opa_helium(&asm_dsc); return LV_RESULT_OK; } -extern void lv_rgb888_blend_normal_to_rgb565_helium(asm_dsc_t * dsc); -extern void lv_xrgb8888_blend_normal_to_rgb565_helium(asm_dsc_t * dsc); +extern LVGL_HIDDEN void _lv_rgb888_blend_normal_to_rgb565_helium(asm_dsc_t * dsc); +extern LVGL_HIDDEN void _lv_xrgb8888_blend_normal_to_rgb565_helium(asm_dsc_t * dsc); static inline lv_result_t lv_rgb888_blend_normal_to_rgb565_helium(lv_draw_sw_blend_image_dsc_t * dsc, uint32_t src_px_size) { @@ -441,16 +447,16 @@ static inline lv_result_t lv_rgb888_blend_normal_to_rgb565_helium(lv_draw_sw_ble .src_stride = dsc->src_stride }; if(src_px_size == 3) { - lv_rgb888_blend_normal_to_rgb565_helium(&asm_dsc); + _lv_rgb888_blend_normal_to_rgb565_helium(&asm_dsc); } else { - lv_xrgb8888_blend_normal_to_rgb565_helium(&asm_dsc); + _lv_xrgb8888_blend_normal_to_rgb565_helium(&asm_dsc); } return LV_RESULT_OK; } -extern void lv_rgb888_blend_normal_to_rgb565_with_opa_helium(asm_dsc_t * dsc); -extern void lv_xrgb8888_blend_normal_to_rgb565_with_opa_helium(asm_dsc_t * dsc); +extern LVGL_HIDDEN void _lv_rgb888_blend_normal_to_rgb565_with_opa_helium(asm_dsc_t * dsc); +extern LVGL_HIDDEN void _lv_xrgb8888_blend_normal_to_rgb565_with_opa_helium(asm_dsc_t * dsc); static inline lv_result_t lv_rgb888_blend_normal_to_rgb565_with_opa_helium(lv_draw_sw_blend_image_dsc_t * dsc, uint32_t src_px_size) { @@ -464,16 +470,16 @@ static inline lv_result_t lv_rgb888_blend_normal_to_rgb565_with_opa_helium(lv_dr .src_stride = dsc->src_stride }; if(src_px_size == 3) { - lv_rgb888_blend_normal_to_rgb565_with_opa_helium(&asm_dsc); + _lv_rgb888_blend_normal_to_rgb565_with_opa_helium(&asm_dsc); } else { - lv_xrgb8888_blend_normal_to_rgb565_with_opa_helium(&asm_dsc); + _lv_xrgb8888_blend_normal_to_rgb565_with_opa_helium(&asm_dsc); } return LV_RESULT_OK; } -extern void lv_rgb888_blend_normal_to_rgb565_with_mask_helium(asm_dsc_t * dsc); -extern void lv_xrgb8888_blend_normal_to_rgb565_with_mask_helium(asm_dsc_t * dsc); +extern LVGL_HIDDEN void _lv_rgb888_blend_normal_to_rgb565_with_mask_helium(asm_dsc_t * dsc); +extern LVGL_HIDDEN void _lv_xrgb8888_blend_normal_to_rgb565_with_mask_helium(asm_dsc_t * dsc); static inline lv_result_t lv_rgb888_blend_normal_to_rgb565_with_mask_helium(lv_draw_sw_blend_image_dsc_t * dsc, uint32_t src_px_size) { @@ -488,16 +494,16 @@ static inline lv_result_t lv_rgb888_blend_normal_to_rgb565_with_mask_helium(lv_d .mask_stride = dsc->mask_stride }; if(src_px_size == 3) { - lv_rgb888_blend_normal_to_rgb565_with_mask_helium(&asm_dsc); + _lv_rgb888_blend_normal_to_rgb565_with_mask_helium(&asm_dsc); } else { - lv_xrgb8888_blend_normal_to_rgb565_with_mask_helium(&asm_dsc); + _lv_xrgb8888_blend_normal_to_rgb565_with_mask_helium(&asm_dsc); } return LV_RESULT_OK; } -extern void lv_rgb888_blend_normal_to_rgb565_mix_mask_opa_helium(asm_dsc_t * dsc); -extern void lv_xrgb8888_blend_normal_to_rgb565_mix_mask_opa_helium(asm_dsc_t * dsc); +extern LVGL_HIDDEN void _lv_rgb888_blend_normal_to_rgb565_mix_mask_opa_helium(asm_dsc_t * dsc); +extern LVGL_HIDDEN void _lv_xrgb8888_blend_normal_to_rgb565_mix_mask_opa_helium(asm_dsc_t * dsc); static inline lv_result_t lv_rgb888_blend_normal_to_rgb565_mix_mask_opa_helium(lv_draw_sw_blend_image_dsc_t * dsc, uint32_t src_px_size) { @@ -513,15 +519,15 @@ static inline lv_result_t lv_rgb888_blend_normal_to_rgb565_mix_mask_opa_helium(l .mask_stride = dsc->mask_stride }; if(src_px_size == 3) { - lv_rgb888_blend_normal_to_rgb565_mix_mask_opa_helium(&asm_dsc); + _lv_rgb888_blend_normal_to_rgb565_mix_mask_opa_helium(&asm_dsc); } else { - lv_xrgb8888_blend_normal_to_rgb565_mix_mask_opa_helium(&asm_dsc); + _lv_xrgb8888_blend_normal_to_rgb565_mix_mask_opa_helium(&asm_dsc); } return LV_RESULT_OK; } -extern void lv_argb8888_blend_normal_to_rgb565_helium(asm_dsc_t * dsc); +extern LVGL_HIDDEN void _lv_argb8888_blend_normal_to_rgb565_helium(asm_dsc_t * dsc); static inline lv_result_t lv_argb8888_blend_normal_to_rgb565_helium(lv_draw_sw_blend_image_dsc_t * dsc) { asm_dsc_t asm_dsc = { @@ -532,11 +538,11 @@ static inline lv_result_t lv_argb8888_blend_normal_to_rgb565_helium(lv_draw_sw_b .src_buf = dsc->src_buf, .src_stride = dsc->src_stride }; - lv_argb8888_blend_normal_to_rgb565_helium(&asm_dsc); + _lv_argb8888_blend_normal_to_rgb565_helium(&asm_dsc); return LV_RESULT_OK; } -extern void lv_argb8888_blend_normal_to_rgb565_with_opa_helium(asm_dsc_t * dsc); +extern LVGL_HIDDEN void _lv_argb8888_blend_normal_to_rgb565_with_opa_helium(asm_dsc_t * dsc); static inline lv_result_t lv_argb8888_blend_normal_to_rgb565_with_opa_helium(lv_draw_sw_blend_image_dsc_t * dsc) { asm_dsc_t asm_dsc = { @@ -548,11 +554,11 @@ static inline lv_result_t lv_argb8888_blend_normal_to_rgb565_with_opa_helium(lv_ .src_buf = dsc->src_buf, .src_stride = dsc->src_stride }; - lv_argb8888_blend_normal_to_rgb565_with_opa_helium(&asm_dsc); + _lv_argb8888_blend_normal_to_rgb565_with_opa_helium(&asm_dsc); return LV_RESULT_OK; } -extern void lv_argb8888_blend_normal_to_rgb565_with_mask_helium(asm_dsc_t * dsc); +extern LVGL_HIDDEN void _lv_argb8888_blend_normal_to_rgb565_with_mask_helium(asm_dsc_t * dsc); static inline lv_result_t lv_argb8888_blend_normal_to_rgb565_with_mask_helium(lv_draw_sw_blend_image_dsc_t * dsc) { asm_dsc_t asm_dsc = { @@ -565,11 +571,11 @@ static inline lv_result_t lv_argb8888_blend_normal_to_rgb565_with_mask_helium(lv .mask_buf = dsc->mask_buf, .mask_stride = dsc->mask_stride }; - lv_argb8888_blend_normal_to_rgb565_with_mask_helium(&asm_dsc); + _lv_argb8888_blend_normal_to_rgb565_with_mask_helium(&asm_dsc); return LV_RESULT_OK; } -extern void lv_argb8888_blend_normal_to_rgb565_mix_mask_opa_helium(asm_dsc_t * dsc); +extern LVGL_HIDDEN void _lv_argb8888_blend_normal_to_rgb565_mix_mask_opa_helium(asm_dsc_t * dsc); static inline lv_result_t lv_argb8888_blend_normal_to_rgb565_mix_mask_opa_helium(lv_draw_sw_blend_image_dsc_t * dsc) { asm_dsc_t asm_dsc = { @@ -583,12 +589,12 @@ static inline lv_result_t lv_argb8888_blend_normal_to_rgb565_mix_mask_opa_helium .mask_buf = dsc->mask_buf, .mask_stride = dsc->mask_stride }; - lv_argb8888_blend_normal_to_rgb565_mix_mask_opa_helium(&asm_dsc); + _lv_argb8888_blend_normal_to_rgb565_mix_mask_opa_helium(&asm_dsc); return LV_RESULT_OK; } -extern void lv_color_blend_to_rgb888_helium(asm_dsc_t * dsc); -extern void lv_color_blend_to_xrgb8888_helium(asm_dsc_t * dsc); +extern LVGL_HIDDEN void _lv_color_blend_to_rgb888_helium(asm_dsc_t * dsc); +extern LVGL_HIDDEN void _lv_color_blend_to_xrgb8888_helium(asm_dsc_t * dsc); static inline lv_result_t lv_color_blend_to_rgb888_helium(lv_draw_sw_blend_fill_dsc_t * dsc, uint32_t dst_px_size) { asm_dsc_t asm_dsc = { @@ -599,16 +605,16 @@ static inline lv_result_t lv_color_blend_to_rgb888_helium(lv_draw_sw_blend_fill_ .src_buf = &dsc->color }; if(dst_px_size == 3) { - lv_color_blend_to_rgb888_helium(&asm_dsc); + _lv_color_blend_to_rgb888_helium(&asm_dsc); } else { - lv_color_blend_to_xrgb8888_helium(&asm_dsc); + _lv_color_blend_to_xrgb8888_helium(&asm_dsc); } return LV_RESULT_OK; } -extern void lv_color_blend_to_rgb888_with_opa_helium(asm_dsc_t * dsc); -extern void lv_color_blend_to_xrgb8888_with_opa_helium(asm_dsc_t * dsc); +extern LVGL_HIDDEN void _lv_color_blend_to_rgb888_with_opa_helium(asm_dsc_t * dsc); +extern LVGL_HIDDEN void _lv_color_blend_to_xrgb8888_with_opa_helium(asm_dsc_t * dsc); static inline lv_result_t lv_color_blend_to_rgb888_with_opa_helium(lv_draw_sw_blend_fill_dsc_t * dsc, uint32_t dst_px_size) { @@ -621,16 +627,16 @@ static inline lv_result_t lv_color_blend_to_rgb888_with_opa_helium(lv_draw_sw_bl .src_buf = &dsc->color }; if(dst_px_size == 3) { - lv_color_blend_to_rgb888_with_opa_helium(&asm_dsc); + _lv_color_blend_to_rgb888_with_opa_helium(&asm_dsc); } else { - lv_color_blend_to_xrgb8888_with_opa_helium(&asm_dsc); + _lv_color_blend_to_xrgb8888_with_opa_helium(&asm_dsc); } return LV_RESULT_OK; } -extern void lv_color_blend_to_rgb888_with_mask_helium(asm_dsc_t * dsc); -extern void lv_color_blend_to_xrgb8888_with_mask_helium(asm_dsc_t * dsc); +extern LVGL_HIDDEN void _lv_color_blend_to_rgb888_with_mask_helium(asm_dsc_t * dsc); +extern LVGL_HIDDEN void _lv_color_blend_to_xrgb8888_with_mask_helium(asm_dsc_t * dsc); static inline lv_result_t lv_color_blend_to_rgb888_with_mask_helium(lv_draw_sw_blend_fill_dsc_t * dsc, uint32_t dst_px_size) { @@ -644,16 +650,16 @@ static inline lv_result_t lv_color_blend_to_rgb888_with_mask_helium(lv_draw_sw_b .mask_stride = dsc->mask_stride }; if(dst_px_size == 3) { - lv_color_blend_to_rgb888_with_mask_helium(&asm_dsc); + _lv_color_blend_to_rgb888_with_mask_helium(&asm_dsc); } else { - lv_color_blend_to_xrgb8888_with_mask_helium(&asm_dsc); + _lv_color_blend_to_xrgb8888_with_mask_helium(&asm_dsc); } return LV_RESULT_OK; } -extern void lv_color_blend_to_rgb888_mix_mask_opa_helium(asm_dsc_t * dsc); -extern void lv_color_blend_to_xrgb8888_mix_mask_opa_helium(asm_dsc_t * dsc); +extern LVGL_HIDDEN void _lv_color_blend_to_rgb888_mix_mask_opa_helium(asm_dsc_t * dsc); +extern LVGL_HIDDEN void _lv_color_blend_to_xrgb8888_mix_mask_opa_helium(asm_dsc_t * dsc); static inline lv_result_t lv_color_blend_to_rgb888_mix_mask_opa_helium(lv_draw_sw_blend_fill_dsc_t * dsc, uint32_t dst_px_size) { @@ -668,16 +674,16 @@ static inline lv_result_t lv_color_blend_to_rgb888_mix_mask_opa_helium(lv_draw_s .mask_stride = dsc->mask_stride }; if(dst_px_size == 3) { - lv_color_blend_to_rgb888_mix_mask_opa_helium(&asm_dsc); + _lv_color_blend_to_rgb888_mix_mask_opa_helium(&asm_dsc); } else { - lv_color_blend_to_xrgb8888_mix_mask_opa_helium(&asm_dsc); + _lv_color_blend_to_xrgb8888_mix_mask_opa_helium(&asm_dsc); } return LV_RESULT_OK; } -extern void lv_rgb565_blend_normal_to_rgb888_helium(asm_dsc_t * dsc); -extern void lv_rgb565_blend_normal_to_xrgb8888_helium(asm_dsc_t * dsc); +extern LVGL_HIDDEN void _lv_rgb565_blend_normal_to_rgb888_helium(asm_dsc_t * dsc); +extern LVGL_HIDDEN void _lv_rgb565_blend_normal_to_xrgb8888_helium(asm_dsc_t * dsc); static inline lv_result_t lv_rgb565_blend_normal_to_rgb888_helium(lv_draw_sw_blend_image_dsc_t * dsc, uint32_t dst_px_size) { @@ -690,16 +696,16 @@ static inline lv_result_t lv_rgb565_blend_normal_to_rgb888_helium(lv_draw_sw_ble .src_stride = dsc->src_stride }; if(dst_px_size == 3) { - lv_rgb565_blend_normal_to_rgb888_helium(&asm_dsc); + _lv_rgb565_blend_normal_to_rgb888_helium(&asm_dsc); } else { - lv_rgb565_blend_normal_to_xrgb8888_helium(&asm_dsc); + _lv_rgb565_blend_normal_to_xrgb8888_helium(&asm_dsc); } return LV_RESULT_OK; } -extern void lv_rgb565_blend_normal_to_rgb888_with_opa_helium(asm_dsc_t * dsc); -extern void lv_rgb565_blend_normal_to_xrgb8888_with_opa_helium(asm_dsc_t * dsc); +extern LVGL_HIDDEN void _lv_rgb565_blend_normal_to_rgb888_with_opa_helium(asm_dsc_t * dsc); +extern LVGL_HIDDEN void _lv_rgb565_blend_normal_to_xrgb8888_with_opa_helium(asm_dsc_t * dsc); static inline lv_result_t lv_rgb565_blend_normal_to_rgb888_with_opa_helium(lv_draw_sw_blend_image_dsc_t * dsc, uint32_t dst_px_size) { @@ -713,16 +719,16 @@ static inline lv_result_t lv_rgb565_blend_normal_to_rgb888_with_opa_helium(lv_dr .src_stride = dsc->src_stride }; if(dst_px_size == 3) { - lv_rgb565_blend_normal_to_rgb888_with_opa_helium(&asm_dsc); + _lv_rgb565_blend_normal_to_rgb888_with_opa_helium(&asm_dsc); } else { - lv_rgb565_blend_normal_to_xrgb8888_with_opa_helium(&asm_dsc); + _lv_rgb565_blend_normal_to_xrgb8888_with_opa_helium(&asm_dsc); } return LV_RESULT_OK; } -extern void lv_rgb565_blend_normal_to_rgb888_with_mask_helium(asm_dsc_t * dsc); -extern void lv_rgb565_blend_normal_to_xrgb8888_with_mask_helium(asm_dsc_t * dsc); +extern LVGL_HIDDEN void _lv_rgb565_blend_normal_to_rgb888_with_mask_helium(asm_dsc_t * dsc); +extern LVGL_HIDDEN void _lv_rgb565_blend_normal_to_xrgb8888_with_mask_helium(asm_dsc_t * dsc); static inline lv_result_t lv_rgb565_blend_normal_to_rgb888_with_mask_helium(lv_draw_sw_blend_image_dsc_t * dsc, uint32_t dst_px_size) { @@ -737,16 +743,16 @@ static inline lv_result_t lv_rgb565_blend_normal_to_rgb888_with_mask_helium(lv_d .mask_stride = dsc->mask_stride }; if(dst_px_size == 3) { - lv_rgb565_blend_normal_to_rgb888_with_mask_helium(&asm_dsc); + _lv_rgb565_blend_normal_to_rgb888_with_mask_helium(&asm_dsc); } else { - lv_rgb565_blend_normal_to_xrgb8888_with_mask_helium(&asm_dsc); + _lv_rgb565_blend_normal_to_xrgb8888_with_mask_helium(&asm_dsc); } return LV_RESULT_OK; } -extern void lv_rgb565_blend_normal_to_rgb888_mix_mask_opa_helium(asm_dsc_t * dsc); -extern void lv_rgb565_blend_normal_to_xrgb8888_mix_mask_opa_helium(asm_dsc_t * dsc); +extern LVGL_HIDDEN void _lv_rgb565_blend_normal_to_rgb888_mix_mask_opa_helium(asm_dsc_t * dsc); +extern LVGL_HIDDEN void _lv_rgb565_blend_normal_to_xrgb8888_mix_mask_opa_helium(asm_dsc_t * dsc); static inline lv_result_t lv_rgb565_blend_normal_to_rgb888_mix_mask_opa_helium(lv_draw_sw_blend_image_dsc_t * dsc, uint32_t dst_px_size) { @@ -762,18 +768,18 @@ static inline lv_result_t lv_rgb565_blend_normal_to_rgb888_mix_mask_opa_helium(l .mask_stride = dsc->mask_stride }; if(dst_px_size == 3) { - lv_rgb565_blend_normal_to_rgb888_mix_mask_opa_helium(&asm_dsc); + _lv_rgb565_blend_normal_to_rgb888_mix_mask_opa_helium(&asm_dsc); } else { - lv_rgb565_blend_normal_to_xrgb8888_mix_mask_opa_helium(&asm_dsc); + _lv_rgb565_blend_normal_to_xrgb8888_mix_mask_opa_helium(&asm_dsc); } return LV_RESULT_OK; } -extern void lv_rgb888_blend_normal_to_rgb888_helium(asm_dsc_t * dsc); -extern void lv_rgb888_blend_normal_to_xrgb8888_helium(asm_dsc_t * dsc); -extern void lv_xrgb8888_blend_normal_to_rgb888_helium(asm_dsc_t * dsc); -extern void lv_xrgb8888_blend_normal_to_xrgb8888_helium(asm_dsc_t * dsc); +extern LVGL_HIDDEN void _lv_rgb888_blend_normal_to_rgb888_helium(asm_dsc_t * dsc); +extern LVGL_HIDDEN void _lv_rgb888_blend_normal_to_xrgb8888_helium(asm_dsc_t * dsc); +extern LVGL_HIDDEN void _lv_xrgb8888_blend_normal_to_rgb888_helium(asm_dsc_t * dsc); +extern LVGL_HIDDEN void _lv_xrgb8888_blend_normal_to_xrgb8888_helium(asm_dsc_t * dsc); static inline lv_result_t lv_rgb888_blend_normal_to_rgb888_helium(lv_draw_sw_blend_image_dsc_t * dsc, uint32_t dst_px_size, uint32_t src_px_size) @@ -788,27 +794,27 @@ static inline lv_result_t lv_rgb888_blend_normal_to_rgb888_helium(lv_draw_sw_ble }; if(dst_px_size == 3) { if(src_px_size == 3) { - lv_rgb888_blend_normal_to_rgb888_helium(&asm_dsc); + _lv_rgb888_blend_normal_to_rgb888_helium(&asm_dsc); } else { - lv_xrgb8888_blend_normal_to_rgb888_helium(&asm_dsc); + _lv_xrgb8888_blend_normal_to_rgb888_helium(&asm_dsc); } } else { if(src_px_size == 3) { - lv_rgb888_blend_normal_to_xrgb8888_helium(&asm_dsc); + _lv_rgb888_blend_normal_to_xrgb8888_helium(&asm_dsc); } else { - lv_xrgb8888_blend_normal_to_xrgb8888_helium(&asm_dsc); + _lv_xrgb8888_blend_normal_to_xrgb8888_helium(&asm_dsc); } } return LV_RESULT_OK; } -extern void lv_rgb888_blend_normal_to_rgb888_with_opa_helium(asm_dsc_t * dsc); -extern void lv_rgb888_blend_normal_to_xrgb8888_with_opa_helium(asm_dsc_t * dsc); -extern void lv_xrgb8888_blend_normal_to_rgb888_with_opa_helium(asm_dsc_t * dsc); -extern void lv_xrgb8888_blend_normal_to_xrgb8888_with_opa_helium(asm_dsc_t * dsc); +extern LVGL_HIDDEN void _lv_rgb888_blend_normal_to_rgb888_with_opa_helium(asm_dsc_t * dsc); +extern LVGL_HIDDEN void _lv_rgb888_blend_normal_to_xrgb8888_with_opa_helium(asm_dsc_t * dsc); +extern LVGL_HIDDEN void _lv_xrgb8888_blend_normal_to_rgb888_with_opa_helium(asm_dsc_t * dsc); +extern LVGL_HIDDEN void _lv_xrgb8888_blend_normal_to_xrgb8888_with_opa_helium(asm_dsc_t * dsc); static inline lv_result_t lv_rgb888_blend_normal_to_rgb888_with_opa_helium(lv_draw_sw_blend_image_dsc_t * dsc, uint32_t dst_px_size, uint32_t src_px_size) { @@ -823,27 +829,27 @@ static inline lv_result_t lv_rgb888_blend_normal_to_rgb888_with_opa_helium(lv_dr }; if(dst_px_size == 3) { if(src_px_size == 3) { - lv_rgb888_blend_normal_to_rgb888_with_opa_helium(&asm_dsc); + _lv_rgb888_blend_normal_to_rgb888_with_opa_helium(&asm_dsc); } else { - lv_xrgb8888_blend_normal_to_rgb888_with_opa_helium(&asm_dsc); + _lv_xrgb8888_blend_normal_to_rgb888_with_opa_helium(&asm_dsc); } } else { if(src_px_size == 3) { - lv_rgb888_blend_normal_to_xrgb8888_with_opa_helium(&asm_dsc); + _lv_rgb888_blend_normal_to_xrgb8888_with_opa_helium(&asm_dsc); } else { - lv_xrgb8888_blend_normal_to_xrgb8888_with_opa_helium(&asm_dsc); + _lv_xrgb8888_blend_normal_to_xrgb8888_with_opa_helium(&asm_dsc); } } return LV_RESULT_OK; } -extern void lv_rgb888_blend_normal_to_rgb888_with_mask_helium(asm_dsc_t * dsc); -extern void lv_rgb888_blend_normal_to_xrgb8888_with_mask_helium(asm_dsc_t * dsc); -extern void lv_xrgb8888_blend_normal_to_rgb888_with_mask_helium(asm_dsc_t * dsc); -extern void lv_xrgb8888_blend_normal_to_xrgb8888_with_mask_helium(asm_dsc_t * dsc); +extern LVGL_HIDDEN void _lv_rgb888_blend_normal_to_rgb888_with_mask_helium(asm_dsc_t * dsc); +extern LVGL_HIDDEN void _lv_rgb888_blend_normal_to_xrgb8888_with_mask_helium(asm_dsc_t * dsc); +extern LVGL_HIDDEN void _lv_xrgb8888_blend_normal_to_rgb888_with_mask_helium(asm_dsc_t * dsc); +extern LVGL_HIDDEN void _lv_xrgb8888_blend_normal_to_xrgb8888_with_mask_helium(asm_dsc_t * dsc); static inline lv_result_t lv_rgb888_blend_normal_to_rgb888_with_mask_helium(lv_draw_sw_blend_image_dsc_t * dsc, uint32_t dst_px_size, uint32_t src_px_size) { @@ -859,27 +865,27 @@ static inline lv_result_t lv_rgb888_blend_normal_to_rgb888_with_mask_helium(lv_d }; if(dst_px_size == 3) { if(src_px_size == 3) { - lv_rgb888_blend_normal_to_rgb888_with_mask_helium(&asm_dsc); + _lv_rgb888_blend_normal_to_rgb888_with_mask_helium(&asm_dsc); } else { - lv_xrgb8888_blend_normal_to_rgb888_with_mask_helium(&asm_dsc); + _lv_xrgb8888_blend_normal_to_rgb888_with_mask_helium(&asm_dsc); } } else { if(src_px_size == 3) { - lv_rgb888_blend_normal_to_xrgb8888_with_mask_helium(&asm_dsc); + _lv_rgb888_blend_normal_to_xrgb8888_with_mask_helium(&asm_dsc); } else { - lv_xrgb8888_blend_normal_to_xrgb8888_with_mask_helium(&asm_dsc); + _lv_xrgb8888_blend_normal_to_xrgb8888_with_mask_helium(&asm_dsc); } } return LV_RESULT_OK; } -extern void lv_rgb888_blend_normal_to_rgb888_mix_mask_opa_helium(asm_dsc_t * dsc); -extern void lv_rgb888_blend_normal_to_xrgb8888_mix_mask_opa_helium(asm_dsc_t * dsc); -extern void lv_xrgb8888_blend_normal_to_rgb888_mix_mask_opa_helium(asm_dsc_t * dsc); -extern void lv_xrgb8888_blend_normal_to_xrgb8888_mix_mask_opa_helium(asm_dsc_t * dsc); +extern LVGL_HIDDEN void _lv_rgb888_blend_normal_to_rgb888_mix_mask_opa_helium(asm_dsc_t * dsc); +extern LVGL_HIDDEN void _lv_rgb888_blend_normal_to_xrgb8888_mix_mask_opa_helium(asm_dsc_t * dsc); +extern LVGL_HIDDEN void _lv_xrgb8888_blend_normal_to_rgb888_mix_mask_opa_helium(asm_dsc_t * dsc); +extern LVGL_HIDDEN void _lv_xrgb8888_blend_normal_to_xrgb8888_mix_mask_opa_helium(asm_dsc_t * dsc); static inline lv_result_t lv_rgb888_blend_normal_to_rgb888_mix_mask_opa_helium(lv_draw_sw_blend_image_dsc_t * dsc, uint32_t dst_px_size, uint32_t src_px_size) { @@ -896,25 +902,25 @@ static inline lv_result_t lv_rgb888_blend_normal_to_rgb888_mix_mask_opa_helium(l }; if(dst_px_size == 3) { if(src_px_size == 3) { - lv_rgb888_blend_normal_to_rgb888_mix_mask_opa_helium(&asm_dsc); + _lv_rgb888_blend_normal_to_rgb888_mix_mask_opa_helium(&asm_dsc); } else { - lv_xrgb8888_blend_normal_to_rgb888_mix_mask_opa_helium(&asm_dsc); + _lv_xrgb8888_blend_normal_to_rgb888_mix_mask_opa_helium(&asm_dsc); } } else { if(src_px_size == 3) { - lv_rgb888_blend_normal_to_xrgb8888_mix_mask_opa_helium(&asm_dsc); + _lv_rgb888_blend_normal_to_xrgb8888_mix_mask_opa_helium(&asm_dsc); } else { - lv_xrgb8888_blend_normal_to_xrgb8888_mix_mask_opa_helium(&asm_dsc); + _lv_xrgb8888_blend_normal_to_xrgb8888_mix_mask_opa_helium(&asm_dsc); } } return LV_RESULT_OK; } -extern void lv_argb8888_blend_normal_to_rgb888_helium(asm_dsc_t * dsc); -extern void lv_argb8888_blend_normal_to_xrgb8888_helium(asm_dsc_t * dsc); +extern LVGL_HIDDEN void _lv_argb8888_blend_normal_to_rgb888_helium(asm_dsc_t * dsc); +extern LVGL_HIDDEN void _lv_argb8888_blend_normal_to_xrgb8888_helium(asm_dsc_t * dsc); static inline lv_result_t lv_argb8888_blend_normal_to_rgb888_helium(lv_draw_sw_blend_image_dsc_t * dsc, uint32_t dst_px_size) { @@ -927,16 +933,16 @@ static inline lv_result_t lv_argb8888_blend_normal_to_rgb888_helium(lv_draw_sw_b .src_stride = dsc->src_stride }; if(dst_px_size == 3) { - lv_argb8888_blend_normal_to_rgb888_helium(&asm_dsc); + _lv_argb8888_blend_normal_to_rgb888_helium(&asm_dsc); } else { - lv_argb8888_blend_normal_to_xrgb8888_helium(&asm_dsc); + _lv_argb8888_blend_normal_to_xrgb8888_helium(&asm_dsc); } return LV_RESULT_OK; } -extern void lv_argb8888_blend_normal_to_rgb888_with_opa_helium(asm_dsc_t * dsc); -extern void lv_argb8888_blend_normal_to_xrgb8888_with_opa_helium(asm_dsc_t * dsc); +extern LVGL_HIDDEN void _lv_argb8888_blend_normal_to_rgb888_with_opa_helium(asm_dsc_t * dsc); +extern LVGL_HIDDEN void _lv_argb8888_blend_normal_to_xrgb8888_with_opa_helium(asm_dsc_t * dsc); static inline lv_result_t lv_argb8888_blend_normal_to_rgb888_with_opa_helium(lv_draw_sw_blend_image_dsc_t * dsc, uint32_t dst_px_size) { @@ -950,16 +956,16 @@ static inline lv_result_t lv_argb8888_blend_normal_to_rgb888_with_opa_helium(lv_ .src_stride = dsc->src_stride }; if(dst_px_size == 3) { - lv_argb8888_blend_normal_to_rgb888_with_opa_helium(&asm_dsc); + _lv_argb8888_blend_normal_to_rgb888_with_opa_helium(&asm_dsc); } else { - lv_argb8888_blend_normal_to_xrgb8888_with_opa_helium(&asm_dsc); + _lv_argb8888_blend_normal_to_xrgb8888_with_opa_helium(&asm_dsc); } return LV_RESULT_OK; } -extern void lv_argb8888_blend_normal_to_rgb888_with_mask_helium(asm_dsc_t * dsc); -extern void lv_argb8888_blend_normal_to_xrgb8888_with_mask_helium(asm_dsc_t * dsc); +extern LVGL_HIDDEN void _lv_argb8888_blend_normal_to_rgb888_with_mask_helium(asm_dsc_t * dsc); +extern LVGL_HIDDEN void _lv_argb8888_blend_normal_to_xrgb8888_with_mask_helium(asm_dsc_t * dsc); static inline lv_result_t lv_argb8888_blend_normal_to_rgb888_with_mask_helium(lv_draw_sw_blend_image_dsc_t * dsc, uint32_t dst_px_size) { @@ -974,16 +980,16 @@ static inline lv_result_t lv_argb8888_blend_normal_to_rgb888_with_mask_helium(lv .mask_stride = dsc->mask_stride }; if(dst_px_size == 3) { - lv_argb8888_blend_normal_to_rgb888_with_mask_helium(&asm_dsc); + _lv_argb8888_blend_normal_to_rgb888_with_mask_helium(&asm_dsc); } else { - lv_argb8888_blend_normal_to_xrgb8888_with_mask_helium(&asm_dsc); + _lv_argb8888_blend_normal_to_xrgb8888_with_mask_helium(&asm_dsc); } return LV_RESULT_OK; } -extern void lv_argb8888_blend_normal_to_rgb888_mix_mask_opa_helium(asm_dsc_t * dsc); -extern void lv_argb8888_blend_normal_to_xrgb8888_mix_mask_opa_helium(asm_dsc_t * dsc); +extern LVGL_HIDDEN void _lv_argb8888_blend_normal_to_rgb888_mix_mask_opa_helium(asm_dsc_t * dsc); +extern LVGL_HIDDEN void _lv_argb8888_blend_normal_to_xrgb8888_mix_mask_opa_helium(asm_dsc_t * dsc); static inline lv_result_t lv_argb8888_blend_normal_to_rgb888_mix_mask_opa_helium(lv_draw_sw_blend_image_dsc_t * dsc, uint32_t dst_px_size) { @@ -999,15 +1005,15 @@ static inline lv_result_t lv_argb8888_blend_normal_to_rgb888_mix_mask_opa_helium .mask_stride = dsc->mask_stride }; if(dst_px_size == 3) { - lv_argb8888_blend_normal_to_rgb888_mix_mask_opa_helium(&asm_dsc); + _lv_argb8888_blend_normal_to_rgb888_mix_mask_opa_helium(&asm_dsc); } else { - lv_argb8888_blend_normal_to_xrgb8888_mix_mask_opa_helium(&asm_dsc); + _lv_argb8888_blend_normal_to_xrgb8888_mix_mask_opa_helium(&asm_dsc); } return LV_RESULT_OK; } -extern void lv_color_blend_to_argb8888_helium(asm_dsc_t * dsc); +extern LVGL_HIDDEN void _lv_color_blend_to_argb8888_helium(asm_dsc_t * dsc); static inline lv_result_t lv_color_blend_to_argb8888_helium(lv_draw_sw_blend_fill_dsc_t * dsc) { asm_dsc_t asm_dsc = { @@ -1018,11 +1024,11 @@ static inline lv_result_t lv_color_blend_to_argb8888_helium(lv_draw_sw_blend_fil .src_buf = &dsc->color }; - lv_color_blend_to_argb8888_helium(&asm_dsc); + _lv_color_blend_to_argb8888_helium(&asm_dsc); return LV_RESULT_OK; } -extern void lv_color_blend_to_argb8888_with_opa_helium(asm_dsc_t * dsc); +extern LVGL_HIDDEN void _lv_color_blend_to_argb8888_with_opa_helium(asm_dsc_t * dsc); static inline lv_result_t lv_color_blend_to_argb8888_with_opa_helium(lv_draw_sw_blend_fill_dsc_t * dsc) { asm_dsc_t asm_dsc = { @@ -1033,11 +1039,11 @@ static inline lv_result_t lv_color_blend_to_argb8888_with_opa_helium(lv_draw_sw_ .dst_stride = dsc->dest_stride, .src_buf = &dsc->color }; - lv_color_blend_to_argb8888_with_opa_helium(&asm_dsc); + _lv_color_blend_to_argb8888_with_opa_helium(&asm_dsc); return LV_RESULT_OK; } -extern void lv_color_blend_to_argb8888_with_mask_helium(asm_dsc_t * dsc); +extern LVGL_HIDDEN void _lv_color_blend_to_argb8888_with_mask_helium(asm_dsc_t * dsc); static inline lv_result_t lv_color_blend_to_argb8888_with_mask_helium(lv_draw_sw_blend_fill_dsc_t * dsc) { asm_dsc_t asm_dsc = { @@ -1049,11 +1055,11 @@ static inline lv_result_t lv_color_blend_to_argb8888_with_mask_helium(lv_draw_sw .mask_buf = dsc->mask_buf, .mask_stride = dsc->mask_stride }; - lv_color_blend_to_argb8888_with_mask_helium(&asm_dsc); + _lv_color_blend_to_argb8888_with_mask_helium(&asm_dsc); return LV_RESULT_OK; } -extern void lv_color_blend_to_argb8888_mix_mask_opa_helium(asm_dsc_t * dsc); +extern LVGL_HIDDEN void _lv_color_blend_to_argb8888_mix_mask_opa_helium(asm_dsc_t * dsc); static inline lv_result_t lv_color_blend_to_argb8888_mix_mask_opa_helium(lv_draw_sw_blend_fill_dsc_t * dsc) { asm_dsc_t asm_dsc = { @@ -1066,11 +1072,11 @@ static inline lv_result_t lv_color_blend_to_argb8888_mix_mask_opa_helium(lv_draw .mask_buf = dsc->mask_buf, .mask_stride = dsc->mask_stride }; - lv_color_blend_to_argb8888_mix_mask_opa_helium(&asm_dsc); + _lv_color_blend_to_argb8888_mix_mask_opa_helium(&asm_dsc); return LV_RESULT_OK; } -extern void lv_rgb565_blend_normal_to_argb8888_helium(asm_dsc_t * dsc); +extern LVGL_HIDDEN void _lv_rgb565_blend_normal_to_argb8888_helium(asm_dsc_t * dsc); static inline lv_result_t lv_rgb565_blend_normal_to_argb8888_helium(lv_draw_sw_blend_image_dsc_t * dsc) { asm_dsc_t asm_dsc = { @@ -1081,11 +1087,11 @@ static inline lv_result_t lv_rgb565_blend_normal_to_argb8888_helium(lv_draw_sw_b .src_buf = dsc->src_buf, .src_stride = dsc->src_stride }; - lv_rgb565_blend_normal_to_argb8888_helium(&asm_dsc); + _lv_rgb565_blend_normal_to_argb8888_helium(&asm_dsc); return LV_RESULT_OK; } -extern void lv_rgb565_blend_normal_to_argb8888_with_opa_helium(asm_dsc_t * dsc); +extern LVGL_HIDDEN void _lv_rgb565_blend_normal_to_argb8888_with_opa_helium(asm_dsc_t * dsc); static inline lv_result_t lv_rgb565_blend_normal_to_argb8888_with_opa_helium(lv_draw_sw_blend_image_dsc_t * dsc) { asm_dsc_t asm_dsc = { @@ -1097,11 +1103,11 @@ static inline lv_result_t lv_rgb565_blend_normal_to_argb8888_with_opa_helium(lv_ .src_buf = dsc->src_buf, .src_stride = dsc->src_stride }; - lv_rgb565_blend_normal_to_argb8888_with_opa_helium(&asm_dsc); + _lv_rgb565_blend_normal_to_argb8888_with_opa_helium(&asm_dsc); return LV_RESULT_OK; } -extern void lv_rgb565_blend_normal_to_argb8888_with_mask_helium(asm_dsc_t * dsc); +extern LVGL_HIDDEN void _lv_rgb565_blend_normal_to_argb8888_with_mask_helium(asm_dsc_t * dsc); static inline lv_result_t lv_rgb565_blend_normal_to_argb8888_with_mask_helium(lv_draw_sw_blend_image_dsc_t * dsc) { asm_dsc_t asm_dsc = { @@ -1114,11 +1120,11 @@ static inline lv_result_t lv_rgb565_blend_normal_to_argb8888_with_mask_helium(lv .mask_buf = dsc->mask_buf, .mask_stride = dsc->mask_stride }; - lv_rgb565_blend_normal_to_argb8888_with_mask_helium(&asm_dsc); + _lv_rgb565_blend_normal_to_argb8888_with_mask_helium(&asm_dsc); return LV_RESULT_OK; } -extern void lv_rgb565_blend_normal_to_argb8888_mix_mask_opa_helium(asm_dsc_t * dsc); +extern LVGL_HIDDEN void _lv_rgb565_blend_normal_to_argb8888_mix_mask_opa_helium(asm_dsc_t * dsc); static inline lv_result_t lv_rgb565_blend_normal_to_argb8888_mix_mask_opa_helium(lv_draw_sw_blend_image_dsc_t * dsc) { asm_dsc_t asm_dsc = { @@ -1132,12 +1138,12 @@ static inline lv_result_t lv_rgb565_blend_normal_to_argb8888_mix_mask_opa_helium .mask_buf = dsc->mask_buf, .mask_stride = dsc->mask_stride }; - lv_rgb565_blend_normal_to_argb8888_mix_mask_opa_helium(&asm_dsc); + _lv_rgb565_blend_normal_to_argb8888_mix_mask_opa_helium(&asm_dsc); return LV_RESULT_OK; } -extern void lv_rgb888_blend_normal_to_argb8888_helium(asm_dsc_t * dsc); -extern void lv_xrgb8888_blend_normal_to_argb8888_helium(asm_dsc_t * dsc); +extern LVGL_HIDDEN void _lv_rgb888_blend_normal_to_argb8888_helium(asm_dsc_t * dsc); +extern LVGL_HIDDEN void _lv_xrgb8888_blend_normal_to_argb8888_helium(asm_dsc_t * dsc); static inline lv_result_t lv_rgb888_blend_normal_to_argb8888_helium(lv_draw_sw_blend_image_dsc_t * dsc, uint32_t src_px_size) { @@ -1150,16 +1156,16 @@ static inline lv_result_t lv_rgb888_blend_normal_to_argb8888_helium(lv_draw_sw_b .src_stride = dsc->src_stride }; if(src_px_size == 3) { - lv_rgb888_blend_normal_to_argb8888_helium(&asm_dsc); + _lv_rgb888_blend_normal_to_argb8888_helium(&asm_dsc); } else { - lv_xrgb8888_blend_normal_to_argb8888_helium(&asm_dsc); + _lv_xrgb8888_blend_normal_to_argb8888_helium(&asm_dsc); } return LV_RESULT_OK; } -extern void lv_rgb888_blend_normal_to_argb8888_with_opa_helium(asm_dsc_t * dsc); -extern void lv_xrgb8888_blend_normal_to_argb8888_with_opa_helium(asm_dsc_t * dsc); +extern LVGL_HIDDEN void _lv_rgb888_blend_normal_to_argb8888_with_opa_helium(asm_dsc_t * dsc); +extern LVGL_HIDDEN void _lv_xrgb8888_blend_normal_to_argb8888_with_opa_helium(asm_dsc_t * dsc); static inline lv_result_t lv_rgb888_blend_normal_to_argb8888_with_opa_helium(lv_draw_sw_blend_image_dsc_t * dsc, uint32_t src_px_size) { @@ -1173,16 +1179,16 @@ static inline lv_result_t lv_rgb888_blend_normal_to_argb8888_with_opa_helium(lv_ .src_stride = dsc->src_stride }; if(src_px_size == 3) { - lv_rgb888_blend_normal_to_argb8888_with_opa_helium(&asm_dsc); + _lv_rgb888_blend_normal_to_argb8888_with_opa_helium(&asm_dsc); } else { - lv_xrgb8888_blend_normal_to_argb8888_with_opa_helium(&asm_dsc); + _lv_xrgb8888_blend_normal_to_argb8888_with_opa_helium(&asm_dsc); } return LV_RESULT_OK; } -extern void lv_rgb888_blend_normal_to_argb8888_with_mask_helium(asm_dsc_t * dsc); -extern void lv_xrgb8888_blend_normal_to_argb8888_with_mask_helium(asm_dsc_t * dsc); +extern LVGL_HIDDEN void _lv_rgb888_blend_normal_to_argb8888_with_mask_helium(asm_dsc_t * dsc); +extern LVGL_HIDDEN void _lv_xrgb8888_blend_normal_to_argb8888_with_mask_helium(asm_dsc_t * dsc); static inline lv_result_t lv_rgb888_blend_normal_to_argb8888_with_mask_helium(lv_draw_sw_blend_image_dsc_t * dsc, uint32_t src_px_size) { @@ -1197,16 +1203,16 @@ static inline lv_result_t lv_rgb888_blend_normal_to_argb8888_with_mask_helium(lv .mask_stride = dsc->mask_stride }; if(src_px_size == 3) { - lv_rgb888_blend_normal_to_argb8888_with_mask_helium(&asm_dsc); + _lv_rgb888_blend_normal_to_argb8888_with_mask_helium(&asm_dsc); } else { - lv_xrgb8888_blend_normal_to_argb8888_with_mask_helium(&asm_dsc); + _lv_xrgb8888_blend_normal_to_argb8888_with_mask_helium(&asm_dsc); } return LV_RESULT_OK; } -extern void lv_rgb888_blend_normal_to_argb8888_mix_mask_opa_helium(asm_dsc_t * dsc); -extern void lv_xrgb8888_blend_normal_to_argb8888_mix_mask_opa_helium(asm_dsc_t * dsc); +extern LVGL_HIDDEN void _lv_rgb888_blend_normal_to_argb8888_mix_mask_opa_helium(asm_dsc_t * dsc); +extern LVGL_HIDDEN void _lv_xrgb8888_blend_normal_to_argb8888_mix_mask_opa_helium(asm_dsc_t * dsc); static inline lv_result_t lv_rgb888_blend_normal_to_argb8888_mix_mask_opa_helium(lv_draw_sw_blend_image_dsc_t * dsc, uint32_t src_px_size) { @@ -1222,15 +1228,15 @@ static inline lv_result_t lv_rgb888_blend_normal_to_argb8888_mix_mask_opa_helium .mask_stride = dsc->mask_stride }; if(src_px_size == 3) { - lv_rgb888_blend_normal_to_argb8888_mix_mask_opa_helium(&asm_dsc); + _lv_rgb888_blend_normal_to_argb8888_mix_mask_opa_helium(&asm_dsc); } else { - lv_xrgb8888_blend_normal_to_argb8888_mix_mask_opa_helium(&asm_dsc); + _lv_xrgb8888_blend_normal_to_argb8888_mix_mask_opa_helium(&asm_dsc); } return LV_RESULT_OK; } -extern void lv_argb8888_blend_normal_to_argb8888_helium(asm_dsc_t * dsc); +extern LVGL_HIDDEN void _lv_argb8888_blend_normal_to_argb8888_helium(asm_dsc_t * dsc); static inline lv_result_t lv_argb8888_blend_normal_to_argb8888_helium(lv_draw_sw_blend_image_dsc_t * dsc) { asm_dsc_t asm_dsc = { @@ -1241,11 +1247,11 @@ static inline lv_result_t lv_argb8888_blend_normal_to_argb8888_helium(lv_draw_sw .src_buf = dsc->src_buf, .src_stride = dsc->src_stride }; - lv_argb8888_blend_normal_to_argb8888_helium(&asm_dsc); + _lv_argb8888_blend_normal_to_argb8888_helium(&asm_dsc); return LV_RESULT_OK; } -extern void lv_argb8888_blend_normal_to_argb8888_with_opa_helium(asm_dsc_t * dsc); +extern LVGL_HIDDEN void _lv_argb8888_blend_normal_to_argb8888_with_opa_helium(asm_dsc_t * dsc); static inline lv_result_t lv_argb8888_blend_normal_to_argb8888_with_opa_helium(lv_draw_sw_blend_image_dsc_t * dsc) { asm_dsc_t asm_dsc = { @@ -1257,11 +1263,11 @@ static inline lv_result_t lv_argb8888_blend_normal_to_argb8888_with_opa_helium(l .src_buf = dsc->src_buf, .src_stride = dsc->src_stride }; - lv_argb8888_blend_normal_to_argb8888_with_opa_helium(&asm_dsc); + _lv_argb8888_blend_normal_to_argb8888_with_opa_helium(&asm_dsc); return LV_RESULT_OK; } -extern void lv_argb8888_blend_normal_to_argb8888_with_mask_helium(asm_dsc_t * dsc); +extern LVGL_HIDDEN void _lv_argb8888_blend_normal_to_argb8888_with_mask_helium(asm_dsc_t * dsc); static inline lv_result_t lv_argb8888_blend_normal_to_argb8888_with_mask_helium(lv_draw_sw_blend_image_dsc_t * dsc) { asm_dsc_t asm_dsc = { @@ -1274,11 +1280,11 @@ static inline lv_result_t lv_argb8888_blend_normal_to_argb8888_with_mask_helium( .mask_buf = dsc->mask_buf, .mask_stride = dsc->mask_stride }; - lv_argb8888_blend_normal_to_argb8888_with_mask_helium(&asm_dsc); + _lv_argb8888_blend_normal_to_argb8888_with_mask_helium(&asm_dsc); return LV_RESULT_OK; } -extern void lv_argb8888_blend_normal_to_argb8888_mix_mask_opa_helium(asm_dsc_t * dsc); +extern LVGL_HIDDEN void _lv_argb8888_blend_normal_to_argb8888_mix_mask_opa_helium(asm_dsc_t * dsc); static inline lv_result_t lv_argb8888_blend_normal_to_argb8888_mix_mask_opa_helium(lv_draw_sw_blend_image_dsc_t * dsc) { asm_dsc_t asm_dsc = { @@ -1292,7 +1298,7 @@ static inline lv_result_t lv_argb8888_blend_normal_to_argb8888_mix_mask_opa_heli .mask_buf = dsc->mask_buf, .mask_stride = dsc->mask_stride }; - lv_argb8888_blend_normal_to_argb8888_mix_mask_opa_helium(&asm_dsc); + _lv_argb8888_blend_normal_to_argb8888_mix_mask_opa_helium(&asm_dsc); return LV_RESULT_OK; } diff --git a/src/draw/sw/blend/lv_draw_sw_blend_to_al88.c b/src/draw/sw/blend/lv_draw_sw_blend_to_al88.c index dc56243a62..749be4cea8 100644 --- a/src/draw/sw/blend/lv_draw_sw_blend_to_al88.c +++ b/src/draw/sw/blend/lv_draw_sw_blend_to_al88.c @@ -1,5 +1,5 @@ /** - * @file lv_draw_sw_blend_al88.c + * @file lv_draw_sw_blend_to_al88.c * */ diff --git a/src/draw/sw/blend/lv_draw_sw_blend_to_argb8888.c b/src/draw/sw/blend/lv_draw_sw_blend_to_argb8888.c index 2e1bc5b1be..eb3ae338e8 100644 --- a/src/draw/sw/blend/lv_draw_sw_blend_to_argb8888.c +++ b/src/draw/sw/blend/lv_draw_sw_blend_to_argb8888.c @@ -1,5 +1,5 @@ /** - * @file lv_draw_sw_blend.c + * @file lv_draw_sw_blend_to_argb8888.c * */ @@ -91,7 +91,9 @@ static inline void /* LV_ATTRIBUTE_FAST_MEM */ blend_non_normal_pixel(lv_color32 static inline void * /* LV_ATTRIBUTE_FAST_MEM */ drawbuf_next_row(const void * buf, uint32_t stride); -static inline lv_color16_t /* LV_ATTRIBUTE_FAST_MEM */ lv_color16_from_u16(uint16_t raw); +#if LV_DRAW_SW_SUPPORT_RGB565_SWAPPED + static inline lv_color16_t /* LV_ATTRIBUTE_FAST_MEM */ lv_color16_from_u16(uint16_t raw); +#endif /********************** * STATIC VARIABLES @@ -1350,6 +1352,7 @@ static inline void * LV_ATTRIBUTE_FAST_MEM drawbuf_next_row(const void * buf, ui return (void *)((uint8_t *)buf + stride); } +#if LV_DRAW_SW_SUPPORT_RGB565_SWAPPED static inline lv_color16_t LV_ATTRIBUTE_FAST_MEM lv_color16_from_u16(uint16_t raw) { lv_color16_t c; @@ -1358,6 +1361,7 @@ static inline lv_color16_t LV_ATTRIBUTE_FAST_MEM lv_color16_from_u16(uint16_t ra c.blue = raw & 0x1F; return c; } +#endif #endif /* LV_DRAW_SW_SUPPORT_ARGB8888 */ diff --git a/src/draw/sw/blend/lv_draw_sw_blend_to_argb8888_premultiplied.c b/src/draw/sw/blend/lv_draw_sw_blend_to_argb8888_premultiplied.c index c0b3031653..a74863a0fe 100644 --- a/src/draw/sw/blend/lv_draw_sw_blend_to_argb8888_premultiplied.c +++ b/src/draw/sw/blend/lv_draw_sw_blend_to_argb8888_premultiplied.c @@ -302,7 +302,8 @@ static void LV_ATTRIBUTE_FAST_MEM argb8888_image_blend(lv_draw_sw_blend_image_ds *darker color when blending the same color to the background.*/ if(dest_buf_c32[x].red != color_argb.red || dest_buf_c32[x].green != color_argb.green || - dest_buf_c32[x].blue != color_argb.blue) { + dest_buf_c32[x].blue != color_argb.blue || + dest_buf_c32[x].alpha != color_argb.alpha) { color_argb.red = (color_argb.red * color_argb.alpha) >> 8; color_argb.green = (color_argb.green * color_argb.alpha) >> 8; @@ -334,7 +335,8 @@ static void LV_ATTRIBUTE_FAST_MEM argb8888_image_blend(lv_draw_sw_blend_image_ds *darker color when blending the same color to the background.*/ if(dest_buf_c32[x].red != color_argb.red || dest_buf_c32[x].green != color_argb.green || - dest_buf_c32[x].blue != color_argb.blue) { + dest_buf_c32[x].blue != color_argb.blue || + dest_buf_c32[x].alpha != color_argb.alpha) { color_argb.alpha = alpha; color_argb.red = (color_argb.red * color_argb.alpha) >> 8; color_argb.green = (color_argb.green * color_argb.alpha) >> 8; @@ -366,7 +368,8 @@ static void LV_ATTRIBUTE_FAST_MEM argb8888_image_blend(lv_draw_sw_blend_image_ds *darker color when blending the same color to the background.*/ if(dest_buf_c32[x].red != color_argb.red || dest_buf_c32[x].green != color_argb.green || - dest_buf_c32[x].blue != color_argb.blue) { + dest_buf_c32[x].blue != color_argb.blue || + dest_buf_c32[x].alpha != color_argb.alpha) { color_argb.alpha = alpha; color_argb.red = (color_argb.red * color_argb.alpha) >> 8; color_argb.green = (color_argb.green * color_argb.alpha) >> 8; @@ -399,7 +402,8 @@ static void LV_ATTRIBUTE_FAST_MEM argb8888_image_blend(lv_draw_sw_blend_image_ds *darker color when blending the same color to the background.*/ if(dest_buf_c32[x].red != color_argb.red || dest_buf_c32[x].green != color_argb.green || - dest_buf_c32[x].blue != color_argb.blue) { + dest_buf_c32[x].blue != color_argb.blue || + dest_buf_c32[x].alpha != color_argb.alpha) { color_argb.alpha = alpha; color_argb.red = (color_argb.red * color_argb.alpha) >> 8; color_argb.green = (color_argb.green * color_argb.alpha) >> 8; @@ -529,9 +533,9 @@ static void LV_ATTRIBUTE_FAST_MEM rgb888_image_blend(lv_draw_sw_blend_image_dsc_ for(y = 0; y < h; y++) { for(dest_x = 0, src_x = 0; dest_x < w; dest_x++, src_x += src_px_size) { color_argb.alpha = (opa * mask_buf[dest_x]) >> 8; - color_argb.red = (src_buf[src_x + 2] * color_argb.alpha) >> 8;; - color_argb.green = (src_buf[src_x + 1] * color_argb.alpha) >> 8;; - color_argb.blue = (src_buf[src_x + 0] * color_argb.alpha) >> 8;; + color_argb.red = (src_buf[src_x + 2] * color_argb.alpha) >> 8; + color_argb.green = (src_buf[src_x + 1] * color_argb.alpha) >> 8; + color_argb.blue = (src_buf[src_x + 0] * color_argb.alpha) >> 8; dest_buf_c32[dest_x] = lv_color_32_32_mix_premul(color_argb, dest_buf_c32[dest_x], &cache); } dest_buf_c32 = drawbuf_next_row(dest_buf_c32, dest_stride); diff --git a/src/draw/sw/blend/lv_draw_sw_blend_to_i1.c b/src/draw/sw/blend/lv_draw_sw_blend_to_i1.c index eaeccfab7b..7fe446cab3 100644 --- a/src/draw/sw/blend/lv_draw_sw_blend_to_i1.c +++ b/src/draw/sw/blend/lv_draw_sw_blend_to_i1.c @@ -78,7 +78,9 @@ static inline uint8_t /* LV_ATTRIBUTE_FAST_MEM */ get_bit(const uint8_t * buf, i static inline void * /* LV_ATTRIBUTE_FAST_MEM */ drawbuf_next_row(const void * buf, uint32_t stride); -static inline lv_color16_t /* LV_ATTRIBUTE_FAST_MEM */ lv_color16_from_u16(uint16_t raw); +#if LV_DRAW_SW_SUPPORT_RGB565_SWAPPED + static inline lv_color16_t /* LV_ATTRIBUTE_FAST_MEM */ lv_color16_from_u16(uint16_t raw); +#endif /********************** * STATIC VARIABLES @@ -1271,6 +1273,7 @@ static inline uint8_t LV_ATTRIBUTE_FAST_MEM get_bit(const uint8_t * buf, int32_t return (buf[bit_idx / 8] >> (7 - (bit_idx % 8))) & 1; } +#if LV_DRAW_SW_SUPPORT_RGB565_SWAPPED static inline lv_color16_t LV_ATTRIBUTE_FAST_MEM lv_color16_from_u16(uint16_t raw) { lv_color16_t c; @@ -1279,5 +1282,6 @@ static inline lv_color16_t LV_ATTRIBUTE_FAST_MEM lv_color16_from_u16(uint16_t ra c.blue = raw & 0x1F; return c; } +#endif #endif diff --git a/src/draw/sw/blend/lv_draw_sw_blend_to_l8.c b/src/draw/sw/blend/lv_draw_sw_blend_to_l8.c index 91bb1162a0..99b438debf 100644 --- a/src/draw/sw/blend/lv_draw_sw_blend_to_l8.c +++ b/src/draw/sw/blend/lv_draw_sw_blend_to_l8.c @@ -1,5 +1,5 @@ /** - * @file lv_draw_sw_blend_l8.c + * @file lv_draw_sw_blend_to_l8.c * */ @@ -74,7 +74,9 @@ static inline void /* LV_ATTRIBUTE_FAST_MEM */ blend_non_normal_pixel(uint8_t * static inline void * /* LV_ATTRIBUTE_FAST_MEM */ drawbuf_next_row(const void * buf, uint32_t stride); -static inline lv_color16_t /* LV_ATTRIBUTE_FAST_MEM */ lv_color16_from_u16(uint16_t raw); +#if LV_DRAW_SW_SUPPORT_RGB565_SWAPPED + static inline lv_color16_t /* LV_ATTRIBUTE_FAST_MEM */ lv_color16_from_u16(uint16_t raw); +#endif /********************** * STATIC VARIABLES @@ -1005,6 +1007,7 @@ static inline void * LV_ATTRIBUTE_FAST_MEM drawbuf_next_row(const void * buf, ui return (void *)((uint8_t *)buf + stride); } +#if LV_DRAW_SW_SUPPORT_RGB565_SWAPPED static inline lv_color16_t LV_ATTRIBUTE_FAST_MEM lv_color16_from_u16(uint16_t raw) { lv_color16_t c; @@ -1013,6 +1016,7 @@ static inline lv_color16_t LV_ATTRIBUTE_FAST_MEM lv_color16_from_u16(uint16_t ra c.blue = raw & 0x1F; return c; } +#endif #endif diff --git a/src/draw/sw/blend/lv_draw_sw_blend_to_rgb565.c b/src/draw/sw/blend/lv_draw_sw_blend_to_rgb565.c index bca595caab..a2bcacd33b 100644 --- a/src/draw/sw/blend/lv_draw_sw_blend_to_rgb565.c +++ b/src/draw/sw/blend/lv_draw_sw_blend_to_rgb565.c @@ -79,7 +79,9 @@ static inline uint16_t /* LV_ATTRIBUTE_FAST_MEM */ lv_color_24_16_mix(const uint static inline void * /* LV_ATTRIBUTE_FAST_MEM */ drawbuf_next_row(const void * buf, uint32_t stride); -static inline lv_color16_t /* LV_ATTRIBUTE_FAST_MEM */ lv_color16_from_u16(uint16_t raw); +#if LV_DRAW_SW_SUPPORT_RGB565_SWAPPED + static inline lv_color16_t /* LV_ATTRIBUTE_FAST_MEM */ lv_color16_from_u16(uint16_t raw); +#endif /********************** * STATIC VARIABLES @@ -153,6 +155,22 @@ static inline lv_color16_t /* LV_ATTRIBUTE_FAST_MEM */ lv_color16_from_u16(uint1 #define LV_DRAW_SW_RGB565_BLEND_NORMAL_TO_RGB565_MIX_MASK_OPA(...) LV_RESULT_INVALID #endif +#ifndef LV_DRAW_SW_RGB565_SWAPPED_BLEND_NORMAL_TO_RGB565 + #define LV_DRAW_SW_RGB565_SWAPPED_BLEND_NORMAL_TO_RGB565(...) LV_RESULT_INVALID +#endif + +#ifndef LV_DRAW_SW_RGB565_SWAPPED_BLEND_NORMAL_TO_RGB565_WITH_OPA + #define LV_DRAW_SW_RGB565_SWAPPED_BLEND_NORMAL_TO_RGB565_WITH_OPA(...) LV_RESULT_INVALID +#endif + +#ifndef LV_DRAW_SW_RGB565_SWAPPED_BLEND_NORMAL_TO_RGB565_WITH_MASK + #define LV_DRAW_SW_RGB565_SWAPPED_BLEND_NORMAL_TO_RGB565_WITH_MASK(...) LV_RESULT_INVALID +#endif + +#ifndef LV_DRAW_SW_RGB565_SWAPPED_BLEND_NORMAL_TO_RGB565_MIX_MASK_OPA + #define LV_DRAW_SW_RGB565_SWAPPED_BLEND_NORMAL_TO_RGB565_MIX_MASK_OPA(...) LV_RESULT_INVALID +#endif + #ifndef LV_DRAW_SW_RGB888_BLEND_NORMAL_TO_RGB565 #define LV_DRAW_SW_RGB888_BLEND_NORMAL_TO_RGB565(...) LV_RESULT_INVALID #endif @@ -931,7 +949,7 @@ static void LV_ATTRIBUTE_FAST_MEM rgb565_swapped_image_blend(lv_draw_sw_blend_im if(dsc->blend_mode == LV_BLEND_MODE_NORMAL) { if(mask_buf == NULL && opa >= LV_OPA_MAX) { - if(LV_RESULT_INVALID == LV_DRAW_SW_RGB565_BLEND_NORMAL_TO_RGB565(dsc)) { + if(LV_RESULT_INVALID == LV_DRAW_SW_RGB565_SWAPPED_BLEND_NORMAL_TO_RGB565(dsc)) { uint32_t line_in_bytes = w * 2; for(y = 0; y < h; y++) { lv_memcpy(dest_buf_u16, src_buf_u16, line_in_bytes); @@ -942,7 +960,7 @@ static void LV_ATTRIBUTE_FAST_MEM rgb565_swapped_image_blend(lv_draw_sw_blend_im } } else if(mask_buf == NULL && opa < LV_OPA_MAX) { - if(LV_RESULT_INVALID == LV_DRAW_SW_RGB565_BLEND_NORMAL_TO_RGB565_WITH_OPA(dsc)) { + if(LV_RESULT_INVALID == LV_DRAW_SW_RGB565_SWAPPED_BLEND_NORMAL_TO_RGB565_WITH_OPA(dsc)) { for(y = 0; y < h; y++) { for(x = 0; x < w; x++) { dest_buf_u16[x] = lv_color_16_16_mix(lv_color_swap_16(src_buf_u16[x]), dest_buf_u16[x], opa); @@ -953,7 +971,7 @@ static void LV_ATTRIBUTE_FAST_MEM rgb565_swapped_image_blend(lv_draw_sw_blend_im } } else if(mask_buf && opa >= LV_OPA_MAX) { - if(LV_RESULT_INVALID == LV_DRAW_SW_RGB565_BLEND_NORMAL_TO_RGB565_WITH_MASK(dsc)) { + if(LV_RESULT_INVALID == LV_DRAW_SW_RGB565_SWAPPED_BLEND_NORMAL_TO_RGB565_WITH_MASK(dsc)) { for(y = 0; y < h; y++) { for(x = 0; x < w; x++) { dest_buf_u16[x] = lv_color_16_16_mix(lv_color_swap_16(src_buf_u16[x]), dest_buf_u16[x], mask_buf[x]); @@ -965,7 +983,7 @@ static void LV_ATTRIBUTE_FAST_MEM rgb565_swapped_image_blend(lv_draw_sw_blend_im } } else { - if(LV_RESULT_INVALID == LV_DRAW_SW_RGB565_BLEND_NORMAL_TO_RGB565_MIX_MASK_OPA(dsc)) { + if(LV_RESULT_INVALID == LV_DRAW_SW_RGB565_SWAPPED_BLEND_NORMAL_TO_RGB565_MIX_MASK_OPA(dsc)) { for(y = 0; y < h; y++) { for(x = 0; x < w; x++) { dest_buf_u16[x] = lv_color_16_16_mix(lv_color_swap_16(src_buf_u16[x]), dest_buf_u16[x], LV_OPA_MIX2(mask_buf[x], opa)); @@ -1316,7 +1334,7 @@ static void LV_ATTRIBUTE_FAST_MEM argb8888_premultiplied_image_blend(lv_draw_sw_ if(LV_RESULT_INVALID == LV_DRAW_SW_ARGB8888_PREMULTIPLIED_BLEND_NORMAL_TO_RGB565(dsc)) { for(y = 0; y < h; y++) { for(dest_x = 0, src_x = 0; dest_x < w; dest_x++, src_x += 4) { - /*For the trivial case use the premultipled image as it is. + /*For the trivial case use the premultiplied image as it is. *For the other cases unpremultiply as another alpha also needs to be applied.*/ dest_buf_u16[dest_x] = lv_color_24_16_mix_premult(&src_buf_u8[src_x], dest_buf_u16[dest_x], src_buf_u8[src_x + 3]); } @@ -1497,6 +1515,7 @@ static inline void * LV_ATTRIBUTE_FAST_MEM drawbuf_next_row(const void * buf, ui return (void *)((uint8_t *)buf + stride); } +#if LV_DRAW_SW_SUPPORT_RGB565_SWAPPED static inline lv_color16_t LV_ATTRIBUTE_FAST_MEM lv_color16_from_u16(uint16_t raw) { lv_color16_t c; @@ -1505,6 +1524,7 @@ static inline lv_color16_t LV_ATTRIBUTE_FAST_MEM lv_color16_from_u16(uint16_t ra c.blue = raw & 0x1F; return c; } +#endif #endif /*LV_DRAW_SW_SUPPORT_RGB565*/ diff --git a/src/draw/sw/blend/lv_draw_sw_blend_to_rgb565_swapped.h b/src/draw/sw/blend/lv_draw_sw_blend_to_rgb565_swapped.h index 475b765d23..a9da699d75 100644 --- a/src/draw/sw/blend/lv_draw_sw_blend_to_rgb565_swapped.h +++ b/src/draw/sw/blend/lv_draw_sw_blend_to_rgb565_swapped.h @@ -42,4 +42,4 @@ void /* LV_ATTRIBUTE_FAST_MEM */ lv_draw_sw_blend_image_to_rgb565_swapped(lv_dra } /*extern "C"*/ #endif -#endif /*LV_DRAW_SW_BLEND_TO_RGB565_H*/ +#endif /*LV_DRAW_SW_BLEND_TO_RGB565_SWAPPED_H*/ diff --git a/src/draw/sw/blend/lv_draw_sw_blend_to_rgb888.c b/src/draw/sw/blend/lv_draw_sw_blend_to_rgb888.c index a99d4bce46..7a9daa0839 100644 --- a/src/draw/sw/blend/lv_draw_sw_blend_to_rgb888.c +++ b/src/draw/sw/blend/lv_draw_sw_blend_to_rgb888.c @@ -119,6 +119,22 @@ static inline void * /* LV_ATTRIBUTE_FAST_MEM */ drawbuf_next_row(const void * b #define LV_DRAW_SW_L8_BLEND_NORMAL_TO_RGB888_MIX_MASK_OPA(...) LV_RESULT_INVALID #endif +#ifndef LV_DRAW_SW_AL88_BLEND_NORMAL_TO_RGB888 + #define LV_DRAW_SW_AL88_BLEND_NORMAL_TO_RGB888(...) LV_RESULT_INVALID +#endif + +#ifndef LV_DRAW_SW_AL88_BLEND_NORMAL_TO_RGB888_WITH_OPA + #define LV_DRAW_SW_AL88_BLEND_NORMAL_TO_RGB888_WITH_OPA(...) LV_RESULT_INVALID +#endif + +#ifndef LV_DRAW_SW_AL88_BLEND_NORMAL_TO_RGB888_WITH_MASK + #define LV_DRAW_SW_AL88_BLEND_NORMAL_TO_RGB888_WITH_MASK(...) LV_RESULT_INVALID +#endif + +#ifndef LV_DRAW_SW_AL88_BLEND_NORMAL_TO_RGB888_MIX_MASK_OPA + #define LV_DRAW_SW_AL88_BLEND_NORMAL_TO_RGB888_MIX_MASK_OPA(...) LV_RESULT_INVALID +#endif + #ifndef LV_DRAW_SW_RGB565_BLEND_NORMAL_TO_RGB888 #define LV_DRAW_SW_RGB565_BLEND_NORMAL_TO_RGB888(...) LV_RESULT_INVALID #endif @@ -491,7 +507,7 @@ static void LV_ATTRIBUTE_FAST_MEM al88_image_blend(lv_draw_sw_blend_image_dsc_t if(dsc->blend_mode == LV_BLEND_MODE_NORMAL) { if(mask_buf == NULL && opa >= LV_OPA_MAX) { - if(LV_RESULT_INVALID == LV_DRAW_SW_L8_BLEND_NORMAL_TO_RGB888(dsc, dest_px_size)) { + if(LV_RESULT_INVALID == LV_DRAW_SW_AL88_BLEND_NORMAL_TO_RGB888(dsc, dest_px_size)) { for(y = 0; y < h; y++) { for(dest_x = 0, src_x = 0; src_x < w; dest_x += dest_px_size, src_x++) { lv_color_8_24_mix(src_buf_al88[src_x].lumi, &dest_buf_u8[dest_x], src_buf_al88[src_x].alpha); @@ -502,7 +518,7 @@ static void LV_ATTRIBUTE_FAST_MEM al88_image_blend(lv_draw_sw_blend_image_dsc_t } } else if(mask_buf == NULL && opa < LV_OPA_MAX) { - if(LV_RESULT_INVALID == LV_DRAW_SW_L8_BLEND_NORMAL_TO_RGB888_WITH_OPA(dsc, dest_px_size)) { + if(LV_RESULT_INVALID == LV_DRAW_SW_AL88_BLEND_NORMAL_TO_RGB888_WITH_OPA(dsc, dest_px_size)) { for(y = 0; y < h; y++) { for(dest_x = 0, src_x = 0; src_x < w; dest_x += dest_px_size, src_x++) { lv_color_8_24_mix(src_buf_al88[src_x].lumi, &dest_buf_u8[dest_x], LV_OPA_MIX2(src_buf_al88[src_x].alpha, opa)); @@ -513,7 +529,7 @@ static void LV_ATTRIBUTE_FAST_MEM al88_image_blend(lv_draw_sw_blend_image_dsc_t } } else if(mask_buf && opa >= LV_OPA_MAX) { - if(LV_RESULT_INVALID == LV_DRAW_SW_L8_BLEND_NORMAL_TO_RGB888_WITH_MASK(dsc, dest_px_size)) { + if(LV_RESULT_INVALID == LV_DRAW_SW_AL88_BLEND_NORMAL_TO_RGB888_WITH_MASK(dsc, dest_px_size)) { for(y = 0; y < h; y++) { for(dest_x = 0, src_x = 0; src_x < w; dest_x += dest_px_size, src_x++) { lv_color_8_24_mix(src_buf_al88[src_x].lumi, &dest_buf_u8[dest_x], LV_OPA_MIX2(src_buf_al88[src_x].alpha, @@ -526,7 +542,7 @@ static void LV_ATTRIBUTE_FAST_MEM al88_image_blend(lv_draw_sw_blend_image_dsc_t } } else if(mask_buf && opa < LV_OPA_MAX) { - if(LV_RESULT_INVALID == LV_DRAW_SW_L8_BLEND_NORMAL_TO_RGB888_MIX_MASK_OPA(dsc, dest_px_size)) { + if(LV_RESULT_INVALID == LV_DRAW_SW_AL88_BLEND_NORMAL_TO_RGB888_MIX_MASK_OPA(dsc, dest_px_size)) { for(y = 0; y < h; y++) { for(dest_x = 0, src_x = 0; src_x < w; dest_x += dest_px_size, src_x++) { lv_color_8_24_mix(src_buf_al88[src_x].lumi, &dest_buf_u8[dest_x], LV_OPA_MIX3(src_buf_al88[src_x].alpha, @@ -971,7 +987,7 @@ static void LV_ATTRIBUTE_FAST_MEM argb8888_premultiplied_image_blend(lv_draw_sw_ if(LV_RESULT_INVALID == LV_DRAW_SW_ARGB8888_PREMULTIPLIED_BLEND_NORMAL_TO_RGB888(dsc, dest_px_size)) { for(y = 0; y < h; y++) { for(dest_x = 0, src_x = 0; src_x < w; dest_x += dest_px_size, src_x++) { - /*For the trivial case use the premultipled image as it is. + /*For the trivial case use the premultiplied image as it is. *For the other cases unpremultiply as another alpha also needs to be applied.*/ lv_color_24_24_mix_premult((const uint8_t *)&src_buf_c32[src_x], &dest_buf[dest_x], src_buf_c32[src_x].alpha); } diff --git a/src/draw/sw/blend/neon/lv_blend_neon.S b/src/draw/sw/blend/neon/lv_blend_neon.S deleted file mode 100644 index 83480c554f..0000000000 --- a/src/draw/sw/blend/neon/lv_blend_neon.S +++ /dev/null @@ -1,705 +0,0 @@ -/** - * @file lv_blend_neon.S - * - */ - -#ifndef __ASSEMBLY__ -#define __ASSEMBLY__ -#endif - -#include "lv_blend_neon.h" - - -/*Workaround: missing .note.GNU-stack section implies executable stack*/ -#ifdef __ELF__ -.section .note.GNU-stack,"",%progbits -#endif /* __ELF__ */ - -#if LV_USE_DRAW_SW_ASM == LV_DRAW_SW_ASM_NEON - -.text -.fpu neon -.arch armv7a -.syntax unified -.p2align 2 - -@ d0 ~ d3 : src B,G,R,A -@ d4 ~ d7 : dst B,G,R,A -@ q8 : src RGB565 raw -@ q9 : dst RGB565 raw -@ q10 ~ q12: pre-multiplied src -@ d26~29 : temp -@ d30 : mask -@ d31 : opa - -FG_MASK .req r0 -BG_MASK .req r1 -DST_ADDR .req r2 -DST_W .req r3 -DST_H .req r4 -DST_STRIDE .req r5 -SRC_ADDR .req r6 -SRC_STRIDE .req r7 -MASK_ADDR .req r8 -MASK_STRIDE .req r9 -W .req r10 -H .req r11 -S_8888_L .qn q0 -S_8888_H .qn q1 -D_8888_L .qn q2 -D_8888_H .qn q3 - S_B .dn d0 - S_G .dn d1 - S_R .dn d2 - S_A .dn d3 - D_B .dn d4 - D_G .dn d5 - D_R .dn d6 - D_A .dn d7 -S_565 .qn q8 -D_565 .qn q9 - S_565_L .dn d16 - S_565_H .dn d17 - D_565_L .dn d18 - D_565_H .dn d19 -PREMULT_B .qn q10 -PREMULT_G .qn q11 -PREMULT_R .qn q12 -TMP_Q0 .qn q13 - TMP_D0 .dn d26 - TMP_D1 .dn d27 -TMP_Q1 .qn q14 - TMP_D2 .dn d28 - TMP_D3 .dn d29 - M_A .dn d30 - OPA .dn d31 - -.macro convert reg, bpp, intlv -.if \bpp >= 31 - .if \intlv - vzip.8 \reg\()_B, \reg\()_R @ BRBRBRBR GGGGGGGG BRBRBRBR AAAAAAAA - vzip.8 \reg\()_G, \reg\()_A @ BRBRBRBR GAGAGAGA BRBRBRBR GAGAGAGA - vzip.8 \reg\()_R, \reg\()_A @ BRBRBRBR GAGAGAGA BGRABGRA BGRABGRA - vzip.8 \reg\()_B, \reg\()_G @ BGRABGRA BGRABGRA BGRABGRA BGRABGRA - .else - vuzp.8 \reg\()_B, \reg\()_G @ BRBRBRBR GAGAGAGA BGRABGRA BGRABGRA - vuzp.8 \reg\()_R, \reg\()_A @ BRBRBRBR GAGAGAGA BRBRBRBR GAGAGAGA - vuzp.8 \reg\()_G, \reg\()_A @ BRBRBRBR GGGGGGGG BRBRBRBR AAAAAAAA - vuzp.8 \reg\()_B, \reg\()_R @ BBBBBBBB GGGGGGGG RRRRRRRR AAAAAAAA - .endif -.elseif \bpp == 24 - .if \intlv @ for init only (same B,G,R for all channel) - vzip.8 \reg\()_B, \reg\()_G @ BGBGBGBG BGBGBGBG RRRRRRRR - vzip.16 \reg\()_B, \reg\()_R @ BGRRBGRR BGBGBGBG BGRRBGRR - vsli.64 \reg\()_8888_L, \reg\()_8888_L, #24 @ BGRBGRRB BGBBGBGB - vsli.64 \reg\()_B, \reg\()_G, #48 @ BGRBGRBG - vsri.64 \reg\()_R, \reg\()_B, #8 @ GRBGRBGR - vsri.64 \reg\()_G, \reg\()_R, #8 @ RBGRBGRB - .endif -.elseif \bpp == 16 - .if \intlv - vshll.u8 \reg\()_565, \reg\()_R, #8 @ RRRrrRRR 00000000 - vshll.u8 TMP_Q0, \reg\()_G, #8 @ GGGgggGG 00000000 - vshll.u8 TMP_Q1, \reg\()_B, #8 @ BBBbbBBB 00000000 - vsri.16 \reg\()_565, TMP_Q0, #5 @ RRRrrGGG gggGG000 - vsri.16 \reg\()_565, TMP_Q1, #11 @ RRRrrGGG gggBBBbb - .else - vshr.u8 TMP_Q0, \reg\()_565, #3 @ 000RRRrr 000gggBB - vshrn.i16 \reg\()_G, \reg\()_565, #5 @ rrGGGggg - vshrn.i16 \reg\()_R, TMP_Q0, #5 @ RRRrr000 - vshl.i8 \reg\()_G, \reg\()_G, #2 @ GGGggg00 - vshl.i16 TMP_Q1, \reg\()_565, #3 @ rrGGGggg BBBbb000 - vsri.8 \reg\()_R, \reg\()_R, #5 @ RRRrrRRR - vmovn.i16 \reg\()_B, TMP_Q1 @ BBBbb000 - vsri.8 \reg\()_G, \reg\()_G, #6 @ GGGgggGG - vsri.8 \reg\()_B, \reg\()_B, #5 @ BBBbbBBB - .endif -.endif -.endm - -.macro ldst op, bpp, len, mem, reg, cvt, wb -.if \bpp >= 31 - .if \len == 8 - .if \cvt - v\op\()4.8 {\reg\()_B, \reg\()_G, \reg\()_R, \reg\()_A}, [\mem\()_ADDR]\wb - .else - v\op\()1.32 {\reg\()_8888_L, \reg\()_8888_H}, [\mem\()_ADDR]\wb - .endif - .else - .ifc \op,st - .if \cvt - convert \reg, \bpp, 1 - .endif - .endif - .if \len == 7 - v\op\()1.32 {\reg\()_8888_L}, [\mem\()_ADDR]! - v\op\()1.32 {\reg\()_R}, [\mem\()_ADDR]! - v\op\()1.32 {\reg\()_A[0]}, [\mem\()_ADDR]! - .elseif \len == 6 - v\op\()1.32 {\reg\()_8888_L}, [\mem\()_ADDR]! - v\op\()1.32 {\reg\()_R}, [\mem\()_ADDR]! - .elseif \len == 5 - v\op\()1.32 {\reg\()_8888_L}, [\mem\()_ADDR]! - v\op\()1.32 {\reg\()_R[0]}, [\mem\()_ADDR]! - .elseif \len == 4 - v\op\()1.32 {\reg\()_8888_L}, [\mem\()_ADDR]\wb - .elseif \len == 3 - v\op\()1.32 {\reg\()_B}, [\mem\()_ADDR]! - v\op\()1.32 {\reg\()_G[0]}, [\mem\()_ADDR]! - .elseif \len == 2 - v\op\()1.32 {\reg\()_B}, [\mem\()_ADDR]\wb - .elseif \len == 1 - v\op\()1.32 {\reg\()_B[0]}, [\mem\()_ADDR]\wb - .else - .error "[32bpp]len should be 1~8" - .endif - .ifc \op,ld - .if \cvt - convert \reg, \bpp, 0 - .endif - .endif - .ifb \wb - .if (\len != 4) && (\len != 2) && (\len != 1) - sub \mem\()_ADDR, #4*\len - .endif - .endif - .endif -.elseif \bpp == 24 - .if \len == 8 - .if \cvt - v\op\()3.8 {\reg\()_B, \reg\()_G, \reg\()_R}, [\mem\()_ADDR]\wb - .else - v\op\()1.8 {\reg\()_B, \reg\()_G, \reg\()_R}, [\mem\()_ADDR]\wb - .endif - .elseif (\len < 8) && (\len > 0) - .if \cvt - v\op\()3.8 {\reg\()_B[0], \reg\()_G[0], \reg\()_R[0]}, [\mem\()_ADDR]! - .if \len > 1 - v\op\()3.8 {\reg\()_B[1], \reg\()_G[1], \reg\()_R[1]}, [\mem\()_ADDR]! - .endif - .if \len > 2 - v\op\()3.8 {\reg\()_B[2], \reg\()_G[2], \reg\()_R[2]}, [\mem\()_ADDR]! - .endif - .if \len > 3 - v\op\()3.8 {\reg\()_B[3], \reg\()_G[3], \reg\()_R[3]}, [\mem\()_ADDR]! - .endif - .if \len > 4 - v\op\()3.8 {\reg\()_B[4], \reg\()_G[4], \reg\()_R[4]}, [\mem\()_ADDR]! - .endif - .if \len > 5 - v\op\()3.8 {\reg\()_B[5], \reg\()_G[5], \reg\()_R[5]}, [\mem\()_ADDR]! - .endif - .if \len > 6 - v\op\()3.8 {\reg\()_B[6], \reg\()_G[6], \reg\()_R[6]}, [\mem\()_ADDR]! - .endif - .ifb \wb - sub \mem\()_ADDR, #3*\len - .endif - .else - .if \len == 7 - v\op\()1.32 {\reg\()_8888_L}, [\mem\()_ADDR]! - v\op\()1.32 {\reg\()_R[0]}, [\mem\()_ADDR]! - v\op\()1.8 {\reg\()_R[4]}, [\mem\()_ADDR]! - .elseif \len == 6 - v\op\()1.32 {\reg\()_8888_L}, [\mem\()_ADDR]! - v\op\()1.16 {\reg\()_R[0]}, [\mem\()_ADDR]! - .elseif \len == 5 - v\op\()1.32 {\reg\()_B}, [\mem\()_ADDR]! - v\op\()1.32 {\reg\()_G[0]}, [\mem\()_ADDR]! - v\op\()1.16 {\reg\()_G[2]}, [\mem\()_ADDR]! - v\op\()1.8 {\reg\()_G[6]}, [\mem\()_ADDR]! - .elseif \len == 4 - v\op\()1.32 {\reg\()_B}, [\mem\()_ADDR]! - v\op\()1.32 {\reg\()_G[0]}, [\mem\()_ADDR]! - .elseif \len == 3 - v\op\()1.32 {\reg\()_B}, [\mem\()_ADDR]! - v\op\()1.8 {\reg\()_G[0]}, [\mem\()_ADDR]! - .elseif \len == 2 - v\op\()1.32 {\reg\()_B[0]}, [\mem\()_ADDR]! - v\op\()1.16 {\reg\()_B[2]}, [\mem\()_ADDR]! - .elseif \len == 1 - v\op\()1.16 {\reg\()_B[0]}, [\mem\()_ADDR]! - v\op\()1.8 {\reg\()_B[2]}, [\mem\()_ADDR]! - .endif - .ifb \wb - sub \mem\()_ADDR, #3*\len - .endif - .endif - .else - .error "[24bpp]len should be 1~8" - .endif -.elseif \bpp == 16 - .ifc \op,st - .if \cvt - convert \reg, \bpp, 1 - .endif - .endif - .if \len == 8 - v\op\()1.16 {\reg\()_565}, [\mem\()_ADDR]\wb - .elseif \len == 7 - v\op\()1.16 {\reg\()_565_L}, [\mem\()_ADDR]! - v\op\()1.32 {\reg\()_565_H[0]}, [\mem\()_ADDR]! - v\op\()1.16 {\reg\()_565_H[2]}, [\mem\()_ADDR]! - .ifb \wb - sub \mem\()_ADDR, #14 - .endif - .elseif \len == 6 - v\op\()1.16 {\reg\()_565_L}, [\mem\()_ADDR]! - v\op\()1.32 {\reg\()_565_H[0]}, [\mem\()_ADDR]! - .ifb \wb - sub \mem\()_ADDR, #12 - .endif - .elseif \len == 5 - v\op\()1.16 {\reg\()_565_L}, [\mem\()_ADDR]! - v\op\()1.16 {\reg\()_565_H[0]}, [\mem\()_ADDR]! - .ifb \wb - sub \mem\()_ADDR, #10 - .endif - .elseif \len == 4 - v\op\()1.16 {\reg\()_565_L}, [\mem\()_ADDR]\wb - .elseif \len == 3 - v\op\()1.32 {\reg\()_565_L[0]}, [\mem\()_ADDR]! - v\op\()1.16 {\reg\()_565_L[2]}, [\mem\()_ADDR]! - .ifb \wb - sub \mem\()_ADDR, #6 - .endif - .elseif \len == 2 - v\op\()1.32 {\reg\()_565_L[0]}, [\mem\()_ADDR]\wb - .elseif \len == 1 - v\op\()1.16 {\reg\()_565_L[0]}, [\mem\()_ADDR]\wb - .else - .error "[16bpp]len should be 1~8" - .endif - .ifc \op,ld - .if \cvt - convert \reg, \bpp, 0 - .endif - .endif -.elseif \bpp == 8 - .if \len == 8 - v\op\()1.8 {\reg\()_A}, [\mem\()_ADDR]\wb - .elseif \len == 7 - v\op\()1.32 {\reg\()_A[0]}, [\mem\()_ADDR]! - v\op\()1.16 {\reg\()_A[2]}, [\mem\()_ADDR]! - v\op\()1.8 {\reg\()_A[6]}, [\mem\()_ADDR]! - .ifb \wb - sub \mem\()_ADDR, #7 - .endif - .elseif \len == 6 - v\op\()1.32 {\reg\()_A[0]}, [\mem\()_ADDR]! - v\op\()1.16 {\reg\()_A[2]}, [\mem\()_ADDR]! - .ifb \wb - sub \mem\()_ADDR, #6 - .endif - .elseif \len == 5 - v\op\()1.32 {\reg\()_A[0]}, [\mem\()_ADDR]! - v\op\()1.8 {\reg\()_A[4]}, [\mem\()_ADDR]! - .ifb \wb - sub \mem\()_ADDR, #5 - .endif - .elseif \len == 4 - v\op\()1.32 {\reg\()_A[0]}, [\mem\()_ADDR]\wb - .elseif \len == 3 - v\op\()1.16 {\reg\()_A[0]}, [\mem\()_ADDR]! - v\op\()1.8 {\reg\()_A[2]}, [\mem\()_ADDR]! - .ifb \wb - sub \mem\()_ADDR, #3 - .endif - .elseif \len == 2 - v\op\()1.16 {\reg\()_A[0]}, [\mem\()_ADDR]\wb - .elseif \len == 1 - v\op\()1.8 {\reg\()_A[0]}, [\mem\()_ADDR]\wb - .else - .error "[8bpp]len should be 1~8" - .endif -.elseif \bpp == 0 - .ifb \wb - .if \len == 8 - v\op\()3.8 {\reg\()_B[], \reg\()_G[], \reg\()_R[]}, [\mem\()_ADDR] - .else - .error "[color]len should be 8" - .endif - .endif -.endif -.ifc \op,ld - .if \cvt && (\bpp > 8) && (\bpp < 32) - vmov.u8 \reg\()_A, #0xFF - .endif -.endif -.endm - -.macro premult alpha - vmull.u8 PREMULT_B, S_B, \alpha - vmull.u8 PREMULT_G, S_G, \alpha - vmull.u8 PREMULT_R, S_R, \alpha -.endm - -.macro init src_bpp, dst_bpp, mask, opa - ldr DST_ADDR, [r0, #4] - ldr DST_W, [r0, #8] - ldr DST_H, [r0, #12] - ldr DST_STRIDE, [r0, #16] - ldr SRC_ADDR, [r0, #20] -.if \src_bpp > 0 - ldr SRC_STRIDE, [r0, #24] -.endif -.if \mask - ldr MASK_ADDR, [r0, #28] - ldr MASK_STRIDE, [r0, #32] - sub MASK_STRIDE, MASK_STRIDE, DST_W -.endif -.if \opa - vld1.8 {OPA[]}, [r0] -.else - vmov.u8 OPA, #0xFF -.endif - - vmvn D_A, OPA -.if \dst_bpp == 16 - sub DST_STRIDE, DST_STRIDE, DST_W, lsl #1 -.elseif \dst_bpp == 24 - sub DST_STRIDE, DST_STRIDE, DST_W - sub DST_STRIDE, DST_STRIDE, DST_W, lsl #1 -.elseif \dst_bpp >= 31 - sub DST_STRIDE, DST_STRIDE, DST_W, lsl #2 -.endif -.if \src_bpp == 0 - .if \mask || \opa - ldst ld, \src_bpp, 8, SRC, S, 1 - vmov.u8 S_A, #0xFF - premult OPA - .else - ldst ld, \src_bpp, 8, SRC, D, 1 - vmov.u8 D_A, #0xFF - convert D, \dst_bpp, 1 - .endif -.else -.if \src_bpp == 16 - sub SRC_STRIDE, SRC_STRIDE, DST_W, lsl #1 -.elseif \src_bpp == 24 - sub SRC_STRIDE, SRC_STRIDE, DST_W - sub SRC_STRIDE, SRC_STRIDE, DST_W, lsl #1 -.elseif \src_bpp >= 31 - sub SRC_STRIDE, SRC_STRIDE, DST_W, lsl #2 -.endif -.endif - mvn FG_MASK, #0 - mvn BG_MASK, #0 -.endm - -@ input: M_A = 255 - fg.alpha -.macro calc_alpha len - vmov.u8 TMP_D0, #0xFD - vmvn D_A, D_A - vcge.u8 TMP_D1, S_A, TMP_D0 @ if (fg.alpha >= LV_OPA_MAX - vcge.u8 TMP_D2, D_A, TMP_D0 @ || bg.alpha <= LV_OPA_MIN) - vorr TMP_D2, TMP_D1 - vcge.u8 TMP_D3, M_A, TMP_D0 @ elseif (fg.alpha <= LV_OPA_MIN) - vmvn TMP_Q1, TMP_Q1 - vshrn.i16 TMP_D0, TMP_Q1, #4 - vmov FG_MASK, BG_MASK, TMP_D0 - cbz FG_MASK, 99f @ return fg; - vmull.u8 TMP_Q0, M_A, D_A @ D_A = 255 - LV_OPA_MIX2(255 - fg.alpha, 255 - bg.alpha) - vqrshrn.u16 M_A, TMP_Q0, #8 - vbif M_A, D_A, TMP_D3 @ insert original D_A when fg.alpha <= LV_OPA_MIN - vmvn D_A, M_A - cbz BG_MASK, 99f @ return bg; - vmov.u8 TMP_D2, #0xFF - vmovl.u8 TMP_Q0, D_A - .if \len > 4 - vmovl.u16 S_565, TMP_D1 - .endif - vmovl.u16 TMP_Q0, TMP_D0 - vmull.u8 TMP_Q1, S_A, TMP_D2 - vcvt.f32.u32 TMP_Q0, TMP_Q0 - .if \len > 4 - vmovl.u16 D_565, TMP_D3 - vcvt.f32.u32 S_565, S_565 - .endif - vmovl.u16 TMP_Q1, TMP_D2 - vrecpe.f32 TMP_Q0, TMP_Q0 - vcvt.f32.u32 TMP_Q1, TMP_Q1 - .if \len > 4 - vcvt.f32.u32 D_565, D_565 - vrecpe.f32 S_565, S_565 - .endif - vmul.f32 TMP_Q0, TMP_Q0, TMP_Q1 - .if \len > 4 - vmul.f32 S_565, S_565, D_565 - .endif - vcvt.u32.f32 TMP_Q0, TMP_Q0 - .if \len > 4 - vcvt.u32.f32 S_565, S_565 - .endif - vmovn.u32 TMP_D0, TMP_Q0 - .if \len > 4 - vmovn.u32 TMP_D1, S_565 - .endif - vmovn.u16 TMP_D0, TMP_Q0 - premult TMP_D0 - vmvn M_A, TMP_D0 -99: -.endm - -.macro blend mode, dst_bpp -.if \dst_bpp == 32 - vmov TMP_D0, FG_MASK, BG_MASK - vmovl.s8 TMP_Q0, TMP_D0 - vsli.8 TMP_Q0, TMP_Q0, #4 - cbz FG_MASK, 98f -.endif -.ifc \mode,normal -.if \dst_bpp == 32 - cbz BG_MASK, 97f - mvns BG_MASK, BG_MASK - beq 96f - vmov S_565_L, D_B - vmov S_565_H, D_G - vmov D_565_L, D_R -.endif -96: - vmlal.u8 PREMULT_B, D_B, M_A - vmlal.u8 PREMULT_G, D_G, M_A - vmlal.u8 PREMULT_R, D_R, M_A - vqrshrn.u16 D_B, PREMULT_B, #8 - vqrshrn.u16 D_G, PREMULT_G, #8 - vqrshrn.u16 D_R, PREMULT_R, #8 -.if \dst_bpp == 32 - beq 97f - vbif D_B, S_565_L, TMP_D1 - vbif D_G, S_565_H, TMP_D1 - vbif D_R, D_565_L, TMP_D1 -97: - mvns FG_MASK, FG_MASK - beq 99f -.endif -.else - .error "blend mode is unsupported" -.endif -.if \dst_bpp == 32 -98: - vbif D_B, S_B, TMP_D0 - vbif D_G, S_G, TMP_D0 - vbif D_R, S_R, TMP_D0 - vbif D_A, S_A, TMP_D0 -99: -.endif -.endm - -.macro process len, src_bpp, dst_bpp, mask, opa, mode -.if (\src_bpp < 32) && (\mask == 0) && (\opa == 0) -@ no blend - .if \src_bpp == 0 || \src_bpp == \dst_bpp - ldst ld, \src_bpp, \len, SRC, D, 0, ! - ldst st, \dst_bpp, \len, DST, D, 0, ! - .else - ldst ld, \src_bpp, \len, SRC, D, 1, ! - ldst st, \dst_bpp, \len, DST, D, 1, ! - .endif -.elseif \src_bpp < 32 -@ no src_a - .if \src_bpp > 0 - ldst ld, \src_bpp, \len, SRC, S, 1, ! - .endif - ldst ld, \dst_bpp, \len, DST, D, 1 - .if \mask - ldst ld, 8, \len, MASK, S, 1, ! - .if \opa - vmull.u8 TMP_Q0, S_A, OPA - vqrshrn.u16 S_A, TMP_Q0, #8 - .endif - vmvn M_A, S_A - .if \dst_bpp < 32 - premult S_A - .else - calc_alpha \len - .endif - .else - vmvn M_A, OPA - .if \dst_bpp < 32 - premult OPA - .else - vmov S_A, OPA - calc_alpha \len - .endif - .endif - blend \mode, \dst_bpp - ldst st, \dst_bpp, \len, DST, D, 1, ! -.else -@ src_a (+\mask) (+\opa) - ldst ld, \src_bpp, \len, SRC, S, 1, ! - ldst ld, \dst_bpp, \len, DST, D, 1 - .if \mask == 0 - .if \opa - vmull.u8 TMP_Q0, S_A, OPA - vqrshrn.u16 S_A, TMP_Q0, #8 - .endif - .else - ldst ld, 8, \len, MASK, M, 1, ! - vmull.u8 TMP_Q0, S_A, M_A - vqrshrn.u16 S_A, TMP_Q0, #8 - .if \opa - vmull.u8 TMP_Q0, S_A, OPA - vqrshrn.u16 S_A, TMP_Q0, #8 - .endif - .endif - vmvn M_A, S_A - .if \dst_bpp < 32 - premult S_A - .else - calc_alpha \len - .endif - blend \mode, \dst_bpp - ldst st, \dst_bpp, \len, DST, D, 1, ! -.endif -.endm - -.macro tail src_bpp, dst_bpp, mask, opa, mode - tst DST_W, #4 - beq 3f - tst DST_W, #2 - beq 5f - tst DST_W, #1 - beq 6f - process 7, \src_bpp, \dst_bpp, \mask, \opa, \mode - b 0f -6: - process 6, \src_bpp, \dst_bpp, \mask, \opa, \mode - b 0f -5: - tst DST_W, #1 - beq 4f - process 5, \src_bpp, \dst_bpp, \mask, \opa, \mode - b 0f -4: - process 4, \src_bpp, \dst_bpp, \mask, \opa, \mode - b 0f -3: - tst DST_W, #2 - beq 1f - tst DST_W, #1 - beq 2f - process 3, \src_bpp, \dst_bpp, \mask, \opa, \mode - b 0f -2: - process 2, \src_bpp, \dst_bpp, \mask, \opa, \mode - b 0f -1: - process 1, \src_bpp, \dst_bpp, \mask, \opa, \mode -0: -.endm - -.macro next src_bpp, mask - add DST_ADDR, DST_ADDR, DST_STRIDE -.if \src_bpp - add SRC_ADDR, SRC_ADDR, SRC_STRIDE -.endif -.if \mask - add MASK_ADDR, MASK_ADDR, MASK_STRIDE -.endif -.endm - -.macro enter - push {r4-r11, lr} -.endm - -.macro exit - pop {r4-r11, pc} -.endm - -.macro preload mem, bpp -.if \bpp >= 31 - pld [\mem\()_ADDR, DST_W, lsl #2] -.elseif \bpp == 24 - add W, DST_W, DST_W, lsl #1 - pld [\mem\()_ADDR, W] -.elseif \bpp == 16 - pld [\mem\()_ADDR, DST_W, lsl #1] -.elseif \bpp == 8 - pld [\mem\()_ADDR, DST_W] -.endif -.endm - -.macro blender src_bpp, dst_bpp, mask, opa, mode - enter - init \src_bpp, \dst_bpp, \mask, \opa - movs H, DST_H - beq 0f - preload SRC, \src_bpp -.if \mask || \opa || (\src_bpp == 32) - preload DST, \dst_bpp -.endif - subs W, DST_W, #8 - blt 7f -9: - process 8, \src_bpp, \dst_bpp, \mask, \opa, \mode - subs W, W, #8 - bge 9b - tst DST_W, #7 - beq 8f - tail \src_bpp, \dst_bpp, \mask, \opa, \mode -8: - next \src_bpp, \mask - preload SRC, \src_bpp -.if \mask || \opa || (\src_bpp == 32) - preload DST, \dst_bpp -.endif - sub W, DST_W, #8 - subs H, H, #1 - bgt 9b - exit -7: - tail \src_bpp, \dst_bpp, \mask, \opa, \mode - next \src_bpp, \mask - subs H, H, #1 - bgt 7b - exit -.endm - -.macro export name, src_bpp, dst_bpp, mask, opa, mode -.thumb_func -.func \name -.global \name -.hidden \name -\name\(): - blender \src_bpp, \dst_bpp, \mask, \opa, \mode -.endfunc -.endm - -.macro export_set src, dst, src_bpp, dst_bpp, mode -.ifc \src,color - export _lv_\src\()_blend_to_\dst\()_neon, \src_bpp, \dst_bpp, 0, 0, \mode - export _lv_\src\()_blend_to_\dst\()_with_opa_neon, \src_bpp, \dst_bpp, 0, 1, \mode - export _lv_\src\()_blend_to_\dst\()_with_mask_neon, \src_bpp, \dst_bpp, 1, 0, \mode - export _lv_\src\()_blend_to_\dst\()_mix_mask_opa_neon, \src_bpp, \dst_bpp, 1, 1, \mode -.else - export _lv_\src\()_blend_\mode\()_to_\dst\()_neon, \src_bpp, \dst_bpp, 0, 0, \mode - export _lv_\src\()_blend_\mode\()_to_\dst\()_with_opa_neon, \src_bpp, \dst_bpp, 0, 1, \mode - export _lv_\src\()_blend_\mode\()_to_\dst\()_with_mask_neon, \src_bpp, \dst_bpp, 1, 0, \mode - export _lv_\src\()_blend_\mode\()_to_\dst\()_mix_mask_opa_neon, \src_bpp, \dst_bpp, 1, 1, \mode -.endif -.endm - -export_set color, rgb565, 0, 16, normal -export_set rgb565, rgb565, 16, 16, normal -export_set rgb888, rgb565, 24, 16, normal -export_set xrgb8888, rgb565, 31, 16, normal -export_set argb8888, rgb565, 32, 16, normal -export_set color, rgb888, 0, 24, normal -export_set rgb565, rgb888, 16, 24, normal -export_set rgb888, rgb888, 24, 24, normal -export_set xrgb8888, rgb888, 31, 24, normal -export_set argb8888, rgb888, 32, 24, normal -export_set color, xrgb8888, 0, 31, normal -export_set rgb565, xrgb8888, 16, 31, normal -export_set rgb888, xrgb8888, 24, 31, normal -export_set xrgb8888, xrgb8888, 31, 31, normal -export_set argb8888, xrgb8888, 32, 31, normal -export_set color, argb8888, 0, 32, normal -export_set rgb565, argb8888, 16, 32, normal -export_set rgb888, argb8888, 24, 32, normal -export_set xrgb8888, argb8888, 31, 32, normal -export_set argb8888, argb8888, 32, 32, normal - -#endif /*LV_USE_DRAW_SW_ASM == LV_DRAW_SW_ASM_NEON*/ - diff --git a/src/draw/sw/blend/neon/lv_blend_neon.h b/src/draw/sw/blend/neon/lv_blend_neon.h index fd52647bff..66e1e217ac 100644 --- a/src/draw/sw/blend/neon/lv_blend_neon.h +++ b/src/draw/sw/blend/neon/lv_blend_neon.h @@ -16,1284 +16,33 @@ extern "C" { #include "../../../../lv_conf_internal.h" +#if LV_USE_DRAW_SW_ASM == LV_DRAW_SW_ASM_NEON + #ifdef LV_DRAW_SW_NEON_CUSTOM_INCLUDE #include LV_DRAW_SW_NEON_CUSTOM_INCLUDE #endif +#include "lv_draw_sw_blend_neon_to_rgb565.h" +#include "lv_draw_sw_blend_neon_to_rgb888.h" + /********************* * DEFINES *********************/ -#if !defined(__ASSEMBLY__) - -#if __GNUC__ >= 4 -#define LVGL_HIDDEN __attribute__((visibility("hidden"))) -#else -#define LVGL_HIDDEN -#endif - -#ifndef LV_DRAW_SW_COLOR_BLEND_TO_RGB565 -#define LV_DRAW_SW_COLOR_BLEND_TO_RGB565(dsc) \ - lv_color_blend_to_rgb565_neon(dsc) -#endif - -#ifndef LV_DRAW_SW_COLOR_BLEND_TO_RGB565_WITH_OPA -#define LV_DRAW_SW_COLOR_BLEND_TO_RGB565_WITH_OPA(dsc) \ - lv_color_blend_to_rgb565_with_opa_neon(dsc) -#endif - -#ifndef LV_DRAW_SW_COLOR_BLEND_TO_RGB565_WITH_MASK -#define LV_DRAW_SW_COLOR_BLEND_TO_RGB565_WITH_MASK(dsc) \ - lv_color_blend_to_rgb565_with_mask_neon(dsc) -#endif - -#ifndef LV_DRAW_SW_COLOR_BLEND_TO_RGB565_MIX_MASK_OPA -#define LV_DRAW_SW_COLOR_BLEND_TO_RGB565_MIX_MASK_OPA(dsc) \ - lv_color_blend_to_rgb565_mix_mask_opa_neon(dsc) -#endif - -#ifndef LV_DRAW_SW_RGB565_BLEND_NORMAL_TO_RGB565 -#define LV_DRAW_SW_RGB565_BLEND_NORMAL_TO_RGB565(dsc) \ - lv_rgb565_blend_normal_to_rgb565_neon(dsc) -#endif - -#ifndef LV_DRAW_SW_RGB565_BLEND_NORMAL_TO_RGB565_WITH_OPA -#define LV_DRAW_SW_RGB565_BLEND_NORMAL_TO_RGB565_WITH_OPA(dsc) \ - lv_rgb565_blend_normal_to_rgb565_with_opa_neon(dsc) -#endif - -#ifndef LV_DRAW_SW_RGB565_BLEND_NORMAL_TO_RGB565_WITH_MASK -#define LV_DRAW_SW_RGB565_BLEND_NORMAL_TO_RGB565_WITH_MASK(dsc) \ - lv_rgb565_blend_normal_to_rgb565_with_mask_neon(dsc) -#endif - -#ifndef LV_DRAW_SW_RGB565_BLEND_NORMAL_TO_RGB565_MIX_MASK_OPA -#define LV_DRAW_SW_RGB565_BLEND_NORMAL_TO_RGB565_MIX_MASK_OPA(dsc) \ - lv_rgb565_blend_normal_to_rgb565_mix_mask_opa_neon(dsc) -#endif - -#ifndef LV_DRAW_SW_RGB888_BLEND_NORMAL_TO_RGB565 -#define LV_DRAW_SW_RGB888_BLEND_NORMAL_TO_RGB565(dsc, src_px_size) \ - lv_rgb888_blend_normal_to_rgb565_neon(dsc, src_px_size) -#endif - -#ifndef LV_DRAW_SW_RGB888_BLEND_NORMAL_TO_RGB565_WITH_OPA -#define LV_DRAW_SW_RGB888_BLEND_NORMAL_TO_RGB565_WITH_OPA(dsc, src_px_size) \ - lv_rgb888_blend_normal_to_rgb565_with_opa_neon(dsc, src_px_size) -#endif - -#ifndef LV_DRAW_SW_RGB888_BLEND_NORMAL_TO_RGB565_WITH_MASK -#define LV_DRAW_SW_RGB888_BLEND_NORMAL_TO_RGB565_WITH_MASK(dsc, src_px_size) \ - lv_rgb888_blend_normal_to_rgb565_with_mask_neon(dsc, src_px_size) -#endif - -#ifndef LV_DRAW_SW_RGB888_BLEND_NORMAL_TO_RGB565_MIX_MASK_OPA -#define LV_DRAW_SW_RGB888_BLEND_NORMAL_TO_RGB565_MIX_MASK_OPA(dsc, src_px_size) \ - lv_rgb888_blend_normal_to_rgb565_mix_mask_opa_neon(dsc, src_px_size) -#endif - -#ifndef LV_DRAW_SW_ARGB8888_BLEND_NORMAL_TO_RGB565 -#define LV_DRAW_SW_ARGB8888_BLEND_NORMAL_TO_RGB565(dsc) \ - lv_argb8888_blend_normal_to_rgb565_neon(dsc) -#endif - -#ifndef LV_DRAW_SW_ARGB8888_BLEND_NORMAL_TO_RGB565_WITH_OPA -#define LV_DRAW_SW_ARGB8888_BLEND_NORMAL_TO_RGB565_WITH_OPA(dsc) \ - lv_argb8888_blend_normal_to_rgb565_with_opa_neon(dsc) -#endif - -#ifndef LV_DRAW_SW_ARGB8888_BLEND_NORMAL_TO_RGB565_WITH_MASK -#define LV_DRAW_SW_ARGB8888_BLEND_NORMAL_TO_RGB565_WITH_MASK(dsc) \ - lv_argb8888_blend_normal_to_rgb565_with_mask_neon(dsc) -#endif - -#ifndef LV_DRAW_SW_ARGB8888_BLEND_NORMAL_TO_RGB565_MIX_MASK_OPA -#define LV_DRAW_SW_ARGB8888_BLEND_NORMAL_TO_RGB565_MIX_MASK_OPA(dsc) \ - lv_argb8888_blend_normal_to_rgb565_mix_mask_opa_neon(dsc) -#endif - -#ifndef LV_DRAW_SW_COLOR_BLEND_TO_RGB888 -#define LV_DRAW_SW_COLOR_BLEND_TO_RGB888(dsc, dst_px_size) \ - lv_color_blend_to_rgb888_neon(dsc, dst_px_size) -#endif - -#ifndef LV_DRAW_SW_COLOR_BLEND_TO_RGB888_WITH_OPA -#define LV_DRAW_SW_COLOR_BLEND_TO_RGB888_WITH_OPA(dsc, dst_px_size) \ - lv_color_blend_to_rgb888_with_opa_neon(dsc, dst_px_size) -#endif - -#ifndef LV_DRAW_SW_COLOR_BLEND_TO_RGB888_WITH_MASK -#define LV_DRAW_SW_COLOR_BLEND_TO_RGB888_WITH_MASK(dsc, dst_px_size) \ - lv_color_blend_to_rgb888_with_mask_neon(dsc, dst_px_size) -#endif - -#ifndef LV_DRAW_SW_COLOR_BLEND_TO_RGB888_MIX_MASK_OPA -#define LV_DRAW_SW_COLOR_BLEND_TO_RGB888_MIX_MASK_OPA(dsc, dst_px_size) \ - lv_color_blend_to_rgb888_mix_mask_opa_neon(dsc, dst_px_size) -#endif - -#ifndef LV_DRAW_SW_RGB565_BLEND_NORMAL_TO_RGB888 -#define LV_DRAW_SW_RGB565_BLEND_NORMAL_TO_RGB888(dsc, dst_px_size) \ - lv_rgb565_blend_normal_to_rgb888_neon(dsc, dst_px_size) -#endif - -#ifndef LV_DRAW_SW_RGB565_BLEND_NORMAL_TO_RGB888_WITH_OPA -#define LV_DRAW_SW_RGB565_BLEND_NORMAL_TO_RGB888_WITH_OPA(dsc, dst_px_size) \ - lv_rgb565_blend_normal_to_rgb888_with_opa_neon(dsc, dst_px_size) -#endif - -#ifndef LV_DRAW_SW_RGB565_BLEND_NORMAL_TO_RGB888_WITH_MASK -#define LV_DRAW_SW_RGB565_BLEND_NORMAL_TO_RGB888_WITH_MASK(dsc, dst_px_size) \ - lv_rgb565_blend_normal_to_rgb888_with_mask_neon(dsc, dst_px_size) -#endif - -#ifndef LV_DRAW_SW_RGB565_BLEND_NORMAL_TO_RGB888_MIX_MASK_OPA -#define LV_DRAW_SW_RGB565_BLEND_NORMAL_TO_RGB888_MIX_MASK_OPA(dsc, dst_px_size) \ - lv_rgb565_blend_normal_to_rgb888_mix_mask_opa_neon(dsc, dst_px_size) -#endif - -#ifndef LV_DRAW_SW_RGB888_BLEND_NORMAL_TO_RGB888 -#define LV_DRAW_SW_RGB888_BLEND_NORMAL_TO_RGB888(dsc, dst_px_size, src_px_size) \ - lv_rgb888_blend_normal_to_rgb888_neon(dsc, dst_px_size, src_px_size) -#endif - -#ifndef LV_DRAW_SW_RGB888_BLEND_NORMAL_TO_RGB888_WITH_OPA -#define LV_DRAW_SW_RGB888_BLEND_NORMAL_TO_RGB888_WITH_OPA(dsc, dst_px_size, src_px_size) \ - lv_rgb888_blend_normal_to_rgb888_with_opa_neon(dsc, dst_px_size, src_px_size) -#endif - -#ifndef LV_DRAW_SW_RGB888_BLEND_NORMAL_TO_RGB888_WITH_MASK -#define LV_DRAW_SW_RGB888_BLEND_NORMAL_TO_RGB888_WITH_MASK(dsc, dst_px_size, src_px_size) \ - lv_rgb888_blend_normal_to_rgb888_with_mask_neon(dsc, dst_px_size, src_px_size) -#endif - -#ifndef LV_DRAW_SW_RGB888_BLEND_NORMAL_TO_RGB888_MIX_MASK_OPA -#define LV_DRAW_SW_RGB888_BLEND_NORMAL_TO_RGB888_MIX_MASK_OPA(dsc, dst_px_size, src_px_size) \ - lv_rgb888_blend_normal_to_rgb888_mix_mask_opa_neon(dsc, dst_px_size, src_px_size) -#endif - -#ifndef LV_DRAW_SW_ARGB8888_BLEND_NORMAL_TO_RGB888 -#define LV_DRAW_SW_ARGB8888_BLEND_NORMAL_TO_RGB888(dsc, dst_px_size) \ - lv_argb8888_blend_normal_to_rgb888_neon(dsc, dst_px_size) -#endif - -#ifndef LV_DRAW_SW_ARGB8888_BLEND_NORMAL_TO_RGB888_WITH_OPA -#define LV_DRAW_SW_ARGB8888_BLEND_NORMAL_TO_RGB888_WITH_OPA(dsc, dst_px_size) \ - lv_argb8888_blend_normal_to_rgb888_with_opa_neon(dsc, dst_px_size) -#endif - -#ifndef LV_DRAW_SW_ARGB8888_BLEND_NORMAL_TO_RGB888_WITH_MASK -#define LV_DRAW_SW_ARGB8888_BLEND_NORMAL_TO_RGB888_WITH_MASK(dsc, dst_px_size) \ - lv_argb8888_blend_normal_to_rgb888_with_mask_neon(dsc, dst_px_size) -#endif - -#ifndef LV_DRAW_SW_ARGB8888_BLEND_NORMAL_TO_RGB888_MIX_MASK_OPA -#define LV_DRAW_SW_ARGB8888_BLEND_NORMAL_TO_RGB888_MIX_MASK_OPA(dsc, dst_px_size) \ - lv_argb8888_blend_normal_to_rgb888_mix_mask_opa_neon(dsc, dst_px_size) -#endif - -#ifndef LV_DRAW_SW_COLOR_BLEND_TO_ARGB8888 -#define LV_DRAW_SW_COLOR_BLEND_TO_ARGB8888(dsc) \ - lv_color_blend_to_argb8888_neon(dsc) -#endif - -#ifndef LV_DRAW_SW_COLOR_BLEND_TO_ARGB8888_WITH_OPA -#define LV_DRAW_SW_COLOR_BLEND_TO_ARGB8888_WITH_OPA(dsc) \ - lv_color_blend_to_argb8888_with_opa_neon(dsc) -#endif - -#ifndef LV_DRAW_SW_COLOR_BLEND_TO_ARGB8888_WITH_MASK -#define LV_DRAW_SW_COLOR_BLEND_TO_ARGB8888_WITH_MASK(dsc) \ - lv_color_blend_to_argb8888_with_mask_neon(dsc) -#endif - -#ifndef LV_DRAW_SW_COLOR_BLEND_TO_ARGB8888_MIX_MASK_OPA -#define LV_DRAW_SW_COLOR_BLEND_TO_ARGB8888_MIX_MASK_OPA(dsc) \ - lv_color_blend_to_argb8888_mix_mask_opa_neon(dsc) -#endif - -#ifndef LV_DRAW_SW_RGB565_BLEND_NORMAL_TO_ARGB8888 -#define LV_DRAW_SW_RGB565_BLEND_NORMAL_TO_ARGB8888(dsc) \ - lv_rgb565_blend_normal_to_argb8888_neon(dsc) -#endif - -#ifndef LV_DRAW_SW_RGB565_BLEND_NORMAL_TO_ARGB8888_WITH_OPA -#define LV_DRAW_SW_RGB565_BLEND_NORMAL_TO_ARGB8888_WITH_OPA(dsc) \ - lv_rgb565_blend_normal_to_argb8888_with_opa_neon(dsc) -#endif - -#ifndef LV_DRAW_SW_RGB565_BLEND_NORMAL_TO_ARGB8888_WITH_MASK -#define LV_DRAW_SW_RGB565_BLEND_NORMAL_TO_ARGB8888_WITH_MASK(dsc) \ - lv_rgb565_blend_normal_to_argb8888_with_mask_neon(dsc) -#endif - -#ifndef LV_DRAW_SW_RGB565_BLEND_NORMAL_TO_ARGB8888_MIX_MASK_OPA -#define LV_DRAW_SW_RGB565_BLEND_NORMAL_TO_ARGB8888_MIX_MASK_OPA(dsc) \ - lv_rgb565_blend_normal_to_argb8888_mix_mask_opa_neon(dsc) -#endif - -#ifndef LV_DRAW_SW_RGB888_BLEND_NORMAL_TO_ARGB8888 -#define LV_DRAW_SW_RGB888_BLEND_NORMAL_TO_ARGB8888(dsc, src_px_size) \ - lv_rgb888_blend_normal_to_argb8888_neon(dsc, src_px_size) -#endif - -#ifndef LV_DRAW_SW_RGB888_BLEND_NORMAL_TO_ARGB8888_WITH_OPA -#define LV_DRAW_SW_RGB888_BLEND_NORMAL_TO_ARGB8888_WITH_OPA(dsc, src_px_size) \ - lv_rgb888_blend_normal_to_argb8888_with_opa_neon(dsc, src_px_size) -#endif - -#ifndef LV_DRAW_SW_RGB888_BLEND_NORMAL_TO_ARGB8888_WITH_MASK -#define LV_DRAW_SW_RGB888_BLEND_NORMAL_TO_ARGB8888_WITH_MASK(dsc, src_px_size) \ - lv_rgb888_blend_normal_to_argb8888_with_mask_neon(dsc, src_px_size) -#endif - -#ifndef LV_DRAW_SW_RGB888_BLEND_NORMAL_TO_ARGB8888_MIX_MASK_OPA -#define LV_DRAW_SW_RGB888_BLEND_NORMAL_TO_ARGB8888_MIX_MASK_OPA(dsc, src_px_size) \ - lv_rgb888_blend_normal_to_argb8888_mix_mask_opa_neon(dsc, src_px_size) -#endif - -#ifndef LV_DRAW_SW_ARGB8888_BLEND_NORMAL_TO_ARGB8888 -#define LV_DRAW_SW_ARGB8888_BLEND_NORMAL_TO_ARGB8888(dsc) \ - lv_argb8888_blend_normal_to_argb8888_neon(dsc) -#endif - -#ifndef LV_DRAW_SW_ARGB8888_BLEND_NORMAL_TO_ARGB8888_WITH_OPA -#define LV_DRAW_SW_ARGB8888_BLEND_NORMAL_TO_ARGB8888_WITH_OPA(dsc) \ - lv_argb8888_blend_normal_to_argb8888_with_opa_neon(dsc) -#endif - -#ifndef LV_DRAW_SW_ARGB8888_BLEND_NORMAL_TO_ARGB8888_WITH_MASK -#define LV_DRAW_SW_ARGB8888_BLEND_NORMAL_TO_ARGB8888_WITH_MASK(dsc) \ - lv_argb8888_blend_normal_to_argb8888_with_mask_neon(dsc) -#endif - -#ifndef LV_DRAW_SW_ARGB8888_BLEND_NORMAL_TO_ARGB8888_MIX_MASK_OPA -#define LV_DRAW_SW_ARGB8888_BLEND_NORMAL_TO_ARGB8888_MIX_MASK_OPA(dsc) \ - lv_argb8888_blend_normal_to_argb8888_mix_mask_opa_neon(dsc) -#endif /********************** * TYPEDEFS **********************/ -typedef struct { - uint32_t opa; - void * dst_buf; - uint32_t dst_w; - uint32_t dst_h; - uint32_t dst_stride; - const void * src_buf; - uint32_t src_stride; - const lv_opa_t * mask_buf; - uint32_t mask_stride; -} asm_dsc_t; /********************** * GLOBAL PROTOTYPES **********************/ -extern LVGL_HIDDEN void _lv_color_blend_to_rgb565_neon(asm_dsc_t * dsc); -static inline lv_result_t lv_color_blend_to_rgb565_neon(lv_draw_sw_blend_fill_dsc_t * dsc) -{ - asm_dsc_t asm_dsc = { - .dst_buf = dsc->dest_buf, - .dst_w = dsc->dest_w, - .dst_h = dsc->dest_h, - .dst_stride = dsc->dest_stride, - .src_buf = &dsc->color - }; - - _lv_color_blend_to_rgb565_neon(&asm_dsc); - return LV_RESULT_OK; -} - -extern LVGL_HIDDEN void _lv_color_blend_to_rgb565_with_opa_neon(asm_dsc_t * dsc); -static inline lv_result_t lv_color_blend_to_rgb565_with_opa_neon(lv_draw_sw_blend_fill_dsc_t * dsc) -{ - asm_dsc_t asm_dsc = { - .opa = dsc->opa, - .dst_buf = dsc->dest_buf, - .dst_w = dsc->dest_w, - .dst_h = dsc->dest_h, - .dst_stride = dsc->dest_stride, - .src_buf = &dsc->color - }; - _lv_color_blend_to_rgb565_with_opa_neon(&asm_dsc); - return LV_RESULT_OK; -} - -extern LVGL_HIDDEN void _lv_color_blend_to_rgb565_with_mask_neon(asm_dsc_t * dsc); -static inline lv_result_t lv_color_blend_to_rgb565_with_mask_neon(lv_draw_sw_blend_fill_dsc_t * dsc) -{ - asm_dsc_t asm_dsc = { - .dst_buf = dsc->dest_buf, - .dst_w = dsc->dest_w, - .dst_h = dsc->dest_h, - .dst_stride = dsc->dest_stride, - .src_buf = &dsc->color, - .mask_buf = dsc->mask_buf, - .mask_stride = dsc->mask_stride - }; - _lv_color_blend_to_rgb565_with_mask_neon(&asm_dsc); - return LV_RESULT_OK; -} - -extern LVGL_HIDDEN void _lv_color_blend_to_rgb565_mix_mask_opa_neon(asm_dsc_t * dsc); -static inline lv_result_t lv_color_blend_to_rgb565_mix_mask_opa_neon(lv_draw_sw_blend_fill_dsc_t * dsc) -{ - asm_dsc_t asm_dsc = { - .opa = dsc->opa, - .dst_buf = dsc->dest_buf, - .dst_w = dsc->dest_w, - .dst_h = dsc->dest_h, - .dst_stride = dsc->dest_stride, - .src_buf = &dsc->color, - .mask_buf = dsc->mask_buf, - .mask_stride = dsc->mask_stride - }; - _lv_color_blend_to_rgb565_mix_mask_opa_neon(&asm_dsc); - return LV_RESULT_OK; -} - -extern LVGL_HIDDEN void _lv_rgb565_blend_normal_to_rgb565_neon(asm_dsc_t * dsc); -static inline lv_result_t lv_rgb565_blend_normal_to_rgb565_neon(lv_draw_sw_blend_image_dsc_t * dsc) -{ - asm_dsc_t asm_dsc = { - .dst_buf = dsc->dest_buf, - .dst_w = dsc->dest_w, - .dst_h = dsc->dest_h, - .dst_stride = dsc->dest_stride, - .src_buf = dsc->src_buf, - .src_stride = dsc->src_stride - }; - _lv_rgb565_blend_normal_to_rgb565_neon(&asm_dsc); - return LV_RESULT_OK; -} - -extern LVGL_HIDDEN void _lv_rgb565_blend_normal_to_rgb565_with_opa_neon(asm_dsc_t * dsc); -static inline lv_result_t lv_rgb565_blend_normal_to_rgb565_with_opa_neon(lv_draw_sw_blend_image_dsc_t * dsc) -{ - asm_dsc_t asm_dsc = { - .opa = dsc->opa, - .dst_buf = dsc->dest_buf, - .dst_w = dsc->dest_w, - .dst_h = dsc->dest_h, - .dst_stride = dsc->dest_stride, - .src_buf = dsc->src_buf, - .src_stride = dsc->src_stride - }; - _lv_rgb565_blend_normal_to_rgb565_with_opa_neon(&asm_dsc); - return LV_RESULT_OK; -} - -extern LVGL_HIDDEN void _lv_rgb565_blend_normal_to_rgb565_with_mask_neon(asm_dsc_t * dsc); -static inline lv_result_t lv_rgb565_blend_normal_to_rgb565_with_mask_neon(lv_draw_sw_blend_image_dsc_t * dsc) -{ - asm_dsc_t asm_dsc = { - .dst_buf = dsc->dest_buf, - .dst_w = dsc->dest_w, - .dst_h = dsc->dest_h, - .dst_stride = dsc->dest_stride, - .src_buf = dsc->src_buf, - .src_stride = dsc->src_stride, - .mask_buf = dsc->mask_buf, - .mask_stride = dsc->mask_stride - }; - _lv_rgb565_blend_normal_to_rgb565_with_mask_neon(&asm_dsc); - return LV_RESULT_OK; -} - -extern LVGL_HIDDEN void _lv_rgb565_blend_normal_to_rgb565_mix_mask_opa_neon(asm_dsc_t * dsc); -static inline lv_result_t lv_rgb565_blend_normal_to_rgb565_mix_mask_opa_neon(lv_draw_sw_blend_image_dsc_t * dsc) -{ - asm_dsc_t asm_dsc = { - .opa = dsc->opa, - .dst_buf = dsc->dest_buf, - .dst_w = dsc->dest_w, - .dst_h = dsc->dest_h, - .dst_stride = dsc->dest_stride, - .src_buf = dsc->src_buf, - .src_stride = dsc->src_stride, - .mask_buf = dsc->mask_buf, - .mask_stride = dsc->mask_stride - }; - _lv_rgb565_blend_normal_to_rgb565_mix_mask_opa_neon(&asm_dsc); - return LV_RESULT_OK; -} - -extern LVGL_HIDDEN void _lv_rgb888_blend_normal_to_rgb565_neon(asm_dsc_t * dsc); -extern LVGL_HIDDEN void _lv_xrgb8888_blend_normal_to_rgb565_neon(asm_dsc_t * dsc); -static inline lv_result_t lv_rgb888_blend_normal_to_rgb565_neon(lv_draw_sw_blend_image_dsc_t * dsc, - uint32_t src_px_size) -{ - asm_dsc_t asm_dsc = { - .dst_buf = dsc->dest_buf, - .dst_w = dsc->dest_w, - .dst_h = dsc->dest_h, - .dst_stride = dsc->dest_stride, - .src_buf = dsc->src_buf, - .src_stride = dsc->src_stride - }; - if(src_px_size == 3) { - _lv_rgb888_blend_normal_to_rgb565_neon(&asm_dsc); - } - else { - _lv_xrgb8888_blend_normal_to_rgb565_neon(&asm_dsc); - } - return LV_RESULT_OK; -} - -extern LVGL_HIDDEN void _lv_rgb888_blend_normal_to_rgb565_with_opa_neon(asm_dsc_t * dsc); -extern LVGL_HIDDEN void _lv_xrgb8888_blend_normal_to_rgb565_with_opa_neon(asm_dsc_t * dsc); -static inline lv_result_t lv_rgb888_blend_normal_to_rgb565_with_opa_neon(lv_draw_sw_blend_image_dsc_t * dsc, - uint32_t src_px_size) -{ - asm_dsc_t asm_dsc = { - .opa = dsc->opa, - .dst_buf = dsc->dest_buf, - .dst_w = dsc->dest_w, - .dst_h = dsc->dest_h, - .dst_stride = dsc->dest_stride, - .src_buf = dsc->src_buf, - .src_stride = dsc->src_stride - }; - if(src_px_size == 3) { - _lv_rgb888_blend_normal_to_rgb565_with_opa_neon(&asm_dsc); - } - else { - _lv_xrgb8888_blend_normal_to_rgb565_with_opa_neon(&asm_dsc); - } - return LV_RESULT_OK; -} - -extern LVGL_HIDDEN void _lv_rgb888_blend_normal_to_rgb565_with_mask_neon(asm_dsc_t * dsc); -extern LVGL_HIDDEN void _lv_xrgb8888_blend_normal_to_rgb565_with_mask_neon(asm_dsc_t * dsc); -static inline lv_result_t lv_rgb888_blend_normal_to_rgb565_with_mask_neon(lv_draw_sw_blend_image_dsc_t * dsc, - uint32_t src_px_size) -{ - asm_dsc_t asm_dsc = { - .dst_buf = dsc->dest_buf, - .dst_w = dsc->dest_w, - .dst_h = dsc->dest_h, - .dst_stride = dsc->dest_stride, - .src_buf = dsc->src_buf, - .src_stride = dsc->src_stride, - .mask_buf = dsc->mask_buf, - .mask_stride = dsc->mask_stride - }; - if(src_px_size == 3) { - _lv_rgb888_blend_normal_to_rgb565_with_mask_neon(&asm_dsc); - } - else { - _lv_xrgb8888_blend_normal_to_rgb565_with_mask_neon(&asm_dsc); - } - return LV_RESULT_OK; -} - -extern LVGL_HIDDEN void _lv_rgb888_blend_normal_to_rgb565_mix_mask_opa_neon(asm_dsc_t * dsc); -extern LVGL_HIDDEN void _lv_xrgb8888_blend_normal_to_rgb565_mix_mask_opa_neon(asm_dsc_t * dsc); -static inline lv_result_t lv_rgb888_blend_normal_to_rgb565_mix_mask_opa_neon(lv_draw_sw_blend_image_dsc_t * dsc, - uint32_t src_px_size) -{ - asm_dsc_t asm_dsc = { - .opa = dsc->opa, - .dst_buf = dsc->dest_buf, - .dst_w = dsc->dest_w, - .dst_h = dsc->dest_h, - .dst_stride = dsc->dest_stride, - .src_buf = dsc->src_buf, - .src_stride = dsc->src_stride, - .mask_buf = dsc->mask_buf, - .mask_stride = dsc->mask_stride - }; - if(src_px_size == 3) { - _lv_rgb888_blend_normal_to_rgb565_mix_mask_opa_neon(&asm_dsc); - } - else { - _lv_xrgb8888_blend_normal_to_rgb565_mix_mask_opa_neon(&asm_dsc); - } - return LV_RESULT_OK; -} - -extern LVGL_HIDDEN void _lv_argb8888_blend_normal_to_rgb565_neon(asm_dsc_t * dsc); -static inline lv_result_t lv_argb8888_blend_normal_to_rgb565_neon(lv_draw_sw_blend_image_dsc_t * dsc) -{ - asm_dsc_t asm_dsc = { - .dst_buf = dsc->dest_buf, - .dst_w = dsc->dest_w, - .dst_h = dsc->dest_h, - .dst_stride = dsc->dest_stride, - .src_buf = dsc->src_buf, - .src_stride = dsc->src_stride - }; - _lv_argb8888_blend_normal_to_rgb565_neon(&asm_dsc); - return LV_RESULT_OK; -} - -extern LVGL_HIDDEN void _lv_argb8888_blend_normal_to_rgb565_with_opa_neon(asm_dsc_t * dsc); -static inline lv_result_t lv_argb8888_blend_normal_to_rgb565_with_opa_neon(lv_draw_sw_blend_image_dsc_t * dsc) -{ - asm_dsc_t asm_dsc = { - .opa = dsc->opa, - .dst_buf = dsc->dest_buf, - .dst_w = dsc->dest_w, - .dst_h = dsc->dest_h, - .dst_stride = dsc->dest_stride, - .src_buf = dsc->src_buf, - .src_stride = dsc->src_stride - }; - _lv_argb8888_blend_normal_to_rgb565_with_opa_neon(&asm_dsc); - return LV_RESULT_OK; -} - -extern LVGL_HIDDEN void _lv_argb8888_blend_normal_to_rgb565_with_mask_neon(asm_dsc_t * dsc); -static inline lv_result_t lv_argb8888_blend_normal_to_rgb565_with_mask_neon(lv_draw_sw_blend_image_dsc_t * dsc) -{ - asm_dsc_t asm_dsc = { - .dst_buf = dsc->dest_buf, - .dst_w = dsc->dest_w, - .dst_h = dsc->dest_h, - .dst_stride = dsc->dest_stride, - .src_buf = dsc->src_buf, - .src_stride = dsc->src_stride, - .mask_buf = dsc->mask_buf, - .mask_stride = dsc->mask_stride - }; - _lv_argb8888_blend_normal_to_rgb565_with_mask_neon(&asm_dsc); - return LV_RESULT_OK; -} - -extern LVGL_HIDDEN void _lv_argb8888_blend_normal_to_rgb565_mix_mask_opa_neon(asm_dsc_t * dsc); -static inline lv_result_t lv_argb8888_blend_normal_to_rgb565_mix_mask_opa_neon(lv_draw_sw_blend_image_dsc_t * dsc) -{ - asm_dsc_t asm_dsc = { - .opa = dsc->opa, - .dst_buf = dsc->dest_buf, - .dst_w = dsc->dest_w, - .dst_h = dsc->dest_h, - .dst_stride = dsc->dest_stride, - .src_buf = dsc->src_buf, - .src_stride = dsc->src_stride, - .mask_buf = dsc->mask_buf, - .mask_stride = dsc->mask_stride - }; - _lv_argb8888_blend_normal_to_rgb565_mix_mask_opa_neon(&asm_dsc); - return LV_RESULT_OK; -} - -extern LVGL_HIDDEN void _lv_color_blend_to_rgb888_neon(asm_dsc_t * dsc); -extern LVGL_HIDDEN void _lv_color_blend_to_xrgb8888_neon(asm_dsc_t * dsc); -static inline lv_result_t lv_color_blend_to_rgb888_neon(lv_draw_sw_blend_fill_dsc_t * dsc, uint32_t dst_px_size) -{ - asm_dsc_t asm_dsc = { - .dst_buf = dsc->dest_buf, - .dst_w = dsc->dest_w, - .dst_h = dsc->dest_h, - .dst_stride = dsc->dest_stride, - .src_buf = &dsc->color - }; - if(dst_px_size == 3) { - _lv_color_blend_to_rgb888_neon(&asm_dsc); - } - else { - _lv_color_blend_to_xrgb8888_neon(&asm_dsc); - } - return LV_RESULT_OK; -} - -extern LVGL_HIDDEN void _lv_color_blend_to_rgb888_with_opa_neon(asm_dsc_t * dsc); -extern LVGL_HIDDEN void _lv_color_blend_to_xrgb8888_with_opa_neon(asm_dsc_t * dsc); -static inline lv_result_t lv_color_blend_to_rgb888_with_opa_neon(lv_draw_sw_blend_fill_dsc_t * dsc, - uint32_t dst_px_size) -{ - asm_dsc_t asm_dsc = { - .opa = dsc->opa, - .dst_buf = dsc->dest_buf, - .dst_w = dsc->dest_w, - .dst_h = dsc->dest_h, - .dst_stride = dsc->dest_stride, - .src_buf = &dsc->color - }; - if(dst_px_size == 3) { - _lv_color_blend_to_rgb888_with_opa_neon(&asm_dsc); - } - else { - _lv_color_blend_to_xrgb8888_with_opa_neon(&asm_dsc); - } - return LV_RESULT_OK; -} - -extern LVGL_HIDDEN void _lv_color_blend_to_rgb888_with_mask_neon(asm_dsc_t * dsc); -extern LVGL_HIDDEN void _lv_color_blend_to_xrgb8888_with_mask_neon(asm_dsc_t * dsc); -static inline lv_result_t lv_color_blend_to_rgb888_with_mask_neon(lv_draw_sw_blend_fill_dsc_t * dsc, - uint32_t dst_px_size) -{ - asm_dsc_t asm_dsc = { - .dst_buf = dsc->dest_buf, - .dst_w = dsc->dest_w, - .dst_h = dsc->dest_h, - .dst_stride = dsc->dest_stride, - .src_buf = &dsc->color, - .mask_buf = dsc->mask_buf, - .mask_stride = dsc->mask_stride - }; - if(dst_px_size == 3) { - _lv_color_blend_to_rgb888_with_mask_neon(&asm_dsc); - } - else { - _lv_color_blend_to_xrgb8888_with_mask_neon(&asm_dsc); - } - return LV_RESULT_OK; -} - -extern LVGL_HIDDEN void _lv_color_blend_to_rgb888_mix_mask_opa_neon(asm_dsc_t * dsc); -extern LVGL_HIDDEN void _lv_color_blend_to_xrgb8888_mix_mask_opa_neon(asm_dsc_t * dsc); -static inline lv_result_t lv_color_blend_to_rgb888_mix_mask_opa_neon(lv_draw_sw_blend_fill_dsc_t * dsc, - uint32_t dst_px_size) -{ - asm_dsc_t asm_dsc = { - .opa = dsc->opa, - .dst_buf = dsc->dest_buf, - .dst_w = dsc->dest_w, - .dst_h = dsc->dest_h, - .dst_stride = dsc->dest_stride, - .src_buf = &dsc->color, - .mask_buf = dsc->mask_buf, - .mask_stride = dsc->mask_stride - }; - if(dst_px_size == 3) { - _lv_color_blend_to_rgb888_mix_mask_opa_neon(&asm_dsc); - } - else { - _lv_color_blend_to_xrgb8888_mix_mask_opa_neon(&asm_dsc); - } - return LV_RESULT_OK; -} - -extern LVGL_HIDDEN void _lv_rgb565_blend_normal_to_rgb888_neon(asm_dsc_t * dsc); -extern LVGL_HIDDEN void _lv_rgb565_blend_normal_to_xrgb8888_neon(asm_dsc_t * dsc); -static inline lv_result_t lv_rgb565_blend_normal_to_rgb888_neon(lv_draw_sw_blend_image_dsc_t * dsc, - uint32_t dst_px_size) -{ - asm_dsc_t asm_dsc = { - .dst_buf = dsc->dest_buf, - .dst_w = dsc->dest_w, - .dst_h = dsc->dest_h, - .dst_stride = dsc->dest_stride, - .src_buf = dsc->src_buf, - .src_stride = dsc->src_stride - }; - if(dst_px_size == 3) { - _lv_rgb565_blend_normal_to_rgb888_neon(&asm_dsc); - } - else { - _lv_rgb565_blend_normal_to_xrgb8888_neon(&asm_dsc); - } - return LV_RESULT_OK; -} - -extern LVGL_HIDDEN void _lv_rgb565_blend_normal_to_rgb888_with_opa_neon(asm_dsc_t * dsc); -extern LVGL_HIDDEN void _lv_rgb565_blend_normal_to_xrgb8888_with_opa_neon(asm_dsc_t * dsc); -static inline lv_result_t lv_rgb565_blend_normal_to_rgb888_with_opa_neon(lv_draw_sw_blend_image_dsc_t * dsc, - uint32_t dst_px_size) -{ - asm_dsc_t asm_dsc = { - .opa = dsc->opa, - .dst_buf = dsc->dest_buf, - .dst_w = dsc->dest_w, - .dst_h = dsc->dest_h, - .dst_stride = dsc->dest_stride, - .src_buf = dsc->src_buf, - .src_stride = dsc->src_stride - }; - if(dst_px_size == 3) { - _lv_rgb565_blend_normal_to_rgb888_with_opa_neon(&asm_dsc); - } - else { - _lv_rgb565_blend_normal_to_xrgb8888_with_opa_neon(&asm_dsc); - } - return LV_RESULT_OK; -} - -extern LVGL_HIDDEN void _lv_rgb565_blend_normal_to_rgb888_with_mask_neon(asm_dsc_t * dsc); -extern LVGL_HIDDEN void _lv_rgb565_blend_normal_to_xrgb8888_with_mask_neon(asm_dsc_t * dsc); -static inline lv_result_t lv_rgb565_blend_normal_to_rgb888_with_mask_neon(lv_draw_sw_blend_image_dsc_t * dsc, - uint32_t dst_px_size) -{ - asm_dsc_t asm_dsc = { - .dst_buf = dsc->dest_buf, - .dst_w = dsc->dest_w, - .dst_h = dsc->dest_h, - .dst_stride = dsc->dest_stride, - .src_buf = dsc->src_buf, - .src_stride = dsc->src_stride, - .mask_buf = dsc->mask_buf, - .mask_stride = dsc->mask_stride - }; - if(dst_px_size == 3) { - _lv_rgb565_blend_normal_to_rgb888_with_mask_neon(&asm_dsc); - } - else { - _lv_rgb565_blend_normal_to_xrgb8888_with_mask_neon(&asm_dsc); - } - return LV_RESULT_OK; -} - -extern LVGL_HIDDEN void _lv_rgb565_blend_normal_to_rgb888_mix_mask_opa_neon(asm_dsc_t * dsc); -extern LVGL_HIDDEN void _lv_rgb565_blend_normal_to_xrgb8888_mix_mask_opa_neon(asm_dsc_t * dsc); -static inline lv_result_t lv_rgb565_blend_normal_to_rgb888_mix_mask_opa_neon(lv_draw_sw_blend_image_dsc_t * dsc, - uint32_t dst_px_size) -{ - asm_dsc_t asm_dsc = { - .opa = dsc->opa, - .dst_buf = dsc->dest_buf, - .dst_w = dsc->dest_w, - .dst_h = dsc->dest_h, - .dst_stride = dsc->dest_stride, - .src_buf = dsc->src_buf, - .src_stride = dsc->src_stride, - .mask_buf = dsc->mask_buf, - .mask_stride = dsc->mask_stride - }; - if(dst_px_size == 3) { - _lv_rgb565_blend_normal_to_rgb888_mix_mask_opa_neon(&asm_dsc); - } - else { - _lv_rgb565_blend_normal_to_xrgb8888_mix_mask_opa_neon(&asm_dsc); - } - return LV_RESULT_OK; -} - -extern LVGL_HIDDEN void _lv_rgb888_blend_normal_to_rgb888_neon(asm_dsc_t * dsc); -extern LVGL_HIDDEN void _lv_rgb888_blend_normal_to_xrgb8888_neon(asm_dsc_t * dsc); -extern LVGL_HIDDEN void _lv_xrgb8888_blend_normal_to_rgb888_neon(asm_dsc_t * dsc); -extern LVGL_HIDDEN void _lv_xrgb8888_blend_normal_to_xrgb8888_neon(asm_dsc_t * dsc); -static inline lv_result_t lv_rgb888_blend_normal_to_rgb888_neon(lv_draw_sw_blend_image_dsc_t * dsc, - uint32_t dst_px_size, - uint32_t src_px_size) -{ - asm_dsc_t asm_dsc = { - .dst_buf = dsc->dest_buf, - .dst_w = dsc->dest_w, - .dst_h = dsc->dest_h, - .dst_stride = dsc->dest_stride, - .src_buf = dsc->src_buf, - .src_stride = dsc->src_stride - }; - if(dst_px_size == 3) { - if(src_px_size == 3) { - _lv_rgb888_blend_normal_to_rgb888_neon(&asm_dsc); - } - else { - _lv_xrgb8888_blend_normal_to_rgb888_neon(&asm_dsc); - } - } - else { - if(src_px_size == 3) { - _lv_rgb888_blend_normal_to_xrgb8888_neon(&asm_dsc); - } - else { - _lv_xrgb8888_blend_normal_to_xrgb8888_neon(&asm_dsc); - } - } - return LV_RESULT_OK; -} - -extern LVGL_HIDDEN void _lv_rgb888_blend_normal_to_rgb888_with_opa_neon(asm_dsc_t * dsc); -extern LVGL_HIDDEN void _lv_rgb888_blend_normal_to_xrgb8888_with_opa_neon(asm_dsc_t * dsc); -extern LVGL_HIDDEN void _lv_xrgb8888_blend_normal_to_rgb888_with_opa_neon(asm_dsc_t * dsc); -extern LVGL_HIDDEN void _lv_xrgb8888_blend_normal_to_xrgb8888_with_opa_neon(asm_dsc_t * dsc); -static inline lv_result_t lv_rgb888_blend_normal_to_rgb888_with_opa_neon(lv_draw_sw_blend_image_dsc_t * dsc, - uint32_t dst_px_size, uint32_t src_px_size) -{ - asm_dsc_t asm_dsc = { - .opa = dsc->opa, - .dst_buf = dsc->dest_buf, - .dst_w = dsc->dest_w, - .dst_h = dsc->dest_h, - .dst_stride = dsc->dest_stride, - .src_buf = dsc->src_buf, - .src_stride = dsc->src_stride - }; - if(dst_px_size == 3) { - if(src_px_size == 3) { - _lv_rgb888_blend_normal_to_rgb888_with_opa_neon(&asm_dsc); - } - else { - _lv_xrgb8888_blend_normal_to_rgb888_with_opa_neon(&asm_dsc); - } - } - else { - if(src_px_size == 3) { - _lv_rgb888_blend_normal_to_xrgb8888_with_opa_neon(&asm_dsc); - } - else { - _lv_xrgb8888_blend_normal_to_xrgb8888_with_opa_neon(&asm_dsc); - } - } - return LV_RESULT_OK; -} - -extern LVGL_HIDDEN void _lv_rgb888_blend_normal_to_rgb888_with_mask_neon(asm_dsc_t * dsc); -extern LVGL_HIDDEN void _lv_rgb888_blend_normal_to_xrgb8888_with_mask_neon(asm_dsc_t * dsc); -extern LVGL_HIDDEN void _lv_xrgb8888_blend_normal_to_rgb888_with_mask_neon(asm_dsc_t * dsc); -extern LVGL_HIDDEN void _lv_xrgb8888_blend_normal_to_xrgb8888_with_mask_neon(asm_dsc_t * dsc); -static inline lv_result_t lv_rgb888_blend_normal_to_rgb888_with_mask_neon(lv_draw_sw_blend_image_dsc_t * dsc, - uint32_t dst_px_size, uint32_t src_px_size) -{ - asm_dsc_t asm_dsc = { - .dst_buf = dsc->dest_buf, - .dst_w = dsc->dest_w, - .dst_h = dsc->dest_h, - .dst_stride = dsc->dest_stride, - .src_buf = dsc->src_buf, - .src_stride = dsc->src_stride, - .mask_buf = dsc->mask_buf, - .mask_stride = dsc->mask_stride - }; - if(dst_px_size == 3) { - if(src_px_size == 3) { - _lv_rgb888_blend_normal_to_rgb888_with_mask_neon(&asm_dsc); - } - else { - _lv_xrgb8888_blend_normal_to_rgb888_with_mask_neon(&asm_dsc); - } - } - else { - if(src_px_size == 3) { - _lv_rgb888_blend_normal_to_xrgb8888_with_mask_neon(&asm_dsc); - } - else { - _lv_xrgb8888_blend_normal_to_xrgb8888_with_mask_neon(&asm_dsc); - } - } - return LV_RESULT_OK; -} - -extern LVGL_HIDDEN void _lv_rgb888_blend_normal_to_rgb888_mix_mask_opa_neon(asm_dsc_t * dsc); -extern LVGL_HIDDEN void _lv_rgb888_blend_normal_to_xrgb8888_mix_mask_opa_neon(asm_dsc_t * dsc); -extern LVGL_HIDDEN void _lv_xrgb8888_blend_normal_to_rgb888_mix_mask_opa_neon(asm_dsc_t * dsc); -extern LVGL_HIDDEN void _lv_xrgb8888_blend_normal_to_xrgb8888_mix_mask_opa_neon(asm_dsc_t * dsc); -static inline lv_result_t lv_rgb888_blend_normal_to_rgb888_mix_mask_opa_neon(lv_draw_sw_blend_image_dsc_t * dsc, - uint32_t dst_px_size, uint32_t src_px_size) -{ - asm_dsc_t asm_dsc = { - .opa = dsc->opa, - .dst_buf = dsc->dest_buf, - .dst_w = dsc->dest_w, - .dst_h = dsc->dest_h, - .dst_stride = dsc->dest_stride, - .src_buf = dsc->src_buf, - .src_stride = dsc->src_stride, - .mask_buf = dsc->mask_buf, - .mask_stride = dsc->mask_stride - }; - if(dst_px_size == 3) { - if(src_px_size == 3) { - _lv_rgb888_blend_normal_to_rgb888_mix_mask_opa_neon(&asm_dsc); - } - else { - _lv_xrgb8888_blend_normal_to_rgb888_mix_mask_opa_neon(&asm_dsc); - } - } - else { - if(src_px_size == 3) { - _lv_rgb888_blend_normal_to_xrgb8888_mix_mask_opa_neon(&asm_dsc); - } - else { - _lv_xrgb8888_blend_normal_to_xrgb8888_mix_mask_opa_neon(&asm_dsc); - } - } - return LV_RESULT_OK; -} - -extern LVGL_HIDDEN void _lv_argb8888_blend_normal_to_rgb888_neon(asm_dsc_t * dsc); -extern LVGL_HIDDEN void _lv_argb8888_blend_normal_to_xrgb8888_neon(asm_dsc_t * dsc); -static inline lv_result_t lv_argb8888_blend_normal_to_rgb888_neon(lv_draw_sw_blend_image_dsc_t * dsc, - uint32_t dst_px_size) -{ - asm_dsc_t asm_dsc = { - .dst_buf = dsc->dest_buf, - .dst_w = dsc->dest_w, - .dst_h = dsc->dest_h, - .dst_stride = dsc->dest_stride, - .src_buf = dsc->src_buf, - .src_stride = dsc->src_stride - }; - if(dst_px_size == 3) { - _lv_argb8888_blend_normal_to_rgb888_neon(&asm_dsc); - } - else { - _lv_argb8888_blend_normal_to_xrgb8888_neon(&asm_dsc); - } - return LV_RESULT_OK; -} - -extern LVGL_HIDDEN void _lv_argb8888_blend_normal_to_rgb888_with_opa_neon(asm_dsc_t * dsc); -extern LVGL_HIDDEN void _lv_argb8888_blend_normal_to_xrgb8888_with_opa_neon(asm_dsc_t * dsc); -static inline lv_result_t lv_argb8888_blend_normal_to_rgb888_with_opa_neon(lv_draw_sw_blend_image_dsc_t * dsc, - uint32_t dst_px_size) -{ - asm_dsc_t asm_dsc = { - .opa = dsc->opa, - .dst_buf = dsc->dest_buf, - .dst_w = dsc->dest_w, - .dst_h = dsc->dest_h, - .dst_stride = dsc->dest_stride, - .src_buf = dsc->src_buf, - .src_stride = dsc->src_stride - }; - if(dst_px_size == 3) { - _lv_argb8888_blend_normal_to_rgb888_with_opa_neon(&asm_dsc); - } - else { - _lv_argb8888_blend_normal_to_xrgb8888_with_opa_neon(&asm_dsc); - } - return LV_RESULT_OK; -} - -extern LVGL_HIDDEN void _lv_argb8888_blend_normal_to_rgb888_with_mask_neon(asm_dsc_t * dsc); -extern LVGL_HIDDEN void _lv_argb8888_blend_normal_to_xrgb8888_with_mask_neon(asm_dsc_t * dsc); -static inline lv_result_t lv_argb8888_blend_normal_to_rgb888_with_mask_neon(lv_draw_sw_blend_image_dsc_t * dsc, - uint32_t dst_px_size) -{ - asm_dsc_t asm_dsc = { - .dst_buf = dsc->dest_buf, - .dst_w = dsc->dest_w, - .dst_h = dsc->dest_h, - .dst_stride = dsc->dest_stride, - .src_buf = dsc->src_buf, - .src_stride = dsc->src_stride, - .mask_buf = dsc->mask_buf, - .mask_stride = dsc->mask_stride - }; - if(dst_px_size == 3) { - _lv_argb8888_blend_normal_to_rgb888_with_mask_neon(&asm_dsc); - } - else { - _lv_argb8888_blend_normal_to_xrgb8888_with_mask_neon(&asm_dsc); - } - return LV_RESULT_OK; -} - -extern LVGL_HIDDEN void _lv_argb8888_blend_normal_to_rgb888_mix_mask_opa_neon(asm_dsc_t * dsc); -extern LVGL_HIDDEN void _lv_argb8888_blend_normal_to_xrgb8888_mix_mask_opa_neon(asm_dsc_t * dsc); -static inline lv_result_t lv_argb8888_blend_normal_to_rgb888_mix_mask_opa_neon(lv_draw_sw_blend_image_dsc_t * dsc, - uint32_t dst_px_size) -{ - asm_dsc_t asm_dsc = { - .opa = dsc->opa, - .dst_buf = dsc->dest_buf, - .dst_w = dsc->dest_w, - .dst_h = dsc->dest_h, - .dst_stride = dsc->dest_stride, - .src_buf = dsc->src_buf, - .src_stride = dsc->src_stride, - .mask_buf = dsc->mask_buf, - .mask_stride = dsc->mask_stride - }; - if(dst_px_size == 3) { - _lv_argb8888_blend_normal_to_rgb888_mix_mask_opa_neon(&asm_dsc); - } - else { - _lv_argb8888_blend_normal_to_xrgb8888_mix_mask_opa_neon(&asm_dsc); - } - return LV_RESULT_OK; -} - -extern LVGL_HIDDEN void _lv_color_blend_to_argb8888_neon(asm_dsc_t * dsc); -static inline lv_result_t lv_color_blend_to_argb8888_neon(lv_draw_sw_blend_fill_dsc_t * dsc) -{ - asm_dsc_t asm_dsc = { - .dst_buf = dsc->dest_buf, - .dst_w = dsc->dest_w, - .dst_h = dsc->dest_h, - .dst_stride = dsc->dest_stride, - .src_buf = &dsc->color - }; - - _lv_color_blend_to_argb8888_neon(&asm_dsc); - return LV_RESULT_OK; -} - -extern LVGL_HIDDEN void _lv_color_blend_to_argb8888_with_opa_neon(asm_dsc_t * dsc); -static inline lv_result_t lv_color_blend_to_argb8888_with_opa_neon(lv_draw_sw_blend_fill_dsc_t * dsc) -{ - asm_dsc_t asm_dsc = { - .opa = dsc->opa, - .dst_buf = dsc->dest_buf, - .dst_w = dsc->dest_w, - .dst_h = dsc->dest_h, - .dst_stride = dsc->dest_stride, - .src_buf = &dsc->color - }; - _lv_color_blend_to_argb8888_with_opa_neon(&asm_dsc); - return LV_RESULT_OK; -} - -extern LVGL_HIDDEN void _lv_color_blend_to_argb8888_with_mask_neon(asm_dsc_t * dsc); -static inline lv_result_t lv_color_blend_to_argb8888_with_mask_neon(lv_draw_sw_blend_fill_dsc_t * dsc) -{ - asm_dsc_t asm_dsc = { - .dst_buf = dsc->dest_buf, - .dst_w = dsc->dest_w, - .dst_h = dsc->dest_h, - .dst_stride = dsc->dest_stride, - .src_buf = &dsc->color, - .mask_buf = dsc->mask_buf, - .mask_stride = dsc->mask_stride - }; - _lv_color_blend_to_argb8888_with_mask_neon(&asm_dsc); - return LV_RESULT_OK; -} - -extern LVGL_HIDDEN void _lv_color_blend_to_argb8888_mix_mask_opa_neon(asm_dsc_t * dsc); -static inline lv_result_t lv_color_blend_to_argb8888_mix_mask_opa_neon(lv_draw_sw_blend_fill_dsc_t * dsc) -{ - asm_dsc_t asm_dsc = { - .opa = dsc->opa, - .dst_buf = dsc->dest_buf, - .dst_w = dsc->dest_w, - .dst_h = dsc->dest_h, - .dst_stride = dsc->dest_stride, - .src_buf = &dsc->color, - .mask_buf = dsc->mask_buf, - .mask_stride = dsc->mask_stride - }; - _lv_color_blend_to_argb8888_mix_mask_opa_neon(&asm_dsc); - return LV_RESULT_OK; -} - -extern LVGL_HIDDEN void _lv_rgb565_blend_normal_to_argb8888_neon(asm_dsc_t * dsc); -static inline lv_result_t lv_rgb565_blend_normal_to_argb8888_neon(lv_draw_sw_blend_image_dsc_t * dsc) -{ - asm_dsc_t asm_dsc = { - .dst_buf = dsc->dest_buf, - .dst_w = dsc->dest_w, - .dst_h = dsc->dest_h, - .dst_stride = dsc->dest_stride, - .src_buf = dsc->src_buf, - .src_stride = dsc->src_stride - }; - _lv_rgb565_blend_normal_to_argb8888_neon(&asm_dsc); - return LV_RESULT_OK; -} - -extern LVGL_HIDDEN void _lv_rgb565_blend_normal_to_argb8888_with_opa_neon(asm_dsc_t * dsc); -static inline lv_result_t lv_rgb565_blend_normal_to_argb8888_with_opa_neon(lv_draw_sw_blend_image_dsc_t * dsc) -{ - asm_dsc_t asm_dsc = { - .opa = dsc->opa, - .dst_buf = dsc->dest_buf, - .dst_w = dsc->dest_w, - .dst_h = dsc->dest_h, - .dst_stride = dsc->dest_stride, - .src_buf = dsc->src_buf, - .src_stride = dsc->src_stride - }; - _lv_rgb565_blend_normal_to_argb8888_with_opa_neon(&asm_dsc); - return LV_RESULT_OK; -} - -extern LVGL_HIDDEN void _lv_rgb565_blend_normal_to_argb8888_with_mask_neon(asm_dsc_t * dsc); -static inline lv_result_t lv_rgb565_blend_normal_to_argb8888_with_mask_neon(lv_draw_sw_blend_image_dsc_t * dsc) -{ - asm_dsc_t asm_dsc = { - .dst_buf = dsc->dest_buf, - .dst_w = dsc->dest_w, - .dst_h = dsc->dest_h, - .dst_stride = dsc->dest_stride, - .src_buf = dsc->src_buf, - .src_stride = dsc->src_stride, - .mask_buf = dsc->mask_buf, - .mask_stride = dsc->mask_stride - }; - _lv_rgb565_blend_normal_to_argb8888_with_mask_neon(&asm_dsc); - return LV_RESULT_OK; -} - -extern LVGL_HIDDEN void _lv_rgb565_blend_normal_to_argb8888_mix_mask_opa_neon(asm_dsc_t * dsc); -static inline lv_result_t lv_rgb565_blend_normal_to_argb8888_mix_mask_opa_neon(lv_draw_sw_blend_image_dsc_t * dsc) -{ - asm_dsc_t asm_dsc = { - .opa = dsc->opa, - .dst_buf = dsc->dest_buf, - .dst_w = dsc->dest_w, - .dst_h = dsc->dest_h, - .dst_stride = dsc->dest_stride, - .src_buf = dsc->src_buf, - .src_stride = dsc->src_stride, - .mask_buf = dsc->mask_buf, - .mask_stride = dsc->mask_stride - }; - _lv_rgb565_blend_normal_to_argb8888_mix_mask_opa_neon(&asm_dsc); - return LV_RESULT_OK; -} - -extern LVGL_HIDDEN void _lv_rgb888_blend_normal_to_argb8888_neon(asm_dsc_t * dsc); -extern LVGL_HIDDEN void _lv_xrgb8888_blend_normal_to_argb8888_neon(asm_dsc_t * dsc); -static inline lv_result_t lv_rgb888_blend_normal_to_argb8888_neon(lv_draw_sw_blend_image_dsc_t * dsc, - uint32_t src_px_size) -{ - asm_dsc_t asm_dsc = { - .dst_buf = dsc->dest_buf, - .dst_w = dsc->dest_w, - .dst_h = dsc->dest_h, - .dst_stride = dsc->dest_stride, - .src_buf = dsc->src_buf, - .src_stride = dsc->src_stride - }; - if(src_px_size == 3) { - _lv_rgb888_blend_normal_to_argb8888_neon(&asm_dsc); - } - else { - _lv_xrgb8888_blend_normal_to_argb8888_neon(&asm_dsc); - } - return LV_RESULT_OK; -} - -extern LVGL_HIDDEN void _lv_rgb888_blend_normal_to_argb8888_with_opa_neon(asm_dsc_t * dsc); -extern LVGL_HIDDEN void _lv_xrgb8888_blend_normal_to_argb8888_with_opa_neon(asm_dsc_t * dsc); -static inline lv_result_t lv_rgb888_blend_normal_to_argb8888_with_opa_neon(lv_draw_sw_blend_image_dsc_t * dsc, - uint32_t src_px_size) -{ - asm_dsc_t asm_dsc = { - .opa = dsc->opa, - .dst_buf = dsc->dest_buf, - .dst_w = dsc->dest_w, - .dst_h = dsc->dest_h, - .dst_stride = dsc->dest_stride, - .src_buf = dsc->src_buf, - .src_stride = dsc->src_stride - }; - if(src_px_size == 3) { - _lv_rgb888_blend_normal_to_argb8888_with_opa_neon(&asm_dsc); - } - else { - _lv_xrgb8888_blend_normal_to_argb8888_with_opa_neon(&asm_dsc); - } - return LV_RESULT_OK; -} - -extern LVGL_HIDDEN void _lv_rgb888_blend_normal_to_argb8888_with_mask_neon(asm_dsc_t * dsc); -extern LVGL_HIDDEN void _lv_xrgb8888_blend_normal_to_argb8888_with_mask_neon(asm_dsc_t * dsc); -static inline lv_result_t lv_rgb888_blend_normal_to_argb8888_with_mask_neon(lv_draw_sw_blend_image_dsc_t * dsc, - uint32_t src_px_size) -{ - asm_dsc_t asm_dsc = { - .dst_buf = dsc->dest_buf, - .dst_w = dsc->dest_w, - .dst_h = dsc->dest_h, - .dst_stride = dsc->dest_stride, - .src_buf = dsc->src_buf, - .src_stride = dsc->src_stride, - .mask_buf = dsc->mask_buf, - .mask_stride = dsc->mask_stride - }; - if(src_px_size == 3) { - _lv_rgb888_blend_normal_to_argb8888_with_mask_neon(&asm_dsc); - } - else { - _lv_xrgb8888_blend_normal_to_argb8888_with_mask_neon(&asm_dsc); - } - return LV_RESULT_OK; -} - -extern LVGL_HIDDEN void _lv_rgb888_blend_normal_to_argb8888_mix_mask_opa_neon(asm_dsc_t * dsc); -extern LVGL_HIDDEN void _lv_xrgb8888_blend_normal_to_argb8888_mix_mask_opa_neon(asm_dsc_t * dsc); -static inline lv_result_t lv_rgb888_blend_normal_to_argb8888_mix_mask_opa_neon(lv_draw_sw_blend_image_dsc_t * dsc, - uint32_t src_px_size) -{ - asm_dsc_t asm_dsc = { - .opa = dsc->opa, - .dst_buf = dsc->dest_buf, - .dst_w = dsc->dest_w, - .dst_h = dsc->dest_h, - .dst_stride = dsc->dest_stride, - .src_buf = dsc->src_buf, - .src_stride = dsc->src_stride, - .mask_buf = dsc->mask_buf, - .mask_stride = dsc->mask_stride - }; - if(src_px_size == 3) { - _lv_rgb888_blend_normal_to_argb8888_mix_mask_opa_neon(&asm_dsc); - } - else { - _lv_xrgb8888_blend_normal_to_argb8888_mix_mask_opa_neon(&asm_dsc); - } - return LV_RESULT_OK; -} - -extern LVGL_HIDDEN void _lv_argb8888_blend_normal_to_argb8888_neon(asm_dsc_t * dsc); -static inline lv_result_t lv_argb8888_blend_normal_to_argb8888_neon(lv_draw_sw_blend_image_dsc_t * dsc) -{ - asm_dsc_t asm_dsc = { - .dst_buf = dsc->dest_buf, - .dst_w = dsc->dest_w, - .dst_h = dsc->dest_h, - .dst_stride = dsc->dest_stride, - .src_buf = dsc->src_buf, - .src_stride = dsc->src_stride - }; - _lv_argb8888_blend_normal_to_argb8888_neon(&asm_dsc); - return LV_RESULT_OK; -} - -extern LVGL_HIDDEN void _lv_argb8888_blend_normal_to_argb8888_with_opa_neon(asm_dsc_t * dsc); -static inline lv_result_t lv_argb8888_blend_normal_to_argb8888_with_opa_neon(lv_draw_sw_blend_image_dsc_t * dsc) -{ - asm_dsc_t asm_dsc = { - .opa = dsc->opa, - .dst_buf = dsc->dest_buf, - .dst_w = dsc->dest_w, - .dst_h = dsc->dest_h, - .dst_stride = dsc->dest_stride, - .src_buf = dsc->src_buf, - .src_stride = dsc->src_stride - }; - _lv_argb8888_blend_normal_to_argb8888_with_opa_neon(&asm_dsc); - return LV_RESULT_OK; -} - -extern LVGL_HIDDEN void _lv_argb8888_blend_normal_to_argb8888_with_mask_neon(asm_dsc_t * dsc); -static inline lv_result_t lv_argb8888_blend_normal_to_argb8888_with_mask_neon(lv_draw_sw_blend_image_dsc_t * dsc) -{ - asm_dsc_t asm_dsc = { - .dst_buf = dsc->dest_buf, - .dst_w = dsc->dest_w, - .dst_h = dsc->dest_h, - .dst_stride = dsc->dest_stride, - .src_buf = dsc->src_buf, - .src_stride = dsc->src_stride, - .mask_buf = dsc->mask_buf, - .mask_stride = dsc->mask_stride - }; - _lv_argb8888_blend_normal_to_argb8888_with_mask_neon(&asm_dsc); - return LV_RESULT_OK; -} - -extern LVGL_HIDDEN void _lv_argb8888_blend_normal_to_argb8888_mix_mask_opa_neon(asm_dsc_t * dsc); -static inline lv_result_t lv_argb8888_blend_normal_to_argb8888_mix_mask_opa_neon(lv_draw_sw_blend_image_dsc_t * dsc) -{ - asm_dsc_t asm_dsc = { - .opa = dsc->opa, - .dst_buf = dsc->dest_buf, - .dst_w = dsc->dest_w, - .dst_h = dsc->dest_h, - .dst_stride = dsc->dest_stride, - .src_buf = dsc->src_buf, - .src_stride = dsc->src_stride, - .mask_buf = dsc->mask_buf, - .mask_stride = dsc->mask_stride - }; - _lv_argb8888_blend_normal_to_argb8888_mix_mask_opa_neon(&asm_dsc); - return LV_RESULT_OK; -} - -#endif /* !defined(__ASSEMBLY__) */ - /********************** * MACROS **********************/ +#endif /* #if LV_USE_DRAW_SW_ASM == LV_DRAW_SW_ASM_NEON */ + #ifdef __cplusplus } /*extern "C"*/ #endif diff --git a/src/draw/sw/blend/neon/lv_draw_sw_blend_neon_to_rgb565.c b/src/draw/sw/blend/neon/lv_draw_sw_blend_neon_to_rgb565.c new file mode 100644 index 0000000000..2b933e687b --- /dev/null +++ b/src/draw/sw/blend/neon/lv_draw_sw_blend_neon_to_rgb565.c @@ -0,0 +1,2093 @@ +/** + * @file lv_draw_sw_blend_neon_to_rgb565.c + * + */ + +/********************* + * INCLUDES + *********************/ +#include "lv_draw_sw_blend_neon_to_rgb565.h" +#if LV_USE_DRAW_SW_ASM == LV_DRAW_SW_ASM_NEON + +#include "../../../../misc/lv_color.h" +#include "../../../../misc/lv_types.h" +#include "../lv_draw_sw_blend_private.h" +#include + +/********************* + * DEFINES + *********************/ + +/********************** + * TYPEDEFS + **********************/ + +/********************** + * STATIC PROTOTYPES + **********************/ + +static inline void * LV_ATTRIBUTE_FAST_MEM drawbuf_next_row(const void * buf, uint32_t stride); + +static inline uint16x8_t l8_to_rgb565_8(const uint8_t * src); +static inline uint16x4_t l8_to_rgb565_4(const uint8_t * src); +static inline uint32_t l8_to_rgb565_2(const uint8_t * src); +static inline uint16_t l8_to_rgb565_1(const uint8_t * src); + +static inline uint16x8_t lv_color_8_16_mix_8(const uint16_t * src, const uint16_t * dst); +static inline uint16x4_t lv_color_8_16_mix_4(const uint16_t * src, const uint16_t * dst); + +static inline uint16x8_t lv_color_8_16_mix_8_with_opa(const uint16_t * src, const uint16_t * dst, uint8_t opa); +static inline uint16x4_t lv_color_8_16_mix_4_with_opa(const uint16_t * src, const uint16_t * dst, uint8_t opa); +static inline uint16x8_t lv_color_8_16_mix_8_with_mask(const uint16_t * src, const uint16_t * dst, + const uint8_t * mask); +static inline uint16x4_t lv_color_8_16_mix_4_with_mask(const uint16_t * src, const uint16_t * dst, + const uint8_t * mask); +static inline uint16x8_t lv_color_8_16_mix_8_with_opa_mask(const uint16_t * src, const uint16_t * dst, uint8_t opa, + const uint8_t * mask); +static inline uint16x4_t lv_color_8_16_mix_4_with_opa_mask(const uint16_t * src, const uint16_t * dst, uint8_t opa, + const uint8_t * mask); + +static inline uint16x8_t lv_color_8_16_mix_8_internal(uint16x8_t dst_pixels, uint16x8_t src_pixels, + uint16x8_t mix_pixels); +static inline uint16x4_t lv_color_8_16_mix_4_internal(uint16x4_t dst_pixels, uint16x4_t src_pixels, + uint16x4_t mix_pixels); + +static inline uint32_t lv_color_8_16_mix_2(const uint8_t * src, const uint16_t * dst); +static inline uint32_t lv_color_8_16_mix_2_with_opa(const uint8_t * src, const uint16_t * dst, uint8_t opa); +static inline uint32_t lv_color_8_16_mix_2_with_mask(const uint8_t * src, const uint16_t * dst, const uint8_t * mask); +static inline uint32_t lv_color_8_16_mix_2_with_opa_mask(const uint8_t * src, const uint16_t * dst, uint8_t, + const uint8_t * mask); + +static inline uint16_t lv_color_8_16_mix_1_internal(uint8_t src, uint16_t dst, uint8_t mix); + +static inline uint16x8_t lv_color_32_16_mix_8(const uint8_t * src, const uint16_t * dst); +static inline uint16x8_t lv_color_32_16_mix_8_with_opa(const uint8_t * src, const uint16_t * dst, uint8_t opa); +static inline uint16x8_t lv_color_32_16_mix_8_with_mask(const uint8_t * src, const uint16_t * dst, + const uint8_t * mask); +static inline uint16x8_t lv_color_32_16_mix_8_with_opa_mask(const uint8_t * src, const uint16_t * dst, uint8_t opa, + const uint8_t * mask); + +static inline uint16x8_t lv_color_32_16_mix_8_internal(uint16x8_t g_pixels, uint16x8_t r_pixels, uint16x8_t b_pixels, + uint16x8_t a_pixels, uint16x8_t dst_pixels); + +static inline uint16x4_t lv_color_32_16_mix_4(const uint8_t * src, const uint16_t * dst); + +static inline uint16x4_t lv_color_32_16_mix_4_with_opa(const uint8_t * src, const uint16_t * dst, uint8_t opa); +static inline uint16x4_t lv_color_32_16_mix_4_with_mask(const uint8_t * src, const uint16_t * dst, + const uint8_t * mask); +static inline uint16x4_t lv_color_32_16_mix_4_with_opa_mask(const uint8_t * src, const uint16_t * dst, uint8_t opa, + const uint8_t * mask); +static inline uint16x4_t lv_color_32_16_mix_4_internal(uint16x4_t g_pixels, uint16x4_t r_pixels, uint16x4_t b_pixels, + uint16x4_t a_pixels, uint16x4_t dst_pixels); + +static inline uint32_t lv_color_32_16_mix_2(const uint8_t * src, const uint16_t * dst); + +static inline uint32_t lv_color_32_16_mix_2_with_opa(const uint8_t * src, const uint16_t * dst, uint8_t opa); +static inline uint32_t lv_color_32_16_mix_2_with_mask(const uint8_t * src, const uint16_t * dst, const uint8_t * mask); +static inline uint32_t lv_color_32_16_mix_2_with_opa_mask(const uint8_t * src, const uint16_t * dst, uint8_t opa, + const uint8_t * mask); + +static inline uint32_t lv_color_32_16_mix_1(const uint8_t * src, const uint16_t * dst); +static inline uint16_t lv_color_32_16_mix_1_with_opa(const uint8_t * src, const uint16_t * dst, uint8_t opa); +static inline uint16_t lv_color_32_16_mix_1_with_mask(const uint8_t * src, const uint16_t * dst, const uint8_t * mask); +static inline uint16_t lv_color_32_16_mix_1_with_opa_mask(const uint8_t * src, const uint16_t * dst, uint8_t opa, + const uint8_t * mask); + +#if LV_DRAW_SW_SUPPORT_ARGB8888_PREMULTIPLIED + static inline uint16x8_t lv_color_24_16_mix_premult_8(const uint8_t * src, const uint16_t * dst); + static inline uint16x4_t lv_color_24_16_mix_premult_4(const uint8_t * src, const uint16_t * dst); + static inline uint32_t lv_color_24_16_mix_premult_2(const uint8_t * src, const uint16_t * dst); + static inline uint16_t lv_color_24_16_mix_premult_1(const uint8_t * src, const uint16_t * dst); +#endif + +static inline uint16x8_t lv_color_24_16_mix_8_with_opa(const uint8_t * src, const uint16_t * dst, uint8_t opa, + uint8_t src_px_size); +static inline uint16x4_t lv_color_24_16_mix_4_with_opa(const uint8_t * src, const uint16_t * dst, uint8_t opa, + uint8_t src_px_size); +static inline uint32_t lv_color_24_16_mix_2_with_opa(const uint8_t * src, const uint16_t * dst, uint8_t opa, + uint8_t src_px_size); + +static inline uint16x8_t lv_color_24_16_mix_8_with_mask(const uint8_t * src, const uint16_t * dst, const uint8_t * mask, + uint8_t src_px_size); +static inline uint16x4_t lv_color_24_16_mix_4_with_mask(const uint8_t * src, const uint16_t * dst, const uint8_t * mask, + uint8_t src_px_size); +static inline uint32_t lv_color_24_16_mix_2_with_mask(const uint8_t * src, const uint16_t * dst, const uint8_t * mask, + uint8_t src_px_size); + +static inline uint16x8_t lv_color_24_16_mix_8_with_opa_mask(const uint8_t * src, const uint16_t * dst, uint8_t opa, + const uint8_t * mask, uint8_t src_px_size); +static inline uint16x4_t lv_color_24_16_mix_4_with_opa_mask(const uint8_t * src, const uint16_t * dst, uint8_t opa, + const uint8_t * mask, uint8_t src_px_size); +static inline uint32_t lv_color_24_16_mix_2_with_opa_mask(const uint8_t * src, const uint16_t * dst, uint8_t opa, + const uint8_t * mask, uint8_t src_px_size); + +static inline uint16_t lv_color_24_16_mix_1_internal(const uint8_t * src, const uint16_t * dst, uint8_t mix); +static inline uint16x8_t rgb888_to_rgb565_8(const uint8_t * src, uint8_t src_px_size); +static inline uint16x4_t rgb888_to_rgb565_4(const uint8_t * src, uint8_t src_px_size); +static inline uint32_t rgb888_to_rgb565_2(const uint8_t * src, uint8_t src_px_size); +static inline uint16_t rgb888_to_rgb565_1(const uint8_t * src); + +static inline uint16x8_t lv_color_16_16_mix_8_with_opa(const uint16_t * c1, const uint16_t * c2, uint8_t opa); +static inline uint16x8_t lv_color_16_16_mix_8_with_mask(const uint16_t * c1, const uint16_t * c2, const uint8_t * mask); +static inline uint16x8_t lv_color_16_16_mix_8_with_opa_mask(const uint16_t * c1, const uint16_t * c2, uint8_t opa, + const uint8_t * mask); +static inline uint16x8_t lv_color_16_16_mix_8_internal(uint16x8_t c1_vec, uint16x8_t c2_vec, uint16x8_t mix); + +static inline uint16x4_t lv_color_16_16_mix_4_with_opa(const uint16_t * c1, const uint16_t * c2, uint8_t opa); +static inline uint16x4_t lv_color_16_16_mix_4_with_mask(const uint16_t * c1, const uint16_t * c2, const uint8_t * mask); +static inline uint16x4_t lv_color_16_16_mix_4_with_opa_mask(const uint16_t * c1, const uint16_t * c2, uint8_t opa, + const uint8_t * mask); +static inline uint16x4_t lv_color_16_16_mix_4_internal(uint16x4_t c1_vec, uint16x4_t c2_vec, uint16x4_t mix); + +static inline uint32_t lv_color_16_16_mix_2_with_opa(const uint16_t * c1, const uint16_t * c2, uint8_t opa); +static inline uint32_t lv_color_16_16_mix_2_with_mask(const uint16_t * c1, const uint16_t * c2, const uint8_t * mask); +static inline uint32_t lv_color_16_16_mix_2_with_opa_mask(const uint16_t * c1, const uint16_t * c2, uint8_t opa, + const uint8_t * mask); + +/********************** + * STATIC VARIABLES + **********************/ + +/********************** + * MACROS + **********************/ + +/********************** + * GLOBAL FUNCTIONS + **********************/ + +lv_result_t lv_draw_sw_blend_neon_color_to_rgb565(lv_draw_sw_blend_fill_dsc_t * dsc) +{ + + LV_ASSERT(dsc->opa >= LV_OPA_MAX); + LV_ASSERT(dsc->mask_buf == NULL); + const int32_t w = dsc->dest_w; + const int32_t h = dsc->dest_h; + const int32_t dest_stride = dsc->dest_stride; + const uint16_t color16 = lv_color_to_u16(dsc->color); + const uint16x8_t color_vec_8 = vdupq_n_u16(color16); + const uint16x4_t color_vec_4 = vdup_n_u16(color16); + const uint32_t color_vec_2 = color16 << 16 | color16; + uint16_t * dest_buf_u16 = dsc->dest_buf; + + for(int32_t y = 0; y < h; y++) { + uint16_t * row_ptr = dest_buf_u16; + int32_t x = 0; + /* Handle unaligned pixels at the beginning */ + const size_t offset = ((size_t)row_ptr) & 0xF; + if(offset != 0) { + int32_t pixel_alignment = (16 - offset) >> 1; + pixel_alignment = (pixel_alignment > w) ? w : pixel_alignment; + for(; x < pixel_alignment; x++) { + row_ptr[x] = color16; + } + } + for(; x < w - 7; x += 8) { + vst1q_u16(&row_ptr[x], color_vec_8); + } + for(; x < w - 3; x += 4) { + vst1_u16(&row_ptr[x], color_vec_4); + } + for(; x < w - 1; x += 2) { + *(uint32_t *)&row_ptr[x] = color_vec_2; + } + for(; x < w; x++) { + row_ptr[x] = color16; + } + + dest_buf_u16 = drawbuf_next_row(dest_buf_u16, dest_stride); + } + + return LV_RESULT_OK; +} +lv_result_t lv_draw_sw_blend_neon_color_to_rgb565_with_opa(lv_draw_sw_blend_fill_dsc_t * dsc) +{ + + LV_ASSERT(dsc->opa < LV_OPA_MAX); + LV_ASSERT(dsc->mask_buf == NULL); + const int32_t w = dsc->dest_w; + const int32_t h = dsc->dest_h; + const int32_t dest_stride = dsc->dest_stride; + const uint16_t color16 = lv_color_to_u16(dsc->color); + const uint32_t color32 = color16 << 16 | color16; + const uint16x8_t color_vec_8 = vdupq_n_u16(color16); + const uint16x4_t color_vec_4 = vdup_n_u16(color16); + const uint8_t opa = dsc->opa; + const uint16x8_t opa_vec_8 = vmovq_n_u16(opa); + const uint16x4_t opa_vec_4 = vmov_n_u16(opa); + uint16_t * dest_buf_u16 = dsc->dest_buf; + + for(int32_t y = 0; y < h; y++) { + uint16_t * row_ptr = dest_buf_u16; + int32_t x = 0; + /* Handle unaligned pixels at the beginning */ + const size_t offset = ((size_t)row_ptr) & 0xF; + if(offset != 0) { + int32_t pixel_alignment = (16 - offset) >> 1; + pixel_alignment = (pixel_alignment > w) ? w : pixel_alignment; + for(; x < pixel_alignment; x++) { + row_ptr[x] = lv_color_16_16_mix(color16, row_ptr[x], opa); + } + } + for(; x < w - 7; x += 8) { + const uint16x8_t src = vld1q_u16(&row_ptr[x]); + vst1q_u16(&row_ptr[x], lv_color_16_16_mix_8_internal(color_vec_8, src, opa_vec_8)); + } + for(; x < w - 3; x += 4) { + const uint16x4_t src = vld1_u16(&row_ptr[x]); + vst1_u16(&row_ptr[x], lv_color_16_16_mix_4_internal(color_vec_4, src, opa_vec_4)); + } + for(; x < w - 1; x += 2) { + *(uint32_t *)&row_ptr[x] = lv_color_16_16_mix_2_with_opa((const uint16_t *)&color32, &row_ptr[x], opa); + } + for(; x < w; x++) { + row_ptr[x] = lv_color_16_16_mix(color16, row_ptr[x], opa); + } + + dest_buf_u16 = drawbuf_next_row(dest_buf_u16, dest_stride); + } + + return LV_RESULT_OK; +} +lv_result_t lv_draw_sw_blend_neon_color_to_rgb565_with_mask(lv_draw_sw_blend_fill_dsc_t * dsc) +{ + LV_ASSERT(dsc->opa >= LV_OPA_MAX); + LV_ASSERT(dsc->mask_buf != NULL); + const int32_t w = dsc->dest_w; + const int32_t h = dsc->dest_h; + const int32_t dest_stride = dsc->dest_stride; + const uint16_t color16 = lv_color_to_u16(dsc->color); + const uint32_t color32 = color16 << 16 | color16; + const uint16x8_t color_vec_8 = vdupq_n_u16(color16); + const uint16x4_t color_vec_4 = vdup_n_u16(color16); + uint16_t * dest_buf_u16 = dsc->dest_buf; + const uint8_t * mask_buf_u8 = dsc->mask_buf; + const int32_t mask_stride = dsc->mask_stride; + + for(int32_t y = 0; y < h; y++) { + uint16_t * row_ptr = dest_buf_u16; + const uint8_t * mask_row = mask_buf_u8; + int32_t x = 0; + /* Handle unaligned pixels at the beginning */ + const size_t offset = ((size_t)row_ptr) & 0xF; + if(offset != 0) { + int32_t pixel_alignment = (16 - offset) >> 1; + pixel_alignment = (pixel_alignment > w) ? w : pixel_alignment; + for(; x < pixel_alignment; x++) { + row_ptr[x] = lv_color_16_16_mix(color16, row_ptr[x], mask_row[x]); + } + } + for(; x < w - 7; x += 8) { + const uint16x8_t src = vld1q_u16(&row_ptr[x]); + const uint16x8_t mask = vmovl_u8(vld1_u8(&mask_row[x])); + vst1q_u16(&row_ptr[x], lv_color_16_16_mix_8_internal(color_vec_8, src, mask)); + } + for(; x < w - 3; x += 4) { + const uint16x4_t src = vld1_u16(&row_ptr[x]); + const uint16x4_t mask_vec = vget_low_u16(vmovl_u8(vld1_u8(&mask_row[x]))); + vst1_u16(&row_ptr[x], lv_color_16_16_mix_4_internal(color_vec_4, src, mask_vec)); + } + for(; x < w - 1; x += 2) { + *(uint32_t *)&row_ptr[x] = + lv_color_16_16_mix_2_with_mask((const uint16_t *)&color32, &row_ptr[x], &mask_row[x]); + } + for(; x < w; x++) { + row_ptr[x] = lv_color_16_16_mix(color16, row_ptr[x], mask_row[x]); + } + + dest_buf_u16 = drawbuf_next_row(dest_buf_u16, dest_stride); + mask_buf_u8 += mask_stride; + } + + return LV_RESULT_OK; +} + +lv_result_t lv_draw_sw_blend_neon_color_to_rgb565_with_opa_mask(lv_draw_sw_blend_fill_dsc_t * dsc) +{ + LV_ASSERT(dsc->opa < LV_OPA_MAX); + LV_ASSERT(dsc->mask_buf != NULL); + const int32_t w = dsc->dest_w; + const int32_t h = dsc->dest_h; + const int32_t dest_stride = dsc->dest_stride; + const uint16_t color16 = lv_color_to_u16(dsc->color); + const uint32_t color32 = color16 << 16 | color16; + const uint16x8_t color_vec_8 = vdupq_n_u16(color16); + const uint16x4_t color_vec_4 = vdup_n_u16(color16); + const uint8_t opa = dsc->opa; + const uint16x8_t opa_vec_8 = vmovq_n_u16(opa); + const uint16x4_t opa_vec_4 = vmov_n_u16(opa); + + uint16_t * dest_buf_u16 = dsc->dest_buf; + const uint8_t * mask_buf_u8 = dsc->mask_buf; + const int32_t mask_stride = dsc->mask_stride; + + for(int32_t y = 0; y < h; y++) { + uint16_t * row_ptr = dest_buf_u16; + const uint8_t * mask_row = mask_buf_u8; + int32_t x = 0; + /* Handle unaligned pixels at the beginning */ + const size_t offset = ((size_t)row_ptr) & 0xF; + if(offset != 0) { + int32_t pixel_alignment = (16 - offset) >> 1; + pixel_alignment = (pixel_alignment > w) ? w : pixel_alignment; + for(; x < pixel_alignment; x++) { + row_ptr[x] = lv_color_16_16_mix(color16, row_ptr[x], LV_OPA_MIX2(opa, mask_row[x])); + } + } + for(; x < w - 7; x += 8) { + const uint16x8_t src = vld1q_u16(&row_ptr[x]); + const uint16x8_t mix = vshrq_n_u16(vmulq_u16(opa_vec_8, vmovl_u8(vld1_u8(&mask_row[x]))), 8); + vst1q_u16(&row_ptr[x], lv_color_16_16_mix_8_internal(color_vec_8, src, mix)); + } + for(; x < w - 3; x += 4) { + const uint16x4_t src = vld1_u16(&row_ptr[x]); + const uint16x4_t mix = vshr_n_u16(vmul_u16(opa_vec_4, vget_low_u16(vmovl_u8(vld1_u8(&mask_row[x])))), 8); + vst1_u16(&row_ptr[x], lv_color_16_16_mix_4_internal(color_vec_4, src, mix)); + } + for(; x < w - 1; x += 2) { + *(uint32_t *)&row_ptr[x] = + lv_color_16_16_mix_2_with_opa_mask((const uint16_t *)&color32, &row_ptr[x], opa, &mask_row[x]); + } + for(; x < w; x++) { + row_ptr[x] = lv_color_16_16_mix(color16, row_ptr[x], LV_OPA_MIX2(opa, mask_row[x])); + } + + dest_buf_u16 = drawbuf_next_row(dest_buf_u16, dest_stride); + mask_buf_u8 += mask_stride; + } + + return LV_RESULT_OK; +} + +lv_result_t lv_draw_sw_blend_neon_l8_to_rgb565(lv_draw_sw_blend_image_dsc_t * dsc) +{ + LV_ASSERT(dsc->opa >= LV_OPA_MAX); + LV_ASSERT(dsc->mask_buf == NULL); + int32_t w = dsc->dest_w; + int32_t h = dsc->dest_h; + uint16_t * dest_buf_u16 = dsc->dest_buf; + int32_t dest_stride = dsc->dest_stride; + const uint8_t * src_buf_l8 = dsc->src_buf; + int32_t src_stride = dsc->src_stride; + + for(int32_t y = 0; y < h; y++) { + uint16_t * dest_row = dest_buf_u16; + const uint8_t * src_row = src_buf_l8; + int32_t x = 0; + for(; x < w - 7; x += 8) { + + vst1q_u16(&dest_row[x], l8_to_rgb565_8(&src_row[x])); + } + for(; x < w - 3; x += 4) { + vst1_u16(&dest_row[x], l8_to_rgb565_4(&src_row[x])); + } + for(; x < w - 1; x += 2) { + *(uint32_t *)&dest_row[x] = l8_to_rgb565_2(&src_row[x]); + } + for(; x < w - 0; x += 1) { + dest_row[x] = l8_to_rgb565_1(&src_row[x]); + } + dest_buf_u16 = drawbuf_next_row(dest_buf_u16, dest_stride); + src_buf_l8 += src_stride; + } + return LV_RESULT_OK; +} + +lv_result_t lv_draw_sw_blend_neon_al88_to_rgb565(lv_draw_sw_blend_image_dsc_t * dsc) +{ + LV_ASSERT(dsc->opa >= LV_OPA_MAX); + LV_ASSERT(dsc->mask_buf == NULL); + int32_t w = dsc->dest_w; + int32_t h = dsc->dest_h; + uint16_t * dest_buf_u16 = dsc->dest_buf; + int32_t dest_stride = dsc->dest_stride; + const uint8_t * src_buf_u8 = dsc->src_buf; + int32_t src_stride = dsc->src_stride; + + for(int32_t y = 0; y < h; y++) { + uint16_t * dest_row = dest_buf_u16; + const uint8_t * src_row = (const uint8_t *)src_buf_u8; + int32_t x = 0; + int32_t src_x = 0; + + for(; x < w - 7; x += 8, src_x += 16) { + vst1q_u16(&dest_row[x], lv_color_8_16_mix_8((const uint16_t *)&src_row[src_x], &dest_row[x])); + } + for(; x < w - 3; x += 4, src_x += 8) { + vst1_u16(&dest_row[x], lv_color_8_16_mix_4((const uint16_t *)&src_row[src_x], &dest_row[x])); + } + for(; x < w - 1; x += 2, src_x += 4) { + *(uint32_t *)&dest_row[x] = lv_color_8_16_mix_2(&src_row[src_x], &dest_row[x]); + } + for(; x < w - 0; x += 1, src_x += 2) { + dest_row[x] = lv_color_8_16_mix_1_internal(src_row[src_x], dest_row[x], src_row[src_x + 1]); + } + dest_buf_u16 = drawbuf_next_row(dest_buf_u16, dest_stride); + src_buf_u8 += src_stride; + } + return LV_RESULT_OK; +} +lv_result_t lv_draw_sw_blend_neon_al88_to_rgb565_with_opa(lv_draw_sw_blend_image_dsc_t * dsc) +{ + LV_ASSERT(dsc->opa < LV_OPA_MAX); + LV_ASSERT(dsc->mask_buf == NULL); + const int32_t w = dsc->dest_w; + const int32_t h = dsc->dest_h; + uint16_t * dest_buf_u16 = dsc->dest_buf; + const int32_t dest_stride = dsc->dest_stride; + const uint8_t * src_buf_u8 = dsc->src_buf; + const int32_t src_stride = dsc->src_stride; + const uint8_t opa = dsc->opa; + + for(int32_t y = 0; y < h; y++) { + uint16_t * dest_row = dest_buf_u16; + const uint8_t * src_row = (const uint8_t *)src_buf_u8; + int32_t x = 0; + int32_t src_x = 0; + + for(; x < w - 7; x += 8, src_x += 16) { + vst1q_u16(&dest_row[x], lv_color_8_16_mix_8_with_opa((const uint16_t *)&src_row[src_x], &dest_row[x], opa)); + } + for(; x < w - 3; x += 4, src_x += 8) { + vst1_u16(&dest_row[x], lv_color_8_16_mix_4_with_opa((const uint16_t *)&src_row[src_x], &dest_row[x], opa)); + } + for(; x < w - 1; x += 2, src_x += 4) { + *(uint32_t *)&dest_row[x] = lv_color_8_16_mix_2_with_opa(&src_row[src_x], &dest_row[x], opa); + } + for(; x < w - 0; x += 1, src_x += 2) { + dest_row[x] = + lv_color_8_16_mix_1_internal(src_row[src_x], dest_row[x], LV_OPA_MIX2(src_row[src_x + 1], opa)); + } + dest_buf_u16 = drawbuf_next_row(dest_buf_u16, dest_stride); + src_buf_u8 += src_stride; + } + return LV_RESULT_OK; +} +lv_result_t lv_draw_sw_blend_neon_al88_to_rgb565_with_mask(lv_draw_sw_blend_image_dsc_t * dsc) +{ + LV_ASSERT(dsc->opa >= LV_OPA_MAX); + LV_ASSERT(dsc->mask_buf != NULL); + const int32_t w = dsc->dest_w; + const int32_t h = dsc->dest_h; + uint16_t * dest_buf_u16 = dsc->dest_buf; + const int32_t dest_stride = dsc->dest_stride; + const uint8_t * src_buf_u8 = dsc->src_buf; + const int32_t src_stride = dsc->src_stride; + const uint8_t * mask_buf_u8 = dsc->mask_buf; + const int32_t mask_stride = dsc->mask_stride; + + for(int32_t y = 0; y < h; y++) { + uint16_t * dest_row = dest_buf_u16; + const uint8_t * src_row = (const uint8_t *)src_buf_u8; + const uint8_t * mask_row = (const uint8_t *)mask_buf_u8; + int32_t x = 0; + int32_t src_x = 0; + + for(; x < w - 7; x += 8, src_x += 16) { + vst1q_u16(&dest_row[x], + lv_color_8_16_mix_8_with_mask((const uint16_t *)&src_row[src_x], &dest_row[x], &mask_row[x])); + } + for(; x < w - 3; x += 4, src_x += 8) { + vst1_u16(&dest_row[x], + lv_color_8_16_mix_4_with_mask((const uint16_t *)&src_row[src_x], &dest_row[x], &mask_row[x])); + } + for(; x < w - 1; x += 2, src_x += 4) { + *(uint32_t *)&dest_row[x] = lv_color_8_16_mix_2_with_mask(&src_row[src_x], &dest_row[x], &mask_row[x]); + } + for(; x < w - 0; x += 1, src_x += 2) { + dest_row[x] = + lv_color_8_16_mix_1_internal(src_row[src_x], dest_row[x], LV_OPA_MIX2(src_row[src_x + 1], mask_row[x])); + } + dest_buf_u16 = drawbuf_next_row(dest_buf_u16, dest_stride); + src_buf_u8 += src_stride; + mask_buf_u8 += mask_stride; + } + return LV_RESULT_OK; +} +lv_result_t lv_draw_sw_blend_neon_al88_to_rgb565_with_opa_mask(lv_draw_sw_blend_image_dsc_t * dsc) +{ + LV_ASSERT(dsc->opa < LV_OPA_MAX); + LV_ASSERT(dsc->mask_buf != NULL); + const int32_t w = dsc->dest_w; + const int32_t h = dsc->dest_h; + uint16_t * dest_buf_u16 = dsc->dest_buf; + const int32_t dest_stride = dsc->dest_stride; + const uint8_t * src_buf_u8 = dsc->src_buf; + const int32_t src_stride = dsc->src_stride; + const uint8_t * mask_buf_u8 = dsc->mask_buf; + const int32_t mask_stride = dsc->mask_stride; + const uint8_t opa = dsc->opa; + + for(int32_t y = 0; y < h; y++) { + uint16_t * dest_row = dest_buf_u16; + const uint8_t * src_row = (const uint8_t *)src_buf_u8; + const uint8_t * mask_row = (const uint8_t *)mask_buf_u8; + int32_t x = 0; + int32_t src_x = 0; + + for(; x < w - 7; x += 8, src_x += 16) { + vst1q_u16(&dest_row[x], lv_color_8_16_mix_8_with_opa_mask((const uint16_t *)&src_row[src_x], &dest_row[x], + opa, &mask_row[x])); + } + for(; x < w - 3; x += 4, src_x += 8) { + vst1_u16(&dest_row[x], lv_color_8_16_mix_4_with_opa_mask((const uint16_t *)&src_row[src_x], &dest_row[x], + opa, &mask_row[x])); + } + for(; x < w - 1; x += 2, src_x += 4) { + *(uint32_t *)&dest_row[x] = + lv_color_8_16_mix_2_with_opa_mask(&src_row[src_x], &dest_row[x], opa, &mask_row[x]); + } + for(; x < w - 0; x += 1, src_x += 2) { + dest_row[x] = lv_color_8_16_mix_1_internal(src_row[src_x], dest_row[x], + LV_OPA_MIX3(src_row[src_x + 1], mask_row[x], opa)); + } + dest_buf_u16 = drawbuf_next_row(dest_buf_u16, dest_stride); + src_buf_u8 += src_stride; + mask_buf_u8 += mask_stride; + } + return LV_RESULT_OK; +} + +lv_result_t lv_draw_sw_blend_neon_rgb565_to_rgb565(lv_draw_sw_blend_image_dsc_t * dsc) +{ + + LV_ASSERT(dsc->opa >= LV_OPA_MAX); + LV_ASSERT(dsc->mask_buf == NULL); + int32_t w = dsc->dest_w; + int32_t h = dsc->dest_h; + uint16_t * dest_buf_u16 = dsc->dest_buf; + int32_t dest_stride = dsc->dest_stride; + const uint16_t * src_buf_u16 = dsc->src_buf; + int32_t src_stride = dsc->src_stride; + + for(int32_t y = 0; y < h; y++) { + uint16_t * dest_row = dest_buf_u16; + const uint16_t * src_row = (const uint16_t *)src_buf_u16; + int32_t x = 0; + + for(; x < w - 7; x += 8) { + vst1q_u16(&dest_row[x], vld1q_u16(&src_row[x])); + } + for(; x < w - 3; x += 4) { + vst1_u16(&dest_row[x], vld1_u16(&src_row[x])); + } + for(; x < w - 1; x += 2) { + *(uint32_t *)&dest_row[x] = *(uint32_t *)&src_row[x]; + } + for(; x < w - 0; x += 1) { + dest_row[x] = src_row[x]; + } + dest_buf_u16 = drawbuf_next_row(dest_buf_u16, dest_stride); + src_buf_u16 = drawbuf_next_row(src_buf_u16, src_stride); + } + return LV_RESULT_OK; +} +lv_result_t lv_draw_sw_blend_neon_rgb565_to_rgb565_with_opa(lv_draw_sw_blend_image_dsc_t * dsc) +{ + + LV_ASSERT(dsc->opa < LV_OPA_MAX); + LV_ASSERT(dsc->mask_buf == NULL); + const int32_t w = dsc->dest_w; + const int32_t h = dsc->dest_h; + uint16_t * dest_buf_u16 = dsc->dest_buf; + const int32_t dest_stride = dsc->dest_stride; + const uint16_t * src_buf_u16 = dsc->src_buf; + const int32_t src_stride = dsc->src_stride; + const uint8_t opa = dsc->opa; + + for(int32_t y = 0; y < h; y++) { + uint16_t * dest_row = dest_buf_u16; + const uint16_t * src_row = (const uint16_t *)src_buf_u16; + int32_t x = 0; + + for(; x < w - 7; x += 8) { + vst1q_u16(&dest_row[x], lv_color_16_16_mix_8_with_opa(&src_row[x], &dest_row[x], opa)); + } + for(; x < w - 3; x += 4) { + vst1_u16(&dest_row[x], lv_color_16_16_mix_4_with_opa(&src_row[x], &dest_row[x], opa)); + } + for(; x < w - 1; x += 2) { + *(uint32_t *)&dest_row[x] = lv_color_16_16_mix_2_with_opa(&src_row[x], &dest_row[x], opa); + } + for(; x < w - 0; x += 1) { + dest_row[x] = lv_color_16_16_mix(src_row[x], dest_row[x], opa); + } + dest_buf_u16 = drawbuf_next_row(dest_buf_u16, dest_stride); + src_buf_u16 = drawbuf_next_row(src_buf_u16, src_stride); + } + return LV_RESULT_OK; +} +lv_result_t lv_draw_sw_blend_neon_rgb565_to_rgb565_with_mask(lv_draw_sw_blend_image_dsc_t * dsc) +{ + LV_ASSERT(dsc->opa >= LV_OPA_MAX); + LV_ASSERT(dsc->mask_buf != NULL); + const int32_t w = dsc->dest_w; + const int32_t h = dsc->dest_h; + uint16_t * dest_buf_u16 = dsc->dest_buf; + const int32_t dest_stride = dsc->dest_stride; + const uint16_t * src_buf_u16 = dsc->src_buf; + const int32_t src_stride = dsc->src_stride; + const uint8_t * mask_buf_u8 = dsc->mask_buf; + const int32_t mask_stride = dsc->mask_stride; + + for(int32_t y = 0; y < h; y++) { + uint16_t * dest_row = dest_buf_u16; + const uint8_t * mask_row = mask_buf_u8; + const uint16_t * src_row = (const uint16_t *)src_buf_u16; + int32_t x = 0; + + for(; x < w - 7; x += 8) { + vst1q_u16(&dest_row[x], lv_color_16_16_mix_8_with_mask(&src_row[x], &dest_row[x], &mask_row[x])); + } + for(; x < w - 3; x += 4) { + vst1_u16(&dest_row[x], lv_color_16_16_mix_4_with_mask(&src_row[x], &dest_row[x], &mask_row[x])); + } + for(; x < w - 1; x += 2) { + *(uint32_t *)&dest_row[x] = lv_color_16_16_mix_2_with_mask(&src_row[x], &dest_row[x], &mask_row[x]); + } + for(; x < w - 0; x += 1) { + dest_row[x] = lv_color_16_16_mix(src_row[x], dest_row[x], mask_row[x]); + } + dest_buf_u16 = drawbuf_next_row(dest_buf_u16, dest_stride); + src_buf_u16 = drawbuf_next_row(src_buf_u16, src_stride); + mask_buf_u8 += mask_stride; + } + return LV_RESULT_OK; +} +lv_result_t lv_draw_sw_blend_neon_rgb565_to_rgb565_with_opa_mask(lv_draw_sw_blend_image_dsc_t * dsc) +{ + LV_ASSERT(dsc->opa < LV_OPA_MAX); + LV_ASSERT(dsc->mask_buf != NULL); + const int32_t w = dsc->dest_w; + const int32_t h = dsc->dest_h; + uint16_t * dest_buf_u16 = dsc->dest_buf; + const int32_t dest_stride = dsc->dest_stride; + const uint16_t * src_buf_u16 = dsc->src_buf; + const int32_t src_stride = dsc->src_stride; + const uint8_t * mask_buf_u8 = dsc->mask_buf; + const uint8_t opa = dsc->opa; + const int32_t mask_stride = dsc->mask_stride; + + for(int32_t y = 0; y < h; y++) { + uint16_t * dest_row = dest_buf_u16; + const uint8_t * mask_row = mask_buf_u8; + const uint16_t * src_row = (const uint16_t *)src_buf_u16; + int32_t x = 0; + + for(; x < w - 7; x += 8) { + vst1q_u16(&dest_row[x], lv_color_16_16_mix_8_with_opa_mask(&src_row[x], &dest_row[x], opa, &mask_row[x])); + } + for(; x < w - 3; x += 4) { + vst1_u16(&dest_row[x], lv_color_16_16_mix_4_with_opa_mask(&src_row[x], &dest_row[x], opa, &mask_row[x])); + } + for(; x < w - 1; x += 2) { + *(uint32_t *)&dest_row[x] = + lv_color_16_16_mix_2_with_opa_mask(&src_row[x], &dest_row[x], opa, &mask_row[x]); + } + for(; x < w - 0; x += 1) { + dest_row[x] = lv_color_16_16_mix(src_row[x], dest_row[x], LV_OPA_MIX2(mask_row[x], opa)); + } + dest_buf_u16 = drawbuf_next_row(dest_buf_u16, dest_stride); + src_buf_u16 = drawbuf_next_row(src_buf_u16, src_stride); + mask_buf_u8 += mask_stride; + } + return LV_RESULT_OK; +} +lv_result_t lv_draw_sw_blend_neon_rgb888_to_rgb565(lv_draw_sw_blend_image_dsc_t * dsc, uint8_t src_px_size) +{ + + LV_ASSERT(dsc->opa >= LV_OPA_MAX); + LV_ASSERT(dsc->mask_buf == NULL); + int32_t w = dsc->dest_w; + int32_t h = dsc->dest_h; + uint16_t * dest_buf_u16 = dsc->dest_buf; + int32_t dest_stride = dsc->dest_stride; + const uint8_t * src_buf_u8 = dsc->src_buf; + int32_t src_stride = dsc->src_stride; + + for(int32_t y = 0; y < h; y++) { + uint16_t * dest_row = dest_buf_u16; + const uint8_t * src_row = (const uint8_t *)src_buf_u8; + int32_t x = 0; + int32_t src_x = 0; + for(; x < w - 7; x += 8, src_x += src_px_size * 8) { + vst1q_u16(&dest_row[x], rgb888_to_rgb565_8(&src_row[src_x], src_px_size)); + } + for(; x < w - 3; x += 4, src_x += src_px_size * 4) { + vst1_u16(&dest_row[x], rgb888_to_rgb565_4(&src_row[src_x], src_px_size)); + } + for(; x < w - 1; x += 2, src_x += src_px_size * 2) { + *(uint32_t *)&dest_row[x] = rgb888_to_rgb565_2(&src_row[src_x], src_px_size); + } + for(; x < w - 0; x += 1, src_x += src_px_size * 1) { + dest_row[x] = rgb888_to_rgb565_1(&src_row[src_x]); + } + dest_buf_u16 = drawbuf_next_row(dest_buf_u16, dest_stride); + src_buf_u8 += src_stride; + } + + return LV_RESULT_OK; +} + +lv_result_t lv_draw_sw_blend_neon_rgb888_to_rgb565_with_opa(lv_draw_sw_blend_image_dsc_t * dsc, uint8_t src_px_size) +{ + LV_ASSERT(dsc->opa < LV_OPA_MAX); + LV_ASSERT(dsc->mask_buf == NULL); + const int32_t w = dsc->dest_w; + const int32_t h = dsc->dest_h; + uint16_t * dest_buf_u16 = dsc->dest_buf; + const int32_t dest_stride = dsc->dest_stride; + const uint8_t * src_buf_u8 = dsc->src_buf; + const int32_t src_stride = dsc->src_stride; + const uint8_t opa = dsc->opa; + + for(int32_t y = 0; y < h; y++) { + uint16_t * dest_row = dest_buf_u16; + const uint8_t * src_row = (const uint8_t *)src_buf_u8; + int32_t x = 0; + int32_t src_x = 0; + + for(; x < w - 7; x += 8, src_x += src_px_size * 8) { + vst1q_u16(&dest_row[x], lv_color_24_16_mix_8_with_opa(&src_row[src_x], &dest_row[x], opa, src_px_size)); + } + for(; x < w - 3; x += 4, src_x += src_px_size * 4) { + vst1_u16(&dest_row[x], lv_color_24_16_mix_4_with_opa(&src_row[src_x], &dest_row[x], opa, src_px_size)); + } + for(; x < w - 1; x += 2, src_x += src_px_size * 2) { + *(uint32_t *)&dest_row[x] = lv_color_24_16_mix_2_with_opa(&src_row[src_x], &dest_row[x], opa, src_px_size); + } + for(; x < w - 0; x += 1, src_x += src_px_size * 1) { + dest_row[x] = lv_color_24_16_mix_1_internal(&src_row[src_x], &dest_row[x], opa); + } + dest_buf_u16 = drawbuf_next_row(dest_buf_u16, dest_stride); + src_buf_u8 += src_stride; + } + + return LV_RESULT_OK; +} +lv_result_t lv_draw_sw_blend_neon_rgb888_to_rgb565_with_mask(lv_draw_sw_blend_image_dsc_t * dsc, uint8_t src_px_size) +{ + LV_ASSERT(dsc->opa >= LV_OPA_MAX); + LV_ASSERT(dsc->mask_buf != NULL); + const int32_t w = dsc->dest_w; + const int32_t h = dsc->dest_h; + uint16_t * dest_buf_u16 = dsc->dest_buf; + const int32_t dest_stride = dsc->dest_stride; + const uint8_t * src_buf_u8 = dsc->src_buf; + const int32_t src_stride = dsc->src_stride; + const uint8_t * mask_buf_u8 = dsc->mask_buf; + const int32_t mask_stride = dsc->mask_stride; + + for(int32_t y = 0; y < h; y++) { + uint16_t * dest_row = dest_buf_u16; + const uint8_t * mask_row = mask_buf_u8; + const uint8_t * src_row = src_buf_u8; + int32_t x = 0; + int32_t src_x = 0; + + for(; x < w - 7; x += 8, src_x += src_px_size * 8) { + vst1q_u16(&dest_row[x], + lv_color_24_16_mix_8_with_mask(&src_row[src_x], &dest_row[x], &mask_row[x], src_px_size)); + } + for(; x < w - 3; x += 4, src_x += src_px_size * 4) { + vst1_u16(&dest_row[x], + lv_color_24_16_mix_4_with_mask(&src_row[src_x], &dest_row[x], &mask_row[x], src_px_size)); + } + for(; x < w - 1; x += 2, src_x += src_px_size * 2) { + *(uint32_t *)&dest_row[x] = + lv_color_24_16_mix_2_with_mask(&src_row[src_x], &dest_row[x], &mask_row[x], src_px_size); + } + for(; x < w - 0; x += 1, src_x += src_px_size * 1) { + dest_row[x] = lv_color_24_16_mix_1_internal(&src_row[src_x], &dest_row[x], mask_row[x]); + } + dest_buf_u16 = drawbuf_next_row(dest_buf_u16, dest_stride); + src_buf_u8 += src_stride; + mask_buf_u8 += mask_stride; + } + + return LV_RESULT_OK; +} +lv_result_t lv_draw_sw_blend_neon_rgb888_to_rgb565_with_opa_mask(lv_draw_sw_blend_image_dsc_t * dsc, + uint8_t src_px_size) +{ + LV_ASSERT(dsc->opa < LV_OPA_MAX); + LV_ASSERT(dsc->mask_buf != NULL); + const int32_t w = dsc->dest_w; + const int32_t h = dsc->dest_h; + uint16_t * dest_buf_u16 = dsc->dest_buf; + const int32_t dest_stride = dsc->dest_stride; + const uint8_t * src_buf_u8 = dsc->src_buf; + const int32_t src_stride = dsc->src_stride; + const uint8_t * mask_buf_u8 = dsc->mask_buf; + const int32_t mask_stride = dsc->mask_stride; + const uint8_t opa = dsc->opa; + + for(int32_t y = 0; y < h; y++) { + uint16_t * dest_row = dest_buf_u16; + const uint8_t * mask_row = mask_buf_u8; + const uint8_t * src_row = src_buf_u8; + int32_t x = 0; + int32_t src_x = 0; + + for(; x < w - 7; x += 8, src_x += src_px_size * 8) { + vst1q_u16(&dest_row[x], lv_color_24_16_mix_8_with_opa_mask(&src_row[src_x], &dest_row[x], opa, &mask_row[x], + src_px_size)); + } + for(; x < w - 3; x += 4, src_x += src_px_size * 4) { + vst1_u16(&dest_row[x], + lv_color_24_16_mix_4_with_opa_mask(&src_row[src_x], &dest_row[x], opa, &mask_row[x], src_px_size)); + } + for(; x < w - 1; x += 2, src_x += src_px_size * 2) { + *(uint32_t *)&dest_row[x] = + lv_color_24_16_mix_2_with_opa_mask(&src_row[src_x], &dest_row[x], opa, &mask_row[x], src_px_size); + } + for(; x < w - 0; x += 1, src_x += src_px_size * 1) { + dest_row[x] = lv_color_24_16_mix_1_internal(&src_row[src_x], &dest_row[x], LV_OPA_MIX2(mask_row[x], opa)); + } + dest_buf_u16 = drawbuf_next_row(dest_buf_u16, dest_stride); + src_buf_u8 += src_stride; + mask_buf_u8 += mask_stride; + } + + return LV_RESULT_OK; +} +lv_result_t lv_draw_sw_blend_neon_argb888_to_rgb565(lv_draw_sw_blend_image_dsc_t * dsc) +{ + LV_ASSERT(dsc->opa >= LV_OPA_MAX); + LV_ASSERT(dsc->mask_buf == NULL); + int32_t w = dsc->dest_w; + int32_t h = dsc->dest_h; + uint16_t * dest_buf_u16 = dsc->dest_buf; + int32_t dest_stride = dsc->dest_stride; + const uint8_t * src_buf_u8 = dsc->src_buf; + int32_t src_stride = dsc->src_stride; + + for(int32_t y = 0; y < h; y++) { + uint16_t * dest_row = dest_buf_u16; + const uint8_t * src_row = (const uint8_t *)src_buf_u8; + int32_t x = 0; + int32_t src_x = 0; + + for(; x < w - 7; x += 8, src_x += 32) { + vst1q_u16(&dest_row[x], lv_color_32_16_mix_8(&src_row[src_x], &dest_row[x])); + } + for(; x < w - 3; x += 4, src_x += 16) { + vst1_u16(&dest_row[x], lv_color_32_16_mix_4(&src_row[src_x], &dest_row[x])); + } + for(; x < w - 1; x += 2, src_x += 8) { + *(uint32_t *)&dest_row[x] = lv_color_32_16_mix_2(&src_row[src_x], &dest_row[x]); + } + for(; x < w - 0; x += 1, src_x += 4) { + dest_row[x] = lv_color_32_16_mix_1(&src_row[src_x], &dest_row[x]); + } + dest_buf_u16 = drawbuf_next_row(dest_buf_u16, dest_stride); + src_buf_u8 += src_stride; + } + return LV_RESULT_OK; +} + +lv_result_t lv_draw_sw_blend_neon_argb888_to_rgb565_with_opa(lv_draw_sw_blend_image_dsc_t * dsc) +{ + LV_ASSERT(dsc->opa < LV_OPA_MAX); + LV_ASSERT(dsc->mask_buf == NULL); + const int32_t w = dsc->dest_w; + const int32_t h = dsc->dest_h; + uint16_t * dest_buf_u16 = dsc->dest_buf; + const int32_t dest_stride = dsc->dest_stride; + const uint8_t * src_buf_u8 = dsc->src_buf; + const int32_t src_stride = dsc->src_stride; + const uint8_t opa = dsc->opa; + + for(int32_t y = 0; y < h; y++) { + uint16_t * dest_row = dest_buf_u16; + const uint8_t * src_row = (const uint8_t *)src_buf_u8; + int32_t x = 0; + int32_t src_x = 0; + + for(; x < w - 7; x += 8, src_x += 32) { + vst1q_u16(&dest_row[x], lv_color_32_16_mix_8_with_opa(&src_row[src_x], &dest_row[x], opa)); + } + for(; x < w - 3; x += 4, src_x += 16) { + vst1_u16(&dest_row[x], lv_color_32_16_mix_4_with_opa(&src_row[src_x], &dest_row[x], opa)); + } + for(; x < w - 1; x += 2, src_x += 8) { + *(uint32_t *)&dest_row[x] = lv_color_32_16_mix_2_with_opa(&src_row[src_x], &dest_row[x], opa); + } + for(; x < w - 0; x += 1, src_x += 4) { + dest_row[x] = lv_color_32_16_mix_1_with_opa(&src_row[src_x], &dest_row[x], opa); + } + dest_buf_u16 = drawbuf_next_row(dest_buf_u16, dest_stride); + src_buf_u8 += src_stride; + } + return LV_RESULT_OK; +} +lv_result_t lv_draw_sw_blend_neon_argb888_to_rgb565_with_mask(lv_draw_sw_blend_image_dsc_t * dsc) +{ + LV_ASSERT(dsc->opa >= LV_OPA_MAX); + LV_ASSERT(dsc->mask_buf != NULL); + const int32_t w = dsc->dest_w; + const int32_t h = dsc->dest_h; + uint16_t * dest_buf_u16 = dsc->dest_buf; + const int32_t dest_stride = dsc->dest_stride; + const uint8_t * src_buf_u8 = dsc->src_buf; + const int32_t src_stride = dsc->src_stride; + const uint8_t * mask_buf_u8 = dsc->mask_buf; + const int32_t mask_stride = dsc->mask_stride; + + for(int32_t y = 0; y < h; y++) { + uint16_t * dest_row = dest_buf_u16; + const uint8_t * mask_row = mask_buf_u8; + const uint8_t * src_row = (const uint8_t *)src_buf_u8; + int32_t x = 0; + int32_t src_x = 0; + + for(; x < w - 7; x += 8, src_x += 32) { + vst1q_u16(&dest_row[x], lv_color_32_16_mix_8_with_mask(&src_row[src_x], &dest_row[x], &mask_row[x])); + } + for(; x < w - 3; x += 4, src_x += 16) { + vst1_u16(&dest_row[x], lv_color_32_16_mix_4_with_mask(&src_row[src_x], &dest_row[x], &mask_row[x])); + } + for(; x < w - 1; x += 2, src_x += 8) { + *(uint32_t *)&dest_row[x] = lv_color_32_16_mix_2_with_mask(&src_row[src_x], &dest_row[x], &mask_row[x]); + } + for(; x < w - 0; x += 1, src_x += 4) { + dest_row[x] = lv_color_32_16_mix_1_with_mask(&src_row[src_x], &dest_row[x], &mask_row[x]); + } + dest_buf_u16 = drawbuf_next_row(dest_buf_u16, dest_stride); + src_buf_u8 += src_stride; + mask_buf_u8 += mask_stride; + } + return LV_RESULT_OK; +} +lv_result_t lv_draw_sw_blend_neon_argb888_to_rgb565_with_opa_mask(lv_draw_sw_blend_image_dsc_t * dsc) +{ + LV_ASSERT(dsc->opa < LV_OPA_MAX); + LV_ASSERT(dsc->mask_buf != NULL); + const int32_t w = dsc->dest_w; + const int32_t h = dsc->dest_h; + uint16_t * dest_buf_u16 = dsc->dest_buf; + const int32_t dest_stride = dsc->dest_stride; + const uint8_t * src_buf_u8 = dsc->src_buf; + const int32_t src_stride = dsc->src_stride; + const uint8_t opa = dsc->opa; + const uint8_t * mask_buf_u8 = dsc->mask_buf; + const int32_t mask_stride = dsc->mask_stride; + + for(int32_t y = 0; y < h; y++) { + uint16_t * dest_row = dest_buf_u16; + const uint8_t * mask_row = mask_buf_u8; + const uint8_t * src_row = (const uint8_t *)src_buf_u8; + int32_t x = 0; + int32_t src_x = 0; + + for(; x < w - 7; x += 8, src_x += 32) { + vst1q_u16(&dest_row[x], + lv_color_32_16_mix_8_with_opa_mask(&src_row[src_x], &dest_row[x], opa, &mask_row[x])); + } + for(; x < w - 3; x += 4, src_x += 16) { + vst1_u16(&dest_row[x], + lv_color_32_16_mix_4_with_opa_mask(&src_row[src_x], &dest_row[x], opa, &mask_row[x])); + } + for(; x < w - 1; x += 2, src_x += 8) { + *(uint32_t *)&dest_row[x] = + lv_color_32_16_mix_2_with_opa_mask(&src_row[src_x], &dest_row[x], opa, &mask_row[x]); + } + + for(; x < w - 0; x += 1, src_x += 4) { + dest_row[x] = lv_color_32_16_mix_1_with_opa_mask(&src_row[src_x], &dest_row[x], opa, &mask_row[x]); + } + dest_buf_u16 = drawbuf_next_row(dest_buf_u16, dest_stride); + src_buf_u8 += src_stride; + mask_buf_u8 += mask_stride; + } + return LV_RESULT_OK; +} + +#if LV_DRAW_SW_SUPPORT_ARGB8888_PREMULTIPLIED +lv_result_t lv_draw_sw_blend_neon_argb888_premultiplied_to_rgb565(lv_draw_sw_blend_image_dsc_t * dsc) +{ + LV_ASSERT(dsc->opa >= LV_OPA_MAX); + LV_ASSERT(dsc->mask_buf == NULL); + int32_t w = dsc->dest_w; + int32_t h = dsc->dest_h; + uint16_t * dest_buf_u16 = dsc->dest_buf; + int32_t dest_stride = dsc->dest_stride; + const uint8_t * src_buf_u8 = dsc->src_buf; + int32_t src_stride = dsc->src_stride; + + for(int32_t y = 0; y < h; y++) { + uint16_t * dest_row = dest_buf_u16; + const uint8_t * src_row = (const uint8_t *)src_buf_u8; + int32_t x = 0; + int32_t src_x = 0; + + for(; x < w - 7; x += 8, src_x += 32) { + vst1q_u16(&dest_row[x], lv_color_24_16_mix_premult_8(&src_row[src_x], &dest_row[x])); + } + for(; x < w - 3; x += 4, src_x += 16) { + vst1_u16(&dest_row[x], lv_color_24_16_mix_premult_4(&src_row[src_x], &dest_row[x])); + } + for(; x < w - 1; x += 2, src_x += 8) { + *(uint32_t *)&dest_row[x] = lv_color_24_16_mix_premult_2(&src_row[src_x], &dest_row[x]); + } + for(; x < w - 0; x += 1, src_x += 4) { + dest_row[x] = lv_color_24_16_mix_premult_1(&src_row[src_x], &dest_row[x]); + } + dest_buf_u16 = drawbuf_next_row(dest_buf_u16, dest_stride); + src_buf_u8 += src_stride; + } + return LV_RESULT_OK; +} +#endif + +/********************** + * STATIC FUNCTIONS + **********************/ + +static inline uint16x8_t l8_to_rgb565_8(const uint8_t * src) +{ + uint16x8_t pixels = vmovl_u8(vld1_u8(src)); + uint16x8_t r = vshlq_n_u16(vandq_u16(pixels, vdupq_n_u16(0xF8)), 8); + uint16x8_t g = vshlq_n_u16(vandq_u16(pixels, vdupq_n_u16(0xFC)), 3); + uint16x8_t b = vshrq_n_u16(vandq_u16(pixels, vdupq_n_u16(0xF8)), 3); + return vorrq_u16(vorrq_u16(r, g), b); +} + +static inline uint16x4_t l8_to_rgb565_4(const uint8_t * src) +{ + const uint8_t tmp[8] = {src[0], src[1], src[2], src[3]}; + const uint16x8_t p = vmovl_u8(vld1_u8(tmp)); + const uint16x4_t pixels = vget_low_u16(p); + + const uint16x4_t r = vshl_n_u16(vand_u16(pixels, vdup_n_u16(0xF8)), 8); + const uint16x4_t g = vshl_n_u16(vand_u16(pixels, vdup_n_u16(0xFC)), 3); + const uint16x4_t b = vshr_n_u16(vand_u16(pixels, vdup_n_u16(0xF8)), 3); + return vorr_u16(vorr_u16(r, g), b); +} + +static inline uint32_t l8_to_rgb565_2(const uint8_t * src) +{ + return ((uint32_t)l8_to_rgb565_1(src + 1) << 16) | l8_to_rgb565_1(src); +} +static inline uint16_t l8_to_rgb565_1(const uint8_t * src) +{ + return ((src[0] & 0xF8) << 8) + ((src[0] & 0xFC) << 3) + ((src[0] & 0xF8) >> 3); +} + +static inline uint16x8_t lv_color_8_16_mix_8(const uint16_t * src, const uint16_t * dst) +{ + const uint16x8_t src_mix_pixels = vld1q_u16(src); + const uint16x8_t dst_pixels = vld1q_u16(dst); + const uint16x8_t src_pixels = vandq_u16(src_mix_pixels, vdupq_n_u16(0xFF)); + const uint16x8_t mix_pixels = vshrq_n_u16(src_mix_pixels, 8); + + return lv_color_8_16_mix_8_internal(src_pixels, dst_pixels, mix_pixels); +} + +static inline uint16x8_t lv_color_8_16_mix_8_with_opa(const uint16_t * src, const uint16_t * dst, uint8_t opa) +{ + const uint16x8_t src_mix_pixels = vld1q_u16(src); + const uint16x8_t dst_pixels = vld1q_u16(dst); + const uint16x8_t src_pixels = vandq_u16(src_mix_pixels, vdupq_n_u16(0xFF)); + const uint16x8_t mix_pixels = vshrq_n_u16(src_mix_pixels, 8); + const uint16x8_t opa_vec = vmovq_n_u16(opa); + const uint16x8_t mix_vec = vshrq_n_u16(vmulq_u16(opa_vec, mix_pixels), 8); + return lv_color_8_16_mix_8_internal(src_pixels, dst_pixels, mix_vec); +} + +static inline uint16x4_t lv_color_8_16_mix_4_with_opa(const uint16_t * src, const uint16_t * dst, uint8_t opa) +{ + const uint16x4_t src_mix_pixels = vld1_u16(src); + const uint16x4_t dst_pixels = vld1_u16(dst); + const uint16x4_t src_pixels = vand_u16(src_mix_pixels, vdup_n_u16(0xFF)); + const uint16x4_t mix_pixels = vshr_n_u16(src_mix_pixels, 8); + const uint16x4_t opa_vec = vmov_n_u16(opa); + const uint16x4_t mix_vec = vshr_n_u16(vmul_u16(opa_vec, mix_pixels), 8); + return lv_color_8_16_mix_4_internal(src_pixels, dst_pixels, mix_vec); +} +static inline uint16x8_t lv_color_8_16_mix_8_with_mask(const uint16_t * src, const uint16_t * dst, const uint8_t * mask) +{ + const uint16x8_t src_mix_pixels = vld1q_u16(src); + const uint16x8_t dst_pixels = vld1q_u16(dst); + const uint16x8_t src_pixels = vandq_u16(src_mix_pixels, vdupq_n_u16(0xFF)); + const uint16x8_t mix_pixels = vshrq_n_u16(src_mix_pixels, 8); + const uint16x8_t mask_vec = vmovl_u8(vld1_u8(mask)); + const uint16x8_t mix_vec = vshrq_n_u16(vmulq_u16(mask_vec, mix_pixels), 8); + return lv_color_8_16_mix_8_internal(src_pixels, dst_pixels, mix_vec); +} + +static inline uint16x4_t lv_color_8_16_mix_4_with_mask(const uint16_t * src, const uint16_t * dst, const uint8_t * mask) +{ + const uint16x4_t src_mix_pixels = vld1_u16(src); + const uint16x4_t dst_pixels = vld1_u16(dst); + const uint16x4_t src_pixels = vand_u16(src_mix_pixels, vdup_n_u16(0xFF)); + const uint16x4_t mix_pixels = vshr_n_u16(src_mix_pixels, 8); + const uint16x4_t mask_vec = vget_low_u16(vmovl_u8(vld1_u8(mask))); + const uint16x4_t mix_vec = vshr_n_u16(vmul_u16(mask_vec, mix_pixels), 8); + return lv_color_8_16_mix_4_internal(src_pixels, dst_pixels, mix_vec); +} +static inline uint16x8_t lv_color_8_16_mix_8_with_opa_mask(const uint16_t * src, const uint16_t * dst, uint8_t opa, + const uint8_t * mask) +{ + const uint16x8_t src_mix_pixels = vld1q_u16(src); + const uint16x8_t dst_pixels = vld1q_u16(dst); + const uint16x8_t src_pixels = vandq_u16(src_mix_pixels, vdupq_n_u16(0xFF)); + const uint16x8_t mix_pixels = vshrq_n_u16(src_mix_pixels, 8); + const uint16x8_t mask_vec = vmovl_u8(vld1_u8(mask)); + const uint16x8_t opa_vec = vmovq_n_u16(opa); + + /* Use uint32 for intermediate multiplication results to avoid 16bit overflows */ + const uint32x4_t mix_pixels_low = vmovl_u16(vget_low_u16(mix_pixels)); + const uint32x4_t mix_pixels_high = vmovl_u16(vget_high_u16(mix_pixels)); + const uint32x4_t opa_vec_low = vmovl_u16(vget_low_u16(opa_vec)); + const uint32x4_t opa_vec_high = vmovl_u16(vget_high_u16(opa_vec)); + const uint32x4_t mask_vec_low = vmovl_u16(vget_low_u16(mask_vec)); + const uint32x4_t mask_vec_high = vmovl_u16(vget_high_u16(mask_vec)); + + const uint32x4_t mul_low = vshrq_n_u32(vmulq_u32(vmulq_u32(mix_pixels_low, opa_vec_low), mask_vec_low), 16); + const uint32x4_t mul_high = vshrq_n_u32(vmulq_u32(vmulq_u32(mix_pixels_high, opa_vec_high), mask_vec_high), 16); + const uint16x8_t mix_vec = vcombine_u16(vmovn_u32(mul_low), vmovn_u32(mul_high)); + return lv_color_8_16_mix_8_internal(src_pixels, dst_pixels, mix_vec); +} + +static inline uint16x4_t lv_color_8_16_mix_4_with_opa_mask(const uint16_t * src, const uint16_t * dst, uint8_t opa, + const uint8_t * mask) +{ + + const uint16x4_t src_mix_pixels = vld1_u16(src); + const uint16x4_t dst_pixels = vld1_u16(dst); + const uint16x4_t src_pixels = vand_u16(src_mix_pixels, vdup_n_u16(0xFF)); + const uint16x4_t mix_pixels = vshr_n_u16(src_mix_pixels, 8); + const uint16x4_t opa_vec = vmov_n_u16(opa); + const uint16x4_t mask_vec = vget_low_u16(vmovl_u8(vld1_u8(mask))); + const uint32x4_t a_pixels_low = vmovl_u16(mix_pixels); + const uint32x4_t opa_vec_low = vmovl_u16(opa_vec); + const uint32x4_t mask_vec_low = vmovl_u16(mask_vec); + + const uint32x4_t mul_result = vshrq_n_u32(vmulq_u32(vmulq_u32(a_pixels_low, opa_vec_low), mask_vec_low), 16); + const uint16x4_t mix_vec = vmovn_u32(mul_result); + return lv_color_8_16_mix_4_internal(src_pixels, dst_pixels, mix_vec); +} + +static inline uint16x8_t lv_color_8_16_mix_8_internal(uint16x8_t src_pixels, uint16x8_t dst_pixels, + uint16x8_t mix_pixels) +{ + const uint16x8_t mix_zero_mask = vceqq_u16(mix_pixels, vdupq_n_u16(0)); + const uint16x8_t mix_full_mask = vceqq_u16(mix_pixels, vdupq_n_u16(255)); + /* Prepare result in case mix == 255 */ + const uint16x8_t src_r565 = vshlq_n_u16(vandq_u16(src_pixels, vdupq_n_u16(0xF8)), 8); + const uint16x8_t src_g565 = vshlq_n_u16(vandq_u16(src_pixels, vdupq_n_u16(0xFC)), 3); + const uint16x8_t src_b565 = vshrq_n_u16(vandq_u16(src_pixels, vdupq_n_u16(0xF8)), 3); + const uint16x8_t src_rgb565 = vaddq_u16(vaddq_u16(src_r565, src_g565), src_b565); + + /* Do the actual blending */ + const uint16x8_t mix_inv_16 = vsubq_u16(vdupq_n_u16(255), mix_pixels); + + /* Red: ((c1 >> 3) * mix + ((c2 >> 11) & 0x1F) * mix_inv) << 3) & 0xF800 */ + const uint16x8_t src_r = vmulq_u16(vshrq_n_u16(src_pixels, 3), mix_pixels); + const uint16x8_t dst_r = vandq_u16(vshrq_n_u16(dst_pixels, 11), vdupq_n_u16(0x1F)); + uint16x8_t blended_r = vmlaq_u16(src_r, dst_r, mix_inv_16); + blended_r = vandq_u16(vshlq_n_u16(blended_r, 3), vdupq_n_u16(0xF800)); + + /* Green: ((c1 >> 2) * mix + ((c2 >> 5) & 0x3F) * mix_inv) >> 3) & 0x07E0 */ + const uint16x8_t src_g = vmulq_u16(vshrq_n_u16(src_pixels, 2), mix_pixels); + const uint16x8_t dst_g = vandq_u16(vshrq_n_u16(dst_pixels, 5), vdupq_n_u16(0x3F)); + uint16x8_t blended_g = vmlaq_u16(src_g, dst_g, mix_inv_16); + blended_g = vandq_u16(vshrq_n_u16(blended_g, 3), vdupq_n_u16(0x07E0)); + + /* Blue: ((c1 >> 3) * mix + (c2 & 0x1F) * mix_inv) >> 8 */ + const uint16x8_t src_b = vmulq_u16(vshrq_n_u16(src_pixels, 3), mix_pixels); + const uint16x8_t dst_b = vandq_u16(dst_pixels, vdupq_n_u16(0x1F)); + uint16x8_t blended_b = vmlaq_u16(src_b, dst_b, mix_inv_16); + blended_b = vshrq_n_u16(blended_b, 8); + + /* Select what value to take for each pixel depending on original mix value */ + const uint16x8_t blended_result = vorrq_u16(vorrq_u16(blended_r, blended_g), blended_b); + const uint16x8_t result = vbslq_u16(mix_zero_mask, dst_pixels, blended_result); + return vbslq_u16(mix_full_mask, src_rgb565, result); +} +static inline uint16x4_t lv_color_8_16_mix_4_internal(uint16x4_t src_pixels, uint16x4_t dst_pixels, + uint16x4_t mix_pixels) +{ + + const uint16x4_t mix_zero_mask = vceq_u16(mix_pixels, vdup_n_u16(0)); + const uint16x4_t mix_full_mask = vceq_u16(mix_pixels, vdup_n_u16(255)); + /* Prepare result in case mix == 255 */ + const uint16x4_t src_r565 = vshl_n_u16(vand_u16(src_pixels, vdup_n_u16(0xF8)), 8); + const uint16x4_t src_g565 = vshl_n_u16(vand_u16(src_pixels, vdup_n_u16(0xFC)), 3); + const uint16x4_t src_b565 = vshr_n_u16(vand_u16(src_pixels, vdup_n_u16(0xF8)), 3); + const uint16x4_t src_rgb565 = vadd_u16(vadd_u16(src_r565, src_g565), src_b565); + const uint16x4_t mix_inv_16 = vsub_u16(vdup_n_u16(255), mix_pixels); + + /* Red: ((c1 >> 3) * mix + ((c2 >> 11) & 0x1F) * mix_inv) << 3) & 0xF800 */ + const uint16x4_t src_r = vmul_u16(vshr_n_u16(src_pixels, 3), mix_pixels); + const uint16x4_t dst_r = vand_u16(vshr_n_u16(dst_pixels, 11), vdup_n_u16(0x1F)); + uint16x4_t blended_r = vmla_u16(src_r, dst_r, mix_inv_16); + blended_r = vand_u16(vshl_n_u16(blended_r, 3), vdup_n_u16(0xF800)); + + /* Green: ((c1 >> 2) * mix + ((c2 >> 5) & 0x3F) * mix_inv) >> 3) & 0x07E0 */ + const uint16x4_t src_g = vmul_u16(vshr_n_u16(src_pixels, 2), mix_pixels); + const uint16x4_t dst_g = vand_u16(vshr_n_u16(dst_pixels, 5), vdup_n_u16(0x3F)); + uint16x4_t blended_g = vmla_u16(src_g, dst_g, mix_inv_16); + blended_g = vand_u16(vshr_n_u16(blended_g, 3), vdup_n_u16(0x07E0)); + + /* Blue: ((c1 >> 3) * mix + (c2 & 0x1F) * mix_inv) >> 8 */ + const uint16x4_t src_b = vmul_u16(vshr_n_u16(src_pixels, 3), mix_pixels); + const uint16x4_t dst_b = vand_u16(dst_pixels, vdup_n_u16(0x1F)); + uint16x4_t blended_b = vmla_u16(src_b, dst_b, mix_inv_16); + blended_b = vshr_n_u16(blended_b, 8); + + const uint16x4_t blended_result = vorr_u16(vorr_u16(blended_r, blended_g), blended_b); + const uint16x4_t result = vbsl_u16(mix_zero_mask, dst_pixels, blended_result); + return vbsl_u16(mix_full_mask, src_rgb565, result); +} + +static inline uint16x4_t lv_color_8_16_mix_4(const uint16_t * src, const uint16_t * dst) +{ + const uint16x4_t src_mix_pixels = vld1_u16(src); + const uint16x4_t dst_pixels = vld1_u16(dst); + const uint16x4_t src_pixels = vand_u16(src_mix_pixels, vdup_n_u16(0xFF)); + const uint16x4_t mix_pixels = vshr_n_u16(src_mix_pixels, 8); + return lv_color_8_16_mix_4_internal(src_pixels, dst_pixels, mix_pixels); +} + +static inline uint32_t lv_color_8_16_mix_2(const uint8_t * src, const uint16_t * dst) +{ + return ((uint32_t)lv_color_8_16_mix_1_internal(src[2], dst[1], src[3]) << 16) | + lv_color_8_16_mix_1_internal(src[0], dst[0], src[1]); +} + +static inline uint32_t lv_color_8_16_mix_2_with_opa(const uint8_t * src, const uint16_t * dst, uint8_t opa) +{ + return ((uint32_t)lv_color_8_16_mix_1_internal(src[2], dst[1], LV_OPA_MIX2(src[3], opa)) << 16) | + lv_color_8_16_mix_1_internal(src[0], dst[0], LV_OPA_MIX2(src[1], opa)); +} + +static inline uint32_t lv_color_8_16_mix_2_with_mask(const uint8_t * src, const uint16_t * dst, const uint8_t * mask) +{ + + return ((uint32_t)lv_color_8_16_mix_1_internal(src[2], dst[1], LV_OPA_MIX2(src[3], mask[1])) << 16) | + lv_color_8_16_mix_1_internal(src[0], dst[0], LV_OPA_MIX2(src[1], mask[0])); +} +static inline uint32_t lv_color_8_16_mix_2_with_opa_mask(const uint8_t * src, const uint16_t * dst, uint8_t opa, + const uint8_t * mask) +{ + + return ((uint32_t)lv_color_8_16_mix_1_internal(src[2], dst[1], LV_OPA_MIX3(src[3], mask[1], opa)) << 16) | + lv_color_8_16_mix_1_internal(src[0], dst[0], LV_OPA_MIX3(src[3], mask[0], opa)); +} + +static inline uint16_t lv_color_8_16_mix_1_internal(uint8_t src, uint16_t dst, uint8_t mix) +{ + const uint8_t c1 = src; + const uint16_t c2 = dst; + + if(mix == 0) { + return c2; + } + else if(mix == 255) { + return ((c1 & 0xF8) << 8) + ((c1 & 0xFC) << 3) + ((c1 & 0xF8) >> 3); + } + else { + uint8_t mix_inv = 255 - mix; + return ((((c1 >> 3) * mix + ((c2 >> 11) & 0x1F) * mix_inv) << 3) & 0xF800) + + ((((c1 >> 2) * mix + ((c2 >> 5) & 0x3F) * mix_inv) >> 3) & 0x07E0) + + (((c1 >> 3) * mix + (c2 & 0x1F) * mix_inv) >> 8); + } +} + +static inline uint16x8_t lv_color_32_16_mix_8(const uint8_t * src, const uint16_t * dst) +{ + const uint16x8_t dst_pixels = vld1q_u16(dst); + + const uint8x8x4_t rgba = vld4_u8(src); + const uint16x8_t b_pixels = vmovl_u8(rgba.val[0]); + const uint16x8_t g_pixels = vmovl_u8(rgba.val[1]); + const uint16x8_t r_pixels = vmovl_u8(rgba.val[2]); + const uint16x8_t a_pixels = vmovl_u8(rgba.val[3]); + + return lv_color_32_16_mix_8_internal(r_pixels, g_pixels, b_pixels, a_pixels, dst_pixels); +} +static inline uint16x4_t lv_color_32_16_mix_4(const uint8_t * src, const uint16_t * dst) +{ + const uint16x4_t dst_pixels = vld1_u16(dst); + uint8_t b_array[8] = {src[0], src[4], src[8], src[12], 0, 0, 0, 0}; + uint8_t g_array[8] = {src[1], src[5], src[9], src[13], 0, 0, 0, 0}; + uint8_t r_array[8] = {src[2], src[6], src[10], src[14], 0, 0, 0, 0}; + uint8_t a_array[8] = {src[3], src[7], src[11], src[15], 0, 0, 0, 0}; + const uint16x4_t b_pixels = vget_low_u16(vmovl_u8(vld1_u8(b_array))); + const uint16x4_t g_pixels = vget_low_u16(vmovl_u8(vld1_u8(g_array))); + const uint16x4_t r_pixels = vget_low_u16(vmovl_u8(vld1_u8(r_array))); + const uint16x4_t a_pixels = vget_low_u16(vmovl_u8(vld1_u8(a_array))); + return lv_color_32_16_mix_4_internal(r_pixels, g_pixels, b_pixels, a_pixels, dst_pixels); +} + +static inline uint16x8_t lv_color_24_16_mix_8_with_mask(const uint8_t * src, const uint16_t * dst, const uint8_t * mask, + uint8_t src_px_size) +{ + uint16x8_t b_pixels; + uint16x8_t g_pixels; + uint16x8_t r_pixels; + LV_ASSERT_MSG(src_px_size == 3 || src_px_size == 4, "Invalid pixel size for rgb888. Expected either 3 or 4 bytes"); + + if(src_px_size == 3) { + const uint8x8x3_t rgba = vld3_u8(src); + b_pixels = vmovl_u8(rgba.val[0]); + g_pixels = vmovl_u8(rgba.val[1]); + r_pixels = vmovl_u8(rgba.val[2]); + } + else if(src_px_size == 4) { + const uint8x8x4_t rgba = vld4_u8(src); + b_pixels = vmovl_u8(rgba.val[0]); + g_pixels = vmovl_u8(rgba.val[1]); + r_pixels = vmovl_u8(rgba.val[2]); + } + const uint16x8_t dst_pixels = vld1q_u16(dst); + const uint16x8_t mask_vec = vmovl_u8(vld1_u8(mask)); + + return lv_color_32_16_mix_8_internal(r_pixels, g_pixels, b_pixels, mask_vec, dst_pixels); +} +static inline uint16x4_t lv_color_24_16_mix_4_with_mask(const uint8_t * src, const uint16_t * dst, const uint8_t * mask, + uint8_t src_px_size) +{ + uint16x4_t b_pixels; + uint16x4_t g_pixels; + uint16x4_t r_pixels; + LV_ASSERT_MSG(src_px_size == 3 || src_px_size == 4, "Invalid pixel size for rgb888. Expected either 3 or 4 bytes"); + + if(src_px_size == 3) { + const uint8x8x3_t rgba = vld3_u8(src); + b_pixels = vget_low_u16(vmovl_u8(rgba.val[0])); + g_pixels = vget_low_u16(vmovl_u8(rgba.val[1])); + r_pixels = vget_low_u16(vmovl_u8(rgba.val[2])); + } + else if(src_px_size == 4) { + const uint8x8x4_t rgba = vld4_u8(src); + b_pixels = vget_low_u16(vmovl_u8(rgba.val[0])); + g_pixels = vget_low_u16(vmovl_u8(rgba.val[1])); + r_pixels = vget_low_u16(vmovl_u8(rgba.val[2])); + } + const uint16x4_t dst_pixels = vld1_u16(dst); + const uint16x4_t mask_vec = vget_low_u16(vmovl_u8(vld1_u8(mask))); + + return lv_color_32_16_mix_4_internal(r_pixels, g_pixels, b_pixels, mask_vec, dst_pixels); +} + +static inline uint16x8_t lv_color_24_16_mix_8_with_opa_mask(const uint8_t * src, const uint16_t * dst, uint8_t opa, + const uint8_t * mask, uint8_t src_px_size) +{ + uint16x8_t b_pixels; + uint16x8_t g_pixels; + uint16x8_t r_pixels; + LV_ASSERT_MSG(src_px_size == 3 || src_px_size == 4, "Invalid pixel size for rgb888. Expected either 3 or 4 bytes"); + + if(src_px_size == 3) { + const uint8x8x3_t rgba = vld3_u8(src); + b_pixels = vmovl_u8(rgba.val[0]); + g_pixels = vmovl_u8(rgba.val[1]); + r_pixels = vmovl_u8(rgba.val[2]); + } + else if(src_px_size == 4) { + const uint8x8x4_t rgba = vld4_u8(src); + b_pixels = vmovl_u8(rgba.val[0]); + g_pixels = vmovl_u8(rgba.val[1]); + r_pixels = vmovl_u8(rgba.val[2]); + } + const uint16x8_t dst_pixels = vld1q_u16(dst); + const uint16x8_t mask_vec = vmovl_u8(vld1_u8(mask)); + const uint16x8_t opa_vec = vmovq_n_u16(opa); + const uint16x8_t mix_vec = vshrq_n_u16(vmulq_u16(opa_vec, mask_vec), 8); + + return lv_color_32_16_mix_8_internal(r_pixels, g_pixels, b_pixels, mix_vec, dst_pixels); +} +static inline uint16x4_t lv_color_24_16_mix_4_with_opa_mask(const uint8_t * src, const uint16_t * dst, uint8_t opa, + const uint8_t * mask, uint8_t src_px_size) +{ + uint16x4_t b_pixels; + uint16x4_t g_pixels; + uint16x4_t r_pixels; + LV_ASSERT_MSG(src_px_size == 3 || src_px_size == 4, "Invalid pixel size for rgb888. Expected either 3 or 4 bytes"); + + if(src_px_size == 3) { + const uint8x8x3_t rgba = vld3_u8(src); + b_pixels = vget_low_u16(vmovl_u8(rgba.val[0])); + g_pixels = vget_low_u16(vmovl_u8(rgba.val[1])); + r_pixels = vget_low_u16(vmovl_u8(rgba.val[2])); + } + else if(src_px_size == 4) { + const uint8x8x4_t rgba = vld4_u8(src); + b_pixels = vget_low_u16(vmovl_u8(rgba.val[0])); + g_pixels = vget_low_u16(vmovl_u8(rgba.val[1])); + r_pixels = vget_low_u16(vmovl_u8(rgba.val[2])); + } + const uint16x4_t dst_pixels = vld1_u16(dst); + const uint16x4_t mask_vec = vget_low_u16(vmovl_u8(vld1_u8(mask))); + const uint16x4_t opa_vec = vmov_n_u16(opa); + const uint16x4_t mix_vec = vshr_n_u16(vmul_u16(opa_vec, mask_vec), 8); + + return lv_color_32_16_mix_4_internal(r_pixels, g_pixels, b_pixels, mix_vec, dst_pixels); +} +static inline uint32_t lv_color_24_16_mix_2_with_opa_mask(const uint8_t * src, const uint16_t * dst, uint8_t opa, + const uint8_t * mask, uint8_t src_px_size) +{ + + return (lv_color_24_16_mix_1_internal(src + src_px_size, dst + 1, LV_OPA_MIX2(mask[1], opa)) << 16) | + lv_color_24_16_mix_1_internal(src, dst, LV_OPA_MIX2(mask[0], opa)); +} +static inline uint16x8_t lv_color_24_16_mix_8_with_opa(const uint8_t * src, const uint16_t * dst, uint8_t opa, + uint8_t src_px_size) +{ + uint16x8_t b_pixels; + uint16x8_t g_pixels; + uint16x8_t r_pixels; + LV_ASSERT_MSG(src_px_size == 3 || src_px_size == 4, "Invalid pixel size for rgb888. Expected either 3 or 4 bytes"); + + if(src_px_size == 3) { + const uint8x8x3_t rgba = vld3_u8(src); + b_pixels = vmovl_u8(rgba.val[0]); + g_pixels = vmovl_u8(rgba.val[1]); + r_pixels = vmovl_u8(rgba.val[2]); + } + else if(src_px_size == 4) { + const uint8x8x4_t rgba = vld4_u8(src); + b_pixels = vmovl_u8(rgba.val[0]); + g_pixels = vmovl_u8(rgba.val[1]); + r_pixels = vmovl_u8(rgba.val[2]); + } + const uint16x8_t dst_pixels = vld1q_u16(dst); + const uint16x8_t opa_vec = vmovq_n_u16(opa); + + return lv_color_32_16_mix_8_internal(r_pixels, g_pixels, b_pixels, opa_vec, dst_pixels); +} +static inline uint16x8_t lv_color_32_16_mix_8_with_opa(const uint8_t * src, const uint16_t * dst, uint8_t opa) +{ + const uint16x8_t dst_pixels = vld1q_u16(dst); + + const uint8x8x4_t rgba = vld4_u8(src); + const uint16x8_t b_pixels = vmovl_u8(rgba.val[0]); + const uint16x8_t g_pixels = vmovl_u8(rgba.val[1]); + const uint16x8_t r_pixels = vmovl_u8(rgba.val[2]); + const uint16x8_t a_pixels = vmovl_u8(rgba.val[3]); + const uint16x8_t opa_vec = vmovq_n_u16(opa); + const uint16x8_t opa_a_mul = vshrq_n_u16(vmulq_u16(a_pixels, opa_vec), 8); + + return lv_color_32_16_mix_8_internal(r_pixels, g_pixels, b_pixels, opa_a_mul, dst_pixels); +} + +static inline uint16x4_t lv_color_24_16_mix_4_with_opa(const uint8_t * src, const uint16_t * dst, uint8_t mix, + uint8_t src_px_size) +{ + + uint16x4_t b_pixels; + uint16x4_t g_pixels; + uint16x4_t r_pixels; + LV_ASSERT_MSG(src_px_size == 3 || src_px_size == 4, "Invalid pixel size for rgb888. Expected either 3 or 4 bytes"); + + if(src_px_size == 3) { + const uint8x8x3_t rgba = vld3_u8(src); + b_pixels = vget_low_u16(vmovl_u8(rgba.val[0])); + g_pixels = vget_low_u16(vmovl_u8(rgba.val[1])); + r_pixels = vget_low_u16(vmovl_u8(rgba.val[2])); + } + else if(src_px_size == 4) { + const uint8x8x4_t rgba = vld4_u8(src); + b_pixels = vget_low_u16(vmovl_u8(rgba.val[0])); + g_pixels = vget_low_u16(vmovl_u8(rgba.val[1])); + r_pixels = vget_low_u16(vmovl_u8(rgba.val[2])); + } + const uint16x4_t dst_pixels = vld1_u16(dst); + const uint16x4_t mix_vec = vget_low_u16(vmovq_n_u16(mix)); + + return lv_color_32_16_mix_4_internal(r_pixels, g_pixels, b_pixels, mix_vec, dst_pixels); +} +static inline uint16x4_t lv_color_32_16_mix_4_with_opa(const uint8_t * src, const uint16_t * dst, uint8_t opa) +{ + const uint16x4_t dst_pixels = vld1_u16(dst); + uint8_t b_array[8] = {src[0], src[4], src[8], src[12], 0, 0, 0, 0}; + uint8_t g_array[8] = {src[1], src[5], src[9], src[13], 0, 0, 0, 0}; + uint8_t r_array[8] = {src[2], src[6], src[10], src[14], 0, 0, 0, 0}; + uint8_t a_array[8] = {src[3], src[7], src[11], src[15], 0, 0, 0, 0}; + const uint16x4_t b_pixels = vget_low_u16(vmovl_u8(vld1_u8(b_array))); + const uint16x4_t g_pixels = vget_low_u16(vmovl_u8(vld1_u8(g_array))); + const uint16x4_t r_pixels = vget_low_u16(vmovl_u8(vld1_u8(r_array))); + const uint16x4_t a_pixels = vget_low_u16(vmovl_u8(vld1_u8(a_array))); + const uint16x4_t opa_vec = vmov_n_u16(opa); + const uint16x4_t opa_a_mul = vshr_n_u16(vmul_u16(a_pixels, opa_vec), 8); + + return lv_color_32_16_mix_4_internal(r_pixels, g_pixels, b_pixels, opa_a_mul, dst_pixels); +} + +static inline uint16x8_t lv_color_32_16_mix_8_with_mask(const uint8_t * src, const uint16_t * dst, const uint8_t * mask) +{ + const uint16x8_t dst_pixels = vld1q_u16(dst); + + const uint8x8x4_t rgba = vld4_u8(src); + const uint16x8_t b_pixels = vmovl_u8(rgba.val[0]); + const uint16x8_t g_pixels = vmovl_u8(rgba.val[1]); + const uint16x8_t r_pixels = vmovl_u8(rgba.val[2]); + const uint16x8_t a_pixels = vmovl_u8(rgba.val[3]); + const uint16x8_t mask_vec = vmovl_u8(vld1_u8(mask)); + const uint16x8_t mask_a_mul = vshrq_n_u16(vmulq_u16(a_pixels, mask_vec), 8); + + return lv_color_32_16_mix_8_internal(r_pixels, g_pixels, b_pixels, mask_a_mul, dst_pixels); +} +static inline uint16x4_t lv_color_32_16_mix_4_with_mask(const uint8_t * src, const uint16_t * dst, const uint8_t * mask) +{ + + const uint16x4_t dst_pixels = vld1_u16(dst); + uint8_t b_array[8] = {src[0], src[4], src[8], src[12], 0, 0, 0, 0}; + uint8_t g_array[8] = {src[1], src[5], src[9], src[13], 0, 0, 0, 0}; + uint8_t r_array[8] = {src[2], src[6], src[10], src[14], 0, 0, 0, 0}; + uint8_t a_array[8] = {src[3], src[7], src[11], src[15], 0, 0, 0, 0}; + uint8_t mask_array[8] = {mask[0], mask[1], mask[2], mask[3], 0, 0, 0, 0}; + const uint16x4_t b_pixels = vget_low_u16(vmovl_u8(vld1_u8(b_array))); + const uint16x4_t g_pixels = vget_low_u16(vmovl_u8(vld1_u8(g_array))); + const uint16x4_t r_pixels = vget_low_u16(vmovl_u8(vld1_u8(r_array))); + const uint16x4_t a_pixels = vget_low_u16(vmovl_u8(vld1_u8(a_array))); + const uint16x4_t mask_vec = vget_low_u16(vmovl_u8(vld1_u8(mask_array))); + const uint16x4_t mask_a_mul = vshr_n_u16(vmul_u16(a_pixels, mask_vec), 8); + return lv_color_32_16_mix_4_internal(r_pixels, g_pixels, b_pixels, mask_a_mul, dst_pixels); +} +static inline uint16x8_t lv_color_32_16_mix_8_with_opa_mask(const uint8_t * src, const uint16_t * dst, uint8_t opa, + const uint8_t * mask) +{ + const uint16x8_t dst_pixels = vld1q_u16(dst); + + const uint8x8x4_t rgba = vld4_u8(src); + const uint16x8_t b_pixels = vmovl_u8(rgba.val[0]); + const uint16x8_t g_pixels = vmovl_u8(rgba.val[1]); + const uint16x8_t r_pixels = vmovl_u8(rgba.val[2]); + const uint16x8_t a_pixels = vmovl_u8(rgba.val[3]); + const uint16x8_t mask_vec = vmovl_u8(vld1_u8(mask)); + const uint16x8_t opa_vec = vmovq_n_u16(opa); + + /* Use uint32 for intermediate multiplication results to avoid 16bit overflows */ + const uint32x4_t a_pixels_low = vmovl_u16(vget_low_u16(a_pixels)); + const uint32x4_t a_pixels_high = vmovl_u16(vget_high_u16(a_pixels)); + const uint32x4_t opa_vec_low = vmovl_u16(vget_low_u16(opa_vec)); + const uint32x4_t opa_vec_high = vmovl_u16(vget_high_u16(opa_vec)); + const uint32x4_t mask_vec_low = vmovl_u16(vget_low_u16(mask_vec)); + const uint32x4_t mask_vec_high = vmovl_u16(vget_high_u16(mask_vec)); + + const uint32x4_t mul_low = vshrq_n_u32(vmulq_u32(vmulq_u32(a_pixels_low, opa_vec_low), mask_vec_low), 16); + const uint32x4_t mul_high = vshrq_n_u32(vmulq_u32(vmulq_u32(a_pixels_high, opa_vec_high), mask_vec_high), 16); + const uint16x8_t mask_opa_a_mul = vcombine_u16(vmovn_u32(mul_low), vmovn_u32(mul_high)); + + return lv_color_32_16_mix_8_internal(r_pixels, g_pixels, b_pixels, mask_opa_a_mul, dst_pixels); +} +static inline uint16x4_t lv_color_32_16_mix_4_with_opa_mask(const uint8_t * src, const uint16_t * dst, uint8_t opa, + const uint8_t * mask) +{ + + const uint16x4_t dst_pixels = vld1_u16(dst); + uint8_t b_array[8] = {src[0], src[4], src[8], src[12], 0, 0, 0, 0}; + uint8_t g_array[8] = {src[1], src[5], src[9], src[13], 0, 0, 0, 0}; + uint8_t r_array[8] = {src[2], src[6], src[10], src[14], 0, 0, 0, 0}; + uint8_t a_array[8] = {src[3], src[7], src[11], src[15], 0, 0, 0, 0}; + uint8_t mask_array[8] = {mask[0], mask[1], mask[2], mask[3], 0, 0, 0, 0}; + const uint16x4_t b_pixels = vget_low_u16(vmovl_u8(vld1_u8(b_array))); + const uint16x4_t g_pixels = vget_low_u16(vmovl_u8(vld1_u8(g_array))); + const uint16x4_t r_pixels = vget_low_u16(vmovl_u8(vld1_u8(r_array))); + const uint16x4_t a_pixels = vget_low_u16(vmovl_u8(vld1_u8(a_array))); + const uint16x4_t mask_vec = vget_low_u16(vmovl_u8(vld1_u8(mask_array))); + const uint16x4_t opa_vec = vmov_n_u16(opa); + + const uint32x4_t a_pixels_low = vmovl_u16(a_pixels); + const uint32x4_t opa_vec_low = vmovl_u16(opa_vec); + const uint32x4_t mask_vec_low = vmovl_u16(mask_vec); + + const uint32x4_t mul_result = vshrq_n_u32(vmulq_u32(vmulq_u32(a_pixels_low, opa_vec_low), mask_vec_low), 16); + const uint16x4_t mask_opa_a_mul = vmovn_u32(mul_result); + + return lv_color_32_16_mix_4_internal(r_pixels, g_pixels, b_pixels, mask_opa_a_mul, dst_pixels); +} + +static inline uint16x8_t lv_color_32_16_mix_8_internal(uint16x8_t r_pixels, uint16x8_t g_pixels, uint16x8_t b_pixels, + uint16x8_t a_pixels, uint16x8_t dst_pixels) +{ + const uint16x8_t mix_zero_mask = vceqq_u16(a_pixels, vdupq_n_u16(0)); + const uint16x8_t mix_full_mask = vceqq_u16(a_pixels, vdupq_n_u16(255)); + + /* Prepare result in case alpha == 255 */ + const uint16x8_t src_r565 = vandq_u16(vshlq_n_u16(r_pixels, 8), vdupq_n_u16(0xF800)); + const uint16x8_t src_g565 = vandq_u16(vshlq_n_u16(g_pixels, 3), vdupq_n_u16(0x07E0)); + const uint16x8_t src_b565 = vshrq_n_u16(b_pixels, 3); + const uint16x8_t src_rgb565 = vorrq_u16(vorrq_u16(src_r565, src_g565), src_b565); + + /* Do the actual blending */ + const uint16x8_t mix_inv_16 = vsubq_u16(vdupq_n_u16(255), a_pixels); + + /* Red: ((src_r >> 3) * mix + ((dst >> 11) & 0x1F) * mix_inv) << 3) & 0xF800 */ + const uint16x8_t src_r = vshrq_n_u16(r_pixels, 3); + const uint16x8_t dst_r = vandq_u16(vshrq_n_u16(dst_pixels, 11), vdupq_n_u16(0x1F)); + uint16x8_t blended_r = vmlaq_u16(vmulq_u16(src_r, a_pixels), dst_r, mix_inv_16); + blended_r = vandq_u16(vshlq_n_u16(blended_r, 3), vdupq_n_u16(0xF800)); + + /* Green: ((src_g >> 2) * mix + ((dst >> 5) & 0x3F) * mix_inv) >> 3) & 0x07E0 */ + const uint16x8_t src_g = vshrq_n_u16(g_pixels, 2); + const uint16x8_t dst_g = vandq_u16(vshrq_n_u16(dst_pixels, 5), vdupq_n_u16(0x3F)); + uint16x8_t blended_g = vmlaq_u16(vmulq_u16(src_g, a_pixels), dst_g, mix_inv_16); + blended_g = vandq_u16(vshrq_n_u16(blended_g, 3), vdupq_n_u16(0x07E0)); + + /* Blue: ((src_b >> 3) * mix + (dst & 0x1F) * mix_inv) >> 8 */ + const uint16x8_t src_b = vshrq_n_u16(b_pixels, 3); + const uint16x8_t dst_b = vandq_u16(dst_pixels, vdupq_n_u16(0x1F)); + uint16x8_t blended_b = vmlaq_u16(vmulq_u16(src_b, a_pixels), dst_b, mix_inv_16); + blended_b = vshrq_n_u16(blended_b, 8); + + const uint16x8_t blended_result = vorrq_u16(vorrq_u16(blended_r, blended_g), blended_b); + const uint16x8_t result = vbslq_u16(mix_zero_mask, dst_pixels, blended_result); + return vbslq_u16(mix_full_mask, src_rgb565, result); +} +static inline uint16x4_t lv_color_32_16_mix_4_internal(uint16x4_t r_pixels, uint16x4_t g_pixels, uint16x4_t b_pixels, + uint16x4_t a_pixels, uint16x4_t dst_pixels) +{ + const uint16x4_t mix_zero_mask = vceq_u16(a_pixels, vdup_n_u16(0)); + const uint16x4_t mix_full_mask = vceq_u16(a_pixels, vdup_n_u16(255)); + + /* Prepare result in case alpha == 255 */ + const uint16x4_t src_r565 = vand_u16(vshl_n_u16(r_pixels, 8), vdup_n_u16(0xF800)); + const uint16x4_t src_g565 = vand_u16(vshl_n_u16(g_pixels, 3), vdup_n_u16(0x07E0)); + const uint16x4_t src_b565 = vshr_n_u16(b_pixels, 3); + const uint16x4_t src_rgb565 = vorr_u16(vorr_u16(src_r565, src_g565), src_b565); + + const uint16x4_t mix_inv_16 = vsub_u16(vdup_n_u16(255), a_pixels); + + /* Red: ((src_r >> 3) * mix + ((dst >> 11) & 0x1F) * mix_inv) << 3) & 0xF800 */ + const uint16x4_t src_r = vshr_n_u16(r_pixels, 3); + const uint16x4_t dst_r = vand_u16(vshr_n_u16(dst_pixels, 11), vdup_n_u16(0x1F)); + uint16x4_t blended_r = vmla_u16(vmul_u16(src_r, a_pixels), dst_r, mix_inv_16); + blended_r = vand_u16(vshl_n_u16(blended_r, 3), vdup_n_u16(0xF800)); + + /* Green: ((src_g >> 2) * mix + ((dst >> 5) & 0x3F) * mix_inv) >> 3) & 0x07E0 */ + const uint16x4_t src_g = vshr_n_u16(g_pixels, 2); + const uint16x4_t dst_g = vand_u16(vshr_n_u16(dst_pixels, 5), vdup_n_u16(0x3F)); + uint16x4_t blended_g = vmla_u16(vmul_u16(src_g, a_pixels), dst_g, mix_inv_16); + blended_g = vand_u16(vshr_n_u16(blended_g, 3), vdup_n_u16(0x07E0)); + + /* Blue: ((src_b >> 3) * mix + (dst & 0x1F) * mix_inv) >> 8 */ + const uint16x4_t src_b = vshr_n_u16(b_pixels, 3); + const uint16x4_t dst_b = vand_u16(dst_pixels, vdup_n_u16(0x1F)); + uint16x4_t blended_b = vmla_u16(vmul_u16(src_b, a_pixels), dst_b, mix_inv_16); + blended_b = vshr_n_u16(blended_b, 8); + + const uint16x4_t blended_result = vorr_u16(vorr_u16(blended_r, blended_g), blended_b); + + const uint16x4_t result = vbsl_u16(mix_zero_mask, dst_pixels, blended_result); + return vbsl_u16(mix_full_mask, src_rgb565, result); +} + +static inline uint32_t lv_color_24_16_mix_2_with_mask(const uint8_t * src, const uint16_t * dst, const uint8_t * mask, + uint8_t src_px_size) +{ + + return (lv_color_24_16_mix_1_internal(src + src_px_size, dst + 1, mask[1]) << 16) | + lv_color_24_16_mix_1_internal(src, dst, *mask); +} + +static inline uint32_t lv_color_24_16_mix_2_with_opa(const uint8_t * src, const uint16_t * dst, uint8_t mix, + uint8_t src_px_size) +{ + return (lv_color_24_16_mix_1_internal(src + src_px_size, dst + 1, mix) << 16) | + lv_color_24_16_mix_1_internal(src, dst, mix); +} +static inline uint32_t lv_color_32_16_mix_2_with_opa(const uint8_t * src, const uint16_t * dst, uint8_t opa) +{ + return (lv_color_32_16_mix_1_with_opa(src + 4, dst + 1, opa) << 16) | lv_color_32_16_mix_1_with_opa(src, dst, opa); +} +static inline uint32_t lv_color_32_16_mix_2_with_opa_mask(const uint8_t * src, const uint16_t * dst, uint8_t opa, + const uint8_t * mask) +{ + return (lv_color_32_16_mix_1_with_opa_mask(src + 4, dst + 1, opa, &mask[1]) << 16) | + lv_color_32_16_mix_1_with_opa_mask(src, dst, opa, &mask[0]); +} + +static inline uint32_t lv_color_32_16_mix_2_with_mask(const uint8_t * src, const uint16_t * dst, const uint8_t * mask) +{ + return (lv_color_32_16_mix_1_with_mask(src + 4, dst + 1, mask + 1) << 16) | + lv_color_32_16_mix_1_with_mask(src, dst, mask); +} +static inline uint32_t lv_color_32_16_mix_2(const uint8_t * src, const uint16_t * dst) +{ + return (lv_color_32_16_mix_1(src + 4, dst + 1) << 16) | lv_color_32_16_mix_1(src, dst); +} + +static inline uint32_t lv_color_32_16_mix_1(const uint8_t * src, const uint16_t * dst) +{ + return lv_color_24_16_mix_1_internal(src, dst, src[3]); +} + +static inline uint16_t lv_color_32_16_mix_1_with_opa_mask(const uint8_t * src, const uint16_t * dst, uint8_t opa, + const uint8_t * mask) +{ + return lv_color_24_16_mix_1_internal(src, dst, LV_OPA_MIX3(src[3], opa, *mask)); +} + +static inline uint16_t lv_color_32_16_mix_1_with_opa(const uint8_t * src, const uint16_t * dst, uint8_t opa) +{ + return lv_color_24_16_mix_1_internal(src, dst, LV_OPA_MIX2(src[3], opa)); +} +static inline uint16_t lv_color_32_16_mix_1_with_mask(const uint8_t * src, const uint16_t * dst, const uint8_t * mask) +{ + + return lv_color_24_16_mix_1_internal(src, dst, LV_OPA_MIX2(src[3], *mask)); +} + +static inline uint16_t lv_color_24_16_mix_1_internal(const uint8_t * src, const uint16_t * dst, uint8_t mix) +{ + if(mix == 0) { + return *dst; + } + else if(mix == 255) { + return ((src[2] & 0xF8) << 8) + ((src[1] & 0xFC) << 3) + ((src[0] & 0xF8) >> 3); + } + else { + lv_opa_t mix_inv = 255 - mix; + + return ((((src[2] >> 3) * mix + ((*dst >> 11) & 0x1F) * mix_inv) << 3) & 0xF800) + + ((((src[1] >> 2) * mix + ((*dst >> 5) & 0x3F) * mix_inv) >> 3) & 0x07E0) + + (((src[0] >> 3) * mix + (*dst & 0x1F) * mix_inv) >> 8); + } +} + +#if LV_DRAW_SW_SUPPORT_ARGB8888_PREMULTIPLIED +static inline uint16x8_t lv_color_24_16_mix_premult_8(const uint8_t * src, const uint16_t * dst) +{ + const uint16x8_t dst_pixels = vld1q_u16(dst); + + const uint8x8x4_t rgba = vld4_u8(src); + const uint16x8_t b_pixels = vmovl_u8(rgba.val[0]); + const uint16x8_t g_pixels = vmovl_u8(rgba.val[1]); + const uint16x8_t r_pixels = vmovl_u8(rgba.val[2]); + const uint16x8_t a_pixels = vmovl_u8(rgba.val[3]); + + const uint16x8_t mix_zero_mask = vceqq_u16(a_pixels, vdupq_n_u16(0)); + const uint16x8_t mix_full_mask = vceqq_u16(a_pixels, vdupq_n_u16(255)); + + /* Prepare result in case alpha == 255 */ + const uint16x8_t src_r565 = vandq_u16(vshlq_n_u16(r_pixels, 8), vdupq_n_u16(0xF800)); + const uint16x8_t src_g565 = vandq_u16(vshlq_n_u16(g_pixels, 3), vdupq_n_u16(0x07E0)); + const uint16x8_t src_b565 = vshrq_n_u16(b_pixels, 3); + const uint16x8_t src_rgb565 = vorrq_u16(vorrq_u16(src_r565, src_g565), src_b565); + + /* Do the actual blending */ + const uint16x8_t mix_inv_16 = vsubq_u16(vdupq_n_u16(255), a_pixels); + + const uint16x8_t src_r = vshrq_n_u16(r_pixels, 3); + const uint16x8_t dst_r = vandq_u16(vshrq_n_u16(dst_pixels, 11), vdupq_n_u16(0x1F)); + uint16x8_t blended_r = vaddq_u16(src_r, vshrq_n_u16(vmulq_u16(dst_r, mix_inv_16), 8)); + blended_r = vshlq_n_u16(blended_r, 11); + + /* Green: ((src_g >> 2) * mix + ((dst >> 5) & 0x3F) * mix_inv) >> 3) & 0x07E0 */ + const uint16x8_t src_g = vshrq_n_u16(g_pixels, 2); + const uint16x8_t dst_g = vandq_u16(vshrq_n_u16(dst_pixels, 5), vdupq_n_u16(0x3F)); + uint16x8_t blended_g = vaddq_u16(src_g, vshrq_n_u16(vmulq_u16(dst_g, mix_inv_16), 8)); + blended_g = vshlq_n_u16(blended_g, 5); + + /* Blue: ((src_b >> 3) * mix + (dst & 0x1F) * mix_inv) >> 8 */ + const uint16x8_t src_b = vshrq_n_u16(b_pixels, 3); + const uint16x8_t dst_b = vandq_u16(dst_pixels, vdupq_n_u16(0x1F)); + uint16x8_t blended_b = vaddq_u16(src_b, vshrq_n_u16(vmulq_u16(dst_b, mix_inv_16), 8)); + + const uint16x8_t blended_result = vaddq_u16(vaddq_u16(blended_r, blended_g), blended_b); + const uint16x8_t result = vbslq_u16(mix_zero_mask, dst_pixels, blended_result); + return vbslq_u16(mix_full_mask, src_rgb565, result); +} +static inline uint16x4_t lv_color_24_16_mix_premult_4(const uint8_t * src, const uint16_t * dst) +{ + const uint16x4_t dst_pixels = vld1_u16(dst); + uint8_t b_array[8] = {src[0], src[4], src[8], src[12], 0, 0, 0, 0}; + uint8_t g_array[8] = {src[1], src[5], src[9], src[13], 0, 0, 0, 0}; + uint8_t r_array[8] = {src[2], src[6], src[10], src[14], 0, 0, 0, 0}; + uint8_t a_array[8] = {src[3], src[7], src[11], src[15], 0, 0, 0, 0}; + const uint16x4_t b_pixels = vget_low_u16(vmovl_u8(vld1_u8(b_array))); + const uint16x4_t g_pixels = vget_low_u16(vmovl_u8(vld1_u8(g_array))); + const uint16x4_t r_pixels = vget_low_u16(vmovl_u8(vld1_u8(r_array))); + const uint16x4_t a_pixels = vget_low_u16(vmovl_u8(vld1_u8(a_array))); + + const uint16x4_t mix_zero_mask = vceq_u16(a_pixels, vdup_n_u16(0)); + const uint16x4_t mix_full_mask = vceq_u16(a_pixels, vdup_n_u16(255)); + + /* Prepare result in case alpha == 255 */ + const uint16x4_t src_r565 = vand_u16(vshl_n_u16(r_pixels, 8), vdup_n_u16(0xF800)); + const uint16x4_t src_g565 = vand_u16(vshl_n_u16(g_pixels, 3), vdup_n_u16(0x07E0)); + const uint16x4_t src_b565 = vshr_n_u16(b_pixels, 3); + const uint16x4_t src_rgb565 = vorr_u16(vorr_u16(src_r565, src_g565), src_b565); + + const uint16x4_t mix_inv_16 = vsub_u16(vdup_n_u16(255), a_pixels); + + const uint16x4_t src_r = vshr_n_u16(r_pixels, 3); + const uint16x4_t dst_r = vand_u16(vshr_n_u16(dst_pixels, 11), vdup_n_u16(0x1F)); + uint16x4_t blended_r = vadd_u16(src_r, vshr_n_u16(vmul_u16(dst_r, mix_inv_16), 8)); + blended_r = vshl_n_u16(blended_r, 11); + + /* Green: ((src_g >> 2) * mix + ((dst >> 5) & 0x3F) * mix_inv) >> 3) & 0x07E0 */ + const uint16x4_t src_g = vshr_n_u16(g_pixels, 2); + const uint16x4_t dst_g = vand_u16(vshr_n_u16(dst_pixels, 5), vdup_n_u16(0x3F)); + uint16x4_t blended_g = vadd_u16(src_g, vshr_n_u16(vmul_u16(dst_g, mix_inv_16), 8)); + blended_g = vshl_n_u16(blended_g, 5); + + /* Blue: ((src_b >> 3) * mix + (dst & 0x1F) * mix_inv) >> 8 */ + const uint16x4_t src_b = vshr_n_u16(b_pixels, 3); + const uint16x4_t dst_b = vand_u16(dst_pixels, vdup_n_u16(0x1F)); + uint16x4_t blended_b = vadd_u16(src_b, vshr_n_u16(vmul_u16(dst_b, mix_inv_16), 8)); + + const uint16x4_t blended_result = vorr_u16(vorr_u16(blended_r, blended_g), blended_b); + + const uint16x4_t result = vbsl_u16(mix_zero_mask, dst_pixels, blended_result); + return vbsl_u16(mix_full_mask, src_rgb565, result); +} + +static inline uint32_t lv_color_24_16_mix_premult_2(const uint8_t * src, const uint16_t * dst) +{ + return ((uint32_t)lv_color_24_16_mix_premult_1(src + 4, dst + 1) << 16) | lv_color_24_16_mix_premult_1(src, dst); +} +static inline uint16_t lv_color_24_16_mix_premult_1(const uint8_t * src, const uint16_t * dst) +{ + const uint8_t mix = src[3]; + if(mix == 0) { + return *dst; + } + else if(mix == 255) { + return ((src[2] & 0xF8) << 8) + ((src[1] & 0xFC) << 3) + ((src[0] & 0xF8) >> 3); + } + else { + lv_opa_t mix_inv = 255 - mix; + + return (((src[2] >> 3) + ((((*dst >> 11) & 0x1F) * mix_inv) >> 8)) << 11) + + (((src[1] >> 2) + ((((*dst >> 5) & 0x3F) * mix_inv) >> 8)) << 5) + + (((src[0] >> 3) + ((((*dst >> 0) & 0x1F) * mix_inv) >> 8))); + } +} + +#endif + +static inline uint16x8_t rgb888_to_rgb565_8(const uint8_t * src, uint8_t src_px_size) +{ + uint16x8_t b_pixels; + uint16x8_t g_pixels; + uint16x8_t r_pixels; + LV_ASSERT_MSG(src_px_size == 3 || src_px_size == 4, "Invalid pixel size for rgb888. Expected either 3 or 4 bytes"); + + if(src_px_size == 3) { + const uint8x8x3_t rgba = vld3_u8(src); + b_pixels = vmovl_u8(rgba.val[0]); + g_pixels = vmovl_u8(rgba.val[1]); + r_pixels = vmovl_u8(rgba.val[2]); + } + else if(src_px_size == 4) { + const uint8x8x4_t rgba = vld4_u8(src); + b_pixels = vmovl_u8(rgba.val[0]); + g_pixels = vmovl_u8(rgba.val[1]); + r_pixels = vmovl_u8(rgba.val[2]); + } + + const uint16x8_t r = vshlq_n_u16(vandq_u16(r_pixels, vdupq_n_u16(0xF8)), 8); + const uint16x8_t g = vshlq_n_u16(vandq_u16(g_pixels, vdupq_n_u16(0xFC)), 3); + const uint16x8_t b = vshrq_n_u16(vandq_u16(b_pixels, vdupq_n_u16(0xF8)), 3); + return vorrq_u16(vorrq_u16(r, g), b); +} + +static inline uint16x4_t rgb888_to_rgb565_4(const uint8_t * src, uint8_t src_px_size) +{ + uint16x4_t b_pixels; + uint16x4_t g_pixels; + uint16x4_t r_pixels; + LV_ASSERT_MSG(src_px_size == 3 || src_px_size == 4, "Invalid pixel size for rgb888. Expected either 3 or 4 bytes"); + + if(src_px_size == 3) { + const uint8x8x3_t rgba = vld3_u8(src); + b_pixels = vget_low_u16(vmovl_u8(rgba.val[0])); + g_pixels = vget_low_u16(vmovl_u8(rgba.val[1])); + r_pixels = vget_low_u16(vmovl_u8(rgba.val[2])); + } + else if(src_px_size == 4) { + const uint8x8x4_t rgba = vld4_u8(src); + b_pixels = vget_low_u16(vmovl_u8(rgba.val[0])); + g_pixels = vget_low_u16(vmovl_u8(rgba.val[1])); + r_pixels = vget_low_u16(vmovl_u8(rgba.val[2])); + } + + const uint16x4_t r = vshl_n_u16(vand_u16(r_pixels, vdup_n_u16(0xF8)), 8); + const uint16x4_t g = vshl_n_u16(vand_u16(g_pixels, vdup_n_u16(0xFC)), 3); + const uint16x4_t b = vshr_n_u16(vand_u16(b_pixels, vdup_n_u16(0xF8)), 3); + return vorr_u16(vorr_u16(r, g), b); +} + +static inline uint32_t rgb888_to_rgb565_2(const uint8_t * src, uint8_t src_px_size) +{ + return ((uint32_t)rgb888_to_rgb565_1(src + src_px_size) << 16) | rgb888_to_rgb565_1(src); +} +static inline uint16_t rgb888_to_rgb565_1(const uint8_t * src) +{ + return ((src[2] & 0xF8) << 8) + ((src[1] & 0xFC) << 3) + ((src[0] & 0xF8) >> 3); +} + +static inline uint16x8_t lv_color_16_16_mix_8_with_opa(const uint16_t * c1, const uint16_t * c2, uint8_t opa) +{ + + const uint16x8_t c1_vec = vld1q_u16(c1); + const uint16x8_t c2_vec = vld1q_u16(c2); + const uint16x8_t mix_vec = vmovq_n_u16(opa); + return lv_color_16_16_mix_8_internal(c1_vec, c2_vec, mix_vec); +} +static inline uint16x8_t lv_color_16_16_mix_8_with_mask(const uint16_t * c1, const uint16_t * c2, const uint8_t * mask) +{ + const uint16x8_t c1_vec = vld1q_u16(c1); + const uint16x8_t c2_vec = vld1q_u16(c2); + const uint16x8_t mix_vec = vmovl_u8(vld1_u8(mask)); + return lv_color_16_16_mix_8_internal(c1_vec, c2_vec, mix_vec); +} +static inline uint16x8_t lv_color_16_16_mix_8_with_opa_mask(const uint16_t * c1, const uint16_t * c2, uint8_t opa, + const uint8_t * mask) +{ + + const uint16x8_t c1_vec = vld1q_u16(c1); + const uint16x8_t c2_vec = vld1q_u16(c2); + const uint16x8_t opa_vec = vmovq_n_u16(opa); + const uint16x8_t mask_vec = vmovl_u8(vld1_u8(mask)); + const uint16x8_t mix_vec = vshrq_n_u16(vmulq_u16(opa_vec, mask_vec), 8); + return lv_color_16_16_mix_8_internal(c1_vec, c2_vec, mix_vec); +} + +static inline uint16x8_t lv_color_16_16_mix_8_internal(uint16x8_t c1_vec, uint16x8_t c2_vec, uint16x8_t mix) +{ + const uint16x8_t mix_zero_mask = vceqq_u16(mix, vdupq_n_u16(0)); + const uint16x8_t mix_full_mask = vceqq_u16(mix, vdupq_n_u16(255)); + const uint16x8_t equal_mask = vceqq_u16(c1_vec, c2_vec); + + mix = vshrq_n_u16(vaddq_u16(mix, vdupq_n_u16(4)), 3); + /* Split into low and high parts for 32-bit operations */ + uint32x4_t c1_low = vmovl_u16(vget_low_u16(c1_vec)); + uint32x4_t c1_high = vmovl_u16(vget_high_u16(c1_vec)); + uint32x4_t c2_low = vmovl_u16(vget_low_u16(c2_vec)); + uint32x4_t c2_high = vmovl_u16(vget_high_u16(c2_vec)); + uint32x4_t fg_low = vorrq_u32(c1_low, vshlq_n_u32(c1_low, 16)); + uint32x4_t fg_high = vorrq_u32(c1_high, vshlq_n_u32(c1_high, 16)); + uint32x4_t bg_low = vorrq_u32(c2_low, vshlq_n_u32(c2_low, 16)); + uint32x4_t bg_high = vorrq_u32(c2_high, vshlq_n_u32(c2_high, 16)); + + /* Apply mask 0x7E0F81F to extract RGB components */ + const uint32x4_t mask = vdupq_n_u32(0x7E0F81F); + fg_low = vandq_u32(fg_low, mask); + fg_high = vandq_u32(fg_high, mask); + bg_low = vandq_u32(bg_low, mask); + bg_high = vandq_u32(bg_high, mask); + + const uint32x4_t mix_low = vmovl_u16(vget_low_u16(mix)); + const uint32x4_t mix_high = vmovl_u16(vget_high_u16(mix)); + + /* Perform the blend: ((fg - bg) * mix) >> 5 + bg */ + const uint32x4_t diff_low = vsubq_u32(fg_low, bg_low); + const uint32x4_t diff_high = vsubq_u32(fg_high, bg_high); + const uint32x4_t scaled_low = vmulq_u32(diff_low, mix_low); + const uint32x4_t scaled_high = vmulq_u32(diff_high, mix_high); + const uint32x4_t shifted_low = vshrq_n_u32(scaled_low, 5); + const uint32x4_t shifted_high = vshrq_n_u32(scaled_high, 5); + uint32x4_t result_low = vaddq_u32(shifted_low, bg_low); + uint32x4_t result_high = vaddq_u32(shifted_high, bg_high); + + /* Apply final mask */ + result_low = vandq_u32(result_low, mask); + result_high = vandq_u32(result_high, mask); + + /* Convert back to 16-bit: (result >> 16) | result */ + const uint32x4_t final_low = vorrq_u32(result_low, vshrq_n_u32(result_low, 16)); + const uint32x4_t final_high = vorrq_u32(result_high, vshrq_n_u32(result_high, 16)); + + const uint16x4_t packed_low = vmovn_u32(final_low); + const uint16x4_t packed_high = vmovn_u32(final_high); + uint16x8_t result = vcombine_u16(packed_low, packed_high); + + result = vbslq_u16(mix_zero_mask, c2_vec, result); + result = vbslq_u16(mix_full_mask, c1_vec, result); + result = vbslq_u16(equal_mask, c1_vec, result); + + return result; +} + +static inline uint16x4_t lv_color_16_16_mix_4_with_opa(const uint16_t * c1, const uint16_t * c2, uint8_t opa) +{ + const uint16x4_t c1_vec = vld1_u16(c1); + const uint16x4_t c2_vec = vld1_u16(c2); + const uint16x4_t mix_vec = vmov_n_u16(opa); + return lv_color_16_16_mix_4_internal(c1_vec, c2_vec, mix_vec); +} +static inline uint16x4_t lv_color_16_16_mix_4_with_mask(const uint16_t * c1, const uint16_t * c2, const uint8_t * mask) +{ + const uint16x4_t c1_vec = vld1_u16(c1); + const uint16x4_t c2_vec = vld1_u16(c2); + const uint16x4_t mix_vec = vget_low_u16(vmovl_u8(vld1_u8(mask))); + return lv_color_16_16_mix_4_internal(c1_vec, c2_vec, mix_vec); +} +static inline uint16x4_t lv_color_16_16_mix_4_with_opa_mask(const uint16_t * c1, const uint16_t * c2, uint8_t opa, + const uint8_t * mask) +{ + + const uint16x4_t c1_vec = vld1_u16(c1); + const uint16x4_t c2_vec = vld1_u16(c2); + const uint16x4_t opa_vec = vmov_n_u16(opa); + const uint16x4_t mask_vec = vget_low_u16(vmovl_u8(vld1_u8(mask))); + const uint16x4_t mix_vec = vshr_n_u16(vmul_u16(opa_vec, mask_vec), 8); + return lv_color_16_16_mix_4_internal(c1_vec, c2_vec, mix_vec); +} + +static inline uint16x4_t lv_color_16_16_mix_4_internal(uint16x4_t c1_vec, uint16x4_t c2_vec, uint16x4_t mix) +{ + const uint16x4_t mix_zero_mask = vceq_u16(mix, vdup_n_u16(0)); + const uint16x4_t mix_full_mask = vceq_u16(mix, vdup_n_u16(255)); + const uint16x4_t equal_mask = vceq_u16(c1_vec, c2_vec); + + mix = vshr_n_u16(vadd_u16(mix, vdup_n_u16(4)), 3); + /* Split into low and high parts for 32-bit operations */ + uint32x4_t c1 = vmovl_u16(c1_vec); + uint32x4_t c2 = vmovl_u16(c2_vec); + uint32x4_t fg = vorrq_u32(c1, vshlq_n_u32(c1, 16)); + uint32x4_t bg = vorrq_u32(c2, vshlq_n_u32(c2, 16)); + + /* Apply mask 0x7E0F81F to extract RGB components */ + const uint32x4_t mask = vdupq_n_u32(0x7E0F81F); + fg = vandq_u32(fg, mask); + bg = vandq_u32(bg, mask); + + const uint32x4_t mix32 = vmovl_u16(mix); + + /* Perform the blend: ((fg - bg) * mix) >> 5 + bg */ + const uint32x4_t diff = vsubq_u32(fg, bg); + const uint32x4_t scaled = vmulq_u32(diff, mix32); + const uint32x4_t shifted = vshrq_n_u32(scaled, 5); + uint32x4_t result32 = vaddq_u32(shifted, bg); + result32 = vandq_u32(result32, mask); + + /* Convert back to 16-bit: (result >> 16) | result */ + const uint32x4_t final = vorrq_u32(result32, vshrq_n_u32(result32, 16)); + + uint16x4_t result = vmovn_u32(final); + result = vbsl_u16(mix_zero_mask, c2_vec, result); + result = vbsl_u16(mix_full_mask, c1_vec, result); + result = vbsl_u16(equal_mask, c1_vec, result); + + return result; +} + +static inline uint32_t lv_color_16_16_mix_2_with_opa(const uint16_t * c1, const uint16_t * c2, uint8_t opa) +{ + return lv_color_16_16_mix(c1[1], c2[1], opa) << 16 | lv_color_16_16_mix(*c1, *c2, opa); +} +static inline uint32_t lv_color_16_16_mix_2_with_mask(const uint16_t * c1, const uint16_t * c2, const uint8_t * mask) +{ + return lv_color_16_16_mix(c1[1], c2[1], mask[1]) << 16 | lv_color_16_16_mix(*c1, *c2, *mask); +} +static inline uint32_t lv_color_16_16_mix_2_with_opa_mask(const uint16_t * c1, const uint16_t * c2, uint8_t opa, + const uint8_t * mask) +{ + + return lv_color_16_16_mix(c1[1], c2[1], LV_OPA_MIX2(opa, mask[1])) << 16 | + lv_color_16_16_mix(*c1, *c2, LV_OPA_MIX2(*mask, opa)); +} + +static inline void * LV_ATTRIBUTE_FAST_MEM drawbuf_next_row(const void * buf, uint32_t stride) +{ + return (void *)((uint8_t *)buf + stride); +} +#endif /* LV_USE_DRAW_SW_ASM == LV_DRAW_SW_ASM_NEON*/ diff --git a/src/draw/sw/blend/neon/lv_draw_sw_blend_neon_to_rgb565.h b/src/draw/sw/blend/neon/lv_draw_sw_blend_neon_to_rgb565.h new file mode 100644 index 0000000000..27fcf4b99b --- /dev/null +++ b/src/draw/sw/blend/neon/lv_draw_sw_blend_neon_to_rgb565.h @@ -0,0 +1,190 @@ +/** + * @file lv_draw_sw_blend_neon_to_rgb565.h + * + */ + +#ifndef LV_DRAW_SW_BLEND_NEON_TO_RGB565_H +#define LV_DRAW_SW_BLEND_NEON_TO_RGB565_H + +#ifdef __cplusplus +extern "C" { +#endif + +/********************* + * INCLUDES + *********************/ + +#include "../../../../lv_conf_internal.h" +#if LV_USE_DRAW_SW_ASM == LV_DRAW_SW_ASM_NEON + +#include "../../../../misc/lv_types.h" + +/********************* + * DEFINES + *********************/ + +#ifndef LV_DRAW_SW_COLOR_BLEND_TO_RGB565 +#define LV_DRAW_SW_COLOR_BLEND_TO_RGB565(dsc) lv_draw_sw_blend_neon_color_to_rgb565(dsc) + +#endif + +#ifndef LV_DRAW_SW_COLOR_BLEND_TO_RGB565_WITH_OPA +#define LV_DRAW_SW_COLOR_BLEND_TO_RGB565_WITH_OPA(dsc) lv_draw_sw_blend_neon_color_to_rgb565_with_opa(dsc) +#endif + +#ifndef LV_DRAW_SW_COLOR_BLEND_TO_RGB565_WITH_MASK +#define LV_DRAW_SW_COLOR_BLEND_TO_RGB565_WITH_MASK(dsc) lv_draw_sw_blend_neon_color_to_rgb565_with_mask(dsc) + +#endif + +#ifndef LV_DRAW_SW_COLOR_BLEND_TO_RGB565_MIX_MASK_OPA +#define LV_DRAW_SW_COLOR_BLEND_TO_RGB565_MIX_MASK_OPA(dsc) lv_draw_sw_blend_neon_color_to_rgb565_with_opa_mask(dsc) +#endif + +#ifndef LV_DRAW_SW_L8_BLEND_NORMAL_TO_RGB565 +#define LV_DRAW_SW_L8_BLEND_NORMAL_TO_RGB565(dsc) lv_draw_sw_blend_neon_l8_to_rgb565(dsc) +#endif + +#ifndef LV_DRAW_SW_L8_BLEND_NORMAL_TO_RGB565_WITH_OPA +#define LV_DRAW_SW_L8_BLEND_NORMAL_TO_RGB565_WITH_OPA(...) LV_RESULT_INVALID +#endif + +#ifndef LV_DRAW_SW_L8_BLEND_NORMAL_TO_RGB565_WITH_MASK +#define LV_DRAW_SW_L8_BLEND_NORMAL_TO_RGB565_WITH_MASK(...) LV_RESULT_INVALID +#endif + +#ifndef LV_DRAW_SW_L8_BLEND_NORMAL_TO_RGB565_MIX_MASK_OPA +#define LV_DRAW_SW_L8_BLEND_NORMAL_TO_RGB565_MIX_MASK_OPA(...) LV_RESULT_INVALID +#endif + +#ifndef LV_DRAW_SW_AL88_BLEND_NORMAL_TO_RGB565 +#define LV_DRAW_SW_AL88_BLEND_NORMAL_TO_RGB565(dsc) lv_draw_sw_blend_neon_al88_to_rgb565(dsc) +#endif + +#ifndef LV_DRAW_SW_AL88_BLEND_NORMAL_TO_RGB565_WITH_OPA +#define LV_DRAW_SW_AL88_BLEND_NORMAL_TO_RGB565_WITH_OPA(dsc) lv_draw_sw_blend_neon_al88_to_rgb565_with_opa(dsc) +#endif + +#if 0 /* Disabled as it's not tested */ +#ifndef LV_DRAW_SW_AL88_BLEND_NORMAL_TO_RGB565_WITH_MASK +#define LV_DRAW_SW_AL88_BLEND_NORMAL_TO_RGB565_WITH_MASK(dsc) lv_draw_sw_blend_neon_al88_to_rgb565_with_mask(dsc) + +#endif + +#ifndef LV_DRAW_SW_AL88_BLEND_NORMAL_TO_RGB565_MIX_MASK_OPA +#define LV_DRAW_SW_AL88_BLEND_NORMAL_TO_RGB565_MIX_MASK_OPA(dsc) lv_draw_sw_blend_neon_al88_to_rgb565_with_opa_mask(dsc) +#endif +#endif + +#ifndef LV_DRAW_SW_RGB565_BLEND_NORMAL_TO_RGB565 +#define LV_DRAW_SW_RGB565_BLEND_NORMAL_TO_RGB565(dsc) lv_draw_sw_blend_neon_rgb565_to_rgb565(dsc) +#endif + +#ifndef LV_DRAW_SW_RGB565_BLEND_NORMAL_TO_RGB565_WITH_OPA +#define LV_DRAW_SW_RGB565_BLEND_NORMAL_TO_RGB565_WITH_OPA(dsc) lv_draw_sw_blend_neon_rgb565_to_rgb565_with_opa(dsc) +#endif + +#ifndef LV_DRAW_SW_RGB565_BLEND_NORMAL_TO_RGB565_WITH_MASK +#define LV_DRAW_SW_RGB565_BLEND_NORMAL_TO_RGB565_WITH_MASK(dsc) lv_draw_sw_blend_neon_rgb565_to_rgb565_with_mask(dsc) +#endif + +#ifndef LV_DRAW_SW_RGB565_BLEND_NORMAL_TO_RGB565_MIX_MASK_OPA +#define LV_DRAW_SW_RGB565_BLEND_NORMAL_TO_RGB565_MIX_MASK_OPA(dsc) lv_draw_sw_blend_neon_rgb565_to_rgb565_with_opa_mask(dsc) +#endif + +#ifndef LV_DRAW_SW_RGB888_BLEND_NORMAL_TO_RGB565 +#define LV_DRAW_SW_RGB888_BLEND_NORMAL_TO_RGB565(dsc, src_px_size) lv_draw_sw_blend_neon_rgb888_to_rgb565(dsc, src_px_size) +#endif + +#ifndef LV_DRAW_SW_RGB888_BLEND_NORMAL_TO_RGB565_WITH_OPA +#define LV_DRAW_SW_RGB888_BLEND_NORMAL_TO_RGB565_WITH_OPA(dsc, src_px_size) lv_draw_sw_blend_neon_rgb888_to_rgb565_with_opa(dsc, src_px_size) +#endif + +#ifndef LV_DRAW_SW_RGB888_BLEND_NORMAL_TO_RGB565_WITH_MASK +#define LV_DRAW_SW_RGB888_BLEND_NORMAL_TO_RGB565_WITH_MASK(dsc, src_px_size) lv_draw_sw_blend_neon_rgb888_to_rgb565_with_mask(dsc, src_px_size) +#endif + +#ifndef LV_DRAW_SW_RGB888_BLEND_NORMAL_TO_RGB565_MIX_MASK_OPA +#define LV_DRAW_SW_RGB888_BLEND_NORMAL_TO_RGB565_MIX_MASK_OPA(dsc, src_px_size) lv_draw_sw_blend_neon_rgb888_to_rgb565_with_opa_mask(dsc, src_px_size) +#endif + +#ifndef LV_DRAW_SW_ARGB8888_BLEND_NORMAL_TO_RGB565 +#define LV_DRAW_SW_ARGB8888_BLEND_NORMAL_TO_RGB565(dsc) lv_draw_sw_blend_neon_argb888_to_rgb565(dsc) +#endif + +#ifndef LV_DRAW_SW_ARGB8888_BLEND_NORMAL_TO_RGB565_WITH_OPA +#define LV_DRAW_SW_ARGB8888_BLEND_NORMAL_TO_RGB565_WITH_OPA(dsc) lv_draw_sw_blend_neon_argb888_to_rgb565_with_opa(dsc) +#endif + +#ifndef LV_DRAW_SW_ARGB8888_BLEND_NORMAL_TO_RGB565_WITH_MASK +#define LV_DRAW_SW_ARGB8888_BLEND_NORMAL_TO_RGB565_WITH_MASK(dsc) lv_draw_sw_blend_neon_argb888_to_rgb565_with_mask(dsc) +#endif + +#ifndef LV_DRAW_SW_ARGB8888_BLEND_NORMAL_TO_RGB565_MIX_MASK_OPA +#define LV_DRAW_SW_ARGB8888_BLEND_NORMAL_TO_RGB565_MIX_MASK_OPA(dsc) lv_draw_sw_blend_neon_argb888_to_rgb565_with_opa_mask(dsc) +#endif + +#ifndef LV_DRAW_SW_ARGB8888_PREMULTIPLIED_BLEND_NORMAL_TO_RGB565 +#define LV_DRAW_SW_ARGB8888_PREMULTIPLIED_BLEND_NORMAL_TO_RGB565(dsc) lv_draw_sw_blend_neon_argb888_premultiplied_to_rgb565(dsc) +#endif + +/* + * Bleding operations with premultiplied argb8888 require division. + * As division is not supported for integer values in neon we don't define these functions + */ +#ifndef LV_DRAW_SW_ARGB8888_PREMULTIPLIED_BLEND_NORMAL_TO_RGB565_WITH_OPA +#define LV_DRAW_SW_ARGB8888_PREMULTIPLIED_BLEND_NORMAL_TO_RGB565_WITH_OPA(...) LV_RESULT_INVALID +#endif + +#ifndef LV_DRAW_SW_ARGB8888_PREMULTIPLIED_BLEND_NORMAL_TO_RGB565_WITH_MASK +#define LV_DRAW_SW_ARGB8888_PREMULTIPLIED_BLEND_NORMAL_TO_RGB565_WITH_MASK(...) LV_RESULT_INVALID +#endif + +#ifndef LV_DRAW_SW_ARGB8888_PREMULTIPLIED_BLEND_NORMAL_TO_RGB565_MIX_MASK_OPA +#define LV_DRAW_SW_ARGB8888_PREMULTIPLIED_BLEND_NORMAL_TO_RGB565_MIX_MASK_OPA(...) LV_RESULT_INVALID +#endif + +/********************** + * TYPEDEFS + **********************/ + +/********************** + * GLOBAL PROTOTYPES + **********************/ + +lv_result_t lv_draw_sw_blend_neon_color_to_rgb565(lv_draw_sw_blend_fill_dsc_t * dsc); +lv_result_t lv_draw_sw_blend_neon_color_to_rgb565_with_opa(lv_draw_sw_blend_fill_dsc_t * dsc); +lv_result_t lv_draw_sw_blend_neon_color_to_rgb565_with_mask(lv_draw_sw_blend_fill_dsc_t * dsc); +lv_result_t lv_draw_sw_blend_neon_color_to_rgb565_with_opa_mask(lv_draw_sw_blend_fill_dsc_t * dsc); +lv_result_t lv_draw_sw_blend_neon_l8_to_rgb565(lv_draw_sw_blend_image_dsc_t * dsc); +lv_result_t lv_draw_sw_blend_neon_al88_to_rgb565(lv_draw_sw_blend_image_dsc_t * dsc); +lv_result_t lv_draw_sw_blend_neon_al88_to_rgb565_with_opa(lv_draw_sw_blend_image_dsc_t * dsc); +lv_result_t lv_draw_sw_blend_neon_al88_to_rgb565_with_mask(lv_draw_sw_blend_image_dsc_t * dsc); +lv_result_t lv_draw_sw_blend_neon_al88_to_rgb565_with_opa_mask(lv_draw_sw_blend_image_dsc_t * dsc); + +lv_result_t lv_draw_sw_blend_neon_rgb565_to_rgb565(lv_draw_sw_blend_image_dsc_t * dsc); +lv_result_t lv_draw_sw_blend_neon_rgb565_to_rgb565_with_opa(lv_draw_sw_blend_image_dsc_t * dsc); +lv_result_t lv_draw_sw_blend_neon_rgb565_to_rgb565_with_mask(lv_draw_sw_blend_image_dsc_t * dsc); +lv_result_t lv_draw_sw_blend_neon_rgb565_to_rgb565_with_opa_mask(lv_draw_sw_blend_image_dsc_t * dsc); +lv_result_t lv_draw_sw_blend_neon_rgb888_to_rgb565(lv_draw_sw_blend_image_dsc_t * dsc, uint8_t src_px_size); +lv_result_t lv_draw_sw_blend_neon_rgb888_to_rgb565_with_opa(lv_draw_sw_blend_image_dsc_t * dsc, uint8_t src_px_size); +lv_result_t lv_draw_sw_blend_neon_rgb888_to_rgb565_with_mask(lv_draw_sw_blend_image_dsc_t * dsc, uint8_t src_px_size); +lv_result_t lv_draw_sw_blend_neon_rgb888_to_rgb565_with_opa_mask(lv_draw_sw_blend_image_dsc_t * dsc, + uint8_t src_px_size); +lv_result_t lv_draw_sw_blend_neon_argb888_to_rgb565(lv_draw_sw_blend_image_dsc_t * dsc); +lv_result_t lv_draw_sw_blend_neon_argb888_premultiplied_to_rgb565(lv_draw_sw_blend_image_dsc_t * dsc); +lv_result_t lv_draw_sw_blend_neon_argb888_to_rgb565_with_opa(lv_draw_sw_blend_image_dsc_t * dsc); +lv_result_t lv_draw_sw_blend_neon_argb888_to_rgb565_with_mask(lv_draw_sw_blend_image_dsc_t * dsc); +lv_result_t lv_draw_sw_blend_neon_argb888_to_rgb565_with_opa_mask(lv_draw_sw_blend_image_dsc_t * dsc); + +/********************** + * MACROS + **********************/ + +#endif /* LV_USE_DRAW_SW_ASM == LV_DRAW_SW_ASM_NEON */ + +#ifdef __cplusplus +} /*extern "C"*/ +#endif + +#endif /*LV_DRAW_SW_BLEND_NEON_TO_RGB565_H*/ diff --git a/src/draw/sw/blend/neon/lv_draw_sw_blend_neon_to_rgb888.c b/src/draw/sw/blend/neon/lv_draw_sw_blend_neon_to_rgb888.c new file mode 100644 index 0000000000..9c20c522a6 --- /dev/null +++ b/src/draw/sw/blend/neon/lv_draw_sw_blend_neon_to_rgb888.c @@ -0,0 +1,1704 @@ +/** + * @file lv_draw_sw_blend_neon_to_rgb888.c + * + */ + +/********************* + * INCLUDES + *********************/ +#include "lv_draw_sw_blend_neon_to_rgb888.h" +#include +#if LV_USE_DRAW_SW_ASM == LV_DRAW_SW_ASM_NEON + +#include "../../../../misc/lv_color.h" +#include "../../../../misc/lv_types.h" +#include "../lv_draw_sw_blend_private.h" +#include + +/********************* + * DEFINES + *********************/ + +/********************** + * TYPEDEFS + **********************/ + +/********************** + * STATIC PROTOTYPES + **********************/ + +static inline void * LV_ATTRIBUTE_FAST_MEM drawbuf_next_row(const void * buf, uint32_t stride); + +static inline uint32x4_t rgb565_xrgb_mix_4_internal(uint32x4_t src, uint32x4_t dst, uint32x4_t mix); +static inline uint32x2_t rgb565_xrgb_mix_2_internal(uint32x2_t src, uint32x2_t dst, uint32x2_t mix); + +static inline uint8x16x3_t lv_color_to_rgb888_16(const lv_color_t * color); +static inline uint8x8x3_t lv_color_to_rgb888_8(const lv_color_t * color); + +static inline uint8x16x4_t lv_color_to_xrgb888_16(const lv_color_t * color); +static inline uint8x8x4_t lv_color_to_xrgb888_8(const lv_color_t * color); +static inline uint8x16_t lv_color_to_xrgb888_4(const lv_color_t * color); +static inline uint8x8_t lv_color_to_xrgb888_2(const lv_color_t * color); +static inline uint8x8x3_t lv_rgb565_to_rgb888_8(const uint16_t * color); +static inline uint8x8x4_t lv_rgb565_to_xrgb8888_8(const uint16_t * color); + + +static inline uint8x8x3_t rgb565_rgb888_mix_8_internal(uint16x8_t src, uint8x8x3_t dst, uint8x8_t mix); + +static inline void lv_color_24_24_mix_1(const uint8_t * src, uint8_t * dest, uint8_t mix); + +static inline void rgb565_mix_1(const uint16_t * src, uint8_t * dest, uint8_t mix); + +static inline uint32x4_t argb_rgb_mix_4(const uint32_t * src, const uint32_t * dst); +static inline uint32x2_t argb_rgb_mix_2(const uint32_t * src, const uint32_t * dst); + +static inline uint32x4_t argb_rgb_mix_4_with_opa(const uint32_t * src, const uint32_t * dst, uint32x4_t mix); +static inline uint32x2_t argb_rgb_mix_2_with_opa(const uint32_t * src, const uint32_t * dst, uint32x2_t mix); + +static inline uint32x4_t argb_rgb_mix_4_with_opa_mask(const uint32_t * src, const uint32_t * dst, uint32x4_t opa, + uint32x4_t mask); +static inline uint32x2_t argb_rgb_mix_2_with_opa_mask(const uint32_t * src, const uint32_t * dst, uint32x2_t opa, + uint32x2_t mask); + +static inline uint32x4_t lv_color_24_24_mix_4_internal(uint32x4_t src, uint32x4_t dst, uint32x4_t mix); +static inline uint32x2_t lv_color_24_24_mix_2_internal(uint32x2_t src, uint32x2_t dst, uint32x2_t mix); + +static inline uint32x4_t lv_color_24_24_mix_4_premul_internal(uint32x4_t src, uint32x4_t dst, uint32x4_t mix); +static inline uint32x2_t lv_color_24_24_mix_2_premul_internal(uint32x2_t src, uint32x2_t dst, uint32x2_t mix); +static inline void lv_color_24_24_mix_premult(const uint8_t * src, uint8_t * dest, uint8_t mix); + +static inline uint8x16x3_t rgb_mix_8_internal(uint8x16x3_t src, uint8x16x3_t dst, uint8x16_t mix); +static inline uint8x8x3_t rgb_mix_4_internal(uint8x8x3_t src, uint8x8x3_t dst, uint8x8_t mix); + +/********************** + * STATIC VARIABLES + **********************/ + +/********************** + * MACROS + **********************/ + +/********************** + * GLOBAL FUNCTIONS + **********************/ + +lv_result_t lv_draw_sw_blend_neon_color_to_rgb888(lv_draw_sw_blend_fill_dsc_t * dsc, uint32_t dest_px_size) +{ + LV_ASSERT(dest_px_size == 3 || dest_px_size == 4); + LV_ASSERT(dsc->opa >= LV_OPA_MAX); + LV_ASSERT(dsc->mask_buf == NULL); + const int32_t w = dsc->dest_w; + const int32_t h = dsc->dest_h; + const int32_t dest_stride = dsc->dest_stride; + uint8_t * dest_buf_8 = dsc->dest_buf; + + if(dest_px_size == 3) { + const int32_t byte_w = w * 3; + const uint8x16x3_t vec_16 = lv_color_to_rgb888_16(&dsc->color); + const uint8x8x3_t vec_8 = lv_color_to_rgb888_8(&dsc->color); + for(int32_t y = 0; y < h; y++) { + uint8_t * row_byte_ptr = dest_buf_8; + int32_t x = 0; + for(; x < byte_w - 47; x += 48) { + vst3q_u8(&row_byte_ptr[x], vec_16); + } + for(; x < byte_w - 23; x += 24) { + vst3_u8(&row_byte_ptr[x], vec_8); + } + for(; x < byte_w; x += 3) { + row_byte_ptr[x + 0] = dsc->color.blue; + row_byte_ptr[x + 1] = dsc->color.green; + row_byte_ptr[x + 2] = dsc->color.red; + } + dest_buf_8 = drawbuf_next_row(dest_buf_8, dest_stride); + } + } + else if(dest_px_size == 4) { + const int32_t byte_w = w * 4; + const uint8x16x4_t vec_16 = lv_color_to_xrgb888_16(&dsc->color); + const uint8x8x4_t vec_8 = lv_color_to_xrgb888_8(&dsc->color); + const uint8x16_t vec_4 = lv_color_to_xrgb888_4(&dsc->color); + const uint8x8_t vec_2 = lv_color_to_xrgb888_2(&dsc->color); + + for(int32_t y = 0; y < h; y++) { + uint8_t * row_byte_ptr = dest_buf_8; + int32_t x = 0; + for(; x < byte_w - 63; x += 64) { + vst4q_u8(&row_byte_ptr[x], vec_16); + } + for(; x < byte_w - 31; x += 32) { + vst4_u8(&row_byte_ptr[x], vec_8); + } + for(; x < byte_w - 15; x += 16) { + vst1q_u8(&row_byte_ptr[x], vec_4); + } + for(; x < byte_w - 7; x += 8) { + vst1_u8(&row_byte_ptr[x], vec_2); + } + for(; x < byte_w; x += 4) { + row_byte_ptr[x + 0] = dsc->color.blue; + row_byte_ptr[x + 1] = dsc->color.green; + row_byte_ptr[x + 2] = dsc->color.red; + row_byte_ptr[x + 3] = 0xFF; + } + dest_buf_8 = drawbuf_next_row(dest_buf_8, dest_stride); + } + } + + return LV_RESULT_OK; +} +lv_result_t lv_draw_sw_blend_neon_color_to_rgb888_with_opa(lv_draw_sw_blend_fill_dsc_t * dsc, uint32_t dest_px_size) +{ + LV_ASSERT(dest_px_size == 3 || dest_px_size == 4); + LV_ASSERT(dsc->opa < LV_OPA_MAX); + LV_ASSERT(dsc->mask_buf == NULL); + const int32_t w = dsc->dest_w; + const int32_t h = dsc->dest_h; + const int32_t dest_stride = dsc->dest_stride; + const uint8_t opa = dsc->opa; + + if(dest_px_size == 3) { + const uint8x16x3_t color_16 = {{vdupq_n_u8(dsc->color.blue), vdupq_n_u8(dsc->color.green), vdupq_n_u8(dsc->color.red)}}; + const uint8x8x3_t color_8 = {{vdup_n_u8(dsc->color.blue), vdup_n_u8(dsc->color.green), vdup_n_u8(dsc->color.red)}}; + const uint8x16_t opa_16 = vdupq_n_u8(dsc->opa); + const uint8x8_t opa_8 = vdup_n_u8(dsc->opa); + + uint8_t * dest_buf_8 = dsc->dest_buf; + for(int32_t y = 0; y < h; y++) { + uint8_t * row_ptr = dest_buf_8; + int32_t x = 0; + for(; x < w - 15; x += 16) { + uint8x16x3_t dst = vld3q_u8(&row_ptr[x * 3]); + vst3q_u8(&row_ptr[x * 3], rgb_mix_8_internal(color_16, dst, opa_16)); + } + for(; x < w - 7; x += 8) { + uint8x8x3_t dst = vld3_u8(&row_ptr[x * 3]); + vst3_u8(&row_ptr[x * 3], rgb_mix_4_internal(color_8, dst, opa_8)); + } + for(; x < w; x ++) { + lv_color_24_24_mix_1((const uint8_t *)&dsc->color, &row_ptr[x * 3], opa); + } + dest_buf_8 = drawbuf_next_row(dest_buf_8, dest_stride); + } + + } + else if(dest_px_size == 4) { + uint32_t * dest_buf_32 = dsc->dest_buf; + const uint32_t color = dsc->color.red << 16 | dsc->color.green << 8 | dsc->color.blue; + const uint32x4_t vec_4 = vdupq_n_u32(color); + const uint32x4_t opa_4 = vdupq_n_u32((uint32_t)dsc->opa); + const uint32x2_t vec_2 = vdup_n_u32(color); + const uint32x2_t opa_2 = vdup_n_u32((uint32_t)dsc->opa); + + for(int32_t y = 0; y < h; y++) { + uint32_t * row_ptr = dest_buf_32; + int32_t x = 0; + for(; x < w - 3; x += 4) { + uint32x4_t dst = vld1q_u32(&row_ptr[x]); + vst1q_u32(&row_ptr[x], lv_color_24_24_mix_4_internal(vec_4, dst, opa_4)); + } + for(; x < w - 1; x += 2) { + uint32x2_t dst = vld1_u32(&row_ptr[x]); + vst1_u32(&row_ptr[x], lv_color_24_24_mix_2_internal(vec_2, dst, opa_2)); + } + for(; x < w; x ++) { + lv_color_24_24_mix_1((const uint8_t *)&dsc->color, (uint8_t *)&row_ptr[x], opa); + } + dest_buf_32 = drawbuf_next_row(dest_buf_32, dest_stride); + } + } + + return LV_RESULT_OK; +} + +lv_result_t lv_draw_sw_blend_neon_color_to_rgb888_with_mask(lv_draw_sw_blend_fill_dsc_t * dsc, uint32_t dest_px_size) +{ + LV_ASSERT(dest_px_size == 3 || dest_px_size == 4); + LV_ASSERT(dsc->opa >= LV_OPA_MAX); + LV_ASSERT_NULL(dsc->mask_buf); + const int32_t w = dsc->dest_w; + const int32_t h = dsc->dest_h; + const int32_t dest_stride = dsc->dest_stride; + const int32_t mask_stride = dsc->mask_stride; + const uint8_t * mask_buf_8 = dsc->mask_buf; + + if(dest_px_size == 3) { + const uint8x16x3_t color_16 = {{vdupq_n_u8(dsc->color.blue), vdupq_n_u8(dsc->color.green), vdupq_n_u8(dsc->color.red)}}; + const uint8x8x3_t color_8 = {{vdup_n_u8(dsc->color.blue), vdup_n_u8(dsc->color.green), vdup_n_u8(dsc->color.red)}}; + + uint8_t * dest_buf_8 = dsc->dest_buf; + for(int32_t y = 0; y < h; y++) { + uint8_t * row_ptr = dest_buf_8; + const uint8_t * mask_row_ptr = mask_buf_8; + int32_t x = 0; + for(; x < w - 15; x += 16) { + const uint8x16_t mask_16 = vld1q_u8(&mask_row_ptr[x]); + uint8x16x3_t dst = vld3q_u8(&row_ptr[x * 3]); + vst3q_u8(&row_ptr[x * 3], rgb_mix_8_internal(color_16, dst, mask_16)); + } + for(; x < w - 7; x += 8) { + const uint8x8_t mask_8 = vld1_u8(&mask_row_ptr[x]); + uint8x8x3_t dst = vld3_u8(&row_ptr[x * 3]); + vst3_u8(&row_ptr[x * 3], rgb_mix_4_internal(color_8, dst, mask_8)); + } + for(; x < w; x ++) { + lv_color_24_24_mix_1((const uint8_t *)&dsc->color, &row_ptr[x * 3], mask_row_ptr[x]); + } + dest_buf_8 = drawbuf_next_row(dest_buf_8, dest_stride); + mask_buf_8 = drawbuf_next_row(mask_buf_8, mask_stride); + } + } + else if(dest_px_size == 4) { + uint32_t * dest_buf_32 = dsc->dest_buf; + const uint32_t color = dsc->color.red << 16 | dsc->color.green << 8 | dsc->color.blue; + const uint32x4_t vec_4 = vdupq_n_u32(color); + const uint32x2_t vec_2 = vdup_n_u32(color); + + for(int32_t y = 0; y < h; y++) { + uint32_t * row_ptr = dest_buf_32; + const uint8_t * mask_row_ptr = mask_buf_8; + int32_t x = 0; + for(; x < w - 3; x += 4) { + const uint32x4_t mix_4 = {mask_row_ptr[x], mask_row_ptr[x + 1], mask_row_ptr[x + 2], mask_row_ptr[x + 3]}; + const uint32x4_t dst = vld1q_u32(&row_ptr[x]); + vst1q_u32(&row_ptr[x], lv_color_24_24_mix_4_internal(vec_4, dst, mix_4)); + } + for(; x < w - 1; x += 2) { + const uint32x2_t mix_2 = {mask_row_ptr[x], mask_row_ptr[x + 1]}; + const uint32x2_t dst = vld1_u32(&row_ptr[x]); + vst1_u32(&row_ptr[x], lv_color_24_24_mix_2_internal(vec_2, dst, mix_2)); + } + for(; x < w; x ++) { + lv_color_24_24_mix_1((const uint8_t *)&dsc->color, (uint8_t *)&row_ptr[x], mask_row_ptr[x]); + } + dest_buf_32 = drawbuf_next_row(dest_buf_32, dest_stride); + mask_buf_8 = drawbuf_next_row(mask_buf_8, mask_stride); + } + } + return LV_RESULT_OK; +} + +lv_result_t lv_draw_sw_blend_neon_color_to_rgb888_with_opa_mask(lv_draw_sw_blend_fill_dsc_t * dsc, + uint32_t dest_px_size) +{ + LV_ASSERT(dest_px_size == 3 || dest_px_size == 4); + LV_ASSERT(dsc->opa < LV_OPA_MAX); + LV_ASSERT_NULL(dsc->mask_buf); + const int32_t w = dsc->dest_w; + const int32_t h = dsc->dest_h; + const int32_t dest_stride = dsc->dest_stride; + const uint8_t opa = dsc->opa; + const int32_t mask_stride = dsc->mask_stride; + const uint8_t * mask_buf_8 = dsc->mask_buf; + + if(dest_px_size == 3) { + const uint8x16x3_t color_16 = {{vdupq_n_u8(dsc->color.blue), vdupq_n_u8(dsc->color.green), vdupq_n_u8(dsc->color.red)}}; + const uint8x8x3_t color_8 = {{vdup_n_u8(dsc->color.blue), vdup_n_u8(dsc->color.green), vdup_n_u8(dsc->color.red)}}; + const uint8x16_t opa_16 = vdupq_n_u8(dsc->opa); + const uint8x8_t opa_8 = vdup_n_u8(dsc->opa); + + uint8_t * dest_buf_8 = dsc->dest_buf; + for(int32_t y = 0; y < h; y++) { + uint8_t * row_ptr = dest_buf_8; + const uint8_t * mask_row_ptr = mask_buf_8; + int32_t x = 0; + for(; x < w - 15; x += 16) { + const uint8x16_t mask_16 = vld1q_u8(&mask_row_ptr[x]); + const uint8x8_t opa_lo = vget_low_u8(opa_16); + const uint8x8_t opa_hi = vget_high_u8(opa_16); + const uint8x8_t mask_lo = vget_low_u8(mask_16); + const uint8x8_t mask_hi = vget_high_u8(mask_16); + const uint16x8_t result_lo_wide = vmull_u8(opa_lo, mask_lo); + const uint16x8_t result_hi_wide = vmull_u8(opa_hi, mask_hi); + const uint8x8_t result_lo = vshrn_n_u16(result_lo_wide, 8); + const uint8x8_t result_hi = vshrn_n_u16(result_hi_wide, 8); + const uint8x16_t mix = vcombine_u8(result_lo, result_hi); + uint8x16x3_t dst = vld3q_u8(&row_ptr[x * 3]); + vst3q_u8(&row_ptr[x * 3], rgb_mix_8_internal(color_16, dst, mix)); + } + for(; x < w - 7; x += 8) { + const uint8x8_t mask_8 = vld1_u8(&mask_row_ptr[x]); + const uint16x8_t mult = vmull_u8(opa_8, mask_8); + const uint8x8_t mix = vshrn_n_u16(mult, 8); + uint8x8x3_t dst = vld3_u8(&row_ptr[x * 3]); + vst3_u8(&row_ptr[x * 3], rgb_mix_4_internal(color_8, dst, mix)); + } + for(; x < w; x ++) { + lv_color_24_24_mix_1((const uint8_t *)&dsc->color, &row_ptr[x * 3], LV_OPA_MIX2(opa, mask_row_ptr[x])); + } + dest_buf_8 = drawbuf_next_row(dest_buf_8, dest_stride); + mask_buf_8 = drawbuf_next_row(mask_buf_8, mask_stride); + } + } + else if(dest_px_size == 4) { + const int32_t mask_stride = dsc->mask_stride; + uint32_t * dest_buf_32 = dsc->dest_buf; + const uint8_t * mask_buf_8 = dsc->mask_buf; + const uint32_t color = dsc->color.red << 16 | dsc->color.green << 8 | dsc->color.blue; + const uint32x4_t vec_4 = vdupq_n_u32(color); + const uint32x4_t opa_4 = vdupq_n_u32((uint32_t)dsc->opa); + const uint32x2_t vec_2 = vdup_n_u32(color); + const uint32x2_t opa_2 = vdup_n_u32((uint32_t)dsc->opa); + + for(int32_t y = 0; y < h; y++) { + uint32_t * row_ptr = dest_buf_32; + const uint8_t * mask_row_ptr = mask_buf_8; + int32_t x = 0; + for(; x < w - 3; x += 4) { + const uint32x4_t mask_4 = {mask_row_ptr[x], mask_row_ptr[x + 1], mask_row_ptr[x + 2], mask_row_ptr[x + 3]}; + const uint32x4_t mix_4 = vshrq_n_u32(vmulq_u32(opa_4, mask_4), 8); + const uint32x4_t dst = vld1q_u32(&row_ptr[x]); + vst1q_u32(&row_ptr[x], lv_color_24_24_mix_4_internal(vec_4, dst, mix_4)); + } + for(; x < w - 1; x += 2) { + const uint32x2_t mask_2 = {mask_row_ptr[x], mask_row_ptr[x + 1]}; + const uint32x2_t mix_2 = vshr_n_u32(vmul_u32(opa_2, mask_2), 8); + const uint32x2_t dst = vld1_u32(&row_ptr[x]); + vst1_u32(&row_ptr[x], lv_color_24_24_mix_2_internal(vec_2, dst, mix_2)); + } + for(; x < w; x ++) { + lv_color_24_24_mix_1((const uint8_t *)&dsc->color, (uint8_t *)&row_ptr[x], LV_OPA_MIX2(opa, mask_row_ptr[x])); + } + dest_buf_32 = drawbuf_next_row(dest_buf_32, dest_stride); + mask_buf_8 = drawbuf_next_row(mask_buf_8, mask_stride); + } + } + return LV_RESULT_OK; +} + +#ifdef __aarch64__ /* vqtbl1q_u8 is only available on arm64 */ +lv_result_t lv_draw_sw_blend_neon_l8_to_rgb888(lv_draw_sw_blend_image_dsc_t * dsc, uint32_t dest_px_size) +{ + LV_ASSERT(dest_px_size == 3 || dest_px_size == 4); + LV_ASSERT(dsc->opa >= LV_OPA_MAX); + LV_ASSERT(dsc->mask_buf == NULL); + const int32_t w = dsc->dest_w; + const int32_t h = dsc->dest_h; + const int32_t src_stride = dsc->src_stride; + const int32_t dest_stride = dsc->dest_stride; + uint8_t * dest_buf_8 = dsc->dest_buf; + const uint8_t * src_buf_l8 = dsc->src_buf; + + if(dest_px_size == 3) { + static const uint8x16_t selector_mask = {0, 0, 0, 1, 1, 1, 2, 2, 2, 3, 3, 3, 4, 4, 4, 0}; + for(int32_t y = 0; y < h; y++) { + uint8_t * row_byte_ptr = dest_buf_8; + const uint8_t * src_row = src_buf_l8; + int32_t dest_x = 0; + int32_t src_x = 0; + for(; src_x < w - 8; src_x += 5, dest_x += 15) { + uint8x8_t gray_pixels = vld1_u8(&src_row[src_x]); + uint8x16_t gray_extended = vcombine_u8(gray_pixels, vdup_n_u8(0)); + uint8x16_t rgb_result = vqtbl1q_u8(gray_extended, selector_mask); + vst1q_u8(&row_byte_ptr[dest_x], rgb_result); + } + for(; src_x < w; src_x++, dest_x += 3) { + row_byte_ptr[dest_x + 0] = src_row[src_x]; + row_byte_ptr[dest_x + 1] = src_row[src_x]; + row_byte_ptr[dest_x + 2] = src_row[src_x]; + } + dest_buf_8 = drawbuf_next_row(dest_buf_8, dest_stride); + src_buf_l8 = drawbuf_next_row(src_buf_l8, src_stride); + } + } + else if(dest_px_size == 4) { + static const uint8x16_t selector_mask = {0, 0, 0, 0, 1, 1, 1, 1, 2, 2, 2, 2, 3, 3, 3, 3}; + for(int32_t y = 0; y < h; y++) { + uint8_t * row_byte_ptr = dest_buf_8; + const uint8_t * src_row = src_buf_l8; + int32_t dest_x = 0; + int32_t src_x = 0; + for(; src_x < w - 8; src_x += 4, dest_x += 16) { + uint8x8_t gray_pixels = vld1_u8(&src_row[src_x]); + uint8x16_t gray_extended = vcombine_u8(gray_pixels, vdup_n_u8(0)); + uint8x16_t rgb_result = vqtbl1q_u8(gray_extended, selector_mask); + vst1q_u8(&row_byte_ptr[dest_x], rgb_result); + } + for(; src_x < w; src_x++, dest_x += 4) { + row_byte_ptr[dest_x + 0] = src_row[src_x]; + row_byte_ptr[dest_x + 1] = src_row[src_x]; + row_byte_ptr[dest_x + 2] = src_row[src_x]; + row_byte_ptr[dest_x + 3] = src_row[src_x]; + } + dest_buf_8 = drawbuf_next_row(dest_buf_8, dest_stride); + src_buf_l8 = drawbuf_next_row(src_buf_l8, src_stride); + } + } + return LV_RESULT_OK; +} +#endif + +lv_result_t lv_draw_sw_blend_neon_rgb565_to_rgb888(lv_draw_sw_blend_image_dsc_t * dsc, uint32_t dest_px_size) +{ + LV_ASSERT(dest_px_size == 3 || dest_px_size == 4); + LV_ASSERT(dsc->opa >= LV_OPA_MAX); + LV_ASSERT(dsc->mask_buf == NULL); + int32_t w = dsc->dest_w; + int32_t h = dsc->dest_h; + uint8_t * dest_buf_u8 = dsc->dest_buf; + int32_t dest_stride = dsc->dest_stride; + const uint16_t * src_buf_u16 = dsc->src_buf; + int32_t src_stride = dsc->src_stride; + + if(dest_px_size == 3) { + for(int32_t y = 0; y < h; y++) { + uint8_t * dest_row = dest_buf_u8; + const uint16_t * src_row = (const uint16_t *)src_buf_u16; + int32_t src_x = 0; + int32_t dest_x = 0; + + for(; src_x < w - 7; src_x += 8, dest_x += 24) { + uint8x8x3_t rgb = lv_rgb565_to_rgb888_8(&src_row[src_x]); + vst3_u8(&dest_row[dest_x], rgb); + } + for(; src_x < w; src_x++, dest_x += 3) { + const uint8_t r = (((src_row[src_x] & 0xF800) >> 11) * 2106) >> 8; + const uint8_t g = (((src_row[src_x] & 0x07E0) >> 5) * 1037) >> 8; + const uint8_t b = (((src_row[src_x] & 0x001F)) * 2106) >> 8; + dest_row[dest_x + 0] = b; + dest_row[dest_x + 1] = g; + dest_row[dest_x + 2] = r; + } + dest_buf_u8 = drawbuf_next_row(dest_buf_u8, dest_stride); + src_buf_u16 = drawbuf_next_row(src_buf_u16, src_stride); + } + } + else { + for(int32_t y = 0; y < h; y++) { + uint8_t * dest_row = dest_buf_u8; + const uint16_t * src_row = (const uint16_t *)src_buf_u16; + int32_t src_x = 0; + int32_t dest_x = 0; + + for(; src_x < w - 7; src_x += 8, dest_x += 32) { + uint8x8x4_t xrgb = lv_rgb565_to_xrgb8888_8(&src_row[src_x]); + vst4_u8(&dest_row[dest_x], xrgb); + } + for(; src_x < w; src_x++, dest_x += 4) { + const uint8_t r = (((src_row[src_x] & 0xF800) >> 11) * 2106) >> 8; + const uint8_t g = (((src_row[src_x] & 0x07E0) >> 5) * 1037) >> 8; + const uint8_t b = (((src_row[src_x] & 0x001F)) * 2106) >> 8; + dest_row[dest_x + 0] = b; + dest_row[dest_x + 1] = g; + dest_row[dest_x + 2] = r; + } + dest_buf_u8 = drawbuf_next_row(dest_buf_u8, dest_stride); + src_buf_u16 = drawbuf_next_row(src_buf_u16, src_stride); + } + } + return LV_RESULT_OK; +} +lv_result_t lv_draw_sw_blend_neon_rgb565_to_rgb888_with_opa(lv_draw_sw_blend_image_dsc_t * dsc, uint32_t dest_px_size) +{ + + LV_ASSERT(dest_px_size == 3 || dest_px_size == 4); + LV_ASSERT(dsc->opa < LV_OPA_MAX); + LV_ASSERT(dsc->mask_buf == NULL); + const int32_t w = dsc->dest_w; + const int32_t h = dsc->dest_h; + const int32_t dest_stride = dsc->dest_stride; + const uint8_t opa = dsc->opa; + const uint16_t * src_buf_u16 = dsc->src_buf; + const int32_t src_stride = dsc->src_stride; + + if(dest_px_size == 3) { + const uint8x8_t opa_8 = vdup_n_u8(dsc->opa); + uint8_t * dest_buf_8 = dsc->dest_buf; + for(int32_t y = 0; y < h; y++) { + uint8_t * row_ptr = dest_buf_8; + const uint16_t * src_row_ptr = src_buf_u16; + int32_t x = 0; + for(; x < w - 7; x += 8) { + uint16x8_t src = vld1q_u16(&src_row_ptr[x]); + uint8x8x3_t dst = vld3_u8(&row_ptr[x * 3]); + vst3_u8(&row_ptr[x * 3], rgb565_rgb888_mix_8_internal(src, dst, opa_8)); + } + for(; x < w; x++) { + rgb565_mix_1(&src_row_ptr[x], &row_ptr[x * 3], opa); + } + dest_buf_8 = drawbuf_next_row(dest_buf_8, dest_stride); + src_buf_u16 = drawbuf_next_row(src_buf_u16, src_stride); + } + } + else if(dest_px_size == 4) { + uint32_t * dest_buf_32 = dsc->dest_buf; + const uint16_t * src_buf_u16 = dsc->src_buf; + const uint32x4_t opa_4 = vdupq_n_u32((uint32_t)dsc->opa); + const uint32x2_t opa_2 = vdup_n_u32((uint32_t)dsc->opa); + + for(int32_t y = 0; y < h; y++) { + uint32_t * row_ptr = dest_buf_32; + const uint16_t * src_row_ptr = src_buf_u16; + int32_t x = 0; + for(; x < w - 3; x += 4) { + uint32x4_t dst = vld1q_u32(&row_ptr[x]); + const uint16x4_t vec_4 = vld1_u16(&src_row_ptr[x]); + uint32x4_t src = vmovl_u16(vec_4); + vst1q_u32(&row_ptr[x], rgb565_xrgb_mix_4_internal(src, dst, opa_4)); + } + for(; x < w - 1; x += 2) { + uint32x2_t dst = vld1_u32(&row_ptr[x]); + uint32x2_t src = {src_row_ptr[x], src_row_ptr[x + 1]}; + vst1_u32(&row_ptr[x], rgb565_xrgb_mix_2_internal(src, dst, opa_2)); + } + for(; x < w; x++) { + rgb565_mix_1(&src_row_ptr[x], (uint8_t *)&row_ptr[x], opa); + } + dest_buf_32 = drawbuf_next_row(dest_buf_32, dest_stride); + src_buf_u16 = drawbuf_next_row(src_buf_u16, src_stride); + } + } + + return LV_RESULT_OK; +} +lv_result_t lv_draw_sw_blend_neon_rgb565_to_rgb888_with_mask(lv_draw_sw_blend_image_dsc_t * dsc, uint32_t dest_px_size) +{ + LV_ASSERT(dest_px_size == 3 || dest_px_size == 4); + LV_ASSERT(dsc->opa >= LV_OPA_MAX); + LV_ASSERT_NULL(dsc->mask_buf); + const int32_t w = dsc->dest_w; + const int32_t h = dsc->dest_h; + const int32_t dest_stride = dsc->dest_stride; + const uint16_t * src_buf_u16 = dsc->src_buf; + const int32_t src_stride = dsc->src_stride; + const uint8_t * mask_buf_u8 = dsc->mask_buf; + const int32_t mask_stride = dsc->mask_stride; + + if(dest_px_size == 3) { + uint8_t * dest_buf_8 = dsc->dest_buf; + for(int32_t y = 0; y < h; y++) { + uint8_t * row_ptr = dest_buf_8; + const uint16_t * src_row_ptr = src_buf_u16; + const uint8_t * mask_row_ptr = mask_buf_u8; + int32_t x = 0; + for(; x < w - 7; x += 8) { + uint16x8_t src = vld1q_u16(&src_row_ptr[x]); + uint8x8x3_t dst = vld3_u8(&row_ptr[x * 3]); + uint8x8_t mask = vld1_u8(&mask_row_ptr[x]); + vst3_u8(&row_ptr[x * 3], rgb565_rgb888_mix_8_internal(src, dst, mask)); + } + for(; x < w; x++) { + rgb565_mix_1(&src_row_ptr[x], &row_ptr[x * 3], mask_row_ptr[x]); + } + dest_buf_8 = drawbuf_next_row(dest_buf_8, dest_stride); + src_buf_u16 = drawbuf_next_row(src_buf_u16, src_stride); + mask_buf_u8 = drawbuf_next_row(mask_buf_u8, mask_stride); + } + } + else if(dest_px_size == 4) { + /* The algorithm below might look okay but the demo render test fails with it so it's disabled */ + return LV_RESULT_INVALID; +#if 0 /* TODO: Figure out the problem with the algorithm below */ + uint32_t * dest_buf_32 = dsc->dest_buf; + const uint16_t * src_buf_u16 = dsc->src_buf; + + for(int32_t y = 0; y < h; y++) { + uint32_t * row_ptr = dest_buf_32; + const uint16_t * src_row_ptr = src_buf_u16; + const uint8_t * mask_row_ptr = mask_buf_u8; + int32_t x = 0; + for(; x < w - 3; x += 4) { + uint32x4_t dst = vld1q_u32(&row_ptr[x]); + const uint16x4_t vec_4 = vld1_u16(&src_row_ptr[x]); + uint32x4_t src = vmovl_u16(vec_4); + const uint32x4_t mask_4 = {mask_row_ptr[x], mask_row_ptr[x + 1], mask_row_ptr[x + 2], mask_row_ptr[x + 3]}; + + vst1q_u32(&row_ptr[x], rgb565_xrgb_mix_4_internal(src, dst, mask_4)); + } + for(; x < w - 1; x += 2) { + uint32x2_t dst = vld1_u32(&row_ptr[x]); + uint32x2_t src = {src_row_ptr[x], src_row_ptr[x + 1]}; + const uint32x2_t mask_2 = {mask_row_ptr[x], mask_row_ptr[x + 1]}; + vst1_u32(&row_ptr[x], rgb565_xrgb_mix_2_internal(src, dst, mask_2)); + } + for(; x < w; x++) { + rgb565_mix_1(&src_row_ptr[x], (uint8_t *)&row_ptr[x], mask_row_ptr[x]); + } + dest_buf_32 = drawbuf_next_row(dest_buf_32, dest_stride); + src_buf_u16 = drawbuf_next_row(src_buf_u16, src_stride); + mask_buf_u8 = drawbuf_next_row(mask_buf_u8, mask_stride); + } +#endif + } + + return LV_RESULT_OK; +} +lv_result_t lv_draw_sw_blend_neon_rgb565_to_rgb888_with_opa_mask(lv_draw_sw_blend_image_dsc_t * dsc, + uint32_t dest_px_size) +{ + LV_ASSERT(dsc->opa < LV_OPA_MAX); + LV_ASSERT(dsc->mask_buf != NULL); + const int32_t w = dsc->dest_w; + const int32_t h = dsc->dest_h; + const int32_t dest_stride = dsc->dest_stride; + const uint16_t * src_buf_u16 = dsc->src_buf; + const int32_t src_stride = dsc->src_stride; + const uint8_t * mask_buf_u8 = dsc->mask_buf; + const int32_t mask_stride = dsc->mask_stride; + const uint8_t opa = dsc->opa; + + if(dest_px_size == 3) { + uint8_t * dest_buf_8 = dsc->dest_buf; + const uint8x8_t opa_8 = vdup_n_u8(dsc->opa); + for(int32_t y = 0; y < h; y++) { + uint8_t * row_ptr = dest_buf_8; + const uint16_t * src_row_ptr = src_buf_u16; + const uint8_t * mask_row_ptr = mask_buf_u8; + int32_t x = 0; + for(; x < w - 7; x += 8) { + uint16x8_t src = vld1q_u16(&src_row_ptr[x]); + uint8x8x3_t dst = vld3_u8(&row_ptr[x * 3]); + uint8x8_t mask = vld1_u8(&mask_row_ptr[x]); + const uint16x8_t mult = vmull_u8(opa_8, mask); + const uint8x8_t mix = vshrn_n_u16(mult, 8); + vst3_u8(&row_ptr[x * 3], rgb565_rgb888_mix_8_internal(src, dst, mix)); + } + for(; x < w; x++) { + rgb565_mix_1(&src_row_ptr[x], &row_ptr[x * 3], LV_OPA_MIX2(mask_row_ptr[x], opa)); + } + dest_buf_8 = drawbuf_next_row(dest_buf_8, dest_stride); + src_buf_u16 = drawbuf_next_row(src_buf_u16, src_stride); + mask_buf_u8 = drawbuf_next_row(mask_buf_u8, mask_stride); + } + } + else if(dest_px_size == 4) { + uint32_t * dest_buf_32 = dsc->dest_buf; + const uint16_t * src_buf_u16 = dsc->src_buf; + const uint32x4_t opa_4 = vdupq_n_u32((uint32_t)dsc->opa); + const uint32x2_t opa_2 = vdup_n_u32((uint32_t)dsc->opa); + + for(int32_t y = 0; y < h; y++) { + uint32_t * row_ptr = dest_buf_32; + const uint16_t * src_row_ptr = src_buf_u16; + const uint8_t * mask_row_ptr = mask_buf_u8; + int32_t x = 0; + for(; x < w - 3; x += 4) { + uint32x4_t dst = vld1q_u32(&row_ptr[x]); + const uint16x4_t vec_4 = vld1_u16(&src_row_ptr[x]); + uint32x4_t src = vmovl_u16(vec_4); + const uint32x4_t mask_4 = {mask_row_ptr[x], mask_row_ptr[x + 1], mask_row_ptr[x + 2], mask_row_ptr[x + 3]}; + const uint32x4_t mix_4 = vshrq_n_u32(vmulq_u32(opa_4, mask_4), 8); + + vst1q_u32(&row_ptr[x], rgb565_xrgb_mix_4_internal(src, dst, mix_4)); + } + for(; x < w - 1; x += 2) { + uint32x2_t dst = vld1_u32(&row_ptr[x]); + uint32x2_t src = {src_row_ptr[x], src_row_ptr[x + 1]}; + const uint32x2_t mask_2 = {mask_row_ptr[x], mask_row_ptr[x + 1]}; + const uint32x2_t mix_2 = vshr_n_u32(vmul_u32(opa_2, mask_2), 8); + vst1_u32(&row_ptr[x], rgb565_xrgb_mix_2_internal(src, dst, mix_2)); + } + for(; x < w; x++) { + rgb565_mix_1(&src_row_ptr[x], (uint8_t *)&row_ptr[x], LV_OPA_MIX2(opa, mask_row_ptr[x])); + } + dest_buf_32 = drawbuf_next_row(dest_buf_32, dest_stride); + src_buf_u16 = drawbuf_next_row(src_buf_u16, src_stride); + mask_buf_u8 = drawbuf_next_row(mask_buf_u8, mask_stride); + } + } + return LV_RESULT_OK; +} +lv_result_t lv_draw_sw_blend_neon_rgb888_to_rgb888(lv_draw_sw_blend_image_dsc_t * dsc, uint32_t dest_px_size, + uint32_t src_px_size) +{ + LV_ASSERT(dest_px_size == 3 || dest_px_size == 4); + LV_ASSERT(src_px_size == 3 || src_px_size == 4); + LV_ASSERT(dsc->opa >= LV_OPA_MAX); + LV_ASSERT(dsc->mask_buf == NULL); + int32_t w = dsc->dest_w; + int32_t h = dsc->dest_h; + uint8_t * dest_buf_u8 = dsc->dest_buf; + int32_t dest_stride = dsc->dest_stride; + const uint8_t * src_buf_u8 = dsc->src_buf; + int32_t src_stride = dsc->src_stride; + + /* Fallback to sw implementation*/ + if(src_px_size != dest_px_size) { + return LV_RESULT_INVALID; + } + + for(int32_t y = 0; y < h; y++) { + uint8_t * dest_row = dest_buf_u8; + const uint8_t * src_row = src_buf_u8; + int32_t byte_w = w * src_px_size; + int32_t x = 0; + for(; x < byte_w - 15; x += 16) { + vst1q_u8(&dest_row[x], vld1q_u8(&src_row[x])); + } + for(; x < byte_w - 7; x += 8) { + vst1_u8(&dest_row[x], vld1_u8(&src_row[x])); + } + for(; x < byte_w; x++) { + dest_row[x] = src_row[x]; + } + dest_buf_u8 = drawbuf_next_row(dest_buf_u8, dest_stride); + src_buf_u8 = drawbuf_next_row(src_buf_u8, src_stride); + } + return LV_RESULT_OK; +} + +lv_result_t lv_draw_sw_blend_neon_rgb888_to_rgb888_with_opa(lv_draw_sw_blend_image_dsc_t * dsc, uint32_t dest_px_size, + uint32_t src_px_size) +{ + LV_ASSERT(dest_px_size == 3 || dest_px_size == 4); + LV_ASSERT(src_px_size == 3 || src_px_size == 4); + LV_ASSERT(dsc->opa < LV_OPA_MAX); + LV_ASSERT(dsc->mask_buf == NULL); + const int32_t w = dsc->dest_w; + const int32_t h = dsc->dest_h; + const int32_t dest_stride = dsc->dest_stride; + const int32_t src_stride = dsc->src_stride; + const uint8_t opa = dsc->opa; + + /* Fallback to sw implementation*/ + if(dest_px_size != src_px_size) { + return LV_RESULT_INVALID; + } + + if(dest_px_size == 3) { + const uint8x16_t opa_16 = vdupq_n_u8(dsc->opa); + const uint8x8_t opa_8 = vdup_n_u8(dsc->opa); + uint8_t * dest_buf_8 = dsc->dest_buf; + const uint8_t * src_buf_8 = dsc->src_buf; + for(int32_t y = 0; y < h; y++) { + uint8_t * row_ptr = dest_buf_8; + const uint8_t * src_row_ptr = src_buf_8; + + int32_t x = 0; + for(; x < w - 15; x += 16) { + uint8x16x3_t src = vld3q_u8(&src_row_ptr[x * 3]); + uint8x16x3_t dst = vld3q_u8(&row_ptr[x * 3]); + vst3q_u8(&row_ptr[x * 3], rgb_mix_8_internal(src, dst, opa_16)); + } + for(; x < w - 7; x += 8) { + uint8x8x3_t src = vld3_u8(&src_row_ptr[x * 3]); + uint8x8x3_t dst = vld3_u8(&row_ptr[x * 3]); + vst3_u8(&row_ptr[x * 3], rgb_mix_4_internal(src, dst, opa_8)); + } + for(; x < w; x ++) { + lv_color_24_24_mix_1(&src_row_ptr[x * 3], &row_ptr[x * 3], opa); + } + dest_buf_8 = drawbuf_next_row(dest_buf_8, dest_stride); + src_buf_8 = drawbuf_next_row(src_buf_8, src_stride); + } + + } + else if(dest_px_size == 4) { + uint32_t * dest_buf_32 = dsc->dest_buf; + const uint32_t * src_buf_32 = dsc->src_buf; + const uint32x4_t opa_4 = vdupq_n_u32((uint32_t)dsc->opa); + const uint32x2_t opa_2 = vdup_n_u32((uint32_t)dsc->opa); + + for(int32_t y = 0; y < h; y++) { + uint32_t * row_ptr = dest_buf_32; + const uint32_t * src_row_ptr = src_buf_32; + int32_t x = 0; + for(; x < w - 3; x += 4) { + uint32x4_t src = vld1q_u32(&src_row_ptr[x]); + uint32x4_t dst = vld1q_u32(&row_ptr[x]); + vst1q_u32(&row_ptr[x], lv_color_24_24_mix_4_internal(src, dst, opa_4)); + } + for(; x < w - 1; x += 2) { + uint32x2_t src = vld1_u32(&src_row_ptr[x]); + uint32x2_t dst = vld1_u32(&row_ptr[x]); + vst1_u32(&row_ptr[x], lv_color_24_24_mix_2_internal(src, dst, opa_2)); + } + for(; x < w; x ++) { + lv_color_24_24_mix_1((uint8_t *)&src_row_ptr[x], (uint8_t *)&row_ptr[x], opa); + } + dest_buf_32 = drawbuf_next_row(dest_buf_32, dest_stride); + src_buf_32 = drawbuf_next_row(src_buf_32, src_stride); + } + } + return LV_RESULT_OK; +} +lv_result_t lv_draw_sw_blend_neon_rgb888_to_rgb888_with_mask(lv_draw_sw_blend_image_dsc_t * dsc, uint32_t dest_px_size, + uint32_t src_px_size) +{ + LV_ASSERT(dest_px_size == 3 || dest_px_size == 4); + LV_ASSERT(src_px_size == 3 || src_px_size == 4); + LV_ASSERT(dsc->opa >= LV_OPA_MAX); + LV_ASSERT_NULL(dsc->mask_buf); + const int32_t w = dsc->dest_w; + const int32_t h = dsc->dest_h; + const int32_t dest_stride = dsc->dest_stride; + const int32_t src_stride = dsc->src_stride; + const int32_t mask_stride = dsc->mask_stride; + const uint8_t * mask_buf_8 = dsc->mask_buf; + + /* Fallback to sw implementation*/ + if(dest_px_size != src_px_size) { + return LV_RESULT_INVALID; + } + + if(dest_px_size == 3) { + uint8_t * dest_buf_8 = dsc->dest_buf; + const uint8_t * src_buf_8 = dsc->src_buf; + for(int32_t y = 0; y < h; y++) { + uint8_t * row_ptr = dest_buf_8; + const uint8_t * src_row_ptr = src_buf_8; + const uint8_t * mask_row_ptr = mask_buf_8; + + int32_t x = 0; + for(; x < w - 15; x += 16) { + const uint8x16_t mask_16 = vld1q_u8(&mask_row_ptr[x]); + uint8x16x3_t src = vld3q_u8(&src_row_ptr[x * 3]); + uint8x16x3_t dst = vld3q_u8(&row_ptr[x * 3]); + vst3q_u8(&row_ptr[x * 3], rgb_mix_8_internal(src, dst, mask_16)); + } + for(; x < w - 7; x += 8) { + const uint8x8_t mask = vld1_u8(&mask_row_ptr[x]); + uint8x8x3_t src = vld3_u8(&src_row_ptr[x * 3]); + uint8x8x3_t dst = vld3_u8(&row_ptr[x * 3]); + vst3_u8(&row_ptr[x * 3], rgb_mix_4_internal(src, dst, mask)); + } + for(; x < w; x ++) { + lv_color_24_24_mix_1(&src_row_ptr[x * 3], &row_ptr[x * 3], mask_row_ptr[x]); + } + dest_buf_8 = drawbuf_next_row(dest_buf_8, dest_stride); + src_buf_8 = drawbuf_next_row(src_buf_8, src_stride); + mask_buf_8 = drawbuf_next_row(mask_buf_8, mask_stride); + } + + } + else if(dest_px_size == 4) { + uint32_t * dest_buf_32 = dsc->dest_buf; + const uint32_t * src_buf_32 = dsc->src_buf; + + for(int32_t y = 0; y < h; y++) { + uint32_t * row_ptr = dest_buf_32; + const uint32_t * src_row_ptr = src_buf_32; + const uint8_t * mask_row_ptr = mask_buf_8; + int32_t x = 0; + for(; x < w - 3; x += 4) { + const uint32x4_t mask_4 = {mask_row_ptr[x], mask_row_ptr[x + 1], mask_row_ptr[x + 2], mask_row_ptr[x + 3]}; + uint32x4_t src = vld1q_u32(&src_row_ptr[x]); + uint32x4_t dst = vld1q_u32(&row_ptr[x]); + vst1q_u32(&row_ptr[x], lv_color_24_24_mix_4_internal(src, dst, mask_4)); + } + for(; x < w - 1; x += 2) { + const uint32x2_t mask_2 = {mask_row_ptr[x], mask_row_ptr[x + 1]}; + uint32x2_t src = vld1_u32(&src_row_ptr[x]); + uint32x2_t dst = vld1_u32(&row_ptr[x]); + vst1_u32(&row_ptr[x], lv_color_24_24_mix_2_internal(src, dst, mask_2)); + } + for(; x < w; x ++) { + lv_color_24_24_mix_1((uint8_t *)&src_row_ptr[x], (uint8_t *)&row_ptr[x], mask_row_ptr[x]); + } + dest_buf_32 = drawbuf_next_row(dest_buf_32, dest_stride); + src_buf_32 = drawbuf_next_row(src_buf_32, src_stride); + mask_buf_8 = drawbuf_next_row(mask_buf_8, mask_stride); + } + } + return LV_RESULT_OK; +} +lv_result_t lv_draw_sw_blend_neon_rgb888_to_rgb888_with_opa_mask(lv_draw_sw_blend_image_dsc_t * dsc, + uint32_t dest_px_size, uint32_t src_px_size) +{ + LV_ASSERT(dest_px_size == 3 || dest_px_size == 4); + LV_ASSERT(src_px_size == 3 || src_px_size == 4); + LV_ASSERT(dsc->opa < LV_OPA_MAX); + LV_ASSERT_NULL(dsc->mask_buf); + const int32_t w = dsc->dest_w; + const int32_t h = dsc->dest_h; + const int32_t dest_stride = dsc->dest_stride; + const int32_t src_stride = dsc->src_stride; + const int32_t mask_stride = dsc->src_stride; + const uint8_t opa = dsc->opa; + const uint8_t * mask_buf_8 = dsc->mask_buf; + + /* Fallback to sw implementation*/ + if(dest_px_size != src_px_size) { + return LV_RESULT_INVALID; + } + + if(dest_px_size == 3) { + const uint8x16_t opa_16 = vdupq_n_u8(dsc->opa); + const uint8x8_t opa_8 = vdup_n_u8(dsc->opa); + uint8_t * dest_buf_8 = dsc->dest_buf; + const uint8_t * src_buf_8 = dsc->src_buf; + for(int32_t y = 0; y < h; y++) { + uint8_t * row_ptr = dest_buf_8; + const uint8_t * src_row_ptr = src_buf_8; + const uint8_t * mask_row_ptr = mask_buf_8; + + int32_t x = 0; + for(; x < w - 15; x += 16) { + const uint8x16_t mask_16 = vld1q_u8(&mask_row_ptr[x]); + const uint8x8_t opa_lo = vget_low_u8(opa_16); + const uint8x8_t opa_hi = vget_high_u8(opa_16); + const uint8x8_t mask_lo = vget_low_u8(mask_16); + const uint8x8_t mask_hi = vget_high_u8(mask_16); + const uint16x8_t result_lo_wide = vmull_u8(opa_lo, mask_lo); + const uint16x8_t result_hi_wide = vmull_u8(opa_hi, mask_hi); + const uint8x8_t result_lo = vshrn_n_u16(result_lo_wide, 8); + const uint8x8_t result_hi = vshrn_n_u16(result_hi_wide, 8); + const uint8x16_t mix = vcombine_u8(result_lo, result_hi); + uint8x16x3_t src = vld3q_u8(&src_row_ptr[x * 3]); + uint8x16x3_t dst = vld3q_u8(&row_ptr[x * 3]); + vst3q_u8(&row_ptr[x * 3], rgb_mix_8_internal(src, dst, mix)); + } + for(; x < w - 7; x += 8) { + const uint8x8_t mask = vld1_u8(&mask_row_ptr[x]); + const uint16x8_t mult = vmull_u8(opa_8, mask); + const uint8x8_t mix = vshrn_n_u16(mult, 8); + uint8x8x3_t src = vld3_u8(&src_row_ptr[x * 3]); + uint8x8x3_t dst = vld3_u8(&row_ptr[x * 3]); + vst3_u8(&row_ptr[x * 3], rgb_mix_4_internal(src, dst, mix)); + } + for(; x < w; x ++) { + lv_color_24_24_mix_1(&src_row_ptr[x * 3], &row_ptr[x * 3], LV_OPA_MIX2(opa, mask_row_ptr[x])); + } + dest_buf_8 = drawbuf_next_row(dest_buf_8, dest_stride); + src_buf_8 = drawbuf_next_row(src_buf_8, src_stride); + mask_buf_8 = drawbuf_next_row(mask_buf_8, mask_stride); + } + + } + else if(dest_px_size == 4) { + uint32_t * dest_buf_32 = dsc->dest_buf; + const uint32_t * src_buf_32 = dsc->src_buf; + const uint32x4_t opa_4 = vdupq_n_u32((uint32_t)dsc->opa); + const uint32x2_t opa_2 = vdup_n_u32((uint32_t)dsc->opa); + + for(int32_t y = 0; y < h; y++) { + uint32_t * row_ptr = dest_buf_32; + const uint32_t * src_row_ptr = src_buf_32; + const uint8_t * mask_row_ptr = mask_buf_8; + int32_t x = 0; + for(; x < w - 3; x += 4) { + const uint32x4_t mask_4 = {mask_row_ptr[x], mask_row_ptr[x + 1], mask_row_ptr[x + 2], mask_row_ptr[x + 3]}; + const uint32x4_t mix_4 = vshrq_n_u32(vmulq_u32(opa_4, mask_4), 8); + uint32x4_t src = vld1q_u32(&src_row_ptr[x]); + uint32x4_t dst = vld1q_u32(&row_ptr[x]); + vst1q_u32(&row_ptr[x], lv_color_24_24_mix_4_internal(src, dst, mix_4)); + } + for(; x < w - 1; x += 2) { + const uint32x2_t mask_2 = {mask_row_ptr[x], mask_row_ptr[x + 1]}; + const uint32x2_t mix_2 = vshr_n_u32(vmul_u32(opa_2, mask_2), 8); + uint32x2_t src = vld1_u32(&src_row_ptr[x]); + uint32x2_t dst = vld1_u32(&row_ptr[x]); + vst1_u32(&row_ptr[x], lv_color_24_24_mix_2_internal(src, dst, mix_2)); + } + for(; x < w; x ++) { + lv_color_24_24_mix_1((uint8_t *)&src_row_ptr[x], (uint8_t *)&row_ptr[x], LV_OPA_MIX2(opa, mask_row_ptr[x])); + } + dest_buf_32 = drawbuf_next_row(dest_buf_32, dest_stride); + src_buf_32 = drawbuf_next_row(src_buf_32, src_stride); + mask_buf_8 = drawbuf_next_row(mask_buf_8, mask_stride); + } + } + return LV_RESULT_OK; +} + +lv_result_t lv_draw_sw_blend_neon_argb888_to_rgb888(lv_draw_sw_blend_image_dsc_t * dsc, uint32_t dest_px_size) +{ + LV_ASSERT(dsc->opa >= LV_OPA_MAX); + LV_ASSERT(dsc->mask_buf == NULL); + LV_ASSERT(dest_px_size == 3 || dest_px_size == 4); + int32_t w = dsc->dest_w; + int32_t h = dsc->dest_h; + int32_t dest_stride = dsc->dest_stride; + int32_t src_stride = dsc->src_stride; + + /* Fallback to sw implementation*/ + if(dest_px_size == 3) { + return LV_RESULT_INVALID; + } + else if(dest_px_size == 4) { + uint32_t * dest_buf_u32 = dsc->dest_buf; + const uint32_t * src_buf_u32 = dsc->src_buf; + for(int32_t y = 0; y < h; y++) { + int32_t x = 0; + for(; x < w - 3; x += 4) { + vst1q_u32(&dest_buf_u32[x], argb_rgb_mix_4(&src_buf_u32[x], &dest_buf_u32[x])); + } + for(; x < w - 1; x += 2) { + vst1_u32(&dest_buf_u32[x], argb_rgb_mix_2(&src_buf_u32[x], &dest_buf_u32[x])); + } + for(; x < w; x++) { + lv_color_24_24_mix_1((uint8_t *)&src_buf_u32[x], (uint8_t *)&dest_buf_u32[x], + ((uint8_t *)src_buf_u32)[x * sizeof(uint32_t) + 3]); + } + src_buf_u32 = drawbuf_next_row(src_buf_u32, src_stride); + dest_buf_u32 = drawbuf_next_row(dest_buf_u32, dest_stride); + } + + } + return LV_RESULT_OK; +} + +lv_result_t lv_draw_sw_blend_neon_argb888_to_rgb888_with_opa(lv_draw_sw_blend_image_dsc_t * dsc, uint32_t dest_px_size) +{ + LV_ASSERT(dest_px_size == 3 || dest_px_size == 4); + LV_ASSERT(dsc->opa < LV_OPA_MAX); + LV_ASSERT(dsc->mask_buf == NULL); + const int32_t w = dsc->dest_w; + const int32_t h = dsc->dest_h; + const int32_t dest_stride = dsc->dest_stride; + const int32_t src_stride = dsc->src_stride; + const uint8_t opa = dsc->opa; + + /* Fallback to sw implementation*/ + if(dest_px_size == 3) { + return LV_RESULT_INVALID; + } + else if(dest_px_size == 4) { + uint32_t * dest_buf_u32 = dsc->dest_buf; + const uint32_t * src_buf_u32 = dsc->src_buf; + const uint32x4_t opa_4 = vdupq_n_u32((uint32_t)dsc->opa); + const uint32x2_t opa_2 = vdup_n_u32((uint32_t)dsc->opa); + for(int32_t y = 0; y < h; y++) { + int32_t x = 0; + for(; x < w - 3; x += 4) { + vst1q_u32(&dest_buf_u32[x], argb_rgb_mix_4_with_opa(&src_buf_u32[x], &dest_buf_u32[x], opa_4)); + } + for(; x < w - 1; x += 2) { + vst1_u32(&dest_buf_u32[x], argb_rgb_mix_2_with_opa(&src_buf_u32[x], &dest_buf_u32[x], opa_2)); + } + for(; x < w; x++) { + uint8_t alpha = ((uint8_t *)src_buf_u32)[x * sizeof(uint32_t) + 3]; + lv_color_24_24_mix_1((uint8_t *)&src_buf_u32[x], (uint8_t *)&dest_buf_u32[x], + LV_OPA_MIX2(alpha, opa)); + } + src_buf_u32 = drawbuf_next_row(src_buf_u32, src_stride); + dest_buf_u32 = drawbuf_next_row(dest_buf_u32, dest_stride); + } + } + return LV_RESULT_OK; +} +lv_result_t lv_draw_sw_blend_neon_argb888_to_rgb888_with_mask(lv_draw_sw_blend_image_dsc_t * dsc, uint32_t dest_px_size) +{ + LV_ASSERT(dest_px_size == 3 || dest_px_size == 4); + LV_ASSERT(dsc->opa >= LV_OPA_MAX); + LV_ASSERT_NULL(dsc->mask_buf); + const int32_t w = dsc->dest_w; + const int32_t h = dsc->dest_h; + const int32_t dest_stride = dsc->dest_stride; + const int32_t src_stride = dsc->src_stride; + const uint8_t * mask_buf_8 = dsc->mask_buf; + const int32_t mask_stride = dsc->mask_stride; + + /* Fallback to sw implementation*/ + if(dest_px_size == 3) { + return LV_RESULT_INVALID; + } + else if(dest_px_size == 4) { + uint32_t * dest_buf_u32 = dsc->dest_buf; + const uint32_t * src_buf_u32 = dsc->src_buf; + const uint8_t * mask_row_ptr = mask_buf_8; + for(int32_t y = 0; y < h; y++) { + int32_t x = 0; + for(; x < w - 3; x += 4) { + const uint32x4_t mask_4 = {mask_row_ptr[x], mask_row_ptr[x + 1], mask_row_ptr[x + 2], mask_row_ptr[x + 3]}; + vst1q_u32(&dest_buf_u32[x], argb_rgb_mix_4_with_opa(&src_buf_u32[x], &dest_buf_u32[x], mask_4)); + } + for(; x < w - 1; x += 2) { + const uint32x2_t mask_2 = {mask_row_ptr[x], mask_row_ptr[x + 1]}; + vst1_u32(&dest_buf_u32[x], argb_rgb_mix_2_with_opa(&src_buf_u32[x], &dest_buf_u32[x], mask_2)); + } + for(; x < w; x++) { + uint8_t alpha = ((uint8_t *)src_buf_u32)[x * sizeof(uint32_t) + 3]; + lv_color_24_24_mix_1((uint8_t *)&src_buf_u32[x], (uint8_t *)&dest_buf_u32[x], + LV_OPA_MIX2(alpha, mask_row_ptr[x])); + } + src_buf_u32 = drawbuf_next_row(src_buf_u32, src_stride); + dest_buf_u32 = drawbuf_next_row(dest_buf_u32, dest_stride); + mask_buf_8 = drawbuf_next_row(mask_buf_8, mask_stride); + } + } + return LV_RESULT_OK; +} +lv_result_t lv_draw_sw_blend_neon_argb888_to_rgb888_with_opa_mask(lv_draw_sw_blend_image_dsc_t * dsc, + uint32_t dest_px_size) +{ + LV_ASSERT(dest_px_size == 3 || dest_px_size == 4); + LV_ASSERT(dsc->opa < LV_OPA_MAX); + LV_ASSERT_NULL(dsc->mask_buf); + const int32_t w = dsc->dest_w; + const int32_t h = dsc->dest_h; + const int32_t dest_stride = dsc->dest_stride; + const int32_t src_stride = dsc->src_stride; + const uint8_t * mask_buf_8 = dsc->mask_buf; + const int32_t mask_stride = dsc->mask_stride; + + /* Fallback to sw implementation*/ + if(dest_px_size == 3) { + return LV_RESULT_INVALID; + } + else if(dest_px_size == 4) { + uint32_t * dest_buf_u32 = dsc->dest_buf; + const uint32_t * src_buf_u32 = dsc->src_buf; + const uint8_t * mask_row_ptr = mask_buf_8; + const uint32x4_t opa_4 = vdupq_n_u32((uint32_t)dsc->opa); + const uint32x2_t opa_2 = vdup_n_u32((uint32_t)dsc->opa); + for(int32_t y = 0; y < h; y++) { + int32_t x = 0; + for(; x < w - 3; x += 4) { + const uint32x4_t mask_4 = {mask_row_ptr[x], mask_row_ptr[x + 1], mask_row_ptr[x + 2], mask_row_ptr[x + 3]}; + vst1q_u32(&dest_buf_u32[x], argb_rgb_mix_4_with_opa_mask(&src_buf_u32[x], &dest_buf_u32[x], opa_4, mask_4)); + } + for(; x < w - 1; x += 2) { + const uint32x2_t mask_2 = {mask_row_ptr[x], mask_row_ptr[x + 1]}; + vst1_u32(&dest_buf_u32[x], argb_rgb_mix_2_with_opa_mask(&src_buf_u32[x], &dest_buf_u32[x], opa_2, mask_2)); + } + for(; x < w; x++) { + uint8_t alpha = ((uint8_t *)src_buf_u32)[x * sizeof(uint32_t) + 3]; + lv_color_24_24_mix_1((uint8_t *)&src_buf_u32[x], (uint8_t *)&dest_buf_u32[x], + LV_OPA_MIX2(alpha, mask_row_ptr[x])); + } + src_buf_u32 = drawbuf_next_row(src_buf_u32, src_stride); + dest_buf_u32 = drawbuf_next_row(dest_buf_u32, dest_stride); + mask_buf_8 = drawbuf_next_row(mask_buf_8, mask_stride); + } + } + return LV_RESULT_OK; +} + +#if LV_DRAW_SW_SUPPORT_ARGB8888_PREMULTIPLIED +lv_result_t lv_draw_sw_blend_neon_argb888_premultiplied_to_rgb888(lv_draw_sw_blend_image_dsc_t * dsc, + uint32_t dest_px_size) +{ + LV_ASSERT(dsc->opa >= LV_OPA_MAX); + LV_ASSERT(dsc->mask_buf == NULL); + LV_ASSERT(dest_px_size == 3 || dest_px_size == 4); + int32_t w = dsc->dest_w; + int32_t h = dsc->dest_h; + int32_t dest_stride = dsc->dest_stride; + int32_t src_stride = dsc->src_stride; + + /* Fallback to sw implementation*/ + if(dest_px_size == 3) { + return LV_RESULT_INVALID; + } + else if(dest_px_size == 4) { + uint32_t * dest_buf_u32 = dsc->dest_buf; + const uint32_t * src_buf_u32 = dsc->src_buf; + for(int32_t y = 0; y < h; y++) { + int32_t x = 0; + for(; x < w - 3; x += 4) { + uint32x4_t src_pixels = vld1q_u32(&src_buf_u32[x]); + uint32x4_t dst_pixels = vld1q_u32(&dest_buf_u32[x]); + uint32x4_t alpha = vshrq_n_u32(src_pixels, 24); + vst1q_u32(&dest_buf_u32[x], lv_color_24_24_mix_4_premul_internal(src_pixels, dst_pixels, alpha)); + } + for(; x < w - 1; x += 2) { + uint32x2_t src_pixels = vld1_u32(&src_buf_u32[x]); + uint32x2_t dst_pixels = vld1_u32(&dest_buf_u32[x]); + uint32x2_t alpha = vshr_n_u32(src_pixels, 24); + vst1_u32(&dest_buf_u32[x], lv_color_24_24_mix_2_premul_internal(src_pixels, dst_pixels, alpha)); + } + for(; x < w; x++) { + lv_color_24_24_mix_premult((uint8_t *)&src_buf_u32[x], (uint8_t *)&dest_buf_u32[x], + ((uint8_t *)src_buf_u32)[x * sizeof(uint32_t) + 3]); + } + src_buf_u32 = drawbuf_next_row(src_buf_u32, src_stride); + dest_buf_u32 = drawbuf_next_row(dest_buf_u32, dest_stride); + } + + } + return LV_RESULT_OK; +} +#endif + +/********************** + * STATIC FUNCTIONS + **********************/ + + +static inline void * LV_ATTRIBUTE_FAST_MEM drawbuf_next_row(const void * buf, uint32_t stride) +{ + return (void *)((uint8_t *)buf + stride); +} + +static inline uint8x16x3_t lv_color_to_rgb888_16(const lv_color_t * color) +{ + const uint8x16_t r_vec = vdupq_n_u8(color->red); + const uint8x16_t g_vec = vdupq_n_u8(color->green); + const uint8x16_t b_vec = vdupq_n_u8(color->blue); + uint8x16x3_t rgb_data; + rgb_data.val[0] = b_vec; + rgb_data.val[1] = g_vec; + rgb_data.val[2] = r_vec; + return rgb_data; +} + +static inline uint8x8x3_t lv_color_to_rgb888_8(const lv_color_t * color) +{ + const uint8x8_t r_vec = vdup_n_u8(color->red); + const uint8x8_t g_vec = vdup_n_u8(color->green); + const uint8x8_t b_vec = vdup_n_u8(color->blue); + uint8x8x3_t rgb_data; + rgb_data.val[0] = b_vec; + rgb_data.val[1] = g_vec; + rgb_data.val[2] = r_vec; + return rgb_data; +} + +static inline uint8x16x4_t lv_color_to_xrgb888_16(const lv_color_t * color) +{ + const uint8x16_t r_vec = vdupq_n_u8(color->red); + const uint8x16_t g_vec = vdupq_n_u8(color->green); + const uint8x16_t b_vec = vdupq_n_u8(color->blue); + const uint8x16_t a_vec = vdupq_n_u8(0xFF); + uint8x16x4_t rgb_data; + rgb_data.val[0] = b_vec; + rgb_data.val[1] = g_vec; + rgb_data.val[2] = r_vec; + rgb_data.val[3] = a_vec; + return rgb_data; +} + +static inline uint8x8x4_t lv_color_to_xrgb888_8(const lv_color_t * color) +{ + const uint8x8_t r_vec = vdup_n_u8(color->red); + const uint8x8_t g_vec = vdup_n_u8(color->green); + const uint8x8_t b_vec = vdup_n_u8(color->blue); + const uint8x8_t a_vec = vdup_n_u8(0xFF); + uint8x8x4_t rgb_data; + rgb_data.val[0] = b_vec; + rgb_data.val[1] = g_vec; + rgb_data.val[2] = r_vec; + rgb_data.val[3] = a_vec; + return rgb_data; +} + +static inline uint8x16_t lv_color_to_xrgb888_4(const lv_color_t * color) +{ + uint32_t pixel_value = (0xFF << 24) | (color->red << 16) | (color->green << 8) | color->blue; + return vreinterpretq_u8_u32(vdupq_n_u32(pixel_value)); +} + +static inline uint8x8_t lv_color_to_xrgb888_2(const lv_color_t * color) +{ + uint32_t pixel_value = (0xFF << 24) | (color->red << 16) | (color->green << 8) | color->blue; + return vreinterpret_u8_u32(vdup_n_u32(pixel_value)); +} + +static inline uint8x8x3_t lv_rgb565_to_rgb888_8(const uint16_t * color) +{ + const uint16x8_t pixels = vld1q_u16(color); + + const uint16x8_t blue_mask = vdupq_n_u16(0x001F); + const uint16x8_t green_mask = vdupq_n_u16(0x07E0); + const uint16x8_t red_mask = vdupq_n_u16(0xF800); + + const uint16x8_t rb_multiplier = vdupq_n_u16(2106); + const uint16x8_t g_multiplier = vdupq_n_u16(1037); + + const uint16x8_t r5 = vshrq_n_u16(vandq_u16(pixels, red_mask), 11); + const uint16x8_t g6 = vshrq_n_u16(vandq_u16(pixels, green_mask), 5); + const uint16x8_t b5 = vandq_u16(pixels, blue_mask); + + const uint8x8_t r8 = vmovn_u16(vshrq_n_u16(vmulq_u16(r5, rb_multiplier), 8)); + const uint8x8_t g8 = vmovn_u16(vshrq_n_u16(vmulq_u16(g6, g_multiplier), 8)); + const uint8x8_t b8 = vmovn_u16(vshrq_n_u16(vmulq_u16(b5, rb_multiplier), 8)); + + uint8x8x3_t rgb; + rgb.val[0] = b8; + rgb.val[1] = g8; + rgb.val[2] = r8; + return rgb; +} +static inline uint8x8x4_t lv_rgb565_to_xrgb8888_8(const uint16_t * color) +{ + const uint16x8_t pixels = vld1q_u16(color); + + const uint16x8_t blue_mask = vdupq_n_u16(0x001F); + const uint16x8_t green_mask = vdupq_n_u16(0x07E0); + const uint16x8_t red_mask = vdupq_n_u16(0xF800); + + const uint16x8_t rb_multiplier = vdupq_n_u16(2106); + const uint16x8_t g_multiplier = vdupq_n_u16(1037); + + const uint16x8_t r5 = vshrq_n_u16(vandq_u16(pixels, red_mask), 11); + const uint16x8_t g6 = vshrq_n_u16(vandq_u16(pixels, green_mask), 5); + const uint16x8_t b5 = vandq_u16(pixels, blue_mask); + + const uint8x8_t r8 = vmovn_u16(vshrq_n_u16(vmulq_u16(r5, rb_multiplier), 8)); + const uint8x8_t g8 = vmovn_u16(vshrq_n_u16(vmulq_u16(g6, g_multiplier), 8)); + const uint8x8_t b8 = vmovn_u16(vshrq_n_u16(vmulq_u16(b5, rb_multiplier), 8)); + + uint8x8x4_t rgb; + rgb.val[0] = b8; + rgb.val[1] = g8; + rgb.val[2] = r8; + return rgb; +} + +static inline void rgb565_mix_1(const uint16_t * src, uint8_t * dest, uint8_t mix) +{ + if(mix == 0) { + return; + } + const uint32_t b = ((src[0] & 0x001F) * 2106) >> 8; + const uint32_t g = (((src[0] & 0x07E0) >> 5) * 1037) >> 8; + const uint32_t r = (((src[0] & 0xF800) >> 11) * 2106) >> 8; + if(mix >= LV_OPA_MAX) { + dest[0] = b; + dest[1] = g; + dest[2] = r; + return; + } + const lv_opa_t mix_inv = 255 - mix; + dest[0] = (uint32_t)(b * mix + dest[0] * mix_inv) >> 8; + dest[1] = (uint32_t)(g * mix + dest[1] * mix_inv) >> 8; + dest[2] = (uint32_t)(r * mix + dest[2] * mix_inv) >> 8; + + +} + +static inline void lv_color_24_24_mix_1(const uint8_t * src, uint8_t * dest, uint8_t mix) +{ + if(mix == 0) { + return; + } + + if(mix >= LV_OPA_MAX) { + dest[0] = src[0]; + dest[1] = src[1]; + dest[2] = src[2]; + return; + } + const lv_opa_t mix_inv = 255 - mix; + dest[0] = (uint32_t)((uint32_t)src[0] * mix + dest[0] * mix_inv) >> 8; + dest[1] = (uint32_t)((uint32_t)src[1] * mix + dest[1] * mix_inv) >> 8; + dest[2] = (uint32_t)((uint32_t)src[2] * mix + dest[2] * mix_inv) >> 8; +} + +static inline void lv_color_24_24_mix_premult(const uint8_t * src, uint8_t * dest, uint8_t mix) +{ + if(mix == 0) return; + + if(mix >= LV_OPA_MAX) { + dest[0] = src[0]; + dest[1] = src[1]; + dest[2] = src[2]; + } + else { + lv_opa_t mix_inv = 255 - mix; + dest[0] = (uint32_t)src[0] + ((uint32_t)(dest[0] * mix_inv) >> 8); + dest[1] = (uint32_t)src[1] + ((uint32_t)(dest[1] * mix_inv) >> 8); + dest[2] = (uint32_t)src[2] + ((uint32_t)(dest[2] * mix_inv) >> 8); + } +} + + +static inline uint32x4_t argb_rgb_mix_4(const uint32_t * src, const uint32_t * dst) +{ + uint32x4_t src_pixels = vld1q_u32(src); + uint32x4_t dst_pixels = vld1q_u32(dst); + + uint32x4_t alpha = vshrq_n_u32(src_pixels, 24); + return lv_color_24_24_mix_4_internal(src_pixels, dst_pixels, alpha); +} +static inline uint32x2_t argb_rgb_mix_2(const uint32_t * src, const uint32_t * dst) +{ + uint32x2_t src_pixels = vld1_u32(src); + uint32x2_t dst_pixels = vld1_u32(dst); + uint32x2_t alpha = vshr_n_u32(src_pixels, 24); + return lv_color_24_24_mix_2_internal(src_pixels, dst_pixels, alpha); +} + +static inline uint32x4_t argb_rgb_mix_4_with_opa(const uint32_t * src, const uint32_t * dst, uint32x4_t opa) +{ + uint32x4_t src_pixels = vld1q_u32(src); + uint32x4_t dst_pixels = vld1q_u32(dst); + + uint32x4_t alpha = vshrq_n_u32(src_pixels, 24); + uint32x4_t mix = vshrq_n_u32(vmulq_u32(alpha, opa), 8); + return lv_color_24_24_mix_4_internal(src_pixels, dst_pixels, mix); +} +static inline uint32x2_t argb_rgb_mix_2_with_opa(const uint32_t * src, const uint32_t * dst, uint32x2_t opa) +{ + uint32x2_t src_pixels = vld1_u32(src); + uint32x2_t dst_pixels = vld1_u32(dst); + uint32x2_t alpha = vshr_n_u32(src_pixels, 24); + uint32x2_t mix = vshr_n_u32(vmul_u32(alpha, opa), 8); + return lv_color_24_24_mix_2_internal(src_pixels, dst_pixels, mix); +} +static inline uint32x4_t argb_rgb_mix_4_with_opa_mask(const uint32_t * src, const uint32_t * dst, uint32x4_t opa, + uint32x4_t mask) +{ + uint32x4_t src_pixels = vld1q_u32(src); + uint32x4_t dst_pixels = vld1q_u32(dst); + + uint32x4_t alpha = vshrq_n_u32(src_pixels, 24); + uint32x4_t mix = vshrq_n_u32(vmulq_u32(alpha, vmulq_u32(opa, mask)), 16); + return lv_color_24_24_mix_4_internal(src_pixels, dst_pixels, mix); +} + +static inline uint32x2_t argb_rgb_mix_2_with_opa_mask(const uint32_t * src, const uint32_t * dst, uint32x2_t opa, + uint32x2_t mask) +{ + uint32x2_t src_pixels = vld1_u32(src); + uint32x2_t dst_pixels = vld1_u32(dst); + uint32x2_t alpha = vshr_n_u32(src_pixels, 24); + uint32x2_t mix = vshr_n_u32(vmul_u32(alpha, vmul_u32(opa, mask)), 16); + return lv_color_24_24_mix_2_internal(src_pixels, dst_pixels, mix); +} + +static inline uint8x8x3_t rgb565_rgb888_mix_8_internal(uint16x8_t src, uint8x8x3_t dst, uint8x8_t mix) +{ + uint8x8_t zero_mask = vceq_u8(mix, vdup_n_u8(0)); + uint8x8_t full_mask = vcge_u8(mix, vdup_n_u8(LV_OPA_MAX)); + uint8x8_t inv_mix = vsub_u8(vdup_n_u8(255), mix); + + uint8x8_t src_r = vqmovn_u16(vshrq_n_u16(vmulq_u16(vshrq_n_u16(vandq_u16(src, vdupq_n_u16(0xF800)), 11), + vdupq_n_u16(2106)), 8)); + uint8x8_t src_g = vqmovn_u16(vshrq_n_u16(vmulq_u16(vshrq_n_u16(vandq_u16(src, vdupq_n_u16(0x07E0)), 5), + vdupq_n_u16(1037)), 8)); + uint8x8_t src_b = vqmovn_u16(vshrq_n_u16(vmulq_u16(vandq_u16(src, vdupq_n_u16(0x001F)), vdupq_n_u16(2106)), 8)); + + uint8x8_t dst_b = dst.val[0]; + uint8x8_t dst_g = dst.val[1]; + uint8x8_t dst_r = dst.val[2]; + + uint16x8_t blend_r_wide = vaddq_u16(vmull_u8(src_r, mix), vmull_u8(dst_r, inv_mix)); + uint16x8_t blend_g_wide = vaddq_u16(vmull_u8(src_g, mix), vmull_u8(dst_g, inv_mix)); + uint16x8_t blend_b_wide = vaddq_u16(vmull_u8(src_b, mix), vmull_u8(dst_b, inv_mix)); + + uint8x8_t blend_r = vshrn_n_u16(blend_r_wide, 8); + uint8x8_t blend_g = vshrn_n_u16(blend_g_wide, 8); + uint8x8_t blend_b = vshrn_n_u16(blend_b_wide, 8); + + uint8x8_t result_r = vbsl_u8(zero_mask, dst_r, blend_r); + result_r = vbsl_u8(full_mask, src_r, result_r); + + uint8x8_t result_g = vbsl_u8(zero_mask, dst_g, blend_g); + result_g = vbsl_u8(full_mask, src_g, result_g); + + uint8x8_t result_b = vbsl_u8(zero_mask, dst_b, blend_b); + result_b = vbsl_u8(full_mask, src_b, result_b); + + uint8x8x3_t result = {{ result_b, result_g, result_r }}; + return result; +} + +static inline uint8x16x3_t rgb_mix_8_internal(uint8x16x3_t src, uint8x16x3_t dst, uint8x16_t mix) +{ + uint8x16_t zero_mask = vceqq_u8(mix, vdupq_n_u8(0)); + uint8x16_t full_mask = vcgeq_u8(mix, vdupq_n_u8(LV_OPA_MAX)); + uint8x16_t inv_mix = vsubq_u8(vdupq_n_u8(255), mix); + + uint8x8_t mix_lo = vget_low_u8(mix); + uint8x8_t mix_hi = vget_high_u8(mix); + uint8x8_t inv_mix_lo = vget_low_u8(inv_mix); + uint8x8_t inv_mix_hi = vget_high_u8(inv_mix); + + uint8x8_t src_r_lo = vget_low_u8(src.val[0]); + uint8x8_t src_r_hi = vget_high_u8(src.val[0]); + uint8x8_t dst_r_lo = vget_low_u8(dst.val[0]); + uint8x8_t dst_r_hi = vget_high_u8(dst.val[0]); + + uint16x8_t blend_r_wide_lo = vaddq_u16(vmull_u8(src_r_lo, mix_lo), vmull_u8(dst_r_lo, inv_mix_lo)); + uint16x8_t blend_r_wide_hi = vaddq_u16(vmull_u8(src_r_hi, mix_hi), vmull_u8(dst_r_hi, inv_mix_hi)); + + uint8x8_t blend_r_lo = vshrn_n_u16(blend_r_wide_lo, 8); + uint8x8_t blend_r_hi = vshrn_n_u16(blend_r_wide_hi, 8); + uint8x16_t blend_r = vcombine_u8(blend_r_lo, blend_r_hi); + + uint8x8_t src_g_lo = vget_low_u8(src.val[1]); + uint8x8_t src_g_hi = vget_high_u8(src.val[1]); + uint8x8_t dst_g_lo = vget_low_u8(dst.val[1]); + uint8x8_t dst_g_hi = vget_high_u8(dst.val[1]); + + uint16x8_t blend_g_wide_lo = vaddq_u16(vmull_u8(src_g_lo, mix_lo), vmull_u8(dst_g_lo, inv_mix_lo)); + uint16x8_t blend_g_wide_hi = vaddq_u16(vmull_u8(src_g_hi, mix_hi), vmull_u8(dst_g_hi, inv_mix_hi)); + + uint8x8_t blend_g_lo = vshrn_n_u16(blend_g_wide_lo, 8); + uint8x8_t blend_g_hi = vshrn_n_u16(blend_g_wide_hi, 8); + uint8x16_t blend_g = vcombine_u8(blend_g_lo, blend_g_hi); + + uint8x8_t src_b_lo = vget_low_u8(src.val[2]); + uint8x8_t src_b_hi = vget_high_u8(src.val[2]); + uint8x8_t dst_b_lo = vget_low_u8(dst.val[2]); + uint8x8_t dst_b_hi = vget_high_u8(dst.val[2]); + + uint16x8_t blend_b_wide_lo = vaddq_u16(vmull_u8(src_b_lo, mix_lo), vmull_u8(dst_b_lo, inv_mix_lo)); + uint16x8_t blend_b_wide_hi = vaddq_u16(vmull_u8(src_b_hi, mix_hi), vmull_u8(dst_b_hi, inv_mix_hi)); + + uint8x8_t blend_b_lo = vshrn_n_u16(blend_b_wide_lo, 8); + uint8x8_t blend_b_hi = vshrn_n_u16(blend_b_wide_hi, 8); + uint8x16_t blend_b = vcombine_u8(blend_b_lo, blend_b_hi); + + uint8x16_t result_r = vbslq_u8(zero_mask, dst.val[0], blend_r); + result_r = vbslq_u8(full_mask, src.val[0], result_r); + + uint8x16_t result_g = vbslq_u8(zero_mask, dst.val[1], blend_g); + result_g = vbslq_u8(full_mask, src.val[1], result_g); + + uint8x16_t result_b = vbslq_u8(zero_mask, dst.val[2], blend_b); + result_b = vbslq_u8(full_mask, src.val[2], result_b); + + uint8x16x3_t result = {{result_r, result_g, result_b}}; + return result; +} + +static inline uint8x8x3_t rgb_mix_4_internal(uint8x8x3_t src, uint8x8x3_t dst, uint8x8_t mix) +{ + uint8x8_t zero_mask = vceq_u8(mix, vdup_n_u8(0)); + uint8x8_t full_mask = vcge_u8(mix, vdup_n_u8(LV_OPA_MAX)); + uint8x8_t inv_mix = vsub_u8(vdup_n_u8(255), mix); + + uint16x8_t blend_r_wide = vaddq_u16(vmull_u8(src.val[0], mix), vmull_u8(dst.val[0], inv_mix)); + uint8x8_t blend_r = vshrn_n_u16(blend_r_wide, 8); + + uint16x8_t blend_g_wide = vaddq_u16(vmull_u8(src.val[1], mix), vmull_u8(dst.val[1], inv_mix)); + uint8x8_t blend_g = vshrn_n_u16(blend_g_wide, 8); + + uint16x8_t blend_b_wide = vaddq_u16(vmull_u8(src.val[2], mix), vmull_u8(dst.val[2], inv_mix)); + uint8x8_t blend_b = vshrn_n_u16(blend_b_wide, 8); + + uint8x8_t result_r = vbsl_u8(zero_mask, dst.val[0], blend_r); + result_r = vbsl_u8(full_mask, src.val[0], result_r); + + uint8x8_t result_g = vbsl_u8(zero_mask, dst.val[1], blend_g); + result_g = vbsl_u8(full_mask, src.val[1], result_g); + + uint8x8_t result_b = vbsl_u8(zero_mask, dst.val[2], blend_b); + result_b = vbsl_u8(full_mask, src.val[2], result_b); + + uint8x8x3_t result = {{result_r, result_g, result_b}}; + return result; +} + +static inline uint32x4_t lv_color_24_24_mix_4_internal(uint32x4_t src, uint32x4_t dst, uint32x4_t mix) +{ + uint32x4_t zero_mask = vceqq_u32(mix, vdupq_n_u32(0)); + uint32x4_t full_mask = vcgeq_u32(mix, vdupq_n_u32(LV_OPA_MAX)); + + uint32x4_t src_r = vandq_u32(vshrq_n_u32(src, 16), vdupq_n_u32(0xFF)); + uint32x4_t src_g = vandq_u32(vshrq_n_u32(src, 8), vdupq_n_u32(0xFF)); + uint32x4_t src_b = vandq_u32(src, vdupq_n_u32(0xFF)); + + uint32x4_t dst_r = vandq_u32(vshrq_n_u32(dst, 16), vdupq_n_u32(0xFF)); + uint32x4_t dst_g = vandq_u32(vshrq_n_u32(dst, 8), vdupq_n_u32(0xFF)); + uint32x4_t dst_b = vandq_u32(dst, vdupq_n_u32(0xFF)); + + uint32x4_t inv_mix = vsubq_u32(vdupq_n_u32(255), mix); + uint32x4_t blend_r = vshrq_n_u32(vaddq_u32(vmulq_u32(src_r, mix), vmulq_u32(dst_r, inv_mix)), 8); + uint32x4_t blend_g = vshrq_n_u32(vaddq_u32(vmulq_u32(src_g, mix), vmulq_u32(dst_g, inv_mix)), 8); + uint32x4_t blend_b = vshrq_n_u32(vaddq_u32(vmulq_u32(src_b, mix), vmulq_u32(dst_b, inv_mix)), 8); + + uint32x4_t blended = vorrq_u32(vorrq_u32(vshlq_n_u32(blend_r, 16), vshlq_n_u32(blend_g, 8)), blend_b); + uint32x4_t result = vbslq_u32(zero_mask, dst, blended); + return vbslq_u32(full_mask, src, result); +} + +static inline uint32x2_t lv_color_24_24_mix_2_internal(uint32x2_t src, uint32x2_t dst, uint32x2_t mix) +{ + uint32x2_t zero_mask = vceq_u32(mix, vdup_n_u32(0)); + uint32x2_t full_mask = vcge_u32(mix, vdup_n_u32(LV_OPA_MAX)); + + uint32x2_t src_r = vand_u32(vshr_n_u32(src, 16), vdup_n_u32(0xFF)); + uint32x2_t src_g = vand_u32(vshr_n_u32(src, 8), vdup_n_u32(0xFF)); + uint32x2_t src_b = vand_u32(src, vdup_n_u32(0xFF)); + + uint32x2_t dst_r = vand_u32(vshr_n_u32(dst, 16), vdup_n_u32(0xFF)); + uint32x2_t dst_g = vand_u32(vshr_n_u32(dst, 8), vdup_n_u32(0xFF)); + uint32x2_t dst_b = vand_u32(dst, vdup_n_u32(0xFF)); + + uint32x2_t inv_mix = vsub_u32(vdup_n_u32(255), mix); + uint32x2_t blend_r = vshr_n_u32(vadd_u32(vmul_u32(src_r, mix), vmul_u32(dst_r, inv_mix)), 8); + uint32x2_t blend_g = vshr_n_u32(vadd_u32(vmul_u32(src_g, mix), vmul_u32(dst_g, inv_mix)), 8); + uint32x2_t blend_b = vshr_n_u32(vadd_u32(vmul_u32(src_b, mix), vmul_u32(dst_b, inv_mix)), 8); + + uint32x2_t blended = vorr_u32(vorr_u32(vshl_n_u32(blend_r, 16), vshl_n_u32(blend_g, 8)), blend_b); + uint32x2_t result = vbsl_u32(zero_mask, dst, blended); + return vbsl_u32(full_mask, src, result); +} +static inline uint32x4_t lv_color_24_24_mix_4_premul_internal(uint32x4_t src, uint32x4_t dst, uint32x4_t mix) +{ + uint32x4_t zero_mask = vceqq_u32(mix, vdupq_n_u32(0)); + uint32x4_t full_mask = vcgeq_u32(mix, vdupq_n_u32(LV_OPA_MAX)); + + uint32x4_t src_r = vandq_u32(vshrq_n_u32(src, 16), vdupq_n_u32(0xFF)); + uint32x4_t src_g = vandq_u32(vshrq_n_u32(src, 8), vdupq_n_u32(0xFF)); + uint32x4_t src_b = vandq_u32(src, vdupq_n_u32(0xFF)); + + uint32x4_t dst_r = vandq_u32(vshrq_n_u32(dst, 16), vdupq_n_u32(0xFF)); + uint32x4_t dst_g = vandq_u32(vshrq_n_u32(dst, 8), vdupq_n_u32(0xFF)); + uint32x4_t dst_b = vandq_u32(dst, vdupq_n_u32(0xFF)); + + uint32x4_t inv_mix = vsubq_u32(vdupq_n_u32(255), mix); + + uint32x4_t blend_r = vaddq_u32(src_r, vshrq_n_u32(vmulq_u32(inv_mix, dst_r), 8)); + uint32x4_t blend_g = vaddq_u32(src_g, vshrq_n_u32(vmulq_u32(inv_mix, dst_g), 8)); + uint32x4_t blend_b = vaddq_u32(src_b, vshrq_n_u32(vmulq_u32(inv_mix, dst_b), 8)); + + uint32x4_t blended = vorrq_u32(vorrq_u32(vshlq_n_u32(blend_r, 16), vshlq_n_u32(blend_g, 8)), blend_b); + uint32x4_t result = vbslq_u32(zero_mask, dst, blended); + return vbslq_u32(full_mask, src, result); +} + +static inline uint32x2_t lv_color_24_24_mix_2_premul_internal(uint32x2_t src, uint32x2_t dst, uint32x2_t mix) +{ + uint32x2_t zero_mask = vceq_u32(mix, vdup_n_u32(0)); + uint32x2_t full_mask = vcge_u32(mix, vdup_n_u32(LV_OPA_MAX)); + + uint32x2_t src_r = vand_u32(vshr_n_u32(src, 16), vdup_n_u32(0xFF)); + uint32x2_t src_g = vand_u32(vshr_n_u32(src, 8), vdup_n_u32(0xFF)); + uint32x2_t src_b = vand_u32(src, vdup_n_u32(0xFF)); + + uint32x2_t dst_r = vand_u32(vshr_n_u32(dst, 16), vdup_n_u32(0xFF)); + uint32x2_t dst_g = vand_u32(vshr_n_u32(dst, 8), vdup_n_u32(0xFF)); + uint32x2_t dst_b = vand_u32(dst, vdup_n_u32(0xFF)); + + uint32x2_t inv_mix = vsub_u32(vdup_n_u32(255), mix); + + uint32x2_t blend_r = vadd_u32(src_r, vshr_n_u32(vmul_u32(inv_mix, dst_r), 8)); + uint32x2_t blend_g = vadd_u32(src_g, vshr_n_u32(vmul_u32(inv_mix, dst_g), 8)); + uint32x2_t blend_b = vadd_u32(src_b, vshr_n_u32(vmul_u32(inv_mix, dst_b), 8)); + + uint32x2_t blended = vorr_u32(vorr_u32(vshl_n_u32(blend_r, 16), vshl_n_u32(blend_g, 8)), blend_b); + uint32x2_t result = vbsl_u32(zero_mask, dst, blended); + return vbsl_u32(full_mask, src, result); +} + +static inline uint32x4_t rgb565_xrgb_mix_4_internal(uint32x4_t src, uint32x4_t dst, uint32x4_t mix) +{ + uint32x4_t zero_mask = vceqq_u32(mix, vdupq_n_u32(0)); + uint32x4_t full_mask = vcgeq_u32(mix, vdupq_n_u32(LV_OPA_MAX)); + + uint32x4_t src_r = vshrq_n_u32(vmulq_u32(vshrq_n_u32(vandq_u32(src, vdupq_n_u32(0xF800)), 11), vdupq_n_u32(2106)), 8); + uint32x4_t src_g = vshrq_n_u32(vmulq_u32(vshrq_n_u32(vandq_u32(src, vdupq_n_u32(0x07E0)), 5), vdupq_n_u32(1037)), 8); + uint32x4_t src_b = vshrq_n_u32(vmulq_u32(vandq_u32(src, vdupq_n_u32(0x001F)), vdupq_n_u32(2106)), 8); + + uint32x4_t dst_r = vandq_u32(vshrq_n_u32(dst, 16), vdupq_n_u32(0xFF)); + uint32x4_t dst_g = vandq_u32(vshrq_n_u32(dst, 8), vdupq_n_u32(0xFF)); + uint32x4_t dst_b = vandq_u32(dst, vdupq_n_u32(0xFF)); + + uint32x4_t inv_mix = vsubq_u32(vdupq_n_u32(255), mix); + uint32x4_t blend_r = vshrq_n_u32(vaddq_u32(vmulq_u32(src_r, mix), vmulq_u32(dst_r, inv_mix)), 8); + uint32x4_t blend_g = vshrq_n_u32(vaddq_u32(vmulq_u32(src_g, mix), vmulq_u32(dst_g, inv_mix)), 8); + uint32x4_t blend_b = vshrq_n_u32(vaddq_u32(vmulq_u32(src_b, mix), vmulq_u32(dst_b, inv_mix)), 8); + + uint32x4_t blended = vorrq_u32(vorrq_u32(vshlq_n_u32(blend_r, 16), vshlq_n_u32(blend_g, 8)), blend_b); + uint32x4_t result = vbslq_u32(zero_mask, dst, blended); + return vbslq_u32(full_mask, src, result); +} + +static inline uint32x2_t rgb565_xrgb_mix_2_internal(uint32x2_t src, uint32x2_t dst, uint32x2_t mix) +{ + uint32x2_t zero_mask = vceq_u32(mix, vdup_n_u32(0)); + uint32x2_t full_mask = vcge_u32(mix, vdup_n_u32(LV_OPA_MAX)); + + uint32x2_t src_r = vshr_n_u32(vmul_u32(vshr_n_u32(vand_u32(src, vdup_n_u32(0xF800)), 11), vdup_n_u32(2106)), 8); + uint32x2_t src_g = vshr_n_u32(vmul_u32(vshr_n_u32(vand_u32(src, vdup_n_u32(0x07E0)), 5), vdup_n_u32(1037)), 8); + uint32x2_t src_b = vshr_n_u32(vmul_u32(vand_u32(src, vdup_n_u32(0x001F)), vdup_n_u32(2106)), 8); + + uint32x2_t dst_r = vand_u32(vshr_n_u32(dst, 16), vdup_n_u32(0xFF)); + uint32x2_t dst_g = vand_u32(vshr_n_u32(dst, 8), vdup_n_u32(0xFF)); + uint32x2_t dst_b = vand_u32(dst, vdup_n_u32(0xFF)); + + uint32x2_t inv_mix = vsub_u32(vdup_n_u32(255), mix); + uint32x2_t blend_r = vshr_n_u32(vadd_u32(vmul_u32(src_r, mix), vmul_u32(dst_r, inv_mix)), 8); + uint32x2_t blend_g = vshr_n_u32(vadd_u32(vmul_u32(src_g, mix), vmul_u32(dst_g, inv_mix)), 8); + uint32x2_t blend_b = vshr_n_u32(vadd_u32(vmul_u32(src_b, mix), vmul_u32(dst_b, inv_mix)), 8); + + uint32x2_t blended = vorr_u32(vorr_u32(vshl_n_u32(blend_r, 16), vshl_n_u32(blend_g, 8)), blend_b); + uint32x2_t result = vbsl_u32(zero_mask, dst, blended); + return vbsl_u32(full_mask, src, result); +} +#endif /* LV_USE_DRAW_SW_ASM == LV_DRAW_SW_ASM_NEON*/ diff --git a/src/draw/sw/blend/neon/lv_draw_sw_blend_neon_to_rgb888.h b/src/draw/sw/blend/neon/lv_draw_sw_blend_neon_to_rgb888.h new file mode 100644 index 0000000000..6002465480 --- /dev/null +++ b/src/draw/sw/blend/neon/lv_draw_sw_blend_neon_to_rgb888.h @@ -0,0 +1,158 @@ +/** + * @file lv_draw_sw_blend_neon_to_rgb888.h + * + */ + +#ifndef LV_DRAW_SW_BLEND_NEON_TO_RGB888_H +#define LV_DRAW_SW_BLEND_NEON_TO_RGB888_H + +#ifdef __cplusplus +extern "C" { +#endif + +/********************* + * INCLUDES + *********************/ + +#include "../../../../lv_conf_internal.h" +#if LV_USE_DRAW_SW_ASM == LV_DRAW_SW_ASM_NEON + +#include "../../../../misc/lv_types.h" + +/********************* + * DEFINES + *********************/ + +#ifndef LV_DRAW_SW_COLOR_BLEND_TO_RGB888 +#define LV_DRAW_SW_COLOR_BLEND_TO_RGB888(dsc, dest_px_size) lv_draw_sw_blend_neon_color_to_rgb888(dsc, dest_px_size) +#endif + +#ifndef LV_DRAW_SW_COLOR_BLEND_TO_RGB888_WITH_OPA +#define LV_DRAW_SW_COLOR_BLEND_TO_RGB888_WITH_OPA(dsc, dest_px_size) lv_draw_sw_blend_neon_color_to_rgb888_with_opa(dsc, dest_px_size) +#endif + +#ifndef LV_DRAW_SW_COLOR_BLEND_TO_RGB888_WITH_MASK +#define LV_DRAW_SW_COLOR_BLEND_TO_RGB888_WITH_MASK(dsc, dest_px_size) lv_draw_sw_blend_neon_color_to_rgb888_with_mask(dsc, dest_px_size) +#endif + +#ifndef LV_DRAW_SW_COLOR_BLEND_TO_RGB888_MIX_MASK_OPA +#define LV_DRAW_SW_COLOR_BLEND_TO_RGB888_MIX_MASK_OPA(dsc, dest_px_size) lv_draw_sw_blend_neon_color_to_rgb888_with_opa_mask(dsc, dest_px_size) +#endif + +#ifdef __aarch64__ /* This function uses a special intrinsic only available for arm64 */ +#ifndef LV_DRAW_SW_L8_BLEND_NORMAL_TO_RGB888 +#define LV_DRAW_SW_L8_BLEND_NORMAL_TO_RGB888(dsc, dest_px_size) lv_draw_sw_blend_neon_l8_to_rgb888(dsc, dest_px_size) +#endif +#endif + +#ifndef LV_DRAW_SW_RGB565_BLEND_NORMAL_TO_RGB888 +#define LV_DRAW_SW_RGB565_BLEND_NORMAL_TO_RGB888(dsc, dest_px_size) lv_draw_sw_blend_neon_rgb565_to_rgb888(dsc, dest_px_size) +#endif + +#ifndef LV_DRAW_SW_RGB565_BLEND_NORMAL_TO_RGB888_WITH_OPA +#define LV_DRAW_SW_RGB565_BLEND_NORMAL_TO_RGB888_WITH_OPA(dsc, dest_px_size) lv_draw_sw_blend_neon_rgb565_to_rgb888_with_opa(dsc, dest_px_size) +#endif + +#ifndef LV_DRAW_SW_RGB565_BLEND_NORMAL_TO_RGB888_WITH_MASK +#define LV_DRAW_SW_RGB565_BLEND_NORMAL_TO_RGB888_WITH_MASK(dsc, dest_px_size) lv_draw_sw_blend_neon_rgb565_to_rgb888_with_mask(dsc, dest_px_size) +#endif + +#ifndef LV_DRAW_SW_RGB565_BLEND_NORMAL_TO_RGB888_MIX_MASK_OPA +#define LV_DRAW_SW_RGB565_BLEND_NORMAL_TO_RGB888_MIX_MASK_OPA(dsc, dest_px_size) lv_draw_sw_blend_neon_rgb565_to_rgb888_with_opa_mask(dsc, dest_px_size) +#endif + +#ifndef LV_DRAW_SW_RGB888_BLEND_NORMAL_TO_RGB888 +#define LV_DRAW_SW_RGB888_BLEND_NORMAL_TO_RGB888(dsc, dest_px_size, src_px_size) lv_draw_sw_blend_neon_rgb888_to_rgb888(dsc, dest_px_size, src_px_size) +#endif + +#ifndef LV_DRAW_SW_RGB888_BLEND_NORMAL_TO_RGB888_WITH_OPA +#define LV_DRAW_SW_RGB888_BLEND_NORMAL_TO_RGB888_WITH_OPA(dsc, dest_px_size, src_px_size) lv_draw_sw_blend_neon_rgb888_to_rgb888_with_opa(dsc, dest_px_size, src_px_size) +#endif + +#ifndef LV_DRAW_SW_RGB888_BLEND_NORMAL_TO_RGB888_WITH_MASK +#define LV_DRAW_SW_RGB888_BLEND_NORMAL_TO_RGB888_WITH_MASK(dsc, dest_px_size, src_px_size) lv_draw_sw_blend_neon_rgb888_to_rgb888_with_mask(dsc, dest_px_size, src_px_size) +#endif + +#ifndef LV_DRAW_SW_RGB888_BLEND_NORMAL_TO_RGB888_MIX_MASK_OPA +#define LV_DRAW_SW_RGB888_BLEND_NORMAL_TO_RGB888_MIX_MASK_OPA(dsc, dest_px_size, src_px_size) lv_draw_sw_blend_neon_rgb888_to_rgb888_with_opa_mask(dsc, dest_px_size, src_px_size) +#endif + +#if 0 /* These seem to produce worse results than sw rendering, also RGB888 is not implemented, only XRGB8888. So they are disabled for now*/ +#ifndef LV_DRAW_SW_ARGB8888_BLEND_NORMAL_TO_RGB888 +#define LV_DRAW_SW_ARGB8888_BLEND_NORMAL_TO_RGB888(dsc, dest_px_size) lv_draw_sw_blend_neon_argb888_to_rgb888(dsc, dest_px_size) +#endif + +#ifndef LV_DRAW_SW_ARGB8888_BLEND_NORMAL_TO_RGB888_WITH_OPA +#define LV_DRAW_SW_ARGB8888_BLEND_NORMAL_TO_RGB888_WITH_OPA(dsc, dest_px_size) lv_draw_sw_blend_neon_argb888_to_rgb888_with_opa(dsc, dest_px_size) + +#endif +#ifndef LV_DRAW_SW_ARGB8888_BLEND_NORMAL_TO_RGB888_WITH_MASK +#define LV_DRAW_SW_ARGB8888_BLEND_NORMAL_TO_RGB888_WITH_MASK(dsc, dest_px_size) lv_draw_sw_blend_neon_argb888_to_rgb888_with_mask(dsc, dest_px_size) +#endif + +#ifndef LV_DRAW_SW_ARGB8888_BLEND_NORMAL_TO_RGB888_MIX_MASK_OPA +#define LV_DRAW_SW_ARGB8888_BLEND_NORMAL_TO_RGB888_MIX_MASK_OPA(dsc, dest_px_size) lv_draw_sw_blend_neon_argb888_to_rgb888_with_opa_mask(dsc, dest_px_size) +#endif +#endif + +#ifndef LV_DRAW_SW_ARGB8888_PREMULTIPLIED_BLEND_NORMAL_TO_RGB888 +#define LV_DRAW_SW_ARGB8888_PREMULTIPLIED_BLEND_NORMAL_TO_RGB888(dsc, dest_px_size) lv_draw_sw_blend_neon_argb888_premultiplied_to_rgb888(dsc, dest_px_size) +#endif + +/********************** + * TYPEDEFS + **********************/ + +/********************** + * GLOBAL PROTOTYPES + **********************/ + +lv_result_t lv_draw_sw_blend_neon_color_to_rgb888(lv_draw_sw_blend_fill_dsc_t * dsc, uint32_t dest_px_size); +lv_result_t lv_draw_sw_blend_neon_color_to_rgb888_with_opa(lv_draw_sw_blend_fill_dsc_t * dsc, uint32_t dest_px_size); +lv_result_t lv_draw_sw_blend_neon_color_to_rgb888_with_mask(lv_draw_sw_blend_fill_dsc_t * dsc, uint32_t dest_px_size); +lv_result_t lv_draw_sw_blend_neon_color_to_rgb888_with_opa_mask(lv_draw_sw_blend_fill_dsc_t * dsc, + uint32_t dest_px_size); + +#ifdef __aarch64__ +lv_result_t lv_draw_sw_blend_neon_l8_to_rgb888(lv_draw_sw_blend_image_dsc_t * dsc, uint32_t dest_px_size); +#endif /*__aarch64__*/ + +lv_result_t lv_draw_sw_blend_neon_al88_to_rgb888(lv_draw_sw_blend_image_dsc_t * dsc, uint32_t dest_px_size); +lv_result_t lv_draw_sw_blend_neon_al88_to_rgb888_with_opa(lv_draw_sw_blend_image_dsc_t * dsc); +lv_result_t lv_draw_sw_blend_neon_al88_to_rgb888_with_mask(lv_draw_sw_blend_image_dsc_t * dsc); +lv_result_t lv_draw_sw_blend_neon_al88_to_rgb888_with_opa_mask(lv_draw_sw_blend_image_dsc_t * dsc); + +lv_result_t lv_draw_sw_blend_neon_rgb565_to_rgb888(lv_draw_sw_blend_image_dsc_t * dsc, uint32_t dest_px_size); +lv_result_t lv_draw_sw_blend_neon_rgb565_to_rgb888_with_opa(lv_draw_sw_blend_image_dsc_t * dsc, uint32_t dest_px_size); +lv_result_t lv_draw_sw_blend_neon_rgb565_to_rgb888_with_mask(lv_draw_sw_blend_image_dsc_t * dsc, uint32_t dest_px_size); +lv_result_t lv_draw_sw_blend_neon_rgb565_to_rgb888_with_opa_mask(lv_draw_sw_blend_image_dsc_t * dsc, + uint32_t dest_px_size); + +lv_result_t lv_draw_sw_blend_neon_rgb888_to_rgb888(lv_draw_sw_blend_image_dsc_t * dsc, uint32_t dest_px_size, + uint32_t src_px_size); +lv_result_t lv_draw_sw_blend_neon_rgb888_to_rgb888_with_opa(lv_draw_sw_blend_image_dsc_t * dsc, uint32_t dest_px_size, + uint32_t src_px_size); +lv_result_t lv_draw_sw_blend_neon_rgb888_to_rgb888_with_mask(lv_draw_sw_blend_image_dsc_t * dsc, uint32_t dest_px_size, + uint32_t src_px_size); +lv_result_t lv_draw_sw_blend_neon_rgb888_to_rgb888_with_opa_mask(lv_draw_sw_blend_image_dsc_t * dsc, + uint32_t dest_px_size, uint32_t src_px_size); +lv_result_t lv_draw_sw_blend_neon_argb888_to_rgb888(lv_draw_sw_blend_image_dsc_t * dsc, uint32_t dest_px_size); +lv_result_t lv_draw_sw_blend_neon_argb888_premultiplied_to_rgb888(lv_draw_sw_blend_image_dsc_t * dsc, + uint32_t dest_px_size); +lv_result_t lv_draw_sw_blend_neon_argb888_to_rgb888_with_opa(lv_draw_sw_blend_image_dsc_t * dsc, uint32_t dest_px_size); +lv_result_t lv_draw_sw_blend_neon_argb888_to_rgb888_with_mask(lv_draw_sw_blend_image_dsc_t * dsc, + uint32_t dest_px_size); +lv_result_t lv_draw_sw_blend_neon_argb888_to_rgb888_with_opa_mask(lv_draw_sw_blend_image_dsc_t * dsc, + uint32_t dest_px_size); + +/********************** + * MACROS + **********************/ + +#endif /* LV_USE_DRAW_SW_ASM == LV_DRAW_SW_ASM_NEON */ + +#ifdef __cplusplus +} /*extern "C"*/ +#endif + +#endif /*LV_DRAW_SW_BLEND_NEON_TO_RGB888_H*/ diff --git a/src/draw/sw/lv_draw_sw.c b/src/draw/sw/lv_draw_sw.c index 8b1ef4cc5d..c62b6c6706 100644 --- a/src/draw/sw/lv_draw_sw.c +++ b/src/draw/sw/lv_draw_sw.c @@ -329,7 +329,7 @@ static int32_t dispatch(lv_draw_unit_t * draw_unit, lv_layer_t * layer) draw_sw_unit->task_act = t; execute_drawing(t); - draw_sw_unit->task_act->state = LV_DRAW_TASK_STATE_READY; + draw_sw_unit->task_act->state = LV_DRAW_TASK_STATE_FINISHED; draw_sw_unit->task_act = NULL; /*The draw unit is free now. Request a new dispatching as it can get a new task*/ @@ -366,7 +366,7 @@ static void render_thread_cb(void * ptr) #if LV_USE_PARALLEL_DRAW_DEBUG parallel_debug_draw(thread_dsc->task_act, thread_dsc->idx); #endif - thread_dsc->task_act->state = LV_DRAW_TASK_STATE_READY; + thread_dsc->task_act->state = LV_DRAW_TASK_STATE_FINISHED; thread_dsc->task_act = NULL; /*The draw unit is free now. Request a new dispatching as it can get a new task*/ @@ -437,6 +437,13 @@ static void parallel_debug_draw(lv_draw_task_t * t, uint32_t idx) /*Layers manage it for themselves*/ if(t->type != LV_DRAW_TASK_TYPE_LAYER) { lv_area_t draw_area; + lv_text_attributes_t attributes = {0}; + + attributes.text_flags = LV_TEXT_FLAG_NONE; + attributes.line_space = 0; + attributes.letter_space = 0; + attributes.max_width = 100; + if(!lv_area_intersect(&draw_area, &t->area, &t->clip_area)) return; lv_draw_fill_dsc_t fill_dsc; @@ -453,7 +460,7 @@ static void parallel_debug_draw(lv_draw_task_t * t, uint32_t idx) lv_draw_sw_border(t, &border_dsc, &draw_area); lv_point_t txt_size; - lv_text_get_size(&txt_size, "W", LV_FONT_DEFAULT, 0, 0, 100, LV_TEXT_FLAG_NONE); + lv_text_get_size_attributes(&txt_size, "W", LV_FONT_DEFAULT, &attributes); lv_area_t txt_area; txt_area.x1 = draw_area.x1; diff --git a/src/draw/sw/lv_draw_sw.h b/src/draw/sw/lv_draw_sw.h index d5e0df24c6..aae25c6d18 100644 --- a/src/draw/sw/lv_draw_sw.h +++ b/src/draw/sw/lv_draw_sw.h @@ -19,7 +19,6 @@ extern "C" { #include "../../misc/lv_area.h" #include "../../misc/lv_color.h" #include "../../display/lv_display.h" -#include "../../osal/lv_os.h" #include "../lv_draw_vector.h" #include "../lv_draw_triangle.h" @@ -152,7 +151,7 @@ void lv_draw_sw_transform(const lv_area_t * dest_area, const void * src_buf, * @param t pointer to a draw task * @param dsc the draw descriptor */ -void lv_draw_sw_vector(lv_draw_task_t * t, lv_draw_vector_task_dsc_t * dsc); +void lv_draw_sw_vector(lv_draw_task_t * t, lv_draw_vector_dsc_t * dsc); #endif /** diff --git a/src/draw/sw/lv_draw_sw_grad.c b/src/draw/sw/lv_draw_sw_grad.c index 4550a6c95f..090f55d5c8 100644 --- a/src/draw/sw/lv_draw_sw_grad.c +++ b/src/draw/sw/lv_draw_sw_grad.c @@ -10,7 +10,7 @@ #if LV_USE_DRAW_SW #include "../../misc/lv_types.h" -#include "../../osal/lv_os.h" +#include "../../osal/lv_os_private.h" #include "../../misc/lv_math.h" /********************* diff --git a/src/draw/sw/lv_draw_sw_grad.h b/src/draw/sw/lv_draw_sw_grad.h index 42b36c2117..3033119a09 100644 --- a/src/draw/sw/lv_draw_sw_grad.h +++ b/src/draw/sw/lv_draw_sw_grad.h @@ -144,4 +144,4 @@ void /* LV_ATTRIBUTE_FAST_MEM */ lv_draw_sw_grad_conical_get_line(lv_grad_dsc_t } /*extern "C"*/ #endif -#endif /*LV_DRAW_GRADIENT_H*/ +#endif /*LV_DRAW_SW_GRAD_H*/ diff --git a/src/draw/sw/lv_draw_sw_img.c b/src/draw/sw/lv_draw_sw_img.c index 5d5574cff7..3cf1f19679 100644 --- a/src/draw/sw/lv_draw_sw_img.c +++ b/src/draw/sw/lv_draw_sw_img.c @@ -86,6 +86,9 @@ static void transform_and_recolor(lv_draw_task_t * t, const lv_draw_image_dsc_t static void recolor(lv_area_t relative_area, uint8_t * src_buf, uint8_t * dest_buf, int32_t src_stride, lv_color_format_t cf, const lv_draw_image_dsc_t * draw_dsc); +static void colorkey_and_recolor(lv_area_t relative_area, uint8_t * src_buf, uint8_t * dest_buf, int32_t src_stride, + lv_color_format_t cf, const lv_draw_image_dsc_t * draw_dsc, lv_draw_sw_blend_dsc_t * blend_dsc); + static bool apply_mask(const lv_draw_image_dsc_t * draw_dsc); /********************** @@ -175,7 +178,7 @@ void lv_draw_sw_layer(lv_draw_task_t * t, const lv_draw_image_dsc_t * draw_dsc, lv_draw_sw_border(t, &border_dsc, &area_rot); lv_point_t txt_size; - lv_text_get_size(&txt_size, "W", LV_FONT_DEFAULT, 0, 0, 100, LV_TEXT_FLAG_NONE); + lv_text_get_size_attributes(&txt_size, "W", LV_FONT_DEFAULT, 0, 0, 100, LV_TEXT_FLAG_NONE); lv_area_t txt_area; txt_area.x1 = draw_area.x1; @@ -248,7 +251,8 @@ static void img_draw_core(lv_draw_task_t * t, const lv_draw_image_dsc_t * draw_d blend_dsc.blend_area = img_coords; lv_draw_sw_blend(t, &blend_dsc); } - else if(!transformed && !radius && cf == LV_COLOR_FORMAT_RGB565A8 && draw_dsc->recolor_opa <= LV_OPA_MIN) { + else if(!transformed && !radius && cf == LV_COLOR_FORMAT_RGB565A8 && draw_dsc->recolor_opa <= LV_OPA_MIN && + draw_dsc->colorkey == NULL) { int32_t src_h = lv_area_get_height(img_coords); int32_t src_w = lv_area_get_width(img_coords); blend_dsc.src_area = img_coords; @@ -267,7 +271,8 @@ static void img_draw_core(lv_draw_task_t * t, const lv_draw_image_dsc_t * draw_d blend_dsc.src_color_format = LV_COLOR_FORMAT_RGB565; lv_draw_sw_blend(t, &blend_dsc); } - else if(!transformed && !radius && (cf == LV_COLOR_FORMAT_L8 || cf == LV_COLOR_FORMAT_AL88)) { + else if(!transformed && !radius && (cf == LV_COLOR_FORMAT_L8 || cf == LV_COLOR_FORMAT_AL88) && + draw_dsc->colorkey == NULL) { blend_dsc.src_area = img_coords; blend_dsc.src_buf = src_buf; blend_dsc.blend_area = img_coords; @@ -275,19 +280,19 @@ static void img_draw_core(lv_draw_task_t * t, const lv_draw_image_dsc_t * draw_d lv_draw_sw_blend(t, &blend_dsc); } /*The simplest case just copy the pixels into the draw_buf. Blending will convert the colors if needed*/ - else if(!transformed && !radius && draw_dsc->recolor_opa <= LV_OPA_MIN) { + else if(!transformed && !radius && draw_dsc->recolor_opa <= LV_OPA_MIN && draw_dsc->colorkey == NULL) { blend_dsc.src_area = img_coords; blend_dsc.src_buf = src_buf; blend_dsc.blend_area = img_coords; blend_dsc.src_color_format = cf; lv_draw_sw_blend(t, &blend_dsc); } - else if(!transformed && !radius && draw_dsc->recolor_opa > LV_OPA_MIN) { + else if(!transformed && !radius && draw_dsc->recolor_opa > LV_OPA_MIN && draw_dsc->colorkey == NULL) { recolor_only(t, draw_dsc, decoder_dsc, img_coords, clipped_img_area); } #if LV_DRAW_SW_COMPLEX /*Handle masked RGB565, RGB888, XRGB888, or ARGB8888 images*/ - else if(!transformed && radius && draw_dsc->recolor_opa <= LV_OPA_MIN) { + else if(!transformed && radius && draw_dsc->recolor_opa <= LV_OPA_MIN && draw_dsc->colorkey == NULL) { radius_only(t, draw_dsc, decoder_dsc, img_coords, clipped_img_area); } #endif /*LV_DRAW_SW_COMPLEX*/ @@ -386,6 +391,7 @@ static void radius_only(lv_draw_task_t * t, const lv_draw_image_dsc_t * draw_dsc } #endif /*LV_DRAW_SW_COMPLEX*/ + static void recolor_only(lv_draw_task_t * t, const lv_draw_image_dsc_t * draw_dsc, const lv_image_decoder_dsc_t * decoder_dsc, const lv_area_t * img_coords, const lv_area_t * clipped_img_area) @@ -408,6 +414,11 @@ static void recolor_only(lv_draw_task_t * t, const lv_draw_image_dsc_t * draw_ds buf_h = MAX_BUF_SIZE / buf_stride; if(buf_h > blend_h) buf_h = blend_h; tmp_buf = lv_malloc(buf_stride * buf_h); + LV_ASSERT_MALLOC(tmp_buf); + if(!tmp_buf) { + LV_LOG_WARN("Failed to perform image recolor operation. Out of memory"); + return; + } lv_draw_sw_blend_dsc_t blend_dsc; lv_memzero(&blend_dsc, sizeof(lv_draw_sw_blend_dsc_t)); @@ -432,6 +443,7 @@ static void recolor_only(lv_draw_task_t * t, const lv_draw_image_dsc_t * draw_ds lv_area_t relative_area; lv_area_copy(&relative_area, &blend_area); lv_area_move(&relative_area, -img_coords->x1, -img_coords->y1); + recolor(relative_area, decoded->data, tmp_buf, img_stride, blend_dsc.src_color_format, draw_dsc); lv_draw_sw_blend(t, &blend_dsc); @@ -476,6 +488,8 @@ static void transform_and_recolor(lv_draw_task_t * t, const lv_draw_image_dsc_t do_recolor = false; } + bool has_colorkey = draw_dsc->colorkey != NULL; + lv_color_format_t cf_final = cf; if(cf_final == LV_COLOR_FORMAT_RGB888 || cf_final == LV_COLOR_FORMAT_XRGB8888) cf_final = LV_COLOR_FORMAT_ARGB8888; else if(cf_final == LV_COLOR_FORMAT_RGB565 || @@ -512,6 +526,7 @@ static void transform_and_recolor(lv_draw_task_t * t, const lv_draw_image_dsc_t blend_dsc.mask_area = &blend_area; blend_dsc.mask_res = LV_DRAW_SW_MASK_RES_CHANGED; blend_dsc.mask_buf = transformed_buf + blend_w * 2 * buf_h; + blend_dsc.mask_stride = blend_w; blend_dsc.src_color_format = LV_COLOR_FORMAT_RGB565; } else if(cf_final == LV_COLOR_FORMAT_A8) { @@ -533,11 +548,17 @@ static void transform_and_recolor(lv_draw_task_t * t, const lv_draw_image_dsc_t lv_draw_sw_transform(&relative_area, src_buf, src_w, src_h, img_stride, draw_dsc, sup, cf, transformed_buf); - if(do_recolor) { + if(do_recolor || has_colorkey) { lv_area_t relative_area2; lv_area_copy(&relative_area2, &blend_area); lv_area_move(&relative_area2, -blend_area.x1, -blend_area.y1); - recolor(relative_area2, transformed_buf, transformed_buf, blend_dsc.src_stride, cf_final, draw_dsc); + if(has_colorkey && cf_final != LV_COLOR_FORMAT_RGB565_SWAPPED) { + colorkey_and_recolor(relative_area2, transformed_buf, transformed_buf, blend_dsc.src_stride, cf_final, draw_dsc, + &blend_dsc); + } + else { + recolor(relative_area2, transformed_buf, transformed_buf, blend_dsc.src_stride, cf_final, draw_dsc); + } } /*Blend*/ @@ -557,6 +578,199 @@ static void transform_and_recolor(lv_draw_task_t * t, const lv_draw_image_dsc_t lv_free(transformed_buf); } +static void colorkey_and_recolor(lv_area_t relative_area, uint8_t * src_buf, uint8_t * dest_buf, int32_t src_stride, + lv_color_format_t cf, const lv_draw_image_dsc_t * draw_dsc, lv_draw_sw_blend_dsc_t * blend_dsc) +{ + int32_t w = lv_area_get_width(&relative_area); + int32_t h = lv_area_get_height(&relative_area); + + /* Recolor parameters */ + lv_color_t recolor = draw_dsc->recolor; + lv_opa_t mix = draw_dsc->recolor_opa; + lv_opa_t mix_inv = 255 - mix; + + /* Colorkey parameters */ + lv_color_t colorkey_low = draw_dsc->colorkey->low; + lv_color_t colorkey_high = draw_dsc->colorkey->high; + if(cf == LV_COLOR_FORMAT_RGB565A8 || cf == LV_COLOR_FORMAT_RGB565) { + const uint8_t * src_buf_tmp = src_buf + src_stride * relative_area.y1 + relative_area.x1 * 2; + int32_t img_stride_px = src_stride / 2; + + uint16_t * buf16_src = (uint16_t *)src_buf_tmp; + uint16_t * buf16_dest = (uint16_t *)dest_buf; + uint16_t recolor16 = lv_color_to_u16(recolor); + + uint16_t c_mult[3]; + c_mult[0] = (recolor.blue >> 3) * mix; + c_mult[1] = (recolor.green >> 2) * mix; + c_mult[2] = (recolor.red >> 3) * mix; + uint8_t * mask_buf_tmp = (uint8_t *)blend_dsc->mask_buf; + int32_t y; + for(y = 0; y < h; y++) { + int32_t x; + for(x = 0; x < w; x++) { + lv_color_t src_color = lv_color16_to_color(*(lv_color16_t *)&buf16_src[x]); + + /* Check colorkey */ + if(lv_color_is_in_range(src_color, colorkey_low, colorkey_high)) { + if(cf == LV_COLOR_FORMAT_RGB565A8 && mask_buf_tmp) { + mask_buf_tmp[x] = 0; + } + else { + *buf16_dest = 0x0000; // Transparent + } + } + /* Apply recolor */ + else if(mix >= LV_OPA_MAX) { + *buf16_dest = recolor16; + } + else if(mix > LV_OPA_MIN) { + uint16_t src16 = buf16_src[x]; + *buf16_dest = (((c_mult[2] + ((src16 >> 11) & 0x1F) * mix_inv) << 3) & 0xF800) + + (((c_mult[1] + ((src16 >> 5) & 0x3F) * mix_inv) >> 3) & 0x07E0) + + ((c_mult[0] + (src16 & 0x1F) * mix_inv) >> 8); + } + else { + *buf16_dest = buf16_src[x]; // No change + } + buf16_dest++; + } + buf16_src += img_stride_px; + mask_buf_tmp += blend_dsc->mask_stride; + } + } + else if(cf == LV_COLOR_FORMAT_RGB888 || cf == LV_COLOR_FORMAT_XRGB8888 || cf == LV_COLOR_FORMAT_ARGB8888) { + uint32_t px_size = lv_color_format_get_size(cf); + const uint8_t * src_buf_tmp = src_buf + src_stride * relative_area.y1 + relative_area.x1 * px_size; + uint8_t * dest_buf_tmp = dest_buf; + + uint16_t c_mult[3]; + c_mult[0] = recolor.blue * mix; + c_mult[1] = recolor.green * mix; + c_mult[2] = recolor.red * mix; + + int32_t y; + for(y = 0; y < h; y++) { + int32_t x; + for(x = 0; x < w; x++) { + lv_color_t src_color; + src_color.blue = src_buf_tmp[0]; + src_color.green = src_buf_tmp[1]; + src_color.red = src_buf_tmp[2]; + + /* Check colorkey */ + if(lv_color_is_in_range(src_color, colorkey_low, colorkey_high)) { + dest_buf_tmp[0] = 0; + dest_buf_tmp[1] = 0; + dest_buf_tmp[2] = 0; + if(cf == LV_COLOR_FORMAT_ARGB8888) { + dest_buf_tmp[3] = 0; // Set alpha to 0 + } + } + /* Apply recolor */ + else if(mix >= LV_OPA_MAX) { + dest_buf_tmp[0] = recolor.blue; + dest_buf_tmp[1] = recolor.green; + dest_buf_tmp[2] = recolor.red; + if(cf == LV_COLOR_FORMAT_ARGB8888) { + dest_buf_tmp[3] = src_buf_tmp[3]; // Keep original alpha + } + } + else if(mix > LV_OPA_MIN) { + dest_buf_tmp[0] = (c_mult[0] + (src_buf_tmp[0] * mix_inv)) >> 8; + dest_buf_tmp[1] = (c_mult[1] + (src_buf_tmp[1] * mix_inv)) >> 8; + dest_buf_tmp[2] = (c_mult[2] + (src_buf_tmp[2] * mix_inv)) >> 8; + if(cf == LV_COLOR_FORMAT_ARGB8888) { + dest_buf_tmp[3] = src_buf_tmp[3]; // Keep original alpha + } + } + else { + // Copy as-is + dest_buf_tmp[0] = src_buf_tmp[0]; + dest_buf_tmp[1] = src_buf_tmp[1]; + dest_buf_tmp[2] = src_buf_tmp[2]; + if(cf == LV_COLOR_FORMAT_ARGB8888) { + dest_buf_tmp[3] = src_buf_tmp[3]; + } + } + + src_buf_tmp += px_size; + dest_buf_tmp += px_size; + } + src_buf_tmp += (src_stride - w * px_size); + } + } + else if(cf == LV_COLOR_FORMAT_ARGB8888_PREMULTIPLIED) { + uint32_t px_size = 4; + const uint8_t * src_buf_tmp = src_buf + src_stride * relative_area.y1 + relative_area.x1 * px_size; + uint8_t * dest_buf_tmp = dest_buf; + + uint16_t c_mult[3]; + c_mult[0] = recolor.blue * mix; + c_mult[1] = recolor.green * mix; + c_mult[2] = recolor.red * mix; + + int32_t y; + for(y = 0; y < h; y++) { + int32_t x; + for(x = 0; x < w; x++) { + uint8_t alpha = src_buf_tmp[3]; + + // Only process if pixel is visible + if(alpha > 0) { + /* Unpremultiply for color comparison and recolor */ + uint16_t reciprocal = (255 * 256) / alpha; + uint8_t r = (src_buf_tmp[2] * reciprocal) >> 8; + uint8_t g = (src_buf_tmp[1] * reciprocal) >> 8; + uint8_t b = (src_buf_tmp[0] * reciprocal) >> 8; + + lv_color_t src_color = lv_color_make(r, g, b); + + /* Check colorkey */ + if(lv_color_is_in_range(src_color, colorkey_low, colorkey_high)) { + // Set entire pixel to transparent + dest_buf_tmp[0] = 0; + dest_buf_tmp[1] = 0; + dest_buf_tmp[2] = 0; + dest_buf_tmp[3] = 0; + } + /* Apply recolor */ + else { + if(mix >= LV_OPA_MAX) { + r = recolor.red; + g = recolor.green; + b = recolor.blue; + } + else if(mix > LV_OPA_MIN) { + r = (c_mult[2] + (r * mix_inv)) >> 8; + g = (c_mult[1] + (g * mix_inv)) >> 8; + b = (c_mult[0] + (b * mix_inv)) >> 8; + } + // Else keep original colors + + /* Premultiply again */ + dest_buf_tmp[0] = (b * alpha) >> 8; + dest_buf_tmp[1] = (g * alpha) >> 8; + dest_buf_tmp[2] = (r * alpha) >> 8; + dest_buf_tmp[3] = alpha; // Keep original alpha + } + } + else { + // Already transparent, copy as-is + dest_buf_tmp[0] = src_buf_tmp[0]; + dest_buf_tmp[1] = src_buf_tmp[1]; + dest_buf_tmp[2] = src_buf_tmp[2]; + dest_buf_tmp[3] = 0; // Ensure alpha is 0 + } + + src_buf_tmp += px_size; + dest_buf_tmp += px_size; + } + src_buf_tmp += (src_stride - w * px_size); + } + } +} + static void recolor(lv_area_t relative_area, uint8_t * src_buf, uint8_t * dest_buf, int32_t src_stride, lv_color_format_t cf, const lv_draw_image_dsc_t * draw_dsc) { diff --git a/src/draw/sw/lv_draw_sw_letter.c b/src/draw/sw/lv_draw_sw_letter.c index 5bb69c98bf..c57632b7ac 100644 --- a/src/draw/sw/lv_draw_sw_letter.c +++ b/src/draw/sw/lv_draw_sw_letter.c @@ -170,6 +170,11 @@ static void LV_ATTRIBUTE_FAST_MEM draw_letter_cb(lv_draw_task_t * t, lv_draw_gly } else { glyph_draw_dsc->glyph_data = lv_font_get_glyph_bitmap(glyph_draw_dsc->g, glyph_draw_dsc->_draw_buf); + if(glyph_draw_dsc->glyph_data == NULL) { + LV_LOG_WARN("Couldn't get the bitmap of a glyph"); + break; + } + mask_area.x2 = mask_area.x1 + lv_draw_buf_width_to_stride(lv_area_get_width(&mask_area), LV_COLOR_FORMAT_A8) - 1; lv_draw_sw_blend_dsc_t blend_dsc; lv_memzero(&blend_dsc, sizeof(blend_dsc)); @@ -229,7 +234,7 @@ static void draw_letter_outline(lv_draw_task_t * t, lv_draw_glyph_dsc_t * glyph_ { lv_draw_sw_letter_outlines_t * glyph_paths; - lv_vector_dsc_t * vector_dsc; + lv_draw_vector_dsc_t * vector_dsc; lv_draw_buf_t * draw_buf; lv_matrix_t matrix; lv_layer_t layer; @@ -269,7 +274,7 @@ static void draw_letter_outline(lv_draw_task_t * t, lv_draw_glyph_dsc_t * glyph_ lv_matrix_identity(&matrix); - vector_dsc = lv_vector_dsc_create(&layer); + vector_dsc = lv_draw_vector_dsc_create(&layer); int32_t offset_x; int32_t offset_y; @@ -281,20 +286,20 @@ static void draw_letter_outline(lv_draw_task_t * t, lv_draw_glyph_dsc_t * glyph_ lv_matrix_scale(&matrix, 1, -1); lv_matrix_translate(&matrix, -offset_x, -h - offset_y); lv_matrix_scale(&matrix, scale, scale); - lv_vector_dsc_set_transform(vector_dsc, &matrix); + lv_draw_vector_dsc_set_transform(vector_dsc, &matrix); /*Set attributes color, line width etc*/ if(cf == LV_COLOR_FORMAT_ARGB8888) { if(glyph_dsc->outline_stroke_width > 0) { - lv_vector_dsc_set_fill_color(vector_dsc, glyph_dsc->outline_stroke_color); - lv_vector_dsc_set_fill_opa(vector_dsc, glyph_dsc->outline_stroke_opa); - lv_vector_dsc_add_path(vector_dsc, glyph_paths->outside_path); + lv_draw_vector_dsc_set_fill_color(vector_dsc, glyph_dsc->outline_stroke_color); + lv_draw_vector_dsc_set_fill_opa(vector_dsc, glyph_dsc->outline_stroke_opa); + lv_draw_vector_dsc_add_path(vector_dsc, glyph_paths->outside_path); } - lv_vector_dsc_set_fill_color(vector_dsc, glyph_dsc->color); - lv_vector_dsc_set_fill_opa(vector_dsc, glyph_dsc->opa); - lv_vector_dsc_add_path(vector_dsc, glyph_paths->inside_path); + lv_draw_vector_dsc_set_fill_color(vector_dsc, glyph_dsc->color); + lv_draw_vector_dsc_set_fill_opa(vector_dsc, glyph_dsc->opa); + lv_draw_vector_dsc_add_path(vector_dsc, glyph_paths->inside_path); } else { @@ -312,16 +317,16 @@ static void draw_letter_outline(lv_draw_task_t * t, lv_draw_glyph_dsc_t * glyph_ /*Can't call lv_draw_vector() as it would create a new draw task while *the main thread also can create draw tasks. So create a dummy draw task *manually to draw the outline*/ - if(vector_dsc->tasks.task_list) { - vector_dsc->tasks.base.layer = vector_dsc->layer; + if(vector_dsc->task_list) { + vector_dsc->base.layer = vector_dsc->base.layer; lv_draw_task_t dummy_t; lv_memzero(&dummy_t, sizeof(lv_draw_task_t)); - dummy_t.area = vector_dsc->layer->_clip_area; - dummy_t._real_area = vector_dsc->layer->_clip_area; - dummy_t.clip_area = vector_dsc->layer->_clip_area; - dummy_t.target_layer = vector_dsc->layer; + dummy_t.area = vector_dsc->base.layer->_clip_area; + dummy_t._real_area = vector_dsc->base.layer->_clip_area; + dummy_t.clip_area = vector_dsc->base.layer->_clip_area; + dummy_t.target_layer = vector_dsc->base.layer; dummy_t.type = LV_DRAW_TASK_TYPE_VECTOR; - dummy_t.draw_dsc = &vector_dsc->tasks; + dummy_t.draw_dsc = vector_dsc; lv_draw_sw_vector(&dummy_t, dummy_t.draw_dsc); } @@ -342,7 +347,7 @@ static void draw_letter_outline(lv_draw_task_t * t, lv_draw_glyph_dsc_t * glyph_ img_dsc.src = draw_buf; lv_draw_sw_image(t, &img_dsc, &letter_coords); - lv_vector_dsc_delete(vector_dsc); + lv_draw_vector_dsc_delete(vector_dsc); lv_draw_buf_destroy(draw_buf); } diff --git a/src/draw/sw/lv_draw_sw_mask.c b/src/draw/sw/lv_draw_sw_mask.c index 0e1a17a67f..7c154ba322 100644 --- a/src/draw/sw/lv_draw_sw_mask.c +++ b/src/draw/sw/lv_draw_sw_mask.c @@ -15,7 +15,7 @@ #include "../../misc/lv_math.h" #include "../../misc/lv_log.h" #include "../../misc/lv_assert.h" -#include "../../osal/lv_os.h" +#include "../../osal/lv_os_private.h" #include "../../stdlib/lv_string.h" /********************* @@ -1137,7 +1137,7 @@ static void circ_calc_aa4(lv_draw_sw_mask_radius_circle_dsc_t * c, int32_t radiu cir_x[cir_size] = x_int[0] - 1; cir_y[cir_size] = y_8th_cnt; - c->cir_opa[cir_size] = 1 * 4 + x_fract[1] + x_fract[2] + x_fract[3];; + c->cir_opa[cir_size] = 1 * 4 + x_fract[1] + x_fract[2] + x_fract[3]; c->cir_opa[cir_size] *= 16; cir_size++; } @@ -1151,7 +1151,7 @@ static void circ_calc_aa4(lv_draw_sw_mask_radius_circle_dsc_t * c, int32_t radiu cir_x[cir_size] = x_int[0] - 1; cir_y[cir_size] = y_8th_cnt; - c->cir_opa[cir_size] = 2 * 4 + x_fract[2] + x_fract[3];; + c->cir_opa[cir_size] = 2 * 4 + x_fract[2] + x_fract[3]; c->cir_opa[cir_size] *= 16; cir_size++; } @@ -1165,7 +1165,7 @@ static void circ_calc_aa4(lv_draw_sw_mask_radius_circle_dsc_t * c, int32_t radiu cir_x[cir_size] = x_int[0] - 1; cir_y[cir_size] = y_8th_cnt; - c->cir_opa[cir_size] = 3 * 4 + x_fract[3];; + c->cir_opa[cir_size] = 3 * 4 + x_fract[3]; c->cir_opa[cir_size] *= 16; cir_size++; } @@ -1209,7 +1209,7 @@ static void circ_calc_aa4(lv_draw_sw_mask_radius_circle_dsc_t * c, int32_t radiu while(i < cir_size) { c->opa_start_on_y[y] = i; c->x_start_on_y[y] = cir_x[i]; - for(; cir_y[i] == y && i < (int32_t)cir_size; i++) { + for(; i < (int32_t)cir_size && cir_y[i] == y; i++) { c->x_start_on_y[y] = LV_MIN(c->x_start_on_y[y], cir_x[i]); } y++; diff --git a/src/draw/sw/lv_draw_sw_transform.c b/src/draw/sw/lv_draw_sw_transform.c index 30db0620be..11ebed683d 100644 --- a/src/draw/sw/lv_draw_sw_transform.c +++ b/src/draw/sw/lv_draw_sw_transform.c @@ -581,7 +581,7 @@ static void transform_argb8888_premultiplied(const uint8_t * src, int32_t src_w, lv_color32_t px_hor = src_c32[x_next]; lv_color32_t px_ver = *(const lv_color32_t *)((uint8_t *)src_c32 + y_next * src_stride); - /*Have the non-premultipled colors first, mix them as needed, + /*Have the non-premultiplied colors first, mix them as needed, *and premultiply again*/ dest_c32[x] = unpremultiply(dest_c32[x]); px_hor = unpremultiply(px_hor); diff --git a/src/draw/sw/lv_draw_sw_triangle.c b/src/draw/sw/lv_draw_sw_triangle.c index 8d7a4b119f..0cfc36d889 100644 --- a/src/draw/sw/lv_draw_sw_triangle.c +++ b/src/draw/sw/lv_draw_sw_triangle.c @@ -88,8 +88,10 @@ void lv_draw_sw_triangle(lv_draw_task_t * t, const lv_draw_triangle_dsc_t * dsc) if(p[1].y < p[2].y) lv_point_swap(&p[1], &p[2]); } - /*Be sure p[0] is on the top*/ + /*Be sure p[0] is on top followed by lowest point (p[1]) and middle point last (p[2])*/ + if(p[0].y > p[2].y) lv_point_swap(&p[0], &p[2]); if(p[0].y > p[1].y) lv_point_swap(&p[0], &p[1]); + if(p[1].y < p[2].y) lv_point_swap(&p[1], &p[2]); /*If right == true p[2] is on the right side of the p[0] p[1] line*/ bool right = ((p[1].x - p[0].x) * (p[2].y - p[0].y) - (p[1].y - p[0].y) * (p[2].x - p[0].x)) < 0; diff --git a/src/draw/sw/lv_draw_sw_vector.c b/src/draw/sw/lv_draw_sw_vector.c index 6e3493f86a..114d1cd2fe 100644 --- a/src/draw/sw/lv_draw_sw_vector.c +++ b/src/draw/sw/lv_draw_sw_vector.c @@ -1,5 +1,5 @@ /** - * @file lv_draw_img.c + * @file lv_draw_sw_vector.c * */ @@ -48,6 +48,7 @@ typedef struct { int32_t partial_y_offset; int32_t translate_x; int32_t translate_y; + lv_opa_t opa; } _tvg_draw_state; /********************** * STATIC PROTOTYPES @@ -281,7 +282,7 @@ static void _set_paint_fill_gradient(Tvg_Paint * obj, const lv_vector_gradient_t } static void _set_paint_fill_pattern(Tvg_Paint * obj, Tvg_Canvas * canvas, const lv_draw_image_dsc_t * p, - const lv_matrix_t * m) + const lv_matrix_t * m, const lv_opa_t opa) { lv_image_decoder_dsc_t decoder_dsc; lv_image_decoder_args_t args = { 0 }; @@ -298,7 +299,6 @@ static void _set_paint_fill_pattern(Tvg_Paint * obj, Tvg_Canvas * canvas, const return; } - const uint8_t * src_buf = decoder_dsc.decoded->data; const lv_image_header_t * header = &decoder_dsc.decoded->header; lv_color_format_t cf = header->cf; @@ -308,11 +308,24 @@ static void _set_paint_fill_pattern(Tvg_Paint * obj, Tvg_Canvas * canvas, const return; } + const uint32_t tvg_stride = header->w * sizeof(uint32_t); + if(header->stride != tvg_stride) { + LV_LOG_WARN("img_stride != tvg_stride (%" LV_PRIu32 " != %" LV_PRIu32 "), width = %" LV_PRIu32, + (uint32_t)header->stride, + tvg_stride, (uint32_t)header->w); + lv_result_t result = lv_draw_buf_adjust_stride((lv_draw_buf_t *)decoder_dsc.decoded, tvg_stride); + if(result != LV_RESULT_OK) { + lv_image_decoder_close(&decoder_dsc); + LV_LOG_ERROR("Failed to adjust stride"); + return; + } + } + Tvg_Paint * img = tvg_picture_new(); - tvg_picture_load_raw(img, (uint32_t *)src_buf, header->w, header->h, true); + tvg_picture_load_raw(img, (uint32_t *)decoder_dsc.decoded->data, header->w, header->h, true); Tvg_Paint * clip_path = tvg_paint_duplicate(obj); tvg_paint_set_composite_method(img, clip_path, TVG_COMPOSITE_METHOD_CLIP_PATH); - tvg_paint_set_opacity(img, p->opa); + tvg_paint_set_opacity(img, LV_UDIV255(p->opa * opa)); Tvg_Matrix mtx; lv_matrix_to_tvg(&mtx, m); @@ -322,7 +335,7 @@ static void _set_paint_fill_pattern(Tvg_Paint * obj, Tvg_Canvas * canvas, const } static void _set_paint_fill(Tvg_Paint * obj, Tvg_Canvas * canvas, const lv_vector_fill_dsc_t * dsc, - const lv_matrix_t * matrix) + const lv_matrix_t * matrix, const lv_opa_t opa) { tvg_shape_set_fill_rule(obj, lv_fill_rule_to_tvg(dsc->fill_rule)); @@ -343,7 +356,7 @@ static void _set_paint_fill(Tvg_Paint * obj, Tvg_Canvas * canvas, const lv_vecto lv_matrix_multiply(&imx, &dsc->matrix); - _set_paint_fill_pattern(obj, canvas, &dsc->img_dsc, &imx); + _set_paint_fill_pattern(obj, canvas, &dsc->img_dsc, &imx, opa); } else if(dsc->style == LV_VECTOR_DRAW_STYLE_GRADIENT) { _set_paint_fill_gradient(obj, &dsc->gradient, &dsc->matrix); @@ -416,14 +429,13 @@ static void _blend_draw_buf(lv_draw_buf_t * draw_buf, const lv_area_t * dst_area } } -static void _task_draw_cb(void * ctx, const lv_vector_path_t * path, const lv_vector_draw_dsc_t * dsc) +static void _task_draw_cb(void * ctx, const lv_vector_path_t * path, const lv_vector_path_ctx_t * dsc) { _tvg_draw_state * state = (_tvg_draw_state *)ctx; Tvg_Canvas * canvas = (Tvg_Canvas *)state->canvas; Tvg_Paint * obj = tvg_shape_new(); - int32_t y_offset = state->partial_y_offset; _tvg_rect rc; lv_area_to_tvg(&rc, &dsc->scissor_area); @@ -437,12 +449,11 @@ static void _task_draw_cb(void * ctx, const lv_vector_path_t * path, const lv_ve 0.0f, 0.0f, 1.0f, }; _set_paint_matrix(obj, &mtx); - mtx.e23 -= (float)(y_offset); tvg_shape_append_rect(obj, rc.x + state->translate_x, rc.y + state->translate_y, rc.w, rc.h, 0, 0); tvg_shape_set_fill_color(obj, c.r, c.g, c.b, c.a); } else { - tvg_canvas_set_viewport(canvas, (int32_t)rc.x + state->translate_x, (int32_t)(rc.y - y_offset) + state->translate_y, + tvg_canvas_set_viewport(canvas, (int32_t)rc.x + state->translate_x, (int32_t)rc.y + state->translate_y, (int32_t)rc.w, (int32_t)rc.h); lv_matrix_t matrix; @@ -451,15 +462,15 @@ static void _task_draw_cb(void * ctx, const lv_vector_path_t * path, const lv_ve lv_matrix_multiply(&matrix, &dsc->matrix); Tvg_Matrix mtx; lv_matrix_to_tvg(&mtx, &matrix); - mtx.e23 -= (float)(y_offset); _set_paint_matrix(obj, &mtx); _set_paint_shape(obj, path); - _set_paint_fill(obj, canvas, &dsc->fill_dsc, &matrix); + _set_paint_fill(obj, canvas, &dsc->fill_dsc, &matrix, state->opa); _set_paint_stroke(obj, &dsc->stroke_dsc); _set_paint_blend_mode(obj, dsc->blend_mode); } + tvg_paint_set_opacity(obj, state->opa); tvg_canvas_push(canvas, obj); } @@ -467,7 +478,7 @@ static void _task_draw_cb(void * ctx, const lv_vector_path_t * path, const lv_ve * GLOBAL FUNCTIONS **********************/ -void lv_draw_sw_vector(lv_draw_task_t * t, lv_draw_vector_task_dsc_t * dsc) +void lv_draw_sw_vector(lv_draw_task_t * t, lv_draw_vector_dsc_t * dsc) { if(dsc->task_list == NULL) return; @@ -502,7 +513,7 @@ void lv_draw_sw_vector(lv_draw_task_t * t, lv_draw_vector_task_dsc_t * dsc) lv_area_to_tvg(&rc, &t->clip_area); tvg_canvas_set_viewport(canvas, (int32_t)rc.x, (int32_t)(rc.y - layer->partial_y_offset), (int32_t)rc.w, (int32_t)rc.h); - _tvg_draw_state state = {canvas, layer->partial_y_offset, -layer->buf_area.x1, -layer->buf_area.y1}; + _tvg_draw_state state = {canvas, layer->partial_y_offset, -layer->buf_area.x1, -layer->buf_area.y1, t->opa}; lv_ll_t * task_list = dsc->task_list; lv_vector_for_each_destroy_tasks(task_list, _task_draw_cb, &state); diff --git a/src/draw/vg_lite/lv_draw_buf_vg_lite.c b/src/draw/vg_lite/lv_draw_buf_vg_lite.c index de0b4b90bc..9d31737439 100644 --- a/src/draw/vg_lite/lv_draw_buf_vg_lite.c +++ b/src/draw/vg_lite/lv_draw_buf_vg_lite.c @@ -26,7 +26,7 @@ * STATIC PROTOTYPES **********************/ -static uint32_t width_to_stride(uint32_t w, lv_color_format_t color_format); +static void init_handlers(lv_draw_buf_handlers_t * handlers); /********************** * STATIC VARIABLES @@ -42,8 +42,9 @@ static uint32_t width_to_stride(uint32_t w, lv_color_format_t color_format); void lv_draw_buf_vg_lite_init_handlers(void) { - lv_draw_buf_handlers_t * handlers = lv_draw_buf_get_handlers(); - handlers->width_to_stride_cb = width_to_stride; + init_handlers(lv_draw_buf_get_handlers()); + init_handlers(lv_draw_buf_get_font_handlers()); + init_handlers(lv_draw_buf_get_image_handlers()); } /********************** @@ -55,4 +56,10 @@ static uint32_t width_to_stride(uint32_t w, lv_color_format_t color_format) return lv_vg_lite_width_to_stride(w, lv_vg_lite_vg_fmt(color_format)); } +static void init_handlers(lv_draw_buf_handlers_t * handlers) +{ + LV_ASSERT_NULL(handlers); + handlers->width_to_stride_cb = width_to_stride; +} + #endif /*LV_USE_DRAW_VG_LITE*/ diff --git a/src/draw/vg_lite/lv_draw_vg_lite.c b/src/draw/vg_lite/lv_draw_vg_lite.c index 47c9f91cef..a5f64197da 100644 --- a/src/draw/vg_lite/lv_draw_vg_lite.c +++ b/src/draw/vg_lite/lv_draw_vg_lite.c @@ -1,5 +1,5 @@ /** - * @file lv_vg_lite_draw.c + * @file lv_draw_vg_lite.c * */ @@ -40,6 +40,8 @@ static int32_t draw_evaluate(lv_draw_unit_t * draw_unit, lv_draw_task_t * task); static int32_t draw_delete(lv_draw_unit_t * draw_unit); +static void draw_event_cb(lv_event_t * e); + /********************** * STATIC VARIABLES **********************/ @@ -70,6 +72,7 @@ void lv_draw_vg_lite_init(void) unit->base_unit.dispatch_cb = draw_dispatch; unit->base_unit.evaluate_cb = draw_evaluate; unit->base_unit.delete_cb = draw_delete; + unit->base_unit.event_cb = draw_event_cb; unit->base_unit.name = "VG_LITE"; lv_vg_lite_image_dsc_init(unit); @@ -133,15 +136,13 @@ static void draw_execute(lv_draw_vg_lite_unit_t * u) vg_lite_matrix_t layer_matrix; lv_vg_lite_matrix(&layer_matrix, &t->matrix); lv_vg_lite_matrix_multiply(&u->global_matrix, &layer_matrix); - - /* Crop out extra pixels drawn due to scaling accuracy issues */ - lv_area_t scissor_area = layer->phy_clip_area; -#else - lv_area_t scissor_area = layer->_clip_area; #endif - lv_area_move(&scissor_area, -layer->buf_area.x1, -layer->buf_area.y1); + if(vg_lite_query_feature(gcFEATURE_BIT_VG_SCISSOR)) { - lv_vg_lite_set_scissor_area(&scissor_area); + /* Crop out extra pixels drawn due to scaling accuracy issues */ + lv_area_t scissor_area = layer->phy_clip_area; + lv_area_move(&scissor_area, -layer->buf_area.x1, -layer->buf_area.y1); + lv_vg_lite_set_scissor_area(u, &scissor_area); } switch(t->type) { @@ -223,7 +224,7 @@ static int32_t draw_dispatch(lv_draw_unit_t * draw_unit, lv_layer_t * layer) draw_execute(u); - u->task_act->state = LV_DRAW_TASK_STATE_READY; + u->task_act->state = LV_DRAW_TASK_STATE_FINISHED; u->task_act = NULL; /*The draw unit is free now. Request a new dispatching as it can get a new task*/ @@ -303,4 +304,28 @@ static int32_t draw_delete(lv_draw_unit_t * draw_unit) return 1; } +static void draw_event_cb(lv_event_t * e) +{ + lv_event_code_t code = lv_event_get_code(e); + + switch(code) { + case LV_EVENT_CANCEL: { +#if LV_USE_VECTOR_GRAPHIC + /** + * Because VG-Lite will deinitialize the context (including the GPU independent heap) + * before the GPU goes to sleep, it is necessary to first discard and dereference + * all caches that depend on the independent heap. + */ + lv_draw_vg_lite_unit_t * unit = lv_event_get_current_target(e); + lv_cache_drop_all(lv_vg_lite_grad_ctx_get_cache(unit->grad_ctx), NULL); + lv_cache_drop_all(unit->stroke_cache, NULL); + LV_LOG_INFO("dropt all cache"); +#endif + } + break; + default: + break; + } +} + #endif /*LV_USE_DRAW_VG_LITE*/ diff --git a/src/draw/vg_lite/lv_draw_vg_lite.h b/src/draw/vg_lite/lv_draw_vg_lite.h index 0b873848bd..07a9abceba 100644 --- a/src/draw/vg_lite/lv_draw_vg_lite.h +++ b/src/draw/vg_lite/lv_draw_vg_lite.h @@ -79,7 +79,7 @@ void lv_draw_vg_lite_mask_rect(lv_draw_task_t * t, const lv_draw_mask_rect_dsc_t const lv_area_t * coords); #if LV_USE_VECTOR_GRAPHIC -void lv_draw_vg_lite_vector(lv_draw_task_t * t, const lv_draw_vector_task_dsc_t * dsc); +void lv_draw_vg_lite_vector(lv_draw_task_t * t, const lv_draw_vector_dsc_t * dsc); #endif /********************** diff --git a/src/draw/vg_lite/lv_draw_vg_lite_border.c b/src/draw/vg_lite/lv_draw_vg_lite_border.c index 52c623ac2d..a769d73b28 100644 --- a/src/draw/vg_lite/lv_draw_vg_lite_border.c +++ b/src/draw/vg_lite/lv_draw_vg_lite_border.c @@ -164,7 +164,7 @@ static vg_lite_fill_t path_append_inner_rect(lv_vg_lite_path_t * path, return VG_LITE_FILL_EVEN_ODD; } - /* reset outter rect path */ + /* reset outer rect path */ lv_vg_lite_path_reset(path, VG_LITE_FP32); /* coordinate reference map: https://github.com/lvgl/lvgl/pull/6796 */ diff --git a/src/draw/vg_lite/lv_draw_vg_lite_fill.c b/src/draw/vg_lite/lv_draw_vg_lite_fill.c index d0fd89aaec..37cb372e8d 100644 --- a/src/draw/vg_lite/lv_draw_vg_lite_fill.c +++ b/src/draw/vg_lite/lv_draw_vg_lite_fill.c @@ -58,6 +58,14 @@ void lv_draw_vg_lite_fill(lv_draw_task_t * t, const lv_draw_fill_dsc_t * dsc, co vg_lite_matrix_t matrix = u->global_matrix; + /* Improve GPU rendering efficiency using simpler fill modes */ + if(dsc->radius == 0 && dsc->opa >= LV_OPA_MAX && dsc->grad.dir == LV_GRAD_DIR_NONE && + lv_matrix_is_identity((lv_matrix_t *)&matrix)) { + lv_vg_lite_clear(&u->target_buffer, &clip_area, lv_vg_lite_color(dsc->color, LV_OPA_COVER, false)); + LV_PROFILER_DRAW_END; + return; + } + lv_vg_lite_path_t * path = lv_vg_lite_path_get(u, VG_LITE_FP32); lv_vg_lite_path_set_quality(path, dsc->radius == 0 ? VG_LITE_LOW : VG_LITE_HIGH); lv_vg_lite_path_set_bounding_box_area(path, &clip_area); diff --git a/src/draw/vg_lite/lv_draw_vg_lite_img.c b/src/draw/vg_lite/lv_draw_vg_lite_img.c index a98aa6e0c3..e26ab67085 100644 --- a/src/draw/vg_lite/lv_draw_vg_lite_img.c +++ b/src/draw/vg_lite/lv_draw_vg_lite_img.c @@ -51,22 +51,8 @@ void lv_draw_vg_lite_img(lv_draw_task_t * t, const lv_draw_image_dsc_t * dsc, { lv_draw_vg_lite_unit_t * u = (lv_draw_vg_lite_unit_t *)t->draw_unit; - /* The coordinates passed in by coords are not transformed, - * so the transformed area needs to be calculated once. - */ - lv_area_t image_tf_area; - lv_image_buf_get_transformed_area( - &image_tf_area, - lv_area_get_width(coords), - lv_area_get_height(coords), - dsc->rotation, - dsc->scale_x, - dsc->scale_y, - &dsc->pivot); - lv_area_move(&image_tf_area, coords->x1, coords->y1); - lv_area_t clip_area; - if(!lv_area_intersect(&clip_area, &image_tf_area, &t->clip_area)) { + if(!lv_area_intersect(&clip_area, &t->_real_area, &t->clip_area)) { /*Fully clipped, nothing to do*/ return; } @@ -86,7 +72,8 @@ void lv_draw_vg_lite_img(lv_draw_task_t * t, const lv_draw_image_dsc_t * dsc, vg_lite_color_t color = lv_vg_lite_image_recolor(&src_buf, dsc); /* convert the blend mode to vg-lite blend mode, considering the premultiplied alpha */ - bool has_pre_mul = lv_draw_buf_has_flag(decoder_dsc.decoded, LV_IMAGE_FLAGS_PREMULTIPLIED); + bool has_pre_mul = lv_draw_buf_has_flag(decoder_dsc.decoded, LV_IMAGE_FLAGS_PREMULTIPLIED) + || (decoder_dsc.decoded->header.cf == LV_COLOR_FORMAT_ARGB8888_PREMULTIPLIED); vg_lite_blend_t blend = lv_vg_lite_blend_mode(dsc->blend_mode, has_pre_mul); /* original image matrix */ @@ -98,17 +85,25 @@ void lv_draw_vg_lite_img(lv_draw_task_t * t, const lv_draw_image_dsc_t * dsc, vg_lite_matrix_t matrix = u->global_matrix; lv_vg_lite_matrix_multiply(&matrix, &image_matrix); - bool has_transform = matrix_has_transform(&matrix); - vg_lite_filter_t filter = has_transform ? VG_LITE_FILTER_BI_LINEAR : VG_LITE_FILTER_POINT; + const bool has_transform = matrix_has_transform(&matrix); + const vg_lite_filter_t filter = has_transform ? VG_LITE_FILTER_BI_LINEAR : VG_LITE_FILTER_POINT; + + /* Use coords as the fallback image width and height */ + const uint32_t img_w = dsc->header.w ? dsc->header.w : lv_area_get_width(coords); + const uint32_t img_h = dsc->header.h ? dsc->header.h : lv_area_get_height(coords); + + if(dsc->colorkey) { + lv_vg_lite_set_color_key(dsc->colorkey); + } /* If clipping is not required, blit directly */ - if(lv_area_is_in(&image_tf_area, &t->clip_area, false) && dsc->clip_radius <= 0) { + if(lv_area_is_in(&t->_real_area, &t->clip_area, false) && dsc->clip_radius <= 0 && !dsc->tile) { /* rect is used to crop the pixel-aligned padding area */ vg_lite_rectangle_t rect = { .x = 0, .y = 0, - .width = lv_area_get_width(coords), - .height = lv_area_get_height(coords), + .width = img_w, + .height = img_h, }; lv_vg_lite_blit_rect( @@ -119,38 +114,107 @@ void lv_draw_vg_lite_img(lv_draw_task_t * t, const lv_draw_image_dsc_t * dsc, blend, color, filter); + + lv_vg_lite_pending_add(u->image_dsc_pending, &decoder_dsc); + LV_PROFILER_DRAW_END; + return; } - else { - lv_vg_lite_path_t * path = lv_vg_lite_path_get(u, VG_LITE_FP32); + + lv_vg_lite_path_t * path = lv_vg_lite_path_get(u, VG_LITE_FP32); + + if(dsc->tile) { + /* When the image is tiled, use coords as the tile area and create a path around it */ + lv_vg_lite_path_append_rect( + path, + coords->x1, coords->y1, + lv_area_get_width(coords), lv_area_get_height(coords), + dsc->clip_radius); + } + else if(has_transform || dsc->clip_radius) { /** * When the image is transformed or rounded, create a path around * the image and follow the image_matrix for coordinate transformation */ - if(has_transform || dsc->clip_radius) { - /* apply the image transform to the path */ - lv_vg_lite_path_set_transform(path, &image_matrix); - lv_vg_lite_path_append_rect( - path, - 0, 0, - lv_area_get_width(&dsc->image_area), lv_area_get_height(&dsc->image_area), - dsc->clip_radius); - lv_vg_lite_path_set_transform(path, NULL); + lv_vg_lite_path_set_transform(path, &image_matrix); + + /* Each point will be transformed accordingly. */ + lv_vg_lite_path_append_rect( + path, + dsc->image_area.x1 - coords->x1, dsc->image_area.y1 - coords->y1, + lv_area_get_width(&dsc->image_area), lv_area_get_height(&dsc->image_area), + dsc->clip_radius); + } + else { + /* append normal rect to the path */ + lv_vg_lite_path_append_rect( + path, + clip_area.x1, clip_area.y1, + lv_area_get_width(&clip_area), lv_area_get_height(&clip_area), + 0); + } + + lv_vg_lite_path_set_bounding_box_area(path, &clip_area); + lv_vg_lite_path_end(path); + + vg_lite_matrix_t path_matrix = u->global_matrix; + + if(dsc->tile) { + lv_area_t tile_area; + if(lv_area_get_width(&dsc->image_area) >= 0) { + tile_area = dsc->image_area; } else { - /* append normal rect to the path */ - lv_vg_lite_path_append_rect( - path, - clip_area.x1, clip_area.y1, - lv_area_get_width(&clip_area), lv_area_get_height(&clip_area), - 0); + tile_area = *coords; } + lv_area_set_width(&tile_area, img_w); + lv_area_set_height(&tile_area, img_h); - lv_vg_lite_path_set_bounding_box_area(path, &clip_area); - lv_vg_lite_path_end(path); - - vg_lite_matrix_t path_matrix = u->global_matrix; - + /** + * vg_lite_tvg does not support VG_LITE_PATTERN_REPEAT, + * use looping texture for simulation. + */ +#if LV_USE_VG_LITE_THORVG + const int32_t tile_x_start = tile_area.x1; + while(tile_area.y1 <= coords->y2) { + while(tile_area.x1 <= coords->x2) { +#endif + vg_lite_matrix_t tile_matrix; + vg_lite_identity(&tile_matrix); + vg_lite_translate(tile_area.x1 - coords->x1, tile_area.y1 - coords->y1, &tile_matrix); + + vg_lite_matrix_t pattern_matrix = matrix; + lv_vg_lite_matrix_multiply(&pattern_matrix, &tile_matrix); + + lv_area_t clipped_img_area; + if(!LV_USE_VG_LITE_THORVG || lv_area_intersect(&clipped_img_area, &tile_area, coords)) { + lv_vg_lite_draw_pattern( + &u->target_buffer, + lv_vg_lite_path_get_path(path), + VG_LITE_FILL_EVEN_ODD, + &path_matrix, + &src_buf, + &pattern_matrix, + blend, + VG_LITE_PATTERN_REPEAT, + 0, + color, + filter); + } + +#if LV_USE_VG_LITE_THORVG + tile_area.x1 += img_w; + tile_area.x2 += img_w; + } + + tile_area.y1 += img_h; + tile_area.y2 += img_h; + tile_area.x1 = tile_x_start; + tile_area.x2 = tile_x_start + img_w - 1; + } +#endif + } + else { lv_vg_lite_draw_pattern( &u->target_buffer, lv_vg_lite_path_get_path(path), @@ -163,10 +227,14 @@ void lv_draw_vg_lite_img(lv_draw_task_t * t, const lv_draw_image_dsc_t * dsc, 0, color, filter); + } - lv_vg_lite_path_drop(u, path); + if(dsc->colorkey) { + lv_vg_lite_set_color_key(NULL); } + lv_vg_lite_path_drop(u, path); + lv_vg_lite_pending_add(u->image_dsc_pending, &decoder_dsc); LV_PROFILER_DRAW_END; } diff --git a/src/draw/vg_lite/lv_draw_vg_lite_label.c b/src/draw/vg_lite/lv_draw_vg_lite_label.c index afbdd37df1..9ab37bfc4d 100644 --- a/src/draw/vg_lite/lv_draw_vg_lite_label.c +++ b/src/draw/vg_lite/lv_draw_vg_lite_label.c @@ -20,6 +20,7 @@ #include "../../misc/lv_area_private.h" #include "../../libs/freetype/lv_freetype_private.h" #include "../lv_draw_label_private.h" +#include "../lv_draw_image_private.h" /********************* @@ -53,13 +54,14 @@ static void draw_letter_cb(lv_draw_task_t * t, lv_draw_glyph_dsc_t * glyph_draw_dsc, lv_draw_fill_dsc_t * fill_draw_dsc, const lv_area_t * fill_area); -static void draw_letter_bitmap(lv_draw_task_t * t, const lv_draw_glyph_dsc_t * dsc); +static void draw_letter_bitmap(lv_draw_task_t * t, const lv_draw_glyph_dsc_t * dsc, vg_lite_buffer_t * src_buf); static void bitmap_cache_release_cb(void * entry, void * user_data); #if LV_USE_FREETYPE static void freetype_outline_event_cb(lv_event_t * e); static void draw_letter_outline(lv_draw_task_t * t, const lv_draw_glyph_dsc_t * dsc); + static void outline_iter_cb(void * user_data, uint8_t op_code, const float * data, uint32_t len); #endif /* LV_USE_FREETYPE */ /********************** @@ -135,6 +137,27 @@ void lv_draw_vg_lite_label(lv_draw_task_t * t, const lv_draw_label_dsc_t * dsc, * STATIC FUNCTIONS **********************/ +static inline bool init_buffer_from_glyph_dsc(vg_lite_buffer_t * buffer, lv_font_glyph_dsc_t * g_dsc) +{ + const void * glyph_bitmap = lv_font_get_glyph_static_bitmap(g_dsc); + if(!glyph_bitmap) { + return false; + } + + if(!LV_VG_LITE_IS_ALIGNED(glyph_bitmap, 16)) { + LV_LOG_WARN("Glyph data %p is not aligned to 16 bytes", glyph_bitmap); + return false; + } + + if(!LV_VG_LITE_IS_ALIGNED(g_dsc->stride, 16)) { + LV_LOG_WARN("Glyph stride %" LV_PRIu32 " is not aligned to 16 bytes", g_dsc->stride); + return false; + } + + lv_vg_lite_buffer_init(buffer, glyph_bitmap, g_dsc->box_w, g_dsc->box_h, g_dsc->stride, VG_LITE_A8, false); + return true; +} + static void draw_letter_cb(lv_draw_task_t * t, lv_draw_glyph_dsc_t * glyph_draw_dsc, lv_draw_fill_dsc_t * fill_draw_dsc, const lv_area_t * fill_area) { @@ -146,12 +169,22 @@ static void draw_letter_cb(lv_draw_task_t * t, lv_draw_glyph_dsc_t * glyph_draw_ case LV_FONT_GLYPH_FORMAT_A3: case LV_FONT_GLYPH_FORMAT_A4: case LV_FONT_GLYPH_FORMAT_A8: { - glyph_draw_dsc->glyph_data = lv_font_get_glyph_bitmap(glyph_draw_dsc->g, glyph_draw_dsc->_draw_buf); - if(!glyph_draw_dsc->glyph_data) { - return; + vg_lite_buffer_t src_buf; + if(lv_font_has_static_bitmap(glyph_draw_dsc->g->resolved_font)) { + if(!init_buffer_from_glyph_dsc(&src_buf, glyph_draw_dsc->g)) { + return; + } } + else { + glyph_draw_dsc->glyph_data = lv_font_get_glyph_bitmap(glyph_draw_dsc->g, glyph_draw_dsc->_draw_buf); + if(!glyph_draw_dsc->glyph_data) { + return; + } - draw_letter_bitmap(t, glyph_draw_dsc); + lv_vg_lite_buffer_from_draw_buf(&src_buf, glyph_draw_dsc->glyph_data); + } + + draw_letter_bitmap(t, glyph_draw_dsc, &src_buf); } break; @@ -213,50 +246,87 @@ static void draw_letter_cb(lv_draw_task_t * t, lv_draw_glyph_dsc_t * glyph_draw_ } } -static void draw_letter_bitmap(lv_draw_task_t * t, const lv_draw_glyph_dsc_t * dsc) +static inline void convert_letter_matrix(vg_lite_matrix_t * matrix, const lv_draw_glyph_dsc_t * dsc) { - lv_area_t clip_area; - lv_draw_vg_lite_unit_t * u = (lv_draw_vg_lite_unit_t *)t->draw_unit; - if(!lv_area_intersect(&clip_area, &t->clip_area, dsc->letter_coords)) { + vg_lite_translate(dsc->letter_coords->x1, dsc->letter_coords->y1, matrix); + + if(!dsc->rotation) { return; } - LV_PROFILER_DRAW_BEGIN; + const lv_point_t pivot = { + .x = dsc->pivot.x, + .y = dsc->g->box_h + dsc->g->ofs_y + }; + vg_lite_translate(pivot.x, pivot.y, matrix); + vg_lite_rotate(dsc->rotation / 10.0f, matrix); + vg_lite_translate(-pivot.x, -pivot.y, matrix); +} - const lv_area_t image_area = *dsc->letter_coords; +static bool draw_letter_clip_areas(lv_draw_task_t * t, const lv_draw_glyph_dsc_t * dsc, lv_area_t * letter_area, + lv_area_t * cliped_area) +{ + *letter_area = *dsc->letter_coords; - vg_lite_matrix_t matrix = u->global_matrix; + if(dsc->rotation) { + const lv_point_t pivot = { + .x = dsc->pivot.x, + .y = dsc->g->box_h + dsc->g->ofs_y + }; - const bool is_rotated = dsc->rotation % 3600 != 0; + lv_image_buf_get_transformed_area( + letter_area, + lv_area_get_width(dsc->letter_coords), + lv_area_get_height(dsc->letter_coords), + dsc->rotation, + LV_SCALE_NONE, + LV_SCALE_NONE, + &pivot); + lv_area_move(letter_area, dsc->letter_coords->x1, dsc->letter_coords->y1); + } - if(!is_rotated) { - vg_lite_translate(image_area.x1, image_area.y1, &matrix); + if(!lv_area_intersect(cliped_area, &t->clip_area, letter_area)) { + return false; } - else { - vg_lite_translate(image_area.x1 + dsc->pivot.x, image_area.y1 + (dsc->g->box_h + dsc->g->ofs_y), &matrix); - vg_lite_rotate(dsc->rotation / 10.0f, &matrix); - vg_lite_translate(-dsc->pivot.x, -dsc->g->box_h - dsc->g->ofs_y, &matrix); + + return true; +} + +static void draw_letter_bitmap(lv_draw_task_t * t, const lv_draw_glyph_dsc_t * dsc, vg_lite_buffer_t * src_buf) +{ + LV_PROFILER_DRAW_BEGIN; + + lv_area_t image_area; + lv_area_t clip_area; + if(!draw_letter_clip_areas(t, dsc, &image_area, &clip_area)) { + LV_PROFILER_DRAW_END; + return; } - vg_lite_buffer_t src_buf; - const lv_draw_buf_t * draw_buf = dsc->glyph_data; - lv_vg_lite_buffer_from_draw_buf(&src_buf, draw_buf); + lv_draw_vg_lite_unit_t * u = (lv_draw_vg_lite_unit_t *)t->draw_unit; + + vg_lite_matrix_t matrix = u->global_matrix; + convert_letter_matrix(&matrix, dsc); const vg_lite_color_t color = lv_vg_lite_color(dsc->color, dsc->opa, true); - /* If clipping is not required, blit directly */ - if(lv_area_is_in(&image_area, &t->clip_area, false)) { - /* rect is used to crop the pixel-aligned padding area */ + /* If rotation is not required, blit directly */ + if(!dsc->rotation) { vg_lite_rectangle_t rect = { - .x = 0, - .y = 0, - .width = lv_area_get_width(&image_area), - .height = lv_area_get_height(&image_area) + .x = clip_area.x1 - image_area.x1, + .y = clip_area.y1 - image_area.y1, + .width = lv_area_get_width(&clip_area), + .height = lv_area_get_height(&clip_area) }; + /* add offset for clipped area */ + if(rect.x || rect.y) { + vg_lite_translate(rect.x, rect.y, &matrix); + } + lv_vg_lite_blit_rect( &u->target_buffer, - &src_buf, + src_buf, &rect, &matrix, VG_LITE_BLEND_SRC_OVER, @@ -267,21 +337,20 @@ static void draw_letter_bitmap(lv_draw_task_t * t, const lv_draw_glyph_dsc_t * d lv_vg_lite_path_t * path = lv_vg_lite_path_get(u, VG_LITE_S16); lv_vg_lite_path_append_rect( path, - clip_area.x1, clip_area.y1, - lv_area_get_width(&clip_area), lv_area_get_height(&clip_area), + image_area.x1, image_area.y1, + lv_area_get_width(&image_area), lv_area_get_height(&image_area), 0); - lv_vg_lite_path_set_bounding_box_area(path, &clip_area); lv_vg_lite_path_end(path); + lv_vg_lite_path_set_bounding_box_area(path, &clip_area); vg_lite_matrix_t path_matrix = u->global_matrix; - if(is_rotated) vg_lite_rotate(dsc->rotation / 10.0f, &path_matrix); lv_vg_lite_draw_pattern( &u->target_buffer, lv_vg_lite_path_get_path(path), VG_LITE_FILL_EVEN_ODD, &path_matrix, - &src_buf, + src_buf, &matrix, VG_LITE_BLEND_SRC_OVER, VG_LITE_PATTERN_COLOR, @@ -298,8 +367,8 @@ static void draw_letter_bitmap(lv_draw_task_t * t, const lv_draw_glyph_dsc_t * d lv_cache_entry_acquire_data(dsc->g->entry); lv_vg_lite_pending_add(u->bitmap_font_pending, dsc->g); } - else { - /* No caching, wait for GPU finish before releasing the data */ + else if(!lv_font_has_static_bitmap(dsc->g->resolved_font)) { + /* If there is no caching or no static bitmap is used, wait for the GPU to finish before releasing the data. */ lv_vg_lite_finish(u); } @@ -317,79 +386,117 @@ static void bitmap_cache_release_cb(void * entry, void * user_data) static void draw_letter_outline(lv_draw_task_t * t, const lv_draw_glyph_dsc_t * dsc) { - lv_draw_vg_lite_unit_t * u = (lv_draw_vg_lite_unit_t *)t->draw_unit; - /* get clip area */ + LV_PROFILER_DRAW_BEGIN; + + lv_area_t letter_area; lv_area_t path_clip_area; - if(!lv_area_intersect(&path_clip_area, &t->clip_area, dsc->letter_coords)) { + if(!draw_letter_clip_areas(t, dsc, &letter_area, &path_clip_area)) { + LV_PROFILER_DRAW_END; return; } - LV_PROFILER_DRAW_BEGIN; + lv_draw_vg_lite_unit_t * u = (lv_draw_vg_lite_unit_t *)t->draw_unit; /* vg-lite bounding_box will crop the pixels on the edge, so +1px is needed here */ path_clip_area.x2++; path_clip_area.y2++; lv_vg_lite_path_t * outline = (lv_vg_lite_path_t *)dsc->glyph_data; - const lv_point_t pos = {dsc->letter_coords->x1, dsc->letter_coords->y1}; + const lv_point_t glyph_pos = { + dsc->letter_coords->x1 - dsc->g->ofs_x, + dsc->letter_coords->y1 + dsc->g->box_h + dsc->g->ofs_y + }; /* scale size */ const float scale = FT_F26DOT6_TO_PATH_SCALE(lv_freetype_outline_get_scale(dsc->g->resolved_font)); - const bool is_rotated = dsc->rotation % 3600 != 0; + + const bool has_rotation_with_cliped = dsc->rotation && !lv_area_is_in(&letter_area, &t->clip_area, false); /* calc convert matrix */ vg_lite_matrix_t matrix; vg_lite_identity(&matrix); - if(!is_rotated) { - vg_lite_translate(pos.x - dsc->g->ofs_x, pos.y + dsc->g->box_h + dsc->g->ofs_y, &matrix); - vg_lite_scale(scale, scale, &matrix); - } - else { - vg_lite_translate(pos.x - dsc->g->ofs_x + dsc->pivot.x, pos.y + dsc->g->box_h + dsc->g->ofs_y, &matrix); + if(!has_rotation_with_cliped && dsc->rotation) { + vg_lite_translate(glyph_pos.x + dsc->pivot.x, glyph_pos.y, &matrix); vg_lite_rotate(dsc->rotation / 10.0f, &matrix); vg_lite_translate(-dsc->pivot.x, 0, &matrix); - vg_lite_scale(scale, scale, &matrix); + } + else { + vg_lite_translate(glyph_pos.x, glyph_pos.y, &matrix); } - if(vg_lite_query_feature(gcFEATURE_BIT_VG_SCISSOR)) { - /* set scissor area */ - lv_vg_lite_set_scissor_area(&t->clip_area); + vg_lite_scale(scale, scale, &matrix); - /* no bounding box */ - lv_vg_lite_path_set_bounding_box(outline, - (float)PATH_COORD_MIN, (float)PATH_COORD_MIN, - (float)PATH_COORD_MAX, (float)PATH_COORD_MAX); + /* matrix for drawing, different from matrix for calculating the bounding box */ + vg_lite_matrix_t draw_matrix = u->global_matrix; + lv_vg_lite_matrix_multiply(&draw_matrix, &matrix); + + /* calc inverse matrix */ + vg_lite_matrix_t result; + if(!lv_vg_lite_matrix_inverse(&result, &matrix)) { + LV_LOG_ERROR("no inverse matrix"); + lv_vg_lite_matrix_dump_info(&matrix); + LV_PROFILER_DRAW_END; + return; } - else { - if(is_rotated) { - LV_LOG_WARN("clip may be incorrect when vg_lite_query_feature(gcFEATURE_BIT_VG_SCISSOR) is false"); - } - /* calc inverse matrix */ - vg_lite_matrix_t result; - if(!lv_vg_lite_matrix_inverse(&result, &matrix)) { - LV_LOG_ERROR("no inverse matrix"); - LV_PROFILER_DRAW_END; - return; - } + const lv_point_precise_t p1 = { path_clip_area.x1, path_clip_area.y1 }; + const lv_point_precise_t p1_res = lv_vg_lite_matrix_transform_point(&result, &p1); + const lv_point_precise_t p2 = { path_clip_area.x2, path_clip_area.y2 }; + const lv_point_precise_t p2_res = lv_vg_lite_matrix_transform_point(&result, &p2); - const lv_point_precise_t p1 = { path_clip_area.x1, path_clip_area.y1 }; - const lv_point_precise_t p1_res = lv_vg_lite_matrix_transform_point(&result, &p1); + if(has_rotation_with_cliped) { + /** + * When intersecting the clipping region, + * rotate the path contents without rotating the bounding box for cropping + */ + vg_lite_matrix_t internal_matrix; + vg_lite_identity(&internal_matrix); + const float pivot_x = dsc->pivot.x / scale; + const float pivot_y = dsc->g->box_h + dsc->g->ofs_y; + vg_lite_translate(pivot_x, pivot_y, &internal_matrix); + vg_lite_rotate(dsc->rotation / 10.0f, &internal_matrix); + vg_lite_translate(-pivot_x, -pivot_y, &internal_matrix); + + lv_vg_lite_path_t * outline_transformed = lv_vg_lite_path_get(u, VG_LITE_FP32); + lv_vg_lite_path_set_transform(outline_transformed, &internal_matrix); + lv_vg_lite_path_for_each_data(lv_vg_lite_path_get_path(outline), outline_iter_cb, outline_transformed); + lv_vg_lite_path_set_bounding_box(outline_transformed, p1_res.x, p2_res.y, p2_res.x, p1_res.y); + + lv_vg_lite_draw( + &u->target_buffer, + lv_vg_lite_path_get_path(outline_transformed), + VG_LITE_FILL_NON_ZERO, + &draw_matrix, + VG_LITE_BLEND_SRC_OVER, + lv_vg_lite_color(dsc->color, dsc->opa, true)); - const lv_point_precise_t p2 = { path_clip_area.x2, path_clip_area.y2 }; - const lv_point_precise_t p2_res = lv_vg_lite_matrix_transform_point(&result, &p2); + lv_vg_lite_path_drop(u, outline_transformed); - /* Since the font uses Cartesian coordinates, the y coordinates need to be reversed */ - if(is_rotated) - lv_vg_lite_path_set_bounding_box(outline, - (float)PATH_COORD_MIN, (float)PATH_COORD_MIN, - (float)PATH_COORD_MAX, (float)PATH_COORD_MAX); - else lv_vg_lite_path_set_bounding_box(outline, p1_res.x, p2_res.y, p2_res.x, p1_res.y); + LV_PROFILER_DRAW_END; + return; } - /* matrix for drawing, different from matrix for calculating the bounding box */ - vg_lite_matrix_t draw_matrix = u->global_matrix; - lv_vg_lite_matrix_multiply(&draw_matrix, &matrix); + if(dsc->rotation) { + /* The bounding rectangle before scaling relative to the original coordinates of the path */ + lv_area_t box_area; + box_area.x1 = dsc->g->ofs_x; + box_area.y1 = -dsc->g->box_h - dsc->g->ofs_y; + lv_area_set_width(&box_area, dsc->g->box_w); + lv_area_set_height(&box_area, dsc->g->box_h); + + /* Workaround for loss of rotation precision */ + lv_area_increase(&box_area, 5, 5); + + /* Scale the path area to fit the original path data */ + lv_vg_lite_path_set_bounding_box(outline, + box_area.x1 / scale, + box_area.y1 / scale, + box_area.x2 / scale, + box_area.y2 / scale); + } + else { + lv_vg_lite_path_set_bounding_box(outline, p1_res.x, p2_res.y, p2_res.x, p1_res.y); + } lv_vg_lite_draw( &u->target_buffer, @@ -463,6 +570,42 @@ static void freetype_outline_event_cb(lv_event_t * e) LV_PROFILER_DRAW_END; } +static void outline_iter_cb(void * user_data, uint8_t op_code, const float * data, uint32_t len) +{ + LV_UNUSED(len); + typedef struct { + float x; + float y; + } point_t; + + lv_vg_lite_path_t * path = user_data; + const point_t * pt = (point_t *)data; + + switch(op_code) { + case VLC_OP_MOVE: + lv_vg_lite_path_move_to(path, pt->x, pt->y); + break; + case VLC_OP_LINE: + lv_vg_lite_path_line_to(path, pt->x, pt->y); + break; + case VLC_OP_QUAD: + lv_vg_lite_path_quad_to(path, pt[0].x, pt[0].y, pt[1].x, pt[1].y); + break; + case VLC_OP_CUBIC: + lv_vg_lite_path_cubic_to(path, pt[0].x, pt[0].y, pt[1].x, pt[1].y, pt[2].x, pt[2].y); + break; + case VLC_OP_CLOSE: + lv_vg_lite_path_close(path); + break; + case VLC_OP_END: + lv_vg_lite_path_end(path); + break; + default: + LV_ASSERT_FORMAT_MSG(false, "unknown op_code: %d", op_code); + break; + } +} + #endif /* LV_USE_FREETYPE */ #endif /*LV_USE_DRAW_VG_LITE*/ diff --git a/src/draw/vg_lite/lv_draw_vg_lite_mask_rect.c b/src/draw/vg_lite/lv_draw_vg_lite_mask_rect.c index 0620d981f1..934d116dab 100644 --- a/src/draw/vg_lite/lv_draw_vg_lite_mask_rect.c +++ b/src/draw/vg_lite/lv_draw_vg_lite_mask_rect.c @@ -1,5 +1,5 @@ /** - * @file lv_draw_vg_lite_rect.c + * @file lv_draw_vg_lite_mask_rect.c * */ diff --git a/src/draw/vg_lite/lv_draw_vg_lite_type.h b/src/draw/vg_lite/lv_draw_vg_lite_type.h index 99569bea4d..a5cc899618 100644 --- a/src/draw/vg_lite/lv_draw_vg_lite_type.h +++ b/src/draw/vg_lite/lv_draw_vg_lite_type.h @@ -24,8 +24,12 @@ extern "C" { #if LV_USE_VG_LITE_THORVG #include "../../others/vg_lite_tvg/vg_lite.h" #else +#if LV_USE_VG_LITE_DRIVER +#include "../../libs/vg_lite_driver/inc/vg_lite.h" +#else #include #endif +#endif /********************* * DEFINES @@ -41,6 +45,7 @@ struct _lv_vg_lite_grad_ctx_t; struct _lv_draw_vg_lite_unit_t { lv_draw_unit_t base_unit; lv_draw_task_t * task_act; + lv_area_t current_scissor_area; struct _lv_vg_lite_pending_t * image_dsc_pending; diff --git a/src/draw/vg_lite/lv_draw_vg_lite_vector.c b/src/draw/vg_lite/lv_draw_vg_lite_vector.c index 46870434cc..3dc4bc3079 100644 --- a/src/draw/vg_lite/lv_draw_vg_lite_vector.c +++ b/src/draw/vg_lite/lv_draw_vg_lite_vector.c @@ -26,6 +26,8 @@ * DEFINES *********************/ +#define OPA_MIX(opa1, opa2) LV_UDIV255((opa1) * (opa2)) + /********************** * TYPEDEFS **********************/ @@ -37,7 +39,7 @@ typedef void (*path_drop_func_t)(struct _lv_draw_vg_lite_unit_t *, path_drop_dat * STATIC PROTOTYPES **********************/ -static void task_draw_cb(void * ctx, const lv_vector_path_t * path, const lv_vector_draw_dsc_t * dsc); +static void task_draw_cb(void * user_data, const lv_vector_path_t * path, const lv_vector_path_ctx_t * ctx); static void lv_path_to_vg(lv_vg_lite_path_t * dest, const lv_vector_path_t * src, lv_fpoint_t * offset, float expand_bound); static vg_lite_blend_t lv_blend_to_vg(lv_vector_blend_t blend); @@ -55,7 +57,7 @@ static vg_lite_fill_t lv_fill_to_vg(lv_vector_fill_t fill_rule); * GLOBAL FUNCTIONS **********************/ -void lv_draw_vg_lite_vector(lv_draw_task_t * t, const lv_draw_vector_task_dsc_t * dsc) +void lv_draw_vg_lite_vector(lv_draw_task_t * t, const lv_draw_vector_dsc_t * dsc) { if(dsc->task_list == NULL) return; @@ -88,15 +90,16 @@ static vg_lite_color_t lv_color32_to_vg(lv_color32_t color, lv_opa_t opa) static void draw_fill(lv_draw_vg_lite_unit_t * u, lv_vg_lite_path_t * lv_vg_path, - const lv_vector_draw_dsc_t * dsc, + const lv_vector_path_ctx_t * ctx, vg_lite_matrix_t * matrix, - const lv_fpoint_t * offset) + const lv_fpoint_t * offset, + const lv_opa_t opa) { LV_PROFILER_DRAW_BEGIN; - const vg_lite_color_t vg_color = lv_color32_to_vg(dsc->fill_dsc.color, dsc->fill_dsc.opa); - const vg_lite_blend_t blend = lv_blend_to_vg(dsc->blend_mode); - const vg_lite_fill_t fill = lv_fill_to_vg(dsc->fill_dsc.fill_rule); + const vg_lite_color_t vg_color = lv_color32_to_vg(ctx->fill_dsc.color, OPA_MIX(ctx->fill_dsc.opa, opa)); + const vg_lite_blend_t blend = lv_blend_to_vg(ctx->blend_mode); + const vg_lite_fill_t fill = lv_fill_to_vg(ctx->fill_dsc.fill_rule); /* If it is fill mode, the end op code should be added */ lv_vg_lite_path_end(lv_vg_path); @@ -104,7 +107,7 @@ static void draw_fill(lv_draw_vg_lite_unit_t * u, vg_lite_path_t * vg_path = lv_vg_lite_path_get_path(lv_vg_path); LV_VG_LITE_ASSERT_PATH(vg_path); - switch(dsc->fill_dsc.style) { + switch(ctx->fill_dsc.style) { case LV_VECTOR_DRAW_STYLE_SOLID: { /* normal draw shape */ lv_vg_lite_draw( @@ -120,21 +123,32 @@ static void draw_fill(lv_draw_vg_lite_unit_t * u, /* draw image */ vg_lite_buffer_t image_buffer; lv_image_decoder_dsc_t decoder_dsc; - if(lv_vg_lite_buffer_open_image(&image_buffer, &decoder_dsc, dsc->fill_dsc.img_dsc.src, false, true)) { + if(lv_vg_lite_buffer_open_image(&image_buffer, &decoder_dsc, ctx->fill_dsc.img_dsc.src, false, true)) { /* Calculate pattern matrix. Should start from path bond box, and also apply fill matrix. */ vg_lite_matrix_t pattern_matrix = *matrix; - if(dsc->fill_dsc.fill_units == LV_VECTOR_FILL_UNITS_OBJECT_BOUNDING_BOX) { + if(ctx->fill_dsc.fill_units == LV_VECTOR_FILL_UNITS_OBJECT_BOUNDING_BOX) { /* Convert to object bounding box coordinates */ vg_lite_translate(offset->x, offset->y, &pattern_matrix); } vg_lite_matrix_t fill_matrix; - lv_vg_lite_matrix(&fill_matrix, &dsc->fill_dsc.matrix); + lv_vg_lite_matrix(&fill_matrix, &ctx->fill_dsc.matrix); lv_vg_lite_matrix_multiply(&pattern_matrix, &fill_matrix); - vg_lite_color_t recolor = lv_vg_lite_image_recolor(&image_buffer, &dsc->fill_dsc.img_dsc); + const lv_draw_image_dsc_t * img_dsc = &ctx->fill_dsc.img_dsc; + lv_draw_image_dsc_t tmp_dsc; + if(opa < LV_OPA_COVER) { + tmp_dsc = ctx->fill_dsc.img_dsc; + tmp_dsc.opa = OPA_MIX(tmp_dsc.opa, opa); + img_dsc = &tmp_dsc; + } + + vg_lite_color_t recolor = lv_vg_lite_image_recolor(&image_buffer, img_dsc); + if(ctx->fill_dsc.img_dsc.colorkey) { + lv_vg_lite_set_color_key(ctx->fill_dsc.img_dsc.colorkey); + } lv_vg_lite_draw_pattern( &u->target_buffer, vg_path, @@ -148,30 +162,36 @@ static void draw_fill(lv_draw_vg_lite_unit_t * u, recolor, VG_LITE_FILTER_BI_LINEAR); + if(ctx->fill_dsc.img_dsc.colorkey) { + lv_vg_lite_set_color_key(NULL); + } + lv_vg_lite_pending_add(u->image_dsc_pending, &decoder_dsc); } } break; case LV_VECTOR_DRAW_STYLE_GRADIENT: { vg_lite_matrix_t grad_matrix = *matrix; - -#if LV_USE_VG_LITE_THORVG - /* Workaround inconsistent radial gradient matrix behavior between device and ThorVG */ - if(dsc->fill_dsc.gradient.style == LV_VECTOR_GRADIENT_STYLE_RADIAL) { - /* Restore matrix to identity */ - vg_lite_identity(&grad_matrix); - } -#endif - vg_lite_matrix_t fill_matrix; - lv_vg_lite_matrix(&fill_matrix, &dsc->fill_dsc.matrix); + lv_vg_lite_matrix(&fill_matrix, &ctx->fill_dsc.matrix); lv_vg_lite_matrix_multiply(&grad_matrix, &fill_matrix); + const lv_vector_gradient_t * gradient = &ctx->fill_dsc.gradient; + lv_vector_gradient_t tmp_gradient; + if(opa < LV_OPA_COVER) { + tmp_gradient = ctx->fill_dsc.gradient; + for(uint16_t i = 0; i < tmp_gradient.stops_count; i++) { + tmp_gradient.stops[i].opa = OPA_MIX(tmp_gradient.stops[i].opa, opa); + } + + gradient = &tmp_gradient; + } + lv_vg_lite_draw_grad( u->grad_ctx, &u->target_buffer, vg_path, - &dsc->fill_dsc.gradient, + gradient, &grad_matrix, matrix, fill, @@ -179,7 +199,7 @@ static void draw_fill(lv_draw_vg_lite_unit_t * u, } break; default: - LV_LOG_WARN("unsupported style: %d", dsc->fill_dsc.style); + LV_LOG_WARN("unsupported style: %d", ctx->fill_dsc.style); break; } @@ -189,15 +209,16 @@ static void draw_fill(lv_draw_vg_lite_unit_t * u, static void draw_stroke(lv_draw_vg_lite_unit_t * u, const lv_vector_path_t * path, lv_vg_lite_path_t * lv_vg_path, - const lv_vector_draw_dsc_t * dsc, - vg_lite_matrix_t * matrix) + const lv_vector_path_ctx_t * ctx, + vg_lite_matrix_t * matrix, + const lv_opa_t opa) { LV_PROFILER_DRAW_BEGIN; vg_lite_path_t * vg_path = lv_vg_lite_path_get_path(lv_vg_path); LV_UNUSED(path); - lv_cache_entry_t * stroke_cache_entey = lv_vg_lite_stroke_get(u, lv_vg_path, &dsc->stroke_dsc); + lv_cache_entry_t * stroke_cache_entey = lv_vg_lite_stroke_get(u, lv_vg_path, &ctx->stroke_dsc); if(!stroke_cache_entey) { LV_LOG_ERROR("convert stroke failed"); LV_PROFILER_DRAW_END; @@ -208,16 +229,16 @@ static void draw_stroke(lv_draw_vg_lite_unit_t * u, /* set stroke params */ vg_stroke_path->quality = vg_path->quality; - vg_stroke_path->stroke_color = lv_color32_to_vg(dsc->stroke_dsc.color, dsc->stroke_dsc.opa); + vg_stroke_path->stroke_color = lv_color32_to_vg(ctx->stroke_dsc.color, OPA_MIX(ctx->stroke_dsc.opa, opa)); const vg_lite_color_t vg_color = 0; /* set stroke path bounding box */ lv_memcpy(vg_stroke_path->bounding_box, vg_path->bounding_box, sizeof(vg_path->bounding_box)); LV_VG_LITE_ASSERT_PATH(vg_stroke_path); - const vg_lite_blend_t blend = lv_blend_to_vg(dsc->blend_mode); + const vg_lite_blend_t blend = lv_blend_to_vg(ctx->blend_mode); - switch(dsc->stroke_dsc.style) { + switch(ctx->stroke_dsc.style) { case LV_VECTOR_DRAW_STYLE_SOLID: { /* normal draw shape */ lv_vg_lite_draw( @@ -230,7 +251,7 @@ static void draw_stroke(lv_draw_vg_lite_unit_t * u, } break; default: - LV_LOG_WARN("unsupported style: %d", dsc->stroke_dsc.style); + LV_LOG_WARN("unsupported style: %d", ctx->stroke_dsc.style); break; } @@ -238,36 +259,27 @@ static void draw_stroke(lv_draw_vg_lite_unit_t * u, LV_PROFILER_DRAW_END; } -static void task_draw_cb(void * ctx, const lv_vector_path_t * path, const lv_vector_draw_dsc_t * dsc) +static void task_draw_cb(void * user_data, const lv_vector_path_t * path, const lv_vector_path_ctx_t * ctx) { LV_PROFILER_DRAW_BEGIN; - lv_draw_vg_lite_unit_t * u = ctx; + lv_draw_vg_lite_unit_t * u = user_data; LV_VG_LITE_ASSERT_DEST_BUFFER(&u->target_buffer); vg_lite_matrix_t matrix = u->global_matrix; const lv_area_t scissor_area = lv_matrix_is_identity((lv_matrix_t *)&matrix) - ? dsc->scissor_area - : lv_matrix_transform_area((lv_matrix_t *)&matrix, &dsc->scissor_area); + ? ctx->scissor_area + : lv_matrix_transform_area((lv_matrix_t *)&matrix, &ctx->scissor_area); /* clear area */ if(!path) { - /* clear color needs to ignore fill_dsc.opa */ - vg_lite_color_t c = lv_color32_to_vg(dsc->fill_dsc.color, dsc->fill_dsc.opa); - vg_lite_rectangle_t rect; - lv_vg_lite_rect(&rect, &scissor_area); - LV_PROFILER_DRAW_BEGIN_TAG("vg_lite_clear"); - LV_VG_LITE_CHECK_ERROR(vg_lite_clear(&u->target_buffer, &rect, c), { - lv_vg_lite_buffer_dump_info(&u->target_buffer); - LV_LOG_ERROR("rect: X%d Y%d W%d H%d", rect.x, rect.y, rect.width, rect.height); - lv_vg_lite_color_dump_info(c); - }); - LV_PROFILER_DRAW_END_TAG("vg_lite_clear"); + vg_lite_color_t c = lv_color32_to_vg(ctx->fill_dsc.color, OPA_MIX(ctx->fill_dsc.opa, u->task_act->opa)); + lv_vg_lite_clear(&u->target_buffer, &scissor_area, c); LV_PROFILER_DRAW_END; return; } - if(dsc->fill_dsc.opa == LV_OPA_TRANSP && dsc->stroke_dsc.opa == LV_OPA_TRANSP) { + if(ctx->fill_dsc.opa == LV_OPA_TRANSP && ctx->stroke_dsc.opa == LV_OPA_TRANSP) { LV_LOG_TRACE("Full transparent, no need to draw"); LV_PROFILER_DRAW_END; return; @@ -275,7 +287,7 @@ static void task_draw_cb(void * ctx, const lv_vector_path_t * path, const lv_vec /* transform matrix */ vg_lite_matrix_t dsc_matrix; - lv_vg_lite_matrix(&dsc_matrix, &dsc->matrix); + lv_vg_lite_matrix(&dsc_matrix, &ctx->matrix); lv_vg_lite_matrix_multiply(&matrix, &dsc_matrix); LV_VG_LITE_ASSERT_MATRIX(&matrix); @@ -283,11 +295,11 @@ static void task_draw_cb(void * ctx, const lv_vector_path_t * path, const lv_vec lv_vg_lite_path_t * lv_vg_path = lv_vg_lite_path_get(u, VG_LITE_FP32); lv_fpoint_t offset = {0, 0}; - lv_path_to_vg(lv_vg_path, path, &offset, dsc->stroke_dsc.opa ? dsc->stroke_dsc.width : 0); + lv_path_to_vg(lv_vg_path, path, &offset, ctx->stroke_dsc.opa ? ctx->stroke_dsc.width : 0); if(vg_lite_query_feature(gcFEATURE_BIT_VG_SCISSOR)) { /* set scissor area */ - lv_vg_lite_set_scissor_area(&scissor_area); + lv_vg_lite_set_scissor_area(u, &scissor_area); LV_LOG_TRACE("Set scissor area: X1:%" LV_PRId32 ", Y1:%" LV_PRId32 ", X2:%" LV_PRId32 ", Y2:%" LV_PRId32, scissor_area.x1, scissor_area.y1, scissor_area.x2, scissor_area.y2); } @@ -313,12 +325,14 @@ static void task_draw_cb(void * ctx, const lv_vector_path_t * path, const lv_vec lv_vg_lite_path_set_bounding_box(lv_vg_path, p1_res.x, p1_res.y, p2_res.x, p2_res.y); } - if(dsc->fill_dsc.opa) { - draw_fill(u, lv_vg_path, dsc, &matrix, &offset); + const lv_opa_t layer_opa = u->task_act->opa; + + if(ctx->fill_dsc.opa) { + draw_fill(u, lv_vg_path, ctx, &matrix, &offset, layer_opa); } - if(dsc->stroke_dsc.opa) { - draw_stroke(u, path, lv_vg_path, dsc, &matrix); + if(ctx->stroke_dsc.opa) { + draw_stroke(u, path, lv_vg_path, ctx, &matrix, layer_opa); } /* drop path */ @@ -352,8 +366,8 @@ static void lv_path_to_vg(lv_vg_lite_path_t * dest, const lv_vector_path_t * src float min_x = FLT_MAX; float min_y = FLT_MAX; - float max_x = FLT_MIN; - float max_y = FLT_MIN; + float max_x = -FLT_MAX; + float max_y = -FLT_MAX; #define CMP_BOUNDS(point) \ do { \ diff --git a/src/draw/vg_lite/lv_vg_lite_grad.c b/src/draw/vg_lite/lv_vg_lite_grad.c index 46d0c0507c..e5fb595bf9 100644 --- a/src/draw/vg_lite/lv_vg_lite_grad.c +++ b/src/draw/vg_lite/lv_vg_lite_grad.c @@ -40,7 +40,10 @@ typedef enum { GRAD_TYPE_UNKNOWN, } grad_type_t; +struct _lv_vg_lite_grad_ctx_t; + typedef struct { + struct _lv_vg_lite_grad_ctx_t * ctx; grad_type_t type; lv_vector_gradient_t lv; union { @@ -56,8 +59,7 @@ typedef struct _lv_vg_lite_grad_ctx_t { struct _lv_draw_vg_lite_unit_t * unit; lv_cache_t * cache; struct _lv_vg_lite_pending_t * pending; - grad_item_t * item_pool; - uint32_t item_pool_size; + lv_ll_t item_pool; /** * Temporary reuse of data to reduce the use of @@ -111,9 +113,7 @@ struct _lv_vg_lite_grad_ctx_t * lv_vg_lite_grad_ctx_create(uint32_t cache_cnt, s LV_ASSERT_MALLOC(ctx); ctx->unit = unit; - ctx->item_pool = lv_malloc_zeroed(cache_cnt * sizeof(grad_item_t)); - LV_ASSERT_MALLOC(ctx->item_pool); - ctx->item_pool_size = cache_cnt; + lv_ll_init(&ctx->item_pool, sizeof(grad_item_t)); ctx->cache = lv_cache_create(&lv_cache_class_lru_ll_count, sizeof(grad_item_ref_t), cache_cnt, ops); lv_cache_set_name(ctx->cache, "VG_GRAD"); @@ -128,7 +128,7 @@ void lv_vg_lite_grad_ctx_delete(struct _lv_vg_lite_grad_ctx_t * ctx) LV_ASSERT_NULL(ctx); lv_vg_lite_pending_destroy(ctx->pending); lv_cache_destroy(ctx->cache, NULL); - lv_free(ctx->item_pool); + lv_ll_clear(&ctx->item_pool); lv_memzero(ctx, sizeof(lv_vg_lite_grad_ctx_t)); lv_free(ctx); @@ -140,6 +140,12 @@ struct _lv_vg_lite_pending_t * lv_vg_lite_grad_ctx_get_pending(struct _lv_vg_lit return ctx->pending; } +struct _lv_cache_t * lv_vg_lite_grad_ctx_get_cache(struct _lv_vg_lite_grad_ctx_t * ctx) +{ + LV_ASSERT_NULL(ctx); + return ctx->cache; +} + bool lv_vg_lite_draw_grad( struct _lv_vg_lite_grad_ctx_t * ctx, vg_lite_buffer_t * buffer, @@ -160,13 +166,13 @@ bool lv_vg_lite_draw_grad( /* check radial gradient is supported */ if(grad->style == LV_VECTOR_GRADIENT_STYLE_RADIAL) { if(!vg_lite_query_feature(gcFEATURE_BIT_VG_RADIAL_GRADIENT)) { - LV_LOG_INFO("radial gradient is not supported"); + LV_LOG_WARN("radial gradient is not supported"); return false; } /* check if the radius is valid */ if(grad->cr <= 0) { - LV_LOG_INFO("radius: %f is not valid", grad->cr); + LV_LOG_WARN("radius: %f is not valid", grad->cr); return false; } } @@ -174,7 +180,7 @@ bool lv_vg_lite_draw_grad( /* check spread mode is supported */ if(grad->spread == LV_VECTOR_GRADIENT_SPREAD_REPEAT || grad->spread == LV_VECTOR_GRADIENT_SPREAD_REFLECT) { if(!vg_lite_query_feature(gcFEATURE_BIT_VG_IM_REPEAT_REFLECT)) { - LV_LOG_INFO("repeat/reflect spread(%d) is not supported", grad->spread); + LV_LOG_WARN("repeat/reflect spread(%d) is not supported", grad->spread); return false; } } @@ -191,8 +197,7 @@ bool lv_vg_lite_draw_grad( vg_lite_linear_gradient_t * linear_grad = &grad_item->vg.linear; vg_lite_matrix_t * grad_mat_p = vg_lite_get_grad_matrix(linear_grad); LV_ASSERT_NULL(grad_mat_p); - vg_lite_identity(grad_mat_p); - lv_vg_lite_matrix_multiply(grad_mat_p, grad_matrix); + *grad_mat_p = *grad_matrix; grad_point_to_matrix(grad_mat_p, grad->x1, grad->y1, grad->x2, grad->y2); LV_PROFILER_DRAW_BEGIN_TAG("vg_lite_draw_grad"); @@ -307,7 +312,6 @@ bool lv_vg_lite_draw_grad_helper( lv_memcpy(grad.stops, grad_dsc->stops, sizeof(lv_grad_stop_t) * grad_dsc->stops_count); /*convert to spread mode*/ -#if LV_USE_DRAW_SW_COMPLEX_GRADIENTS switch(grad_dsc->extend) { case LV_GRAD_EXTEND_PAD: grad.spread = LV_VECTOR_GRADIENT_SPREAD_PAD; @@ -323,9 +327,6 @@ bool lv_vg_lite_draw_grad_helper( grad.spread = LV_VECTOR_GRADIENT_SPREAD_PAD; break; } -#else - grad.spread = LV_VECTOR_GRADIENT_SPREAD_PAD; -#endif switch(grad_dsc->dir) { case LV_GRAD_DIR_VER: @@ -342,7 +343,6 @@ bool lv_vg_lite_draw_grad_helper( grad.y2 = area->y1; break; -#if LV_USE_DRAW_SW_COMPLEX_GRADIENTS case LV_GRAD_DIR_LINEAR: { int32_t w = lv_area_get_width(area); int32_t h = lv_area_get_height(area); @@ -366,7 +366,6 @@ bool lv_vg_lite_draw_grad_helper( grad.cr = LV_MAX(end_extent_x - grad.cx, end_extent_y - grad.cy); } break; -#endif default: LV_LOG_WARN("Unsupported gradient direction: %d", grad_dsc->dir); @@ -420,21 +419,42 @@ static grad_item_t * grad_get(lv_vg_lite_grad_ctx_t * ctx, const lv_vector_gradi static grad_item_t * grad_item_pool_alloc(lv_vg_lite_grad_ctx_t * ctx, grad_type_t type) { LV_ASSERT_NULL(ctx); - for(uint32_t i = 0; i < ctx->item_pool_size; i++) { - if(ctx->item_pool[i].type == GRAD_TYPE_FREE) { - ctx->item_pool[i].type = type; - return &ctx->item_pool[i]; + + grad_item_t * item = lv_ll_get_head(&ctx->item_pool); + + /* Try to obtain a free node from the head */ + if(item && item->type == GRAD_TYPE_FREE) { + lv_ll_move_before(&ctx->item_pool, item, NULL); + LV_LOG_TRACE("reuse item: %p, type: %d", (void *)item, type); + } + else { + /* Allocate a new node if the pool is empty or all nodes are in use */ + item = lv_ll_ins_tail(&ctx->item_pool); + LV_ASSERT_MALLOC(item); + if(!item) { + LV_LOG_ERROR("alloc grad item failed"); + return NULL; } + + LV_LOG_TRACE("alloc new item: %p, type: %d, pool size: %" LV_PRIu32, + (void *)item, type, lv_ll_get_len(&ctx->item_pool)); } - LV_LOG_WARN("alloc grad item failed, no free slot"); - return NULL; + lv_memzero(item, sizeof(grad_item_t)); + item->ctx = ctx; + item->type = type; + return item; } static void grad_item_pool_free(grad_item_t * item) { LV_ASSERT_NULL(item); + LV_ASSERT_NULL(item->ctx); + + /* Move the free nodes to the head to ensure quick allocation */ item->type = GRAD_TYPE_FREE; + grad_item_t * head = lv_ll_get_head(&item->ctx->item_pool); + lv_ll_move_before(&item->ctx->item_pool, item, head); } static void grad_cache_release_cb(void * entry, void * user_data) @@ -608,7 +628,11 @@ static bool radial_grad_create(grad_item_t * item, vg_lite_color_ramp_t * color_ static grad_type_t lv_grad_style_to_type(lv_vector_gradient_style_t style) { if(style == LV_VECTOR_GRADIENT_STYLE_LINEAR) { +#if LV_VG_LITE_DISABLE_LINEAR_GRADIENT_EXT + return GRAD_TYPE_LINEAR; +#else return vg_lite_query_feature(gcFEATURE_BIT_VG_LINEAR_GRADIENT_EXT) ? GRAD_TYPE_LINEAR_EXT : GRAD_TYPE_LINEAR; +#endif } if(style == LV_VECTOR_GRADIENT_STYLE_RADIAL) { diff --git a/src/draw/vg_lite/lv_vg_lite_grad.h b/src/draw/vg_lite/lv_vg_lite_grad.h index 7688bc530e..4195701f0d 100644 --- a/src/draw/vg_lite/lv_vg_lite_grad.h +++ b/src/draw/vg_lite/lv_vg_lite_grad.h @@ -51,6 +51,12 @@ void lv_vg_lite_grad_ctx_delete(struct _lv_vg_lite_grad_ctx_t * ctx); */ struct _lv_vg_lite_pending_t * lv_vg_lite_grad_ctx_get_pending(struct _lv_vg_lite_grad_ctx_t * ctx); +/** + * @brief Get the cache of gradient items + * @param ctx the gradient context + */ +struct _lv_cache_t * lv_vg_lite_grad_ctx_get_cache(struct _lv_vg_lite_grad_ctx_t * ctx); + /** * @brief Draw a gradient * @param ctx the gradient context diff --git a/src/draw/vg_lite/lv_vg_lite_math.c b/src/draw/vg_lite/lv_vg_lite_math.c index 25a416bf8a..0c9bd8ebcd 100644 --- a/src/draw/vg_lite/lv_vg_lite_math.c +++ b/src/draw/vg_lite/lv_vg_lite_math.c @@ -1,5 +1,5 @@ /** - * @file lv_vg_lite_math.h + * @file lv_vg_lite_math.c * */ diff --git a/src/draw/vg_lite/lv_vg_lite_path.c b/src/draw/vg_lite/lv_vg_lite_path.c index 0a06485a08..ea49cf86dd 100644 --- a/src/draw/vg_lite/lv_vg_lite_path.c +++ b/src/draw/vg_lite/lv_vg_lite_path.c @@ -228,8 +228,8 @@ bool lv_vg_lite_path_update_bounding_box(lv_vg_lite_path_t * path) /* init bounds */ bounds.min_x = FLT_MAX; bounds.min_y = FLT_MAX; - bounds.max_x = FLT_MIN; - bounds.max_y = FLT_MIN; + bounds.max_x = -FLT_MAX; + bounds.max_y = -FLT_MAX; /* calc bounds */ lv_vg_lite_path_for_each_data(lv_vg_lite_path_get_path(path), path_bounds_iter_cb, &bounds); @@ -398,8 +398,12 @@ void lv_vg_lite_path_cubic_to(lv_vg_lite_path_t * path, void lv_vg_lite_path_close(lv_vg_lite_path_t * path) { LV_ASSERT_NULL(path); +#if LV_VG_LITE_DISABLE_VLC_OP_CLOSE + LV_UNUSED(path); +#else lv_vg_lite_path_reserve_space(path, 1 * path->format_len); lv_vg_lite_path_append_op(path, VLC_OP_CLOSE); +#endif } void lv_vg_lite_path_end(lv_vg_lite_path_t * path) @@ -643,6 +647,7 @@ void lv_vg_lite_path_for_each_data(const vg_lite_path_t * path, lv_vg_lite_path_ { LV_ASSERT_NULL(path); LV_ASSERT_NULL(cb); + LV_PROFILER_DRAW_BEGIN; uint8_t fmt_len = lv_vg_lite_path_format_len(path->format); uint8_t * cur = path->path; @@ -684,6 +689,8 @@ void lv_vg_lite_path_for_each_data(const vg_lite_path_t * path, lv_vg_lite_path_ cb(user_data, op_code, tmp_data, arg_len); } + + LV_PROFILER_DRAW_END; } void lv_vg_lite_path_append_path(lv_vg_lite_path_t * dest, const lv_vg_lite_path_t * src) diff --git a/src/draw/vg_lite/lv_vg_lite_path.h b/src/draw/vg_lite/lv_vg_lite_path.h index a9ffee3dc6..09ac1d2780 100644 --- a/src/draw/vg_lite/lv_vg_lite_path.h +++ b/src/draw/vg_lite/lv_vg_lite_path.h @@ -23,20 +23,6 @@ extern "C" { * DEFINES *********************/ -#if LV_USE_VG_LITE_THORVG -/** -* It is found that thorvg cannot handle large coordinates well. -* When the coordinates are larger than 4096, the calculation of tvgSwRle module will overflow in 32-bit system. -* So we use FLT_MAX and FLT_MIN to write the mark to bounding_box to tell vg_lite_tvg not to add clip path to the current path. -*/ -#define PATH_COORD_MAX FLT_MAX -#define PATH_COORD_MIN FLT_MIN -#else -/* 18 bits is enough to represent the coordinates of path bounding box */ -#define PATH_COORD_MAX (1 << 18) -#define PATH_COORD_MIN (-PATH_COORD_MAX) -#endif - #define LV_VG_LITE_PATH_SET_OP_CODE(PTR, TYPE, OP_CODE) (*((TYPE*)PTR) = (OP_CODE)) #define LV_VG_LITE_PATH_GET_OP_CODE(PTR) (*((uint8_t*)PTR)) diff --git a/src/draw/vg_lite/lv_vg_lite_utils.c b/src/draw/vg_lite/lv_vg_lite_utils.c index 56c2da4d1f..62e6cfea56 100644 --- a/src/draw/vg_lite/lv_vg_lite_utils.c +++ b/src/draw/vg_lite/lv_vg_lite_utils.c @@ -1,5 +1,5 @@ /** - * @file vg_lite_utils.c + * @file lv_vg_lite_utils.c * */ @@ -17,6 +17,7 @@ #include "lv_vg_lite_pending.h" #include "lv_vg_lite_grad.h" #include "lv_draw_vg_lite_type.h" +#include "../../misc/lv_area_private.h" #include #include @@ -40,6 +41,8 @@ case (gcFEATURE_BIT_VG_##e): \ return #e +#define LV_VG_LITE_IMAGE_FLAGS_TILED LV_IMAGE_FLAGS_USER1 + /********************** * TYPEDEFS **********************/ @@ -158,7 +161,7 @@ const char * lv_vg_lite_error_string(vg_lite_error_t error) default: break; } - return "UNKNOW_ERROR"; + return "UNKNOWN_ERROR"; } const char * lv_vg_lite_feature_string(vg_lite_feature_t feature) @@ -213,7 +216,7 @@ const char * lv_vg_lite_feature_string(vg_lite_feature_t feature) default: break; } - return "UNKNOW_FEATURE"; + return "UNKNOWN_FEATURE"; } const char * lv_vg_lite_buffer_format_string(vg_lite_buffer_format_t format) @@ -271,7 +274,7 @@ const char * lv_vg_lite_buffer_format_string(vg_lite_buffer_format_t format) default: break; } - return "UNKNOW_BUFFER_FORMAT"; + return "UNKNOWN_BUFFER_FORMAT"; } const char * lv_vg_lite_vlc_op_string(uint8_t vlc_op) @@ -299,7 +302,7 @@ const char * lv_vg_lite_vlc_op_string(uint8_t vlc_op) default: break; } - return "UNKNOW_VLC_OP"; + return "UNKNOWN_VLC_OP"; } static void path_data_print_cb(void * user_data, uint8_t op_code, const float * data, uint32_t len) @@ -478,6 +481,7 @@ bool lv_vg_lite_is_dest_cf_supported(lv_color_format_t cf) case LV_COLOR_FORMAT_L8: case LV_COLOR_FORMAT_RGB565: case LV_COLOR_FORMAT_ARGB8888: + case LV_COLOR_FORMAT_ARGB8888_PREMULTIPLIED: case LV_COLOR_FORMAT_XRGB8888: case LV_COLOR_FORMAT_ARGB1555: case LV_COLOR_FORMAT_ARGB4444: @@ -503,6 +507,7 @@ bool lv_vg_lite_is_src_cf_supported(lv_color_format_t cf) case LV_COLOR_FORMAT_L8: case LV_COLOR_FORMAT_RGB565: case LV_COLOR_FORMAT_ARGB8888: + case LV_COLOR_FORMAT_ARGB8888_PREMULTIPLIED: case LV_COLOR_FORMAT_XRGB8888: case LV_COLOR_FORMAT_ARGB1555: case LV_COLOR_FORMAT_ARGB4444: @@ -579,10 +584,13 @@ vg_lite_buffer_format_t lv_vg_lite_vg_fmt(lv_color_format_t cf) case LV_COLOR_FORMAT_RGB888: return VG_LITE_BGR888; + /** + * The lv_vg_lite_blend_mode function will automatically select the appropriate blend mode, + * which is uniformly mapped to VG_LITE_BGRA8888 here. + */ case LV_COLOR_FORMAT_ARGB8888: - return VG_LITE_BGRA8888; case LV_COLOR_FORMAT_ARGB8888_PREMULTIPLIED: - return VG_sBGRA_8888_PRE; + return VG_LITE_BGRA8888; case LV_COLOR_FORMAT_XRGB8888: return VG_LITE_BGRX8888; @@ -645,7 +653,6 @@ void lv_vg_lite_buffer_format_bytes( case VG_LITE_BGRX8888: case VG_LITE_XBGR8888: case VG_LITE_XRGB8888: - case VG_sBGRA_8888_PRE: *mul = 4; break; case VG_LITE_NV12: @@ -694,22 +701,15 @@ void lv_vg_lite_buffer_format_bytes( uint32_t lv_vg_lite_width_to_stride(uint32_t w, vg_lite_buffer_format_t color_format) { - w = lv_vg_lite_width_align(w); + if(vg_lite_query_feature(gcFEATURE_BIT_VG_16PIXELS_ALIGN)) { + w = LV_VG_LITE_ALIGN(w, 16); + } uint32_t mul, div, align; lv_vg_lite_buffer_format_bytes(color_format, &mul, &div, &align); return LV_VG_LITE_ALIGN(((w * mul + div - 1) / div), align); } -uint32_t lv_vg_lite_width_align(uint32_t w) -{ - if(lv_vg_lite_16px_align()) { - w = LV_VG_LITE_ALIGN(w, 16); - } - - return w; -} - void lv_vg_lite_buffer_init( vg_lite_buffer_t * buffer, const void * ptr, @@ -719,9 +719,6 @@ void lv_vg_lite_buffer_init( vg_lite_buffer_format_t format, bool tiled) { - uint32_t mul; - uint32_t div; - uint32_t align; LV_ASSERT_NULL(buffer); LV_ASSERT_NULL(ptr); @@ -734,13 +731,26 @@ void lv_vg_lite_buffer_init( else { buffer->tiled = VG_LITE_LINEAR; } - buffer->image_mode = VG_LITE_NORMAL_IMAGE_MODE; + + if(buffer->tiled) { + LV_ASSERT_FORMAT_MSG(LV_VG_LITE_IS_ALIGNED(width, 4) && + LV_VG_LITE_IS_ALIGNED(height, 4), + "width : %" LV_PRId32 ", height : %" LV_PRId32, width, height); + } + + /* Alpha image need to be multiplied by color */ + if(format == VG_LITE_A8 || format == VG_LITE_A4) { + buffer->image_mode = VG_LITE_MULTIPLY_IMAGE_MODE; + } + else { + buffer->image_mode = VG_LITE_NORMAL_IMAGE_MODE; + } + buffer->transparency_mode = VG_LITE_IMAGE_OPAQUE; buffer->width = width; buffer->height = height; if(stride == LV_STRIDE_AUTO) { - lv_vg_lite_buffer_format_bytes(buffer->format, &mul, &div, &align); - buffer->stride = LV_VG_LITE_ALIGN((buffer->width * mul / div), align); + buffer->stride = lv_vg_lite_width_to_stride(width, buffer->format); } else { buffer->stride = stride; @@ -781,14 +791,9 @@ void lv_vg_lite_buffer_from_draw_buf(vg_lite_buffer_t * buffer, const lv_draw_bu ptr += LV_VG_LITE_ALIGN(palette_size_bytes, LV_DRAW_BUF_ALIGN); } - width = lv_vg_lite_width_align(width); - - lv_vg_lite_buffer_init(buffer, ptr, width, height, stride, format, false); - - /* Alpha image need to be multiplied by color */ - if(LV_COLOR_FORMAT_IS_ALPHA_ONLY(draw_buf->header.cf)) { - buffer->image_mode = VG_LITE_MULTIPLY_IMAGE_MODE; - } + lv_vg_lite_buffer_init(buffer, ptr, + width, height, stride, format, + lv_draw_buf_has_flag(draw_buf, LV_VG_LITE_IMAGE_FLAGS_TILED)); } void lv_vg_lite_image_matrix(vg_lite_matrix_t * matrix, int32_t x, int32_t y, const lv_draw_image_dsc_t * dsc) @@ -952,7 +957,7 @@ vg_lite_color_t lv_vg_lite_color(lv_color_t color, lv_opa_t opa, bool pre_mul) vg_lite_blend_t lv_vg_lite_blend_mode(lv_blend_mode_t blend_mode, bool has_pre_mul) { - if(!has_pre_mul && vg_lite_query_feature(gcFEATURE_BIT_VG_LVGL_SUPPORT)) { + if(!has_pre_mul && lv_vg_lite_support_blend_normal()) { switch(blend_mode) { case LV_BLEND_MODE_NORMAL: /**< Simply mix according to the opacity value*/ return VG_LITE_BLEND_NORMAL_LVGL; @@ -973,9 +978,6 @@ vg_lite_blend_t lv_vg_lite_blend_mode(lv_blend_mode_t blend_mode, bool has_pre_m switch(blend_mode) { case LV_BLEND_MODE_NORMAL: /**< Simply mix according to the opacity value*/ - if(!has_pre_mul && vg_lite_query_feature(gcFEATURE_BIT_VG_HW_PREMULTIPLY)) { - return VG_LITE_BLEND_PREMULTIPLY_SRC_OVER; - } return VG_LITE_BLEND_SRC_OVER; case LV_BLEND_MODE_ADDITIVE: /**< Add the respective color channels*/ @@ -994,11 +996,6 @@ vg_lite_blend_t lv_vg_lite_blend_mode(lv_blend_mode_t blend_mode, bool has_pre_m bool lv_vg_lite_buffer_check(const vg_lite_buffer_t * buffer, bool is_src) { - uint32_t mul; - uint32_t div; - uint32_t align; - int32_t stride; - if(!buffer) { LV_LOG_ERROR("buffer is NULL"); return false; @@ -1024,21 +1021,59 @@ bool lv_vg_lite_buffer_check(const vg_lite_buffer_t * buffer, bool is_src) return false; } - if(is_src && buffer->width != (vg_lite_int32_t)lv_vg_lite_width_align(buffer->width)) { - LV_LOG_ERROR("buffer width(%d) is not aligned", (int)buffer->width); - return false; + if(buffer->tiled == VG_LITE_TILED) { + if(!LV_VG_LITE_IS_ALIGNED(buffer->width, 4) || !LV_VG_LITE_IS_ALIGNED(buffer->height, 4)) { + LV_LOG_ERROR("tiled buffer width(%d) or height(%d) is not aligned to 4", (int)buffer->width, (int)buffer->height); + return false; + } } - if(!LV_VG_LITE_IS_ALIGNED(buffer->memory, LV_DRAW_BUF_ALIGN)) { - LV_LOG_ERROR("buffer address(%p) is not aligned to %d", buffer->memory, LV_DRAW_BUF_ALIGN); - return false; + int memory_align = LV_DRAW_BUF_ALIGN; + if(is_src) { + switch(buffer->format) { + case VG_LITE_INDEX_1: + case VG_LITE_INDEX_2: + case VG_LITE_INDEX_4: + case VG_LITE_A4: + memory_align = 8; + break; + + case VG_LITE_INDEX_8: + case VG_LITE_A8: + case VG_LITE_L8: + case VG_LITE_RGBA2222: + case VG_LITE_BGRA2222: + case VG_LITE_ABGR2222: + case VG_LITE_ARGB2222: + memory_align = 16; + break; + + case VG_LITE_ABGR1555: + case VG_LITE_ARGB1555: + case VG_LITE_BGRA5551: + case VG_LITE_RGBA5551: + case VG_LITE_RGBA4444: + case VG_LITE_BGRA4444: + case VG_LITE_ABGR4444: + case VG_LITE_ARGB4444: + case VG_LITE_RGB565: + case VG_LITE_BGR565: + memory_align = 32; + break; + + default: + break; + } } - lv_vg_lite_buffer_format_bytes(buffer->format, &mul, &div, &align); - stride = LV_VG_LITE_ALIGN((buffer->width * mul / div), align); + if(!LV_VG_LITE_IS_ALIGNED(buffer->memory, memory_align)) { + LV_LOG_ERROR("buffer address(%p) is not aligned to %d", buffer->memory, memory_align); + return false; + } - if(buffer->stride != stride) { - LV_LOG_ERROR("buffer stride(%d) != %d", (int)buffer->stride, (int)stride); + const uint32_t stride = lv_vg_lite_width_to_stride(buffer->width, buffer->format); + if(buffer->stride < 0 || (uint32_t)buffer->stride != stride) { + LV_LOG_ERROR("buffer stride(%d) != expected(%d)", (int)buffer->stride, (int)stride); return false; } @@ -1161,20 +1196,7 @@ bool lv_vg_lite_matrix_check(const vg_lite_matrix_t * matrix) bool lv_vg_lite_support_blend_normal(void) { - if(vg_lite_query_feature(gcFEATURE_BIT_VG_HW_PREMULTIPLY)) { - return true; - } - - if(vg_lite_query_feature(gcFEATURE_BIT_VG_LVGL_SUPPORT)) { - return true; - } - - return false; -} - -bool lv_vg_lite_16px_align(void) -{ - return vg_lite_query_feature(gcFEATURE_BIT_VG_16PIXELS_ALIGN); + return vg_lite_query_feature(gcFEATURE_BIT_VG_LVGL_SUPPORT); } void lv_vg_lite_matrix_multiply(vg_lite_matrix_t * matrix, const vg_lite_matrix_t * mult) @@ -1262,9 +1284,16 @@ lv_point_precise_t lv_vg_lite_matrix_transform_point(const vg_lite_matrix_t * ma return p; } -void lv_vg_lite_set_scissor_area(const lv_area_t * area) +void lv_vg_lite_set_scissor_area(struct _lv_draw_vg_lite_unit_t * u, const lv_area_t * area) { LV_PROFILER_DRAW_BEGIN; + + /* Avoid setting the same scissor frequently */ + if(lv_area_is_equal(area, &u->current_scissor_area)) { + LV_PROFILER_DRAW_END; + return; + } + #if VGLITE_RELEASE_VERSION <= VGLITE_MAKE_VERSION(4,0,57) /** * In the new version of VG-Lite, vg_lite_set_scissor no longer needs to call vg_lite_enable_scissor and @@ -1287,6 +1316,8 @@ void lv_vg_lite_set_scissor_area(const lv_area_t * area) LV_LOG_ERROR("area: %d, %d, %d, %d", (int)area->x1, (int)area->y1, (int)area->x2, (int)area->y2); }); + + u->current_scissor_area = *area; LV_PROFILER_DRAW_END; } @@ -1363,11 +1394,39 @@ void lv_vg_lite_finish(struct _lv_draw_vg_lite_unit_t * u) /* Clear bitmap font dsc reference */ lv_vg_lite_pending_remove_all(u->bitmap_font_pending); + /* Reset scissor area */ + lv_memzero(&u->current_scissor_area, sizeof(u->current_scissor_area)); + u->flush_count = 0; u->letter_count = 0; LV_PROFILER_DRAW_END; } +void lv_vg_lite_set_color_key(const lv_image_colorkey_t * colorkey) +{ + if(!vg_lite_query_feature(gcFEATURE_BIT_VG_COLOR_KEY)) { + LV_LOG_TRACE("vg_lite_set_color_key not support"); + return; + } + + vg_lite_color_key4_t vg_colorkey; + lv_memzero(&vg_colorkey, sizeof(vg_colorkey)); + if(colorkey) { + vg_lite_color_key_t key0 = { + .enable = true, + .low_r = colorkey->low.red, + .low_g = colorkey->low.green, + .low_b = colorkey->low.blue, + .alpha = 0, + .hign_r = colorkey->high.red, + .hign_g = colorkey->high.green, + .hign_b = colorkey->high.blue, + }; + vg_colorkey[0] = key0; + } + LV_VG_LITE_CHECK_ERROR(vg_lite_set_color_key(vg_colorkey), {}); +} + /********************** * STATIC FUNCTIONS **********************/ diff --git a/src/draw/vg_lite/lv_vg_lite_utils.h b/src/draw/vg_lite/lv_vg_lite_utils.h index 425050fc54..50f39f21ed 100644 --- a/src/draw/vg_lite/lv_vg_lite_utils.h +++ b/src/draw/vg_lite/lv_vg_lite_utils.h @@ -24,8 +24,12 @@ extern "C" { #if LV_USE_VG_LITE_THORVG #include "../../others/vg_lite_tvg/vg_lite.h" #else +#if LV_USE_VG_LITE_DRIVER +#include "../../libs/vg_lite_driver/inc/vg_lite.h" +#else #include #endif +#endif /********************* * DEFINES @@ -114,8 +118,6 @@ void lv_vg_lite_buffer_format_bytes( uint32_t lv_vg_lite_width_to_stride(uint32_t w, vg_lite_buffer_format_t color_format); -uint32_t lv_vg_lite_width_align(uint32_t w); - void lv_vg_lite_buffer_init( vg_lite_buffer_t * buffer, const void * ptr, @@ -163,15 +165,13 @@ bool lv_vg_lite_matrix_check(const vg_lite_matrix_t * matrix); bool lv_vg_lite_support_blend_normal(void); -bool lv_vg_lite_16px_align(void); - void lv_vg_lite_matrix_multiply(vg_lite_matrix_t * matrix, const vg_lite_matrix_t * mult); bool lv_vg_lite_matrix_inverse(vg_lite_matrix_t * result, const vg_lite_matrix_t * matrix); lv_point_precise_t lv_vg_lite_matrix_transform_point(const vg_lite_matrix_t * matrix, const lv_point_precise_t * point); -void lv_vg_lite_set_scissor_area(const lv_area_t * area); +void lv_vg_lite_set_scissor_area(struct _lv_draw_vg_lite_unit_t * u, const lv_area_t * area); void lv_vg_lite_disable_scissor(void); @@ -292,6 +292,20 @@ static inline void lv_vg_lite_blit_rect(vg_lite_buffer_t * target, }); LV_PROFILER_DRAW_END_TAG("vg_lite_blit_rect"); } +void lv_vg_lite_set_color_key(const lv_image_colorkey_t * colorkey); + +static inline void lv_vg_lite_clear(vg_lite_buffer_t * target, const lv_area_t * area, vg_lite_color_t color) +{ + vg_lite_rectangle_t rect; + lv_vg_lite_rect(&rect, area); + LV_PROFILER_DRAW_BEGIN_TAG("vg_lite_clear"); + LV_VG_LITE_CHECK_ERROR(vg_lite_clear(target, &rect, color), { + lv_vg_lite_buffer_dump_info(target); + LV_LOG_ERROR("rect: X%d Y%d W%d H%d", rect.x, rect.y, rect.width, rect.height); + lv_vg_lite_color_dump_info(color); + }); + LV_PROFILER_DRAW_END_TAG("vg_lite_clear"); +} /********************** * MACROS @@ -303,4 +317,4 @@ static inline void lv_vg_lite_blit_rect(vg_lite_buffer_t * target, } /*extern "C"*/ #endif -#endif /*VG_LITE_UTILS_H*/ +#endif /*LV_VG_LITE_UTILS_H*/ diff --git a/src/drivers/display/drm/lv_linux_drm.c b/src/drivers/display/drm/lv_linux_drm.c index 4d2f3f8707..050556e06b 100644 --- a/src/drivers/display/drm/lv_linux_drm.c +++ b/src/drivers/display/drm/lv_linux_drm.c @@ -7,7 +7,7 @@ * INCLUDES *********************/ #include "lv_linux_drm.h" -#if LV_USE_LINUX_DRM +#if LV_USE_LINUX_DRM && !LV_LINUX_DRM_USE_EGL #include #include @@ -80,6 +80,9 @@ typedef struct { drmModePropertyPtr conn_props[128]; drm_buffer_t drm_bufs[BUFFER_CNT]; drm_buffer_t * act_buf; +#if LV_USE_LINUX_DRM_GBM_BUFFERS + struct gbm_device * gbm_device; +#endif } drm_dev_t; /********************** @@ -96,36 +99,30 @@ static int drm_get_conn_props(drm_dev_t * drm_dev); static int drm_add_plane_property(drm_dev_t * drm_dev, const char * name, uint64_t value); static int drm_add_crtc_property(drm_dev_t * drm_dev, const char * name, uint64_t value); static int drm_add_conn_property(drm_dev_t * drm_dev, const char * name, uint64_t value); -static int drm_dmabuf_set_plane(drm_dev_t * drm_dev, drm_buffer_t * buf); static int find_plane(drm_dev_t * drm_dev, unsigned int fourcc, uint32_t * plane_id, uint32_t crtc_id, uint32_t crtc_idx); static int drm_find_connector(drm_dev_t * drm_dev, int64_t connector_id); static int drm_open(const char * path); static int drm_setup(drm_dev_t * drm_dev, const char * device_path, int64_t connector_id, unsigned int fourcc); -static int drm_allocate_dumb(drm_dev_t * drm_dev, drm_buffer_t * buf); -static int drm_setup_buffers(drm_dev_t * drm_dev); -static void drm_flush_wait(lv_display_t * drm_dev); -static void drm_flush(lv_display_t * disp, const lv_area_t * area, uint8_t * px_map); -static void drm_dmabuf_set_active_buf(lv_event_t * event); static uint32_t tick_get_cb(void); -#if LV_USE_LINUX_DRM_GBM_BUFFERS - +#if !LV_USE_LINUX_DRM_GBM_BUFFERS + static int drm_allocate_dumb(drm_dev_t * drm_dev, drm_buffer_t * buf); +#elif LV_USE_LINUX_DRM_GBM_BUFFERS static int create_gbm_buffer(drm_dev_t * drm_dev, drm_buffer_t * buf); - #endif +static int drm_setup_buffers(drm_dev_t * drm_dev); +static int drm_dmabuf_set_plane(drm_dev_t * drm_dev, drm_buffer_t * buf); +static void drm_flush_wait(lv_display_t * drm_dev); +static void drm_flush(lv_display_t * disp, const lv_area_t * area, uint8_t * px_map); +static void drm_dmabuf_set_active_buf(lv_event_t * event); + /********************** * STATIC VARIABLES **********************/ -#if LV_USE_LINUX_DRM_GBM_BUFFERS - - static struct gbm_device * gbm_device; - -#endif - /********************** * MACROS **********************/ @@ -139,23 +136,25 @@ static uint32_t tick_get_cb(void); lv_display_t * lv_linux_drm_create(void) { + lv_display_t * disp; + lv_tick_set_cb(tick_get_cb); drm_dev_t * drm_dev = lv_malloc_zeroed(sizeof(drm_dev_t)); LV_ASSERT_MALLOC(drm_dev); if(drm_dev == NULL) return NULL; - lv_display_t * disp = lv_display_create(800, 480); + drm_dev->fd = -1; + + disp = lv_display_create(800, 480); if(disp == NULL) { lv_free(drm_dev); return NULL; } - drm_dev->fd = -1; lv_display_set_driver_data(disp, drm_dev); lv_display_set_flush_wait_cb(disp, drm_flush_wait); lv_display_set_flush_cb(disp, drm_flush); - return disp; } @@ -207,16 +206,18 @@ static void drm_dmabuf_set_active_buf(lv_event_t * event) void lv_linux_drm_set_file(lv_display_t * disp, const char * file, int64_t connector_id) { - drm_dev_t * drm_dev = lv_display_get_driver_data(disp); int ret; + drm_dev_t * drm_dev = lv_display_get_driver_data(disp); + ret = drm_setup(drm_dev, file, connector_id, DRM_FOURCC); if(ret) { - close(drm_dev->fd); - drm_dev->fd = -1; return; } + int32_t hor_res = drm_dev->width; + int32_t ver_res = drm_dev->height; + ret = drm_setup_buffers(drm_dev); if(ret) { LV_LOG_ERROR("DRM buffer allocation failed"); @@ -227,8 +228,6 @@ void lv_linux_drm_set_file(lv_display_t * disp, const char * file, int64_t conne LV_LOG_INFO("DRM subsystem and buffer mapped successfully"); - int32_t hor_res = drm_dev->width; - int32_t ver_res = drm_dev->height; int32_t width = drm_dev->mmWidth; size_t buf_size = LV_MIN(drm_dev->drm_bufs[1].size, drm_dev->drm_bufs[0].size); @@ -252,6 +251,12 @@ void lv_linux_drm_set_file(lv_display_t * disp, const char * file, int64_t conne hor_res, ver_res, lv_display_get_dpi(disp)); } +void lv_linux_drm_set_mode_cb(lv_display_t * disp, lv_linux_drm_select_mode_cb_t callback) +{ + LV_UNUSED(disp); + LV_UNUSED(callback); + LV_LOG_WARN("DRM without EGL support doesn't currently support setting a mode selection callback"); +} /********************** * STATIC FUNCTIONS **********************/ @@ -810,15 +815,14 @@ static int drm_setup(drm_dev_t * drm_dev, const char * device_path, int64_t conn #if LV_USE_LINUX_DRM_GBM_BUFFERS /* Create GBM device and buffer */ - gbm_device = gbm_create_device(drm_dev->fd); + drm_dev->gbm_device = gbm_create_device(drm_dev->fd); - if(gbm_device == NULL) { + if(drm_dev->gbm_device == NULL) { LV_LOG_ERROR("Failed to create GBM device"); goto err; } - LV_LOG_INFO("GBM device backend: %s", gbm_device_get_backend_name(gbm_device)); - + LV_LOG_INFO("GBM device backend: %s", gbm_device_get_backend_name(drm_dev->gbm_device)); #endif return 0; @@ -828,6 +832,7 @@ static int drm_setup(drm_dev_t * drm_dev, const char * device_path, int64_t conn return -1; } +#if !LV_USE_LINUX_DRM_GBM_BUFFERS static int drm_allocate_dumb(drm_dev_t * drm_dev, drm_buffer_t * buf) { struct drm_mode_create_dumb creq; @@ -885,6 +890,7 @@ static int drm_allocate_dumb(drm_dev_t * drm_dev, drm_buffer_t * buf) return 0; } +#endif /*!LV_USE_LINUX_DRM_GBM_BUFFERS*/ #if LV_USE_LINUX_DRM_GBM_BUFFERS @@ -894,9 +900,7 @@ static int create_gbm_buffer(drm_dev_t * drm_dev, drm_buffer_t * buf) struct gbm_bo * gbm_bo; int prime_fd; uint32_t handles[4] = {0}, pitches[4] = {0}, offsets[4] = {0}; - uint32_t w, h, format; uint32_t n_planes; - char * drm_format_name; int res; /* gbm_bo_format does not define anything other than ARGB8888 or XRGB8888 */ @@ -906,7 +910,7 @@ static int create_gbm_buffer(drm_dev_t * drm_dev, drm_buffer_t * buf) } /* Create a linear GBM buffer object - best practice when modifiers are not used */ - if(!(gbm_bo = gbm_bo_create(gbm_device, + if(!(gbm_bo = gbm_bo_create(drm_dev->gbm_device, drm_dev->width, drm_dev->height, GBM_BO_FORMAT_XRGB8888, GBM_BO_USE_SCANOUT | GBM_BO_USE_LINEAR))) { @@ -925,16 +929,13 @@ static int create_gbm_buffer(drm_dev_t * drm_dev, drm_buffer_t * buf) return -1; } - w = gbm_bo_get_width(gbm_bo); - h = gbm_bo_get_height(gbm_bo); - format = gbm_bo_get_format(gbm_bo); + uint32_t h = gbm_bo_get_height(gbm_bo); pitches[0] = buf->pitch = gbm_bo_get_stride_for_plane(gbm_bo, 0); offsets[0] = buf->offset = gbm_bo_get_offset(gbm_bo, 0); buf->size = h * buf->pitch; - drm_format_name = drmGetFormatName(format); - LV_LOG_INFO("Created GBM BO of size: %lu pitch: %u offset: %u format: %s", - buf->size, buf->pitch, buf->offset, drm_format_name); + LV_LOG_INFO("Created GBM BO of size: %lu pitch: %u offset: %u", + buf->size, buf->pitch, buf->offset); prime_fd = gbm_bo_get_fd_for_plane(gbm_bo, 0); @@ -975,8 +976,7 @@ static int create_gbm_buffer(drm_dev_t * drm_dev, drm_buffer_t * buf) } -#endif /* END LV_USE_LINUX_DRM_GBM_BUFFERS */ - +#endif /* LV_USE_LINUX_DRM_GBM_BUFFERS */ static int drm_setup_buffers(drm_dev_t * drm_dev) { @@ -1061,4 +1061,4 @@ static uint32_t tick_get_cb(void) return time_ms; } -#endif /*LV_USE_LINUX_DRM*/ +#endif /*LV_USE_LINUX_DRM && !LV_LINUX_DRM_USE_EGL*/ diff --git a/src/drivers/display/drm/lv_linux_drm.h b/src/drivers/display/drm/lv_linux_drm.h index ee32466caa..b4547308e9 100644 --- a/src/drivers/display/drm/lv_linux_drm.h +++ b/src/drivers/display/drm/lv_linux_drm.h @@ -17,6 +17,7 @@ extern "C" { #include "../../../display/lv_display.h" #if LV_USE_LINUX_DRM +#include /********************* * DEFINES @@ -26,13 +27,96 @@ extern "C" { * TYPEDEFS **********************/ +typedef drmModeModeInfo lv_linux_drm_mode_t; + +/** + * Callback function type for selecting a DRM display mode + * @param disp pointer to the display object + * @param modes array of available DRM modes + * @param mode_count number of modes in the array + * @return index of the selected mode from the modes array + */ +typedef size_t (*lv_linux_drm_select_mode_cb_t)(lv_display_t * disp, + const lv_linux_drm_mode_t * modes, + size_t mode_count); + /********************** * GLOBAL PROTOTYPES **********************/ + +/** + * @brief Create a new Linux DRM display + * + * Creates and initializes a new LVGL display using the Linux DRM (Direct Rendering Manager) + * subsystem for hardware-accelerated graphics output. + * + * @return Pointer to the created display object, or NULL on failure + */ lv_display_t * lv_linux_drm_create(void); +/** + * @brief Configure the DRM device file and connector for a display + * + * Sets the DRM device file path and connector ID to use for the specified display. + * The DRM device file is typically located at /dev/dri/cardN where N is the card number. + * The connector ID specifies which physical output (HDMI, VGA, etc.) to use. + * + * @param disp Pointer to the display object created with lv_linux_drm_create() + * @param file Path to the DRM device file (e.g., "/dev/dri/card0") + * @param connector_id ID of the DRM connector to use, or -1 to auto-select the first available + */ void lv_linux_drm_set_file(lv_display_t * disp, const char * file, int64_t connector_id); +/** + * @brief Automatically find a suitable DRM device path + * + * Scans the system for available DRM devices and returns the path to a suitable + * device file that can be used with lv_linux_drm_set_file(). + * + * @return Dynamically allocated string containing the device path (must be freed with lv_free()), + * or NULL if no suitable device is found + */ +char * lv_linux_drm_find_device_path(void); + +/** + * Set a callback function for custom DRM mode selection to override the default mode selection behavior + * + * The default mode selection behavior is selecting the native mode + * + * @param disp pointer to the display object + * @param callback function to be called when a display mode needs to be selected, + * or NULL to use the default mode selection behavior + */ +void lv_linux_drm_set_mode_cb(lv_display_t * disp, lv_linux_drm_select_mode_cb_t callback); + +/** + * Get the horizontal resolution of a DRM mode + * @param mode pointer to the DRM mode object + * @return horizontal resolution in pixels, or 0 if mode is invalid + */ +int32_t lv_linux_drm_mode_get_horizontal_resolution(const lv_linux_drm_mode_t * mode); + +/** + * Get the vertical resolution of a DRM mode + * @param mode pointer to the DRM mode object + * @return vertical resolution in pixels, or 0 if mode is invalid + */ +int32_t lv_linux_drm_mode_get_vertical_resolution(const lv_linux_drm_mode_t * mode); + +/** + * Get the refresh rate of a DRM mode + * @param mode pointer to the DRM mode object + * @return refresh rate in Hz, or 0 if mode is invalid + */ +int32_t lv_linux_drm_mode_get_refresh_rate(const lv_linux_drm_mode_t * mode); + +/** + * Check if a DRM mode is the preferred mode for the display + * @param mode pointer to the DRM mode object + * @return true if this is the preferred/native mode, false otherwise + */ +bool lv_linux_drm_mode_is_preferred(const lv_linux_drm_mode_t * mode); + /********************** * MACROS **********************/ diff --git a/src/drivers/display/drm/lv_linux_drm_common.c b/src/drivers/display/drm/lv_linux_drm_common.c new file mode 100644 index 0000000000..0fecb501ab --- /dev/null +++ b/src/drivers/display/drm/lv_linux_drm_common.c @@ -0,0 +1,128 @@ +/** + * @file lv_linux_drm_common.c + * + */ + +/********************* + * INCLUDES + *********************/ + +#include "lv_linux_drm.h" + +#if LV_USE_LINUX_DRM + +#include +#include + +#include "lv_linux_drm.h" +#include "../../../stdlib/lv_sprintf.h" + +/********************* + * DEFINES + *********************/ + +#define LV_DRM_CLASS_DIR "/sys/class/drm" +#define LV_DRM_CARD_PATH "/dev/dri/card" + +/********************** + * TYPEDEFS + **********************/ + +/********************** + * STATIC PROTOTYPES + **********************/ + +static char * find_by_class(void); + +/********************** + * STATIC VARIABLES + **********************/ + +/********************** + * MACROS + **********************/ + +/********************** + * GLOBAL FUNCTIONS + **********************/ + +char * lv_linux_drm_find_device_path(void) +{ + return find_by_class(); +} + +/********************** + * STATIC FUNCTIONS + **********************/ + +static char * find_by_class(void) +{ + DIR * d = opendir(LV_DRM_CLASS_DIR); + if(!d) { + return NULL; + } + + struct dirent * ent; + while((ent = readdir(d)) != NULL) { + if(lv_strcmp(ent->d_name, ".") == 0 || lv_strcmp(ent->d_name, "..") == 0) { + continue; + } + /* connector dirs look like card0-HDMI-A-1, card0-eDP-1, etc. */ + bool is_card = lv_strncmp(ent->d_name, "card", 4) == 0; + bool is_connected = lv_strchr(ent->d_name, '-') != NULL; + + if(!is_card || !is_connected) { + continue; + } + + const size_t buf_size = lv_strlen(LV_DRM_CARD_PATH) + 3; + char * card_path = lv_zalloc(buf_size); + if(ent->d_name[5] != '-') { + /* Double digit card*/ + lv_snprintf(card_path, buf_size, LV_DRM_CARD_PATH "%c%c", ent->d_name[4], ent->d_name[5]); + } + else { + lv_snprintf(card_path, buf_size, LV_DRM_CARD_PATH "%c", ent->d_name[4]); + } + closedir(d); + return card_path; + } + + closedir(d); + return NULL; + +} + +int32_t lv_linux_drm_mode_get_horizontal_resolution(const lv_linux_drm_mode_t * mode) +{ + if(!mode) { + return 0; + } + return mode->hdisplay; +} + +int32_t lv_linux_drm_mode_get_vertical_resolution(const lv_linux_drm_mode_t * mode) +{ + if(!mode) { + return 0; + } + return mode->vdisplay; +} + +int32_t lv_linux_drm_mode_get_refresh_rate(const lv_linux_drm_mode_t * mode) +{ + if(!mode) { + return 0; + } + return mode->vrefresh; +} + +bool lv_linux_drm_mode_is_preferred(const lv_linux_drm_mode_t * mode) +{ + if(!mode) { + return false; + } + return (mode->type & DRM_MODE_TYPE_PREFERRED) != 0; +} + +#endif /*LV_USE_LINUX_DRM*/ diff --git a/src/drivers/display/drm/lv_linux_drm_egl.c b/src/drivers/display/drm/lv_linux_drm_egl.c new file mode 100644 index 0000000000..d315898bbe --- /dev/null +++ b/src/drivers/display/drm/lv_linux_drm_egl.c @@ -0,0 +1,746 @@ +/** + * @file lv_linux_drm_egl.c + * + */ + +/********************* + * INCLUDES + *********************/ +#include "lv_linux_drm.h" + +#if LV_USE_LINUX_DRM && LV_LINUX_DRM_USE_EGL + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "lv_linux_drm_egl_private.h" +#include "../../../draw/lv_draw_buf.h" +#include "../../opengles/lv_opengles_debug.h" + +#include "../../opengles/lv_opengles_driver.h" +#include "../../opengles/lv_opengles_texture.h" +#include "../../opengles/lv_opengles_private.h" + +#include "../../../stdlib/lv_string.h" +#include "../../../display/lv_display.h" + +/********************** + * TYPEDEFS + **********************/ + +typedef struct { + int fd; + struct gbm_bo * bo; + uint32_t fb_id; +} drm_fb_state_t; + +/********************** + * STATIC PROTOTYPES + **********************/ + +static uint32_t tick_cb(void); +static void flush_cb(lv_display_t * disp, const lv_area_t * area, uint8_t * px_map); +static void event_cb(lv_event_t * e); + +static lv_result_t drm_device_init(lv_drm_ctx_t * ctx, const char * path); +static void drm_device_deinit(lv_drm_ctx_t * ctx); + +static lv_egl_interface_t drm_get_egl_interface(lv_drm_ctx_t * ctx); +static drmModeConnector * drm_get_connector(lv_drm_ctx_t * ctx); +static drmModeModeInfo * drm_get_mode(lv_drm_ctx_t * ctx); +static drmModeEncoder * drm_get_encoder(lv_drm_ctx_t * ctx); +static drmModeCrtc * drm_get_crtc(lv_drm_ctx_t * ctx); +static void drm_on_page_flip(int fd, unsigned int frame, unsigned int sec, unsigned int usec, void * data); +static drm_fb_state_t * drm_fb_state_create(lv_drm_ctx_t * ctx, struct gbm_bo * bo); +static void drm_fb_state_destroy_cb(struct gbm_bo * bo, void * data); +static void drm_flip_cb(void * driver_data, bool vsync); + +static void * drm_create_window(void * driver_data, const lv_egl_native_window_properties_t * properties); +static void drm_destroy_window(void * driver_data, void * native_window); +static size_t drm_egl_select_config_cb(void * driver_data, const lv_egl_config_t * configs, size_t config_count); +static inline void set_viewport(lv_display_t * display); + +/********************** + * STATIC VARIABLES + **********************/ + +/********************** + * MACROS + **********************/ + +/********************** + * GLOBAL FUNCTIONS + **********************/ + +lv_display_t * lv_linux_drm_create(void) +{ + lv_tick_set_cb(tick_cb); + lv_drm_ctx_t * ctx = lv_zalloc(sizeof(*ctx)); + LV_ASSERT_MALLOC(ctx); + if(!ctx) { + LV_LOG_ERROR("Failed to create drm context"); + return NULL; + } + + ctx->display = lv_display_create(1, 1); + + if(!ctx->display) { + LV_LOG_ERROR("Failed to create display"); + lv_free(ctx); + return NULL; + } + + lv_display_set_driver_data(ctx->display, ctx); + lv_display_add_event_cb(ctx->display, event_cb, LV_EVENT_DELETE, NULL); + return ctx->display; +} + +void lv_linux_drm_set_file(lv_display_t * display, const char * file, int64_t connector_id) +{ + LV_UNUSED(connector_id); + lv_drm_ctx_t * ctx = lv_display_get_driver_data(display); + + lv_result_t err = drm_device_init(ctx, file); + if(err != LV_RESULT_OK) { + LV_LOG_ERROR("Failed to initialize DRM device"); + return; + } + + lv_display_set_resolution(display, ctx->drm_mode->hdisplay, ctx->drm_mode->vdisplay); + + ctx->egl_interface = drm_get_egl_interface(ctx); + ctx->egl_ctx = lv_opengles_egl_context_create(&ctx->egl_interface); + if(!ctx->egl_ctx) { + LV_LOG_ERROR("Failed to create egl context"); + return; + } + + /* Let the opengles texture driver handle the texture lifetime */ + ctx->texture.is_texture_owner = true; + lv_result_t res = lv_opengles_texture_create_draw_buffers(&ctx->texture, display); + if(res != LV_RESULT_OK) { + LV_LOG_ERROR("Failed to create draw buffers"); + lv_opengles_egl_context_destroy(ctx->egl_ctx); + ctx->egl_ctx = NULL; + return; + } + /* This creates the texture for the first time*/ + lv_opengles_texture_reshape(display, ctx->drm_mode->hdisplay, ctx->drm_mode->vdisplay); + + lv_display_set_flush_cb(display, flush_cb); + lv_display_set_render_mode(display, LV_DISPLAY_RENDER_MODE_DIRECT); + + lv_display_add_event_cb(ctx->display, event_cb, LV_EVENT_RESOLUTION_CHANGED, NULL); + lv_display_add_event_cb(ctx->display, event_cb, LV_EVENT_DELETE, NULL); +} + +void lv_linux_drm_set_mode_cb(lv_display_t * disp, lv_linux_drm_select_mode_cb_t callback) +{ + if(!disp) { + LV_LOG_ERROR("Cannot set a mode select callback on a NULL display"); + return; + } + lv_drm_ctx_t * ctx = lv_display_get_driver_data(disp); + ctx->mode_select_cb = callback; +} + +/********************** + * STATIC FUNCTIONS + **********************/ + +static void event_cb(lv_event_t * e) +{ + lv_event_code_t code = lv_event_get_code(e); + lv_display_t * display = (lv_display_t *) lv_event_get_target(e); + lv_drm_ctx_t * ctx = lv_display_get_driver_data(display); + switch(code) { + case LV_EVENT_DELETE: + if(ctx) { + lv_opengles_egl_context_destroy(ctx->egl_ctx); + ctx->egl_ctx = NULL; + lv_opengles_texture_deinit(&ctx->texture); + drm_device_deinit(ctx); + lv_display_set_driver_data(display, NULL); + } + break; + case LV_EVENT_RESOLUTION_CHANGED: + lv_opengles_texture_reshape(display, lv_display_get_horizontal_resolution(display), + lv_display_get_vertical_resolution(display)); + break; + default: + return; + } +} + +static uint32_t tick_cb(void) +{ + struct timespec ts; + clock_gettime(CLOCK_MONOTONIC, &ts); + return ts.tv_sec * 1000 + (ts.tv_nsec / 1000000);; +} + +static inline void set_viewport(lv_display_t * display) +{ + const lv_display_rotation_t rotation = lv_display_get_rotation(display); + int32_t disp_width, disp_height; + if(rotation == LV_DISPLAY_ROTATION_0 || rotation == LV_DISPLAY_ROTATION_180) { + disp_width = lv_display_get_horizontal_resolution(display); + disp_height = lv_display_get_vertical_resolution(display); + } + else { + disp_width = lv_display_get_vertical_resolution(display) ; + disp_height = lv_display_get_horizontal_resolution(display) ; + } + lv_opengles_viewport(0, 0, disp_width, disp_height); +} + +#if LV_USE_DRAW_OPENGLES + +static void flush_cb(lv_display_t * disp, const lv_area_t * area, uint8_t * px_map) +{ + LV_UNUSED(area); + LV_UNUSED(px_map); + if(lv_display_flush_is_last(disp)) { + set_viewport(disp); + lv_drm_ctx_t * ctx = lv_display_get_driver_data(disp); + lv_opengles_render_display_texture(disp, false, true); + lv_opengles_egl_update(ctx->egl_ctx); + } + lv_display_flush_ready(disp); +} + +#else + +static void flush_cb(lv_display_t * disp, const lv_area_t * area, uint8_t * px_map) +{ + LV_UNUSED(px_map); + LV_UNUSED(area); + if(lv_display_flush_is_last(disp)) { + lv_drm_ctx_t * ctx = lv_display_get_driver_data(disp); + int32_t disp_width = lv_display_get_horizontal_resolution(disp); + int32_t disp_height = lv_display_get_vertical_resolution(disp); + + set_viewport(disp); + + lv_color_format_t cf = lv_display_get_color_format(disp); + uint32_t stride = lv_draw_buf_width_to_stride(lv_display_get_horizontal_resolution(disp), cf); + GL_CALL(glBindTexture(GL_TEXTURE_2D, ctx->texture.texture_id)); + + GL_CALL(glPixelStorei(GL_UNPACK_ALIGNMENT, 1)); + GL_CALL(glPixelStorei(GL_UNPACK_ROW_LENGTH, stride / lv_color_format_get_size(cf))); + /*Color depth: 16 (RGB565), 32 (ARGB8888)*/ +#if LV_COLOR_DEPTH == 16 + GL_CALL(glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB565, disp_width, disp_height, 0, GL_RGB, GL_UNSIGNED_SHORT_5_6_5, + ctx->texture.fb1)); +#elif LV_COLOR_DEPTH == 32 + GL_CALL(glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, disp_width, disp_height, 0, GL_BGRA, GL_UNSIGNED_BYTE, + ctx->texture.fb1)); +#else +#error("Unsupported color format") +#endif + + lv_opengles_render_display_texture(disp, false, false); + lv_opengles_egl_update(ctx->egl_ctx); + } + lv_display_flush_ready(disp); +} +#endif + +void drm_device_deinit(lv_drm_ctx_t * ctx) +{ + if(ctx->drm_crtc) { + drmModeSetCrtc(ctx->fd, + ctx->drm_crtc->crtc_id, + ctx->drm_crtc->buffer_id, + ctx->drm_crtc->x, + ctx->drm_crtc->y, + &ctx->drm_connector->connector_id, + 1, + &ctx->drm_crtc->mode); + drmModeFreeCrtc(ctx->drm_crtc); + ctx->drm_crtc = 0; + } + drm_destroy_window(ctx, ctx->gbm_surface); + + if(ctx->gbm_dev) { + gbm_device_destroy(ctx->gbm_dev); + ctx->gbm_dev = NULL; + } + if(ctx->drm_connector) { + drmModeFreeConnector(ctx->drm_connector); + ctx->drm_connector = NULL; + } + if(ctx->drm_encoder) { + drmModeFreeEncoder(ctx->drm_encoder); + ctx->drm_encoder = NULL; + } + if(ctx->drm_resources) { + drmModeFreeResources(ctx->drm_resources); + ctx->drm_resources = NULL; + } + if(ctx->fd > 0) { + drmClose(ctx->fd); + } + ctx->fd = 0; + ctx->drm_mode = NULL; + lv_free(ctx); +} + +static void drm_fb_state_destroy_cb(struct gbm_bo * bo, void * data) +{ + LV_UNUSED(bo); + drm_fb_state_t * fb = (drm_fb_state_t *) data; + if(fb && fb->fb_id) { + drmModeRmFB(fb->fd, fb->fb_id); + } + lv_free(fb); +} + +static int drm_do_page_flip(lv_drm_ctx_t * ctx, int timeout_ms) +{ + fd_set fds; + FD_ZERO(&fds); + FD_SET(ctx->fd, &fds); + + drmEventContext event_ctx; + lv_memset(&event_ctx, 0, sizeof(event_ctx)); + event_ctx.version = 2; + event_ctx.page_flip_handler = drm_on_page_flip; + + struct timeval timeout; + int status; + if(timeout_ms >= 0) { + timeout.tv_sec = timeout_ms / 1000; + timeout.tv_usec = (timeout_ms % 1000) * 1000; + status = select(ctx->fd + 1, &fds, NULL, NULL, &timeout); + } + else { + status = select(ctx->fd + 1, &fds, NULL, NULL, NULL); + } + + if(status == 1) { + drmHandleEvent(ctx->fd, &event_ctx); + } + return status; +} + +static void drm_on_page_flip(int fd, unsigned int frame, unsigned int sec, unsigned int usec, void * data) +{ + LV_UNUSED(fd); + LV_UNUSED(frame); + LV_UNUSED(sec); + LV_UNUSED(usec); + lv_drm_ctx_t * ctx = (lv_drm_ctx_t *) data; + + if(ctx->gbm_bo_presented) { + gbm_surface_release_buffer(ctx->gbm_surface, ctx->gbm_bo_presented); + } + ctx->gbm_bo_presented = ctx->gbm_bo_flipped; + ctx->gbm_bo_flipped = NULL; +} + +static drm_fb_state_t * drm_fb_state_create(lv_drm_ctx_t * ctx, struct gbm_bo * bo) +{ + LV_ASSERT_NULL(bo); + drm_fb_state_t * fb = (drm_fb_state_t *)gbm_bo_get_user_data(bo); + + if(fb) { + return fb; + } + + uint32_t width = gbm_bo_get_width(bo); + uint32_t height = gbm_bo_get_height(bo); + uint32_t handles[4] = {0}; + uint32_t strides[4] = {0}; + uint32_t offsets[4] = {0}; + uint64_t modifiers[4] = {0}; + uint32_t format = gbm_bo_get_format(bo); + uint64_t modifier = gbm_bo_get_modifier(bo); + uint32_t fb_id = 0; + uint64_t addfb2_mods = 0; + int32_t status; + + drmGetCap(ctx->fd, DRM_CAP_ADDFB2_MODIFIERS, &addfb2_mods); + + for(int i = 0; i < gbm_bo_get_plane_count(bo); i++) { + handles[i] = gbm_bo_get_handle_for_plane(bo, i).u32; + strides[i] = gbm_bo_get_stride_for_plane(bo, i); + offsets[i] = gbm_bo_get_offset(bo, i); + modifiers[i] = modifier; + } + + if(addfb2_mods && modifier != DRM_FORMAT_MOD_INVALID) { + status = drmModeAddFB2WithModifiers(ctx->fd, width, height, format, + handles, strides, offsets, modifiers, + &fb_id, DRM_MODE_FB_MODIFIERS); + } + else { + status = drmModeAddFB2(ctx->fd, width, height, format, + handles, strides, offsets, &fb_id, 0); + } + + if(status < 0) { + LV_LOG_ERROR("Failed to create drm_fb_state: %d", status); + return NULL; + } + + fb = (drm_fb_state_t *)lv_malloc(sizeof(*fb)); + if(!fb) { + LV_LOG_ERROR("Failed to allocate drmfb_state"); + return NULL; + } + + fb->fd = ctx->fd; + fb->bo = bo; + fb->fb_id = fb_id; + + gbm_bo_set_user_data(bo, fb, drm_fb_state_destroy_cb); + return fb; +} + +static void drm_flip_cb(void * driver_data, bool vsync) +{ + lv_drm_ctx_t * ctx = (lv_drm_ctx_t *) driver_data; + + if(ctx->gbm_bo_pending) { + gbm_surface_release_buffer(ctx->gbm_surface, ctx->gbm_bo_pending); + } + ctx->gbm_bo_pending = gbm_surface_lock_front_buffer(ctx->gbm_surface); + + if(!ctx->gbm_bo_pending) { + LV_LOG_ERROR("Failed to lock front buffer"); + return; + } + + drm_fb_state_t * pending_fb = drm_fb_state_create(ctx, ctx->gbm_bo_pending); + + if(!ctx->gbm_bo_pending || !pending_fb) { + LV_LOG_ERROR("Failed to get gbm front buffer"); + return; + } + + if(vsync) { + while(ctx->gbm_bo_flipped && drm_do_page_flip(ctx, -1) >= 0) + continue; + } + else { + drm_do_page_flip(ctx, 0); + } + + if(!ctx->gbm_bo_flipped) { + if(!ctx->crtc_isset) { + int status = drmModeSetCrtc(ctx->fd, ctx->drm_encoder->crtc_id, pending_fb->fb_id, 0, 0, + &(ctx->drm_connector->connector_id), 1, ctx->drm_mode); + if(status < 0) { + LV_LOG_ERROR("Failed to set crtc: %d", status); + return; + } + ctx->crtc_isset = true; + if(ctx->gbm_bo_presented) + gbm_surface_release_buffer(ctx->gbm_surface, ctx->gbm_bo_presented); + ctx->gbm_bo_presented = ctx->gbm_bo_pending; + ctx->gbm_bo_flipped = NULL; + ctx->gbm_bo_pending = NULL; + return; + } + + + uint32_t flip_flags = DRM_MODE_PAGE_FLIP_EVENT; + int status = drmModePageFlip(ctx->fd, ctx->drm_encoder->crtc_id, pending_fb->fb_id, flip_flags, ctx); + if(status < 0) { + LV_LOG_ERROR("Failed to enqueue page flip: %d", status); + return; + } + ctx->gbm_bo_flipped = ctx->gbm_bo_pending; + ctx->gbm_bo_pending = NULL; + } + + /* We need to ensure our surface has a free buffer, otherwise GL will + * have no buffer to render on. */ + while(!gbm_surface_has_free_buffers(ctx->gbm_surface) && + drm_do_page_flip(ctx, -1) >= 0) { + continue; + } +} + +static lv_result_t drm_device_init(lv_drm_ctx_t * ctx, const char * path) +{ + if(!path) { + LV_LOG_ERROR("Device path must not be NULL"); + return LV_RESULT_INVALID; + } + int ret = open(path, O_RDWR); + if(ret < 0) { + LV_LOG_ERROR("Failed to open device path '%s'", path); + goto open_err; + } + ctx->fd = ret; + + ret = drmSetClientCap(ctx->fd, DRM_CLIENT_CAP_UNIVERSAL_PLANES, 1); + if(ret < 0) { + LV_LOG_ERROR("Failed to set universal planes capability"); + goto set_client_cap_err; + } + + ctx->drm_resources = drmModeGetResources(ctx->fd); + if(!ctx->drm_resources) { + LV_LOG_ERROR("Failed to get card resources"); + goto get_resources_err; + } + + ctx->drm_connector = drm_get_connector(ctx); + if(!ctx->drm_connector) { + LV_LOG_ERROR("Failed to find a suitable connector"); + goto get_connector_err; + } + + ctx->drm_mode = drm_get_mode(ctx); + if(!ctx->drm_mode) { + LV_LOG_ERROR("Failed to find a suitable drm mode"); + goto get_mode_err; + } + + ctx->drm_encoder = drm_get_encoder(ctx); + if(!ctx->drm_encoder) { + LV_LOG_ERROR("Failed to find a suitable encoder"); + goto get_encoder_err; + } + + ctx->gbm_dev = gbm_create_device(ctx->fd); + if(!ctx->gbm_dev) { + LV_LOG_ERROR("Failed to create gbm device"); + goto gbm_create_device_err; + } + + if(drmSetMaster(ctx->fd) < 0) { + LV_LOG_ERROR("Failed to become DRM master"); + goto set_master_err; + } + + ctx->drm_crtc = drm_get_crtc(ctx); + if(!ctx->drm_crtc) { + LV_LOG_ERROR("Failed to get crtc"); + goto get_crtc_err; + } + + return LV_RESULT_OK; + +get_crtc_err: + gbm_device_destroy(ctx->gbm_dev); + ctx->gbm_dev = NULL; +set_master_err: + /* Nothing special to do */ +gbm_create_device_err: + drmModeFreeEncoder(ctx->drm_encoder); + ctx->drm_encoder = NULL; +get_encoder_err: + drmModeFreeConnector(ctx->drm_connector); + ctx->drm_connector = NULL; +get_mode_err: + /* Nothing special to do */ +get_connector_err: + drmModeFreeResources(ctx->drm_resources); + ctx->drm_resources = NULL; +get_resources_err: + /* Nothing special to do */ +set_client_cap_err: + close(ctx->fd); + ctx->fd = 0; +open_err: + return LV_RESULT_INVALID; +} + +static size_t drm_egl_select_config_cb(void * driver_data, const lv_egl_config_t * configs, size_t config_count) +{ + lv_drm_ctx_t * ctx = (lv_drm_ctx_t *)driver_data; + int32_t target_w = lv_display_get_horizontal_resolution(ctx->display); + int32_t target_h = lv_display_get_vertical_resolution(ctx->display); + +#if LV_COLOR_DEPTH == 16 + lv_color_format_t target_cf = LV_COLOR_FORMAT_RGB565; +#elif LV_COLOR_DEPTH == 32 + lv_color_format_t target_cf = LV_COLOR_FORMAT_ARGB8888; +#else +#error("Unsupported color format") +#endif + + + for(size_t i = 0; i < config_count; ++i) { + LV_LOG_TRACE("Got config %zu %#x %dx%d %d %d %d %d buffer size %d depth %d samples %d stencil %d surface type %d", + i, configs[i].id, + configs[i].max_width, configs[i].max_height, configs[i].r_bits, configs[i].g_bits, configs[i].b_bits, configs[i].a_bits, + configs[i].buffer_size, configs[i].depth, configs[i].samples, configs[i].stencil, configs[i].surface_type); + } + + for(size_t i = 0; i < config_count; ++i) { + lv_color_format_t config_cf = lv_opengles_egl_color_format_from_egl_config(&configs[i]); + if(configs[i].max_width >= target_w && + configs[i].max_height >= target_h && + config_cf == target_cf && + configs[i].surface_type & EGL_WINDOW_BIT + ) { + LV_LOG_TRACE("Choosing config %zu", i); + return i; + } + } + return config_count; +} + + +/********************** + * STATIC FUNCTIONS + **********************/ + +static lv_egl_interface_t drm_get_egl_interface(lv_drm_ctx_t * ctx) +{ + return (lv_egl_interface_t) { + .driver_data = ctx, + .native_display = ctx->gbm_dev, + .egl_platform = EGL_PLATFORM_GBM_KHR, + .select_config = drm_egl_select_config_cb, + .flip_cb = drm_flip_cb, + .create_window_cb = drm_create_window, + .destroy_window_cb = drm_destroy_window, + }; +} + +static drmModeConnector * drm_get_connector(lv_drm_ctx_t * ctx) +{ + drmModeConnector * connector = NULL; + + LV_ASSERT_NULL(ctx->drm_resources); + for(int i = 0; i < ctx->drm_resources->count_connectors; i++) { + connector = drmModeGetConnector(ctx->fd, ctx->drm_resources->connectors[i]); + if(connector->connection == DRM_MODE_CONNECTED && connector->count_modes > 0) { + return connector; + } + drmModeFreeConnector(connector); + connector = NULL; + } + return connector; +} + +static drmModeModeInfo * drm_get_mode(lv_drm_ctx_t * ctx) +{ + LV_ASSERT_NULL(ctx->drm_connector); + if(ctx->mode_select_cb) { + size_t mode_index = ctx->mode_select_cb(ctx->display, (lv_linux_drm_mode_t *)ctx->drm_connector->modes, + (size_t)ctx->drm_connector->count_modes); + if(mode_index >= (size_t)ctx->drm_connector->count_modes) { + LV_LOG_ERROR("Failed to select drm mode. User select callback return an invalid mode index"); + return NULL; + } + return &ctx->drm_connector->modes[mode_index]; + } + + drmModeModeInfo * best_mode = NULL; + uint32_t best_area = 0; + + for(int i = 0 ; i < ctx->drm_connector->count_modes; ++i) { + drmModeModeInfo * mode = &ctx->drm_connector->modes[i]; + if(mode->type & DRM_MODE_TYPE_PREFERRED) { + return mode; + } + uint32_t area = mode->hdisplay * mode->vdisplay; + if(area > best_area) { + best_area = area; + best_mode = mode; + } + } + LV_LOG_WARN("Failed to find a drm mode with the TYPE_PREFERRED flag. Using the one with the biggest area"); + return best_mode; +} + +static drmModeCrtc * drm_get_crtc(lv_drm_ctx_t * ctx) +{ + drmModeCrtc * crtc = drmModeGetCrtc(ctx->fd, ctx->drm_encoder->crtc_id); + if(crtc) { + return crtc; + } + + /* if there is no current CRTC, attach a suitable one */ + for(int i = 0; i < ctx->drm_resources->count_crtcs; i++) { + if(ctx->drm_encoder->possible_crtcs & (1 << i)) { + ctx->drm_encoder->crtc_id = ctx->drm_resources->crtcs[i]; + crtc = drmModeGetCrtc(ctx->fd, ctx->drm_encoder->crtc_id); + break; + } + } + return crtc; +} + +static drmModeEncoder * drm_get_encoder(lv_drm_ctx_t * ctx) +{ + LV_ASSERT_NULL(ctx->drm_connector); + drmModeEncoder * encoder = NULL; + for(int i = 0; i < ctx->drm_resources->count_encoders; i++) { + encoder = drmModeGetEncoder(ctx->fd, ctx->drm_resources->encoders[i]); + if(!encoder) { + continue; + } + for(int j = 0; j < ctx->drm_connector->count_encoders; j++) { + if(encoder->encoder_id == ctx->drm_connector->encoders[j]) { + return encoder; + } + } + drmModeFreeEncoder(encoder); + encoder = NULL; + } + return encoder; +} + +static void * drm_create_window(void * driver_data, const lv_egl_native_window_properties_t * properties) +{ + lv_drm_ctx_t * ctx = (lv_drm_ctx_t *)driver_data; + LV_ASSERT_NULL(ctx->gbm_dev); + + uint32_t format = properties->visual_id; + + if(format == 0) { + LV_LOG_ERROR("Invalid format requested"); + return NULL; + } + ctx->gbm_surface = gbm_surface_create(ctx->gbm_dev, ctx->drm_mode->hdisplay, ctx->drm_mode->vdisplay, format, + GBM_BO_USE_SCANOUT | GBM_BO_USE_RENDERING); + if(!ctx->gbm_surface) { + LV_LOG_ERROR("Failed to create GBM surface"); + return NULL; + } + return (void *)ctx->gbm_surface; + +} + +static void drm_destroy_window(void * driver_data, void * native_window) +{ + lv_drm_ctx_t * ctx = (lv_drm_ctx_t *)driver_data; + LV_ASSERT(native_window == ctx->gbm_surface); + + if(!ctx->gbm_surface) { + return; + } + + if(ctx->gbm_bo_pending) { + gbm_surface_release_buffer(ctx->gbm_surface, ctx->gbm_bo_pending); + ctx->gbm_bo_pending = NULL; + } + if(ctx->gbm_bo_flipped) { + gbm_surface_release_buffer(ctx->gbm_surface, ctx->gbm_bo_flipped); + ctx->gbm_bo_flipped = NULL; + } + if(ctx->gbm_bo_presented) { + gbm_surface_release_buffer(ctx->gbm_surface, ctx->gbm_bo_presented); + ctx->gbm_bo_presented = NULL; + } + gbm_surface_destroy(ctx->gbm_surface); + ctx->gbm_surface = NULL; +} + + +#endif /*LV_USE_LINUX_DRM && LV_LINUX_DRM_USE_EGL*/ diff --git a/src/drivers/display/drm/lv_linux_drm_egl_private.h b/src/drivers/display/drm/lv_linux_drm_egl_private.h new file mode 100644 index 0000000000..f94572f41a --- /dev/null +++ b/src/drivers/display/drm/lv_linux_drm_egl_private.h @@ -0,0 +1,76 @@ +/** + * @file lv_linux_drm_egl_private.h + * + */ + +#ifndef LV_LINUX_DRM_EGL_PRIVATE_H +#define LV_LINUX_DRM_EGL_PRIVATE_H + + +#ifdef __cplusplus +extern "C" { +#endif + +/********************* + * INCLUDES + *********************/ + +#include "../../../lv_conf_internal.h" + +#if LV_USE_LINUX_DRM && LV_LINUX_DRM_USE_EGL + +#include +#include "../../opengles/lv_opengles_texture_private.h" +#include "../../opengles/lv_opengles_egl.h" +#include "../../opengles/lv_opengles_egl_private.h" +#include "lv_linux_drm.h" + +/********************* + * DEFINES + *********************/ + +/********************** + * TYPEDEFS + **********************/ + +typedef struct { + lv_opengles_texture_t texture; + lv_display_t * display; + lv_opengles_egl_t * egl_ctx; + lv_egl_interface_t egl_interface; + + drmModeRes * drm_resources; + drmModeConnector * drm_connector; + drmModeEncoder * drm_encoder; + drmModeCrtc * drm_crtc; + drmModeModeInfo * drm_mode; + + struct gbm_device * gbm_dev; + struct gbm_surface * gbm_surface; + struct gbm_bo * gbm_bo_pending; + struct gbm_bo * gbm_bo_flipped; + struct gbm_bo * gbm_bo_presented; + + lv_linux_drm_select_mode_cb_t mode_select_cb; + int fd; + bool crtc_isset; +} lv_drm_ctx_t; + + + +/********************** + * GLOBAL PROTOTYPES + **********************/ + +/********************** + * MACROS + **********************/ + +#endif /*LV_USE_LINUX_DRM && LV_LINUX_DRM_USE_EGL*/ + +#ifdef __cplusplus +} /*extern "C"*/ +#endif + + +#endif /*LV_LINUX_DRM_EGL_PRIVATE_H*/ diff --git a/src/drivers/display/fb/lv_linux_fbdev.c b/src/drivers/display/fb/lv_linux_fbdev.c index 1b9ddc02bc..768f7487aa 100644 --- a/src/drivers/display/fb/lv_linux_fbdev.c +++ b/src/drivers/display/fb/lv_linux_fbdev.c @@ -28,6 +28,7 @@ #include "../../../display/lv_display_private.h" #include "../../../draw/sw/lv_draw_sw.h" +#include "../../../misc/lv_area_private.h" /********************* * DEFINES @@ -241,6 +242,7 @@ void lv_linux_fbdev_set_file(lv_display_t * disp, const char * file) LV_LOG_INFO("Resolution is set to %" LV_PRId32 "x%" LV_PRId32 " at %" LV_PRId32 "dpi", hor_res, ver_res, lv_display_get_dpi(disp)); + /* TODO: map delete event callback to deallocate buffers */ } void lv_linux_fbdev_set_force_refresh(lv_display_t * disp, bool enabled) @@ -275,55 +277,75 @@ static void flush_cb(lv_display_t * disp, const lv_area_t * area, uint8_t * colo } #endif - int32_t w = lv_area_get_width(area); - int32_t h = lv_area_get_height(area); - lv_color_format_t cf = lv_display_get_color_format(disp); - uint32_t px_size = lv_color_format_get_size(cf); + const bool wait_for_last_flush = LV_LINUX_FBDEV_RENDER_MODE == LV_DISPLAY_RENDER_MODE_FULL; + const bool is_last_flush = lv_display_flush_is_last(disp); + const bool skip_flush = wait_for_last_flush && !is_last_flush; + + if(skip_flush) { + lv_display_flush_ready(disp); + return; + } + + const lv_color_format_t cf = lv_display_get_color_format(disp); + const uint32_t px_size = lv_color_format_get_size(cf); lv_area_t rotated_area; - lv_display_rotation_t rotation = lv_display_get_rotation(disp); + const lv_display_rotation_t rotation = lv_display_get_rotation(disp); /* Not all framebuffer kernel drivers support hardware rotation, so we need to handle it in software here */ - if(rotation != LV_DISPLAY_ROTATION_0 && LV_LINUX_FBDEV_RENDER_MODE == LV_DISPLAY_RENDER_MODE_PARTIAL) { - /* (Re)allocate temporary buffer if needed */ - size_t buf_size = w * h * px_size; - if(!dsc->rotated_buf || dsc->rotated_buf_size != buf_size) { - dsc->rotated_buf = realloc(dsc->rotated_buf, buf_size); - dsc->rotated_buf_size = buf_size; + if(rotation != LV_DISPLAY_ROTATION_0) { + int32_t src_w; + int32_t src_h; + uint32_t src_stride; + + /* Direct render mode rotation only works if we rotate the whole screen at the same time + * To do that, we use the display's resolution and as the area + * we also grab the current draw buffer so that we can rotate the whole display */ + if(LV_LINUX_FBDEV_RENDER_MODE == LV_DISPLAY_RENDER_MODE_DIRECT) { + if(!is_last_flush) { + /* We need to wait for the last flush when using direct render mode with rotation*/ + lv_display_flush_ready(disp); + return; + } + lv_draw_buf_t * draw_buf = lv_display_get_buf_active(disp); + src_w = lv_display_get_horizontal_resolution(disp); + src_h = lv_display_get_vertical_resolution(disp); + src_stride = lv_draw_buf_width_to_stride(src_w, cf); + color_p = draw_buf->data; + rotated_area.x1 = rotated_area.y1 = 0; + lv_area_set_width(&rotated_area, src_w); + lv_area_set_height(&rotated_area, src_h); } - - /* Rotate the pixel buffer */ - uint32_t w_stride = lv_draw_buf_width_to_stride(w, cf); - uint32_t h_stride = lv_draw_buf_width_to_stride(h, cf); - - switch(rotation) { - case LV_DISPLAY_ROTATION_0: - break; - case LV_DISPLAY_ROTATION_90: - lv_draw_sw_rotate(color_p, dsc->rotated_buf, w, h, w_stride, h_stride, rotation, cf); - break; - case LV_DISPLAY_ROTATION_180: - lv_draw_sw_rotate(color_p, dsc->rotated_buf, w, h, w_stride, w_stride, rotation, cf); - break; - case LV_DISPLAY_ROTATION_270: - lv_draw_sw_rotate(color_p, dsc->rotated_buf, w, h, w_stride, h_stride, rotation, cf); - break; + else { + /* For partial and full render modes, we need to rotate the current area + * In Full mode we will rotate the whole display just like with direct render mode + * but we don't need to do anything special since the area is already the full area of the display + * For Partial mode we will rotate just the part we're currently displaying*/ + src_w = lv_area_get_width(area); + src_h = lv_area_get_height(area); + src_stride = lv_draw_buf_width_to_stride(lv_area_get_width(area), cf); + rotated_area = *area; } - color_p = dsc->rotated_buf; - /* Rotate the area */ - rotated_area = *area; lv_display_rotate_area(disp, &rotated_area); - area = &rotated_area; - - if(rotation != LV_DISPLAY_ROTATION_180) { - w = lv_area_get_width(area); - h = lv_area_get_height(area); + const uint32_t dest_stride = lv_draw_buf_width_to_stride(lv_area_get_width(&rotated_area), cf); + const size_t buf_size = dest_stride * lv_area_get_height(&rotated_area); + if(!dsc->rotated_buf || dsc->rotated_buf_size != buf_size) { + dsc->rotated_buf = lv_realloc(dsc->rotated_buf, buf_size); + LV_ASSERT_MALLOC(dsc->rotated_buf); + dsc->rotated_buf_size = buf_size; } + lv_draw_sw_rotate(color_p, dsc->rotated_buf, src_w, src_h, src_stride, dest_stride, rotation, cf); + area = &rotated_area; + color_p = dsc->rotated_buf; } - /* Ensure that we're within the framebuffer's bounds */ - if(area->x2 < 0 || area->y2 < 0 || area->x1 > (int32_t)dsc->vinfo.xres - 1 || area->y1 > (int32_t)dsc->vinfo.yres - 1) { + lv_area_t display_area; + /* vinfo.xres and vinfo.yres will already be 1 less than the actual resolution. i.e: 1023x767 on a 1024x768 screen */ + lv_area_set(&display_area, 0, 0, dsc->vinfo.xres, dsc->vinfo.yres); + + /* TODO: Consider rendering the clipped area*/ + if(!lv_area_is_in(area, &display_area, 0)) { lv_display_flush_ready(disp); return; } @@ -332,24 +354,25 @@ static void flush_cb(lv_display_t * disp, const lv_area_t * area, uint8_t * colo (area->x1 + dsc->vinfo.xoffset) * px_size + (area->y1 + dsc->vinfo.yoffset) * dsc->finfo.line_length; - int32_t y; - if(LV_LINUX_FBDEV_RENDER_MODE == LV_DISPLAY_RENDER_MODE_DIRECT) { + + const int32_t w = lv_area_get_width(area); + if(LV_LINUX_FBDEV_RENDER_MODE == LV_DISPLAY_RENDER_MODE_DIRECT && rotation == LV_DISPLAY_ROTATION_0) { uint32_t color_pos = area->x1 * px_size + area->y1 * disp->hor_res * px_size; - for(y = area->y1; y <= area->y2; y++) { + for(int32_t y = area->y1; y <= area->y2; y++) { write_to_fb(dsc, fb_pos, &color_p[color_pos], w * px_size); fb_pos += dsc->finfo.line_length; color_pos += disp->hor_res * px_size; } } else { - w = lv_area_get_width(area); - for(y = area->y1; y <= area->y2; y++) { + const int32_t stride = lv_draw_buf_width_to_stride(w, cf); + for(int32_t y = area->y1; y <= area->y2; y++) { write_to_fb(dsc, fb_pos, color_p, w * px_size); fb_pos += dsc->finfo.line_length; - color_p += w * px_size; + color_p += stride; } } diff --git a/src/drivers/display/ft81x/lv_ft81x.h b/src/drivers/display/ft81x/lv_ft81x.h index 0995d4a47d..05899ee029 100644 --- a/src/drivers/display/ft81x/lv_ft81x.h +++ b/src/drivers/display/ft81x/lv_ft81x.h @@ -28,24 +28,24 @@ extern "C" { **********************/ typedef struct { - uint16_t hor_res; - uint16_t ver_res; - - uint16_t hcycle; - uint16_t hoffset; - uint16_t hsync0; - uint16_t hsync1; - uint16_t vcycle; - uint16_t voffset; - uint16_t vsync0; - uint16_t vsync1; - uint8_t swizzle; - uint8_t pclkpol; - uint8_t cspread; - uint8_t pclk; - - bool has_crystal; - bool is_bt81x; + uint16_t hor_res; /**< active display width */ + uint16_t ver_res; /**< active display height */ + + uint16_t hcycle; /**< total number of clocks per line, incl front/back porch */ + uint16_t hoffset; /**< start of active line */ + uint16_t hsync0; /**< start of horizontal sync pulse */ + uint16_t hsync1; /**< end of horizontal sync pulse */ + uint16_t vcycle; /**< total number of lines per screen, including pre/post */ + uint16_t voffset; /**< start of active screen */ + uint16_t vsync0; /**< start of vertical sync pulse */ + uint16_t vsync1; /**< end of vertical sync pulse */ + uint8_t swizzle; /**< FT8xx output to LCD - pin order */ + uint8_t pclkpol; /**< LCD data is clocked in on this PCLK edge */ + uint8_t cspread; /**< helps with noise, when set to 1 fewer signals are changed simultaneously, reset-default: 1 */ + uint8_t pclk; /**< 60MHz / pclk = pclk frequency */ + + bool has_crystal; /**< has an external clock crystal */ + bool is_bt81x; /**< is a BT series model, not FT */ } lv_ft81x_parameters_t; typedef enum { @@ -53,9 +53,10 @@ typedef enum { LV_FT81X_SPI_OPERATION_CS_DEASSERT, LV_FT81X_SPI_OPERATION_SEND, LV_FT81X_SPI_OPERATION_RECEIVE -} lv_ft81x_spi_operation; +} lv_ft81x_spi_operation_t; -typedef void (*lv_ft81x_spi_cb_t)(lv_display_t * disp, lv_ft81x_spi_operation operation, void * data, uint32_t length); +typedef void (*lv_ft81x_spi_cb_t)(lv_display_t * disp, lv_ft81x_spi_operation_t operation, void * data, + uint32_t length); /********************** * GLOBAL PROTOTYPES diff --git a/src/drivers/display/ft81x/lv_ft81x_defines.h b/src/drivers/display/ft81x/lv_ft81x_defines.h index ae9a511092..9a81cd6522 100644 --- a/src/drivers/display/ft81x/lv_ft81x_defines.h +++ b/src/drivers/display/ft81x/lv_ft81x_defines.h @@ -42,7 +42,7 @@ extern "C" { #define CLR_STN 0x2 #define CLR_TAG 0x1 -/* SPI SIO/DIO/QIO tranfer widths */ +/* SPI SIO/DIO/QIO transfer widths */ #define SPI_WIDTH_SIO 0x0 #define SPI_WIDTH_DIO 0x1 #define SPI_WIDTH_QIO 0x2 @@ -168,7 +168,7 @@ extern "C" { /* Defines related to inbuilt font */ #define EVE_NUMCHAR_PERFONT (128L) /* number of font characters per bitmap handle */ -#define EVE_FONT_TABLE_SIZE (148L) /* size of the font table - utilized for loopup by the graphics engine */ +#define EVE_FONT_TABLE_SIZE (148L) /* size of the font table - utilized for lookup by the graphics engine */ #define EVE_FONT_TABLE_POINTER (0xFFFFCUL) /* pointer to the inbuilt font tables starting from bitmap handle 16 */ diff --git a/src/drivers/display/lcd/lv_lcd_generic_mipi.c b/src/drivers/display/lcd/lv_lcd_generic_mipi.c index f589ce9dfd..05edf3aa7a 100644 --- a/src/drivers/display/lcd/lv_lcd_generic_mipi.c +++ b/src/drivers/display/lcd/lv_lcd_generic_mipi.c @@ -30,6 +30,7 @@ static void set_mirror(lv_lcd_generic_mipi_driver_t * drv, bool mirror_x, bool m static void set_swap_xy(lv_lcd_generic_mipi_driver_t * drv, bool swap); static void set_rotation(lv_lcd_generic_mipi_driver_t * drv, lv_display_rotation_t rot); static void res_chg_event_cb(lv_event_t * e); +static void delete_cb(lv_event_t * e); static lv_lcd_generic_mipi_driver_t * get_driver(lv_display_t * disp); static void flush_cb(lv_display_t * disp, const lv_area_t * area, uint8_t * px_map); @@ -71,6 +72,9 @@ lv_display_t * lv_lcd_generic_mipi_create(uint32_t hor_res, uint32_t ver_res, lv /* register resolution change callback (NOTE: this handles screen rotation as well) */ lv_display_add_event_cb(disp, res_chg_event_cb, LV_EVENT_RESOLUTION_CHANGED, NULL); + /* register object deletion callback for freeing driver struct */ + lv_display_add_event_cb(disp, delete_cb, LV_EVENT_DELETE, NULL); + /* register flush callback */ lv_display_set_flush_cb(disp, flush_cb); @@ -333,6 +337,15 @@ static void res_chg_event_cb(lv_event_t * e) set_rotation(drv, rot); } +static void delete_cb(lv_event_t * e) +{ + lv_display_t * disp = lv_event_get_current_target(e); + lv_lcd_generic_mipi_driver_t * drv = get_driver(disp); + LV_ASSERT_NULL(drv); + lv_free(drv); + lv_display_set_driver_data(disp, NULL); +} + static lv_lcd_generic_mipi_driver_t * get_driver(lv_display_t * disp) { return (lv_lcd_generic_mipi_driver_t *)lv_display_get_driver_data(disp); diff --git a/src/drivers/display/lovyan_gfx/lv_lgfx_user.hpp b/src/drivers/display/lovyan_gfx/lv_lgfx_user.hpp new file mode 100644 index 0000000000..7dfce479e2 --- /dev/null +++ b/src/drivers/display/lovyan_gfx/lv_lgfx_user.hpp @@ -0,0 +1,53 @@ +#pragma once + +#if LV_USE_LOVYAN_GFX + +/** + * If using LovyanGFX create LGFX class that inherits from lgfx::LGFX_Device + * https://github.com/lovyan03/LovyanGFX/blob/master/examples/HowToUse/2_user_setting/2_user_setting.ino */ + +/** + * If using other display drivers that is not LovyanGFX + * Create an LGFX wrapper class that implements the functions used in lv_lovyan_gfx.cpp */ +class LGFX +{ +public: + LGFX(void) {} + + bool init(void) + { + return true; + } + + void initDMA(void) {} + + void waitDMA(void) {} + + void fillScreen(uint16_t color) {} + + void setRotation(uint8_t rotation) {} + + void pushImage(int32_t x, int32_t y, int32_t w, int32_t h, uint16_t *data) {} + + void pushImageDMA(int32_t x, int32_t y, int32_t w, int32_t h, uint16_t *data) {} + + void startWrite(void) {} + + uint32_t getStartCount(void) + { + return 0; + } + + void endWrite(void) {} + + void setBrightness(uint8_t brightness){} + + void writePixel(int32_t x, int32_t y, const uint16_t color) {} + + bool getTouch(uint16_t *x, uint16_t *y) + { + return false; + } +}; + +#endif diff --git a/src/drivers/display/lovyan_gfx/lv_lovyan_gfx.cpp b/src/drivers/display/lovyan_gfx/lv_lovyan_gfx.cpp new file mode 100644 index 0000000000..1cfa88f98e --- /dev/null +++ b/src/drivers/display/lovyan_gfx/lv_lovyan_gfx.cpp @@ -0,0 +1,145 @@ +/** + * @file lv_lovyan_gfx.cpp + * + */ + +/********************* + * INCLUDES + *********************/ +#include "lv_lovyan_gfx.h" +#if LV_USE_LOVYAN_GFX + +#include LV_LGFX_USER_INCLUDE + +/********************* + * DEFINES + *********************/ + +/********************** + * TYPEDEFS + **********************/ +typedef struct { + LGFX * tft; +} lv_lovyan_gfx_t; + +/********************** + * STATIC PROTOTYPES + **********************/ +static void flush_cb(lv_display_t * disp, const lv_area_t * area, uint8_t * px_map); +static void resolution_changed_event_cb(lv_event_t * e); +static void read_touch(lv_indev_t * indev_driver, lv_indev_data_t * data); + +/********************** + * STATIC VARIABLES + **********************/ + +/********************** + * MACROS + **********************/ + +/********************** + * GLOBAL FUNCTIONS + **********************/ + +lv_display_t * lv_lovyan_gfx_create(uint32_t hor_res, uint32_t ver_res, void * buf, uint32_t buf_size_bytes, bool touch) +{ + lv_lovyan_gfx_t * dsc = (lv_lovyan_gfx_t *)lv_malloc_zeroed(sizeof(lv_lovyan_gfx_t)); + LV_ASSERT_MALLOC(dsc); + if(dsc == NULL) return NULL; + + lv_display_t * disp = lv_display_create(hor_res, ver_res); + if(disp == NULL) { + lv_free(dsc); + return NULL; + } + + dsc->tft = new LGFX(); + dsc->tft->init(); /* TFT init */ + dsc->tft->initDMA(); + dsc->tft->setRotation(0); + dsc->tft->setBrightness(255); + dsc->tft->startWrite(); + dsc->tft->fillScreen(0x00000); + + lv_display_set_driver_data(disp, (void *)dsc); + lv_display_set_flush_cb(disp, flush_cb); + lv_display_set_color_format(disp, LV_COLOR_FORMAT_RGB565_SWAPPED); + lv_display_add_event_cb(disp, resolution_changed_event_cb, LV_EVENT_RESOLUTION_CHANGED, NULL); + lv_display_set_buffers(disp, (void *)buf, NULL, buf_size_bytes, LV_DISPLAY_RENDER_MODE_PARTIAL); + + if(touch) { + /* Register an input device when touch is enabled */ + lv_indev_t * lv_input = lv_indev_create(); + lv_indev_set_driver_data(lv_input, (void *)dsc); + lv_indev_set_type(lv_input, LV_INDEV_TYPE_POINTER); + lv_indev_set_read_cb(lv_input, read_touch); + } + + return disp; +} + +/********************** + * STATIC FUNCTIONS + **********************/ + +static void flush_cb(lv_display_t * disp, const lv_area_t * area, uint8_t * px_map) +{ + lv_lovyan_gfx_t * dsc = (lv_lovyan_gfx_t *)lv_display_get_driver_data(disp); + + uint32_t w = (area->x2 - area->x1 + 1); + uint32_t h = (area->y2 - area->y1 + 1); + + + if(dsc->tft->getStartCount() == 0) { + dsc->tft->endWrite(); + } + dsc->tft->pushImageDMA(area->x1, area->y1, w, h, (uint16_t *)px_map); + dsc->tft->waitDMA(); + + lv_display_flush_ready(disp); + +} + +static void resolution_changed_event_cb(lv_event_t * e) +{ + lv_display_t * disp = (lv_display_t *)lv_event_get_target(e); + lv_lovyan_gfx_t * dsc = (lv_lovyan_gfx_t *)lv_display_get_driver_data(disp); + int32_t hor_res = lv_display_get_horizontal_resolution(disp); + int32_t ver_res = lv_display_get_vertical_resolution(disp); + lv_display_rotation_t rot = lv_display_get_rotation(disp); + + /* handle rotation */ + switch(rot) { + case LV_DISPLAY_ROTATION_0: + dsc->tft->setRotation(0); /* Portrait orientation */ + break; + case LV_DISPLAY_ROTATION_90: + dsc->tft->setRotation(1); /* Landscape orientation */ + break; + case LV_DISPLAY_ROTATION_180: + dsc->tft->setRotation(2); /* Portrait orientation, flipped */ + break; + case LV_DISPLAY_ROTATION_270: + dsc->tft->setRotation(3); /* Landscape orientation, flipped */ + break; + } +} + +static void read_touch(lv_indev_t * indev_driver, lv_indev_data_t * data) +{ + lv_lovyan_gfx_t * dsc = (lv_lovyan_gfx_t *)lv_indev_get_driver_data(indev_driver); + uint16_t x; + uint16_t y; + bool touched = dsc->tft->getTouch(&x, &y); + if(!touched) { + data->state = LV_INDEV_STATE_RELEASED; + } + else { + data->state = LV_INDEV_STATE_PRESSED; + /*Set the coordinates*/ + data->point.x = x; + data->point.y = y; + } +} + +#endif /*LV_USE_LOVYAN_GFX*/ diff --git a/src/drivers/display/lovyan_gfx/lv_lovyan_gfx.h b/src/drivers/display/lovyan_gfx/lv_lovyan_gfx.h new file mode 100644 index 0000000000..1d27c454d5 --- /dev/null +++ b/src/drivers/display/lovyan_gfx/lv_lovyan_gfx.h @@ -0,0 +1,45 @@ +/** + * @file lv_lovyan_gfx.h + * + */ + +#ifndef LV_LOVYAN_GFX_H +#define LV_LOVYAN_GFX_H + +#ifdef __cplusplus +extern "C" { +#endif + +/********************* + * INCLUDES + *********************/ +#include "../../../display/lv_display.h" +#include "../../../indev/lv_indev.h" + +#if LV_USE_LOVYAN_GFX + +/********************* + * DEFINES + *********************/ + +/********************** + * TYPEDEFS + **********************/ + +/********************** + * GLOBAL PROTOTYPES + **********************/ +lv_display_t * lv_lovyan_gfx_create(uint32_t hor_res, uint32_t ver_res, void * buf, uint32_t buf_size_bytes, + bool touch); + +/********************** + * MACROS + **********************/ + +#endif /* LV_USE_LOVYAN_GFX */ + +#ifdef __cplusplus +} /* extern "C" */ +#endif + +#endif /* LV_LOVYAN_GFX_H */ diff --git a/src/drivers/display/nv3007/lv_nv3007.c b/src/drivers/display/nv3007/lv_nv3007.c new file mode 100644 index 0000000000..5e96adc7e8 --- /dev/null +++ b/src/drivers/display/nv3007/lv_nv3007.c @@ -0,0 +1,226 @@ +/** + * @file lv_nv3007.c + * + */ + +/********************* + * INCLUDES + *********************/ +#include "lv_nv3007.h" + +#if LV_USE_NV3007 + +/********************* + * DEFINES + *********************/ + +#define NV3007_SLPIN 0x10 +#define NV3007_SLPOUT 0x11 + +#define NV3007_INVOFF 0x20 +#define NV3007_INVON 0x21 +#define NV3007_DISPOFF 0x28 +#define NV3007_DISPON 0x29 + +/********************** + * TYPEDEFS + **********************/ + +/********************** + * STATIC PROTOTYPES + **********************/ + +/********************** + * STATIC CONSTANTS + **********************/ + +/* init commands based on ArduinoGFX NV3007 driver */ +static const uint8_t init_cmd_list[] = { + 0x9a, 1, 0x08, + 0x9b, 1, 0x08, + 0x9c, 1, 0xb0, + 0x9d, 1, 0x16, + 0x9e, 1, 0xc4, + 0x8f, 2, 0x55, 0x04, + 0x84, 1, 0x90, + 0x83, 1, 0x7b, + 0x85, 1, 0x33, + 0x60, 1, 0x00, + 0x70, 1, 0x00, + 0x61, 1, 0x02, + 0x71, 1, 0x02, + 0x62, 1, 0x04, + 0x72, 1, 0x04, + 0x6c, 1, 0x29, + 0x7c, 1, 0x29, + 0x6d, 1, 0x31, + 0x7d, 1, 0x31, + 0x6e, 1, 0x0f, + 0x7e, 1, 0x0f, + 0x66, 1, 0x21, + 0x76, 1, 0x21, + 0x68, 1, 0x3A, + 0x78, 1, 0x3A, + 0x63, 1, 0x07, + 0x73, 1, 0x07, + 0x64, 1, 0x05, + 0x74, 1, 0x05, + 0x65, 1, 0x02, + 0x75, 1, 0x02, + 0x67, 1, 0x23, + 0x77, 1, 0x23, + 0x69, 1, 0x08, + 0x79, 1, 0x08, + 0x6a, 1, 0x13, + 0x7a, 1, 0x13, + 0x6b, 1, 0x13, + 0x7b, 1, 0x13, + 0x6f, 1, 0x00, + 0x7f, 1, 0x00, + 0x50, 1, 0x00, + 0x52, 1, 0xd6, + 0x53, 1, 0x08, + 0x54, 1, 0x08, + 0x55, 1, 0x1e, + 0x56, 1, 0x1c, + + 0xa0, 3, 0x2b, 0x24, 0x00, + + 0xa1, 1, 0x87, + 0xa2, 1, 0x86, + 0xa5, 1, 0x00, + 0xa6, 1, 0x00, + 0xa7, 1, 0x00, + 0xa8, 1, 0x36, + 0xa9, 1, 0x7e, + 0xaa, 1, 0x7e, + 0xB9, 1, 0x85, + 0xBA, 1, 0x84, + 0xBB, 1, 0x83, + 0xBC, 1, 0x82, + 0xBD, 1, 0x81, + 0xBE, 1, 0x80, + 0xBF, 1, 0x01, + 0xC0, 1, 0x02, + 0xc1, 1, 0x00, + 0xc2, 1, 0x00, + 0xc3, 1, 0x00, + 0xc4, 1, 0x33, + 0xc5, 1, 0x7e, + 0xc6, 1, 0x7e, + 0xC8, 2, 0x33, 0x33, + 0xC9, 1, 0x68, + 0xCA, 1, 0x69, + 0xCB, 1, 0x6a, + 0xCC, 1, 0x6b, + 0xCD, 2, 0x33, 0x33, + 0xCE, 1, 0x6c, + 0xCF, 1, 0x6d, + 0xD0, 1, 0x6e, + 0xD1, 1, 0x6f, + 0xAB, 2, 0x03, 0x67, + 0xAC, 2, 0x03, 0x6b, + 0xAD, 2, 0x03, 0x68, + 0xAE, 2, 0x03, 0x6c, + 0xb3, 1, 0x00, + 0xb4, 1, 0x00, + 0xb5, 1, 0x00, + 0xB6, 1, 0x32, + 0xB7, 1, 0x7e, + 0xB8, 1, 0x7e, + 0xe0, 1, 0x00, + 0xe1, 2, 0x03, 0x0f, + 0xe2, 1, 0x04, + 0xe3, 1, 0x01, + 0xe4, 1, 0x0e, + 0xe5, 1, 0x01, + 0xe6, 1, 0x19, + 0xe7, 1, 0x10, + 0xe8, 1, 0x10, + 0xea, 1, 0x12, + 0xeb, 1, 0xd0, + 0xec, 1, 0x04, + 0xed, 1, 0x07, + 0xee, 1, 0x07, + 0xef, 1, 0x09, + 0xf0, 1, 0xd0, + 0xf1, 1, 0x0e, + 0xF9, 1, 0x17, + + 0xf2, 4, 0x2c, 0x1b, 0x0b, 0x20, + + 0xe9, 1, 0x29, + 0xec, 1, 0x04, + 0x35, 1, 0x00, + 0x44, 2, 0x00, 0x10, + 0x46, 1, 0x10, + + LV_LCD_CMD_DELAY_MS, LV_LCD_CMD_EOF +}; + +static const uint8_t init_cmd_list_2[] = { + 0x3a, 1, 0x05, + NV3007_SLPOUT, 0, + LV_LCD_CMD_DELAY_MS, 22, + NV3007_DISPON, 0, + + LV_LCD_CMD_DELAY_MS, LV_LCD_CMD_EOF +}; + +/********************** + * STATIC VARIABLES + **********************/ + +/********************** + * MACROS + **********************/ + +/********************** + * GLOBAL FUNCTIONS + **********************/ + +lv_display_t * lv_nv3007_create(uint32_t hor_res, uint32_t ver_res, lv_lcd_flag_t flags, + lv_nv3007_send_cmd_cb_t send_cmd_cb, lv_nv3007_send_color_cb_t send_color_cb) +{ + lv_display_t * disp = lv_lcd_generic_mipi_create(hor_res, ver_res, flags, send_cmd_cb, send_color_cb); + + send_cmd_cb(disp, (const uint8_t[]) { + 0xFF + }, 1, (const uint8_t[]) { + 0xA5 + }, 1); + lv_lcd_generic_mipi_send_cmd_list(disp, init_cmd_list); + send_cmd_cb(disp, (const uint8_t[]) { + 0xFF + }, 1, (const uint8_t[]) { + 0x00 + }, 1); + lv_lcd_generic_mipi_send_cmd_list(disp, init_cmd_list_2); + return disp; +} + +void lv_nv3007_set_gap(lv_display_t * disp, uint16_t x, uint16_t y) +{ + lv_lcd_generic_mipi_set_gap(disp, x, y); +} + +void lv_nv3007_set_invert(lv_display_t * disp, bool invert) +{ + lv_lcd_generic_mipi_set_invert(disp, invert); +} + +void lv_nv3007_set_gamma_curve(lv_display_t * disp, uint8_t gamma) +{ + lv_lcd_generic_mipi_set_gamma_curve(disp, gamma); +} + +void lv_nv3007_send_cmd_list(lv_display_t * disp, const uint8_t * cmd_list) +{ + lv_lcd_generic_mipi_send_cmd_list(disp, cmd_list); +} + +/********************** + * STATIC FUNCTIONS + **********************/ + +#endif /*LV_USE_NV3007*/ diff --git a/src/drivers/display/nv3007/lv_nv3007.h b/src/drivers/display/nv3007/lv_nv3007.h new file mode 100644 index 0000000000..9b5d581e6f --- /dev/null +++ b/src/drivers/display/nv3007/lv_nv3007.h @@ -0,0 +1,94 @@ +/** + * @file lv_nv3007.h + * + * This driver is just a wrapper around the generic MIPI compatible LCD controller driver + * + */ + +#ifndef LV_NV3007_H +#define LV_NV3007_H + +#ifdef __cplusplus +extern "C" { +#endif + +/********************* + * INCLUDES + *********************/ + +#include "../lcd/lv_lcd_generic_mipi.h" + +#if LV_USE_NV3007 + +/********************* + * DEFINES + *********************/ + +/********************** + * TYPEDEFS + **********************/ + +typedef lv_lcd_send_cmd_cb_t lv_nv3007_send_cmd_cb_t; +typedef lv_lcd_send_color_cb_t lv_nv3007_send_color_cb_t; + +/********************** + * GLOBAL PROTOTYPES + **********************/ + +/** + * Create an LCD display with NV3007 driver + * @param hor_res horizontal resolution + * @param ver_res vertical resolution + * @param flags default configuration settings (mirror, RGB ordering, etc.) + * @param send_cmd platform-dependent function to send a command to the LCD controller (usually uses polling transfer) + * @param send_color platform-dependent function to send pixel data to the LCD controller (usually uses DMA transfer: must implement a 'ready' callback) + * @return pointer to the created display + */ +lv_display_t * lv_nv3007_create(uint32_t hor_res, uint32_t ver_res, lv_lcd_flag_t flags, + lv_nv3007_send_cmd_cb_t send_cmd_cb, lv_nv3007_send_color_cb_t send_color_cb); + +/** + * Set gap, i.e., the offset of the (0,0) pixel in the VRAM + * @param disp display object + * @param x x offset + * @param y y offset + */ +void lv_nv3007_set_gap(lv_display_t * disp, uint16_t x, uint16_t y); + +/** + * Set color inversion + * @param disp display object + * @param invert false: normal, true: invert + */ +void lv_nv3007_set_invert(lv_display_t * disp, bool invert); + +/** + * Set gamma curve + * @param disp display object + * @param gamma gamma curve + */ +void lv_nv3007_set_gamma_curve(lv_display_t * disp, uint8_t gamma); + +/** + * Send list of commands. + * @param disp display object + * @param cmd_list controller and panel-specific commands + */ +void lv_nv3007_send_cmd_list(lv_display_t * disp, const uint8_t * cmd_list); + +/********************** + * OTHERS + **********************/ + +/********************** + * MACROS + **********************/ + + +#endif /*LV_USE_NV3007*/ + +#ifdef __cplusplus +} /*extern "C"*/ +#endif + +#endif /*LV_NV3007_H*/ diff --git a/src/drivers/display/nxp_elcdif/lv_nxp_elcdif.c b/src/drivers/display/nxp_elcdif/lv_nxp_elcdif.c new file mode 100644 index 0000000000..c25b371ee4 --- /dev/null +++ b/src/drivers/display/nxp_elcdif/lv_nxp_elcdif.c @@ -0,0 +1,185 @@ +/** + * @file lv_nxp_elcdif.c + * + * Driver for NXP's ELCD + */ + +#include "lv_nxp_elcdif.h" + +#if LV_USE_NXP_ELCDIF == 1 +/********************* + * INCLUDES + *********************/ +#include "../../../display/lv_display_private.h" +#include "fsl_video_common.h" +#include "fsl_elcdif.h" +#include "fsl_cache.h" + +/********************* + * DEFINES + *********************/ +#if (defined(FSL_FEATURE_MEMORY_HAS_ADDRESS_OFFSET) && (0 != FSL_FEATURE_MEMORY_HAS_ADDRESS_OFFSET)) + #define ELCDIF_ADDR_IP_2_CPU(addr) (MEMORY_ConvertMemoryMapAddress((uint32_t)(addr), kMEMORY_DMA2Local)) +#else + #define ELCDIF_ADDR_IP_2_CPU(addr) (addr) +#endif + +/********************** + * TYPEDEFS + **********************/ + +/********************** + * STATIC PROTOTYPES + **********************/ +static void flush_cb(lv_display_t * disp, const lv_area_t * area, uint8_t * color_p); +static void flush_partial_cb(lv_display_t * disp, const lv_area_t * area, uint8_t * color_p); +static lv_color_format_t lv_nxp_elcdif_to_lvgl_color_converter(elcdif_rgb_mode_config_t * config); + +/********************** + * STATIC VARIABLES + **********************/ + +/********************** + * MACROS + **********************/ + +/********************** + * GLOBAL FUNCTIONS + **********************/ + +lv_display_t * lv_nxp_display_elcdif_create_direct(LCDIF_Type * base, const elcdif_rgb_mode_config_t * config, + void * frame_buffer1, + void * frame_buffer2, size_t buf_size) +{ + LV_ASSERT(base); + LV_ASSERT(config); + + lv_display_t * disp = lv_display_create(config->panelWidth, config->panelHeight); + LV_ASSERT(disp); + + lv_color_format_t color_format = lv_nxp_elcdif_to_lvgl_color_converter((elcdif_rgb_mode_config_t *)config); + lv_display_set_color_format(disp, color_format); + lv_display_set_buffers(disp, frame_buffer1, frame_buffer2, buf_size, LV_DISPLAY_RENDER_MODE_DIRECT); + lv_display_set_user_data(disp, base); + + ELCDIF_EnableInterrupts(base, kELCDIF_CurFrameDoneInterruptEnable); + NVIC_EnableIRQ(eLCDIF_IRQn); + + return disp; +} + +lv_display_t * lv_nxp_display_elcdif_create_partial(LCDIF_Type * base, const elcdif_rgb_mode_config_t * config, + void * frame_buffer1, + void * frame_buffer2, size_t buf_size) +{ + LV_ASSERT(base); + LV_ASSERT(config); + + /* Create a direct mode display and then update the buffers to be set in partial mode */ + lv_display_t * disp = lv_nxp_display_elcdif_create_direct(base, config, frame_buffer1, frame_buffer2, buf_size); + ELCDIF_DisableInterrupts(base, kELCDIF_CurFrameDoneInterruptEnable); + NVIC_DisableIRQ(eLCDIF_IRQn); + + lv_display_set_flush_cb(disp, flush_partial_cb); + lv_display_set_buffers(disp, frame_buffer1, frame_buffer2, buf_size, LV_DISPLAY_RENDER_MODE_PARTIAL); + + ELCDIF_EnableInterrupts(base, kELCDIF_CurFrameDoneInterruptEnable); + NVIC_EnableIRQ(eLCDIF_IRQn); + + return disp; +} + +void lv_nxp_display_elcdif_event_handler(const lv_display_t * disp) +{ + if(disp == NULL) { + /* Just return since no valid display has been set yet */ + return; + } + + LCDIF_Type * base = (LCDIF_Type *)lv_display_get_user_data((lv_display_t *)disp); + uint32_t intStatus = ELCDIF_GetInterruptStatus(base); + + ELCDIF_ClearInterruptStatus(base, intStatus); + + if(intStatus & kELCDIF_CurFrameDone) { + /* flush ready is ISR safe and atomic, so calling inside of the + * framebuffer interrupt is safe and makes the flush chain + * non blocking even in bare metal systems. + */ + lv_disp_flush_ready((lv_display_t *)disp); + } + + SDK_ISR_EXIT_BARRIER; +} + +/********************** + * STATIC FUNCTIONS + **********************/ + +static void flush_cb(lv_display_t * disp, const lv_area_t * area, uint8_t * color_p) +{ + LCDIF_Type * base = (LCDIF_Type *)lv_display_get_user_data(disp); + + DCACHE_CleanInvalidateByRange((uint32_t)color_p, lv_display_get_draw_buf_size(disp)); + + if(!lv_display_flush_is_last(disp)) { + lv_disp_flush_ready(disp); + return; + } + ELCDIF_SetNextBufferAddr(base, (uint32_t)color_p); +} + +static void flush_partial_cb(lv_display_t * disp, const lv_area_t * area, uint8_t * color_p) +{ + LCDIF_Type * base = (LCDIF_Type *)lv_display_get_user_data(disp); + + DCACHE_CleanInvalidateByRange((uint32_t)color_p, lv_display_get_draw_buf_size(disp)); + + uint8_t * fb = (uint8_t *)ELCDIF_ADDR_IP_2_CPU(base->CUR_BUF); + int32_t w = lv_area_get_width(area); + int32_t h = lv_area_get_height(area); + int32_t disp_w = lv_display_get_horizontal_resolution(disp); + int32_t disp_h = lv_display_get_vertical_resolution(disp); + int32_t bytes_per_pixel = LV_COLOR_FORMAT_GET_SIZE(lv_display_get_color_format(disp)); + int32_t i; + + fb = fb + area->y1 * disp_h; + fb = fb + area->x1; + + for(i = 0; i < h; i++) { + lv_memcpy(fb, color_p, w * bytes_per_pixel); + fb += disp_h; + color_p += w; + } +} + +static lv_color_format_t lv_nxp_elcdif_to_lvgl_color_converter(elcdif_rgb_mode_config_t * config) +{ + /*Handle color format conversion*/ + lv_color_format_t color_format; + + switch(config->pixelFormat) { + case kELCDIF_PixelFormatRAW8 : + color_format = LV_COLOR_FORMAT_L8; + break; + case kELCDIF_PixelFormatRGB565 : + color_format = LV_COLOR_FORMAT_RGB565; + break; + case kELCDIF_PixelFormatXRGB8888 : + color_format = LV_COLOR_FORMAT_XRGB8888; + break; + case kELCDIF_PixelFormatRGB888 : + color_format = LV_COLOR_FORMAT_RGB888; + break; + /* + There are some color formats in ELCDIF which LVGL does not support. + For these, use unknown format and drop a msg for the user + */ + default : + color_format = LV_COLOR_FORMAT_UNKNOWN; + LV_LOG_WARN("Not supported color format in ELCDIF. Using LV_UNKNOWN!"); + } + return color_format; +} + +#endif /*LV_USE_NXP_ELCDIF*/ diff --git a/src/drivers/display/nxp_elcdif/lv_nxp_elcdif.h b/src/drivers/display/nxp_elcdif/lv_nxp_elcdif.h new file mode 100644 index 0000000000..29625e9e3a --- /dev/null +++ b/src/drivers/display/nxp_elcdif/lv_nxp_elcdif.h @@ -0,0 +1,84 @@ +/** + * @file lv_nxp_elcdif.h + * Driver for NXP's ELCD + */ + +#ifndef LV_NXP_ELCDIF_H +#define LV_NXP_ELCDIF_H + +#include "../../../lvgl.h" +#include "../../../display/lv_display.h" + +#if LV_USE_NXP_ELCDIF == 1 + +#ifdef __cplusplus +extern "C" { +#endif + +/********************* + * INCLUDES + *********************/ + +#include "fsl_elcdif.h" +/********************* + * DEFINES + *********************/ + +/********************** + * TYPEDEFS + **********************/ + +/********************** + * GLOBAL PROTOTYPES + **********************/ + +/** + * Attach LVGL to ELCDIF using DIRECT rendering mode. + * ELCDIF should be already initialized. + * @param base The NXP eLCD controller base address + * @param config NXP eLCD config object + * @param frame_buffer1 pointer the first frame buffers + * @param frame_buffer2 pointer the second frame buffers + * @param buf_size size of a buffer in bytes (must be at least as large as the screen) + * @return a display object initialized and registerd on the LVGL runtime + */ +lv_display_t * lv_nxp_display_elcdif_create_direct(LCDIF_Type * base, const elcdif_rgb_mode_config_t * config, + void * frame_buffer1, + void * frame_buffer2, size_t buf_size); + + +/** +* Attach LVGL to ELCDIF using PARTIAL rendering mode. +* ELCDIF should be already initialized. +* @param base The NXP eLCD controller base address +* @param config NXP eLCD config object +* @param frame_buffer1 pointer the first frame buffers +* @param frame_buffer2 pointer the second frame buffers +* @param buf_size size of a buffer in bytes +* @return a display object initialized and registerd on the LVGL runtime +*/ +lv_display_t * lv_nxp_display_elcdif_create_partial(LCDIF_Type * base, const elcdif_rgb_mode_config_t * config, + void * frame_buffer1, + void * frame_buffer2, size_t buf_size); + +/** + * Call this function on the LCD Interrupt Service Routine + * It tells to LVGL what to do when a framebuffer is transmitted + * to the LCD panel + * @param disp The display instance that contains the eLCD related data + * + * @note: the parameter disp is tipycally the return value after + * `lv_nxp_display_elcdif_create_direct` has been sucessfully executed + */ +void lv_nxp_display_elcdif_event_handler(const lv_display_t * disp); +/********************** + * MACROS + **********************/ + +#ifdef __cplusplus +} /*extern "C"*/ +#endif + +#endif /*LV_USE_NXP_ELCDIF*/ + +#endif /* LV_NXP_ELCDIF_H */ diff --git a/src/drivers/display/st_ltdc/lv_st_ltdc.c b/src/drivers/display/st_ltdc/lv_st_ltdc.c index 0b167f14bd..10599d1529 100644 --- a/src/drivers/display/st_ltdc/lv_st_ltdc.c +++ b/src/drivers/display/st_ltdc/lv_st_ltdc.c @@ -13,16 +13,18 @@ #include "lv_st_ltdc.h" #include "../../../display/lv_display_private.h" #include "../../../draw/sw/lv_draw_sw.h" -#include "ltdc.h" +#include "main.h" #if LV_ST_LTDC_USE_DMA2D_FLUSH #if LV_USE_DRAW_DMA2D #error cannot use LV_ST_LTDC_USE_DMA2D_FLUSH with LV_USE_DRAW_DMA2D #endif /*LV_USE_DRAW_DMA2D*/ - #include "dma2d.h" + extern DMA2D_HandleTypeDef hdma2d; #endif /*LV_ST_LTDC_USE_DMA2D_FLUSH*/ +extern LTDC_HandleTypeDef hltdc; + /********************* * DEFINES *********************/ diff --git a/src/drivers/draw/eve/lv_draw_eve_display.c b/src/drivers/draw/eve/lv_draw_eve_display.c new file mode 100644 index 0000000000..e6c3d3a14f --- /dev/null +++ b/src/drivers/draw/eve/lv_draw_eve_display.c @@ -0,0 +1,278 @@ +/** + * @file lv_draw_eve_display.c + * + */ + +/********************* + * INCLUDES + *********************/ + +#include "lv_draw_eve_display.h" +#if LV_USE_DRAW_EVE + +#include "../../../draw/eve/lv_eve.h" +#include "../../../draw/eve/lv_draw_eve.h" +#include "../../../display/lv_display_private.h" +#include "../../../misc/lv_text_private.h" + +#include "../../../libs/FT800-FT813/EVE_commands.h" + + +/********************* + * DEFINES + *********************/ + +/********************** + * TYPEDEFS + **********************/ + +/********************** + * STATIC PROTOTYPES + **********************/ + +static void flush_cb(lv_display_t * disp, const lv_area_t * area, uint8_t * px_map); +static void resolution_changed_cb(lv_event_t * e); +static void render_start_cb(lv_event_t * e); +static void render_ready_cb(lv_event_t * e); +static void touch_read_cb(lv_indev_t * indev, lv_indev_data_t * data); + +/********************** + * STATIC VARIABLES + **********************/ + +/********************** + * MACROS + **********************/ + +/********************** + * GLOBAL FUNCTIONS + **********************/ + +lv_display_t * lv_draw_eve_display_create(const lv_draw_eve_parameters_t * params, lv_draw_eve_operation_cb_t op_cb, + void * user_data) +{ + static uint32_t dummy_buf; /* It won't be used as it will send commands instead of draw pixels. */ + + lv_display_t * disp = lv_display_create(params->hor_res, params->ver_res); + lv_display_set_flush_cb(disp, flush_cb); + lv_display_set_buffers(disp, &dummy_buf, NULL, + params->hor_res * params->ver_res * LV_COLOR_FORMAT_GET_SIZE(LV_COLOR_FORMAT_NATIVE), + LV_DISPLAY_RENDER_MODE_FULL); /* recreate the full display list each refresh */ + lv_display_add_event_cb(disp, resolution_changed_cb, LV_EVENT_RESOLUTION_CHANGED, NULL); + lv_display_add_event_cb(disp, render_start_cb, LV_EVENT_RENDER_START, NULL); + lv_display_add_event_cb(disp, render_ready_cb, LV_EVENT_RENDER_READY, NULL); + lv_display_set_driver_data(disp, user_data); + + lv_draw_eve_set_display_data(disp, params, op_cb); + + EVE_init(); + EVE_memWrite8(REG_PWM_DUTY, EVE_BACKLIGHT_PWM); /* 0 = off, 0x80 = max */ + + return disp; +} + +void * lv_draw_eve_display_get_user_data(lv_display_t * disp) +{ + return lv_display_get_driver_data(disp); +} + +lv_indev_t * lv_draw_eve_touch_create(lv_display_t * disp) +{ + lv_indev_t * indev = lv_indev_create(); + + lv_indev_set_display(indev, disp); + lv_indev_set_type(indev, LV_INDEV_TYPE_POINTER); + lv_indev_set_read_cb(indev, touch_read_cb); + + return indev; +} + +void lv_draw_eve_pre_upload_image(lv_display_t * disp, const void * src) +{ + LV_ASSERT_MSG(disp->flush_cb == flush_cb, "tried to do an LVGL EVE pre-upload without a draw_eve display"); + + if(!lv_draw_eve_image_src_check(src)) { + return; + } + + uint32_t ramg_addr = lv_draw_eve_image_upload_image(false, src); + if(ramg_addr == LV_DRAW_EVE_RAMG_OUT_OF_RAMG) { + LV_LOG_WARN("Could not pre-upload image because space could not be allocated in RAM_G."); + } +} + +void lv_draw_eve_pre_upload_font_range(lv_display_t * disp, const lv_font_t * font, uint32_t unicode_range_start, + uint32_t unicode_range_end) +{ + LV_ASSERT_MSG(disp->flush_cb == flush_cb, "tried to do an LVGL EVE pre-upload without a draw_eve display"); + + if(!lv_draw_eve_label_font_check(font)) { + return; + } + + for(uint32_t i = unicode_range_start; i <= unicode_range_end; i++) { + lv_font_glyph_dsc_t glyph_dsc; + bool found = lv_font_get_glyph_dsc_fmt_txt(font, &glyph_dsc, i, '\0'); + if(!found) { + LV_LOG_INFO("Could not pre-upload glyph with unicode code point '0x%"LV_PRIX32"' " + "because it is not part of the font", i); + continue; + } + uint32_t ramg_addr = lv_draw_eve_label_upload_glyph(false, font->dsc, glyph_dsc.gid.index); + if(ramg_addr == LV_DRAW_EVE_RAMG_OUT_OF_RAMG) { + LV_LOG_WARN("Could not pre-upload glyph because space could not be allocated in RAM_G."); + /* don't return in case there are smaller glyphs that there is space for */ + } + } +} + +void lv_draw_eve_pre_upload_font_text(lv_display_t * disp, const lv_font_t * font, const char * text) +{ + LV_ASSERT_MSG(disp->flush_cb == flush_cb, "tried to do an LVGL EVE pre-upload without a draw_eve display"); + + if(!lv_draw_eve_label_font_check(font)) { + return; + } + + for(uint32_t i = 0; text[i];) { + uint32_t unicode_letter; + uint32_t unicode_letter_next; + lv_text_encoded_letter_next_2(text, &unicode_letter, &unicode_letter_next, &i); + lv_font_glyph_dsc_t glyph_dsc; + bool found = lv_font_get_glyph_dsc_fmt_txt(font, &glyph_dsc, unicode_letter, unicode_letter_next); + if(!found) { + LV_LOG_INFO("Could not pre-upload glyph with unicode code point '0x%"LV_PRIX32"' " + "because it is not part of the font", unicode_letter); + continue; + } + uint32_t ramg_addr = lv_draw_eve_label_upload_glyph(false, font->dsc, glyph_dsc.gid.index); + if(ramg_addr == LV_DRAW_EVE_RAMG_OUT_OF_RAMG) { + LV_LOG_WARN("Could not pre-upload glyph because space could not be allocated in RAM_G."); + /* don't return in case there are smaller glyphs that there is space for */ + } + } +} + +uint8_t lv_draw_eve_memread8(lv_display_t * disp, uint32_t address) +{ + LV_ASSERT_MSG(disp->flush_cb == flush_cb, "tried to use an LVGL EVE command without a draw_eve display"); + return EVE_memRead8(address); +} + +uint16_t lv_draw_eve_memread16(lv_display_t * disp, uint32_t address) +{ + LV_ASSERT_MSG(disp->flush_cb == flush_cb, "tried to use an LVGL EVE command with a non-draw_eve display"); + return EVE_memRead16(address); +} + +uint32_t lv_draw_eve_memread32(lv_display_t * disp, uint32_t address) +{ + LV_ASSERT_MSG(disp->flush_cb == flush_cb, "tried to use an LVGL EVE command with a non-draw_eve display"); + return EVE_memRead32(address); +} + +void lv_draw_eve_memwrite8(lv_display_t * disp, uint32_t address, uint8_t data) +{ + LV_ASSERT_MSG(disp->flush_cb == flush_cb, "tried to use an LVGL EVE command with a non-draw_eve display"); + EVE_memWrite8(address, data); +} + +void lv_draw_eve_memwrite16(lv_display_t * disp, uint32_t address, uint16_t data) +{ + LV_ASSERT_MSG(disp->flush_cb == flush_cb, "tried to use an LVGL EVE command with a non-draw_eve display"); + EVE_memWrite16(address, data); +} + +void lv_draw_eve_memwrite32(lv_display_t * disp, uint32_t address, uint32_t data) +{ + LV_ASSERT_MSG(disp->flush_cb == flush_cb, "tried to use an LVGL EVE command with a non-draw_eve display"); + EVE_memWrite32(address, data); +} + +/********************** + * STATIC FUNCTIONS + **********************/ + +static void flush_cb(lv_display_t * disp, const lv_area_t * area, uint8_t * px_map) +{ + if(lv_display_flush_is_last(disp)) { + EVE_cmd_dl_burst(DL_DISPLAY); /* instruct the co-processor to show the list */ + EVE_cmd_dl_burst(CMD_SWAP); /* make this list active */ + EVE_end_cmd_burst(); + + EVE_execute_cmd(); + + EVE_start_cmd_burst(); + } + + lv_display_flush_ready(disp); +} + +static void resolution_changed_cb(lv_event_t * e) +{ + lv_display_t * disp = lv_event_get_target(e); + + lv_display_rotation_t rotation = lv_display_get_rotation(disp); + uint32_t cmd_value; + switch(rotation) { + case LV_DISPLAY_ROTATION_0: + cmd_value = 0; + break; + case LV_DISPLAY_ROTATION_90: + cmd_value = 2; + break; + case LV_DISPLAY_ROTATION_180: + cmd_value = 1; + break; + case LV_DISPLAY_ROTATION_270: + cmd_value = 3; + break; + default: + return; + } + + /* no need to rotate the touch coordinates with CMD_SETROTATE, as LVGL + * already rotates the input coordinates. + */ + EVE_memWrite8(REG_ROTATE, cmd_value); +} + +static void render_start_cb(lv_event_t * e) +{ + EVE_start_cmd_burst(); + + EVE_cmd_dl_burst(CMD_DLSTART); /* start the display list */ + EVE_cmd_dl_burst(DL_CLEAR_COLOR_RGB | 0x000000); + EVE_cmd_dl_burst(DL_CLEAR | CLR_COL | CLR_STN | CLR_TAG); + EVE_cmd_dl_burst(VERTEX_FORMAT(0)); +} + +static void render_ready_cb(lv_event_t * e) +{ + EVE_end_cmd_burst(); +} + +static void touch_read_cb(lv_indev_t * indev, lv_indev_data_t * data) +{ + lv_display_t * disp = lv_indev_get_display(indev); + + if(disp == NULL || disp->flush_cb != flush_cb) return; + + uint32_t xy = EVE_memRead32(REG_TOUCH_SCREEN_XY); + uint16_t x = xy >> 16; + uint16_t y = xy & 0xffff; + + int32_t disp_w = lv_display_get_original_horizontal_resolution(disp); + int32_t disp_h = lv_display_get_original_vertical_resolution(disp); + + if(x < disp_w && y < disp_h) { + data->state = LV_INDEV_STATE_PRESSED; + data->point.x = x; + data->point.y = y; + } + else { + data->state = LV_INDEV_STATE_RELEASED; + } +} + +#endif /*LV_USE_DRAW_EVE*/ diff --git a/src/drivers/draw/eve/lv_draw_eve_display.h b/src/drivers/draw/eve/lv_draw_eve_display.h new file mode 100644 index 0000000000..860159ba05 --- /dev/null +++ b/src/drivers/draw/eve/lv_draw_eve_display.h @@ -0,0 +1,151 @@ +/** + * @file lv_draw_eve_display.h + * + */ + +#ifndef LV_DRAW_EVE_DISPLAY_H +#define LV_DRAW_EVE_DISPLAY_H + +#ifdef __cplusplus +extern "C" { +#endif + +/********************* + * INCLUDES + *********************/ + +#include "../../../lv_conf_internal.h" +#if LV_USE_DRAW_EVE + +#include "../../../draw/eve/lv_draw_eve_target.h" + +/********************* + * DEFINES + *********************/ + +/********************** + * TYPEDEFS + **********************/ + +/********************** + * GLOBAL PROTOTYPES + **********************/ + +/** + * Create a display for the EVE draw unit. + * @param params Pointer to a struct of display parameters. Can be a temporary variable + * @param op_cb A callback that will be called to perform pin and SPI IO operations with the EVE chip + * @param user_data use `lv_draw_eve_display_get_user_data` to get this pointer inside the `op_cb` + * @return the EVE display + */ +lv_display_t * lv_draw_eve_display_create(const lv_draw_eve_parameters_t * params, lv_draw_eve_operation_cb_t op_cb, + void * user_data); + +/** + * Get the `user_data` parameter that was passed to `lv_draw_eve_display_create`. Useful in the operation callback. + * @param disp pointer to the lv_draw_eve display + * @return the `user_data` pointer + */ +void * lv_draw_eve_display_get_user_data(lv_display_t * disp); + +/** + * Create a touchscreen indev for the EVE display. + * @param disp pointer to the lv_draw_eve display + * @return the EVE touchscreen indev + */ +lv_indev_t * lv_draw_eve_touch_create(lv_display_t * disp); + + +/* RAM_G asset pre-upload functions */ + +/** + * Upload an image src to RAM_G now instead of as-needed during rendering. + * @param disp pointer to the lv_draw_eve display + * @param src image src. The value passed to `lv_image_set_src` + */ +void lv_draw_eve_pre_upload_image(lv_display_t * disp, const void * src); + +/** + * Upload font glyphs to RAM_G now instead of as-needed during rendering. + * Upload all the glyphs in the range of unicode code points (inclusive of the start and end values). + * It can be called multiple times with different ranges. + * @param disp pointer to the lv_draw_eve display + * @param font the font to upload glyphs from + * @param unicode_range_start the first unicode code point in the range of glyphs to upload + * @param unicode_range_end the last unicode code point (inclusive) in the range of glyphs to upload + */ +void lv_draw_eve_pre_upload_font_range(lv_display_t * disp, const lv_font_t * font, uint32_t unicode_range_start, + uint32_t unicode_range_end); + +/** + * Upload font glyphs to RAM_G now instead of as-needed during rendering. + * It will upload all the glyphs needed to render the string `text`. + * It can be called multiple times with different strings. + * @param disp pointer to the lv_draw_eve display + * @param font the font to upload glyphs from + * @param text the ASCII or UTF-8 string that will be iterated for glyphs to upload + */ +void lv_draw_eve_pre_upload_font_text(lv_display_t * disp, const lv_font_t * font, const char * text); + + +/* Low-level EVE control functions */ + +/** + * Call `EVE_memRead8` for custom low-level control of the display. + * @param disp the display returned by `lv_draw_eve_display_create` + * @param address the EVE address to read from + * @return the read value + */ +uint8_t lv_draw_eve_memread8(lv_display_t * disp, uint32_t address); + +/** + * Call `EVE_memRead16` for custom low-level control of the display. + * @param disp the display returned by `lv_draw_eve_display_create` + * @param address the EVE address to read from + * @return the read value + */ +uint16_t lv_draw_eve_memread16(lv_display_t * disp, uint32_t address); + +/** + * Call `EVE_memRead32` for custom low-level control of the display. + * @param disp the display returned by `lv_draw_eve_display_create` + * @param address the EVE address to read from + * @return the read value + */ +uint32_t lv_draw_eve_memread32(lv_display_t * disp, uint32_t address); + +/** + * Call `EVE_memWrite8` for custom low-level control of the display. + * @param disp the display returned by `lv_draw_eve_display_create` + * @param address the EVE address to write to + * @param data the value to write + */ +void lv_draw_eve_memwrite8(lv_display_t * disp, uint32_t address, uint8_t data); + +/** + * Call `EVE_memWrite16` for custom low-level control of the display. + * @param disp the display returned by `lv_draw_eve_display_create` + * @param address the EVE address to write to + * @param data the value to write + */ +void lv_draw_eve_memwrite16(lv_display_t * disp, uint32_t address, uint16_t data); + +/** + * Call `EVE_memWrite32` for custom low-level control of the display. + * @param disp the display returned by `lv_draw_eve_display_create` + * @param address the EVE address to write to + * @param data the value to write + */ +void lv_draw_eve_memwrite32(lv_display_t * disp, uint32_t address, uint32_t data); + +/********************** + * MACROS + **********************/ + +#endif /*LV_USE_DRAW_EVE*/ + +#ifdef __cplusplus +} /*extern "C"*/ +#endif + +#endif /*LV_DRAW_EVE_DISPLAY_H*/ diff --git a/src/drivers/draw/eve/lv_draw_eve_display_defines.h b/src/drivers/draw/eve/lv_draw_eve_display_defines.h new file mode 100644 index 0000000000..1d2efff155 --- /dev/null +++ b/src/drivers/draw/eve/lv_draw_eve_display_defines.h @@ -0,0 +1,1207 @@ +/** + * @file lv_draw_eve_display_defines.h + * + */ + +#ifndef LV_DRAW_EVE_DISPLAY_DEFINES_H +#define LV_DRAW_EVE_DISPLAY_DEFINES_H + +#ifdef __cplusplus +extern "C" { +#endif + +/********************* + * INCLUDES + *********************/ + +#include "../../../lv_conf_internal.h" +#if LV_USE_DRAW_EVE + +/********************* + * DEFINES + *********************/ + +/* Memory */ +#define LV_EVE_EVE_RAM_G ((uint32_t) 0x00000000UL) +#define LV_EVE_EVE_ROM_CHIPID ((uint32_t) 0x000C0000UL) +#define LV_EVE_EVE_ROM_FONT ((uint32_t) 0x001E0000UL) +#define LV_EVE_EVE_ROM_FONTROOT ((uint32_t) 0x002FFFFCUL) +#define LV_EVE_EVE_RAM_DL ((uint32_t) 0x00300000UL) +#define LV_EVE_EVE_RAM_REG ((uint32_t) 0x00302000UL) +#define LV_EVE_EVE_RAM_CMD ((uint32_t) 0x00308000UL) + +/* Memory buffer sizes */ +#define LV_EVE_EVE_RAM_G_SIZE ((uint32_t) 1024U*1024UL) +#define LV_EVE_EVE_CMDFIFO_SIZE ((uint32_t) 4U*1024UL) +#define LV_EVE_EVE_RAM_DL_SIZE ((uint32_t) 8U*1024UL) + +/* diplay list list commands, most need OR's arguments */ +#define LV_EVE_DL_DISPLAY ((uint32_t) 0x00000000UL) +#define LV_EVE_DL_BITMAP_SOURCE ((uint32_t) 0x01000000UL) +#define LV_EVE_DL_CLEAR_COLOR_RGB ((uint32_t) 0x02000000UL) +#define LV_EVE_DL_TAG ((uint32_t) 0x03000000UL) +#define LV_EVE_DL_COLOR_RGB ((uint32_t) 0x04000000UL) +#define LV_EVE_DL_BITMAP_HANDLE ((uint32_t) 0x05000000UL) +#define LV_EVE_DL_CELL ((uint32_t) 0x06000000UL) +#define LV_EVE_DL_BITMAP_LAYOUT ((uint32_t) 0x07000000UL) +#define LV_EVE_DL_BITMAP_SIZE ((uint32_t) 0x08000000UL) +#define LV_EVE_DL_ALPHA_FUNC ((uint32_t) 0x09000000UL) +#define LV_EVE_DL_STENCIL_FUNC ((uint32_t) 0x0A000000UL) +#define LV_EVE_DL_BLEND_FUNC ((uint32_t) 0x0B000000UL) +#define LV_EVE_DL_STENCIL_OP ((uint32_t) 0x0C000000UL) +#define LV_EVE_DL_POINT_SIZE ((uint32_t) 0x0D000000UL) +#define LV_EVE_DL_LINE_WIDTH ((uint32_t) 0x0E000000UL) +#define LV_EVE_DL_CLEAR_COLOR_A ((uint32_t) 0x0F000000UL) +#define LV_EVE_DL_COLOR_A ((uint32_t) 0x10000000UL) +#define LV_EVE_DL_CLEAR_STENCIL ((uint32_t) 0x11000000UL) +#define LV_EVE_DL_CLEAR_TAG ((uint32_t) 0x12000000UL) +#define LV_EVE_DL_STENCIL_MASK ((uint32_t) 0x13000000UL) +#define LV_EVE_DL_TAG_MASK ((uint32_t) 0x14000000UL) +#define LV_EVE_DL_BITMAP_TRANSFORM_A ((uint32_t) 0x15000000UL) +#define LV_EVE_DL_BITMAP_TRANSFORM_B ((uint32_t) 0x16000000UL) +#define LV_EVE_DL_BITMAP_TRANSFORM_C ((uint32_t) 0x17000000UL) +#define LV_EVE_DL_BITMAP_TRANSFORM_D ((uint32_t) 0x18000000UL) +#define LV_EVE_DL_BITMAP_TRANSFORM_E ((uint32_t) 0x19000000UL) +#define LV_EVE_DL_BITMAP_TRANSFORM_F ((uint32_t) 0x1A000000UL) +#define LV_EVE_DL_SCISSOR_XY ((uint32_t) 0x1B000000UL) +#define LV_EVE_DL_SCISSOR_SIZE ((uint32_t) 0x1C000000UL) +#define LV_EVE_DL_CALL ((uint32_t) 0x1D000000UL) +#define LV_EVE_DL_JUMP ((uint32_t) 0x1E000000UL) +#define LV_EVE_DL_BEGIN ((uint32_t) 0x1F000000UL) +#define LV_EVE_DL_COLOR_MASK ((uint32_t) 0x20000000UL) +#define LV_EVE_DL_END ((uint32_t) 0x21000000UL) +#define LV_EVE_DL_SAVE_CONTEXT ((uint32_t) 0x22000000UL) +#define LV_EVE_DL_RESTORE_CONTEXT ((uint32_t) 0x23000000UL) +#define LV_EVE_DL_RETURN ((uint32_t) 0x24000000UL) +#define LV_EVE_DL_MACRO ((uint32_t) 0x25000000UL) +#define LV_EVE_DL_CLEAR ((uint32_t) 0x26000000UL) +#define LV_EVE_DL_VERTEX_FORMAT ((uint32_t) 0x27000000UL) +#define LV_EVE_DL_BITMAP_LAYOUT_H ((uint32_t) 0x28000000UL) +#define LV_EVE_DL_BITMAP_SIZE_H ((uint32_t) 0x29000000UL) +#define LV_EVE_DL_PALETTE_SOURCE ((uint32_t) 0x2A000000UL) +#define LV_EVE_DL_VERTEX_TRANSLATE_X ((uint32_t) 0x2B000000UL) +#define LV_EVE_DL_VERTEX_TRANSLATE_Y ((uint32_t) 0x2C000000UL) +#define LV_EVE_DL_NOP ((uint32_t) 0x2D000000UL) + +#define LV_EVE_DL_VERTEX2F ((uint32_t) 0x40000000UL) +#define LV_EVE_DL_VERTEX2II ((uint32_t) 0x80000000UL) + +#define LV_EVE_CLR_COL ((uint8_t) 0x4U) +#define LV_EVE_CLR_STN ((uint8_t) 0x2U) +#define LV_EVE_CLR_TAG ((uint8_t) 0x1U) + +/* Host commands */ +#define LV_EVE_EVE_ACTIVE ((uint8_t) 0x00U) /* place EVE in active state */ +#define LV_EVE_EVE_STANDBY ((uint8_t) 0x41U) /* place EVE in Standby (clk running) */ +#define LV_EVE_EVE_SLEEP ((uint8_t) 0x42U) /* place EVE in Sleep (clk off) */ +#define LV_EVE_EVE_CLKEXT ((uint8_t) 0x44U) /* select external clock source */ +#define LV_EVE_EVE_CLKINT ((uint8_t) 0x48U) /* select internal clock source, not a valid option for BT817 / BT818 */ +#define LV_EVE_EVE_PWRDOWN ((uint8_t) 0x50U) /* place EVE in Power Down (core off) */ +#define LV_EVE_EVE_CLKSEL ((uint8_t) 0x61U) /* configure system clock */ +#define LV_EVE_EVE_RST_PULSE ((uint8_t) 0x68U) /* reset core - all registers default and processors reset */ +#define LV_EVE_EVE_CORERST ((uint8_t) 0x68U) /* reset core - all registers default and processors reset */ +#define LV_EVE_EVE_PINDRIVE ((uint8_t) 0x70U) /* setup drive strength for various pins */ +#define LV_EVE_EVE_PIN_PD_STATE ((uint8_t) 0x71U) /* setup how pins behave during power down */ + +/* Graphic command defines */ +#define LV_EVE_EVE_NEVER ((uint8_t) 0UL) +#define LV_EVE_EVE_LESS ((uint8_t) 1UL) +#define LV_EVE_EVE_LEQUAL ((uint8_t) 2UL) +#define LV_EVE_EVE_GREATER ((uint8_t) 3UL) +#define LV_EVE_EVE_GEQUAL ((uint8_t) 4UL) +#define LV_EVE_EVE_EQUAL ((uint8_t) 5UL) +#define LV_EVE_EVE_NOTEQUAL ((uint8_t) 6UL) +#define LV_EVE_EVE_ALWAYS ((uint8_t) 7UL) + +/* Bitmap formats */ +#define LV_EVE_EVE_ARGB1555 ((uint8_t) 0UL) +#define LV_EVE_EVE_L1 ((uint8_t) 1UL) +#define LV_EVE_EVE_L4 ((uint8_t) 2UL) +#define LV_EVE_EVE_L8 ((uint8_t) 3UL) +#define LV_EVE_EVE_RGB332 ((uint8_t) 4UL) +#define LV_EVE_EVE_ARGB2 ((uint8_t) 5UL) +#define LV_EVE_EVE_ARGB4 ((uint8_t) 6UL) +#define LV_EVE_EVE_RGB565 ((uint8_t) 7UL) +#define LV_EVE_EVE_PALETTED ((uint8_t) 8UL) +#define LV_EVE_EVE_TEXT8X8 ((uint8_t) 9UL) +#define LV_EVE_EVE_TEXTVGA ((uint8_t) 10UL) +#define LV_EVE_EVE_BARGRAPH ((uint8_t) 11UL) + +/* Bitmap filter types */ +#define LV_EVE_EVE_NEAREST ((uint8_t) 0UL) +#define LV_EVE_EVE_BILINEAR ((uint8_t) 1UL) + +/* Bitmap wrap types */ +#define LV_EVE_EVE_BORDER ((uint8_t) 0UL) +#define LV_EVE_EVE_REPEAT ((uint8_t) 1UL) + +/* Stencil defines */ +#define LV_EVE_EVE_KEEP ((uint8_t) 1UL) +#define LV_EVE_EVE_REPLACE ((uint8_t) 2UL) +#define LV_EVE_EVE_INCR ((uint8_t) 3UL) +#define LV_EVE_EVE_DECR ((uint8_t) 4UL) +#define LV_EVE_EVE_INVERT ((uint8_t) 5UL) + +/* Graphics display list swap defines */ +#define LV_EVE_EVE_DLSWAP_DONE ((uint8_t) 0UL) +#define LV_EVE_EVE_DLSWAP_LINE ((uint8_t) 1UL) +#define LV_EVE_EVE_DLSWAP_FRAME ((uint8_t) 2UL) + +/* Interrupt bits */ +#define LV_EVE_EVE_INT_SWAP ((uint8_t) 0x01) +#define LV_EVE_EVE_INT_TOUCH ((uint8_t) 0x02) +#define LV_EVE_EVE_INT_TAG ((uint8_t) 0x04) +#define LV_EVE_EVE_INT_SOUND ((uint8_t) 0x08) +#define LV_EVE_EVE_INT_PLAYBACK ((uint8_t) 0x10) +#define LV_EVE_EVE_INT_CMDEMPTY ((uint8_t) 0x20) +#define LV_EVE_EVE_INT_CMDFLAG ((uint8_t) 0x40) +#define LV_EVE_EVE_INT_CONVCOMPLETE ((uint8_t) 0x80) + +/* Touch mode */ +#define LV_EVE_EVE_TMODE_OFF ((uint8_t) 0U) +#define LV_EVE_EVE_TMODE_ONESHOT ((uint8_t) 1U) +#define LV_EVE_EVE_TMODE_FRAME ((uint8_t) 2U) +#define LV_EVE_EVE_TMODE_CONTINUOUS ((uint8_t) 3U) + +/* Alpha blending */ +#define LV_EVE_EVE_ZERO ((uint32_t) 0UL) +#define LV_EVE_EVE_ONE ((uint32_t) 1UL) +#define LV_EVE_EVE_SRC_ALPHA ((uint32_t) 2UL) +#define LV_EVE_EVE_DST_ALPHA ((uint32_t) 3UL) +#define LV_EVE_EVE_ONE_MINUS_SRC_ALPHA ((uint32_t) 4UL) +#define LV_EVE_EVE_ONE_MINUS_DST_ALPHA ((uint32_t) 5UL) + +/* Graphics primitives */ +#define LV_EVE_EVE_BITMAPS ((uint32_t) 1UL) +#define LV_EVE_EVE_POINTS ((uint32_t) 2UL) +#define LV_EVE_EVE_LINES ((uint32_t) 3UL) +#define LV_EVE_EVE_LINE_STRIP ((uint32_t) 4UL) +#define LV_EVE_EVE_EDGE_STRIP_R ((uint32_t) 5UL) +#define LV_EVE_EVE_EDGE_STRIP_L ((uint32_t) 6UL) +#define LV_EVE_EVE_EDGE_STRIP_A ((uint32_t) 7UL) +#define LV_EVE_EVE_EDGE_STRIP_B ((uint32_t) 8UL) +#define LV_EVE_EVE_RECTS ((uint32_t) 9UL) +#define LV_EVE_EVE_INT_G8 ((uint32_t) 18UL) +#define LV_EVE_EVE_INT_L8C ((uint32_t) 12UL) +#define LV_EVE_EVE_INT_VGA ((uint32_t) 13UL) +#define LV_EVE_EVE_PALETTED565 ((uint32_t) 14UL) +#define LV_EVE_EVE_PALETTED4444 ((uint32_t) 15UL) +#define LV_EVE_EVE_PALETTED8 ((uint32_t) 16UL) +#define LV_EVE_EVE_L2 ((uint32_t) 17UL) + +/* Widget command options */ +#define LV_EVE_EVE_OPT_MONO ((uint16_t) 1U) +#define LV_EVE_EVE_OPT_NODL ((uint16_t) 2U) +#define LV_EVE_EVE_OPT_FLAT ((uint16_t) 256U) +#define LV_EVE_EVE_OPT_CENTERX ((uint16_t) 512U) +#define LV_EVE_EVE_OPT_CENTERY ((uint16_t) 1024U) +#define LV_EVE_EVE_OPT_CENTER (LV_EVE_EVE_OPT_CENTERX | LV_EVE_EVE_OPT_CENTERY) +#define LV_EVE_EVE_OPT_NOBACK ((uint16_t) 4096U) +#define LV_EVE_EVE_OPT_NOTICKS ((uint16_t) 8192U) +#define LV_EVE_EVE_OPT_NOHM ((uint16_t) 16384U) +#define LV_EVE_EVE_OPT_NOPOINTER ((uint16_t) 16384U) +#define LV_EVE_EVE_OPT_NOSECS ((uint16_t) 32768U) +#define LV_EVE_EVE_OPT_NOHANDS ((uint16_t) 49152U) +#define LV_EVE_EVE_OPT_RIGHTX ((uint16_t) 2048U) +#define LV_EVE_EVE_OPT_SIGNED ((uint16_t) 256U) + +#define LV_EVE_EVE_OPT_MEDIAFIFO ((uint16_t) 16U) +#define LV_EVE_EVE_OPT_FULLSCREEN ((uint16_t) 8U) +#define LV_EVE_EVE_OPT_NOTEAR ((uint16_t) 4U) +#define LV_EVE_EVE_OPT_SOUND ((uint16_t) 32U) + +/* ADC */ +#define LV_EVE_EVE_ADC_DIFFERENTIAL ((uint32_t) 1UL) +#define LV_EVE_EVE_ADC_SINGLE_ENDED ((uint32_t) 0UL) + +/* Fonts */ +#define LV_EVE_EVE_NUMCHAR_PERFONT ((uint32_t) 128UL) /* number of font characters per bitmap handle */ +#define LV_EVE_EVE_FONT_TABLE_SIZE ((uint32_t) 148UL) /* size of the font table - utilized for loopup by the graphics engine */ +#define LV_EVE_EVE_FONT_TABLE_POINTER ((uint32_t) 0xFFFFCUL) /* pointer to the inbuilt font tables starting from bitmap handle 16 */ + +/* Audio sample type defines */ +#define LV_EVE_EVE_LINEAR_SAMPLES ((uint32_t) 0UL) /* 8bit signed samples */ +#define LV_EVE_EVE_ULAW_SAMPLES ((uint32_t) 1UL) /* 8bit ulaw samples */ +#define LV_EVE_EVE_ADPCM_SAMPLES ((uint32_t) 2UL) /* 4bit ima adpcm samples */ + +/* Synthesized sound */ +#define LV_EVE_EVE_SILENCE ((uint8_t) 0x00U) +#define LV_EVE_EVE_SQUAREWAVE ((uint8_t) 0x01U) +#define LV_EVE_EVE_SINEWAVE ((uint8_t) 0x02U) +#define LV_EVE_EVE_SAWTOOTH ((uint8_t) 0x03U) +#define LV_EVE_EVE_TRIANGLE ((uint8_t) 0x04U) +#define LV_EVE_EVE_BEEPING ((uint8_t) 0x05U) +#define LV_EVE_EVE_ALARM ((uint8_t) 0x06U) +#define LV_EVE_EVE_WARBLE ((uint8_t) 0x07U) +#define LV_EVE_EVE_CAROUSEL ((uint8_t) 0x08U) +#define LV_EVE_EVE_PIPS(n) ((uint8_t) (0x0FU + (n))) +#define LV_EVE_EVE_HARP ((uint8_t) 0x40U) +#define LV_EVE_EVE_XYLOPHONE ((uint8_t) 0x41U) +#define LV_EVE_EVE_TUBA ((uint8_t) 0x42U) +#define LV_EVE_EVE_GLOCKENSPIEL ((uint8_t) 0x43U) +#define LV_EVE_EVE_ORGAN ((uint8_t) 0x44U) +#define LV_EVE_EVE_TRUMPET ((uint8_t) 0x45U) +#define LV_EVE_EVE_PIANO ((uint8_t) 0x46U) +#define LV_EVE_EVE_CHIMES ((uint8_t) 0x47U) +#define LV_EVE_EVE_MUSICBOX ((uint8_t) 0x48U) +#define LV_EVE_EVE_BELL ((uint8_t) 0x49U) +#define LV_EVE_EVE_CLICK ((uint8_t) 0x50U) +#define LV_EVE_EVE_SWITCH ((uint8_t) 0x51U) +#define LV_EVE_EVE_COWBELL ((uint8_t) 0x52U) +#define LV_EVE_EVE_NOTCH ((uint8_t) 0x53U) +#define LV_EVE_EVE_HIHAT ((uint8_t) 0x54U) +#define LV_EVE_EVE_KICKDRUM ((uint8_t) 0x55U) +#define LV_EVE_EVE_POP ((uint8_t) 0x56U) +#define LV_EVE_EVE_CLACK ((uint8_t) 0x57U) +#define LV_EVE_EVE_CHACK ((uint8_t) 0x58U) +#define LV_EVE_EVE_MUTE ((uint8_t) 0x60U) +#define LV_EVE_EVE_UNMUTE ((uint8_t) 0x61U) + +/* Synthesized sound frequencies, midi note */ +#define LV_EVE_EVE_MIDI_A0 ((uint8_t) 21U) +#define LV_EVE_EVE_MIDI_A_0 ((uint8_t) 22U) +#define LV_EVE_EVE_MIDI_B0 ((uint8_t) 23U) +#define LV_EVE_EVE_MIDI_C1 ((uint8_t) 24U) +#define LV_EVE_EVE_MIDI_C_1 ((uint8_t) 25U) +#define LV_EVE_EVE_MIDI_D1 ((uint8_t) 26U) +#define LV_EVE_EVE_MIDI_D_1 ((uint8_t) 27U) +#define LV_EVE_EVE_MIDI_E1 ((uint8_t) 28U) +#define LV_EVE_EVE_MIDI_F1 ((uint8_t) 29U) +#define LV_EVE_EVE_MIDI_F_1 ((uint8_t) 30U) +#define LV_EVE_EVE_MIDI_G1 ((uint8_t) 31U) +#define LV_EVE_EVE_MIDI_G_1 ((uint8_t) 32U) +#define LV_EVE_EVE_MIDI_A1 ((uint8_t) 33U) +#define LV_EVE_EVE_MIDI_A_1 ((uint8_t) 34U) +#define LV_EVE_EVE_MIDI_B1 ((uint8_t) 35U) +#define LV_EVE_EVE_MIDI_C2 ((uint8_t) 36U) +#define LV_EVE_EVE_MIDI_C_2 ((uint8_t) 37U) +#define LV_EVE_EVE_MIDI_D2 ((uint8_t) 38U) +#define LV_EVE_EVE_MIDI_D_2 ((uint8_t) 39U) +#define LV_EVE_EVE_MIDI_E2 ((uint8_t) 40U) +#define LV_EVE_EVE_MIDI_F2 ((uint8_t) 41U) +#define LV_EVE_EVE_MIDI_F_2 ((uint8_t) 42U) +#define LV_EVE_EVE_MIDI_G2 ((uint8_t) 43U) +#define LV_EVE_EVE_MIDI_G_2 ((uint8_t) 44U) +#define LV_EVE_EVE_MIDI_A2 ((uint8_t) 45U) +#define LV_EVE_EVE_MIDI_A_2 ((uint8_t) 46U) +#define LV_EVE_EVE_MIDI_B2 ((uint8_t) 47U) +#define LV_EVE_EVE_MIDI_C3 ((uint8_t) 48U) +#define LV_EVE_EVE_MIDI_C_3 ((uint8_t) 49U) +#define LV_EVE_EVE_MIDI_D3 ((uint8_t) 50U) +#define LV_EVE_EVE_MIDI_D_3 ((uint8_t) 51U) +#define LV_EVE_EVE_MIDI_E3 ((uint8_t) 52U) +#define LV_EVE_EVE_MIDI_F3 ((uint8_t) 53U) +#define LV_EVE_EVE_MIDI_F_3 ((uint8_t) 54U) +#define LV_EVE_EVE_MIDI_G3 ((uint8_t) 55U) +#define LV_EVE_EVE_MIDI_G_3 ((uint8_t) 56U) +#define LV_EVE_EVE_MIDI_A3 ((uint8_t) 57U) +#define LV_EVE_EVE_MIDI_A_3 ((uint8_t) 58U) +#define LV_EVE_EVE_MIDI_B3 ((uint8_t) 59U) +#define LV_EVE_EVE_MIDI_C4 ((uint8_t) 60U) +#define LV_EVE_EVE_MIDI_C_4 ((uint8_t) 61U) +#define LV_EVE_EVE_MIDI_D4 ((uint8_t) 62U) +#define LV_EVE_EVE_MIDI_D_4 ((uint8_t) 63U) +#define LV_EVE_EVE_MIDI_E4 ((uint8_t) 64U) +#define LV_EVE_EVE_MIDI_F4 ((uint8_t) 65U) +#define LV_EVE_EVE_MIDI_F_4 ((uint8_t) 66U) +#define LV_EVE_EVE_MIDI_G4 ((uint8_t) 67U) +#define LV_EVE_EVE_MIDI_G_4 ((uint8_t) 68U) +#define LV_EVE_EVE_MIDI_A4 ((uint8_t) 69U) +#define LV_EVE_EVE_MIDI_A_4 ((uint8_t) 70U) +#define LV_EVE_EVE_MIDI_B4 ((uint8_t) 71U) +#define LV_EVE_EVE_MIDI_C5 ((uint8_t) 72U) +#define LV_EVE_EVE_MIDI_C_5 ((uint8_t) 73U) +#define LV_EVE_EVE_MIDI_D5 ((uint8_t) 74U) +#define LV_EVE_EVE_MIDI_D_5 ((uint8_t) 75U) +#define LV_EVE_EVE_MIDI_E5 ((uint8_t) 76U) +#define LV_EVE_EVE_MIDI_F5 ((uint8_t) 77U) +#define LV_EVE_EVE_MIDI_F_5 ((uint8_t) 78U) +#define LV_EVE_EVE_MIDI_G5 ((uint8_t) 79U) +#define LV_EVE_EVE_MIDI_G_5 ((uint8_t) 80U) +#define LV_EVE_EVE_MIDI_A5 ((uint8_t) 81U) +#define LV_EVE_EVE_MIDI_A_5 ((uint8_t) 82U) +#define LV_EVE_EVE_MIDI_B5 ((uint8_t) 83U) +#define LV_EVE_EVE_MIDI_C6 ((uint8_t) 84U) +#define LV_EVE_EVE_MIDI_C_6 ((uint8_t) 85U) +#define LV_EVE_EVE_MIDI_D6 ((uint8_t) 86U) +#define LV_EVE_EVE_MIDI_D_6 ((uint8_t) 87U) +#define LV_EVE_EVE_MIDI_E6 ((uint8_t) 88U) +#define LV_EVE_EVE_MIDI_F6 ((uint8_t) 89U) +#define LV_EVE_EVE_MIDI_F_6 ((uint8_t) 90U) +#define LV_EVE_EVE_MIDI_G6 ((uint8_t) 91U) +#define LV_EVE_EVE_MIDI_G_6 ((uint8_t) 92U) +#define LV_EVE_EVE_MIDI_A6 ((uint8_t) 93U) +#define LV_EVE_EVE_MIDI_A_6 ((uint8_t) 94U) +#define LV_EVE_EVE_MIDI_B6 ((uint8_t) 95U) +#define LV_EVE_EVE_MIDI_C7 ((uint8_t) 96U) +#define LV_EVE_EVE_MIDI_C_7 ((uint8_t) 97U) +#define LV_EVE_EVE_MIDI_D7 ((uint8_t) 98U) +#define LV_EVE_EVE_MIDI_D_7 ((uint8_t) 99U) +#define LV_EVE_EVE_MIDI_E7 ((uint8_t) 100U) +#define LV_EVE_EVE_MIDI_F7 ((uint8_t) 101U) +#define LV_EVE_EVE_MIDI_F_7 ((uint8_t) 102U) +#define LV_EVE_EVE_MIDI_G7 ((uint8_t) 103U) +#define LV_EVE_EVE_MIDI_G_7 ((uint8_t) 104U) +#define LV_EVE_EVE_MIDI_A7 ((uint8_t) 105U) +#define LV_EVE_EVE_MIDI_A_7 ((uint8_t) 106U) +#define LV_EVE_EVE_MIDI_B7 ((uint8_t) 107U) +#define LV_EVE_EVE_MIDI_C8 ((uint8_t) 108U) + +/* GPIO bits */ +#define LV_EVE_EVE_GPIO0 ((uint8_t) 0U) +#define LV_EVE_EVE_GPIO1 ((uint8_t) 1U) /* default gpio pin for audio shutdown, 1 - enable, 0 - disable */ +#define LV_EVE_EVE_GPIO7 ((uint8_t) 7U) /* default gpio pin for display enable, 1 - enable, 0 - disable */ + +/* Display rotation */ +#define LV_EVE_EVE_DISPLAY_0 ((uint8_t) 0U) /* 0 degrees rotation */ +#define LV_EVE_EVE_DISPLAY_180 ((uint8_t) 1U) /* 180 degrees rotation */ + +/* Commands */ +#define LV_EVE_CMD_APPEND ((uint32_t) 0xFFFFFF1EUL) +#define LV_EVE_CMD_BGCOLOR ((uint32_t) 0xFFFFFF09UL) +#define LV_EVE_CMD_BUTTON ((uint32_t) 0xFFFFFF0DUL) +#define LV_EVE_CMD_CALIBRATE ((uint32_t) 0xFFFFFF15UL) +#define LV_EVE_CMD_CLOCK ((uint32_t) 0xFFFFFF14UL) +#define LV_EVE_CMD_COLDSTART ((uint32_t) 0xFFFFFF32UL) +#define LV_EVE_CMD_DIAL ((uint32_t) 0xFFFFFF2DUL) +#define LV_EVE_CMD_DLSTART ((uint32_t) 0xFFFFFF00UL) +#define LV_EVE_CMD_FGCOLOR ((uint32_t) 0xFFFFFF0AUL) +#define LV_EVE_CMD_GAUGE ((uint32_t) 0xFFFFFF13UL) +#define LV_EVE_CMD_GETMATRIX ((uint32_t) 0xFFFFFF33UL) +#define LV_EVE_CMD_GETPROPS ((uint32_t) 0xFFFFFF25UL) +#define LV_EVE_CMD_GETPTR ((uint32_t) 0xFFFFFF23UL) +#define LV_EVE_CMD_GRADCOLOR ((uint32_t) 0xFFFFFF34UL) +#define LV_EVE_CMD_GRADIENT ((uint32_t) 0xFFFFFF0BUL) +#define LV_EVE_CMD_INFLATE ((uint32_t) 0xFFFFFF22UL) +#define LV_EVE_CMD_INTERRUPT ((uint32_t) 0xFFFFFF02UL) +#define LV_EVE_CMD_KEYS ((uint32_t) 0xFFFFFF0EUL) +#define LV_EVE_CMD_LOADIDENTITY ((uint32_t) 0xFFFFFF26UL) +#define LV_EVE_CMD_LOADIMAGE ((uint32_t) 0xFFFFFF24UL) +#define LV_EVE_CMD_LOGO ((uint32_t) 0xFFFFFF31UL) +#define LV_EVE_CMD_MEDIAFIFO ((uint32_t) 0xFFFFFF39UL) +#define LV_EVE_CMD_MEMCPY ((uint32_t) 0xFFFFFF1DUL) +#define LV_EVE_CMD_MEMCRC ((uint32_t) 0xFFFFFF18UL) +#define LV_EVE_CMD_MEMSET ((uint32_t) 0xFFFFFF1BUL) +#define LV_EVE_CMD_MEMWRITE ((uint32_t) 0xFFFFFF1AUL) +#define LV_EVE_CMD_MEMZERO ((uint32_t) 0xFFFFFF1CUL) +#define LV_EVE_CMD_NUMBER ((uint32_t) 0xFFFFFF2EUL) +#define LV_EVE_CMD_PLAYVIDEO ((uint32_t) 0xFFFFFF3AUL) +#define LV_EVE_CMD_PROGRESS ((uint32_t) 0xFFFFFF0FUL) +#define LV_EVE_CMD_REGREAD ((uint32_t) 0xFFFFFF19UL) +#define LV_EVE_CMD_ROMFONT ((uint32_t) 0xFFFFFF3FUL) +#define LV_EVE_CMD_ROTATE ((uint32_t) 0xFFFFFF29UL) +#define LV_EVE_CMD_SCALE ((uint32_t) 0xFFFFFF28UL) +#define LV_EVE_CMD_SCREENSAVER ((uint32_t) 0xFFFFFF2FUL) +#define LV_EVE_CMD_SCROLLBAR ((uint32_t) 0xFFFFFF11UL) +#define LV_EVE_CMD_SETBASE ((uint32_t) 0xFFFFFF38UL) +#define LV_EVE_CMD_SETBITMAP ((uint32_t) 0xFFFFFF43UL) +#define LV_EVE_CMD_SETFONT ((uint32_t) 0xFFFFFF2BUL) +#define LV_EVE_CMD_SETFONT2 ((uint32_t) 0xFFFFFF3BUL) +#define LV_EVE_CMD_SETMATRIX ((uint32_t) 0xFFFFFF2AUL) +#define LV_EVE_CMD_SETROTATE ((uint32_t) 0xFFFFFF36UL) +#define LV_EVE_CMD_SETSCRATCH ((uint32_t) 0xFFFFFF3CUL) +#define LV_EVE_CMD_SKETCH ((uint32_t) 0xFFFFFF30UL) +#define LV_EVE_CMD_SLIDER ((uint32_t) 0xFFFFFF10UL) +#define LV_EVE_CMD_SNAPSHOT ((uint32_t) 0xFFFFFF1FUL) +#define LV_EVE_CMD_SNAPSHOT2 ((uint32_t) 0xFFFFFF37UL) +#define LV_EVE_CMD_SPINNER ((uint32_t) 0xFFFFFF16UL) +#define LV_EVE_CMD_STOP ((uint32_t) 0xFFFFFF17UL) +#define LV_EVE_CMD_SWAP ((uint32_t) 0xFFFFFF01UL) +#define LV_EVE_CMD_TEXT ((uint32_t) 0xFFFFFF0CUL) +#define LV_EVE_CMD_TOGGLE ((uint32_t) 0xFFFFFF12UL) +#define LV_EVE_CMD_TRACK ((uint32_t) 0xFFFFFF2CUL) +#define LV_EVE_CMD_TRANSLATE ((uint32_t) 0xFFFFFF27UL) +#define LV_EVE_CMD_VIDEOFRAME ((uint32_t) 0xFFFFFF41UL) +#define LV_EVE_CMD_VIDEOSTART ((uint32_t) 0xFFFFFF40UL) + +/* Registers */ +#define LV_EVE_REG_ANA_COMP ((uint32_t) 0x00302184UL) /* only listed in datasheet */ +#define LV_EVE_REG_BIST_EN ((uint32_t) 0x00302174UL) /* only listed in datasheet */ +#define LV_EVE_REG_CLOCK ((uint32_t) 0x00302008UL) +#define LV_EVE_REG_CMDB_SPACE ((uint32_t) 0x00302574UL) +#define LV_EVE_REG_CMDB_WRITE ((uint32_t) 0x00302578UL) +#define LV_EVE_REG_CMD_DL ((uint32_t) 0x00302100UL) +#define LV_EVE_REG_CMD_READ ((uint32_t) 0x003020f8UL) +#define LV_EVE_REG_CMD_WRITE ((uint32_t) 0x003020fcUL) +#define LV_EVE_REG_CPURESET ((uint32_t) 0x00302020UL) +#define LV_EVE_REG_CSPREAD ((uint32_t) 0x00302068UL) +#define LV_EVE_REG_CTOUCH_EXTENDED ((uint32_t) 0x00302108UL) +#define LV_EVE_REG_CTOUCH_TOUCH0_XY ((uint32_t) 0x00302124UL) /* only listed in datasheet */ +#define LV_EVE_REG_CTOUCH_TOUCH4_X ((uint32_t) 0x0030216cUL) +#define LV_EVE_REG_CTOUCH_TOUCH4_Y ((uint32_t) 0x00302120UL) +#define LV_EVE_REG_CTOUCH_TOUCH1_XY ((uint32_t) 0x0030211cUL) +#define LV_EVE_REG_CTOUCH_TOUCH2_XY ((uint32_t) 0x0030218cUL) +#define LV_EVE_REG_CTOUCH_TOUCH3_XY ((uint32_t) 0x00302190UL) +#define LV_EVE_REG_TOUCH_CONFIG ((uint32_t) 0x00302168UL) +#define LV_EVE_REG_DATESTAMP ((uint32_t) 0x00302564UL) /* only listed in datasheet */ +#define LV_EVE_REG_DITHER ((uint32_t) 0x00302060UL) +#define LV_EVE_REG_DLSWAP ((uint32_t) 0x00302054UL) +#define LV_EVE_REG_FRAMES ((uint32_t) 0x00302004UL) +#define LV_EVE_REG_FREQUENCY ((uint32_t) 0x0030200cUL) +#define LV_EVE_REG_GPIO ((uint32_t) 0x00302094UL) +#define LV_EVE_REG_GPIOX ((uint32_t) 0x0030209cUL) +#define LV_EVE_REG_GPIOX_DIR ((uint32_t) 0x00302098UL) +#define LV_EVE_REG_GPIO_DIR ((uint32_t) 0x00302090UL) +#define LV_EVE_REG_HCYCLE ((uint32_t) 0x0030202cUL) +#define LV_EVE_REG_HOFFSET ((uint32_t) 0x00302030UL) +#define LV_EVE_REG_HSIZE ((uint32_t) 0x00302034UL) +#define LV_EVE_REG_HSYNC0 ((uint32_t) 0x00302038UL) +#define LV_EVE_REG_HSYNC1 ((uint32_t) 0x0030203cUL) +#define LV_EVE_REG_ID ((uint32_t) 0x00302000UL) +#define LV_EVE_REG_INT_EN ((uint32_t) 0x003020acUL) +#define LV_EVE_REG_INT_FLAGS ((uint32_t) 0x003020a8UL) +#define LV_EVE_REG_INT_MASK ((uint32_t) 0x003020b0UL) +#define LV_EVE_REG_MACRO_0 ((uint32_t) 0x003020d8UL) +#define LV_EVE_REG_MACRO_1 ((uint32_t) 0x003020dcUL) +#define LV_EVE_REG_MEDIAFIFO_READ ((uint32_t) 0x00309014UL) /* only listed in programmers guide */ +#define LV_EVE_REG_MEDIAFIFO_WRITE ((uint32_t) 0x00309018UL) /* only listed in programmers guide */ +#define LV_EVE_REG_OUTBITS ((uint32_t) 0x0030205cUL) +#define LV_EVE_REG_PCLK ((uint32_t) 0x00302070UL) +#define LV_EVE_REG_PCLK_POL ((uint32_t) 0x0030206cUL) +#define LV_EVE_REG_PLAY ((uint32_t) 0x0030208cUL) +#define LV_EVE_REG_PLAYBACK_FORMAT ((uint32_t) 0x003020c4UL) +#define LV_EVE_REG_PLAYBACK_FREQ ((uint32_t) 0x003020c0UL) +#define LV_EVE_REG_PLAYBACK_LENGTH ((uint32_t) 0x003020b8UL) +#define LV_EVE_REG_PLAYBACK_LOOP ((uint32_t) 0x003020c8UL) +#define LV_EVE_REG_PLAYBACK_PLAY ((uint32_t) 0x003020ccUL) +#define LV_EVE_REG_PLAYBACK_READPTR ((uint32_t) 0x003020bcUL) +#define LV_EVE_REG_PLAYBACK_START ((uint32_t) 0x003020b4UL) +#define LV_EVE_REG_PWM_DUTY ((uint32_t) 0x003020d4UL) +#define LV_EVE_REG_PWM_HZ ((uint32_t) 0x003020d0UL) +#define LV_EVE_REG_RENDERMODE ((uint32_t) 0x00302010UL) /* only listed in datasheet */ +#define LV_EVE_REG_ROTATE ((uint32_t) 0x00302058UL) +#define LV_EVE_REG_SNAPFORMAT ((uint32_t) 0x0030201cUL) /* only listed in datasheet */ +#define LV_EVE_REG_SNAPSHOT ((uint32_t) 0x00302018UL) /* only listed in datasheet */ +#define LV_EVE_REG_SNAPY ((uint32_t) 0x00302014UL) /* only listed in datasheet */ +#define LV_EVE_REG_SOUND ((uint32_t) 0x00302088UL) +#define LV_EVE_REG_SPI_WIDTH ((uint32_t) 0x00302188UL) /* listed with false offset in programmers guide V1.1 */ +#define LV_EVE_REG_SWIZZLE ((uint32_t) 0x00302064UL) +#define LV_EVE_REG_TAG ((uint32_t) 0x0030207cUL) +#define LV_EVE_REG_TAG_X ((uint32_t) 0x00302074UL) +#define LV_EVE_REG_TAG_Y ((uint32_t) 0x00302078UL) +#define LV_EVE_REG_TAP_CRC ((uint32_t) 0x00302024UL) /* only listed in datasheet */ +#define LV_EVE_REG_TAP_MASK ((uint32_t) 0x00302028UL) /* only listed in datasheet */ +#define LV_EVE_REG_TOUCH_ADC_MODE ((uint32_t) 0x00302108UL) +#define LV_EVE_REG_TOUCH_CHARGE ((uint32_t) 0x0030210cUL) +#define LV_EVE_REG_TOUCH_DIRECT_XY ((uint32_t) 0x0030218cUL) +#define LV_EVE_REG_TOUCH_DIRECT_Z1Z2 ((uint32_t) 0x00302190UL) +#define LV_EVE_REG_TOUCH_MODE ((uint32_t) 0x00302104UL) +#define LV_EVE_REG_TOUCH_OVERSAMPLE ((uint32_t) 0x00302114UL) +#define LV_EVE_REG_TOUCH_RAW_XY ((uint32_t) 0x0030211cUL) +#define LV_EVE_REG_TOUCH_RZ ((uint32_t) 0x00302120UL) +#define LV_EVE_REG_TOUCH_RZTHRESH ((uint32_t) 0x00302118UL) +#define LV_EVE_REG_TOUCH_SCREEN_XY ((uint32_t) 0x00302124UL) +#define LV_EVE_REG_TOUCH_SETTLE ((uint32_t) 0x00302110UL) +#define LV_EVE_REG_TOUCH_TAG ((uint32_t) 0x0030212cUL) +#define LV_EVE_REG_TOUCH_TAG1 ((uint32_t) 0x00302134UL) /* only listed in datasheet */ +#define LV_EVE_REG_TOUCH_TAG1_XY ((uint32_t) 0x00302130UL) /* only listed in datasheet */ +#define LV_EVE_REG_TOUCH_TAG2 ((uint32_t) 0x0030213cUL) /* only listed in datasheet */ +#define LV_EVE_REG_TOUCH_TAG2_XY ((uint32_t) 0x00302138UL) /* only listed in datasheet */ +#define LV_EVE_REG_TOUCH_TAG3 ((uint32_t) 0x00302144UL) /* only listed in datasheet */ +#define LV_EVE_REG_TOUCH_TAG3_XY ((uint32_t) 0x00302140UL) /* only listed in datasheet */ +#define LV_EVE_REG_TOUCH_TAG4 ((uint32_t) 0x0030214cUL)/* only listed in datasheet */ +#define LV_EVE_REG_TOUCH_TAG4_XY ((uint32_t) 0x00302148UL) /* only listed in datasheet */ +#define LV_EVE_REG_TOUCH_TAG_XY ((uint32_t) 0x00302128UL) +#define LV_EVE_REG_TOUCH_TRANSFORM_A ((uint32_t) 0x00302150UL) +#define LV_EVE_REG_TOUCH_TRANSFORM_B ((uint32_t) 0x00302154UL) +#define LV_EVE_REG_TOUCH_TRANSFORM_C ((uint32_t) 0x00302158UL) +#define LV_EVE_REG_TOUCH_TRANSFORM_D ((uint32_t) 0x0030215cUL) +#define LV_EVE_REG_TOUCH_TRANSFORM_E ((uint32_t) 0x00302160UL) +#define LV_EVE_REG_TOUCH_TRANSFORM_F ((uint32_t) 0x00302164UL) +#define LV_EVE_REG_TRACKER ((uint32_t) 0x00309000UL) /* only listed in programmers guide */ +#define LV_EVE_REG_TRACKER_1 ((uint32_t) 0x00309004UL) /* only listed in programmers guide */ +#define LV_EVE_REG_TRACKER_2 ((uint32_t) 0x00309008UL) /* only listed in programmers guide */ +#define LV_EVE_REG_TRACKER_3 ((uint32_t) 0x0030900cUL) /* only listed in programmers guide */ +#define LV_EVE_REG_TRACKER_4 ((uint32_t) 0x00309010UL) /* only listed in programmers guide */ +#define LV_EVE_REG_TRIM ((uint32_t) 0x00302180UL) +#define LV_EVE_REG_VCYCLE ((uint32_t) 0x00302040UL) +#define LV_EVE_REG_VOFFSET ((uint32_t) 0x00302044UL) +#define LV_EVE_REG_VOL_PB ((uint32_t) 0x00302080UL) +#define LV_EVE_REG_VOL_SOUND ((uint32_t) 0x00302084UL) +#define LV_EVE_REG_VSIZE ((uint32_t) 0x00302048UL) +#define LV_EVE_REG_VSYNC0 ((uint32_t) 0x0030204cUL) +#define LV_EVE_REG_VSYNC1 ((uint32_t) 0x00302050UL) + + +/* Macros for static display list generation */ + +//#define LV_EVE_ALPHA_FUNC(func,ref) ((LV_EVE_DL_ALPHA_FUNC) | (((func) & 7UL) << 8U) | ((ref) & 0xFFUL)) +/** + * @brief Set the alpha test function. + * + * @return a 32 bit word for use with EVE_cmd_dl() + */ +static inline uint32_t LV_EVE_ALPHA_FUNC(uint8_t func, uint8_t ref) +{ + uint32_t const funcv = ((uint32_t) func & 7U) << 8U; + return (LV_EVE_DL_ALPHA_FUNC | funcv | ref); +} + +//#define LV_EVE_BITMAP_HANDLE(handle) ((LV_EVE_DL_BITMAP_HANDLE) | ((handle) & 0x1FUL)) +/** + * @brief Set the bitmap handle. + * @return a 32 bit word for use with EVE_cmd_dl() + */ +static inline uint32_t LV_EVE_BITMAP_HANDLE(uint8_t handle) +{ + return (LV_EVE_DL_BITMAP_HANDLE | ((handle) & 0x1FUL)); +} + +//#define LV_EVE_BITMAP_LAYOUT(format,linestride,height) ((LV_EVE_DL_BITMAP_LAYOUT) | (((format) & 0x1FUL) << 19U) | (((linestride) & 0x3FFUL) << 9U) | ((height) & 0x1FFUL)) +/** + * @brief Set the source bitmap memory format and layout for the current handle. + * @return a 32 bit word for use with EVE_cmd_dl() + */ +static inline uint32_t LV_EVE_BITMAP_LAYOUT(uint8_t format, uint16_t linestride, uint16_t height) +{ + uint32_t const formatv = ((uint32_t) format & 0x1FUL) << 19U; + uint32_t const linestridev = ((uint32_t) linestride & 0x3FFUL) << 9U; + uint32_t const heightv = height & 0x1FFUL; + return (LV_EVE_DL_BITMAP_LAYOUT | formatv | linestridev | heightv); +} + +//#define LV_EVE_BITMAP_SIZE(filter,wrapx,wrapy,width,height) ((LV_EVE_DL_BITMAP_SIZE) | (((filter) & 1UL) << 20U) | (((wrapx) & 1UL) << 19U) | (((wrapy) & 1UL) << 18U) | (((width) & 0x1FFUL) << 9U) | ((height) & 0x1FFUL)) +/** + * @brief Set the source bitmap memory format and layout for the current handle. + * @return a 32 bit word for use with EVE_cmd_dl() + */ +static inline uint32_t LV_EVE_BITMAP_SIZE(uint8_t filter, uint8_t wrapx, uint8_t wrapy, uint16_t width, uint16_t height) +{ + uint32_t const filterv = (filter & 0x1UL) << 20U; + uint32_t const wrapxv = (wrapx & 0x1UL) << 19U; + uint32_t const wrapyv = (wrapy & 0x1UL) << 18U; + uint32_t const widthv = (width & 0x1FFUL) << 9U; + uint32_t const heightv = height & 0x1FFUL; + return (LV_EVE_DL_BITMAP_SIZE | filterv | wrapxv | wrapyv | widthv | heightv); +} + +//#define LV_EVE_BITMAP_LAYOUT_H(linestride,height) ((LV_EVE_DL_BITMAP_LAYOUT_H) | (((((linestride) & 0xC00U) >> 10U)&3UL) << 2U) | ((((height) & 0x600U) >> 9U) & 3UL)) +/** + * @brief Set the 2 most significant bits of the source bitmap memory format and layout for the current handle. + * @param linestride 12-bit value specified to BITMAP_LAYOUT + * @param height 11-bit value specified to BITMAP_LAYOUT + * @note this is different to FTDIs implementation as this takes the original values as parameters and not only the upper bits + * @return a 32 bit word for use with EVE_cmd_dl() + */ +static inline uint32_t LV_EVE_BITMAP_LAYOUT_H(uint16_t linestride, uint16_t height) +{ + uint32_t const linestridev = (uint32_t)((((linestride & 0xC00U) >> 10U) & 3UL) << 2U); + uint32_t const heightv = (uint32_t)(((height & 0x600U) >> 9U) & 3UL); + return (LV_EVE_DL_BITMAP_LAYOUT_H | linestridev | heightv); +} + +//#define LV_EVE_BITMAP_SIZE_H(width,height) ((LV_EVE_DL_BITMAP_SIZE_H) | (((((width) & 0x600U) >> 9U) & 3UL) << 2U) | ((((height) & 0x600U) >> 9U) & 3UL)) +/** + * @brief Set the 2 most significant bits of bitmaps dimension for the current handle. + * @param linestride 11-bit value of bitmap width, the 2 most significant bits are used + * @param height 11-bit value of bitmap width, the 2 most significant bits are used + * @note this is different to FTDIs implementation as this takes the original values as parameters and not only the upper bits + * @return a 32 bit word for use with EVE_cmd_dl() + */ +static inline uint32_t LV_EVE_BITMAP_SIZE_H(uint16_t width, uint16_t height) +{ + uint32_t const widthv = (uint32_t)((((width & 0x600U) >> 9U) & 3UL) << 2U); + uint32_t const heightv = (uint32_t)(((height & 0x600U) >> 9U) & 3UL); + return ((LV_EVE_DL_BITMAP_SIZE_H) | widthv | heightv); +} + +//#define LV_EVE_BITMAP_SOURCE(addr) ((LV_EVE_DL_BITMAP_SOURCE) | ((addr) & 0x3FFFFFUL)) +/** + * @brief Set the source address of bitmap data in RAM_G or flash memory. + * @return a 32 bit word for use with EVE_cmd_dl() + */ +static inline uint32_t LV_EVE_BITMAP_SOURCE(uint32_t addr) +{ + return (LV_EVE_DL_BITMAP_SOURCE | (addr & 0x3FFFFFUL)); +} + +#if LV_DRAW_EVE_EVE_GENERATION < 3 /* only define these for FT81x */ +//#define LV_EVE_BITMAP_TRANSFORM_A(a) ((LV_EVE_DL_BITMAP_TRANSFORM_A) | ((a) & 0x1FFFFUL)) +/** + * @brief Set the A coefficient of the bitmap transform matrix. + * @return a 32 bit word for use with EVE_cmd_dl() + */ +static inline uint32_t LV_EVE_BITMAP_TRANSFORM_A(uint32_t val) +{ + return (LV_EVE_DL_BITMAP_TRANSFORM_A | (val & 0x1FFFFUL)); +} + +//#define LV_EVE_BITMAP_TRANSFORM_B(b) ((LV_EVE_DL_BITMAP_TRANSFORM_B) | ((b) & 0x1FFFFUL)) +/** + * @brief Set the B coefficient of the bitmap transform matrix. + * @return a 32 bit word for use with EVE_cmd_dl() + */ +static inline uint32_t LV_EVE_BITMAP_TRANSFORM_B(uint32_t val) +{ + return (LV_EVE_DL_BITMAP_TRANSFORM_B | (val & 0x1FFFFUL)); +} + +//#define LV_EVE_BITMAP_TRANSFORM_D(d) ((LV_EVE_DL_BITMAP_TRANSFORM_D) | ((d) & 0x1FFFFUL)) +/** + * @brief Set the D coefficient of the bitmap transform matrix. + * @return a 32 bit word for use with EVE_cmd_dl() + */ +static inline uint32_t LV_EVE_BITMAP_TRANSFORM_D(uint32_t val) +{ + return (LV_EVE_DL_BITMAP_TRANSFORM_D | (val & 0x1FFFFUL)); +} + +//#define LV_EVE_BITMAP_TRANSFORM_E(e) ((LV_EVE_DL_BITMAP_TRANSFORM_E) | ((e) & 0x1FFFFUL)) +/** + * @brief Set he E coefficient of the bitmap transform matrix. + * @return a 32 bit word for use with EVE_cmd_dl() + */ +static inline uint32_t LV_EVE_BITMAP_TRANSFORM_E(uint32_t val) +{ + return (LV_EVE_DL_BITMAP_TRANSFORM_E | (val & 0x1FFFFUL)); +} + +#endif + +//#define LV_EVE_BITMAP_TRANSFORM_C(c) ((LV_EVE_DL_BITMAP_TRANSFORM_C) | ((c) & 0x1FFFFUL)) +/** + * @brief Set the C coefficient of the bitmap transform matrix. + * @return a 32 bit word for use with EVE_cmd_dl() + */ +static inline uint32_t LV_EVE_BITMAP_TRANSFORM_C(uint32_t val) +{ + return (LV_EVE_DL_BITMAP_TRANSFORM_C | (val & 0x1FFFFUL)); +} + +//#define LV_EVE_BITMAP_TRANSFORM_F(f) ((LV_EVE_DL_BITMAP_TRANSFORM_F) | ((f) & 0x1FFFFUL)) +/** + * @brief Set the F coefficient of the bitmap transform matrix. + * @return a 32 bit word for use with EVE_cmd_dl() + */ +static inline uint32_t LV_EVE_BITMAP_TRANSFORM_F(uint32_t val) +{ + return (LV_EVE_DL_BITMAP_TRANSFORM_F | (val & 0x1FFFFUL)); +} + +//#define LV_EVE_BLEND_FUNC(src,dst) ((LV_EVE_DL_BLEND_FUNC) | (((src) & 7UL) << 3U) | ((dst) & 7UL)) +/** + * @brief Execute a sequence of commands at another location in the display list. + * @return a 32 bit word for use with EVE_cmd_dl() + */ +static inline uint32_t LV_EVE_BLEND_FUNC(uint8_t src, uint8_t dst) +{ + uint32_t const srcv = (uint32_t)((src & 7UL) << 3U); + uint32_t const dstv = (uint32_t)(dst & 7UL); + return (LV_EVE_DL_BLEND_FUNC | srcv | dstv); +} + +//#define LV_EVE_CALL(dest) ((LV_EVE_DL_CALL) | ((dest) & 0xFFFFUL)) +/** + * @brief Execute a sequence of commands at another location in the display list. + * @note valid range for dest is from zero to 2047 + * @return a 32 bit word for use with EVE_cmd_dl() + */ +static inline uint32_t LV_EVE_CALL(uint16_t dest) +{ + return (LV_EVE_DL_CALL | (dest & 0x7FFUL)); +} + +//#define LV_EVE_JUMP(dest) ((LV_EVE_DL_JUMP) | ((dest) & 0xFFFFUL)) +/** + * @brief Execute commands at another location in the display list. + * @note valid range for dest is from zero to 2047 + * @return a 32 bit word for use with EVE_cmd_dl() + */ +static inline uint32_t LV_EVE_JUMP(uint16_t dest) +{ + return (LV_EVE_DL_JUMP | (dest & 0x7FFUL)); +} + +//#define LV_EVE_CELL(cell) ((LV_EVE_DL_CELL) | ((cell) & 0x7FUL)) +/** + * @brief Set the bitmap cell number for the VERTEX2F command. + * @return a 32 bit word for use with EVE_cmd_dl() + */ +static inline uint32_t LV_EVE_CELL(uint8_t cell) +{ + return (LV_EVE_DL_CELL | (cell & 0x7FUL)); +} + +//#define LV_EVE_CLEAR(c,s,t) ((LV_EVE_DL_CLEAR) | (((c) & 1UL) << 2U) | (((s) & 1UL) << 1U) | ((t) & 1UL)) +/** + * @brief Clear buffers to preset values. + * @return a 32 bit word for use with EVE_cmd_dl() + */ +static inline uint32_t LV_EVE_CLEAR(uint8_t color, uint8_t stencil, uint8_t tag) +{ + uint32_t const colorv = (color & 1UL) << 2U; + uint32_t const stencilv = (stencil & 1UL) << 1U; + uint32_t const tagv = (tag & 1UL); + return (LV_EVE_DL_CLEAR | colorv | stencilv | tagv); +} + +//#define LV_EVE_CLEAR_COLOR_A(alpha) ((LV_EVE_DL_CLEAR_COLOR_A) | ((alpha) & 0xFFUL)) +/** + * @brief Set clear value for the alpha channel. + * @return a 32 bit word for use with EVE_cmd_dl() + */ +static inline uint32_t LV_EVE_CLEAR_COLOR_A(uint8_t alpha) +{ + return (LV_EVE_DL_CLEAR_COLOR_A | alpha); +} + +//#define LV_EVE_CLEAR_COLOR_RGB(red,green,blue) ((LV_EVE_DL_CLEAR_COLOR_RGB) | (((red) & 0xFFUL) << 16U) | (((green) & 0xFFUL) << 8U) | ((blue) & 0xFFUL)) +/** + * @brief Set clear values for red, green and blue channels. + * @return a 32 bit word for use with EVE_cmd_dl() + */ +static inline uint32_t LV_EVE_CLEAR_COLOR_RGB(uint8_t red, uint8_t green, uint8_t blue) +{ + uint32_t const redv = ((red & 0xFFUL) << 16U); + uint32_t const greenv = ((green & 0xFFUL) << 8U); + uint32_t const bluev = (blue & 0xFFUL); + return (LV_EVE_DL_CLEAR_COLOR_RGB | redv | greenv | bluev); +} + +//#define LV_EVE_CLEAR_STENCIL(s) ((LV_EVE_DL_CLEAR_STENCIL) | ((s) & 0xFFUL)) +/** + * @brief Set clear value for the stencil buffer. + * @return a 32 bit word for use with EVE_cmd_dl() + */ +static inline uint32_t LV_EVE_CLEAR_STENCIL(uint8_t val) +{ + return (LV_EVE_DL_CLEAR_STENCIL | val); +} + +//#define LV_EVE_CLEAR_TAG(s) ((LV_EVE_DL_CLEAR_TAG) | ((s) & 0xFFUL)) +/** + * @brief Set clear value for the tag buffer. + * @return a 32 bit word for use with EVE_cmd_dl() + */ +static inline uint32_t LV_EVE_CLEAR_TAG(uint8_t val) +{ + return (LV_EVE_DL_CLEAR_TAG | val); +} + +//#define LV_EVE_COLOR_A(alpha) ((LV_EVE_DL_COLOR_A) | ((alpha) & 0xFFUL)) +/** + * @brief Set the current color alpha. + * @return a 32 bit word for use with EVE_cmd_dl() + */ +static inline uint32_t LV_EVE_COLOR_A(uint8_t alpha) +{ + return (LV_EVE_DL_COLOR_A | alpha); +} + +//#define LV_EVE_COLOR_MASK(r,g,b,a) ((LV_EVE_DL_COLOR_MASK) | (((r) & 1UL) << 3U) | (((g) & 1UL) << 2U) | (((b) & 1UL) << 1U) | ((a) & 1UL)) +/** + * @brief Enable or disable writing of color components. + * @return a 32 bit word for use with EVE_cmd_dl() + */ +static inline uint32_t LV_EVE_COLOR_MASK(uint8_t red, uint8_t green, uint8_t blue, uint8_t alpha) +{ + uint32_t const redv = ((red & 1UL) << 3U); + uint32_t const greenv = ((green & 1UL) << 2U); + uint32_t const bluev = ((blue & 1UL) << 1U); + uint32_t const alphav = (alpha & 1UL); + return (LV_EVE_DL_COLOR_MASK | redv | greenv | bluev | alphav); +} + +//#define LV_EVE_COLOR_RGB(red,green,blue) ((LV_EVE_DL_COLOR_RGB) | (((red) & 0xFFUL) << 16U) | (((green) & 0xFFUL) << 8U) | ((blue) & 0xFFUL)) +/** + * @brief Set the current color red, green and blue. + * @return a 32 bit word for use with EVE_cmd_dl() + */ +static inline uint32_t LV_EVE_COLOR_RGB(uint8_t red, uint8_t green, uint8_t blue) +{ + uint32_t const redv = ((red & 0xFFUL) << 16U); + uint32_t const greenv = ((green & 0xFFUL) << 8U); + uint32_t const bluev = (blue & 0xFFUL); + return (LV_EVE_DL_COLOR_RGB | redv | greenv | bluev); +} + +//#define LV_EVE_LINE_WIDTH(width) ((LV_EVE_DL_LINE_WIDTH) | (((uint32_t) (width)) & 0xFFFUL)) +/** + * @brief Set the width of lines to be drawn with primitive LINES in 1/16 pixel precision. + * @return a 32 bit word for use with EVE_cmd_dl() + */ +static inline uint32_t LV_EVE_LINE_WIDTH(uint16_t width) +{ + return (LV_EVE_DL_LINE_WIDTH | (width & 0xFFFUL)); +} + +//#define LV_EVE_MACRO(m) ((LV_EVE_DL_MACRO) | ((m) & 1UL)) +/** + * @brief Execute a single command from a macro register. + * @return a 32 bit word for use with EVE_cmd_dl() + */ +static inline uint32_t LV_EVE_MACRO(uint8_t macro) +{ + return (LV_EVE_DL_MACRO | (macro & 0x1UL)); +} + +//#define LV_EVE_PALETTE_SOURCE(addr) ((LV_EVE_DL_PALETTE_SOURCE) | ((addr) & 0x3FFFFF3UL)) +/** + * @brief Set the base address of the palette. + * @note 2-byte alignment is required if pixel format is PALETTE4444 or PALETTE565. + * @return a 32 bit word for use with EVE_cmd_dl() + */ +static inline uint32_t LV_EVE_PALETTE_SOURCE(uint32_t addr) +{ + return (LV_EVE_DL_PALETTE_SOURCE | (addr & 0x3FFFFFUL)); +} + +//#define LV_EVE_POINT_SIZE(size) ((LV_EVE_DL_POINT_SIZE) | ((size) & 0x1FFFUL)) +/** + * @brief Set the radius of points to be drawn with primitive POINTS in 1/16 pixel precision. + * @return a 32 bit word for use with EVE_cmd_dl() + */ +static inline uint32_t LV_EVE_POINT_SIZE(uint16_t size) +{ + return (LV_EVE_DL_POINT_SIZE | (size & 0x1FFFUL)); +} + +//#define LV_EVE_SCISSOR_SIZE(width,height) ((LV_EVE_DL_SCISSOR_SIZE) | (((width) & 0xFFFUL) << 12U) | ((height) & 0xFFFUL)) +/** + * @brief Set the size of the scissor clip rectangle. + * @note valid range for width and height is from zero to 2048 + * @return a 32 bit word for use with EVE_cmd_dl() + */ +static inline uint32_t LV_EVE_SCISSOR_SIZE(uint16_t width, uint16_t height) +{ + uint32_t const widthv = (uint32_t)((width & 0xFFFUL) << 12U); + uint32_t const heightv = (uint32_t)(height & 0xFFFUL); + return (LV_EVE_DL_SCISSOR_SIZE | widthv | heightv); +} + +//#define LV_EVE_SCISSOR_XY(x,y) ((LV_EVE_DL_SCISSOR_XY) | (((x) & 0x7FFUL) << 11U) | ((y) & 0x7FFUL)) +/** + * @brief Set the top left corner of the scissor clip rectangle. + * @note valid range for width and height is from zero to 2047 + * @return a 32 bit word for use with EVE_cmd_dl() + */ +static inline uint32_t LV_EVE_SCISSOR_XY(uint16_t xc0, uint16_t yc0) +{ + uint32_t const xc0v = (uint32_t)((xc0 & 0x7FFUL) << 11U); + uint32_t const yc0v = (uint32_t)(yc0 & 0x7FFUL); + return (LV_EVE_DL_SCISSOR_XY | xc0v | yc0v); +} + +//#define LV_EVE_STENCIL_FUNC(func,ref,mask) ((LV_EVE_DL_STENCIL_FUNC) | (((func) & 7UL) << 16U) | (((ref) & 0xFFUL) << 8U)|((mask) & 0xFFUL)) +/** + * @brief Set function and reference value for stencil testing. + * @return a 32 bit word for use with EVE_cmd_dl() + */ +static inline uint32_t LV_EVE_STENCIL_FUNC(uint8_t func, uint8_t ref, uint8_t mask) +{ + uint32_t const funcv = (uint32_t)((func & 7UL) << 16U); + uint32_t const refv = (uint32_t)((ref & 0xFFUL) << 8U); + uint32_t const maskv = (uint32_t)(mask & 0xFFUL); + return (LV_EVE_DL_STENCIL_FUNC | funcv | refv | maskv); +} + +//#define LV_EVE_STENCIL_MASK(mask) ((LV_EVE_DL_STENCIL_MASK) | ((mask) & 0xFFUL)) +/** + * @brief Control the writing of individual bits in the stencil planes. + * @return a 32 bit word for use with EVE_cmd_dl() + */ +static inline uint32_t LV_EVE_STENCIL_MASK(uint8_t mask) +{ + return (LV_EVE_DL_STENCIL_MASK | mask); +} + +//#define LV_EVE_STENCIL_OP(sfail,spass) ((LV_EVE_DL_STENCIL_OP) | (((sfail) & 7UL) << 3U) | ((spass) & 7UL)) +/** + * @brief Set stencil test actions. + * @return a 32 bit word for use with EVE_cmd_dl() + */ +static inline uint32_t LV_EVE_STENCIL_OP(uint8_t sfail, uint8_t spass) +{ + uint32_t const sfailv = (uint32_t)((sfail & 0x07UL) << 3U); + uint32_t const spassv = (uint32_t)(spass & 0x07UL); + return (LV_EVE_DL_STENCIL_OP | sfailv | spassv); +} + +//#define LV_EVE_TAG(s) ((LV_EVE_DL_TAG) | ((s) & 0xFFUL)) +/** + * @brief Attach the tag value for the following graphics objects drawn on the screen. + * @return a 32 bit word for use with EVE_cmd_dl() + */ +static inline uint32_t LV_EVE_TAG(uint8_t tagval) +{ + return (LV_EVE_DL_TAG | tagval); +} + +//#define LV_EVE_TAG_MASK(mask) ((LV_EVE_DL_TAG_MASK) | ((mask) & 1UL)) +/** + * @brief Control the writing of the tag buffer. + * @return a 32 bit word for use with EVE_cmd_dl() + */ +static inline uint32_t LV_EVE_TAG_MASK(uint8_t mask) +{ + return (LV_EVE_DL_TAG_MASK | ((mask) & 1UL)); +} + +//#define LV_EVE_VERTEX2F(x,y) ((LV_EVE_DL_VERTEX2F) | ((((uint32_t) (x)) & 0x7FFFUL) << 15U) | (((uint32_t) (y)) & 0x7FFFUL)) +/** + * @brief Set coordinates for graphics primitves. + * @return a 32 bit word for use with EVE_cmd_dl() + */ +static inline uint32_t LV_EVE_VERTEX2F(int16_t xc0, int16_t yc0) +{ + uint32_t const xc0v = ((((uint32_t)((uint16_t) xc0)) & 0x7FFFUL) << 15U); + uint32_t const yc0v = (((uint32_t)((uint16_t) yc0)) & 0x7FFFUL); + return (LV_EVE_DL_VERTEX2F | xc0v | yc0v); +} + +//#define LV_EVE_VERTEX2II(x,y,handle,cell) ((LV_EVE_DL_VERTEX2II) | (((x) & 0x1FFUL) << 21U) | (((y) & 0x1FFUL) << 12U) | (((handle) & 0x1FUL) << 7U) | ((cell) & 0x7FUL)) +/** + * @brief Set coordinates, bitmap-handle and cell-number for graphics primitves. + * @return a 32 bit word for use with EVE_cmd_dl() + */ +static inline uint32_t LV_EVE_VERTEX2II(uint16_t xc0, uint16_t yc0, uint8_t handle, uint8_t cell) +{ + uint32_t const xc0v = ((((uint32_t) xc0) & 0x1FFUL) << 21U); + uint32_t const yc0v = ((((uint32_t) yc0) & 0x1FFUL) << 12U); + uint32_t const handlev = ((((uint32_t) handle) & 0x1FUL) << 7U); + uint32_t const cellv = (((uint32_t) cell) & 0x7FUL); + return (LV_EVE_DL_VERTEX2II | xc0v | yc0v | handlev | cellv); +} + +//#define LV_EVE_VERTEX_FORMAT(frac) ((LV_EVE_DL_VERTEX_FORMAT) | ((frac) & 7UL)) +/** + * @brief Set the precision of VERTEX2F coordinates. + * @return a 32 bit word for use with EVE_cmd_dl() + */ +static inline uint32_t LV_EVE_VERTEX_FORMAT(uint8_t frac) +{ + return (LV_EVE_DL_VERTEX_FORMAT | ((frac) & 7UL)); +} + +//#define LV_EVE_VERTEX_TRANSLATE_X(x) ((LV_EVE_DL_VERTEX_TRANSLATE_X) | ((x) & 0x1FFFFUL)) +/** + * @brief Set the vertex transformations X translation component. + * @return a 32 bit word for use with EVE_cmd_dl() + */ +static inline uint32_t LV_EVE_VERTEX_TRANSLATE_X(int32_t xco) +{ + return (LV_EVE_DL_VERTEX_TRANSLATE_X | (((uint32_t) xco) & 0x1FFFFUL)); +} + +//#define LV_EVE_VERTEX_TRANSLATE_Y(y) ((LV_EVE_DL_VERTEX_TRANSLATE_Y) | ((y) & 0x1FFFFUL)) +/** + * @brief Set the vertex transformations Y translation component. + * @return a 32 bit word for use with EVE_cmd_dl() + */ +static inline uint32_t LV_EVE_VERTEX_TRANSLATE_Y(int32_t yco) +{ + return (LV_EVE_DL_VERTEX_TRANSLATE_Y | (((uint32_t) yco) & 0x1FFFFUL)); +} + +/* #define LV_EVE_BEGIN(prim) ((LV_EVE_DL_BEGIN) | ((prim) & 15UL)) */ /* use define LV_EVE_DL_BEGIN */ +/* #define LV_EVE_DISPLAY() ((LV_EVE_DL_DISPLAY)) */ /* use define LV_EVE_DL_DISPLAY */ +/* #define LV_EVE_END() ((LV_EVE_DL_END)) */ /* use define LV_EVE_DL_END */ +/* #define LV_EVE_RESTORE_CONTEXT() ((LV_EVE_DL_RESTORE_CONTEXT)) */ /* use define LV_EVE_DL_RESTORE_CONTEXT */ +/* #define LV_EVE_RETURN() ((LV_EVE_DL_RETURN)) */ /* use define LV_EVE_DL_RETURN */ +/* #define LV_EVE_SAVE_CONTEXT() ((LV_EVE_DL_SAVE_CONTEXT)) */ /* use define LV_EVE_DL_SAVE_CONTEXT */ +/* #define LV_EVE_NOP() ((LV_EVE_DL_NOP)) */ + +/* ########## EVE Generation 3: BT815 / BT816 definitions ########## */ + +#if LV_DRAW_EVE_EVE_GENERATION > 2 + +#define LV_EVE_EVE_GLFORMAT ((uint32_t) 31UL) /* used with BITMAP_LAYOUT to indicate bitmap-format is specified by BITMAP_EXT_FORMAT */ + +#define LV_EVE_DL_BITMAP_EXT_FORMAT ((uint32_t) 0x2E000000UL) /* requires OR'd arguments */ +#define LV_EVE_DL_BITMAP_SWIZZLE ((uint32_t) 0x2F000000UL) +/* #define LV_EVE_DL_INT_FRR ((uint32_t) 0x30000000UL) */ /* ESE displays "Internal: flash read result" - undocumented display list command */ + +/* Extended Bitmap formats */ +#define LV_EVE_EVE_ASTC_4X4 ((uint32_t) 37808UL) +#define LV_EVE_EVE_ASTC_5X4 ((uint32_t) 37809UL) +#define LV_EVE_EVE_ASTC_5X5 ((uint32_t) 37810UL) +#define LV_EVE_EVE_ASTC_6X5 ((uint32_t) 37811UL) +#define LV_EVE_EVE_ASTC_6X6 ((uint32_t) 37812UL) +#define LV_EVE_EVE_ASTC_8X5 ((uint32_t) 37813UL) +#define LV_EVE_EVE_ASTC_8X6 ((uint32_t) 37814UL) +#define LV_EVE_EVE_ASTC_8X8 ((uint32_t) 37815UL) +#define LV_EVE_EVE_ASTC_10X5 ((uint32_t) 37816UL) +#define LV_EVE_EVE_ASTC_10X6 ((uint32_t) 37817UL) +#define LV_EVE_EVE_ASTC_10X8 ((uint32_t) 37818UL) +#define LV_EVE_EVE_ASTC_10X10 ((uint32_t) 37819UL) +#define LV_EVE_EVE_ASTC_12X10 ((uint32_t) 37820UL) +#define LV_EVE_EVE_ASTC_12X12 ((uint32_t) 37821UL) + +#define LV_EVE_EVE_RAM_ERR_REPORT ((uint32_t) 0x309800UL) /* max 128 bytes null terminated string */ +#define LV_EVE_EVE_RAM_FLASH ((uint32_t) 0x800000UL) +#define LV_EVE_EVE_RAM_FLASH_POSTBLOB ((uint32_t) 0x801000UL) + +#define LV_EVE_EVE_OPT_FLASH ((uint16_t) 64U) +#define LV_EVE_EVE_OPT_OVERLAY ((uint16_t) 128U) +#define LV_EVE_EVE_OPT_FORMAT ((uint16_t) 4096U) +#define LV_EVE_EVE_OPT_FILL ((uint16_t) 8192U) + +/* Commands for BT815 / BT816 */ +#define LV_EVE_CMD_BITMAP_TRANSFORM ((uint32_t) 0xFFFFFF21UL) +#define LV_EVE_CMD_SYNC ((uint32_t) 0xFFFFFF42UL) /* does not need a dedicated function, just use EVE_cmd_dl(CMD_SYNC) */ +#define LV_EVE_CMD_FLASHERASE ((uint32_t) 0xFFFFFF44UL) /* does not need a dedicated function, just use EVE_cmd_dl(CMD_FLASHERASE) */ +#define LV_EVE_CMD_FLASHWRITE ((uint32_t) 0xFFFFFF45UL) +#define LV_EVE_CMD_FLASHREAD ((uint32_t) 0xFFFFFF46UL) +#define LV_EVE_CMD_FLASHUPDATE ((uint32_t) 0xFFFFFF47UL) +#define LV_EVE_CMD_FLASHDETACH ((uint32_t) 0xFFFFFF48UL) /* does not need a dedicated function, just use EVE_cmd_dl(CMD_FLASHDETACH) */ +#define LV_EVE_CMD_FLASHATTACH ((uint32_t) 0xFFFFFF49UL) /* does not need a dedicated function, just use EVE_cmd_dl(CMD_FLASHATTACH) */ +#define LV_EVE_CMD_FLASHFAST ((uint32_t) 0xFFFFFF4AUL) +#define LV_EVE_CMD_FLASHSPIDESEL ((uint32_t) 0xFFFFFF4BUL) /* does not need a dedicated function, just use EVE_cmd_dl(CMD_FLASHSPIDESEL) */ +#define LV_EVE_CMD_FLASHSPITX ((uint32_t) 0xFFFFFF4CUL) +#define LV_EVE_CMD_FLASHSPIRX ((uint32_t) 0xFFFFFF4DUL) +#define LV_EVE_CMD_FLASHSOURCE ((uint32_t) 0xFFFFFF4EUL) +#define LV_EVE_CMD_CLEARCACHE ((uint32_t) 0xFFFFFF4FUL) /* does not need a dedicated function, just use EVE_cmd_dl(CMD_CLEARCACHE) */ +#define LV_EVE_CMD_INFLATE2 ((uint32_t) 0xFFFFFF50UL) +#define LV_EVE_CMD_ROTATEAROUND ((uint32_t) 0xFFFFFF51UL) +#define LV_EVE_CMD_RESETFONTS ((uint32_t) 0xFFFFFF52UL) /* does not need a dedicated function, just use EVE_cmd_dl(CMD_RESETFONTS) */ +#define LV_EVE_CMD_ANIMSTART ((uint32_t) 0xFFFFFF53UL) +#define LV_EVE_CMD_ANIMSTOP ((uint32_t) 0xFFFFFF54UL) +#define LV_EVE_CMD_ANIMXY ((uint32_t) 0xFFFFFF55UL) +#define LV_EVE_CMD_ANIMDRAW ((uint32_t) 0xFFFFFF56UL) +#define LV_EVE_CMD_GRADIENTA ((uint32_t) 0xFFFFFF57UL) +#define LV_EVE_CMD_FILLWIDTH ((uint32_t) 0xFFFFFF58UL) +#define LV_EVE_CMD_APPENDF ((uint32_t) 0xFFFFFF59UL) +#define LV_EVE_CMD_ANIMFRAME ((uint32_t) 0xFFFFFF5AUL) +#define LV_EVE_CMD_VIDEOSTARTF ((uint32_t) 0xFFFFFF5FUL) /* does not need a dedicated function, just use EVE_cmd_dl(CMD_VIDEOSTARTF) */ + +/* Registers for BT815 / BT816 */ +#define LV_EVE_REG_ADAPTIVE_FRAMERATE ((uint32_t) 0x0030257cUL) +#define LV_EVE_REG_PLAYBACK_PAUSE ((uint32_t) 0x003025ecUL) +#define LV_EVE_REG_FLASH_STATUS ((uint32_t) 0x003025f0UL) +#define LV_EVE_REG_FLASH_SIZE ((uint32_t) 0x00309024UL) +#define LV_EVE_REG_PLAY_CONTROL ((uint32_t) 0x0030914eUL) +#define LV_EVE_REG_COPRO_PATCH_PTR ((uint32_t) 0x00309162UL) + +/* Macros for BT815 / BT816 */ + +//#define LV_EVE_BITMAP_EXT_FORMAT(format) ((LV_EVE_DL_BITMAP_EXT_FORMAT) | ((format) & 0xFFFFUL)) +/** + * @brief Set the extended format of the bitmap. + * @return a 32 bit word for use with EVE_cmd_dl() + */ +static inline uint32_t LV_EVE_BITMAP_EXT_FORMAT(uint16_t format) +{ + return (LV_EVE_DL_BITMAP_EXT_FORMAT | format); +} + +//#define LV_EVE_BITMAP_SWIZZLE(r,g,b,a) ((LV_EVE_DL_BITMAP_SWIZZLE) | (((r) & 7UL) << 9U) | (((g) & 7UL) << 6U) | (((b) & 7UL) << 3U) | ((a) & 7UL)) +/** + * @brief Set the source for the red, green, blue and alpha channels of a bitmap. + * @return a 32 bit word for use with EVE_cmd_dl() + */ +static inline uint32_t LV_EVE_BITMAP_SWIZZLE(uint8_t red, uint8_t green, uint8_t blue, uint8_t alpha) +{ + uint32_t const redv = ((red & 7UL) << 9U); + uint32_t const greenv = ((green & 7UL) << 6U); + uint32_t const bluev = ((blue & 7UL) << 3U); + uint32_t const alphav = (alpha & 7UL); + return (LV_EVE_DL_BITMAP_SWIZZLE | redv | greenv | bluev | alphav); +} + +//#define LV_EVE_BITMAP_TRANSFORM_A_EXT(p,v) ((LV_EVE_DL_BITMAP_TRANSFORM_A) | (((p) & 1UL) << 17U) | ((v) & 0x1FFFFUL)) +/** + * @brief Set the A coefficient of the bitmap transform matrix. + * @return a 32 bit word for use with EVE_cmd_dl() + */ +static inline uint32_t LV_EVE_BITMAP_TRANSFORM_A(uint8_t prc, uint32_t val) +{ + uint32_t const prcv = ((prc & 1UL) << 17U); + uint32_t const valv = (val & 0x1FFFFUL); + return (LV_EVE_DL_BITMAP_TRANSFORM_A | prcv | valv); +} + +//#define LV_EVE_BITMAP_TRANSFORM_B_EXT(p,v) ((LV_EVE_DL_BITMAP_TRANSFORM_B) | (((p) & 1UL) << 17U) | ((v) & 0x1FFFFUL)) +/** + * @brief Set the B coefficient of the bitmap transform matrix. + * @return a 32 bit word for use with EVE_cmd_dl() + */ +static inline uint32_t LV_EVE_BITMAP_TRANSFORM_B(uint8_t prc, uint32_t val) +{ + uint32_t const prcv = ((prc & 1UL) << 17U); + uint32_t const valv = (val & 0x1FFFFUL); + return (LV_EVE_DL_BITMAP_TRANSFORM_B | prcv | valv); +} + +//#define LV_EVE_BITMAP_TRANSFORM_D_EXT(p,v) ((LV_EVE_DL_BITMAP_TRANSFORM_D) | (((p) & 1UL) << 17U) | ((v) & 0x1FFFFUL)) +/** + * @brief Set the D coefficient of the bitmap transform matrix. + * @return a 32 bit word for use with EVE_cmd_dl() + */ +static inline uint32_t LV_EVE_BITMAP_TRANSFORM_D(uint8_t prc, uint32_t val) +{ + uint32_t const prcv = ((prc & 1UL) << 17U); + uint32_t const valv = (val & 0x1FFFFUL); + return (LV_EVE_DL_BITMAP_TRANSFORM_D | prcv | valv); +} + +//#define LV_EVE_BITMAP_TRANSFORM_E_EXT(p,v) ((LV_EVE_DL_BITMAP_TRANSFORM_E) | (((p) & 1UL) << 17U) | ((v) & 0x1FFFFUL)) +/** + * @brief Set the E coefficient of the bitmap transform matrix. + * @return a 32 bit word for use with EVE_cmd_dl() + */ +static inline uint32_t LV_EVE_BITMAP_TRANSFORM_E(uint8_t prc, uint32_t val) +{ + uint32_t const prcv = ((prc & 1UL) << 17U); + uint32_t const valv = (val & 0x1FFFFUL); + return (LV_EVE_DL_BITMAP_TRANSFORM_E | prcv | valv); +} + +//#define LV_EVE_BITMAP_TRANSFORM_A(a) LV_EVE_BITMAP_TRANSFORM_A_EXT(0UL,(a)) +//#define LV_EVE_BITMAP_TRANSFORM_B(b) LV_EVE_BITMAP_TRANSFORM_B_EXT(0UL,(b)) +//#define LV_EVE_BITMAP_TRANSFORM_D(d) LV_EVE_BITMAP_TRANSFORM_D_EXT(0UL,(d)) +//#define LV_EVE_BITMAP_TRANSFORM_E(e) LV_EVE_BITMAP_TRANSFORM_E_EXT(0UL,(e)) + +#endif /* LV_DRAW_EVE_EVE_GENERATION > 2 */ + +/* ########## EVE Generation 4: BT817 / BT818 definitions ########## */ + +#if LV_DRAW_EVE_EVE_GENERATION > 3 + +/* Commands for BT817 / BT818 */ +#define LV_EVE_CMD_ANIMFRAMERAM ((uint32_t) 0xFFFFFF6DUL) +#define LV_EVE_CMD_ANIMSTARTRAM ((uint32_t) 0xFFFFFF6EUL) +#define LV_EVE_CMD_APILEVEL ((uint32_t) 0xFFFFFF63UL) +#define LV_EVE_CMD_CALIBRATESUB ((uint32_t) 0xFFFFFF60UL) +#define LV_EVE_CMD_CALLLIST ((uint32_t) 0xFFFFFF67UL) +#define LV_EVE_CMD_ENDLIST ((uint32_t) 0xFFFFFF69UL) /* does not need a dedicated function, just use EVE_cmd_dl(CMD_ENDLIST) */ +#define LV_EVE_CMD_FLASHPROGRAM ((uint32_t) 0xFFFFFF70UL) +#define LV_EVE_CMD_FONTCACHE ((uint32_t) 0xFFFFFF6BUL) +#define LV_EVE_CMD_FONTCACHEQUERY ((uint32_t) 0xFFFFFF6CUL) +#define LV_EVE_CMD_GETIMAGE ((uint32_t) 0xFFFFFF64UL) +#define LV_EVE_CMD_HSF ((uint32_t) 0xFFFFFF62UL) +#define LV_EVE_CMD_LINETIME ((uint32_t) 0xFFFFFF5EUL) +#define LV_EVE_CMD_NEWLIST ((uint32_t) 0xFFFFFF68UL) +#define LV_EVE_CMD_PCLKFREQ ((uint32_t) 0xFFFFFF6AUL) +#define LV_EVE_CMD_RETURN ((uint32_t) 0xFFFFFF66UL) /* does not need a dedicated function, just use EVE_cmd_dl(CMD_RETURN) */ +#define LV_EVE_CMD_RUNANIM ((uint32_t) 0xFFFFFF6FUL) +#define LV_EVE_CMD_TESTCARD ((uint32_t) 0xFFFFFF61UL) /* does not need a dedicated function, just use EVE_cmd_dl(CMD_TESTCARD) */ +#define LV_EVE_CMD_WAIT ((uint32_t) 0xFFFFFF65UL) + +/* Registers for BT817 / BT818 */ +#define LV_EVE_REG_UNDERRUN ((uint32_t) 0x0030260cUL) +#define LV_EVE_REG_AH_HCYCLE_MAX ((uint32_t) 0x00302610UL) +#define LV_EVE_REG_PCLK_FREQ ((uint32_t) 0x00302614UL) +#define LV_EVE_REG_PCLK_2X ((uint32_t) 0x00302618UL) +#define LV_EVE_REG_ANIM_ACTIVE ((uint32_t) 0x0030902CUL) + +#endif /* LV_DRAW_EVE_EVE_GENERATION > 3 */ + +/********************** + * TYPEDEFS + **********************/ + +/********************** + * GLOBAL PROTOTYPES + **********************/ + +/********************** + * MACROS + **********************/ + +#endif /*LV_USE_DRAW_EVE*/ + +#ifdef __cplusplus +} /*extern "C"*/ +#endif + +#endif /*LV_DRAW_EVE_DISPLAY_DEFINES_H*/ diff --git a/src/drivers/evdev/lv_evdev.c b/src/drivers/evdev/lv_evdev.c index a1c954beba..1b8319e049 100644 --- a/src/drivers/evdev/lv_evdev.c +++ b/src/drivers/evdev/lv_evdev.c @@ -33,6 +33,7 @@ #include "../../display/lv_display.h" #include "../../display/lv_display_private.h" #include "../../widgets/image/lv_image.h" +#include "../../indev/lv_indev_gesture.h" /********************* * DEFINES @@ -43,6 +44,7 @@ #define EVDEV_DISCOVERY_PATH_BUF_SIZE 32 #define REL_XY_MASK ((1 << REL_X) | (1 << REL_Y)) #define ABS_XY_MASK ((1 << ABS_X) | (1 << ABS_Y)) +#define MAX_TOUCH_POINTS 5 /********************** * TYPEDEFS @@ -66,6 +68,13 @@ typedef struct { int key; lv_indev_state_t state; bool deleting; + /* Multi-touch support */ +#if LV_USE_GESTURE_RECOGNITION + lv_indev_touch_data_t touch_data[MAX_TOUCH_POINTS]; /* Array of touch points for gesture recognition */ + uint8_t touch_count; /* Number of valid touch points */ + uint8_t current_slot; /* Current touch point slot */ + bool touch_data_changed; /* Flag to indicate if touch data has changed since last SYN_REPORT */ +#endif } lv_evdev_t; #ifndef BSD @@ -161,12 +170,70 @@ static void _evdev_read(lv_indev_t * indev, lv_indev_data_t * data) else if(in.code == REL_Y) dsc->root_y += in.value; } else if(in.type == EV_ABS) { - if(in.code == ABS_X || in.code == ABS_MT_POSITION_X) dsc->root_x = in.value; - else if(in.code == ABS_Y || in.code == ABS_MT_POSITION_Y) dsc->root_y = in.value; - else if(in.code == ABS_MT_TRACKING_ID) { - if(in.value == -1) dsc->state = LV_INDEV_STATE_RELEASED; - else if(in.value == 0) dsc->state = LV_INDEV_STATE_PRESSED; +#if LV_USE_GESTURE_RECOGNITION + if(in.code == ABS_MT_SLOT) { + if(in.value >= MAX_TOUCH_POINTS) { + dsc->current_slot = MAX_TOUCH_POINTS - 1; + dsc->touch_count = MAX_TOUCH_POINTS; + LV_LOG_WARN("Touch point slot out of range, setting to max: %d", MAX_TOUCH_POINTS - 1); + } + else { + dsc->current_slot = in.value; + dsc->touch_count = LV_MAX(dsc->touch_count, dsc->current_slot + 1); + LV_LOG_TRACE("Slot changed to %d, touch_count=%d", dsc->current_slot, dsc->touch_count); + } } + else +#endif + if(in.code == ABS_X || in.code == ABS_MT_POSITION_X) { + dsc->root_x = in.value; +#if LV_USE_GESTURE_RECOGNITION + if(in.code == ABS_MT_POSITION_X && dsc->current_slot < MAX_TOUCH_POINTS) { + dsc->touch_data[dsc->current_slot].point.x = in.value; + dsc->touch_data_changed = true; + LV_LOG_TRACE("MT_X update: slot=%d, x=%d", dsc->current_slot, in.value); + } +#endif + } + else if(in.code == ABS_Y || in.code == ABS_MT_POSITION_Y) { + dsc->root_y = in.value; +#if LV_USE_GESTURE_RECOGNITION + if(in.code == ABS_MT_POSITION_Y && dsc->current_slot < MAX_TOUCH_POINTS) { + dsc->touch_data[dsc->current_slot].point.y = in.value; + dsc->touch_data_changed = true; + LV_LOG_TRACE("MT_Y update: slot=%d, y=%d", dsc->current_slot, in.value); + } +#endif + } + else if(in.code == ABS_MT_TRACKING_ID) { + if(in.value == -1) dsc->state = LV_INDEV_STATE_RELEASED; + else dsc->state = LV_INDEV_STATE_PRESSED; +#if LV_USE_GESTURE_RECOGNITION + if(in.value == -1) { + if(dsc->current_slot < MAX_TOUCH_POINTS) { + dsc->touch_data[dsc->current_slot].state = LV_INDEV_STATE_RELEASED; + dsc->touch_data_changed = true; + LV_LOG_TRACE("Touch slot %d released", dsc->current_slot); + + dsc->touch_count = 0; + for(int i = 0; i < MAX_TOUCH_POINTS; i++) { + if(dsc->touch_data[i].state == LV_INDEV_STATE_PRESSED) { + dsc->touch_count = i + 1; + } + } + } + } + else { + if(dsc->current_slot < MAX_TOUCH_POINTS) { + dsc->touch_data[dsc->current_slot].state = LV_INDEV_STATE_PRESSED; + dsc->touch_data[dsc->current_slot].id = dsc->current_slot; + dsc->touch_count = LV_MAX(dsc->touch_count, dsc->current_slot + 1); + dsc->touch_data_changed = true; + LV_LOG_TRACE("Touch slot %d pressed, touch_count=%d", dsc->current_slot, dsc->touch_count); + } + } +#endif + } } else if(in.type == EV_KEY) { if(in.code == BTN_MOUSE || in.code == BTN_TOUCH) { @@ -182,7 +249,64 @@ static void _evdev_read(lv_indev_t * indev, lv_indev_data_t * data) } } } +#if LV_USE_GESTURE_RECOGNITION + else if(in.type == EV_SYN && in.code == SYN_REPORT) { + /* Handle gesture recognition at sync event */ + if(dsc->touch_count > 0 && dsc->touch_data_changed) { + LV_LOG_TRACE("=== SYN_REPORT: touch_count=%d ===", dsc->touch_count); + for(int i = 0; i < MAX_TOUCH_POINTS; i++) { + if(dsc->touch_data[i].state == LV_INDEV_STATE_PRESSED || dsc->touch_data[i].state == LV_INDEV_STATE_RELEASED) { + LV_LOG_TRACE("Slot %d: state=%s, raw(%d, %d)", + i, + dsc->touch_data[i].state == LV_INDEV_STATE_PRESSED ? "PRESSED" : "RELEASED", + dsc->touch_data[i].point.x, dsc->touch_data[i].point.y); + } + } + + /* Create a temporary array with calibrated coordinates for gesture recognition */ + lv_indev_touch_data_t calibrated_touch_data[MAX_TOUCH_POINTS]; + + int active_touches = 0; + + for(int i = 0; i < MAX_TOUCH_POINTS; i++) { + if(dsc->touch_data[i].state == LV_INDEV_STATE_PRESSED || dsc->touch_data[i].state == LV_INDEV_STATE_RELEASED) { + calibrated_touch_data[active_touches] = dsc->touch_data[i]; + + lv_point_t calib_point = _evdev_process_pointer(indev, dsc->touch_data[i].point.x, dsc->touch_data[i].point.y); + calibrated_touch_data[active_touches].point = calib_point; + + LV_LOG_TRACE("Touch %d (slot %d): state=%s, raw(%d, %d) -> calib(%d, %d)", + active_touches, i, + dsc->touch_data[i].state == LV_INDEV_STATE_PRESSED ? "PRESSED" : "RELEASED", + dsc->touch_data[i].point.x, dsc->touch_data[i].point.y, + calib_point.x, calib_point.y); + active_touches++; + } + } + + LV_LOG_TRACE("Gesture recognition: %d touches detected", active_touches); + lv_indev_gesture_recognizers_update(indev, calibrated_touch_data, active_touches); + lv_indev_gesture_recognizers_set_data(indev, data); + + /* Clear RELEASED touch points after gesture recognition to prevent duplicate processing */ + for(int i = 0; i < MAX_TOUCH_POINTS; i++) { + if(dsc->touch_data[i].state == LV_INDEV_STATE_RELEASED) { + /* Mark touch point as invalid by zeroing out the data */ + dsc->touch_data[i].point.x = 0; + dsc->touch_data[i].point.y = 0; + dsc->touch_data[i].id = -1; /* Mark as invalid */ + /* Note: We keep the RELEASED state for this frame, it will be naturally + * cleared when new touch events come in or when all touches end */ + LV_LOG_TRACE("Cleared released touch point slot %d", i); + } + } + + dsc->touch_data_changed = false; + } + } +#endif } + if(!dsc->deleting && br == -1 && errno != EAGAIN) { if(errno == ENODEV) { LV_LOG_INFO("evdev device was removed"); @@ -201,8 +325,19 @@ static void _evdev_read(lv_indev_t * indev, lv_indev_data_t * data) data->key = dsc->key; break; case LV_INDEV_TYPE_POINTER: +#if LV_USE_GESTURE_RECOGNITION + if(dsc->touch_count > 0) { + data->state = dsc->touch_data[0].state; + data->point = _evdev_process_pointer(indev, dsc->touch_data[0].point.x, dsc->touch_data[0].point.y); + } + else { + data->state = dsc->state; + data->point = _evdev_process_pointer(indev, dsc->root_x, dsc->root_y); + } +#else data->state = dsc->state; data->point = _evdev_process_pointer(indev, dsc->root_x, dsc->root_y); +#endif break; default: break; @@ -339,22 +474,18 @@ static void _evdev_discovery_timer_cb(lv_timer_t * tim) * GLOBAL FUNCTIONS **********************/ -lv_indev_t * lv_evdev_create(lv_indev_type_t indev_type, const char * dev_path) +lv_indev_t * lv_evdev_create_fd(lv_indev_type_t indev_type, int fd) { lv_evdev_t * dsc = lv_malloc_zeroed(sizeof(lv_evdev_t)); LV_ASSERT_MALLOC(dsc); - if(dsc == NULL) return NULL; + if(dsc == NULL) goto err_malloc; - dsc->fd = open(dev_path, O_RDONLY | O_NOCTTY | O_CLOEXEC); - if(dsc->fd < 0) { - LV_LOG_WARN("open failed: %s", strerror(errno)); - goto err_after_malloc; - } + dsc->fd = fd; struct stat sb; if(0 != fstat(dsc->fd, &sb)) { LV_LOG_ERROR("fstat failed: %s", strerror(errno)); - goto err_after_open; + goto err_after_malloc; } dsc->st_dev = sb.st_dev; dsc->st_ino = sb.st_ino; @@ -405,12 +536,12 @@ lv_indev_t * lv_evdev_create(lv_indev_type_t indev_type, const char * dev_path) } if(indev_type == LV_INDEV_TYPE_NONE) { - goto err_after_open; + goto err_after_malloc; } if(fcntl(dsc->fd, F_SETFL, O_NONBLOCK) < 0) { LV_LOG_ERROR("fcntl failed: %s", strerror(errno)); - goto err_after_open; + goto err_after_malloc; } /* Detect the minimum and maximum values of the input device for calibration. */ @@ -434,7 +565,7 @@ lv_indev_t * lv_evdev_create(lv_indev_type_t indev_type, const char * dev_path) } lv_indev_t * indev = lv_indev_create(); - if(indev == NULL) goto err_after_open; + if(indev == NULL) goto err_after_malloc; lv_indev_set_type(indev, indev_type); lv_indev_set_read_cb(indev, _evdev_read); lv_indev_set_driver_data(indev, dsc); @@ -442,13 +573,24 @@ lv_indev_t * lv_evdev_create(lv_indev_type_t indev_type, const char * dev_path) return indev; -err_after_open: - close(dsc->fd); err_after_malloc: lv_free(dsc); +err_malloc: + close(fd); return NULL; } +lv_indev_t * lv_evdev_create(lv_indev_type_t indev_type, const char * dev_path) +{ + int fd = open(dev_path, O_RDONLY | O_NOCTTY | O_CLOEXEC); + if(fd < 0) { + LV_LOG_WARN("open failed: %s", strerror(errno)); + return NULL; + } + + return lv_evdev_create_fd(indev_type, fd); +} + lv_result_t lv_evdev_discovery_start(lv_evdev_discovery_cb_t cb, void * user_data) { #ifndef BSD diff --git a/src/drivers/evdev/lv_evdev.h b/src/drivers/evdev/lv_evdev.h index 091de6717c..ed00bb1e65 100644 --- a/src/drivers/evdev/lv_evdev.h +++ b/src/drivers/evdev/lv_evdev.h @@ -40,13 +40,21 @@ typedef void (*lv_evdev_discovery_cb_t)(lv_indev_t * indev, lv_evdev_type_t type **********************/ /** - * Create evdev input device. + * Create evdev input device from a given path. * @param type LV_INDEV_TYPE_POINTER or LV_INDEV_TYPE_KEYPAD * @param dev_path device path, e.g., /dev/input/event0 * @return pointer to input device or NULL if opening failed */ lv_indev_t * lv_evdev_create(lv_indev_type_t indev_type, const char * dev_path); +/** + * Create evdev input device, taking ownership of the given file descriptor. + * @param type LV_INDEV_TYPE_POINTER or LV_INDEV_TYPE_KEYPAD + * @param fd file descriptor of the evdev device + * @return pointer to input device or NULL if opening failed + */ +lv_indev_t * lv_evdev_create_fd(lv_indev_type_t indev_type, int fd); + /** * Begin automatically creating evdev indevs for all new and existing * evdev devices found in /dev/input/ diff --git a/src/drivers/glfw/lv_glfw_window.c b/src/drivers/glfw/lv_glfw_window.c deleted file mode 100644 index 6b4c195758..0000000000 --- a/src/drivers/glfw/lv_glfw_window.c +++ /dev/null @@ -1,403 +0,0 @@ -/** - * @file lv_glfw_window.c - * - */ - -/********************* - * INCLUDES - *********************/ -#include "lv_glfw_window_private.h" -#if LV_USE_OPENGLES -#include -#include "../../core/lv_refr.h" -#include "../../stdlib/lv_string.h" -#include "../../core/lv_global.h" -#include "../../display/lv_display_private.h" -#include "../../indev/lv_indev.h" -#include "../../lv_init.h" -#include "../../misc/lv_area_private.h" - -#include -#include - -#include "lv_opengles_driver.h" -#include "lv_opengles_texture.h" - -/********************* - * DEFINES - *********************/ - -/********************** - * TYPEDEFS - **********************/ - -/********************** - * STATIC PROTOTYPES - **********************/ -static void window_update_handler(lv_timer_t * t); -static uint32_t lv_glfw_tick_count_callback(void); -static lv_glfw_window_t * lv_glfw_get_lv_window_from_window(GLFWwindow * window); -static void glfw_error_cb(int error, const char * description); -static int lv_glfw_init(void); -static int lv_glew_init(void); -static void lv_glfw_timer_init(void); -static void lv_glfw_window_config(GLFWwindow * window, bool use_mouse_indev); -static void lv_glfw_window_quit(void); -static void window_close_callback(GLFWwindow * window); -static void key_callback(GLFWwindow * window, int key, int scancode, int action, int mods); -static void mouse_button_callback(GLFWwindow * window, int button, int action, int mods); -static void mouse_move_callback(GLFWwindow * window, double xpos, double ypos); -static void proc_mouse(lv_glfw_window_t * window); -static void indev_read_cb(lv_indev_t * indev, lv_indev_data_t * data); -static void framebuffer_size_callback(GLFWwindow * window, int width, int height); - -/********************** - * STATIC VARIABLES - **********************/ -static bool glfw_inited; -static bool glew_inited; -static lv_timer_t * update_handler_timer; -static lv_ll_t glfw_window_ll; - -/********************** - * MACROS - **********************/ - -/********************** - * GLOBAL FUNCTIONS - **********************/ - -lv_glfw_window_t * lv_glfw_window_create(int32_t hor_res, int32_t ver_res, bool use_mouse_indev) -{ - if(lv_glfw_init() != 0) { - return NULL; - } - - lv_glfw_window_t * window = lv_ll_ins_tail(&glfw_window_ll); - LV_ASSERT_MALLOC(window); - if(window == NULL) return NULL; - lv_memzero(window, sizeof(*window)); - - /* Create window with graphics context */ - lv_glfw_window_t * existing_window = lv_ll_get_head(&glfw_window_ll); - window->window = glfwCreateWindow(hor_res, ver_res, "LVGL Simulator", NULL, - existing_window ? existing_window->window : NULL); - if(window->window == NULL) { - LV_LOG_ERROR("glfwCreateWindow fail."); - lv_ll_remove(&glfw_window_ll, window); - lv_free(window); - return NULL; - } - - window->hor_res = hor_res; - window->ver_res = ver_res; - lv_ll_init(&window->textures, sizeof(lv_glfw_texture_t)); - window->use_indev = use_mouse_indev; - - glfwSetWindowUserPointer(window->window, window); - lv_glfw_timer_init(); - lv_glfw_window_config(window->window, use_mouse_indev); - lv_glew_init(); - glfwMakeContextCurrent(window->window); - lv_opengles_init(); - - return window; -} - -void lv_glfw_window_delete(lv_glfw_window_t * window) -{ - glfwDestroyWindow(window->window); - if(window->use_indev) { - lv_glfw_texture_t * texture; - LV_LL_READ(&window->textures, texture) { - if(texture->indev != NULL) lv_indev_delete(texture->indev); - } - } - lv_ll_clear(&window->textures); - lv_ll_remove(&glfw_window_ll, window); - lv_free(window); - - if(lv_ll_is_empty(&glfw_window_ll)) { - lv_glfw_window_quit(); - } -} - -void * lv_glfw_window_get_glfw_window(lv_glfw_window_t * window) -{ - return (void *)(window->window); -} - -lv_glfw_texture_t * lv_glfw_window_add_texture(lv_glfw_window_t * window, unsigned int texture_id, int32_t w, int32_t h) -{ - lv_glfw_texture_t * texture = lv_ll_ins_tail(&window->textures); - LV_ASSERT_MALLOC(texture); - if(texture == NULL) return NULL; - lv_memzero(texture, sizeof(*texture)); - texture->window = window; - texture->texture_id = texture_id; - lv_area_set(&texture->area, 0, 0, w - 1, h - 1); - texture->opa = LV_OPA_COVER; - - if(window->use_indev) { - lv_display_t * texture_disp = lv_opengles_texture_get_from_texture_id(texture_id); - if(texture_disp != NULL) { - lv_indev_t * indev = lv_indev_create(); - if(indev == NULL) { - lv_ll_remove(&window->textures, texture); - lv_free(texture); - return NULL; - } - texture->indev = indev; - lv_indev_set_type(indev, LV_INDEV_TYPE_POINTER); - lv_indev_set_read_cb(indev, indev_read_cb); - lv_indev_set_driver_data(indev, texture); - lv_indev_set_mode(indev, LV_INDEV_MODE_EVENT); - lv_indev_set_display(indev, texture_disp); - } - } - - return texture; -} - -void lv_glfw_texture_remove(lv_glfw_texture_t * texture) -{ - if(texture->indev != NULL) { - lv_indev_delete(texture->indev); - } - lv_ll_remove(&texture->window->textures, texture); - lv_free(texture); -} - -void lv_glfw_texture_set_x(lv_glfw_texture_t * texture, int32_t x) -{ - lv_area_set_pos(&texture->area, x, texture->area.y1); -} - -void lv_glfw_texture_set_y(lv_glfw_texture_t * texture, int32_t y) -{ - lv_area_set_pos(&texture->area, texture->area.x1, y); -} - -void lv_glfw_texture_set_opa(lv_glfw_texture_t * texture, lv_opa_t opa) -{ - texture->opa = opa; -} - -lv_indev_t * lv_glfw_texture_get_mouse_indev(lv_glfw_texture_t * texture) -{ - return texture->indev; -} - -/********************** - * STATIC FUNCTIONS - **********************/ - -static int lv_glfw_init(void) -{ - if(glfw_inited) { - return 0; - } - - glfwSetErrorCallback(glfw_error_cb); - - int ret = glfwInit(); - if(ret == 0) { - LV_LOG_ERROR("glfwInit fail."); - return 1; - } - - lv_ll_init(&glfw_window_ll, sizeof(lv_glfw_window_t)); - - glfw_inited = true; - return 0; -} - -static int lv_glew_init(void) -{ - if(glew_inited) { - return 0; - } - - GLenum ret = glewInit(); - if(ret != GLEW_OK) { - LV_LOG_ERROR("glewInit fail: %d.", ret); - return ret; - } - - LV_LOG_INFO("GL version: %s", glGetString(GL_VERSION)); - LV_LOG_INFO("GLSL version: %s", glGetString(GL_SHADING_LANGUAGE_VERSION)); - - glew_inited = true; - - return 0; -} - -static void lv_glfw_timer_init(void) -{ - if(update_handler_timer == NULL) { - update_handler_timer = lv_timer_create(window_update_handler, LV_DEF_REFR_PERIOD, NULL); - lv_tick_set_cb(lv_glfw_tick_count_callback); - } -} - -static void lv_glfw_window_config(GLFWwindow * window, bool use_mouse_indev) -{ - glfwMakeContextCurrent(window); - - glfwSwapInterval(1); - - glfwSetFramebufferSizeCallback(window, framebuffer_size_callback); - - if(use_mouse_indev) { - glfwSetMouseButtonCallback(window, mouse_button_callback); - glfwSetCursorPosCallback(window, mouse_move_callback); - } - - glfwSetKeyCallback(window, key_callback); - - glfwSetWindowCloseCallback(window, window_close_callback); -} - -static void lv_glfw_window_quit(void) -{ - lv_timer_delete(update_handler_timer); - update_handler_timer = NULL; - - glfwTerminate(); - glfw_inited = false; - - lv_deinit(); - - exit(0); -} - -static void window_update_handler(lv_timer_t * t) -{ - LV_UNUSED(t); - - lv_glfw_window_t * window; - - glfwPollEvents(); - - /* delete windows that are ready to close */ - window = lv_ll_get_head(&glfw_window_ll); - while(window) { - lv_glfw_window_t * window_to_delete = window->closing ? window : NULL; - window = lv_ll_get_next(&glfw_window_ll, window); - if(window_to_delete) { - glfwSetWindowShouldClose(window_to_delete->window, GLFW_TRUE); - lv_glfw_window_delete(window_to_delete); - } - } - - /* render each window */ - LV_LL_READ(&glfw_window_ll, window) { - glfwMakeContextCurrent(window->window); - lv_opengles_viewport(0, 0, window->hor_res, window->ver_res); - lv_opengles_render_clear(); - - /* render each texture in the window */ - lv_glfw_texture_t * texture; - LV_LL_READ(&window->textures, texture) { - /* if the added texture is an LVGL opengles texture display, refresh it before rendering it */ - lv_display_t * texture_disp = lv_opengles_texture_get_from_texture_id(texture->texture_id); - if(texture_disp != NULL) { - lv_refr_now(texture_disp); - } - - lv_area_t clip_area = texture->area; -#if LV_USE_DRAW_OPENGLES - lv_opengles_render_texture(texture->texture_id, &texture->area, texture->opa, window->hor_res, window->ver_res, - &clip_area, texture_disp == NULL); -#else - lv_opengles_render_texture(texture->texture_id, &texture->area, texture->opa, window->hor_res, window->ver_res, - &clip_area, true); -#endif - } - - /* Swap front and back buffers */ - glfwSwapBuffers(window->window); - } -} - -static void glfw_error_cb(int error, const char * description) -{ - LV_LOG_ERROR("GLFW Error %d: %s", error, description); -} - -static lv_glfw_window_t * lv_glfw_get_lv_window_from_window(GLFWwindow * window) -{ - return glfwGetWindowUserPointer(window); -} - -static void window_close_callback(GLFWwindow * window) -{ - lv_glfw_window_t * lv_window = lv_glfw_get_lv_window_from_window(window); - lv_window->closing = 1; -} - -static void key_callback(GLFWwindow * window, int key, int scancode, int action, int mods) -{ - LV_UNUSED(scancode); - LV_UNUSED(mods); - if(key == GLFW_KEY_ESCAPE && action == GLFW_PRESS) { - lv_glfw_window_t * lv_window = lv_glfw_get_lv_window_from_window(window); - lv_window->closing = 1; - } -} - -static void mouse_button_callback(GLFWwindow * window, int button, int action, int mods) -{ - LV_UNUSED(mods); - if(button == GLFW_MOUSE_BUTTON_LEFT) { - lv_glfw_window_t * lv_window = lv_glfw_get_lv_window_from_window(window); - lv_window->mouse_last_state = action == GLFW_PRESS ? LV_INDEV_STATE_PRESSED : LV_INDEV_STATE_RELEASED; - proc_mouse(lv_window); - } -} - -static void mouse_move_callback(GLFWwindow * window, double xpos, double ypos) -{ - lv_glfw_window_t * lv_window = lv_glfw_get_lv_window_from_window(window); - lv_window->mouse_last_point.x = (int32_t)xpos; - lv_window->mouse_last_point.y = (int32_t)ypos; - proc_mouse(lv_window); -} - -static void proc_mouse(lv_glfw_window_t * window) -{ - /* mouse activity will affect the topmost LVGL display texture */ - lv_glfw_texture_t * texture; - LV_LL_READ_BACK(&window->textures, texture) { - if(lv_area_is_point_on(&texture->area, &window->mouse_last_point, 0)) { - /* adjust the mouse pointer coordinates so that they are relative to the texture */ - texture->indev_last_point.x = window->mouse_last_point.x - texture->area.x1; - texture->indev_last_point.y = window->mouse_last_point.y - texture->area.y1; - texture->indev_last_state = window->mouse_last_state; - lv_indev_read(texture->indev); - break; - } - } -} - -static void indev_read_cb(lv_indev_t * indev, lv_indev_data_t * data) -{ - lv_glfw_texture_t * texture = lv_indev_get_driver_data(indev); - data->point = texture->indev_last_point; - data->state = texture->indev_last_state; -} - -static void framebuffer_size_callback(GLFWwindow * window, int width, int height) -{ - lv_glfw_window_t * lv_window = lv_glfw_get_lv_window_from_window(window); - lv_window->hor_res = width; - lv_window->ver_res = height; -} - -static uint32_t lv_glfw_tick_count_callback(void) -{ - double tick = glfwGetTime() * 1000.0; - return (uint32_t)tick; -} - -#endif /*LV_USE_OPENGLES*/ diff --git a/src/drivers/glfw/lv_glfw_window.h b/src/drivers/glfw/lv_glfw_window.h deleted file mode 100644 index 81c289e7ce..0000000000 --- a/src/drivers/glfw/lv_glfw_window.h +++ /dev/null @@ -1,115 +0,0 @@ -/** - * @file lv_glfw_window.h - * - */ - -#ifndef LV_GLFW_WINDOW_H -#define LV_GLFW_WINDOW_H - -#ifdef __cplusplus -extern "C" { -#endif - -/********************* - * INCLUDES - *********************/ - -#include "../../lv_conf_internal.h" -#if LV_USE_OPENGLES - -#include "../../misc/lv_types.h" -#include "../../display/lv_display.h" - -/********************* - * DEFINES - *********************/ - -/********************** - * TYPEDEFS - **********************/ - -/********************** - * GLOBAL PROTOTYPES - **********************/ - -/** - * Create a GLFW window with no textures and initialize OpenGL - * @param hor_res width in pixels of the window - * @param ver_res height in pixels of the window - * @param use_mouse_indev send pointer indev input to LVGL display textures - * @return the new GLFW window handle - */ -lv_glfw_window_t * lv_glfw_window_create(int32_t hor_res, int32_t ver_res, bool use_mouse_indev); - -/** - * Delete a GLFW window. If it is the last one, the process will exit - * @param window GLFW window to delete - */ -void lv_glfw_window_delete(lv_glfw_window_t * window); - -/** - * Get the GLFW window handle for an lv_glfw_window - * @param window GLFW window to return the handle of - * @return the GLFW window handle - */ -void * lv_glfw_window_get_glfw_window(lv_glfw_window_t * window); - -/** - * Add a texture to the GLFW window. It can be an LVGL display texture, or any OpenGL texture - * @param window GLFW window - * @param texture_id OpenGL texture ID - * @param w width in pixels of the texture - * @param h height in pixels of the texture - * @return the new texture handle - */ -lv_glfw_texture_t * lv_glfw_window_add_texture(lv_glfw_window_t * window, unsigned int texture_id, int32_t w, - int32_t h); - -/** - * Remove a texture from its GLFW window and delete it - * @param texture handle of a GLFW window texture - */ -void lv_glfw_texture_remove(lv_glfw_texture_t * texture); - -/** - * Set the x position of a texture within its GLFW window - * @param texture handle of a GLFW window texture - * @param x new x position of the texture - */ -void lv_glfw_texture_set_x(lv_glfw_texture_t * texture, int32_t x); - -/** - * Set the y position of a texture within its GLFW window - * @param texture handle of a GLFW window texture - * @param y new y position of the texture - */ -void lv_glfw_texture_set_y(lv_glfw_texture_t * texture, int32_t y); - -/** - * Set the opacity of a texture in a GLFW window - * @param texture handle of a GLFW window texture - * @param opa new opacity of the texture - */ -void lv_glfw_texture_set_opa(lv_glfw_texture_t * texture, lv_opa_t opa); - -/** - * Get the mouse indev associated with a texture in a GLFW window, if it exists - * @param texture handle of a GLFW window texture - * @return the indev or `NULL` - * @note there will only be an indev if the texture is based on an - * LVGL display texture and the window was created with - * `use_mouse_indev` as `true` - */ -lv_indev_t * lv_glfw_texture_get_mouse_indev(lv_glfw_texture_t * texture); - -/********************** - * MACROS - **********************/ - -#endif /* LV_USE_OPENGLES */ - -#ifdef __cplusplus -} /* extern "C" */ -#endif - -#endif /* LV_GLFW_WINDOW_H */ diff --git a/src/drivers/glfw/lv_glfw_window_private.h b/src/drivers/glfw/lv_glfw_window_private.h deleted file mode 100644 index cc6cac09e8..0000000000 --- a/src/drivers/glfw/lv_glfw_window_private.h +++ /dev/null @@ -1,70 +0,0 @@ -/** - * @file lv_glfw_window_private.h - * - */ - -#ifndef LV_GLFW_WINDOW_PRIVATE_H -#define LV_GLFW_WINDOW_PRIVATE_H - -#ifdef __cplusplus -extern "C" { -#endif - -/********************* - * INCLUDES - *********************/ - -#include "lv_glfw_window.h" -#if LV_USE_OPENGLES - -#include -#include - -#include "../../misc/lv_area.h" -#include "../../display/lv_display.h" -#include "../../indev/lv_indev.h" - -/********************* - * DEFINES - *********************/ - -/********************** - * TYPEDEFS - **********************/ - -struct _lv_glfw_window_t { - GLFWwindow * window; - int32_t hor_res; - int32_t ver_res; - lv_ll_t textures; - lv_point_t mouse_last_point; - lv_indev_state_t mouse_last_state; - uint8_t use_indev : 1; - uint8_t closing : 1; -}; - -struct _lv_glfw_texture_t { - lv_glfw_window_t * window; - unsigned int texture_id; - lv_area_t area; - lv_opa_t opa; - lv_indev_t * indev; - lv_point_t indev_last_point; - lv_indev_state_t indev_last_state; -}; - -/********************** - * GLOBAL PROTOTYPES - **********************/ - -/********************** - * MACROS - **********************/ - -#endif /*LV_USE_OPENGLES*/ - -#ifdef __cplusplus -} /*extern "C"*/ -#endif - -#endif /*LV_GLFW_WINDOW_PRIVATE_H*/ diff --git a/src/drivers/glfw/lv_opengles_driver.c b/src/drivers/glfw/lv_opengles_driver.c deleted file mode 100644 index 1f46f63b89..0000000000 --- a/src/drivers/glfw/lv_opengles_driver.c +++ /dev/null @@ -1,499 +0,0 @@ -/** - * @file lv_opengles_driver.c - * - */ - -/********************* - * INCLUDES - *********************/ -#include "../../display/lv_display.h" -#include "../../misc/lv_area_private.h" - -#if LV_USE_OPENGLES - -#include "lv_opengles_debug.h" -#include "lv_opengles_driver.h" - -/********************* - * DEFINES - *********************/ - -#define LV_OPENGLES_VERTEX_BUFFER_LEN 16 - -/********************** - * TYPEDEFS - **********************/ - -/********************** - * STATIC PROTOTYPES - **********************/ -static void lv_opengles_render_internal(unsigned int texture, const lv_area_t * texture_area, lv_opa_t opa, - int32_t disp_w, int32_t disp_h, const lv_area_t * texture_clip_area, bool flip, lv_color_t fill_color); -static void lv_opengles_enable_blending(void); -static void lv_opengles_vertex_buffer_init(const void * data, unsigned int size); -static void lv_opengles_vertex_buffer_deinit(void); -static void lv_opengles_vertex_buffer_bind(void); -static void lv_opengles_vertex_buffer_unbind(void); -static void lv_opengles_vertex_array_init(void); -static void lv_opengles_vertex_array_deinit(void); -static void lv_opengles_vertex_array_bind(void); -static void lv_opengles_vertex_array_unbind(void); -static void lv_opengles_vertex_array_add_buffer(void); -static void lv_opengles_index_buffer_init(const unsigned int * data, unsigned int count); -static void lv_opengles_index_buffer_deinit(void); -static unsigned int lv_opengles_index_buffer_get_count(void); -static void lv_opengles_index_buffer_bind(void); -static void lv_opengles_index_buffer_unbind(void); -static unsigned int lv_opengles_shader_compile(unsigned int type, const char * source); -static unsigned int lv_opengles_shader_create(const char * vertexShader, const char * fragmentShader); -static void lv_opengles_shader_init(void); -static void lv_opengles_shader_deinit(void); -static void lv_opengles_shader_bind(void); -static void lv_opengles_shader_unbind(void); -static int lv_opengles_shader_get_uniform_location(const char * name); -static void lv_opengles_shader_set_uniform1i(const char * name, int value); -static void lv_opengles_shader_set_uniformmatrix3fv(const char * name, int count, bool transpose, const float * values); -static void lv_opengles_shader_set_uniform1f(const char * name, float value); -static void lv_opengles_shader_set_uniform3f(const char * name, float value_0, float value_1, float value_2); -static void lv_opengles_render_draw(void); -static float lv_opengles_map_float(float x, float min_in, float max_in, float min_out, float max_out); - -/*********************** - * GLOBAL PROTOTYPES - ***********************/ - -/********************** - * STATIC VARIABLES - **********************/ -static bool is_init; - -static unsigned int vertex_buffer_id = 0; - -static unsigned int vertex_array_id = 0; - -static unsigned int index_buffer_id = 0; -static unsigned int index_buffer_count = 0; - -static unsigned int shader_id; - -static const char * shader_names[] = { "u_Texture", "u_ColorDepth", "u_VertexTransform", "u_Opa", "u_IsFill", "u_FillColor" }; -static int shader_location[] = { 0, 0, 0, 0, 0, 0 }; - -static const char * vertex_shader = - "#version 300 es\n" - "\n" - "in vec4 position;\n" - "in vec2 texCoord;\n" - "\n" - "out vec2 v_TexCoord;\n" - "\n" - "uniform mat3 u_VertexTransform;\n" - "\n" - "void main()\n" - "{\n" - " gl_Position = vec4((u_VertexTransform * vec3(position.xy, 1)).xy, position.zw);\n" - " v_TexCoord = texCoord;\n" - "};\n"; - -static const char * fragment_shader = - "#version 300 es\n" - "\n" - "precision lowp float;\n" - "\n" - "layout(location = 0) out vec4 color;\n" - "\n" - "in vec2 v_TexCoord;\n" - "\n" - "uniform sampler2D u_Texture;\n" - "uniform int u_ColorDepth;\n" - "uniform float u_Opa;\n" - "uniform bool u_IsFill;\n" - "uniform vec3 u_FillColor;\n" - "\n" - "void main()\n" - "{\n" - " vec4 texColor;\n" - " if (u_IsFill) {\n" - " texColor = vec4(u_FillColor, 1.0f);\n" - " } else {\n" - " texColor = texture(u_Texture, v_TexCoord);\n" - " }\n" - " if (u_ColorDepth == 8) {\n" - " float gray = texColor.r;\n" - " color = vec4(gray, gray, gray, u_Opa);\n" - " } else {\n" - " float combinedAlpha = texColor.a * u_Opa;\n" - " color = vec4(texColor.rgb * combinedAlpha, combinedAlpha);\n" - " }\n" - "};\n"; - -/********************** - * MACROS - **********************/ - -/********************** - * GLOBAL FUNCTIONS - **********************/ - -void lv_opengles_init(void) -{ - if(is_init) return; - - lv_opengles_enable_blending(); - - unsigned int indices[] = { - 0, 1, 2, - 2, 3, 0 - }; - - lv_opengles_vertex_buffer_init(NULL, sizeof(float) * LV_OPENGLES_VERTEX_BUFFER_LEN); - - lv_opengles_vertex_array_init(); - lv_opengles_vertex_array_add_buffer(); - - lv_opengles_index_buffer_init(indices, 6); - - lv_opengles_shader_init(); - lv_opengles_shader_bind(); - - /* unbind everything */ - lv_opengles_vertex_array_unbind(); - lv_opengles_vertex_buffer_unbind(); - lv_opengles_index_buffer_unbind(); - lv_opengles_shader_unbind(); - - is_init = true; -} - -void lv_opengles_deinit(void) -{ - if(!is_init) return; - - lv_opengles_shader_deinit(); - lv_opengles_index_buffer_deinit(); - lv_opengles_vertex_buffer_deinit(); - lv_opengles_vertex_array_deinit(); - - is_init = false; -} - -void lv_opengles_render_texture(unsigned int texture, const lv_area_t * texture_area, lv_opa_t opa, int32_t disp_w, - int32_t disp_h, const lv_area_t * texture_clip_area, bool flip) -{ - lv_opengles_render_internal(texture, texture_area, opa, disp_w, disp_h, texture_clip_area, flip, lv_color_black()); -} - -void lv_opengles_render_fill(lv_color_t color, const lv_area_t * area, lv_opa_t opa, int32_t disp_w, int32_t disp_h) -{ - lv_opengles_render_internal(0, area, opa, disp_w, disp_h, area, false, color); -} - -void lv_opengles_render_clear(void) -{ - GL_CALL(glClear(GL_COLOR_BUFFER_BIT)); -} - -void lv_opengles_viewport(int32_t x, int32_t y, int32_t w, int32_t h) -{ - glViewport(x, y, w, h); -} - -/********************** - * STATIC FUNCTIONS - **********************/ - -static void lv_opengles_render_internal(unsigned int texture, const lv_area_t * texture_area, lv_opa_t opa, - int32_t disp_w, int32_t disp_h, const lv_area_t * texture_clip_area, bool flip, lv_color_t fill_color) -{ - lv_area_t intersection; - if(!lv_area_intersect(&intersection, texture_area, texture_clip_area)) return; - - GL_CALL(glActiveTexture(GL_TEXTURE0)); - GL_CALL(glBindTexture(GL_TEXTURE_2D, texture)); - - float tex_w = (float)lv_area_get_width(&intersection); - float tex_h = (float)lv_area_get_height(&intersection); - - float hor_scale = tex_w / (float)disp_w; - float ver_scale = tex_h / (float)disp_h; - float hor_translate = (float)intersection.x1 / (float)disp_w * 2.0f - (1.0f - hor_scale); - float ver_translate = -((float)intersection.y1 / (float)disp_h * 2.0f - (1.0f - ver_scale)); - if(flip) ver_scale = -ver_scale; - float matrix[9] = { - hor_scale, 0.0f, hor_translate, - 0.0f, ver_scale, ver_translate, - 0.0f, 0.0f, 1.0f - }; - - if(texture != 0) { - float x_coef = 1.0f / (float)(2 * lv_area_get_width(texture_area)); - float y_coef = 1.0f / (float)(2 * lv_area_get_height(texture_area)); - float tex_clip_x1 = lv_opengles_map_float(texture_clip_area->x1, texture_area->x1, texture_area->x2, x_coef, - 1.0f - x_coef); - float tex_clip_x2 = lv_opengles_map_float(texture_clip_area->x2, texture_area->x1, texture_area->x2, x_coef, - 1.0f - x_coef); - float tex_clip_y1 = lv_opengles_map_float(texture_clip_area->y1, texture_area->y1, texture_area->y2, y_coef, - 1.0f - y_coef); - float tex_clip_y2 = lv_opengles_map_float(texture_clip_area->y2, texture_area->y1, texture_area->y2, y_coef, - 1.0f - y_coef); - - float positions[LV_OPENGLES_VERTEX_BUFFER_LEN] = { - -1.0f, 1.0f, tex_clip_x1, tex_clip_y2, - 1.0f, 1.0f, tex_clip_x2, tex_clip_y2, - 1.0f, -1.0f, tex_clip_x2, tex_clip_y1, - -1.0f, -1.0f, tex_clip_x1, tex_clip_y1 - }; - lv_opengles_vertex_buffer_init(positions, sizeof(positions)); - } - - lv_opengles_shader_bind(); - lv_opengles_shader_set_uniform1i("u_ColorDepth", LV_COLOR_DEPTH); - lv_opengles_shader_set_uniform1i("u_Texture", 0); - lv_opengles_shader_set_uniformmatrix3fv("u_VertexTransform", 1, true, matrix); - lv_opengles_shader_set_uniform1f("u_Opa", (float)opa / (float)LV_OPA_100); - lv_opengles_shader_set_uniform1i("u_IsFill", texture == 0); - lv_opengles_shader_set_uniform3f("u_FillColor", (float)fill_color.red / 255.0f, (float)fill_color.green / 255.0f, - (float)fill_color.blue / 255.0f); - lv_opengles_render_draw(); -} - -static void lv_opengles_enable_blending(void) -{ - glEnable(GL_BLEND); - glBlendFunc(GL_ONE, GL_ONE_MINUS_SRC_ALPHA); -} - -static void lv_opengles_vertex_buffer_init(const void * data, unsigned int size) -{ - if(vertex_buffer_id == 0) GL_CALL(glGenBuffers(1, &vertex_buffer_id)); - GL_CALL(glBindBuffer(GL_ARRAY_BUFFER, vertex_buffer_id)); - GL_CALL(glBufferData(GL_ARRAY_BUFFER, size, data, GL_DYNAMIC_DRAW)); -} - -static void lv_opengles_vertex_buffer_deinit(void) -{ - if(vertex_buffer_id == 0) return; - GL_CALL(glDeleteBuffers(1, &vertex_buffer_id)); - vertex_buffer_id = 0; -} - -static void lv_opengles_vertex_buffer_bind(void) -{ - GL_CALL(glBindBuffer(GL_ARRAY_BUFFER, vertex_buffer_id)); -} - -static void lv_opengles_vertex_buffer_unbind(void) -{ - GL_CALL(glBindBuffer(GL_ARRAY_BUFFER, 0)); -} - -static void lv_opengles_vertex_array_init(void) -{ - if(vertex_array_id == 0) GL_CALL(glGenVertexArrays(1, &vertex_array_id)); -} - -static void lv_opengles_vertex_array_deinit(void) -{ - if(vertex_array_id == 0) return; - GL_CALL(glDeleteVertexArrays(1, &vertex_array_id)); - vertex_array_id = 0; -} - -static void lv_opengles_vertex_array_bind(void) -{ - GL_CALL(glBindVertexArray(vertex_array_id)); -} - -static void lv_opengles_vertex_array_unbind(void) -{ - GL_CALL(glBindVertexArray(0)); -} - -static void lv_opengles_vertex_array_add_buffer(void) -{ - lv_opengles_vertex_buffer_bind(); - intptr_t offset = 0; - - for(unsigned int i = 0; i < 2; i++) { - lv_opengles_vertex_array_bind(); - GL_CALL(glEnableVertexAttribArray(i)); - GL_CALL(glVertexAttribPointer(i, 2, GL_FLOAT, GL_FALSE, 16, (const void *)offset)); - offset += 2 * 4; - } -} - -static void lv_opengles_index_buffer_init(const unsigned int * data, unsigned int count) -{ - index_buffer_count = count; - if(index_buffer_id == 0) GL_CALL(glGenBuffers(1, &index_buffer_id)); - - GL_CALL(glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, index_buffer_id)); - - GL_CALL(glBufferData(GL_ELEMENT_ARRAY_BUFFER, count * sizeof(GLuint), data, GL_STATIC_DRAW)); -} - -static void lv_opengles_index_buffer_deinit(void) -{ - if(index_buffer_id == 0) return; - GL_CALL(glDeleteBuffers(1, &index_buffer_id)); - index_buffer_id = 0; -} - -static unsigned int lv_opengles_index_buffer_get_count(void) -{ - return index_buffer_count; -} - -static void lv_opengles_index_buffer_bind(void) -{ - GL_CALL(glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, index_buffer_id)); -} - -static void lv_opengles_index_buffer_unbind(void) -{ - GL_CALL(glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0)); -} - -static unsigned int lv_opengles_shader_compile(unsigned int type, const char * source) -{ - unsigned int id; - GL_CALL(id = glCreateShader(type)); - const char * src = source; - GL_CALL(glShaderSource(id, 1, &src, NULL)); - GL_CALL(glCompileShader(id)); - - int result; - GL_CALL(glGetShaderiv(id, GL_COMPILE_STATUS, &result)); - if(result == GL_FALSE) { - int length; - GL_CALL(glGetShaderiv(id, GL_INFO_LOG_LENGTH, &length)); - char * message = lv_malloc_zeroed(length * sizeof(char)); - GL_CALL(glGetShaderInfoLog(id, length, &length, message)); - LV_LOG_ERROR("Failed to compile %s shader!", type == GL_VERTEX_SHADER ? "vertex" : "fragment"); - LV_LOG_ERROR("%s", message); - GL_CALL(glDeleteShader(id)); - return 0; - } - - return id; -} - -static unsigned int lv_opengles_shader_create(const char * vertexShader, const char * fragmentShader) -{ - unsigned int program; - GL_CALL(program = glCreateProgram()); - unsigned int vs = lv_opengles_shader_compile(GL_VERTEX_SHADER, vertexShader); - unsigned int fs = lv_opengles_shader_compile(GL_FRAGMENT_SHADER, fragmentShader); - - GL_CALL(glAttachShader(program, vs)); - GL_CALL(glAttachShader(program, fs)); - GL_CALL(glLinkProgram(program)); - GL_CALL(glValidateProgram(program)); - - GL_CALL(glDeleteShader(vs)); - GL_CALL(glDeleteShader(fs)); - - return program; -} - -static void lv_opengles_shader_init(void) -{ - if(shader_id == 0) shader_id = lv_opengles_shader_create(vertex_shader, fragment_shader); -} - -static void lv_opengles_shader_deinit(void) -{ - if(shader_id == 0) return; - GL_CALL(glDeleteProgram(shader_id)); - shader_id = 0; -} - -static void lv_opengles_shader_bind(void) -{ - GL_CALL(glUseProgram(shader_id)); -} - -static void lv_opengles_shader_unbind(void) -{ - GL_CALL(glUseProgram(0)); -} - -static int lv_opengles_shader_get_uniform_location(const char * name) -{ - int id = -1; - for(size_t i = 0; i < sizeof(shader_location) / sizeof(int); i++) { - if(lv_strcmp(shader_names[i], name) == 0) { - id = i; - } - } - if(id == -1) { - return -1; - } - - if(shader_location[id] != 0) { - return shader_location[id]; - } - - int location; - GL_CALL(location = glGetUniformLocation(shader_id, name)); - if(location == -1) - LV_LOG_WARN("Warning: uniform '%s' doesn't exist!", name); - - shader_location[id] = location; - return location; -} - -static void lv_opengles_shader_set_uniform1i(const char * name, int value) -{ - GL_CALL(glUniform1i(lv_opengles_shader_get_uniform_location(name), value)); -} - -static void lv_opengles_shader_set_uniformmatrix3fv(const char * name, int count, bool transpose, const float * values) -{ - GL_CALL(glUniformMatrix3fv(lv_opengles_shader_get_uniform_location(name), count, transpose, values)); -} - -static void lv_opengles_shader_set_uniform1f(const char * name, float value) -{ - GL_CALL(glUniform1f(lv_opengles_shader_get_uniform_location(name), value)); -} - -static void lv_opengles_shader_set_uniform3f(const char * name, float value_0, float value_1, float value_2) -{ - GL_CALL(glUniform3f(lv_opengles_shader_get_uniform_location(name), value_0, value_1, value_2)); -} - -static void lv_opengles_render_draw(void) -{ - lv_opengles_shader_bind(); - lv_opengles_vertex_array_bind(); - lv_opengles_index_buffer_bind(); - unsigned int count = lv_opengles_index_buffer_get_count(); - GL_CALL(glDrawElements(GL_TRIANGLES, count, GL_UNSIGNED_INT, NULL)); -} - -/** - * Copied from `lv_map` in lv_math.h to operate on floats - */ -static float lv_opengles_map_float(float x, float min_in, float max_in, float min_out, float max_out) -{ - if(max_in >= min_in && x >= max_in) return max_out; - if(max_in >= min_in && x <= min_in) return min_out; - - if(max_in <= min_in && x <= max_in) return max_out; - if(max_in <= min_in && x >= min_in) return min_out; - - /** - * The equation should be: - * ((x - min_in) * delta_out) / delta in) + min_out - * To avoid rounding error reorder the operations: - * (x - min_in) * (delta_out / delta_min) + min_out - */ - - float delta_in = max_in - min_in; - float delta_out = max_out - min_out; - - return ((x - min_in) * delta_out) / delta_in + min_out; -} - -#endif /* LV_USE_OPENGLES */ diff --git a/src/drivers/glfw/lv_opengles_texture.c b/src/drivers/glfw/lv_opengles_texture.c deleted file mode 100644 index a719a7846d..0000000000 --- a/src/drivers/glfw/lv_opengles_texture.c +++ /dev/null @@ -1,177 +0,0 @@ -/** - * @file lv_opengles_texture.c - * - */ - -/********************* - * INCLUDES - *********************/ - -#include "lv_opengles_texture.h" -#if LV_USE_OPENGLES - -#include "lv_opengles_debug.h" -#include "../../display/lv_display_private.h" -#include -#include -#include - -/********************* - * DEFINES - *********************/ - -/********************** - * TYPEDEFS - **********************/ - -typedef struct { - unsigned int texture_id; - uint8_t * fb1; -} lv_opengles_texture_t; - -/********************** - * STATIC PROTOTYPES - **********************/ - -static void flush_cb(lv_display_t * disp, const lv_area_t * area, uint8_t * px_map); -static void release_disp_cb(lv_event_t * e); - -/********************** - * STATIC VARIABLES - **********************/ - -/********************** - * MACROS - **********************/ - -/********************** - * GLOBAL FUNCTIONS - **********************/ - -lv_display_t * lv_opengles_texture_create(int32_t w, int32_t h) -{ - lv_display_t * disp = lv_display_create(w, h); - if(disp == NULL) { - return NULL; - } - lv_opengles_texture_t * dsc = lv_malloc_zeroed(sizeof(lv_opengles_texture_t)); - LV_ASSERT_MALLOC(dsc); - if(dsc == NULL) { - lv_display_delete(disp); - return NULL; - } - uint32_t stride = lv_draw_buf_width_to_stride(w, lv_display_get_color_format(disp)); - uint32_t buf_size = stride * h; - dsc->fb1 = malloc(buf_size); - if(dsc->fb1 == NULL) { - lv_free(dsc); - lv_display_delete(disp); - return NULL; - } - - GL_CALL(glGenTextures(1, &dsc->texture_id)); - GL_CALL(glBindTexture(GL_TEXTURE_2D, dsc->texture_id)); - GL_CALL(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST)); - GL_CALL(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST)); - GL_CALL(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE)); - GL_CALL(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE)); - GL_CALL(glPixelStorei(GL_UNPACK_ALIGNMENT, 1)); - - /* set the dimensions and format to complete the texture */ - /* Color depth: 8 (L8), 16 (RGB565), 24 (RGB888), 32 (XRGB8888) */ -#if LV_COLOR_DEPTH == 8 - GL_CALL(glTexImage2D(GL_TEXTURE_2D, 0, GL_R8, disp->hor_res, disp->ver_res, 0, GL_RED, GL_UNSIGNED_BYTE, NULL)); -#elif LV_COLOR_DEPTH == 16 - GL_CALL(glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB565, disp->hor_res, disp->ver_res, 0, GL_RGB, GL_UNSIGNED_SHORT_5_6_5, - NULL)); -#elif LV_COLOR_DEPTH == 24 - GL_CALL(glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, disp->hor_res, disp->ver_res, 0, GL_BGR, GL_UNSIGNED_BYTE, NULL)); -#elif LV_COLOR_DEPTH == 32 - GL_CALL(glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, disp->hor_res, disp->ver_res, 0, GL_BGRA, GL_UNSIGNED_BYTE, NULL)); -#else -#error("Unsupported color format") -#endif - - glGenerateMipmap(GL_TEXTURE_2D); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, 20); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST_MIPMAP_NEAREST); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); - - lv_display_set_buffers(disp, dsc->fb1, NULL, buf_size, LV_DISPLAY_RENDER_MODE_DIRECT); - lv_display_set_flush_cb(disp, flush_cb); - lv_display_set_driver_data(disp, dsc); - lv_display_add_event_cb(disp, release_disp_cb, LV_EVENT_DELETE, disp); - - return disp; -} - -unsigned int lv_opengles_texture_get_texture_id(lv_display_t * disp) -{ - if(disp->flush_cb != flush_cb) { - return 0; - } - lv_opengles_texture_t * dsc = lv_display_get_driver_data(disp); - return dsc->texture_id; -} - -lv_display_t * lv_opengles_texture_get_from_texture_id(unsigned int texture_id) -{ - lv_display_t * disp = NULL; - while(NULL != (disp = lv_display_get_next(disp))) { - unsigned int disp_texture_id = lv_opengles_texture_get_texture_id(disp); - if(disp_texture_id == texture_id) { - return disp; - } - } - return NULL; -} - -/********************** - * STATIC FUNCTIONS - **********************/ - -static void flush_cb(lv_display_t * disp, const lv_area_t * area, uint8_t * px_map) -{ - LV_UNUSED(area); - LV_UNUSED(px_map); - -#if !LV_USE_DRAW_OPENGLES - if(lv_display_flush_is_last(disp)) { - - lv_opengles_texture_t * dsc = lv_display_get_driver_data(disp); - lv_color_format_t cf = lv_display_get_color_format(disp); - uint32_t stride = lv_draw_buf_width_to_stride(lv_display_get_horizontal_resolution(disp), cf); - - GL_CALL(glBindTexture(GL_TEXTURE_2D, dsc->texture_id)); - - GL_CALL(glPixelStorei(GL_UNPACK_ALIGNMENT, 1)); - GL_CALL(glPixelStorei(GL_UNPACK_ROW_LENGTH, stride / lv_color_format_get_size(cf))); - /*Color depth: 8 (L8), 16 (RGB565), 24 (RGB888), 32 (XRGB8888)*/ -#if LV_COLOR_DEPTH == 8 - GL_CALL(glTexImage2D(GL_TEXTURE_2D, 0, GL_R8, disp->hor_res, disp->ver_res, 0, GL_RED, GL_UNSIGNED_BYTE, dsc->fb1)); -#elif LV_COLOR_DEPTH == 16 - GL_CALL(glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB565, disp->hor_res, disp->ver_res, 0, GL_RGB, GL_UNSIGNED_SHORT_5_6_5, - dsc->fb1)); -#elif LV_COLOR_DEPTH == 24 - GL_CALL(glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, disp->hor_res, disp->ver_res, 0, GL_BGR, GL_UNSIGNED_BYTE, dsc->fb1)); -#elif LV_COLOR_DEPTH == 32 - GL_CALL(glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, disp->hor_res, disp->ver_res, 0, GL_BGRA, GL_UNSIGNED_BYTE, dsc->fb1)); -#else -#error("Unsupported color format") -#endif - } -#endif /* !LV_USE_DRAW_OPENGLES */ - - lv_display_flush_ready(disp); -} - -static void release_disp_cb(lv_event_t * e) -{ - lv_display_t * disp = lv_event_get_user_data(e); - lv_opengles_texture_t * dsc = lv_display_get_driver_data(disp); - free(dsc->fb1); - GL_CALL(glDeleteTextures(1, &dsc->texture_id)); - lv_free(dsc); -} - -#endif /*LV_USE_OPENGLES*/ diff --git a/src/drivers/libinput/lv_xkb.h b/src/drivers/libinput/lv_xkb.h index 3f9fd86eab..5f45d99992 100644 --- a/src/drivers/libinput/lv_xkb.h +++ b/src/drivers/libinput/lv_xkb.h @@ -55,10 +55,10 @@ uint32_t lv_xkb_process_key(lv_xkb_t * dsc, uint32_t scancode, bool down); * MACROS **********************/ -#endif /* LV_LIBINPUT_XKB */ +#endif /* defined(LV_LIBINPUT_XKB) && LV_LIBINPUT_XKB */ #ifdef __cplusplus } /* extern "C" */ #endif -#endif /* defined(LV_LIBINPUT_XKB) && LV_LIBINPUT_XKB */ +#endif /* LV_XKB_H */ diff --git a/src/drivers/lv_drivers.h b/src/drivers/lv_drivers.h index 0850108132..8cc91ce21a 100644 --- a/src/drivers/lv_drivers.h +++ b/src/drivers/lv_drivers.h @@ -24,17 +24,22 @@ extern "C" { #include "display/fb/lv_linux_fbdev.h" #include "display/tft_espi/lv_tft_espi.h" +#include "display/lovyan_gfx/lv_lovyan_gfx.h" #include "display/lcd/lv_lcd_generic_mipi.h" #include "display/ili9341/lv_ili9341.h" #include "display/st7735/lv_st7735.h" #include "display/st7789/lv_st7789.h" #include "display/st7796/lv_st7796.h" +#include "display/nv3007/lv_nv3007.h" #include "display/renesas_glcdc/lv_renesas_glcdc.h" #include "display/st_ltdc/lv_st_ltdc.h" #include "display/ft81x/lv_ft81x.h" +#include "draw/eve/lv_draw_eve_display.h" +#include "draw/eve/lv_draw_eve_display_defines.h" + #include "nuttx/lv_nuttx_entry.h" #include "nuttx/lv_nuttx_fbdev.h" #include "nuttx/lv_nuttx_touchscreen.h" @@ -47,9 +52,11 @@ extern "C" { #include "windows/lv_windows_input.h" #include "windows/lv_windows_display.h" -#include "glfw/lv_glfw_window.h" -#include "glfw/lv_opengles_texture.h" -#include "glfw/lv_opengles_driver.h" +#include "opengles/lv_opengles_window.h" +#include "opengles/lv_opengles_texture.h" +#include "opengles/lv_opengles_driver.h" +#include "opengles/lv_opengles_glfw.h" +#include "opengles/lv_opengles_egl.h" #include "qnx/lv_qnx.h" diff --git a/src/drivers/nuttx/lv_nuttx_entry.c b/src/drivers/nuttx/lv_nuttx_entry.c index 3f70308cd4..47c3b18ae2 100644 --- a/src/drivers/nuttx/lv_nuttx_entry.c +++ b/src/drivers/nuttx/lv_nuttx_entry.c @@ -1,5 +1,5 @@ /** - * @file lv_nuttx_entry.h + * @file lv_nuttx_entry.c * */ @@ -19,6 +19,7 @@ #include "lv_nuttx_image_cache.h" #include "../../core/lv_global.h" #include "lv_nuttx_profiler.h" +#include "lv_nuttx_mouse.h" #include "../../../lvgl.h" @@ -106,6 +107,14 @@ void lv_nuttx_dsc_init(lv_nuttx_dsc_t * dsc) #ifdef CONFIG_UINPUT_TOUCH dsc->utouch_path = "/dev/utouch"; #endif + +#if LV_USE_NUTTX_MOUSE + dsc->mouse_path = "/dev/mouse0"; +#endif + +#if LV_USE_NUTTX_TRACE_FILE + dsc->trace_path = LV_NUTTX_TRACE_FILE_PATH; +#endif } void lv_nuttx_init(const lv_nuttx_dsc_t * dsc, lv_nuttx_result_t * result) @@ -126,6 +135,9 @@ void lv_nuttx_init(const lv_nuttx_dsc_t * dsc, lv_nuttx_result_t * result) #if LV_USE_PROFILER && LV_USE_PROFILER_BUILTIN lv_nuttx_profiler_init(); +#if LV_USE_NUTTX_TRACE_FILE + lv_nuttx_profiler_set_file(dsc->trace_path); +#endif #endif if(result) { @@ -167,6 +179,15 @@ void lv_nuttx_init(const lv_nuttx_dsc_t * dsc, lv_nuttx_result_t * result) } } #endif + +#if LV_USE_NUTTX_MOUSE + if(dsc->mouse_path) { + lv_indev_t * indev = lv_nuttx_mouse_create(dsc->mouse_path); + if(result) { + result->mouse_indev = indev; + } + } +#endif } #else @@ -240,6 +261,9 @@ void lv_nuttx_deinit(lv_nuttx_result_t * result) lv_nuttx_cache_deinit(); lv_nuttx_image_cache_deinit(); +#if LV_USE_PROFILER && LV_USE_PROFILER_BUILTIN + lv_nuttx_profiler_deinit(); +#endif lv_free(nuttx_ctx_p); nuttx_ctx_p = NULL; } diff --git a/src/drivers/nuttx/lv_nuttx_entry.h b/src/drivers/nuttx/lv_nuttx_entry.h index 049e741e5f..6100b96c2c 100644 --- a/src/drivers/nuttx/lv_nuttx_entry.h +++ b/src/drivers/nuttx/lv_nuttx_entry.h @@ -35,16 +35,20 @@ typedef struct { const char * fb_path; const char * input_path; const char * utouch_path; + const char * mouse_path; + const char * trace_path; } lv_nuttx_dsc_t; typedef struct { lv_display_t * disp; lv_indev_t * indev; lv_indev_t * utouch_indev; + lv_indev_t * mouse_indev; } lv_nuttx_result_t; typedef struct _lv_nuttx_ctx_t { void * image_cache; + int trace_fd; } lv_nuttx_ctx_t; /********************** diff --git a/src/drivers/nuttx/lv_nuttx_image_cache.c b/src/drivers/nuttx/lv_nuttx_image_cache.c index b295850d0e..8171f78f3b 100644 --- a/src/drivers/nuttx/lv_nuttx_image_cache.c +++ b/src/drivers/nuttx/lv_nuttx_image_cache.c @@ -42,12 +42,12 @@ typedef struct { bool initialized; bool independent_image_heap; - lv_draw_buf_malloc_cb malloc_cb; - lv_draw_buf_free_cb free_cb; + lv_draw_buf_malloc_cb_t malloc_cb; + lv_draw_buf_free_cb_t free_cb; #if LV_NUTTX_DEFAULT_DRAW_BUF_USE_INDEPENDENT_IMAGE_HEAP - lv_draw_buf_malloc_cb malloc_cb_default; - lv_draw_buf_free_cb free_cb_default; + lv_draw_buf_malloc_cb_t malloc_cb_default; + lv_draw_buf_free_cb_t free_cb_default; #endif } lv_nuttx_ctx_image_cache_t; /********************** diff --git a/src/drivers/nuttx/lv_nuttx_mouse.c b/src/drivers/nuttx/lv_nuttx_mouse.c new file mode 100644 index 0000000000..211669408c --- /dev/null +++ b/src/drivers/nuttx/lv_nuttx_mouse.c @@ -0,0 +1,200 @@ +/** + * @file lv_nuttx_mouse.c + * + */ + +/********************* + * INCLUDES + *********************/ + +#include "lv_nuttx_mouse.h" + +#if LV_USE_NUTTX + +#if LV_USE_NUTTX_MOUSE + +#include +#include +#include +#include +#include +#include +#include +#include +#include "../../lvgl_private.h" + +/********************* + * DEFINES + *********************/ + +/********************** + * TYPEDEFS + **********************/ + +typedef struct { + int fd; + lv_indev_state_t last_state; +} lv_nuttx_mouse_t; + +/********************** + * STATIC PROTOTYPES + **********************/ +static void mouse_read(lv_indev_t * drv, lv_indev_data_t * data); +static void mouse_delete_cb(lv_event_t * e); +static lv_indev_t * mouse_init(int fd); + +/********************** + * STATIC VARIABLES + **********************/ + +/********************** + * MACROS + **********************/ + +/********************** + * GLOBAL FUNCTIONS + **********************/ + +lv_indev_t * lv_nuttx_mouse_create(const char * dev_path) +{ + lv_indev_t * indev; + int fd; + + LV_ASSERT_NULL(dev_path); + LV_LOG_USER("mouse %s opening", dev_path); + fd = open(dev_path, O_RDONLY | O_NONBLOCK); + if(fd < 0) { + LV_LOG_ERROR("Error: cannot open mouse device"); + return NULL; + } + + LV_LOG_USER("mouse %s open success", dev_path); + + indev = mouse_init(fd); + + if(indev == NULL) { + close(fd); + } + + return indev; +} + +/********************** + * STATIC FUNCTIONS + **********************/ + +static void mouse_read(lv_indev_t * drv, lv_indev_data_t * data) +{ + lv_nuttx_mouse_t * mouse = drv->driver_data; + struct mouse_report_s sample; + + /* Read one sample */ + + int nbytes = read(mouse->fd, &sample, sizeof(struct mouse_report_s)); + + /* Handle unexpected return values */ + + if(nbytes == sizeof(struct mouse_report_s)) { + lv_display_t * disp = lv_indev_get_display(drv); + int32_t hor_max = lv_display_get_horizontal_resolution(disp) - 1; + int32_t ver_max = lv_display_get_vertical_resolution(disp) - 1; + + data->point.x = + LV_CLAMP(0, + data->point.x + (sample.x * LV_USE_NUTTX_MOUSE_MOVE_STEP), + hor_max); + data->point.y = + LV_CLAMP(0, + data->point.y + (sample.y * LV_USE_NUTTX_MOUSE_MOVE_STEP), + ver_max); + + uint8_t mouse_buttons = sample.buttons; + + if(mouse_buttons & MOUSE_BUTTON_1 || mouse_buttons & MOUSE_BUTTON_2 || + mouse_buttons & MOUSE_BUTTON_3) { + mouse->last_state = LV_INDEV_STATE_PRESSED; + } + else { + mouse->last_state = LV_INDEV_STATE_RELEASED; + } + } + else { + if(nbytes == -1) { + if(errno != EAGAIN) { + LV_LOG_WARN("Read error: %s", strerror(errno)); + } + } + else if(nbytes != 0) { + LV_LOG_WARN("Unexpected read size: %d", nbytes); + } + } + + data->state = mouse->last_state; +} + +static void mouse_delete_cb(lv_event_t * e) +{ + lv_indev_t * indev = lv_event_get_user_data(e); + lv_nuttx_mouse_t * mouse = lv_indev_get_driver_data(indev); + if(mouse) { + lv_indev_set_driver_data(indev, NULL); + lv_indev_set_read_cb(indev, NULL); + + if(mouse->fd >= 0) { + close(mouse->fd); + mouse->fd = -1; + } + lv_free(mouse); + LV_LOG_USER("done"); + } +} + +static void mouse_set_cursor(lv_indev_t * indev) +{ + lv_obj_t * cursor_obj = lv_obj_create(lv_layer_sys()); + lv_obj_remove_style_all(cursor_obj); + + int32_t size = 20; + lv_obj_set_size(cursor_obj, size, size); + lv_obj_set_style_translate_x(cursor_obj, -size / 2, 0); + lv_obj_set_style_translate_y(cursor_obj, -size / 2, 0); + lv_obj_set_style_radius(cursor_obj, LV_RADIUS_CIRCLE, 0); + lv_obj_set_style_bg_opa(cursor_obj, LV_OPA_50, 0); + lv_obj_set_style_bg_color(cursor_obj, lv_color_black(), 0); + lv_obj_set_style_border_width(cursor_obj, 2, 0); + lv_obj_set_style_border_color(cursor_obj, + lv_palette_main(LV_PALETTE_GREY), 0); + lv_indev_set_cursor(indev, cursor_obj); +} + +static lv_indev_t * mouse_init(int fd) +{ + lv_nuttx_mouse_t * mouse; + lv_indev_t * indev = NULL; + + mouse = lv_malloc_zeroed(sizeof(lv_nuttx_mouse_t)); + LV_ASSERT_MALLOC(mouse); + + mouse->fd = fd; + mouse->last_state = LV_INDEV_STATE_RELEASED; + indev = lv_indev_create(); + + if(indev == NULL) { + LV_LOG_ERROR("indev create failed"); + lv_free(mouse); + return NULL; + } + + lv_indev_set_type(indev, LV_INDEV_TYPE_POINTER); + lv_indev_set_read_cb(indev, mouse_read); + lv_indev_set_driver_data(indev, mouse); + lv_indev_add_event_cb(indev, mouse_delete_cb, LV_EVENT_DELETE, indev); + + /* Set cursor icon */ + mouse_set_cursor(indev); + return indev; +} + +#endif /*LV_USE_NUTTX_MOUSE*/ + +#endif /* LV_USE_NUTTX*/ diff --git a/src/drivers/nuttx/lv_nuttx_mouse.h b/src/drivers/nuttx/lv_nuttx_mouse.h new file mode 100644 index 0000000000..dfde8e8074 --- /dev/null +++ b/src/drivers/nuttx/lv_nuttx_mouse.h @@ -0,0 +1,57 @@ +/** + * @file lv_nuttx_mouse.h + * + */ + +/********************* + * INCLUDES + *********************/ + +#ifndef LV_NUTTX_MOUSE_H +#define LV_NUTTX_MOUSE_H + +#ifdef __cplusplus +extern "C" { +#endif + +/********************* + * INCLUDES + *********************/ + +#include "../../indev/lv_indev.h" + +#if LV_USE_NUTTX + +#if LV_USE_NUTTX_MOUSE + +/********************* + * DEFINES + *********************/ + +/********************** + * TYPEDEFS + **********************/ + +/********************** + * GLOBAL PROTOTYPES + **********************/ + +/** + * Initialize indev with specified input device. + * @param dev_path path of input device + */ +lv_indev_t * lv_nuttx_mouse_create(const char * dev_path); + +/********************** + * MACROS + **********************/ + +#endif /* LV_USE_NUTTX_MOUSE */ + +#endif /* LV_USE_NUTTX*/ + +#ifdef __cplusplus +} /* extern "C" */ +#endif + +#endif /* LV_NUTTX_MOUSE_H */ diff --git a/src/drivers/nuttx/lv_nuttx_profiler.c b/src/drivers/nuttx/lv_nuttx_profiler.c index 63c1a5374d..e48fb1d0dd 100644 --- a/src/drivers/nuttx/lv_nuttx_profiler.c +++ b/src/drivers/nuttx/lv_nuttx_profiler.c @@ -13,12 +13,15 @@ #if LV_USE_NUTTX && LV_USE_PROFILER && LV_USE_PROFILER_BUILTIN #include +#include #include /********************* * DEFINES *********************/ +#define trace_fd (LV_GLOBAL_DEFAULT()->nuttx_ctx->trace_fd) + #define TICK_TO_NSEC(tick) ((tick) * 1000 / cpu_freq) /********************** @@ -55,6 +58,10 @@ void lv_nuttx_profiler_init(void) } LV_LOG_USER("CPU frequency: %" LV_PRIu32 " MHz", cpu_freq); +#if LV_USE_NUTTX_TRACE_FILE + trace_fd = -1; +#endif + lv_profiler_builtin_config_t config; lv_profiler_builtin_config_init(&config); config.tick_per_sec = 1000000000; /* 1 sec = 1000000000 nsec */ @@ -63,6 +70,31 @@ void lv_nuttx_profiler_init(void) lv_profiler_builtin_init(&config); } +void lv_nuttx_profiler_set_file(const char * file) +{ +#if LV_USE_NUTTX_TRACE_FILE + if(trace_fd >= 0) { + close(trace_fd); + } + + trace_fd = open(file, O_WRONLY | O_CREAT | O_TRUNC, 0644); + if(trace_fd < 0) { + LV_LOG_ERROR("Failed to open trace file %s, error: %d", file, errno); + } +#endif +} + +void lv_nuttx_profiler_deinit(void) +{ + lv_profiler_builtin_uninit(); +#if LV_USE_NUTTX_TRACE_FILE + if(trace_fd >= 0) { + close(trace_fd); + } + trace_fd = -1; +#endif +} + /********************** * STATIC FUNCTIONS **********************/ @@ -90,6 +122,12 @@ static uint64_t tick_get_cb(void) static void flush_cb(const char * buf) { +#if LV_USE_NUTTX_TRACE_FILE + if(trace_fd >= 0) { + write(trace_fd, buf, strlen(buf)); + return; + } +#endif printf("%s", buf); } diff --git a/src/drivers/nuttx/lv_nuttx_profiler.h b/src/drivers/nuttx/lv_nuttx_profiler.h index 8b8cf65210..01f97589eb 100644 --- a/src/drivers/nuttx/lv_nuttx_profiler.h +++ b/src/drivers/nuttx/lv_nuttx_profiler.h @@ -27,6 +27,8 @@ extern "C" { **********************/ void lv_nuttx_profiler_init(void); +void lv_nuttx_profiler_set_file(const char * file); +void lv_nuttx_profiler_deinit(void); /********************** * MACROS diff --git a/src/drivers/opengles/assets/lv_opengles_shader.c b/src/drivers/opengles/assets/lv_opengles_shader.c new file mode 100644 index 0000000000..107f1dddf7 --- /dev/null +++ b/src/drivers/opengles/assets/lv_opengles_shader.c @@ -0,0 +1,275 @@ +#include "lv_opengles_shader.h" + +#if LV_USE_OPENGLES + +#include "../opengl_shader/lv_opengl_shader_internal.h" +#include "../../../misc/lv_types.h" + +static const lv_opengl_shader_t src_includes_v100[] = {{ + "hsv_adjust.glsl", R"( + + uniform float u_Hue; + uniform float u_Saturation; + uniform float u_Value; + + // Convert RGB to HSV + vec3 rgb2hsv(vec3 c) { + vec4 K = vec4(0.0, -1.0 / 3.0, 2.0 / 3.0, -1.0); + vec4 p = mix(vec4(c.bg, K.wz), vec4(c.gb, K.xy), step(c.b, c.g)); + vec4 q = mix(vec4(p.xyw, c.r), vec4(c.r, p.yzx), step(p.x, c.r)); + float d = q.x - min(q.w, q.y); + float e = 1.0e-10; + return vec3(abs(q.z + (q.w - q.y) / (6.0 * d + e)), d / (q.x + e), q.x); + } + + // Convert HSV to RGB + vec3 hsv2rgb(vec3 c) { + vec4 K = vec4(1.0, 2.0 / 3.0, 1.0 / 3.0, 3.0); + vec3 p = abs(fract(c.xxx + K.xyz) * 6.0 - K.www); + return c.z * mix(K.xxx, clamp(p - K.xxx, 0.0, 1.0), c.y); + } + + vec3 adjustHSV(vec3 color){ + vec3 hsv = rgb2hsv(color); + hsv.x = fract(hsv.x + u_Hue); + hsv.y = clamp(hsv.y * u_Saturation, 0.0, 1.0); + hsv.z = clamp(hsv.z * u_Value, 0.0, 1.0); + return hsv2rgb(hsv); + } + )" + }, { + "brightness_adjust.glsl", R"( + uniform float u_Brightness; // add/subtract in [ -1.0 .. +1.0 ], 0.0 = no change + + vec3 adjustBrightness(vec3 color){ + return clamp(color + vec3(u_Brightness), 0.0, 1.0); + } + + )" + }, { + "contrast_adjust.glsl", R"( + uniform float u_Contrast; // 0.0 = mid-gray, 1.0 = no change, >1.0 increases contrast + + vec3 adjustContrast(vec3 color){ + // shift to [-0.5..0.5], scale, shift back + return clamp(((color - 0.5) * u_Contrast) + 0.5, 0.0, 1.0); + } + )" + }, +}; + +static const char * src_vertex_shader_v100 = R"( + precision mediump float; + + attribute vec4 position; + attribute vec2 texCoord; + + varying vec2 v_TexCoord; + + uniform mat3 u_VertexTransform; + + void main() + { + gl_Position = vec4((u_VertexTransform * vec3(position.xy, 1.0)).xy, position.zw); + v_TexCoord = texCoord; + } +)"; + +static const char *src_fragment_shader_v100 = R"( + precision lowp float; + + varying vec2 v_TexCoord; + + uniform sampler2D u_Texture; + uniform float u_ColorDepth; + uniform float u_Opa; + uniform bool u_IsFill; + uniform vec3 u_FillColor; + + #ifdef HSV_ADJUST +#include + #endif + + void main() + { + vec4 texColor; + if (u_IsFill) { + texColor = vec4(u_FillColor, 1.0); + } else { + texColor = texture2D(u_Texture, v_TexCoord); + } + if (abs(u_ColorDepth - 8.0) < 0.1) { + float gray = texColor.r; + gl_FragColor = vec4(gray, gray, gray, u_Opa); + } else { + float combinedAlpha = texColor.a * u_Opa; + gl_FragColor = vec4(texColor.rgb * combinedAlpha, combinedAlpha); + } + #ifdef HSV_ADJUST + gl_FragColor.rgb = adjustHSV(gl_FragColor.rgb); + #endif + } +)"; + +static const lv_opengl_shader_t src_includes_v300es[] = {{ + "hsv_adjust.glsl", R"( + uniform float u_Hue; + uniform float u_Saturation; + uniform float u_Value; + + // Convert RGB to HSV + vec3 rgb2hsv(vec3 c) { + vec4 K = vec4(0.0, -1.0 / 3.0, 2.0 / 3.0, -1.0); + vec4 p = mix(vec4(c.bg, K.wz), vec4(c.gb, K.xy), step(c.b, c.g)); + vec4 q = mix(vec4(p.xyw, c.r), vec4(c.r, p.yzx), step(p.x, c.r)); + float d = q.x - min(q.w, q.y); + float e = 1.0e-10; + return vec3(abs(q.z + (q.w - q.y) / (6.0 * d + e)), d / (q.x + e), q.x); + } + + // Convert HSV to RGB + vec3 hsv2rgb(vec3 c) { + vec4 K = vec4(1.0, 2.0 / 3.0, 1.0 / 3.0, 3.0); + vec3 p = abs(fract(c.xxx + K.xyz) * 6.0 - K.www); + return c.z * mix(K.xxx, clamp(p - K.xxx, 0.0, 1.0), c.y); + } + + vec3 adjustHSV(vec3 color){ + vec3 hsv = rgb2hsv(color); + hsv.x = fract(hsv.x + u_Hue); + hsv.y = clamp(hsv.y * u_Saturation, 0.0, 1.0); + hsv.z = clamp(hsv.z * u_Value, 0.0, 1.0); + return hsv2rgb(hsv); + } + )" + }, { + "brightness_adjust.glsl", R"( + uniform float u_Brightness; // add/subtract in [ -1.0 .. +1.0 ], 0.0 = no change + + vec3 adjustBrightness(vec3 color){ + return clamp(color + vec3(u_Brightness), 0.0, 1.0); + } + + )" + }, { + "contrast_adjust.glsl", R"( + uniform float u_Contrast; // 0.0 = mid-gray, 1.0 = no change, >1.0 increases contrast + + vec3 adjustContrast(vec3 color){ + // shift to [-0.5..0.5], scale, shift back + return clamp(((color - 0.5) * u_Contrast) + 0.5, 0.0, 1.0); + } + )" + }, +}; + +static const char * src_vertex_shader_v300es = R"( + precision mediump float; + + in vec4 position; + in vec2 texCoord; + + out vec2 v_TexCoord; + + uniform mat3 u_VertexTransform; + + void main() + { + gl_Position = vec4((u_VertexTransform * vec3(position.xy, 1)).xy, position.zw); + v_TexCoord = texCoord; + } +)"; + +static const char *src_fragment_shader_v300es = R"( + precision lowp float; + + out vec4 color; + + in vec2 v_TexCoord; + + uniform sampler2D u_Texture; + uniform float u_ColorDepth; + uniform float u_Opa; + uniform bool u_IsFill; + uniform vec3 u_FillColor; + + #ifdef HSV_ADJUST +#include + #endif + + void main() + { + vec4 texColor; + if (u_IsFill) { + texColor = vec4(u_FillColor, 1.0); + } else { + //texColor = texture(u_Texture, v_TexCoord); + texColor = textureLod(u_Texture, v_TexCoord, 0.0); // If the vertices have been transformed, and mipmaps have not been generated, some rotation angles (notably 90 and 270) require using textureLod() to mitigate derivative calculation errors from increments flipping direction + } + if (abs(u_ColorDepth - 8.0) < 0.1) { + float gray = texColor.r; + color = vec4(gray, gray, gray, u_Opa); + } else { + float combinedAlpha = texColor.a * u_Opa; + color = vec4(texColor.rgb * combinedAlpha, combinedAlpha); + } + #ifdef HSV_ADJUST + color.rgb = adjustHSV(color.rgb); + #endif + } +)"; + +static const size_t src_includes_v100_count = sizeof src_includes_v100 / sizeof src_includes_v100[0]; +static const size_t src_includes_v300es_count = sizeof src_includes_v300es / sizeof src_includes_v300es[0]; + +/********************** + * GLOBAL FUNCTIONS + **********************/ + +char * lv_opengles_shader_get_vertex(lv_opengl_glsl_version version) { + switch (version){ + case LV_OPENGL_GLSL_VERSION_300ES: + return lv_opengl_shader_manager_process_includes(src_vertex_shader_v300es, src_includes_v300es, src_includes_v300es_count); + case LV_OPENGL_GLSL_VERSION_100: + return lv_opengl_shader_manager_process_includes(src_vertex_shader_v100, src_includes_v100, src_includes_v100_count); + case LV_OPENGL_GLSL_VERSION_LAST: + LV_LOG_ERROR("Invalid glsl version %d", version); + return NULL; + } + LV_UNREACHABLE(); +} + +char * lv_opengles_shader_get_fragment(lv_opengl_glsl_version version) { + switch (version){ + case LV_OPENGL_GLSL_VERSION_300ES: + return lv_opengl_shader_manager_process_includes(src_fragment_shader_v300es, src_includes_v300es, src_includes_v300es_count); + case LV_OPENGL_GLSL_VERSION_100: + return lv_opengl_shader_manager_process_includes(src_fragment_shader_v100, src_includes_v100, src_includes_v100_count); + case LV_OPENGL_GLSL_VERSION_LAST: + LV_LOG_ERROR("Invalid glsl version %d", version); + return NULL; + } + LV_UNREACHABLE(); +} + +void lv_opengles_shader_get_source(lv_opengl_shader_portions_t *portions, lv_opengl_glsl_version version) +{ + switch (version){ + case LV_OPENGL_GLSL_VERSION_300ES: + portions->all = src_includes_v300es; + portions->count = src_includes_v300es_count; + return; + case LV_OPENGL_GLSL_VERSION_100: + portions->all = src_includes_v100; + portions->count = src_includes_v100_count; + return; + case LV_OPENGL_GLSL_VERSION_LAST: + LV_LOG_ERROR("Invalid glsl version %d", version); + portions->count = 0; + return; + } + + LV_UNREACHABLE(); +} + +#endif /*LV_USE_OPENGLES*/ diff --git a/src/drivers/opengles/assets/lv_opengles_shader.h b/src/drivers/opengles/assets/lv_opengles_shader.h new file mode 100644 index 0000000000..8c310a1a47 --- /dev/null +++ b/src/drivers/opengles/assets/lv_opengles_shader.h @@ -0,0 +1,39 @@ +/** + * @file lv_opengles_shader.h + * + */ + +#ifndef LV_OPENGLES_SHADER_H +#define LV_OPENGLES_SHADER_H + +#ifdef __cplusplus +extern "C" { +#endif + +/********************* + * INCLUDES + *********************/ +#include "../opengl_shader/lv_opengl_shader_internal.h" + +#if LV_USE_OPENGLES + +/********************** + * GLOBAL PROTOTYPES + **********************/ + +char * lv_opengles_shader_get_vertex(lv_opengl_glsl_version version); +char * lv_opengles_shader_get_fragment(lv_opengl_glsl_version version); +void lv_opengles_shader_get_source(lv_opengl_shader_portions_t * portions, lv_opengl_glsl_version version); + + +/********************** + * MACROS + **********************/ + +#endif /*LV_USE_OPENGLES*/ + +#ifdef __cplusplus +} /*extern "C"*/ +#endif + +#endif /*LV_OPENGLES_SHADER_H*/ diff --git a/src/drivers/opengles/glad/README.md b/src/drivers/opengles/glad/README.md new file mode 100644 index 0000000000..a15015ceb5 --- /dev/null +++ b/src/drivers/opengles/glad/README.md @@ -0,0 +1,5 @@ + +# glad + +GLAD source files are generated using GLAD's online generator. +[Permalink](https://gen.glad.sh/#generator=c&api=egl%3D1.5%2Cgles2%3D2.0&profile=gl%3Dcompatibility%2Cgles1%3Dcommon&extensions=EGL_EXT_image_dma_buf_import%2CEGL_EXT_image_dma_buf_import_modifiers%2CEGL_EXT_platform_base%2CEGL_EXT_platform_wayland%2CEGL_KHR_fence_sync%2CEGL_KHR_image_base%2CEGL_KHR_platform_gbm%2CEGL_KHR_platform_wayland%2CGL_APPLE_texture_max_level%2CGL_ARM_rgba8%2CGL_EXT_color_buffer_float%2CGL_EXT_color_buffer_half_float%2CGL_EXT_texture_format_BGRA8888%2CGL_EXT_texture_storage%2CGL_EXT_unpack_subimage%2CGL_OES_depth24%2CGL_OES_mapbuffer%2CGL_OES_rgb8_rgba8%2CGL_OES_texture_float%2CGL_OES_texture_half_float%2CGL_OES_texture_storage_multisample_2d_array%2CGL_OES_vertex_array_object&options=ALIAS) \ No newline at end of file diff --git a/src/drivers/opengles/glad/include/EGL/eglplatform.h b/src/drivers/opengles/glad/include/EGL/eglplatform.h new file mode 100644 index 0000000000..d556b74f55 --- /dev/null +++ b/src/drivers/opengles/glad/include/EGL/eglplatform.h @@ -0,0 +1,181 @@ +#ifndef __eglplatform_h_ +#define __eglplatform_h_ + +#include "../../../lv_opengles_egl.h" + +#if LV_USE_EGL + +/* +** Copyright 2007-2020 The Khronos Group Inc. +** SPDX-License-Identifier: Apache-2.0 +*/ + +/* Platform-specific types and definitions for egl.h + * + * Adopters may modify khrplatform.h and this file to suit their platform. + * You are encouraged to submit all modifications to the Khronos group so that + * they can be included in future versions of this file. Please submit changes + * by filing an issue or pull request on the public Khronos EGL Registry, at + * https://www.github.com/KhronosGroup/EGL-Registry/ + */ + +#include + +/* Macros used in EGL function prototype declarations. + * + * EGL functions should be prototyped as: + * + * EGLAPI return-type EGLAPIENTRY eglFunction(arguments); + * typedef return-type (EXPAPIENTRYP PFNEGLFUNCTIONPROC) (arguments); + * + * KHRONOS_APICALL and KHRONOS_APIENTRY are defined in KHR/khrplatform.h + */ + +#ifndef EGLAPI +#define EGLAPI KHRONOS_APICALL +#endif + +#ifndef EGLAPIENTRY +#define EGLAPIENTRY KHRONOS_APIENTRY +#endif +#define EGLAPIENTRYP EGLAPIENTRY* + +/* The types NativeDisplayType, NativeWindowType, and NativePixmapType + * are aliases of window-system-dependent types, such as X Display * or + * Windows Device Context. They must be defined in platform-specific + * code below. The EGL-prefixed versions of Native*Type are the same + * types, renamed in EGL 1.3 so all types in the API start with "EGL". + * + * Khronos STRONGLY RECOMMENDS that you use the default definitions + * provided below, since these changes affect both binary and source + * portability of applications using EGL running on different EGL + * implementations. + */ + +#if defined(EGL_NO_PLATFORM_SPECIFIC_TYPES) + +typedef void *EGLNativeDisplayType; +typedef void *EGLNativePixmapType; +typedef void *EGLNativeWindowType; + +#elif defined(_WIN32) || defined(__VC32__) && !defined(__CYGWIN__) && !defined(__SCITECH_SNAP__) /* Win32 and WinCE */ +#ifndef WIN32_LEAN_AND_MEAN +#define WIN32_LEAN_AND_MEAN 1 +#endif +#include + +typedef HDC EGLNativeDisplayType; +typedef HBITMAP EGLNativePixmapType; +typedef HWND EGLNativeWindowType; + +#elif defined(__QNX__) + +typedef khronos_uintptr_t EGLNativeDisplayType; +typedef struct _screen_pixmap* EGLNativePixmapType; /* screen_pixmap_t */ +typedef struct _screen_window* EGLNativeWindowType; /* screen_window_t */ + +#elif defined(__EMSCRIPTEN__) + +typedef int EGLNativeDisplayType; +typedef int EGLNativePixmapType; +typedef int EGLNativeWindowType; + +#elif defined(__WINSCW__) || defined(__SYMBIAN32__) /* Symbian */ + +typedef int EGLNativeDisplayType; +typedef void *EGLNativePixmapType; +typedef void *EGLNativeWindowType; + +#elif defined(WL_EGL_PLATFORM) + +typedef struct wl_display *EGLNativeDisplayType; +typedef struct wl_egl_pixmap *EGLNativePixmapType; +typedef struct wl_egl_window *EGLNativeWindowType; + +#elif defined(__GBM__) + +typedef struct gbm_device *EGLNativeDisplayType; +typedef struct gbm_bo *EGLNativePixmapType; +typedef void *EGLNativeWindowType; + +#elif defined(__ANDROID__) || defined(ANDROID) + +struct ANativeWindow; +struct egl_native_pixmap_t; + +typedef void* EGLNativeDisplayType; +typedef struct egl_native_pixmap_t* EGLNativePixmapType; +typedef struct ANativeWindow* EGLNativeWindowType; + +#elif defined(USE_OZONE) + +typedef intptr_t EGLNativeDisplayType; +typedef intptr_t EGLNativePixmapType; +typedef intptr_t EGLNativeWindowType; + +#elif defined(USE_X11) + +/* X11 (tentative) */ +#include +#include + +typedef Display *EGLNativeDisplayType; +typedef Pixmap EGLNativePixmapType; +typedef Window EGLNativeWindowType; + +#elif defined(__unix__) + +typedef void *EGLNativeDisplayType; +typedef khronos_uintptr_t EGLNativePixmapType; +typedef khronos_uintptr_t EGLNativeWindowType; + +#elif defined(__APPLE__) + +typedef int EGLNativeDisplayType; +typedef void *EGLNativePixmapType; +typedef void *EGLNativeWindowType; + +#elif defined(__HAIKU__) + +#include + +typedef void *EGLNativeDisplayType; +typedef khronos_uintptr_t EGLNativePixmapType; +typedef khronos_uintptr_t EGLNativeWindowType; + +#elif defined(__Fuchsia__) + +typedef void *EGLNativeDisplayType; +typedef khronos_uintptr_t EGLNativePixmapType; +typedef khronos_uintptr_t EGLNativeWindowType; + +#else +#error "Platform not recognized" +#endif + +/* EGL 1.2 types, renamed for consistency in EGL 1.3 */ +typedef EGLNativeDisplayType NativeDisplayType; +typedef EGLNativePixmapType NativePixmapType; +typedef EGLNativeWindowType NativeWindowType; + + +/* Define EGLint. This must be a signed integral type large enough to contain + * all legal attribute names and values passed into and out of EGL, whether + * their type is boolean, bitmask, enumerant (symbolic constant), integer, + * handle, or other. While in general a 32-bit integer will suffice, if + * handles are 64 bit types, then EGLint should be defined as a signed 64-bit + * integer type. + */ +typedef khronos_int32_t EGLint; + + +/* C++ / C typecast macros for special EGL handle values */ +#if defined(__cplusplus) +#define EGL_CAST(type, value) (static_cast(value)) +#else +#define EGL_CAST(type, value) ((type) (value)) +#endif + +#endif /*LV_USE_EGL*/ + +#endif /* __eglplatform_h */ diff --git a/src/drivers/opengles/glad/include/KHR/khrplatform.h b/src/drivers/opengles/glad/include/KHR/khrplatform.h new file mode 100644 index 0000000000..af2ae885b9 --- /dev/null +++ b/src/drivers/opengles/glad/include/KHR/khrplatform.h @@ -0,0 +1,317 @@ +#ifndef __khrplatform_h_ +#define __khrplatform_h_ + +#include "../../../lv_opengles_egl.h" + +#if LV_USE_EGL + +/* +** Copyright (c) 2008-2018 The Khronos Group Inc. +** +** Permission is hereby granted, free of charge, to any person obtaining a +** copy of this software and/or associated documentation files (the +** "Materials"), to deal in the Materials without restriction, including +** without limitation the rights to use, copy, modify, merge, publish, +** distribute, sublicense, and/or sell copies of the Materials, and to +** permit persons to whom the Materials are furnished to do so, subject to +** the following conditions: +** +** The above copyright notice and this permission notice shall be included +** in all copies or substantial portions of the Materials. +** +** THE MATERIALS ARE PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +** EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +** MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +** IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY +** CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, +** TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE +** MATERIALS OR THE USE OR OTHER DEALINGS IN THE MATERIALS. +*/ + +/* Khronos platform-specific types and definitions. + * + * The master copy of khrplatform.h is maintained in the Khronos EGL + * Registry repository at https://github.com/KhronosGroup/EGL-Registry + * The last semantic modification to khrplatform.h was at commit ID: + * 67a3e0864c2d75ea5287b9f3d2eb74a745936692 + * + * Adopters may modify this file to suit their platform. Adopters are + * encouraged to submit platform specific modifications to the Khronos + * group so that they can be included in future versions of this file. + * Please submit changes by filing pull requests or issues on + * the EGL Registry repository linked above. + * + * + * See the Implementer's Guidelines for information about where this file + * should be located on your system and for more details of its use: + * http://www.khronos.org/registry/implementers_guide.pdf + * + * This file should be included as + * #include + * by Khronos client API header files that use its types and defines. + * + * The types in khrplatform.h should only be used to define API-specific types. + * + * Types defined in khrplatform.h: + * khronos_int8_t signed 8 bit + * khronos_uint8_t unsigned 8 bit + * khronos_int16_t signed 16 bit + * khronos_uint16_t unsigned 16 bit + * khronos_int32_t signed 32 bit + * khronos_uint32_t unsigned 32 bit + * khronos_int64_t signed 64 bit + * khronos_uint64_t unsigned 64 bit + * khronos_intptr_t signed same number of bits as a pointer + * khronos_uintptr_t unsigned same number of bits as a pointer + * khronos_ssize_t signed size + * khronos_usize_t unsigned size + * khronos_float_t signed 32 bit floating point + * khronos_time_ns_t unsigned 64 bit time in nanoseconds + * khronos_utime_nanoseconds_t unsigned time interval or absolute time in + * nanoseconds + * khronos_stime_nanoseconds_t signed time interval in nanoseconds + * khronos_boolean_enum_t enumerated boolean type. This should + * only be used as a base type when a client API's boolean type is + * an enum. Client APIs which use an integer or other type for + * booleans cannot use this as the base type for their boolean. + * + * Tokens defined in khrplatform.h: + * + * KHRONOS_FALSE, KHRONOS_TRUE Enumerated boolean false/true values. + * + * KHRONOS_SUPPORT_INT64 is 1 if 64 bit integers are supported; otherwise 0. + * KHRONOS_SUPPORT_FLOAT is 1 if floats are supported; otherwise 0. + * + * Calling convention macros defined in this file: + * KHRONOS_APICALL + * KHRONOS_APIENTRY + * KHRONOS_APIATTRIBUTES + * + * These may be used in function prototypes as: + * + * KHRONOS_APICALL void KHRONOS_APIENTRY funcname( + * int arg1, + * int arg2) KHRONOS_APIATTRIBUTES; + */ + +#if defined(__SCITECH_SNAP__) && !defined(KHRONOS_STATIC) +# define KHRONOS_STATIC 1 +#endif + +/*------------------------------------------------------------------------- + * Definition of KHRONOS_APICALL + *------------------------------------------------------------------------- + * This precedes the return type of the function in the function prototype. + */ +#if defined(KHRONOS_STATIC) + /* If the preprocessor constant KHRONOS_STATIC is defined, make the + * header compatible with static linking. */ +# define KHRONOS_APICALL +#elif defined(_WIN32) +# define KHRONOS_APICALL __declspec(dllimport) +#elif defined (__SYMBIAN32__) +# define KHRONOS_APICALL IMPORT_C +#elif defined(__ANDROID__) +# define KHRONOS_APICALL __attribute__((visibility("default"))) +#else +# define KHRONOS_APICALL +#endif + +/*------------------------------------------------------------------------- + * Definition of KHRONOS_APIENTRY + *------------------------------------------------------------------------- + * This follows the return type of the function and precedes the function + * name in the function prototype. + */ +#if defined(_WIN32) && !defined(_WIN32_WCE) && !defined(__SCITECH_SNAP__) + /* Win32 but not WinCE */ +# define KHRONOS_APIENTRY __stdcall +#else +# define KHRONOS_APIENTRY +#endif + +/*------------------------------------------------------------------------- + * Definition of KHRONOS_APIATTRIBUTES + *------------------------------------------------------------------------- + * This follows the closing parenthesis of the function prototype arguments. + */ +#if defined (__ARMCC_2__) +#define KHRONOS_APIATTRIBUTES __softfp +#else +#define KHRONOS_APIATTRIBUTES +#endif + +/*------------------------------------------------------------------------- + * basic type definitions + *-----------------------------------------------------------------------*/ +#if (defined(__STDC_VERSION__) && __STDC_VERSION__ >= 199901L) || defined(__GNUC__) || defined(__SCO__) || defined(__USLC__) + + +/* + * Using + */ +#include +typedef int32_t khronos_int32_t; +typedef uint32_t khronos_uint32_t; +typedef int64_t khronos_int64_t; +typedef uint64_t khronos_uint64_t; +#define KHRONOS_SUPPORT_INT64 1 +#define KHRONOS_SUPPORT_FLOAT 1 +/* + * To support platform where unsigned long cannot be used interchangeably with + * inptr_t (e.g. CHERI-extended ISAs), we can use the stdint.h intptr_t. + * Ideally, we could just use (u)intptr_t everywhere, but this could result in + * ABI breakage if khronos_uintptr_t is changed from unsigned long to + * unsigned long long or similar (this results in different C++ name mangling). + * To avoid changes for existing platforms, we restrict usage of intptr_t to + * platforms where the size of a pointer is larger than the size of long. + */ +#if defined(__SIZEOF_LONG__) && defined(__SIZEOF_POINTER__) +#if __SIZEOF_POINTER__ > __SIZEOF_LONG__ +#define KHRONOS_USE_INTPTR_T +#endif +#endif + +#elif defined(__VMS ) || defined(__sgi) + +/* + * Using + */ +#include +typedef int32_t khronos_int32_t; +typedef uint32_t khronos_uint32_t; +typedef int64_t khronos_int64_t; +typedef uint64_t khronos_uint64_t; +#define KHRONOS_SUPPORT_INT64 1 +#define KHRONOS_SUPPORT_FLOAT 1 + +#elif defined(_WIN32) && !defined(__SCITECH_SNAP__) + +/* + * Win32 + */ +typedef __int32 khronos_int32_t; +typedef unsigned __int32 khronos_uint32_t; +typedef __int64 khronos_int64_t; +typedef unsigned __int64 khronos_uint64_t; +#define KHRONOS_SUPPORT_INT64 1 +#define KHRONOS_SUPPORT_FLOAT 1 + +#elif defined(__sun__) || defined(__digital__) + +/* + * Sun or Digital + */ +typedef int khronos_int32_t; +typedef unsigned int khronos_uint32_t; +#if defined(__arch64__) || defined(_LP64) +typedef long int khronos_int64_t; +typedef unsigned long int khronos_uint64_t; +#else +typedef long long int khronos_int64_t; +typedef unsigned long long int khronos_uint64_t; +#endif /* __arch64__ */ +#define KHRONOS_SUPPORT_INT64 1 +#define KHRONOS_SUPPORT_FLOAT 1 + +#elif 0 + +/* + * Hypothetical platform with no float or int64 support + */ +typedef int khronos_int32_t; +typedef unsigned int khronos_uint32_t; +#define KHRONOS_SUPPORT_INT64 0 +#define KHRONOS_SUPPORT_FLOAT 0 + +#else + +/* + * Generic fallback + */ +#include +typedef int32_t khronos_int32_t; +typedef uint32_t khronos_uint32_t; +typedef int64_t khronos_int64_t; +typedef uint64_t khronos_uint64_t; +#define KHRONOS_SUPPORT_INT64 1 +#define KHRONOS_SUPPORT_FLOAT 1 + +#endif + + +/* + * Types that are (so far) the same on all platforms + */ +typedef signed char khronos_int8_t; +typedef unsigned char khronos_uint8_t; +typedef signed short int khronos_int16_t; +typedef unsigned short int khronos_uint16_t; + +/* + * Types that differ between LLP64 and LP64 architectures - in LLP64, + * pointers are 64 bits, but 'long' is still 32 bits. Win64 appears + * to be the only LLP64 architecture in current use. + */ +#ifdef KHRONOS_USE_INTPTR_T +typedef intptr_t khronos_intptr_t; +typedef uintptr_t khronos_uintptr_t; +#elif defined(_WIN64) +typedef signed long long int khronos_intptr_t; +typedef unsigned long long int khronos_uintptr_t; +#else +typedef signed long int khronos_intptr_t; +typedef unsigned long int khronos_uintptr_t; +#endif + +#if defined(_WIN64) +typedef signed long long int khronos_ssize_t; +typedef unsigned long long int khronos_usize_t; +#else +typedef signed long int khronos_ssize_t; +typedef unsigned long int khronos_usize_t; +#endif + +#if KHRONOS_SUPPORT_FLOAT +/* + * Float type + */ +typedef float khronos_float_t; +#endif + +#if KHRONOS_SUPPORT_INT64 +/* Time types + * + * These types can be used to represent a time interval in nanoseconds or + * an absolute Unadjusted System Time. Unadjusted System Time is the number + * of nanoseconds since some arbitrary system event (e.g. since the last + * time the system booted). The Unadjusted System Time is an unsigned + * 64 bit value that wraps back to 0 every 584 years. Time intervals + * may be either signed or unsigned. + */ +typedef khronos_uint64_t khronos_utime_nanoseconds_t; +typedef khronos_int64_t khronos_stime_nanoseconds_t; +#endif + +/* + * Dummy value used to pad enum types to 32 bits. + */ +#ifndef KHRONOS_MAX_ENUM +#define KHRONOS_MAX_ENUM 0x7FFFFFFF +#endif + +/* + * Enumerated boolean type + * + * Values other than zero should be considered to be true. Therefore + * comparisons should not be made against KHRONOS_TRUE. + */ +typedef enum { + KHRONOS_FALSE = 0, + KHRONOS_TRUE = 1, + KHRONOS_BOOLEAN_ENUM_FORCE_SIZE = KHRONOS_MAX_ENUM +} khronos_boolean_enum_t; + +#endif /* LV_USE_EGL */ + +#endif /* __khrplatform_h_ */ diff --git a/src/drivers/opengles/glad/include/glad/egl.h b/src/drivers/opengles/glad/include/glad/egl.h new file mode 100644 index 0000000000..755bf0382b --- /dev/null +++ b/src/drivers/opengles/glad/include/glad/egl.h @@ -0,0 +1,665 @@ +/** + * Loader generated by glad 2.0.8 on Tue Sep 30 16:40:42 2025 + * + * SPDX-License-Identifier: (WTFPL OR CC0-1.0) AND Apache-2.0 + * + * Generator: C/C++ + * Specification: egl + * Extensions: 11 + * + * APIs: + * - egl=1.5 + * + * Options: + * - ALIAS = True + * - DEBUG = False + * - HEADER_ONLY = False + * - LOADER = False + * - MX = False + * - ON_DEMAND = False + * + * Commandline: + * --api='egl=1.5' --extensions='EGL_EXT_image_dma_buf_import,EGL_EXT_image_dma_buf_import_modifiers,EGL_EXT_platform_base,EGL_EXT_platform_wayland,EGL_KHR_cl_event2,EGL_KHR_fence_sync,EGL_KHR_image,EGL_KHR_image_base,EGL_KHR_platform_gbm,EGL_KHR_platform_wayland,EGL_KHR_reusable_sync' c --alias + * + * Online: + * http://glad.sh/#api=egl%3D1.5&extensions=EGL_EXT_image_dma_buf_import%2CEGL_EXT_image_dma_buf_import_modifiers%2CEGL_EXT_platform_base%2CEGL_EXT_platform_wayland%2CEGL_KHR_cl_event2%2CEGL_KHR_fence_sync%2CEGL_KHR_image%2CEGL_KHR_image_base%2CEGL_KHR_platform_gbm%2CEGL_KHR_platform_wayland%2CEGL_KHR_reusable_sync&generator=c&options=ALIAS + * + */ + +#ifndef GLAD_EGL_H_ +#define GLAD_EGL_H_ + +#include "../../../lv_opengles_egl.h" + +#if LV_USE_EGL + +#define GLAD_EGL +#define GLAD_OPTION_EGL_ALIAS + +#ifdef __cplusplus +extern "C" { +#endif + +#ifndef GLAD_PLATFORM_H_ +#define GLAD_PLATFORM_H_ + +#ifndef GLAD_PLATFORM_WIN32 + #if defined(_WIN32) || defined(__WIN32__) || defined(WIN32) || defined(__MINGW32__) + #define GLAD_PLATFORM_WIN32 1 + #else + #define GLAD_PLATFORM_WIN32 0 + #endif +#endif + +#ifndef GLAD_PLATFORM_APPLE + #ifdef __APPLE__ + #define GLAD_PLATFORM_APPLE 1 + #else + #define GLAD_PLATFORM_APPLE 0 + #endif +#endif + +#ifndef GLAD_PLATFORM_EMSCRIPTEN + #ifdef __EMSCRIPTEN__ + #define GLAD_PLATFORM_EMSCRIPTEN 1 + #else + #define GLAD_PLATFORM_EMSCRIPTEN 0 + #endif +#endif + +#ifndef GLAD_PLATFORM_UWP + #if defined(_MSC_VER) && !defined(GLAD_INTERNAL_HAVE_WINAPIFAMILY) + #ifdef __has_include + #if __has_include() + #define GLAD_INTERNAL_HAVE_WINAPIFAMILY 1 + #endif + #elif _MSC_VER >= 1700 && !_USING_V110_SDK71_ + #define GLAD_INTERNAL_HAVE_WINAPIFAMILY 1 + #endif + #endif + + #ifdef GLAD_INTERNAL_HAVE_WINAPIFAMILY + #include + #if !WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP) && WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_APP) + #define GLAD_PLATFORM_UWP 1 + #endif + #endif + + #ifndef GLAD_PLATFORM_UWP + #define GLAD_PLATFORM_UWP 0 + #endif +#endif + +#ifdef __GNUC__ + #define GLAD_GNUC_EXTENSION __extension__ +#else + #define GLAD_GNUC_EXTENSION +#endif + +#define GLAD_UNUSED(x) (void)(x) + +#ifndef GLAD_API_CALL + #if defined(GLAD_API_CALL_EXPORT) + #if GLAD_PLATFORM_WIN32 || defined(__CYGWIN__) + #if defined(GLAD_API_CALL_EXPORT_BUILD) + #if defined(__GNUC__) + #define GLAD_API_CALL __attribute__ ((dllexport)) extern + #else + #define GLAD_API_CALL __declspec(dllexport) extern + #endif + #else + #if defined(__GNUC__) + #define GLAD_API_CALL __attribute__ ((dllimport)) extern + #else + #define GLAD_API_CALL __declspec(dllimport) extern + #endif + #endif + #elif defined(__GNUC__) && defined(GLAD_API_CALL_EXPORT_BUILD) + #define GLAD_API_CALL __attribute__ ((visibility ("default"))) extern + #else + #define GLAD_API_CALL extern + #endif + #else + #define GLAD_API_CALL extern + #endif +#endif + +#ifdef APIENTRY + #define GLAD_API_PTR APIENTRY +#elif GLAD_PLATFORM_WIN32 + #define GLAD_API_PTR __stdcall +#else + #define GLAD_API_PTR +#endif + +#ifndef GLAPI +#define GLAPI GLAD_API_CALL +#endif + +#ifndef GLAPIENTRY +#define GLAPIENTRY GLAD_API_PTR +#endif + +#define GLAD_MAKE_VERSION(major, minor) (major * 10000 + minor) +#define GLAD_VERSION_MAJOR(version) (version / 10000) +#define GLAD_VERSION_MINOR(version) (version % 10000) + +#define GLAD_GENERATOR_VERSION "2.0.8" + +typedef void (*GLADapiproc)(void); + +typedef GLADapiproc (*GLADloadfunc)(const char *name); +typedef GLADapiproc (*GLADuserptrloadfunc)(void *userptr, const char *name); + +typedef void (*GLADprecallback)(const char *name, GLADapiproc apiproc, int len_args, ...); +typedef void (*GLADpostcallback)(void *ret, const char *name, GLADapiproc apiproc, int len_args, ...); + +#endif /* GLAD_PLATFORM_H_ */ + +#define EGL_ALPHA_FORMAT 0x3088 +#define EGL_ALPHA_FORMAT_NONPRE 0x308B +#define EGL_ALPHA_FORMAT_PRE 0x308C +#define EGL_ALPHA_MASK_SIZE 0x303E +#define EGL_ALPHA_SIZE 0x3021 +#define EGL_BACK_BUFFER 0x3084 +#define EGL_BAD_ACCESS 0x3002 +#define EGL_BAD_ALLOC 0x3003 +#define EGL_BAD_ATTRIBUTE 0x3004 +#define EGL_BAD_CONFIG 0x3005 +#define EGL_BAD_CONTEXT 0x3006 +#define EGL_BAD_CURRENT_SURFACE 0x3007 +#define EGL_BAD_DISPLAY 0x3008 +#define EGL_BAD_MATCH 0x3009 +#define EGL_BAD_NATIVE_PIXMAP 0x300A +#define EGL_BAD_NATIVE_WINDOW 0x300B +#define EGL_BAD_PARAMETER 0x300C +#define EGL_BAD_SURFACE 0x300D +#define EGL_BIND_TO_TEXTURE_RGB 0x3039 +#define EGL_BIND_TO_TEXTURE_RGBA 0x303A +#define EGL_BLUE_SIZE 0x3022 +#define EGL_BUFFER_DESTROYED 0x3095 +#define EGL_BUFFER_PRESERVED 0x3094 +#define EGL_BUFFER_SIZE 0x3020 +#define EGL_CLIENT_APIS 0x308D +#define EGL_CL_EVENT_HANDLE 0x309C +#define EGL_CL_EVENT_HANDLE_KHR 0x309C +#define EGL_COLORSPACE 0x3087 +#define EGL_COLORSPACE_LINEAR 0x308A +#define EGL_COLORSPACE_sRGB 0x3089 +#define EGL_COLOR_BUFFER_TYPE 0x303F +#define EGL_CONDITION_SATISFIED 0x30F6 +#define EGL_CONDITION_SATISFIED_KHR 0x30F6 +#define EGL_CONFIG_CAVEAT 0x3027 +#define EGL_CONFIG_ID 0x3028 +#define EGL_CONFORMANT 0x3042 +#define EGL_CONTEXT_CLIENT_TYPE 0x3097 +#define EGL_CONTEXT_CLIENT_VERSION 0x3098 +#define EGL_CONTEXT_LOST 0x300E +#define EGL_CONTEXT_MAJOR_VERSION 0x3098 +#define EGL_CONTEXT_MINOR_VERSION 0x30FB +#define EGL_CONTEXT_OPENGL_COMPATIBILITY_PROFILE_BIT 0x00000002 +#define EGL_CONTEXT_OPENGL_CORE_PROFILE_BIT 0x00000001 +#define EGL_CONTEXT_OPENGL_DEBUG 0x31B0 +#define EGL_CONTEXT_OPENGL_FORWARD_COMPATIBLE 0x31B1 +#define EGL_CONTEXT_OPENGL_PROFILE_MASK 0x30FD +#define EGL_CONTEXT_OPENGL_RESET_NOTIFICATION_STRATEGY 0x31BD +#define EGL_CONTEXT_OPENGL_ROBUST_ACCESS 0x31B2 +#define EGL_CORE_NATIVE_ENGINE 0x305B +#define EGL_DEFAULT_DISPLAY EGL_CAST(EGLNativeDisplayType,0) +#define EGL_DEPTH_SIZE 0x3025 +#define EGL_DISPLAY_SCALING 10000 +#define EGL_DMA_BUF_PLANE0_FD_EXT 0x3272 +#define EGL_DMA_BUF_PLANE0_MODIFIER_HI_EXT 0x3444 +#define EGL_DMA_BUF_PLANE0_MODIFIER_LO_EXT 0x3443 +#define EGL_DMA_BUF_PLANE0_OFFSET_EXT 0x3273 +#define EGL_DMA_BUF_PLANE0_PITCH_EXT 0x3274 +#define EGL_DMA_BUF_PLANE1_FD_EXT 0x3275 +#define EGL_DMA_BUF_PLANE1_MODIFIER_HI_EXT 0x3446 +#define EGL_DMA_BUF_PLANE1_MODIFIER_LO_EXT 0x3445 +#define EGL_DMA_BUF_PLANE1_OFFSET_EXT 0x3276 +#define EGL_DMA_BUF_PLANE1_PITCH_EXT 0x3277 +#define EGL_DMA_BUF_PLANE2_FD_EXT 0x3278 +#define EGL_DMA_BUF_PLANE2_MODIFIER_HI_EXT 0x3448 +#define EGL_DMA_BUF_PLANE2_MODIFIER_LO_EXT 0x3447 +#define EGL_DMA_BUF_PLANE2_OFFSET_EXT 0x3279 +#define EGL_DMA_BUF_PLANE2_PITCH_EXT 0x327A +#define EGL_DMA_BUF_PLANE3_FD_EXT 0x3440 +#define EGL_DMA_BUF_PLANE3_MODIFIER_HI_EXT 0x344A +#define EGL_DMA_BUF_PLANE3_MODIFIER_LO_EXT 0x3449 +#define EGL_DMA_BUF_PLANE3_OFFSET_EXT 0x3441 +#define EGL_DMA_BUF_PLANE3_PITCH_EXT 0x3442 +#define EGL_DONT_CARE EGL_CAST(EGLint,-1) +#define EGL_DRAW 0x3059 +#define EGL_EXTENSIONS 0x3055 +#define EGL_FALSE 0 +#define EGL_FOREVER 0xFFFFFFFFFFFFFFFF +#define EGL_FOREVER_KHR 0xFFFFFFFFFFFFFFFF +#define EGL_GL_COLORSPACE 0x309D +#define EGL_GL_COLORSPACE_LINEAR 0x308A +#define EGL_GL_COLORSPACE_SRGB 0x3089 +#define EGL_GL_RENDERBUFFER 0x30B9 +#define EGL_GL_TEXTURE_2D 0x30B1 +#define EGL_GL_TEXTURE_3D 0x30B2 +#define EGL_GL_TEXTURE_CUBE_MAP_NEGATIVE_X 0x30B4 +#define EGL_GL_TEXTURE_CUBE_MAP_NEGATIVE_Y 0x30B6 +#define EGL_GL_TEXTURE_CUBE_MAP_NEGATIVE_Z 0x30B8 +#define EGL_GL_TEXTURE_CUBE_MAP_POSITIVE_X 0x30B3 +#define EGL_GL_TEXTURE_CUBE_MAP_POSITIVE_Y 0x30B5 +#define EGL_GL_TEXTURE_CUBE_MAP_POSITIVE_Z 0x30B7 +#define EGL_GL_TEXTURE_LEVEL 0x30BC +#define EGL_GL_TEXTURE_ZOFFSET 0x30BD +#define EGL_GREEN_SIZE 0x3023 +#define EGL_HEIGHT 0x3056 +#define EGL_HORIZONTAL_RESOLUTION 0x3090 +#define EGL_IMAGE_PRESERVED 0x30D2 +#define EGL_IMAGE_PRESERVED_KHR 0x30D2 +#define EGL_ITU_REC2020_EXT 0x3281 +#define EGL_ITU_REC601_EXT 0x327F +#define EGL_ITU_REC709_EXT 0x3280 +#define EGL_LARGEST_PBUFFER 0x3058 +#define EGL_LEVEL 0x3029 +#define EGL_LINUX_DMA_BUF_EXT 0x3270 +#define EGL_LINUX_DRM_FOURCC_EXT 0x3271 +#define EGL_LOSE_CONTEXT_ON_RESET 0x31BF +#define EGL_LUMINANCE_BUFFER 0x308F +#define EGL_LUMINANCE_SIZE 0x303D +#define EGL_MATCH_NATIVE_PIXMAP 0x3041 +#define EGL_MAX_PBUFFER_HEIGHT 0x302A +#define EGL_MAX_PBUFFER_PIXELS 0x302B +#define EGL_MAX_PBUFFER_WIDTH 0x302C +#define EGL_MAX_SWAP_INTERVAL 0x303C +#define EGL_MIN_SWAP_INTERVAL 0x303B +#define EGL_MIPMAP_LEVEL 0x3083 +#define EGL_MIPMAP_TEXTURE 0x3082 +#define EGL_MULTISAMPLE_RESOLVE 0x3099 +#define EGL_MULTISAMPLE_RESOLVE_BOX 0x309B +#define EGL_MULTISAMPLE_RESOLVE_BOX_BIT 0x0200 +#define EGL_MULTISAMPLE_RESOLVE_DEFAULT 0x309A +#define EGL_NATIVE_PIXMAP_KHR 0x30B0 +#define EGL_NATIVE_RENDERABLE 0x302D +#define EGL_NATIVE_VISUAL_ID 0x302E +#define EGL_NATIVE_VISUAL_TYPE 0x302F +#define EGL_NONE 0x3038 +#define EGL_NON_CONFORMANT_CONFIG 0x3051 +#define EGL_NOT_INITIALIZED 0x3001 +#define EGL_NO_CONTEXT EGL_CAST(EGLContext,0) +#define EGL_NO_DISPLAY EGL_CAST(EGLDisplay,0) +#define EGL_NO_IMAGE EGL_CAST(EGLImage,0) +#define EGL_NO_IMAGE_KHR EGL_CAST(EGLImageKHR,0) +#define EGL_NO_RESET_NOTIFICATION 0x31BE +#define EGL_NO_SURFACE EGL_CAST(EGLSurface,0) +#define EGL_NO_SYNC EGL_CAST(EGLSync,0) +#define EGL_NO_SYNC_KHR EGL_CAST(EGLSync,0) +#define EGL_NO_TEXTURE 0x305C +#define EGL_OPENGL_API 0x30A2 +#define EGL_OPENGL_BIT 0x0008 +#define EGL_OPENGL_ES2_BIT 0x0004 +#define EGL_OPENGL_ES3_BIT 0x00000040 +#define EGL_OPENGL_ES_API 0x30A0 +#define EGL_OPENGL_ES_BIT 0x0001 +#define EGL_OPENVG_API 0x30A1 +#define EGL_OPENVG_BIT 0x0002 +#define EGL_OPENVG_IMAGE 0x3096 +#define EGL_PBUFFER_BIT 0x0001 +#define EGL_PIXEL_ASPECT_RATIO 0x3092 +#define EGL_PIXMAP_BIT 0x0002 +#define EGL_PLATFORM_GBM_KHR 0x31D7 +#define EGL_PLATFORM_WAYLAND_EXT 0x31D8 +#define EGL_PLATFORM_WAYLAND_KHR 0x31D8 +#define EGL_READ 0x305A +#define EGL_RED_SIZE 0x3024 +#define EGL_RENDERABLE_TYPE 0x3040 +#define EGL_RENDER_BUFFER 0x3086 +#define EGL_RGB_BUFFER 0x308E +#define EGL_SAMPLES 0x3031 +#define EGL_SAMPLE_BUFFERS 0x3032 +#define EGL_SAMPLE_RANGE_HINT_EXT 0x327C +#define EGL_SIGNALED 0x30F2 +#define EGL_SIGNALED_KHR 0x30F2 +#define EGL_SINGLE_BUFFER 0x3085 +#define EGL_SLOW_CONFIG 0x3050 +#define EGL_STENCIL_SIZE 0x3026 +#define EGL_SUCCESS 0x3000 +#define EGL_SURFACE_TYPE 0x3033 +#define EGL_SWAP_BEHAVIOR 0x3093 +#define EGL_SWAP_BEHAVIOR_PRESERVED_BIT 0x0400 +#define EGL_SYNC_CL_EVENT 0x30FE +#define EGL_SYNC_CL_EVENT_COMPLETE 0x30FF +#define EGL_SYNC_CL_EVENT_COMPLETE_KHR 0x30FF +#define EGL_SYNC_CL_EVENT_KHR 0x30FE +#define EGL_SYNC_CONDITION 0x30F8 +#define EGL_SYNC_CONDITION_KHR 0x30F8 +#define EGL_SYNC_FENCE 0x30F9 +#define EGL_SYNC_FENCE_KHR 0x30F9 +#define EGL_SYNC_FLUSH_COMMANDS_BIT 0x0001 +#define EGL_SYNC_FLUSH_COMMANDS_BIT_KHR 0x0001 +#define EGL_SYNC_PRIOR_COMMANDS_COMPLETE 0x30F0 +#define EGL_SYNC_PRIOR_COMMANDS_COMPLETE_KHR 0x30F0 +#define EGL_SYNC_REUSABLE_KHR 0x30FA +#define EGL_SYNC_STATUS 0x30F1 +#define EGL_SYNC_STATUS_KHR 0x30F1 +#define EGL_SYNC_TYPE 0x30F7 +#define EGL_SYNC_TYPE_KHR 0x30F7 +#define EGL_TEXTURE_2D 0x305F +#define EGL_TEXTURE_FORMAT 0x3080 +#define EGL_TEXTURE_RGB 0x305D +#define EGL_TEXTURE_RGBA 0x305E +#define EGL_TEXTURE_TARGET 0x3081 +#define EGL_TIMEOUT_EXPIRED 0x30F5 +#define EGL_TIMEOUT_EXPIRED_KHR 0x30F5 +#define EGL_TRANSPARENT_BLUE_VALUE 0x3035 +#define EGL_TRANSPARENT_GREEN_VALUE 0x3036 +#define EGL_TRANSPARENT_RED_VALUE 0x3037 +#define EGL_TRANSPARENT_RGB 0x3052 +#define EGL_TRANSPARENT_TYPE 0x3034 +#define EGL_TRUE 1 +#define EGL_UNKNOWN EGL_CAST(EGLint,-1) +#define EGL_UNSIGNALED 0x30F3 +#define EGL_UNSIGNALED_KHR 0x30F3 +#define EGL_VENDOR 0x3053 +#define EGL_VERSION 0x3054 +#define EGL_VERTICAL_RESOLUTION 0x3091 +#define EGL_VG_ALPHA_FORMAT 0x3088 +#define EGL_VG_ALPHA_FORMAT_NONPRE 0x308B +#define EGL_VG_ALPHA_FORMAT_PRE 0x308C +#define EGL_VG_ALPHA_FORMAT_PRE_BIT 0x0040 +#define EGL_VG_COLORSPACE 0x3087 +#define EGL_VG_COLORSPACE_LINEAR 0x308A +#define EGL_VG_COLORSPACE_LINEAR_BIT 0x0020 +#define EGL_VG_COLORSPACE_sRGB 0x3089 +#define EGL_WIDTH 0x3057 +#define EGL_WINDOW_BIT 0x0004 +#define EGL_YUV_CHROMA_HORIZONTAL_SITING_HINT_EXT 0x327D +#define EGL_YUV_CHROMA_SITING_0_5_EXT 0x3285 +#define EGL_YUV_CHROMA_SITING_0_EXT 0x3284 +#define EGL_YUV_CHROMA_VERTICAL_SITING_HINT_EXT 0x327E +#define EGL_YUV_COLOR_SPACE_HINT_EXT 0x327B +#define EGL_YUV_FULL_RANGE_EXT 0x3282 +#define EGL_YUV_NARROW_RANGE_EXT 0x3283 + + +#include +#include + + + + + + + + + + + +struct AHardwareBuffer; +struct wl_buffer; +struct wl_display; +struct wl_resource; + +typedef unsigned int EGLBoolean; +typedef unsigned int EGLenum; +typedef intptr_t EGLAttribKHR; +typedef intptr_t EGLAttrib; +typedef void *EGLClientBuffer; +typedef void *EGLConfig; +typedef void *EGLContext; +typedef void *EGLDeviceEXT; +typedef void *EGLDisplay; +typedef void *EGLImage; +typedef void *EGLImageKHR; +typedef void *EGLLabelKHR; +typedef void *EGLObjectKHR; +typedef void *EGLOutputLayerEXT; +typedef void *EGLOutputPortEXT; +typedef void *EGLStreamKHR; +typedef void *EGLSurface; +typedef void *EGLSync; +typedef void *EGLSyncKHR; +typedef void *EGLSyncNV; +typedef void (*__eglMustCastToProperFunctionPointerType)(void); +typedef khronos_utime_nanoseconds_t EGLTimeKHR; +typedef khronos_utime_nanoseconds_t EGLTime; +typedef khronos_utime_nanoseconds_t EGLTimeNV; +typedef khronos_utime_nanoseconds_t EGLuint64NV; +typedef khronos_uint64_t EGLuint64KHR; +typedef khronos_stime_nanoseconds_t EGLnsecsANDROID; +typedef int EGLNativeFileDescriptorKHR; +typedef khronos_ssize_t EGLsizeiANDROID; +typedef void (*EGLSetBlobFuncANDROID) (const void *key, EGLsizeiANDROID keySize, const void *value, EGLsizeiANDROID valueSize); +typedef EGLsizeiANDROID (*EGLGetBlobFuncANDROID) (const void *key, EGLsizeiANDROID keySize, void *value, EGLsizeiANDROID valueSize); +struct EGLClientPixmapHI { + void *pData; + EGLint iWidth; + EGLint iHeight; + EGLint iStride; +}; +typedef void (GLAD_API_PTR *EGLDEBUGPROCKHR)(EGLenum error,const char *command,EGLint messageType,EGLLabelKHR threadLabel,EGLLabelKHR objectLabel,const char* message); +#define PFNEGLBINDWAYLANDDISPLAYWL PFNEGLBINDWAYLANDDISPLAYWLPROC +#define PFNEGLUNBINDWAYLANDDISPLAYWL PFNEGLUNBINDWAYLANDDISPLAYWLPROC +#define PFNEGLQUERYWAYLANDBUFFERWL PFNEGLQUERYWAYLANDBUFFERWLPROC +#define PFNEGLCREATEWAYLANDBUFFERFROMIMAGEWL PFNEGLCREATEWAYLANDBUFFERFROMIMAGEWLPROC + + +#define EGL_VERSION_1_0 1 +GLAD_API_CALL int GLAD_EGL_VERSION_1_0; +#define EGL_VERSION_1_1 1 +GLAD_API_CALL int GLAD_EGL_VERSION_1_1; +#define EGL_VERSION_1_2 1 +GLAD_API_CALL int GLAD_EGL_VERSION_1_2; +#define EGL_VERSION_1_3 1 +GLAD_API_CALL int GLAD_EGL_VERSION_1_3; +#define EGL_VERSION_1_4 1 +GLAD_API_CALL int GLAD_EGL_VERSION_1_4; +#define EGL_VERSION_1_5 1 +GLAD_API_CALL int GLAD_EGL_VERSION_1_5; +#define EGL_EXT_image_dma_buf_import 1 +GLAD_API_CALL int GLAD_EGL_EXT_image_dma_buf_import; +#define EGL_EXT_image_dma_buf_import_modifiers 1 +GLAD_API_CALL int GLAD_EGL_EXT_image_dma_buf_import_modifiers; +#define EGL_EXT_platform_base 1 +GLAD_API_CALL int GLAD_EGL_EXT_platform_base; +#define EGL_EXT_platform_wayland 1 +GLAD_API_CALL int GLAD_EGL_EXT_platform_wayland; +#define EGL_KHR_cl_event2 1 +GLAD_API_CALL int GLAD_EGL_KHR_cl_event2; +#define EGL_KHR_fence_sync 1 +GLAD_API_CALL int GLAD_EGL_KHR_fence_sync; +#define EGL_KHR_image 1 +GLAD_API_CALL int GLAD_EGL_KHR_image; +#define EGL_KHR_image_base 1 +GLAD_API_CALL int GLAD_EGL_KHR_image_base; +#define EGL_KHR_platform_gbm 1 +GLAD_API_CALL int GLAD_EGL_KHR_platform_gbm; +#define EGL_KHR_platform_wayland 1 +GLAD_API_CALL int GLAD_EGL_KHR_platform_wayland; +#define EGL_KHR_reusable_sync 1 +GLAD_API_CALL int GLAD_EGL_KHR_reusable_sync; + + +typedef EGLBoolean (GLAD_API_PTR *PFNEGLBINDAPIPROC)(EGLenum api); +typedef EGLBoolean (GLAD_API_PTR *PFNEGLBINDTEXIMAGEPROC)(EGLDisplay dpy, EGLSurface surface, EGLint buffer); +typedef EGLBoolean (GLAD_API_PTR *PFNEGLCHOOSECONFIGPROC)(EGLDisplay dpy, const EGLint * attrib_list, EGLConfig * configs, EGLint config_size, EGLint * num_config); +typedef EGLint (GLAD_API_PTR *PFNEGLCLIENTWAITSYNCPROC)(EGLDisplay dpy, EGLSync sync, EGLint flags, EGLTime timeout); +typedef EGLint (GLAD_API_PTR *PFNEGLCLIENTWAITSYNCKHRPROC)(EGLDisplay dpy, EGLSyncKHR sync, EGLint flags, EGLTimeKHR timeout); +typedef EGLBoolean (GLAD_API_PTR *PFNEGLCOPYBUFFERSPROC)(EGLDisplay dpy, EGLSurface surface, EGLNativePixmapType target); +typedef EGLContext (GLAD_API_PTR *PFNEGLCREATECONTEXTPROC)(EGLDisplay dpy, EGLConfig config, EGLContext share_context, const EGLint * attrib_list); +typedef EGLImage (GLAD_API_PTR *PFNEGLCREATEIMAGEPROC)(EGLDisplay dpy, EGLContext ctx, EGLenum target, EGLClientBuffer buffer, const EGLAttrib * attrib_list); +typedef EGLImageKHR (GLAD_API_PTR *PFNEGLCREATEIMAGEKHRPROC)(EGLDisplay dpy, EGLContext ctx, EGLenum target, EGLClientBuffer buffer, const EGLint * attrib_list); +typedef EGLSurface (GLAD_API_PTR *PFNEGLCREATEPBUFFERFROMCLIENTBUFFERPROC)(EGLDisplay dpy, EGLenum buftype, EGLClientBuffer buffer, EGLConfig config, const EGLint * attrib_list); +typedef EGLSurface (GLAD_API_PTR *PFNEGLCREATEPBUFFERSURFACEPROC)(EGLDisplay dpy, EGLConfig config, const EGLint * attrib_list); +typedef EGLSurface (GLAD_API_PTR *PFNEGLCREATEPIXMAPSURFACEPROC)(EGLDisplay dpy, EGLConfig config, EGLNativePixmapType pixmap, const EGLint * attrib_list); +typedef EGLSurface (GLAD_API_PTR *PFNEGLCREATEPLATFORMPIXMAPSURFACEPROC)(EGLDisplay dpy, EGLConfig config, void * native_pixmap, const EGLAttrib * attrib_list); +typedef EGLSurface (GLAD_API_PTR *PFNEGLCREATEPLATFORMPIXMAPSURFACEEXTPROC)(EGLDisplay dpy, EGLConfig config, void * native_pixmap, const EGLint * attrib_list); +typedef EGLSurface (GLAD_API_PTR *PFNEGLCREATEPLATFORMWINDOWSURFACEPROC)(EGLDisplay dpy, EGLConfig config, void * native_window, const EGLAttrib * attrib_list); +typedef EGLSurface (GLAD_API_PTR *PFNEGLCREATEPLATFORMWINDOWSURFACEEXTPROC)(EGLDisplay dpy, EGLConfig config, void * native_window, const EGLint * attrib_list); +typedef EGLSync (GLAD_API_PTR *PFNEGLCREATESYNCPROC)(EGLDisplay dpy, EGLenum type, const EGLAttrib * attrib_list); +typedef EGLSyncKHR (GLAD_API_PTR *PFNEGLCREATESYNC64KHRPROC)(EGLDisplay dpy, EGLenum type, const EGLAttribKHR * attrib_list); +typedef EGLSyncKHR (GLAD_API_PTR *PFNEGLCREATESYNCKHRPROC)(EGLDisplay dpy, EGLenum type, const EGLint * attrib_list); +typedef EGLSurface (GLAD_API_PTR *PFNEGLCREATEWINDOWSURFACEPROC)(EGLDisplay dpy, EGLConfig config, EGLNativeWindowType win, const EGLint * attrib_list); +typedef EGLBoolean (GLAD_API_PTR *PFNEGLDESTROYCONTEXTPROC)(EGLDisplay dpy, EGLContext ctx); +typedef EGLBoolean (GLAD_API_PTR *PFNEGLDESTROYIMAGEPROC)(EGLDisplay dpy, EGLImage image); +typedef EGLBoolean (GLAD_API_PTR *PFNEGLDESTROYIMAGEKHRPROC)(EGLDisplay dpy, EGLImageKHR image); +typedef EGLBoolean (GLAD_API_PTR *PFNEGLDESTROYSURFACEPROC)(EGLDisplay dpy, EGLSurface surface); +typedef EGLBoolean (GLAD_API_PTR *PFNEGLDESTROYSYNCPROC)(EGLDisplay dpy, EGLSync sync); +typedef EGLBoolean (GLAD_API_PTR *PFNEGLDESTROYSYNCKHRPROC)(EGLDisplay dpy, EGLSyncKHR sync); +typedef EGLBoolean (GLAD_API_PTR *PFNEGLGETCONFIGATTRIBPROC)(EGLDisplay dpy, EGLConfig config, EGLint attribute, EGLint * value); +typedef EGLBoolean (GLAD_API_PTR *PFNEGLGETCONFIGSPROC)(EGLDisplay dpy, EGLConfig * configs, EGLint config_size, EGLint * num_config); +typedef EGLContext (GLAD_API_PTR *PFNEGLGETCURRENTCONTEXTPROC)(void); +typedef EGLDisplay (GLAD_API_PTR *PFNEGLGETCURRENTDISPLAYPROC)(void); +typedef EGLSurface (GLAD_API_PTR *PFNEGLGETCURRENTSURFACEPROC)(EGLint readdraw); +typedef EGLDisplay (GLAD_API_PTR *PFNEGLGETDISPLAYPROC)(EGLNativeDisplayType display_id); +typedef EGLint (GLAD_API_PTR *PFNEGLGETERRORPROC)(void); +typedef EGLDisplay (GLAD_API_PTR *PFNEGLGETPLATFORMDISPLAYPROC)(EGLenum platform, void * native_display, const EGLAttrib * attrib_list); +typedef EGLDisplay (GLAD_API_PTR *PFNEGLGETPLATFORMDISPLAYEXTPROC)(EGLenum platform, void * native_display, const EGLint * attrib_list); +typedef __eglMustCastToProperFunctionPointerType (GLAD_API_PTR *PFNEGLGETPROCADDRESSPROC)(const char * procname); +typedef EGLBoolean (GLAD_API_PTR *PFNEGLGETSYNCATTRIBPROC)(EGLDisplay dpy, EGLSync sync, EGLint attribute, EGLAttrib * value); +typedef EGLBoolean (GLAD_API_PTR *PFNEGLGETSYNCATTRIBKHRPROC)(EGLDisplay dpy, EGLSyncKHR sync, EGLint attribute, EGLint * value); +typedef EGLBoolean (GLAD_API_PTR *PFNEGLINITIALIZEPROC)(EGLDisplay dpy, EGLint * major, EGLint * minor); +typedef EGLBoolean (GLAD_API_PTR *PFNEGLMAKECURRENTPROC)(EGLDisplay dpy, EGLSurface draw, EGLSurface read, EGLContext ctx); +typedef EGLenum (GLAD_API_PTR *PFNEGLQUERYAPIPROC)(void); +typedef EGLBoolean (GLAD_API_PTR *PFNEGLQUERYCONTEXTPROC)(EGLDisplay dpy, EGLContext ctx, EGLint attribute, EGLint * value); +typedef EGLBoolean (GLAD_API_PTR *PFNEGLQUERYDMABUFFORMATSEXTPROC)(EGLDisplay dpy, EGLint max_formats, EGLint * formats, EGLint * num_formats); +typedef EGLBoolean (GLAD_API_PTR *PFNEGLQUERYDMABUFMODIFIERSEXTPROC)(EGLDisplay dpy, EGLint format, EGLint max_modifiers, EGLuint64KHR * modifiers, EGLBoolean * external_only, EGLint * num_modifiers); +typedef const char * (GLAD_API_PTR *PFNEGLQUERYSTRINGPROC)(EGLDisplay dpy, EGLint name); +typedef EGLBoolean (GLAD_API_PTR *PFNEGLQUERYSURFACEPROC)(EGLDisplay dpy, EGLSurface surface, EGLint attribute, EGLint * value); +typedef EGLBoolean (GLAD_API_PTR *PFNEGLRELEASETEXIMAGEPROC)(EGLDisplay dpy, EGLSurface surface, EGLint buffer); +typedef EGLBoolean (GLAD_API_PTR *PFNEGLRELEASETHREADPROC)(void); +typedef EGLBoolean (GLAD_API_PTR *PFNEGLSIGNALSYNCKHRPROC)(EGLDisplay dpy, EGLSyncKHR sync, EGLenum mode); +typedef EGLBoolean (GLAD_API_PTR *PFNEGLSURFACEATTRIBPROC)(EGLDisplay dpy, EGLSurface surface, EGLint attribute, EGLint value); +typedef EGLBoolean (GLAD_API_PTR *PFNEGLSWAPBUFFERSPROC)(EGLDisplay dpy, EGLSurface surface); +typedef EGLBoolean (GLAD_API_PTR *PFNEGLSWAPINTERVALPROC)(EGLDisplay dpy, EGLint interval); +typedef EGLBoolean (GLAD_API_PTR *PFNEGLTERMINATEPROC)(EGLDisplay dpy); +typedef EGLBoolean (GLAD_API_PTR *PFNEGLWAITCLIENTPROC)(void); +typedef EGLBoolean (GLAD_API_PTR *PFNEGLWAITGLPROC)(void); +typedef EGLBoolean (GLAD_API_PTR *PFNEGLWAITNATIVEPROC)(EGLint engine); +typedef EGLBoolean (GLAD_API_PTR *PFNEGLWAITSYNCPROC)(EGLDisplay dpy, EGLSync sync, EGLint flags); + +GLAD_API_CALL PFNEGLBINDAPIPROC glad_eglBindAPI; +#define eglBindAPI glad_eglBindAPI +GLAD_API_CALL PFNEGLBINDTEXIMAGEPROC glad_eglBindTexImage; +#define eglBindTexImage glad_eglBindTexImage +GLAD_API_CALL PFNEGLCHOOSECONFIGPROC glad_eglChooseConfig; +#define eglChooseConfig glad_eglChooseConfig +GLAD_API_CALL PFNEGLCLIENTWAITSYNCPROC glad_eglClientWaitSync; +#define eglClientWaitSync glad_eglClientWaitSync +GLAD_API_CALL PFNEGLCLIENTWAITSYNCKHRPROC glad_eglClientWaitSyncKHR; +#define eglClientWaitSyncKHR glad_eglClientWaitSyncKHR +GLAD_API_CALL PFNEGLCOPYBUFFERSPROC glad_eglCopyBuffers; +#define eglCopyBuffers glad_eglCopyBuffers +GLAD_API_CALL PFNEGLCREATECONTEXTPROC glad_eglCreateContext; +#define eglCreateContext glad_eglCreateContext +GLAD_API_CALL PFNEGLCREATEIMAGEPROC glad_eglCreateImage; +#define eglCreateImage glad_eglCreateImage +GLAD_API_CALL PFNEGLCREATEIMAGEKHRPROC glad_eglCreateImageKHR; +#define eglCreateImageKHR glad_eglCreateImageKHR +GLAD_API_CALL PFNEGLCREATEPBUFFERFROMCLIENTBUFFERPROC glad_eglCreatePbufferFromClientBuffer; +#define eglCreatePbufferFromClientBuffer glad_eglCreatePbufferFromClientBuffer +GLAD_API_CALL PFNEGLCREATEPBUFFERSURFACEPROC glad_eglCreatePbufferSurface; +#define eglCreatePbufferSurface glad_eglCreatePbufferSurface +GLAD_API_CALL PFNEGLCREATEPIXMAPSURFACEPROC glad_eglCreatePixmapSurface; +#define eglCreatePixmapSurface glad_eglCreatePixmapSurface +GLAD_API_CALL PFNEGLCREATEPLATFORMPIXMAPSURFACEPROC glad_eglCreatePlatformPixmapSurface; +#define eglCreatePlatformPixmapSurface glad_eglCreatePlatformPixmapSurface +GLAD_API_CALL PFNEGLCREATEPLATFORMPIXMAPSURFACEEXTPROC glad_eglCreatePlatformPixmapSurfaceEXT; +#define eglCreatePlatformPixmapSurfaceEXT glad_eglCreatePlatformPixmapSurfaceEXT +GLAD_API_CALL PFNEGLCREATEPLATFORMWINDOWSURFACEPROC glad_eglCreatePlatformWindowSurface; +#define eglCreatePlatformWindowSurface glad_eglCreatePlatformWindowSurface +GLAD_API_CALL PFNEGLCREATEPLATFORMWINDOWSURFACEEXTPROC glad_eglCreatePlatformWindowSurfaceEXT; +#define eglCreatePlatformWindowSurfaceEXT glad_eglCreatePlatformWindowSurfaceEXT +GLAD_API_CALL PFNEGLCREATESYNCPROC glad_eglCreateSync; +#define eglCreateSync glad_eglCreateSync +GLAD_API_CALL PFNEGLCREATESYNC64KHRPROC glad_eglCreateSync64KHR; +#define eglCreateSync64KHR glad_eglCreateSync64KHR +GLAD_API_CALL PFNEGLCREATESYNCKHRPROC glad_eglCreateSyncKHR; +#define eglCreateSyncKHR glad_eglCreateSyncKHR +GLAD_API_CALL PFNEGLCREATEWINDOWSURFACEPROC glad_eglCreateWindowSurface; +#define eglCreateWindowSurface glad_eglCreateWindowSurface +GLAD_API_CALL PFNEGLDESTROYCONTEXTPROC glad_eglDestroyContext; +#define eglDestroyContext glad_eglDestroyContext +GLAD_API_CALL PFNEGLDESTROYIMAGEPROC glad_eglDestroyImage; +#define eglDestroyImage glad_eglDestroyImage +GLAD_API_CALL PFNEGLDESTROYIMAGEKHRPROC glad_eglDestroyImageKHR; +#define eglDestroyImageKHR glad_eglDestroyImageKHR +GLAD_API_CALL PFNEGLDESTROYSURFACEPROC glad_eglDestroySurface; +#define eglDestroySurface glad_eglDestroySurface +GLAD_API_CALL PFNEGLDESTROYSYNCPROC glad_eglDestroySync; +#define eglDestroySync glad_eglDestroySync +GLAD_API_CALL PFNEGLDESTROYSYNCKHRPROC glad_eglDestroySyncKHR; +#define eglDestroySyncKHR glad_eglDestroySyncKHR +GLAD_API_CALL PFNEGLGETCONFIGATTRIBPROC glad_eglGetConfigAttrib; +#define eglGetConfigAttrib glad_eglGetConfigAttrib +GLAD_API_CALL PFNEGLGETCONFIGSPROC glad_eglGetConfigs; +#define eglGetConfigs glad_eglGetConfigs +GLAD_API_CALL PFNEGLGETCURRENTCONTEXTPROC glad_eglGetCurrentContext; +#define eglGetCurrentContext glad_eglGetCurrentContext +GLAD_API_CALL PFNEGLGETCURRENTDISPLAYPROC glad_eglGetCurrentDisplay; +#define eglGetCurrentDisplay glad_eglGetCurrentDisplay +GLAD_API_CALL PFNEGLGETCURRENTSURFACEPROC glad_eglGetCurrentSurface; +#define eglGetCurrentSurface glad_eglGetCurrentSurface +GLAD_API_CALL PFNEGLGETDISPLAYPROC glad_eglGetDisplay; +#define eglGetDisplay glad_eglGetDisplay +GLAD_API_CALL PFNEGLGETERRORPROC glad_eglGetError; +#define eglGetError glad_eglGetError +GLAD_API_CALL PFNEGLGETPLATFORMDISPLAYPROC glad_eglGetPlatformDisplay; +#define eglGetPlatformDisplay glad_eglGetPlatformDisplay +GLAD_API_CALL PFNEGLGETPLATFORMDISPLAYEXTPROC glad_eglGetPlatformDisplayEXT; +#define eglGetPlatformDisplayEXT glad_eglGetPlatformDisplayEXT +GLAD_API_CALL PFNEGLGETPROCADDRESSPROC glad_eglGetProcAddress; +#define eglGetProcAddress glad_eglGetProcAddress +GLAD_API_CALL PFNEGLGETSYNCATTRIBPROC glad_eglGetSyncAttrib; +#define eglGetSyncAttrib glad_eglGetSyncAttrib +GLAD_API_CALL PFNEGLGETSYNCATTRIBKHRPROC glad_eglGetSyncAttribKHR; +#define eglGetSyncAttribKHR glad_eglGetSyncAttribKHR +GLAD_API_CALL PFNEGLINITIALIZEPROC glad_eglInitialize; +#define eglInitialize glad_eglInitialize +GLAD_API_CALL PFNEGLMAKECURRENTPROC glad_eglMakeCurrent; +#define eglMakeCurrent glad_eglMakeCurrent +GLAD_API_CALL PFNEGLQUERYAPIPROC glad_eglQueryAPI; +#define eglQueryAPI glad_eglQueryAPI +GLAD_API_CALL PFNEGLQUERYCONTEXTPROC glad_eglQueryContext; +#define eglQueryContext glad_eglQueryContext +GLAD_API_CALL PFNEGLQUERYDMABUFFORMATSEXTPROC glad_eglQueryDmaBufFormatsEXT; +#define eglQueryDmaBufFormatsEXT glad_eglQueryDmaBufFormatsEXT +GLAD_API_CALL PFNEGLQUERYDMABUFMODIFIERSEXTPROC glad_eglQueryDmaBufModifiersEXT; +#define eglQueryDmaBufModifiersEXT glad_eglQueryDmaBufModifiersEXT +GLAD_API_CALL PFNEGLQUERYSTRINGPROC glad_eglQueryString; +#define eglQueryString glad_eglQueryString +GLAD_API_CALL PFNEGLQUERYSURFACEPROC glad_eglQuerySurface; +#define eglQuerySurface glad_eglQuerySurface +GLAD_API_CALL PFNEGLRELEASETEXIMAGEPROC glad_eglReleaseTexImage; +#define eglReleaseTexImage glad_eglReleaseTexImage +GLAD_API_CALL PFNEGLRELEASETHREADPROC glad_eglReleaseThread; +#define eglReleaseThread glad_eglReleaseThread +GLAD_API_CALL PFNEGLSIGNALSYNCKHRPROC glad_eglSignalSyncKHR; +#define eglSignalSyncKHR glad_eglSignalSyncKHR +GLAD_API_CALL PFNEGLSURFACEATTRIBPROC glad_eglSurfaceAttrib; +#define eglSurfaceAttrib glad_eglSurfaceAttrib +GLAD_API_CALL PFNEGLSWAPBUFFERSPROC glad_eglSwapBuffers; +#define eglSwapBuffers glad_eglSwapBuffers +GLAD_API_CALL PFNEGLSWAPINTERVALPROC glad_eglSwapInterval; +#define eglSwapInterval glad_eglSwapInterval +GLAD_API_CALL PFNEGLTERMINATEPROC glad_eglTerminate; +#define eglTerminate glad_eglTerminate +GLAD_API_CALL PFNEGLWAITCLIENTPROC glad_eglWaitClient; +#define eglWaitClient glad_eglWaitClient +GLAD_API_CALL PFNEGLWAITGLPROC glad_eglWaitGL; +#define eglWaitGL glad_eglWaitGL +GLAD_API_CALL PFNEGLWAITNATIVEPROC glad_eglWaitNative; +#define eglWaitNative glad_eglWaitNative +GLAD_API_CALL PFNEGLWAITSYNCPROC glad_eglWaitSync; +#define eglWaitSync glad_eglWaitSync + + + + + +GLAD_API_CALL int gladLoadEGLUserPtr(EGLDisplay display, GLADuserptrloadfunc load, void *userptr); +GLAD_API_CALL int gladLoadEGL(EGLDisplay display, GLADloadfunc load); + + +#ifdef __cplusplus +} +#endif +#endif /*LV_USE_EGL*/ + +#endif diff --git a/src/drivers/opengles/glad/include/glad/gles2.h b/src/drivers/opengles/glad/include/glad/gles2.h new file mode 100644 index 0000000000..8738be8b47 --- /dev/null +++ b/src/drivers/opengles/glad/include/glad/gles2.h @@ -0,0 +1,1111 @@ +/** + * Loader generated by glad 2.0.8 on Tue Sep 30 16:40:43 2025 + * + * SPDX-License-Identifier: (WTFPL OR CC0-1.0) AND Apache-2.0 + * + * Generator: C/C++ + * Specification: gl + * Extensions: 14 + * + * APIs: + * - gles2=2.0 + * + * Options: + * - ALIAS = True + * - DEBUG = False + * - HEADER_ONLY = False + * - LOADER = False + * - MX = False + * - ON_DEMAND = False + * + * Commandline: + * --api='gles2=2.0' --extensions='GL_APPLE_texture_max_level,GL_ARM_rgba8,GL_EXT_color_buffer_float,GL_EXT_color_buffer_half_float,GL_EXT_texture_format_BGRA8888,GL_EXT_texture_storage,GL_EXT_unpack_subimage,GL_OES_depth24,GL_OES_mapbuffer,GL_OES_rgb8_rgba8,GL_OES_texture_float,GL_OES_texture_half_float,GL_OES_texture_storage_multisample_2d_array,GL_OES_vertex_array_object' c --alias + * + * Online: + * http://glad.sh/#api=gles2%3D2.0&extensions=GL_APPLE_texture_max_level%2CGL_ARM_rgba8%2CGL_EXT_color_buffer_float%2CGL_EXT_color_buffer_half_float%2CGL_EXT_texture_format_BGRA8888%2CGL_EXT_texture_storage%2CGL_EXT_unpack_subimage%2CGL_OES_depth24%2CGL_OES_mapbuffer%2CGL_OES_rgb8_rgba8%2CGL_OES_texture_float%2CGL_OES_texture_half_float%2CGL_OES_texture_storage_multisample_2d_array%2CGL_OES_vertex_array_object&generator=c&options=ALIAS + * + */ + +#ifndef GLAD_GLES2_H_ +#define GLAD_GLES2_H_ + +#include "../../../lv_opengles_egl.h" + +#if LV_USE_EGL + +#ifdef __clang__ +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Wreserved-id-macro" +#endif +#ifdef __gl2_h_ + #error OpenGL ES 2 header already included (API: gles2), remove previous include! +#endif +#define __gl2_h_ 1 +#ifdef __gles2_gl2_h_ + #error OpenGL ES 2 header already included (API: gles2), remove previous include! +#endif +#define __gles2_gl2_h_ 1 +#ifdef __gl3_h_ + #error OpenGL ES 3 header already included (API: gles2), remove previous include! +#endif +#define __gl3_h_ 1 +#ifdef __gles2_gl3_h_ + #error OpenGL ES 3 header already included (API: gles2), remove previous include! +#endif +#define __gles2_gl3_h_ 1 +#ifdef __clang__ +#pragma clang diagnostic pop +#endif + +#define GLAD_GLES2 +#define GLAD_OPTION_GLES2_ALIAS + +#ifdef __cplusplus +extern "C" { +#endif + +#ifndef GLAD_PLATFORM_H_ +#define GLAD_PLATFORM_H_ + +#ifndef GLAD_PLATFORM_WIN32 + #if defined(_WIN32) || defined(__WIN32__) || defined(WIN32) || defined(__MINGW32__) + #define GLAD_PLATFORM_WIN32 1 + #else + #define GLAD_PLATFORM_WIN32 0 + #endif +#endif + +#ifndef GLAD_PLATFORM_APPLE + #ifdef __APPLE__ + #define GLAD_PLATFORM_APPLE 1 + #else + #define GLAD_PLATFORM_APPLE 0 + #endif +#endif + +#ifndef GLAD_PLATFORM_EMSCRIPTEN + #ifdef __EMSCRIPTEN__ + #define GLAD_PLATFORM_EMSCRIPTEN 1 + #else + #define GLAD_PLATFORM_EMSCRIPTEN 0 + #endif +#endif + +#ifndef GLAD_PLATFORM_UWP + #if defined(_MSC_VER) && !defined(GLAD_INTERNAL_HAVE_WINAPIFAMILY) + #ifdef __has_include + #if __has_include() + #define GLAD_INTERNAL_HAVE_WINAPIFAMILY 1 + #endif + #elif _MSC_VER >= 1700 && !_USING_V110_SDK71_ + #define GLAD_INTERNAL_HAVE_WINAPIFAMILY 1 + #endif + #endif + + #ifdef GLAD_INTERNAL_HAVE_WINAPIFAMILY + #include + #if !WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP) && WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_APP) + #define GLAD_PLATFORM_UWP 1 + #endif + #endif + + #ifndef GLAD_PLATFORM_UWP + #define GLAD_PLATFORM_UWP 0 + #endif +#endif + +#ifdef __GNUC__ + #define GLAD_GNUC_EXTENSION __extension__ +#else + #define GLAD_GNUC_EXTENSION +#endif + +#define GLAD_UNUSED(x) (void)(x) + +#ifndef GLAD_API_CALL + #if defined(GLAD_API_CALL_EXPORT) + #if GLAD_PLATFORM_WIN32 || defined(__CYGWIN__) + #if defined(GLAD_API_CALL_EXPORT_BUILD) + #if defined(__GNUC__) + #define GLAD_API_CALL __attribute__ ((dllexport)) extern + #else + #define GLAD_API_CALL __declspec(dllexport) extern + #endif + #else + #if defined(__GNUC__) + #define GLAD_API_CALL __attribute__ ((dllimport)) extern + #else + #define GLAD_API_CALL __declspec(dllimport) extern + #endif + #endif + #elif defined(__GNUC__) && defined(GLAD_API_CALL_EXPORT_BUILD) + #define GLAD_API_CALL __attribute__ ((visibility ("default"))) extern + #else + #define GLAD_API_CALL extern + #endif + #else + #define GLAD_API_CALL extern + #endif +#endif + +#ifdef APIENTRY + #define GLAD_API_PTR APIENTRY +#elif GLAD_PLATFORM_WIN32 + #define GLAD_API_PTR __stdcall +#else + #define GLAD_API_PTR +#endif + +#ifndef GLAPI +#define GLAPI GLAD_API_CALL +#endif + +#ifndef GLAPIENTRY +#define GLAPIENTRY GLAD_API_PTR +#endif + +#define GLAD_MAKE_VERSION(major, minor) (major * 10000 + minor) +#define GLAD_VERSION_MAJOR(version) (version / 10000) +#define GLAD_VERSION_MINOR(version) (version % 10000) + +#define GLAD_GENERATOR_VERSION "2.0.8" + +typedef void (*GLADapiproc)(void); + +typedef GLADapiproc (*GLADloadfunc)(const char *name); +typedef GLADapiproc (*GLADuserptrloadfunc)(void *userptr, const char *name); + +typedef void (*GLADprecallback)(const char *name, GLADapiproc apiproc, int len_args, ...); +typedef void (*GLADpostcallback)(void *ret, const char *name, GLADapiproc apiproc, int len_args, ...); + +#endif /* GLAD_PLATFORM_H_ */ + +#define GL_ACTIVE_ATTRIBUTES 0x8B89 +#define GL_ACTIVE_ATTRIBUTE_MAX_LENGTH 0x8B8A +#define GL_ACTIVE_TEXTURE 0x84E0 +#define GL_ACTIVE_UNIFORMS 0x8B86 +#define GL_ACTIVE_UNIFORM_MAX_LENGTH 0x8B87 +#define GL_ALIASED_LINE_WIDTH_RANGE 0x846E +#define GL_ALIASED_POINT_SIZE_RANGE 0x846D +#define GL_ALPHA 0x1906 +#define GL_ALPHA16F_EXT 0x881C +#define GL_ALPHA32F_EXT 0x8816 +#define GL_ALPHA8_EXT 0x803C +#define GL_ALPHA_BITS 0x0D55 +#define GL_ALWAYS 0x0207 +#define GL_ARRAY_BUFFER 0x8892 +#define GL_ARRAY_BUFFER_BINDING 0x8894 +#define GL_ATTACHED_SHADERS 0x8B85 +#define GL_BACK 0x0405 +#define GL_BGRA8_EXT 0x93A1 +#define GL_BGRA_EXT 0x80E1 +#define GL_BLEND 0x0BE2 +#define GL_BLEND_COLOR 0x8005 +#define GL_BLEND_DST_ALPHA 0x80CA +#define GL_BLEND_DST_RGB 0x80C8 +#define GL_BLEND_EQUATION 0x8009 +#define GL_BLEND_EQUATION_ALPHA 0x883D +#define GL_BLEND_EQUATION_RGB 0x8009 +#define GL_BLEND_SRC_ALPHA 0x80CB +#define GL_BLEND_SRC_RGB 0x80C9 +#define GL_BLUE_BITS 0x0D54 +#define GL_BOOL 0x8B56 +#define GL_BOOL_VEC2 0x8B57 +#define GL_BOOL_VEC3 0x8B58 +#define GL_BOOL_VEC4 0x8B59 +#define GL_BUFFER_ACCESS_OES 0x88BB +#define GL_BUFFER_MAPPED_OES 0x88BC +#define GL_BUFFER_MAP_POINTER_OES 0x88BD +#define GL_BUFFER_SIZE 0x8764 +#define GL_BUFFER_USAGE 0x8765 +#define GL_BYTE 0x1400 +#define GL_CCW 0x0901 +#define GL_CLAMP_TO_EDGE 0x812F +#define GL_COLOR_ATTACHMENT0 0x8CE0 +#define GL_COLOR_BUFFER_BIT 0x00004000 +#define GL_COLOR_CLEAR_VALUE 0x0C22 +#define GL_COLOR_WRITEMASK 0x0C23 +#define GL_COMPILE_STATUS 0x8B81 +#define GL_COMPRESSED_TEXTURE_FORMATS 0x86A3 +#define GL_CONSTANT_ALPHA 0x8003 +#define GL_CONSTANT_COLOR 0x8001 +#define GL_CULL_FACE 0x0B44 +#define GL_CULL_FACE_MODE 0x0B45 +#define GL_CURRENT_PROGRAM 0x8B8D +#define GL_CURRENT_VERTEX_ATTRIB 0x8626 +#define GL_CW 0x0900 +#define GL_DECR 0x1E03 +#define GL_DECR_WRAP 0x8508 +#define GL_DELETE_STATUS 0x8B80 +#define GL_DEPTH_ATTACHMENT 0x8D00 +#define GL_DEPTH_BITS 0x0D56 +#define GL_DEPTH_BUFFER_BIT 0x00000100 +#define GL_DEPTH_CLEAR_VALUE 0x0B73 +#define GL_DEPTH_COMPONENT 0x1902 +#define GL_DEPTH_COMPONENT16 0x81A5 +#define GL_DEPTH_COMPONENT24_OES 0x81A6 +#define GL_DEPTH_FUNC 0x0B74 +#define GL_DEPTH_RANGE 0x0B70 +#define GL_DEPTH_TEST 0x0B71 +#define GL_DEPTH_WRITEMASK 0x0B72 +#define GL_DITHER 0x0BD0 +#define GL_DONT_CARE 0x1100 +#define GL_DST_ALPHA 0x0304 +#define GL_DST_COLOR 0x0306 +#define GL_DYNAMIC_DRAW 0x88E8 +#define GL_ELEMENT_ARRAY_BUFFER 0x8893 +#define GL_ELEMENT_ARRAY_BUFFER_BINDING 0x8895 +#define GL_EQUAL 0x0202 +#define GL_EXTENSIONS 0x1F03 +#define GL_FALSE 0 +#define GL_FASTEST 0x1101 +#define GL_FIXED 0x140C +#define GL_FLOAT 0x1406 +#define GL_FLOAT_MAT2 0x8B5A +#define GL_FLOAT_MAT3 0x8B5B +#define GL_FLOAT_MAT4 0x8B5C +#define GL_FLOAT_VEC2 0x8B50 +#define GL_FLOAT_VEC3 0x8B51 +#define GL_FLOAT_VEC4 0x8B52 +#define GL_FRAGMENT_SHADER 0x8B30 +#define GL_FRAMEBUFFER 0x8D40 +#define GL_FRAMEBUFFER_ATTACHMENT_COMPONENT_TYPE_EXT 0x8211 +#define GL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME 0x8CD1 +#define GL_FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE 0x8CD0 +#define GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_CUBE_MAP_FACE 0x8CD3 +#define GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_LEVEL 0x8CD2 +#define GL_FRAMEBUFFER_BINDING 0x8CA6 +#define GL_FRAMEBUFFER_COMPLETE 0x8CD5 +#define GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT 0x8CD6 +#define GL_FRAMEBUFFER_INCOMPLETE_DIMENSIONS 0x8CD9 +#define GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT 0x8CD7 +#define GL_FRAMEBUFFER_UNSUPPORTED 0x8CDD +#define GL_FRONT 0x0404 +#define GL_FRONT_AND_BACK 0x0408 +#define GL_FRONT_FACE 0x0B46 +#define GL_FUNC_ADD 0x8006 +#define GL_FUNC_REVERSE_SUBTRACT 0x800B +#define GL_FUNC_SUBTRACT 0x800A +#define GL_GENERATE_MIPMAP_HINT 0x8192 +#define GL_GEQUAL 0x0206 +#define GL_GREATER 0x0204 +#define GL_GREEN_BITS 0x0D53 +#define GL_HALF_FLOAT_OES 0x8D61 +#define GL_HIGH_FLOAT 0x8DF2 +#define GL_HIGH_INT 0x8DF5 +#define GL_IMPLEMENTATION_COLOR_READ_FORMAT 0x8B9B +#define GL_IMPLEMENTATION_COLOR_READ_TYPE 0x8B9A +#define GL_INCR 0x1E02 +#define GL_INCR_WRAP 0x8507 +#define GL_INFO_LOG_LENGTH 0x8B84 +#define GL_INT 0x1404 +#define GL_INT_SAMPLER_2D_MULTISAMPLE_ARRAY_OES 0x910C +#define GL_INT_VEC2 0x8B53 +#define GL_INT_VEC3 0x8B54 +#define GL_INT_VEC4 0x8B55 +#define GL_INVALID_ENUM 0x0500 +#define GL_INVALID_FRAMEBUFFER_OPERATION 0x0506 +#define GL_INVALID_OPERATION 0x0502 +#define GL_INVALID_VALUE 0x0501 +#define GL_INVERT 0x150A +#define GL_KEEP 0x1E00 +#define GL_LEQUAL 0x0203 +#define GL_LESS 0x0201 +#define GL_LINEAR 0x2601 +#define GL_LINEAR_MIPMAP_LINEAR 0x2703 +#define GL_LINEAR_MIPMAP_NEAREST 0x2701 +#define GL_LINES 0x0001 +#define GL_LINE_LOOP 0x0002 +#define GL_LINE_STRIP 0x0003 +#define GL_LINE_WIDTH 0x0B21 +#define GL_LINK_STATUS 0x8B82 +#define GL_LOW_FLOAT 0x8DF0 +#define GL_LOW_INT 0x8DF3 +#define GL_LUMINANCE 0x1909 +#define GL_LUMINANCE16F_EXT 0x881E +#define GL_LUMINANCE32F_EXT 0x8818 +#define GL_LUMINANCE8_ALPHA8_EXT 0x8045 +#define GL_LUMINANCE8_EXT 0x8040 +#define GL_LUMINANCE_ALPHA 0x190A +#define GL_LUMINANCE_ALPHA16F_EXT 0x881F +#define GL_LUMINANCE_ALPHA32F_EXT 0x8819 +#define GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS 0x8B4D +#define GL_MAX_CUBE_MAP_TEXTURE_SIZE 0x851C +#define GL_MAX_FRAGMENT_UNIFORM_VECTORS 0x8DFD +#define GL_MAX_RENDERBUFFER_SIZE 0x84E8 +#define GL_MAX_TEXTURE_IMAGE_UNITS 0x8872 +#define GL_MAX_TEXTURE_SIZE 0x0D33 +#define GL_MAX_VARYING_VECTORS 0x8DFC +#define GL_MAX_VERTEX_ATTRIBS 0x8869 +#define GL_MAX_VERTEX_TEXTURE_IMAGE_UNITS 0x8B4C +#define GL_MAX_VERTEX_UNIFORM_VECTORS 0x8DFB +#define GL_MAX_VIEWPORT_DIMS 0x0D3A +#define GL_MEDIUM_FLOAT 0x8DF1 +#define GL_MEDIUM_INT 0x8DF4 +#define GL_MIRRORED_REPEAT 0x8370 +#define GL_NEAREST 0x2600 +#define GL_NEAREST_MIPMAP_LINEAR 0x2702 +#define GL_NEAREST_MIPMAP_NEAREST 0x2700 +#define GL_NEVER 0x0200 +#define GL_NICEST 0x1102 +#define GL_NONE 0 +#define GL_NOTEQUAL 0x0205 +#define GL_NO_ERROR 0 +#define GL_NUM_COMPRESSED_TEXTURE_FORMATS 0x86A2 +#define GL_NUM_SHADER_BINARY_FORMATS 0x8DF9 +#define GL_ONE 1 +#define GL_ONE_MINUS_CONSTANT_ALPHA 0x8004 +#define GL_ONE_MINUS_CONSTANT_COLOR 0x8002 +#define GL_ONE_MINUS_DST_ALPHA 0x0305 +#define GL_ONE_MINUS_DST_COLOR 0x0307 +#define GL_ONE_MINUS_SRC_ALPHA 0x0303 +#define GL_ONE_MINUS_SRC_COLOR 0x0301 +#define GL_OUT_OF_MEMORY 0x0505 +#define GL_PACK_ALIGNMENT 0x0D05 +#define GL_POINTS 0x0000 +#define GL_POLYGON_OFFSET_FACTOR 0x8038 +#define GL_POLYGON_OFFSET_FILL 0x8037 +#define GL_POLYGON_OFFSET_UNITS 0x2A00 +#define GL_R16F_EXT 0x822D +#define GL_R32F_EXT 0x822E +#define GL_R8_EXT 0x8229 +#define GL_RED_BITS 0x0D52 +#define GL_RENDERBUFFER 0x8D41 +#define GL_RENDERBUFFER_ALPHA_SIZE 0x8D53 +#define GL_RENDERBUFFER_BINDING 0x8CA7 +#define GL_RENDERBUFFER_BLUE_SIZE 0x8D52 +#define GL_RENDERBUFFER_DEPTH_SIZE 0x8D54 +#define GL_RENDERBUFFER_GREEN_SIZE 0x8D51 +#define GL_RENDERBUFFER_HEIGHT 0x8D43 +#define GL_RENDERBUFFER_INTERNAL_FORMAT 0x8D44 +#define GL_RENDERBUFFER_RED_SIZE 0x8D50 +#define GL_RENDERBUFFER_STENCIL_SIZE 0x8D55 +#define GL_RENDERBUFFER_WIDTH 0x8D42 +#define GL_RENDERER 0x1F01 +#define GL_REPEAT 0x2901 +#define GL_REPLACE 0x1E01 +#define GL_RG16F_EXT 0x822F +#define GL_RG32F_EXT 0x8230 +#define GL_RG8_EXT 0x822B +#define GL_RGB 0x1907 +#define GL_RGB10_A2_EXT 0x8059 +#define GL_RGB10_EXT 0x8052 +#define GL_RGB16F_EXT 0x881B +#define GL_RGB32F_EXT 0x8815 +#define GL_RGB565 0x8D62 +#define GL_RGB5_A1 0x8057 +#define GL_RGB8_OES 0x8051 +#define GL_RGBA 0x1908 +#define GL_RGBA16F_EXT 0x881A +#define GL_RGBA32F_EXT 0x8814 +#define GL_RGBA4 0x8056 +#define GL_RGBA8_OES 0x8058 +#define GL_SAMPLER_2D 0x8B5E +#define GL_SAMPLER_2D_MULTISAMPLE_ARRAY_OES 0x910B +#define GL_SAMPLER_CUBE 0x8B60 +#define GL_SAMPLES 0x80A9 +#define GL_SAMPLE_ALPHA_TO_COVERAGE 0x809E +#define GL_SAMPLE_BUFFERS 0x80A8 +#define GL_SAMPLE_COVERAGE 0x80A0 +#define GL_SAMPLE_COVERAGE_INVERT 0x80AB +#define GL_SAMPLE_COVERAGE_VALUE 0x80AA +#define GL_SCISSOR_BOX 0x0C10 +#define GL_SCISSOR_TEST 0x0C11 +#define GL_SHADER_BINARY_FORMATS 0x8DF8 +#define GL_SHADER_COMPILER 0x8DFA +#define GL_SHADER_SOURCE_LENGTH 0x8B88 +#define GL_SHADER_TYPE 0x8B4F +#define GL_SHADING_LANGUAGE_VERSION 0x8B8C +#define GL_SHORT 0x1402 +#define GL_SRC_ALPHA 0x0302 +#define GL_SRC_ALPHA_SATURATE 0x0308 +#define GL_SRC_COLOR 0x0300 +#define GL_STATIC_DRAW 0x88E4 +#define GL_STENCIL_ATTACHMENT 0x8D20 +#define GL_STENCIL_BACK_FAIL 0x8801 +#define GL_STENCIL_BACK_FUNC 0x8800 +#define GL_STENCIL_BACK_PASS_DEPTH_FAIL 0x8802 +#define GL_STENCIL_BACK_PASS_DEPTH_PASS 0x8803 +#define GL_STENCIL_BACK_REF 0x8CA3 +#define GL_STENCIL_BACK_VALUE_MASK 0x8CA4 +#define GL_STENCIL_BACK_WRITEMASK 0x8CA5 +#define GL_STENCIL_BITS 0x0D57 +#define GL_STENCIL_BUFFER_BIT 0x00000400 +#define GL_STENCIL_CLEAR_VALUE 0x0B91 +#define GL_STENCIL_FAIL 0x0B94 +#define GL_STENCIL_FUNC 0x0B92 +#define GL_STENCIL_INDEX8 0x8D48 +#define GL_STENCIL_PASS_DEPTH_FAIL 0x0B95 +#define GL_STENCIL_PASS_DEPTH_PASS 0x0B96 +#define GL_STENCIL_REF 0x0B97 +#define GL_STENCIL_TEST 0x0B90 +#define GL_STENCIL_VALUE_MASK 0x0B93 +#define GL_STENCIL_WRITEMASK 0x0B98 +#define GL_STREAM_DRAW 0x88E0 +#define GL_SUBPIXEL_BITS 0x0D50 +#define GL_TEXTURE 0x1702 +#define GL_TEXTURE0 0x84C0 +#define GL_TEXTURE1 0x84C1 +#define GL_TEXTURE10 0x84CA +#define GL_TEXTURE11 0x84CB +#define GL_TEXTURE12 0x84CC +#define GL_TEXTURE13 0x84CD +#define GL_TEXTURE14 0x84CE +#define GL_TEXTURE15 0x84CF +#define GL_TEXTURE16 0x84D0 +#define GL_TEXTURE17 0x84D1 +#define GL_TEXTURE18 0x84D2 +#define GL_TEXTURE19 0x84D3 +#define GL_TEXTURE2 0x84C2 +#define GL_TEXTURE20 0x84D4 +#define GL_TEXTURE21 0x84D5 +#define GL_TEXTURE22 0x84D6 +#define GL_TEXTURE23 0x84D7 +#define GL_TEXTURE24 0x84D8 +#define GL_TEXTURE25 0x84D9 +#define GL_TEXTURE26 0x84DA +#define GL_TEXTURE27 0x84DB +#define GL_TEXTURE28 0x84DC +#define GL_TEXTURE29 0x84DD +#define GL_TEXTURE3 0x84C3 +#define GL_TEXTURE30 0x84DE +#define GL_TEXTURE31 0x84DF +#define GL_TEXTURE4 0x84C4 +#define GL_TEXTURE5 0x84C5 +#define GL_TEXTURE6 0x84C6 +#define GL_TEXTURE7 0x84C7 +#define GL_TEXTURE8 0x84C8 +#define GL_TEXTURE9 0x84C9 +#define GL_TEXTURE_2D 0x0DE1 +#define GL_TEXTURE_2D_MULTISAMPLE_ARRAY_OES 0x9102 +#define GL_TEXTURE_BINDING_2D 0x8069 +#define GL_TEXTURE_BINDING_2D_MULTISAMPLE_ARRAY_OES 0x9105 +#define GL_TEXTURE_BINDING_CUBE_MAP 0x8514 +#define GL_TEXTURE_CUBE_MAP 0x8513 +#define GL_TEXTURE_CUBE_MAP_NEGATIVE_X 0x8516 +#define GL_TEXTURE_CUBE_MAP_NEGATIVE_Y 0x8518 +#define GL_TEXTURE_CUBE_MAP_NEGATIVE_Z 0x851A +#define GL_TEXTURE_CUBE_MAP_POSITIVE_X 0x8515 +#define GL_TEXTURE_CUBE_MAP_POSITIVE_Y 0x8517 +#define GL_TEXTURE_CUBE_MAP_POSITIVE_Z 0x8519 +#define GL_TEXTURE_IMMUTABLE_FORMAT_EXT 0x912F +#define GL_TEXTURE_MAG_FILTER 0x2800 +#define GL_TEXTURE_MAX_LEVEL_APPLE 0x813D +#define GL_TEXTURE_MIN_FILTER 0x2801 +#define GL_TEXTURE_WRAP_S 0x2802 +#define GL_TEXTURE_WRAP_T 0x2803 +#define GL_TRIANGLES 0x0004 +#define GL_TRIANGLE_FAN 0x0006 +#define GL_TRIANGLE_STRIP 0x0005 +#define GL_TRUE 1 +#define GL_UNPACK_ALIGNMENT 0x0CF5 +#define GL_UNPACK_ROW_LENGTH_EXT 0x0CF2 +#define GL_UNPACK_SKIP_PIXELS_EXT 0x0CF4 +#define GL_UNPACK_SKIP_ROWS_EXT 0x0CF3 +#define GL_UNSIGNED_BYTE 0x1401 +#define GL_UNSIGNED_INT 0x1405 +#define GL_UNSIGNED_INT_SAMPLER_2D_MULTISAMPLE_ARRAY_OES 0x910D +#define GL_UNSIGNED_NORMALIZED_EXT 0x8C17 +#define GL_UNSIGNED_SHORT 0x1403 +#define GL_UNSIGNED_SHORT_4_4_4_4 0x8033 +#define GL_UNSIGNED_SHORT_5_5_5_1 0x8034 +#define GL_UNSIGNED_SHORT_5_6_5 0x8363 +#define GL_VALIDATE_STATUS 0x8B83 +#define GL_VENDOR 0x1F00 +#define GL_VERSION 0x1F02 +#define GL_VERTEX_ARRAY_BINDING_OES 0x85B5 +#define GL_VERTEX_ATTRIB_ARRAY_BUFFER_BINDING 0x889F +#define GL_VERTEX_ATTRIB_ARRAY_ENABLED 0x8622 +#define GL_VERTEX_ATTRIB_ARRAY_NORMALIZED 0x886A +#define GL_VERTEX_ATTRIB_ARRAY_POINTER 0x8645 +#define GL_VERTEX_ATTRIB_ARRAY_SIZE 0x8623 +#define GL_VERTEX_ATTRIB_ARRAY_STRIDE 0x8624 +#define GL_VERTEX_ATTRIB_ARRAY_TYPE 0x8625 +#define GL_VERTEX_SHADER 0x8B31 +#define GL_VIEWPORT 0x0BA2 +#define GL_WRITE_ONLY_OES 0x88B9 +#define GL_ZERO 0 + + +#include +typedef unsigned int GLenum; +typedef unsigned char GLboolean; +typedef unsigned int GLbitfield; +typedef void GLvoid; +typedef khronos_int8_t GLbyte; +typedef khronos_uint8_t GLubyte; +typedef khronos_int16_t GLshort; +typedef khronos_uint16_t GLushort; +typedef int GLint; +typedef unsigned int GLuint; +typedef khronos_int32_t GLclampx; +typedef int GLsizei; +typedef khronos_float_t GLfloat; +typedef khronos_float_t GLclampf; +typedef double GLdouble; +typedef double GLclampd; +typedef void *GLeglClientBufferEXT; +typedef void *GLeglImageOES; +typedef char GLchar; +typedef char GLcharARB; +#ifdef __APPLE__ +typedef void *GLhandleARB; +#else +typedef unsigned int GLhandleARB; +#endif +typedef khronos_uint16_t GLhalf; +typedef khronos_uint16_t GLhalfARB; +typedef khronos_int32_t GLfixed; +#if defined(__ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__) && (__ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__ > 1060) +typedef khronos_intptr_t GLintptr; +#else +typedef khronos_intptr_t GLintptr; +#endif +#if defined(__ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__) && (__ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__ > 1060) +typedef khronos_intptr_t GLintptrARB; +#else +typedef khronos_intptr_t GLintptrARB; +#endif +#if defined(__ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__) && (__ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__ > 1060) +typedef khronos_ssize_t GLsizeiptr; +#else +typedef khronos_ssize_t GLsizeiptr; +#endif +#if defined(__ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__) && (__ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__ > 1060) +typedef khronos_ssize_t GLsizeiptrARB; +#else +typedef khronos_ssize_t GLsizeiptrARB; +#endif +typedef khronos_int64_t GLint64; +typedef khronos_int64_t GLint64EXT; +typedef khronos_uint64_t GLuint64; +typedef khronos_uint64_t GLuint64EXT; +typedef struct __GLsync *GLsync; +struct _cl_context; +struct _cl_event; +typedef void (GLAD_API_PTR *GLDEBUGPROC)(GLenum source,GLenum type,GLuint id,GLenum severity,GLsizei length,const GLchar *message,const void *userParam); +typedef void (GLAD_API_PTR *GLDEBUGPROCARB)(GLenum source,GLenum type,GLuint id,GLenum severity,GLsizei length,const GLchar *message,const void *userParam); +typedef void (GLAD_API_PTR *GLDEBUGPROCKHR)(GLenum source,GLenum type,GLuint id,GLenum severity,GLsizei length,const GLchar *message,const void *userParam); +typedef void (GLAD_API_PTR *GLDEBUGPROCAMD)(GLuint id,GLenum category,GLenum severity,GLsizei length,const GLchar *message,void *userParam); +typedef unsigned short GLhalfNV; +typedef GLintptr GLvdpauSurfaceNV; +typedef void (GLAD_API_PTR *GLVULKANPROCNV)(void); + + +#define GL_ES_VERSION_2_0 1 +GLAD_API_CALL int GLAD_GL_ES_VERSION_2_0; +#define GL_APPLE_texture_max_level 1 +GLAD_API_CALL int GLAD_GL_APPLE_texture_max_level; +#define GL_ARM_rgba8 1 +GLAD_API_CALL int GLAD_GL_ARM_rgba8; +#define GL_EXT_color_buffer_float 1 +GLAD_API_CALL int GLAD_GL_EXT_color_buffer_float; +#define GL_EXT_color_buffer_half_float 1 +GLAD_API_CALL int GLAD_GL_EXT_color_buffer_half_float; +#define GL_EXT_texture_format_BGRA8888 1 +GLAD_API_CALL int GLAD_GL_EXT_texture_format_BGRA8888; +#define GL_EXT_texture_storage 1 +GLAD_API_CALL int GLAD_GL_EXT_texture_storage; +#define GL_EXT_unpack_subimage 1 +GLAD_API_CALL int GLAD_GL_EXT_unpack_subimage; +#define GL_OES_depth24 1 +GLAD_API_CALL int GLAD_GL_OES_depth24; +#define GL_OES_mapbuffer 1 +GLAD_API_CALL int GLAD_GL_OES_mapbuffer; +#define GL_OES_rgb8_rgba8 1 +GLAD_API_CALL int GLAD_GL_OES_rgb8_rgba8; +#define GL_OES_texture_float 1 +GLAD_API_CALL int GLAD_GL_OES_texture_float; +#define GL_OES_texture_half_float 1 +GLAD_API_CALL int GLAD_GL_OES_texture_half_float; +#define GL_OES_texture_storage_multisample_2d_array 1 +GLAD_API_CALL int GLAD_GL_OES_texture_storage_multisample_2d_array; +#define GL_OES_vertex_array_object 1 +GLAD_API_CALL int GLAD_GL_OES_vertex_array_object; + + +typedef void (GLAD_API_PTR *PFNGLACTIVETEXTUREPROC)(GLenum texture); +typedef void (GLAD_API_PTR *PFNGLATTACHSHADERPROC)(GLuint program, GLuint shader); +typedef void (GLAD_API_PTR *PFNGLBINDATTRIBLOCATIONPROC)(GLuint program, GLuint index, const GLchar * name); +typedef void (GLAD_API_PTR *PFNGLBINDBUFFERPROC)(GLenum target, GLuint buffer); +typedef void (GLAD_API_PTR *PFNGLBINDFRAMEBUFFERPROC)(GLenum target, GLuint framebuffer); +typedef void (GLAD_API_PTR *PFNGLBINDRENDERBUFFERPROC)(GLenum target, GLuint renderbuffer); +typedef void (GLAD_API_PTR *PFNGLBINDTEXTUREPROC)(GLenum target, GLuint texture); +typedef void (GLAD_API_PTR *PFNGLBINDVERTEXARRAYOESPROC)(GLuint array); +typedef void (GLAD_API_PTR *PFNGLBLENDCOLORPROC)(GLfloat red, GLfloat green, GLfloat blue, GLfloat alpha); +typedef void (GLAD_API_PTR *PFNGLBLENDEQUATIONPROC)(GLenum mode); +typedef void (GLAD_API_PTR *PFNGLBLENDEQUATIONSEPARATEPROC)(GLenum modeRGB, GLenum modeAlpha); +typedef void (GLAD_API_PTR *PFNGLBLENDFUNCPROC)(GLenum sfactor, GLenum dfactor); +typedef void (GLAD_API_PTR *PFNGLBLENDFUNCSEPARATEPROC)(GLenum sfactorRGB, GLenum dfactorRGB, GLenum sfactorAlpha, GLenum dfactorAlpha); +typedef void (GLAD_API_PTR *PFNGLBUFFERDATAPROC)(GLenum target, GLsizeiptr size, const void * data, GLenum usage); +typedef void (GLAD_API_PTR *PFNGLBUFFERSUBDATAPROC)(GLenum target, GLintptr offset, GLsizeiptr size, const void * data); +typedef GLenum (GLAD_API_PTR *PFNGLCHECKFRAMEBUFFERSTATUSPROC)(GLenum target); +typedef void (GLAD_API_PTR *PFNGLCLEARPROC)(GLbitfield mask); +typedef void (GLAD_API_PTR *PFNGLCLEARCOLORPROC)(GLfloat red, GLfloat green, GLfloat blue, GLfloat alpha); +typedef void (GLAD_API_PTR *PFNGLCLEARDEPTHFPROC)(GLfloat d); +typedef void (GLAD_API_PTR *PFNGLCLEARSTENCILPROC)(GLint s); +typedef void (GLAD_API_PTR *PFNGLCOLORMASKPROC)(GLboolean red, GLboolean green, GLboolean blue, GLboolean alpha); +typedef void (GLAD_API_PTR *PFNGLCOMPILESHADERPROC)(GLuint shader); +typedef void (GLAD_API_PTR *PFNGLCOMPRESSEDTEXIMAGE2DPROC)(GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLint border, GLsizei imageSize, const void * data); +typedef void (GLAD_API_PTR *PFNGLCOMPRESSEDTEXSUBIMAGE2DPROC)(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLsizei imageSize, const void * data); +typedef void (GLAD_API_PTR *PFNGLCOPYTEXIMAGE2DPROC)(GLenum target, GLint level, GLenum internalformat, GLint x, GLint y, GLsizei width, GLsizei height, GLint border); +typedef void (GLAD_API_PTR *PFNGLCOPYTEXSUBIMAGE2DPROC)(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint x, GLint y, GLsizei width, GLsizei height); +typedef GLuint (GLAD_API_PTR *PFNGLCREATEPROGRAMPROC)(void); +typedef GLuint (GLAD_API_PTR *PFNGLCREATESHADERPROC)(GLenum type); +typedef void (GLAD_API_PTR *PFNGLCULLFACEPROC)(GLenum mode); +typedef void (GLAD_API_PTR *PFNGLDELETEBUFFERSPROC)(GLsizei n, const GLuint * buffers); +typedef void (GLAD_API_PTR *PFNGLDELETEFRAMEBUFFERSPROC)(GLsizei n, const GLuint * framebuffers); +typedef void (GLAD_API_PTR *PFNGLDELETEPROGRAMPROC)(GLuint program); +typedef void (GLAD_API_PTR *PFNGLDELETERENDERBUFFERSPROC)(GLsizei n, const GLuint * renderbuffers); +typedef void (GLAD_API_PTR *PFNGLDELETESHADERPROC)(GLuint shader); +typedef void (GLAD_API_PTR *PFNGLDELETETEXTURESPROC)(GLsizei n, const GLuint * textures); +typedef void (GLAD_API_PTR *PFNGLDELETEVERTEXARRAYSOESPROC)(GLsizei n, const GLuint * arrays); +typedef void (GLAD_API_PTR *PFNGLDEPTHFUNCPROC)(GLenum func); +typedef void (GLAD_API_PTR *PFNGLDEPTHMASKPROC)(GLboolean flag); +typedef void (GLAD_API_PTR *PFNGLDEPTHRANGEFPROC)(GLfloat n, GLfloat f); +typedef void (GLAD_API_PTR *PFNGLDETACHSHADERPROC)(GLuint program, GLuint shader); +typedef void (GLAD_API_PTR *PFNGLDISABLEPROC)(GLenum cap); +typedef void (GLAD_API_PTR *PFNGLDISABLEVERTEXATTRIBARRAYPROC)(GLuint index); +typedef void (GLAD_API_PTR *PFNGLDRAWARRAYSPROC)(GLenum mode, GLint first, GLsizei count); +typedef void (GLAD_API_PTR *PFNGLDRAWELEMENTSPROC)(GLenum mode, GLsizei count, GLenum type, const void * indices); +typedef void (GLAD_API_PTR *PFNGLENABLEPROC)(GLenum cap); +typedef void (GLAD_API_PTR *PFNGLENABLEVERTEXATTRIBARRAYPROC)(GLuint index); +typedef void (GLAD_API_PTR *PFNGLFINISHPROC)(void); +typedef void (GLAD_API_PTR *PFNGLFLUSHPROC)(void); +typedef void (GLAD_API_PTR *PFNGLFRAMEBUFFERRENDERBUFFERPROC)(GLenum target, GLenum attachment, GLenum renderbuffertarget, GLuint renderbuffer); +typedef void (GLAD_API_PTR *PFNGLFRAMEBUFFERTEXTURE2DPROC)(GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level); +typedef void (GLAD_API_PTR *PFNGLFRONTFACEPROC)(GLenum mode); +typedef void (GLAD_API_PTR *PFNGLGENBUFFERSPROC)(GLsizei n, GLuint * buffers); +typedef void (GLAD_API_PTR *PFNGLGENFRAMEBUFFERSPROC)(GLsizei n, GLuint * framebuffers); +typedef void (GLAD_API_PTR *PFNGLGENRENDERBUFFERSPROC)(GLsizei n, GLuint * renderbuffers); +typedef void (GLAD_API_PTR *PFNGLGENTEXTURESPROC)(GLsizei n, GLuint * textures); +typedef void (GLAD_API_PTR *PFNGLGENVERTEXARRAYSOESPROC)(GLsizei n, GLuint * arrays); +typedef void (GLAD_API_PTR *PFNGLGENERATEMIPMAPPROC)(GLenum target); +typedef void (GLAD_API_PTR *PFNGLGETACTIVEATTRIBPROC)(GLuint program, GLuint index, GLsizei bufSize, GLsizei * length, GLint * size, GLenum * type, GLchar * name); +typedef void (GLAD_API_PTR *PFNGLGETACTIVEUNIFORMPROC)(GLuint program, GLuint index, GLsizei bufSize, GLsizei * length, GLint * size, GLenum * type, GLchar * name); +typedef void (GLAD_API_PTR *PFNGLGETATTACHEDSHADERSPROC)(GLuint program, GLsizei maxCount, GLsizei * count, GLuint * shaders); +typedef GLint (GLAD_API_PTR *PFNGLGETATTRIBLOCATIONPROC)(GLuint program, const GLchar * name); +typedef void (GLAD_API_PTR *PFNGLGETBOOLEANVPROC)(GLenum pname, GLboolean * data); +typedef void (GLAD_API_PTR *PFNGLGETBUFFERPARAMETERIVPROC)(GLenum target, GLenum pname, GLint * params); +typedef void (GLAD_API_PTR *PFNGLGETBUFFERPOINTERVOESPROC)(GLenum target, GLenum pname, void ** params); +typedef GLenum (GLAD_API_PTR *PFNGLGETERRORPROC)(void); +typedef void (GLAD_API_PTR *PFNGLGETFLOATVPROC)(GLenum pname, GLfloat * data); +typedef void (GLAD_API_PTR *PFNGLGETFRAMEBUFFERATTACHMENTPARAMETERIVPROC)(GLenum target, GLenum attachment, GLenum pname, GLint * params); +typedef void (GLAD_API_PTR *PFNGLGETINTEGERVPROC)(GLenum pname, GLint * data); +typedef void (GLAD_API_PTR *PFNGLGETPROGRAMINFOLOGPROC)(GLuint program, GLsizei bufSize, GLsizei * length, GLchar * infoLog); +typedef void (GLAD_API_PTR *PFNGLGETPROGRAMIVPROC)(GLuint program, GLenum pname, GLint * params); +typedef void (GLAD_API_PTR *PFNGLGETRENDERBUFFERPARAMETERIVPROC)(GLenum target, GLenum pname, GLint * params); +typedef void (GLAD_API_PTR *PFNGLGETSHADERINFOLOGPROC)(GLuint shader, GLsizei bufSize, GLsizei * length, GLchar * infoLog); +typedef void (GLAD_API_PTR *PFNGLGETSHADERPRECISIONFORMATPROC)(GLenum shadertype, GLenum precisiontype, GLint * range, GLint * precision); +typedef void (GLAD_API_PTR *PFNGLGETSHADERSOURCEPROC)(GLuint shader, GLsizei bufSize, GLsizei * length, GLchar * source); +typedef void (GLAD_API_PTR *PFNGLGETSHADERIVPROC)(GLuint shader, GLenum pname, GLint * params); +typedef const GLubyte * (GLAD_API_PTR *PFNGLGETSTRINGPROC)(GLenum name); +typedef void (GLAD_API_PTR *PFNGLGETTEXPARAMETERFVPROC)(GLenum target, GLenum pname, GLfloat * params); +typedef void (GLAD_API_PTR *PFNGLGETTEXPARAMETERIVPROC)(GLenum target, GLenum pname, GLint * params); +typedef GLint (GLAD_API_PTR *PFNGLGETUNIFORMLOCATIONPROC)(GLuint program, const GLchar * name); +typedef void (GLAD_API_PTR *PFNGLGETUNIFORMFVPROC)(GLuint program, GLint location, GLfloat * params); +typedef void (GLAD_API_PTR *PFNGLGETUNIFORMIVPROC)(GLuint program, GLint location, GLint * params); +typedef void (GLAD_API_PTR *PFNGLGETVERTEXATTRIBPOINTERVPROC)(GLuint index, GLenum pname, void ** pointer); +typedef void (GLAD_API_PTR *PFNGLGETVERTEXATTRIBFVPROC)(GLuint index, GLenum pname, GLfloat * params); +typedef void (GLAD_API_PTR *PFNGLGETVERTEXATTRIBIVPROC)(GLuint index, GLenum pname, GLint * params); +typedef void (GLAD_API_PTR *PFNGLHINTPROC)(GLenum target, GLenum mode); +typedef GLboolean (GLAD_API_PTR *PFNGLISBUFFERPROC)(GLuint buffer); +typedef GLboolean (GLAD_API_PTR *PFNGLISENABLEDPROC)(GLenum cap); +typedef GLboolean (GLAD_API_PTR *PFNGLISFRAMEBUFFERPROC)(GLuint framebuffer); +typedef GLboolean (GLAD_API_PTR *PFNGLISPROGRAMPROC)(GLuint program); +typedef GLboolean (GLAD_API_PTR *PFNGLISRENDERBUFFERPROC)(GLuint renderbuffer); +typedef GLboolean (GLAD_API_PTR *PFNGLISSHADERPROC)(GLuint shader); +typedef GLboolean (GLAD_API_PTR *PFNGLISTEXTUREPROC)(GLuint texture); +typedef GLboolean (GLAD_API_PTR *PFNGLISVERTEXARRAYOESPROC)(GLuint array); +typedef void (GLAD_API_PTR *PFNGLLINEWIDTHPROC)(GLfloat width); +typedef void (GLAD_API_PTR *PFNGLLINKPROGRAMPROC)(GLuint program); +typedef void * (GLAD_API_PTR *PFNGLMAPBUFFEROESPROC)(GLenum target, GLenum access); +typedef void (GLAD_API_PTR *PFNGLPIXELSTOREIPROC)(GLenum pname, GLint param); +typedef void (GLAD_API_PTR *PFNGLPOLYGONOFFSETPROC)(GLfloat factor, GLfloat units); +typedef void (GLAD_API_PTR *PFNGLREADPIXELSPROC)(GLint x, GLint y, GLsizei width, GLsizei height, GLenum format, GLenum type, void * pixels); +typedef void (GLAD_API_PTR *PFNGLRELEASESHADERCOMPILERPROC)(void); +typedef void (GLAD_API_PTR *PFNGLRENDERBUFFERSTORAGEPROC)(GLenum target, GLenum internalformat, GLsizei width, GLsizei height); +typedef void (GLAD_API_PTR *PFNGLSAMPLECOVERAGEPROC)(GLfloat value, GLboolean invert); +typedef void (GLAD_API_PTR *PFNGLSCISSORPROC)(GLint x, GLint y, GLsizei width, GLsizei height); +typedef void (GLAD_API_PTR *PFNGLSHADERBINARYPROC)(GLsizei count, const GLuint * shaders, GLenum binaryFormat, const void * binary, GLsizei length); +typedef void (GLAD_API_PTR *PFNGLSHADERSOURCEPROC)(GLuint shader, GLsizei count, const GLchar *const* string, const GLint * length); +typedef void (GLAD_API_PTR *PFNGLSTENCILFUNCPROC)(GLenum func, GLint ref, GLuint mask); +typedef void (GLAD_API_PTR *PFNGLSTENCILFUNCSEPARATEPROC)(GLenum face, GLenum func, GLint ref, GLuint mask); +typedef void (GLAD_API_PTR *PFNGLSTENCILMASKPROC)(GLuint mask); +typedef void (GLAD_API_PTR *PFNGLSTENCILMASKSEPARATEPROC)(GLenum face, GLuint mask); +typedef void (GLAD_API_PTR *PFNGLSTENCILOPPROC)(GLenum fail, GLenum zfail, GLenum zpass); +typedef void (GLAD_API_PTR *PFNGLSTENCILOPSEPARATEPROC)(GLenum face, GLenum sfail, GLenum dpfail, GLenum dppass); +typedef void (GLAD_API_PTR *PFNGLTEXIMAGE2DPROC)(GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height, GLint border, GLenum format, GLenum type, const void * pixels); +typedef void (GLAD_API_PTR *PFNGLTEXPARAMETERFPROC)(GLenum target, GLenum pname, GLfloat param); +typedef void (GLAD_API_PTR *PFNGLTEXPARAMETERFVPROC)(GLenum target, GLenum pname, const GLfloat * params); +typedef void (GLAD_API_PTR *PFNGLTEXPARAMETERIPROC)(GLenum target, GLenum pname, GLint param); +typedef void (GLAD_API_PTR *PFNGLTEXPARAMETERIVPROC)(GLenum target, GLenum pname, const GLint * params); +typedef void (GLAD_API_PTR *PFNGLTEXSTORAGE1DEXTPROC)(GLenum target, GLsizei levels, GLenum internalformat, GLsizei width); +typedef void (GLAD_API_PTR *PFNGLTEXSTORAGE2DEXTPROC)(GLenum target, GLsizei levels, GLenum internalformat, GLsizei width, GLsizei height); +typedef void (GLAD_API_PTR *PFNGLTEXSTORAGE3DEXTPROC)(GLenum target, GLsizei levels, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth); +typedef void (GLAD_API_PTR *PFNGLTEXSTORAGE3DMULTISAMPLEOESPROC)(GLenum target, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth, GLboolean fixedsamplelocations); +typedef void (GLAD_API_PTR *PFNGLTEXSUBIMAGE2DPROC)(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLenum type, const void * pixels); +typedef void (GLAD_API_PTR *PFNGLTEXTURESTORAGE1DEXTPROC)(GLuint texture, GLenum target, GLsizei levels, GLenum internalformat, GLsizei width); +typedef void (GLAD_API_PTR *PFNGLTEXTURESTORAGE2DEXTPROC)(GLuint texture, GLenum target, GLsizei levels, GLenum internalformat, GLsizei width, GLsizei height); +typedef void (GLAD_API_PTR *PFNGLTEXTURESTORAGE3DEXTPROC)(GLuint texture, GLenum target, GLsizei levels, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth); +typedef void (GLAD_API_PTR *PFNGLUNIFORM1FPROC)(GLint location, GLfloat v0); +typedef void (GLAD_API_PTR *PFNGLUNIFORM1FVPROC)(GLint location, GLsizei count, const GLfloat * value); +typedef void (GLAD_API_PTR *PFNGLUNIFORM1IPROC)(GLint location, GLint v0); +typedef void (GLAD_API_PTR *PFNGLUNIFORM1IVPROC)(GLint location, GLsizei count, const GLint * value); +typedef void (GLAD_API_PTR *PFNGLUNIFORM2FPROC)(GLint location, GLfloat v0, GLfloat v1); +typedef void (GLAD_API_PTR *PFNGLUNIFORM2FVPROC)(GLint location, GLsizei count, const GLfloat * value); +typedef void (GLAD_API_PTR *PFNGLUNIFORM2IPROC)(GLint location, GLint v0, GLint v1); +typedef void (GLAD_API_PTR *PFNGLUNIFORM2IVPROC)(GLint location, GLsizei count, const GLint * value); +typedef void (GLAD_API_PTR *PFNGLUNIFORM3FPROC)(GLint location, GLfloat v0, GLfloat v1, GLfloat v2); +typedef void (GLAD_API_PTR *PFNGLUNIFORM3FVPROC)(GLint location, GLsizei count, const GLfloat * value); +typedef void (GLAD_API_PTR *PFNGLUNIFORM3IPROC)(GLint location, GLint v0, GLint v1, GLint v2); +typedef void (GLAD_API_PTR *PFNGLUNIFORM3IVPROC)(GLint location, GLsizei count, const GLint * value); +typedef void (GLAD_API_PTR *PFNGLUNIFORM4FPROC)(GLint location, GLfloat v0, GLfloat v1, GLfloat v2, GLfloat v3); +typedef void (GLAD_API_PTR *PFNGLUNIFORM4FVPROC)(GLint location, GLsizei count, const GLfloat * value); +typedef void (GLAD_API_PTR *PFNGLUNIFORM4IPROC)(GLint location, GLint v0, GLint v1, GLint v2, GLint v3); +typedef void (GLAD_API_PTR *PFNGLUNIFORM4IVPROC)(GLint location, GLsizei count, const GLint * value); +typedef void (GLAD_API_PTR *PFNGLUNIFORMMATRIX2FVPROC)(GLint location, GLsizei count, GLboolean transpose, const GLfloat * value); +typedef void (GLAD_API_PTR *PFNGLUNIFORMMATRIX3FVPROC)(GLint location, GLsizei count, GLboolean transpose, const GLfloat * value); +typedef void (GLAD_API_PTR *PFNGLUNIFORMMATRIX4FVPROC)(GLint location, GLsizei count, GLboolean transpose, const GLfloat * value); +typedef GLboolean (GLAD_API_PTR *PFNGLUNMAPBUFFEROESPROC)(GLenum target); +typedef void (GLAD_API_PTR *PFNGLUSEPROGRAMPROC)(GLuint program); +typedef void (GLAD_API_PTR *PFNGLVALIDATEPROGRAMPROC)(GLuint program); +typedef void (GLAD_API_PTR *PFNGLVERTEXATTRIB1FPROC)(GLuint index, GLfloat x); +typedef void (GLAD_API_PTR *PFNGLVERTEXATTRIB1FVPROC)(GLuint index, const GLfloat * v); +typedef void (GLAD_API_PTR *PFNGLVERTEXATTRIB2FPROC)(GLuint index, GLfloat x, GLfloat y); +typedef void (GLAD_API_PTR *PFNGLVERTEXATTRIB2FVPROC)(GLuint index, const GLfloat * v); +typedef void (GLAD_API_PTR *PFNGLVERTEXATTRIB3FPROC)(GLuint index, GLfloat x, GLfloat y, GLfloat z); +typedef void (GLAD_API_PTR *PFNGLVERTEXATTRIB3FVPROC)(GLuint index, const GLfloat * v); +typedef void (GLAD_API_PTR *PFNGLVERTEXATTRIB4FPROC)(GLuint index, GLfloat x, GLfloat y, GLfloat z, GLfloat w); +typedef void (GLAD_API_PTR *PFNGLVERTEXATTRIB4FVPROC)(GLuint index, const GLfloat * v); +typedef void (GLAD_API_PTR *PFNGLVERTEXATTRIBPOINTERPROC)(GLuint index, GLint size, GLenum type, GLboolean normalized, GLsizei stride, const void * pointer); +typedef void (GLAD_API_PTR *PFNGLVIEWPORTPROC)(GLint x, GLint y, GLsizei width, GLsizei height); + +GLAD_API_CALL PFNGLACTIVETEXTUREPROC glad_glActiveTexture; +#define glActiveTexture glad_glActiveTexture +GLAD_API_CALL PFNGLATTACHSHADERPROC glad_glAttachShader; +#define glAttachShader glad_glAttachShader +GLAD_API_CALL PFNGLBINDATTRIBLOCATIONPROC glad_glBindAttribLocation; +#define glBindAttribLocation glad_glBindAttribLocation +GLAD_API_CALL PFNGLBINDBUFFERPROC glad_glBindBuffer; +#define glBindBuffer glad_glBindBuffer +GLAD_API_CALL PFNGLBINDFRAMEBUFFERPROC glad_glBindFramebuffer; +#define glBindFramebuffer glad_glBindFramebuffer +GLAD_API_CALL PFNGLBINDRENDERBUFFERPROC glad_glBindRenderbuffer; +#define glBindRenderbuffer glad_glBindRenderbuffer +GLAD_API_CALL PFNGLBINDTEXTUREPROC glad_glBindTexture; +#define glBindTexture glad_glBindTexture +GLAD_API_CALL PFNGLBINDVERTEXARRAYOESPROC glad_glBindVertexArrayOES; +#define glBindVertexArrayOES glad_glBindVertexArrayOES +GLAD_API_CALL PFNGLBLENDCOLORPROC glad_glBlendColor; +#define glBlendColor glad_glBlendColor +GLAD_API_CALL PFNGLBLENDEQUATIONPROC glad_glBlendEquation; +#define glBlendEquation glad_glBlendEquation +GLAD_API_CALL PFNGLBLENDEQUATIONSEPARATEPROC glad_glBlendEquationSeparate; +#define glBlendEquationSeparate glad_glBlendEquationSeparate +GLAD_API_CALL PFNGLBLENDFUNCPROC glad_glBlendFunc; +#define glBlendFunc glad_glBlendFunc +GLAD_API_CALL PFNGLBLENDFUNCSEPARATEPROC glad_glBlendFuncSeparate; +#define glBlendFuncSeparate glad_glBlendFuncSeparate +GLAD_API_CALL PFNGLBUFFERDATAPROC glad_glBufferData; +#define glBufferData glad_glBufferData +GLAD_API_CALL PFNGLBUFFERSUBDATAPROC glad_glBufferSubData; +#define glBufferSubData glad_glBufferSubData +GLAD_API_CALL PFNGLCHECKFRAMEBUFFERSTATUSPROC glad_glCheckFramebufferStatus; +#define glCheckFramebufferStatus glad_glCheckFramebufferStatus +GLAD_API_CALL PFNGLCLEARPROC glad_glClear; +#define glClear glad_glClear +GLAD_API_CALL PFNGLCLEARCOLORPROC glad_glClearColor; +#define glClearColor glad_glClearColor +GLAD_API_CALL PFNGLCLEARDEPTHFPROC glad_glClearDepthf; +#define glClearDepthf glad_glClearDepthf +GLAD_API_CALL PFNGLCLEARSTENCILPROC glad_glClearStencil; +#define glClearStencil glad_glClearStencil +GLAD_API_CALL PFNGLCOLORMASKPROC glad_glColorMask; +#define glColorMask glad_glColorMask +GLAD_API_CALL PFNGLCOMPILESHADERPROC glad_glCompileShader; +#define glCompileShader glad_glCompileShader +GLAD_API_CALL PFNGLCOMPRESSEDTEXIMAGE2DPROC glad_glCompressedTexImage2D; +#define glCompressedTexImage2D glad_glCompressedTexImage2D +GLAD_API_CALL PFNGLCOMPRESSEDTEXSUBIMAGE2DPROC glad_glCompressedTexSubImage2D; +#define glCompressedTexSubImage2D glad_glCompressedTexSubImage2D +GLAD_API_CALL PFNGLCOPYTEXIMAGE2DPROC glad_glCopyTexImage2D; +#define glCopyTexImage2D glad_glCopyTexImage2D +GLAD_API_CALL PFNGLCOPYTEXSUBIMAGE2DPROC glad_glCopyTexSubImage2D; +#define glCopyTexSubImage2D glad_glCopyTexSubImage2D +GLAD_API_CALL PFNGLCREATEPROGRAMPROC glad_glCreateProgram; +#define glCreateProgram glad_glCreateProgram +GLAD_API_CALL PFNGLCREATESHADERPROC glad_glCreateShader; +#define glCreateShader glad_glCreateShader +GLAD_API_CALL PFNGLCULLFACEPROC glad_glCullFace; +#define glCullFace glad_glCullFace +GLAD_API_CALL PFNGLDELETEBUFFERSPROC glad_glDeleteBuffers; +#define glDeleteBuffers glad_glDeleteBuffers +GLAD_API_CALL PFNGLDELETEFRAMEBUFFERSPROC glad_glDeleteFramebuffers; +#define glDeleteFramebuffers glad_glDeleteFramebuffers +GLAD_API_CALL PFNGLDELETEPROGRAMPROC glad_glDeleteProgram; +#define glDeleteProgram glad_glDeleteProgram +GLAD_API_CALL PFNGLDELETERENDERBUFFERSPROC glad_glDeleteRenderbuffers; +#define glDeleteRenderbuffers glad_glDeleteRenderbuffers +GLAD_API_CALL PFNGLDELETESHADERPROC glad_glDeleteShader; +#define glDeleteShader glad_glDeleteShader +GLAD_API_CALL PFNGLDELETETEXTURESPROC glad_glDeleteTextures; +#define glDeleteTextures glad_glDeleteTextures +GLAD_API_CALL PFNGLDELETEVERTEXARRAYSOESPROC glad_glDeleteVertexArraysOES; +#define glDeleteVertexArraysOES glad_glDeleteVertexArraysOES +GLAD_API_CALL PFNGLDEPTHFUNCPROC glad_glDepthFunc; +#define glDepthFunc glad_glDepthFunc +GLAD_API_CALL PFNGLDEPTHMASKPROC glad_glDepthMask; +#define glDepthMask glad_glDepthMask +GLAD_API_CALL PFNGLDEPTHRANGEFPROC glad_glDepthRangef; +#define glDepthRangef glad_glDepthRangef +GLAD_API_CALL PFNGLDETACHSHADERPROC glad_glDetachShader; +#define glDetachShader glad_glDetachShader +GLAD_API_CALL PFNGLDISABLEPROC glad_glDisable; +#define glDisable glad_glDisable +GLAD_API_CALL PFNGLDISABLEVERTEXATTRIBARRAYPROC glad_glDisableVertexAttribArray; +#define glDisableVertexAttribArray glad_glDisableVertexAttribArray +GLAD_API_CALL PFNGLDRAWARRAYSPROC glad_glDrawArrays; +#define glDrawArrays glad_glDrawArrays +GLAD_API_CALL PFNGLDRAWELEMENTSPROC glad_glDrawElements; +#define glDrawElements glad_glDrawElements +GLAD_API_CALL PFNGLENABLEPROC glad_glEnable; +#define glEnable glad_glEnable +GLAD_API_CALL PFNGLENABLEVERTEXATTRIBARRAYPROC glad_glEnableVertexAttribArray; +#define glEnableVertexAttribArray glad_glEnableVertexAttribArray +GLAD_API_CALL PFNGLFINISHPROC glad_glFinish; +#define glFinish glad_glFinish +GLAD_API_CALL PFNGLFLUSHPROC glad_glFlush; +#define glFlush glad_glFlush +GLAD_API_CALL PFNGLFRAMEBUFFERRENDERBUFFERPROC glad_glFramebufferRenderbuffer; +#define glFramebufferRenderbuffer glad_glFramebufferRenderbuffer +GLAD_API_CALL PFNGLFRAMEBUFFERTEXTURE2DPROC glad_glFramebufferTexture2D; +#define glFramebufferTexture2D glad_glFramebufferTexture2D +GLAD_API_CALL PFNGLFRONTFACEPROC glad_glFrontFace; +#define glFrontFace glad_glFrontFace +GLAD_API_CALL PFNGLGENBUFFERSPROC glad_glGenBuffers; +#define glGenBuffers glad_glGenBuffers +GLAD_API_CALL PFNGLGENFRAMEBUFFERSPROC glad_glGenFramebuffers; +#define glGenFramebuffers glad_glGenFramebuffers +GLAD_API_CALL PFNGLGENRENDERBUFFERSPROC glad_glGenRenderbuffers; +#define glGenRenderbuffers glad_glGenRenderbuffers +GLAD_API_CALL PFNGLGENTEXTURESPROC glad_glGenTextures; +#define glGenTextures glad_glGenTextures +GLAD_API_CALL PFNGLGENVERTEXARRAYSOESPROC glad_glGenVertexArraysOES; +#define glGenVertexArraysOES glad_glGenVertexArraysOES +GLAD_API_CALL PFNGLGENERATEMIPMAPPROC glad_glGenerateMipmap; +#define glGenerateMipmap glad_glGenerateMipmap +GLAD_API_CALL PFNGLGETACTIVEATTRIBPROC glad_glGetActiveAttrib; +#define glGetActiveAttrib glad_glGetActiveAttrib +GLAD_API_CALL PFNGLGETACTIVEUNIFORMPROC glad_glGetActiveUniform; +#define glGetActiveUniform glad_glGetActiveUniform +GLAD_API_CALL PFNGLGETATTACHEDSHADERSPROC glad_glGetAttachedShaders; +#define glGetAttachedShaders glad_glGetAttachedShaders +GLAD_API_CALL PFNGLGETATTRIBLOCATIONPROC glad_glGetAttribLocation; +#define glGetAttribLocation glad_glGetAttribLocation +GLAD_API_CALL PFNGLGETBOOLEANVPROC glad_glGetBooleanv; +#define glGetBooleanv glad_glGetBooleanv +GLAD_API_CALL PFNGLGETBUFFERPARAMETERIVPROC glad_glGetBufferParameteriv; +#define glGetBufferParameteriv glad_glGetBufferParameteriv +GLAD_API_CALL PFNGLGETBUFFERPOINTERVOESPROC glad_glGetBufferPointervOES; +#define glGetBufferPointervOES glad_glGetBufferPointervOES +GLAD_API_CALL PFNGLGETERRORPROC glad_glGetError; +#define glGetError glad_glGetError +GLAD_API_CALL PFNGLGETFLOATVPROC glad_glGetFloatv; +#define glGetFloatv glad_glGetFloatv +GLAD_API_CALL PFNGLGETFRAMEBUFFERATTACHMENTPARAMETERIVPROC glad_glGetFramebufferAttachmentParameteriv; +#define glGetFramebufferAttachmentParameteriv glad_glGetFramebufferAttachmentParameteriv +GLAD_API_CALL PFNGLGETINTEGERVPROC glad_glGetIntegerv; +#define glGetIntegerv glad_glGetIntegerv +GLAD_API_CALL PFNGLGETPROGRAMINFOLOGPROC glad_glGetProgramInfoLog; +#define glGetProgramInfoLog glad_glGetProgramInfoLog +GLAD_API_CALL PFNGLGETPROGRAMIVPROC glad_glGetProgramiv; +#define glGetProgramiv glad_glGetProgramiv +GLAD_API_CALL PFNGLGETRENDERBUFFERPARAMETERIVPROC glad_glGetRenderbufferParameteriv; +#define glGetRenderbufferParameteriv glad_glGetRenderbufferParameteriv +GLAD_API_CALL PFNGLGETSHADERINFOLOGPROC glad_glGetShaderInfoLog; +#define glGetShaderInfoLog glad_glGetShaderInfoLog +GLAD_API_CALL PFNGLGETSHADERPRECISIONFORMATPROC glad_glGetShaderPrecisionFormat; +#define glGetShaderPrecisionFormat glad_glGetShaderPrecisionFormat +GLAD_API_CALL PFNGLGETSHADERSOURCEPROC glad_glGetShaderSource; +#define glGetShaderSource glad_glGetShaderSource +GLAD_API_CALL PFNGLGETSHADERIVPROC glad_glGetShaderiv; +#define glGetShaderiv glad_glGetShaderiv +GLAD_API_CALL PFNGLGETSTRINGPROC glad_glGetString; +#define glGetString glad_glGetString +GLAD_API_CALL PFNGLGETTEXPARAMETERFVPROC glad_glGetTexParameterfv; +#define glGetTexParameterfv glad_glGetTexParameterfv +GLAD_API_CALL PFNGLGETTEXPARAMETERIVPROC glad_glGetTexParameteriv; +#define glGetTexParameteriv glad_glGetTexParameteriv +GLAD_API_CALL PFNGLGETUNIFORMLOCATIONPROC glad_glGetUniformLocation; +#define glGetUniformLocation glad_glGetUniformLocation +GLAD_API_CALL PFNGLGETUNIFORMFVPROC glad_glGetUniformfv; +#define glGetUniformfv glad_glGetUniformfv +GLAD_API_CALL PFNGLGETUNIFORMIVPROC glad_glGetUniformiv; +#define glGetUniformiv glad_glGetUniformiv +GLAD_API_CALL PFNGLGETVERTEXATTRIBPOINTERVPROC glad_glGetVertexAttribPointerv; +#define glGetVertexAttribPointerv glad_glGetVertexAttribPointerv +GLAD_API_CALL PFNGLGETVERTEXATTRIBFVPROC glad_glGetVertexAttribfv; +#define glGetVertexAttribfv glad_glGetVertexAttribfv +GLAD_API_CALL PFNGLGETVERTEXATTRIBIVPROC glad_glGetVertexAttribiv; +#define glGetVertexAttribiv glad_glGetVertexAttribiv +GLAD_API_CALL PFNGLHINTPROC glad_glHint; +#define glHint glad_glHint +GLAD_API_CALL PFNGLISBUFFERPROC glad_glIsBuffer; +#define glIsBuffer glad_glIsBuffer +GLAD_API_CALL PFNGLISENABLEDPROC glad_glIsEnabled; +#define glIsEnabled glad_glIsEnabled +GLAD_API_CALL PFNGLISFRAMEBUFFERPROC glad_glIsFramebuffer; +#define glIsFramebuffer glad_glIsFramebuffer +GLAD_API_CALL PFNGLISPROGRAMPROC glad_glIsProgram; +#define glIsProgram glad_glIsProgram +GLAD_API_CALL PFNGLISRENDERBUFFERPROC glad_glIsRenderbuffer; +#define glIsRenderbuffer glad_glIsRenderbuffer +GLAD_API_CALL PFNGLISSHADERPROC glad_glIsShader; +#define glIsShader glad_glIsShader +GLAD_API_CALL PFNGLISTEXTUREPROC glad_glIsTexture; +#define glIsTexture glad_glIsTexture +GLAD_API_CALL PFNGLISVERTEXARRAYOESPROC glad_glIsVertexArrayOES; +#define glIsVertexArrayOES glad_glIsVertexArrayOES +GLAD_API_CALL PFNGLLINEWIDTHPROC glad_glLineWidth; +#define glLineWidth glad_glLineWidth +GLAD_API_CALL PFNGLLINKPROGRAMPROC glad_glLinkProgram; +#define glLinkProgram glad_glLinkProgram +GLAD_API_CALL PFNGLMAPBUFFEROESPROC glad_glMapBufferOES; +#define glMapBufferOES glad_glMapBufferOES +GLAD_API_CALL PFNGLPIXELSTOREIPROC glad_glPixelStorei; +#define glPixelStorei glad_glPixelStorei +GLAD_API_CALL PFNGLPOLYGONOFFSETPROC glad_glPolygonOffset; +#define glPolygonOffset glad_glPolygonOffset +GLAD_API_CALL PFNGLREADPIXELSPROC glad_glReadPixels; +#define glReadPixels glad_glReadPixels +GLAD_API_CALL PFNGLRELEASESHADERCOMPILERPROC glad_glReleaseShaderCompiler; +#define glReleaseShaderCompiler glad_glReleaseShaderCompiler +GLAD_API_CALL PFNGLRENDERBUFFERSTORAGEPROC glad_glRenderbufferStorage; +#define glRenderbufferStorage glad_glRenderbufferStorage +GLAD_API_CALL PFNGLSAMPLECOVERAGEPROC glad_glSampleCoverage; +#define glSampleCoverage glad_glSampleCoverage +GLAD_API_CALL PFNGLSCISSORPROC glad_glScissor; +#define glScissor glad_glScissor +GLAD_API_CALL PFNGLSHADERBINARYPROC glad_glShaderBinary; +#define glShaderBinary glad_glShaderBinary +GLAD_API_CALL PFNGLSHADERSOURCEPROC glad_glShaderSource; +#define glShaderSource glad_glShaderSource +GLAD_API_CALL PFNGLSTENCILFUNCPROC glad_glStencilFunc; +#define glStencilFunc glad_glStencilFunc +GLAD_API_CALL PFNGLSTENCILFUNCSEPARATEPROC glad_glStencilFuncSeparate; +#define glStencilFuncSeparate glad_glStencilFuncSeparate +GLAD_API_CALL PFNGLSTENCILMASKPROC glad_glStencilMask; +#define glStencilMask glad_glStencilMask +GLAD_API_CALL PFNGLSTENCILMASKSEPARATEPROC glad_glStencilMaskSeparate; +#define glStencilMaskSeparate glad_glStencilMaskSeparate +GLAD_API_CALL PFNGLSTENCILOPPROC glad_glStencilOp; +#define glStencilOp glad_glStencilOp +GLAD_API_CALL PFNGLSTENCILOPSEPARATEPROC glad_glStencilOpSeparate; +#define glStencilOpSeparate glad_glStencilOpSeparate +GLAD_API_CALL PFNGLTEXIMAGE2DPROC glad_glTexImage2D; +#define glTexImage2D glad_glTexImage2D +GLAD_API_CALL PFNGLTEXPARAMETERFPROC glad_glTexParameterf; +#define glTexParameterf glad_glTexParameterf +GLAD_API_CALL PFNGLTEXPARAMETERFVPROC glad_glTexParameterfv; +#define glTexParameterfv glad_glTexParameterfv +GLAD_API_CALL PFNGLTEXPARAMETERIPROC glad_glTexParameteri; +#define glTexParameteri glad_glTexParameteri +GLAD_API_CALL PFNGLTEXPARAMETERIVPROC glad_glTexParameteriv; +#define glTexParameteriv glad_glTexParameteriv +GLAD_API_CALL PFNGLTEXSTORAGE1DEXTPROC glad_glTexStorage1DEXT; +#define glTexStorage1DEXT glad_glTexStorage1DEXT +GLAD_API_CALL PFNGLTEXSTORAGE2DEXTPROC glad_glTexStorage2DEXT; +#define glTexStorage2DEXT glad_glTexStorage2DEXT +GLAD_API_CALL PFNGLTEXSTORAGE3DEXTPROC glad_glTexStorage3DEXT; +#define glTexStorage3DEXT glad_glTexStorage3DEXT +GLAD_API_CALL PFNGLTEXSTORAGE3DMULTISAMPLEOESPROC glad_glTexStorage3DMultisampleOES; +#define glTexStorage3DMultisampleOES glad_glTexStorage3DMultisampleOES +GLAD_API_CALL PFNGLTEXSUBIMAGE2DPROC glad_glTexSubImage2D; +#define glTexSubImage2D glad_glTexSubImage2D +GLAD_API_CALL PFNGLTEXTURESTORAGE1DEXTPROC glad_glTextureStorage1DEXT; +#define glTextureStorage1DEXT glad_glTextureStorage1DEXT +GLAD_API_CALL PFNGLTEXTURESTORAGE2DEXTPROC glad_glTextureStorage2DEXT; +#define glTextureStorage2DEXT glad_glTextureStorage2DEXT +GLAD_API_CALL PFNGLTEXTURESTORAGE3DEXTPROC glad_glTextureStorage3DEXT; +#define glTextureStorage3DEXT glad_glTextureStorage3DEXT +GLAD_API_CALL PFNGLUNIFORM1FPROC glad_glUniform1f; +#define glUniform1f glad_glUniform1f +GLAD_API_CALL PFNGLUNIFORM1FVPROC glad_glUniform1fv; +#define glUniform1fv glad_glUniform1fv +GLAD_API_CALL PFNGLUNIFORM1IPROC glad_glUniform1i; +#define glUniform1i glad_glUniform1i +GLAD_API_CALL PFNGLUNIFORM1IVPROC glad_glUniform1iv; +#define glUniform1iv glad_glUniform1iv +GLAD_API_CALL PFNGLUNIFORM2FPROC glad_glUniform2f; +#define glUniform2f glad_glUniform2f +GLAD_API_CALL PFNGLUNIFORM2FVPROC glad_glUniform2fv; +#define glUniform2fv glad_glUniform2fv +GLAD_API_CALL PFNGLUNIFORM2IPROC glad_glUniform2i; +#define glUniform2i glad_glUniform2i +GLAD_API_CALL PFNGLUNIFORM2IVPROC glad_glUniform2iv; +#define glUniform2iv glad_glUniform2iv +GLAD_API_CALL PFNGLUNIFORM3FPROC glad_glUniform3f; +#define glUniform3f glad_glUniform3f +GLAD_API_CALL PFNGLUNIFORM3FVPROC glad_glUniform3fv; +#define glUniform3fv glad_glUniform3fv +GLAD_API_CALL PFNGLUNIFORM3IPROC glad_glUniform3i; +#define glUniform3i glad_glUniform3i +GLAD_API_CALL PFNGLUNIFORM3IVPROC glad_glUniform3iv; +#define glUniform3iv glad_glUniform3iv +GLAD_API_CALL PFNGLUNIFORM4FPROC glad_glUniform4f; +#define glUniform4f glad_glUniform4f +GLAD_API_CALL PFNGLUNIFORM4FVPROC glad_glUniform4fv; +#define glUniform4fv glad_glUniform4fv +GLAD_API_CALL PFNGLUNIFORM4IPROC glad_glUniform4i; +#define glUniform4i glad_glUniform4i +GLAD_API_CALL PFNGLUNIFORM4IVPROC glad_glUniform4iv; +#define glUniform4iv glad_glUniform4iv +GLAD_API_CALL PFNGLUNIFORMMATRIX2FVPROC glad_glUniformMatrix2fv; +#define glUniformMatrix2fv glad_glUniformMatrix2fv +GLAD_API_CALL PFNGLUNIFORMMATRIX3FVPROC glad_glUniformMatrix3fv; +#define glUniformMatrix3fv glad_glUniformMatrix3fv +GLAD_API_CALL PFNGLUNIFORMMATRIX4FVPROC glad_glUniformMatrix4fv; +#define glUniformMatrix4fv glad_glUniformMatrix4fv +GLAD_API_CALL PFNGLUNMAPBUFFEROESPROC glad_glUnmapBufferOES; +#define glUnmapBufferOES glad_glUnmapBufferOES +GLAD_API_CALL PFNGLUSEPROGRAMPROC glad_glUseProgram; +#define glUseProgram glad_glUseProgram +GLAD_API_CALL PFNGLVALIDATEPROGRAMPROC glad_glValidateProgram; +#define glValidateProgram glad_glValidateProgram +GLAD_API_CALL PFNGLVERTEXATTRIB1FPROC glad_glVertexAttrib1f; +#define glVertexAttrib1f glad_glVertexAttrib1f +GLAD_API_CALL PFNGLVERTEXATTRIB1FVPROC glad_glVertexAttrib1fv; +#define glVertexAttrib1fv glad_glVertexAttrib1fv +GLAD_API_CALL PFNGLVERTEXATTRIB2FPROC glad_glVertexAttrib2f; +#define glVertexAttrib2f glad_glVertexAttrib2f +GLAD_API_CALL PFNGLVERTEXATTRIB2FVPROC glad_glVertexAttrib2fv; +#define glVertexAttrib2fv glad_glVertexAttrib2fv +GLAD_API_CALL PFNGLVERTEXATTRIB3FPROC glad_glVertexAttrib3f; +#define glVertexAttrib3f glad_glVertexAttrib3f +GLAD_API_CALL PFNGLVERTEXATTRIB3FVPROC glad_glVertexAttrib3fv; +#define glVertexAttrib3fv glad_glVertexAttrib3fv +GLAD_API_CALL PFNGLVERTEXATTRIB4FPROC glad_glVertexAttrib4f; +#define glVertexAttrib4f glad_glVertexAttrib4f +GLAD_API_CALL PFNGLVERTEXATTRIB4FVPROC glad_glVertexAttrib4fv; +#define glVertexAttrib4fv glad_glVertexAttrib4fv +GLAD_API_CALL PFNGLVERTEXATTRIBPOINTERPROC glad_glVertexAttribPointer; +#define glVertexAttribPointer glad_glVertexAttribPointer +GLAD_API_CALL PFNGLVIEWPORTPROC glad_glViewport; +#define glViewport glad_glViewport + + + + + +GLAD_API_CALL int gladLoadGLES2UserPtr( GLADuserptrloadfunc load, void *userptr); +GLAD_API_CALL int gladLoadGLES2( GLADloadfunc load); + + + +#ifdef __cplusplus +} +#endif +#endif /*LV_USE_EGL*/ + +#endif diff --git a/src/drivers/opengles/glad/src/egl.c b/src/drivers/opengles/glad/src/egl.c new file mode 100644 index 0000000000..21bce5d2fc --- /dev/null +++ b/src/drivers/opengles/glad/src/egl.c @@ -0,0 +1,353 @@ +/** + * SPDX-License-Identifier: (WTFPL OR CC0-1.0) AND Apache-2.0 + */ + + #include "../../lv_opengles_egl.h" + +#if LV_USE_EGL + +#include +#include +#include +#include "../include/glad/egl.h" + +#ifndef GLAD_IMPL_UTIL_C_ +#define GLAD_IMPL_UTIL_C_ + +#ifdef _MSC_VER +#define GLAD_IMPL_UTIL_SSCANF sscanf_s +#else +#define GLAD_IMPL_UTIL_SSCANF sscanf +#endif + +#endif /* GLAD_IMPL_UTIL_C_ */ + +#ifdef __cplusplus +extern "C" { +#endif + + + +int GLAD_EGL_VERSION_1_0 = 0; +int GLAD_EGL_VERSION_1_1 = 0; +int GLAD_EGL_VERSION_1_2 = 0; +int GLAD_EGL_VERSION_1_3 = 0; +int GLAD_EGL_VERSION_1_4 = 0; +int GLAD_EGL_VERSION_1_5 = 0; +int GLAD_EGL_EXT_image_dma_buf_import = 0; +int GLAD_EGL_EXT_image_dma_buf_import_modifiers = 0; +int GLAD_EGL_EXT_platform_base = 0; +int GLAD_EGL_EXT_platform_wayland = 0; +int GLAD_EGL_KHR_cl_event2 = 0; +int GLAD_EGL_KHR_fence_sync = 0; +int GLAD_EGL_KHR_image = 0; +int GLAD_EGL_KHR_image_base = 0; +int GLAD_EGL_KHR_platform_gbm = 0; +int GLAD_EGL_KHR_platform_wayland = 0; +int GLAD_EGL_KHR_reusable_sync = 0; + + + +PFNEGLBINDAPIPROC glad_eglBindAPI = NULL; +PFNEGLBINDTEXIMAGEPROC glad_eglBindTexImage = NULL; +PFNEGLCHOOSECONFIGPROC glad_eglChooseConfig = NULL; +PFNEGLCLIENTWAITSYNCPROC glad_eglClientWaitSync = NULL; +PFNEGLCLIENTWAITSYNCKHRPROC glad_eglClientWaitSyncKHR = NULL; +PFNEGLCOPYBUFFERSPROC glad_eglCopyBuffers = NULL; +PFNEGLCREATECONTEXTPROC glad_eglCreateContext = NULL; +PFNEGLCREATEIMAGEPROC glad_eglCreateImage = NULL; +PFNEGLCREATEIMAGEKHRPROC glad_eglCreateImageKHR = NULL; +PFNEGLCREATEPBUFFERFROMCLIENTBUFFERPROC glad_eglCreatePbufferFromClientBuffer = NULL; +PFNEGLCREATEPBUFFERSURFACEPROC glad_eglCreatePbufferSurface = NULL; +PFNEGLCREATEPIXMAPSURFACEPROC glad_eglCreatePixmapSurface = NULL; +PFNEGLCREATEPLATFORMPIXMAPSURFACEPROC glad_eglCreatePlatformPixmapSurface = NULL; +PFNEGLCREATEPLATFORMPIXMAPSURFACEEXTPROC glad_eglCreatePlatformPixmapSurfaceEXT = NULL; +PFNEGLCREATEPLATFORMWINDOWSURFACEPROC glad_eglCreatePlatformWindowSurface = NULL; +PFNEGLCREATEPLATFORMWINDOWSURFACEEXTPROC glad_eglCreatePlatformWindowSurfaceEXT = NULL; +PFNEGLCREATESYNCPROC glad_eglCreateSync = NULL; +PFNEGLCREATESYNC64KHRPROC glad_eglCreateSync64KHR = NULL; +PFNEGLCREATESYNCKHRPROC glad_eglCreateSyncKHR = NULL; +PFNEGLCREATEWINDOWSURFACEPROC glad_eglCreateWindowSurface = NULL; +PFNEGLDESTROYCONTEXTPROC glad_eglDestroyContext = NULL; +PFNEGLDESTROYIMAGEPROC glad_eglDestroyImage = NULL; +PFNEGLDESTROYIMAGEKHRPROC glad_eglDestroyImageKHR = NULL; +PFNEGLDESTROYSURFACEPROC glad_eglDestroySurface = NULL; +PFNEGLDESTROYSYNCPROC glad_eglDestroySync = NULL; +PFNEGLDESTROYSYNCKHRPROC glad_eglDestroySyncKHR = NULL; +PFNEGLGETCONFIGATTRIBPROC glad_eglGetConfigAttrib = NULL; +PFNEGLGETCONFIGSPROC glad_eglGetConfigs = NULL; +PFNEGLGETCURRENTCONTEXTPROC glad_eglGetCurrentContext = NULL; +PFNEGLGETCURRENTDISPLAYPROC glad_eglGetCurrentDisplay = NULL; +PFNEGLGETCURRENTSURFACEPROC glad_eglGetCurrentSurface = NULL; +PFNEGLGETDISPLAYPROC glad_eglGetDisplay = NULL; +PFNEGLGETERRORPROC glad_eglGetError = NULL; +PFNEGLGETPLATFORMDISPLAYPROC glad_eglGetPlatformDisplay = NULL; +PFNEGLGETPLATFORMDISPLAYEXTPROC glad_eglGetPlatformDisplayEXT = NULL; +PFNEGLGETPROCADDRESSPROC glad_eglGetProcAddress = NULL; +PFNEGLGETSYNCATTRIBPROC glad_eglGetSyncAttrib = NULL; +PFNEGLGETSYNCATTRIBKHRPROC glad_eglGetSyncAttribKHR = NULL; +PFNEGLINITIALIZEPROC glad_eglInitialize = NULL; +PFNEGLMAKECURRENTPROC glad_eglMakeCurrent = NULL; +PFNEGLQUERYAPIPROC glad_eglQueryAPI = NULL; +PFNEGLQUERYCONTEXTPROC glad_eglQueryContext = NULL; +PFNEGLQUERYDMABUFFORMATSEXTPROC glad_eglQueryDmaBufFormatsEXT = NULL; +PFNEGLQUERYDMABUFMODIFIERSEXTPROC glad_eglQueryDmaBufModifiersEXT = NULL; +PFNEGLQUERYSTRINGPROC glad_eglQueryString = NULL; +PFNEGLQUERYSURFACEPROC glad_eglQuerySurface = NULL; +PFNEGLRELEASETEXIMAGEPROC glad_eglReleaseTexImage = NULL; +PFNEGLRELEASETHREADPROC glad_eglReleaseThread = NULL; +PFNEGLSIGNALSYNCKHRPROC glad_eglSignalSyncKHR = NULL; +PFNEGLSURFACEATTRIBPROC glad_eglSurfaceAttrib = NULL; +PFNEGLSWAPBUFFERSPROC glad_eglSwapBuffers = NULL; +PFNEGLSWAPINTERVALPROC glad_eglSwapInterval = NULL; +PFNEGLTERMINATEPROC glad_eglTerminate = NULL; +PFNEGLWAITCLIENTPROC glad_eglWaitClient = NULL; +PFNEGLWAITGLPROC glad_eglWaitGL = NULL; +PFNEGLWAITNATIVEPROC glad_eglWaitNative = NULL; +PFNEGLWAITSYNCPROC glad_eglWaitSync = NULL; + + +static void glad_egl_load_EGL_VERSION_1_0( GLADuserptrloadfunc load, void* userptr) { + if(!GLAD_EGL_VERSION_1_0) return; + glad_eglChooseConfig = (PFNEGLCHOOSECONFIGPROC) load(userptr, "eglChooseConfig"); + glad_eglCopyBuffers = (PFNEGLCOPYBUFFERSPROC) load(userptr, "eglCopyBuffers"); + glad_eglCreateContext = (PFNEGLCREATECONTEXTPROC) load(userptr, "eglCreateContext"); + glad_eglCreatePbufferSurface = (PFNEGLCREATEPBUFFERSURFACEPROC) load(userptr, "eglCreatePbufferSurface"); + glad_eglCreatePixmapSurface = (PFNEGLCREATEPIXMAPSURFACEPROC) load(userptr, "eglCreatePixmapSurface"); + glad_eglCreateWindowSurface = (PFNEGLCREATEWINDOWSURFACEPROC) load(userptr, "eglCreateWindowSurface"); + glad_eglDestroyContext = (PFNEGLDESTROYCONTEXTPROC) load(userptr, "eglDestroyContext"); + glad_eglDestroySurface = (PFNEGLDESTROYSURFACEPROC) load(userptr, "eglDestroySurface"); + glad_eglGetConfigAttrib = (PFNEGLGETCONFIGATTRIBPROC) load(userptr, "eglGetConfigAttrib"); + glad_eglGetConfigs = (PFNEGLGETCONFIGSPROC) load(userptr, "eglGetConfigs"); + glad_eglGetCurrentDisplay = (PFNEGLGETCURRENTDISPLAYPROC) load(userptr, "eglGetCurrentDisplay"); + glad_eglGetCurrentSurface = (PFNEGLGETCURRENTSURFACEPROC) load(userptr, "eglGetCurrentSurface"); + glad_eglGetDisplay = (PFNEGLGETDISPLAYPROC) load(userptr, "eglGetDisplay"); + glad_eglGetError = (PFNEGLGETERRORPROC) load(userptr, "eglGetError"); + glad_eglGetProcAddress = (PFNEGLGETPROCADDRESSPROC) load(userptr, "eglGetProcAddress"); + glad_eglInitialize = (PFNEGLINITIALIZEPROC) load(userptr, "eglInitialize"); + glad_eglMakeCurrent = (PFNEGLMAKECURRENTPROC) load(userptr, "eglMakeCurrent"); + glad_eglQueryContext = (PFNEGLQUERYCONTEXTPROC) load(userptr, "eglQueryContext"); + glad_eglQueryString = (PFNEGLQUERYSTRINGPROC) load(userptr, "eglQueryString"); + glad_eglQuerySurface = (PFNEGLQUERYSURFACEPROC) load(userptr, "eglQuerySurface"); + glad_eglSwapBuffers = (PFNEGLSWAPBUFFERSPROC) load(userptr, "eglSwapBuffers"); + glad_eglTerminate = (PFNEGLTERMINATEPROC) load(userptr, "eglTerminate"); + glad_eglWaitGL = (PFNEGLWAITGLPROC) load(userptr, "eglWaitGL"); + glad_eglWaitNative = (PFNEGLWAITNATIVEPROC) load(userptr, "eglWaitNative"); +} +static void glad_egl_load_EGL_VERSION_1_1( GLADuserptrloadfunc load, void* userptr) { + if(!GLAD_EGL_VERSION_1_1) return; + glad_eglBindTexImage = (PFNEGLBINDTEXIMAGEPROC) load(userptr, "eglBindTexImage"); + glad_eglReleaseTexImage = (PFNEGLRELEASETEXIMAGEPROC) load(userptr, "eglReleaseTexImage"); + glad_eglSurfaceAttrib = (PFNEGLSURFACEATTRIBPROC) load(userptr, "eglSurfaceAttrib"); + glad_eglSwapInterval = (PFNEGLSWAPINTERVALPROC) load(userptr, "eglSwapInterval"); +} +static void glad_egl_load_EGL_VERSION_1_2( GLADuserptrloadfunc load, void* userptr) { + if(!GLAD_EGL_VERSION_1_2) return; + glad_eglBindAPI = (PFNEGLBINDAPIPROC) load(userptr, "eglBindAPI"); + glad_eglCreatePbufferFromClientBuffer = (PFNEGLCREATEPBUFFERFROMCLIENTBUFFERPROC) load(userptr, "eglCreatePbufferFromClientBuffer"); + glad_eglQueryAPI = (PFNEGLQUERYAPIPROC) load(userptr, "eglQueryAPI"); + glad_eglReleaseThread = (PFNEGLRELEASETHREADPROC) load(userptr, "eglReleaseThread"); + glad_eglWaitClient = (PFNEGLWAITCLIENTPROC) load(userptr, "eglWaitClient"); +} +static void glad_egl_load_EGL_VERSION_1_4( GLADuserptrloadfunc load, void* userptr) { + if(!GLAD_EGL_VERSION_1_4) return; + glad_eglGetCurrentContext = (PFNEGLGETCURRENTCONTEXTPROC) load(userptr, "eglGetCurrentContext"); +} +static void glad_egl_load_EGL_VERSION_1_5( GLADuserptrloadfunc load, void* userptr) { + if(!GLAD_EGL_VERSION_1_5) return; + glad_eglClientWaitSync = (PFNEGLCLIENTWAITSYNCPROC) load(userptr, "eglClientWaitSync"); + glad_eglCreateImage = (PFNEGLCREATEIMAGEPROC) load(userptr, "eglCreateImage"); + glad_eglCreatePlatformPixmapSurface = (PFNEGLCREATEPLATFORMPIXMAPSURFACEPROC) load(userptr, "eglCreatePlatformPixmapSurface"); + glad_eglCreatePlatformWindowSurface = (PFNEGLCREATEPLATFORMWINDOWSURFACEPROC) load(userptr, "eglCreatePlatformWindowSurface"); + glad_eglCreateSync = (PFNEGLCREATESYNCPROC) load(userptr, "eglCreateSync"); + glad_eglDestroyImage = (PFNEGLDESTROYIMAGEPROC) load(userptr, "eglDestroyImage"); + glad_eglDestroySync = (PFNEGLDESTROYSYNCPROC) load(userptr, "eglDestroySync"); + glad_eglGetPlatformDisplay = (PFNEGLGETPLATFORMDISPLAYPROC) load(userptr, "eglGetPlatformDisplay"); + glad_eglGetSyncAttrib = (PFNEGLGETSYNCATTRIBPROC) load(userptr, "eglGetSyncAttrib"); + glad_eglWaitSync = (PFNEGLWAITSYNCPROC) load(userptr, "eglWaitSync"); +} +static void glad_egl_load_EGL_EXT_image_dma_buf_import_modifiers( GLADuserptrloadfunc load, void* userptr) { + if(!GLAD_EGL_EXT_image_dma_buf_import_modifiers) return; + glad_eglQueryDmaBufFormatsEXT = (PFNEGLQUERYDMABUFFORMATSEXTPROC) load(userptr, "eglQueryDmaBufFormatsEXT"); + glad_eglQueryDmaBufModifiersEXT = (PFNEGLQUERYDMABUFMODIFIERSEXTPROC) load(userptr, "eglQueryDmaBufModifiersEXT"); +} +static void glad_egl_load_EGL_EXT_platform_base( GLADuserptrloadfunc load, void* userptr) { + if(!GLAD_EGL_EXT_platform_base) return; + glad_eglCreatePlatformPixmapSurfaceEXT = (PFNEGLCREATEPLATFORMPIXMAPSURFACEEXTPROC) load(userptr, "eglCreatePlatformPixmapSurfaceEXT"); + glad_eglCreatePlatformWindowSurfaceEXT = (PFNEGLCREATEPLATFORMWINDOWSURFACEEXTPROC) load(userptr, "eglCreatePlatformWindowSurfaceEXT"); + glad_eglGetPlatformDisplayEXT = (PFNEGLGETPLATFORMDISPLAYEXTPROC) load(userptr, "eglGetPlatformDisplayEXT"); +} +static void glad_egl_load_EGL_KHR_cl_event2( GLADuserptrloadfunc load, void* userptr) { + if(!GLAD_EGL_KHR_cl_event2) return; + glad_eglCreateSync64KHR = (PFNEGLCREATESYNC64KHRPROC) load(userptr, "eglCreateSync64KHR"); +} +static void glad_egl_load_EGL_KHR_fence_sync( GLADuserptrloadfunc load, void* userptr) { + if(!GLAD_EGL_KHR_fence_sync) return; + glad_eglClientWaitSyncKHR = (PFNEGLCLIENTWAITSYNCKHRPROC) load(userptr, "eglClientWaitSyncKHR"); + glad_eglCreateSyncKHR = (PFNEGLCREATESYNCKHRPROC) load(userptr, "eglCreateSyncKHR"); + glad_eglDestroySyncKHR = (PFNEGLDESTROYSYNCKHRPROC) load(userptr, "eglDestroySyncKHR"); + glad_eglGetSyncAttribKHR = (PFNEGLGETSYNCATTRIBKHRPROC) load(userptr, "eglGetSyncAttribKHR"); +} +static void glad_egl_load_EGL_KHR_image( GLADuserptrloadfunc load, void* userptr) { + if(!GLAD_EGL_KHR_image) return; + glad_eglCreateImageKHR = (PFNEGLCREATEIMAGEKHRPROC) load(userptr, "eglCreateImageKHR"); + glad_eglDestroyImageKHR = (PFNEGLDESTROYIMAGEKHRPROC) load(userptr, "eglDestroyImageKHR"); +} +static void glad_egl_load_EGL_KHR_image_base( GLADuserptrloadfunc load, void* userptr) { + if(!GLAD_EGL_KHR_image_base) return; + glad_eglCreateImageKHR = (PFNEGLCREATEIMAGEKHRPROC) load(userptr, "eglCreateImageKHR"); + glad_eglDestroyImageKHR = (PFNEGLDESTROYIMAGEKHRPROC) load(userptr, "eglDestroyImageKHR"); +} +static void glad_egl_load_EGL_KHR_reusable_sync( GLADuserptrloadfunc load, void* userptr) { + if(!GLAD_EGL_KHR_reusable_sync) return; + glad_eglClientWaitSyncKHR = (PFNEGLCLIENTWAITSYNCKHRPROC) load(userptr, "eglClientWaitSyncKHR"); + glad_eglCreateSyncKHR = (PFNEGLCREATESYNCKHRPROC) load(userptr, "eglCreateSyncKHR"); + glad_eglDestroySyncKHR = (PFNEGLDESTROYSYNCKHRPROC) load(userptr, "eglDestroySyncKHR"); + glad_eglGetSyncAttribKHR = (PFNEGLGETSYNCATTRIBKHRPROC) load(userptr, "eglGetSyncAttribKHR"); + glad_eglSignalSyncKHR = (PFNEGLSIGNALSYNCKHRPROC) load(userptr, "eglSignalSyncKHR"); +} + + +static void glad_egl_resolve_aliases(void) { + if (glad_eglClientWaitSync == NULL && glad_eglClientWaitSyncKHR != NULL) glad_eglClientWaitSync = (PFNEGLCLIENTWAITSYNCPROC)glad_eglClientWaitSyncKHR; + if (glad_eglClientWaitSyncKHR == NULL && glad_eglClientWaitSync != NULL) glad_eglClientWaitSyncKHR = (PFNEGLCLIENTWAITSYNCKHRPROC)glad_eglClientWaitSync; + if (glad_eglCreateSync == NULL && glad_eglCreateSync64KHR != NULL) glad_eglCreateSync = (PFNEGLCREATESYNCPROC)glad_eglCreateSync64KHR; + if (glad_eglCreateSync64KHR == NULL && glad_eglCreateSync != NULL) glad_eglCreateSync64KHR = (PFNEGLCREATESYNC64KHRPROC)glad_eglCreateSync; + if (glad_eglDestroyImage == NULL && glad_eglDestroyImageKHR != NULL) glad_eglDestroyImage = (PFNEGLDESTROYIMAGEPROC)glad_eglDestroyImageKHR; + if (glad_eglDestroyImageKHR == NULL && glad_eglDestroyImage != NULL) glad_eglDestroyImageKHR = (PFNEGLDESTROYIMAGEKHRPROC)glad_eglDestroyImage; + if (glad_eglDestroySync == NULL && glad_eglDestroySyncKHR != NULL) glad_eglDestroySync = (PFNEGLDESTROYSYNCPROC)glad_eglDestroySyncKHR; + if (glad_eglDestroySyncKHR == NULL && glad_eglDestroySync != NULL) glad_eglDestroySyncKHR = (PFNEGLDESTROYSYNCKHRPROC)glad_eglDestroySync; +} + +static int glad_egl_get_extensions(EGLDisplay display, const char **extensions) { + *extensions = eglQueryString(display, EGL_EXTENSIONS); + + return extensions != NULL; +} + +static int glad_egl_has_extension(const char *extensions, const char *ext) { + const char *loc; + const char *terminator; + if(extensions == NULL) { + return 0; + } + while(1) { + loc = strstr(extensions, ext); + if(loc == NULL) { + return 0; + } + terminator = loc + strlen(ext); + if((loc == extensions || *(loc - 1) == ' ') && + (*terminator == ' ' || *terminator == '\0')) { + return 1; + } + extensions = terminator; + } +} + +static GLADapiproc glad_egl_get_proc_from_userptr(void *userptr, const char *name) { + return (GLAD_GNUC_EXTENSION (GLADapiproc (*)(const char *name)) userptr)(name); +} + +static int glad_egl_find_extensions_egl(EGLDisplay display) { + const char *extensions; + if (!glad_egl_get_extensions(display, &extensions)) return 0; + + GLAD_EGL_EXT_image_dma_buf_import = glad_egl_has_extension(extensions, "EGL_EXT_image_dma_buf_import"); + GLAD_EGL_EXT_image_dma_buf_import_modifiers = glad_egl_has_extension(extensions, "EGL_EXT_image_dma_buf_import_modifiers"); + GLAD_EGL_EXT_platform_base = glad_egl_has_extension(extensions, "EGL_EXT_platform_base"); + GLAD_EGL_EXT_platform_wayland = glad_egl_has_extension(extensions, "EGL_EXT_platform_wayland"); + GLAD_EGL_KHR_cl_event2 = glad_egl_has_extension(extensions, "EGL_KHR_cl_event2"); + GLAD_EGL_KHR_fence_sync = glad_egl_has_extension(extensions, "EGL_KHR_fence_sync"); + GLAD_EGL_KHR_image = glad_egl_has_extension(extensions, "EGL_KHR_image"); + GLAD_EGL_KHR_image_base = glad_egl_has_extension(extensions, "EGL_KHR_image_base"); + GLAD_EGL_KHR_platform_gbm = glad_egl_has_extension(extensions, "EGL_KHR_platform_gbm"); + GLAD_EGL_KHR_platform_wayland = glad_egl_has_extension(extensions, "EGL_KHR_platform_wayland"); + GLAD_EGL_KHR_reusable_sync = glad_egl_has_extension(extensions, "EGL_KHR_reusable_sync"); + + return 1; +} + +static int glad_egl_find_core_egl(EGLDisplay display) { + int major, minor; + const char *version; + + if (display == NULL) { + display = EGL_NO_DISPLAY; /* this is usually NULL, better safe than sorry */ + } + if (display == EGL_NO_DISPLAY) { + display = eglGetCurrentDisplay(); + } +#ifdef EGL_VERSION_1_4 + if (display == EGL_NO_DISPLAY) { + display = eglGetDisplay(EGL_DEFAULT_DISPLAY); + } +#endif +#ifndef EGL_VERSION_1_5 + if (display == EGL_NO_DISPLAY) { + return 0; + } +#endif + + version = eglQueryString(display, EGL_VERSION); + (void) eglGetError(); + + if (version == NULL) { + major = 1; + minor = 0; + } else { + GLAD_IMPL_UTIL_SSCANF(version, "%d.%d", &major, &minor); + } + + GLAD_EGL_VERSION_1_0 = (major == 1 && minor >= 0) || major > 1; + GLAD_EGL_VERSION_1_1 = (major == 1 && minor >= 1) || major > 1; + GLAD_EGL_VERSION_1_2 = (major == 1 && minor >= 2) || major > 1; + GLAD_EGL_VERSION_1_3 = (major == 1 && minor >= 3) || major > 1; + GLAD_EGL_VERSION_1_4 = (major == 1 && minor >= 4) || major > 1; + GLAD_EGL_VERSION_1_5 = (major == 1 && minor >= 5) || major > 1; + + return GLAD_MAKE_VERSION(major, minor); +} + +int gladLoadEGLUserPtr(EGLDisplay display, GLADuserptrloadfunc load, void* userptr) { + int version; + eglGetDisplay = (PFNEGLGETDISPLAYPROC) load(userptr, "eglGetDisplay"); + eglGetCurrentDisplay = (PFNEGLGETCURRENTDISPLAYPROC) load(userptr, "eglGetCurrentDisplay"); + eglQueryString = (PFNEGLQUERYSTRINGPROC) load(userptr, "eglQueryString"); + eglGetError = (PFNEGLGETERRORPROC) load(userptr, "eglGetError"); + if (eglGetDisplay == NULL || eglGetCurrentDisplay == NULL || eglQueryString == NULL || eglGetError == NULL) return 0; + + version = glad_egl_find_core_egl(display); + if (!version) return 0; + glad_egl_load_EGL_VERSION_1_0(load, userptr); + glad_egl_load_EGL_VERSION_1_1(load, userptr); + glad_egl_load_EGL_VERSION_1_2(load, userptr); + glad_egl_load_EGL_VERSION_1_4(load, userptr); + glad_egl_load_EGL_VERSION_1_5(load, userptr); + + if (!glad_egl_find_extensions_egl(display)) return 0; + glad_egl_load_EGL_EXT_image_dma_buf_import_modifiers(load, userptr); + glad_egl_load_EGL_EXT_platform_base(load, userptr); + glad_egl_load_EGL_KHR_cl_event2(load, userptr); + glad_egl_load_EGL_KHR_fence_sync(load, userptr); + glad_egl_load_EGL_KHR_image(load, userptr); + glad_egl_load_EGL_KHR_image_base(load, userptr); + glad_egl_load_EGL_KHR_reusable_sync(load, userptr); + + glad_egl_resolve_aliases(); + + return version; +} + +int gladLoadEGL(EGLDisplay display, GLADloadfunc load) { + return gladLoadEGLUserPtr(display, glad_egl_get_proc_from_userptr, GLAD_GNUC_EXTENSION (void*) load); +} + + + + +#ifdef __cplusplus +} +#endif + +#endif /*LV_USE_EGL*/ \ No newline at end of file diff --git a/src/drivers/opengles/glad/src/gles2.c b/src/drivers/opengles/glad/src/gles2.c new file mode 100644 index 0000000000..9bf6190e43 --- /dev/null +++ b/src/drivers/opengles/glad/src/gles2.c @@ -0,0 +1,558 @@ +/** + * SPDX-License-Identifier: (WTFPL OR CC0-1.0) AND Apache-2.0 + */ +#include "../../lv_opengles_egl.h" + +#if LV_USE_EGL + +#include +#include +#include +#include "../include/glad/gles2.h" + +#ifndef GLAD_IMPL_UTIL_C_ +#define GLAD_IMPL_UTIL_C_ + +#ifdef _MSC_VER +#define GLAD_IMPL_UTIL_SSCANF sscanf_s +#else +#define GLAD_IMPL_UTIL_SSCANF sscanf +#endif + +#endif /* GLAD_IMPL_UTIL_C_ */ + +#ifdef __cplusplus +extern "C" { +#endif + + + +int GLAD_GL_ES_VERSION_2_0 = 0; +int GLAD_GL_APPLE_texture_max_level = 0; +int GLAD_GL_ARM_rgba8 = 0; +int GLAD_GL_EXT_color_buffer_float = 0; +int GLAD_GL_EXT_color_buffer_half_float = 0; +int GLAD_GL_EXT_texture_format_BGRA8888 = 0; +int GLAD_GL_EXT_texture_storage = 0; +int GLAD_GL_EXT_unpack_subimage = 0; +int GLAD_GL_OES_depth24 = 0; +int GLAD_GL_OES_mapbuffer = 0; +int GLAD_GL_OES_rgb8_rgba8 = 0; +int GLAD_GL_OES_texture_float = 0; +int GLAD_GL_OES_texture_half_float = 0; +int GLAD_GL_OES_texture_storage_multisample_2d_array = 0; +int GLAD_GL_OES_vertex_array_object = 0; + + + +PFNGLACTIVETEXTUREPROC glad_glActiveTexture = NULL; +PFNGLATTACHSHADERPROC glad_glAttachShader = NULL; +PFNGLBINDATTRIBLOCATIONPROC glad_glBindAttribLocation = NULL; +PFNGLBINDBUFFERPROC glad_glBindBuffer = NULL; +PFNGLBINDFRAMEBUFFERPROC glad_glBindFramebuffer = NULL; +PFNGLBINDRENDERBUFFERPROC glad_glBindRenderbuffer = NULL; +PFNGLBINDTEXTUREPROC glad_glBindTexture = NULL; +PFNGLBINDVERTEXARRAYOESPROC glad_glBindVertexArrayOES = NULL; +PFNGLBLENDCOLORPROC glad_glBlendColor = NULL; +PFNGLBLENDEQUATIONPROC glad_glBlendEquation = NULL; +PFNGLBLENDEQUATIONSEPARATEPROC glad_glBlendEquationSeparate = NULL; +PFNGLBLENDFUNCPROC glad_glBlendFunc = NULL; +PFNGLBLENDFUNCSEPARATEPROC glad_glBlendFuncSeparate = NULL; +PFNGLBUFFERDATAPROC glad_glBufferData = NULL; +PFNGLBUFFERSUBDATAPROC glad_glBufferSubData = NULL; +PFNGLCHECKFRAMEBUFFERSTATUSPROC glad_glCheckFramebufferStatus = NULL; +PFNGLCLEARPROC glad_glClear = NULL; +PFNGLCLEARCOLORPROC glad_glClearColor = NULL; +PFNGLCLEARDEPTHFPROC glad_glClearDepthf = NULL; +PFNGLCLEARSTENCILPROC glad_glClearStencil = NULL; +PFNGLCOLORMASKPROC glad_glColorMask = NULL; +PFNGLCOMPILESHADERPROC glad_glCompileShader = NULL; +PFNGLCOMPRESSEDTEXIMAGE2DPROC glad_glCompressedTexImage2D = NULL; +PFNGLCOMPRESSEDTEXSUBIMAGE2DPROC glad_glCompressedTexSubImage2D = NULL; +PFNGLCOPYTEXIMAGE2DPROC glad_glCopyTexImage2D = NULL; +PFNGLCOPYTEXSUBIMAGE2DPROC glad_glCopyTexSubImage2D = NULL; +PFNGLCREATEPROGRAMPROC glad_glCreateProgram = NULL; +PFNGLCREATESHADERPROC glad_glCreateShader = NULL; +PFNGLCULLFACEPROC glad_glCullFace = NULL; +PFNGLDELETEBUFFERSPROC glad_glDeleteBuffers = NULL; +PFNGLDELETEFRAMEBUFFERSPROC glad_glDeleteFramebuffers = NULL; +PFNGLDELETEPROGRAMPROC glad_glDeleteProgram = NULL; +PFNGLDELETERENDERBUFFERSPROC glad_glDeleteRenderbuffers = NULL; +PFNGLDELETESHADERPROC glad_glDeleteShader = NULL; +PFNGLDELETETEXTURESPROC glad_glDeleteTextures = NULL; +PFNGLDELETEVERTEXARRAYSOESPROC glad_glDeleteVertexArraysOES = NULL; +PFNGLDEPTHFUNCPROC glad_glDepthFunc = NULL; +PFNGLDEPTHMASKPROC glad_glDepthMask = NULL; +PFNGLDEPTHRANGEFPROC glad_glDepthRangef = NULL; +PFNGLDETACHSHADERPROC glad_glDetachShader = NULL; +PFNGLDISABLEPROC glad_glDisable = NULL; +PFNGLDISABLEVERTEXATTRIBARRAYPROC glad_glDisableVertexAttribArray = NULL; +PFNGLDRAWARRAYSPROC glad_glDrawArrays = NULL; +PFNGLDRAWELEMENTSPROC glad_glDrawElements = NULL; +PFNGLENABLEPROC glad_glEnable = NULL; +PFNGLENABLEVERTEXATTRIBARRAYPROC glad_glEnableVertexAttribArray = NULL; +PFNGLFINISHPROC glad_glFinish = NULL; +PFNGLFLUSHPROC glad_glFlush = NULL; +PFNGLFRAMEBUFFERRENDERBUFFERPROC glad_glFramebufferRenderbuffer = NULL; +PFNGLFRAMEBUFFERTEXTURE2DPROC glad_glFramebufferTexture2D = NULL; +PFNGLFRONTFACEPROC glad_glFrontFace = NULL; +PFNGLGENBUFFERSPROC glad_glGenBuffers = NULL; +PFNGLGENFRAMEBUFFERSPROC glad_glGenFramebuffers = NULL; +PFNGLGENRENDERBUFFERSPROC glad_glGenRenderbuffers = NULL; +PFNGLGENTEXTURESPROC glad_glGenTextures = NULL; +PFNGLGENVERTEXARRAYSOESPROC glad_glGenVertexArraysOES = NULL; +PFNGLGENERATEMIPMAPPROC glad_glGenerateMipmap = NULL; +PFNGLGETACTIVEATTRIBPROC glad_glGetActiveAttrib = NULL; +PFNGLGETACTIVEUNIFORMPROC glad_glGetActiveUniform = NULL; +PFNGLGETATTACHEDSHADERSPROC glad_glGetAttachedShaders = NULL; +PFNGLGETATTRIBLOCATIONPROC glad_glGetAttribLocation = NULL; +PFNGLGETBOOLEANVPROC glad_glGetBooleanv = NULL; +PFNGLGETBUFFERPARAMETERIVPROC glad_glGetBufferParameteriv = NULL; +PFNGLGETBUFFERPOINTERVOESPROC glad_glGetBufferPointervOES = NULL; +PFNGLGETERRORPROC glad_glGetError = NULL; +PFNGLGETFLOATVPROC glad_glGetFloatv = NULL; +PFNGLGETFRAMEBUFFERATTACHMENTPARAMETERIVPROC glad_glGetFramebufferAttachmentParameteriv = NULL; +PFNGLGETINTEGERVPROC glad_glGetIntegerv = NULL; +PFNGLGETPROGRAMINFOLOGPROC glad_glGetProgramInfoLog = NULL; +PFNGLGETPROGRAMIVPROC glad_glGetProgramiv = NULL; +PFNGLGETRENDERBUFFERPARAMETERIVPROC glad_glGetRenderbufferParameteriv = NULL; +PFNGLGETSHADERINFOLOGPROC glad_glGetShaderInfoLog = NULL; +PFNGLGETSHADERPRECISIONFORMATPROC glad_glGetShaderPrecisionFormat = NULL; +PFNGLGETSHADERSOURCEPROC glad_glGetShaderSource = NULL; +PFNGLGETSHADERIVPROC glad_glGetShaderiv = NULL; +PFNGLGETSTRINGPROC glad_glGetString = NULL; +PFNGLGETTEXPARAMETERFVPROC glad_glGetTexParameterfv = NULL; +PFNGLGETTEXPARAMETERIVPROC glad_glGetTexParameteriv = NULL; +PFNGLGETUNIFORMLOCATIONPROC glad_glGetUniformLocation = NULL; +PFNGLGETUNIFORMFVPROC glad_glGetUniformfv = NULL; +PFNGLGETUNIFORMIVPROC glad_glGetUniformiv = NULL; +PFNGLGETVERTEXATTRIBPOINTERVPROC glad_glGetVertexAttribPointerv = NULL; +PFNGLGETVERTEXATTRIBFVPROC glad_glGetVertexAttribfv = NULL; +PFNGLGETVERTEXATTRIBIVPROC glad_glGetVertexAttribiv = NULL; +PFNGLHINTPROC glad_glHint = NULL; +PFNGLISBUFFERPROC glad_glIsBuffer = NULL; +PFNGLISENABLEDPROC glad_glIsEnabled = NULL; +PFNGLISFRAMEBUFFERPROC glad_glIsFramebuffer = NULL; +PFNGLISPROGRAMPROC glad_glIsProgram = NULL; +PFNGLISRENDERBUFFERPROC glad_glIsRenderbuffer = NULL; +PFNGLISSHADERPROC glad_glIsShader = NULL; +PFNGLISTEXTUREPROC glad_glIsTexture = NULL; +PFNGLISVERTEXARRAYOESPROC glad_glIsVertexArrayOES = NULL; +PFNGLLINEWIDTHPROC glad_glLineWidth = NULL; +PFNGLLINKPROGRAMPROC glad_glLinkProgram = NULL; +PFNGLMAPBUFFEROESPROC glad_glMapBufferOES = NULL; +PFNGLPIXELSTOREIPROC glad_glPixelStorei = NULL; +PFNGLPOLYGONOFFSETPROC glad_glPolygonOffset = NULL; +PFNGLREADPIXELSPROC glad_glReadPixels = NULL; +PFNGLRELEASESHADERCOMPILERPROC glad_glReleaseShaderCompiler = NULL; +PFNGLRENDERBUFFERSTORAGEPROC glad_glRenderbufferStorage = NULL; +PFNGLSAMPLECOVERAGEPROC glad_glSampleCoverage = NULL; +PFNGLSCISSORPROC glad_glScissor = NULL; +PFNGLSHADERBINARYPROC glad_glShaderBinary = NULL; +PFNGLSHADERSOURCEPROC glad_glShaderSource = NULL; +PFNGLSTENCILFUNCPROC glad_glStencilFunc = NULL; +PFNGLSTENCILFUNCSEPARATEPROC glad_glStencilFuncSeparate = NULL; +PFNGLSTENCILMASKPROC glad_glStencilMask = NULL; +PFNGLSTENCILMASKSEPARATEPROC glad_glStencilMaskSeparate = NULL; +PFNGLSTENCILOPPROC glad_glStencilOp = NULL; +PFNGLSTENCILOPSEPARATEPROC glad_glStencilOpSeparate = NULL; +PFNGLTEXIMAGE2DPROC glad_glTexImage2D = NULL; +PFNGLTEXPARAMETERFPROC glad_glTexParameterf = NULL; +PFNGLTEXPARAMETERFVPROC glad_glTexParameterfv = NULL; +PFNGLTEXPARAMETERIPROC glad_glTexParameteri = NULL; +PFNGLTEXPARAMETERIVPROC glad_glTexParameteriv = NULL; +PFNGLTEXSTORAGE1DEXTPROC glad_glTexStorage1DEXT = NULL; +PFNGLTEXSTORAGE2DEXTPROC glad_glTexStorage2DEXT = NULL; +PFNGLTEXSTORAGE3DEXTPROC glad_glTexStorage3DEXT = NULL; +PFNGLTEXSTORAGE3DMULTISAMPLEOESPROC glad_glTexStorage3DMultisampleOES = NULL; +PFNGLTEXSUBIMAGE2DPROC glad_glTexSubImage2D = NULL; +PFNGLTEXTURESTORAGE1DEXTPROC glad_glTextureStorage1DEXT = NULL; +PFNGLTEXTURESTORAGE2DEXTPROC glad_glTextureStorage2DEXT = NULL; +PFNGLTEXTURESTORAGE3DEXTPROC glad_glTextureStorage3DEXT = NULL; +PFNGLUNIFORM1FPROC glad_glUniform1f = NULL; +PFNGLUNIFORM1FVPROC glad_glUniform1fv = NULL; +PFNGLUNIFORM1IPROC glad_glUniform1i = NULL; +PFNGLUNIFORM1IVPROC glad_glUniform1iv = NULL; +PFNGLUNIFORM2FPROC glad_glUniform2f = NULL; +PFNGLUNIFORM2FVPROC glad_glUniform2fv = NULL; +PFNGLUNIFORM2IPROC glad_glUniform2i = NULL; +PFNGLUNIFORM2IVPROC glad_glUniform2iv = NULL; +PFNGLUNIFORM3FPROC glad_glUniform3f = NULL; +PFNGLUNIFORM3FVPROC glad_glUniform3fv = NULL; +PFNGLUNIFORM3IPROC glad_glUniform3i = NULL; +PFNGLUNIFORM3IVPROC glad_glUniform3iv = NULL; +PFNGLUNIFORM4FPROC glad_glUniform4f = NULL; +PFNGLUNIFORM4FVPROC glad_glUniform4fv = NULL; +PFNGLUNIFORM4IPROC glad_glUniform4i = NULL; +PFNGLUNIFORM4IVPROC glad_glUniform4iv = NULL; +PFNGLUNIFORMMATRIX2FVPROC glad_glUniformMatrix2fv = NULL; +PFNGLUNIFORMMATRIX3FVPROC glad_glUniformMatrix3fv = NULL; +PFNGLUNIFORMMATRIX4FVPROC glad_glUniformMatrix4fv = NULL; +PFNGLUNMAPBUFFEROESPROC glad_glUnmapBufferOES = NULL; +PFNGLUSEPROGRAMPROC glad_glUseProgram = NULL; +PFNGLVALIDATEPROGRAMPROC glad_glValidateProgram = NULL; +PFNGLVERTEXATTRIB1FPROC glad_glVertexAttrib1f = NULL; +PFNGLVERTEXATTRIB1FVPROC glad_glVertexAttrib1fv = NULL; +PFNGLVERTEXATTRIB2FPROC glad_glVertexAttrib2f = NULL; +PFNGLVERTEXATTRIB2FVPROC glad_glVertexAttrib2fv = NULL; +PFNGLVERTEXATTRIB3FPROC glad_glVertexAttrib3f = NULL; +PFNGLVERTEXATTRIB3FVPROC glad_glVertexAttrib3fv = NULL; +PFNGLVERTEXATTRIB4FPROC glad_glVertexAttrib4f = NULL; +PFNGLVERTEXATTRIB4FVPROC glad_glVertexAttrib4fv = NULL; +PFNGLVERTEXATTRIBPOINTERPROC glad_glVertexAttribPointer = NULL; +PFNGLVIEWPORTPROC glad_glViewport = NULL; + + +static void glad_gl_load_GL_ES_VERSION_2_0( GLADuserptrloadfunc load, void* userptr) { + if(!GLAD_GL_ES_VERSION_2_0) return; + glad_glActiveTexture = (PFNGLACTIVETEXTUREPROC) load(userptr, "glActiveTexture"); + glad_glAttachShader = (PFNGLATTACHSHADERPROC) load(userptr, "glAttachShader"); + glad_glBindAttribLocation = (PFNGLBINDATTRIBLOCATIONPROC) load(userptr, "glBindAttribLocation"); + glad_glBindBuffer = (PFNGLBINDBUFFERPROC) load(userptr, "glBindBuffer"); + glad_glBindFramebuffer = (PFNGLBINDFRAMEBUFFERPROC) load(userptr, "glBindFramebuffer"); + glad_glBindRenderbuffer = (PFNGLBINDRENDERBUFFERPROC) load(userptr, "glBindRenderbuffer"); + glad_glBindTexture = (PFNGLBINDTEXTUREPROC) load(userptr, "glBindTexture"); + glad_glBlendColor = (PFNGLBLENDCOLORPROC) load(userptr, "glBlendColor"); + glad_glBlendEquation = (PFNGLBLENDEQUATIONPROC) load(userptr, "glBlendEquation"); + glad_glBlendEquationSeparate = (PFNGLBLENDEQUATIONSEPARATEPROC) load(userptr, "glBlendEquationSeparate"); + glad_glBlendFunc = (PFNGLBLENDFUNCPROC) load(userptr, "glBlendFunc"); + glad_glBlendFuncSeparate = (PFNGLBLENDFUNCSEPARATEPROC) load(userptr, "glBlendFuncSeparate"); + glad_glBufferData = (PFNGLBUFFERDATAPROC) load(userptr, "glBufferData"); + glad_glBufferSubData = (PFNGLBUFFERSUBDATAPROC) load(userptr, "glBufferSubData"); + glad_glCheckFramebufferStatus = (PFNGLCHECKFRAMEBUFFERSTATUSPROC) load(userptr, "glCheckFramebufferStatus"); + glad_glClear = (PFNGLCLEARPROC) load(userptr, "glClear"); + glad_glClearColor = (PFNGLCLEARCOLORPROC) load(userptr, "glClearColor"); + glad_glClearDepthf = (PFNGLCLEARDEPTHFPROC) load(userptr, "glClearDepthf"); + glad_glClearStencil = (PFNGLCLEARSTENCILPROC) load(userptr, "glClearStencil"); + glad_glColorMask = (PFNGLCOLORMASKPROC) load(userptr, "glColorMask"); + glad_glCompileShader = (PFNGLCOMPILESHADERPROC) load(userptr, "glCompileShader"); + glad_glCompressedTexImage2D = (PFNGLCOMPRESSEDTEXIMAGE2DPROC) load(userptr, "glCompressedTexImage2D"); + glad_glCompressedTexSubImage2D = (PFNGLCOMPRESSEDTEXSUBIMAGE2DPROC) load(userptr, "glCompressedTexSubImage2D"); + glad_glCopyTexImage2D = (PFNGLCOPYTEXIMAGE2DPROC) load(userptr, "glCopyTexImage2D"); + glad_glCopyTexSubImage2D = (PFNGLCOPYTEXSUBIMAGE2DPROC) load(userptr, "glCopyTexSubImage2D"); + glad_glCreateProgram = (PFNGLCREATEPROGRAMPROC) load(userptr, "glCreateProgram"); + glad_glCreateShader = (PFNGLCREATESHADERPROC) load(userptr, "glCreateShader"); + glad_glCullFace = (PFNGLCULLFACEPROC) load(userptr, "glCullFace"); + glad_glDeleteBuffers = (PFNGLDELETEBUFFERSPROC) load(userptr, "glDeleteBuffers"); + glad_glDeleteFramebuffers = (PFNGLDELETEFRAMEBUFFERSPROC) load(userptr, "glDeleteFramebuffers"); + glad_glDeleteProgram = (PFNGLDELETEPROGRAMPROC) load(userptr, "glDeleteProgram"); + glad_glDeleteRenderbuffers = (PFNGLDELETERENDERBUFFERSPROC) load(userptr, "glDeleteRenderbuffers"); + glad_glDeleteShader = (PFNGLDELETESHADERPROC) load(userptr, "glDeleteShader"); + glad_glDeleteTextures = (PFNGLDELETETEXTURESPROC) load(userptr, "glDeleteTextures"); + glad_glDepthFunc = (PFNGLDEPTHFUNCPROC) load(userptr, "glDepthFunc"); + glad_glDepthMask = (PFNGLDEPTHMASKPROC) load(userptr, "glDepthMask"); + glad_glDepthRangef = (PFNGLDEPTHRANGEFPROC) load(userptr, "glDepthRangef"); + glad_glDetachShader = (PFNGLDETACHSHADERPROC) load(userptr, "glDetachShader"); + glad_glDisable = (PFNGLDISABLEPROC) load(userptr, "glDisable"); + glad_glDisableVertexAttribArray = (PFNGLDISABLEVERTEXATTRIBARRAYPROC) load(userptr, "glDisableVertexAttribArray"); + glad_glDrawArrays = (PFNGLDRAWARRAYSPROC) load(userptr, "glDrawArrays"); + glad_glDrawElements = (PFNGLDRAWELEMENTSPROC) load(userptr, "glDrawElements"); + glad_glEnable = (PFNGLENABLEPROC) load(userptr, "glEnable"); + glad_glEnableVertexAttribArray = (PFNGLENABLEVERTEXATTRIBARRAYPROC) load(userptr, "glEnableVertexAttribArray"); + glad_glFinish = (PFNGLFINISHPROC) load(userptr, "glFinish"); + glad_glFlush = (PFNGLFLUSHPROC) load(userptr, "glFlush"); + glad_glFramebufferRenderbuffer = (PFNGLFRAMEBUFFERRENDERBUFFERPROC) load(userptr, "glFramebufferRenderbuffer"); + glad_glFramebufferTexture2D = (PFNGLFRAMEBUFFERTEXTURE2DPROC) load(userptr, "glFramebufferTexture2D"); + glad_glFrontFace = (PFNGLFRONTFACEPROC) load(userptr, "glFrontFace"); + glad_glGenBuffers = (PFNGLGENBUFFERSPROC) load(userptr, "glGenBuffers"); + glad_glGenFramebuffers = (PFNGLGENFRAMEBUFFERSPROC) load(userptr, "glGenFramebuffers"); + glad_glGenRenderbuffers = (PFNGLGENRENDERBUFFERSPROC) load(userptr, "glGenRenderbuffers"); + glad_glGenTextures = (PFNGLGENTEXTURESPROC) load(userptr, "glGenTextures"); + glad_glGenerateMipmap = (PFNGLGENERATEMIPMAPPROC) load(userptr, "glGenerateMipmap"); + glad_glGetActiveAttrib = (PFNGLGETACTIVEATTRIBPROC) load(userptr, "glGetActiveAttrib"); + glad_glGetActiveUniform = (PFNGLGETACTIVEUNIFORMPROC) load(userptr, "glGetActiveUniform"); + glad_glGetAttachedShaders = (PFNGLGETATTACHEDSHADERSPROC) load(userptr, "glGetAttachedShaders"); + glad_glGetAttribLocation = (PFNGLGETATTRIBLOCATIONPROC) load(userptr, "glGetAttribLocation"); + glad_glGetBooleanv = (PFNGLGETBOOLEANVPROC) load(userptr, "glGetBooleanv"); + glad_glGetBufferParameteriv = (PFNGLGETBUFFERPARAMETERIVPROC) load(userptr, "glGetBufferParameteriv"); + glad_glGetError = (PFNGLGETERRORPROC) load(userptr, "glGetError"); + glad_glGetFloatv = (PFNGLGETFLOATVPROC) load(userptr, "glGetFloatv"); + glad_glGetFramebufferAttachmentParameteriv = (PFNGLGETFRAMEBUFFERATTACHMENTPARAMETERIVPROC) load(userptr, "glGetFramebufferAttachmentParameteriv"); + glad_glGetIntegerv = (PFNGLGETINTEGERVPROC) load(userptr, "glGetIntegerv"); + glad_glGetProgramInfoLog = (PFNGLGETPROGRAMINFOLOGPROC) load(userptr, "glGetProgramInfoLog"); + glad_glGetProgramiv = (PFNGLGETPROGRAMIVPROC) load(userptr, "glGetProgramiv"); + glad_glGetRenderbufferParameteriv = (PFNGLGETRENDERBUFFERPARAMETERIVPROC) load(userptr, "glGetRenderbufferParameteriv"); + glad_glGetShaderInfoLog = (PFNGLGETSHADERINFOLOGPROC) load(userptr, "glGetShaderInfoLog"); + glad_glGetShaderPrecisionFormat = (PFNGLGETSHADERPRECISIONFORMATPROC) load(userptr, "glGetShaderPrecisionFormat"); + glad_glGetShaderSource = (PFNGLGETSHADERSOURCEPROC) load(userptr, "glGetShaderSource"); + glad_glGetShaderiv = (PFNGLGETSHADERIVPROC) load(userptr, "glGetShaderiv"); + glad_glGetString = (PFNGLGETSTRINGPROC) load(userptr, "glGetString"); + glad_glGetTexParameterfv = (PFNGLGETTEXPARAMETERFVPROC) load(userptr, "glGetTexParameterfv"); + glad_glGetTexParameteriv = (PFNGLGETTEXPARAMETERIVPROC) load(userptr, "glGetTexParameteriv"); + glad_glGetUniformLocation = (PFNGLGETUNIFORMLOCATIONPROC) load(userptr, "glGetUniformLocation"); + glad_glGetUniformfv = (PFNGLGETUNIFORMFVPROC) load(userptr, "glGetUniformfv"); + glad_glGetUniformiv = (PFNGLGETUNIFORMIVPROC) load(userptr, "glGetUniformiv"); + glad_glGetVertexAttribPointerv = (PFNGLGETVERTEXATTRIBPOINTERVPROC) load(userptr, "glGetVertexAttribPointerv"); + glad_glGetVertexAttribfv = (PFNGLGETVERTEXATTRIBFVPROC) load(userptr, "glGetVertexAttribfv"); + glad_glGetVertexAttribiv = (PFNGLGETVERTEXATTRIBIVPROC) load(userptr, "glGetVertexAttribiv"); + glad_glHint = (PFNGLHINTPROC) load(userptr, "glHint"); + glad_glIsBuffer = (PFNGLISBUFFERPROC) load(userptr, "glIsBuffer"); + glad_glIsEnabled = (PFNGLISENABLEDPROC) load(userptr, "glIsEnabled"); + glad_glIsFramebuffer = (PFNGLISFRAMEBUFFERPROC) load(userptr, "glIsFramebuffer"); + glad_glIsProgram = (PFNGLISPROGRAMPROC) load(userptr, "glIsProgram"); + glad_glIsRenderbuffer = (PFNGLISRENDERBUFFERPROC) load(userptr, "glIsRenderbuffer"); + glad_glIsShader = (PFNGLISSHADERPROC) load(userptr, "glIsShader"); + glad_glIsTexture = (PFNGLISTEXTUREPROC) load(userptr, "glIsTexture"); + glad_glLineWidth = (PFNGLLINEWIDTHPROC) load(userptr, "glLineWidth"); + glad_glLinkProgram = (PFNGLLINKPROGRAMPROC) load(userptr, "glLinkProgram"); + glad_glPixelStorei = (PFNGLPIXELSTOREIPROC) load(userptr, "glPixelStorei"); + glad_glPolygonOffset = (PFNGLPOLYGONOFFSETPROC) load(userptr, "glPolygonOffset"); + glad_glReadPixels = (PFNGLREADPIXELSPROC) load(userptr, "glReadPixels"); + glad_glReleaseShaderCompiler = (PFNGLRELEASESHADERCOMPILERPROC) load(userptr, "glReleaseShaderCompiler"); + glad_glRenderbufferStorage = (PFNGLRENDERBUFFERSTORAGEPROC) load(userptr, "glRenderbufferStorage"); + glad_glSampleCoverage = (PFNGLSAMPLECOVERAGEPROC) load(userptr, "glSampleCoverage"); + glad_glScissor = (PFNGLSCISSORPROC) load(userptr, "glScissor"); + glad_glShaderBinary = (PFNGLSHADERBINARYPROC) load(userptr, "glShaderBinary"); + glad_glShaderSource = (PFNGLSHADERSOURCEPROC) load(userptr, "glShaderSource"); + glad_glStencilFunc = (PFNGLSTENCILFUNCPROC) load(userptr, "glStencilFunc"); + glad_glStencilFuncSeparate = (PFNGLSTENCILFUNCSEPARATEPROC) load(userptr, "glStencilFuncSeparate"); + glad_glStencilMask = (PFNGLSTENCILMASKPROC) load(userptr, "glStencilMask"); + glad_glStencilMaskSeparate = (PFNGLSTENCILMASKSEPARATEPROC) load(userptr, "glStencilMaskSeparate"); + glad_glStencilOp = (PFNGLSTENCILOPPROC) load(userptr, "glStencilOp"); + glad_glStencilOpSeparate = (PFNGLSTENCILOPSEPARATEPROC) load(userptr, "glStencilOpSeparate"); + glad_glTexImage2D = (PFNGLTEXIMAGE2DPROC) load(userptr, "glTexImage2D"); + glad_glTexParameterf = (PFNGLTEXPARAMETERFPROC) load(userptr, "glTexParameterf"); + glad_glTexParameterfv = (PFNGLTEXPARAMETERFVPROC) load(userptr, "glTexParameterfv"); + glad_glTexParameteri = (PFNGLTEXPARAMETERIPROC) load(userptr, "glTexParameteri"); + glad_glTexParameteriv = (PFNGLTEXPARAMETERIVPROC) load(userptr, "glTexParameteriv"); + glad_glTexSubImage2D = (PFNGLTEXSUBIMAGE2DPROC) load(userptr, "glTexSubImage2D"); + glad_glUniform1f = (PFNGLUNIFORM1FPROC) load(userptr, "glUniform1f"); + glad_glUniform1fv = (PFNGLUNIFORM1FVPROC) load(userptr, "glUniform1fv"); + glad_glUniform1i = (PFNGLUNIFORM1IPROC) load(userptr, "glUniform1i"); + glad_glUniform1iv = (PFNGLUNIFORM1IVPROC) load(userptr, "glUniform1iv"); + glad_glUniform2f = (PFNGLUNIFORM2FPROC) load(userptr, "glUniform2f"); + glad_glUniform2fv = (PFNGLUNIFORM2FVPROC) load(userptr, "glUniform2fv"); + glad_glUniform2i = (PFNGLUNIFORM2IPROC) load(userptr, "glUniform2i"); + glad_glUniform2iv = (PFNGLUNIFORM2IVPROC) load(userptr, "glUniform2iv"); + glad_glUniform3f = (PFNGLUNIFORM3FPROC) load(userptr, "glUniform3f"); + glad_glUniform3fv = (PFNGLUNIFORM3FVPROC) load(userptr, "glUniform3fv"); + glad_glUniform3i = (PFNGLUNIFORM3IPROC) load(userptr, "glUniform3i"); + glad_glUniform3iv = (PFNGLUNIFORM3IVPROC) load(userptr, "glUniform3iv"); + glad_glUniform4f = (PFNGLUNIFORM4FPROC) load(userptr, "glUniform4f"); + glad_glUniform4fv = (PFNGLUNIFORM4FVPROC) load(userptr, "glUniform4fv"); + glad_glUniform4i = (PFNGLUNIFORM4IPROC) load(userptr, "glUniform4i"); + glad_glUniform4iv = (PFNGLUNIFORM4IVPROC) load(userptr, "glUniform4iv"); + glad_glUniformMatrix2fv = (PFNGLUNIFORMMATRIX2FVPROC) load(userptr, "glUniformMatrix2fv"); + glad_glUniformMatrix3fv = (PFNGLUNIFORMMATRIX3FVPROC) load(userptr, "glUniformMatrix3fv"); + glad_glUniformMatrix4fv = (PFNGLUNIFORMMATRIX4FVPROC) load(userptr, "glUniformMatrix4fv"); + glad_glUseProgram = (PFNGLUSEPROGRAMPROC) load(userptr, "glUseProgram"); + glad_glValidateProgram = (PFNGLVALIDATEPROGRAMPROC) load(userptr, "glValidateProgram"); + glad_glVertexAttrib1f = (PFNGLVERTEXATTRIB1FPROC) load(userptr, "glVertexAttrib1f"); + glad_glVertexAttrib1fv = (PFNGLVERTEXATTRIB1FVPROC) load(userptr, "glVertexAttrib1fv"); + glad_glVertexAttrib2f = (PFNGLVERTEXATTRIB2FPROC) load(userptr, "glVertexAttrib2f"); + glad_glVertexAttrib2fv = (PFNGLVERTEXATTRIB2FVPROC) load(userptr, "glVertexAttrib2fv"); + glad_glVertexAttrib3f = (PFNGLVERTEXATTRIB3FPROC) load(userptr, "glVertexAttrib3f"); + glad_glVertexAttrib3fv = (PFNGLVERTEXATTRIB3FVPROC) load(userptr, "glVertexAttrib3fv"); + glad_glVertexAttrib4f = (PFNGLVERTEXATTRIB4FPROC) load(userptr, "glVertexAttrib4f"); + glad_glVertexAttrib4fv = (PFNGLVERTEXATTRIB4FVPROC) load(userptr, "glVertexAttrib4fv"); + glad_glVertexAttribPointer = (PFNGLVERTEXATTRIBPOINTERPROC) load(userptr, "glVertexAttribPointer"); + glad_glViewport = (PFNGLVIEWPORTPROC) load(userptr, "glViewport"); +} +static void glad_gl_load_GL_EXT_texture_storage( GLADuserptrloadfunc load, void* userptr) { + if(!GLAD_GL_EXT_texture_storage) return; + glad_glTexStorage1DEXT = (PFNGLTEXSTORAGE1DEXTPROC) load(userptr, "glTexStorage1DEXT"); + glad_glTexStorage2DEXT = (PFNGLTEXSTORAGE2DEXTPROC) load(userptr, "glTexStorage2DEXT"); + glad_glTexStorage3DEXT = (PFNGLTEXSTORAGE3DEXTPROC) load(userptr, "glTexStorage3DEXT"); + glad_glTextureStorage1DEXT = (PFNGLTEXTURESTORAGE1DEXTPROC) load(userptr, "glTextureStorage1DEXT"); + glad_glTextureStorage2DEXT = (PFNGLTEXTURESTORAGE2DEXTPROC) load(userptr, "glTextureStorage2DEXT"); + glad_glTextureStorage3DEXT = (PFNGLTEXTURESTORAGE3DEXTPROC) load(userptr, "glTextureStorage3DEXT"); +} +static void glad_gl_load_GL_OES_mapbuffer( GLADuserptrloadfunc load, void* userptr) { + if(!GLAD_GL_OES_mapbuffer) return; + glad_glGetBufferPointervOES = (PFNGLGETBUFFERPOINTERVOESPROC) load(userptr, "glGetBufferPointervOES"); + glad_glMapBufferOES = (PFNGLMAPBUFFEROESPROC) load(userptr, "glMapBufferOES"); + glad_glUnmapBufferOES = (PFNGLUNMAPBUFFEROESPROC) load(userptr, "glUnmapBufferOES"); +} +static void glad_gl_load_GL_OES_texture_storage_multisample_2d_array( GLADuserptrloadfunc load, void* userptr) { + if(!GLAD_GL_OES_texture_storage_multisample_2d_array) return; + glad_glTexStorage3DMultisampleOES = (PFNGLTEXSTORAGE3DMULTISAMPLEOESPROC) load(userptr, "glTexStorage3DMultisampleOES"); +} +static void glad_gl_load_GL_OES_vertex_array_object( GLADuserptrloadfunc load, void* userptr) { + if(!GLAD_GL_OES_vertex_array_object) return; + glad_glBindVertexArrayOES = (PFNGLBINDVERTEXARRAYOESPROC) load(userptr, "glBindVertexArrayOES"); + glad_glDeleteVertexArraysOES = (PFNGLDELETEVERTEXARRAYSOESPROC) load(userptr, "glDeleteVertexArraysOES"); + glad_glGenVertexArraysOES = (PFNGLGENVERTEXARRAYSOESPROC) load(userptr, "glGenVertexArraysOES"); + glad_glIsVertexArrayOES = (PFNGLISVERTEXARRAYOESPROC) load(userptr, "glIsVertexArrayOES"); +} + + +static void glad_gl_resolve_aliases(void) { +} + +static void glad_gl_free_extensions(char **exts_i) { + if (exts_i != NULL) { + unsigned int index; + for(index = 0; exts_i[index]; index++) { + free((void *) (exts_i[index])); + } + free((void *)exts_i); + exts_i = NULL; + } +} +static int glad_gl_get_extensions( const char **out_exts, char ***out_exts_i) { +#if defined(GL_ES_VERSION_3_0) || defined(GL_VERSION_3_0) + if (glad_glGetStringi != NULL && glad_glGetIntegerv != NULL) { + unsigned int index = 0; + unsigned int num_exts_i = 0; + char **exts_i = NULL; + glad_glGetIntegerv(GL_NUM_EXTENSIONS, (int*) &num_exts_i); + exts_i = (char **) malloc((num_exts_i + 1) * (sizeof *exts_i)); + if (exts_i == NULL) { + return 0; + } + for(index = 0; index < num_exts_i; index++) { + const char *gl_str_tmp = (const char*) glad_glGetStringi(GL_EXTENSIONS, index); + size_t len = strlen(gl_str_tmp) + 1; + + char *local_str = (char*) malloc(len * sizeof(char)); + if(local_str == NULL) { + exts_i[index] = NULL; + glad_gl_free_extensions(exts_i); + return 0; + } + + memcpy(local_str, gl_str_tmp, len * sizeof(char)); + exts_i[index] = local_str; + } + exts_i[index] = NULL; + + *out_exts_i = exts_i; + + return 1; + } +#else + GLAD_UNUSED(out_exts_i); +#endif + if (glad_glGetString == NULL) { + return 0; + } + *out_exts = (const char *)glad_glGetString(GL_EXTENSIONS); + return 1; +} +static int glad_gl_has_extension(const char *exts, char **exts_i, const char *ext) { + if(exts_i) { + unsigned int index; + for(index = 0; exts_i[index]; index++) { + const char *e = exts_i[index]; + if(strcmp(e, ext) == 0) { + return 1; + } + } + } else { + const char *extensions; + const char *loc; + const char *terminator; + extensions = exts; + if(extensions == NULL || ext == NULL) { + return 0; + } + while(1) { + loc = strstr(extensions, ext); + if(loc == NULL) { + return 0; + } + terminator = loc + strlen(ext); + if((loc == extensions || *(loc - 1) == ' ') && + (*terminator == ' ' || *terminator == '\0')) { + return 1; + } + extensions = terminator; + } + } + return 0; +} + +static GLADapiproc glad_gl_get_proc_from_userptr(void *userptr, const char* name) { + return (GLAD_GNUC_EXTENSION (GLADapiproc (*)(const char *name)) userptr)(name); +} + +static int glad_gl_find_extensions_gles2(void) { + const char *exts = NULL; + char **exts_i = NULL; + if (!glad_gl_get_extensions(&exts, &exts_i)) return 0; + + GLAD_GL_APPLE_texture_max_level = glad_gl_has_extension(exts, exts_i, "GL_APPLE_texture_max_level"); + GLAD_GL_ARM_rgba8 = glad_gl_has_extension(exts, exts_i, "GL_ARM_rgba8"); + GLAD_GL_EXT_color_buffer_float = glad_gl_has_extension(exts, exts_i, "GL_EXT_color_buffer_float"); + GLAD_GL_EXT_color_buffer_half_float = glad_gl_has_extension(exts, exts_i, "GL_EXT_color_buffer_half_float"); + GLAD_GL_EXT_texture_format_BGRA8888 = glad_gl_has_extension(exts, exts_i, "GL_EXT_texture_format_BGRA8888"); + GLAD_GL_EXT_texture_storage = glad_gl_has_extension(exts, exts_i, "GL_EXT_texture_storage"); + GLAD_GL_EXT_unpack_subimage = glad_gl_has_extension(exts, exts_i, "GL_EXT_unpack_subimage"); + GLAD_GL_OES_depth24 = glad_gl_has_extension(exts, exts_i, "GL_OES_depth24"); + GLAD_GL_OES_mapbuffer = glad_gl_has_extension(exts, exts_i, "GL_OES_mapbuffer"); + GLAD_GL_OES_rgb8_rgba8 = glad_gl_has_extension(exts, exts_i, "GL_OES_rgb8_rgba8"); + GLAD_GL_OES_texture_float = glad_gl_has_extension(exts, exts_i, "GL_OES_texture_float"); + GLAD_GL_OES_texture_half_float = glad_gl_has_extension(exts, exts_i, "GL_OES_texture_half_float"); + GLAD_GL_OES_texture_storage_multisample_2d_array = glad_gl_has_extension(exts, exts_i, "GL_OES_texture_storage_multisample_2d_array"); + GLAD_GL_OES_vertex_array_object = glad_gl_has_extension(exts, exts_i, "GL_OES_vertex_array_object"); + + glad_gl_free_extensions(exts_i); + + return 1; +} + +static int glad_gl_find_core_gles2(void) { + int i; + const char* version; + const char* prefixes[] = { + "OpenGL ES-CM ", + "OpenGL ES-CL ", + "OpenGL ES ", + "OpenGL SC ", + NULL + }; + int major = 0; + int minor = 0; + version = (const char*) glad_glGetString(GL_VERSION); + if (!version) return 0; + for (i = 0; prefixes[i]; i++) { + const size_t length = strlen(prefixes[i]); + if (strncmp(version, prefixes[i], length) == 0) { + version += length; + break; + } + } + + GLAD_IMPL_UTIL_SSCANF(version, "%d.%d", &major, &minor); + + GLAD_GL_ES_VERSION_2_0 = (major == 2 && minor >= 0) || major > 2; + + return GLAD_MAKE_VERSION(major, minor); +} + +int gladLoadGLES2UserPtr( GLADuserptrloadfunc load, void *userptr) { + int version; + + glad_glGetString = (PFNGLGETSTRINGPROC) load(userptr, "glGetString"); + if(glad_glGetString == NULL) return 0; + version = glad_gl_find_core_gles2(); + + glad_gl_load_GL_ES_VERSION_2_0(load, userptr); + + if (!glad_gl_find_extensions_gles2()) return 0; + glad_gl_load_GL_EXT_texture_storage(load, userptr); + glad_gl_load_GL_OES_mapbuffer(load, userptr); + glad_gl_load_GL_OES_texture_storage_multisample_2d_array(load, userptr); + glad_gl_load_GL_OES_vertex_array_object(load, userptr); + + + glad_gl_resolve_aliases(); + + return version; +} + + +int gladLoadGLES2( GLADloadfunc load) { + return gladLoadGLES2UserPtr( glad_gl_get_proc_from_userptr, GLAD_GNUC_EXTENSION (void*) load); +} + + + + + + +#ifdef __cplusplus +} +#endif + +#endif /*LV_USE_EGL*/ diff --git a/src/drivers/glfw/lv_opengles_debug.c b/src/drivers/opengles/lv_opengles_debug.c similarity index 93% rename from src/drivers/glfw/lv_opengles_debug.c rename to src/drivers/opengles/lv_opengles_debug.c index 1b098be6b0..c0d7ecf4c8 100644 --- a/src/drivers/glfw/lv_opengles_debug.c +++ b/src/drivers/opengles/lv_opengles_debug.c @@ -10,6 +10,8 @@ #include "lv_opengles_debug.h" #if LV_USE_OPENGLES +#include "lv_opengles_private.h" + #include "../../misc/lv_log.h" /********************* @@ -36,6 +38,7 @@ * GLOBAL FUNCTIONS **********************/ +#if LV_USE_OPENGLES_DEBUG void GLClearError() { while(glGetError() != GL_NO_ERROR); @@ -48,6 +51,7 @@ void GLLogCall(const char * function, const char * file, int line) LV_LOG_ERROR("[OpenGL Error] (%d) %s %s:%d", error, function, file, line); } } +#endif /********************** * STATIC FUNCTIONS diff --git a/src/drivers/glfw/lv_opengles_debug.h b/src/drivers/opengles/lv_opengles_debug.h similarity index 61% rename from src/drivers/glfw/lv_opengles_debug.h rename to src/drivers/opengles/lv_opengles_debug.h index aa8bbebe93..3e26302a9c 100644 --- a/src/drivers/glfw/lv_opengles_debug.h +++ b/src/drivers/opengles/lv_opengles_debug.h @@ -10,17 +10,37 @@ extern "C" { #endif +/********************* + * INCLUDES + *********************/ + #include "../../lv_conf_internal.h" #if LV_USE_OPENGLES -#include -#include -#include +/********************* + * DEFINES + *********************/ + +/********************** + * TYPEDEFS + **********************/ + +/********************** + * GLOBAL PROTOTYPES + **********************/ + +#if LV_USE_OPENGLES_DEBUG void GLClearError(void); void GLLogCall(const char * function, const char * file, int line); +#endif + +/********************** + * MACROS + **********************/ + #if LV_USE_OPENGLES_DEBUG #define GL_CALL(x) do {\ GLClearError();\ diff --git a/src/drivers/opengles/lv_opengles_driver.c b/src/drivers/opengles/lv_opengles_driver.c new file mode 100644 index 0000000000..90a4ee60c8 --- /dev/null +++ b/src/drivers/opengles/lv_opengles_driver.c @@ -0,0 +1,628 @@ +/** + * @file lv_opengles_driver.c + * + */ + +/********************* + * INCLUDES + *********************/ + +#include "lv_opengles_driver.h" +#if LV_USE_OPENGLES + +#include "../../misc/lv_types.h" +#include "../../misc/lv_profiler.h" +#include "lv_opengles_debug.h" +#include "lv_opengles_private.h" + +#include "../../display/lv_display.h" +#include "../../misc/lv_area_private.h" +#include "opengl_shader/lv_opengl_shader_internal.h" +#include "assets/lv_opengles_shader.h" + +/********************* + * DEFINES + *********************/ + +#define LV_OPENGLES_VERTEX_BUFFER_LEN 16 + +/********************** + * TYPEDEFS + **********************/ + +/********************** + * STATIC PROTOTYPES + **********************/ +static void lv_opengles_render_internal(unsigned int texture, const lv_area_t * texture_area, lv_opa_t opa, + int32_t disp_w, int32_t disp_h, const lv_area_t * texture_clip_area, + bool h_flip, bool v_flip, lv_color_t fill_color); +static void lv_opengles_enable_blending(void); +static void lv_opengles_vertex_buffer_init(const void * data, unsigned int size); +static void lv_opengles_vertex_buffer_deinit(void); +static void lv_opengles_vertex_buffer_bind(void); +static void lv_opengles_vertex_buffer_unbind(void); +static void lv_opengles_vertex_array_init(void); +static void lv_opengles_vertex_array_deinit(void); +static void lv_opengles_vertex_array_bind(void); +static void lv_opengles_vertex_array_unbind(void); +static void lv_opengles_vertex_array_add_buffer(void); +static void lv_opengles_index_buffer_init(const unsigned int * data, unsigned int count); +static void lv_opengles_index_buffer_deinit(void); +static unsigned int lv_opengles_index_buffer_get_count(void); +static void lv_opengles_index_buffer_bind(void); +static void lv_opengles_index_buffer_unbind(void); +static unsigned int lv_opengles_shader_manager_init(void); +static lv_result_t lv_opengles_shader_init(void); +static void lv_opengles_shader_deinit(void); +static void lv_opengles_shader_bind(void); +static void lv_opengles_shader_unbind(void); +static int lv_opengles_shader_get_uniform_location(const char * name); +static void lv_opengles_shader_set_uniform1i(const char * name, int value); +static void lv_opengles_shader_set_uniformmatrix3fv(const char * name, int count, const float * values); +static void lv_opengles_shader_set_uniform1f(const char * name, float value); +static void lv_opengles_shader_set_uniform3f(const char * name, float value_0, float value_1, float value_2); +static void lv_opengles_render_draw(void); +static float lv_opengles_map_float(float x, float min_in, float max_in, float min_out, float max_out); +static void populate_vertex_buffer(float vertex_buffer[LV_OPENGLES_VERTEX_BUFFER_LEN], + lv_display_rotation_t rotation, bool * h_flip, bool * v_flip, + float clip_x1, float clip_y1, float clip_x2, float clip_y2); + +/*********************** + * GLOBAL PROTOTYPES + ***********************/ + +/********************** + * STATIC VARIABLES + **********************/ +static bool is_init; + +static lv_opengl_shader_manager_t shader_manager; + +static unsigned int vertex_buffer_id = 0; + +static unsigned int vertex_array_id = 0; + +static unsigned int index_buffer_id = 0; +static unsigned int index_buffer_count = 0; + +static unsigned int shader_id; + +static const char * shader_names[] = { "u_Texture", "u_ColorDepth", "u_VertexTransform", "u_Opa", "u_IsFill", "u_FillColor", "u_Hue", "u_Saturation", "u_Value" }; +static int shader_location[] = { 0, 0, 0, 0, 0, 0, 0, 0, 0 }; + +/********************** + * MACROS + **********************/ + +/********************** + * GLOBAL FUNCTIONS + **********************/ + +void lv_opengles_init(void) +{ + if(is_init) return; + + lv_opengles_enable_blending(); + + unsigned int indices[] = { + 0, 1, 2, + 2, 3, 0 + }; + + lv_opengles_vertex_buffer_init(NULL, sizeof(float) * LV_OPENGLES_VERTEX_BUFFER_LEN); + + lv_opengles_vertex_array_init(); + lv_opengles_vertex_array_add_buffer(); + + lv_opengles_index_buffer_init(indices, 6); + + lv_result_t res = lv_opengles_shader_init(); + LV_ASSERT_MSG(res == LV_RESULT_OK, "Failed to initialize shaders"); + + lv_opengles_shader_bind(); + + /* unbind everything */ + lv_opengles_vertex_array_unbind(); + lv_opengles_vertex_buffer_unbind(); + lv_opengles_index_buffer_unbind(); + lv_opengles_shader_unbind(); + + is_init = true; +} + +void lv_opengles_deinit(void) +{ + if(!is_init) return; + + lv_opengles_shader_deinit(); + lv_opengles_index_buffer_deinit(); + lv_opengles_vertex_buffer_deinit(); + lv_opengles_vertex_array_deinit(); + + is_init = false; +} + +void lv_opengles_render_texture(unsigned int texture, const lv_area_t * texture_area, lv_opa_t opa, int32_t disp_w, + int32_t disp_h, const lv_area_t * texture_clip_area, bool h_flip, bool v_flip) +{ + LV_PROFILER_DRAW_BEGIN; + lv_opengles_render_internal(texture, texture_area, opa, disp_w, disp_h, texture_clip_area, h_flip, v_flip, + lv_color_black()); + LV_PROFILER_DRAW_END; +} + +void lv_opengles_render_fill(lv_color_t color, const lv_area_t * area, lv_opa_t opa, int32_t disp_w, int32_t disp_h) +{ + LV_PROFILER_DRAW_BEGIN; + lv_opengles_render_internal(0, area, opa, disp_w, disp_h, area, false, false, color); + LV_PROFILER_DRAW_END; +} + +void lv_opengles_render_display_texture(lv_display_t * display, bool h_flip, bool v_flip) +{ + LV_PROFILER_DRAW_BEGIN; + unsigned int texture = *(unsigned int *)lv_display_get_driver_data(display); + GL_CALL(glActiveTexture(GL_TEXTURE0)); + GL_CALL(glBindTexture(GL_TEXTURE_2D, texture)); + + lv_display_rotation_t rotation = lv_display_get_rotation(display); + + float vert_buffer[LV_OPENGLES_VERTEX_BUFFER_LEN]; + populate_vertex_buffer(vert_buffer, rotation, &h_flip, &v_flip, 0.f, 0.f, 1.f, 1.f); + lv_opengles_vertex_buffer_init(vert_buffer, sizeof(vert_buffer)); + + float hor_scale = 1.0f; + float ver_scale = 1.0f; + float hor_translate = 0.0f; + float ver_translate = 0.0f; + hor_scale = h_flip ? -hor_scale : hor_scale; + ver_scale = v_flip ? ver_scale : -ver_scale; + + const float transposed_matrix[9] = { + hor_scale, 0.0f, 0.0f, + 0.0f, ver_scale, 0.0f, + hor_translate, ver_translate, 1.0f + }; + + lv_opengles_shader_bind(); + lv_opengles_shader_set_uniform1f("u_ColorDepth", LV_COLOR_DEPTH); + lv_opengles_shader_set_uniform1i("u_Texture", 0); + lv_opengles_shader_set_uniformmatrix3fv("u_VertexTransform", 1, transposed_matrix); + lv_opengles_shader_set_uniform1f("u_Opa", 1); + lv_opengles_shader_set_uniform1i("u_IsFill", 0); + lv_opengles_shader_set_uniform3f("u_FillColor", 1.0f, 1.0f, 1.0f); + + lv_opengles_render_draw(); + LV_PROFILER_DRAW_END; +} + +void lv_opengles_render_clear(void) +{ + LV_PROFILER_DRAW_BEGIN; + GL_CALL(glClear(GL_COLOR_BUFFER_BIT)); + LV_PROFILER_DRAW_END; +} + +void lv_opengles_viewport(int32_t x, int32_t y, int32_t w, int32_t h) +{ + LV_PROFILER_DRAW_BEGIN; + GL_CALL(glViewport(x, y, w, h)); + LV_PROFILER_DRAW_END; +} + +/********************** + * STATIC FUNCTIONS + **********************/ + +static void lv_opengles_render_internal(unsigned int texture, const lv_area_t * texture_area, lv_opa_t opa, + int32_t disp_w, int32_t disp_h, const lv_area_t * texture_clip_area, bool h_flip, bool v_flip, lv_color_t fill_color) +{ + LV_PROFILER_DRAW_BEGIN; + lv_area_t intersection; + if(!lv_area_intersect(&intersection, texture_area, texture_clip_area)) { + LV_PROFILER_DRAW_END; + return; + } + + GL_CALL(glActiveTexture(GL_TEXTURE0)); + GL_CALL(glBindTexture(GL_TEXTURE_2D, texture)); + + float tex_w = (float)lv_area_get_width(&intersection); + float tex_h = (float)lv_area_get_height(&intersection); + + float hor_scale = tex_w / (float)disp_w; + float ver_scale = tex_h / (float)disp_h; + float hor_translate = (float)intersection.x1 / (float)disp_w * 2.0f - (1.0f - hor_scale); + float ver_translate = -((float)intersection.y1 / (float)disp_h * 2.0f - (1.0f - ver_scale)); + hor_scale = h_flip ? -hor_scale : hor_scale; + ver_scale = v_flip ? ver_scale : -ver_scale; + + if(texture != 0) { + float clip_x1 = h_flip ? lv_opengles_map_float(texture_clip_area->x2, texture_area->x2, texture_area->x1, 0.f, 1.f) + : lv_opengles_map_float(texture_clip_area->x1, texture_area->x1, texture_area->x2, 0.f, 1.f); + float clip_x2 = h_flip ? lv_opengles_map_float(texture_clip_area->x1, texture_area->x2, texture_area->x1, 0.f, 1.f) + : lv_opengles_map_float(texture_clip_area->x2, texture_area->x1, texture_area->x2, 0.f, 1.f); + float clip_y1 = v_flip ? lv_opengles_map_float(texture_clip_area->y2, texture_area->y2, texture_area->y1, 0.f, 1.f) + : lv_opengles_map_float(texture_clip_area->y1, texture_area->y1, texture_area->y2, 0.f, 1.f); + float clip_y2 = v_flip ? lv_opengles_map_float(texture_clip_area->y1, texture_area->y2, texture_area->y1, 0.f, 1.f) + : lv_opengles_map_float(texture_clip_area->y2, texture_area->y1, texture_area->y2, 0.f, 1.f); + + float positions[LV_OPENGLES_VERTEX_BUFFER_LEN] = { + -1.f, 1.0f, clip_x1, clip_y2, + 1.0f, 1.0f, clip_x2, clip_y2, + 1.0f, -1.0f, clip_x2, clip_y1, + -1.f, -1.0f, clip_x1, clip_y1 + }; + lv_opengles_vertex_buffer_init(positions, sizeof(positions)); + } + + const float transposed_matrix[9] = { + hor_scale, 0.0f, 0.0f, + 0.0f, ver_scale, 0.0f, + hor_translate, ver_translate, 1.0f + }; + + lv_opengles_shader_bind(); + lv_opengles_shader_set_uniform1f("u_ColorDepth", LV_COLOR_DEPTH); + lv_opengles_shader_set_uniform1i("u_Texture", 0); + lv_opengles_shader_set_uniformmatrix3fv("u_VertexTransform", 1, transposed_matrix); + lv_opengles_shader_set_uniform1f("u_Opa", (float)opa / (float)LV_OPA_100); + lv_opengles_shader_set_uniform1i("u_IsFill", texture == 0); + lv_opengles_shader_set_uniform3f("u_FillColor", (float)fill_color.red / 255.0f, (float)fill_color.green / 255.0f, + (float)fill_color.blue / 255.0f); + lv_opengles_render_draw(); + LV_PROFILER_DRAW_END; +} + +static void lv_opengles_enable_blending(void) +{ + GL_CALL(glEnable(GL_BLEND)); + GL_CALL(glBlendFunc(GL_ONE, GL_ONE_MINUS_SRC_ALPHA)); +} + +static void lv_opengles_vertex_buffer_init(const void * data, unsigned int size) +{ + if(vertex_buffer_id == 0) GL_CALL(glGenBuffers(1, &vertex_buffer_id)); + GL_CALL(glBindBuffer(GL_ARRAY_BUFFER, vertex_buffer_id)); + GL_CALL(glBufferData(GL_ARRAY_BUFFER, size, data, GL_DYNAMIC_DRAW)); +} + +static void lv_opengles_vertex_buffer_deinit(void) +{ + if(vertex_buffer_id == 0) return; + GL_CALL(glDeleteBuffers(1, &vertex_buffer_id)); + vertex_buffer_id = 0; +} + +static void lv_opengles_vertex_buffer_bind(void) +{ + GL_CALL(glBindBuffer(GL_ARRAY_BUFFER, vertex_buffer_id)); +} + +static void lv_opengles_vertex_buffer_unbind(void) +{ + GL_CALL(glBindBuffer(GL_ARRAY_BUFFER, 0)); +} + +static void lv_opengles_vertex_array_init(void) +{ + if(vertex_array_id == 0) GL_CALL(glGenVertexArrays(1, &vertex_array_id)); +} + +static void lv_opengles_vertex_array_deinit(void) +{ + if(vertex_array_id == 0) return; + GL_CALL(glDeleteVertexArrays(1, &vertex_array_id)); + vertex_array_id = 0; +} + +static void lv_opengles_vertex_array_bind(void) +{ + GL_CALL(glBindVertexArray(vertex_array_id)); +} + +static void lv_opengles_vertex_array_unbind(void) +{ + GL_CALL(glBindVertexArray(0)); +} + +static void lv_opengles_vertex_array_add_buffer(void) +{ + lv_opengles_vertex_buffer_bind(); + intptr_t offset = 0; + + for(unsigned int i = 0; i < 2; i++) { + lv_opengles_vertex_array_bind(); + GL_CALL(glEnableVertexAttribArray(i)); + GL_CALL(glVertexAttribPointer(i, 2, GL_FLOAT, GL_FALSE, 16, (const void *)offset)); + offset += 2 * 4; + } +} + +static void lv_opengles_index_buffer_init(const unsigned int * data, unsigned int count) +{ + index_buffer_count = count; + if(index_buffer_id == 0) GL_CALL(glGenBuffers(1, &index_buffer_id)); + + GL_CALL(glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, index_buffer_id)); + + GL_CALL(glBufferData(GL_ELEMENT_ARRAY_BUFFER, count * sizeof(GLuint), data, GL_STATIC_DRAW)); +} + +static void lv_opengles_index_buffer_deinit(void) +{ + if(index_buffer_id == 0) return; + GL_CALL(glDeleteBuffers(1, &index_buffer_id)); + index_buffer_id = 0; +} + +static unsigned int lv_opengles_index_buffer_get_count(void) +{ + return index_buffer_count; +} + +static void lv_opengles_index_buffer_bind(void) +{ + GL_CALL(glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, index_buffer_id)); +} + +static void lv_opengles_index_buffer_unbind(void) +{ + GL_CALL(glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0)); +} + +static unsigned int lv_opengles_shader_manager_init(void) +{ + lv_opengl_shader_program_t * program = NULL; + for(lv_opengl_glsl_version version = LV_OPENGL_GLSL_VERSION_300ES; version < LV_OPENGL_GLSL_VERSION_LAST; ++version) { + LV_LOG_INFO("Trying GLSL version %s", lv_opengles_glsl_version_to_string(version)); + lv_opengl_shader_portions_t portions; + lv_opengles_shader_get_source(&portions, version); + char * vertex_shader = lv_opengles_shader_get_vertex(version); + char * frag_shader = lv_opengles_shader_get_fragment(version); + lv_opengl_shader_manager_init(&shader_manager, portions.all, portions.count, vertex_shader, frag_shader); + lv_free(vertex_shader); + lv_free(frag_shader); + + uint32_t frag_shader_hash; + uint32_t vert_shader_hash; + + lv_result_t res = lv_opengl_shader_manager_select_shader(&shader_manager, "__MAIN__.frag", NULL, 0, version, + &frag_shader_hash); + if(res != LV_RESULT_OK) { + lv_opengl_shader_manager_deinit(&shader_manager); + continue; + } + res = lv_opengl_shader_manager_select_shader(&shader_manager, "__MAIN__.vert", NULL, 0, version, &vert_shader_hash); + if(res != LV_RESULT_OK) { + lv_opengl_shader_manager_deinit(&shader_manager); + continue; + } + program = lv_opengl_shader_manager_get_program(&shader_manager, frag_shader_hash, vert_shader_hash); + if(!program) { + lv_opengl_shader_manager_deinit(&shader_manager); + continue; + } + LV_LOG_INFO("Compiled shaders with version %s", lv_opengles_glsl_version_to_string(version)); + break; + } + + if(!program) { + LV_LOG_ERROR("Failed to initialize shaders"); + return 0; + } + return lv_opengl_shader_program_get_id(program); +} + +static lv_result_t lv_opengles_shader_init(void) +{ + if(shader_id != 0) { + return LV_RESULT_OK; + } + shader_id = lv_opengles_shader_manager_init(); + return shader_id != 0 ? LV_RESULT_OK : LV_RESULT_INVALID; +} + +static void lv_opengles_shader_deinit(void) +{ + if(shader_id == 0) return; + /* The program is part of the manager and as such will be destroyed inside */ + lv_opengl_shader_manager_deinit(&shader_manager); + shader_id = 0; +} + +static void lv_opengles_shader_bind(void) +{ + GL_CALL(glUseProgram(shader_id)); +} + +static void lv_opengles_shader_unbind(void) +{ + GL_CALL(glUseProgram(0)); +} + +static int lv_opengles_shader_get_uniform_location(const char * name) +{ + int id = -1; + for(size_t i = 0; i < sizeof(shader_location) / sizeof(int); i++) { + if(lv_strcmp(shader_names[i], name) == 0) { + id = i; + } + } + + LV_ASSERT_FORMAT_MSG(id > -1, "Uniform location doesn't exist for '%s'. Check `shader_location` array", name); + + if(shader_location[id] != 0) { + return shader_location[id]; + } + + int location; + GL_CALL(location = glGetUniformLocation(shader_id, name)); + if(location == -1) + LV_LOG_WARN("Warning: uniform '%s' doesn't exist!", name); + + shader_location[id] = location; + return location; +} + +static void lv_opengles_shader_set_uniform1i(const char * name, int value) +{ + LV_PROFILER_DRAW_BEGIN; + GL_CALL(glUniform1i(lv_opengles_shader_get_uniform_location(name), value)); + LV_PROFILER_DRAW_END; +} + +static void lv_opengles_shader_set_uniformmatrix3fv(const char * name, int count, const float * values) +{ + LV_PROFILER_DRAW_BEGIN; + /* + * GLES2.0 doesn't support transposing the matrix via glUniformMatrix3fv so this is the transposed matrix + * https://registry.khronos.org/OpenGL/specs/es/2.0/es_full_spec_2.0.pdf page 47 + */ + GL_CALL(glUniformMatrix3fv(lv_opengles_shader_get_uniform_location(name), count, GL_FALSE, values)); + LV_PROFILER_DRAW_END; +} + +static void lv_opengles_shader_set_uniform1f(const char * name, float value) +{ + LV_PROFILER_DRAW_BEGIN; + GL_CALL(glUniform1f(lv_opengles_shader_get_uniform_location(name), value)); + LV_PROFILER_DRAW_END; +} + +static void lv_opengles_shader_set_uniform3f(const char * name, float value_0, float value_1, float value_2) +{ + LV_PROFILER_DRAW_BEGIN; + GL_CALL(glUniform3f(lv_opengles_shader_get_uniform_location(name), value_0, value_1, value_2)); + LV_PROFILER_DRAW_END; +} + +static void lv_opengles_render_draw(void) +{ + LV_PROFILER_DRAW_BEGIN; + lv_opengles_shader_bind(); + lv_opengles_vertex_array_bind(); + lv_opengles_index_buffer_bind(); + unsigned int count = lv_opengles_index_buffer_get_count(); + GL_CALL(glDrawElements(GL_TRIANGLES, count, GL_UNSIGNED_INT, NULL)); + LV_PROFILER_DRAW_END; +} + +/** + * Copied from `lv_map` in lv_math.h to operate on floats + */ +static float lv_opengles_map_float(float x, float min_in, float max_in, float min_out, float max_out) +{ + if(max_in >= min_in && x >= max_in) return max_out; + if(max_in >= min_in && x <= min_in) return min_out; + + if(max_in <= min_in && x <= max_in) return max_out; + if(max_in <= min_in && x >= min_in) return min_out; + + /** + * The equation should be: + * ((x - min_in) * delta_out) / delta in) + min_out + * To avoid rounding error reorder the operations: + * (x - min_in) * (delta_out / delta_min) + min_out + */ + + float delta_in = max_in - min_in; + float delta_out = max_out - min_out; + + return ((x - min_in) * delta_out) / delta_in + min_out; +} + +static void populate_vertex_buffer(float vertex_buffer[LV_OPENGLES_VERTEX_BUFFER_LEN], + lv_display_rotation_t rotation, bool * h_flip, bool * v_flip, float clip_x1, float clip_y1, float clip_x2, + float clip_y2) +{ +#if !LV_USE_DRAW_OPENGLES + LV_UNUSED(h_flip); + LV_UNUSED(v_flip); +#endif + switch(rotation) { + case LV_DISPLAY_ROTATION_0: + vertex_buffer[0] = -1.f; + vertex_buffer[1] = 1.0f; + vertex_buffer[2] = clip_x1; + vertex_buffer[3] = clip_y2; + vertex_buffer[4] = 1.0f; + vertex_buffer[5] = 1.0f; + vertex_buffer[6] = clip_x2; + vertex_buffer[7] = clip_y2; + vertex_buffer[8] = 1.0f; + vertex_buffer[9] = -1.0f; + vertex_buffer[10] = clip_x2; + vertex_buffer[11] = clip_y1; + vertex_buffer[12] = -1.f; + vertex_buffer[13] = -1.0f; + vertex_buffer[14] = clip_x1; + vertex_buffer[15] = clip_y1; + break; + + case LV_DISPLAY_ROTATION_270: +#if LV_USE_DRAW_OPENGLES + *h_flip = !*h_flip; + *v_flip = !*v_flip; +#endif + vertex_buffer[0] = 1.0f; + vertex_buffer[1] = 1.0f; + vertex_buffer[2] = clip_x1; + vertex_buffer[3] = clip_y2; + vertex_buffer[4] = 1.0f; + vertex_buffer[5] = -1.0f; + vertex_buffer[6] = clip_x2; + vertex_buffer[7] = clip_y2; + vertex_buffer[8] = -1.f; + vertex_buffer[9] = -1.0f; + vertex_buffer[10] = clip_x2; + vertex_buffer[11] = clip_y1; + vertex_buffer[12] = -1.f; + vertex_buffer[13] = 1.0f; + vertex_buffer[14] = clip_x1; + vertex_buffer[15] = clip_y1; + break; + + case LV_DISPLAY_ROTATION_180: + vertex_buffer[0] = 1.0f; + vertex_buffer[1] = -1.0f; + vertex_buffer[2] = clip_x1; + vertex_buffer[3] = clip_y2; + vertex_buffer[4] = -1.f; + vertex_buffer[5] = -1.0f; + vertex_buffer[6] = clip_x2; + vertex_buffer[7] = clip_y2; + vertex_buffer[8] = -1.f; + vertex_buffer[9] = 1.0f; + vertex_buffer[10] = clip_x2; + vertex_buffer[11] = clip_y1; + vertex_buffer[12] = 1.0f; + vertex_buffer[13] = 1.0f; + vertex_buffer[14] = clip_x1; + vertex_buffer[15] = clip_y1; + break; + case LV_DISPLAY_ROTATION_90: +#if LV_USE_DRAW_OPENGLES + *h_flip = !*h_flip; + *v_flip = !*v_flip; +#endif + vertex_buffer[0] = -1.f; + vertex_buffer[1] = -1.0f; + vertex_buffer[2] = clip_x1; + vertex_buffer[3] = clip_y2; + vertex_buffer[4] = -1.f; + vertex_buffer[5] = 1.0f; + vertex_buffer[6] = clip_x2; + vertex_buffer[7] = clip_y2; + vertex_buffer[8] = 1.0f; + vertex_buffer[9] = 1.0f; + vertex_buffer[10] = clip_x2; + vertex_buffer[11] = clip_y1; + vertex_buffer[12] = 1.0f; + vertex_buffer[13] = -1.0f; + vertex_buffer[14] = clip_x1; + vertex_buffer[15] = clip_y1; + break; + } +} +#endif /* LV_USE_OPENGLES */ diff --git a/src/drivers/glfw/lv_opengles_driver.h b/src/drivers/opengles/lv_opengles_driver.h similarity index 77% rename from src/drivers/glfw/lv_opengles_driver.h rename to src/drivers/opengles/lv_opengles_driver.h index 34bda861d9..67dcf5d270 100644 --- a/src/drivers/glfw/lv_opengles_driver.h +++ b/src/drivers/opengles/lv_opengles_driver.h @@ -34,13 +34,13 @@ extern "C" { /** * Initialize OpenGL - * @note it is not necessary to call this if you use `lv_glfw_window_create` + * @note it is not necessary to call this if you use `lv_opengles_glfw_window_create` */ void lv_opengles_init(void); /** * Deinitialize OpenGL - * @note it is not necessary to call this if you use `lv_glfw_window_create` + * @note it is not necessary to call this if you use `lv_opengles_glfw_window_create` */ void lv_opengles_deinit(void); @@ -51,9 +51,19 @@ void lv_opengles_deinit(void); * @param opa opacity to blend the texture with existing contents * @param disp_w width of the window/framebuffer being rendered to * @param disp_h height of the window/framebuffer being rendered to + * @param h_flip horizontal flip + * @param v_flip vertical flip */ void lv_opengles_render_texture(unsigned int texture, const lv_area_t * texture_area, lv_opa_t opa, int32_t disp_w, - int32_t disp_h, const lv_area_t * texture_clip_area, bool flip); + int32_t disp_h, const lv_area_t * texture_clip_area, bool h_flip, bool v_flip); + +/** + * Render a display texture - Supports rotation + * @param display LVGL Texture display. Created with the `lv_opengles_texture` module + * @param h_flip horizontal flip + * @param v_flip vertical flip + */ +void lv_opengles_render_display_texture(lv_display_t * display, bool h_flip, bool v_flip); /** * Render a fill diff --git a/src/drivers/opengles/lv_opengles_egl.c b/src/drivers/opengles/lv_opengles_egl.c new file mode 100644 index 0000000000..05cd3d265e --- /dev/null +++ b/src/drivers/opengles/lv_opengles_egl.c @@ -0,0 +1,558 @@ +/** + * @file lv_opengles_egl.c + * + */ + +/********************* + * INCLUDES + *********************/ +#include "lv_opengles_egl.h" +#include + +#if LV_USE_EGL + +#include + +#include +#include "lv_opengles_debug.h" + +#include "glad/include/glad/egl.h" +#include "../../misc/lv_assert.h" +#include "../../misc/lv_log.h" +#include "../../misc/lv_types.h" +#include "../../misc/lv_types.h" +#include "../../stdlib/lv_mem.h" +#include "lv_opengles_private.h" +#include "lv_opengles_egl_private.h" +#include "lv_opengles_driver.h" + +/********************* +* DEFINES +*********************/ + +/********************** +* TYPEDEFS +**********************/ + +/********************** +* STATIC PROTOTYPES +**********************/ + +static lv_result_t load_egl(lv_opengles_egl_t * ctx); +static EGLDisplay create_egl_display(lv_opengles_egl_t * ctx); +static EGLSurface create_egl_surface(lv_opengles_egl_t * ctx); +static EGLContext create_egl_context(lv_opengles_egl_t * ctx); +static EGLConfig create_egl_config(lv_opengles_egl_t * ctx); +static lv_result_t lv_egl_config_from_egl_config(lv_opengles_egl_t * ctx, lv_egl_config_t * lv_egl_config, + EGLConfig egl_config); +static void * create_native_window(lv_opengles_egl_t * ctx); +static lv_result_t get_native_config(lv_opengles_egl_t * ctx, EGLint * native_id, uint64_t ** mods, size_t * count); +static GLADapiproc glad_egl_load_cb(void * userdata, const char * name); + +/********************** +* STATIC VARIABLES +**********************/ + +/********************** +* MACROS +**********************/ + +/********************** +* GLOBAL FUNCTIONS +**********************/ + +lv_opengles_egl_t * lv_opengles_egl_context_create(const lv_egl_interface_t * interface) +{ + lv_opengles_egl_t * ctx = lv_zalloc(sizeof(*ctx)); + LV_ASSERT_MALLOC(ctx); + if(!ctx) { + LV_LOG_ERROR("Failed to create egl context"); + return NULL; + } + ctx->interface = *interface; + ctx->vsync = false; + + lv_result_t res = load_egl(ctx); + if(res != LV_RESULT_OK) { + LV_LOG_ERROR("Failed to load egl "); + lv_free(ctx); + return NULL; + } + lv_opengles_init(); + return ctx; +} + +void lv_opengles_egl_context_destroy(lv_opengles_egl_t * ctx) +{ + if(ctx->egl_display) { + eglMakeCurrent(ctx->egl_display, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT); + if(ctx->egl_context) { + eglDestroyContext(ctx->egl_display, ctx->egl_context); + } + ctx->egl_context = EGL_NO_CONTEXT; + } + if(ctx->egl_surface && ctx->egl_display) { + eglDestroySurface(ctx->egl_display, ctx->egl_surface); + ctx->egl_surface = EGL_NO_SURFACE; + } + + if(ctx->egl_lib_handle) { + dlclose(ctx->egl_lib_handle); + } + if(ctx->opengl_lib_handle) { + dlclose(ctx->opengl_lib_handle); + } + + if(ctx->native_window && ctx->interface.destroy_window_cb) { + ctx->interface.destroy_window_cb(ctx->interface.driver_data, (void *)ctx->native_window); + ctx->native_window = 0; + } + if(ctx->egl_display) { + eglTerminate(ctx->egl_display); + ctx->egl_display = EGL_NO_DISPLAY; + } + ctx->egl_config = NULL; + lv_free(ctx); +} + +void lv_opengles_egl_clear(lv_opengles_egl_t * ctx) +{ + LV_UNUSED(ctx); + GL_CALL(glClearColor(0.f, 0.f, 0.f, 1.0f)); + GL_CALL(glDepthRangef(-1.0, 1.0)); + GL_CALL(glDepthFunc(GL_ALWAYS)); + GL_CALL(glClearDepthf(1.0f)); + GL_CALL(glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT)); +} + +void lv_opengles_egl_update(lv_opengles_egl_t * ctx) +{ + eglSwapBuffers(ctx->egl_display, ctx->egl_surface); + ctx->interface.flip_cb(ctx->interface.driver_data, ctx->vsync); +} + + +/********************** +* STATIC FUNCTIONS +**********************/ + +static void * load_lib(const char ** libs, size_t count) +{ + const int mode = RTLD_NOW | RTLD_NODELETE; + for(size_t i = 0; i < count; ++i) { + + void * handle = dlopen(libs[i], mode); + if(handle) { + return handle; + } + } + return NULL; +} +static void * load_egl_lib(void) +{ + const char * egl_libs[] = {"libEGL.so", "libEGL.so.1"}; + return load_lib(egl_libs, sizeof(egl_libs) / sizeof(egl_libs[0])); +} +static void * load_gl_lib(void) +{ + const char * gl_libs[] = {"libGLESv2.so", "libGLESv2.so.2"}; + return load_lib(gl_libs, sizeof(gl_libs) / sizeof(gl_libs[0])); +} + +static lv_result_t load_egl(lv_opengles_egl_t * ctx) +{ + ctx->egl_lib_handle = load_egl_lib(); + if(!ctx->egl_lib_handle) { + LV_LOG_ERROR("Failed to load egl shared lib: %s", dlerror()); + goto err; + } + + ctx->egl_display = create_egl_display(ctx); + if(!ctx->egl_display) { + LV_LOG_ERROR("Failed to create egl display"); + goto egl_display_err; + } + + if(!gladLoadEGLUserPtr(ctx->egl_display, glad_egl_load_cb, ctx->egl_lib_handle)) { + LV_LOG_ERROR("Failed to load EGL entry points"); + goto load_egl_functions_err; + } + + if(eglBindAPI && !eglBindAPI(EGL_OPENGL_ES_API)) { + LV_LOG_ERROR("Failed to bind api"); + goto err; + } + + ctx->opengl_lib_handle = load_gl_lib(); + if(!ctx->opengl_lib_handle) { + LV_LOG_ERROR("Failed to load OpenGL library. %s", dlerror()); + goto opengl_lib_err; + } + + ctx->egl_config = create_egl_config(ctx); + if(!ctx->egl_config) { + LV_LOG_ERROR("Failed to create EGL config. Error code: %#x", eglGetError()); + goto egl_config_err; + } + + ctx->native_window = (EGLNativeWindowType)create_native_window(ctx); + if(!ctx->native_window) { + LV_LOG_ERROR("Failed to create native window"); + goto create_window_err; + + } + ctx->egl_surface = create_egl_surface(ctx); + if(!ctx->egl_surface) { + LV_LOG_ERROR("Failed to create EGL surface. Error code: %#x", eglGetError()); + goto egl_surface_err; + } + + ctx->egl_context = create_egl_context(ctx); + if(!ctx->egl_context) { + LV_LOG_ERROR("Failed to create EGL context. Error code: %#x", eglGetError()); + goto egl_context_err; + } + + if(!eglMakeCurrent(ctx->egl_display, ctx->egl_surface, ctx->egl_surface, ctx->egl_context)) { + LV_LOG_ERROR("Failed to set current egl context. Error code: %#x", eglGetError()); + goto egl_make_current_context_err; + } + + if(!eglSwapInterval(ctx->egl_display, 0)) { + LV_LOG_WARN("Can't set egl swap interval"); + } + + if(!gladLoadGLES2UserPtr(glad_egl_load_cb, ctx->opengl_lib_handle)) { + LV_LOG_ERROR("Failed to load load OpenGL entry points"); + goto load_opengl_functions_err; + } + + return LV_RESULT_OK; + +load_opengl_functions_err: + eglMakeCurrent(ctx->egl_display, NULL, NULL, NULL); + eglDestroyContext(ctx->egl_display, ctx->egl_context); +egl_make_current_context_err: + ctx->egl_context = NULL; +egl_context_err: + ctx->egl_surface = NULL; +egl_surface_err: + ctx->interface.destroy_window_cb(ctx->interface.driver_data, (void *)ctx->native_window); + ctx->native_window = 0; +create_window_err: + ctx->egl_config = NULL; +egl_config_err: + dlclose(ctx->opengl_lib_handle); + ctx->opengl_lib_handle = NULL; +opengl_lib_err: + ctx->egl_display = NULL; +load_egl_functions_err: +egl_display_err: + dlclose(ctx->egl_lib_handle); + ctx->egl_lib_handle = NULL; +err: + return LV_RESULT_INVALID; +} + +static EGLDisplay create_egl_display(lv_opengles_egl_t * ctx) +{ + union { + PFNEGLQUERYSTRINGPROC fn; + void * ptr; + } egl_query_string; + + union { + PFNEGLGETPROCADDRESSPROC fn; + void * ptr; + } egl_get_proc_address; + + union { + PFNEGLGETERRORPROC fn; + void * ptr; + } egl_get_error; + + union { + PFNEGLGETDISPLAYPROC fn; + void * ptr; + } egl_get_display; + + union { + PFNEGLINITIALIZEPROC fn; + void * ptr; + } egl_initialize; + + EGLDisplay display = NULL; + + egl_get_proc_address.ptr = dlsym(ctx->egl_lib_handle, "eglGetProcAddress"); + if(!egl_get_proc_address.ptr) { + LV_LOG_ERROR("Failed to load eglGetProcAddress"); + return NULL; + } + + egl_query_string.ptr = dlsym(ctx->egl_lib_handle, "eglQueryString"); + if(!egl_query_string.ptr) { + LV_LOG_ERROR("Failed to load eglQueryString"); + return NULL; + } + + egl_get_display.ptr = dlsym(ctx->egl_lib_handle, "eglGetDisplay"); + if(!egl_get_display.ptr) { + LV_LOG_ERROR("Failed to load eglGetDisplay"); + return NULL; + } + + egl_get_error.ptr = dlsym(ctx->egl_lib_handle, "eglGetError"); + if(!egl_get_error.ptr) { + LV_LOG_ERROR("Failed to load eglGetError"); + return NULL; + } + + egl_initialize.ptr = dlsym(ctx->egl_lib_handle, "eglInitialize"); + if(!egl_initialize.ptr) { + LV_LOG_ERROR("Failed to load eglInitialize"); + return NULL; + } + + char const * supported_extensions = egl_query_string.fn(EGL_NO_DISPLAY, EGL_EXTENSIONS); + + bool has_platform_display_ext_support = ctx->interface.egl_platform != 0 && supported_extensions && + strstr(supported_extensions, "EGL_EXT_platform_base"); + if(has_platform_display_ext_support) { + PFNEGLGETPLATFORMDISPLAYEXTPROC egl_get_platform_display = (PFNEGLGETPLATFORMDISPLAYEXTPROC) + egl_get_proc_address.fn("eglGetPlatformDisplayEXT"); + if(egl_get_platform_display) { + display = egl_get_platform_display(ctx->interface.egl_platform, (void *)ctx->interface.native_display, NULL); + } + if(!display) { + LV_LOG_WARN("Failed to get egl display from eglGetPlatformDisplay. Error code: %#x", egl_get_error.fn()); + } + } + + if(!display) { + LV_LOG_INFO("Falling back to eglGetDisplay()"); + display = egl_get_display.fn(ctx->interface.native_display); + } + + if(!display) { + LV_LOG_ERROR("Failed to get egl display from eglGetDisplay. Error code: %#x", egl_get_error.fn()); + return NULL; + } + + EGLint egl_major; + EGLint egl_minor; + if(!egl_initialize.fn(display, &egl_major, &egl_minor)) { + LV_LOG_ERROR("Failed to initialize egl. Error code: %#x", egl_get_error.fn()); + return NULL; + } + LV_LOG_INFO("Egl version %d.%d", egl_major, egl_minor); + + return display; +} + +static GLADapiproc glad_egl_load_cb(void * userdata, const char * name) +{ + union { + GLADapiproc fn; + void * ptr; + } result; + + if(eglGetProcAddress) { + GLADapiproc sym = (GLADapiproc)eglGetProcAddress(name); + if(sym) { + return sym; + } + } + result.ptr = dlsym(userdata, name); + return result.fn; +} + +static EGLConfig create_egl_config(lv_opengles_egl_t * ctx) +{ + const EGLint config_attribs[] = { + EGL_RENDERABLE_TYPE, + EGL_OPENGL_ES2_BIT, + EGL_NONE + }; + + EGLint num_configs = 0; + if(!eglChooseConfig(ctx->egl_display, config_attribs, 0, 0, &num_configs)) { + LV_LOG_ERROR("Failed to get number of configs: %d", eglGetError()); + return NULL; + } + + if(num_configs == 0) { + LV_LOG_ERROR("No valid configs"); + return NULL; + } + + EGLConfig * egl_configs = lv_malloc(num_configs * sizeof(*egl_configs)); + LV_ASSERT_MALLOC(egl_configs); + if(!egl_configs) { + LV_LOG_ERROR("Failed to allocate memory for possible configs"); + return NULL; + } + + if(!eglChooseConfig(ctx->egl_display, config_attribs, egl_configs, num_configs, &num_configs)) { + LV_LOG_ERROR("Failed to get configs: %d", eglGetError()); + return NULL; + } + + lv_egl_config_t * configs = lv_malloc(num_configs * sizeof(*configs)); + LV_ASSERT_MALLOC(configs); + if(!configs) { + LV_LOG_ERROR("Failed to allocate memory for configs"); + lv_free(egl_configs); + return NULL; + } + + size_t valid_config_count = 0; + for(size_t i = 0; i < (size_t)num_configs; ++i) { + lv_result_t err = lv_egl_config_from_egl_config(ctx, configs + i, egl_configs[i]); + if(err == LV_RESULT_OK) { + valid_config_count ++; + } + } + + if(valid_config_count == 0) { + LV_LOG_ERROR("Failed to parse available EGL configs"); + lv_free(egl_configs); + lv_free(configs); + return NULL; + } + + size_t config_id = ctx->interface.select_config(ctx->interface.driver_data, configs, valid_config_count); + + if(config_id >= (size_t)num_configs) { + LV_LOG_ERROR("Failed to find suitable EGL config"); + lv_free(egl_configs); + lv_free(configs); + return NULL; + } + EGLConfig config = egl_configs[config_id]; + lv_free(configs); + lv_free(egl_configs); + return config; +} + +static EGLSurface create_egl_surface(lv_opengles_egl_t * ctx) +{ + LV_ASSERT_NULL(ctx->egl_display); + LV_ASSERT_NULL(ctx->egl_config); + LV_ASSERT(ctx->native_window != 0); + return eglCreateWindowSurface(ctx->egl_display, ctx->egl_config, ctx->native_window, NULL); +} + +static EGLContext create_egl_context(lv_opengles_egl_t * ctx) +{ + static const EGLint context_attribs[] = { + EGL_CONTEXT_CLIENT_VERSION, 2, + EGL_NONE + }; + return eglCreateContext(ctx->egl_display, ctx->egl_config, + EGL_NO_CONTEXT, context_attribs); +} + +lv_color_format_t lv_opengles_egl_color_format_from_egl_config(const lv_egl_config_t * config) +{ + if(config->r_bits == 5 && config->g_bits == 6 && config->b_bits == 5) { + if(config->a_bits == 8) { + return LV_COLOR_FORMAT_RGB565A8; + } + else { + return LV_COLOR_FORMAT_RGB565; + } + } + if(config->r_bits == 8 && config->g_bits == 8 && config->b_bits == 8) { + if(config->a_bits == 8) { + return LV_COLOR_FORMAT_ARGB8888; + } + else { + + return LV_COLOR_FORMAT_RGB888; + } + } + LV_LOG_INFO("Unhandled color format (RGBA) (%d %d %d %d)", config->r_bits, config->g_bits, config->b_bits, + config->a_bits); + return LV_COLOR_FORMAT_UNKNOWN; +} + +static lv_result_t lv_egl_config_from_egl_config(lv_opengles_egl_t * ctx, lv_egl_config_t * lv_egl_config, + EGLConfig egl_config) +{ + int res = 1; + res &= eglGetConfigAttrib(ctx->egl_display, egl_config, EGL_CONFIG_ID, &lv_egl_config->id); + res &= eglGetConfigAttrib(ctx->egl_display, egl_config, EGL_RED_SIZE, &lv_egl_config->r_bits); + res &= eglGetConfigAttrib(ctx->egl_display, egl_config, EGL_GREEN_SIZE, &lv_egl_config->g_bits); + res &= eglGetConfigAttrib(ctx->egl_display, egl_config, EGL_BLUE_SIZE, &lv_egl_config->b_bits); + res &= eglGetConfigAttrib(ctx->egl_display, egl_config, EGL_ALPHA_SIZE, &lv_egl_config->a_bits); + res &= eglGetConfigAttrib(ctx->egl_display, egl_config, EGL_MAX_PBUFFER_WIDTH, &lv_egl_config->max_width); + res &= eglGetConfigAttrib(ctx->egl_display, egl_config, EGL_MAX_PBUFFER_HEIGHT, &lv_egl_config->max_height); + res &= eglGetConfigAttrib(ctx->egl_display, egl_config, EGL_BUFFER_SIZE, &lv_egl_config->buffer_size); + res &= eglGetConfigAttrib(ctx->egl_display, egl_config, EGL_DEPTH_SIZE, &lv_egl_config->depth); + res &= eglGetConfigAttrib(ctx->egl_display, egl_config, EGL_STENCIL_SIZE, &lv_egl_config->stencil); + res &= eglGetConfigAttrib(ctx->egl_display, egl_config, EGL_SAMPLES, &lv_egl_config->samples); + res &= eglGetConfigAttrib(ctx->egl_display, egl_config, EGL_SURFACE_TYPE, &lv_egl_config->surface_type); + + if(!res) { + LV_LOG_WARN("Failed to fetch egl config properties"); + return LV_RESULT_INVALID; + } + return LV_RESULT_OK; +} + +static void * create_native_window(lv_opengles_egl_t * ctx) +{ + EGLint native_config_id; + uint64_t * mods = NULL; + size_t mod_count = 0; + lv_result_t res = get_native_config(ctx, &native_config_id, &mods, &mod_count); + + if(res == LV_RESULT_INVALID) { + LV_LOG_ERROR("Failed to get native config"); + return NULL; + } + + lv_egl_native_window_properties_t properties = { .visual_id = native_config_id }; + + void * native_window = ctx->interface.create_window_cb(ctx->interface.driver_data, &properties); + if(!native_window) { + LV_LOG_ERROR("Faield to create window"); + lv_free(mods); + return NULL; + } + lv_free(mods); + return native_window; +} + +static lv_result_t get_native_config(lv_opengles_egl_t * ctx, EGLint * native_id, uint64_t ** mods, size_t * count) +{ + EGLint num_mods; + + if(!eglGetConfigAttrib(ctx->egl_display, ctx->egl_config, EGL_NATIVE_VISUAL_ID, native_id)) { + LV_LOG_ERROR("Failed to get native visual id for egl config"); + return LV_RESULT_INVALID; + } + return LV_RESULT_OK; + + if(!eglQueryDmaBufModifiersEXT || !eglQueryDmaBufModifiersEXT(ctx->egl_display, *native_id, 0, NULL, NULL, &num_mods)) { + LV_LOG_WARN("Failed to get native modifiers"); + return LV_RESULT_OK; + } + + if(num_mods <= 0) { + LV_LOG_INFO("No native modifiers"); + return LV_RESULT_OK; + } + + *mods = lv_malloc(num_mods * sizeof(*mods)); + LV_ASSERT_MALLOC(mods); + eglQueryDmaBufModifiersEXT(ctx->egl_display, *native_id, num_mods, *mods, NULL, &num_mods); + if(*mods[0] == 0) { + lv_free(mods); + return LV_RESULT_OK; + } + *count = (size_t) num_mods; + return LV_RESULT_OK; +} + +#endif /*LV_USE_EGL*/ diff --git a/src/drivers/opengles/lv_opengles_egl.h b/src/drivers/opengles/lv_opengles_egl.h new file mode 100644 index 0000000000..b32ade9152 --- /dev/null +++ b/src/drivers/opengles/lv_opengles_egl.h @@ -0,0 +1,56 @@ +/** + * @file lv_opengles_egl.h + * + */ + +#ifndef LV_OPENGLES_EGL_H +#define LV_OPENGLES_EGL_H + +#ifdef __cplusplus +extern "C" { +#endif + +/********************* + * INCLUDES + *********************/ +#include "../../lv_conf_internal.h" + +#if LV_USE_EGL + +#include "../../misc/lv_types.h" +#include "../../misc/lv_color.h" + + +/********************* + * DEFINES + *********************/ + +/********************** + * TYPEDEFS + **********************/ + +typedef struct _lv_opengles_egl lv_opengles_egl_t; +typedef struct _lv_egl_interface lv_egl_interface_t; +typedef struct _lv_egl_config lv_egl_config_t; + +/********************** + * GLOBAL PROTOTYPES + **********************/ + +lv_opengles_egl_t * lv_opengles_egl_context_create(const lv_egl_interface_t * interface); +lv_color_format_t lv_opengles_egl_color_format_from_egl_config(const lv_egl_config_t * config); + +void lv_opengles_egl_update(lv_opengles_egl_t * ctx); +void lv_opengles_egl_clear(lv_opengles_egl_t * ctx); +void lv_opengles_egl_context_destroy(lv_opengles_egl_t * ctx); + +/********************** + * MACROS + **********************/ + +#endif /*LV_USE_EGL*/ +#ifdef __cplusplus +} /*extern "C"*/ +#endif + +#endif /*LV_OPENGLES_EGL_H*/ diff --git a/src/drivers/opengles/lv_opengles_egl_private.h b/src/drivers/opengles/lv_opengles_egl_private.h new file mode 100644 index 0000000000..78969e399f --- /dev/null +++ b/src/drivers/opengles/lv_opengles_egl_private.h @@ -0,0 +1,102 @@ +/** + * @file lv_opengles_egl_private.h + * + */ + +#ifndef LV_OPENGLES_EGL_PRIVATE_H +#define LV_OPENGLES_EGL_PRIVATE_H + +#ifdef __cplusplus +extern "C" { +#endif + +/********************* + * INCLUDES + *********************/ +#include "../../lv_conf_internal.h" + +#if LV_USE_EGL + +#include "../../misc/lv_types.h" +#include "../../misc/lv_color.h" +#include "lv_opengles_private.h" +#include "lv_opengles_egl.h" + + +/********************* + * DEFINES + *********************/ + +/********************** + * TYPEDEFS + **********************/ + +struct _lv_egl_config { + EGLint id; + EGLint max_width; + EGLint max_height; + EGLint buffer_size; + EGLint depth; + EGLint stencil; + EGLint samples; + EGLint surface_type; + EGLint r_bits; + EGLint g_bits; + EGLint b_bits; + EGLint a_bits; +}; + +typedef struct { + EGLint visual_id; +} lv_egl_native_window_properties_t; + +typedef void * (*lv_egl_init_display_t)(void * driver_data, int32_t width, int32_t height); +typedef void * (*lv_egl_get_display_t)(void * driver_data); +typedef void * (*lv_create_window_t)(void * driver_data, const lv_egl_native_window_properties_t * props); +typedef void (*lv_destroy_window_t)(void * driver_data, void * native_window); + +typedef void (*lv_egl_set_visible_t)(void * driver_data, bool v); +typedef void (*lv_egl_flip_t)(void * driver_data, bool vsync); +typedef void (*lv_egl_native_state_deinit_t)(void ** driver_data); +typedef size_t (*lv_egl_select_config_t)(void * driver_data, const lv_egl_config_t * configs, + size_t config_count); + +struct _lv_egl_interface { + lv_egl_select_config_t select_config; + void * driver_data; + void * native_display; + uint16_t egl_platform; + lv_create_window_t create_window_cb; + lv_destroy_window_t destroy_window_cb; + lv_egl_flip_t flip_cb; +}; + + +struct _lv_opengles_egl { + EGLNativeWindowType native_window; + EGLDisplay egl_display; + EGLConfig egl_config; + EGLContext egl_context; + EGLSurface egl_surface; + void * egl_lib_handle; + void * opengl_lib_handle; + lv_egl_interface_t interface; + int32_t width; + int32_t height; + bool vsync; +}; + +/********************** + * GLOBAL PROTOTYPES + **********************/ + +/********************** + * MACROS + **********************/ + +#endif /*LV_USE_EGL*/ +#ifdef __cplusplus +} /*extern "C"*/ +#endif + +#endif /*LV_OPENGLES_EGL_PRIVATE_H*/ diff --git a/src/drivers/opengles/lv_opengles_glfw.c b/src/drivers/opengles/lv_opengles_glfw.c new file mode 100644 index 0000000000..4323cfbc57 --- /dev/null +++ b/src/drivers/opengles/lv_opengles_glfw.c @@ -0,0 +1,696 @@ +/** + * @file lv_opengles_glfw.c + * + */ + +/********************* + * INCLUDES + *********************/ + +#include "lv_opengles_glfw.h" +#if LV_USE_GLFW + +#include "lv_opengles_window.h" +#include "lv_opengles_driver.h" +#include "lv_opengles_texture.h" +#include "lv_opengles_private.h" +#include "lv_opengles_debug.h" + +#include "../../core/lv_refr.h" +#include "../../stdlib/lv_sprintf.h" +#include "../../stdlib/lv_string.h" +#include "../../core/lv_global.h" +#include "../../display/lv_display_private.h" +#include "../../indev/lv_indev.h" +#include "../../lv_init.h" +#include "../../misc/lv_area_private.h" + +#include + +/********************* + * DEFINES + *********************/ + +/********************** + * TYPEDEFS + **********************/ + +struct _lv_opengles_window_t { + GLFWwindow * window; + int32_t hor_res; + int32_t ver_res; + bool h_flip; + bool v_flip; + lv_ll_t textures; + lv_point_t mouse_last_point; + lv_indev_state_t mouse_last_state; + uint8_t use_indev : 1; + uint8_t closing : 1; +#if LV_USE_DRAW_OPENGLES + uint8_t direct_render_invalidated: 1; +#endif +}; + +struct _lv_opengles_window_texture_t { + lv_opengles_window_t * window; + unsigned int texture_id; /* 0 if it's a window display */ + lv_display_t * disp; /* non-NULL if it's a display texture or a window display */ + uint8_t * fb; /* non-NULL if it's a window display and !DRAW_OPENGLES */ + lv_area_t area; + lv_opa_t opa; + lv_indev_t * indev; + lv_point_t indev_last_point; + lv_indev_state_t indev_last_state; +}; + +/********************** + * STATIC PROTOTYPES + **********************/ +static void window_update_handler(lv_timer_t * t); +static uint32_t lv_glfw_tick_count_callback(void); +static lv_opengles_window_t * lv_glfw_get_lv_window_from_window(GLFWwindow * window); +static void glfw_error_cb(int error, const char * description); +static int lv_glfw_init(void); +static int lv_glew_init(void); +static void lv_glfw_timer_init(void); +static void lv_glfw_window_config(GLFWwindow * window, bool use_mouse_indev); +static void lv_glfw_window_quit(void); +static void window_close_callback(GLFWwindow * window); +static void key_callback(GLFWwindow * window, int key, int scancode, int action, int mods); +static void mouse_button_callback(GLFWwindow * window, int button, int action, int mods); +static void mouse_move_callback(GLFWwindow * window, double xpos, double ypos); +static void proc_mouse(lv_opengles_window_t * window); +static void indev_read_cb(lv_indev_t * indev, lv_indev_data_t * data); +static void framebuffer_size_callback(GLFWwindow * window, int width, int height); +static void window_display_delete_cb(lv_event_t * e); +static void window_display_flush_cb(lv_display_t * disp, const lv_area_t * area, uint8_t * px_map); +#if !LV_USE_DRAW_OPENGLES + static void ensure_init_window_display_texture(void); +#endif + +/********************** + * STATIC VARIABLES + **********************/ +static bool glfw_inited; +static bool glew_inited; +static lv_timer_t * update_handler_timer; +static lv_ll_t glfw_window_ll; +#if !LV_USE_DRAW_OPENGLES + static unsigned int window_display_texture; +#endif + +/********************** + * MACROS + **********************/ + +/********************** + * GLOBAL FUNCTIONS + **********************/ + +lv_opengles_window_t * lv_opengles_glfw_window_create_ex(int32_t hor_res, int32_t ver_res, bool use_mouse_indev, + bool h_flip, bool v_flip, const char * title) +{ + LV_ASSERT_NULL(title); + if(lv_glfw_init() != 0) { + LV_LOG_ERROR("Failed to init glfw"); + return NULL; + } + + lv_opengles_window_t * window = lv_ll_ins_tail(&glfw_window_ll); + LV_ASSERT_MALLOC(window); + if(window == NULL) return NULL; + if(window == NULL) { + LV_LOG_ERROR("Failed to create glfw window"); + return NULL; + } + lv_memzero(window, sizeof(*window)); + + /* Create window with graphics context */ + lv_opengles_window_t * existing_window = lv_ll_get_head(&glfw_window_ll); + window->window = glfwCreateWindow(hor_res, ver_res, title, NULL, + existing_window ? existing_window->window : NULL); + if(window->window == NULL) { + LV_LOG_ERROR("glfwCreateWindow fail"); + lv_ll_remove(&glfw_window_ll, window); + lv_free(window); + return NULL; + } + + glfwSetWindowTitle(window->window, title); + + window->h_flip = h_flip; + window->v_flip = v_flip; + window->hor_res = hor_res; + window->ver_res = ver_res; + + lv_ll_init(&window->textures, sizeof(lv_opengles_window_texture_t)); + window->use_indev = use_mouse_indev; +#if LV_USE_DRAW_OPENGLES + window->direct_render_invalidated = 1; +#endif + + glfwSetWindowUserPointer(window->window, window); + lv_glfw_timer_init(); + lv_glfw_window_config(window->window, use_mouse_indev); + lv_glew_init(); + glfwMakeContextCurrent(window->window); + lv_opengles_init(); + + return window; +} + +lv_opengles_window_t * lv_opengles_glfw_window_create(int32_t hor_res, int32_t ver_res, bool use_mouse_indev) +{ + return lv_opengles_glfw_window_create_ex(hor_res, ver_res, use_mouse_indev, false, false, "LVGL Simulator"); +} + +void lv_opengles_glfw_window_set_title(lv_opengles_window_t * window, const char * new_title) +{ + glfwSetWindowTitle(window->window, new_title); +} + +void lv_opengles_window_delete(lv_opengles_window_t * window) +{ + glfwDestroyWindow(window->window); + + lv_opengles_window_texture_t * texture; + while((texture = lv_ll_get_head(&window->textures))) { + if(texture->texture_id) { + lv_opengles_window_texture_remove(texture); + } + else { + lv_display_delete(texture->disp); + } + } + + lv_ll_remove(&glfw_window_ll, window); + lv_free(window); + + if(lv_ll_is_empty(&glfw_window_ll)) { + lv_glfw_window_quit(); +#if !LV_USE_DRAW_OPENGLES + if(window_display_texture) { + GL_CALL(glDeleteTextures(1, &window_display_texture)); + window_display_texture = 0; + } +#endif + } +} + +void * lv_opengles_glfw_window_get_glfw_window(lv_opengles_window_t * window) +{ + return (void *)(window->window); +} + +void lv_opengles_glfw_window_set_flip(lv_opengles_window_t * window, bool h_flip, bool v_flip) +{ + window->h_flip = h_flip; + window->v_flip = v_flip; +} + +lv_opengles_window_texture_t * lv_opengles_window_add_texture(lv_opengles_window_t * window, unsigned int texture_id, + int32_t w, int32_t h) +{ + lv_opengles_window_texture_t * texture = lv_ll_ins_tail(&window->textures); + LV_ASSERT_MALLOC(texture); + if(texture == NULL) return NULL; + lv_memzero(texture, sizeof(*texture)); + texture->window = window; + texture->texture_id = texture_id; + texture->disp = lv_opengles_texture_get_from_texture_id(texture_id); + lv_area_set(&texture->area, 0, 0, w - 1, h - 1); + texture->opa = LV_OPA_COVER; + + if(window->use_indev && texture->disp) { + lv_indev_t * indev = lv_indev_create(); + if(indev == NULL) { + lv_ll_remove(&window->textures, texture); + lv_free(texture); + return NULL; + } + texture->indev = indev; + lv_indev_set_type(indev, LV_INDEV_TYPE_POINTER); + lv_indev_set_read_cb(indev, indev_read_cb); + lv_indev_set_driver_data(indev, texture); + lv_indev_set_mode(indev, LV_INDEV_MODE_EVENT); + lv_indev_set_display(indev, texture->disp); + } + +#if LV_USE_DRAW_OPENGLES + window->direct_render_invalidated = 1; +#endif + + return texture; +} + +void lv_opengles_window_texture_remove(lv_opengles_window_texture_t * texture) +{ + if(texture->texture_id == 0) { + LV_LOG_WARN("window displays should be deleted with `lv_display_delete`"); + return; + } + if(texture->indev != NULL) { + lv_indev_delete(texture->indev); + } + +#if LV_USE_DRAW_OPENGLES + texture->window->direct_render_invalidated = 1; +#endif + + lv_ll_remove(&texture->window->textures, texture); + lv_free(texture); +} + +lv_display_t * lv_opengles_window_display_create(lv_opengles_window_t * window, int32_t w, int32_t h) +{ + lv_display_t * disp = lv_display_create(w, h); + if(disp == NULL) { + return NULL; + } + + lv_opengles_window_texture_t * dsc = lv_ll_ins_tail(&window->textures); + LV_ASSERT_MALLOC(dsc); + if(dsc == NULL) { + lv_display_delete(disp); + return NULL; + } + lv_memzero(dsc, sizeof(*dsc)); + dsc->window = window; + dsc->disp = disp; + lv_area_set(&dsc->area, 0, 0, w - 1, h - 1); + dsc->opa = LV_OPA_COVER; + +#if LV_USE_DRAW_OPENGLES + static size_t LV_ATTRIBUTE_MEM_ALIGN dummy_buf; + lv_display_set_buffers(disp, &dummy_buf, NULL, h * lv_draw_buf_width_to_stride(w, LV_COLOR_FORMAT_ARGB8888), + LV_DISPLAY_RENDER_MODE_FULL); +#else + uint32_t stride = lv_draw_buf_width_to_stride(w, lv_display_get_color_format(disp)); + uint32_t buf_size = stride * h; + dsc->fb = malloc(buf_size); + LV_ASSERT_MALLOC(dsc->fb); + if(dsc->fb == NULL) { + lv_display_delete(disp); + lv_ll_remove(&window->textures, dsc); + lv_free(dsc); + return NULL; + } + lv_display_set_buffers(disp, dsc->fb, NULL, buf_size, LV_DISPLAY_RENDER_MODE_DIRECT); +#endif + + if(window->use_indev) { + lv_indev_t * indev = lv_indev_create(); + if(indev == NULL) { + lv_display_delete(disp); + lv_ll_remove(&window->textures, dsc); + lv_free(dsc); + return NULL; + } + dsc->indev = indev; + lv_indev_set_type(indev, LV_INDEV_TYPE_POINTER); + lv_indev_set_read_cb(indev, indev_read_cb); + lv_indev_set_driver_data(indev, dsc); + lv_indev_set_mode(indev, LV_INDEV_MODE_EVENT); + lv_indev_set_display(indev, disp); + } + + lv_display_set_driver_data(disp, dsc); + lv_display_delete_refr_timer(disp); + lv_display_set_flush_cb(disp, window_display_flush_cb); + lv_display_add_event_cb(disp, window_display_delete_cb, LV_EVENT_DELETE, disp); + +#if LV_USE_DRAW_OPENGLES + window->direct_render_invalidated = 1; +#endif + + return disp; +} + +lv_opengles_window_texture_t * lv_opengles_window_display_get_window_texture(lv_display_t * window_display) +{ + return lv_display_get_driver_data(window_display); +} + +void lv_opengles_window_texture_set_x(lv_opengles_window_texture_t * texture, int32_t x) +{ + lv_area_set_pos(&texture->area, x, texture->area.y1); + +#if LV_USE_DRAW_OPENGLES + texture->window->direct_render_invalidated = 1; +#endif +} + +void lv_opengles_window_texture_set_y(lv_opengles_window_texture_t * texture, int32_t y) +{ + lv_area_set_pos(&texture->area, texture->area.x1, y); + +#if LV_USE_DRAW_OPENGLES + texture->window->direct_render_invalidated = 1; +#endif +} + +void lv_opengles_window_texture_set_opa(lv_opengles_window_texture_t * texture, lv_opa_t opa) +{ + texture->opa = opa; + +#if LV_USE_DRAW_OPENGLES + texture->window->direct_render_invalidated = 1; +#endif +} + +lv_indev_t * lv_opengles_window_texture_get_mouse_indev(lv_opengles_window_texture_t * texture) +{ + return texture->indev; +} + +/********************** + * STATIC FUNCTIONS + **********************/ + +static int lv_glfw_init(void) +{ + if(glfw_inited) { + return 0; + } + + glfwSetErrorCallback(glfw_error_cb); + + int ret = glfwInit(); + if(ret == 0) { + LV_LOG_ERROR("glfwInit fail."); + return 1; + } + + lv_ll_init(&glfw_window_ll, sizeof(lv_opengles_window_t)); + + glfw_inited = true; + return 0; +} + +static int lv_glew_init(void) +{ + if(glew_inited) { + return 0; + } + + GLenum ret = glewInit(); + if(ret != GLEW_OK) { + LV_LOG_ERROR("glewInit fail: %d.", ret); + return ret; + } + + LV_LOG_INFO("GL version: %s", glGetString(GL_VERSION)); + LV_LOG_INFO("GLSL version: %s", glGetString(GL_SHADING_LANGUAGE_VERSION)); + + glew_inited = true; + + return 0; +} + +static void lv_glfw_timer_init(void) +{ + if(update_handler_timer == NULL) { + update_handler_timer = lv_timer_create(window_update_handler, LV_DEF_REFR_PERIOD, NULL); + lv_tick_set_cb(lv_glfw_tick_count_callback); + } +} + +static void lv_glfw_window_config(GLFWwindow * window, bool use_mouse_indev) +{ + glfwMakeContextCurrent(window); + + glfwSwapInterval(1); + + glfwSetFramebufferSizeCallback(window, framebuffer_size_callback); + + if(use_mouse_indev) { + glfwSetMouseButtonCallback(window, mouse_button_callback); + glfwSetCursorPosCallback(window, mouse_move_callback); + } + + glfwSetKeyCallback(window, key_callback); + + glfwSetWindowCloseCallback(window, window_close_callback); +} + +static void lv_glfw_window_quit(void) +{ + lv_timer_delete(update_handler_timer); + update_handler_timer = NULL; + + glfwTerminate(); + glfw_inited = false; + + lv_deinit(); + + exit(0); +} + +static void window_update_handler(lv_timer_t * t) +{ + LV_UNUSED(t); + + lv_opengles_window_t * window; + + glfwPollEvents(); + + /* delete windows that are ready to close */ + window = lv_ll_get_head(&glfw_window_ll); + while(window) { + lv_opengles_window_t * window_to_delete = window->closing ? window : NULL; + window = lv_ll_get_next(&glfw_window_ll, window); + if(window_to_delete) { + glfwSetWindowShouldClose(window_to_delete->window, GLFW_TRUE); + lv_opengles_window_delete(window_to_delete); + } + } + + /* render each window */ + LV_LL_READ(&glfw_window_ll, window) { + glfwMakeContextCurrent(window->window); + lv_opengles_viewport(0, 0, window->hor_res, window->ver_res); + +#if LV_USE_DRAW_OPENGLES + lv_opengles_window_texture_t * textures_head; + bool window_display_direct_render = + !window->direct_render_invalidated + && (textures_head = lv_ll_get_head(&window->textures)) + && textures_head->texture_id == 0 /* it's a window display */ + && lv_ll_get_next(&window->textures, textures_head) == NULL /* it's the only one */ + && textures_head->opa == LV_OPA_COVER + && textures_head->area.x1 == 0 + && textures_head->area.y1 == 0 + && textures_head->area.x2 == window->hor_res - 1 + && textures_head->area.y2 == window->ver_res - 1 + ; + window->direct_render_invalidated = 0; + if(!window_display_direct_render) { + lv_opengles_render_clear(); + } +#else + lv_opengles_render_clear(); +#endif + + /* render each texture in the window */ + lv_opengles_window_texture_t * texture; + LV_LL_READ(&window->textures, texture) { + if(texture->texture_id == 0) { /* it's a window display */ +#if LV_USE_DRAW_OPENGLES + lv_display_set_render_mode(texture->disp, + window_display_direct_render ? LV_DISPLAY_RENDER_MODE_DIRECT : LV_DISPLAY_RENDER_MODE_FULL); +#endif + + lv_display_t * default_save = lv_display_get_default(); + lv_display_set_default(texture->disp); + lv_display_refr_timer(NULL); + lv_display_set_default(default_save); + +#if !LV_USE_DRAW_OPENGLES + ensure_init_window_display_texture(); + + GL_CALL(glBindTexture(GL_TEXTURE_2D, window_display_texture)); + + /* set the dimensions and format to complete the texture */ + /* Color depth: 8 (L8), 16 (RGB565), 24 (RGB888), 32 (XRGB8888) */ +#if LV_COLOR_DEPTH == 8 + GL_CALL(glTexImage2D(GL_TEXTURE_2D, 0, GL_R8, lv_area_get_width(&texture->area), lv_area_get_height(&texture->area), 0, + GL_RED, GL_UNSIGNED_BYTE, texture->fb)); +#elif LV_COLOR_DEPTH == 16 + GL_CALL(glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB565, lv_area_get_width(&texture->area), lv_area_get_height(&texture->area), + 0, GL_RGB, GL_UNSIGNED_SHORT_5_6_5, + texture->fb)); +#elif LV_COLOR_DEPTH == 24 + GL_CALL(glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, lv_area_get_width(&texture->area), lv_area_get_height(&texture->area), 0, + GL_BGR, GL_UNSIGNED_BYTE, texture->fb)); +#elif LV_COLOR_DEPTH == 32 + GL_CALL(glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, lv_area_get_width(&texture->area), lv_area_get_height(&texture->area), + 0, GL_BGRA, GL_UNSIGNED_BYTE, texture->fb)); +#else +#error("Unsupported color format") +#endif + + GL_CALL(glGenerateMipmap(GL_TEXTURE_2D)); + + GL_CALL(glBindTexture(GL_TEXTURE_2D, 0)); + + lv_opengles_render_texture(window_display_texture, &texture->area, texture->opa, window->hor_res, window->ver_res, + &texture->area, window->h_flip, window->v_flip); +#endif + } + else { + /* if the added texture is an LVGL opengles texture display, refresh it before rendering it */ + if(texture->disp != NULL) { +#if LV_USE_DRAW_OPENGLES + lv_display_t * default_save = lv_display_get_default(); + lv_display_set_default(texture->disp); + lv_display_refr_timer(NULL); + lv_display_set_default(default_save); +#else + lv_refr_now(texture->disp); +#endif + } + +#if LV_USE_DRAW_OPENGLES + lv_opengles_render_texture(texture->texture_id, &texture->area, texture->opa, window->hor_res, window->ver_res, + &texture->area, window->h_flip, texture->disp == NULL ? window->v_flip : !window->v_flip); +#else + lv_opengles_render_texture(texture->texture_id, &texture->area, texture->opa, window->hor_res, window->ver_res, + &texture->area, window->h_flip, window->v_flip); +#endif + } + } + + /* Swap front and back buffers */ + glfwSwapBuffers(window->window); + } +} + +static void glfw_error_cb(int error, const char * description) +{ + LV_LOG_ERROR("GLFW Error %d: %s", error, description); +} + +static lv_opengles_window_t * lv_glfw_get_lv_window_from_window(GLFWwindow * window) +{ + return glfwGetWindowUserPointer(window); +} + +static void window_close_callback(GLFWwindow * window) +{ + lv_opengles_window_t * lv_window = lv_glfw_get_lv_window_from_window(window); + lv_window->closing = 1; +} + +static void key_callback(GLFWwindow * window, int key, int scancode, int action, int mods) +{ + LV_UNUSED(scancode); + LV_UNUSED(mods); + if(key == GLFW_KEY_ESCAPE && action == GLFW_PRESS) { + lv_opengles_window_t * lv_window = lv_glfw_get_lv_window_from_window(window); + lv_window->closing = 1; + } +} + +static void mouse_button_callback(GLFWwindow * window, int button, int action, int mods) +{ + LV_UNUSED(mods); + if(button == GLFW_MOUSE_BUTTON_LEFT) { + lv_opengles_window_t * lv_window = lv_glfw_get_lv_window_from_window(window); + lv_window->mouse_last_state = action == GLFW_PRESS ? LV_INDEV_STATE_PRESSED : LV_INDEV_STATE_RELEASED; + proc_mouse(lv_window); + } +} + +static void mouse_move_callback(GLFWwindow * window, double xpos, double ypos) +{ + lv_opengles_window_t * lv_window = lv_glfw_get_lv_window_from_window(window); + lv_window->mouse_last_point.x = (int32_t)xpos; + lv_window->mouse_last_point.y = (int32_t)ypos; + proc_mouse(lv_window); +} + +static void proc_mouse(lv_opengles_window_t * window) +{ + /* mouse activity will affect the topmost LVGL display texture */ + lv_opengles_window_texture_t * texture; + LV_LL_READ_BACK(&window->textures, texture) { + if(lv_area_is_point_on(&texture->area, &window->mouse_last_point, 0)) { + /* adjust the mouse pointer coordinates so that they are relative to the texture */ + if(window->h_flip) { + texture->indev_last_point.x = texture->area.x2 - window->mouse_last_point.x; + } + else { + texture->indev_last_point.x = window->mouse_last_point.x - texture->area.x1; + } + if(window->v_flip) { + texture->indev_last_point.y = (texture->area.y2 - window->mouse_last_point.y); + } + else { + texture->indev_last_point.y = (window->mouse_last_point.y - texture->area.y1); + } + texture->indev_last_state = window->mouse_last_state; + lv_indev_read(texture->indev); + break; + } + } +} + +static void indev_read_cb(lv_indev_t * indev, lv_indev_data_t * data) +{ + lv_opengles_window_texture_t * texture = lv_indev_get_driver_data(indev); + data->point = texture->indev_last_point; + data->state = texture->indev_last_state; +} + +static void framebuffer_size_callback(GLFWwindow * window, int width, int height) +{ + lv_opengles_window_t * lv_window = lv_glfw_get_lv_window_from_window(window); + lv_window->hor_res = width; + lv_window->ver_res = height; +} + +static uint32_t lv_glfw_tick_count_callback(void) +{ + double tick = glfwGetTime() * 1000.0; + return (uint32_t)tick; +} + +static void window_display_delete_cb(lv_event_t * e) +{ + lv_display_t * disp = lv_event_get_target(e); + lv_opengles_window_texture_t * dsc = lv_display_get_driver_data(disp); + free(dsc->fb); + lv_opengles_window_texture_remove(dsc); +} + +static void window_display_flush_cb(lv_display_t * disp, const lv_area_t * area, uint8_t * px_map) +{ + LV_UNUSED(area); + LV_UNUSED(px_map); + lv_display_flush_ready(disp); +} + +#if !LV_USE_DRAW_OPENGLES +static void ensure_init_window_display_texture(void) +{ + if(window_display_texture) { + return; + } + + GL_CALL(glGenTextures(1, &window_display_texture)); + GL_CALL(glBindTexture(GL_TEXTURE_2D, window_display_texture)); + GL_CALL(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST)); + GL_CALL(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST)); + GL_CALL(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE)); + GL_CALL(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE)); + GL_CALL(glPixelStorei(GL_UNPACK_ALIGNMENT, 1)); + + GL_CALL(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, 20)); + GL_CALL(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST_MIPMAP_NEAREST)); + GL_CALL(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST)); + + GL_CALL(glBindTexture(GL_TEXTURE_2D, 0)); +} +#endif + +#endif /*LV_USE_GLFW*/ diff --git a/src/drivers/opengles/lv_opengles_glfw.h b/src/drivers/opengles/lv_opengles_glfw.h new file mode 100644 index 0000000000..39d2d51e10 --- /dev/null +++ b/src/drivers/opengles/lv_opengles_glfw.h @@ -0,0 +1,88 @@ +/** + * @file lv_opengles_glfw.h + * + */ + +#ifndef LV_OPENGLES_GLFW_H +#define LV_OPENGLES_GLFW_H + +#ifdef __cplusplus +extern "C" { +#endif + +#include "../../lv_conf_internal.h" +#if LV_USE_GLFW + +#include "../../misc/lv_types.h" + +/********************* + * INCLUDES + *********************/ + +/********************* + * DEFINES + *********************/ + +/********************** + * TYPEDEFS + **********************/ + +/********************** + * GLOBAL PROTOTYPES + **********************/ + +/** + * Create a GLFW OpenGL window with no textures and initialize OpenGL + * @param hor_res width in pixels of the window + * @param ver_res height in pixels of the window + * @param use_mouse_indev send pointer indev input to LVGL display textures + * @return the new GLFW OpenGL window handle + */ +lv_opengles_window_t * lv_opengles_glfw_window_create(int32_t hor_res, int32_t ver_res, bool use_mouse_indev); + +/** + * Create a GLFW window with no textures and initialize OpenGL + * @param hor_res width in pixels of the window + * @param ver_res height in pixels of the window + * @param use_mouse_indev send pointer indev input to LVGL display textures + * @param h_flip Should the window contents be horizontally mirrored? + * @param v_flip Should the window contents be vertically mirrored? + * @param title The window title + * @return the new GLFW window handle + */ +lv_opengles_window_t * lv_opengles_glfw_window_create_ex(int32_t hor_res, int32_t ver_res, bool use_mouse_indev, + bool h_flip, bool v_flip, const char * title); + +/** + * Set the window's title text + * @param window GLFW window to configure + * @param new_title The new title text + */ +void lv_opengles_glfw_window_set_title(lv_opengles_window_t * window, const char * new_title); + +/** + * Set the horizontal / vertical flipping of a GLFW window + * @param window GLFW window to configure + * @param h_flip Should the window contents be horizontally mirrored? + * @param v_flip Should the window contents be vertically mirrored? + */ +void lv_opengles_glfw_window_set_flip(lv_opengles_window_t * window, bool h_flip, bool v_flip); + +/** + * Get the GLFW window handle for a GLFW lv_opengles_window_t + * @param window GLFW window to return the handle of + * @return the GLFW window handle + */ +void * lv_opengles_glfw_window_get_glfw_window(lv_opengles_window_t * window); + +/********************** + * MACROS + **********************/ + +#endif /*LV_USE_GLFW*/ + +#ifdef __cplusplus +} /*extern "C"*/ +#endif + +#endif /*LV_OPENGLES_GLFW_H*/ diff --git a/src/drivers/opengles/lv_opengles_private.h b/src/drivers/opengles/lv_opengles_private.h new file mode 100644 index 0000000000..6e98997dbf --- /dev/null +++ b/src/drivers/opengles/lv_opengles_private.h @@ -0,0 +1,113 @@ +/** + * @file lv_opengles_private.h + * + */ + +#ifndef LV_OPENGLES_PRIVATE_H +#define LV_OPENGLES_PRIVATE_H + +#ifdef __cplusplus +extern "C" { +#endif + +/********************* + * INCLUDES + *********************/ + +#include "../../lv_conf_internal.h" +#if LV_USE_OPENGLES + +#if LV_USE_EGL +#include "glad/include/glad/gles2.h" +#include "glad/include/glad/egl.h" +#else +/* For now, by default we add glew and glfw. + In the future we need to consider adding a config for setting these includes*/ +#include +#include +#endif /*LV_USE_EGL*/ + +/********************* + * DEFINES + *********************/ + +/* In desktop GL () these symbols are defined but for EGL + * they are defined as extensions with the _EXT suffix */ +#ifndef GL_BGRA +#define GL_BGRA GL_BGRA_EXT +#endif /*GL_BGRA*/ + +#ifndef GL_TEXTURE_MAX_LEVEL +#define GL_TEXTURE_MAX_LEVEL GL_TEXTURE_MAX_LEVEL_APPLE +#endif /*GL_TEXTURE_MAX_LEVEL*/ + +#ifndef GL_UNPACK_ROW_LENGTH +#define GL_UNPACK_ROW_LENGTH GL_UNPACK_ROW_LENGTH_EXT +#endif /*GL_UNPACK_ROW_LENGTH*/ + +#ifndef glGenVertexArrays +#define glGenVertexArrays glGenVertexArraysOES +#endif + +#ifndef glBindVertexArray +#define glBindVertexArray glBindVertexArrayOES +#endif + +#ifndef glDeleteVertexArrays +#define glDeleteVertexArrays glDeleteVertexArraysOES +#endif + +#ifndef glTexStorage2D +#define glTexStorage2D glTexStorage2DEXT +#endif + +#ifndef GL_RGBA32F +#define GL_RGBA32F 0x8814 +#endif +#ifndef GL_NUM_EXTENSIONS +#define GL_NUM_EXTENSIONS 0x821D +#endif + +#ifndef GL_RGB8 +#define GL_RGB8 0x8051 +#endif + +#ifndef GL_RGBA8 +#define GL_RGBA8 0x8058 +#endif + +#ifndef LV_GL_PREFERRED_DEPTH +#ifdef GL_DEPTH_COMPONENT24 +#define LV_GL_PREFERRED_DEPTH GL_DEPTH_COMPONENT24 +#else +/* + * This will not run correctly yet, it compiles fine but fails to render on RPi3B. Work in progress. + * +#ifdef GL_DEPTH_COMPONENT24_OES +#define LV_GL_PREFERRED_DEPTH GL_DEPTH_COMPONENT24_OES +#else +#define LV_GL_PREFERRED_DEPTH GL_DEPTH_COMPONENT16 +#endif +*/ +#define LV_GL_PREFERRED_DEPTH GL_DEPTH_COMPONENT16 +#endif +#endif +/********************** + * TYPEDEFS + **********************/ + +/********************** + * GLOBAL PROTOTYPES + **********************/ + +/********************** + * MACROS + **********************/ + +#endif /*LV_USE_OPENGLES*/ + +#ifdef __cplusplus +} /*extern "C"*/ +#endif + +#endif /*LV_OPENGLES_PRIVATE_H*/ diff --git a/src/drivers/opengles/lv_opengles_texture.c b/src/drivers/opengles/lv_opengles_texture.c new file mode 100644 index 0000000000..c5b460db52 --- /dev/null +++ b/src/drivers/opengles/lv_opengles_texture.c @@ -0,0 +1,269 @@ +/** + * @file lv_opengles_texture.c + * + */ + +/********************* + * INCLUDES + *********************/ + +#include "lv_opengles_texture.h" +#if LV_USE_OPENGLES + +#include "lv_opengles_debug.h" +#include "lv_opengles_driver.h" + +#include "../../misc/lv_types.h" +#include "../../stdlib/lv_mem.h" +#include "lv_opengles_private.h" +#include "lv_opengles_texture_private.h" +#include "../../display/lv_display_private.h" + +#include + +/********************* + * DEFINES + *********************/ + +/********************** + * TYPEDEFS + **********************/ + +/********************** + * STATIC PROTOTYPES + **********************/ + +static lv_display_t * lv_opengles_texture_create_common(int32_t w, int32_t h); +static unsigned int create_texture(int32_t w, int32_t h); +static void flush_cb(lv_display_t * disp, const lv_area_t * area, uint8_t * px_map); +static void release_disp_cb(lv_event_t * e); + +/********************** + * STATIC VARIABLES + **********************/ + +/********************** + * MACROS + **********************/ + +/********************** + * GLOBAL FUNCTIONS + **********************/ + +lv_display_t * lv_opengles_texture_create(int32_t w, int32_t h) +{ + lv_display_t * disp = lv_opengles_texture_create_common(w, h); + if(!disp) { + LV_LOG_ERROR("Failed to create display"); + return NULL; + } + lv_opengles_texture_t * dsc = lv_display_get_driver_data(disp); + unsigned int texture_id = create_texture(w, h); + dsc->texture_id = texture_id; + dsc->is_texture_owner = true; + return disp; +} + +lv_display_t * lv_opengles_texture_create_from_texture_id(int32_t w, int32_t h, unsigned int texture_id) +{ + lv_display_t * disp = lv_opengles_texture_create_common(w, h); + if(!disp) { + LV_LOG_ERROR("Failed to create display"); + return NULL; + } + lv_opengles_texture_t * dsc = lv_display_get_driver_data(disp); + dsc->texture_id = texture_id; + dsc->is_texture_owner = false; + return disp; +} + +void lv_opengles_texture_reshape(lv_display_t * disp, int32_t width, int32_t height) +{ + lv_opengles_texture_t * dsc = lv_display_get_driver_data(disp); + unsigned int new_texture = create_texture(width, height); + if(new_texture == GL_NONE) { + LV_LOG_ERROR("Failed to reshape texture. Couldn't acquire new texture from GPU"); + return; + } +#if !LV_USE_DRAW_OPENGLES + uint32_t stride = lv_draw_buf_width_to_stride(width, lv_display_get_color_format(disp)); + uint32_t buf_size = stride * height; + uint8_t * buffer = lv_realloc(dsc->fb1, buf_size); + LV_ASSERT_MALLOC(buffer); + if(!buffer) { + GL_CALL(glDeleteTextures(1, &new_texture)); + LV_LOG_ERROR("Failed to reshape texture. Couldn't resize buffer"); + return; + } + dsc->fb1 = buffer; +#endif /*!LV_USE_DRAW_OPENGLES*/ + + if(dsc->is_texture_owner && dsc->texture_id != 0) { + GL_CALL(glDeleteTextures(1, &dsc->texture_id)); + } + dsc->texture_id = new_texture; +} + +lv_result_t lv_opengles_texture_create_draw_buffers(lv_opengles_texture_t * texture, lv_display_t * display) +{ + int32_t w = lv_display_get_horizontal_resolution(display); + int32_t h = lv_display_get_vertical_resolution(display); + +#if LV_USE_DRAW_OPENGLES + LV_UNUSED(texture); + static size_t LV_ATTRIBUTE_MEM_ALIGN dummy_buf; + lv_display_set_buffers(display, &dummy_buf, NULL, w * h * 4, LV_DISPLAY_RENDER_MODE_DIRECT); +#else + uint32_t stride = lv_draw_buf_width_to_stride(w, lv_display_get_color_format(display)); + uint32_t buf_size = stride * h; + texture->fb1 = lv_malloc(buf_size); + LV_ASSERT_MALLOC(texture->fb1); + if(!texture->fb1) { + return LV_RESULT_INVALID; + } + lv_display_set_buffers(display, texture->fb1, NULL, buf_size, LV_DISPLAY_RENDER_MODE_DIRECT); +#endif + return LV_RESULT_OK; +} + +void lv_opengles_texture_deinit(lv_opengles_texture_t * texture) +{ +#if !LV_USE_DRAW_OPENGLES + lv_free(texture->fb1); +#endif /*!LV_USE_DRAW_OPENGLES*/ + + if(texture->is_texture_owner && texture->texture_id != 0) { + GL_CALL(glDeleteTextures(1, &texture->texture_id)); + } +} + +unsigned int lv_opengles_texture_get_texture_id(lv_display_t * disp) +{ + lv_opengles_texture_t * dsc = lv_display_get_driver_data(disp); + return dsc->texture_id; +} + +lv_display_t * lv_opengles_texture_get_from_texture_id(unsigned int texture_id) +{ + lv_display_t * disp = NULL; + while(NULL != (disp = lv_display_get_next(disp))) { + unsigned int disp_texture_id = lv_opengles_texture_get_texture_id(disp); + if(disp_texture_id == texture_id) { + return disp; + } + } + return NULL; +} + +/********************** + * STATIC FUNCTIONS + **********************/ + +static lv_display_t * lv_opengles_texture_create_common(int32_t w, int32_t h) +{ + lv_display_t * disp = lv_display_create(w, h); + if(!disp) { + LV_LOG_ERROR("Failed to create display"); + return NULL; + } + lv_opengles_texture_t * texture = lv_malloc_zeroed(sizeof(lv_opengles_texture_t)); + LV_ASSERT_MALLOC(texture); + if(!texture) { + LV_LOG_ERROR("Failed to create texture"); + lv_display_delete(disp); + return NULL; + } + lv_result_t res = lv_opengles_texture_create_draw_buffers(texture, disp); + if(res != LV_RESULT_OK) { + LV_LOG_ERROR("Failed to create draw buffers"); + lv_free(texture); + lv_display_delete(disp); + return NULL; + } + lv_display_set_resolution(disp, w, h); + lv_display_set_flush_cb(disp, flush_cb); + lv_display_set_driver_data(disp, texture); + lv_display_add_event_cb(disp, release_disp_cb, LV_EVENT_DELETE, disp); + + lv_opengles_init(); + return disp; +} + +static unsigned int create_texture(int32_t w, int32_t h) +{ + unsigned int texture; + GL_CALL(glGenTextures(1, &texture)); + GL_CALL(glBindTexture(GL_TEXTURE_2D, texture)); + GL_CALL(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST)); + GL_CALL(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST)); + GL_CALL(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE)); + GL_CALL(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE)); + GL_CALL(glPixelStorei(GL_UNPACK_ALIGNMENT, 1)); + + /* set the dimensions and format to complete the texture */ + /* Color depth: 16 (RGB565), 32 (XRGB8888) */ +#if LV_COLOR_DEPTH == 16 + GL_CALL(glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB565, w, h, 0, GL_RGB, GL_UNSIGNED_SHORT_5_6_5, + NULL)); +#elif LV_COLOR_DEPTH == 32 + GL_CALL(glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, w, h, 0, GL_BGRA, GL_UNSIGNED_BYTE, NULL)); +#else +#error("Unsupported color format") +#endif + +#if 0 + GL_CALL(glGenerateMipmap(GL_TEXTURE_2D)); + GL_CALL(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, 20)); + GL_CALL(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST_MIPMAP_NEAREST)); +#endif + + GL_CALL(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST)); + GL_CALL(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST)); + GL_CALL(glBindTexture(GL_TEXTURE_2D, GL_NONE)); + return texture; +} + +/********************** + * STATIC FUNCTIONS + **********************/ + +static void flush_cb(lv_display_t * disp, const lv_area_t * area, uint8_t * px_map) +{ + LV_UNUSED(area); + LV_UNUSED(px_map); + +#if !LV_USE_DRAW_OPENGLES + if(lv_display_flush_is_last(disp)) { + + lv_opengles_texture_t * dsc = lv_display_get_driver_data(disp); + lv_color_format_t cf = lv_display_get_color_format(disp); + uint32_t stride = lv_draw_buf_width_to_stride(lv_display_get_horizontal_resolution(disp), cf); + + GL_CALL(glBindTexture(GL_TEXTURE_2D, dsc->texture_id)); + + GL_CALL(glPixelStorei(GL_UNPACK_ALIGNMENT, 1)); + GL_CALL(glPixelStorei(GL_UNPACK_ROW_LENGTH, stride / lv_color_format_get_size(cf))); + /*Color depth: 16 (RGB565), 32 (XRGB8888)*/ +#if LV_COLOR_DEPTH == 16 + GL_CALL(glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB565, disp->hor_res, disp->ver_res, 0, GL_RGB, GL_UNSIGNED_SHORT_5_6_5, + dsc->fb1)); +#elif LV_COLOR_DEPTH == 32 + GL_CALL(glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, disp->hor_res, disp->ver_res, 0, GL_BGRA, GL_UNSIGNED_BYTE, dsc->fb1)); +#else +#error("Unsupported color format") +#endif + } +#endif /* !LV_USE_DRAW_OPENGLES */ + + lv_display_flush_ready(disp); +} + +static void release_disp_cb(lv_event_t * e) +{ + lv_display_t * disp = lv_event_get_user_data(e); + lv_opengles_texture_t * texture = lv_display_get_driver_data(disp); + lv_opengles_texture_deinit(texture); + lv_free(texture); +} + +#endif /*LV_USE_OPENGLES*/ diff --git a/src/drivers/glfw/lv_opengles_texture.h b/src/drivers/opengles/lv_opengles_texture.h similarity index 67% rename from src/drivers/glfw/lv_opengles_texture.h rename to src/drivers/opengles/lv_opengles_texture.h index 0d53b2b168..2a6933a95c 100644 --- a/src/drivers/glfw/lv_opengles_texture.h +++ b/src/drivers/opengles/lv_opengles_texture.h @@ -33,12 +33,25 @@ extern "C" { /** * Create a display that flushes to an OpenGL texture + * If you already have a texture and want to bind it to the display, + * see `lv_opengles_texture_create_from_texture_id` * @param w width in pixels of the texture * @param h height in pixels of the texture - * @return the new display + * @return the new display or NULL on failure */ lv_display_t * lv_opengles_texture_create(int32_t w, int32_t h); +/** + * Create a display that flushes to the provided OpenGL texture + * If you don't have a texture to bind it to the display, + * see `lv_opengles_texture_create` + * @param w width in pixels of the texture + * @param h height in pixels of the texture + * @param texture_id the texture LVGL will render to + * @return the new display or NULL on failure + */ +lv_display_t * lv_opengles_texture_create_from_texture_id(int32_t w, int32_t h, unsigned int texture_id); + /** * Get the OpenGL texture ID of the display * @param disp display diff --git a/src/drivers/opengles/lv_opengles_texture_private.h b/src/drivers/opengles/lv_opengles_texture_private.h new file mode 100644 index 0000000000..47c7a74b56 --- /dev/null +++ b/src/drivers/opengles/lv_opengles_texture_private.h @@ -0,0 +1,57 @@ +/** + * @file lv_opengles_texture_private.h + * + */ + + +#ifndef LV_OPENGLES_TEXTURE_PRIVATE_H +#define LV_OPENGLES_TEXTURE_PRIVATE_H + +#ifdef __cplusplus +extern "C" { +#endif + +/********************* + * INCLUDES + *********************/ +#include "../../lv_conf_internal.h" + +#if LV_USE_OPENGLES + +#include "lv_opengles_texture.h" + +/********************* + * DEFINES + *********************/ + +/********************** + * TYPEDEFS + **********************/ + +typedef struct { + unsigned int texture_id; +#if !LV_USE_DRAW_OPENGLES + uint8_t * fb1; +#endif /*!LV_USE_DRAW_OPENGLES*/ + bool is_texture_owner; +} lv_opengles_texture_t; + +/********************** + * GLOBAL PROTOTYPES + **********************/ + +lv_result_t lv_opengles_texture_create_draw_buffers(lv_opengles_texture_t * texture, lv_display_t * display); +void lv_opengles_texture_reshape(lv_display_t * disp, int32_t width, int32_t height); +void lv_opengles_texture_deinit(lv_opengles_texture_t * texture); + +/********************** + * MACROS + **********************/ + +#endif /*LV_USE_OPENGLES*/ + +#ifdef __cplusplus +} /*extern "C"*/ +#endif + +#endif /* LV_OPENGLES_TEXTURE_PRIVATE_H */ diff --git a/src/drivers/opengles/lv_opengles_window.h b/src/drivers/opengles/lv_opengles_window.h new file mode 100644 index 0000000000..9f22af2c55 --- /dev/null +++ b/src/drivers/opengles/lv_opengles_window.h @@ -0,0 +1,102 @@ +/** + * @file lv_opengles_window.h + * + */ + +#ifndef LV_OPENGLES_WINDOW_H +#define LV_OPENGLES_WINDOW_H + +#ifdef __cplusplus +extern "C" { +#endif + +/********************* + * INCLUDES + *********************/ + +#include "../../lv_conf_internal.h" +#if LV_USE_OPENGLES + +#include "../../misc/lv_types.h" + +/********************* + * DEFINES + *********************/ + +/********************** + * TYPEDEFS + **********************/ + +/********************** + * GLOBAL PROTOTYPES + **********************/ + +/** + * Delete an OpenGL window. If it is the last one, the process will exit + * @param window OpenGL window to delete + */ +void lv_opengles_window_delete(lv_opengles_window_t * window); + +/** + * Add a texture to the OpenGL window. It can be an LVGL display texture, or any OpenGL texture + * @param window OpenGL window + * @param texture_id OpenGL texture ID + * @param w width in pixels of the texture + * @param h height in pixels of the texture + * @return the new texture handle + */ +lv_opengles_window_texture_t * lv_opengles_window_add_texture(lv_opengles_window_t * window, unsigned int texture_id, + int32_t w, int32_t h); + +lv_display_t * lv_opengles_window_display_create(lv_opengles_window_t * window, int32_t w, int32_t h); + +lv_opengles_window_texture_t * lv_opengles_window_display_get_window_texture(lv_display_t * window_display); + +/** + * Remove a texture from its OpenGL window and delete it + * @param texture handle of an OpenGL window texture + */ +void lv_opengles_window_texture_remove(lv_opengles_window_texture_t * texture); + +/** + * Set the x position of a texture within its OpenGL window + * @param texture handle of an OpenGL window texture + * @param x new x position of the texture + */ +void lv_opengles_window_texture_set_x(lv_opengles_window_texture_t * texture, int32_t x); + +/** + * Set the y position of a texture within its OpenGL window + * @param texture handle of an OpenGL window texture + * @param y new y position of the texture + */ +void lv_opengles_window_texture_set_y(lv_opengles_window_texture_t * texture, int32_t y); + +/** + * Set the opacity of a texture in an OpenGL window + * @param texture handle of an OpenGL window texture + * @param opa new opacity of the texture + */ +void lv_opengles_window_texture_set_opa(lv_opengles_window_texture_t * texture, lv_opa_t opa); + +/** + * Get the mouse indev associated with a texture in an OpenGL window, if it exists + * @param texture handle of an OpenGL window texture + * @return the indev or `NULL` + * @note there will only be an indev if the texture is based on an + * LVGL display texture and the window was created with + * `use_mouse_indev` as `true` + */ +lv_indev_t * lv_opengles_window_texture_get_mouse_indev(lv_opengles_window_texture_t * texture); + +/********************** + * MACROS + **********************/ + +#endif /* LV_USE_OPENGLES */ + +#ifdef __cplusplus +} /* extern "C" */ +#endif + +#endif /* LV_OPENGLES_WINDOW_H */ diff --git a/src/drivers/opengles/opengl_shader/lv_opengl_shader_internal.h b/src/drivers/opengles/opengl_shader/lv_opengl_shader_internal.h new file mode 100644 index 0000000000..90f865de5b --- /dev/null +++ b/src/drivers/opengles/opengl_shader/lv_opengl_shader_internal.h @@ -0,0 +1,124 @@ +/** + @file lv_opengl_shader_internal.h + * + */ + +#ifndef LV_OPENGL_SHADER_INTERNAL_H +#define LV_OPENGL_SHADER_INTERNAL_H + +#include "../../../lv_conf_internal.h" + +#if LV_USE_OPENGLES +#include "../lv_opengles_private.h" +#include "../lv_opengles_debug.h" +#include "../../../misc/lv_types.h" +#include "../../../misc/lv_rb_private.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/********************* + * INCLUDES + *********************/ + +/********************* + * DEFINES + *********************/ + +/********************** + * TYPEDEFS + **********************/ + +typedef struct { + const char * name; + const char * source; +} lv_opengl_shader_t; + +typedef struct { + const lv_opengl_shader_t * all; + uint32_t count; +} lv_opengl_shader_portions_t; + +typedef struct { + const char * name; + const char * value; + bool value_allocated; +} lv_opengl_shader_define_t; + +typedef struct { + lv_opengl_shader_t data; + bool src_allocated; +} lv_opengl_shader_source_t; + +typedef struct { + uint32_t hash; + GLuint id; +} lv_opengl_compiled_shader_t; + +typedef struct lv_opengl_shader_cache_struct { + lv_rb_t sources_map; + lv_rb_t textures_map; + lv_rb_t compiled_shaders_map; + lv_rb_t programs_map; + GLuint bg_index_buf; + GLuint bg_vertex_buf; + GLuint bg_program; + GLuint bg_vao; +} lv_opengl_shader_manager_t; + +struct _lv_shader_program; + +typedef void (*lv_opengl_shader_program_update_uniformi_t)(struct _lv_shader_program *, const char *, int); + +typedef void (*lv_opengl_shader_program_update_uniformf_t)(struct _lv_shader_program *, const char *, float); + +typedef struct _lv_shader_program { + lv_opengl_shader_program_update_uniformi_t update_uniform_1i; + lv_opengl_shader_program_update_uniformf_t update_uniform_1f; + uint32_t id; +} lv_opengl_shader_program_t; + +typedef enum { + LV_OPENGL_GLSL_VERSION_300ES, + LV_OPENGL_GLSL_VERSION_100, + LV_OPENGL_GLSL_VERSION_LAST, +} lv_opengl_glsl_version; + +/********************** + * GLOBAL PROTOTYPES + **********************/ + +char * lv_opengl_shader_manager_process_includes(const char * c_src, const lv_opengl_shader_t * src_includes, + size_t num_items); + +lv_opengl_shader_program_t * lv_opengl_shader_program_create(uint32_t id); +void lv_opengl_shader_program_destroy(lv_opengl_shader_program_t * program); +GLuint lv_opengl_shader_program_get_id(lv_opengl_shader_program_t * program); + +void lv_opengl_shader_manager_init(lv_opengl_shader_manager_t * manager, const lv_opengl_shader_t * sources, + size_t len, const char * vert_src, + const char * frag_src); +void lv_opengl_shader_manager_deinit(lv_opengl_shader_manager_t * manager); +uint32_t lv_opengl_shader_hash(const char * value); +GLuint lv_opengl_shader_manager_get_texture(lv_opengl_shader_manager_t * manager, uint32_t hash); +void lv_opengl_shader_manager_store_texture(lv_opengl_shader_manager_t * manager, uint32_t hash, GLuint id); +lv_result_t lv_opengl_shader_manager_select_shader(lv_opengl_shader_manager_t * shader, const char * shader_identifier, + const lv_opengl_shader_define_t * permutations, size_t permutations_len, + lv_opengl_glsl_version glsl_version, uint32_t * out_hash); +lv_opengl_shader_program_t * lv_opengl_shader_manager_get_program(lv_opengl_shader_manager_t * manager, + uint32_t fragment_shader_hash, + uint32_t vertex_shader_hash); + +const char * lv_opengles_glsl_version_to_string(lv_opengl_glsl_version version); + +/********************** + * MACROS + **********************/ + +#ifdef __cplusplus +} /*extern "C"*/ +#endif + +#endif /*LV_USE_OPENGLES*/ +#endif /*LV_OPENGL_SHADER_INTERNAL_H*/ diff --git a/src/drivers/opengles/opengl_shader/lv_opengl_shader_manager.c b/src/drivers/opengles/opengl_shader/lv_opengl_shader_manager.c new file mode 100644 index 0000000000..aa9b62fe75 --- /dev/null +++ b/src/drivers/opengles/opengl_shader/lv_opengl_shader_manager.c @@ -0,0 +1,648 @@ +/** + * @file lv_opengl_shader_manager.c + * + */ + + +/********************* + * INCLUDES + *********************/ + +#include "../../../lv_conf_internal.h" +#if LV_USE_OPENGLES +#include "lv_opengl_shader_internal.h" +#include "../../../misc/lv_assert.h" +#include "../../../misc/lv_log.h" +#include "../../../misc/lv_rb.h" +#include "../../../misc/lv_types.h" +#include "../../../stdlib/lv_mem.h" +#include "../../../stdlib/lv_sprintf.h" +#include "../lv_opengles_private.h" +#include "../lv_opengles_debug.h" +#include "../../../stdlib/lv_string.h" + +#include + +/********************* + * DEFINES + *********************/ + +/********************** + * TYPEDEFS + **********************/ + +typedef lv_opengl_compiled_shader_t lv_opengl_shader_texture_t; + +typedef struct { + lv_opengl_shader_program_t * program; + uint32_t vertex_shader_hash; + uint32_t fragment_shader_hash; +} lv_opengl_program_map_key_t; + +/********************** + * STATIC PROTOTYPES + **********************/ + +static char * replace_word(const char * s, const char * f, const char * r); + +static lv_rb_compare_res_t +shader_source_compare_cb(const lv_opengl_shader_source_t * lhs, + const lv_opengl_shader_source_t * rhs); + +static lv_rb_compare_res_t +compiled_shader_compare_cb(const lv_opengl_compiled_shader_t * lhs, + const lv_opengl_compiled_shader_t * rhs); + +static lv_rb_compare_res_t +shader_program_compare_cb(const lv_opengl_program_map_key_t * lhs, + const lv_opengl_program_map_key_t * rhs); + +static lv_rb_t create_shader_map(const lv_opengl_shader_t * shaders, size_t len); +static bool string_ends_with(const char * value, const char * suffix); + +static char * construct_shader(const char * source, + const lv_opengl_shader_define_t * permutations, + size_t permutations_len, lv_opengl_glsl_version glsl_version); + +static GLuint compile_shader(const char * shader_source, bool is_vertex_shader); +static GLuint link_program(GLuint vertex_shader_id, GLuint fragment_shader_id); +static bool is_shader_compiled(GLint shader_id); +static bool is_program_linked(GLint program_id); +/********************** + * STATIC VARIABLES + **********************/ + +/********************** + * MACROS + **********************/ + +/********************** + * GLOBAL FUNCTIONS + **********************/ + +void lv_opengl_shader_manager_init(lv_opengl_shader_manager_t * manager, const lv_opengl_shader_t * sources, + size_t len, const char * vert_src, + const char * frag_src) +{ + + manager->sources_map = create_shader_map(sources, len); + if(vert_src != NULL) { + lv_opengl_shader_t entry = { "__MAIN__.vert", lv_strdup(vert_src) }; + lv_rb_node_t * node = lv_rb_insert(&manager->sources_map, &entry); + LV_ASSERT_MSG(node, + "Failed to insert shader source to source map"); + lv_memcpy(node->data, &entry, sizeof(entry)); + } + if(frag_src != NULL) { + lv_opengl_shader_t entry = { "__MAIN__.frag", lv_strdup(frag_src) }; + lv_rb_node_t * node = lv_rb_insert(&manager->sources_map, &entry); + LV_ASSERT_MSG(node, "Failed to insert shader to shader map"); + lv_memcpy(node->data, &entry, sizeof(entry)); + } + + lv_rb_init(&manager->compiled_shaders_map, + (lv_rb_compare_t)compiled_shader_compare_cb, + sizeof(lv_opengl_compiled_shader_t)); + + /* Textures and compiled shaders share the same compare function */ + lv_rb_init(&manager->textures_map, + (lv_rb_compare_t)compiled_shader_compare_cb, + sizeof(lv_opengl_shader_texture_t)); + + lv_rb_init(&manager->programs_map, + (lv_rb_compare_t)shader_program_compare_cb, + sizeof(lv_opengl_program_map_key_t)); + + manager->bg_index_buf = 0; + manager->bg_vertex_buf = 0; + manager->bg_program = 0; +} + +uint32_t lv_opengl_shader_hash(const char * value) +{ + uint32_t hash = 0; + const size_t len = lv_strlen(value); + if(len == 0) { + return hash; + } + for(size_t i = 0; i < len; i++) { + hash = ((hash << 5) - hash) + value[i]; + } + return hash; +} + +void lv_opengl_shader_manager_store_texture(lv_opengl_shader_manager_t * manager, + uint32_t texture_hash, + GLuint texture_id) +{ + lv_opengl_shader_texture_t key = { .id = texture_id, .hash = texture_hash }; + lv_rb_node_t * node = lv_rb_insert(&manager->textures_map, &key); + if(!node) { + LV_LOG_WARN("Failed to cache texture hash: %d id: %d", + texture_hash, texture_id); + return; + } + + lv_memcpy(node->data, &key, sizeof(key)); +} + +GLuint lv_opengl_shader_manager_get_texture(lv_opengl_shader_manager_t * manager, + uint32_t texture_hash) +{ + lv_opengl_shader_texture_t key = { .hash = texture_hash }; + lv_rb_node_t * node = lv_rb_find(&manager->textures_map, &key); + if(!node) { + LV_LOG_INFO("Couldn't find texture with hash %d in cache", + texture_hash); + return GL_NONE; + } + return ((lv_opengl_shader_texture_t *)node->data)->id; +} + +lv_result_t lv_opengl_shader_manager_select_shader(lv_opengl_shader_manager_t * shader, const char * shader_identifier, + const lv_opengl_shader_define_t * permutations, size_t permutations_len, + lv_opengl_glsl_version glsl_version, uint32_t * out_hash) +{ + /* First check that the shader identifier exists */ + lv_opengl_shader_t key = { shader_identifier, NULL }; + lv_rb_node_t * source_node = lv_rb_find(&shader->sources_map, &key); + LV_LOG_TRACE("Select shader '%s'", shader_identifier); + + if(!source_node) { + LV_LOG_WARN("Couldn't find shader %s", shader_identifier); + return LV_RESULT_INVALID; + } + + /* Then hash the name with the permutations and see if we already compiled it */ + char define[512]; + uint32_t hash = lv_opengl_shader_hash(shader_identifier); + for(size_t i = 0; i < permutations_len; ++i) { + LV_ASSERT_NULL(permutations[i].name); + if(permutations[i].value) { + lv_snprintf(define, sizeof(define), "%s%s", permutations[i].name, permutations[i].value); + } + else { + lv_snprintf(define, sizeof(define), "%s", permutations[i].name); + } + hash ^= lv_opengl_shader_hash(define); + } + lv_opengl_compiled_shader_t shader_map_key = { hash, 0 }; + lv_rb_node_t * shader_map_node = + lv_rb_find(&shader->compiled_shaders_map, &shader_map_key); + + /* Fast path. Shader already compiled */ + if(shader_map_node != NULL) { + LV_LOG_INFO("Shader '%s' with hash %u found. Id: %d", shader_identifier, hash, + ((lv_opengl_compiled_shader_t *)shader_map_node->data)->id); + *out_hash = hash; + return LV_RESULT_OK; + } + + /* New shader requested, construct and compile it */ + bool is_vertex = string_ends_with(shader_identifier, ".vert"); + const char * original_shader_source = ((lv_opengl_shader_source_t *)source_node->data)->data.source; + + char * shader_source = construct_shader(original_shader_source, + permutations, permutations_len, glsl_version); + + shader_map_key.id = compile_shader(shader_source, is_vertex); + lv_free(shader_source); + + if(!is_shader_compiled(shader_map_key.id)) { + GLchar info_log[512]; + GL_CALL(glGetShaderInfoLog(shader_map_key.id, sizeof(info_log), NULL, info_log)); + LV_LOG_WARN("Failed to compile shader for glsl version '%s': %s", lv_opengles_glsl_version_to_string(glsl_version), + info_log); + return LV_RESULT_INVALID; + } + + LV_LOG_TRACE("Compiled %s shader %s to %d Hash %u", is_vertex ? "V" : "F", shader_identifier, shader_map_key.id, hash); + lv_rb_node_t * node = lv_rb_insert(&shader->compiled_shaders_map, &shader_map_key); + LV_ASSERT_MSG(node, "Failed to insert shader to shader map"); + lv_memcpy(node->data, &shader_map_key, sizeof(shader_map_key)); + + *out_hash = hash; + + return LV_RESULT_OK; +} + +lv_opengl_shader_program_t * +lv_opengl_shader_manager_get_program(lv_opengl_shader_manager_t * manager, + uint32_t fragment_shader_hash, + uint32_t vertex_shader_hash) +{ + lv_opengl_program_map_key_t key = { + .vertex_shader_hash = vertex_shader_hash, + .fragment_shader_hash = fragment_shader_hash + }; + + lv_rb_node_t * node = lv_rb_find(&manager->programs_map, &key); + if(node) { + return ((lv_opengl_program_map_key_t *)node->data)->program; + } + + lv_opengl_compiled_shader_t shader_key = { .hash = vertex_shader_hash }; + lv_rb_node_t * vertex_node = + lv_rb_find(&manager->compiled_shaders_map, &shader_key); + shader_key.hash = fragment_shader_hash; + lv_rb_node_t * fragment_node = + lv_rb_find(&manager->compiled_shaders_map, &shader_key); + + LV_ASSERT_FORMAT_MSG( + vertex_node, + "Unable to find to find vertex shader with hash %d", + vertex_shader_hash); + LV_ASSERT_FORMAT_MSG( + fragment_node, + "Unable to find to find fragment shader with hash %d", + fragment_shader_hash); + + const GLuint vertex_shader_id = + ((lv_opengl_compiled_shader_t *)vertex_node->data)->id; + const GLuint fragment_shader_id = + ((lv_opengl_compiled_shader_t *)fragment_node->data)->id; + + GLuint program_id = link_program(vertex_shader_id, fragment_shader_id); + bool is_linked = is_program_linked(program_id); + if(!is_linked) { + GLchar info_log[512]; + GL_CALL(glGetProgramInfoLog(program_id, sizeof(info_log), NULL, + info_log)); + LV_LOG_WARN("Failed to link program: %s", info_log); + return NULL; + } + LV_LOG_TRACE("Linking program with shaders V: %d F:%d P: %d", vertex_shader_id, fragment_shader_id, program_id); + + lv_opengl_shader_program_t * program = + lv_opengl_shader_program_create(program_id); + + LV_ASSERT_MSG(program, "Failed to create program"); + + lv_opengl_program_map_key_t prog_key = { + .program = program, + .fragment_shader_hash = fragment_shader_hash, + .vertex_shader_hash = vertex_shader_hash + }; + node = lv_rb_insert(&manager->programs_map, &prog_key); + LV_ASSERT_MSG(node, "Failed to store program in cache"); + lv_memcpy(node->data, &prog_key, sizeof(prog_key)); + return program; +} + +void lv_opengl_shader_manager_deinit(lv_opengl_shader_manager_t * manager) +{ + LV_LOG_INFO("Destroying shader cache"); + + lv_rb_destroy(&manager->textures_map); + + lv_rb_node_t * node; + + while((node = manager->sources_map.root)) { + lv_opengl_shader_source_t * shader = node->data; + if(shader->src_allocated) { + lv_free((void *)shader->data.source); + } + lv_rb_remove_node(&manager->sources_map, node); + } + lv_rb_destroy(&manager->sources_map); + + while((node = manager->compiled_shaders_map.root)) { + lv_opengl_compiled_shader_t * shader = node->data; + GL_CALL(glDeleteShader(shader->id)); + lv_rb_remove_node(&manager->compiled_shaders_map, node); + } + + lv_rb_destroy(&manager->compiled_shaders_map); + while((node = manager->programs_map.root)) { + lv_opengl_program_map_key_t * program_key = node->data; + lv_opengl_shader_program_destroy(program_key->program); + lv_rb_remove_node(&manager->programs_map, node); + } + lv_rb_destroy(&manager->programs_map); + +} + +const char * lv_opengles_glsl_version_to_string(lv_opengl_glsl_version version) +{ + + switch(version) { + case LV_OPENGL_GLSL_VERSION_100: + return "#version 100\n"; + case LV_OPENGL_GLSL_VERSION_300ES: + return "#version 300 es\n"; + case LV_OPENGL_GLSL_VERSION_LAST: + LV_LOG_ERROR("LV_OPENGL_GLSL_VERSION_LAST is not a valid version"); + return NULL; + } + LV_UNREACHABLE(); +} + +char * lv_opengl_shader_manager_process_includes(const char * c_src, const lv_opengl_shader_t * src_includes, + size_t num_items) +{ + if(!c_src || !src_includes) { + return NULL; + } + + char * rep = lv_strdup(c_src); + if(!rep) { + return NULL; + } + char search_str[255]; + + for(size_t i = 0; i < num_items; i++) { + lv_snprintf(search_str, sizeof(search_str), "\n#include <%s>", src_includes[i].name); + + char * new_rep = replace_word(rep, search_str, src_includes[i].source); + lv_free(rep); + if(!new_rep) { + return NULL; + } + rep = new_rep; + } + + return rep; +} + +/********************** + * STATIC FUNCTIONS + **********************/ + +static char * replace_word(const char * source, const char * f, const char * r) +{ + if(!source || !f || !r || strlen(f) == 0 || strcmp(f, r) == 0 || !strstr(source, f)) { + return lv_strdup(source); + } + + size_t s_len = strlen(source); + size_t f_len = strlen(f); + size_t r_len = strlen(r); + + size_t count = 0; + const char * temp = source; + while((temp = strstr(temp, f)) != NULL) { + count++; + temp += f_len; + } + + size_t new_size = s_len + count * (r_len - f_len) + 1; + char * result = lv_malloc(new_size); + LV_ASSERT_MALLOC(result); + + char * dest = result; + const char * src = source; + const char * pos; + + while((pos = strstr(src, f)) != NULL) { + size_t prefix_len = pos - src; + memcpy(dest, src, prefix_len); + dest += prefix_len; + + memcpy(dest, r, r_len); + dest += r_len; + + src = pos + f_len; + } + + strcpy(dest, src); + + return result; +} + +static lv_rb_compare_res_t +shader_program_compare_cb(const lv_opengl_program_map_key_t * lhs, + const lv_opengl_program_map_key_t * rhs) +{ + const lv_rb_compare_res_t cmp = lhs->vertex_shader_hash - rhs->vertex_shader_hash; + if(cmp == 0) { + return lhs->fragment_shader_hash - rhs->fragment_shader_hash; + } + return cmp; +} + +static lv_rb_compare_res_t +shader_source_compare_cb(const lv_opengl_shader_source_t * lhs, + const lv_opengl_shader_source_t * rhs) +{ + return lv_strcmp(lhs->data.name, rhs->data.name); +} + +static lv_rb_compare_res_t +compiled_shader_compare_cb(const lv_opengl_compiled_shader_t * lhs, + const lv_opengl_compiled_shader_t * rhs) +{ + return lhs->hash - rhs->hash; +} +static bool is_shader_compiled(GLint shader_id) +{ + int shader_compiled; + GL_CALL(glGetShaderiv(shader_id, GL_COMPILE_STATUS, &shader_compiled)); + return shader_compiled; +} + +static bool is_program_linked(GLint program_id) +{ + int link_status; + GL_CALL(glGetProgramiv(program_id, GL_LINK_STATUS, &link_status)); + return link_status; +} +static GLuint compile_shader(const char * shader_source, bool is_vertex_shader) +{ + GLuint shader_id; + if(is_vertex_shader) { + GL_CALL(shader_id = glCreateShader(GL_VERTEX_SHADER)); + } + else { + GL_CALL(shader_id = glCreateShader(GL_FRAGMENT_SHADER)); + } + + GL_CALL(glShaderSource(shader_id, 1, (const char **)&shader_source, + NULL)); + GL_CALL(glCompileShader(shader_id)); + + return shader_id; +} + +static GLuint link_program(GLuint vertex_shader_id, GLuint fragment_shader_id) +{ + GLuint program_id; + GL_CALL(program_id = glCreateProgram()); + GL_CALL(glAttachShader(program_id, fragment_shader_id)); + GL_CALL(glAttachShader(program_id, vertex_shader_id)); + GL_CALL(glLinkProgram(program_id)); + + return program_id; +} + +static char * append_to_shader(char * dst, const char * src, size_t * curr_index) +{ + lv_strcpy(dst + *curr_index, src); + *curr_index += lv_strlen(src); + return dst; +} + +static char * construct_shader(const char * source, + const lv_opengl_shader_define_t * permutations, + size_t permutations_len, lv_opengl_glsl_version glsl_version) +{ + const char * defines = lv_opengles_glsl_version_to_string(glsl_version); + const char * prefix = "#define "; + + const size_t prefix_len = lv_strlen(prefix); + size_t shader_source_size = lv_strlen(defines) + lv_strlen(source); + + /* First calculate the necessary size */ + for(size_t i = 0; i < permutations_len; ++i) { + shader_source_size += prefix_len; + if(!permutations[i].name) { + LV_LOG_WARN("Name is NULL for permutation # %zu", i); + continue; + } + shader_source_size += + lv_strlen(permutations[i].name) + 1; /* ' ' */ + if(permutations[i].value) { + shader_source_size += + lv_strlen(permutations[i].value) + 1; /* '\n' */ + } + } + + /* Allocate enough for memory with calculated size*/ + char * result = (char *)lv_malloc(shader_source_size + 1); + if(!result) { + LV_LOG_ERROR( + "Failed to allocate enough space for shader changes"); + return 0; + } + + /* Construct shader */ + size_t curr_index = 0; + append_to_shader(result, defines, &curr_index); + for(size_t i = 0; i < permutations_len; ++i) { + if(!permutations[i].name) { + continue; + } + append_to_shader(result, prefix, &curr_index); + append_to_shader(result, permutations[i].name, &curr_index); + if(permutations[i].value) { + result[curr_index++] = ' '; + append_to_shader(result, permutations[i].value, + &curr_index); + } + result[curr_index++] = '\n'; + } + append_to_shader(result, source, &curr_index); + LV_ASSERT(curr_index == shader_source_size); + result[shader_source_size] = '\0'; + return result; +} + +static char * replace_include(const char * source, const char * pattern, + const char * replacement) +{ + const char * pos = strstr(source, pattern); + LV_ASSERT(pos); + + const size_t source_len = lv_strlen(source); + const size_t pattern_len = lv_strlen(pattern); + const size_t replacement_len = lv_strlen(replacement); + + const size_t new_len = source_len - pattern_len + replacement_len; + + char * result = (char *)lv_malloc(new_len + 1); + if(!result) { + return NULL; + } + + const size_t before_len = pos - source; + lv_memcpy(result, source, before_len); + lv_memcpy(result + before_len, replacement, replacement_len); + lv_strcpy(result + before_len + replacement_len, pos + pattern_len); + + /* Replace other patterns with whitespaces */ + while((pos = strstr(result, pattern))) { + lv_memset((void *)pos, ' ', pattern_len); + } + result[new_len] = '\0'; + + return result; +} +static lv_rb_t create_shader_map(const lv_opengl_shader_t * shaders, size_t len) +{ + lv_rb_t map; + lv_rb_init(&map, (lv_rb_compare_t)shader_source_compare_cb, + sizeof(lv_opengl_shader_source_t)); + + char pattern[256]; + for(size_t i = 0; i < len; i++) { + if(strlen(shaders[i].source) == 0) { + LV_LOG_WARN("Shader %s at index %zu is empty\n", + shaders[i].name, i); + continue; + } + lv_opengl_shader_source_t value = { + .data = { + .name = shaders[i].name, + .source = shaders[i].source + }, + .src_allocated = false + }; + + for(size_t j = 0; j < len; j++) { + const char * source = value.data.source; + const char * include_name = shaders[j].name; + const char * include_source = shaders[j].source; + const size_t include_name_len = strlen(include_name); + const size_t include_source_len = + strlen(include_source); + if(include_name_len == 0 || include_source_len == 0) { + continue; + } + lv_snprintf(pattern, sizeof(pattern), "#include <%s>", + include_name); + const char * include_pattern = strstr(source, pattern); + if(include_pattern == NULL) { + continue; + } + LV_LOG_TRACE("Replacing %s", pattern); + char * new_source = replace_include(source, pattern, + include_source); + LV_ASSERT_MSG( + new_source, + "Failed to allocate memory to replace shader include with source code"); + + if(value.src_allocated) { + lv_free((void *)value.data.source); + } + value.data.source = new_source; + value.src_allocated = true; + } + if(strstr(value.data.source, "#include")) { + LV_LOG_ERROR( + "Couldn't replace every include in shader %s. Last result:\n%s", + value.data.name, value.data.source); + LV_ASSERT_MSG( + 0, + "Refusing to continue execution with incorrect shaders"); + } + + lv_rb_node_t * node = lv_rb_insert(&map, &value); + LV_ASSERT_MSG(node, + "Failed to allocate memory for shader map entry"); + lv_memcpy(node->data, &value, sizeof(value)); + } + return map; +} + +static bool string_ends_with(const char * value, const char * suffix) +{ + const size_t value_len = strlen(value); + const size_t suffix_len = strlen(suffix); + + if(value_len < suffix_len) { + return false; + } + + return lv_streq(value + value_len - suffix_len, suffix); +} + +#endif /*LV_USE_OPENGLES*/ diff --git a/src/drivers/opengles/opengl_shader/lv_opengl_shader_program.c b/src/drivers/opengles/opengl_shader/lv_opengl_shader_program.c new file mode 100644 index 0000000000..5d94bd79fc --- /dev/null +++ b/src/drivers/opengles/opengl_shader/lv_opengl_shader_program.c @@ -0,0 +1,124 @@ +/** + * @file lv_opengl_shader_program.c + * + */ + +/********************* + * INCLUDES + *********************/ + +#include "lv_opengl_shader_internal.h" + +#if LV_USE_OPENGLES + +#include "../lv_opengles_private.h" +#include "../lv_opengles_debug.h" +#include "../../../misc/lv_assert.h" +#include "../../../stdlib/lv_mem.h" +/********************* + * DEFINES + *********************/ + +#define INVALID_LOCATION 0xFFFFFFFFu + +/********************** + * TYPEDEFS + **********************/ + +/********************** + * STATIC PROTOTYPES + **********************/ + +static void update_uniform_1i(lv_opengl_shader_program_t * program, const char * prop, + int value); + +static void update_uniform_1f(lv_opengl_shader_program_t * program, const char * prop, + float value); + +/********************** + * STATIC VARIABLES + **********************/ + +/********************** + * MACROS + **********************/ + +/********************** + * GLOBAL FUNCTIONS + **********************/ + +lv_opengl_shader_program_t * lv_opengl_shader_program_create(unsigned int _program) +{ + lv_opengl_shader_program_t * program = lv_malloc(sizeof(*program)); + LV_ASSERT_MALLOC(program); + if(!program) { + return NULL; + } + program->update_uniform_1i = &update_uniform_1i; + program->update_uniform_1f = &update_uniform_1f; + program->id = _program; + + return program; +} + +void lv_opengl_shader_program_destroy(lv_opengl_shader_program_t * program) +{ +#ifndef __EMSCRIPTEN__ + GLuint shader_names[10]; + GLsizei shader_count; + GL_CALL(glGetAttachedShaders(program->id, 10, &shader_count, + shader_names)); + + // Detach and delete each shader + for(GLsizei i = 0; i < shader_count; ++i) { + if(shader_names[i] != 0) + GL_CALL(glDetachShader(program->id, shader_names[i])); + } +#endif + + GL_CALL(glDeleteProgram(program->id)); +} + +GLuint lv_opengl_shader_program_get_id(lv_opengl_shader_program_t * program) +{ + LV_ASSERT_NULL(program); + return program->id; +} + +/********************** + * STATIC FUNCTIONS + **********************/ + + +static void update_uniform_1i(lv_opengl_shader_program_t * program, const char * prop, + int value) +{ + GLuint location = glGetUniformLocation(program->id, prop); + LV_ASSERT_FORMAT_MSG(location != INVALID_LOCATION, + "Uniform '%s' not found in program %d", + prop, program->id); + if(location == INVALID_LOCATION) { + LV_LOG_ERROR("Uniform '%s' not found in program %d", prop, + program->id); + return; + } + GL_CALL(glUniform1i(location, value)); +} + +static void update_uniform_1f(lv_opengl_shader_program_t * program, const char * prop, + float value) +{ + GLuint location = glGetUniformLocation(program->id, prop); + + LV_ASSERT_FORMAT_MSG(location != INVALID_LOCATION, + "Uniform '%s' not found in program %d", + prop, program->id); + if(location == INVALID_LOCATION) { + LV_LOG_ERROR("Uniform '%s' not found in program %d", prop, + program->id); + return; + } + GL_CALL(glUniform1f(location, value)); +} + +#endif /*LV_USE_OPENGLES*/ diff --git a/src/drivers/sdl/lv_sdl_keyboard.c b/src/drivers/sdl/lv_sdl_keyboard.c index ac12b7f7c5..c9b1ee9a83 100644 --- a/src/drivers/sdl/lv_sdl_keyboard.c +++ b/src/drivers/sdl/lv_sdl_keyboard.c @@ -11,6 +11,7 @@ #include "../../core/lv_group.h" #include "../../stdlib/lv_string.h" +#include "../../misc/lv_text_private.h" #include "lv_sdl_private.h" /********************* @@ -81,8 +82,14 @@ static void sdl_keyboard_read(lv_indev_t * indev, lv_indev_data_t * data) else if(len > 0) { dev->dummy_read = true; data->state = LV_INDEV_STATE_PRESSED; - data->key = dev->buf[0]; - lv_memmove(dev->buf, dev->buf + 1, len); + data->key = 0; + /*Copy the first UTF8 character from the buffer*/ + uint32_t utf8_len = lv_text_encoded_size(dev->buf); + if(utf8_len == 0) utf8_len = 1; /*Make sure that at least 1 character is read*/ + lv_memcpy(&data->key, dev->buf, utf8_len); + + /*Drop the first character*/ + lv_memmove(dev->buf, dev->buf + utf8_len, len - utf8_len + 1); } } diff --git a/src/drivers/sdl/lv_sdl_mousewheel.h b/src/drivers/sdl/lv_sdl_mousewheel.h index 7ca34bdbbb..dab3dea4b3 100644 --- a/src/drivers/sdl/lv_sdl_mousewheel.h +++ b/src/drivers/sdl/lv_sdl_mousewheel.h @@ -40,4 +40,4 @@ lv_indev_t * lv_sdl_mousewheel_create(void); } /* extern "C" */ #endif -#endif /* LV_DEV_SDL_MOUSEWHEEL_H */ +#endif /* LV_SDL_MOUSEWHEEL_H */ diff --git a/src/drivers/sdl/lv_sdl_window.c b/src/drivers/sdl/lv_sdl_window.c index 4429c943e7..fe19304d31 100644 --- a/src/drivers/sdl/lv_sdl_window.c +++ b/src/drivers/sdl/lv_sdl_window.c @@ -1,5 +1,5 @@ /** - * @file lv_sdl_window.h + * @file lv_sdl_window.c * */ @@ -158,6 +158,12 @@ void lv_sdl_window_set_resizeable(lv_display_t * disp, bool value) SDL_SetWindowResizable(dsc->window, value); } +void lv_sdl_window_set_size(lv_display_t * disp, int32_t hor_res, int32_t ver_res) +{ + lv_sdl_window_t * dsc = lv_display_get_driver_data(disp); + SDL_SetWindowSize(dsc->window, hor_res, ver_res); +} + void lv_sdl_window_set_zoom(lv_display_t * disp, float zoom) { lv_sdl_window_t * dsc = lv_display_get_driver_data(disp); @@ -208,6 +214,20 @@ void * lv_sdl_window_get_renderer(lv_display_t * disp) return dsc->renderer; } +struct SDL_Window * lv_sdl_window_get_window(lv_display_t * disp) +{ + if(!disp) { + LV_LOG_ERROR("invalid display pointer"); + return NULL; + } + lv_sdl_window_t * dsc = lv_display_get_driver_data(disp); + if(!dsc) { + LV_LOG_ERROR("invalid driver data"); + return NULL; + } + return dsc->window; +} + void lv_sdl_quit(void) { if(inited) { @@ -368,7 +388,7 @@ static void window_create(lv_display_t * disp) lv_sdl_window_t * dsc = lv_display_get_driver_data(disp); dsc->zoom = 1.0; - int flag = SDL_WINDOW_RESIZABLE; + int flag = 0; #if LV_SDL_FULLSCREEN flag |= SDL_WINDOW_FULLSCREEN; #endif @@ -430,6 +450,7 @@ static void texture_resize(lv_display_t * disp) lv_sdl_window_t * dsc = lv_display_get_driver_data(disp); dsc->fb1 = sdl_draw_buf_realloc_aligned(dsc->fb1, stride * disp->ver_res); + LV_ASSERT_MALLOC(dsc->fb1); lv_memzero(dsc->fb1, stride * disp->ver_res); if(sdl_render_mode() == LV_DISPLAY_RENDER_MODE_PARTIAL) { diff --git a/src/drivers/sdl/lv_sdl_window.h b/src/drivers/sdl/lv_sdl_window.h index eb78d9b303..e30b458289 100644 --- a/src/drivers/sdl/lv_sdl_window.h +++ b/src/drivers/sdl/lv_sdl_window.h @@ -35,6 +35,8 @@ extern "C" { * TYPEDEFS **********************/ +struct SDL_Window; + /********************** * GLOBAL PROTOTYPES **********************/ @@ -43,6 +45,8 @@ lv_display_t * lv_sdl_window_create(int32_t hor_res, int32_t ver_res); void lv_sdl_window_set_resizeable(lv_display_t * disp, bool value); +void lv_sdl_window_set_size(lv_display_t * disp, int32_t hor_res, int32_t ver_res); + void lv_sdl_window_set_zoom(lv_display_t * disp, float zoom); float lv_sdl_window_get_zoom(lv_display_t * disp); @@ -55,6 +59,8 @@ void * lv_sdl_window_get_renderer(lv_display_t * disp); void lv_sdl_quit(void); +struct SDL_Window * lv_sdl_window_get_window(lv_display_t * disp); + /********************** * MACROS **********************/ diff --git a/src/drivers/uefi/lv_uefi_context.c b/src/drivers/uefi/lv_uefi_context.c index 03d89cef19..56ba2efd4f 100644 --- a/src/drivers/uefi/lv_uefi_context.c +++ b/src/drivers/uefi/lv_uefi_context.c @@ -27,7 +27,7 @@ **********************/ /********************** - * GOLBAL VARIABLES + * GLOBAL VARIABLES **********************/ /********************** diff --git a/src/drivers/uefi/lv_uefi_context.h b/src/drivers/uefi/lv_uefi_context.h index 392d339b20..ed111b2761 100644 --- a/src/drivers/uefi/lv_uefi_context.h +++ b/src/drivers/uefi/lv_uefi_context.h @@ -14,7 +14,7 @@ extern "C" { * INCLUDES *********************/ -#include "../../lvgl.h" +#include "../../lv_conf_internal.h" #if LV_USE_UEFI diff --git a/src/drivers/uefi/lv_uefi_display.c b/src/drivers/uefi/lv_uefi_display.c index 8fa807ee83..38b0cdacc2 100644 --- a/src/drivers/uefi/lv_uefi_display.c +++ b/src/drivers/uefi/lv_uefi_display.c @@ -43,7 +43,7 @@ static void _display_ctx_free(lv_uefi_display_context_t * display_ctx); static bool _display_interface_is_valid(const EFI_GRAPHICS_OUTPUT_PROTOCOL * interface); /********************** - * GOLBAL VARIABLES + * GLOBAL VARIABLES **********************/ /********************** diff --git a/src/drivers/uefi/lv_uefi_indev_keyboard.c b/src/drivers/uefi/lv_uefi_indev_keyboard.c index 83e99b58fe..4c8ad0b036 100644 --- a/src/drivers/uefi/lv_uefi_indev_keyboard.c +++ b/src/drivers/uefi/lv_uefi_indev_keyboard.c @@ -1,5 +1,5 @@ /** - * @file lv_uefi_indev.c + * @file lv_uefi_indev_keyboard.c * */ @@ -10,7 +10,7 @@ #include "../../lvgl.h" #include "../../stdlib/lv_mem.h" #include "../../misc/lv_types.h" -#include "../../misc/lv_text.h" +#include "../../misc/lv_text_private.h" #if LV_USE_UEFI @@ -343,4 +343,4 @@ static uint32_t _key_from_uefi_key(const EFI_KEY_DATA * key) } } -#endif \ No newline at end of file +#endif diff --git a/src/drivers/uefi/lv_uefi_indev_pointer.c b/src/drivers/uefi/lv_uefi_indev_pointer.c index a00b3a03e3..4714a61ee9 100644 --- a/src/drivers/uefi/lv_uefi_indev_pointer.c +++ b/src/drivers/uefi/lv_uefi_indev_pointer.c @@ -1,5 +1,5 @@ /** - * @file lv_uefi_indev.c + * @file lv_uefi_indev_pointer.c * */ @@ -10,7 +10,7 @@ #include "../../lvgl.h" #include "../../stdlib/lv_mem.h" #include "../../misc/lv_types.h" -#include "../../misc/lv_text.h" +#include "../../misc/lv_text_private.h" #if LV_USE_UEFI @@ -282,4 +282,4 @@ static void _simple_pointer_read(lv_uefi_simple_pointer_context_t * indev_ctx, *was_pressed = state.LeftButton; } -#endif \ No newline at end of file +#endif diff --git a/src/drivers/uefi/lv_uefi_indev_touch.c b/src/drivers/uefi/lv_uefi_indev_touch.c index 3fad4f0876..3ac227e50f 100644 --- a/src/drivers/uefi/lv_uefi_indev_touch.c +++ b/src/drivers/uefi/lv_uefi_indev_touch.c @@ -1,5 +1,5 @@ /** - * @file lv_uefi_indev.c + * @file lv_uefi_indev_touch.c * */ @@ -10,7 +10,7 @@ #include "../../lvgl.h" #include "../../stdlib/lv_mem.h" #include "../../misc/lv_types.h" -#include "../../misc/lv_text.h" +#include "../../misc/lv_text_private.h" #if LV_USE_UEFI @@ -287,4 +287,4 @@ static void _absolute_pointer_read(lv_uefi_absolute_pointer_context_t * indev_ct *was_pressed = (state.ActiveButtons & EFI_ABSP_TouchActive) != 0; } -#endif \ No newline at end of file +#endif diff --git a/src/drivers/uefi/lv_uefi_private.c b/src/drivers/uefi/lv_uefi_private.c index 2d06a90fb7..e8c69769ef 100644 --- a/src/drivers/uefi/lv_uefi_private.c +++ b/src/drivers/uefi/lv_uefi_private.c @@ -26,7 +26,7 @@ **********************/ /********************** - * GOLBAL VARIABLES + * GLOBAL VARIABLES **********************/ EFI_HANDLE gLvEfiImageHandle = NULL; EFI_SYSTEM_TABLE * gLvEfiST = NULL; diff --git a/src/drivers/wayland/lv_wayland.c b/src/drivers/wayland/lv_wayland.c index 3f6bdfe2f5..10cee82b9b 100644 --- a/src/drivers/wayland/lv_wayland.c +++ b/src/drivers/wayland/lv_wayland.c @@ -10,20 +10,34 @@ #if LV_USE_WAYLAND -#if LV_WAYLAND_BUF_COUNT < 1 || LV_WAYLAND_BUF_COUNT > 2 - #error "Invalid LV_WAYLAND_BUF_COUNT. Expected either 1 or 2" +#if LV_USE_G2D + #if LV_USE_ROTATE_G2D + #if !LV_WAYLAND_USE_DMABUF + #error "LV_USE_ROTATE_G2D is supported only with DMABUF" + #endif + #if LV_WAYLAND_BUF_COUNT != 3 + #error "LV_WAYLAND_BUF_COUNT must be 3 when LV_USE_ROTATE_G2D is enabled" + #endif + #define LV_WAYLAND_CHECK_BUF_COUNT 0 + #endif #endif -#if !LV_WAYLAND_USE_DMABUF && LV_WAYLAND_BUF_COUNT != 1 - #error "Wayland doesn't support more than 1 LV_WAYLAND_BUF_COUNT without DMABUF" -#endif +#ifndef LV_WAYLAND_CHECK_BUF_COUNT + #if LV_WAYLAND_BUF_COUNT < 1 || LV_WAYLAND_BUF_COUNT > 2 + #error "Invalid LV_WAYLAND_BUF_COUNT. Expected either 1 or 2" + #endif + + #if !LV_WAYLAND_USE_DMABUF && LV_WAYLAND_BUF_COUNT != 1 + #error "Wayland doesn't support more than 1 LV_WAYLAND_BUF_COUNT without DMABUF" + #endif -#if LV_WAYLAND_USE_DMABUF && !LV_USE_DRAW_G2D - #error "LV_WAYLAND_USE_DMABUF requires LV_USE_DRAW_G2D" + #if LV_WAYLAND_USE_DMABUF && LV_WAYLAND_BUF_COUNT != 2 + #error "Wayland with DMABUF only supports 2 LV_WAYLAND_BUF_COUNT" + #endif #endif -#if LV_WAYLAND_USE_DMABUF && LV_WAYLAND_WINDOW_DECORATIONS - #error "LV_WAYLAND_USE_DMABUF doesn't support LV_WAYLAND_WINDOW_DECORATIONS" +#if LV_WAYLAND_USE_DMABUF && !LV_USE_G2D + #error "LV_WAYLAND_USE_DMABUF requires LV_USE_G2D" #endif #ifndef LV_DISPLAY_RENDER_MODE_PARTIAL @@ -92,13 +106,29 @@ static void handle_output(void); static uint32_t tick_get_cb(void); +static void output_scale(void * data, struct wl_output * output, int32_t factor); +static void output_mode(void * data, struct wl_output * output, uint32_t flags, int32_t width, int32_t height, + int32_t refresh); +static void output_done(void * data, struct wl_output * output); +static void output_geometry(void * data, struct wl_output * output, int32_t x, int32_t y, int32_t physical_width, + int32_t physical_height, int32_t subpixel, const char * make, const char * model, int32_t transform); + /********************** * STATIC VARIABLES **********************/ static bool is_wayland_initialized = false; -static const struct wl_registry_listener registry_listener = {.global = handle_global, - .global_remove = handle_global_remove + +static const struct wl_registry_listener registry_listener = { + .global = handle_global, + .global_remove = handle_global_remove +}; + +static const struct wl_output_listener output_listener = { + .geometry = output_geometry, + .mode = output_mode, + .done = output_done, + .scale = output_scale }; /********************** @@ -126,15 +156,31 @@ uint32_t lv_wayland_timer_handler(void) LV_LOG_TRACE("handle timer frame: %d", window->frame_counter); if(window != NULL && window->resize_pending) { +#if LV_WAYLAND_USE_DMABUF + /* Check surface configuration state before resizing */ + if(!window->surface_configured) { + LV_LOG_TRACE("Deferring resize - surface not configured yet"); + continue; + } +#endif + LV_LOG_TRACE("Processing resize: %dx%d -> %dx%d", + window->width, window->height, + window->resize_width, window->resize_height); + if(lv_wayland_window_resize(window, window->resize_width, window->resize_height) == LV_RESULT_OK) { window->resize_width = window->width; window->resize_height = window->height; window->resize_pending = false; - +#if LV_WAYLAND_USE_DMABUF + /* Reset synchronization flags after successful resize */ + window->surface_configured = false; + window->dmabuf_resize_pending = false; +#endif + LV_LOG_TRACE("Window resize completed successfully: %dx%d", + window->width, window->height); } else { - - LV_LOG_TRACE("Failed to resize window frame: %d", window->frame_counter); + LV_LOG_ERROR("Failed to resize window frame: %d", window->frame_counter); } } else if(window->shall_close == true) { @@ -266,11 +312,7 @@ void lv_wayland_deinit(void) lv_wayland_dmabuf_deinit(&lv_wl_ctx.dmabuf_ctx); #endif -#if LV_WAYLAND_WL_SHELL - lv_wayland_wl_shell_deinit(); -#elif LV_WAYLAND_XDG_SHELL lv_wayland_xdg_shell_deinit(); -#endif if(lv_wl_ctx.wl_seat) { wl_seat_destroy(lv_wl_ctx.wl_seat); @@ -293,7 +335,7 @@ void lv_wayland_deinit(void) void lv_wayland_wait_flush_cb(lv_display_t * disp) { - struct window * window = lv_display_get_user_data(disp); + struct window * window = lv_display_get_driver_data(disp); /* TODO: Figure out why we need this */ if(window->frame_counter == 0) { return; @@ -305,9 +347,86 @@ void lv_wayland_wait_flush_cb(lv_display_t * disp) } } +void lv_wayland_event_cb(lv_event_t * e) +{ + lv_event_code_t code = lv_event_get_code(e); + struct window * window = lv_event_get_user_data(e); + lv_display_t * display = (lv_display_t *) lv_event_get_target(e); + + switch(code) { + case LV_EVENT_RESOLUTION_CHANGED: { + uint32_t rotation = lv_display_get_rotation(window->lv_disp); + int width, height; + if(rotation == LV_DISPLAY_ROTATION_90 || rotation == LV_DISPLAY_ROTATION_270) { + width = lv_display_get_vertical_resolution(display); + height = lv_display_get_horizontal_resolution(display); + } + else { + width = lv_display_get_horizontal_resolution(display); + height = lv_display_get_vertical_resolution(display); + } +#if LV_WAYLAND_USE_DMABUF + dmabuf_ctx_t * context = &window->wl_ctx->dmabuf_ctx; + lv_wayland_dmabuf_resize_window(context, window, width, height); +#else + lv_wayland_shm_resize_window(&window->wl_ctx->shm_ctx, window, width, height); +#endif + break; + } + default: + return; + } +} + /********************** * STATIC FUNCTIONS **********************/ +// --- wl_output listener callbacks --- +static void output_geometry(void * data, struct wl_output * output, int32_t x, int32_t y, int32_t physical_width, + int32_t physical_height, + int32_t subpixel, const char * make, const char * model, int32_t transform) +{ + LV_UNUSED(output); + LV_UNUSED(x); + LV_UNUSED(y); + LV_UNUSED(physical_width); + LV_UNUSED(physical_height); + LV_UNUSED(subpixel); + LV_UNUSED(make); + LV_UNUSED(transform); + + struct output_info * info = data; + snprintf(info->name, sizeof(info->name), "%s", model); +} + +static void output_mode(void * data, struct wl_output * wl_output, uint32_t flags, int32_t width, int32_t height, + int32_t refresh) +{ + LV_UNUSED(wl_output); + + struct output_info * info = data; + + if(flags & WL_OUTPUT_MODE_CURRENT) { + info->height = height; + info->width = width; + info->refresh = refresh; + info->flags = flags; + } +} + +static void output_done(void * data, struct wl_output * output) +{ + /* Called when all geometry/mode info for this output has been sent */ + LV_UNUSED(data); + LV_UNUSED(output); +} + +static void output_scale(void * data, struct wl_output * output, int32_t factor) +{ + LV_UNUSED(output); + struct output_info * info = data; + info->scale = factor; +} static uint32_t tick_get_cb(void) { @@ -339,18 +458,20 @@ static void handle_global(void * data, struct wl_registry * registry, uint32_t n app->wl_seat = wl_registry_bind(app->registry, name, &wl_seat_interface, 1); wl_seat_add_listener(app->wl_seat, lv_wayland_seat_get_listener(), app); } -#if LV_WAYLAND_WL_SHELL - else if(strcmp(interface, wl_shell_interface.name) == 0) { - app->wl_shell = wl_registry_bind(registry, name, &wl_shell_interface, 1); - } -#endif -#if LV_WAYLAND_XDG_SHELL else if(strcmp(interface, xdg_wm_base_interface.name) == 0) { /* supporting version 2 of the XDG protocol - ensures greater compatibility */ app->xdg_wm = wl_registry_bind(app->registry, name, &xdg_wm_base_interface, 2); xdg_wm_base_add_listener(app->xdg_wm, lv_wayland_xdg_shell_get_wm_base_listener(), app); } -#endif + else if(strcmp(interface, wl_output_interface.name) == 0) { + if(app->wl_output_count < LV_WAYLAND_MAX_OUTPUTS) { + memset(&app->outputs[app->wl_output_count], 0, sizeof(struct output_info)); + struct wl_output * out = wl_registry_bind(registry, name, &wl_output_interface, 1); + app->outputs[app->wl_output_count].wl_output = out; + wl_output_add_listener(out, &output_listener, &app->outputs[app->wl_output_count].wl_output); + app->wl_output_count++; + } + } #if LV_WAYLAND_USE_DMABUF else if(strcmp(interface, zwp_linux_dmabuf_v1_interface.name) == 0) { lv_wayland_dmabuf_set_interface(&app->dmabuf_ctx, app->registry, name, interface, version); diff --git a/src/drivers/wayland/lv_wayland.h b/src/drivers/wayland/lv_wayland.h index 9d6ebf2406..178e0ab6bd 100644 --- a/src/drivers/wayland/lv_wayland.h +++ b/src/drivers/wayland/lv_wayland.h @@ -58,4 +58,4 @@ int lv_wayland_get_fd(void); } /* extern "C" */ #endif -#endif /* WAYLAND_H */ +#endif /* LV_WAYLAND_H */ diff --git a/src/drivers/wayland/lv_wayland_private.h b/src/drivers/wayland/lv_wayland_private.h index 374eb0bab8..92b3a08706 100644 --- a/src/drivers/wayland/lv_wayland_private.h +++ b/src/drivers/wayland/lv_wayland_private.h @@ -21,11 +21,11 @@ extern "C" { #include "lv_wayland_smm.h" #include #include -#if !LV_WAYLAND_WL_SHELL -#include "wayland_xdg_shell.h" -#define LV_WAYLAND_XDG_SHELL 1 -#else -#define LV_WAYLAND_XDG_SHELL 0 +#include + +#if LV_WAYLAND_USE_DMABUF +#include +#include #endif /********************* @@ -33,6 +33,7 @@ extern "C" { *********************/ #define LV_WAYLAND_DEFAULT_CURSOR_NAME "left_ptr" +#define LV_WAYLAND_MAX_OUTPUTS 8 #define LVGL_DRAW_BUFFER_DIV (8) #define DMG_CACHE_CAPACITY (32) @@ -62,10 +63,8 @@ extern "C" { enum object_type { OBJECT_TITLEBAR = 0, OBJECT_BUTTON_CLOSE, -#if LV_WAYLAND_XDG_SHELL OBJECT_BUTTON_MAXIMIZE, OBJECT_BUTTON_MINIMIZE, -#endif OBJECT_BORDER_TOP, OBJECT_BORDER_BOTTOM, OBJECT_BORDER_LEFT, @@ -77,6 +76,10 @@ enum object_type { #define LAST_DECORATION (OBJECT_BORDER_RIGHT) #define NUM_DECORATIONS (LAST_DECORATION - FIRST_DECORATION + 1) +#if LV_WAYLAND_USE_DMABUF +#define MAX_BUFFER_PLANES 4 +#endif + struct window; struct input { struct { @@ -97,6 +100,11 @@ struct input { lv_indev_touch_data_t touches[10]; uint8_t touch_event_cnt; uint8_t primary_id; +#else + struct { + lv_point_t point; + lv_indev_state_t state; + } touch; #endif }; @@ -127,14 +135,24 @@ typedef struct { struct buffer * buffers; struct zwp_linux_dmabuf_v1 * handler; uint32_t format; + uint8_t last_used; } dmabuf_ctx_t; typedef struct { - lv_draw_buf_t * lv_draw_buf; struct wl_shm * handler; uint32_t format; } shm_ctx_t; +struct output_info { + struct wl_output * wl_output; + char name[64]; + int width; + int height; + int refresh; + int scale; + int flags; +}; + struct lv_wayland_context { struct wl_display * display; struct wl_registry * registry; @@ -144,18 +162,14 @@ struct lv_wayland_context { struct wl_cursor_theme * cursor_theme; struct wl_surface * cursor_surface; shm_ctx_t shm_ctx; + struct output_info outputs[LV_WAYLAND_MAX_OUTPUTS]; + uint8_t wl_output_count; #if LV_WAYLAND_USE_DMABUF dmabuf_ctx_t dmabuf_ctx; #endif -#if LV_WAYLAND_WL_SHELL - struct wl_shell * wl_shell; -#endif - -#if LV_WAYLAND_XDG_SHELL struct xdg_wm_base * xdg_wm; -#endif #ifdef LV_WAYLAND_WINDOW_DECORATIONS bool opt_disable_decorations; @@ -183,19 +197,16 @@ struct window { lv_indev_t * lv_indev_touch; lv_indev_t * lv_indev_keyboard; - lv_wayland_display_close_f_t close_cb; + lv_draw_buf_t * lv_draw_buf; + lv_wayland_display_close_f_t close_cb; struct lv_wayland_context * wl_ctx; -#if LV_WAYLAND_WL_SHELL - struct wl_shell_surface * wl_shell_surface; -#endif - -#if LV_WAYLAND_XDG_SHELL + /* The current physical assigned output */ + struct wl_output * assigned_output; struct xdg_surface * xdg_surface; struct xdg_toplevel * xdg_toplevel; uint32_t wm_capabilities; -#endif struct graphic_object * body; struct { @@ -222,8 +233,36 @@ struct window { bool maximized; bool fullscreen; uint32_t frame_counter; + bool is_window_configured; + +#if LV_WAYLAND_USE_DMABUF + /* XDG/DMABUF synchronization fields */ + bool dmabuf_resize_pending; + bool surface_configured; + bool configure_acknowledged; + uint32_t configure_serial; +#if LV_WAYLAND_WINDOW_DECORATIONS + struct buffer * decorators_buf[8]; +#endif +#endif }; +#if LV_WAYLAND_USE_DMABUF +struct buffer { + int busy; + struct window * window; + int plane_count; + int dmabuf_fds[MAX_BUFFER_PLANES]; + uint32_t strides[MAX_BUFFER_PLANES]; + uint32_t offsets[MAX_BUFFER_PLANES]; + struct wl_buffer * buffer; + uint32_t width; + uint32_t height; + void * buf_base[MAX_BUFFER_PLANES]; + lv_draw_buf_t * lv_draw_buf; +}; +#endif + /********************** * GLOBAL PROTOTYPES **********************/ @@ -241,6 +280,8 @@ extern struct lv_wayland_context lv_wl_ctx; void lv_wayland_init(void); void lv_wayland_deinit(void); void lv_wayland_wait_flush_cb(lv_display_t * disp); +void lv_wayland_event_cb(lv_event_t * e); + /********************** * Window **********************/ @@ -256,7 +297,7 @@ void lv_wayland_window_decoration_detach_all(struct window * window); bool lv_wayland_window_decoration_create(struct window * window, struct graphic_object * decoration, int window_width, int window_height); bool lv_wayland_window_decoration_attach(struct window * window, struct graphic_object * decoration, - smm_buffer_t * decoration_buffer, struct graphic_object * parent); + void * decoration_buffer, struct graphic_object * parent); void lv_wayland_window_decoration_detach(struct window * window, struct graphic_object * decoration); #endif @@ -264,27 +305,18 @@ void lv_wayland_window_decoration_detach(struct window * window, struct graphic_ * Window Management **********************/ -#if LV_WAYLAND_WL_SHELL -lv_result_t lv_wayland_wl_shell_create_window(struct lv_wayland_context * app, struct window * window, - const char * title); -const struct wl_shell_surface_listener * lv_wayland_wl_shell_get_listener(void); -void lv_wayland_wl_shell_handle_pointer_event(struct lv_wayland_context * app, uint32_t serial, uint32_t button, - uint32_t state); -lv_result_t lv_wayland_wl_shell_set_maximized(struct window * window, bool maximized); -lv_result_t lv_wayland_wl_shell_set_minimized(struct window * window); -lv_result_t lv_wayland_wl_shell_set_fullscreen(struct window * window, bool fullscreen); -lv_result_t lv_wayland_wl_shell_destroy_window(struct window * window); -void lv_wayland_wl_shell_deinit(void); -#elif LV_WAYLAND_XDG_SHELL - const struct xdg_surface_listener * lv_wayland_xdg_shell_get_surface_listener(void); const struct xdg_toplevel_listener * lv_wayland_xdg_shell_get_toplevel_listener(void); const struct xdg_wm_base_listener * lv_wayland_xdg_shell_get_wm_base_listener(void); lv_result_t lv_wayland_xdg_shell_set_maximized(struct window * window, bool maximized); lv_result_t lv_wayland_xdg_shell_set_minimized(struct window * window); -lv_result_t lv_wayland_xdg_shell_set_fullscreen(struct window * window, bool fullscreen); +lv_result_t lv_wayland_xdg_shell_set_fullscreen(struct window * window, bool fullscreen, struct wl_output * output); +#if LV_WAYLAND_USE_DMABUF +void lv_wayland_xdg_shell_ack_configure(struct window * window, uint32_t serial); +#endif lv_result_t lv_wayland_xdg_shell_create_window(struct lv_wayland_context * app, struct window * window, const char * title); +void lv_wayland_xdg_shell_configure_surface(struct window * window); lv_result_t lv_wayland_xdg_shell_destroy_window_toplevel(struct window * window); lv_result_t lv_wayland_xdg_shell_destroy_window_surface(struct window * window); void lv_wayland_xdg_shell_handle_pointer_event(struct lv_wayland_context * app, uint32_t serial, uint32_t button, @@ -292,7 +324,6 @@ void lv_wayland_xdg_shell_handle_pointer_event(struct lv_wayland_context * app, const char * lv_wayland_xdg_shell_get_cursor_name(const struct lv_wayland_context * app); void lv_wayland_xdg_shell_deinit(void); -#endif /********************** * SHM @@ -303,7 +334,7 @@ void lv_wayland_shm_set_interface(shm_ctx_t * context, struct wl_registry * regi struct graphic_object * lv_wayland_shm_on_graphical_object_creation(shm_ctx_t * context, struct graphic_object * obj); void lv_wayland_shm_on_graphical_object_destruction(shm_ctx_t * context, struct graphic_object * obj); -lv_result_t lv_wayland_shm_set_draw_buffers(shm_ctx_t * context, lv_display_t * display); +lv_result_t lv_wayland_shm_set_draw_buffers(shm_ctx_t * context, lv_display_t * display, struct window * window); lv_result_t lv_wayland_shm_create_draw_buffers(shm_ctx_t * context, struct window * window); lv_result_t lv_wayland_shm_resize_window(shm_ctx_t * context, struct window * window, int32_t width, int32_t height); lv_result_t lv_wayland_shm_is_ready(shm_ctx_t * context); @@ -328,14 +359,17 @@ struct graphic_object * lv_wayland_dmabuf_on_graphical_object_creation(dmabuf_ct void lv_wayland_dmabuf_on_graphical_object_destruction(dmabuf_ctx_t * context, struct graphic_object * obj); lv_result_t lv_wayland_dmabuf_set_draw_buffers(dmabuf_ctx_t * context, lv_display_t * display); lv_result_t lv_wayland_dmabuf_create_draw_buffers(dmabuf_ctx_t * context, struct window * window); -lv_result_t lv_wayland_dmabuf_resize_window(dmabuf_ctx_t * context, struct window * window); +lv_result_t lv_wayland_dmabuf_resize_window(dmabuf_ctx_t * context, struct window * window, int width, int height); lv_result_t lv_wayland_dmabuf_is_ready(dmabuf_ctx_t * context); - +void destroy_decorators_buf(struct window * window, struct graphic_object * decoration); void lv_wayland_dmabuf_destroy_draw_buffers(dmabuf_ctx_t * context, struct window * window); void lv_wayland_dmabuf_initalize_context(dmabuf_ctx_t * context); void lv_wayland_dmabuf_deinit(dmabuf_ctx_t * context); void lv_wayland_dmabuf_flush_full_mode(lv_display_t * disp, const lv_area_t * area, unsigned char * color_p); +#if LV_WAYLAND_WINDOW_DECORATIONS +struct buffer * dmabuf_acquire_pool_buffer(struct window * window, struct graphic_object * decoration); +#endif /********************** * SME **********************/ diff --git a/src/drivers/wayland/lv_wl_dmabuf.c b/src/drivers/wayland/lv_wl_dmabuf.c index ce6cb9bb8e..0d8ff0b44a 100644 --- a/src/drivers/wayland/lv_wl_dmabuf.c +++ b/src/drivers/wayland/lv_wl_dmabuf.c @@ -11,9 +11,14 @@ #include #include #include +#include #include #include #include "../../draw/nxp/g2d/lv_g2d_utils.h" +#include +#include +#include +#include /********************* * INCLUDES @@ -27,40 +32,48 @@ * TYPEDEFS **********************/ -#define MAX_BUFFER_PLANES 4 - -struct buffer { - int busy; - -#if LV_WAYLAND_USE_DMABUF - struct window * window; - int plane_count; - - int dmabuf_fds[MAX_BUFFER_PLANES]; - uint32_t strides[MAX_BUFFER_PLANES]; - uint32_t offsets[MAX_BUFFER_PLANES]; - struct wl_buffer * buffer; -#endif - - void * buf_base[MAX_BUFFER_PLANES]; - lv_draw_buf_t * lv_draw_buf; -}; - /********************** * STATIC PROTOTYPES **********************/ +static void dmabuf_done(void * data, struct zwp_linux_dmabuf_feedback_v1 * zwp_linux_dmabuf_feedback); +static void dmabuf_format_table(void * data, struct zwp_linux_dmabuf_feedback_v1 * zwp_linux_dmabuf_feedback, + int32_t fd, uint32_t size); +static void dmabuf_main_device(void * data, struct zwp_linux_dmabuf_feedback_v1 * zwp_linux_dmabuf_feedback, + struct wl_array * device); +static void dmabuf_tranche_done(void * data, struct zwp_linux_dmabuf_feedback_v1 * zwp_linux_dmabuf_feedback); +static void dmabuf_tranche_target_device(void * data, struct zwp_linux_dmabuf_feedback_v1 * zwp_linux_dmabuf_feedback, + struct wl_array * device); +static void dmabuf_tranche_formats(void * data, struct zwp_linux_dmabuf_feedback_v1 * zwp_linux_dmabuf_feedback, + struct wl_array * indices); +static void dmabuf_tranche_flags(void * data, struct zwp_linux_dmabuf_feedback_v1 * zwp_linux_dmabuf_feedback, + uint32_t flags); static void dmabuf_modifiers(void * data, struct zwp_linux_dmabuf_v1 * zwp_linux_dmabuf, uint32_t format, uint32_t modifier_hi, uint32_t modifier_lo); static void dmabuf_format(void * data, struct zwp_linux_dmabuf_v1 * zwp_linux_dmabuf, uint32_t format); -static struct buffer * dmabuf_acquire_buffer(dmabuf_ctx_t * context, unsigned char * color_p); -static struct buffer * lv_wayland_dmabuf_create_draw_buffers_internal(struct window * window); +static struct buffer * lv_wayland_dmabuf_create_draw_buffers_internal(struct window * window, int width, int height); static void buffer_free(struct buffer * buf); +static void dmabuf_wait_swap_buf(lv_display_t * disp); +#if !LV_USE_ROTATE_G2D + static struct buffer * dmabuf_acquire_buffer(dmabuf_ctx_t * context, unsigned char * color_p); +#else + static struct buffer * get_next_buffer(dmabuf_ctx_t * context); +#endif /********************** * STATIC VARIABLES **********************/ +static const struct zwp_linux_dmabuf_feedback_v1_listener dmabuf_listener_v5 = { + .done = dmabuf_done, + .format_table = dmabuf_format_table, + .main_device = dmabuf_main_device, + .tranche_done = dmabuf_tranche_done, + .tranche_target_device = dmabuf_tranche_target_device, + .tranche_formats = dmabuf_tranche_formats, + .tranche_flags = dmabuf_tranche_flags, +}; + static const struct zwp_linux_dmabuf_v1_listener dmabuf_listener_v3 = {.format = dmabuf_format, .modifier = dmabuf_modifiers }; @@ -82,9 +95,14 @@ void lv_wayland_dmabuf_initalize_context(dmabuf_ctx_t * context) { memset(context, 0, sizeof(*context)); context->format = DRM_FORMAT_INVALID; + context->last_used = 0; } lv_result_t lv_wayland_dmabuf_set_draw_buffers(dmabuf_ctx_t * context, lv_display_t * display) { + if(LV_USE_ROTATE_G2D == 1) { + lv_display_set_draw_buffers(display, context->buffers[2].lv_draw_buf, NULL); + return LV_RESULT_OK; + } if(LV_WAYLAND_BUF_COUNT == 2) { lv_display_set_draw_buffers(display, context->buffers[0].lv_draw_buf, context->buffers[1].lv_draw_buf); return LV_RESULT_OK; @@ -100,13 +118,14 @@ void lv_wayland_dmabuf_set_interface(dmabuf_ctx_t * context, struct wl_registry const char * interface, uint32_t version) { LV_UNUSED(interface); - if(version > 3) { - LV_LOG_WARN("Unsupported DMABUF version %d. Using version 3 instead", version); - version = 3; - } context->handler = wl_registry_bind(registry, name, &zwp_linux_dmabuf_v1_interface, version); - if(version < 3) { + + if(version >= 4) { + struct zwp_linux_dmabuf_feedback_v1 * feedback = zwp_linux_dmabuf_v1_get_default_feedback(context->handler); + zwp_linux_dmabuf_feedback_v1_add_listener(feedback, &dmabuf_listener_v5, context); + } + else if(version < 3) { zwp_linux_dmabuf_v1_add_listener(context->handler, &dmabuf_listener, context); } else if(version == 3) { @@ -144,24 +163,69 @@ void lv_wayland_dmabuf_on_graphical_object_destruction(dmabuf_ctx_t * context, s LV_UNUSED(obj); } +static void dmabuf_wait_swap_buf(lv_display_t * disp) +{ + struct window * window = lv_display_get_driver_data(disp); + + if(window->frame_counter == 0) { + return; + } + +#if LV_USE_ROTATE_G2D + int buf_nr = (window->wl_ctx->dmabuf_ctx.last_used + 1) % (LV_WAYLAND_BUF_COUNT - 1); +#else + int buf_nr = (window->wl_ctx->dmabuf_ctx.last_used + 1) % LV_WAYLAND_BUF_COUNT; +#endif + + while(window->wl_ctx->dmabuf_ctx.buffers[buf_nr].busy) { + wl_display_roundtrip(lv_wl_ctx.display); + usleep(500); /* Sleep for 0.5ms to avoid busy waiting */ + } +} + void lv_wayland_dmabuf_flush_full_mode(lv_display_t * disp, const lv_area_t * area, unsigned char * color_p) { - struct window * window = lv_display_get_user_data(disp); - struct buffer * buf = dmabuf_acquire_buffer(&window->wl_ctx->dmabuf_ctx, color_p); + struct window * window = lv_display_get_driver_data(disp); + struct buffer * buf; + int32_t src_width = lv_area_get_width(area); + int32_t src_height = lv_area_get_height(area); + uint32_t rotation = lv_display_get_rotation(window->lv_disp); +#if LV_USE_ROTATE_G2D + LV_UNUSED(color_p); + buf = get_next_buffer(&window->wl_ctx->dmabuf_ctx); + if(rotation == LV_DISPLAY_ROTATION_90 || rotation == LV_DISPLAY_ROTATION_270) { + src_width = lv_area_get_height(area); + src_height = lv_area_get_width(area); + } +#else + buf = dmabuf_acquire_buffer(&window->wl_ctx->dmabuf_ctx, color_p); +#endif if(!buf) { LV_LOG_ERROR("Failed to acquire a wayland window body buffer"); return; } - int32_t src_width = lv_area_get_width(area); - int32_t src_height = lv_area_get_height(area); - lv_draw_buf_invalidate_cache(buf->lv_draw_buf, NULL); +#if LV_USE_ROTATE_G2D + lv_draw_buf_invalidate_cache(window->wl_ctx->dmabuf_ctx.buffers[2].lv_draw_buf, NULL); +#endif + const bool force_full_flush = LV_WAYLAND_RENDER_MODE == LV_DISPLAY_RENDER_MODE_DIRECT && + rotation != LV_DISPLAY_ROTATION_0; /* Mark surface damage */ - wl_surface_damage(window->body->surface, area->x1, area->y1, src_width, src_height); + if(!force_full_flush) { + wl_surface_damage(window->body->surface, area->x1, area->y1, src_width, src_height); + } if(lv_display_flush_is_last(disp)) { + if(force_full_flush) { + wl_surface_damage(window->body->surface, 0, 0, lv_display_get_original_horizontal_resolution(disp), + lv_display_get_original_vertical_resolution(disp)); + } +#if LV_USE_ROTATE_G2D + g2d_rotate(window->wl_ctx->dmabuf_ctx.buffers[2].lv_draw_buf, buf->lv_draw_buf, window->width, window->height, + lv_display_get_rotation(window->lv_disp), lv_display_get_color_format(window->lv_disp)); +#endif /* Finally, attach buffer and commit to surface */ wl_surface_attach(window->body->surface, buf->buffer, 0, 0); wl_surface_commit(window->body->surface); @@ -169,8 +233,14 @@ void lv_wayland_dmabuf_flush_full_mode(lv_display_t * disp, const lv_area_t * ar struct wl_callback * cb = wl_surface_frame(window->body->surface); wl_callback_add_listener(cb, lv_wayland_window_get_wl_surface_frame_listener(), window->body); - buf->busy = 1; window->flush_pending = true; + dmabuf_wait_swap_buf(disp); + } + else { + /* Not the last frame yet, so tell lvgl to keep going + * For the last frame, we wait for the compositor instead */ + buf->busy = 0; + lv_display_flush_ready(disp); } return; @@ -213,22 +283,45 @@ static const struct zwp_linux_buffer_params_v1_listener params_listener = {.crea .failed = create_failed }; -lv_result_t lv_wayland_dmabuf_resize_window(dmabuf_ctx_t * context, struct window * window) +lv_result_t lv_wayland_dmabuf_resize_window(dmabuf_ctx_t * context, struct window * window, int width, int height) { - struct buffer * buffers = lv_wayland_dmabuf_create_draw_buffers_internal(window); - if(!buffers) { + /* Don't attempt to create buffers with invalid dimensions */ + if(width <= 0 || height <= 0) { + LV_LOG_ERROR("DMABUF resize failed: invalid dimensions %dx%d", width, height); return LV_RESULT_INVALID; } + lv_wayland_dmabuf_destroy_draw_buffers(context, window); + struct buffer * buffers = lv_wayland_dmabuf_create_draw_buffers_internal(window, width, height); + if(!buffers) { + LV_LOG_ERROR("Failed to create DMABUF buffers for %dx%d", width, height); + return LV_RESULT_INVALID; + } + context->buffers = buffers; lv_wayland_dmabuf_set_draw_buffers(context, window->lv_disp); + + /* Clear DMABUF resize pending flag and acknowledge XDG configure if needed */ + window->dmabuf_resize_pending = false; + + if(window->surface_configured && window->configure_serial > 0 && !window->configure_acknowledged) { + lv_wayland_xdg_shell_ack_configure(window, window->configure_serial); + window->configure_acknowledged = true; + window->configure_serial = 0; /* Reset after acknowledgment */ + } + else if(window->configure_acknowledged) { + LV_LOG_TRACE("XDG configure already acknowledged, skipping duplicate acknowledgment"); + window->configure_serial = 0; /* Reset the serial */ + } + + LV_LOG_TRACE("DMABUF resize completed successfully: %dx%d", width, height); return LV_RESULT_OK; } lv_result_t lv_wayland_dmabuf_create_draw_buffers(dmabuf_ctx_t * context, struct window * window) { - struct buffer * buffers = lv_wayland_dmabuf_create_draw_buffers_internal(window); + struct buffer * buffers = lv_wayland_dmabuf_create_draw_buffers_internal(window, window->width, window->height); if(!buffers) { return LV_RESULT_INVALID; } @@ -245,54 +338,77 @@ void lv_wayland_dmabuf_destroy_draw_buffers(dmabuf_ctx_t * context, struct windo } for(int i = 0; i < LV_WAYLAND_BUF_COUNT; i++) { buffer_free(&context->buffers[i]); - return; } free(context->buffers); context->buffers = NULL; } -static struct buffer * lv_wayland_dmabuf_create_draw_buffers_internal(struct window * window) +uint32_t lv_wayland_dmabuf_get_format(struct window * window) +{ + uint32_t drmcf = 0; + lv_color_format_t format = lv_display_get_color_format(window->lv_disp); + if(format == LV_COLOR_FORMAT_UNKNOWN) { + return DRM_FORMAT_ARGB8888; /* Default to ARGB8888 */ + } + + switch(format) { + case LV_COLOR_FORMAT_XRGB8888: + drmcf = DRM_FORMAT_XRGB8888; + break; + case LV_COLOR_FORMAT_ARGB8888: + drmcf = DRM_FORMAT_ARGB8888; + break; + case LV_COLOR_FORMAT_RGB565: + drmcf = DRM_FORMAT_RGB565; + break; + default: + drmcf = DRM_FORMAT_ARGB8888; + } + + return drmcf; +} + +static struct buffer * lv_wayland_dmabuf_create_draw_buffers_internal(struct window * window, int width, int height) { const uint32_t flags = 0; struct zwp_linux_buffer_params_v1 * params; - const int stride = lv_draw_buf_width_to_stride(window->width, lv_display_get_color_format(window->lv_disp)); + uint32_t drmcf = lv_wayland_dmabuf_get_format(window); + int stride = lv_draw_buf_width_to_stride(window->width, lv_display_get_color_format(window->lv_disp)); struct buffer * buffers = (struct buffer *)calloc(LV_WAYLAND_BUF_COUNT, sizeof(struct buffer)); LV_ASSERT_MALLOC(buffers); for(int i = 0; i < LV_WAYLAND_BUF_COUNT; i++) { - uint32_t drmcf = 0; + uint32_t w = width; + uint32_t h = height; +#if LV_USE_ROTATE_G2D + uint32_t rotation = lv_display_get_rotation(window->lv_disp); + if(i == 2 && (rotation == LV_DISPLAY_ROTATION_90 || rotation == LV_DISPLAY_ROTATION_270)) { + w = height; + h = width; + } +#endif + stride = lv_draw_buf_width_to_stride(w, lv_display_get_color_format(window->lv_disp)); buffers[i].window = window; buffers[i].lv_draw_buf = - lv_draw_buf_create(window->width, window->height, lv_display_get_color_format(window->lv_disp), stride); + lv_draw_buf_create(w, h, lv_display_get_color_format(window->lv_disp), stride); buffers[i].strides[0] = stride; buffers[i].dmabuf_fds[0] = g2d_get_buf_fd(buffers[i].lv_draw_buf); buffers[i].buf_base[0] = buffers[i].lv_draw_buf->data; params = zwp_linux_dmabuf_v1_create_params(window->wl_ctx->dmabuf_ctx.handler); - switch(lv_display_get_color_format(window->lv_disp)) { - case LV_COLOR_FORMAT_XRGB8888: - drmcf = DRM_FORMAT_XRGB8888; - break; - case LV_COLOR_FORMAT_ARGB8888: - drmcf = DRM_FORMAT_ARGB8888; - break; - case LV_COLOR_FORMAT_RGB565: - drmcf = DRM_FORMAT_RGB565; - break; - default: - drmcf = DRM_FORMAT_ARGB8888; - } - zwp_linux_buffer_params_v1_add(params, buffers[i].dmabuf_fds[0], 0, buffers[i].offsets[0], buffers[i].strides[0], 0, 0); zwp_linux_buffer_params_v1_add_listener(params, ¶ms_listener, &buffers[i]); - zwp_linux_buffer_params_v1_create(params, window->width, window->height, drmcf, flags); + zwp_linux_buffer_params_v1_create(params, w, h, drmcf, flags); } wl_display_roundtrip(lv_wl_ctx.display); + window->body->width = width; + window->body->height = height; + return buffers; } @@ -303,6 +419,144 @@ static void buffer_free(struct buffer * buf) if(buf->lv_draw_buf) lv_draw_buf_destroy(buf->lv_draw_buf); } +static void dmabuf_format_table(void * data, struct zwp_linux_dmabuf_feedback_v1 * zwp_linux_dmabuf_feedback, + int32_t fd, uint32_t size) +{ + dmabuf_ctx_t * ctx = data; + + LV_UNUSED(zwp_linux_dmabuf_feedback); + + if(fd < 0 || size == 0) { + LV_LOG_ERROR("Invalid format table fd=%d size=%u", fd, size); + return; + } + + /* Map the format table file descriptor */ + void * table = mmap(NULL, size, PROT_READ, MAP_PRIVATE, fd, 0); + if(table == MAP_FAILED) { + LV_LOG_ERROR("Failed to mmap format table: %s", strerror(errno)); + close(fd); + return; + } + + LV_LOG_TRACE("Received format table with fd %d and size %u", fd, size); + + /* Parse the format table - each entry is 16 bytes: 4 bytes format + 4 bytes padding + 8 bytes modifier */ + size_t num_formats = size / 16; + uint32_t * formats = (uint32_t *)table; + + for(size_t i = 0; i < num_formats; i++) { + uint32_t format = formats[i * 4]; /* Each entry is 4 uint32_t words */ + + if(LV_COLOR_DEPTH == 32) { + if(format == DRM_FORMAT_ARGB8888) { + ctx->format = format; + break; + } + else if(format == DRM_FORMAT_XRGB8888 && ctx->format == DRM_FORMAT_INVALID) { + ctx->format = format; + break; + } + } + else if(LV_COLOR_DEPTH == 16 && format == DRM_FORMAT_RGB565) { + ctx->format = format; + break; + } + } + + LV_ASSERT(ctx->format != DRM_FORMAT_INVALID); + + /* Clean up */ + munmap(table, size); + close(fd); +} + +static void dmabuf_done(void * data, struct zwp_linux_dmabuf_feedback_v1 * zwp_linux_dmabuf_feedback) +{ + dmabuf_ctx_t * ctx = data; + + LV_UNUSED(zwp_linux_dmabuf_feedback); + LV_UNUSED(ctx); + + LV_LOG_TRACE("DMABUF feedback done - format is %u", ctx->format); + + /* This event marks the end of a feedback round. The client has received + * all the format and modifier pairs from all tranches. This allows + * the client to proceed with buffer allocation. */ +} + +static void dmabuf_main_device(void * data, struct zwp_linux_dmabuf_feedback_v1 * zwp_linux_dmabuf_feedback, + struct wl_array * device) +{ + LV_UNUSED(data); + LV_UNUSED(zwp_linux_dmabuf_feedback); + LV_UNUSED(device); + + LV_LOG_TRACE("DMABUF main device received (size: %zu)", device->size); + + /* This event advertises the main device that the server-side allocator + * will use for scanout. It should be used by clients as a hint for + * buffer allocation. */ +} + +static void dmabuf_tranche_done(void * data, struct zwp_linux_dmabuf_feedback_v1 * zwp_linux_dmabuf_feedback) +{ + LV_UNUSED(data); + LV_UNUSED(zwp_linux_dmabuf_feedback); + + LV_LOG_TRACE("DMABUF tranche done"); + + /* This event marks the end of a tranche. This allows the client to + * process the formats and modifiers it has received for this tranche. */ +} + +static void dmabuf_tranche_target_device(void * data, struct zwp_linux_dmabuf_feedback_v1 * zwp_linux_dmabuf_feedback, + struct wl_array * device) +{ + LV_UNUSED(data); + LV_UNUSED(zwp_linux_dmabuf_feedback); + LV_UNUSED(device); + + LV_LOG_TRACE("DMABUF tranche target device (size: %zu)", device->size); + + /* This event advertises the target device that the following tranche + * will apply to. */ +} + +static void dmabuf_tranche_formats(void * data, struct zwp_linux_dmabuf_feedback_v1 * zwp_linux_dmabuf_feedback, + struct wl_array * indices) +{ + dmabuf_ctx_t * ctx = data; + + LV_UNUSED(zwp_linux_dmabuf_feedback); + + LV_LOG_TRACE("DMABUF tranche formats (count: %zu)", indices->size / sizeof(uint16_t)); + + /* This event advertises the format + modifier pairs that the compositor + * supports for the current tranche. The indices are offsets into the + * format table sent earlier. */ + + if(ctx->format == DRM_FORMAT_INVALID && indices->size > 0) { + /* If we don't have a format yet, we could parse the indices here + * to find a suitable format from the format table, but for now + * we rely on the format_table callback to set a format directly */ + LV_LOG_TRACE("Format indices received but format already set or no format table"); + } +} + +static void dmabuf_tranche_flags(void * data, struct zwp_linux_dmabuf_feedback_v1 * zwp_linux_dmabuf_feedback, + uint32_t flags) +{ + LV_UNUSED(data); + LV_UNUSED(zwp_linux_dmabuf_feedback); + LV_UNUSED(flags); + + LV_LOG_TRACE("DMABUF tranche flags: 0x%x", flags); + + /* This event advertises the flags for the current tranche. + * Flags can indicate special properties like scanout support. */ +} + static void dmabuf_modifiers(void * data, struct zwp_linux_dmabuf_v1 * zwp_linux_dmabuf, uint32_t format, uint32_t modifier_hi, uint32_t modifier_lo) { @@ -333,12 +587,15 @@ static void dmabuf_format(void * data, struct zwp_linux_dmabuf_v1 * zwp_linux_dm } } +#if !LV_USE_ROTATE_G2D static struct buffer * dmabuf_acquire_buffer(dmabuf_ctx_t * context, unsigned char * color_p) { for(int i = 0; i < LV_WAYLAND_BUF_COUNT; i++) { struct buffer * buffer = &context->buffers[i]; if(buffer->buf_base[0] == color_p && buffer->busy == 0) { + context->last_used = i; + buffer->busy = 1; return buffer; } } @@ -349,6 +606,8 @@ static struct buffer * dmabuf_acquire_buffer(dmabuf_ctx_t * context, unsigned ch for(int i = 0; i < LV_WAYLAND_BUF_COUNT; i++) { struct buffer * buffer = &context->buffers[i]; if(buffer->buf_base[0] == color_p && buffer->busy == 0) { + context->last_used = i; + buffer->busy = 1; return buffer; } } @@ -356,5 +615,75 @@ static struct buffer * dmabuf_acquire_buffer(dmabuf_ctx_t * context, unsigned ch return NULL; } +#else +static struct buffer * get_next_buffer(dmabuf_ctx_t * context) +{ + int next_buf = (context->last_used + 1) % (LV_WAYLAND_BUF_COUNT - 1); + context->buffers[next_buf].busy = 1; + context->last_used = next_buf; + return &context->buffers[next_buf]; +} +#endif + +#if LV_WAYLAND_WINDOW_DECORATIONS +static void create_decorators_buf(struct window * window, struct graphic_object * decoration) +{ + struct zwp_linux_buffer_params_v1 * params; + const uint32_t flags = 0; + uint8_t id = decoration->type; + + window->decorators_buf[id] = (struct buffer *)calloc(1, sizeof(struct buffer)); + LV_ASSERT_MALLOC(window->decorators_buf[id]); + + const int stride = lv_draw_buf_width_to_stride(decoration->width, lv_display_get_color_format(window->lv_disp)); + window->decorators_buf[id]->window = window; + window->decorators_buf[id]->lv_draw_buf = + lv_draw_buf_create(decoration->width, decoration->height, lv_display_get_color_format(window->lv_disp), stride); + + window->decorators_buf[id]->strides[0] = stride; + window->decorators_buf[id]->width = decoration->width; + window->decorators_buf[id]->height = decoration->height; + window->decorators_buf[id]->dmabuf_fds[0] = g2d_get_buf_fd(window->decorators_buf[id]->lv_draw_buf); + window->decorators_buf[id]->buf_base[0] = window->decorators_buf[id]->lv_draw_buf->data; + params = zwp_linux_dmabuf_v1_create_params(window->wl_ctx->dmabuf_ctx.handler); + + zwp_linux_buffer_params_v1_add(params, window->decorators_buf[id]->dmabuf_fds[0], 0, + window->decorators_buf[id]->offsets[0], + window->decorators_buf[id]->strides[0], 0, + 0); + + zwp_linux_buffer_params_v1_add_listener(params, ¶ms_listener, window->decorators_buf[id]); + zwp_linux_buffer_params_v1_create(params, decoration->width, decoration->height, lv_wayland_dmabuf_get_format(window), + flags); + + wl_display_roundtrip(lv_wl_ctx.display); +} + +void destroy_decorators_buf(struct window * window, struct graphic_object * decoration) +{ + uint8_t id = decoration->type; + + if(window->decorators_buf[id] != NULL) { + buffer_free(window->decorators_buf[id]); + free(window->decorators_buf[id]); + window->decorators_buf[id] = NULL; + } +} + +struct buffer * dmabuf_acquire_pool_buffer(struct window * window, struct graphic_object * decoration) +{ + uint8_t id = decoration->type; + + if(window->decorators_buf[id] == NULL) { + create_decorators_buf(window, decoration); + } + else if(window->decorators_buf[id]->width != (uint32_t)decoration->width || + window->decorators_buf[id]->height != (uint32_t)decoration->height) { + destroy_decorators_buf(window, decoration); + create_decorators_buf(window, decoration); + } + return window->decorators_buf[id]; +} +#endif #endif /* LV_WAYLAND_DMABUF */ diff --git a/src/drivers/wayland/lv_wl_keyboard.c b/src/drivers/wayland/lv_wl_keyboard.c index 27b589271a..bcdb3885b4 100644 --- a/src/drivers/wayland/lv_wl_keyboard.c +++ b/src/drivers/wayland/lv_wl_keyboard.c @@ -79,7 +79,7 @@ lv_indev_t * lv_wayland_keyboard_create(void) lv_indev_t * lv_wayland_get_keyboard(lv_display_t * display) { - struct window * window = lv_display_get_user_data(display); + struct window * window = lv_display_get_driver_data(display); if(!window) { return NULL; } @@ -101,7 +101,7 @@ const struct wl_keyboard_listener * lv_wayland_keyboard_get_listener(void) static void keyboard_read(lv_indev_t * drv, lv_indev_data_t * data) { - struct window * window = lv_display_get_user_data(lv_indev_get_display(drv)); + struct window * window = lv_display_get_driver_data(lv_indev_get_display(drv)); if(!window || window->closed) { return; } diff --git a/src/drivers/wayland/lv_wl_pointer.c b/src/drivers/wayland/lv_wl_pointer.c index e406d47e21..bffa3bae99 100644 --- a/src/drivers/wayland/lv_wl_pointer.c +++ b/src/drivers/wayland/lv_wl_pointer.c @@ -78,7 +78,7 @@ lv_indev_t * lv_wayland_pointer_create(void) lv_indev_t * lv_wayland_get_pointer(lv_display_t * disp) { - struct window * window = lv_display_get_user_data(disp); + struct window * window = lv_display_get_driver_data(disp); if(!window) { return NULL; } @@ -100,7 +100,7 @@ const struct wl_pointer_listener * lv_wayland_pointer_get_listener(void) static void _lv_wayland_pointer_read(lv_indev_t * drv, lv_indev_data_t * data) { - struct window * window = lv_display_get_user_data(lv_indev_get_display(drv)); + struct window * window = lv_display_get_driver_data(lv_indev_get_display(drv)); if(!window || window->closed) { return; @@ -129,9 +129,7 @@ static void pointer_handle_enter(void * data, struct wl_pointer * pointer, uint3 app->pointer_obj->input.pointer.x = pos_x; app->pointer_obj->input.pointer.y = pos_y; -#if LV_WAYLAND_XDG_SHELL cursor = lv_wayland_xdg_shell_get_cursor_name(app); -#endif if(app->cursor_surface) { struct wl_cursor_image * cursor_image = wl_cursor_theme_get_cursor(app->cursor_theme, cursor)->images[0]; @@ -187,11 +185,7 @@ static void pointer_handle_button(void * data, struct wl_pointer * wl_pointer, u } struct window * window = app->pointer_obj->window; -#if LV_WAYLAND_WL_SHELL - lv_wayland_wl_shell_handle_pointer_event(app, serial, button, state); -#elif LV_WAYLAND_XDG_SHELL lv_wayland_xdg_shell_handle_pointer_event(app, serial, button, state); -#endif switch(app->pointer_obj->type) { case OBJECT_WINDOW: diff --git a/src/drivers/wayland/lv_wl_pointer_axis.c b/src/drivers/wayland/lv_wl_pointer_axis.c index f61bbe7942..9b6ddac4d4 100644 --- a/src/drivers/wayland/lv_wl_pointer_axis.c +++ b/src/drivers/wayland/lv_wl_pointer_axis.c @@ -51,7 +51,7 @@ lv_indev_t * lv_wayland_pointer_axis_create(void) lv_indev_t * lv_wayland_get_pointeraxis(lv_display_t * display) { - struct window * window = lv_display_get_user_data(display); + struct window * window = lv_display_get_driver_data(display); if(!window) { return NULL; } @@ -64,7 +64,7 @@ lv_indev_t * lv_wayland_get_pointeraxis(lv_display_t * display) static void pointeraxis_read(lv_indev_t * drv, lv_indev_data_t * data) { - struct window * window = lv_display_get_user_data(lv_indev_get_display(drv)); + struct window * window = lv_display_get_driver_data(lv_indev_get_display(drv)); if(!window || window->closed) { return; diff --git a/src/drivers/wayland/lv_wl_seat.c b/src/drivers/wayland/lv_wl_seat.c index e4176553c1..64b4342a0f 100644 --- a/src/drivers/wayland/lv_wl_seat.c +++ b/src/drivers/wayland/lv_wl_seat.c @@ -85,12 +85,10 @@ static void seat_handle_capabilities(void * data, struct wl_seat * wl_seat, enum seat->wl_keyboard = NULL; } -#if LV_USE_GESTURE_RECOGNITION if((caps & WL_SEAT_CAPABILITY_TOUCH) && !seat->wl_touch) { seat->wl_touch = wl_seat_get_touch(wl_seat); wl_touch_add_listener(seat->wl_touch, lv_wayland_touch_get_listener(), app); } -#endif else if(!(caps & WL_SEAT_CAPABILITY_TOUCH) && seat->wl_touch) { wl_touch_destroy(seat->wl_touch); seat->wl_touch = NULL; diff --git a/src/drivers/wayland/lv_wl_shell.c b/src/drivers/wayland/lv_wl_shell.c deleted file mode 100644 index 5f3b24941d..0000000000 --- a/src/drivers/wayland/lv_wl_shell.c +++ /dev/null @@ -1,184 +0,0 @@ -/** - * @file lv_wl_shell.c - * - */ - -/********************* - * INCLUDES - *********************/ - -#include "lv_wayland.h" - -#if LV_WAYLAND_WL_SHELL - -/* WL_SHELL has been deprecated for 3 years now */ -#warning LV_WAYLAND_WL_SHELL is deprecated and will be removed in a future release - -#include "lv_wayland_private.h" -#include - -/********************* - * DEFINES - *********************/ - -/********************** - * TYPEDEFS - **********************/ - -/********************** - * STATIC PROTOTYPES - **********************/ - -static void wl_shell_handle_ping(void * data, struct wl_shell_surface * shell_surface, uint32_t serial); -static void wl_shell_handle_configure(void * data, struct wl_shell_surface * shell_surface, uint32_t edges, - int32_t width, int32_t height); - -/********************** - * STATIC VARIABLES - **********************/ - -static const struct wl_shell_surface_listener shell_surface_listener = { - .ping = wl_shell_handle_ping, - .configure = wl_shell_handle_configure, -}; - -/********************** - * MACROS - **********************/ - -/********************** - * GLOBAL FUNCTIONS - **********************/ - -/********************** - * PRIVATE FUNCTIONS - **********************/ - -void lv_wayland_wl_shell_deinit(void) -{ - if(lv_wl_ctx.wl_shell) { - wl_shell_destroy(lv_wl_ctx.wl_shell); - } -} - -const struct wl_shell_surface_listener * lv_wayland_wl_shell_get_listener(void) -{ - return &shell_surface_listener; -} - -lv_result_t lv_wayland_wl_shell_create_window(struct lv_wayland_context * ctx, struct window * window, - const char * title) -{ - if(!ctx->wl_shell) { - return LV_RESULT_INVALID; - } - - window->wl_shell_surface = wl_shell_get_shell_surface(ctx->wl_shell, window->body->surface); - if(!window->wl_shell_surface) { - LV_LOG_ERROR("cannot create WL shell surface"); - return LV_RESULT_INVALID; - } - - wl_shell_surface_add_listener(window->wl_shell_surface, lv_wayland_wl_shell_get_listener(), window); - wl_shell_surface_set_toplevel(window->wl_shell_surface); - wl_shell_surface_set_title(window->wl_shell_surface, title); - - /* For wl_shell, just draw the window, weston doesn't send it */ - lv_wayland_window_draw(window, window->width, window->height); - return LV_RESULT_OK; -} - -lv_result_t lv_wayland_wl_shell_set_maximized(struct window * window, bool maximized) -{ - - if(!window->wl_shell_surface) { - return LV_RESULT_INVALID; - } - if(maximized) { - LV_LOG_ERROR("WL_SHELL - Unsupported operation - Maximization"); - return LV_RESULT_INVALID; - } - else { - wl_shell_surface_set_toplevel(window->wl_shell_surface); - } - return LV_RESULT_OK; -} - -lv_result_t lv_wayland_wl_shell_set_minimized(struct window * window) -{ - LV_LOG_ERROR("WL_SHELL - Unsupported operation - Minization"); - return LV_RESULT_INVALID; -} -lv_result_t lv_wayland_wl_shell_set_fullscreen(struct window * window, bool fullscreen) -{ - if(!window->wl_shell_surface) { - return LV_RESULT_INVALID; - } - if(fullscreen) { - wl_shell_surface_set_fullscreen(window->wl_shell_surface, WL_SHELL_SURFACE_FULLSCREEN_METHOD_SCALE, 0, NULL); - } - else { - wl_shell_surface_set_toplevel(window->wl_shell_surface); - } - return LV_RESULT_OK; -} - -lv_result_t lv_wayland_wl_shell_destroy_window(struct window * window) -{ - if(!window->wl_shell_surface) { - return LV_RESULT_INVALID; - } - wl_shell_surface_destroy(window->wl_shell_surface); - return LV_RESULT_OK; -} - -void lv_wayland_wl_shell_handle_pointer_event(struct lv_wayland_context * ctx, uint32_t serial, uint32_t button, - uint32_t state) -{ - struct window * window = ctx->pointer_obj->window; - switch(ctx->pointer_obj->type) { - case OBJECT_TITLEBAR: - if((button == BTN_LEFT) && (state == WL_POINTER_BUTTON_STATE_PRESSED)) { - if(window->wl_shell_surface) { - wl_shell_surface_move(window->wl_shell_surface, ctx->wl_seat, serial); - window->flush_pending = true; - } - } - break; - case OBJECT_BUTTON_CLOSE: - case OBJECT_BORDER_TOP: - case OBJECT_BORDER_BOTTOM: - case OBJECT_BORDER_LEFT: - case OBJECT_BORDER_RIGHT: - case OBJECT_WINDOW: - break; - } -} - -/********************** - * STATIC FUNCTIONS - **********************/ - -static void wl_shell_handle_ping(void * data, struct wl_shell_surface * shell_surface, uint32_t serial) -{ - return wl_shell_surface_pong(shell_surface, serial); -} - -static void wl_shell_handle_configure(void * data, struct wl_shell_surface * shell_surface, uint32_t edges, - int32_t width, int32_t height) -{ - struct window * window = (struct window *)data; - - LV_UNUSED(edges); - - if((width <= 0) || (height <= 0)) { - return; - } - else if((width != window->width) || (height != window->height)) { - window->resize_width = width; - window->resize_height = height; - window->resize_pending = true; - } -} - -#endif /* LV_WAYLAND_WL_SHELL */ diff --git a/src/drivers/wayland/lv_wl_shm.c b/src/drivers/wayland/lv_wl_shm.c index 87eb547c6e..5d479b085d 100644 --- a/src/drivers/wayland/lv_wl_shm.c +++ b/src/drivers/wayland/lv_wl_shm.c @@ -125,6 +125,7 @@ void lv_wayland_shm_on_graphical_object_destruction(shm_ctx_t * context, struct lv_result_t lv_wayland_shm_resize_window(shm_ctx_t * context, struct window * window, int32_t width, int32_t height) { + LV_UNUSED(context); const uint8_t bpp = lv_color_format_get_size(LV_COLOR_FORMAT_NATIVE); /* Update size for newly allocated buffers */ @@ -143,7 +144,7 @@ lv_result_t lv_wayland_shm_resize_window(shm_ctx_t * context, struct window * wi return LV_RESULT_INVALID; } - /* Moves the buffers to the the unused list of the group */ + /* Moves the buffers to the unused list of the group */ smm_release(body_buf1); smm_release(body_buf2); @@ -156,41 +157,42 @@ lv_result_t lv_wayland_shm_resize_window(shm_ctx_t * context, struct window * wi if(window->lv_disp != NULL) { /* Resize draw buffer */ const uint32_t stride = lv_draw_buf_width_to_stride(width, lv_display_get_color_format(window->lv_disp)); - context->lv_draw_buf = lv_draw_buf_reshape(context->lv_draw_buf, lv_display_get_color_format(window->lv_disp), - width, height / LVGL_DRAW_BUFFER_DIV, stride); + window->lv_draw_buf = lv_draw_buf_reshape(window->lv_draw_buf, lv_display_get_color_format(window->lv_disp), + width, height / LVGL_DRAW_BUFFER_DIV, stride); } return LV_RESULT_OK; } lv_result_t lv_wayland_shm_create_draw_buffers(shm_ctx_t * context, struct window * window) { - + LV_UNUSED(context); const uint32_t stride = lv_draw_buf_width_to_stride(window->width, lv_display_get_color_format(window->lv_disp)); - context->lv_draw_buf = lv_draw_buf_create(window->width, window->height / LVGL_DRAW_BUFFER_DIV, - lv_display_get_color_format(window->lv_disp), stride); - return LV_RESULT_OK; + window->lv_draw_buf = lv_draw_buf_create(window->width, window->height / LVGL_DRAW_BUFFER_DIV, + lv_display_get_color_format(window->lv_disp), stride); + return window->lv_draw_buf ? LV_RESULT_OK : LV_RESULT_INVALID; } -lv_result_t lv_wayland_shm_set_draw_buffers(shm_ctx_t * context, lv_display_t * display) +lv_result_t lv_wayland_shm_set_draw_buffers(shm_ctx_t * context, lv_display_t * display, struct window * window) { + LV_UNUSED(context); if(LV_WAYLAND_BUF_COUNT != 1) { LV_LOG_ERROR("Wayland without dmabuf only supports 1 drawbuffer for now."); return LV_RESULT_INVALID; } - lv_display_set_draw_buffers(display, context->lv_draw_buf, NULL); + lv_display_set_draw_buffers(display, window->lv_draw_buf, NULL); return LV_RESULT_OK; } void lv_wayland_shm_delete_draw_buffers(shm_ctx_t * context, struct window * window) { - LV_UNUSED(window); - lv_draw_buf_destroy(context->lv_draw_buf); + LV_UNUSED(context); + if(window->lv_draw_buf) lv_draw_buf_destroy(window->lv_draw_buf); } void lv_wayland_shm_flush_partial_mode(lv_display_t * disp, const lv_area_t * area, unsigned char * color_p) { - struct window * window = lv_display_get_user_data(disp); - uint32_t format = window->wl_ctx->shm_ctx.format; + struct window * window = lv_display_get_driver_data(disp); + const uint32_t buf_format = window->wl_ctx->shm_ctx.format; smm_buffer_t * buf = window->body->pending_buffer; int32_t src_width = lv_area_get_width(area); int32_t src_height = lv_area_get_height(area); @@ -198,6 +200,8 @@ void lv_wayland_shm_flush_partial_mode(lv_display_t * disp, const lv_area_t * ar lv_display_rotation_t rot = lv_display_get_rotation(disp); int32_t w = lv_display_get_horizontal_resolution(disp); int32_t h = lv_display_get_vertical_resolution(disp); + const uint8_t cf = lv_display_get_color_format(disp); + const int32_t stride = lv_draw_buf_width_to_stride(src_width, cf); /* TODO actually test what happens if the rotation is 90 or 270 or 180 ? */ int32_t hres = (rot == LV_DISPLAY_ROTATION_0) ? w : h; @@ -232,13 +236,14 @@ void lv_wayland_shm_flush_partial_mode(lv_display_t * disp, const lv_area_t * ar /* Modify specified area in buffer */ for(int32_t y = 0; y < src_height; ++y) { - if(format == WL_SHM_FORMAT_ARGB8888) { + if(buf_format == WL_SHM_FORMAT_ARGB8888 && + cf != LV_COLOR_FORMAT_ARGB8888_PREMULTIPLIED) { for(int32_t x = 0; x < src_width; ++x) { lv_color_premultiply((lv_color32_t *)color_p + x); } } memcpy(((char *)buf_base) + ((((area->y1 + y) * hres) + area->x1) * bpp), color_p, src_width * bpp); - color_p += src_width * bpp; + color_p += stride; } /* Mark surface damage */ diff --git a/src/drivers/wayland/lv_wl_touch.c b/src/drivers/wayland/lv_wl_touch.c index ee18ec3ddc..ea375b0612 100644 --- a/src/drivers/wayland/lv_wl_touch.c +++ b/src/drivers/wayland/lv_wl_touch.c @@ -5,7 +5,7 @@ #include "lv_wl_touch.h" -#if LV_USE_WAYLAND && LV_USE_GESTURE_RECOGNITION +#if LV_USE_WAYLAND #include "lv_wayland_private.h" @@ -74,7 +74,7 @@ lv_indev_t * lv_wayland_touch_create(void) lv_indev_t * lv_wayland_get_touchscreen(lv_display_t * display) { - struct window * window = lv_display_get_user_data(display); + struct window * window = lv_display_get_driver_data(display); if(!window) { return NULL; } @@ -97,12 +97,13 @@ const struct wl_touch_listener * lv_wayland_touch_get_listener(void) static void _lv_wayland_touch_read(lv_indev_t * drv, lv_indev_data_t * data) { - struct window * window = lv_display_get_user_data(lv_indev_get_display(drv)); + struct window * window = lv_display_get_driver_data(lv_indev_get_display(drv)); if(!window || window->closed) { return; } +#if LV_USE_GESTURE_RECOGNITION /* Collect touches if there are any - send them to the gesture recognizer */ lv_indev_gesture_recognizers_update(drv, &window->body->input.touches[0], window->body->input.touch_event_cnt); @@ -112,13 +113,29 @@ static void _lv_wayland_touch_read(lv_indev_t * drv, lv_indev_data_t * data) /* Set the gesture information, before returning to LVGL */ lv_indev_gesture_recognizers_set_data(drv, data); + + if(window->body->input.touch_event_cnt > 0) { + data->point.x = window->body->input.touches[0].point.x; + data->point.y = window->body->input.touches[0].point.y; + } + else { + data->point.x = 0; + data->point.y = 0; + } +#else + data->point.x = window->body->input.touch.point.x; + data->point.y = window->body->input.touch.point.y; + data->state = window->body->input.touch.state; +#endif } static void touch_handle_down(void * data, struct wl_touch * wl_touch, uint32_t serial, uint32_t time, struct wl_surface * surface, int32_t id, wl_fixed_t x_w, wl_fixed_t y_w) { struct lv_wayland_context * app = data; +#if LV_USE_GESTURE_RECOGNITION uint8_t i; +#endif LV_UNUSED(id); LV_UNUSED(time); @@ -132,6 +149,8 @@ static void touch_handle_down(void * data, struct wl_touch * wl_touch, uint32_t /* Create the touch down event */ app->touch_obj = wl_surface_get_user_data(surface); + +#if LV_USE_GESTURE_RECOGNITION i = app->touch_obj->input.touch_event_cnt; app->touch_obj->input.touches[i].point.x = wl_fixed_to_int(x_w); @@ -140,23 +159,20 @@ static void touch_handle_down(void * data, struct wl_touch * wl_touch, uint32_t app->touch_obj->input.touches[i].timestamp = time; app->touch_obj->input.touches[i].state = LV_INDEV_STATE_PRESSED; app->touch_obj->input.touch_event_cnt++; +#else + app->touch_obj->input.touch.point.x = wl_fixed_to_int(x_w); + app->touch_obj->input.touch.point.y = wl_fixed_to_int(y_w); + app->touch_obj->input.touch.state = LV_INDEV_STATE_PRESSED; +#endif #if LV_WAYLAND_WINDOW_DECORATIONS struct window * window = app->touch_obj->window; switch(app->touch_obj->type) { case OBJECT_TITLEBAR: -#if LV_WAYLAND_XDG_SHELL if(window->xdg_toplevel) { xdg_toplevel_move(window->xdg_toplevel, app->wl_seat, serial); window->flush_pending = true; } -#endif -#if LV_WAYLAND_WL_SHELL - if(window->wl_shell_surface) { - wl_shell_surface_move(window->wl_shell_surface, app->wl_seat, serial); - window->flush_pending = true; - } -#endif break; default: break; @@ -167,15 +183,17 @@ static void touch_handle_down(void * data, struct wl_touch * wl_touch, uint32_t static void touch_handle_up(void * data, struct wl_touch * wl_touch, uint32_t serial, uint32_t time, int32_t id) { struct lv_wayland_context * app = data; +#if LV_USE_GESTURE_RECOGNITION uint8_t i; +#endif LV_UNUSED(serial); LV_UNUSED(time); LV_UNUSED(id); LV_UNUSED(wl_touch); -#if LV_USE_GESTURE_RECOGNITION /* Create a released event */ +#if LV_USE_GESTURE_RECOGNITION i = app->touch_obj->input.touch_event_cnt; app->touch_obj->input.touches[i].point.x = 0; @@ -185,6 +203,8 @@ static void touch_handle_up(void * data, struct wl_touch * wl_touch, uint32_t se app->touch_obj->input.touches[i].state = LV_INDEV_STATE_RELEASED; app->touch_obj->input.touch_event_cnt++; +#else + app->touch_obj->input.touch.state = LV_INDEV_STATE_RELEASED; #endif #if LV_WAYLAND_WINDOW_DECORATIONS @@ -193,7 +213,6 @@ static void touch_handle_up(void * data, struct wl_touch * wl_touch, uint32_t se case OBJECT_BUTTON_CLOSE: window->shall_close = true; break; -#if LV_WAYLAND_XDG_SHELL case OBJECT_BUTTON_MAXIMIZE: if(window->xdg_toplevel) { if(window->maximized) { @@ -210,7 +229,6 @@ static void touch_handle_up(void * data, struct wl_touch * wl_touch, uint32_t se xdg_toplevel_set_minimized(window->xdg_toplevel); window->flush_pending = true; } -#endif /* LV_WAYLAND_XDG_SHELL */ default: break; } @@ -221,14 +239,17 @@ static void touch_handle_motion(void * data, struct wl_touch * wl_touch, uint32_ wl_fixed_t y_w) { struct lv_wayland_context * app = data; +#if LV_USE_GESTURE_RECOGNITION lv_indev_touch_data_t * touch; lv_indev_touch_data_t * cur; uint8_t i; +#endif LV_UNUSED(time); LV_UNUSED(id); LV_UNUSED(wl_touch); +#if LV_USE_GESTURE_RECOGNITION /* Update the contact point of the corresponding id with the latest coordinate */ touch = &app->touch_obj->input.touches[0]; cur = NULL; @@ -258,6 +279,10 @@ static void touch_handle_motion(void * data, struct wl_touch * wl_touch, uint32_ cur->id = id; cur->timestamp = time; } +#else + app->touch_obj->input.touch.point.x = wl_fixed_to_int(x_w); + app->touch_obj->input.touch.point.y = wl_fixed_to_int(y_w); +#endif } static void touch_handle_frame(void * data, struct wl_touch * wl_touch) @@ -272,4 +297,4 @@ static void touch_handle_cancel(void * data, struct wl_touch * wl_touch) LV_UNUSED(data); } -#endif /* LV_USE_WAYLAND && LV_USE_GESTURE_RECOGNITION */ +#endif /* LV_USE_WAYLAND */ diff --git a/src/drivers/wayland/lv_wl_touch.h b/src/drivers/wayland/lv_wl_touch.h index eab4443469..2c4a742ee0 100644 --- a/src/drivers/wayland/lv_wl_touch.h +++ b/src/drivers/wayland/lv_wl_touch.h @@ -18,7 +18,7 @@ extern "C" { #include "../../indev/lv_indev.h" #include "../../indev/lv_indev_gesture.h" -#if LV_USE_WAYLAND && LV_USE_GESTURE_RECOGNITION +#if LV_USE_WAYLAND /********************* * DEFINES diff --git a/src/drivers/wayland/lv_wl_window.c b/src/drivers/wayland/lv_wl_window.c index 1e9df64061..4bf4ee20d0 100644 --- a/src/drivers/wayland/lv_wl_window.c +++ b/src/drivers/wayland/lv_wl_window.c @@ -83,6 +83,9 @@ lv_display_t * lv_wayland_window_create(uint32_t hor_res, uint32_t ver_res, char int32_t window_width; int32_t window_height; + uint32_t width = hor_res; + uint32_t height = ver_res; + lv_wayland_init(); window_width = hor_res; @@ -104,7 +107,7 @@ lv_display_t * lv_wayland_window_create(uint32_t hor_res, uint32_t ver_res, char window->close_cb = close_cb; /* Initialize display driver */ - window->lv_disp = lv_display_create(hor_res, ver_res); + window->lv_disp = lv_display_create(width, height); if(window->lv_disp == NULL) { LV_LOG_ERROR("failed to create lvgl display"); return NULL; @@ -122,7 +125,9 @@ lv_display_t * lv_wayland_window_create(uint32_t hor_res, uint32_t ver_res, char } #endif - lv_display_set_user_data(window->lv_disp, window); + lv_wayland_xdg_shell_configure_surface(window); + + lv_display_set_driver_data(window->lv_disp, window); lv_display_set_render_mode(window->lv_disp, LV_WAYLAND_RENDER_MODE); lv_display_set_flush_wait_cb(window->lv_disp, lv_wayland_wait_flush_cb); @@ -131,10 +136,12 @@ lv_display_t * lv_wayland_window_create(uint32_t hor_res, uint32_t ver_res, char lv_wayland_dmabuf_set_draw_buffers(&lv_wl_ctx.dmabuf_ctx, window->lv_disp); lv_display_set_flush_cb(window->lv_disp, lv_wayland_dmabuf_flush_full_mode); #else - lv_wayland_shm_set_draw_buffers(&lv_wl_ctx.shm_ctx, window->lv_disp); + lv_wayland_shm_set_draw_buffers(&lv_wl_ctx.shm_ctx, window->lv_disp, window); lv_display_set_flush_cb(window->lv_disp, lv_wayland_shm_flush_partial_mode); #endif + lv_display_add_event_cb(window->lv_disp, lv_wayland_event_cb, LV_EVENT_RESOLUTION_CHANGED, window); + /* Register input */ window->lv_indev_pointer = lv_wayland_pointer_create(); @@ -151,8 +158,6 @@ lv_display_t * lv_wayland_window_create(uint32_t hor_res, uint32_t ver_res, char LV_LOG_ERROR("failed to register pointeraxis indev"); } -#if LV_USE_GESTURE_RECOGNITION - window->lv_indev_touch = lv_wayland_touch_create(); lv_indev_set_display(window->lv_indev_touch, window->lv_disp); @@ -160,8 +165,6 @@ lv_display_t * lv_wayland_window_create(uint32_t hor_res, uint32_t ver_res, char LV_LOG_ERROR("failed to register touch indev"); } -#endif /* END LV_USE_GESTURE_RECOGNITION */ - window->lv_indev_keyboard = lv_wayland_keyboard_create(); lv_indev_set_display(window->lv_indev_keyboard, window->lv_disp); @@ -173,7 +176,7 @@ lv_display_t * lv_wayland_window_create(uint32_t hor_res, uint32_t ver_res, char void lv_wayland_window_close(lv_display_t * disp) { - struct window * window = lv_display_get_user_data(disp); + struct window * window = lv_display_get_driver_data(disp); if(!window || window->closed) { return; } @@ -196,7 +199,7 @@ bool lv_wayland_window_is_open(lv_display_t * disp) } } else { - window = lv_display_get_user_data(disp); + window = lv_display_get_driver_data(disp); open = (!window->closed); } @@ -205,18 +208,14 @@ bool lv_wayland_window_is_open(lv_display_t * disp) void lv_wayland_window_set_maximized(lv_display_t * disp, bool maximized) { - struct window * window = lv_display_get_user_data(disp); + struct window * window = lv_display_get_driver_data(disp); lv_result_t err = LV_RESULT_INVALID; if(!window || window->closed) { return; } if(window->maximized != maximized) { -#if LV_WAYLAND_WL_SHELL - err = lv_wayland_wl_shell_set_maximized(window, maximized); -#elif LV_WAYLAND_XDG_SHELL err = lv_wayland_xdg_shell_set_maximized(window, maximized); -#endif } if(err == LV_RESULT_INVALID) { @@ -228,9 +227,47 @@ void lv_wayland_window_set_maximized(lv_display_t * disp, bool maximized) window->flush_pending = true; } -void lv_wayland_window_set_fullscreen(lv_display_t * disp, bool fullscreen) +void lv_wayland_assign_physical_display(lv_display_t * disp, uint8_t display_number) { + if(!disp) { + LV_LOG_ERROR("Invalid display"); + return; + } + + struct window * window = lv_display_get_driver_data(disp); + + if(!window || window->closed) { + LV_LOG_ERROR("Invalid window"); + return; + } + + if(display_number >= window->wl_ctx->wl_output_count) { + LV_LOG_WARN("Invalid display number '%d'. Expected '0'..'%d'", display_number, window->wl_ctx->wl_output_count - 1); + return; + } + window->assigned_output = lv_wl_ctx.outputs[display_number].wl_output; +} + +void lv_wayland_unassign_physical_display(lv_display_t * disp) +{ + + if(!disp) { + LV_LOG_ERROR("Invalid display"); + return; + } + struct window * window = lv_display_get_user_data(disp); + + if(!window || window->closed) { + LV_LOG_ERROR("Invalid window"); + return; + } + window->assigned_output = NULL; +} + +void lv_wayland_window_set_fullscreen(lv_display_t * disp, bool fullscreen) +{ + struct window * window = lv_display_get_driver_data(disp); lv_result_t err = LV_RESULT_INVALID; if(!window || window->closed) { return; @@ -239,18 +276,14 @@ void lv_wayland_window_set_fullscreen(lv_display_t * disp, bool fullscreen) if(window->fullscreen == fullscreen) { return; } -#if LV_WAYLAND_WL_SHELL - err = lv_wayland_wl_shell_set_fullscreen(window, fullscreen); -#elif LV_WAYLAND_XDG_SHELL - err = lv_wayland_xdg_shell_set_fullscreen(window, fullscreen); -#endif + err = lv_wayland_xdg_shell_set_fullscreen(window, fullscreen, window->assigned_output); if(err == LV_RESULT_INVALID) { LV_LOG_WARN("Failed to set wayland window to fullscreen"); return; } - window->fullscreen = fullscreen; + window->fullscreen = fullscreen; window->flush_pending = true; } @@ -276,9 +309,7 @@ void lv_wayland_window_draw(struct window * window, uint32_t width, uint32_t hei /* First resize */ if(lv_wayland_window_resize(window, width, height) != LV_RESULT_OK) { LV_LOG_ERROR("Failed to resize window"); -#if LV_WAYLAND_XDG_SHELL lv_wayland_xdg_shell_destroy_window_toplevel(window); -#endif } lv_refr_now(window->lv_disp); @@ -287,29 +318,32 @@ void lv_wayland_window_draw(struct window * window, uint32_t width, uint32_t hei lv_result_t lv_wayland_window_resize(struct window * window, int width, int height) { - #if LV_WAYLAND_WINDOW_DECORATIONS if(!window->wl_ctx->opt_disable_decorations && !window->fullscreen) { width -= (2 * BORDER_SIZE); height -= (TITLE_BAR_HEIGHT + (2 * BORDER_SIZE)); } #endif + if(window->lv_disp) { + lv_display_set_resolution(window->lv_disp, width, height); + window->body->input.pointer.x = LV_MIN((int32_t)window->body->input.pointer.x, (width - 1)); + window->body->input.pointer.y = LV_MIN((int32_t)window->body->input.pointer.y, (height - 1)); + } + /* On the first resize call, the resolution of the display is already set, so there won't be a trigger on the resolution changed event.*/ + if(!window->is_window_configured) { #if LV_WAYLAND_USE_DMABUF - { - lv_result_t err = lv_wayland_dmabuf_resize_window(&window->wl_ctx->dmabuf_ctx, window); + lv_result_t err = lv_wayland_dmabuf_resize_window(&window->wl_ctx->dmabuf_ctx, window, width, height); if(err != LV_RESULT_OK) { return err; } - } #else - { lv_result_t err = lv_wayland_shm_resize_window(&window->wl_ctx->shm_ctx, window, width, height); if(err != LV_RESULT_OK) { return err; } - } #endif + } #if LV_WAYLAND_WINDOW_DECORATIONS if(!window->wl_ctx->opt_disable_decorations && !window->fullscreen) { @@ -322,11 +356,6 @@ lv_result_t lv_wayland_window_resize(struct window * window, int width, int heig } #endif - if(window->lv_disp) { - lv_display_set_resolution(window->lv_disp, width, height); - window->body->input.pointer.x = LV_MIN((int32_t)window->body->input.pointer.x, (width - 1)); - window->body->input.pointer.y = LV_MIN((int32_t)window->body->input.pointer.y, (height - 1)); - } window->width = width; window->height = height; return LV_RESULT_OK; @@ -338,12 +367,8 @@ void lv_wayland_window_destroy(struct window * window) return; } -#if LV_WAYLAND_WL_SHELL - lv_wayland_wl_shell_destroy_window(window); -#elif LV_WAYLAND_XDG_SHELL lv_wayland_xdg_shell_destroy_window_toplevel(window); lv_wayland_xdg_shell_destroy_window_surface(window); -#endif #if LV_WAYLAND_WINDOW_DECORATIONS for(size_t i = 0; i < NUM_DECORATIONS; i++) { @@ -390,16 +415,9 @@ static struct window * create_window(struct lv_wayland_context * app, int width, goto err_free_window; } -#if LV_WAYLAND_WL_SHELL - if(lv_wayland_wl_shell_create_window(app, window, title) != LV_RESULT_OK) { - LV_LOG_ERROR("Failed to create wl shell window"); - goto err_destroy_surface; - } -#elif LV_WAYLAND_XDG_SHELL if(lv_wayland_xdg_shell_create_window(app, window, title) != LV_RESULT_OK) { goto err_destroy_surface; } -#endif return window; diff --git a/src/drivers/wayland/lv_wl_window.h b/src/drivers/wayland/lv_wl_window.h index 7333985655..84fd916314 100644 --- a/src/drivers/wayland/lv_wl_window.h +++ b/src/drivers/wayland/lv_wl_window.h @@ -1,6 +1,6 @@ /** - * @file lv_wl_display.h + * @file lv_wl_window.h * */ @@ -57,11 +57,25 @@ void lv_wayland_window_close(lv_display_t * disp); */ bool lv_wayland_window_is_open(lv_display_t * disp); +/** + * Assigns the window to a specific physical display + * @param disp Reference to the LVGL display associated to the window + * @param display Physical display number + */ +void lv_wayland_assign_physical_display(lv_display_t * disp, uint8_t display); + +/** + * Unassigns the current physical display attached to the window + * @param disp Reference to the LVGL display associated to the window + */ +void lv_wayland_unassign_physical_display(lv_display_t * disp); + /** * Sets the fullscreen state of the window * @param disp Reference to the LVGL display associated to the window * @param fullscreen If true the window enters fullscreen */ + void lv_wayland_window_set_fullscreen(lv_display_t * disp, bool fullscreen); /** diff --git a/src/drivers/wayland/lv_wl_window_decorations.c b/src/drivers/wayland/lv_wl_window_decorations.c index 314043643f..a1cbd033f3 100644 --- a/src/drivers/wayland/lv_wl_window_decorations.c +++ b/src/drivers/wayland/lv_wl_window_decorations.c @@ -12,6 +12,8 @@ #if LV_WAYLAND_WINDOW_DECORATIONS #include "lv_wayland_private.h" +#include +#include /********************* * DEFINES @@ -58,9 +60,14 @@ static void color_fill_RGB565(void * pixels, lv_color_t color, uint32_t width, u **********************/ bool lv_wayland_window_decoration_attach(struct window * window, struct graphic_object * decoration, - smm_buffer_t * decoration_buffer, struct graphic_object * parent) + void * decoration_buffer, struct graphic_object * parent) { - struct wl_buffer * wl_buf = SMM_BUFFER_PROPERTIES(decoration_buffer)->tag[TAG_LOCAL]; +#if LV_WAYLAND_USE_DMABUF + struct wl_buffer * wl_buf = ((struct buffer *)decoration_buffer)->buffer; +#else + struct wl_buffer * wl_buf = SMM_BUFFER_PROPERTIES((smm_buffer_t *)decoration_buffer)->tag[TAG_LOCAL]; +#endif + int pos_x, pos_y; @@ -73,7 +80,6 @@ bool lv_wayland_window_decoration_attach(struct window * window, struct graphic_ pos_x = parent->width - 1 * (BUTTON_MARGIN + BUTTON_SIZE); pos_y = -1 * (BUTTON_MARGIN + BUTTON_SIZE + (BORDER_SIZE / 2)); break; -#if LV_WAYLAND_XDG_SHELL case OBJECT_BUTTON_MAXIMIZE: pos_x = parent->width - 2 * (BUTTON_MARGIN + BUTTON_SIZE); pos_y = -1 * (BUTTON_MARGIN + BUTTON_SIZE + (BORDER_SIZE / 2)); @@ -82,7 +88,6 @@ bool lv_wayland_window_decoration_attach(struct window * window, struct graphic_ pos_x = parent->width - 3 * (BUTTON_MARGIN + BUTTON_SIZE); pos_y = -1 * (BUTTON_MARGIN + BUTTON_SIZE + (BORDER_SIZE / 2)); break; -#endif case OBJECT_BORDER_TOP: pos_x = -BORDER_SIZE; pos_y = -(BORDER_SIZE + TITLE_BAR_HEIGHT); @@ -165,7 +170,11 @@ void lv_wayland_window_decoration_detach_all(struct window * window) bool lv_wayland_window_decoration_create(struct window * window, struct graphic_object * decoration, int window_width, int window_height) { +#if LV_WAYLAND_USE_DMABUF + struct buffer * buf; +#else smm_buffer_t * buf; +#endif void * buf_base; int x, y; lv_color_t * pixel; @@ -180,7 +189,6 @@ bool lv_wayland_window_decoration_create(struct window * window, struct graphic_ decoration->width = BUTTON_SIZE; decoration->height = BUTTON_SIZE; break; -#if LV_WAYLAND_XDG_SHELL case OBJECT_BUTTON_MAXIMIZE: decoration->width = BUTTON_SIZE; decoration->height = BUTTON_SIZE; @@ -189,7 +197,6 @@ bool lv_wayland_window_decoration_create(struct window * window, struct graphic_ decoration->width = BUTTON_SIZE; decoration->height = BUTTON_SIZE; break; -#endif case OBJECT_BORDER_TOP: decoration->width = window_width + 2 * (BORDER_SIZE); decoration->height = BORDER_SIZE; @@ -210,7 +217,17 @@ bool lv_wayland_window_decoration_create(struct window * window, struct graphic_ LV_ASSERT_MSG(0, "Invalid object type"); return false; } - +#if LV_WAYLAND_USE_DMABUF + bpp = lv_color_format_get_size(LV_COLOR_FORMAT_NATIVE); + buf = dmabuf_acquire_pool_buffer(window, decoration); + buf_base = mmap(0, (decoration->width * bpp) * decoration->height, PROT_READ | PROT_WRITE, MAP_SHARED, + buf->dmabuf_fds[0], 0); + if(buf_base == MAP_FAILED) { + destroy_decorators_buf(window, decoration); + LV_LOG_ERROR("cannot map in allocated decoration buffer %d (%s)", errno, strerror(errno)); + return false; + } +#else bpp = lv_color_format_get_size(LV_COLOR_FORMAT_NATIVE); LV_LOG_TRACE("decoration window %dx%d", decoration->width, decoration->height); @@ -230,7 +247,7 @@ bool lv_wayland_window_decoration_create(struct window * window, struct graphic_ smm_release(buf); return false; } - +#endif switch(decoration->type) { case OBJECT_TITLEBAR: color_fill(buf_base, lv_color_make(0x66, 0x66, 0x66), decoration->width, decoration->height); @@ -251,7 +268,6 @@ bool lv_wayland_window_decoration_create(struct window * window, struct graphic_ } } break; -#if LV_WAYLAND_XDG_SHELL case OBJECT_BUTTON_MAXIMIZE: color_fill(buf_base, lv_color_make(0xCC, 0xCC, 0xCC), decoration->width, decoration->height); for(y = 0; y < decoration->height; y++) { @@ -282,7 +298,6 @@ bool lv_wayland_window_decoration_create(struct window * window, struct graphic_ } } break; -#endif case OBJECT_BORDER_TOP: /* fallthrough */ case OBJECT_BORDER_BOTTOM: @@ -297,7 +312,13 @@ bool lv_wayland_window_decoration_create(struct window * window, struct graphic_ return false; } - return lv_wayland_window_decoration_attach(window, decoration, buf, window->body); + bool ret = lv_wayland_window_decoration_attach(window, decoration, buf, window->body); + +#if LV_WAYLAND_USE_DMABUF + munmap(buf_base, (decoration->width * bpp) * decoration->height); +#endif + + return ret; } void lv_wayland_window_decoration_detach(struct window * window, struct graphic_object * decoration) diff --git a/src/drivers/wayland/lv_wl_xdg_shell.c b/src/drivers/wayland/lv_wl_xdg_shell.c index 43848544e8..c2010118aa 100644 --- a/src/drivers/wayland/lv_wl_xdg_shell.c +++ b/src/drivers/wayland/lv_wl_xdg_shell.c @@ -9,14 +9,8 @@ #include "lv_wayland.h" #if LV_USE_WAYLAND -/* - * LV_WAYLAND_XDG_SHELL is automatically defined if LV_WAYLAND_WL_SHELL is not set - * inside lv_wayland_private.h so we need include this header file before checking - * for LV_WAYLAND_XDG_SHELL - */ #include "lv_wayland_private.h" -#if LV_WAYLAND_XDG_SHELL #include #include "wayland_xdg_shell.h" @@ -53,7 +47,6 @@ static const struct xdg_toplevel_listener xdg_toplevel_listener = { }; static const struct xdg_wm_base_listener xdg_wm_base_listener = {.ping = xdg_wm_base_ping}; -static bool is_window_configured = false; /********************** * MACROS @@ -102,14 +95,14 @@ const struct xdg_toplevel_listener * lv_wayland_xdg_shell_get_toplevel_listener( * Shell Window **********************/ -lv_result_t lv_wayland_xdg_shell_set_fullscreen(struct window * window, bool fullscreen) +lv_result_t lv_wayland_xdg_shell_set_fullscreen(struct window * window, bool fullscreen, struct wl_output * output) { if(!window->xdg_toplevel) { return LV_RESULT_INVALID; } if(fullscreen) { - xdg_toplevel_set_fullscreen(window->xdg_toplevel, NULL); + xdg_toplevel_set_fullscreen(window->xdg_toplevel, output); } else { xdg_toplevel_unset_fullscreen(window->xdg_toplevel); @@ -143,6 +136,16 @@ lv_result_t lv_wayland_xdg_shell_set_minimized(struct window * window) return LV_RESULT_OK; } +#if LV_WAYLAND_USE_DMABUF +void lv_wayland_xdg_shell_ack_configure(struct window * window, uint32_t serial) +{ + if(window->xdg_surface && serial > 0) { + xdg_surface_ack_configure(window->xdg_surface, serial); + LV_LOG_TRACE("XDG surface configure acknowledged (serial=%u)", serial); + } +} +#endif + lv_result_t lv_wayland_xdg_shell_create_window(struct lv_wayland_context * app, struct window * window, const char * title) { @@ -169,14 +172,18 @@ lv_result_t lv_wayland_xdg_shell_create_window(struct lv_wayland_context * app, xdg_toplevel_set_title(window->xdg_toplevel, title); xdg_toplevel_set_app_id(window->xdg_toplevel, title); + return LV_RESULT_OK; +} + +void lv_wayland_xdg_shell_configure_surface(struct window * window) +{ // XDG surfaces need to be configured before a buffer can be attached. // An (XDG) surface commit (without an attached buffer) triggers this // configure event - is_window_configured = false; + window->is_window_configured = false; wl_surface_commit(window->body->surface); wl_display_roundtrip(lv_wl_ctx.display); - LV_ASSERT_MSG(is_window_configured, "Failed to receive the xdg_surface configuration event"); - return LV_RESULT_OK; + LV_ASSERT_MSG(window->is_window_configured, "Failed to receive the xdg_surface configuration event"); } lv_result_t lv_wayland_xdg_shell_destroy_window_surface(struct window * window) @@ -396,9 +403,28 @@ static void xdg_surface_handle_configure(void * data, struct xdg_surface * xdg_s { struct window * window = (struct window *)data; - xdg_surface_ack_configure(xdg_surface, serial); +#if LV_WAYLAND_USE_DMABUF + LV_LOG_TRACE("XDG surface configure: serial=%u, dmabuf_resize_pending=%d", + serial, window->dmabuf_resize_pending); + + /* Store the configure serial for synchronization */ + window->configure_serial = serial; + window->surface_configured = true; + window->configure_acknowledged = false; - if(!is_window_configured) { + /* Only acknowledge immediately if no DMABUF resize is pending */ + if(!window->dmabuf_resize_pending) { + xdg_surface_ack_configure(xdg_surface, serial); + window->configure_acknowledged = true; + LV_LOG_TRACE("XDG surface configure acknowledged immediately"); + } + else { + LV_LOG_TRACE("XDG surface configure deferred - DMABUF resize pending"); + } +#else + xdg_surface_ack_configure(xdg_surface, serial); +#endif + if(!window->is_window_configured) { /* This branch is executed at launch */ if(!window->resize_pending) { /* Use the size passed to the create_window function */ @@ -415,7 +441,7 @@ static void xdg_surface_handle_configure(void * data, struct xdg_surface * xdg_s window->resize_pending = false; } } - is_window_configured = true; + window->is_window_configured = true; } static void xdg_toplevel_handle_configure(void * data, struct xdg_toplevel * xdg_toplevel, int32_t width, @@ -426,9 +452,9 @@ static void xdg_toplevel_handle_configure(void * data, struct xdg_toplevel * xdg LV_UNUSED(xdg_toplevel); LV_UNUSED(states); - LV_LOG_TRACE("w:%d h:%d", width, height); + LV_LOG_TRACE("XDG toplevel configure: w=%d h=%d (current: %dx%d)", + width, height, window->width, window->height); LV_LOG_TRACE("current body w:%d h:%d", window->body->width, window->body->height); - LV_LOG_TRACE("window w:%d h:%d", window->width, window->height); if((width <= 0) || (height <= 0)) { LV_LOG_TRACE("will not resize to w:%d h:%d", width, height); @@ -439,7 +465,9 @@ static void xdg_toplevel_handle_configure(void * data, struct xdg_toplevel * xdg window->resize_width = width; window->resize_height = height; window->resize_pending = true; - LV_LOG_TRACE("resize_pending is set, will resize to w:%d h:%d", width, height); +#if LV_WAYLAND_USE_DMABUF + window->dmabuf_resize_pending = true; +#endif } else { LV_LOG_TRACE("resize_pending not set w:%d h:%d", width, height); @@ -463,5 +491,4 @@ static void xdg_wm_base_ping(void * data, struct xdg_wm_base * xdg_wm_base, uint return; } -#endif /* LV_WAYLAND_XDG_SHELL */ #endif /* LV_USE_WAYLAND */ diff --git a/src/drivers/windows/lv_windows_context.c b/src/drivers/windows/lv_windows_context.c index a79b7852fd..dd2d6a5995 100644 --- a/src/drivers/windows/lv_windows_context.c +++ b/src/drivers/windows/lv_windows_context.c @@ -16,7 +16,7 @@ #include "lv_windows_display.h" #include "lv_windows_input_private.h" -#include "../../osal/lv_os.h" +#include "../../osal/lv_os_private.h" /********************* * DEFINES diff --git a/src/drivers/windows/lv_windows_display.c b/src/drivers/windows/lv_windows_display.c index 958338ec66..496aada594 100644 --- a/src/drivers/windows/lv_windows_display.c +++ b/src/drivers/windows/lv_windows_display.c @@ -122,23 +122,33 @@ static unsigned int __stdcall lv_windows_display_thread_entrypoint( LV_ASSERT_NULL(data); DWORD window_style = WS_OVERLAPPEDWINDOW; + DWORD ext_window_style = WS_EX_CLIENTEDGE; + RECT rect = { 0, 0, data->hor_res, data->ver_res }; + if(data->simulator_mode) { window_style &= ~(WS_SIZEBOX | WS_MAXIMIZEBOX | WS_THICKFRAME); } + else { + /* Have Windows compute window size so, regardless of window style, + * the CLIENT AREA has dimensions [data->hor_res, data->ver_res]. + * This is the area needed for LVGL to render to. */ + AdjustWindowRectEx(&rect, window_style, false, ext_window_style); + } HWND window_handle = CreateWindowExW( - WS_EX_CLIENTEDGE, + ext_window_style, L"LVGL.Window", data->title, window_style, CW_USEDEFAULT, 0, - data->hor_res, - data->ver_res, + rect.right - rect.left, + rect.bottom - rect.top, NULL, NULL, NULL, data); + if(!window_handle) { return 0; } diff --git a/src/drivers/windows/lv_windows_display.h b/src/drivers/windows/lv_windows_display.h index b9c6f8e94d..2ac4653433 100644 --- a/src/drivers/windows/lv_windows_display.h +++ b/src/drivers/windows/lv_windows_display.h @@ -47,8 +47,8 @@ extern "C" { * @param zoom_level The zoom level value. Base value is 100 a.k.a 100%. * @param allow_dpi_override Allow DPI override if true, or follow the * Windows DPI scaling setting dynamically. - * @param simulator_mode Create simulator mode display if true, or create - * application mode display. + * @param simulator_mode Create simulator mode display if true (not resizable), + * or create application mode display (resizable). * @return The created LVGL display object. */ lv_display_t * lv_windows_create_display( diff --git a/src/font/lv_binfont_loader.c b/src/font/lv_binfont_loader.c index a39e2bc642..d53452c9f2 100644 --- a/src/font/lv_binfont_loader.c +++ b/src/font/lv_binfont_loader.c @@ -125,7 +125,7 @@ lv_font_t * lv_binfont_create_from_buffer(void * buffer, uint32_t size) { lv_fs_path_ex_t mempath; - lv_fs_make_path_from_buffer(&mempath, LV_FS_MEMFS_LETTER, buffer, size); + lv_fs_make_path_from_buffer(&mempath, LV_FS_MEMFS_LETTER, buffer, size, "bin"); return lv_binfont_create((const char *)&mempath); } #endif @@ -253,7 +253,7 @@ static bool load_cmaps_tables(lv_fs_file_t * fp, lv_font_fmt_txt_dsc_t * font_ds switch(cmap_table[i].format_type) { case LV_FONT_FMT_TXT_CMAP_FORMAT0_FULL: { - uint8_t ids_size = (uint8_t)(sizeof(uint8_t) * cmap_table[i].data_entries_count); + uint32_t ids_size = (uint32_t)(sizeof(uint8_t) * cmap_table[i].data_entries_count); uint8_t * glyph_id_ofs_list = lv_malloc(ids_size); cmap->glyph_id_ofs_list = glyph_id_ofs_list; @@ -407,6 +407,7 @@ static int32_t load_glyph(lv_fs_file_t * fp, lv_font_fmt_txt_dsc_t * font_dsc, } uint8_t * glyph_bmp = (uint8_t *)lv_malloc(sizeof(uint8_t) * cur_bmp_size); + LV_ASSERT_MALLOC(glyph_bmp); font_dsc->glyph_bitmap = glyph_bmp; diff --git a/src/font/lv_font.c b/src/font/lv_font.c index 26199fc73f..651998ec92 100644 --- a/src/font/lv_font.c +++ b/src/font/lv_font.c @@ -95,19 +95,20 @@ bool lv_font_get_glyph_dsc(const lv_font_t * font_p, lv_font_glyph_dsc_t * dsc_o uint32_t letter_next) { - LV_ASSERT_NULL(font_p); LV_ASSERT_NULL(dsc_out); + LV_ASSERT_NULL(font_p); #if LV_USE_FONT_PLACEHOLDER const lv_font_t * placeholder_font = NULL; #endif - const lv_font_t * f = font_p; + const bool has_kerning = f->kerning != LV_FONT_KERNING_NONE; lv_memzero(dsc_out, sizeof(lv_font_glyph_dsc_t)); while(f) { - bool found = f->get_glyph_dsc(f, dsc_out, letter, f->kerning == LV_FONT_KERNING_NONE ? 0 : letter_next); + bool found = f->get_glyph_dsc(f, dsc_out, letter, + has_kerning ? letter_next : 0); if(found) { if(!dsc_out->is_placeholder) { dsc_out->resolved_font = f; @@ -125,7 +126,7 @@ bool lv_font_get_glyph_dsc(const lv_font_t * font_p, lv_font_glyph_dsc_t * dsc_o #if LV_USE_FONT_PLACEHOLDER if(placeholder_font != NULL) { placeholder_font->get_glyph_dsc(placeholder_font, dsc_out, letter, - placeholder_font->kerning == LV_FONT_KERNING_NONE ? 0 : letter_next); + has_kerning ? letter_next : 0); dsc_out->resolved_font = placeholder_font; return true; } @@ -147,19 +148,18 @@ bool lv_font_get_glyph_dsc(const lv_font_t * font_p, lv_font_glyph_dsc_t * dsc_o dsc_out->format = LV_FONT_GLYPH_FORMAT_A1; dsc_out->is_placeholder = true; - return false; } uint16_t lv_font_get_glyph_width(const lv_font_t * font, uint32_t letter, uint32_t letter_next) { - LV_ASSERT_NULL(font); lv_font_glyph_dsc_t g; /*Return zero if letter is marker*/ if(lv_text_is_marker(letter)) return 0; lv_font_get_glyph_dsc(font, &g, letter, letter_next); + return g.adv_w; } diff --git a/src/font/lv_font.h b/src/font/lv_font.h index 1808918320..1a3a59a063 100644 --- a/src/font/lv_font.h +++ b/src/font/lv_font.h @@ -36,7 +36,7 @@ extern "C" { typedef enum { LV_FONT_GLYPH_FORMAT_NONE = 0, /**< Maybe not visible*/ - /**< Legacy simple formats with no byte padding at end of the lines*/ + /**< Legacy simple formats*/ LV_FONT_GLYPH_FORMAT_A1 = 0x01, /**< 1 bit per pixel*/ LV_FONT_GLYPH_FORMAT_A2 = 0x02, /**< 2 bit per pixel*/ LV_FONT_GLYPH_FORMAT_A3 = 0x03, /**< 3 bit per pixel*/ @@ -68,10 +68,10 @@ typedef struct { * 1: return the bitmap as it is (Maybe A1/2/4 or any proprietary formats). */ uint8_t req_raw_bitmap: 1; - int32_t outline_stroke_width; /**< used with freetype vector fonts - width of the letter outline */ + int32_t outline_stroke_width; /**< used with freetype vector fonts - width of the letter border */ union { - uint32_t index; /**< Unicode code point*/ + uint32_t index; /**< Glyph descriptor index*/ const void * src; /**< Pointer to the source data used by image fonts*/ } gid; /**< The index of the glyph in the font file. Used by the font cache*/ lv_cache_entry_t * entry; /**< The cache entry of the glyph draw data. Used by the font cache*/ @@ -113,7 +113,7 @@ struct _lv_font_t { int8_t underline_thickness; /**< Thickness of the underline*/ const void * dsc; /**< Store implementation specific or run_time data or caching here*/ - const lv_font_t * fallback; /**< Fallback font for missing glyph. Resolved recursively */ + const lv_font_t * fallback; /**< Fallback font for missing glyph. Resolved recursively */ void * user_data; /**< Custom user data for font.*/ }; @@ -172,7 +172,6 @@ const void * lv_font_get_glyph_static_bitmap(lv_font_glyph_dsc_t * g_dsc); */ bool lv_font_get_glyph_dsc(const lv_font_t * font, lv_font_glyph_dsc_t * dsc_out, uint32_t letter, uint32_t letter_next); - /** * Release the bitmap of a font. * @note You must call lv_font_get_glyph_dsc() to get `g_dsc` (lv_font_glyph_dsc_t) before you can call this function. @@ -322,14 +321,6 @@ LV_FONT_DECLARE(lv_font_montserrat_28_compressed) LV_FONT_DECLARE(lv_font_dejavu_16_persian_hebrew) #endif -#if LV_FONT_SIMSUN_14_CJK -LV_FONT_DECLARE(lv_font_simsun_14_cjk) -#endif - -#if LV_FONT_SIMSUN_16_CJK -LV_FONT_DECLARE(lv_font_simsun_16_cjk) -#endif - #if LV_FONT_SOURCE_HAN_SANS_SC_14_CJK LV_FONT_DECLARE(lv_font_source_han_sans_sc_14_cjk) #endif @@ -355,4 +346,4 @@ LV_FONT_CUSTOM_DECLARE } /*extern "C"*/ #endif -#endif /*USE_FONT*/ +#endif /*LV_FONT_H*/ diff --git a/src/font/lv_font_fmt_txt.c b/src/font/lv_font_fmt_txt.c index 7dbdfb578a..6df2f9a276 100644 --- a/src/font/lv_font_fmt_txt.c +++ b/src/font/lv_font_fmt_txt.c @@ -103,7 +103,8 @@ const void * lv_font_get_bitmap_fmt_txt(lv_font_glyph_dsc_t * g_dsc, lv_draw_buf int32_t gsize = (int32_t) gdsc->box_w * gdsc->box_h; if(gsize == 0) return NULL; - uint16_t stride_in = g_dsc->stride; + uint32_t stride_in = g_dsc->stride; + if(fdsc->bitmap_format == LV_FONT_FMT_TXT_PLAIN) { const uint8_t * bitmap_in = &fdsc->glyph_bitmap[gdsc->bitmap_index]; @@ -139,7 +140,7 @@ const void * lv_font_get_bitmap_fmt_txt(lv_font_glyph_dsc_t * g_dsc, lv_draw_buf } else if(fdsc->bpp == 2) { for(y = 0; y < gdsc->box_h; y ++) { - uint16_t line_rem = stride_in != 0 ? stride_in : gdsc->box_w; + uint32_t line_rem = stride_in != 0 ? stride_in : gdsc->box_w; for(x = 0; x < gdsc->box_w; x++, i++) { i = i & 0x3; if(i == 0) bitmap_out_tmp[x] = opa2_table[(*bitmap_in) >> 6]; @@ -257,9 +258,13 @@ bool lv_font_get_glyph_dsc_fmt_txt(const lv_font_t * font, lv_font_glyph_dsc_t * if(fdsc->stride == 0) dsc_out->stride = 0; else { - /*e.g. font_dsc stride == 4 means align to 4 byte boundary. + /*E.g. w = 5, bpp = 2, means 2 bytes/line*/ + uint32_t bit_count = dsc_out->box_w * fdsc->bpp; + uint32_t width_in_bytes = (bit_count + 7) >> 3; /*No division round up*/ + + /*E.g. font_dsc stride == 4 means align to 4 byte boundary. *In glyph_dsc store the actual line length in bytes*/ - dsc_out->stride = LV_ROUND_UP(dsc_out->box_w, fdsc->stride); + dsc_out->stride = LV_ROUND_UP(width_in_bytes, fdsc->stride); } dsc_out->format = (uint8_t)fdsc->bpp; diff --git a/src/font/lv_font_montserrat_14_aligned.c b/src/font/lv_font_montserrat_14_aligned.c index c364e01810..6ea0971cdd 100644 --- a/src/font/lv_font_montserrat_14_aligned.c +++ b/src/font/lv_font_montserrat_14_aligned.c @@ -15,7 +15,7 @@ #ifdef LV_LVGL_H_INCLUDE_SIMPLE #include "lvgl.h" #else - #include "lvgl/lvgl.h" + #include "../../lvgl.h" #endif #if !LV_VERSION_CHECK(9, 3, 0) diff --git a/src/font/lv_font_simsun_14_cjk.c b/src/font/lv_font_simsun_14_cjk.c deleted file mode 100644 index 81f1fa7f63..0000000000 --- a/src/font/lv_font_simsun_14_cjk.c +++ /dev/null @@ -1,20789 +0,0 @@ -/******************************************************************************* - * Size: 14 px - * Bpp: 4 - * Opts: --no-compress --no-prefilter --bpp 4 --size 14 --font SimSun.woff -r 0x20-0x7f --symbols (),盗提陽帯鼻画輕ッ冊ェル写父ぁフ結想正四O夫源庭場天續鳥れ講猿苦階給了製守8祝己妳薄泣塩帰ぺ吃変輪那着仍嗯爭熱創味保字宿捨準查達肯ァ薬得査障該降察ね網加昼料等図邪秋コ態品屬久原殊候路願楽確針上被怕悲風份重歡っ附ぷ既4黨價娘朝凍僅際洋止右航よ专角應酸師個比則響健昇豐筆歷適修據細忙跟管長令家ザ期般花越ミ域泳通些油乏ラ。營ス返調農叫樹刊愛間包知把ヤ貧橋拡普聞前ジ建当繰ネ送習渇用補ィ覺體法遊宙ョ酔余利壊語くつ払皆時辺追奇そ們只胸械勝住全沈力光ん深溝二類北面社值試9和五勵ゃ貿幾逐打課ゲて領3鼓辦発評1渉詳暇込计駄供嘛郵頃腦反構絵お容規借身妻国慮剛急乗静必議置克土オ乎荷更肉還混古渡授合主離條値決季晴東大尚央州が嗎験流先医亦林田星晩拿60旅婦量為痛テ孫う環友況玩務其ぼち揺坐一肩腰犯タょ希即果ぶ物練待み高九找やヶ都グ去」サ、气仮雑酒許終企笑録形リ銀切ギ快問滿役単黄集森毎實研喜蘇司鉛洲川条媽ノ才兩話言雖媒出客づ卻現異故り誌逮同訊已視本題ぞを横開音第席費持眾怎選元退限ー賽処喝就残無いガ多ケ沒義遠歌隣錢某雪析嬉採自透き側員予ゼ白婚电へ顯呀始均畫似懸格車騒度わ親店週維億締慣免帳電甚來園浴ゅ愈京と杯各海怒ぜ排敗挙老買7極模実紀ヒ携隻告シ並屋這孩讓質ワブ富賃争康由辞マ火於短樣削弟材注節另室ダ招擁ぃ若套底波行勤關著泊背疲狭作念推ぐ民貸祖介說ビ代温契你我レ入描變再札ソ派頭智遅私聽舉灣山伸放直安ト誕煙付符幅ふ絡她届耳飲忘参革團仕様載ど歩獲嫌息の汚交興魚指資雙與館初学年幸史位柱族走括び考青也共腕Lで販擔理病イ今逃當寺猫邊菓係ム秘示解池影ド文例斷曾事茶寫明科桃藝売便え導禁財飛替而亡到し具空寝辛業ウ府セ國何基菜厳市努張缺雲根外だ断万砂ゴ超使台实ぽ礼最慧算軟界段律像夕丈窓助刻月夏政呼ぴざ擇趣除動従涼方勉名線対存請子氏將5少否諸論美感或西者定食御表は參歳緑命進易性錯房も捕皿判中觀戦ニ緩町ピ番ず金千ろ?不た象治関ャ每看徒卒統じ手範訪押座步号ベ旁以母すほ密減成往歲件緒読歯效院种七謂凝濃嵌震喉繼クュ拭死円2積水欲如ポにさ寒道區精啦姐ア聯能足及停思壓2春且メ裏株官答概黒過氷柿戻厚ぱ党祭織引計け委暗複誘港バ失下村較続神ぇ尤強秀膝兒来績十書済化服破新廠1紹您情半式產系好教暑早め樂地休協良な哪常要揮周かエ麗境働避護ンツ香夜太見設非改広聲他検求危清彼經未在起葉控靴所差內造寄南望尺換向展備眠點完約ぎ裡分説申童優伝島机須塊日立拉,鉄軽單気信很転識支布数紙此迎受心輸坊モ處「訳三曇兄野顔戰增ナ伊列又髪両有取左毛至困吧昔赤狀相夠整別士経頼然簡ホ会發隨営需脱ヨば接永居冬迫圍甘醫誰部充消連弱宇會咲覚姉麼的増首统帶糖朋術商担移景功育庫曲總劃牛程駅犬報ロ學責因パ嚴八世後平負公げ曜陸專午之閉ぬ談ご災昨冷職悪謝對它近射敢意運船臉局難什産頗!球真記ま但蔵究制機案湖臺ひ害券男留内木驗雨施種特復句末濟キ色訴依せ百型る石牠討呢时任執飯歐宅組傳配小活ゆべ暖ズ漸站素らボ束価チ浅回女片独妹英目從認生違策僕楚ペ米こ掛む爸六状落漢プ投カ校做啊洗声探あ割体項履触々訓技ハ低工映是標速善点人デ口次可廿节宵植树端阳旦腊妇费愚劳动儿军师庆圣诞闰 --font FontAwesome5-Solid+Brands+Regular.woff -r 61441,61448,61451,61452,61452,61453,61457,61459,61461,61465,61468,61473,61478,61479,61480,61502,61507,61512,61515,61516,61517,61521,61522,61523,61524,61543,61544,61550,61552,61553,61556,61559,61560,61561,61563,61587,61589,61636,61637,61639,61641,61664,61671,61674,61683,61724,61732,61787,61931,62016,62017,62018,62019,62020,62087,62099,62212,62189,62810,63426,63650 --format lvgl -o lv_font_simsun_14_cjk.c --force-fast-kern-format - ******************************************************************************/ - -#ifdef LV_LVGL_H_INCLUDE_SIMPLE - #include "lvgl.h" -#else - #include "../../lvgl.h" -#endif - -#ifndef LV_FONT_SIMSUN_14_CJK - #define LV_FONT_SIMSUN_14_CJK 1 -#endif - -#if LV_FONT_SIMSUN_14_CJK - -/*----------------- - * BITMAPS - *----------------*/ - -/*Store the image of the glyphs*/ -static LV_ATTRIBUTE_LARGE_CONST const uint8_t glyph_bitmap[] = { - /* U+0020 " " */ - - /* U+0021 "!" */ - 0x1d, 0x2, 0xf0, 0xe, 0x0, 0xc0, 0xa, 0x0, - 0x80, 0x5, 0x0, 0x0, 0x18, 0x2, 0xe1, - - /* U+0022 "\"" */ - 0x0, 0x89, 0x5b, 0x1, 0xe3, 0xd5, 0x8, 0x45, - 0x60, 0x4, 0x4, 0x0, - - /* U+0023 "#" */ - 0x0, 0x70, 0x7, 0x0, 0x7, 0x0, 0x70, 0x7f, - 0xff, 0xff, 0x71, 0x46, 0x24, 0x61, 0x4, 0x30, - 0x43, 0x0, 0x52, 0x5, 0x20, 0x7f, 0xff, 0xff, - 0x71, 0x92, 0x28, 0x21, 0x7, 0x0, 0x70, 0x0, - 0x70, 0x7, 0x0, - - /* U+0024 "$" */ - 0x0, 0x4, 0x0, 0x0, 0x8, 0x0, 0x1, 0x8b, - 0x82, 0x9, 0x28, 0x4a, 0xc, 0x28, 0x46, 0x6, - 0xc9, 0x0, 0x0, 0x8f, 0x30, 0x0, 0xa, 0xe2, - 0x0, 0x8, 0x6a, 0xd, 0x28, 0xc, 0xe, 0x8, - 0x19, 0x4, 0x7b, 0x71, 0x0, 0x8, 0x0, 0x0, - 0x4, 0x0, - - /* U+0025 "%" */ - 0x0, 0x0, 0x2, 0x4, 0x76, 0x3, 0x40, 0xa0, - 0x90, 0x70, 0xb, 0x9, 0x16, 0x0, 0x90, 0xa5, - 0x10, 0x1, 0x64, 0x64, 0x60, 0x0, 0x15, 0x93, - 0x60, 0x6, 0x37, 0x9, 0x0, 0x64, 0x70, 0xa0, - 0x32, 0x18, 0x28, 0x5, 0x0, 0x78, 0x10, - - /* U+0026 "&" */ - 0x3, 0x79, 0x0, 0x0, 0xa0, 0x83, 0x0, 0xb, - 0x9, 0x20, 0x0, 0xa5, 0x80, 0x0, 0x8, 0xa0, - 0x78, 0x14, 0x6d, 0x4, 0x40, 0xb0, 0x95, 0x51, - 0xc, 0x2, 0xd7, 0x0, 0x95, 0x8, 0xb0, 0x31, - 0xb9, 0x68, 0xc5, - - /* U+0027 "'" */ - 0xd, 0x60, 0x8a, 0x5, 0x50, 0x60, - - /* U+0028 "(" */ - 0x0, 0x0, 0x0, 0x71, 0x5, 0x40, 0xa, 0x0, - 0x65, 0x0, 0xb1, 0x0, 0xc0, 0x0, 0xc0, 0x0, - 0xc0, 0x0, 0xb0, 0x0, 0x65, 0x0, 0x1a, 0x0, - 0x6, 0x40, 0x0, 0x81, 0x0, 0x1, - - /* U+0029 ")" */ - 0x0, 0x0, 0x26, 0x0, 0x5, 0x40, 0x0, 0xa0, - 0x0, 0x65, 0x0, 0x2a, 0x0, 0xc, 0x0, 0xc, - 0x0, 0xc, 0x0, 0x1b, 0x0, 0x66, 0x0, 0xa0, - 0x4, 0x50, 0x17, 0x0, 0x10, 0x0, - - /* U+002A "*" */ - 0x0, 0x5, 0x0, 0x0, 0x0, 0xf0, 0x0, 0x6b, - 0xb, 0x1c, 0x50, 0x7a, 0x7a, 0x70, 0x0, 0x6a, - 0x60, 0x4, 0xe5, 0x86, 0xe3, 0x24, 0xd, 0x4, - 0x20, 0x0, 0xd0, 0x0, - - /* U+002B "+" */ - 0x0, 0x1, 0x0, 0x0, 0x0, 0x70, 0x0, 0x0, - 0x7, 0x0, 0x0, 0x0, 0x70, 0x0, 0x38, 0x8c, - 0x88, 0x40, 0x0, 0x70, 0x0, 0x0, 0x7, 0x0, - 0x0, 0x0, 0x70, 0x0, 0x0, 0x2, 0x0, 0x0, - - /* U+002C "," */ - 0xd, 0x60, 0x8a, 0x5, 0x50, 0x60, - - /* U+002D "-" */ - 0x48, 0x88, 0x88, 0x40, - - /* U+002E "." */ - 0x9, 0x40, 0xd6, - - /* U+002F "/" */ - 0x0, 0x0, 0x1, 0x30, 0x0, 0x0, 0x60, 0x0, - 0x0, 0x7, 0x0, 0x0, 0x5, 0x10, 0x0, 0x0, - 0x70, 0x0, 0x0, 0x43, 0x0, 0x0, 0x7, 0x0, - 0x0, 0x2, 0x50, 0x0, 0x0, 0x70, 0x0, 0x0, - 0x6, 0x0, 0x0, 0x6, 0x10, 0x0, 0x0, 0x70, - 0x0, 0x0, 0x42, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, - - /* U+0030 "0" */ - 0x0, 0x97, 0x90, 0x0, 0x95, 0x4, 0x90, 0xe, - 0x0, 0xe, 0x3, 0xc0, 0x0, 0xd3, 0x4b, 0x0, - 0xc, 0x45, 0xb0, 0x0, 0xc3, 0x3c, 0x0, 0xd, - 0x20, 0xe0, 0x0, 0xe0, 0x9, 0x50, 0x48, 0x0, - 0x9, 0x79, 0x0, - - /* U+0031 "1" */ - 0x26, 0xe0, 0x0, 0xe, 0x0, 0x0, 0xe0, 0x0, - 0xe, 0x0, 0x0, 0xe0, 0x0, 0xe, 0x0, 0x0, - 0xe0, 0x0, 0xe, 0x0, 0x0, 0xe0, 0x2, 0x7f, - 0x83, - - /* U+0032 "2" */ - 0x3, 0x76, 0x93, 0x0, 0xb0, 0x1, 0xd0, 0x1f, - 0x0, 0xe, 0x0, 0x40, 0x1, 0xc0, 0x0, 0x0, - 0x84, 0x0, 0x0, 0x46, 0x0, 0x0, 0x36, 0x0, - 0x0, 0x17, 0x0, 0x20, 0x8, 0x0, 0x8, 0x4, - 0xee, 0xee, 0xd0, - - /* U+0033 "3" */ - 0x4, 0x67, 0x91, 0x0, 0xd0, 0x5, 0x90, 0x8, - 0x0, 0x3b, 0x0, 0x0, 0x8, 0x40, 0x0, 0x2a, - 0x80, 0x0, 0x0, 0x5, 0x80, 0x0, 0x0, 0xe, - 0x0, 0xb0, 0x0, 0xe0, 0x1e, 0x0, 0x2b, 0x0, - 0x57, 0x68, 0x10, - - /* U+0034 "4" */ - 0x0, 0x0, 0xc0, 0x0, 0x0, 0x6e, 0x0, 0x0, - 0x15, 0xd0, 0x0, 0x7, 0xd, 0x0, 0x4, 0x20, - 0xd0, 0x0, 0x60, 0xd, 0x0, 0x45, 0x55, 0xe5, - 0x20, 0x0, 0xd, 0x0, 0x0, 0x0, 0xd0, 0x0, - 0x1, 0x6f, 0x81, - - /* U+0035 "5" */ - 0x8, 0xee, 0xec, 0x0, 0x60, 0x0, 0x0, 0x6, - 0x0, 0x0, 0x0, 0x68, 0x9b, 0x20, 0x9, 0x10, - 0x3b, 0x0, 0x0, 0x0, 0xe0, 0x1, 0x0, 0xd, - 0x11, 0xf0, 0x0, 0xd0, 0xc, 0x0, 0x2a, 0x0, - 0x37, 0x69, 0x10, - - /* U+0036 "6" */ - 0x0, 0x66, 0x96, 0x0, 0x73, 0x2, 0x60, 0xc, - 0x0, 0x0, 0x2, 0xb6, 0x9c, 0x40, 0x4e, 0x40, - 0x1d, 0x5, 0xc0, 0x0, 0xb3, 0x4c, 0x0, 0xa, - 0x41, 0xe0, 0x0, 0xb2, 0xb, 0x40, 0xb, 0x0, - 0x1a, 0x68, 0x20, - - /* U+0037 "7" */ - 0xd, 0xee, 0xef, 0x10, 0x90, 0x0, 0x70, 0x2, - 0x0, 0x61, 0x0, 0x0, 0x8, 0x0, 0x0, 0x5, - 0x40, 0x0, 0x0, 0xb0, 0x0, 0x0, 0x1c, 0x0, - 0x0, 0x5, 0xb0, 0x0, 0x0, 0x7b, 0x0, 0x0, - 0x6, 0xa0, 0x0, - - /* U+0038 "8" */ - 0x3, 0x86, 0x82, 0x0, 0xb0, 0x0, 0xb0, 0x2b, - 0x0, 0xb, 0x0, 0xd6, 0x1, 0xa0, 0x1, 0xec, - 0x90, 0x0, 0x83, 0x5e, 0x50, 0x39, 0x0, 0x2e, - 0x5, 0x60, 0x0, 0xb2, 0x29, 0x0, 0xb, 0x0, - 0x47, 0x67, 0x30, - - /* U+0039 "9" */ - 0x4, 0x87, 0x81, 0x1, 0xc0, 0x2, 0xa0, 0x59, - 0x0, 0xd, 0x5, 0x90, 0x0, 0xe2, 0x1d, 0x10, - 0x6e, 0x30, 0x49, 0x83, 0xe2, 0x0, 0x0, 0xf, - 0x0, 0x10, 0x3, 0xa0, 0xd, 0x30, 0x94, 0x0, - 0x79, 0x76, 0x0, - - /* U+003A ":" */ - 0x3e, 0x1, 0x80, 0x0, 0x0, 0x0, 0x0, 0x1, - 0x80, 0x3e, 0x0, - - /* U+003B ";" */ - 0x3f, 0x1, 0x50, 0x0, 0x0, 0x0, 0x0, 0x1, - 0x50, 0x3f, 0x0, 0xa0, 0x3, 0x0, - - /* U+003C "<" */ - 0x0, 0x0, 0x5, 0x0, 0x0, 0x5, 0x40, 0x0, - 0x5, 0x50, 0x0, 0x4, 0x60, 0x0, 0x3, 0x70, - 0x0, 0x0, 0xa0, 0x0, 0x0, 0x4, 0x60, 0x0, - 0x0, 0x5, 0x50, 0x0, 0x0, 0x6, 0x40, 0x0, - 0x0, 0x6, 0x30, 0x0, 0x0, 0x6, 0x0, - - /* U+003D "=" */ - 0x48, 0x88, 0x88, 0x40, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x4, 0x88, 0x88, 0x84, - - /* U+003E ">" */ - 0x5, 0x0, 0x0, 0x0, 0x46, 0x0, 0x0, 0x0, - 0x55, 0x0, 0x0, 0x0, 0x64, 0x0, 0x0, 0x0, - 0x73, 0x0, 0x0, 0x0, 0xa0, 0x0, 0x0, 0x64, - 0x0, 0x0, 0x55, 0x0, 0x0, 0x46, 0x0, 0x0, - 0x37, 0x0, 0x0, 0x6, 0x0, 0x0, 0x0, - - /* U+003F "?" */ - 0x2, 0x88, 0xa4, 0x0, 0x80, 0x0, 0xd1, 0x3a, - 0x0, 0xb, 0x31, 0x90, 0x0, 0xe1, 0x0, 0x1, - 0xa5, 0x0, 0x0, 0x81, 0x0, 0x0, 0x7, 0x0, - 0x0, 0x0, 0x20, 0x0, 0x0, 0x18, 0x0, 0x0, - 0x3, 0xe0, 0x0, - - /* U+0040 "@" */ - 0x0, 0x77, 0x74, 0x0, 0x72, 0x46, 0xa2, 0x9, - 0x17, 0x65, 0x74, 0x67, 0x27, 0x37, 0x65, 0xb0, - 0x91, 0x76, 0x5b, 0xa, 0x7, 0x46, 0xa1, 0xc4, - 0x31, 0x95, 0x66, 0x61, 0x8, 0x10, 0x4, 0x30, - 0x8, 0x77, 0x50, - - /* U+0041 "A" */ - 0x0, 0xb, 0x0, 0x0, 0x4, 0xe2, 0x0, 0x0, - 0x77, 0x60, 0x0, 0x8, 0x49, 0x0, 0x0, 0x70, - 0xd0, 0x0, 0x44, 0xc, 0x10, 0x7, 0x65, 0xb5, - 0x0, 0x80, 0x5, 0x80, 0x7, 0x0, 0x1c, 0x8, - 0xb0, 0x4, 0xf5, - - /* U+0042 "B" */ - 0x4e, 0x66, 0x95, 0x0, 0xd0, 0x0, 0xe0, 0xd, - 0x0, 0xe, 0x0, 0xd0, 0x3, 0xb0, 0xd, 0x56, - 0xb1, 0x0, 0xd0, 0x1, 0xc0, 0xd, 0x0, 0x9, - 0x60, 0xd0, 0x0, 0x97, 0xd, 0x0, 0xc, 0x34, - 0xe6, 0x68, 0x60, - - /* U+0043 "C" */ - 0x0, 0x87, 0x8f, 0x10, 0x94, 0x0, 0x54, 0x1d, - 0x0, 0x0, 0x36, 0x90, 0x0, 0x0, 0x88, 0x0, - 0x0, 0x8, 0x80, 0x0, 0x0, 0x79, 0x0, 0x0, - 0x4, 0xc0, 0x0, 0x4, 0xd, 0x30, 0x6, 0x10, - 0x1a, 0x88, 0x30, - - /* U+0044 "D" */ - 0x4e, 0x76, 0x80, 0x0, 0xd0, 0x3, 0xb0, 0xd, - 0x0, 0xc, 0x30, 0xd0, 0x0, 0x96, 0xd, 0x0, - 0x8, 0x70, 0xd0, 0x0, 0x87, 0xd, 0x0, 0xa, - 0x60, 0xd0, 0x0, 0xd2, 0xd, 0x0, 0x4a, 0x4, - 0xe7, 0x78, 0x0, - - /* U+0045 "E" */ - 0x3e, 0x75, 0x7d, 0x0, 0xc1, 0x0, 0x43, 0xc, - 0x10, 0x0, 0x0, 0xc1, 0x5, 0x0, 0xc, 0x65, - 0xd0, 0x0, 0xc1, 0x6, 0x0, 0xc, 0x10, 0x20, - 0x0, 0xc1, 0x0, 0x1, 0xc, 0x10, 0x2, 0x53, - 0xe7, 0x57, 0xe1, - - /* U+0046 "F" */ - 0x3e, 0x75, 0x6d, 0x30, 0xc1, 0x0, 0x17, 0xc, - 0x10, 0x0, 0x0, 0xc1, 0x2, 0x40, 0xc, 0x65, - 0xb4, 0x0, 0xc1, 0x2, 0x40, 0xc, 0x10, 0x1, - 0x0, 0xc1, 0x0, 0x0, 0xc, 0x10, 0x0, 0x4, - 0xe7, 0x0, 0x0, - - /* U+0047 "G" */ - 0x1, 0x97, 0xc8, 0x0, 0xa2, 0x0, 0x90, 0x1a, - 0x0, 0x3, 0x6, 0x70, 0x0, 0x0, 0x86, 0x0, - 0x0, 0x9, 0x60, 0x7, 0xa4, 0x77, 0x0, 0xe, - 0x3, 0xb0, 0x0, 0xd0, 0xc, 0x10, 0xd, 0x0, - 0x29, 0x67, 0x40, - - /* U+0048 "H" */ - 0x5f, 0x30, 0x3f, 0x40, 0xd0, 0x0, 0xe0, 0xd, - 0x0, 0xe, 0x0, 0xd0, 0x0, 0xe0, 0xe, 0x55, - 0x5e, 0x0, 0xd0, 0x0, 0xe0, 0xd, 0x0, 0xe, - 0x0, 0xd0, 0x0, 0xe0, 0xd, 0x0, 0xe, 0x5, - 0xf3, 0x4, 0xf4, - - /* U+0049 "I" */ - 0x36, 0xf6, 0x30, 0xe, 0x0, 0x0, 0xe0, 0x0, - 0xe, 0x0, 0x0, 0xe0, 0x0, 0xe, 0x0, 0x0, - 0xe0, 0x0, 0xe, 0x0, 0x0, 0xe0, 0x3, 0x6f, - 0x63, - - /* U+004A "J" */ - 0x0, 0x46, 0xf5, 0x30, 0x0, 0xe, 0x0, 0x0, - 0x0, 0xe0, 0x0, 0x0, 0xe, 0x0, 0x0, 0x0, - 0xe0, 0x0, 0x0, 0xe, 0x0, 0x0, 0x0, 0xe0, - 0x0, 0x0, 0xe, 0x0, 0x0, 0x0, 0xe0, 0x0, - 0x0, 0xd, 0x0, 0x57, 0x3, 0x90, 0x3, 0xb6, - 0x70, 0x0, - - /* U+004B "K" */ - 0x4e, 0x50, 0x8c, 0x20, 0xd0, 0x7, 0x0, 0xd, - 0x4, 0x30, 0x0, 0xd1, 0x70, 0x0, 0xd, 0x8c, - 0x0, 0x0, 0xd4, 0xa4, 0x0, 0xd, 0x3, 0xb0, - 0x0, 0xd0, 0xc, 0x20, 0xd, 0x0, 0x59, 0x4, - 0xe6, 0x4, 0xf5, - - /* U+004C "L" */ - 0x2d, 0x80, 0x0, 0x0, 0xb3, 0x0, 0x0, 0xb, - 0x30, 0x0, 0x0, 0xb3, 0x0, 0x0, 0xb, 0x30, - 0x0, 0x0, 0xb3, 0x0, 0x0, 0xb, 0x30, 0x0, - 0x0, 0xb3, 0x0, 0x1, 0xb, 0x30, 0x1, 0x53, - 0xd8, 0x56, 0xd2, - - /* U+004D "M" */ - 0x7c, 0x0, 0xf, 0x62, 0xe0, 0x3, 0xe2, 0x2b, - 0x30, 0x6c, 0x22, 0x86, 0x6, 0xc2, 0x25, 0x90, - 0x6c, 0x22, 0x2c, 0x14, 0xc2, 0x22, 0xb5, 0xc, - 0x22, 0x28, 0x90, 0xc2, 0x22, 0x59, 0xc, 0x27, - 0x72, 0x63, 0xe7, - - /* U+004E "N" */ - 0x4f, 0x10, 0x1a, 0x50, 0xc8, 0x0, 0x50, 0x5, - 0xd1, 0x5, 0x0, 0x57, 0x80, 0x50, 0x5, 0xd, - 0x5, 0x0, 0x50, 0x87, 0x50, 0x5, 0x1, 0xe5, - 0x0, 0x50, 0x8, 0xc0, 0x5, 0x0, 0x1f, 0x5, - 0xa1, 0x0, 0x90, - - /* U+004F "O" */ - 0x1, 0x96, 0x81, 0x0, 0xa2, 0x0, 0xb0, 0x1c, - 0x0, 0xb, 0x35, 0x90, 0x0, 0x87, 0x78, 0x0, - 0x7, 0x97, 0x80, 0x0, 0x79, 0x59, 0x0, 0x7, - 0x71, 0xb0, 0x0, 0xa3, 0xa, 0x20, 0xb, 0x0, - 0x18, 0x57, 0x20, - - /* U+0050 "P" */ - 0x3e, 0x75, 0x75, 0x0, 0xc1, 0x0, 0xb2, 0xc, - 0x10, 0x8, 0x60, 0xc1, 0x0, 0x95, 0xc, 0x10, - 0x1c, 0x0, 0xc6, 0x57, 0x10, 0xc, 0x10, 0x0, - 0x0, 0xc1, 0x0, 0x0, 0xc, 0x10, 0x0, 0x4, - 0xe7, 0x0, 0x0, - - /* U+0051 "Q" */ - 0x2, 0x96, 0x81, 0x0, 0xc1, 0x1, 0xb0, 0x3b, - 0x0, 0xb, 0x36, 0x90, 0x0, 0x87, 0x87, 0x0, - 0x7, 0x88, 0x70, 0x0, 0x78, 0x78, 0x0, 0x8, - 0x74, 0xa8, 0xa1, 0xa3, 0xd, 0x44, 0x9b, 0x0, - 0x28, 0x7f, 0x30, 0x0, 0x0, 0x7d, 0x20, - - /* U+0052 "R" */ - 0x3d, 0x76, 0x95, 0x0, 0xb2, 0x0, 0xe1, 0xb, - 0x20, 0xc, 0x20, 0xb2, 0x2, 0xc0, 0xb, 0x68, - 0x91, 0x0, 0xb2, 0x58, 0x0, 0xb, 0x20, 0xd0, - 0x0, 0xb2, 0xa, 0x40, 0xb, 0x20, 0x49, 0x3, - 0xd7, 0x0, 0xe4, - - /* U+0053 "S" */ - 0x4, 0x67, 0xcb, 0x1, 0x80, 0x0, 0x90, 0x37, - 0x0, 0x1, 0x1, 0xd3, 0x0, 0x0, 0x3, 0xcb, - 0x20, 0x0, 0x0, 0x5d, 0x50, 0x0, 0x0, 0x1d, - 0x3, 0x10, 0x0, 0x92, 0x38, 0x0, 0xa, 0x0, - 0xfa, 0x67, 0x30, - - /* U+0054 "T" */ - 0x3b, 0x6f, 0x6b, 0x26, 0x0, 0xe0, 0x15, 0x10, - 0xe, 0x0, 0x10, 0x0, 0xe0, 0x0, 0x0, 0xe, - 0x0, 0x0, 0x0, 0xe0, 0x0, 0x0, 0xe, 0x0, - 0x0, 0x0, 0xe0, 0x0, 0x0, 0xe, 0x0, 0x0, - 0x6, 0xf5, 0x0, - - /* U+0055 "U" */ - 0x5f, 0x30, 0x1a, 0x40, 0xd0, 0x0, 0x50, 0xd, - 0x0, 0x5, 0x0, 0xd0, 0x0, 0x50, 0xd, 0x0, - 0x5, 0x0, 0xd0, 0x0, 0x50, 0xd, 0x0, 0x5, - 0x0, 0xd0, 0x0, 0x50, 0xc, 0x0, 0x6, 0x0, - 0x39, 0x77, 0x10, - - /* U+0056 "V" */ - 0x5f, 0x30, 0x2c, 0x40, 0xd1, 0x0, 0x70, 0x9, - 0x40, 0x15, 0x0, 0x58, 0x5, 0x10, 0x2, 0xc0, - 0x60, 0x0, 0xd, 0x6, 0x0, 0x0, 0xa4, 0x50, - 0x0, 0x7, 0xb1, 0x0, 0x0, 0x3d, 0x0, 0x0, - 0x0, 0x80, 0x0, - - /* U+0057 "W" */ - 0x9a, 0x2e, 0x36, 0x83, 0x80, 0xb0, 0x32, 0x1a, - 0xb, 0x25, 0x0, 0xb0, 0xd4, 0x50, 0xb, 0x1a, - 0x65, 0x0, 0xa5, 0x58, 0x50, 0x8, 0x91, 0xb5, - 0x0, 0x6b, 0xe, 0x20, 0x3, 0x90, 0xc0, 0x0, - 0x16, 0x7, 0x0, - - /* U+0058 "X" */ - 0x2d, 0x70, 0x4c, 0x20, 0x57, 0x3, 0x30, 0x0, - 0xc0, 0x70, 0x0, 0x8, 0x75, 0x0, 0x0, 0x1e, - 0x0, 0x0, 0x0, 0xe3, 0x0, 0x0, 0x65, 0xa0, - 0x0, 0x7, 0xc, 0x10, 0x5, 0x20, 0x68, 0x3, - 0xd2, 0x5, 0xf4, - - /* U+0059 "Y" */ - 0x4f, 0x40, 0x3d, 0x40, 0xa3, 0x0, 0x60, 0x4, - 0x90, 0x41, 0x0, 0xd, 0x6, 0x0, 0x0, 0x95, - 0x50, 0x0, 0x3, 0xd0, 0x0, 0x0, 0xe, 0x0, - 0x0, 0x0, 0xe0, 0x0, 0x0, 0xe, 0x0, 0x0, - 0x6, 0xf5, 0x0, - - /* U+005A "Z" */ - 0xb, 0x95, 0x5e, 0x21, 0x70, 0x4, 0xa0, 0x0, - 0x0, 0xc2, 0x0, 0x0, 0x4a, 0x0, 0x0, 0xc, - 0x20, 0x0, 0x4, 0xa0, 0x0, 0x0, 0xb2, 0x0, - 0x0, 0x4a, 0x0, 0x1, 0xb, 0x20, 0x6, 0x24, - 0xd5, 0x57, 0xd0, - - /* U+005B "[" */ - 0x39, 0x88, 0x4, 0x40, 0x0, 0x44, 0x0, 0x4, - 0x40, 0x0, 0x44, 0x0, 0x4, 0x40, 0x0, 0x44, - 0x0, 0x4, 0x40, 0x0, 0x44, 0x0, 0x4, 0x40, - 0x0, 0x44, 0x0, 0x4, 0x40, 0x0, 0x44, 0x0, - 0x3, 0x98, 0x80, - - /* U+005C "\\" */ - 0xa0, 0x0, 0x0, 0x64, 0x0, 0x0, 0x9, 0x0, - 0x0, 0x9, 0x0, 0x0, 0x4, 0x50, 0x0, 0x0, - 0xa0, 0x0, 0x0, 0x81, 0x0, 0x0, 0x27, 0x0, - 0x0, 0xa, 0x0, 0x0, 0x6, 0x30, 0x0, 0x1, - 0x90, 0x0, 0x0, 0x90, 0x0, 0x0, 0x32, - - /* U+005D "]" */ - 0x8, 0x89, 0x20, 0x0, 0x53, 0x0, 0x5, 0x30, - 0x0, 0x53, 0x0, 0x5, 0x30, 0x0, 0x53, 0x0, - 0x5, 0x30, 0x0, 0x53, 0x0, 0x5, 0x30, 0x0, - 0x53, 0x0, 0x5, 0x30, 0x0, 0x53, 0x0, 0x5, - 0x30, 0x88, 0x92, - - /* U+005E "^" */ - 0x8, 0xb8, 0x1, 0x30, 0x31, - - /* U+005F "_" */ - 0x55, 0x55, 0x55, 0x50, - - /* U+0060 "`" */ - 0x5c, 0x30, 0x4, - - /* U+0061 "a" */ - 0x5, 0x65, 0x81, 0x0, 0xd0, 0x4, 0x80, 0x0, - 0x4, 0x79, 0x0, 0x78, 0x23, 0x90, 0x3b, 0x0, - 0x39, 0x5, 0x90, 0x3, 0x92, 0xa, 0x76, 0x6b, - 0x50, - - /* U+0062 "b" */ - 0x3, 0x0, 0x0, 0x4, 0xd0, 0x0, 0x0, 0xc, - 0x0, 0x0, 0x0, 0xc0, 0x0, 0x0, 0xc, 0x47, - 0x94, 0x0, 0xd4, 0x0, 0xc0, 0xc, 0x0, 0xb, - 0x20, 0xc0, 0x0, 0xa3, 0xc, 0x0, 0xb, 0x10, - 0xd1, 0x0, 0xb0, 0x8, 0x66, 0x82, 0x0, - - /* U+0063 "c" */ - 0x0, 0x85, 0x83, 0x0, 0xa2, 0x3, 0xa0, 0xd, - 0x0, 0x2, 0x2, 0xb0, 0x0, 0x0, 0xc, 0x0, - 0x0, 0x0, 0xb2, 0x0, 0x60, 0x1, 0x97, 0x73, - 0x0, - - /* U+0064 "d" */ - 0x0, 0x0, 0x3, 0x0, 0x0, 0x5, 0xc0, 0x0, - 0x0, 0xc, 0x0, 0x0, 0x0, 0xc0, 0x1, 0x97, - 0x6c, 0x0, 0xa2, 0x0, 0xc0, 0xc, 0x0, 0xc, - 0x2, 0xb0, 0x0, 0xc0, 0xc, 0x0, 0xc, 0x0, - 0xb1, 0x3, 0xc0, 0x2, 0x97, 0x5c, 0x30, - - /* U+0065 "e" */ - 0x0, 0x86, 0x82, 0x0, 0x92, 0x1, 0xc0, 0xc, - 0x0, 0xc, 0x11, 0xd5, 0x55, 0x91, 0xd, 0x0, - 0x0, 0x0, 0xa2, 0x0, 0x50, 0x1, 0x97, 0x73, - 0x0, - - /* U+0066 "f" */ - 0x0, 0x7, 0x58, 0x50, 0x6, 0x40, 0x24, 0x0, - 0x83, 0x0, 0x1, 0x5b, 0x75, 0x20, 0x0, 0x83, - 0x0, 0x0, 0x8, 0x30, 0x0, 0x0, 0x83, 0x0, - 0x0, 0x8, 0x30, 0x0, 0x0, 0x83, 0x0, 0x0, - 0x5c, 0x95, 0x0, - - /* U+0067 "g" */ - 0x1, 0x86, 0x99, 0x70, 0xa1, 0x6, 0x60, 0xb, - 0x0, 0x47, 0x0, 0x83, 0x7, 0x30, 0x5, 0x75, - 0x40, 0x0, 0x99, 0x64, 0x0, 0x7, 0x2, 0x5b, - 0x2, 0x90, 0x0, 0x91, 0x7, 0x65, 0x66, 0x0, - - /* U+0068 "h" */ - 0x6, 0x0, 0x0, 0x3, 0xe0, 0x0, 0x0, 0xc, - 0x0, 0x0, 0x0, 0xc0, 0x0, 0x0, 0xc, 0x58, - 0xa4, 0x0, 0xc4, 0x0, 0xb0, 0xc, 0x0, 0xc, - 0x0, 0xc0, 0x0, 0xc0, 0xc, 0x0, 0xc, 0x0, - 0xc0, 0x0, 0xc0, 0x3e, 0x50, 0x4e, 0x30, - - /* U+0069 "i" */ - 0x0, 0xe2, 0x0, 0x5, 0x0, 0x0, 0x20, 0x2, - 0x5d, 0x0, 0x0, 0xc0, 0x0, 0xc, 0x0, 0x0, - 0xc0, 0x0, 0xc, 0x0, 0x0, 0xc0, 0x2, 0x6e, - 0x63, - - /* U+006A "j" */ - 0x0, 0x8, 0x80, 0x0, 0x33, 0x0, 0x1, 0x10, - 0x5, 0xa6, 0x0, 0x5, 0x60, 0x0, 0x56, 0x0, - 0x5, 0x60, 0x0, 0x56, 0x0, 0x5, 0x60, 0x0, - 0x55, 0x60, 0x8, 0x29, 0x97, 0x50, - - /* U+006B "k" */ - 0x6, 0x0, 0x0, 0x3, 0xd0, 0x0, 0x0, 0xb, - 0x0, 0x0, 0x0, 0xb0, 0x0, 0x0, 0xb, 0x0, - 0xc7, 0x0, 0xb0, 0x26, 0x0, 0xb, 0x1b, 0x0, - 0x0, 0xb8, 0xa3, 0x0, 0xb, 0x12, 0xc0, 0x0, - 0xb0, 0x9, 0x50, 0x2d, 0x50, 0x5e, 0x30, - - /* U+006C "l" */ - 0x2, 0x90, 0x3, 0x5d, 0x0, 0x0, 0xc0, 0x0, - 0xc, 0x0, 0x0, 0xc0, 0x0, 0xc, 0x0, 0x0, - 0xc0, 0x0, 0xc, 0x0, 0x0, 0xc0, 0x0, 0xc, - 0x0, 0x36, 0xe6, 0x30, - - /* U+006D "m" */ - 0x8a, 0x7a, 0x7a, 0x24, 0x90, 0xc0, 0x55, 0x47, - 0xc, 0x5, 0x64, 0x70, 0xc0, 0x56, 0x47, 0xc, - 0x5, 0x64, 0x70, 0xc0, 0x56, 0x8b, 0x2e, 0x39, - 0xa0, - - /* U+006E "n" */ - 0x3e, 0x47, 0x94, 0x0, 0xc4, 0x0, 0xb0, 0xc, - 0x0, 0xc, 0x0, 0xc0, 0x0, 0xc0, 0xc, 0x0, - 0xc, 0x0, 0xc0, 0x0, 0xc0, 0x3e, 0x50, 0x4e, - 0x30, - - /* U+006F "o" */ - 0x1, 0x86, 0x82, 0x0, 0xb0, 0x0, 0xb0, 0x2a, - 0x0, 0xa, 0x24, 0x80, 0x0, 0x84, 0x3a, 0x0, - 0xa, 0x30, 0xb0, 0x0, 0xb0, 0x2, 0x85, 0x71, - 0x0, - - /* U+0070 "p" */ - 0x4e, 0x57, 0x94, 0x0, 0xc3, 0x0, 0xc0, 0xc, - 0x0, 0x9, 0x30, 0xc0, 0x0, 0x84, 0xc, 0x0, - 0xa, 0x30, 0xc1, 0x0, 0xc0, 0xc, 0x66, 0x92, - 0x0, 0xc0, 0x0, 0x0, 0x3e, 0x50, 0x0, 0x0, - - /* U+0071 "q" */ - 0x2, 0x86, 0x68, 0x0, 0xb0, 0x2, 0xc0, 0x2a, - 0x0, 0xc, 0x4, 0x90, 0x0, 0xc0, 0x2a, 0x0, - 0xc, 0x0, 0xb0, 0x2, 0xc0, 0x3, 0x97, 0x5c, - 0x0, 0x0, 0x0, 0xc0, 0x0, 0x0, 0x6e, 0x30, - - /* U+0072 "r" */ - 0x38, 0xc2, 0x7c, 0x30, 0xc, 0x60, 0x42, 0x0, - 0xe0, 0x0, 0x0, 0xc, 0x0, 0x0, 0x0, 0xc0, - 0x0, 0x0, 0xc, 0x0, 0x0, 0x36, 0xe5, 0x20, - 0x0, - - /* U+0073 "s" */ - 0x17, 0x6b, 0xa8, 0x10, 0x8, 0x69, 0x10, 0x0, - 0x5c, 0xa1, 0x10, 0x4, 0xc8, 0x0, 0xa, 0xba, - 0x66, 0x40, - - /* U+0074 "t" */ - 0x0, 0x24, 0x0, 0x0, 0x94, 0x0, 0x5, 0xa8, - 0x52, 0x0, 0x74, 0x0, 0x0, 0x74, 0x0, 0x0, - 0x74, 0x0, 0x0, 0x74, 0x0, 0x0, 0x65, 0x5, - 0x0, 0x1a, 0x83, - - /* U+0075 "u" */ - 0x4d, 0x0, 0x5c, 0x0, 0xc0, 0x0, 0xc0, 0xc, - 0x0, 0xc, 0x0, 0xc0, 0x0, 0xc0, 0xc, 0x0, - 0xc, 0x0, 0xb0, 0x4, 0xc0, 0x4, 0xb8, 0x5c, - 0x30, - - /* U+0076 "v" */ - 0x2d, 0x70, 0x3d, 0x20, 0x75, 0x1, 0x50, 0x2, - 0xa0, 0x50, 0x0, 0xc, 0x6, 0x0, 0x0, 0x84, - 0x50, 0x0, 0x3, 0xd1, 0x0, 0x0, 0xa, 0x0, - 0x0, - - /* U+0077 "w" */ - 0x9b, 0x3e, 0x28, 0x82, 0x90, 0xb0, 0x50, 0xb, - 0xd, 0x35, 0x0, 0xa2, 0x76, 0x50, 0x7, 0x81, - 0xa4, 0x0, 0x4b, 0xd, 0x10, 0x0, 0x80, 0x80, - 0x0, - - /* U+0078 "x" */ - 0x9, 0xd0, 0x89, 0x10, 0xc, 0x18, 0x0, 0x0, - 0x5d, 0x30, 0x0, 0x0, 0xe1, 0x0, 0x0, 0x65, - 0x90, 0x0, 0x16, 0xa, 0x20, 0x2c, 0x50, 0x9c, - 0x20, - - /* U+0079 "y" */ - 0x2c, 0x80, 0x5c, 0x20, 0x57, 0x3, 0x40, 0x0, - 0xb0, 0x70, 0x0, 0x9, 0x17, 0x0, 0x0, 0x48, - 0x50, 0x0, 0x0, 0xe0, 0x0, 0x0, 0x7, 0x0, - 0x0, 0x1, 0x50, 0x0, 0xd, 0x90, 0x0, 0x0, - - /* U+007A "z" */ - 0xc, 0x65, 0xa7, 0x0, 0x70, 0x1c, 0x0, 0x0, - 0x9, 0x40, 0x0, 0x2, 0xb0, 0x0, 0x0, 0xb2, - 0x2, 0x0, 0x58, 0x0, 0x70, 0xe, 0x65, 0x8b, - 0x0, - - /* U+007B "{" */ - 0x0, 0x26, 0x0, 0x80, 0x0, 0x70, 0x0, 0x80, - 0x0, 0x80, 0x0, 0x80, 0x5, 0x40, 0x5, 0x40, - 0x0, 0x80, 0x0, 0x80, 0x0, 0x80, 0x0, 0x70, - 0x0, 0x80, 0x0, 0x27, - - /* U+007C "|" */ - 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x50, - - /* U+007D "}" */ - 0x62, 0x0, 0x7, 0x0, 0x7, 0x0, 0x7, 0x0, - 0x7, 0x0, 0x7, 0x0, 0x4, 0x50, 0x4, 0x50, - 0x7, 0x0, 0x7, 0x0, 0x7, 0x0, 0x7, 0x0, - 0x7, 0x0, 0x62, 0x0, - - /* U+007E "~" */ - 0x5, 0x92, 0x0, 0x3, 0x11, 0xb2, 0x4, 0x0, - 0x1, 0x97, 0x0, - - /* U+007F "" */ - - /* U+3001 "、" */ - 0x0, 0x0, 0x29, 0x50, 0x0, 0xd7, 0x0, 0x4d, - 0x0, 0x1, - - /* U+3002 "。" */ - 0x0, 0x0, 0x67, 0x70, 0x70, 0x70, 0x77, 0x70, - 0x0, 0x0, - - /* U+3005 "々" */ - 0x0, 0x11, 0x0, 0x0, 0x0, 0x49, 0x0, 0x0, - 0x0, 0x82, 0x0, 0x11, 0x1, 0xc7, 0x55, 0xc8, - 0x7, 0x21, 0x0, 0xb0, 0x11, 0x0, 0x5, 0x50, - 0x0, 0x0, 0x8, 0x0, 0x0, 0x6, 0x52, 0x0, - 0x0, 0x2, 0xd3, 0x0, 0x0, 0x0, 0x4d, 0x0, - 0x0, 0x0, 0x3, 0x0, - - /* U+300C "「" */ - 0x88, 0x86, 0x80, 0x0, 0x80, 0x0, 0x80, 0x0, - 0x80, 0x0, 0x80, 0x0, 0x80, 0x0, 0x80, 0x0, - 0x80, 0x0, 0x80, 0x0, 0x80, 0x0, 0x80, 0x0, - - /* U+300D "」" */ - 0x0, 0x8, 0x0, 0x8, 0x0, 0x8, 0x0, 0x8, - 0x0, 0x8, 0x0, 0x8, 0x0, 0x8, 0x0, 0x8, - 0x0, 0x8, 0x0, 0x8, 0x0, 0x8, 0x78, 0x88, - - /* U+3041 "ぁ" */ - 0x0, 0x33, 0x0, 0x0, 0x0, 0x55, 0x54, 0x0, - 0x5, 0xa8, 0x30, 0x0, 0x0, 0x63, 0x95, 0x10, - 0x0, 0xb4, 0x71, 0x91, 0x8, 0x67, 0x10, 0x46, - 0x70, 0x58, 0x0, 0x63, 0x78, 0x78, 0x3, 0x80, - 0x1, 0x0, 0x54, 0x0, - - /* U+3042 "あ" */ - 0x0, 0x4, 0x10, 0x0, 0x0, 0x0, 0x9, 0x30, - 0x10, 0x0, 0x0, 0xa, 0x7a, 0x91, 0x0, 0x6, - 0x7c, 0x21, 0x0, 0x0, 0x0, 0x9, 0x2c, 0x75, - 0x0, 0x0, 0x2d, 0x6c, 0x3, 0xb1, 0x3, 0xa9, - 0x37, 0x0, 0x48, 0x1a, 0x9, 0xa0, 0x0, 0x29, - 0x82, 0xa, 0x50, 0x0, 0x65, 0x93, 0x89, 0x90, - 0x2, 0xa0, 0x17, 0x20, 0x20, 0x67, 0x0, 0x0, - 0x0, 0x14, 0x10, 0x0, - - /* U+3043 "ぃ" */ - 0x0, 0x0, 0x0, 0x0, 0x55, 0x0, 0x1, 0x0, - 0x62, 0x0, 0x3, 0x50, 0x81, 0x0, 0x0, 0x82, - 0x71, 0x10, 0x1, 0x57, 0x37, 0x60, 0x0, 0x83, - 0x8, 0x30, 0x0, 0x0, - - /* U+3044 "い" */ - 0x34, 0x0, 0x0, 0x0, 0x0, 0x4a, 0x0, 0x0, - 0x5, 0x0, 0x65, 0x0, 0x0, 0x2, 0x90, 0x82, - 0x0, 0x0, 0x0, 0x56, 0x91, 0x1, 0x0, 0x0, - 0x1a, 0x74, 0x14, 0x0, 0x4, 0x7b, 0x1c, 0xb1, - 0x0, 0x0, 0x75, 0x4, 0xd0, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x0, 0x0, 0x0, - - /* U+3046 "う" */ - 0x0, 0x32, 0x0, 0x0, 0x0, 0x4, 0xdb, 0x0, - 0x0, 0x2, 0x42, 0x0, 0x0, 0x2, 0x78, 0x20, - 0x3, 0x97, 0x1, 0xb0, 0x58, 0x10, 0x0, 0x92, - 0x0, 0x0, 0x0, 0x92, 0x0, 0x0, 0x0, 0xc0, - 0x0, 0x0, 0x3, 0x90, 0x0, 0x0, 0x1b, 0x0, - 0x0, 0x3, 0x91, 0x0, 0x0, 0x43, 0x0, 0x0, - - /* U+3047 "ぇ" */ - 0x0, 0x3, 0x70, 0x0, 0x0, 0x1, 0x60, 0x0, - 0x0, 0x16, 0xb5, 0x0, 0x5, 0x71, 0xa0, 0x0, - 0x0, 0x8, 0x10, 0x0, 0x0, 0x78, 0x40, 0x0, - 0x9, 0x30, 0x80, 0x0, 0x45, 0x0, 0x88, 0x91, - 0x0, 0x0, 0x0, 0x0, - - /* U+3048 "え" */ - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x1, 0x78, - 0x10, 0x0, 0x0, 0x0, 0x5a, 0x40, 0x0, 0x0, - 0x0, 0x6, 0x30, 0x0, 0x1, 0x47, 0x78, 0x90, - 0x0, 0x6, 0x70, 0x1a, 0x0, 0x0, 0x0, 0x0, - 0x91, 0x0, 0x0, 0x0, 0x7, 0x40, 0x0, 0x0, - 0x0, 0x58, 0x86, 0x0, 0x0, 0x4, 0x80, 0xa, - 0x0, 0x0, 0x4c, 0x0, 0xb, 0x34, 0x81, 0x31, - 0x0, 0x2, 0x66, 0x30, - - /* U+304A "お" */ - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xc2, - 0x0, 0x0, 0x0, 0x0, 0xb, 0x10, 0x1, 0x68, - 0x10, 0x0, 0xa6, 0xb2, 0x0, 0xb8, 0x5, 0x9e, - 0x40, 0x0, 0x0, 0x0, 0x0, 0xa1, 0x89, 0x96, - 0x0, 0x0, 0xc, 0x81, 0x0, 0x66, 0x0, 0x1a, - 0xc0, 0x0, 0x0, 0xc0, 0x6, 0x3a, 0x2, 0x0, - 0x39, 0x0, 0x8, 0xc1, 0x74, 0x4b, 0x20, 0x0, - 0x1d, 0x0, 0x55, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, - - /* U+304B "か" */ - 0x0, 0x0, 0x60, 0x0, 0x0, 0x0, 0x0, 0x0, - 0xc4, 0x0, 0x0, 0x0, 0x0, 0x0, 0xc0, 0x0, - 0x0, 0x0, 0x3, 0x5a, 0xc9, 0xc1, 0x6, 0x0, - 0x9, 0x5b, 0x10, 0x76, 0x1, 0xb0, 0x0, 0x29, - 0x0, 0x74, 0x0, 0x78, 0x0, 0x92, 0x0, 0xa1, - 0x6, 0xc9, 0x3, 0x80, 0x0, 0xb0, 0x0, 0x62, - 0xc, 0x4, 0x49, 0x60, 0x0, 0x0, 0x14, 0x0, - 0xea, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, - - /* U+304C "が" */ - 0x0, 0x0, 0x0, 0x0, 0x4, 0xa0, 0x0, 0x0, - 0x82, 0x0, 0x76, 0x50, 0x0, 0x0, 0xb3, 0x0, - 0x6, 0x0, 0x0, 0x1, 0xb1, 0x10, 0x20, 0x0, - 0x17, 0x8c, 0xa6, 0xc2, 0x19, 0x10, 0x4, 0x2b, - 0x0, 0x83, 0x2, 0xc0, 0x0, 0x47, 0x0, 0xa1, - 0x0, 0x95, 0x0, 0xb0, 0x0, 0xb0, 0x18, 0xd6, - 0x6, 0x60, 0x4, 0x70, 0x0, 0x81, 0x2c, 0x6, - 0x6d, 0x20, 0x0, 0x0, 0x12, 0x0, 0xb5, 0x0, - 0x0, 0x0, - - /* U+304D "き" */ - 0x0, 0x10, 0x0, 0x0, 0x1, 0xe1, 0x0, 0x0, - 0x0, 0x48, 0x6a, 0x20, 0x17, 0x8d, 0x40, 0x11, - 0x0, 0x2, 0xa6, 0xa1, 0x4, 0x79, 0xb7, 0x0, - 0x0, 0x0, 0xb, 0x10, 0x5, 0x99, 0x87, 0xb0, - 0x97, 0x0, 0x17, 0xf4, 0xc0, 0x0, 0x0, 0x10, - 0x69, 0x0, 0x1, 0x0, 0x5, 0xcc, 0xca, 0x0, - - /* U+304E "ぎ" */ - 0x0, 0x0, 0x0, 0x0, 0x12, 0x0, 0x1c, 0x0, - 0x0, 0x37, 0xb4, 0x0, 0x75, 0x2a, 0x40, 0xa1, - 0x1, 0x36, 0xe7, 0x10, 0x0, 0x0, 0x3, 0x25, - 0x54, 0xb2, 0x0, 0x0, 0x12, 0x6e, 0x80, 0x0, - 0x0, 0x2, 0x42, 0x1a, 0x0, 0x0, 0x0, 0x26, - 0x75, 0x69, 0x0, 0x0, 0x69, 0x32, 0x48, 0xe4, - 0x0, 0xb, 0x0, 0x0, 0x1, 0x0, 0x0, 0x5a, - 0x20, 0x26, 0x10, 0x0, 0x0, 0x4a, 0xca, 0x60, - 0x0, 0x0, - - /* U+304F "く" */ - 0x0, 0x1, 0x50, 0x0, 0x6, 0xe0, 0x0, 0x1c, - 0x20, 0x1, 0xa1, 0x0, 0x9, 0x10, 0x0, 0x71, - 0x0, 0x0, 0x46, 0x0, 0x0, 0x3, 0x91, 0x0, - 0x0, 0x2d, 0x20, 0x0, 0x7, 0xd0, 0x0, 0x0, - 0xe3, 0x0, 0x0, 0x30, - - /* U+3050 "ぐ" */ - 0x0, 0x2, 0x20, 0x0, 0x0, 0x0, 0x8b, 0x0, - 0x0, 0x0, 0x3c, 0x10, 0x8, 0x70, 0x1b, 0x10, - 0xa, 0x34, 0x9, 0x0, 0x0, 0x23, 0x6, 0x0, - 0x0, 0x0, 0x0, 0x55, 0x0, 0x0, 0x0, 0x0, - 0x49, 0x0, 0x0, 0x0, 0x0, 0x5b, 0x0, 0x0, - 0x0, 0x0, 0xaa, 0x0, 0x0, 0x0, 0x2, 0xf0, - 0x0, 0x0, 0x0, 0x4, 0x0, 0x0, - - /* U+3051 "け" */ - 0x0, 0x0, 0x0, 0x1, 0x20, 0x0, 0x2, 0xc0, - 0x0, 0x1, 0xe0, 0x0, 0x2, 0xa0, 0x0, 0x0, - 0xc0, 0x10, 0x6, 0x50, 0x4, 0x88, 0xea, 0x80, - 0xa, 0x10, 0x0, 0x0, 0xb0, 0x0, 0xb, 0x0, - 0x0, 0x0, 0xb0, 0x0, 0xb, 0x3, 0x0, 0x0, - 0xb0, 0x0, 0xc, 0x43, 0x0, 0x2, 0x90, 0x0, - 0xa, 0xd0, 0x0, 0x8, 0x40, 0x0, 0x2, 0xc0, - 0x0, 0x39, 0x0, 0x0, 0x0, 0x0, 0x4, 0x70, - 0x0, 0x0, 0x0, 0x0, 0x1, 0x0, 0x0, 0x0, - - /* U+3052 "げ" */ - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x0, 0x15, 0x70, 0x18, 0x0, 0x0, - 0x1b, 0x6, 0x77, 0x1, 0xe0, 0x0, 0x0, 0xd0, - 0x4, 0x0, 0x48, 0x0, 0x0, 0x2d, 0x9a, 0x0, - 0x8, 0x30, 0x5, 0x87, 0xd1, 0x0, 0x0, 0xa0, - 0x0, 0x0, 0xb, 0x0, 0x0, 0xb, 0x0, 0x0, - 0x0, 0xb0, 0x0, 0x0, 0xb0, 0x30, 0x0, 0xb, - 0x0, 0x0, 0x8, 0x93, 0x0, 0x4, 0x70, 0x0, - 0x0, 0x3f, 0x10, 0x0, 0xb1, 0x0, 0x0, 0x0, - 0x40, 0x0, 0x92, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x50, 0x0, 0x0, 0x0, 0x0, - - /* U+3053 "こ" */ - 0x0, 0x11, 0x1, 0x30, 0x0, 0x0, 0x68, 0xed, - 0x20, 0x0, 0x0, 0x64, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x10, - 0x0, 0x0, 0x0, 0x6, 0x0, 0x0, 0x0, 0x0, - 0x90, 0x0, 0x0, 0x0, 0x7, 0x95, 0x45, 0x7b, - 0x60, 0x2, 0x67, 0x76, 0x20, - - /* U+3054 "ご" */ - 0x0, 0x0, 0x0, 0x0, 0x36, 0x0, 0x10, 0x0, - 0x10, 0x56, 0x72, 0x1, 0x69, 0xcf, 0x60, 0x90, - 0x0, 0x0, 0x37, 0x10, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x5, 0x0, - 0x0, 0x0, 0x0, 0x0, 0x70, 0x0, 0x0, 0x0, - 0x0, 0x2, 0xa4, 0x22, 0x48, 0x90, 0x0, 0x1, - 0x69, 0xa9, 0x61, 0x0, 0x0, - - /* U+3055 "さ" */ - 0x1, 0x50, 0x0, 0x0, 0x0, 0xb2, 0x0, 0x0, - 0x0, 0x1b, 0x25, 0xb0, 0x7, 0x7b, 0xf6, 0x0, - 0x1, 0x20, 0x49, 0x0, 0x0, 0x0, 0x9, 0x50, - 0x19, 0x9a, 0xa9, 0xe0, 0xb1, 0x0, 0x3, 0xd2, - 0xc0, 0x0, 0x0, 0x0, 0x4b, 0x42, 0x33, 0x0, - 0x2, 0x7a, 0xa5, 0x0, - - /* U+3056 "ざ" */ - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x14, 0x90, 0x0, 0xd3, 0x0, 0x3, 0xb5, - 0x0, 0x1, 0xb1, 0x5, 0x53, 0x0, 0x0, 0x4, - 0xca, 0x70, 0x0, 0x0, 0x36, 0x66, 0x90, 0x0, - 0x0, 0x0, 0x0, 0x8, 0x60, 0x0, 0x0, 0x16, - 0x75, 0x2d, 0x10, 0x0, 0x4a, 0x33, 0x59, 0xe7, - 0x0, 0x9, 0x20, 0x0, 0x2, 0x30, 0x0, 0x4a, - 0x0, 0x0, 0x0, 0x0, 0x0, 0x5b, 0xbc, 0xc1, - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - - /* U+3057 "し" */ - 0x0, 0x0, 0x0, 0x0, 0xb6, 0x0, 0x0, 0x0, - 0x94, 0x0, 0x0, 0x0, 0x92, 0x0, 0x0, 0x0, - 0xa1, 0x0, 0x0, 0x0, 0xa0, 0x0, 0x0, 0x0, - 0xa0, 0x0, 0x0, 0x0, 0xa0, 0x0, 0x0, 0x0, - 0xa1, 0x0, 0x0, 0x33, 0x75, 0x0, 0x7, 0x60, - 0xc, 0x99, 0xc5, 0x0, 0x0, 0x22, 0x0, 0x0, - - /* U+3058 "じ" */ - 0x20, 0x0, 0x0, 0x0, 0x98, 0x0, 0x6, 0x0, - 0x85, 0x1, 0x74, 0x90, 0x83, 0x0, 0x56, 0x0, - 0x92, 0x0, 0x0, 0x0, 0xa2, 0x0, 0x0, 0x0, - 0xa1, 0x0, 0x0, 0x0, 0xa2, 0x0, 0x0, 0x0, - 0x83, 0x0, 0x0, 0x34, 0x58, 0x0, 0x7, 0x70, - 0xa, 0xba, 0xa3, 0x0, 0x0, 0x0, 0x0, 0x0, - - /* U+3059 "す" */ - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0xe0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xb0, - 0x0, 0x0, 0x1, 0x13, 0x57, 0xd9, 0x9a, 0xa2, - 0x8, 0x96, 0x30, 0xa0, 0x0, 0x0, 0x0, 0x0, - 0x69, 0xd0, 0x0, 0x0, 0x0, 0x0, 0xa0, 0xb2, - 0x0, 0x0, 0x0, 0x0, 0xa0, 0xc2, 0x0, 0x0, - 0x0, 0x0, 0x8a, 0xe0, 0x0, 0x0, 0x0, 0x0, - 0x2, 0x90, 0x0, 0x0, 0x0, 0x0, 0x1a, 0x10, - 0x0, 0x0, 0x0, 0x2, 0x60, 0x0, 0x0, 0x0, - - /* U+305A "ず" */ - 0x0, 0x0, 0x0, 0x0, 0x0, 0x5, 0x50, 0x0, - 0x0, 0x0, 0xe1, 0x0, 0x85, 0x80, 0x0, 0x0, - 0x0, 0xb0, 0x0, 0x6, 0x0, 0x0, 0x2, 0x47, - 0xd9, 0x9a, 0xa1, 0x0, 0x8, 0xa7, 0x41, 0xa0, - 0x0, 0x0, 0x0, 0x0, 0x0, 0x68, 0xd0, 0x0, - 0x0, 0x0, 0x0, 0x1, 0x90, 0x93, 0x0, 0x0, - 0x0, 0x0, 0x1, 0x90, 0xa4, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x9a, 0xf1, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x2, 0xa0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x1b, 0x10, 0x0, 0x0, 0x0, 0x0, 0x2, 0x70, - 0x0, 0x0, 0x0, 0x0, - - /* U+305B "せ" */ - 0x0, 0x0, 0x0, 0x6, 0x0, 0x0, 0x0, 0x91, - 0x0, 0xd1, 0x0, 0x0, 0x9, 0x20, 0xb, 0x0, - 0x0, 0x0, 0x93, 0x57, 0xda, 0xb6, 0x4a, 0x9c, - 0x73, 0xa, 0x0, 0x0, 0x0, 0x91, 0x0, 0xb0, - 0x0, 0x0, 0x8, 0x21, 0xb9, 0x0, 0x0, 0x0, - 0x73, 0x2, 0x0, 0x0, 0x0, 0x3, 0xa0, 0x0, - 0x0, 0x0, 0x0, 0x5, 0xab, 0xbb, 0x30, - - /* U+305C "ぜ" */ - 0x0, 0x0, 0x0, 0x0, 0x0, 0x5, 0x0, 0x0, - 0x0, 0x0, 0x16, 0x7, 0x4a, 0x0, 0x3, 0x90, - 0x0, 0xe0, 0x37, 0x0, 0x0, 0xb, 0x0, 0xb, - 0x0, 0x0, 0x0, 0x0, 0xb4, 0x69, 0xda, 0xa2, - 0x0, 0x9a, 0x9c, 0x52, 0xa, 0x0, 0x0, 0x0, - 0x0, 0xa0, 0x2, 0x90, 0x0, 0x0, 0x0, 0xa, - 0x2, 0xe4, 0x0, 0x0, 0x0, 0x0, 0xb0, 0x1, - 0x0, 0x0, 0x0, 0x0, 0xa, 0x50, 0x0, 0x20, - 0x0, 0x0, 0x0, 0x8, 0xbc, 0xca, 0x0, 0x0, - - /* U+305D "そ" */ - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x47, - 0xc4, 0x0, 0x0, 0x8a, 0x42, 0xc4, 0x0, 0x0, - 0x0, 0x39, 0x10, 0x0, 0x0, 0x6, 0x60, 0x2, - 0x30, 0x3, 0x85, 0x79, 0xc9, 0x70, 0x7e, 0x84, - 0x48, 0x0, 0x0, 0x0, 0x1, 0x90, 0x0, 0x0, - 0x0, 0x6, 0x30, 0x0, 0x0, 0x0, 0x5, 0x50, - 0x0, 0x0, 0x0, 0x0, 0xc7, 0x41, 0x0, 0x0, - 0x0, 0x7, 0xa4, 0x0, - - /* U+305E "ぞ" */ - 0x0, 0x0, 0x0, 0x30, 0x2, 0x40, 0x0, 0x23, - 0x67, 0xe6, 0x36, 0x66, 0x0, 0x86, 0x18, 0x70, - 0x8, 0x30, 0x0, 0x1, 0x93, 0x0, 0x0, 0x0, - 0x0, 0x28, 0x0, 0x25, 0x71, 0x0, 0x6, 0x97, - 0x7c, 0xa5, 0x41, 0x0, 0x6a, 0x40, 0x75, 0x0, - 0x0, 0x0, 0x0, 0x4, 0x70, 0x0, 0x0, 0x0, - 0x0, 0x8, 0x20, 0x0, 0x0, 0x0, 0x0, 0x5, - 0x70, 0x0, 0x0, 0x0, 0x0, 0x0, 0x9c, 0x93, - 0x0, 0x0, 0x0, 0x0, 0x2, 0x61, 0x0, 0x0, - - /* U+305F "た" */ - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x3b, 0x0, - 0x0, 0x0, 0x0, 0x48, 0x14, 0x0, 0x0, 0x24, - 0x9c, 0xa3, 0x0, 0x10, 0x14, 0xb1, 0x2, 0x77, - 0xf5, 0x0, 0xb0, 0x0, 0x17, 0x30, 0x2, 0x90, - 0x0, 0x0, 0x0, 0x7, 0x30, 0x0, 0x0, 0x0, - 0xb, 0x0, 0x60, 0x0, 0x0, 0x67, 0x0, 0x80, - 0x0, 0x0, 0x90, 0x0, 0x39, 0xab, 0xc5, 0x0, - 0x0, 0x0, 0x0, 0x0, - - /* U+3060 "だ" */ - 0x0, 0x0, 0x0, 0x0, 0x2, 0x10, 0x0, 0x6, - 0x70, 0x0, 0x43, 0xb2, 0x0, 0x7, 0x53, 0x20, - 0xb, 0x20, 0x3, 0x3b, 0xb7, 0x0, 0x1, 0x0, - 0x2, 0x5c, 0x0, 0x47, 0x8e, 0x10, 0x0, 0xa, - 0x0, 0x2, 0x73, 0x0, 0x0, 0x56, 0x0, 0x0, - 0x0, 0x0, 0x0, 0x91, 0x0, 0x0, 0x0, 0x0, - 0x0, 0xb0, 0x5, 0x0, 0x0, 0x0, 0x7, 0x50, - 0x19, 0x0, 0x0, 0x0, 0xa, 0x0, 0x4, 0xaa, - 0xbc, 0x10, - - /* U+3061 "ち" */ - 0x0, 0x3, 0x0, 0x0, 0x0, 0x0, 0xc, 0x30, - 0x0, 0x0, 0x0, 0xb, 0x3, 0x71, 0x0, 0x28, - 0xad, 0x86, 0x30, 0x0, 0x0, 0x54, 0x0, 0x0, - 0x0, 0x0, 0xa0, 0x48, 0x99, 0x20, 0x1, 0xc9, - 0x40, 0x2, 0xd0, 0x2, 0xd1, 0x0, 0x0, 0xb2, - 0x0, 0x0, 0x0, 0x1, 0xd0, 0x0, 0x0, 0x0, - 0x3b, 0x30, 0x0, 0x0, 0x46, 0x40, 0x0, - - /* U+3063 "っ" */ - 0x0, 0x0, 0x0, 0x0, 0x0, 0x2, 0x78, 0x78, - 0x80, 0xb, 0x71, 0x0, 0x7, 0x40, 0x0, 0x0, - 0x0, 0x47, 0x0, 0x0, 0x0, 0x8, 0x30, 0x0, - 0x0, 0x7, 0x70, 0x0, 0x4, 0x67, 0x20, 0x0, - - /* U+3064 "つ" */ - 0x0, 0x0, 0x17, 0x99, 0x81, 0x0, 0x36, 0xa8, - 0x20, 0x1, 0xb3, 0xb, 0x70, 0x0, 0x0, 0x3, - 0xb0, 0x0, 0x0, 0x0, 0x0, 0xd, 0x0, 0x0, - 0x0, 0x0, 0x3, 0xa0, 0x0, 0x0, 0x0, 0x0, - 0xb3, 0x0, 0x0, 0x0, 0x2, 0xb5, 0x0, 0x0, - 0x3, 0x68, 0x81, 0x0, 0x0, 0x0, 0x20, 0x0, - 0x0, 0x0, - - /* U+3065 "づ" */ - 0x0, 0x0, 0x0, 0x0, 0x0, 0x72, 0x0, 0x0, - 0x0, 0x0, 0x8, 0x39, 0x0, 0x0, 0x37, 0x89, - 0x61, 0x60, 0x14, 0x8a, 0x50, 0x0, 0x4a, 0x0, - 0x2a, 0x30, 0x0, 0x0, 0xb, 0x20, 0x0, 0x0, - 0x0, 0x0, 0x9, 0x30, 0x0, 0x0, 0x0, 0x0, - 0xc, 0x0, 0x0, 0x0, 0x0, 0x0, 0x68, 0x0, - 0x0, 0x0, 0x0, 0x18, 0x80, 0x0, 0x0, 0x3, - 0x68, 0x72, 0x0, 0x0, - - /* U+3066 "て" */ - 0x0, 0x0, 0x0, 0x36, 0x82, 0x35, 0x78, 0x87, - 0xbc, 0x83, 0x46, 0x30, 0x9, 0x30, 0x0, 0x0, - 0x0, 0x92, 0x0, 0x0, 0x0, 0x4, 0x60, 0x0, - 0x0, 0x0, 0x9, 0x10, 0x0, 0x0, 0x0, 0xa, - 0x0, 0x0, 0x0, 0x0, 0x7, 0x40, 0x0, 0x0, - 0x0, 0x1, 0xc3, 0x0, 0x0, 0x0, 0x0, 0x1a, - 0xd7, 0x0, - - /* U+3067 "で" */ - 0x0, 0x0, 0x0, 0x26, 0x89, 0x10, 0x3, 0x47, - 0x98, 0x7c, 0x85, 0x10, 0x8, 0x73, 0x2, 0xb2, - 0x2, 0x0, 0x0, 0x0, 0x1b, 0x10, 0x33, 0xa0, - 0x0, 0x0, 0x93, 0x0, 0x49, 0x40, 0x0, 0x0, - 0xc0, 0x0, 0x3, 0x0, 0x0, 0x1, 0xb0, 0x0, - 0x0, 0x0, 0x0, 0x0, 0xd0, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x6a, 0x10, 0x0, 0x0, 0x0, 0x0, - 0x5, 0xde, 0x40, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, - - /* U+3068 "と" */ - 0x0, 0x20, 0x0, 0x0, 0x0, 0xf0, 0x0, 0x0, - 0x0, 0xc0, 0x0, 0x0, 0x0, 0xb0, 0x0, 0x40, - 0x0, 0x92, 0x3b, 0xb0, 0x0, 0x5d, 0x71, 0x0, - 0x9, 0x80, 0x0, 0x0, 0x66, 0x0, 0x0, 0x0, - 0xa0, 0x0, 0x0, 0x0, 0x77, 0x0, 0x0, 0x20, - 0x7, 0xbc, 0xcd, 0xc3, 0x0, 0x0, 0x0, 0x0, - - /* U+3069 "ど" */ - 0x0, 0x10, 0x0, 0x0, 0x20, 0x0, 0x8, 0x70, - 0x0, 0x43, 0xb0, 0x0, 0x65, 0x0, 0x3, 0x94, - 0x0, 0x5, 0x50, 0x3, 0x11, 0x0, 0x0, 0x28, - 0x19, 0xd4, 0x0, 0x0, 0x1, 0xda, 0x30, 0x0, - 0x0, 0x3, 0xb3, 0x0, 0x0, 0x0, 0x0, 0xb0, - 0x0, 0x0, 0x0, 0x0, 0x38, 0x0, 0x0, 0x0, - 0x0, 0x1, 0xc1, 0x0, 0x0, 0x10, 0x0, 0x3, - 0xab, 0xbc, 0xd9, 0x0, 0x0, - - /* U+306A "な" */ - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x5, - 0x80, 0x0, 0x0, 0x0, 0x0, 0x82, 0x41, 0x0, - 0x0, 0x6, 0x8c, 0x96, 0x5, 0x30, 0x0, 0x8, - 0x10, 0x0, 0x2b, 0x60, 0x2, 0x80, 0x0, 0x96, - 0x56, 0x1, 0xb0, 0x0, 0x9, 0x0, 0x0, 0xb4, - 0x0, 0x1, 0x90, 0x0, 0x3, 0x0, 0x67, 0x59, - 0x0, 0x0, 0x0, 0x92, 0x4, 0xe6, 0x0, 0x0, - 0x9, 0x42, 0x94, 0xa5, 0x0, 0x0, 0x5, 0x73, - 0x0, 0x20, - - /* U+306B "に" */ - 0x26, 0x0, 0x24, 0x6a, 0x50, 0x2c, 0x0, 0x23, - 0x78, 0x20, 0x65, 0x0, 0x1, 0x30, 0x0, 0xa0, - 0x0, 0x0, 0x0, 0x0, 0xa0, 0x0, 0x0, 0x0, - 0x0, 0xb0, 0x13, 0x0, 0x0, 0x0, 0xb6, 0x7, - 0x0, 0x0, 0x0, 0x7d, 0x6, 0x50, 0x0, 0x30, - 0x8, 0x0, 0x6a, 0xbc, 0x90, - - /* U+306C "ぬ" */ - 0x0, 0x0, 0x5, 0x0, 0x0, 0x0, 0x0, 0x0, - 0xd, 0x0, 0x0, 0x0, 0xa, 0x20, 0x3d, 0x88, - 0x70, 0x0, 0x6, 0x48, 0x87, 0x0, 0x39, 0x0, - 0x3, 0xc2, 0x72, 0x0, 0xa, 0x10, 0x8, 0xa0, - 0x90, 0x0, 0x8, 0x30, 0x18, 0x69, 0x40, 0x0, - 0xa, 0x0, 0x53, 0xe, 0x32, 0xa9, 0xac, 0x0, - 0x46, 0x92, 0x56, 0x41, 0xa8, 0xb0, 0x6, 0x10, - 0x0, 0x78, 0x20, 0x40, - - /* U+306D "ね" */ - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x3a, - 0x0, 0x0, 0x0, 0x0, 0x0, 0x9, 0x0, 0x0, - 0x0, 0x0, 0x0, 0x1b, 0x5, 0x98, 0xa5, 0x0, - 0x29, 0x99, 0x84, 0x0, 0xa, 0x10, 0x1, 0x8d, - 0x10, 0x0, 0x7, 0x40, 0x0, 0xc8, 0x0, 0x0, - 0x6, 0x50, 0x7, 0x48, 0x0, 0x1, 0x9, 0x20, - 0x2b, 0x8, 0x3, 0xb8, 0xae, 0x30, 0x84, 0x99, - 0x7, 0x40, 0x88, 0xa7, 0x0, 0x76, 0x1, 0x9a, - 0x40, 0x2, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - - /* U+306E "の" */ - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x28, - 0xa9, 0x99, 0x10, 0x0, 0x69, 0x16, 0x0, 0x2c, - 0x10, 0x48, 0x0, 0x80, 0x0, 0x58, 0xb, 0x0, - 0x9, 0x0, 0x1, 0xc1, 0x90, 0x0, 0x90, 0x0, - 0xc, 0x36, 0x0, 0x19, 0x0, 0x0, 0xb2, 0x70, - 0x8, 0x30, 0x0, 0x57, 0xb, 0x15, 0x80, 0x0, - 0x2b, 0x0, 0x3a, 0x70, 0x0, 0x69, 0x10, 0x0, - 0x0, 0x2, 0x52, 0x0, 0x0, - - /* U+306F "は" */ - 0x0, 0x0, 0x0, 0x1, 0x0, 0x0, 0x24, 0x0, - 0x1, 0xe0, 0x0, 0x4, 0xa0, 0x0, 0xb, 0x0, - 0x0, 0x64, 0x0, 0x1, 0xc8, 0x90, 0xa, 0x0, - 0x16, 0x7c, 0x10, 0x0, 0xa0, 0x0, 0x0, 0xa0, - 0x0, 0x18, 0x0, 0x0, 0xa, 0x0, 0x3, 0x73, - 0x0, 0x0, 0xa0, 0x0, 0x3b, 0x51, 0xa8, 0x9d, - 0x30, 0x0, 0xe3, 0x55, 0x2, 0xaa, 0x70, 0x3, - 0x1, 0xb9, 0xa1, 0x4, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, - - /* U+3070 "ば" */ - 0x0, 0x0, 0x0, 0x0, 0x0, 0x60, 0x5, 0x0, - 0x0, 0x92, 0x7, 0x49, 0xd, 0x0, 0x0, 0xa1, - 0x2, 0x70, 0x19, 0x0, 0x0, 0x94, 0x92, 0x0, - 0x45, 0x0, 0x68, 0xd5, 0x10, 0x0, 0x72, 0x0, - 0x0, 0x90, 0x0, 0x0, 0x90, 0x0, 0x0, 0x90, - 0x0, 0x0, 0x93, 0x0, 0x0, 0x90, 0x0, 0x0, - 0xa7, 0x5, 0x88, 0xd2, 0x0, 0x0, 0x97, 0xb, - 0x0, 0xaa, 0x70, 0x0, 0x33, 0x9, 0x9a, 0x50, - 0x80, 0x0, 0x0, 0x0, 0x10, 0x0, 0x0, 0x0, - - /* U+3071 "ぱ" */ - 0x0, 0x0, 0x0, 0x0, 0x0, 0x45, 0x0, 0x5, - 0x0, 0x0, 0xa1, 0x6, 0x42, 0x0, 0xd0, 0x0, - 0xa, 0x0, 0x66, 0x0, 0x28, 0x0, 0x0, 0xa5, - 0x92, 0x0, 0x5, 0x40, 0x6, 0x8c, 0x40, 0x0, - 0x0, 0x80, 0x0, 0x0, 0x90, 0x0, 0x0, 0x9, - 0x0, 0x0, 0x9, 0x0, 0x0, 0x0, 0x93, 0x0, - 0x0, 0x90, 0x0, 0x0, 0xa, 0x70, 0x78, 0x8d, - 0x30, 0x0, 0x0, 0x96, 0xa, 0x0, 0xb9, 0x80, - 0x0, 0x2, 0x20, 0x89, 0xa4, 0x5, 0x0, 0x0, - - /* U+3072 "ひ" */ - 0x0, 0x4, 0x60, 0x1, 0x20, 0x0, 0x1b, 0x99, - 0xb0, 0x6, 0xd0, 0x0, 0x0, 0x2a, 0x0, 0x3, - 0xd3, 0x0, 0x0, 0xa1, 0x0, 0x2, 0x89, 0x0, - 0x3, 0x70, 0x0, 0x3, 0x7a, 0x50, 0x8, 0x20, - 0x0, 0x6, 0x51, 0xa0, 0xa, 0x0, 0x0, 0xa, - 0x10, 0x0, 0x8, 0x30, 0x0, 0x2a, 0x0, 0x0, - 0x2, 0xa0, 0x1, 0xc2, 0x0, 0x0, 0x0, 0x5b, - 0xaa, 0x20, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, - - /* U+3073 "び" */ - 0x0, 0x0, 0x0, 0x0, 0x0, 0x60, 0x0, 0x17, - 0x30, 0x2, 0x8, 0x55, 0x5b, 0x7d, 0x60, 0xc, - 0x61, 0x60, 0x0, 0x76, 0x0, 0xa, 0x90, 0x0, - 0x2, 0xa0, 0x0, 0xa, 0x83, 0x0, 0x9, 0x20, - 0x0, 0xa, 0x1c, 0x0, 0xb, 0x0, 0x0, 0xb, - 0x5, 0x70, 0xa, 0x0, 0x0, 0x1a, 0x0, 0x0, - 0xb, 0x0, 0x0, 0x84, 0x0, 0x0, 0x9, 0x30, - 0x5, 0xa0, 0x0, 0x0, 0x1, 0xbb, 0xb8, 0x0, - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - - /* U+3074 "ぴ" */ - 0x0, 0x0, 0x0, 0x0, 0x1, 0x50, 0x0, 0x16, - 0x30, 0x2, 0x5, 0x5, 0x4b, 0x8c, 0x70, 0xa, - 0x72, 0x51, 0x0, 0x67, 0x0, 0x8, 0xa0, 0x0, - 0x1, 0xa0, 0x0, 0x7, 0x94, 0x0, 0x8, 0x30, - 0x0, 0x8, 0x2c, 0x10, 0xb, 0x0, 0x0, 0xb, - 0x4, 0x70, 0xb, 0x0, 0x0, 0xb, 0x0, 0x0, - 0xb, 0x0, 0x0, 0x67, 0x0, 0x0, 0x9, 0x40, - 0x3, 0xc0, 0x0, 0x0, 0x1, 0xba, 0xba, 0x10, - 0x0, 0x0, 0x0, 0x1, 0x0, 0x0, 0x0, 0x0, - - /* U+3075 "ふ" */ - 0x0, 0x2, 0x20, 0x0, 0x0, 0x0, 0x0, 0x94, - 0x0, 0x0, 0x0, 0x0, 0x2f, 0x30, 0x0, 0x0, - 0x1, 0xa2, 0x0, 0x0, 0x0, 0x4, 0x40, 0x0, - 0x0, 0x0, 0x0, 0x90, 0x0, 0x0, 0x0, 0x0, - 0x46, 0x3, 0x70, 0x21, 0x60, 0xb, 0x0, 0x78, - 0xba, 0x12, 0xb, 0x0, 0xa, 0x30, 0x5, 0x95, - 0x0, 0x0, - - /* U+3076 "ぶ" */ - 0x0, 0x0, 0x20, 0x0, 0x1, 0x0, 0x0, 0x0, - 0x9, 0x30, 0x22, 0xa1, 0x0, 0x0, 0x5, 0xf0, - 0xb, 0x30, 0x0, 0x0, 0x57, 0x0, 0x1, 0x0, - 0x0, 0x0, 0x81, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x1a, 0x0, 0x0, 0x0, 0x0, 0x0, 0x6, 0x50, - 0x53, 0x0, 0x10, 0x34, 0x0, 0xb0, 0xb, 0x40, - 0x3c, 0x70, 0x20, 0xb0, 0x2, 0x90, 0x4, 0x0, - 0x38, 0x30, 0x0, 0x0, - - /* U+3077 "ぷ" */ - 0x0, 0x0, 0x30, 0x0, 0x4, 0x10, 0x0, 0x0, - 0xa3, 0x2, 0x26, 0x0, 0x0, 0x7, 0xf0, 0x5, - 0x40, 0x0, 0x7, 0x60, 0x0, 0x0, 0x0, 0x0, - 0x80, 0x0, 0x0, 0x0, 0x0, 0x2, 0x80, 0x0, - 0x0, 0x0, 0x0, 0x7, 0x40, 0x64, 0x1, 0x3, - 0x50, 0xa, 0x0, 0xb4, 0x4c, 0x62, 0x0, 0xb0, - 0x3, 0x71, 0x40, 0x8, 0x93, 0x0, 0x0, - - /* U+3078 "へ" */ - 0x0, 0x0, 0x40, 0x0, 0x0, 0x0, 0x0, 0x8, - 0x69, 0x0, 0x0, 0x0, 0x0, 0x85, 0x2, 0x80, - 0x0, 0x0, 0x1a, 0x80, 0x0, 0x57, 0x0, 0x0, - 0x13, 0x0, 0x0, 0x8, 0x50, 0x0, 0x0, 0x0, - 0x0, 0x0, 0xa8, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x8, 0xc0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - - /* U+3079 "べ" */ - 0x0, 0x0, 0x0, 0x0, 0x6, 0x10, 0x0, 0x0, - 0x20, 0x1, 0x94, 0x80, 0x0, 0x8, 0x69, 0x0, - 0x25, 0x0, 0x0, 0x83, 0x2, 0x80, 0x0, 0x0, - 0x19, 0x60, 0x0, 0x56, 0x0, 0x0, 0x15, 0x0, - 0x0, 0x8, 0x50, 0x0, 0x0, 0x0, 0x0, 0x0, - 0xa9, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8, 0xd0, - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - - /* U+307A "ぺ" */ - 0x0, 0x0, 0x0, 0x0, 0x3, 0x0, 0x0, 0x0, - 0x20, 0x0, 0x52, 0x40, 0x0, 0x7, 0x69, 0x0, - 0x35, 0x10, 0x0, 0x75, 0x2, 0x90, 0x0, 0x0, - 0x19, 0x70, 0x0, 0x56, 0x0, 0x0, 0x14, 0x0, - 0x0, 0x8, 0x40, 0x0, 0x0, 0x0, 0x0, 0x0, - 0xa6, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8, 0xc0, - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - - /* U+307B "ほ" */ - 0x3, 0x0, 0x0, 0x1, 0x10, 0xe, 0x0, 0x58, - 0xc8, 0x40, 0xa, 0x0, 0x0, 0xc0, 0x0, 0x46, - 0x0, 0x0, 0xa0, 0x30, 0x72, 0x0, 0x68, 0xda, - 0x70, 0x90, 0x0, 0x0, 0x90, 0x0, 0x91, 0x0, - 0x0, 0x90, 0x0, 0xa6, 0x0, 0x20, 0x90, 0x0, - 0x98, 0x1a, 0x68, 0xe4, 0x0, 0x34, 0x45, 0x3, - 0x98, 0x80, 0x0, 0xa, 0xbb, 0x10, 0x30, - - /* U+307C "ぼ" */ - 0x1, 0x0, 0x0, 0x1, 0x20, 0x0, 0x0, 0xc0, - 0x5, 0x8c, 0x84, 0x4, 0x0, 0xa, 0x0, 0x0, - 0xc0, 0x6, 0x3a, 0x3, 0x60, 0x0, 0xa, 0x0, - 0x28, 0x0, 0x63, 0x0, 0x11, 0xb7, 0x92, 0x0, - 0x7, 0x10, 0x3, 0x6c, 0x30, 0x0, 0x0, 0x91, - 0x0, 0x0, 0xa0, 0x0, 0x0, 0x9, 0x60, 0x0, - 0xa, 0x0, 0x0, 0x0, 0x7a, 0x7, 0x77, 0xd2, - 0x0, 0x0, 0x2, 0x72, 0x60, 0xb, 0x98, 0x0, - 0x0, 0x0, 0x9, 0x89, 0x40, 0x50, 0x0, 0x0, - - /* U+307D "ぽ" */ - 0x1, 0x0, 0x0, 0x1, 0x20, 0x0, 0xc, 0x0, - 0x58, 0xc8, 0x42, 0x83, 0xa, 0x0, 0x0, 0xc0, - 0x4, 0x6, 0x36, 0x0, 0x0, 0xa0, 0x0, 0x40, - 0x63, 0x0, 0x11, 0xb7, 0x92, 0x0, 0x71, 0x0, - 0x36, 0xc3, 0x0, 0x0, 0x90, 0x0, 0x0, 0xa0, - 0x0, 0x0, 0x96, 0x0, 0x0, 0xa0, 0x0, 0x0, - 0x7a, 0x7, 0x77, 0xd2, 0x0, 0x0, 0x28, 0x26, - 0x0, 0xba, 0x70, 0x0, 0x0, 0x9, 0x89, 0x40, - 0x60, 0x0, - - /* U+307E "ま" */ - 0x0, 0x0, 0x0, 0x0, 0x0, 0x2, 0xb0, 0x0, - 0x0, 0x0, 0xb0, 0x21, 0x2, 0x67, 0xda, 0x81, - 0x0, 0x1, 0xa0, 0x0, 0x0, 0x0, 0xb5, 0x80, - 0x2, 0x79, 0xd4, 0x0, 0x0, 0x0, 0xa0, 0x0, - 0x7, 0x88, 0xb0, 0x0, 0x82, 0x3, 0xcb, 0x20, - 0x67, 0x3b, 0x22, 0xd3, 0x4, 0x62, 0x0, 0x12, - - /* U+307F "み" */ - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x46, - 0x8d, 0x50, 0x0, 0x0, 0x3, 0x20, 0xc1, 0x0, - 0x0, 0x0, 0x0, 0x56, 0x0, 0x0, 0x0, 0x0, - 0xb, 0x0, 0x43, 0x0, 0x2, 0x6a, 0x92, 0x7, - 0x60, 0x7, 0x63, 0xa2, 0x7a, 0xc0, 0x3, 0x70, - 0xa1, 0x0, 0x4c, 0xb0, 0x53, 0x84, 0x0, 0x1a, - 0x5, 0x61, 0x84, 0x0, 0x19, 0x10, 0x0, 0x0, - 0x0, 0x15, 0x0, 0x0, 0x0, - - /* U+3080 "む" */ - 0x0, 0x4, 0x0, 0x0, 0x0, 0x0, 0x0, 0xd0, - 0x0, 0x0, 0x0, 0x0, 0x1b, 0x78, 0x0, 0x71, - 0x0, 0x37, 0xc2, 0x0, 0x1, 0xc0, 0x0, 0x3a, - 0x0, 0x0, 0x6, 0x10, 0x80, 0xc0, 0x0, 0x0, - 0x0, 0x26, 0x1d, 0x0, 0x0, 0x0, 0x1, 0xcd, - 0x80, 0x0, 0x5, 0x0, 0x0, 0x82, 0x0, 0x0, - 0x57, 0x0, 0x9, 0x40, 0x2, 0x6c, 0x50, 0x0, - 0x6, 0x99, 0x84, 0x0, 0x0, - - /* U+3081 "め" */ - 0x0, 0x0, 0x0, 0x71, 0x0, 0x0, 0x1d, 0x0, - 0xb, 0x10, 0x0, 0x0, 0xa1, 0x28, 0xd7, 0x30, - 0x0, 0x5, 0xb6, 0x38, 0x18, 0x80, 0x0, 0x99, - 0x7, 0x20, 0x9, 0x30, 0x73, 0x82, 0x90, 0x0, - 0x56, 0xa, 0x1, 0xd2, 0x0, 0x7, 0x40, 0x90, - 0x5a, 0x60, 0x0, 0xb0, 0xa, 0xa6, 0x0, 0x1, - 0x92, 0x0, 0x0, 0x0, 0x15, 0x60, 0x0, 0x0, - 0x0, 0x1, 0x0, 0x0, 0x0, - - /* U+3082 "も" */ - 0x0, 0x1, 0x0, 0x0, 0x0, 0x1e, 0x0, 0x0, - 0x0, 0x1a, 0x0, 0x0, 0x3, 0x46, 0x0, 0x0, - 0x3, 0xca, 0x80, 0x0, 0x0, 0xa0, 0x0, 0x0, - 0x20, 0xa0, 0x0, 0x20, 0x29, 0xd9, 0x80, 0x24, - 0x1, 0x90, 0x0, 0x25, 0x0, 0xa0, 0x0, 0x63, - 0x0, 0xa4, 0x3, 0xa0, 0x0, 0x7, 0x97, 0x0, - - /* U+3083 "ゃ" */ - 0x0, 0x0, 0x10, 0x0, 0x0, 0x0, 0x30, 0x38, - 0x0, 0x0, 0x0, 0xa0, 0x1a, 0x87, 0x10, 0x0, - 0x87, 0x94, 0x2, 0xc0, 0x17, 0xa9, 0x3, 0x0, - 0xc0, 0x13, 0x9, 0x12, 0x89, 0x30, 0x0, 0x2, - 0x90, 0x0, 0x0, 0x0, 0x0, 0xb0, 0x0, 0x0, - 0x0, 0x0, 0x40, 0x0, 0x0, - - /* U+3084 "や" */ - 0x0, 0x0, 0x2, 0x60, 0x0, 0x0, 0x0, 0xa3, - 0x3, 0xc3, 0x0, 0x0, 0x0, 0x74, 0x3, 0xb9, - 0x99, 0xa0, 0x0, 0xc, 0xa6, 0x0, 0x0, 0x74, - 0x3, 0xab, 0x40, 0x10, 0x0, 0x93, 0x49, 0x10, - 0xb0, 0x37, 0x57, 0xa0, 0x0, 0x0, 0x84, 0x0, - 0x32, 0x0, 0x0, 0x0, 0x2b, 0x0, 0x0, 0x0, - 0x0, 0x0, 0xc, 0x10, 0x0, 0x0, 0x0, 0x0, - 0x7, 0x50, 0x0, 0x0, 0x0, 0x0, 0x1, 0x10, - 0x0, 0x0, - - /* U+3085 "ゅ" */ - 0x0, 0x3, 0x60, 0x0, 0x65, 0x3, 0xd8, 0x40, - 0x91, 0x85, 0x72, 0x84, 0x95, 0x50, 0x72, 0x29, - 0xaa, 0x30, 0x90, 0x19, 0x97, 0x17, 0x90, 0x84, - 0x22, 0x7, 0xb9, 0x50, 0x0, 0x45, 0x0, 0x0, - - /* U+3086 "ゆ" */ - 0x0, 0x0, 0x49, 0x10, 0x0, 0x2, 0x30, 0x0, - 0x49, 0x10, 0x0, 0x39, 0x2, 0xa8, 0xc8, 0x90, - 0x6, 0x52, 0xa1, 0xa, 0x3, 0x90, 0x91, 0xa0, - 0x0, 0xa0, 0xc, 0xa, 0x55, 0x30, 0xa, 0x0, - 0xc0, 0xba, 0x6, 0x3, 0x70, 0xb, 0x9, 0xa0, - 0x18, 0x83, 0x9, 0x50, 0x26, 0x0, 0x4e, 0x9a, - 0x40, 0x0, 0x0, 0x2a, 0x20, 0x0, 0x0, 0x0, - 0x14, 0x0, 0x0, 0x0, 0x0, - - /* U+3087 "ょ" */ - 0x0, 0xa, 0x20, 0x0, 0x0, 0xb3, 0x31, 0x0, - 0xa, 0x66, 0x10, 0x0, 0xb0, 0x0, 0x0, 0xb, - 0x0, 0x0, 0x67, 0xe9, 0x30, 0x37, 0x1c, 0x1a, - 0x0, 0xce, 0x40, 0x0, - - /* U+3088 "よ" */ - 0x0, 0xa, 0x20, 0x0, 0x0, 0xa, 0x20, 0x0, - 0x0, 0xa, 0x8a, 0x80, 0x0, 0xa, 0x0, 0x0, - 0x0, 0xa, 0x0, 0x0, 0x0, 0xa, 0x0, 0x0, - 0x39, 0x9d, 0x81, 0x0, 0xa0, 0xa, 0x3c, 0x10, - 0x7a, 0xa3, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, - - /* U+3089 "ら" */ - 0x0, 0x0, 0x0, 0x0, 0x0, 0x7, 0x10, 0x0, - 0x0, 0x3, 0xc6, 0x0, 0x2, 0x93, 0x58, 0x0, - 0x9, 0x0, 0x0, 0x0, 0x18, 0x0, 0x21, 0x0, - 0x57, 0x98, 0x68, 0xb1, 0xac, 0x10, 0x0, 0x39, - 0x40, 0x0, 0x0, 0x2a, 0x0, 0x0, 0x0, 0x94, - 0x0, 0x13, 0x79, 0x50, 0x1, 0x33, 0x10, 0x0, - - /* U+308A "り" */ - 0x0, 0x0, 0x0, 0x7, 0x60, 0x68, 0x10, 0x83, - 0x93, 0x39, 0xa, 0x66, 0x0, 0xc0, 0xab, 0x0, - 0xb, 0xc, 0x70, 0x0, 0xb0, 0xd2, 0x0, 0xb, - 0x5, 0x0, 0x3, 0x70, 0x0, 0x0, 0x91, 0x0, - 0x0, 0x47, 0x0, 0x0, 0x27, 0x0, 0x0, 0x14, - 0x0, 0x0, - - /* U+308B "る" */ - 0x0, 0x0, 0x5a, 0x20, 0x0, 0x7a, 0x83, 0xb5, - 0x0, 0x0, 0x0, 0x85, 0x0, 0x0, 0x0, 0x75, - 0x0, 0x0, 0x0, 0x66, 0x23, 0x10, 0x0, 0x6e, - 0x85, 0x5a, 0x70, 0x9b, 0x10, 0x0, 0xc, 0x7, - 0x3, 0x40, 0x0, 0xb1, 0x2, 0xa4, 0x80, 0x2b, - 0x0, 0xb, 0x46, 0x9b, 0x10, 0x0, 0x15, 0x63, - 0x0, 0x0, - - /* U+308C "れ" */ - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x2b, - 0x0, 0x0, 0x0, 0x0, 0x0, 0xa, 0x0, 0x46, - 0x0, 0x0, 0x0, 0xc, 0x29, 0x66, 0x50, 0x0, - 0x18, 0x8d, 0x91, 0x4, 0x60, 0x0, 0x0, 0x6c, - 0x0, 0x6, 0x40, 0x0, 0x0, 0xc9, 0x0, 0x8, - 0x10, 0x0, 0x5, 0x79, 0x0, 0xa, 0x0, 0x0, - 0xc, 0x9, 0x0, 0x9, 0x0, 0x12, 0x66, 0x9a, - 0x0, 0x9, 0x35, 0x70, 0x10, 0x68, 0x0, 0x1, - 0x63, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - - /* U+308D "ろ" */ - 0x0, 0x0, 0x36, 0x90, 0x0, 0x0, 0x89, 0x43, - 0xd1, 0x0, 0x0, 0x0, 0x1a, 0x0, 0x0, 0x0, - 0x1, 0x90, 0x0, 0x0, 0x0, 0x1a, 0x57, 0x74, - 0x0, 0x2, 0xda, 0x40, 0x15, 0xa0, 0x2d, 0x40, - 0x0, 0x0, 0x92, 0x11, 0x0, 0x0, 0x0, 0xa1, - 0x0, 0x0, 0x0, 0x3, 0xa0, 0x0, 0x2, 0x56, - 0x88, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - - /* U+308F "わ" */ - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xc, - 0x10, 0x0, 0x0, 0x0, 0x0, 0xb, 0x0, 0x0, - 0x0, 0x0, 0x0, 0xa, 0x30, 0x34, 0x30, 0x0, - 0x4, 0x8d, 0x79, 0x54, 0x6a, 0x10, 0x4, 0x1e, - 0x70, 0x0, 0x2, 0xa0, 0x0, 0x8e, 0x0, 0x0, - 0x0, 0xb0, 0x2, 0xba, 0x0, 0x0, 0x0, 0xa0, - 0xb, 0x2a, 0x0, 0x0, 0x2, 0x80, 0x2b, 0x7b, - 0x0, 0x0, 0x29, 0x0, 0x1, 0x2d, 0x0, 0x4, - 0x40, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - - /* U+3092 "を" */ - 0x0, 0x0, 0x10, 0x0, 0x0, 0x0, 0x0, 0xb2, - 0x0, 0x0, 0x1, 0x1, 0xa1, 0x64, 0x0, 0x2, - 0x8d, 0xa8, 0x40, 0x0, 0x0, 0x47, 0x0, 0x0, - 0x0, 0x1, 0xd8, 0x93, 0x0, 0x87, 0xd, 0x60, - 0xb, 0x7a, 0x51, 0x14, 0x0, 0x8d, 0x30, 0x0, - 0x0, 0x2a, 0x3a, 0x0, 0x0, 0x0, 0xa1, 0x16, - 0x0, 0x0, 0x0, 0xa2, 0x0, 0x0, 0x0, 0x0, - 0x2a, 0xaa, 0xba, 0x0, - - /* U+3093 "ん" */ - 0x0, 0x0, 0x7, 0x0, 0x0, 0x0, 0x0, 0x4, - 0xb0, 0x0, 0x0, 0x0, 0x0, 0xa2, 0x0, 0x0, - 0x0, 0x0, 0x29, 0x0, 0x0, 0x0, 0x0, 0x9, - 0x10, 0x0, 0x0, 0x0, 0x2, 0x98, 0xa5, 0x0, - 0x0, 0x0, 0x9c, 0x20, 0xa0, 0x0, 0x20, 0x2f, - 0x20, 0xa, 0x0, 0x6, 0xa, 0x70, 0x0, 0xb0, - 0x7, 0x11, 0xd0, 0x0, 0xb, 0x58, 0x50, 0x1, - 0x0, 0x0, 0x15, 0x10, 0x0, - - /* U+30A1 "ァ" */ - 0x0, 0x0, 0x0, 0x0, 0x3, 0x46, 0x77, 0xc5, - 0x7, 0x62, 0x4, 0xa2, 0x0, 0x4, 0x74, 0x0, - 0x0, 0x6, 0x60, 0x0, 0x0, 0xa, 0x20, 0x0, - 0x0, 0x1a, 0x0, 0x0, 0x0, 0x91, 0x0, 0x0, - 0x4, 0x10, 0x0, 0x0, - - /* U+30A2 "ア" */ - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x14, - 0x78, 0xe6, 0x1c, 0xb8, 0x62, 0x4, 0xd3, 0x1, - 0x0, 0x0, 0x3a, 0x0, 0x0, 0x0, 0x5a, 0x50, - 0x0, 0x0, 0x0, 0x76, 0x0, 0x0, 0x0, 0x0, - 0xb1, 0x0, 0x0, 0x0, 0x2, 0xa0, 0x0, 0x0, - 0x0, 0xa, 0x30, 0x0, 0x0, 0x0, 0x48, 0x0, - 0x0, 0x0, 0x1, 0x90, 0x0, 0x0, 0x0, 0x3, - 0x0, 0x0, 0x0, 0x0, - - /* U+30A3 "ィ" */ - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xb3, - 0x0, 0x0, 0x6, 0xa0, 0x0, 0x0, 0x69, 0x0, - 0x0, 0x8, 0x8a, 0x0, 0x2, 0x72, 0xa, 0x0, - 0x1, 0x0, 0x9, 0x0, 0x0, 0x0, 0x1a, 0x0, - 0x0, 0x0, 0x19, 0x0, 0x0, 0x0, 0x1, 0x0, - - /* U+30A4 "イ" */ - 0x0, 0x0, 0x0, 0x1, 0x0, 0x0, 0x0, 0x2, - 0xe0, 0x0, 0x0, 0x0, 0xb5, 0x0, 0x0, 0x0, - 0x95, 0x0, 0x0, 0x0, 0x99, 0x0, 0x0, 0x1, - 0xa5, 0xd0, 0x0, 0x5, 0x71, 0xb, 0x0, 0x3, - 0x10, 0x0, 0xa0, 0x0, 0x0, 0x0, 0xa, 0x0, - 0x0, 0x0, 0x0, 0xb0, 0x0, 0x0, 0x0, 0x1b, - 0x0, 0x0, 0x0, 0x0, 0x60, 0x0, - - /* U+30A6 "ウ" */ - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xd2, - 0x0, 0x0, 0x0, 0x0, 0xa2, 0x25, 0x80, 0x29, - 0x89, 0xa8, 0x63, 0xe3, 0xb, 0x0, 0x0, 0x4, - 0x90, 0xc, 0x0, 0x0, 0xb, 0x10, 0xd, 0x0, - 0x0, 0x66, 0x0, 0x2, 0x0, 0x2, 0xa0, 0x0, - 0x0, 0x0, 0xb, 0x10, 0x0, 0x0, 0x0, 0x92, - 0x0, 0x0, 0x0, 0x17, 0x10, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x0, 0x0, - - /* U+30A7 "ェ" */ - 0x0, 0x12, 0x36, 0x91, 0x0, 0x7, 0x7c, 0x40, - 0x0, 0x0, 0x0, 0x92, 0x0, 0x0, 0x0, 0x9, - 0x10, 0x0, 0x2, 0x45, 0xc9, 0xab, 0x50, 0x56, - 0x42, 0x0, 0x0, - - /* U+30A8 "エ" */ - 0x0, 0x0, 0x0, 0x1, 0x10, 0x0, 0x7, 0x89, - 0xa9, 0x97, 0x0, 0x0, 0x22, 0xd, 0x10, 0x0, - 0x0, 0x0, 0x0, 0xb0, 0x0, 0x0, 0x0, 0x0, - 0xa, 0x0, 0x0, 0x0, 0x0, 0x0, 0xa0, 0x0, - 0x0, 0x7, 0x78, 0x9c, 0x99, 0xaa, 0x70, 0x44, - 0x10, 0x0, 0x0, 0x0, - - /* U+30AA "オ" */ - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0xc, 0x30, 0x0, 0x0, 0x0, 0x0, 0x92, 0x0, - 0x0, 0x0, 0x0, 0x2a, 0x68, 0xa3, 0x4, 0xb9, - 0x89, 0xf2, 0x10, 0x0, 0x0, 0x1, 0xb9, 0x10, - 0x0, 0x0, 0x0, 0xb2, 0x91, 0x0, 0x0, 0x0, - 0xa3, 0x9, 0x10, 0x0, 0x0, 0x92, 0x0, 0x91, - 0x0, 0x2, 0x60, 0x1, 0x19, 0x20, 0x0, 0x0, - 0x0, 0x9, 0xe0, 0x0, 0x0, 0x0, 0x0, 0x4, - 0x0, 0x0, - - /* U+30AB "カ" */ - 0x0, 0x0, 0xb, 0x0, 0x0, 0x0, 0x0, 0xd, - 0x0, 0x0, 0x0, 0x0, 0x1a, 0x37, 0x90, 0x7, - 0x99, 0xba, 0x52, 0xe1, 0x2, 0x20, 0xb0, 0x2, - 0xa0, 0x0, 0x2, 0x90, 0x6, 0x60, 0x0, 0xa, - 0x10, 0xb, 0x10, 0x0, 0x65, 0x0, 0x1c, 0x0, - 0x4, 0x70, 0x9, 0xa7, 0x0, 0x14, 0x0, 0x3, - 0xb0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - - /* U+30AC "ガ" */ - 0x0, 0x0, 0x0, 0x0, 0x2, 0x50, 0x0, 0x0, - 0x9, 0x30, 0x54, 0x92, 0x0, 0x0, 0xb, 0x30, - 0xb, 0x0, 0x0, 0x0, 0xc, 0x4, 0x81, 0x0, - 0x3, 0x68, 0x9d, 0x85, 0xb6, 0x0, 0x0, 0x41, - 0x56, 0x0, 0xb1, 0x0, 0x0, 0x0, 0xb1, 0x0, - 0xb0, 0x0, 0x0, 0x3, 0x80, 0x4, 0x70, 0x0, - 0x0, 0xa, 0x0, 0x9, 0x20, 0x0, 0x0, 0x82, - 0x6, 0x6c, 0x0, 0x0, 0x4, 0x10, 0x1, 0xe5, - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - - /* U+30AD "キ" */ - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x2, 0xa0, - 0x0, 0x0, 0x0, 0x0, 0xb0, 0x0, 0x0, 0x0, - 0x1, 0xb6, 0x89, 0x30, 0x7, 0x97, 0xa3, 0x0, - 0x0, 0x0, 0x0, 0x54, 0x3, 0x40, 0x23, 0x57, - 0xac, 0x87, 0x51, 0x47, 0x31, 0x9, 0x0, 0x0, - 0x0, 0x0, 0xa, 0x0, 0x0, 0x0, 0x0, 0xb, - 0x0, 0x0, 0x0, 0x0, 0x9, 0x10, 0x0, 0x0, - 0x0, 0x1, 0x0, 0x0, - - /* U+30AE "ギ" */ - 0x0, 0x0, 0x0, 0x0, 0x20, 0x0, 0x0, 0x2b, - 0x0, 0x32, 0xc0, 0x0, 0x0, 0xb0, 0x1, 0xc0, - 0x0, 0x0, 0x1b, 0x79, 0x80, 0x0, 0x6, 0x96, - 0x93, 0x0, 0x0, 0x0, 0x0, 0x4, 0x51, 0x35, - 0x0, 0x24, 0x68, 0x9c, 0x86, 0x51, 0x3, 0x63, - 0x0, 0xa0, 0x0, 0x0, 0x0, 0x0, 0xa, 0x0, - 0x0, 0x0, 0x0, 0x0, 0xb0, 0x0, 0x0, 0x0, - 0x0, 0x8, 0x20, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, - - /* U+30AF "ク" */ - 0x0, 0x0, 0x21, 0x0, 0x0, 0x0, 0x9, 0x80, - 0x0, 0x0, 0x1, 0xd2, 0x25, 0x10, 0x0, 0x97, - 0x75, 0x9b, 0x0, 0x66, 0x0, 0xd, 0x20, 0x23, - 0x0, 0x8, 0x50, 0x0, 0x0, 0x3, 0xa0, 0x0, - 0x0, 0x1, 0xb0, 0x0, 0x0, 0x0, 0xb2, 0x0, - 0x0, 0x1, 0xa3, 0x0, 0x0, 0x3, 0x71, 0x0, - 0x0, 0x0, 0x10, 0x0, 0x0, 0x0, - - /* U+30B0 "グ" */ - 0x0, 0x0, 0x31, 0x0, 0x31, 0x0, 0x0, 0xa, - 0x60, 0x36, 0xb0, 0x0, 0x2, 0xd3, 0x36, 0x82, - 0x0, 0x0, 0xa6, 0x64, 0xa9, 0x0, 0x0, 0x74, - 0x0, 0x1d, 0x10, 0x0, 0x32, 0x0, 0xa, 0x30, - 0x0, 0x0, 0x0, 0x5, 0x80, 0x0, 0x0, 0x0, - 0x2, 0xb0, 0x0, 0x0, 0x0, 0x1, 0xb1, 0x0, - 0x0, 0x0, 0x2, 0xa1, 0x0, 0x0, 0x0, 0x4, - 0x70, 0x0, 0x0, 0x0, 0x0, 0x10, 0x0, 0x0, - 0x0, 0x0, - - /* U+30B1 "ケ" */ - 0x0, 0x6, 0x10, 0x0, 0x0, 0x0, 0xe, 0x30, - 0x0, 0x0, 0x0, 0x67, 0x3, 0x69, 0xa4, 0x1, - 0xba, 0x89, 0x91, 0x0, 0x9, 0x10, 0x7, 0x70, - 0x0, 0x30, 0x0, 0xb, 0x10, 0x0, 0x0, 0x0, - 0x38, 0x0, 0x0, 0x0, 0x0, 0xa1, 0x0, 0x0, - 0x0, 0x6, 0x40, 0x0, 0x0, 0x0, 0x34, 0x0, - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - - /* U+30B2 "ゲ" */ - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x50, - 0x0, 0x0, 0x83, 0x0, 0xd, 0x20, 0x0, 0x75, - 0x70, 0x6, 0x70, 0x3, 0x66, 0x60, 0x1, 0xb9, - 0x8a, 0xa3, 0x20, 0x0, 0x91, 0x0, 0x69, 0x0, - 0x0, 0x30, 0x0, 0xb, 0x10, 0x0, 0x0, 0x0, - 0x4, 0x70, 0x0, 0x0, 0x0, 0x0, 0xa0, 0x0, - 0x0, 0x0, 0x0, 0x82, 0x0, 0x0, 0x0, 0x0, - 0x42, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, - - /* U+30B3 "コ" */ - 0x0, 0x0, 0x0, 0x0, 0x0, 0x36, 0x78, 0x99, - 0xd6, 0x1, 0x53, 0x0, 0x8, 0x50, 0x0, 0x0, - 0x0, 0xa0, 0x0, 0x0, 0x0, 0xb, 0x0, 0x0, - 0x0, 0x0, 0xa0, 0x0, 0x0, 0x13, 0x79, 0x0, - 0x8b, 0xa8, 0x65, 0x40, - - /* U+30B4 "ゴ" */ - 0x0, 0x0, 0x0, 0x0, 0x4, 0x20, 0x0, 0x0, - 0x0, 0x0, 0x72, 0xb0, 0x0, 0x0, 0x0, 0x1, - 0x19, 0x0, 0x2, 0x46, 0x78, 0x8c, 0x80, 0x0, - 0x1, 0x74, 0x0, 0x7, 0x60, 0x0, 0x0, 0x0, - 0x0, 0xa, 0x10, 0x0, 0x0, 0x0, 0x0, 0xb, - 0x0, 0x0, 0x0, 0x0, 0x0, 0xb, 0x0, 0x0, - 0x0, 0x0, 0x13, 0x6a, 0x0, 0x0, 0x8, 0xb9, - 0x76, 0x54, 0x0, 0x0, - - /* U+30B5 "サ" */ - 0x0, 0x0, 0x0, 0x14, 0x0, 0x0, 0x0, 0xd, - 0x10, 0xd, 0x0, 0x0, 0x0, 0xa, 0x0, 0xb, - 0x0, 0x0, 0x1, 0x2c, 0x67, 0x8d, 0x9a, 0xa1, - 0x59, 0x6c, 0x20, 0xb, 0x0, 0x0, 0x0, 0xb, - 0x0, 0x1a, 0x0, 0x0, 0x0, 0xb, 0x0, 0x47, - 0x0, 0x0, 0x0, 0x0, 0x0, 0x82, 0x0, 0x0, - 0x0, 0x0, 0x1, 0xa0, 0x0, 0x0, 0x0, 0x0, - 0x1a, 0x10, 0x0, 0x0, 0x0, 0x0, 0x50, 0x0, - 0x0, 0x0, - - /* U+30B6 "ザ" */ - 0x0, 0x0, 0x0, 0x0, 0x0, 0x13, 0x0, 0x0, - 0x0, 0x0, 0x40, 0x43, 0x85, 0x0, 0x3, 0xa0, - 0xb, 0x20, 0xa1, 0x10, 0x0, 0xa, 0x0, 0xa0, - 0x0, 0x0, 0x0, 0x2, 0xc7, 0x7d, 0x89, 0xa2, - 0x0, 0x99, 0x5b, 0x0, 0xa0, 0x0, 0x0, 0x0, - 0x1, 0xa0, 0xa, 0x0, 0x0, 0x0, 0x0, 0x19, - 0x0, 0xa0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x45, - 0x0, 0x0, 0x0, 0x0, 0x0, 0xa, 0x0, 0x0, - 0x0, 0x0, 0x0, 0x7, 0x10, 0x0, 0x0, 0x0, - 0x0, 0x3, 0x0, 0x0, 0x0, 0x0, - - /* U+30B7 "シ" */ - 0x2, 0x72, 0x0, 0x0, 0x0, 0x0, 0x2, 0xd1, - 0x0, 0x0, 0x0, 0x0, 0x1, 0x0, 0x0, 0x6, - 0x4, 0x93, 0x0, 0x0, 0x8, 0x10, 0x2, 0xc0, - 0x0, 0x9, 0x30, 0x0, 0x0, 0x0, 0x1a, 0x20, - 0x0, 0x0, 0x0, 0x5b, 0x10, 0x0, 0x0, 0x26, - 0xc8, 0x0, 0x0, 0x0, 0xa, 0xb2, 0x0, 0x0, - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - - /* U+30B8 "ジ" */ - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x1, 0x48, 0x0, 0x2, 0x72, 0x0, 0x49, 0x50, - 0x0, 0x2, 0xd2, 0x0, 0x40, 0x0, 0x10, 0x1, - 0x0, 0x0, 0x6, 0x1, 0x96, 0x0, 0x0, 0x9, - 0x10, 0x0, 0xb3, 0x0, 0xa, 0x30, 0x0, 0x0, - 0x0, 0x1b, 0x30, 0x0, 0x0, 0x0, 0x5b, 0x10, - 0x0, 0x0, 0x15, 0xa7, 0x0, 0x0, 0x0, 0x6, - 0xb1, 0x0, 0x0, 0x0, 0x0, - - /* U+30B9 "ス" */ - 0x0, 0x0, 0x0, 0x2, 0x20, 0x0, 0x1, 0x34, - 0x89, 0xad, 0x0, 0x0, 0x39, 0x61, 0xa, 0x50, - 0x0, 0x0, 0x0, 0x2, 0xb0, 0x0, 0x0, 0x0, - 0x0, 0xb2, 0x0, 0x0, 0x0, 0x0, 0x89, 0x60, - 0x0, 0x0, 0x0, 0x59, 0x4, 0x80, 0x0, 0x0, - 0x69, 0x0, 0x8, 0x80, 0x0, 0x85, 0x0, 0x0, - 0x1e, 0x20, 0x30, 0x0, 0x0, 0x0, 0x51, - - /* U+30BA "ズ" */ - 0x0, 0x0, 0x0, 0x0, 0x1, 0x71, 0x0, 0x0, - 0x0, 0x11, 0x57, 0x26, 0x1, 0x24, 0x79, 0xbc, - 0x8, 0x0, 0x3, 0xa5, 0x10, 0xa4, 0x0, 0x0, - 0x0, 0x0, 0x3, 0xb0, 0x0, 0x0, 0x0, 0x0, - 0xb, 0x20, 0x0, 0x0, 0x0, 0x0, 0x6a, 0x40, - 0x0, 0x0, 0x0, 0x4, 0x90, 0x58, 0x0, 0x0, - 0x0, 0x48, 0x0, 0x8, 0x80, 0x0, 0x6, 0x50, - 0x0, 0x0, 0xe2, 0x0, 0x20, 0x0, 0x0, 0x0, - 0x30, 0x0, - - /* U+30BB "セ" */ - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xe, - 0x10, 0x0, 0x0, 0x0, 0x0, 0xd0, 0x0, 0x39, - 0x0, 0x0, 0xb, 0x6, 0x96, 0xe4, 0x0, 0x5, - 0xd8, 0x20, 0x84, 0x0, 0x6b, 0x5b, 0x0, 0x35, - 0x0, 0x0, 0x0, 0xb0, 0x1, 0x0, 0x0, 0x0, - 0xb, 0x0, 0x0, 0x0, 0x0, 0x0, 0x95, 0x0, - 0x14, 0x10, 0x0, 0x1, 0x9b, 0xba, 0x70, - - /* U+30BC "ゼ" */ - 0x0, 0x0, 0x0, 0x0, 0x0, 0x33, 0x0, 0x0, - 0x0, 0x0, 0x0, 0x35, 0xb1, 0x0, 0x0, 0xd2, - 0x0, 0x0, 0x92, 0x0, 0x0, 0xb, 0x0, 0x2, - 0x81, 0x0, 0x0, 0x0, 0xb1, 0x69, 0x8e, 0x50, - 0x0, 0x0, 0x5e, 0x72, 0x8, 0x30, 0x0, 0x6, - 0xb4, 0xb0, 0x4, 0x40, 0x0, 0x0, 0x0, 0xb, - 0x0, 0x20, 0x0, 0x0, 0x0, 0x0, 0xa0, 0x0, - 0x0, 0x0, 0x0, 0x0, 0x8, 0x50, 0x12, 0x52, - 0x0, 0x0, 0x0, 0x18, 0xab, 0xa8, 0x10, 0x0, - - /* U+30BD "ソ" */ - 0x0, 0x0, 0x0, 0x0, 0x50, 0x0, 0x0, 0x6a, - 0x59, 0x0, 0x0, 0x88, 0xd, 0x20, 0x0, 0xd1, - 0x5, 0x10, 0x5, 0x80, 0x0, 0x0, 0xc, 0x0, - 0x0, 0x0, 0x94, 0x0, 0x0, 0x6, 0x70, 0x0, - 0x0, 0x67, 0x0, 0x0, 0x6, 0x40, 0x0, 0x0, - 0x10, 0x0, 0x0, 0x0, - - /* U+30BF "タ" */ - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x66, - 0x0, 0x0, 0x0, 0x0, 0xd9, 0x8b, 0xe0, 0x0, - 0x8, 0x64, 0x18, 0x80, 0x0, 0x7b, 0x10, 0x1d, - 0x0, 0x7, 0x60, 0xb5, 0x95, 0x0, 0x21, 0x0, - 0x1d, 0xa0, 0x0, 0x0, 0x0, 0x1b, 0x0, 0x0, - 0x0, 0x1, 0xb1, 0x0, 0x0, 0x0, 0x4a, 0x10, - 0x0, 0x0, 0x7, 0x60, 0x0, 0x0, 0x0, 0x20, - 0x0, 0x0, 0x0, 0x0, - - /* U+30C0 "ダ" */ - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x0, 0x1, 0x92, 0x0, 0x0, 0x9, - 0x20, 0x1, 0x95, 0x50, 0x0, 0x2, 0xe7, 0x8c, - 0xa1, 0x40, 0x0, 0x0, 0xb5, 0x40, 0xb3, 0x0, - 0x0, 0x0, 0x98, 0x0, 0x49, 0x0, 0x0, 0x0, - 0x83, 0x2c, 0x2c, 0x10, 0x0, 0x0, 0x20, 0x0, - 0x4d, 0x50, 0x0, 0x0, 0x0, 0x0, 0x5, 0x80, - 0x0, 0x0, 0x0, 0x0, 0x4, 0x90, 0x0, 0x0, - 0x0, 0x0, 0x6, 0x80, 0x0, 0x0, 0x0, 0x0, - 0x17, 0x40, 0x0, 0x0, 0x0, 0x0, 0x3, 0x0, - 0x0, 0x0, 0x0, 0x0, 0x0, - - /* U+30C1 "チ" */ - 0x0, 0x0, 0x0, 0x8, 0x70, 0x0, 0x0, 0x0, - 0x48, 0xb6, 0x20, 0x0, 0x0, 0x14, 0x21, 0xe0, - 0x0, 0x0, 0x0, 0x0, 0x0, 0xd4, 0x57, 0x50, - 0x7, 0xba, 0x99, 0xc5, 0x44, 0x40, 0x0, 0x0, - 0x4, 0x70, 0x0, 0x0, 0x0, 0x0, 0x9, 0x30, - 0x0, 0x0, 0x0, 0x0, 0x2a, 0x0, 0x0, 0x0, - 0x0, 0x0, 0xa1, 0x0, 0x0, 0x0, 0x0, 0x8, - 0x10, 0x0, 0x0, 0x0, 0x0, 0x20, 0x0, 0x0, - 0x0, 0x0, - - /* U+30C3 "ッ" */ - 0x0, 0x20, 0x0, 0x0, 0x41, 0x47, 0x3, 0xd0, - 0x1c, 0x8, 0x6, 0x80, 0x4, 0x0, 0xc, 0x10, - 0x0, 0x0, 0x65, 0x0, 0x0, 0x3, 0x80, 0x0, - 0x0, 0x38, 0x0, 0x0, 0x1, 0x30, 0x0, 0x0, - - /* U+30C4 "ツ" */ - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x6, 0x20, - 0x0, 0x70, 0x16, 0x1, 0xd0, 0x1, 0xe1, 0xa, - 0x40, 0x90, 0x7, 0x60, 0x5, 0x50, 0x0, 0x1b, - 0x0, 0x0, 0x0, 0x0, 0x93, 0x0, 0x0, 0x0, - 0x4, 0x80, 0x0, 0x0, 0x0, 0x1a, 0x0, 0x0, - 0x0, 0x1, 0x90, 0x0, 0x0, 0x0, 0x26, 0x0, - 0x0, 0x0, 0x0, 0x10, 0x0, 0x0, 0x0, - - /* U+30C6 "テ" */ - 0x0, 0x0, 0x2, 0x61, 0x0, 0x0, 0x59, 0x86, - 0x52, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x34, - 0x56, 0x87, 0x8a, 0xb1, 0x36, 0x31, 0x79, 0x0, - 0x0, 0x0, 0x0, 0x94, 0x0, 0x0, 0x0, 0x0, - 0xb0, 0x0, 0x0, 0x0, 0x8, 0x40, 0x0, 0x0, - 0x0, 0x38, 0x0, 0x0, 0x0, 0x2, 0x80, 0x0, - 0x0, 0x0, 0x2, 0x0, 0x0, 0x0, 0x0, - - /* U+30C7 "デ" */ - 0x0, 0x0, 0x0, 0x0, 0x2, 0x40, 0x0, 0x0, - 0x1, 0x41, 0x25, 0x93, 0x0, 0x49, 0x87, 0x63, - 0x8, 0x10, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x12, 0x46, 0x78, 0x9a, 0xb2, 0x0, 0x26, 0x42, - 0x2c, 0x0, 0x0, 0x0, 0x0, 0x0, 0x66, 0x0, - 0x0, 0x0, 0x0, 0x0, 0xb0, 0x0, 0x0, 0x0, - 0x0, 0x5, 0x50, 0x0, 0x0, 0x0, 0x0, 0x19, - 0x0, 0x0, 0x0, 0x0, 0x1, 0x80, 0x0, 0x0, - 0x0, 0x0, 0x2, 0x0, 0x0, 0x0, 0x0, 0x0, - - /* U+30C8 "ト" */ - 0x18, 0x0, 0x0, 0xc, 0x0, 0x0, 0xb, 0x0, - 0x0, 0xb, 0x10, 0x0, 0xa, 0x59, 0x20, 0xa, - 0x1, 0xd5, 0xa, 0x0, 0x14, 0xa, 0x0, 0x0, - 0xb, 0x0, 0x0, 0xb, 0x0, 0x0, 0x3, 0x0, - 0x0, - - /* U+30C9 "ド" */ - 0x81, 0x0, 0x3, 0x0, 0xb2, 0x1, 0x53, 0xb0, - 0xa0, 0x0, 0x67, 0x30, 0xa3, 0x0, 0x0, 0x0, - 0xa2, 0x94, 0x0, 0x0, 0xa0, 0xb, 0x70, 0x0, - 0xa0, 0x0, 0x50, 0x0, 0xa0, 0x0, 0x0, 0x0, - 0xc0, 0x0, 0x0, 0x0, 0xc0, 0x0, 0x0, 0x0, - 0x20, 0x0, 0x0, 0x0, - - /* U+30CA "ナ" */ - 0x0, 0x0, 0x36, 0x0, 0x0, 0x0, 0x0, 0x2c, - 0x0, 0x0, 0x0, 0x0, 0x1a, 0x0, 0x0, 0x0, - 0x23, 0x6d, 0x99, 0xb5, 0x7a, 0x75, 0x58, 0x0, - 0x0, 0x0, 0x0, 0x55, 0x0, 0x0, 0x0, 0x0, - 0x91, 0x0, 0x0, 0x0, 0x1, 0xa0, 0x0, 0x0, - 0x0, 0x8, 0x20, 0x0, 0x0, 0x0, 0x44, 0x0, - 0x0, 0x0, 0x0, 0x20, 0x0, 0x0, 0x0, - - /* U+30CB "ニ" */ - 0x0, 0x0, 0x0, 0x2, 0x10, 0x0, 0x0, 0x8, - 0xa8, 0x87, 0x70, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x28, 0x88, - 0x88, 0x88, 0x9a, 0x90, 0x2, 0x10, 0x0, 0x0, - 0x0, 0x0, - - /* U+30CD "ネ" */ - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x2, 0x96, - 0x0, 0x0, 0x0, 0x0, 0x5, 0x0, 0x0, 0x0, - 0x0, 0x37, 0xc7, 0x0, 0x1, 0xa9, 0x52, 0xc1, - 0x0, 0x0, 0x0, 0x1b, 0x10, 0x0, 0x0, 0x2, - 0xc6, 0x23, 0x0, 0x0, 0x49, 0x2a, 0x6, 0xa0, - 0x6, 0x50, 0x9, 0x0, 0x84, 0x20, 0x0, 0xa, - 0x0, 0x0, 0x0, 0x0, 0x2a, 0x0, 0x0, 0x0, - 0x0, 0x5, 0x0, 0x0, - - /* U+30CE "ノ" */ - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x1, 0xe0, 0x0, 0x0, 0x0, 0x7, 0x90, 0x0, - 0x0, 0x0, 0x2c, 0x0, 0x0, 0x0, 0x0, 0xc2, - 0x0, 0x0, 0x0, 0x9, 0x40, 0x0, 0x0, 0x0, - 0x85, 0x0, 0x0, 0x0, 0x9, 0x40, 0x0, 0x0, - 0x1, 0x92, 0x0, 0x0, 0x0, 0x25, 0x0, 0x0, - 0x0, 0x0, - - /* U+30CF "ハ" */ - 0x0, 0x0, 0x60, 0x1, 0x0, 0x0, 0x0, 0x1, - 0xf2, 0x1, 0x70, 0x0, 0x0, 0x9, 0x60, 0x0, - 0x49, 0x0, 0x0, 0x3a, 0x0, 0x0, 0xa, 0x60, - 0x1, 0xa0, 0x0, 0x0, 0x1, 0xe0, 0x7, 0x0, - 0x0, 0x0, 0x0, 0x81, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, - - /* U+30D0 "バ" */ - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x22, 0x90, 0x0, 0x0, 0x0, 0x0, - 0x48, 0x51, 0x0, 0x0, 0x50, 0x1, 0x3, 0x0, - 0x0, 0x1, 0xe1, 0x0, 0x70, 0x0, 0x0, 0x8, - 0x50, 0x0, 0x29, 0x0, 0x0, 0x29, 0x0, 0x0, - 0x9, 0x60, 0x0, 0x90, 0x0, 0x0, 0x1, 0xe0, - 0x6, 0x0, 0x0, 0x0, 0x0, 0x91, 0x0, 0x0, - 0x0, 0x0, 0x0, 0x0, - - /* U+30D1 "パ" */ - 0x0, 0x0, 0x0, 0x0, 0x4, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x41, 0x60, 0x0, 0x0, 0x0, 0x0, - 0x16, 0x40, 0x0, 0x0, 0x40, 0x1, 0x20, 0x0, - 0x0, 0x0, 0xd3, 0x0, 0x71, 0x0, 0x0, 0x5, - 0x80, 0x0, 0xb, 0x0, 0x0, 0x1a, 0x0, 0x0, - 0x6, 0x90, 0x0, 0x91, 0x0, 0x0, 0x0, 0xe2, - 0x6, 0x10, 0x0, 0x0, 0x0, 0x73, 0x0, 0x0, - 0x0, 0x0, 0x0, 0x0, - - /* U+30D2 "ヒ" */ - 0x0, 0x0, 0x0, 0x0, 0xd2, 0x0, 0x0, 0x0, - 0xb0, 0x0, 0x1, 0x0, 0xb0, 0x15, 0xae, 0x40, - 0xb5, 0x53, 0x0, 0x0, 0xb0, 0x0, 0x0, 0x0, - 0xb0, 0x0, 0x0, 0x0, 0xb0, 0x0, 0x0, 0x0, - 0x96, 0x10, 0x13, 0x50, 0x6, 0x99, 0x98, 0x60, - - /* U+30D3 "ビ" */ - 0x0, 0x0, 0x0, 0x10, 0x2, 0xc0, 0x0, 0x2, - 0xa4, 0xb, 0x0, 0x0, 0x79, 0x30, 0xb0, 0x0, - 0x28, 0x20, 0xb, 0x3, 0x9a, 0x61, 0x0, 0xc6, - 0x40, 0x0, 0x0, 0xb, 0x0, 0x0, 0x0, 0x0, - 0xb0, 0x0, 0x0, 0x0, 0xc, 0x30, 0x1, 0x44, - 0x0, 0x28, 0x99, 0x98, 0x40, - - /* U+30D4 "ピ" */ - 0x0, 0x0, 0x0, 0x6, 0x90, 0xa, 0x0, 0x0, - 0x5, 0x32, 0xc, 0x0, 0x0, 0x1, 0x20, 0xb, - 0x0, 0x1, 0xa1, 0x0, 0xb, 0x3, 0x8a, 0x61, - 0x0, 0xb, 0x54, 0x0, 0x0, 0x0, 0xb, 0x0, - 0x0, 0x0, 0x0, 0xb, 0x0, 0x0, 0x0, 0x0, - 0x9, 0x52, 0x12, 0x46, 0x0, 0x0, 0x68, 0x98, - 0x75, 0x0, - - /* U+30D5 "フ" */ - 0x0, 0x0, 0x0, 0x0, 0x10, 0x14, 0x46, 0x89, - 0x99, 0xf4, 0x7, 0x63, 0x10, 0x3, 0xc0, 0x0, - 0x0, 0x0, 0xb, 0x20, 0x0, 0x0, 0x0, 0x67, - 0x0, 0x0, 0x0, 0x3, 0xb0, 0x0, 0x0, 0x0, - 0x2b, 0x0, 0x0, 0x0, 0x3, 0xa0, 0x0, 0x0, - 0x0, 0x57, 0x0, 0x0, 0x0, 0x4, 0x10, 0x0, - 0x0, 0x0, - - /* U+30D6 "ブ" */ - 0x0, 0x0, 0x0, 0x0, 0x0, 0x6, 0x20, 0x0, - 0x0, 0x0, 0x0, 0x8, 0x2b, 0x0, 0x0, 0x2, - 0x57, 0xa7, 0x25, 0x0, 0x7b, 0xa8, 0x63, 0x17, - 0xa0, 0x0, 0x0, 0x0, 0x0, 0x1, 0xd0, 0x0, - 0x0, 0x0, 0x0, 0x0, 0xa4, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x58, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x3a, 0x0, 0x0, 0x0, 0x0, 0x0, 0x3a, 0x0, - 0x0, 0x0, 0x0, 0x0, 0x58, 0x0, 0x0, 0x0, - 0x0, 0x1, 0x63, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - - /* U+30D7 "プ" */ - 0x0, 0x0, 0x0, 0x0, 0x0, 0x35, 0x30, 0x0, - 0x0, 0x0, 0x0, 0x5, 0x15, 0x0, 0x0, 0x1, - 0x36, 0x95, 0x4, 0x0, 0x8b, 0x99, 0x75, 0x28, - 0xa0, 0x0, 0x0, 0x0, 0x0, 0x1, 0xd0, 0x0, - 0x0, 0x0, 0x0, 0x0, 0x94, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x59, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x3b, 0x0, 0x0, 0x0, 0x0, 0x0, 0x3a, 0x0, - 0x0, 0x0, 0x0, 0x0, 0x49, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x64, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - - /* U+30D9 "ベ" */ - 0x0, 0x0, 0x0, 0x0, 0x14, 0x0, 0x0, 0x0, - 0x10, 0x4, 0x48, 0x50, 0x0, 0x9, 0xb5, 0x0, - 0x90, 0x0, 0x0, 0xa4, 0x9, 0x50, 0x0, 0x0, - 0x2b, 0x50, 0x0, 0xb4, 0x0, 0x0, 0x35, 0x0, - 0x0, 0xb, 0x40, 0x0, 0x0, 0x0, 0x0, 0x0, - 0xc7, 0x0, 0x0, 0x0, 0x0, 0x0, 0xa, 0xb1, - 0x0, 0x0, 0x0, 0x0, 0x0, 0x41, - - /* U+30DA "ペ" */ - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x26, 0x40, 0x0, 0x0, 0x0, 0x30, 0x34, - 0x60, 0x0, 0x0, 0xb, 0x98, 0x1, 0x0, 0x0, - 0x0, 0xb2, 0x7, 0x70, 0x0, 0x0, 0x3c, 0x30, - 0x0, 0x96, 0x0, 0x0, 0x13, 0x0, 0x0, 0xa, - 0x70, 0x0, 0x0, 0x0, 0x0, 0x0, 0xa9, 0x0, - 0x0, 0x0, 0x0, 0x0, 0x8, 0xd2, 0x0, 0x0, - 0x0, 0x0, 0x0, 0x10, - - /* U+30DB "ホ" */ - 0x0, 0x0, 0xa1, 0x0, 0x0, 0x0, 0x0, 0xc1, - 0x0, 0x0, 0x0, 0x0, 0xb0, 0x23, 0x30, 0x5b, - 0x99, 0xd8, 0x77, 0x70, 0x0, 0x0, 0xb0, 0x0, - 0x0, 0x0, 0x20, 0xb0, 0x4, 0x0, 0x5, 0x20, - 0xb0, 0x3, 0x80, 0x2c, 0x0, 0xb0, 0x0, 0xc2, - 0x52, 0x6, 0xd0, 0x0, 0x31, 0x0, 0x2, 0xc0, - 0x0, 0x0, - - /* U+30DC "ボ" */ - 0x0, 0x0, 0x0, 0x0, 0x51, 0x0, 0x0, 0x9, - 0x10, 0x72, 0xb0, 0x0, 0x0, 0xb1, 0x2, 0x60, - 0x0, 0x0, 0xa, 0x1, 0x32, 0x0, 0x4a, 0x98, - 0xd8, 0x87, 0x70, 0x0, 0x0, 0xa, 0x0, 0x0, - 0x0, 0x0, 0x20, 0xa0, 0x4, 0x0, 0x0, 0x52, - 0xa, 0x0, 0x47, 0x0, 0x1c, 0x0, 0xa0, 0x0, - 0xc2, 0x6, 0x30, 0x6c, 0x10, 0x4, 0x10, 0x0, - 0x3, 0xd0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, - - /* U+30DD "ポ" */ - 0x0, 0x0, 0x0, 0x5, 0x10, 0x0, 0x0, 0x91, - 0x50, 0x50, 0x0, 0x0, 0xb1, 0x16, 0x20, 0x0, - 0x0, 0xa0, 0x23, 0x30, 0x5b, 0x98, 0xd8, 0x76, - 0x60, 0x0, 0x0, 0xa0, 0x0, 0x0, 0x0, 0x20, - 0xa0, 0x4, 0x0, 0x5, 0x20, 0xa0, 0x3, 0x80, - 0x2c, 0x0, 0xa0, 0x0, 0xc2, 0x52, 0x6, 0xc1, - 0x0, 0x31, 0x0, 0x2, 0xc0, 0x0, 0x0, - - /* U+30DE "マ" */ - 0x0, 0x0, 0x0, 0x24, 0x61, 0x7b, 0x98, 0x88, - 0x64, 0xb9, 0x0, 0x0, 0x0, 0x7, 0x90, 0x0, - 0x4, 0x0, 0x65, 0x0, 0x0, 0x2, 0x95, 0x20, - 0x0, 0x0, 0x0, 0x78, 0x0, 0x0, 0x0, 0x0, - 0xd, 0x20, 0x0, 0x0, 0x0, 0x4, 0x10, 0x0, - - /* U+30DF "ミ" */ - 0x4, 0x20, 0x0, 0x0, 0x6b, 0x70, 0x0, 0x0, - 0xa5, 0x1, 0x0, 0x0, 0x4, 0x96, 0x0, 0x0, - 0x7, 0xc0, 0x0, 0x0, 0x20, 0x35, 0x10, 0x0, - 0x1, 0x8b, 0x40, 0x0, 0x2, 0xc6, 0x0, 0x0, - 0x2, - - /* U+30E0 "ム" */ - 0x0, 0x0, 0x10, 0x0, 0x0, 0x0, 0x0, 0x88, - 0x0, 0x0, 0x0, 0x0, 0xc2, 0x0, 0x0, 0x0, - 0x3, 0x90, 0x0, 0x0, 0x0, 0x9, 0x10, 0x0, - 0x0, 0x0, 0x28, 0x0, 0x40, 0x0, 0x0, 0x91, - 0x0, 0x2a, 0x0, 0x3, 0x70, 0x15, 0x79, 0x90, - 0x1d, 0xaa, 0x83, 0x0, 0xe1, 0x18, 0x20, 0x0, - 0x0, 0x40, - - /* U+30E1 "メ" */ - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x5, 0xc0, 0x0, 0x0, 0x0, 0xa, 0x50, 0x0, - 0x2, 0x20, 0x2b, 0x0, 0x0, 0x0, 0x39, 0xc2, - 0x0, 0x0, 0x0, 0x7, 0xd8, 0x0, 0x0, 0x0, - 0x39, 0xa, 0x70, 0x0, 0x2, 0xb0, 0x0, 0x40, - 0x0, 0x39, 0x0, 0x0, 0x0, 0x5, 0x60, 0x0, - 0x0, 0x0, 0x10, 0x0, 0x0, 0x0, 0x0, - - /* U+30E2 "モ" */ - 0x0, 0x0, 0x1, 0x47, 0x81, 0x0, 0x7, 0x98, - 0xc4, 0x21, 0x0, 0x0, 0x0, 0xd, 0x0, 0x0, - 0x0, 0x0, 0x0, 0xb2, 0x46, 0x71, 0x6, 0xa9, - 0x8c, 0x65, 0x43, 0x10, 0x0, 0x0, 0xa0, 0x0, - 0x0, 0x0, 0x0, 0xa, 0x0, 0x0, 0x0, 0x0, - 0x0, 0xb2, 0x1, 0x20, 0x0, 0x0, 0x2, 0x9a, - 0xa6, 0x0, - - /* U+30E3 "ャ" */ - 0x0, 0x9, 0x50, 0x0, 0x0, 0x0, 0x3, 0x90, - 0x5, 0x70, 0x0, 0x4, 0xd8, 0x74, 0xc1, 0x6, - 0x94, 0x82, 0x6, 0x10, 0x0, 0x0, 0x37, 0x2, - 0x0, 0x0, 0x0, 0xb, 0x0, 0x0, 0x0, 0x0, - 0xa, 0x20, 0x0, 0x0, 0x0, 0x3, 0x40, 0x0, - - /* U+30E4 "ヤ" */ - 0x0, 0x4, 0x70, 0x0, 0x0, 0x0, 0x0, 0x1c, - 0x0, 0x0, 0x0, 0x0, 0x0, 0xb0, 0x0, 0x5b, - 0x70, 0x0, 0x9, 0x98, 0x84, 0x97, 0x1a, 0xa8, - 0x68, 0x0, 0x19, 0x0, 0x0, 0x0, 0xa0, 0x7, - 0x0, 0x0, 0x0, 0x9, 0x10, 0x20, 0x0, 0x0, - 0x0, 0x55, 0x0, 0x0, 0x0, 0x0, 0x1, 0xa0, - 0x0, 0x0, 0x0, 0x0, 0xc, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x20, 0x0, 0x0, - - /* U+30E5 "ュ" */ - 0x0, 0x12, 0x35, 0x30, 0x0, 0x0, 0x67, 0x46, - 0xb0, 0x0, 0x0, 0x0, 0x7, 0x40, 0x0, 0x0, - 0x0, 0xb, 0x0, 0x0, 0x7, 0x88, 0x9d, 0xab, - 0x90, 0x0, 0x20, 0x0, 0x0, 0x0, - - /* U+30E7 "ョ" */ - 0x0, 0x0, 0x1, 0x10, 0x3, 0xba, 0x9a, 0xd0, - 0x0, 0x0, 0x2, 0xa0, 0x1, 0xa9, 0x8a, 0x70, - 0x0, 0x0, 0x6, 0x40, 0x0, 0x0, 0x8, 0x20, - 0x8, 0xa9, 0x9a, 0x30, - - /* U+30E8 "ヨ" */ - 0x0, 0x0, 0x0, 0x0, 0x0, 0x29, 0x89, 0xaa, - 0xd5, 0x0, 0x21, 0x0, 0x7, 0x70, 0x0, 0x0, - 0x0, 0x93, 0x0, 0x0, 0x0, 0xb, 0x0, 0x2b, - 0xb9, 0x98, 0xc0, 0x0, 0x0, 0x0, 0xa, 0x0, - 0x0, 0x0, 0x2, 0x80, 0xb, 0xba, 0x99, 0xb8, - 0x0, 0x0, 0x0, 0x0, 0x0, - - /* U+30E9 "ラ" */ - 0x0, 0x0, 0x1, 0x35, 0x0, 0x0, 0x7a, 0x98, - 0x65, 0x10, 0x0, 0x0, 0x0, 0x0, 0x0, 0x3, - 0x35, 0x69, 0x9a, 0xe0, 0x6, 0x74, 0x20, 0x3, - 0xb0, 0x0, 0x0, 0x0, 0xb, 0x10, 0x0, 0x0, - 0x0, 0x85, 0x0, 0x0, 0x0, 0x7, 0x70, 0x0, - 0x0, 0x0, 0x86, 0x0, 0x0, 0x0, 0x18, 0x30, - 0x0, 0x0, 0x0, 0x30, 0x0, 0x0, 0x0, - - /* U+30EA "リ" */ - 0x5, 0x0, 0xa, 0x0, 0xc1, 0x0, 0xe0, 0xb, - 0x0, 0xc, 0x0, 0xb0, 0x0, 0xc0, 0xb, 0x0, - 0xc, 0x0, 0xc0, 0x0, 0xb0, 0x3, 0x0, 0x29, - 0x0, 0x0, 0x9, 0x30, 0x0, 0x3, 0x90, 0x0, - 0x3, 0x80, 0x0, 0x1, 0x30, 0x0, 0x0, - - /* U+30EB "ル" */ - 0x0, 0x0, 0x5, 0x0, 0x0, 0x0, 0x0, 0x20, - 0xe, 0x10, 0x0, 0x0, 0x0, 0xd2, 0xc, 0x0, - 0x0, 0x0, 0x0, 0xc0, 0xb, 0x0, 0x0, 0x50, - 0x0, 0xc0, 0xb, 0x0, 0x6, 0x30, 0x0, 0xc0, - 0xb, 0x0, 0x76, 0x0, 0x2, 0x80, 0xb, 0x1a, - 0x60, 0x0, 0x9, 0x10, 0xd, 0xd3, 0x0, 0x0, - 0x32, 0x0, 0x3, 0x10, 0x0, 0x0, - - /* U+30EC "レ" */ - 0x24, 0x0, 0x0, 0x0, 0x2f, 0x0, 0x0, 0x0, - 0xd, 0x0, 0x0, 0x0, 0xb, 0x0, 0x0, 0x0, - 0xb, 0x0, 0x0, 0x62, 0xb, 0x0, 0x59, 0x10, - 0xb, 0x3b, 0x60, 0x0, 0x1f, 0xb1, 0x0, 0x0, - 0x2, 0x0, 0x0, 0x0, - - /* U+30ED "ロ" */ - 0x0, 0x0, 0x24, 0x69, 0x20, 0xf9, 0x97, 0x53, - 0xa9, 0xc, 0x0, 0x0, 0xb, 0x20, 0xb0, 0x0, - 0x0, 0xb0, 0xa, 0x10, 0x0, 0x19, 0x0, 0x91, - 0x0, 0x6, 0x60, 0xa, 0xaa, 0x99, 0x96, 0x0, - 0x40, 0x0, 0x0, 0x0, - - /* U+30EF "ワ" */ - 0x0, 0x0, 0x0, 0x0, 0x0, 0x17, 0x56, 0x79, - 0xab, 0xe2, 0xd, 0x43, 0x20, 0x0, 0xd2, 0xc, - 0x0, 0x0, 0x5, 0x80, 0xd, 0x0, 0x0, 0xc, - 0x10, 0x9, 0x0, 0x0, 0x76, 0x0, 0x0, 0x0, - 0x2, 0xa0, 0x0, 0x0, 0x0, 0x1a, 0x0, 0x0, - 0x0, 0x1, 0x90, 0x0, 0x0, 0x0, 0x27, 0x0, - 0x0, 0x0, 0x0, 0x20, 0x0, 0x0, 0x0, - - /* U+30F3 "ン" */ - 0x15, 0x0, 0x0, 0x0, 0x0, 0x2, 0xc4, 0x0, - 0x0, 0x2, 0x0, 0x3a, 0x0, 0x0, 0x53, 0x0, - 0x0, 0x0, 0x6, 0x60, 0x0, 0x0, 0x0, 0x66, - 0x0, 0x0, 0x0, 0x9, 0x50, 0x0, 0x0, 0x3, - 0xb3, 0x0, 0x0, 0x6, 0xa9, 0x10, 0x0, 0x0, - 0x6, 0x30, 0x0, 0x0, 0x0, - - /* U+30F6 "ヶ" */ - 0x0, 0x82, 0x0, 0x0, 0x0, 0xc1, 0x2, 0x50, - 0x8, 0xa9, 0xd7, 0x51, 0x35, 0x0, 0xc2, 0x0, - 0x0, 0x2, 0x90, 0x0, 0x0, 0x9, 0x10, 0x0, - 0x0, 0x45, 0x0, 0x0, 0x0, 0x30, 0x0, 0x0, - - /* U+30FC "ー" */ - 0x2, 0x10, 0x0, 0x1, 0x24, 0x69, 0x40, 0x8, - 0xff, 0xcb, 0xa9, 0x87, 0x77, 0x80, 0x0, 0x0, - 0x0, 0x0, 0x0, 0x0, 0x0, - - /* U+4E00 "一" */ - 0x0, 0x0, 0x0, 0x0, 0x0, 0x4, 0x30, 0x6, - 0x55, 0x55, 0x55, 0x55, 0x58, 0x70, - - /* U+4E03 "七" */ - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, 0xd1, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0xd0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0xd0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xd0, - 0x0, 0x7, 0x90, 0x0, 0x0, 0x0, 0xd3, 0x55, - 0x51, 0x0, 0x0, 0x3, 0x55, 0xd1, 0x0, 0x0, - 0x0, 0x7, 0x51, 0x0, 0xd0, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x0, 0xd0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, 0xd0, 0x0, 0x0, 0x50, 0x0, 0x0, - 0x0, 0xd0, 0x0, 0x0, 0x80, 0x0, 0x0, 0x0, - 0xd1, 0x0, 0x0, 0xd2, 0x0, 0x0, 0x0, 0x5b, - 0xbb, 0xbb, 0xa2, - - /* U+4E07 "万" */ - 0x0, 0x0, 0x0, 0x0, 0x0, 0x4, 0x10, 0x75, - 0x55, 0xa7, 0x55, 0x55, 0x85, 0x0, 0x0, 0xc, - 0x30, 0x0, 0x0, 0x0, 0x0, 0x0, 0xd2, 0x0, - 0x1, 0x0, 0x0, 0x0, 0xf, 0x55, 0x55, 0xb8, - 0x0, 0x0, 0x2, 0xc0, 0x0, 0x9, 0x40, 0x0, - 0x0, 0x68, 0x0, 0x0, 0xa3, 0x0, 0x0, 0xb, - 0x30, 0x0, 0xb, 0x20, 0x0, 0x2, 0xa0, 0x0, - 0x0, 0xd1, 0x0, 0x0, 0xa2, 0x0, 0x0, 0xe, - 0x0, 0x0, 0x73, 0x0, 0x5, 0x78, 0xc0, 0x0, - 0x43, 0x0, 0x0, 0x6, 0xb2, 0x0, 0x10, 0x0, - 0x0, 0x0, 0x0, 0x0, 0x0, - - /* U+4E08 "丈" */ - 0x0, 0x0, 0x0, 0x3, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, 0xa, 0x50, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x9, 0x30, 0x1, 0x0, 0x5, 0x65, 0x55, - 0x5b, 0x75, 0x5a, 0xa0, 0x0, 0x1, 0x0, 0xa, - 0x20, 0x0, 0x0, 0x0, 0x5, 0x0, 0xb, 0x10, - 0x0, 0x0, 0x0, 0x0, 0x60, 0xd, 0x0, 0x0, - 0x0, 0x0, 0x0, 0x73, 0xd, 0x0, 0x0, 0x0, - 0x0, 0x0, 0xb, 0x59, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x3, 0xf6, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x6, 0xbe, 0x70, 0x0, 0x0, 0x0, 0x0, 0x88, - 0x1, 0xbe, 0x95, 0x30, 0x0, 0x58, 0x30, 0x0, - 0x3, 0xaf, 0x50, 0x3, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, - - /* U+4E09 "三" */ - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x1, - 0x65, 0x55, 0x55, 0x55, 0x6d, 0x30, 0x0, 0x0, - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x1, - 0x90, 0x0, 0x0, 0x26, 0x55, 0x55, 0x55, 0x52, - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x0, 0x0, 0x0, 0x10, 0x16, 0x55, - 0x55, 0x55, 0x55, 0x58, 0xd1, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x0, 0x0, - - /* U+4E0A "上" */ - 0x0, 0x0, 0x0, 0x10, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, 0xe2, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0xd0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0xd0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xd0, - 0x0, 0x10, 0x0, 0x0, 0x0, 0x0, 0xd5, 0x55, - 0xa8, 0x0, 0x0, 0x0, 0x0, 0xd0, 0x0, 0x0, - 0x0, 0x0, 0x0, 0x0, 0xd0, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x0, 0xd0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, 0xd0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0xd0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0xd0, 0x0, 0x3, 0x80, 0x7, 0x55, 0x55, 0x55, - 0x55, 0x55, 0x51, - - /* U+4E0B "下" */ - 0x0, 0x0, 0x0, 0x0, 0x0, 0x7, 0x30, 0x65, - 0x55, 0x5d, 0x55, 0x55, 0x54, 0x0, 0x0, 0x0, - 0xd0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xd, 0x0, - 0x0, 0x0, 0x0, 0x0, 0x0, 0xd6, 0x50, 0x0, - 0x0, 0x0, 0x0, 0xd, 0x5, 0xd7, 0x0, 0x0, - 0x0, 0x0, 0xd0, 0x2, 0xe2, 0x0, 0x0, 0x0, - 0xd, 0x0, 0x3, 0x0, 0x0, 0x0, 0x0, 0xd0, - 0x0, 0x0, 0x0, 0x0, 0x0, 0xd, 0x0, 0x0, - 0x0, 0x0, 0x0, 0x0, 0xd0, 0x0, 0x0, 0x0, - 0x0, 0x0, 0xd, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x20, 0x0, 0x0, 0x0, - - /* U+4E0D "不" */ - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x6, - 0x55, 0x55, 0x56, 0x55, 0x5b, 0x80, 0x0, 0x0, - 0x0, 0x88, 0x0, 0x0, 0x0, 0x0, 0x0, 0x1, - 0xe1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8, 0xe4, - 0x0, 0x0, 0x0, 0x0, 0x0, 0x3c, 0xa2, 0x25, - 0x0, 0x0, 0x0, 0x1, 0xc2, 0xa2, 0x2, 0xa1, - 0x0, 0x0, 0xb, 0x20, 0xa2, 0x0, 0x3d, 0x30, - 0x0, 0x92, 0x0, 0xa2, 0x0, 0x6, 0xc0, 0x16, - 0x0, 0x0, 0xa2, 0x0, 0x0, 0x40, 0x0, 0x0, - 0x0, 0xa2, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0xa2, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xa2, - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, - - /* U+4E13 "专" */ - 0x0, 0x0, 0x0, 0x30, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x1, 0xd0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x3, 0x90, 0x0, 0x70, 0x0, 0x0, 0x55, 0x59, - 0x95, 0x55, 0x52, 0x0, 0x0, 0x0, 0x8, 0x30, - 0x0, 0x0, 0x0, 0x15, 0x55, 0x5d, 0x65, 0x55, - 0x58, 0xb0, 0x1, 0x0, 0xc, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x0, 0x49, 0x0, 0x0, 0x30, 0x0, - 0x0, 0x0, 0x57, 0x55, 0x57, 0xf2, 0x0, 0x0, - 0x0, 0x0, 0x0, 0xa, 0x20, 0x0, 0x0, 0x0, - 0x16, 0x30, 0x71, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x6c, 0x80, 0x0, 0x0, 0x0, 0x0, 0x0, 0x1, - 0xc5, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x1, - 0x0, 0x0, - - /* U+4E14 "且" */ - 0x0, 0x0, 0x95, 0x55, 0x55, 0xb0, 0x0, 0x0, - 0x0, 0xd0, 0x0, 0x0, 0xc0, 0x0, 0x0, 0x0, - 0xd0, 0x0, 0x0, 0xc0, 0x0, 0x0, 0x0, 0xd0, - 0x0, 0x0, 0xc0, 0x0, 0x0, 0x0, 0xd5, 0x55, - 0x55, 0xc0, 0x0, 0x0, 0x0, 0xd0, 0x0, 0x0, - 0xc0, 0x0, 0x0, 0x0, 0xd0, 0x0, 0x0, 0xc0, - 0x0, 0x0, 0x0, 0xd5, 0x55, 0x55, 0xc0, 0x0, - 0x0, 0x0, 0xd0, 0x0, 0x0, 0xc0, 0x0, 0x0, - 0x0, 0xd0, 0x0, 0x0, 0xc0, 0x0, 0x0, 0x0, - 0xd0, 0x0, 0x0, 0xc0, 0x80, 0x6, 0x55, 0x75, - 0x55, 0x55, 0x76, 0x74, - - /* U+4E16 "世" */ - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, 0xc1, 0x0, 0xd1, 0x0, 0x0, 0x2c, - 0x0, 0xc0, 0x0, 0xc0, 0x0, 0x0, 0x1a, 0x0, - 0xc0, 0x0, 0xc0, 0x0, 0x0, 0x1a, 0x0, 0xc0, - 0x0, 0xc0, 0x91, 0x6, 0x6c, 0x55, 0xd5, 0x55, - 0xd5, 0x52, 0x0, 0x1a, 0x0, 0xc0, 0x0, 0xc0, - 0x0, 0x0, 0x1a, 0x0, 0xc0, 0x0, 0xc0, 0x0, - 0x0, 0x1a, 0x0, 0xc0, 0x0, 0xc0, 0x0, 0x0, - 0x1a, 0x0, 0xc5, 0x55, 0xc0, 0x0, 0x0, 0x1a, - 0x0, 0x90, 0x0, 0x70, 0x0, 0x0, 0x1a, 0x0, - 0x0, 0x0, 0x0, 0x50, 0x0, 0x3b, 0x55, 0x55, - 0x55, 0x56, 0x93, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, - - /* U+4E21 "両" */ - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x10, 0x6, - 0x55, 0x55, 0x57, 0x55, 0x59, 0x90, 0x0, 0x0, - 0x0, 0x29, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x29, 0x0, 0x1, 0x0, 0x0, 0xc5, 0x55, 0x6b, - 0x55, 0x5c, 0x30, 0x0, 0xb0, 0x0, 0x29, 0x1, - 0xa, 0x10, 0x0, 0xb0, 0xb1, 0x29, 0xd, 0xa, - 0x10, 0x0, 0xb0, 0xb0, 0x29, 0xc, 0xa, 0x10, - 0x0, 0xb0, 0xb0, 0x29, 0xc, 0xa, 0x10, 0x0, - 0xb0, 0xc5, 0x6a, 0x5d, 0xa, 0x10, 0x0, 0xb0, - 0x20, 0x0, 0x5, 0xa, 0x10, 0x0, 0xb0, 0x0, - 0x0, 0x3, 0x2c, 0x0, 0x0, 0xa0, 0x0, 0x0, - 0x2, 0xab, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, - - /* U+4E26 "並" */ - 0x0, 0x0, 0x0, 0x0, 0x0, 0x10, 0x0, 0x0, - 0x1, 0x81, 0x0, 0x5, 0xc0, 0x0, 0x0, 0x0, - 0x3d, 0x0, 0xa, 0x10, 0x0, 0x0, 0x0, 0xc, - 0x10, 0x42, 0x7, 0x0, 0x2, 0x65, 0x5d, 0x55, - 0xd5, 0x55, 0x20, 0x0, 0x20, 0xc, 0x0, 0xc0, - 0x4, 0x10, 0x0, 0x70, 0xc, 0x0, 0xc0, 0xd, - 0x50, 0x0, 0x56, 0xc, 0x0, 0xc0, 0x67, 0x0, - 0x0, 0x1d, 0xc, 0x0, 0xc0, 0xa0, 0x0, 0x0, - 0xd, 0xc, 0x0, 0xc6, 0x10, 0x0, 0x0, 0x3, - 0xc, 0x0, 0xc2, 0x0, 0x0, 0x0, 0x0, 0xc, - 0x0, 0xc0, 0x3, 0x40, 0x6, 0x55, 0x57, 0x55, - 0x75, 0x57, 0x80, - - /* U+4E2D "中" */ - 0x0, 0x0, 0x41, 0x0, 0x0, 0x0, 0x0, 0xa, - 0x50, 0x0, 0x0, 0x0, 0x0, 0xa3, 0x0, 0x0, - 0x8, 0x55, 0x5b, 0x75, 0x55, 0xa2, 0xc0, 0x0, - 0xa3, 0x0, 0xc, 0xc, 0x0, 0xa, 0x30, 0x0, - 0xc0, 0xc0, 0x0, 0xa3, 0x0, 0xc, 0xd, 0x55, - 0x5b, 0x75, 0x55, 0xd0, 0xb0, 0x0, 0xa3, 0x0, - 0xa, 0x0, 0x0, 0xa, 0x30, 0x0, 0x0, 0x0, - 0x0, 0xa3, 0x0, 0x0, 0x0, 0x0, 0xa, 0x30, - 0x0, 0x0, 0x0, 0x0, 0xa3, 0x0, 0x0, 0x0, - 0x0, 0x2, 0x0, 0x0, 0x0, - - /* U+4E3B "主" */ - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x4, 0x70, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x99, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x15, 0x0, 0x18, 0x0, 0x3, 0x65, 0x55, 0xc7, - 0x55, 0x55, 0x10, 0x0, 0x0, 0x0, 0xa2, 0x0, - 0x0, 0x0, 0x0, 0x0, 0x0, 0xa2, 0x0, 0x0, - 0x0, 0x0, 0x0, 0x0, 0xa3, 0x11, 0x90, 0x0, - 0x0, 0x46, 0x55, 0xc6, 0x44, 0x41, 0x0, 0x0, - 0x0, 0x0, 0xa2, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0xa2, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0xa2, 0x0, 0x5, 0x10, 0x26, 0x55, 0x55, 0x75, - 0x55, 0x58, 0x60, - - /* U+4E45 "久" */ - 0x0, 0x0, 0x2, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0xc, 0x50, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x1c, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x89, - 0x55, 0xb1, 0x0, 0x0, 0x0, 0x0, 0xb0, 0x4, - 0xb0, 0x0, 0x0, 0x0, 0x7, 0x20, 0xa, 0x50, - 0x0, 0x0, 0x0, 0x36, 0x0, 0x1d, 0x50, 0x0, - 0x0, 0x1, 0x50, 0x0, 0x94, 0x70, 0x0, 0x0, - 0x0, 0x0, 0x3, 0xb0, 0x45, 0x0, 0x0, 0x0, - 0x0, 0x1b, 0x10, 0xb, 0x10, 0x0, 0x0, 0x0, - 0xb2, 0x0, 0x4, 0xc1, 0x0, 0x0, 0x28, 0x10, - 0x0, 0x0, 0x8d, 0x50, 0x5, 0x60, 0x0, 0x0, - 0x0, 0x8, 0x71, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, - - /* U+4E4B "之" */ - 0x0, 0x0, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x5, 0x90, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0xb3, 0x0, 0x0, 0x0, 0x3, 0x55, 0x55, - 0x65, 0x59, 0x50, 0x0, 0x0, 0x10, 0x0, 0x0, - 0x3d, 0x40, 0x0, 0x0, 0x0, 0x0, 0x2, 0xc1, - 0x0, 0x0, 0x0, 0x0, 0x0, 0x1c, 0x20, 0x0, - 0x0, 0x0, 0x0, 0x1, 0xb1, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x1a, 0x10, 0x0, 0x0, 0x0, 0x0, - 0x2, 0xa1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x6c, - 0x20, 0x0, 0x0, 0x0, 0x0, 0x1d, 0x70, 0x87, - 0x31, 0x0, 0x2, 0x31, 0x4, 0x0, 0x4, 0xad, - 0xef, 0xff, 0x70, - - /* U+4E4E "乎" */ - 0x0, 0x0, 0x0, 0x0, 0x0, 0x12, 0x0, 0x0, - 0x0, 0x0, 0x14, 0x7b, 0xd8, 0x0, 0x0, 0x45, - 0x67, 0x8b, 0x20, 0x0, 0x0, 0x0, 0x4, 0x0, - 0x2a, 0x0, 0xa5, 0x0, 0x0, 0x4, 0x90, 0x2a, - 0x1, 0xa0, 0x0, 0x0, 0x0, 0xc2, 0x2a, 0x7, - 0x10, 0x0, 0x0, 0x0, 0x20, 0x2a, 0x2, 0x1, - 0x80, 0x6, 0x55, 0x55, 0x6c, 0x55, 0x55, 0x52, - 0x0, 0x0, 0x0, 0x2a, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x2a, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x2a, 0x0, 0x0, 0x0, 0x0, 0x0, 0x22, - 0x4a, 0x0, 0x0, 0x0, 0x0, 0x0, 0x6, 0xf6, - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x20, 0x0, - 0x0, 0x0, - - /* U+4E4F "乏" */ - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x48, 0xd5, 0x0, 0x15, 0x56, 0x78, - 0x86, 0x53, 0x20, 0x0, 0x0, 0x3, 0x91, 0x0, - 0x0, 0x0, 0x0, 0x0, 0x7, 0x80, 0x0, 0x0, - 0x0, 0x45, 0x55, 0x56, 0x55, 0xb0, 0x0, 0x1, - 0x0, 0x0, 0x2, 0xb5, 0x0, 0x0, 0x0, 0x0, - 0x4, 0xa1, 0x0, 0x0, 0x0, 0x0, 0x8, 0x60, - 0x0, 0x0, 0x0, 0x0, 0x58, 0x10, 0x0, 0x0, - 0x0, 0x2, 0xa6, 0x0, 0x0, 0x0, 0x0, 0x6, - 0xb0, 0x68, 0x41, 0x0, 0x1, 0x21, 0x21, 0x0, - 0x17, 0xbd, 0xef, 0xf8, 0x0, - - /* U+4E57 "乗" */ - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x12, 0x46, 0x8b, 0xe8, 0x0, 0x0, 0x44, - 0x33, 0xa4, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x92, 0x0, 0x43, 0x0, 0x0, 0x65, 0x85, 0xb7, - 0x59, 0x54, 0x0, 0x0, 0x0, 0xc0, 0x92, 0xc, - 0x4, 0x0, 0x6, 0x55, 0xd5, 0xb7, 0x5d, 0x56, - 0x30, 0x0, 0x0, 0xc0, 0x92, 0xc, 0x12, 0x0, - 0x0, 0x65, 0x79, 0xe9, 0x57, 0x66, 0x0, 0x0, - 0x0, 0x1b, 0x94, 0x70, 0x0, 0x0, 0x0, 0x1, - 0xa1, 0x92, 0x58, 0x0, 0x0, 0x0, 0x38, 0x10, - 0x92, 0x6, 0xc5, 0x0, 0x5, 0x40, 0x0, 0x93, - 0x0, 0x4d, 0x80, 0x0, 0x0, 0x0, 0x10, 0x0, - 0x0, 0x0, - - /* U+4E5D "九" */ - 0x0, 0x0, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0xd, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0xc, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xc, - 0x0, 0x10, 0x0, 0x0, 0x1, 0x65, 0x5d, 0x55, - 0xb5, 0x0, 0x0, 0x0, 0x0, 0x1a, 0x0, 0xa1, - 0x0, 0x0, 0x0, 0x0, 0x38, 0x0, 0xa1, 0x0, - 0x0, 0x0, 0x0, 0x64, 0x0, 0xa1, 0x0, 0x0, - 0x0, 0x0, 0xa0, 0x0, 0xa1, 0x0, 0x0, 0x0, - 0x2, 0x90, 0x0, 0xa1, 0x0, 0x10, 0x0, 0x9, - 0x10, 0x0, 0xa2, 0x0, 0x60, 0x0, 0x63, 0x0, - 0x0, 0x92, 0x0, 0x90, 0x4, 0x30, 0x0, 0x0, - 0x6c, 0xaa, 0xd1, 0x1, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, - - /* U+4E5F "也" */ - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x94, 0x0, 0x0, 0x0, 0x0, 0x2, - 0x0, 0x92, 0x0, 0x0, 0x0, 0x0, 0xd, 0x0, - 0x92, 0x0, 0x3a, 0x0, 0x0, 0xc, 0x0, 0x95, - 0x66, 0x69, 0x0, 0x0, 0xc, 0x16, 0xc5, 0x0, - 0x39, 0x0, 0x2, 0x5d, 0x40, 0x92, 0x0, 0x47, - 0x0, 0x4, 0xc, 0x0, 0x92, 0x0, 0x66, 0x0, - 0x0, 0xc, 0x0, 0x93, 0x57, 0xd2, 0x0, 0x0, - 0xc, 0x0, 0x93, 0x7, 0x60, 0x20, 0x0, 0xc, - 0x0, 0x71, 0x0, 0x0, 0x60, 0x0, 0xc, 0x0, - 0x0, 0x0, 0x0, 0xa0, 0x0, 0xa, 0xba, 0xaa, - 0xaa, 0xac, 0xd1, - - /* U+4E86 "了" */ - 0x0, 0x0, 0x0, 0x0, 0x0, 0x5, 0x55, 0x55, - 0x55, 0x57, 0xc0, 0x0, 0x0, 0x0, 0x3, 0xb5, - 0x0, 0x0, 0x0, 0x4, 0x60, 0x0, 0x0, 0x0, - 0x29, 0x30, 0x0, 0x0, 0x0, 0x2, 0xb0, 0x0, - 0x0, 0x0, 0x0, 0x2a, 0x0, 0x0, 0x0, 0x0, - 0x2, 0xa0, 0x0, 0x0, 0x0, 0x0, 0x2a, 0x0, - 0x0, 0x0, 0x0, 0x2, 0xa0, 0x0, 0x0, 0x0, - 0x0, 0x2a, 0x0, 0x0, 0x0, 0x2, 0x15, 0xa0, - 0x0, 0x0, 0x0, 0x17, 0xf6, 0x0, 0x0, 0x0, - 0x0, 0x2, 0x0, 0x0, 0x0, - - /* U+4E88 "予" */ - 0x0, 0x55, 0x55, 0x55, 0x5b, 0x10, 0x0, 0x1, - 0x0, 0x0, 0x1a, 0x82, 0x0, 0x0, 0x0, 0x54, - 0x27, 0x10, 0x0, 0x0, 0x0, 0x0, 0x7d, 0x10, - 0x0, 0x0, 0x0, 0x0, 0x0, 0xb4, 0x0, 0x15, - 0x4, 0x65, 0x55, 0x5e, 0x55, 0x5b, 0xc0, 0x0, - 0x0, 0x0, 0xd0, 0x3, 0x70, 0x0, 0x0, 0x0, - 0xd, 0x0, 0x20, 0x0, 0x0, 0x0, 0x0, 0xd0, - 0x0, 0x0, 0x0, 0x0, 0x0, 0xd, 0x0, 0x0, - 0x0, 0x0, 0x0, 0x0, 0xd0, 0x0, 0x0, 0x0, - 0x0, 0x17, 0xea, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x2, 0x0, 0x0, 0x0, 0x0, - - /* U+4E89 "争" */ - 0x0, 0x0, 0x13, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x99, 0x0, 0x50, 0x0, 0x0, 0x0, 0x5, - 0xa5, 0x57, 0xd2, 0x0, 0x0, 0x0, 0x28, 0x0, - 0x8, 0x0, 0x0, 0x0, 0x2, 0x66, 0x55, 0x96, - 0x55, 0xd1, 0x0, 0x2, 0x0, 0x0, 0xa1, 0x0, - 0xb0, 0x0, 0x15, 0x55, 0x55, 0xc6, 0x55, 0xc8, - 0xa0, 0x1, 0x0, 0x0, 0xa1, 0x0, 0xb0, 0x0, - 0x0, 0x0, 0x0, 0xa1, 0x0, 0xb0, 0x0, 0x0, - 0x55, 0x55, 0xc6, 0x55, 0xa0, 0x0, 0x0, 0x0, - 0x0, 0xa1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0xb1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x5b, 0xe0, - 0x0, 0x0, 0x0, 0x0, 0x0, 0x1, 0x20, 0x0, - 0x0, 0x0, - - /* U+4E8B "事" */ - 0x0, 0x0, 0x0, 0x12, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x2b, 0x0, 0x4, 0x20, 0x5, 0x55, - 0x55, 0x6b, 0x55, 0x57, 0x60, 0x0, 0x7, 0x55, - 0x6b, 0x55, 0x92, 0x0, 0x0, 0xb, 0x0, 0x29, - 0x0, 0xc0, 0x0, 0x0, 0xc, 0x55, 0x6b, 0x55, - 0xd0, 0x0, 0x0, 0x3, 0x0, 0x29, 0x0, 0x50, - 0x0, 0x0, 0x36, 0x55, 0x6b, 0x55, 0xd2, 0x0, - 0x16, 0x55, 0x55, 0x6b, 0x55, 0xd7, 0xb0, 0x0, - 0x0, 0x0, 0x29, 0x0, 0xc0, 0x0, 0x0, 0x36, - 0x55, 0x6b, 0x55, 0xd0, 0x0, 0x0, 0x0, 0x0, - 0x39, 0x0, 0x20, 0x0, 0x0, 0x0, 0x17, 0xf7, - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x20, 0x0, - 0x0, 0x0, - - /* U+4E8C "二" */ - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x46, 0x55, 0x55, 0x55, 0x98, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x0, 0x0, 0x0, 0x7, 0x50, 0x6, - 0x55, 0x55, 0x55, 0x55, 0x56, 0x60, - - /* U+4E94 "五" */ - 0x0, 0x0, 0x0, 0x0, 0x0, 0x7, 0x10, 0x0, - 0x65, 0x55, 0xc6, 0x55, 0x55, 0x30, 0x0, 0x0, - 0x0, 0xc0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0xc0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x1, 0xa0, - 0x0, 0x30, 0x0, 0x0, 0x36, 0x58, 0xa5, 0x55, - 0xd0, 0x0, 0x0, 0x0, 0x6, 0x50, 0x1, 0xa0, - 0x0, 0x0, 0x0, 0x9, 0x30, 0x2, 0xa0, 0x0, - 0x0, 0x0, 0xb, 0x0, 0x2, 0x90, 0x0, 0x0, - 0x0, 0xc, 0x0, 0x3, 0x90, 0x0, 0x0, 0x0, - 0xb, 0x0, 0x3, 0x80, 0x70, 0x5, 0x55, 0x56, - 0x55, 0x55, 0x66, 0x72, - - /* U+4E9B "些" */ - 0x0, 0x0, 0x92, 0x0, 0xa0, 0x0, 0x0, 0x0, - 0x0, 0xb0, 0x0, 0xb0, 0x2, 0x0, 0x0, 0xc0, - 0xb0, 0x50, 0xb0, 0x3c, 0x40, 0x0, 0xb0, 0xb5, - 0x52, 0xb5, 0x50, 0x0, 0x0, 0xb0, 0xb0, 0x0, - 0xb0, 0x0, 0x50, 0x0, 0xb0, 0xb0, 0x1, 0xb0, - 0x0, 0x90, 0x5, 0xd9, 0xa6, 0x41, 0x9a, 0x99, - 0xc2, 0x8, 0x40, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x15, 0x55, 0x55, 0x56, 0xd3, 0x0, 0x0, - 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x0, 0x6, 0x60, 0x6, 0x55, 0x55, - 0x55, 0x55, 0x56, 0x60, - - /* U+4EA1 "亡" */ - 0x0, 0x0, 0x0, 0x10, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, 0xa4, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x2f, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x5, 0x0, 0x4, 0x80, 0x16, 0x5d, 0x55, 0x55, - 0x55, 0x55, 0x51, 0x0, 0xd, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x0, 0xd, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, 0xd, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0xd, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0xd, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xd, - 0x0, 0x0, 0x0, 0x1, 0x0, 0x0, 0xe, 0x55, - 0x55, 0x55, 0x7d, 0x20, 0x0, 0x2, 0x0, 0x0, - 0x0, 0x0, 0x0, - - /* U+4EA4 "交" */ - 0x0, 0x0, 0x1, 0x10, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, 0xb5, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x37, 0x0, 0x6, 0x50, 0x6, 0x55, 0x65, - 0x55, 0x65, 0x55, 0x50, 0x0, 0x0, 0xc4, 0x0, - 0x18, 0x30, 0x0, 0x0, 0xa, 0x40, 0x0, 0x10, - 0xb9, 0x0, 0x1, 0x81, 0x31, 0x0, 0x88, 0xc, - 0x0, 0x3, 0x0, 0x6, 0x0, 0xd1, 0x0, 0x0, - 0x0, 0x0, 0x6, 0x26, 0x70, 0x0, 0x0, 0x0, - 0x0, 0x0, 0xab, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x2, 0xba, 0x0, 0x0, 0x0, 0x0, 0x0, 0x69, - 0x13, 0xc7, 0x20, 0x0, 0x1, 0x57, 0x20, 0x0, - 0x6, 0xcf, 0xc1, 0x3, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x10, - - /* U+4EA6 "亦" */ - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0xb, 0x30, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x58, 0x0, 0x8, 0x20, 0x65, 0x55, 0xd5, 0x5d, - 0x55, 0x54, 0x0, 0x0, 0xc, 0x0, 0xc0, 0x0, - 0x0, 0x3, 0xa0, 0xc0, 0xc, 0x12, 0x0, 0x0, - 0x76, 0xc, 0x0, 0xc0, 0x82, 0x0, 0xb, 0x0, - 0xb0, 0xc, 0x1, 0xd1, 0x3, 0x50, 0x39, 0x0, - 0xc0, 0x8, 0x90, 0x60, 0x9, 0x20, 0xc, 0x0, - 0x27, 0x0, 0x2, 0x90, 0x0, 0xc0, 0x0, 0x0, - 0x1, 0x90, 0x4, 0x4e, 0x0, 0x0, 0x3, 0x50, - 0x0, 0x1a, 0x90, 0x0, 0x0, 0x10, 0x0, 0x0, - 0x0, 0x0, 0x0, - - /* U+4EAC "京" */ - 0x0, 0x0, 0x2, 0x10, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, 0xc2, 0x0, 0x0, 0x0, 0x5, 0x55, - 0x55, 0x96, 0x55, 0x5a, 0xc0, 0x1, 0x0, 0x0, - 0x0, 0x0, 0x0, 0x0, 0x0, 0x7, 0x55, 0x55, - 0x55, 0xa0, 0x0, 0x0, 0xd, 0x0, 0x0, 0x2, - 0xb0, 0x0, 0x0, 0xd, 0x0, 0x0, 0x2, 0xa0, - 0x0, 0x0, 0xd, 0x55, 0x55, 0x56, 0xb0, 0x0, - 0x0, 0x8, 0x0, 0xd0, 0x1, 0x30, 0x0, 0x0, - 0x3, 0xa0, 0xd0, 0x6, 0x0, 0x0, 0x0, 0x1b, - 0x20, 0xd0, 0x1, 0xb2, 0x0, 0x1, 0x91, 0x0, - 0xd0, 0x0, 0x3e, 0x0, 0x15, 0x0, 0x4c, 0xd0, - 0x0, 0x7, 0x0, 0x0, 0x0, 0x1, 0x10, 0x0, - 0x0, 0x0, - - /* U+4EBA "人" */ - 0x0, 0x0, 0x0, 0x10, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, 0xf5, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0xf4, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0xf6, 0x0, 0x0, 0x0, 0x0, 0x0, 0x2, 0xd6, - 0x0, 0x0, 0x0, 0x0, 0x0, 0x4, 0xb8, 0x0, - 0x0, 0x0, 0x0, 0x0, 0x7, 0x76, 0x30, 0x0, - 0x0, 0x0, 0x0, 0xb, 0x31, 0x90, 0x0, 0x0, - 0x0, 0x0, 0x2c, 0x0, 0xa2, 0x0, 0x0, 0x0, - 0x0, 0xa4, 0x0, 0x2c, 0x0, 0x0, 0x0, 0x5, - 0x80, 0x0, 0x8, 0xb0, 0x0, 0x0, 0x57, 0x0, - 0x0, 0x0, 0xbd, 0x61, 0x5, 0x40, 0x0, 0x0, - 0x0, 0x9, 0x71, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, - - /* U+4EC0 "什" */ - 0x0, 0x0, 0x20, 0x0, 0x30, 0x0, 0x0, 0x0, - 0x4, 0xd0, 0x0, 0xc2, 0x0, 0x0, 0x0, 0x9, - 0x50, 0x0, 0xc0, 0x0, 0x0, 0x0, 0xd, 0x0, - 0x0, 0xc0, 0x0, 0x0, 0x0, 0x6c, 0x0, 0x0, - 0xc0, 0x0, 0x10, 0x0, 0xac, 0x36, 0x55, 0xd5, - 0x58, 0x90, 0x5, 0x3c, 0x0, 0x0, 0xc0, 0x0, - 0x0, 0x15, 0xc, 0x0, 0x0, 0xc0, 0x0, 0x0, - 0x10, 0xc, 0x0, 0x0, 0xc0, 0x0, 0x0, 0x0, - 0xc, 0x0, 0x0, 0xc0, 0x0, 0x0, 0x0, 0xc, - 0x0, 0x0, 0xc0, 0x0, 0x0, 0x0, 0xc, 0x0, - 0x0, 0xc0, 0x0, 0x0, 0x0, 0xd, 0x0, 0x0, - 0xc0, 0x0, 0x0, 0x0, 0x2, 0x0, 0x0, 0x20, - 0x0, 0x0, - - /* U+4ECA "今" */ - 0x0, 0x0, 0x0, 0x30, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, 0xe5, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x8, 0x76, 0x0, 0x0, 0x0, 0x0, 0x0, 0x3c, - 0x0, 0x90, 0x0, 0x0, 0x0, 0x1, 0xc2, 0x0, - 0x3b, 0x10, 0x0, 0x0, 0x1a, 0x11, 0x92, 0x3, - 0xd7, 0x10, 0x2, 0x81, 0x0, 0x3b, 0x0, 0x1b, - 0xd2, 0x14, 0x0, 0x0, 0x1, 0x0, 0x20, 0x0, - 0x0, 0x16, 0x55, 0x55, 0x58, 0xd0, 0x0, 0x0, - 0x0, 0x0, 0x0, 0xc, 0x20, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x86, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x3, 0xa0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xc, - 0x10, 0x0, 0x0, 0x0, 0x0, 0x0, 0x13, 0x0, - 0x0, 0x0, - - /* U+4ECB "介" */ - 0x0, 0x0, 0x0, 0x40, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, 0xe6, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x6, 0x86, 0x10, 0x0, 0x0, 0x0, 0x0, 0x1c, - 0x0, 0x90, 0x0, 0x0, 0x0, 0x0, 0xa3, 0x0, - 0x2b, 0x10, 0x0, 0x0, 0x8, 0x42, 0x0, 0x44, - 0xd8, 0x20, 0x1, 0x71, 0x2c, 0x0, 0xa4, 0x1a, - 0x80, 0x3, 0x0, 0x29, 0x0, 0xa2, 0x0, 0x0, - 0x0, 0x0, 0x39, 0x0, 0xa2, 0x0, 0x0, 0x0, - 0x0, 0x56, 0x0, 0xa2, 0x0, 0x0, 0x0, 0x0, - 0xb1, 0x0, 0xa2, 0x0, 0x0, 0x0, 0x6, 0x60, - 0x0, 0xa2, 0x0, 0x0, 0x0, 0x65, 0x0, 0x0, - 0xa2, 0x0, 0x0, 0x2, 0x0, 0x0, 0x0, 0x30, - 0x0, 0x0, - - /* U+4ECD "仍" */ - 0x0, 0x1, 0x10, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x5, 0xb0, 0x0, 0x0, 0x13, 0x0, 0x0, 0xa, - 0x25, 0x6d, 0x55, 0x99, 0x0, 0x0, 0x1a, 0x0, - 0xc, 0x0, 0x84, 0x0, 0x0, 0x7c, 0x0, 0xb, - 0x0, 0xb0, 0x0, 0x0, 0x8c, 0x0, 0x1a, 0x0, - 0xc0, 0x40, 0x6, 0x1c, 0x0, 0x29, 0x2, 0x85, - 0xd1, 0x12, 0xc, 0x0, 0x47, 0x0, 0x0, 0xc0, - 0x0, 0xc, 0x0, 0x74, 0x0, 0x1, 0xb0, 0x0, - 0xc, 0x0, 0xb0, 0x0, 0x3, 0x90, 0x0, 0xc, - 0x3, 0x80, 0x0, 0x6, 0x70, 0x0, 0xc, 0x9, - 0x0, 0x4, 0x3c, 0x30, 0x0, 0xd, 0x62, 0x0, - 0x1, 0xc9, 0x0, 0x0, 0x3, 0x10, 0x0, 0x0, - 0x0, 0x0, - - /* U+4ED5 "仕" */ - 0x0, 0x0, 0x20, 0x0, 0x10, 0x0, 0x0, 0x0, - 0x3, 0xe1, 0x0, 0xd3, 0x0, 0x0, 0x0, 0x8, - 0x70, 0x0, 0xd0, 0x0, 0x0, 0x0, 0xd, 0x0, - 0x0, 0xd0, 0x0, 0x0, 0x0, 0x4c, 0x0, 0x0, - 0xd0, 0x0, 0x20, 0x0, 0xbe, 0x26, 0x55, 0xd5, - 0x57, 0x90, 0x4, 0x4d, 0x0, 0x0, 0xd0, 0x0, - 0x0, 0x6, 0xd, 0x0, 0x0, 0xd0, 0x0, 0x0, - 0x10, 0xd, 0x0, 0x0, 0xd0, 0x0, 0x0, 0x0, - 0xd, 0x0, 0x0, 0xd0, 0x0, 0x0, 0x0, 0xd, - 0x0, 0x0, 0xd0, 0x0, 0x0, 0x0, 0xd, 0x0, - 0x0, 0xd0, 0x7, 0x10, 0x0, 0xe, 0x6, 0x55, - 0x55, 0x55, 0x30, 0x0, 0x3, 0x0, 0x0, 0x0, - 0x0, 0x0, - - /* U+4ED6 "他" */ - 0x0, 0x1, 0x30, 0x0, 0x20, 0x0, 0x0, 0x0, - 0x6, 0xd0, 0x0, 0xb2, 0x0, 0x0, 0x0, 0xa, - 0x40, 0x0, 0xb0, 0x0, 0x0, 0x0, 0x1c, 0x0, - 0x90, 0xb0, 0x2, 0x0, 0x0, 0x7a, 0x0, 0xc0, - 0xb5, 0x5d, 0x10, 0x0, 0xac, 0x14, 0xd5, 0xc0, - 0xb, 0x0, 0x5, 0x3c, 0x21, 0xb0, 0xb0, 0xc, - 0x0, 0x6, 0xc, 0x0, 0xb0, 0xb0, 0xc, 0x0, - 0x0, 0xc, 0x0, 0xb0, 0xb1, 0x7d, 0x0, 0x0, - 0xc, 0x0, 0xb0, 0xb0, 0x23, 0x0, 0x0, 0xc, - 0x0, 0xb0, 0x70, 0x0, 0x50, 0x0, 0xc, 0x0, - 0xb0, 0x0, 0x0, 0x90, 0x0, 0xc, 0x0, 0xa9, - 0x99, 0x99, 0xd3, 0x0, 0x3, 0x0, 0x0, 0x0, - 0x0, 0x0, - - /* U+4ED8 "付" */ - 0x0, 0x0, 0x30, 0x0, 0x0, 0x10, 0x0, 0x0, - 0x1, 0xe1, 0x0, 0x0, 0xd2, 0x0, 0x0, 0x6, - 0x70, 0x0, 0x0, 0xd0, 0x0, 0x0, 0xc, 0x0, - 0x0, 0x0, 0xd0, 0x10, 0x0, 0x3c, 0x5, 0x55, - 0x55, 0xe5, 0xa1, 0x0, 0xad, 0x0, 0x0, 0x0, - 0xd0, 0x0, 0x4, 0x5c, 0x0, 0x40, 0x0, 0xd0, - 0x0, 0x6, 0xc, 0x0, 0x67, 0x0, 0xd0, 0x0, - 0x10, 0xc, 0x0, 0xe, 0x0, 0xd0, 0x0, 0x0, - 0xc, 0x0, 0x2, 0x0, 0xd0, 0x0, 0x0, 0xc, - 0x0, 0x0, 0x0, 0xd0, 0x0, 0x0, 0xc, 0x0, - 0x0, 0x0, 0xd0, 0x0, 0x0, 0xd, 0x0, 0x0, - 0x5c, 0xd0, 0x0, 0x0, 0x2, 0x0, 0x0, 0x1, - 0x10, 0x0, - - /* U+4EE3 "代" */ - 0x0, 0x0, 0x30, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x1, 0xf2, 0x4, 0x90, 0x40, 0x0, 0x0, 0x6, - 0x80, 0x3, 0x90, 0x3d, 0x20, 0x0, 0xc, 0x10, - 0x2, 0xa0, 0x5, 0x40, 0x0, 0x4d, 0x10, 0x1, - 0xb0, 0x3, 0x70, 0x0, 0xad, 0x15, 0x55, 0xd5, - 0x54, 0x30, 0x6, 0x3c, 0x0, 0x0, 0xc0, 0x0, - 0x0, 0x15, 0xc, 0x0, 0x0, 0xa2, 0x0, 0x0, - 0x10, 0xc, 0x0, 0x0, 0x76, 0x0, 0x0, 0x0, - 0xc, 0x0, 0x0, 0x2c, 0x0, 0x0, 0x0, 0xc, - 0x0, 0x0, 0xa, 0x60, 0x32, 0x0, 0xc, 0x0, - 0x0, 0x1, 0xd6, 0x81, 0x0, 0xd, 0x0, 0x0, - 0x0, 0x1b, 0xf2, 0x0, 0x3, 0x0, 0x0, 0x0, - 0x0, 0x31, - - /* U+4EE4 "令" */ - 0x0, 0x0, 0x0, 0x31, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, 0xd8, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x5, 0xb4, 0x20, 0x0, 0x0, 0x0, 0x0, 0x1d, - 0x10, 0x90, 0x0, 0x0, 0x0, 0x0, 0xb5, 0x20, - 0x2a, 0x0, 0x0, 0x0, 0x9, 0x50, 0x87, 0x4, - 0xd3, 0x0, 0x0, 0x72, 0x0, 0xd, 0x0, 0x3d, - 0xc1, 0x14, 0x5, 0x55, 0x56, 0x57, 0xb0, 0x10, - 0x0, 0x1, 0x0, 0x0, 0xc, 0x60, 0x0, 0x0, - 0x0, 0x0, 0x0, 0x73, 0x0, 0x0, 0x0, 0x0, - 0x47, 0x23, 0x40, 0x0, 0x0, 0x0, 0x0, 0x1, - 0xac, 0x10, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8, - 0xc0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x30, - 0x0, 0x0, - - /* U+4EE5 "以" */ - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x6, 0x10, - 0x0, 0x0, 0x3c, 0x0, 0xd, 0x10, 0x70, 0x0, - 0x3b, 0x0, 0xd, 0x0, 0x3d, 0x0, 0x3a, 0x0, - 0xd, 0x0, 0xc, 0x40, 0x3a, 0x0, 0xd, 0x0, - 0x2, 0x0, 0x49, 0x0, 0xd, 0x0, 0x0, 0x0, - 0x58, 0x0, 0xd, 0x0, 0x4, 0x0, 0x85, 0x0, - 0xd, 0x3, 0x80, 0x0, 0xd1, 0x0, 0xd, 0x99, - 0x0, 0x5, 0xa8, 0x0, 0xe, 0x80, 0x0, 0x3c, - 0x3, 0xd1, 0x1, 0x0, 0x7, 0x80, 0x0, 0x97, - 0x0, 0x35, 0x61, 0x0, 0x0, 0x12, 0x0, 0x0, - 0x0, 0x0, 0x0, 0x0, - - /* U+4EEE "仮" */ - 0x0, 0x0, 0x30, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x2, 0xd0, 0x10, 0x4, 0x8d, 0x70, 0x0, 0x8, - 0x50, 0xc4, 0x42, 0x0, 0x0, 0x0, 0xb, 0x0, - 0xb0, 0x0, 0x0, 0x0, 0x0, 0x6c, 0x0, 0xc5, - 0x55, 0x59, 0x30, 0x0, 0x9b, 0x0, 0xb4, 0x0, - 0xc, 0x10, 0x6, 0x1b, 0x0, 0xc4, 0x10, 0x1a, - 0x0, 0x2, 0xb, 0x0, 0xb0, 0x60, 0x74, 0x0, - 0x0, 0xb, 0x3, 0x80, 0x80, 0xb0, 0x0, 0x0, - 0xb, 0x6, 0x40, 0x3b, 0x70, 0x0, 0x0, 0xb, - 0x9, 0x0, 0x2e, 0x50, 0x0, 0x0, 0xb, 0x16, - 0x4, 0x91, 0xb7, 0x0, 0x0, 0xb, 0x62, 0x64, - 0x0, 0x8, 0xd2, 0x0, 0x0, 0x2, 0x0, 0x0, - 0x0, 0x0, - - /* U+4EF6 "件" */ - 0x0, 0x0, 0x30, 0x0, 0x4, 0x0, 0x0, 0x0, - 0x2, 0xf1, 0x0, 0xe, 0x0, 0x0, 0x0, 0x8, - 0x70, 0xa5, 0xc, 0x0, 0x0, 0x0, 0xc, 0x0, - 0xd0, 0xc, 0x0, 0x20, 0x0, 0x6e, 0x1, 0xb5, - 0x5d, 0x56, 0x70, 0x0, 0x9c, 0x6, 0x20, 0xc, - 0x0, 0x0, 0x6, 0x1c, 0x5, 0x0, 0xc, 0x0, - 0x0, 0x13, 0xc, 0x5, 0x55, 0x5d, 0x55, 0xa4, - 0x0, 0xc, 0x1, 0x0, 0xc, 0x0, 0x0, 0x0, - 0xc, 0x0, 0x0, 0xc, 0x0, 0x0, 0x0, 0xc, - 0x0, 0x0, 0xc, 0x0, 0x0, 0x0, 0xc, 0x0, - 0x0, 0xd, 0x0, 0x0, 0x0, 0xd, 0x0, 0x0, - 0xd, 0x0, 0x0, 0x0, 0x1, 0x0, 0x0, 0x2, - 0x0, 0x0, - - /* U+4EFB "任" */ - 0x0, 0x0, 0x20, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x1, 0xe0, 0x0, 0x0, 0x14, 0x0, 0x0, 0x6, - 0x70, 0x35, 0x89, 0xa9, 0x10, 0x0, 0xc, 0x2, - 0x10, 0xb1, 0x0, 0x0, 0x0, 0x4b, 0x0, 0x0, - 0xb1, 0x0, 0x0, 0x0, 0xad, 0x0, 0x0, 0xb1, - 0x0, 0x0, 0x5, 0x3c, 0x0, 0x0, 0xb1, 0x3, - 0x40, 0x15, 0xc, 0x26, 0x55, 0xc5, 0x55, 0x40, - 0x0, 0xc, 0x0, 0x0, 0xb1, 0x0, 0x0, 0x0, - 0xc, 0x0, 0x0, 0xb1, 0x0, 0x0, 0x0, 0xc, - 0x0, 0x0, 0xb1, 0x0, 0x0, 0x0, 0xc, 0x0, - 0x0, 0xb1, 0x0, 0x30, 0x0, 0xd, 0x36, 0x55, - 0x75, 0x56, 0x70, 0x0, 0x2, 0x0, 0x0, 0x0, - 0x0, 0x0, - - /* U+4EFD "份" */ - 0x0, 0x0, 0x0, 0x0, 0x2, 0x0, 0x0, 0x0, - 0x0, 0xd1, 0x6, 0x7, 0x0, 0x0, 0x0, 0x4, - 0x90, 0x2c, 0x6, 0x10, 0x0, 0x0, 0xb, 0x10, - 0x84, 0x1, 0x70, 0x0, 0x0, 0x3a, 0x0, 0xa0, - 0x0, 0x93, 0x0, 0x0, 0x9d, 0x7, 0x20, 0x0, - 0x1d, 0x60, 0x5, 0x2c, 0x34, 0x55, 0x55, 0x84, - 0xa3, 0x13, 0xc, 0x20, 0xd, 0x0, 0xa1, 0x0, - 0x0, 0xc, 0x0, 0x1b, 0x0, 0xb0, 0x0, 0x0, - 0xc, 0x0, 0x38, 0x0, 0xb0, 0x0, 0x0, 0xc, - 0x0, 0x92, 0x0, 0xb0, 0x0, 0x0, 0xc, 0x2, - 0x80, 0x22, 0xc0, 0x0, 0x0, 0xc, 0x36, 0x0, - 0x3d, 0x60, 0x0, 0x0, 0x2, 0x10, 0x0, 0x0, - 0x0, 0x0, - - /* U+4F01 "企" */ - 0x0, 0x0, 0x0, 0x12, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x9c, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x2, 0xd4, 0x30, 0x0, 0x0, 0x0, 0x0, 0xc, - 0x30, 0x73, 0x0, 0x0, 0x0, 0x0, 0x95, 0x2, - 0xa, 0x50, 0x0, 0x0, 0x8, 0x40, 0xe, 0x10, - 0xab, 0x41, 0x1, 0x72, 0x0, 0xc, 0x0, 0x6, - 0x91, 0x3, 0x0, 0xe1, 0xc, 0x0, 0x60, 0x0, - 0x0, 0x0, 0xc0, 0xd, 0x55, 0x61, 0x0, 0x0, - 0x0, 0xc0, 0xc, 0x0, 0x0, 0x0, 0x0, 0x0, - 0xc0, 0xc, 0x0, 0x0, 0x0, 0x0, 0x0, 0xc0, - 0xc, 0x0, 0x2, 0x40, 0x5, 0x55, 0x75, 0x57, - 0x55, 0x56, 0x70, - - /* U+4F0A "伊" */ - 0x0, 0x2, 0x20, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x7, 0x90, 0x0, 0x0, 0x4, 0x0, 0x0, 0xc, - 0x16, 0x5c, 0x55, 0x5d, 0x0, 0x0, 0x39, 0x0, - 0xc, 0x0, 0xc, 0x0, 0x0, 0x9b, 0x0, 0xc, - 0x0, 0xc, 0x20, 0x2, 0x6c, 0x46, 0x5d, 0x55, - 0x5d, 0x74, 0x6, 0xc, 0x0, 0xc, 0x0, 0xc, - 0x0, 0x0, 0xc, 0x0, 0xc, 0x0, 0xc, 0x0, - 0x0, 0xc, 0x7, 0x5d, 0x55, 0x5c, 0x0, 0x0, - 0xc, 0x0, 0x2a, 0x0, 0x5, 0x0, 0x0, 0xc, - 0x0, 0x83, 0x0, 0x0, 0x0, 0x0, 0xc, 0x3, - 0x80, 0x0, 0x0, 0x0, 0x0, 0xc, 0x35, 0x0, - 0x0, 0x0, 0x0, 0x0, 0x1, 0x10, 0x0, 0x0, - 0x0, 0x0, - - /* U+4F11 "休" */ - 0x0, 0x0, 0x20, 0x0, 0x30, 0x0, 0x0, 0x0, - 0x2, 0xd1, 0x0, 0xc2, 0x0, 0x0, 0x0, 0x8, - 0x50, 0x0, 0xc0, 0x0, 0x0, 0x0, 0xb, 0x0, - 0x0, 0xc0, 0x3, 0x40, 0x0, 0x6b, 0x36, 0x5a, - 0xf7, 0x55, 0x50, 0x0, 0xac, 0x0, 0xc, 0xd5, - 0x0, 0x0, 0x6, 0x2c, 0x0, 0x2a, 0xc3, 0x40, - 0x0, 0x13, 0xc, 0x0, 0xa2, 0xc0, 0xa0, 0x0, - 0x0, 0xc, 0x3, 0x80, 0xc0, 0x67, 0x0, 0x0, - 0xc, 0x8, 0x0, 0xc0, 0xc, 0x70, 0x0, 0xc, - 0x51, 0x0, 0xc0, 0x2, 0x92, 0x0, 0xc, 0x0, - 0x0, 0xc0, 0x0, 0x0, 0x0, 0xc, 0x0, 0x0, - 0xc0, 0x0, 0x0, 0x0, 0x2, 0x0, 0x0, 0x20, - 0x0, 0x0, - - /* U+4F1A "会" */ - 0x0, 0x0, 0x0, 0x60, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x2, 0xe5, 0x0, 0x0, 0x0, 0x0, 0x0, - 0xa, 0x47, 0x10, 0x0, 0x0, 0x0, 0x0, 0x68, - 0x0, 0xa2, 0x0, 0x0, 0x0, 0x3, 0x90, 0x0, - 0x1c, 0x70, 0x0, 0x0, 0x3a, 0x55, 0x55, 0x79, - 0x9f, 0xa2, 0x4, 0x40, 0x10, 0x0, 0x0, 0x2, - 0x20, 0x10, 0x0, 0x0, 0x0, 0x0, 0x6, 0x0, - 0x2, 0x65, 0x58, 0x95, 0x55, 0x58, 0x30, 0x0, - 0x0, 0xd, 0x50, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x85, 0x0, 0x64, 0x0, 0x0, 0x0, 0x6, 0x50, - 0x0, 0x8, 0x90, 0x0, 0x0, 0x5e, 0xca, 0x87, - 0x65, 0xc5, 0x0, 0x0, 0x2, 0x0, 0x0, 0x0, - 0x21, 0x0, - - /* U+4F1D "伝" */ - 0x0, 0x0, 0x10, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0xe3, 0x0, 0x0, 0x1, 0x0, 0x0, 0x5, - 0xa0, 0x55, 0x55, 0x68, 0x0, 0x0, 0xc, 0x20, - 0x0, 0x0, 0x0, 0x0, 0x0, 0x4b, 0x0, 0x0, - 0x0, 0x0, 0x0, 0x0, 0xad, 0x15, 0x55, 0x55, - 0x56, 0xc1, 0x7, 0x1c, 0x1, 0x0, 0xd2, 0x0, - 0x0, 0x11, 0xc, 0x0, 0x3, 0xa0, 0x0, 0x0, - 0x0, 0xc, 0x0, 0x9, 0x20, 0x0, 0x0, 0x0, - 0xc, 0x0, 0x29, 0x0, 0x52, 0x0, 0x0, 0xc, - 0x0, 0x90, 0x0, 0xc, 0x10, 0x0, 0xc, 0x8, - 0xa7, 0x86, 0x5a, 0x80, 0x0, 0xd, 0x4, 0x62, - 0x0, 0x3, 0x50, 0x0, 0x1, 0x0, 0x0, 0x0, - 0x0, 0x0, - - /* U+4F38 "伸" */ - 0x0, 0x1, 0x0, 0x0, 0x12, 0x0, 0x0, 0x0, - 0x8, 0x70, 0x0, 0x2b, 0x0, 0x0, 0x0, 0xc, - 0x0, 0x0, 0x2a, 0x0, 0x20, 0x0, 0x39, 0xb, - 0x55, 0x6b, 0x55, 0xe0, 0x0, 0xab, 0xc, 0x0, - 0x2a, 0x0, 0xc0, 0x2, 0x9a, 0xc, 0x0, 0x2a, - 0x0, 0xc0, 0x8, 0x1a, 0xc, 0x55, 0x6b, 0x55, - 0xc0, 0x11, 0x1a, 0xc, 0x0, 0x2a, 0x0, 0xc0, - 0x0, 0x1a, 0xc, 0x55, 0x6b, 0x55, 0xc0, 0x0, - 0x1a, 0x8, 0x0, 0x2a, 0x0, 0x80, 0x0, 0x1a, - 0x0, 0x0, 0x2a, 0x0, 0x0, 0x0, 0x1a, 0x0, - 0x0, 0x2a, 0x0, 0x0, 0x0, 0x2b, 0x0, 0x0, - 0x2a, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x1, - 0x0, 0x0, - - /* U+4F3C "似" */ - 0x0, 0x1, 0x10, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x8, 0x70, 0x0, 0x0, 0x8, 0x20, 0x0, 0xc, - 0x3, 0x1, 0x0, 0xc, 0x10, 0x0, 0x48, 0xb, - 0x14, 0x60, 0xc, 0x0, 0x0, 0xab, 0xb, 0x0, - 0xe1, 0xd, 0x0, 0x2, 0x7b, 0xb, 0x0, 0x60, - 0xd, 0x0, 0x7, 0xb, 0xb, 0x0, 0x0, 0xd, - 0x0, 0x10, 0xb, 0xb, 0x0, 0x0, 0x3b, 0x0, - 0x0, 0xb, 0xb, 0x0, 0x50, 0x77, 0x0, 0x0, - 0xb, 0xb, 0x59, 0x10, 0xd6, 0x0, 0x0, 0xb, - 0xc, 0x90, 0xa, 0x63, 0xa0, 0x0, 0xb, 0x2, - 0x0, 0x96, 0x0, 0x97, 0x0, 0x1b, 0x0, 0x56, - 0x10, 0x0, 0x23, 0x0, 0x1, 0x3, 0x0, 0x0, - 0x0, 0x0, - - /* U+4F46 "但" */ - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0xb, 0x31, 0x0, 0x0, 0x2, 0x0, 0x0, 0x2c, - 0xc, 0x55, 0x55, 0x5e, 0x0, 0x0, 0x84, 0xc, - 0x0, 0x0, 0xc, 0x0, 0x1, 0xe1, 0xc, 0x0, - 0x0, 0xc, 0x0, 0x7, 0xd0, 0xc, 0x55, 0x55, - 0x5c, 0x0, 0x25, 0xc0, 0xc, 0x0, 0x0, 0xc, - 0x0, 0x30, 0xc0, 0xc, 0x0, 0x0, 0xc, 0x0, - 0x0, 0xc0, 0xc, 0x0, 0x0, 0xc, 0x0, 0x0, - 0xc0, 0xc, 0x55, 0x55, 0x5c, 0x0, 0x0, 0xc0, - 0x7, 0x0, 0x0, 0x3, 0x0, 0x0, 0xc0, 0x0, - 0x0, 0x0, 0x0, 0x40, 0x0, 0xc2, 0x65, 0x55, - 0x55, 0x55, 0x71, 0x0, 0x20, 0x0, 0x0, 0x0, - 0x0, 0x0, - - /* U+4F4D "位" */ - 0x0, 0x0, 0x0, 0x1, 0x0, 0x0, 0x0, 0x0, - 0x4, 0xc0, 0x3, 0x80, 0x0, 0x0, 0x0, 0x9, - 0x50, 0x0, 0xd2, 0x0, 0x0, 0x0, 0xc, 0x0, - 0x0, 0x20, 0x4, 0x50, 0x0, 0x5a, 0x16, 0x55, - 0x55, 0x55, 0x40, 0x0, 0xac, 0x0, 0x20, 0x0, - 0x87, 0x0, 0x4, 0x4b, 0x0, 0x80, 0x0, 0xa3, - 0x0, 0x5, 0xb, 0x0, 0x74, 0x0, 0xb0, 0x0, - 0x0, 0xb, 0x0, 0x3b, 0x1, 0x80, 0x0, 0x0, - 0xb, 0x0, 0x1d, 0x6, 0x30, 0x0, 0x0, 0xb, - 0x0, 0x4, 0x8, 0x0, 0x0, 0x0, 0xb, 0x0, - 0x0, 0x6, 0x0, 0x70, 0x0, 0xb, 0x36, 0x55, - 0x55, 0x55, 0x62, 0x0, 0x1, 0x0, 0x0, 0x0, - 0x0, 0x0, - - /* U+4F4E "低" */ - 0x0, 0x3, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0xd3, 0x0, 0x0, 0x3b, 0x30, 0x0, 0x49, 0x4, - 0x46, 0xc7, 0x41, 0x0, 0xa, 0x10, 0xc0, 0xb, - 0x0, 0x0, 0x2, 0xf2, 0xb, 0x0, 0xb0, 0x0, - 0x0, 0x9b, 0x10, 0xb0, 0xb, 0x0, 0x20, 0x43, - 0xa1, 0xc, 0x55, 0xb6, 0x57, 0x41, 0xa, 0x10, - 0xb0, 0x6, 0x40, 0x0, 0x0, 0xa1, 0xb, 0x0, - 0x38, 0x0, 0x0, 0xa, 0x10, 0xb0, 0x0, 0xc0, - 0x1, 0x0, 0xa1, 0xb, 0x36, 0x6, 0x90, 0x70, - 0xa, 0x10, 0xf7, 0x53, 0xa, 0x99, 0x0, 0xa1, - 0x3, 0x0, 0xc0, 0x7, 0xa0, 0x1, 0x0, 0x0, - 0x1, 0x0, 0x0, - - /* U+4F4F "住" */ - 0x0, 0x0, 0x20, 0x1, 0x0, 0x0, 0x0, 0x0, - 0x0, 0xe3, 0x7, 0x70, 0x0, 0x0, 0x0, 0x5, - 0x90, 0x0, 0xd2, 0x0, 0x0, 0x0, 0xb, 0x15, - 0x55, 0x75, 0x59, 0x90, 0x0, 0x4c, 0x1, 0x0, - 0xc0, 0x0, 0x0, 0x0, 0x9c, 0x0, 0x0, 0xc0, - 0x0, 0x0, 0x6, 0x1c, 0x0, 0x0, 0xc0, 0x0, - 0x0, 0x12, 0xc, 0x3, 0x55, 0xd5, 0x6c, 0x10, - 0x0, 0xc, 0x1, 0x0, 0xc0, 0x0, 0x0, 0x0, - 0xc, 0x0, 0x0, 0xc0, 0x0, 0x0, 0x0, 0xc, - 0x0, 0x0, 0xc0, 0x0, 0x0, 0x0, 0xc, 0x0, - 0x0, 0xc0, 0x0, 0x30, 0x0, 0xd, 0x36, 0x55, - 0x85, 0x57, 0x80, 0x0, 0x1, 0x0, 0x0, 0x0, - 0x0, 0x0, - - /* U+4F53 "体" */ - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x3, 0xb0, 0x0, 0xc2, 0x0, 0x0, 0x0, 0x9, - 0x40, 0x0, 0xc0, 0x0, 0x0, 0x0, 0xb, 0x0, - 0x0, 0xc0, 0x2, 0x50, 0x0, 0x69, 0x16, 0x5b, - 0xf8, 0x55, 0x50, 0x0, 0xac, 0x0, 0xc, 0xc5, - 0x0, 0x0, 0x6, 0x1b, 0x0, 0x57, 0xc1, 0x60, - 0x0, 0x13, 0xb, 0x0, 0xa0, 0xc0, 0x91, 0x0, - 0x0, 0xb, 0x7, 0x30, 0xc0, 0x2c, 0x0, 0x0, - 0xb, 0x25, 0x0, 0xc0, 0x59, 0xc2, 0x0, 0xb, - 0x30, 0x75, 0xd5, 0x53, 0x30, 0x0, 0xb, 0x0, - 0x0, 0xc0, 0x0, 0x0, 0x0, 0xb, 0x0, 0x0, - 0xc0, 0x0, 0x0, 0x0, 0x2, 0x0, 0x0, 0x20, - 0x0, 0x0, - - /* U+4F55 "何" */ - 0x0, 0x0, 0x10, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x3, 0xb0, 0x0, 0x0, 0x0, 0x10, 0x0, 0x8, - 0x46, 0x55, 0x55, 0x59, 0x93, 0x0, 0xc, 0x0, - 0x0, 0x0, 0xb, 0x0, 0x0, 0x5c, 0x2, 0x0, - 0x30, 0xb, 0x0, 0x0, 0xab, 0xb, 0x55, 0xb4, - 0xb, 0x0, 0x6, 0x2b, 0xb, 0x0, 0xa2, 0xb, - 0x0, 0x2, 0xb, 0xb, 0x0, 0xa2, 0xb, 0x0, - 0x0, 0xb, 0xb, 0x55, 0xb2, 0xb, 0x0, 0x0, - 0xb, 0xa, 0x0, 0x40, 0xb, 0x0, 0x0, 0xb, - 0x0, 0x0, 0x0, 0xb, 0x0, 0x0, 0xb, 0x0, - 0x0, 0x0, 0xb, 0x0, 0x0, 0xc, 0x0, 0x0, - 0x17, 0xd9, 0x0, 0x0, 0x1, 0x0, 0x0, 0x0, - 0x20, 0x0, - - /* U+4F59 "余" */ - 0x0, 0x0, 0x0, 0x40, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x2, 0xe4, 0x0, 0x0, 0x0, 0x0, 0x0, - 0xb, 0x46, 0x10, 0x0, 0x0, 0x0, 0x0, 0x87, - 0x0, 0x92, 0x0, 0x0, 0x0, 0x7, 0x70, 0x0, - 0xb, 0x60, 0x0, 0x0, 0x68, 0x65, 0x65, 0x7a, - 0xae, 0x80, 0x16, 0x10, 0x0, 0xb1, 0x0, 0x4, - 0x30, 0x0, 0x55, 0x55, 0xc5, 0x55, 0xc3, 0x0, - 0x0, 0x10, 0x0, 0xb1, 0x0, 0x0, 0x0, 0x0, - 0x4, 0xb0, 0xb1, 0x45, 0x0, 0x0, 0x0, 0x2c, - 0x10, 0xb1, 0x5, 0xc2, 0x0, 0x2, 0x90, 0x0, - 0xb0, 0x0, 0x5e, 0x0, 0x15, 0x0, 0x3b, 0xe0, - 0x0, 0x6, 0x0, 0x0, 0x0, 0x0, 0x10, 0x0, - 0x0, 0x0, - - /* U+4F5C "作" */ - 0x0, 0x0, 0x30, 0x3, 0x10, 0x0, 0x0, 0x0, - 0x2, 0xd1, 0xa, 0x50, 0x0, 0x0, 0x0, 0x7, - 0x50, 0x1b, 0x0, 0x0, 0x20, 0x0, 0xb, 0x0, - 0x87, 0x95, 0x55, 0x91, 0x0, 0x5b, 0x1, 0x90, - 0xc0, 0x0, 0x0, 0x0, 0xac, 0x7, 0x0, 0xc0, - 0x0, 0x0, 0x6, 0x2c, 0x21, 0x0, 0xd5, 0x5a, - 0x70, 0x3, 0xc, 0x0, 0x0, 0xc0, 0x0, 0x0, - 0x0, 0xc, 0x0, 0x0, 0xc0, 0x0, 0x0, 0x0, - 0xc, 0x0, 0x0, 0xd5, 0x56, 0xb0, 0x0, 0xc, - 0x0, 0x0, 0xc0, 0x0, 0x0, 0x0, 0xc, 0x0, - 0x0, 0xc0, 0x0, 0x0, 0x0, 0xd, 0x0, 0x0, - 0xd0, 0x0, 0x0, 0x0, 0x2, 0x0, 0x0, 0x20, - 0x0, 0x0, - - /* U+4F60 "你" */ - 0x0, 0x0, 0x40, 0x2, 0x0, 0x0, 0x0, 0x0, - 0x2, 0xe1, 0xe, 0x20, 0x0, 0x0, 0x0, 0x8, - 0x60, 0x58, 0x0, 0x0, 0x0, 0x0, 0xc, 0x0, - 0xb6, 0x55, 0x58, 0x90, 0x0, 0x7c, 0x2, 0x70, - 0x30, 0x9, 0x30, 0x1, 0x9c, 0x7, 0x0, 0x94, - 0x2, 0x0, 0x7, 0x1c, 0x11, 0x51, 0x93, 0x10, - 0x0, 0x12, 0xc, 0x0, 0xd1, 0x93, 0x53, 0x0, - 0x0, 0xc, 0x3, 0x70, 0x93, 0xb, 0x20, 0x0, - 0xc, 0x8, 0x0, 0x93, 0x4, 0xc0, 0x0, 0xc, - 0x24, 0x0, 0x93, 0x0, 0xc0, 0x0, 0xc, 0x20, - 0x0, 0xa2, 0x0, 0x0, 0x0, 0xc, 0x0, 0x19, - 0xe1, 0x0, 0x0, 0x0, 0x1, 0x0, 0x0, 0x10, - 0x0, 0x0, - - /* U+4F7F "使" */ - 0x0, 0x0, 0x20, 0x0, 0x10, 0x0, 0x0, 0x0, - 0x3, 0xe1, 0x0, 0xa2, 0x0, 0x0, 0x0, 0x8, - 0x60, 0x0, 0xa1, 0x1, 0x60, 0x0, 0xc, 0x5, - 0x55, 0xc5, 0x55, 0x50, 0x0, 0x6b, 0x1, 0x65, - 0xc5, 0x58, 0x10, 0x0, 0x8b, 0x2, 0x90, 0xa0, - 0xb, 0x0, 0x5, 0x1b, 0x1, 0x90, 0xa0, 0xb, - 0x0, 0x12, 0xb, 0x2, 0xb5, 0xc5, 0x5c, 0x0, - 0x0, 0xb, 0x0, 0x30, 0xb0, 0x2, 0x0, 0x0, - 0xb, 0x0, 0x5, 0xa0, 0x0, 0x0, 0x0, 0xb, - 0x0, 0x7, 0x80, 0x0, 0x0, 0x0, 0xb, 0x0, - 0x2a, 0x7a, 0x30, 0x0, 0x0, 0xb, 0x5, 0x60, - 0x2, 0xae, 0xa1, 0x0, 0x2, 0x30, 0x0, 0x0, - 0x0, 0x10, - - /* U+4F86 "來" */ - 0x0, 0x0, 0x0, 0x11, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x2c, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x2a, 0x0, 0x3, 0x0, 0x1, 0x65, 0x55, - 0x6c, 0x55, 0x59, 0x50, 0x0, 0x3, 0xb0, 0x2a, - 0x1, 0xd0, 0x0, 0x0, 0x8, 0x60, 0x2a, 0x4, - 0x80, 0x0, 0x0, 0x1a, 0x76, 0x3b, 0x9, 0x5a, - 0x10, 0x0, 0x81, 0x9, 0xbd, 0x64, 0x4, 0x50, - 0x1, 0x0, 0x6, 0xaa, 0x81, 0x0, 0x0, 0x0, - 0x0, 0x49, 0x2a, 0xb, 0x20, 0x0, 0x0, 0x5, - 0x80, 0x2a, 0x1, 0xd6, 0x0, 0x0, 0x64, 0x0, - 0x2a, 0x0, 0x1b, 0xe3, 0x4, 0x0, 0x0, 0x3b, - 0x0, 0x0, 0x10, 0x0, 0x0, 0x0, 0x12, 0x0, - 0x0, 0x0, - - /* U+4F8B "例" */ - 0x0, 0x2, 0x0, 0x0, 0x0, 0x0, 0x0, 0x2, - 0xd0, 0x0, 0x0, 0x0, 0xb2, 0x0, 0x76, 0x57, - 0x76, 0x80, 0xb, 0x0, 0xb, 0x0, 0x83, 0x0, - 0x82, 0xb0, 0x2, 0xe1, 0xb, 0x3, 0x1b, 0xb, - 0x0, 0x8d, 0x1, 0xa5, 0xb5, 0xb0, 0xb0, 0x25, - 0xb0, 0x73, 0xc, 0xb, 0xb, 0x2, 0xb, 0x7, - 0x93, 0xa0, 0xb0, 0xb0, 0x0, 0xb2, 0x4, 0x94, - 0xb, 0xb, 0x0, 0xb, 0x0, 0x1b, 0x0, 0xb0, - 0xb0, 0x0, 0xb0, 0x8, 0x30, 0x1, 0xb, 0x0, - 0xb, 0x4, 0x50, 0x0, 0x0, 0xb0, 0x0, 0xb4, - 0x30, 0x0, 0x3, 0x9e, 0x0, 0x2, 0x0, 0x0, - 0x0, 0x0, 0x20, - - /* U+4F9B "供" */ - 0x0, 0x0, 0x20, 0x2, 0x0, 0x10, 0x0, 0x0, - 0x1, 0xe1, 0xd, 0x0, 0xd0, 0x0, 0x0, 0x7, - 0x70, 0xb, 0x0, 0xb0, 0x0, 0x0, 0xc, 0x0, - 0xb, 0x0, 0xb0, 0x40, 0x0, 0x6b, 0x6, 0x5c, - 0x55, 0xc5, 0x60, 0x0, 0xaa, 0x0, 0xb, 0x0, - 0xb0, 0x0, 0x6, 0x1a, 0x0, 0xb, 0x0, 0xb0, - 0x0, 0x2, 0xa, 0x0, 0xb, 0x0, 0xb0, 0x30, - 0x0, 0xa, 0x56, 0x57, 0x55, 0x75, 0x84, 0x0, - 0xa, 0x0, 0x8, 0x1, 0x10, 0x0, 0x0, 0xa, - 0x0, 0x79, 0x0, 0x85, 0x0, 0x0, 0xa, 0x3, - 0x90, 0x0, 0xa, 0x80, 0x0, 0x1b, 0x27, 0x0, - 0x0, 0x0, 0xb0, 0x0, 0x3, 0x20, 0x0, 0x0, - 0x0, 0x0, - - /* U+4F9D "依" */ - 0x0, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x8, 0x80, 0x3, 0x80, 0x0, 0x0, 0x0, 0xc, - 0x10, 0x0, 0xc1, 0x2, 0x30, 0x0, 0x29, 0x26, - 0x56, 0xe5, 0x55, 0x50, 0x0, 0x9c, 0x0, 0x7, - 0x90, 0x0, 0x0, 0x1, 0x7b, 0x0, 0x1a, 0x50, - 0x6, 0x0, 0x6, 0xb, 0x0, 0xa1, 0x51, 0x5b, - 0x20, 0x2, 0xb, 0x6, 0xe1, 0x19, 0x50, 0x0, - 0x0, 0xb, 0x44, 0xb0, 0xa, 0x0, 0x0, 0x0, - 0xb, 0x20, 0xb0, 0x6, 0x70, 0x0, 0x0, 0xb, - 0x0, 0xb0, 0x41, 0xc4, 0x0, 0x0, 0xb, 0x0, - 0xb9, 0x20, 0x2e, 0x70, 0x0, 0xc, 0x0, 0xa2, - 0x0, 0x3, 0x60, 0x0, 0x3, 0x0, 0x0, 0x0, - 0x0, 0x0, - - /* U+4FA1 "価" */ - 0x0, 0x0, 0x10, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x3, 0xc0, 0x0, 0x0, 0x0, 0x10, 0x0, 0x8, - 0x56, 0x58, 0x58, 0x55, 0xa2, 0x0, 0xb, 0x0, - 0xa, 0x9, 0x10, 0x0, 0x0, 0x6c, 0x0, 0xa, - 0x9, 0x10, 0x0, 0x0, 0x9a, 0xa, 0x5c, 0x5b, - 0x55, 0xd0, 0x5, 0x1a, 0xb, 0xa, 0x9, 0x10, - 0xb0, 0x2, 0xa, 0xb, 0xa, 0x9, 0x10, 0xb0, - 0x0, 0xa, 0xb, 0xa, 0x9, 0x10, 0xb0, 0x0, - 0xa, 0xb, 0xa, 0x9, 0x10, 0xb0, 0x0, 0xa, - 0xb, 0xa, 0x9, 0x10, 0xb0, 0x0, 0xa, 0xb, - 0x58, 0x57, 0x55, 0xb0, 0x0, 0xb, 0xb, 0x0, - 0x0, 0x0, 0xa0, 0x0, 0x1, 0x1, 0x0, 0x0, - 0x0, 0x0, - - /* U+4FBF "便" */ - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0xb, 0x40, 0x0, 0x0, 0x3, 0x40, 0x0, 0x1c, - 0x36, 0x55, 0xc5, 0x55, 0x40, 0x0, 0x74, 0x6, - 0x55, 0xc5, 0x58, 0x10, 0x0, 0xd2, 0xb, 0x0, - 0xb0, 0xb, 0x0, 0x5, 0xc2, 0xc, 0x55, 0xc5, - 0x5b, 0x0, 0x6, 0x92, 0xb, 0x0, 0xb0, 0xb, - 0x0, 0x30, 0x92, 0xb, 0x0, 0xb0, 0xb, 0x0, - 0x0, 0x92, 0xb, 0x55, 0xc5, 0x59, 0x0, 0x0, - 0x92, 0x1, 0x20, 0xa0, 0x0, 0x0, 0x0, 0x92, - 0x0, 0x67, 0x60, 0x0, 0x0, 0x0, 0x92, 0x0, - 0x1e, 0x80, 0x0, 0x0, 0x0, 0x92, 0x5, 0x91, - 0x5c, 0xb8, 0x70, 0x0, 0x32, 0x51, 0x0, 0x0, - 0x25, 0x30, - - /* U+4FC2 "係" */ - 0x0, 0x0, 0x20, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x2, 0xe2, 0x0, 0x2, 0x5a, 0x80, 0x0, 0x7, - 0x73, 0x56, 0xb8, 0x53, 0x30, 0x0, 0xd, 0x0, - 0x3, 0xb4, 0x14, 0x0, 0x0, 0x5b, 0x0, 0x66, - 0x0, 0xc8, 0x0, 0x0, 0xbb, 0x5, 0xa8, 0x7c, - 0x31, 0x0, 0x6, 0x3b, 0x0, 0x4, 0x70, 0x6, - 0x20, 0x3, 0xb, 0x2, 0xca, 0x77, 0x55, 0xd0, - 0x0, 0xb, 0x0, 0x41, 0xb, 0x0, 0x90, 0x0, - 0xb, 0x0, 0x2a, 0xb, 0x51, 0x0, 0x0, 0xb, - 0x0, 0xb3, 0xb, 0xa, 0x40, 0x0, 0xb, 0x7, - 0x30, 0xb, 0x1, 0xe0, 0x0, 0xc, 0x22, 0x6, - 0xc9, 0x0, 0x20, 0x0, 0x1, 0x0, 0x0, 0x30, - 0x0, 0x0, - - /* U+4FDD "保" */ - 0x0, 0x0, 0x40, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x3, 0xd0, 0x85, 0x55, 0x5b, 0x10, 0x0, 0x8, - 0x50, 0xc0, 0x0, 0xb, 0x0, 0x0, 0xb, 0x0, - 0xc0, 0x0, 0xb, 0x0, 0x0, 0x6b, 0x0, 0xc0, - 0x0, 0xb, 0x0, 0x0, 0xaa, 0x0, 0xd5, 0xb5, - 0x5a, 0x0, 0x6, 0x1a, 0x0, 0x0, 0xb0, 0x0, - 0x0, 0x1, 0xa, 0x45, 0x56, 0xd6, 0x55, 0xa2, - 0x0, 0xa, 0x0, 0x9, 0xd4, 0x20, 0x0, 0x0, - 0xa, 0x0, 0x38, 0xb0, 0x80, 0x0, 0x0, 0xa, - 0x0, 0x90, 0xb0, 0x39, 0x0, 0x0, 0xa, 0x7, - 0x10, 0xb0, 0x6, 0xd2, 0x0, 0x1b, 0x40, 0x0, - 0xb0, 0x0, 0x10, 0x0, 0x1, 0x0, 0x0, 0x20, - 0x0, 0x0, - - /* U+4FE1 "信" */ - 0x0, 0x0, 0x10, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x2, 0xd0, 0x0, 0xa1, 0x0, 0x0, 0x0, 0x8, - 0x50, 0x0, 0x75, 0x1, 0x50, 0x0, 0xb, 0x17, - 0x55, 0x55, 0x55, 0x50, 0x0, 0x6a, 0x0, 0x0, - 0x0, 0x6, 0x0, 0x0, 0xba, 0x1, 0x65, 0x55, - 0x55, 0x10, 0x6, 0x49, 0x0, 0x0, 0x0, 0x6, - 0x0, 0x13, 0x19, 0x1, 0x65, 0x55, 0x55, 0x20, - 0x0, 0x19, 0x0, 0x75, 0x55, 0x58, 0x20, 0x0, - 0x19, 0x0, 0xb0, 0x0, 0xb, 0x0, 0x0, 0x19, - 0x0, 0xb0, 0x0, 0xb, 0x0, 0x0, 0x19, 0x0, - 0xc5, 0x55, 0x5c, 0x0, 0x0, 0x19, 0x0, 0xa0, - 0x0, 0xa, 0x0, 0x0, 0x2, 0x0, 0x0, 0x0, - 0x0, 0x0, - - /* U+4FEE "修" */ - 0x0, 0x3, 0x0, 0x2, 0x20, 0x0, 0x0, 0x0, - 0xd, 0x10, 0x9, 0x60, 0x0, 0x0, 0x0, 0x57, - 0x0, 0xd, 0x55, 0x59, 0x10, 0x0, 0xa1, 0x40, - 0x65, 0x30, 0x69, 0x0, 0x2, 0xf2, 0xb2, 0x40, - 0x78, 0x80, 0x0, 0x8, 0xa1, 0xa0, 0x0, 0x8b, - 0x60, 0x0, 0x34, 0x91, 0xa0, 0x47, 0x14, 0x6c, - 0x90, 0x10, 0x91, 0xa3, 0x10, 0x69, 0x20, 0x0, - 0x0, 0x91, 0xa0, 0x17, 0x30, 0xa6, 0x0, 0x0, - 0x91, 0xa1, 0x20, 0x2a, 0x60, 0x20, 0x0, 0x91, - 0xa0, 0x17, 0x70, 0x2c, 0x90, 0x0, 0x91, 0x1, - 0x30, 0x28, 0xa2, 0x0, 0x0, 0x91, 0x1, 0x57, - 0x71, 0x0, 0x0, 0x0, 0x20, 0x13, 0x0, 0x0, - 0x0, 0x0, - - /* U+500B "個" */ - 0x0, 0x2, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0xc7, 0x30, 0x0, 0x0, 0x30, 0x0, 0x2c, 0xc, - 0x55, 0x65, 0x5c, 0x20, 0x8, 0x40, 0xb0, 0xa, - 0x0, 0xb0, 0x0, 0xe2, 0xb, 0x35, 0xa6, 0x6b, - 0x0, 0x6e, 0x0, 0xb0, 0x8, 0x0, 0xb0, 0x16, - 0xb0, 0xb, 0x1, 0x82, 0xb, 0x2, 0xb, 0x0, - 0xb0, 0xc5, 0xc1, 0xb0, 0x0, 0xb0, 0xb, 0xa, - 0xa, 0xb, 0x0, 0xb, 0x0, 0xb0, 0xc5, 0xc0, - 0xb0, 0x0, 0xb0, 0xb, 0x8, 0x6, 0xb, 0x0, - 0xb, 0x0, 0xc5, 0x55, 0x55, 0xc0, 0x0, 0xb0, - 0xb, 0x0, 0x0, 0xa, 0x0, 0x2, 0x0, 0x0, - 0x0, 0x0, 0x0, - - /* U+5011 "們" */ - 0x0, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0xf, 0x41, 0x4, 0x3, 0x0, 0x40, 0x0, 0x4a, - 0x2b, 0x5c, 0x1d, 0x56, 0xb0, 0x0, 0x93, 0x2a, - 0xb, 0xb, 0x2, 0x90, 0x0, 0xe1, 0x2b, 0x5c, - 0xc, 0x56, 0x90, 0x5, 0xf0, 0x2a, 0xb, 0xb, - 0x2, 0x90, 0x8, 0xb0, 0x2b, 0x5a, 0xa, 0x56, - 0x90, 0x31, 0xb0, 0x2a, 0x0, 0x0, 0x2, 0x90, - 0x0, 0xb0, 0x2a, 0x0, 0x0, 0x2, 0x90, 0x0, - 0xb0, 0x2a, 0x0, 0x0, 0x2, 0x90, 0x0, 0xb0, - 0x2a, 0x0, 0x0, 0x2, 0x90, 0x0, 0xb0, 0x2a, - 0x0, 0x0, 0x2, 0x90, 0x0, 0xb0, 0x2a, 0x0, - 0x0, 0x6c, 0x80, 0x0, 0x30, 0x11, 0x0, 0x0, - 0x3, 0x0, - - /* U+5019 "候" */ - 0x0, 0x2, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x1e, 0x10, 0x45, 0x55, 0xa0, 0x0, 0x0, 0x58, - 0x0, 0x0, 0x3, 0x90, 0x0, 0x0, 0xa2, 0x82, - 0x0, 0x5, 0x61, 0x30, 0x0, 0xe1, 0xa2, 0x7a, - 0x55, 0x55, 0x40, 0x6, 0xe0, 0xa0, 0x57, 0x0, - 0x11, 0x0, 0x16, 0xb0, 0xa0, 0x85, 0xa6, 0x65, - 0x0, 0x20, 0xb0, 0xa0, 0x30, 0xa2, 0x0, 0x0, - 0x0, 0xb0, 0xa2, 0x65, 0xc7, 0x58, 0x60, 0x0, - 0xb0, 0xa0, 0x0, 0xb6, 0x0, 0x0, 0x0, 0xb0, - 0xa0, 0x6, 0x52, 0x60, 0x0, 0x0, 0xb0, 0x0, - 0x29, 0x0, 0x87, 0x0, 0x0, 0xb0, 0x4, 0x60, - 0x0, 0xa, 0xb1, 0x0, 0x20, 0x11, 0x0, 0x0, - 0x0, 0x0, - - /* U+501F "借" */ - 0x0, 0x0, 0x10, 0x3, 0x0, 0x30, 0x0, 0x0, - 0x1, 0xe1, 0xb, 0x10, 0xd0, 0x0, 0x0, 0x6, - 0x70, 0xa, 0x0, 0xb0, 0x30, 0x0, 0xc, 0x14, - 0x5c, 0x55, 0xc5, 0x60, 0x0, 0x57, 0x0, 0xa, - 0x0, 0xb0, 0x0, 0x0, 0xba, 0x0, 0xa, 0x0, - 0xb0, 0x51, 0x7, 0x39, 0x36, 0x55, 0x55, 0x55, - 0x53, 0x1, 0x19, 0x0, 0x75, 0x55, 0x59, 0x0, - 0x0, 0x19, 0x0, 0xc0, 0x0, 0xb, 0x0, 0x0, - 0x19, 0x0, 0xc0, 0x0, 0xb, 0x0, 0x0, 0x19, - 0x0, 0xd5, 0x55, 0x5b, 0x0, 0x0, 0x19, 0x0, - 0xc0, 0x0, 0xb, 0x0, 0x0, 0x2a, 0x0, 0xd5, - 0x55, 0x5b, 0x0, 0x0, 0x12, 0x0, 0x20, 0x0, - 0x1, 0x0, - - /* U+5024 "値" */ - 0x0, 0x3, 0x0, 0x0, 0x30, 0x0, 0x0, 0x0, - 0xc, 0x30, 0x0, 0xc2, 0x0, 0x0, 0x0, 0x2a, - 0x35, 0x55, 0xd5, 0x56, 0xa0, 0x0, 0x84, 0x10, - 0x0, 0xc0, 0x0, 0x0, 0x0, 0xe2, 0x0, 0x86, - 0xc5, 0x5a, 0x0, 0x7, 0xd1, 0x51, 0xb0, 0x0, - 0x1a, 0x0, 0x16, 0xa1, 0xc0, 0xc5, 0x55, 0x5a, - 0x0, 0x20, 0xa1, 0xb0, 0xb0, 0x0, 0x1a, 0x0, - 0x0, 0xa1, 0xb0, 0xc5, 0x55, 0x5a, 0x0, 0x0, - 0xa1, 0xb0, 0xb0, 0x0, 0x1a, 0x0, 0x0, 0xa1, - 0xb0, 0xc5, 0x55, 0x5a, 0x0, 0x0, 0xa1, 0xb0, - 0x90, 0x0, 0x7, 0x10, 0x0, 0xa1, 0xd5, 0x55, - 0x55, 0x56, 0xe1, 0x0, 0x50, 0x30, 0x0, 0x0, - 0x0, 0x0, - - /* U+503C "值" */ - 0x0, 0x2, 0x0, 0x3, 0x0, 0x0, 0x0, 0x0, - 0xd, 0x20, 0xa, 0x40, 0x0, 0x0, 0x0, 0x2a, - 0x45, 0x5c, 0x65, 0x5c, 0x20, 0x0, 0x84, 0x10, - 0xb, 0x10, 0x0, 0x0, 0x0, 0xe2, 0x7, 0x5c, - 0x55, 0xa2, 0x0, 0x6, 0xd2, 0xb, 0x0, 0x0, - 0xb0, 0x0, 0x8, 0x92, 0xb, 0x55, 0x55, 0xc0, - 0x0, 0x40, 0x92, 0xb, 0x0, 0x0, 0xb0, 0x0, - 0x0, 0x92, 0xb, 0x55, 0x55, 0xc0, 0x0, 0x0, - 0x92, 0xb, 0x0, 0x0, 0xb0, 0x0, 0x0, 0x92, - 0xb, 0x55, 0x55, 0xc0, 0x0, 0x0, 0x92, 0xb, - 0x0, 0x0, 0xb0, 0x0, 0x0, 0x94, 0x5c, 0x55, - 0x55, 0xc7, 0xb0, 0x0, 0x41, 0x10, 0x0, 0x0, - 0x0, 0x0, - - /* U+505A "做" */ - 0x0, 0x2, 0x0, 0x0, 0x1, 0x0, 0x0, 0x0, - 0xd, 0x14, 0x80, 0x7, 0x60, 0x0, 0x0, 0x39, - 0x3, 0x70, 0xa, 0x0, 0x0, 0x0, 0x83, 0x3, - 0x72, 0x8, 0x0, 0x30, 0x0, 0xd2, 0x67, 0x96, - 0x59, 0x5b, 0x60, 0x4, 0xe0, 0x3, 0x70, 0x44, - 0xa, 0x0, 0x7, 0xb0, 0x3, 0x70, 0x44, 0xa, - 0x0, 0x21, 0xb0, 0xa6, 0x6c, 0x16, 0xa, 0x0, - 0x0, 0xb0, 0xa0, 0xa, 0x6, 0x56, 0x0, 0x0, - 0xb0, 0xa0, 0xa, 0x1, 0xe1, 0x0, 0x0, 0xb0, - 0xb5, 0x5b, 0x5, 0xc2, 0x0, 0x0, 0xb0, 0xa0, - 0x7, 0x57, 0x1b, 0x20, 0x0, 0xc0, 0x30, 0x16, - 0x30, 0x2, 0xa1, 0x0, 0x20, 0x0, 0x0, 0x0, - 0x0, 0x0, - - /* U+505C "停" */ - 0x0, 0x3, 0x0, 0x3, 0x0, 0x0, 0x0, 0x0, - 0x1e, 0x10, 0x2, 0xa0, 0x1, 0x0, 0x0, 0x57, - 0x36, 0x55, 0x85, 0x58, 0x50, 0x0, 0xa1, 0x0, - 0x75, 0x55, 0x90, 0x0, 0x1, 0xf2, 0x0, 0xb0, - 0x0, 0xb0, 0x0, 0x7, 0xd0, 0x0, 0xc5, 0x55, - 0xc0, 0x0, 0x16, 0xb0, 0x20, 0x20, 0x0, 0x10, - 0x30, 0x20, 0xb0, 0xb5, 0x55, 0x55, 0x58, 0x80, - 0x0, 0xb1, 0x54, 0x55, 0x55, 0x97, 0x0, 0x0, - 0xb0, 0x1, 0x0, 0xb0, 0x0, 0x0, 0x0, 0xb0, - 0x0, 0x0, 0xb0, 0x0, 0x0, 0x0, 0xb0, 0x0, - 0x0, 0xb0, 0x0, 0x0, 0x0, 0xb0, 0x0, 0x39, - 0xc0, 0x0, 0x0, 0x0, 0x20, 0x0, 0x1, 0x10, - 0x0, 0x0, - - /* U+5065 "健" */ - 0x0, 0x2, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0xc, 0x20, 0x0, 0xb, 0x0, 0x0, 0x0, 0x1b, - 0x47, 0x62, 0x5c, 0x5a, 0x0, 0x0, 0x74, 0x9, - 0x20, 0xa, 0xa, 0x10, 0x0, 0xc0, 0xb, 0x5, - 0x5c, 0x5c, 0x70, 0x5, 0xe1, 0x56, 0x20, 0x2b, - 0x2b, 0x0, 0x15, 0xb0, 0x85, 0xc1, 0x3b, 0x35, - 0x0, 0x20, 0xb0, 0x0, 0x93, 0x5c, 0x59, 0x10, - 0x0, 0xb0, 0x53, 0x70, 0xa, 0x0, 0x0, 0x0, - 0xb0, 0x67, 0x45, 0x5c, 0x56, 0x60, 0x0, 0xb0, - 0x1e, 0x0, 0xb, 0x0, 0x0, 0x0, 0xb0, 0x48, - 0xa4, 0x5, 0x0, 0x0, 0x0, 0xb3, 0x40, 0x18, - 0xbb, 0xbc, 0x90, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, - - /* U+5074 "側" */ - 0x0, 0x4, 0x0, 0x0, 0x0, 0x0, 0x10, 0x0, - 0xd, 0x37, 0x55, 0x80, 0x0, 0xc0, 0x0, 0x2b, - 0xa, 0x0, 0xa0, 0x70, 0xa0, 0x0, 0x74, 0xa, - 0x0, 0xa0, 0xb0, 0xa0, 0x0, 0xc2, 0xc, 0x55, - 0xa0, 0xa0, 0xa0, 0x3, 0xe0, 0xa, 0x0, 0xa0, - 0xa0, 0xa0, 0x7, 0xa0, 0xa, 0x0, 0xa0, 0xa0, - 0xa0, 0x21, 0xa0, 0xc, 0x55, 0xa0, 0xa0, 0xa0, - 0x0, 0xa0, 0xa, 0x0, 0xa0, 0xa0, 0xa0, 0x0, - 0xa0, 0xc, 0x55, 0xa0, 0xa0, 0xa0, 0x0, 0xa0, - 0x6, 0x33, 0x10, 0x0, 0xa0, 0x0, 0xa0, 0x1b, - 0x21, 0xa0, 0x0, 0xa0, 0x0, 0xb0, 0x70, 0x0, - 0x93, 0x5b, 0x80, 0x0, 0x11, 0x0, 0x0, 0x10, - 0x2, 0x0, - - /* U+5099 "備" */ - 0x0, 0x1, 0x0, 0x40, 0x3, 0x0, 0x0, 0x0, - 0xd, 0x30, 0xd1, 0xa, 0x40, 0x0, 0x0, 0x3b, - 0x36, 0xd5, 0x5c, 0x6b, 0x30, 0x0, 0x84, 0x0, - 0xc0, 0xa, 0x20, 0x10, 0x0, 0xe2, 0x65, 0xd5, - 0x5a, 0x67, 0xb1, 0x6, 0xe0, 0x2, 0xc1, 0x0, - 0x1, 0x0, 0x16, 0xb0, 0xd, 0x65, 0xa5, 0x5d, - 0x0, 0x20, 0xb0, 0x7c, 0x0, 0xb0, 0xb, 0x0, - 0x0, 0xb3, 0xb, 0x55, 0xc5, 0x5b, 0x0, 0x0, - 0xb0, 0xb, 0x0, 0xb0, 0xb, 0x0, 0x0, 0xb0, - 0xb, 0x55, 0xc5, 0x5b, 0x0, 0x0, 0xb0, 0xb, - 0x0, 0xb0, 0xb, 0x0, 0x0, 0xb0, 0xb, 0x0, - 0xb3, 0xa9, 0x0, 0x0, 0x30, 0x3, 0x0, 0x0, - 0x31, 0x0, - - /* U+50B3 "傳" */ - 0x0, 0x0, 0x0, 0x0, 0x40, 0x0, 0x0, 0x0, - 0x5, 0x90, 0x0, 0xc0, 0x2, 0x30, 0x0, 0xa, - 0x37, 0x55, 0xc5, 0x56, 0x50, 0x0, 0x1a, 0xa, - 0x55, 0xc5, 0x5c, 0x0, 0x0, 0x8b, 0xb, 0x55, - 0xc5, 0x5b, 0x0, 0x1, 0xa9, 0xb, 0x0, 0xb0, - 0xb, 0x0, 0x6, 0x29, 0x8, 0x55, 0xc5, 0x77, - 0x0, 0x1, 0x19, 0x13, 0x44, 0xc5, 0x5b, 0x40, - 0x0, 0x19, 0x28, 0x53, 0x10, 0x81, 0x40, 0x0, - 0x19, 0x55, 0x55, 0x55, 0xc5, 0xb1, 0x0, 0x19, - 0x4, 0x80, 0x0, 0xb0, 0x0, 0x0, 0x19, 0x0, - 0x71, 0x0, 0xb0, 0x0, 0x0, 0x2a, 0x0, 0x2, - 0x6c, 0x90, 0x0, 0x0, 0x1, 0x0, 0x0, 0x3, - 0x0, 0x0, - - /* U+50C5 "僅" */ - 0x0, 0x2, 0x0, 0x30, 0x0, 0x20, 0x0, 0x0, - 0xe, 0x20, 0xc1, 0x1, 0xc0, 0x0, 0x0, 0x59, - 0x55, 0xd5, 0x55, 0xc6, 0xb0, 0x0, 0xb2, 0x10, - 0xb0, 0x0, 0xa0, 0x0, 0x1, 0xe2, 0x0, 0xb5, - 0xa5, 0x80, 0x0, 0x7, 0xd0, 0x7, 0x55, 0xc5, - 0x58, 0x0, 0x16, 0xb0, 0xb, 0x0, 0xb0, 0xb, - 0x0, 0x30, 0xb0, 0xc, 0x55, 0xc5, 0x5b, 0x0, - 0x0, 0xb0, 0x5, 0x0, 0xb0, 0x5, 0x0, 0x0, - 0xb0, 0x6, 0x55, 0xc5, 0x67, 0x0, 0x0, 0xb0, - 0x5, 0x55, 0xc5, 0x69, 0x0, 0x0, 0xb0, 0x1, - 0x0, 0xb0, 0x0, 0x0, 0x0, 0xb1, 0x55, 0x55, - 0xc5, 0x56, 0xd1, 0x0, 0x30, 0x10, 0x0, 0x0, - 0x0, 0x0, - - /* U+50CD "働" */ - 0x0, 0x1, 0x0, 0x0, 0x0, 0x10, 0x0, 0x0, - 0x2d, 0x13, 0x6a, 0x60, 0xd1, 0x0, 0x0, 0x66, - 0x22, 0xa0, 0x0, 0xb0, 0x0, 0x0, 0xa2, 0x75, - 0xc5, 0x90, 0xb0, 0x0, 0x1, 0xd1, 0x20, 0xa0, - 0x36, 0xc5, 0xd0, 0x7, 0xc0, 0xb5, 0xc5, 0xb0, - 0xb0, 0xb0, 0x8, 0xa0, 0xa5, 0xc5, 0x90, 0xb0, - 0xb0, 0x30, 0xa0, 0xa0, 0xa1, 0x90, 0xa0, 0xb0, - 0x0, 0xa0, 0xb5, 0xc5, 0x92, 0x80, 0xa0, 0x0, - 0xa0, 0x0, 0xa1, 0x46, 0x30, 0x90, 0x0, 0xa0, - 0x65, 0xc5, 0x49, 0x1, 0x80, 0x0, 0xa0, 0x24, - 0xc5, 0x55, 0x3, 0x70, 0x0, 0xb1, 0xb5, 0x11, - 0x60, 0x7d, 0x30, 0x0, 0x20, 0x0, 0x2, 0x0, - 0x2, 0x0, - - /* U+50CF "像" */ - 0x0, 0x1, 0x50, 0x6, 0x0, 0x0, 0x0, 0x0, - 0x5, 0xb0, 0x4d, 0x55, 0x80, 0x0, 0x0, 0xb, - 0x30, 0xb1, 0x8, 0x40, 0x0, 0x0, 0x1b, 0x8, - 0xb5, 0x78, 0x5b, 0x20, 0x0, 0x9c, 0x33, 0xb0, - 0xb0, 0xb, 0x0, 0x1, 0x9a, 0x0, 0xd5, 0xc5, - 0x5d, 0x10, 0x6, 0x1a, 0x0, 0x26, 0x50, 0x5, - 0x0, 0x11, 0x1a, 0x0, 0x56, 0x93, 0xa6, 0x0, - 0x0, 0x1a, 0x5, 0x28, 0x98, 0x50, 0x0, 0x0, - 0x1a, 0x1, 0x83, 0x9b, 0x81, 0x0, 0x0, 0x1a, - 0x14, 0x9, 0x5d, 0x2c, 0x0, 0x0, 0x1a, 0x3, - 0x92, 0xd, 0x9, 0xd3, 0x0, 0x1a, 0x43, 0x6, - 0xd8, 0x0, 0x40, 0x0, 0x1, 0x0, 0x0, 0x30, - 0x0, 0x0, - - /* U+50D5 "僕" */ - 0x0, 0x3, 0x0, 0x3, 0x3, 0x0, 0x0, 0x0, - 0xd, 0x30, 0xd, 0xd, 0x0, 0x0, 0x0, 0x3a, - 0x8, 0x1b, 0xb, 0x2c, 0x0, 0x0, 0x84, 0x5, - 0x4b, 0xb, 0x81, 0x0, 0x0, 0xd3, 0x56, 0x5a, - 0x5b, 0x67, 0x80, 0x5, 0xd2, 0x0, 0x82, 0x4, - 0x60, 0x0, 0x7, 0x92, 0x15, 0x78, 0x59, 0x6a, - 0x0, 0x20, 0x92, 0x1, 0x0, 0xb0, 0x10, 0x0, - 0x0, 0x92, 0x3, 0x65, 0xc5, 0x73, 0x0, 0x0, - 0x92, 0x45, 0x57, 0xa5, 0x59, 0x60, 0x0, 0x92, - 0x10, 0xa, 0x15, 0x0, 0x0, 0x0, 0x92, 0x1, - 0x92, 0x3, 0x80, 0x0, 0x0, 0x92, 0x46, 0x0, - 0x0, 0x3c, 0x80, 0x0, 0x1, 0x0, 0x0, 0x0, - 0x0, 0x0, - - /* U+50F9 "價" */ - 0x0, 0x3, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x4d, 0x46, 0x57, 0x57, 0x56, 0x90, 0x0, 0x85, - 0x2, 0xa, 0xa, 0x2, 0x10, 0x0, 0xc2, 0xc, - 0x5c, 0x5c, 0x5a, 0x40, 0x2, 0xf3, 0xc, 0x5c, - 0x5c, 0x5a, 0x30, 0x7, 0xa2, 0x4, 0x0, 0x0, - 0x3, 0x0, 0x6, 0x82, 0x6, 0x65, 0x55, 0x5b, - 0x0, 0x30, 0x82, 0x6, 0x75, 0x55, 0x59, 0x0, - 0x0, 0x82, 0x6, 0x30, 0x0, 0x19, 0x0, 0x0, - 0x82, 0x6, 0x75, 0x55, 0x59, 0x0, 0x0, 0x82, - 0x6, 0x75, 0x55, 0x59, 0x0, 0x0, 0x82, 0x1, - 0xb3, 0x3, 0x86, 0x0, 0x0, 0x82, 0x48, 0x10, - 0x0, 0x6, 0xb0, 0x0, 0x10, 0x10, 0x0, 0x0, - 0x0, 0x0, - - /* U+5104 "億" */ - 0x0, 0x1, 0x0, 0x1, 0x0, 0x0, 0x0, 0x0, - 0x9, 0x70, 0x0, 0xb0, 0x0, 0x0, 0x0, 0xd, - 0x4, 0x65, 0x95, 0x58, 0x50, 0x0, 0x49, 0x0, - 0x55, 0x5, 0xa0, 0x0, 0x0, 0xab, 0x24, 0x48, - 0x49, 0x44, 0xa1, 0x1, 0x99, 0x12, 0x31, 0x11, - 0x24, 0x10, 0x6, 0x29, 0x0, 0xc5, 0x55, 0x6b, - 0x0, 0x2, 0x19, 0x0, 0xc5, 0x55, 0x69, 0x0, - 0x0, 0x19, 0x0, 0xd5, 0x55, 0x6a, 0x0, 0x0, - 0x19, 0x0, 0x42, 0x70, 0x22, 0x0, 0x0, 0x19, - 0x5, 0x1a, 0x63, 0x2a, 0x20, 0x0, 0x19, 0x38, - 0x19, 0x0, 0x83, 0x80, 0x0, 0x2a, 0x41, 0xc, - 0xab, 0xd2, 0x0, 0x0, 0x1, 0x0, 0x0, 0x0, - 0x0, 0x0, - - /* U+512A "優" */ - 0x0, 0x2, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0xe, 0x26, 0x55, 0x85, 0x5a, 0x20, 0x0, 0x48, - 0x0, 0xb5, 0x75, 0xb1, 0x0, 0x0, 0x92, 0x0, - 0xc5, 0x55, 0xc0, 0x0, 0x0, 0xd2, 0x0, 0xc5, - 0x55, 0xc0, 0x0, 0x5, 0xe0, 0x75, 0xa5, 0x55, - 0xa5, 0xb0, 0x7, 0xb1, 0xa2, 0x73, 0xa2, 0x25, - 0x40, 0x21, 0xb0, 0x38, 0x83, 0x12, 0x7a, 0x10, - 0x0, 0xb0, 0x31, 0x5a, 0x88, 0x33, 0x0, 0x0, - 0xb0, 0x0, 0xd7, 0x55, 0x92, 0x0, 0x0, 0xb0, - 0x9, 0x47, 0x7, 0x70, 0x0, 0x0, 0xb0, 0x30, - 0x5, 0xf9, 0x0, 0x0, 0x0, 0xb0, 0x4, 0x75, - 0x6, 0xcb, 0x50, 0x0, 0x20, 0x30, 0x0, 0x0, - 0x2, 0x0, - - /* U+513F "儿" */ - 0x0, 0x0, 0x20, 0x3, 0x0, 0x0, 0x0, 0x0, - 0x1d, 0x0, 0xa3, 0x0, 0x0, 0x0, 0x1, 0xb0, - 0xa, 0x20, 0x0, 0x0, 0x0, 0x1b, 0x0, 0xa2, - 0x0, 0x0, 0x0, 0x1, 0xa0, 0xa, 0x20, 0x0, - 0x0, 0x0, 0x29, 0x0, 0xa2, 0x0, 0x0, 0x0, - 0x4, 0x80, 0xa, 0x20, 0x0, 0x0, 0x0, 0x75, - 0x0, 0xa2, 0x0, 0x0, 0x0, 0xb, 0x10, 0xa, - 0x20, 0x4, 0x0, 0x3, 0x90, 0x0, 0xa2, 0x0, - 0x60, 0x0, 0xb1, 0x0, 0x9, 0x20, 0xa, 0x21, - 0x81, 0x0, 0x0, 0x5d, 0xbb, 0xe4, 0x30, 0x0, - 0x0, 0x0, 0x0, 0x0, 0x0, - - /* U+5143 "元" */ - 0x0, 0x0, 0x0, 0x0, 0x0, 0x71, 0x0, 0x0, - 0x6, 0x55, 0x55, 0x55, 0x53, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x2, 0x0, 0x4, 0x65, 0x59, 0x55, - 0x95, 0x5a, 0x60, 0x0, 0x0, 0xe, 0x0, 0xd0, - 0x0, 0x0, 0x0, 0x0, 0xc, 0x0, 0xd0, 0x0, - 0x0, 0x0, 0x0, 0x49, 0x0, 0xd0, 0x0, 0x0, - 0x0, 0x0, 0x95, 0x0, 0xd0, 0x0, 0x30, 0x0, - 0x1, 0xc0, 0x0, 0xd0, 0x0, 0x60, 0x0, 0xb, - 0x30, 0x0, 0xd0, 0x0, 0xc0, 0x1, 0x92, 0x0, - 0x0, 0xac, 0xbc, 0xc2, 0x4, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x0, - - /* U+5144 "兄" */ - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xb, - 0x55, 0x55, 0x55, 0xc2, 0x0, 0x0, 0xd0, 0x0, - 0x0, 0xd, 0x0, 0x0, 0xd, 0x0, 0x0, 0x0, - 0xd0, 0x0, 0x0, 0xd0, 0x0, 0x0, 0xd, 0x0, - 0x0, 0xd, 0x0, 0x0, 0x0, 0xd0, 0x0, 0x0, - 0xe5, 0xb8, 0x5d, 0x5c, 0x0, 0x0, 0x3, 0xa, - 0x30, 0xd0, 0x0, 0x0, 0x0, 0x0, 0xc0, 0xd, - 0x0, 0x0, 0x0, 0x0, 0xd, 0x0, 0xd0, 0x0, - 0x40, 0x0, 0x6, 0x70, 0xd, 0x0, 0x6, 0x0, - 0x2, 0xb0, 0x0, 0xd0, 0x0, 0xc0, 0x4, 0x80, - 0x0, 0xb, 0xcb, 0xcd, 0x23, 0x20, 0x0, 0x0, - 0x0, 0x0, 0x0, - - /* U+5145 "充" */ - 0x0, 0x0, 0x0, 0x30, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x77, 0x0, 0x0, 0x0, 0x4, 0x55, - 0x55, 0x7b, 0x55, 0x59, 0x90, 0x1, 0x0, 0x3, - 0xc1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x1c, 0x30, - 0x23, 0x0, 0x0, 0x0, 0x2, 0x91, 0x0, 0x6, - 0x90, 0x0, 0x0, 0x4f, 0xaa, 0x87, 0x95, 0x9c, - 0x0, 0x0, 0x2, 0xd, 0x1, 0xb0, 0x8, 0x0, - 0x0, 0x0, 0x1c, 0x1, 0xb0, 0x0, 0x0, 0x0, - 0x0, 0x57, 0x1, 0xb0, 0x0, 0x30, 0x0, 0x0, - 0xb1, 0x1, 0xb0, 0x0, 0x60, 0x0, 0x7, 0x60, - 0x0, 0xb0, 0x0, 0xb0, 0x1, 0x73, 0x0, 0x0, - 0xbb, 0xbc, 0xd2, 0x2, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, - - /* U+5148 "先" */ - 0x0, 0x0, 0x0, 0x30, 0x0, 0x0, 0x0, 0x0, - 0x3, 0x0, 0x94, 0x0, 0x0, 0x0, 0x0, 0xe, - 0x30, 0x92, 0x0, 0x0, 0x0, 0x0, 0x3c, 0x55, - 0xb6, 0x55, 0xd2, 0x0, 0x0, 0x92, 0x0, 0x92, - 0x0, 0x0, 0x0, 0x2, 0x50, 0x0, 0x92, 0x0, - 0x0, 0x0, 0x1, 0x0, 0x0, 0x92, 0x0, 0x6, - 0x30, 0x17, 0x55, 0x7b, 0x59, 0x95, 0x55, 0x40, - 0x0, 0x0, 0x66, 0x6, 0x60, 0x0, 0x0, 0x0, - 0x0, 0x93, 0x6, 0x60, 0x0, 0x10, 0x0, 0x0, - 0xb0, 0x6, 0x60, 0x0, 0x50, 0x0, 0xa, 0x30, - 0x5, 0x60, 0x1, 0x80, 0x2, 0x82, 0x0, 0x2, - 0xda, 0xab, 0xb0, 0x13, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, - - /* U+5149 "光" */ - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x4a, 0x0, 0x0, 0x0, 0x0, 0x7, - 0x0, 0x48, 0x0, 0x91, 0x0, 0x0, 0x2, 0xc0, - 0x48, 0x4, 0xb0, 0x0, 0x0, 0x0, 0xa4, 0x48, - 0xa, 0x10, 0x0, 0x0, 0x0, 0x20, 0x48, 0x33, - 0x2, 0x40, 0x6, 0x55, 0x5c, 0x56, 0xc5, 0x56, - 0x60, 0x0, 0x0, 0x1c, 0x0, 0xb0, 0x0, 0x0, - 0x0, 0x0, 0x29, 0x0, 0xb0, 0x0, 0x0, 0x0, - 0x0, 0x76, 0x0, 0xb0, 0x0, 0x30, 0x0, 0x0, - 0xb0, 0x0, 0xb0, 0x0, 0x60, 0x0, 0x8, 0x50, - 0x0, 0xc0, 0x0, 0xa0, 0x1, 0x73, 0x0, 0x0, - 0xab, 0xaa, 0xd2, 0x3, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, - - /* U+514B "克" */ - 0x0, 0x0, 0x0, 0x42, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x95, 0x0, 0x0, 0x0, 0x5, 0x55, - 0x55, 0xb6, 0x55, 0x59, 0x70, 0x1, 0x0, 0x0, - 0xb0, 0x0, 0x0, 0x0, 0x0, 0x7, 0x55, 0xc5, - 0x55, 0xa0, 0x0, 0x0, 0xb, 0x0, 0x0, 0x0, - 0xb0, 0x0, 0x0, 0xb, 0x0, 0x0, 0x0, 0xa0, - 0x0, 0x0, 0xb, 0x0, 0x0, 0x0, 0xa0, 0x0, - 0x0, 0xb, 0x5c, 0x5a, 0x95, 0x80, 0x0, 0x0, - 0x0, 0xb, 0x7, 0x60, 0x0, 0x0, 0x0, 0x0, - 0x47, 0x7, 0x60, 0x0, 0x50, 0x0, 0x1, 0xb0, - 0x7, 0x60, 0x0, 0x80, 0x0, 0x57, 0x10, 0x5, - 0xd9, 0x9b, 0xb0, 0x3, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, - - /* U+514D "免" */ - 0x0, 0x0, 0x4, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x6b, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0xd7, 0x55, 0xb5, 0x0, 0x0, 0x0, 0x8, 0x50, - 0x0, 0xc1, 0x0, 0x0, 0x0, 0x4a, 0x0, 0x5, - 0x20, 0x4, 0x0, 0x3, 0x7c, 0x55, 0x6c, 0x55, - 0x5d, 0x0, 0x3, 0xc, 0x0, 0x39, 0x0, 0x1b, - 0x0, 0x0, 0xd, 0x55, 0x8a, 0x55, 0x5b, 0x0, - 0x0, 0x8, 0x0, 0x86, 0xb0, 0x5, 0x0, 0x0, - 0x0, 0x0, 0xd2, 0xb0, 0x0, 0x20, 0x0, 0x0, - 0x7, 0x81, 0xb0, 0x0, 0x60, 0x0, 0x0, 0x5b, - 0x0, 0xb0, 0x0, 0x91, 0x0, 0x38, 0x50, 0x0, - 0xda, 0xaa, 0xe4, 0x3, 0x20, 0x0, 0x0, 0x0, - 0x0, 0x0, - - /* U+5152 "兒" */ - 0x0, 0x0, 0x5, 0x0, 0x0, 0x0, 0x0, 0x3, - 0x59, 0x73, 0x55, 0x93, 0x0, 0x0, 0xd0, 0x0, - 0x1, 0xa, 0x20, 0x0, 0xc, 0x2, 0x0, 0x0, - 0xa1, 0x0, 0x0, 0xd5, 0x74, 0x6, 0x5c, 0x10, - 0x0, 0xc, 0x0, 0x0, 0x0, 0xa1, 0x0, 0x0, - 0xd5, 0x55, 0x55, 0x5c, 0x20, 0x0, 0x7, 0xc, - 0x0, 0xc0, 0x50, 0x0, 0x0, 0x0, 0xc0, 0xc, - 0x0, 0x0, 0x0, 0x0, 0x38, 0x0, 0xc0, 0x0, - 0x40, 0x0, 0xa, 0x20, 0xc, 0x0, 0x7, 0x0, - 0x7, 0x60, 0x0, 0xd1, 0x1, 0xd4, 0x6, 0x40, - 0x0, 0x6, 0x99, 0x97, 0x12, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x0, - - /* U+515A "党" */ - 0x0, 0x0, 0x0, 0x1, 0x0, 0x0, 0x0, 0x0, - 0x4, 0x0, 0x2b, 0x5, 0x30, 0x0, 0x0, 0x1, - 0xc2, 0x19, 0xc, 0x30, 0x0, 0x0, 0x30, 0x42, - 0x19, 0x52, 0x0, 0x30, 0x1, 0xa5, 0x55, 0x55, - 0x55, 0x5a, 0xa0, 0x9, 0x40, 0x30, 0x0, 0x4, - 0x5, 0x0, 0x0, 0x0, 0xd5, 0x55, 0x5c, 0x20, - 0x0, 0x0, 0x0, 0xb0, 0x0, 0xb, 0x0, 0x0, - 0x0, 0x0, 0xd6, 0x86, 0x7c, 0x0, 0x0, 0x0, - 0x0, 0x36, 0x72, 0x60, 0x0, 0x10, 0x0, 0x0, - 0xb, 0x22, 0x60, 0x0, 0x50, 0x0, 0x0, 0x78, - 0x2, 0x70, 0x0, 0xa0, 0x1, 0x57, 0x40, 0x1, - 0xca, 0xab, 0xc1, 0x13, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, - - /* U+5165 "入" */ - 0x0, 0x0, 0x88, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x3, 0xb0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x95, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0xda, 0x0, 0x0, 0x0, 0x0, 0x0, 0x2, 0xb9, - 0x10, 0x0, 0x0, 0x0, 0x0, 0x8, 0x54, 0x70, - 0x0, 0x0, 0x0, 0x0, 0x1c, 0x0, 0xc1, 0x0, - 0x0, 0x0, 0x0, 0x94, 0x0, 0x6a, 0x0, 0x0, - 0x0, 0x5, 0x90, 0x0, 0xc, 0x60, 0x0, 0x0, - 0x29, 0x0, 0x0, 0x2, 0xe8, 0x0, 0x3, 0x70, - 0x0, 0x0, 0x0, 0x2e, 0xc2, 0x24, 0x0, 0x0, - 0x0, 0x0, 0x1, 0x10, - - /* U+5167 "內" */ - 0x0, 0x0, 0x30, 0x0, 0x0, 0x0, 0x0, 0xa, - 0x20, 0x0, 0x0, 0x0, 0x0, 0x53, 0x0, 0x0, - 0xa, 0x55, 0x57, 0x95, 0x55, 0xc1, 0xc0, 0x0, - 0x3c, 0x0, 0xc, 0xc, 0x0, 0x6, 0xc1, 0x0, - 0xc0, 0xc0, 0x0, 0xb3, 0x70, 0xc, 0xc, 0x0, - 0x46, 0xb, 0x10, 0xc0, 0xc0, 0x9, 0x0, 0x4c, - 0xc, 0xc, 0x7, 0x10, 0x0, 0xa9, 0xc0, 0xc1, - 0x0, 0x0, 0x0, 0xc, 0xc, 0x0, 0x0, 0x0, - 0x10, 0xd0, 0xb0, 0x0, 0x0, 0x4, 0xca, 0x0, - 0x0, 0x0, 0x0, 0x0, 0x0, - - /* U+5168 "全" */ - 0x0, 0x0, 0x0, 0x20, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x4, 0xe1, 0x0, 0x0, 0x0, 0x0, 0x0, - 0xc, 0x36, 0x0, 0x0, 0x0, 0x0, 0x0, 0x87, - 0x3, 0x70, 0x0, 0x0, 0x0, 0x4, 0xa0, 0x0, - 0x59, 0x10, 0x0, 0x0, 0x49, 0x0, 0x0, 0x9, - 0xe9, 0x40, 0x6, 0x66, 0x55, 0xc6, 0x55, 0x39, - 0x70, 0x20, 0x0, 0x0, 0xa1, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x0, 0xa1, 0x2, 0x40, 0x0, 0x0, - 0x16, 0x55, 0xc6, 0x55, 0x40, 0x0, 0x0, 0x0, - 0x0, 0xa1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0xa1, 0x0, 0x0, 0x0, 0x4, 0x55, 0x55, 0xc6, - 0x55, 0x5d, 0x50, 0x1, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, - - /* U+5169 "兩" */ - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x3, 0x55, - 0x55, 0x55, 0x55, 0x57, 0xe2, 0x0, 0x0, 0x0, - 0xb0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xb, 0x0, - 0x0, 0x10, 0xc, 0x55, 0x55, 0xc5, 0x55, 0x5c, - 0x0, 0xb1, 0x10, 0xb, 0x10, 0x0, 0xa0, 0xb, - 0x7, 0x10, 0xb0, 0x70, 0xa, 0x0, 0xb0, 0x3b, - 0xb, 0x5, 0x90, 0xa0, 0xb, 0x9, 0xa4, 0xb0, - 0x9b, 0x4a, 0x0, 0xb3, 0x52, 0x9b, 0x44, 0x59, - 0xa0, 0xc, 0x50, 0x2, 0xb4, 0x1, 0x3a, 0x0, - 0xb0, 0x0, 0xb, 0x0, 0x1, 0xa0, 0xb, 0x0, - 0x0, 0xa0, 0x6, 0xe6, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x1, 0x0, - - /* U+516B "八" */ - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x1, 0x2, 0x70, 0x0, 0x0, 0x0, 0x0, - 0x1e, 0x10, 0x70, 0x0, 0x0, 0x0, 0x0, 0x1c, - 0x0, 0x80, 0x0, 0x0, 0x0, 0x0, 0x39, 0x0, - 0x90, 0x0, 0x0, 0x0, 0x0, 0x57, 0x0, 0x81, - 0x0, 0x0, 0x0, 0x0, 0x84, 0x0, 0x55, 0x0, - 0x0, 0x0, 0x0, 0xc0, 0x0, 0x1a, 0x0, 0x0, - 0x0, 0x1, 0xa0, 0x0, 0xa, 0x10, 0x0, 0x0, - 0x8, 0x30, 0x0, 0x4, 0xa0, 0x0, 0x0, 0x19, - 0x0, 0x0, 0x0, 0xb7, 0x0, 0x0, 0x80, 0x0, - 0x0, 0x0, 0x1e, 0x80, 0x5, 0x10, 0x0, 0x0, - 0x0, 0x3, 0x81, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, - - /* U+516C "公" */ - 0x0, 0x0, 0x0, 0x0, 0x10, 0x0, 0x0, 0x0, - 0x0, 0xa, 0x10, 0x80, 0x0, 0x0, 0x0, 0x0, - 0x4b, 0x0, 0x90, 0x0, 0x0, 0x0, 0x0, 0xb2, - 0x0, 0x55, 0x0, 0x0, 0x0, 0x4, 0x80, 0x0, - 0xc, 0x10, 0x0, 0x0, 0x1a, 0x0, 0x20, 0x3, - 0xc1, 0x0, 0x0, 0x81, 0x0, 0xa8, 0x0, 0x6e, - 0x60, 0x5, 0x0, 0x3, 0xc0, 0x0, 0x5, 0x40, - 0x0, 0x0, 0xb, 0x20, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x74, 0x0, 0x53, 0x0, 0x0, 0x0, 0x3, - 0x70, 0x0, 0xa, 0x30, 0x0, 0x0, 0x4c, 0x66, - 0x76, 0x67, 0xe1, 0x0, 0x0, 0x28, 0x42, 0x10, - 0x0, 0xb3, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, - - /* U+516D "六" */ - 0x0, 0x0, 0x2, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x1, 0xb1, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x8b, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x18, 0x0, 0x0, 0x10, 0x6, 0x55, 0x55, 0x55, - 0x55, 0x58, 0xc1, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x0, 0x0, 0x3c, 0x10, 0x50, 0x0, - 0x0, 0x0, 0x0, 0x98, 0x0, 0x28, 0x0, 0x0, - 0x0, 0x1, 0xd0, 0x0, 0x6, 0x80, 0x0, 0x0, - 0x9, 0x40, 0x0, 0x0, 0xb7, 0x0, 0x0, 0x57, - 0x0, 0x0, 0x0, 0x3f, 0x20, 0x2, 0x80, 0x0, - 0x0, 0x0, 0xb, 0x40, 0x15, 0x0, 0x0, 0x0, - 0x0, 0x2, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, - - /* U+5171 "共" */ - 0x0, 0x0, 0x0, 0x0, 0x10, 0x0, 0x0, 0x0, - 0x0, 0xc1, 0x0, 0xc1, 0x0, 0x0, 0x0, 0x0, - 0xc0, 0x0, 0xc0, 0x0, 0x0, 0x4, 0x55, 0xd5, - 0x55, 0xd5, 0x5c, 0x20, 0x0, 0x0, 0xc0, 0x0, - 0xc0, 0x0, 0x0, 0x0, 0x0, 0xc0, 0x0, 0xc0, - 0x0, 0x0, 0x0, 0x0, 0xc0, 0x0, 0xc0, 0x0, - 0x0, 0x0, 0x0, 0xc0, 0x0, 0xc0, 0x6, 0x20, - 0x36, 0x55, 0x75, 0x55, 0x65, 0x56, 0x50, 0x0, - 0x0, 0xa8, 0x0, 0x52, 0x0, 0x0, 0x0, 0x7, - 0xa0, 0x0, 0x7, 0xa1, 0x0, 0x0, 0x67, 0x0, - 0x0, 0x0, 0x5e, 0x20, 0x6, 0x30, 0x0, 0x0, - 0x0, 0x6, 0x50, 0x20, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, - - /* U+5176 "其" */ - 0x0, 0x0, 0x30, 0x0, 0x3, 0x0, 0x0, 0x0, - 0x0, 0xc1, 0x0, 0x1d, 0x0, 0x0, 0x3, 0x55, - 0xd5, 0x55, 0x6c, 0x5b, 0x60, 0x0, 0x0, 0xc0, - 0x0, 0x1b, 0x0, 0x0, 0x0, 0x0, 0xc5, 0x55, - 0x5b, 0x0, 0x0, 0x0, 0x0, 0xc0, 0x0, 0x1b, - 0x0, 0x0, 0x0, 0x0, 0xc0, 0x0, 0x1b, 0x0, - 0x0, 0x0, 0x0, 0xc5, 0x55, 0x5b, 0x0, 0x0, - 0x0, 0x0, 0xc0, 0x0, 0x1b, 0x1, 0x60, 0x16, - 0x55, 0x76, 0x55, 0x57, 0x56, 0x72, 0x0, 0x0, - 0xab, 0x0, 0x48, 0x10, 0x0, 0x0, 0xa, 0x70, - 0x0, 0x2, 0xd7, 0x0, 0x3, 0x82, 0x0, 0x0, - 0x0, 0x2e, 0x10, 0x1, 0x0, 0x0, 0x0, 0x0, - 0x1, 0x0, - - /* U+5177 "具" */ - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0xc5, 0x55, 0x55, 0xc0, 0x0, 0x0, 0x0, - 0xb0, 0x0, 0x1, 0x90, 0x0, 0x0, 0x0, 0xc5, - 0x55, 0x56, 0x90, 0x0, 0x0, 0x0, 0xb0, 0x0, - 0x1, 0x90, 0x0, 0x0, 0x0, 0xc5, 0x55, 0x56, - 0x90, 0x0, 0x0, 0x0, 0xb0, 0x0, 0x1, 0x90, - 0x0, 0x0, 0x0, 0xc5, 0x55, 0x56, 0x90, 0x0, - 0x0, 0x0, 0xb0, 0x0, 0x1, 0x90, 0x40, 0x6, - 0x55, 0x85, 0x55, 0x55, 0x87, 0xa2, 0x0, 0x0, - 0x89, 0x0, 0x25, 0x10, 0x0, 0x0, 0x9, 0x70, - 0x0, 0x1, 0xa7, 0x0, 0x3, 0x72, 0x0, 0x0, - 0x0, 0xb, 0x40, 0x1, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, - - /* U+5185 "内" */ - 0x0, 0x0, 0x41, 0x0, 0x0, 0x0, 0x0, 0xc, - 0x50, 0x0, 0x0, 0x0, 0x0, 0xc1, 0x0, 0x0, - 0x7, 0x55, 0x5d, 0x55, 0x55, 0xa0, 0xc0, 0x0, - 0xd0, 0x0, 0xc, 0xc, 0x0, 0xc, 0x0, 0x0, - 0xc0, 0xc0, 0x5, 0xa7, 0x0, 0xc, 0xc, 0x0, - 0xa1, 0x3c, 0x20, 0xc0, 0xc0, 0x73, 0x0, 0x6b, - 0xc, 0xc, 0x52, 0x0, 0x0, 0x60, 0xc0, 0xc0, - 0x0, 0x0, 0x0, 0xc, 0xc, 0x0, 0x0, 0x1, - 0x23, 0xb0, 0xc0, 0x0, 0x0, 0x4, 0xe7, 0x1, - 0x0, 0x0, 0x0, 0x1, 0x0, - - /* U+5186 "円" */ - 0x85, 0x55, 0x55, 0x55, 0x5a, 0x1c, 0x0, 0x2, - 0x90, 0x0, 0xc0, 0xc0, 0x0, 0x29, 0x0, 0xc, - 0xc, 0x0, 0x2, 0x90, 0x0, 0xc0, 0xc0, 0x0, - 0x29, 0x0, 0xc, 0xd, 0x55, 0x56, 0xa5, 0x55, - 0xd0, 0xc0, 0x0, 0x0, 0x0, 0xc, 0xc, 0x0, - 0x0, 0x0, 0x0, 0xc0, 0xc0, 0x0, 0x0, 0x0, - 0xc, 0xc, 0x0, 0x0, 0x0, 0x0, 0xc0, 0xc0, - 0x0, 0x0, 0x0, 0xc, 0xc, 0x0, 0x0, 0x0, - 0x6c, 0xc0, 0x10, 0x0, 0x0, 0x0, 0x21, 0x0, - - /* U+518A "冊" */ - 0x0, 0x17, 0x55, 0x55, 0x55, 0x59, 0x0, 0x0, - 0x1a, 0xb, 0x0, 0xb0, 0xc, 0x0, 0x0, 0xa, - 0xb, 0x0, 0xb0, 0xb, 0x0, 0x0, 0xa, 0xb, - 0x0, 0xb0, 0xb, 0x0, 0x0, 0xa, 0xb, 0x0, - 0xb0, 0xb, 0x0, 0x4, 0x5c, 0x5c, 0x55, 0xc5, - 0x5d, 0xd3, 0x1, 0x1a, 0xb, 0x0, 0xb0, 0xb, - 0x0, 0x0, 0xa, 0xb, 0x0, 0xb0, 0xb, 0x0, - 0x0, 0xa, 0xb, 0x0, 0xb0, 0xb, 0x0, 0x0, - 0xa, 0xb, 0x0, 0xb0, 0xb, 0x0, 0x0, 0xa, - 0xa, 0x0, 0xa0, 0xb, 0x0, 0x0, 0x19, 0x0, - 0x0, 0x4, 0xc8, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x0, - - /* U+518D "再" */ - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x1, - 0x65, 0x55, 0x55, 0x55, 0x5d, 0x30, 0x0, 0x0, - 0x0, 0x29, 0x0, 0x0, 0x0, 0x0, 0x7, 0x55, - 0x6b, 0x55, 0x92, 0x0, 0x0, 0xc, 0x0, 0x29, - 0x0, 0xc0, 0x0, 0x0, 0xc, 0x0, 0x29, 0x0, - 0xc0, 0x0, 0x0, 0xd, 0x55, 0x6b, 0x55, 0xd0, - 0x0, 0x0, 0xc, 0x0, 0x29, 0x0, 0xc0, 0x0, - 0x0, 0xc, 0x0, 0x29, 0x0, 0xc1, 0x70, 0x6, - 0x5d, 0x55, 0x55, 0x55, 0xd5, 0x61, 0x0, 0xc, - 0x0, 0x0, 0x0, 0xc0, 0x0, 0x0, 0xc, 0x0, - 0x0, 0x0, 0xc0, 0x0, 0x0, 0xc, 0x0, 0x0, - 0x5b, 0xd0, 0x0, 0x0, 0x2, 0x0, 0x0, 0x1, - 0x10, 0x0, - - /* U+5199 "写" */ - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8, - 0x55, 0x55, 0x55, 0x55, 0x97, 0x1, 0xc0, 0x10, - 0x0, 0x0, 0xa, 0x20, 0x46, 0xd, 0x10, 0x0, - 0x1, 0x10, 0x0, 0x0, 0xd5, 0x55, 0x55, 0xa5, - 0x0, 0x0, 0x39, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x6, 0x60, 0x0, 0x0, 0x3, 0x0, 0x0, 0x77, - 0x55, 0x55, 0x55, 0xe1, 0x0, 0x0, 0x0, 0x0, - 0x0, 0xc, 0x0, 0x45, 0x55, 0x55, 0x5a, 0x81, - 0xa0, 0x1, 0x0, 0x0, 0x0, 0x0, 0x48, 0x0, - 0x0, 0x0, 0x0, 0x13, 0x1a, 0x40, 0x0, 0x0, - 0x0, 0x0, 0x3d, 0xc0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x10, 0x0, - - /* U+519B "军" */ - 0x0, 0x85, 0x55, 0x55, 0x55, 0x59, 0x70, 0x5, - 0x80, 0x2, 0x90, 0x0, 0x7, 0x10, 0x2, 0x10, - 0x8, 0x50, 0x0, 0x20, 0x0, 0x0, 0x35, 0x6c, - 0x55, 0x55, 0x72, 0x0, 0x0, 0x0, 0x93, 0x9, - 0x0, 0x0, 0x0, 0x0, 0x3, 0x80, 0xb, 0x0, - 0x0, 0x0, 0x0, 0xd, 0x55, 0x5c, 0x55, 0xb1, - 0x0, 0x0, 0x0, 0x0, 0xb, 0x0, 0x0, 0x0, - 0x4, 0x55, 0x55, 0x5c, 0x55, 0x56, 0xa0, 0x1, - 0x0, 0x0, 0xb, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0xb, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0xb, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x1, - 0x0, 0x0, 0x0, - - /* U+51AC "冬" */ - 0x0, 0x0, 0x2, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x2e, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x99, 0x55, 0x5a, 0x70, 0x0, 0x0, 0x3, 0xa3, - 0x0, 0x3c, 0x10, 0x0, 0x0, 0x9, 0x6, 0x31, - 0xc2, 0x0, 0x0, 0x0, 0x60, 0x0, 0xac, 0x20, - 0x0, 0x0, 0x1, 0x0, 0x5, 0xaa, 0x91, 0x0, - 0x0, 0x0, 0x2, 0x96, 0x0, 0x4d, 0x94, 0x0, - 0x4, 0x65, 0x0, 0x6a, 0x20, 0x6d, 0xa1, 0x0, - 0x0, 0x0, 0x4, 0x90, 0x0, 0x0, 0x0, 0x0, - 0x57, 0x51, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x5d, 0x90, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0xa6, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, - - /* U+51B7 "冷" */ - 0x0, 0x0, 0x0, 0x2, 0x20, 0x0, 0x0, 0x1, - 0x0, 0x0, 0x8, 0xb0, 0x0, 0x0, 0x8, 0x60, - 0x0, 0xd, 0x52, 0x0, 0x0, 0x0, 0xf0, 0x40, - 0x58, 0x9, 0x0, 0x0, 0x0, 0x30, 0x50, 0xb3, - 0x3, 0xa0, 0x0, 0x0, 0x5, 0x18, 0x31, 0xc0, - 0x7c, 0x30, 0x0, 0x8, 0x53, 0x0, 0xa1, 0x6, - 0xa2, 0x0, 0x55, 0x13, 0x55, 0x55, 0x92, 0x0, - 0x18, 0xe0, 0x0, 0x0, 0x3, 0xb0, 0x0, 0x2, - 0xc0, 0x0, 0x10, 0xa, 0x0, 0x0, 0x4, 0xb0, - 0x0, 0x9, 0x71, 0x0, 0x0, 0x4, 0xa0, 0x0, - 0x1, 0xe3, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x66, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, - - /* U+51CD "凍" */ - 0x0, 0x0, 0x0, 0x0, 0x20, 0x0, 0x0, 0x2, - 0x0, 0x0, 0x0, 0xc1, 0x0, 0x0, 0x2, 0xc1, - 0x45, 0x55, 0xd5, 0x57, 0xb0, 0x0, 0x75, 0x1, - 0x0, 0xb0, 0x1, 0x0, 0x0, 0x2, 0x2c, 0x55, - 0xc5, 0x5d, 0x10, 0x0, 0x5, 0xb, 0x0, 0xb0, - 0xb, 0x0, 0x0, 0x6, 0xb, 0x55, 0xc5, 0x5c, - 0x0, 0x0, 0x43, 0xb, 0x0, 0xb0, 0xb, 0x0, - 0x6, 0xd0, 0xa, 0x5d, 0xe8, 0x58, 0x0, 0x2, - 0xc0, 0x0, 0x39, 0xb6, 0x10, 0x0, 0x2, 0xb0, - 0x1, 0xa0, 0xb1, 0xa0, 0x0, 0x4, 0xb0, 0x9, - 0x10, 0xb0, 0x5b, 0x20, 0x1, 0x51, 0x60, 0x0, - 0xb0, 0x6, 0xb1, 0x0, 0x0, 0x0, 0x0, 0x50, - 0x0, 0x0, - - /* U+51DD "凝" */ - 0x0, 0x0, 0x30, 0x0, 0x0, 0x0, 0x0, 0x13, - 0x0, 0xc0, 0x80, 0x65, 0x5d, 0x20, 0xa, 0x60, - 0xb6, 0x21, 0x1, 0x35, 0x0, 0x2, 0x52, 0xa0, - 0x15, 0x7, 0x80, 0x0, 0x0, 0x3, 0x98, 0xa5, - 0x0, 0xb0, 0x0, 0x0, 0x50, 0xb0, 0x2, 0x65, - 0x85, 0xd0, 0x0, 0x72, 0xb5, 0x92, 0x0, 0xa3, - 0x20, 0x3, 0x76, 0xa, 0x0, 0xb1, 0xa0, 0x30, - 0x3e, 0x45, 0x5c, 0x78, 0xa0, 0xc5, 0x50, 0xb, - 0x1, 0xc, 0x0, 0xb0, 0xa0, 0x0, 0xf, 0x0, - 0x57, 0xa1, 0xa7, 0xa0, 0x0, 0x8, 0x0, 0x90, - 0x66, 0x41, 0xb6, 0x20, 0x0, 0x6, 0x0, 0x5, - 0x0, 0x7, 0x91, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, - - /* U+51E6 "処" */ - 0x0, 0x2, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0xb, 0x50, 0x0, 0x0, 0x0, 0x0, 0x0, 0xd, - 0x0, 0x0, 0xa5, 0xb2, 0x0, 0x0, 0x3b, 0x56, - 0x90, 0xb0, 0xc0, 0x0, 0x0, 0x92, 0x4, 0x60, - 0xb0, 0xc0, 0x0, 0x0, 0xb1, 0x7, 0x31, 0x90, - 0xc0, 0x0, 0x7, 0x14, 0xb, 0x3, 0x70, 0xc0, - 0x0, 0x3, 0x6, 0x1a, 0x8, 0x10, 0xc0, 0x10, - 0x0, 0x2, 0xc4, 0x27, 0x0, 0xc0, 0x60, 0x0, - 0x1, 0xe3, 0x60, 0x0, 0xa9, 0xd2, 0x0, 0x9, - 0x2b, 0x40, 0x0, 0x1, 0x0, 0x0, 0x73, 0x1, - 0xbc, 0x63, 0x22, 0x31, 0x6, 0x20, 0x0, 0x3, - 0x8c, 0xde, 0xb0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, - - /* U+51FA "出" */ - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0xa, 0x30, 0x0, 0x0, 0x3, 0x10, 0xa, 0x10, - 0x5, 0x10, 0x7, 0x60, 0xa, 0x10, 0xa, 0x20, - 0x6, 0x50, 0xa, 0x10, 0xa, 0x10, 0x6, 0x50, - 0xa, 0x10, 0xa, 0x10, 0x8, 0x75, 0x5c, 0x65, - 0x5c, 0x20, 0x0, 0x0, 0xa, 0x10, 0x2, 0x0, - 0xd, 0x10, 0xa, 0x10, 0x2, 0xa0, 0xc, 0x0, - 0xa, 0x10, 0x1, 0xa0, 0xc, 0x0, 0xa, 0x10, - 0x1, 0xa0, 0xc, 0x0, 0xa, 0x10, 0x1, 0xa0, - 0x8, 0x55, 0x55, 0x55, 0x56, 0xa0, 0x0, 0x0, - 0x0, 0x0, 0x0, 0x0, - - /* U+5206 "分" */ - 0x0, 0x0, 0x0, 0x0, 0x10, 0x0, 0x0, 0x0, - 0x0, 0x1b, 0x0, 0x80, 0x0, 0x0, 0x0, 0x0, - 0x87, 0x0, 0x80, 0x0, 0x0, 0x0, 0x1, 0xc0, - 0x0, 0x27, 0x0, 0x0, 0x0, 0xa, 0x30, 0x0, - 0x9, 0x40, 0x0, 0x0, 0x65, 0x0, 0x0, 0x1, - 0xb8, 0x10, 0x4, 0x54, 0x57, 0x85, 0x5c, 0x59, - 0xc1, 0x2, 0x0, 0x8, 0x40, 0xb, 0x10, 0x0, - 0x0, 0x0, 0xb, 0x10, 0xc, 0x0, 0x0, 0x0, - 0x0, 0x2a, 0x0, 0xd, 0x0, 0x0, 0x0, 0x0, - 0x93, 0x0, 0xd, 0x0, 0x0, 0x0, 0x5, 0x60, - 0x0, 0x2b, 0x0, 0x0, 0x0, 0x63, 0x0, 0x18, - 0xf3, 0x0, 0x0, 0x2, 0x0, 0x0, 0x0, 0x10, - 0x0, 0x0, - - /* U+5207 "切" */ - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0xd, 0x0, 0x0, 0x0, 0x0, 0x10, 0x0, 0xc, - 0x0, 0x65, 0x69, 0x56, 0xd0, 0x0, 0xc, 0x0, - 0x10, 0x3a, 0x1, 0xb0, 0x0, 0xc, 0x46, 0xa1, - 0x48, 0x2, 0xb0, 0x5, 0x5c, 0x0, 0x0, 0x67, - 0x2, 0xa0, 0x0, 0xc, 0x0, 0x0, 0x84, 0x3, - 0x90, 0x0, 0xc, 0x0, 0x0, 0xc1, 0x4, 0x90, - 0x0, 0xc, 0x1, 0x51, 0xc0, 0x4, 0x80, 0x0, - 0xc, 0x57, 0x8, 0x50, 0x5, 0x70, 0x0, 0x1f, - 0x60, 0x2b, 0x0, 0x7, 0x50, 0x0, 0x3, 0x1, - 0xa1, 0x4, 0x3c, 0x30, 0x0, 0x0, 0x36, 0x0, - 0x1, 0xca, 0x0, 0x0, 0x0, 0x10, 0x0, 0x0, - 0x0, 0x0, - - /* U+520A "刊" */ - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x10, 0x3, - 0x55, 0x55, 0x96, 0x0, 0x1, 0xd0, 0x0, 0x10, - 0xc0, 0x0, 0x7, 0x1, 0xb0, 0x0, 0x0, 0xc0, - 0x0, 0xc, 0x1, 0xb0, 0x0, 0x0, 0xc0, 0x0, - 0xb, 0x1, 0xb0, 0x0, 0x0, 0xc0, 0x17, 0xb, - 0x1, 0xb0, 0x6, 0x55, 0xd5, 0x55, 0x1b, 0x1, - 0xb0, 0x0, 0x0, 0xc0, 0x0, 0xb, 0x1, 0xb0, - 0x0, 0x0, 0xc0, 0x0, 0xc, 0x1, 0xb0, 0x0, - 0x0, 0xc0, 0x0, 0x1b, 0x1, 0xb0, 0x0, 0x0, - 0xc0, 0x0, 0x0, 0x1, 0xb0, 0x0, 0x0, 0xc0, - 0x0, 0x0, 0x13, 0xa0, 0x0, 0x0, 0xd0, 0x0, - 0x1, 0x6e, 0x60, 0x0, 0x0, 0x10, 0x0, 0x0, - 0x2, 0x0, - - /* U+5217 "列" */ - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x6, 0x10, 0x1, 0xc0, 0x3, 0x65, - 0xe5, 0x55, 0x30, 0x1, 0xa0, 0x0, 0x3, 0xb0, - 0x0, 0xb, 0x1, 0xa0, 0x0, 0x8, 0x95, 0x75, - 0xb, 0x1, 0xa0, 0x0, 0xc, 0x0, 0x94, 0xb, - 0x1, 0xa0, 0x0, 0x79, 0x10, 0xc0, 0xb, 0x1, - 0xa0, 0x1, 0x62, 0xb3, 0x90, 0xb, 0x1, 0xa0, - 0x4, 0x0, 0x7b, 0x20, 0xb, 0x1, 0xa0, 0x0, - 0x0, 0x48, 0x0, 0xc, 0x1, 0xa0, 0x0, 0x2, - 0xa0, 0x0, 0x4, 0x1, 0xa0, 0x0, 0x38, 0x0, - 0x0, 0x3, 0x24, 0xa0, 0x4, 0x40, 0x0, 0x0, - 0x1, 0x6f, 0x50, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x1, 0x0, - - /* U+521D "初" */ - 0x0, 0x22, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0xc, 0x30, 0x0, 0x0, 0x0, 0x0, 0x0, 0x4, - 0x40, 0x45, 0x65, 0x55, 0xb1, 0x17, 0x55, 0xb7, - 0x0, 0xc0, 0x0, 0xc0, 0x0, 0x2, 0xb0, 0x0, - 0xc0, 0x0, 0xb0, 0x0, 0xc, 0x16, 0x50, 0xb0, - 0x1, 0xa0, 0x0, 0x7e, 0x19, 0x2, 0x90, 0x2, - 0x90, 0x6, 0x4b, 0x95, 0x5, 0x60, 0x4, 0x80, - 0x32, 0xb, 0xb, 0x38, 0x20, 0x5, 0x70, 0x0, - 0xb, 0x0, 0xa, 0x0, 0x6, 0x60, 0x0, 0xb, - 0x0, 0x64, 0x0, 0x8, 0x40, 0x0, 0xb, 0x2, - 0x70, 0x13, 0x1b, 0x10, 0x0, 0xb, 0x25, 0x0, - 0x4, 0xea, 0x0, 0x0, 0x1, 0x0, 0x0, 0x0, - 0x0, 0x0, - - /* U+5224 "判" */ - 0x0, 0x0, 0x20, 0x0, 0x0, 0x1, 0x20, 0x0, - 0x0, 0xb2, 0x0, 0x0, 0x2, 0xb0, 0x3, 0x50, - 0xb0, 0x3b, 0x2, 0x1, 0x90, 0x0, 0xc3, 0xb0, - 0x92, 0xc, 0x11, 0x90, 0x0, 0x62, 0xb3, 0x30, - 0xb, 0x1, 0x90, 0x2, 0x55, 0xc5, 0x6b, 0xb, - 0x1, 0x90, 0x0, 0x0, 0xb0, 0x0, 0xb, 0x1, - 0x90, 0x0, 0x0, 0xb0, 0x3, 0xb, 0x1, 0x90, - 0x17, 0x55, 0xc5, 0x58, 0x3b, 0x1, 0x90, 0x0, - 0x4, 0x70, 0x0, 0xc, 0x1, 0x90, 0x0, 0xa, - 0x0, 0x0, 0x6, 0x1, 0x90, 0x0, 0x73, 0x0, - 0x0, 0x0, 0x2, 0x90, 0x6, 0x20, 0x0, 0x0, - 0x0, 0x7f, 0x50, 0x10, 0x0, 0x0, 0x0, 0x0, - 0x2, 0x0, - - /* U+5225 "別" */ - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x85, 0x55, 0x59, 0x0, 0x0, 0xc0, 0x0, 0xb0, - 0x0, 0x1a, 0x0, 0x0, 0xb0, 0x0, 0xb0, 0x0, - 0x1a, 0xa, 0x0, 0xb0, 0x0, 0xd5, 0x55, 0x6a, - 0xb, 0x0, 0xb0, 0x0, 0x68, 0x10, 0x4, 0xb, - 0x0, 0xb0, 0x0, 0xd, 0x0, 0x0, 0xb, 0x0, - 0xb0, 0x0, 0xd, 0x55, 0x6a, 0xb, 0x0, 0xb0, - 0x0, 0x39, 0x0, 0x46, 0xb, 0x0, 0xb0, 0x0, - 0x75, 0x0, 0x74, 0xa, 0x0, 0xb0, 0x0, 0xb0, - 0x0, 0xa1, 0x0, 0x0, 0xb0, 0x4, 0x50, 0x22, - 0xc0, 0x0, 0x12, 0xb0, 0x7, 0x0, 0x1d, 0x50, - 0x0, 0x5e, 0x70, 0x10, 0x0, 0x0, 0x0, 0x0, - 0x1, 0x0, - - /* U+5229 "利" */ - 0x0, 0x0, 0x0, 0x40, 0x0, 0x4, 0x0, 0x2, - 0x59, 0xba, 0x40, 0x0, 0xb3, 0x3, 0x21, 0xc0, - 0x0, 0x6, 0xa, 0x10, 0x0, 0xc, 0x0, 0x0, - 0xb0, 0xa1, 0x25, 0x55, 0xd5, 0x6c, 0x1b, 0xa, - 0x10, 0x10, 0x1f, 0x0, 0x0, 0xb0, 0xa1, 0x0, - 0x7, 0xf5, 0x10, 0xb, 0xa, 0x10, 0x1, 0xac, - 0x1d, 0x40, 0xb0, 0xa1, 0x0, 0x91, 0xc0, 0x36, - 0xb, 0xa, 0x10, 0x62, 0xc, 0x0, 0x0, 0x90, - 0xa1, 0x31, 0x0, 0xc0, 0x0, 0x0, 0xa, 0x10, - 0x0, 0xc, 0x0, 0x0, 0x44, 0xd1, 0x0, 0x0, - 0xc0, 0x0, 0x0, 0x7d, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x0, - - /* U+5230 "到" */ - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x20, 0x4, - 0x55, 0x55, 0x6b, 0x0, 0x0, 0xd0, 0x1, 0x0, - 0xd2, 0x0, 0x5, 0x0, 0xb0, 0x0, 0x8, 0x42, - 0x10, 0xc, 0x10, 0xb0, 0x0, 0x53, 0x0, 0x93, - 0xb, 0x0, 0xb0, 0x6, 0xd8, 0xa6, 0x5e, 0xb, - 0x0, 0xb0, 0x0, 0x0, 0xc1, 0x5, 0xb, 0x0, - 0xb0, 0x0, 0x0, 0xc0, 0x2, 0xb, 0x0, 0xb0, - 0x4, 0x55, 0xd5, 0x67, 0xb, 0x0, 0xb0, 0x0, - 0x0, 0xc0, 0x0, 0xc, 0x0, 0xb0, 0x0, 0x0, - 0xc0, 0x14, 0x2, 0x0, 0xb0, 0x4, 0x68, 0xb7, - 0x40, 0x0, 0x1, 0xb0, 0xa, 0x72, 0x0, 0x0, - 0x1, 0x7f, 0x70, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x2, 0x0, - - /* U+5236 "制" */ - 0x0, 0x0, 0x10, 0x0, 0x0, 0x3, 0x0, 0x0, - 0xb, 0x0, 0x0, 0x0, 0xb1, 0x3, 0xa0, 0xa0, - 0x0, 0x2, 0xb, 0x0, 0x87, 0x5c, 0x6a, 0x0, - 0xc0, 0xb0, 0x7, 0x0, 0xa0, 0x0, 0xa, 0xb, - 0x3, 0x65, 0x5c, 0x57, 0x80, 0xa0, 0xb0, 0x0, - 0x0, 0xa0, 0x10, 0xa, 0xb, 0x0, 0x95, 0x5c, - 0x5c, 0x20, 0xa0, 0xb0, 0x9, 0x10, 0xa0, 0xa0, - 0xa, 0xb, 0x0, 0x91, 0xa, 0xa, 0x0, 0xa0, - 0xb0, 0x9, 0x10, 0xb5, 0xc0, 0x0, 0xb, 0x0, - 0x60, 0xa, 0x26, 0x0, 0x0, 0xc0, 0x0, 0x0, - 0xa0, 0x0, 0x3, 0xad, 0x0, 0x0, 0x1, 0x0, - 0x0, 0x0, 0x10, - - /* U+5238 "券" */ - 0x0, 0x0, 0x0, 0x60, 0x1, 0x0, 0x0, 0x0, - 0x1a, 0x10, 0xe1, 0xc, 0x20, 0x0, 0x0, 0x5, - 0x92, 0xa0, 0x63, 0x0, 0x0, 0x2, 0x55, 0x69, - 0x95, 0x75, 0xa8, 0x0, 0x0, 0x10, 0xb, 0x10, - 0x0, 0x0, 0x0, 0x15, 0x55, 0x5d, 0x55, 0x55, - 0x5b, 0x80, 0x1, 0x0, 0xa2, 0x0, 0x52, 0x0, - 0x0, 0x0, 0x8, 0x40, 0x0, 0x9, 0x71, 0x0, - 0x1, 0x84, 0x5b, 0x55, 0x5e, 0x7e, 0xb2, 0x14, - 0x0, 0xc, 0x0, 0xc, 0x0, 0x20, 0x0, 0x0, - 0x66, 0x0, 0x1a, 0x0, 0x0, 0x0, 0x3, 0xa0, - 0x0, 0x48, 0x0, 0x0, 0x1, 0x67, 0x0, 0x18, - 0xf3, 0x0, 0x0, 0x3, 0x0, 0x0, 0x0, 0x10, - 0x0, 0x0, - - /* U+523B "刻" */ - 0x0, 0x1, 0x0, 0x0, 0x0, 0x0, 0x20, 0x0, - 0x1, 0xb0, 0x0, 0x0, 0x0, 0xc0, 0x0, 0x0, - 0x81, 0x5, 0x2, 0x0, 0xb0, 0x16, 0x57, 0xc5, - 0x56, 0x2a, 0x40, 0xb0, 0x0, 0xa, 0x30, 0x50, - 0x9, 0x20, 0xb0, 0x0, 0x64, 0x4, 0xb1, 0x9, - 0x20, 0xb0, 0x3, 0xd6, 0x5c, 0x11, 0x9, 0x20, - 0xb0, 0x0, 0x0, 0xa3, 0x6c, 0x9, 0x20, 0xb0, - 0x0, 0x9, 0x31, 0xc1, 0x9, 0x20, 0xb0, 0x2, - 0x81, 0xc, 0x20, 0x9, 0x20, 0xb0, 0x23, 0x1, - 0xa4, 0xa1, 0x1, 0x0, 0xb0, 0x0, 0x49, 0x10, - 0x5a, 0x0, 0x1, 0xa0, 0x16, 0x30, 0x0, 0x3, - 0x0, 0x6d, 0x80, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x2, 0x0, - - /* U+5247 "則" */ - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x10, 0x0, - 0x95, 0x55, 0xa2, 0x0, 0x0, 0xd0, 0x0, 0xb0, - 0x0, 0xb0, 0x1, 0x0, 0xb0, 0x0, 0xc5, 0x55, - 0xc0, 0xd, 0x0, 0xb0, 0x0, 0xb0, 0x0, 0xb0, - 0xb, 0x0, 0xb0, 0x0, 0xc5, 0x55, 0xc0, 0xb, - 0x0, 0xb0, 0x0, 0xb0, 0x0, 0xb0, 0xb, 0x0, - 0xb0, 0x0, 0xb0, 0x0, 0xb0, 0xb, 0x0, 0xb0, - 0x0, 0xc5, 0x55, 0xc0, 0xb, 0x0, 0xb0, 0x0, - 0x53, 0x2, 0x40, 0x8, 0x0, 0xb0, 0x0, 0x4b, - 0x7, 0x50, 0x0, 0x0, 0xb0, 0x0, 0x90, 0x0, - 0xc4, 0x0, 0x0, 0xb0, 0x6, 0x0, 0x0, 0x38, - 0x0, 0x6e, 0x90, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x2, 0x0, - - /* U+524A "削" */ - 0x0, 0x3, 0x0, 0x0, 0x0, 0x0, 0x2, 0x0, - 0xc2, 0x6, 0x0, 0x0, 0xc0, 0x1b, 0xb, 0x3, - 0xa0, 0x0, 0xb, 0x0, 0x84, 0xb0, 0x70, 0xa, - 0x10, 0xb0, 0x8, 0x5d, 0x65, 0x90, 0xb0, 0xb, - 0x0, 0xb0, 0x0, 0xc, 0xb, 0x0, 0xb0, 0xd, - 0x55, 0x55, 0xc0, 0xb0, 0xb, 0x0, 0xb0, 0x0, - 0xc, 0xb, 0x0, 0xb0, 0xb, 0x0, 0x0, 0xc0, - 0xb0, 0xb, 0x0, 0xd5, 0x55, 0x5c, 0xc, 0x0, - 0xb0, 0xb, 0x0, 0x0, 0xc0, 0x60, 0xb, 0x0, - 0xb0, 0x1, 0x2c, 0x0, 0x12, 0xa0, 0x1b, 0x0, - 0x3d, 0x70, 0x5, 0xe7, 0x0, 0x10, 0x0, 0x0, - 0x0, 0x1, 0x0, - - /* U+524D "前" */ - 0x0, 0x0, 0x10, 0x0, 0x3, 0x0, 0x0, 0x0, - 0x0, 0x85, 0x0, 0x3e, 0x20, 0x0, 0x0, 0x0, - 0x1c, 0x0, 0x91, 0x0, 0x40, 0x6, 0x55, 0x55, - 0x55, 0x65, 0x56, 0x92, 0x0, 0x30, 0x3, 0x10, - 0x0, 0x19, 0x0, 0x0, 0xb5, 0x5b, 0x30, 0xa2, - 0x1a, 0x0, 0x0, 0xb0, 0x9, 0x10, 0xb0, 0x1a, - 0x0, 0x0, 0xb5, 0x5b, 0x10, 0xb0, 0x1a, 0x0, - 0x0, 0xb0, 0x9, 0x10, 0xb0, 0x1a, 0x0, 0x0, - 0xb5, 0x5b, 0x10, 0xb0, 0x1a, 0x0, 0x0, 0xb0, - 0x9, 0x10, 0xb0, 0x1a, 0x0, 0x0, 0xb0, 0x9, - 0x10, 0x11, 0x3a, 0x0, 0x0, 0xb0, 0x6d, 0x0, - 0x6, 0xf5, 0x0, 0x0, 0x10, 0x1, 0x0, 0x0, - 0x10, 0x0, - - /* U+525B "剛" */ - 0x0, 0x0, 0x0, 0x0, 0x0, 0x1, 0xa, 0x55, - 0x55, 0x5c, 0x20, 0x0, 0xc0, 0xb1, 0x40, 0x61, - 0xb0, 0x10, 0xb, 0xb, 0xa, 0x1a, 0xb, 0xa, - 0x10, 0xb0, 0xb2, 0x66, 0x76, 0xb0, 0xa0, 0xb, - 0xb, 0x12, 0xa1, 0x1b, 0xa, 0x0, 0xb0, 0xb1, - 0x19, 0x22, 0xb0, 0xa0, 0xb, 0xb, 0x55, 0x94, - 0x5b, 0xa, 0x0, 0xb0, 0xb5, 0x49, 0x45, 0xb0, - 0xa0, 0xb, 0xb, 0x68, 0xa8, 0x5b, 0x8, 0x0, - 0xb0, 0xb0, 0x0, 0x11, 0xb0, 0x0, 0xb, 0xb, - 0x0, 0x0, 0xb, 0x0, 0x2, 0xa0, 0xa0, 0x0, - 0x2a, 0xd0, 0x27, 0xe7, 0x0, 0x0, 0x0, 0x11, - 0x0, 0x1, 0x0, - - /* U+5272 "割" */ - 0x0, 0x2, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x1, 0xb0, 0x0, 0x0, 0x0, 0xc0, 0x6, 0x55, - 0x75, 0x5a, 0x21, 0x0, 0xb0, 0x1b, 0x0, 0xb1, - 0x4, 0xb, 0x30, 0xb0, 0x3, 0x55, 0xc5, 0x67, - 0xa, 0x0, 0xb0, 0x0, 0x0, 0xb0, 0x0, 0xa, - 0x0, 0xb0, 0x1, 0x55, 0xc5, 0x73, 0xa, 0x0, - 0xb0, 0x0, 0x0, 0xb0, 0x4, 0x2a, 0x0, 0xb0, - 0x6, 0x55, 0xd5, 0x55, 0x3b, 0x0, 0xb0, 0x0, - 0x95, 0x65, 0xa1, 0xa, 0x10, 0xb0, 0x0, 0xb0, - 0x0, 0xb0, 0x0, 0x0, 0xb0, 0x0, 0xb0, 0x0, - 0xb0, 0x0, 0x0, 0xb0, 0x0, 0xd5, 0x55, 0xc0, - 0x0, 0x6c, 0xa0, 0x0, 0x10, 0x0, 0x0, 0x0, - 0x2, 0x0, - - /* U+5275 "創" */ - 0x0, 0x0, 0x20, 0x0, 0x0, 0x0, 0x10, 0x0, - 0x0, 0xd5, 0x0, 0x0, 0x0, 0xc0, 0x0, 0x6, - 0x73, 0xa3, 0x0, 0x0, 0xa0, 0x0, 0x29, 0x45, - 0x1c, 0xb, 0x0, 0xa0, 0x1, 0x80, 0xa, 0x1, - 0xa, 0x0, 0xa0, 0x15, 0x86, 0x55, 0x5a, 0xa, - 0x0, 0xa0, 0x0, 0x86, 0x55, 0x59, 0xa, 0x0, - 0xa0, 0x0, 0x82, 0x0, 0x9, 0xa, 0x0, 0xa0, - 0x0, 0x96, 0x55, 0x58, 0xb, 0x0, 0xa0, 0x0, - 0xb7, 0x55, 0x57, 0x6, 0x0, 0xa0, 0x1, 0xa9, - 0x0, 0xa, 0x0, 0x0, 0xa0, 0x6, 0x39, 0x0, - 0xa, 0x0, 0x0, 0xa0, 0x15, 0x1b, 0x55, 0x5a, - 0x1, 0x7d, 0x70, 0x10, 0x0, 0x0, 0x0, 0x0, - 0x1, 0x0, - - /* U+5283 "劃" */ - 0x0, 0x0, 0x30, 0x0, 0x0, 0x0, 0x10, 0x0, - 0x0, 0xa2, 0x2, 0x0, 0x0, 0xc0, 0x0, 0x55, - 0xb5, 0x5c, 0x0, 0x0, 0xa0, 0x6, 0x55, 0xb5, - 0x5c, 0x92, 0x90, 0xa0, 0x0, 0x33, 0xb4, 0x3b, - 0x0, 0xa0, 0xa0, 0x0, 0x22, 0xa2, 0x35, 0x0, - 0xa0, 0xa0, 0x0, 0x55, 0xb5, 0x54, 0x40, 0xa0, - 0xa0, 0x5, 0x75, 0x55, 0x57, 0x51, 0xa0, 0xa0, - 0x0, 0xc5, 0xc5, 0x5c, 0x0, 0xa0, 0xa0, 0x0, - 0xc5, 0xc5, 0x5a, 0x0, 0x60, 0xa0, 0x0, 0xc5, - 0xc5, 0x5a, 0x0, 0x0, 0xa0, 0x0, 0x40, 0x0, - 0x27, 0x20, 0x11, 0xb0, 0x7, 0xb9, 0x75, 0x31, - 0x0, 0x4d, 0x80, 0x1, 0x0, 0x0, 0x0, 0x0, - 0x1, 0x0, - - /* U+529B "力" */ - 0x0, 0x0, 0x0, 0x41, 0x0, 0x0, 0x0, 0x0, - 0x0, 0xb, 0x50, 0x0, 0x0, 0x0, 0x0, 0x0, - 0xb2, 0x0, 0x0, 0x0, 0x0, 0x0, 0xb, 0x10, - 0x0, 0x10, 0x1, 0x75, 0x55, 0xd5, 0x55, 0x5d, - 0x40, 0x0, 0x0, 0xc, 0x0, 0x0, 0xd0, 0x0, - 0x0, 0x3, 0x90, 0x0, 0xd, 0x0, 0x0, 0x0, - 0x84, 0x0, 0x0, 0xd0, 0x0, 0x0, 0x1c, 0x0, - 0x0, 0x2b, 0x0, 0x0, 0x9, 0x40, 0x0, 0x4, - 0xa0, 0x0, 0x4, 0x80, 0x0, 0x0, 0x67, 0x0, - 0x4, 0x80, 0x0, 0x36, 0x4d, 0x30, 0x5, 0x50, - 0x0, 0x0, 0x4f, 0x80, 0x1, 0x0, 0x0, 0x0, - 0x0, 0x10, 0x0, - - /* U+529F "功" */ - 0x0, 0x0, 0x0, 0x0, 0x20, 0x0, 0x0, 0x0, - 0x0, 0x0, 0xb, 0x30, 0x0, 0x0, 0x0, 0x4, - 0x0, 0xa1, 0x0, 0x0, 0x65, 0xc5, 0x52, 0xa, - 0x0, 0x0, 0x0, 0xa, 0x0, 0x55, 0xc5, 0x5a, - 0x50, 0x0, 0xa0, 0x0, 0xb, 0x0, 0x92, 0x0, - 0xa, 0x0, 0x0, 0xb0, 0xa, 0x10, 0x0, 0xa0, - 0x0, 0x1a, 0x0, 0xb0, 0x0, 0xa, 0x3, 0x25, - 0x60, 0xc, 0x0, 0x26, 0xc6, 0x10, 0xb0, 0x0, - 0xc0, 0x2c, 0x50, 0x0, 0x65, 0x0, 0xc, 0x0, - 0x0, 0x0, 0x47, 0x4, 0x23, 0xb0, 0x0, 0x0, - 0x54, 0x0, 0x18, 0xf4, 0x0, 0x0, 0x10, 0x0, - 0x0, 0x1, 0x0, - - /* U+52A0 "加" */ - 0x0, 0x3, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0xb, 0x20, 0x0, 0x0, 0x0, 0x0, 0x0, 0xb, - 0x0, 0x0, 0x0, 0x0, 0x0, 0x5, 0x5d, 0x55, - 0x91, 0xb5, 0x55, 0xc0, 0x0, 0xb, 0x0, 0xb0, - 0xb0, 0x0, 0xb0, 0x0, 0xc, 0x0, 0xb0, 0xb0, - 0x0, 0xb0, 0x0, 0xc, 0x0, 0xb0, 0xb0, 0x0, - 0xb0, 0x0, 0xb, 0x0, 0xa0, 0xb0, 0x0, 0xb0, - 0x0, 0x29, 0x1, 0x90, 0xb0, 0x0, 0xb0, 0x0, - 0x64, 0x2, 0x80, 0xb0, 0x0, 0xb0, 0x0, 0xa0, - 0x5, 0x60, 0xb0, 0x0, 0xb0, 0x5, 0x44, 0x7c, - 0x30, 0xc5, 0x55, 0xb0, 0x15, 0x0, 0x66, 0x0, - 0xb0, 0x0, 0x70, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, - - /* U+52A8 "动" */ - 0x0, 0x0, 0x0, 0x0, 0x1, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x0, 0xd, 0x0, 0x0, 0x3, 0x65, - 0x5a, 0x50, 0xb, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0xb, 0x0, 0x10, 0x0, 0x0, 0x0, 0x15, - 0x5c, 0x55, 0xd0, 0x5, 0x57, 0x65, 0x92, 0xb, - 0x0, 0xb0, 0x0, 0xb, 0x60, 0x0, 0x19, 0x0, - 0xb0, 0x0, 0x29, 0x2, 0x0, 0x46, 0x0, 0xb0, - 0x0, 0x80, 0x8, 0x20, 0x82, 0x1, 0xa0, 0x5, - 0x32, 0x36, 0xd0, 0xa0, 0x1, 0xa0, 0xd, 0xb6, - 0x20, 0x96, 0x30, 0x3, 0x90, 0x0, 0x0, 0x0, - 0x36, 0x3, 0x17, 0x60, 0x0, 0x0, 0x4, 0x40, - 0x2, 0xcd, 0x10, 0x0, 0x0, 0x1, 0x0, 0x0, - 0x0, 0x0, - - /* U+52A9 "助" */ - 0x0, 0x0, 0x0, 0x0, 0x1, 0x0, 0x0, 0x0, - 0x30, 0x4, 0x0, 0xe, 0x0, 0x0, 0x0, 0xd5, - 0x5c, 0x20, 0xc, 0x0, 0x0, 0x0, 0xb0, 0xb, - 0x0, 0xc, 0x0, 0x0, 0x0, 0xb0, 0xb, 0x26, - 0x5d, 0x55, 0xc0, 0x0, 0xc5, 0x5c, 0x0, 0xc, - 0x0, 0xb0, 0x0, 0xb0, 0xb, 0x0, 0xc, 0x0, - 0xb0, 0x0, 0xc5, 0x5c, 0x0, 0x2a, 0x0, 0xb0, - 0x0, 0xb0, 0xb, 0x0, 0x56, 0x0, 0xb0, 0x0, - 0xb0, 0xb, 0x0, 0xb1, 0x0, 0xb0, 0x0, 0xb4, - 0x78, 0x46, 0x60, 0x2, 0x90, 0x1d, 0xa4, 0x0, - 0x36, 0x3, 0x59, 0x60, 0x1, 0x0, 0x5, 0x40, - 0x0, 0x5a, 0x0, 0x0, 0x0, 0x10, 0x0, 0x0, - 0x0, 0x0, - - /* U+52AA "努" */ - 0x0, 0x1, 0x10, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x8, 0x50, 0x1, 0x11, 0x14, 0x0, 0x5, 0x5c, - 0x57, 0x67, 0x44, 0x6d, 0x10, 0x1, 0x28, 0x9, - 0x30, 0x60, 0x93, 0x0, 0x0, 0x92, 0xb, 0x0, - 0x58, 0x80, 0x0, 0x0, 0x16, 0xca, 0x10, 0x2d, - 0x80, 0x0, 0x0, 0x18, 0x44, 0x76, 0x70, 0x5c, - 0x82, 0x14, 0x50, 0x1, 0xa4, 0x0, 0x0, 0x20, - 0x0, 0x35, 0x55, 0xc8, 0x55, 0x75, 0x0, 0x0, - 0x10, 0x1, 0xc0, 0x0, 0x85, 0x0, 0x0, 0x0, - 0x9, 0x50, 0x0, 0xa3, 0x0, 0x0, 0x0, 0x87, - 0x1, 0x31, 0xd0, 0x0, 0x2, 0x57, 0x20, 0x0, - 0x6f, 0x60, 0x0, 0x1, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, - - /* U+52B3 "劳" */ - 0x0, 0x0, 0x40, 0x0, 0x30, 0x0, 0x0, 0x0, - 0xc, 0x0, 0xd, 0x0, 0x0, 0x35, 0x55, 0xc5, - 0x55, 0xc5, 0x6d, 0x20, 0x0, 0xb, 0x0, 0xb, - 0x0, 0x0, 0x2, 0x0, 0x60, 0x0, 0x50, 0x2, - 0x0, 0x95, 0x55, 0x65, 0x55, 0x56, 0xe1, 0x3b, - 0x0, 0xb, 0x40, 0x0, 0x51, 0x0, 0x0, 0x0, - 0xc1, 0x0, 0x21, 0x0, 0x4, 0x65, 0x5e, 0x55, - 0x5b, 0x60, 0x0, 0x0, 0x2, 0xb0, 0x0, 0xa2, - 0x0, 0x0, 0x0, 0xa4, 0x0, 0xc, 0x0, 0x0, - 0x0, 0x78, 0x1, 0x1, 0xd0, 0x0, 0x3, 0x84, - 0x0, 0x7, 0xf7, 0x0, 0x3, 0x20, 0x0, 0x0, - 0x2, 0x0, 0x0, - - /* U+52C9 "勉" */ - 0x0, 0x4, 0x0, 0x0, 0x2, 0x0, 0x0, 0x0, - 0x2c, 0x0, 0x0, 0xc, 0x10, 0x0, 0x0, 0x97, - 0x5d, 0x20, 0xa, 0x0, 0x0, 0x2, 0x80, 0x35, - 0x0, 0xa, 0x2, 0x0, 0x7, 0xa5, 0xa5, 0xb5, - 0x5c, 0x5a, 0x40, 0x10, 0xb0, 0xb0, 0xa0, 0xa, - 0x8, 0x10, 0x0, 0xb0, 0xb0, 0xa0, 0xa, 0x8, - 0x10, 0x0, 0xc5, 0xd8, 0xc0, 0x46, 0x9, 0x10, - 0x0, 0x23, 0x98, 0x10, 0x91, 0xa, 0x0, 0x0, - 0x8, 0x48, 0x2, 0x81, 0x1b, 0x0, 0x0, 0x19, - 0x28, 0x7, 0x0, 0xa7, 0x40, 0x0, 0x81, 0x18, - 0x30, 0x0, 0x0, 0x80, 0x6, 0x20, 0xb, 0x88, - 0x88, 0x8a, 0xa0, 0x10, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, - - /* U+52D5 "動" */ - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x2, 0x6b, 0x80, 0xc, 0x10, 0x0, 0x3, 0x4b, - 0x30, 0x0, 0xc, 0x0, 0x0, 0x26, 0x5b, 0x65, - 0xa2, 0xb, 0x0, 0x30, 0x1, 0x9, 0x10, 0x24, - 0x6c, 0x55, 0xd0, 0xb, 0x5b, 0x65, 0xc0, 0xb, - 0x0, 0xb0, 0xa, 0x5b, 0x65, 0xa0, 0xb, 0x0, - 0xa0, 0xa, 0x9, 0x10, 0xa0, 0x19, 0x0, 0xa0, - 0xa, 0x5b, 0x65, 0x90, 0x55, 0x0, 0xa0, 0x0, - 0x9, 0x10, 0x40, 0xa0, 0x2, 0x80, 0x6, 0x5b, - 0x65, 0x52, 0x80, 0x4, 0x60, 0x0, 0x1a, 0x65, - 0x48, 0x3, 0x1a, 0x30, 0x1d, 0x94, 0x0, 0x52, - 0x2, 0xca, 0x0, 0x0, 0x0, 0x0, 0x10, 0x0, - 0x10, 0x0, - - /* U+52D9 "務" */ - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x2, - 0x44, 0x46, 0x10, 0xd1, 0x0, 0x0, 0x1, 0x20, - 0x2a, 0x45, 0xa5, 0x5d, 0x20, 0x0, 0x19, 0x70, - 0x7, 0x60, 0x38, 0x0, 0x0, 0x1, 0xd0, 0x20, - 0x28, 0xb0, 0x0, 0x5, 0x57, 0x97, 0x70, 0x1a, - 0xb1, 0x0, 0x0, 0xc, 0xa5, 0x14, 0x91, 0x2c, - 0xa4, 0x0, 0x29, 0xa1, 0x63, 0x76, 0x0, 0x40, - 0x0, 0x92, 0xa0, 0x46, 0xc6, 0x5c, 0x30, 0x3, - 0x51, 0xa0, 0x0, 0xb0, 0xb, 0x0, 0x5, 0x1, - 0xa0, 0x5, 0x60, 0xb, 0x0, 0x0, 0x23, 0xa0, - 0x29, 0x0, 0x1b, 0x0, 0x0, 0x4d, 0x63, 0x60, - 0x7, 0xe6, 0x0, 0x0, 0x0, 0x1, 0x0, 0x0, - 0x10, 0x0, - - /* U+52DD "勝" */ - 0x0, 0x0, 0x0, 0x0, 0x20, 0x0, 0x0, 0x8, - 0x55, 0xb0, 0x81, 0xc1, 0x76, 0x0, 0x9, 0x10, - 0xa0, 0x3a, 0xb2, 0x70, 0x0, 0x9, 0x10, 0xa2, - 0x57, 0xc6, 0x78, 0x0, 0x9, 0x65, 0xa0, 0x12, - 0x80, 0x2, 0x0, 0x9, 0x10, 0xb6, 0x5a, 0x77, - 0x58, 0x50, 0x9, 0x10, 0xa0, 0x2a, 0x25, 0x30, - 0x0, 0x9, 0x65, 0xa1, 0x83, 0xa0, 0x7b, 0x60, - 0xa, 0x0, 0xb6, 0x77, 0xa5, 0x95, 0x30, 0xa, - 0x0, 0xa0, 0x7, 0x20, 0xa0, 0x0, 0x9, 0x0, - 0xa0, 0xa, 0x0, 0xa0, 0x0, 0x15, 0x0, 0xa0, - 0x82, 0x0, 0xb0, 0x0, 0x40, 0x3c, 0x66, 0x20, - 0x5c, 0x80, 0x0, 0x10, 0x1, 0x10, 0x0, 0x2, - 0x0, 0x0, - - /* U+52E4 "勤" */ - 0x0, 0x12, 0x3, 0x0, 0x3, 0x0, 0x0, 0x0, - 0x38, 0x8, 0x13, 0xa, 0x30, 0x0, 0x6, 0x7a, - 0x5b, 0x67, 0xa, 0x0, 0x0, 0x0, 0x3a, 0x5b, - 0x0, 0xb, 0x0, 0x0, 0x0, 0x22, 0xa2, 0x22, - 0x6c, 0x55, 0xc2, 0x1, 0xb5, 0xc5, 0xb3, 0xb, - 0x0, 0xb0, 0x1, 0xa0, 0xa0, 0x91, 0xb, 0x0, - 0xb0, 0x1, 0xa5, 0xc5, 0x91, 0xb, 0x0, 0xb0, - 0x2, 0x65, 0xc5, 0x86, 0xa, 0x0, 0xb0, 0x0, - 0x0, 0xa0, 0x40, 0x47, 0x0, 0xb0, 0x0, 0x65, - 0xc5, 0x52, 0x91, 0x0, 0xc0, 0x0, 0x2, 0xb5, - 0x47, 0x63, 0x36, 0xa0, 0xb, 0xa6, 0x30, 0x35, - 0x0, 0x7d, 0x10, 0x0, 0x0, 0x0, 0x20, 0x0, - 0x0, 0x0, - - /* U+52F5 "勵" */ - 0x0, 0x0, 0x0, 0x0, 0x1, 0x0, 0x0, 0x6, - 0x55, 0x55, 0x5a, 0xb, 0x20, 0x0, 0x9, 0x0, - 0x60, 0x60, 0xa, 0x0, 0x0, 0x9, 0x56, 0xa5, - 0xb7, 0xa, 0x0, 0x10, 0x8, 0x0, 0x30, 0x42, - 0x6c, 0x55, 0xb2, 0x8, 0xb, 0x59, 0x75, 0xa, - 0x0, 0xa0, 0x9, 0xc, 0x5a, 0x74, 0xa, 0x0, - 0xa0, 0x9, 0xc, 0x5a, 0x74, 0xa, 0x0, 0xa0, - 0x9, 0x2, 0x17, 0x11, 0x9, 0x0, 0xa0, 0x8, - 0x77, 0x5a, 0x5a, 0x46, 0x0, 0xa0, 0x7, 0x74, - 0x3a, 0x59, 0x81, 0x0, 0xa0, 0x32, 0x75, 0x61, - 0x59, 0x81, 0x14, 0x80, 0x20, 0x73, 0x0, 0x8b, - 0x10, 0x7d, 0x10, 0x0, 0x10, 0x0, 0x1, 0x0, - 0x0, 0x0, - - /* U+5305 "包" */ - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0xd2, 0x0, 0x0, 0x0, 0x0, 0x0, 0x5, - 0x90, 0x0, 0x0, 0x30, 0x0, 0x0, 0xc, 0x55, - 0x55, 0x55, 0xc4, 0x0, 0x0, 0x84, 0x0, 0x1, - 0x0, 0xa1, 0x0, 0x4, 0x6c, 0x55, 0x5c, 0x30, - 0xb0, 0x0, 0x25, 0xb, 0x0, 0xb, 0x0, 0xb0, - 0x0, 0x0, 0xb, 0x0, 0xb, 0x0, 0xc0, 0x0, - 0x0, 0xb, 0x55, 0x5b, 0x20, 0xc0, 0x0, 0x0, - 0xb, 0x0, 0x0, 0x4a, 0xa0, 0x30, 0x0, 0xb, - 0x0, 0x0, 0x3, 0x0, 0x60, 0x0, 0xb, 0x0, - 0x0, 0x0, 0x1, 0xc0, 0x0, 0x5, 0xba, 0xaa, - 0xaa, 0xbd, 0xb1, - - /* U+5316 "化" */ - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0xc0, 0xa, 0x30, 0x0, 0x0, 0x0, 0x6, - 0x80, 0xa, 0x10, 0x0, 0x0, 0x0, 0xc, 0x10, - 0xa, 0x10, 0x12, 0x0, 0x0, 0x4b, 0x0, 0xa, - 0x10, 0xa8, 0x0, 0x0, 0xbd, 0x0, 0xa, 0x17, - 0x80, 0x0, 0x4, 0x4c, 0x0, 0xa, 0x79, 0x0, - 0x0, 0x6, 0xc, 0x0, 0xb, 0x80, 0x0, 0x0, - 0x10, 0xc, 0x0, 0x8d, 0x10, 0x0, 0x0, 0x0, - 0xc, 0x26, 0x1a, 0x10, 0x0, 0x30, 0x0, 0xc, - 0x10, 0xa, 0x10, 0x0, 0x60, 0x0, 0xc, 0x0, - 0xa, 0x20, 0x1, 0xb0, 0x0, 0xd, 0x0, 0x6, - 0xdb, 0xbc, 0xa0, 0x0, 0x5, 0x0, 0x0, 0x0, - 0x0, 0x0, - - /* U+5317 "北" */ - 0x0, 0x0, 0x2, 0x0, 0x10, 0x0, 0x0, 0x0, - 0x0, 0xe, 0x0, 0xd1, 0x0, 0x0, 0x0, 0x0, - 0xc, 0x0, 0xc0, 0x0, 0x0, 0x0, 0x0, 0xc, - 0x0, 0xc0, 0x0, 0x20, 0x3, 0x55, 0x5c, 0x0, - 0xc0, 0xb, 0xa0, 0x0, 0x0, 0xc, 0x0, 0xc3, - 0x83, 0x0, 0x0, 0x0, 0xc, 0x0, 0xc3, 0x0, - 0x0, 0x0, 0x0, 0xc, 0x0, 0xc0, 0x0, 0x0, - 0x0, 0x0, 0xc, 0x0, 0xc0, 0x0, 0x0, 0x0, - 0x0, 0xc, 0x0, 0xc0, 0x0, 0x40, 0x1, 0x58, - 0x5c, 0x0, 0xc0, 0x0, 0x60, 0xa, 0x60, 0xc, - 0x0, 0xc0, 0x0, 0xb1, 0x0, 0x0, 0xc, 0x0, - 0x9c, 0xbc, 0xd3, 0x0, 0x0, 0x4, 0x0, 0x0, - 0x0, 0x0, - - /* U+533B "医" */ - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x7, - 0x55, 0x55, 0x55, 0x55, 0x7c, 0x10, 0xb, 0x10, - 0xa, 0x10, 0x0, 0x0, 0x0, 0xb, 0x10, 0x1b, - 0x0, 0x0, 0x20, 0x0, 0xb, 0x10, 0x78, 0x59, - 0x57, 0x80, 0x0, 0xb, 0x10, 0x80, 0xb, 0x0, - 0x0, 0x0, 0xb, 0x14, 0x0, 0x1a, 0x0, 0x3, - 0x0, 0xb, 0x26, 0x55, 0x7b, 0x55, 0x58, 0x30, - 0xb, 0x10, 0x0, 0x79, 0x10, 0x0, 0x0, 0xb, - 0x10, 0x2, 0xb0, 0x7a, 0x30, 0x0, 0xb, 0x10, - 0x39, 0x0, 0x3, 0xe3, 0x0, 0xb, 0x15, 0x40, - 0x0, 0x0, 0x36, 0x10, 0xb, 0x55, 0x55, 0x55, - 0x55, 0x58, 0x60, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, - - /* U+5340 "區" */ - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x85, 0x55, - 0x55, 0x55, 0x58, 0x80, 0x92, 0x1, 0x0, 0x0, - 0x30, 0x0, 0x92, 0x5, 0x95, 0x55, 0xc0, 0x0, - 0x92, 0x5, 0x60, 0x0, 0xa0, 0x0, 0x92, 0x5, - 0x95, 0x55, 0xa0, 0x0, 0x92, 0x1, 0x10, 0x0, - 0x20, 0x0, 0x92, 0x85, 0x58, 0x85, 0x5a, 0x10, - 0x92, 0xa0, 0x19, 0xa0, 0xa, 0x0, 0x92, 0xa0, - 0x19, 0xa0, 0xa, 0x0, 0x92, 0xb5, 0x69, 0xa5, - 0x5c, 0x0, 0x92, 0x30, 0x1, 0x20, 0x1, 0x0, - 0xa6, 0x55, 0x55, 0x55, 0x55, 0xe3, 0x20, 0x0, - 0x0, 0x0, 0x0, 0x0, - - /* U+5341 "十" */ - 0x0, 0x0, 0x0, 0x30, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, 0xb4, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0xb1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0xb1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xb1, - 0x0, 0x0, 0x0, 0x25, 0x55, 0x55, 0xc6, 0x55, - 0x5a, 0x90, 0x1, 0x0, 0x0, 0xb1, 0x0, 0x0, - 0x0, 0x0, 0x0, 0x0, 0xb1, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x0, 0xb1, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, 0xb1, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0xb1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0xb1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xb2, - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, - - /* U+5343 "千" */ - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x25, 0x9e, 0xa0, 0x0, 0x0, 0x45, - 0x67, 0xd6, 0x20, 0x0, 0x0, 0x0, 0x0, 0x0, - 0xa2, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xa2, - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xa2, 0x0, - 0x5, 0x40, 0x36, 0x55, 0x55, 0xc7, 0x55, 0x55, - 0x50, 0x0, 0x0, 0x0, 0xa2, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x0, 0xa2, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, 0xa2, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0xa2, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0xa2, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xa3, - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x10, 0x0, - 0x0, 0x0, - - /* U+5348 "午" */ - 0x0, 0x0, 0x30, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0xe4, 0x0, 0x0, 0x0, 0x0, 0x0, 0x5, - 0x80, 0x0, 0x0, 0x62, 0x0, 0x0, 0xb, 0x55, - 0x6b, 0x55, 0x54, 0x0, 0x0, 0x73, 0x0, 0x2a, - 0x0, 0x0, 0x0, 0x3, 0x40, 0x0, 0x2a, 0x0, - 0x0, 0x0, 0x0, 0x0, 0x0, 0x2a, 0x0, 0x0, - 0x40, 0x6, 0x55, 0x55, 0x6c, 0x55, 0x56, 0x81, - 0x0, 0x0, 0x0, 0x2a, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x2a, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x2a, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x2a, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x2b, - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x11, 0x0, - 0x0, 0x0, - - /* U+534A "半" */ - 0x0, 0x0, 0x0, 0x30, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, 0xc2, 0x0, 0x20, 0x0, 0x0, 0x26, - 0x0, 0xc0, 0x5, 0xd1, 0x0, 0x0, 0x6, 0xb0, - 0xc0, 0xa, 0x10, 0x0, 0x0, 0x0, 0xb0, 0xc0, - 0x60, 0x0, 0x0, 0x2, 0x55, 0x55, 0xd5, 0x55, - 0x8a, 0x0, 0x0, 0x10, 0x0, 0xc0, 0x0, 0x0, - 0x0, 0x0, 0x0, 0x0, 0xc0, 0x0, 0x0, 0x0, - 0x16, 0x55, 0x55, 0xd5, 0x55, 0x5a, 0x90, 0x0, - 0x0, 0x0, 0xc0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0xc0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0xc0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xc0, - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x20, 0x0, - 0x0, 0x0, - - /* U+5352 "卒" */ - 0x0, 0x0, 0x0, 0x20, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x3a, 0x0, 0x1, 0x0, 0x0, 0x65, - 0x55, 0x59, 0x55, 0x6b, 0x20, 0x0, 0x0, 0x86, - 0x0, 0x1d, 0x0, 0x0, 0x0, 0x0, 0xd0, 0x0, - 0x77, 0x0, 0x0, 0x0, 0x6, 0x6a, 0x11, 0xa6, - 0x60, 0x0, 0x0, 0x18, 0x5, 0x78, 0x10, 0xa6, - 0x0, 0x0, 0x50, 0x0, 0x5a, 0x0, 0x13, 0x0, - 0x4, 0x55, 0x55, 0x5d, 0x55, 0x56, 0xd2, 0x1, - 0x0, 0x0, 0xc, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0xc, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0xc, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xc, - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x2, 0x0, - 0x0, 0x0, - - /* U+5354 "協" */ - 0x0, 0x10, 0x0, 0x0, 0x30, 0x0, 0x0, 0x0, - 0xa3, 0x0, 0x0, 0xc0, 0x0, 0x0, 0x0, 0xa1, - 0x3, 0x67, 0xa5, 0x5b, 0x20, 0x0, 0xa1, 0x0, - 0x9, 0x20, 0xa, 0x0, 0x26, 0xc5, 0x91, 0x56, - 0x0, 0x37, 0x0, 0x0, 0xa1, 0x15, 0x40, 0x18, - 0xc1, 0x0, 0x0, 0xa1, 0x24, 0x30, 0x0, 0x60, - 0x0, 0x0, 0xa1, 0x6a, 0x96, 0x75, 0xd5, 0x90, - 0x0, 0xa1, 0x9, 0x14, 0x50, 0xa0, 0x90, 0x0, - 0xa1, 0xa, 0x6, 0x32, 0x90, 0xa0, 0x0, 0xa1, - 0x27, 0x8, 0x17, 0x40, 0xa0, 0x0, 0xa1, 0x72, - 0x3b, 0x9, 0x0, 0xa0, 0x0, 0xa5, 0x30, 0x76, - 0x70, 0x5b, 0x60, 0x0, 0x21, 0x0, 0x2, 0x0, - 0x3, 0x0, - - /* U+5357 "南" */ - 0x0, 0x0, 0x0, 0x30, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, 0xa5, 0x0, 0x0, 0x0, 0x5, 0x55, - 0x55, 0xc6, 0x55, 0x5a, 0xc0, 0x1, 0x0, 0x0, - 0xb0, 0x0, 0x0, 0x0, 0x0, 0x75, 0x55, 0xd5, - 0x55, 0x59, 0x10, 0x0, 0xb0, 0x22, 0x0, 0x91, - 0xb, 0x0, 0x0, 0xb0, 0xc, 0x14, 0x80, 0xb, - 0x0, 0x0, 0xb0, 0x58, 0x5a, 0x5b, 0x1b, 0x0, - 0x0, 0xb0, 0x10, 0xa1, 0x0, 0xb, 0x0, 0x0, - 0xb4, 0x65, 0xc5, 0x59, 0x4b, 0x0, 0x0, 0xb0, - 0x0, 0xa1, 0x0, 0xb, 0x0, 0x0, 0xb0, 0x0, - 0xa1, 0x13, 0x2c, 0x0, 0x0, 0xb0, 0x0, 0x70, - 0x4, 0xd8, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x10, 0x0, - - /* U+5358 "単" */ - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x4, 0x50, 0xa1, 0x4, 0xc0, 0x0, 0x0, 0x0, - 0xb5, 0x68, 0xa, 0x20, 0x0, 0x0, 0x2, 0x23, - 0x12, 0x43, 0x30, 0x0, 0x0, 0xc, 0x55, 0xb6, - 0x55, 0xc2, 0x0, 0x0, 0xb, 0x0, 0x91, 0x0, - 0xb0, 0x0, 0x0, 0xc, 0x55, 0xb6, 0x55, 0xc0, - 0x0, 0x0, 0xb, 0x0, 0x91, 0x0, 0xb0, 0x0, - 0x0, 0xb, 0x55, 0xb6, 0x55, 0xa0, 0x0, 0x4, - 0x55, 0x55, 0xb6, 0x55, 0x59, 0xc0, 0x1, 0x0, - 0x0, 0x91, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x91, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x92, - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, - - /* U+5371 "危" */ - 0x0, 0x0, 0x21, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0xb5, 0x0, 0x3, 0x0, 0x0, 0x0, 0x5, - 0xa5, 0x55, 0xab, 0x0, 0x0, 0x0, 0x2a, 0x0, - 0x1, 0x80, 0x0, 0x0, 0x2, 0x89, 0x55, 0x58, - 0x55, 0x5a, 0x60, 0x3, 0xc, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x0, 0xc, 0x9, 0x65, 0x55, 0xc0, - 0x0, 0x0, 0xc, 0x9, 0x20, 0x0, 0xa0, 0x0, - 0x0, 0xc, 0x9, 0x20, 0x0, 0xa0, 0x0, 0x0, - 0xb, 0x9, 0x20, 0x57, 0xa0, 0x20, 0x0, 0x47, - 0x9, 0x20, 0x7, 0x20, 0x60, 0x0, 0xa1, 0x9, - 0x20, 0x0, 0x0, 0xb0, 0x5, 0x30, 0x4, 0xca, - 0xaa, 0xab, 0xb1, 0x11, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, - - /* U+5373 "即" */ - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xa, 0x55, - 0xa4, 0x7, 0x55, 0x93, 0xb, 0x0, 0x92, 0xb, - 0x0, 0xa1, 0xb, 0x0, 0x92, 0xb, 0x0, 0xa1, - 0xc, 0x55, 0xb2, 0xb, 0x0, 0xa1, 0xb, 0x0, - 0x92, 0xb, 0x0, 0xa1, 0xc, 0x55, 0xb2, 0xb, - 0x0, 0xa1, 0xb, 0x1, 0x30, 0xb, 0x0, 0xa1, - 0xb, 0x5, 0x60, 0xb, 0x0, 0xa1, 0xb, 0x0, - 0xc7, 0xb, 0x27, 0xc0, 0x1d, 0x86, 0x1b, 0xb, - 0x3, 0x50, 0x6, 0x0, 0x0, 0xb, 0x0, 0x0, - 0x0, 0x0, 0x0, 0xb, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x2, 0x0, 0x0, - - /* U+537B "卻" */ - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x4a, 0x4, 0x80, 0x20, 0x0, 0x20, 0x1, 0xa1, - 0x0, 0x79, 0xc5, 0x55, 0xd0, 0x15, 0x1, 0x90, - 0x4, 0xb0, 0x0, 0xb0, 0x0, 0x9, 0x85, 0x0, - 0xb0, 0x0, 0xb0, 0x0, 0x47, 0x5, 0xb0, 0xb0, - 0x0, 0xb0, 0x2, 0x80, 0x0, 0x77, 0xb0, 0x0, - 0xb0, 0x16, 0x75, 0x55, 0xa2, 0xb0, 0x0, 0xb0, - 0x10, 0xb0, 0x0, 0xb0, 0xb0, 0x0, 0xb0, 0x0, - 0xb0, 0x0, 0xb0, 0xb1, 0x54, 0xb0, 0x0, 0xb0, - 0x0, 0xb0, 0xb0, 0x1a, 0x40, 0x0, 0xb5, 0x55, - 0xb0, 0xb0, 0x0, 0x0, 0x0, 0x60, 0x0, 0x40, - 0xb0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, - - /* U+539A "厚" */ - 0x0, 0x0, 0x0, 0x0, 0x0, 0x3, 0x0, 0x0, - 0x95, 0x55, 0x55, 0x55, 0x5a, 0x50, 0x0, 0xa1, - 0x7, 0x55, 0x55, 0x80, 0x0, 0x0, 0xa1, 0xb, - 0x0, 0x0, 0xb0, 0x0, 0x0, 0xa1, 0xc, 0x55, - 0x55, 0xc0, 0x0, 0x0, 0xa1, 0xc, 0x55, 0x55, - 0xc0, 0x0, 0x0, 0xa0, 0x6, 0x0, 0x0, 0x60, - 0x0, 0x0, 0xb0, 0x56, 0x55, 0x57, 0xd2, 0x0, - 0x0, 0xb0, 0x0, 0x1, 0x75, 0x0, 0x0, 0x0, - 0xb4, 0x65, 0x55, 0xc5, 0x58, 0x80, 0x3, 0x70, - 0x0, 0x1, 0xa0, 0x0, 0x0, 0x7, 0x10, 0x0, - 0x11, 0xa0, 0x0, 0x0, 0x14, 0x0, 0x0, 0x4e, - 0x50, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, - - /* U+539F "原" */ - 0x0, 0x0, 0x0, 0x0, 0x0, 0x2, 0x0, 0x9, - 0x55, 0x55, 0x65, 0x58, 0x90, 0x0, 0xb1, 0x0, - 0x9, 0x30, 0x0, 0x0, 0xb, 0x11, 0x75, 0x95, - 0x59, 0x20, 0x0, 0xb1, 0x1a, 0x0, 0x0, 0x91, - 0x0, 0xb, 0x11, 0xc5, 0x55, 0x5b, 0x10, 0x0, - 0xb0, 0x1a, 0x0, 0x0, 0x91, 0x0, 0xb, 0x1, - 0xc5, 0x57, 0x5b, 0x20, 0x0, 0xb0, 0x3, 0x1, - 0xa0, 0x30, 0x0, 0xb, 0x0, 0x7a, 0x1a, 0x35, - 0x0, 0x2, 0x80, 0x5a, 0x1, 0xa0, 0x4c, 0x30, - 0x71, 0x65, 0x3, 0x5a, 0x0, 0x3c, 0x14, 0x11, - 0x0, 0x1b, 0x50, 0x0, 0x10, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x0, - - /* U+53B3 "厳" */ - 0x0, 0x1, 0x0, 0x10, 0x0, 0x10, 0x0, 0x0, - 0x2b, 0x4, 0x80, 0x67, 0x0, 0x0, 0x10, 0x80, - 0x8, 0x15, 0x6, 0x0, 0xc, 0x55, 0x55, 0x56, - 0x75, 0x73, 0x0, 0xc1, 0x77, 0x80, 0x59, 0x0, - 0x0, 0xc, 0x0, 0x72, 0x39, 0x10, 0x60, 0x0, - 0xc3, 0xc5, 0xc5, 0xc5, 0x99, 0x10, 0xc, 0xa, - 0x5c, 0x56, 0x8, 0x30, 0x0, 0xb0, 0xa0, 0xa0, - 0x33, 0xb0, 0x0, 0xa, 0xa, 0x5c, 0x0, 0x99, - 0x0, 0x2, 0x70, 0xb4, 0xc5, 0x1b, 0x60, 0x0, - 0x61, 0xa8, 0x3a, 0x5, 0x6b, 0x60, 0x6, 0x0, - 0x0, 0x94, 0x30, 0xb, 0x50, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x0, - - /* U+53BB "去" */ - 0x0, 0x0, 0x0, 0x10, 0x0, 0x0, 0x0, 0x0, - 0x0, 0xa, 0x40, 0x0, 0x0, 0x0, 0x0, 0x0, - 0xa2, 0x0, 0x0, 0x0, 0x0, 0x0, 0xa, 0x20, - 0x8, 0x0, 0x0, 0x55, 0x55, 0xc7, 0x55, 0x52, - 0x0, 0x0, 0x0, 0xa, 0x20, 0x0, 0x0, 0x0, - 0x0, 0x0, 0xa2, 0x0, 0x8, 0x21, 0x65, 0x55, - 0x5e, 0x65, 0x55, 0x53, 0x0, 0x0, 0x7, 0x90, - 0x0, 0x0, 0x0, 0x0, 0x3, 0x90, 0x4, 0x10, - 0x0, 0x0, 0x2, 0x80, 0x0, 0xa, 0x50, 0x0, - 0x6, 0xc6, 0x66, 0x66, 0x5e, 0x60, 0x0, 0x49, - 0x53, 0x10, 0x0, 0x39, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x0, - - /* U+53C2 "参" */ - 0x0, 0x0, 0x0, 0x20, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x8, 0xa0, 0x0, 0x0, 0x0, 0x0, 0x2, - 0x73, 0x0, 0x28, 0x50, 0x0, 0x0, 0x4e, 0x88, - 0xa5, 0x54, 0xb6, 0x0, 0x0, 0x0, 0x8, 0x50, - 0x0, 0x3, 0x50, 0x5, 0x55, 0x7c, 0x55, 0x85, - 0x55, 0x60, 0x0, 0x1, 0xa1, 0x48, 0x47, 0x0, - 0x0, 0x0, 0x28, 0x5, 0xb2, 0x13, 0xb8, 0x30, - 0x5, 0x41, 0x75, 0x5, 0xd2, 0x6, 0x81, 0x0, - 0x34, 0x1, 0x87, 0x1, 0x80, 0x0, 0x0, 0x3, - 0x66, 0x10, 0x5c, 0x60, 0x0, 0x0, 0x22, 0x1, - 0x6a, 0x60, 0x0, 0x0, 0x1, 0x46, 0x68, 0x30, - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, - - /* U+53C3 "參" */ - 0x0, 0x0, 0x0, 0x30, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x7, 0x80, 0x51, 0x0, 0x0, 0x0, 0x1, - 0xa6, 0x54, 0x5d, 0x20, 0x0, 0x0, 0x6, 0x52, - 0x0, 0x8, 0x20, 0x0, 0x0, 0x66, 0x11, 0x0, - 0x86, 0x6, 0x0, 0x4, 0xb6, 0x49, 0xc8, 0x61, - 0x8, 0x40, 0x0, 0x0, 0xa, 0x66, 0x20, 0x1, - 0x0, 0x0, 0x4, 0x92, 0x3, 0x6a, 0x62, 0x10, - 0x4, 0x64, 0x3, 0xb8, 0x1, 0x8d, 0x91, 0x0, - 0x5, 0x75, 0x4, 0xc1, 0x0, 0x0, 0x0, 0x30, - 0x5, 0x97, 0x13, 0x10, 0x0, 0x0, 0x35, 0x52, - 0x4, 0xab, 0x60, 0x0, 0x1, 0x34, 0x55, 0x64, - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, - - /* U+53C8 "又" */ - 0x0, 0x45, 0x55, 0x55, 0x55, 0x91, 0x0, 0x0, - 0x10, 0x40, 0x0, 0x1, 0xc0, 0x0, 0x0, 0x0, - 0x50, 0x0, 0x5, 0x70, 0x0, 0x0, 0x0, 0x50, - 0x0, 0xb, 0x10, 0x0, 0x0, 0x0, 0x15, 0x0, - 0x29, 0x0, 0x0, 0x0, 0x0, 0x8, 0x0, 0xa2, - 0x0, 0x0, 0x0, 0x0, 0x2, 0x84, 0x90, 0x0, - 0x0, 0x0, 0x0, 0x0, 0x8c, 0x10, 0x0, 0x0, - 0x0, 0x0, 0x1, 0xbb, 0x40, 0x0, 0x0, 0x0, - 0x0, 0x2a, 0x20, 0xa9, 0x10, 0x0, 0x0, 0x6, - 0x70, 0x0, 0x6, 0xea, 0x51, 0x4, 0x51, 0x0, - 0x0, 0x0, 0x18, 0x80, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x0, - - /* U+53CA "及" */ - 0x0, 0x25, 0x56, 0x55, 0x59, 0x40, 0x0, 0x0, - 0x0, 0xc, 0x0, 0xd, 0x10, 0x0, 0x0, 0x0, - 0x1b, 0x0, 0x2a, 0x0, 0x0, 0x0, 0x0, 0x3b, - 0x0, 0x84, 0x0, 0x0, 0x0, 0x0, 0x68, 0x20, - 0xb5, 0x7c, 0x0, 0x0, 0x0, 0xa1, 0x60, 0x0, - 0x94, 0x0, 0x0, 0x0, 0xb0, 0x61, 0x2, 0xb0, - 0x0, 0x0, 0x6, 0x50, 0xa, 0xb, 0x20, 0x0, - 0x0, 0xb, 0x0, 0x5, 0xd5, 0x0, 0x0, 0x0, - 0x83, 0x0, 0x8, 0xb7, 0x0, 0x0, 0x4, 0x40, - 0x4, 0x93, 0x8, 0xc5, 0x0, 0x23, 0x15, 0x63, - 0x0, 0x0, 0x3b, 0xa0, 0x0, 0x10, 0x0, 0x0, - 0x0, 0x0, 0x0, - - /* U+53CB "友" */ - 0x0, 0x0, 0x3, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0xb, 0x50, 0x0, 0x0, 0x0, 0x0, 0x0, - 0xd, 0x0, 0x0, 0x2, 0x30, 0x6, 0x55, 0x5e, - 0x55, 0x55, 0x58, 0x80, 0x0, 0x0, 0x3a, 0x0, - 0x0, 0x0, 0x0, 0x0, 0x0, 0x67, 0x0, 0x0, - 0x40, 0x0, 0x0, 0x0, 0xa7, 0x75, 0x57, 0xd0, - 0x0, 0x0, 0x1, 0xc0, 0x60, 0x9, 0x50, 0x0, - 0x0, 0x6, 0x60, 0x53, 0x1c, 0x0, 0x0, 0x0, - 0xb, 0x0, 0x9, 0xb4, 0x0, 0x0, 0x0, 0x74, - 0x0, 0x9, 0xe4, 0x0, 0x0, 0x2, 0x70, 0x1, - 0x96, 0x1a, 0xa4, 0x0, 0x6, 0x2, 0x66, 0x0, - 0x0, 0x5d, 0xb1, 0x10, 0x11, 0x0, 0x0, 0x0, - 0x0, 0x0, - - /* U+53CD "反" */ - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x25, 0x8b, 0xe9, 0x0, 0x0, 0x1c, - 0x55, 0x43, 0x10, 0x0, 0x0, 0x0, 0xb, 0x0, - 0x0, 0x0, 0x0, 0x0, 0x0, 0xb, 0x0, 0x0, - 0x0, 0x1, 0x0, 0x0, 0xc, 0x58, 0x55, 0x55, - 0xaa, 0x0, 0x0, 0x1b, 0x5, 0x0, 0x0, 0xd1, - 0x0, 0x0, 0x2a, 0x0, 0x70, 0x7, 0x80, 0x0, - 0x0, 0x38, 0x0, 0x64, 0x2c, 0x0, 0x0, 0x0, - 0x74, 0x0, 0x9, 0xc2, 0x0, 0x0, 0x0, 0xa0, - 0x0, 0x1b, 0xc6, 0x0, 0x0, 0x4, 0x50, 0x7, - 0x81, 0x9, 0xd6, 0x10, 0x6, 0x15, 0x61, 0x0, - 0x0, 0x3c, 0xd2, 0x10, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, - - /* U+53D6 "取" */ - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x5, - 0x75, 0x57, 0xb1, 0x0, 0x0, 0x0, 0x0, 0xb0, - 0xb, 0x12, 0x22, 0x27, 0x0, 0x0, 0xb0, 0xb, - 0x16, 0x33, 0x3e, 0x10, 0x0, 0xc5, 0x5c, 0x1, - 0x30, 0x3a, 0x0, 0x0, 0xb0, 0xb, 0x0, 0x60, - 0x76, 0x0, 0x0, 0xc5, 0x5c, 0x0, 0x70, 0xc1, - 0x0, 0x0, 0xb0, 0xb, 0x0, 0x64, 0xa0, 0x0, - 0x0, 0xb0, 0xb, 0x52, 0x1e, 0x30, 0x0, 0x4, - 0xd9, 0x8d, 0x0, 0x2e, 0x40, 0x0, 0xa, 0x40, - 0xb, 0x0, 0xa1, 0xc5, 0x0, 0x0, 0x0, 0xb, - 0x8, 0x20, 0x1c, 0xb1, 0x0, 0x0, 0xa, 0x51, - 0x0, 0x0, 0x30, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, - - /* U+53D7 "受" */ - 0x0, 0x0, 0x0, 0x0, 0x0, 0x30, 0x0, 0x0, - 0x0, 0x13, 0x57, 0xac, 0xd5, 0x0, 0x0, 0x45, - 0x44, 0x31, 0x0, 0x80, 0x0, 0x0, 0x9, 0x10, - 0xb1, 0x6, 0x80, 0x0, 0x0, 0x27, 0x70, 0x86, - 0x9, 0x0, 0x10, 0x1, 0xa6, 0x55, 0x65, 0x56, - 0x58, 0xd0, 0x9, 0x60, 0x0, 0x0, 0x1, 0x7, - 0x10, 0x2, 0x5, 0x75, 0x55, 0x5f, 0x31, 0x0, - 0x0, 0x0, 0x15, 0x0, 0x87, 0x0, 0x0, 0x0, - 0x0, 0x6, 0x45, 0xa0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0xcd, 0x0, 0x0, 0x0, 0x0, 0x0, 0x3a, - 0x56, 0xb7, 0x20, 0x0, 0x2, 0x57, 0x50, 0x0, - 0x6, 0xcf, 0xb1, 0x2, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, - - /* U+53E3 "口" */ - 0x18, 0x55, 0x55, 0x55, 0x5a, 0x1, 0xb0, 0x0, - 0x0, 0x0, 0xc0, 0xb, 0x0, 0x0, 0x0, 0xc, - 0x0, 0xb0, 0x0, 0x0, 0x0, 0xc0, 0xb, 0x0, - 0x0, 0x0, 0xc, 0x0, 0xb0, 0x0, 0x0, 0x0, - 0xc0, 0xb, 0x0, 0x0, 0x0, 0xc, 0x0, 0xb0, - 0x0, 0x0, 0x0, 0xc0, 0x1c, 0x55, 0x55, 0x55, - 0x5c, 0x1, 0xa0, 0x0, 0x0, 0x0, 0x70, 0x0, - 0x0, 0x0, 0x0, 0x0, 0x0, - - /* U+53E4 "古" */ - 0x0, 0x0, 0x0, 0x30, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, 0xa4, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0xa2, 0x0, 0x0, 0x0, 0x5, 0x55, 0x55, - 0xc6, 0x55, 0x59, 0x90, 0x0, 0x0, 0x0, 0xa2, - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xa2, 0x0, - 0x0, 0x0, 0x0, 0x0, 0x0, 0xa2, 0x0, 0x0, - 0x0, 0x0, 0xb, 0x55, 0x85, 0x55, 0xd2, 0x0, - 0x0, 0xc, 0x0, 0x0, 0x0, 0xc0, 0x0, 0x0, - 0xc, 0x0, 0x0, 0x0, 0xc0, 0x0, 0x0, 0xc, - 0x0, 0x0, 0x0, 0xc0, 0x0, 0x0, 0xc, 0x55, - 0x55, 0x55, 0xd0, 0x0, 0x0, 0xc, 0x0, 0x0, - 0x0, 0xb0, 0x0, 0x0, 0x1, 0x0, 0x0, 0x0, - 0x0, 0x0, - - /* U+53E5 "句" */ - 0x0, 0x0, 0x50, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x2, 0xe2, 0x0, 0x0, 0x0, 0x0, 0x0, 0x9, - 0x95, 0x55, 0x55, 0x55, 0x90, 0x0, 0x3a, 0x0, - 0x0, 0x0, 0x2, 0xa0, 0x0, 0xa0, 0x0, 0x0, - 0x0, 0x1, 0xa0, 0x7, 0x17, 0x55, 0x55, 0x90, - 0x1, 0xa0, 0x10, 0xc, 0x0, 0x2, 0xa0, 0x2, - 0xa0, 0x0, 0xc, 0x0, 0x2, 0xa0, 0x2, 0xa0, - 0x0, 0xc, 0x0, 0x2, 0xa0, 0x2, 0x90, 0x0, - 0xd, 0x55, 0x56, 0x90, 0x3, 0x90, 0x0, 0x4, - 0x0, 0x0, 0x0, 0x4, 0x80, 0x0, 0x0, 0x0, - 0x0, 0x20, 0x8, 0x50, 0x0, 0x0, 0x0, 0x0, - 0x18, 0xec, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x40, 0x0, - - /* U+53E6 "另" */ - 0x0, 0x0, 0x0, 0x0, 0x0, 0x10, 0x0, 0x0, - 0xb5, 0x55, 0x55, 0x5e, 0x0, 0x0, 0xb, 0x0, - 0x0, 0x0, 0xc0, 0x0, 0x0, 0xb0, 0x0, 0x0, - 0xc, 0x0, 0x0, 0xb, 0x55, 0x55, 0x55, 0xc0, - 0x0, 0x0, 0x90, 0xa, 0x10, 0x7, 0x0, 0x0, - 0x0, 0x1, 0xc0, 0x0, 0x3, 0x0, 0x26, 0x55, - 0x7c, 0x55, 0x56, 0xc0, 0x0, 0x0, 0x5, 0x70, - 0x0, 0x29, 0x0, 0x0, 0x0, 0xa2, 0x0, 0x3, - 0x90, 0x0, 0x0, 0x29, 0x0, 0x0, 0x48, 0x0, - 0x0, 0x49, 0x0, 0x3, 0x18, 0x60, 0x3, 0x64, - 0x0, 0x0, 0x2b, 0xe1, 0x0, 0x10, 0x0, 0x0, - 0x0, 0x0, 0x0, - - /* U+53EA "只" */ - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xa5, - 0x55, 0x55, 0x5d, 0x0, 0x0, 0xc0, 0x0, 0x0, - 0xc, 0x0, 0x0, 0xc0, 0x0, 0x0, 0xc, 0x0, - 0x0, 0xc0, 0x0, 0x0, 0xc, 0x0, 0x0, 0xc0, - 0x0, 0x0, 0xc, 0x0, 0x0, 0xc5, 0x55, 0x55, - 0x5c, 0x0, 0x0, 0xc0, 0x0, 0x0, 0x9, 0x0, - 0x0, 0x2, 0xd1, 0x5, 0x10, 0x0, 0x0, 0xc, - 0x40, 0x0, 0xa4, 0x0, 0x0, 0x76, 0x0, 0x0, - 0x1e, 0x50, 0x5, 0x60, 0x0, 0x0, 0x5, 0xe0, - 0x44, 0x0, 0x0, 0x0, 0x0, 0x80, 0x0, 0x0, - 0x0, 0x0, 0x0, 0x0, - - /* U+53EB "叫" */ - 0x0, 0x0, 0x0, 0x0, 0x0, 0x30, 0x0, 0x0, - 0x0, 0x0, 0x0, 0xc2, 0x27, 0x55, 0xa0, 0x29, - 0x0, 0xb0, 0x2a, 0x0, 0xc0, 0x2a, 0x0, 0xb0, - 0x2a, 0x0, 0xc0, 0x2a, 0x0, 0xb0, 0x2a, 0x0, - 0xc0, 0x2a, 0x0, 0xb0, 0x2a, 0x0, 0xc0, 0x2a, - 0x0, 0xb0, 0x2a, 0x0, 0xc0, 0x2a, 0x2, 0xc0, - 0x2b, 0x55, 0xc0, 0x3d, 0x83, 0xb0, 0x2a, 0x0, - 0xc0, 0x5, 0x0, 0xb0, 0x25, 0x0, 0x0, 0x0, - 0x0, 0xb0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xc0, - 0x0, 0x0, 0x0, 0x0, 0x0, 0xc1, 0x0, 0x0, - 0x0, 0x0, 0x0, 0x10, - - /* U+53EF "可" */ - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x90, 0x6, - 0x55, 0x55, 0x55, 0x55, 0xd5, 0x52, 0x0, 0x0, - 0x0, 0x0, 0x0, 0xc0, 0x0, 0x0, 0x18, 0x55, - 0x5a, 0x0, 0xc0, 0x0, 0x0, 0x2a, 0x0, 0xc, - 0x0, 0xc0, 0x0, 0x0, 0x1a, 0x0, 0xc, 0x0, - 0xc0, 0x0, 0x0, 0x1a, 0x0, 0xc, 0x0, 0xc0, - 0x0, 0x0, 0x1c, 0x55, 0x5c, 0x0, 0xc0, 0x0, - 0x0, 0x2a, 0x0, 0xa, 0x0, 0xc0, 0x0, 0x0, - 0x13, 0x0, 0x0, 0x0, 0xc0, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x54, 0xd0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x1a, 0x90, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x0, - - /* U+53F0 "台" */ - 0x0, 0x0, 0x3, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x3e, 0x30, 0x0, 0x0, 0x0, 0x1, 0xc2, 0x0, - 0x0, 0x0, 0x0, 0xa, 0x20, 0x0, 0x60, 0x0, - 0x0, 0x92, 0x0, 0x0, 0x1b, 0x50, 0x2d, 0x87, - 0x77, 0x76, 0x57, 0xe5, 0xa, 0x74, 0x10, 0x0, - 0x0, 0x45, 0x0, 0x30, 0x0, 0x0, 0x5, 0x0, - 0x0, 0xc5, 0x55, 0x55, 0x5d, 0x0, 0x0, 0xc0, - 0x0, 0x0, 0xc, 0x0, 0x0, 0xc0, 0x0, 0x0, - 0xc, 0x0, 0x0, 0xc0, 0x0, 0x0, 0xc, 0x0, - 0x0, 0xc5, 0x55, 0x55, 0x5c, 0x0, 0x0, 0x20, - 0x0, 0x0, 0x1, 0x0, - - /* U+53F2 "史" */ - 0x0, 0x0, 0x0, 0x40, 0x0, 0x0, 0x0, 0x0, - 0x0, 0xc, 0x10, 0x0, 0x0, 0x0, 0x0, 0x0, - 0xc0, 0x0, 0x0, 0x0, 0xc, 0x55, 0x5d, 0x55, - 0x5d, 0x20, 0x0, 0xd0, 0x0, 0xc0, 0x0, 0xc0, - 0x0, 0xd, 0x0, 0xc, 0x0, 0xc, 0x0, 0x0, - 0xe5, 0x55, 0xd5, 0x55, 0xd0, 0x0, 0x6, 0x10, - 0xb, 0x0, 0x4, 0x0, 0x0, 0x3, 0x20, 0xb0, - 0x0, 0x0, 0x0, 0x0, 0x7, 0x77, 0x0, 0x0, - 0x0, 0x0, 0x0, 0xe, 0x90, 0x0, 0x0, 0x0, - 0x0, 0x2b, 0x45, 0xca, 0x63, 0x20, 0x4, 0x87, - 0x10, 0x0, 0x49, 0xcc, 0x23, 0x10, 0x0, 0x0, - 0x0, 0x0, 0x0, - - /* U+53F3 "右" */ - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x1e, 0x0, 0x0, 0x0, 0x0, 0x0, 0x5, - 0x80, 0x0, 0x3, 0x1, 0x65, 0x55, 0xb7, 0x55, - 0x55, 0x96, 0x0, 0x0, 0x1c, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x7, 0x50, 0x0, 0x0, 0x0, 0x0, - 0x1, 0xc0, 0x0, 0x0, 0x30, 0x0, 0x0, 0x9c, - 0x65, 0x55, 0x5d, 0x20, 0x0, 0x54, 0xa2, 0x0, - 0x0, 0xc0, 0x0, 0x35, 0xa, 0x20, 0x0, 0xc, - 0x0, 0x23, 0x0, 0xa2, 0x0, 0x0, 0xc0, 0x0, - 0x0, 0xa, 0x65, 0x55, 0x5d, 0x0, 0x0, 0x0, - 0x81, 0x0, 0x0, 0x90, 0x0, - - /* U+53F7 "号" */ - 0x0, 0x0, 0x0, 0x0, 0x1, 0x0, 0x0, 0x0, - 0xb5, 0x55, 0x55, 0xc3, 0x0, 0x0, 0xb, 0x0, - 0x0, 0xb, 0x10, 0x0, 0x0, 0xb0, 0x0, 0x0, - 0xb1, 0x0, 0x0, 0xb, 0x55, 0x55, 0x5c, 0x10, - 0x0, 0x0, 0x40, 0x0, 0x0, 0x10, 0x50, 0x5, - 0x55, 0x99, 0x55, 0x55, 0x56, 0x30, 0x0, 0xb, - 0x20, 0x0, 0x0, 0x0, 0x0, 0x2, 0xd5, 0x55, - 0x59, 0xa0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x84, - 0x0, 0x0, 0x0, 0x0, 0x0, 0xc, 0x10, 0x0, - 0x0, 0x0, 0x3, 0x2, 0xd0, 0x0, 0x0, 0x0, - 0x0, 0x2d, 0xf4, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x20, 0x0, 0x0, - - /* U+53F8 "司" */ - 0x2, 0x65, 0x55, 0x55, 0x55, 0xa1, 0x0, 0x0, - 0x0, 0x0, 0x0, 0xc0, 0x0, 0x0, 0x0, 0x1, - 0x20, 0xc0, 0x35, 0x55, 0x55, 0x57, 0x70, 0xc0, - 0x0, 0x10, 0x0, 0x20, 0x0, 0xc0, 0x0, 0xd5, - 0x55, 0xd4, 0x0, 0xc0, 0x0, 0xc0, 0x0, 0xb0, - 0x0, 0xc0, 0x0, 0xc0, 0x0, 0xb0, 0x0, 0xc0, - 0x0, 0xd5, 0x55, 0xd1, 0x0, 0xc0, 0x0, 0x80, - 0x0, 0x50, 0x0, 0xc0, 0x0, 0x0, 0x0, 0x0, - 0x21, 0xc0, 0x0, 0x0, 0x0, 0x0, 0x5d, 0x90, - 0x0, 0x0, 0x0, 0x0, 0x1, 0x0, - - /* U+5403 "吃" */ - 0x0, 0x0, 0x0, 0x20, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x9, 0x80, 0x0, 0x0, 0x42, 0x26, 0x0, - 0xc0, 0x0, 0x0, 0xd, 0x33, 0xd0, 0x69, 0x55, - 0x58, 0x80, 0xc0, 0xc, 0x9, 0x0, 0x0, 0x0, - 0xc, 0x0, 0xc5, 0x10, 0x0, 0x40, 0x0, 0xc0, - 0xc, 0x15, 0x55, 0x9c, 0x10, 0xc, 0x0, 0xc0, - 0x0, 0x2c, 0x10, 0x0, 0xc5, 0x5d, 0x0, 0xc, - 0x20, 0x0, 0xd, 0x0, 0xb0, 0xa, 0x30, 0x0, - 0x30, 0x50, 0x0, 0x7, 0x70, 0x0, 0x6, 0x0, - 0x0, 0x0, 0xd0, 0x0, 0x1, 0xa0, 0x0, 0x0, - 0x8, 0xba, 0xaa, 0xcc, 0x0, - - /* U+5404 "各" */ - 0x0, 0x0, 0x3, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x3d, 0x10, 0x3, 0x0, 0x0, 0x0, 0x0, - 0xc7, 0x55, 0x6e, 0x20, 0x0, 0x0, 0x7, 0x56, - 0x0, 0x96, 0x0, 0x0, 0x0, 0x44, 0x4, 0x53, - 0xb0, 0x0, 0x0, 0x0, 0x10, 0x0, 0x9c, 0x10, - 0x0, 0x0, 0x0, 0x0, 0x4, 0xa8, 0xa3, 0x0, - 0x0, 0x0, 0x0, 0x86, 0x0, 0x3b, 0xd8, 0x51, - 0x0, 0x58, 0xb5, 0x55, 0x5c, 0x48, 0x60, 0x4, - 0x1, 0xa0, 0x0, 0xc, 0x0, 0x0, 0x0, 0x1, - 0xa0, 0x0, 0xc, 0x0, 0x0, 0x0, 0x1, 0xa0, - 0x0, 0xc, 0x0, 0x0, 0x0, 0x2, 0xc5, 0x55, - 0x5d, 0x0, 0x0, 0x0, 0x1, 0x30, 0x0, 0x3, - 0x0, 0x0, - - /* U+5408 "合" */ - 0x0, 0x0, 0x0, 0x30, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x1, 0xf4, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x9, 0x67, 0x0, 0x0, 0x0, 0x0, 0x0, 0x5a, - 0x2, 0x90, 0x0, 0x0, 0x0, 0x4, 0xa0, 0x0, - 0x4b, 0x20, 0x0, 0x0, 0x68, 0x0, 0x0, 0x17, - 0xda, 0x50, 0x26, 0x24, 0x55, 0x55, 0x56, 0x7, - 0x40, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x9, 0x55, 0x55, 0x5c, 0x20, 0x0, 0x0, - 0xa, 0x10, 0x0, 0xc, 0x0, 0x0, 0x0, 0xa, - 0x10, 0x0, 0xc, 0x0, 0x0, 0x0, 0xa, 0x65, - 0x55, 0x5d, 0x0, 0x0, 0x0, 0xa, 0x10, 0x0, - 0x9, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, - - /* U+540C "同" */ - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xa, 0x55, - 0x55, 0x55, 0x55, 0xa3, 0xc, 0x0, 0x0, 0x0, - 0x0, 0xa2, 0xc, 0x0, 0x0, 0x0, 0x61, 0xa2, - 0xc, 0x6, 0x55, 0x55, 0x52, 0xa2, 0xc, 0x0, - 0x10, 0x0, 0x30, 0xa2, 0xc, 0x1, 0xc5, 0x55, - 0xc0, 0xa2, 0xc, 0x0, 0xa0, 0x0, 0xb0, 0xa2, - 0xc, 0x0, 0xa0, 0x0, 0xb0, 0xa2, 0xc, 0x1, - 0xc5, 0x55, 0xb0, 0xa2, 0xc, 0x0, 0x20, 0x0, - 0x10, 0xa2, 0xc, 0x0, 0x0, 0x0, 0x20, 0xc1, - 0xd, 0x0, 0x0, 0x0, 0x4c, 0xd0, 0x2, 0x0, - 0x0, 0x0, 0x1, 0x0, - - /* U+540D "名" */ - 0x0, 0x0, 0x0, 0x20, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x6c, 0x0, 0x0, 0x0, 0x0, 0x0, 0xd, - 0x75, 0x55, 0x78, 0x0, 0x0, 0x7, 0x50, 0x0, - 0xc, 0x40, 0x0, 0x4, 0xc2, 0x0, 0x9, 0x70, - 0x0, 0x3, 0x60, 0xd3, 0x9, 0x80, 0x0, 0x0, - 0x20, 0x3, 0x1a, 0x80, 0x0, 0x0, 0x0, 0x0, - 0x3b, 0x50, 0x0, 0x10, 0x0, 0x0, 0x7e, 0x65, - 0x55, 0x5d, 0x20, 0x15, 0x72, 0xc0, 0x0, 0x0, - 0xc0, 0x2, 0x0, 0xc, 0x0, 0x0, 0xc, 0x0, - 0x0, 0x0, 0xd5, 0x55, 0x55, 0xd0, 0x0, 0x0, - 0x9, 0x0, 0x0, 0x7, 0x0, - - /* U+5411 "向" */ - 0x0, 0x0, 0x30, 0x0, 0x0, 0x0, 0x0, 0x1b, - 0x0, 0x0, 0x0, 0x10, 0x5, 0x20, 0x0, 0x2, - 0xd, 0x55, 0x65, 0x55, 0x55, 0xd2, 0xc0, 0x0, - 0x0, 0x0, 0xc, 0xc, 0x1, 0x20, 0x4, 0x0, - 0xc0, 0xc0, 0x1c, 0x55, 0xc3, 0xc, 0xc, 0x1, - 0xa0, 0xb, 0x10, 0xc0, 0xc0, 0x1a, 0x0, 0xb1, - 0xc, 0xc, 0x2, 0xc5, 0x5c, 0x10, 0xc0, 0xc0, - 0x13, 0x0, 0x10, 0xc, 0xc, 0x0, 0x0, 0x0, - 0x22, 0xd0, 0xc0, 0x0, 0x0, 0x3, 0xbb, 0x1, - 0x0, 0x0, 0x0, 0x0, 0x0, - - /* U+5426 "否" */ - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x45, - 0x55, 0x56, 0x55, 0x55, 0xd4, 0x0, 0x0, 0x3, - 0xd0, 0x0, 0x0, 0x0, 0x0, 0x1, 0xbd, 0x12, - 0x0, 0x0, 0x0, 0x1, 0xb2, 0xc0, 0x27, 0x60, - 0x0, 0x3, 0xa1, 0xc, 0x0, 0x4, 0xd4, 0x5, - 0x50, 0x0, 0xd0, 0x0, 0x2, 0xa0, 0x0, 0x30, - 0x4, 0x0, 0x5, 0x0, 0x0, 0xc, 0x65, 0x55, - 0x55, 0xe0, 0x0, 0x0, 0xb1, 0x0, 0x0, 0xd, - 0x0, 0x0, 0xb, 0x10, 0x0, 0x0, 0xd0, 0x0, - 0x0, 0xb6, 0x55, 0x55, 0x5d, 0x0, 0x0, 0xc, - 0x10, 0x0, 0x0, 0xd0, 0x0, 0x0, 0x20, 0x0, - 0x0, 0x0, 0x0, - - /* U+5427 "吧" */ - 0x0, 0x0, 0x2, 0x0, 0x0, 0x30, 0x7, 0x55, - 0x90, 0xd5, 0xc5, 0x6d, 0x0, 0xc0, 0x1b, 0xc, - 0xc, 0x1, 0xb0, 0xc, 0x1, 0xb0, 0xc0, 0xc0, - 0x1b, 0x0, 0xc0, 0x1b, 0xc, 0xc, 0x1, 0xb0, - 0xc, 0x1, 0xb0, 0xd5, 0xd5, 0x6b, 0x0, 0xc0, - 0x1b, 0xc, 0x0, 0x1, 0x70, 0xc, 0x56, 0xb0, - 0xc0, 0x0, 0x0, 0x0, 0xc0, 0x1b, 0xc, 0x0, - 0x0, 0x1, 0xc, 0x0, 0x50, 0xc0, 0x0, 0x0, - 0x60, 0x0, 0x0, 0xc, 0x0, 0x0, 0xa, 0x0, - 0x0, 0x0, 0xab, 0xaa, 0xab, 0xc0, - - /* U+5440 "呀" */ - 0x0, 0x0, 0x2, 0x22, 0x22, 0x65, 0x9, 0x55, - 0xb2, 0x42, 0x22, 0xc2, 0x20, 0xc0, 0xc, 0x6, - 0x90, 0xc, 0x0, 0xc, 0x0, 0xc0, 0xb3, 0x0, - 0xc0, 0x0, 0xc0, 0xc, 0x1c, 0x0, 0xc, 0x7, - 0xc, 0x0, 0xc2, 0x75, 0x7d, 0xd5, 0x51, 0xc0, - 0xc, 0x0, 0xa, 0x4c, 0x0, 0xc, 0x55, 0xd0, - 0x4, 0x90, 0xc0, 0x0, 0xa0, 0x1, 0x2, 0xa0, - 0xc, 0x0, 0x0, 0x0, 0x2, 0x90, 0x0, 0xc0, - 0x0, 0x0, 0x3, 0x60, 0x12, 0x3b, 0x0, 0x0, - 0x1, 0x20, 0x0, 0x5e, 0x60, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x0, 0x0, 0x0, - - /* U+544A "告" */ - 0x0, 0x0, 0x0, 0x30, 0x0, 0x0, 0x0, 0x0, - 0x64, 0xb, 0x30, 0x0, 0x0, 0x0, 0xb, 0x10, - 0xb1, 0x2, 0x10, 0x0, 0x5, 0x85, 0x5c, 0x65, - 0x76, 0x0, 0x1, 0x70, 0x0, 0xb1, 0x0, 0x0, - 0x0, 0x20, 0x0, 0xb, 0x10, 0x1, 0x50, 0x6, - 0x55, 0x55, 0x65, 0x55, 0x67, 0x10, 0x0, 0x20, - 0x0, 0x0, 0x20, 0x0, 0x0, 0xc, 0x55, 0x55, - 0x5c, 0x30, 0x0, 0x0, 0xc0, 0x0, 0x0, 0xb1, - 0x0, 0x0, 0xc, 0x0, 0x0, 0xb, 0x10, 0x0, - 0x0, 0xc5, 0x55, 0x55, 0xc1, 0x0, 0x0, 0xc, - 0x0, 0x0, 0xa, 0x10, 0x0, 0x0, 0x20, 0x0, - 0x0, 0x0, 0x0, - - /* U+5462 "呢" */ - 0x10, 0x1, 0x8, 0x55, 0x55, 0x91, 0xc5, 0x5d, - 0xc, 0x0, 0x0, 0xc0, 0xc0, 0xc, 0xc, 0x0, - 0x0, 0xc0, 0xc0, 0xc, 0xc, 0x55, 0x55, 0xd0, - 0xc0, 0xc, 0xc, 0x12, 0x0, 0x20, 0xc0, 0xc, - 0xc, 0x3a, 0x0, 0x70, 0xc0, 0xc, 0xb, 0x38, - 0x9, 0x80, 0xc5, 0x5c, 0x38, 0x38, 0x74, 0x0, - 0xc0, 0x6, 0x73, 0x3b, 0x10, 0x2, 0x40, 0x0, - 0xa0, 0x38, 0x0, 0x14, 0x0, 0x4, 0x40, 0x2b, - 0x11, 0x6a, 0x0, 0x6, 0x0, 0x7, 0x99, 0x93, - 0x0, 0x10, 0x0, 0x0, 0x0, 0x0, - - /* U+5468 "周" */ - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x9, - 0x65, 0x55, 0x55, 0x55, 0xd0, 0x0, 0x92, 0x0, - 0x92, 0x0, 0xb, 0x0, 0x9, 0x20, 0xa, 0x14, - 0x10, 0xb0, 0x0, 0x92, 0x36, 0xc5, 0x53, 0xb, - 0x0, 0x9, 0x20, 0xa, 0x10, 0x60, 0xb0, 0x0, - 0xa4, 0x65, 0x55, 0x55, 0x2b, 0x0, 0xa, 0x0, - 0x85, 0x5a, 0x30, 0xb0, 0x0, 0xb0, 0xb, 0x0, - 0xb0, 0xb, 0x0, 0xa, 0x0, 0xb0, 0xb, 0x0, - 0xb0, 0x4, 0x50, 0xc, 0x55, 0xc0, 0xb, 0x0, - 0x80, 0x0, 0x40, 0x3, 0x22, 0xb0, 0x32, 0x0, - 0x0, 0x0, 0x5, 0xe5, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x0, - - /* U+5473 "味" */ - 0x0, 0x0, 0x0, 0x4, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, 0xd0, 0x0, 0x0, 0x74, 0x49, 0x0, - 0xc, 0x0, 0x20, 0xc, 0x0, 0xc1, 0x65, 0xd5, - 0x67, 0x0, 0xc0, 0xc, 0x0, 0xc, 0x0, 0x0, - 0xc, 0x0, 0xc0, 0x0, 0xc0, 0x2, 0x50, 0xc0, - 0xc, 0x65, 0xae, 0x85, 0x55, 0xc, 0x0, 0xc0, - 0xc, 0xc5, 0x10, 0x0, 0xd5, 0x5c, 0x6, 0x5c, - 0x8, 0x0, 0xa, 0x0, 0x32, 0x90, 0xc0, 0x76, - 0x0, 0x0, 0x1, 0x90, 0xc, 0x0, 0xc9, 0x10, - 0x1, 0x70, 0x0, 0xc0, 0x1, 0x50, 0x0, 0x20, - 0x0, 0xd, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x20, 0x0, 0x0, - - /* U+547C "呼" */ - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x4, 0x8e, 0x20, 0x85, 0x5c, 0x14, - 0x58, 0xc2, 0x0, 0xb, 0x0, 0xc1, 0x10, 0x1a, - 0x1, 0x90, 0xb0, 0xc, 0xa, 0x11, 0xa0, 0x94, - 0xb, 0x0, 0xc0, 0x67, 0x1a, 0x25, 0x0, 0xb0, - 0xc, 0x1, 0x11, 0xa2, 0x5, 0xb, 0x0, 0xc5, - 0x55, 0x6c, 0x55, 0x71, 0xb5, 0x5c, 0x0, 0x1, - 0xa0, 0x0, 0xb, 0x0, 0xc0, 0x0, 0x1a, 0x0, - 0x0, 0x50, 0x0, 0x0, 0x1, 0xa0, 0x0, 0x0, - 0x0, 0x0, 0x1, 0x3a, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x6e, 0x60, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x10, 0x0, 0x0, - - /* U+547D "命" */ - 0x0, 0x0, 0x0, 0x40, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x4, 0xf1, 0x0, 0x0, 0x0, 0x0, 0x0, - 0xc, 0x36, 0x0, 0x0, 0x0, 0x0, 0x0, 0xa4, - 0x2, 0x80, 0x0, 0x0, 0x0, 0xa, 0x40, 0x0, - 0x7c, 0x71, 0x0, 0x3, 0x82, 0x65, 0x55, 0x61, - 0x8f, 0x80, 0x33, 0x20, 0x3, 0x4, 0x11, 0x52, - 0x0, 0x0, 0xb5, 0x5d, 0xb, 0x33, 0xc1, 0x0, - 0x0, 0xb0, 0xb, 0xb, 0x0, 0xb0, 0x0, 0x0, - 0xb0, 0xb, 0xb, 0x0, 0xb0, 0x0, 0x0, 0xb5, - 0x5c, 0xb, 0x0, 0xb0, 0x0, 0x0, 0xb0, 0x9, - 0xb, 0x29, 0xc0, 0x0, 0x0, 0x30, 0x0, 0xb, - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x1, 0x0, - 0x0, 0x0, - - /* U+548C "和" */ - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x4a, 0xd0, 0x0, 0x0, 0x0, 0x2, 0x55, - 0xd1, 0x0, 0x85, 0x55, 0x90, 0x0, 0x0, 0xc0, - 0x0, 0xc0, 0x2, 0xa0, 0x3, 0x55, 0xd5, 0x94, - 0xc0, 0x2, 0xa0, 0x0, 0x4, 0xe0, 0x0, 0xc0, - 0x2, 0xa0, 0x0, 0xb, 0xe7, 0x20, 0xc0, 0x2, - 0xa0, 0x0, 0x37, 0xc1, 0xd3, 0xc0, 0x2, 0xa0, - 0x0, 0x90, 0xc0, 0x11, 0xc0, 0x2, 0xa0, 0x6, - 0x10, 0xc0, 0x0, 0xd5, 0x56, 0xa0, 0x11, 0x0, - 0xc0, 0x0, 0xc0, 0x2, 0xa0, 0x0, 0x0, 0xd0, - 0x0, 0x50, 0x0, 0x0, 0x0, 0x0, 0xb0, 0x0, - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, - - /* U+54B2 "咲" */ - 0x0, 0x0, 0x1, 0x0, 0x1, 0x10, 0x0, 0x0, - 0x0, 0x94, 0x0, 0x7a, 0x0, 0xb5, 0x5c, 0x1, - 0xf0, 0xa, 0x0, 0xc, 0x0, 0xc0, 0x4, 0x3, - 0x21, 0x30, 0xc0, 0xc, 0x26, 0x59, 0x85, 0x66, - 0xc, 0x0, 0xc0, 0x0, 0x93, 0x0, 0x0, 0xc0, - 0xc, 0x0, 0xa, 0x20, 0x4, 0xc, 0x0, 0xc6, - 0x55, 0xd8, 0x55, 0x73, 0xd5, 0x5c, 0x0, 0xc, - 0x41, 0x0, 0xc, 0x0, 0x80, 0x3, 0x91, 0x70, - 0x0, 0x10, 0x0, 0x0, 0xa2, 0xa, 0x10, 0x0, - 0x0, 0x0, 0x56, 0x0, 0x3c, 0x0, 0x0, 0x0, - 0x64, 0x0, 0x0, 0x8e, 0x40, 0x0, 0x30, 0x0, - 0x0, 0x0, 0x30, - - /* U+54C1 "品" */ - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xb, - 0x55, 0x55, 0xa4, 0x0, 0x0, 0xc, 0x0, 0x0, - 0x82, 0x0, 0x0, 0xc, 0x0, 0x0, 0x82, 0x0, - 0x0, 0xc, 0x0, 0x0, 0x82, 0x0, 0x0, 0xd, - 0x55, 0x55, 0xb2, 0x0, 0x0, 0x4, 0x0, 0x0, - 0x10, 0x0, 0x1a, 0x55, 0xa5, 0xb, 0x55, 0xb4, - 0xb, 0x0, 0x93, 0xc, 0x0, 0xa2, 0xb, 0x0, - 0x93, 0xc, 0x0, 0xa2, 0xb, 0x0, 0x93, 0xc, - 0x0, 0xa2, 0xd, 0x55, 0xb3, 0xd, 0x55, 0xb2, - 0x1a, 0x0, 0x51, 0x9, 0x0, 0x61, 0x0, 0x0, - 0x0, 0x0, 0x0, 0x0, - - /* U+54E1 "員" */ - 0x0, 0x2, 0x0, 0x0, 0x3, 0x0, 0x0, 0x1c, - 0x55, 0x55, 0x5d, 0x0, 0x0, 0x1b, 0x0, 0x0, - 0xb, 0x0, 0x0, 0x1c, 0x55, 0x55, 0x5a, 0x0, - 0x1, 0x86, 0x55, 0x55, 0x56, 0x80, 0x1, 0xb0, - 0x0, 0x0, 0x2, 0x90, 0x1, 0xc5, 0x55, 0x55, - 0x56, 0x90, 0x0, 0xb0, 0x0, 0x0, 0x2, 0x90, - 0x1, 0xc5, 0x55, 0x55, 0x56, 0x90, 0x1, 0xc5, - 0x55, 0x55, 0x56, 0xa0, 0x0, 0x50, 0x54, 0x5, - 0x10, 0x20, 0x0, 0x7, 0xa3, 0x1, 0x9b, 0x30, - 0x3, 0x72, 0x0, 0x0, 0x3, 0xe0, 0x11, 0x0, - 0x0, 0x0, 0x0, 0x10, - - /* U+54EA "哪" */ - 0x0, 0x3, 0x33, 0x37, 0x24, 0x37, 0x8, 0x5a, - 0x22, 0xb1, 0xb4, 0x72, 0xc1, 0xa0, 0xa0, 0xa, - 0xb, 0x46, 0x53, 0xa, 0xa, 0x25, 0xc5, 0xb4, - 0x66, 0x0, 0xa0, 0xa0, 0xa, 0xb, 0x46, 0x50, - 0xa, 0xa, 0x0, 0x90, 0xb4, 0x64, 0x30, 0xa0, - 0xa2, 0x5b, 0x4b, 0x46, 0xa, 0xc, 0x5b, 0x5, - 0x61, 0xa4, 0x60, 0x91, 0xb0, 0x20, 0x91, 0x1a, - 0x47, 0x2b, 0x12, 0x0, 0x28, 0x3, 0x84, 0x6a, - 0x90, 0x0, 0x8, 0x17, 0xb4, 0x46, 0x0, 0x0, - 0x6, 0x0, 0x25, 0x4, 0x50, 0x0, 0x1, 0x0, - 0x0, 0x0, 0x0, 0x0, 0x0, - - /* U+5546 "商" */ - 0x0, 0x0, 0x0, 0x30, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x67, 0x0, 0x2, 0x20, 0x6, 0x55, - 0x75, 0x56, 0x67, 0x57, 0x60, 0x0, 0x0, 0x67, - 0x0, 0x67, 0x0, 0x0, 0x0, 0x75, 0x5c, 0x55, - 0x95, 0x59, 0x10, 0x0, 0xb0, 0x5, 0x0, 0x20, - 0xb, 0x0, 0x0, 0xb0, 0x3c, 0x10, 0x5c, 0x1b, - 0x0, 0x0, 0xb1, 0x71, 0x0, 0x25, 0x2b, 0x0, - 0x0, 0xb2, 0xc, 0x55, 0xc2, 0xb, 0x0, 0x0, - 0xb0, 0xb, 0x0, 0xb0, 0xb, 0x0, 0x0, 0xb0, - 0xc, 0x55, 0xc0, 0xb, 0x0, 0x0, 0xb0, 0xa, - 0x0, 0x60, 0xb, 0x0, 0x0, 0xc0, 0x0, 0x0, - 0x3, 0xbb, 0x0, 0x0, 0x20, 0x0, 0x0, 0x0, - 0x10, 0x0, - - /* U+554A "啊" */ - 0x0, 0x4, 0x67, 0x74, 0x55, 0x5a, 0x2c, 0x5c, - 0x65, 0x73, 0x0, 0x5, 0x60, 0xa0, 0xa5, 0x58, - 0x0, 0x0, 0x56, 0xa, 0xa, 0x55, 0x50, 0xa5, - 0xb5, 0x60, 0xa0, 0xa5, 0x64, 0xa, 0xa, 0x56, - 0xa, 0xa, 0x55, 0x70, 0xa0, 0xa5, 0x60, 0xa0, - 0xa5, 0x55, 0x6a, 0xa, 0x56, 0xc, 0x5b, 0x55, - 0x47, 0xc5, 0xa5, 0x60, 0xa0, 0x35, 0x8d, 0x23, - 0x1, 0x56, 0x0, 0x0, 0x55, 0x0, 0x0, 0x5, - 0x60, 0x0, 0x5, 0x50, 0x0, 0x10, 0x56, 0x0, - 0x0, 0x64, 0x0, 0x1, 0x8f, 0x30, 0x0, 0x1, - 0x0, 0x0, 0x0, 0x0, 0x0, - - /* U+554F "問" */ - 0x1, 0x0, 0x1, 0x0, 0x0, 0x1, 0x1, 0xc5, - 0x55, 0xc0, 0xc5, 0x55, 0xd0, 0x1b, 0x0, 0xa, - 0xb, 0x0, 0xc, 0x1, 0xc5, 0x55, 0xa0, 0xc5, - 0x55, 0xc0, 0x1b, 0x0, 0xa, 0xb, 0x0, 0xc, - 0x1, 0xc5, 0x55, 0x80, 0xb5, 0x55, 0xc0, 0x1b, - 0x0, 0x0, 0x0, 0x10, 0xc, 0x1, 0xb0, 0xc, - 0x55, 0x5d, 0x0, 0xc0, 0x1b, 0x0, 0xb0, 0x0, - 0xb0, 0xc, 0x1, 0xb0, 0xb, 0x0, 0xb, 0x0, - 0xc0, 0x1b, 0x0, 0xd5, 0x55, 0xb0, 0xc, 0x1, - 0xb0, 0x3, 0x0, 0x2, 0x0, 0xc0, 0x1a, 0x0, - 0x0, 0x0, 0x6, 0xd8, 0x0, 0x10, 0x0, 0x0, - 0x0, 0x1, 0x0, - - /* U+5566 "啦" */ - 0x0, 0x0, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0xd0, 0x4, 0x30, 0x0, 0x0, 0x0, 0xb, - 0x0, 0xd, 0x0, 0xb, 0x5c, 0x10, 0xb4, 0x0, - 0x71, 0x50, 0xb0, 0xb4, 0x6c, 0x54, 0x65, 0x55, - 0xb, 0xb, 0x0, 0xb0, 0x0, 0x5, 0x30, 0xb0, - 0xb0, 0xb, 0x45, 0x20, 0xa5, 0xb, 0xb, 0x5, - 0xd2, 0x9, 0xb, 0x0, 0xb0, 0xba, 0x6b, 0x0, - 0xc0, 0xa0, 0xc, 0x5c, 0x0, 0xb0, 0xa, 0x27, - 0x0, 0xa0, 0x20, 0xb, 0x0, 0x24, 0x30, 0x0, - 0x0, 0x11, 0xb0, 0x0, 0x50, 0x60, 0x0, 0x4, - 0xd7, 0x36, 0x55, 0x56, 0x20, 0x0, 0x1, 0x0, - 0x0, 0x0, 0x0, - - /* U+5584 "善" */ - 0x0, 0x0, 0x20, 0x0, 0x20, 0x0, 0x0, 0x0, - 0x6, 0x70, 0x1b, 0x0, 0x0, 0x3, 0x55, 0x6b, - 0x59, 0x55, 0xc5, 0x0, 0x0, 0x0, 0xc, 0x0, - 0x21, 0x0, 0x0, 0x36, 0x55, 0xd5, 0x56, 0x50, - 0x0, 0x65, 0x55, 0x5d, 0x55, 0x56, 0xb0, 0x0, - 0x4, 0x60, 0xc0, 0x1b, 0x0, 0x0, 0x0, 0xb, - 0xc, 0x5, 0x20, 0x60, 0x16, 0x55, 0x55, 0x65, - 0x55, 0x57, 0x40, 0x0, 0x75, 0x55, 0x55, 0xa1, - 0x0, 0x0, 0xb, 0x0, 0x0, 0xb, 0x0, 0x0, - 0x0, 0xb0, 0x0, 0x0, 0xb0, 0x0, 0x0, 0xc, - 0x55, 0x55, 0x5d, 0x0, 0x0, 0x0, 0x20, 0x0, - 0x0, 0x20, 0x0, - - /* U+5589 "喉" */ - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0xc2, 0x55, 0x82, 0x0, 0x54, 0x72, 0x1a, - 0x0, 0xa, 0x0, 0xa, 0x1a, 0x6, 0x30, 0x0, - 0xa0, 0x40, 0xa0, 0xa0, 0xc2, 0x7b, 0x55, 0x55, - 0xa, 0xa, 0x3e, 0x4, 0xa0, 0x2, 0x0, 0xa0, - 0xa4, 0xa0, 0x95, 0xb5, 0x62, 0xa, 0xa, 0xa, - 0x32, 0xb, 0x0, 0x0, 0xa5, 0xc0, 0xa4, 0x55, - 0xc6, 0x59, 0xb, 0x9, 0xa, 0x0, 0xa, 0x60, - 0x0, 0x60, 0x0, 0xa0, 0x6, 0x56, 0x30, 0x0, - 0x0, 0xa, 0x1, 0x90, 0xb, 0x10, 0x0, 0x0, - 0xb2, 0x60, 0x0, 0x3b, 0x0, 0x0, 0x1, 0x10, - 0x0, 0x0, 0x0, - - /* U+559C "喜" */ - 0x0, 0x0, 0x0, 0x30, 0x0, 0x0, 0x0, 0x0, - 0x0, 0xb, 0x10, 0x4, 0x10, 0x2, 0x65, 0x55, - 0xc5, 0x55, 0x75, 0x0, 0x0, 0x22, 0x2c, 0x22, - 0x91, 0x0, 0x0, 0x6, 0x32, 0x22, 0x26, 0x10, - 0x0, 0x0, 0xb5, 0x55, 0x55, 0xc1, 0x0, 0x0, - 0xb, 0x55, 0x55, 0x5c, 0x0, 0x0, 0x0, 0x63, - 0x30, 0x8, 0x40, 0x0, 0x1, 0x11, 0x1b, 0x13, - 0x51, 0x18, 0x21, 0x64, 0x54, 0x44, 0x44, 0x54, - 0x42, 0x0, 0xa, 0x55, 0x55, 0x5b, 0x40, 0x0, - 0x0, 0xa0, 0x0, 0x0, 0x82, 0x0, 0x0, 0xb, - 0x55, 0x55, 0x5b, 0x30, 0x0, 0x0, 0x30, 0x0, - 0x0, 0x20, 0x0, - - /* U+559D "喝" */ - 0x0, 0x0, 0x0, 0x0, 0x0, 0x10, 0x0, 0x0, - 0x10, 0xc5, 0x55, 0x5e, 0x0, 0xb5, 0x6c, 0xc, - 0x0, 0x0, 0xc0, 0xc, 0x1, 0xa0, 0xd5, 0x55, - 0x5c, 0x0, 0xc0, 0x1a, 0xd, 0x55, 0x55, 0xc0, - 0xc, 0x1, 0xa0, 0x8a, 0x0, 0x4, 0x0, 0xc0, - 0x1a, 0xa, 0x73, 0x33, 0x37, 0xc, 0x56, 0xb6, - 0x52, 0x86, 0x22, 0xb0, 0xc0, 0x8, 0xa5, 0x1c, - 0x60, 0x18, 0x9, 0x0, 0x26, 0x38, 0x13, 0xa3, - 0x70, 0x0, 0x0, 0x65, 0x0, 0x16, 0x46, 0x0, - 0x0, 0x6, 0x65, 0x55, 0x47, 0x40, 0x0, 0x0, - 0x0, 0x0, 0x3b, 0xd0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x11, 0x0, - - /* U+55AE "單" */ - 0x0, 0x10, 0x3, 0x2, 0x0, 0x11, 0x0, 0x0, - 0xb5, 0x5c, 0x1b, 0x55, 0x87, 0x0, 0x0, 0xb0, - 0xb, 0xa, 0x0, 0x55, 0x0, 0x0, 0xb5, 0x5a, - 0xb, 0x55, 0x85, 0x0, 0x0, 0x27, 0x55, 0x65, - 0x55, 0xa0, 0x0, 0x0, 0x38, 0x0, 0x90, 0x0, - 0xb0, 0x0, 0x0, 0x2b, 0x55, 0xb5, 0x55, 0xb0, - 0x0, 0x0, 0x28, 0x0, 0x90, 0x0, 0xb0, 0x0, - 0x0, 0x3b, 0x55, 0xb5, 0x55, 0xb0, 0x0, 0x0, - 0x11, 0x0, 0x90, 0x0, 0x13, 0x20, 0x16, 0x55, - 0x55, 0xb5, 0x55, 0x56, 0x60, 0x0, 0x0, 0x0, - 0x90, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xa0, - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x30, 0x0, - 0x0, 0x0, - - /* U+55B6 "営" */ - 0x0, 0x0, 0x0, 0x10, 0x0, 0x0, 0x0, 0x0, - 0x91, 0x9, 0x10, 0x87, 0x0, 0x0, 0x5, 0x90, - 0x57, 0x18, 0x0, 0x0, 0x20, 0x2, 0x0, 0x4, - 0x0, 0x11, 0x8, 0x55, 0x55, 0x55, 0x55, 0x5b, - 0x91, 0xd0, 0x47, 0x55, 0x55, 0xb0, 0x70, 0x11, - 0x5, 0x60, 0x0, 0xb, 0x0, 0x0, 0x0, 0x59, - 0x55, 0x55, 0xb0, 0x0, 0x0, 0x3, 0x20, 0x0, - 0x3, 0x0, 0x0, 0x5, 0x55, 0x55, 0x55, 0x59, - 0x10, 0x0, 0xa1, 0x0, 0x0, 0x0, 0xb0, 0x0, - 0xa, 0x10, 0x0, 0x0, 0xb, 0x0, 0x0, 0xa5, - 0x55, 0x55, 0x55, 0xc0, 0x0, 0x5, 0x0, 0x0, - 0x0, 0x4, 0x0, - - /* U+55CE "嗎" */ - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x9, 0x55, - 0x95, 0x85, 0x59, 0x57, 0x60, 0xb0, 0xa, 0x56, - 0x0, 0xb0, 0x10, 0xb, 0x0, 0xa5, 0x95, 0x5c, - 0x58, 0x20, 0xb0, 0xa, 0x56, 0x0, 0xb0, 0x10, - 0xb, 0x0, 0xa5, 0x95, 0x5c, 0x57, 0x30, 0xb0, - 0xa, 0x56, 0x0, 0xb0, 0x2, 0xc, 0x55, 0xb5, - 0x95, 0x47, 0x45, 0xc2, 0xb0, 0x6, 0x0, 0x0, - 0x4, 0xb, 0x5, 0x0, 0x4, 0x24, 0x26, 0x3a, - 0xb0, 0x0, 0x0, 0x90, 0xc0, 0xc0, 0xab, 0x0, - 0x0, 0x67, 0x7, 0x2, 0x2, 0xa0, 0x0, 0x0, - 0x0, 0x0, 0x39, 0xf5, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x3, 0x0, - - /* U+55EF "嗯" */ - 0x20, 0x3, 0x18, 0x55, 0x55, 0xa3, 0xb, 0x56, - 0xb1, 0xa0, 0x73, 0xa, 0x10, 0xb0, 0x1a, 0x1a, - 0x5b, 0x79, 0xa1, 0xb, 0x1, 0xa1, 0xa0, 0xb0, - 0xa, 0x10, 0xb0, 0x1a, 0x1a, 0x18, 0x94, 0xa1, - 0xb, 0x1, 0xa1, 0xa7, 0x0, 0x7a, 0x10, 0xb5, - 0x6a, 0x1c, 0x55, 0x55, 0xb1, 0xb, 0x1, 0x70, - 0x30, 0x71, 0x2, 0x0, 0x80, 0x0, 0x22, 0x63, - 0xa0, 0x63, 0x0, 0x0, 0x36, 0x28, 0x2, 0x3, - 0xd2, 0x0, 0xd, 0x22, 0x70, 0x1, 0x64, 0x0, - 0x0, 0x0, 0xc, 0x99, 0xb9, 0x0, - - /* U+561B "嘛" */ - 0x0, 0x0, 0x0, 0x2, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, 0xb2, 0x0, 0x0, 0x85, 0x94, 0x75, - 0x58, 0x55, 0x98, 0xb, 0xb, 0x47, 0xb, 0x0, - 0xa1, 0x0, 0xb0, 0xb4, 0x70, 0xa0, 0xa, 0x0, - 0xb, 0xb, 0x4a, 0x5c, 0x94, 0xc6, 0x80, 0xb0, - 0xb5, 0x63, 0xc0, 0xe, 0x40, 0xb, 0xb, 0x64, - 0x8c, 0xb4, 0xe6, 0x0, 0xc5, 0xc9, 0x1a, 0xa2, - 0x8a, 0x70, 0x9, 0x0, 0xa6, 0x2a, 0x25, 0xa2, - 0x90, 0x0, 0x36, 0x50, 0xa5, 0xa, 0xa, 0x30, - 0x7, 0x20, 0xa, 0x0, 0xb0, 0x0, 0x3, 0x10, - 0x0, 0xa0, 0xa, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x0, - - /* U+56B4 "嚴" */ - 0x0, 0x1, 0x0, 0x30, 0x10, 0x2, 0x0, 0x0, - 0x1b, 0x55, 0xc0, 0xb5, 0x5c, 0x0, 0x0, 0x1b, - 0x55, 0xb0, 0xb5, 0x5b, 0x0, 0x0, 0x33, 0x0, - 0x30, 0x40, 0x7, 0x30, 0x0, 0xd5, 0x55, 0x65, - 0x57, 0x56, 0x50, 0x0, 0xb0, 0x65, 0xc1, 0x2b, - 0x0, 0x0, 0x0, 0xb0, 0x0, 0x93, 0x66, 0x25, - 0x40, 0x0, 0xb5, 0xc5, 0x79, 0xb2, 0x49, 0x10, - 0x1, 0xa0, 0xb5, 0x77, 0x73, 0x55, 0x0, 0x2, - 0x80, 0xa0, 0x39, 0x7, 0x91, 0x0, 0x5, 0x40, - 0xb5, 0x77, 0x5, 0xb0, 0x0, 0x7, 0x2, 0xc7, - 0x89, 0x38, 0xa5, 0x0, 0x5, 0x9, 0x40, 0x37, - 0x52, 0xb, 0x90, 0x10, 0x0, 0x0, 0x12, 0x0, - 0x0, 0x0, - - /* U+56DB "四" */ - 0x0, 0x0, 0x0, 0x0, 0x0, 0xa, 0x55, 0x75, - 0x57, 0x55, 0xc2, 0xc0, 0xc, 0x0, 0xc0, 0xc, - 0xc, 0x0, 0xc0, 0xc, 0x0, 0xc0, 0xc0, 0xc, - 0x0, 0xc0, 0xc, 0xc, 0x0, 0xb0, 0xc, 0x0, - 0xc0, 0xc0, 0xb, 0x0, 0xc0, 0xc, 0xc, 0x4, - 0x70, 0xc, 0x0, 0xc0, 0xc0, 0xa1, 0x0, 0xab, - 0xcd, 0xc, 0x73, 0x0, 0x0, 0x0, 0xc0, 0xd1, - 0x0, 0x0, 0x0, 0xc, 0xd, 0x55, 0x55, 0x55, - 0x55, 0xd0, 0xc0, 0x0, 0x0, 0x0, 0xb, 0x0, - 0x0, 0x0, 0x0, 0x0, 0x10, - - /* U+56DE "回" */ - 0x85, 0x55, 0x55, 0x55, 0x59, 0x2c, 0x0, 0x0, - 0x0, 0x0, 0xb0, 0xc0, 0x0, 0x0, 0x0, 0xb, - 0xc, 0x1, 0x75, 0x55, 0x80, 0xb0, 0xc0, 0x1a, - 0x0, 0x1a, 0xb, 0xc, 0x0, 0xa0, 0x1, 0xa0, - 0xb0, 0xc0, 0x1a, 0x0, 0x1a, 0xb, 0xc, 0x1, - 0xc5, 0x56, 0xa0, 0xb0, 0xc0, 0x4, 0x0, 0x2, - 0xb, 0xc, 0x0, 0x0, 0x0, 0x0, 0xb0, 0xd5, - 0x55, 0x55, 0x55, 0x5c, 0xc, 0x0, 0x0, 0x0, - 0x0, 0x80, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - - /* U+56E0 "因" */ - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x1, 0x95, - 0x55, 0x55, 0x55, 0x56, 0xa0, 0x1b, 0x0, 0x1, - 0x60, 0x0, 0x2a, 0x1, 0xb0, 0x0, 0x1b, 0x0, - 0x2, 0xa0, 0x1b, 0x0, 0x1, 0xa0, 0x4, 0x2a, - 0x1, 0xb3, 0x65, 0x6c, 0x56, 0x72, 0xa0, 0x1b, - 0x0, 0x4, 0x90, 0x0, 0x2a, 0x1, 0xb0, 0x0, - 0x88, 0x70, 0x2, 0xa0, 0x1b, 0x0, 0xc, 0x4, - 0xc0, 0x2a, 0x1, 0xb0, 0x9, 0x30, 0x9, 0x72, - 0xa0, 0x1b, 0x16, 0x20, 0x0, 0x14, 0x2a, 0x1, - 0xb0, 0x0, 0x0, 0x0, 0x2, 0xa0, 0x1c, 0x55, - 0x55, 0x55, 0x55, 0x6a, 0x0, 0x10, 0x0, 0x0, - 0x0, 0x0, 0x0, - - /* U+56F0 "困" */ - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xc, 0x55, - 0x55, 0x65, 0x55, 0xc4, 0xc, 0x0, 0x0, 0xd0, - 0x0, 0xa2, 0xc, 0x0, 0x0, 0xc0, 0x0, 0xa2, - 0xc, 0x36, 0x56, 0xd5, 0x79, 0xa2, 0xc, 0x0, - 0xc, 0xc0, 0x0, 0xa2, 0xc, 0x0, 0x47, 0xd5, - 0x0, 0xa2, 0xc, 0x0, 0xa0, 0xc2, 0xc4, 0xa2, - 0xc, 0x8, 0x20, 0xc0, 0x2c, 0xa2, 0xc, 0x52, - 0x0, 0xc0, 0x2, 0xa2, 0xc, 0x0, 0x0, 0xd0, - 0x0, 0xa2, 0xc, 0x0, 0x0, 0x40, 0x0, 0xa2, - 0xd, 0x55, 0x55, 0x55, 0x55, 0xb2, 0x2, 0x0, - 0x0, 0x0, 0x0, 0x0, - - /* U+56F3 "図" */ - 0x30, 0x0, 0x0, 0x0, 0x0, 0x30, 0xb6, 0x55, - 0x55, 0x55, 0x55, 0xd2, 0xb1, 0x0, 0x1, 0x30, - 0x0, 0xb0, 0xb1, 0x0, 0x71, 0xb2, 0x71, 0xb0, - 0xb1, 0x4, 0x2b, 0x56, 0xd1, 0xb0, 0xb1, 0x5, - 0x14, 0x9, 0x40, 0xb0, 0xb1, 0x0, 0x80, 0x3a, - 0x0, 0xb0, 0xb1, 0x0, 0x29, 0xb1, 0x0, 0xb0, - 0xb1, 0x0, 0xb, 0xb0, 0x0, 0xb0, 0xb1, 0x1, - 0x81, 0x3c, 0x72, 0xb0, 0xb1, 0x45, 0x0, 0x1, - 0x89, 0xc0, 0xb3, 0x0, 0x0, 0x0, 0x0, 0xb0, - 0xb6, 0x55, 0x55, 0x55, 0x55, 0xd1, 0x20, 0x0, - 0x0, 0x0, 0x0, 0x20, - - /* U+56FD "国" */ - 0x10, 0x0, 0x0, 0x0, 0x1, 0xd, 0x55, 0x55, - 0x55, 0x55, 0xd2, 0xc0, 0x0, 0x0, 0x3, 0x3c, - 0xc, 0x16, 0x56, 0xb5, 0x53, 0xc0, 0xc0, 0x0, - 0x2a, 0x0, 0xc, 0xc, 0x4, 0x56, 0xb5, 0xa1, - 0xc0, 0xc0, 0x10, 0x2a, 0x20, 0xc, 0xc, 0x0, - 0x2, 0xa9, 0x70, 0xc0, 0xc0, 0x0, 0x2a, 0x9, - 0xc, 0xc, 0x35, 0x56, 0xb5, 0x98, 0xc0, 0xc1, - 0x0, 0x0, 0x0, 0xc, 0xd, 0x55, 0x55, 0x55, - 0x55, 0xd0, 0xc0, 0x0, 0x0, 0x0, 0x9, 0x0, - 0x0, 0x0, 0x0, 0x0, 0x0, - - /* U+570B "國" */ - 0x20, 0x0, 0x0, 0x0, 0x0, 0x30, 0xa6, 0x55, - 0x55, 0x87, 0x55, 0xc2, 0xa1, 0x0, 0x0, 0xc1, - 0xc0, 0xb0, 0xa2, 0x65, 0x55, 0xc5, 0x8a, 0xb0, - 0xa1, 0x0, 0x0, 0xa0, 0x0, 0xb0, 0xa1, 0x95, - 0xb2, 0xa0, 0x65, 0xb0, 0xa1, 0xa0, 0xa0, 0x90, - 0xa1, 0xb0, 0xa1, 0xa5, 0xc0, 0x67, 0x80, 0xb0, - 0xa1, 0x70, 0x40, 0xf, 0x11, 0xc0, 0xa1, 0x36, - 0x63, 0x7a, 0x86, 0xb0, 0xa2, 0x91, 0x6, 0x40, - 0x6f, 0xb0, 0xa1, 0x0, 0x40, 0x0, 0x3, 0xc0, - 0xa6, 0x55, 0x55, 0x55, 0x55, 0xc0, 0x30, 0x0, - 0x0, 0x0, 0x0, 0x20, - - /* U+570D "圍" */ - 0x11, 0x0, 0x0, 0x0, 0x0, 0x3, 0x2, 0xb5, - 0x55, 0x75, 0x55, 0x55, 0xd0, 0x2a, 0x0, 0xa, - 0x10, 0x20, 0xc, 0x2, 0xa0, 0x46, 0xb5, 0x5d, - 0x0, 0xc0, 0x2a, 0x45, 0x5b, 0x55, 0xca, 0x3c, - 0x2, 0xa1, 0x16, 0x55, 0x58, 0x0, 0xc0, 0x2a, - 0x1, 0x90, 0x0, 0xb0, 0xc, 0x2, 0xa0, 0x18, - 0x5c, 0x57, 0x0, 0xc0, 0x2a, 0x6, 0x85, 0xc5, - 0x84, 0xc, 0x2, 0xa0, 0xa8, 0x5c, 0x57, 0x70, - 0xc0, 0x2a, 0x1, 0x0, 0xb0, 0x0, 0xc, 0x2, - 0xa0, 0x0, 0x8, 0x0, 0x0, 0xc0, 0x2b, 0x55, - 0x55, 0x55, 0x55, 0x5c, 0x0, 0x20, 0x0, 0x0, - 0x0, 0x0, 0x20, - - /* U+5712 "園" */ - 0x30, 0x0, 0x0, 0x0, 0x0, 0x30, 0xa6, 0x55, - 0x5a, 0x55, 0x55, 0xd1, 0xa2, 0x0, 0xc, 0x3, - 0x0, 0xc0, 0xa2, 0x6, 0x5c, 0x56, 0x20, 0xc0, - 0xa2, 0x65, 0x5a, 0x55, 0xa3, 0xc0, 0xa2, 0x7, - 0x55, 0x58, 0x20, 0xc0, 0xa2, 0xb, 0x0, 0xa, - 0x10, 0xc0, 0xa2, 0xd, 0x66, 0x5b, 0x10, 0xc0, - 0xa2, 0x3, 0xd1, 0x1, 0xc1, 0xc0, 0xa2, 0x18, - 0xa1, 0x69, 0x10, 0xc0, 0xa4, 0x50, 0x80, 0x9, - 0xa0, 0xc0, 0xa2, 0x0, 0x60, 0x0, 0x70, 0xc0, - 0xa6, 0x55, 0x55, 0x55, 0x55, 0xd0, 0x20, 0x0, - 0x0, 0x0, 0x0, 0x10, - - /* U+5718 "團" */ - 0x30, 0x0, 0x0, 0x0, 0x0, 0x30, 0xb6, 0x55, - 0x5a, 0x65, 0x55, 0xd1, 0xb3, 0x65, 0x5d, 0x55, - 0x76, 0xc0, 0xb1, 0x55, 0x5c, 0x55, 0x80, 0xc0, - 0xb1, 0x86, 0x5c, 0x55, 0xa0, 0xc0, 0xb1, 0x86, - 0x5c, 0x55, 0xa0, 0xc0, 0xb1, 0x50, 0xb, 0x3, - 0x70, 0xc0, 0xb1, 0x9a, 0x88, 0x48, 0x86, 0xc0, - 0xb2, 0x55, 0x55, 0x5c, 0x82, 0xc0, 0xb1, 0x15, - 0x40, 0xa, 0x0, 0xc0, 0xb1, 0x0, 0x72, 0x5a, - 0x0, 0xc0, 0xb1, 0x0, 0x0, 0x74, 0x0, 0xc0, - 0xb6, 0x55, 0x55, 0x55, 0x55, 0xd0, 0x20, 0x0, - 0x0, 0x0, 0x0, 0x10, - - /* U+571F "土" */ - 0x0, 0x0, 0x0, 0x10, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, 0xb4, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0xb1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0xb1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xb1, - 0x0, 0x0, 0x0, 0x2, 0x55, 0x55, 0xc6, 0x55, - 0x9a, 0x0, 0x0, 0x10, 0x0, 0xb1, 0x0, 0x0, - 0x0, 0x0, 0x0, 0x0, 0xb1, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x0, 0xb1, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, 0xb1, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0xb1, 0x0, 0x1, 0x0, 0x26, 0x55, 0x55, - 0xb6, 0x55, 0x5b, 0x90, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x0, - - /* U+5723 "圣" */ - 0x0, 0x0, 0x0, 0x0, 0x0, 0x10, 0x0, 0x0, - 0x16, 0x65, 0x55, 0x58, 0xd0, 0x0, 0x0, 0x0, - 0x32, 0x0, 0xd, 0x50, 0x0, 0x0, 0x0, 0x6, - 0x40, 0xa6, 0x0, 0x0, 0x0, 0x0, 0x0, 0x7c, - 0x70, 0x0, 0x0, 0x0, 0x0, 0x2, 0xb8, 0xb7, - 0x20, 0x0, 0x0, 0x3, 0x87, 0x19, 0x15, 0xbf, - 0xd3, 0x4, 0x53, 0x0, 0xd, 0x0, 0x0, 0x20, - 0x0, 0x0, 0x0, 0xd, 0x0, 0x26, 0x0, 0x0, - 0x26, 0x55, 0x5e, 0x55, 0x55, 0x0, 0x0, 0x0, - 0x0, 0xd, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0xd, 0x0, 0x1, 0x80, 0x5, 0x55, 0x55, 0x56, - 0x55, 0x55, 0x62, - - /* U+5728 "在" */ - 0x0, 0x0, 0x0, 0x30, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, 0xe2, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x6, 0x80, 0x0, 0x6, 0x40, 0x5, 0x65, 0x5d, - 0x55, 0x65, 0x55, 0x40, 0x0, 0x0, 0x58, 0x0, - 0xd0, 0x0, 0x0, 0x0, 0x1, 0xb0, 0x0, 0xc0, - 0x0, 0x0, 0x0, 0xd, 0x20, 0x0, 0xc0, 0x7, - 0x0, 0x0, 0x8c, 0x6, 0x55, 0xd5, 0x55, 0x20, - 0x6, 0x2c, 0x0, 0x0, 0xc0, 0x0, 0x0, 0x10, - 0xc, 0x0, 0x0, 0xc0, 0x0, 0x0, 0x0, 0xc, - 0x0, 0x0, 0xc0, 0x0, 0x0, 0x0, 0xc, 0x45, - 0x55, 0xc5, 0x56, 0xc1, 0x0, 0xc, 0x0, 0x0, - 0x0, 0x0, 0x0, 0x0, 0x1, 0x0, 0x0, 0x0, - 0x0, 0x0, - - /* U+5730 "地" */ - 0x0, 0x0, 0x0, 0x0, 0x1, 0x0, 0x0, 0x0, - 0x29, 0x0, 0x0, 0x1a, 0x0, 0x0, 0x0, 0x29, - 0x0, 0x51, 0x1a, 0x0, 0x0, 0x0, 0x29, 0x0, - 0xb0, 0x1a, 0x3, 0x0, 0x0, 0x29, 0x10, 0xb0, - 0x1b, 0x5d, 0x20, 0x6, 0x7b, 0x83, 0xb5, 0x6a, - 0xb, 0x0, 0x0, 0x29, 0x35, 0xc0, 0x1a, 0xb, - 0x0, 0x0, 0x29, 0x0, 0xb0, 0x1a, 0xb, 0x0, - 0x0, 0x29, 0x0, 0xb0, 0x1a, 0xb, 0x0, 0x0, - 0x29, 0x0, 0xb0, 0x1b, 0x9b, 0x10, 0x0, 0x2c, - 0x64, 0xb0, 0x17, 0x0, 0x50, 0xb, 0xb3, 0x0, - 0xb0, 0x0, 0x0, 0x91, 0x3, 0x0, 0x0, 0x7b, - 0xaa, 0xaa, 0xe4, - - /* U+5747 "均" */ - 0x0, 0x2, 0x0, 0x2, 0x10, 0x0, 0x0, 0x0, - 0xe, 0x0, 0x7, 0x90, 0x0, 0x0, 0x0, 0xc, - 0x0, 0xb, 0x10, 0x0, 0x10, 0x0, 0xc, 0x0, - 0x2b, 0x55, 0x55, 0xd1, 0x5, 0x5d, 0x86, 0x81, - 0x0, 0x0, 0xc0, 0x0, 0xc, 0x2, 0x53, 0x60, - 0x0, 0xc0, 0x0, 0xc, 0x2, 0x0, 0xb6, 0x0, - 0xc0, 0x0, 0xc, 0x0, 0x0, 0x35, 0x0, 0xb0, - 0x0, 0xc, 0x2, 0x10, 0x5, 0x41, 0xb0, 0x0, - 0x2e, 0x83, 0x6, 0x91, 0x2, 0xa0, 0x1d, 0xc3, - 0x2, 0xe6, 0x0, 0x4, 0x80, 0x3, 0x0, 0x0, - 0x20, 0x22, 0x1a, 0x50, 0x0, 0x0, 0x0, 0x0, - 0x5, 0xea, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x10, 0x0, - - /* U+574A "坊" */ - 0x0, 0x0, 0x0, 0x1, 0x0, 0x0, 0x0, 0x0, - 0xc, 0x10, 0x1, 0xb1, 0x0, 0x0, 0x0, 0xc, - 0x0, 0x0, 0x88, 0x0, 0x0, 0x0, 0xc, 0x0, - 0x11, 0x22, 0x11, 0x80, 0x0, 0xc, 0x16, 0x36, - 0xb3, 0x33, 0x31, 0x4, 0x5d, 0x54, 0x4, 0x90, - 0x0, 0x0, 0x0, 0xc, 0x0, 0x5, 0xa5, 0x5b, - 0x60, 0x0, 0xc, 0x0, 0x7, 0x60, 0xa, 0x30, - 0x0, 0xc, 0x0, 0xb, 0x20, 0xb, 0x10, 0x0, - 0x1d, 0x86, 0x2b, 0x0, 0xd, 0x0, 0xc, 0xc4, - 0x0, 0x93, 0x0, 0xd, 0x0, 0x2, 0x0, 0x5, - 0x40, 0x21, 0x3b, 0x0, 0x0, 0x0, 0x53, 0x0, - 0x1a, 0xf4, 0x0, 0x0, 0x2, 0x0, 0x0, 0x0, - 0x10, 0x0, - - /* U+5750 "坐" */ - 0x0, 0x0, 0x0, 0x30, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x95, 0x0, 0x0, 0x0, 0x0, 0xd, - 0x20, 0x92, 0x0, 0xd2, 0x0, 0x0, 0x2c, 0x0, - 0x92, 0x3, 0xb0, 0x0, 0x0, 0x88, 0x0, 0x92, - 0x9, 0x80, 0x0, 0x0, 0xc5, 0xa0, 0x92, 0x1a, - 0x2b, 0x0, 0x6, 0x40, 0xb4, 0x92, 0x71, 0x9, - 0x60, 0x16, 0x0, 0x20, 0x95, 0x30, 0x1, 0x10, - 0x10, 0x35, 0x55, 0xb7, 0x55, 0xd3, 0x0, 0x0, - 0x10, 0x0, 0x92, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x92, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x92, 0x0, 0x5, 0x40, 0x26, 0x55, 0x55, 0x65, - 0x55, 0x57, 0x70, - - /* U+578B "型" */ - 0x0, 0x0, 0x0, 0x0, 0x0, 0x3, 0x0, 0x15, - 0x55, 0x58, 0x80, 0x0, 0xb1, 0x0, 0xa, 0x9, - 0x20, 0xb, 0xb, 0x0, 0x0, 0xa0, 0x92, 0x30, - 0xb0, 0xb0, 0x5, 0x5c, 0x5b, 0x78, 0x3b, 0xb, - 0x0, 0x0, 0xb0, 0x92, 0x0, 0xb0, 0xb0, 0x0, - 0x28, 0x9, 0x20, 0x3, 0xb, 0x0, 0x9, 0x0, - 0x92, 0x0, 0x38, 0xd0, 0x5, 0x10, 0x1, 0xa5, - 0x0, 0x23, 0x0, 0x1, 0x55, 0x5c, 0x75, 0x5c, - 0x30, 0x0, 0x1, 0x0, 0xa3, 0x0, 0x0, 0x0, - 0x0, 0x0, 0xa, 0x30, 0x0, 0x10, 0x4, 0x55, - 0x55, 0xb7, 0x55, 0x5e, 0x80, 0x10, 0x0, 0x0, - 0x0, 0x0, 0x0, - - /* U+57DF "域" */ - 0x0, 0x0, 0x0, 0x0, 0x2, 0x10, 0x0, 0x0, - 0x94, 0x0, 0x0, 0xc, 0x2b, 0x20, 0x0, 0x92, - 0x0, 0x0, 0xb, 0x4, 0x40, 0x0, 0x92, 0x36, - 0x55, 0x5c, 0x56, 0xa1, 0x25, 0xb8, 0x80, 0x0, - 0xb, 0x0, 0x0, 0x1, 0x92, 0xa, 0x5c, 0x3b, - 0xa, 0x30, 0x0, 0x92, 0xa, 0xa, 0xb, 0xd, - 0x0, 0x0, 0x92, 0xa, 0xa, 0xb, 0x57, 0x0, - 0x0, 0x92, 0xa, 0x59, 0xa, 0xc1, 0x0, 0x15, - 0xc7, 0x40, 0x0, 0x28, 0xa0, 0x2, 0x49, 0x10, - 0x68, 0x74, 0x3b, 0xc2, 0x32, 0x0, 0x0, 0x61, - 0x2, 0x90, 0x3d, 0xa1, 0x0, 0x0, 0x0, 0x56, - 0x0, 0x4, 0xe2, 0x0, 0x0, 0x1, 0x10, 0x0, - 0x0, 0x0, - - /* U+57F7 "執" */ - 0x0, 0x3, 0x0, 0x0, 0x20, 0x0, 0x0, 0x0, - 0xc, 0x20, 0x0, 0xc2, 0x0, 0x0, 0x4, 0x5d, - 0x59, 0x0, 0xc0, 0x0, 0x0, 0x0, 0xc, 0x0, - 0x0, 0xc0, 0x3, 0x0, 0x0, 0xc, 0x3, 0x26, - 0xd5, 0x8b, 0x0, 0x27, 0x85, 0x59, 0x30, 0xb0, - 0x57, 0x0, 0x0, 0x93, 0x56, 0x5, 0xb0, 0x65, - 0x0, 0x5, 0x77, 0x99, 0x12, 0xe4, 0x74, 0x0, - 0x0, 0xc, 0x0, 0x4, 0x8d, 0x74, 0x0, 0x25, - 0x5d, 0x5a, 0x49, 0x20, 0x75, 0x10, 0x1, 0xc, - 0x0, 0x19, 0x0, 0x58, 0x60, 0x0, 0xc, 0x0, - 0x91, 0x0, 0xd, 0xa0, 0x0, 0xb, 0x16, 0x10, - 0x0, 0x3, 0xd0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, - - /* U+57FA "基" */ - 0x0, 0x0, 0x20, 0x0, 0x3, 0x0, 0x0, 0x0, - 0x0, 0xd0, 0x0, 0xd, 0x1, 0x0, 0x3, 0x55, - 0xd5, 0x55, 0x5d, 0x5a, 0x30, 0x0, 0x0, 0xc0, - 0x0, 0xc, 0x0, 0x0, 0x0, 0x0, 0xc5, 0x55, - 0x5c, 0x0, 0x0, 0x0, 0x0, 0xc5, 0x55, 0x5c, - 0x0, 0x0, 0x0, 0x0, 0xc0, 0x0, 0xc, 0x5, - 0x40, 0x6, 0x55, 0xc7, 0x75, 0x87, 0x57, 0x60, - 0x0, 0x4, 0x90, 0xb2, 0x9, 0x30, 0x0, 0x0, - 0x57, 0x0, 0xb0, 0x5, 0x9c, 0x71, 0x16, 0x32, - 0x55, 0xc5, 0x56, 0x3, 0x40, 0x0, 0x0, 0x0, - 0xb0, 0x0, 0x0, 0x0, 0x3, 0x55, 0x55, 0xc5, - 0x55, 0x6e, 0x20, 0x0, 0x10, 0x0, 0x0, 0x0, - 0x0, 0x0, - - /* U+5831 "報" */ - 0x0, 0x3, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0xa, 0x20, 0xa, 0x55, 0x59, 0x50, 0x5, 0x5c, - 0x59, 0x1b, 0x0, 0x8, 0x30, 0x0, 0xa, 0x0, - 0xb, 0x0, 0xa, 0x10, 0x25, 0x5c, 0x57, 0x7b, - 0x2, 0xac, 0x0, 0x1, 0x60, 0x35, 0xb, 0x0, - 0x11, 0x0, 0x0, 0x85, 0x72, 0xc, 0x75, 0x5a, - 0x80, 0x6, 0x68, 0x79, 0x3b, 0x40, 0xb, 0x0, - 0x0, 0xa, 0x0, 0xb, 0x7, 0x74, 0x0, 0x25, - 0x5c, 0x57, 0x6b, 0x7, 0xa0, 0x0, 0x1, 0xa, - 0x0, 0xb, 0xa, 0xb3, 0x0, 0x0, 0xa, 0x0, - 0xb, 0x71, 0x1d, 0x80, 0x0, 0xa, 0x10, 0xb, - 0x0, 0x2, 0x50, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, - - /* U+5834 "場" */ - 0x0, 0x20, 0x0, 0x0, 0x0, 0x1, 0x0, 0x0, - 0xa4, 0x0, 0xc5, 0x55, 0x5d, 0x0, 0x0, 0xa2, - 0x0, 0xb0, 0x0, 0xc, 0x0, 0x0, 0xa2, 0x0, - 0xc5, 0x55, 0x5c, 0x0, 0x36, 0xc6, 0x92, 0xd5, - 0x55, 0x5c, 0x0, 0x0, 0xa2, 0x0, 0x60, 0x0, - 0x5, 0x10, 0x0, 0xa2, 0x16, 0x5a, 0x55, 0x56, - 0x90, 0x0, 0xa2, 0x0, 0x7a, 0x55, 0x56, 0x50, - 0x0, 0xa5, 0x67, 0x65, 0x76, 0x66, 0x50, 0x27, - 0xb4, 0x42, 0x28, 0xb, 0x8, 0x20, 0x47, 0x0, - 0x4, 0x60, 0x92, 0xb, 0x0, 0x0, 0x0, 0x12, - 0x8, 0x30, 0xc, 0x0, 0x0, 0x0, 0x3, 0x61, - 0x6, 0xe5, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x10, 0x0, - - /* U+584A "塊" */ - 0x0, 0x10, 0x0, 0x0, 0x30, 0x0, 0x0, 0x0, - 0xa3, 0x0, 0x4, 0x80, 0x0, 0x0, 0x0, 0xa2, - 0xa, 0x57, 0x85, 0x5c, 0x0, 0x0, 0xa2, 0xb, - 0x0, 0xc0, 0xc, 0x0, 0x25, 0xc7, 0x8b, 0x55, - 0xd5, 0x5c, 0x0, 0x1, 0xa2, 0xb, 0x0, 0xc0, - 0xc, 0x0, 0x0, 0xa2, 0xb, 0x1, 0xb0, 0xc, - 0x0, 0x0, 0xa2, 0x9, 0x48, 0xe8, 0x47, 0x0, - 0x0, 0xa2, 0x40, 0xa, 0x84, 0x82, 0x0, 0x1, - 0xb8, 0x10, 0x39, 0x65, 0x74, 0x0, 0x5d, 0x30, - 0x1, 0xa0, 0x6c, 0x79, 0x50, 0x1, 0x0, 0x19, - 0x10, 0x66, 0x2, 0x80, 0x0, 0x3, 0x50, 0x0, - 0x3b, 0x89, 0xc0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, - - /* U+5869 "塩" */ - 0x0, 0x30, 0x0, 0x20, 0x0, 0x0, 0x0, 0x0, - 0xb1, 0x0, 0xa5, 0x0, 0x0, 0x0, 0x0, 0xb0, - 0x0, 0xc5, 0x55, 0x5c, 0x40, 0x0, 0xb0, 0x6, - 0x20, 0x0, 0x0, 0x0, 0x36, 0xd7, 0x56, 0x85, - 0x55, 0x5a, 0x0, 0x0, 0xb0, 0x10, 0xb0, 0x0, - 0xb, 0x0, 0x0, 0xb0, 0x0, 0xb0, 0x0, 0xb, - 0x0, 0x0, 0xb0, 0x1, 0xa5, 0x55, 0x58, 0x0, - 0x0, 0xb1, 0x45, 0x55, 0x55, 0x58, 0x20, 0x3, - 0xc6, 0xb, 0xa, 0xa, 0xa, 0x10, 0x4b, 0x10, - 0xb, 0xa, 0xa, 0xa, 0x10, 0x0, 0x0, 0xb, - 0xa, 0xa, 0xa, 0x10, 0x0, 0x0, 0x4c, 0x5c, - 0x5c, 0x5b, 0xc1, 0x0, 0x0, 0x10, 0x0, 0x0, - 0x0, 0x0, - - /* U+5883 "境" */ - 0x0, 0x0, 0x0, 0x0, 0x30, 0x0, 0x0, 0x0, - 0x2b, 0x0, 0x0, 0x92, 0x1, 0x0, 0x0, 0x29, - 0x1, 0x65, 0x65, 0x68, 0x50, 0x0, 0x29, 0x0, - 0x9, 0x20, 0xc2, 0x0, 0x5, 0x6b, 0xa3, 0x15, - 0x44, 0x51, 0x70, 0x0, 0x29, 0x5, 0x54, 0x44, - 0x45, 0x41, 0x0, 0x29, 0x0, 0xb5, 0x55, 0x5e, - 0x10, 0x0, 0x29, 0x0, 0xb5, 0x55, 0x5c, 0x0, - 0x0, 0x29, 0x13, 0xb0, 0x0, 0xc, 0x0, 0x6, - 0xa9, 0x30, 0xc7, 0x78, 0x5c, 0x0, 0x6, 0x10, - 0x0, 0x9, 0x4b, 0x0, 0x50, 0x0, 0x0, 0x0, - 0x2c, 0xb, 0x0, 0x71, 0x0, 0x0, 0x37, 0x81, - 0x6, 0xb9, 0xd4, 0x0, 0x2, 0x10, 0x0, 0x0, - 0x0, 0x0, - - /* U+5897 "増" */ - 0x0, 0x20, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0xb3, 0x0, 0x49, 0x0, 0x7a, 0x0, 0x0, 0xb1, - 0x0, 0x9, 0x61, 0x80, 0x0, 0x0, 0xb1, 0x8, - 0x56, 0x77, 0x55, 0x90, 0x13, 0xc5, 0x6c, 0x0, - 0xb0, 0x2, 0xa0, 0x13, 0xb2, 0x1c, 0x55, 0xc5, - 0x56, 0xa0, 0x0, 0xb1, 0xc, 0x0, 0xb0, 0x2, - 0xa0, 0x0, 0xb1, 0xa, 0x55, 0x55, 0x56, 0x70, - 0x0, 0xb1, 0x1, 0x85, 0x55, 0x5a, 0x0, 0x0, - 0xb8, 0x61, 0xa0, 0x0, 0xc, 0x0, 0x4c, 0xa1, - 0x0, 0xc5, 0x55, 0x5c, 0x0, 0x15, 0x0, 0x0, - 0xa0, 0x0, 0xc, 0x0, 0x0, 0x0, 0x1, 0xc5, - 0x55, 0x5d, 0x0, 0x0, 0x0, 0x0, 0x30, 0x0, - 0x2, 0x0, - - /* U+589E "增" */ - 0x0, 0x0, 0x0, 0x1, 0x0, 0x1, 0x0, 0x0, - 0x2b, 0x0, 0x9, 0x30, 0x67, 0x0, 0x0, 0x19, - 0x0, 0x22, 0x50, 0x70, 0x30, 0x0, 0x19, 0x0, - 0xc5, 0x5c, 0x55, 0xc0, 0x6, 0x6b, 0xa4, 0xe5, - 0xa, 0x28, 0xa0, 0x0, 0x19, 0x0, 0xad, 0xa, - 0x61, 0xa0, 0x0, 0x19, 0x0, 0xa2, 0xa, 0x10, - 0xa0, 0x0, 0x19, 0x0, 0x95, 0x55, 0x55, 0x80, - 0x0, 0x19, 0x0, 0x56, 0x55, 0x5b, 0x10, 0x0, - 0x3d, 0x63, 0x55, 0x0, 0xb, 0x0, 0xc, 0x91, - 0x0, 0x58, 0x55, 0x5c, 0x0, 0x1, 0x0, 0x0, - 0x55, 0x0, 0xb, 0x0, 0x0, 0x0, 0x0, 0x58, - 0x55, 0x5c, 0x0, 0x0, 0x0, 0x0, 0x10, 0x0, - 0x0, 0x0, - - /* U+58CA "壊" */ - 0x0, 0x10, 0x0, 0x0, 0x40, 0x0, 0x0, 0x0, - 0xb2, 0x0, 0x0, 0xd1, 0x2, 0x20, 0x0, 0xb0, - 0x26, 0x55, 0xd5, 0x56, 0x50, 0x0, 0xb0, 0x5, - 0x55, 0xd5, 0x58, 0x20, 0x25, 0xc6, 0x8a, 0xa, - 0xa, 0xa, 0x0, 0x1, 0xb0, 0xa, 0xa, 0xa, - 0xa, 0x0, 0x0, 0xb0, 0xb, 0x59, 0x59, 0x5c, - 0x0, 0x0, 0xb0, 0x1, 0x0, 0xa1, 0x3, 0x0, - 0x0, 0xb0, 0x26, 0x5b, 0x95, 0x58, 0x20, 0x0, - 0xb6, 0x50, 0x86, 0x24, 0x1b, 0x0, 0x2a, 0x91, - 0x7, 0xc3, 0x9, 0x71, 0x0, 0x5, 0x2, 0x62, - 0x73, 0x42, 0xd4, 0x0, 0x0, 0x1, 0x0, 0x8a, - 0x10, 0x3e, 0x91, 0x0, 0x0, 0x0, 0x10, 0x0, - 0x0, 0x0, - - /* U+58D3 "壓" */ - 0x0, 0x0, 0x0, 0x0, 0x0, 0x3, 0x0, 0xc, - 0x55, 0x55, 0x55, 0x65, 0x83, 0x0, 0xb3, 0x95, - 0x5b, 0xa, 0x27, 0x0, 0xb, 0x39, 0x55, 0xa0, - 0xa0, 0x52, 0x0, 0xb3, 0x75, 0x57, 0x5c, 0x59, - 0x0, 0x9, 0x67, 0x55, 0xb0, 0xa4, 0x0, 0x3, - 0x76, 0x85, 0x5a, 0x9, 0x60, 0x0, 0x62, 0x68, - 0x55, 0xa5, 0x45, 0x50, 0x8, 0x6, 0x40, 0x5a, - 0x60, 0xc, 0x42, 0x30, 0x31, 0x1, 0x70, 0x0, - 0x10, 0x0, 0x25, 0x55, 0x6b, 0x55, 0xa0, 0x0, - 0x0, 0x10, 0x1, 0x80, 0x0, 0x0, 0x4, 0x55, - 0x55, 0x6b, 0x55, 0x5c, 0x80, 0x10, 0x0, 0x0, - 0x0, 0x0, 0x0, - - /* U+58EB "士" */ - 0x0, 0x0, 0x0, 0x20, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, 0xa5, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0xa2, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0xa2, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xa2, - 0x0, 0x0, 0x0, 0x15, 0x55, 0x55, 0xc7, 0x55, - 0x5c, 0x90, 0x1, 0x0, 0x0, 0xa2, 0x0, 0x0, - 0x0, 0x0, 0x0, 0x0, 0xa2, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x0, 0xa2, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, 0xa2, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0xa2, 0x0, 0x0, 0x0, 0x0, 0x55, 0x55, - 0xc7, 0x55, 0xaa, 0x0, 0x0, 0x10, 0x0, 0x0, - 0x0, 0x0, 0x0, - - /* U+58F0 "声" */ - 0x0, 0x0, 0x0, 0x30, 0x0, 0x0, 0x0, 0x0, - 0x0, 0xd, 0x0, 0x0, 0x0, 0x25, 0x55, 0x55, - 0xd5, 0x55, 0x7b, 0x0, 0x0, 0x0, 0xc, 0x0, - 0x0, 0x0, 0x0, 0x65, 0x55, 0xb5, 0x58, 0x80, - 0x0, 0x3, 0x0, 0x0, 0x0, 0x4, 0x0, 0x0, - 0xd5, 0x55, 0xd5, 0x55, 0xd0, 0x0, 0xc, 0x0, - 0xc, 0x0, 0xc, 0x0, 0x0, 0xd5, 0x55, 0xa5, - 0x55, 0xd0, 0x0, 0x1b, 0x0, 0x0, 0x0, 0x2, - 0x0, 0x4, 0x60, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x90, 0x0, 0x0, 0x0, 0x0, 0x0, 0x53, 0x0, - 0x0, 0x0, 0x0, 0x0, 0x1, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x0, - - /* U+58F2 "売" */ - 0x0, 0x0, 0x0, 0x30, 0x0, 0x0, 0x0, 0x0, - 0x0, 0xa, 0x20, 0x2, 0x10, 0x2, 0x65, 0x55, - 0xc6, 0x55, 0x86, 0x0, 0x0, 0x0, 0xa, 0x10, - 0x21, 0x0, 0x0, 0x16, 0x55, 0x75, 0x57, 0x40, - 0x0, 0x55, 0x55, 0x55, 0x55, 0x55, 0x82, 0xa, - 0x10, 0x0, 0x0, 0x0, 0xa, 0x20, 0x80, 0x6, - 0x60, 0x36, 0x1, 0x10, 0x0, 0x0, 0x86, 0x4, - 0x80, 0x0, 0x0, 0x0, 0x9, 0x30, 0x48, 0x0, - 0x0, 0x0, 0x0, 0xc0, 0x4, 0x80, 0x4, 0x0, - 0x0, 0x58, 0x0, 0x38, 0x0, 0x52, 0x0, 0x66, - 0x0, 0x2, 0xea, 0xac, 0x51, 0x40, 0x0, 0x0, - 0x0, 0x0, 0x0, - - /* U+5909 "変" */ - 0x0, 0x0, 0x0, 0x20, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x5a, 0x0, 0x0, 0x30, 0x4, 0x65, - 0x58, 0x59, 0x68, 0x56, 0xb3, 0x0, 0x2, 0x1c, - 0x0, 0x3b, 0x0, 0x0, 0x0, 0x1c, 0x4c, 0x0, - 0x3c, 0x86, 0x0, 0x0, 0x91, 0x1c, 0x0, 0x3b, - 0x8, 0xb0, 0x5, 0x0, 0xa, 0x10, 0x11, 0x0, - 0x50, 0x0, 0x0, 0x4e, 0x65, 0x55, 0x91, 0x0, - 0x0, 0x2, 0x95, 0x0, 0x7, 0xc2, 0x0, 0x0, - 0x35, 0x4, 0x60, 0x7a, 0x0, 0x0, 0x0, 0x10, - 0x0, 0x6d, 0x80, 0x0, 0x0, 0x0, 0x0, 0x17, - 0x94, 0xa9, 0x40, 0x0, 0x1, 0x56, 0x61, 0x0, - 0x3, 0x9e, 0xe5, 0x2, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x10, - - /* U+590F "夏" */ - 0x0, 0x0, 0x0, 0x0, 0x0, 0x3, 0x0, 0x3, - 0x65, 0x55, 0xa5, 0x55, 0x5a, 0x20, 0x0, 0x7, - 0x56, 0x85, 0x55, 0x90, 0x0, 0x0, 0xc, 0x0, - 0x0, 0x0, 0xc0, 0x0, 0x0, 0xd, 0x55, 0x55, - 0x55, 0xc0, 0x0, 0x0, 0xd, 0x55, 0x55, 0x55, - 0xc0, 0x0, 0x0, 0xc, 0x0, 0x0, 0x0, 0xc0, - 0x0, 0x0, 0xc, 0x6e, 0x55, 0x55, 0x80, 0x0, - 0x0, 0x0, 0x99, 0x55, 0x5c, 0x20, 0x0, 0x0, - 0x6, 0x55, 0x10, 0xa6, 0x0, 0x0, 0x0, 0x64, - 0x0, 0x9a, 0x50, 0x0, 0x0, 0x3, 0x10, 0x5, - 0x97, 0xa6, 0x20, 0x0, 0x1, 0x56, 0x72, 0x0, - 0x6, 0xbe, 0x92, 0x12, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, - - /* U+5915 "夕" */ - 0x0, 0x0, 0x0, 0x10, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x1f, 0x30, 0x0, 0x0, 0x0, 0x0, 0x6, - 0xb0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xd8, 0x55, - 0x57, 0xd1, 0x0, 0x0, 0x5a, 0x0, 0x0, 0x8a, - 0x0, 0x0, 0xc, 0x10, 0x0, 0xe, 0x20, 0x0, - 0x7, 0x88, 0x0, 0x7, 0x90, 0x0, 0x3, 0x70, - 0x5d, 0x1, 0xe1, 0x0, 0x1, 0x60, 0x0, 0xc2, - 0xa5, 0x0, 0x0, 0x0, 0x0, 0x0, 0x79, 0x0, - 0x0, 0x0, 0x0, 0x0, 0x88, 0x0, 0x0, 0x0, - 0x0, 0x3, 0xa5, 0x0, 0x0, 0x0, 0x1, 0x57, - 0x50, 0x0, 0x0, 0x0, 0x0, 0x30, 0x0, 0x0, - 0x0, 0x0, 0x0, - - /* U+5916 "外" */ - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0xe2, 0x0, 0xd, 0x10, 0x0, 0x0, 0x3c, 0x0, - 0x0, 0xc0, 0x0, 0x0, 0x8, 0x60, 0x23, 0xc, - 0x0, 0x0, 0x0, 0xc5, 0x5a, 0xb0, 0xc0, 0x0, - 0x0, 0x48, 0x0, 0xc2, 0xd, 0x10, 0x0, 0xa, - 0x84, 0x1c, 0x0, 0xc6, 0xa2, 0x4, 0x40, 0xd7, - 0x50, 0xc, 0x3, 0xe1, 0x30, 0x1, 0xc0, 0x0, - 0xc0, 0x4, 0x0, 0x0, 0x65, 0x0, 0xc, 0x0, - 0x0, 0x0, 0x29, 0x0, 0x0, 0xc0, 0x0, 0x0, - 0x27, 0x0, 0x0, 0xc, 0x0, 0x0, 0x34, 0x0, - 0x0, 0x0, 0xd0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x4, 0x0, 0x0, - - /* U+591A "多" */ - 0x0, 0x0, 0x1, 0x10, 0x0, 0x0, 0x0, 0x0, - 0xc, 0x50, 0x0, 0x0, 0x0, 0x1, 0xb8, 0x55, - 0x59, 0xb0, 0x0, 0x48, 0x72, 0x0, 0x5c, 0x10, - 0x15, 0x20, 0x1b, 0x8, 0x80, 0x0, 0x0, 0x0, - 0x6, 0xa3, 0x0, 0x0, 0x0, 0x37, 0x86, 0xc1, - 0x0, 0x0, 0x24, 0x20, 0x2d, 0x95, 0x55, 0x93, - 0x0, 0x5, 0xb2, 0x0, 0x4, 0xc2, 0x2, 0x75, - 0x38, 0x0, 0x4b, 0x10, 0x2, 0x0, 0xd, 0x7, - 0x90, 0x0, 0x0, 0x0, 0x17, 0x93, 0x0, 0x0, - 0x3, 0x56, 0x62, 0x0, 0x0, 0x0, 0x21, 0x0, - 0x0, 0x0, 0x0, 0x0, - - /* U+591C "夜" */ - 0x0, 0x0, 0x0, 0x30, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x78, 0x0, 0x0, 0x0, 0x5, 0x55, - 0x55, 0x58, 0x55, 0x57, 0xb0, 0x1, 0x2, 0xc0, - 0x1d, 0x0, 0x0, 0x0, 0x0, 0x9, 0x60, 0x68, - 0x0, 0x14, 0x0, 0x0, 0x1c, 0x0, 0xb5, 0x55, - 0x99, 0x0, 0x0, 0x8e, 0x3, 0x93, 0x60, 0xb2, - 0x0, 0x2, 0x7c, 0x9, 0x60, 0xb1, 0xb0, 0x0, - 0x6, 0xc, 0x52, 0x16, 0x8, 0x50, 0x0, 0x0, - 0xc, 0x0, 0x6, 0x5b, 0x0, 0x0, 0x0, 0xc, - 0x0, 0x0, 0xf6, 0x0, 0x0, 0x0, 0xc, 0x0, - 0x19, 0x4a, 0x92, 0x0, 0x0, 0xc, 0x5, 0x70, - 0x0, 0x6e, 0xc2, 0x0, 0x4, 0x30, 0x0, 0x0, - 0x0, 0x10, - - /* U+5920 "夠" */ - 0x0, 0x2, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0xc, 0x30, 0x0, 0xd2, 0x0, 0x0, 0x0, 0x77, - 0x58, 0xc4, 0x90, 0x0, 0x10, 0x5, 0x84, 0xc, - 0x2a, 0x55, 0x55, 0xd0, 0x11, 0x6, 0xa3, 0x53, - 0x0, 0x0, 0xb0, 0x0, 0x9, 0x52, 0x42, 0x0, - 0x40, 0xb0, 0x4, 0x77, 0xa0, 0x1b, 0x55, 0xc0, - 0xb0, 0x11, 0x2b, 0x57, 0xeb, 0x0, 0xb0, 0xb0, - 0x1, 0xb1, 0x9, 0x5a, 0x0, 0xb0, 0xb0, 0x16, - 0x1b, 0x2b, 0xb, 0x55, 0xb1, 0xa0, 0x0, 0x3, - 0xb2, 0x0, 0x0, 0x3, 0x80, 0x0, 0x19, 0x30, - 0x0, 0x12, 0x17, 0x60, 0x4, 0x60, 0x0, 0x0, - 0x5, 0xde, 0x10, 0x10, 0x0, 0x0, 0x0, 0x0, - 0x10, 0x0, - - /* U+5927 "大" */ - 0x0, 0x0, 0x0, 0x30, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, 0xd2, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0xd0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0xd0, 0x0, 0x2, 0x10, 0x6, 0x55, 0x55, 0xe5, - 0x55, 0x59, 0x80, 0x0, 0x0, 0x0, 0xe2, 0x0, - 0x0, 0x0, 0x0, 0x0, 0x0, 0xc6, 0x0, 0x0, - 0x0, 0x0, 0x0, 0x4, 0x87, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x9, 0x31, 0x80, 0x0, 0x0, 0x0, - 0x0, 0x1c, 0x0, 0x73, 0x0, 0x0, 0x0, 0x0, - 0xb2, 0x0, 0xa, 0x40, 0x0, 0x0, 0x1a, 0x30, - 0x0, 0x1, 0xda, 0x30, 0x5, 0x70, 0x0, 0x0, - 0x0, 0xa, 0x70, 0x10, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, - - /* U+5929 "天" */ - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x45, 0x55, 0x55, 0x55, 0xd4, 0x0, 0x0, 0x10, - 0x0, 0xd0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0xd0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xd0, - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xd0, 0x0, - 0x1b, 0x10, 0x6, 0x55, 0x56, 0xc8, 0x55, 0x55, - 0x30, 0x0, 0x0, 0x6, 0x75, 0x0, 0x0, 0x0, - 0x0, 0x0, 0xb, 0x21, 0x70, 0x0, 0x0, 0x0, - 0x0, 0x3a, 0x0, 0x82, 0x0, 0x0, 0x0, 0x0, - 0xb1, 0x0, 0x1c, 0x30, 0x0, 0x0, 0x9, 0x10, - 0x0, 0x3, 0xe8, 0x20, 0x3, 0x70, 0x0, 0x0, - 0x0, 0x2c, 0xa1, 0x1, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, - - /* U+592A "太" */ - 0x0, 0x0, 0x0, 0x30, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, 0xb5, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0xb2, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0xb1, 0x0, 0x3, 0x10, 0x5, 0x65, 0x55, 0xd7, - 0x55, 0x5a, 0x70, 0x0, 0x0, 0x0, 0xd6, 0x0, - 0x0, 0x0, 0x0, 0x0, 0x3, 0xa2, 0x50, 0x0, - 0x0, 0x0, 0x0, 0x8, 0x50, 0xa0, 0x0, 0x0, - 0x0, 0x0, 0xc, 0x0, 0x65, 0x0, 0x0, 0x0, - 0x0, 0x87, 0x10, 0xc, 0x10, 0x0, 0x0, 0x4, - 0x80, 0xb5, 0x3, 0xc1, 0x0, 0x0, 0x47, 0x0, - 0x1e, 0x0, 0x6e, 0x60, 0x5, 0x30, 0x0, 0x2, - 0x0, 0x6, 0x71, 0x10, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, - - /* U+592B "夫" */ - 0x0, 0x0, 0x0, 0x20, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x96, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x93, 0x0, 0x1, 0x0, 0x0, 0x55, 0x55, - 0xb7, 0x55, 0x87, 0x0, 0x0, 0x0, 0x0, 0xa3, - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xa2, 0x0, - 0x2, 0x0, 0x6, 0x55, 0x55, 0xd6, 0x55, 0x5b, - 0x80, 0x0, 0x0, 0x1, 0xd4, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x6, 0x70, 0x60, 0x0, 0x0, 0x0, - 0x0, 0x1c, 0x0, 0x72, 0x0, 0x0, 0x0, 0x0, - 0xa3, 0x0, 0xb, 0x20, 0x0, 0x0, 0x19, 0x20, - 0x0, 0x2, 0xe7, 0x10, 0x4, 0x50, 0x0, 0x0, - 0x0, 0x2c, 0x80, 0x10, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, - - /* U+592E "央" */ - 0x0, 0x0, 0x0, 0x12, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x3b, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x3a, 0x0, 0x0, 0x0, 0x0, 0xa, 0x55, - 0x7c, 0x55, 0xc2, 0x0, 0x0, 0xd, 0x0, 0x39, - 0x0, 0xd0, 0x0, 0x0, 0xd, 0x0, 0x39, 0x0, - 0xd0, 0x0, 0x0, 0xd, 0x0, 0x48, 0x0, 0xd0, - 0x10, 0x4, 0x6b, 0x55, 0x9a, 0x55, 0xb8, 0xb0, - 0x0, 0x0, 0x0, 0x94, 0x50, 0x0, 0x0, 0x0, - 0x0, 0x1, 0xc0, 0x71, 0x0, 0x0, 0x0, 0x0, - 0xa, 0x30, 0x1b, 0x10, 0x0, 0x0, 0x2, 0x93, - 0x0, 0x2, 0xd7, 0x20, 0x2, 0x65, 0x0, 0x0, - 0x0, 0x1a, 0xb1, 0x2, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, - - /* U+5931 "失" */ - 0x0, 0x0, 0x0, 0x41, 0x0, 0x0, 0x0, 0x0, - 0x2, 0x0, 0x96, 0x0, 0x0, 0x0, 0x0, 0xe, - 0x20, 0x93, 0x0, 0x0, 0x0, 0x0, 0x2d, 0x55, - 0xb7, 0x55, 0xd4, 0x0, 0x0, 0x72, 0x0, 0xa3, - 0x0, 0x0, 0x0, 0x0, 0x70, 0x0, 0xb1, 0x0, - 0x0, 0x0, 0x0, 0x0, 0x0, 0xc0, 0x0, 0x9, - 0x30, 0x6, 0x55, 0x55, 0xd8, 0x55, 0x55, 0x40, - 0x0, 0x0, 0x4, 0x83, 0x30, 0x0, 0x0, 0x0, - 0x0, 0xb, 0x10, 0x90, 0x0, 0x0, 0x0, 0x0, - 0x67, 0x0, 0x2a, 0x0, 0x0, 0x0, 0x6, 0x70, - 0x0, 0x4, 0xc4, 0x0, 0x2, 0x73, 0x0, 0x0, - 0x0, 0x4e, 0x90, 0x2, 0x0, 0x0, 0x0, 0x0, - 0x1, 0x0, - - /* U+5947 "奇" */ - 0x0, 0x0, 0x0, 0x20, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x97, 0x0, 0x0, 0x0, 0x0, 0x55, - 0x55, 0xd6, 0x55, 0x7b, 0x0, 0x0, 0x10, 0x5, - 0x96, 0x30, 0x0, 0x0, 0x0, 0x0, 0x58, 0x0, - 0x5c, 0x80, 0x0, 0x0, 0x46, 0x30, 0x0, 0x0, - 0x92, 0x80, 0x6, 0x55, 0x55, 0x55, 0x55, 0xc5, - 0x62, 0x0, 0x3, 0x0, 0x4, 0x0, 0xc0, 0x0, - 0x0, 0xd, 0x55, 0x5d, 0x10, 0xc0, 0x0, 0x0, - 0xc, 0x0, 0xc, 0x0, 0xc0, 0x0, 0x0, 0xd, - 0x55, 0x5d, 0x0, 0xc0, 0x0, 0x0, 0xa, 0x0, - 0x5, 0x0, 0xd0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x5d, 0xb0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x1, - 0x0, 0x0, - - /* U+5951 "契" */ - 0x0, 0x0, 0x30, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0xc0, 0x10, 0x0, 0x0, 0x20, 0x3, 0x65, - 0xc5, 0x93, 0x6b, 0x56, 0xd0, 0x0, 0x0, 0xb1, - 0x30, 0xc, 0x2, 0xa0, 0x0, 0x65, 0xc5, 0x40, - 0x48, 0x4, 0x80, 0x3, 0x55, 0xc5, 0xa2, 0xb1, - 0x6, 0x60, 0x0, 0x0, 0xb0, 0x8, 0x33, 0x6c, - 0x20, 0x0, 0x0, 0xc1, 0x70, 0x0, 0x55, 0x0, - 0x0, 0x0, 0x0, 0x95, 0x0, 0x5, 0x40, 0x5, - 0x65, 0x55, 0xd8, 0x55, 0x55, 0x50, 0x0, 0x0, - 0x7, 0x50, 0x80, 0x0, 0x0, 0x0, 0x0, 0x77, - 0x0, 0x1a, 0x60, 0x0, 0x0, 0x58, 0x30, 0x0, - 0x0, 0x8e, 0xb2, 0x4, 0x0, 0x0, 0x0, 0x0, - 0x1, 0x10, - - /* U+5957 "套" */ - 0x0, 0x0, 0x0, 0x40, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x2, 0xd1, 0x0, 0x2, 0x0, 0x2, 0x65, - 0x5c, 0x85, 0x65, 0x5b, 0x20, 0x0, 0x0, 0x59, - 0x0, 0x53, 0x0, 0x0, 0x0, 0x3, 0xa0, 0x0, - 0x1a, 0x60, 0x0, 0x0, 0x56, 0xc5, 0x55, 0x66, - 0x7e, 0x91, 0x15, 0x20, 0xc5, 0x55, 0x79, 0x2, - 0x20, 0x0, 0x0, 0xc0, 0x0, 0x2, 0x0, 0x0, - 0x0, 0x0, 0xc5, 0x55, 0x58, 0x30, 0x0, 0x5, - 0x55, 0xd5, 0x55, 0x55, 0x5c, 0x90, 0x1, 0x0, - 0xa, 0x60, 0x30, 0x0, 0x0, 0x0, 0x0, 0x73, - 0x0, 0x9, 0x90, 0x0, 0x0, 0x9, 0xc9, 0x76, - 0x54, 0x87, 0x0, 0x0, 0x1, 0x0, 0x0, 0x0, - 0x1, 0x0, - - /* U+5973 "女" */ - 0x0, 0x0, 0x0, 0x20, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, 0xb7, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0xe0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x4, - 0xa0, 0x0, 0x0, 0x10, 0x5, 0x55, 0x5a, 0x85, - 0x55, 0x59, 0xc0, 0x0, 0x0, 0xc, 0x0, 0xb, - 0x40, 0x0, 0x0, 0x0, 0x48, 0x0, 0xe, 0x0, - 0x0, 0x0, 0x0, 0xa2, 0x0, 0x69, 0x0, 0x0, - 0x0, 0x1, 0xd1, 0x0, 0xc2, 0x0, 0x0, 0x0, - 0x0, 0x16, 0x89, 0xa0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x4c, 0xab, 0x50, 0x0, 0x0, 0x0, 0x8, - 0x80, 0x3, 0xdb, 0x0, 0x0, 0x36, 0x71, 0x0, - 0x0, 0xa, 0x10, 0x3, 0x10, 0x0, 0x0, 0x0, - 0x0, 0x0, - - /* U+5979 "她" */ - 0x0, 0x3, 0x0, 0x0, 0x1, 0x0, 0x0, 0x0, - 0xe, 0x10, 0x0, 0xd, 0x0, 0x0, 0x0, 0x1b, - 0x0, 0x14, 0xb, 0x0, 0x0, 0x0, 0x38, 0x3, - 0x2a, 0xb, 0x1, 0x0, 0x6, 0x98, 0x6b, 0x19, - 0xc, 0x5d, 0x20, 0x0, 0x73, 0x38, 0x7b, 0x5b, - 0xb, 0x0, 0x0, 0xa0, 0x65, 0x19, 0xb, 0xc, - 0x0, 0x0, 0xa0, 0x82, 0x19, 0xb, 0xc, 0x0, - 0x0, 0x90, 0xb0, 0x19, 0xb, 0x5c, 0x0, 0x2, - 0x93, 0xa0, 0x19, 0xc, 0x24, 0x10, 0x0, 0xa, - 0xc3, 0x19, 0xb, 0x0, 0x50, 0x0, 0x27, 0x1d, - 0x2a, 0x0, 0x0, 0x90, 0x2, 0x70, 0x1, 0xd, - 0xa9, 0x9a, 0xd1, 0x3, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, - - /* U+597D "好" */ - 0x0, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0xd, 0x10, 0x0, 0x0, 0x4, 0x0, 0x0, 0xc, - 0x0, 0x25, 0x55, 0x6e, 0x30, 0x0, 0x29, 0x3, - 0x0, 0x0, 0x81, 0x0, 0x15, 0x99, 0x5d, 0x10, - 0x8, 0x30, 0x0, 0x0, 0x92, 0xb, 0x0, 0xc, - 0x0, 0x0, 0x0, 0xa0, 0x38, 0x0, 0xc, 0x0, - 0x70, 0x0, 0x90, 0x75, 0x55, 0x5d, 0x55, 0x51, - 0x4, 0x50, 0xb0, 0x0, 0xc, 0x0, 0x0, 0x2, - 0x67, 0xb0, 0x0, 0xc, 0x0, 0x0, 0x0, 0x9, - 0xba, 0x0, 0xc, 0x0, 0x0, 0x0, 0x65, 0x8, - 0x40, 0xc, 0x0, 0x0, 0x6, 0x30, 0x0, 0x6, - 0xbc, 0x0, 0x0, 0x10, 0x0, 0x0, 0x0, 0x31, - 0x0, 0x0, - - /* U+5982 "如" */ - 0x0, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x7, 0x80, 0x0, 0x0, 0x0, 0x0, 0x0, 0x9, - 0x30, 0x0, 0x0, 0x0, 0x0, 0x0, 0xc, 0x0, - 0x50, 0x95, 0x55, 0xc0, 0x6, 0x5d, 0x55, 0xd0, - 0xb0, 0x0, 0xb0, 0x0, 0x29, 0x2, 0xa0, 0xb0, - 0x0, 0xb0, 0x0, 0x65, 0x5, 0x70, 0xb0, 0x0, - 0xb0, 0x0, 0x91, 0x8, 0x40, 0xb0, 0x0, 0xb0, - 0x0, 0xb0, 0xb, 0x0, 0xb0, 0x0, 0xb0, 0x0, - 0x57, 0x7b, 0x0, 0xb0, 0x0, 0xb0, 0x0, 0x0, - 0x9b, 0xa0, 0xc5, 0x55, 0xb0, 0x0, 0x7, 0x40, - 0x73, 0xb0, 0x0, 0xb0, 0x2, 0x72, 0x0, 0x0, - 0x40, 0x0, 0x10, 0x1, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, - - /* U+5987 "妇" */ - 0x0, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0xd, 0x20, 0x0, 0x0, 0x0, 0x0, 0x0, 0xd, - 0x0, 0x12, 0x22, 0x22, 0x60, 0x0, 0x2a, 0x2, - 0x44, 0x33, 0x34, 0xb0, 0x5, 0x89, 0x5b, 0x50, - 0x0, 0x2, 0xa0, 0x0, 0x83, 0xb, 0x0, 0x0, - 0x2, 0xa0, 0x0, 0xb0, 0xb, 0x6, 0x55, 0x56, - 0xa0, 0x0, 0xb0, 0x1a, 0x0, 0x0, 0x2, 0xa0, - 0x1, 0x92, 0x65, 0x0, 0x0, 0x2, 0xa0, 0x0, - 0x6, 0xe4, 0x0, 0x0, 0x2, 0xa0, 0x0, 0x3, - 0x9c, 0x30, 0x0, 0x2, 0xa0, 0x0, 0x19, 0x1, - 0x46, 0x55, 0x56, 0xa0, 0x1, 0x70, 0x0, 0x0, - 0x0, 0x1, 0x80, 0x3, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, - - /* U+59B3 "妳" */ - 0x0, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x2d, 0x0, 0x5, 0x90, 0x0, 0x0, 0x0, 0x58, - 0x0, 0x9, 0x50, 0x0, 0x0, 0x0, 0x83, 0x3, - 0xd, 0x44, 0x44, 0x70, 0x36, 0xd5, 0x7b, 0x37, - 0x0, 0x5, 0x90, 0x0, 0xb0, 0x56, 0x70, 0x6, - 0x15, 0x0, 0x5, 0x60, 0x93, 0x20, 0xc, 0x0, - 0x0, 0x9, 0x10, 0xc0, 0x7, 0x1c, 0x3, 0x0, - 0xb, 0x1, 0xa0, 0x1c, 0xc, 0x7, 0x50, 0x1, - 0x7b, 0x60, 0x63, 0xc, 0x0, 0xd1, 0x0, 0x1b, - 0xc6, 0x50, 0xc, 0x0, 0x50, 0x0, 0x91, 0x5, - 0x0, 0xc, 0x0, 0x0, 0x7, 0x10, 0x0, 0x3, - 0xad, 0x0, 0x0, 0x10, 0x0, 0x0, 0x0, 0x12, - 0x0, 0x0, - - /* U+59B9 "妹" */ - 0x0, 0x2, 0x0, 0x0, 0x2, 0x0, 0x0, 0x0, - 0xc, 0x20, 0x0, 0xd, 0x0, 0x0, 0x0, 0xc, - 0x0, 0x0, 0xb, 0x0, 0x0, 0x0, 0x38, 0x4, - 0x26, 0x5c, 0x58, 0x40, 0x6, 0xa7, 0x5d, 0x0, - 0xb, 0x0, 0x0, 0x0, 0xa0, 0x29, 0x0, 0xb, - 0x0, 0x50, 0x0, 0xa0, 0x56, 0x65, 0xbd, 0x75, - 0x52, 0x3, 0x60, 0x92, 0x0, 0xcb, 0x60, 0x0, - 0x7, 0x40, 0xb0, 0x6, 0x5b, 0x61, 0x0, 0x0, - 0x5a, 0x90, 0xa, 0xb, 0x19, 0x0, 0x0, 0x9, - 0x96, 0x72, 0xb, 0x8, 0x80, 0x0, 0x62, 0x6, - 0x30, 0xb, 0x0, 0xb5, 0x4, 0x30, 0x2, 0x0, - 0xc, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x2, - 0x0, 0x0, - - /* U+59BB "妻" */ - 0x0, 0x0, 0x0, 0x30, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, 0xc1, 0x0, 0x9, 0x20, 0x6, 0x55, - 0x55, 0xd5, 0x55, 0x55, 0x30, 0x0, 0x25, 0x55, - 0xd5, 0x55, 0x90, 0x0, 0x0, 0x0, 0x0, 0xc0, - 0x1, 0xa0, 0x40, 0x7, 0x55, 0x55, 0xd5, 0x56, - 0xc6, 0x81, 0x0, 0x0, 0x0, 0xc0, 0x1, 0xb0, - 0x0, 0x0, 0x36, 0x5c, 0x65, 0x55, 0x70, 0x0, - 0x25, 0x55, 0x6d, 0x55, 0x55, 0x57, 0xc1, 0x1, - 0x0, 0x92, 0x0, 0x6a, 0x0, 0x0, 0x0, 0x1, - 0x85, 0x56, 0xb0, 0x0, 0x0, 0x0, 0x0, 0x1, - 0x99, 0x9c, 0x92, 0x0, 0x3, 0x55, 0x66, 0x10, - 0x0, 0x4a, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, - - /* U+59C9 "姉" */ - 0x0, 0x1, 0x0, 0x0, 0x1, 0x0, 0x0, 0x3, - 0xc0, 0x0, 0x0, 0xc0, 0x0, 0x0, 0x66, 0x0, - 0x0, 0xb, 0x0, 0x0, 0xa, 0x20, 0x25, 0x55, - 0xc5, 0x95, 0x36, 0xd5, 0x89, 0x10, 0xb, 0x0, - 0x0, 0x29, 0x7, 0x52, 0x0, 0xb0, 0x30, 0x6, - 0x50, 0xa1, 0xb5, 0x5c, 0x5b, 0x20, 0xa0, 0xb, - 0xb, 0x0, 0xb0, 0xa1, 0xb, 0x3, 0x80, 0xb0, - 0xb, 0xa, 0x10, 0x38, 0xc4, 0xb, 0x0, 0xb0, - 0xa1, 0x0, 0x2a, 0xc5, 0xb0, 0xb, 0x4c, 0x10, - 0x9, 0x0, 0x54, 0x0, 0xb3, 0x70, 0x7, 0x10, - 0x0, 0x0, 0xc, 0x0, 0x2, 0x0, 0x0, 0x0, - 0x0, 0x20, 0x0, - - /* U+59CB "始" */ - 0x0, 0x1, 0x0, 0x0, 0x20, 0x0, 0x0, 0x0, - 0xd, 0x20, 0x0, 0x97, 0x0, 0x0, 0x0, 0x1b, - 0x0, 0x0, 0xc0, 0x0, 0x0, 0x0, 0x47, 0x3, - 0x5, 0x50, 0x43, 0x0, 0x16, 0xb7, 0x5e, 0x19, - 0x0, 0xb, 0x40, 0x0, 0xb0, 0x1a, 0x8c, 0x86, - 0x56, 0xc0, 0x1, 0x90, 0x57, 0x13, 0x0, 0x0, - 0x30, 0x6, 0x50, 0x92, 0x7, 0x55, 0x59, 0x20, - 0x9, 0x20, 0xc0, 0xc, 0x0, 0xb, 0x0, 0x0, - 0x5b, 0xa0, 0xc, 0x0, 0xb, 0x0, 0x0, 0xb, - 0x9b, 0xc, 0x0, 0xb, 0x0, 0x0, 0x82, 0x8, - 0xd, 0x55, 0x5d, 0x0, 0x6, 0x20, 0x0, 0xc, - 0x0, 0xa, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, - - /* U+59D0 "姐" */ - 0x0, 0x4, 0x10, 0x0, 0x0, 0x0, 0x0, 0x0, - 0xd, 0x20, 0x8, 0x55, 0x59, 0x10, 0x0, 0x1c, - 0x0, 0xc, 0x0, 0xc, 0x0, 0x2, 0x69, 0x26, - 0xc, 0x0, 0xc, 0x0, 0x3, 0xa5, 0x3d, 0x1c, - 0x0, 0xc, 0x0, 0x0, 0xb0, 0xb, 0xd, 0x55, - 0x5d, 0x0, 0x1, 0x90, 0x48, 0xc, 0x0, 0xc, - 0x0, 0x6, 0x40, 0x83, 0xc, 0x0, 0xc, 0x0, - 0x9, 0x20, 0xb0, 0xd, 0x55, 0x5d, 0x0, 0x0, - 0x4a, 0xb0, 0xc, 0x0, 0xc, 0x0, 0x0, 0xb, - 0x6c, 0x1c, 0x0, 0xc, 0x0, 0x0, 0x82, 0x4, - 0x2c, 0x0, 0xc, 0x20, 0x6, 0x10, 0x5, 0x68, - 0x55, 0x58, 0x92, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, - - /* U+59D4 "委" */ - 0x0, 0x0, 0x0, 0x0, 0x1, 0x40, 0x0, 0x0, - 0x3, 0x46, 0x79, 0x99, 0x81, 0x0, 0x0, 0x0, - 0x0, 0x2a, 0x0, 0x0, 0x10, 0x5, 0x65, 0x55, - 0x9c, 0x65, 0x57, 0xc1, 0x0, 0x0, 0xa, 0x7a, - 0x62, 0x0, 0x0, 0x0, 0x1, 0xa4, 0x1a, 0x8, - 0x92, 0x0, 0x0, 0x57, 0x10, 0x57, 0x0, 0x4d, - 0xd3, 0x4, 0x10, 0x5, 0xc0, 0x0, 0x0, 0x50, - 0x7, 0x55, 0x6c, 0x65, 0x5a, 0x56, 0xa2, 0x0, - 0x0, 0xa3, 0x0, 0x4a, 0x0, 0x0, 0x0, 0x0, - 0x55, 0x77, 0xd1, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x6a, 0x7d, 0xa3, 0x0, 0x0, 0x25, 0x68, 0x30, - 0x0, 0x6e, 0x20, 0x3, 0x20, 0x0, 0x0, 0x0, - 0x1, 0x10, - - /* U+5A18 "娘" */ - 0x0, 0x2, 0x0, 0x0, 0x20, 0x0, 0x0, 0x0, - 0xb, 0x50, 0x0, 0x1c, 0x0, 0x0, 0x0, 0xd, - 0x0, 0x8, 0x5b, 0x59, 0x10, 0x2, 0x4b, 0x36, - 0xb, 0x0, 0xb, 0x0, 0x3, 0x77, 0x2c, 0x1c, - 0x55, 0x5c, 0x0, 0x0, 0x92, 0xb, 0xb, 0x0, - 0xb, 0x0, 0x0, 0xb0, 0x28, 0xb, 0x0, 0xb, - 0x0, 0x1, 0x90, 0x64, 0xc, 0x58, 0x59, 0x10, - 0x4, 0x70, 0xa0, 0xb, 0x7, 0x6, 0xa0, 0x0, - 0x39, 0xc0, 0xb, 0x7, 0x65, 0x0, 0x0, 0x9, - 0x8c, 0xb, 0x2, 0xc1, 0x0, 0x0, 0x56, 0x4, - 0xc, 0x83, 0x4d, 0x71, 0x5, 0x50, 0x0, 0xc, - 0x10, 0x2, 0x81, 0x1, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, - - /* U+5A5A "婚" */ - 0x0, 0x2, 0x0, 0x0, 0x0, 0x2, 0x0, 0x0, - 0x1d, 0x0, 0x22, 0x58, 0xb8, 0x0, 0x0, 0x48, - 0x0, 0xb3, 0x1b, 0x0, 0x0, 0x0, 0x74, 0x2, - 0xa1, 0x1b, 0x11, 0x50, 0x15, 0xc5, 0x88, 0xa4, - 0x4a, 0x64, 0x40, 0x0, 0xb0, 0x74, 0xa0, 0x23, - 0xa0, 0x40, 0x3, 0x70, 0xa1, 0xd9, 0x30, 0x5b, - 0xb0, 0x7, 0x30, 0xb0, 0x40, 0x0, 0x6, 0xa1, - 0xa, 0x12, 0x80, 0x97, 0x55, 0x5d, 0x10, 0x0, - 0x6c, 0x50, 0x93, 0x0, 0xb, 0x0, 0x0, 0x29, - 0xc4, 0x87, 0x55, 0x5c, 0x0, 0x0, 0x80, 0x16, - 0x93, 0x0, 0xb, 0x0, 0x6, 0x0, 0x0, 0x97, - 0x55, 0x5c, 0x0, 0x0, 0x0, 0x0, 0x20, 0x0, - 0x0, 0x0, - - /* U+5A66 "婦" */ - 0x0, 0x11, 0x0, 0x0, 0x0, 0x1, 0x0, 0x0, - 0x5a, 0x0, 0x55, 0x55, 0x5d, 0x10, 0x0, 0x84, - 0x0, 0x15, 0x55, 0x5c, 0x0, 0x12, 0xb2, 0x42, - 0x1, 0x0, 0xb, 0x0, 0x15, 0xc3, 0xa6, 0x46, - 0x55, 0x5c, 0x0, 0x2, 0x80, 0xb4, 0x0, 0x0, - 0x0, 0x30, 0x7, 0x40, 0xb8, 0x55, 0x6b, 0x56, - 0xc1, 0xa, 0x1, 0x99, 0x20, 0x1a, 0x5, 0x0, - 0xa, 0x6, 0x50, 0xb5, 0x6b, 0x5d, 0x10, 0x0, - 0x7e, 0x30, 0xb0, 0x1a, 0xb, 0x0, 0x0, 0x38, - 0xc3, 0xb0, 0x1a, 0xb, 0x0, 0x1, 0x80, 0x13, - 0xb0, 0x1a, 0x6c, 0x0, 0x15, 0x0, 0x0, 0x0, - 0x1a, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x2, - 0x0, 0x0, - - /* U+5A92 "媒" */ - 0x0, 0x3, 0x0, 0x2, 0x0, 0x2, 0x0, 0x0, - 0xe, 0x10, 0x1c, 0x0, 0xd, 0x0, 0x0, 0x2a, - 0x3, 0x5c, 0x55, 0x5c, 0x91, 0x1, 0x67, 0x15, - 0xa, 0x0, 0xb, 0x0, 0x5, 0xb5, 0x5b, 0xc, - 0x55, 0x5b, 0x0, 0x0, 0xb0, 0x47, 0xa, 0x0, - 0xb, 0x0, 0x1, 0xa0, 0x73, 0x1c, 0x55, 0x5b, - 0x0, 0x4, 0x50, 0xa0, 0x2, 0x1c, 0x0, 0x0, - 0x7, 0x30, 0xa3, 0x65, 0x8d, 0x55, 0xa0, 0x0, - 0x4b, 0x80, 0x3, 0xbb, 0x50, 0x0, 0x0, 0x1a, - 0x97, 0x1b, 0x2a, 0x63, 0x0, 0x0, 0x81, 0x4, - 0x91, 0x1a, 0xa, 0x81, 0x6, 0x20, 0x36, 0x0, - 0x1b, 0x0, 0x60, 0x0, 0x0, 0x0, 0x0, 0x2, - 0x0, 0x0, - - /* U+5ABD "媽" */ - 0x0, 0x2, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x2c, 0x0, 0xa5, 0x58, 0x58, 0x60, 0x0, 0x67, - 0x0, 0xb0, 0xb, 0x0, 0x0, 0x0, 0x93, 0x2, - 0xb5, 0x5c, 0x59, 0x20, 0x26, 0xd5, 0x88, 0xb0, - 0xb, 0x0, 0x0, 0x1, 0xa0, 0x74, 0xb5, 0x5c, - 0x58, 0x40, 0x5, 0x60, 0xa1, 0xb0, 0xb, 0x0, - 0x0, 0x9, 0x20, 0xb0, 0xb5, 0x5b, 0x55, 0xa2, - 0xb, 0x3, 0x80, 0x40, 0x0, 0x20, 0xc0, 0x2, - 0x7c, 0x50, 0x24, 0x8, 0x29, 0xc0, 0x0, 0x1a, - 0xb4, 0x84, 0x78, 0x3a, 0xc0, 0x0, 0x80, 0x7, - 0x72, 0x51, 0x1, 0xc0, 0x6, 0x10, 0x0, 0x0, - 0x3, 0x9e, 0x60, 0x10, 0x0, 0x0, 0x0, 0x0, - 0x3, 0x0, - - /* U+5ACC "嫌" */ - 0x0, 0x42, 0x0, 0x10, 0x0, 0x40, 0x0, 0x0, - 0xa4, 0x0, 0xb, 0x4, 0x80, 0x0, 0x0, 0xb0, - 0x5, 0x5a, 0x59, 0x5a, 0x40, 0x13, 0xc3, 0x73, - 0xa, 0xa, 0x0, 0x0, 0x15, 0x92, 0xc1, 0x6c, - 0x5c, 0x5a, 0x0, 0x5, 0x50, 0xb0, 0xa, 0xa, - 0xa, 0x0, 0x8, 0x12, 0x85, 0x5c, 0x5c, 0x5c, - 0x80, 0xa, 0x5, 0x40, 0xa, 0xa, 0xa, 0x0, - 0xa, 0x19, 0x2, 0x7f, 0x5c, 0x79, 0x0, 0x0, - 0x7d, 0x20, 0x7d, 0xa, 0x60, 0x0, 0x0, 0x84, - 0xa3, 0x6a, 0xa, 0x27, 0x0, 0x4, 0x50, 0x16, - 0xa, 0xa, 0x9, 0x90, 0x24, 0x0, 0x30, 0xa, - 0xb, 0x0, 0x20, 0x0, 0x0, 0x0, 0x2, 0x1, - 0x0, 0x0, - - /* U+5B09 "嬉" */ - 0x0, 0x10, 0x0, 0x0, 0x11, 0x0, 0x0, 0x0, - 0x68, 0x0, 0x0, 0x2b, 0x0, 0x0, 0x0, 0x92, - 0x3, 0x65, 0x6b, 0x57, 0x70, 0x0, 0xb0, 0x31, - 0x12, 0x4a, 0x27, 0x0, 0x36, 0xc5, 0xb3, 0x43, - 0x22, 0x25, 0x0, 0x4, 0x70, 0xb0, 0xa5, 0x55, - 0x5d, 0x0, 0x8, 0x30, 0xb0, 0xa5, 0x55, 0x5c, - 0x0, 0xb, 0x3, 0x80, 0x25, 0x10, 0x72, 0x0, - 0xa, 0x8, 0x32, 0x26, 0x82, 0x72, 0x60, 0x5, - 0x8d, 0x4, 0x53, 0x33, 0x36, 0x30, 0x0, 0x69, - 0xd0, 0xb5, 0x55, 0x5d, 0x10, 0x1, 0x90, 0x30, - 0xb0, 0x0, 0xb, 0x0, 0x17, 0x0, 0x0, 0xb5, - 0x55, 0x5c, 0x0, 0x10, 0x0, 0x0, 0x20, 0x0, - 0x0, 0x0, - - /* U+5B50 "子" */ - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x16, 0x55, 0x55, 0x55, 0x7c, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x3, 0xb5, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x56, 0x0, 0x0, 0x0, 0x0, 0x0, 0x2c, - 0x30, 0x0, 0x0, 0x0, 0x0, 0x0, 0x2c, 0x0, - 0x0, 0x50, 0x6, 0x55, 0x55, 0x6c, 0x55, 0x56, - 0x92, 0x0, 0x0, 0x0, 0x1b, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x0, 0x1b, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x1b, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x1b, 0x0, 0x0, 0x0, 0x0, 0x0, 0x12, - 0x3b, 0x0, 0x0, 0x0, 0x0, 0x0, 0x17, 0xf7, - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x20, 0x0, - 0x0, 0x0, - - /* U+5B57 "字" */ - 0x0, 0x0, 0x0, 0x40, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x5a, 0x0, 0x0, 0x0, 0x0, 0x30, - 0x0, 0x7, 0x0, 0x2, 0x60, 0x0, 0xa5, 0x55, - 0x55, 0x55, 0x5a, 0x90, 0x3, 0xc3, 0x55, 0x55, - 0x56, 0x73, 0x0, 0x0, 0x0, 0x10, 0x0, 0x2b, - 0x50, 0x0, 0x0, 0x0, 0x0, 0x3, 0x60, 0x0, - 0x0, 0x0, 0x0, 0x0, 0x1c, 0x0, 0x0, 0x70, - 0x6, 0x55, 0x55, 0x6c, 0x55, 0x55, 0x72, 0x0, - 0x0, 0x0, 0x1a, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x1a, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x1a, 0x0, 0x0, 0x0, 0x0, 0x0, 0x28, 0xe8, - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x30, 0x0, - 0x0, 0x0, - - /* U+5B58 "存" */ - 0x0, 0x0, 0x1, 0x20, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x6, 0xa0, 0x0, 0x3, 0x0, 0x6, 0x55, - 0x5d, 0x65, 0x55, 0x6b, 0x30, 0x0, 0x0, 0x39, - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xa4, 0x55, - 0x55, 0x95, 0x0, 0x0, 0x9, 0x60, 0x0, 0x4, - 0x82, 0x0, 0x0, 0x2e, 0x10, 0x0, 0x85, 0x0, - 0x0, 0x0, 0x9b, 0x10, 0x0, 0xc0, 0x0, 0x0, - 0x8, 0x1a, 0x26, 0x55, 0xd5, 0x58, 0x80, 0x30, - 0xa, 0x10, 0x0, 0xc0, 0x0, 0x0, 0x0, 0xa, - 0x10, 0x0, 0xc0, 0x0, 0x0, 0x0, 0xa, 0x20, - 0x0, 0xc0, 0x0, 0x0, 0x0, 0xb, 0x20, 0x3b, - 0xd0, 0x0, 0x0, 0x0, 0x2, 0x0, 0x1, 0x10, - 0x0, 0x0, - - /* U+5B63 "季" */ - 0x0, 0x0, 0x0, 0x0, 0x0, 0x20, 0x0, 0x0, - 0x0, 0x2, 0x47, 0xac, 0xc2, 0x0, 0x0, 0x3, - 0x43, 0x3a, 0x0, 0x0, 0x0, 0x5, 0x55, 0x55, - 0x5c, 0x55, 0x56, 0xd2, 0x0, 0x0, 0x8, 0x8a, - 0x71, 0x0, 0x0, 0x0, 0x0, 0x95, 0x1a, 0x9, - 0x71, 0x0, 0x0, 0x58, 0x10, 0x18, 0x0, 0x6d, - 0xd4, 0x4, 0x11, 0x65, 0x55, 0x5c, 0xa0, 0x20, - 0x0, 0x0, 0x0, 0x6, 0x61, 0x0, 0x0, 0x4, - 0x55, 0x55, 0x5d, 0x55, 0x58, 0xd1, 0x1, 0x0, - 0x0, 0xa, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0xa, 0x0, 0x0, 0x0, 0x0, 0x0, 0x6, 0xd8, - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x20, 0x0, - 0x0, 0x0, - - /* U+5B66 "学" */ - 0x0, 0x0, 0x0, 0x0, 0x1, 0x0, 0x0, 0x8, - 0x0, 0xa0, 0x0, 0xe2, 0x0, 0x0, 0x6b, 0x9, - 0x70, 0x66, 0x0, 0x0, 0x20, 0x90, 0x32, 0x8, - 0x0, 0x20, 0xa, 0x55, 0x55, 0x55, 0x65, 0x6f, - 0x25, 0xa0, 0x0, 0x0, 0x1, 0x16, 0x20, 0x32, - 0x46, 0x55, 0x55, 0xd8, 0x0, 0x0, 0x0, 0x0, - 0x1, 0x73, 0x0, 0x0, 0x0, 0x0, 0x0, 0xd0, - 0x0, 0x38, 0x5, 0x65, 0x55, 0x5d, 0x55, 0x55, - 0x51, 0x0, 0x0, 0x0, 0xc0, 0x0, 0x0, 0x0, - 0x0, 0x0, 0xc, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x6e, 0x90, 0x0, 0x0, 0x0, 0x0, 0x0, 0x10, - 0x0, 0x0, 0x0, - - /* U+5B69 "孩" */ - 0x0, 0x0, 0x0, 0x0, 0x20, 0x0, 0x0, 0x0, - 0x11, 0x15, 0x0, 0x59, 0x0, 0x0, 0x2, 0x43, - 0x89, 0x0, 0x9, 0x0, 0x70, 0x0, 0x1, 0x62, - 0x55, 0xd6, 0x55, 0x52, 0x0, 0xc, 0x0, 0x4, - 0x80, 0x21, 0x0, 0x0, 0xb, 0x2, 0x8, 0x0, - 0xc6, 0x0, 0x0, 0xc, 0x73, 0x8a, 0x68, 0xa0, - 0x0, 0x5, 0xac, 0x0, 0x0, 0x1b, 0x8, 0x50, - 0x1a, 0x1b, 0x0, 0x1, 0xa1, 0x3b, 0x0, 0x0, - 0xb, 0x0, 0x38, 0x11, 0xb1, 0x0, 0x0, 0xb, - 0x4, 0x30, 0x2b, 0x74, 0x0, 0x0, 0xb, 0x0, - 0x6, 0x80, 0xa, 0x70, 0x2, 0xc7, 0x25, 0x61, - 0x0, 0x1, 0xb0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, - - /* U+5B6B "孫" */ - 0x0, 0x0, 0x0, 0x0, 0x0, 0x1, 0x0, 0x0, - 0x0, 0x14, 0x2, 0x57, 0x9b, 0x50, 0x4, 0x55, - 0xa9, 0x22, 0x88, 0x0, 0x0, 0x0, 0x1, 0x60, - 0x1, 0xa0, 0x32, 0x0, 0x0, 0x2b, 0x0, 0x39, - 0x44, 0xc4, 0x0, 0x0, 0x19, 0x0, 0x46, 0x4a, - 0x30, 0x0, 0x0, 0x1b, 0x62, 0x1, 0x91, 0x15, - 0x0, 0x5, 0xab, 0x0, 0x7b, 0x55, 0x58, 0x90, - 0x9, 0x29, 0x0, 0x55, 0x2b, 0x0, 0xa0, 0x0, - 0x19, 0x0, 0x17, 0xb, 0x30, 0x0, 0x0, 0x19, - 0x0, 0x95, 0xb, 0xa, 0x20, 0x0, 0x29, 0x5, - 0x40, 0xb, 0x2, 0xe0, 0x2, 0xd6, 0x11, 0x6, - 0xe9, 0x0, 0x60, 0x0, 0x10, 0x0, 0x0, 0x20, - 0x0, 0x0, - - /* U+5B78 "學" */ - 0x0, 0x0, 0x3, 0x2, 0x20, 0x0, 0x0, 0x0, - 0x29, 0x64, 0x3c, 0x45, 0xb4, 0x0, 0x0, 0x1b, - 0x72, 0x44, 0x65, 0xc1, 0x0, 0x0, 0x9, 0x0, - 0x24, 0x30, 0xa0, 0x0, 0x0, 0xc, 0x65, 0x3e, - 0x15, 0xc0, 0x0, 0x4, 0xa, 0x0, 0x53, 0x40, - 0xb0, 0x30, 0xa, 0x55, 0x55, 0x55, 0x55, 0x58, - 0xb0, 0x1c, 0x3, 0x55, 0x55, 0x7b, 0x4, 0x0, - 0x0, 0x0, 0x0, 0x5, 0x60, 0x0, 0x0, 0x4, - 0x55, 0x55, 0x6e, 0x55, 0x5b, 0x90, 0x1, 0x0, - 0x0, 0x1a, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x1a, 0x0, 0x0, 0x0, 0x0, 0x0, 0x6, 0xd7, - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x20, 0x0, - 0x0, 0x0, - - /* U+5B83 "它" */ - 0x0, 0x0, 0x0, 0x20, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x95, 0x0, 0x0, 0x0, 0x0, 0x30, - 0x0, 0x28, 0x0, 0x1, 0x20, 0x3, 0x95, 0x55, - 0x55, 0x55, 0x5b, 0xb0, 0xc, 0x50, 0x0, 0x0, - 0x0, 0x7, 0x0, 0x2, 0x0, 0xd1, 0x0, 0x0, - 0x0, 0x0, 0x0, 0x0, 0xc0, 0x0, 0x2c, 0x20, - 0x0, 0x0, 0x0, 0xc0, 0x17, 0xa4, 0x10, 0x0, - 0x0, 0x0, 0xd5, 0x50, 0x0, 0x0, 0x0, 0x0, - 0x0, 0xc0, 0x0, 0x0, 0x2, 0x0, 0x0, 0x0, - 0xc0, 0x0, 0x0, 0x6, 0x0, 0x0, 0x0, 0xc0, - 0x0, 0x0, 0xb, 0x0, 0x0, 0x0, 0xab, 0xaa, - 0xaa, 0xbc, 0x20, - - /* U+5B85 "宅" */ - 0x0, 0x0, 0x0, 0x20, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x85, 0x0, 0x0, 0x0, 0x0, 0x20, - 0x0, 0x36, 0x0, 0x1, 0x20, 0x0, 0xa5, 0x55, - 0x55, 0x55, 0x5a, 0x90, 0x3, 0xc0, 0x0, 0x3, - 0x9d, 0x27, 0x0, 0x0, 0x34, 0x57, 0xd6, 0x30, - 0x0, 0x0, 0x0, 0x0, 0x0, 0xc0, 0x0, 0x1, - 0x0, 0x0, 0x0, 0x0, 0xc0, 0x2, 0x6e, 0x40, - 0x0, 0x14, 0x55, 0xd5, 0x53, 0x10, 0x0, 0x6, - 0x31, 0x0, 0xc0, 0x0, 0x0, 0x10, 0x0, 0x0, - 0x0, 0xc0, 0x0, 0x0, 0x50, 0x0, 0x0, 0x0, - 0xc0, 0x0, 0x0, 0xa0, 0x0, 0x0, 0x0, 0xbb, - 0xaa, 0xab, 0xc0, - - /* U+5B87 "宇" */ - 0x0, 0x0, 0x3, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x68, 0x0, 0x0, 0x0, 0x3, 0x0, 0x1, - 0x70, 0x0, 0x23, 0x0, 0xa5, 0x55, 0x55, 0x55, - 0x5b, 0x80, 0x2c, 0x0, 0x0, 0x0, 0x2, 0x50, - 0x0, 0x5, 0x55, 0x58, 0x56, 0xa1, 0x0, 0x0, - 0x0, 0x1, 0xa0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x1a, 0x0, 0x3, 0x80, 0x55, 0x55, 0x56, 0xc5, - 0x55, 0x55, 0x10, 0x0, 0x0, 0x1a, 0x0, 0x0, - 0x0, 0x0, 0x0, 0x1, 0xa0, 0x0, 0x0, 0x0, - 0x0, 0x10, 0x3a, 0x0, 0x0, 0x0, 0x0, 0x2, - 0x8f, 0x60, 0x0, 0x0, 0x0, 0x0, 0x0, 0x20, - 0x0, 0x0, 0x0, - - /* U+5B88 "守" */ - 0x0, 0x0, 0x0, 0x20, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x9, 0x60, 0x0, 0x0, 0x0, 0x20, 0x0, - 0x29, 0x0, 0x2, 0x0, 0xa, 0x55, 0x55, 0x55, - 0x55, 0xe7, 0x4, 0xb0, 0x0, 0x0, 0xa2, 0x35, - 0x0, 0x10, 0x0, 0x0, 0xd, 0x0, 0x20, 0x5, - 0x55, 0x55, 0x55, 0xe5, 0x5a, 0x70, 0x0, 0x40, - 0x0, 0xd, 0x0, 0x0, 0x0, 0x2, 0xb0, 0x0, - 0xd0, 0x0, 0x0, 0x0, 0xb, 0x40, 0xd, 0x0, - 0x0, 0x0, 0x0, 0x30, 0x0, 0xd0, 0x0, 0x0, - 0x0, 0x0, 0x0, 0xd, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x4d, 0xc0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x10, 0x0, 0x0, - - /* U+5B89 "安" */ - 0x0, 0x0, 0x0, 0x30, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x58, 0x0, 0x0, 0x0, 0x0, 0x20, - 0x0, 0x8, 0x0, 0x3, 0x10, 0x0, 0x95, 0x55, - 0x55, 0x55, 0x5c, 0x60, 0x2, 0xb0, 0x3, 0x60, - 0x0, 0x14, 0x0, 0x0, 0x0, 0x8, 0x50, 0x0, - 0x0, 0x10, 0x5, 0x55, 0x5d, 0x55, 0x57, 0x59, - 0x90, 0x0, 0x0, 0x57, 0x0, 0x1d, 0x0, 0x0, - 0x0, 0x0, 0xb0, 0x0, 0x86, 0x0, 0x0, 0x0, - 0x1, 0x86, 0x33, 0xc0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x5e, 0xb5, 0x0, 0x0, 0x0, 0x0, 0x5, - 0xa2, 0x6, 0xd8, 0x0, 0x0, 0x36, 0x84, 0x0, - 0x0, 0x1a, 0x50, 0x3, 0x20, 0x0, 0x0, 0x0, - 0x0, 0x0, - - /* U+5B8C "完" */ - 0x0, 0x0, 0x0, 0x20, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x85, 0x0, 0x0, 0x0, 0x0, 0x40, - 0x0, 0x26, 0x0, 0x0, 0x30, 0x0, 0xb5, 0x55, - 0x55, 0x55, 0x58, 0xa0, 0x3, 0x80, 0x0, 0x0, - 0x4, 0x3, 0x0, 0x0, 0x5, 0x55, 0x55, 0x55, - 0x30, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x3, - 0x0, 0x1, 0x55, 0x59, 0x55, 0x85, 0x5a, 0x40, - 0x0, 0x0, 0xc, 0x2, 0xa0, 0x0, 0x0, 0x0, - 0x0, 0x29, 0x2, 0xa0, 0x0, 0x10, 0x0, 0x0, - 0x84, 0x2, 0xa0, 0x0, 0x50, 0x0, 0x2, 0xa0, - 0x1, 0xa0, 0x0, 0x90, 0x0, 0x67, 0x0, 0x0, - 0xba, 0xaa, 0xd3, 0x4, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, - - /* U+5B98 "官" */ - 0x0, 0x0, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x1b, 0x20, 0x0, 0x0, 0x0, 0x20, 0x0, - 0x64, 0x0, 0x3, 0x20, 0x68, 0x55, 0x55, 0x55, - 0x55, 0xc7, 0xd, 0x16, 0x55, 0x55, 0x59, 0x23, - 0x0, 0x0, 0xc0, 0x0, 0x0, 0xc0, 0x0, 0x0, - 0xb, 0x0, 0x0, 0xc, 0x0, 0x0, 0x0, 0xb5, - 0x55, 0x55, 0xb0, 0x0, 0x0, 0xb, 0x0, 0x0, - 0x0, 0x10, 0x0, 0x0, 0xb5, 0x55, 0x55, 0x98, - 0x0, 0x0, 0xb, 0x0, 0x0, 0x6, 0x60, 0x0, - 0x0, 0xb0, 0x0, 0x0, 0x66, 0x0, 0x0, 0xc, - 0x55, 0x55, 0x59, 0x50, 0x0, 0x0, 0x20, 0x0, - 0x0, 0x0, 0x0, - - /* U+5B99 "宙" */ - 0x0, 0x0, 0x1, 0x10, 0x0, 0x0, 0x0, 0x0, - 0x0, 0xb, 0x20, 0x0, 0x0, 0x2, 0x0, 0x0, - 0x54, 0x0, 0x2, 0x10, 0x95, 0x55, 0x57, 0x55, - 0x55, 0xc7, 0x1d, 0x0, 0x0, 0xc2, 0x0, 0x14, - 0x0, 0x1, 0x0, 0xc, 0x0, 0x1, 0x0, 0x0, - 0x96, 0x55, 0xd5, 0x55, 0xe1, 0x0, 0x9, 0x20, - 0xc, 0x0, 0xc, 0x0, 0x0, 0x92, 0x0, 0xc0, - 0x0, 0xc0, 0x0, 0x9, 0x75, 0x5d, 0x55, 0x5c, - 0x0, 0x0, 0x92, 0x0, 0xc0, 0x0, 0xc0, 0x0, - 0x9, 0x20, 0xc, 0x0, 0xc, 0x0, 0x0, 0x97, - 0x55, 0x55, 0x55, 0xd0, 0x0, 0x3, 0x0, 0x0, - 0x0, 0x2, 0x0, - - /* U+5B9A "定" */ - 0x0, 0x0, 0x2, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x85, 0x0, 0x0, 0x0, 0x3, 0x0, 0x2, - 0x60, 0x0, 0x13, 0x0, 0xa5, 0x55, 0x55, 0x55, - 0x5a, 0xa0, 0x3b, 0x0, 0x0, 0x0, 0x0, 0x50, - 0x0, 0x45, 0x55, 0x55, 0x55, 0x7c, 0x10, 0x1, - 0x0, 0x2, 0x90, 0x0, 0x0, 0x0, 0x5, 0x70, - 0x29, 0x0, 0x0, 0x0, 0x0, 0x87, 0x2, 0xb5, - 0x5b, 0x50, 0x0, 0xa, 0x50, 0x29, 0x0, 0x0, - 0x0, 0x1, 0xa4, 0x32, 0x90, 0x0, 0x0, 0x0, - 0x82, 0x6, 0xaa, 0x10, 0x0, 0x0, 0x44, 0x0, - 0x2, 0x8b, 0xde, 0xf9, 0x1, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x0, - - /* U+5B9E "实" */ - 0x0, 0x0, 0x0, 0x40, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x6a, 0x0, 0x0, 0x0, 0x0, 0x30, - 0x0, 0x9, 0x0, 0x1, 0x30, 0x0, 0xa5, 0x55, - 0x55, 0x55, 0x5a, 0xc0, 0x8, 0x80, 0x65, 0x7, - 0x70, 0x7, 0x0, 0x2, 0x0, 0xd, 0x18, 0x50, - 0x0, 0x0, 0x0, 0x18, 0x12, 0xa, 0x30, 0x0, - 0x0, 0x0, 0x5, 0xc0, 0xb, 0x10, 0x0, 0x0, - 0x4, 0x55, 0x95, 0x5e, 0x55, 0x58, 0xb0, 0x1, - 0x0, 0x0, 0x4a, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0xc5, 0x87, 0x10, 0x0, 0x0, 0x0, 0x2b, - 0x40, 0x5, 0xe7, 0x0, 0x1, 0x57, 0x60, 0x0, - 0x0, 0x2d, 0x0, 0x2, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, - - /* U+5B9F "実" */ - 0x0, 0x0, 0x0, 0x30, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x9, 0x70, 0x0, 0x0, 0x2, 0x20, 0x0, - 0x26, 0x0, 0x5, 0x20, 0x78, 0x55, 0x56, 0x55, - 0x55, 0xd6, 0xd, 0x20, 0x0, 0xa3, 0x0, 0x22, - 0x0, 0x4, 0x55, 0x5c, 0x65, 0x5c, 0x10, 0x0, - 0x10, 0x0, 0xa1, 0x0, 0x20, 0x0, 0x1, 0x55, - 0x5c, 0x65, 0x78, 0x0, 0x4, 0x55, 0x55, 0xc6, - 0x55, 0x6d, 0x20, 0x10, 0x0, 0x1d, 0x50, 0x0, - 0x0, 0x0, 0x0, 0x8, 0x61, 0x70, 0x0, 0x0, - 0x0, 0x8, 0x90, 0x3, 0xb5, 0x0, 0x1, 0x58, - 0x30, 0x0, 0x2, 0xae, 0x40, 0x10, 0x0, 0x0, - 0x0, 0x0, 0x0, - - /* U+5BA2 "客" */ - 0x0, 0x0, 0x0, 0x40, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x5b, 0x0, 0x0, 0x0, 0x0, 0x95, - 0x55, 0x59, 0x55, 0x55, 0xb0, 0x5, 0x80, 0xb, - 0x20, 0x0, 0x6, 0x60, 0x5, 0x10, 0x6c, 0x55, - 0x5b, 0x52, 0x0, 0x0, 0x2, 0x93, 0x30, 0x6a, - 0x0, 0x0, 0x0, 0x27, 0x0, 0x69, 0x90, 0x0, - 0x0, 0x0, 0x30, 0x0, 0x98, 0x94, 0x0, 0x0, - 0x0, 0x0, 0x68, 0x20, 0x7, 0xda, 0x84, 0x4, - 0x56, 0xc5, 0x55, 0x55, 0xc4, 0x70, 0x0, 0x0, - 0xb0, 0x0, 0x0, 0xb0, 0x0, 0x0, 0x0, 0xb0, - 0x0, 0x0, 0xb0, 0x0, 0x0, 0x0, 0xc5, 0x55, - 0x55, 0xb0, 0x0, 0x0, 0x0, 0x10, 0x0, 0x0, - 0x10, 0x0, - - /* U+5BA4 "室" */ - 0x0, 0x0, 0x0, 0x20, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x96, 0x0, 0x0, 0x0, 0x0, 0x65, - 0x55, 0x79, 0x55, 0x56, 0x10, 0x7, 0x50, 0x0, - 0x0, 0x0, 0x9, 0x10, 0x6, 0x45, 0x55, 0x55, - 0x58, 0xa0, 0x0, 0x0, 0x0, 0xa, 0x50, 0x11, - 0x0, 0x0, 0x0, 0x1, 0x82, 0x0, 0xa, 0x40, - 0x0, 0x0, 0x2f, 0xa8, 0x76, 0x56, 0xe0, 0x0, - 0x0, 0x3, 0x0, 0x84, 0x0, 0x40, 0x0, 0x0, - 0x25, 0x55, 0xb7, 0x56, 0xb0, 0x0, 0x0, 0x1, - 0x0, 0x92, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x92, 0x0, 0x0, 0x0, 0x15, 0x55, 0x55, 0xb7, - 0x55, 0x5b, 0xa0, 0x1, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, - - /* U+5BB3 "害" */ - 0x0, 0x0, 0x0, 0x30, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x85, 0x0, 0x0, 0x0, 0x2, 0x85, - 0x55, 0x67, 0x55, 0x59, 0x80, 0xb, 0x30, 0x0, - 0xb2, 0x0, 0x26, 0x0, 0x1, 0x25, 0x55, 0xd5, - 0x55, 0x92, 0x0, 0x0, 0x0, 0x0, 0xc0, 0x0, - 0x50, 0x0, 0x0, 0x25, 0x55, 0xd5, 0x55, 0x51, - 0x0, 0x5, 0x55, 0x55, 0xd5, 0x55, 0x59, 0x90, - 0x0, 0x0, 0x0, 0xc0, 0x0, 0x0, 0x0, 0x0, - 0xa, 0x55, 0x75, 0x55, 0xd0, 0x0, 0x0, 0xb, - 0x0, 0x0, 0x0, 0xb0, 0x0, 0x0, 0xb, 0x0, - 0x0, 0x0, 0xb0, 0x0, 0x0, 0xb, 0x55, 0x55, - 0x55, 0xb0, 0x0, 0x0, 0x6, 0x0, 0x0, 0x0, - 0x50, 0x0, - - /* U+5BB5 "宵" */ - 0x0, 0x0, 0x11, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0xb4, 0x0, 0x0, 0x0, 0x7, 0x55, 0x57, - 0x75, 0x55, 0x68, 0x3, 0x92, 0x0, 0x64, 0x1, - 0x16, 0x40, 0x42, 0x2c, 0x2a, 0x20, 0xa5, 0x10, - 0x0, 0x0, 0x55, 0xa1, 0x53, 0x0, 0x0, 0x0, - 0xa5, 0x59, 0x55, 0x5c, 0x0, 0x0, 0xb, 0x0, - 0x0, 0x0, 0xb0, 0x0, 0x0, 0xc5, 0x55, 0x55, - 0x5b, 0x0, 0x0, 0xb, 0x0, 0x0, 0x0, 0xb0, - 0x0, 0x0, 0xc5, 0x55, 0x55, 0x5b, 0x0, 0x0, - 0xb, 0x0, 0x0, 0x0, 0xb0, 0x0, 0x0, 0xb0, - 0x0, 0x6, 0xc9, 0x0, 0x0, 0x2, 0x0, 0x0, - 0x3, 0x0, 0x0, - - /* U+5BB6 "家" */ - 0x0, 0x0, 0x0, 0x40, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x78, 0x0, 0x0, 0x0, 0x0, 0x95, - 0x55, 0x58, 0x55, 0x57, 0xa0, 0x6, 0x80, 0x0, - 0x0, 0x0, 0x7, 0x20, 0x1, 0x5, 0x55, 0x95, - 0x57, 0x70, 0x0, 0x0, 0x0, 0x1b, 0x60, 0x0, - 0x50, 0x0, 0x0, 0x4, 0x81, 0x92, 0x8, 0x71, - 0x0, 0x3, 0x53, 0x6, 0x7b, 0x54, 0x0, 0x0, - 0x0, 0x1, 0x84, 0x1e, 0x37, 0x0, 0x0, 0x1, - 0x56, 0x2, 0xb8, 0x75, 0x60, 0x0, 0x2, 0x0, - 0x49, 0x14, 0x80, 0x99, 0x20, 0x0, 0x37, 0x40, - 0x6, 0x60, 0x7, 0x80, 0x14, 0x20, 0x4, 0xbd, - 0x10, 0x0, 0x0, 0x0, 0x0, 0x0, 0x10, 0x0, - 0x0, 0x0, - - /* U+5BB9 "容" */ - 0x0, 0x0, 0x1, 0x30, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x87, 0x0, 0x0, 0x0, 0x0, 0x95, - 0x55, 0x58, 0x55, 0x57, 0x70, 0x5, 0x80, 0x40, - 0x0, 0x20, 0x8, 0x30, 0x5, 0x12, 0xc3, 0x42, - 0x3a, 0x51, 0x0, 0x0, 0x29, 0x10, 0xd7, 0x0, - 0xb7, 0x0, 0x2, 0x40, 0xa, 0x54, 0x40, 0x4, - 0x0, 0x0, 0x0, 0x97, 0x0, 0x58, 0x0, 0x0, - 0x0, 0x9, 0x90, 0x0, 0x7, 0xda, 0x61, 0x4, - 0x71, 0xd5, 0x55, 0x5d, 0x36, 0x60, 0x0, 0x0, - 0xc0, 0x0, 0xc, 0x0, 0x0, 0x0, 0x0, 0xc0, - 0x0, 0xc, 0x0, 0x0, 0x0, 0x0, 0xd5, 0x55, - 0x5d, 0x0, 0x0, 0x0, 0x0, 0x20, 0x0, 0x1, - 0x0, 0x0, - - /* U+5BBF "宿" */ - 0x0, 0x0, 0x0, 0x30, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x69, 0x0, 0x0, 0x0, 0x0, 0x85, - 0x55, 0x59, 0x55, 0x56, 0x80, 0x3, 0x91, 0x90, - 0x0, 0x0, 0x7, 0x40, 0x5, 0x26, 0x94, 0x55, - 0x55, 0x56, 0xb1, 0x0, 0xb, 0x0, 0x0, 0xa3, - 0x0, 0x0, 0x0, 0x6d, 0x0, 0x20, 0x80, 0x3, - 0x0, 0x1, 0x8c, 0x0, 0xc5, 0x55, 0x5d, 0x0, - 0x6, 0xc, 0x0, 0xc0, 0x0, 0xc, 0x0, 0x0, - 0xc, 0x0, 0xc5, 0x55, 0x5c, 0x0, 0x0, 0xc, - 0x0, 0xc0, 0x0, 0xc, 0x0, 0x0, 0xc, 0x0, - 0xc0, 0x0, 0xc, 0x0, 0x0, 0xc, 0x0, 0xc5, - 0x55, 0x5c, 0x0, 0x0, 0x3, 0x0, 0x20, 0x0, - 0x2, 0x0, - - /* U+5BC4 "寄" */ - 0x0, 0x0, 0x4, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x92, 0x0, 0x0, 0x0, 0x9, 0x55, 0x56, - 0x55, 0x55, 0x89, 0x6, 0x80, 0x0, 0x77, 0x0, - 0x15, 0x0, 0x1, 0x55, 0x6d, 0x65, 0x5a, 0x20, - 0x0, 0x0, 0x1a, 0x33, 0x85, 0x0, 0x0, 0x1, - 0x55, 0x0, 0x0, 0x90, 0x17, 0x5, 0x55, 0x55, - 0x55, 0x55, 0xc5, 0x61, 0x0, 0x95, 0x55, 0xa0, - 0xc, 0x0, 0x0, 0xc, 0x0, 0xb, 0x0, 0xc0, - 0x0, 0x0, 0xd5, 0x55, 0xb0, 0xc, 0x0, 0x0, - 0xb, 0x0, 0x7, 0x0, 0xc0, 0x0, 0x0, 0x0, - 0x0, 0x5, 0xe9, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x1, 0x0, 0x0, - - /* U+5BC6 "密" */ - 0x0, 0x0, 0x0, 0x20, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x1c, 0x0, 0x0, 0x0, 0x0, 0x95, - 0x55, 0x59, 0x55, 0x55, 0xd1, 0x6, 0x80, 0x0, - 0x71, 0x7, 0x15, 0x20, 0x2, 0x1, 0x49, 0x57, - 0x8a, 0x10, 0x0, 0x0, 0x27, 0x38, 0xa, 0x61, - 0x39, 0x0, 0x0, 0xb3, 0x3c, 0x92, 0x5, 0x9, - 0x60, 0x0, 0x26, 0x9d, 0x99, 0x9c, 0x31, 0x10, - 0x3, 0x20, 0x0, 0x16, 0x0, 0x0, 0x0, 0x0, - 0x19, 0x0, 0x1b, 0x0, 0x55, 0x0, 0x0, 0xa, - 0x0, 0xa, 0x0, 0x65, 0x0, 0x0, 0x1a, 0x0, - 0xa, 0x0, 0x65, 0x0, 0x0, 0x28, 0x55, 0x56, - 0x55, 0x95, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, - - /* U+5BCC "富" */ - 0x0, 0x0, 0x3, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x2, 0xc0, 0x0, 0x0, 0x8, 0x55, 0x55, 0x85, - 0x55, 0x97, 0x49, 0x0, 0x0, 0x0, 0x41, 0x81, - 0x10, 0x35, 0x55, 0x55, 0x53, 0x0, 0x0, 0xa, - 0x55, 0x55, 0xb2, 0x0, 0x0, 0xc, 0x0, 0x0, - 0xb0, 0x0, 0x0, 0xb, 0x55, 0x55, 0x90, 0x0, - 0x0, 0x85, 0x55, 0x55, 0x59, 0x20, 0x0, 0xc0, - 0x1, 0xa0, 0xb, 0x0, 0x0, 0xd5, 0x55, 0xc5, - 0x5d, 0x0, 0x0, 0xc0, 0x1, 0xa0, 0xb, 0x0, - 0x0, 0xd5, 0x55, 0x75, 0x5d, 0x10, 0x0, 0x20, - 0x0, 0x0, 0x0, 0x0, - - /* U+5BD2 "寒" */ - 0x0, 0x0, 0x0, 0x30, 0x0, 0x0, 0x0, 0x0, - 0x10, 0x0, 0x39, 0x0, 0x0, 0x10, 0x1, 0x95, - 0x55, 0x57, 0x55, 0x56, 0xd0, 0xa, 0x30, 0x1a, - 0x0, 0xb1, 0x14, 0x10, 0x0, 0x45, 0x6c, 0x55, - 0xc5, 0x93, 0x0, 0x0, 0x0, 0x1a, 0x0, 0xb0, - 0x51, 0x0, 0x0, 0x25, 0x6c, 0x55, 0xc5, 0x52, - 0x0, 0x4, 0x55, 0x6c, 0x55, 0xc5, 0x58, 0xc0, - 0x0, 0x0, 0x68, 0x0, 0x42, 0x0, 0x0, 0x0, - 0x3, 0xa0, 0x78, 0x8, 0x40, 0x0, 0x0, 0x38, - 0x0, 0x7, 0x0, 0x9d, 0x81, 0x4, 0x30, 0x15, - 0x87, 0x20, 0x2, 0x30, 0x0, 0x0, 0x0, 0x5, - 0xe2, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, - - /* U+5BDD "寝" */ - 0x0, 0x0, 0x2, 0x30, 0x0, 0x0, 0x0, 0x0, - 0x0, 0xa, 0x50, 0x0, 0x0, 0x2, 0x85, 0x55, - 0x66, 0x55, 0x5a, 0x30, 0x84, 0x30, 0x0, 0x0, - 0x2, 0x50, 0x3, 0xb, 0x12, 0x65, 0x55, 0xc1, - 0x0, 0x71, 0xb0, 0x5, 0x55, 0x5c, 0x0, 0x4, - 0x8b, 0x2, 0x65, 0x55, 0xc0, 0x0, 0x1, 0xb0, - 0x53, 0x33, 0x34, 0x60, 0x2, 0x8c, 0x38, 0x11, - 0x12, 0x59, 0x13, 0xb0, 0xb3, 0x27, 0x65, 0x99, - 0x0, 0x0, 0xb, 0x0, 0x7, 0x2a, 0x0, 0x0, - 0x0, 0xb0, 0x0, 0x4f, 0x30, 0x0, 0x0, 0xb, - 0x1, 0x65, 0x17, 0xba, 0x60, 0x0, 0x32, 0x20, - 0x0, 0x0, 0x20, - - /* U+5BDF "察" */ - 0x0, 0x0, 0x0, 0x31, 0x0, 0x0, 0x0, 0x0, - 0x10, 0x0, 0xc, 0x0, 0x0, 0x20, 0x0, 0x95, - 0x65, 0x55, 0x55, 0x56, 0xd2, 0x6, 0x71, 0xd1, - 0x11, 0x10, 0x5, 0x10, 0x0, 0xa, 0x75, 0xd5, - 0x85, 0x5d, 0x50, 0x0, 0x57, 0x93, 0xa0, 0x52, - 0x54, 0x0, 0x2, 0x82, 0x5a, 0x10, 0x1a, 0x50, - 0x0, 0x1, 0x8, 0x96, 0x55, 0x74, 0xb7, 0x10, - 0x0, 0x18, 0x10, 0x0, 0x0, 0x89, 0xd2, 0x4, - 0x45, 0x55, 0x6c, 0x55, 0x52, 0x0, 0x0, 0x0, - 0xb4, 0x1a, 0x16, 0x10, 0x0, 0x0, 0x19, 0x30, - 0x1a, 0x0, 0xb6, 0x0, 0x3, 0x60, 0x6, 0xc9, - 0x0, 0x1b, 0x0, 0x0, 0x0, 0x0, 0x30, 0x0, - 0x0, 0x0, - - /* U+5BE6 "實" */ - 0x0, 0x0, 0x0, 0x30, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x58, 0x0, 0x0, 0x0, 0x0, 0x84, - 0x44, 0x47, 0x44, 0x48, 0x60, 0x1, 0xb3, 0x55, - 0x55, 0x55, 0x87, 0x0, 0x2, 0x28, 0x52, 0x67, - 0x22, 0xb5, 0x80, 0x5, 0x3b, 0x43, 0x95, 0x36, - 0x93, 0x30, 0x0, 0x9, 0x55, 0x65, 0x57, 0x50, - 0x0, 0x0, 0xa, 0x55, 0x55, 0x55, 0xd0, 0x0, - 0x0, 0xb, 0x55, 0x55, 0x55, 0xb0, 0x0, 0x0, - 0xb, 0x55, 0x55, 0x55, 0xb0, 0x0, 0x0, 0xb, - 0x55, 0x55, 0x55, 0xb0, 0x0, 0x0, 0x3, 0x29, - 0x0, 0x56, 0x40, 0x0, 0x0, 0x37, 0x72, 0x0, - 0x3, 0xc7, 0x0, 0x2, 0x10, 0x0, 0x0, 0x0, - 0x3, 0x0, - - /* U+5BEB "寫" */ - 0x0, 0x0, 0x3, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x76, 0x0, 0x0, 0x0, 0x8, 0x55, 0x56, - 0x95, 0x55, 0x67, 0x7, 0x50, 0x5, 0x40, 0x0, - 0x26, 0x40, 0x61, 0xa5, 0x41, 0x46, 0x5d, 0x20, - 0x0, 0xc, 0x58, 0x31, 0x55, 0xb0, 0x0, 0x0, - 0xb0, 0x0, 0x1, 0xb, 0x0, 0x0, 0xc, 0x8a, - 0x55, 0x55, 0xa0, 0x0, 0x0, 0x1d, 0x65, 0x55, - 0x55, 0x91, 0x0, 0x38, 0x10, 0x2, 0x14, 0xb, - 0x0, 0x23, 0x60, 0x80, 0x91, 0xb1, 0xb0, 0x0, - 0x2c, 0x8, 0x24, 0x12, 0x39, 0x0, 0x1, 0x20, - 0x0, 0x4, 0xad, 0x30, 0x0, 0x0, 0x0, 0x0, - 0x2, 0x20, 0x0, - - /* U+5BFA "寺" */ - 0x0, 0x0, 0x0, 0x40, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, 0xd1, 0x0, 0x0, 0x0, 0x1, 0x55, - 0x55, 0xe5, 0x55, 0x99, 0x0, 0x0, 0x10, 0x0, - 0xd0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xd0, - 0x0, 0x1, 0x40, 0x36, 0x55, 0x55, 0x85, 0x66, - 0x57, 0x91, 0x0, 0x0, 0x0, 0x0, 0x2d, 0x0, - 0x0, 0x0, 0x0, 0x0, 0x0, 0x2b, 0x6, 0x30, - 0x6, 0x57, 0x55, 0x55, 0x6c, 0x55, 0x40, 0x0, - 0x1, 0xb0, 0x0, 0x2b, 0x0, 0x0, 0x0, 0x0, - 0xa5, 0x0, 0x2b, 0x0, 0x0, 0x0, 0x0, 0x20, - 0x0, 0x2a, 0x0, 0x0, 0x0, 0x0, 0x0, 0x28, - 0xe8, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x40, - 0x0, 0x0, - - /* U+5BFE "対" */ - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x63, 0x0, 0x0, 0x0, 0xc1, 0x0, 0x0, 0x1e, - 0x10, 0x0, 0x0, 0xc0, 0x0, 0x0, 0x6, 0x4, - 0x0, 0x0, 0xc0, 0x0, 0x6, 0x55, 0xc7, 0x35, - 0x55, 0xd5, 0xb0, 0x0, 0x0, 0xd0, 0x1, 0x0, - 0xc0, 0x0, 0x3, 0x21, 0xb0, 0x33, 0x0, 0xc0, - 0x0, 0x0, 0x5a, 0x60, 0xc, 0x20, 0xc0, 0x0, - 0x0, 0xc, 0x90, 0x7, 0x60, 0xc0, 0x0, 0x0, - 0x47, 0xa8, 0x0, 0x0, 0xc0, 0x0, 0x1, 0x90, - 0x1c, 0x0, 0x0, 0xc0, 0x0, 0x18, 0x0, 0x0, - 0x1, 0x32, 0xd0, 0x0, 0x20, 0x0, 0x0, 0x0, - 0x3d, 0xb0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x1, - 0x0, 0x0, - - /* U+5C04 "射" */ - 0x0, 0x1, 0x20, 0x0, 0x0, 0x30, 0x0, 0x0, - 0x6, 0x40, 0x0, 0x0, 0xc2, 0x0, 0x0, 0xa7, - 0x5b, 0x20, 0x0, 0xc0, 0x0, 0x0, 0xc0, 0xb, - 0x10, 0x0, 0xc0, 0x10, 0x0, 0xd5, 0x5c, 0x46, - 0x55, 0xd6, 0xa0, 0x0, 0xc0, 0xb, 0x10, 0x0, - 0xc0, 0x0, 0x0, 0xd5, 0x5c, 0x15, 0x10, 0xc0, - 0x0, 0x0, 0xc0, 0xb, 0x12, 0xc0, 0xc0, 0x0, - 0x16, 0x86, 0xac, 0x10, 0xc0, 0xc0, 0x0, 0x0, - 0x9, 0x4b, 0x10, 0x0, 0xc0, 0x0, 0x0, 0x48, - 0xb, 0x10, 0x0, 0xc0, 0x0, 0x2, 0x80, 0xb, - 0x10, 0x0, 0xc0, 0x0, 0x15, 0x2, 0xad, 0x0, - 0x6d, 0xc0, 0x0, 0x0, 0x0, 0x1, 0x0, 0x1, - 0x0, 0x0, - - /* U+5C07 "將" */ - 0x0, 0x0, 0x20, 0x0, 0x20, 0x0, 0x0, 0x2, - 0x0, 0xd0, 0x1, 0xe1, 0x0, 0x0, 0xb, 0x10, - 0xb0, 0x9, 0x85, 0x5b, 0x60, 0xb, 0x0, 0xb0, - 0x58, 0x70, 0x3c, 0x10, 0xc, 0x55, 0xb3, 0x75, - 0x74, 0xb1, 0x0, 0x3, 0x0, 0xb0, 0x8, 0x2a, - 0x20, 0x0, 0x0, 0x0, 0xb0, 0x6, 0x80, 0xb1, - 0x0, 0x17, 0x95, 0xb3, 0x51, 0x0, 0xb1, 0x60, - 0x0, 0xc0, 0xb5, 0x65, 0x55, 0xc5, 0x50, 0x0, - 0xb0, 0xb0, 0x64, 0x0, 0xb0, 0x0, 0x3, 0x80, - 0xb0, 0x1d, 0x0, 0xb0, 0x0, 0x8, 0x20, 0xb0, - 0x3, 0x0, 0xb0, 0x0, 0x35, 0x0, 0xc0, 0x1, - 0x7d, 0xc0, 0x0, 0x0, 0x0, 0x20, 0x0, 0x2, - 0x10, 0x0, - - /* U+5C08 "專" */ - 0x0, 0x0, 0x0, 0x20, 0x0, 0x0, 0x0, 0x0, - 0x0, 0xb, 0x30, 0x3, 0x50, 0x0, 0x65, 0x55, - 0xc5, 0x55, 0x55, 0x0, 0x0, 0xa5, 0x5c, 0x55, - 0x79, 0x0, 0x0, 0xc, 0x0, 0xb1, 0x4, 0x80, - 0x0, 0x0, 0xc5, 0x5c, 0x55, 0x78, 0x0, 0x0, - 0xc, 0x55, 0xc5, 0x57, 0x80, 0x0, 0x0, 0x30, - 0xb, 0x22, 0x97, 0x0, 0x0, 0xac, 0xa8, 0x76, - 0x84, 0x96, 0x0, 0x45, 0x55, 0x55, 0x5c, 0x75, - 0xd7, 0x1, 0x3, 0x40, 0x0, 0xa2, 0x0, 0x0, - 0x0, 0xb, 0x30, 0xa, 0x20, 0x0, 0x0, 0x0, - 0x30, 0x3a, 0xe0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x1, 0x0, 0x0, - - /* U+5C0D "對" */ - 0x0, 0x3, 0x3, 0x0, 0x0, 0x2, 0x0, 0x1, - 0xc, 0xc, 0x1, 0x0, 0xd, 0x0, 0x8, 0x4a, - 0xa, 0x67, 0x0, 0xb, 0x0, 0x2, 0x4a, 0xc, - 0x42, 0x0, 0xb, 0x0, 0x16, 0x58, 0x59, 0x5a, - 0x10, 0xb, 0x51, 0x0, 0x72, 0xb, 0x10, 0x65, - 0x5c, 0x52, 0x0, 0x38, 0x25, 0x22, 0x30, 0xb, - 0x0, 0x4, 0x66, 0xa5, 0x70, 0xb3, 0xb, 0x0, - 0x0, 0x2, 0x90, 0x0, 0x59, 0xb, 0x0, 0x1, - 0x66, 0xb6, 0x90, 0x1, 0xb, 0x0, 0x0, 0x2, - 0x90, 0x0, 0x0, 0xb, 0x0, 0x0, 0x2, 0xa3, - 0x42, 0x1, 0x1b, 0x0, 0xb, 0xb8, 0x52, 0x0, - 0x5, 0xe8, 0x0, 0x2, 0x0, 0x0, 0x0, 0x0, - 0x10, 0x0, - - /* U+5C0E "導" */ - 0x0, 0x10, 0x0, 0x30, 0x2, 0x0, 0x0, 0x0, - 0x94, 0x0, 0x2a, 0x8, 0x31, 0x0, 0x0, 0x38, - 0x46, 0x58, 0x77, 0x59, 0x60, 0x1, 0x26, 0x9, - 0x57, 0x55, 0x86, 0x0, 0x1, 0x3c, 0xb, 0x55, - 0x55, 0x95, 0x0, 0x0, 0xb, 0xb, 0x44, 0x44, - 0x95, 0x0, 0x0, 0xb, 0xb, 0x55, 0x55, 0x95, - 0x0, 0x1, 0x76, 0x89, 0x21, 0x11, 0x34, 0x41, - 0x2, 0x40, 0x4, 0x79, 0xac, 0xab, 0x70, 0x4, - 0x55, 0x55, 0x55, 0x5e, 0x5a, 0xb0, 0x1, 0x1, - 0x40, 0x0, 0xb, 0x0, 0x0, 0x0, 0x0, 0xa3, - 0x0, 0xb, 0x0, 0x0, 0x0, 0x0, 0x20, 0x5, - 0xb9, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x30, - 0x0, 0x0, - - /* U+5C0F "小" */ - 0x0, 0x0, 0x0, 0x10, 0x0, 0x0, 0x0, 0x0, - 0x1, 0xe1, 0x0, 0x0, 0x0, 0x0, 0x0, 0xc0, - 0x0, 0x0, 0x0, 0x0, 0x0, 0xc0, 0x0, 0x0, - 0x0, 0x8, 0x10, 0xc0, 0x30, 0x0, 0x0, 0x1e, - 0x20, 0xc0, 0x46, 0x0, 0x0, 0x95, 0x0, 0xc0, - 0x9, 0x70, 0x2, 0x90, 0x0, 0xc0, 0x0, 0xe5, - 0x8, 0x0, 0x0, 0xc0, 0x0, 0x6c, 0x51, 0x0, - 0x0, 0xc0, 0x0, 0x6, 0x0, 0x0, 0x0, 0xc0, - 0x0, 0x0, 0x0, 0x1, 0x45, 0xb0, 0x0, 0x0, - 0x0, 0x0, 0x4e, 0x60, 0x0, 0x0, 0x0, 0x0, - 0x1, 0x0, 0x0, 0x0, - - /* U+5C11 "少" */ - 0x0, 0x0, 0x0, 0x20, 0x0, 0x0, 0x0, 0x0, - 0x0, 0xa, 0x50, 0x0, 0x0, 0x0, 0x0, 0x0, - 0xa2, 0x0, 0x0, 0x0, 0x0, 0x34, 0xa, 0x22, - 0x10, 0x0, 0x0, 0xa, 0x90, 0xa2, 0x7, 0x91, - 0x0, 0x2, 0xc0, 0xa, 0x20, 0x7, 0xe2, 0x0, - 0xa2, 0x0, 0xa2, 0x0, 0xa, 0x80, 0x54, 0x0, - 0xa, 0x20, 0x29, 0x12, 0x24, 0x0, 0x0, 0xa3, - 0x1d, 0xa1, 0x0, 0x0, 0x0, 0x1, 0x2d, 0x70, - 0x0, 0x0, 0x0, 0x0, 0x6c, 0x30, 0x0, 0x0, - 0x0, 0x5, 0xb7, 0x0, 0x0, 0x0, 0x3, 0x68, - 0x40, 0x0, 0x0, 0x0, 0x1, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x0, - - /* U+5C1A "尚" */ - 0x0, 0x0, 0x4, 0x0, 0x0, 0x0, 0x11, 0x0, - 0xd, 0x0, 0x5, 0x0, 0x9, 0x60, 0xc, 0x0, - 0x4d, 0x10, 0x0, 0xe3, 0xc, 0x0, 0xa1, 0x0, - 0x20, 0x40, 0xc, 0x5, 0x20, 0x20, 0xc5, 0x55, - 0x57, 0x56, 0x56, 0xc0, 0xc0, 0x2, 0x0, 0x3, - 0x2, 0xa0, 0xc0, 0xc, 0x55, 0x5c, 0x2, 0xa0, - 0xc0, 0xb, 0x0, 0xb, 0x2, 0xa0, 0xc0, 0xb, - 0x0, 0xb, 0x2, 0xa0, 0xc0, 0xc, 0x55, 0x5b, - 0x2, 0xa0, 0xc0, 0x4, 0x0, 0x3, 0x24, 0xa0, - 0xc0, 0x0, 0x0, 0x1, 0x7f, 0x50, 0x10, 0x0, - 0x0, 0x0, 0x2, 0x0, - - /* U+5C24 "尤" */ - 0x0, 0x0, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x9, 0x60, 0x66, 0x0, 0x0, 0x0, 0x0, - 0x8, 0x30, 0xa, 0x90, 0x0, 0x0, 0x0, 0x8, - 0x30, 0x0, 0x44, 0x0, 0x6, 0x55, 0x5b, 0x78, - 0x55, 0x5b, 0x50, 0x0, 0x0, 0x9, 0x3a, 0x10, - 0x0, 0x0, 0x0, 0x0, 0xa, 0x2a, 0x10, 0x0, - 0x0, 0x0, 0x0, 0xc, 0xa, 0x10, 0x0, 0x0, - 0x0, 0x0, 0xc, 0xa, 0x10, 0x0, 0x0, 0x0, - 0x0, 0x48, 0xa, 0x10, 0x0, 0x10, 0x0, 0x0, - 0xb1, 0xa, 0x10, 0x0, 0x50, 0x0, 0x9, 0x40, - 0xa, 0x20, 0x1, 0x80, 0x1, 0x82, 0x0, 0x6, - 0xdb, 0xbc, 0xb0, 0x13, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, - - /* U+5C31 "就" */ - 0x0, 0x1, 0x0, 0x0, 0x10, 0x0, 0x0, 0x0, - 0x3, 0x90, 0x0, 0xb1, 0x30, 0x0, 0x0, 0x0, - 0x70, 0x21, 0xb0, 0x4a, 0x0, 0x5, 0x55, 0x55, - 0x52, 0xb0, 0x6, 0x0, 0x0, 0x75, 0x55, 0x74, - 0xc5, 0x56, 0x90, 0x0, 0xb0, 0x0, 0xb0, 0xb4, - 0x60, 0x0, 0x0, 0xb0, 0x0, 0xb0, 0xb4, 0x60, - 0x0, 0x0, 0xc5, 0xb5, 0xa0, 0xb4, 0x60, 0x0, - 0x0, 0x30, 0xa1, 0x0, 0xb4, 0x60, 0x0, 0x0, - 0xc1, 0xa2, 0x82, 0x84, 0x60, 0x0, 0x5, 0x40, - 0xa0, 0x98, 0x24, 0x60, 0x40, 0x6, 0x0, 0xa0, - 0x8, 0x4, 0x60, 0x80, 0x10, 0x3b, 0x90, 0x70, - 0x2, 0xca, 0xd0, 0x0, 0x1, 0x2, 0x10, 0x0, - 0x0, 0x0, - - /* U+5C3A "尺" */ - 0x0, 0x3, 0x0, 0x0, 0x0, 0x4, 0x0, 0x0, - 0xd, 0x55, 0x55, 0x55, 0x5d, 0x0, 0x0, 0xd, - 0x0, 0x0, 0x0, 0x1b, 0x0, 0x0, 0xd, 0x0, - 0x0, 0x0, 0x1b, 0x0, 0x0, 0xd, 0x55, 0x57, - 0x55, 0x5b, 0x0, 0x0, 0xd, 0x0, 0x6, 0x0, - 0x4, 0x0, 0x0, 0xc, 0x0, 0x7, 0x10, 0x0, - 0x0, 0x0, 0xb, 0x0, 0x1, 0x70, 0x0, 0x0, - 0x0, 0x38, 0x0, 0x0, 0x93, 0x0, 0x0, 0x0, - 0x82, 0x0, 0x0, 0x1d, 0x40, 0x0, 0x2, 0x80, - 0x0, 0x0, 0x2, 0xe9, 0x20, 0x7, 0x0, 0x0, - 0x0, 0x0, 0x1b, 0xe3, 0x20, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x0, - - /* U+5C40 "局" */ - 0x0, 0x8, 0x55, 0x55, 0x55, 0x5a, 0x0, 0x0, - 0xc, 0x0, 0x0, 0x0, 0xc, 0x0, 0x0, 0xc, - 0x0, 0x0, 0x0, 0xc, 0x0, 0x0, 0xd, 0x55, - 0x55, 0x55, 0x59, 0x0, 0x0, 0xc, 0x0, 0x0, - 0x0, 0x0, 0x30, 0x0, 0xd, 0x55, 0x55, 0x55, - 0x55, 0xd0, 0x0, 0x1a, 0x7, 0x55, 0x58, 0x0, - 0xc0, 0x0, 0x28, 0xb, 0x0, 0xb, 0x0, 0xc0, - 0x0, 0x64, 0xb, 0x0, 0xb, 0x0, 0xc0, 0x0, - 0x90, 0xc, 0x55, 0x5a, 0x1, 0xb0, 0x1, 0x60, - 0x2, 0x0, 0x2, 0x14, 0xa0, 0x5, 0x0, 0x0, - 0x0, 0x1, 0x8f, 0x30, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x0, - - /* U+5C45 "居" */ - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8, - 0x65, 0x55, 0x55, 0x56, 0xa0, 0x0, 0x83, 0x0, - 0x0, 0x0, 0x38, 0x0, 0x8, 0x75, 0x55, 0x55, - 0x57, 0x90, 0x0, 0x83, 0x0, 0x9, 0x10, 0x13, - 0x0, 0x8, 0x30, 0x0, 0xc0, 0x0, 0x11, 0x0, - 0x87, 0x65, 0x5d, 0x55, 0x58, 0x60, 0xa, 0x10, - 0x0, 0xc0, 0x0, 0x0, 0x0, 0xa0, 0x20, 0xc, - 0x0, 0x40, 0x0, 0xa, 0xc, 0x66, 0x66, 0x6d, - 0x10, 0x3, 0x50, 0xc0, 0x0, 0x0, 0xc0, 0x0, - 0x70, 0xc, 0x0, 0x0, 0xc, 0x0, 0x23, 0x0, - 0xc5, 0x55, 0x55, 0xc0, 0x0, 0x0, 0x2, 0x0, - 0x0, 0x0, 0x0, - - /* U+5C4A "届" */ - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8, - 0x65, 0x55, 0x55, 0x55, 0xc0, 0x0, 0x83, 0x0, - 0x0, 0x0, 0xc, 0x0, 0x8, 0x75, 0x55, 0x55, - 0x55, 0xc0, 0x0, 0x83, 0x0, 0x0, 0x30, 0x5, - 0x0, 0x8, 0x30, 0x0, 0xd, 0x0, 0x0, 0x0, - 0x82, 0x65, 0x55, 0xd5, 0x59, 0x30, 0xa, 0x1b, - 0x10, 0xc, 0x0, 0xa1, 0x0, 0xa0, 0xb1, 0x0, - 0xc0, 0xa, 0x10, 0xa, 0xa, 0x65, 0x5d, 0x55, - 0xc1, 0x3, 0x60, 0xa1, 0x0, 0xc0, 0xa, 0x10, - 0x70, 0xb, 0x65, 0x5d, 0x55, 0xc1, 0x14, 0x0, - 0x91, 0x0, 0x0, 0x7, 0x10, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x0, - - /* U+5C4B "屋" */ - 0x0, 0x0, 0x0, 0x0, 0x0, 0x1, 0x0, 0x0, - 0x97, 0x55, 0x55, 0x55, 0x5e, 0x0, 0x0, 0x83, - 0x0, 0x0, 0x0, 0xc, 0x0, 0x0, 0x87, 0x55, - 0x55, 0x55, 0x5c, 0x0, 0x0, 0x83, 0x0, 0x0, - 0x0, 0x5, 0x0, 0x0, 0x84, 0x65, 0x78, 0x55, - 0x68, 0x10, 0x0, 0x92, 0x0, 0xb5, 0x6, 0x10, - 0x0, 0x0, 0xa1, 0x38, 0x10, 0x2, 0xd5, 0x0, - 0x0, 0xc0, 0x8a, 0x8b, 0x74, 0x4b, 0x0, 0x0, - 0xb0, 0x0, 0xa, 0x20, 0x13, 0x0, 0x3, 0x60, - 0x56, 0x5c, 0x65, 0x66, 0x0, 0x8, 0x0, 0x0, - 0xa, 0x10, 0x0, 0x0, 0x15, 0x5, 0x55, 0x5c, - 0x65, 0x58, 0xc0, 0x10, 0x1, 0x0, 0x0, 0x0, - 0x0, 0x0, - - /* U+5C55 "展" */ - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x86, 0x55, 0x55, 0x55, 0x5d, 0x0, 0x0, 0x83, - 0x0, 0x0, 0x0, 0xc, 0x0, 0x0, 0x87, 0x55, - 0x55, 0x55, 0x5c, 0x0, 0x0, 0x83, 0x3, 0xa0, - 0x1a, 0x2, 0x0, 0x0, 0x97, 0x57, 0xb5, 0x6b, - 0x69, 0x0, 0x0, 0x92, 0x3, 0x80, 0x1a, 0x0, - 0x0, 0x0, 0xa1, 0x3, 0x80, 0x1a, 0x5, 0x50, - 0x0, 0xb5, 0x5c, 0x59, 0x55, 0x75, 0x40, 0x0, - 0xb0, 0xb, 0x5, 0x32, 0xb3, 0x0, 0x2, 0x70, - 0xb, 0x0, 0xa7, 0x0, 0x0, 0x7, 0x10, 0xb, - 0x55, 0x1b, 0x83, 0x10, 0x15, 0x0, 0x1e, 0x40, - 0x0, 0x6d, 0xa1, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, - - /* U+5C65 "履" */ - 0x0, 0x10, 0x0, 0x0, 0x0, 0x1, 0x0, 0x0, - 0xa6, 0x55, 0x55, 0x55, 0x5c, 0x10, 0x0, 0x96, - 0x55, 0x55, 0x55, 0x5c, 0x0, 0x0, 0x91, 0x27, - 0x9, 0x30, 0x5, 0x0, 0x0, 0x91, 0x92, 0xc, - 0x55, 0x58, 0x20, 0x0, 0x95, 0x46, 0x6b, 0x55, - 0x5b, 0x0, 0x0, 0xa2, 0x69, 0x5a, 0x55, 0x5a, - 0x0, 0x0, 0xa0, 0xc1, 0xa, 0x0, 0xa, 0x0, - 0x0, 0xa6, 0xc1, 0x7, 0xc6, 0x56, 0x0, 0x0, - 0x92, 0xa0, 0x5, 0xc5, 0x78, 0x0, 0x3, 0x50, - 0xa0, 0x35, 0x42, 0xb2, 0x0, 0x7, 0x0, 0xa0, - 0x20, 0x3d, 0x80, 0x0, 0x13, 0x0, 0x91, 0x47, - 0x50, 0x5b, 0xa0, 0x0, 0x0, 0x2, 0x0, 0x0, - 0x0, 0x0, - - /* U+5C6C "屬" */ - 0x0, 0x20, 0x0, 0x0, 0x0, 0x3, 0x0, 0x9, - 0x75, 0x55, 0x55, 0x55, 0xc0, 0x0, 0x97, 0x55, - 0x56, 0x55, 0x6b, 0x0, 0x9, 0x23, 0x91, 0x92, - 0x57, 0x10, 0x0, 0x96, 0x76, 0x39, 0x15, 0x87, - 0x0, 0x9, 0x47, 0x55, 0x75, 0x55, 0xa0, 0x0, - 0xa2, 0x70, 0x90, 0x90, 0xa, 0x0, 0xb, 0x19, - 0x84, 0x44, 0x44, 0x60, 0x0, 0xa0, 0x96, 0x57, - 0x55, 0x5a, 0x40, 0x9, 0x57, 0x55, 0xb5, 0x91, - 0x91, 0x5, 0x40, 0x95, 0x5a, 0x5c, 0xa, 0x0, - 0x70, 0x4, 0x23, 0xa5, 0x81, 0xa0, 0x14, 0x0, - 0x85, 0x31, 0x6, 0x9a, 0x1, 0x0, 0x0, 0x0, - 0x0, 0x2, 0x0, - - /* U+5C71 "山" */ - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0xb, 0x20, 0x0, 0x0, 0x0, 0x0, 0xc, 0x0, - 0x0, 0x0, 0x0, 0x0, 0xc, 0x0, 0x0, 0x0, - 0x8, 0x10, 0xc, 0x0, 0x0, 0xa1, 0xc, 0x0, - 0xc, 0x0, 0x0, 0xc0, 0xc, 0x0, 0xc, 0x0, - 0x0, 0xc0, 0xc, 0x0, 0xc, 0x0, 0x0, 0xc0, - 0xc, 0x0, 0xc, 0x0, 0x0, 0xc0, 0xc, 0x0, - 0xc, 0x0, 0x0, 0xc0, 0xc, 0x0, 0xc, 0x0, - 0x0, 0xc0, 0xe, 0x55, 0x5a, 0x55, 0x55, 0xc0, - 0x1, 0x0, 0x0, 0x0, 0x0, 0x80, - - /* U+5CF6 "島" */ - 0x0, 0x0, 0x4, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x90, 0x0, 0x0, 0x0, 0x0, 0x86, 0x56, - 0x55, 0x5c, 0x30, 0x0, 0x9, 0x75, 0x55, 0x55, - 0xc0, 0x0, 0x0, 0x93, 0x0, 0x0, 0xa, 0x0, - 0x0, 0x9, 0x75, 0x55, 0x55, 0xb0, 0x0, 0x0, - 0x97, 0x55, 0x55, 0x55, 0x59, 0x70, 0x9, 0x30, - 0x0, 0x0, 0x0, 0x30, 0x0, 0x76, 0x57, 0x55, - 0x55, 0x5d, 0x10, 0x51, 0x0, 0xd0, 0x5, 0x0, - 0xb0, 0xb, 0x0, 0xb, 0x0, 0xb1, 0xb, 0x0, - 0xb5, 0x55, 0x95, 0x5b, 0x2, 0x90, 0x0, 0x0, - 0x0, 0x0, 0x5b, 0xd3, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x11, 0x0, - - /* U+5D4C "嵌" */ - 0x0, 0x0, 0x0, 0x31, 0x0, 0x0, 0x0, 0x0, - 0x71, 0x0, 0x85, 0x0, 0x18, 0x0, 0x0, 0xb0, - 0x0, 0x74, 0x0, 0x1a, 0x0, 0x0, 0xb5, 0x55, - 0x76, 0x55, 0x5a, 0x0, 0x0, 0x71, 0x8, 0x10, - 0x59, 0x0, 0x0, 0x0, 0xb0, 0xb, 0x41, 0xa3, - 0x0, 0x50, 0x6, 0xc5, 0x5c, 0x54, 0xb5, 0x57, - 0xb0, 0x0, 0xb0, 0xb, 0x8, 0x1c, 0x25, 0x0, - 0x0, 0xb5, 0x5c, 0x12, 0xe, 0x20, 0x0, 0x0, - 0xb0, 0xb, 0x0, 0x58, 0x60, 0x0, 0x0, 0xb0, - 0xb, 0x0, 0xa2, 0x72, 0x0, 0x0, 0xb5, 0x5d, - 0x5, 0x70, 0xc, 0x30, 0x0, 0x80, 0x4, 0x64, - 0x0, 0x3, 0xe4, 0x0, 0x0, 0x2, 0x0, 0x0, - 0x0, 0x0, - - /* U+5DDD "川" */ - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0xa3, 0x0, 0x0, 0x0, 0xd1, 0x0, 0xa, 0x10, - 0xb, 0x20, 0xc, 0x0, 0x0, 0xa1, 0x0, 0xc0, - 0x0, 0xc0, 0x0, 0xa, 0x10, 0xc, 0x0, 0xc, - 0x0, 0x0, 0xb0, 0x0, 0xc0, 0x0, 0xc0, 0x0, - 0xb, 0x0, 0xc, 0x0, 0xc, 0x0, 0x0, 0xb0, - 0x0, 0xc0, 0x0, 0xc0, 0x0, 0xa, 0x0, 0xc, - 0x0, 0xc, 0x0, 0x3, 0x70, 0x0, 0xc0, 0x0, - 0xc0, 0x0, 0x71, 0x0, 0xa, 0x0, 0xc, 0x0, - 0x7, 0x0, 0x0, 0x0, 0x0, 0xc0, 0x5, 0x0, - 0x0, 0x0, 0x0, 0xc, 0x0, 0x10, 0x0, 0x0, - 0x0, 0x0, 0x10, - - /* U+5DDE "州" */ - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x27, 0x0, 0x20, 0x1, 0xc0, 0x0, 0x2, 0x90, - 0x9, 0x40, 0x1a, 0x0, 0x0, 0x29, 0x0, 0x92, - 0x1, 0xa0, 0x0, 0x3, 0x80, 0x9, 0x20, 0xa, - 0x0, 0x6, 0x47, 0x80, 0x92, 0x91, 0xa0, 0x2, - 0xa5, 0x66, 0x79, 0x29, 0x4a, 0x0, 0x74, 0x65, - 0x23, 0x92, 0x21, 0xa0, 0x0, 0x9, 0x20, 0x9, - 0x20, 0xa, 0x0, 0x0, 0xc0, 0x0, 0x92, 0x0, - 0xa0, 0x0, 0x38, 0x0, 0x9, 0x20, 0xa, 0x0, - 0x9, 0x0, 0x0, 0x71, 0x1, 0xa0, 0x5, 0x30, - 0x0, 0x0, 0x0, 0x1b, 0x0, 0x10, 0x0, 0x0, - 0x0, 0x0, 0x0, - - /* U+5DE5 "工" */ - 0x0, 0x0, 0x0, 0x0, 0x0, 0x1, 0x0, 0x3, - 0x65, 0x55, 0x75, 0x55, 0x8b, 0x0, 0x0, 0x0, - 0x0, 0xa2, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0xa2, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xa2, - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xa2, 0x0, - 0x0, 0x0, 0x0, 0x0, 0x0, 0xa2, 0x0, 0x0, - 0x0, 0x0, 0x0, 0x0, 0xa2, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x0, 0xa2, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, 0xa2, 0x0, 0x1, 0x0, 0x15, 0x55, - 0x55, 0xc7, 0x55, 0x5e, 0x80, 0x1, 0x0, 0x0, - 0x0, 0x0, 0x0, 0x0, - - /* U+5DE6 "左" */ - 0x0, 0x0, 0x2, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0xd3, 0x0, 0x0, 0x0, 0x0, 0x0, 0xe, - 0x0, 0x0, 0x16, 0x0, 0x46, 0x56, 0xc5, 0x55, - 0x56, 0x81, 0x0, 0x0, 0x66, 0x0, 0x0, 0x0, - 0x0, 0x0, 0xa, 0x10, 0x0, 0x0, 0x0, 0x0, - 0x1, 0xb0, 0x0, 0x0, 0x40, 0x0, 0x0, 0x76, - 0x55, 0xb5, 0x58, 0x10, 0x0, 0x1a, 0x0, 0xc, - 0x0, 0x0, 0x0, 0x8, 0x10, 0x0, 0xc0, 0x0, - 0x0, 0x4, 0x40, 0x0, 0xc, 0x0, 0x0, 0x2, - 0x40, 0x0, 0x0, 0xc0, 0x0, 0x70, 0x0, 0x17, - 0x55, 0x56, 0x55, 0x56, 0x30, - - /* U+5DEE "差" */ - 0x0, 0x1, 0x10, 0x0, 0x3, 0x0, 0x0, 0x0, - 0x0, 0xa5, 0x0, 0xc, 0x40, 0x0, 0x0, 0x0, - 0x17, 0x0, 0x44, 0x3, 0x50, 0x0, 0x55, 0x55, - 0xb6, 0x55, 0x56, 0x60, 0x0, 0x0, 0x0, 0xc0, - 0x0, 0x24, 0x0, 0x0, 0x25, 0x56, 0xc5, 0x55, - 0x55, 0x0, 0x0, 0x0, 0x6, 0x50, 0x0, 0x3, - 0x80, 0x4, 0x55, 0x5d, 0x55, 0x55, 0x55, 0x51, - 0x0, 0x0, 0x56, 0x0, 0x0, 0x11, 0x0, 0x0, - 0x1, 0x95, 0x56, 0xa5, 0x66, 0x0, 0x0, 0x18, - 0x0, 0x2, 0xa0, 0x0, 0x0, 0x1, 0x70, 0x0, - 0x2, 0xa0, 0x0, 0x0, 0x3, 0x4, 0x55, 0x56, - 0xc5, 0x56, 0xd1, 0x0, 0x1, 0x0, 0x0, 0x0, - 0x0, 0x0, - - /* U+5DF1 "己" */ - 0x0, 0x0, 0x0, 0x0, 0x5, 0x0, 0x0, 0x65, - 0x55, 0x55, 0x55, 0xd1, 0x0, 0x0, 0x0, 0x0, - 0x0, 0xc, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0xc0, 0x0, 0x3, 0x0, 0x0, 0x0, 0xc, 0x0, - 0x0, 0xb5, 0x55, 0x55, 0x55, 0xd0, 0x0, 0xb, - 0x10, 0x0, 0x0, 0x0, 0x0, 0x0, 0xb1, 0x0, - 0x0, 0x0, 0x0, 0x0, 0xb, 0x10, 0x0, 0x0, - 0x0, 0x5, 0x0, 0xb1, 0x0, 0x0, 0x0, 0x0, - 0x70, 0xa, 0x52, 0x22, 0x22, 0x22, 0x6e, 0x0, - 0x29, 0x99, 0x99, 0x99, 0x99, 0x50, - - /* U+5DF2 "已" */ - 0x4, 0x55, 0x55, 0x55, 0x5b, 0x0, 0x1, 0x0, - 0x0, 0x0, 0xc, 0x0, 0x0, 0x0, 0x0, 0x0, - 0xc, 0x0, 0x5, 0x10, 0x0, 0x0, 0xc, 0x0, - 0xb, 0x65, 0x55, 0x55, 0x5c, 0x0, 0xb, 0x10, - 0x0, 0x0, 0x9, 0x0, 0xb, 0x10, 0x0, 0x0, - 0x0, 0x0, 0xb, 0x10, 0x0, 0x0, 0x0, 0x10, - 0xb, 0x10, 0x0, 0x0, 0x0, 0x50, 0xb, 0x10, - 0x0, 0x0, 0x0, 0x62, 0xa, 0x42, 0x22, 0x22, - 0x22, 0xb8, 0x2, 0x88, 0x88, 0x88, 0x88, 0x72, - - /* U+5E02 "市" */ - 0x0, 0x0, 0x2, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x68, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x90, 0x0, 0x19, 0x4, 0x65, 0x55, 0x5d, 0x55, - 0x55, 0x52, 0x0, 0x0, 0x0, 0xc0, 0x0, 0x10, - 0x0, 0xc, 0x55, 0x5d, 0x55, 0x6d, 0x0, 0x0, - 0xc0, 0x0, 0xc0, 0x1, 0xb0, 0x0, 0xc, 0x0, - 0xc, 0x0, 0x1b, 0x0, 0x0, 0xc0, 0x0, 0xc0, - 0x1, 0xb0, 0x0, 0xc, 0x0, 0xc, 0x0, 0x1b, - 0x0, 0x0, 0xc0, 0x0, 0xc0, 0x56, 0xa0, 0x0, - 0xa, 0x0, 0xc, 0x1, 0xb4, 0x0, 0x0, 0x0, - 0x0, 0xc0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x2, - 0x0, 0x0, 0x0, - - /* U+5E03 "布" */ - 0x0, 0x0, 0x0, 0x20, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x1, 0xe1, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x7, 0x60, 0x0, 0x1, 0x40, 0x5, 0x55, 0x5d, - 0x55, 0x55, 0x56, 0x81, 0x0, 0x0, 0x57, 0x9, - 0x30, 0x0, 0x0, 0x0, 0x0, 0xc0, 0xb, 0x0, - 0x4, 0x0, 0x0, 0x8, 0xe5, 0x5c, 0x55, 0x5d, - 0x0, 0x0, 0x54, 0xc0, 0xb, 0x0, 0xc, 0x0, - 0x4, 0x40, 0xc0, 0xb, 0x0, 0xc, 0x0, 0x12, - 0x0, 0xc0, 0xb, 0x0, 0xc, 0x0, 0x0, 0x0, - 0xc0, 0xb, 0x2, 0x2c, 0x0, 0x0, 0x0, 0xb0, - 0xb, 0x1, 0xc6, 0x0, 0x0, 0x0, 0x0, 0xc, - 0x10, 0x0, 0x0, 0x0, 0x0, 0x0, 0x3, 0x0, - 0x0, 0x0, - - /* U+5E08 "师" */ - 0x0, 0x2, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0xa3, 0x55, 0x55, 0x55, 0xa5, 0x3, 0xa, 0x11, - 0x0, 0xb0, 0x0, 0x0, 0xa2, 0xa1, 0x0, 0xb, - 0x0, 0x0, 0xa, 0x1a, 0x1a, 0x55, 0xc5, 0x5c, - 0x20, 0xa1, 0xa1, 0xb0, 0xb, 0x0, 0xa0, 0xa, - 0x1a, 0xb, 0x0, 0xb0, 0xa, 0x0, 0xa1, 0xb0, - 0xb0, 0xb, 0x0, 0xa0, 0xa, 0x1b, 0xb, 0x0, - 0xb0, 0xa, 0x0, 0x32, 0x80, 0xb0, 0xb, 0x1, - 0xb0, 0x0, 0x82, 0x7, 0x0, 0xb0, 0x6b, 0x0, - 0x27, 0x0, 0x0, 0xb, 0x0, 0x0, 0x6, 0x0, - 0x0, 0x0, 0xb0, 0x0, 0x1, 0x0, 0x0, 0x0, - 0x3, 0x0, 0x0, - - /* U+5E0C "希" */ - 0x0, 0x0, 0x0, 0x0, 0x4, 0x0, 0x0, 0x0, - 0x14, 0x52, 0x3, 0xc8, 0x0, 0x0, 0x0, 0x0, - 0x7, 0xdd, 0x30, 0x0, 0x0, 0x0, 0x0, 0x68, - 0x14, 0xcb, 0x10, 0x0, 0x0, 0x44, 0xc, 0x40, - 0x6, 0x51, 0x0, 0x16, 0x55, 0x7c, 0x55, 0x55, - 0x5b, 0x80, 0x0, 0x0, 0xb1, 0x94, 0x0, 0x0, - 0x0, 0x0, 0xb, 0x85, 0xb7, 0x55, 0x91, 0x0, - 0x0, 0x8c, 0x20, 0x92, 0x0, 0xc0, 0x0, 0x25, - 0x9, 0x20, 0x92, 0x0, 0xc0, 0x0, 0x0, 0x9, - 0x20, 0x92, 0x11, 0xd0, 0x0, 0x0, 0xa, 0x20, - 0x92, 0x2b, 0x90, 0x0, 0x0, 0x1, 0x0, 0xa3, - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x10, 0x0, - 0x0, 0x0, - - /* U+5E2B "師" */ - 0x0, 0x30, 0x0, 0x0, 0x0, 0x0, 0x0, 0xc, - 0x10, 0x0, 0x0, 0x0, 0x20, 0x23, 0x30, 0x36, - 0x55, 0xa5, 0x58, 0x2c, 0x55, 0x5c, 0x0, 0xb, - 0x0, 0x0, 0xb0, 0x0, 0xb3, 0x54, 0xc4, 0x49, - 0xc, 0x55, 0x5b, 0x55, 0xb, 0x0, 0xb0, 0xb0, - 0x0, 0x45, 0x50, 0xb0, 0xb, 0xc, 0x55, 0x58, - 0x55, 0xb, 0x0, 0xb0, 0xb0, 0x0, 0xb5, 0x50, - 0xb0, 0xb, 0xb, 0x0, 0xb, 0x55, 0xb, 0x0, - 0xb0, 0xb0, 0x0, 0xb5, 0x40, 0xb3, 0xb9, 0xc, - 0x55, 0x5b, 0x0, 0xb, 0x1, 0x0, 0x70, 0x0, - 0x10, 0x0, 0xc0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x2, 0x0, 0x0, - - /* U+5E2D "席" */ - 0x0, 0x0, 0x0, 0x20, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x1c, 0x0, 0x0, 0x20, 0x0, 0xc5, - 0x55, 0x58, 0x55, 0x57, 0x80, 0x0, 0xc0, 0x6, - 0x50, 0xc, 0x0, 0x0, 0x0, 0xc3, 0x59, 0x85, - 0x5d, 0x5a, 0x50, 0x0, 0xb0, 0x5, 0x50, 0xb, - 0x0, 0x0, 0x0, 0xb0, 0x6, 0x86, 0x5c, 0x0, - 0x0, 0x1, 0xa0, 0x3, 0x1b, 0x4, 0x0, 0x0, - 0x2, 0x90, 0xa5, 0x5c, 0x55, 0x5c, 0x0, 0x5, - 0x60, 0xb0, 0xb, 0x0, 0xb, 0x0, 0x8, 0x10, - 0xb0, 0xb, 0x0, 0xb, 0x0, 0x7, 0x0, 0xb0, - 0xb, 0x3, 0xba, 0x0, 0x22, 0x0, 0x30, 0xb, - 0x0, 0x20, 0x0, 0x0, 0x0, 0x0, 0x2, 0x0, - 0x0, 0x0, - - /* U+5E2F "帯" */ - 0x0, 0x0, 0x0, 0x12, 0x0, 0x0, 0x0, 0x0, - 0x5, 0x20, 0x37, 0x0, 0x80, 0x0, 0x3, 0x5a, - 0x75, 0x79, 0x55, 0xd8, 0xc0, 0x0, 0x7, 0x30, - 0x36, 0x0, 0xb0, 0x0, 0x0, 0x9, 0x75, 0x68, - 0x55, 0xc0, 0x0, 0x0, 0x30, 0x0, 0x0, 0x0, - 0x20, 0x40, 0x4, 0x85, 0x55, 0x78, 0x55, 0x56, - 0xd1, 0xb, 0x22, 0x0, 0x37, 0x0, 0x24, 0x0, - 0x0, 0xc, 0x55, 0x79, 0x55, 0xa5, 0x0, 0x0, - 0xb, 0x0, 0x36, 0x0, 0x73, 0x0, 0x0, 0xb, - 0x0, 0x36, 0x0, 0x73, 0x0, 0x0, 0xb, 0x0, - 0x36, 0x16, 0xd2, 0x0, 0x0, 0x1, 0x0, 0x36, - 0x0, 0x40, 0x0, 0x0, 0x0, 0x0, 0x11, 0x0, - 0x0, 0x0, - - /* U+5E30 "帰" */ - 0x0, 0x0, 0x0, 0x0, 0x0, 0x1, 0x0, 0x0, - 0xb, 0x14, 0x65, 0x55, 0x5c, 0x20, 0x0, 0xb, - 0x0, 0x0, 0x0, 0xb, 0x0, 0x3, 0xb, 0x2, - 0x65, 0x55, 0x5c, 0x0, 0xa, 0xb, 0x3, 0x55, - 0x55, 0x5c, 0x0, 0xa, 0xb, 0x3, 0x0, 0x0, - 0x3, 0x20, 0xa, 0xb, 0x48, 0x55, 0xb5, 0x55, - 0xd2, 0xa, 0xb, 0x82, 0x0, 0xb0, 0x3, 0x20, - 0x2, 0x19, 0x9, 0x65, 0xc5, 0x5d, 0x10, 0x0, - 0x55, 0x9, 0x20, 0xb0, 0xb, 0x0, 0x0, 0x80, - 0x9, 0x20, 0xb0, 0xb, 0x0, 0x1, 0x70, 0x9, - 0x20, 0xb1, 0x7d, 0x0, 0x5, 0x0, 0x3, 0x0, - 0xb0, 0x24, 0x0, 0x1, 0x0, 0x0, 0x0, 0x40, - 0x0, 0x0, - - /* U+5E33 "帳" */ - 0x0, 0x4, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x1d, 0x0, 0xb, 0x55, 0x58, 0x50, 0x0, 0x1b, - 0x0, 0xb, 0x0, 0x4, 0x0, 0xb, 0x5d, 0x5c, - 0xc, 0x55, 0x56, 0x0, 0xb, 0x1b, 0xb, 0xb, - 0x0, 0x6, 0x0, 0xb, 0x1b, 0xb, 0xc, 0x55, - 0x55, 0x10, 0xb, 0x1b, 0xb, 0x5c, 0x55, 0x55, - 0xb1, 0xb, 0x1b, 0xb, 0x28, 0x13, 0x1, 0x10, - 0xb, 0x1b, 0xb, 0x28, 0x7, 0xa, 0x60, 0xa, - 0x1c, 0x96, 0x28, 0x6, 0x82, 0x0, 0x0, 0x1b, - 0x0, 0x28, 0x0, 0xb1, 0x0, 0x0, 0x1b, 0x0, - 0x2a, 0x72, 0x3d, 0x30, 0x0, 0x1c, 0x0, 0x3c, - 0x10, 0x4, 0xb2, 0x0, 0x1, 0x0, 0x0, 0x0, - 0x0, 0x0, - - /* U+5E36 "帶" */ - 0x0, 0x3, 0x2, 0x2, 0x2, 0x0, 0x0, 0x0, - 0xb, 0x1a, 0x1a, 0x2a, 0x30, 0x0, 0x3, 0x5d, - 0x5c, 0x5c, 0x5b, 0x6d, 0x70, 0x0, 0xb, 0xa, - 0xa, 0x9, 0x10, 0x30, 0x0, 0x64, 0xa, 0x5c, - 0x9, 0x65, 0xa0, 0x4, 0x20, 0x4, 0x3, 0x1, - 0x44, 0x20, 0x6, 0x55, 0x55, 0x86, 0x55, 0x58, - 0xc0, 0xd, 0x0, 0x0, 0x92, 0x0, 0x36, 0x10, - 0x14, 0x49, 0x55, 0xb6, 0x55, 0xd0, 0x0, 0x0, - 0x46, 0x0, 0x91, 0x0, 0xb0, 0x0, 0x0, 0x46, - 0x0, 0x91, 0x0, 0xb0, 0x0, 0x0, 0x45, 0x0, - 0x91, 0x28, 0xa0, 0x0, 0x0, 0x0, 0x0, 0x91, - 0x2, 0x20, 0x0, 0x0, 0x0, 0x0, 0x30, 0x0, - 0x0, 0x0, - - /* U+5E38 "常" */ - 0x0, 0x0, 0x0, 0x20, 0x0, 0x0, 0x0, 0x5, - 0x70, 0xc, 0x5, 0x90, 0x0, 0x0, 0xb, 0x10, - 0xb0, 0x80, 0x0, 0x0, 0x85, 0x55, 0x59, 0x65, - 0x55, 0xe1, 0x67, 0x2, 0x0, 0x0, 0x30, 0x53, - 0x5, 0x10, 0x96, 0x55, 0x5c, 0x10, 0x0, 0x0, - 0x9, 0x20, 0x0, 0xb0, 0x0, 0x0, 0x0, 0x86, - 0x5c, 0x58, 0x0, 0x0, 0x0, 0x95, 0x55, 0xc5, - 0x57, 0x60, 0x0, 0xc, 0x0, 0xb, 0x0, 0x56, - 0x0, 0x0, 0xc0, 0x0, 0xb0, 0x5, 0x60, 0x0, - 0xc, 0x0, 0xb, 0x7, 0xc4, 0x0, 0x0, 0x30, - 0x0, 0xb0, 0x5, 0x0, 0x0, 0x0, 0x0, 0x2, - 0x0, 0x0, 0x0, - - /* U+5E45 "幅" */ - 0x0, 0x30, 0x0, 0x0, 0x0, 0x0, 0x0, 0xc, - 0x0, 0x55, 0x55, 0x55, 0xa1, 0x0, 0xa0, 0x1, - 0x0, 0x0, 0x0, 0xa, 0x5c, 0x5b, 0x9, 0x55, - 0x5c, 0x0, 0xa0, 0xa0, 0xa0, 0xb0, 0x0, 0xb0, - 0xa, 0xa, 0xa, 0xc, 0x55, 0x5b, 0x0, 0xa0, - 0xa0, 0xa0, 0x70, 0x0, 0x40, 0xa, 0xa, 0xa, - 0x95, 0x59, 0x55, 0xb0, 0xa0, 0xa0, 0xa9, 0x0, - 0xa0, 0x1a, 0xb, 0xa, 0x78, 0x95, 0x5c, 0x55, - 0xa0, 0x30, 0xa1, 0x9, 0x0, 0xa0, 0x1a, 0x0, - 0xb, 0x0, 0x95, 0x5c, 0x55, 0xa0, 0x0, 0xb0, - 0xa, 0x0, 0x0, 0x1a, 0x0, 0x2, 0x0, 0x10, - 0x0, 0x0, 0x0, - - /* U+5E73 "平" */ - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x1, - 0x55, 0x55, 0x55, 0x55, 0x8b, 0x0, 0x0, 0x10, - 0x0, 0xa2, 0x0, 0x30, 0x0, 0x0, 0x9, 0x0, - 0xa2, 0x4, 0xd1, 0x0, 0x0, 0x6, 0xb0, 0xa2, - 0x9, 0x10, 0x0, 0x0, 0x0, 0xb0, 0xa2, 0x42, - 0x0, 0x0, 0x36, 0x55, 0x55, 0xc7, 0x65, 0x5a, - 0x90, 0x0, 0x0, 0x0, 0xa2, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x0, 0xa2, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, 0xa2, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0xa2, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0xa3, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xa2, - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, - - /* U+5E74 "年" */ - 0x0, 0x1, 0x40, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x7, 0xa0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xd, - 0x65, 0x55, 0x55, 0x5c, 0x60, 0x0, 0x74, 0x0, - 0xd, 0x0, 0x0, 0x0, 0x3, 0x60, 0x0, 0xd, - 0x0, 0x0, 0x0, 0x4, 0x8, 0x55, 0x5d, 0x55, - 0xa7, 0x0, 0x0, 0xd, 0x0, 0xd, 0x0, 0x0, - 0x0, 0x0, 0xd, 0x0, 0xd, 0x0, 0x0, 0x0, - 0x0, 0xd, 0x0, 0xd, 0x0, 0x2, 0x80, 0x17, - 0x55, 0x55, 0x5d, 0x55, 0x55, 0x51, 0x0, 0x0, - 0x0, 0xd, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0xd, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xe, - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x3, 0x0, - 0x0, 0x0, - - /* U+5E78 "幸" */ - 0x0, 0x0, 0x0, 0x30, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, 0xa3, 0x0, 0x0, 0x0, 0x0, 0x16, - 0x55, 0xc6, 0x58, 0x90, 0x0, 0x0, 0x0, 0x0, - 0xa1, 0x0, 0x0, 0x0, 0x5, 0x55, 0x55, 0xb6, - 0x55, 0x6d, 0x30, 0x0, 0x0, 0x52, 0x0, 0x83, - 0x0, 0x0, 0x0, 0x0, 0x1c, 0x0, 0xa0, 0x0, - 0x0, 0x0, 0x65, 0x57, 0x68, 0x65, 0xc3, 0x0, - 0x0, 0x0, 0x0, 0xa1, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, 0xa1, 0x0, 0x7, 0x50, 0x26, 0x55, - 0x55, 0xc6, 0x55, 0x55, 0x40, 0x0, 0x0, 0x0, - 0xa1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xa2, - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x30, 0x0, - 0x0, 0x0, - - /* U+5E7E "幾" */ - 0x0, 0x0, 0x10, 0x13, 0x0, 0x20, 0x0, 0x0, - 0x4, 0xa0, 0x1a, 0x4, 0xa0, 0x0, 0x0, 0x18, - 0x2, 0xa, 0x18, 0x3, 0x0, 0x1, 0xb6, 0x6b, - 0x1b, 0xa8, 0x5c, 0x30, 0x0, 0x32, 0x80, 0xa, - 0x10, 0x82, 0x0, 0x0, 0x36, 0x28, 0xb, 0x3a, - 0x47, 0x60, 0x0, 0x99, 0x67, 0x3a, 0x2a, 0x30, - 0x90, 0x0, 0x3, 0x90, 0x9, 0x12, 0x73, 0x40, - 0x5, 0x58, 0x95, 0x59, 0x85, 0x57, 0x60, 0x0, - 0x9, 0x80, 0x2, 0x90, 0xaa, 0x0, 0x0, 0x9, - 0x3c, 0x0, 0xbb, 0x70, 0x2, 0x0, 0x71, 0x3, - 0x4, 0xac, 0x40, 0x24, 0x5, 0x20, 0x4, 0x73, - 0x1, 0x9c, 0xc4, 0x1, 0x0, 0x30, 0x0, 0x0, - 0x1, 0x52, - - /* U+5E83 "広" */ - 0x0, 0x0, 0x0, 0x10, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, 0xc2, 0x0, 0x0, 0x0, 0x20, 0x0, - 0x5, 0x30, 0x8, 0x20, 0x9, 0x85, 0x55, 0x55, - 0x55, 0x53, 0x0, 0x94, 0x0, 0x4, 0x20, 0x0, - 0x0, 0x9, 0x30, 0x0, 0xb7, 0x0, 0x0, 0x0, - 0xa3, 0x0, 0x2d, 0x0, 0x0, 0x0, 0xb, 0x10, - 0x8, 0x40, 0x0, 0x0, 0x0, 0xc0, 0x1, 0xa0, - 0x0, 0x0, 0x0, 0xa, 0x0, 0x82, 0x0, 0x19, - 0x10, 0x3, 0x50, 0x46, 0x0, 0x0, 0x3d, 0x10, - 0x70, 0x2e, 0x99, 0x98, 0x87, 0xc8, 0x15, 0x0, - 0x84, 0x10, 0x0, 0x2, 0x61, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x0, - - /* U+5E86 "庆" */ - 0x0, 0x0, 0x0, 0x20, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x1d, 0x0, 0x0, 0x0, 0x0, 0x85, - 0x55, 0x5c, 0x55, 0x5b, 0x80, 0x0, 0xc0, 0x0, - 0x7, 0x10, 0x0, 0x0, 0x0, 0xc0, 0x0, 0xd, - 0x0, 0x0, 0x0, 0x0, 0xc0, 0x0, 0xc, 0x0, - 0x0, 0x10, 0x0, 0xc3, 0x65, 0x5d, 0x65, 0x57, - 0x80, 0x0, 0xc0, 0x0, 0xc, 0x50, 0x0, 0x0, - 0x0, 0xc0, 0x0, 0x29, 0x71, 0x0, 0x0, 0x1, - 0xa0, 0x0, 0x84, 0x19, 0x0, 0x0, 0x5, 0x60, - 0x1, 0xb0, 0x7, 0x70, 0x0, 0x8, 0x0, 0x29, - 0x10, 0x0, 0xab, 0x30, 0x24, 0x5, 0x60, 0x0, - 0x0, 0x8, 0x91, 0x10, 0x20, 0x0, 0x0, 0x0, - 0x0, 0x0, - - /* U+5E95 "底" */ - 0x0, 0x0, 0x0, 0x30, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x2d, 0x0, 0x0, 0x0, 0x0, 0xb5, - 0x55, 0x5b, 0x55, 0x5a, 0x70, 0x0, 0xd0, 0x0, - 0x0, 0x0, 0x40, 0x0, 0x0, 0xd0, 0x42, 0x47, - 0x9b, 0xb5, 0x0, 0x0, 0xd0, 0xc3, 0x15, 0x80, - 0x0, 0x0, 0x0, 0xd0, 0xc0, 0x2, 0xa0, 0x2, - 0x0, 0x0, 0xd0, 0xc5, 0x55, 0xd5, 0x59, 0x40, - 0x0, 0xb0, 0xc0, 0x0, 0xb1, 0x0, 0x0, 0x2, - 0x80, 0xc0, 0x0, 0x77, 0x0, 0x0, 0x6, 0x30, - 0xc1, 0x75, 0xd, 0x20, 0x50, 0x8, 0x0, 0xdb, - 0x38, 0x13, 0xd4, 0x90, 0x23, 0x0, 0x30, 0x5, - 0x80, 0x2b, 0xd0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x20, - - /* U+5E97 "店" */ - 0x0, 0x0, 0x0, 0x31, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x1d, 0x10, 0x0, 0x20, 0x0, 0x86, - 0x55, 0x5a, 0x55, 0x58, 0xb1, 0x0, 0x93, 0x0, - 0xa, 0x20, 0x0, 0x0, 0x0, 0x93, 0x0, 0xc, - 0x0, 0x0, 0x0, 0x0, 0x93, 0x0, 0xc, 0x55, - 0x5b, 0x40, 0x0, 0xa2, 0x0, 0xc, 0x0, 0x0, - 0x0, 0x0, 0xa2, 0x0, 0xc, 0x0, 0x1, 0x0, - 0x0, 0xc0, 0xb5, 0x58, 0x55, 0x5e, 0x0, 0x0, - 0xc0, 0xb0, 0x0, 0x0, 0xd, 0x0, 0x3, 0x70, - 0xb0, 0x0, 0x0, 0xd, 0x0, 0x7, 0x0, 0xb5, - 0x55, 0x55, 0x5d, 0x0, 0x23, 0x0, 0xb0, 0x0, - 0x0, 0x9, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, - - /* U+5E9C "府" */ - 0x0, 0x0, 0x0, 0x30, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x1d, 0x0, 0x0, 0x10, 0x0, 0xa5, - 0x55, 0x59, 0x55, 0x59, 0x90, 0x0, 0xc0, 0x2, - 0x50, 0x0, 0x61, 0x0, 0x0, 0xc0, 0x8, 0x70, - 0x0, 0xb0, 0x0, 0x0, 0xc0, 0xc, 0x0, 0x0, - 0xb0, 0x60, 0x0, 0xc0, 0x7d, 0x26, 0x55, 0xc5, - 0x51, 0x0, 0xb1, 0x9b, 0x12, 0x0, 0xb0, 0x0, - 0x2, 0xa7, 0xb, 0x9, 0x50, 0xb0, 0x0, 0x4, - 0x70, 0xb, 0x1, 0x90, 0xb0, 0x0, 0x7, 0x10, - 0xb, 0x0, 0x0, 0xb0, 0x0, 0x8, 0x0, 0xb, - 0x0, 0x0, 0xb0, 0x0, 0x32, 0x0, 0xb, 0x0, - 0x39, 0xc0, 0x0, 0x0, 0x0, 0x4, 0x0, 0x1, - 0x20, 0x0, - - /* U+5EA6 "度" */ - 0x0, 0x0, 0x0, 0x40, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x3c, 0x0, 0x1, 0x0, 0x0, 0xb5, - 0x55, 0x58, 0x55, 0x59, 0x70, 0x0, 0xc0, 0x9, - 0x30, 0xa, 0x20, 0x0, 0x0, 0xc4, 0x5b, 0x65, - 0x5d, 0x5b, 0x40, 0x0, 0xc0, 0x9, 0x20, 0xb, - 0x0, 0x0, 0x0, 0xc0, 0x9, 0x65, 0x5c, 0x0, - 0x0, 0x0, 0xc0, 0x4, 0x0, 0x3, 0x20, 0x0, - 0x0, 0xa0, 0x47, 0x55, 0x59, 0xb0, 0x0, 0x2, - 0x70, 0x0, 0x70, 0x2c, 0x0, 0x0, 0x6, 0x20, - 0x0, 0x29, 0xc1, 0x0, 0x0, 0x7, 0x0, 0x0, - 0x6a, 0xb6, 0x10, 0x0, 0x23, 0x2, 0x67, 0x30, - 0x7, 0xcd, 0x80, 0x10, 0x22, 0x0, 0x0, 0x0, - 0x1, 0x0, - - /* U+5EA7 "座" */ - 0x0, 0x0, 0x0, 0x20, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x4b, 0x0, 0x1, 0x0, 0x0, 0x95, - 0x55, 0x5b, 0x55, 0x5d, 0x50, 0x0, 0xd0, 0x0, - 0x3, 0x0, 0x0, 0x0, 0x0, 0xc0, 0x36, 0xa, - 0x20, 0x81, 0x0, 0x0, 0xc0, 0x75, 0xa, 0x1, - 0xd0, 0x0, 0x0, 0xc0, 0xa5, 0xa, 0x6, 0x94, - 0x0, 0x0, 0xc2, 0x55, 0x9a, 0x8, 0x9, 0x70, - 0x0, 0xb6, 0x0, 0x5a, 0x41, 0x21, 0x30, 0x1, - 0x90, 0x65, 0x5c, 0x55, 0x86, 0x0, 0x5, 0x40, - 0x0, 0xa, 0x0, 0x0, 0x0, 0x7, 0x0, 0x0, - 0xa, 0x0, 0x0, 0x0, 0x14, 0x15, 0x55, 0x5c, - 0x55, 0x5b, 0xa0, 0x0, 0x1, 0x0, 0x0, 0x0, - 0x0, 0x0, - - /* U+5EAB "庫" */ - 0x0, 0x0, 0x0, 0x31, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x1, 0xd0, 0x0, 0x0, 0x0, 0x65, 0x55, - 0x5a, 0x55, 0x5d, 0x30, 0x8, 0x30, 0x0, 0x28, - 0x0, 0x0, 0x0, 0x83, 0x65, 0x56, 0xb5, 0x88, - 0x0, 0x8, 0x30, 0x20, 0x19, 0x3, 0x0, 0x0, - 0x92, 0xd, 0x56, 0xb5, 0xc2, 0x0, 0xa, 0x10, - 0xc5, 0x6b, 0x5c, 0x10, 0x0, 0xa0, 0xb, 0x1, - 0x90, 0xa1, 0x0, 0xa, 0x0, 0xc5, 0x6b, 0x59, - 0x10, 0x3, 0x53, 0x55, 0x56, 0xb5, 0x5d, 0x50, - 0x70, 0x1, 0x0, 0x19, 0x0, 0x0, 0x23, 0x0, - 0x0, 0x2, 0xa0, 0x0, 0x1, 0x0, 0x0, 0x0, - 0x12, 0x0, 0x0, - - /* U+5EAD "庭" */ - 0x0, 0x0, 0x0, 0x40, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x2c, 0x0, 0x3, 0x0, 0x2, 0xa5, - 0x55, 0x58, 0x55, 0x59, 0x40, 0x2, 0xa0, 0x2, - 0x0, 0x0, 0x48, 0x0, 0x2, 0xa6, 0x6e, 0x24, - 0x5d, 0x53, 0x0, 0x2, 0xa0, 0x84, 0x0, 0xc, - 0x0, 0x0, 0x2, 0x95, 0x82, 0x10, 0xc, 0x4, - 0x10, 0x2, 0x97, 0x5b, 0x56, 0x5d, 0x55, 0x30, - 0x3, 0x72, 0xb, 0x0, 0xc, 0x0, 0x0, 0x4, - 0x53, 0x69, 0x0, 0xc, 0x0, 0x30, 0x7, 0x10, - 0xd5, 0x26, 0x56, 0x55, 0x60, 0x7, 0x7, 0x68, - 0x94, 0x10, 0x0, 0x0, 0x32, 0x74, 0x0, 0x28, - 0xbd, 0xef, 0xa1, 0x1, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, - - /* U+5EB7 "康" */ - 0x0, 0x0, 0x0, 0x13, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, 0xa, 0x40, 0x1, 0x20, 0x0, 0xa5, - 0x55, 0x57, 0x65, 0x58, 0x80, 0x0, 0xa1, 0x0, - 0xc, 0x0, 0x20, 0x0, 0x0, 0xa1, 0x65, 0x5c, - 0x55, 0xc3, 0x0, 0x0, 0xa5, 0x55, 0x5c, 0x55, - 0xc7, 0xa0, 0x0, 0xb2, 0x0, 0xb, 0x0, 0xa0, - 0x0, 0x0, 0xc0, 0x65, 0x5c, 0x65, 0xc1, 0x0, - 0x0, 0xb0, 0x44, 0xb, 0x50, 0x2a, 0x20, 0x1, - 0xa0, 0xb, 0x2c, 0x54, 0x83, 0x0, 0x5, 0x40, - 0x7, 0x5b, 0xb, 0x20, 0x0, 0x8, 0x9, 0xa1, - 0xb, 0x1, 0xc7, 0x20, 0x23, 0x5, 0x3, 0xba, - 0x0, 0x9, 0x60, 0x10, 0x0, 0x0, 0x10, 0x0, - 0x0, 0x0, - - /* U+5EE0 "廠" */ - 0x0, 0x0, 0x0, 0x22, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, 0xc, 0x10, 0x1, 0x10, 0x0, 0x85, - 0x55, 0x58, 0x55, 0x59, 0x80, 0x0, 0xb0, 0x2, - 0x70, 0x2, 0x30, 0x0, 0x0, 0xb1, 0x63, 0xb2, - 0x96, 0x60, 0x0, 0x0, 0xb0, 0x84, 0xb6, 0x9, - 0x44, 0x60, 0x0, 0xb3, 0x66, 0xb6, 0x9a, 0x19, - 0x20, 0x0, 0xa4, 0x61, 0x12, 0xb6, 0x19, 0x0, - 0x0, 0xa4, 0x6b, 0x87, 0xa1, 0x59, 0x0, 0x0, - 0x84, 0x69, 0x46, 0x90, 0xa6, 0x0, 0x4, 0x44, - 0x69, 0x75, 0x90, 0xb4, 0x0, 0x6, 0x4, 0x60, - 0x13, 0x95, 0x4b, 0x20, 0x4, 0x4, 0x30, 0x8, - 0x73, 0x2, 0xc2, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, - - /* U+5EFA "建" */ - 0x0, 0x0, 0x0, 0x0, 0x30, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x0, 0xd0, 0x0, 0x0, 0x5, 0x57, - 0xa2, 0x55, 0xc5, 0x5b, 0x0, 0x0, 0xa, 0x20, - 0x0, 0xb0, 0xb, 0x20, 0x0, 0x48, 0x15, 0x55, - 0xc5, 0x5d, 0x70, 0x0, 0xa0, 0x1, 0x22, 0xb2, - 0x2b, 0x0, 0x5, 0x85, 0xd2, 0x33, 0xc3, 0x35, - 0x0, 0x0, 0x0, 0xa2, 0x55, 0xc5, 0x86, 0x0, - 0x1, 0x33, 0x70, 0x0, 0xb0, 0x0, 0x0, 0x0, - 0x77, 0x45, 0x55, 0xc5, 0x57, 0x70, 0x0, 0x2d, - 0x0, 0x0, 0xb0, 0x0, 0x0, 0x0, 0x77, 0xb5, - 0x10, 0xa0, 0x0, 0x0, 0x5, 0x20, 0x17, 0xbc, - 0xcc, 0xde, 0xc1, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, - - /* U+5EFF "廿" */ - 0x0, 0x0, 0x10, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0xc2, 0x0, 0xd, 0x0, 0x0, 0x0, 0x0, - 0xc0, 0x0, 0xc, 0x0, 0x0, 0x0, 0x0, 0xc0, - 0x0, 0xc, 0x0, 0x0, 0x0, 0x0, 0xc0, 0x0, - 0xc, 0x1, 0x60, 0x6, 0x55, 0xd5, 0x55, 0x5d, - 0x56, 0x61, 0x0, 0x0, 0xc0, 0x0, 0xc, 0x0, - 0x0, 0x0, 0x0, 0xc0, 0x0, 0xc, 0x0, 0x0, - 0x0, 0x0, 0xc0, 0x0, 0xc, 0x0, 0x0, 0x0, - 0x0, 0xc0, 0x0, 0xc, 0x0, 0x0, 0x0, 0x0, - 0xc0, 0x0, 0xc, 0x0, 0x0, 0x0, 0x0, 0xc5, - 0x55, 0x5c, 0x0, 0x0, 0x0, 0x0, 0xb0, 0x0, - 0xb, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, - - /* U+5F0F "式" */ - 0x0, 0x0, 0x0, 0x1, 0x30, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x2, 0xc2, 0x81, 0x0, 0x0, 0x0, - 0x0, 0x1, 0xb0, 0x68, 0x0, 0x3, 0x55, 0x55, - 0x56, 0xd5, 0x5b, 0xa0, 0x1, 0x10, 0x0, 0x0, - 0xc0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x10, 0xc0, - 0x0, 0x0, 0x3, 0x65, 0x85, 0xb3, 0xc0, 0x0, - 0x0, 0x0, 0x0, 0xc0, 0x0, 0x93, 0x0, 0x0, - 0x0, 0x0, 0xc0, 0x0, 0x58, 0x0, 0x0, 0x0, - 0x0, 0xc0, 0x0, 0xd, 0x0, 0x30, 0x0, 0x0, - 0xd6, 0x64, 0x8, 0x80, 0x60, 0x8, 0xba, 0x61, - 0x0, 0x0, 0xc8, 0x90, 0x5, 0x20, 0x0, 0x0, - 0x0, 0xa, 0xf1, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x11, - - /* U+5F15 "引" */ - 0x0, 0x0, 0x0, 0x0, 0x1, 0x0, 0x55, 0x55, - 0x59, 0x0, 0xb4, 0x1, 0x0, 0x2, 0x90, 0xa, - 0x10, 0x0, 0x0, 0x29, 0x0, 0xa1, 0x6, 0x75, - 0x56, 0xa0, 0xa, 0x10, 0x93, 0x0, 0x12, 0x0, - 0xa1, 0xc, 0x0, 0x0, 0x0, 0xa, 0x12, 0xc5, - 0x55, 0x5d, 0x10, 0xa1, 0x0, 0x0, 0x0, 0xa0, - 0xa, 0x10, 0x0, 0x0, 0x47, 0x0, 0xa1, 0x0, - 0x0, 0x8, 0x40, 0xa, 0x10, 0x2, 0x54, 0xd0, - 0x0, 0xa1, 0x0, 0x4, 0xe4, 0x0, 0xb, 0x20, - 0x0, 0x0, 0x0, 0x0, 0x10, - - /* U+5F1F "弟" */ - 0x0, 0x0, 0x0, 0x0, 0x20, 0x0, 0x0, 0x0, - 0x94, 0x0, 0xd, 0x30, 0x0, 0x0, 0x1, 0xb0, - 0x6, 0x30, 0x0, 0x0, 0x46, 0x55, 0x58, 0x75, - 0x5d, 0x0, 0x0, 0x0, 0x1, 0xa0, 0x0, 0xc0, - 0x0, 0x8, 0x55, 0x6c, 0x55, 0x5c, 0x0, 0x1, - 0xb0, 0x1, 0xa0, 0x0, 0x60, 0x0, 0x76, 0x0, - 0x1a, 0x0, 0x0, 0x40, 0x6, 0x55, 0x6f, 0xc5, - 0x55, 0x7c, 0x0, 0x0, 0xb, 0x5a, 0x0, 0x4, - 0x80, 0x0, 0x9, 0x41, 0xa0, 0x0, 0x75, 0x0, - 0x18, 0x20, 0x1a, 0x5, 0xad, 0x20, 0x35, 0x0, - 0x2, 0xb0, 0x4, 0x30, 0x0, 0x0, 0x0, 0x1, - 0x0, 0x0, 0x0, - - /* U+5F31 "弱" */ - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x36, - 0x55, 0xb3, 0x56, 0x55, 0xc1, 0x0, 0x0, 0xa, - 0x10, 0x0, 0xb, 0x0, 0x3, 0x0, 0xa1, 0x14, - 0x22, 0xc0, 0x0, 0xc5, 0x59, 0x13, 0x92, 0x27, - 0x0, 0x1a, 0x0, 0x0, 0x65, 0x0, 0x10, 0x4, - 0x95, 0x5c, 0x3a, 0x65, 0x5a, 0x60, 0x4, 0x10, - 0xb0, 0x5, 0x10, 0x75, 0x0, 0x1c, 0xb, 0x0, - 0x2b, 0x7, 0x50, 0x0, 0x24, 0xc0, 0x0, 0x45, - 0x84, 0x2, 0x87, 0xb, 0x3, 0x86, 0x8, 0x40, - 0xc3, 0x0, 0xb0, 0xa2, 0x10, 0xb2, 0x0, 0x6, - 0xd6, 0x0, 0x3, 0xcc, 0x0, 0x0, 0x2, 0x0, - 0x0, 0x1, 0x0, - - /* U+5F35 "張" */ - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x5, - 0x55, 0x92, 0x75, 0x55, 0x5b, 0x20, 0x0, 0x0, - 0xa1, 0x91, 0x0, 0x1, 0x0, 0x0, 0x0, 0xa1, - 0x96, 0x55, 0x67, 0x0, 0x8, 0x55, 0xc1, 0x91, - 0x0, 0x5, 0x0, 0xc, 0x0, 0x30, 0x96, 0x55, - 0x55, 0x0, 0xb, 0x0, 0x2, 0xa4, 0x33, 0x35, - 0x60, 0x3c, 0x55, 0x96, 0xc2, 0x72, 0x23, 0x20, - 0x0, 0x0, 0xa2, 0xb0, 0x51, 0x2c, 0x20, 0x0, - 0x0, 0xb0, 0xb0, 0x19, 0x60, 0x0, 0x0, 0x0, - 0xb0, 0xb0, 0x7, 0x50, 0x0, 0x2, 0x14, 0x80, - 0xb5, 0x60, 0xb7, 0x0, 0x0, 0xaf, 0x20, 0xd7, - 0x0, 0x1b, 0x90, 0x0, 0x1, 0x0, 0x10, 0x0, - 0x0, 0x0, - - /* U+5F37 "強" */ - 0x0, 0x0, 0x0, 0x0, 0x31, 0x0, 0x1, 0x55, - 0x5a, 0x20, 0xc, 0x50, 0x0, 0x0, 0x0, 0xa0, - 0x7, 0x30, 0x10, 0x0, 0x0, 0xa, 0x6, 0x20, - 0x1, 0xa3, 0x9, 0x55, 0xc4, 0xd9, 0x88, 0x44, - 0xc0, 0xb0, 0x2, 0x0, 0x2, 0xa0, 0x1, 0xa, - 0x0, 0x0, 0xa5, 0x6b, 0x5b, 0x14, 0xb5, 0x59, - 0x3b, 0x2, 0x90, 0xb0, 0x0, 0x0, 0xb1, 0xb0, - 0x29, 0xb, 0x0, 0x0, 0xc, 0xc, 0x56, 0xb5, - 0xb0, 0x0, 0x1, 0xb0, 0x0, 0x29, 0x5, 0x0, - 0x20, 0x77, 0x1, 0x25, 0xb5, 0x87, 0x0, 0xad, - 0x2, 0xd8, 0x53, 0x0, 0xb0, 0x1, 0x10, 0x0, - 0x0, 0x0, 0x0, - - /* U+5F53 "当" */ - 0x0, 0x0, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, - 0xa, 0x50, 0x2, 0x0, 0x4, 0x80, 0xa, 0x10, - 0x4e, 0x10, 0x0, 0x7a, 0xa, 0x10, 0xb2, 0x0, - 0x0, 0x5, 0xa, 0x16, 0x10, 0x0, 0x16, 0x55, - 0x5b, 0x65, 0x55, 0xb2, 0x0, 0x0, 0x0, 0x0, - 0x0, 0xd0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xd0, - 0x3, 0x55, 0x55, 0x55, 0x55, 0xe0, 0x0, 0x0, - 0x0, 0x0, 0x0, 0xd0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0xd0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xd0, - 0x46, 0x55, 0x55, 0x55, 0x55, 0xe0, 0x0, 0x0, - 0x0, 0x0, 0x0, 0x20, - - /* U+5F62 "形" */ - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x3, - 0x55, 0x55, 0x5b, 0x50, 0x1d, 0x10, 0x0, 0xc, - 0x0, 0xb0, 0x0, 0x95, 0x0, 0x0, 0xc, 0x0, - 0xb0, 0x5, 0x50, 0x0, 0x0, 0xc, 0x0, 0xb0, - 0x24, 0x0, 0x0, 0x0, 0xc, 0x0, 0xb4, 0x40, - 0xa, 0x70, 0x5, 0x5d, 0x55, 0xc5, 0x40, 0x79, - 0x0, 0x0, 0xc, 0x0, 0xb0, 0x7, 0x60, 0x0, - 0x0, 0x1a, 0x0, 0xb0, 0x63, 0x0, 0x40, 0x0, - 0x56, 0x0, 0xb0, 0x0, 0x8, 0xd1, 0x0, 0x91, - 0x0, 0xb0, 0x0, 0x79, 0x0, 0x2, 0x60, 0x0, - 0xb0, 0x8, 0x50, 0x0, 0x6, 0x0, 0x0, 0x73, - 0x72, 0x0, 0x0, 0x0, 0x0, 0x0, 0x2, 0x0, - 0x0, 0x0, - - /* U+5F71 "影" */ - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x1, - 0x95, 0x55, 0x5c, 0x0, 0x8, 0x50, 0x1, 0xa0, - 0x0, 0xb, 0x0, 0x3b, 0x0, 0x1, 0xb5, 0x55, - 0x5b, 0x1, 0x90, 0x0, 0x1, 0xb5, 0x85, 0x5a, - 0x15, 0x0, 0x10, 0x2, 0x22, 0xb2, 0x26, 0x40, - 0x2, 0xe1, 0x4, 0x53, 0x33, 0x37, 0x20, 0xb, - 0x20, 0x0, 0xc5, 0x55, 0x6b, 0x0, 0x91, 0x0, - 0x0, 0xa0, 0x0, 0x1a, 0x16, 0x0, 0x33, 0x0, - 0x95, 0xc5, 0x67, 0x0, 0x1, 0xd5, 0x0, 0x66, - 0xb3, 0x60, 0x0, 0x2b, 0x20, 0x1, 0x90, 0xb0, - 0x77, 0x4, 0x91, 0x0, 0x6, 0x17, 0xd0, 0x3, - 0x64, 0x0, 0x0, 0x0, 0x0, 0x10, 0x2, 0x0, - 0x0, 0x0, - - /* U+5F79 "役" */ - 0x0, 0x1, 0x10, 0x0, 0x0, 0x0, 0x0, 0x0, - 0xa, 0x80, 0x2a, 0x55, 0xc0, 0x0, 0x0, 0x49, - 0x0, 0x29, 0x0, 0xb0, 0x0, 0x2, 0x80, 0x20, - 0x47, 0x0, 0xb0, 0x0, 0x4, 0x3, 0xe1, 0x82, - 0x0, 0xc0, 0x10, 0x0, 0xc, 0x24, 0x50, 0x0, - 0x68, 0x83, 0x0, 0x8c, 0x23, 0x55, 0x55, 0x78, - 0x0, 0x5, 0x4c, 0x0, 0x5, 0x0, 0x93, 0x0, - 0x13, 0xc, 0x0, 0x6, 0x1, 0xb0, 0x0, 0x0, - 0xc, 0x0, 0x1, 0x8a, 0x30, 0x0, 0x0, 0xc, - 0x0, 0x0, 0xbb, 0x0, 0x0, 0x0, 0xc, 0x0, - 0x19, 0x57, 0xa2, 0x0, 0x0, 0xc, 0x5, 0x71, - 0x0, 0x4c, 0xc1, 0x0, 0x3, 0x20, 0x0, 0x0, - 0x0, 0x0, - - /* U+5F7C "彼" */ - 0x0, 0x0, 0x0, 0x0, 0x3, 0x0, 0x0, 0x0, - 0xd, 0x20, 0x0, 0xc, 0x0, 0x0, 0x0, 0x57, - 0x0, 0x30, 0xb, 0x0, 0x40, 0x1, 0x90, 0x30, - 0xd5, 0x5c, 0x57, 0xc1, 0x6, 0x6, 0xb0, 0xb0, - 0xb, 0x5, 0x0, 0x0, 0xc, 0x10, 0xb0, 0xb, - 0x0, 0x0, 0x0, 0x8b, 0x0, 0xc6, 0x58, 0x5c, - 0x20, 0x4, 0x5b, 0x0, 0xa1, 0x40, 0x1a, 0x0, - 0x3, 0xb, 0x2, 0x90, 0x80, 0x83, 0x0, 0x0, - 0xb, 0x5, 0x50, 0x65, 0xa0, 0x0, 0x0, 0xb, - 0x8, 0x0, 0x1f, 0x20, 0x0, 0x0, 0xb, 0x16, - 0x3, 0x94, 0xb5, 0x0, 0x0, 0xb, 0x53, 0x53, - 0x0, 0x1a, 0xc1, 0x0, 0x1, 0x0, 0x0, 0x0, - 0x0, 0x0, - - /* U+5F80 "往" */ - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x6, 0x90, 0x4, 0x70, 0x0, 0x0, 0x0, 0x1b, - 0x0, 0x0, 0xb3, 0x0, 0x0, 0x0, 0x71, 0x0, - 0x0, 0x20, 0x6, 0x10, 0x4, 0x2, 0xa5, 0x55, - 0xd5, 0x55, 0x30, 0x0, 0xa, 0x60, 0x0, 0xc0, - 0x0, 0x0, 0x0, 0x4d, 0x0, 0x0, 0xc0, 0x0, - 0x0, 0x1, 0x9c, 0x1, 0x55, 0xd5, 0x5a, 0x10, - 0x7, 0xc, 0x0, 0x0, 0xc0, 0x0, 0x0, 0x10, - 0xc, 0x0, 0x0, 0xc0, 0x0, 0x0, 0x0, 0xc, - 0x0, 0x0, 0xc0, 0x0, 0x0, 0x0, 0xc, 0x0, - 0x0, 0xc0, 0x0, 0x50, 0x0, 0xc, 0x36, 0x55, - 0x75, 0x56, 0x71, 0x0, 0x3, 0x0, 0x0, 0x0, - 0x0, 0x0, - - /* U+5F85 "待" */ - 0x0, 0x0, 0x0, 0x0, 0x20, 0x0, 0x0, 0x0, - 0x7, 0x90, 0x0, 0xc2, 0x0, 0x0, 0x0, 0x1b, - 0x0, 0x0, 0xc0, 0x5, 0x0, 0x0, 0x91, 0x32, - 0x55, 0xd5, 0x55, 0x0, 0x5, 0x13, 0xd0, 0x0, - 0xc0, 0x0, 0x0, 0x0, 0xb, 0x47, 0x55, 0x95, - 0x55, 0xa1, 0x0, 0x6d, 0x0, 0x0, 0x0, 0xa1, - 0x0, 0x2, 0x6c, 0x5, 0x55, 0x55, 0xd5, 0xb0, - 0x4, 0xc, 0x0, 0x30, 0x0, 0xb0, 0x0, 0x0, - 0xc, 0x0, 0x3a, 0x0, 0xb0, 0x0, 0x0, 0xc, - 0x0, 0xa, 0x0, 0xb0, 0x0, 0x0, 0xc, 0x0, - 0x0, 0x0, 0xb0, 0x0, 0x0, 0xc, 0x0, 0x0, - 0x5b, 0xc0, 0x0, 0x0, 0x1, 0x0, 0x0, 0x2, - 0x10, 0x0, - - /* U+5F88 "很" */ - 0x0, 0x2, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0xc, 0x40, 0x75, 0x55, 0x59, 0x0, 0x0, 0x47, - 0x0, 0xb0, 0x0, 0xb, 0x0, 0x0, 0x80, 0x30, - 0xb0, 0x0, 0xb, 0x0, 0x5, 0x3, 0xc0, 0xb5, - 0x55, 0x5b, 0x0, 0x0, 0xa, 0x20, 0xb0, 0x0, - 0xb, 0x0, 0x0, 0x4c, 0x0, 0xb5, 0x65, 0x5b, - 0x0, 0x0, 0x8b, 0x0, 0xb0, 0x60, 0x8, 0x20, - 0x6, 0xb, 0x0, 0xb0, 0x61, 0x67, 0x10, 0x0, - 0xb, 0x0, 0xb0, 0xb, 0x10, 0x0, 0x0, 0xb, - 0x0, 0xb0, 0x6, 0x80, 0x0, 0x0, 0xb, 0x0, - 0xb6, 0x71, 0x7c, 0x40, 0x0, 0xc, 0x0, 0xb5, - 0x0, 0x3, 0x81, 0x0, 0x2, 0x0, 0x0, 0x0, - 0x0, 0x0, - - /* U+5F8B "律" */ - 0x0, 0x4, 0x0, 0x0, 0x50, 0x0, 0x0, 0x0, - 0x4b, 0x0, 0x0, 0xd0, 0x0, 0x0, 0x0, 0xa1, - 0x3, 0x55, 0xd5, 0x5a, 0x10, 0x5, 0x24, 0x50, - 0x0, 0xc0, 0xc, 0x0, 0x2, 0xb, 0x66, 0x55, - 0xd5, 0x5d, 0xa3, 0x0, 0x3b, 0x0, 0x0, 0xc0, - 0xc, 0x0, 0x0, 0xba, 0x4, 0x65, 0xd5, 0x5b, - 0x0, 0x6, 0x3a, 0x0, 0x0, 0xc0, 0x4, 0x0, - 0x2, 0x1a, 0x5, 0x55, 0xd5, 0x56, 0x20, 0x0, - 0x1a, 0x0, 0x0, 0xc0, 0x0, 0x60, 0x0, 0x1a, - 0x56, 0x55, 0xd5, 0x55, 0x51, 0x0, 0x1a, 0x0, - 0x0, 0xc0, 0x0, 0x0, 0x0, 0x2a, 0x0, 0x0, - 0xd0, 0x0, 0x0, 0x0, 0x1, 0x0, 0x0, 0x40, - 0x0, 0x0, - - /* U+5F8C "後" */ - 0x0, 0x0, 0x10, 0x0, 0x10, 0x0, 0x0, 0x0, - 0x7, 0xb0, 0x0, 0xd3, 0x0, 0x0, 0x0, 0x2b, - 0x0, 0x9, 0x20, 0x97, 0x0, 0x1, 0x90, 0x31, - 0xd8, 0x59, 0x70, 0x0, 0x6, 0x3, 0xd1, 0x41, - 0x83, 0x31, 0x0, 0x0, 0xb, 0x20, 0x58, 0x0, - 0x2c, 0x20, 0x0, 0x8d, 0x4, 0xcc, 0x85, 0x35, - 0x70, 0x6, 0x5c, 0x0, 0xc, 0x20, 0x12, 0x0, - 0x12, 0xc, 0x0, 0x89, 0x55, 0xaa, 0x0, 0x0, - 0xc, 0x4, 0x54, 0x21, 0xc0, 0x0, 0x0, 0xc, - 0x13, 0x0, 0x9b, 0x20, 0x0, 0x0, 0xc, 0x0, - 0x1, 0xab, 0x40, 0x0, 0x0, 0xc, 0x2, 0x77, - 0x10, 0x7d, 0xa2, 0x0, 0x3, 0x22, 0x0, 0x0, - 0x0, 0x20, - - /* U+5F92 "徒" */ - 0x0, 0x2, 0x0, 0x0, 0x30, 0x0, 0x0, 0x0, - 0xc, 0x40, 0x0, 0xa4, 0x0, 0x0, 0x0, 0x58, - 0x0, 0x0, 0x92, 0x3, 0x0, 0x1, 0x90, 0x42, - 0x65, 0xb7, 0x57, 0x40, 0x6, 0x5, 0xc0, 0x0, - 0x92, 0x0, 0x0, 0x0, 0xc, 0x20, 0x0, 0x92, - 0x1, 0x70, 0x0, 0x7c, 0x16, 0x55, 0xb8, 0x55, - 0x51, 0x3, 0x8c, 0x0, 0xa0, 0x92, 0x0, 0x0, - 0x15, 0xc, 0x1, 0xb0, 0x97, 0x59, 0x50, 0x0, - 0xc, 0x3, 0xa0, 0x92, 0x0, 0x0, 0x0, 0xc, - 0x7, 0x35, 0x92, 0x0, 0x0, 0x0, 0xc, 0x7, - 0x3, 0xd6, 0x10, 0x0, 0x0, 0xc, 0x40, 0x0, - 0x6, 0xbe, 0xe3, 0x0, 0x0, 0x10, 0x0, 0x0, - 0x0, 0x0, - - /* U+5F93 "従" */ - 0x0, 0x0, 0x20, 0x0, 0x0, 0x1, 0x0, 0x0, - 0x7, 0xc0, 0x73, 0x0, 0xb, 0x60, 0x0, 0x2b, - 0x0, 0xd, 0x20, 0x29, 0x0, 0x0, 0x90, 0x20, - 0x5, 0x40, 0x70, 0x0, 0x6, 0x1, 0xe4, 0x55, - 0x55, 0x66, 0xc1, 0x0, 0x9, 0x60, 0x10, 0xc, - 0x0, 0x0, 0x0, 0x4d, 0x0, 0x51, 0xc, 0x0, - 0x0, 0x1, 0x8c, 0x0, 0xa4, 0xc, 0x2, 0x20, - 0x5, 0xc, 0x0, 0xb1, 0xd, 0x55, 0x30, 0x0, - 0xc, 0x0, 0xd1, 0xc, 0x0, 0x0, 0x0, 0xc, - 0x2, 0x97, 0x1c, 0x0, 0x0, 0x0, 0xc, 0x7, - 0x10, 0xac, 0x0, 0x0, 0x0, 0xc, 0x23, 0x0, - 0x7, 0xdc, 0xa3, 0x0, 0x2, 0x10, 0x0, 0x0, - 0x2, 0x40, - - /* U+5F97 "得" */ - 0x0, 0x0, 0x20, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x5, 0xd0, 0x85, 0x55, 0x5b, 0x0, 0x0, 0x2b, - 0x10, 0xb0, 0x0, 0x1a, 0x0, 0x1, 0x80, 0x42, - 0xb5, 0x55, 0x6a, 0x0, 0x4, 0x0, 0xd5, 0xb0, - 0x0, 0x1a, 0x0, 0x0, 0x8, 0x60, 0xc5, 0x55, - 0x6a, 0x0, 0x0, 0x4d, 0x3, 0x65, 0x55, 0x58, - 0x60, 0x3, 0x6c, 0x0, 0x10, 0x0, 0xc0, 0x0, - 0x3, 0xc, 0x16, 0x55, 0x55, 0xd5, 0xc1, 0x0, - 0xc, 0x0, 0x51, 0x0, 0xc0, 0x0, 0x0, 0xc, - 0x0, 0x2c, 0x0, 0xc0, 0x0, 0x0, 0xc, 0x0, - 0x5, 0x0, 0xc0, 0x0, 0x0, 0xc, 0x0, 0x0, - 0x4a, 0xd0, 0x0, 0x0, 0x2, 0x0, 0x0, 0x1, - 0x10, 0x0, - - /* U+5F9E "從" */ - 0x0, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x8, 0xa0, 0x6b, 0x0, 0x5a, 0x0, 0x0, 0x2a, - 0x0, 0x85, 0x0, 0x94, 0x0, 0x0, 0x80, 0x10, - 0xa8, 0x30, 0xb7, 0x0, 0x5, 0x0, 0xe4, 0x61, - 0xd5, 0x33, 0xc0, 0x0, 0x8, 0x55, 0x0, 0x15, - 0x0, 0x40, 0x0, 0x4c, 0x0, 0x0, 0x9, 0x0, - 0x0, 0x3, 0x7c, 0x0, 0xa3, 0xc, 0x0, 0x0, - 0x13, 0xc, 0x0, 0xc0, 0xd, 0x59, 0x20, 0x0, - 0xc, 0x0, 0xc0, 0xc, 0x0, 0x0, 0x0, 0xc, - 0x1, 0xc7, 0xc, 0x0, 0x0, 0x0, 0xc, 0x6, - 0x21, 0xad, 0x30, 0x0, 0x0, 0xc, 0x24, 0x0, - 0x4, 0xae, 0xd4, 0x0, 0x1, 0x10, 0x0, 0x0, - 0x0, 0x10, - - /* U+5FA1 "御" */ - 0x0, 0x1, 0x0, 0x10, 0x0, 0x0, 0x0, 0x0, - 0xa, 0x50, 0xd0, 0x0, 0x0, 0x0, 0x0, 0x48, - 0x2, 0x80, 0x40, 0x63, 0x71, 0x2, 0x70, 0x37, - 0x6b, 0x52, 0xc1, 0xb0, 0x4, 0x5, 0xa6, 0xa, - 0x0, 0xb0, 0xa0, 0x0, 0xb, 0x15, 0x5b, 0x86, - 0xb0, 0xa0, 0x0, 0x99, 0x0, 0xa, 0x0, 0xb0, - 0xa0, 0x4, 0x49, 0xa, 0x1a, 0x31, 0xb0, 0xa0, - 0x2, 0x19, 0xa, 0xb, 0x53, 0xb0, 0xa0, 0x0, - 0x19, 0xa, 0xa, 0x0, 0xb0, 0xa0, 0x0, 0x19, - 0xa, 0x1c, 0x52, 0xb6, 0xb0, 0x0, 0x19, 0x4d, - 0x82, 0x0, 0xb0, 0x10, 0x0, 0x29, 0x1, 0x0, - 0x0, 0xb0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x10, 0x0, - - /* U+5FA9 "復" */ - 0x0, 0x0, 0x10, 0x3, 0x0, 0x0, 0x0, 0x0, - 0x7, 0xc0, 0xd, 0x20, 0x0, 0x0, 0x0, 0x1b, - 0x0, 0x6a, 0x55, 0x57, 0x90, 0x0, 0x91, 0x1, - 0x72, 0x0, 0x3, 0x10, 0x6, 0x0, 0x94, 0xd, - 0x55, 0x5b, 0x40, 0x0, 0x7, 0x80, 0xc, 0x55, - 0x5b, 0x20, 0x0, 0x3c, 0x0, 0xb, 0x0, 0x9, - 0x20, 0x1, 0x8b, 0x0, 0xa, 0xc5, 0x58, 0x10, - 0x4, 0xb, 0x0, 0x8, 0x85, 0x5a, 0x10, 0x0, - 0xb, 0x0, 0x45, 0x50, 0x6a, 0x0, 0x0, 0xb, - 0x3, 0x30, 0x38, 0xb0, 0x0, 0x0, 0xb, 0x0, - 0x0, 0x5c, 0x80, 0x0, 0x0, 0xb, 0x0, 0x47, - 0x30, 0x6d, 0xa2, 0x0, 0x1, 0x2, 0x0, 0x0, - 0x0, 0x20, - - /* U+5FC3 "心" */ - 0x0, 0x0, 0x0, 0x50, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x7a, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x40, 0xe, 0x60, 0x0, 0x0, 0x0, 0x0, 0xc4, - 0x5, 0x20, 0x0, 0x0, 0x0, 0x30, 0xb1, 0x0, - 0x0, 0x21, 0x0, 0x0, 0x80, 0xb1, 0x0, 0x0, - 0xb, 0x10, 0x3, 0xa0, 0xb1, 0x0, 0x0, 0x6, - 0xb0, 0xd, 0x70, 0xb1, 0x0, 0x0, 0x42, 0xd0, - 0x4, 0x0, 0xb1, 0x0, 0x0, 0x60, 0x10, 0x0, - 0x0, 0xb2, 0x0, 0x3, 0x90, 0x0, 0x0, 0x0, - 0x7d, 0xaa, 0xad, 0xc0, 0x0, 0x0, 0x0, 0x0, - 0x11, 0x10, 0x0, 0x0, - - /* U+5FC5 "必" */ - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x53, 0x0, 0x26, 0x0, 0x0, 0x0, 0x0, - 0xb5, 0x7, 0x80, 0x0, 0x0, 0xc, 0x23, 0xb0, - 0xc1, 0x0, 0x0, 0x0, 0xc0, 0x0, 0x49, 0x0, - 0x0, 0x5, 0xc, 0x0, 0xb, 0x13, 0x20, 0x0, - 0x80, 0xc0, 0x4, 0x80, 0xa, 0x10, 0x67, 0xc, - 0x0, 0xb1, 0x0, 0x6a, 0xa, 0x20, 0xc0, 0x93, - 0x0, 0x21, 0x70, 0x0, 0xc, 0x76, 0x0, 0x6, - 0x0, 0x0, 0x0, 0xd5, 0x0, 0x1, 0xb0, 0x0, - 0x16, 0x79, 0xdc, 0xcc, 0xdb, 0x0, 0x13, 0x0, - 0x0, 0x0, 0x0, 0x0, 0x0, - - /* U+5FD8 "忘" */ - 0x0, 0x0, 0x0, 0x10, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x95, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x2d, 0x0, 0x4, 0x70, 0x6, 0x55, 0xd5, - 0x55, 0x55, 0x55, 0x50, 0x0, 0x0, 0xc0, 0x0, - 0x0, 0x0, 0x0, 0x0, 0x0, 0xc0, 0x0, 0x0, - 0x0, 0x0, 0x0, 0x2, 0xd5, 0x55, 0x55, 0x7c, - 0x0, 0x0, 0x0, 0x50, 0x40, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x30, 0x2d, 0x10, 0x0, 0x0, 0x0, - 0x40, 0x95, 0x9, 0x20, 0x19, 0x10, 0x0, 0xa0, - 0x83, 0x0, 0x0, 0x45, 0xc0, 0x6, 0xc0, 0x83, - 0x0, 0x0, 0x90, 0x70, 0x1, 0x0, 0x5c, 0xaa, - 0xab, 0xb0, 0x0, - - /* U+5FD9 "忙" */ - 0x0, 0x20, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x95, 0x0, 0x2, 0x90, 0x0, 0x0, 0x0, 0x92, - 0x0, 0x0, 0x97, 0x0, 0x0, 0x0, 0x93, 0x0, - 0x0, 0x22, 0x2, 0x60, 0x2, 0x9a, 0x85, 0xd5, - 0x55, 0x55, 0x50, 0x9, 0x93, 0xa0, 0xc0, 0x0, - 0x0, 0x0, 0x4a, 0x92, 0x0, 0xc0, 0x0, 0x0, - 0x0, 0x21, 0x92, 0x0, 0xc0, 0x0, 0x0, 0x0, - 0x0, 0x92, 0x0, 0xc0, 0x0, 0x0, 0x0, 0x0, - 0x92, 0x0, 0xc0, 0x0, 0x0, 0x0, 0x0, 0x92, - 0x0, 0xc0, 0x0, 0x0, 0x0, 0x0, 0x93, 0x0, - 0xc0, 0x0, 0x4, 0x20, 0x0, 0xa3, 0x1, 0x85, - 0x55, 0x55, 0x40, 0x0, 0x20, 0x0, 0x0, 0x0, - 0x0, 0x0, - - /* U+5FEB "快" */ - 0x0, 0x13, 0x0, 0x0, 0x40, 0x0, 0x0, 0x0, - 0x2c, 0x0, 0x0, 0xe0, 0x0, 0x0, 0x0, 0x1a, - 0x0, 0x0, 0xc0, 0x1, 0x0, 0x0, 0x1c, 0x3, - 0x55, 0xd5, 0x5e, 0x10, 0x1, 0x3b, 0xb3, 0x0, - 0xc0, 0xc, 0x0, 0x7, 0x4a, 0x35, 0x0, 0xc0, - 0xc, 0x0, 0xd, 0x2a, 0x0, 0x0, 0xb0, 0xc, - 0x20, 0x0, 0x1a, 0x26, 0x56, 0xc6, 0x59, 0x94, - 0x0, 0x1a, 0x0, 0x6, 0x66, 0x0, 0x0, 0x0, - 0x1a, 0x0, 0xb, 0x16, 0x20, 0x0, 0x0, 0x1a, - 0x0, 0x47, 0x0, 0xa0, 0x0, 0x0, 0x1a, 0x2, - 0x90, 0x0, 0x5b, 0x10, 0x0, 0x2b, 0x37, 0x0, - 0x0, 0x7, 0xe4, 0x0, 0x1, 0x10, 0x0, 0x0, - 0x0, 0x10, - - /* U+5FF5 "念" */ - 0x0, 0x0, 0x0, 0x30, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x1, 0xe6, 0x0, 0x0, 0x0, 0x0, 0x0, - 0xc, 0x45, 0x30, 0x0, 0x0, 0x0, 0x0, 0xa5, - 0x50, 0x67, 0x0, 0x0, 0x0, 0xa, 0x30, 0x77, - 0x4, 0xd8, 0x41, 0x4, 0x71, 0x0, 0x13, 0x3, - 0x7, 0x80, 0x12, 0x4, 0x65, 0x55, 0x7e, 0x20, - 0x0, 0x0, 0x0, 0x0, 0x0, 0xa4, 0x0, 0x0, - 0x0, 0x0, 0x42, 0x93, 0x90, 0x0, 0x0, 0x0, - 0x40, 0xd2, 0x96, 0x0, 0x23, 0x0, 0x0, 0xb0, - 0xc0, 0x10, 0x4, 0xb, 0x40, 0x7, 0x80, 0xc0, - 0x0, 0x8, 0x24, 0x60, 0x0, 0x0, 0xac, 0xaa, - 0xad, 0x50, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, - - /* U+600E "怎" */ - 0x0, 0x0, 0x30, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0xc3, 0x0, 0x0, 0x0, 0x0, 0x0, 0x5, - 0xb5, 0x55, 0x55, 0x6c, 0x10, 0x0, 0x1a, 0xc, - 0x0, 0x0, 0x0, 0x0, 0x0, 0x81, 0xc, 0x55, - 0x56, 0xb0, 0x0, 0x5, 0x10, 0xc, 0x0, 0x0, - 0x0, 0x0, 0x0, 0x0, 0xc, 0x55, 0x55, 0xb7, - 0x0, 0x0, 0x0, 0xc, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x7, 0x30, 0x0, 0x0, 0x0, 0x0, - 0x30, 0xc1, 0x1d, 0x0, 0x17, 0x0, 0x0, 0x90, - 0xc0, 0x6, 0x0, 0x36, 0xb0, 0x9, 0x70, 0xc0, - 0x0, 0x1, 0x60, 0xa0, 0x4, 0x0, 0x8b, 0xaa, - 0xac, 0x90, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, - - /* U+6012 "怒" */ - 0x0, 0x2, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x8, 0x60, 0x1, 0x11, 0x15, 0x0, 0x5, 0x5d, - 0x57, 0x67, 0x44, 0x7c, 0x0, 0x0, 0x28, 0x9, - 0x31, 0x50, 0xa3, 0x0, 0x0, 0x92, 0xb, 0x0, - 0x76, 0x90, 0x0, 0x0, 0x26, 0xc9, 0x0, 0x4f, - 0x40, 0x0, 0x0, 0x7, 0x58, 0x55, 0x71, 0xb9, - 0x30, 0x4, 0x61, 0x3, 0x52, 0x0, 0x6, 0x80, - 0x10, 0x0, 0x10, 0x55, 0x0, 0x10, 0x0, 0x0, - 0x40, 0xb2, 0xd, 0x30, 0x39, 0x0, 0x0, 0xa0, - 0xb1, 0x4, 0x2, 0x8, 0x90, 0x7, 0x70, 0xb1, - 0x0, 0x6, 0x20, 0x40, 0x0, 0x0, 0x8c, 0xbb, - 0xbd, 0x50, 0x0, - - /* U+6015 "怕" */ - 0x0, 0x3, 0x0, 0x0, 0x21, 0x0, 0x0, 0x0, - 0xd1, 0x0, 0x7, 0x70, 0x0, 0x0, 0xc, 0x0, - 0x0, 0x80, 0x0, 0x0, 0x0, 0xc0, 0x9, 0x57, - 0x55, 0xc2, 0x1, 0x2c, 0xa2, 0xc0, 0x0, 0xc, - 0x0, 0x64, 0xc3, 0x3c, 0x0, 0x0, 0xc0, 0xd, - 0x2c, 0x0, 0xc0, 0x0, 0xc, 0x0, 0x0, 0xc0, - 0xc, 0x55, 0x55, 0xd0, 0x0, 0xc, 0x0, 0xc0, - 0x0, 0xc, 0x0, 0x0, 0xc0, 0xc, 0x0, 0x0, - 0xc0, 0x0, 0xc, 0x0, 0xc0, 0x0, 0xc, 0x0, - 0x0, 0xc0, 0xc, 0x55, 0x55, 0xd0, 0x0, 0xd, - 0x0, 0xc0, 0x0, 0xb, 0x0, 0x0, 0x20, 0x1, - 0x0, 0x0, 0x0, - - /* U+601D "思" */ - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0xb, 0x55, 0x58, 0x55, 0x5d, 0x0, 0x0, 0xc, - 0x0, 0xc, 0x0, 0xc, 0x0, 0x0, 0xc, 0x0, - 0xc, 0x0, 0xc, 0x0, 0x0, 0xd, 0x55, 0x5d, - 0x55, 0x5c, 0x0, 0x0, 0xc, 0x0, 0xc, 0x0, - 0xc, 0x0, 0x0, 0xc, 0x0, 0xc, 0x0, 0xc, - 0x0, 0x0, 0xd, 0x55, 0x65, 0x55, 0x5b, 0x0, - 0x0, 0x1, 0x30, 0x69, 0x0, 0x0, 0x0, 0x0, - 0x60, 0x95, 0xb, 0x20, 0x33, 0x91, 0x1, 0xb0, - 0x93, 0x0, 0x0, 0xc3, 0x6b, 0x8, 0x80, 0x94, - 0x0, 0x0, 0xe6, 0x6, 0x0, 0x0, 0x6d, 0xbb, - 0xbc, 0xe5, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, - - /* U+6025 "急" */ - 0x0, 0x0, 0x5, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x5b, 0x10, 0x12, 0x0, 0x0, 0x0, 0x1, - 0xb5, 0x55, 0xba, 0x0, 0x0, 0x0, 0x8, 0x0, - 0x2, 0x70, 0x2, 0x0, 0x0, 0x76, 0x55, 0x56, - 0x55, 0x8c, 0x0, 0x3, 0x0, 0x0, 0x0, 0x0, - 0x49, 0x0, 0x0, 0x2, 0x65, 0x55, 0x55, 0x79, - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x49, 0x0, - 0x0, 0x6, 0x55, 0x96, 0x55, 0x77, 0x0, 0x0, - 0x10, 0xb2, 0x1d, 0x11, 0x14, 0x0, 0x0, 0x80, - 0xc0, 0x3, 0x5, 0x7, 0x90, 0x5, 0xb0, 0xc0, - 0x0, 0x7, 0x20, 0x90, 0x2, 0x10, 0x9b, 0xaa, - 0xad, 0x50, 0x0, - - /* U+6027 "性" */ - 0x0, 0x13, 0x0, 0x0, 0x2, 0x0, 0x0, 0x0, - 0x1c, 0x0, 0x0, 0xe, 0x10, 0x0, 0x0, 0x1a, - 0x0, 0x77, 0xc, 0x0, 0x0, 0x0, 0x1c, 0x40, - 0xa3, 0xc, 0x0, 0x10, 0x2, 0x4a, 0xa3, 0xd5, - 0x5d, 0x57, 0xa0, 0x7, 0x5a, 0x14, 0x60, 0xc, - 0x0, 0x0, 0xa, 0x2a, 0x7, 0x0, 0xc, 0x0, - 0x0, 0x0, 0x1a, 0x2, 0x45, 0x5d, 0x59, 0x70, - 0x0, 0x1a, 0x0, 0x10, 0xc, 0x0, 0x0, 0x0, - 0x1a, 0x0, 0x0, 0xc, 0x0, 0x0, 0x0, 0x1a, - 0x0, 0x0, 0xc, 0x0, 0x0, 0x0, 0x1a, 0x0, - 0x0, 0xc, 0x0, 0x71, 0x0, 0x2b, 0x7, 0x55, - 0x55, 0x55, 0x53, 0x0, 0x1, 0x0, 0x0, 0x0, - 0x0, 0x0, - - /* U+606F "息" */ - 0x0, 0x0, 0x0, 0x50, 0x0, 0x0, 0x0, 0x0, - 0x20, 0x37, 0x0, 0x5, 0x0, 0x0, 0xd, 0x55, - 0x55, 0x55, 0xe0, 0x0, 0x0, 0xd0, 0x0, 0x0, - 0xc, 0x0, 0x0, 0xd, 0x55, 0x55, 0x55, 0xc0, - 0x0, 0x0, 0xd5, 0x55, 0x55, 0x5c, 0x0, 0x0, - 0xd, 0x0, 0x0, 0x0, 0xc0, 0x0, 0x0, 0xd5, - 0x55, 0x55, 0x5d, 0x0, 0x0, 0x5, 0x0, 0x83, - 0x0, 0x30, 0x0, 0x2, 0xc, 0x22, 0xf0, 0x0, - 0x40, 0x0, 0x90, 0xd0, 0x3, 0x3, 0x17, 0x80, - 0xa8, 0xd, 0x0, 0x0, 0x54, 0x1c, 0x4, 0x0, - 0x9b, 0xaa, 0xac, 0x60, 0x0, - - /* U+60A8 "您" */ - 0x0, 0x2, 0x10, 0x11, 0x0, 0x0, 0x0, 0x0, - 0x96, 0x8, 0x90, 0x0, 0x0, 0x0, 0x1c, 0x0, - 0xd5, 0x55, 0x59, 0x30, 0x9, 0xa0, 0x62, 0x3, - 0x0, 0xa2, 0x4, 0x6a, 0x23, 0x20, 0xc1, 0x20, - 0x0, 0x41, 0xa0, 0x1d, 0x1c, 0x7, 0x10, 0x0, - 0x1a, 0x8, 0x20, 0xc0, 0x2d, 0x10, 0x1, 0xa3, - 0x14, 0x8e, 0x0, 0x61, 0x0, 0x15, 0x0, 0x44, - 0x40, 0x0, 0x0, 0x1, 0x18, 0x55, 0x90, 0x2, - 0x40, 0x0, 0x81, 0x73, 0x7, 0x0, 0x48, 0x70, - 0x4e, 0x7, 0x30, 0x0, 0x28, 0x9, 0x1, 0x10, - 0x4b, 0x99, 0x9b, 0x80, 0x0, - - /* U+60AA "悪" */ - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x36, - 0x55, 0x65, 0x56, 0x58, 0xa0, 0x0, 0x0, 0xc, - 0x0, 0xc0, 0x0, 0x0, 0x8, 0x65, 0xd5, 0x5d, - 0x5c, 0x30, 0x0, 0x92, 0xc, 0x0, 0xc0, 0xb0, - 0x0, 0x9, 0x75, 0xd5, 0x5d, 0x5c, 0x10, 0x0, - 0x30, 0xc, 0x0, 0xc0, 0x24, 0x0, 0x55, 0x55, - 0x95, 0x59, 0x56, 0xa3, 0x0, 0x0, 0x20, 0x64, - 0x0, 0x0, 0x0, 0x3, 0x1d, 0x0, 0xc3, 0x1, - 0x70, 0x0, 0x91, 0xb0, 0x2, 0x4, 0x7, 0x70, - 0xb8, 0x1b, 0x0, 0x0, 0x63, 0x17, 0x3, 0x0, - 0xdb, 0xbb, 0xbd, 0x60, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x0, - - /* U+60B2 "悲" */ - 0x0, 0x0, 0x3, 0x0, 0x40, 0x0, 0x0, 0x0, - 0x0, 0xd, 0x0, 0xd0, 0x0, 0x0, 0x3, 0x55, - 0x5c, 0x0, 0xd5, 0x57, 0x50, 0x0, 0x0, 0xc, - 0x0, 0xc0, 0x2, 0x0, 0x0, 0x55, 0x5c, 0x0, - 0xd5, 0x57, 0x0, 0x0, 0x0, 0xc, 0x0, 0xc0, - 0x0, 0x10, 0x5, 0x55, 0x5c, 0x0, 0xd5, 0x57, - 0x70, 0x0, 0x0, 0xd, 0x0, 0xc0, 0x0, 0x0, - 0x0, 0x0, 0x21, 0x46, 0x0, 0x11, 0x0, 0x0, - 0x40, 0xd1, 0xb, 0x30, 0x9, 0x40, 0x2, 0x80, - 0xc0, 0x2, 0x0, 0x41, 0xb0, 0xc, 0x40, 0xc0, - 0x0, 0x1, 0x80, 0x10, 0x0, 0x0, 0xbb, 0xaa, - 0xac, 0x90, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, - - /* U+60C5 "情" */ - 0x0, 0x20, 0x0, 0x0, 0x30, 0x0, 0x0, 0xa, - 0x40, 0x0, 0xd, 0x0, 0x0, 0x0, 0xa2, 0x26, - 0x55, 0xd5, 0x6a, 0x0, 0x1a, 0x93, 0x0, 0xc, - 0x3, 0x0, 0x7, 0xa4, 0x74, 0x65, 0xd5, 0x63, - 0x4, 0x9a, 0x24, 0x55, 0x5d, 0x55, 0x86, 0x21, - 0xa2, 0x12, 0x0, 0x0, 0x20, 0x0, 0xa, 0x20, - 0xa5, 0x55, 0x5c, 0x30, 0x0, 0xa2, 0xa, 0x65, - 0x55, 0xc1, 0x0, 0xa, 0x20, 0xa1, 0x0, 0xa, - 0x10, 0x0, 0xa2, 0xa, 0x65, 0x55, 0xc1, 0x0, - 0xa, 0x20, 0xa1, 0x0, 0xa, 0x10, 0x0, 0xa2, - 0xa, 0x10, 0x28, 0xe0, 0x0, 0x2, 0x0, 0x20, - 0x0, 0x2, 0x0, - - /* U+60F3 "想" */ - 0x0, 0x4, 0x20, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x9, 0x30, 0x8, 0x55, 0x59, 0x10, 0x0, 0x8, - 0x24, 0xb, 0x0, 0xb, 0x0, 0x6, 0x5c, 0x78, - 0x2c, 0x55, 0x5c, 0x0, 0x0, 0x1f, 0x70, 0xb, - 0x0, 0xb, 0x0, 0x0, 0x8c, 0x6c, 0xc, 0x55, - 0x5c, 0x0, 0x2, 0x78, 0x25, 0xb, 0x0, 0xb, - 0x0, 0x6, 0x9, 0x20, 0xd, 0x55, 0x5c, 0x0, - 0x10, 0x7, 0x20, 0x46, 0x0, 0x4, 0x0, 0x0, - 0x0, 0x71, 0x2d, 0x0, 0x2, 0x0, 0x0, 0x70, - 0xb0, 0x7, 0x14, 0x7, 0x60, 0x4, 0xa0, 0xb0, - 0x0, 0x6, 0x10, 0xc0, 0x4, 0x20, 0x8a, 0x99, - 0x9c, 0x40, 0x0, - - /* U+6108 "愈" */ - 0x0, 0x0, 0x0, 0x20, 0x0, 0x0, 0x0, 0x0, - 0x0, 0xab, 0x0, 0x0, 0x0, 0x0, 0x0, 0xa5, - 0x17, 0x0, 0x0, 0x0, 0x3, 0x93, 0x11, 0x7b, - 0x61, 0x0, 0x35, 0x52, 0x36, 0x33, 0x17, 0xda, - 0x10, 0xc, 0x55, 0xb0, 0x80, 0xc0, 0x0, 0x0, - 0xb4, 0x4a, 0x9, 0xa, 0x0, 0x0, 0xc, 0x55, - 0xa0, 0xa0, 0xa0, 0x0, 0x0, 0xa0, 0x69, 0x3, - 0x2b, 0x0, 0x0, 0x5, 0x23, 0x84, 0x5, 0x60, - 0x0, 0x1, 0x18, 0x40, 0xc0, 0x0, 0x70, 0x0, - 0xa1, 0x83, 0x0, 0x2, 0x15, 0xa0, 0x27, 0x5, - 0xb9, 0x99, 0xb6, 0x2, 0x0, - - /* U+610F "意" */ - 0x0, 0x0, 0x0, 0x30, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x75, 0x0, 0x30, 0x0, 0x0, 0x25, - 0x76, 0x66, 0x97, 0x80, 0x0, 0x0, 0x0, 0xc, - 0x0, 0xa1, 0x1, 0x0, 0x6, 0x55, 0x57, 0x56, - 0x65, 0x59, 0x80, 0x0, 0x7, 0x55, 0x55, 0x55, - 0x70, 0x0, 0x0, 0xb, 0x0, 0x0, 0x2, 0x90, - 0x0, 0x0, 0xc, 0x55, 0x55, 0x56, 0x90, 0x0, - 0x0, 0xc, 0x55, 0x55, 0x56, 0x90, 0x0, 0x0, - 0x5, 0x20, 0x71, 0x1, 0x30, 0x0, 0x0, 0x50, - 0xc0, 0x3a, 0x1, 0x39, 0x10, 0x2, 0xa0, 0xb0, - 0x1, 0x6, 0x6, 0x90, 0x8, 0x40, 0xaa, 0x99, - 0x9d, 0x10, 0x10, - - /* U+611A "愚" */ - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xc5, - 0x58, 0x55, 0x5c, 0x0, 0x0, 0xc0, 0x9, 0x10, - 0xb, 0x0, 0x0, 0xd5, 0x5b, 0x65, 0x5b, 0x0, - 0x0, 0xd5, 0x5b, 0x65, 0x5c, 0x0, 0x3, 0x30, - 0x9, 0x10, 0x1, 0x50, 0xd, 0x55, 0x5b, 0x67, - 0x55, 0xc1, 0xc, 0x1, 0x2a, 0x57, 0xb0, 0xb0, - 0xc, 0xb, 0x74, 0x10, 0x60, 0xb0, 0xb, 0x1, - 0x1a, 0x20, 0x29, 0xb0, 0x3, 0xc, 0x4, 0x80, - 0x23, 0x60, 0x1a, 0xb, 0x0, 0x0, 0x60, 0x97, - 0x74, 0x9, 0xa9, 0x99, 0xc4, 0x13, - - /* U+611B "愛" */ - 0x0, 0x0, 0x0, 0x0, 0x4, 0x0, 0x1, 0x24, - 0x57, 0x8a, 0xcc, 0x50, 0x1, 0x43, 0x7, 0x10, - 0x86, 0x0, 0x2, 0xb, 0x2, 0x60, 0x70, 0x12, - 0x2a, 0x56, 0x5a, 0x75, 0x55, 0xb7, 0xa4, 0x5a, - 0x31, 0xd1, 0x13, 0x80, 0x8, 0x59, 0x30, 0x10, - 0x64, 0x4c, 0x6, 0x4, 0xaa, 0xaa, 0x92, 0x2, - 0x0, 0xa, 0x50, 0x0, 0x10, 0x0, 0x0, 0x5a, - 0x85, 0x59, 0xc0, 0x0, 0x4, 0x50, 0x64, 0x5a, - 0x10, 0x0, 0x1, 0x0, 0x2d, 0xe2, 0x0, 0x0, - 0x2, 0x57, 0x61, 0x3a, 0xdb, 0x93, 0x12, 0x0, - 0x0, 0x0, 0x3, 0x30, - - /* U+611F "感" */ - 0x0, 0x0, 0x0, 0x0, 0x41, 0x10, 0x0, 0x0, - 0x0, 0x0, 0x0, 0xb0, 0xa2, 0x0, 0x0, 0x95, - 0x55, 0x55, 0xc5, 0x67, 0xb0, 0x0, 0xb0, 0x0, - 0x2, 0x91, 0x3, 0x0, 0x0, 0xb3, 0x55, 0x56, - 0x73, 0x2d, 0x10, 0x0, 0xb0, 0x85, 0x58, 0x48, - 0xb3, 0x0, 0x0, 0xb0, 0xb0, 0x1a, 0xe, 0x70, - 0x10, 0x3, 0x70, 0xd5, 0x6a, 0x4a, 0xa0, 0x50, - 0x8, 0x0, 0x60, 0x7, 0x40, 0x5c, 0xb0, 0x22, - 0x0, 0x50, 0x75, 0x0, 0x32, 0x82, 0x0, 0x70, - 0xd0, 0xc, 0x2, 0xc, 0x20, 0x7, 0x80, 0xb0, - 0x0, 0x7, 0x6, 0x40, 0x5, 0x10, 0xb9, 0x99, - 0x9c, 0x20, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, - - /* U+614B "態" */ - 0x0, 0x22, 0x0, 0x0, 0x0, 0x0, 0x0, 0x1b, - 0x51, 0x1, 0xb0, 0x4, 0x0, 0x47, 0x10, 0x47, - 0x1b, 0x58, 0x61, 0x8, 0xa8, 0x54, 0x91, 0xa0, - 0x0, 0x70, 0xa, 0x55, 0x96, 0xb, 0x99, 0xa8, - 0x0, 0xc5, 0x59, 0x51, 0xc0, 0x16, 0x0, 0xb, - 0x0, 0x75, 0x1b, 0x69, 0x61, 0x0, 0xc4, 0x49, - 0x51, 0xb0, 0x0, 0x60, 0xc, 0x6, 0xc4, 0xc, - 0xaa, 0xb8, 0x0, 0x20, 0x55, 0x2a, 0x10, 0x3, - 0x0, 0x6, 0xc, 0x10, 0x47, 0x4, 0x58, 0x4, - 0xb0, 0xc0, 0x0, 0x0, 0x70, 0xc0, 0x42, 0xa, - 0xba, 0xaa, 0xc9, 0x0, 0x0, - - /* U+6163 "慣" */ - 0x0, 0x10, 0x0, 0x0, 0x0, 0x1, 0x0, 0x0, - 0xb2, 0x0, 0xc5, 0x87, 0x5c, 0x0, 0x0, 0xb0, - 0x0, 0xb0, 0x92, 0x1a, 0x50, 0x2, 0xb6, 0x56, - 0xb5, 0xd5, 0x8a, 0x50, 0x7, 0xb6, 0x55, 0xa5, - 0xd5, 0x97, 0x0, 0x49, 0xb2, 0x21, 0x10, 0x0, - 0x22, 0x0, 0x31, 0xb0, 0xa, 0x55, 0x55, 0x5c, - 0x0, 0x0, 0xb0, 0xb, 0x44, 0x44, 0x4b, 0x0, - 0x0, 0xb0, 0xb, 0x11, 0x11, 0x1b, 0x0, 0x0, - 0xb0, 0xb, 0x55, 0x55, 0x5b, 0x0, 0x0, 0xb0, - 0xc, 0x55, 0x55, 0x5b, 0x0, 0x0, 0xb0, 0x3, - 0xc4, 0x1, 0x84, 0x0, 0x0, 0xb0, 0x38, 0x20, - 0x0, 0x1d, 0x30, 0x0, 0x10, 0x20, 0x0, 0x0, - 0x1, 0x10, - - /* U+6167 "慧" */ - 0x0, 0x3, 0x0, 0x0, 0x30, 0x0, 0x0, 0x0, - 0xc1, 0x40, 0xc, 0x3, 0x20, 0x36, 0x5c, 0x55, - 0x46, 0xc5, 0x53, 0x0, 0x65, 0xc6, 0x53, 0x6c, - 0x59, 0x10, 0x45, 0x5c, 0x59, 0x35, 0xc5, 0x59, - 0x1, 0x0, 0xa0, 0x0, 0x1a, 0x0, 0x0, 0x3, - 0x65, 0x55, 0x55, 0x59, 0x70, 0x0, 0x5, 0x55, - 0x55, 0x55, 0x95, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x6, 0x50, 0x0, 0x27, 0x65, 0x95, 0x55, 0x83, - 0x0, 0x4, 0xa, 0x35, 0x90, 0x21, 0x70, 0x0, - 0xa0, 0xa2, 0x3, 0x7, 0x13, 0xb0, 0x33, 0x7, - 0xb9, 0x99, 0xc3, 0x3, 0x0, - - /* U+616E "慮" */ - 0x0, 0x0, 0x0, 0x2, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x2c, 0x11, 0x50, 0x0, 0x0, 0x10, - 0x0, 0x1b, 0x44, 0x42, 0x0, 0x0, 0xb6, 0x55, - 0x6a, 0x56, 0x5c, 0x50, 0x0, 0xa1, 0x24, 0x6b, - 0x58, 0x35, 0x0, 0x0, 0xb1, 0x30, 0x1a, 0x22, - 0x39, 0x0, 0x0, 0xb0, 0x20, 0x4, 0x66, 0xa3, - 0x0, 0x0, 0xb0, 0xc5, 0x5b, 0x65, 0xc2, 0x0, - 0x0, 0xb0, 0xb5, 0x5b, 0x65, 0xc0, 0x0, 0x0, - 0x90, 0xc5, 0x5a, 0x65, 0xc0, 0x0, 0x4, 0x40, - 0x28, 0x5, 0x60, 0x14, 0x0, 0x7, 0x4, 0x3d, - 0x0, 0x91, 0x42, 0xd0, 0x32, 0x3d, 0xb, 0xba, - 0xab, 0x80, 0x30, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, - - /* U+61C9 "應" */ - 0x0, 0x0, 0x0, 0x41, 0x0, 0x0, 0x0, 0x0, - 0x20, 0x0, 0x2b, 0x0, 0x1, 0x40, 0x0, 0xc5, - 0x56, 0x57, 0x76, 0x56, 0x70, 0x0, 0xc0, 0x2d, - 0x6b, 0x1b, 0x1, 0x0, 0x0, 0xc0, 0xb2, 0xc6, - 0x5a, 0x57, 0x40, 0x0, 0xc4, 0xc4, 0xc5, 0x5c, - 0x59, 0x0, 0x0, 0xc0, 0xb1, 0xa1, 0xa, 0x4, - 0x0, 0x0, 0xb0, 0xb0, 0xa5, 0x5c, 0x55, 0x10, - 0x0, 0xb0, 0xb0, 0xa5, 0x59, 0x56, 0x80, 0x3, - 0x80, 0x40, 0x41, 0x0, 0x1, 0x0, 0x7, 0x34, - 0x39, 0xa, 0x60, 0x24, 0x70, 0x8, 0x1b, 0x28, - 0x0, 0x60, 0x70, 0xc1, 0x23, 0x54, 0xc, 0xaa, - 0xab, 0xd1, 0x10, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, - - /* U+61F8 "懸" */ - 0x0, 0x0, 0x1, 0x0, 0x0, 0x0, 0x10, 0x0, - 0xa5, 0x5b, 0x33, 0x57, 0x9a, 0x70, 0x0, 0xb5, - 0x5b, 0x10, 0x19, 0x65, 0x10, 0x0, 0xa4, 0x4b, - 0x13, 0xd6, 0x9a, 0x30, 0x0, 0xa5, 0x5b, 0x10, - 0x5a, 0x32, 0x50, 0x0, 0xa0, 0x9, 0x55, 0xf9, - 0xa5, 0xb2, 0x6, 0x97, 0xa5, 0x54, 0x60, 0xb3, - 0x10, 0x2, 0xa4, 0x79, 0x24, 0xa1, 0xb3, 0xa0, - 0x5, 0x2a, 0x52, 0x65, 0x26, 0xa0, 0x81, 0x0, - 0x3, 0x50, 0x52, 0x6, 0x31, 0x0, 0x0, 0x51, - 0x90, 0x1d, 0x10, 0x8, 0x50, 0x4, 0xa1, 0x90, - 0x2, 0x0, 0x60, 0xc0, 0x7, 0x20, 0xca, 0xaa, - 0xac, 0xa0, 0x0, - - /* U+6210 "成" */ - 0x0, 0x0, 0x0, 0x1, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, 0xf, 0x15, 0x70, 0x0, 0x0, 0x0, - 0x0, 0xe, 0x0, 0xc3, 0x0, 0x0, 0x75, 0x55, - 0x5e, 0x55, 0x6b, 0x60, 0x0, 0xc1, 0x0, 0xb, - 0x10, 0x0, 0x0, 0x0, 0xc1, 0x0, 0x9, 0x30, - 0x38, 0x0, 0x0, 0xc5, 0x58, 0x46, 0x60, 0x97, - 0x0, 0x0, 0xc0, 0x9, 0x33, 0x90, 0xd0, 0x0, - 0x0, 0xc0, 0xa, 0x10, 0xd7, 0x70, 0x0, 0x0, - 0xb0, 0xb, 0x0, 0x8e, 0x0, 0x20, 0x2, 0x74, - 0x6c, 0x0, 0xbd, 0x50, 0x60, 0x7, 0x10, 0x75, - 0x19, 0x12, 0xd9, 0x90, 0x6, 0x0, 0x2, 0x50, - 0x0, 0x9, 0xd0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, - - /* U+6211 "我" */ - 0x0, 0x0, 0x0, 0x4, 0x0, 0x0, 0x0, 0x0, - 0x3, 0x8d, 0x6a, 0x51, 0x30, 0x0, 0x2, 0x43, - 0xc0, 0xa, 0x20, 0x99, 0x0, 0x0, 0x0, 0xc0, - 0x9, 0x20, 0x9, 0x0, 0x5, 0x55, 0xd5, 0x5b, - 0x75, 0x5a, 0x90, 0x1, 0x0, 0xc0, 0x7, 0x40, - 0x1, 0x0, 0x0, 0x0, 0xc0, 0x5, 0x60, 0x79, - 0x0, 0x0, 0x1, 0xe6, 0x33, 0x82, 0xb0, 0x0, - 0x18, 0xc8, 0xc0, 0x0, 0xcb, 0x10, 0x0, 0x6, - 0x10, 0xc0, 0x1, 0xe5, 0x0, 0x10, 0x0, 0x0, - 0xc0, 0x29, 0x4c, 0x10, 0x50, 0x0, 0x43, 0xc4, - 0x50, 0x2, 0xd6, 0x90, 0x0, 0x2d, 0x60, 0x0, - 0x0, 0x18, 0xe4, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, - - /* U+6216 "或" */ - 0x0, 0x0, 0x0, 0x0, 0x11, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x0, 0xe1, 0xb4, 0x0, 0x0, 0x0, - 0x0, 0x0, 0xd0, 0x15, 0x40, 0x6, 0x55, 0x55, - 0x55, 0xd5, 0x56, 0x70, 0x0, 0x0, 0x1, 0x0, - 0xc0, 0x1, 0x0, 0x0, 0xd5, 0x5c, 0x50, 0xc0, - 0xe, 0x10, 0x0, 0xc0, 0xa, 0x20, 0xa2, 0x4a, - 0x0, 0x0, 0xc0, 0xa, 0x20, 0x74, 0xa3, 0x0, - 0x0, 0xd5, 0x5c, 0x20, 0x3b, 0xb0, 0x0, 0x0, - 0x50, 0x0, 0x0, 0xf, 0x40, 0x10, 0x0, 0x35, - 0x77, 0x54, 0x98, 0xb0, 0x50, 0x1f, 0xa5, 0x10, - 0x28, 0x10, 0x7c, 0xa0, 0x0, 0x0, 0x5, 0x40, - 0x0, 0x5, 0xd2, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, - - /* U+6226 "戦" */ - 0x0, 0x2, 0x0, 0x10, 0x4, 0x0, 0x0, 0x8, - 0x18, 0x51, 0xb0, 0xe, 0x25, 0x0, 0x4, 0x81, - 0x66, 0x10, 0xc, 0x9, 0x50, 0x9, 0x55, 0x77, - 0xb0, 0xc, 0x1, 0x20, 0xb, 0x1, 0x90, 0xb0, - 0x2d, 0x55, 0x80, 0xb, 0x55, 0xb5, 0xb5, 0x3c, - 0x4, 0x20, 0xb, 0x1, 0x90, 0xb0, 0xc, 0xc, - 0x40, 0xb, 0x55, 0xb5, 0xb0, 0xc, 0x59, 0x0, - 0x7, 0x1, 0x90, 0x60, 0x9, 0xd1, 0x0, 0x0, - 0x1, 0x90, 0x43, 0x8, 0x90, 0x0, 0x27, 0x55, - 0xb5, 0x54, 0x4a, 0xd1, 0x51, 0x0, 0x1, 0x90, - 0x3, 0x90, 0x4d, 0xb0, 0x0, 0x1, 0xa0, 0x56, - 0x0, 0x6, 0xf1, 0x0, 0x0, 0x10, 0x10, 0x0, - 0x0, 0x31, - - /* U+6230 "戰" */ - 0x0, 0x0, 0x0, 0x0, 0x3, 0x0, 0x0, 0xa, - 0x5b, 0x57, 0xb2, 0xd, 0x34, 0x0, 0xa, 0xa, - 0x55, 0x91, 0xd, 0xa, 0x40, 0xb, 0x5b, 0x58, - 0xb1, 0xc, 0x1, 0x10, 0x5, 0x2, 0x21, 0x50, - 0xc, 0x46, 0x80, 0x7, 0x77, 0x95, 0xc3, 0x5c, - 0x3, 0x10, 0x7, 0x77, 0x95, 0xa0, 0xb, 0xb, - 0x40, 0x7, 0x33, 0x70, 0xa0, 0xa, 0x4a, 0x0, - 0x8, 0x77, 0x95, 0xa0, 0x7, 0xd2, 0x0, 0x3, - 0x3, 0x70, 0x20, 0x6, 0xb0, 0x0, 0x6, 0x57, - 0x95, 0x74, 0x2a, 0xb3, 0x60, 0x0, 0x3, 0x70, - 0x2, 0x80, 0x2d, 0xb0, 0x0, 0x4, 0x70, 0x34, - 0x0, 0x4, 0xf0, 0x0, 0x1, 0x0, 0x0, 0x0, - 0x0, 0x21, - - /* U+623B "戻" */ - 0x0, 0x0, 0x0, 0x40, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x5a, 0x0, 0x0, 0x0, 0x0, 0x8, - 0x55, 0x5a, 0x55, 0x5a, 0x0, 0x0, 0xd, 0x0, - 0x0, 0x0, 0xc, 0x0, 0x0, 0xd, 0x0, 0x0, - 0x0, 0xc, 0x0, 0x0, 0xe, 0x55, 0x55, 0x55, - 0x5c, 0x0, 0x0, 0x1c, 0x0, 0x8, 0x40, 0x4, - 0x0, 0x0, 0x3a, 0x0, 0xc, 0x20, 0x3, 0x0, - 0x0, 0x66, 0x65, 0x5d, 0x75, 0x58, 0x40, 0x0, - 0xa1, 0x0, 0x75, 0x43, 0x0, 0x0, 0x1, 0x90, - 0x3, 0xa0, 0x9, 0x30, 0x0, 0x7, 0x10, 0x38, - 0x0, 0x0, 0xb9, 0x20, 0x14, 0x15, 0x40, 0x0, - 0x0, 0x8, 0xc2, 0x0, 0x10, 0x0, 0x0, 0x0, - 0x0, 0x0, - - /* U+623F "房" */ - 0x0, 0x0, 0x0, 0x30, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x2b, 0x0, 0x0, 0x0, 0x0, 0x3a, - 0x55, 0x56, 0x55, 0x5d, 0x10, 0x0, 0x39, 0x0, - 0x0, 0x0, 0xc, 0x0, 0x0, 0x2b, 0x55, 0x55, - 0x55, 0x5d, 0x0, 0x0, 0x38, 0x0, 0x8, 0x30, - 0x1, 0x0, 0x0, 0x47, 0x0, 0x2, 0x70, 0x1, - 0x50, 0x0, 0x56, 0x55, 0x8b, 0x55, 0x55, 0x50, - 0x0, 0x82, 0x0, 0x68, 0x0, 0x5, 0x0, 0x0, - 0xa0, 0x0, 0xb7, 0x55, 0x5e, 0x10, 0x2, 0x70, - 0x2, 0xd0, 0x0, 0x1c, 0x0, 0x6, 0x10, 0x1c, - 0x20, 0x0, 0x3a, 0x0, 0x13, 0x2, 0x92, 0x0, - 0x17, 0xd5, 0x0, 0x0, 0x3, 0x0, 0x0, 0x0, - 0x40, 0x0, - - /* U+6240 "所" */ - 0x0, 0x0, 0x0, 0x0, 0x0, 0x1, 0x0, 0x0, - 0x21, 0x6b, 0x52, 0x4, 0x8c, 0x60, 0x0, 0xd4, - 0x0, 0xa, 0x61, 0x0, 0x0, 0x0, 0xd0, 0x0, - 0xa, 0x30, 0x0, 0x0, 0x0, 0xd5, 0x59, 0x29, - 0x30, 0x0, 0x20, 0x0, 0xc0, 0xc, 0x9, 0x75, - 0x96, 0x80, 0x0, 0xc0, 0xc, 0xa, 0x20, 0xb0, - 0x0, 0x0, 0xd5, 0x5d, 0xc, 0x0, 0xb0, 0x0, - 0x0, 0xc0, 0x8, 0xb, 0x0, 0xb0, 0x0, 0x0, - 0xb0, 0x0, 0x47, 0x0, 0xb0, 0x0, 0x4, 0x60, - 0x0, 0x91, 0x0, 0xb0, 0x0, 0x7, 0x0, 0x4, - 0x50, 0x0, 0xb0, 0x0, 0x15, 0x0, 0x15, 0x0, - 0x0, 0xb1, 0x0, 0x10, 0x0, 0x10, 0x0, 0x0, - 0x10, 0x0, - - /* U+624B "手" */ - 0x0, 0x0, 0x0, 0x0, 0x0, 0x10, 0x0, 0x0, - 0x0, 0x0, 0x25, 0x8c, 0xf3, 0x0, 0x2, 0x45, - 0x66, 0xd4, 0x20, 0x0, 0x0, 0x0, 0x0, 0x0, - 0xc1, 0x0, 0x0, 0x0, 0x0, 0x55, 0x55, 0xd5, - 0x55, 0xd5, 0x0, 0x0, 0x10, 0x0, 0xc1, 0x0, - 0x0, 0x0, 0x0, 0x0, 0x0, 0xc1, 0x0, 0x0, - 0x0, 0x25, 0x55, 0x55, 0xd5, 0x55, 0x5b, 0xa0, - 0x1, 0x0, 0x0, 0xc1, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, 0xc1, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0xc1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x22, - 0xd0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x4d, 0xc0, - 0x0, 0x0, 0x0, 0x0, 0x0, 0x1, 0x0, 0x0, - 0x0, 0x0, - - /* U+624D "才" */ - 0x0, 0x0, 0x0, 0x0, 0x30, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x0, 0xe1, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, 0xd0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0xd0, 0x0, 0x50, 0x5, 0x65, 0x55, 0x5c, - 0xd5, 0x56, 0x71, 0x0, 0x0, 0x0, 0x6a, 0xd0, - 0x0, 0x0, 0x0, 0x0, 0x1, 0xd1, 0xd0, 0x0, - 0x0, 0x0, 0x0, 0xb, 0x30, 0xd0, 0x0, 0x0, - 0x0, 0x0, 0x75, 0x0, 0xd0, 0x0, 0x0, 0x0, - 0x6, 0x50, 0x0, 0xd0, 0x0, 0x0, 0x0, 0x63, - 0x0, 0x0, 0xd0, 0x0, 0x0, 0x5, 0x10, 0x1, - 0x0, 0xc0, 0x0, 0x0, 0x0, 0x0, 0x1, 0x9f, - 0x80, 0x0, 0x0, 0x0, 0x0, 0x0, 0x4, 0x0, - 0x0, 0x0, - - /* U+6253 "打" */ - 0x0, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0xc, 0x10, 0x0, 0x0, 0x0, 0x0, 0x0, 0xc, - 0x0, 0x55, 0x57, 0x58, 0x90, 0x15, 0x5d, 0x5a, - 0x10, 0xd, 0x0, 0x0, 0x0, 0xc, 0x0, 0x0, - 0xd, 0x0, 0x0, 0x0, 0xc, 0x1, 0x0, 0xd, - 0x0, 0x0, 0x0, 0xc, 0x73, 0x0, 0xd, 0x0, - 0x0, 0x29, 0xbd, 0x0, 0x0, 0xd, 0x0, 0x0, - 0x5, 0xc, 0x0, 0x0, 0xd, 0x0, 0x0, 0x0, - 0xc, 0x0, 0x0, 0xd, 0x0, 0x0, 0x0, 0xc, - 0x0, 0x0, 0xd, 0x0, 0x0, 0x3, 0x2d, 0x0, - 0x3, 0x1d, 0x0, 0x0, 0x1, 0xbc, 0x0, 0x2, - 0xca, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x10, - 0x0, 0x0, - - /* U+6255 "払" */ - 0x0, 0x2, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0xb2, 0x0, 0x8, 0x50, 0x0, 0x0, 0xb, 0x0, - 0x0, 0xd3, 0x0, 0x1, 0x55, 0xd5, 0xa1, 0x1d, - 0x0, 0x0, 0x0, 0xb, 0x0, 0x5, 0x80, 0x0, - 0x0, 0x0, 0xb0, 0x11, 0x92, 0x0, 0x0, 0x0, - 0xc, 0x74, 0xb, 0x0, 0x0, 0x2, 0xab, 0xd0, - 0x3, 0x70, 0x4, 0x0, 0x5, 0xb, 0x0, 0x72, - 0x0, 0x43, 0x0, 0x0, 0xb0, 0x9, 0x0, 0x0, - 0xb0, 0x0, 0xb, 0x3, 0x60, 0x0, 0x8, 0x70, - 0x32, 0xd0, 0xcb, 0xa9, 0x76, 0x7c, 0x1, 0xbb, - 0x4, 0x40, 0x0, 0x2, 0xa0, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x0, - - /* U+627E "找" */ - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0xc, 0x20, 0x8, 0x61, 0x40, 0x0, 0x0, 0xc, - 0x0, 0x8, 0x40, 0x8a, 0x0, 0x0, 0xc, 0x4, - 0x8, 0x40, 0x5, 0x0, 0x16, 0x5d, 0x55, 0x19, - 0x64, 0x5b, 0x30, 0x0, 0xc, 0x3, 0x39, 0x40, - 0x0, 0x0, 0x0, 0xc, 0x64, 0x7, 0x50, 0x6a, - 0x0, 0x28, 0xae, 0x0, 0x5, 0x74, 0xc1, 0x0, - 0x16, 0xc, 0x0, 0x2, 0xdb, 0x0, 0x0, 0x0, - 0xc, 0x0, 0x5, 0xf2, 0x0, 0x30, 0x0, 0xc, - 0x0, 0x75, 0x2c, 0x10, 0x60, 0x3, 0x3d, 0x5, - 0x10, 0x4, 0xd8, 0x70, 0x1, 0xaa, 0x0, 0x0, - 0x0, 0x2b, 0xa0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, - - /* U+6280 "技" */ - 0x0, 0x3, 0x0, 0x0, 0x3, 0x0, 0x0, 0x0, - 0xd, 0x10, 0x0, 0xe, 0x0, 0x0, 0x0, 0xc, - 0x0, 0x0, 0xc, 0x0, 0x0, 0x15, 0x5d, 0x6a, - 0x35, 0x5d, 0x55, 0xb1, 0x0, 0xc, 0x0, 0x0, - 0xc, 0x0, 0x0, 0x0, 0xc, 0x0, 0x0, 0xc, - 0x0, 0x0, 0x0, 0xc, 0x75, 0x47, 0x59, 0x5d, - 0x30, 0x18, 0xbd, 0x0, 0x6, 0x0, 0x1b, 0x0, - 0x6, 0xc, 0x0, 0x3, 0x40, 0x84, 0x0, 0x0, - 0xc, 0x0, 0x0, 0x94, 0xb0, 0x0, 0x0, 0xc, - 0x0, 0x0, 0x5f, 0x20, 0x0, 0x1, 0xc, 0x0, - 0x7, 0x95, 0xc4, 0x0, 0x3, 0xcc, 0x15, 0x72, - 0x0, 0x2a, 0xd3, 0x0, 0x10, 0x20, 0x0, 0x0, - 0x0, 0x0, - - /* U+628A "把" */ - 0x0, 0x4, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0xd, 0x10, 0x10, 0x0, 0x2, 0x0, 0x0, 0xc, - 0x0, 0xd5, 0x5b, 0x5d, 0x30, 0x15, 0x5d, 0x77, - 0xc0, 0xb, 0xb, 0x0, 0x0, 0xc, 0x0, 0xc0, - 0xb, 0xb, 0x0, 0x0, 0xc, 0x0, 0xc0, 0xb, - 0xb, 0x0, 0x0, 0xd, 0x73, 0xd5, 0x57, 0x5c, - 0x10, 0x2a, 0xbd, 0x0, 0xc0, 0x0, 0x0, 0x0, - 0x5, 0xc, 0x0, 0xc0, 0x0, 0x0, 0x0, 0x0, - 0xc, 0x0, 0xc0, 0x0, 0x0, 0x10, 0x0, 0xc, - 0x0, 0xc0, 0x0, 0x0, 0x50, 0x0, 0xc, 0x0, - 0xc0, 0x0, 0x0, 0xa0, 0x5, 0xbb, 0x0, 0xab, - 0xaa, 0xab, 0xd0, 0x0, 0x21, 0x0, 0x0, 0x0, - 0x0, 0x0, - - /* U+6295 "投" */ - 0x0, 0x3, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0xe, 0x10, 0x9, 0x55, 0xa1, 0x0, 0x0, 0xc, - 0x0, 0xb, 0x0, 0xc0, 0x0, 0x5, 0x5d, 0x78, - 0x2a, 0x0, 0xc0, 0x0, 0x0, 0xc, 0x0, 0x55, - 0x0, 0xc0, 0x0, 0x0, 0xc, 0x1, 0x90, 0x0, - 0x8a, 0xb3, 0x0, 0xd, 0x67, 0x65, 0x55, 0x87, - 0x0, 0x18, 0xbc, 0x0, 0x5, 0x0, 0xa3, 0x0, - 0x6, 0xc, 0x0, 0x6, 0x11, 0xb0, 0x0, 0x0, - 0xc, 0x0, 0x0, 0x9a, 0x30, 0x0, 0x0, 0xc, - 0x0, 0x0, 0xac, 0x0, 0x0, 0x1, 0xc, 0x0, - 0x19, 0x57, 0xc3, 0x0, 0x3, 0xc8, 0x15, 0x60, - 0x0, 0x3c, 0xb1, 0x0, 0x0, 0x20, 0x0, 0x0, - 0x0, 0x0, - - /* U+62BC "押" */ - 0x0, 0x3, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0xd, 0x0, 0x85, 0x55, 0x55, 0xa0, 0x0, 0xc, - 0x0, 0xc0, 0xc, 0x1, 0xb0, 0x5, 0x5d, 0x95, - 0xc0, 0xc, 0x1, 0xb0, 0x0, 0xc, 0x0, 0xd5, - 0x5d, 0x56, 0xb0, 0x0, 0xc, 0x1, 0xc0, 0xc, - 0x1, 0xb0, 0x0, 0xe, 0x61, 0xc0, 0xc, 0x1, - 0xb0, 0x17, 0xbc, 0x0, 0xd5, 0x5d, 0x56, 0xb0, - 0x19, 0xc, 0x0, 0xa0, 0xc, 0x0, 0x60, 0x0, - 0xc, 0x0, 0x0, 0xc, 0x0, 0x0, 0x0, 0xc, - 0x0, 0x0, 0xc, 0x0, 0x0, 0x1, 0x2c, 0x0, - 0x0, 0xc, 0x0, 0x0, 0x3, 0xd7, 0x0, 0x0, - 0xd, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x2, - 0x0, 0x0, - - /* U+62C5 "担" */ - 0x0, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0xd, 0x10, 0x0, 0x0, 0x1, 0x0, 0x0, 0xc, - 0x0, 0x96, 0x55, 0x5e, 0x10, 0x0, 0xc, 0x13, - 0x92, 0x0, 0xd, 0x0, 0x5, 0x5d, 0x54, 0x92, - 0x0, 0xd, 0x0, 0x0, 0xc, 0x1, 0x97, 0x55, - 0x5d, 0x0, 0x0, 0xc, 0x71, 0x92, 0x0, 0xd, - 0x0, 0x5, 0xbe, 0x0, 0x92, 0x0, 0xd, 0x0, - 0x1a, 0x1c, 0x0, 0x92, 0x0, 0xd, 0x0, 0x0, - 0xc, 0x0, 0xa7, 0x55, 0x5e, 0x0, 0x0, 0xc, - 0x0, 0x50, 0x0, 0x2, 0x0, 0x0, 0xc, 0x0, - 0x0, 0x0, 0x2, 0x70, 0x3, 0xbc, 0x6, 0x55, - 0x55, 0x55, 0x50, 0x0, 0x10, 0x0, 0x0, 0x0, - 0x0, 0x0, - - /* U+62C9 "拉" */ - 0x0, 0x2, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0xc, 0x20, 0x0, 0x70, 0x0, 0x0, 0x0, 0xc, - 0x0, 0x0, 0x6a, 0x0, 0x0, 0x2, 0x2c, 0x36, - 0x0, 0x16, 0x1, 0x0, 0x3, 0x2c, 0x22, 0x55, - 0x55, 0x58, 0x50, 0x0, 0xc, 0x0, 0x0, 0x0, - 0x42, 0x0, 0x0, 0xc, 0x64, 0x23, 0x0, 0x97, - 0x0, 0x2, 0x9e, 0x10, 0xa, 0x0, 0xb1, 0x0, - 0x2d, 0x3c, 0x0, 0xa, 0x30, 0xb0, 0x0, 0x0, - 0xc, 0x0, 0x8, 0x73, 0x70, 0x0, 0x0, 0xc, - 0x0, 0x4, 0x27, 0x10, 0x0, 0x1, 0xd, 0x0, - 0x0, 0x7, 0x0, 0x50, 0x2, 0xbc, 0x6, 0x55, - 0x56, 0x56, 0x71, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, - - /* U+62DB "招" */ - 0x0, 0x3, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0xc0, 0x25, 0x55, 0x55, 0x76, 0x0, 0xb, 0x0, - 0x6, 0x70, 0x7, 0x50, 0x55, 0xc6, 0x80, 0x83, - 0x0, 0x83, 0x0, 0xb, 0x0, 0xb, 0x0, 0xa, - 0x10, 0x0, 0xb0, 0x4, 0x60, 0x55, 0xd0, 0x0, - 0xc, 0x73, 0x80, 0x0, 0xa5, 0x1, 0x7b, 0xc0, - 0x46, 0x55, 0x55, 0x92, 0x8, 0xb, 0x0, 0xa1, - 0x0, 0xb, 0x0, 0x0, 0xb0, 0xa, 0x10, 0x0, - 0xb0, 0x0, 0xb, 0x0, 0xa1, 0x0, 0xb, 0x0, - 0x0, 0xb0, 0xa, 0x65, 0x55, 0xd0, 0x3, 0xc9, - 0x0, 0x90, 0x0, 0x8, 0x0, 0x1, 0x0, 0x0, - 0x0, 0x0, 0x0, - - /* U+62E1 "拡" */ - 0x0, 0x2, 0x0, 0x0, 0x20, 0x0, 0x0, 0x0, - 0xd, 0x0, 0x0, 0x78, 0x0, 0x0, 0x0, 0xc, - 0x0, 0x20, 0xa, 0x0, 0x50, 0x0, 0xc, 0x12, - 0xd5, 0x55, 0x55, 0x61, 0x5, 0x5d, 0x54, 0xc0, - 0x1, 0x0, 0x0, 0x0, 0xc, 0x0, 0xc0, 0xa, - 0x70, 0x0, 0x0, 0xc, 0x52, 0xc0, 0xd, 0x0, - 0x0, 0x0, 0x7d, 0x10, 0xc0, 0x38, 0x0, 0x0, - 0x2e, 0x5c, 0x0, 0xc0, 0x81, 0x0, 0x0, 0x1, - 0xc, 0x1, 0xa0, 0x80, 0x7, 0x0, 0x0, 0xc, - 0x5, 0x55, 0x30, 0x3, 0xa0, 0x0, 0xc, 0x9, - 0xd, 0xa8, 0x65, 0xd2, 0x5, 0xd8, 0x42, 0x3, - 0x0, 0x0, 0x50, 0x0, 0x10, 0x10, 0x0, 0x0, - 0x0, 0x0, - - /* U+62EC "括" */ - 0x0, 0x3, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0xd, 0x20, 0x0, 0x2, 0x7c, 0x10, 0x0, 0xc, - 0x0, 0x35, 0x7d, 0x41, 0x0, 0x17, 0x5d, 0x5a, - 0x0, 0xc, 0x0, 0x0, 0x0, 0xc, 0x0, 0x0, - 0xc, 0x0, 0x30, 0x0, 0xc, 0x3, 0x65, 0x5d, - 0x56, 0x80, 0x0, 0xc, 0x54, 0x0, 0xc, 0x0, - 0x0, 0x16, 0xae, 0x10, 0x20, 0xc, 0x3, 0x0, - 0x19, 0x1c, 0x0, 0xc5, 0x55, 0x5d, 0x10, 0x0, - 0xc, 0x0, 0xc0, 0x0, 0xc, 0x0, 0x0, 0xc, - 0x0, 0xc0, 0x0, 0xc, 0x0, 0x2, 0x2d, 0x0, - 0xc5, 0x55, 0x5d, 0x0, 0x1, 0xaa, 0x0, 0xc0, - 0x0, 0x8, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, - - /* U+62ED "拭" */ - 0x0, 0x2, 0x0, 0x0, 0x2, 0x0, 0x0, 0x0, - 0xe, 0x10, 0x0, 0xd, 0x29, 0x30, 0x0, 0xc, - 0x0, 0x0, 0xd, 0x2, 0x80, 0x0, 0xc, 0x23, - 0x0, 0xc, 0x1, 0x50, 0x16, 0x5d, 0x54, 0x46, - 0x5d, 0x55, 0x50, 0x0, 0xc, 0x0, 0x0, 0xa, - 0x10, 0x0, 0x0, 0xd, 0x66, 0x55, 0x89, 0x20, - 0x0, 0x18, 0xbd, 0x0, 0xc, 0x6, 0x50, 0x0, - 0x18, 0xc, 0x0, 0xc, 0x3, 0x80, 0x0, 0x0, - 0xc, 0x0, 0xc, 0x0, 0xc0, 0x0, 0x0, 0xc, - 0x0, 0x1d, 0x63, 0x86, 0x41, 0x1, 0xc, 0xa, - 0xa4, 0x0, 0xd, 0xc0, 0x3, 0xd8, 0x0, 0x0, - 0x0, 0x1, 0xc2, 0x0, 0x10, 0x0, 0x0, 0x0, - 0x0, 0x0, - - /* U+62FF "拿" */ - 0x0, 0x0, 0x0, 0x14, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, 0xb9, 0x10, 0x0, 0x0, 0x0, 0x0, - 0x3b, 0x30, 0x66, 0x0, 0x0, 0x0, 0x17, 0x76, - 0x55, 0x86, 0xb9, 0x62, 0x4, 0x40, 0x85, 0x55, - 0x59, 0x13, 0x60, 0x0, 0x0, 0xc0, 0x0, 0xc, - 0x0, 0x0, 0x0, 0x0, 0xd5, 0x55, 0x5a, 0x10, - 0x0, 0x0, 0x23, 0x45, 0x68, 0xac, 0xb0, 0x0, - 0x0, 0x0, 0x0, 0x2a, 0x0, 0x40, 0x0, 0x0, - 0x36, 0x55, 0x6c, 0x56, 0x92, 0x0, 0x4, 0x55, - 0x55, 0x6c, 0x55, 0x5a, 0x90, 0x0, 0x0, 0x0, - 0x2a, 0x0, 0x0, 0x0, 0x0, 0x0, 0x6, 0xd7, - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x30, 0x0, - 0x0, 0x0, - - /* U+6301 "持" */ - 0x0, 0x4, 0x0, 0x0, 0x30, 0x0, 0x0, 0x0, - 0xd, 0x0, 0x0, 0xb3, 0x0, 0x0, 0x0, 0xc, - 0x1, 0x44, 0xc5, 0x49, 0x0, 0x5, 0x5d, 0x86, - 0x11, 0xb2, 0x11, 0x0, 0x0, 0xc, 0x0, 0x0, - 0xb1, 0x0, 0x20, 0x0, 0xc, 0x6, 0x55, 0x86, - 0x56, 0x90, 0x0, 0xd, 0x62, 0x0, 0x7, 0x70, - 0x0, 0x7, 0xbc, 0x5, 0x55, 0x5a, 0x87, 0x90, - 0x6, 0xc, 0x1, 0x20, 0x7, 0x50, 0x0, 0x0, - 0xc, 0x0, 0x85, 0x7, 0x50, 0x0, 0x0, 0xc, - 0x0, 0x19, 0x7, 0x50, 0x0, 0x1, 0x1c, 0x0, - 0x0, 0x7, 0x50, 0x0, 0x2, 0xc8, 0x0, 0x0, - 0x7f, 0x20, 0x0, 0x0, 0x0, 0x0, 0x0, 0x1, - 0x0, 0x0, - - /* U+6307 "指" */ - 0x0, 0x5, 0x0, 0x31, 0x0, 0x0, 0x0, 0x0, - 0xc1, 0x8, 0x60, 0x3, 0x70, 0x0, 0xc, 0x0, - 0x83, 0x18, 0xa5, 0x0, 0x55, 0xd6, 0xb8, 0x75, - 0x10, 0x3, 0x1, 0xc, 0x0, 0x84, 0x0, 0x0, - 0x70, 0x0, 0xc0, 0x35, 0xc9, 0x99, 0xb9, 0x0, - 0xc, 0x70, 0x0, 0x0, 0x0, 0x0, 0x4b, 0xe0, - 0x6, 0x75, 0x55, 0xc1, 0x1b, 0x2c, 0x0, 0x65, - 0x0, 0xc, 0x0, 0x0, 0xc0, 0x6, 0x85, 0x55, - 0xd0, 0x0, 0xc, 0x0, 0x65, 0x0, 0xc, 0x0, - 0x10, 0xd0, 0x6, 0x85, 0x55, 0xd0, 0x2, 0xba, - 0x0, 0x74, 0x0, 0xb, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x0, - - /* U+6319 "挙" */ - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x7, 0x0, 0x91, 0x5, 0xb0, 0x0, 0x0, 0x5, - 0xb0, 0x5a, 0xa, 0x10, 0x0, 0x0, 0x0, 0x70, - 0x4, 0x34, 0x4, 0x30, 0x6, 0x55, 0xc5, 0x55, - 0x95, 0x57, 0x60, 0x0, 0x5, 0x80, 0x0, 0x66, - 0x0, 0x0, 0x0, 0x3a, 0x46, 0x9b, 0xa6, 0xb4, - 0x0, 0x5, 0x60, 0x0, 0xb0, 0x0, 0x7c, 0x80, - 0x31, 0x55, 0x55, 0xc5, 0x55, 0x71, 0x0, 0x0, - 0x0, 0x0, 0xb0, 0x0, 0x7, 0x30, 0x7, 0x55, - 0x55, 0xc5, 0x55, 0x55, 0x40, 0x0, 0x0, 0x0, - 0xb0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x3a, 0xd0, - 0x0, 0x0, 0x0, 0x0, 0x0, 0x1, 0x20, 0x0, - 0x0, 0x0, - - /* U+6355 "捕" */ - 0x0, 0x2, 0x0, 0x0, 0x10, 0x0, 0x0, 0x0, - 0xd, 0x0, 0x0, 0xb2, 0x81, 0x0, 0x0, 0xb, - 0x0, 0x0, 0xb0, 0x36, 0x10, 0x0, 0xb, 0x45, - 0x55, 0xc5, 0x56, 0x90, 0x4, 0x4c, 0x41, 0x0, - 0xb0, 0x0, 0x0, 0x0, 0xb, 0xa, 0x65, 0xc5, - 0x5c, 0x20, 0x0, 0xd, 0x59, 0x10, 0xb0, 0xb, - 0x0, 0x7, 0xbb, 0x9, 0x65, 0xc5, 0x5c, 0x0, - 0x7, 0xb, 0x9, 0x10, 0xb0, 0xb, 0x0, 0x0, - 0xb, 0x9, 0x65, 0xc5, 0x5c, 0x0, 0x0, 0xb, - 0x9, 0x10, 0xb0, 0xb, 0x0, 0x0, 0xb, 0x9, - 0x10, 0xb0, 0xb, 0x0, 0x4, 0xc7, 0xa, 0x10, - 0xb2, 0x8d, 0x0, 0x0, 0x10, 0x2, 0x0, 0x10, - 0x1, 0x0, - - /* U+6368 "捨" */ - 0x0, 0x2, 0x0, 0x0, 0x10, 0x0, 0x0, 0x0, - 0xe, 0x0, 0x0, 0xe1, 0x0, 0x0, 0x0, 0xc, - 0x0, 0x8, 0x57, 0x0, 0x0, 0x0, 0xc, 0x41, - 0x47, 0x2, 0x90, 0x0, 0x5, 0x5d, 0x55, 0x70, - 0x0, 0x8c, 0x72, 0x0, 0xc, 0x14, 0x25, 0xc5, - 0x63, 0x71, 0x0, 0xc, 0x43, 0x0, 0xb0, 0x2, - 0x20, 0x1, 0x8e, 0x24, 0x65, 0xc5, 0x56, 0x50, - 0xc, 0x4c, 0x0, 0x0, 0xb0, 0x0, 0x0, 0x0, - 0xc, 0x0, 0xc5, 0x85, 0x5d, 0x10, 0x0, 0xc, - 0x0, 0xb0, 0x0, 0xc, 0x0, 0x1, 0xc, 0x0, - 0xb0, 0x0, 0xc, 0x0, 0x4, 0xd8, 0x0, 0xd5, - 0x55, 0x5d, 0x0, 0x0, 0x10, 0x0, 0x20, 0x0, - 0x1, 0x0, - - /* U+6388 "授" */ - 0x0, 0x3, 0x0, 0x0, 0x0, 0x1, 0x0, 0x0, - 0xd, 0x0, 0x1, 0x47, 0xad, 0x40, 0x0, 0xb, - 0x1, 0x43, 0x30, 0x9, 0x20, 0x5, 0x5c, 0x84, - 0x90, 0xa2, 0x2a, 0x0, 0x0, 0xb, 0x0, 0x75, - 0x63, 0x71, 0x0, 0x0, 0xb, 0x27, 0x55, 0x55, - 0x85, 0xb0, 0x0, 0x1d, 0x5c, 0x0, 0x0, 0x5, - 0x30, 0x17, 0xab, 0x2, 0x55, 0x55, 0xa4, 0x0, - 0x17, 0xb, 0x0, 0x5, 0x2, 0xc1, 0x0, 0x0, - 0xb, 0x0, 0x3, 0x5b, 0x20, 0x0, 0x0, 0xb, - 0x0, 0x0, 0xd8, 0x0, 0x0, 0x0, 0xb, 0x0, - 0x2a, 0x48, 0x93, 0x0, 0x5, 0xd7, 0x16, 0x60, - 0x0, 0x4b, 0xc2, 0x0, 0x10, 0x10, 0x0, 0x0, - 0x0, 0x0, - - /* U+6392 "排" */ - 0x0, 0x5, 0x0, 0x4, 0x10, 0x40, 0x0, 0x0, - 0xc, 0x0, 0x9, 0x50, 0xd0, 0x0, 0x0, 0xb, - 0x0, 0x9, 0x20, 0xb0, 0x0, 0x5, 0x5c, 0x96, - 0x5b, 0x20, 0xc5, 0x84, 0x0, 0xb, 0x0, 0x9, - 0x20, 0xb0, 0x0, 0x0, 0xb, 0x11, 0x9, 0x20, - 0xb0, 0x10, 0x0, 0x2d, 0x52, 0x5b, 0x20, 0xc5, - 0x82, 0x1b, 0xab, 0x0, 0x9, 0x20, 0xb0, 0x0, - 0x3, 0xb, 0x0, 0x9, 0x20, 0xb0, 0x21, 0x0, - 0xb, 0x15, 0x5b, 0x20, 0xc5, 0x64, 0x0, 0xb, - 0x0, 0x9, 0x20, 0xb0, 0x0, 0x1, 0xb, 0x0, - 0x9, 0x20, 0xb0, 0x0, 0x3, 0xc7, 0x0, 0x9, - 0x20, 0xb0, 0x0, 0x0, 0x0, 0x0, 0x1, 0x0, - 0x10, 0x0, - - /* U+639B "掛" */ - 0x0, 0x20, 0x0, 0x0, 0x0, 0x10, 0x0, 0x0, - 0xa3, 0x0, 0x1b, 0x0, 0xb2, 0x0, 0x0, 0xa1, - 0x0, 0x19, 0x0, 0xb0, 0x0, 0x0, 0xa2, 0x25, - 0x5b, 0x91, 0xb0, 0x0, 0x35, 0xc6, 0x40, 0x19, - 0x0, 0xb0, 0x0, 0x0, 0xa1, 0x0, 0x19, 0x13, - 0xb5, 0x0, 0x0, 0xa2, 0x35, 0x57, 0x54, 0xb4, - 0xb0, 0x3, 0xd4, 0x0, 0x1b, 0x0, 0xb0, 0xa0, - 0x6a, 0xb1, 0x15, 0x6b, 0x83, 0xb0, 0x0, 0x0, - 0xa1, 0x0, 0x19, 0x0, 0xb0, 0x0, 0x0, 0xa1, - 0x0, 0x19, 0x0, 0xb0, 0x0, 0x0, 0xb0, 0x2, - 0x5b, 0x53, 0xb0, 0x0, 0x8, 0xb0, 0x5b, 0x40, - 0x0, 0xb0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, - - /* U+63A1 "採" */ - 0x0, 0x2, 0x0, 0x0, 0x0, 0x2, 0x0, 0x0, - 0xd, 0x0, 0x14, 0x69, 0xcc, 0x10, 0x0, 0xb, - 0x3, 0x33, 0x0, 0x2, 0x40, 0x0, 0xb, 0x44, - 0x31, 0x90, 0x9, 0x60, 0x5, 0x5c, 0x52, 0xc2, - 0x85, 0x37, 0x0, 0x0, 0xb, 0x0, 0x40, 0x51, - 0x40, 0x0, 0x0, 0xb, 0x42, 0x0, 0x93, 0x2, - 0x40, 0x0, 0x6d, 0x24, 0x59, 0xf9, 0x55, 0x40, - 0x1e, 0x6b, 0x0, 0xb, 0xb8, 0x10, 0x0, 0x1, - 0xb, 0x0, 0x46, 0x92, 0xa0, 0x0, 0x0, 0xb, - 0x1, 0x80, 0x92, 0x69, 0x0, 0x0, 0xb, 0x7, - 0x0, 0x92, 0xb, 0xb2, 0x4, 0xd8, 0x20, 0x0, - 0x92, 0x0, 0x20, 0x0, 0x10, 0x0, 0x0, 0x20, - 0x0, 0x0, - - /* U+63A2 "探" */ - 0x0, 0x2, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0xd, 0x0, 0x75, 0x55, 0x55, 0x82, 0x0, 0xb, - 0x1, 0xb0, 0x0, 0x0, 0xa1, 0x0, 0xb, 0x44, - 0x25, 0x92, 0x51, 0x0, 0x5, 0x5c, 0x53, 0x1b, - 0x10, 0x3d, 0x30, 0x0, 0xb, 0x3, 0x81, 0x1a, - 0x3, 0x50, 0x0, 0xd, 0x62, 0x0, 0x1a, 0x0, - 0x50, 0x6, 0xbb, 0x5, 0x55, 0xec, 0x75, 0x63, - 0x8, 0xb, 0x0, 0x6, 0x9a, 0x70, 0x0, 0x0, - 0xb, 0x0, 0x1b, 0x1a, 0x46, 0x0, 0x0, 0xb, - 0x0, 0x91, 0x1a, 0xa, 0x70, 0x0, 0xb, 0x7, - 0x10, 0x1a, 0x0, 0xb6, 0x2, 0xb7, 0x20, 0x0, - 0x19, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, - - /* U+63A5 "接" */ - 0x0, 0x4, 0x0, 0x0, 0x20, 0x0, 0x0, 0x0, - 0xc, 0x0, 0x0, 0x94, 0x0, 0x0, 0x0, 0xb, - 0x1, 0x55, 0x77, 0x58, 0x60, 0x5, 0x5c, 0x77, - 0x34, 0x0, 0xa1, 0x0, 0x0, 0xb, 0x0, 0xb, - 0x23, 0x70, 0x0, 0x0, 0xb, 0x5, 0x57, 0x68, - 0x55, 0xb1, 0x0, 0xc, 0x51, 0x1, 0xc0, 0x0, - 0x0, 0x16, 0xab, 0x0, 0x8, 0x50, 0x0, 0x50, - 0x18, 0xb, 0x35, 0x5c, 0x55, 0xc6, 0x62, 0x0, - 0xb, 0x0, 0x73, 0x2, 0xb0, 0x0, 0x0, 0xb, - 0x0, 0x57, 0x7c, 0x20, 0x0, 0x1, 0xb, 0x0, - 0x1, 0xa6, 0xb8, 0x0, 0x2, 0xc7, 0x3, 0x78, - 0x10, 0x7, 0xa0, 0x0, 0x10, 0x31, 0x0, 0x0, - 0x0, 0x10, - - /* U+63A7 "控" */ - 0x0, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0xe, 0x10, 0x1, 0x82, 0x0, 0x0, 0x0, 0xc, - 0x0, 0x10, 0x39, 0x0, 0x10, 0x5, 0x5d, 0x83, - 0x94, 0x44, 0x46, 0xb0, 0x0, 0xc, 0x5, 0x55, - 0x32, 0x4, 0x0, 0x0, 0xc, 0x0, 0x1c, 0x20, - 0x97, 0x0, 0x0, 0xd, 0x63, 0x91, 0x0, 0xb, - 0x50, 0x5, 0xad, 0x4, 0x0, 0x0, 0x26, 0x10, - 0x1a, 0x1c, 0x0, 0x55, 0xc6, 0x54, 0x0, 0x0, - 0xc, 0x0, 0x0, 0xa2, 0x0, 0x0, 0x0, 0xc, - 0x0, 0x0, 0xa2, 0x0, 0x0, 0x0, 0xc, 0x0, - 0x0, 0xa2, 0x1, 0x60, 0x5, 0xb9, 0x6, 0x55, - 0x55, 0x55, 0x50, 0x0, 0x20, 0x0, 0x0, 0x0, - 0x0, 0x0, - - /* U+63A8 "推" */ - 0x0, 0x2, 0x0, 0x2, 0x0, 0x0, 0x0, 0x0, - 0xd, 0x0, 0x3d, 0x9, 0x20, 0x0, 0x0, 0xb, - 0x0, 0x76, 0x4, 0x70, 0x20, 0x5, 0x5c, 0x76, - 0xb5, 0x5a, 0x55, 0x80, 0x0, 0xb, 0x0, 0xf0, - 0xb, 0x0, 0x0, 0x0, 0xb, 0x7, 0xd0, 0xb, - 0x3, 0x20, 0x0, 0x1d, 0x45, 0xb5, 0x5c, 0x55, - 0x30, 0x19, 0x9b, 0x0, 0xb0, 0xb, 0x0, 0x0, - 0x5, 0xb, 0x0, 0xb5, 0x5c, 0x57, 0x80, 0x0, - 0xb, 0x0, 0xb0, 0xb, 0x0, 0x0, 0x0, 0xb, - 0x0, 0xb0, 0xb, 0x0, 0x0, 0x0, 0xb, 0x0, - 0xb5, 0x5c, 0x56, 0xc1, 0x3, 0xc6, 0x0, 0xb0, - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, - - /* U+63CF "描" */ - 0x0, 0x4, 0x0, 0x1, 0x0, 0x10, 0x0, 0x0, - 0xe, 0x10, 0x8, 0x60, 0xc2, 0x0, 0x0, 0xc, - 0x0, 0x8, 0x30, 0xc0, 0x20, 0x0, 0xc, 0x26, - 0x5a, 0x75, 0xd5, 0x81, 0x6, 0x5d, 0x54, 0x8, - 0x30, 0xc0, 0x0, 0x0, 0xc, 0x0, 0x4, 0x10, - 0x40, 0x10, 0x0, 0xc, 0x53, 0xc5, 0x5a, 0x56, - 0xc0, 0x5, 0x9d, 0x10, 0xb0, 0xb, 0x1, 0xa0, - 0x9, 0x1c, 0x0, 0xc5, 0x5c, 0x56, 0xa0, 0x0, - 0xc, 0x0, 0xb0, 0xb, 0x1, 0xa0, 0x0, 0xc, - 0x0, 0xb0, 0xb, 0x1, 0xa0, 0x3, 0x2c, 0x0, - 0xc5, 0x5c, 0x56, 0xa0, 0x2, 0xc7, 0x0, 0xa0, - 0x0, 0x1, 0x80, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, - - /* U+63D0 "提" */ - 0x0, 0x2, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0xd, 0x0, 0x85, 0x55, 0x5a, 0x0, 0x0, 0xb, - 0x0, 0x91, 0x0, 0xa, 0x0, 0x5, 0x5c, 0x84, - 0x96, 0x55, 0x5a, 0x0, 0x0, 0xb, 0x0, 0x91, - 0x0, 0xa, 0x0, 0x0, 0xb, 0x1, 0xa6, 0x55, - 0x5a, 0x0, 0x0, 0xd, 0x60, 0x30, 0x0, 0x0, - 0x50, 0x8, 0xab, 0x17, 0x55, 0x5c, 0x55, 0x62, - 0x6, 0xb, 0x2, 0xa0, 0xb, 0x0, 0x0, 0x0, - 0xb, 0x5, 0x70, 0xc, 0x56, 0x60, 0x0, 0xb, - 0x9, 0x63, 0xb, 0x0, 0x0, 0x1, 0x2b, 0x26, - 0x8, 0x9c, 0x0, 0x0, 0x2, 0xc6, 0x50, 0x0, - 0x4a, 0xde, 0xd2, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, - - /* U+63DB "換" */ - 0x0, 0x2, 0x0, 0x1, 0x0, 0x0, 0x0, 0x0, - 0x2c, 0x0, 0x9, 0x41, 0x20, 0x0, 0x0, 0x19, - 0x0, 0x38, 0x5b, 0xa0, 0x0, 0x5, 0x6b, 0x94, - 0x50, 0x26, 0x0, 0x0, 0x0, 0x19, 0x0, 0xa5, - 0x75, 0x5b, 0x20, 0x0, 0x19, 0x3, 0xb5, 0x65, - 0xa, 0x0, 0x0, 0x2d, 0x60, 0xb8, 0x1, 0xcb, - 0x0, 0x9, 0xc9, 0x0, 0xc2, 0x81, 0x6b, 0x0, - 0x5, 0x19, 0x0, 0x40, 0xc0, 0x4, 0x30, 0x0, - 0x19, 0x16, 0x56, 0xb7, 0x55, 0x81, 0x0, 0x19, - 0x0, 0x9, 0x25, 0x20, 0x0, 0x0, 0x19, 0x0, - 0x76, 0x0, 0xa6, 0x0, 0x4, 0xc7, 0x37, 0x20, - 0x0, 0x9, 0xd2, 0x0, 0x20, 0x10, 0x0, 0x0, - 0x0, 0x0, - - /* U+63EE "揮" */ - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x93, 0x7, 0x55, 0x55, 0x56, 0x80, 0x0, 0x92, - 0xe, 0x10, 0x62, 0x7, 0x30, 0x0, 0x93, 0x13, - 0x0, 0xb1, 0x6, 0x0, 0x35, 0xb7, 0x45, 0x55, - 0xc5, 0x55, 0x20, 0x0, 0x92, 0x6, 0x55, 0xc5, - 0x5a, 0x20, 0x0, 0x93, 0x49, 0x20, 0xb0, 0xb, - 0x0, 0x1, 0xc6, 0x9, 0x65, 0xc5, 0x5c, 0x0, - 0x6c, 0xb2, 0x9, 0x65, 0xc5, 0x5c, 0x0, 0x10, - 0x92, 0x5, 0x0, 0xb0, 0x4, 0x0, 0x0, 0x92, - 0x26, 0x55, 0xc5, 0x58, 0x80, 0x0, 0x92, 0x0, - 0x0, 0xb0, 0x0, 0x0, 0x29, 0xe0, 0x0, 0x0, - 0xb0, 0x0, 0x0, 0x0, 0x20, 0x0, 0x0, 0x30, - 0x0, 0x0, - - /* U+63FA "揺" */ - 0x0, 0x2, 0x0, 0x0, 0x0, 0x1, 0x10, 0x0, - 0xd, 0x0, 0x1, 0x48, 0xbd, 0xa0, 0x0, 0xb, - 0x2, 0x44, 0x31, 0x0, 0x80, 0x0, 0xb, 0x34, - 0x20, 0x91, 0x5, 0xa0, 0x5, 0x5c, 0x53, 0xc1, - 0x67, 0x8, 0x0, 0x0, 0xb, 0x0, 0x40, 0x1, - 0x22, 0x20, 0x0, 0xb, 0x53, 0x55, 0x5b, 0x56, - 0x50, 0x1, 0x7d, 0x10, 0x0, 0xb, 0x0, 0x20, - 0x1e, 0x5b, 0x6, 0x55, 0x5c, 0x55, 0x95, 0x1, - 0xb, 0x0, 0x40, 0xb, 0x0, 0x20, 0x0, 0xb, - 0x0, 0xc0, 0xb, 0x0, 0xc0, 0x0, 0x1b, 0x0, - 0xa0, 0xb, 0x0, 0xa0, 0x5, 0xe7, 0x1, 0xa5, - 0x57, 0x55, 0xb0, 0x0, 0x10, 0x0, 0x0, 0x0, - 0x0, 0x10, - - /* U+643A "携" */ - 0x0, 0x2, 0x0, 0x1, 0x0, 0x0, 0x0, 0x0, - 0xd, 0x0, 0x1d, 0x1b, 0x10, 0x0, 0x0, 0xb, - 0x0, 0x88, 0x5b, 0x67, 0x80, 0x5, 0x5c, 0x93, - 0xf0, 0xa, 0x3, 0x10, 0x0, 0xb, 0x6, 0xb5, - 0x5c, 0x55, 0x30, 0x0, 0xb, 0x22, 0xb5, 0x5c, - 0x59, 0x30, 0x0, 0x1d, 0x40, 0xb0, 0xa, 0x0, - 0x30, 0x19, 0xab, 0x0, 0xb5, 0x56, 0x55, 0x60, - 0x6, 0xb, 0x3, 0x68, 0x55, 0x96, 0x0, 0x0, - 0xb, 0x0, 0xd, 0x0, 0xb0, 0x40, 0x0, 0xb, - 0x0, 0x48, 0x1, 0x75, 0xd0, 0x0, 0xb, 0x1, - 0xb1, 0x0, 0x3, 0x80, 0x4, 0xc8, 0x38, 0x10, - 0x2, 0x9c, 0x20, 0x0, 0x10, 0x10, 0x0, 0x0, - 0x12, 0x0, - - /* U+64C1 "擁" */ - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0xb1, 0x0, 0x0, 0xa1, 0x0, 0x0, 0x0, 0xb0, - 0x25, 0x55, 0x96, 0x56, 0xa0, 0x0, 0xb0, 0x1, - 0xb0, 0x44, 0x60, 0x0, 0x25, 0xc6, 0x56, 0x22, - 0xa2, 0x73, 0x10, 0x0, 0xb0, 0x5, 0x4c, 0xc5, - 0x96, 0x70, 0x0, 0xb2, 0x68, 0xb6, 0xb0, 0xb0, - 0x0, 0x0, 0xc4, 0x5, 0x32, 0xc5, 0xc6, 0x60, - 0x3c, 0xd0, 0x37, 0x6a, 0xb0, 0xb0, 0x0, 0x13, - 0xb0, 0x56, 0xb1, 0xc5, 0xc6, 0x60, 0x0, 0xb0, - 0x2, 0x70, 0xb0, 0xb0, 0x0, 0x0, 0xb0, 0x9, - 0x0, 0xb0, 0xb0, 0x40, 0x18, 0xd0, 0x60, 0x0, - 0xd5, 0x65, 0x60, 0x0, 0x10, 0x0, 0x0, 0x10, - 0x0, 0x0, - - /* U+64C7 "擇" */ - 0x0, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x1c, 0x0, 0x85, 0x55, 0x55, 0x90, 0x0, 0x1a, - 0x0, 0xa0, 0xb0, 0xa0, 0xa0, 0x0, 0xa, 0x20, - 0xc5, 0xc5, 0xc5, 0xb0, 0x5, 0x5c, 0x73, 0x60, - 0x1a, 0x0, 0x40, 0x0, 0xa, 0x0, 0x45, 0x5c, - 0x5a, 0x20, 0x0, 0xa, 0x50, 0x0, 0xb, 0x0, - 0x40, 0x0, 0x3d, 0x13, 0x69, 0x55, 0x86, 0x52, - 0x8, 0xaa, 0x0, 0x4, 0x80, 0x93, 0x0, 0x6, - 0x1a, 0x0, 0x76, 0x79, 0x67, 0x40, 0x0, 0xa, - 0x0, 0x0, 0xb, 0x0, 0x60, 0x0, 0xa, 0x7, - 0x55, 0x5c, 0x55, 0x52, 0x4, 0xa9, 0x0, 0x0, - 0xb, 0x0, 0x0, 0x0, 0x40, 0x0, 0x0, 0x5, - 0x0, 0x0, - - /* U+64D4 "擔" */ - 0x0, 0x1, 0x0, 0x2, 0x10, 0x0, 0x0, 0x0, - 0xd, 0x0, 0xa, 0x60, 0x10, 0x0, 0x0, 0xb, - 0x0, 0x3a, 0x55, 0xd1, 0x0, 0x0, 0xb, 0x20, - 0xb5, 0x57, 0x65, 0xa0, 0x5, 0x5c, 0x65, 0xc1, - 0xa2, 0x37, 0x0, 0x0, 0xb, 0x0, 0xb5, 0x18, - 0x36, 0x30, 0x0, 0xb, 0x62, 0xb5, 0x56, 0x55, - 0x81, 0x0, 0x3d, 0x10, 0xb2, 0x55, 0x59, 0x0, - 0x9, 0x9b, 0x0, 0xa0, 0x0, 0x5, 0x0, 0x5, - 0xb, 0x3, 0x72, 0x65, 0x55, 0x10, 0x0, 0xb, - 0x8, 0x28, 0x65, 0x5b, 0x20, 0x1, 0xb, 0x7, - 0x8, 0x30, 0xa, 0x10, 0x2, 0xd7, 0x50, 0x8, - 0x75, 0x5a, 0x10, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, - - /* U+64DA "據" */ - 0x0, 0x1, 0x0, 0x0, 0x30, 0x0, 0x0, 0x0, - 0x1b, 0x0, 0x0, 0xb1, 0x4, 0x0, 0x0, 0x19, - 0x1, 0x0, 0xb5, 0x55, 0x20, 0x0, 0x19, 0x29, - 0x65, 0xb6, 0x55, 0xd1, 0x5, 0x6b, 0x6a, 0x10, - 0xb5, 0x83, 0x20, 0x0, 0x19, 0x9, 0x44, 0xb1, - 0x7, 0x0, 0x0, 0x1a, 0x49, 0x10, 0x37, 0x76, - 0x40, 0x0, 0x4c, 0xa, 0x45, 0xa8, 0x57, 0x60, - 0x9, 0xa9, 0xa, 0x5, 0x84, 0x1b, 0x20, 0x4, - 0x19, 0xa, 0x23, 0x8a, 0x90, 0x0, 0x0, 0x19, - 0x26, 0x56, 0x4a, 0x97, 0x0, 0x0, 0x19, 0x61, - 0x27, 0x60, 0xb4, 0xc2, 0x5, 0xc7, 0x42, 0x30, - 0x39, 0x90, 0x10, 0x0, 0x20, 0x0, 0x0, 0x2, - 0x0, 0x0, - - /* U+652F "支" */ - 0x0, 0x0, 0x0, 0x30, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, 0xc3, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0xc1, 0x0, 0x6, 0x10, 0x6, 0x55, 0x55, - 0xd5, 0x55, 0x57, 0x40, 0x0, 0x0, 0x0, 0xc1, - 0x0, 0x0, 0x0, 0x0, 0x25, 0x55, 0xd5, 0x59, - 0x10, 0x0, 0x0, 0x0, 0x40, 0x0, 0x4a, 0x0, - 0x0, 0x0, 0x0, 0x51, 0x0, 0xc2, 0x0, 0x0, - 0x0, 0x0, 0x9, 0x7, 0x70, 0x0, 0x0, 0x0, - 0x0, 0x5, 0xab, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x5, 0xdb, 0x20, 0x0, 0x0, 0x0, 0x1, 0x97, - 0x3, 0xca, 0x63, 0x10, 0x4, 0x67, 0x10, 0x0, - 0x4, 0xae, 0x60, 0x10, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, - - /* U+6539 "改" */ - 0x0, 0x0, 0x0, 0x0, 0x10, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x1d, 0x0, 0x0, 0x5, 0x55, 0x5c, - 0x15, 0x70, 0x0, 0x0, 0x0, 0x0, 0xb0, 0xa1, - 0x0, 0x41, 0x0, 0x0, 0xb, 0xb, 0x55, 0xb6, - 0x30, 0x20, 0x0, 0xb6, 0x70, 0xa, 0x0, 0xb, - 0x65, 0x58, 0x55, 0x10, 0xb0, 0x0, 0xb1, 0x0, - 0x0, 0x25, 0xb, 0x0, 0xb, 0x10, 0x0, 0x0, - 0x95, 0x60, 0x0, 0xb1, 0x0, 0x2, 0x6, 0xc0, - 0x0, 0xb, 0x13, 0x75, 0x0, 0x8c, 0x20, 0x0, - 0xcc, 0x60, 0x0, 0x85, 0x1c, 0x40, 0x4, 0x10, - 0x4, 0x71, 0x0, 0x2d, 0x80, 0x0, 0x1, 0x10, - 0x0, 0x0, 0x0, - - /* U+653E "放" */ - 0x0, 0x0, 0x0, 0x0, 0x30, 0x0, 0x0, 0x0, - 0x9, 0x30, 0x0, 0xc4, 0x0, 0x0, 0x0, 0x1, - 0xb0, 0x0, 0xd0, 0x0, 0x0, 0x25, 0x65, 0x55, - 0xa4, 0xb5, 0x59, 0x80, 0x0, 0x92, 0x0, 0x8, - 0x20, 0x57, 0x0, 0x0, 0x92, 0x3, 0xa, 0x20, - 0x75, 0x0, 0x0, 0xa6, 0x5c, 0x52, 0x60, 0xb1, - 0x0, 0x0, 0xb0, 0xb, 0x0, 0x80, 0xc0, 0x0, - 0x0, 0xb0, 0xb, 0x0, 0x68, 0x60, 0x0, 0x0, - 0xa0, 0xb, 0x0, 0x1f, 0x0, 0x0, 0x4, 0x60, - 0xc, 0x0, 0x98, 0x90, 0x0, 0x9, 0x6, 0xa8, - 0x8, 0x30, 0x8a, 0x10, 0x43, 0x0, 0x83, 0x61, - 0x0, 0x7, 0x91, 0x0, 0x0, 0x1, 0x0, 0x0, - 0x0, 0x0, - - /* U+653F "政" */ - 0x0, 0x0, 0x0, 0x0, 0x22, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x0, 0x88, 0x0, 0x0, 0x6, 0x55, - 0x65, 0xc3, 0xb1, 0x0, 0x0, 0x0, 0x0, 0xb0, - 0x0, 0xd5, 0x56, 0xb2, 0x0, 0x0, 0xb0, 0x4, - 0x70, 0xd, 0x0, 0x1, 0xb0, 0xb1, 0x28, 0x50, - 0xb, 0x0, 0x1, 0xa0, 0xc5, 0x55, 0x60, 0x38, - 0x0, 0x1, 0xa0, 0xb0, 0x20, 0x52, 0x75, 0x0, - 0x1, 0xa0, 0xb0, 0x0, 0x8, 0xc0, 0x0, 0x1, - 0xa0, 0xb0, 0x31, 0xa, 0x90, 0x0, 0x2, 0xc8, - 0xb6, 0x10, 0x4b, 0xc1, 0x0, 0x1d, 0x72, 0x0, - 0x6, 0x70, 0x3d, 0x40, 0x0, 0x0, 0x2, 0x62, - 0x0, 0x3, 0xc4, 0x0, 0x0, 0x1, 0x0, 0x0, - 0x0, 0x0, - - /* U+6545 "故" */ - 0x0, 0x0, 0x0, 0x0, 0x1, 0x0, 0x0, 0x0, - 0x0, 0xc0, 0x0, 0x4c, 0x0, 0x0, 0x0, 0x0, - 0xb0, 0x0, 0x75, 0x0, 0x0, 0x0, 0x0, 0xb0, - 0x30, 0xb0, 0x0, 0x40, 0x5, 0x55, 0xc5, 0x73, - 0xd5, 0x5d, 0x61, 0x0, 0x0, 0xb0, 0x6, 0x80, - 0xc, 0x0, 0x0, 0x0, 0xb0, 0x6, 0x50, 0x1b, - 0x0, 0x0, 0xc5, 0x79, 0x80, 0x34, 0x47, 0x0, - 0x0, 0xb0, 0x6, 0x50, 0x9, 0x92, 0x0, 0x0, - 0xb0, 0x6, 0x50, 0x9, 0xb0, 0x0, 0x0, 0xb0, - 0x6, 0x50, 0xb, 0xb0, 0x0, 0x0, 0xd5, 0x59, - 0x51, 0x92, 0x5b, 0x20, 0x0, 0x50, 0x1, 0x55, - 0x0, 0x5, 0xd2, 0x0, 0x0, 0x1, 0x0, 0x0, - 0x0, 0x0, - - /* U+6548 "效" */ - 0x0, 0x1, 0x0, 0x0, 0x4, 0x0, 0x0, 0x0, - 0x5, 0x60, 0x0, 0x1e, 0x20, 0x0, 0x0, 0x0, - 0xd1, 0x21, 0x48, 0x0, 0x0, 0x3, 0x65, 0x65, - 0x75, 0x92, 0x0, 0x60, 0x0, 0x2b, 0x7, 0x40, - 0xb5, 0x5d, 0x51, 0x0, 0x93, 0x0, 0xd4, 0x90, - 0xb, 0x0, 0x3, 0x60, 0x6, 0x36, 0x50, 0x29, - 0x0, 0x5, 0x14, 0x1c, 0x12, 0x34, 0x64, 0x0, - 0x0, 0x3, 0xc4, 0x0, 0x9, 0xb0, 0x0, 0x0, - 0x2, 0xba, 0x0, 0xa, 0x70, 0x0, 0x0, 0xa, - 0x8, 0x70, 0x3a, 0xa0, 0x0, 0x0, 0x81, 0x1, - 0x54, 0x60, 0x6b, 0x10, 0x6, 0x10, 0x0, 0x53, - 0x0, 0x7, 0xb1, 0x0, 0x0, 0x2, 0x0, 0x0, - 0x0, 0x0, - - /* U+6557 "敗" */ - 0x0, 0x0, 0x0, 0x0, 0x10, 0x0, 0x0, 0x6, - 0x55, 0x55, 0x90, 0x7a, 0x0, 0x0, 0xb, 0x0, - 0x1, 0xb0, 0xa2, 0x0, 0x0, 0xb, 0x0, 0x1, - 0xa0, 0xc5, 0x57, 0xb2, 0xb, 0x55, 0x55, 0xa3, - 0x80, 0xc, 0x0, 0xb, 0x0, 0x1, 0xa7, 0x40, - 0xc, 0x0, 0xb, 0x55, 0x55, 0xa6, 0x50, 0x29, - 0x0, 0xb, 0x0, 0x1, 0xb0, 0x42, 0x75, 0x0, - 0xb, 0x55, 0x55, 0xa0, 0x7, 0xb0, 0x0, 0x7, - 0x11, 0x10, 0x40, 0x9, 0x80, 0x0, 0x0, 0xa6, - 0x1a, 0x30, 0x3a, 0xb1, 0x0, 0x5, 0x60, 0x2, - 0x72, 0x80, 0x3d, 0x20, 0x24, 0x0, 0x0, 0x44, - 0x0, 0x4, 0xd3, 0x0, 0x0, 0x1, 0x0, 0x0, - 0x0, 0x0, - - /* U+6559 "教" */ - 0x0, 0x0, 0x10, 0x0, 0x1, 0x0, 0x0, 0x0, - 0x0, 0xc0, 0x0, 0x9, 0x70, 0x0, 0x0, 0x0, - 0xb3, 0x2b, 0xc, 0x10, 0x0, 0x1, 0x55, 0xc5, - 0xd2, 0xa, 0x0, 0x50, 0x5, 0x55, 0xc8, 0xaa, - 0x67, 0x4a, 0x62, 0x0, 0x0, 0x38, 0x0, 0x73, - 0xa, 0x10, 0x1, 0x57, 0xb5, 0xd3, 0x44, 0xb, - 0x0, 0x0, 0x46, 0x16, 0x22, 0x6, 0xa, 0x0, - 0x4, 0x20, 0x85, 0x2, 0x6, 0x56, 0x0, 0x1, - 0x36, 0xc8, 0x52, 0x3, 0xd0, 0x0, 0x8, 0x72, - 0x83, 0x0, 0x7, 0xc2, 0x0, 0x0, 0x0, 0x83, - 0x0, 0x75, 0x1c, 0x20, 0x0, 0x27, 0xd1, 0x26, - 0x20, 0x3, 0xd4, 0x0, 0x0, 0x30, 0x10, 0x0, - 0x0, 0x0, - - /* U+6562 "敢" */ - 0x0, 0x0, 0x0, 0x0, 0x12, 0x0, 0x0, 0x1, - 0x55, 0x58, 0x0, 0x5a, 0x0, 0x0, 0x0, 0x0, - 0x48, 0x0, 0x83, 0x0, 0x0, 0x15, 0x55, 0xa6, - 0x86, 0xb5, 0x56, 0xa0, 0x0, 0xb0, 0xb, 0x0, - 0xa0, 0x1a, 0x0, 0x0, 0xb0, 0xb, 0x5, 0x80, - 0x38, 0x0, 0x0, 0xc5, 0x5c, 0x7, 0x50, 0x65, - 0x0, 0x0, 0xb0, 0xb, 0x13, 0x34, 0x92, 0x0, - 0x0, 0xc5, 0x5c, 0x0, 0x8, 0xb0, 0x0, 0x0, - 0xb0, 0xb, 0x33, 0x9, 0x70, 0x0, 0x16, 0xe9, - 0x7d, 0x10, 0x1b, 0xb0, 0x0, 0x8, 0x20, 0xb, - 0x0, 0x91, 0x4b, 0x10, 0x0, 0x0, 0xb, 0x27, - 0x10, 0x5, 0xc2, 0x0, 0x0, 0x1, 0x20, 0x0, - 0x0, 0x0, - - /* U+6570 "数" */ - 0x0, 0x0, 0x30, 0x0, 0x11, 0x0, 0x0, 0x1, - 0x40, 0xc1, 0x62, 0x5b, 0x0, 0x0, 0x0, 0xb3, - 0xb1, 0x90, 0x93, 0x0, 0x0, 0x0, 0x31, 0xb3, - 0x41, 0xb0, 0x0, 0x60, 0x6, 0x5b, 0xe5, 0x56, - 0xb5, 0x5d, 0x51, 0x0, 0x48, 0xb9, 0x77, 0x50, - 0x1a, 0x0, 0x4, 0x60, 0xa0, 0x54, 0x50, 0x38, - 0x0, 0x11, 0x4, 0x90, 0x10, 0x52, 0x65, 0x0, - 0x6, 0x5b, 0x75, 0xc0, 0x17, 0xb1, 0x0, 0x0, - 0x29, 0x7, 0x50, 0xa, 0xb0, 0x0, 0x0, 0x26, - 0x8d, 0x20, 0xb, 0xa0, 0x0, 0x0, 0x6, 0x84, - 0xc2, 0x93, 0x8a, 0x10, 0x4, 0x62, 0x0, 0x36, - 0x10, 0x7, 0xc1, 0x0, 0x0, 0x1, 0x10, 0x0, - 0x0, 0x0, - - /* U+6574 "整" */ - 0x0, 0x0, 0x30, 0x0, 0x22, 0x0, 0x0, 0x0, - 0x0, 0xc0, 0x30, 0x86, 0x0, 0x0, 0x5, 0x65, - 0xc5, 0x63, 0xc5, 0x57, 0xa0, 0x0, 0x95, 0xc5, - 0xa3, 0xa0, 0x29, 0x0, 0x0, 0xa0, 0xb0, 0xa7, - 0x24, 0x84, 0x0, 0x0, 0xb7, 0xe5, 0x90, 0x9, - 0xb0, 0x0, 0x0, 0x2a, 0xc8, 0x60, 0x2a, 0xb2, - 0x0, 0x3, 0x70, 0xc0, 0x65, 0x60, 0x2c, 0xa1, - 0x12, 0x46, 0x65, 0x86, 0x55, 0x96, 0x10, 0x0, - 0x0, 0x20, 0x57, 0x0, 0x20, 0x0, 0x0, 0x0, - 0xc0, 0x5a, 0x56, 0x80, 0x0, 0x0, 0x0, 0xb0, - 0x57, 0x0, 0x0, 0x0, 0x4, 0x55, 0xc5, 0x8a, - 0x55, 0x5b, 0x90, 0x1, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, - - /* U+6587 "文" */ - 0x0, 0x0, 0x0, 0x10, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x83, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x48, 0x0, 0x0, 0x10, 0x5, 0x55, 0x65, - 0x55, 0x57, 0x5a, 0xa0, 0x0, 0x0, 0x50, 0x0, - 0x2a, 0x0, 0x0, 0x0, 0x0, 0x51, 0x0, 0x66, - 0x0, 0x0, 0x0, 0x0, 0x7, 0x0, 0xb1, 0x0, - 0x0, 0x0, 0x0, 0x8, 0x2, 0xb0, 0x0, 0x0, - 0x0, 0x0, 0x3, 0x8a, 0x30, 0x0, 0x0, 0x0, - 0x0, 0x0, 0xaa, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x6, 0x8a, 0x70, 0x0, 0x0, 0x0, 0x1, 0x84, - 0x0, 0x7d, 0x84, 0x10, 0x3, 0x55, 0x0, 0x0, - 0x1, 0x8e, 0x80, 0x11, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, - - /* U+6599 "料" */ - 0x0, 0x2, 0x0, 0x0, 0x0, 0x30, 0x0, 0x0, - 0xc, 0x10, 0x0, 0x0, 0xd2, 0x0, 0x5, 0xb, - 0x9, 0x13, 0x20, 0xc0, 0x0, 0x3, 0x9b, 0x9, - 0x0, 0xd2, 0xc0, 0x0, 0x0, 0x6b, 0x40, 0x0, - 0x40, 0xc0, 0x0, 0x5, 0x5d, 0x5a, 0x31, 0x0, - 0xc0, 0x0, 0x0, 0x2f, 0x10, 0x4, 0x90, 0xc0, - 0x0, 0x0, 0x9e, 0x79, 0x0, 0xa0, 0xc0, 0x10, - 0x1, 0x8b, 0x9, 0x10, 0x0, 0xc6, 0xa0, 0x8, - 0x1b, 0x3, 0x55, 0x55, 0xd0, 0x0, 0x32, 0xb, - 0x0, 0x0, 0x0, 0xc0, 0x0, 0x0, 0xb, 0x0, - 0x0, 0x0, 0xc0, 0x0, 0x0, 0xb, 0x0, 0x0, - 0x0, 0xd0, 0x0, 0x0, 0x1, 0x0, 0x0, 0x0, - 0x10, 0x0, - - /* U+65AD "断" */ - 0x0, 0x0, 0x10, 0x0, 0x0, 0x0, 0x0, 0x8, - 0x20, 0xb2, 0x0, 0x12, 0x6b, 0x70, 0xb, 0x12, - 0xb0, 0x92, 0xc3, 0x10, 0x0, 0xb, 0xb, 0xc1, - 0x90, 0xb0, 0x0, 0x0, 0xb, 0x4, 0xc4, 0x0, - 0xb0, 0x0, 0x0, 0xb, 0x45, 0xe5, 0x93, 0xc5, - 0x57, 0xb1, 0xb, 0x4, 0xf4, 0x0, 0xb0, 0x1a, - 0x0, 0xb, 0x8, 0xc3, 0x90, 0xa0, 0x1a, 0x0, - 0xb, 0x17, 0xb0, 0xa3, 0x90, 0x1a, 0x0, 0xb, - 0x50, 0xb0, 0x4, 0x70, 0x1a, 0x0, 0xb, 0x0, - 0xa1, 0x8, 0x20, 0x1a, 0x0, 0xc, 0x55, 0x59, - 0x66, 0x0, 0x1a, 0x0, 0x0, 0x0, 0x1, 0x60, - 0x0, 0x1a, 0x0, 0x0, 0x0, 0x2, 0x0, 0x0, - 0x0, 0x0, - - /* U+65B0 "新" */ - 0x0, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x4, 0x80, 0x0, 0x0, 0x39, 0xa0, 0x4, 0x55, - 0xb5, 0xb2, 0xb5, 0x41, 0x0, 0x0, 0x61, 0xa, - 0x20, 0xb0, 0x0, 0x0, 0x0, 0x2a, 0x8, 0x0, - 0xb0, 0x0, 0x0, 0x6, 0x57, 0x85, 0x87, 0xb5, - 0x56, 0xc3, 0x0, 0x0, 0xb0, 0x0, 0xb0, 0x1a, - 0x0, 0x3, 0x55, 0xc5, 0xa3, 0xb0, 0x1a, 0x0, - 0x0, 0x10, 0xb0, 0x0, 0xb0, 0x1a, 0x0, 0x0, - 0xd2, 0xb5, 0x41, 0xa0, 0x1a, 0x0, 0x4, 0x60, - 0xb0, 0xc6, 0x40, 0x1a, 0x0, 0x7, 0x22, 0xb0, - 0x28, 0x0, 0x1a, 0x0, 0x10, 0xa, 0x70, 0x60, - 0x0, 0x1a, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, - - /* U+65B7 "斷" */ - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x9, - 0x19, 0x2, 0x70, 0x32, 0x6b, 0x60, 0xb, 0x35, - 0x57, 0x73, 0xc2, 0x0, 0x0, 0xb, 0x4a, 0x16, - 0xa0, 0xb0, 0x0, 0x0, 0xb, 0x25, 0x67, 0x81, - 0xb0, 0x0, 0x10, 0xb, 0x55, 0x75, 0x54, 0xb5, - 0x87, 0x80, 0xb, 0x58, 0x56, 0x90, 0xb0, 0x92, - 0x0, 0xb, 0xa, 0x16, 0x40, 0xb0, 0x92, 0x0, - 0xb, 0x68, 0x79, 0xb1, 0xb0, 0x92, 0x0, 0xb, - 0x18, 0x4, 0x60, 0xa0, 0x92, 0x0, 0xb, 0x48, - 0x8a, 0x92, 0x80, 0x92, 0x0, 0xb, 0x0, 0x36, - 0x47, 0x20, 0x92, 0x0, 0x8, 0x55, 0x55, 0x46, - 0x0, 0x92, 0x0, 0x0, 0x0, 0x0, 0x10, 0x0, - 0x10, 0x0, - - /* U+65B9 "方" */ - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, 0xa5, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x29, 0x0, 0x0, 0x20, 0x16, 0x55, 0x55, - 0x85, 0x55, 0x57, 0xb1, 0x0, 0x0, 0x2, 0xa0, - 0x0, 0x0, 0x0, 0x0, 0x0, 0x4, 0x80, 0x0, - 0x20, 0x0, 0x0, 0x0, 0x6, 0x95, 0x55, 0xe2, - 0x0, 0x0, 0x0, 0xa, 0x10, 0x1, 0xc0, 0x0, - 0x0, 0x0, 0xb, 0x0, 0x3, 0xa0, 0x0, 0x0, - 0x0, 0x73, 0x0, 0x5, 0x80, 0x0, 0x0, 0x2, - 0x80, 0x0, 0x8, 0x50, 0x0, 0x0, 0x28, 0x0, - 0x22, 0xc, 0x20, 0x0, 0x3, 0x50, 0x0, 0x7, - 0xfa, 0x0, 0x0, 0x1, 0x0, 0x0, 0x0, 0x20, - 0x0, 0x0, - - /* U+65BC "於" */ - 0x0, 0x2, 0x0, 0x0, 0x10, 0x0, 0x0, 0x0, - 0x9, 0x30, 0x0, 0x7a, 0x0, 0x0, 0x0, 0x3, - 0x52, 0x10, 0xb8, 0x0, 0x0, 0x16, 0x96, 0x57, - 0x61, 0xb2, 0x60, 0x0, 0x0, 0x92, 0x0, 0x6, - 0x40, 0xa1, 0x0, 0x0, 0x97, 0x59, 0x19, 0x0, - 0x2d, 0x20, 0x0, 0xa2, 0xb, 0x61, 0x63, 0x6, - 0xa0, 0x0, 0xb0, 0xb, 0x10, 0x1b, 0x80, 0x0, - 0x0, 0xb0, 0xb, 0x0, 0x0, 0x30, 0x0, 0x0, - 0xa0, 0x1a, 0x0, 0x0, 0x0, 0x0, 0x5, 0x40, - 0x38, 0x5, 0x95, 0x0, 0x0, 0x8, 0x17, 0xb4, - 0x0, 0x9, 0xe1, 0x0, 0x32, 0x3, 0x60, 0x0, - 0x0, 0x63, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, - - /* U+65BD "施" */ - 0x0, 0x10, 0x0, 0x0, 0x30, 0x0, 0x0, 0x0, - 0x1a, 0x0, 0x0, 0xe2, 0x0, 0x0, 0x0, 0x9, - 0x20, 0x7, 0x92, 0x24, 0x90, 0x15, 0x75, 0x5b, - 0x5b, 0x33, 0x33, 0x30, 0x0, 0xb0, 0x0, 0x71, - 0xd, 0x0, 0x0, 0x0, 0xb0, 0x32, 0x2a, 0xb, - 0x5, 0x20, 0x0, 0xb5, 0xc3, 0xb, 0x1d, 0x6c, - 0x10, 0x0, 0xb0, 0xa2, 0x6d, 0x4b, 0xb, 0x0, - 0x0, 0xb0, 0xb1, 0xb, 0xb, 0xb, 0x0, 0x0, - 0x90, 0xb0, 0xb, 0xb, 0x6c, 0x0, 0x4, 0x50, - 0xb0, 0xb, 0xc, 0x12, 0x50, 0x8, 0x32, 0xc0, - 0xb, 0x3, 0x0, 0x90, 0x23, 0xb, 0x50, 0xc, - 0xaa, 0xaa, 0xd3, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, - - /* U+65C1 "旁" */ - 0x0, 0x0, 0x1, 0x30, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x94, 0x0, 0x3, 0x0, 0x0, 0x65, - 0x65, 0x66, 0x65, 0x78, 0x0, 0x0, 0x0, 0x67, - 0x0, 0x77, 0x0, 0x0, 0x0, 0x20, 0xa, 0x0, - 0x70, 0x2, 0x0, 0x3, 0x95, 0x55, 0x85, 0x55, - 0x5c, 0x60, 0x7, 0x20, 0x0, 0x59, 0x0, 0x14, - 0x10, 0x4, 0x65, 0x57, 0x78, 0x55, 0x57, 0x90, - 0x0, 0x0, 0xb, 0x30, 0x0, 0x30, 0x0, 0x0, - 0x0, 0xd, 0x55, 0x56, 0xd0, 0x0, 0x0, 0x0, - 0x67, 0x0, 0x4, 0x90, 0x0, 0x0, 0x2, 0xa0, - 0x2, 0x8, 0x50, 0x0, 0x1, 0x66, 0x0, 0x2, - 0xcd, 0x0, 0x0, 0x3, 0x0, 0x0, 0x0, 0x10, - 0x0, 0x0, - - /* U+65C5 "旅" */ - 0x0, 0x10, 0x0, 0x1, 0x0, 0x0, 0x0, 0x0, - 0xb, 0x10, 0x7, 0xa0, 0x0, 0x0, 0x0, 0x7, - 0x60, 0xb, 0x20, 0x1, 0x0, 0x15, 0x55, 0x5a, - 0x5b, 0x55, 0x59, 0x60, 0x0, 0xb0, 0x0, 0x62, - 0x0, 0x12, 0x0, 0x0, 0xb0, 0x4, 0x41, 0x27, - 0xa6, 0x0, 0x0, 0xb5, 0x5c, 0xc, 0x52, 0x0, - 0x0, 0x0, 0xb0, 0xa, 0xb, 0x4, 0xb, 0x30, - 0x0, 0xb0, 0x1a, 0xb, 0x8, 0x61, 0x0, 0x2, - 0x90, 0x29, 0xb, 0x8, 0x10, 0x0, 0x7, 0x30, - 0x47, 0xb, 0x2, 0xa0, 0x0, 0x8, 0x16, 0xb3, - 0xb, 0x54, 0x7a, 0x10, 0x41, 0x4, 0x50, 0xe, - 0x40, 0x7, 0xc1, 0x0, 0x0, 0x0, 0x1, 0x0, - 0x0, 0x0, - - /* U+65CF "族" */ - 0x0, 0x10, 0x0, 0x2, 0x0, 0x0, 0x0, 0x0, - 0x48, 0x0, 0xd, 0x0, 0x0, 0x0, 0x0, 0xb, - 0x0, 0x56, 0x0, 0x5, 0x0, 0x25, 0x85, 0x67, - 0x98, 0x55, 0x57, 0x20, 0x0, 0xb0, 0x1, 0x6d, - 0x10, 0x1, 0x0, 0x0, 0xb5, 0x95, 0x58, 0x85, - 0x68, 0x0, 0x0, 0xb0, 0xb0, 0x70, 0xa1, 0x0, - 0x0, 0x0, 0xb0, 0xb1, 0x0, 0xa0, 0x2, 0x10, - 0x0, 0xb0, 0xb5, 0x55, 0xc7, 0x57, 0x50, 0x1, - 0x90, 0xb0, 0x0, 0xa6, 0x0, 0x0, 0x6, 0x30, - 0xb0, 0x7, 0x42, 0x70, 0x0, 0x8, 0x29, 0x90, - 0x48, 0x0, 0x96, 0x0, 0x41, 0x4, 0x26, 0x50, - 0x0, 0xb, 0x90, 0x0, 0x0, 0x20, 0x0, 0x0, - 0x0, 0x0, - - /* U+65E2 "既" */ - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x6, 0x55, - 0x59, 0x25, 0x57, 0x58, 0x70, 0xa1, 0x0, 0xb1, - 0x30, 0xc0, 0x0, 0xa, 0x10, 0xb, 0x2b, 0xc, - 0x0, 0x0, 0xa6, 0x55, 0xb3, 0x70, 0xc0, 0x0, - 0xa, 0x10, 0xb, 0x46, 0xb, 0x0, 0x10, 0xa6, - 0x55, 0xb6, 0x77, 0xb5, 0x77, 0xa, 0x10, 0x4, - 0x0, 0x6c, 0x20, 0x0, 0xa1, 0x14, 0x0, 0xa, - 0xa2, 0x0, 0xa, 0x10, 0x67, 0x2, 0xa9, 0x20, - 0x0, 0xa1, 0x65, 0xd1, 0x91, 0x92, 0x5, 0xb, - 0xc3, 0x3, 0x64, 0x9, 0x20, 0x80, 0x31, 0x0, - 0x53, 0x0, 0x6b, 0xad, 0x0, 0x0, 0x10, 0x0, - 0x0, 0x0, 0x0, - - /* U+65E5 "日" */ - 0x95, 0x55, 0x55, 0x5a, 0x2c, 0x0, 0x0, 0x0, - 0xc0, 0xc0, 0x0, 0x0, 0xc, 0xc, 0x0, 0x0, - 0x0, 0xc0, 0xc0, 0x0, 0x0, 0xc, 0xd, 0x55, - 0x55, 0x55, 0xd0, 0xc0, 0x0, 0x0, 0xc, 0xc, - 0x0, 0x0, 0x0, 0xc0, 0xc0, 0x0, 0x0, 0xc, - 0xc, 0x0, 0x0, 0x0, 0xc0, 0xd5, 0x55, 0x55, - 0x5d, 0xa, 0x0, 0x0, 0x0, 0x90, 0x0, 0x0, - 0x0, 0x0, 0x0, - - /* U+65E6 "旦" */ - 0x0, 0x1, 0x0, 0x0, 0x2, 0x0, 0x0, 0x0, - 0xb6, 0x55, 0x55, 0xd3, 0x0, 0x0, 0xb, 0x10, - 0x0, 0xc, 0x0, 0x0, 0x0, 0xa1, 0x0, 0x0, - 0xc0, 0x0, 0x0, 0xa, 0x65, 0x55, 0x5d, 0x0, - 0x0, 0x0, 0xa1, 0x0, 0x0, 0xc0, 0x0, 0x0, - 0xa, 0x10, 0x0, 0xc, 0x0, 0x0, 0x0, 0xb6, - 0x55, 0x55, 0xd0, 0x0, 0x0, 0xb, 0x10, 0x0, - 0xb, 0x0, 0x0, 0x0, 0x20, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xa, 0x11, - 0x75, 0x55, 0x55, 0x55, 0x55, 0x53, - - /* U+65E9 "早" */ - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0xa5, 0x55, 0x55, 0xc4, 0x0, 0x0, 0xc, 0x0, - 0x0, 0xb, 0x10, 0x0, 0x0, 0xc0, 0x0, 0x0, - 0xb1, 0x0, 0x0, 0xc, 0x55, 0x55, 0x5c, 0x10, - 0x0, 0x0, 0xc0, 0x0, 0x0, 0xb1, 0x0, 0x0, - 0xc, 0x55, 0x75, 0x5c, 0x10, 0x0, 0x0, 0x60, - 0xb, 0x10, 0x40, 0x0, 0x0, 0x0, 0x0, 0xb1, - 0x0, 0x8, 0x1, 0x75, 0x55, 0x5c, 0x65, 0x55, - 0x52, 0x0, 0x0, 0x0, 0xb1, 0x0, 0x0, 0x0, - 0x0, 0x0, 0xb, 0x20, 0x0, 0x0, 0x0, 0x0, - 0x0, 0xc2, 0x0, 0x0, 0x0, 0x0, 0x0, 0x2, - 0x0, 0x0, 0x0, - - /* U+65F6 "时" */ - 0x0, 0x0, 0x0, 0x0, 0x2, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x0, 0xe1, 0x0, 0x85, 0x5a, 0x20, - 0x0, 0xc, 0x0, 0xc, 0x0, 0xc0, 0x0, 0x0, - 0xc0, 0x50, 0xc0, 0xc, 0x46, 0x55, 0x5d, 0x57, - 0x1c, 0x0, 0xc0, 0x0, 0x0, 0xc0, 0x0, 0xc5, - 0x5d, 0x7, 0x40, 0xc, 0x0, 0xc, 0x0, 0xc0, - 0xe, 0x10, 0xc0, 0x0, 0xc0, 0xc, 0x0, 0x60, - 0xc, 0x0, 0xc, 0x0, 0xc0, 0x0, 0x0, 0xc0, - 0x0, 0xc5, 0x5d, 0x0, 0x0, 0xc, 0x0, 0x9, - 0x0, 0x30, 0x0, 0x11, 0xc0, 0x0, 0x0, 0x0, - 0x0, 0x4, 0xd8, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x1, 0x0, 0x0, - - /* U+6607 "昇" */ - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0xc, 0x55, 0x55, 0x55, 0x8b, 0x0, 0x0, 0xc, - 0x0, 0x0, 0x0, 0x47, 0x0, 0x0, 0xd, 0x55, - 0x55, 0x55, 0x87, 0x0, 0x0, 0xc, 0x0, 0x0, - 0x0, 0x47, 0x0, 0x0, 0xc, 0x55, 0x75, 0x55, - 0x75, 0x0, 0x0, 0x2, 0x6a, 0xc2, 0xc, 0x10, - 0x0, 0x0, 0x33, 0x57, 0x0, 0xc, 0x0, 0x0, - 0x0, 0x0, 0x47, 0x0, 0xc, 0x3, 0x70, 0x5, - 0x55, 0x99, 0x55, 0x5d, 0x55, 0x50, 0x0, 0x0, - 0xa2, 0x0, 0xc, 0x0, 0x0, 0x0, 0x3, 0x80, - 0x0, 0xc, 0x0, 0x0, 0x0, 0x57, 0x0, 0x0, - 0xd, 0x0, 0x0, 0x3, 0x0, 0x0, 0x0, 0x3, - 0x0, 0x0, - - /* U+660E "明" */ - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x10, - 0x95, 0x55, 0xc2, 0xc5, 0x5d, 0xa, 0x10, 0xb, - 0xb, 0x0, 0xb0, 0xa1, 0x0, 0xb0, 0xb0, 0xb, - 0xa, 0x65, 0x5c, 0xc, 0x55, 0xb0, 0xa1, 0x0, - 0xb0, 0xb0, 0xb, 0xb, 0x0, 0xb, 0xb, 0x0, - 0xb0, 0xb3, 0x33, 0xc0, 0xc5, 0x5c, 0xc, 0x11, - 0x1b, 0xb, 0x0, 0x51, 0xb0, 0x0, 0xb0, 0x0, - 0x0, 0x84, 0x0, 0xb, 0x0, 0x0, 0x47, 0x0, - 0x10, 0xc0, 0x0, 0x44, 0x0, 0x4, 0xcc, 0x0, - 0x11, 0x0, 0x0, 0x1, 0x0, - - /* U+6613 "易" */ - 0x0, 0x0, 0x0, 0x0, 0x1, 0x0, 0x0, 0x1b, - 0x55, 0x55, 0x5d, 0x0, 0x0, 0x1b, 0x0, 0x0, - 0xc, 0x0, 0x0, 0x1c, 0x55, 0x55, 0x5c, 0x0, - 0x0, 0x1b, 0x0, 0x0, 0xc, 0x0, 0x0, 0x1c, - 0x85, 0x55, 0x5b, 0x0, 0x0, 0x7, 0xa0, 0x0, - 0x0, 0x11, 0x0, 0x2b, 0x5b, 0x75, 0xc5, 0xa8, - 0x2, 0x90, 0x3b, 0x6, 0x70, 0x93, 0x4, 0x1, - 0xb1, 0xc, 0x10, 0xc0, 0x0, 0x48, 0x10, 0x95, - 0x0, 0xc0, 0x4, 0x20, 0x19, 0x51, 0x4, 0x90, - 0x0, 0x15, 0x61, 0x1, 0xae, 0x20, 0x0, 0x20, - 0x0, 0x0, 0x0, 0x0, - - /* U+6614 "昔" */ - 0x0, 0x0, 0x10, 0x0, 0x20, 0x0, 0x0, 0x0, - 0x0, 0x76, 0x0, 0xc2, 0x0, 0x0, 0x0, 0x0, - 0x74, 0x0, 0xc0, 0x36, 0x0, 0x2, 0x65, 0xa8, - 0x55, 0xd5, 0x55, 0x0, 0x0, 0x0, 0x74, 0x0, - 0xc0, 0x0, 0x0, 0x15, 0x55, 0xa8, 0x55, 0xd5, - 0x5b, 0x80, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, 0xc, 0x55, 0x55, 0x5a, 0x70, 0x0, - 0x0, 0xc, 0x0, 0x0, 0x8, 0x40, 0x0, 0x0, - 0xc, 0x55, 0x55, 0x5a, 0x40, 0x0, 0x0, 0xc, - 0x0, 0x0, 0x8, 0x40, 0x0, 0x0, 0xc, 0x0, - 0x0, 0x8, 0x40, 0x0, 0x0, 0xc, 0x55, 0x55, - 0x5a, 0x40, 0x0, 0x0, 0x1, 0x0, 0x0, 0x0, - 0x0, 0x0, - - /* U+661F "星" */ - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0xc, 0x55, 0x55, 0x55, 0x8a, 0x0, 0x0, 0xc, - 0x0, 0x0, 0x0, 0x57, 0x0, 0x0, 0xd, 0x55, - 0x55, 0x55, 0x87, 0x0, 0x0, 0xc, 0x0, 0x0, - 0x0, 0x57, 0x0, 0x0, 0xb, 0x55, 0x65, 0x55, - 0x86, 0x0, 0x0, 0x9, 0x20, 0x2b, 0x0, 0x0, - 0x0, 0x0, 0x1e, 0x55, 0x6b, 0x55, 0x6d, 0x20, - 0x0, 0x82, 0x0, 0x29, 0x0, 0x0, 0x0, 0x2, - 0x50, 0x0, 0x29, 0x0, 0x82, 0x0, 0x3, 0x5, - 0x55, 0x6b, 0x55, 0x53, 0x0, 0x0, 0x0, 0x0, - 0x29, 0x0, 0x0, 0x40, 0x6, 0x55, 0x55, 0x57, - 0x55, 0x56, 0x92, - - /* U+6620 "映" */ - 0x0, 0x0, 0x0, 0x2, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, 0xb2, 0x0, 0x0, 0x75, 0x59, 0x0, - 0xb, 0x0, 0x0, 0xb, 0x0, 0xb0, 0xb5, 0xc5, - 0x5c, 0x0, 0xb0, 0xb, 0xa, 0xb, 0x0, 0xa0, - 0xb, 0x0, 0xb0, 0xa0, 0xb0, 0xa, 0x0, 0xb5, - 0x5b, 0xa, 0xb, 0x0, 0xa0, 0xb, 0x0, 0xb5, - 0xa5, 0xc5, 0x5b, 0xb1, 0xb0, 0xb, 0x0, 0x28, - 0x50, 0x0, 0xb, 0x0, 0xb0, 0x8, 0x46, 0x10, - 0x0, 0xb5, 0x5b, 0x1, 0xa0, 0x1a, 0x0, 0x9, - 0x0, 0x1, 0xa1, 0x0, 0x6a, 0x0, 0x0, 0x5, - 0x70, 0x0, 0x0, 0x8d, 0x10, 0x2, 0x10, 0x0, - 0x0, 0x0, 0x0, - - /* U+6625 "春" */ - 0x0, 0x0, 0x0, 0x30, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, 0xf3, 0x0, 0x1, 0x0, 0x2, 0x55, - 0x56, 0xe5, 0x55, 0x5a, 0x30, 0x0, 0x0, 0x5, - 0x70, 0x0, 0x60, 0x0, 0x0, 0x55, 0x5d, 0x65, - 0x55, 0x51, 0x0, 0x5, 0x55, 0x6c, 0x55, 0x55, - 0x57, 0xc1, 0x0, 0x1, 0xb1, 0x0, 0x7, 0x0, - 0x0, 0x0, 0x1a, 0x61, 0x11, 0x18, 0x90, 0x0, - 0x4, 0x70, 0xd3, 0x33, 0x3d, 0x3c, 0xa3, 0x11, - 0x0, 0xc0, 0x0, 0xc, 0x0, 0x40, 0x0, 0x0, - 0xd5, 0x55, 0x5c, 0x0, 0x0, 0x0, 0x0, 0xc0, - 0x0, 0xc, 0x0, 0x0, 0x0, 0x0, 0xd5, 0x55, - 0x5c, 0x0, 0x0, 0x0, 0x0, 0x10, 0x0, 0x1, - 0x0, 0x0, - - /* U+6628 "昨" */ - 0x0, 0x0, 0x0, 0x20, 0x0, 0x0, 0x0, 0x0, - 0x0, 0xa, 0x70, 0x0, 0x0, 0x85, 0x5b, 0x20, - 0xd0, 0x0, 0x0, 0xb, 0x0, 0xb0, 0x4a, 0x75, - 0x57, 0xb0, 0xb0, 0xb, 0x9, 0xc, 0x0, 0x0, - 0xb, 0x0, 0xb3, 0x40, 0xc0, 0x0, 0x0, 0xb5, - 0x5c, 0x20, 0xd, 0x55, 0xa2, 0xb, 0x0, 0xb0, - 0x0, 0xc0, 0x0, 0x0, 0xb0, 0xb, 0x0, 0xc, - 0x0, 0x33, 0xb, 0x0, 0xb0, 0x0, 0xd5, 0x56, - 0x50, 0xb5, 0x5d, 0x0, 0xc, 0x0, 0x0, 0xa, - 0x0, 0x40, 0x0, 0xc0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0xc, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x10, 0x0, 0x0, - - /* U+662F "是" */ - 0x0, 0x0, 0x0, 0x0, 0x1, 0x0, 0x0, 0x0, - 0x0, 0xd5, 0x55, 0x5c, 0x50, 0x0, 0x0, 0x0, - 0xc0, 0x0, 0xa, 0x20, 0x0, 0x0, 0x0, 0xd5, - 0x55, 0x5c, 0x20, 0x0, 0x0, 0x0, 0xc0, 0x0, - 0xa, 0x20, 0x0, 0x0, 0x0, 0xd5, 0x55, 0x5b, - 0x20, 0x0, 0x0, 0x0, 0x20, 0x0, 0x0, 0x7, - 0x30, 0x4, 0x65, 0x75, 0x5d, 0x55, 0x55, 0x40, - 0x0, 0x4, 0xd0, 0xc, 0x0, 0x22, 0x0, 0x0, - 0x8, 0x60, 0xd, 0x55, 0x65, 0x0, 0x0, 0xb, - 0x45, 0xc, 0x0, 0x0, 0x0, 0x0, 0x92, 0x5, - 0xbd, 0x20, 0x0, 0x0, 0x5, 0x30, 0x0, 0x17, - 0xbd, 0xef, 0x90, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, - - /* U+663C "昼" */ - 0x0, 0x8, 0x55, 0x55, 0x55, 0xb0, 0x0, 0x0, - 0xb, 0x0, 0x0, 0x0, 0xa0, 0x0, 0x0, 0xc, - 0x55, 0x55, 0x65, 0xb0, 0x0, 0x0, 0xb, 0x0, - 0x0, 0x42, 0x10, 0x0, 0x0, 0x39, 0x0, 0x0, - 0x9, 0x20, 0x0, 0x0, 0x98, 0x75, 0x55, 0x5d, - 0xa7, 0x0, 0x2, 0x67, 0x30, 0x0, 0xa, 0x6, - 0xb0, 0x16, 0x7, 0x75, 0x55, 0x5b, 0x0, 0x0, - 0x10, 0x7, 0x30, 0x0, 0xa, 0x0, 0x0, 0x0, - 0x7, 0x75, 0x55, 0x5b, 0x0, 0x0, 0x0, 0x1, - 0x0, 0x0, 0x0, 0x8, 0x0, 0x3, 0x55, 0x55, - 0x55, 0x55, 0x56, 0x30, - - /* U+6642 "時" */ - 0x0, 0x0, 0x0, 0x2, 0x0, 0x0, 0x1, 0x0, - 0x20, 0x0, 0xb2, 0x0, 0x0, 0xc5, 0x5d, 0x10, - 0xb, 0x0, 0x30, 0xb, 0x0, 0xb0, 0x55, 0xc5, - 0x57, 0x0, 0xb0, 0xb, 0x0, 0xb, 0x0, 0x0, - 0xb, 0x0, 0xb5, 0x55, 0xd5, 0x57, 0xa0, 0xb5, - 0x5b, 0x0, 0x0, 0x9, 0x10, 0xb, 0x0, 0xb4, - 0x55, 0x55, 0xc5, 0xa0, 0xb0, 0xb, 0x14, 0x10, - 0xb, 0x0, 0xb, 0x0, 0xb0, 0xc, 0x10, 0xb0, - 0x0, 0xc5, 0x5c, 0x0, 0x41, 0xb, 0x0, 0x8, - 0x0, 0x30, 0x0, 0x0, 0xb0, 0x0, 0x0, 0x0, - 0x0, 0x5, 0xac, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x3, 0x10, 0x0, - - /* U+6669 "晩" */ - 0x0, 0x0, 0x0, 0x30, 0x0, 0x0, 0x0, 0x0, - 0x0, 0xd, 0x20, 0x0, 0x0, 0xb5, 0x5c, 0x4, - 0xb5, 0x6b, 0x10, 0xb, 0x1, 0x90, 0xa0, 0x8, - 0x40, 0x0, 0xb0, 0x19, 0x7a, 0x56, 0x85, 0x92, - 0xb, 0x1, 0xb2, 0xb0, 0x91, 0xb, 0x0, 0xc5, - 0x69, 0xb, 0x9, 0x10, 0xb0, 0xb, 0x1, 0x90, - 0xd5, 0xb6, 0x5c, 0x0, 0xb0, 0x19, 0x4, 0x17, - 0xc0, 0x10, 0xb, 0x1, 0xa0, 0x4, 0x4c, 0x0, - 0x0, 0xd5, 0x6a, 0x0, 0x90, 0xc0, 0x4, 0x6, - 0x0, 0x0, 0x65, 0xc, 0x0, 0x60, 0x0, 0x0, - 0x64, 0x0, 0xba, 0x9d, 0x10, 0x0, 0x10, 0x0, - 0x0, 0x0, 0x0, - - /* U+666E "普" */ - 0x0, 0x0, 0x40, 0x0, 0x22, 0x0, 0x0, 0x0, - 0x4, 0xb0, 0x8, 0x30, 0x0, 0x2, 0x55, 0x5d, - 0x55, 0x95, 0x7c, 0x10, 0x1, 0x0, 0xc0, 0x2a, - 0x5, 0x0, 0x0, 0xa, 0xc, 0x2, 0xa1, 0xb0, - 0x0, 0x0, 0x75, 0xc0, 0x2a, 0x71, 0x0, 0x35, - 0x56, 0x5d, 0x56, 0xb7, 0x5c, 0x70, 0x0, 0x10, - 0x0, 0x0, 0x20, 0x0, 0x0, 0xa, 0x65, 0x55, - 0x5d, 0x30, 0x0, 0x0, 0x92, 0x0, 0x0, 0xc0, - 0x0, 0x0, 0x9, 0x65, 0x55, 0x5d, 0x0, 0x0, - 0x0, 0x92, 0x0, 0x0, 0xc0, 0x0, 0x0, 0xa, - 0x65, 0x55, 0x5d, 0x0, 0x0, 0x0, 0x20, 0x0, - 0x0, 0x10, 0x0, - - /* U+666F "景" */ - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0xb, 0x55, 0x55, 0x55, 0xd1, 0x0, 0x0, 0xc, - 0x55, 0x55, 0x55, 0xd0, 0x0, 0x0, 0xc, 0x0, - 0x0, 0x0, 0xc0, 0x0, 0x0, 0xb, 0x55, 0x88, - 0x55, 0xa0, 0x0, 0x3, 0x33, 0x33, 0x3c, 0x33, - 0x35, 0xa0, 0x3, 0x24, 0x22, 0x22, 0x22, 0x62, - 0x20, 0x0, 0x8, 0x85, 0x55, 0x56, 0xc0, 0x0, - 0x0, 0x8, 0x40, 0x0, 0x1, 0xa0, 0x0, 0x0, - 0x6, 0x65, 0x6c, 0x55, 0x70, 0x0, 0x0, 0x1, - 0xc2, 0x1a, 0x5, 0x40, 0x0, 0x0, 0x59, 0x20, - 0x1a, 0x0, 0x6c, 0x20, 0x15, 0x20, 0x5, 0xa8, - 0x0, 0x4, 0x70, 0x0, 0x0, 0x0, 0x40, 0x0, - 0x0, 0x0, - - /* U+6674 "晴" */ - 0x0, 0x0, 0x0, 0x3, 0x0, 0x0, 0x0, 0x0, - 0x10, 0x0, 0xb3, 0x2, 0x10, 0xb5, 0x5d, 0x35, - 0x5c, 0x55, 0x64, 0xb, 0x0, 0xb0, 0x0, 0xb1, - 0x6, 0x0, 0xb0, 0xb, 0x5, 0x5c, 0x65, 0x51, - 0xb, 0x33, 0xb5, 0x55, 0xb5, 0x55, 0xa0, 0xb2, - 0x2b, 0x2, 0x0, 0x0, 0x40, 0xb, 0x0, 0xb0, - 0xb5, 0x55, 0x5c, 0x0, 0xb0, 0xb, 0xb, 0x55, - 0x55, 0xb0, 0xb, 0x33, 0xb0, 0xb0, 0x0, 0xb, - 0x0, 0xb2, 0x2b, 0xb, 0x55, 0x55, 0xb0, 0x5, - 0x0, 0x10, 0xb0, 0x0, 0xb, 0x0, 0x0, 0x0, - 0xb, 0x0, 0x49, 0xa0, 0x0, 0x0, 0x0, 0x30, - 0x0, 0x41, 0x0, - - /* U+667A "智" */ - 0x0, 0x40, 0x0, 0x0, 0x0, 0x0, 0x1, 0xb0, - 0x3, 0x1, 0x0, 0x1, 0x6, 0x69, 0x86, 0x1b, - 0x55, 0x79, 0x5, 0x7, 0x30, 0xb, 0x0, 0x37, - 0x55, 0x5b, 0x57, 0x6b, 0x0, 0x37, 0x0, 0xb, - 0x74, 0xb, 0x55, 0x78, 0x0, 0x74, 0xa, 0x6b, - 0x0, 0x36, 0x5, 0x43, 0x0, 0x21, 0x4, 0x0, - 0x31, 0xd, 0x55, 0x55, 0x5d, 0x20, 0x0, 0xb, - 0x0, 0x0, 0xb, 0x0, 0x0, 0xc, 0x55, 0x55, - 0x5c, 0x0, 0x0, 0xb, 0x0, 0x0, 0xb, 0x0, - 0x0, 0xd, 0x55, 0x55, 0x5c, 0x0, 0x0, 0x1, - 0x0, 0x0, 0x1, 0x0, - - /* U+6687 "暇" */ - 0x0, 0x11, 0x75, 0x83, 0x55, 0x92, 0xb, 0x5c, - 0x49, 0xa, 0x0, 0xa, 0x0, 0xa0, 0xa1, 0x90, - 0xa0, 0x0, 0xa0, 0xa, 0xa, 0x1b, 0x5c, 0x15, - 0x5c, 0x0, 0xb5, 0xc1, 0x90, 0x40, 0x0, 0x10, - 0xa, 0xa, 0x19, 0x3, 0x45, 0x58, 0x30, 0xa0, - 0xa1, 0xb5, 0x40, 0x40, 0xb1, 0xa, 0xa, 0x19, - 0x2, 0x5, 0x1b, 0x0, 0xb5, 0xc2, 0xb5, 0x71, - 0x69, 0x30, 0x7, 0x1, 0x19, 0x0, 0x4, 0xe0, - 0x0, 0x0, 0x1, 0x90, 0x3, 0x84, 0xc3, 0x0, - 0x0, 0x28, 0x4, 0x40, 0x4, 0xa2, 0x0, 0x0, - 0x0, 0x0, 0x0, 0x0, 0x0, - - /* U+6691 "暑" */ - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0xb, 0x55, 0x55, 0x56, 0xc0, 0x0, 0x0, 0xc, - 0x55, 0x55, 0x56, 0xa0, 0x0, 0x0, 0xc, 0x0, - 0x0, 0x2, 0xa0, 0x0, 0x0, 0xb, 0x55, 0xd6, - 0x56, 0x8b, 0x10, 0x0, 0x15, 0x55, 0xd6, 0xa3, - 0xc4, 0x0, 0x0, 0x0, 0x0, 0xc0, 0x6b, 0x11, - 0x50, 0x6, 0x55, 0x55, 0x9d, 0x85, 0x56, 0x70, - 0x0, 0x0, 0x7a, 0xc6, 0x55, 0x90, 0x0, 0x0, - 0x58, 0xd0, 0x0, 0x0, 0xc0, 0x0, 0x23, 0x0, - 0xd5, 0x55, 0x55, 0xc0, 0x0, 0x0, 0x0, 0xc0, - 0x0, 0x0, 0xc0, 0x0, 0x0, 0x0, 0xd5, 0x55, - 0x55, 0xc0, 0x0, 0x0, 0x0, 0x10, 0x0, 0x0, - 0x0, 0x0, - - /* U+6696 "暖" */ - 0x0, 0x0, 0x0, 0x0, 0x0, 0x20, 0x0, 0x0, - 0x1, 0x45, 0x68, 0xab, 0x30, 0xb5, 0x5d, 0x23, - 0x6, 0x2, 0x90, 0xb, 0x0, 0xb0, 0x93, 0x74, - 0x73, 0x0, 0xb0, 0xb, 0x28, 0x66, 0x58, 0x95, - 0xb, 0x0, 0xb0, 0x4, 0x70, 0x0, 0x0, 0xc5, - 0x5b, 0x46, 0x98, 0x55, 0x5b, 0x1b, 0x0, 0xb0, - 0xa, 0x10, 0x0, 0x0, 0xb0, 0xb, 0x0, 0xc6, - 0x56, 0xd0, 0xb, 0x0, 0xb0, 0x64, 0x70, 0xb3, - 0x0, 0xc5, 0x5b, 0x19, 0x3, 0xc5, 0x0, 0xa, - 0x0, 0x7, 0x0, 0x8a, 0xa1, 0x0, 0x0, 0x3, - 0x3, 0x82, 0x5, 0xda, 0x20, 0x0, 0x0, 0x20, - 0x0, 0x0, 0x20, - - /* U+6697 "暗" */ - 0x0, 0x0, 0x0, 0x3, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x85, 0x0, 0x0, 0xb5, 0x5d, 0x16, - 0x56, 0x75, 0x93, 0xc, 0x0, 0xb0, 0x23, 0x0, - 0xa3, 0x0, 0xb0, 0xb, 0x0, 0xc1, 0xa, 0x0, - 0xb, 0x0, 0xb1, 0x26, 0x26, 0x32, 0x80, 0xc5, - 0x5b, 0x33, 0x33, 0x33, 0x33, 0xb, 0x0, 0xb0, - 0x75, 0x55, 0x5a, 0x0, 0xb0, 0xb, 0xb, 0x0, - 0x0, 0xb0, 0xb, 0x0, 0xb0, 0xb5, 0x55, 0x5b, - 0x0, 0xc5, 0x5b, 0xb, 0x0, 0x0, 0xb0, 0x4, - 0x0, 0x10, 0xb5, 0x55, 0x5c, 0x0, 0x0, 0x0, - 0xb, 0x0, 0x0, 0xa0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x0, - - /* U+66C7 "曇" */ - 0x0, 0x10, 0x0, 0x0, 0x4, 0x0, 0x0, 0xa, - 0x55, 0x55, 0x55, 0xc1, 0x0, 0x0, 0xa5, 0x55, - 0x55, 0x5b, 0x0, 0x0, 0xa, 0x55, 0x55, 0x55, - 0xb0, 0x0, 0x0, 0x53, 0x33, 0x33, 0x39, 0x20, - 0x0, 0x32, 0x11, 0xa2, 0x11, 0x11, 0x40, 0x39, - 0x77, 0x6b, 0x56, 0x77, 0x5c, 0x28, 0x27, 0x72, - 0x91, 0x37, 0x62, 0x0, 0x0, 0x11, 0x13, 0x11, - 0x44, 0x0, 0x0, 0x4, 0x43, 0x33, 0x33, 0x33, - 0x30, 0x55, 0x55, 0x79, 0x55, 0x55, 0x66, 0x0, - 0x0, 0x29, 0x20, 0x6, 0x40, 0x0, 0x0, 0x8d, - 0x98, 0x76, 0x5c, 0x30, 0x0, 0x2, 0x20, 0x0, - 0x0, 0x10, 0x0, - - /* U+66DC "曜" */ - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x2, 0x0, - 0x34, 0x65, 0xb4, 0x65, 0xb0, 0xc5, 0x6b, 0x37, - 0xa, 0x26, 0xa, 0xb, 0x1, 0x90, 0x60, 0xa0, - 0x61, 0xa0, 0xb0, 0x19, 0x16, 0x5a, 0x37, 0x5b, - 0xb, 0x56, 0xa9, 0x22, 0x69, 0x10, 0x60, 0xb0, - 0x19, 0x8, 0x60, 0xc2, 0x12, 0xb, 0x1, 0x91, - 0xc5, 0x5c, 0x56, 0x60, 0xb0, 0x19, 0x7c, 0x22, - 0xb2, 0x80, 0xb, 0x56, 0xb1, 0xc3, 0x3b, 0x33, - 0x10, 0xb0, 0x13, 0xc, 0x55, 0xc5, 0xa2, 0x2, - 0x0, 0x0, 0xb0, 0xa, 0x0, 0x30, 0x0, 0x0, - 0xd, 0x55, 0x75, 0x68, 0x0, 0x0, 0x0, 0x10, - 0x0, 0x0, 0x0, - - /* U+66F2 "曲" */ - 0x0, 0x3, 0x0, 0x30, 0x0, 0x0, 0x0, 0xc1, - 0xc, 0x10, 0x0, 0x0, 0xb, 0x0, 0xb0, 0x0, - 0x8, 0x55, 0xc5, 0x5c, 0x55, 0xa1, 0xd0, 0xb, - 0x0, 0xb0, 0xc, 0xc, 0x0, 0xb0, 0xb, 0x0, - 0xc0, 0xc0, 0xb, 0x0, 0xb0, 0xc, 0xc, 0x55, - 0xc5, 0x5c, 0x55, 0xc0, 0xc0, 0xb, 0x0, 0xb0, - 0xc, 0xc, 0x0, 0xb0, 0xb, 0x0, 0xc0, 0xc0, - 0xb, 0x0, 0xb0, 0xc, 0xc, 0x55, 0xb5, 0x5b, - 0x55, 0xd0, 0xc0, 0x0, 0x0, 0x0, 0x9, 0x0, - 0x0, 0x0, 0x0, 0x0, 0x0, - - /* U+66F4 "更" */ - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x4, - 0x55, 0x55, 0x56, 0x55, 0x56, 0xc1, 0x0, 0x0, - 0x0, 0xc, 0x0, 0x0, 0x0, 0x0, 0x19, 0x55, - 0x5d, 0x55, 0x5b, 0x0, 0x0, 0x1b, 0x0, 0xc, - 0x0, 0x1a, 0x0, 0x0, 0xc, 0x55, 0x5d, 0x55, - 0x6a, 0x0, 0x0, 0xb, 0x0, 0xc, 0x0, 0x1a, - 0x0, 0x0, 0x1c, 0x55, 0x5d, 0x55, 0x6a, 0x0, - 0x0, 0x5, 0x10, 0x38, 0x0, 0x4, 0x0, 0x0, - 0x0, 0x33, 0x75, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x7, 0xd0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x3a, - 0x7b, 0x62, 0x0, 0x0, 0x1, 0x57, 0x50, 0x1, - 0x6a, 0xdd, 0xe4, 0x2, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, - - /* U+66F8 "書" */ - 0x0, 0x0, 0x1, 0x20, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x2b, 0x0, 0x20, 0x0, 0x0, 0x45, 0x56, - 0xb5, 0x5c, 0x41, 0x3, 0x65, 0x55, 0x6b, 0x55, - 0xb7, 0x90, 0x0, 0x45, 0x56, 0xb5, 0x5b, 0x10, - 0x0, 0x0, 0x0, 0x29, 0x0, 0x32, 0x0, 0x3, - 0x55, 0x56, 0xb5, 0x56, 0x60, 0x4, 0x55, 0x55, - 0x69, 0x55, 0x58, 0x80, 0x0, 0x85, 0x55, 0x55, - 0x59, 0x20, 0x0, 0xc, 0x0, 0x0, 0x0, 0xa1, - 0x0, 0x0, 0xd5, 0x55, 0x55, 0x5c, 0x10, 0x0, - 0xc, 0x0, 0x0, 0x0, 0xa1, 0x0, 0x0, 0xd5, - 0x55, 0x55, 0x5c, 0x10, 0x0, 0x2, 0x0, 0x0, - 0x0, 0x20, 0x0, - - /* U+66FE "曾" */ - 0x0, 0x20, 0x0, 0x11, 0x0, 0x0, 0x3a, 0x0, - 0x96, 0x0, 0x20, 0x7, 0x2, 0x60, 0x12, 0xb5, - 0x55, 0xb6, 0x55, 0x88, 0xb0, 0x82, 0x91, 0x59, - 0x56, 0xb0, 0x39, 0x92, 0x80, 0x56, 0xb5, 0x56, - 0xb7, 0x55, 0x86, 0x60, 0x0, 0x0, 0x0, 0x22, - 0x9, 0x55, 0x55, 0x5b, 0x40, 0x9, 0x10, 0x0, - 0x9, 0x10, 0x9, 0x65, 0x55, 0x5b, 0x10, 0x9, - 0x10, 0x0, 0x9, 0x20, 0x9, 0x55, 0x55, 0x5b, - 0x20, 0x0, 0x0, 0x0, 0x0, 0x0, - - /* U+66FF "替" */ - 0x0, 0x3, 0x0, 0x1, 0x20, 0x0, 0x0, 0xd, - 0x10, 0x2, 0xb0, 0x0, 0x5, 0x5d, 0x77, 0x46, - 0xb7, 0x70, 0x0, 0xb, 0x1, 0x3, 0x80, 0x20, - 0x25, 0x7b, 0x65, 0x59, 0xb5, 0x73, 0x0, 0x86, - 0x90, 0xa, 0x17, 0x0, 0x4, 0x60, 0x55, 0x81, - 0x5, 0xa4, 0x43, 0x75, 0x59, 0x55, 0x5a, 0x42, - 0x0, 0xc0, 0x0, 0x0, 0x2a, 0x0, 0x0, 0xc0, - 0x0, 0x0, 0x29, 0x0, 0x0, 0xc5, 0x55, 0x55, - 0x69, 0x0, 0x0, 0xc0, 0x0, 0x0, 0x2a, 0x0, - 0x0, 0xc5, 0x55, 0x55, 0x6a, 0x0, 0x0, 0x20, - 0x0, 0x0, 0x0, 0x0, - - /* U+6700 "最" */ - 0x0, 0x1, 0x0, 0x0, 0x0, 0x30, 0x0, 0x0, - 0x6, 0x85, 0x55, 0x55, 0xd2, 0x0, 0x0, 0x6, - 0x95, 0x55, 0x55, 0xd0, 0x0, 0x0, 0x6, 0x60, - 0x0, 0x0, 0xc0, 0x0, 0x0, 0x6, 0x95, 0x55, - 0x55, 0xd0, 0x0, 0x4, 0x56, 0x55, 0x55, 0x55, - 0x58, 0xd1, 0x0, 0x29, 0x0, 0xb0, 0x0, 0x3, - 0x0, 0x0, 0x2b, 0x55, 0xc4, 0x85, 0x5d, 0x30, - 0x0, 0x2b, 0x55, 0xc0, 0x50, 0x39, 0x0, 0x0, - 0x29, 0x0, 0xb0, 0x28, 0xb1, 0x0, 0x0, 0x2b, - 0x67, 0xd5, 0x1a, 0x90, 0x0, 0xa, 0xc7, 0x30, - 0xb0, 0x56, 0x99, 0x10, 0x0, 0x0, 0x0, 0xb5, - 0x30, 0x6, 0xb2, 0x0, 0x0, 0x0, 0x10, 0x0, - 0x0, 0x0, - - /* U+6703 "會" */ - 0x0, 0x0, 0x0, 0x1, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, 0xba, 0x0, 0x0, 0x0, 0x0, 0x0, - 0xa, 0x71, 0x60, 0x0, 0x0, 0x0, 0x1, 0xa5, - 0x0, 0x5a, 0x61, 0x0, 0x0, 0x57, 0x25, 0x55, - 0x51, 0x6c, 0xb1, 0x4, 0xb, 0x55, 0x59, 0x55, - 0xb3, 0x0, 0x0, 0xb, 0x57, 0xb, 0x56, 0x91, - 0x0, 0x0, 0xb, 0x6, 0xb, 0x60, 0x91, 0x0, - 0x0, 0x8, 0x55, 0x55, 0x56, 0x70, 0x0, 0x0, - 0x3, 0xa5, 0x55, 0x5c, 0x30, 0x0, 0x0, 0x2, - 0xb5, 0x55, 0x5c, 0x10, 0x0, 0x0, 0x2, 0x90, - 0x0, 0xa, 0x10, 0x0, 0x0, 0x3, 0xb5, 0x55, - 0x5c, 0x10, 0x0, 0x0, 0x1, 0x30, 0x0, 0x4, - 0x0, 0x0, - - /* U+6708 "月" */ - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xa5, - 0x55, 0x55, 0xc1, 0x0, 0xc, 0x0, 0x0, 0xc, - 0x0, 0x0, 0xc0, 0x0, 0x0, 0xc0, 0x0, 0xd, - 0x55, 0x55, 0x5c, 0x0, 0x0, 0xc0, 0x0, 0x0, - 0xc0, 0x0, 0xc, 0x0, 0x0, 0xc, 0x0, 0x0, - 0xd5, 0x55, 0x55, 0xc0, 0x0, 0x2a, 0x0, 0x0, - 0xc, 0x0, 0x5, 0x70, 0x0, 0x0, 0xc0, 0x0, - 0xa1, 0x0, 0x0, 0xc, 0x0, 0x37, 0x0, 0x1, - 0x11, 0xd0, 0x26, 0x0, 0x0, 0x5, 0xe9, 0x2, - 0x0, 0x0, 0x0, 0x1, 0x0, - - /* U+6709 "有" */ - 0x0, 0x0, 0x0, 0x40, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, 0xe3, 0x0, 0x0, 0x0, 0x15, 0x55, - 0x58, 0xc5, 0x55, 0x5a, 0xc1, 0x1, 0x0, 0xc, - 0x10, 0x0, 0x0, 0x0, 0x0, 0x0, 0x77, 0x0, - 0x0, 0x40, 0x0, 0x0, 0x2, 0xe5, 0x55, 0x55, - 0xe0, 0x0, 0x0, 0x19, 0xc0, 0x0, 0x0, 0xc0, - 0x0, 0x1, 0x80, 0xc5, 0x55, 0x55, 0xc0, 0x0, - 0x15, 0x0, 0xc0, 0x0, 0x0, 0xc0, 0x0, 0x0, - 0x0, 0xd5, 0x55, 0x55, 0xc0, 0x0, 0x0, 0x0, - 0xc0, 0x0, 0x0, 0xc0, 0x0, 0x0, 0x0, 0xc0, - 0x0, 0x0, 0xc0, 0x0, 0x0, 0x0, 0xc0, 0x0, - 0x5c, 0x90, 0x0, 0x0, 0x0, 0x10, 0x0, 0x2, - 0x0, 0x0, - - /* U+670B "朋" */ - 0x0, 0x75, 0x59, 0x20, 0x85, 0x59, 0x20, 0xb, - 0x0, 0xb0, 0xb, 0x0, 0xb0, 0x0, 0xb0, 0xb, - 0x0, 0xb0, 0xb, 0x0, 0xc, 0x55, 0xc0, 0xc, - 0x55, 0xc0, 0x0, 0xb0, 0xb, 0x0, 0xb0, 0xb, - 0x0, 0xb, 0x0, 0xb0, 0xb, 0x0, 0xb0, 0x0, - 0xc5, 0x5c, 0x0, 0xc5, 0x5c, 0x0, 0xa, 0x0, - 0xb0, 0xa, 0x0, 0xb0, 0x0, 0xa0, 0xb, 0x3, - 0x70, 0xb, 0x0, 0x36, 0x0, 0xb0, 0x82, 0x0, - 0xb0, 0x7, 0x2, 0x6d, 0x18, 0x0, 0xc, 0x1, - 0x40, 0x4, 0x66, 0x0, 0x4c, 0xd0, 0x0, 0x0, - 0x1, 0x0, 0x0, 0x10, 0x0, - - /* U+670D "服" */ - 0x0, 0x95, 0x5a, 0x9, 0x55, 0x5a, 0x10, 0x0, - 0xb0, 0xb, 0xb, 0x0, 0xc, 0x0, 0x0, 0xb0, - 0xb, 0xb, 0x0, 0xc, 0x0, 0x0, 0xc5, 0x5b, - 0xb, 0x4, 0x89, 0x0, 0x0, 0xb0, 0xb, 0xb, - 0x0, 0x51, 0x0, 0x0, 0xb0, 0xb, 0xc, 0x65, - 0x5a, 0x50, 0x0, 0xc5, 0x5b, 0xb, 0x42, 0xc, - 0x0, 0x0, 0xb0, 0xb, 0xb, 0x7, 0x29, 0x0, - 0x0, 0xa0, 0xb, 0xb, 0x6, 0xb2, 0x0, 0x4, - 0x60, 0xb, 0xb, 0x4, 0xd1, 0x0, 0x8, 0x2, - 0x1b, 0xb, 0x37, 0x1c, 0x61, 0x14, 0x1, 0xc7, - 0xd, 0x30, 0x1, 0x71, 0x0, 0x0, 0x0, 0x1, - 0x0, 0x0, 0x0, - - /* U+671B "望" */ - 0x0, 0x2, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0xb, 0x10, 0x8, 0x55, 0x59, 0x10, 0x0, 0x5, - 0x14, 0xc, 0x0, 0xb, 0x0, 0x16, 0xb5, 0x57, - 0x2d, 0x55, 0x5c, 0x0, 0x0, 0xb0, 0x0, 0xc, - 0x0, 0xb, 0x0, 0x0, 0xb0, 0x25, 0x3c, 0x55, - 0x5c, 0x0, 0x0, 0xca, 0x60, 0x75, 0x2, 0x3c, - 0x0, 0x0, 0x40, 0x3, 0x60, 0x0, 0x67, 0x0, - 0x3, 0x65, 0x57, 0x75, 0x55, 0x6b, 0x10, 0x0, - 0x0, 0x0, 0xc0, 0x0, 0x10, 0x0, 0x0, 0x46, - 0x55, 0xd5, 0x56, 0x90, 0x0, 0x0, 0x0, 0x0, - 0xc0, 0x0, 0x0, 0x0, 0x15, 0x55, 0x55, 0xd5, - 0x55, 0x5b, 0x90, 0x1, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, - - /* U+671D "朝" */ - 0x0, 0x0, 0x30, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0xc0, 0x0, 0x42, 0x22, 0x70, 0x4, 0x55, - 0xc5, 0x75, 0x93, 0x22, 0xc0, 0x0, 0x0, 0xb0, - 0x0, 0x91, 0x0, 0xb0, 0x0, 0xa5, 0x95, 0xc0, - 0x93, 0x11, 0xb0, 0x0, 0xb0, 0x0, 0xb0, 0x94, - 0x33, 0xb0, 0x0, 0xc5, 0x55, 0xb0, 0x91, 0x0, - 0xb0, 0x0, 0xb0, 0x0, 0xb0, 0xa1, 0x0, 0xb0, - 0x0, 0xc5, 0xc5, 0x90, 0xb5, 0x55, 0xb0, 0x0, - 0x0, 0xb0, 0x31, 0xb0, 0x0, 0xb0, 0x16, 0x55, - 0xc5, 0x55, 0x80, 0x0, 0xb0, 0x0, 0x0, 0xb0, - 0x8, 0x10, 0x0, 0xb0, 0x0, 0x0, 0xc0, 0x43, - 0x0, 0x4c, 0x80, 0x0, 0x0, 0x20, 0x10, 0x0, - 0x1, 0x0, - - /* U+671F "期" */ - 0x0, 0x0, 0x0, 0x10, 0x0, 0x0, 0x0, 0x0, - 0x1c, 0x0, 0xd0, 0x16, 0x44, 0x81, 0x0, 0x1a, - 0x0, 0xc5, 0x1b, 0x11, 0xc0, 0x3, 0x6c, 0x55, - 0xd5, 0x3b, 0x0, 0xc0, 0x0, 0x1c, 0x55, 0xc0, - 0x1c, 0x55, 0xc0, 0x0, 0x1a, 0x0, 0xc0, 0x1a, - 0x0, 0xc0, 0x0, 0x1c, 0x55, 0xc0, 0x1a, 0x0, - 0xc0, 0x0, 0x1a, 0x0, 0xc0, 0x2b, 0x22, 0xc0, - 0x3, 0x6c, 0x55, 0xda, 0x5a, 0x33, 0xc0, 0x0, - 0x6, 0x13, 0x0, 0x66, 0x0, 0xc0, 0x0, 0x2c, - 0x24, 0xa0, 0xb1, 0x0, 0xc0, 0x0, 0xa1, 0x0, - 0x75, 0x60, 0x10, 0xc0, 0x6, 0x0, 0x0, 0x35, - 0x0, 0x2b, 0xa0, 0x0, 0x0, 0x0, 0x10, 0x0, - 0x0, 0x0, - - /* U+6728 "木" */ - 0x0, 0x0, 0x0, 0x20, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, 0xc3, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0xc1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0xc1, 0x0, 0x3, 0x0, 0x7, 0x55, 0x57, 0xe7, - 0x55, 0x5b, 0x50, 0x0, 0x0, 0xb, 0xf7, 0x0, - 0x0, 0x0, 0x0, 0x0, 0x2b, 0xc3, 0x60, 0x0, - 0x0, 0x0, 0x0, 0xb3, 0xc1, 0xa1, 0x0, 0x0, - 0x0, 0x6, 0x70, 0xc1, 0x3b, 0x0, 0x0, 0x0, - 0x48, 0x0, 0xc1, 0x6, 0xd3, 0x0, 0x3, 0x70, - 0x0, 0xc1, 0x0, 0x7f, 0xa0, 0x23, 0x0, 0x0, - 0xc1, 0x0, 0x3, 0x0, 0x0, 0x0, 0x0, 0xc1, - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x20, 0x0, - 0x0, 0x0, - - /* U+672A "未" */ - 0x0, 0x0, 0x0, 0x30, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, 0xa5, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0xa2, 0x0, 0x50, 0x0, 0x0, 0x46, 0x55, - 0xc7, 0x56, 0x71, 0x0, 0x0, 0x0, 0x0, 0xa2, - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xa2, 0x0, - 0x5, 0x0, 0x6, 0x55, 0x58, 0xf9, 0x55, 0x58, - 0x40, 0x0, 0x0, 0xc, 0xd5, 0x40, 0x0, 0x0, - 0x0, 0x0, 0x86, 0xa2, 0x81, 0x0, 0x0, 0x0, - 0x6, 0x70, 0xa2, 0x1c, 0x20, 0x0, 0x0, 0x65, - 0x0, 0xa2, 0x2, 0xe8, 0x10, 0x16, 0x20, 0x0, - 0xa3, 0x0, 0x2c, 0x80, 0x0, 0x0, 0x0, 0xb3, - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x20, 0x0, - 0x0, 0x0, - - /* U+672B "末" */ - 0x0, 0x0, 0x0, 0x20, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, 0xb5, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0xa2, 0x0, 0x5, 0x0, 0x7, 0x55, 0x55, - 0xc7, 0x55, 0x58, 0x40, 0x0, 0x0, 0x0, 0xa2, - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xa2, 0x0, - 0x80, 0x0, 0x0, 0x55, 0x5a, 0xfa, 0x55, 0x52, - 0x0, 0x0, 0x0, 0x1c, 0xb4, 0x60, 0x0, 0x0, - 0x0, 0x0, 0xb3, 0xa2, 0x74, 0x0, 0x0, 0x0, - 0x9, 0x40, 0xa2, 0xb, 0x60, 0x0, 0x0, 0x83, - 0x0, 0xa2, 0x0, 0xcc, 0x60, 0x26, 0x10, 0x0, - 0xa3, 0x0, 0x7, 0x20, 0x0, 0x0, 0x0, 0xb3, - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x20, 0x0, - 0x0, 0x0, - - /* U+672C "本" */ - 0x0, 0x0, 0x0, 0x13, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x3c, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x2a, 0x0, 0x0, 0x0, 0x2, 0x55, 0x55, - 0x6c, 0x55, 0x58, 0xb0, 0x0, 0x10, 0x0, 0xea, - 0x50, 0x0, 0x0, 0x0, 0x0, 0x6, 0xaa, 0x60, - 0x0, 0x0, 0x0, 0x0, 0x1c, 0x3a, 0x18, 0x0, - 0x0, 0x0, 0x0, 0xa3, 0x2a, 0x7, 0x50, 0x0, - 0x0, 0x7, 0x50, 0x2a, 0x0, 0xb7, 0x0, 0x0, - 0x66, 0x55, 0x6c, 0x59, 0x7c, 0xd3, 0x5, 0x20, - 0x0, 0x2a, 0x0, 0x0, 0x30, 0x0, 0x0, 0x0, - 0x2a, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x3b, - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x11, 0x0, - 0x0, 0x0, - - /* U+672D "札" */ - 0x0, 0x1, 0x10, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x3, 0xc0, 0x0, 0xd2, 0x0, 0x0, 0x0, 0x3, - 0xa0, 0x0, 0xd0, 0x0, 0x0, 0x0, 0x2, 0xa0, - 0x60, 0xd0, 0x0, 0x0, 0x6, 0x57, 0xc5, 0x50, - 0xd0, 0x0, 0x0, 0x0, 0x7, 0xb0, 0x0, 0xd0, - 0x0, 0x0, 0x0, 0xc, 0xca, 0x30, 0xd0, 0x0, - 0x0, 0x0, 0x3a, 0xa3, 0xe0, 0xd0, 0x0, 0x0, - 0x0, 0x93, 0xa0, 0x30, 0xd0, 0x0, 0x0, 0x3, - 0x42, 0xa0, 0x0, 0xd0, 0x0, 0x30, 0x4, 0x2, - 0xa0, 0x0, 0xd0, 0x0, 0x60, 0x0, 0x3, 0xa0, - 0x0, 0xc0, 0x0, 0xa2, 0x0, 0x3, 0xa0, 0x0, - 0x9c, 0xaa, 0xd3, 0x0, 0x1, 0x30, 0x0, 0x0, - 0x0, 0x0, - - /* U+673A "机" */ - 0x0, 0x5, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0xd, 0x0, 0x2, 0x0, 0x40, 0x0, 0x0, 0xc, - 0x0, 0x1c, 0x55, 0xd1, 0x0, 0x0, 0xc, 0x4, - 0x1b, 0x0, 0xc0, 0x0, 0x5, 0x6e, 0x55, 0x1b, - 0x0, 0xc0, 0x0, 0x0, 0x4d, 0x0, 0x1b, 0x0, - 0xc0, 0x0, 0x0, 0x8d, 0x94, 0x1b, 0x0, 0xc0, - 0x0, 0x0, 0xac, 0xc, 0x1a, 0x0, 0xc0, 0x0, - 0x3, 0x5c, 0x0, 0x29, 0x0, 0xc0, 0x0, 0x7, - 0xc, 0x0, 0x56, 0x0, 0xc0, 0x0, 0x22, 0xc, - 0x0, 0xa1, 0x0, 0xc0, 0x50, 0x0, 0xc, 0x2, - 0x70, 0x0, 0xc0, 0x70, 0x0, 0xd, 0x7, 0x0, - 0x0, 0xba, 0xd3, 0x0, 0x8, 0x30, 0x0, 0x0, - 0x0, 0x0, - - /* U+6750 "材" */ - 0x0, 0x3, 0x0, 0x0, 0x0, 0x30, 0x0, 0x0, - 0xd, 0x30, 0x0, 0x0, 0xd2, 0x0, 0x0, 0xc, - 0x0, 0x0, 0x0, 0xd0, 0x0, 0x0, 0xc, 0x6, - 0x0, 0x0, 0xd1, 0x60, 0x35, 0x5e, 0x55, 0x24, - 0x46, 0xf4, 0x40, 0x0, 0x1f, 0x50, 0x0, 0x9, - 0xf0, 0x0, 0x0, 0x7f, 0x4b, 0x0, 0x2c, 0xd0, - 0x0, 0x0, 0xbc, 0x9, 0x10, 0xa2, 0xd0, 0x0, - 0x5, 0x5c, 0x0, 0x7, 0x50, 0xd0, 0x0, 0x7, - 0xc, 0x0, 0x55, 0x0, 0xd0, 0x0, 0x40, 0xc, - 0x3, 0x20, 0x0, 0xd0, 0x0, 0x0, 0xc, 0x10, - 0x0, 0x0, 0xd0, 0x0, 0x0, 0xc, 0x10, 0x0, - 0x5c, 0xd0, 0x0, 0x0, 0x4, 0x0, 0x0, 0x1, - 0x10, 0x0, - - /* U+6751 "村" */ - 0x0, 0x4, 0x0, 0x0, 0x0, 0x40, 0x0, 0x0, - 0xd, 0x20, 0x0, 0x0, 0xd2, 0x0, 0x0, 0xd, - 0x0, 0x0, 0x0, 0xd0, 0x0, 0x0, 0xd, 0x5, - 0x0, 0x0, 0xd1, 0x40, 0x25, 0x5f, 0x55, 0x25, - 0x55, 0xe5, 0x40, 0x0, 0x4f, 0x20, 0x3, 0x0, - 0xd0, 0x0, 0x0, 0x8f, 0x69, 0x6, 0x60, 0xd0, - 0x0, 0x0, 0x9d, 0xb, 0x10, 0xe0, 0xd0, 0x0, - 0x6, 0x3d, 0x0, 0x0, 0x40, 0xd0, 0x0, 0x6, - 0xd, 0x0, 0x0, 0x0, 0xd0, 0x0, 0x30, 0xd, - 0x0, 0x0, 0x0, 0xd0, 0x0, 0x0, 0xd, 0x0, - 0x0, 0x0, 0xd0, 0x0, 0x0, 0xd, 0x0, 0x0, - 0x5c, 0xe0, 0x0, 0x0, 0x4, 0x0, 0x0, 0x2, - 0x10, 0x0, - - /* U+675F "束" */ - 0x0, 0x0, 0x0, 0x4, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x1d, 0x0, 0x0, 0x10, 0x5, 0x65, - 0x55, 0x5d, 0x55, 0x55, 0xb4, 0x0, 0x0, 0x0, - 0xc, 0x0, 0x0, 0x0, 0x0, 0x29, 0x55, 0x5d, - 0x55, 0x6b, 0x0, 0x0, 0x1b, 0x0, 0xc, 0x0, - 0x2a, 0x0, 0x0, 0x1b, 0x0, 0xc, 0x0, 0x2a, - 0x0, 0x0, 0x1c, 0x55, 0x8d, 0x65, 0x7a, 0x0, - 0x0, 0x28, 0x5, 0xbc, 0x60, 0x13, 0x0, 0x0, - 0x0, 0x2c, 0x1c, 0x18, 0x0, 0x0, 0x0, 0x2, - 0xb1, 0xc, 0x4, 0xa2, 0x0, 0x0, 0x49, 0x0, - 0x1c, 0x0, 0x4e, 0xa3, 0x5, 0x40, 0x0, 0x1c, - 0x0, 0x1, 0x60, 0x0, 0x0, 0x0, 0x2, 0x0, - 0x0, 0x0, - - /* U+6761 "条" */ - 0x0, 0x0, 0x3, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x4c, 0x0, 0x1, 0x40, 0x0, 0x0, 0x0, - 0xb8, 0x55, 0x5c, 0xb0, 0x0, 0x0, 0x7, 0x35, - 0x10, 0x4d, 0x0, 0x0, 0x0, 0x44, 0x0, 0x95, - 0xc2, 0x0, 0x0, 0x1, 0x20, 0x0, 0x9f, 0x70, - 0x0, 0x0, 0x0, 0x2, 0x79, 0x47, 0x9d, 0xa7, - 0x63, 0x4, 0x54, 0x0, 0xe, 0x0, 0x58, 0x70, - 0x0, 0x17, 0x55, 0x5e, 0x55, 0x96, 0x0, 0x0, - 0x0, 0x54, 0xd, 0x21, 0x0, 0x0, 0x0, 0x2, - 0xd3, 0xd, 0x7, 0x80, 0x0, 0x0, 0x2a, 0x10, - 0xd, 0x0, 0x8c, 0x0, 0x3, 0x50, 0x5, 0xda, - 0x0, 0xa, 0x0, 0x0, 0x0, 0x0, 0x20, 0x0, - 0x0, 0x0, - - /* U+6765 "来" */ - 0x0, 0x0, 0x0, 0x30, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, 0xa5, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0xa2, 0x0, 0x17, 0x0, 0x2, 0x66, 0x55, - 0xc7, 0x55, 0x75, 0x10, 0x0, 0x8, 0x60, 0xa2, - 0x7, 0xa0, 0x0, 0x0, 0x0, 0xe0, 0xa2, 0x1a, - 0x0, 0x0, 0x25, 0x55, 0x75, 0xc7, 0x95, 0x5a, - 0x90, 0x1, 0x0, 0x8, 0xf6, 0x10, 0x0, 0x0, - 0x0, 0x0, 0x2b, 0xa2, 0x80, 0x0, 0x0, 0x0, - 0x0, 0xc1, 0xa2, 0x3a, 0x0, 0x0, 0x0, 0xa, - 0x20, 0xa2, 0x5, 0xc3, 0x0, 0x1, 0x81, 0x0, - 0xa3, 0x0, 0x4e, 0xa0, 0x24, 0x0, 0x0, 0xb3, - 0x0, 0x1, 0x0, 0x0, 0x0, 0x0, 0x20, 0x0, - 0x0, 0x0, - - /* U+676F "杯" */ - 0x0, 0x2, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0xc2, 0x0, 0x0, 0x0, 0x42, 0x0, 0xb, 0x4, - 0x55, 0x9a, 0x55, 0x30, 0x0, 0xb0, 0x40, 0xa, - 0x20, 0x0, 0x15, 0x5d, 0x56, 0x0, 0xb0, 0x0, - 0x0, 0x1, 0xf4, 0x0, 0x7d, 0x20, 0x0, 0x0, - 0x7f, 0x68, 0xb, 0xb0, 0x30, 0x0, 0x9, 0xb0, - 0xa8, 0x2b, 0x2, 0x90, 0x6, 0x2b, 0x3, 0x50, - 0xb0, 0x7, 0xa2, 0x40, 0xb2, 0x50, 0xb, 0x0, - 0x5, 0x20, 0xb, 0x10, 0x0, 0xc0, 0x0, 0x0, - 0x0, 0xb1, 0x0, 0xc, 0x0, 0x0, 0x0, 0xc, - 0x10, 0x0, 0xc1, 0x0, 0x0, 0x0, 0x30, 0x0, - 0x2, 0x0, 0x0, - - /* U+6771 "東" */ - 0x0, 0x0, 0x0, 0x3, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x1c, 0x0, 0x2, 0x10, 0x3, 0x65, - 0x55, 0x5c, 0x55, 0x59, 0x80, 0x0, 0x2, 0x0, - 0x1b, 0x0, 0x40, 0x0, 0x0, 0xd, 0x55, 0x5c, - 0x55, 0xd3, 0x0, 0x0, 0xc, 0x0, 0x1b, 0x0, - 0xc0, 0x0, 0x0, 0xd, 0x55, 0x5c, 0x55, 0xd0, - 0x0, 0x0, 0xd, 0x55, 0x6c, 0x55, 0xd0, 0x0, - 0x0, 0x7, 0x3, 0xdb, 0x50, 0x40, 0x0, 0x0, - 0x0, 0xc, 0x3b, 0x44, 0x0, 0x0, 0x0, 0x0, - 0xa3, 0x1b, 0x9, 0x50, 0x0, 0x0, 0x9, 0x30, - 0x1b, 0x0, 0xac, 0x51, 0x4, 0x60, 0x0, 0x1b, - 0x0, 0x5, 0xa2, 0x1, 0x0, 0x0, 0x2, 0x0, - 0x0, 0x0, - - /* U+6790 "析" */ - 0x0, 0x5, 0x0, 0x0, 0x0, 0x3, 0x0, 0x0, - 0xd, 0x0, 0x24, 0x46, 0x9a, 0x40, 0x0, 0xc, - 0x0, 0x39, 0x0, 0x0, 0x0, 0x5, 0x5d, 0x69, - 0x39, 0x0, 0x0, 0x0, 0x0, 0x1c, 0x0, 0x39, - 0x0, 0x0, 0x10, 0x0, 0x5e, 0x10, 0x3b, 0x55, - 0x85, 0xb2, 0x0, 0xac, 0xa4, 0x38, 0x0, 0xc0, - 0x0, 0x0, 0x9c, 0x28, 0x48, 0x0, 0xc0, 0x0, - 0x6, 0x2c, 0x0, 0x56, 0x0, 0xc0, 0x0, 0x5, - 0xc, 0x0, 0x83, 0x0, 0xc0, 0x0, 0x0, 0xc, - 0x0, 0xb0, 0x0, 0xc0, 0x0, 0x0, 0xd, 0x6, - 0x40, 0x0, 0xc0, 0x0, 0x0, 0xd, 0x25, 0x0, - 0x0, 0xc0, 0x0, 0x0, 0x2, 0x10, 0x0, 0x0, - 0x10, 0x0, - - /* U+6797 "林" */ - 0x0, 0x1, 0x0, 0x0, 0x10, 0x0, 0x0, 0x0, - 0xb, 0x30, 0x0, 0xb3, 0x0, 0x0, 0x0, 0xa, - 0x10, 0x0, 0xb1, 0x0, 0x0, 0x0, 0xa, 0x33, - 0x0, 0xb1, 0x18, 0x0, 0x5, 0x5d, 0x64, 0x34, - 0xf8, 0x44, 0x10, 0x0, 0xf, 0x20, 0x5, 0xf7, - 0x0, 0x0, 0x0, 0x5f, 0x94, 0xa, 0xc7, 0x10, - 0x0, 0x0, 0xab, 0x2c, 0x27, 0xb2, 0x90, 0x0, - 0x4, 0x5a, 0x11, 0x80, 0xb1, 0x94, 0x0, 0x6, - 0xa, 0x15, 0x20, 0xb1, 0x1e, 0x60, 0x20, 0xa, - 0x33, 0x0, 0xb1, 0x3, 0x30, 0x0, 0xa, 0x10, - 0x0, 0xb1, 0x0, 0x0, 0x0, 0xb, 0x20, 0x0, - 0xb1, 0x0, 0x0, 0x0, 0x4, 0x0, 0x0, 0x40, - 0x0, 0x0, - - /* U+679C "果" */ - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0xc, 0x55, 0x59, 0x55, 0xc3, 0x0, 0x0, 0xc, - 0x0, 0x1b, 0x0, 0xc0, 0x0, 0x0, 0xd, 0x55, - 0x6c, 0x55, 0xd0, 0x0, 0x0, 0xc, 0x0, 0x1b, - 0x0, 0xc0, 0x0, 0x0, 0xd, 0x55, 0x6c, 0x55, - 0xd0, 0x0, 0x0, 0x9, 0x0, 0x1b, 0x0, 0x70, - 0x0, 0x3, 0x55, 0x55, 0x6c, 0x55, 0x5b, 0xb1, - 0x1, 0x0, 0x4, 0xcd, 0x40, 0x0, 0x0, 0x0, - 0x0, 0x3c, 0x2b, 0x74, 0x0, 0x0, 0x0, 0x3, - 0xa0, 0x1b, 0xb, 0x80, 0x0, 0x0, 0x66, 0x0, - 0x2b, 0x0, 0x9e, 0x92, 0x5, 0x10, 0x0, 0x2b, - 0x0, 0x4, 0x30, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, - - /* U+67D0 "某" */ - 0x0, 0x0, 0x20, 0x0, 0x3, 0x0, 0x0, 0x0, - 0x0, 0xc1, 0x0, 0xd, 0x0, 0x0, 0x5, 0x55, - 0xd5, 0x55, 0x5d, 0x5a, 0x50, 0x0, 0x0, 0xc0, - 0x0, 0xc, 0x0, 0x0, 0x0, 0x0, 0xc5, 0x55, - 0x5c, 0x0, 0x0, 0x0, 0x0, 0xc0, 0x0, 0xc, - 0x0, 0x0, 0x0, 0x0, 0xd5, 0x85, 0x5c, 0x0, - 0x0, 0x0, 0x0, 0x10, 0xa1, 0x0, 0x3, 0x30, - 0x7, 0x55, 0x5b, 0xe9, 0x55, 0x56, 0x60, 0x0, - 0x0, 0x39, 0xa3, 0x60, 0x0, 0x0, 0x0, 0x2, - 0xa0, 0xa1, 0x58, 0x0, 0x0, 0x0, 0x48, 0x0, - 0xa2, 0x4, 0xd8, 0x40, 0x15, 0x30, 0x0, 0xb2, - 0x0, 0x19, 0x60, 0x0, 0x0, 0x0, 0x20, 0x0, - 0x0, 0x0, - - /* U+67E5 "查" */ - 0x0, 0x0, 0x0, 0x30, 0x0, 0x0, 0x0, 0x0, - 0x0, 0xc, 0x20, 0x0, 0x10, 0x6, 0x55, 0x57, - 0xe6, 0x55, 0x59, 0x40, 0x0, 0x1, 0xbd, 0x25, - 0x0, 0x0, 0x0, 0x1, 0xa2, 0xc0, 0x57, 0x0, - 0x0, 0x2, 0x91, 0xb, 0x0, 0x4c, 0x72, 0x5, - 0x49, 0x65, 0x55, 0x56, 0xc7, 0x41, 0x0, 0xa2, - 0x0, 0x0, 0x29, 0x0, 0x0, 0x9, 0x65, 0x55, - 0x56, 0x90, 0x0, 0x0, 0x92, 0x0, 0x0, 0x29, - 0x0, 0x0, 0xa, 0x65, 0x55, 0x56, 0xa0, 0x0, - 0x0, 0x91, 0x0, 0x0, 0x15, 0x10, 0x4, 0x55, - 0x55, 0x55, 0x55, 0x5e, 0x30, 0x10, 0x0, 0x0, - 0x0, 0x0, 0x0, - - /* U+67F1 "柱" */ - 0x0, 0x2, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0xe, 0x0, 0x0, 0xa2, 0x0, 0x0, 0x0, 0xc, - 0x0, 0x0, 0x4b, 0x0, 0x0, 0x0, 0xc, 0x13, - 0x23, 0x36, 0x34, 0xb1, 0x6, 0x5d, 0x55, 0x22, - 0x1c, 0x11, 0x10, 0x0, 0x3d, 0x0, 0x0, 0xc, - 0x0, 0x0, 0x0, 0x8d, 0xa3, 0x0, 0xc, 0x0, - 0x0, 0x0, 0xac, 0x3a, 0x35, 0x5d, 0x59, 0x80, - 0x5, 0x4c, 0x0, 0x10, 0xc, 0x0, 0x0, 0x6, - 0xc, 0x0, 0x0, 0xc, 0x0, 0x0, 0x10, 0xc, - 0x0, 0x0, 0xc, 0x0, 0x0, 0x0, 0xc, 0x0, - 0x0, 0xc, 0x0, 0x30, 0x0, 0xd, 0x5, 0x55, - 0x58, 0x56, 0x92, 0x0, 0x2, 0x0, 0x0, 0x0, - 0x0, 0x0, - - /* U+67FB "査" */ - 0x0, 0x0, 0x0, 0x2, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, 0xe, 0x10, 0x0, 0x0, 0x0, 0x0, - 0x0, 0xc, 0x0, 0x2, 0x80, 0x4, 0x65, 0x55, - 0xdd, 0x95, 0x55, 0x51, 0x0, 0x0, 0x9, 0x6c, - 0x37, 0x0, 0x0, 0x0, 0x0, 0x95, 0xc, 0x4, - 0xb4, 0x0, 0x0, 0x58, 0x20, 0xa, 0x0, 0x4a, - 0xe6, 0x4, 0x11, 0xc5, 0x55, 0x55, 0xe0, 0x10, - 0x0, 0x1, 0xb0, 0x0, 0x0, 0xc0, 0x0, 0x0, - 0x1, 0xc5, 0x55, 0x55, 0xc0, 0x0, 0x0, 0x1, - 0xc5, 0x55, 0x55, 0xc0, 0x0, 0x0, 0x1, 0xb0, - 0x0, 0x0, 0xc0, 0x10, 0x5, 0x55, 0xc5, 0x55, - 0x55, 0xd6, 0xf5, 0x1, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, - - /* U+67FF "柿" */ - 0x0, 0x2, 0x0, 0x0, 0x10, 0x0, 0x0, 0x0, - 0xe, 0x0, 0x0, 0x95, 0x0, 0x0, 0x0, 0xc, - 0x0, 0x0, 0x2b, 0x0, 0x10, 0x0, 0xc, 0x14, - 0x65, 0x58, 0x55, 0xb2, 0x5, 0x5d, 0x65, 0x0, - 0xc, 0x0, 0x0, 0x0, 0x4d, 0x0, 0x75, 0x5d, - 0x55, 0x80, 0x0, 0x9d, 0xb3, 0xc0, 0xc, 0x2, - 0xa0, 0x0, 0x9c, 0x35, 0xc0, 0xc, 0x2, 0xa0, - 0x5, 0x3c, 0x0, 0xc0, 0xc, 0x2, 0xa0, 0x6, - 0xc, 0x0, 0xc0, 0xc, 0x2, 0xa0, 0x10, 0xc, - 0x0, 0xc0, 0xc, 0x2a, 0x80, 0x0, 0xd, 0x0, - 0x20, 0xc, 0x2, 0x0, 0x0, 0xd, 0x0, 0x0, - 0xc, 0x0, 0x0, 0x0, 0x1, 0x0, 0x0, 0x1, - 0x0, 0x0, - - /* U+6811 "树" */ - 0x0, 0x4, 0x0, 0x0, 0x0, 0x3, 0x0, 0x0, - 0xd, 0x0, 0x0, 0x0, 0xd, 0x0, 0x0, 0xc, - 0x4, 0x55, 0x91, 0xc, 0x0, 0x0, 0xc, 0x22, - 0x0, 0xc0, 0xc, 0x41, 0x5, 0x5d, 0x66, 0x3, - 0x95, 0x5d, 0x53, 0x0, 0x3d, 0x0, 0x57, 0x40, - 0xc, 0x0, 0x0, 0x7d, 0xa2, 0x6c, 0x53, 0xc, - 0x0, 0x0, 0xac, 0x28, 0x4d, 0xc, 0xc, 0x0, - 0x3, 0x4c, 0x0, 0xa8, 0x58, 0xc, 0x0, 0x6, - 0xc, 0x5, 0x33, 0x90, 0xc, 0x0, 0x10, 0xc, - 0x24, 0x0, 0x20, 0xc, 0x0, 0x0, 0xc, 0x10, - 0x0, 0x11, 0x1c, 0x0, 0x0, 0xd, 0x0, 0x0, - 0x6, 0xe9, 0x0, 0x0, 0x3, 0x0, 0x0, 0x0, - 0x20, 0x0, - - /* U+6821 "校" */ - 0x0, 0x1, 0x0, 0x1, 0x10, 0x0, 0x0, 0x0, - 0xe, 0x0, 0x0, 0xb3, 0x0, 0x0, 0x0, 0xc, - 0x0, 0x0, 0x56, 0x0, 0x40, 0x0, 0xc, 0x15, - 0x65, 0x55, 0x56, 0x81, 0x5, 0x5e, 0x54, 0x8, - 0x61, 0x61, 0x0, 0x0, 0x4e, 0x60, 0x2b, 0x0, - 0x2d, 0x40, 0x0, 0x9d, 0x86, 0x80, 0x0, 0x34, - 0x90, 0x0, 0x9c, 0x4, 0x4, 0x0, 0xd5, 0x0, - 0x5, 0x3c, 0x0, 0x5, 0x3, 0xb0, 0x0, 0x6, - 0xc, 0x0, 0x1, 0x6b, 0x20, 0x0, 0x10, 0xc, - 0x0, 0x0, 0xa9, 0x0, 0x0, 0x0, 0xc, 0x0, - 0x6, 0x7a, 0x91, 0x0, 0x0, 0xd, 0x4, 0x72, - 0x0, 0x5d, 0xc3, 0x0, 0x3, 0x21, 0x0, 0x0, - 0x0, 0x20, - - /* U+682A "株" */ - 0x0, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0xe, 0x10, 0x1, 0xd, 0x0, 0x0, 0x0, 0xc, - 0x0, 0x3c, 0xc, 0x0, 0x0, 0x0, 0xc, 0x23, - 0x7a, 0x5d, 0x59, 0x60, 0x6, 0x6d, 0x54, 0xa0, - 0xc, 0x0, 0x0, 0x0, 0x4d, 0x1, 0x20, 0xc, - 0x0, 0x10, 0x0, 0x9d, 0xb5, 0x65, 0x8d, 0x65, - 0x94, 0x0, 0x9c, 0x34, 0x1, 0xdc, 0x50, 0x0, - 0x6, 0x2c, 0x0, 0x9, 0x4c, 0x71, 0x0, 0x5, - 0xc, 0x0, 0x38, 0xc, 0x1a, 0x0, 0x0, 0xc, - 0x1, 0x80, 0xc, 0x6, 0xb2, 0x0, 0xd, 0x16, - 0x0, 0xc, 0x0, 0x84, 0x0, 0xd, 0x10, 0x0, - 0xc, 0x0, 0x0, 0x0, 0x2, 0x0, 0x0, 0x2, - 0x0, 0x0, - - /* U+6839 "根" */ - 0x0, 0x2, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0xe, 0x0, 0x85, 0x55, 0x5c, 0x10, 0x0, 0xc, - 0x0, 0xc0, 0x0, 0xc, 0x0, 0x1, 0x1c, 0x24, - 0xc0, 0x0, 0xc, 0x0, 0x4, 0x4d, 0x33, 0xc5, - 0x55, 0x5c, 0x0, 0x0, 0x4d, 0x10, 0xc0, 0x0, - 0xc, 0x0, 0x0, 0x9c, 0xa3, 0xc5, 0x65, 0x5c, - 0x0, 0x0, 0x9c, 0x37, 0xc0, 0x60, 0x7, 0x70, - 0x5, 0x2c, 0x0, 0xc0, 0x61, 0x68, 0x10, 0x5, - 0xc, 0x0, 0xc0, 0x1b, 0x10, 0x0, 0x0, 0xc, - 0x0, 0xc0, 0x8, 0x50, 0x0, 0x0, 0xd, 0x0, - 0xc2, 0x61, 0xb9, 0x10, 0x0, 0xd, 0x0, 0xd9, - 0x0, 0x9, 0xd3, 0x0, 0x2, 0x0, 0x10, 0x0, - 0x0, 0x0, - - /* U+683C "格" */ - 0x0, 0x3, 0x0, 0x3, 0x10, 0x0, 0x0, 0x0, - 0xd, 0x0, 0xc, 0x50, 0x0, 0x0, 0x0, 0xb, - 0x0, 0x2d, 0x55, 0x5a, 0x0, 0x0, 0xb, 0x23, - 0x87, 0x0, 0x85, 0x0, 0x5, 0x6d, 0x56, 0x43, - 0x53, 0xa0, 0x0, 0x0, 0x4d, 0x3, 0x0, 0x9c, - 0x10, 0x0, 0x0, 0x9c, 0xa2, 0x2, 0xbb, 0x40, - 0x0, 0x0, 0x8b, 0x25, 0x47, 0x0, 0x9c, 0x72, - 0x5, 0x2b, 0x24, 0x95, 0x55, 0x5b, 0x60, 0x5, - 0xb, 0x0, 0xa1, 0x0, 0x29, 0x0, 0x0, 0xb, - 0x0, 0xa1, 0x0, 0x29, 0x0, 0x0, 0xc, 0x0, - 0xa1, 0x0, 0x29, 0x0, 0x0, 0xc, 0x0, 0xa6, - 0x55, 0x6a, 0x0, 0x0, 0x4, 0x0, 0x30, 0x0, - 0x2, 0x0, - - /* U+6843 "桃" */ - 0x0, 0x2, 0x0, 0x0, 0x1, 0x0, 0x0, 0x0, - 0xd, 0x0, 0x9, 0x4a, 0x40, 0x0, 0x0, 0xb, - 0x0, 0x9, 0x29, 0x10, 0x0, 0x0, 0xb, 0x32, - 0x9, 0x29, 0x13, 0x30, 0x5, 0x5d, 0x53, 0x79, - 0x29, 0x2b, 0x40, 0x0, 0x4d, 0x0, 0xc9, 0x29, - 0x71, 0x0, 0x0, 0x8c, 0xa2, 0x29, 0x29, 0x10, - 0x0, 0x0, 0xab, 0x36, 0xb, 0x29, 0x84, 0x0, - 0x4, 0x4b, 0x3, 0x9b, 0x19, 0x2b, 0x40, 0x7, - 0xb, 0xa, 0xb, 0x9, 0x10, 0x20, 0x11, 0xb, - 0x0, 0x29, 0x9, 0x10, 0x40, 0x0, 0xc, 0x0, - 0x91, 0x9, 0x20, 0x80, 0x0, 0xc, 0x6, 0x30, - 0x6, 0xca, 0xd2, 0x0, 0x6, 0x21, 0x0, 0x0, - 0x0, 0x0, - - /* U+6848 "案" */ - 0x0, 0x0, 0x0, 0x30, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x85, 0x0, 0x0, 0x0, 0x0, 0x75, - 0x55, 0x86, 0x55, 0x5a, 0x60, 0x3, 0xb0, 0x4, - 0xa0, 0x0, 0x9, 0x0, 0x1, 0x55, 0x5c, 0x55, - 0x58, 0x59, 0x60, 0x0, 0x0, 0x94, 0x0, 0xa4, - 0x0, 0x0, 0x0, 0x0, 0x14, 0x7d, 0xc6, 0x10, - 0x0, 0x0, 0x1, 0x57, 0x83, 0x6, 0xd4, 0x0, - 0x0, 0x32, 0x0, 0x2c, 0x0, 0x3, 0x70, 0x3, - 0x55, 0x57, 0xdc, 0x85, 0x55, 0x61, 0x0, 0x0, - 0x2b, 0x3a, 0x56, 0x0, 0x0, 0x0, 0x5, 0x80, - 0x2a, 0x5, 0xb7, 0x30, 0x4, 0x62, 0x0, 0x2b, - 0x0, 0x18, 0xb2, 0x0, 0x0, 0x0, 0x1, 0x0, - 0x0, 0x0, - - /* U+689D "條" */ - 0x0, 0x3, 0x0, 0x1, 0x30, 0x0, 0x0, 0x0, - 0x1f, 0x20, 0x6, 0xb0, 0x0, 0x0, 0x0, 0x58, - 0x0, 0xc, 0x75, 0x5a, 0x10, 0x0, 0xb1, 0x50, - 0x39, 0x50, 0x78, 0x0, 0x3, 0xf1, 0xc0, 0x80, - 0x87, 0x90, 0x0, 0x8, 0xb0, 0xb1, 0x0, 0x8d, - 0x60, 0x0, 0x41, 0xb0, 0xb0, 0x28, 0x41, 0x8d, - 0x92, 0x0, 0xb0, 0xb3, 0x30, 0x1c, 0x1, 0x40, - 0x0, 0xb0, 0xb4, 0x65, 0x6b, 0x57, 0x80, 0x0, - 0xb0, 0xc0, 0x14, 0x1a, 0x10, 0x0, 0x0, 0xb0, - 0x70, 0xa7, 0x1a, 0x2a, 0x20, 0x0, 0xb0, 0x5, - 0x60, 0x1a, 0x3, 0xd0, 0x0, 0xb0, 0x23, 0x5, - 0xd8, 0x0, 0x40, 0x0, 0x20, 0x0, 0x0, 0x20, - 0x0, 0x0, - - /* U+68B0 "械" */ - 0x0, 0x10, 0x0, 0x0, 0x1, 0x0, 0x0, 0x0, - 0xa4, 0x0, 0x0, 0xd, 0x28, 0x0, 0x0, 0x92, - 0x0, 0x0, 0xb, 0x6, 0x30, 0x0, 0x93, 0x34, - 0x44, 0x4c, 0x45, 0x90, 0x36, 0xc6, 0x44, 0x12, - 0xb, 0x0, 0x0, 0x0, 0xd8, 0x19, 0x2c, 0xb, - 0x3, 0x50, 0x1, 0xf5, 0xa9, 0x1a, 0xa, 0x8, - 0x50, 0x6, 0xb2, 0x7b, 0x5c, 0x8b, 0xc, 0x0, - 0x7, 0x92, 0xa, 0xa, 0x8, 0x86, 0x0, 0x41, - 0x92, 0xa, 0xa, 0x5, 0xd0, 0x10, 0x0, 0x92, - 0x17, 0xb, 0x9, 0xc0, 0x50, 0x0, 0xa2, 0x60, - 0x8, 0x83, 0x4a, 0x80, 0x0, 0xa4, 0x30, 0x26, - 0x10, 0x6, 0xe0, 0x0, 0x30, 0x0, 0x20, 0x0, - 0x0, 0x10, - - /* U+68EE "森" */ - 0x0, 0x0, 0x0, 0x40, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, 0xc2, 0x0, 0x2, 0x0, 0x5, 0x55, - 0x57, 0xe7, 0x55, 0x5b, 0x20, 0x0, 0x0, 0x2c, - 0xd3, 0x50, 0x0, 0x0, 0x0, 0x1, 0xb1, 0xc0, - 0x69, 0x10, 0x0, 0x0, 0x38, 0x0, 0xc0, 0x7, - 0xe9, 0x50, 0x4, 0x39, 0x30, 0xb0, 0xd, 0x17, - 0x20, 0x25, 0x5b, 0x69, 0x35, 0x5d, 0x58, 0x80, - 0x0, 0x1f, 0x20, 0x0, 0xdc, 0x50, 0x0, 0x0, - 0x9c, 0x88, 0x7, 0x7b, 0x81, 0x0, 0x4, 0x6a, - 0x16, 0x39, 0xb, 0x2c, 0x10, 0x25, 0xa, 0x23, - 0x60, 0xc, 0x6, 0xc1, 0x10, 0xa, 0x22, 0x0, - 0xc, 0x0, 0x0, 0x0, 0x2, 0x0, 0x0, 0x3, - 0x0, 0x0, - - /* U+690D "植" */ - 0x0, 0x6, 0x0, 0x0, 0x41, 0x0, 0x0, 0x0, - 0xd, 0x0, 0x0, 0xa2, 0x0, 0x0, 0x0, 0xc, - 0x3, 0x55, 0xc5, 0x58, 0x90, 0x2, 0x2c, 0x73, - 0x0, 0xb0, 0x0, 0x0, 0x4, 0x4d, 0x31, 0x75, - 0xc5, 0x5a, 0x0, 0x0, 0x4d, 0x20, 0xb0, 0x0, - 0xb, 0x0, 0x0, 0x9c, 0xa4, 0xb5, 0x55, 0x5b, - 0x0, 0x0, 0x9c, 0x13, 0xb0, 0x0, 0xb, 0x0, - 0x5, 0x3c, 0x0, 0xb5, 0x55, 0x5b, 0x0, 0x5, - 0xc, 0x0, 0xb0, 0x0, 0xb, 0x0, 0x0, 0xc, - 0x0, 0xb5, 0x55, 0x5b, 0x0, 0x0, 0xc, 0x0, - 0xb0, 0x0, 0xb, 0x50, 0x0, 0xc, 0x36, 0x65, - 0x55, 0x56, 0x62, 0x0, 0x3, 0x0, 0x0, 0x0, - 0x0, 0x0, - - /* U+691C "検" */ - 0x0, 0x4, 0x0, 0x0, 0x21, 0x0, 0x0, 0x0, - 0xe, 0x0, 0x0, 0xb9, 0x0, 0x0, 0x0, 0xc, - 0x0, 0x3, 0xb3, 0x50, 0x0, 0x1, 0x1c, 0x43, - 0x1a, 0x0, 0x6b, 0x30, 0x4, 0x4d, 0x34, 0x76, - 0x55, 0x87, 0xb3, 0x0, 0x4e, 0x22, 0x0, 0xb, - 0x0, 0x0, 0x0, 0x9d, 0xa5, 0xa5, 0x5c, 0x5c, - 0x30, 0x0, 0x9c, 0x14, 0xb0, 0xa, 0xb, 0x0, - 0x5, 0x3c, 0x0, 0xb5, 0x6b, 0x5c, 0x0, 0x5, - 0xc, 0x0, 0x70, 0x6b, 0x14, 0x0, 0x0, 0xc, - 0x0, 0x0, 0xc1, 0xa0, 0x0, 0x0, 0xd, 0x0, - 0x9, 0x40, 0x4c, 0x30, 0x0, 0xd, 0x2, 0x72, - 0x0, 0x5, 0xc3, 0x0, 0x2, 0x1, 0x0, 0x0, - 0x0, 0x0, - - /* U+695A "楚" */ - 0x0, 0x0, 0x20, 0x0, 0x4, 0x0, 0x0, 0x0, - 0x0, 0xc1, 0x0, 0xc, 0x0, 0x0, 0x2, 0x55, - 0xc6, 0x83, 0x5c, 0x59, 0x30, 0x0, 0x4, 0xf2, - 0x0, 0x7e, 0x0, 0x0, 0x0, 0xb, 0xc6, 0x72, - 0x9b, 0x77, 0x0, 0x0, 0x82, 0xc0, 0x48, 0xb, - 0xa, 0x20, 0x5, 0x20, 0xb0, 0x50, 0xb, 0x0, - 0x0, 0x1, 0x65, 0x55, 0x58, 0x55, 0x5e, 0x30, - 0x0, 0x0, 0x60, 0xb, 0x0, 0x42, 0x0, 0x0, - 0x5, 0xb0, 0xc, 0x55, 0x86, 0x0, 0x0, 0xc, - 0x70, 0xb, 0x0, 0x0, 0x0, 0x0, 0x73, 0x8, - 0x6b, 0x0, 0x0, 0x0, 0x4, 0x30, 0x0, 0x39, - 0xbc, 0xce, 0xb1, 0x1, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, - - /* U+696D "業" */ - 0x0, 0x0, 0x4, 0x0, 0x50, 0x0, 0x0, 0x0, - 0x76, 0xc, 0x10, 0xc0, 0xb2, 0x0, 0x0, 0xa, - 0x4b, 0x0, 0xb7, 0x30, 0x0, 0x4, 0x56, 0x6c, - 0x55, 0xd5, 0x56, 0xb0, 0x1, 0x0, 0x63, 0x0, - 0x72, 0x0, 0x0, 0x0, 0x0, 0x8, 0x0, 0x60, - 0x35, 0x0, 0x0, 0x45, 0x55, 0xa7, 0x55, 0x55, - 0x0, 0x0, 0x15, 0x55, 0xb7, 0x55, 0xb1, 0x0, - 0x0, 0x0, 0x0, 0x82, 0x0, 0x3, 0x10, 0x4, - 0x55, 0x58, 0xe9, 0x65, 0x56, 0x50, 0x0, 0x0, - 0x3b, 0xa3, 0x92, 0x0, 0x0, 0x0, 0x7, 0x80, - 0x92, 0xa, 0xa5, 0x20, 0x4, 0x72, 0x0, 0x93, - 0x0, 0x4b, 0xc2, 0x0, 0x0, 0x0, 0x30, 0x0, - 0x0, 0x0, - - /* U+6975 "極" */ - 0x0, 0x4, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0xd, 0x0, 0x0, 0x0, 0x4, 0x0, 0x0, 0xb, - 0x0, 0x55, 0x55, 0xb8, 0x0, 0x3, 0x3c, 0x71, - 0x0, 0x18, 0x20, 0x0, 0x2, 0x2c, 0x26, 0x58, - 0x3a, 0x55, 0x81, 0x0, 0x3d, 0x38, 0x1a, 0x19, - 0x1, 0xb0, 0x0, 0x8c, 0x9d, 0x1a, 0x19, 0x56, - 0x60, 0x0, 0xab, 0x1c, 0x1a, 0x19, 0xe, 0x10, - 0x4, 0x5b, 0x8, 0x6c, 0x19, 0x1a, 0x90, 0x7, - 0xb, 0x9, 0x18, 0x19, 0x60, 0xb0, 0x10, 0xb, - 0x4, 0x3, 0x3a, 0x30, 0x0, 0x0, 0xc, 0x0, - 0x2, 0xc5, 0x0, 0x0, 0x0, 0xc, 0x25, 0x55, - 0x55, 0x55, 0xd2, 0x0, 0x5, 0x0, 0x0, 0x0, - 0x0, 0x0, - - /* U+697D "楽" */ - 0x0, 0x0, 0x0, 0x3, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, 0xa, 0x10, 0x0, 0x0, 0x2, 0x71, - 0x1b, 0x66, 0x5b, 0x6, 0x80, 0x0, 0x3c, 0xb, - 0x0, 0x1a, 0x37, 0x0, 0x0, 0x1, 0xc, 0x55, - 0x6c, 0x20, 0x0, 0x0, 0x16, 0x4b, 0x0, 0x1b, - 0x7b, 0x40, 0x6, 0xa1, 0xc, 0x55, 0x6a, 0x2, - 0xa0, 0x0, 0x0, 0x5, 0xa, 0x14, 0x0, 0x20, - 0x5, 0x65, 0x55, 0x9d, 0x75, 0x57, 0x80, 0x0, - 0x0, 0x6, 0xbc, 0x71, 0x0, 0x0, 0x0, 0x0, - 0x69, 0xc, 0xa, 0x30, 0x0, 0x0, 0x18, 0x50, - 0xc, 0x1, 0xbb, 0x61, 0x5, 0x50, 0x0, 0xd, - 0x0, 0x4, 0x60, 0x0, 0x0, 0x0, 0x3, 0x0, - 0x0, 0x0, - - /* U+6982 "概" */ - 0x0, 0x5, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x1a, 0x5, 0x57, 0x24, 0x55, 0x93, 0x0, 0x9, - 0xa, 0x9, 0x0, 0xb, 0x0, 0x2, 0x3b, 0x7a, - 0x9, 0x8, 0x2a, 0x0, 0x2, 0x4a, 0x2a, 0x5b, - 0xb, 0x19, 0x0, 0x0, 0x6c, 0x2a, 0x9, 0x2a, - 0x28, 0x0, 0x0, 0xaa, 0xcc, 0x9, 0x79, 0x8a, - 0x95, 0x0, 0x99, 0x3c, 0x57, 0x0, 0x88, 0x0, - 0x6, 0x39, 0xa, 0x15, 0x0, 0xcb, 0x0, 0x6, - 0x19, 0xa, 0xa, 0x55, 0x7a, 0x0, 0x10, 0x19, - 0xb, 0x92, 0x4a, 0xa, 0x3, 0x0, 0x1a, 0x6, - 0x10, 0x92, 0xa, 0x6, 0x0, 0x1a, 0x0, 0x16, - 0x10, 0xa, 0xa9, 0x0, 0x3, 0x0, 0x20, 0x0, - 0x0, 0x0, - - /* U+69CB "構" */ - 0x0, 0x20, 0x0, 0x4, 0x0, 0x30, 0x0, 0x0, - 0x84, 0x0, 0xc, 0x0, 0xc1, 0x20, 0x0, 0x82, - 0x15, 0x5c, 0x55, 0xc6, 0x60, 0x0, 0x82, 0x44, - 0x5c, 0x55, 0xc9, 0x30, 0x25, 0xb6, 0x51, 0xa, - 0x0, 0xa0, 0x40, 0x0, 0xd9, 0x55, 0x56, 0x97, - 0x65, 0x60, 0x1, 0xf4, 0xa5, 0x55, 0xa8, 0x58, - 0x20, 0x6, 0xc2, 0x38, 0x20, 0x74, 0xa, 0x0, - 0x8, 0x82, 0x8, 0x65, 0xa8, 0x5b, 0x0, 0x32, - 0x82, 0x8, 0x20, 0x74, 0xa, 0x50, 0x10, 0x82, - 0x5b, 0x65, 0x55, 0x5b, 0x61, 0x0, 0x82, 0x8, - 0x20, 0x0, 0xa, 0x0, 0x0, 0x92, 0x9, 0x20, - 0x2, 0x8d, 0x0, 0x0, 0x10, 0x2, 0x0, 0x0, - 0x1, 0x0, - - /* U+69D8 "様" */ - 0x0, 0x2, 0x0, 0x3, 0x0, 0x4, 0x0, 0x0, - 0xc, 0x0, 0x3, 0xb0, 0xb, 0x10, 0x0, 0xa, - 0x0, 0x45, 0xb5, 0x86, 0xb2, 0x0, 0xa, 0x23, - 0x0, 0xb, 0x0, 0x0, 0x5, 0x6c, 0x54, 0x25, - 0x5c, 0x57, 0x70, 0x0, 0x4d, 0x50, 0x0, 0xb, - 0x0, 0x10, 0x0, 0x8a, 0xa4, 0x65, 0x5b, 0x55, - 0x94, 0x0, 0xaa, 0x20, 0x0, 0xb, 0x20, 0x80, - 0x4, 0x4a, 0x4, 0x59, 0x7b, 0x47, 0x50, 0x6, - 0xa, 0x0, 0xa, 0x1b, 0x72, 0x0, 0x0, 0xa, - 0x0, 0x47, 0xb, 0xb, 0x0, 0x0, 0xb, 0x1, - 0x80, 0xb, 0x5, 0xc3, 0x0, 0xb, 0x25, 0x4, - 0xac, 0x0, 0x40, 0x0, 0x1, 0x0, 0x0, 0x11, - 0x0, 0x0, - - /* U+6A02 "樂" */ - 0x0, 0x21, 0x0, 0x32, 0x0, 0x30, 0x0, 0x0, - 0x86, 0x1, 0x72, 0x20, 0xa5, 0x0, 0x0, 0xa2, - 0x3a, 0x55, 0xc1, 0x83, 0x20, 0x7, 0x38, 0x7a, - 0x0, 0xa7, 0x2a, 0x40, 0x9, 0x7a, 0xa, 0x55, - 0xa9, 0x78, 0x0, 0x0, 0x73, 0xa, 0x0, 0xa0, - 0x83, 0x0, 0x6, 0x75, 0xaa, 0x55, 0xa6, 0x55, - 0xb0, 0x8, 0x62, 0xa4, 0x45, 0x3a, 0x62, 0x90, - 0x6, 0x55, 0x55, 0xaa, 0x55, 0x5a, 0x70, 0x0, - 0x0, 0xb, 0xb7, 0x60, 0x0, 0x0, 0x0, 0x1, - 0xa4, 0x66, 0x48, 0x0, 0x0, 0x0, 0x58, 0x10, - 0x66, 0x4, 0xd8, 0x50, 0x15, 0x20, 0x0, 0x66, - 0x0, 0x17, 0x70, 0x0, 0x0, 0x0, 0x21, 0x0, - 0x0, 0x0, - - /* U+6A19 "標" */ - 0x0, 0x2, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0xc, 0x3, 0x65, 0x75, 0x75, 0xa2, 0x0, 0xa, - 0x0, 0x0, 0x90, 0x90, 0x0, 0x5, 0x5c, 0x86, - 0xa5, 0xb5, 0xb5, 0xa0, 0x0, 0x2b, 0x0, 0xa0, - 0x90, 0x92, 0x80, 0x0, 0x7d, 0x60, 0xc5, 0xb5, - 0xb6, 0x80, 0x0, 0xaa, 0x94, 0x70, 0x0, 0x2, - 0x20, 0x3, 0x5a, 0x10, 0x55, 0x55, 0x58, 0x20, - 0x6, 0xa, 0x4, 0x55, 0x55, 0x55, 0x85, 0x12, - 0xa, 0x1, 0x23, 0xb, 0x10, 0x0, 0x0, 0xb, - 0x0, 0xb5, 0xb, 0x38, 0x0, 0x0, 0xb, 0x8, - 0x20, 0xb, 0x4, 0xb0, 0x0, 0xb, 0x40, 0x5, - 0xb8, 0x0, 0x40, 0x0, 0x1, 0x0, 0x0, 0x10, - 0x0, 0x0, - - /* U+6A21 "模" */ - 0x0, 0x4, 0x0, 0x3, 0x0, 0x40, 0x0, 0x0, - 0xd, 0x0, 0xb, 0x20, 0xd0, 0x10, 0x0, 0xb, - 0x4, 0x5c, 0x55, 0xc5, 0xa1, 0x4, 0x4c, 0x85, - 0xa, 0x0, 0xa0, 0x0, 0x1, 0x3c, 0x10, 0x95, - 0x55, 0x5b, 0x10, 0x0, 0x6d, 0x20, 0xb0, 0x0, - 0xb, 0x0, 0x0, 0xab, 0xa4, 0xb5, 0x55, 0x5c, - 0x0, 0x1, 0x7b, 0x16, 0xb5, 0x55, 0x5c, 0x0, - 0x6, 0xb, 0x0, 0x60, 0x93, 0x5, 0x0, 0x12, - 0xb, 0x16, 0x55, 0xc7, 0x55, 0xb2, 0x0, 0xb, - 0x0, 0x1, 0xb4, 0x20, 0x0, 0x0, 0xc, 0x0, - 0xa, 0x30, 0xa5, 0x0, 0x0, 0xc, 0x2, 0x83, - 0x0, 0xa, 0xd3, 0x0, 0x2, 0x22, 0x0, 0x0, - 0x0, 0x0, - - /* U+6A23 "樣" */ - 0x0, 0x4, 0x0, 0x3, 0x0, 0x32, 0x0, 0x0, - 0xc, 0x0, 0x5, 0x80, 0x94, 0x0, 0x0, 0xb, - 0x2, 0x55, 0x7a, 0x57, 0x50, 0x5, 0x5c, 0x76, - 0x45, 0x5c, 0x59, 0x20, 0x0, 0x2c, 0x0, 0x0, - 0xa, 0x0, 0x10, 0x0, 0x6d, 0x53, 0x55, 0x69, - 0x55, 0x92, 0x0, 0xab, 0x85, 0x0, 0x3c, 0x0, - 0x0, 0x2, 0x7b, 0x13, 0x55, 0x5a, 0x0, 0x40, - 0x7, 0xb, 0x0, 0x2, 0xc, 0x19, 0x60, 0x12, - 0xb, 0x5, 0x5e, 0x5b, 0x91, 0x0, 0x0, 0xb, - 0x0, 0x79, 0xb, 0x38, 0x0, 0x0, 0xc, 0x4, - 0x90, 0xb, 0x7, 0xa2, 0x0, 0xc, 0x25, 0x5, - 0xbc, 0x0, 0x51, 0x0, 0x2, 0x0, 0x0, 0x20, - 0x0, 0x0, - - /* U+6A2A "横" */ - 0x0, 0x13, 0x0, 0x2, 0x1, 0x20, 0x0, 0x0, - 0x1b, 0x0, 0xa, 0x2, 0xb0, 0x0, 0x0, 0x19, - 0x3, 0x5b, 0x56, 0xb7, 0x50, 0x5, 0x6b, 0xa4, - 0x9, 0x2, 0x90, 0x0, 0x0, 0x59, 0x16, 0x58, - 0x86, 0x85, 0x91, 0x0, 0x8b, 0x0, 0x20, 0xa0, - 0x3, 0x0, 0x0, 0xba, 0xb2, 0xc4, 0xb5, 0x5c, - 0x20, 0x2, 0x89, 0x32, 0xa0, 0xa0, 0xa, 0x0, - 0x7, 0x29, 0x0, 0xc5, 0xb5, 0x5c, 0x0, 0x5, - 0x19, 0x0, 0xa0, 0xa0, 0xa, 0x0, 0x0, 0x19, - 0x0, 0xb8, 0x56, 0x57, 0x0, 0x0, 0x1a, 0x0, - 0x5b, 0x10, 0x76, 0x0, 0x0, 0x2a, 0x6, 0x60, - 0x0, 0x7, 0x80, 0x0, 0x13, 0x20, 0x0, 0x0, - 0x0, 0x30, - - /* U+6A39 "樹" */ - 0x0, 0x31, 0x0, 0x21, 0x0, 0x3, 0x0, 0x0, - 0x92, 0x0, 0x67, 0x0, 0xb, 0x0, 0x0, 0x92, - 0x25, 0x99, 0x83, 0xa, 0x0, 0x25, 0xb8, 0x70, - 0x66, 0x0, 0xa, 0x40, 0x0, 0xb2, 0x5, 0x77, - 0x84, 0x5c, 0x50, 0x0, 0xe4, 0x6, 0x55, 0x80, - 0xa, 0x0, 0x3, 0xf8, 0x7a, 0x0, 0xa6, 0x2a, - 0x0, 0x8, 0xa2, 0x4b, 0x55, 0xa1, 0xba, 0x0, - 0x16, 0x92, 0x6, 0x0, 0x90, 0x2a, 0x0, 0x40, - 0x92, 0x7, 0x13, 0x70, 0xa, 0x0, 0x0, 0x92, - 0x3, 0x47, 0x32, 0xa, 0x0, 0x0, 0x92, 0x6a, - 0x85, 0x10, 0xb, 0x0, 0x0, 0x92, 0x20, 0x0, - 0x2, 0xbb, 0x0, 0x0, 0x10, 0x0, 0x0, 0x0, - 0x0, 0x0, - - /* U+6A4B "橋" */ - 0x0, 0x30, 0x0, 0x0, 0x0, 0x42, 0x0, 0x0, - 0x94, 0x3, 0x57, 0xaa, 0x85, 0x0, 0x0, 0x92, - 0x0, 0x0, 0xc0, 0x1, 0x0, 0x25, 0xb8, 0x74, - 0x5b, 0x75, 0x86, 0x40, 0x0, 0xb2, 0x0, 0x76, - 0x0, 0x87, 0x10, 0x0, 0xe5, 0x17, 0x4b, 0x55, - 0xc5, 0xa1, 0x3, 0xf7, 0x80, 0xb, 0x55, 0xb0, - 0x0, 0x8, 0xa2, 0x33, 0x13, 0x0, 0x41, 0x40, - 0x17, 0x92, 0xc, 0x45, 0x44, 0x55, 0xb0, 0x50, - 0x92, 0xb, 0x9, 0x55, 0xc1, 0x90, 0x0, 0x92, - 0xb, 0x9, 0x55, 0xa1, 0x90, 0x0, 0x92, 0xb, - 0x4, 0x0, 0x31, 0x90, 0x0, 0x92, 0xb, 0x0, - 0x0, 0x6c, 0x60, 0x0, 0x10, 0x1, 0x0, 0x0, - 0x1, 0x0, - - /* U+6A5F "機" */ - 0x0, 0x41, 0x0, 0x0, 0x30, 0x0, 0x0, 0x0, - 0xa2, 0x0, 0xb0, 0xb2, 0x68, 0x0, 0x0, 0xa1, - 0x4, 0x36, 0xb0, 0x83, 0x20, 0x25, 0xc9, 0x6b, - 0x78, 0xb9, 0x8b, 0x40, 0x0, 0xc1, 0x1, 0x71, - 0xb1, 0x46, 0x0, 0x0, 0xf3, 0x5, 0x29, 0xb2, - 0x65, 0x60, 0x4, 0xf8, 0x6a, 0x57, 0xb7, 0x92, - 0x80, 0x9, 0xb1, 0x40, 0xb0, 0x91, 0x56, 0x20, - 0x26, 0xa1, 0x25, 0xc5, 0xa7, 0x57, 0x80, 0x40, - 0xa1, 0x0, 0xc0, 0x47, 0x2c, 0x0, 0x0, 0xa1, - 0x5, 0x5a, 0xb, 0xc2, 0x30, 0x0, 0xa1, 0x18, - 0x1, 0x78, 0xc4, 0x70, 0x0, 0xa3, 0x50, 0x5, - 0x10, 0x18, 0xe0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, - - /* U+6B21 "次" */ - 0x0, 0x0, 0x0, 0x4, 0x0, 0x0, 0x0, 0x2, - 0x40, 0x0, 0xe, 0x30, 0x0, 0x0, 0x0, 0xa6, - 0x10, 0x3a, 0x0, 0x0, 0x0, 0x0, 0x38, 0x40, - 0x88, 0x55, 0x57, 0x70, 0x0, 0x0, 0x50, 0xb0, - 0x40, 0xa, 0x60, 0x0, 0x5, 0x17, 0x20, 0xe2, - 0x24, 0x0, 0x0, 0x7, 0x25, 0x1, 0xb3, 0x0, - 0x0, 0x0, 0x44, 0x10, 0x3, 0x85, 0x0, 0x0, - 0x6, 0xd0, 0x0, 0x7, 0x47, 0x0, 0x0, 0x0, - 0xb0, 0x0, 0xb, 0x4, 0x50, 0x0, 0x0, 0xe0, - 0x0, 0x74, 0x0, 0xb1, 0x0, 0x0, 0xf0, 0x5, - 0x50, 0x0, 0x3d, 0x30, 0x0, 0x21, 0x62, 0x0, - 0x0, 0x4, 0xb2, 0x0, 0x1, 0x0, 0x0, 0x0, - 0x0, 0x0, - - /* U+6B32 "欲" */ - 0x0, 0x0, 0x0, 0x0, 0x10, 0x0, 0x0, 0x0, - 0x55, 0x15, 0x0, 0x78, 0x0, 0x0, 0x0, 0xa1, - 0x7, 0x90, 0xb1, 0x0, 0x0, 0x7, 0x13, 0x50, - 0x40, 0xc5, 0x55, 0xa0, 0x10, 0xa, 0x70, 0x6, - 0x30, 0x5, 0x60, 0x0, 0x38, 0x3c, 0x46, 0xe, - 0x4, 0x0, 0x1, 0x90, 0x2, 0x80, 0x1c, 0x0, - 0x0, 0x6, 0x30, 0x4, 0x0, 0x39, 0x30, 0x0, - 0x10, 0xc5, 0x5d, 0x0, 0x65, 0x60, 0x0, 0x0, - 0xa0, 0xb, 0x0, 0xb0, 0x90, 0x0, 0x0, 0xa0, - 0xb, 0x3, 0x80, 0x74, 0x0, 0x0, 0xc5, 0x5c, - 0x19, 0x0, 0xd, 0x30, 0x0, 0x60, 0x4, 0x60, - 0x0, 0x4, 0xc2, 0x0, 0x0, 0x1, 0x0, 0x0, - 0x0, 0x0, - - /* U+6B4C "歌" */ - 0x0, 0x0, 0x0, 0x0, 0x21, 0x0, 0x0, 0x16, - 0x55, 0x56, 0xa3, 0x79, 0x0, 0x0, 0x1, 0x0, - 0x18, 0x30, 0xb1, 0x0, 0x0, 0x4, 0xa5, 0xa8, - 0x31, 0xc5, 0x56, 0x70, 0x4, 0xa5, 0xa8, 0x36, - 0x14, 0x7, 0x40, 0x3, 0x40, 0x47, 0x43, 0xe, - 0x2, 0x0, 0x26, 0x55, 0x58, 0xa2, 0xf, 0x0, - 0x0, 0x2, 0x0, 0x3a, 0x10, 0x2a, 0x40, 0x0, - 0xb, 0x65, 0xba, 0x10, 0x67, 0x70, 0x0, 0xb, - 0x10, 0xaa, 0x10, 0x91, 0x80, 0x0, 0xb, 0x65, - 0x7a, 0x11, 0x90, 0x57, 0x0, 0x1, 0x0, 0x3b, - 0x18, 0x10, 0xd, 0x40, 0x0, 0x0, 0x4b, 0x62, - 0x0, 0x3, 0x90, 0x0, 0x0, 0x2, 0x0, 0x0, - 0x0, 0x0, - - /* U+6B50 "歐" */ - 0x0, 0x0, 0x0, 0x0, 0x30, 0x0, 0x0, 0x9, - 0x55, 0x55, 0xa0, 0xc2, 0x0, 0x0, 0xa, 0x3, - 0x12, 0x30, 0xb0, 0x0, 0x0, 0xa, 0xa, 0x48, - 0x65, 0x95, 0x57, 0x80, 0xa, 0x9, 0x5, 0x48, - 0x5, 0x8, 0x20, 0xa, 0xa, 0x58, 0x53, 0xe, - 0x12, 0x0, 0xa, 0x1, 0x0, 0x0, 0xd, 0x10, - 0x0, 0xa, 0x87, 0x9a, 0x96, 0xb, 0x40, 0x0, - 0xa, 0x83, 0x79, 0x63, 0x39, 0x70, 0x0, 0xa, - 0x87, 0x7a, 0x93, 0x75, 0x80, 0x0, 0xa, 0x61, - 0x16, 0x21, 0xb0, 0x49, 0x0, 0xb, 0x0, 0x4, - 0x18, 0x30, 0xc, 0x70, 0x8, 0x55, 0x55, 0x93, - 0x0, 0x1, 0xb2, 0x0, 0x0, 0x3, 0x0, 0x0, - 0x0, 0x0, - - /* U+6B61 "歡" */ - 0x0, 0x10, 0x2, 0x0, 0x10, 0x0, 0x0, 0x0, - 0x48, 0xc, 0x31, 0x79, 0x0, 0x0, 0x6, 0x89, - 0x5c, 0x52, 0x92, 0x0, 0x0, 0x6, 0x58, 0x56, - 0x71, 0xc5, 0x57, 0x80, 0xb, 0xb, 0x91, 0xa2, - 0x62, 0x9, 0x30, 0x8, 0x86, 0x85, 0x66, 0xe, - 0x12, 0x0, 0x0, 0xc1, 0x80, 0x31, 0x1d, 0x0, - 0x0, 0x7, 0xa5, 0xb5, 0x62, 0x2b, 0x20, 0x0, - 0x27, 0xa4, 0xc4, 0x70, 0x56, 0x60, 0x0, 0x2, - 0xa5, 0xc5, 0x70, 0x92, 0x90, 0x0, 0x2, 0x70, - 0xb0, 0x10, 0xa0, 0x57, 0x0, 0x3, 0xa5, 0x95, - 0x99, 0x20, 0xc, 0x60, 0x3, 0x60, 0x0, 0x62, - 0x0, 0x2, 0xb2, 0x0, 0x0, 0x2, 0x0, 0x0, - 0x0, 0x0, - - /* U+6B62 "止" */ - 0x0, 0x0, 0x0, 0x2, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, 0xe, 0x10, 0x0, 0x0, 0x0, 0x0, - 0x0, 0xc, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0xc, 0x0, 0x0, 0x0, 0x0, 0xb, 0x30, 0xc, - 0x0, 0x3, 0x0, 0x0, 0xc, 0x0, 0xd, 0x55, - 0x59, 0x20, 0x0, 0xc, 0x0, 0xc, 0x0, 0x0, - 0x0, 0x0, 0xc, 0x0, 0xc, 0x0, 0x0, 0x0, - 0x0, 0xc, 0x0, 0xc, 0x0, 0x0, 0x0, 0x0, - 0xc, 0x0, 0xc, 0x0, 0x0, 0x0, 0x0, 0xc, - 0x0, 0xc, 0x0, 0x0, 0x0, 0x15, 0x5d, 0x55, - 0x5d, 0x55, 0x5a, 0xb0, 0x1, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x0, - - /* U+6B63 "正" */ - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x1, - 0x55, 0x55, 0x55, 0x55, 0x5b, 0x90, 0x0, 0x10, - 0x0, 0xc, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0xc, 0x0, 0x0, 0x0, 0x0, 0x1, 0x0, 0xc, - 0x0, 0x0, 0x0, 0x0, 0xb, 0x30, 0xc, 0x0, - 0x1, 0x0, 0x0, 0xb, 0x0, 0xd, 0x55, 0x7a, - 0x0, 0x0, 0xb, 0x0, 0xc, 0x0, 0x0, 0x0, - 0x0, 0xb, 0x0, 0xc, 0x0, 0x0, 0x0, 0x0, - 0xb, 0x0, 0xc, 0x0, 0x0, 0x0, 0x0, 0xb, - 0x0, 0xc, 0x0, 0x0, 0x0, 0x0, 0xb, 0x0, - 0xc, 0x0, 0x6, 0x50, 0x17, 0x55, 0x55, 0x55, - 0x55, 0x55, 0x50, - - /* U+6B64 "此" */ - 0x0, 0x0, 0x0, 0x0, 0x30, 0x0, 0x0, 0x0, - 0x0, 0xa4, 0x0, 0xc2, 0x0, 0x0, 0x0, 0x0, - 0xa2, 0x0, 0xb0, 0x0, 0x0, 0x0, 0x10, 0x92, - 0x0, 0xb0, 0x1, 0x20, 0x0, 0xd0, 0x92, 0x0, - 0xb0, 0x1c, 0x90, 0x0, 0xb0, 0x96, 0x86, 0xb3, - 0x93, 0x0, 0x0, 0xb0, 0x92, 0x0, 0xb4, 0x0, - 0x0, 0x0, 0xb0, 0x92, 0x0, 0xb0, 0x0, 0x0, - 0x0, 0xb0, 0x92, 0x0, 0xb0, 0x0, 0x0, 0x0, - 0xb0, 0x92, 0x2, 0xb0, 0x0, 0x30, 0x0, 0xb0, - 0xa9, 0x62, 0xb0, 0x0, 0x60, 0x16, 0xea, 0x50, - 0x0, 0xc0, 0x0, 0xc2, 0x1a, 0x30, 0x0, 0x0, - 0x5a, 0xaa, 0x91, - - /* U+6B65 "步" */ - 0x0, 0x0, 0x0, 0x6, 0x0, 0x0, 0x0, 0x0, - 0x1, 0x0, 0xd, 0x0, 0x0, 0x0, 0x0, 0xc, - 0x20, 0xd, 0x55, 0x6b, 0x0, 0x0, 0xc, 0x0, - 0xc, 0x0, 0x0, 0x0, 0x0, 0xc, 0x0, 0xc, - 0x0, 0x0, 0x20, 0x7, 0x5b, 0x55, 0x5b, 0x55, - 0x57, 0xc1, 0x0, 0x0, 0x0, 0xc, 0x0, 0x0, - 0x0, 0x0, 0x3, 0xa0, 0xc, 0x0, 0xa, 0x30, - 0x0, 0xb, 0x30, 0xc, 0x0, 0x9a, 0x0, 0x0, - 0x75, 0x0, 0xc, 0xa, 0x80, 0x0, 0x4, 0x50, - 0x0, 0x8, 0xb5, 0x0, 0x0, 0x2, 0x0, 0x2, - 0x89, 0x10, 0x0, 0x0, 0x0, 0x25, 0x66, 0x10, - 0x0, 0x0, 0x0, 0x3, 0x10, 0x0, 0x0, 0x0, - 0x0, 0x0, - - /* U+6B69 "歩" */ - 0x0, 0x0, 0x0, 0x20, 0x0, 0x0, 0x0, 0x0, - 0x0, 0xd, 0x20, 0x0, 0x0, 0x0, 0x2b, 0x0, - 0xc0, 0x2, 0x40, 0x0, 0x2, 0xa0, 0xc, 0x55, - 0x54, 0x0, 0x0, 0x1a, 0x0, 0xc0, 0x0, 0x4, - 0x5, 0x65, 0x85, 0x5b, 0x55, 0x56, 0x92, 0x0, - 0x1, 0x0, 0xe0, 0x44, 0x0, 0x0, 0x2, 0xe2, - 0xc, 0x0, 0x5b, 0x30, 0x0, 0xb3, 0x0, 0xc0, - 0xa, 0x8d, 0x0, 0x82, 0x0, 0xd, 0xb, 0xb2, - 0x20, 0x20, 0x0, 0x0, 0x7c, 0x60, 0x0, 0x0, - 0x0, 0x3, 0x98, 0x10, 0x0, 0x0, 0x1, 0x57, - 0x50, 0x0, 0x0, 0x0, 0x2, 0x20, 0x0, 0x0, - 0x0, 0x0, 0x0, - - /* U+6B6F "歯" */ - 0x0, 0x0, 0x0, 0x4, 0x0, 0x0, 0x0, 0x0, - 0x3, 0x50, 0xd, 0x0, 0x0, 0x0, 0x0, 0x4, - 0x80, 0xd, 0x55, 0xb1, 0x0, 0x0, 0x4, 0x80, - 0xc, 0x0, 0x0, 0x0, 0x4, 0x57, 0xa5, 0x5d, - 0x55, 0x5b, 0x80, 0x1, 0x0, 0x10, 0x8, 0x2, - 0x0, 0x0, 0x0, 0xb0, 0x57, 0xb, 0xb, 0x27, - 0x10, 0x0, 0xb0, 0x7, 0xb, 0x43, 0x2c, 0x0, - 0x0, 0xb3, 0x65, 0xae, 0x76, 0x7c, 0x0, 0x0, - 0xb0, 0x5, 0x8b, 0x87, 0xc, 0x0, 0x0, 0xb0, - 0x47, 0xb, 0x9, 0x9c, 0x0, 0x0, 0xb4, 0x40, - 0xa, 0x0, 0x2c, 0x0, 0x2, 0xa5, 0x55, 0x55, - 0x55, 0x5c, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, - - /* U+6B72 "歲" */ - 0x0, 0x0, 0x0, 0x21, 0x0, 0x0, 0x0, 0x0, - 0x3, 0x40, 0x66, 0x0, 0x50, 0x0, 0x0, 0x4, - 0x60, 0x68, 0x55, 0x50, 0x10, 0x6, 0x57, 0x85, - 0x88, 0x55, 0x57, 0xa0, 0x0, 0x0, 0x0, 0x6, - 0x63, 0x90, 0x0, 0x0, 0xb5, 0x55, 0x58, 0x95, - 0x79, 0x50, 0x0, 0xc0, 0x0, 0x21, 0x90, 0x24, - 0x0, 0x0, 0xc3, 0x6a, 0x72, 0xb0, 0x89, 0x0, - 0x0, 0xc2, 0x5a, 0x23, 0xa3, 0xc0, 0x0, 0x2, - 0xa7, 0x2a, 0xb6, 0x6e, 0x30, 0x0, 0x4, 0x64, - 0xf, 0x60, 0xad, 0x20, 0x40, 0x8, 0x0, 0x95, - 0x1a, 0x42, 0xd4, 0x80, 0x15, 0x47, 0x24, 0x71, - 0x0, 0x2c, 0xf0, 0x10, 0x10, 0x20, 0x0, 0x0, - 0x0, 0x10, - - /* U+6B73 "歳" */ - 0x0, 0x0, 0x0, 0x11, 0x0, 0x0, 0x0, 0x0, - 0x3, 0x50, 0x58, 0x0, 0x60, 0x0, 0x0, 0x4, - 0x70, 0x49, 0x55, 0x51, 0x10, 0x6, 0x57, 0x85, - 0x78, 0x55, 0x58, 0xa0, 0x0, 0x0, 0x0, 0x5, - 0x83, 0xa0, 0x0, 0x0, 0xa5, 0x55, 0x57, 0xa5, - 0x78, 0x60, 0x0, 0xb0, 0x0, 0x13, 0xa0, 0x14, - 0x0, 0x0, 0xb6, 0x5b, 0x54, 0xb0, 0x7b, 0x0, - 0x0, 0xa2, 0x3a, 0x40, 0x94, 0xd1, 0x0, 0x1, - 0x98, 0x3a, 0x57, 0x4f, 0x30, 0x0, 0x4, 0x84, - 0xa, 0x4, 0x9d, 0x20, 0x40, 0x7, 0x12, 0xa9, - 0x19, 0x43, 0xd3, 0x70, 0x6, 0x0, 0x4, 0x60, - 0x0, 0x2c, 0xe0, 0x10, 0x0, 0x20, 0x0, 0x0, - 0x0, 0x20, - - /* U+6B77 "歷" */ - 0x0, 0x0, 0x0, 0x0, 0x0, 0x1, 0x0, 0x1, - 0x95, 0x55, 0x55, 0x55, 0x5b, 0x50, 0x1, 0xa0, - 0x15, 0xc2, 0x1, 0x78, 0x0, 0x1, 0xa3, 0x5a, - 0x0, 0x4c, 0x20, 0x0, 0x1, 0xa5, 0x7b, 0xa3, - 0x6c, 0x58, 0x50, 0x1, 0xa0, 0xab, 0x20, 0x5e, - 0x60, 0x0, 0x2, 0x92, 0x99, 0xa1, 0x8a, 0x2a, - 0x0, 0x3, 0x87, 0x29, 0x6, 0xa, 0x5, 0x70, - 0x4, 0x70, 0x15, 0x12, 0x74, 0x0, 0x0, 0x6, - 0x30, 0x51, 0x2, 0x80, 0x50, 0x0, 0x8, 0x0, - 0xa0, 0x2, 0xa5, 0x52, 0x0, 0x7, 0x0, 0xa0, - 0x2, 0x80, 0x0, 0x0, 0x42, 0x55, 0xc5, 0x56, - 0xa5, 0x59, 0xb0, 0x0, 0x10, 0x0, 0x0, 0x0, - 0x0, 0x0, - - /* U+6B7B "死" */ - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x5, - 0x55, 0x55, 0x55, 0x55, 0x5a, 0xc0, 0x1, 0x3, - 0xa0, 0x0, 0xc0, 0x0, 0x0, 0x0, 0x7, 0x60, - 0x0, 0xc0, 0x0, 0x0, 0x0, 0xb, 0x10, 0x40, - 0xc0, 0x4, 0x60, 0x0, 0x1c, 0x56, 0xe1, 0xc0, - 0x2c, 0x40, 0x0, 0x85, 0x5, 0x80, 0xc3, 0x80, - 0x0, 0x1, 0x88, 0x3a, 0x20, 0xc3, 0x0, 0x0, - 0x7, 0x3, 0x6c, 0x0, 0xc0, 0x0, 0x0, 0x10, - 0x0, 0x94, 0x0, 0xc0, 0x0, 0x40, 0x0, 0x4, - 0x80, 0x0, 0xc0, 0x0, 0x70, 0x0, 0x38, 0x0, - 0x0, 0xc2, 0x11, 0xd2, 0x4, 0x50, 0x0, 0x0, - 0x59, 0x99, 0x70, 0x11, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, - - /* U+6B8A "殊" */ - 0x0, 0x0, 0x0, 0x0, 0x12, 0x0, 0x0, 0x0, - 0x0, 0x4, 0x6, 0x2c, 0x0, 0x0, 0x5, 0x99, - 0x55, 0x3a, 0x2a, 0x1, 0x0, 0x0, 0x84, 0x0, - 0x67, 0x6b, 0x59, 0x40, 0x0, 0xb6, 0x75, 0x80, - 0x2a, 0x0, 0x0, 0x0, 0xb0, 0x77, 0x20, 0x2a, - 0x0, 0x40, 0x3, 0x90, 0xa4, 0x55, 0xbc, 0x65, - 0x92, 0x7, 0x57, 0xc0, 0x2, 0xda, 0x60, 0x0, - 0x13, 0x5, 0x90, 0xa, 0x4a, 0x80, 0x0, 0x0, - 0x8, 0x20, 0x56, 0x2a, 0x38, 0x0, 0x0, 0x19, - 0x3, 0x80, 0x2a, 0xa, 0x80, 0x0, 0x71, 0x26, - 0x0, 0x2a, 0x1, 0xb4, 0x5, 0x10, 0x20, 0x0, - 0x2a, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, - - /* U+6B8B "残" */ - 0x0, 0x0, 0x0, 0x0, 0x20, 0x0, 0x0, 0x0, - 0x0, 0x5, 0x0, 0xc2, 0x60, 0x0, 0x5, 0x99, - 0x55, 0x10, 0xc0, 0x69, 0x0, 0x0, 0x83, 0x0, - 0x0, 0xc0, 0x6, 0x0, 0x0, 0xa0, 0x4, 0x35, - 0xd5, 0x57, 0x40, 0x0, 0xb5, 0x5d, 0x10, 0xb0, - 0x0, 0x0, 0x5, 0x80, 0x38, 0x0, 0xb6, 0x57, - 0x60, 0x8, 0x49, 0x64, 0x54, 0x94, 0x7, 0x10, - 0x21, 0x4, 0xa0, 0x0, 0x57, 0x4b, 0x0, 0x0, - 0x2, 0x80, 0x0, 0x1d, 0xb0, 0x0, 0x0, 0x9, - 0x0, 0x0, 0x4e, 0x50, 0x12, 0x0, 0x63, 0x0, - 0x18, 0x60, 0xc5, 0x60, 0x4, 0x30, 0x4, 0x50, - 0x0, 0x1b, 0xe0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x30, - - /* U+6BB5 "段" */ - 0x0, 0x0, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x43, 0x8b, 0x27, 0x55, 0x91, 0x0, 0x0, 0xc2, - 0x0, 0xc, 0x0, 0xb0, 0x0, 0x0, 0xb0, 0x0, - 0xc, 0x0, 0xb0, 0x0, 0x0, 0xc5, 0x68, 0xa, - 0x0, 0xc0, 0x10, 0x0, 0xb0, 0x0, 0x72, 0x0, - 0x59, 0x80, 0x0, 0xc5, 0x68, 0x55, 0x44, 0x78, - 0x0, 0x0, 0xb0, 0x0, 0x6, 0x0, 0xa3, 0x0, - 0x0, 0xb0, 0x2, 0x24, 0x42, 0xb0, 0x0, 0x14, - 0xd9, 0x73, 0x0, 0xbb, 0x30, 0x0, 0x19, 0xc0, - 0x0, 0x0, 0xbd, 0x10, 0x0, 0x0, 0xb0, 0x0, - 0x3a, 0x33, 0xd6, 0x0, 0x0, 0xb0, 0x35, 0x40, - 0x0, 0x1a, 0xc2, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, - - /* U+6BCD "母" */ - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x9, 0x65, 0x55, 0x55, 0xb5, 0x0, 0x0, 0xc, - 0x11, 0x50, 0x0, 0xa2, 0x0, 0x0, 0xd, 0x0, - 0x87, 0x0, 0xb1, 0x0, 0x0, 0xd, 0x0, 0x17, - 0x0, 0xc0, 0x0, 0x15, 0x5d, 0x55, 0x55, 0x55, - 0xe7, 0xc0, 0x0, 0x2a, 0x2, 0x30, 0x0, 0xd0, - 0x0, 0x0, 0x48, 0x0, 0xb5, 0x0, 0xd0, 0x0, - 0x0, 0x67, 0x0, 0x49, 0x1, 0xc0, 0x0, 0x0, - 0x85, 0x0, 0x0, 0x2, 0xb3, 0x60, 0x0, 0x86, - 0x55, 0x55, 0x57, 0xb5, 0x50, 0x0, 0x0, 0x0, - 0x2, 0x7, 0x70, 0x0, 0x0, 0x0, 0x0, 0x1, - 0xbf, 0x20, 0x0, 0x0, 0x0, 0x0, 0x0, 0x11, - 0x0, 0x0, - - /* U+6BCE "毎" */ - 0x0, 0x0, 0x30, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x5, 0xc0, 0x0, 0x0, 0x6, 0x0, 0x0, 0xc, - 0x55, 0x55, 0x55, 0x56, 0x20, 0x0, 0x84, 0x0, - 0x0, 0x0, 0x30, 0x0, 0x4, 0x26, 0x85, 0x5c, - 0x55, 0xd3, 0x0, 0x0, 0x8, 0x30, 0x1a, 0x0, - 0xc0, 0x0, 0x0, 0xa, 0x10, 0x38, 0x0, 0xc0, - 0x50, 0x16, 0x5d, 0x55, 0x89, 0x55, 0xd6, 0x71, - 0x0, 0xc, 0x0, 0x75, 0x0, 0xc0, 0x0, 0x0, - 0xb, 0x0, 0x83, 0x0, 0xc0, 0x0, 0x0, 0x5b, - 0x55, 0x96, 0x55, 0xd8, 0x80, 0x0, 0x1, 0x0, - 0x0, 0x3, 0xa0, 0x0, 0x0, 0x0, 0x0, 0x2, - 0x8d, 0x60, 0x0, 0x0, 0x0, 0x0, 0x0, 0x3, - 0x0, 0x0, - - /* U+6BCF "每" */ - 0x0, 0x0, 0x40, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x5, 0xc0, 0x0, 0x0, 0x5, 0x0, 0x0, 0xc, - 0x65, 0x55, 0x55, 0x58, 0x30, 0x0, 0x85, 0x0, - 0x0, 0x0, 0x30, 0x0, 0x5, 0x56, 0x95, 0x75, - 0x55, 0xd3, 0x0, 0x12, 0x7, 0x40, 0x87, 0x0, - 0xc0, 0x0, 0x0, 0x9, 0x30, 0x8, 0x0, 0xc0, - 0x60, 0x16, 0x5c, 0x66, 0x55, 0x55, 0xd5, 0x71, - 0x0, 0xc, 0x0, 0xa4, 0x0, 0xd0, 0x0, 0x0, - 0xc, 0x0, 0x2a, 0x0, 0xc0, 0x0, 0x0, 0x3c, - 0x55, 0x55, 0x55, 0xd8, 0xa0, 0x0, 0x1, 0x0, - 0x0, 0x3, 0x90, 0x0, 0x0, 0x0, 0x0, 0x1, - 0x8d, 0x50, 0x0, 0x0, 0x0, 0x0, 0x0, 0x3, - 0x0, 0x0, - - /* U+6BD4 "比" */ - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xb2, 0x0, - 0xc, 0x30, 0x0, 0x0, 0xc0, 0x0, 0xc, 0x0, - 0x0, 0x0, 0xc0, 0x0, 0xc, 0x0, 0xc, 0x30, - 0xc0, 0x0, 0xc, 0x0, 0xb7, 0x0, 0xc5, 0x5a, - 0x3c, 0x9, 0x30, 0x0, 0xc0, 0x0, 0xc, 0x60, - 0x0, 0x0, 0xc0, 0x0, 0xc, 0x0, 0x0, 0x0, - 0xc0, 0x0, 0xc, 0x0, 0x0, 0x0, 0xc0, 0x0, - 0xc, 0x0, 0x0, 0x40, 0xc0, 0x15, 0x2c, 0x0, - 0x0, 0x60, 0xdb, 0x70, 0xc, 0x31, 0x14, 0xc0, - 0x62, 0x0, 0x4, 0xaa, 0xaa, 0x60, - - /* U+6BDB "毛" */ - 0x0, 0x0, 0x0, 0x1, 0x5c, 0x30, 0x0, 0x0, - 0x14, 0x57, 0xb9, 0x74, 0x20, 0x0, 0x0, 0x20, - 0x0, 0xc0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0xc0, 0x0, 0x50, 0x0, 0x0, 0x24, 0x55, 0xd5, - 0x55, 0x62, 0x0, 0x0, 0x31, 0x0, 0xc0, 0x0, - 0x0, 0x0, 0x0, 0x0, 0x0, 0xc0, 0x1, 0x29, - 0x80, 0x4, 0x55, 0x55, 0xd5, 0x54, 0x21, 0x0, - 0x1, 0x0, 0x0, 0xc0, 0x0, 0x0, 0x10, 0x0, - 0x0, 0x0, 0xc0, 0x0, 0x0, 0x50, 0x0, 0x0, - 0x0, 0xd0, 0x0, 0x0, 0xa0, 0x0, 0x0, 0x0, - 0xbc, 0xbb, 0xbc, 0xc1, - - /* U+6C0F "氏" */ - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x4, 0x8e, 0x80, 0x0, 0xa5, 0x56, 0xd5, 0x31, - 0x0, 0x0, 0xb1, 0x0, 0xb1, 0x0, 0x0, 0x0, - 0xb1, 0x0, 0xa2, 0x0, 0x0, 0x0, 0xb5, 0x55, - 0xb7, 0x55, 0x6e, 0x30, 0xb1, 0x0, 0x56, 0x0, - 0x0, 0x0, 0xb1, 0x0, 0x2b, 0x0, 0x0, 0x0, - 0xb1, 0x0, 0xc, 0x30, 0x0, 0x0, 0xb1, 0x0, - 0x34, 0xd0, 0x0, 0x30, 0xb1, 0x66, 0x0, 0x8b, - 0x10, 0x70, 0xcd, 0x40, 0x0, 0x7, 0xe9, 0x70, - 0x62, 0x0, 0x0, 0x0, 0x2a, 0x90, 0x0, 0x0, - 0x0, 0x0, 0x0, 0x0, - - /* U+6C11 "民" */ - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x95, - 0x55, 0x55, 0x55, 0xc1, 0x0, 0xc, 0x0, 0x0, - 0x0, 0xc, 0x0, 0x0, 0xc0, 0x0, 0x0, 0x0, - 0xc0, 0x0, 0xc, 0x55, 0x5a, 0x55, 0x5d, 0x0, - 0x0, 0xc0, 0x0, 0xa1, 0x0, 0x0, 0x0, 0xc, - 0x0, 0x9, 0x20, 0x0, 0x53, 0x0, 0xc5, 0x55, - 0x99, 0x55, 0x55, 0x40, 0xc, 0x0, 0x1, 0xb0, - 0x0, 0x0, 0x0, 0xc0, 0x0, 0xa, 0x40, 0x0, - 0x0, 0xc, 0x1, 0x50, 0x2d, 0x20, 0x5, 0x0, - 0xd8, 0x80, 0x0, 0x4d, 0x41, 0x80, 0xc, 0x50, - 0x0, 0x0, 0x2b, 0xfc, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x1, 0x30, - - /* U+6C14 "气" */ - 0x0, 0x2, 0x10, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x8, 0x90, 0x0, 0x0, 0x0, 0x0, 0x0, 0xe, - 0x55, 0x55, 0x55, 0x7d, 0x10, 0x0, 0x65, 0x0, - 0x0, 0x0, 0x10, 0x0, 0x0, 0x90, 0x65, 0x55, - 0x57, 0x90, 0x0, 0x7, 0x10, 0x0, 0x0, 0x3, - 0x0, 0x0, 0x21, 0x36, 0x55, 0x55, 0x5c, 0x30, - 0x0, 0x0, 0x0, 0x0, 0x0, 0xb, 0x0, 0x0, - 0x0, 0x0, 0x0, 0x0, 0xa, 0x10, 0x0, 0x0, - 0x0, 0x0, 0x0, 0x9, 0x30, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x5, 0x70, 0x40, 0x0, 0x0, 0x0, - 0x0, 0x0, 0xc2, 0x80, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x3d, 0xc0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x30, - - /* U+6C17 "気" */ - 0x0, 0x0, 0x40, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x4, 0xc0, 0x0, 0x0, 0x2, 0x0, 0x0, 0xa, - 0x75, 0x55, 0x55, 0x59, 0x40, 0x0, 0x28, 0x55, - 0x55, 0x55, 0xa2, 0x0, 0x0, 0x90, 0x10, 0x0, - 0x0, 0x10, 0x0, 0x5, 0x16, 0x55, 0x55, 0x55, - 0xe0, 0x0, 0x1, 0x0, 0x0, 0xa, 0x60, 0xc0, - 0x0, 0x0, 0x4, 0x20, 0x3c, 0x0, 0xb0, 0x0, - 0x0, 0x0, 0x49, 0xc1, 0x0, 0xb0, 0x0, 0x0, - 0x0, 0xa, 0xc7, 0x0, 0xb0, 0x0, 0x0, 0x0, - 0x93, 0xc, 0x60, 0x83, 0x30, 0x0, 0x27, 0x10, - 0x2, 0x60, 0x2c, 0x51, 0x1, 0x30, 0x0, 0x0, - 0x0, 0x6, 0xe4, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x12, - - /* U+6C34 "水" */ - 0x0, 0x0, 0x0, 0x40, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, 0xb4, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0xb2, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0xb4, 0x0, 0x7a, 0x0, 0x5, 0x55, 0xa4, 0xb7, - 0x5, 0x80, 0x0, 0x1, 0x0, 0xd1, 0xb7, 0x63, - 0x0, 0x0, 0x0, 0x3, 0xa0, 0xb2, 0x80, 0x0, - 0x0, 0x0, 0x9, 0x40, 0xb1, 0x83, 0x0, 0x0, - 0x0, 0x1b, 0x0, 0xb1, 0x1c, 0x0, 0x0, 0x0, - 0x83, 0x0, 0xb1, 0x6, 0xb0, 0x0, 0x3, 0x60, - 0x0, 0xb1, 0x0, 0x9d, 0x40, 0x15, 0x0, 0x11, - 0xc1, 0x0, 0x8, 0x60, 0x0, 0x0, 0x2b, 0xd0, - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, - - /* U+6C37 "氷" */ - 0x0, 0x0, 0x0, 0x52, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, 0xa3, 0x0, 0x0, 0x0, 0x0, 0x20, - 0x0, 0xa2, 0x0, 0x10, 0x0, 0x0, 0x6a, 0x10, - 0xa3, 0x0, 0xd4, 0x0, 0x0, 0x6, 0x80, 0xa8, - 0x9, 0x30, 0x0, 0x4, 0x55, 0x66, 0xa8, 0x72, - 0x0, 0x0, 0x1, 0x0, 0x85, 0xa4, 0x70, 0x0, - 0x0, 0x0, 0x0, 0xc0, 0xa2, 0xa1, 0x0, 0x0, - 0x0, 0x7, 0x50, 0xa2, 0x3c, 0x0, 0x0, 0x0, - 0x1a, 0x0, 0xa2, 0x9, 0xb0, 0x0, 0x0, 0xa1, - 0x0, 0xa2, 0x0, 0xbd, 0x50, 0x8, 0x10, 0x22, - 0xc2, 0x0, 0x8, 0x20, 0x20, 0x0, 0x18, 0xc0, - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, - - /* U+6C38 "永" */ - 0x0, 0x0, 0x1, 0x20, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x8b, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x8, 0x0, 0x0, 0x0, 0x0, 0x0, 0x55, - 0x5a, 0x10, 0x1, 0x0, 0x0, 0x0, 0x10, 0xe, - 0x0, 0x2e, 0x10, 0x0, 0x0, 0x12, 0xd, 0x40, - 0xa2, 0x0, 0x3, 0x65, 0xa9, 0xc, 0x77, 0x20, - 0x0, 0x0, 0x0, 0xc1, 0xc, 0x55, 0x0, 0x0, - 0x0, 0x4, 0x80, 0xc, 0xb, 0x0, 0x0, 0x0, - 0xb, 0x0, 0xc, 0x5, 0xb0, 0x0, 0x0, 0x73, - 0x0, 0xc, 0x0, 0x9c, 0x20, 0x4, 0x40, 0x3, - 0x4c, 0x0, 0x8, 0xc2, 0x2, 0x0, 0x2, 0xd7, - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, - - /* U+6C42 "求" */ - 0x0, 0x0, 0x0, 0x30, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, 0xd2, 0x29, 0x20, 0x0, 0x0, 0x0, - 0x0, 0xd0, 0x3, 0xc0, 0x0, 0x5, 0x55, 0x55, - 0xe5, 0x55, 0x7d, 0x30, 0x1, 0x0, 0x0, 0xd3, - 0x0, 0x0, 0x0, 0x0, 0x56, 0x0, 0xd5, 0x0, - 0x65, 0x0, 0x0, 0xa, 0x90, 0xd7, 0x5, 0xb3, - 0x0, 0x0, 0x1, 0x60, 0xd2, 0xa5, 0x0, 0x0, - 0x0, 0x0, 0x36, 0xd0, 0x93, 0x0, 0x0, 0x0, - 0x39, 0x40, 0xd0, 0x1d, 0x30, 0x0, 0x3c, 0xa0, - 0x0, 0xd0, 0x3, 0xe8, 0x10, 0x6, 0x0, 0x32, - 0xe0, 0x0, 0x2d, 0x90, 0x0, 0x0, 0x3c, 0xb0, - 0x0, 0x0, 0x0, 0x0, 0x0, 0x1, 0x0, 0x0, - 0x0, 0x0, - - /* U+6C5A "汚" */ - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x92, 0x6, 0x55, 0x65, 0x5a, 0x10, 0x0, 0x3a, - 0x0, 0x4, 0x70, 0x0, 0x0, 0x0, 0x1, 0x20, - 0x6, 0x50, 0x0, 0x0, 0x27, 0x0, 0x76, 0x5b, - 0x75, 0x55, 0xb1, 0x7, 0x73, 0x20, 0xb, 0x0, - 0x0, 0x0, 0x0, 0x46, 0x0, 0xc, 0x0, 0x0, - 0x0, 0x0, 0x7, 0x0, 0x4b, 0x55, 0x5c, 0x40, - 0x0, 0x44, 0x0, 0x0, 0x0, 0xd, 0x0, 0x7, - 0xe0, 0x0, 0x0, 0x0, 0xc, 0x0, 0x0, 0xd0, - 0x0, 0x0, 0x0, 0x39, 0x0, 0x1, 0xd0, 0x0, - 0x0, 0x30, 0x86, 0x0, 0x0, 0xa0, 0x0, 0x0, - 0x3e, 0xd1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x2, - 0x0, 0x0, - - /* U+6C60 "池" */ - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0xa2, 0x0, 0x0, 0xb2, 0x0, 0x0, 0x0, 0x49, - 0x0, 0x0, 0xb0, 0x0, 0x0, 0x0, 0x0, 0x31, - 0xa0, 0xb0, 0x2, 0x0, 0x9, 0x10, 0x41, 0xa0, - 0xb4, 0x4c, 0x30, 0x3, 0xb1, 0x44, 0xb4, 0xc0, - 0xa, 0x0, 0x0, 0x26, 0x22, 0xa0, 0xb0, 0xb, - 0x0, 0x0, 0x7, 0x1, 0xa0, 0xb0, 0xb, 0x0, - 0x0, 0x35, 0x1, 0xa0, 0xb2, 0x4c, 0x0, 0x6, - 0xe1, 0x1, 0xa0, 0xb0, 0x76, 0x20, 0x0, 0xd0, - 0x1, 0xa0, 0x70, 0x0, 0x60, 0x0, 0xe0, 0x1, - 0xb0, 0x0, 0x0, 0xb4, 0x0, 0xa0, 0x0, 0x8a, - 0xaa, 0xaa, 0x91, - - /* U+6C7A "決" */ - 0x0, 0x0, 0x0, 0x0, 0x30, 0x0, 0x0, 0x0, - 0x75, 0x0, 0x1, 0xd0, 0x0, 0x0, 0x0, 0xd, - 0x0, 0x1, 0xb0, 0x0, 0x0, 0x0, 0x1, 0x5, - 0x76, 0xc5, 0x5c, 0x0, 0x7, 0x20, 0x40, 0x1, - 0xa0, 0xc, 0x0, 0x1, 0xe0, 0x60, 0x1, 0xa0, - 0xc, 0x0, 0x0, 0x43, 0x30, 0x2, 0x90, 0xc, - 0x0, 0x0, 0x8, 0x26, 0x57, 0xb5, 0x5a, 0x93, - 0x0, 0x27, 0x0, 0x7, 0x56, 0x0, 0x0, 0x5, - 0xe3, 0x0, 0xc, 0x9, 0x10, 0x0, 0x0, 0xc0, - 0x0, 0x57, 0x2, 0xc0, 0x0, 0x0, 0xe0, 0x1, - 0xa0, 0x0, 0x7c, 0x20, 0x0, 0x70, 0x28, 0x0, - 0x0, 0x7, 0xf4, 0x0, 0x0, 0x20, 0x0, 0x0, - 0x0, 0x10, - - /* U+6C88 "沈" */ - 0x0, 0x0, 0x0, 0x0, 0x20, 0x0, 0x0, 0x1, - 0x50, 0x0, 0x1, 0xd0, 0x0, 0x0, 0x0, 0x77, - 0x0, 0x1, 0xb0, 0x0, 0x0, 0x0, 0x3, 0x7, - 0x55, 0xc5, 0x57, 0x80, 0x14, 0x0, 0x4c, 0x1, - 0xa0, 0x7, 0x20, 0x9, 0x54, 0x11, 0x2, 0xa0, - 0x0, 0x0, 0x1, 0x25, 0x0, 0x4, 0xe5, 0x0, - 0x0, 0x0, 0x6, 0x0, 0x7, 0xb4, 0x0, 0x0, - 0x0, 0x62, 0x0, 0xc, 0x74, 0x0, 0x0, 0x14, - 0xc0, 0x0, 0x39, 0x64, 0x0, 0x10, 0x7, 0xb0, - 0x0, 0xa1, 0x64, 0x0, 0x50, 0x4, 0xa0, 0x7, - 0x20, 0x65, 0x0, 0x61, 0x5, 0xa0, 0x62, 0x0, - 0x3c, 0x99, 0xc4, 0x0, 0x23, 0x0, 0x0, 0x0, - 0x0, 0x0, - - /* U+6C92 "沒" */ - 0x0, 0x0, 0x0, 0x2, 0x0, 0x0, 0x0, 0x0, - 0x73, 0x0, 0x4b, 0x0, 0x0, 0x0, 0x0, 0x1d, - 0x0, 0x96, 0x55, 0x5d, 0x0, 0x0, 0x2, 0x13, - 0x80, 0x0, 0x1b, 0x0, 0x7, 0x0, 0x56, 0x10, - 0x0, 0x38, 0x0, 0x4, 0xb0, 0x73, 0x0, 0x3, - 0xd2, 0x0, 0x0, 0x55, 0x15, 0x65, 0x55, 0x6c, - 0x0, 0x0, 0x8, 0x0, 0x60, 0x0, 0x86, 0x0, - 0x0, 0x46, 0x0, 0x43, 0x1, 0xb0, 0x0, 0x6, - 0xf1, 0x0, 0xa, 0x1b, 0x20, 0x0, 0x0, 0xc0, - 0x0, 0x3, 0xf5, 0x0, 0x0, 0x0, 0xe0, 0x0, - 0x3b, 0x6c, 0x60, 0x0, 0x0, 0x80, 0x38, 0x71, - 0x1, 0x9f, 0xb2, 0x0, 0x2, 0x20, 0x0, 0x0, - 0x1, 0x20, - - /* U+6CB9 "油" */ - 0x0, 0x0, 0x0, 0x0, 0x20, 0x0, 0x0, 0x5, - 0x0, 0x0, 0xc, 0x10, 0x0, 0x0, 0x3c, 0x0, - 0x0, 0xb0, 0x0, 0x0, 0x0, 0x42, 0x20, 0xb, - 0x0, 0x40, 0x23, 0x0, 0x5b, 0x55, 0xc5, 0x5d, - 0x10, 0xb5, 0x14, 0xb0, 0xb, 0x0, 0xb0, 0x2, - 0x36, 0xb, 0x0, 0xb0, 0xb, 0x0, 0x0, 0x80, - 0xb5, 0x5c, 0x55, 0xc0, 0x0, 0x54, 0xb, 0x0, - 0xb0, 0xb, 0x1, 0x6d, 0x0, 0xb0, 0xb, 0x0, - 0xb0, 0x3, 0xc0, 0xb, 0x0, 0xb0, 0xb, 0x0, - 0x3b, 0x0, 0xb5, 0x5c, 0x55, 0xc0, 0x3, 0xb0, - 0xa, 0x0, 0x0, 0xa, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x0, - - /* U+6CBB "治" */ - 0x0, 0x0, 0x0, 0x0, 0x10, 0x0, 0x0, 0x0, - 0x53, 0x0, 0x1, 0xe1, 0x0, 0x0, 0x0, 0xe, - 0x10, 0x8, 0x40, 0x0, 0x0, 0x0, 0x4, 0x4, - 0x27, 0x0, 0x53, 0x0, 0x4, 0x0, 0x32, 0x80, - 0x0, 0xb, 0x50, 0x6, 0xa0, 0x6a, 0xc8, 0x65, - 0x55, 0xd0, 0x0, 0x80, 0x61, 0x0, 0x0, 0x0, - 0x20, 0x0, 0x6, 0x10, 0x95, 0x55, 0x5b, 0x0, - 0x0, 0xa, 0x0, 0xb0, 0x0, 0xb, 0x0, 0x4, - 0xb7, 0x0, 0xb0, 0x0, 0xb, 0x0, 0x0, 0x95, - 0x0, 0xb0, 0x0, 0xb, 0x0, 0x0, 0xb4, 0x0, - 0xc5, 0x55, 0x5b, 0x0, 0x0, 0x93, 0x0, 0xa0, - 0x0, 0x9, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, - - /* U+6CC1 "況" */ - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x82, 0x1, 0xa5, 0x55, 0x5b, 0x20, 0x0, 0x1d, - 0x0, 0xa0, 0x0, 0xb, 0x0, 0x0, 0x2, 0x3, - 0xa0, 0x0, 0xb, 0x0, 0x6, 0x0, 0x40, 0xa0, - 0x0, 0xb, 0x0, 0x4, 0xb0, 0x50, 0xc5, 0x55, - 0x5c, 0x0, 0x0, 0x64, 0x21, 0x77, 0x3b, 0x5, - 0x0, 0x0, 0x8, 0x0, 0x8, 0x1b, 0x0, 0x0, - 0x0, 0x37, 0x0, 0xa, 0xb, 0x0, 0x0, 0x6, - 0xe2, 0x0, 0xa, 0xb, 0x0, 0x0, 0x0, 0xd0, - 0x0, 0x74, 0xb, 0x0, 0x50, 0x0, 0xf0, 0x3, - 0x80, 0xb, 0x0, 0x80, 0x0, 0xa0, 0x46, 0x0, - 0x7, 0xa9, 0xc2, 0x0, 0x0, 0x10, 0x0, 0x0, - 0x0, 0x0, - - /* U+6CCA "泊" */ - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x51, - 0x0, 0x0, 0x5b, 0x0, 0x0, 0x1, 0xd0, 0x0, - 0x8, 0x10, 0x0, 0x0, 0x5, 0x3, 0x95, 0x85, - 0x55, 0xb0, 0x40, 0x2, 0x2b, 0x0, 0x0, 0x1a, - 0x3, 0xb0, 0x50, 0xb0, 0x0, 0x1, 0xa0, 0x9, - 0x16, 0xb, 0x0, 0x0, 0x1a, 0x0, 0x6, 0x10, - 0xc5, 0x55, 0x56, 0xa0, 0x0, 0x90, 0xb, 0x0, - 0x0, 0x1a, 0x4, 0xb6, 0x0, 0xb0, 0x0, 0x1, - 0xa0, 0xa, 0x30, 0xb, 0x0, 0x0, 0x1a, 0x0, - 0xb2, 0x0, 0xc5, 0x55, 0x56, 0xa0, 0x9, 0x30, - 0xb, 0x0, 0x0, 0x1a, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x0, - - /* U+6CD5 "法" */ - 0x0, 0x0, 0x0, 0x0, 0x40, 0x0, 0x0, 0x0, - 0x91, 0x0, 0x0, 0xb3, 0x0, 0x0, 0x0, 0x3a, - 0x0, 0x0, 0xb0, 0x0, 0x0, 0x0, 0x2, 0x34, - 0x65, 0xc5, 0x5a, 0x30, 0x26, 0x0, 0x50, 0x0, - 0xb0, 0x0, 0x0, 0x8, 0x71, 0x40, 0x0, 0xb0, - 0x0, 0x0, 0x1, 0x46, 0x0, 0x0, 0xb0, 0x0, - 0x60, 0x0, 0x7, 0x36, 0x56, 0xd5, 0x55, 0x51, - 0x0, 0x63, 0x0, 0x7, 0x90, 0x0, 0x0, 0x18, - 0xd0, 0x0, 0x2b, 0x0, 0x30, 0x0, 0x1, 0xb0, - 0x0, 0x91, 0x0, 0x57, 0x0, 0x3, 0xa0, 0x19, - 0x44, 0x55, 0x5c, 0x70, 0x2, 0x80, 0x2e, 0x95, - 0x20, 0x1, 0xa0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, - - /* U+6CE2 "波" */ - 0x0, 0x0, 0x0, 0x0, 0x30, 0x0, 0x0, 0x0, - 0x92, 0x0, 0x0, 0xb1, 0x0, 0x0, 0x0, 0x4a, - 0x0, 0x0, 0xb0, 0x0, 0x0, 0x0, 0x1, 0x4a, - 0x55, 0xc5, 0x5b, 0x70, 0x27, 0x0, 0x5b, 0x0, - 0xb0, 0x17, 0x0, 0x8, 0x73, 0x2b, 0x0, 0xb0, - 0x0, 0x0, 0x1, 0x27, 0xb, 0x56, 0xa5, 0x6a, - 0x0, 0x0, 0x16, 0xb, 0x5, 0x0, 0x84, 0x0, - 0x0, 0x81, 0xb, 0x6, 0x11, 0xa0, 0x0, 0x29, - 0xb0, 0x28, 0x0, 0xaa, 0x10, 0x0, 0x3, 0x90, - 0x72, 0x0, 0xab, 0x0, 0x0, 0x5, 0x91, 0x70, - 0x9, 0x45, 0xc3, 0x0, 0x3, 0x76, 0x5, 0x71, - 0x0, 0x3d, 0x80, 0x0, 0x0, 0x30, 0x0, 0x0, - 0x0, 0x0, - - /* U+6CE3 "泣" */ - 0x0, 0x0, 0x0, 0x2, 0x0, 0x0, 0x0, 0x0, - 0x82, 0x0, 0x8, 0x50, 0x0, 0x0, 0x0, 0x3c, - 0x0, 0x3, 0xb0, 0x0, 0x0, 0x0, 0x3, 0x5, - 0x55, 0x65, 0x5d, 0x30, 0x16, 0x0, 0x31, 0x0, - 0x0, 0x0, 0x0, 0x7, 0x90, 0x52, 0x0, 0x0, - 0xe1, 0x0, 0x0, 0x54, 0x20, 0x70, 0x2, 0xb0, - 0x0, 0x0, 0x8, 0x0, 0xa2, 0x5, 0x60, 0x0, - 0x0, 0x28, 0x0, 0x77, 0x8, 0x10, 0x0, 0x6, - 0xe3, 0x0, 0x49, 0x9, 0x0, 0x0, 0x0, 0xd1, - 0x0, 0x12, 0x7, 0x0, 0x0, 0x0, 0xe0, 0x0, - 0x0, 0x42, 0x1, 0x80, 0x0, 0xa0, 0x65, 0x55, - 0x55, 0x55, 0x51, - - /* U+6CE8 "注" */ - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x70, 0x0, 0x8, 0x50, 0x0, 0x0, 0x0, 0x6a, - 0x0, 0x1, 0xe0, 0x0, 0x0, 0x0, 0x4, 0x40, - 0x0, 0x20, 0x5, 0x50, 0x22, 0x0, 0x56, 0x55, - 0xd5, 0x55, 0x40, 0xb, 0x53, 0x30, 0x0, 0xc0, - 0x0, 0x0, 0x3, 0x67, 0x0, 0x0, 0xc0, 0x0, - 0x0, 0x0, 0x8, 0x4, 0x55, 0xd5, 0x6d, 0x10, - 0x0, 0x55, 0x1, 0x0, 0xc0, 0x0, 0x0, 0x17, - 0xe0, 0x0, 0x0, 0xc0, 0x0, 0x0, 0x3, 0xd0, - 0x0, 0x0, 0xc0, 0x0, 0x0, 0x4, 0xb0, 0x0, - 0x0, 0xc0, 0x2, 0x70, 0x4, 0xa0, 0x65, 0x55, - 0x55, 0x55, 0x50, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, - - /* U+6CF3 "泳" */ - 0x0, 0x0, 0x0, 0x13, 0x0, 0x0, 0x0, 0x0, - 0x82, 0x0, 0x6, 0xd2, 0x0, 0x0, 0x0, 0x2c, - 0x0, 0x0, 0x52, 0x0, 0x0, 0x0, 0x2, 0x32, - 0x65, 0xe1, 0x1, 0x0, 0x17, 0x0, 0x50, 0x0, - 0xe1, 0xb, 0x40, 0x7, 0x93, 0x20, 0x40, 0xc5, - 0x73, 0x0, 0x0, 0x47, 0x46, 0xd2, 0xc9, 0x10, - 0x0, 0x0, 0x8, 0x0, 0xb0, 0xc7, 0x10, 0x0, - 0x0, 0x55, 0x4, 0x70, 0xc2, 0x80, 0x0, 0x7, - 0xf1, 0xa, 0x10, 0xc0, 0xb3, 0x0, 0x0, 0xe0, - 0x37, 0x0, 0xc0, 0x3e, 0x30, 0x3, 0xd1, 0x60, - 0x11, 0xc0, 0x6, 0xa1, 0x1, 0xa0, 0x0, 0x4d, - 0xa0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x2, 0x0, - 0x0, 0x0, - - /* U+6D0B "洋" */ - 0x0, 0x0, 0x0, 0x0, 0x0, 0x10, 0x0, 0x0, - 0x60, 0x0, 0x92, 0x0, 0xd2, 0x0, 0x0, 0x69, - 0x0, 0x4b, 0x4, 0x70, 0x0, 0x0, 0x5, 0x20, - 0x3, 0x7, 0x5, 0x40, 0x12, 0x0, 0x45, 0x55, - 0xd5, 0x55, 0x40, 0xb, 0x50, 0x50, 0x0, 0xc0, - 0x2, 0x0, 0x2, 0x64, 0x23, 0x65, 0xd5, 0x59, - 0x10, 0x0, 0x8, 0x0, 0x0, 0xc0, 0x0, 0x0, - 0x0, 0x18, 0x0, 0x0, 0xc0, 0x1, 0x60, 0x5, - 0xb4, 0x36, 0x55, 0xd5, 0x55, 0x50, 0x0, 0xe1, - 0x0, 0x0, 0xc0, 0x0, 0x0, 0x0, 0xe0, 0x0, - 0x0, 0xc0, 0x0, 0x0, 0x0, 0xe0, 0x0, 0x0, - 0xd0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x20, - 0x0, 0x0, - - /* U+6D17 "洗" */ - 0x0, 0x0, 0x0, 0x0, 0x20, 0x0, 0x0, 0x1, - 0x60, 0x0, 0x40, 0xb2, 0x0, 0x0, 0x0, 0x87, - 0x2, 0xd0, 0xb0, 0x0, 0x0, 0x0, 0x12, 0x35, - 0x95, 0xc5, 0x5d, 0x20, 0x15, 0x0, 0x49, 0x0, - 0xb0, 0x0, 0x0, 0x7, 0x81, 0x54, 0x0, 0xb0, - 0x0, 0x0, 0x0, 0x55, 0x35, 0x55, 0xc5, 0x56, - 0xb0, 0x0, 0x7, 0x1, 0x1b, 0xa, 0x10, 0x0, - 0x0, 0x17, 0x0, 0x29, 0xa, 0x10, 0x0, 0x5, - 0xb4, 0x0, 0x57, 0xa, 0x10, 0x0, 0x0, 0xd2, - 0x0, 0xa2, 0xa, 0x10, 0x40, 0x0, 0xf1, 0x4, - 0x90, 0xa, 0x10, 0x80, 0x0, 0xe0, 0x57, 0x0, - 0x6, 0xb9, 0xd4, 0x0, 0x2, 0x10, 0x0, 0x0, - 0x0, 0x0, - - /* U+6D32 "洲" */ - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x10, 0x0, - 0x83, 0x0, 0xb0, 0x2, 0x0, 0xd0, 0x0, 0x1b, - 0x0, 0xb0, 0xc, 0x0, 0xb0, 0x0, 0x0, 0x40, - 0xb0, 0xa, 0x0, 0xb0, 0x7, 0x10, 0x50, 0xa0, - 0xa, 0x0, 0xb0, 0x3, 0xc1, 0x45, 0xb6, 0xa, - 0x70, 0xb0, 0x0, 0x26, 0x66, 0xa5, 0x6a, 0x84, - 0xb0, 0x0, 0x8, 0x62, 0x91, 0x1a, 0x10, 0xb0, - 0x0, 0x36, 0x4, 0x70, 0xa, 0x0, 0xb0, 0x6, - 0xe2, 0x8, 0x20, 0xa, 0x0, 0xb0, 0x0, 0xd0, - 0xa, 0x0, 0xa, 0x0, 0xb0, 0x0, 0xf0, 0x63, - 0x0, 0xb, 0x0, 0xb0, 0x0, 0x92, 0x40, 0x0, - 0x1, 0x0, 0xb0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, - - /* U+6D3B "活" */ - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x72, 0x0, 0x0, 0x15, 0xac, 0x0, 0x0, 0x2d, - 0x4, 0x57, 0xd6, 0x32, 0x0, 0x0, 0x3, 0x0, - 0x0, 0xb0, 0x0, 0x0, 0x24, 0x0, 0x30, 0x0, - 0xb0, 0x0, 0x20, 0x9, 0x64, 0x46, 0x55, 0xc5, - 0x55, 0x91, 0x1, 0x56, 0x0, 0x0, 0xb0, 0x0, - 0x0, 0x0, 0x16, 0x2, 0x0, 0xb0, 0x3, 0x0, - 0x0, 0x72, 0xc, 0x55, 0x55, 0x5e, 0x10, 0x18, - 0xd0, 0xc, 0x0, 0x0, 0xb, 0x0, 0x1, 0xb0, - 0xc, 0x0, 0x0, 0xb, 0x0, 0x3, 0xb0, 0xc, - 0x55, 0x55, 0x5c, 0x0, 0x2, 0x80, 0xc, 0x0, - 0x0, 0xc, 0x0, 0x0, 0x0, 0x2, 0x0, 0x0, - 0x2, 0x0, - - /* U+6D3E "派" */ - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x66, 0x0, 0x0, 0x26, 0xbc, 0x0, 0x0, 0xd, - 0x9, 0x65, 0x42, 0x0, 0x0, 0x0, 0x0, 0x39, - 0x20, 0x1, 0x6c, 0x0, 0x38, 0x1, 0x39, 0x2a, - 0x67, 0x20, 0x0, 0x9, 0x55, 0x9, 0x2b, 0x4, - 0x5, 0x40, 0x1, 0x7, 0xa, 0x1b, 0x6, 0x69, - 0x20, 0x0, 0x35, 0xb, 0xb, 0x9, 0x20, 0x0, - 0x0, 0xa0, 0xb, 0xb, 0x8, 0x10, 0x0, 0x19, - 0xd0, 0x19, 0xb, 0x3, 0x80, 0x0, 0x3, 0xb0, - 0x72, 0xb, 0x0, 0xa4, 0x0, 0x5, 0xa0, 0x70, - 0xc, 0x83, 0x1e, 0x80, 0x1, 0x56, 0x0, 0x9, - 0x10, 0x3, 0x40, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, - - /* U+6D41 "流" */ - 0x0, 0x0, 0x0, 0x3, 0x0, 0x0, 0x0, 0x0, - 0x60, 0x0, 0x9, 0x50, 0x1, 0x0, 0x0, 0x4b, - 0x27, 0x59, 0x75, 0x59, 0x40, 0x0, 0x4, 0x0, - 0x1d, 0x20, 0x0, 0x0, 0x32, 0x0, 0x40, 0x93, - 0x0, 0x70, 0x0, 0xc, 0x32, 0x37, 0x73, 0x34, - 0x98, 0x0, 0x3, 0x26, 0x7, 0x74, 0x20, 0x8, - 0x0, 0x0, 0x7, 0xa, 0x29, 0x30, 0xb0, 0x0, - 0x0, 0x63, 0xb, 0xb, 0x0, 0xb0, 0x0, 0x26, - 0xc0, 0xb, 0xb, 0x0, 0xb0, 0x0, 0x6, 0xa0, - 0xb, 0xb, 0x0, 0xb0, 0x30, 0x5, 0x90, 0x55, - 0xb, 0x0, 0xb0, 0x60, 0x6, 0x93, 0x60, 0xb, - 0x0, 0xb9, 0xc0, 0x0, 0x12, 0x0, 0x2, 0x0, - 0x0, 0x0, - - /* U+6D45 "浅" */ - 0x0, 0x0, 0x0, 0x0, 0x20, 0x0, 0x0, 0x0, - 0x56, 0x0, 0x0, 0xd2, 0x50, 0x0, 0x0, 0xd, - 0x20, 0x0, 0xc0, 0x86, 0x0, 0x0, 0x2, 0x4, - 0x0, 0xc0, 0x4, 0x20, 0x7, 0x20, 0x33, 0x45, - 0xd5, 0x56, 0x50, 0x2, 0xe0, 0x61, 0x10, 0xb0, - 0x0, 0x20, 0x0, 0x41, 0x60, 0x2, 0xc5, 0x57, - 0x90, 0x0, 0x6, 0x36, 0x43, 0xb0, 0x7, 0x0, - 0x0, 0xa, 0x0, 0x0, 0x83, 0x8a, 0x0, 0x4, - 0xb8, 0x0, 0x0, 0x3e, 0x80, 0x0, 0x0, 0x95, - 0x0, 0x1, 0xad, 0x30, 0x50, 0x0, 0xb4, 0x0, - 0x57, 0x11, 0xc4, 0x90, 0x0, 0x93, 0x13, 0x0, - 0x0, 0x1b, 0xf0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x20, - - /* U+6D74 "浴" */ - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x92, 0x0, 0x1d, 0x2, 0x70, 0x0, 0x0, 0x4c, - 0x0, 0xa3, 0x0, 0x3e, 0x20, 0x0, 0x3, 0x45, - 0x30, 0xa5, 0x7, 0x40, 0x17, 0x0, 0x62, 0x4, - 0xb6, 0x0, 0x0, 0x7, 0xa2, 0x30, 0xc, 0x13, - 0x60, 0x0, 0x0, 0x47, 0x0, 0xa2, 0x0, 0x69, - 0x10, 0x0, 0x9, 0x8, 0x70, 0x0, 0xb, 0xe2, - 0x0, 0x37, 0x51, 0xc5, 0x55, 0x5c, 0x0, 0x6, - 0xd2, 0x0, 0xc0, 0x0, 0x1b, 0x0, 0x0, 0xf0, - 0x0, 0xc0, 0x0, 0x1b, 0x0, 0x2, 0xf0, 0x0, - 0xd5, 0x55, 0x5b, 0x0, 0x1, 0xc0, 0x0, 0xc0, - 0x0, 0x1b, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, - - /* U+6D77 "海" */ - 0x0, 0x0, 0x0, 0x20, 0x0, 0x0, 0x0, 0x1, - 0x70, 0x4, 0xb0, 0x0, 0x0, 0x0, 0x0, 0x94, - 0x9, 0x75, 0x55, 0x5a, 0x40, 0x0, 0x12, 0x19, - 0x0, 0x0, 0x0, 0x0, 0x29, 0x4, 0x6a, 0x55, - 0x55, 0xa5, 0x0, 0x9, 0x25, 0x1c, 0x7, 0x30, - 0x91, 0x0, 0x0, 0x14, 0xc, 0x1, 0x80, 0xa0, - 0x20, 0x0, 0x64, 0x7c, 0x55, 0x55, 0xc5, 0x81, - 0x0, 0x80, 0x38, 0x7, 0x20, 0xb0, 0x0, 0x2a, - 0x80, 0x65, 0x3, 0x60, 0xb0, 0x0, 0x6, 0x60, - 0xb6, 0x55, 0x55, 0xd5, 0x90, 0x8, 0x60, 0x0, - 0x1, 0x11, 0xb0, 0x0, 0x5, 0x50, 0x0, 0x0, - 0x6f, 0x70, 0x0, 0x0, 0x0, 0x0, 0x0, 0x2, - 0x0, 0x0, - - /* U+6D88 "消" */ - 0x0, 0x0, 0x0, 0x0, 0x11, 0x0, 0x0, 0x6, - 0x20, 0x31, 0x2, 0xc0, 0x43, 0x0, 0x1e, 0x0, - 0xc3, 0x1a, 0xb, 0x20, 0x0, 0x40, 0x35, 0x51, - 0xa5, 0x10, 0x6, 0x10, 0x13, 0x85, 0x6c, 0x69, - 0x20, 0x3d, 0x5, 0xc, 0x0, 0x0, 0xc0, 0x0, - 0x50, 0x70, 0xd5, 0x55, 0x5d, 0x0, 0x0, 0x35, - 0xc, 0x0, 0x0, 0xc0, 0x0, 0x9, 0x0, 0xc0, - 0x0, 0xc, 0x0, 0x48, 0xb0, 0xd, 0x55, 0x55, - 0xd0, 0x0, 0x68, 0x0, 0xc0, 0x0, 0xc, 0x0, - 0x6, 0x70, 0xc, 0x0, 0x0, 0xc0, 0x0, 0x67, - 0x0, 0xc0, 0x4, 0xbc, 0x0, 0x0, 0x0, 0x1, - 0x0, 0x1, 0x10, - - /* U+6DBC "涼" */ - 0x0, 0x0, 0x0, 0x0, 0x10, 0x0, 0x0, 0x0, - 0x50, 0x0, 0x0, 0x94, 0x0, 0x0, 0x0, 0x69, - 0x0, 0x0, 0x16, 0x0, 0x60, 0x0, 0x6, 0x6, - 0x65, 0x55, 0x55, 0x51, 0x13, 0x0, 0x40, 0x65, - 0x55, 0x57, 0x0, 0x9, 0x60, 0x50, 0xb0, 0x0, - 0xb, 0x0, 0x1, 0x94, 0x20, 0xb0, 0x0, 0xb, - 0x0, 0x0, 0x8, 0x0, 0xb5, 0x57, 0x5c, 0x0, - 0x0, 0x26, 0x0, 0x50, 0x1a, 0x3, 0x0, 0x6, - 0xc1, 0x0, 0xa3, 0x1a, 0x33, 0x0, 0x0, 0xd0, - 0x3, 0xa0, 0x1a, 0x9, 0x50, 0x0, 0xd0, 0x18, - 0x0, 0x19, 0x1, 0xe0, 0x0, 0xc0, 0x50, 0x6, - 0xb8, 0x0, 0x30, 0x0, 0x0, 0x0, 0x0, 0x40, - 0x0, 0x0, - - /* U+6DF1 "深" */ - 0x0, 0x70, 0x4, 0x0, 0x0, 0x2, 0x10, 0x0, - 0x59, 0xa, 0x55, 0x55, 0x5b, 0x50, 0x0, 0x2, - 0x56, 0x47, 0x3, 0x43, 0x0, 0x32, 0x3, 0x10, - 0xa1, 0x10, 0x6b, 0x0, 0xc, 0x35, 0x6, 0x0, - 0xc2, 0x7, 0x0, 0x2, 0x16, 0x0, 0x0, 0xc0, - 0x2, 0x40, 0x0, 0x53, 0x16, 0x5b, 0xf8, 0x55, - 0x50, 0x0, 0xa0, 0x0, 0x2b, 0xc5, 0x10, 0x0, - 0x29, 0xb0, 0x0, 0xb1, 0xc0, 0xa0, 0x0, 0x4, - 0x90, 0x9, 0x20, 0xc0, 0x4c, 0x20, 0x6, 0x81, - 0x61, 0x0, 0xc0, 0x7, 0x80, 0x4, 0x60, 0x0, - 0x0, 0xc0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x0, - - /* U+6DF7 "混" */ - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x64, 0x2, 0x0, 0x0, 0x4, 0x0, 0x0, 0xd, - 0x17, 0x85, 0x55, 0x5d, 0x0, 0x0, 0x2, 0x47, - 0x85, 0x55, 0x5b, 0x0, 0x29, 0x0, 0x56, 0x50, - 0x0, 0xb, 0x0, 0x7, 0x72, 0x37, 0x50, 0x0, - 0xb, 0x0, 0x0, 0x17, 0x5, 0x65, 0x58, 0x57, - 0x0, 0x0, 0x7, 0xa, 0x20, 0xc, 0x6, 0x10, - 0x0, 0x63, 0xb, 0x5a, 0x3b, 0x88, 0x10, 0x18, - 0xf0, 0xb, 0x0, 0xd, 0x20, 0x0, 0x0, 0xc0, - 0xb, 0x0, 0xb, 0x0, 0x50, 0x1, 0xd0, 0xb, - 0x66, 0x2b, 0x0, 0x90, 0x0, 0x80, 0x8, 0x40, - 0xc, 0xab, 0xb0, - - /* U+6E05 "清" */ - 0x0, 0x0, 0x0, 0x0, 0x40, 0x0, 0x0, 0x1, - 0x91, 0x0, 0x0, 0xc0, 0x2, 0x0, 0x0, 0x59, - 0x26, 0x55, 0xc5, 0x58, 0x40, 0x0, 0x2, 0x3, - 0x55, 0xc5, 0x77, 0x0, 0x28, 0x4, 0x1, 0x10, - 0xb0, 0x0, 0x10, 0x7, 0x85, 0x55, 0x55, 0xa5, - 0x56, 0xb0, 0x0, 0x25, 0x2, 0x0, 0x0, 0x4, - 0x0, 0x0, 0x33, 0xb, 0x55, 0x55, 0x5c, 0x0, - 0x0, 0x80, 0xb, 0x55, 0x55, 0x5b, 0x0, 0x28, - 0xb0, 0xb, 0x0, 0x0, 0xb, 0x0, 0x4, 0xa0, - 0xb, 0x55, 0x55, 0x5b, 0x0, 0x5, 0x80, 0xb, - 0x0, 0x0, 0xb, 0x0, 0x5, 0x70, 0xb, 0x0, - 0x5, 0xc9, 0x0, 0x0, 0x0, 0x2, 0x0, 0x0, - 0x20, 0x0, - - /* U+6E07 "渇" */ - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x73, 0x9, 0x65, 0x55, 0x5c, 0x0, 0x0, 0x1d, - 0x9, 0x20, 0x0, 0xb, 0x0, 0x0, 0x2, 0x2b, - 0x65, 0x55, 0x5b, 0x0, 0x16, 0x0, 0x59, 0x20, - 0x0, 0xb, 0x0, 0x6, 0x91, 0x59, 0x85, 0x55, - 0x5b, 0x0, 0x0, 0x56, 0x3, 0xc4, 0x0, 0x0, - 0x10, 0x0, 0x8, 0x7, 0x85, 0x55, 0x57, 0xb0, - 0x0, 0x54, 0x5a, 0x30, 0x35, 0x3, 0x80, 0x6, - 0xe2, 0x27, 0x67, 0x62, 0x4, 0x70, 0x0, 0xc0, - 0x7, 0x60, 0x5, 0x14, 0x70, 0x0, 0xd0, 0x3, - 0xa9, 0x9a, 0x25, 0x60, 0x0, 0x70, 0x0, 0x0, - 0x0, 0x7e, 0x30, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x3, 0x0, - - /* U+6E08 "済" */ - 0x0, 0x0, 0x0, 0x2, 0x10, 0x0, 0x0, 0x0, - 0x72, 0x0, 0x1, 0xd1, 0x0, 0x0, 0x0, 0x1d, - 0x6, 0x65, 0x95, 0x88, 0x70, 0x0, 0x3, 0x0, - 0x60, 0x2, 0xb0, 0x0, 0x15, 0x0, 0x40, 0x1a, - 0x1b, 0x10, 0x0, 0x7, 0x80, 0x40, 0x7, 0xf4, - 0x0, 0x0, 0x0, 0x65, 0x2, 0x87, 0x2a, 0xb6, - 0x41, 0x0, 0x8, 0x46, 0x80, 0x0, 0xa9, 0x60, - 0x0, 0x45, 0x3, 0xa5, 0x55, 0xd0, 0x0, 0x7, - 0xe0, 0x4, 0x70, 0x0, 0xb0, 0x0, 0x0, 0xd0, - 0x7, 0x75, 0x55, 0xc0, 0x0, 0x1, 0xd0, 0xa, - 0x0, 0x0, 0xb0, 0x0, 0x0, 0x90, 0x54, 0x0, - 0x0, 0xb0, 0x0, 0x0, 0x0, 0x20, 0x0, 0x0, - 0x40, 0x0, - - /* U+6E09 "渉" */ - 0x0, 0x0, 0x0, 0x0, 0x20, 0x0, 0x0, 0x0, - 0x73, 0x0, 0x0, 0xa3, 0x0, 0x0, 0x0, 0x1d, - 0x0, 0x61, 0xa1, 0x0, 0x0, 0x0, 0x2, 0x30, - 0xa0, 0xa6, 0x59, 0x0, 0x26, 0x0, 0x50, 0xa0, - 0xa1, 0x0, 0x0, 0x8, 0x72, 0x55, 0xc5, 0xb6, - 0x56, 0xa0, 0x1, 0x47, 0x1, 0x10, 0x93, 0x0, - 0x0, 0x0, 0x17, 0x0, 0xd1, 0xa1, 0x19, 0x20, - 0x0, 0x82, 0x4, 0x70, 0xa1, 0x31, 0xd0, 0x18, - 0xd0, 0x9, 0x0, 0xa4, 0xd2, 0x30, 0x2, 0xb0, - 0x23, 0x0, 0x6c, 0x10, 0x0, 0x4, 0xb0, 0x0, - 0x8, 0x90, 0x0, 0x0, 0x2, 0x70, 0x6, 0x83, - 0x0, 0x0, 0x0, 0x0, 0x0, 0x41, 0x0, 0x0, - 0x0, 0x0, - - /* U+6E1B "減" */ - 0x0, 0x0, 0x0, 0x0, 0x3, 0x0, 0x0, 0x1, - 0x60, 0x0, 0x0, 0xc, 0x48, 0x0, 0x0, 0x78, - 0x0, 0x0, 0xb, 0x6, 0x50, 0x0, 0x4, 0x3b, - 0x55, 0x5c, 0x65, 0x92, 0x22, 0x0, 0x4b, 0x0, - 0x9, 0x10, 0x0, 0xb, 0x43, 0x2b, 0x46, 0xba, - 0x22, 0x70, 0x3, 0x56, 0xa, 0x0, 0x17, 0x36, - 0x70, 0x0, 0x16, 0xa, 0x95, 0xc7, 0x6b, 0x10, - 0x0, 0x72, 0xa, 0x90, 0xa2, 0xb9, 0x0, 0x18, - 0xc0, 0xa, 0x90, 0xa0, 0xe2, 0x0, 0x3, 0xa0, - 0x36, 0x95, 0xa6, 0xc5, 0x40, 0x4, 0x90, 0x91, - 0x0, 0x38, 0xc, 0x80, 0x3, 0x82, 0x50, 0x3, - 0x70, 0x3, 0xf3, 0x0, 0x2, 0x0, 0x2, 0x0, - 0x0, 0x12, - - /* U+6E21 "渡" */ - 0x0, 0x0, 0x0, 0x1, 0x10, 0x0, 0x0, 0x0, - 0x91, 0x0, 0x0, 0xb3, 0x0, 0x0, 0x0, 0x59, - 0x9, 0x55, 0x87, 0x55, 0xb1, 0x10, 0x1, 0x1b, - 0x7, 0x10, 0x80, 0x0, 0x1a, 0x10, 0x4b, 0xa, - 0x0, 0xa1, 0x40, 0x6, 0x65, 0xc, 0x5c, 0x55, - 0xc5, 0x40, 0x0, 0x6, 0xb, 0xa, 0x55, 0xb0, - 0x0, 0x0, 0x16, 0xb, 0x5, 0x0, 0x40, 0x0, - 0x0, 0x81, 0x19, 0x37, 0x55, 0xd4, 0x0, 0x18, - 0xd0, 0x46, 0x5, 0x15, 0x90, 0x0, 0x2, 0xb0, - 0x82, 0x0, 0xbb, 0x0, 0x0, 0x4, 0xb0, 0x90, - 0x7, 0x9b, 0x60, 0x0, 0x1, 0x66, 0x25, 0x73, - 0x0, 0x7e, 0xa1, 0x0, 0x1, 0x21, 0x0, 0x0, - 0x0, 0x10, - - /* U+6E29 "温" */ - 0x0, 0x81, 0x7, 0x55, 0x55, 0x91, 0x0, 0x0, - 0x47, 0xa, 0x0, 0x0, 0x90, 0x0, 0x0, 0x0, - 0x4b, 0x55, 0x55, 0xb0, 0x0, 0x17, 0x3, 0x1a, - 0x0, 0x0, 0x90, 0x0, 0x7, 0x55, 0xa, 0x0, - 0x0, 0xa0, 0x0, 0x0, 0x7, 0xa, 0x55, 0x55, - 0xa0, 0x0, 0x0, 0x35, 0x20, 0x0, 0x0, 0x3, - 0x0, 0x0, 0x81, 0xb5, 0xb5, 0x5c, 0x5d, 0x0, - 0x28, 0xc0, 0xb0, 0xa0, 0xa, 0xb, 0x0, 0x4, - 0xa0, 0xb0, 0xa0, 0xa, 0xb, 0x0, 0x5, 0x90, - 0xb0, 0xa0, 0xa, 0xb, 0x0, 0x5, 0x95, 0xc5, - 0xb5, 0x5c, 0x5d, 0xb1, 0x0, 0x1, 0x0, 0x0, - 0x0, 0x0, 0x0, - - /* U+6E2F "港" */ - 0x0, 0x0, 0x0, 0x20, 0x3, 0x0, 0x0, 0x0, - 0xa2, 0x0, 0x94, 0xb, 0x10, 0x0, 0x0, 0x49, - 0x0, 0x92, 0xb, 0x5, 0x0, 0x10, 0x2, 0x26, - 0xb6, 0x5c, 0x55, 0x10, 0xb, 0x24, 0x0, 0x92, - 0xb, 0x0, 0x10, 0x5, 0x65, 0x65, 0xa8, 0x5a, - 0x55, 0x81, 0x0, 0x5, 0x0, 0xb0, 0x3, 0x40, - 0x0, 0x0, 0x42, 0x7, 0xb5, 0x58, 0xb7, 0x0, - 0x0, 0x90, 0x55, 0xb0, 0x7, 0x36, 0xd2, 0x19, - 0xa4, 0x30, 0xc5, 0x59, 0x30, 0x0, 0x4, 0x80, - 0x0, 0xb0, 0x3, 0x13, 0x0, 0x6, 0x80, 0x0, - 0xb0, 0x0, 0x4, 0x30, 0x3, 0x50, 0x0, 0xba, - 0xaa, 0xac, 0x60, - - /* U+6E56 "湖" */ - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x2, - 0x60, 0x3, 0x90, 0x2, 0x0, 0x30, 0x0, 0x94, - 0x13, 0x70, 0xd, 0x55, 0xb0, 0x0, 0x1, 0x45, - 0x85, 0x1b, 0x1, 0x90, 0x44, 0x4, 0x26, 0x82, - 0x1c, 0x55, 0x90, 0xc, 0x25, 0x3, 0x70, 0xa, - 0x1, 0x90, 0x2, 0x6, 0x46, 0x86, 0xa, 0x1, - 0x90, 0x0, 0x43, 0xb2, 0x2a, 0xc, 0x55, 0x90, - 0x0, 0x90, 0xa0, 0xa, 0x19, 0x1, 0x90, 0x29, - 0xb0, 0xa0, 0xa, 0x46, 0x1, 0x90, 0x3, 0x90, - 0xb5, 0x59, 0x90, 0x1, 0x90, 0x5, 0x90, 0x80, - 0x5, 0x40, 0x22, 0x90, 0x2, 0x60, 0x0, 0x44, - 0x0, 0x4e, 0x50, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, - - /* U+6E90 "源" */ - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x1, - 0x91, 0x8, 0x55, 0x55, 0x57, 0xb0, 0x0, 0x68, - 0xc, 0x0, 0xc, 0x10, 0x0, 0x0, 0x1, 0x4c, - 0x2, 0x34, 0x4, 0x0, 0x35, 0x1, 0x3c, 0xc, - 0x55, 0x5c, 0x20, 0xb, 0x65, 0xc, 0xb, 0x0, - 0xb, 0x0, 0x2, 0x26, 0xc, 0xc, 0x55, 0x5c, - 0x0, 0x0, 0x16, 0xb, 0xb, 0x0, 0xb, 0x0, - 0x0, 0x71, 0x29, 0xa, 0x5d, 0x59, 0x0, 0x18, - 0xd0, 0x64, 0x6, 0xc, 0x22, 0x0, 0x2, 0xb0, - 0x90, 0x4a, 0xc, 0xa, 0x50, 0x4, 0xa3, 0x41, - 0x80, 0xc, 0x1, 0xe0, 0x2, 0x85, 0x4, 0x2, - 0x9d, 0x0, 0x30, 0x0, 0x10, 0x0, 0x0, 0x11, - 0x0, 0x0, - - /* U+6E96 "準" */ - 0x0, 0x10, 0x0, 0x10, 0x10, 0x0, 0x0, 0x0, - 0x94, 0x0, 0x95, 0x2a, 0x0, 0x0, 0x0, 0x5, - 0x31, 0xc5, 0x58, 0x59, 0x70, 0x8, 0x30, 0x48, - 0xb0, 0x1a, 0x2, 0x0, 0x1, 0x65, 0x62, 0xc5, - 0x6c, 0x57, 0x20, 0x0, 0x7, 0x10, 0xb0, 0x1a, - 0x15, 0x10, 0x3, 0xb3, 0x0, 0xc5, 0x6b, 0x44, - 0x20, 0x0, 0x91, 0x0, 0xd5, 0x6b, 0x57, 0x90, - 0x0, 0x82, 0x0, 0x46, 0x0, 0x0, 0x0, 0x5, - 0x55, 0x55, 0x7b, 0x55, 0x55, 0xa2, 0x1, 0x0, - 0x0, 0x29, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x29, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x29, - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x1, 0x0, - 0x0, 0x0, - - /* U+6E9D "溝" */ - 0x0, 0x0, 0x0, 0x21, 0x2, 0x10, 0x0, 0x0, - 0x70, 0x0, 0x67, 0x6, 0x70, 0x0, 0x0, 0x69, - 0x36, 0x98, 0x59, 0x87, 0x70, 0x0, 0x4, 0x20, - 0x65, 0x5, 0x54, 0x0, 0x31, 0x0, 0x46, 0x98, - 0x59, 0x85, 0x30, 0xc, 0x25, 0x36, 0x76, 0x97, - 0x75, 0x90, 0x5, 0x36, 0x2, 0x0, 0xb0, 0x3, - 0x0, 0x0, 0x34, 0xb, 0x55, 0xc5, 0x5d, 0x0, - 0x0, 0x90, 0xb, 0x55, 0xc5, 0x5b, 0x0, 0x29, - 0xa0, 0xb, 0x0, 0xb0, 0xb, 0x20, 0x6, 0x70, - 0x6c, 0x55, 0x65, 0x5c, 0x61, 0x7, 0x70, 0xb, - 0x0, 0x0, 0xb, 0x0, 0x5, 0x60, 0xb, 0x0, - 0x5, 0x9a, 0x0, 0x0, 0x0, 0x4, 0x0, 0x0, - 0x42, 0x0, - - /* U+6EFF "滿" */ - 0x0, 0x0, 0x0, 0x11, 0x0, 0x30, 0x0, 0x0, - 0x72, 0x0, 0x47, 0x0, 0xc0, 0x0, 0x0, 0x1d, - 0x36, 0x79, 0x55, 0xd5, 0x92, 0x0, 0x3, 0x20, - 0x36, 0x0, 0xb0, 0x0, 0x6, 0x0, 0x40, 0x49, - 0xa5, 0xc0, 0x0, 0x4, 0xb0, 0x50, 0x10, 0xb0, - 0x0, 0x0, 0x0, 0x74, 0x2c, 0x55, 0xc5, 0x58, - 0x90, 0x0, 0x7, 0xb, 0x61, 0xb3, 0x54, 0x60, - 0x0, 0x27, 0xb, 0x3b, 0xb0, 0xd8, 0x60, 0x5, - 0xd3, 0xb, 0x79, 0xd5, 0x6e, 0x60, 0x0, 0xc0, - 0xc, 0x11, 0xb3, 0x6, 0x60, 0x0, 0xe0, 0xb, - 0x0, 0xb0, 0x4, 0x60, 0x0, 0x90, 0xb, 0x0, - 0xb0, 0x5b, 0x50, 0x0, 0x0, 0x3, 0x0, 0x0, - 0x5, 0x0, - - /* U+6F22 "漢" */ - 0x0, 0x0, 0x0, 0x30, 0x0, 0x20, 0x0, 0x0, - 0x81, 0x0, 0xb0, 0x1, 0xa0, 0x40, 0x0, 0x4a, - 0x36, 0xc5, 0x56, 0xb5, 0x50, 0x0, 0x3, 0x31, - 0xb5, 0x56, 0x90, 0x0, 0x14, 0x0, 0x50, 0x40, - 0xa0, 0x31, 0x0, 0x9, 0x61, 0x4c, 0x55, 0xc5, - 0x5c, 0x0, 0x1, 0x56, 0xb, 0x0, 0xa0, 0xa, - 0x0, 0x0, 0x7, 0xa, 0x55, 0xc5, 0x58, 0x0, - 0x0, 0x63, 0x6, 0x55, 0xc5, 0x68, 0x0, 0x17, - 0xd0, 0x0, 0x1, 0x90, 0x0, 0x40, 0x1, 0xb0, - 0x65, 0x5a, 0x89, 0x55, 0x51, 0x2, 0xb0, 0x0, - 0x39, 0x5, 0x70, 0x0, 0x1, 0x80, 0x6, 0x70, - 0x0, 0x4d, 0x92, 0x0, 0x0, 0x41, 0x0, 0x0, - 0x0, 0x10, - - /* U+6F38 "漸" */ - 0x0, 0x0, 0x0, 0x50, 0x0, 0x0, 0x0, 0x0, - 0x92, 0x0, 0xc0, 0x0, 0x16, 0xc2, 0x0, 0x4a, - 0x65, 0xc5, 0x99, 0x51, 0x0, 0x0, 0x1, 0x10, - 0xb0, 0x28, 0x10, 0x0, 0x26, 0x4, 0xb5, 0xc5, - 0xd8, 0x10, 0x50, 0x8, 0x75, 0xb0, 0xb0, 0xb8, - 0x6c, 0x51, 0x1, 0x45, 0xb5, 0xc5, 0xb8, 0x1b, - 0x0, 0x0, 0x52, 0xb0, 0xb0, 0xb8, 0x1b, 0x0, - 0x0, 0xa0, 0x95, 0xc5, 0x69, 0xb, 0x0, 0x29, - 0xa3, 0x55, 0xc5, 0xa9, 0xb, 0x0, 0x4, 0x80, - 0x0, 0xb0, 0x9, 0xb, 0x0, 0x6, 0x80, 0x0, - 0xb0, 0x44, 0xb, 0x0, 0x4, 0x60, 0x0, 0xc1, - 0x60, 0xb, 0x0, 0x0, 0x0, 0x0, 0x42, 0x0, - 0x4, 0x0, - - /* U+6FC3 "濃" */ - 0x0, 0x0, 0x0, 0x3, 0x3, 0x0, 0x0, 0x1, - 0x60, 0x2, 0xa, 0xa, 0x3, 0x0, 0x0, 0x78, - 0xb, 0x5c, 0x5c, 0x5c, 0x20, 0x0, 0x4, 0x4b, - 0x5c, 0x5c, 0x5c, 0x0, 0x7, 0x11, 0x4b, 0xa, - 0xa, 0xb, 0x0, 0x3, 0xc5, 0x18, 0x55, 0x55, - 0x58, 0x0, 0x0, 0x57, 0x1c, 0x55, 0x55, 0x56, - 0x30, 0x0, 0x26, 0xb, 0x45, 0x55, 0x57, 0x0, - 0x1, 0xa2, 0xc, 0x55, 0x55, 0x55, 0x90, 0x5, - 0xe0, 0x1a, 0x73, 0x60, 0x36, 0x0, 0x0, 0xc0, - 0x37, 0x73, 0x39, 0x71, 0x0, 0x1, 0xd0, 0x81, - 0x75, 0x55, 0xb4, 0x10, 0x0, 0x42, 0x40, 0x77, - 0x0, 0x2a, 0x91, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, - - /* U+6FDF "濟" */ - 0x0, 0x0, 0x0, 0x3, 0x0, 0x0, 0x0, 0x2, - 0x60, 0x0, 0x1, 0xb0, 0x0, 0x10, 0x0, 0x95, - 0x46, 0x56, 0x66, 0x57, 0x80, 0x0, 0x12, 0x30, - 0xa, 0x2b, 0x15, 0x10, 0x27, 0x4, 0x3a, 0x98, - 0x93, 0x68, 0x10, 0x8, 0x76, 0xa, 0x64, 0xb4, - 0x68, 0x0, 0x0, 0x45, 0x36, 0x92, 0xa5, 0x97, - 0xa1, 0x0, 0x61, 0x65, 0x90, 0x62, 0x43, 0x61, - 0x0, 0xa0, 0xa, 0x75, 0x55, 0x5d, 0x0, 0x1a, - 0x90, 0xa, 0x10, 0x0, 0xc, 0x0, 0x5, 0x70, - 0xb, 0x55, 0x55, 0x5c, 0x0, 0x6, 0x70, 0x18, - 0x0, 0x0, 0xc, 0x0, 0x3, 0x41, 0x80, 0x0, - 0x0, 0xc, 0x0, 0x0, 0x2, 0x0, 0x0, 0x0, - 0x3, 0x0, - - /* U+7063 "灣" */ - 0x0, 0x0, 0x2, 0x1, 0x20, 0x2, 0x0, 0x2, - 0x50, 0x28, 0x10, 0x92, 0x9, 0x40, 0x0, 0xa4, - 0x97, 0x66, 0x57, 0x96, 0xa0, 0x0, 0x23, 0x34, - 0x26, 0x87, 0x17, 0x30, 0x16, 0x4, 0xa7, 0xa5, - 0x35, 0x89, 0x75, 0x7, 0x75, 0x33, 0x3a, 0x5b, - 0x23, 0x30, 0x1, 0x57, 0x99, 0x8a, 0x5b, 0x94, - 0x86, 0x0, 0x52, 0x16, 0x58, 0x57, 0x6a, 0x10, - 0x0, 0x90, 0x3, 0x22, 0x22, 0x2b, 0x0, 0x18, - 0xa0, 0xb, 0x33, 0x33, 0x37, 0x0, 0x4, 0x80, - 0x18, 0x55, 0x55, 0x5b, 0x50, 0x5, 0x70, 0x0, - 0x0, 0x0, 0xb, 0x0, 0x4, 0x70, 0x0, 0x0, - 0x17, 0xa4, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, - - /* U+706B "火" */ - 0x0, 0x0, 0x0, 0x30, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, 0xb6, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0xb3, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0xb3, 0x0, 0x10, 0x0, 0x0, 0x4, 0x0, 0xb3, - 0x0, 0xb6, 0x0, 0x0, 0x18, 0x0, 0xc3, 0x6, - 0x80, 0x0, 0x1, 0xc4, 0x0, 0xd4, 0x36, 0x0, - 0x0, 0x4, 0x70, 0x1, 0xc4, 0x40, 0x0, 0x0, - 0x0, 0x0, 0x6, 0x70, 0x80, 0x0, 0x0, 0x0, - 0x0, 0xc, 0x10, 0x47, 0x0, 0x0, 0x0, 0x0, - 0x85, 0x0, 0x9, 0x70, 0x0, 0x0, 0x8, 0x60, - 0x0, 0x0, 0xab, 0x40, 0x4, 0x72, 0x0, 0x0, - 0x0, 0x8, 0x80, 0x21, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, - - /* U+707D "災" */ - 0x0, 0x1, 0x0, 0x0, 0x0, 0x10, 0x0, 0x0, - 0xb, 0x40, 0x59, 0x0, 0xa5, 0x0, 0x0, 0x45, - 0x0, 0x90, 0x3, 0x60, 0x0, 0x0, 0x70, 0x6, - 0x0, 0x7, 0x0, 0x0, 0x0, 0x67, 0x3, 0x90, - 0x6, 0x60, 0x0, 0x0, 0xb, 0x20, 0x58, 0x0, - 0x94, 0x0, 0x0, 0x1, 0x0, 0x32, 0x0, 0x11, - 0x0, 0x0, 0x2, 0x0, 0xa7, 0x0, 0x10, 0x0, - 0x0, 0x9, 0x0, 0xc6, 0x3, 0xb0, 0x0, 0x0, - 0x7a, 0x2, 0xb3, 0x76, 0x0, 0x0, 0x0, 0x10, - 0xb, 0x40, 0x82, 0x0, 0x0, 0x0, 0x0, 0x97, - 0x0, 0xc, 0x60, 0x0, 0x1, 0x69, 0x30, 0x0, - 0x0, 0x9e, 0x81, 0x13, 0x0, 0x0, 0x0, 0x0, - 0x1, 0x0, - - /* U+70B9 "点" */ - 0x0, 0x0, 0x0, 0x51, 0x0, 0x0, 0x0, 0x0, - 0x0, 0xc, 0x10, 0x0, 0x0, 0x0, 0x0, 0x0, - 0xc5, 0x55, 0x6c, 0x10, 0x0, 0x0, 0xc, 0x0, - 0x0, 0x0, 0x0, 0x0, 0x0, 0xc0, 0x0, 0x0, - 0x0, 0x0, 0xc5, 0x59, 0x55, 0x5e, 0x10, 0x0, - 0xd, 0x0, 0x0, 0x0, 0xc0, 0x0, 0x0, 0xd0, - 0x0, 0x0, 0xc, 0x0, 0x0, 0xd, 0x55, 0x55, - 0x55, 0xc0, 0x0, 0x0, 0xb0, 0x0, 0x0, 0x8, - 0x0, 0x0, 0x30, 0x12, 0x2, 0x10, 0x14, 0x0, - 0x9, 0x0, 0xb1, 0xc, 0x0, 0x85, 0x9, 0x70, - 0x7, 0x10, 0x81, 0x2, 0x90, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x0, - - /* U+70BA "為" */ - 0x0, 0x0, 0x0, 0x11, 0x0, 0x0, 0x0, 0x0, - 0x2, 0xa0, 0x6a, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x61, 0xb2, 0x0, 0x0, 0x0, 0x0, 0x75, 0x56, - 0xc5, 0x56, 0xb0, 0x0, 0x0, 0x0, 0x9, 0x30, - 0x6, 0x50, 0x0, 0x0, 0x0, 0x1c, 0x55, 0x59, - 0x6d, 0x10, 0x0, 0x0, 0xa2, 0x0, 0x0, 0x47, - 0x0, 0x0, 0x6, 0x95, 0x55, 0x55, 0x96, 0xc1, - 0x0, 0x38, 0x0, 0x1, 0x3, 0x0, 0xb0, 0x2, - 0x72, 0x27, 0x6, 0x62, 0xa2, 0xa0, 0x13, 0xa, - 0x4, 0x90, 0xb0, 0x64, 0x80, 0x0, 0x6b, 0x0, - 0x50, 0x0, 0x7, 0x50, 0x0, 0x0, 0x0, 0x0, - 0x2, 0x8e, 0x10, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x3, 0x0, - - /* U+7121 "無" */ - 0x0, 0x0, 0x20, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x2d, 0x0, 0x0, 0x0, 0x0, 0x0, 0xb, 0x86, - 0x56, 0x56, 0xa2, 0x0, 0x6, 0xd0, 0xa0, 0xa0, - 0xb0, 0x0, 0x2, 0x3a, 0xa, 0xa, 0xb, 0x0, - 0x0, 0x0, 0xa0, 0xa0, 0xa0, 0xb0, 0x70, 0x2, - 0x6c, 0x5c, 0x5c, 0x5c, 0x55, 0x10, 0x0, 0xa0, - 0xa0, 0xa0, 0xb0, 0x0, 0x0, 0xa, 0xa, 0xa, - 0xb, 0x3, 0x0, 0x65, 0x85, 0x85, 0x85, 0x85, - 0x93, 0x0, 0x40, 0x23, 0x1, 0x50, 0x16, 0x0, - 0x1a, 0x0, 0xb1, 0x9, 0x40, 0x86, 0xc, 0x50, - 0x8, 0x30, 0x35, 0x2, 0x60, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x0, - - /* U+7136 "然" */ - 0x0, 0x3, 0x0, 0x0, 0x20, 0x0, 0x0, 0x0, - 0xe, 0x20, 0x0, 0xb2, 0x50, 0x0, 0x0, 0x49, - 0x2, 0x20, 0xb1, 0x4b, 0x0, 0x0, 0xa6, 0x5a, - 0x80, 0xb0, 0x7, 0x0, 0x2, 0xa9, 0x2b, 0x56, - 0xd6, 0x5b, 0x40, 0x8, 0x73, 0x6b, 0x0, 0xc5, - 0x0, 0x0, 0x32, 0x67, 0x74, 0x1, 0xa5, 0x30, - 0x0, 0x0, 0x3, 0xa0, 0x8, 0x30, 0xb1, 0x0, - 0x0, 0x2a, 0x0, 0x57, 0x0, 0x4d, 0x40, 0x4, - 0x70, 0x5, 0x30, 0x0, 0x6, 0x50, 0x11, 0x40, - 0x31, 0x4, 0x10, 0x34, 0x0, 0x1, 0xa0, 0x1c, - 0x1, 0xc0, 0xb, 0x40, 0xb, 0x70, 0xc, 0x0, - 0xa0, 0x4, 0x70, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, - - /* U+7159 "煙" */ - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0xd, 0x2, 0x65, 0x55, 0x55, 0xb3, 0x0, 0xc, - 0x0, 0x0, 0xb0, 0xb0, 0x0, 0x0, 0xc, 0x27, - 0x75, 0xc5, 0xd5, 0x90, 0x2, 0x1c, 0x92, 0xa0, - 0xb0, 0xb0, 0xb0, 0x8, 0x2d, 0x10, 0xa0, 0xb0, - 0xb0, 0xb0, 0x1d, 0xb, 0x0, 0xa0, 0xb0, 0xb0, - 0xb0, 0x0, 0xb, 0x0, 0xa5, 0x5a, 0x55, 0x60, - 0x0, 0x1b, 0x0, 0x0, 0xc, 0x0, 0x0, 0x0, - 0x39, 0xa2, 0x55, 0x5c, 0x59, 0x60, 0x0, 0x73, - 0x3b, 0x0, 0xb, 0x0, 0x0, 0x0, 0xa0, 0x2, - 0x0, 0xb, 0x0, 0x0, 0x7, 0x20, 0x5, 0x55, - 0x5c, 0x55, 0x97, 0x12, 0x0, 0x1, 0x0, 0x0, - 0x0, 0x0, - - /* U+71B1 "熱" */ - 0x0, 0x0, 0x20, 0x0, 0x1, 0x0, 0x0, 0x0, - 0x0, 0xd0, 0x0, 0xc, 0x0, 0x0, 0x0, 0x65, - 0xc6, 0x80, 0xb, 0x4, 0x0, 0x0, 0x0, 0xb0, - 0x24, 0x5c, 0x79, 0x0, 0x4, 0x77, 0x76, 0x72, - 0x19, 0x36, 0x0, 0x0, 0x96, 0x37, 0x92, 0x48, - 0x36, 0x0, 0x6, 0x20, 0xc0, 0x70, 0xb9, 0x38, - 0x0, 0x0, 0x65, 0xc7, 0x70, 0xb9, 0x6b, 0x2, - 0x0, 0x0, 0xb3, 0x46, 0x30, 0x18, 0xa2, 0x4, - 0xba, 0x62, 0x23, 0x0, 0x0, 0xb2, 0x1, 0x23, - 0x5, 0x1, 0x40, 0x24, 0x0, 0x0, 0x92, 0x7, - 0x50, 0xa3, 0xb, 0x40, 0x7, 0xa0, 0x2, 0x60, - 0x33, 0x4, 0x60, 0x1, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, - - /* U+71DF "營" */ - 0x0, 0x0, 0x30, 0x0, 0x2, 0x0, 0x0, 0x0, - 0x2b, 0x15, 0x2, 0xa1, 0x30, 0x0, 0x63, 0xc7, - 0x37, 0x4a, 0x84, 0x0, 0x6, 0x2c, 0x63, 0x86, - 0x94, 0x0, 0x0, 0x9, 0x12, 0x92, 0x90, 0x6b, - 0x0, 0x5, 0x22, 0x22, 0x62, 0x22, 0x64, 0x4, - 0x73, 0x43, 0x33, 0x36, 0x3a, 0x60, 0xa1, 0xc, - 0x55, 0x55, 0xd2, 0x30, 0x0, 0x0, 0xc5, 0x55, - 0x5c, 0x0, 0x0, 0x0, 0x15, 0x0, 0x0, 0x32, - 0x0, 0x0, 0xd, 0x55, 0x55, 0x55, 0xd2, 0x0, - 0x0, 0xc0, 0x0, 0x0, 0xc, 0x0, 0x0, 0xd, - 0x55, 0x55, 0x55, 0xd0, 0x0, 0x0, 0x70, 0x0, - 0x0, 0x5, 0x0, - - /* U+722D "爭" */ - 0x0, 0x0, 0x0, 0x0, 0x0, 0x10, 0x0, 0x0, - 0x2, 0x35, 0x7a, 0xdc, 0x0, 0x1, 0x54, 0x47, - 0x21, 0x2, 0x50, 0x0, 0x8, 0x50, 0x3a, 0x0, - 0x94, 0x0, 0x0, 0x9, 0x0, 0x60, 0x53, 0x0, - 0x0, 0x5, 0x55, 0x57, 0x56, 0x5c, 0x0, 0x0, - 0x0, 0x1, 0x90, 0x1, 0xa0, 0x13, 0x65, 0x55, - 0x6b, 0x55, 0x5c, 0x86, 0x0, 0x0, 0x1, 0x90, - 0x1, 0xa0, 0x0, 0x6, 0x55, 0x6b, 0x55, 0x5a, - 0x0, 0x0, 0x0, 0x1, 0x90, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x29, 0x0, 0x0, 0x0, 0x0, 0x4, - 0x8e, 0x70, 0x0, 0x0, 0x0, 0x0, 0x0, 0x50, - 0x0, 0x0, 0x0, - - /* U+7236 "父" */ - 0x0, 0x0, 0x47, 0x0, 0x30, 0x0, 0x0, 0x0, - 0x1, 0xd5, 0x0, 0x7, 0x60, 0x0, 0x0, 0xb, - 0x30, 0x0, 0x0, 0x7c, 0x0, 0x1, 0x81, 0x10, - 0x0, 0x5, 0x9, 0x50, 0x14, 0x0, 0x50, 0x0, - 0x1d, 0x10, 0x0, 0x0, 0x0, 0x52, 0x0, 0x85, - 0x0, 0x0, 0x0, 0x0, 0x9, 0x1, 0xb0, 0x0, - 0x0, 0x0, 0x0, 0x3, 0x8a, 0x30, 0x0, 0x0, - 0x0, 0x0, 0x0, 0xab, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x7, 0x76, 0xc3, 0x0, 0x0, 0x0, 0x2, - 0x94, 0x0, 0x3c, 0xc7, 0x30, 0x3, 0x75, 0x0, - 0x0, 0x0, 0x4a, 0x91, 0x12, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x0, - - /* U+7238 "爸" */ - 0x0, 0x0, 0x20, 0x0, 0x10, 0x0, 0x0, 0x0, - 0x1, 0xc4, 0x0, 0x6, 0x91, 0x0, 0x0, 0x29, - 0x41, 0x0, 0x77, 0x4d, 0x0, 0x3, 0x50, 0x7, - 0x39, 0x80, 0x2, 0x0, 0x0, 0x0, 0x4, 0xda, - 0x10, 0x0, 0x0, 0x0, 0x5, 0x96, 0x2, 0x8a, - 0x97, 0x63, 0x15, 0x68, 0x55, 0x55, 0x55, 0xb5, - 0x50, 0x0, 0xb, 0x0, 0xb0, 0x1, 0xa0, 0x0, - 0x0, 0xb, 0x0, 0xb0, 0x1, 0x90, 0x0, 0x0, - 0xb, 0x55, 0x85, 0x56, 0x90, 0x0, 0x0, 0xb, - 0x0, 0x0, 0x0, 0x3, 0x10, 0x0, 0xb, 0x0, - 0x0, 0x0, 0x5, 0x30, 0x0, 0x7, 0xba, 0xaa, - 0xaa, 0xad, 0x60, - - /* U+7247 "片" */ - 0x0, 0x0, 0x0, 0x0, 0x40, 0x0, 0x0, 0x0, - 0x64, 0x0, 0xd, 0x0, 0x0, 0x0, 0x8, 0x40, - 0x0, 0xc0, 0x0, 0x0, 0x0, 0x83, 0x0, 0xc, - 0x0, 0x0, 0x0, 0x8, 0x75, 0x55, 0xd5, 0x5b, - 0x70, 0x0, 0x93, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x9, 0x30, 0x0, 0x0, 0x0, 0x0, 0x0, 0xb6, - 0x55, 0x55, 0xc0, 0x0, 0x0, 0xc, 0x0, 0x0, - 0x1b, 0x0, 0x0, 0x1, 0xb0, 0x0, 0x1, 0xb0, - 0x0, 0x0, 0x83, 0x0, 0x0, 0x1b, 0x0, 0x0, - 0x28, 0x0, 0x0, 0x1, 0xb0, 0x0, 0x6, 0x0, - 0x0, 0x0, 0x1b, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x10, 0x0, - - /* U+725B "牛" */ - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x10, 0x1d, 0x0, 0x0, 0x0, 0x0, 0x4c, 0x0, - 0xc0, 0x0, 0x0, 0x0, 0x9, 0x50, 0xc, 0x0, - 0x17, 0x0, 0x0, 0xc5, 0x55, 0xd5, 0x55, 0x51, - 0x0, 0x73, 0x0, 0xc, 0x0, 0x0, 0x0, 0x15, - 0x0, 0x0, 0xc0, 0x0, 0x0, 0x4, 0x55, 0x55, - 0x5d, 0x55, 0x59, 0xc1, 0x10, 0x0, 0x0, 0xc0, - 0x0, 0x0, 0x0, 0x0, 0x0, 0xc, 0x0, 0x0, - 0x0, 0x0, 0x0, 0x0, 0xc0, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x1c, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x1, 0xc0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x0, - - /* U+7260 "牠" */ - 0x0, 0x2, 0x0, 0x0, 0x1, 0x0, 0x0, 0x0, - 0xc, 0x20, 0x0, 0xd, 0x0, 0x0, 0x5, 0x5b, - 0x0, 0x40, 0xb, 0x0, 0x0, 0x9, 0x4b, 0x0, - 0xb2, 0xb, 0x3, 0x0, 0xb, 0x5c, 0x93, 0xb0, - 0xc, 0x5c, 0x20, 0x8, 0xb, 0x5, 0xc5, 0x4b, - 0xa, 0x0, 0x51, 0xb, 0x1, 0xb0, 0xb, 0xb, - 0x0, 0x20, 0xb, 0x22, 0xb0, 0xb, 0xb, 0x0, - 0x0, 0x3d, 0x40, 0xb0, 0xb, 0x5c, 0x0, 0x2b, - 0x6b, 0x0, 0xb0, 0xb, 0x56, 0x0, 0x2, 0xb, - 0x0, 0xb0, 0xb, 0x0, 0x40, 0x0, 0xb, 0x0, - 0xb0, 0x0, 0x2, 0x70, 0x0, 0xb, 0x0, 0x5b, - 0x99, 0x9b, 0x90, 0x0, 0x7, 0x0, 0x0, 0x0, - 0x0, 0x0, - - /* U+7269 "物" */ - 0x0, 0x2, 0x0, 0x3, 0x0, 0x0, 0x0, 0x0, - 0xb, 0x20, 0xd, 0x30, 0x0, 0x0, 0x6, 0x7b, - 0x0, 0x2b, 0x0, 0x0, 0x0, 0x9, 0x2b, 0x11, - 0x88, 0x95, 0x95, 0xd1, 0xb, 0x5c, 0x66, 0x90, - 0xc0, 0xd0, 0xc0, 0x24, 0xb, 0x6, 0x15, 0x61, - 0xb0, 0xc0, 0x30, 0xb, 0x2, 0xa, 0x6, 0x70, - 0xc0, 0x0, 0xc, 0x62, 0x64, 0xb, 0x11, 0xb0, - 0x18, 0x9d, 0x2, 0x60, 0x3a, 0x2, 0xa0, 0x15, - 0xb, 0x4, 0x0, 0xb1, 0x4, 0x80, 0x0, 0xb, - 0x0, 0x8, 0x30, 0x6, 0x70, 0x0, 0xb, 0x0, - 0x63, 0x14, 0x2c, 0x30, 0x0, 0xb, 0x4, 0x0, - 0x3, 0xf8, 0x0, 0x0, 0x1, 0x0, 0x0, 0x0, - 0x0, 0x0, - - /* U+7279 "特" */ - 0x0, 0x4, 0x0, 0x0, 0x51, 0x0, 0x0, 0x0, - 0xc, 0x10, 0x0, 0xc0, 0x0, 0x0, 0x7, 0x3c, - 0x0, 0x55, 0xd5, 0x6b, 0x0, 0xb, 0x1c, 0x0, - 0x10, 0xc0, 0x0, 0x0, 0xc, 0x5d, 0x6a, 0x0, - 0xc0, 0x0, 0x20, 0x26, 0xc, 0x5, 0x55, 0x95, - 0x56, 0xa1, 0x40, 0xc, 0x2, 0x0, 0x0, 0xd0, - 0x0, 0x0, 0xc, 0x75, 0x55, 0x55, 0xd5, 0xc2, - 0x18, 0xbd, 0x0, 0x30, 0x0, 0xc0, 0x0, 0x7, - 0xc, 0x0, 0x66, 0x0, 0xc0, 0x0, 0x0, 0xc, - 0x0, 0x1c, 0x0, 0xc0, 0x0, 0x0, 0xc, 0x0, - 0x2, 0x11, 0xc0, 0x0, 0x0, 0xc, 0x0, 0x0, - 0x5e, 0x70, 0x0, 0x0, 0x2, 0x0, 0x0, 0x1, - 0x0, 0x0, - - /* U+72AC "犬" */ - 0x0, 0x0, 0x0, 0x30, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, 0xe2, 0x10, 0x0, 0x0, 0x0, 0x0, - 0x0, 0xe0, 0x4a, 0x10, 0x0, 0x0, 0x0, 0x0, - 0xd0, 0x8, 0x90, 0x0, 0x0, 0x0, 0x0, 0xc0, - 0x0, 0x30, 0x30, 0x6, 0x55, 0x56, 0xd7, 0x55, - 0x57, 0x91, 0x0, 0x0, 0x4, 0x95, 0x0, 0x0, - 0x0, 0x0, 0x0, 0x7, 0x65, 0x10, 0x0, 0x0, - 0x0, 0x0, 0xb, 0x11, 0x80, 0x0, 0x0, 0x0, - 0x0, 0x2b, 0x0, 0x74, 0x0, 0x0, 0x0, 0x0, - 0xb2, 0x0, 0xc, 0x30, 0x0, 0x0, 0xa, 0x40, - 0x0, 0x1, 0xe8, 0x10, 0x3, 0x81, 0x0, 0x0, - 0x0, 0x1c, 0xb1, 0x1, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, - - /* U+72AF "犯" */ - 0x1, 0x10, 0xb, 0x21, 0x0, 0x3, 0x0, 0x0, - 0x54, 0x88, 0xd, 0x55, 0x5d, 0x20, 0x0, 0xa, - 0x80, 0xc, 0x0, 0xc, 0x0, 0x0, 0x47, 0x80, - 0xc, 0x0, 0xc, 0x0, 0x5, 0x40, 0xb0, 0xc, - 0x0, 0xc, 0x0, 0x0, 0x3, 0xf0, 0xc, 0x0, - 0xc, 0x0, 0x0, 0xa, 0xa2, 0xc, 0x5, 0x4d, - 0x0, 0x0, 0x82, 0x93, 0xc, 0x1, 0xb7, 0x0, - 0x6, 0x20, 0xa2, 0xc, 0x0, 0x0, 0x10, 0x0, - 0x0, 0xb1, 0xc, 0x0, 0x0, 0x60, 0x0, 0x0, - 0xd0, 0xc, 0x0, 0x0, 0xb1, 0x1, 0x8d, 0x50, - 0x8, 0xcb, 0xbb, 0xd2, 0x0, 0x3, 0x0, 0x0, - 0x0, 0x0, 0x0, - - /* U+72B6 "状" */ - 0x0, 0x0, 0x10, 0x0, 0x10, 0x0, 0x0, 0x0, - 0x0, 0xe1, 0x0, 0xc2, 0x40, 0x0, 0x0, 0x0, - 0xc0, 0x0, 0xc0, 0x4d, 0x0, 0x6, 0x20, 0xc0, - 0x0, 0xc0, 0x8, 0x0, 0x1, 0xe0, 0xc0, 0x0, - 0xc0, 0x0, 0x70, 0x0, 0x91, 0xc5, 0x65, 0xd8, - 0x55, 0x61, 0x0, 0x0, 0xc0, 0x0, 0xc6, 0x0, - 0x0, 0x0, 0x6, 0xc0, 0x1, 0xa5, 0x10, 0x0, - 0x2, 0xa1, 0xc0, 0x5, 0x71, 0x70, 0x0, 0xd, - 0x20, 0xc0, 0xa, 0x10, 0xb0, 0x0, 0x0, 0x0, - 0xc0, 0x1a, 0x0, 0x6a, 0x0, 0x0, 0x0, 0xc0, - 0x91, 0x0, 0xd, 0x90, 0x0, 0x0, 0xd5, 0x30, - 0x0, 0x2, 0xc4, 0x0, 0x0, 0x21, 0x0, 0x0, - 0x0, 0x0, - - /* U+72C0 "狀" */ - 0x0, 0x0, 0x10, 0x0, 0x30, 0x0, 0x0, 0x0, - 0x40, 0xb2, 0x0, 0xb3, 0x30, 0x0, 0x0, 0xc0, - 0xb0, 0x0, 0xb1, 0x3a, 0x0, 0x0, 0xb0, 0xb0, - 0x0, 0xb1, 0x8, 0x0, 0x0, 0xb0, 0xb1, 0x22, - 0xb3, 0x23, 0x90, 0x2, 0x95, 0xc1, 0x32, 0xc7, - 0x22, 0x20, 0x0, 0x0, 0xb0, 0x0, 0xb7, 0x0, - 0x0, 0x3, 0x55, 0xc0, 0x0, 0xb6, 0x20, 0x0, - 0x0, 0x82, 0xb0, 0x4, 0x72, 0x80, 0x0, 0x0, - 0xa0, 0xb0, 0x9, 0x20, 0xb1, 0x0, 0x0, 0x90, - 0xb0, 0x1a, 0x0, 0x5b, 0x0, 0x5, 0x30, 0xb0, - 0x91, 0x0, 0xb, 0xa0, 0x5, 0x0, 0xb5, 0x30, - 0x0, 0x1, 0x81, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, - - /* U+72EC "独" */ - 0x0, 0x0, 0x0, 0x0, 0x3, 0x0, 0x0, 0x3, - 0x20, 0x79, 0x0, 0xd, 0x0, 0x0, 0x0, 0x76, - 0xb0, 0x0, 0xc, 0x0, 0x0, 0x0, 0x1e, 0x30, - 0x85, 0x5d, 0x59, 0x20, 0x1, 0x85, 0x60, 0xc0, - 0xc, 0xc, 0x0, 0x15, 0x3, 0xb0, 0xc0, 0xc, - 0xc, 0x0, 0x0, 0xb, 0xc0, 0xc0, 0xc, 0xc, - 0x0, 0x0, 0x57, 0xb0, 0xc0, 0xc, 0xc, 0x0, - 0x1, 0xa0, 0xc0, 0xd5, 0x5d, 0x5c, 0x0, 0x7, - 0x0, 0xc0, 0x10, 0xc, 0x2, 0x0, 0x10, 0x0, - 0xd0, 0x0, 0xc, 0x8, 0x20, 0x0, 0x2, 0xb1, - 0x24, 0x5d, 0x65, 0xd0, 0x0, 0x8e, 0x35, 0xc7, - 0x30, 0x0, 0x90, 0x0, 0x1, 0x0, 0x0, 0x0, - 0x0, 0x0, - - /* U+72ED "狭" */ - 0x0, 0x0, 0x0, 0x1, 0x10, 0x0, 0x0, 0x3, - 0x0, 0xb1, 0x4, 0xa0, 0x0, 0x0, 0x1, 0x87, - 0x50, 0x3, 0x80, 0x2, 0x0, 0x0, 0x7a, 0x6, - 0x57, 0xa5, 0x5a, 0x20, 0x4, 0x5a, 0x2, 0x3, - 0x80, 0x62, 0x0, 0x22, 0xa, 0x31, 0xb4, 0x70, - 0xb1, 0x0, 0x0, 0x2e, 0x50, 0xc5, 0x75, 0x20, - 0x0, 0x0, 0x95, 0x85, 0x68, 0x96, 0x59, 0x90, - 0x6, 0x33, 0x81, 0x8, 0x44, 0x0, 0x0, 0x32, - 0x4, 0x80, 0xc, 0x7, 0x0, 0x0, 0x0, 0x6, - 0x70, 0x56, 0x4, 0x70, 0x0, 0x3, 0x4c, 0x22, - 0xa0, 0x0, 0x98, 0x0, 0x0, 0xa5, 0x56, 0x0, - 0x0, 0x9, 0x90, 0x0, 0x1, 0x0, 0x0, 0x0, - 0x0, 0x0, - - /* U+732B "猫" */ - 0x0, 0x0, 0x0, 0x1, 0x0, 0x10, 0x0, 0x4, - 0x0, 0x67, 0xc, 0x20, 0xe1, 0x0, 0x0, 0x75, - 0xb0, 0xc, 0x0, 0xc0, 0x10, 0x0, 0x1e, 0x26, - 0x5d, 0x55, 0xd5, 0xb1, 0x1, 0x84, 0x60, 0xc, - 0x0, 0xc0, 0x0, 0x4, 0x3, 0xb0, 0x7, 0x0, - 0x61, 0x0, 0x0, 0xa, 0xb1, 0xb5, 0x77, 0x5a, - 0x60, 0x0, 0x46, 0xb1, 0x90, 0x56, 0x7, 0x40, - 0x1, 0x80, 0xb1, 0x90, 0x56, 0x7, 0x40, 0x15, - 0x0, 0xb1, 0xb5, 0x99, 0x5a, 0x40, 0x10, 0x0, - 0xc1, 0x90, 0x56, 0x7, 0x40, 0x1, 0x37, 0x81, - 0xb5, 0x99, 0x5a, 0x40, 0x0, 0x4c, 0x1, 0x80, - 0x0, 0x4, 0x20, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, - - /* U+733F "猿" */ - 0x0, 0x0, 0x0, 0x0, 0x20, 0x0, 0x0, 0x3, - 0x0, 0x83, 0x0, 0xc2, 0x1, 0x0, 0x1, 0x74, - 0xb1, 0x65, 0xd5, 0x69, 0x0, 0x0, 0x3e, 0x0, - 0x0, 0xc0, 0x0, 0x50, 0x1, 0x8a, 0x26, 0x55, - 0x65, 0x55, 0x60, 0x15, 0x7, 0x50, 0xb5, 0x55, - 0x5c, 0x0, 0x0, 0xd, 0x80, 0xb0, 0x0, 0xb, - 0x0, 0x0, 0x66, 0xa0, 0xd5, 0x76, 0x5b, 0x0, - 0x1, 0x81, 0xb0, 0x29, 0x46, 0x4, 0xb0, 0x7, - 0x2, 0xb0, 0x68, 0x8, 0x67, 0x0, 0x10, 0x4, - 0xa5, 0x97, 0x1, 0xc0, 0x0, 0x0, 0x8, 0x80, - 0x46, 0x42, 0x5c, 0x30, 0x1, 0x9e, 0x0, 0x5c, - 0x20, 0x4, 0xb2, 0x0, 0x1, 0x0, 0x1, 0x0, - 0x0, 0x0, - - /* U+7372 "獲" */ - 0x0, 0x0, 0x0, 0x1, 0x0, 0x10, 0x0, 0x2, - 0x0, 0x63, 0x9, 0x20, 0xa3, 0x40, 0x2, 0x82, - 0xb4, 0x6b, 0x65, 0xb6, 0x61, 0x0, 0x2e, 0x10, - 0x55, 0x37, 0x30, 0x0, 0x0, 0x9a, 0x10, 0xd6, - 0x5a, 0x58, 0x50, 0x6, 0x16, 0x56, 0xc3, 0x3c, - 0x38, 0x0, 0x0, 0xb, 0x93, 0xb2, 0x2b, 0x27, - 0x0, 0x0, 0x48, 0xa0, 0xc5, 0x5c, 0x55, 0x40, - 0x0, 0x90, 0xb0, 0xc5, 0x56, 0x55, 0x60, 0x7, - 0x10, 0xb0, 0x66, 0x55, 0x7b, 0x0, 0x11, 0x1, - 0xa0, 0x5, 0x31, 0xb2, 0x0, 0x0, 0x4, 0x80, - 0x0, 0x9d, 0x20, 0x0, 0x1, 0x8d, 0x30, 0x17, - 0x86, 0xb7, 0x52, 0x0, 0x25, 0x14, 0x40, 0x0, - 0x4, 0x50, - - /* U+73A9 "玩" */ - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x5, - 0x55, 0x6a, 0x15, 0x55, 0x59, 0x50, 0x1, 0xd, - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xd, 0x0, - 0x0, 0x0, 0x0, 0x0, 0x0, 0xd, 0x0, 0x0, - 0x0, 0x0, 0x31, 0x5, 0x5e, 0x95, 0x68, 0x75, - 0xa5, 0x85, 0x0, 0xd, 0x0, 0x8, 0x40, 0xc0, - 0x0, 0x0, 0xd, 0x0, 0xa, 0x20, 0xc0, 0x0, - 0x0, 0xd, 0x0, 0xc, 0x0, 0xc0, 0x0, 0x0, - 0xd, 0x34, 0x1b, 0x0, 0xc0, 0x0, 0x16, 0x99, - 0x20, 0x75, 0x0, 0xc0, 0x22, 0x9, 0x10, 0x3, - 0xa0, 0x0, 0xc0, 0x44, 0x0, 0x0, 0x57, 0x0, - 0x0, 0xba, 0xd8, 0x0, 0x2, 0x10, 0x0, 0x0, - 0x0, 0x0, - - /* U+73FE "現" */ - 0x4, 0x55, 0x68, 0x85, 0x55, 0x58, 0x30, 0x1, - 0xb, 0x0, 0xb0, 0x0, 0x8, 0x20, 0x0, 0xb, - 0x0, 0xb5, 0x55, 0x5a, 0x20, 0x0, 0xb, 0x0, - 0xb0, 0x0, 0x8, 0x20, 0x0, 0xb, 0x23, 0xb4, - 0x44, 0x4a, 0x20, 0x4, 0x6c, 0x53, 0xb0, 0x0, - 0x8, 0x20, 0x0, 0xb, 0x0, 0xb5, 0x55, 0x5a, - 0x20, 0x0, 0xb, 0x0, 0x82, 0xb0, 0xa4, 0x10, - 0x0, 0xb, 0x1, 0x6, 0x60, 0xa0, 0x0, 0x1, - 0x4d, 0x53, 0xc, 0x10, 0xa0, 0x40, 0x1c, 0x60, - 0x0, 0x76, 0x0, 0xa0, 0x70, 0x0, 0x0, 0x7, - 0x50, 0x0, 0xca, 0xd4, 0x0, 0x0, 0x30, 0x0, - 0x0, 0x0, 0x0, - - /* U+7403 "球" */ - 0x0, 0x0, 0x0, 0x0, 0x2, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x0, 0x1c, 0x18, 0x10, 0x6, 0x57, - 0x77, 0x0, 0x1b, 0x6, 0x60, 0x0, 0x1a, 0x2, - 0x55, 0x6c, 0x55, 0xc4, 0x0, 0x1a, 0x0, 0x0, - 0x1d, 0x0, 0x0, 0x0, 0x1a, 0x13, 0x70, 0x1e, - 0x11, 0xb0, 0x5, 0x6c, 0x64, 0x96, 0x1b, 0x69, - 0x30, 0x0, 0x1a, 0x0, 0x12, 0x1b, 0x91, 0x0, - 0x0, 0x1a, 0x0, 0x2, 0x7b, 0x38, 0x0, 0x0, - 0x1c, 0x65, 0x87, 0x1b, 0xb, 0x60, 0xa, 0xb4, - 0x8, 0x50, 0x1b, 0x1, 0xe7, 0x4, 0x0, 0x0, - 0x1, 0x2a, 0x0, 0x10, 0x0, 0x0, 0x0, 0x5, - 0xf7, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x20, - 0x0, 0x0, - - /* U+7406 "理" */ - 0x0, 0x0, 0x0, 0x53, 0x33, 0x37, 0x10, 0x6, - 0x58, 0x85, 0xb1, 0x1b, 0x1b, 0x0, 0x0, 0xb, - 0x0, 0xa0, 0xa, 0xa, 0x0, 0x0, 0xb, 0x0, - 0xb5, 0x5c, 0x5c, 0x0, 0x0, 0xb, 0x21, 0xa0, - 0xa, 0xa, 0x0, 0x6, 0x6d, 0x74, 0xb0, 0xa, - 0xa, 0x0, 0x0, 0xb, 0x0, 0xb5, 0x5c, 0x5a, - 0x0, 0x0, 0xb, 0x0, 0x0, 0xa, 0x0, 0x0, - 0x0, 0xc, 0x54, 0x55, 0x5c, 0x5a, 0x20, 0x7, - 0xb8, 0x10, 0x0, 0xa, 0x0, 0x0, 0x6, 0x0, - 0x0, 0x0, 0xa, 0x0, 0x40, 0x0, 0x0, 0x36, - 0x55, 0x56, 0x55, 0x71, - - /* U+74B0 "環" */ - 0x0, 0x0, 0x40, 0x75, 0x55, 0x57, 0x40, 0x6, - 0x6b, 0x52, 0xa0, 0x90, 0x95, 0x30, 0x0, 0x19, - 0x0, 0xc5, 0xa5, 0xa8, 0x30, 0x0, 0x19, 0x0, - 0x20, 0x0, 0x0, 0x40, 0x4, 0x6b, 0xa6, 0x55, - 0x55, 0x55, 0x50, 0x1, 0x29, 0x0, 0x85, 0x55, - 0x5b, 0x0, 0x0, 0x19, 0x0, 0xa1, 0x0, 0x9, - 0x0, 0x0, 0x19, 0x0, 0xa6, 0xb7, 0x58, 0x20, - 0x0, 0x1a, 0x52, 0xa, 0x37, 0x16, 0x90, 0x9, - 0xb6, 0x0, 0x8d, 0x1, 0xc2, 0x0, 0x3, 0x0, - 0x26, 0x1b, 0x14, 0x2c, 0x60, 0x0, 0x0, 0x0, - 0xc, 0x80, 0x1, 0x70, 0x0, 0x0, 0x0, 0x1, - 0x0, 0x0, 0x0, - - /* U+7518 "甘" */ - 0x0, 0x0, 0x40, 0x0, 0x2, 0x0, 0x0, 0x0, - 0x0, 0xe0, 0x0, 0xc, 0x20, 0x0, 0x0, 0x0, - 0xc0, 0x0, 0xc, 0x0, 0x0, 0x0, 0x0, 0xc0, - 0x0, 0xc, 0x2, 0x80, 0x6, 0x55, 0xd5, 0x55, - 0x5d, 0x55, 0x51, 0x0, 0x0, 0xc0, 0x0, 0xc, - 0x0, 0x0, 0x0, 0x0, 0xc0, 0x0, 0xc, 0x0, - 0x0, 0x0, 0x0, 0xd5, 0x55, 0x5d, 0x0, 0x0, - 0x0, 0x0, 0xc0, 0x0, 0xc, 0x0, 0x0, 0x0, - 0x0, 0xc0, 0x0, 0xc, 0x0, 0x0, 0x0, 0x0, - 0xc0, 0x0, 0xc, 0x0, 0x0, 0x0, 0x0, 0xe5, - 0x55, 0x5d, 0x0, 0x0, 0x0, 0x0, 0xd0, 0x0, - 0xb, 0x10, 0x0, 0x0, 0x0, 0x10, 0x0, 0x0, - 0x0, 0x0, - - /* U+751A "甚" */ - 0x0, 0x0, 0x40, 0x0, 0x3, 0x0, 0x0, 0x0, - 0x0, 0xc0, 0x0, 0xc, 0x10, 0x0, 0x2, 0x65, - 0xd5, 0x55, 0x5d, 0x5a, 0x50, 0x0, 0x0, 0xc0, - 0x0, 0xc, 0x0, 0x0, 0x0, 0x0, 0xc5, 0x55, - 0x5d, 0x0, 0x0, 0x0, 0x0, 0xc0, 0x0, 0xc, - 0x0, 0x0, 0x0, 0x0, 0xc5, 0x55, 0x5d, 0x0, - 0x0, 0x0, 0x0, 0xc0, 0x0, 0xc, 0x0, 0x20, - 0x17, 0x5a, 0x85, 0x55, 0x58, 0x55, 0x91, 0x0, - 0xc, 0x1, 0xc0, 0x35, 0x0, 0x0, 0x0, 0xc, - 0x9, 0x40, 0x7, 0xb0, 0x0, 0x0, 0xc, 0x64, - 0x0, 0x0, 0x90, 0x0, 0x0, 0xe, 0x75, 0x55, - 0x55, 0x5d, 0x30, 0x0, 0x3, 0x0, 0x0, 0x0, - 0x0, 0x0, - - /* U+751F "生" */ - 0x0, 0x0, 0x0, 0x12, 0x0, 0x0, 0x0, 0x0, - 0x3, 0x10, 0x2c, 0x0, 0x0, 0x0, 0x0, 0x9, - 0x80, 0x2a, 0x0, 0x0, 0x0, 0x0, 0xc, 0x0, - 0x2a, 0x0, 0x5, 0x0, 0x0, 0x49, 0x55, 0x6c, - 0x55, 0x58, 0x30, 0x0, 0x90, 0x0, 0x2a, 0x0, - 0x0, 0x0, 0x2, 0x50, 0x0, 0x2a, 0x0, 0x0, - 0x0, 0x5, 0x0, 0x0, 0x2a, 0x0, 0x54, 0x0, - 0x0, 0x5, 0x55, 0x6c, 0x55, 0x54, 0x0, 0x0, - 0x0, 0x0, 0x2a, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x2a, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x2a, 0x0, 0x0, 0x60, 0x6, 0x55, 0x55, 0x56, - 0x55, 0x56, 0x72, - - /* U+7522 "產" */ - 0x0, 0x0, 0x0, 0x40, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x6, 0x40, 0x0, 0x40, 0x0, 0x55, 0x67, - 0x55, 0x6d, 0x65, 0x0, 0x0, 0x0, 0x27, 0x89, - 0x30, 0x0, 0x0, 0x0, 0x25, 0x65, 0xb4, 0x0, - 0x0, 0x7, 0x67, 0x55, 0x56, 0xb5, 0xc2, 0x0, - 0xc0, 0x23, 0x7, 0x10, 0x0, 0x0, 0xb, 0x8, - 0x60, 0xb0, 0x1, 0x0, 0x0, 0xb0, 0xc5, 0x5c, - 0x55, 0x84, 0x0, 0xa, 0x62, 0x0, 0xb0, 0x1, - 0x0, 0x2, 0x72, 0x46, 0x5c, 0x55, 0x80, 0x0, - 0x61, 0x0, 0x0, 0xb0, 0x0, 0x0, 0x6, 0x15, - 0x55, 0x5c, 0x55, 0x5a, 0x71, 0x0, 0x10, 0x0, - 0x0, 0x0, 0x0, - - /* U+7523 "産" */ - 0x0, 0x0, 0x0, 0x40, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x6, 0x50, 0x0, 0x60, 0x0, 0x55, 0x75, - 0x55, 0x76, 0x56, 0x10, 0x0, 0x2, 0x90, 0x8, - 0x60, 0x0, 0x0, 0x20, 0x8, 0x0, 0x70, 0x4, - 0x0, 0xc, 0x55, 0x55, 0x85, 0x55, 0x62, 0x0, - 0xb0, 0x57, 0xb, 0x10, 0x0, 0x0, 0xb, 0xa, - 0x30, 0xb0, 0x2, 0x50, 0x0, 0xb1, 0xa5, 0x5c, - 0x55, 0x54, 0x0, 0x19, 0x60, 0x0, 0xb0, 0x5, - 0x0, 0x4, 0x60, 0x36, 0x5c, 0x55, 0x51, 0x0, - 0x70, 0x0, 0x0, 0xb0, 0x0, 0x0, 0x6, 0x15, - 0x55, 0x5c, 0x55, 0x5b, 0x51, 0x0, 0x10, 0x0, - 0x0, 0x0, 0x0, - - /* U+7528 "用" */ - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8, - 0x65, 0x55, 0x75, 0x55, 0xd1, 0x0, 0x83, 0x0, - 0xa, 0x0, 0xc, 0x0, 0x8, 0x30, 0x0, 0xa0, - 0x0, 0xc0, 0x0, 0x87, 0x55, 0x5c, 0x55, 0x5c, - 0x0, 0x8, 0x30, 0x0, 0xa0, 0x0, 0xc0, 0x0, - 0x93, 0x0, 0xa, 0x0, 0xc, 0x0, 0x9, 0x20, - 0x0, 0xa0, 0x0, 0xc0, 0x0, 0xb5, 0x55, 0x5c, - 0x55, 0x5c, 0x0, 0xc, 0x0, 0x0, 0xa0, 0x0, - 0xc0, 0x2, 0x80, 0x0, 0x1a, 0x0, 0xc, 0x0, - 0x71, 0x0, 0x1, 0xa0, 0x22, 0xd0, 0x6, 0x0, - 0x0, 0x17, 0x3, 0xc9, 0x1, 0x0, 0x0, 0x0, - 0x0, 0x1, 0x0, - - /* U+7530 "田" */ - 0x10, 0x0, 0x0, 0x0, 0x10, 0xc5, 0x55, 0xa6, - 0x55, 0xa6, 0xc0, 0x0, 0xa1, 0x0, 0x84, 0xc0, - 0x0, 0xa1, 0x0, 0x84, 0xc0, 0x0, 0xa1, 0x0, - 0x84, 0xc5, 0x55, 0xc6, 0x55, 0xa4, 0xc0, 0x0, - 0xa1, 0x0, 0x84, 0xc0, 0x0, 0xa1, 0x0, 0x84, - 0xc0, 0x0, 0xa1, 0x0, 0x84, 0xc0, 0x0, 0xa1, - 0x0, 0x84, 0xc5, 0x55, 0x55, 0x55, 0xa4, 0x40, - 0x0, 0x0, 0x0, 0x20, - - /* U+7531 "由" */ - 0x0, 0x0, 0x10, 0x0, 0x0, 0x0, 0x0, 0xb, - 0x30, 0x0, 0x0, 0x0, 0x0, 0xa1, 0x0, 0x0, - 0x2, 0x0, 0xa, 0x10, 0x0, 0x40, 0xc5, 0x55, - 0xc6, 0x55, 0x5e, 0x1c, 0x0, 0xa, 0x10, 0x0, - 0xc0, 0xc0, 0x0, 0xa1, 0x0, 0xc, 0xc, 0x0, - 0xa, 0x10, 0x0, 0xc0, 0xc5, 0x55, 0xc6, 0x55, - 0x5c, 0xc, 0x0, 0xa, 0x10, 0x0, 0xc0, 0xc0, - 0x0, 0xa1, 0x0, 0xc, 0xc, 0x0, 0xa, 0x10, - 0x0, 0xc0, 0xc5, 0x55, 0x55, 0x55, 0x5c, 0x0, - 0x0, 0x0, 0x0, 0x0, 0x0, - - /* U+7533 "申" */ - 0x0, 0x0, 0x40, 0x0, 0x0, 0x0, 0x0, 0xc2, - 0x0, 0x0, 0x20, 0x0, 0xb0, 0x0, 0x30, 0xc5, - 0x55, 0xc5, 0x55, 0xd3, 0xc0, 0x0, 0xb0, 0x0, - 0xb0, 0xc5, 0x55, 0xc5, 0x55, 0xc0, 0xc0, 0x0, - 0xb0, 0x0, 0xb0, 0xc0, 0x0, 0xb0, 0x0, 0xb0, - 0xc5, 0x55, 0xc5, 0x55, 0xc1, 0xb0, 0x0, 0xb0, - 0x0, 0x70, 0x0, 0x0, 0xb0, 0x0, 0x0, 0x0, - 0x0, 0xb0, 0x0, 0x0, 0x0, 0x0, 0xb1, 0x0, - 0x0, 0x0, 0x0, 0x30, 0x0, 0x0, - - /* U+7535 "电" */ - 0x0, 0x0, 0x30, 0x0, 0x0, 0x0, 0x0, 0x0, - 0xc1, 0x0, 0x0, 0x0, 0x0, 0x0, 0xc0, 0x0, - 0x0, 0x0, 0xa5, 0x55, 0xd5, 0x55, 0xb4, 0x0, - 0xc0, 0x0, 0xc0, 0x0, 0xc0, 0x0, 0xc0, 0x0, - 0xc0, 0x0, 0xc0, 0x0, 0xc5, 0x55, 0xd5, 0x55, - 0xd0, 0x0, 0xc0, 0x0, 0xc0, 0x0, 0xc0, 0x0, - 0xc0, 0x0, 0xc0, 0x0, 0xc0, 0x0, 0xd5, 0x55, - 0xd5, 0x55, 0xa0, 0x10, 0x30, 0x0, 0xc0, 0x0, - 0x0, 0x50, 0x0, 0x0, 0xc0, 0x0, 0x0, 0xa0, - 0x0, 0x0, 0x8b, 0xaa, 0xab, 0xd0, - - /* U+7537 "男" */ - 0x0, 0x0, 0x0, 0x0, 0x1, 0x0, 0x0, 0xc5, - 0x55, 0xa5, 0x5c, 0x20, 0x0, 0xb0, 0x1, 0xa0, - 0xb, 0x0, 0x0, 0xc5, 0x55, 0xc5, 0x5c, 0x0, - 0x0, 0xb0, 0x1, 0xa0, 0xb, 0x0, 0x0, 0xd5, - 0x55, 0xc5, 0x5c, 0x10, 0x0, 0x80, 0x1, 0x80, - 0x5, 0x0, 0x0, 0x0, 0x3, 0xa0, 0x0, 0x30, - 0x6, 0x55, 0x59, 0x95, 0x55, 0xe1, 0x0, 0x0, - 0xa, 0x20, 0x1, 0xb0, 0x0, 0x0, 0x3a, 0x0, - 0x4, 0x80, 0x0, 0x4, 0xa0, 0x4, 0x8, 0x40, - 0x4, 0x86, 0x0, 0x1, 0xdc, 0x0, 0x31, 0x0, - 0x0, 0x0, 0x10, 0x0, - - /* U+753A "町" */ - 0x0, 0x0, 0x10, 0x0, 0x0, 0x24, 0xb, 0x5a, - 0x5c, 0x56, 0x5b, 0x65, 0x50, 0xb0, 0xb0, 0xa0, - 0x0, 0xa2, 0x0, 0xb, 0xb, 0xa, 0x0, 0xa, - 0x20, 0x0, 0xb0, 0xb0, 0xa0, 0x0, 0xa2, 0x0, - 0xb, 0x5c, 0x5c, 0x0, 0xa, 0x20, 0x0, 0xb0, - 0xb0, 0xa0, 0x0, 0xa2, 0x0, 0xb, 0xb, 0xa, - 0x0, 0xa, 0x20, 0x0, 0xb0, 0xb0, 0xa0, 0x0, - 0xa2, 0x0, 0xc, 0x55, 0x5c, 0x10, 0xa, 0x20, - 0x0, 0x60, 0x0, 0x0, 0x0, 0xa2, 0x0, 0x0, - 0x0, 0x0, 0x3, 0xae, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x20, 0x0, 0x0, - - /* U+753B "画" */ - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x3, 0x65, - 0x55, 0x55, 0x55, 0x59, 0xb0, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x0, 0x0, 0x0, 0x85, 0x56, 0x59, - 0x40, 0x0, 0x1, 0xc, 0x0, 0xa0, 0xb0, 0x8, - 0x1, 0xb0, 0xb0, 0xa, 0xb, 0x0, 0xb0, 0x1a, - 0xc, 0x55, 0xc5, 0xc0, 0xb, 0x1, 0xa0, 0xb0, - 0xa, 0xb, 0x0, 0xb0, 0x1a, 0xb, 0x0, 0xa0, - 0xb0, 0xb, 0x1, 0xa0, 0xb0, 0xa, 0xb, 0x0, - 0xb0, 0x1a, 0xc, 0x55, 0x55, 0xa0, 0xb, 0x3, - 0xb5, 0x55, 0x55, 0x55, 0x55, 0xb0, 0x3, 0x0, - 0x0, 0x0, 0x0, 0x8, 0x0, - - /* U+754C "界" */ - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0xb, 0x55, 0x57, 0x55, 0x97, 0x0, 0x0, 0xb, - 0x0, 0x19, 0x0, 0x74, 0x0, 0x0, 0xc, 0x55, - 0x6b, 0x55, 0x94, 0x0, 0x0, 0xb, 0x0, 0x19, - 0x0, 0x74, 0x0, 0x0, 0xc, 0x55, 0xb7, 0x75, - 0x94, 0x0, 0x0, 0x1, 0x7, 0x70, 0x34, 0x0, - 0x0, 0x0, 0x0, 0x7b, 0x0, 0x7, 0x93, 0x0, - 0x0, 0x29, 0x4a, 0x40, 0x2b, 0x2a, 0xe3, 0x4, - 0x30, 0xc, 0x0, 0x1a, 0x0, 0x0, 0x0, 0x0, - 0x2a, 0x0, 0x1a, 0x0, 0x0, 0x0, 0x1, 0xa1, - 0x0, 0x1a, 0x0, 0x0, 0x0, 0x46, 0x0, 0x0, - 0x2a, 0x0, 0x0, 0x1, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, - - /* U+7559 "留" */ - 0x0, 0x0, 0x1, 0x0, 0x0, 0x0, 0x0, 0x22, - 0x69, 0x80, 0x0, 0x0, 0x40, 0xc, 0x20, 0x0, - 0x6a, 0x95, 0x6b, 0x0, 0xb0, 0x17, 0x10, 0x93, - 0x3, 0x80, 0xb, 0x1, 0x7d, 0x1b, 0x0, 0x56, - 0x1, 0xd9, 0x60, 0x49, 0x22, 0x6b, 0x30, 0x7, - 0x0, 0x16, 0x20, 0x3, 0x70, 0x0, 0x59, 0x55, - 0x59, 0x55, 0x6c, 0x0, 0x4, 0x80, 0x1, 0xb0, - 0x1, 0xa0, 0x0, 0x4a, 0x55, 0x6c, 0x55, 0x6a, - 0x0, 0x4, 0x80, 0x1, 0xb0, 0x1, 0xa0, 0x0, - 0x48, 0x0, 0x1b, 0x0, 0x1b, 0x0, 0x5, 0xa5, - 0x55, 0x65, 0x56, 0xb0, 0x0, 0x11, 0x0, 0x0, - 0x0, 0x0, 0x0, - - /* U+756A "番" */ - 0x0, 0x0, 0x0, 0x0, 0x0, 0x30, 0x0, 0x0, - 0x0, 0x24, 0x79, 0xbb, 0x10, 0x0, 0x36, 0x64, - 0xa2, 0x9, 0x10, 0x0, 0x0, 0xb, 0x9, 0x24, - 0x60, 0x0, 0x6, 0x55, 0x88, 0xc8, 0x75, 0x57, - 0x40, 0x0, 0x4, 0x99, 0x27, 0x0, 0x0, 0x0, - 0x6, 0x60, 0x92, 0x9, 0x71, 0x0, 0x26, 0x40, - 0x8, 0x10, 0x8, 0xd7, 0x11, 0xb, 0x55, 0x97, - 0x55, 0xd2, 0x0, 0x0, 0xb0, 0x7, 0x40, 0xb, - 0x0, 0x0, 0xb, 0x55, 0xa7, 0x55, 0xc0, 0x0, - 0x0, 0xb0, 0x7, 0x40, 0xb, 0x0, 0x0, 0xb, - 0x55, 0x55, 0x55, 0xb0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x0, - - /* U+756B "畫" */ - 0x0, 0x0, 0x0, 0x12, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x2b, 0x0, 0x30, 0x0, 0x0, 0x6, - 0x55, 0x6b, 0x55, 0xd1, 0x20, 0x3, 0x65, 0x55, - 0x6b, 0x55, 0xc5, 0x70, 0x0, 0x7, 0x55, 0x6b, - 0x55, 0xc0, 0x0, 0x0, 0x5, 0x55, 0x6b, 0x55, - 0x76, 0x0, 0x0, 0x23, 0x22, 0x3a, 0x22, 0x25, - 0x20, 0x0, 0x45, 0x33, 0x33, 0x33, 0x53, 0x10, - 0x0, 0xd, 0x55, 0x6b, 0x55, 0xb4, 0x0, 0x0, - 0xc, 0x55, 0x6b, 0x55, 0xb1, 0x0, 0x0, 0xb, - 0x0, 0x29, 0x0, 0xa1, 0x0, 0x0, 0xc, 0x55, - 0x55, 0x55, 0x91, 0x10, 0x5, 0x55, 0x55, 0x55, - 0x55, 0x58, 0xe1, 0x1, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, - - /* U+7570 "異" */ - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xa, - 0x55, 0x57, 0x55, 0xa5, 0x0, 0x0, 0xb0, 0x0, - 0xb0, 0x9, 0x10, 0x0, 0xc, 0x55, 0x5c, 0x55, - 0xb1, 0x0, 0x0, 0xb0, 0x0, 0xb0, 0x9, 0x10, - 0x0, 0xd, 0x55, 0x58, 0x55, 0xb2, 0x0, 0x0, - 0x21, 0xb0, 0x8, 0x20, 0x0, 0x0, 0x65, 0x6c, - 0x55, 0xa6, 0x5a, 0x10, 0x0, 0x1, 0xa0, 0x8, - 0x10, 0x0, 0x3, 0x55, 0x6c, 0x55, 0xa6, 0x57, - 0x80, 0x10, 0x0, 0x91, 0x4, 0x30, 0x0, 0x0, - 0x4, 0xb7, 0x10, 0x4, 0xb5, 0x0, 0x37, 0x50, - 0x0, 0x0, 0x0, 0xb5, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x10, - - /* U+7576 "當" */ - 0x0, 0x0, 0x0, 0x30, 0x0, 0x0, 0x0, 0x6, - 0x10, 0x1b, 0x3, 0x70, 0x0, 0x0, 0x39, 0x0, - 0xa0, 0x92, 0x0, 0x0, 0x75, 0x65, 0x5b, 0x67, - 0x55, 0xa0, 0x29, 0x0, 0x0, 0x0, 0x10, 0x74, - 0x6, 0x40, 0xb5, 0x55, 0x5c, 0x22, 0x0, 0x0, - 0xb, 0x0, 0x0, 0xb0, 0x0, 0x0, 0x0, 0xc5, - 0x55, 0x5c, 0x0, 0x0, 0x0, 0x31, 0x0, 0x0, - 0x2, 0x30, 0x0, 0x1c, 0x55, 0x5c, 0x55, 0xa7, - 0x0, 0x1, 0xc5, 0x55, 0xc5, 0x5a, 0x40, 0x0, - 0x1a, 0x0, 0xb, 0x0, 0x74, 0x0, 0x1, 0xc5, - 0x55, 0xc5, 0x5a, 0x40, 0x0, 0x15, 0x0, 0x0, - 0x0, 0x42, 0x0, - - /* U+75B2 "疲" */ - 0x0, 0x0, 0x0, 0x2, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, 0xa, 0x40, 0x0, 0x0, 0x0, 0x9, - 0x55, 0x58, 0x85, 0x56, 0xc1, 0x2, 0xb, 0x0, - 0x0, 0x91, 0x0, 0x0, 0x8, 0x2b, 0x6, 0x55, - 0xd5, 0x58, 0x40, 0x5, 0x4b, 0xb, 0x0, 0xb0, - 0x9, 0x20, 0x0, 0xb, 0xb, 0x0, 0xb0, 0x1, - 0x0, 0x16, 0x7b, 0xb, 0x55, 0xb5, 0x79, 0x0, - 0x15, 0xa, 0xb, 0x5, 0x0, 0xa3, 0x0, 0x0, - 0x47, 0xb, 0x3, 0x44, 0x90, 0x0, 0x0, 0x92, - 0x55, 0x0, 0x9b, 0x0, 0x0, 0x1, 0x80, 0x90, - 0x4, 0x99, 0x83, 0x0, 0x6, 0x6, 0x13, 0x63, - 0x0, 0x3a, 0xc1, 0x0, 0x0, 0x10, 0x0, 0x0, - 0x0, 0x0, - - /* U+75C5 "病" */ - 0x0, 0x0, 0x0, 0x3, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x75, 0x0, 0x0, 0x0, 0xc, 0x55, - 0x56, 0x65, 0x58, 0x60, 0x60, 0xc0, 0x0, 0x0, - 0x0, 0x20, 0x8, 0x3c, 0x26, 0x55, 0xb5, 0x58, - 0x20, 0x10, 0xb0, 0x0, 0xd, 0x0, 0x0, 0x1, - 0x6b, 0x9, 0x55, 0xd5, 0x5b, 0x22, 0xb1, 0xa0, - 0xb0, 0x2a, 0x0, 0xc0, 0x0, 0x28, 0xb, 0x6, - 0x86, 0xc, 0x0, 0x6, 0x40, 0xb0, 0xa0, 0x76, - 0xc0, 0x0, 0x90, 0xb, 0x61, 0x1, 0x6c, 0x0, - 0x26, 0x0, 0xb0, 0x0, 0x10, 0xc0, 0x6, 0x0, - 0xb, 0x0, 0x3, 0xcc, 0x0, 0x0, 0x0, 0x10, - 0x0, 0x0, 0x0, - - /* U+75DB "痛" */ - 0x0, 0x0, 0x0, 0x3, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x5, 0x90, 0x0, 0x10, 0x0, 0x9, - 0x55, 0x55, 0x85, 0x58, 0x90, 0x7, 0xa, 0x15, - 0x55, 0x55, 0x57, 0x0, 0x7, 0x6a, 0x10, 0x3, - 0x23, 0x85, 0x0, 0x3, 0x3a, 0x13, 0x0, 0xc3, - 0x3, 0x0, 0x0, 0xb, 0x1c, 0x55, 0xc5, 0x5b, - 0x30, 0x3, 0x8c, 0xb, 0x0, 0xb0, 0xa, 0x10, - 0x3a, 0xb, 0xb, 0x55, 0xc5, 0x5b, 0x10, 0x0, - 0x19, 0xb, 0x55, 0xc5, 0x5b, 0x10, 0x0, 0x73, - 0xb, 0x0, 0xb0, 0xa, 0x10, 0x1, 0x80, 0xb, - 0x0, 0xb0, 0x1a, 0x10, 0x6, 0x0, 0xb, 0x0, - 0x90, 0x7d, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, - - /* U+767A "発" */ - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x65, 0x55, 0xd5, 0x12, 0xc1, 0x0, 0x0, 0x15, - 0x7, 0x70, 0x76, 0x4, 0x10, 0x0, 0xa, 0x3a, - 0x0, 0x54, 0x48, 0x20, 0x0, 0x3, 0xa0, 0x0, - 0x8, 0xa1, 0x0, 0x0, 0x58, 0x55, 0x55, 0x58, - 0xad, 0xb1, 0x4, 0x10, 0x1b, 0x0, 0xb0, 0x0, - 0x10, 0x0, 0x0, 0xb, 0x0, 0xb0, 0x0, 0x0, - 0x2, 0x55, 0x5c, 0x55, 0xc5, 0x58, 0x70, 0x0, - 0x10, 0xb, 0x0, 0xb0, 0x0, 0x0, 0x0, 0x0, - 0x65, 0x0, 0xb0, 0x0, 0x30, 0x0, 0x3, 0x80, - 0x0, 0xb0, 0x0, 0x70, 0x2, 0x64, 0x0, 0x0, - 0x9a, 0x9b, 0xa0, 0x1, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, - - /* U+767C "發" */ - 0x0, 0x0, 0x4, 0x10, 0x21, 0x0, 0x0, 0x46, - 0x59, 0xb2, 0x38, 0x11, 0x0, 0x3, 0x73, 0xa0, - 0x5, 0x25, 0x70, 0x0, 0x7, 0x80, 0x0, 0x4, - 0x91, 0x0, 0x36, 0x86, 0xa0, 0x18, 0x5a, 0x8a, - 0x21, 0x0, 0xb, 0x2, 0x80, 0xb0, 0x0, 0x4, - 0x22, 0xb0, 0x55, 0xc, 0x1, 0x0, 0xc2, 0x25, - 0x8, 0x0, 0x69, 0x91, 0xd, 0x55, 0x93, 0x26, - 0x46, 0xb0, 0x0, 0x30, 0xc, 0x1, 0x10, 0xa3, - 0x0, 0x0, 0x2, 0xa0, 0x3, 0x98, 0x0, 0x0, - 0x0, 0x57, 0x0, 0x57, 0x97, 0x0, 0x2, 0x9d, - 0x22, 0x53, 0x0, 0xa4, 0x0, 0x1, 0x10, 0x10, - 0x0, 0x0, 0x0, - - /* U+767D "白" */ - 0x0, 0x0, 0x20, 0x0, 0x0, 0x0, 0x0, 0x3e, - 0x10, 0x0, 0x0, 0x0, 0x9, 0x20, 0x0, 0x0, - 0x7, 0x56, 0x85, 0x55, 0x56, 0xc0, 0xa2, 0x0, - 0x0, 0x0, 0x1a, 0x9, 0x20, 0x0, 0x0, 0x1, - 0xa0, 0x92, 0x0, 0x0, 0x0, 0x1a, 0x9, 0x75, - 0x55, 0x55, 0x56, 0xa0, 0x92, 0x0, 0x0, 0x0, - 0x1a, 0x9, 0x20, 0x0, 0x0, 0x1, 0xa0, 0x92, - 0x0, 0x0, 0x0, 0x1a, 0xa, 0x75, 0x55, 0x55, - 0x56, 0xa0, 0xa2, 0x0, 0x0, 0x0, 0x19, 0x0, - 0x0, 0x0, 0x0, 0x0, 0x0, - - /* U+767E "百" */ - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x4, 0x55, - 0x55, 0x55, 0x55, 0x59, 0x90, 0x10, 0x0, 0xb, - 0x40, 0x0, 0x0, 0x0, 0x0, 0x0, 0xa0, 0x0, - 0x0, 0x0, 0x0, 0x85, 0x77, 0x55, 0x5b, 0x0, - 0x0, 0xd, 0x0, 0x0, 0x0, 0xd0, 0x0, 0x0, - 0xd0, 0x0, 0x0, 0xd, 0x0, 0x0, 0xd, 0x0, - 0x0, 0x0, 0xd0, 0x0, 0x0, 0xd5, 0x55, 0x55, - 0x5d, 0x0, 0x0, 0xd, 0x0, 0x0, 0x0, 0xd0, - 0x0, 0x0, 0xd0, 0x0, 0x0, 0xd, 0x0, 0x0, - 0xd, 0x55, 0x55, 0x55, 0xd0, 0x0, 0x0, 0xd0, - 0x0, 0x0, 0xd, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x0, - - /* U+7684 "的" */ - 0x0, 0x11, 0x0, 0x1, 0x10, 0x0, 0x0, 0x5, - 0x90, 0x0, 0x6c, 0x0, 0x0, 0x0, 0x70, 0x0, - 0xb, 0x30, 0x0, 0x1, 0xa7, 0x5b, 0x42, 0xd5, - 0x56, 0xb0, 0x1b, 0x0, 0xb0, 0x92, 0x0, 0x3a, - 0x0, 0xb0, 0xb, 0x35, 0x0, 0x3, 0x90, 0xb, - 0x0, 0xb2, 0x25, 0x0, 0x39, 0x0, 0xc5, 0x5c, - 0x0, 0xa3, 0x4, 0x90, 0xb, 0x0, 0xb0, 0x5, - 0x40, 0x48, 0x0, 0xb0, 0xb, 0x0, 0x0, 0x5, - 0x70, 0xb, 0x0, 0xb0, 0x0, 0x0, 0x66, 0x1, - 0xc5, 0x5c, 0x0, 0x14, 0x2b, 0x40, 0x19, 0x0, - 0x70, 0x0, 0x2d, 0xc0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x0, - - /* U+7686 "皆" */ - 0x20, 0x0, 0x4, 0x0, 0x0, 0x0, 0xb1, 0x0, - 0xb, 0x20, 0x57, 0x0, 0xb5, 0x5b, 0x2b, 0x8, - 0x82, 0x0, 0xb0, 0x0, 0xb, 0x40, 0x0, 0x30, - 0xb0, 0x35, 0x1b, 0x0, 0x0, 0x80, 0xdb, 0x41, - 0x39, 0xa9, 0x99, 0xe1, 0x10, 0x4, 0x70, 0x11, - 0x11, 0x0, 0x8, 0x59, 0x55, 0x55, 0xa0, 0x0, - 0xc, 0x0, 0x0, 0x0, 0xc0, 0x0, 0xd, 0x55, - 0x55, 0x55, 0xc0, 0x0, 0xc, 0x0, 0x0, 0x0, - 0xc0, 0x0, 0xc, 0x0, 0x0, 0x0, 0xc0, 0x0, - 0xd, 0x55, 0x55, 0x55, 0xb0, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x0, 0x0, - - /* U+76BF "皿" */ - 0x0, 0x75, 0x56, 0x55, 0x55, 0xa2, 0x0, 0x0, - 0xc0, 0xb, 0x2, 0x90, 0xc0, 0x0, 0x0, 0xc0, - 0xb, 0x2, 0x90, 0xc0, 0x0, 0x0, 0xc0, 0xb, - 0x2, 0x90, 0xc0, 0x0, 0x0, 0xc0, 0xb, 0x2, - 0x90, 0xc0, 0x0, 0x0, 0xc0, 0xb, 0x2, 0x90, - 0xc0, 0x0, 0x0, 0xc0, 0xb, 0x2, 0x90, 0xc0, - 0x0, 0x0, 0xc0, 0xb, 0x2, 0x90, 0xc0, 0x0, - 0x0, 0xc0, 0xb, 0x2, 0x90, 0xc1, 0x40, 0x26, - 0x65, 0x56, 0x55, 0x65, 0x66, 0x60, - - /* U+76D7 "盗" */ - 0x0, 0x0, 0x0, 0x31, 0x0, 0x0, 0x0, 0x63, - 0x0, 0xc, 0x60, 0x0, 0x0, 0x0, 0xd0, 0x44, - 0xc5, 0x55, 0x84, 0x0, 0x1, 0x62, 0xa0, 0x62, - 0x9, 0x20, 0x0, 0x38, 0x61, 0xd, 0x41, 0x0, - 0x0, 0x6e, 0x10, 0x5, 0x87, 0x0, 0x0, 0x0, - 0xb0, 0x0, 0xc1, 0x2a, 0x0, 0x0, 0x3b, 0x2, - 0x92, 0x0, 0x6e, 0x40, 0x0, 0x31, 0x30, 0x0, - 0x3, 0x30, 0x0, 0xc, 0x5c, 0x65, 0xc5, 0xb4, - 0x0, 0x0, 0xb0, 0xa1, 0xb, 0x9, 0x10, 0x0, - 0xb, 0xa, 0x10, 0xb0, 0x91, 0x0, 0x35, 0xc5, - 0xc6, 0x5c, 0x5b, 0x8b, 0x1, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x0, - - /* U+76EE "目" */ - 0x85, 0x55, 0x55, 0x5a, 0x1d, 0x0, 0x0, 0x0, - 0xd0, 0xd0, 0x0, 0x0, 0xd, 0xd, 0x0, 0x0, - 0x0, 0xd0, 0xd5, 0x55, 0x55, 0x5d, 0xd, 0x0, - 0x0, 0x0, 0xd0, 0xd0, 0x0, 0x0, 0xd, 0xd, - 0x55, 0x55, 0x55, 0xd0, 0xd0, 0x0, 0x0, 0xd, - 0xd, 0x0, 0x0, 0x0, 0xd0, 0xd5, 0x55, 0x55, - 0x5d, 0xc, 0x0, 0x0, 0x0, 0xc0, 0x0, 0x0, - 0x0, 0x0, 0x0, - - /* U+76F4 "直" */ - 0x0, 0x0, 0x0, 0x11, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x69, 0x0, 0x2, 0x0, 0x4, 0x65, - 0x55, 0xa8, 0x55, 0x5a, 0x40, 0x0, 0x1, 0x0, - 0xa1, 0x0, 0x20, 0x0, 0x0, 0xc, 0x55, 0x75, - 0x56, 0xc0, 0x0, 0x0, 0xc, 0x0, 0x0, 0x1, - 0xa0, 0x0, 0x0, 0xc, 0x55, 0x55, 0x56, 0xa0, - 0x0, 0x0, 0xc, 0x0, 0x0, 0x1, 0xa0, 0x0, - 0x0, 0xc, 0x55, 0x55, 0x56, 0xa0, 0x0, 0x0, - 0xc, 0x0, 0x0, 0x1, 0xa0, 0x0, 0x0, 0xc, - 0x55, 0x55, 0x56, 0xa0, 0x0, 0x0, 0xc, 0x0, - 0x0, 0x1, 0xa1, 0x60, 0x16, 0x56, 0x55, 0x55, - 0x55, 0x65, 0x61, - - /* U+76F8 "相" */ - 0x0, 0x2, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0xa4, 0x0, 0x10, 0x0, 0x30, 0x0, 0x9, 0x10, - 0xd, 0x55, 0x5d, 0x30, 0x0, 0x91, 0x20, 0xc0, - 0x0, 0xc0, 0x6, 0x5d, 0x67, 0x4c, 0x0, 0xc, - 0x0, 0x0, 0xf2, 0x0, 0xc5, 0x55, 0xd0, 0x0, - 0x5f, 0x97, 0xc, 0x0, 0xc, 0x0, 0xa, 0xa1, - 0xb0, 0xc0, 0x0, 0xc0, 0x3, 0x79, 0x10, 0xc, - 0x55, 0x5d, 0x0, 0x80, 0x91, 0x0, 0xc0, 0x0, - 0xc0, 0x31, 0xa, 0x10, 0xc, 0x0, 0xc, 0x0, - 0x0, 0xa2, 0x0, 0xd5, 0x55, 0xd0, 0x0, 0xa, - 0x20, 0xc, 0x0, 0xa, 0x0, 0x0, 0x10, 0x0, - 0x0, 0x0, 0x0, - - /* U+770B "看" */ - 0x0, 0x0, 0x0, 0x0, 0x0, 0x20, 0x0, 0x0, - 0x0, 0x13, 0x57, 0x9b, 0xb5, 0x0, 0x1, 0x44, - 0x43, 0xd0, 0x0, 0x0, 0x0, 0x0, 0x65, 0x58, - 0xb5, 0x55, 0xa4, 0x0, 0x0, 0x0, 0xb, 0x20, - 0x0, 0x0, 0x40, 0x17, 0x55, 0x7b, 0x55, 0x55, - 0x56, 0x92, 0x0, 0x0, 0xb1, 0x0, 0x0, 0x30, - 0x0, 0x0, 0x7, 0xe5, 0x55, 0x55, 0xd0, 0x0, - 0x0, 0x45, 0xc5, 0x55, 0x55, 0xc0, 0x0, 0x4, - 0x40, 0xc0, 0x0, 0x0, 0xc0, 0x0, 0x11, 0x0, - 0xc5, 0x55, 0x55, 0xc0, 0x0, 0x0, 0x0, 0xc0, - 0x0, 0x0, 0xc0, 0x0, 0x0, 0x0, 0xc5, 0x55, - 0x55, 0xc0, 0x0, 0x0, 0x0, 0x80, 0x0, 0x0, - 0x60, 0x0, - - /* U+771F "真" */ - 0x0, 0x0, 0x0, 0x14, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x3b, 0x0, 0x1, 0x30, 0x0, 0x65, - 0x55, 0x8a, 0x55, 0x56, 0x70, 0x0, 0x0, 0x0, - 0x56, 0x0, 0x30, 0x0, 0x0, 0x1, 0xc5, 0x65, - 0x56, 0xc0, 0x0, 0x0, 0x1, 0xc5, 0x55, 0x56, - 0x90, 0x0, 0x0, 0x1, 0xb0, 0x0, 0x2, 0x90, - 0x0, 0x0, 0x1, 0xc5, 0x55, 0x56, 0x90, 0x0, - 0x0, 0x1, 0xc5, 0x55, 0x56, 0x90, 0x0, 0x0, - 0x1, 0xb0, 0x0, 0x2, 0x90, 0x52, 0x6, 0x55, - 0x6a, 0x55, 0x86, 0x65, 0x64, 0x0, 0x0, 0x89, - 0x10, 0x8, 0x91, 0x0, 0x0, 0x28, 0x30, 0x0, - 0x0, 0x5c, 0x0, 0x0, 0x20, 0x0, 0x0, 0x0, - 0x2, 0x0, - - /* U+7720 "眠" */ - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x2, 0x0, - 0x30, 0xa5, 0x55, 0x5c, 0x20, 0xc5, 0x5c, 0xb, - 0x0, 0x0, 0xc0, 0xb, 0x1, 0xa0, 0xb0, 0x0, - 0xc, 0x0, 0xb0, 0x1a, 0xc, 0x59, 0x55, 0xd0, - 0xc, 0x55, 0xa0, 0xb0, 0x91, 0x0, 0x0, 0xb0, - 0x1a, 0xb, 0x8, 0x30, 0x37, 0xc, 0x55, 0xa0, - 0xc4, 0x88, 0x44, 0x41, 0xb0, 0x1a, 0xb, 0x3, - 0x90, 0x0, 0xb, 0x1, 0xa0, 0xb0, 0xc, 0x0, - 0x3, 0xc5, 0x5b, 0xb, 0x23, 0x5a, 0x1, 0x5b, - 0x0, 0x70, 0xe7, 0x0, 0x8b, 0x84, 0x0, 0x0, - 0x8, 0x0, 0x0, 0x5e, 0x60, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x0, - - /* U+773E "眾" */ - 0x0, 0x0, 0x0, 0x0, 0x0, 0x10, 0xb, 0x55, - 0xa5, 0x5b, 0x55, 0xd2, 0xb, 0x0, 0xa0, 0xe, - 0x0, 0xb0, 0xb, 0x0, 0xa0, 0xe, 0x0, 0xb0, - 0xb, 0x55, 0x55, 0x55, 0x55, 0x90, 0x0, 0x0, - 0x0, 0x14, 0x7b, 0xb0, 0x4, 0x55, 0x6a, 0x94, - 0x32, 0x10, 0x0, 0x46, 0x5, 0x50, 0x9, 0x0, - 0x0, 0x93, 0x5, 0x50, 0x3a, 0x0, 0x0, 0xc7, - 0x5, 0x50, 0x9a, 0x0, 0x8, 0x23, 0xc5, 0x52, - 0x91, 0x80, 0x43, 0x0, 0x65, 0x77, 0x0, 0x78, - 0x0, 0x0, 0x5, 0x60, 0x0, 0x0, 0x0, 0x0, - 0x2, 0x0, 0x0, 0x0, - - /* U+7740 "着" */ - 0x0, 0x0, 0x20, 0x0, 0x3, 0x0, 0x0, 0x0, - 0x0, 0x3b, 0x0, 0x67, 0x0, 0x0, 0x3, 0x55, - 0x5c, 0x55, 0x95, 0x5c, 0x30, 0x1, 0x0, 0x0, - 0xc0, 0x0, 0x20, 0x0, 0x0, 0x36, 0x58, 0xa5, - 0x57, 0x90, 0x0, 0x0, 0x0, 0xb, 0x10, 0x0, - 0x4, 0x40, 0x16, 0x55, 0xa8, 0x55, 0x55, 0x55, - 0x40, 0x0, 0x3, 0xe5, 0x55, 0x55, 0xb0, 0x0, - 0x0, 0x39, 0x92, 0x0, 0x0, 0xb0, 0x0, 0x4, - 0x60, 0x96, 0x55, 0x55, 0xb0, 0x0, 0x21, 0x0, - 0x96, 0x55, 0x55, 0xb0, 0x0, 0x0, 0x0, 0x92, - 0x0, 0x0, 0xb0, 0x0, 0x0, 0x0, 0x96, 0x55, - 0x55, 0xb0, 0x0, 0x0, 0x0, 0x20, 0x0, 0x0, - 0x20, 0x0, - - /* U+77E5 "知" */ - 0x0, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0xd, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x47, - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x96, 0x66, - 0xb0, 0x95, 0x55, 0xc0, 0x0, 0x80, 0xc0, 0x0, - 0xb0, 0x0, 0xb0, 0x5, 0x10, 0xc0, 0x0, 0xb0, - 0x0, 0xb0, 0x1, 0x0, 0xc0, 0x62, 0xb0, 0x0, - 0xb0, 0x6, 0x55, 0xd5, 0x53, 0xb0, 0x0, 0xb0, - 0x0, 0x2, 0xc0, 0x0, 0xb0, 0x0, 0xb0, 0x0, - 0x7, 0x59, 0x30, 0xb0, 0x0, 0xb0, 0x0, 0xb, - 0x1, 0xd2, 0xc5, 0x55, 0xb0, 0x0, 0x82, 0x0, - 0x64, 0xb0, 0x0, 0xb0, 0x6, 0x30, 0x0, 0x0, - 0x50, 0x0, 0x40, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, - - /* U+77ED "短" */ - 0x0, 0x32, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x97, 0x0, 0x55, 0x55, 0x58, 0x60, 0x0, 0xc0, - 0x1, 0x10, 0x0, 0x0, 0x0, 0x3, 0xba, 0x69, - 0x0, 0x0, 0x1, 0x0, 0x8, 0x1c, 0x0, 0xc, - 0x55, 0x5d, 0x0, 0x3, 0xc, 0x0, 0xb, 0x0, - 0xb, 0x0, 0x3, 0x3d, 0x39, 0x2b, 0x0, 0xb, - 0x0, 0x3, 0x2c, 0x22, 0x1c, 0x55, 0x5b, 0x0, - 0x0, 0xd, 0x10, 0x6, 0x0, 0x34, 0x0, 0x0, - 0x29, 0x83, 0x8, 0x0, 0xa5, 0x0, 0x0, 0x73, - 0x1b, 0x7, 0x50, 0xa0, 0x0, 0x0, 0x90, 0x2, - 0x3, 0x21, 0x50, 0x30, 0x6, 0x10, 0x5, 0x55, - 0x56, 0x55, 0x91, 0x1, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, - - /* U+77F3 "石" */ - 0x0, 0x0, 0x0, 0x0, 0x0, 0x5, 0x30, 0x6, - 0x55, 0x59, 0xa5, 0x55, 0x55, 0x50, 0x0, 0x0, - 0xc, 0x20, 0x0, 0x0, 0x0, 0x0, 0x0, 0x4a, - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xc1, 0x0, - 0x0, 0x0, 0x0, 0x0, 0x7, 0xd5, 0x55, 0x55, - 0xc3, 0x0, 0x0, 0x48, 0xc0, 0x0, 0x0, 0xc0, - 0x0, 0x2, 0x70, 0xc0, 0x0, 0x0, 0xc0, 0x0, - 0x24, 0x0, 0xc0, 0x0, 0x0, 0xc0, 0x0, 0x0, - 0x0, 0xc0, 0x0, 0x0, 0xc0, 0x0, 0x0, 0x0, - 0xc5, 0x55, 0x55, 0xd0, 0x0, 0x0, 0x0, 0xc0, - 0x0, 0x0, 0x80, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x0, - - /* U+7802 "砂" */ - 0x0, 0x0, 0x0, 0x0, 0x2, 0x0, 0x0, 0x0, - 0x0, 0x4, 0x0, 0xd, 0x0, 0x0, 0x7, 0x79, - 0x67, 0x0, 0xb, 0x0, 0x0, 0x0, 0x74, 0x0, - 0x27, 0xb, 0x22, 0x0, 0x0, 0xa0, 0x0, 0x68, - 0xb, 0x9, 0x60, 0x0, 0xb0, 0x40, 0xa1, 0xc, - 0x1, 0xe0, 0x5, 0xe5, 0xc3, 0x80, 0xc, 0x0, - 0x20, 0x7, 0xb0, 0xa6, 0x10, 0xc, 0xa, 0x20, - 0x21, 0xb0, 0xa2, 0x0, 0x8, 0x6c, 0x10, 0x0, - 0xb0, 0xa0, 0x0, 0x4, 0xb0, 0x0, 0x0, 0xc5, - 0xc1, 0x0, 0x5a, 0x0, 0x0, 0x0, 0xb0, 0x60, - 0x18, 0x60, 0x0, 0x0, 0x0, 0x30, 0x25, 0x60, - 0x0, 0x0, 0x0, 0x0, 0x0, 0x10, 0x0, 0x0, - 0x0, 0x0, - - /* U+7814 "研" */ - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x12, 0x56, 0x55, 0x58, 0x70, 0x6, 0x78, - 0x65, 0x9, 0x20, 0xb0, 0x0, 0x0, 0x73, 0x0, - 0x9, 0x20, 0xb0, 0x0, 0x0, 0xa0, 0x0, 0x9, - 0x20, 0xb0, 0x0, 0x0, 0xe5, 0xa3, 0x9, 0x20, - 0xb0, 0x20, 0x6, 0xe0, 0x94, 0x6b, 0x65, 0xc6, - 0x90, 0x7, 0xb0, 0x92, 0xa, 0x10, 0xb0, 0x0, - 0x20, 0xb0, 0x92, 0xb, 0x0, 0xb0, 0x0, 0x0, - 0xb0, 0x92, 0x1b, 0x0, 0xb0, 0x0, 0x0, 0xc5, - 0xb2, 0x74, 0x0, 0xb0, 0x0, 0x0, 0x70, 0x12, - 0x70, 0x0, 0xc0, 0x0, 0x0, 0x0, 0x26, 0x0, - 0x0, 0xb1, 0x0, 0x0, 0x0, 0x10, 0x0, 0x0, - 0x0, 0x0, - - /* U+7834 "破" */ - 0x0, 0x0, 0x0, 0x0, 0x1, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x0, 0xd, 0x0, 0x0, 0x6, 0x58, - 0x86, 0x30, 0xb, 0x0, 0x40, 0x0, 0x38, 0x0, - 0xa5, 0x5c, 0x58, 0xa0, 0x0, 0x74, 0x0, 0xa0, - 0xb, 0x3, 0x0, 0x0, 0xb1, 0x50, 0xa0, 0xb, - 0x0, 0x0, 0x3, 0xd3, 0xc1, 0xa5, 0x6a, 0x5c, - 0x10, 0x8, 0xb0, 0xb0, 0xb0, 0x50, 0x1a, 0x0, - 0x22, 0xb0, 0xb0, 0xb0, 0x60, 0x74, 0x0, 0x0, - 0xb0, 0xb0, 0xa0, 0x17, 0xb0, 0x0, 0x0, 0xc5, - 0xc5, 0x40, 0xb, 0x80, 0x0, 0x0, 0xb0, 0x68, - 0x0, 0x85, 0x89, 0x30, 0x0, 0x50, 0x52, 0x56, - 0x10, 0x5, 0xb2, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, - - /* U+78BA "確" */ - 0x0, 0x0, 0x0, 0x0, 0x4, 0x0, 0x0, 0x3, - 0x33, 0x74, 0x0, 0xd, 0x30, 0x0, 0x3, 0x75, - 0x11, 0x46, 0x6c, 0x55, 0xa5, 0x0, 0x91, 0x0, - 0xc0, 0x95, 0x10, 0x50, 0x0, 0xb0, 0x10, 0x2, - 0xa0, 0xb0, 0x0, 0x0, 0xd5, 0xc3, 0xb, 0x65, - 0xa5, 0xa2, 0x5, 0xc0, 0xa0, 0x8c, 0x1, 0x90, - 0x0, 0x7, 0xa0, 0xa5, 0x2c, 0x56, 0xb5, 0x80, - 0x22, 0xa0, 0xa0, 0xb, 0x1, 0x90, 0x0, 0x0, - 0xa0, 0xa0, 0xb, 0x23, 0xa4, 0x60, 0x0, 0xb5, - 0xb0, 0xc, 0x34, 0xa2, 0x20, 0x0, 0x90, 0x0, - 0xb, 0x1, 0x90, 0x40, 0x0, 0x0, 0x0, 0xc, - 0x55, 0x55, 0x52, 0x0, 0x0, 0x0, 0x2, 0x0, - 0x0, 0x0, - - /* U+793A "示" */ - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x15, 0x55, 0x55, 0x55, 0x9b, 0x0, 0x0, 0x1, - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x40, 0x6, 0x55, 0x55, 0x68, 0x55, - 0x55, 0xa3, 0x0, 0x0, 0x0, 0x2a, 0x0, 0x0, - 0x0, 0x0, 0x1, 0xe2, 0x2a, 0x6, 0x0, 0x0, - 0x0, 0x8, 0x70, 0x2a, 0x0, 0xa2, 0x0, 0x0, - 0x3a, 0x0, 0x2a, 0x0, 0x2d, 0x20, 0x1, 0x90, - 0x0, 0x2a, 0x0, 0x6, 0xb0, 0x6, 0x0, 0x23, - 0x6a, 0x0, 0x0, 0x60, 0x0, 0x0, 0x6, 0xf6, - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x20, 0x0, - 0x0, 0x0, - - /* U+793C "礼" */ - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x8, 0x30, 0x0, 0xd0, 0x0, 0x0, 0x0, 0x2, - 0xb0, 0x0, 0xc0, 0x0, 0x0, 0x0, 0x0, 0x12, - 0x20, 0xc0, 0x0, 0x0, 0x2, 0x65, 0x5e, 0x60, - 0xc0, 0x0, 0x0, 0x0, 0x0, 0x58, 0x0, 0xc0, - 0x0, 0x0, 0x0, 0x2, 0xd0, 0x0, 0xc0, 0x0, - 0x0, 0x0, 0x19, 0xd9, 0x40, 0xc0, 0x0, 0x0, - 0x1, 0x70, 0xc1, 0xc0, 0xc0, 0x0, 0x0, 0x3, - 0x0, 0xc0, 0x0, 0xc0, 0x0, 0x10, 0x0, 0x0, - 0xc0, 0x0, 0xc0, 0x0, 0x50, 0x0, 0x0, 0xc0, - 0x0, 0xc0, 0x0, 0xa0, 0x0, 0x0, 0xd0, 0x0, - 0x8b, 0xbb, 0xd2, 0x0, 0x0, 0x20, 0x0, 0x0, - 0x0, 0x0, - - /* U+793E "社" */ - 0x0, 0x10, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0xb, 0x10, 0x0, 0x2b, 0x0, 0x0, 0x0, 0x7, - 0x30, 0x0, 0x2a, 0x0, 0x0, 0x5, 0x55, 0x78, - 0x0, 0x2a, 0x0, 0x0, 0x1, 0x0, 0xb4, 0x0, - 0x2a, 0x0, 0x0, 0x0, 0x4, 0x90, 0x55, 0x6b, - 0x58, 0x90, 0x0, 0xe, 0x70, 0x10, 0x2a, 0x0, - 0x0, 0x0, 0x9d, 0x3c, 0x0, 0x2a, 0x0, 0x0, - 0x6, 0x2c, 0x4, 0x0, 0x2a, 0x0, 0x0, 0x11, - 0xc, 0x0, 0x0, 0x2a, 0x0, 0x0, 0x0, 0xc, - 0x0, 0x0, 0x2a, 0x0, 0x0, 0x0, 0xc, 0x4, - 0x55, 0x6b, 0x55, 0xc3, 0x0, 0xc, 0x1, 0x0, - 0x0, 0x0, 0x0, 0x0, 0x2, 0x0, 0x0, 0x0, - 0x0, 0x0, - - /* U+7956 "祖" */ - 0x0, 0x10, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x59, 0x0, 0x65, 0x55, 0x5a, 0x0, 0x0, 0xc, - 0x0, 0xa2, 0x0, 0xc, 0x0, 0x5, 0x55, 0xa1, - 0xa2, 0x0, 0xc, 0x0, 0x0, 0x2, 0xa0, 0x92, - 0x0, 0xc, 0x0, 0x0, 0xa, 0x20, 0x96, 0x55, - 0x5c, 0x0, 0x0, 0x4d, 0x60, 0x92, 0x0, 0xc, - 0x0, 0x0, 0x9b, 0x78, 0x92, 0x0, 0xc, 0x0, - 0x6, 0xb, 0x4, 0x96, 0x55, 0x5c, 0x0, 0x0, - 0xb, 0x0, 0x92, 0x0, 0xc, 0x0, 0x0, 0xb, - 0x0, 0x92, 0x0, 0xc, 0x0, 0x0, 0xb, 0x0, - 0x92, 0x0, 0xc, 0x52, 0x0, 0xc, 0x26, 0x55, - 0x55, 0x55, 0x54, 0x0, 0x1, 0x0, 0x0, 0x0, - 0x0, 0x0, - - /* U+795D "祝" */ - 0x0, 0x10, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x2a, 0x0, 0x20, 0x0, 0x4, 0x0, 0x0, 0xa, - 0x10, 0xb5, 0x55, 0x5d, 0x0, 0x5, 0x55, 0x93, - 0xb0, 0x0, 0xb, 0x0, 0x1, 0x0, 0xc0, 0xb0, - 0x0, 0xb, 0x0, 0x0, 0x7, 0x40, 0xb0, 0x0, - 0xb, 0x0, 0x0, 0x2e, 0x30, 0xb6, 0x89, 0x5c, - 0x0, 0x0, 0x9b, 0x95, 0x14, 0x6b, 0x1, 0x0, - 0x6, 0x1b, 0x15, 0x5, 0x4b, 0x0, 0x0, 0x21, - 0xb, 0x0, 0x8, 0x1b, 0x0, 0x0, 0x0, 0xb, - 0x0, 0xa, 0xb, 0x0, 0x50, 0x0, 0xc, 0x0, - 0x82, 0xb, 0x0, 0x80, 0x0, 0xc, 0x6, 0x20, - 0x7, 0xa9, 0xd2, 0x0, 0x4, 0x30, 0x0, 0x0, - 0x0, 0x0, - - /* U+795E "神" */ - 0x0, 0x0, 0x0, 0x0, 0x5, 0x0, 0x0, 0x0, - 0x29, 0x0, 0x0, 0xc, 0x0, 0x0, 0x0, 0xc, - 0x0, 0x0, 0xb, 0x0, 0x10, 0x5, 0x55, 0x92, - 0xb5, 0x5c, 0x55, 0xd0, 0x1, 0x0, 0xb0, 0xb0, - 0xb, 0x0, 0xb0, 0x0, 0x7, 0x40, 0xb5, 0x5c, - 0x55, 0xb0, 0x0, 0x2d, 0x60, 0xb0, 0xb, 0x0, - 0xb0, 0x0, 0x9b, 0x69, 0xb0, 0xb, 0x0, 0xb0, - 0x6, 0xb, 0x3, 0xb5, 0x5c, 0x55, 0xb0, 0x10, - 0xb, 0x0, 0x50, 0xb, 0x0, 0x20, 0x0, 0xb, - 0x0, 0x0, 0xb, 0x0, 0x0, 0x0, 0xb, 0x0, - 0x0, 0xc, 0x0, 0x0, 0x0, 0xc, 0x0, 0x0, - 0xc, 0x0, 0x0, 0x0, 0x2, 0x0, 0x0, 0x3, - 0x0, 0x0, - - /* U+796D "祭" */ - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x5, 0x90, 0x11, 0x30, 0x3, 0x0, 0x0, 0xb, - 0x55, 0xc5, 0x95, 0x5d, 0x30, 0x0, 0x57, 0x92, - 0xc0, 0x71, 0x71, 0x0, 0x1, 0x93, 0x4a, 0x40, - 0x1b, 0x20, 0x0, 0x5, 0xb, 0x49, 0x0, 0x7, - 0x70, 0x0, 0x0, 0x2, 0x96, 0x55, 0x68, 0x8b, - 0x30, 0x0, 0x37, 0x0, 0x0, 0x0, 0x5, 0xa2, - 0x15, 0x56, 0x55, 0x56, 0x55, 0x87, 0x0, 0x0, - 0x0, 0x55, 0xb, 0x13, 0x0, 0x0, 0x0, 0x3, - 0xc3, 0xb, 0x3, 0xa4, 0x0, 0x0, 0x49, 0x0, - 0xb, 0x0, 0x1d, 0x30, 0x2, 0x30, 0x5, 0xb9, - 0x0, 0x1, 0x10, 0x0, 0x0, 0x0, 0x31, 0x0, - 0x0, 0x0, - - /* U+7981 "禁" */ - 0x0, 0x0, 0x40, 0x0, 0x3, 0x0, 0x0, 0x0, - 0x0, 0xc0, 0x0, 0xb, 0x10, 0x0, 0x4, 0x55, - 0xc5, 0xa2, 0x5d, 0x56, 0xa0, 0x0, 0xb, 0xc2, - 0x0, 0x5f, 0x50, 0x0, 0x0, 0x56, 0xb9, 0x50, - 0x9b, 0x46, 0x0, 0x2, 0x80, 0xb1, 0x27, 0x1b, - 0x8, 0xb1, 0x4, 0x0, 0x80, 0x21, 0x7, 0x20, - 0x20, 0x0, 0x6, 0x55, 0x55, 0x55, 0x92, 0x0, - 0x5, 0x55, 0x55, 0x55, 0x55, 0x55, 0xb1, 0x1, - 0x0, 0x42, 0xc, 0x0, 0x0, 0x0, 0x0, 0x3, - 0xd4, 0xc, 0x7, 0x60, 0x0, 0x0, 0x48, 0x10, - 0xc, 0x0, 0x8a, 0x0, 0x2, 0x30, 0x6, 0xd9, - 0x0, 0x8, 0x0, 0x0, 0x0, 0x0, 0x20, 0x0, - 0x0, 0x0, - - /* U+79C0 "秀" */ - 0x0, 0x0, 0x0, 0x0, 0x1, 0x50, 0x0, 0x0, - 0x4, 0x56, 0x7a, 0x89, 0x72, 0x0, 0x0, 0x0, - 0x0, 0xa, 0x0, 0x0, 0x10, 0x4, 0x65, 0x55, - 0x8c, 0x65, 0x56, 0xb1, 0x0, 0x0, 0xb, 0x5a, - 0x42, 0x0, 0x0, 0x0, 0x0, 0xa4, 0x1a, 0x8, - 0x60, 0x0, 0x0, 0x29, 0x20, 0x15, 0x2, 0x6d, - 0x72, 0x4, 0x42, 0x6b, 0x65, 0x8a, 0x1, 0x60, - 0x0, 0x0, 0xc, 0x0, 0xa2, 0x4, 0x0, 0x0, - 0x0, 0x1b, 0x0, 0x85, 0x6c, 0x0, 0x0, 0x0, - 0x93, 0x0, 0x0, 0x47, 0x0, 0x0, 0x6, 0x60, - 0x0, 0x10, 0x93, 0x0, 0x0, 0x64, 0x0, 0x0, - 0x4d, 0xb0, 0x0, 0x1, 0x0, 0x0, 0x0, 0x1, - 0x0, 0x0, - - /* U+79C1 "私" */ - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x4a, 0xd1, 0x5, 0x10, 0x0, 0x2, 0x46, - 0xd1, 0x0, 0xb, 0x50, 0x0, 0x0, 0x0, 0xc0, - 0x0, 0xd, 0x0, 0x0, 0x0, 0x0, 0xc0, 0x52, - 0x2a, 0x0, 0x0, 0x6, 0x55, 0xe5, 0x53, 0x65, - 0x0, 0x0, 0x0, 0x5, 0xf4, 0x0, 0x90, 0x0, - 0x0, 0x0, 0xb, 0xd6, 0xb0, 0x90, 0x10, 0x0, - 0x0, 0x83, 0xc0, 0x93, 0x50, 0x35, 0x0, 0x5, - 0x40, 0xc0, 0x7, 0x0, 0xb, 0x10, 0x13, 0x0, - 0xc0, 0x18, 0x0, 0x7, 0xb0, 0x0, 0x0, 0xd0, - 0x8e, 0xa8, 0x64, 0xf0, 0x0, 0x0, 0xe0, 0x12, - 0x0, 0x0, 0x50, 0x0, 0x0, 0x30, 0x0, 0x0, - 0x0, 0x0, - - /* U+79CB "秋" */ - 0x0, 0x0, 0x0, 0x0, 0x30, 0x0, 0x0, 0x0, - 0x3, 0xaa, 0x0, 0xb4, 0x0, 0x0, 0x3, 0x5b, - 0x30, 0x0, 0xb1, 0x0, 0x0, 0x0, 0x9, 0x20, - 0x1, 0xb1, 0x9, 0x10, 0x15, 0x5b, 0x7b, 0x35, - 0xc2, 0x6a, 0x10, 0x1, 0xe, 0x20, 0x84, 0xd6, - 0x70, 0x0, 0x0, 0x4f, 0x50, 0xa0, 0xc7, 0x0, - 0x0, 0x0, 0x9b, 0x7a, 0x0, 0xc7, 0x0, 0x0, - 0x3, 0x69, 0x29, 0x3, 0x97, 0x10, 0x0, 0x6, - 0x9, 0x20, 0x9, 0x42, 0x90, 0x0, 0x20, 0x9, - 0x20, 0x1b, 0x0, 0xb3, 0x0, 0x0, 0xa, 0x20, - 0x91, 0x0, 0x2e, 0x40, 0x0, 0xa, 0x46, 0x0, - 0x0, 0x6, 0x70, 0x0, 0x0, 0x10, 0x0, 0x0, - 0x0, 0x0, - - /* U+79CD "种" */ - 0x0, 0x0, 0x0, 0x0, 0x3, 0x0, 0x0, 0x0, - 0x4, 0xb8, 0x0, 0xd, 0x0, 0x0, 0x4, 0x5c, - 0x10, 0x0, 0xb, 0x0, 0x0, 0x0, 0xb, 0x0, - 0x10, 0xb, 0x0, 0x40, 0x16, 0x5c, 0x69, 0xa5, - 0x5c, 0x56, 0xb0, 0x0, 0xe, 0x0, 0xa1, 0xb, - 0x2, 0x90, 0x0, 0x3f, 0x61, 0xa1, 0xb, 0x2, - 0x90, 0x0, 0xad, 0x3c, 0xa1, 0xb, 0x2, 0x90, - 0x3, 0x7b, 0x2, 0xa5, 0x5c, 0x56, 0x90, 0x8, - 0xb, 0x0, 0x20, 0xb, 0x0, 0x0, 0x30, 0xb, - 0x0, 0x0, 0xb, 0x0, 0x0, 0x0, 0xb, 0x0, - 0x0, 0xc, 0x0, 0x0, 0x0, 0xb, 0x0, 0x0, - 0xc, 0x0, 0x0, 0x0, 0x4, 0x0, 0x0, 0x3, - 0x0, 0x0, - - /* U+79D1 "科" */ - 0x0, 0x0, 0x0, 0x0, 0x0, 0x20, 0x0, 0x0, - 0x2, 0x8d, 0x0, 0x0, 0xc2, 0x0, 0x4, 0x5b, - 0x40, 0x3, 0x10, 0xb0, 0x0, 0x0, 0x8, 0x20, - 0x1, 0xd0, 0xb0, 0x0, 0x0, 0x8, 0x25, 0x10, - 0x40, 0xb0, 0x0, 0x26, 0x5d, 0x65, 0x31, 0x0, - 0xb0, 0x0, 0x0, 0x1f, 0x60, 0x5, 0x70, 0xb0, - 0x0, 0x0, 0x8c, 0x6b, 0x0, 0x90, 0xb0, 0x30, - 0x2, 0x88, 0x26, 0x0, 0x3, 0xd6, 0x70, 0x7, - 0x8, 0x23, 0x65, 0x41, 0xb0, 0x0, 0x30, 0x9, - 0x20, 0x0, 0x0, 0xb0, 0x0, 0x0, 0x9, 0x20, - 0x0, 0x0, 0xb0, 0x0, 0x0, 0x9, 0x30, 0x0, - 0x0, 0xc0, 0x0, 0x0, 0x3, 0x0, 0x0, 0x0, - 0x40, 0x0, - - /* U+79D8 "秘" */ - 0x0, 0x0, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x38, 0xb7, 0x0, 0x70, 0x6, 0x0, 0x4, 0x2b, - 0x0, 0x0, 0x4b, 0x1e, 0x10, 0x0, 0xb, 0x0, - 0x6, 0x44, 0x49, 0x0, 0x14, 0x4c, 0x4a, 0x9, - 0x20, 0x95, 0x0, 0x2, 0x1f, 0x0, 0x9, 0x20, - 0xd1, 0x0, 0x0, 0x5f, 0x82, 0x49, 0x23, 0xb5, - 0x20, 0x0, 0xac, 0x29, 0x99, 0x2a, 0x50, 0xd0, - 0x4, 0x5b, 0x6, 0x99, 0x5c, 0x0, 0xb2, 0x7, - 0xb, 0x2, 0x19, 0xe2, 0x1, 0x10, 0x20, 0xb, - 0x0, 0xb, 0x60, 0x5, 0x0, 0x0, 0xb, 0x0, - 0x8c, 0x20, 0x9, 0x10, 0x0, 0xb, 0x26, 0x15, - 0xca, 0xad, 0x30, 0x0, 0x5, 0x0, 0x0, 0x0, - 0x0, 0x0, - - /* U+79FB "移" */ - 0x0, 0x0, 0x0, 0x0, 0x10, 0x0, 0x0, 0x0, - 0x3, 0xa8, 0x0, 0xb4, 0x0, 0x0, 0x4, 0x6d, - 0x20, 0x4, 0xb5, 0x59, 0x30, 0x0, 0xb, 0x0, - 0x19, 0x50, 0x2b, 0x0, 0x0, 0xb, 0x5, 0x30, - 0xa2, 0xb1, 0x0, 0x26, 0x5f, 0x55, 0x10, 0x2a, - 0x10, 0x0, 0x0, 0x3f, 0x20, 0x4, 0x78, 0x50, - 0x0, 0x0, 0x9e, 0x77, 0x42, 0x4b, 0x10, 0x30, - 0x1, 0x8c, 0x7, 0x3, 0xa5, 0x59, 0xb0, 0x7, - 0xc, 0x0, 0x48, 0x70, 0x1c, 0x10, 0x22, 0xc, - 0x1, 0x20, 0x92, 0xb2, 0x0, 0x0, 0xc, 0x0, - 0x0, 0x4a, 0x20, 0x0, 0x0, 0xc, 0x0, 0x57, - 0x50, 0x0, 0x0, 0x0, 0x3, 0x13, 0x0, 0x0, - 0x0, 0x0, - - /* U+7A0B "程" */ - 0x0, 0x0, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x37, 0xb9, 0x18, 0x55, 0x59, 0x30, 0x4, 0x3b, - 0x0, 0x1a, 0x0, 0xa, 0x0, 0x0, 0xb, 0x0, - 0xa, 0x0, 0xa, 0x0, 0x15, 0x5c, 0x5a, 0x2c, - 0x55, 0x5c, 0x0, 0x1, 0x1e, 0x0, 0x17, 0x0, - 0x5, 0x0, 0x0, 0x5f, 0x71, 0x35, 0x55, 0x57, - 0x70, 0x0, 0x9c, 0x2b, 0x10, 0xb, 0x0, 0x0, - 0x1, 0x7b, 0x1, 0x0, 0xb, 0x0, 0x0, 0x7, - 0xb, 0x0, 0x16, 0x5c, 0x59, 0x30, 0x23, 0xb, - 0x0, 0x0, 0xb, 0x0, 0x0, 0x0, 0xc, 0x0, - 0x0, 0xb, 0x0, 0x30, 0x0, 0xc, 0x3, 0x65, - 0x57, 0x55, 0x80, 0x0, 0x2, 0x0, 0x0, 0x0, - 0x0, 0x0, - - /* U+7A2E "種" */ - 0x0, 0x0, 0x0, 0x0, 0x0, 0x1, 0x0, 0x0, - 0x2, 0x95, 0x14, 0x6a, 0xa8, 0x0, 0x3, 0x5c, - 0x20, 0x0, 0xb, 0x0, 0x10, 0x0, 0xb, 0x1, - 0x65, 0x5c, 0x56, 0x70, 0x4, 0x4c, 0x67, 0x20, - 0xb, 0x2, 0x0, 0x2, 0x4d, 0x0, 0xa5, 0x5c, - 0x5c, 0x10, 0x0, 0x7c, 0x80, 0xa5, 0x5c, 0x5c, - 0x0, 0x0, 0xab, 0x65, 0xa0, 0xb, 0xb, 0x0, - 0x5, 0x3b, 0x1, 0xa5, 0x5c, 0x5c, 0x0, 0x5, - 0xb, 0x0, 0x40, 0xb, 0x4, 0x0, 0x10, 0xb, - 0x0, 0x65, 0x5c, 0x59, 0x40, 0x0, 0xc, 0x0, - 0x0, 0xb, 0x0, 0x0, 0x0, 0xc, 0x3, 0x55, - 0x5c, 0x57, 0xd0, 0x0, 0x3, 0x1, 0x0, 0x0, - 0x0, 0x0, - - /* U+7A4D "積" */ - 0x0, 0x0, 0x0, 0x0, 0x4, 0x0, 0x0, 0x0, - 0x27, 0xd3, 0x0, 0xc, 0x0, 0x40, 0x3, 0x3b, - 0x0, 0x65, 0x5c, 0x55, 0x61, 0x0, 0xb, 0x0, - 0x27, 0x5c, 0x57, 0x50, 0x6, 0x6d, 0x85, 0x11, - 0x1b, 0x11, 0x62, 0x0, 0x5d, 0x31, 0x63, 0x33, - 0x33, 0x52, 0x0, 0xab, 0x83, 0x96, 0x55, 0x56, - 0xb0, 0x1, 0x8b, 0x23, 0x86, 0x55, 0x56, 0x90, - 0x7, 0x1b, 0x0, 0x81, 0x0, 0x2, 0x90, 0x14, - 0xb, 0x0, 0x86, 0x55, 0x56, 0x90, 0x0, 0xb, - 0x0, 0x96, 0x55, 0x56, 0x90, 0x0, 0xc, 0x0, - 0x2a, 0x60, 0x37, 0x10, 0x0, 0xb, 0x3, 0x73, - 0x0, 0x2, 0xc0, 0x0, 0x0, 0x1, 0x0, 0x0, - 0x0, 0x20, - - /* U+7A76 "究" */ - 0x0, 0x0, 0x1, 0x20, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, 0xb4, 0x0, 0x0, 0x0, 0x0, 0x75, - 0x55, 0x87, 0x55, 0x5c, 0x10, 0x3, 0x90, 0x94, - 0x1, 0x50, 0x36, 0x0, 0x3, 0x29, 0x75, 0x10, - 0x2b, 0xa0, 0x0, 0x2, 0x61, 0xb, 0x10, 0x0, - 0x91, 0x0, 0x0, 0x46, 0x6d, 0x66, 0x94, 0x0, - 0x0, 0x0, 0x0, 0xb, 0x0, 0x92, 0x0, 0x0, - 0x0, 0x0, 0x38, 0x0, 0x92, 0x0, 0x0, 0x0, - 0x0, 0x93, 0x0, 0xa1, 0x0, 0x0, 0x0, 0x2, - 0xb0, 0x0, 0xa1, 0x0, 0x50, 0x0, 0xb, 0x20, - 0x0, 0xa1, 0x1, 0x90, 0x1, 0x82, 0x0, 0x0, - 0x5b, 0xac, 0x90, 0x4, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, - - /* U+7A7A "空" */ - 0x0, 0x0, 0x1, 0x10, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, 0xa6, 0x0, 0x0, 0x0, 0x0, 0x10, - 0x0, 0x16, 0x0, 0x2, 0x0, 0x4, 0x95, 0x56, - 0x55, 0x55, 0x5c, 0x80, 0xd, 0x30, 0xa9, 0x0, - 0x57, 0x25, 0x0, 0x0, 0x9, 0x70, 0x0, 0x2, - 0xc8, 0x0, 0x2, 0x72, 0x0, 0x0, 0x0, 0x1b, - 0x10, 0x3, 0x17, 0x55, 0x85, 0x57, 0x80, 0x0, - 0x0, 0x0, 0x0, 0xa2, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, 0xa2, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0xa2, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0xa2, 0x0, 0x0, 0x0, 0x5, 0x55, 0x55, 0xc7, - 0x55, 0x5d, 0x60, 0x1, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, - - /* U+7A93 "窓" */ - 0x0, 0x0, 0x0, 0x30, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x4c, 0x0, 0x0, 0x0, 0x0, 0x75, - 0x55, 0x5c, 0x55, 0x56, 0xa0, 0x3, 0x90, 0x18, - 0x0, 0x54, 0x5, 0x50, 0x6, 0x25, 0xa4, 0x63, - 0x4, 0xd7, 0x0, 0x0, 0x52, 0x3, 0xc3, 0x10, - 0x4, 0x0, 0x0, 0x0, 0x58, 0x0, 0xa, 0x10, - 0x0, 0x0, 0x8, 0xda, 0x87, 0x68, 0xb0, 0x0, - 0x0, 0x2, 0x30, 0x50, 0x0, 0x80, 0x0, 0x0, - 0x10, 0xc1, 0x2c, 0x0, 0x5, 0x0, 0x0, 0x70, - 0xc0, 0x7, 0x0, 0x46, 0x70, 0x7, 0x90, 0xc0, - 0x0, 0x1, 0x70, 0xb0, 0x3, 0x0, 0xbb, 0xbb, - 0xbc, 0xb0, 0x0, - - /* U+7ACB "立" */ - 0x0, 0x0, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, 0xc3, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x68, 0x0, 0x1, 0x0, 0x2, 0x65, 0x55, - 0x55, 0x55, 0x5c, 0x30, 0x0, 0x0, 0x0, 0x0, - 0x5, 0x0, 0x0, 0x0, 0x1, 0x40, 0x0, 0xe, - 0x40, 0x0, 0x0, 0x0, 0x90, 0x0, 0x1c, 0x0, - 0x0, 0x0, 0x0, 0x67, 0x0, 0x47, 0x0, 0x0, - 0x0, 0x0, 0x3d, 0x0, 0x91, 0x0, 0x0, 0x0, - 0x0, 0xe, 0x0, 0x90, 0x0, 0x0, 0x0, 0x0, - 0x2, 0x2, 0x40, 0x0, 0x0, 0x15, 0x55, 0x55, - 0x59, 0x55, 0x57, 0xd1, 0x1, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x0, - - /* U+7AD9 "站" */ - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x43, 0x0, 0x0, 0xc, 0x0, 0x0, 0x0, 0xd, - 0x0, 0x0, 0xb, 0x0, 0x0, 0x0, 0x7, 0x0, - 0x30, 0xb, 0x1, 0x40, 0x6, 0x55, 0x56, 0x70, - 0xc, 0x55, 0x50, 0x0, 0x10, 0x28, 0x0, 0xb, - 0x0, 0x0, 0x0, 0x70, 0x57, 0x0, 0xb, 0x0, - 0x0, 0x0, 0xb0, 0x72, 0xa, 0x5a, 0x5b, 0x30, - 0x0, 0x94, 0x80, 0xb, 0x0, 0xb, 0x0, 0x0, - 0x51, 0x60, 0xb, 0x0, 0xb, 0x0, 0x0, 0x36, - 0x95, 0x2b, 0x0, 0xb, 0x0, 0xc, 0x83, 0x0, - 0xc, 0x55, 0x5c, 0x0, 0x0, 0x0, 0x0, 0xb, - 0x0, 0x8, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, - - /* U+7AE5 "童" */ - 0x0, 0x0, 0x0, 0x40, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x7, 0x40, 0x14, 0x0, 0x0, 0x46, 0x97, - 0x55, 0xc6, 0x50, 0x0, 0x0, 0x1, 0xb0, 0x26, - 0x0, 0x0, 0x5, 0x65, 0x56, 0x57, 0x55, 0x87, - 0x0, 0x0, 0x75, 0x55, 0x55, 0x75, 0x0, 0x0, - 0xb, 0x0, 0x91, 0x5, 0x50, 0x0, 0x0, 0xb5, - 0x5b, 0x65, 0x95, 0x0, 0x0, 0xb, 0x55, 0xb6, - 0x59, 0x60, 0x0, 0x0, 0x60, 0x9, 0x10, 0x33, - 0x0, 0x0, 0x55, 0x55, 0xb6, 0x55, 0xb4, 0x0, - 0x0, 0x0, 0x9, 0x10, 0x0, 0x20, 0x6, 0x55, - 0x55, 0x75, 0x55, 0x58, 0x50, - - /* U+7AEF "端" */ - 0x0, 0x0, 0x0, 0x0, 0x1, 0x0, 0x0, 0x0, - 0x71, 0x0, 0x50, 0x1c, 0x2, 0x10, 0x0, 0x48, - 0x0, 0xb0, 0xa, 0x4, 0x70, 0x0, 0x1, 0x50, - 0xa0, 0xa, 0x4, 0x60, 0x5, 0x44, 0x62, 0x85, - 0x55, 0x57, 0x40, 0x3, 0x10, 0xd3, 0x55, 0x55, - 0x55, 0x92, 0x1, 0x72, 0x80, 0x10, 0x92, 0x0, - 0x0, 0x0, 0xb5, 0x30, 0x85, 0xa5, 0x55, 0x90, - 0x0, 0x66, 0x0, 0xb0, 0xa0, 0xa0, 0xb0, 0x0, - 0x8, 0x53, 0xb0, 0xa0, 0xa0, 0xb0, 0xb, 0xa3, - 0x0, 0xb0, 0xa0, 0xa0, 0xb0, 0x1, 0x0, 0x0, - 0xb0, 0xa0, 0x90, 0xb0, 0x0, 0x0, 0x0, 0xb0, - 0x40, 0x29, 0xa0, 0x0, 0x0, 0x0, 0x10, 0x0, - 0x2, 0x10, - - /* U+7B11 "笑" */ - 0x0, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0xd, 0x30, 0x0, 0x5a, 0x0, 0x0, 0x0, 0x4c, - 0x55, 0xb3, 0xc6, 0x57, 0xb0, 0x0, 0xa0, 0x82, - 0x5, 0x50, 0xa1, 0x0, 0x6, 0x20, 0x47, 0x15, - 0x0, 0x73, 0x0, 0x1, 0x0, 0x13, 0x67, 0xad, - 0xc0, 0x0, 0x0, 0x24, 0x43, 0xb3, 0x0, 0x0, - 0x0, 0x0, 0x0, 0x0, 0xb0, 0x0, 0x2, 0x10, - 0x6, 0x55, 0x55, 0xd7, 0x55, 0x58, 0x60, 0x0, - 0x0, 0x4, 0x83, 0x40, 0x0, 0x0, 0x0, 0x0, - 0xb, 0x10, 0x83, 0x0, 0x0, 0x0, 0x1, 0x92, - 0x0, 0xa, 0x92, 0x0, 0x2, 0x56, 0x0, 0x0, - 0x0, 0x6e, 0xa0, 0x1, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, - - /* U+7B26 "符" */ - 0x0, 0x2, 0x0, 0x0, 0x2, 0x0, 0x0, 0x0, - 0xd, 0x30, 0x0, 0x69, 0x0, 0x0, 0x0, 0x6a, - 0x65, 0x92, 0xb5, 0x75, 0x90, 0x1, 0x90, 0x1a, - 0x5, 0x30, 0x83, 0x0, 0x6, 0x0, 0x54, 0x25, - 0x0, 0x32, 0x0, 0x0, 0x2, 0xd1, 0x0, 0x0, - 0xd0, 0x0, 0x0, 0xb, 0x25, 0x55, 0x55, 0xc5, - 0xa2, 0x0, 0x7d, 0x10, 0x20, 0x0, 0xb0, 0x0, - 0x6, 0x3b, 0x0, 0x75, 0x0, 0xb0, 0x0, 0x11, - 0xb, 0x0, 0xd, 0x0, 0xb0, 0x0, 0x0, 0xb, - 0x0, 0x1, 0x0, 0xb0, 0x0, 0x0, 0xb, 0x0, - 0x0, 0x0, 0xb0, 0x0, 0x0, 0xc, 0x0, 0x0, - 0x6c, 0x90, 0x0, 0x0, 0x2, 0x0, 0x0, 0x3, - 0x0, 0x0, - - /* U+7B2C "第" */ - 0x0, 0x2, 0x0, 0x0, 0x11, 0x0, 0x0, 0x0, - 0xc, 0x50, 0x10, 0x8a, 0x0, 0x10, 0x0, 0x6a, - 0x85, 0x94, 0xc7, 0x65, 0x91, 0x3, 0x70, 0x66, - 0x8, 0x0, 0xb0, 0x0, 0x2, 0x25, 0x67, 0x65, - 0x55, 0x89, 0x0, 0x0, 0x1, 0x0, 0xb, 0x0, - 0xb, 0x0, 0x0, 0x9, 0x55, 0x5c, 0x55, 0x5b, - 0x0, 0x0, 0x1b, 0x0, 0xb, 0x0, 0x5, 0x0, - 0x0, 0x7a, 0x55, 0x5c, 0x55, 0x55, 0x90, 0x0, - 0x21, 0x5, 0x9b, 0x0, 0x1, 0xb0, 0x0, 0x0, - 0x59, 0xb, 0x0, 0x4, 0x80, 0x0, 0x18, 0x50, - 0xb, 0x2, 0x9e, 0x30, 0x15, 0x50, 0x0, 0xb, - 0x0, 0x12, 0x0, 0x0, 0x0, 0x0, 0x2, 0x0, - 0x0, 0x0, - - /* U+7B46 "筆" */ - 0x0, 0x4, 0x10, 0x0, 0x22, 0x0, 0x0, 0x0, - 0xd, 0x40, 0x0, 0x78, 0x0, 0x10, 0x0, 0x5b, - 0x65, 0x95, 0xc5, 0x76, 0xa0, 0x0, 0xa0, 0x2b, - 0x6, 0x30, 0x69, 0x0, 0x7, 0x10, 0x8, 0x39, - 0x0, 0x1a, 0x0, 0x1, 0x4, 0x65, 0x6b, 0x55, - 0xd2, 0x0, 0x1, 0x55, 0x55, 0x6b, 0x55, 0xd9, - 0x80, 0x0, 0x10, 0x0, 0x29, 0x0, 0xc0, 0x0, - 0x0, 0x4, 0x65, 0x6b, 0x55, 0xa0, 0x0, 0x0, - 0x2, 0x22, 0x4a, 0x23, 0x80, 0x0, 0x0, 0x3, - 0x33, 0x5a, 0x33, 0x35, 0x10, 0x3, 0x65, 0x55, - 0x6b, 0x55, 0x57, 0x40, 0x0, 0x0, 0x0, 0x2a, - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x11, 0x0, - 0x0, 0x0, - - /* U+7B49 "等" */ - 0x0, 0x3, 0x0, 0x0, 0x12, 0x0, 0x0, 0x0, - 0xe, 0x50, 0x10, 0x88, 0x0, 0x10, 0x0, 0x5b, - 0x75, 0x85, 0xb7, 0x55, 0x80, 0x1, 0xa0, 0x84, - 0x5, 0x10, 0xb0, 0x0, 0x6, 0x0, 0x35, 0xc, - 0x0, 0x70, 0x0, 0x0, 0x6, 0x55, 0x5d, 0x55, - 0x78, 0x0, 0x0, 0x0, 0x0, 0xc, 0x0, 0x0, - 0x30, 0x6, 0x55, 0x55, 0x57, 0x56, 0x55, 0x70, - 0x0, 0x0, 0x0, 0x0, 0xb, 0x21, 0x30, 0x1, - 0x75, 0x75, 0x55, 0x5c, 0x55, 0x60, 0x0, 0x0, - 0x39, 0x0, 0xb, 0x10, 0x0, 0x0, 0x0, 0xb, - 0x10, 0xb, 0x0, 0x0, 0x0, 0x0, 0x0, 0x4, - 0xae, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x12, - 0x0, 0x0, - - /* U+7B54 "答" */ - 0x0, 0x2, 0x0, 0x0, 0x20, 0x0, 0x0, 0x0, - 0xf, 0x20, 0x1, 0xe0, 0x0, 0x0, 0x0, 0x7b, - 0x55, 0xa7, 0x86, 0x59, 0x30, 0x1, 0xa0, 0xa0, - 0x16, 0x6, 0x60, 0x0, 0x7, 0x10, 0x85, 0xe1, - 0x0, 0xa0, 0x0, 0x0, 0x0, 0x4b, 0x17, 0x20, - 0x0, 0x0, 0x0, 0x6, 0x90, 0x0, 0x79, 0x30, - 0x0, 0x1, 0x85, 0x65, 0x55, 0xa4, 0xae, 0x80, - 0x24, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0xb, 0x55, 0x55, 0x5d, 0x30, 0x0, 0x0, 0xc, - 0x0, 0x0, 0xc, 0x0, 0x0, 0x0, 0xc, 0x0, - 0x0, 0xc, 0x0, 0x0, 0x0, 0xc, 0x55, 0x55, - 0x5d, 0x0, 0x0, 0x0, 0x2, 0x0, 0x0, 0x1, - 0x0, 0x0, - - /* U+7B56 "策" */ - 0x0, 0x1, 0x10, 0x0, 0x10, 0x0, 0x0, 0x0, - 0x9, 0x70, 0x0, 0x93, 0x0, 0x0, 0x0, 0x3c, - 0x75, 0x86, 0xa7, 0x58, 0x70, 0x0, 0x90, 0x47, - 0x5, 0x8, 0x40, 0x0, 0x4, 0x0, 0x4, 0xa, - 0x2, 0x22, 0x30, 0x4, 0x55, 0x55, 0x5c, 0x55, - 0x58, 0x80, 0x0, 0x7, 0x55, 0x5c, 0x55, 0x83, - 0x0, 0x0, 0xb, 0x0, 0xb, 0x0, 0xa1, 0x0, - 0x0, 0xb, 0x0, 0x7d, 0x11, 0xb0, 0x0, 0x0, - 0xb, 0x6, 0x8b, 0x87, 0xc0, 0x0, 0x0, 0x0, - 0x86, 0xb, 0x1a, 0x30, 0x0, 0x0, 0x38, 0x20, - 0xb, 0x0, 0xac, 0x83, 0x15, 0x30, 0x0, 0xb, - 0x0, 0x3, 0x60, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, - - /* U+7B97 "算" */ - 0x0, 0x4, 0x0, 0x0, 0x20, 0x0, 0x0, 0x0, - 0xd, 0x10, 0x30, 0xb2, 0x0, 0x10, 0x0, 0x77, - 0x96, 0x75, 0x85, 0x96, 0x60, 0x2, 0x71, 0x37, - 0x5, 0x0, 0x85, 0x0, 0x5, 0xb, 0x55, 0x55, - 0x57, 0xb0, 0x0, 0x0, 0xb, 0x55, 0x55, 0x57, - 0x90, 0x0, 0x0, 0xb, 0x0, 0x0, 0x3, 0x90, - 0x0, 0x0, 0xc, 0x55, 0x55, 0x57, 0x90, 0x0, - 0x0, 0xc, 0x59, 0x55, 0x97, 0x90, 0x0, 0x0, - 0x2, 0x2b, 0x0, 0xc0, 0x0, 0x20, 0x16, 0x55, - 0x8b, 0x55, 0xd5, 0x57, 0x80, 0x0, 0x0, 0xb2, - 0x0, 0xc0, 0x0, 0x0, 0x0, 0x38, 0x20, 0x0, - 0xc0, 0x0, 0x0, 0x2, 0x20, 0x0, 0x0, 0x30, - 0x0, 0x0, - - /* U+7BA1 "管" */ - 0x0, 0x3, 0x0, 0x0, 0x30, 0x0, 0x0, 0x0, - 0x79, 0x0, 0x11, 0xc1, 0x1, 0x0, 0x0, 0xb7, - 0x66, 0x58, 0x68, 0x57, 0x40, 0x7, 0x10, 0xa0, - 0x61, 0x6, 0x60, 0x0, 0x3, 0x0, 0x20, 0x92, - 0x0, 0x12, 0x30, 0x9, 0x55, 0x55, 0x55, 0x55, - 0x5b, 0x80, 0x29, 0x8, 0x55, 0x55, 0x5c, 0x4, - 0x0, 0x0, 0xa, 0x0, 0x0, 0xb, 0x0, 0x0, - 0x0, 0xa, 0x55, 0x55, 0x5b, 0x0, 0x0, 0x0, - 0xa, 0x0, 0x0, 0x2, 0x10, 0x0, 0x0, 0xa, - 0x55, 0x55, 0x5a, 0x60, 0x0, 0x0, 0xa, 0x0, - 0x0, 0x7, 0x30, 0x0, 0x0, 0xb, 0x55, 0x55, - 0x5a, 0x40, 0x0, 0x0, 0x3, 0x0, 0x0, 0x0, - 0x0, 0x0, - - /* U+7BC0 "節" */ - 0x0, 0x4, 0x0, 0x0, 0x31, 0x0, 0x0, 0x0, - 0x3c, 0x0, 0x60, 0xb3, 0x3, 0x40, 0x0, 0xa5, - 0xa8, 0x54, 0xa6, 0xa5, 0x40, 0x4, 0x30, 0xc, - 0x7, 0x0, 0x5a, 0x0, 0x13, 0x20, 0x0, 0x41, - 0x20, 0x7, 0x0, 0x0, 0xb5, 0x55, 0xd1, 0xc5, - 0x5d, 0x0, 0x0, 0xb5, 0x55, 0xb0, 0xb0, 0xb, - 0x0, 0x0, 0xb0, 0x0, 0xb0, 0xb0, 0xb, 0x0, - 0x0, 0xb5, 0x55, 0xb0, 0xb0, 0xb, 0x0, 0x0, - 0xb0, 0x3, 0x10, 0xb0, 0xb, 0x0, 0x0, 0xb0, - 0x8, 0x50, 0xb2, 0x9a, 0x0, 0x0, 0xc7, 0x74, - 0xe0, 0xb0, 0x20, 0x0, 0x0, 0x74, 0x0, 0x41, - 0xb0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x10, - 0x0, 0x0, - - /* U+7BC4 "範" */ - 0x0, 0x3, 0x0, 0x0, 0x21, 0x0, 0x0, 0x0, - 0x4d, 0x10, 0x60, 0xa5, 0x3, 0x40, 0x0, 0xb6, - 0xa6, 0x55, 0xa6, 0xb6, 0x40, 0x5, 0x40, 0x3d, - 0x8, 0x0, 0x3d, 0x10, 0x4, 0x11, 0xc4, 0x61, - 0x20, 0x8, 0x0, 0x2, 0x64, 0xb4, 0x51, 0xc5, - 0x5c, 0x0, 0x0, 0xb5, 0xc5, 0xc0, 0xa0, 0xa, - 0x0, 0x0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa, 0x0, - 0x0, 0xc5, 0xc5, 0xa0, 0xa0, 0xa, 0x0, 0x0, - 0xc5, 0xc5, 0xb0, 0xa4, 0x7a, 0x0, 0x0, 0x20, - 0xa0, 0x70, 0xa0, 0x41, 0x20, 0x5, 0x55, 0xc5, - 0x52, 0xa0, 0x0, 0x50, 0x0, 0x0, 0xb0, 0x0, - 0xb9, 0x9a, 0xc0, 0x0, 0x0, 0x40, 0x0, 0x0, - 0x0, 0x0, - - /* U+7C21 "簡" */ - 0x0, 0x3, 0x0, 0x0, 0x40, 0x0, 0x0, 0x3, - 0xc0, 0x6, 0x3d, 0x10, 0x43, 0x0, 0xa6, 0xb5, - 0x5a, 0x6b, 0x75, 0x40, 0x51, 0x6, 0x52, 0x20, - 0x1c, 0x0, 0x0, 0xb4, 0x4b, 0x27, 0x54, 0x5c, - 0x10, 0xc, 0x55, 0xc0, 0x86, 0x55, 0xc0, 0x0, - 0xb0, 0xa, 0x8, 0x20, 0xb, 0x0, 0xc, 0x55, - 0x90, 0x75, 0x55, 0xc0, 0x0, 0xb0, 0x85, 0x55, - 0x88, 0xb, 0x0, 0xb, 0x9, 0x55, 0x58, 0x70, - 0xb0, 0x0, 0xb0, 0x91, 0x0, 0x47, 0xb, 0x0, - 0xb, 0x9, 0x55, 0x57, 0x50, 0xb0, 0x0, 0xc0, - 0x0, 0x0, 0x4, 0x8d, 0x0, 0x2, 0x0, 0x0, - 0x0, 0x1, 0x20, - - /* U+7C73 "米" */ - 0x0, 0x0, 0x0, 0x40, 0x0, 0x0, 0x0, 0x0, - 0x10, 0x0, 0xb5, 0x0, 0x60, 0x0, 0x0, 0x1a, - 0x10, 0xb1, 0x6, 0xc1, 0x0, 0x0, 0x7, 0xa0, - 0xb1, 0xb, 0x10, 0x0, 0x0, 0x1, 0x90, 0xb1, - 0x72, 0x0, 0x0, 0x16, 0x55, 0x56, 0xd8, 0x85, - 0x5b, 0x70, 0x0, 0x0, 0xb, 0xf7, 0x10, 0x0, - 0x0, 0x0, 0x0, 0x4a, 0xb2, 0x80, 0x0, 0x0, - 0x0, 0x1, 0xc1, 0xb1, 0x67, 0x0, 0x0, 0x0, - 0xb, 0x20, 0xb1, 0xa, 0x80, 0x0, 0x0, 0x91, - 0x0, 0xb1, 0x0, 0xbd, 0x60, 0x26, 0x0, 0x0, - 0xb1, 0x0, 0x9, 0x50, 0x0, 0x0, 0x0, 0xb2, - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x20, 0x0, - 0x0, 0x0, - - /* U+7CBE "精" */ - 0x0, 0x2, 0x0, 0x0, 0x5, 0x0, 0x0, 0x0, - 0xd, 0x10, 0x0, 0xc, 0x0, 0x0, 0x6, 0xb, - 0xb, 0x36, 0x5c, 0x57, 0x60, 0x6, 0x6b, 0x63, - 0x0, 0xb, 0x3, 0x0, 0x1, 0x3b, 0x31, 0x6, - 0x5c, 0x56, 0x10, 0x6, 0x5d, 0x57, 0x45, 0x5c, - 0x55, 0x90, 0x0, 0x5e, 0x10, 0x12, 0x0, 0x2, - 0x0, 0x0, 0xac, 0xa4, 0xc, 0x55, 0x5d, 0x10, - 0x1, 0x9b, 0x27, 0xc, 0x55, 0x5c, 0x0, 0x7, - 0x2b, 0x0, 0xb, 0x0, 0xb, 0x0, 0x14, 0xb, - 0x0, 0xc, 0x55, 0x5c, 0x0, 0x10, 0xb, 0x0, - 0xb, 0x0, 0xb, 0x0, 0x0, 0xc, 0x0, 0xb, - 0x2, 0x8c, 0x0, 0x0, 0x2, 0x0, 0x3, 0x0, - 0x12, 0x0, - - /* U+7CD6 "糖" */ - 0x0, 0x20, 0x0, 0x0, 0x31, 0x0, 0x0, 0x0, - 0x67, 0x0, 0x0, 0xc, 0x0, 0x10, 0x15, 0x65, - 0x95, 0xb5, 0x59, 0x57, 0x70, 0xc, 0x66, 0x90, - 0xb0, 0xc, 0x1, 0x0, 0x5, 0x69, 0x0, 0xb4, - 0x6c, 0x5d, 0x0, 0x36, 0xa8, 0x95, 0xb1, 0x1b, - 0xb, 0x50, 0x0, 0xb5, 0x0, 0xa5, 0x4c, 0x5c, - 0x40, 0x0, 0xea, 0x71, 0xa3, 0x5c, 0x5c, 0x0, - 0x5, 0xa5, 0xa3, 0x81, 0xb, 0x4, 0x0, 0x7, - 0x65, 0x6, 0x58, 0x56, 0x5b, 0x10, 0x31, 0x65, - 0x9, 0xa, 0x0, 0xb, 0x0, 0x0, 0x75, 0x16, - 0xa, 0x0, 0xb, 0x0, 0x0, 0x75, 0x60, 0xb, - 0x55, 0x5c, 0x0, 0x0, 0x20, 0x0, 0x2, 0x0, - 0x0, 0x0, - - /* U+7CFB "系" */ - 0x0, 0x0, 0x0, 0x0, 0x0, 0x42, 0x0, 0x0, - 0x2, 0x46, 0x79, 0xaa, 0x60, 0x0, 0x24, 0x32, - 0xb7, 0x0, 0x0, 0x0, 0x0, 0x0, 0x85, 0x0, - 0x25, 0x0, 0x0, 0x4, 0x94, 0x23, 0x5c, 0x60, - 0x0, 0x0, 0x9a, 0x65, 0xa7, 0x0, 0x0, 0x0, - 0x0, 0x6, 0x81, 0x3, 0x60, 0x0, 0x1, 0x8b, - 0x64, 0x55, 0x59, 0xe1, 0x0, 0x1a, 0x64, 0x2c, - 0x0, 0x9, 0x20, 0x0, 0x7, 0x70, 0xc1, 0x61, - 0x0, 0x0, 0x5, 0xb1, 0xc, 0x1, 0xb9, 0x0, - 0x7, 0x60, 0x21, 0xc0, 0x0, 0xc8, 0x5, 0x10, - 0x3, 0xca, 0x0, 0x1, 0x50, 0x0, 0x0, 0x1, - 0x0, 0x0, 0x0, - - /* U+7D00 "紀" */ - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0xa, 0x30, 0x0, 0x0, 0x5, 0x10, 0x0, 0x38, - 0x0, 0x36, 0x55, 0x5d, 0x20, 0x0, 0x80, 0x34, - 0x0, 0x0, 0xc, 0x0, 0xb, 0x65, 0xb3, 0x0, - 0x0, 0xc, 0x0, 0x6, 0x38, 0x40, 0x7, 0x55, - 0x5d, 0x0, 0x0, 0x65, 0x26, 0xc, 0x0, 0x6, - 0x0, 0x8, 0x84, 0x6d, 0x2c, 0x0, 0x0, 0x0, - 0xb, 0x82, 0x6, 0x1c, 0x0, 0x0, 0x0, 0x0, - 0x1, 0x16, 0xc, 0x0, 0x0, 0x20, 0x6, 0xb, - 0xb, 0x2c, 0x0, 0x0, 0x80, 0xb, 0xb, 0x36, - 0x3d, 0x0, 0x0, 0xc0, 0x36, 0x3, 0x0, 0x9, - 0xdb, 0xbd, 0xe1, - - /* U+7D04 "約" */ - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x5, 0xa0, 0x0, 0x6b, 0x0, 0x0, 0x0, 0xa, - 0x10, 0x0, 0xa3, 0x0, 0x0, 0x0, 0x72, 0x9, - 0x1, 0xd5, 0x55, 0xb1, 0x7, 0xa6, 0x97, 0x6, - 0x20, 0x0, 0xc0, 0x4, 0x54, 0x80, 0x15, 0x0, - 0x0, 0xc0, 0x0, 0x38, 0x8, 0x12, 0x20, 0x0, - 0xc0, 0x5, 0xb4, 0x6a, 0x80, 0xb6, 0x0, 0xb0, - 0x5, 0x83, 0x2, 0x50, 0x1d, 0x1, 0xa0, 0x0, - 0x12, 0x5, 0x10, 0x1, 0x2, 0x90, 0x4, 0x36, - 0x51, 0xc0, 0x0, 0x4, 0x80, 0xb, 0x23, 0xa0, - 0xa0, 0x0, 0x6, 0x60, 0x9, 0x0, 0x20, 0x0, - 0x5, 0xce, 0x10, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x10, 0x0, - - /* U+7D19 "紙" */ - 0x0, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0xd, 0x10, 0x0, 0x1, 0x7c, 0x10, 0x0, 0x74, - 0x0, 0x85, 0x6d, 0x40, 0x0, 0x3, 0x70, 0x63, - 0x91, 0xb, 0x0, 0x0, 0x2d, 0x76, 0xb1, 0x91, - 0xb, 0x0, 0x0, 0x6, 0x19, 0x10, 0x91, 0xa, - 0x3, 0x30, 0x0, 0x91, 0x62, 0x95, 0x5b, 0x55, - 0x40, 0x1c, 0x66, 0x8b, 0x91, 0x7, 0x20, 0x0, - 0x9, 0x40, 0x7, 0x91, 0x5, 0x60, 0x0, 0x1, - 0x20, 0x61, 0x91, 0x0, 0xa0, 0x10, 0x7, 0x47, - 0x2b, 0x91, 0x1, 0xa2, 0x60, 0x39, 0xb, 0x2, - 0xa7, 0x50, 0x2c, 0xa0, 0x64, 0x0, 0x0, 0xa4, - 0x0, 0x2, 0xa0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, - - /* U+7D20 "素" */ - 0x0, 0x0, 0x0, 0x13, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x2b, 0x0, 0x6, 0x0, 0x0, 0x56, - 0x55, 0x6b, 0x55, 0x55, 0x20, 0x0, 0x5, 0x55, - 0x6b, 0x55, 0xa2, 0x0, 0x0, 0x0, 0x0, 0x29, - 0x0, 0x0, 0x60, 0x6, 0x55, 0x5b, 0xa5, 0x55, - 0x55, 0x62, 0x0, 0x2, 0x75, 0x12, 0xc6, 0x0, - 0x0, 0x0, 0x7, 0x96, 0x8a, 0x33, 0x0, 0x0, - 0x0, 0x0, 0x48, 0x40, 0x6, 0xa0, 0x0, 0x0, - 0xe, 0xd8, 0x8c, 0x53, 0x75, 0x0, 0x0, 0x2, - 0x92, 0x29, 0x25, 0x10, 0x0, 0x0, 0x9, 0x70, - 0x29, 0x2, 0xb8, 0x0, 0x2, 0x61, 0x16, 0xd8, - 0x0, 0xc, 0x20, 0x0, 0x0, 0x0, 0x30, 0x0, - 0x0, 0x0, - - /* U+7D30 "細" */ - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0xd, 0x10, 0x0, 0x0, 0x0, 0x10, 0x0, 0x74, - 0x0, 0xb5, 0x5a, 0x57, 0xc0, 0x3, 0x60, 0x62, - 0xb0, 0xb, 0x2, 0x90, 0x3c, 0x66, 0xc1, 0xb0, - 0xb, 0x2, 0x90, 0x6, 0x2a, 0x10, 0xb0, 0xb, - 0x2, 0x90, 0x0, 0x91, 0x70, 0xb5, 0x5c, 0x56, - 0x90, 0x2c, 0x66, 0x98, 0xb0, 0xb, 0x2, 0x90, - 0x1a, 0x51, 0x16, 0xb0, 0xb, 0x2, 0x90, 0x1, - 0x10, 0x61, 0xb0, 0xb, 0x2, 0x90, 0x7, 0x28, - 0x3b, 0xb0, 0xb, 0x2, 0x90, 0x2a, 0xd, 0x5, - 0xb5, 0x5b, 0x56, 0x90, 0x44, 0x1, 0x0, 0xb0, - 0x0, 0x2, 0x90, 0x0, 0x0, 0x0, 0x10, 0x0, - 0x0, 0x0, - - /* U+7D39 "紹" */ - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x9, 0x50, 0x35, 0x55, 0x55, 0xa1, 0x0, 0x2a, - 0x0, 0x10, 0xa3, 0x0, 0xc0, 0x0, 0x90, 0x16, - 0x0, 0xc1, 0x1, 0xb0, 0xa, 0x75, 0xa5, 0x1, - 0xc0, 0x3, 0x90, 0x7, 0x57, 0x60, 0x7, 0x50, - 0x5, 0x70, 0x0, 0x47, 0x33, 0x27, 0x1, 0x8d, - 0x30, 0x6, 0x82, 0x5d, 0x43, 0x0, 0x3, 0x40, - 0xa, 0x94, 0x17, 0xc, 0x55, 0x55, 0xd0, 0x0, - 0x2, 0x18, 0xb, 0x0, 0x0, 0xb0, 0x4, 0x28, - 0x28, 0x6b, 0x0, 0x0, 0xb0, 0xb, 0x26, 0x61, - 0x3c, 0x55, 0x55, 0xb0, 0x8, 0x0, 0x0, 0xa, - 0x0, 0x0, 0x90, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, - - /* U+7D42 "終" */ - 0x0, 0x0, 0x0, 0x0, 0x20, 0x0, 0x0, 0x0, - 0xa, 0x30, 0x2, 0xe1, 0x0, 0x0, 0x0, 0x39, - 0x0, 0x8, 0x85, 0x5a, 0x20, 0x0, 0x90, 0x35, - 0x2b, 0x10, 0x2b, 0x0, 0xb, 0x76, 0xb3, 0x60, - 0x70, 0xa2, 0x0, 0x5, 0x38, 0x40, 0x0, 0x5a, - 0x70, 0x0, 0x0, 0x64, 0x25, 0x0, 0x4e, 0x60, - 0x0, 0x9, 0x85, 0x5d, 0x15, 0x70, 0xab, 0x50, - 0x8, 0x62, 0x5, 0x62, 0x29, 0x25, 0x81, 0x1, - 0x2, 0x35, 0x0, 0x4, 0xa0, 0x0, 0x7, 0xa, - 0xc, 0x12, 0x62, 0x10, 0x0, 0xc, 0xb, 0x23, - 0x0, 0x1a, 0xb1, 0x0, 0x26, 0x0, 0x0, 0x0, - 0x0, 0x89, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x1, 0x0, - - /* U+7D44 "組" */ - 0x0, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0xb, 0x30, 0x7, 0x55, 0x59, 0x0, 0x0, 0x47, - 0x0, 0xc, 0x0, 0xc, 0x0, 0x1, 0x80, 0x36, - 0xc, 0x0, 0xc, 0x0, 0xc, 0x76, 0xb3, 0xc, - 0x0, 0xc, 0x0, 0x6, 0x38, 0x30, 0xd, 0x55, - 0x5c, 0x0, 0x0, 0x74, 0x26, 0xc, 0x0, 0xc, - 0x0, 0xa, 0x85, 0x6d, 0x2c, 0x0, 0xc, 0x0, - 0x8, 0x61, 0x5, 0x1d, 0x55, 0x5c, 0x0, 0x1, - 0x3, 0x26, 0xc, 0x0, 0xc, 0x0, 0x7, 0xa, - 0xc, 0x1c, 0x0, 0xc, 0x0, 0xc, 0x9, 0x32, - 0xc, 0x0, 0xc, 0x0, 0x16, 0x0, 0x4, 0x5d, - 0x55, 0x5d, 0xd1, 0x0, 0x0, 0x1, 0x0, 0x0, - 0x0, 0x0, - - /* U+7D4C "経" */ - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0xc, 0x0, 0x66, 0x55, 0x59, 0x40, 0x0, 0x74, - 0x0, 0x7, 0x0, 0x1d, 0x20, 0x2, 0x70, 0x62, - 0x2, 0x70, 0xa4, 0x0, 0x1c, 0x55, 0xb0, 0x0, - 0x7b, 0x60, 0x0, 0x7, 0x3a, 0x10, 0x0, 0x9b, - 0xa2, 0x0, 0x0, 0x82, 0x61, 0x48, 0x14, 0x4d, - 0xc2, 0x9, 0x64, 0x7b, 0x10, 0xd, 0x0, 0x10, - 0xa, 0x62, 0x7, 0x25, 0x5d, 0x59, 0x50, 0x0, - 0x12, 0x52, 0x1, 0xc, 0x0, 0x0, 0x7, 0xb, - 0xd, 0x0, 0xc, 0x0, 0x0, 0x1c, 0xc, 0x5, - 0x0, 0xc, 0x0, 0x70, 0x25, 0x0, 0x3, 0x65, - 0x55, 0x55, 0x51, - - /* U+7D50 "結" */ - 0x0, 0x1, 0x0, 0x0, 0x2, 0x0, 0x0, 0x0, - 0xc, 0x20, 0x0, 0xc, 0x10, 0x0, 0x0, 0x66, - 0x0, 0x0, 0xb, 0x0, 0x0, 0x2, 0x80, 0x54, - 0x45, 0x5c, 0x55, 0xb1, 0x1c, 0x66, 0xc2, 0x10, - 0xb, 0x0, 0x0, 0x7, 0x39, 0x20, 0x0, 0xb, - 0x0, 0x0, 0x0, 0x83, 0x34, 0x16, 0x5a, 0x59, - 0x40, 0x1a, 0x64, 0x6e, 0x10, 0x0, 0x0, 0x0, - 0xb, 0x62, 0x7, 0xb, 0x55, 0x5c, 0x20, 0x1, - 0x3, 0x26, 0xb, 0x0, 0xb, 0x0, 0x6, 0xa, - 0xb, 0x2b, 0x0, 0xb, 0x0, 0xc, 0xa, 0x34, - 0x1c, 0x55, 0x5c, 0x0, 0x27, 0x1, 0x0, 0xb, - 0x0, 0x9, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, - - /* U+7D61 "絡" */ - 0x0, 0x0, 0x0, 0x0, 0x40, 0x0, 0x0, 0x0, - 0x1c, 0x0, 0x4, 0xb0, 0x0, 0x0, 0x0, 0x73, - 0x0, 0xa, 0x75, 0x59, 0x10, 0x2, 0x70, 0x60, - 0x2b, 0x0, 0x3c, 0x10, 0x1b, 0x34, 0xc0, 0x72, - 0x50, 0xc1, 0x0, 0x9, 0x4b, 0x12, 0x0, 0x5b, - 0x30, 0x0, 0x0, 0x72, 0x60, 0x0, 0x99, 0x80, - 0x0, 0x8, 0x42, 0x87, 0x37, 0x10, 0x5d, 0x91, - 0x1e, 0x95, 0x29, 0x28, 0x55, 0x59, 0x20, 0x0, - 0x0, 0x20, 0xb, 0x0, 0xb, 0x0, 0x5, 0x6, - 0x56, 0xb, 0x0, 0xb, 0x0, 0xb, 0xd, 0x1b, - 0xb, 0x0, 0xb, 0x0, 0x48, 0x6, 0x0, 0xd, - 0x55, 0x5b, 0x0, 0x0, 0x0, 0x0, 0x1, 0x0, - 0x1, 0x0, - - /* U+7D66 "給" */ - 0x0, 0x0, 0x0, 0x0, 0x1, 0x0, 0x0, 0x0, - 0x8, 0x50, 0x0, 0x2e, 0x10, 0x0, 0x0, 0x1a, - 0x0, 0x0, 0x87, 0x40, 0x0, 0x0, 0x81, 0x34, - 0x1, 0xb0, 0x70, 0x0, 0x7, 0x85, 0xa3, 0x9, - 0x20, 0x1b, 0x10, 0x4, 0x57, 0x50, 0x63, 0x0, - 0x16, 0xe4, 0x0, 0x36, 0x27, 0x16, 0x55, 0x64, - 0x30, 0x4, 0xa4, 0x6d, 0x11, 0x0, 0x3, 0x0, - 0x5, 0x83, 0x6, 0x1c, 0x55, 0x5d, 0x10, 0x1, - 0x14, 0x35, 0xa, 0x0, 0xb, 0x0, 0x6, 0x27, - 0x3d, 0x2a, 0x0, 0xb, 0x0, 0xd, 0x6, 0x54, - 0x1c, 0x55, 0x5c, 0x0, 0x3, 0x0, 0x0, 0x1a, - 0x0, 0xa, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, - - /* U+7D71 "統" */ - 0x0, 0x0, 0x0, 0x0, 0x10, 0x0, 0x0, 0x0, - 0xb, 0x30, 0x0, 0x97, 0x0, 0x0, 0x0, 0x38, - 0x0, 0x0, 0x17, 0x0, 0x60, 0x0, 0x90, 0x34, - 0x65, 0xa8, 0x55, 0x50, 0xb, 0x65, 0xb3, 0x3, - 0xa0, 0x31, 0x0, 0x7, 0x38, 0x30, 0x47, 0x0, - 0x1b, 0x20, 0x0, 0x64, 0x34, 0x99, 0x65, 0x36, - 0x80, 0x9, 0x74, 0x6e, 0x16, 0x50, 0xa0, 0x0, - 0xb, 0x83, 0x17, 0x7, 0x40, 0xb0, 0x0, 0x1, - 0x11, 0x55, 0x9, 0x20, 0xb0, 0x0, 0x7, 0xb, - 0xc, 0xb, 0x0, 0xb0, 0x30, 0x1c, 0xa, 0x1, - 0x57, 0x0, 0xb0, 0x60, 0x13, 0x0, 0x6, 0x60, - 0x0, 0xba, 0xd4, 0x0, 0x0, 0x30, 0x0, 0x0, - 0x0, 0x0, - - /* U+7D75 "絵" */ - 0x0, 0x1, 0x0, 0x0, 0x11, 0x0, 0x0, 0x0, - 0x1d, 0x0, 0x0, 0x8a, 0x0, 0x0, 0x0, 0x93, - 0x0, 0x1, 0xc5, 0x20, 0x0, 0x4, 0x50, 0x82, - 0x9, 0x30, 0x91, 0x0, 0x2d, 0x77, 0xb0, 0x55, - 0x0, 0x1c, 0x40, 0x5, 0x1a, 0x14, 0x34, 0x55, - 0xb5, 0xb3, 0x0, 0x91, 0x62, 0x1, 0x0, 0x0, - 0x0, 0x1a, 0x44, 0x8b, 0x0, 0x0, 0x4, 0x30, - 0x1d, 0x73, 0x8, 0x55, 0xa7, 0x55, 0x40, 0x0, - 0x11, 0x51, 0x1, 0xd2, 0x0, 0x0, 0x6, 0xa, - 0x1c, 0x9, 0x20, 0x33, 0x0, 0xa, 0xb, 0x6, - 0x74, 0x12, 0x3c, 0x20, 0x24, 0x0, 0x0, 0xb9, - 0x64, 0x25, 0x80, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, - - /* U+7D93 "經" */ - 0x0, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x1c, 0x1, 0x55, 0x55, 0x58, 0x90, 0x0, 0x82, - 0x0, 0x23, 0x5, 0x4, 0x0, 0x2, 0x60, 0x70, - 0x68, 0x3a, 0x1c, 0x10, 0x1b, 0x46, 0xa0, 0x90, - 0x80, 0x71, 0x0, 0x8, 0x3a, 0x1, 0x70, 0x80, - 0x83, 0x0, 0x0, 0x82, 0x50, 0x86, 0x4a, 0xd, - 0x10, 0x7, 0x51, 0x95, 0x26, 0x7, 0x4, 0x0, - 0xd, 0xa5, 0x47, 0x45, 0x55, 0x57, 0x70, 0x1, - 0x1, 0x41, 0x10, 0xb, 0x0, 0x0, 0x6, 0x9, - 0x1b, 0x0, 0xb, 0x0, 0x0, 0xc, 0xc, 0x6, - 0x0, 0xb, 0x0, 0x0, 0x18, 0x2, 0x2, 0x55, - 0x5c, 0x56, 0xd1, 0x0, 0x0, 0x0, 0x10, 0x0, - 0x0, 0x0, - - /* U+7D9A "続" */ - 0x0, 0x1, 0x0, 0x0, 0x3, 0x0, 0x0, 0x0, - 0x1c, 0x0, 0x0, 0xc, 0x0, 0x0, 0x0, 0x73, - 0x0, 0x55, 0x5c, 0x57, 0xa0, 0x1, 0x70, 0x60, - 0x10, 0xb, 0x0, 0x0, 0xb, 0x45, 0xa0, 0x6, - 0x5a, 0x5a, 0x10, 0x8, 0x4a, 0x0, 0x30, 0x0, - 0x0, 0x20, 0x0, 0x72, 0x50, 0xa5, 0x55, 0x55, - 0xe1, 0x6, 0x51, 0x96, 0x74, 0x51, 0x44, 0x20, - 0xd, 0xa6, 0x57, 0x5, 0x71, 0xa0, 0x0, 0x1, - 0x0, 0x30, 0x7, 0x41, 0x90, 0x0, 0x5, 0x17, - 0x2a, 0xa, 0x1, 0x90, 0x40, 0xb, 0xc, 0x7, - 0x47, 0x1, 0x90, 0x70, 0x17, 0x3, 0x6, 0x60, - 0x0, 0xca, 0xe2, 0x0, 0x0, 0x30, 0x0, 0x0, - 0x0, 0x0, - - /* U+7DAD "維" */ - 0x0, 0x1, 0x0, 0x1, 0x0, 0x0, 0x0, 0x0, - 0x1b, 0x0, 0x6, 0x6a, 0x30, 0x0, 0x0, 0x82, - 0x0, 0xb, 0x14, 0x80, 0x0, 0x2, 0x60, 0x70, - 0x1d, 0x57, 0x58, 0x80, 0x1b, 0x56, 0xa0, 0x7b, - 0xa, 0x10, 0x0, 0x6, 0x2a, 0x1, 0x6b, 0xa, - 0x11, 0x0, 0x0, 0x81, 0x74, 0xc, 0x5c, 0x57, - 0x40, 0x9, 0x54, 0xa7, 0xb, 0xa, 0x10, 0x0, - 0xc, 0x72, 0x16, 0xb, 0xa, 0x13, 0x10, 0x1, - 0x20, 0x51, 0xc, 0x5c, 0x55, 0x30, 0x6, 0x19, - 0x1d, 0xb, 0xa, 0x10, 0x0, 0x2a, 0xc, 0x5, - 0xb, 0xa, 0x12, 0x50, 0x33, 0x0, 0x0, 0xd, - 0x55, 0x55, 0x50, 0x0, 0x0, 0x0, 0x2, 0x0, - 0x0, 0x0, - - /* U+7DB2 "網" */ - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x1b, 0x0, 0x85, 0x55, 0x55, 0xa1, 0x0, 0x72, - 0x0, 0xb2, 0x20, 0x82, 0xc0, 0x2, 0x60, 0x60, - 0xb0, 0xb2, 0x90, 0xc0, 0x1c, 0x67, 0x90, 0xb4, - 0x88, 0x86, 0xc0, 0x6, 0x2a, 0x0, 0xb1, 0x42, - 0x0, 0xc0, 0x0, 0x91, 0x60, 0xb0, 0xd, 0x0, - 0xc0, 0x9, 0x54, 0xa6, 0xb6, 0x86, 0x77, 0xc0, - 0xb, 0x72, 0x25, 0xb0, 0xb0, 0x0, 0xc0, 0x1, - 0x20, 0x70, 0xb0, 0xb0, 0x40, 0xc0, 0x7, 0x45, - 0x76, 0xb1, 0x75, 0x52, 0xc0, 0x3a, 0x29, 0x23, - 0xb0, 0x0, 0x0, 0xc0, 0x42, 0x0, 0x0, 0xb0, - 0x0, 0x5d, 0x90, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x1, 0x0, - - /* U+7DD1 "緑" */ - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x1b, 0x0, 0x65, 0x55, 0x5c, 0x0, 0x0, 0x82, - 0x0, 0x0, 0x0, 0xc, 0x0, 0x3, 0x50, 0x70, - 0x26, 0x55, 0x5c, 0x0, 0x1c, 0x67, 0x80, 0x0, - 0x0, 0xc, 0x20, 0x6, 0x29, 0x1, 0x75, 0x69, - 0x58, 0x81, 0x0, 0x90, 0x70, 0x20, 0x2d, 0x2, - 0x60, 0xb, 0x66, 0xa6, 0x86, 0x2c, 0x68, 0x20, - 0x9, 0x50, 0x24, 0x9, 0x3a, 0xa0, 0x0, 0x2, - 0x31, 0x91, 0x5, 0x7a, 0x64, 0x0, 0x8, 0x1a, - 0x57, 0x94, 0x2a, 0xb, 0x20, 0x4a, 0x8, 0x7, - 0x30, 0x29, 0x2, 0xc2, 0x21, 0x0, 0x0, 0x5, - 0xe7, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x20, - 0x0, 0x0, - - /* U+7DD2 "緒" */ - 0x0, 0x0, 0x0, 0x0, 0x10, 0x0, 0x0, 0x0, - 0x1a, 0x0, 0x0, 0x92, 0x1, 0x0, 0x0, 0x82, - 0x0, 0x0, 0x91, 0x2b, 0x20, 0x2, 0x60, 0x60, - 0x65, 0xb6, 0x98, 0x0, 0x1b, 0x46, 0xa0, 0x0, - 0x91, 0xa0, 0x10, 0x7, 0x3a, 0x5, 0x65, 0x9b, - 0x76, 0xa0, 0x0, 0x91, 0x60, 0x0, 0x75, 0x0, - 0x0, 0xa, 0x54, 0xa7, 0xa, 0xa5, 0x59, 0x0, - 0xb, 0x62, 0x26, 0x89, 0x0, 0xa, 0x0, 0x1, - 0x20, 0x64, 0x1b, 0x55, 0x5b, 0x0, 0x7, 0x36, - 0x84, 0x9, 0x0, 0xa, 0x0, 0x2a, 0x1b, 0x25, - 0x19, 0x0, 0xa, 0x0, 0x33, 0x1, 0x0, 0x1b, - 0x55, 0x5b, 0x0, 0x0, 0x0, 0x0, 0x1, 0x0, - 0x0, 0x0, - - /* U+7DDA "線" */ - 0x0, 0x0, 0x0, 0x0, 0x11, 0x0, 0x0, 0x0, - 0x29, 0x0, 0x0, 0x85, 0x0, 0x0, 0x0, 0x92, - 0x0, 0x95, 0x85, 0x5c, 0x10, 0x3, 0x50, 0x50, - 0xb0, 0x0, 0xb, 0x0, 0x2a, 0x37, 0x80, 0xb5, - 0x55, 0x5c, 0x0, 0x18, 0x4a, 0x0, 0xb0, 0x0, - 0xb, 0x0, 0x0, 0x92, 0x40, 0xa5, 0x6b, 0x59, - 0x0, 0x9, 0x33, 0xd1, 0x1, 0x1d, 0x1, 0x50, - 0x1d, 0x73, 0x74, 0x6c, 0x8b, 0x59, 0x50, 0x2, - 0x30, 0x80, 0xb, 0x1a, 0x90, 0x0, 0x7, 0x65, - 0x93, 0x83, 0x1a, 0x57, 0x0, 0x86, 0x37, 0x15, - 0x50, 0x1a, 0xa, 0xa1, 0x30, 0x0, 0x42, 0x6, - 0xd8, 0x1, 0x20, 0x0, 0x0, 0x0, 0x0, 0x30, - 0x0, 0x0, - - /* U+7DE0 "締" */ - 0x0, 0x0, 0x0, 0x0, 0x40, 0x0, 0x0, 0x0, - 0x1b, 0x0, 0x0, 0x5b, 0x0, 0x0, 0x0, 0x82, - 0x2, 0x65, 0x59, 0x58, 0x70, 0x2, 0x60, 0x50, - 0x8, 0x0, 0xa2, 0x0, 0x1a, 0x35, 0xa0, 0x5, - 0x60, 0x80, 0x0, 0x8, 0x4a, 0x5, 0x75, 0x56, - 0x55, 0xd1, 0x0, 0x81, 0x5b, 0x10, 0x18, 0x2, - 0x30, 0x8, 0x42, 0xa3, 0x20, 0x19, 0x3, 0x0, - 0xe, 0x94, 0x55, 0xa5, 0x6b, 0x5c, 0x10, 0x0, - 0x10, 0x50, 0xa0, 0x19, 0xa, 0x0, 0x6, 0x63, - 0x85, 0xa0, 0x19, 0xa, 0x0, 0x29, 0x2a, 0x13, - 0x90, 0x19, 0x7b, 0x0, 0x53, 0x1, 0x0, 0x0, - 0x19, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x1, - 0x0, 0x0, - - /* U+7DE9 "緩" */ - 0x0, 0x0, 0x0, 0x0, 0x0, 0x1, 0x0, 0x0, - 0x1c, 0x0, 0x35, 0x67, 0x9b, 0x40, 0x0, 0x85, - 0x0, 0x30, 0x50, 0x1a, 0x0, 0x2, 0x70, 0x60, - 0x65, 0x46, 0x55, 0x0, 0x1b, 0x46, 0xa1, 0x77, - 0x65, 0x88, 0x60, 0x7, 0x3a, 0x0, 0x1, 0xa0, - 0x0, 0x0, 0x0, 0x81, 0x64, 0x67, 0xa5, 0x55, - 0xb1, 0x8, 0x54, 0xa6, 0x8, 0x40, 0x0, 0x0, - 0xb, 0x72, 0x25, 0xb, 0x85, 0x6d, 0x0, 0x2, - 0x30, 0x60, 0x47, 0x70, 0xa4, 0x0, 0x8, 0x38, - 0x85, 0x90, 0x1c, 0x70, 0x0, 0x59, 0x9, 0x19, - 0x10, 0x7a, 0xb2, 0x0, 0x10, 0x0, 0x21, 0x27, - 0x30, 0x3d, 0xb2, 0x0, 0x0, 0x0, 0x20, 0x0, - 0x0, 0x20, - - /* U+7DF4 "練" */ - 0x0, 0x1, 0x0, 0x0, 0x2, 0x0, 0x0, 0x0, - 0x1c, 0x0, 0x0, 0xb, 0x0, 0x0, 0x0, 0x72, - 0x3, 0x65, 0x5c, 0x56, 0xb1, 0x2, 0x60, 0x70, - 0x0, 0xa, 0x0, 0x0, 0x1c, 0x56, 0x90, 0x95, - 0x5c, 0x5b, 0x20, 0x6, 0x29, 0x0, 0xa5, 0xa, - 0x7b, 0x0, 0x0, 0x81, 0x60, 0xa4, 0x6a, 0x7a, - 0x0, 0x8, 0x53, 0x97, 0xb5, 0x6d, 0x5c, 0x0, - 0xc, 0x73, 0x26, 0x61, 0xdb, 0x33, 0x0, 0x1, - 0x11, 0x61, 0x8, 0x5a, 0x80, 0x0, 0x6, 0xa, - 0x3a, 0x39, 0xa, 0x49, 0x0, 0x1b, 0xc, 0x5, - 0x80, 0xa, 0x9, 0xc3, 0x25, 0x0, 0x14, 0x0, - 0xa, 0x0, 0x30, 0x0, 0x0, 0x0, 0x0, 0x1, - 0x0, 0x0, - - /* U+7E3D "總" */ - 0x0, 0x0, 0x0, 0x0, 0x11, 0x0, 0x0, 0x0, - 0xc, 0x0, 0x0, 0x76, 0x0, 0x0, 0x0, 0x73, - 0x0, 0x94, 0x84, 0x48, 0x70, 0x1, 0x70, 0x60, - 0xa0, 0xa5, 0x27, 0x50, 0xb, 0x45, 0xa0, 0xa3, - 0x85, 0xc9, 0x50, 0x7, 0x39, 0x0, 0xa3, 0x39, - 0x76, 0x50, 0x0, 0x81, 0x60, 0xb1, 0x66, 0xc6, - 0x50, 0x9, 0x65, 0x97, 0xb8, 0x66, 0x7a, 0x50, - 0xa, 0x62, 0x15, 0x21, 0x44, 0x2, 0x0, 0x0, - 0x14, 0x30, 0x2c, 0xd, 0x14, 0x60, 0x5, 0x63, - 0xc6, 0x2a, 0x3, 0x3, 0xc2, 0x1a, 0x37, 0x1d, - 0xa, 0x0, 0x6, 0x10, 0x56, 0x0, 0x1, 0xd, - 0xaa, 0xbc, 0x0, - - /* U+7E3E "績" */ - 0x0, 0x0, 0x0, 0x0, 0x12, 0x0, 0x0, 0x0, - 0x1c, 0x0, 0x0, 0x2a, 0x4, 0x0, 0x0, 0x73, - 0x3, 0x65, 0x6b, 0x56, 0x30, 0x1, 0x70, 0x60, - 0x46, 0x6b, 0x58, 0x0, 0xb, 0x45, 0x91, 0x11, - 0x39, 0x14, 0x70, 0x7, 0x39, 0x3, 0x63, 0x33, - 0x36, 0x30, 0x0, 0x72, 0x60, 0xc5, 0x55, 0x5d, - 0x20, 0x7, 0x52, 0xa5, 0xc5, 0x55, 0x5c, 0x0, - 0xc, 0x94, 0x36, 0xc4, 0x44, 0x4c, 0x0, 0x0, - 0x20, 0x50, 0xc1, 0x11, 0x1b, 0x0, 0x6, 0x37, - 0x57, 0xa6, 0x55, 0x5a, 0x0, 0x1b, 0xc, 0x3, - 0xb, 0x60, 0x67, 0x10, 0x24, 0x0, 0x1, 0x93, - 0x0, 0x5, 0xd0, 0x0, 0x0, 0x3, 0x0, 0x0, - 0x0, 0x30, - - /* U+7E54 "織" */ - 0x0, 0x0, 0x0, 0x20, 0x0, 0x10, 0x0, 0x0, - 0x83, 0x0, 0x39, 0x0, 0xa0, 0x0, 0x0, 0x90, - 0x6, 0x58, 0x93, 0x97, 0x10, 0x6, 0x13, 0x15, - 0x20, 0xc0, 0x92, 0x90, 0x49, 0x4b, 0x21, 0x93, - 0x40, 0x90, 0x0, 0x35, 0x74, 0x26, 0x57, 0x55, - 0xb5, 0xb1, 0x1, 0x74, 0x22, 0x0, 0x30, 0x93, - 0x20, 0x19, 0x25, 0xb9, 0x65, 0xc0, 0x99, 0x40, - 0x4b, 0x51, 0x79, 0x10, 0xa0, 0x9b, 0x0, 0x0, - 0x24, 0x29, 0x65, 0xa0, 0xa5, 0x0, 0x7, 0x92, - 0xc9, 0x10, 0xa1, 0xc6, 0x22, 0x77, 0x75, 0x2a, - 0x65, 0x97, 0xb, 0xa0, 0x41, 0x0, 0x1, 0x1, - 0x50, 0x1, 0xd0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, - - /* U+7E70 "繰" */ - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0xc, 0x10, 0xb, 0x55, 0x5c, 0x0, 0x0, 0x45, - 0x0, 0xb, 0x0, 0xb, 0x0, 0x0, 0x80, 0x61, - 0xb, 0x55, 0x5a, 0x0, 0xb, 0x86, 0xb0, 0x75, - 0x70, 0x75, 0x70, 0x4, 0x19, 0x10, 0xa0, 0xa0, - 0xb0, 0x90, 0x0, 0x73, 0x61, 0xc5, 0xb0, 0xc5, - 0xa0, 0x6, 0x84, 0x8a, 0x40, 0x36, 0x50, 0x30, - 0x8, 0x83, 0x7, 0x65, 0x6e, 0x55, 0xb1, 0x0, - 0x10, 0x61, 0x0, 0xbc, 0x50, 0x0, 0x7, 0xa, - 0x2a, 0x9, 0x2c, 0x64, 0x0, 0x1b, 0xc, 0x3, - 0x82, 0xc, 0x9, 0x81, 0x14, 0x0, 0x15, 0x0, - 0xc, 0x0, 0x60, 0x0, 0x0, 0x0, 0x0, 0x1, - 0x0, 0x0, - - /* U+7E7C "繼" */ - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x56, 0x8, 0x16, 0x0, 0x33, 0x0, 0x0, 0xa0, - 0xa, 0x37, 0x40, 0x93, 0x20, 0x6, 0x31, 0x3a, - 0xb6, 0xa6, 0x8a, 0x20, 0x3a, 0x49, 0x4a, 0x18, - 0x30, 0x64, 0x10, 0x26, 0x57, 0xa, 0xa7, 0x96, - 0xa4, 0xa0, 0x1, 0x81, 0x4a, 0x10, 0x0, 0x13, - 0x50, 0x1a, 0x34, 0xda, 0x59, 0x55, 0x69, 0x30, - 0x2c, 0x51, 0x6a, 0x18, 0x30, 0x73, 0x20, 0x0, - 0x13, 0xa, 0x95, 0xa6, 0x89, 0x40, 0x6, 0x81, - 0xba, 0x18, 0x20, 0x64, 0x30, 0x56, 0x84, 0x7a, - 0x96, 0x95, 0xa4, 0x90, 0x61, 0x10, 0xc, 0x75, - 0x86, 0x67, 0xb0, 0x0, 0x0, 0x3, 0x0, 0x0, - 0x0, 0x0, - - /* U+7E8C "續" */ - 0x0, 0x0, 0x0, 0x0, 0x15, 0x0, 0x0, 0x0, - 0xb, 0x2, 0x55, 0x6c, 0x55, 0xb1, 0x0, 0x64, - 0x0, 0x21, 0x2a, 0x15, 0x20, 0x1, 0x80, 0x40, - 0x55, 0x44, 0x44, 0x40, 0x9, 0x23, 0xb0, 0xb5, - 0xa5, 0xa5, 0xc0, 0xa, 0x5b, 0x10, 0xa0, 0x90, - 0x90, 0xa0, 0x0, 0x63, 0x50, 0x95, 0x55, 0x56, - 0x50, 0x6, 0x52, 0x95, 0x87, 0x55, 0x5a, 0x50, - 0xd, 0x95, 0x37, 0x77, 0x55, 0x5a, 0x40, 0x0, - 0x10, 0x30, 0x87, 0x55, 0x5a, 0x40, 0x6, 0x64, - 0x93, 0x87, 0x55, 0x5a, 0x40, 0x29, 0x2a, 0x34, - 0x39, 0x60, 0x48, 0x10, 0x43, 0x1, 0x4, 0x84, - 0x0, 0x4, 0xd0, 0x0, 0x0, 0x1, 0x0, 0x0, - 0x0, 0x20, - - /* U+7EDF "统" */ - 0x0, 0x22, 0x0, 0x4, 0x0, 0x0, 0x0, 0x9, - 0x70, 0x0, 0x2c, 0x0, 0x0, 0x1, 0xb0, 0x5, - 0x55, 0xa5, 0x6c, 0x10, 0x81, 0xa, 0x20, 0x77, - 0x0, 0x0, 0x57, 0x39, 0x70, 0x19, 0x2, 0x0, - 0x7, 0x65, 0x80, 0x8, 0x0, 0x3a, 0x20, 0x1, - 0x90, 0xb, 0xaa, 0x6a, 0x7c, 0x1, 0xa2, 0x34, - 0x34, 0xa0, 0xb0, 0x30, 0x6d, 0x72, 0x0, 0x39, - 0xb, 0x0, 0x0, 0x0, 0x0, 0x5, 0x70, 0xb0, - 0x0, 0x14, 0x76, 0x40, 0x93, 0xb, 0x4, 0x8, - 0x81, 0x0, 0x3a, 0x0, 0xb0, 0x61, 0x0, 0x0, - 0x57, 0x0, 0xb, 0xbc, 0x40, 0x0, 0x10, 0x0, - 0x0, 0x0, 0x0, - - /* U+7F3A "缺" */ - 0x0, 0x20, 0x0, 0x0, 0x30, 0x0, 0x0, 0x0, - 0xb4, 0x0, 0x0, 0xc2, 0x0, 0x0, 0x0, 0xb0, - 0x1, 0x0, 0xb0, 0x0, 0x0, 0x5, 0x89, 0x59, - 0x46, 0xc5, 0x6b, 0x0, 0x7, 0xa, 0x0, 0x0, - 0xb0, 0x19, 0x0, 0x11, 0xa, 0x1, 0x20, 0xb0, - 0x19, 0x0, 0x36, 0x5c, 0x57, 0x60, 0xb0, 0x19, - 0x30, 0x5, 0x1a, 0x5, 0x65, 0xc7, 0x57, 0x72, - 0xa, 0xa, 0xa, 0x2, 0x86, 0x0, 0x0, 0xa, - 0xa, 0xa, 0x7, 0x33, 0x60, 0x0, 0xa, 0x5c, - 0x5c, 0x9, 0x0, 0xa1, 0x0, 0x8, 0x60, 0x4, - 0x81, 0x0, 0x3d, 0x20, 0x0, 0x0, 0x16, 0x10, - 0x0, 0x5, 0xb1, 0x0, 0x0, 0x10, 0x0, 0x0, - 0x0, 0x0, - - /* U+7F6E "置" */ - 0x0, 0x0, 0x0, 0x0, 0x0, 0x1, 0x0, 0x0, - 0xb6, 0x6b, 0x66, 0xa6, 0x6d, 0x0, 0x0, 0xc0, - 0xc, 0x0, 0xb0, 0xd, 0x0, 0x0, 0xc6, 0x6b, - 0x76, 0xa6, 0x6d, 0x0, 0x0, 0x20, 0x0, 0xa3, - 0x0, 0x7, 0x0, 0x2, 0x76, 0x66, 0xd6, 0x66, - 0x66, 0x10, 0x0, 0xa, 0x66, 0x96, 0x69, 0xa0, - 0x0, 0x0, 0xb, 0x10, 0x0, 0x4, 0x80, 0x0, - 0x0, 0xb, 0x66, 0x66, 0x68, 0x80, 0x0, 0x0, - 0xb, 0x76, 0x66, 0x69, 0x80, 0x0, 0x0, 0xb, - 0x10, 0x0, 0x4, 0x80, 0x0, 0x0, 0xb, 0x76, - 0x66, 0x69, 0x80, 0x0, 0x26, 0x6d, 0x76, 0x66, - 0x69, 0xb7, 0xd2, 0x1, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, - - /* U+7F8E "美" */ - 0x0, 0x0, 0x0, 0x0, 0x10, 0x0, 0x0, 0x0, - 0x0, 0xa3, 0x0, 0xc3, 0x0, 0x0, 0x0, 0x0, - 0x57, 0x3, 0x40, 0x44, 0x0, 0x3, 0x65, 0x55, - 0xd5, 0x55, 0x54, 0x0, 0x0, 0x45, 0x55, 0xd5, - 0x56, 0xa1, 0x0, 0x0, 0x10, 0x0, 0xc0, 0x0, - 0x0, 0x0, 0x25, 0x55, 0x55, 0xd5, 0x55, 0x5b, - 0x70, 0x1, 0x0, 0x0, 0xa2, 0x0, 0x0, 0x0, - 0x4, 0x55, 0x55, 0xe5, 0x55, 0x98, 0x0, 0x1, - 0x0, 0x6, 0x76, 0x0, 0x0, 0x0, 0x0, 0x0, - 0xc, 0x2, 0x80, 0x0, 0x0, 0x0, 0x1, 0xa3, - 0x0, 0x3c, 0x61, 0x0, 0x2, 0x67, 0x10, 0x0, - 0x1, 0x9f, 0x90, 0x11, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, - - /* U+7FA9 "義" */ - 0x0, 0x0, 0x40, 0x0, 0x32, 0x0, 0x0, 0x0, - 0x0, 0x58, 0x0, 0xa3, 0x12, 0x0, 0x2, 0x65, - 0x57, 0x95, 0x75, 0x88, 0x0, 0x0, 0x25, 0x55, - 0xc5, 0x55, 0xb0, 0x0, 0x0, 0x1, 0x0, 0xb0, - 0x0, 0x5, 0x0, 0x5, 0x55, 0x55, 0x85, 0x55, - 0x59, 0x30, 0x0, 0x0, 0x38, 0xb5, 0x82, 0x81, - 0x0, 0x1, 0x45, 0xc3, 0x13, 0x90, 0x57, 0x0, - 0x16, 0x55, 0xc5, 0x55, 0xc5, 0x59, 0x80, 0x0, - 0x0, 0xa3, 0x30, 0xb0, 0x68, 0x0, 0xb, 0xa7, - 0xc0, 0x0, 0x6b, 0x90, 0x20, 0x0, 0x0, 0xa0, - 0x3, 0xac, 0x50, 0x60, 0x0, 0x29, 0xd2, 0x53, - 0x0, 0x7c, 0xd0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, - - /* U+7FD2 "習" */ - 0x0, 0x0, 0x20, 0x0, 0x0, 0x20, 0x26, 0x55, - 0xd2, 0x55, 0x57, 0xc0, 0x6, 0x70, 0xc0, 0x39, - 0x12, 0x90, 0x0, 0xb0, 0xc0, 0x6, 0x32, 0x90, - 0x0, 0x46, 0xd0, 0x3, 0x77, 0x90, 0x5b, 0x40, - 0xc2, 0x99, 0x12, 0x70, 0x21, 0x0, 0xc, 0x30, - 0x0, 0x0, 0x0, 0x85, 0x78, 0x55, 0x5a, 0x20, - 0x0, 0xc0, 0x0, 0x0, 0xc, 0x0, 0x0, 0xc0, - 0x0, 0x0, 0xc, 0x0, 0x0, 0xd5, 0x55, 0x55, - 0x5d, 0x0, 0x0, 0xc0, 0x0, 0x0, 0xc, 0x0, - 0x0, 0xd5, 0x55, 0x55, 0x5d, 0x0, 0x0, 0x10, - 0x0, 0x0, 0x1, 0x0, - - /* U+8001 "老" */ - 0x0, 0x0, 0x0, 0x30, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, 0xb4, 0x0, 0x14, 0x0, 0x0, 0x0, - 0x0, 0xb2, 0x5, 0x8c, 0x0, 0x0, 0x16, 0x55, - 0xc6, 0x58, 0xd1, 0x0, 0x0, 0x0, 0x0, 0xb2, - 0xc, 0x30, 0x0, 0x5, 0x55, 0x55, 0xb6, 0xaa, - 0x55, 0xc2, 0x0, 0x0, 0x0, 0x9, 0x70, 0x0, - 0x0, 0x0, 0x0, 0x4, 0xb4, 0x1, 0x40, 0x0, - 0x0, 0x0, 0x7e, 0x10, 0x3d, 0x90, 0x0, 0x0, - 0x49, 0x5c, 0x28, 0x71, 0x1, 0x0, 0x5, 0x30, - 0x1d, 0x40, 0x0, 0x5, 0x0, 0x0, 0x0, 0x1c, - 0x0, 0x0, 0xa, 0x0, 0x0, 0x0, 0xc, 0xcb, - 0xbb, 0xbe, 0x40, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, - - /* U+8003 "考" */ - 0x0, 0x0, 0x0, 0x10, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, 0xe0, 0x0, 0x71, 0x0, 0x0, 0x0, - 0x0, 0xc0, 0x55, 0xc1, 0x0, 0x0, 0x16, 0x55, - 0xd5, 0x8c, 0x0, 0x0, 0x0, 0x0, 0x0, 0xc2, - 0xb0, 0x0, 0x60, 0x16, 0x55, 0x55, 0x8c, 0x55, - 0x55, 0x51, 0x0, 0x0, 0x4, 0xa0, 0x0, 0x15, - 0x0, 0x0, 0x0, 0x76, 0x99, 0x55, 0x56, 0x0, - 0x0, 0x48, 0x10, 0xa2, 0x0, 0x20, 0x0, 0x4, - 0x10, 0x0, 0x95, 0x55, 0xa6, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x0, 0xb1, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, 0xc0, 0x0, 0x0, 0x0, 0x0, 0x16, - 0xab, 0x70, 0x0, 0x0, 0x0, 0x0, 0x0, 0x43, - 0x0, 0x0, - - /* U+8005 "者" */ - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x1, 0xd0, 0x0, 0x31, 0x0, 0x0, 0x0, - 0x0, 0xc1, 0x71, 0xd4, 0x0, 0x0, 0x36, 0x55, - 0xd5, 0x5d, 0x40, 0x0, 0x0, 0x0, 0x0, 0xc0, - 0xa5, 0x0, 0x50, 0x7, 0x55, 0x55, 0x7c, 0x75, - 0x56, 0x72, 0x0, 0x0, 0x1, 0xa3, 0x0, 0x0, - 0x0, 0x0, 0x0, 0xbb, 0x65, 0x56, 0xd0, 0x0, - 0x0, 0x18, 0xe0, 0x0, 0x1, 0xa0, 0x0, 0x4, - 0x50, 0xc5, 0x55, 0x56, 0xa0, 0x0, 0x0, 0x0, - 0xc0, 0x0, 0x1, 0xa0, 0x0, 0x0, 0x0, 0xc0, - 0x0, 0x1, 0xa0, 0x0, 0x0, 0x0, 0xc5, 0x55, - 0x56, 0xb0, 0x0, 0x0, 0x0, 0x30, 0x0, 0x0, - 0x10, 0x0, - - /* U+800C "而" */ - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x15, - 0x55, 0x55, 0x55, 0x55, 0x58, 0xb0, 0x1, 0x0, - 0x0, 0xb4, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x90, 0x0, 0x0, 0x0, 0x0, 0x75, 0x57, 0x75, - 0x55, 0x5a, 0x10, 0x0, 0xc0, 0xb, 0x0, 0xb0, - 0xd, 0x0, 0x0, 0xc0, 0xb, 0x0, 0xb0, 0xc, - 0x0, 0x0, 0xc0, 0xb, 0x0, 0xb0, 0xc, 0x0, - 0x0, 0xc0, 0xb, 0x0, 0xb0, 0xc, 0x0, 0x0, - 0xc0, 0xb, 0x0, 0xb0, 0xc, 0x0, 0x0, 0xc0, - 0xb, 0x0, 0xb0, 0xc, 0x0, 0x0, 0xc0, 0xb, - 0x0, 0xb1, 0x1c, 0x0, 0x0, 0x90, 0x3, 0x0, - 0x24, 0xd8, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, - - /* U+8033 "耳" */ - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x6, - 0x57, 0x55, 0x55, 0x57, 0x58, 0x80, 0x0, 0xa, - 0x20, 0x0, 0xc, 0x0, 0x0, 0x0, 0xa, 0x20, - 0x0, 0xc, 0x0, 0x0, 0x0, 0xa, 0x65, 0x55, - 0x5c, 0x0, 0x0, 0x0, 0xa, 0x20, 0x0, 0xc, - 0x0, 0x0, 0x0, 0xa, 0x20, 0x0, 0xc, 0x0, - 0x0, 0x0, 0xa, 0x65, 0x55, 0x5c, 0x0, 0x0, - 0x0, 0xa, 0x20, 0x0, 0xc, 0x0, 0x20, 0x0, - 0xa, 0x32, 0x34, 0x5d, 0x56, 0x91, 0x26, 0x55, - 0x42, 0x10, 0xc, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0xc, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x1d, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x2, - 0x0, 0x0, - - /* U+805E "聞" */ - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xa5, 0x55, - 0xd0, 0x95, 0x55, 0xc3, 0xb0, 0x0, 0xb0, 0xa0, - 0x0, 0xa0, 0xb5, 0x55, 0xb0, 0xa5, 0x55, 0xc0, - 0xb5, 0x55, 0xa0, 0xa5, 0x55, 0xc0, 0xb0, 0x0, - 0x0, 0x0, 0x40, 0xa0, 0xb0, 0x6a, 0x65, 0x69, - 0x72, 0xa0, 0xb0, 0xa, 0x65, 0x78, 0x0, 0xa0, - 0xb0, 0xa, 0x10, 0x28, 0x0, 0xa0, 0xb0, 0xa, - 0x65, 0x78, 0x0, 0xa0, 0xb0, 0xa, 0x32, 0x5a, - 0x79, 0xa0, 0xb3, 0x54, 0x32, 0x38, 0x0, 0xb0, - 0xb0, 0x0, 0x0, 0x25, 0x3a, 0xe0, 0x0, 0x0, - 0x0, 0x0, 0x0, 0x10, - - /* U+806F "聯" */ - 0x0, 0x0, 0x0, 0x2, 0x20, 0x3, 0x0, 0x5, - 0x55, 0x5c, 0x59, 0x30, 0x59, 0x0, 0x1, 0xb0, - 0x91, 0x54, 0x63, 0x80, 0x82, 0x0, 0xb0, 0x93, - 0xd7, 0x86, 0x87, 0x80, 0x0, 0xc5, 0xb1, 0x18, - 0x31, 0x36, 0x30, 0x0, 0xb0, 0x92, 0x93, 0x83, - 0x84, 0x94, 0x0, 0xb0, 0x93, 0xb5, 0x53, 0x83, - 0x23, 0x0, 0xc5, 0xb1, 0x1, 0x44, 0xa1, 0x10, - 0x0, 0xb0, 0x91, 0x1a, 0x44, 0xa0, 0xa0, 0x1, - 0xc6, 0xc5, 0x29, 0x64, 0xa0, 0xa0, 0xd, 0x71, - 0x91, 0x2a, 0x83, 0xa5, 0xb0, 0x0, 0x0, 0xa1, - 0x0, 0xa0, 0xa0, 0x0, 0x0, 0x0, 0xa2, 0x38, - 0x20, 0xb0, 0x0, 0x0, 0x0, 0x11, 0x10, 0x0, - 0x20, 0x0, - - /* U+8072 "聲" */ - 0x0, 0x0, 0x50, 0x0, 0x10, 0x10, 0x0, 0x4, - 0x55, 0xc5, 0xa2, 0xb5, 0xc1, 0x0, 0x1, 0x0, - 0xa0, 0x31, 0x80, 0xa4, 0x50, 0x2, 0x85, 0x55, - 0x57, 0x10, 0x28, 0x60, 0x0, 0xb5, 0xa6, 0xb2, - 0x95, 0xa8, 0x0, 0x1, 0xb5, 0xc6, 0x90, 0x1b, - 0x70, 0x0, 0x3, 0x60, 0x0, 0x2, 0x85, 0x98, - 0x50, 0x6, 0x35, 0x55, 0x68, 0x55, 0x89, 0x40, - 0x2, 0x1, 0xb1, 0x11, 0x17, 0x30, 0x0, 0x0, - 0x0, 0xb4, 0x44, 0x49, 0x30, 0x0, 0x0, 0x0, - 0xb5, 0x55, 0x5a, 0x30, 0x20, 0x2, 0x44, 0xc5, - 0x55, 0x5a, 0x76, 0x80, 0x1, 0x10, 0x0, 0x0, - 0x7, 0x30, 0x0, 0x0, 0x0, 0x0, 0x0, 0x2, - 0x0, 0x0, - - /* U+8077 "職" */ - 0x0, 0x0, 0x0, 0x1, 0x0, 0x10, 0x0, 0x5, - 0x55, 0x5a, 0x3b, 0x10, 0xc0, 0x0, 0x0, 0xa0, - 0xa2, 0x68, 0x67, 0xb5, 0x30, 0x0, 0xa0, 0xa0, - 0x50, 0x55, 0xa0, 0xc0, 0x0, 0xc5, 0xc0, 0x73, - 0x70, 0xa0, 0x0, 0x0, 0xa0, 0xa4, 0x75, 0x85, - 0xc5, 0xb1, 0x0, 0xa0, 0xa0, 0x31, 0x40, 0xa1, - 0x90, 0x0, 0xc5, 0xc0, 0xb4, 0xa3, 0x94, 0x70, - 0x0, 0xa0, 0xa0, 0xa0, 0x81, 0x7b, 0x10, 0x0, - 0xb3, 0xc4, 0xb5, 0xb1, 0x4b, 0x0, 0xc, 0xa4, - 0xa0, 0xa0, 0x81, 0x8a, 0x3, 0x0, 0x0, 0xa0, - 0xa5, 0x84, 0x67, 0xa2, 0x0, 0x0, 0xb0, 0x0, - 0x26, 0x0, 0xc2, 0x0, 0x0, 0x10, 0x0, 0x10, - 0x0, 0x0, - - /* U+807D "聽" */ - 0x0, 0x0, 0x0, 0x0, 0x3, 0x0, 0x0, 0x5, - 0x55, 0x57, 0x80, 0xa, 0x10, 0x30, 0x0, 0xa0, - 0xa, 0x46, 0x5a, 0x55, 0x71, 0x0, 0xc5, 0x5a, - 0x15, 0x36, 0x33, 0x60, 0x0, 0xc5, 0x5a, 0x1a, - 0x56, 0xb2, 0xb0, 0x0, 0xa0, 0xa, 0x1a, 0x44, - 0xa0, 0xa0, 0x6, 0x75, 0x5a, 0x1b, 0x77, 0xb4, - 0xa0, 0x5, 0x67, 0x5a, 0x15, 0x11, 0x11, 0x50, - 0x0, 0x83, 0xa, 0x36, 0x55, 0x55, 0x92, 0x5, - 0xa9, 0x3a, 0x1, 0x47, 0x11, 0x0, 0x0, 0x82, - 0xa, 0x34, 0xa2, 0x82, 0xa1, 0x6, 0xa6, 0x2a, - 0xd1, 0xa0, 0x4, 0x63, 0x4, 0x0, 0xb, 0x10, - 0xc9, 0x9c, 0x40, 0x0, 0x0, 0x3, 0x0, 0x0, - 0x0, 0x0, - - /* U+8089 "肉" */ - 0x0, 0x0, 0x31, 0x0, 0x0, 0x0, 0x0, 0x8, - 0x60, 0x0, 0x0, 0x95, 0x55, 0xa8, 0x55, 0x5a, - 0x2d, 0x0, 0xc, 0x10, 0x0, 0xc1, 0xd0, 0x2, - 0xb8, 0x50, 0xc, 0x1d, 0x1, 0x92, 0x9, 0xc0, - 0xc1, 0xd2, 0x60, 0x97, 0x9, 0xc, 0x1d, 0x10, - 0xe, 0x20, 0x0, 0xc1, 0xd0, 0x7, 0x57, 0x81, - 0xc, 0x1d, 0x4, 0x60, 0x6, 0xd0, 0xc1, 0xd3, - 0x30, 0x0, 0x7, 0xc, 0x1d, 0x0, 0x0, 0x0, - 0x56, 0xe0, 0xc0, 0x0, 0x0, 0x0, 0xa9, 0x0, - 0x0, 0x0, 0x0, 0x0, 0x0, - - /* U+80A9 "肩" */ - 0x0, 0x0, 0x0, 0x30, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x2, 0xc0, 0x0, 0x0, 0x0, 0x49, 0x55, - 0x57, 0x55, 0x5c, 0x30, 0x3, 0x90, 0x0, 0x0, - 0x0, 0xb1, 0x0, 0x3b, 0x55, 0x55, 0x55, 0x5c, - 0x10, 0x3, 0x90, 0x10, 0x0, 0x0, 0x20, 0x0, - 0x48, 0xd, 0x55, 0x55, 0x6c, 0x0, 0x4, 0x70, - 0xc0, 0x0, 0x2, 0xa0, 0x0, 0x75, 0xd, 0x55, - 0x55, 0x6a, 0x0, 0xa, 0x10, 0xd5, 0x55, 0x56, - 0xa0, 0x0, 0x90, 0xc, 0x0, 0x0, 0x2a, 0x0, - 0x62, 0x0, 0xc0, 0x0, 0x2, 0x90, 0x23, 0x0, - 0xc, 0x0, 0x6, 0xf6, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x1, 0x0, - - /* U+80AF "肯" */ - 0x0, 0x0, 0x0, 0x5, 0x0, 0x0, 0x0, 0x0, - 0x5, 0x70, 0xe, 0x0, 0x1, 0x0, 0x0, 0x6, - 0x70, 0xd, 0x55, 0x6a, 0x0, 0x0, 0x6, 0x70, - 0xd, 0x0, 0x0, 0x20, 0x17, 0x57, 0x75, 0x5a, - 0x55, 0x57, 0xa0, 0x0, 0x2, 0x0, 0x0, 0x0, - 0x40, 0x0, 0x0, 0xd, 0x55, 0x55, 0x55, 0xe1, - 0x0, 0x0, 0xd, 0x0, 0x0, 0x0, 0xd0, 0x0, - 0x0, 0xd, 0x55, 0x55, 0x55, 0xd0, 0x0, 0x0, - 0xd, 0x55, 0x55, 0x55, 0xd0, 0x0, 0x0, 0xd, - 0x0, 0x0, 0x0, 0xd0, 0x0, 0x0, 0xd, 0x0, - 0x0, 0x0, 0xc0, 0x0, 0x0, 0xe, 0x0, 0x1, - 0x6d, 0xa0, 0x0, 0x0, 0x1, 0x0, 0x0, 0x2, - 0x0, 0x0, - - /* U+80B2 "育" */ - 0x0, 0x0, 0x1, 0x10, 0x0, 0x0, 0x0, 0x0, - 0x0, 0xb, 0x10, 0x0, 0x20, 0x6, 0x55, 0x58, - 0x85, 0x55, 0x6a, 0x10, 0x0, 0x6, 0x92, 0x4, - 0x10, 0x0, 0x0, 0x39, 0x53, 0x33, 0x4c, 0xa0, - 0x0, 0x2, 0xa7, 0x53, 0x20, 0xa, 0x10, 0x0, - 0x9, 0x55, 0x55, 0x5b, 0x30, 0x0, 0x0, 0xa1, - 0x0, 0x0, 0xa2, 0x0, 0x0, 0xa, 0x65, 0x55, - 0x5c, 0x20, 0x0, 0x0, 0xa1, 0x0, 0x0, 0xa2, - 0x0, 0x0, 0xa, 0x65, 0x55, 0x5c, 0x20, 0x0, - 0x0, 0xa1, 0x0, 0x0, 0xa1, 0x0, 0x0, 0xb, - 0x10, 0x3, 0x9e, 0x0, 0x0, 0x0, 0x20, 0x0, - 0x0, 0x10, 0x0, - - /* U+80CC "背" */ - 0x0, 0x0, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x2, 0xd0, 0x2c, 0x0, 0x60, 0x6, 0x55, 0x6c, - 0x2, 0xb5, 0x98, 0x10, 0x0, 0x4, 0xc0, 0x2c, - 0x0, 0x4, 0x3b, 0x96, 0x4c, 0x1, 0xe6, 0x68, - 0xb0, 0x20, 0x2, 0x80, 0x4, 0x66, 0x52, 0x0, - 0xb, 0x55, 0x55, 0x55, 0xe1, 0x0, 0x0, 0xd0, - 0x0, 0x0, 0xc, 0x0, 0x0, 0xd, 0x55, 0x55, - 0x55, 0xc0, 0x0, 0x0, 0xd0, 0x0, 0x0, 0xc, - 0x0, 0x0, 0xd, 0x55, 0x55, 0x55, 0xc0, 0x0, - 0x0, 0xd0, 0x0, 0x0, 0xc, 0x0, 0x0, 0xd, - 0x0, 0x1, 0x6c, 0xa0, 0x0, 0x0, 0x50, 0x0, - 0x0, 0x41, 0x0, - - /* U+80F8 "胸" */ - 0x0, 0x0, 0x0, 0x2, 0x0, 0x0, 0x0, 0x65, - 0x5a, 0x14, 0x90, 0x0, 0x0, 0x9, 0x20, 0xb0, - 0x92, 0x0, 0x3, 0x10, 0x92, 0xb, 0xa, 0x57, - 0x65, 0xa3, 0x9, 0x65, 0xc4, 0x12, 0x79, 0x8, - 0x20, 0x92, 0xb, 0x2, 0x6a, 0x11, 0x82, 0x9, - 0x20, 0xb0, 0xb3, 0x90, 0xb8, 0x20, 0x96, 0x5c, - 0xa, 0x4b, 0xa, 0x81, 0xa, 0x10, 0xb0, 0xa7, - 0x82, 0xa9, 0x10, 0xb0, 0xb, 0xc, 0x23, 0x2a, - 0x91, 0xa, 0x0, 0xb0, 0xa5, 0x55, 0xaa, 0x1, - 0x62, 0x3c, 0x0, 0x0, 0x33, 0xc0, 0x40, 0x9, - 0x70, 0x0, 0x1, 0x89, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x0, - - /* U+80FD "能" */ - 0x0, 0x6, 0x0, 0x2, 0x0, 0x0, 0x0, 0x7, - 0x80, 0x0, 0xb2, 0x3, 0x0, 0x4, 0x60, 0x26, - 0xb, 0x7, 0xb1, 0x5, 0xa5, 0x55, 0xa5, 0xb6, - 0x20, 0x20, 0x35, 0x20, 0x2, 0x2b, 0x0, 0x6, - 0x0, 0xa5, 0x55, 0xb0, 0x8a, 0x99, 0xd1, 0xc, - 0x0, 0x1a, 0x0, 0x0, 0x0, 0x0, 0xd5, 0x55, - 0xa0, 0xb1, 0x5, 0x0, 0xc, 0x0, 0x1a, 0xb, - 0x7, 0xb2, 0x0, 0xd5, 0x55, 0xa0, 0xc8, 0x40, - 0x0, 0xc, 0x0, 0x1a, 0xb, 0x0, 0x4, 0x0, - 0xc0, 0x1, 0xa0, 0xb0, 0x0, 0x80, 0xc, 0x5, - 0xc8, 0xa, 0xba, 0xad, 0x30, 0x20, 0x3, 0x0, - 0x0, 0x0, 0x0, - - /* U+8131 "脱" */ - 0x0, 0x0, 0x0, 0x0, 0x0, 0x10, 0x0, 0x0, - 0xa5, 0xa3, 0x8, 0x0, 0xe1, 0x0, 0x0, 0xb0, - 0x92, 0x9, 0x44, 0x70, 0x0, 0x0, 0xb0, 0x92, - 0x23, 0x17, 0x4, 0x0, 0x0, 0xc5, 0xb2, 0xb5, - 0x55, 0x5c, 0x0, 0x0, 0xb0, 0x92, 0xa0, 0x0, - 0x1b, 0x0, 0x0, 0xb0, 0x92, 0xa0, 0x0, 0x1b, - 0x0, 0x0, 0xc5, 0xb2, 0xb8, 0x9b, 0x6b, 0x0, - 0x0, 0xa0, 0x92, 0x24, 0x6a, 0x0, 0x0, 0x1, - 0x90, 0x92, 0x5, 0x5a, 0x0, 0x0, 0x4, 0x50, - 0x92, 0x8, 0x2a, 0x0, 0x40, 0x7, 0x11, 0xa1, - 0x1a, 0xa, 0x10, 0x70, 0x6, 0x5, 0xd2, 0x70, - 0x7, 0xb9, 0xc2, 0x10, 0x0, 0x2, 0x0, 0x0, - 0x0, 0x0, - - /* U+814A "腊" */ - 0x0, 0x0, 0x0, 0x2, 0x0, 0x20, 0x0, 0x0, - 0x95, 0xa3, 0x7, 0x80, 0xc1, 0x0, 0x0, 0xb0, - 0xa1, 0x7, 0x50, 0xb2, 0x30, 0x0, 0xb0, 0xa1, - 0x6a, 0x85, 0xc5, 0x40, 0x0, 0xc5, 0xc1, 0x7, - 0x50, 0xb0, 0x0, 0x0, 0xb0, 0xa3, 0x5a, 0x85, - 0xc5, 0xc2, 0x0, 0xb0, 0xa1, 0x10, 0x0, 0x0, - 0x0, 0x0, 0xc5, 0xc1, 0x65, 0x55, 0x59, 0x20, - 0x0, 0xb0, 0xa1, 0x92, 0x0, 0xa, 0x10, 0x1, - 0x90, 0xa1, 0x96, 0x55, 0x5c, 0x10, 0x3, 0x60, - 0xa1, 0x92, 0x0, 0xa, 0x10, 0x7, 0x11, 0xb0, - 0x96, 0x55, 0x5c, 0x10, 0x5, 0x6, 0xd0, 0x91, - 0x0, 0x9, 0x10, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, - - /* U+8155 "腕" */ - 0x0, 0x0, 0x0, 0x0, 0x10, 0x0, 0x0, 0x1, - 0x42, 0x61, 0x0, 0x38, 0x0, 0x0, 0x1, 0xb3, - 0xc0, 0x75, 0x5c, 0x55, 0x80, 0x1, 0xa0, 0xb2, - 0x95, 0x0, 0x3, 0x50, 0x1, 0xb5, 0xc2, 0x3a, - 0x0, 0x2, 0x0, 0x1, 0xa0, 0xb0, 0x68, 0x8b, - 0x5b, 0x20, 0x1, 0xa0, 0xb0, 0x90, 0xba, 0xa, - 0x0, 0x1, 0xb5, 0xc2, 0xa1, 0xaa, 0xa, 0x0, - 0x2, 0x90, 0xb4, 0x49, 0x6a, 0xa, 0x0, 0x3, - 0x70, 0xb0, 0xa, 0x1a, 0x3d, 0x0, 0x5, 0x40, - 0xb0, 0x18, 0xa, 0x3, 0x40, 0x8, 0x0, 0xb0, - 0x80, 0xa, 0x0, 0x70, 0x6, 0x18, 0xc5, 0x10, - 0x7, 0xa9, 0xc2, 0x10, 0x0, 0x10, 0x0, 0x0, - 0x0, 0x0, - - /* U+8166 "腦" */ - 0x0, 0x0, 0x0, 0x1, 0x0, 0x0, 0x0, 0x0, - 0xa5, 0xa3, 0x3d, 0xa, 0x50, 0xd1, 0x0, 0xb0, - 0xa1, 0x82, 0x19, 0x6, 0x60, 0x0, 0xb0, 0xa2, - 0x60, 0x70, 0x27, 0x0, 0x0, 0xc5, 0xc1, 0x91, - 0x47, 0x19, 0x30, 0x0, 0xb0, 0xa1, 0x3b, 0x48, - 0x61, 0xe0, 0x0, 0xb0, 0xa1, 0x4, 0xa1, 0x10, - 0x30, 0x0, 0xc5, 0xc1, 0xb5, 0x65, 0x55, 0xd0, - 0x0, 0xb0, 0xa1, 0xb2, 0x0, 0xd2, 0xb0, 0x0, - 0x90, 0xa1, 0xb0, 0x7b, 0x50, 0xb0, 0x3, 0x60, - 0xa1, 0xb0, 0x5b, 0x70, 0xb0, 0x6, 0x10, 0xa0, - 0xb3, 0x50, 0xb1, 0xb0, 0x6, 0x29, 0xd0, 0xb6, - 0x55, 0x55, 0xb0, 0x11, 0x0, 0x20, 0x50, 0x0, - 0x0, 0x50, - - /* U+8170 "腰" */ - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8, - 0x65, 0xc4, 0x55, 0x55, 0x58, 0x70, 0x9, 0x20, - 0xb1, 0xa, 0xa, 0x0, 0x0, 0x9, 0x20, 0xb5, - 0x6c, 0x5c, 0x5a, 0x10, 0x9, 0x65, 0xb7, 0x3a, - 0xa, 0xb, 0x0, 0x9, 0x20, 0xb7, 0x3a, 0xa, - 0xb, 0x0, 0x9, 0x20, 0xb7, 0x79, 0x57, 0x5c, - 0x0, 0x9, 0x65, 0xb1, 0x9, 0x50, 0x0, 0x0, - 0x9, 0x10, 0xb6, 0x5d, 0x55, 0x77, 0x90, 0xa, - 0x0, 0xb0, 0x64, 0x5, 0x60, 0x0, 0x9, 0x0, - 0xb0, 0xb4, 0x1b, 0x0, 0x0, 0x17, 0x11, 0xb0, - 0x2, 0xda, 0x61, 0x0, 0x50, 0x2c, 0x71, 0x58, - 0x20, 0x5d, 0x0, 0x0, 0x0, 0x13, 0x0, 0x0, - 0x1, 0x0, - - /* U+819D "膝" */ - 0x0, 0x0, 0x0, 0x0, 0x20, 0x0, 0x0, 0x4, - 0x37, 0x30, 0x0, 0xb1, 0x4, 0x0, 0xa, 0x2a, - 0x25, 0x59, 0xf5, 0x57, 0x20, 0xa, 0xa, 0x10, - 0x2a, 0xb6, 0x82, 0x0, 0xa, 0x5c, 0x12, 0x80, - 0x70, 0x2e, 0x20, 0xa, 0xa, 0x33, 0x6, 0xc2, - 0x3, 0x10, 0xa, 0xa, 0x10, 0x3a, 0x6, 0x60, - 0x0, 0xa, 0x5c, 0x14, 0x70, 0xb1, 0x6d, 0x80, - 0xa, 0xa, 0x33, 0x55, 0xb2, 0xb2, 0x20, 0xa, - 0xa, 0x10, 0x8, 0xd4, 0x0, 0x0, 0x9, 0xa, - 0x10, 0x66, 0xb5, 0x93, 0x0, 0x25, 0x1b, 0x1c, - 0x50, 0xb0, 0x1d, 0x20, 0x50, 0x5b, 0x0, 0x18, - 0xe0, 0x1, 0x10, 0x0, 0x0, 0x0, 0x0, 0x10, - 0x0, 0x0, - - /* U+81C9 "臉" */ - 0x0, 0x0, 0x0, 0x0, 0x12, 0x0, 0x0, 0x1, - 0x85, 0xa1, 0x0, 0x8a, 0x0, 0x0, 0x1, 0x90, - 0xa0, 0x2, 0x91, 0x50, 0x0, 0x1, 0x90, 0xa0, - 0x9, 0x0, 0x57, 0x0, 0x1, 0xb5, 0xb0, 0x65, - 0x55, 0x96, 0xc3, 0x1, 0x90, 0xa2, 0x20, 0x21, - 0x10, 0x40, 0x1, 0x90, 0xa0, 0xb5, 0xb3, 0xa5, - 0xb0, 0x1, 0xb5, 0xb0, 0x90, 0x92, 0x70, 0x90, - 0x1, 0x80, 0xa0, 0xb5, 0xa3, 0x95, 0x90, 0x3, - 0x60, 0xa0, 0x1b, 0x0, 0x38, 0x0, 0x5, 0x30, - 0xa0, 0x49, 0x0, 0x74, 0x0, 0x7, 0x12, 0xa0, - 0x82, 0xb0, 0x96, 0x80, 0x4, 0x9, 0x63, 0x30, - 0x36, 0x10, 0x74, 0x0, 0x0, 0x1, 0x0, 0x0, - 0x0, 0x0, - - /* U+81EA "自" */ - 0x0, 0x3, 0x0, 0x0, 0x0, 0x0, 0xe2, 0x0, - 0x0, 0x10, 0x44, 0x0, 0x3, 0xd, 0x56, 0x55, - 0x55, 0xd4, 0xd0, 0x0, 0x0, 0xc, 0xd, 0x0, - 0x0, 0x0, 0xc0, 0xd5, 0x55, 0x55, 0x5d, 0xd, - 0x0, 0x0, 0x0, 0xc0, 0xd0, 0x0, 0x0, 0xc, - 0xd, 0x55, 0x55, 0x55, 0xd0, 0xd0, 0x0, 0x0, - 0xc, 0xd, 0x0, 0x0, 0x0, 0xc0, 0xe5, 0x55, - 0x55, 0x5d, 0x14, 0x0, 0x0, 0x0, 0x40, - - /* U+81F3 "至" */ - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x4, - 0x55, 0x55, 0x55, 0x55, 0x6d, 0x20, 0x1, 0x0, - 0xa, 0x60, 0x0, 0x0, 0x0, 0x0, 0x0, 0x58, - 0x1, 0x50, 0x0, 0x0, 0x0, 0x4, 0x80, 0x0, - 0x2c, 0x50, 0x0, 0x0, 0x89, 0x45, 0x66, 0x67, - 0xe5, 0x0, 0x0, 0x98, 0x53, 0xb2, 0x0, 0x34, - 0x0, 0x0, 0x0, 0x0, 0xa2, 0x0, 0x0, 0x0, - 0x0, 0x55, 0x55, 0xc7, 0x55, 0xd5, 0x0, 0x0, - 0x10, 0x0, 0xa2, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0xa2, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0xa2, 0x0, 0x7, 0x50, 0x26, 0x55, 0x55, 0x55, - 0x55, 0x55, 0x40, - - /* U+81FA "臺" */ - 0x0, 0x0, 0x0, 0x13, 0x0, 0x0, 0x10, 0x6, - 0x55, 0x55, 0x6c, 0x55, 0x58, 0xa0, 0x0, 0x24, - 0x44, 0x6b, 0x44, 0x94, 0x0, 0x0, 0x8, 0x55, - 0x55, 0x55, 0xa1, 0x0, 0x0, 0xc, 0x0, 0x0, - 0x0, 0xc0, 0x0, 0x1, 0xb, 0x55, 0x55, 0x55, - 0x90, 0x0, 0x8, 0x55, 0x55, 0x55, 0x55, 0x56, - 0xd1, 0x4b, 0x35, 0x55, 0x65, 0x56, 0xb5, 0x20, - 0x0, 0x0, 0x48, 0x30, 0x6, 0x30, 0x0, 0x0, - 0x1d, 0xc8, 0x88, 0x55, 0xc5, 0x0, 0x0, 0x3, - 0x0, 0x38, 0x0, 0x82, 0x0, 0x0, 0x36, 0x55, - 0x7b, 0x55, 0x52, 0x0, 0x4, 0x55, 0x55, 0x7b, - 0x55, 0x5c, 0x70, 0x1, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, - - /* U+8207 "與" */ - 0x0, 0x0, 0x2, 0x10, 0x0, 0x0, 0x0, 0x0, - 0x24, 0xa7, 0x70, 0x1, 0x16, 0x0, 0x0, 0xd2, - 0x6, 0x85, 0xa6, 0x4d, 0x20, 0x0, 0xc0, 0x26, - 0x50, 0x0, 0xc, 0x0, 0x0, 0xc5, 0x59, 0x85, - 0xb3, 0x6c, 0x0, 0x0, 0xb0, 0x3, 0x0, 0xb0, - 0xb, 0x0, 0x0, 0xc5, 0x99, 0x40, 0xb2, 0x5c, - 0x0, 0x0, 0xc0, 0x9, 0x20, 0xb0, 0x1b, 0x0, - 0x0, 0xc0, 0x9, 0x20, 0xb0, 0xb, 0x50, 0x8, - 0x65, 0x66, 0x55, 0x65, 0x56, 0x61, 0x0, 0x1, - 0xd5, 0x0, 0x17, 0x50, 0x0, 0x0, 0x1b, 0x40, - 0x0, 0x0, 0x5d, 0x40, 0x4, 0x81, 0x0, 0x0, - 0x0, 0x4, 0xb0, 0x1, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, - - /* U+8208 "興" */ - 0x0, 0x38, 0x68, 0x55, 0x85, 0x15, 0x0, 0x0, - 0xc1, 0x19, 0x2, 0x65, 0x5c, 0x10, 0x0, 0xb2, - 0x1a, 0x66, 0x84, 0xb, 0x0, 0x0, 0xb5, 0x39, - 0x67, 0x75, 0x5c, 0x0, 0x0, 0xa0, 0x19, 0x89, - 0x64, 0xb, 0x0, 0x0, 0xb8, 0x49, 0x89, 0x65, - 0x4b, 0x0, 0x0, 0xb1, 0x19, 0x89, 0x64, 0x2b, - 0x0, 0x0, 0xb0, 0x19, 0x0, 0x64, 0x1b, 0x50, - 0x6, 0x65, 0x57, 0x55, 0x65, 0x56, 0x61, 0x0, - 0x0, 0x9a, 0x0, 0x18, 0x60, 0x0, 0x0, 0x9, - 0x70, 0x0, 0x0, 0x7e, 0x50, 0x3, 0x71, 0x0, - 0x0, 0x0, 0x5, 0x90, 0x1, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x0, - - /* U+8209 "舉" */ - 0x0, 0x0, 0x31, 0x30, 0x0, 0x0, 0x0, 0x0, - 0xa7, 0x85, 0xd5, 0x95, 0x6c, 0x20, 0x0, 0xb0, - 0x31, 0xa0, 0x0, 0xb, 0x0, 0x0, 0xb5, 0x65, - 0xb5, 0xa5, 0x6b, 0x0, 0x0, 0xa0, 0x61, 0x50, - 0xc0, 0xa, 0x0, 0x0, 0xa6, 0x53, 0xb0, 0xc4, - 0x6b, 0x0, 0x5, 0xb6, 0x56, 0xb5, 0xd5, 0x5d, - 0xb1, 0x1, 0x0, 0xc4, 0x25, 0x5, 0x0, 0x0, - 0x0, 0xa, 0x50, 0x37, 0x24, 0x80, 0x0, 0x1, - 0x93, 0x46, 0x79, 0x54, 0x2b, 0x50, 0x15, 0x25, - 0x55, 0x79, 0x55, 0xb6, 0x70, 0x0, 0x1, 0x0, - 0x37, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x37, - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x10, 0x0, - 0x0, 0x0, - - /* U+822A "航" */ - 0x0, 0x3, 0x20, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x9, 0x30, 0x0, 0x45, 0x0, 0x0, 0x0, 0x99, - 0x5a, 0x0, 0xb, 0x1, 0x0, 0x0, 0xb0, 0xb, - 0x45, 0x55, 0x59, 0x50, 0x0, 0xb6, 0x2b, 0x0, - 0x0, 0x0, 0x0, 0x0, 0xb2, 0x6b, 0x9, 0x55, - 0xb2, 0x0, 0x15, 0xc5, 0x5c, 0xa, 0x10, 0xb0, - 0x0, 0x1, 0xa1, 0xb, 0xa, 0x10, 0xb0, 0x0, - 0x0, 0xa6, 0x4b, 0xa, 0x0, 0xb0, 0x0, 0x1, - 0x81, 0x7b, 0xa, 0x0, 0xb0, 0x0, 0x4, 0x40, - 0xb, 0x9, 0x0, 0xb0, 0x40, 0x7, 0x1, 0xb, - 0x43, 0x0, 0xb0, 0x80, 0x14, 0x2, 0xc9, 0x60, - 0x0, 0x8b, 0xe2, 0x10, 0x0, 0x1, 0x0, 0x0, - 0x0, 0x0, - - /* U+822C "般" */ - 0x0, 0x3, 0x10, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x9, 0x30, 0x7, 0x55, 0x82, 0x0, 0x0, 0xa7, - 0x5b, 0x2a, 0x10, 0xb0, 0x0, 0x0, 0xb3, 0xb, - 0xb, 0x0, 0xb0, 0x0, 0x0, 0xb4, 0x7b, 0xa, - 0x0, 0x8b, 0xc2, 0x0, 0xb0, 0x3b, 0x35, 0x0, - 0x0, 0x0, 0x5, 0xc5, 0x5c, 0x37, 0x55, 0x7c, - 0x0, 0x0, 0xb2, 0xb, 0x4, 0x10, 0x75, 0x0, - 0x0, 0xb6, 0x4b, 0x0, 0x60, 0xc0, 0x0, 0x1, - 0x91, 0x7b, 0x0, 0x79, 0x60, 0x0, 0x4, 0x50, - 0xb, 0x0, 0x4f, 0x30, 0x0, 0x8, 0x2, 0x3c, - 0x4, 0x91, 0xc8, 0x10, 0x24, 0x0, 0x78, 0x64, - 0x0, 0x9, 0xc1, 0x0, 0x0, 0x1, 0x0, 0x0, - 0x0, 0x0, - - /* U+8239 "船" */ - 0x0, 0x2, 0x20, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x8, 0x40, 0x0, 0xa5, 0x5b, 0x0, 0x0, 0x98, - 0x5b, 0x20, 0xa0, 0xb, 0x0, 0x0, 0xb1, 0xb, - 0x0, 0xa0, 0xb, 0x0, 0x0, 0xb5, 0x5b, 0x2, - 0x80, 0xb, 0x0, 0x0, 0xb0, 0x4b, 0x7, 0x20, - 0xb, 0xb6, 0x16, 0xc5, 0x5c, 0x34, 0x0, 0x0, - 0x0, 0x0, 0xa1, 0xb, 0x11, 0x75, 0x56, 0x60, - 0x0, 0x96, 0x4b, 0x2, 0x90, 0x5, 0x60, 0x2, - 0x70, 0x6b, 0x1, 0x90, 0x5, 0x50, 0x5, 0x30, - 0xb, 0x1, 0x90, 0x5, 0x50, 0x8, 0x1, 0x4b, - 0x2, 0xb5, 0x59, 0x60, 0x13, 0x0, 0x67, 0x2, - 0x80, 0x4, 0x40, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, - - /* U+826F "良" */ - 0x0, 0x1, 0x10, 0x0, 0x0, 0x0, 0x0, 0xc, - 0x20, 0x0, 0x0, 0x8, 0x55, 0xb6, 0x59, 0x30, - 0x0, 0xc0, 0x0, 0x0, 0xa2, 0x0, 0xc, 0x0, - 0x0, 0xa, 0x20, 0x0, 0xd5, 0x55, 0x55, 0xc2, - 0x0, 0xc, 0x0, 0x0, 0xa, 0x20, 0x0, 0xd5, - 0x65, 0x55, 0xb2, 0x0, 0xc, 0x2, 0x30, 0x5, - 0xd1, 0x0, 0xc0, 0x8, 0x37, 0x50, 0x0, 0xc, - 0x0, 0x3b, 0x10, 0x0, 0x0, 0xc5, 0x71, 0x2b, - 0x94, 0x10, 0xd, 0x50, 0x0, 0x5, 0xce, 0x40, - 0x0, 0x0, 0x0, 0x0, 0x0, - - /* U+8272 "色" */ - 0x0, 0x0, 0x31, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0xd5, 0x0, 0x50, 0x0, 0x0, 0x0, 0x7, - 0x95, 0x58, 0xe3, 0x0, 0x0, 0x0, 0x2a, 0x0, - 0x9, 0x10, 0x0, 0x0, 0x1, 0xd6, 0x55, 0x86, - 0x55, 0xa1, 0x0, 0x16, 0x82, 0x0, 0xb0, 0x0, - 0xb0, 0x0, 0x0, 0x82, 0x0, 0xb0, 0x0, 0xb0, - 0x0, 0x0, 0x87, 0x55, 0xc5, 0x55, 0xc0, 0x0, - 0x0, 0x82, 0x0, 0x0, 0x0, 0xa0, 0x0, 0x0, - 0x82, 0x0, 0x0, 0x0, 0x0, 0x30, 0x0, 0x82, - 0x0, 0x0, 0x0, 0x0, 0x60, 0x0, 0x83, 0x0, - 0x0, 0x0, 0x1, 0xa0, 0x0, 0x5d, 0xaa, 0xaa, - 0xaa, 0xac, 0xa0, - - /* U+8282 "节" */ - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0xc, 0x0, 0xd, 0x0, 0x0, 0x0, 0x0, - 0xc, 0x0, 0xc, 0x1, 0xa0, 0x6, 0x55, 0x5d, - 0x55, 0x5d, 0x55, 0x52, 0x0, 0x0, 0xb, 0x0, - 0xa, 0x0, 0x0, 0x0, 0x45, 0x55, 0x55, 0x55, - 0x5a, 0x0, 0x0, 0x10, 0x0, 0xb0, 0x0, 0x2b, - 0x0, 0x0, 0x0, 0x0, 0xb0, 0x0, 0x2b, 0x0, - 0x0, 0x0, 0x0, 0xb0, 0x0, 0x2b, 0x0, 0x0, - 0x0, 0x0, 0xb0, 0x0, 0x2a, 0x0, 0x0, 0x0, - 0x0, 0xb0, 0x58, 0xe8, 0x0, 0x0, 0x0, 0x0, - 0xb0, 0x0, 0x40, 0x0, 0x0, 0x0, 0x0, 0xc0, - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x10, 0x0, - 0x0, 0x0, - - /* U+82B1 "花" */ - 0x0, 0x0, 0x20, 0x0, 0x10, 0x0, 0x0, 0x0, - 0x0, 0x84, 0x1, 0xc0, 0x0, 0x0, 0x25, 0x55, - 0xa7, 0x56, 0xd5, 0x5c, 0x80, 0x1, 0x0, 0x73, - 0x1, 0xb0, 0x0, 0x0, 0x0, 0x0, 0x71, 0x0, - 0x50, 0x0, 0x0, 0x0, 0x3, 0xb0, 0x7, 0x20, - 0x2, 0x0, 0x0, 0xb, 0x20, 0xb, 0x10, 0x8c, - 0x0, 0x0, 0x5f, 0x10, 0xb, 0x2a, 0x80, 0x0, - 0x1, 0x9c, 0x0, 0xb, 0xb3, 0x0, 0x0, 0x27, - 0xc, 0x2, 0x7d, 0x10, 0x0, 0x0, 0x10, 0xc, - 0x12, 0xa, 0x10, 0x0, 0x50, 0x0, 0xc, 0x0, - 0xa, 0x10, 0x0, 0x80, 0x0, 0xc, 0x0, 0x7, - 0xca, 0xab, 0xc0, 0x0, 0x3, 0x0, 0x0, 0x0, - 0x0, 0x0, - - /* U+82E5 "若" */ - 0x0, 0x0, 0x21, 0x0, 0x30, 0x0, 0x0, 0x0, - 0x0, 0x68, 0x0, 0xc2, 0x0, 0x0, 0x5, 0x55, - 0x99, 0x55, 0xd5, 0x5c, 0x30, 0x0, 0x0, 0x56, - 0x10, 0xb0, 0x0, 0x0, 0x0, 0x0, 0x33, 0xd0, - 0x20, 0x0, 0x0, 0x0, 0x0, 0x6, 0x70, 0x0, - 0x3, 0x40, 0x6, 0x55, 0x5d, 0x55, 0x55, 0x56, - 0x50, 0x0, 0x0, 0x76, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x4, 0xe5, 0x55, 0x57, 0x90, 0x0, 0x0, - 0x4a, 0xc0, 0x0, 0x4, 0x80, 0x0, 0x5, 0x50, - 0xc0, 0x0, 0x4, 0x80, 0x0, 0x10, 0x0, 0xc5, - 0x55, 0x58, 0x80, 0x0, 0x0, 0x0, 0xc0, 0x0, - 0x4, 0x70, 0x0, 0x0, 0x0, 0x10, 0x0, 0x0, - 0x0, 0x0, - - /* U+82E6 "苦" */ - 0x0, 0x0, 0x20, 0x0, 0x2, 0x0, 0x0, 0x0, - 0x0, 0x76, 0x0, 0xd, 0x0, 0x10, 0x6, 0x55, - 0xa8, 0x55, 0x5c, 0x56, 0xc2, 0x0, 0x0, 0x74, - 0x10, 0xb, 0x0, 0x0, 0x0, 0x0, 0x31, 0xa4, - 0x3, 0x0, 0x0, 0x0, 0x0, 0x0, 0xa1, 0x0, - 0x1, 0x80, 0x6, 0x55, 0x55, 0xc5, 0x55, 0x55, - 0x51, 0x0, 0x0, 0x0, 0xb0, 0x0, 0x0, 0x0, - 0x0, 0xc, 0x55, 0x85, 0x55, 0xb3, 0x0, 0x0, - 0xc, 0x0, 0x0, 0x0, 0xa1, 0x0, 0x0, 0xc, - 0x0, 0x0, 0x0, 0xa1, 0x0, 0x0, 0xc, 0x0, - 0x0, 0x0, 0xa1, 0x0, 0x0, 0xd, 0x55, 0x55, - 0x55, 0xc1, 0x0, 0x0, 0x2, 0x0, 0x0, 0x0, - 0x10, 0x0, - - /* U+82F1 "英" */ - 0x0, 0x0, 0x10, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x67, 0x0, 0x1c, 0x0, 0x30, 0x6, 0x55, - 0x88, 0x55, 0x5c, 0x56, 0xb2, 0x0, 0x0, 0x55, - 0x42, 0xa, 0x0, 0x0, 0x0, 0x0, 0x11, 0x84, - 0x1, 0x0, 0x0, 0x0, 0xa, 0x55, 0xb7, 0x55, - 0xc3, 0x0, 0x0, 0xb, 0x0, 0x92, 0x0, 0xa0, - 0x0, 0x0, 0xb, 0x0, 0xa1, 0x0, 0xa0, 0x0, - 0x5, 0x5c, 0x55, 0xd5, 0x55, 0xc6, 0xd2, 0x1, - 0x0, 0x2, 0xb3, 0x30, 0x0, 0x0, 0x0, 0x0, - 0xb, 0x30, 0x74, 0x0, 0x0, 0x0, 0x1, 0xa5, - 0x0, 0x8, 0xa3, 0x0, 0x0, 0x57, 0x10, 0x0, - 0x0, 0x3c, 0xd2, 0x3, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x10, - - /* U+8336 "茶" */ - 0x0, 0x0, 0x30, 0x0, 0x30, 0x0, 0x0, 0x0, - 0x0, 0xb3, 0x0, 0xc1, 0x3, 0x0, 0x6, 0x55, - 0xc6, 0x55, 0xd5, 0x59, 0x60, 0x0, 0x0, 0xb2, - 0xc1, 0xb0, 0x0, 0x0, 0x0, 0x0, 0x29, 0x65, - 0x0, 0x0, 0x0, 0x0, 0x0, 0x86, 0x1, 0x81, - 0x0, 0x0, 0x0, 0x18, 0x40, 0x82, 0x9, 0xa4, - 0x10, 0x4, 0x50, 0x0, 0xc0, 0x2, 0x8b, 0x60, - 0x0, 0x55, 0x55, 0xd5, 0x57, 0x70, 0x0, 0x0, - 0x1, 0xa0, 0xc0, 0x33, 0x0, 0x0, 0x0, 0xa, - 0x40, 0xc0, 0x5, 0xa1, 0x0, 0x0, 0x82, 0x10, - 0xc0, 0x0, 0x6c, 0x0, 0x4, 0x0, 0x2b, 0xd0, - 0x0, 0x5, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, - - /* U+8377 "荷" */ - 0x0, 0x0, 0x2, 0x0, 0x10, 0x0, 0x0, 0x0, - 0x0, 0xe, 0x0, 0x49, 0x0, 0x10, 0x5, 0x55, - 0x5d, 0x55, 0x79, 0x56, 0xc2, 0x0, 0x0, 0xc, - 0x0, 0x36, 0x0, 0x0, 0x0, 0x3, 0xa3, 0x0, - 0x11, 0x0, 0x30, 0x0, 0xa, 0x46, 0x55, 0x55, - 0x59, 0xa3, 0x0, 0x4b, 0x0, 0x0, 0x10, 0x1a, - 0x0, 0x1, 0xad, 0x8, 0x65, 0xe1, 0x1a, 0x0, - 0x7, 0x1b, 0x8, 0x30, 0xb0, 0x1a, 0x0, 0x0, - 0xb, 0x8, 0x30, 0xb0, 0x1a, 0x0, 0x0, 0xb, - 0x8, 0x75, 0xb0, 0x1a, 0x0, 0x0, 0xb, 0x6, - 0x10, 0x0, 0x1a, 0x0, 0x0, 0x1c, 0x0, 0x0, - 0x5, 0xc8, 0x0, 0x0, 0x2, 0x0, 0x0, 0x0, - 0x20, 0x0, - - /* U+83D3 "菓" */ - 0x0, 0x0, 0x10, 0x0, 0x10, 0x0, 0x0, 0x0, - 0x0, 0x5a, 0x0, 0x48, 0x0, 0x20, 0x6, 0x55, - 0x8a, 0x55, 0x89, 0x57, 0xb2, 0x0, 0x0, 0x47, - 0x0, 0x46, 0x0, 0x0, 0x0, 0xb, 0x55, 0x58, - 0x55, 0xd4, 0x0, 0x0, 0xb, 0x0, 0x1a, 0x0, - 0xc0, 0x0, 0x0, 0xc, 0x55, 0x6c, 0x55, 0xd0, - 0x0, 0x0, 0xc, 0x55, 0x6c, 0x55, 0xd0, 0x0, - 0x0, 0x4, 0x0, 0x1a, 0x0, 0x38, 0x0, 0x2, - 0x65, 0x57, 0xdc, 0x85, 0x56, 0x40, 0x0, 0x0, - 0x2c, 0x4a, 0x36, 0x0, 0x0, 0x0, 0x5, 0x91, - 0x1a, 0x4, 0xb4, 0x0, 0x4, 0x63, 0x0, 0x2a, - 0x0, 0x2b, 0xd2, 0x0, 0x0, 0x0, 0x1, 0x0, - 0x0, 0x0, - - /* U+83DC "菜" */ - 0x0, 0x0, 0x4, 0x0, 0x30, 0x0, 0x0, 0x0, - 0x0, 0xd, 0x0, 0xc1, 0x1, 0x40, 0x6, 0x55, - 0x5d, 0x55, 0xd5, 0x57, 0x90, 0x0, 0x0, 0xa, - 0x0, 0x73, 0x81, 0x0, 0x0, 0x34, 0x56, 0x78, - 0x97, 0x62, 0x0, 0x0, 0x11, 0x0, 0x54, 0x0, - 0xb1, 0x0, 0x0, 0xb, 0x30, 0xb, 0x4, 0x70, - 0x0, 0x0, 0x3, 0x30, 0x38, 0x7, 0x0, 0x20, - 0x17, 0x55, 0x55, 0xab, 0x65, 0x58, 0xb1, 0x0, - 0x0, 0xa, 0x88, 0x60, 0x0, 0x0, 0x0, 0x0, - 0x95, 0x38, 0x19, 0x10, 0x0, 0x0, 0x29, 0x20, - 0x38, 0x2, 0xc8, 0x30, 0x5, 0x50, 0x0, 0x38, - 0x0, 0x7, 0x91, 0x0, 0x0, 0x0, 0x11, 0x0, - 0x0, 0x0, - - /* U+843D "落" */ - 0x0, 0x0, 0x20, 0x0, 0x30, 0x0, 0x0, 0x0, - 0x0, 0xb2, 0x0, 0xc0, 0x3, 0x20, 0x6, 0x55, - 0xc5, 0x55, 0xc5, 0x58, 0x70, 0x1, 0x40, 0x60, - 0x36, 0x50, 0x0, 0x0, 0x0, 0x86, 0x10, 0xa7, - 0x55, 0x80, 0x0, 0x0, 0x2, 0x42, 0x84, 0x8, - 0x40, 0x0, 0xa, 0x23, 0x27, 0x5, 0x77, 0x0, - 0x0, 0x3, 0x47, 0x21, 0x6, 0xc6, 0x0, 0x0, - 0x0, 0x17, 0x0, 0x76, 0x5, 0xc7, 0x30, 0x3, - 0xb3, 0x37, 0xa5, 0x55, 0xb7, 0x70, 0x2, 0xd0, - 0x2, 0x90, 0x0, 0xb0, 0x0, 0x0, 0xd0, 0x2, - 0x90, 0x0, 0xb0, 0x0, 0x0, 0xb0, 0x2, 0xb5, - 0x55, 0xb0, 0x0, 0x0, 0x0, 0x0, 0x10, 0x0, - 0x0, 0x0, - - /* U+8449 "葉" */ - 0x0, 0x0, 0x20, 0x0, 0x30, 0x0, 0x0, 0x0, - 0x0, 0x91, 0x0, 0xb1, 0x6, 0x60, 0x16, 0x55, - 0xb5, 0x55, 0xc5, 0x55, 0x50, 0x0, 0x6, 0x35, - 0x10, 0x50, 0x0, 0x0, 0x0, 0xa, 0x1b, 0x10, - 0xa3, 0x16, 0x0, 0x4, 0x5c, 0x5c, 0x55, 0xb6, - 0x55, 0x10, 0x0, 0xa, 0xb, 0x55, 0xb1, 0x0, - 0x0, 0x0, 0xc, 0x57, 0x55, 0x75, 0xb1, 0x0, - 0x0, 0x2, 0x0, 0xc0, 0x0, 0x4, 0x0, 0x5, - 0x55, 0x5a, 0xe7, 0x55, 0x6a, 0x40, 0x0, 0x0, - 0x79, 0xc1, 0x60, 0x0, 0x0, 0x0, 0x19, 0x50, - 0xc0, 0x1a, 0x71, 0x0, 0x14, 0x50, 0x0, 0xd0, - 0x0, 0x6e, 0x90, 0x0, 0x0, 0x0, 0x30, 0x0, - 0x0, 0x0, - - /* U+8457 "著" */ - 0x0, 0x0, 0x10, 0x0, 0x20, 0x0, 0x0, 0x0, - 0x6, 0x70, 0xc, 0x10, 0x60, 0x5, 0x55, 0x98, - 0x55, 0xc5, 0x57, 0x30, 0x0, 0x5, 0x38, 0x27, - 0x0, 0x0, 0x0, 0x0, 0x0, 0xb0, 0x61, 0xb2, - 0x0, 0x0, 0x65, 0x5c, 0x56, 0xd6, 0x0, 0x4, - 0x55, 0x55, 0xc5, 0xd8, 0x5b, 0x70, 0x10, 0x0, - 0x4, 0xa1, 0x0, 0x0, 0x0, 0x0, 0x6a, 0xb5, - 0x55, 0xa0, 0x0, 0x1, 0x7e, 0x10, 0x0, 0xb, - 0x0, 0x15, 0x50, 0xb5, 0x55, 0x55, 0xb0, 0x0, - 0x0, 0xb, 0x0, 0x0, 0xb, 0x0, 0x0, 0x0, - 0xb5, 0x55, 0x55, 0xc0, 0x0, 0x0, 0x2, 0x0, - 0x0, 0x2, 0x0, - - /* U+8535 "蔵" */ - 0x0, 0x0, 0x1, 0x0, 0x10, 0x0, 0x0, 0x0, - 0x0, 0x1b, 0x0, 0xa3, 0x2, 0x40, 0x6, 0x55, - 0x6b, 0x55, 0xb6, 0x57, 0x80, 0x0, 0x0, 0x5, - 0x0, 0x74, 0x80, 0x0, 0x0, 0x41, 0x11, 0x11, - 0x97, 0x76, 0x50, 0x0, 0xb4, 0x44, 0x46, 0x88, - 0x44, 0x30, 0x0, 0xb1, 0xb6, 0x87, 0x56, 0x6, - 0x20, 0x0, 0xb1, 0x93, 0x54, 0x38, 0xc, 0x30, - 0x0, 0xb1, 0xb5, 0x5c, 0x1b, 0x39, 0x0, 0x0, - 0xb1, 0xb5, 0x6b, 0xb, 0xb1, 0x0, 0x0, 0x91, - 0x93, 0x52, 0x9, 0xa0, 0x40, 0x5, 0x22, 0xa5, - 0x68, 0x75, 0xa5, 0x70, 0x5, 0x0, 0x0, 0x16, - 0x20, 0xa, 0xc0, 0x10, 0x0, 0x0, 0x10, 0x0, - 0x0, 0x20, - - /* U+8584 "薄" */ - 0x0, 0x0, 0x3, 0x0, 0x21, 0x0, 0x0, 0x0, - 0x0, 0xc, 0x0, 0x58, 0x1, 0x50, 0x3, 0x65, - 0x5c, 0x55, 0x8a, 0x85, 0x60, 0x1, 0x81, 0x4, - 0x0, 0xa1, 0x83, 0x20, 0x0, 0x46, 0x26, 0x55, - 0xd5, 0x56, 0x70, 0x4, 0x0, 0x47, 0x55, 0xc5, - 0x5c, 0x0, 0x5, 0x84, 0x9, 0x54, 0xc4, 0x4b, - 0x0, 0x0, 0x26, 0x9, 0x31, 0xb1, 0x1b, 0x0, - 0x0, 0x44, 0x9, 0x65, 0xc5, 0x6a, 0x0, 0x5, - 0xe0, 0x56, 0x55, 0x65, 0xd5, 0xb1, 0x0, 0xc0, - 0x11, 0x70, 0x0, 0xb0, 0x0, 0x0, 0xe0, 0x0, - 0x54, 0x0, 0xb0, 0x0, 0x0, 0xa0, 0x0, 0x0, - 0x5d, 0x80, 0x0, 0x0, 0x0, 0x0, 0x0, 0x1, - 0x0, 0x0, - - /* U+85AC "薬" */ - 0x0, 0x0, 0x2, 0x0, 0x11, 0x0, 0x0, 0x0, - 0x0, 0xd, 0x0, 0x3a, 0x0, 0x81, 0x6, 0x55, - 0x5c, 0x55, 0x7a, 0x55, 0x52, 0x0, 0x0, 0x2, - 0x2a, 0x11, 0x0, 0x0, 0x1, 0x72, 0x17, 0x95, - 0x59, 0x2, 0x60, 0x0, 0x2a, 0x19, 0x0, 0xa, - 0x58, 0x30, 0x0, 0x0, 0x4b, 0x55, 0x5a, 0x40, - 0x0, 0x4, 0x96, 0x29, 0x0, 0xa, 0x1a, 0x80, - 0x3, 0x10, 0x19, 0x57, 0x57, 0x0, 0x60, 0x3, - 0x55, 0x55, 0x5e, 0x55, 0x57, 0xd1, 0x1, 0x0, - 0x9, 0x9b, 0x51, 0x0, 0x0, 0x0, 0x2, 0xa5, - 0xb, 0x7, 0x82, 0x0, 0x3, 0x55, 0x0, 0xb, - 0x0, 0x3c, 0xd3, 0x0, 0x0, 0x0, 0x2, 0x0, - 0x0, 0x0, - - /* U+85DD "藝" */ - 0x0, 0x0, 0x2, 0x0, 0x1, 0x0, 0x0, 0x0, - 0x0, 0xc, 0x0, 0x1b, 0x0, 0x80, 0x5, 0x55, - 0x5c, 0x55, 0x6a, 0x55, 0x52, 0x0, 0x0, 0xa0, - 0x10, 0x7, 0x0, 0x0, 0x0, 0x65, 0xb5, 0x73, - 0x5c, 0x58, 0x0, 0x3, 0x75, 0x96, 0x93, 0xa, - 0x18, 0x0, 0x1, 0x92, 0xb6, 0x90, 0x5b, 0x19, - 0x0, 0x3, 0x26, 0xb5, 0x30, 0x95, 0x7b, 0x40, - 0x0, 0x78, 0xa5, 0x35, 0x21, 0x16, 0xc0, 0x0, - 0x33, 0x65, 0x55, 0x57, 0x72, 0x20, 0x1, 0x65, - 0x55, 0x95, 0x55, 0x5a, 0x30, 0x0, 0x0, 0x18, - 0x71, 0x27, 0x30, 0x0, 0x0, 0x8, 0xea, 0x87, - 0x54, 0xb4, 0x0, 0x0, 0x2, 0x10, 0x0, 0x0, - 0x0, 0x0, - - /* U+8607 "蘇" */ - 0x0, 0x0, 0x2, 0x0, 0x20, 0x0, 0x0, 0x0, - 0x0, 0x1b, 0x0, 0xa2, 0x2, 0x50, 0x6, 0x55, - 0x5b, 0x55, 0xc5, 0x55, 0x50, 0x0, 0x8, 0x24, - 0x0, 0x40, 0x15, 0x0, 0x0, 0x3c, 0x5a, 0x13, - 0x5b, 0x86, 0x10, 0x0, 0xa0, 0x44, 0x0, 0xa, - 0x0, 0x0, 0x6, 0xb5, 0xa5, 0xa5, 0x6d, 0x59, - 0x50, 0x0, 0x90, 0x91, 0x80, 0x9d, 0x50, 0x0, - 0x0, 0xb5, 0xb5, 0x80, 0x9a, 0x70, 0x0, 0x0, - 0x90, 0x91, 0x93, 0x5a, 0x29, 0x0, 0x0, 0x85, - 0x55, 0x45, 0xb, 0x9, 0xa1, 0x0, 0x43, 0x65, - 0x60, 0xb, 0x0, 0x20, 0xa, 0x2a, 0x44, 0x70, - 0xb, 0x0, 0x0, 0x2, 0x0, 0x0, 0x0, 0x1, - 0x0, 0x0, - - /* U+8655 "處" */ - 0x0, 0x0, 0x0, 0x40, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, 0xd1, 0x0, 0x50, 0x0, 0x0, 0x0, - 0x0, 0xd5, 0x55, 0x61, 0x0, 0x0, 0xb5, 0x55, - 0xa5, 0x55, 0x59, 0x90, 0x0, 0xb0, 0x0, 0xd1, - 0x3, 0x16, 0x0, 0x0, 0xb2, 0x34, 0xc4, 0x55, - 0x32, 0x0, 0x0, 0xb0, 0x20, 0xb9, 0x88, 0x9a, - 0x0, 0x0, 0xb0, 0xa4, 0x1, 0x20, 0x20, 0x0, - 0x0, 0xa0, 0xc5, 0x8b, 0x87, 0xc2, 0x0, 0x0, - 0x95, 0x80, 0x93, 0x91, 0xa0, 0x20, 0x3, 0x57, - 0x36, 0xa0, 0x90, 0xa0, 0x70, 0x6, 0x10, 0x2c, - 0x97, 0x10, 0x38, 0x70, 0x13, 0x5, 0x60, 0x17, - 0xac, 0xdd, 0xb1, 0x0, 0x10, 0x0, 0x0, 0x0, - 0x0, 0x0, - - /* U+884C "行" */ - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x8, 0x80, 0x0, 0x0, 0x6, 0x0, 0x0, 0x3a, - 0x0, 0x55, 0x55, 0x56, 0x10, 0x1, 0x80, 0x50, - 0x0, 0x0, 0x0, 0x0, 0x4, 0x1, 0xd1, 0x0, - 0x0, 0x0, 0x20, 0x0, 0xb, 0x34, 0x65, 0x59, - 0x57, 0x90, 0x0, 0x7e, 0x10, 0x0, 0xc, 0x0, - 0x0, 0x4, 0x6c, 0x0, 0x0, 0xc, 0x0, 0x0, - 0x13, 0xc, 0x0, 0x0, 0xc, 0x0, 0x0, 0x0, - 0xc, 0x0, 0x0, 0xc, 0x0, 0x0, 0x0, 0xc, - 0x0, 0x0, 0xc, 0x0, 0x0, 0x0, 0xc, 0x0, - 0x12, 0x2c, 0x0, 0x0, 0x0, 0xc, 0x0, 0x6, - 0xe8, 0x0, 0x0, 0x0, 0x1, 0x0, 0x0, 0x10, - 0x0, 0x0, - - /* U+8853 "術" */ - 0x0, 0x21, 0x0, 0x30, 0x0, 0x0, 0x0, 0x0, - 0x87, 0x0, 0xd2, 0x2, 0x55, 0x90, 0x1, 0x90, - 0x0, 0xb5, 0x60, 0x10, 0x0, 0x7, 0x9, 0x0, - 0xb0, 0x60, 0x0, 0x0, 0x20, 0x5a, 0x33, 0xc6, - 0x50, 0x0, 0x50, 0x0, 0xd1, 0x2a, 0xc1, 0x15, - 0x6c, 0x51, 0x7, 0xd2, 0xb, 0xc4, 0x0, 0xb, - 0x0, 0x32, 0xb0, 0x19, 0xb6, 0x90, 0xb, 0x0, - 0x0, 0xb0, 0x63, 0xb0, 0x70, 0xb, 0x0, 0x0, - 0xb0, 0x70, 0xb0, 0x0, 0xb, 0x0, 0x0, 0xb4, - 0x10, 0xb0, 0x0, 0xb, 0x0, 0x0, 0xb1, 0x0, - 0xb0, 0x0, 0xb, 0x0, 0x0, 0xb0, 0x0, 0xb0, - 0x6, 0xd9, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x10, 0x0, - - /* U+8868 "表" */ - 0x0, 0x0, 0x0, 0x30, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, 0xc1, 0x0, 0x1, 0x0, 0x1, 0x65, - 0x55, 0xd5, 0x55, 0x6c, 0x10, 0x0, 0x0, 0x0, - 0xc0, 0x0, 0x20, 0x0, 0x0, 0x26, 0x55, 0xd5, - 0x55, 0x92, 0x0, 0x0, 0x0, 0x0, 0xc0, 0x0, - 0x2, 0x30, 0x6, 0x55, 0x57, 0xe5, 0x55, 0x57, - 0x70, 0x0, 0x0, 0xc, 0x45, 0x0, 0xc3, 0x0, - 0x0, 0x0, 0xc4, 0x8, 0x28, 0x20, 0x0, 0x0, - 0x3a, 0xe0, 0x1, 0xb0, 0x0, 0x0, 0x16, 0x50, - 0xd0, 0x0, 0x4a, 0x10, 0x0, 0x0, 0x0, 0xd2, - 0x73, 0x3, 0xda, 0x61, 0x0, 0x0, 0xe9, 0x0, - 0x0, 0x7, 0x40, 0x0, 0x0, 0x10, 0x0, 0x0, - 0x0, 0x0, - - /* U+88AB "被" */ - 0x0, 0x20, 0x0, 0x0, 0x4, 0x0, 0x0, 0x0, - 0x49, 0x0, 0x0, 0xc, 0x0, 0x0, 0x0, 0x6, - 0x0, 0x0, 0xb, 0x0, 0x0, 0x5, 0x55, 0xc1, - 0xb5, 0x5c, 0x55, 0xe1, 0x0, 0x2, 0xa0, 0xb0, - 0xb, 0x5, 0x30, 0x0, 0xa, 0x33, 0xb0, 0xb, - 0x0, 0x0, 0x0, 0x3b, 0x65, 0xc5, 0x5b, 0x5a, - 0x30, 0x0, 0x8d, 0x60, 0xc1, 0x30, 0xd, 0x0, - 0x6, 0xb, 0x94, 0xb0, 0x60, 0x66, 0x0, 0x0, - 0xb, 0x15, 0xa0, 0x55, 0xc0, 0x0, 0x0, 0xb, - 0x4, 0x50, 0xe, 0x50, 0x0, 0x0, 0xb, 0x8, - 0x1, 0x94, 0xa6, 0x0, 0x0, 0xc, 0x43, 0x56, - 0x0, 0x8, 0xd3, 0x0, 0x1, 0x11, 0x0, 0x0, - 0x0, 0x0, - - /* U+88CF "裏" */ - 0x0, 0x0, 0x0, 0x40, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x3a, 0x0, 0x5, 0x20, 0x5, 0x55, - 0x55, 0x55, 0x55, 0x65, 0x30, 0x0, 0xc, 0x55, - 0x69, 0x55, 0xd1, 0x0, 0x0, 0xc, 0x55, 0x6b, - 0x55, 0xc0, 0x0, 0x0, 0xb, 0x0, 0x19, 0x0, - 0xb0, 0x0, 0x0, 0x7, 0x55, 0x6b, 0x55, 0x70, - 0x0, 0x0, 0x36, 0x55, 0x6b, 0x55, 0x74, 0x0, - 0x4, 0x65, 0x55, 0x8a, 0x55, 0x58, 0x80, 0x0, - 0x0, 0x7, 0xa5, 0x1, 0xc4, 0x0, 0x0, 0x4, - 0xba, 0x3, 0x87, 0x20, 0x0, 0x3, 0x64, 0x48, - 0x15, 0x4a, 0x85, 0x30, 0x0, 0x0, 0x6d, 0x70, - 0x0, 0x49, 0x40, 0x0, 0x0, 0x1, 0x0, 0x0, - 0x0, 0x0, - - /* U+88DC "補" */ - 0x0, 0x20, 0x0, 0x0, 0x2, 0x0, 0x0, 0x0, - 0x1b, 0x0, 0x0, 0xd, 0x37, 0x0, 0x0, 0x7, - 0x0, 0x0, 0xb, 0x7, 0x40, 0x6, 0x55, 0xc4, - 0x65, 0x5c, 0x55, 0xb3, 0x0, 0x3, 0x90, 0x20, - 0xb, 0x0, 0x30, 0x0, 0xa, 0x23, 0xb5, 0x5c, - 0x57, 0xb0, 0x0, 0x4c, 0x57, 0xb0, 0xb, 0x2, - 0x90, 0x1, 0x8c, 0x70, 0xb5, 0x5c, 0x56, 0x90, - 0x6, 0xb, 0x95, 0xb0, 0xb, 0x2, 0x90, 0x10, - 0xb, 0x17, 0xb5, 0x5c, 0x56, 0x90, 0x0, 0xb, - 0x0, 0xb0, 0xb, 0x2, 0x90, 0x0, 0xb, 0x0, - 0xb0, 0xb, 0x2, 0x90, 0x0, 0xc, 0x0, 0xb0, - 0xa, 0x3b, 0x60, 0x0, 0x1, 0x0, 0x20, 0x0, - 0x1, 0x0, - - /* U+88E1 "裡" */ - 0x0, 0x20, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x1b, 0x0, 0x30, 0x0, 0x4, 0x0, 0x0, 0x7, - 0x0, 0xb5, 0x5c, 0x5c, 0x20, 0x6, 0x55, 0xc1, - 0xa0, 0xb, 0xa, 0x0, 0x0, 0x3, 0x90, 0xa5, - 0x5c, 0x5c, 0x0, 0x0, 0xa, 0x23, 0xa0, 0xb, - 0xa, 0x0, 0x0, 0x3c, 0x48, 0xa0, 0xb, 0xa, - 0x0, 0x0, 0x8c, 0x70, 0xb5, 0x5c, 0x5b, 0x0, - 0x6, 0xb, 0x95, 0x40, 0xb, 0x0, 0x0, 0x10, - 0xb, 0x17, 0x0, 0xb, 0x6, 0x10, 0x0, 0xb, - 0x0, 0x75, 0x5c, 0x55, 0x20, 0x0, 0xb, 0x0, - 0x0, 0xb, 0x0, 0x0, 0x0, 0xc, 0x5, 0x55, - 0x5c, 0x57, 0xc1, 0x0, 0x3, 0x1, 0x0, 0x0, - 0x0, 0x0, - - /* U+88FD "製" */ - 0x0, 0x10, 0x30, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x84, 0xa3, 0x1, 0x0, 0xb, 0x20, 0x2, 0x95, - 0xc5, 0x68, 0x8, 0xb, 0x0, 0x7, 0x55, 0xc5, - 0x5a, 0x1b, 0xb, 0x0, 0x0, 0x75, 0xc5, 0x58, - 0xb, 0xb, 0x0, 0x0, 0xa0, 0xa0, 0xa, 0xb, - 0xb, 0x0, 0x0, 0xa0, 0xa1, 0x79, 0x2, 0x1b, - 0x0, 0x0, 0x60, 0x90, 0x64, 0x0, 0x7a, 0x0, - 0x4, 0x55, 0x55, 0x5b, 0x55, 0x5d, 0x60, 0x1, - 0x0, 0x3a, 0x25, 0x0, 0x73, 0x0, 0x0, 0x17, - 0xd1, 0x0, 0x76, 0x50, 0x0, 0x15, 0x40, 0xa1, - 0x55, 0x1a, 0x51, 0x0, 0x0, 0x0, 0xbb, 0x30, - 0x0, 0x6c, 0x80, 0x0, 0x0, 0x10, 0x0, 0x0, - 0x0, 0x0, - - /* U+8907 "複" */ - 0x0, 0x20, 0x0, 0x2, 0x0, 0x0, 0x0, 0x0, - 0x57, 0x0, 0xc, 0x40, 0x0, 0x10, 0x0, 0xa, - 0x0, 0x1d, 0x55, 0x56, 0xa1, 0x5, 0x55, 0xa0, - 0x76, 0x0, 0x4, 0x0, 0x0, 0x3, 0xa1, 0x6c, - 0x55, 0x5c, 0x20, 0x0, 0xa, 0x25, 0xc, 0x55, - 0x5c, 0x0, 0x0, 0x3b, 0x57, 0xb, 0x0, 0xb, - 0x0, 0x0, 0x9c, 0x70, 0x9, 0xd5, 0x58, 0x0, - 0x7, 0xa, 0x94, 0x4, 0xa5, 0x5b, 0x0, 0x0, - 0xa, 0x16, 0x17, 0x50, 0x67, 0x0, 0x0, 0xa, - 0x0, 0x40, 0x46, 0xa0, 0x0, 0x0, 0xa, 0x0, - 0x0, 0x6d, 0x60, 0x0, 0x0, 0xa, 0x1, 0x57, - 0x30, 0x5c, 0xa3, 0x0, 0x1, 0x12, 0x0, 0x0, - 0x0, 0x10, - - /* U+897F "西" */ - 0x0, 0x0, 0x0, 0x0, 0x0, 0x6, 0x20, 0x65, - 0x55, 0xc5, 0x5c, 0x55, 0x53, 0x0, 0x0, 0xb, - 0x0, 0xb0, 0x0, 0x0, 0x7, 0x55, 0xc5, 0x5c, - 0x55, 0x92, 0x0, 0xb0, 0xb, 0x0, 0xb0, 0xb, - 0x0, 0xb, 0x0, 0xc0, 0xb, 0x0, 0xb0, 0x0, - 0xb0, 0x1a, 0x0, 0xb0, 0xb, 0x0, 0xb, 0x6, - 0x40, 0xb, 0x1, 0xb0, 0x0, 0xb1, 0x70, 0x0, - 0x7a, 0x9b, 0x0, 0xb, 0x30, 0x0, 0x0, 0x0, - 0xb0, 0x0, 0xc5, 0x55, 0x55, 0x55, 0x5d, 0x0, - 0xb, 0x0, 0x0, 0x0, 0x0, 0x90, 0x0, 0x0, - 0x0, 0x0, 0x0, 0x0, 0x0, - - /* U+8981 "要" */ - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x55, - 0x55, 0x55, 0x55, 0x56, 0xd2, 0x0, 0x0, 0xb, - 0x0, 0xb0, 0x0, 0x0, 0x7, 0x55, 0xc5, 0x5c, - 0x5b, 0x20, 0x0, 0xb0, 0xb, 0x0, 0xb0, 0xb0, - 0x0, 0xb, 0x0, 0xb0, 0xb, 0xb, 0x0, 0x0, - 0xa5, 0x5a, 0x65, 0x55, 0x90, 0x0, 0x0, 0x1, - 0xd1, 0x0, 0x0, 0x61, 0x26, 0x55, 0xc7, 0x55, - 0x89, 0x57, 0x40, 0x0, 0x39, 0x0, 0xb, 0x10, - 0x0, 0x0, 0x3, 0x66, 0x7b, 0x90, 0x0, 0x0, - 0x0, 0x0, 0x4a, 0x66, 0xca, 0x10, 0x3, 0x56, - 0x74, 0x0, 0x0, 0x59, 0x1, 0x10, 0x0, 0x0, - 0x0, 0x0, 0x0, - - /* U+898B "見" */ - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0xb, 0x55, 0x55, 0x55, 0xe1, 0x0, 0x0, 0xc, - 0x0, 0x0, 0x0, 0xc0, 0x0, 0x0, 0xc, 0x55, - 0x55, 0x55, 0xc0, 0x0, 0x0, 0xc, 0x0, 0x0, - 0x0, 0xc0, 0x0, 0x0, 0xc, 0x55, 0x55, 0x55, - 0xc0, 0x0, 0x0, 0xc, 0x0, 0x0, 0x0, 0xc0, - 0x0, 0x0, 0xc, 0x0, 0x0, 0x0, 0xc0, 0x0, - 0x0, 0xd, 0x5c, 0x65, 0xd5, 0xb0, 0x0, 0x0, - 0x3, 0xc, 0x0, 0xc0, 0x0, 0x10, 0x0, 0x0, - 0x1c, 0x0, 0xc0, 0x0, 0x50, 0x0, 0x0, 0xa4, - 0x0, 0xc0, 0x0, 0x90, 0x0, 0x48, 0x40, 0x0, - 0xdb, 0xaa, 0xe2, 0x14, 0x10, 0x0, 0x0, 0x0, - 0x0, 0x0, - - /* U+898F "規" */ - 0x0, 0x2, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0xd, 0x0, 0x85, 0x55, 0x5b, 0x20, 0x0, 0xb, - 0x0, 0xb0, 0x0, 0xb, 0x0, 0x4, 0x5c, 0x74, - 0xb5, 0x55, 0x5c, 0x0, 0x1, 0xb, 0x0, 0xb0, - 0x0, 0xb, 0x0, 0x0, 0xb, 0x0, 0xb5, 0x55, - 0x5c, 0x0, 0x17, 0x5c, 0x59, 0xb0, 0x0, 0xb, - 0x0, 0x0, 0xb, 0x0, 0xb0, 0x0, 0xb, 0x0, - 0x0, 0x1c, 0x10, 0xb5, 0xd7, 0x9a, 0x0, 0x0, - 0x37, 0x76, 0x10, 0xc3, 0x70, 0x0, 0x0, 0x82, - 0xc, 0x14, 0x83, 0x70, 0x20, 0x1, 0x70, 0x1, - 0xb, 0x13, 0x70, 0x60, 0x6, 0x0, 0x3, 0x71, - 0x2, 0xca, 0xd1, 0x10, 0x0, 0x11, 0x0, 0x0, - 0x0, 0x0, - - /* U+8996 "視" */ - 0x0, 0x10, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x1a, 0x0, 0x85, 0x55, 0x5b, 0x30, 0x0, 0x8, - 0x20, 0xb0, 0x0, 0xb, 0x0, 0x6, 0x55, 0xb2, - 0xb5, 0x55, 0x5c, 0x0, 0x0, 0x2, 0xa0, 0xb0, - 0x0, 0xb, 0x0, 0x0, 0xa, 0x10, 0xb5, 0x55, - 0x5c, 0x0, 0x0, 0x5d, 0x10, 0xb0, 0x0, 0xb, - 0x0, 0x2, 0x7b, 0xa5, 0xb0, 0x0, 0xb, 0x0, - 0x15, 0xb, 0x19, 0xb5, 0xd7, 0x9b, 0x0, 0x0, - 0xb, 0x0, 0x0, 0xb3, 0x70, 0x0, 0x0, 0xb, - 0x0, 0x5, 0x73, 0x70, 0x30, 0x0, 0xc, 0x0, - 0x1a, 0x3, 0x70, 0x70, 0x0, 0xc, 0x3, 0x60, - 0x1, 0xca, 0xe2, 0x0, 0x1, 0x21, 0x0, 0x0, - 0x0, 0x0, - - /* U+899A "覚" */ - 0x0, 0x0, 0x0, 0x0, 0x1, 0x0, 0x0, 0x0, - 0x72, 0xa, 0x10, 0x97, 0x0, 0x1, 0x1, 0xc0, - 0x57, 0x19, 0x0, 0x0, 0x75, 0x56, 0x55, 0x58, - 0x55, 0xa9, 0x3d, 0x1, 0x0, 0x0, 0x2, 0x9, - 0x1, 0x20, 0xa5, 0x55, 0x55, 0xd4, 0x10, 0x0, - 0xa, 0x55, 0x55, 0x5c, 0x0, 0x0, 0x0, 0xa0, - 0x0, 0x0, 0xb0, 0x0, 0x0, 0xa, 0x55, 0x55, - 0x5c, 0x0, 0x0, 0x0, 0xa5, 0x75, 0x75, 0xc0, - 0x0, 0x0, 0x3, 0xc, 0xb, 0x3, 0x0, 0x30, - 0x0, 0x7, 0x60, 0xb0, 0x0, 0x15, 0x0, 0x47, - 0x50, 0x8, 0xba, 0xac, 0x90, 0x30, 0x0, 0x0, - 0x0, 0x0, 0x0, - - /* U+89AA "親" */ - 0x0, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x5, 0x80, 0x6, 0x55, 0x56, 0x80, 0x2, 0x65, - 0xa6, 0x89, 0x10, 0x3, 0x60, 0x0, 0x51, 0xb, - 0x9, 0x65, 0x57, 0x60, 0x0, 0x1a, 0x16, 0x9, - 0x10, 0x3, 0x60, 0x5, 0x56, 0x85, 0xa9, 0x65, - 0x57, 0x60, 0x0, 0x1, 0x80, 0x9, 0x10, 0x3, - 0x60, 0x2, 0x56, 0xb6, 0x69, 0x65, 0x57, 0x60, - 0x0, 0x1, 0x80, 0x8, 0x47, 0xa2, 0x40, 0x0, - 0xa4, 0x95, 0x0, 0x55, 0xa0, 0x0, 0x2, 0x81, - 0x86, 0x80, 0x82, 0xa0, 0x20, 0x7, 0x1, 0x80, - 0x71, 0x90, 0xa0, 0x40, 0x1, 0x4c, 0x50, 0x26, - 0x0, 0x7a, 0xc4, 0x0, 0x0, 0x0, 0x20, 0x0, - 0x0, 0x0, - - /* U+89BA "覺" */ - 0x0, 0x0, 0x20, 0x2, 0x0, 0x0, 0x0, 0x0, - 0x86, 0x71, 0x6a, 0x36, 0x98, 0x0, 0x0, 0xa4, - 0x63, 0x47, 0x14, 0x94, 0x0, 0x0, 0x92, 0x31, - 0x4a, 0x12, 0xa2, 0x0, 0x0, 0x87, 0x43, 0x7a, - 0x16, 0xd0, 0x0, 0x9, 0x76, 0x55, 0x55, 0x55, - 0x97, 0xb0, 0x58, 0x8, 0x55, 0x55, 0x5a, 0x25, - 0x0, 0x0, 0xa, 0x55, 0x55, 0x5b, 0x0, 0x0, - 0x0, 0xa, 0x33, 0x33, 0x3b, 0x0, 0x0, 0x0, - 0xa, 0x11, 0x11, 0x1a, 0x10, 0x0, 0x0, 0x8, - 0x5c, 0x5c, 0x58, 0x0, 0x30, 0x0, 0x0, 0x56, - 0xa, 0x0, 0x0, 0x60, 0x0, 0x36, 0x50, 0x8, - 0xa9, 0x9a, 0xd0, 0x3, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, - - /* U+89C0 "觀" */ - 0x0, 0x10, 0x10, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x93, 0x56, 0x6, 0x55, 0x57, 0x60, 0x6, 0xb6, - 0x99, 0x99, 0x10, 0x5, 0x50, 0x1, 0x53, 0x42, - 0x28, 0x65, 0x58, 0x50, 0xa, 0x5b, 0xa5, 0xb8, - 0x10, 0x5, 0x50, 0xa, 0x59, 0xa5, 0x98, 0x65, - 0x58, 0x50, 0x2, 0xa5, 0x50, 0x8, 0x10, 0x5, - 0x50, 0x4, 0xa5, 0xa7, 0x78, 0x65, 0x58, 0x50, - 0xb, 0x52, 0x81, 0x8, 0x57, 0xa4, 0x30, 0x26, - 0x86, 0xa6, 0x30, 0x55, 0xa0, 0x0, 0x5, 0x86, - 0xa7, 0x40, 0x82, 0xa0, 0x20, 0x5, 0x52, 0x81, - 0x21, 0x90, 0xa0, 0x50, 0x6, 0x85, 0x55, 0x66, - 0x0, 0x9a, 0xd3, 0x0, 0x0, 0x0, 0x20, 0x0, - 0x0, 0x0, - - /* U+89D2 "角" */ - 0x0, 0x0, 0x12, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x8, 0x90, 0x1, 0x0, 0x0, 0x0, 0x1, 0xd5, - 0x55, 0xc9, 0x0, 0x0, 0x0, 0xa3, 0x0, 0x18, - 0x0, 0x0, 0x0, 0x7d, 0x55, 0x5a, 0x55, 0x5e, - 0x0, 0x63, 0xb0, 0x0, 0xc0, 0x0, 0xc0, 0x0, - 0xb, 0x55, 0x5d, 0x55, 0x5c, 0x0, 0x0, 0xb0, - 0x0, 0xc0, 0x0, 0xc0, 0x0, 0xc, 0x55, 0x5d, - 0x55, 0x5c, 0x0, 0x0, 0xb0, 0x0, 0xc0, 0x0, - 0xc0, 0x0, 0x38, 0x0, 0xc, 0x0, 0xc, 0x0, - 0xa, 0x10, 0x0, 0xc0, 0x0, 0xc0, 0x7, 0x20, - 0x0, 0x1a, 0x6, 0xda, 0x1, 0x0, 0x0, 0x0, - 0x0, 0x2, 0x0, - - /* U+89E3 "解" */ - 0x0, 0x2, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0xb, 0x30, 0x4, 0x56, 0x55, 0xa0, 0x0, 0x2d, - 0x58, 0x0, 0x1b, 0x0, 0xb0, 0x0, 0x92, 0x58, - 0x0, 0x75, 0x0, 0xa0, 0x3, 0xc5, 0x97, 0x63, - 0x90, 0x4a, 0x70, 0x4, 0xa0, 0xa5, 0x74, 0x41, - 0x93, 0x0, 0x0, 0xc5, 0xc8, 0x50, 0xc2, 0xa0, - 0x20, 0x0, 0xa0, 0xa5, 0x55, 0x95, 0xc6, 0x70, - 0x0, 0xb3, 0xb7, 0x67, 0x1, 0xa0, 0x0, 0x0, - 0xa2, 0xb7, 0x77, 0x55, 0xc5, 0x95, 0x2, 0x70, - 0xa5, 0x50, 0x1, 0xa0, 0x0, 0x6, 0x20, 0xb5, - 0x50, 0x1, 0xa0, 0x0, 0x6, 0x0, 0x6b, 0x40, - 0x1, 0xb0, 0x0, 0x10, 0x0, 0x2, 0x0, 0x0, - 0x10, 0x0, - - /* U+89E6 "触" */ - 0x0, 0x3, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0xc, 0x40, 0x0, 0x0, 0xc0, 0x0, 0x0, 0x2c, - 0x5a, 0x20, 0x0, 0xa0, 0x0, 0x0, 0x91, 0x28, - 0x0, 0x0, 0xa0, 0x10, 0x4, 0xc5, 0x95, 0xa3, - 0xa5, 0xc5, 0xd0, 0x13, 0xa0, 0x90, 0xa3, 0x70, - 0xa0, 0xa0, 0x0, 0xc5, 0xb5, 0xa3, 0x70, 0xa0, - 0xa0, 0x0, 0xa0, 0x90, 0xa3, 0x70, 0xa0, 0xa0, - 0x0, 0xc5, 0xb5, 0xa3, 0xa5, 0xc5, 0xa0, 0x0, - 0xa0, 0x90, 0xa1, 0x10, 0xa0, 0x0, 0x2, 0x60, - 0x90, 0xa0, 0x0, 0xa2, 0x60, 0x6, 0x10, 0xa0, - 0xa3, 0x56, 0xc4, 0xb3, 0x5, 0x0, 0x47, 0x98, - 0x62, 0x0, 0x33, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, - - /* U+8A00 "言" */ - 0x0, 0x0, 0x0, 0x20, 0x0, 0x0, 0x0, 0x0, - 0x0, 0xa, 0x50, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x35, 0x0, 0x5, 0x20, 0x65, 0x55, 0x55, 0x55, - 0x55, 0x54, 0x0, 0x0, 0x0, 0x0, 0x2, 0x70, - 0x0, 0x0, 0x65, 0x55, 0x55, 0x55, 0x10, 0x0, - 0x0, 0x0, 0x0, 0x0, 0x50, 0x0, 0x0, 0x65, - 0x55, 0x55, 0x56, 0x10, 0x0, 0x3, 0x0, 0x0, - 0x0, 0x40, 0x0, 0x0, 0xc5, 0x55, 0x55, 0x6c, - 0x0, 0x0, 0xc, 0x0, 0x0, 0x2, 0xa0, 0x0, - 0x0, 0xc5, 0x55, 0x55, 0x7a, 0x0, 0x0, 0xc, - 0x0, 0x0, 0x2, 0xa0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x0, - - /* U+8A08 "計" */ - 0x0, 0x21, 0x0, 0x0, 0x4, 0x0, 0x0, 0x0, - 0x1d, 0x10, 0x0, 0xd, 0x10, 0x0, 0x15, 0x5d, - 0x67, 0x80, 0xc, 0x0, 0x0, 0x1, 0x0, 0x0, - 0x0, 0xc, 0x0, 0x0, 0x3, 0x44, 0x49, 0x0, - 0xc, 0x0, 0x30, 0x2, 0x21, 0x11, 0x36, 0x5d, - 0x56, 0x80, 0x4, 0x55, 0x5a, 0x10, 0xc, 0x0, - 0x0, 0x1, 0x0, 0x0, 0x0, 0xc, 0x0, 0x0, - 0x7, 0x55, 0x59, 0x0, 0xc, 0x0, 0x0, 0xb, - 0x0, 0xb, 0x0, 0xc, 0x0, 0x0, 0xb, 0x0, - 0xb, 0x0, 0xc, 0x0, 0x0, 0xb, 0x55, 0x5b, - 0x0, 0xd, 0x0, 0x0, 0xb, 0x0, 0xb, 0x0, - 0xd, 0x0, 0x0, 0x1, 0x0, 0x0, 0x0, 0x1, - 0x0, 0x0, - - /* U+8A0A "訊" */ - 0x0, 0x20, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x39, 0x4, 0x68, 0x55, 0xd0, 0x0, 0x15, 0x5c, - 0x6a, 0xb, 0x0, 0xc0, 0x0, 0x1, 0x0, 0x0, - 0xb, 0x0, 0xb0, 0x0, 0x4, 0x55, 0x91, 0xb, - 0x0, 0xb0, 0x0, 0x1, 0x0, 0x0, 0xb, 0x10, - 0xb0, 0x0, 0x4, 0x55, 0xa3, 0x6c, 0x74, 0xa0, - 0x0, 0x1, 0x0, 0x0, 0xb, 0x0, 0xb0, 0x0, - 0x7, 0x55, 0x92, 0xb, 0x0, 0xb0, 0x0, 0xb, - 0x0, 0xa1, 0xb, 0x0, 0x93, 0x10, 0xb, 0x0, - 0xa1, 0xb, 0x0, 0x48, 0x60, 0xb, 0x55, 0xc1, - 0xc, 0x0, 0xc, 0xb0, 0xb, 0x0, 0xa1, 0xb, - 0x0, 0x1, 0xd0, 0x1, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, - - /* U+8A0E "討" */ - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x46, 0x0, 0x0, 0x0, 0xe0, 0x0, 0x0, 0xa, - 0x6, 0x0, 0x0, 0xd0, 0x0, 0x26, 0x55, 0x55, - 0x10, 0x0, 0xd0, 0x10, 0x4, 0x55, 0x93, 0x54, - 0x44, 0xd5, 0x80, 0x1, 0x0, 0x0, 0x0, 0x0, - 0xd0, 0x0, 0x0, 0x0, 0x50, 0x8, 0x0, 0xd0, - 0x0, 0x5, 0x55, 0x50, 0x4, 0xb0, 0xd0, 0x0, - 0x6, 0x55, 0x82, 0x0, 0x90, 0xd0, 0x0, 0xb, - 0x0, 0xa1, 0x0, 0x0, 0xd0, 0x0, 0xb, 0x0, - 0xa1, 0x0, 0x0, 0xd0, 0x0, 0xb, 0x55, 0xc1, - 0x1, 0x0, 0xd0, 0x0, 0xc, 0x0, 0xa1, 0x1, - 0x7e, 0xc0, 0x0, 0x1, 0x0, 0x0, 0x0, 0x2, - 0x10, 0x0, - - /* U+8A13 "訓" */ - 0x0, 0x20, 0x0, 0x1, 0x0, 0x0, 0x10, 0x0, - 0x39, 0x0, 0xc, 0x7, 0x11, 0xc0, 0x25, 0x5b, - 0x6a, 0xc, 0xb, 0x0, 0xa0, 0x0, 0x0, 0x0, - 0xc, 0xb, 0x0, 0xa0, 0x5, 0x55, 0x91, 0xb, - 0xb, 0x0, 0xa0, 0x0, 0x0, 0x10, 0xc, 0xb, - 0x0, 0xa0, 0x4, 0x55, 0x81, 0xc, 0xb, 0x0, - 0xa0, 0x0, 0x0, 0x10, 0xc, 0xb, 0x0, 0xa0, - 0xb, 0x55, 0xc3, 0x1a, 0xb, 0x0, 0xa0, 0xb, - 0x0, 0xa1, 0x56, 0xb, 0x0, 0xa0, 0xb, 0x0, - 0xa1, 0xa1, 0xb, 0x0, 0xa0, 0xb, 0x55, 0x94, - 0x70, 0x7, 0x1, 0xa0, 0x5, 0x0, 0x16, 0x0, - 0x0, 0x1, 0xa0, 0x0, 0x0, 0x10, 0x0, 0x0, - 0x0, 0x0, - - /* U+8A18 "記" */ - 0x0, 0x20, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x4a, 0x0, 0x25, 0x55, 0x5a, 0x20, 0x25, 0x5d, - 0x59, 0x31, 0x0, 0xc, 0x0, 0x1, 0x0, 0x0, - 0x0, 0x0, 0xc, 0x0, 0x4, 0x55, 0x58, 0x0, - 0x0, 0xc, 0x0, 0x1, 0x0, 0x0, 0x9, 0x55, - 0x5d, 0x0, 0x4, 0x55, 0x76, 0xc, 0x0, 0x5, - 0x0, 0x1, 0x0, 0x0, 0xc, 0x0, 0x0, 0x0, - 0x7, 0x55, 0x5a, 0xc, 0x0, 0x0, 0x0, 0xb, - 0x0, 0xc, 0xc, 0x0, 0x0, 0x10, 0xb, 0x0, - 0xb, 0xc, 0x0, 0x0, 0x50, 0xb, 0x55, 0x5b, - 0xc, 0x0, 0x0, 0x90, 0xc, 0x0, 0xb, 0x9, - 0xcb, 0xbc, 0xb0, 0x2, 0x0, 0x1, 0x0, 0x0, - 0x0, 0x0, - - /* U+8A2A "訪" */ - 0x0, 0x20, 0x0, 0x0, 0x20, 0x0, 0x0, 0x0, - 0x67, 0x0, 0x0, 0x4b, 0x0, 0x0, 0x25, 0x6b, - 0x68, 0x0, 0xb, 0x30, 0x10, 0x1, 0x0, 0x0, - 0x65, 0x85, 0x57, 0x90, 0x4, 0x55, 0x91, 0x0, - 0xd0, 0x0, 0x0, 0x1, 0x0, 0x0, 0x0, 0xd0, - 0x1, 0x0, 0x3, 0x55, 0x80, 0x0, 0xc5, 0x5c, - 0x40, 0x1, 0x0, 0x0, 0x2, 0x80, 0xa, 0x10, - 0x7, 0x55, 0xa2, 0x6, 0x50, 0xb, 0x0, 0xb, - 0x0, 0xb0, 0xa, 0x0, 0xc, 0x0, 0xb, 0x0, - 0xb0, 0x27, 0x0, 0xc, 0x0, 0xb, 0x55, 0xc0, - 0x80, 0x12, 0x2a, 0x0, 0xb, 0x0, 0x95, 0x20, - 0x5, 0xf3, 0x0, 0x0, 0x0, 0x1, 0x0, 0x0, - 0x10, 0x0, - - /* U+8A2D "設" */ - 0x0, 0x20, 0x0, 0x0, 0x0, 0x10, 0x0, 0x0, - 0x67, 0x0, 0xb, 0x55, 0xd2, 0x0, 0x25, 0x6b, - 0x67, 0xc, 0x0, 0xb0, 0x0, 0x0, 0x0, 0x0, - 0xb, 0x0, 0xb0, 0x0, 0x5, 0x55, 0x91, 0x29, - 0x0, 0xb2, 0x30, 0x0, 0x0, 0x0, 0x80, 0x0, - 0x4a, 0x92, 0x4, 0x65, 0x84, 0x46, 0x55, 0x6d, - 0x10, 0x0, 0x0, 0x0, 0x6, 0x0, 0x88, 0x0, - 0xa, 0x55, 0xb2, 0x3, 0x41, 0xc0, 0x0, 0xb, - 0x0, 0xb0, 0x0, 0x9a, 0x30, 0x0, 0xb, 0x0, - 0xb0, 0x0, 0x9c, 0x0, 0x0, 0xb, 0x55, 0xc0, - 0x7, 0x46, 0xa0, 0x0, 0xb, 0x0, 0x72, 0x72, - 0x0, 0x7e, 0x81, 0x1, 0x0, 0x13, 0x0, 0x0, - 0x3, 0x40, - - /* U+8A31 "許" */ - 0x0, 0x20, 0x0, 0x1, 0x20, 0x0, 0x0, 0x0, - 0x49, 0x0, 0x4, 0xb0, 0x0, 0x0, 0x15, 0x5d, - 0x59, 0x8, 0x30, 0x1, 0x0, 0x1, 0x0, 0x0, - 0xc, 0x58, 0x59, 0x40, 0x4, 0x55, 0x91, 0x45, - 0xc, 0x0, 0x0, 0x0, 0x0, 0x0, 0x70, 0xc, - 0x0, 0x0, 0x3, 0x55, 0x92, 0x0, 0xc, 0x0, - 0x0, 0x0, 0x0, 0x0, 0x65, 0x5d, 0x55, 0xc1, - 0x7, 0x55, 0xa2, 0x0, 0xc, 0x0, 0x0, 0xb, - 0x0, 0xb0, 0x0, 0xc, 0x0, 0x0, 0xb, 0x0, - 0xb0, 0x0, 0xc, 0x0, 0x0, 0xb, 0x55, 0xc0, - 0x0, 0xc, 0x0, 0x0, 0xb, 0x0, 0x70, 0x0, - 0xc, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x2, - 0x0, 0x0, - - /* U+8A33 "訳" */ - 0x0, 0x20, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x29, 0x0, 0x5, 0x22, 0x22, 0x60, 0x26, 0x59, - 0x6a, 0x1d, 0x33, 0x34, 0xa0, 0x0, 0x0, 0x10, - 0xc, 0x0, 0x2, 0x90, 0x4, 0x55, 0x80, 0xc, - 0x0, 0x2, 0x90, 0x0, 0x0, 0x10, 0xd, 0x56, - 0x56, 0x90, 0x4, 0x55, 0x70, 0xb, 0x5, 0x0, - 0x0, 0x0, 0x0, 0x0, 0x1a, 0x7, 0x0, 0x0, - 0xb, 0x55, 0xc4, 0x28, 0x8, 0x0, 0x0, 0xb, - 0x0, 0xb0, 0x64, 0x4, 0x60, 0x0, 0xb, 0x0, - 0xb0, 0x90, 0x0, 0xc1, 0x0, 0xb, 0x55, 0xc2, - 0x80, 0x0, 0x4c, 0x0, 0x6, 0x0, 0x27, 0x0, - 0x0, 0x9, 0xd4, 0x0, 0x0, 0x31, 0x0, 0x0, - 0x0, 0x40, - - /* U+8A34 "訴" */ - 0x0, 0x30, 0x0, 0x0, 0x0, 0x2, 0x0, 0x0, - 0x68, 0x0, 0x3, 0x36, 0xac, 0x30, 0x16, 0x6a, - 0x69, 0xd, 0x31, 0x0, 0x0, 0x0, 0x0, 0x0, - 0xc, 0x0, 0x0, 0x0, 0x4, 0x65, 0x81, 0xd, - 0x55, 0x55, 0xb1, 0x0, 0x0, 0x0, 0xc, 0x0, - 0xc0, 0x0, 0x3, 0x55, 0x80, 0xc, 0x22, 0xc0, - 0x0, 0x0, 0x0, 0x0, 0x1b, 0x4, 0xe8, 0x10, - 0xa, 0x55, 0xc2, 0x38, 0x0, 0xc5, 0xe0, 0xb, - 0x0, 0xb0, 0x74, 0x0, 0xc0, 0x30, 0xb, 0x0, - 0xb0, 0xa0, 0x0, 0xc0, 0x0, 0xb, 0x55, 0xc5, - 0x40, 0x0, 0xd0, 0x0, 0x7, 0x0, 0x36, 0x0, - 0x0, 0xc0, 0x0, 0x0, 0x0, 0x10, 0x0, 0x0, - 0x0, 0x0, - - /* U+8A55 "評" */ - 0x0, 0x20, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x59, 0x0, 0x36, 0x59, 0x56, 0x70, 0x15, 0x5d, - 0x67, 0x20, 0xc, 0x1, 0x30, 0x1, 0x0, 0x0, - 0x56, 0xc, 0x6, 0xa0, 0x3, 0x55, 0x90, 0xe, - 0x1c, 0xa, 0x0, 0x1, 0x0, 0x0, 0x8, 0x1c, - 0x34, 0x0, 0x3, 0x44, 0x70, 0x0, 0xc, 0x10, - 0x50, 0x1, 0x11, 0x11, 0x65, 0x5d, 0x55, 0x71, - 0x7, 0x55, 0x92, 0x0, 0xc, 0x0, 0x0, 0xb, - 0x0, 0xb0, 0x0, 0xc, 0x0, 0x0, 0xb, 0x0, - 0xb0, 0x0, 0xc, 0x0, 0x0, 0xb, 0x55, 0xc0, - 0x0, 0xd, 0x0, 0x0, 0xb, 0x0, 0xa0, 0x0, - 0xc, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, - - /* U+8A66 "試" */ - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x74, 0x0, 0x0, 0xb, 0x43, 0x0, 0x0, 0x1a, - 0x4, 0x0, 0xb, 0xc, 0x10, 0x16, 0x55, 0x56, - 0x11, 0x1b, 0x13, 0x60, 0x3, 0x55, 0x82, 0x32, - 0x2b, 0x32, 0x20, 0x1, 0x0, 0x0, 0x0, 0x9, - 0x10, 0x0, 0x0, 0x0, 0x51, 0x67, 0xa9, 0x30, - 0x0, 0x4, 0x55, 0x50, 0xb, 0x6, 0x50, 0x0, - 0x6, 0x55, 0x81, 0xb, 0x3, 0x80, 0x0, 0xb, - 0x0, 0xb0, 0xb, 0x0, 0xb0, 0x10, 0xb, 0x0, - 0xb0, 0x4d, 0x62, 0x84, 0x50, 0xb, 0x55, 0xc3, - 0x91, 0x0, 0x1c, 0xa0, 0xb, 0x0, 0xa0, 0x0, - 0x0, 0x2, 0xb0, 0x1, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, - - /* U+8A71 "話" */ - 0x0, 0x10, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x66, 0x0, 0x0, 0x14, 0x7c, 0xa0, 0x15, 0x5c, - 0x59, 0x24, 0x5c, 0x31, 0x0, 0x1, 0x0, 0x0, - 0x0, 0xb, 0x0, 0x0, 0x2, 0x33, 0x80, 0x0, - 0xb, 0x0, 0x70, 0x2, 0x21, 0x12, 0x65, 0x5c, - 0x55, 0x51, 0x3, 0x55, 0x80, 0x0, 0xb, 0x0, - 0x0, 0x1, 0x0, 0x0, 0x43, 0x3c, 0x37, 0x10, - 0x7, 0x55, 0x91, 0x94, 0x22, 0x2b, 0x10, 0xb, - 0x0, 0xb0, 0x92, 0x0, 0xb, 0x0, 0xb, 0x0, - 0xb0, 0x92, 0x0, 0xb, 0x0, 0xb, 0x55, 0xc0, - 0x96, 0x55, 0x5c, 0x0, 0xb, 0x0, 0x90, 0x91, - 0x0, 0xa, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, - - /* U+8A72 "該" */ - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x73, 0x0, 0x0, 0x85, 0x0, 0x0, 0x0, 0x1a, - 0x4, 0x0, 0xc, 0x0, 0x0, 0x16, 0x55, 0x55, - 0x54, 0x54, 0x44, 0xa1, 0x3, 0x55, 0x80, 0x0, - 0xc4, 0x1, 0x0, 0x1, 0x0, 0x0, 0x8, 0x50, - 0x2e, 0x10, 0x0, 0x0, 0x40, 0xaa, 0x87, 0xc4, - 0x0, 0x4, 0x55, 0x50, 0x44, 0x17, 0x52, 0x0, - 0x6, 0x55, 0x81, 0x0, 0x73, 0x1d, 0x40, 0xb, - 0x0, 0xb0, 0x45, 0x0, 0xb4, 0x0, 0xb, 0x0, - 0xb1, 0x0, 0x1c, 0x86, 0x0, 0xb, 0x55, 0xc0, - 0x3, 0xa2, 0x6, 0xb0, 0xc, 0x0, 0xa2, 0x66, - 0x0, 0x0, 0xb2, 0x1, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, - - /* U+8A73 "詳" */ - 0x0, 0x10, 0x0, 0x0, 0x0, 0x5, 0x0, 0x0, - 0x67, 0x0, 0x9, 0x10, 0x2d, 0x10, 0x15, 0x5b, - 0x6a, 0x6, 0x90, 0x73, 0x0, 0x1, 0x0, 0x1, - 0x45, 0x84, 0xa4, 0xb1, 0x3, 0x55, 0x91, 0x21, - 0x1c, 0x11, 0x10, 0x0, 0x0, 0x0, 0x0, 0xc, - 0x2, 0x0, 0x3, 0x55, 0x90, 0x26, 0x5d, 0x57, - 0x30, 0x1, 0x0, 0x0, 0x0, 0xc, 0x0, 0x0, - 0x6, 0x44, 0x81, 0x0, 0xc, 0x0, 0x70, 0xb, - 0x0, 0xb2, 0x65, 0x5d, 0x55, 0x52, 0xb, 0x0, - 0xb0, 0x0, 0xc, 0x0, 0x0, 0xb, 0x55, 0xc0, - 0x0, 0xc, 0x0, 0x0, 0x9, 0x0, 0x70, 0x0, - 0xd, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x2, - 0x0, 0x0, - - /* U+8A8C "誌" */ - 0x0, 0x20, 0x0, 0x0, 0x3, 0x0, 0x0, 0x0, - 0x77, 0x0, 0x0, 0xc, 0x0, 0x0, 0x15, 0x6b, - 0x68, 0x0, 0xb, 0x0, 0x20, 0x1, 0x0, 0x0, - 0x65, 0x5c, 0x56, 0xa0, 0x3, 0x55, 0x90, 0x0, - 0xb, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xb, - 0x4, 0x10, 0x3, 0x55, 0x80, 0x26, 0x55, 0x55, - 0x20, 0x1, 0x0, 0x0, 0x0, 0x43, 0x0, 0x0, - 0x6, 0x55, 0x91, 0x8, 0x1c, 0x31, 0x0, 0xb, - 0x0, 0xb0, 0x6b, 0x3, 0x24, 0x90, 0xb, 0x0, - 0xb3, 0x8b, 0x0, 0x3, 0xa4, 0xb, 0x55, 0xc7, - 0x2b, 0x10, 0x19, 0x0, 0xb, 0x0, 0xb0, 0x3, - 0xaa, 0xa5, 0x0, 0x2, 0x0, 0x10, 0x0, 0x0, - 0x0, 0x0, - - /* U+8A8D "認" */ - 0x0, 0x20, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x57, 0x0, 0x14, 0x44, 0x45, 0x70, 0x15, 0x5c, - 0x68, 0x2, 0x76, 0x14, 0xa0, 0x1, 0x0, 0x0, - 0x42, 0x93, 0x4, 0x80, 0x3, 0x55, 0x91, 0xc1, - 0xc0, 0x6, 0x60, 0x1, 0x0, 0x0, 0x27, 0x60, - 0x9, 0x40, 0x3, 0x55, 0x70, 0x38, 0x3, 0x9d, - 0x0, 0x1, 0x0, 0x0, 0x40, 0x35, 0x21, 0x0, - 0x7, 0x55, 0x92, 0x7, 0x1b, 0x21, 0x0, 0xb, - 0x0, 0xb0, 0x6b, 0x3, 0x5, 0x60, 0xb, 0x0, - 0xb4, 0x8b, 0x0, 0x4, 0xb1, 0xb, 0x55, 0xc5, - 0x2b, 0x10, 0x29, 0x10, 0xb, 0x0, 0xa0, 0x3, - 0xaa, 0xa6, 0x0, 0x1, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, - - /* U+8A95 "誕" */ - 0x0, 0x20, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x84, 0x1, 0x15, 0x0, 0x16, 0x90, 0x15, 0x8a, - 0x97, 0x4d, 0x36, 0xb6, 0x20, 0x1, 0x0, 0x0, - 0x57, 0x0, 0x72, 0x0, 0x4, 0x55, 0x80, 0xb1, - 0x5, 0x72, 0x0, 0x0, 0x0, 0x3, 0xa2, 0xb, - 0x77, 0x90, 0x4, 0x55, 0x83, 0x6b, 0x4a, 0x72, - 0x0, 0x0, 0x0, 0x0, 0xa, 0xa, 0x72, 0x0, - 0xa, 0x55, 0xc5, 0xa, 0xa, 0x72, 0x0, 0xa, - 0x0, 0xa1, 0xb6, 0x2c, 0x97, 0x90, 0xa, 0x0, - 0xa0, 0xb9, 0x2, 0x0, 0x0, 0xa, 0x55, 0xb7, - 0x34, 0xc8, 0x53, 0x21, 0x5, 0x0, 0x53, 0x0, - 0x5, 0xac, 0xa1, 0x0, 0x0, 0x10, 0x0, 0x0, - 0x0, 0x0, - - /* U+8A98 "誘" */ - 0x0, 0x20, 0x0, 0x0, 0x0, 0x3, 0x0, 0x0, - 0x85, 0x0, 0x35, 0x7a, 0xbb, 0x20, 0x15, 0x79, - 0x92, 0x0, 0xb, 0x0, 0x0, 0x0, 0x0, 0x2, - 0x65, 0x7d, 0x65, 0xb1, 0x4, 0x55, 0x80, 0x2, - 0xbb, 0x60, 0x0, 0x0, 0x0, 0x0, 0x2a, 0x1b, - 0x2b, 0x10, 0x4, 0x55, 0x74, 0x70, 0xb, 0x3, - 0xd3, 0x0, 0x0, 0x10, 0x46, 0x95, 0x7a, 0x0, - 0xb, 0x55, 0xd1, 0x2, 0xb0, 0x85, 0x0, 0xb, - 0x0, 0xb0, 0x5, 0x70, 0xb5, 0xd1, 0xb, 0x0, - 0xb0, 0xb, 0x10, 0x0, 0xc0, 0xb, 0x55, 0xc0, - 0x75, 0x0, 0x4, 0x90, 0x4, 0x0, 0x26, 0x30, - 0x2, 0xae, 0x20, 0x0, 0x0, 0x10, 0x0, 0x0, - 0x11, 0x0, - - /* U+8A9E "語" */ - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x74, 0x0, 0x22, 0x22, 0x28, 0x0, 0x0, 0x1a, - 0x13, 0x33, 0xb3, 0x33, 0x0, 0x16, 0x55, 0x54, - 0x12, 0xb2, 0x52, 0x0, 0x3, 0x55, 0x80, 0x3, - 0xa2, 0xa3, 0x0, 0x1, 0x0, 0x0, 0x1, 0x80, - 0xa2, 0x0, 0x0, 0x0, 0x41, 0x35, 0x93, 0xc5, - 0xa0, 0x4, 0x55, 0x51, 0x42, 0x22, 0x22, 0x20, - 0x6, 0x55, 0x81, 0x1a, 0x44, 0x4d, 0x0, 0xb, - 0x0, 0xb0, 0xb, 0x0, 0xc, 0x0, 0xb, 0x0, - 0xb0, 0xb, 0x0, 0xc, 0x0, 0xb, 0x55, 0xc0, - 0xd, 0x55, 0x5c, 0x0, 0xa, 0x0, 0x80, 0x1a, - 0x0, 0xa, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, - - /* U+8AAA "說" */ - 0x0, 0x20, 0x0, 0x0, 0x30, 0x30, 0x0, 0x0, - 0x57, 0x0, 0x2, 0xd1, 0x70, 0x0, 0x15, 0x5c, - 0x68, 0xa, 0x20, 0x64, 0x0, 0x1, 0x0, 0x0, - 0x65, 0x0, 0xc, 0x40, 0x3, 0x55, 0x94, 0x58, - 0x55, 0x5c, 0xb2, 0x0, 0x0, 0x0, 0xb, 0x0, - 0xa, 0x0, 0x3, 0x55, 0x90, 0xb, 0x0, 0xa, - 0x0, 0x1, 0x0, 0x0, 0xc, 0x33, 0x3b, 0x0, - 0x7, 0x55, 0x92, 0x7, 0xb3, 0xc5, 0x0, 0xb, - 0x0, 0xb0, 0x0, 0xb0, 0xb0, 0x0, 0xb, 0x0, - 0xb0, 0x1, 0xa0, 0xb0, 0x30, 0xb, 0x55, 0xc0, - 0x8, 0x30, 0xb0, 0x60, 0xb, 0x0, 0xa0, 0x64, - 0x0, 0xb9, 0xd1, 0x1, 0x0, 0x3, 0x10, 0x0, - 0x0, 0x0, - - /* U+8AAC "説" */ - 0x0, 0x20, 0x0, 0x10, 0x0, 0x23, 0x0, 0x0, - 0x77, 0x0, 0xa, 0x0, 0x78, 0x0, 0x15, 0x6b, - 0x75, 0x8, 0x50, 0x90, 0x0, 0x1, 0x0, 0x0, - 0x44, 0x44, 0x66, 0x0, 0x4, 0x55, 0x91, 0xb3, - 0x33, 0x3b, 0x10, 0x0, 0x0, 0x0, 0xb0, 0x0, - 0xa, 0x0, 0x4, 0x55, 0x90, 0xb0, 0x0, 0xa, - 0x0, 0x0, 0x0, 0x0, 0xb6, 0x85, 0x8b, 0x0, - 0xa, 0x55, 0xc2, 0x32, 0xa1, 0xa0, 0x0, 0xb, - 0x0, 0xb0, 0x4, 0x91, 0xa0, 0x0, 0xb, 0x0, - 0xb0, 0x9, 0x41, 0xa0, 0x50, 0xb, 0x55, 0xc0, - 0x3a, 0x1, 0xa0, 0x70, 0x9, 0x0, 0x45, 0x80, - 0x0, 0xc9, 0xd2, 0x0, 0x0, 0x32, 0x0, 0x0, - 0x0, 0x0, - - /* U+8AAD "読" */ - 0x0, 0x20, 0x0, 0x0, 0x3, 0x0, 0x0, 0x0, - 0x74, 0x0, 0x0, 0xc, 0x0, 0x0, 0x15, 0x78, - 0x94, 0x55, 0x5c, 0x56, 0xa0, 0x0, 0x0, 0x0, - 0x0, 0xa, 0x0, 0x0, 0x4, 0x55, 0x91, 0x16, - 0x5a, 0x58, 0x30, 0x0, 0x0, 0x0, 0x30, 0x0, - 0x0, 0x20, 0x4, 0x55, 0x81, 0xb5, 0x55, 0x55, - 0xe1, 0x0, 0x0, 0x13, 0x52, 0x80, 0x74, 0x10, - 0xb, 0x55, 0xd1, 0x3, 0xa0, 0xb0, 0x0, 0xb, - 0x0, 0xb0, 0x5, 0x80, 0xb0, 0x20, 0xb, 0x0, - 0xb0, 0xa, 0x30, 0xb0, 0x40, 0xb, 0x55, 0xc0, - 0x4a, 0x0, 0xb0, 0x70, 0x7, 0x0, 0x25, 0x80, - 0x0, 0xba, 0xd1, 0x0, 0x0, 0x32, 0x0, 0x0, - 0x0, 0x0, - - /* U+8AB0 "誰" */ - 0x0, 0x10, 0x0, 0x2, 0x10, 0x0, 0x0, 0x0, - 0x65, 0x0, 0x7, 0x59, 0x40, 0x0, 0x13, 0x3b, - 0x46, 0xb, 0x1, 0x71, 0x10, 0x3, 0x22, 0x22, - 0x3d, 0x59, 0x57, 0x60, 0x4, 0x55, 0x80, 0xab, - 0xa, 0x0, 0x0, 0x1, 0x0, 0x4, 0x5b, 0xa, - 0x5, 0x10, 0x4, 0x55, 0x93, 0xc, 0x4c, 0x54, - 0x20, 0x1, 0x0, 0x0, 0xb, 0xa, 0x0, 0x0, - 0x5, 0x44, 0x81, 0xb, 0xa, 0x4, 0x10, 0xb, - 0x11, 0xb1, 0xc, 0x5c, 0x55, 0x30, 0xb, 0x0, - 0xb0, 0xb, 0xa, 0x0, 0x0, 0xb, 0x55, 0xc0, - 0xb, 0xa, 0x2, 0x50, 0xb, 0x0, 0xa0, 0xd, - 0x55, 0x55, 0x50, 0x1, 0x0, 0x0, 0x2, 0x0, - 0x0, 0x0, - - /* U+8AB2 "課" */ - 0x0, 0x10, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x84, 0x0, 0xa5, 0x58, 0x5d, 0x20, 0x15, 0x89, - 0x84, 0xb0, 0xb, 0xb, 0x0, 0x1, 0x0, 0x0, - 0xb5, 0x5c, 0x5c, 0x0, 0x5, 0x55, 0x90, 0xb0, - 0xb, 0xb, 0x0, 0x0, 0x0, 0x0, 0xb5, 0x5c, - 0x5c, 0x0, 0x5, 0x55, 0x80, 0x40, 0xb, 0x3, - 0x0, 0x0, 0x0, 0x2, 0x55, 0x5c, 0x56, 0xc2, - 0xa, 0x55, 0xd1, 0x0, 0xec, 0x40, 0x0, 0xb, - 0x0, 0xb0, 0x8, 0x6b, 0x80, 0x0, 0xb, 0x0, - 0xb0, 0x3a, 0xb, 0x48, 0x0, 0xb, 0x55, 0xc2, - 0x90, 0xb, 0xa, 0xa2, 0x5, 0x0, 0x34, 0x0, - 0xc, 0x0, 0x51, 0x0, 0x0, 0x0, 0x0, 0x1, - 0x0, 0x0, - - /* U+8ABF "調" */ - 0x0, 0x10, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x94, 0x0, 0x95, 0x56, 0x55, 0xd0, 0x14, 0x79, - 0x64, 0xb0, 0xb, 0x0, 0xb0, 0x2, 0x11, 0x11, - 0xb2, 0x5c, 0x74, 0xb0, 0x4, 0x54, 0x81, 0xb0, - 0xa, 0x0, 0xb0, 0x0, 0x0, 0x0, 0xb4, 0x5c, - 0x57, 0xb0, 0x5, 0x65, 0x91, 0xb1, 0x0, 0x0, - 0xb0, 0x0, 0x0, 0x0, 0xb2, 0xa5, 0xb3, 0xb0, - 0x9, 0x55, 0xb2, 0xb1, 0x80, 0x91, 0xb0, 0xb, - 0x0, 0xb0, 0xb2, 0xb5, 0xb1, 0xb0, 0xb, 0x0, - 0xb3, 0x71, 0x50, 0x50, 0xb0, 0xb, 0x55, 0xb8, - 0x10, 0x0, 0x32, 0xb0, 0x4, 0x0, 0x24, 0x0, - 0x0, 0x1b, 0x70, 0x0, 0x0, 0x10, 0x0, 0x0, - 0x0, 0x0, - - /* U+8AC7 "談" */ - 0x0, 0x20, 0x0, 0x0, 0x30, 0x0, 0x0, 0x0, - 0x95, 0x0, 0x1, 0xa2, 0x5, 0x20, 0x15, 0x89, - 0x85, 0x17, 0xa1, 0x8a, 0x30, 0x1, 0x0, 0x0, - 0xc3, 0xb8, 0x30, 0x0, 0x5, 0x55, 0x90, 0x21, - 0xe5, 0x60, 0x0, 0x0, 0x0, 0x0, 0xa, 0x50, - 0x3d, 0x20, 0x5, 0x55, 0x82, 0x72, 0x94, 0x3, - 0x30, 0x0, 0x0, 0x0, 0x2, 0xa3, 0x6, 0x0, - 0x9, 0x55, 0xb2, 0x55, 0xc6, 0x98, 0x20, 0xb, - 0x0, 0xb1, 0xb1, 0xc8, 0x0, 0x0, 0xb, 0x0, - 0xb0, 0x7, 0x67, 0x30, 0x0, 0xb, 0x55, 0xc0, - 0x1b, 0x1, 0xd2, 0x0, 0xb, 0x0, 0x83, 0x80, - 0x0, 0x4f, 0x91, 0x1, 0x0, 0x34, 0x0, 0x0, - 0x3, 0x30, - - /* U+8ACB "請" */ - 0x0, 0x10, 0x0, 0x0, 0x1, 0x0, 0x0, 0x0, - 0x57, 0x0, 0x0, 0xc, 0x0, 0x0, 0x14, 0x4c, - 0x75, 0x55, 0x5c, 0x58, 0x80, 0x2, 0x11, 0x11, - 0x0, 0xb, 0x5, 0x0, 0x2, 0x44, 0x81, 0x16, - 0x5c, 0x55, 0x20, 0x1, 0x11, 0x12, 0x65, 0x5b, - 0x56, 0xa0, 0x2, 0x33, 0x71, 0x2, 0x0, 0x4, - 0x0, 0x1, 0x21, 0x10, 0xc, 0x55, 0x5c, 0x20, - 0x6, 0x55, 0x92, 0xc, 0x55, 0x5c, 0x0, 0xb, - 0x0, 0xb0, 0xb, 0x0, 0xb, 0x0, 0xb, 0x0, - 0xb0, 0xc, 0x55, 0x5c, 0x0, 0xb, 0x55, 0xc0, - 0xb, 0x0, 0xb, 0x0, 0x7, 0x0, 0x50, 0xa, - 0x4, 0xad, 0x0, 0x0, 0x0, 0x0, 0x1, 0x0, - 0x1, 0x0, - - /* U+8AD6 "論" */ - 0x0, 0x20, 0x0, 0x0, 0x14, 0x0, 0x0, 0x0, - 0x76, 0x0, 0x0, 0x6d, 0x0, 0x0, 0x15, 0x6b, - 0x67, 0x0, 0xd5, 0x20, 0x0, 0x1, 0x0, 0x0, - 0x8, 0x50, 0x90, 0x0, 0x3, 0x44, 0x80, 0x57, - 0x0, 0x5b, 0x10, 0x1, 0x21, 0x16, 0x56, 0x55, - 0x95, 0xd4, 0x3, 0x55, 0x90, 0x65, 0x55, 0x55, - 0x80, 0x1, 0x0, 0x0, 0xa0, 0xa0, 0xa0, 0x90, - 0x6, 0x55, 0x90, 0xa0, 0xa0, 0xa0, 0x90, 0xa, - 0x0, 0xb0, 0xb5, 0xc5, 0xc5, 0x90, 0xa, 0x0, - 0xa0, 0xa0, 0xa0, 0xa0, 0x90, 0xa, 0x55, 0xb0, - 0xa0, 0xa0, 0x80, 0x90, 0xa, 0x0, 0xa0, 0xa0, - 0x0, 0x4b, 0x80, 0x1, 0x0, 0x0, 0x10, 0x0, - 0x2, 0x0, - - /* U+8AF8 "諸" */ - 0x0, 0x10, 0x0, 0x0, 0x20, 0x0, 0x0, 0x0, - 0x84, 0x0, 0x0, 0xb1, 0x2, 0x30, 0x14, 0x69, - 0x73, 0x0, 0xa0, 0x3a, 0x70, 0x2, 0x0, 0x0, - 0x45, 0xc5, 0x8a, 0x0, 0x5, 0x55, 0x90, 0x0, - 0xa0, 0xc1, 0x20, 0x0, 0x0, 0x3, 0x65, 0x8b, - 0x86, 0x90, 0x5, 0x55, 0x80, 0x0, 0x84, 0x0, - 0x0, 0x0, 0x0, 0x0, 0x1b, 0x85, 0x5b, 0x10, - 0x9, 0x55, 0xd4, 0x8a, 0x0, 0xb, 0x0, 0xb, - 0x0, 0xb2, 0x1c, 0x55, 0x5c, 0x0, 0xb, 0x0, - 0xb0, 0x1a, 0x0, 0xb, 0x0, 0xb, 0x44, 0xc0, - 0x1c, 0x55, 0x5c, 0x0, 0x7, 0x0, 0x50, 0x17, - 0x0, 0x8, 0x0, - - /* U+8B02 "謂" */ - 0x0, 0x20, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x67, 0x0, 0x95, 0x57, 0x56, 0xb0, 0x25, 0x6b, - 0x78, 0xb0, 0xb, 0x1, 0x90, 0x0, 0x0, 0x0, - 0xb5, 0x5c, 0x56, 0x90, 0x5, 0x55, 0x92, 0xb0, - 0xb, 0x1, 0x90, 0x0, 0x0, 0x0, 0xb5, 0x57, - 0x56, 0x70, 0x5, 0x55, 0x81, 0x16, 0x55, 0x59, - 0x20, 0x0, 0x0, 0x0, 0x19, 0x0, 0xb, 0x0, - 0xa, 0x55, 0xc2, 0x1b, 0x55, 0x5c, 0x0, 0xb, - 0x0, 0xb0, 0x19, 0x0, 0xb, 0x0, 0xb, 0x0, - 0xb0, 0x1b, 0x44, 0x4c, 0x0, 0xb, 0x55, 0xc0, - 0x19, 0x0, 0xb, 0x0, 0x8, 0x0, 0x60, 0x29, - 0x1, 0x8c, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x1, 0x0, - - /* U+8B1B "講" */ - 0x0, 0x10, 0x0, 0x2, 0x0, 0x20, 0x0, 0x0, - 0x85, 0x0, 0x9, 0x40, 0xb0, 0x10, 0x12, 0x4a, - 0x64, 0x6b, 0x65, 0xc5, 0x80, 0x14, 0x33, 0x31, - 0x9, 0x20, 0xa1, 0x20, 0x3, 0x44, 0x70, 0x6b, - 0x65, 0xc5, 0x40, 0x0, 0x0, 0x4, 0x57, 0x67, - 0x85, 0x82, 0x5, 0x55, 0x80, 0x55, 0x5d, 0x58, - 0x20, 0x0, 0x0, 0x0, 0x91, 0xa, 0xa, 0x0, - 0x9, 0x55, 0xb0, 0x95, 0x5c, 0x5c, 0x0, 0xa, - 0x0, 0xa0, 0x91, 0xa, 0xa, 0x10, 0xa, 0x0, - 0xa4, 0xb5, 0x59, 0x5c, 0x91, 0xb, 0x55, 0xa0, - 0x91, 0x0, 0xa, 0x0, 0x7, 0x0, 0x40, 0xa0, - 0x2, 0x8d, 0x0, 0x0, 0x0, 0x0, 0x10, 0x0, - 0x2, 0x0, - - /* U+8B1D "謝" */ - 0x0, 0x0, 0x0, 0x2, 0x0, 0x0, 0x0, 0x0, - 0x92, 0x0, 0xa, 0x0, 0xa, 0x10, 0x0, 0x57, - 0x43, 0x86, 0x80, 0xa, 0x0, 0x16, 0x55, 0x57, - 0x40, 0xa0, 0xa, 0x0, 0x4, 0x56, 0x75, 0x74, - 0xb4, 0x5c, 0x80, 0x1, 0x0, 0x5, 0x40, 0xa0, - 0xa, 0x0, 0x3, 0x55, 0x85, 0x75, 0xb6, 0x2a, - 0x0, 0x1, 0x0, 0x6, 0x41, 0xa0, 0xda, 0x0, - 0x7, 0x55, 0x95, 0x4c, 0xc0, 0x3a, 0x0, 0xa, - 0x0, 0xa0, 0x29, 0xa0, 0xa, 0x0, 0xa, 0x0, - 0xa0, 0x90, 0xa0, 0xa, 0x0, 0xa, 0x55, 0xa7, - 0x20, 0xa0, 0x1b, 0x0, 0x6, 0x0, 0x51, 0x1a, - 0xb1, 0x8c, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, - - /* U+8B58 "識" */ - 0x0, 0x0, 0x0, 0x0, 0x0, 0x10, 0x0, 0x1, - 0x70, 0x0, 0x83, 0x0, 0xb0, 0x0, 0x0, 0x84, - 0x25, 0x89, 0x83, 0xa6, 0x30, 0x16, 0x55, 0x35, - 0x10, 0xa1, 0xa0, 0xa0, 0x3, 0x48, 0x2, 0xa2, - 0x80, 0xa0, 0x0, 0x1, 0x0, 0x45, 0x79, 0x55, - 0xc5, 0xb0, 0x4, 0x59, 0x23, 0x0, 0x30, 0xa0, - 0x70, 0x1, 0x0, 0xb, 0x55, 0xc0, 0xa4, 0x90, - 0x8, 0x5a, 0x3a, 0x0, 0xa0, 0x9b, 0x20, 0xa, - 0x9, 0xa, 0x55, 0xa0, 0x6b, 0x0, 0xa, 0x9, - 0x1a, 0x0, 0xa0, 0xba, 0x4, 0xb, 0x5b, 0x1b, - 0x55, 0xa7, 0x48, 0xa3, 0x7, 0x6, 0x3, 0x0, - 0x64, 0x0, 0xa3, 0x0, 0x0, 0x0, 0x0, 0x10, - 0x0, 0x0, - - /* U+8B70 "議" */ - 0x0, 0x10, 0x0, 0x3, 0x0, 0x52, 0x0, 0x0, - 0xa3, 0x0, 0x4, 0x90, 0xb2, 0x0, 0x25, 0x98, - 0x93, 0x65, 0x98, 0x68, 0x70, 0x1, 0x0, 0x0, - 0x1, 0x46, 0x15, 0x0, 0x5, 0x56, 0x60, 0x25, - 0x78, 0x44, 0x0, 0x0, 0x0, 0x2, 0x65, 0x78, - 0x56, 0xb0, 0x5, 0x56, 0x70, 0x3, 0x77, 0x25, - 0x0, 0x0, 0x0, 0x1, 0x6c, 0x39, 0x6, 0x30, - 0x9, 0x55, 0xc4, 0x5c, 0x5b, 0x65, 0xb2, 0xa, - 0x0, 0xa0, 0xa, 0x26, 0x46, 0x20, 0xa, 0x0, - 0xa5, 0x9d, 0x22, 0xc9, 0x0, 0xb, 0x55, 0xa3, - 0xa, 0x5, 0xd4, 0x21, 0x6, 0x0, 0x51, 0x7c, - 0x54, 0xa, 0xc1, 0x0, 0x0, 0x0, 0x1, 0x0, - 0x0, 0x31, - - /* U+8B77 "護" */ - 0x0, 0x20, 0x0, 0x3, 0x10, 0x40, 0x0, 0x0, - 0xa4, 0x0, 0x7, 0x40, 0xb0, 0x40, 0x25, 0x99, - 0x87, 0x5a, 0x95, 0xc5, 0x52, 0x1, 0x0, 0x0, - 0x66, 0x1b, 0x20, 0x10, 0x5, 0x55, 0x80, 0xd5, - 0x5c, 0x57, 0x80, 0x0, 0x0, 0x6, 0xd4, 0x4c, - 0x58, 0x20, 0x5, 0x55, 0x73, 0xa5, 0x5c, 0x58, - 0x20, 0x0, 0x0, 0x0, 0xa1, 0x1a, 0x11, 0x80, - 0xb, 0x55, 0xc0, 0x74, 0x44, 0x47, 0x41, 0xa, - 0x0, 0xa1, 0x68, 0x55, 0x8d, 0x0, 0xa, 0x0, - 0xa0, 0x3, 0x53, 0xa1, 0x0, 0xb, 0x55, 0xa0, - 0x1, 0xbc, 0x10, 0x0, 0x3, 0x0, 0x33, 0x55, - 0x1, 0x9a, 0x92, - - /* U+8B8A "變" */ - 0x0, 0x0, 0x0, 0x40, 0x0, 0x1, 0x0, 0x0, - 0x85, 0x0, 0x44, 0x30, 0x2a, 0x0, 0x4, 0x77, - 0x36, 0x55, 0x82, 0x85, 0x70, 0x9, 0x8a, 0x14, - 0x66, 0x86, 0x9c, 0x30, 0x5, 0x96, 0x74, 0x33, - 0x51, 0x96, 0x80, 0x4, 0x86, 0x96, 0x75, 0xb0, - 0xa7, 0x82, 0x6, 0x44, 0x96, 0x75, 0x91, 0x57, - 0x71, 0x6, 0x15, 0x53, 0x10, 0x35, 0x15, 0x22, - 0x0, 0x3, 0xf6, 0x55, 0x56, 0x7a, 0x0, 0x0, - 0x2a, 0x33, 0x0, 0x49, 0x0, 0x0, 0x0, 0x40, - 0x4, 0x65, 0x90, 0x0, 0x0, 0x0, 0x0, 0x4, - 0xbc, 0x40, 0x0, 0x0, 0x2, 0x46, 0x74, 0x0, - 0x5a, 0xbb, 0x60, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, - - /* U+8B93 "讓" */ - 0x0, 0x0, 0x0, 0x0, 0x20, 0x0, 0x0, 0x1, - 0x80, 0x0, 0x0, 0x57, 0x0, 0x20, 0x0, 0x75, - 0x34, 0x55, 0x57, 0x55, 0x91, 0x26, 0x55, 0x50, - 0x84, 0x95, 0x54, 0x80, 0x5, 0x55, 0x50, 0xb5, - 0xa6, 0x75, 0x90, 0x0, 0x0, 0x0, 0x34, 0x32, - 0x50, 0x20, 0x4, 0x57, 0x53, 0x6a, 0x65, 0xc6, - 0xa0, 0x0, 0x0, 0x0, 0x8, 0x10, 0x91, 0x40, - 0x8, 0x55, 0x90, 0x6a, 0x65, 0xb5, 0x60, 0x9, - 0x0, 0x95, 0x59, 0x96, 0x86, 0x92, 0x9, 0x0, - 0x90, 0x1c, 0x27, 0x38, 0x30, 0xa, 0x55, 0x93, - 0x8b, 0x3, 0xb3, 0x0, 0x5, 0x0, 0x23, 0xb, - 0x70, 0x9, 0xc2, 0x0, 0x0, 0x0, 0x1, 0x0, - 0x0, 0x0, - - /* U+8BA1 "计" */ - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x46, 0x0, 0x0, 0xb3, 0x0, 0x0, 0x0, 0xb, - 0x40, 0x0, 0xb2, 0x0, 0x0, 0x0, 0x1, 0x0, - 0x0, 0xb2, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0xb2, 0x0, 0x0, 0x16, 0x5c, 0x16, 0x55, 0xc6, - 0x56, 0xb0, 0x0, 0xb, 0x0, 0x0, 0xb2, 0x0, - 0x0, 0x0, 0xb, 0x0, 0x0, 0xb2, 0x0, 0x0, - 0x0, 0xb, 0x0, 0x0, 0xb2, 0x0, 0x0, 0x0, - 0xb, 0x3, 0x0, 0xb2, 0x0, 0x0, 0x0, 0xb, - 0x82, 0x0, 0xb2, 0x0, 0x0, 0x0, 0x1f, 0x60, - 0x0, 0xb2, 0x0, 0x0, 0x0, 0x6, 0x0, 0x0, - 0xb2, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x10, - 0x0, 0x0, - - /* U+8BDE "诞" */ - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x4, - 0x20, 0x0, 0x40, 0x0, 0x2a, 0x80, 0x0, 0xd0, - 0x67, 0xd2, 0x68, 0xd3, 0x0, 0x0, 0x20, 0x7, - 0x50, 0x0, 0xb0, 0x0, 0x0, 0x0, 0xb, 0x0, - 0x50, 0xb0, 0x0, 0x26, 0xb2, 0x58, 0x30, 0xc0, - 0xc6, 0xa0, 0x0, 0xb0, 0x56, 0xc3, 0xa0, 0xb0, - 0x0, 0x0, 0xb0, 0x20, 0xb0, 0xa0, 0xb0, 0x0, - 0x0, 0xb0, 0x34, 0xb0, 0xa0, 0xb0, 0x10, 0x0, - 0xb0, 0x3c, 0x51, 0xc5, 0x85, 0x90, 0x0, 0xb9, - 0x1b, 0x90, 0x0, 0x0, 0x0, 0x0, 0xa2, 0x81, - 0x2b, 0x96, 0x43, 0x20, 0x0, 0x16, 0x10, 0x0, - 0x37, 0xac, 0x90, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, - - /* U+8C50 "豐" */ - 0x0, 0x0, 0x30, 0x41, 0x2, 0x0, 0x0, 0x0, - 0xb0, 0x93, 0xa1, 0xb, 0x1a, 0x0, 0x0, 0xa4, - 0xc5, 0x93, 0x6b, 0x3a, 0x0, 0x0, 0xa4, 0xb7, - 0x93, 0x6c, 0x5a, 0x0, 0x0, 0xa3, 0xb7, 0x93, - 0x5b, 0x4a, 0x0, 0x1, 0xd5, 0xb5, 0xb5, 0x5b, - 0x5a, 0x0, 0x0, 0x20, 0x0, 0x0, 0x0, 0x6, - 0x0, 0x2, 0x65, 0x55, 0x55, 0x55, 0x57, 0x30, - 0x0, 0x7, 0x55, 0x55, 0x55, 0xa0, 0x0, 0x0, - 0xa, 0x0, 0x0, 0x0, 0xb0, 0x0, 0x0, 0xa, - 0x65, 0x55, 0x56, 0xa0, 0x0, 0x0, 0x1, 0x47, - 0x0, 0x68, 0x0, 0x0, 0x5, 0x55, 0x5a, 0x55, - 0xa5, 0x57, 0xd1, 0x1, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, - - /* U+8C61 "象" */ - 0x0, 0x0, 0x20, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x5d, 0x10, 0x13, 0x0, 0x0, 0x0, 0x4b, 0x55, - 0x5c, 0x80, 0x0, 0x0, 0x5d, 0x55, 0x58, 0x75, - 0x58, 0x0, 0x42, 0xb0, 0x3, 0xa0, 0x2, 0xa0, - 0x0, 0xd, 0x55, 0xa9, 0x55, 0x6a, 0x0, 0x0, - 0x70, 0x3d, 0x10, 0x2, 0x70, 0x0, 0x0, 0x67, - 0x3b, 0x6, 0x95, 0x0, 0x3, 0x62, 0x59, 0x79, - 0x60, 0x0, 0x0, 0x2, 0x85, 0x2b, 0xb3, 0x60, - 0x0, 0x4, 0x40, 0x59, 0xd, 0x9, 0x80, 0x0, - 0x3, 0x84, 0x2, 0xc0, 0x8, 0xe4, 0x35, 0x30, - 0x4b, 0xe4, 0x0, 0x1, 0x0, 0x0, 0x0, 0x12, - 0x0, 0x0, 0x0, - - /* U+8CA0 "負" */ - 0x0, 0x0, 0x4, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x6c, 0x10, 0x21, 0x0, 0x0, 0x3, 0xc5, 0x55, - 0xd8, 0x0, 0x0, 0x3a, 0x10, 0x5, 0x60, 0x0, - 0x5, 0x75, 0x22, 0x38, 0x23, 0x70, 0x1, 0x2b, - 0x22, 0x22, 0x23, 0xb0, 0x0, 0x1c, 0x55, 0x55, - 0x56, 0xa0, 0x0, 0x1a, 0x0, 0x0, 0x1, 0xa0, - 0x0, 0x1c, 0x55, 0x55, 0x56, 0xa0, 0x0, 0x2a, - 0x0, 0x0, 0x1, 0xa0, 0x0, 0x2a, 0x85, 0x55, - 0x76, 0x90, 0x0, 0x4, 0xd4, 0x0, 0x4a, 0x60, - 0x0, 0x77, 0x0, 0x0, 0x0, 0xb6, 0x2, 0x0, - 0x0, 0x0, 0x0, 0x1, - - /* U+8CA1 "財" */ - 0x0, 0x0, 0x0, 0x0, 0x0, 0x20, 0x0, 0x7, - 0x55, 0x59, 0x0, 0x0, 0xb2, 0x0, 0xb, 0x0, - 0xb, 0x0, 0x0, 0xb0, 0x0, 0xb, 0x0, 0xb, - 0x0, 0x0, 0xb0, 0x50, 0xb, 0x55, 0x5b, 0x35, - 0x59, 0xf5, 0x50, 0xb, 0x0, 0xb, 0x0, 0xc, - 0xc0, 0x0, 0xb, 0x55, 0x5b, 0x0, 0x49, 0xb0, - 0x0, 0xb, 0x0, 0xb, 0x0, 0xb1, 0xb0, 0x0, - 0xb, 0x0, 0xb, 0x7, 0x40, 0xb0, 0x0, 0xb, - 0x55, 0x5a, 0x36, 0x0, 0xb0, 0x0, 0x1, 0x82, - 0x52, 0x50, 0x0, 0xb0, 0x0, 0x4, 0x90, 0x1b, - 0x0, 0x0, 0xb0, 0x0, 0x28, 0x0, 0x8, 0x10, - 0x4a, 0xe0, 0x0, 0x10, 0x0, 0x0, 0x0, 0x1, - 0x30, 0x0, - - /* U+8CA7 "貧" */ - 0x0, 0x0, 0x0, 0x3, 0x0, 0x0, 0x0, 0x0, - 0x98, 0x0, 0x61, 0x0, 0x0, 0x0, 0x85, 0x0, - 0x0, 0x86, 0x0, 0x2, 0x73, 0x6a, 0x75, 0x5c, - 0x9d, 0x80, 0x0, 0x6, 0x80, 0x0, 0xc0, 0x0, - 0x0, 0x27, 0x40, 0x2, 0xa8, 0x0, 0x0, 0x12, - 0x95, 0x55, 0x56, 0x5c, 0x0, 0x0, 0xb, 0x55, - 0x55, 0x55, 0xb0, 0x0, 0x0, 0xb0, 0x0, 0x0, - 0xb, 0x0, 0x0, 0xb, 0x55, 0x55, 0x55, 0xc0, - 0x0, 0x0, 0xb5, 0x55, 0x55, 0x5b, 0x0, 0x0, - 0x2, 0x5c, 0x0, 0x37, 0x82, 0x0, 0x4, 0x85, - 0x0, 0x0, 0x2, 0xc3, 0x2, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x0, - - /* U+8CA9 "販" */ - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x7, - 0x55, 0x59, 0x1, 0x25, 0x9c, 0x70, 0xb, 0x0, - 0xb, 0xc, 0x31, 0x0, 0x0, 0xb, 0x11, 0x1b, - 0xa, 0x0, 0x0, 0x0, 0xb, 0x33, 0x3b, 0xc, - 0x55, 0x58, 0x10, 0xb, 0x0, 0xb, 0xa, 0x50, - 0xc, 0x0, 0xb, 0x55, 0x5b, 0x19, 0x60, 0x29, - 0x0, 0xb, 0x0, 0xb, 0x18, 0x43, 0x65, 0x0, - 0xb, 0x0, 0xb, 0x46, 0x8, 0xb0, 0x0, 0xb, - 0x55, 0x5b, 0x63, 0x9, 0x80, 0x0, 0x1, 0xb1, - 0x91, 0x80, 0x1b, 0xa0, 0x0, 0x6, 0x60, 0x57, - 0x60, 0x91, 0x5b, 0x10, 0x17, 0x0, 0x5, 0x25, - 0x0, 0x7, 0xa0, 0x20, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, - - /* U+8CAC "責" */ - 0x0, 0x0, 0x1, 0x20, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x2b, 0x0, 0x7, 0x0, 0x6, 0x55, 0x56, - 0xb5, 0x56, 0x52, 0x0, 0x6, 0x55, 0x6b, 0x55, - 0x85, 0x0, 0x11, 0x11, 0x13, 0xa1, 0x11, 0x2a, - 0x4, 0x47, 0x44, 0x44, 0x44, 0x75, 0x41, 0x0, - 0xc5, 0x55, 0x55, 0x59, 0x60, 0x0, 0xc, 0x44, - 0x44, 0x44, 0x95, 0x0, 0x0, 0xc5, 0x55, 0x55, - 0x59, 0x50, 0x0, 0xc, 0x0, 0x0, 0x0, 0x75, - 0x0, 0x0, 0xb5, 0x75, 0x55, 0x59, 0x40, 0x0, - 0x0, 0x8c, 0x10, 0x48, 0x82, 0x0, 0x5, 0x94, - 0x0, 0x0, 0x3, 0xd3, 0x2, 0x10, 0x0, 0x0, - 0x0, 0x1, 0x0, - - /* U+8CB7 "買" */ - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xa, 0x55, - 0x85, 0x58, 0x55, 0xc0, 0xc, 0x0, 0xb0, 0xb, - 0x1, 0xa0, 0xc, 0x0, 0xb0, 0xb, 0x1, 0xa0, - 0x9, 0x55, 0x55, 0x55, 0x55, 0x70, 0x0, 0x95, - 0x55, 0x55, 0x5c, 0x0, 0x0, 0xc0, 0x0, 0x0, - 0xc, 0x0, 0x0, 0xc5, 0x55, 0x55, 0x5c, 0x0, - 0x0, 0xc5, 0x55, 0x55, 0x5c, 0x0, 0x0, 0xc0, - 0x0, 0x0, 0xc, 0x0, 0x0, 0xb5, 0x75, 0x55, - 0x59, 0x0, 0x0, 0x1b, 0x90, 0x3, 0x78, 0x20, - 0x6, 0x82, 0x0, 0x0, 0x3, 0xd0, 0x20, 0x0, - 0x0, 0x0, 0x0, 0x0, - - /* U+8CB8 "貸" */ - 0x0, 0x0, 0x11, 0x1, 0x11, 0x0, 0x0, 0x0, - 0xc, 0x60, 0xc0, 0xa5, 0x0, 0x0, 0x1c, 0x40, - 0xa, 0x12, 0x39, 0x20, 0x48, 0x93, 0x55, 0x7a, - 0x43, 0x32, 0x11, 0x8, 0x20, 0x0, 0x86, 0x0, - 0x50, 0x0, 0x71, 0x0, 0x0, 0x7b, 0x78, 0x0, - 0xb, 0x55, 0x55, 0x55, 0xd5, 0x50, 0x0, 0xc5, - 0x55, 0x55, 0x5c, 0x0, 0x0, 0xc, 0x0, 0x0, - 0x0, 0xc0, 0x0, 0x0, 0xc5, 0x55, 0x55, 0x5c, - 0x0, 0x0, 0xc, 0x55, 0x55, 0x55, 0xc0, 0x0, - 0x0, 0x19, 0xa0, 0x2, 0x78, 0x20, 0x0, 0x59, - 0x30, 0x0, 0x0, 0x4d, 0x0, 0x20, 0x0, 0x0, - 0x0, 0x0, 0x0, - - /* U+8CBB "費" */ - 0x0, 0x0, 0x20, 0x2, 0x0, 0x0, 0x0, 0x0, - 0xa1, 0xc, 0x3, 0x0, 0x4, 0x55, 0xc5, 0x5c, - 0x5c, 0x20, 0x5, 0x95, 0xc5, 0x5c, 0x5a, 0x0, - 0x9, 0x95, 0xc5, 0x5c, 0x55, 0x69, 0x0, 0x8, - 0x20, 0xa, 0x3, 0x84, 0x14, 0x95, 0x44, 0x49, - 0x48, 0x60, 0x0, 0xb1, 0x11, 0x11, 0x1c, 0x0, - 0x0, 0xb5, 0x55, 0x55, 0x5b, 0x0, 0x0, 0xb5, - 0x55, 0x55, 0x5b, 0x0, 0x0, 0xb5, 0x55, 0x55, - 0x5b, 0x0, 0x0, 0x49, 0x50, 0x4, 0x78, 0x0, - 0x5, 0x94, 0x0, 0x0, 0x5, 0xd1, 0x21, 0x0, - 0x0, 0x0, 0x0, 0x20, - - /* U+8CBF "貿" */ - 0x0, 0x0, 0x60, 0x0, 0x0, 0x0, 0x5, 0x58, - 0x63, 0x55, 0x55, 0x93, 0xb, 0x1, 0x50, 0x1c, - 0x0, 0xb0, 0xb, 0x0, 0xa5, 0x29, 0x0, 0xc0, - 0xc, 0x87, 0x23, 0xa1, 0x58, 0x90, 0x5, 0x10, - 0x16, 0x10, 0x7, 0x10, 0x0, 0x95, 0x55, 0x55, - 0x5d, 0x10, 0x0, 0xb5, 0x55, 0x55, 0x5c, 0x0, - 0x0, 0xb0, 0x0, 0x0, 0xc, 0x0, 0x0, 0xb5, - 0x55, 0x55, 0x5d, 0x0, 0x0, 0xb5, 0x65, 0x55, - 0x5c, 0x0, 0x0, 0x17, 0xc0, 0x2, 0x78, 0x10, - 0x4, 0x84, 0x0, 0x0, 0x4, 0xd0, 0x21, 0x0, - 0x0, 0x0, 0x0, 0x0, - - /* U+8CC3 "賃" */ - 0x0, 0x3, 0x0, 0x0, 0x0, 0x0, 0x0, 0x5b, - 0x23, 0x68, 0x9b, 0x70, 0x3, 0xc0, 0x11, 0x1b, - 0x0, 0x0, 0x37, 0xb3, 0x65, 0x5c, 0x55, 0x86, - 0x20, 0xb0, 0x0, 0xb, 0x0, 0x20, 0x0, 0x70, - 0x36, 0x57, 0x57, 0x70, 0x0, 0x95, 0x55, 0x55, - 0x5d, 0x0, 0x0, 0xb5, 0x55, 0x55, 0x5b, 0x0, - 0x0, 0xb0, 0x0, 0x0, 0xb, 0x0, 0x0, 0xb5, - 0x55, 0x55, 0x5c, 0x0, 0x0, 0xb5, 0x55, 0x55, - 0x5b, 0x0, 0x0, 0x16, 0xb0, 0x2, 0x67, 0x10, - 0x3, 0x95, 0x0, 0x0, 0x3, 0xd1, 0x11, 0x0, - 0x0, 0x0, 0x0, 0x0, - - /* U+8CC7 "資" */ - 0x0, 0x0, 0x4, 0x10, 0x0, 0x0, 0x8, 0x50, - 0x1c, 0x10, 0x0, 0x10, 0x0, 0x46, 0x3a, 0x56, - 0x57, 0xb0, 0x0, 0x80, 0x90, 0x3d, 0x5, 0x0, - 0x3e, 0x12, 0x10, 0xb4, 0x70, 0x0, 0xc, 0x0, - 0x9, 0x50, 0x6a, 0x41, 0xa, 0x34, 0x72, 0x11, - 0x19, 0x94, 0x0, 0xc3, 0x33, 0x33, 0x3d, 0x0, - 0x0, 0xc5, 0x55, 0x55, 0x5c, 0x0, 0x0, 0xc5, - 0x55, 0x55, 0x5c, 0x0, 0x0, 0xc5, 0x55, 0x55, - 0x5c, 0x0, 0x0, 0x3a, 0x80, 0x2, 0x78, 0x0, - 0x5, 0x94, 0x0, 0x0, 0x5, 0xd0, 0x21, 0x0, - 0x0, 0x0, 0x0, 0x10, - - /* U+8CEA "質" */ - 0x0, 0x0, 0x1, 0x0, 0x0, 0x20, 0x0, 0x7, - 0x58, 0xa2, 0x66, 0x8a, 0x30, 0x0, 0xb0, 0x2, - 0xc, 0x0, 0x3, 0x0, 0xc, 0x5b, 0x63, 0xd5, - 0x97, 0x60, 0x4, 0x70, 0xb0, 0x37, 0x8, 0x30, - 0x0, 0x90, 0xa, 0x19, 0x0, 0x83, 0x0, 0x40, - 0x55, 0x68, 0x55, 0x5a, 0x10, 0x0, 0x8, 0x40, - 0x0, 0x0, 0xc0, 0x0, 0x0, 0x87, 0x55, 0x55, - 0x5d, 0x0, 0x0, 0x8, 0x75, 0x55, 0x55, 0xd0, - 0x0, 0x0, 0x87, 0x55, 0x55, 0x5d, 0x0, 0x0, - 0x2, 0x3b, 0x10, 0x26, 0x60, 0x0, 0x1, 0x77, - 0x10, 0x0, 0x6, 0xd0, 0x0, 0x30, 0x0, 0x0, - 0x0, 0x2, 0x0, - - /* U+8CFD "賽" */ - 0x0, 0x0, 0x0, 0x40, 0x0, 0x0, 0x0, 0x0, - 0x10, 0x0, 0x39, 0x0, 0x1, 0x0, 0x0, 0xa5, - 0x59, 0x55, 0x85, 0x5b, 0x40, 0x1, 0x56, 0x5c, - 0x55, 0xc5, 0x85, 0x0, 0x0, 0x5, 0x5c, 0x55, - 0xc5, 0x71, 0x0, 0x1, 0x56, 0x5c, 0x55, 0xc5, - 0x59, 0x30, 0x0, 0x10, 0x95, 0x0, 0x25, 0x0, - 0x0, 0x0, 0x19, 0xd5, 0x55, 0x5d, 0xb3, 0x0, - 0x4, 0x50, 0xc5, 0x55, 0x5b, 0x2a, 0xc1, 0x0, - 0x0, 0xc3, 0x33, 0x3b, 0x10, 0x0, 0x0, 0x0, - 0xc1, 0x11, 0x1a, 0x10, 0x0, 0x0, 0x0, 0x9a, - 0x55, 0xa9, 0x0, 0x0, 0x0, 0x2, 0x96, 0x10, - 0x6, 0xc1, 0x0, 0x0, 0x23, 0x0, 0x0, 0x0, - 0x21, 0x0, - - /* U+8D39 "费" */ - 0x0, 0x0, 0x40, 0x2, 0x0, 0x0, 0x0, 0x0, - 0xc, 0x10, 0xd0, 0x1, 0x0, 0x6, 0x55, 0xc5, - 0x5c, 0x56, 0xc0, 0x0, 0x75, 0x5c, 0x55, 0xc5, - 0x69, 0x0, 0xc, 0x0, 0xb0, 0xb, 0x0, 0x34, - 0x1, 0x75, 0xa8, 0x55, 0xd5, 0x57, 0xc0, 0x0, - 0x66, 0x0, 0xb, 0x4, 0xc3, 0x3, 0x59, 0x55, - 0x55, 0x55, 0xb2, 0x0, 0x0, 0xc0, 0x6, 0x50, - 0x1a, 0x0, 0x0, 0xc, 0x0, 0x92, 0x1, 0xb0, - 0x0, 0x0, 0xb0, 0xb, 0x21, 0x17, 0x0, 0x0, - 0x0, 0xa, 0x30, 0x5b, 0x81, 0x0, 0x2, 0x67, - 0x10, 0x0, 0x9, 0xa0, 0x3, 0x20, 0x0, 0x0, - 0x0, 0x1, 0x0, - - /* U+8D64 "赤" */ - 0x0, 0x0, 0x0, 0x21, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x67, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x65, 0x0, 0x52, 0x0, 0x0, 0x16, 0x55, - 0x99, 0x55, 0x53, 0x0, 0x0, 0x0, 0x0, 0x65, - 0x0, 0x0, 0x0, 0x4, 0x55, 0x55, 0x99, 0x55, - 0x56, 0xc1, 0x0, 0x1, 0xa, 0x20, 0xc0, 0x0, - 0x0, 0x0, 0xd, 0x3b, 0x0, 0xc1, 0x60, 0x0, - 0x0, 0x57, 0xc, 0x0, 0xc0, 0x2b, 0x10, 0x1, - 0x70, 0x39, 0x0, 0xc0, 0x7, 0xa0, 0x5, 0x0, - 0x92, 0x0, 0xc0, 0x0, 0x60, 0x0, 0x6, 0x50, - 0x0, 0xc0, 0x0, 0x0, 0x0, 0x63, 0x0, 0x5b, - 0xe0, 0x0, 0x0, 0x2, 0x0, 0x0, 0x1, 0x20, - 0x0, 0x0, - - /* U+8D70 "走" */ - 0x0, 0x0, 0x0, 0x30, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, 0xa4, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0xa1, 0x1, 0x70, 0x0, 0x0, 0x45, 0x55, - 0xc6, 0x55, 0x50, 0x0, 0x0, 0x0, 0x0, 0xa1, - 0x0, 0x0, 0x0, 0x16, 0x55, 0x55, 0xb6, 0x55, - 0x5c, 0x50, 0x0, 0x1, 0x0, 0xa3, 0x0, 0x0, - 0x0, 0x0, 0xd, 0x30, 0xa1, 0x0, 0x0, 0x0, - 0x0, 0xd, 0x0, 0xa6, 0x55, 0xc4, 0x0, 0x0, - 0x4b, 0x0, 0xa1, 0x0, 0x0, 0x0, 0x0, 0x92, - 0x81, 0xa1, 0x0, 0x0, 0x0, 0x2, 0x90, 0xa, - 0xe6, 0x31, 0x11, 0x20, 0x8, 0x0, 0x0, 0x48, - 0xbd, 0xff, 0x60, 0x10, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, - - /* U+8D77 "起" */ - 0x0, 0x0, 0x30, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0xc1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0xb0, 0x60, 0x65, 0x5b, 0x10, 0x2, 0x65, 0xc5, - 0x50, 0x0, 0xb, 0x0, 0x0, 0x0, 0xb0, 0x0, - 0x0, 0xb, 0x0, 0x6, 0x55, 0xc5, 0xa5, 0x95, - 0x5c, 0x0, 0x0, 0x0, 0xb2, 0x0, 0xb0, 0x4, - 0x0, 0x0, 0xc0, 0xb0, 0x0, 0xb0, 0x0, 0x10, - 0x0, 0xc0, 0xb5, 0xb2, 0xb0, 0x0, 0x50, 0x3, - 0xa0, 0xb0, 0x0, 0xb0, 0x0, 0xa0, 0x6, 0x75, - 0xb0, 0x0, 0x89, 0x9a, 0x90, 0x8, 0x3, 0xc7, - 0x42, 0x0, 0x0, 0x10, 0x23, 0x0, 0x3, 0x8b, - 0xde, 0xff, 0x80, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, - - /* U+8D85 "超" */ - 0x0, 0x3, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0xa, 0x30, 0x2, 0x22, 0x23, 0x40, 0x0, 0xa, - 0x4, 0x4, 0xc5, 0x38, 0x60, 0x4, 0x5c, 0x56, - 0x10, 0xd0, 0x8, 0x40, 0x0, 0xa, 0x0, 0x2, - 0xa0, 0xa, 0x20, 0x5, 0x5c, 0x5a, 0x3a, 0x11, - 0x9d, 0x0, 0x1, 0x8, 0x20, 0x63, 0x0, 0x3, - 0x0, 0x3, 0x78, 0x20, 0xc, 0x55, 0x5d, 0x30, - 0x5, 0x68, 0x68, 0x5c, 0x0, 0xb, 0x0, 0x6, - 0x48, 0x20, 0xc, 0x0, 0xb, 0x0, 0x8, 0x5a, - 0x20, 0xc, 0x55, 0x5d, 0x0, 0x8, 0x6, 0x84, - 0x15, 0x0, 0x1, 0x0, 0x31, 0x0, 0x5, 0x9b, - 0xcd, 0xde, 0x90, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, - - /* U+8D8A "越" */ - 0x0, 0x2, 0x0, 0x0, 0x2, 0x0, 0x0, 0x0, - 0xb, 0x10, 0x0, 0xd, 0x33, 0x0, 0x1, 0x1b, - 0x17, 0x10, 0xb, 0xc, 0x0, 0x4, 0x3c, 0x33, - 0x17, 0x5d, 0x58, 0xa0, 0x0, 0xb, 0x0, 0xb, - 0xb, 0x0, 0x0, 0x36, 0x5b, 0x58, 0x6b, 0xb, - 0xa, 0x30, 0x1, 0x7, 0x40, 0xb, 0xa, 0x1c, - 0x0, 0x4, 0xa7, 0x31, 0x1b, 0x7, 0xb4, 0x0, - 0x6, 0x67, 0x76, 0x4c, 0x64, 0xd0, 0x50, 0x8, - 0x47, 0x30, 0x1c, 0x1a, 0x96, 0x80, 0xa, 0x6a, - 0x30, 0x1, 0x81, 0x9, 0xc0, 0x8, 0x7, 0xa4, - 0x14, 0x0, 0x0, 0x30, 0x41, 0x0, 0x17, 0xbc, - 0xcc, 0xdd, 0xa1, 0x10, 0x0, 0x0, 0x0, 0x0, - 0x11, 0x0, - - /* U+8DA3 "趣" */ - 0x0, 0x2, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0xc, 0x0, 0x0, 0x2, 0x0, 0x0, 0x0, 0xa, - 0x16, 0xa5, 0xa7, 0x20, 0x0, 0x4, 0x5c, 0x73, - 0xa0, 0xa2, 0x65, 0xb0, 0x0, 0xa, 0x0, 0xa5, - 0xc0, 0x2, 0x80, 0x15, 0x5c, 0x5a, 0xa0, 0xa1, - 0x45, 0x50, 0x1, 0x9, 0x10, 0xa0, 0xa0, 0x5b, - 0x10, 0x5, 0x4a, 0x0, 0xa5, 0xc0, 0xd, 0x0, - 0x8, 0x4a, 0x67, 0xa0, 0xa3, 0x68, 0x70, 0x9, - 0x1a, 0x4, 0xc7, 0xc2, 0x60, 0xb0, 0x9, 0x6b, - 0x3, 0x10, 0xa3, 0x0, 0x10, 0x7, 0x9, 0x72, - 0x0, 0x60, 0x0, 0x0, 0x31, 0x0, 0x27, 0xbc, - 0xcd, 0xde, 0xc1, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, - - /* U+8DB3 "足" */ - 0x0, 0x0, 0x0, 0x0, 0x0, 0x10, 0x0, 0x0, - 0x9, 0x55, 0x55, 0x55, 0xd0, 0x0, 0x0, 0xa, - 0x0, 0x0, 0x0, 0xa0, 0x0, 0x0, 0xa, 0x0, - 0x0, 0x0, 0xa0, 0x0, 0x0, 0xa, 0x0, 0x0, - 0x0, 0xa0, 0x0, 0x0, 0xa, 0x55, 0xc5, 0x55, - 0xa0, 0x0, 0x0, 0x0, 0x0, 0xc0, 0x0, 0x0, - 0x0, 0x0, 0x9, 0x10, 0xc0, 0x0, 0x34, 0x0, - 0x0, 0x2d, 0x0, 0xc5, 0x55, 0x55, 0x0, 0x0, - 0x7a, 0x0, 0xc0, 0x0, 0x0, 0x0, 0x0, 0xc1, - 0x70, 0xc0, 0x0, 0x0, 0x0, 0x5, 0x40, 0x19, - 0xe3, 0x21, 0x1, 0x21, 0x16, 0x0, 0x0, 0x49, - 0xce, 0xef, 0x90, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, - - /* U+8DDF "跟" */ - 0x4, 0x55, 0x59, 0x7, 0x55, 0x59, 0x0, 0x7, - 0x40, 0xb, 0xb, 0x0, 0xc, 0x0, 0x7, 0x40, - 0xa, 0xb, 0x0, 0xb, 0x0, 0x7, 0x40, 0xa, - 0xd, 0x55, 0x5b, 0x0, 0x7, 0x7b, 0x57, 0xb, - 0x0, 0xb, 0x0, 0x1, 0xa, 0x0, 0xc, 0x65, - 0x5b, 0x0, 0xa, 0x2b, 0x59, 0x1b, 0x41, 0x6, - 0x40, 0xa, 0xa, 0x0, 0xb, 0x16, 0x59, 0x20, - 0xa, 0xa, 0x0, 0xb, 0x9, 0x40, 0x0, 0xa, - 0xb, 0x55, 0x1b, 0x3, 0xb1, 0x0, 0x4d, 0xb7, - 0x10, 0xd, 0x80, 0x3d, 0x91, 0x35, 0x0, 0x0, - 0x8, 0x0, 0x1, 0x30, - - /* U+8DEF "路" */ - 0x0, 0x0, 0x0, 0x1, 0x20, 0x0, 0x0, 0x3, - 0x22, 0x25, 0x6, 0xa0, 0x0, 0x0, 0x8, 0x53, - 0x4a, 0xa, 0x65, 0x5c, 0x0, 0x8, 0x20, 0x19, - 0x1b, 0x0, 0x66, 0x0, 0x9, 0x20, 0x19, 0x61, - 0x71, 0xa0, 0x0, 0x8, 0x6b, 0x66, 0x50, 0x4e, - 0x20, 0x0, 0x0, 0xa, 0x0, 0x0, 0xa9, 0xb2, - 0x0, 0xa, 0x2b, 0x68, 0x9, 0x30, 0x3d, 0xb1, - 0xa, 0xa, 0x3, 0x6c, 0x55, 0x5c, 0x20, 0xa, - 0xa, 0x0, 0xb, 0x0, 0xb, 0x0, 0xa, 0xc, - 0x64, 0xb, 0x0, 0xb, 0x0, 0x3d, 0x94, 0x0, - 0xc, 0x55, 0x5b, 0x0, 0x0, 0x0, 0x0, 0xb, - 0x0, 0x9, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, - - /* U+8EAB "身" */ - 0x0, 0x0, 0x2, 0x10, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x93, 0x0, 0x0, 0x0, 0x0, 0xa, 0x58, - 0x55, 0x5d, 0x0, 0x0, 0x0, 0xc0, 0x0, 0x0, - 0xc0, 0x0, 0x0, 0xd, 0x55, 0x55, 0x5c, 0x3, - 0x0, 0x0, 0xc0, 0x0, 0x0, 0xc5, 0xc0, 0x0, - 0xd, 0x55, 0x55, 0x5e, 0xb0, 0x0, 0x0, 0xc0, - 0x0, 0x4, 0xe1, 0x0, 0x36, 0x57, 0x55, 0x58, - 0xbc, 0x0, 0x0, 0x0, 0x0, 0x6, 0x90, 0xc0, - 0x0, 0x0, 0x0, 0x19, 0x50, 0xc, 0x0, 0x0, - 0x0, 0x67, 0x10, 0x0, 0xc0, 0x0, 0x24, 0x50, - 0x0, 0x5, 0xca, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x2, 0x0, 0x0, - - /* U+8ECA "車" */ - 0x0, 0x0, 0x0, 0x4, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x1, 0xc0, 0x0, 0x0, 0x0, 0x2, - 0x65, 0x55, 0x5c, 0x55, 0x56, 0xb1, 0x0, 0x0, - 0x0, 0x0, 0xa0, 0x0, 0x20, 0x0, 0x0, 0x1b, - 0x55, 0x5c, 0x55, 0x5e, 0x10, 0x0, 0x1, 0x90, - 0x0, 0xa0, 0x0, 0xb0, 0x0, 0x0, 0x1b, 0x55, - 0x5c, 0x55, 0x5b, 0x0, 0x0, 0x1, 0x90, 0x0, - 0xa0, 0x0, 0xb0, 0x0, 0x0, 0x1b, 0x55, 0x5c, - 0x55, 0x5c, 0x0, 0x0, 0x0, 0x10, 0x0, 0xa0, - 0x0, 0x2, 0x20, 0x6, 0x55, 0x55, 0x5c, 0x55, - 0x55, 0x88, 0x0, 0x0, 0x0, 0x0, 0xa0, 0x0, - 0x0, 0x0, 0x0, 0x0, 0x0, 0x1b, 0x0, 0x0, - 0x0, 0x0, 0x0, 0x0, 0x0, 0x30, 0x0, 0x0, - 0x0, - - /* U+8EDF "軟" */ - 0x0, 0x3, 0x0, 0x0, 0x30, 0x0, 0x0, 0x0, - 0xb, 0x20, 0x0, 0xc3, 0x0, 0x0, 0x6, 0x5c, - 0x59, 0x50, 0xb0, 0x0, 0x0, 0x0, 0xa, 0x0, - 0x5, 0x95, 0x57, 0x90, 0xa, 0x5c, 0x5c, 0x29, - 0x45, 0x7, 0x30, 0xb, 0xa, 0xa, 0x33, 0x48, - 0x2, 0x0, 0xb, 0x5c, 0x5b, 0x10, 0x5a, 0x0, - 0x0, 0xb, 0xa, 0xa, 0x0, 0x7a, 0x0, 0x0, - 0xb, 0x5c, 0x5b, 0x0, 0xa6, 0x20, 0x0, 0x2, - 0xa, 0x1, 0x41, 0xb1, 0x90, 0x0, 0x36, 0x5c, - 0x55, 0x58, 0x30, 0xa3, 0x0, 0x0, 0xa, 0x0, - 0x55, 0x0, 0x2d, 0x30, 0x0, 0xb, 0x4, 0x40, - 0x0, 0x4, 0xa1, 0x0, 0x3, 0x0, 0x0, 0x0, - 0x0, 0x0, - - /* U+8EE2 "転" */ - 0x0, 0x4, 0x10, 0x0, 0x0, 0x0, 0x0, 0x0, - 0xb, 0x20, 0x0, 0x0, 0x0, 0x0, 0x6, 0x5c, - 0x5a, 0x45, 0x65, 0x5b, 0x10, 0x0, 0xa, 0x0, - 0x0, 0x0, 0x0, 0x0, 0xa, 0x5c, 0x5c, 0x10, - 0x0, 0x0, 0x0, 0xb, 0xa, 0xa, 0x0, 0x0, - 0x0, 0x40, 0xb, 0x5c, 0x5b, 0x46, 0x59, 0x56, - 0x70, 0xb, 0xa, 0xa, 0x0, 0x4a, 0x0, 0x0, - 0xb, 0x5c, 0x5b, 0x0, 0xa1, 0x0, 0x0, 0x2, - 0xa, 0x4, 0x12, 0x70, 0x31, 0x0, 0x36, 0x5c, - 0x55, 0x38, 0x0, 0xa, 0x20, 0x0, 0xa, 0x0, - 0x7b, 0x97, 0x67, 0xa0, 0x0, 0xb, 0x0, 0x23, - 0x0, 0x0, 0x50, 0x0, 0x4, 0x0, 0x0, 0x0, - 0x0, 0x0, - - /* U+8EFD "軽" */ - 0x0, 0x4, 0x10, 0x0, 0x0, 0x0, 0x0, 0x0, - 0xb, 0x10, 0x36, 0x55, 0x5b, 0x40, 0x6, 0x5c, - 0x5a, 0x24, 0x0, 0x2a, 0x0, 0x0, 0xa, 0x0, - 0x0, 0x70, 0xa1, 0x0, 0xa, 0x5c, 0x5d, 0x10, - 0x5b, 0x30, 0x0, 0xb, 0xa, 0xa, 0x0, 0x89, - 0x91, 0x0, 0xb, 0x5c, 0x5b, 0x27, 0x22, 0x4d, - 0xa1, 0xb, 0xa, 0xb, 0x30, 0xd, 0x10, 0x10, - 0xb, 0x5c, 0x5b, 0x0, 0xb, 0x5, 0x20, 0x3, - 0xa, 0x2, 0x46, 0x5c, 0x55, 0x30, 0x26, 0x5c, - 0x55, 0x40, 0xb, 0x0, 0x0, 0x0, 0xa, 0x0, - 0x0, 0xb, 0x0, 0x30, 0x0, 0xb, 0x1, 0x65, - 0x57, 0x56, 0x81, 0x0, 0x4, 0x0, 0x0, 0x0, - 0x0, 0x0, - - /* U+8F03 "較" */ - 0x0, 0x4, 0x10, 0x0, 0x11, 0x0, 0x0, 0x0, - 0xb, 0x10, 0x0, 0xb, 0x30, 0x0, 0x6, 0x5c, - 0x5b, 0x20, 0x3, 0x20, 0x30, 0x0, 0xa, 0x0, - 0x26, 0x75, 0x56, 0x70, 0xa, 0x5c, 0x5c, 0x20, - 0xc3, 0x26, 0x0, 0xb, 0xa, 0xa, 0x6, 0x50, - 0x3, 0xc0, 0xb, 0x5c, 0x5b, 0x37, 0x20, 0x26, - 0x62, 0xb, 0xa, 0xa, 0x40, 0x60, 0x69, 0x0, - 0xb, 0x5c, 0x5b, 0x0, 0x71, 0xb1, 0x0, 0x2, - 0xa, 0x3, 0x20, 0x1c, 0x80, 0x0, 0x26, 0x5c, - 0x56, 0x40, 0x2c, 0x80, 0x0, 0x0, 0xa, 0x0, - 0x4, 0x80, 0x8b, 0x30, 0x0, 0xb, 0x1, 0x64, - 0x0, 0x5, 0xa2, 0x0, 0x4, 0x0, 0x0, 0x0, - 0x0, 0x0, - - /* U+8F09 "載" */ - 0x0, 0x0, 0x41, 0x0, 0x4, 0x0, 0x0, 0x0, - 0x0, 0xa1, 0x51, 0xd, 0x73, 0x0, 0x0, 0x65, - 0xc5, 0x53, 0xb, 0x19, 0x0, 0x6, 0x55, 0xb5, - 0x55, 0x5c, 0x55, 0xb3, 0x0, 0x0, 0x92, 0x21, - 0xb, 0x0, 0x0, 0x2, 0x65, 0xc5, 0x66, 0xb, - 0x2, 0x30, 0x0, 0x95, 0xc5, 0xa5, 0xb, 0x7, - 0x70, 0x0, 0xb0, 0xa0, 0x91, 0xb, 0xb, 0x0, - 0x0, 0xc5, 0xc5, 0xb1, 0x9, 0x68, 0x0, 0x0, - 0xd5, 0xc5, 0xb1, 0x5, 0xe1, 0x0, 0x0, 0x20, - 0xa0, 0x26, 0x9, 0xd0, 0x3, 0x5, 0x55, 0xc5, - 0x55, 0xa6, 0x59, 0x15, 0x0, 0x0, 0xa0, 0x38, - 0x20, 0x7, 0xd5, 0x0, 0x0, 0x40, 0x20, 0x0, - 0x0, 0x34, - - /* U+8F15 "輕" */ - 0x0, 0x4, 0x10, 0x0, 0x0, 0x0, 0x0, 0x0, - 0xb, 0x10, 0x12, 0x22, 0x25, 0x60, 0x16, 0x5c, - 0x5a, 0x36, 0x45, 0x45, 0x40, 0x0, 0xa, 0x0, - 0x9, 0x3a, 0x3a, 0x30, 0xa, 0x5c, 0x5c, 0x37, - 0x34, 0x25, 0x0, 0xb, 0xa, 0xa, 0x35, 0x36, - 0x18, 0x0, 0xb, 0x5c, 0x5b, 0xa, 0x3a, 0x37, - 0x60, 0xb, 0xa, 0xa, 0x3, 0x43, 0x12, 0x20, - 0xb, 0x5c, 0x5b, 0x6, 0x58, 0x59, 0x50, 0x3, - 0xa, 0x1, 0x30, 0xb, 0x0, 0x0, 0x36, 0x5c, - 0x55, 0x50, 0xb, 0x0, 0x0, 0x0, 0xa, 0x0, - 0x0, 0xb, 0x0, 0x0, 0x0, 0xb, 0x0, 0x55, - 0x5c, 0x55, 0xd2, 0x0, 0x8, 0x0, 0x10, 0x0, - 0x0, 0x0, - - /* U+8F2A "輪" */ - 0x0, 0x5, 0x0, 0x0, 0x5, 0x0, 0x0, 0x0, - 0xb, 0x0, 0x0, 0x2d, 0x0, 0x0, 0x6, 0x5c, - 0x5a, 0x0, 0x95, 0x50, 0x0, 0x0, 0xa, 0x0, - 0x2, 0xa0, 0x84, 0x0, 0xb, 0x5c, 0x5d, 0x19, - 0x0, 0x3d, 0xa2, 0xb, 0xa, 0xb, 0x62, 0x65, - 0x53, 0x40, 0xb, 0x4c, 0x4a, 0x45, 0x55, 0x55, - 0x80, 0xb, 0xa, 0xa, 0x64, 0x90, 0x90, 0xa0, - 0xb, 0x5c, 0x5a, 0x64, 0x90, 0x90, 0xa0, 0x2, - 0xa, 0x5, 0x68, 0xb5, 0xb5, 0xa0, 0x26, 0x5c, - 0x55, 0x74, 0x90, 0x90, 0xa0, 0x0, 0xa, 0x0, - 0x64, 0x90, 0x90, 0xa0, 0x0, 0xb, 0x0, 0x64, - 0x60, 0x67, 0x90, 0x0, 0x4, 0x0, 0x10, 0x0, - 0x1, 0x0, - - /* U+8F38 "輸" */ - 0x0, 0x1, 0x0, 0x0, 0x11, 0x0, 0x0, 0x0, - 0xc, 0x10, 0x0, 0x6c, 0x0, 0x0, 0x6, 0x5c, - 0x5a, 0x0, 0xd4, 0x40, 0x0, 0x0, 0xa, 0x0, - 0x6, 0x80, 0x84, 0x0, 0x9, 0x5c, 0x5c, 0x39, - 0x65, 0x8c, 0xa2, 0xb, 0xa, 0xb, 0x60, 0x1, - 0x4, 0x50, 0xb, 0x5c, 0x5a, 0x68, 0x69, 0x39, - 0x20, 0xb, 0xa, 0xa, 0x65, 0x29, 0xa8, 0x10, - 0xc, 0x5c, 0x5a, 0x68, 0x59, 0x98, 0x10, 0x2, - 0xa, 0x6, 0x67, 0x49, 0x98, 0x10, 0x26, 0x5c, - 0x55, 0x76, 0x39, 0xa8, 0x10, 0x0, 0xa, 0x0, - 0x65, 0x18, 0x18, 0x10, 0x0, 0xc, 0x0, 0x66, - 0xa7, 0x6d, 0x0, 0x0, 0x3, 0x0, 0x0, 0x0, - 0x0, 0x0, - - /* U+8F9B "辛" */ - 0x0, 0x0, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x3a, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0xb3, 0x0, 0x71, 0x0, 0x6, 0x57, 0x55, 0x58, - 0x65, 0x30, 0x0, 0x0, 0x75, 0x0, 0xa6, 0x0, - 0x0, 0x0, 0x2, 0xd0, 0x9, 0x0, 0x0, 0x6, - 0x55, 0x57, 0x68, 0x65, 0x5c, 0x60, 0x0, 0x0, - 0xa, 0x20, 0x0, 0x0, 0x0, 0x0, 0x0, 0xa2, - 0x0, 0x30, 0x0, 0x6, 0x55, 0x5c, 0x75, 0x5b, - 0x30, 0x0, 0x0, 0x0, 0xa2, 0x0, 0x0, 0x0, - 0x0, 0x0, 0xa, 0x20, 0x0, 0x0, 0x0, 0x0, - 0x0, 0xa3, 0x0, 0x0, 0x0, 0x0, 0x0, 0x1, - 0x0, 0x0, 0x0, - - /* U+8F9E "辞" */ - 0x0, 0x0, 0x0, 0x0, 0x31, 0x0, 0x0, 0x0, - 0x0, 0x6c, 0x0, 0x1b, 0x0, 0x0, 0x3, 0x6a, - 0x93, 0x36, 0x57, 0x56, 0x90, 0x0, 0x4, 0x70, - 0x2, 0x0, 0x15, 0x0, 0x0, 0x4, 0x72, 0x46, - 0x50, 0x5b, 0x0, 0x5, 0x57, 0x95, 0x41, 0xa0, - 0x91, 0x0, 0x0, 0x4, 0x70, 0x45, 0x45, 0x84, - 0x92, 0x1, 0x77, 0x98, 0x20, 0xb, 0x0, 0x0, - 0x1, 0xb0, 0xb, 0x0, 0xb, 0x0, 0x0, 0x1, - 0xb0, 0xb, 0x26, 0x5c, 0x57, 0x70, 0x1, 0xb0, - 0xb, 0x0, 0xb, 0x0, 0x0, 0x1, 0xc5, 0x5c, - 0x0, 0xb, 0x0, 0x0, 0x1, 0x80, 0x3, 0x0, - 0xc, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x3, - 0x0, 0x0, - - /* U+8FA6 "辦" */ - 0x0, 0x0, 0x0, 0x10, 0x2, 0x0, 0x0, 0x0, - 0xa1, 0x0, 0xc0, 0x1, 0xc0, 0x0, 0x3, 0x97, - 0x40, 0xa0, 0x13, 0x75, 0x40, 0x4, 0x26, 0x35, - 0xc9, 0x53, 0x25, 0x20, 0x7, 0x2a, 0x20, 0xa7, - 0x29, 0xb, 0x20, 0x3, 0x57, 0x11, 0x97, 0x17, - 0x37, 0x0, 0x36, 0xa6, 0x83, 0x78, 0x55, 0x96, - 0xa0, 0x0, 0xa0, 0x5, 0x49, 0x0, 0xa0, 0x0, - 0x3, 0xb6, 0x49, 0xa, 0x0, 0xa1, 0x20, 0x3, - 0xa1, 0x29, 0xa, 0x26, 0xc6, 0x50, 0x0, 0x90, - 0x81, 0xa, 0x0, 0xa0, 0x0, 0x6, 0x34, 0x43, - 0xb7, 0x0, 0xa0, 0x0, 0x25, 0x24, 0x0, 0x20, - 0x0, 0xb0, 0x0, 0x10, 0x0, 0x0, 0x0, 0x0, - 0x30, 0x0, - - /* U+8FB2 "農" */ - 0x0, 0x0, 0x16, 0x0, 0x60, 0x0, 0x0, 0x5, - 0x56, 0xc5, 0x5d, 0x58, 0x20, 0x0, 0x92, 0x1a, - 0x0, 0xb0, 0xa1, 0x0, 0x9, 0x66, 0xc5, 0x5c, - 0x5c, 0x0, 0x0, 0x92, 0x1a, 0x0, 0xb0, 0xa1, - 0x0, 0x7, 0x55, 0x65, 0x56, 0x59, 0x10, 0x0, - 0x85, 0x55, 0x55, 0x55, 0x87, 0x0, 0x9, 0x33, - 0x33, 0x33, 0x62, 0x0, 0x0, 0x93, 0x21, 0x11, - 0x11, 0x15, 0x0, 0xb, 0x5b, 0x57, 0x65, 0x58, - 0x61, 0x0, 0xb0, 0xa0, 0x7, 0x18, 0x70, 0x0, - 0x55, 0xa, 0x1, 0x3a, 0xa0, 0x0, 0x17, 0x0, - 0xda, 0x60, 0x6, 0xdb, 0x52, 0x0, 0x2, 0x0, - 0x0, 0x0, 0x30, - - /* U+8FBA "辺" */ - 0x0, 0x20, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x86, 0x0, 0x0, 0x0, 0x1, 0x0, 0x0, 0x1e, - 0x6, 0x57, 0x75, 0x5c, 0x60, 0x0, 0x0, 0x0, - 0x8, 0x30, 0xa, 0x10, 0x0, 0x6, 0x0, 0xa, - 0x10, 0xa, 0x0, 0x6, 0x5d, 0x0, 0xc, 0x0, - 0xb, 0x0, 0x0, 0xa, 0x0, 0x1a, 0x0, 0xb, - 0x0, 0x0, 0xa, 0x0, 0x74, 0x0, 0xc, 0x0, - 0x0, 0xa, 0x0, 0xa0, 0x0, 0xb, 0x0, 0x0, - 0xa, 0x7, 0x20, 0x0, 0x58, 0x0, 0x0, 0x7c, - 0x32, 0x0, 0x19, 0xe2, 0x0, 0x1d, 0x51, 0xa4, - 0x0, 0x0, 0x10, 0x0, 0x2, 0x0, 0x6, 0xbc, - 0xdd, 0xde, 0xc2, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, - - /* U+8FBC "込" */ - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x92, 0x0, 0x7, 0x0, 0x0, 0x0, 0x0, 0x3d, - 0x0, 0x3, 0x20, 0x0, 0x0, 0x0, 0x4, 0x0, - 0x0, 0x60, 0x0, 0x0, 0x0, 0x3, 0x0, 0x0, - 0xd0, 0x0, 0x0, 0x6, 0x5e, 0x10, 0x5, 0x94, - 0x0, 0x0, 0x0, 0xb, 0x0, 0xb, 0x9, 0x0, - 0x0, 0x0, 0xb, 0x0, 0x55, 0x7, 0x30, 0x0, - 0x0, 0xb, 0x1, 0x80, 0x0, 0xc1, 0x0, 0x0, - 0xb, 0x17, 0x0, 0x0, 0x5c, 0x20, 0x0, 0x6c, - 0x40, 0x0, 0x0, 0x8, 0xb1, 0xc, 0x61, 0x94, - 0x0, 0x0, 0x0, 0x0, 0x3, 0x0, 0x5, 0xbc, - 0xcc, 0xdd, 0xc3, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, - - /* U+8FCE "迎" */ - 0x0, 0x0, 0x0, 0x0, 0x10, 0x0, 0x0, 0x0, - 0x70, 0x0, 0x7, 0xb1, 0x0, 0x0, 0x0, 0x78, - 0xa, 0x41, 0x8, 0x55, 0xa0, 0x0, 0x13, 0xb, - 0x0, 0xb, 0x0, 0xb0, 0x0, 0x0, 0xb, 0x0, - 0xb, 0x0, 0xb0, 0x6, 0x6c, 0xb, 0x0, 0xb, - 0x0, 0xb0, 0x0, 0xa, 0xb, 0x0, 0xb, 0x0, - 0xb0, 0x0, 0xa, 0xb, 0x4, 0x2b, 0x0, 0xb0, - 0x0, 0xa, 0xc, 0xb3, 0xb, 0x26, 0xa0, 0x0, - 0xa, 0x5, 0x10, 0xb, 0x5, 0x30, 0x1, 0x89, - 0x20, 0x0, 0xb, 0x0, 0x0, 0x1d, 0x20, 0x68, - 0x42, 0x14, 0x11, 0x23, 0x0, 0x0, 0x1, 0x69, - 0xbc, 0xcd, 0xc1, - - /* U+8FD1 "近" */ - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x70, 0x0, 0x10, 0x14, 0x8d, 0x20, 0x0, 0x59, - 0x0, 0xb5, 0x53, 0x10, 0x0, 0x0, 0x2, 0x0, - 0xb0, 0x0, 0x0, 0x0, 0x0, 0x1, 0x0, 0xb0, - 0x0, 0x0, 0x40, 0x7, 0x6d, 0x0, 0xb5, 0x55, - 0xb5, 0x62, 0x0, 0xa, 0x0, 0xb0, 0x0, 0xb0, - 0x0, 0x0, 0xa, 0x0, 0xa0, 0x0, 0xb0, 0x0, - 0x0, 0xa, 0x4, 0x60, 0x0, 0xb0, 0x0, 0x0, - 0xa, 0x8, 0x0, 0x0, 0xb0, 0x0, 0x0, 0x3b, - 0x21, 0x0, 0x0, 0xc0, 0x0, 0x6, 0x80, 0x74, - 0x0, 0x0, 0x40, 0x0, 0x9, 0x0, 0x5, 0xbc, - 0xdd, 0xdd, 0xd5, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, - - /* U+8FD4 "返" */ - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x62, 0x1, 0x1, 0x37, 0xca, 0x0, 0x0, 0x1d, - 0x3, 0xb4, 0x31, 0x0, 0x0, 0x0, 0x5, 0x3, - 0x90, 0x0, 0x0, 0x0, 0x0, 0x0, 0x3, 0xb5, - 0x55, 0x69, 0x0, 0x7, 0x5c, 0x4, 0x80, 0x0, - 0x67, 0x0, 0x0, 0xb, 0x5, 0x74, 0x0, 0xc0, - 0x0, 0x0, 0xb, 0x6, 0x30, 0x89, 0x60, 0x0, - 0x0, 0xb, 0x9, 0x0, 0x2c, 0xb1, 0x0, 0x0, - 0xb, 0x26, 0x2, 0xa1, 0x3d, 0x10, 0x0, 0xb, - 0x40, 0x47, 0x0, 0x5, 0x30, 0x4, 0x83, 0x75, - 0x10, 0x0, 0x0, 0x0, 0x9, 0x0, 0x6, 0xbc, - 0xdd, 0xde, 0xc2, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, - - /* U+8FEB "迫" */ - 0x0, 0x0, 0x0, 0x0, 0x10, 0x0, 0x0, 0x0, - 0x40, 0x0, 0x0, 0xd2, 0x0, 0x0, 0x0, 0x87, - 0x0, 0x1, 0x80, 0x0, 0x0, 0x0, 0x2b, 0x0, - 0xa7, 0x65, 0x5d, 0x0, 0x0, 0x0, 0x0, 0xc0, - 0x0, 0x1b, 0x0, 0x5, 0x5a, 0x0, 0xc0, 0x0, - 0x1b, 0x0, 0x1, 0xc, 0x0, 0xd5, 0x55, 0x5b, - 0x0, 0x0, 0xc, 0x0, 0xc0, 0x0, 0x1b, 0x0, - 0x0, 0xc, 0x0, 0xc0, 0x0, 0x1b, 0x0, 0x0, - 0xc, 0x0, 0xd5, 0x55, 0x5b, 0x0, 0x0, 0x7d, - 0x10, 0xc0, 0x0, 0x9, 0x0, 0xc, 0x60, 0x86, - 0x31, 0x0, 0x1, 0x22, 0x3, 0x0, 0x3, 0x8b, - 0xcd, 0xee, 0xc1, - - /* U+8FFD "追" */ - 0x0, 0x0, 0x0, 0x0, 0x20, 0x0, 0x0, 0x0, - 0x60, 0x0, 0x0, 0xa2, 0x0, 0x0, 0x0, 0x79, - 0x0, 0x75, 0x95, 0x59, 0x0, 0x0, 0x17, 0x0, - 0xb0, 0x0, 0x1a, 0x0, 0x0, 0x0, 0x0, 0xb0, - 0x0, 0x1a, 0x0, 0x6, 0x5b, 0x0, 0xc5, 0x55, - 0x6a, 0x0, 0x0, 0xb, 0x0, 0xb0, 0x0, 0x0, - 0x0, 0x0, 0xb, 0x0, 0xc5, 0x55, 0x5b, 0x50, - 0x0, 0xb, 0x0, 0xb0, 0x0, 0x9, 0x20, 0x0, - 0xb, 0x0, 0xb0, 0x0, 0x9, 0x20, 0x0, 0x6c, - 0x10, 0xd5, 0x55, 0x5b, 0x20, 0xb, 0x60, 0x85, - 0x40, 0x0, 0x1, 0x0, 0x4, 0x0, 0x5, 0xac, - 0xcc, 0xdd, 0xe4, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x11, 0x10, - - /* U+9000 "退" */ - 0x0, 0x60, 0x0, 0x20, 0x0, 0x5, 0x0, 0x0, - 0x6a, 0x0, 0xd5, 0x55, 0x5d, 0x0, 0x0, 0x6, - 0x0, 0xc0, 0x0, 0xc, 0x0, 0x0, 0x0, 0x0, - 0xd5, 0x55, 0x5c, 0x0, 0x5, 0x5b, 0x0, 0xc0, - 0x0, 0xc, 0x0, 0x0, 0xc, 0x0, 0xd5, 0x55, - 0x58, 0x30, 0x0, 0xc, 0x0, 0xc1, 0x40, 0x2a, - 0x40, 0x0, 0xc, 0x0, 0xc0, 0x18, 0xa0, 0x0, - 0x0, 0xc, 0x0, 0xc2, 0x62, 0x5d, 0x30, 0x0, - 0x6b, 0x21, 0xf7, 0x0, 0x4, 0x80, 0xc, 0x40, - 0x67, 0x50, 0x0, 0x0, 0x12, 0x1, 0x0, 0x3, - 0x9b, 0xde, 0xef, 0xe2, - - /* U+9001 "送" */ - 0x0, 0x0, 0x0, 0x0, 0x0, 0x20, 0x0, 0x0, - 0x70, 0x0, 0x81, 0x1, 0xd0, 0x0, 0x0, 0x88, - 0x0, 0x4a, 0x7, 0x30, 0x0, 0x0, 0x13, 0x3, - 0x57, 0x59, 0x5b, 0x30, 0x0, 0x0, 0x0, 0x0, - 0xc0, 0x0, 0x0, 0x7, 0x6b, 0x0, 0x0, 0xc0, - 0x0, 0x40, 0x0, 0x19, 0x26, 0x55, 0xd5, 0x56, - 0x80, 0x0, 0x19, 0x0, 0x2, 0xb0, 0x0, 0x0, - 0x0, 0x19, 0x0, 0x9, 0x69, 0x40, 0x0, 0x0, - 0x19, 0x0, 0x48, 0x0, 0xa9, 0x0, 0x0, 0x5c, - 0x4, 0x60, 0x0, 0xc, 0x0, 0xa, 0x61, 0xa6, - 0x0, 0x0, 0x0, 0x0, 0x5, 0x0, 0x7, 0xbb, - 0xcc, 0xde, 0xb1, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, - - /* U+9003 "逃" */ - 0x0, 0x0, 0x0, 0x1, 0x1, 0x0, 0x0, 0x0, - 0x60, 0x0, 0xb, 0x2c, 0x20, 0x0, 0x0, 0x59, - 0x11, 0xb, 0xb, 0x5, 0x40, 0x0, 0x6, 0xb, - 0xb, 0xb, 0x39, 0x10, 0x0, 0x0, 0x8, 0x2b, - 0xb, 0x40, 0x0, 0x6, 0x5c, 0x0, 0xb, 0xb, - 0x10, 0x0, 0x0, 0xa, 0x1, 0x7d, 0xb, 0x6b, - 0x10, 0x0, 0xa, 0x5a, 0xc, 0xb, 0x5, 0x60, - 0x0, 0xa, 0x0, 0x38, 0xb, 0x0, 0x50, 0x0, - 0xa, 0x0, 0x91, 0xb, 0x20, 0xa1, 0x0, 0x6b, - 0x15, 0x10, 0x4, 0x99, 0x80, 0xb, 0x60, 0x84, - 0x0, 0x0, 0x0, 0x11, 0x3, 0x0, 0x5, 0xac, - 0xde, 0xef, 0xe2, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, - - /* U+900F "透" */ - 0x0, 0x0, 0x0, 0x0, 0x0, 0x10, 0x0, 0x1, - 0x30, 0x0, 0x14, 0x79, 0xb4, 0x0, 0x0, 0xa4, - 0x1, 0x31, 0xa0, 0x0, 0x20, 0x0, 0x32, 0x36, - 0x58, 0xd6, 0x56, 0xa0, 0x0, 0x0, 0x0, 0x2a, - 0xa4, 0x50, 0x0, 0x4, 0x59, 0x3, 0x70, 0xa0, - 0x5b, 0x61, 0x2, 0x1a, 0x46, 0x67, 0x85, 0x92, - 0x60, 0x0, 0xa, 0x0, 0xb, 0x4, 0x72, 0x0, - 0x0, 0xa, 0x0, 0x19, 0x6, 0x5d, 0x0, 0x0, - 0xa, 0x0, 0x72, 0x0, 0x1a, 0x0, 0x0, 0x3b, - 0x3, 0x50, 0x16, 0x96, 0x0, 0x9, 0x71, 0x84, - 0x0, 0x3, 0x80, 0x0, 0x6, 0x0, 0x7, 0xab, - 0xcc, 0xcd, 0xc2, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x1, 0x0, - - /* U+9010 "逐" */ - 0x0, 0x82, 0x0, 0x0, 0x0, 0x2, 0x60, 0x0, - 0x3c, 0x6, 0x55, 0xd5, 0x55, 0x50, 0x0, 0x3, - 0x0, 0x9, 0x40, 0x4, 0x10, 0x0, 0x0, 0x1, - 0x71, 0x90, 0x3a, 0x20, 0x6, 0x5c, 0x3, 0x5, - 0xaa, 0x50, 0x0, 0x0, 0xb, 0x0, 0x65, 0xc, - 0x0, 0x0, 0x0, 0xb, 0x15, 0x20, 0xad, 0x76, - 0x0, 0x0, 0xb, 0x0, 0x9, 0x4a, 0x19, 0x80, - 0x0, 0xb, 0x3, 0x81, 0xc, 0x0, 0xb0, 0x0, - 0x4c, 0x23, 0x5, 0x7c, 0x0, 0x0, 0xa, 0x50, - 0x94, 0x0, 0x72, 0x0, 0x0, 0x4, 0x0, 0x6, - 0xbc, 0xcc, 0xcd, 0xa1, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x11, 0x0, - - /* U+9019 "這" */ - 0x0, 0x0, 0x0, 0x0, 0x10, 0x0, 0x0, 0x0, - 0x92, 0x0, 0x0, 0xb2, 0x0, 0x0, 0x0, 0x3c, - 0x0, 0x0, 0x42, 0x4, 0x30, 0x0, 0x1, 0x6, - 0x55, 0x55, 0x55, 0x40, 0x0, 0x1, 0x0, 0x55, - 0x55, 0x79, 0x0, 0x6, 0x7d, 0x0, 0x10, 0x0, - 0x0, 0x0, 0x0, 0x19, 0x0, 0x65, 0x55, 0x77, - 0x0, 0x0, 0x19, 0x0, 0x20, 0x0, 0x3, 0x0, - 0x0, 0x19, 0x0, 0xd5, 0x55, 0x5d, 0x0, 0x0, - 0x19, 0x0, 0xb0, 0x0, 0xb, 0x0, 0x1, 0xab, - 0x20, 0xc5, 0x55, 0x5b, 0x0, 0x1d, 0x30, 0x86, - 0x70, 0x0, 0x3, 0x1, 0x2, 0x0, 0x3, 0x9b, - 0xcd, 0xde, 0xd2, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, - - /* U+901A "通" */ - 0x0, 0x0, 0x0, 0x0, 0x0, 0x1, 0x0, 0x0, - 0x60, 0x3, 0x65, 0x55, 0x7e, 0x20, 0x0, 0x87, - 0x0, 0x5, 0x54, 0x60, 0x0, 0x0, 0x23, 0x4, - 0x0, 0xc4, 0x0, 0x40, 0x0, 0x0, 0xc, 0x55, - 0xc5, 0x56, 0xa0, 0x5, 0x4b, 0xb, 0x55, 0xc5, - 0x56, 0x90, 0x0, 0xa, 0xb, 0x0, 0xb0, 0x2, - 0x90, 0x0, 0xa, 0xb, 0x55, 0xc5, 0x56, 0x90, - 0x0, 0xa, 0xb, 0x0, 0xb0, 0x2, 0x90, 0x0, - 0xa, 0xb, 0x0, 0xb0, 0x2, 0x90, 0x0, 0x3c, - 0xb, 0x0, 0xa0, 0x4a, 0x80, 0x8, 0x80, 0x75, - 0x0, 0x0, 0x5, 0x10, 0x6, 0x0, 0x5, 0xac, - 0xdd, 0xde, 0xf4, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x11, 0x10, - - /* U+901F "速" */ - 0x0, 0x0, 0x0, 0x0, 0x20, 0x0, 0x0, 0x2, - 0x10, 0x0, 0x0, 0xb2, 0x0, 0x0, 0x0, 0xc2, - 0x35, 0x55, 0xd5, 0x57, 0x90, 0x0, 0x63, 0x0, - 0x0, 0xb0, 0x0, 0x0, 0x0, 0x0, 0x6, 0x55, - 0xc5, 0x5c, 0x0, 0x3, 0x38, 0x9, 0x10, 0xb0, - 0xb, 0x0, 0x3, 0x1b, 0x9, 0x65, 0xc5, 0x5b, - 0x0, 0x0, 0xb, 0x6, 0x6, 0xf0, 0x5, 0x0, - 0x0, 0xb, 0x0, 0x39, 0xb6, 0x71, 0x0, 0x0, - 0xb, 0x2, 0x80, 0xb0, 0x3d, 0x30, 0x0, 0x4b, - 0x33, 0x0, 0xc0, 0x2, 0x40, 0xa, 0x60, 0x84, - 0x0, 0x90, 0x0, 0x0, 0x4, 0x0, 0x5, 0xab, - 0xcd, 0xde, 0xd2, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, - - /* U+9020 "造" */ - 0x0, 0x0, 0x0, 0x0, 0x10, 0x0, 0x0, 0x1, - 0x50, 0x0, 0x30, 0xb2, 0x0, 0x0, 0x0, 0xa6, - 0x0, 0xd2, 0xb0, 0x3, 0x0, 0x0, 0x33, 0x3, - 0xa5, 0xc5, 0x69, 0x10, 0x0, 0x0, 0x7, 0x0, - 0xb0, 0x0, 0x0, 0x6, 0x6b, 0x26, 0x55, 0xc5, - 0x55, 0xc2, 0x0, 0x19, 0x1, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x19, 0x0, 0xa5, 0x55, 0x5d, 0x0, - 0x0, 0x19, 0x0, 0xb0, 0x0, 0xb, 0x0, 0x0, - 0x19, 0x0, 0xb0, 0x0, 0xb, 0x0, 0x1, 0x8b, - 0x0, 0xc5, 0x55, 0x5b, 0x0, 0x1d, 0x40, 0x95, - 0x50, 0x0, 0x1, 0x0, 0x3, 0x0, 0x6, 0xbc, - 0xcd, 0xee, 0xf4, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, - - /* U+9023 "連" */ - 0x0, 0x0, 0x0, 0x0, 0x30, 0x0, 0x0, 0x0, - 0x93, 0x0, 0x0, 0xa2, 0x1, 0x0, 0x0, 0x2c, - 0x5, 0x55, 0xc5, 0x57, 0x50, 0x0, 0x1, 0x0, - 0x30, 0xa0, 0x5, 0x0, 0x0, 0x1, 0x0, 0xc5, - 0xc5, 0x5c, 0x10, 0x16, 0x5e, 0x10, 0xc5, 0xc5, - 0x5b, 0x0, 0x0, 0xb, 0x0, 0xb0, 0xa0, 0xa, - 0x0, 0x0, 0xb, 0x0, 0xc5, 0xc5, 0x5b, 0x0, - 0x0, 0xb, 0x0, 0x10, 0xa0, 0x0, 0x30, 0x0, - 0xb, 0x46, 0x55, 0xc5, 0x55, 0x71, 0x2, 0xaa, - 0x20, 0x0, 0xa0, 0x0, 0x0, 0xd, 0x20, 0x78, - 0x31, 0x70, 0x0, 0x22, 0x1, 0x0, 0x2, 0x7a, - 0xcc, 0xdd, 0xa1, - - /* U+902E "逮" */ - 0x0, 0x0, 0x0, 0x0, 0x30, 0x0, 0x0, 0x0, - 0x71, 0x0, 0x0, 0xc1, 0x1, 0x0, 0x0, 0x2c, - 0x3, 0x65, 0xc5, 0x5d, 0x0, 0x0, 0x2, 0x0, - 0x0, 0xb0, 0xc, 0x40, 0x0, 0x0, 0x26, 0x55, - 0xc5, 0x5d, 0x52, 0x7, 0x6d, 0x2, 0x55, 0xc5, - 0x5c, 0x0, 0x0, 0xa, 0x4, 0x20, 0xb0, 0x4, - 0x0, 0x0, 0xa, 0x0, 0xb3, 0xb2, 0xa7, 0x0, - 0x0, 0xa, 0x0, 0x26, 0xd8, 0x0, 0x0, 0x0, - 0xa, 0x3a, 0x70, 0xb2, 0x98, 0x0, 0x0, 0x5a, - 0x13, 0x33, 0xc0, 0x7, 0x40, 0x9, 0x50, 0x83, - 0x8, 0x90, 0x0, 0x0, 0x4, 0x0, 0x6, 0xab, - 0xbc, 0xcd, 0xe4, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, - - /* U+9031 "週" */ - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x85, 0x8, 0x55, 0x65, 0x5b, 0x30, 0x0, 0xd, - 0xb, 0x0, 0xa2, 0xa, 0x0, 0x0, 0x0, 0xa, - 0x6, 0xc7, 0x4a, 0x0, 0x0, 0x5, 0xa, 0x0, - 0xa0, 0x3a, 0x0, 0x16, 0x5d, 0xa, 0x36, 0x65, - 0x7a, 0x0, 0x0, 0xa, 0x9, 0x8, 0x59, 0x4a, - 0x0, 0x0, 0xa, 0x9, 0xa, 0x8, 0x2a, 0x0, - 0x0, 0xa, 0x8, 0xc, 0x5a, 0x2a, 0x0, 0x0, - 0xa, 0x24, 0x7, 0x2, 0xa, 0x0, 0x0, 0x7b, - 0x50, 0x0, 0x2, 0x7c, 0x0, 0x1c, 0x30, 0x94, - 0x0, 0x0, 0x3, 0x0, 0x2, 0x0, 0x6, 0xbb, - 0xcc, 0xde, 0xd2, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, - - /* U+9032 "進" */ - 0x0, 0x0, 0x0, 0x10, 0x10, 0x0, 0x0, 0x0, - 0x84, 0x0, 0xa7, 0x49, 0x0, 0x0, 0x0, 0x1e, - 0x0, 0xd0, 0x9, 0x2, 0x0, 0x0, 0x1, 0x5, - 0xc5, 0x59, 0x58, 0x40, 0x0, 0x4, 0xa, 0xa0, - 0xa, 0x1, 0x0, 0x6, 0x5d, 0x63, 0xc5, 0x5c, - 0x59, 0x10, 0x0, 0xb, 0x0, 0xa0, 0xa, 0x0, - 0x0, 0x0, 0xb, 0x0, 0xc5, 0x5c, 0x5b, 0x10, - 0x0, 0xb, 0x0, 0xa0, 0xa, 0x0, 0x0, 0x0, - 0xb, 0x0, 0xa0, 0xa, 0x5, 0x30, 0x1, 0x8b, - 0x10, 0xc5, 0x55, 0x55, 0x30, 0xd, 0x40, 0x96, - 0x20, 0x0, 0x0, 0x1, 0x3, 0x0, 0x5, 0xbc, - 0xcd, 0xef, 0xd2, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, - - /* U+9045 "遅" */ - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x84, 0x2, 0x95, 0x55, 0x55, 0xc0, 0x0, 0x1d, - 0x1, 0xa0, 0x0, 0x0, 0xb0, 0x0, 0x1, 0x0, - 0xc5, 0x55, 0x55, 0xb0, 0x0, 0x4, 0x0, 0xa2, - 0x70, 0x67, 0x0, 0x6, 0x5d, 0x11, 0xa5, 0xb5, - 0xb6, 0x90, 0x0, 0xb, 0x3, 0x71, 0xb, 0x1, - 0x0, 0x0, 0xb, 0x6, 0x36, 0x5c, 0x59, 0x40, - 0x0, 0xb, 0x8, 0x0, 0xb, 0x0, 0x51, 0x0, - 0xb, 0x33, 0x55, 0x5d, 0x55, 0x52, 0x0, 0x7c, - 0x40, 0x0, 0xc, 0x0, 0x0, 0xc, 0x50, 0x95, - 0x0, 0x8, 0x0, 0x0, 0x4, 0x0, 0x5, 0xab, - 0xbb, 0xcd, 0xd5, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, - - /* U+904A "遊" */ - 0x0, 0x10, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x85, 0x0, 0x93, 0x0, 0xc1, 0x0, 0x0, 0x1c, - 0x0, 0x24, 0x5, 0x60, 0x41, 0x0, 0x0, 0x16, - 0x75, 0x9a, 0x55, 0x53, 0x0, 0x3, 0x1, 0x90, - 0x44, 0x55, 0xa1, 0x6, 0x6d, 0x2, 0xb6, 0xa0, - 0x5, 0x50, 0x0, 0x19, 0x4, 0x63, 0x70, 0x1a, - 0x10, 0x0, 0x19, 0x7, 0x24, 0x77, 0x5b, 0x75, - 0x0, 0x19, 0x9, 0x6, 0x40, 0x18, 0x0, 0x0, - 0x19, 0x43, 0x9, 0x10, 0x18, 0x0, 0x0, 0x7b, - 0x41, 0x9b, 0x3, 0x88, 0x0, 0x1d, 0x31, 0x82, - 0x0, 0x0, 0x41, 0x0, 0x2, 0x0, 0x6, 0xaa, - 0xbb, 0xcc, 0xd4, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x11, 0x0, - - /* U+904B "運" */ - 0x1, 0x80, 0x5, 0x65, 0x55, 0x56, 0x70, 0x0, - 0x6a, 0xc, 0x0, 0x72, 0x6, 0x30, 0x0, 0x5, - 0x6, 0x55, 0xc5, 0x59, 0x20, 0x0, 0x1, 0x0, - 0x30, 0xa0, 0x4, 0x0, 0x6, 0x6e, 0x10, 0xc5, - 0xc5, 0x5c, 0x0, 0x0, 0xa, 0x0, 0xc5, 0xc5, - 0x5b, 0x0, 0x0, 0xa, 0x0, 0xa0, 0xa0, 0xa, - 0x0, 0x0, 0xa, 0x0, 0xa5, 0xc5, 0x58, 0x0, - 0x0, 0xa, 0x26, 0x55, 0xc5, 0x55, 0xa0, 0x0, - 0x7c, 0x0, 0x0, 0xa0, 0x0, 0x0, 0x1d, 0x51, - 0x93, 0x0, 0xa0, 0x0, 0x0, 0x2, 0x0, 0x6, - 0xbb, 0xcc, 0xcd, 0xb2, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x0, - - /* U+904E "過" */ - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x94, 0x0, 0x75, 0x55, 0x69, 0x0, 0x0, 0x2d, - 0x0, 0x91, 0x3, 0x46, 0x0, 0x0, 0x1, 0x0, - 0x86, 0x89, 0x46, 0x0, 0x0, 0x3, 0x1, 0x81, - 0x46, 0x46, 0x20, 0x16, 0x6d, 0xb, 0x65, 0x56, - 0x56, 0xd0, 0x0, 0x19, 0xa, 0x7, 0x55, 0x90, - 0xa0, 0x0, 0x19, 0xa, 0xa, 0x0, 0xa0, 0xa0, - 0x0, 0x19, 0xa, 0xb, 0x55, 0xb0, 0xa0, 0x0, - 0x19, 0xb, 0x9, 0x0, 0x70, 0xa0, 0x0, 0x7a, - 0xa, 0x0, 0x0, 0x3a, 0x80, 0x1d, 0x41, 0x84, - 0x0, 0x0, 0x1, 0x0, 0x2, 0x0, 0x5, 0xac, - 0xcd, 0xdd, 0xd3, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, - - /* U+9053 "道" */ - 0x0, 0x0, 0x0, 0x10, 0x0, 0x20, 0x0, 0x0, - 0x84, 0x0, 0x67, 0x0, 0xc4, 0x0, 0x0, 0x2c, - 0x0, 0xa, 0x4, 0x40, 0x40, 0x0, 0x1, 0x16, - 0x55, 0xa6, 0x55, 0x82, 0x0, 0x4, 0x0, 0x75, - 0xa5, 0x59, 0x0, 0x7, 0x6d, 0x0, 0xc0, 0x0, - 0xc, 0x0, 0x0, 0xa, 0x0, 0xc5, 0x55, 0x5b, - 0x0, 0x0, 0xa, 0x0, 0xb0, 0x0, 0xb, 0x0, - 0x0, 0xa, 0x0, 0xc5, 0x55, 0x5b, 0x0, 0x0, - 0xa, 0x0, 0xb0, 0x0, 0xb, 0x0, 0x1, 0x88, - 0x20, 0xc5, 0x55, 0x5b, 0x0, 0xc, 0x20, 0x77, - 0x40, 0x0, 0x0, 0x0, 0x0, 0x0, 0x2, 0x8b, - 0xcc, 0xde, 0xd2, - - /* U+9054 "達" */ - 0x0, 0x20, 0x0, 0x0, 0x31, 0x0, 0x0, 0x0, - 0x76, 0x0, 0x0, 0xa3, 0x2, 0x0, 0x0, 0xd, - 0x2, 0x65, 0xb6, 0x67, 0x0, 0x0, 0x0, 0x0, - 0x0, 0xa1, 0x1, 0x70, 0x0, 0x3, 0x26, 0x88, - 0x55, 0xb5, 0x51, 0x16, 0x6c, 0x0, 0xc, 0x6, - 0x62, 0x20, 0x0, 0x19, 0x6, 0x55, 0xb6, 0x56, - 0x50, 0x0, 0x19, 0x1, 0x55, 0xb6, 0x69, 0x0, - 0x0, 0x19, 0x0, 0x10, 0xa1, 0x0, 0x10, 0x0, - 0x19, 0x17, 0x55, 0xb6, 0x56, 0x70, 0x2, 0xbb, - 0x10, 0x0, 0xa1, 0x0, 0x0, 0x1e, 0x20, 0xa6, - 0x10, 0x81, 0x0, 0x0, 0x1, 0x0, 0x5, 0xbd, - 0xde, 0xef, 0xa1, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, - - /* U+9055 "違" */ - 0x0, 0x0, 0x0, 0x4, 0x0, 0x0, 0x0, 0x4, - 0x90, 0x0, 0xc, 0x10, 0x40, 0x0, 0x0, 0xb5, - 0x6, 0x8a, 0x55, 0xc0, 0x0, 0x0, 0x20, 0x22, - 0x77, 0x22, 0xb4, 0x70, 0x0, 0x20, 0x35, 0x22, - 0x22, 0x43, 0x20, 0x46, 0xc5, 0x9, 0x65, 0x55, - 0xb4, 0x0, 0x0, 0x92, 0x9, 0x65, 0x75, 0xb1, - 0x0, 0x0, 0x92, 0x2, 0x0, 0xa0, 0x34, 0x0, - 0x0, 0x92, 0x4a, 0x55, 0xc5, 0x54, 0x0, 0x0, - 0x92, 0x4c, 0x55, 0xc5, 0x57, 0x80, 0x5, 0xc6, - 0x11, 0x0, 0xb0, 0x0, 0x0, 0x8b, 0x5, 0x81, - 0x0, 0x90, 0x0, 0x0, 0x10, 0x0, 0x3a, 0xcb, - 0xbc, 0xde, 0xa1, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x1, 0x0, - - /* U+9060 "遠" */ - 0x0, 0x0, 0x0, 0x0, 0x41, 0x0, 0x0, 0x0, - 0x74, 0x0, 0x0, 0xb2, 0x2, 0x0, 0x0, 0xe, - 0x1, 0x75, 0xc5, 0x59, 0x10, 0x0, 0x3, 0x0, - 0x0, 0xb0, 0x0, 0x60, 0x0, 0x0, 0x26, 0x65, - 0x55, 0x57, 0x51, 0x16, 0x6c, 0x0, 0xc4, 0x44, - 0x4d, 0x0, 0x0, 0x19, 0x0, 0xc5, 0x55, 0x5b, - 0x0, 0x0, 0x19, 0x0, 0x77, 0xb0, 0x6, 0x0, - 0x0, 0x19, 0x0, 0x78, 0xa4, 0x58, 0x20, 0x0, - 0x19, 0x27, 0x31, 0x90, 0x79, 0x10, 0x1, 0x8b, - 0x10, 0x2, 0x90, 0x3, 0x90, 0x1d, 0x40, 0x94, - 0x1, 0x60, 0x0, 0x0, 0x2, 0x0, 0x5, 0xab, - 0xcc, 0xdd, 0xd4, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, - - /* U+9069 "適" */ - 0x0, 0x0, 0x0, 0x1, 0x20, 0x0, 0x0, 0x0, - 0x91, 0x0, 0x0, 0xb0, 0x0, 0x0, 0x0, 0x5a, - 0x6, 0x55, 0x65, 0x58, 0x80, 0x0, 0x2, 0x0, - 0x46, 0x6, 0x50, 0x0, 0x0, 0x2, 0x6, 0x5a, - 0x5a, 0x58, 0x30, 0x16, 0x6d, 0xa, 0x0, 0xa2, - 0x9, 0x20, 0x0, 0x19, 0xa, 0x26, 0xc5, 0x89, - 0x10, 0x0, 0x19, 0xa, 0x2, 0xa1, 0x19, 0x10, - 0x0, 0x19, 0xa, 0xc, 0x59, 0x59, 0x10, 0x0, - 0x19, 0xa, 0xc, 0x59, 0x49, 0x10, 0x0, 0x7b, - 0xb, 0x5, 0x3, 0x3a, 0x10, 0x1d, 0x41, 0x94, - 0x0, 0x0, 0x39, 0x0, 0x2, 0x0, 0x7, 0xbb, - 0xcc, 0xcd, 0xa2, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, - - /* U+9078 "選" */ - 0x0, 0x10, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x95, 0x7, 0x59, 0x48, 0x5a, 0x20, 0x0, 0x1d, - 0x9, 0x9, 0x19, 0x9, 0x0, 0x0, 0x0, 0x9, - 0x57, 0x39, 0x57, 0x30, 0x0, 0x2, 0x8, 0x65, - 0x98, 0x65, 0x90, 0x16, 0x6d, 0x0, 0x3a, 0x11, - 0x72, 0x0, 0x0, 0x19, 0x4, 0x5c, 0x57, 0xb8, - 0x50, 0x0, 0x19, 0x1, 0x9, 0x2, 0x70, 0x0, - 0x0, 0x19, 0x35, 0x5b, 0x56, 0x95, 0xa1, 0x0, - 0x19, 0x0, 0xa, 0x23, 0x61, 0x0, 0x1, 0xac, - 0x3, 0x93, 0x0, 0x1c, 0x30, 0x1e, 0x41, 0xa6, - 0x0, 0x0, 0x1, 0x10, 0x3, 0x0, 0x6, 0xaa, - 0xbb, 0xbc, 0xa2, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x11, 0x0, - - /* U+907F "避" */ - 0x0, 0x0, 0x0, 0x0, 0x2, 0x0, 0x0, 0x3, - 0x60, 0x32, 0x25, 0x2, 0xa0, 0x0, 0x0, 0xa4, - 0x94, 0x3c, 0x65, 0x86, 0x70, 0x0, 0x10, 0x91, - 0xa, 0x31, 0xa, 0x0, 0x0, 0x0, 0x96, 0x5b, - 0xb, 0x26, 0x0, 0x46, 0xa5, 0x90, 0x3, 0x57, - 0x95, 0xa0, 0x0, 0x92, 0xa4, 0x25, 0x10, 0xa0, - 0x0, 0x0, 0x92, 0x8c, 0x3b, 0x0, 0xa0, 0x30, - 0x0, 0x93, 0x6b, 0xa, 0x55, 0xc5, 0x40, 0x0, - 0x97, 0xb, 0xa, 0x0, 0xa0, 0x0, 0x1, 0x94, - 0xc, 0x5a, 0x0, 0xb0, 0x0, 0x3b, 0x4, 0x72, - 0x0, 0x0, 0x50, 0x0, 0x1, 0x0, 0x18, 0xbc, - 0xcc, 0xde, 0x81, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, - - /* U+9084 "還" */ - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x3, - 0xa0, 0xa, 0x58, 0x58, 0x5b, 0x30, 0x0, 0x97, - 0xb, 0xa, 0xa, 0x9, 0x0, 0x0, 0x11, 0xc, - 0x59, 0x59, 0x5b, 0x10, 0x0, 0x10, 0x57, 0x55, - 0x55, 0x56, 0xb0, 0x36, 0xb5, 0x4, 0x55, 0x55, - 0x58, 0x0, 0x0, 0x92, 0x7, 0x30, 0x0, 0xb, - 0x0, 0x0, 0x92, 0x7, 0x7c, 0x55, 0x59, 0x0, - 0x0, 0x92, 0x0, 0xb6, 0x42, 0x96, 0x0, 0x0, - 0x92, 0x29, 0x94, 0x2a, 0x60, 0x0, 0x1, 0xb5, - 0x40, 0x79, 0x72, 0x8a, 0x0, 0x3c, 0x15, 0x71, - 0x35, 0x0, 0x2, 0x0, 0x43, 0x0, 0x29, 0xbc, - 0xcc, 0xcd, 0x92, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, - - /* U+908A "邊" */ - 0x0, 0x0, 0x0, 0x0, 0x23, 0x0, 0x0, 0x0, - 0x71, 0x0, 0x55, 0xb7, 0x58, 0x0, 0x0, 0x3d, - 0x0, 0xb5, 0x55, 0x5b, 0x0, 0x0, 0x7, 0x0, - 0xa5, 0x55, 0x5b, 0x0, 0x0, 0x0, 0x0, 0xb5, - 0x55, 0x5c, 0x0, 0x14, 0x5a, 0x2, 0x30, 0x55, - 0x2, 0x30, 0x1, 0x1a, 0x2a, 0x5a, 0x77, 0x85, - 0xb1, 0x0, 0x19, 0x12, 0x54, 0x45, 0x35, 0x30, - 0x0, 0x19, 0x6, 0x58, 0x75, 0x57, 0x70, 0x0, - 0x19, 0x0, 0xb, 0x55, 0x5d, 0x10, 0x1, 0x9b, - 0x11, 0x92, 0x3, 0x58, 0x0, 0x1d, 0x31, 0xaa, - 0x10, 0x1, 0x91, 0x0, 0x2, 0x0, 0x6, 0xbc, - 0xdd, 0xde, 0xc3, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, - - /* U+90A3 "那" */ - 0x2, 0x55, 0x55, 0x93, 0x75, 0x56, 0x70, 0x0, - 0x11, 0xa0, 0xa1, 0xb0, 0x7, 0x70, 0x0, 0x1, - 0xa0, 0xa1, 0xb0, 0xa, 0x0, 0x1, 0x55, 0xc5, - 0xc1, 0xb0, 0x25, 0x0, 0x0, 0x11, 0xa0, 0xa1, - 0xb0, 0x50, 0x0, 0x0, 0x2, 0x90, 0xa1, 0xb0, - 0x7, 0x0, 0x2, 0x67, 0xa5, 0xc1, 0xb0, 0x5, - 0x40, 0x0, 0x6, 0x30, 0xa1, 0xb0, 0x0, 0xa0, - 0x0, 0x9, 0x0, 0xa1, 0xb0, 0x13, 0xb0, 0x0, - 0x27, 0x0, 0xb0, 0xb1, 0x7f, 0x40, 0x0, 0x80, - 0x5b, 0xc0, 0xb0, 0x0, 0x0, 0x5, 0x0, 0x3, - 0x10, 0xc0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x10, 0x0, 0x0, - - /* U+90AA "邪" */ - 0x2, 0x55, 0x55, 0x87, 0x75, 0x57, 0x70, 0x1, - 0x0, 0xb0, 0xb, 0x0, 0x95, 0x0, 0xb2, 0xb, - 0x0, 0xb0, 0xa, 0x0, 0x1c, 0x0, 0xb0, 0xb, - 0x4, 0x40, 0x7, 0xa5, 0x5c, 0x7a, 0xb0, 0x60, - 0x0, 0x10, 0x9, 0xd0, 0xb, 0x4, 0x30, 0x0, - 0x2, 0xab, 0x0, 0xb0, 0x9, 0x0, 0x0, 0xa1, - 0xb0, 0xb, 0x0, 0x47, 0x0, 0x64, 0xb, 0x0, - 0xb0, 0x3, 0xa0, 0x44, 0x0, 0xb0, 0xb, 0x28, - 0xe6, 0x22, 0x3, 0x3c, 0x0, 0xb0, 0x4, 0x0, - 0x0, 0x9, 0x90, 0xb, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x10, 0x0, 0x0, - - /* U+90E8 "部" */ - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x1, 0xa0, 0x0, 0x1, 0x0, 0x10, 0x0, 0x0, - 0x92, 0x15, 0xc, 0x55, 0xd2, 0x3, 0x75, 0x55, - 0x75, 0xb, 0x1, 0xa0, 0x0, 0x37, 0x2, 0xc0, - 0xb, 0x6, 0x30, 0x0, 0xb, 0x7, 0x10, 0xb, - 0x7, 0x0, 0x6, 0x55, 0x57, 0x58, 0x6b, 0x6, - 0x0, 0x0, 0x10, 0x0, 0x30, 0xb, 0x3, 0x60, - 0x0, 0xc5, 0x55, 0xd2, 0xb, 0x0, 0xb0, 0x0, - 0xb0, 0x0, 0xb0, 0xb, 0x0, 0xa2, 0x0, 0xb0, - 0x0, 0xb0, 0xb, 0x59, 0xd0, 0x0, 0xb5, 0x55, - 0xc0, 0xb, 0x6, 0x20, 0x0, 0x90, 0x0, 0x70, - 0xb, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x2, - 0x0, 0x0, - - /* U+90F5 "郵" */ - 0x0, 0x0, 0x0, 0x20, 0x0, 0x0, 0x0, 0x1, - 0x47, 0xab, 0xa0, 0x65, 0x58, 0x50, 0x1, 0x10, - 0xa0, 0x0, 0x82, 0xc, 0x30, 0x5, 0x55, 0xc5, - 0x5a, 0x92, 0x36, 0x0, 0x0, 0xa0, 0xa0, 0xa0, - 0x82, 0x70, 0x0, 0x0, 0xa0, 0xa0, 0xa1, 0x82, - 0x50, 0x0, 0x5, 0xc5, 0xc5, 0xb6, 0x82, 0x33, - 0x0, 0x0, 0xa0, 0xa0, 0xa0, 0x82, 0x7, 0x30, - 0x5, 0xc5, 0xc5, 0xc9, 0x92, 0x0, 0xa0, 0x1, - 0x0, 0xa0, 0x0, 0x82, 0x0, 0xc0, 0x0, 0x0, - 0xb4, 0x53, 0x85, 0x7e, 0x80, 0x7, 0xca, 0x52, - 0x0, 0x82, 0x3, 0x0, 0x1, 0x0, 0x0, 0x0, - 0x82, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, - - /* U+90FD "都" */ - 0x0, 0x0, 0x41, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0xb2, 0x3, 0x6, 0x44, 0x72, 0x0, 0x45, - 0xc7, 0x8d, 0x3c, 0x11, 0xd1, 0x0, 0x10, 0xb1, - 0x67, 0xb, 0x3, 0x70, 0x0, 0x0, 0xb3, 0xb0, - 0x3b, 0x7, 0x10, 0x5, 0x55, 0x7d, 0x65, 0x5b, - 0x6, 0x0, 0x0, 0x1, 0xa2, 0x3, 0xb, 0x6, - 0x10, 0x0, 0x4d, 0x55, 0x6c, 0xb, 0x0, 0xa0, - 0x5, 0x4a, 0x0, 0x19, 0xb, 0x0, 0xa3, 0x0, - 0xc, 0x55, 0x69, 0xb, 0x0, 0x94, 0x0, 0xa, - 0x0, 0x1a, 0xb, 0x3b, 0xd0, 0x0, 0x1c, 0x55, - 0x6a, 0xb, 0x1, 0x0, 0x0, 0x1a, 0x0, 0x16, - 0xc, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x3, - 0x0, 0x0, - - /* U+914D "配" */ - 0x25, 0x55, 0x55, 0xb3, 0x55, 0x58, 0x10, 0x1, - 0xa, 0x91, 0x0, 0x10, 0xb, 0x0, 0x3, 0xa, - 0x91, 0x40, 0x0, 0xb, 0x0, 0xb, 0x5b, 0xb6, - 0xc0, 0x0, 0xb, 0x0, 0xb, 0x18, 0x91, 0xb0, - 0x75, 0x5c, 0x0, 0xb, 0x44, 0x91, 0xb0, 0xb0, - 0x7, 0x0, 0xb, 0x70, 0x4a, 0xb0, 0xb0, 0x0, - 0x0, 0xb, 0x0, 0x0, 0xb0, 0xb0, 0x0, 0x0, - 0xb, 0x55, 0x55, 0xb0, 0xb0, 0x0, 0x10, 0xb, - 0x0, 0x0, 0xb0, 0xb0, 0x0, 0x50, 0xb, 0x55, - 0x55, 0xb0, 0xb0, 0x0, 0x90, 0xb, 0x0, 0x0, - 0xb0, 0xaa, 0x9b, 0xb0, 0x4, 0x0, 0x0, 0x30, - 0x0, 0x0, 0x0, - - /* U+9152 "酒" */ - 0x1, 0x60, 0x45, 0x55, 0x55, 0x56, 0xa0, 0x0, - 0x75, 0x10, 0xa, 0xa, 0x0, 0x0, 0x0, 0x1, - 0x32, 0xa, 0xa, 0x3, 0x0, 0x7, 0x1, 0x4d, - 0x5c, 0x5c, 0x5c, 0x20, 0x4, 0x95, 0xb, 0xa, - 0xa, 0xb, 0x0, 0x0, 0x27, 0xb, 0x9, 0xa, - 0xb, 0x0, 0x0, 0x26, 0xb, 0x53, 0x6, 0x9d, - 0x0, 0x1, 0x92, 0xb, 0x30, 0x0, 0xb, 0x0, - 0x4, 0xe0, 0xc, 0x55, 0x55, 0x5c, 0x0, 0x0, - 0xb0, 0xb, 0x0, 0x0, 0xb, 0x0, 0x0, 0xe0, - 0xd, 0x55, 0x55, 0x5c, 0x0, 0x0, 0x80, 0xb, - 0x0, 0x0, 0x9, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x0, - - /* U+9154 "酔" */ - 0x0, 0x0, 0x0, 0x0, 0x32, 0x0, 0x0, 0x15, - 0x55, 0x55, 0x90, 0x85, 0x0, 0x0, 0x1, 0x54, - 0x90, 0x4, 0xa7, 0x58, 0x0, 0x1, 0x54, 0x92, - 0x1, 0x91, 0xa, 0x0, 0xa, 0x88, 0xba, 0x50, - 0xa0, 0xa, 0x10, 0x9, 0x53, 0x97, 0x24, 0x60, - 0x9, 0x50, 0x9, 0x71, 0x97, 0x46, 0x8, 0x4a, - 0xa3, 0x9, 0x70, 0xac, 0x40, 0xc, 0x10, 0x0, - 0xa, 0x0, 0x7, 0x43, 0x3c, 0x43, 0x80, 0xa, - 0x55, 0x5a, 0x43, 0x2c, 0x32, 0x20, 0x9, 0x0, - 0x7, 0x20, 0xb, 0x10, 0x0, 0xa, 0x55, 0x5a, - 0x30, 0xc, 0x10, 0x0, 0xa, 0x0, 0x7, 0x20, - 0xc, 0x10, 0x0, 0x0, 0x0, 0x0, 0x0, 0x1, - 0x0, 0x0, - - /* U+9178 "酸" */ - 0x0, 0x0, 0x0, 0x0, 0x4, 0x0, 0x0, 0x15, - 0x55, 0x56, 0x80, 0x3a, 0x11, 0x0, 0x1, 0x36, - 0x90, 0x2, 0x70, 0x8, 0x40, 0x1, 0x36, 0x91, - 0x2c, 0x86, 0x55, 0xd0, 0xa, 0x79, 0xbb, 0x32, - 0x51, 0x33, 0x30, 0xa, 0x45, 0x99, 0x13, 0xa1, - 0x7, 0xb0, 0xa, 0x53, 0x99, 0x45, 0x57, 0x0, - 0x81, 0xa, 0x70, 0x9c, 0x10, 0xc6, 0x5b, 0x30, - 0xa, 0x20, 0x9, 0x16, 0x70, 0x1b, 0x0, 0xa, - 0x55, 0x5b, 0x44, 0x51, 0xa3, 0x0, 0xa, 0x0, - 0x9, 0x20, 0xc, 0x70, 0x0, 0xa, 0x55, 0x5b, - 0x10, 0x59, 0xa1, 0x0, 0xb, 0x0, 0x8, 0x27, - 0x50, 0x3d, 0x92, 0x3, 0x0, 0x1, 0x40, 0x0, - 0x1, 0x50, - - /* U+91AB "醫" */ - 0x0, 0x0, 0x0, 0x10, 0x0, 0x10, 0x0, 0x0, - 0xb5, 0x85, 0x82, 0x95, 0xb3, 0x0, 0x0, 0xa6, - 0x96, 0x80, 0x90, 0x86, 0x30, 0x0, 0xa4, 0x27, - 0x34, 0x30, 0x16, 0x20, 0x0, 0xa5, 0xaa, 0x52, - 0x75, 0xb7, 0x0, 0x0, 0xa3, 0x51, 0x61, 0x29, - 0xb1, 0x0, 0x2, 0xa6, 0x55, 0x57, 0x53, 0x29, - 0x10, 0x5, 0x55, 0x55, 0x95, 0x95, 0x55, 0x91, - 0x0, 0x17, 0x55, 0xc5, 0xc5, 0x76, 0x0, 0x0, - 0x1a, 0x5, 0x50, 0xa0, 0x55, 0x0, 0x0, 0x1a, - 0x44, 0x0, 0x57, 0xa5, 0x0, 0x0, 0x1b, 0x55, - 0x55, 0x55, 0x85, 0x0, 0x0, 0x1b, 0x55, 0x55, - 0x55, 0x85, 0x0, 0x0, 0x15, 0x0, 0x0, 0x0, - 0x22, 0x0, - - /* U+91CD "重" */ - 0x0, 0x0, 0x0, 0x0, 0x0, 0x10, 0x0, 0x0, - 0x0, 0x23, 0x57, 0x9b, 0x90, 0x0, 0x0, 0x23, - 0x22, 0xb1, 0x0, 0x2, 0x0, 0x5, 0x65, 0x55, - 0xc5, 0x55, 0x5a, 0x40, 0x0, 0x2, 0x0, 0xa1, - 0x0, 0x40, 0x0, 0x0, 0xd, 0x55, 0xc5, 0x55, - 0xc0, 0x0, 0x0, 0xd, 0x55, 0xc5, 0x55, 0xb0, - 0x0, 0x0, 0xc, 0x0, 0xa1, 0x0, 0xb0, 0x0, - 0x0, 0xd, 0x55, 0xc5, 0x55, 0xc0, 0x0, 0x0, - 0x4, 0x0, 0xa1, 0x0, 0x50, 0x0, 0x0, 0x65, - 0x55, 0xc5, 0x55, 0x86, 0x0, 0x0, 0x0, 0x0, - 0xa1, 0x0, 0x1, 0x40, 0x26, 0x55, 0x55, 0x85, - 0x55, 0x57, 0x91, - - /* U+91CE "野" */ - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x95, - 0x75, 0x5b, 0x45, 0x55, 0xd2, 0xb, 0x9, 0x10, - 0xb0, 0x0, 0x75, 0x0, 0xb0, 0x91, 0xb, 0x5, - 0x93, 0x0, 0xb, 0x5b, 0x65, 0xb0, 0x9, 0x60, - 0x0, 0xb0, 0x91, 0xb, 0x65, 0x86, 0x89, 0xb, - 0x5b, 0x65, 0xb0, 0xa, 0x8, 0x0, 0x40, 0x91, - 0x2, 0x0, 0xa1, 0x10, 0x1, 0x19, 0x10, 0x70, - 0xa, 0x0, 0x0, 0x54, 0xb6, 0x55, 0x0, 0xa0, - 0x0, 0x0, 0x9, 0x10, 0x11, 0xa, 0x0, 0x1, - 0x46, 0xb7, 0x53, 0x0, 0xa0, 0x0, 0x59, 0x30, - 0x0, 0x3, 0x9e, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x20, 0x0, - - /* U+91CF "量" */ - 0x0, 0x0, 0x0, 0x0, 0x0, 0x10, 0x0, 0x0, - 0xb, 0x55, 0x55, 0x55, 0xd0, 0x0, 0x0, 0xb, - 0x55, 0x55, 0x55, 0xb0, 0x0, 0x0, 0xb, 0x55, - 0x55, 0x55, 0xb0, 0x0, 0x0, 0x8, 0x0, 0x0, - 0x0, 0x40, 0x50, 0x17, 0x55, 0x55, 0x55, 0x55, - 0x55, 0x72, 0x0, 0xa, 0x55, 0x57, 0x55, 0xb0, - 0x0, 0x0, 0xb, 0x0, 0x19, 0x0, 0xb0, 0x0, - 0x0, 0xc, 0x55, 0x6b, 0x55, 0xc0, 0x0, 0x0, - 0xd, 0x55, 0x6b, 0x55, 0xb0, 0x0, 0x0, 0x2, - 0x0, 0x19, 0x0, 0x34, 0x0, 0x0, 0x56, 0x55, - 0x6b, 0x55, 0x54, 0x0, 0x5, 0x55, 0x55, 0x6b, - 0x55, 0x56, 0xc1, 0x1, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, - - /* U+91D1 "金" */ - 0x0, 0x0, 0x0, 0x30, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x4, 0xf2, 0x0, 0x0, 0x0, 0x0, 0x0, - 0xc, 0x37, 0x0, 0x0, 0x0, 0x0, 0x0, 0x78, - 0x3, 0x80, 0x0, 0x0, 0x0, 0x5, 0x90, 0x0, - 0x4b, 0x20, 0x0, 0x0, 0x56, 0x0, 0x0, 0x6, - 0xdb, 0x71, 0x15, 0x21, 0x65, 0xc5, 0x56, 0x5, - 0x50, 0x0, 0x0, 0x0, 0xc0, 0x0, 0x0, 0x0, - 0x0, 0x65, 0x55, 0xd5, 0x55, 0x95, 0x0, 0x0, - 0x4, 0x0, 0xc0, 0x7, 0x10, 0x0, 0x0, 0x3, - 0xc0, 0xc0, 0x1c, 0x10, 0x0, 0x0, 0x0, 0xb3, - 0xc0, 0x72, 0x0, 0x0, 0x15, 0x55, 0x65, 0xd5, - 0x95, 0x58, 0xa0, 0x1, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, - - /* U+91DD "針" */ - 0x0, 0x3, 0x10, 0x0, 0x6, 0x10, 0x0, 0x0, - 0xe, 0x50, 0x0, 0xc, 0x10, 0x0, 0x0, 0x58, - 0x79, 0x0, 0xc, 0x0, 0x0, 0x0, 0xa0, 0x8, - 0x30, 0xc, 0x0, 0x0, 0x6, 0x30, 0x22, 0x0, - 0xc, 0x0, 0x0, 0x24, 0x5b, 0x63, 0x35, 0x5d, - 0x56, 0xb0, 0x0, 0x9, 0x10, 0x1, 0xc, 0x0, - 0x0, 0x4, 0x6b, 0x6b, 0x10, 0xc, 0x0, 0x0, - 0x1, 0x9, 0x15, 0x0, 0xc, 0x0, 0x0, 0x0, - 0xa9, 0x2c, 0x0, 0xc, 0x0, 0x0, 0x0, 0xba, - 0x62, 0x0, 0xc, 0x0, 0x0, 0x2, 0x5c, 0x85, - 0x10, 0xc, 0x0, 0x0, 0x9, 0x61, 0x0, 0x0, - 0xc, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x4, - 0x0, 0x0, - - /* U+9244 "鉄" */ - 0x0, 0x1, 0x0, 0x0, 0x1, 0x0, 0x0, 0x0, - 0xe, 0x30, 0x0, 0xd, 0x0, 0x0, 0x0, 0x59, - 0x84, 0xd, 0x1b, 0x0, 0x0, 0x0, 0xa0, 0xc, - 0x5a, 0xb, 0x3, 0x0, 0x6, 0x30, 0x32, 0x77, - 0x5c, 0x57, 0x30, 0x24, 0x6c, 0x53, 0x90, 0xb, - 0x0, 0x0, 0x0, 0xb, 0x3, 0x10, 0x1a, 0x0, - 0x30, 0x5, 0x6c, 0x57, 0x56, 0x7d, 0x55, 0x71, - 0x3, 0xb, 0x9, 0x10, 0x78, 0x20, 0x0, 0x4, - 0x7b, 0x29, 0x0, 0xb0, 0x90, 0x0, 0x1, 0x8b, - 0x42, 0x16, 0x50, 0x75, 0x0, 0x5, 0x8b, 0x73, - 0x47, 0x0, 0xd, 0x70, 0x7, 0x20, 0x4, 0x40, - 0x0, 0x1, 0x92, 0x0, 0x0, 0x1, 0x0, 0x0, - 0x0, 0x0, - - /* U+925B "鉛" */ - 0x0, 0x2, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0xe, 0x30, 0x2, 0x0, 0x3, 0x0, 0x0, 0x59, - 0x85, 0x7, 0x95, 0x5c, 0x0, 0x0, 0xa0, 0xc, - 0x27, 0x50, 0xa, 0x0, 0x6, 0x30, 0x32, 0x8, - 0x30, 0xa, 0x0, 0x24, 0x6c, 0x52, 0xa, 0x0, - 0xb, 0x0, 0x0, 0xb, 0x0, 0x45, 0x0, 0x7, - 0x93, 0x5, 0x5c, 0x5b, 0x33, 0x0, 0x4, 0x0, - 0x2, 0xb, 0x7, 0xc, 0x55, 0x5b, 0x40, 0x4, - 0x6b, 0x2a, 0xb, 0x0, 0x9, 0x20, 0x1, 0x9b, - 0x42, 0x1b, 0x0, 0x9, 0x20, 0x5, 0x8c, 0x74, - 0xc, 0x55, 0x5b, 0x20, 0x7, 0x20, 0x0, 0xb, - 0x0, 0x5, 0x10, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, - - /* U+9280 "銀" */ - 0x0, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x2e, 0x10, 0x2, 0x0, 0x3, 0x0, 0x0, 0x97, - 0x82, 0x1c, 0x55, 0x5d, 0x0, 0x1, 0xa0, 0x2c, - 0xa, 0x0, 0xb, 0x0, 0x9, 0x10, 0x41, 0xc, - 0x55, 0x5b, 0x0, 0x23, 0x6c, 0x52, 0xa, 0x0, - 0xb, 0x0, 0x0, 0xb, 0x0, 0xc, 0x55, 0x5b, - 0x0, 0x6, 0x5c, 0x6a, 0x1a, 0x40, 0x6, 0x50, - 0x2, 0xb, 0x7, 0xa, 0x6, 0x19, 0x30, 0x8, - 0x2b, 0x57, 0xa, 0x8, 0x50, 0x0, 0x5, 0x4b, - 0x61, 0x1a, 0x2, 0xb2, 0x0, 0x4, 0x7c, 0x74, - 0x2c, 0x71, 0x2c, 0xa2, 0xa, 0x20, 0x0, 0x19, - 0x0, 0x0, 0x20, - - /* U+9322 "錢" */ - 0x0, 0x6, 0x0, 0x6, 0x33, 0x20, 0x0, 0x0, - 0x4d, 0x0, 0x6, 0x60, 0xa3, 0x20, 0x0, 0xa2, - 0xa5, 0x46, 0xc5, 0x55, 0x20, 0x4, 0x60, 0x8, - 0x0, 0xb1, 0xa7, 0x0, 0x8, 0x55, 0x92, 0x0, - 0x6e, 0x40, 0x10, 0x10, 0x1b, 0x0, 0x37, 0x77, - 0xb3, 0x51, 0x0, 0xb, 0x4, 0x27, 0x47, 0x5b, - 0xe3, 0x5, 0x5c, 0x66, 0x5, 0x73, 0x42, 0x60, - 0x4, 0xb, 0x1a, 0x56, 0xc5, 0x54, 0x20, 0x5, - 0x6b, 0x63, 0x0, 0xb1, 0x96, 0x0, 0x2, 0x4b, - 0x65, 0x0, 0x4d, 0x80, 0x0, 0xb, 0x96, 0x10, - 0x2, 0x8a, 0x91, 0x41, 0x2, 0x0, 0x1, 0x44, - 0x0, 0x4b, 0xc3, - - /* U+932F "錯" */ - 0x0, 0x0, 0x0, 0x0, 0x0, 0x10, 0x0, 0x0, - 0x3d, 0x0, 0x1, 0xc0, 0xc1, 0x0, 0x0, 0xa7, - 0x81, 0x0, 0xa0, 0xc4, 0x20, 0x2, 0x90, 0x4b, - 0x36, 0xc5, 0xd5, 0x30, 0x9, 0x10, 0x42, 0x0, - 0xa0, 0xc0, 0x0, 0x31, 0x5c, 0x43, 0x55, 0xc5, - 0xd5, 0xb2, 0x0, 0xb, 0x1, 0x10, 0x0, 0x0, - 0x0, 0x6, 0x5c, 0x78, 0xa, 0x55, 0x5b, 0x30, - 0x3, 0xb, 0x9, 0xc, 0x0, 0xb, 0x0, 0x7, - 0x4b, 0x56, 0xd, 0x55, 0x5d, 0x0, 0x4, 0x4b, - 0x52, 0x1c, 0x0, 0xb, 0x0, 0x6, 0x9b, 0x73, - 0xd, 0x55, 0x5d, 0x10, 0x8, 0x10, 0x0, 0xb, - 0x0, 0x6, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, - - /* U+9332 "録" */ - 0x0, 0x2, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x4c, 0x0, 0x25, 0x55, 0x59, 0x10, 0x0, 0xb5, - 0x92, 0x1, 0x0, 0xb, 0x0, 0x2, 0x80, 0x3a, - 0x4, 0x55, 0x5b, 0x0, 0x9, 0x11, 0x60, 0x1, - 0x0, 0xb, 0x0, 0x32, 0x5c, 0x42, 0x55, 0x55, - 0x5c, 0xb3, 0x0, 0xb, 0x0, 0x20, 0xb, 0x0, - 0x20, 0x6, 0x5c, 0x76, 0x39, 0xe, 0x8, 0x80, - 0x3, 0xb, 0x28, 0x8, 0xc, 0x92, 0x0, 0x8, - 0x3b, 0x74, 0x1, 0x3b, 0x72, 0x0, 0x5, 0x3b, - 0x53, 0x47, 0xb, 0xc, 0x30, 0x16, 0x9a, 0x64, - 0x90, 0xb, 0x2, 0xc2, 0x7, 0x10, 0x0, 0x5, - 0xd8, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x10, - 0x0, 0x0, - - /* U+9577 "長" */ - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x6, 0x65, 0x55, 0x55, 0xa2, 0x0, 0x0, 0x8, - 0x50, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8, 0x85, - 0x55, 0x58, 0x50, 0x0, 0x0, 0x8, 0x50, 0x0, - 0x0, 0x0, 0x0, 0x0, 0x8, 0x85, 0x55, 0x58, - 0x70, 0x0, 0x0, 0x8, 0x50, 0x0, 0x0, 0x0, - 0x0, 0x16, 0x5b, 0x85, 0x55, 0x55, 0x57, 0x90, - 0x0, 0xd, 0x0, 0x60, 0x0, 0x60, 0x0, 0x0, - 0xd, 0x0, 0x17, 0x29, 0x60, 0x0, 0x0, 0xd, - 0x0, 0x14, 0xb0, 0x0, 0x0, 0x0, 0xd, 0x37, - 0x10, 0x4c, 0x71, 0x0, 0x0, 0xd, 0x80, 0x0, - 0x0, 0x8e, 0x80, 0x0, 0x1, 0x0, 0x0, 0x0, - 0x0, 0x0, - - /* U+9589 "閉" */ - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xb, 0x55, - 0xd3, 0xa, 0x55, 0xb5, 0xc, 0x0, 0xb0, 0xa, - 0x0, 0xa2, 0xd, 0x55, 0xc0, 0xb, 0x55, 0xb2, - 0xd, 0x55, 0xc0, 0xc, 0x55, 0xb2, 0xc, 0x0, - 0x30, 0x24, 0x0, 0xa2, 0xc, 0x0, 0x0, 0xb1, - 0x0, 0xa2, 0xc, 0x26, 0x58, 0xe5, 0x83, 0xa2, - 0xc, 0x0, 0x2b, 0xb0, 0x0, 0xa2, 0xc, 0x2, - 0x91, 0xb0, 0x0, 0xa2, 0xc, 0x36, 0x0, 0xb0, - 0x0, 0xa2, 0xc, 0x0, 0x29, 0xd0, 0x0, 0xa2, - 0xc, 0x0, 0x0, 0x20, 0x3a, 0xe0, 0x2, 0x0, - 0x0, 0x0, 0x1, 0x10, - - /* U+958B "開" */ - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xc, 0x55, - 0xa5, 0xb, 0x55, 0xb4, 0xc, 0x0, 0x83, 0xc, - 0x0, 0xa2, 0xd, 0x55, 0xa3, 0xc, 0x55, 0xb2, - 0xd, 0x55, 0xa3, 0xc, 0x55, 0xb2, 0xc, 0x0, - 0x20, 0x5, 0x0, 0xa2, 0xc, 0x4, 0x65, 0x56, - 0x80, 0xa2, 0xc, 0x0, 0x55, 0xa, 0x0, 0xa2, - 0xc, 0x15, 0x88, 0x5c, 0x85, 0xa2, 0xc, 0x1, - 0x74, 0xa, 0x0, 0xa2, 0xc, 0x0, 0xa0, 0xa, - 0x0, 0xa2, 0xc, 0x7, 0x30, 0xa, 0x0, 0xa2, - 0xc, 0x10, 0x0, 0x1, 0x2a, 0xe0, 0x0, 0x0, - 0x0, 0x0, 0x0, 0x10, - - /* U+9593 "間" */ - 0x1, 0x0, 0x10, 0x1, 0x0, 0x20, 0xd, 0x55, - 0x97, 0xb, 0x55, 0xc4, 0xc, 0x0, 0x54, 0xb, - 0x0, 0xa2, 0xd, 0x55, 0x94, 0xc, 0x55, 0xb2, - 0xd, 0x55, 0x95, 0xc, 0x55, 0xb2, 0xc, 0x0, - 0x10, 0x3, 0x0, 0xa2, 0xc, 0x0, 0xa5, 0x59, - 0x50, 0xa2, 0xc, 0x0, 0xc0, 0x7, 0x30, 0xa2, - 0xc, 0x0, 0xd5, 0x5a, 0x30, 0xa2, 0xc, 0x0, - 0xc0, 0x7, 0x30, 0xa2, 0xc, 0x0, 0xd5, 0x5a, - 0x30, 0xa2, 0xc, 0x0, 0x70, 0x4, 0x20, 0xa2, - 0xc, 0x0, 0x0, 0x0, 0x2a, 0xe0, 0x2, 0x0, - 0x0, 0x0, 0x1, 0x10, - - /* U+95A2 "関" */ - 0x1, 0x0, 0x10, 0x1, 0x0, 0x1, 0x0, 0xd5, - 0x5c, 0x30, 0xc5, 0x56, 0xc0, 0xd, 0x55, 0xc0, - 0xc, 0x55, 0x6a, 0x0, 0xc0, 0xb, 0x0, 0xb0, - 0x2, 0xa0, 0xd, 0x55, 0xc0, 0xc, 0x55, 0x6a, - 0x0, 0xc0, 0x6, 0x0, 0x71, 0x2, 0xa0, 0xc, - 0x0, 0x73, 0x29, 0x0, 0x2a, 0x0, 0xc0, 0x55, - 0x6a, 0x57, 0x32, 0xa0, 0xc, 0x0, 0x5, 0x70, - 0x3, 0x2a, 0x0, 0xc1, 0x65, 0xd8, 0x55, 0x42, - 0xa0, 0xc, 0x0, 0x67, 0x4a, 0x60, 0x2a, 0x0, - 0xc0, 0x65, 0x0, 0x6, 0x2, 0xa0, 0xc, 0x10, - 0x0, 0x0, 0x17, 0xc9, 0x0, 0x40, 0x0, 0x0, - 0x0, 0x4, 0x0, - - /* U+95DC "關" */ - 0x0, 0x0, 0x0, 0x0, 0x0, 0x1, 0x1, 0xb5, - 0x59, 0x60, 0xc5, 0x56, 0xc0, 0x1b, 0x55, 0x95, - 0xc, 0x55, 0x6a, 0x1, 0xa0, 0x6, 0x50, 0xb0, - 0x1, 0xa0, 0x1b, 0x55, 0x92, 0x9, 0x85, 0x6a, - 0x1, 0xa0, 0x38, 0x21, 0x82, 0x31, 0xa0, 0x1a, - 0x1a, 0x88, 0x67, 0xa5, 0x1a, 0x1, 0xa0, 0x76, - 0x84, 0x93, 0x71, 0xa0, 0x1a, 0x8, 0x37, 0x55, - 0x14, 0x1a, 0x1, 0xa0, 0xa0, 0xb4, 0x70, 0xa1, - 0xa0, 0x1a, 0x17, 0x59, 0x39, 0x5a, 0x1a, 0x1, - 0xa0, 0x6, 0x44, 0x60, 0x1, 0xa0, 0x1a, 0x2, - 0x20, 0x12, 0x5, 0xc7, 0x0, 0x20, 0x0, 0x0, - 0x0, 0x3, 0x0, - - /* U+95F0 "闰" */ - 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xb, - 0x20, 0x55, 0x55, 0x55, 0x90, 0x15, 0x64, 0x1, - 0x0, 0x0, 0xc, 0x2, 0xb0, 0x0, 0x0, 0x0, - 0x30, 0xc0, 0x2a, 0x17, 0x55, 0xb5, 0x67, 0xc, - 0x2, 0xa0, 0x0, 0xc, 0x0, 0x0, 0xc0, 0x2a, - 0x0, 0x0, 0xc0, 0x42, 0xc, 0x2, 0xa0, 0x36, - 0x5d, 0x55, 0x30, 0xc0, 0x2a, 0x0, 0x0, 0xc0, - 0x0, 0xc, 0x2, 0xa0, 0x0, 0xc, 0x0, 0x60, - 0xc0, 0x2a, 0x46, 0x55, 0x55, 0x55, 0x2c, 0x2, - 0xa0, 0x0, 0x0, 0x0, 0x0, 0xb0, 0x29, 0x0, - 0x0, 0x0, 0x5, 0xd8, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x1, 0x0, - - /* U+9633 "阳" */ - 0x65, 0x58, 0x51, 0x0, 0x0, 0x10, 0x92, 0xb, - 0x3b, 0x55, 0x55, 0xd0, 0x92, 0x17, 0xb, 0x0, - 0x0, 0xb0, 0x92, 0x60, 0xb, 0x0, 0x0, 0xb0, - 0x92, 0x60, 0xb, 0x0, 0x0, 0xb0, 0x92, 0x9, - 0xb, 0x55, 0x55, 0xb0, 0x92, 0x6, 0x6b, 0x0, - 0x0, 0xb0, 0x92, 0x7, 0x7b, 0x0, 0x0, 0xb0, - 0x95, 0xbe, 0x1b, 0x0, 0x0, 0xb0, 0x92, 0x31, - 0xb, 0x0, 0x0, 0xb0, 0x92, 0x0, 0xb, 0x55, - 0x55, 0xc0, 0x92, 0x0, 0x8, 0x0, 0x0, 0x70, - 0x20, 0x0, 0x0, 0x0, 0x0, 0x0, - - /* U+9644 "附" */ - 0x0, 0x0, 0x0, 0x10, 0x0, 0x0, 0x1, 0x85, - 0x93, 0xb, 0x40, 0xc, 0x0, 0x1a, 0xa, 0x1, - 0xb0, 0x0, 0xb0, 0x1, 0xa0, 0x80, 0x73, 0x0, - 0xb, 0x0, 0x1a, 0x52, 0xd, 0x24, 0x55, 0xc8, - 0x31, 0xa3, 0x15, 0xa1, 0x10, 0xb, 0x0, 0x1a, - 0x8, 0x29, 0x14, 0x0, 0xb0, 0x1, 0xa0, 0x72, - 0x91, 0x3b, 0xb, 0x0, 0x1a, 0x7, 0x49, 0x10, - 0x50, 0xb0, 0x1, 0xba, 0xc0, 0x91, 0x0, 0xb, - 0x0, 0x1a, 0x10, 0x9, 0x10, 0x0, 0xb0, 0x1, - 0xa0, 0x0, 0x91, 0x2, 0x1b, 0x0, 0x19, 0x0, - 0x8, 0x10, 0x2c, 0x60, 0x0, 0x10, 0x0, 0x0, - 0x0, 0x0, 0x0, - - /* U+964D "降" */ - 0x0, 0x0, 0x0, 0x25, 0x0, 0x0, 0x2, 0xa5, - 0x89, 0x7, 0xa5, 0x59, 0x10, 0x1a, 0xa, 0x20, - 0xb2, 0x3, 0xb0, 0x1, 0xa0, 0x90, 0x53, 0x71, - 0xb0, 0x0, 0x1a, 0x32, 0x13, 0x3, 0xe2, 0x0, - 0x1, 0xa1, 0x40, 0x2, 0x94, 0xa6, 0x20, 0x1a, - 0x6, 0x35, 0x50, 0xa1, 0x59, 0x11, 0xa0, 0x2a, - 0x36, 0x5c, 0x58, 0x50, 0x1a, 0x3, 0xa5, 0x30, - 0xb0, 0x0, 0x1, 0xb9, 0xe3, 0xb1, 0xb, 0x0, - 0x30, 0x1a, 0x1, 0x28, 0x55, 0xc5, 0x57, 0x21, - 0xa0, 0x0, 0x0, 0xb, 0x0, 0x0, 0x1a, 0x0, - 0x0, 0x0, 0xc0, 0x0, 0x0, 0x20, 0x0, 0x0, - 0x3, 0x0, 0x0, - - /* U+9650 "限" */ - 0x75, 0x5a, 0x8, 0x55, 0x5a, 0x40, 0xa, 0x12, - 0x90, 0xb0, 0x0, 0xa1, 0x0, 0xa1, 0x62, 0xb, - 0x0, 0xa, 0x10, 0xa, 0x16, 0x0, 0xd5, 0x55, - 0xc1, 0x0, 0xa1, 0x50, 0xb, 0x0, 0xa, 0x20, - 0xa, 0x12, 0x50, 0xd6, 0x55, 0xc2, 0x0, 0xa1, - 0xa, 0xb, 0x14, 0x2, 0x90, 0xa, 0x10, 0xb0, - 0xb0, 0x71, 0xa5, 0x0, 0xa5, 0xbd, 0xb, 0x7, - 0x70, 0x0, 0xa, 0x14, 0x10, 0xb0, 0x1b, 0x20, - 0x0, 0xa1, 0x0, 0xd, 0x82, 0x2d, 0x93, 0xa, - 0x10, 0x1, 0xc1, 0x0, 0x1a, 0x40, 0x20, 0x0, - 0x0, 0x0, 0x0, 0x0, 0x0, - - /* U+9662 "院" */ - 0x0, 0x0, 0x0, 0x1, 0x0, 0x0, 0x65, 0x58, - 0x0, 0xa, 0x10, 0x0, 0xa0, 0x48, 0x55, 0x5b, - 0x65, 0x83, 0xa0, 0x71, 0xb0, 0x0, 0x0, 0x80, - 0xa0, 0x60, 0x40, 0x0, 0x5, 0x0, 0xa0, 0x40, - 0x5, 0x55, 0x55, 0x0, 0xa0, 0x53, 0x0, 0x0, - 0x0, 0x40, 0xa0, 0xb, 0x56, 0xb5, 0xb5, 0x71, - 0xa0, 0xc, 0x0, 0xb0, 0xb0, 0x0, 0xa3, 0xbb, - 0x1, 0xa0, 0xb0, 0x0, 0xa0, 0x30, 0x6, 0x60, - 0xb0, 0x4, 0xa0, 0x0, 0x1a, 0x0, 0xb0, 0x17, - 0xa0, 0x3, 0x70, 0x0, 0xaa, 0xba, 0x40, 0x11, - 0x0, 0x0, 0x0, 0x0, - - /* U+9664 "除" */ - 0x0, 0x0, 0x0, 0x4, 0x0, 0x0, 0x6, 0x55, - 0xa1, 0x4, 0xe1, 0x0, 0x0, 0xa0, 0x2a, 0x0, - 0xc2, 0x70, 0x0, 0xa, 0x7, 0x20, 0x66, 0x4, - 0x80, 0x0, 0xa0, 0x60, 0x38, 0x0, 0x6, 0xc5, - 0xa, 0x4, 0x25, 0x46, 0x85, 0x83, 0x70, 0xa0, - 0x54, 0x0, 0xb, 0x0, 0x0, 0xa, 0x0, 0xc3, - 0x55, 0xc5, 0x5b, 0x20, 0xa0, 0x1c, 0x12, 0xb, - 0x0, 0x0, 0xa, 0x4e, 0x50, 0xd3, 0xb0, 0x61, - 0x0, 0xa0, 0x0, 0x85, 0xb, 0x1, 0xb2, 0xa, - 0x0, 0x64, 0x0, 0xb0, 0x5, 0x90, 0xb0, 0x1, - 0x4, 0xbd, 0x0, 0x1, 0x1, 0x0, 0x0, 0x1, - 0x0, 0x0, 0x0, - - /* U+9678 "陸" */ - 0x0, 0x0, 0x0, 0x2, 0x0, 0x0, 0x7, 0x55, - 0x91, 0x0, 0xc1, 0x0, 0x0, 0xb0, 0xb, 0x0, - 0xb, 0x0, 0x60, 0xb, 0x5, 0x32, 0x65, 0xc5, - 0x55, 0x0, 0xb0, 0x50, 0x0, 0xb, 0x0, 0x3, - 0xb, 0x5, 0x16, 0x58, 0x65, 0x55, 0x60, 0xb0, - 0x34, 0x7, 0xa1, 0x6, 0x91, 0xb, 0x0, 0xb5, - 0x50, 0xb1, 0x5, 0x70, 0xb0, 0x2b, 0x10, 0xb, - 0x0, 0x0, 0xb, 0x6d, 0x23, 0x65, 0xc5, 0x69, - 0x0, 0xb0, 0x0, 0x0, 0xb, 0x0, 0x0, 0xb, - 0x0, 0x0, 0x0, 0xb0, 0x0, 0x20, 0xb0, 0x6, - 0x55, 0x58, 0x55, 0x77, 0x1, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x0, - - /* U+967D "陽" */ - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x9, 0x55, - 0xb2, 0xa5, 0x55, 0x5c, 0x0, 0xb0, 0x1b, 0xb, - 0x0, 0x0, 0xb0, 0xb, 0x6, 0x20, 0xb5, 0x55, - 0x5b, 0x0, 0xb0, 0x50, 0xb, 0x55, 0x55, 0xc0, - 0xb, 0x6, 0x0, 0x50, 0x0, 0x3, 0x10, 0xb0, - 0x27, 0x65, 0x85, 0x55, 0x59, 0xb, 0x0, 0xb0, - 0x2b, 0x0, 0x0, 0x30, 0xb1, 0x1d, 0x1a, 0x5d, - 0x6c, 0x6b, 0xb, 0x4d, 0x67, 0x17, 0x57, 0x53, - 0x80, 0xb0, 0x2, 0x5, 0x62, 0xa0, 0x56, 0xb, - 0x0, 0x4, 0x22, 0x91, 0x9, 0x30, 0xa0, 0x0, - 0x4, 0x60, 0x4b, 0xc0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x30, 0x0, - - /* U+968E "階" */ - 0x0, 0x0, 0x0, 0x0, 0x10, 0x0, 0x9, 0x55, - 0xb5, 0xb0, 0xc, 0x0, 0x0, 0xa0, 0xb, 0x1a, - 0x1, 0xb0, 0xb5, 0xa, 0x6, 0x21, 0xc6, 0x5c, - 0x82, 0x0, 0xa0, 0x60, 0x1a, 0x0, 0xb0, 0x4, - 0xa, 0x6, 0x1, 0xc6, 0x2b, 0x0, 0x90, 0xa0, - 0x18, 0x19, 0x4, 0x49, 0x97, 0xa, 0x0, 0xb0, - 0x11, 0x80, 0x2, 0x0, 0xa4, 0x8d, 0xc, 0x55, - 0x55, 0xd0, 0xa, 0x5, 0x10, 0xb0, 0x0, 0xb, - 0x0, 0xa0, 0x0, 0xc, 0x55, 0x55, 0xb0, 0xb, - 0x0, 0x0, 0xb0, 0x0, 0xb, 0x0, 0xa0, 0x0, - 0xc, 0x55, 0x55, 0xc0, 0x0, 0x0, 0x0, 0x10, - 0x0, 0x0, 0x0, - - /* U+969B "際" */ - 0x0, 0x0, 0x1, 0x10, 0x0, 0x0, 0x7, 0x55, - 0xa1, 0x86, 0x24, 0x0, 0x20, 0xb0, 0x3a, 0xb, - 0x5c, 0x85, 0x97, 0xb, 0x8, 0x17, 0x75, 0xa3, - 0x38, 0x0, 0xb1, 0x53, 0x75, 0x93, 0xb, 0x20, - 0xb, 0x6, 0x0, 0x57, 0x0, 0x3c, 0x40, 0xb0, - 0x45, 0x35, 0x55, 0x58, 0x58, 0x1b, 0x0, 0xc1, - 0x1, 0x0, 0x0, 0x0, 0xb3, 0x5b, 0x26, 0x55, - 0x75, 0x77, 0xb, 0x8, 0x10, 0x13, 0xb, 0x20, - 0x0, 0xb0, 0x0, 0xb, 0x60, 0xb1, 0xa2, 0xb, - 0x0, 0x17, 0x20, 0xb, 0x2, 0xe0, 0xb0, 0x3, - 0x0, 0x6d, 0x80, 0x3, 0x1, 0x0, 0x0, 0x0, - 0x20, 0x0, 0x0, - - /* U+969C "障" */ - 0x0, 0x0, 0x0, 0x11, 0x0, 0x0, 0x6, 0x45, - 0x70, 0x0, 0xc0, 0x1, 0x0, 0xc0, 0x77, 0x17, - 0x57, 0x57, 0x90, 0xb, 0x9, 0x0, 0x19, 0x4, - 0xa0, 0x0, 0xb0, 0x61, 0x33, 0xa3, 0x83, 0x49, - 0xb, 0x5, 0x3, 0x42, 0x22, 0x25, 0x20, 0xb0, - 0x54, 0xc, 0x55, 0x55, 0xd1, 0xb, 0x0, 0xc0, - 0xc5, 0x55, 0x5c, 0x0, 0xb0, 0xe, 0xb, 0x0, - 0x0, 0xb0, 0xb, 0x5d, 0x80, 0xa5, 0xc5, 0x59, - 0x0, 0xb0, 0x12, 0x65, 0x5c, 0x55, 0x5b, 0x1b, - 0x0, 0x0, 0x0, 0xb0, 0x0, 0x0, 0xc0, 0x0, - 0x0, 0xc, 0x0, 0x0, 0x1, 0x0, 0x0, 0x0, - 0x30, 0x0, 0x0, - - /* U+96A3 "隣" */ - 0x0, 0x0, 0x0, 0x2, 0x0, 0x0, 0x7, 0x56, - 0x80, 0x71, 0x94, 0xa, 0x0, 0xb0, 0x74, 0x2, - 0x89, 0x27, 0x40, 0xb, 0x8, 0x4, 0x66, 0xc8, - 0x85, 0x70, 0xb3, 0x10, 0x2, 0xaa, 0x65, 0x0, - 0xb, 0x14, 0x5, 0x60, 0x92, 0x5c, 0x70, 0xb0, - 0x74, 0x14, 0x6, 0x10, 0x31, 0xb, 0x3, 0x86, - 0x92, 0x10, 0x19, 0x20, 0xb5, 0x97, 0xa5, 0xc4, - 0x86, 0xb5, 0xb, 0x6, 0x78, 0x1b, 0x3b, 0x19, - 0x0, 0xb0, 0x0, 0x49, 0x37, 0x65, 0xb7, 0x1b, - 0x0, 0x4, 0x70, 0x0, 0x19, 0x0, 0xb0, 0x4, - 0x50, 0x0, 0x1, 0x90, 0x1, 0x0, 0x0, 0x0, - 0x0, 0x1, 0x0, - - /* U+96A8 "隨" */ - 0x0, 0x0, 0x0, 0x0, 0x30, 0x0, 0x8, 0x5a, - 0x40, 0x0, 0xd, 0x0, 0x20, 0xa0, 0xb2, 0x64, - 0x69, 0x95, 0x55, 0xa, 0x35, 0xb, 0x3, 0xb5, - 0x78, 0x30, 0xa5, 0x0, 0x13, 0x62, 0x3a, 0x27, - 0xa, 0x33, 0x2, 0x2, 0x42, 0x24, 0x20, 0xa0, - 0x95, 0xb5, 0xb, 0x55, 0xa3, 0xa, 0x8, 0x39, - 0x10, 0xc5, 0x5a, 0x10, 0xb7, 0xc1, 0x91, 0xa, - 0x0, 0x81, 0xa, 0x33, 0x9, 0x10, 0xc5, 0x5a, - 0x10, 0xa0, 0x0, 0x91, 0xa, 0x4, 0xa1, 0xa, - 0x0, 0x83, 0x65, 0x30, 0x17, 0x0, 0xa0, 0x26, - 0x0, 0x4a, 0xdc, 0xdb, 0x20, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x0, - - /* U+96BB "隻" */ - 0x0, 0x0, 0x0, 0x31, 0x0, 0x0, 0x0, 0x0, - 0x0, 0xc1, 0x1d, 0x0, 0x0, 0x0, 0x0, 0x8, - 0x70, 0x4, 0x0, 0x8, 0x0, 0x0, 0x5f, 0x55, - 0x5d, 0x55, 0x55, 0x10, 0x3, 0x5b, 0x55, 0x5d, - 0x55, 0x83, 0x0, 0x2, 0xb, 0x0, 0xc, 0x0, - 0x33, 0x0, 0x0, 0xb, 0x55, 0x5d, 0x55, 0x54, - 0x0, 0x0, 0xb, 0x44, 0x49, 0x44, 0x49, 0x30, - 0x0, 0x36, 0x55, 0x55, 0x58, 0x50, 0x0, 0x0, - 0x10, 0x61, 0x0, 0x3c, 0x30, 0x0, 0x0, 0x0, - 0x8, 0x57, 0xa0, 0x0, 0x0, 0x0, 0x0, 0x6, - 0xcc, 0x62, 0x0, 0x0, 0x2, 0x46, 0x72, 0x0, - 0x49, 0xbc, 0xb1, 0x1, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, - - /* U+96C6 "集" */ - 0x0, 0x0, 0x50, 0x20, 0x0, 0x0, 0x0, 0x0, - 0x3, 0xc1, 0x1c, 0x0, 0x0, 0x0, 0x0, 0xb, - 0x75, 0x59, 0x55, 0x5a, 0x40, 0x0, 0x5d, 0x0, - 0xb, 0x0, 0x0, 0x0, 0x2, 0x7c, 0x55, 0x5c, - 0x55, 0x77, 0x0, 0x15, 0xb, 0x0, 0xb, 0x0, - 0x33, 0x0, 0x0, 0xc, 0x55, 0x5c, 0x55, 0x54, - 0x0, 0x0, 0xc, 0x55, 0x5a, 0x55, 0x5a, 0x20, - 0x0, 0x7, 0x0, 0x1b, 0x0, 0x0, 0x30, 0x16, - 0x55, 0x57, 0xbc, 0x85, 0x55, 0x73, 0x0, 0x0, - 0x3b, 0x2a, 0x35, 0x0, 0x0, 0x0, 0x7, 0x70, - 0x1a, 0x4, 0xb5, 0x0, 0x4, 0x61, 0x0, 0x1b, - 0x0, 0x19, 0xe3, 0x10, 0x0, 0x0, 0x2, 0x0, - 0x0, 0x0, - - /* U+96D1 "雑" */ - 0x0, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0xc, 0x0, 0x0, 0x76, 0x70, 0x0, 0x3, 0x6c, - 0x6a, 0x0, 0xc1, 0xc0, 0x0, 0x0, 0x28, 0x47, - 0x1, 0xc5, 0x75, 0xb1, 0x0, 0x83, 0x74, 0x57, - 0xa0, 0xb0, 0x0, 0x3, 0x61, 0x4a, 0x99, 0xa0, - 0xb0, 0x0, 0x3, 0x5, 0x70, 0x32, 0xc5, 0xc5, - 0x80, 0x2, 0x37, 0x83, 0x81, 0xa0, 0xb0, 0x0, - 0x2, 0x26, 0x72, 0x21, 0xa0, 0xb0, 0x40, 0x0, - 0xb6, 0x95, 0x1, 0xc5, 0xc5, 0x50, 0x3, 0x65, - 0x67, 0x71, 0xa0, 0xb0, 0x0, 0x6, 0x5, 0x60, - 0x51, 0xa0, 0xb0, 0x51, 0x0, 0x3c, 0x50, 0x1, - 0xc5, 0x55, 0x52, 0x0, 0x2, 0x0, 0x0, 0x20, - 0x0, 0x0, - - /* U+96D6 "雖" */ - 0x1, 0x10, 0x4, 0x1, 0xb2, 0x70, 0x0, 0x2, - 0xa5, 0x5c, 0x5, 0x90, 0x94, 0x0, 0x1, 0x70, - 0xa, 0x9, 0x65, 0x65, 0x90, 0x2, 0xa8, 0x5a, - 0xe, 0x10, 0xa0, 0x0, 0x0, 0x1a, 0x0, 0x5a, - 0x10, 0xa0, 0x0, 0x9, 0x5b, 0x58, 0x49, 0x65, - 0xc6, 0x70, 0xa, 0xa, 0x4, 0x29, 0x10, 0xa0, - 0x0, 0xa, 0xa, 0x4, 0x29, 0x10, 0xa1, 0x30, - 0x8, 0x5b, 0x56, 0x19, 0x65, 0xc5, 0x40, 0x0, - 0xa, 0x5, 0x9, 0x10, 0xa0, 0x0, 0x4, 0x6c, - 0x78, 0x49, 0x10, 0xa0, 0x60, 0x9, 0x52, 0x2, - 0x6a, 0x65, 0x55, 0x51, 0x0, 0x0, 0x0, 0x1, - 0x0, 0x0, 0x0, - - /* U+96D9 "雙" */ - 0x0, 0x0, 0x20, 0x0, 0x3, 0x0, 0x0, 0x0, - 0x67, 0x92, 0x5, 0x87, 0x50, 0x0, 0x0, 0xd5, - 0x67, 0x69, 0x68, 0x69, 0x20, 0x7, 0xb0, 0xa0, - 0xf, 0xa, 0x1, 0x0, 0x13, 0xc5, 0xc7, 0x6b, - 0x5c, 0x57, 0x0, 0x0, 0xa0, 0xa2, 0x1a, 0xa, - 0x3, 0x0, 0x0, 0xc5, 0xc5, 0x2a, 0x5c, 0x55, - 0x0, 0x0, 0xc5, 0x95, 0x6b, 0x5b, 0x58, 0x30, - 0x0, 0x40, 0x0, 0x3, 0x0, 0x30, 0x0, 0x0, - 0x66, 0x95, 0x55, 0x5d, 0x80, 0x0, 0x0, 0x0, - 0x26, 0x2, 0xa3, 0x0, 0x0, 0x0, 0x0, 0x1, - 0xcd, 0x20, 0x0, 0x0, 0x0, 0x15, 0x65, 0x12, - 0x8a, 0x98, 0x72, 0x4, 0x30, 0x0, 0x0, 0x0, - 0x14, 0x30, - - /* U+96E2 "離" */ - 0x0, 0x2, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x4, 0x80, 0x10, 0x84, 0x70, 0x0, 0x6, 0x56, - 0x85, 0x91, 0xa0, 0x83, 0x0, 0x4, 0x34, 0x85, - 0x30, 0xc5, 0x66, 0x90, 0x7, 0x26, 0xb1, 0x95, - 0xb0, 0xb0, 0x0, 0x7, 0x51, 0x52, 0x95, 0xb0, - 0xb0, 0x0, 0x8, 0x57, 0x85, 0x80, 0xc5, 0xc6, - 0x60, 0x3, 0x19, 0x51, 0x60, 0xb0, 0xb0, 0x0, - 0xa, 0x3a, 0x53, 0xc0, 0xb0, 0xb0, 0x20, 0xa, - 0x65, 0x75, 0xa0, 0xd5, 0xc5, 0x40, 0xa, 0x54, - 0x13, 0xa0, 0xb0, 0xb0, 0x0, 0xa, 0x0, 0x0, - 0xa0, 0xb0, 0xb0, 0x40, 0xa, 0x0, 0x3b, 0x80, - 0xd5, 0x55, 0x50, 0x2, 0x0, 0x0, 0x0, 0x10, - 0x0, 0x0, - - /* U+96E3 "難" */ - 0x0, 0x10, 0x0, 0x0, 0x40, 0x10, 0x0, 0x0, - 0xa0, 0x74, 0x3, 0xe1, 0x93, 0x0, 0x15, 0xb5, - 0x97, 0x87, 0x60, 0x35, 0x20, 0x1, 0x90, 0x73, - 0xb, 0x65, 0xa6, 0x80, 0x0, 0x8a, 0x82, 0x2e, - 0x20, 0xb0, 0x0, 0x6, 0x5c, 0x5a, 0x69, 0x20, - 0xb0, 0x0, 0x9, 0x1a, 0xa, 0x9, 0x65, 0xc6, - 0x40, 0x8, 0x5c, 0x58, 0x9, 0x20, 0xb0, 0x0, - 0x4, 0x5c, 0x58, 0x19, 0x30, 0xb2, 0x20, 0x15, - 0x5c, 0x56, 0x79, 0x64, 0xc4, 0x20, 0x1, 0x9, - 0x11, 0x9, 0x20, 0xb0, 0x0, 0x0, 0x83, 0xa, - 0x49, 0x20, 0xb0, 0x40, 0x6, 0x30, 0x1, 0x49, - 0x65, 0x65, 0x60, 0x10, 0x0, 0x0, 0x1, 0x0, - 0x0, 0x0, - - /* U+96E8 "雨" */ - 0x0, 0x0, 0x0, 0x0, 0x0, 0x44, 0x45, 0x55, - 0x5c, 0x55, 0x55, 0x54, 0x0, 0x0, 0xb, 0x0, - 0x0, 0x20, 0xc, 0x55, 0x5c, 0x55, 0x55, 0xe0, - 0xc, 0x26, 0xb, 0x6, 0x0, 0xc0, 0xc, 0x8, - 0x7b, 0x4, 0xb0, 0xc0, 0xc, 0x0, 0x2b, 0x0, - 0x30, 0xc0, 0xc, 0x33, 0xb, 0x3, 0x0, 0xc0, - 0xc, 0xb, 0x4b, 0x6, 0xa0, 0xc0, 0xc, 0x1, - 0x2b, 0x0, 0x50, 0xc0, 0xc, 0x0, 0xb, 0x0, - 0x45, 0xb0, 0xa, 0x0, 0x7, 0x0, 0x1b, 0x60, - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - - /* U+96EA "雪" */ - 0x0, 0x0, 0x0, 0x0, 0x0, 0x10, 0x0, 0x0, - 0x46, 0x55, 0x65, 0x55, 0xc4, 0x0, 0x0, 0x0, - 0x0, 0x73, 0x0, 0x0, 0x10, 0x4, 0x75, 0x55, - 0xa7, 0x55, 0x58, 0xb0, 0xb, 0x35, 0x53, 0x73, - 0x45, 0x44, 0x0, 0x3, 0x0, 0x0, 0x74, 0x0, - 0x0, 0x0, 0x0, 0x5, 0x53, 0x84, 0x45, 0x50, - 0x0, 0x0, 0x0, 0x0, 0x30, 0x0, 0x40, 0x0, - 0x0, 0x46, 0x55, 0x55, 0x55, 0xc2, 0x0, 0x0, - 0x0, 0x0, 0x0, 0x0, 0xb0, 0x0, 0x0, 0x16, - 0x55, 0x55, 0x55, 0xc0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, 0xb0, 0x0, 0x0, 0x65, 0x55, 0x55, - 0x55, 0xd1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x20, 0x0, - - /* U+96F2 "雲" */ - 0x0, 0x0, 0x0, 0x0, 0x1, 0x0, 0x0, 0x7, - 0x55, 0x77, 0x55, 0x83, 0x0, 0x3, 0x0, 0x5, - 0x60, 0x0, 0x12, 0x2, 0xa5, 0x55, 0x89, 0x55, - 0x59, 0xb0, 0x93, 0x55, 0x35, 0x63, 0x54, 0x50, - 0x0, 0x0, 0x0, 0x57, 0x0, 0x0, 0x0, 0x0, - 0x55, 0x34, 0x44, 0x54, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x70, 0x0, 0x1, 0x65, 0x55, 0x55, - 0x55, 0x20, 0x3, 0x65, 0x55, 0x65, 0x55, 0x58, - 0x80, 0x0, 0x0, 0xa8, 0x2, 0x20, 0x0, 0x0, - 0x5, 0x71, 0x0, 0x6, 0xa1, 0x0, 0x6, 0xeb, - 0x98, 0x65, 0x57, 0x90, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x1, 0x0, - - /* U+96FB "電" */ - 0x0, 0x0, 0x0, 0x0, 0x2, 0x0, 0x0, 0x6, - 0x55, 0x59, 0x55, 0x91, 0x0, 0x7, 0x55, 0x56, - 0xc5, 0x55, 0x69, 0x3, 0x90, 0x0, 0x1a, 0x0, - 0x5, 0x60, 0x32, 0x45, 0x42, 0xa3, 0x55, 0x30, - 0x0, 0x4, 0x54, 0x29, 0x35, 0x50, 0x0, 0x0, - 0x20, 0x0, 0x0, 0x3, 0x0, 0x0, 0xc, 0x55, - 0x6b, 0x55, 0xc3, 0x0, 0x0, 0xc5, 0x56, 0xc5, - 0x5c, 0x0, 0x0, 0xb, 0x0, 0x1a, 0x0, 0xb0, - 0x0, 0x0, 0xc5, 0x56, 0xc5, 0x5c, 0x3, 0x0, - 0x5, 0x0, 0x1a, 0x0, 0x30, 0x70, 0x0, 0x0, - 0x0, 0xe9, 0x99, 0x9d, 0x10, - - /* U+9700 "需" */ - 0x0, 0x0, 0x0, 0x0, 0x0, 0x20, 0x0, 0x0, - 0x36, 0x55, 0x77, 0x55, 0x85, 0x0, 0x1, 0x65, - 0x55, 0x99, 0x55, 0x56, 0x80, 0x8, 0x40, 0x0, - 0x66, 0x0, 0x6, 0x50, 0x4, 0x4, 0x52, 0x66, - 0x45, 0x31, 0x0, 0x0, 0x5, 0x52, 0x66, 0x45, - 0x30, 0x0, 0x3, 0x55, 0x55, 0x55, 0x55, 0x5b, - 0x40, 0x1, 0x0, 0x3, 0x80, 0x0, 0x0, 0x0, - 0x0, 0x85, 0x59, 0x55, 0x75, 0x5b, 0x0, 0x0, - 0xb1, 0xb, 0x0, 0xb0, 0x1a, 0x0, 0x0, 0xb1, - 0xb, 0x0, 0xb0, 0x1a, 0x0, 0x0, 0xb1, 0xb, - 0x0, 0xb0, 0x1a, 0x0, 0x0, 0xb0, 0x7, 0x0, - 0x52, 0xb8, 0x0, 0x0, 0x20, 0x0, 0x0, 0x0, - 0x10, 0x0, - - /* U+9707 "震" */ - 0x0, 0x0, 0x0, 0x0, 0x0, 0x20, 0x0, 0x0, - 0x26, 0x55, 0x95, 0x56, 0x80, 0x0, 0x0, 0x85, - 0x55, 0xc5, 0x55, 0x59, 0x40, 0x8, 0x50, 0x0, - 0xb0, 0x0, 0x9, 0x10, 0x3, 0x5, 0x52, 0xb0, - 0x55, 0x30, 0x0, 0x0, 0x24, 0x42, 0x80, 0x44, - 0x52, 0x0, 0x0, 0xb5, 0x55, 0x55, 0x55, 0x65, - 0x0, 0x0, 0xb0, 0x65, 0x55, 0x55, 0x90, 0x0, - 0x0, 0xc5, 0x55, 0x55, 0x55, 0x5a, 0x50, 0x0, - 0xb0, 0xb0, 0x42, 0x2, 0x80, 0x0, 0x0, 0xa0, - 0xb0, 0x8, 0x57, 0x20, 0x0, 0x6, 0x30, 0xb3, - 0x51, 0x99, 0x30, 0x0, 0x15, 0x0, 0xb6, 0x0, - 0x3, 0xaf, 0x80, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, - - /* U+9752 "青" */ - 0x0, 0x0, 0x0, 0x40, 0x0, 0x0, 0x0, 0x0, - 0x0, 0xd, 0x0, 0x1, 0x20, 0x6, 0x55, 0x55, - 0xd5, 0x55, 0x88, 0x0, 0x4, 0x55, 0x5d, 0x55, - 0x6a, 0x0, 0x0, 0x10, 0x0, 0xc0, 0x0, 0x2, - 0x3, 0x65, 0x55, 0x59, 0x55, 0x55, 0x96, 0x0, - 0x7, 0x55, 0x55, 0x58, 0x20, 0x0, 0x0, 0xc0, - 0x0, 0x0, 0xb1, 0x0, 0x0, 0xc, 0x55, 0x55, - 0x5c, 0x10, 0x0, 0x0, 0xc0, 0x0, 0x0, 0xb1, - 0x0, 0x0, 0xc, 0x55, 0x55, 0x5c, 0x10, 0x0, - 0x0, 0xc0, 0x0, 0x0, 0xb0, 0x0, 0x0, 0xc, - 0x0, 0x3, 0xae, 0x0, 0x0, 0x0, 0x30, 0x0, - 0x1, 0x10, 0x0, - - /* U+9759 "静" */ - 0x0, 0x3, 0x0, 0x0, 0x40, 0x0, 0x0, 0x0, - 0xb, 0x11, 0x1, 0xc1, 0x10, 0x0, 0x7, 0x5c, - 0x57, 0x48, 0x75, 0xd2, 0x0, 0x4, 0x5c, 0x58, - 0x36, 0x2, 0x50, 0x0, 0x1, 0xa, 0x0, 0x36, - 0x69, 0x5c, 0x10, 0x26, 0x58, 0x57, 0x80, 0xa, - 0xa, 0x0, 0x5, 0x55, 0x59, 0x35, 0x5b, 0x5c, - 0x90, 0x9, 0x10, 0xa, 0x1, 0xa, 0xa, 0x0, - 0x9, 0x65, 0x5a, 0x1, 0x1a, 0x1b, 0x0, 0x9, - 0x65, 0x5a, 0x5, 0x4b, 0x36, 0x0, 0x9, 0x10, - 0xa, 0x0, 0xa, 0x0, 0x0, 0x9, 0x10, 0xa, - 0x0, 0x9, 0x0, 0x0, 0x9, 0x14, 0xc7, 0x5, - 0xc7, 0x0, 0x0, 0x1, 0x0, 0x10, 0x0, 0x20, - 0x0, 0x0, - - /* U+975E "非" */ - 0x0, 0x0, 0x1, 0x0, 0x10, 0x0, 0x0, 0x0, - 0x0, 0xc, 0x10, 0xe0, 0x0, 0x0, 0x0, 0x0, - 0xc, 0x0, 0xc0, 0x0, 0x0, 0x4, 0x55, 0x5d, - 0x0, 0xd5, 0x57, 0x80, 0x0, 0x0, 0xc, 0x0, - 0xc0, 0x0, 0x0, 0x0, 0x0, 0xc, 0x0, 0xc0, - 0x0, 0x0, 0x1, 0x75, 0x5d, 0x0, 0xd5, 0x58, - 0x40, 0x0, 0x0, 0xc, 0x0, 0xc0, 0x0, 0x0, - 0x0, 0x0, 0xc, 0x0, 0xc0, 0x0, 0x0, 0x6, - 0x55, 0x5d, 0x0, 0xd5, 0x55, 0xb1, 0x0, 0x0, - 0xc, 0x0, 0xc0, 0x0, 0x0, 0x0, 0x0, 0xc, - 0x0, 0xc0, 0x0, 0x0, 0x0, 0x0, 0xc, 0x0, - 0xd0, 0x0, 0x0, 0x0, 0x0, 0x2, 0x0, 0x10, - 0x0, 0x0, - - /* U+9762 "面" */ - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x10, 0x6, - 0x55, 0x55, 0x75, 0x55, 0x56, 0xc1, 0x0, 0x0, - 0x0, 0xd1, 0x0, 0x0, 0x0, 0x0, 0x10, 0x4, - 0x30, 0x0, 0x2, 0x0, 0x0, 0xd5, 0x5b, 0x55, - 0xb5, 0x5d, 0x10, 0x0, 0xc0, 0xb, 0x0, 0xb0, - 0xc, 0x0, 0x0, 0xc0, 0xb, 0x55, 0xc0, 0xc, - 0x0, 0x0, 0xc0, 0xb, 0x0, 0xb0, 0xc, 0x0, - 0x0, 0xc0, 0xb, 0x0, 0xb0, 0xc, 0x0, 0x0, - 0xc0, 0xb, 0x55, 0xc0, 0xc, 0x0, 0x0, 0xc0, - 0xb, 0x0, 0xb0, 0xc, 0x0, 0x0, 0xd5, 0x5c, - 0x55, 0xd5, 0x5d, 0x0, 0x0, 0xb0, 0x0, 0x0, - 0x0, 0xa, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, - - /* U+9769 "革" */ - 0x0, 0x0, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x1d, 0x0, 0x38, 0x1, 0x0, 0x1, 0x65, - 0x5c, 0x55, 0x6a, 0x59, 0x50, 0x0, 0x0, 0x1b, - 0x0, 0x27, 0x0, 0x0, 0x0, 0x0, 0x1c, 0x5a, - 0x65, 0x0, 0x0, 0x0, 0x3, 0x0, 0xc, 0x0, - 0x30, 0x0, 0x0, 0xd, 0x55, 0x5d, 0x55, 0xb4, - 0x0, 0x0, 0xc, 0x0, 0xc, 0x0, 0x92, 0x0, - 0x0, 0xc, 0x55, 0x5d, 0x55, 0x91, 0x0, 0x0, - 0x0, 0x0, 0xc, 0x0, 0x0, 0x50, 0x6, 0x55, - 0x55, 0x5d, 0x55, 0x56, 0x71, 0x0, 0x0, 0x0, - 0xc, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xd, - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x2, 0x0, - 0x0, 0x0, - - /* U+9774 "靴" */ - 0x0, 0x20, 0x20, 0x0, 0x0, 0x0, 0x0, 0x0, - 0xb0, 0x84, 0x5, 0x8a, 0x10, 0x0, 0x16, 0xb5, - 0xa9, 0x49, 0x3b, 0x0, 0x0, 0x0, 0xa0, 0x82, - 0xb, 0xa, 0x4, 0x50, 0x1, 0xaa, 0x82, 0x28, - 0xa, 0xb, 0x20, 0x5, 0x5c, 0x57, 0x7b, 0xa, - 0x55, 0x0, 0x9, 0x1a, 0xb, 0x4a, 0xa, 0x80, - 0x0, 0x9, 0x1a, 0xb, 0xa, 0xd, 0x10, 0x0, - 0x8, 0x5c, 0x57, 0xa, 0x5a, 0x10, 0x0, 0x0, - 0xa, 0x4, 0x1a, 0x9, 0x10, 0x0, 0x26, 0x5c, - 0x55, 0x2a, 0x9, 0x10, 0x40, 0x0, 0xb, 0x0, - 0xa, 0x9, 0x10, 0x70, 0x0, 0xb, 0x0, 0xb, - 0x6, 0xba, 0xc0, 0x0, 0x4, 0x0, 0x2, 0x0, - 0x0, 0x0, - - /* U+97F3 "音" */ - 0x0, 0x0, 0x1, 0x30, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, 0xb4, 0x0, 0x0, 0x0, 0x0, 0x65, - 0x55, 0x87, 0x55, 0x98, 0x0, 0x0, 0x0, 0x53, - 0x0, 0x3c, 0x0, 0x0, 0x0, 0x0, 0x1e, 0x0, - 0x84, 0x0, 0x0, 0x0, 0x0, 0x6, 0x0, 0x70, - 0x5, 0x70, 0x26, 0x55, 0x55, 0x55, 0x55, 0x55, - 0x50, 0x0, 0x7, 0x55, 0x55, 0x56, 0xa0, 0x0, - 0x0, 0x9, 0x20, 0x0, 0x2, 0x90, 0x0, 0x0, - 0x9, 0x65, 0x55, 0x56, 0x90, 0x0, 0x0, 0x9, - 0x20, 0x0, 0x2, 0x90, 0x0, 0x0, 0xa, 0x65, - 0x55, 0x56, 0xa0, 0x0, 0x0, 0x9, 0x20, 0x0, - 0x2, 0x90, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, - - /* U+97FF "響" */ - 0x0, 0x0, 0x0, 0x31, 0x0, 0x0, 0x0, 0x2, - 0xa0, 0x66, 0x76, 0x54, 0x71, 0x1, 0x71, 0x49, - 0x0, 0xa9, 0x18, 0x0, 0xa6, 0x93, 0xa5, 0x5a, - 0x95, 0x0, 0x2, 0x62, 0x9a, 0x57, 0x59, 0x8, - 0x0, 0x46, 0x93, 0xa6, 0x67, 0x94, 0xa1, 0x0, - 0x67, 0x4, 0x71, 0x18, 0x14, 0x0, 0x46, 0x55, - 0x57, 0x76, 0x5a, 0x0, 0x0, 0x0, 0x47, 0x2, - 0xa0, 0x1, 0x0, 0x65, 0x55, 0x65, 0x75, 0x55, - 0x91, 0x0, 0xa, 0x55, 0x55, 0x5b, 0x20, 0x0, - 0x0, 0xa5, 0x55, 0x55, 0xc0, 0x0, 0x0, 0xa, - 0x55, 0x55, 0x5c, 0x0, 0x0, 0x0, 0x20, 0x0, - 0x0, 0x20, 0x0, - - /* U+9803 "頃" */ - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x30, - 0x0, 0x46, 0x57, 0x55, 0xa3, 0xd, 0x0, 0x0, - 0x0, 0xb0, 0x0, 0x0, 0xb0, 0x0, 0x8, 0x67, - 0x55, 0xb0, 0xb, 0x0, 0x10, 0xb0, 0x0, 0xb, - 0x0, 0xc5, 0x65, 0xc, 0x55, 0x55, 0xb0, 0xb, - 0x0, 0x0, 0xb0, 0x0, 0xb, 0x0, 0xb0, 0x0, - 0xc, 0x55, 0x55, 0xb0, 0xb, 0x0, 0x20, 0xb0, - 0x0, 0xb, 0x0, 0xb2, 0x82, 0xd, 0x55, 0x55, - 0xb0, 0x1f, 0xa0, 0x0, 0x1a, 0x23, 0x20, 0x0, - 0x40, 0x0, 0x7, 0x70, 0xa, 0x50, 0x0, 0x0, - 0x5, 0x30, 0x0, 0x1c, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x0, - - /* U+9805 "項" */ - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x46, 0x56, 0x55, 0xb3, 0x5, 0x67, - 0x77, 0x0, 0xc, 0x0, 0x0, 0x0, 0xb, 0x0, - 0x7, 0x68, 0x55, 0x90, 0x0, 0xb, 0x0, 0xc, - 0x0, 0x0, 0xb0, 0x0, 0xb, 0x0, 0xd, 0x55, - 0x55, 0xb0, 0x0, 0xb, 0x0, 0xb, 0x0, 0x0, - 0xb0, 0x0, 0xb, 0x0, 0xc, 0x55, 0x55, 0xb0, - 0x0, 0xb, 0x3, 0xb, 0x0, 0x0, 0xb0, 0x0, - 0x5d, 0x61, 0xd, 0x55, 0x55, 0xb0, 0x1e, 0x70, - 0x0, 0x2, 0x82, 0x31, 0x10, 0x0, 0x0, 0x0, - 0x6, 0x80, 0xa, 0x40, 0x0, 0x0, 0x0, 0x54, - 0x0, 0x1, 0xc0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, - - /* U+9808 "須" */ - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0xa1, 0x45, 0x56, 0x55, 0xb3, 0x0, 0x8, - 0x70, 0x0, 0xc, 0x0, 0x0, 0x0, 0x66, 0x0, - 0x7, 0x68, 0x55, 0x90, 0x5, 0x20, 0x10, 0xb, - 0x0, 0x0, 0xb0, 0x0, 0x0, 0x98, 0xc, 0x55, - 0x55, 0xb0, 0x0, 0x7, 0x80, 0xb, 0x0, 0x0, - 0xb0, 0x0, 0x64, 0x0, 0xc, 0x55, 0x55, 0xb0, - 0x3, 0x0, 0x7, 0xb, 0x0, 0x0, 0xb0, 0x0, - 0x0, 0x6b, 0x1d, 0x55, 0x55, 0xb0, 0x0, 0x6, - 0x80, 0x2, 0x61, 0x31, 0x10, 0x0, 0x64, 0x0, - 0x5, 0xa1, 0xa, 0x40, 0x2, 0x0, 0x0, 0x56, - 0x0, 0x1, 0xc0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, - - /* U+9817 "頗" */ - 0x0, 0x0, 0x10, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0xc0, 0x26, 0x55, 0x55, 0xb3, 0x0, 0x0, - 0xa0, 0x0, 0xc, 0x10, 0x0, 0x2, 0xa4, 0xc5, - 0xa5, 0x5a, 0x55, 0x91, 0x1, 0x90, 0xa5, 0x2b, - 0x0, 0x0, 0xb0, 0x1, 0x90, 0xa2, 0xb, 0x55, - 0x55, 0xc0, 0x1, 0xb5, 0x98, 0x6a, 0x0, 0x0, - 0xb0, 0x2, 0x80, 0x8, 0x1a, 0x55, 0x55, 0xc0, - 0x4, 0x65, 0x1a, 0xa, 0x0, 0x0, 0xb0, 0x5, - 0x30, 0xb6, 0xb, 0x55, 0x55, 0xc0, 0x7, 0x3, - 0x9c, 0x3, 0x63, 0x21, 0x20, 0x6, 0x27, 0x7, - 0x13, 0xb1, 0x9, 0x50, 0x12, 0x30, 0x0, 0x37, - 0x0, 0x0, 0xd0, 0x0, 0x0, 0x0, 0x10, 0x0, - 0x0, 0x10, - - /* U+9818 "領" */ - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0xc, 0x10, 0x56, 0x56, 0x55, 0xb3, 0x0, 0x2c, - 0x50, 0x0, 0xc, 0x0, 0x0, 0x0, 0x83, 0x68, - 0x7, 0x68, 0x55, 0x90, 0x1, 0x92, 0xa, 0x4b, - 0x0, 0x0, 0xb0, 0x7, 0x16, 0x51, 0xc, 0x55, - 0x55, 0xb0, 0x22, 0x0, 0x70, 0xb, 0x0, 0x0, - 0xb0, 0x2, 0x65, 0x5d, 0x2b, 0x55, 0x55, 0xb0, - 0x0, 0x0, 0x47, 0xb, 0x0, 0x0, 0xb0, 0x1, - 0x20, 0x80, 0xc, 0x55, 0x55, 0xb0, 0x0, 0x6a, - 0x20, 0x2, 0x82, 0x22, 0x10, 0x0, 0x9, 0x80, - 0x6, 0x80, 0x8, 0x60, 0x0, 0x0, 0x60, 0x54, - 0x0, 0x0, 0xd0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, - - /* U+982D "頭" */ - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x4, 0x36, 0x55, 0x55, 0xb1, 0x16, 0x55, - 0x55, 0x20, 0xc, 0x0, 0x0, 0x2, 0x0, 0x4, - 0x6, 0x57, 0x44, 0x80, 0xa, 0x65, 0x5d, 0xc, - 0x0, 0x0, 0xb0, 0xa, 0x10, 0xb, 0xc, 0x55, - 0x55, 0xb0, 0xa, 0x55, 0x5b, 0xb, 0x0, 0x0, - 0xb0, 0x4, 0x0, 0x12, 0xb, 0x55, 0x55, 0xb0, - 0x3, 0x20, 0x67, 0xb, 0x0, 0x0, 0xb0, 0x0, - 0xc0, 0x90, 0xc, 0x55, 0x55, 0xb0, 0x0, 0x60, - 0x73, 0x12, 0x82, 0x13, 0x10, 0x2c, 0xa8, 0x41, - 0x6, 0x90, 0x6, 0x80, 0x2, 0x0, 0x0, 0x55, - 0x0, 0x0, 0xc2, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, - - /* U+983C "頼" */ - 0x0, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0xb, 0x20, 0x36, 0x56, 0x55, 0xb1, 0x1, 0x1b, - 0x16, 0x10, 0xc, 0x10, 0x0, 0x5, 0x3b, 0x33, - 0x26, 0x59, 0x55, 0x90, 0x3, 0x1a, 0x14, 0xc, - 0x0, 0x0, 0xb0, 0xa, 0x4b, 0x4c, 0x1b, 0x55, - 0x55, 0xb0, 0xa, 0xa, 0xb, 0xb, 0x0, 0x0, - 0xb0, 0xa, 0x5d, 0x5c, 0xb, 0x55, 0x55, 0xb0, - 0x2, 0x5f, 0x41, 0xb, 0x0, 0x0, 0xb0, 0x0, - 0xab, 0x3b, 0xb, 0x55, 0x55, 0xb0, 0x6, 0x3a, - 0x6, 0x52, 0x83, 0x14, 0x10, 0x24, 0xa, 0x0, - 0x5, 0x90, 0x6, 0x90, 0x0, 0xa, 0x0, 0x45, - 0x0, 0x0, 0xb2, 0x0, 0x1, 0x0, 0x10, 0x0, - 0x0, 0x0, - - /* U+984C "題" */ - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x4, - 0x75, 0x5b, 0x36, 0x55, 0x57, 0x90, 0x4, 0x50, - 0xa, 0x0, 0x9, 0x0, 0x0, 0x4, 0x85, 0x5a, - 0x7, 0x67, 0x5b, 0x0, 0x5, 0x51, 0x1a, 0xa, - 0x0, 0xa, 0x0, 0x4, 0x64, 0x46, 0xa, 0x55, - 0x5a, 0x0, 0x5, 0x55, 0x57, 0x7a, 0x55, 0x5a, - 0x0, 0x3, 0xa, 0x0, 0xa, 0x0, 0xa, 0x0, - 0x8, 0x3a, 0x3, 0x1a, 0x55, 0x58, 0x0, 0x9, - 0x1a, 0x55, 0x21, 0xc0, 0x44, 0x0, 0x9, 0x5a, - 0x0, 0x8, 0x20, 0xa, 0x40, 0x7, 0xb, 0x30, - 0x30, 0x0, 0x1, 0x20, 0x41, 0x0, 0x7b, 0xbb, - 0xcc, 0xde, 0x80, 0x10, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, - - /* U+9854 "顔" */ - 0x0, 0x2, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x8, 0x40, 0x36, 0x56, 0x55, 0xb1, 0x5, 0x66, - 0x79, 0x60, 0xc, 0x10, 0x0, 0x0, 0x71, 0x39, - 0x7, 0x59, 0x55, 0xa0, 0x1, 0x36, 0x60, 0x1c, - 0x0, 0x0, 0xa0, 0xa, 0x55, 0x66, 0x6b, 0x55, - 0x55, 0xa0, 0xa, 0x0, 0x2a, 0xb, 0x0, 0x0, - 0xa0, 0xa, 0x5, 0x71, 0xb, 0x55, 0x55, 0xa0, - 0xa, 0x20, 0x1b, 0x4b, 0x0, 0x0, 0xa0, 0x9, - 0x3, 0x82, 0xb, 0x55, 0x55, 0xa0, 0x8, 0x22, - 0x6, 0xb1, 0x93, 0x24, 0x0, 0x15, 0x1, 0x87, - 0x5, 0x90, 0x7, 0x80, 0x40, 0x45, 0x0, 0x45, - 0x0, 0x0, 0xc0, 0x0, 0x0, 0x0, 0x10, 0x0, - 0x0, 0x0, - - /* U+9858 "願" */ - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x6, - 0x55, 0x59, 0x76, 0x57, 0x55, 0xb1, 0xa, 0x0, - 0x90, 0x0, 0xc, 0x10, 0x0, 0xa, 0x23, 0x32, - 0x15, 0x48, 0x44, 0x90, 0xa, 0x58, 0x59, 0x4b, - 0x11, 0x11, 0xc0, 0xa, 0x57, 0x59, 0x2b, 0x55, - 0x55, 0xb0, 0xa, 0x54, 0x7, 0x2b, 0x0, 0x0, - 0xb0, 0xa, 0x57, 0x99, 0x2b, 0x55, 0x55, 0xb0, - 0x8, 0x10, 0xa0, 0xb, 0x0, 0x0, 0xb0, 0x7, - 0x85, 0xa6, 0x1b, 0x55, 0x55, 0xb0, 0x33, 0x70, - 0xa2, 0xa1, 0x83, 0x14, 0x10, 0x24, 0x22, 0xb0, - 0x54, 0x90, 0x6, 0x90, 0x0, 0xa, 0x70, 0x36, - 0x0, 0x0, 0xc1, 0x0, 0x0, 0x0, 0x10, 0x0, - 0x0, 0x0, - - /* U+985E "類" */ - 0x0, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x3, - 0x9, 0x35, 0x26, 0x56, 0x55, 0xb1, 0x2, 0xa9, - 0x2a, 0x0, 0xc, 0x20, 0x0, 0x0, 0x39, 0x73, - 0x45, 0x49, 0x44, 0x90, 0x26, 0xaf, 0xb6, 0x4b, - 0x10, 0x0, 0xb0, 0x3, 0x89, 0x3b, 0x3b, 0x55, - 0x55, 0xb0, 0x34, 0x9, 0x32, 0x3a, 0x0, 0x0, - 0xb0, 0x0, 0x6, 0x4b, 0xa, 0x55, 0x55, 0xb0, - 0x12, 0x29, 0x55, 0x6a, 0x0, 0x0, 0xb0, 0x14, - 0x3d, 0x33, 0x3b, 0x55, 0x55, 0xb0, 0x0, 0x2a, - 0x78, 0x1, 0x84, 0x14, 0x10, 0x0, 0xa1, 0x7, - 0x54, 0xa0, 0x6, 0x90, 0x6, 0x10, 0x0, 0x36, - 0x0, 0x0, 0xb1, 0x10, 0x0, 0x0, 0x10, 0x0, - 0x0, 0x0, - - /* U+986F "顯" */ - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x6, - 0x55, 0x59, 0x56, 0x57, 0x58, 0x70, 0xa, 0x0, - 0xa, 0x0, 0xc, 0x0, 0x0, 0xa, 0x55, 0x5c, - 0x6, 0x68, 0x59, 0x30, 0xa, 0x55, 0x5a, 0xb, - 0x0, 0x9, 0x10, 0x2, 0x80, 0x17, 0xa, 0x55, - 0x5b, 0x10, 0x6, 0x34, 0x74, 0x5a, 0x0, 0x9, - 0x10, 0x28, 0x91, 0x8a, 0x1a, 0x55, 0x5b, 0x10, - 0x27, 0x54, 0x64, 0x4a, 0x0, 0x9, 0x10, 0x36, - 0x39, 0x63, 0x7a, 0x55, 0x5b, 0x10, 0x3, 0x31, - 0x54, 0x21, 0x92, 0x24, 0x0, 0x19, 0x37, 0xa2, - 0xa3, 0x90, 0x8, 0x60, 0x33, 0x2, 0x10, 0x36, - 0x0, 0x0, 0xc0, 0x0, 0x0, 0x0, 0x10, 0x0, - 0x0, 0x0, - - /* U+98A8 "風" */ - 0x0, 0x0, 0x0, 0x0, 0x0, 0x10, 0x0, 0x0, - 0x86, 0x55, 0x55, 0x55, 0xd0, 0x0, 0x0, 0x82, - 0x0, 0x4, 0x92, 0xb0, 0x0, 0x0, 0x84, 0x57, - 0xd5, 0x20, 0xb0, 0x0, 0x0, 0x82, 0x0, 0xb0, - 0x0, 0xb0, 0x0, 0x0, 0x82, 0xa5, 0xc5, 0xc1, - 0xb0, 0x0, 0x0, 0x82, 0xb0, 0xb0, 0xb0, 0xb0, - 0x0, 0x0, 0x82, 0xb0, 0xb0, 0xb0, 0xb0, 0x0, - 0x0, 0x91, 0xa5, 0xc5, 0x90, 0xb0, 0x0, 0x0, - 0xb0, 0x0, 0xb0, 0x60, 0xc0, 0x0, 0x0, 0xa0, - 0x0, 0xb4, 0x7a, 0x93, 0x50, 0x6, 0x49, 0xc9, - 0x63, 0xb, 0x3c, 0x90, 0x16, 0x0, 0x0, 0x0, - 0x0, 0x5, 0xd0, 0x10, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x10, - - /* U+98DB "飛" */ - 0x0, 0x0, 0x0, 0x0, 0x10, 0x0, 0x0, 0x0, - 0x65, 0x55, 0x55, 0xc6, 0x3, 0x0, 0x0, 0x0, - 0x73, 0x90, 0xa4, 0x88, 0x0, 0x0, 0x2b, 0x51, - 0xa0, 0x98, 0x52, 0x0, 0x3, 0x3a, 0x0, 0xa0, - 0x5a, 0xa, 0x31, 0x0, 0xa, 0x0, 0xa0, 0xb, - 0x50, 0x61, 0x15, 0x5c, 0x55, 0xb5, 0xa2, 0x78, - 0xc5, 0x1, 0xa, 0x0, 0xa0, 0xb0, 0x12, 0x11, - 0x0, 0xb, 0x0, 0xa0, 0xb6, 0x73, 0x0, 0x0, - 0xa, 0x0, 0xa0, 0xb1, 0xa6, 0x0, 0x0, 0x45, - 0x0, 0xa0, 0x76, 0x5, 0x13, 0x0, 0x80, 0x0, - 0xa0, 0xb, 0x60, 0x53, 0x15, 0x0, 0x1, 0x50, - 0x0, 0x6b, 0xd5, - - /* U+98DF "食" */ - 0x0, 0x0, 0x0, 0x40, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x7, 0xd1, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x4c, 0x7, 0x10, 0x0, 0x0, 0x0, 0x3, 0xb1, - 0x71, 0x96, 0x0, 0x0, 0x0, 0x59, 0x0, 0x58, - 0x8, 0xd9, 0x60, 0x16, 0x39, 0x65, 0x56, 0x5d, - 0x28, 0x40, 0x0, 0x9, 0x20, 0x0, 0xc, 0x0, - 0x0, 0x0, 0x9, 0x65, 0x55, 0x5c, 0x0, 0x0, - 0x0, 0x9, 0x65, 0x55, 0x5c, 0x0, 0x0, 0x0, - 0x9, 0x22, 0x0, 0x7, 0xb0, 0x0, 0x0, 0x9, - 0x20, 0x68, 0x66, 0x0, 0x0, 0x0, 0xa, 0x34, - 0x52, 0x8c, 0x50, 0x0, 0x0, 0xb, 0xb3, 0x0, - 0x3, 0xe2, 0x0, 0x0, 0x1, 0x0, 0x0, 0x0, - 0x10, 0x0, - - /* U+98EF "飯" */ - 0x0, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x8, 0x60, 0x1, 0x1, 0x5b, 0x60, 0x0, 0x1b, - 0x66, 0xb, 0x54, 0x31, 0x0, 0x0, 0x84, 0x6, - 0x8b, 0x0, 0x0, 0x0, 0x4, 0x41, 0xa0, 0x2b, - 0x0, 0x0, 0x0, 0x13, 0xa5, 0x6a, 0x2b, 0x65, - 0x58, 0x90, 0x0, 0xa0, 0xa, 0xb, 0x30, 0x7, - 0x30, 0x0, 0xc5, 0x5c, 0xb, 0x4, 0xa, 0x0, - 0x0, 0xc5, 0x5c, 0xb, 0x6, 0x27, 0x0, 0x0, - 0xa0, 0x42, 0xa, 0x5, 0xb0, 0x0, 0x0, 0xa0, - 0x4a, 0x18, 0x6, 0xb0, 0x0, 0x0, 0xc9, 0x4a, - 0x51, 0x37, 0x49, 0x0, 0x0, 0xa1, 0x0, 0x52, - 0x50, 0x8, 0xb1, 0x0, 0x0, 0x2, 0x2, 0x0, - 0x0, 0x30, - - /* U+98F2 "飲" */ - 0x0, 0x1, 0x0, 0x0, 0x10, 0x0, 0x0, 0x0, - 0x8, 0x70, 0x0, 0xc2, 0x0, 0x0, 0x0, 0xb, - 0x65, 0x0, 0xb0, 0x0, 0x0, 0x0, 0x84, 0x7, - 0x85, 0x95, 0x58, 0x60, 0x3, 0x41, 0xa0, 0x29, - 0x10, 0x9, 0x30, 0x13, 0x95, 0x7a, 0x44, 0x4a, - 0x7, 0x0, 0x0, 0xa0, 0xa, 0x20, 0x59, 0x11, - 0x0, 0x0, 0xc5, 0x5c, 0x0, 0x69, 0x0, 0x0, - 0x0, 0xc5, 0x5c, 0x0, 0x97, 0x0, 0x0, 0x0, - 0xa0, 0x42, 0x0, 0xb1, 0x60, 0x0, 0x0, 0xa0, - 0x5b, 0x3, 0x80, 0xa1, 0x0, 0x1, 0xe9, 0x18, - 0x8, 0x0, 0x3c, 0x10, 0x0, 0x50, 0x0, 0x50, - 0x0, 0x5, 0xc1, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, - - /* U+9928 "館" */ - 0x0, 0x0, 0x0, 0x0, 0x2, 0x0, 0x0, 0x0, - 0x8, 0x70, 0x0, 0x7, 0x60, 0x0, 0x0, 0xc, - 0x74, 0x8, 0x56, 0xa5, 0x93, 0x0, 0x85, 0xa, - 0xb6, 0x0, 0x0, 0x90, 0x3, 0x53, 0x80, 0x23, - 0x11, 0x16, 0x10, 0x14, 0x85, 0x79, 0x19, 0x64, - 0x4c, 0x10, 0x0, 0xa0, 0xa, 0x9, 0x20, 0xb, - 0x0, 0x0, 0xb5, 0x5b, 0x9, 0x65, 0x59, 0x0, - 0x0, 0xa1, 0x1b, 0x9, 0x20, 0x2, 0x30, 0x0, - 0xb3, 0x65, 0x9, 0x65, 0x58, 0x80, 0x0, 0xa0, - 0x4a, 0x9, 0x20, 0x5, 0x50, 0x1, 0xd9, 0x4a, - 0x9, 0x65, 0x58, 0x60, 0x0, 0x80, 0x0, 0x9, - 0x20, 0x4, 0x30, 0x0, 0x0, 0x0, 0x1, 0x0, - 0x0, 0x0, - - /* U+9996 "首" */ - 0x0, 0x0, 0x0, 0x0, 0x2, 0x0, 0x0, 0x0, - 0x0, 0x84, 0x0, 0x4c, 0x0, 0x0, 0x0, 0x0, - 0x1e, 0x0, 0x81, 0x0, 0x30, 0x16, 0x55, 0x58, - 0xb5, 0x75, 0x57, 0x91, 0x0, 0x0, 0x2, 0x80, - 0x0, 0x0, 0x0, 0x0, 0xa, 0x57, 0x65, 0x56, - 0xc0, 0x0, 0x0, 0xc, 0x0, 0x0, 0x1, 0xa0, - 0x0, 0x0, 0xc, 0x55, 0x55, 0x56, 0xa0, 0x0, - 0x0, 0xc, 0x0, 0x0, 0x1, 0xa0, 0x0, 0x0, - 0xc, 0x55, 0x55, 0x56, 0xa0, 0x0, 0x0, 0xc, - 0x0, 0x0, 0x1, 0xa0, 0x0, 0x0, 0xc, 0x55, - 0x55, 0x56, 0xa0, 0x0, 0x0, 0xc, 0x0, 0x0, - 0x1, 0xa0, 0x0, 0x0, 0x1, 0x0, 0x0, 0x0, - 0x0, 0x0, - - /* U+9999 "香" */ - 0x0, 0x0, 0x0, 0x0, 0x0, 0x10, 0x0, 0x0, - 0x0, 0x0, 0x35, 0x8b, 0xc3, 0x0, 0x0, 0x4, - 0x55, 0x4c, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0xc, 0x0, 0x1, 0x80, 0x4, 0x55, 0x58, 0xdd, - 0x95, 0x55, 0x51, 0x0, 0x0, 0x2b, 0x1c, 0x18, - 0x10, 0x0, 0x0, 0x5, 0x90, 0xd, 0x1, 0xb9, - 0x30, 0x1, 0x64, 0x75, 0x57, 0x55, 0xa6, 0xc4, - 0x3, 0x0, 0xb0, 0x0, 0x0, 0xb0, 0x0, 0x0, - 0x0, 0xb0, 0x0, 0x0, 0xa0, 0x0, 0x0, 0x0, - 0xc5, 0x55, 0x55, 0xa0, 0x0, 0x0, 0x0, 0xb0, - 0x0, 0x0, 0xa0, 0x0, 0x0, 0x0, 0xc5, 0x55, - 0x55, 0xb0, 0x0, 0x0, 0x0, 0x10, 0x0, 0x0, - 0x0, 0x0, - - /* U+99C4 "駄" */ - 0x0, 0x0, 0x0, 0x0, 0x3, 0x0, 0x0, 0x2, - 0xa5, 0x85, 0x80, 0xb, 0x20, 0x0, 0x1, 0xa0, - 0xa0, 0x0, 0xa, 0x0, 0x0, 0x1, 0xb5, 0xc6, - 0x60, 0xa, 0x0, 0x10, 0x1, 0xa0, 0xa0, 0x26, - 0x5c, 0x65, 0x91, 0x1, 0xb5, 0xc5, 0x40, 0xa, - 0x50, 0x0, 0x1, 0xa0, 0xa0, 0x30, 0x9, 0x60, - 0x0, 0x1, 0xb4, 0x54, 0xd1, 0x37, 0x70, 0x0, - 0x0, 0x21, 0x40, 0xb0, 0x72, 0x81, 0x0, 0x4, - 0x66, 0x85, 0xb0, 0xa0, 0x47, 0x0, 0xa, 0x82, - 0x42, 0x93, 0x82, 0xc, 0x0, 0x14, 0x1, 0x8, - 0x69, 0xa, 0x27, 0x90, 0x0, 0x0, 0x8c, 0x61, - 0x3, 0x10, 0xc4, 0x0, 0x0, 0x0, 0x10, 0x0, - 0x0, 0x0, - - /* U+99C5 "駅" */ - 0x0, 0x0, 0x0, 0x10, 0x0, 0x0, 0x0, 0x2, - 0xa5, 0x95, 0x86, 0x65, 0x55, 0xc0, 0x1, 0x90, - 0xb0, 0x16, 0x40, 0x0, 0xb0, 0x1, 0xb5, 0xc6, - 0x56, 0x40, 0x0, 0xb0, 0x1, 0x90, 0xb0, 0x16, - 0x40, 0x0, 0xb0, 0x1, 0xb5, 0xc5, 0x46, 0x88, - 0x55, 0xa0, 0x1, 0x90, 0xb0, 0x26, 0x45, 0x0, - 0x0, 0x1, 0xb4, 0x54, 0xd7, 0x34, 0x30, 0x0, - 0x0, 0x11, 0x40, 0xb8, 0x10, 0x80, 0x0, 0x4, - 0x64, 0x77, 0xb9, 0x0, 0xa0, 0x0, 0xa, 0x73, - 0x53, 0x98, 0x0, 0x49, 0x0, 0x14, 0x0, 0x8, - 0x83, 0x0, 0xb, 0x80, 0x0, 0x0, 0x7c, 0x60, - 0x0, 0x0, 0x93, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, - - /* U+9A12 "騒" */ - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x1, - 0x85, 0x76, 0x74, 0x65, 0x56, 0xb0, 0x1, 0xa0, - 0xb0, 0x0, 0x51, 0x9, 0x40, 0x1, 0xb5, 0xc7, - 0x40, 0x9, 0x3a, 0x0, 0x1, 0xa0, 0xb0, 0x0, - 0x4, 0xf2, 0x0, 0x1, 0xb5, 0xc7, 0x40, 0x58, - 0x5c, 0x83, 0x1, 0xa0, 0xb0, 0x14, 0x20, 0xc0, - 0x51, 0x2, 0xb4, 0x74, 0xd6, 0x85, 0xc5, 0xc0, - 0x0, 0x1, 0x30, 0xb5, 0x60, 0xb0, 0xb0, 0x3, - 0x66, 0x85, 0xa5, 0x95, 0xc5, 0xc0, 0xa, 0x65, - 0x43, 0x82, 0x20, 0xb2, 0x30, 0x14, 0x0, 0x6, - 0x50, 0x0, 0xb3, 0xb2, 0x0, 0x3, 0x9c, 0x1c, - 0xb8, 0x63, 0x28, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, - - /* U+9A13 "験" */ - 0x0, 0x0, 0x0, 0x0, 0x4, 0x0, 0x0, 0x1, - 0x85, 0x77, 0x50, 0x1e, 0x10, 0x0, 0x1, 0x90, - 0xb0, 0x0, 0x93, 0x70, 0x0, 0x1, 0xb5, 0xc7, - 0x24, 0x70, 0x2b, 0x51, 0x1, 0x90, 0xb0, 0x37, - 0x68, 0x6a, 0x82, 0x1, 0xb5, 0xc7, 0x20, 0xa, - 0x11, 0x0, 0x1, 0x90, 0xb0, 0x1b, 0x5c, 0x5b, - 0x40, 0x2, 0xa4, 0x66, 0x9b, 0xa, 0x19, 0x10, - 0x0, 0x1, 0x43, 0x7b, 0x5c, 0x5b, 0x10, 0x7, - 0x66, 0x88, 0x66, 0xb, 0x14, 0x0, 0x2b, 0x73, - 0x36, 0x40, 0x28, 0x70, 0x0, 0x11, 0x0, 0x9, - 0x21, 0xa0, 0x59, 0x0, 0x0, 0x2, 0xaa, 0x37, - 0x0, 0x6, 0xd3, 0x0, 0x0, 0x0, 0x10, 0x0, - 0x0, 0x0, - - /* U+9A57 "驗" */ - 0x0, 0x0, 0x0, 0x0, 0x3, 0x0, 0x0, 0x1, - 0x85, 0x68, 0x40, 0xd, 0x30, 0x0, 0x1, 0x90, - 0xa0, 0x0, 0x64, 0x80, 0x0, 0x1, 0xb5, 0xc8, - 0x12, 0x80, 0x2a, 0x10, 0x1, 0x90, 0xa0, 0x18, - 0x65, 0x5b, 0xc5, 0x1, 0xb5, 0xc7, 0x31, 0x1, - 0x10, 0x20, 0x1, 0x90, 0xa0, 0xc, 0x77, 0xb5, - 0xc0, 0x1, 0xb4, 0x77, 0x8a, 0x35, 0xa0, 0xa0, - 0x0, 0x20, 0x34, 0x5c, 0x76, 0xb5, 0xb0, 0x4, - 0x56, 0x4b, 0x56, 0x81, 0x46, 0x40, 0xa, 0x82, - 0x37, 0x44, 0x80, 0xc, 0x0, 0x14, 0x0, 0xa, - 0x19, 0x63, 0x48, 0x60, 0x0, 0x2, 0x9a, 0x53, - 0x8, 0x70, 0x81, 0x0, 0x0, 0x0, 0x10, 0x2, - 0x0, 0x0, - - /* U+9AD4 "體" */ - 0x0, 0x0, 0x0, 0x0, 0x11, 0x20, 0x0, 0x0, - 0x85, 0x5a, 0x0, 0x46, 0xb1, 0x0, 0x0, 0xa2, - 0x1a, 0x7, 0x89, 0xc6, 0xa0, 0x0, 0xca, 0x5a, - 0xb, 0x46, 0xa2, 0x90, 0x2, 0xa7, 0x3a, 0x1b, - 0x78, 0xc6, 0x90, 0xb, 0x66, 0x57, 0x9b, 0x78, - 0xc6, 0x90, 0x25, 0x85, 0x5b, 0x5, 0x0, 0x1, - 0x60, 0x0, 0xb0, 0xa, 0x26, 0x55, 0x56, 0x51, - 0x0, 0xc5, 0x5a, 0x7, 0x75, 0x5a, 0x60, 0x0, - 0xb0, 0xa, 0x6, 0x52, 0x28, 0x40, 0x0, 0xc5, - 0x5a, 0x5, 0x73, 0x59, 0x20, 0x0, 0xb0, 0xa, - 0x0, 0x83, 0x64, 0x0, 0x0, 0xb2, 0x99, 0x45, - 0x66, 0x95, 0xb2, 0x0, 0x20, 0x0, 0x10, 0x0, - 0x0, 0x0, - - /* U+9AD8 "高" */ - 0x0, 0x0, 0x24, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0xa2, 0x0, 0x0, 0x20, 0x55, 0x55, 0x55, - 0x55, 0x55, 0x69, 0x0, 0x3, 0x65, 0x55, 0x59, - 0x0, 0x0, 0x0, 0x46, 0x0, 0x0, 0xb0, 0x0, - 0x0, 0x4, 0x95, 0x55, 0x5c, 0x0, 0x0, 0x0, - 0x32, 0x0, 0x0, 0x50, 0x10, 0x0, 0xc5, 0x55, - 0x55, 0x55, 0x5d, 0x30, 0xb, 0x6, 0x55, 0x59, - 0x30, 0xc0, 0x0, 0xb0, 0x91, 0x0, 0x91, 0xc, - 0x0, 0xb, 0x9, 0x65, 0x5b, 0x20, 0xc0, 0x0, - 0xb0, 0x70, 0x0, 0x61, 0xc, 0x0, 0xb, 0x0, - 0x0, 0x0, 0x39, 0xd0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x2, 0x0, - - /* U+9AEA "髪" */ - 0x0, 0x20, 0x0, 0x30, 0x0, 0x20, 0x0, 0x0, - 0xa5, 0x55, 0x50, 0x5, 0xb3, 0x0, 0x0, 0xa5, - 0x56, 0x44, 0x73, 0x4, 0x0, 0x0, 0xa5, 0x56, - 0x50, 0x3, 0xa6, 0x0, 0x6, 0xa8, 0x55, 0x86, - 0x53, 0x3, 0x40, 0x0, 0x58, 0x16, 0x20, 0x3, - 0x98, 0x30, 0x6, 0xc7, 0x55, 0x84, 0x64, 0x0, - 0x0, 0x0, 0x0, 0xa, 0x40, 0x0, 0x7, 0x20, - 0x16, 0x55, 0x8b, 0x55, 0x55, 0x55, 0x30, 0x0, - 0x1, 0xb8, 0x55, 0x5d, 0x40, 0x0, 0x0, 0x1a, - 0x23, 0x42, 0xb4, 0x0, 0x0, 0x3, 0x70, 0x1, - 0xad, 0x50, 0x0, 0x0, 0x22, 0x4, 0x66, 0x10, - 0x5b, 0xa8, 0x60, 0x1, 0x30, 0x0, 0x0, 0x0, - 0x3, 0x0, - - /* U+9B5A "魚" */ - 0x0, 0x0, 0x4, 0x10, 0x0, 0x0, 0x0, 0x0, - 0x1, 0xd5, 0x0, 0x10, 0x0, 0x0, 0x0, 0xa7, - 0x55, 0xab, 0x0, 0x0, 0x0, 0x83, 0x0, 0x19, - 0x0, 0x0, 0x0, 0x7b, 0x55, 0x5a, 0x55, 0x6d, - 0x1, 0x50, 0xb0, 0x0, 0xc0, 0x2, 0xa0, 0x0, - 0xb, 0x55, 0x5d, 0x55, 0x7a, 0x0, 0x0, 0xb0, - 0x0, 0xc0, 0x2, 0xa0, 0x0, 0xb, 0x0, 0xc, - 0x0, 0x2a, 0x0, 0x0, 0xb5, 0x55, 0x55, 0x56, - 0x70, 0x0, 0x12, 0x22, 0x4, 0x20, 0x53, 0x0, - 0xb, 0x0, 0xc0, 0xd, 0x10, 0xc6, 0x9, 0x80, - 0xb, 0x10, 0x82, 0x2, 0xa0, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x0, - - /* U+9CE5 "鳥" */ - 0x0, 0x0, 0x1, 0x30, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x7, 0x50, 0x0, 0x0, 0x0, 0x0, 0xa, - 0x58, 0x55, 0x5b, 0x20, 0x0, 0x0, 0xb, 0x0, - 0x0, 0xb, 0x0, 0x0, 0x0, 0xc, 0x55, 0x55, - 0x5c, 0x0, 0x0, 0x0, 0xc, 0x55, 0x55, 0x5c, - 0x0, 0x0, 0x0, 0xc, 0x55, 0x55, 0x55, 0x56, - 0xa0, 0x0, 0xb, 0x0, 0x0, 0x0, 0x2, 0x0, - 0x0, 0xb, 0x55, 0x55, 0x55, 0x5b, 0x50, 0x0, - 0x11, 0x2, 0x30, 0x73, 0xb, 0x10, 0x0, 0x60, - 0xa0, 0xa4, 0x1d, 0xc, 0x0, 0x5, 0x80, 0xa1, - 0x24, 0x13, 0x1c, 0x0, 0x6, 0x10, 0x10, 0x0, - 0x29, 0xe6, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x30, 0x0, - - /* U+9E97 "麗" */ - 0x0, 0x0, 0x0, 0x10, 0x0, 0x0, 0x0, 0x4, - 0x65, 0x56, 0x64, 0x65, 0x56, 0x40, 0x0, 0xb5, - 0x5c, 0x10, 0xb5, 0x5b, 0x0, 0x0, 0xb2, 0x5b, - 0x0, 0xb8, 0x1a, 0x0, 0x0, 0x90, 0x28, 0x56, - 0x92, 0xa, 0x0, 0x0, 0x96, 0x59, 0x56, 0x95, - 0x57, 0x50, 0x0, 0x96, 0x5b, 0x65, 0xb5, 0x58, - 0x10, 0x0, 0x92, 0x9, 0x10, 0x90, 0xa, 0x0, - 0x0, 0xa6, 0x86, 0x55, 0xa7, 0x59, 0x0, 0x0, - 0xc0, 0xa1, 0x2, 0x90, 0x18, 0x0, 0x0, 0xa0, - 0xa5, 0x55, 0x96, 0x74, 0x30, 0x2, 0x60, 0xa1, - 0x43, 0x90, 0x0, 0x60, 0x7, 0x0, 0xb9, 0x20, - 0x6b, 0xaa, 0xd1, 0x1, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, - - /* U+9EBC "麼" */ - 0x0, 0x0, 0x0, 0x20, 0x0, 0x0, 0x0, 0x1, - 0x0, 0x1, 0xc0, 0x0, 0x21, 0x0, 0xc5, 0x56, - 0x57, 0x56, 0x58, 0x60, 0xb, 0x0, 0xa1, 0x0, - 0xa2, 0x0, 0x0, 0xb5, 0x6d, 0x74, 0x6d, 0x67, - 0x40, 0xb, 0x4, 0xf6, 0x14, 0xf6, 0x10, 0x0, - 0xa2, 0x7a, 0x16, 0x7a, 0x1b, 0x60, 0xa, 0x40, - 0x81, 0x50, 0x60, 0x12, 0x0, 0x90, 0x3, 0x95, - 0x5, 0x20, 0x0, 0x27, 0x1b, 0x96, 0x49, 0xa3, - 0x0, 0x4, 0x30, 0x41, 0x37, 0x20, 0x50, 0x0, - 0x70, 0x5, 0x75, 0x34, 0x59, 0x70, 0x4, 0x0, - 0xc9, 0x64, 0x20, 0xa, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x0, - - /* U+9EC4 "黄" */ - 0x0, 0x0, 0x21, 0x0, 0x30, 0x0, 0x0, 0x0, - 0x0, 0x56, 0x0, 0xb2, 0x1, 0x0, 0x0, 0x65, - 0x98, 0x55, 0xc5, 0x5a, 0x20, 0x0, 0x0, 0x54, - 0x0, 0xb0, 0x0, 0x20, 0x26, 0x55, 0x77, 0x75, - 0x95, 0x56, 0xa1, 0x0, 0x2, 0x0, 0x91, 0x0, - 0x30, 0x0, 0x0, 0xd, 0x55, 0xb6, 0x55, 0xc2, - 0x0, 0x0, 0xc, 0x0, 0x91, 0x0, 0xb0, 0x0, - 0x0, 0xd, 0x55, 0xb6, 0x55, 0xc0, 0x0, 0x0, - 0xc, 0x0, 0x91, 0x0, 0xb0, 0x0, 0x0, 0xb, - 0x88, 0x55, 0x96, 0x90, 0x0, 0x0, 0x4, 0xd5, - 0x0, 0x7, 0xa3, 0x0, 0x0, 0x77, 0x0, 0x0, - 0x0, 0x3e, 0x20, 0x4, 0x10, 0x0, 0x0, 0x0, - 0x1, 0x0, - - /* U+9ED2 "黒" */ - 0x1, 0x95, 0x55, 0x65, 0x55, 0xa0, 0x0, 0x1a, - 0x0, 0xb, 0x0, 0xb, 0x0, 0x1, 0xc5, 0x55, - 0xc5, 0x55, 0xb0, 0x0, 0x1a, 0x0, 0xb, 0x0, - 0xb, 0x0, 0x1, 0xc5, 0x55, 0xc5, 0x55, 0xb0, - 0x0, 0x3, 0x0, 0xb, 0x0, 0x2, 0x0, 0x5, - 0x65, 0x55, 0xc5, 0x55, 0xb2, 0x0, 0x0, 0x0, - 0xb, 0x0, 0x1, 0x40, 0x46, 0x55, 0x55, 0x85, - 0x55, 0x79, 0x10, 0x4, 0x6, 0x0, 0x70, 0x8, - 0x0, 0x4, 0x60, 0x74, 0x8, 0x40, 0x86, 0x0, - 0xc1, 0x4, 0x30, 0x33, 0x3, 0x50, 0x0, 0x0, - 0x0, 0x0, 0x0, 0x0, 0x0, - - /* U+9EDE "點" */ - 0x0, 0x0, 0x0, 0x0, 0x2, 0x0, 0x0, 0x7, - 0x57, 0x59, 0x30, 0xd, 0x0, 0x0, 0x9, 0x1a, - 0x3a, 0x0, 0xb, 0x0, 0x0, 0x9, 0x8a, 0x6a, - 0x0, 0xc, 0x44, 0x80, 0x9, 0x6c, 0x5b, 0x10, - 0xb, 0x0, 0x0, 0x6, 0xa, 0x4, 0x0, 0xb, - 0x0, 0x0, 0x2, 0x3b, 0x38, 0x10, 0xb, 0x0, - 0x0, 0x2, 0x3b, 0x22, 0x19, 0x5a, 0x5b, 0x20, - 0x0, 0xa, 0x54, 0x1a, 0x0, 0xb, 0x0, 0xb, - 0xa5, 0x1, 0xa, 0x0, 0xb, 0x0, 0x2, 0x20, - 0x62, 0x7a, 0x0, 0xb, 0x0, 0x7, 0x27, 0x71, - 0x8b, 0x55, 0x5c, 0x0, 0x19, 0x2, 0x0, 0xb, - 0x0, 0xa, 0x0, 0x0, 0x0, 0x0, 0x2, 0x0, - 0x0, 0x0, - - /* U+9EE8 "黨" */ - 0x0, 0x0, 0x0, 0x5, 0x0, 0x10, 0x0, 0x0, - 0x6, 0x70, 0xb, 0x6, 0x80, 0x0, 0x0, 0x53, - 0xa3, 0x3b, 0x38, 0x33, 0x70, 0x3, 0x82, 0x52, - 0x22, 0x25, 0x26, 0x91, 0x8, 0x10, 0x96, 0x55, - 0x5c, 0x12, 0x0, 0x0, 0x0, 0x96, 0x55, 0x5a, - 0x0, 0x0, 0x0, 0x29, 0x65, 0x58, 0x55, 0x6a, - 0x0, 0x0, 0x29, 0x37, 0xa, 0x19, 0x18, 0x0, - 0x0, 0x2b, 0x56, 0x5b, 0x65, 0x68, 0x0, 0x0, - 0x47, 0x55, 0x5b, 0x55, 0x5a, 0x10, 0x4, 0x55, - 0x55, 0x5b, 0x55, 0x55, 0xb1, 0x1, 0x30, 0x4, - 0x0, 0x40, 0x4, 0x10, 0x2, 0xa0, 0x2, 0x70, - 0x35, 0x1, 0x80, 0x2, 0x20, 0x0, 0x0, 0x0, - 0x0, 0x0, - - /* U+9F13 "鼓" */ - 0x0, 0x0, 0x40, 0x0, 0x2, 0x0, 0x0, 0x0, - 0x0, 0xd0, 0x0, 0x9, 0x40, 0x0, 0x6, 0x55, - 0xd5, 0x75, 0x9, 0x20, 0x0, 0x0, 0x0, 0xb0, - 0x5, 0x5b, 0x65, 0xa0, 0x1, 0x75, 0xb5, 0x91, - 0x9, 0x20, 0x0, 0x0, 0x10, 0x0, 0x20, 0x9, - 0x21, 0x10, 0x0, 0xd5, 0x55, 0xd3, 0x86, 0x5b, - 0x70, 0x0, 0xd0, 0x0, 0xb0, 0x50, 0xc, 0x0, - 0x0, 0xd5, 0x55, 0xa0, 0x43, 0x66, 0x0, 0x0, - 0x40, 0x9, 0x10, 0xa, 0xb0, 0x0, 0x0, 0x19, - 0x9, 0x0, 0xb, 0x90, 0x0, 0x0, 0x15, 0x78, - 0x53, 0x82, 0x7a, 0x10, 0xc, 0x95, 0x20, 0x36, - 0x0, 0x6, 0xc1, 0x0, 0x0, 0x1, 0x10, 0x0, - 0x0, 0x0, - - /* U+9F3B "鼻" */ - 0x0, 0x0, 0x3, 0x30, 0x0, 0x0, 0x0, 0x0, - 0x5, 0x5a, 0x65, 0x58, 0x10, 0x0, 0x0, 0xa, - 0x22, 0x22, 0x2a, 0x0, 0x0, 0x0, 0xa, 0x33, - 0x33, 0x3a, 0x0, 0x0, 0x0, 0xa, 0x55, 0x55, - 0x5b, 0x0, 0x0, 0x0, 0x9, 0x55, 0x55, 0x5a, - 0x0, 0x0, 0x0, 0xa5, 0x55, 0x95, 0x55, 0xc2, - 0x0, 0x0, 0xa5, 0x55, 0xc5, 0x55, 0xc0, 0x0, - 0x0, 0xb5, 0x55, 0xc5, 0x55, 0xc0, 0x0, 0x0, - 0x40, 0x0, 0x0, 0x0, 0x42, 0x40, 0x17, 0x55, - 0xc6, 0x55, 0xd5, 0x55, 0x40, 0x0, 0x1, 0xa0, - 0x0, 0xb0, 0x0, 0x0, 0x0, 0x29, 0x10, 0x0, - 0xb0, 0x0, 0x0, 0x1, 0x30, 0x0, 0x0, 0x30, - 0x0, 0x0, - - /* U+F001 "" */ - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x0, 0x0, 0x2, 0x7b, 0xfb, 0x0, - 0x0, 0x0, 0x4, 0x9d, 0xff, 0xff, 0xd0, 0x0, - 0x3, 0xaf, 0xff, 0xff, 0xff, 0xfd, 0x0, 0x0, - 0xaf, 0xff, 0xff, 0xff, 0xdf, 0xd0, 0x0, 0xa, - 0xff, 0xff, 0xb6, 0x10, 0xed, 0x0, 0x0, 0xaf, - 0x94, 0x0, 0x0, 0xe, 0xd0, 0x0, 0xa, 0xf1, - 0x0, 0x0, 0x0, 0xed, 0x0, 0x0, 0xaf, 0x10, - 0x0, 0x0, 0xe, 0xd0, 0x0, 0xa, 0xf1, 0x0, - 0x0, 0x45, 0xfd, 0x0, 0x0, 0xaf, 0x10, 0x1, - 0xef, 0xff, 0xd0, 0x17, 0x9d, 0xf1, 0x0, 0x5f, - 0xff, 0xfc, 0xe, 0xff, 0xff, 0x10, 0x0, 0xaf, - 0xfd, 0x31, 0xff, 0xff, 0xe0, 0x0, 0x0, 0x1, - 0x0, 0x3, 0xbd, 0xa3, 0x0, 0x0, 0x0, 0x0, - 0x0, - - /* U+F008 "" */ - 0x50, 0x18, 0x88, 0x88, 0x88, 0x84, 0x5, 0xfa, - 0xbf, 0xdd, 0xdd, 0xdd, 0xfd, 0xaf, 0xe4, 0x7f, - 0x10, 0x0, 0x0, 0xca, 0x4e, 0xe0, 0x4f, 0x10, - 0x0, 0x0, 0xc8, 0xe, 0xfe, 0xef, 0x10, 0x0, - 0x0, 0xcf, 0xef, 0xe0, 0x3f, 0xee, 0xee, 0xee, - 0xf8, 0xe, 0xf6, 0x8f, 0x76, 0x66, 0x66, 0xeb, - 0x6f, 0xf8, 0xaf, 0x10, 0x0, 0x0, 0xcc, 0x8f, - 0xe0, 0x3f, 0x10, 0x0, 0x0, 0xc8, 0xe, 0xfc, - 0xdf, 0x65, 0x55, 0x55, 0xee, 0xcf, 0xc2, 0x5f, - 0xff, 0xff, 0xff, 0xf9, 0x2c, - - /* U+F00B "" */ - 0x57, 0x75, 0x5, 0x77, 0x77, 0x77, 0x75, 0xff, - 0xff, 0x1f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0x2f, 0xff, 0xff, 0xff, 0xff, 0xef, 0xff, 0xe, - 0xff, 0xff, 0xff, 0xfe, 0x1, 0x10, 0x0, 0x11, - 0x11, 0x11, 0x10, 0xef, 0xfe, 0xe, 0xff, 0xff, - 0xff, 0xfe, 0xff, 0xff, 0x2f, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0x1f, 0xff, 0xff, 0xff, 0xff, - 0x68, 0x87, 0x7, 0x88, 0x88, 0x88, 0x86, 0x68, - 0x87, 0x7, 0x88, 0x88, 0x88, 0x86, 0xff, 0xff, - 0x1f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x2f, - 0xff, 0xff, 0xff, 0xff, 0xdf, 0xfd, 0xd, 0xff, - 0xff, 0xff, 0xfd, - - /* U+F00C "" */ - 0x0, 0x0, 0x0, 0x0, 0x0, 0x1, 0x50, 0x0, - 0x0, 0x0, 0x0, 0x0, 0x1d, 0xf8, 0x0, 0x0, - 0x0, 0x0, 0x1, 0xdf, 0xfd, 0x0, 0x0, 0x0, - 0x0, 0x1d, 0xff, 0xe2, 0x2d, 0x60, 0x0, 0x1, - 0xdf, 0xfe, 0x20, 0xdf, 0xf7, 0x0, 0x1d, 0xff, - 0xe2, 0x0, 0x8f, 0xff, 0x71, 0xdf, 0xfe, 0x20, - 0x0, 0x8, 0xff, 0xfe, 0xff, 0xe2, 0x0, 0x0, - 0x0, 0x8f, 0xff, 0xfe, 0x20, 0x0, 0x0, 0x0, - 0x8, 0xff, 0xe2, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x7d, 0x20, 0x0, 0x0, 0x0, - - /* U+F00D "" */ - 0x0, 0x0, 0x0, 0x0, 0x0, 0x7f, 0x60, 0x0, - 0xb, 0xe2, 0xef, 0xf6, 0x0, 0xbf, 0xf8, 0x4f, - 0xff, 0x6b, 0xff, 0xd1, 0x4, 0xff, 0xff, 0xfd, - 0x10, 0x0, 0x5f, 0xff, 0xe1, 0x0, 0x0, 0xbf, - 0xff, 0xf6, 0x0, 0xb, 0xff, 0xdf, 0xff, 0x60, - 0xbf, 0xfd, 0x14, 0xff, 0xf5, 0xcf, 0xd1, 0x0, - 0x4f, 0xf6, 0x17, 0x10, 0x0, 0x3, 0x60, - - /* U+F011 "" */ - 0x0, 0x0, 0x0, 0x11, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, 0xff, 0x0, 0x0, 0x0, 0x0, 0x6f, - 0x21, 0xff, 0x12, 0xf7, 0x0, 0x6, 0xff, 0x61, - 0xff, 0x16, 0xff, 0x60, 0x1f, 0xf9, 0x1, 0xff, - 0x10, 0x9f, 0xf1, 0x6f, 0xe0, 0x1, 0xff, 0x10, - 0xe, 0xf6, 0xaf, 0x80, 0x1, 0xff, 0x10, 0x8, - 0xfa, 0xcf, 0x60, 0x1, 0xff, 0x10, 0x6, 0xfc, - 0xaf, 0x80, 0x0, 0xaa, 0x0, 0x8, 0xfb, 0x7f, - 0xd0, 0x0, 0x0, 0x0, 0xd, 0xf7, 0x1f, 0xf8, - 0x0, 0x0, 0x0, 0x8f, 0xf1, 0x7, 0xff, 0x91, - 0x0, 0x2a, 0xff, 0x70, 0x0, 0x9f, 0xff, 0xee, - 0xff, 0xf9, 0x0, 0x0, 0x5, 0xcf, 0xff, 0xfd, - 0x50, 0x0, 0x0, 0x0, 0x2, 0x44, 0x20, 0x0, - 0x0, - - /* U+F013 "" */ - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0xa, 0xff, 0xa0, 0x0, 0x0, 0x0, 0x0, - 0xc, 0xff, 0xc0, 0x0, 0x0, 0x3, 0xd6, 0xdf, - 0xff, 0xfd, 0x6d, 0x30, 0xe, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xe0, 0x5f, 0xff, 0xff, 0xaa, 0xff, - 0xff, 0xf5, 0x1a, 0xff, 0xf4, 0x0, 0x4f, 0xff, - 0xa1, 0x3, 0xff, 0xd0, 0x0, 0xd, 0xff, 0x30, - 0x4, 0xff, 0xf0, 0x0, 0xf, 0xff, 0x40, 0x4f, - 0xff, 0xfb, 0x22, 0xbf, 0xff, 0xf4, 0x2f, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xf2, 0x9, 0xfe, 0xff, - 0xff, 0xff, 0xef, 0x90, 0x0, 0x50, 0x5e, 0xff, - 0xe5, 0x5, 0x0, 0x0, 0x0, 0xc, 0xff, 0xc0, - 0x0, 0x0, 0x0, 0x0, 0x4, 0x77, 0x40, 0x0, - 0x0, - - /* U+F015 "" */ - 0x0, 0x0, 0x0, 0x3, 0x10, 0x3, 0x41, 0x0, - 0x0, 0x0, 0x0, 0x9f, 0xf5, 0xd, 0xf5, 0x0, - 0x0, 0x0, 0x1b, 0xfd, 0xff, 0x8d, 0xf5, 0x0, - 0x0, 0x2, 0xdf, 0xb1, 0x2d, 0xff, 0xf5, 0x0, - 0x0, 0x4f, 0xf8, 0x3e, 0xc2, 0xbf, 0xf5, 0x0, - 0x7, 0xff, 0x55, 0xff, 0xfe, 0x39, 0xfe, 0x40, - 0x9f, 0xe3, 0x8f, 0xff, 0xff, 0xf5, 0x6f, 0xf6, - 0xac, 0x2a, 0xff, 0xff, 0xff, 0xff, 0x73, 0xe6, - 0x0, 0x5f, 0xff, 0xff, 0xff, 0xff, 0xf1, 0x0, - 0x0, 0x6f, 0xff, 0xd7, 0x7f, 0xff, 0xf2, 0x0, - 0x0, 0x6f, 0xff, 0x90, 0xd, 0xff, 0xf2, 0x0, - 0x0, 0x6f, 0xff, 0x90, 0xd, 0xff, 0xf2, 0x0, - 0x0, 0x4f, 0xff, 0x70, 0xb, 0xff, 0xe1, 0x0, - - /* U+F019 "" */ - 0x0, 0x0, 0x0, 0x33, 0x0, 0x0, 0x0, 0x0, - 0x0, 0xb, 0xff, 0xb0, 0x0, 0x0, 0x0, 0x0, - 0xc, 0xff, 0xc0, 0x0, 0x0, 0x0, 0x0, 0xc, - 0xff, 0xc0, 0x0, 0x0, 0x0, 0x0, 0xc, 0xff, - 0xc0, 0x0, 0x0, 0x0, 0x0, 0xc, 0xff, 0xc0, - 0x0, 0x0, 0x0, 0x8f, 0xff, 0xff, 0xff, 0xf8, - 0x0, 0x0, 0x2e, 0xff, 0xff, 0xff, 0xe2, 0x0, - 0x0, 0x2, 0xef, 0xff, 0xfe, 0x20, 0x0, 0x0, - 0x0, 0x2d, 0xff, 0xe2, 0x0, 0x0, 0x79, 0x99, - 0x82, 0xde, 0x28, 0x99, 0x97, 0xff, 0xff, 0xfb, - 0x22, 0xbf, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfa, - 0xb3, 0xcf, 0xac, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, - 0xca, - - /* U+F01C "" */ - 0x0, 0x6, 0xbb, 0xbb, 0xbb, 0xba, 0x30, 0x0, - 0x0, 0x4f, 0xff, 0xff, 0xff, 0xff, 0xe1, 0x0, - 0x0, 0xef, 0x30, 0x0, 0x0, 0x6, 0xfb, 0x0, - 0x9, 0xf8, 0x0, 0x0, 0x0, 0x0, 0xcf, 0x50, - 0x4f, 0xd0, 0x0, 0x0, 0x0, 0x0, 0x2f, 0xe1, - 0xdf, 0x84, 0x42, 0x0, 0x0, 0x34, 0x4b, 0xf9, - 0xff, 0xff, 0xfd, 0x0, 0x1, 0xff, 0xff, 0xfb, - 0xff, 0xff, 0xff, 0x98, 0x8b, 0xff, 0xff, 0xfc, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfc, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfb, - 0x9f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf6, - - /* U+F021 "" */ - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x33, 0x0, - 0x1, 0x8d, 0xff, 0xc6, 0x0, 0xef, 0x0, 0x4e, - 0xff, 0xff, 0xff, 0xe4, 0xdf, 0x4, 0xff, 0xb3, - 0x0, 0x4c, 0xff, 0xff, 0xe, 0xf9, 0x0, 0x0, - 0x0, 0x8f, 0xff, 0x6f, 0xc0, 0x0, 0x1, 0xff, - 0xff, 0xff, 0x8e, 0x50, 0x0, 0x1, 0xde, 0xee, - 0xed, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x22, 0x22, 0x22, 0x0, 0x0, 0x0, 0x21, 0xff, - 0xff, 0xff, 0x10, 0x0, 0x8, 0xf8, 0xff, 0xfb, - 0xbc, 0x10, 0x0, 0x1e, 0xf4, 0xff, 0xfc, 0x10, - 0x0, 0x1, 0xdf, 0xc0, 0xfe, 0xef, 0xe8, 0x44, - 0x8e, 0xfe, 0x10, 0xfe, 0x1a, 0xff, 0xff, 0xff, - 0xc1, 0x0, 0xfd, 0x0, 0x28, 0xbb, 0x94, 0x0, - 0x0, - - /* U+F026 "" */ - 0x0, 0x0, 0x2, 0x70, 0x0, 0x2, 0xef, 0x0, - 0x2, 0xef, 0xfd, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0x34, 0x47, 0xff, 0xf0, - 0x0, 0x5, 0xff, 0x0, 0x0, 0x5, 0xc0, 0x0, - 0x0, 0x0, - - /* U+F027 "" */ - 0x0, 0x0, 0x2, 0x70, 0x0, 0x0, 0x0, 0x2, - 0xef, 0x0, 0x0, 0x0, 0x2, 0xef, 0xf0, 0x0, - 0xd, 0xff, 0xff, 0xff, 0x2, 0x20, 0xff, 0xff, - 0xff, 0xf0, 0x8e, 0x1f, 0xff, 0xff, 0xff, 0x0, - 0xe7, 0xff, 0xff, 0xff, 0xf0, 0x3f, 0x5f, 0xff, - 0xff, 0xff, 0x8, 0x90, 0x34, 0x47, 0xff, 0xf0, - 0x0, 0x0, 0x0, 0x5, 0xff, 0x0, 0x0, 0x0, - 0x0, 0x5, 0xc0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, - - /* U+F028 "" */ - 0x0, 0x0, 0x0, 0x0, 0x0, 0x7, 0x70, 0x0, - 0x0, 0x0, 0x2, 0x70, 0x0, 0x5, 0xfa, 0x0, - 0x0, 0x0, 0x2e, 0xf0, 0x0, 0x81, 0x4f, 0x60, - 0x0, 0x2, 0xef, 0xf0, 0x1, 0xdd, 0x7, 0xf0, - 0xdf, 0xff, 0xff, 0xf0, 0x32, 0x1e, 0x80, 0xf6, - 0xff, 0xff, 0xff, 0xf0, 0x8e, 0x27, 0xe0, 0xb9, - 0xff, 0xff, 0xff, 0xf0, 0xe, 0x73, 0xf1, 0x9b, - 0xff, 0xff, 0xff, 0xf0, 0x3f, 0x54, 0xf0, 0x9a, - 0xff, 0xff, 0xff, 0xf0, 0x89, 0xa, 0xc0, 0xd8, - 0x34, 0x47, 0xff, 0xf0, 0x0, 0x7f, 0x43, 0xf3, - 0x0, 0x0, 0x5f, 0xf0, 0x2, 0xf6, 0xc, 0xb0, - 0x0, 0x0, 0x5, 0xc0, 0x0, 0x0, 0xbf, 0x10, - 0x0, 0x0, 0x0, 0x0, 0x0, 0x9, 0xe3, 0x0, - 0x0, 0x0, 0x0, 0x0, 0x0, 0x2, 0x10, 0x0, - - /* U+F03E "" */ - 0x37, 0x88, 0x88, 0x88, 0x88, 0x88, 0x73, 0xef, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe, 0xfe, 0x32, - 0xdf, 0xff, 0xff, 0xff, 0xff, 0xf9, 0x0, 0x7f, - 0xff, 0xfd, 0xff, 0xff, 0xfd, 0x10, 0xcf, 0xff, - 0xa0, 0x7f, 0xff, 0xff, 0xff, 0xff, 0xfa, 0x0, - 0x7, 0xff, 0xff, 0xf3, 0x5f, 0xa0, 0x0, 0x0, - 0xcf, 0xff, 0x30, 0x3, 0x0, 0x0, 0x0, 0xcf, - 0xfc, 0x0, 0x0, 0x0, 0x0, 0x0, 0xcf, 0xff, - 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xff, 0xaf, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xf9, - - /* U+F043 "" */ - 0x0, 0x0, 0x20, 0x0, 0x0, 0x0, 0x1, 0xfa, - 0x0, 0x0, 0x0, 0x6, 0xff, 0x10, 0x0, 0x0, - 0xd, 0xff, 0x70, 0x0, 0x0, 0x6f, 0xff, 0xf1, - 0x0, 0x1, 0xef, 0xff, 0xfa, 0x0, 0xb, 0xff, - 0xff, 0xff, 0x60, 0x5f, 0xff, 0xff, 0xff, 0xe0, - 0xcf, 0xff, 0xff, 0xff, 0xf6, 0xfe, 0xbf, 0xff, - 0xff, 0xf9, 0xfd, 0x4f, 0xff, 0xff, 0xf9, 0xbf, - 0x49, 0xff, 0xff, 0xf5, 0x3f, 0xe5, 0x2e, 0xff, - 0xd0, 0x6, 0xff, 0xff, 0xfd, 0x20, 0x0, 0x28, - 0xba, 0x60, 0x0, - - /* U+F048 "" */ - 0x4, 0x30, 0x0, 0x0, 0x31, 0x1f, 0xe0, 0x0, - 0x6, 0xf9, 0x1f, 0xe0, 0x0, 0x7f, 0xfa, 0x1f, - 0xe0, 0x9, 0xff, 0xfa, 0x1f, 0xe0, 0xaf, 0xff, - 0xfa, 0x1f, 0xeb, 0xff, 0xff, 0xfa, 0x1f, 0xff, - 0xff, 0xff, 0xfa, 0x1f, 0xff, 0xff, 0xff, 0xfa, - 0x1f, 0xe6, 0xff, 0xff, 0xfa, 0x1f, 0xe0, 0x5f, - 0xff, 0xfa, 0x1f, 0xe0, 0x4, 0xff, 0xfa, 0x1f, - 0xe0, 0x0, 0x3e, 0xfa, 0xf, 0xd0, 0x0, 0x2, - 0xd7, 0x0, 0x0, 0x0, 0x0, 0x0, - - /* U+F04B "" */ - 0x2, 0x0, 0x0, 0x0, 0x0, 0x0, 0xc, 0xfb, - 0x20, 0x0, 0x0, 0x0, 0x0, 0xff, 0xff, 0x90, - 0x0, 0x0, 0x0, 0xf, 0xff, 0xff, 0xe6, 0x0, - 0x0, 0x0, 0xff, 0xff, 0xff, 0xfc, 0x30, 0x0, - 0xf, 0xff, 0xff, 0xff, 0xff, 0x91, 0x0, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xe6, 0xf, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xf2, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xfd, 0xf, 0xff, 0xff, 0xff, 0xff, 0xf8, - 0x0, 0xff, 0xff, 0xff, 0xff, 0xb2, 0x0, 0xf, - 0xff, 0xff, 0xfd, 0x40, 0x0, 0x0, 0xff, 0xff, - 0xf7, 0x0, 0x0, 0x0, 0xf, 0xff, 0xa1, 0x0, - 0x0, 0x0, 0x0, 0x6a, 0x40, 0x0, 0x0, 0x0, - 0x0, 0x0, - - /* U+F04C "" */ - 0x14, 0x44, 0x20, 0x1, 0x44, 0x42, 0xd, 0xff, - 0xff, 0x10, 0xdf, 0xff, 0xf1, 0xff, 0xff, 0xf3, - 0xf, 0xff, 0xff, 0x3f, 0xff, 0xff, 0x40, 0xff, - 0xff, 0xf4, 0xff, 0xff, 0xf4, 0xf, 0xff, 0xff, - 0x4f, 0xff, 0xff, 0x40, 0xff, 0xff, 0xf4, 0xff, - 0xff, 0xf4, 0xf, 0xff, 0xff, 0x4f, 0xff, 0xff, - 0x40, 0xff, 0xff, 0xf4, 0xff, 0xff, 0xf4, 0xf, - 0xff, 0xff, 0x4f, 0xff, 0xff, 0x40, 0xff, 0xff, - 0xf4, 0xff, 0xff, 0xf4, 0xf, 0xff, 0xff, 0x4f, - 0xff, 0xff, 0x30, 0xff, 0xff, 0xf3, 0x9f, 0xff, - 0xc0, 0x9, 0xff, 0xfc, 0x0, - - /* U+F04D "" */ - 0x14, 0x44, 0x44, 0x44, 0x44, 0x42, 0xd, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xf1, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0x3f, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xf4, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0x4f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf4, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0x4f, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xf4, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0x4f, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xf4, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x4f, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xf3, 0x9f, 0xff, - 0xff, 0xff, 0xff, 0xfc, 0x0, - - /* U+F051 "" */ - 0x2, 0x10, 0x0, 0x0, 0x42, 0xf, 0xe2, 0x0, - 0x3, 0xfb, 0xf, 0xfe, 0x30, 0x4, 0xfb, 0xf, - 0xff, 0xf4, 0x4, 0xfb, 0xf, 0xff, 0xff, 0x54, - 0xfb, 0xf, 0xff, 0xff, 0xfa, 0xfb, 0xf, 0xff, - 0xff, 0xff, 0xfb, 0xf, 0xff, 0xff, 0xff, 0xfb, - 0xf, 0xff, 0xff, 0xd6, 0xfb, 0xf, 0xff, 0xfd, - 0x14, 0xfb, 0xf, 0xff, 0xc1, 0x4, 0xfb, 0xf, - 0xfb, 0x0, 0x4, 0xfb, 0xc, 0xa0, 0x0, 0x3, - 0xfa, 0x0, 0x0, 0x0, 0x0, 0x0, - - /* U+F052 "" */ - 0x0, 0x0, 0x0, 0x12, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x3, 0xff, 0x60, 0x0, 0x0, 0x0, 0x0, - 0x2e, 0xff, 0xf5, 0x0, 0x0, 0x0, 0x1, 0xef, - 0xff, 0xff, 0x40, 0x0, 0x0, 0x1d, 0xff, 0xff, - 0xff, 0xf3, 0x0, 0x0, 0xcf, 0xff, 0xff, 0xff, - 0xfe, 0x20, 0xa, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xe0, 0xe, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf2, - 0x3, 0x99, 0x99, 0x99, 0x99, 0x99, 0x50, 0x5, - 0x88, 0x88, 0x88, 0x88, 0x88, 0x70, 0xf, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xf3, 0xf, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xf4, 0xb, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xd1, - - /* U+F053 "" */ - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x3f, - 0x90, 0x0, 0x0, 0x3f, 0xfc, 0x0, 0x0, 0x3f, - 0xfd, 0x10, 0x0, 0x3f, 0xfd, 0x10, 0x0, 0x3f, - 0xfd, 0x10, 0x0, 0x1f, 0xfd, 0x10, 0x0, 0x0, - 0xcf, 0xf4, 0x0, 0x0, 0x0, 0xcf, 0xf4, 0x0, - 0x0, 0x0, 0xcf, 0xf4, 0x0, 0x0, 0x0, 0xcf, - 0xf4, 0x0, 0x0, 0x0, 0xcf, 0xe0, 0x0, 0x0, - 0x0, 0xa4, 0x0, - - /* U+F054 "" */ - 0x0, 0x0, 0x0, 0x0, 0x0, 0xcd, 0x10, 0x0, - 0x0, 0x1f, 0xfd, 0x10, 0x0, 0x0, 0x3f, 0xfd, - 0x10, 0x0, 0x0, 0x3f, 0xfd, 0x10, 0x0, 0x0, - 0x3f, 0xfd, 0x10, 0x0, 0x0, 0x3f, 0xfd, 0x0, - 0x0, 0x8, 0xff, 0x90, 0x0, 0x8, 0xff, 0x90, - 0x0, 0x8, 0xff, 0x90, 0x0, 0x8, 0xff, 0x90, - 0x0, 0x2, 0xff, 0x90, 0x0, 0x0, 0x7, 0x80, - 0x0, 0x0, 0x0, - - /* U+F067 "" */ - 0x0, 0x0, 0x4, 0x50, 0x0, 0x0, 0x0, 0x0, - 0x2, 0xff, 0x60, 0x0, 0x0, 0x0, 0x0, 0x3f, - 0xf7, 0x0, 0x0, 0x0, 0x0, 0x3, 0xff, 0x70, - 0x0, 0x0, 0x0, 0x0, 0x3f, 0xf7, 0x0, 0x0, - 0x6, 0x99, 0x9a, 0xff, 0xc9, 0x99, 0x80, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0x3d, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xf2, 0x1, 0x11, 0x3f, 0xf7, - 0x11, 0x10, 0x0, 0x0, 0x3, 0xff, 0x70, 0x0, - 0x0, 0x0, 0x0, 0x3f, 0xf7, 0x0, 0x0, 0x0, - 0x0, 0x3, 0xff, 0x70, 0x0, 0x0, 0x0, 0x0, - 0xc, 0xd3, 0x0, 0x0, 0x0, - - /* U+F068 "" */ - 0x69, 0x99, 0x99, 0x99, 0x99, 0x98, 0xf, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xf3, 0xdf, 0xff, 0xff, - 0xff, 0xff, 0xff, 0x20, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, - - /* U+F06E "" */ - 0x0, 0x0, 0x1, 0x56, 0x64, 0x0, 0x0, 0x0, - 0x0, 0x3, 0xbf, 0xfe, 0xef, 0xf9, 0x10, 0x0, - 0x0, 0x7f, 0xfa, 0x10, 0x3, 0xdf, 0xe4, 0x0, - 0x8, 0xff, 0xa0, 0x9, 0xb4, 0x1e, 0xff, 0x50, - 0x4f, 0xff, 0x20, 0xb, 0xff, 0x26, 0xff, 0xe1, - 0xef, 0xff, 0x9, 0xcf, 0xff, 0x63, 0xff, 0xfa, - 0xbf, 0xff, 0x9, 0xff, 0xff, 0x54, 0xff, 0xf6, - 0x1e, 0xff, 0x51, 0xdf, 0xfb, 0x9, 0xff, 0xb0, - 0x3, 0xef, 0xe2, 0x4, 0x30, 0x5f, 0xfc, 0x10, - 0x0, 0x2c, 0xff, 0x95, 0x6a, 0xff, 0x90, 0x0, - 0x0, 0x0, 0x49, 0xdf, 0xfd, 0x92, 0x0, 0x0, - - /* U+F070 "" */ - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0xcd, 0x20, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x8f, 0xf5, 0x0, 0x14, 0x66, 0x40, - 0x0, 0x0, 0x0, 0x4, 0xef, 0xac, 0xff, 0xef, - 0xff, 0x91, 0x0, 0x0, 0x0, 0x1c, 0xff, 0xa1, - 0x0, 0x4d, 0xfe, 0x30, 0x0, 0x0, 0x0, 0x9f, - 0xf5, 0xab, 0x31, 0xef, 0xf4, 0x0, 0x7, 0xb1, - 0x5, 0xff, 0xff, 0xe1, 0x7f, 0xfe, 0x10, 0xf, - 0xfe, 0x30, 0x2d, 0xff, 0xf5, 0x4f, 0xff, 0x90, - 0xc, 0xff, 0xe0, 0x0, 0xaf, 0xf6, 0x5f, 0xff, - 0x60, 0x2, 0xff, 0xf4, 0x0, 0x6, 0xff, 0xef, - 0xfb, 0x0, 0x0, 0x4f, 0xfd, 0x10, 0x0, 0x3e, - 0xff, 0xc0, 0x0, 0x0, 0x2, 0xdf, 0xe8, 0x54, - 0x1, 0xbf, 0xe3, 0x0, 0x0, 0x0, 0x5, 0xae, - 0xff, 0x60, 0x7, 0xff, 0x60, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x0, 0x0, 0x4e, 0xf6, 0x0, 0x0, - 0x0, 0x0, 0x0, 0x0, 0x0, 0x1, 0xa1, - - /* U+F071 "" */ - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x0, 0x0, 0x3e, 0xd0, 0x0, 0x0, - 0x0, 0x0, 0x0, 0x0, 0xc, 0xff, 0x80, 0x0, - 0x0, 0x0, 0x0, 0x0, 0x6, 0xff, 0xff, 0x20, - 0x0, 0x0, 0x0, 0x0, 0x0, 0xef, 0xff, 0xfb, - 0x0, 0x0, 0x0, 0x0, 0x0, 0x8f, 0xfc, 0xcf, - 0xf4, 0x0, 0x0, 0x0, 0x0, 0x2f, 0xfb, 0x0, - 0xff, 0xd0, 0x0, 0x0, 0x0, 0xb, 0xff, 0xc0, - 0xf, 0xff, 0x70, 0x0, 0x0, 0x4, 0xff, 0xfd, - 0x1, 0xff, 0xff, 0x10, 0x0, 0x0, 0xdf, 0xff, - 0xe0, 0x2f, 0xff, 0xfa, 0x0, 0x0, 0x7f, 0xff, - 0xff, 0x9b, 0xff, 0xff, 0xf3, 0x0, 0x1f, 0xff, - 0xff, 0xb0, 0xe, 0xff, 0xff, 0xc0, 0xa, 0xff, - 0xff, 0xfe, 0x24, 0xff, 0xff, 0xff, 0x60, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfa, 0x6, - 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcb, 0x30, - - /* U+F074 "" */ - 0x0, 0x0, 0x0, 0x0, 0x0, 0x36, 0x0, 0x0, - 0x0, 0x0, 0x0, 0x0, 0x7f, 0x80, 0xdd, 0xdb, - 0x0, 0x0, 0x8d, 0xef, 0xf8, 0xff, 0xff, 0xb0, - 0x7, 0xff, 0xff, 0xfd, 0x55, 0x6f, 0xf4, 0x6f, - 0xf8, 0xaf, 0xe2, 0x0, 0x5, 0x74, 0xff, 0x90, - 0x7e, 0x20, 0x0, 0x0, 0x3f, 0xfa, 0x0, 0x0, - 0x0, 0x0, 0x2, 0xef, 0xb2, 0x50, 0x4a, 0x0, - 0x1, 0x2e, 0xfd, 0x1d, 0xf4, 0x8f, 0xb0, 0xff, - 0xff, 0xd1, 0xb, 0xff, 0xff, 0xfb, 0xff, 0xfe, - 0x20, 0x0, 0xcf, 0xff, 0xfb, 0x12, 0x21, 0x0, - 0x0, 0x2, 0x9f, 0xc0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x5b, 0x0, - - /* U+F077 "" */ - 0x0, 0x0, 0x7, 0xa0, 0x0, 0x0, 0x0, 0x0, - 0x8, 0xff, 0xb0, 0x0, 0x0, 0x0, 0x8, 0xff, - 0xff, 0xb0, 0x0, 0x0, 0x8, 0xff, 0x95, 0xff, - 0xb0, 0x0, 0x8, 0xff, 0x90, 0x5, 0xff, 0xb0, - 0x7, 0xff, 0x90, 0x0, 0x5, 0xff, 0xb0, 0x9f, - 0x90, 0x0, 0x0, 0x5, 0xfd, 0x0, 0x40, 0x0, - 0x0, 0x0, 0x3, 0x10, - - /* U+F078 "" */ - 0x4c, 0x20, 0x0, 0x0, 0x0, 0xb6, 0xb, 0xfe, - 0x20, 0x0, 0x0, 0xcf, 0xf0, 0x2e, 0xfe, 0x20, - 0x0, 0xcf, 0xf4, 0x0, 0x2e, 0xfe, 0x20, 0xcf, - 0xf4, 0x0, 0x0, 0x2e, 0xfe, 0xcf, 0xf4, 0x0, - 0x0, 0x0, 0x2e, 0xff, 0xf4, 0x0, 0x0, 0x0, - 0x0, 0x2e, 0xf4, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x13, 0x0, 0x0, 0x0, - - /* U+F079 "" */ - 0x0, 0x8, 0x30, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, 0xbf, 0xf3, 0x8, 0xbb, 0xbb, 0xbb, - 0x90, 0x0, 0xb, 0xff, 0xff, 0x39, 0xff, 0xff, - 0xff, 0xf1, 0x0, 0x8f, 0xcf, 0xcf, 0xf0, 0x0, - 0x0, 0xa, 0xf1, 0x0, 0x38, 0x2f, 0x94, 0x80, - 0x0, 0x0, 0xa, 0xf1, 0x0, 0x0, 0x2f, 0x90, - 0x0, 0x0, 0x0, 0xa, 0xf1, 0x0, 0x0, 0x2f, - 0x90, 0x0, 0x0, 0x3, 0xa, 0xf1, 0x30, 0x0, - 0x2f, 0x90, 0x0, 0x0, 0x1f, 0xcb, 0xf8, 0xf8, - 0x0, 0x2f, 0xeb, 0xbb, 0xbb, 0x39, 0xff, 0xff, - 0xe2, 0x0, 0x1f, 0xff, 0xff, 0xff, 0xb0, 0x9f, - 0xfd, 0x20, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x8, 0xd1, 0x0, - - /* U+F07B "" */ - 0x37, 0x88, 0x87, 0x0, 0x0, 0x0, 0x0, 0xef, - 0xff, 0xff, 0xa0, 0x0, 0x0, 0x0, 0xff, 0xff, - 0xff, 0xfd, 0xcc, 0xcc, 0xb6, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xaf, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xf9, - - /* U+F093 "" */ - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x1, 0xdd, 0x10, 0x0, 0x0, 0x0, 0x0, - 0x1d, 0xff, 0xd1, 0x0, 0x0, 0x0, 0x1, 0xdf, - 0xff, 0xfd, 0x10, 0x0, 0x0, 0x1d, 0xff, 0xff, - 0xff, 0xd1, 0x0, 0x0, 0x9f, 0xff, 0xff, 0xff, - 0xf9, 0x0, 0x0, 0x1, 0x1c, 0xff, 0xc1, 0x10, - 0x0, 0x0, 0x0, 0xc, 0xff, 0xc0, 0x0, 0x0, - 0x0, 0x0, 0xc, 0xff, 0xc0, 0x0, 0x0, 0x0, - 0x0, 0xc, 0xff, 0xc0, 0x0, 0x0, 0x79, 0x99, - 0x3b, 0xff, 0xb3, 0x99, 0x97, 0xff, 0xff, 0xb2, - 0x44, 0x2b, 0xff, 0xff, 0xff, 0xff, 0xfe, 0xdd, - 0xef, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfa, - 0xb3, 0xcf, 0xac, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, - 0xca, - - /* U+F095 "" */ - 0x0, 0x0, 0x0, 0x0, 0x0, 0x2, 0x0, 0x0, - 0x0, 0x0, 0x0, 0x0, 0x4, 0xff, 0xc7, 0x0, - 0x0, 0x0, 0x0, 0x0, 0xaf, 0xff, 0xf0, 0x0, - 0x0, 0x0, 0x0, 0x1f, 0xff, 0xfd, 0x0, 0x0, - 0x0, 0x0, 0x6, 0xff, 0xff, 0xc0, 0x0, 0x0, - 0x0, 0x0, 0x8, 0xff, 0xf7, 0x0, 0x0, 0x0, - 0x0, 0x0, 0xc, 0xff, 0x30, 0x0, 0x0, 0x0, - 0x0, 0x4, 0xff, 0xc0, 0x0, 0x0, 0x0, 0x0, - 0x1, 0xef, 0xf3, 0x0, 0x0, 0x4a, 0x30, 0x2, - 0xdf, 0xf8, 0x0, 0x5, 0xdf, 0xfe, 0x15, 0xef, - 0xfb, 0x0, 0x0, 0xef, 0xff, 0xff, 0xff, 0xfa, - 0x0, 0x0, 0xb, 0xff, 0xff, 0xff, 0xf7, 0x0, - 0x0, 0x0, 0x7f, 0xff, 0xff, 0xa2, 0x0, 0x0, - 0x0, 0x2, 0xba, 0x85, 0x0, 0x0, 0x0, 0x0, - 0x0, - - /* U+F0C4 "" */ - 0x4, 0x86, 0x0, 0x0, 0x0, 0x10, 0x6, 0xff, - 0xfa, 0x0, 0x2, 0xdf, 0xd1, 0xef, 0x3c, 0xf1, - 0x1, 0xdf, 0xfa, 0xe, 0xe0, 0xaf, 0x21, 0xdf, - 0xfa, 0x0, 0x9f, 0xef, 0xf6, 0xdf, 0xfa, 0x0, - 0x0, 0x8d, 0xff, 0xff, 0xfb, 0x0, 0x0, 0x0, - 0x6, 0xff, 0xfd, 0x0, 0x0, 0x0, 0x48, 0xef, - 0xff, 0xf6, 0x0, 0x0, 0x6f, 0xff, 0xfb, 0xff, - 0xf6, 0x0, 0xe, 0xf3, 0xcf, 0x23, 0xff, 0xf6, - 0x0, 0xee, 0xa, 0xf2, 0x4, 0xff, 0xf6, 0x9, - 0xfe, 0xfc, 0x0, 0x4, 0xff, 0xf1, 0x8, 0xda, - 0x10, 0x0, 0x2, 0x62, 0x0, - - /* U+F0C5 "" */ - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x6f, 0xff, 0xf9, 0x87, 0x0, 0x0, 0x8, 0xff, - 0xff, 0x98, 0xf7, 0x8, 0xa6, 0x8f, 0xff, 0xf9, - 0x59, 0x90, 0xff, 0xa8, 0xff, 0xff, 0xfc, 0xcc, - 0xf, 0xfa, 0x8f, 0xff, 0xff, 0xff, 0xf1, 0xff, - 0xa8, 0xff, 0xff, 0xff, 0xff, 0x1f, 0xfa, 0x8f, - 0xff, 0xff, 0xff, 0xf1, 0xff, 0xa8, 0xff, 0xff, - 0xff, 0xff, 0x1f, 0xfa, 0x8f, 0xff, 0xff, 0xff, - 0xf1, 0xff, 0xa8, 0xff, 0xff, 0xff, 0xff, 0x1f, - 0xfa, 0x7f, 0xff, 0xff, 0xff, 0xf0, 0xff, 0xe3, - 0x12, 0x22, 0x22, 0x21, 0xf, 0xff, 0xff, 0xff, - 0xf9, 0x0, 0x0, 0xac, 0xcc, 0xcc, 0xcb, 0x50, - 0x0, 0x0, - - /* U+F0C7 "" */ - 0x49, 0x99, 0x99, 0x99, 0x95, 0x0, 0xe, 0xff, - 0xff, 0xff, 0xff, 0xf6, 0x0, 0xfd, 0x22, 0x22, - 0x22, 0x4f, 0xf6, 0xf, 0xc0, 0x0, 0x0, 0x1, - 0xff, 0xf3, 0xfc, 0x0, 0x0, 0x0, 0x1f, 0xff, - 0x6f, 0xc0, 0x0, 0x0, 0x2, 0xff, 0xf6, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0x6f, 0xff, 0xff, - 0xdc, 0xff, 0xff, 0xf6, 0xff, 0xff, 0xb0, 0x5, - 0xff, 0xff, 0x6f, 0xff, 0xf6, 0x0, 0xf, 0xff, - 0xf6, 0xff, 0xff, 0xc0, 0x6, 0xff, 0xff, 0x6f, - 0xff, 0xff, 0xed, 0xff, 0xff, 0xf6, 0x9f, 0xff, - 0xff, 0xff, 0xff, 0xfd, 0x10, - - /* U+F0C9 "" */ - 0xcd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0x2f, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xf3, 0x12, 0x22, 0x22, - 0x22, 0x22, 0x22, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0xf, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf3, 0xde, - 0xee, 0xee, 0xee, 0xee, 0xee, 0x20, 0x0, 0x0, - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, 0xd, 0xee, 0xee, 0xee, 0xee, 0xee, - 0xe2, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x30, - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - - /* U+F0E0 "" */ - 0x37, 0x88, 0x88, 0x88, 0x88, 0x88, 0x73, 0xef, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe, 0xef, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xfe, 0x1c, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xc1, 0xd2, 0x8f, 0xff, 0xff, - 0xff, 0xf8, 0x2d, 0xff, 0x64, 0xef, 0xff, 0xfe, - 0x45, 0xff, 0xff, 0xfa, 0x2b, 0xff, 0xb2, 0xaf, - 0xff, 0xff, 0xff, 0xd3, 0x55, 0x3d, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xbb, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xaf, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xf9, - - /* U+F0E7 "" */ - 0x0, 0x0, 0x0, 0x0, 0x0, 0x1, 0xff, 0xff, - 0xf0, 0x0, 0x4, 0xff, 0xff, 0xd0, 0x0, 0x6, - 0xff, 0xff, 0x80, 0x0, 0x8, 0xff, 0xff, 0x30, - 0x0, 0xa, 0xff, 0xff, 0xaa, 0xa6, 0xc, 0xff, - 0xff, 0xff, 0xf8, 0xe, 0xff, 0xff, 0xff, 0xe1, - 0xb, 0xdd, 0xdf, 0xff, 0x60, 0x0, 0x0, 0x4f, - 0xfd, 0x0, 0x0, 0x0, 0x7f, 0xf3, 0x0, 0x0, - 0x0, 0xbf, 0xa0, 0x0, 0x0, 0x0, 0xff, 0x10, - 0x0, 0x0, 0x3, 0xf8, 0x0, 0x0, 0x0, 0x3, - 0xc0, 0x0, 0x0, - - /* U+F0EA "" */ - 0x0, 0x0, 0x20, 0x0, 0x0, 0x0, 0x4, 0x55, - 0xef, 0xb5, 0x52, 0x0, 0x0, 0xff, 0xfd, 0x1f, - 0xff, 0xb0, 0x0, 0xf, 0xff, 0xff, 0xff, 0xfc, - 0x0, 0x0, 0xff, 0xff, 0x53, 0x33, 0x20, 0x0, - 0xf, 0xff, 0x97, 0xff, 0xfb, 0x57, 0x0, 0xff, - 0xf8, 0xaf, 0xff, 0xc6, 0xf8, 0xf, 0xff, 0x8a, - 0xff, 0xfc, 0x4a, 0xa1, 0xff, 0xf8, 0xaf, 0xff, - 0xe3, 0x22, 0xf, 0xff, 0x8a, 0xff, 0xff, 0xff, - 0xf4, 0xff, 0xf8, 0xaf, 0xff, 0xff, 0xff, 0x4f, - 0xff, 0x8a, 0xff, 0xff, 0xff, 0xf4, 0x35, 0x52, - 0xaf, 0xff, 0xff, 0xff, 0x40, 0x0, 0xa, 0xff, - 0xff, 0xff, 0xf4, 0x0, 0x0, 0x7f, 0xff, 0xff, - 0xfe, 0x20, - - /* U+F0F3 "" */ - 0x0, 0x0, 0x1, 0x10, 0x0, 0x0, 0x0, 0x0, - 0x0, 0xaf, 0x0, 0x0, 0x0, 0x0, 0x1, 0x8f, - 0xfa, 0x30, 0x0, 0x0, 0x2, 0xef, 0xff, 0xff, - 0x50, 0x0, 0x0, 0xbf, 0xff, 0xff, 0xff, 0x10, - 0x0, 0x1f, 0xff, 0xff, 0xff, 0xf5, 0x0, 0x3, - 0xff, 0xff, 0xff, 0xff, 0x70, 0x0, 0x5f, 0xff, - 0xff, 0xff, 0xf9, 0x0, 0x8, 0xff, 0xff, 0xff, - 0xff, 0xc0, 0x0, 0xdf, 0xff, 0xff, 0xff, 0xff, - 0x20, 0x9f, 0xff, 0xff, 0xff, 0xff, 0xfd, 0xe, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xf2, 0x2, 0x22, - 0x22, 0x22, 0x22, 0x21, 0x0, 0x0, 0x8, 0xff, - 0xc0, 0x0, 0x0, 0x0, 0x0, 0x9, 0xa2, 0x0, - 0x0, 0x0, - - /* U+F11C "" */ - 0x5b, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xa3, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfb, - 0xfc, 0xc, 0x30, 0xe1, 0x1d, 0xd, 0x11, 0xfc, - 0xfc, 0xb, 0x30, 0xe0, 0x1d, 0xd, 0x10, 0xfc, - 0xff, 0xfe, 0xff, 0xef, 0xfe, 0xfe, 0xef, 0xfc, - 0xff, 0xf1, 0x5a, 0x8, 0x70, 0xa0, 0x5f, 0xfc, - 0xff, 0xf3, 0x7b, 0x29, 0x92, 0xc2, 0x7f, 0xfc, - 0xff, 0xbf, 0xcb, 0xbb, 0xbb, 0xbf, 0xcb, 0xfc, - 0xfc, 0xb, 0x20, 0x0, 0x0, 0xd, 0x0, 0xfc, - 0xff, 0xcf, 0xcc, 0xcc, 0xcc, 0xcf, 0xcc, 0xfb, - 0x9f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf6, - - /* U+F124 "" */ - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x2, 0x0, - 0x0, 0x0, 0x0, 0x0, 0x0, 0x5, 0xdf, 0xb0, - 0x0, 0x0, 0x0, 0x0, 0x7, 0xef, 0xff, 0xd0, - 0x0, 0x0, 0x0, 0x18, 0xff, 0xff, 0xff, 0x70, - 0x0, 0x0, 0x29, 0xff, 0xff, 0xff, 0xff, 0x0, - 0x0, 0x3b, 0xff, 0xff, 0xff, 0xff, 0xf8, 0x0, - 0xa, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf1, 0x0, - 0xf, 0xff, 0xff, 0xff, 0xff, 0xff, 0xa0, 0x0, - 0x4, 0x9a, 0xaa, 0xaf, 0xff, 0xff, 0x20, 0x0, - 0x0, 0x0, 0x0, 0xe, 0xff, 0xfb, 0x0, 0x0, - 0x0, 0x0, 0x0, 0xe, 0xff, 0xf4, 0x0, 0x0, - 0x0, 0x0, 0x0, 0xe, 0xff, 0xc0, 0x0, 0x0, - 0x0, 0x0, 0x0, 0xe, 0xff, 0x50, 0x0, 0x0, - 0x0, 0x0, 0x0, 0xd, 0xfd, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x0, 0x4, 0xb3, 0x0, 0x0, 0x0, - - /* U+F15B "" */ - 0x35, 0x55, 0x55, 0x2, 0x0, 0xf, 0xff, 0xff, - 0xf2, 0xf4, 0x0, 0xff, 0xff, 0xff, 0x2f, 0xf4, - 0xf, 0xff, 0xff, 0xf2, 0xff, 0xf3, 0xff, 0xff, - 0xff, 0x32, 0x22, 0x1f, 0xff, 0xff, 0xff, 0xff, - 0xf7, 0xff, 0xff, 0xff, 0xff, 0xff, 0x8f, 0xff, - 0xff, 0xff, 0xff, 0xf8, 0xff, 0xff, 0xff, 0xff, - 0xff, 0x8f, 0xff, 0xff, 0xff, 0xff, 0xf8, 0xff, - 0xff, 0xff, 0xff, 0xff, 0x8f, 0xff, 0xff, 0xff, - 0xff, 0xf8, 0xff, 0xff, 0xff, 0xff, 0xff, 0x8f, - 0xff, 0xff, 0xff, 0xff, 0xf8, 0x8a, 0xaa, 0xaa, - 0xaa, 0xaa, 0x30, - - /* U+F1EB "" */ - 0x0, 0x0, 0x0, 0x24, 0x55, 0x31, 0x0, 0x0, - 0x0, 0x0, 0x3, 0xaf, 0xff, 0xff, 0xff, 0xc7, - 0x0, 0x0, 0x2, 0xbf, 0xff, 0xfe, 0xde, 0xff, - 0xff, 0xf6, 0x0, 0x5f, 0xff, 0xb5, 0x10, 0x0, - 0x3, 0x8e, 0xff, 0xb0, 0xdf, 0xd3, 0x0, 0x0, - 0x0, 0x0, 0x0, 0x8f, 0xf5, 0x18, 0x0, 0x5, - 0xae, 0xfe, 0xc8, 0x10, 0x4, 0x60, 0x0, 0x2, - 0xdf, 0xff, 0xff, 0xff, 0xf8, 0x0, 0x0, 0x0, - 0xc, 0xff, 0x95, 0x34, 0x7d, 0xff, 0x40, 0x0, - 0x0, 0x2, 0xa2, 0x0, 0x0, 0x0, 0x77, 0x0, - 0x0, 0x0, 0x0, 0x0, 0x2, 0x96, 0x0, 0x0, - 0x0, 0x0, 0x0, 0x0, 0x0, 0xd, 0xff, 0x50, - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xe, 0xff, - 0x60, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x5, - 0xda, 0x0, 0x0, 0x0, 0x0, - - /* U+F240 "" */ - 0x5b, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xba, - 0x20, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0x90, 0xfc, 0x12, 0x22, 0x22, 0x22, 0x22, - 0x22, 0xf, 0xf7, 0xfc, 0x5f, 0xff, 0xff, 0xff, - 0xff, 0xff, 0x2c, 0xfa, 0xfc, 0x5f, 0xff, 0xff, - 0xff, 0xff, 0xff, 0x21, 0xfa, 0xfc, 0x5f, 0xff, - 0xff, 0xff, 0xff, 0xff, 0x27, 0xfa, 0xfc, 0x26, - 0x66, 0x66, 0x66, 0x66, 0x66, 0x1f, 0xfa, 0xfe, - 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbf, 0xb1, - 0xaf, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0x50, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, - - /* U+F241 "" */ - 0x5b, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xba, - 0x20, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0x90, 0xfc, 0x12, 0x22, 0x22, 0x22, 0x21, - 0x0, 0xf, 0xf7, 0xfc, 0x5f, 0xff, 0xff, 0xff, - 0xf8, 0x0, 0xc, 0xfa, 0xfc, 0x5f, 0xff, 0xff, - 0xff, 0xf8, 0x0, 0x1, 0xfa, 0xfc, 0x5f, 0xff, - 0xff, 0xff, 0xf8, 0x0, 0x7, 0xfa, 0xfc, 0x26, - 0x66, 0x66, 0x66, 0x63, 0x0, 0xf, 0xfa, 0xfe, - 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbf, 0xb1, - 0xaf, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0x50, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, - - /* U+F242 "" */ - 0x5b, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xba, - 0x20, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0x90, 0xfc, 0x12, 0x22, 0x22, 0x10, 0x0, - 0x0, 0xf, 0xf7, 0xfc, 0x5f, 0xff, 0xff, 0xd0, - 0x0, 0x0, 0xc, 0xfa, 0xfc, 0x5f, 0xff, 0xff, - 0xd0, 0x0, 0x0, 0x1, 0xfa, 0xfc, 0x5f, 0xff, - 0xff, 0xd0, 0x0, 0x0, 0x7, 0xfa, 0xfc, 0x26, - 0x66, 0x66, 0x50, 0x0, 0x0, 0xf, 0xfa, 0xfe, - 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbf, 0xb1, - 0xaf, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0x50, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, - - /* U+F243 "" */ - 0x5b, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xba, - 0x20, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0x90, 0xfc, 0x12, 0x22, 0x0, 0x0, 0x0, - 0x0, 0xf, 0xf7, 0xfc, 0x5f, 0xff, 0x30, 0x0, - 0x0, 0x0, 0xc, 0xfa, 0xfc, 0x5f, 0xff, 0x30, - 0x0, 0x0, 0x0, 0x1, 0xfa, 0xfc, 0x5f, 0xff, - 0x30, 0x0, 0x0, 0x0, 0x7, 0xfa, 0xfc, 0x26, - 0x66, 0x10, 0x0, 0x0, 0x0, 0xf, 0xfa, 0xfe, - 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbf, 0xb1, - 0xaf, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0x50, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, - - /* U+F244 "" */ - 0x5b, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xba, - 0x20, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0x90, 0xfc, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0xf, 0xf7, 0xfc, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, 0xc, 0xfa, 0xfc, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x0, 0x1, 0xfa, 0xfc, 0x0, 0x0, - 0x0, 0x0, 0x0, 0x0, 0x7, 0xfa, 0xfc, 0x0, - 0x0, 0x0, 0x0, 0x0, 0x0, 0xf, 0xfa, 0xfe, - 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbf, 0xb1, - 0xaf, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0x50, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, - - /* U+F287 "" */ - 0x0, 0x0, 0x0, 0x0, 0x7, 0xb2, 0x0, 0x0, - 0x0, 0x0, 0x0, 0x0, 0xa, 0xdf, 0xfa, 0x0, - 0x0, 0x0, 0x0, 0x0, 0x0, 0xa9, 0x3d, 0xf5, - 0x0, 0x0, 0x0, 0x4, 0x40, 0x2, 0xe0, 0x0, - 0x10, 0x0, 0x0, 0x0, 0xaf, 0xf8, 0xb, 0x60, - 0x0, 0x0, 0x0, 0x6c, 0x30, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xf4, 0xaf, 0xf9, - 0x0, 0xc, 0x50, 0x0, 0x0, 0x6d, 0x40, 0x5, - 0x50, 0x0, 0x4, 0xc0, 0x0, 0x0, 0x10, 0x0, - 0x0, 0x0, 0x0, 0x0, 0xc4, 0x3e, 0xe8, 0x0, - 0x0, 0x0, 0x0, 0x0, 0x0, 0x2e, 0xef, 0xfa, - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x4f, - 0xfa, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x0, 0x0, - - /* U+F293 "" */ - 0x0, 0x0, 0x1, 0x10, 0x0, 0x0, 0x0, 0x7, - 0xef, 0xff, 0xb3, 0x0, 0x0, 0xaf, 0xfd, 0x8f, - 0xff, 0x20, 0x4, 0xff, 0xfd, 0x9, 0xff, 0xb0, - 0xa, 0xfe, 0xfd, 0x12, 0xaf, 0xf0, 0xe, 0xf5, - 0x5d, 0x2c, 0xe, 0xf3, 0xf, 0xff, 0x33, 0x12, - 0x9f, 0xf5, 0xf, 0xff, 0xf3, 0x7, 0xff, 0xf6, - 0xf, 0xff, 0xe2, 0x6, 0xff, 0xf6, 0xf, 0xfe, - 0x24, 0x13, 0x7f, 0xf5, 0xd, 0xf5, 0x7d, 0x2c, - 0xd, 0xf3, 0xa, 0xff, 0xfd, 0x11, 0xbf, 0xf0, - 0x3, 0xff, 0xfe, 0xb, 0xff, 0xa0, 0x0, 0x7f, - 0xfe, 0xbf, 0xfe, 0x10, 0x0, 0x3, 0xac, 0xdc, - 0x81, 0x0, - - /* U+F2ED "" */ - 0x0, 0x0, 0x34, 0x43, 0x0, 0x0, 0x5, 0x66, - 0x7f, 0xff, 0xf9, 0x66, 0x50, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0x35, 0x66, 0x66, 0x66, 0x66, - 0x66, 0x50, 0x1c, 0xcc, 0xcc, 0xcc, 0xcc, 0xc4, - 0x2, 0xff, 0xff, 0xff, 0xff, 0xff, 0x60, 0x2f, - 0xf3, 0xfb, 0x7f, 0x6d, 0xf6, 0x2, 0xff, 0x2f, - 0xb7, 0xf5, 0xdf, 0x60, 0x2f, 0xf2, 0xfb, 0x7f, - 0x5d, 0xf6, 0x2, 0xff, 0x2f, 0xb7, 0xf5, 0xdf, - 0x60, 0x2f, 0xf2, 0xfb, 0x7f, 0x5d, 0xf6, 0x2, - 0xff, 0x2f, 0xb7, 0xf5, 0xdf, 0x60, 0x2f, 0xf3, - 0xfb, 0x7f, 0x6d, 0xf6, 0x1, 0xff, 0xff, 0xff, - 0xff, 0xff, 0x50, 0x7, 0xbc, 0xcc, 0xcc, 0xcc, - 0x90, 0x0, - - /* U+F304 "" */ - 0x0, 0x0, 0x0, 0x0, 0x0, 0x1, 0x20, 0x0, - 0x0, 0x0, 0x0, 0x0, 0x4, 0xff, 0x50, 0x0, - 0x0, 0x0, 0x0, 0x2, 0xff, 0xff, 0x50, 0x0, - 0x0, 0x0, 0x4, 0x39, 0xff, 0xfe, 0x0, 0x0, - 0x0, 0x4, 0xff, 0x39, 0xff, 0xa0, 0x0, 0x0, - 0x4, 0xff, 0xff, 0x39, 0xb0, 0x0, 0x0, 0x4, - 0xff, 0xff, 0xff, 0x20, 0x0, 0x0, 0x4, 0xff, - 0xff, 0xff, 0xb0, 0x0, 0x0, 0x4, 0xff, 0xff, - 0xff, 0xb0, 0x0, 0x0, 0x4, 0xff, 0xff, 0xff, - 0xb0, 0x0, 0x0, 0x4, 0xff, 0xff, 0xff, 0xb0, - 0x0, 0x0, 0x0, 0xbf, 0xff, 0xff, 0xb0, 0x0, - 0x0, 0x0, 0xd, 0xff, 0xff, 0xb0, 0x0, 0x0, - 0x0, 0x0, 0xff, 0xff, 0xb0, 0x0, 0x0, 0x0, - 0x0, 0x9, 0xa8, 0x60, 0x0, 0x0, 0x0, 0x0, - 0x0, - - /* U+F55A "" */ - 0x0, 0x0, 0x17, 0x88, 0x88, 0x88, 0x88, 0x87, - 0x40, 0x0, 0x2, 0xef, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xf4, 0x0, 0x3e, 0xff, 0xff, 0xcf, 0xff, - 0xcf, 0xff, 0xf7, 0x3, 0xef, 0xff, 0xf9, 0x8, - 0xf8, 0x9, 0xff, 0xf8, 0x3e, 0xff, 0xff, 0xfe, - 0x20, 0x40, 0x2e, 0xff, 0xf8, 0xdf, 0xff, 0xff, - 0xff, 0xe1, 0x1, 0xef, 0xff, 0xf8, 0x9f, 0xff, - 0xff, 0xff, 0x80, 0x0, 0x8f, 0xff, 0xf8, 0x9, - 0xff, 0xff, 0xf9, 0x2, 0xc2, 0x9, 0xff, 0xf8, - 0x0, 0x9f, 0xff, 0xfe, 0x4e, 0xfe, 0x4e, 0xff, - 0xf8, 0x0, 0x9, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xf7, 0x0, 0x0, 0x8f, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xc1, - - /* U+F7C2 "" */ - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x3, 0xef, - 0xff, 0xff, 0xe2, 0x3, 0xfb, 0xfb, 0xce, 0xbf, - 0xa4, 0xff, 0x1d, 0x3, 0xa1, 0xfa, 0xff, 0xf1, - 0xd0, 0x3a, 0x1f, 0xaf, 0xff, 0xff, 0xff, 0xff, - 0xfa, 0xff, 0xff, 0xff, 0xff, 0xff, 0xaf, 0xff, - 0xff, 0xff, 0xff, 0xfa, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xaf, 0xff, 0xff, 0xff, 0xff, 0xfa, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xaf, 0xff, 0xff, 0xff, - 0xff, 0xfa, 0xff, 0xff, 0xff, 0xff, 0xff, 0xad, - 0xff, 0xff, 0xff, 0xff, 0xf8, 0x29, 0xaa, 0xaa, - 0xaa, 0xa8, 0x0, - - /* U+F8A2 "" */ - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x3, 0x0, - 0x0, 0x0, 0x0, 0x0, 0x0, 0x4, 0xf1, 0x0, - 0x8, 0x20, 0x0, 0x0, 0x1, 0xff, 0x10, 0xb, - 0xf7, 0x0, 0x0, 0x0, 0x2f, 0xf1, 0xc, 0xff, - 0x94, 0x44, 0x44, 0x45, 0xff, 0x1b, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xf1, 0x8f, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xfd, 0x0, 0x7f, 0xf7, 0x0, - 0x0, 0x0, 0x0, 0x0, 0x0, 0x6f, 0x60, 0x0, - 0x0, 0x0, 0x0, 0x0, 0x0, 0x30, 0x0, 0x0, - 0x0, 0x0, 0x0, - - /* U+FF08 "(" */ - 0x0, 0x0, 0x20, 0x0, 0x61, 0x0, 0x81, 0x0, - 0x46, 0x0, 0xb, 0x10, 0x0, 0xc0, 0x0, 0xc, - 0x0, 0x0, 0xb0, 0x0, 0x4, 0x60, 0x0, 0x8, - 0x20, 0x0, 0x6, 0x20, 0x0, 0x1, - - /* U+FF09 ")" */ - 0x30, 0x0, 0x1, 0x70, 0x0, 0x1, 0x90, 0x0, - 0x6, 0x60, 0x0, 0xc, 0x0, 0x0, 0xd0, 0x0, - 0xd, 0x0, 0x0, 0xc0, 0x0, 0x66, 0x0, 0x2a, - 0x0, 0x27, 0x0, 0x2, 0x0, 0x0, - - /* U+FF0C "," */ - 0x1, 0x0, 0xfc, 0x7, 0xb0, 0x63, 0x3, 0x0, - - /* U+FF11 "1" */ - 0x0, 0x23, 0x0, 0x5, 0xd6, 0x0, 0x0, 0x86, - 0x0, 0x0, 0x86, 0x0, 0x0, 0x86, 0x0, 0x0, - 0x86, 0x0, 0x0, 0x86, 0x0, 0x0, 0x86, 0x0, - 0x0, 0x96, 0x0, 0x14, 0x66, 0x40, - - /* U+FF12 "2" */ - 0x0, 0x0, 0x0, 0x7, 0x67, 0x91, 0x87, 0x0, - 0x99, 0x69, 0x0, 0x8b, 0x0, 0x0, 0xd5, 0x0, - 0x6, 0x80, 0x0, 0x39, 0x0, 0x2, 0x90, 0x0, - 0x19, 0x0, 0x3, 0xab, 0xaa, 0xb4, 0x12, 0x22, - 0x20 -}; - -/*--------------------- - * GLYPH DESCRIPTION - *--------------------*/ - -static const lv_font_fmt_txt_glyph_dsc_t glyph_dsc[] = { - {.bitmap_index = 0, .adv_w = 0, .box_w = 0, .box_h = 0, .ofs_x = 0, .ofs_y = 0} /* id = 0 reserved */, - {.bitmap_index = 0, .adv_w = 112, .box_w = 0, .box_h = 0, .ofs_x = 0, .ofs_y = 0}, - {.bitmap_index = 0, .adv_w = 112, .box_w = 3, .box_h = 10, .ofs_x = 2, .ofs_y = 0}, - {.bitmap_index = 15, .adv_w = 112, .box_w = 6, .box_h = 4, .ofs_x = 0, .ofs_y = 8}, - {.bitmap_index = 27, .adv_w = 112, .box_w = 7, .box_h = 10, .ofs_x = 0, .ofs_y = 0}, - {.bitmap_index = 62, .adv_w = 112, .box_w = 6, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 104, .adv_w = 112, .box_w = 7, .box_h = 11, .ofs_x = 0, .ofs_y = 0}, - {.bitmap_index = 143, .adv_w = 112, .box_w = 7, .box_h = 10, .ofs_x = 0, .ofs_y = 0}, - {.bitmap_index = 178, .adv_w = 112, .box_w = 3, .box_h = 4, .ofs_x = 0, .ofs_y = 8}, - {.bitmap_index = 184, .adv_w = 112, .box_w = 4, .box_h = 15, .ofs_x = 3, .ofs_y = -2}, - {.bitmap_index = 214, .adv_w = 112, .box_w = 4, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 244, .adv_w = 112, .box_w = 7, .box_h = 8, .ofs_x = 0, .ofs_y = 2}, - {.bitmap_index = 272, .adv_w = 112, .box_w = 7, .box_h = 9, .ofs_x = 0, .ofs_y = 1}, - {.bitmap_index = 304, .adv_w = 112, .box_w = 3, .box_h = 4, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 310, .adv_w = 112, .box_w = 7, .box_h = 1, .ofs_x = 0, .ofs_y = 5}, - {.bitmap_index = 314, .adv_w = 112, .box_w = 3, .box_h = 2, .ofs_x = 0, .ofs_y = 0}, - {.bitmap_index = 317, .adv_w = 112, .box_w = 7, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 366, .adv_w = 112, .box_w = 7, .box_h = 10, .ofs_x = 0, .ofs_y = 0}, - {.bitmap_index = 401, .adv_w = 112, .box_w = 5, .box_h = 10, .ofs_x = 1, .ofs_y = 0}, - {.bitmap_index = 426, .adv_w = 112, .box_w = 7, .box_h = 10, .ofs_x = 0, .ofs_y = 0}, - {.bitmap_index = 461, .adv_w = 112, .box_w = 7, .box_h = 10, .ofs_x = 0, .ofs_y = 0}, - {.bitmap_index = 496, .adv_w = 112, .box_w = 7, .box_h = 10, .ofs_x = 0, .ofs_y = 0}, - {.bitmap_index = 531, .adv_w = 112, .box_w = 7, .box_h = 10, .ofs_x = 0, .ofs_y = 0}, - {.bitmap_index = 566, .adv_w = 112, .box_w = 7, .box_h = 10, .ofs_x = 0, .ofs_y = 0}, - {.bitmap_index = 601, .adv_w = 112, .box_w = 7, .box_h = 10, .ofs_x = 0, .ofs_y = 0}, - {.bitmap_index = 636, .adv_w = 112, .box_w = 7, .box_h = 10, .ofs_x = 0, .ofs_y = 0}, - {.bitmap_index = 671, .adv_w = 112, .box_w = 7, .box_h = 10, .ofs_x = 0, .ofs_y = 0}, - {.bitmap_index = 706, .adv_w = 112, .box_w = 3, .box_h = 7, .ofs_x = 2, .ofs_y = 0}, - {.bitmap_index = 717, .adv_w = 112, .box_w = 3, .box_h = 9, .ofs_x = 2, .ofs_y = -2}, - {.bitmap_index = 731, .adv_w = 112, .box_w = 7, .box_h = 11, .ofs_x = 0, .ofs_y = 0}, - {.bitmap_index = 770, .adv_w = 112, .box_w = 7, .box_h = 4, .ofs_x = 0, .ofs_y = 3}, - {.bitmap_index = 784, .adv_w = 112, .box_w = 7, .box_h = 11, .ofs_x = 0, .ofs_y = 0}, - {.bitmap_index = 823, .adv_w = 112, .box_w = 7, .box_h = 10, .ofs_x = 0, .ofs_y = 0}, - {.bitmap_index = 858, .adv_w = 112, .box_w = 7, .box_h = 10, .ofs_x = 0, .ofs_y = 0}, - {.bitmap_index = 893, .adv_w = 112, .box_w = 7, .box_h = 10, .ofs_x = 0, .ofs_y = 0}, - {.bitmap_index = 928, .adv_w = 112, .box_w = 7, .box_h = 10, .ofs_x = 0, .ofs_y = 0}, - {.bitmap_index = 963, .adv_w = 112, .box_w = 7, .box_h = 10, .ofs_x = 0, .ofs_y = 0}, - {.bitmap_index = 998, .adv_w = 112, .box_w = 7, .box_h = 10, .ofs_x = 0, .ofs_y = 0}, - {.bitmap_index = 1033, .adv_w = 112, .box_w = 7, .box_h = 10, .ofs_x = 0, .ofs_y = 0}, - {.bitmap_index = 1068, .adv_w = 112, .box_w = 7, .box_h = 10, .ofs_x = 0, .ofs_y = 0}, - {.bitmap_index = 1103, .adv_w = 112, .box_w = 7, .box_h = 10, .ofs_x = 0, .ofs_y = 0}, - {.bitmap_index = 1138, .adv_w = 112, .box_w = 7, .box_h = 10, .ofs_x = 0, .ofs_y = 0}, - {.bitmap_index = 1173, .adv_w = 112, .box_w = 5, .box_h = 10, .ofs_x = 1, .ofs_y = 0}, - {.bitmap_index = 1198, .adv_w = 112, .box_w = 7, .box_h = 12, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 1240, .adv_w = 112, .box_w = 7, .box_h = 10, .ofs_x = 0, .ofs_y = 0}, - {.bitmap_index = 1275, .adv_w = 112, .box_w = 7, .box_h = 10, .ofs_x = 0, .ofs_y = 0}, - {.bitmap_index = 1310, .adv_w = 112, .box_w = 7, .box_h = 10, .ofs_x = 0, .ofs_y = 0}, - {.bitmap_index = 1345, .adv_w = 112, .box_w = 7, .box_h = 10, .ofs_x = 0, .ofs_y = 0}, - {.bitmap_index = 1380, .adv_w = 112, .box_w = 7, .box_h = 10, .ofs_x = 0, .ofs_y = 0}, - {.bitmap_index = 1415, .adv_w = 112, .box_w = 7, .box_h = 10, .ofs_x = 0, .ofs_y = 0}, - {.bitmap_index = 1450, .adv_w = 112, .box_w = 7, .box_h = 11, .ofs_x = 0, .ofs_y = -1}, - {.bitmap_index = 1489, .adv_w = 112, .box_w = 7, .box_h = 10, .ofs_x = 0, .ofs_y = 0}, - {.bitmap_index = 1524, .adv_w = 112, .box_w = 7, .box_h = 10, .ofs_x = 0, .ofs_y = 0}, - {.bitmap_index = 1559, .adv_w = 112, .box_w = 7, .box_h = 10, .ofs_x = 0, .ofs_y = 0}, - {.bitmap_index = 1594, .adv_w = 112, .box_w = 7, .box_h = 10, .ofs_x = 0, .ofs_y = 0}, - {.bitmap_index = 1629, .adv_w = 112, .box_w = 7, .box_h = 10, .ofs_x = 0, .ofs_y = 0}, - {.bitmap_index = 1664, .adv_w = 112, .box_w = 7, .box_h = 10, .ofs_x = 0, .ofs_y = 0}, - {.bitmap_index = 1699, .adv_w = 112, .box_w = 7, .box_h = 10, .ofs_x = 0, .ofs_y = 0}, - {.bitmap_index = 1734, .adv_w = 112, .box_w = 7, .box_h = 10, .ofs_x = 0, .ofs_y = 0}, - {.bitmap_index = 1769, .adv_w = 112, .box_w = 7, .box_h = 10, .ofs_x = 0, .ofs_y = 0}, - {.bitmap_index = 1804, .adv_w = 112, .box_w = 5, .box_h = 14, .ofs_x = 2, .ofs_y = -1}, - {.bitmap_index = 1839, .adv_w = 112, .box_w = 6, .box_h = 13, .ofs_x = 1, .ofs_y = -2}, - {.bitmap_index = 1878, .adv_w = 112, .box_w = 5, .box_h = 14, .ofs_x = 0, .ofs_y = -1}, - {.bitmap_index = 1913, .adv_w = 112, .box_w = 5, .box_h = 2, .ofs_x = 1, .ofs_y = 10}, - {.bitmap_index = 1918, .adv_w = 112, .box_w = 7, .box_h = 1, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 1922, .adv_w = 112, .box_w = 3, .box_h = 2, .ofs_x = 1, .ofs_y = 10}, - {.bitmap_index = 1925, .adv_w = 112, .box_w = 7, .box_h = 7, .ofs_x = 0, .ofs_y = 0}, - {.bitmap_index = 1950, .adv_w = 112, .box_w = 7, .box_h = 11, .ofs_x = 0, .ofs_y = 0}, - {.bitmap_index = 1989, .adv_w = 112, .box_w = 7, .box_h = 7, .ofs_x = 0, .ofs_y = 0}, - {.bitmap_index = 2014, .adv_w = 112, .box_w = 7, .box_h = 11, .ofs_x = 0, .ofs_y = 0}, - {.bitmap_index = 2053, .adv_w = 112, .box_w = 7, .box_h = 7, .ofs_x = 0, .ofs_y = 0}, - {.bitmap_index = 2078, .adv_w = 112, .box_w = 7, .box_h = 10, .ofs_x = 0, .ofs_y = 0}, - {.bitmap_index = 2113, .adv_w = 112, .box_w = 7, .box_h = 9, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 2145, .adv_w = 112, .box_w = 7, .box_h = 11, .ofs_x = 0, .ofs_y = 0}, - {.bitmap_index = 2184, .adv_w = 112, .box_w = 5, .box_h = 10, .ofs_x = 1, .ofs_y = 0}, - {.bitmap_index = 2209, .adv_w = 112, .box_w = 5, .box_h = 12, .ofs_x = 1, .ofs_y = -2}, - {.bitmap_index = 2239, .adv_w = 112, .box_w = 7, .box_h = 11, .ofs_x = 0, .ofs_y = 0}, - {.bitmap_index = 2278, .adv_w = 112, .box_w = 5, .box_h = 11, .ofs_x = 1, .ofs_y = 0}, - {.bitmap_index = 2306, .adv_w = 112, .box_w = 7, .box_h = 7, .ofs_x = 0, .ofs_y = 0}, - {.bitmap_index = 2331, .adv_w = 112, .box_w = 7, .box_h = 7, .ofs_x = 0, .ofs_y = 0}, - {.bitmap_index = 2356, .adv_w = 112, .box_w = 7, .box_h = 7, .ofs_x = 0, .ofs_y = 0}, - {.bitmap_index = 2381, .adv_w = 112, .box_w = 7, .box_h = 9, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 2413, .adv_w = 112, .box_w = 7, .box_h = 9, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 2445, .adv_w = 112, .box_w = 7, .box_h = 7, .ofs_x = 0, .ofs_y = 0}, - {.bitmap_index = 2470, .adv_w = 112, .box_w = 5, .box_h = 7, .ofs_x = 1, .ofs_y = 0}, - {.bitmap_index = 2488, .adv_w = 112, .box_w = 6, .box_h = 9, .ofs_x = 0, .ofs_y = 0}, - {.bitmap_index = 2515, .adv_w = 112, .box_w = 7, .box_h = 7, .ofs_x = 0, .ofs_y = 0}, - {.bitmap_index = 2540, .adv_w = 112, .box_w = 7, .box_h = 7, .ofs_x = 0, .ofs_y = 0}, - {.bitmap_index = 2565, .adv_w = 112, .box_w = 7, .box_h = 7, .ofs_x = 0, .ofs_y = 0}, - {.bitmap_index = 2590, .adv_w = 112, .box_w = 7, .box_h = 7, .ofs_x = 0, .ofs_y = 0}, - {.bitmap_index = 2615, .adv_w = 112, .box_w = 7, .box_h = 9, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 2647, .adv_w = 112, .box_w = 7, .box_h = 7, .ofs_x = 0, .ofs_y = 0}, - {.bitmap_index = 2672, .adv_w = 112, .box_w = 4, .box_h = 14, .ofs_x = 2, .ofs_y = -2}, - {.bitmap_index = 2700, .adv_w = 112, .box_w = 1, .box_h = 15, .ofs_x = 3, .ofs_y = -2}, - {.bitmap_index = 2708, .adv_w = 112, .box_w = 4, .box_h = 14, .ofs_x = 1, .ofs_y = -2}, - {.bitmap_index = 2736, .adv_w = 112, .box_w = 7, .box_h = 3, .ofs_x = 0, .ofs_y = 10}, - {.bitmap_index = 2747, .adv_w = 112, .box_w = 0, .box_h = 0, .ofs_x = 0, .ofs_y = 0}, - {.bitmap_index = 2747, .adv_w = 224, .box_w = 4, .box_h = 5, .ofs_x = 1, .ofs_y = -1}, - {.bitmap_index = 2757, .adv_w = 224, .box_w = 4, .box_h = 5, .ofs_x = 2, .ofs_y = -1}, - {.bitmap_index = 2767, .adv_w = 224, .box_w = 8, .box_h = 11, .ofs_x = 3, .ofs_y = 0}, - {.bitmap_index = 2811, .adv_w = 224, .box_w = 4, .box_h = 12, .ofs_x = 8, .ofs_y = -1}, - {.bitmap_index = 2835, .adv_w = 224, .box_w = 4, .box_h = 12, .ofs_x = 2, .ofs_y = -1}, - {.bitmap_index = 2859, .adv_w = 224, .box_w = 8, .box_h = 9, .ofs_x = 3, .ofs_y = -1}, - {.bitmap_index = 2895, .adv_w = 224, .box_w = 10, .box_h = 12, .ofs_x = 2, .ofs_y = -1}, - {.bitmap_index = 2955, .adv_w = 224, .box_w = 8, .box_h = 7, .ofs_x = 3, .ofs_y = 0}, - {.bitmap_index = 2983, .adv_w = 224, .box_w = 10, .box_h = 9, .ofs_x = 2, .ofs_y = 0}, - {.bitmap_index = 3028, .adv_w = 224, .box_w = 8, .box_h = 12, .ofs_x = 3, .ofs_y = -1}, - {.bitmap_index = 3076, .adv_w = 224, .box_w = 8, .box_h = 9, .ofs_x = 3, .ofs_y = -2}, - {.bitmap_index = 3112, .adv_w = 224, .box_w = 10, .box_h = 12, .ofs_x = 2, .ofs_y = -1}, - {.bitmap_index = 3172, .adv_w = 224, .box_w = 11, .box_h = 12, .ofs_x = 1, .ofs_y = -1}, - {.bitmap_index = 3238, .adv_w = 224, .box_w = 12, .box_h = 11, .ofs_x = 1, .ofs_y = -1}, - {.bitmap_index = 3304, .adv_w = 224, .box_w = 12, .box_h = 11, .ofs_x = 1, .ofs_y = 0}, - {.bitmap_index = 3370, .adv_w = 224, .box_w = 8, .box_h = 12, .ofs_x = 3, .ofs_y = -1}, - {.bitmap_index = 3418, .adv_w = 224, .box_w = 11, .box_h = 12, .ofs_x = 2, .ofs_y = -1}, - {.bitmap_index = 3484, .adv_w = 224, .box_w = 6, .box_h = 12, .ofs_x = 4, .ofs_y = -1}, - {.bitmap_index = 3520, .adv_w = 224, .box_w = 9, .box_h = 12, .ofs_x = 3, .ofs_y = -1}, - {.bitmap_index = 3574, .adv_w = 224, .box_w = 12, .box_h = 12, .ofs_x = 1, .ofs_y = -1}, - {.bitmap_index = 3646, .adv_w = 224, .box_w = 13, .box_h = 13, .ofs_x = 1, .ofs_y = -1}, - {.bitmap_index = 3731, .adv_w = 224, .box_w = 9, .box_h = 10, .ofs_x = 2, .ofs_y = 0}, - {.bitmap_index = 3776, .adv_w = 224, .box_w = 11, .box_h = 11, .ofs_x = 2, .ofs_y = 0}, - {.bitmap_index = 3837, .adv_w = 224, .box_w = 8, .box_h = 11, .ofs_x = 3, .ofs_y = 0}, - {.bitmap_index = 3881, .adv_w = 224, .box_w = 11, .box_h = 13, .ofs_x = 2, .ofs_y = -1}, - {.bitmap_index = 3953, .adv_w = 224, .box_w = 8, .box_h = 12, .ofs_x = 3, .ofs_y = -1}, - {.bitmap_index = 4001, .adv_w = 224, .box_w = 8, .box_h = 12, .ofs_x = 3, .ofs_y = -1}, - {.bitmap_index = 4049, .adv_w = 224, .box_w = 12, .box_h = 12, .ofs_x = 1, .ofs_y = -1}, - {.bitmap_index = 4121, .adv_w = 224, .box_w = 14, .box_h = 12, .ofs_x = 0, .ofs_y = -1}, - {.bitmap_index = 4205, .adv_w = 224, .box_w = 11, .box_h = 10, .ofs_x = 1, .ofs_y = 0}, - {.bitmap_index = 4260, .adv_w = 224, .box_w = 13, .box_h = 11, .ofs_x = 0, .ofs_y = 0}, - {.bitmap_index = 4332, .adv_w = 224, .box_w = 10, .box_h = 12, .ofs_x = 2, .ofs_y = -1}, - {.bitmap_index = 4392, .adv_w = 224, .box_w = 12, .box_h = 12, .ofs_x = 1, .ofs_y = -1}, - {.bitmap_index = 4464, .adv_w = 224, .box_w = 10, .box_h = 12, .ofs_x = 2, .ofs_y = -1}, - {.bitmap_index = 4524, .adv_w = 224, .box_w = 12, .box_h = 11, .ofs_x = 1, .ofs_y = 0}, - {.bitmap_index = 4590, .adv_w = 224, .box_w = 10, .box_h = 11, .ofs_x = 2, .ofs_y = 0}, - {.bitmap_index = 4645, .adv_w = 224, .box_w = 9, .box_h = 7, .ofs_x = 2, .ofs_y = 0}, - {.bitmap_index = 4677, .adv_w = 224, .box_w = 11, .box_h = 9, .ofs_x = 1, .ofs_y = 0}, - {.bitmap_index = 4727, .adv_w = 224, .box_w = 12, .box_h = 10, .ofs_x = 1, .ofs_y = 1}, - {.bitmap_index = 4787, .adv_w = 224, .box_w = 10, .box_h = 10, .ofs_x = 2, .ofs_y = 0}, - {.bitmap_index = 4837, .adv_w = 224, .box_w = 12, .box_h = 11, .ofs_x = 1, .ofs_y = -1}, - {.bitmap_index = 4903, .adv_w = 224, .box_w = 8, .box_h = 12, .ofs_x = 3, .ofs_y = -1}, - {.bitmap_index = 4951, .adv_w = 224, .box_w = 11, .box_h = 11, .ofs_x = 2, .ofs_y = 0}, - {.bitmap_index = 5012, .adv_w = 224, .box_w = 11, .box_h = 12, .ofs_x = 1, .ofs_y = -1}, - {.bitmap_index = 5078, .adv_w = 224, .box_w = 10, .box_h = 9, .ofs_x = 2, .ofs_y = 0}, - {.bitmap_index = 5123, .adv_w = 224, .box_w = 12, .box_h = 10, .ofs_x = 1, .ofs_y = 0}, - {.bitmap_index = 5183, .adv_w = 224, .box_w = 12, .box_h = 12, .ofs_x = 1, .ofs_y = -1}, - {.bitmap_index = 5255, .adv_w = 224, .box_w = 11, .box_h = 11, .ofs_x = 1, .ofs_y = 0}, - {.bitmap_index = 5316, .adv_w = 224, .box_w = 11, .box_h = 12, .ofs_x = 1, .ofs_y = -1}, - {.bitmap_index = 5382, .adv_w = 224, .box_w = 12, .box_h = 12, .ofs_x = 1, .ofs_y = -1}, - {.bitmap_index = 5454, .adv_w = 224, .box_w = 13, .box_h = 11, .ofs_x = 0, .ofs_y = 0}, - {.bitmap_index = 5526, .adv_w = 224, .box_w = 12, .box_h = 11, .ofs_x = 1, .ofs_y = -1}, - {.bitmap_index = 5592, .adv_w = 224, .box_w = 12, .box_h = 12, .ofs_x = 1, .ofs_y = -1}, - {.bitmap_index = 5664, .adv_w = 224, .box_w = 12, .box_h = 12, .ofs_x = 1, .ofs_y = -1}, - {.bitmap_index = 5736, .adv_w = 224, .box_w = 10, .box_h = 10, .ofs_x = 2, .ofs_y = 0}, - {.bitmap_index = 5786, .adv_w = 224, .box_w = 12, .box_h = 10, .ofs_x = 1, .ofs_y = 0}, - {.bitmap_index = 5846, .adv_w = 224, .box_w = 11, .box_h = 10, .ofs_x = 1, .ofs_y = 0}, - {.bitmap_index = 5901, .adv_w = 224, .box_w = 12, .box_h = 8, .ofs_x = 1, .ofs_y = 1}, - {.bitmap_index = 5949, .adv_w = 224, .box_w = 12, .box_h = 9, .ofs_x = 1, .ofs_y = 1}, - {.bitmap_index = 6003, .adv_w = 224, .box_w = 12, .box_h = 9, .ofs_x = 1, .ofs_y = 1}, - {.bitmap_index = 6057, .adv_w = 224, .box_w = 10, .box_h = 11, .ofs_x = 2, .ofs_y = -1}, - {.bitmap_index = 6112, .adv_w = 224, .box_w = 13, .box_h = 11, .ofs_x = 1, .ofs_y = -1}, - {.bitmap_index = 6184, .adv_w = 224, .box_w = 12, .box_h = 11, .ofs_x = 1, .ofs_y = -1}, - {.bitmap_index = 6250, .adv_w = 224, .box_w = 8, .box_h = 12, .ofs_x = 3, .ofs_y = -1}, - {.bitmap_index = 6298, .adv_w = 224, .box_w = 11, .box_h = 11, .ofs_x = 1, .ofs_y = 0}, - {.bitmap_index = 6359, .adv_w = 224, .box_w = 11, .box_h = 11, .ofs_x = 1, .ofs_y = -1}, - {.bitmap_index = 6420, .adv_w = 224, .box_w = 11, .box_h = 11, .ofs_x = 1, .ofs_y = -1}, - {.bitmap_index = 6481, .adv_w = 224, .box_w = 8, .box_h = 12, .ofs_x = 3, .ofs_y = -1}, - {.bitmap_index = 6529, .adv_w = 224, .box_w = 10, .box_h = 9, .ofs_x = 2, .ofs_y = -1}, - {.bitmap_index = 6574, .adv_w = 224, .box_w = 12, .box_h = 11, .ofs_x = 1, .ofs_y = -1}, - {.bitmap_index = 6640, .adv_w = 224, .box_w = 8, .box_h = 8, .ofs_x = 3, .ofs_y = -1}, - {.bitmap_index = 6672, .adv_w = 224, .box_w = 11, .box_h = 11, .ofs_x = 2, .ofs_y = -1}, - {.bitmap_index = 6733, .adv_w = 224, .box_w = 7, .box_h = 8, .ofs_x = 3, .ofs_y = -1}, - {.bitmap_index = 6761, .adv_w = 224, .box_w = 8, .box_h = 10, .ofs_x = 3, .ofs_y = 0}, - {.bitmap_index = 6801, .adv_w = 224, .box_w = 8, .box_h = 12, .ofs_x = 3, .ofs_y = -1}, - {.bitmap_index = 6849, .adv_w = 224, .box_w = 7, .box_h = 12, .ofs_x = 4, .ofs_y = -1}, - {.bitmap_index = 6891, .adv_w = 224, .box_w = 9, .box_h = 11, .ofs_x = 3, .ofs_y = -1}, - {.bitmap_index = 6941, .adv_w = 224, .box_w = 12, .box_h = 12, .ofs_x = 1, .ofs_y = -1}, - {.bitmap_index = 7013, .adv_w = 224, .box_w = 10, .box_h = 11, .ofs_x = 2, .ofs_y = -1}, - {.bitmap_index = 7068, .adv_w = 224, .box_w = 12, .box_h = 12, .ofs_x = 1, .ofs_y = -1}, - {.bitmap_index = 7140, .adv_w = 224, .box_w = 10, .box_h = 12, .ofs_x = 2, .ofs_y = -1}, - {.bitmap_index = 7200, .adv_w = 224, .box_w = 11, .box_h = 11, .ofs_x = 1, .ofs_y = -1}, - {.bitmap_index = 7261, .adv_w = 224, .box_w = 8, .box_h = 9, .ofs_x = 3, .ofs_y = -1}, - {.bitmap_index = 7297, .adv_w = 224, .box_w = 10, .box_h = 12, .ofs_x = 2, .ofs_y = -1}, - {.bitmap_index = 7357, .adv_w = 224, .box_w = 8, .box_h = 10, .ofs_x = 2, .ofs_y = -1}, - {.bitmap_index = 7397, .adv_w = 224, .box_w = 9, .box_h = 12, .ofs_x = 2, .ofs_y = -1}, - {.bitmap_index = 7451, .adv_w = 224, .box_w = 10, .box_h = 12, .ofs_x = 2, .ofs_y = -1}, - {.bitmap_index = 7511, .adv_w = 224, .box_w = 9, .box_h = 6, .ofs_x = 2, .ofs_y = 1}, - {.bitmap_index = 7538, .adv_w = 224, .box_w = 11, .box_h = 8, .ofs_x = 1, .ofs_y = 1}, - {.bitmap_index = 7582, .adv_w = 224, .box_w = 11, .box_h = 12, .ofs_x = 1, .ofs_y = -1}, - {.bitmap_index = 7648, .adv_w = 224, .box_w = 10, .box_h = 11, .ofs_x = 2, .ofs_y = -1}, - {.bitmap_index = 7703, .adv_w = 224, .box_w = 12, .box_h = 12, .ofs_x = 1, .ofs_y = -1}, - {.bitmap_index = 7775, .adv_w = 224, .box_w = 10, .box_h = 12, .ofs_x = 2, .ofs_y = -1}, - {.bitmap_index = 7835, .adv_w = 224, .box_w = 11, .box_h = 12, .ofs_x = 2, .ofs_y = -1}, - {.bitmap_index = 7901, .adv_w = 224, .box_w = 9, .box_h = 12, .ofs_x = 2, .ofs_y = -1}, - {.bitmap_index = 7955, .adv_w = 224, .box_w = 11, .box_h = 12, .ofs_x = 1, .ofs_y = -1}, - {.bitmap_index = 8021, .adv_w = 224, .box_w = 10, .box_h = 11, .ofs_x = 2, .ofs_y = -1}, - {.bitmap_index = 8076, .adv_w = 224, .box_w = 11, .box_h = 12, .ofs_x = 1, .ofs_y = -1}, - {.bitmap_index = 8142, .adv_w = 224, .box_w = 9, .box_h = 8, .ofs_x = 2, .ofs_y = 1}, - {.bitmap_index = 8178, .adv_w = 224, .box_w = 12, .box_h = 10, .ofs_x = 1, .ofs_y = 1}, - {.bitmap_index = 8238, .adv_w = 224, .box_w = 12, .box_h = 11, .ofs_x = 1, .ofs_y = -1}, - {.bitmap_index = 8304, .adv_w = 224, .box_w = 13, .box_h = 12, .ofs_x = 0, .ofs_y = -1}, - {.bitmap_index = 8382, .adv_w = 224, .box_w = 11, .box_h = 10, .ofs_x = 2, .ofs_y = -1}, - {.bitmap_index = 8437, .adv_w = 224, .box_w = 11, .box_h = 11, .ofs_x = 2, .ofs_y = 0}, - {.bitmap_index = 8498, .adv_w = 224, .box_w = 11, .box_h = 10, .ofs_x = 1, .ofs_y = 0}, - {.bitmap_index = 8553, .adv_w = 224, .box_w = 12, .box_h = 11, .ofs_x = 1, .ofs_y = 0}, - {.bitmap_index = 8619, .adv_w = 224, .box_w = 11, .box_h = 10, .ofs_x = 1, .ofs_y = 0}, - {.bitmap_index = 8674, .adv_w = 224, .box_w = 13, .box_h = 11, .ofs_x = 0, .ofs_y = 0}, - {.bitmap_index = 8746, .adv_w = 224, .box_w = 8, .box_h = 11, .ofs_x = 3, .ofs_y = -1}, - {.bitmap_index = 8790, .adv_w = 224, .box_w = 10, .box_h = 12, .ofs_x = 2, .ofs_y = -1}, - {.bitmap_index = 8850, .adv_w = 224, .box_w = 13, .box_h = 13, .ofs_x = 0, .ofs_y = -1}, - {.bitmap_index = 8935, .adv_w = 224, .box_w = 12, .box_h = 11, .ofs_x = 1, .ofs_y = -1}, - {.bitmap_index = 9001, .adv_w = 224, .box_w = 8, .box_h = 8, .ofs_x = 3, .ofs_y = -1}, - {.bitmap_index = 9033, .adv_w = 224, .box_w = 10, .box_h = 11, .ofs_x = 2, .ofs_y = -1}, - {.bitmap_index = 9088, .adv_w = 224, .box_w = 10, .box_h = 11, .ofs_x = 2, .ofs_y = -1}, - {.bitmap_index = 9143, .adv_w = 224, .box_w = 12, .box_h = 12, .ofs_x = 1, .ofs_y = -1}, - {.bitmap_index = 9215, .adv_w = 224, .box_w = 6, .box_h = 11, .ofs_x = 5, .ofs_y = -1}, - {.bitmap_index = 9248, .adv_w = 224, .box_w = 8, .box_h = 11, .ofs_x = 5, .ofs_y = -1}, - {.bitmap_index = 9292, .adv_w = 224, .box_w = 10, .box_h = 11, .ofs_x = 2, .ofs_y = -1}, - {.bitmap_index = 9347, .adv_w = 224, .box_w = 12, .box_h = 7, .ofs_x = 1, .ofs_y = 1}, - {.bitmap_index = 9389, .adv_w = 224, .box_w = 10, .box_h = 12, .ofs_x = 2, .ofs_y = -1}, - {.bitmap_index = 9449, .adv_w = 224, .box_w = 10, .box_h = 10, .ofs_x = 2, .ofs_y = 0}, - {.bitmap_index = 9499, .adv_w = 224, .box_w = 12, .box_h = 7, .ofs_x = 1, .ofs_y = 1}, - {.bitmap_index = 9541, .adv_w = 224, .box_w = 12, .box_h = 10, .ofs_x = 1, .ofs_y = 1}, - {.bitmap_index = 9601, .adv_w = 224, .box_w = 12, .box_h = 10, .ofs_x = 1, .ofs_y = 1}, - {.bitmap_index = 9661, .adv_w = 224, .box_w = 8, .box_h = 10, .ofs_x = 3, .ofs_y = 0}, - {.bitmap_index = 9701, .adv_w = 224, .box_w = 9, .box_h = 10, .ofs_x = 3, .ofs_y = 0}, - {.bitmap_index = 9746, .adv_w = 224, .box_w = 10, .box_h = 10, .ofs_x = 3, .ofs_y = 0}, - {.bitmap_index = 9796, .adv_w = 224, .box_w = 10, .box_h = 10, .ofs_x = 2, .ofs_y = 0}, - {.bitmap_index = 9846, .adv_w = 224, .box_w = 13, .box_h = 12, .ofs_x = 0, .ofs_y = -1}, - {.bitmap_index = 9924, .adv_w = 224, .box_w = 13, .box_h = 12, .ofs_x = 0, .ofs_y = -1}, - {.bitmap_index = 10002, .adv_w = 224, .box_w = 12, .box_h = 9, .ofs_x = 1, .ofs_y = 1}, - {.bitmap_index = 10056, .adv_w = 224, .box_w = 12, .box_h = 10, .ofs_x = 1, .ofs_y = 1}, - {.bitmap_index = 10116, .adv_w = 224, .box_w = 10, .box_h = 10, .ofs_x = 2, .ofs_y = 0}, - {.bitmap_index = 10166, .adv_w = 224, .box_w = 11, .box_h = 12, .ofs_x = 2, .ofs_y = -1}, - {.bitmap_index = 10232, .adv_w = 224, .box_w = 10, .box_h = 11, .ofs_x = 2, .ofs_y = 0}, - {.bitmap_index = 10287, .adv_w = 224, .box_w = 10, .box_h = 8, .ofs_x = 2, .ofs_y = 0}, - {.bitmap_index = 10327, .adv_w = 224, .box_w = 6, .box_h = 11, .ofs_x = 4, .ofs_y = -1}, - {.bitmap_index = 10360, .adv_w = 224, .box_w = 10, .box_h = 10, .ofs_x = 2, .ofs_y = 0}, - {.bitmap_index = 10410, .adv_w = 224, .box_w = 10, .box_h = 11, .ofs_x = 2, .ofs_y = -1}, - {.bitmap_index = 10465, .adv_w = 224, .box_w = 11, .box_h = 9, .ofs_x = 1, .ofs_y = 0}, - {.bitmap_index = 10515, .adv_w = 224, .box_w = 10, .box_h = 8, .ofs_x = 2, .ofs_y = -1}, - {.bitmap_index = 10555, .adv_w = 224, .box_w = 11, .box_h = 11, .ofs_x = 1, .ofs_y = -1}, - {.bitmap_index = 10616, .adv_w = 224, .box_w = 10, .box_h = 6, .ofs_x = 2, .ofs_y = 0}, - {.bitmap_index = 10646, .adv_w = 224, .box_w = 8, .box_h = 7, .ofs_x = 3, .ofs_y = 0}, - {.bitmap_index = 10674, .adv_w = 224, .box_w = 9, .box_h = 10, .ofs_x = 2, .ofs_y = 0}, - {.bitmap_index = 10719, .adv_w = 224, .box_w = 10, .box_h = 11, .ofs_x = 2, .ofs_y = -1}, - {.bitmap_index = 10774, .adv_w = 224, .box_w = 7, .box_h = 11, .ofs_x = 3, .ofs_y = -1}, - {.bitmap_index = 10813, .adv_w = 224, .box_w = 12, .box_h = 9, .ofs_x = 1, .ofs_y = 0}, - {.bitmap_index = 10867, .adv_w = 224, .box_w = 8, .box_h = 9, .ofs_x = 3, .ofs_y = 0}, - {.bitmap_index = 10903, .adv_w = 224, .box_w = 9, .box_h = 8, .ofs_x = 2, .ofs_y = 0}, - {.bitmap_index = 10939, .adv_w = 224, .box_w = 10, .box_h = 11, .ofs_x = 2, .ofs_y = -1}, - {.bitmap_index = 10994, .adv_w = 224, .box_w = 10, .box_h = 9, .ofs_x = 2, .ofs_y = 0}, - {.bitmap_index = 11039, .adv_w = 224, .box_w = 8, .box_h = 8, .ofs_x = 3, .ofs_y = -1}, - {.bitmap_index = 11071, .adv_w = 224, .box_w = 14, .box_h = 3, .ofs_x = 0, .ofs_y = 4}, - {.bitmap_index = 11092, .adv_w = 224, .box_w = 14, .box_h = 2, .ofs_x = 0, .ofs_y = 5}, - {.bitmap_index = 11106, .adv_w = 224, .box_w = 14, .box_h = 13, .ofs_x = 0, .ofs_y = -1}, - {.bitmap_index = 11197, .adv_w = 224, .box_w = 13, .box_h = 13, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 11282, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 11380, .adv_w = 224, .box_w = 14, .box_h = 12, .ofs_x = 0, .ofs_y = -1}, - {.bitmap_index = 11464, .adv_w = 224, .box_w = 14, .box_h = 13, .ofs_x = 0, .ofs_y = -1}, - {.bitmap_index = 11555, .adv_w = 224, .box_w = 13, .box_h = 13, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 11640, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 11738, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 11836, .adv_w = 224, .box_w = 14, .box_h = 12, .ofs_x = 0, .ofs_y = -1}, - {.bitmap_index = 11920, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 12018, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 12116, .adv_w = 224, .box_w = 14, .box_h = 13, .ofs_x = 0, .ofs_y = -1}, - {.bitmap_index = 12207, .adv_w = 224, .box_w = 11, .box_h = 14, .ofs_x = 2, .ofs_y = -2}, - {.bitmap_index = 12284, .adv_w = 224, .box_w = 14, .box_h = 13, .ofs_x = 0, .ofs_y = -1}, - {.bitmap_index = 12375, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 12473, .adv_w = 224, .box_w = 14, .box_h = 13, .ofs_x = 0, .ofs_y = -1}, - {.bitmap_index = 12564, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 12662, .adv_w = 224, .box_w = 13, .box_h = 13, .ofs_x = 1, .ofs_y = -1}, - {.bitmap_index = 12747, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 12845, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 12943, .adv_w = 224, .box_w = 14, .box_h = 13, .ofs_x = 0, .ofs_y = -1}, - {.bitmap_index = 13034, .adv_w = 224, .box_w = 11, .box_h = 14, .ofs_x = 2, .ofs_y = -2}, - {.bitmap_index = 13111, .adv_w = 224, .box_w = 13, .box_h = 13, .ofs_x = 1, .ofs_y = -2}, - {.bitmap_index = 13196, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 13294, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 13392, .adv_w = 224, .box_w = 14, .box_h = 10, .ofs_x = 0, .ofs_y = 0}, - {.bitmap_index = 13462, .adv_w = 224, .box_w = 14, .box_h = 12, .ofs_x = 0, .ofs_y = -1}, - {.bitmap_index = 13546, .adv_w = 224, .box_w = 14, .box_h = 12, .ofs_x = 0, .ofs_y = -1}, - {.bitmap_index = 13630, .adv_w = 224, .box_w = 14, .box_h = 13, .ofs_x = 0, .ofs_y = -1}, - {.bitmap_index = 13721, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 13819, .adv_w = 224, .box_w = 13, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 13910, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 14008, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 14106, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 14204, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 14302, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 14400, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 14498, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 14596, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 14694, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 14792, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 14890, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 14988, .adv_w = 224, .box_w = 12, .box_h = 14, .ofs_x = 1, .ofs_y = -2}, - {.bitmap_index = 15072, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 15170, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 15268, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 15366, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 15464, .adv_w = 224, .box_w = 14, .box_h = 13, .ofs_x = 0, .ofs_y = -1}, - {.bitmap_index = 15555, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 15653, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 15751, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 15849, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 15947, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 16045, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 16143, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 16241, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 16339, .adv_w = 224, .box_w = 13, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 16430, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 16528, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 16626, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 16724, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 16822, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 16920, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 17018, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 17116, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 17214, .adv_w = 224, .box_w = 13, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 17305, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 17403, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 17501, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 17599, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 17697, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 17795, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 17893, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 17991, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 18089, .adv_w = 224, .box_w = 13, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 18180, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 18278, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 18376, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 18474, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 18572, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 18670, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 18768, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 18866, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 18964, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 19062, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 19160, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 19258, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 19356, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 19454, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 19552, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 19650, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 19748, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 19846, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 19944, .adv_w = 224, .box_w = 13, .box_h = 13, .ofs_x = 1, .ofs_y = -2}, - {.bitmap_index = 20029, .adv_w = 224, .box_w = 14, .box_h = 13, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 20120, .adv_w = 224, .box_w = 13, .box_h = 14, .ofs_x = 1, .ofs_y = -2}, - {.bitmap_index = 20211, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 20309, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 20407, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 20505, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 20603, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 20701, .adv_w = 224, .box_w = 13, .box_h = 14, .ofs_x = 1, .ofs_y = -2}, - {.bitmap_index = 20792, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 20890, .adv_w = 224, .box_w = 14, .box_h = 12, .ofs_x = 0, .ofs_y = -1}, - {.bitmap_index = 20974, .adv_w = 224, .box_w = 11, .box_h = 14, .ofs_x = 2, .ofs_y = -2}, - {.bitmap_index = 21051, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 21149, .adv_w = 224, .box_w = 13, .box_h = 14, .ofs_x = 1, .ofs_y = -2}, - {.bitmap_index = 21240, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 21338, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 21436, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 21534, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 21632, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 21730, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 21828, .adv_w = 224, .box_w = 11, .box_h = 14, .ofs_x = 2, .ofs_y = -2}, - {.bitmap_index = 21905, .adv_w = 224, .box_w = 11, .box_h = 13, .ofs_x = 2, .ofs_y = -2}, - {.bitmap_index = 21977, .adv_w = 224, .box_w = 14, .box_h = 13, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 22068, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 22166, .adv_w = 224, .box_w = 13, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 22257, .adv_w = 224, .box_w = 14, .box_h = 13, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 22348, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 22446, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 22544, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 22642, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 22740, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 22838, .adv_w = 224, .box_w = 12, .box_h = 14, .ofs_x = 1, .ofs_y = -2}, - {.bitmap_index = 22922, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 23020, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 23118, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 23216, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 23314, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 23412, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 23510, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 23608, .adv_w = 224, .box_w = 13, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 23699, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 23797, .adv_w = 224, .box_w = 13, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 23888, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 23986, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 24084, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 24182, .adv_w = 224, .box_w = 13, .box_h = 14, .ofs_x = 1, .ofs_y = -2}, - {.bitmap_index = 24273, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 24371, .adv_w = 224, .box_w = 13, .box_h = 14, .ofs_x = 1, .ofs_y = -2}, - {.bitmap_index = 24462, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 24560, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 24658, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 24756, .adv_w = 224, .box_w = 13, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 24847, .adv_w = 224, .box_w = 13, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 24938, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 25036, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 25134, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 25232, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 25330, .adv_w = 224, .box_w = 13, .box_h = 14, .ofs_x = 1, .ofs_y = -2}, - {.bitmap_index = 25421, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 25519, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 25617, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 25715, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 25813, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 25911, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 26009, .adv_w = 224, .box_w = 14, .box_h = 13, .ofs_x = 0, .ofs_y = -1}, - {.bitmap_index = 26100, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 26198, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 26296, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 26394, .adv_w = 224, .box_w = 12, .box_h = 14, .ofs_x = 1, .ofs_y = -2}, - {.bitmap_index = 26478, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 26576, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 26674, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 26772, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 26870, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 26968, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 27066, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 27164, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 27262, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 27360, .adv_w = 224, .box_w = 12, .box_h = 14, .ofs_x = 1, .ofs_y = -2}, - {.bitmap_index = 27444, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 27542, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 27640, .adv_w = 224, .box_w = 13, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 27731, .adv_w = 224, .box_w = 13, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 27822, .adv_w = 224, .box_w = 13, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 27913, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 28011, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 28109, .adv_w = 224, .box_w = 14, .box_h = 13, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 28200, .adv_w = 224, .box_w = 14, .box_h = 13, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 28291, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 28389, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 28487, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 28585, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 28683, .adv_w = 224, .box_w = 11, .box_h = 11, .ofs_x = 2, .ofs_y = -1}, - {.bitmap_index = 28744, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 28842, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 28940, .adv_w = 224, .box_w = 13, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 29031, .adv_w = 224, .box_w = 12, .box_h = 14, .ofs_x = 1, .ofs_y = -2}, - {.bitmap_index = 29115, .adv_w = 224, .box_w = 12, .box_h = 14, .ofs_x = 1, .ofs_y = -2}, - {.bitmap_index = 29199, .adv_w = 224, .box_w = 14, .box_h = 13, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 29290, .adv_w = 224, .box_w = 12, .box_h = 14, .ofs_x = 1, .ofs_y = -2}, - {.bitmap_index = 29374, .adv_w = 224, .box_w = 13, .box_h = 14, .ofs_x = 1, .ofs_y = -2}, - {.bitmap_index = 29465, .adv_w = 224, .box_w = 13, .box_h = 13, .ofs_x = 0, .ofs_y = -1}, - {.bitmap_index = 29550, .adv_w = 224, .box_w = 13, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 29641, .adv_w = 224, .box_w = 12, .box_h = 13, .ofs_x = 1, .ofs_y = -2}, - {.bitmap_index = 29719, .adv_w = 224, .box_w = 13, .box_h = 13, .ofs_x = 1, .ofs_y = -1}, - {.bitmap_index = 29804, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 29902, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 30000, .adv_w = 224, .box_w = 12, .box_h = 14, .ofs_x = 1, .ofs_y = -2}, - {.bitmap_index = 30084, .adv_w = 224, .box_w = 13, .box_h = 13, .ofs_x = 0, .ofs_y = -1}, - {.bitmap_index = 30169, .adv_w = 224, .box_w = 11, .box_h = 14, .ofs_x = 2, .ofs_y = -2}, - {.bitmap_index = 30246, .adv_w = 224, .box_w = 13, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 30337, .adv_w = 224, .box_w = 13, .box_h = 12, .ofs_x = 1, .ofs_y = -1}, - {.bitmap_index = 30415, .adv_w = 224, .box_w = 13, .box_h = 13, .ofs_x = 1, .ofs_y = -2}, - {.bitmap_index = 30500, .adv_w = 224, .box_w = 13, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 30591, .adv_w = 224, .box_w = 12, .box_h = 13, .ofs_x = 1, .ofs_y = -2}, - {.bitmap_index = 30669, .adv_w = 224, .box_w = 13, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 30760, .adv_w = 224, .box_w = 13, .box_h = 14, .ofs_x = 1, .ofs_y = -2}, - {.bitmap_index = 30851, .adv_w = 224, .box_w = 13, .box_h = 14, .ofs_x = 1, .ofs_y = -2}, - {.bitmap_index = 30942, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 31040, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 31138, .adv_w = 224, .box_w = 13, .box_h = 14, .ofs_x = 1, .ofs_y = -2}, - {.bitmap_index = 31229, .adv_w = 224, .box_w = 12, .box_h = 14, .ofs_x = 1, .ofs_y = -2}, - {.bitmap_index = 31313, .adv_w = 224, .box_w = 12, .box_h = 14, .ofs_x = 1, .ofs_y = -2}, - {.bitmap_index = 31397, .adv_w = 224, .box_w = 13, .box_h = 13, .ofs_x = 1, .ofs_y = -2}, - {.bitmap_index = 31482, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 31580, .adv_w = 224, .box_w = 13, .box_h = 13, .ofs_x = 1, .ofs_y = -2}, - {.bitmap_index = 31665, .adv_w = 224, .box_w = 13, .box_h = 14, .ofs_x = 1, .ofs_y = -2}, - {.bitmap_index = 31756, .adv_w = 224, .box_w = 13, .box_h = 14, .ofs_x = 1, .ofs_y = -2}, - {.bitmap_index = 31847, .adv_w = 224, .box_w = 13, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 31938, .adv_w = 224, .box_w = 13, .box_h = 14, .ofs_x = 1, .ofs_y = -2}, - {.bitmap_index = 32029, .adv_w = 224, .box_w = 13, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 32120, .adv_w = 224, .box_w = 13, .box_h = 14, .ofs_x = 1, .ofs_y = -2}, - {.bitmap_index = 32211, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 32309, .adv_w = 224, .box_w = 13, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 32400, .adv_w = 224, .box_w = 13, .box_h = 14, .ofs_x = 1, .ofs_y = -2}, - {.bitmap_index = 32491, .adv_w = 224, .box_w = 13, .box_h = 12, .ofs_x = 1, .ofs_y = -1}, - {.bitmap_index = 32569, .adv_w = 224, .box_w = 13, .box_h = 14, .ofs_x = 1, .ofs_y = -2}, - {.bitmap_index = 32660, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 32758, .adv_w = 224, .box_w = 11, .box_h = 14, .ofs_x = 2, .ofs_y = -2}, - {.bitmap_index = 32835, .adv_w = 224, .box_w = 11, .box_h = 13, .ofs_x = 2, .ofs_y = -2}, - {.bitmap_index = 32907, .adv_w = 224, .box_w = 13, .box_h = 14, .ofs_x = 1, .ofs_y = -2}, - {.bitmap_index = 32998, .adv_w = 224, .box_w = 12, .box_h = 14, .ofs_x = 1, .ofs_y = -2}, - {.bitmap_index = 33082, .adv_w = 224, .box_w = 12, .box_h = 14, .ofs_x = 1, .ofs_y = -2}, - {.bitmap_index = 33166, .adv_w = 224, .box_w = 11, .box_h = 14, .ofs_x = 2, .ofs_y = -2}, - {.bitmap_index = 33243, .adv_w = 224, .box_w = 12, .box_h = 14, .ofs_x = 1, .ofs_y = -2}, - {.bitmap_index = 33327, .adv_w = 224, .box_w = 13, .box_h = 14, .ofs_x = 1, .ofs_y = -2}, - {.bitmap_index = 33418, .adv_w = 224, .box_w = 12, .box_h = 14, .ofs_x = 1, .ofs_y = -2}, - {.bitmap_index = 33502, .adv_w = 224, .box_w = 12, .box_h = 14, .ofs_x = 1, .ofs_y = -2}, - {.bitmap_index = 33586, .adv_w = 224, .box_w = 14, .box_h = 13, .ofs_x = 0, .ofs_y = -1}, - {.bitmap_index = 33677, .adv_w = 224, .box_w = 14, .box_h = 13, .ofs_x = 0, .ofs_y = -1}, - {.bitmap_index = 33768, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 33866, .adv_w = 224, .box_w = 14, .box_h = 13, .ofs_x = 0, .ofs_y = -1}, - {.bitmap_index = 33957, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 34055, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 34153, .adv_w = 224, .box_w = 14, .box_h = 13, .ofs_x = 0, .ofs_y = -1}, - {.bitmap_index = 34244, .adv_w = 224, .box_w = 13, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 34335, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 34433, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 34531, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 34629, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 34727, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 34825, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 34923, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 35021, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 35119, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 35217, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 35315, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 35413, .adv_w = 224, .box_w = 13, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 35504, .adv_w = 224, .box_w = 14, .box_h = 13, .ofs_x = 0, .ofs_y = -1}, - {.bitmap_index = 35595, .adv_w = 224, .box_w = 13, .box_h = 14, .ofs_x = 1, .ofs_y = -2}, - {.bitmap_index = 35686, .adv_w = 224, .box_w = 13, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 35777, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 35875, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 35973, .adv_w = 224, .box_w = 13, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 36064, .adv_w = 224, .box_w = 13, .box_h = 14, .ofs_x = 1, .ofs_y = -2}, - {.bitmap_index = 36155, .adv_w = 224, .box_w = 12, .box_h = 14, .ofs_x = 1, .ofs_y = -2}, - {.bitmap_index = 36239, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 36337, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 36435, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 36533, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 36631, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 36729, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 36827, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 36925, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 37023, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 37121, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 37219, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 37317, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 37415, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 37513, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 37611, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 37709, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 37807, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 37905, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 38003, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 38101, .adv_w = 224, .box_w = 13, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 38192, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 38290, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 38388, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 38486, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 38584, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 38682, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 38780, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 38878, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 38976, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 39074, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 39172, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 39270, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 39368, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 39466, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 39564, .adv_w = 224, .box_w = 13, .box_h = 14, .ofs_x = 1, .ofs_y = -2}, - {.bitmap_index = 39655, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 39753, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 39851, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 39949, .adv_w = 224, .box_w = 14, .box_h = 13, .ofs_x = 0, .ofs_y = -1}, - {.bitmap_index = 40040, .adv_w = 224, .box_w = 14, .box_h = 13, .ofs_x = 0, .ofs_y = -1}, - {.bitmap_index = 40131, .adv_w = 224, .box_w = 13, .box_h = 14, .ofs_x = 1, .ofs_y = -2}, - {.bitmap_index = 40222, .adv_w = 224, .box_w = 13, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 40313, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 40411, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 40509, .adv_w = 224, .box_w = 13, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 40600, .adv_w = 224, .box_w = 13, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 40691, .adv_w = 224, .box_w = 13, .box_h = 14, .ofs_x = 1, .ofs_y = -2}, - {.bitmap_index = 40782, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 40880, .adv_w = 224, .box_w = 13, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 40971, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 41069, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 41167, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 41265, .adv_w = 224, .box_w = 13, .box_h = 14, .ofs_x = 1, .ofs_y = -2}, - {.bitmap_index = 41356, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 41454, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 41552, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 41650, .adv_w = 224, .box_w = 13, .box_h = 14, .ofs_x = 1, .ofs_y = -2}, - {.bitmap_index = 41741, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 41839, .adv_w = 224, .box_w = 12, .box_h = 14, .ofs_x = 1, .ofs_y = -2}, - {.bitmap_index = 41923, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 42021, .adv_w = 224, .box_w = 13, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 42112, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 42210, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 42308, .adv_w = 224, .box_w = 13, .box_h = 14, .ofs_x = 1, .ofs_y = -2}, - {.bitmap_index = 42399, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 42497, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 42595, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 42693, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 42791, .adv_w = 224, .box_w = 13, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 42882, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 42980, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 43078, .adv_w = 224, .box_w = 12, .box_h = 14, .ofs_x = 1, .ofs_y = -2}, - {.bitmap_index = 43162, .adv_w = 224, .box_w = 13, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 43253, .adv_w = 224, .box_w = 12, .box_h = 14, .ofs_x = 2, .ofs_y = -2}, - {.bitmap_index = 43337, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 43435, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 43533, .adv_w = 224, .box_w = 14, .box_h = 13, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 43624, .adv_w = 224, .box_w = 14, .box_h = 13, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 43715, .adv_w = 224, .box_w = 13, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 43806, .adv_w = 224, .box_w = 13, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 43897, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 43995, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 44093, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 44191, .adv_w = 224, .box_w = 13, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 44282, .adv_w = 224, .box_w = 12, .box_h = 13, .ofs_x = 1, .ofs_y = -1}, - {.bitmap_index = 44360, .adv_w = 224, .box_w = 13, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 44451, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 44549, .adv_w = 224, .box_w = 13, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 44640, .adv_w = 224, .box_w = 13, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 44731, .adv_w = 224, .box_w = 14, .box_h = 12, .ofs_x = 0, .ofs_y = -1}, - {.bitmap_index = 44815, .adv_w = 224, .box_w = 13, .box_h = 13, .ofs_x = 0, .ofs_y = -1}, - {.bitmap_index = 44900, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 44998, .adv_w = 224, .box_w = 13, .box_h = 12, .ofs_x = 1, .ofs_y = -1}, - {.bitmap_index = 45076, .adv_w = 224, .box_w = 12, .box_h = 12, .ofs_x = 1, .ofs_y = -1}, - {.bitmap_index = 45148, .adv_w = 224, .box_w = 13, .box_h = 14, .ofs_x = 1, .ofs_y = -2}, - {.bitmap_index = 45239, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 45337, .adv_w = 224, .box_w = 13, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 45428, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 45526, .adv_w = 224, .box_w = 13, .box_h = 14, .ofs_x = 1, .ofs_y = -2}, - {.bitmap_index = 45617, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 45715, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 45813, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 45911, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 46009, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 46107, .adv_w = 224, .box_w = 13, .box_h = 14, .ofs_x = 1, .ofs_y = -2}, - {.bitmap_index = 46198, .adv_w = 224, .box_w = 13, .box_h = 14, .ofs_x = 1, .ofs_y = -2}, - {.bitmap_index = 46289, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 46387, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 46485, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 46583, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 46681, .adv_w = 224, .box_w = 13, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 46772, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 46870, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 46968, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 47066, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 47164, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 47262, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 47360, .adv_w = 224, .box_w = 13, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 47451, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 47549, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 47647, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 47745, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 47843, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 47941, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 48039, .adv_w = 224, .box_w = 11, .box_h = 14, .ofs_x = 1, .ofs_y = -2}, - {.bitmap_index = 48116, .adv_w = 224, .box_w = 13, .box_h = 14, .ofs_x = 1, .ofs_y = -2}, - {.bitmap_index = 48207, .adv_w = 224, .box_w = 13, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 48298, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 48396, .adv_w = 224, .box_w = 13, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 48487, .adv_w = 224, .box_w = 12, .box_h = 14, .ofs_x = 1, .ofs_y = -2}, - {.bitmap_index = 48571, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 48669, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 48767, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 48865, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 48963, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 49061, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 49159, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 49257, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 49355, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 49453, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 49551, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 49649, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 49747, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 49845, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 49943, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 50041, .adv_w = 224, .box_w = 14, .box_h = 12, .ofs_x = 0, .ofs_y = -1}, - {.bitmap_index = 50125, .adv_w = 224, .box_w = 13, .box_h = 13, .ofs_x = 0, .ofs_y = -1}, - {.bitmap_index = 50210, .adv_w = 224, .box_w = 14, .box_h = 13, .ofs_x = 0, .ofs_y = -1}, - {.bitmap_index = 50301, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 50399, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 50497, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 50595, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 50693, .adv_w = 224, .box_w = 14, .box_h = 13, .ofs_x = 0, .ofs_y = -1}, - {.bitmap_index = 50784, .adv_w = 224, .box_w = 13, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 50875, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 50973, .adv_w = 224, .box_w = 14, .box_h = 13, .ofs_x = 0, .ofs_y = -1}, - {.bitmap_index = 51064, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 51162, .adv_w = 224, .box_w = 13, .box_h = 13, .ofs_x = 0, .ofs_y = -1}, - {.bitmap_index = 51247, .adv_w = 224, .box_w = 13, .box_h = 13, .ofs_x = 0, .ofs_y = -1}, - {.bitmap_index = 51332, .adv_w = 224, .box_w = 13, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 51423, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 51521, .adv_w = 224, .box_w = 13, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 51612, .adv_w = 224, .box_w = 14, .box_h = 13, .ofs_x = 0, .ofs_y = -1}, - {.bitmap_index = 51703, .adv_w = 224, .box_w = 13, .box_h = 13, .ofs_x = 1, .ofs_y = -1}, - {.bitmap_index = 51788, .adv_w = 224, .box_w = 14, .box_h = 13, .ofs_x = 0, .ofs_y = -1}, - {.bitmap_index = 51879, .adv_w = 224, .box_w = 12, .box_h = 13, .ofs_x = 1, .ofs_y = -1}, - {.bitmap_index = 51957, .adv_w = 224, .box_w = 12, .box_h = 14, .ofs_x = 1, .ofs_y = -2}, - {.bitmap_index = 52041, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 52139, .adv_w = 224, .box_w = 13, .box_h = 13, .ofs_x = 1, .ofs_y = -1}, - {.bitmap_index = 52224, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 52322, .adv_w = 224, .box_w = 13, .box_h = 13, .ofs_x = 1, .ofs_y = -1}, - {.bitmap_index = 52407, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 52505, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 52603, .adv_w = 224, .box_w = 14, .box_h = 13, .ofs_x = 0, .ofs_y = -1}, - {.bitmap_index = 52694, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 52792, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 52890, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 52988, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 53086, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 53184, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 53282, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 53380, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 53478, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 53576, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 53674, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 53772, .adv_w = 224, .box_w = 13, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 53863, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 53961, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 54059, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 54157, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 54255, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 54353, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 54451, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 54549, .adv_w = 224, .box_w = 13, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 54640, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 54738, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 54836, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 54934, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 55032, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 55130, .adv_w = 224, .box_w = 13, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 55221, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 55319, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 55417, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 55515, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 55613, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 55711, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 55809, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 55907, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 56005, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 56103, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 56201, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 56299, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 56397, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 56495, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 56593, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 56691, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 56789, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 56887, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 56985, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 57083, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 57181, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 57279, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 57377, .adv_w = 224, .box_w = 13, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 57468, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 57566, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 57664, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 57762, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 57860, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 57958, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 58056, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 58154, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 58252, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 58350, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 58448, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 58546, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 58644, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 58742, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 58840, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 58938, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 59036, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 59134, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 59232, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 59330, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 59428, .adv_w = 224, .box_w = 13, .box_h = 14, .ofs_x = 1, .ofs_y = -2}, - {.bitmap_index = 59519, .adv_w = 224, .box_w = 9, .box_h = 13, .ofs_x = 3, .ofs_y = -2}, - {.bitmap_index = 59578, .adv_w = 224, .box_w = 13, .box_h = 12, .ofs_x = 0, .ofs_y = -1}, - {.bitmap_index = 59656, .adv_w = 224, .box_w = 13, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 59747, .adv_w = 224, .box_w = 13, .box_h = 14, .ofs_x = 1, .ofs_y = -2}, - {.bitmap_index = 59838, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 59936, .adv_w = 224, .box_w = 11, .box_h = 14, .ofs_x = 2, .ofs_y = -2}, - {.bitmap_index = 60013, .adv_w = 224, .box_w = 12, .box_h = 14, .ofs_x = 1, .ofs_y = -2}, - {.bitmap_index = 60097, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 60195, .adv_w = 224, .box_w = 14, .box_h = 13, .ofs_x = 0, .ofs_y = -1}, - {.bitmap_index = 60286, .adv_w = 224, .box_w = 13, .box_h = 14, .ofs_x = 1, .ofs_y = -2}, - {.bitmap_index = 60377, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 60475, .adv_w = 224, .box_w = 13, .box_h = 14, .ofs_x = 1, .ofs_y = -2}, - {.bitmap_index = 60566, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 60664, .adv_w = 224, .box_w = 14, .box_h = 12, .ofs_x = 0, .ofs_y = -1}, - {.bitmap_index = 60748, .adv_w = 224, .box_w = 13, .box_h = 14, .ofs_x = 1, .ofs_y = -2}, - {.bitmap_index = 60839, .adv_w = 224, .box_w = 13, .box_h = 14, .ofs_x = 1, .ofs_y = -2}, - {.bitmap_index = 60930, .adv_w = 224, .box_w = 13, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 61021, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 61119, .adv_w = 224, .box_w = 13, .box_h = 14, .ofs_x = 1, .ofs_y = -2}, - {.bitmap_index = 61210, .adv_w = 224, .box_w = 12, .box_h = 14, .ofs_x = 1, .ofs_y = -2}, - {.bitmap_index = 61294, .adv_w = 224, .box_w = 13, .box_h = 13, .ofs_x = 1, .ofs_y = -2}, - {.bitmap_index = 61379, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 61477, .adv_w = 224, .box_w = 13, .box_h = 14, .ofs_x = 1, .ofs_y = -2}, - {.bitmap_index = 61568, .adv_w = 224, .box_w = 13, .box_h = 14, .ofs_x = 1, .ofs_y = -2}, - {.bitmap_index = 61659, .adv_w = 224, .box_w = 13, .box_h = 14, .ofs_x = 1, .ofs_y = -2}, - {.bitmap_index = 61750, .adv_w = 224, .box_w = 13, .box_h = 14, .ofs_x = 1, .ofs_y = -2}, - {.bitmap_index = 61841, .adv_w = 224, .box_w = 11, .box_h = 14, .ofs_x = 2, .ofs_y = -2}, - {.bitmap_index = 61918, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 62016, .adv_w = 224, .box_w = 13, .box_h = 14, .ofs_x = 1, .ofs_y = -2}, - {.bitmap_index = 62107, .adv_w = 224, .box_w = 10, .box_h = 14, .ofs_x = 2, .ofs_y = -2}, - {.bitmap_index = 62177, .adv_w = 224, .box_w = 12, .box_h = 14, .ofs_x = 1, .ofs_y = -2}, - {.bitmap_index = 62261, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 62359, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 62457, .adv_w = 224, .box_w = 11, .box_h = 14, .ofs_x = 1, .ofs_y = -2}, - {.bitmap_index = 62534, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 62632, .adv_w = 224, .box_w = 13, .box_h = 13, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 62717, .adv_w = 224, .box_w = 14, .box_h = 13, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 62808, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 62906, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 63004, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 63102, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 63200, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 63298, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 63396, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 63494, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 63592, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 63690, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 63788, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 63886, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 63984, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 64082, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 64180, .adv_w = 224, .box_w = 13, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 64271, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 64369, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 64467, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 64565, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 64663, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 64761, .adv_w = 224, .box_w = 13, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 64852, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 64950, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 65048, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 65146, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 65244, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 65342, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 65440, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 65538, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 65636, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 65734, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 65832, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 65930, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 66028, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 66126, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 66224, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 66322, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 66420, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 66518, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 66616, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 66714, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 66812, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 66910, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 67008, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 67106, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 67204, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 67302, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 67400, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 67498, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 67596, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 67694, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 67792, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 67890, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 67988, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 68086, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 68184, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 68282, .adv_w = 224, .box_w = 14, .box_h = 13, .ofs_x = 0, .ofs_y = -1}, - {.bitmap_index = 68373, .adv_w = 224, .box_w = 14, .box_h = 13, .ofs_x = 0, .ofs_y = -1}, - {.bitmap_index = 68464, .adv_w = 224, .box_w = 14, .box_h = 13, .ofs_x = 0, .ofs_y = -1}, - {.bitmap_index = 68555, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 68653, .adv_w = 224, .box_w = 13, .box_h = 14, .ofs_x = 1, .ofs_y = -2}, - {.bitmap_index = 68744, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 68842, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 68940, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 69038, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 69136, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 69234, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 69332, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 69430, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 69528, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 69626, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 69724, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 69822, .adv_w = 224, .box_w = 12, .box_h = 13, .ofs_x = 2, .ofs_y = -1}, - {.bitmap_index = 69900, .adv_w = 224, .box_w = 14, .box_h = 12, .ofs_x = 0, .ofs_y = -1}, - {.bitmap_index = 69984, .adv_w = 224, .box_w = 12, .box_h = 14, .ofs_x = 2, .ofs_y = -2}, - {.bitmap_index = 70068, .adv_w = 224, .box_w = 13, .box_h = 14, .ofs_x = 1, .ofs_y = -2}, - {.bitmap_index = 70159, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 70257, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 70355, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 70453, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 70551, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 70649, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 70747, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 70845, .adv_w = 224, .box_w = 14, .box_h = 13, .ofs_x = 0, .ofs_y = -1}, - {.bitmap_index = 70936, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 71034, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 71132, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 71230, .adv_w = 224, .box_w = 13, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 71321, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 71419, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 71517, .adv_w = 224, .box_w = 13, .box_h = 14, .ofs_x = 1, .ofs_y = -2}, - {.bitmap_index = 71608, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 71706, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 71804, .adv_w = 224, .box_w = 14, .box_h = 13, .ofs_x = 0, .ofs_y = -1}, - {.bitmap_index = 71895, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 71993, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 72091, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 72189, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 72287, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 72385, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 72483, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 72581, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 72679, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 72777, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 72875, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 72973, .adv_w = 224, .box_w = 13, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 73064, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 73162, .adv_w = 224, .box_w = 14, .box_h = 13, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 73253, .adv_w = 224, .box_w = 14, .box_h = 13, .ofs_x = 0, .ofs_y = -1}, - {.bitmap_index = 73344, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 73442, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 73540, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 73638, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 73736, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 73834, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 73932, .adv_w = 224, .box_w = 14, .box_h = 13, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 74023, .adv_w = 224, .box_w = 14, .box_h = 13, .ofs_x = 0, .ofs_y = -1}, - {.bitmap_index = 74114, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 74212, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 74310, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 74408, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 74506, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 74604, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 74702, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 74800, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 74898, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 74996, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 75094, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 75192, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 75290, .adv_w = 224, .box_w = 13, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 75381, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 75479, .adv_w = 224, .box_w = 13, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 75570, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 75668, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 75766, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 75864, .adv_w = 224, .box_w = 13, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 75955, .adv_w = 224, .box_w = 13, .box_h = 14, .ofs_x = 1, .ofs_y = -2}, - {.bitmap_index = 76046, .adv_w = 224, .box_w = 14, .box_h = 13, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 76137, .adv_w = 224, .box_w = 14, .box_h = 13, .ofs_x = 0, .ofs_y = -1}, - {.bitmap_index = 76228, .adv_w = 224, .box_w = 13, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 76319, .adv_w = 224, .box_w = 13, .box_h = 14, .ofs_x = 1, .ofs_y = -2}, - {.bitmap_index = 76410, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 76508, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 76606, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 76704, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 76802, .adv_w = 224, .box_w = 14, .box_h = 13, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 76893, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 76991, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 77089, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 77187, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 77285, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 77383, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 77481, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 77579, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 77677, .adv_w = 224, .box_w = 14, .box_h = 13, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 77768, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 77866, .adv_w = 224, .box_w = 14, .box_h = 12, .ofs_x = 0, .ofs_y = -1}, - {.bitmap_index = 77950, .adv_w = 224, .box_w = 14, .box_h = 13, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 78041, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 78139, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 78237, .adv_w = 224, .box_w = 14, .box_h = 13, .ofs_x = 0, .ofs_y = -1}, - {.bitmap_index = 78328, .adv_w = 224, .box_w = 13, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 78419, .adv_w = 224, .box_w = 13, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 78510, .adv_w = 224, .box_w = 13, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 78601, .adv_w = 224, .box_w = 10, .box_h = 12, .ofs_x = 2, .ofs_y = -1}, - {.bitmap_index = 78661, .adv_w = 224, .box_w = 11, .box_h = 14, .ofs_x = 2, .ofs_y = -2}, - {.bitmap_index = 78738, .adv_w = 224, .box_w = 10, .box_h = 14, .ofs_x = 2, .ofs_y = -2}, - {.bitmap_index = 78808, .adv_w = 224, .box_w = 12, .box_h = 13, .ofs_x = 2, .ofs_y = -1}, - {.bitmap_index = 78886, .adv_w = 224, .box_w = 12, .box_h = 14, .ofs_x = 1, .ofs_y = -2}, - {.bitmap_index = 78970, .adv_w = 224, .box_w = 13, .box_h = 13, .ofs_x = 1, .ofs_y = -2}, - {.bitmap_index = 79055, .adv_w = 224, .box_w = 13, .box_h = 13, .ofs_x = 1, .ofs_y = -1}, - {.bitmap_index = 79140, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 79238, .adv_w = 224, .box_w = 13, .box_h = 14, .ofs_x = 1, .ofs_y = -2}, - {.bitmap_index = 79329, .adv_w = 224, .box_w = 13, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 79420, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 79518, .adv_w = 224, .box_w = 13, .box_h = 14, .ofs_x = 1, .ofs_y = -2}, - {.bitmap_index = 79609, .adv_w = 224, .box_w = 13, .box_h = 14, .ofs_x = 1, .ofs_y = -2}, - {.bitmap_index = 79700, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 79798, .adv_w = 224, .box_w = 13, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 79889, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 79987, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 80085, .adv_w = 224, .box_w = 13, .box_h = 14, .ofs_x = 1, .ofs_y = -2}, - {.bitmap_index = 80176, .adv_w = 224, .box_w = 11, .box_h = 14, .ofs_x = 2, .ofs_y = -2}, - {.bitmap_index = 80253, .adv_w = 224, .box_w = 13, .box_h = 14, .ofs_x = 1, .ofs_y = -2}, - {.bitmap_index = 80344, .adv_w = 224, .box_w = 13, .box_h = 14, .ofs_x = 1, .ofs_y = -2}, - {.bitmap_index = 80435, .adv_w = 224, .box_w = 12, .box_h = 14, .ofs_x = 2, .ofs_y = -2}, - {.bitmap_index = 80519, .adv_w = 224, .box_w = 14, .box_h = 10, .ofs_x = 0, .ofs_y = 0}, - {.bitmap_index = 80589, .adv_w = 224, .box_w = 13, .box_h = 14, .ofs_x = 1, .ofs_y = -2}, - {.bitmap_index = 80680, .adv_w = 224, .box_w = 9, .box_h = 13, .ofs_x = 3, .ofs_y = -2}, - {.bitmap_index = 80739, .adv_w = 224, .box_w = 14, .box_h = 13, .ofs_x = 0, .ofs_y = -1}, - {.bitmap_index = 80830, .adv_w = 224, .box_w = 13, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 80921, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 81019, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 81117, .adv_w = 224, .box_w = 13, .box_h = 14, .ofs_x = 1, .ofs_y = -2}, - {.bitmap_index = 81208, .adv_w = 224, .box_w = 12, .box_h = 14, .ofs_x = 1, .ofs_y = -2}, - {.bitmap_index = 81292, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 81390, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 81488, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 81586, .adv_w = 224, .box_w = 14, .box_h = 13, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 81677, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 81775, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 81873, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 81971, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 82069, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 82167, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 82265, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 82363, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 82461, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 82559, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 82657, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 82755, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 82853, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 82951, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 83049, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 83147, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 83245, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 83343, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 83441, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 83539, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 83637, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 83735, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 83833, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 83931, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 84029, .adv_w = 224, .box_w = 14, .box_h = 13, .ofs_x = 0, .ofs_y = -1}, - {.bitmap_index = 84120, .adv_w = 224, .box_w = 14, .box_h = 13, .ofs_x = 0, .ofs_y = -1}, - {.bitmap_index = 84211, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 84309, .adv_w = 224, .box_w = 13, .box_h = 13, .ofs_x = 0, .ofs_y = -1}, - {.bitmap_index = 84394, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 84492, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 84590, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 84688, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 84786, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 84884, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 84982, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 85080, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 85178, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 85276, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 85374, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 85472, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 85570, .adv_w = 224, .box_w = 13, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 85661, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 85759, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 85857, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 85955, .adv_w = 224, .box_w = 13, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 86046, .adv_w = 224, .box_w = 14, .box_h = 13, .ofs_x = 0, .ofs_y = -1}, - {.bitmap_index = 86137, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 86235, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 86333, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 86431, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 86529, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 86627, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 86725, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 86823, .adv_w = 224, .box_w = 14, .box_h = 13, .ofs_x = 0, .ofs_y = -1}, - {.bitmap_index = 86914, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 87012, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 87110, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 87208, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 87306, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 87404, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 87502, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 87600, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 87698, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 87796, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 87894, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 87992, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 88090, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 88188, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 88286, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 88384, .adv_w = 224, .box_w = 14, .box_h = 13, .ofs_x = 0, .ofs_y = -1}, - {.bitmap_index = 88475, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 88573, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 88671, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 88769, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 88867, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 88965, .adv_w = 224, .box_w = 13, .box_h = 14, .ofs_x = 1, .ofs_y = -2}, - {.bitmap_index = 89056, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 89154, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 89252, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 89350, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 89448, .adv_w = 224, .box_w = 12, .box_h = 14, .ofs_x = 1, .ofs_y = -2}, - {.bitmap_index = 89532, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 89630, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 89728, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 89826, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 89924, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 90022, .adv_w = 224, .box_w = 12, .box_h = 14, .ofs_x = 1, .ofs_y = -2}, - {.bitmap_index = 90106, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 90204, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 90302, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 90400, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 90498, .adv_w = 224, .box_w = 11, .box_h = 14, .ofs_x = 2, .ofs_y = -2}, - {.bitmap_index = 90575, .adv_w = 224, .box_w = 13, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 90666, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 90764, .adv_w = 224, .box_w = 13, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 90855, .adv_w = 224, .box_w = 13, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 90946, .adv_w = 224, .box_w = 13, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 91037, .adv_w = 224, .box_w = 13, .box_h = 14, .ofs_x = 1, .ofs_y = -2}, - {.bitmap_index = 91128, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 91226, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 91324, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 91422, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 91520, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 91618, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 91716, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 91814, .adv_w = 224, .box_w = 9, .box_h = 14, .ofs_x = 3, .ofs_y = -2}, - {.bitmap_index = 91877, .adv_w = 224, .box_w = 14, .box_h = 13, .ofs_x = 0, .ofs_y = -1}, - {.bitmap_index = 91968, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 92066, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 92164, .adv_w = 224, .box_w = 14, .box_h = 13, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 92255, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 92353, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 92451, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 92549, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 92647, .adv_w = 224, .box_w = 11, .box_h = 14, .ofs_x = 2, .ofs_y = -2}, - {.bitmap_index = 92724, .adv_w = 224, .box_w = 14, .box_h = 13, .ofs_x = 0, .ofs_y = -1}, - {.bitmap_index = 92815, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 92913, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 93011, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 93109, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 93207, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 93305, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 93403, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 93501, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 93599, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 93697, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 93795, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 93893, .adv_w = 224, .box_w = 13, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 93984, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 94082, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 94180, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 94278, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 94376, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 94474, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 94572, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 94670, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 94768, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 94866, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 94964, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 95062, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 95160, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 95258, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 95356, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 95454, .adv_w = 224, .box_w = 13, .box_h = 13, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 95539, .adv_w = 224, .box_w = 13, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 95630, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 95728, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 95826, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 95924, .adv_w = 224, .box_w = 13, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 96015, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 96113, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 96211, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 96309, .adv_w = 224, .box_w = 13, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 96400, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 96498, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 96596, .adv_w = 224, .box_w = 13, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 96687, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 96785, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 96883, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 96981, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 97079, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 97177, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 97275, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 97373, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 97471, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 97569, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 97667, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 97765, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 97863, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 97961, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 98059, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 98157, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 98255, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 98353, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 98451, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 98549, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 98647, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 98745, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 98843, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 98941, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 99039, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 99137, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 99235, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 99333, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 99431, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 99529, .adv_w = 224, .box_w = 14, .box_h = 13, .ofs_x = 0, .ofs_y = -1}, - {.bitmap_index = 99620, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 99718, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 99816, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 99914, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 100012, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 100110, .adv_w = 224, .box_w = 14, .box_h = 13, .ofs_x = 0, .ofs_y = -1}, - {.bitmap_index = 100201, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 100299, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 100397, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 100495, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 100593, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 100691, .adv_w = 224, .box_w = 13, .box_h = 14, .ofs_x = 1, .ofs_y = -2}, - {.bitmap_index = 100782, .adv_w = 224, .box_w = 12, .box_h = 14, .ofs_x = 1, .ofs_y = -2}, - {.bitmap_index = 100866, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 100964, .adv_w = 224, .box_w = 13, .box_h = 14, .ofs_x = 1, .ofs_y = -2}, - {.bitmap_index = 101055, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 101153, .adv_w = 224, .box_w = 13, .box_h = 14, .ofs_x = 1, .ofs_y = -2}, - {.bitmap_index = 101244, .adv_w = 224, .box_w = 12, .box_h = 14, .ofs_x = 1, .ofs_y = -2}, - {.bitmap_index = 101328, .adv_w = 224, .box_w = 13, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 101419, .adv_w = 224, .box_w = 12, .box_h = 14, .ofs_x = 1, .ofs_y = -2}, - {.bitmap_index = 101503, .adv_w = 224, .box_w = 12, .box_h = 14, .ofs_x = 1, .ofs_y = -2}, - {.bitmap_index = 101587, .adv_w = 224, .box_w = 12, .box_h = 14, .ofs_x = 1, .ofs_y = -2}, - {.bitmap_index = 101671, .adv_w = 224, .box_w = 12, .box_h = 14, .ofs_x = 1, .ofs_y = -2}, - {.bitmap_index = 101755, .adv_w = 224, .box_w = 13, .box_h = 14, .ofs_x = 1, .ofs_y = -2}, - {.bitmap_index = 101846, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 101944, .adv_w = 224, .box_w = 13, .box_h = 14, .ofs_x = 1, .ofs_y = -2}, - {.bitmap_index = 102035, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 102133, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 102231, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 102329, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 102427, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 102525, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 102623, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 102721, .adv_w = 224, .box_w = 14, .box_h = 12, .ofs_x = 0, .ofs_y = -1}, - {.bitmap_index = 102805, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 102903, .adv_w = 224, .box_w = 13, .box_h = 14, .ofs_x = 1, .ofs_y = -2}, - {.bitmap_index = 102994, .adv_w = 224, .box_w = 15, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 103099, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 103197, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 103295, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 103393, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 103491, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 103589, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 103687, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 103785, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 103883, .adv_w = 224, .box_w = 13, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 103974, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 104072, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 104170, .adv_w = 224, .box_w = 13, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 104261, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 104359, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 104457, .adv_w = 224, .box_w = 14, .box_h = 13, .ofs_x = 0, .ofs_y = -1}, - {.bitmap_index = 104548, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 104646, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 104744, .adv_w = 224, .box_w = 14, .box_h = 13, .ofs_x = 0, .ofs_y = -1}, - {.bitmap_index = 104835, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 104933, .adv_w = 224, .box_w = 14, .box_h = 12, .ofs_x = 0, .ofs_y = -1}, - {.bitmap_index = 105017, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 105115, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 105213, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 105311, .adv_w = 224, .box_w = 14, .box_h = 13, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 105402, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 105500, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 105598, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 105696, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 105794, .adv_w = 224, .box_w = 14, .box_h = 13, .ofs_x = 0, .ofs_y = -1}, - {.bitmap_index = 105885, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 105983, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 106081, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 106179, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 106277, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 106375, .adv_w = 224, .box_w = 14, .box_h = 13, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 106466, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 106564, .adv_w = 224, .box_w = 14, .box_h = 13, .ofs_x = 0, .ofs_y = -1}, - {.bitmap_index = 106655, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 106753, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 106851, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 106949, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 107047, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 107145, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 107243, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 107341, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 107439, .adv_w = 224, .box_w = 14, .box_h = 13, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 107530, .adv_w = 224, .box_w = 13, .box_h = 13, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 107615, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 107713, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 107811, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 107909, .adv_w = 224, .box_w = 14, .box_h = 13, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 108000, .adv_w = 224, .box_w = 14, .box_h = 13, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 108091, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 108189, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 108287, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 108385, .adv_w = 224, .box_w = 14, .box_h = 13, .ofs_x = 0, .ofs_y = -1}, - {.bitmap_index = 108476, .adv_w = 224, .box_w = 13, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 108567, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 108665, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 108763, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 108861, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 108959, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 109057, .adv_w = 224, .box_w = 14, .box_h = 13, .ofs_x = 0, .ofs_y = -1}, - {.bitmap_index = 109148, .adv_w = 224, .box_w = 14, .box_h = 13, .ofs_x = 0, .ofs_y = -1}, - {.bitmap_index = 109239, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 109337, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 109435, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 109533, .adv_w = 224, .box_w = 12, .box_h = 14, .ofs_x = 1, .ofs_y = -2}, - {.bitmap_index = 109617, .adv_w = 224, .box_w = 12, .box_h = 14, .ofs_x = 1, .ofs_y = -2}, - {.bitmap_index = 109701, .adv_w = 224, .box_w = 12, .box_h = 14, .ofs_x = 1, .ofs_y = -2}, - {.bitmap_index = 109785, .adv_w = 224, .box_w = 13, .box_h = 14, .ofs_x = 1, .ofs_y = -2}, - {.bitmap_index = 109876, .adv_w = 224, .box_w = 13, .box_h = 14, .ofs_x = 1, .ofs_y = -2}, - {.bitmap_index = 109967, .adv_w = 224, .box_w = 13, .box_h = 14, .ofs_x = 1, .ofs_y = -2}, - {.bitmap_index = 110058, .adv_w = 224, .box_w = 12, .box_h = 13, .ofs_x = 1, .ofs_y = -2}, - {.bitmap_index = 110136, .adv_w = 224, .box_w = 13, .box_h = 14, .ofs_x = 1, .ofs_y = -2}, - {.bitmap_index = 110227, .adv_w = 224, .box_w = 13, .box_h = 14, .ofs_x = 1, .ofs_y = -2}, - {.bitmap_index = 110318, .adv_w = 224, .box_w = 13, .box_h = 13, .ofs_x = 1, .ofs_y = -2}, - {.bitmap_index = 110403, .adv_w = 224, .box_w = 12, .box_h = 14, .ofs_x = 1, .ofs_y = -2}, - {.bitmap_index = 110487, .adv_w = 224, .box_w = 13, .box_h = 14, .ofs_x = 1, .ofs_y = -2}, - {.bitmap_index = 110578, .adv_w = 224, .box_w = 13, .box_h = 14, .ofs_x = 1, .ofs_y = -2}, - {.bitmap_index = 110669, .adv_w = 224, .box_w = 13, .box_h = 14, .ofs_x = 1, .ofs_y = -2}, - {.bitmap_index = 110760, .adv_w = 224, .box_w = 13, .box_h = 14, .ofs_x = 1, .ofs_y = -2}, - {.bitmap_index = 110851, .adv_w = 224, .box_w = 13, .box_h = 14, .ofs_x = 1, .ofs_y = -2}, - {.bitmap_index = 110942, .adv_w = 224, .box_w = 13, .box_h = 14, .ofs_x = 1, .ofs_y = -2}, - {.bitmap_index = 111033, .adv_w = 224, .box_w = 13, .box_h = 14, .ofs_x = 1, .ofs_y = -2}, - {.bitmap_index = 111124, .adv_w = 224, .box_w = 13, .box_h = 14, .ofs_x = 1, .ofs_y = -2}, - {.bitmap_index = 111215, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 111313, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 111411, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 111509, .adv_w = 224, .box_w = 14, .box_h = 13, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 111600, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 111698, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 111796, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 111894, .adv_w = 224, .box_w = 12, .box_h = 13, .ofs_x = 1, .ofs_y = -2}, - {.bitmap_index = 111972, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 112070, .adv_w = 224, .box_w = 13, .box_h = 14, .ofs_x = 1, .ofs_y = -2}, - {.bitmap_index = 112161, .adv_w = 224, .box_w = 13, .box_h = 13, .ofs_x = 1, .ofs_y = -1}, - {.bitmap_index = 112246, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 112344, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 112442, .adv_w = 224, .box_w = 13, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 112533, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 112631, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 112729, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 112827, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 112925, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 113023, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 113121, .adv_w = 224, .box_w = 13, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 113212, .adv_w = 224, .box_w = 13, .box_h = 14, .ofs_x = 1, .ofs_y = -2}, - {.bitmap_index = 113303, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 113401, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 113499, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 113597, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 113695, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 113793, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 113891, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 113989, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 114087, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 114185, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 114283, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 114381, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 114479, .adv_w = 224, .box_w = 14, .box_h = 13, .ofs_x = 0, .ofs_y = -1}, - {.bitmap_index = 114570, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 114668, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 114766, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 114864, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 114962, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 115060, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 115158, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 115256, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 115354, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 115452, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 115550, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 115648, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 115746, .adv_w = 224, .box_w = 13, .box_h = 14, .ofs_x = 1, .ofs_y = -2}, - {.bitmap_index = 115837, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 115935, .adv_w = 224, .box_w = 13, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 116026, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 116124, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 116222, .adv_w = 224, .box_w = 13, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 116313, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 116411, .adv_w = 224, .box_w = 13, .box_h = 13, .ofs_x = 1, .ofs_y = -2}, - {.bitmap_index = 116496, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 116594, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 116692, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 116790, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 116888, .adv_w = 224, .box_w = 15, .box_h = 15, .ofs_x = -1, .ofs_y = -2}, - {.bitmap_index = 117001, .adv_w = 224, .box_w = 14, .box_h = 11, .ofs_x = 0, .ofs_y = 0}, - {.bitmap_index = 117078, .adv_w = 224, .box_w = 14, .box_h = 13, .ofs_x = 0, .ofs_y = -1}, - {.bitmap_index = 117169, .adv_w = 224, .box_w = 14, .box_h = 11, .ofs_x = 0, .ofs_y = 0}, - {.bitmap_index = 117246, .adv_w = 154, .box_w = 10, .box_h = 11, .ofs_x = 0, .ofs_y = 0}, - {.bitmap_index = 117301, .adv_w = 224, .box_w = 14, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 117406, .adv_w = 224, .box_w = 14, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 117511, .adv_w = 252, .box_w = 16, .box_h = 13, .ofs_x = 0, .ofs_y = -1}, - {.bitmap_index = 117615, .adv_w = 224, .box_w = 14, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 117720, .adv_w = 252, .box_w = 16, .box_h = 11, .ofs_x = 0, .ofs_y = 0}, - {.bitmap_index = 117808, .adv_w = 224, .box_w = 14, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 117913, .adv_w = 112, .box_w = 7, .box_h = 12, .ofs_x = 0, .ofs_y = -1}, - {.bitmap_index = 117955, .adv_w = 168, .box_w = 11, .box_h = 12, .ofs_x = 0, .ofs_y = -1}, - {.bitmap_index = 118021, .adv_w = 252, .box_w = 16, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 118133, .adv_w = 224, .box_w = 14, .box_h = 11, .ofs_x = 0, .ofs_y = 0}, - {.bitmap_index = 118210, .adv_w = 154, .box_w = 10, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 118285, .adv_w = 196, .box_w = 10, .box_h = 14, .ofs_x = 1, .ofs_y = -2}, - {.bitmap_index = 118355, .adv_w = 196, .box_w = 13, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 118453, .adv_w = 196, .box_w = 13, .box_h = 13, .ofs_x = 0, .ofs_y = -1}, - {.bitmap_index = 118538, .adv_w = 196, .box_w = 13, .box_h = 13, .ofs_x = 0, .ofs_y = -1}, - {.bitmap_index = 118623, .adv_w = 196, .box_w = 10, .box_h = 14, .ofs_x = 1, .ofs_y = -2}, - {.bitmap_index = 118693, .adv_w = 196, .box_w = 14, .box_h = 13, .ofs_x = -1, .ofs_y = -1}, - {.bitmap_index = 118784, .adv_w = 140, .box_w = 9, .box_h = 13, .ofs_x = 0, .ofs_y = -1}, - {.bitmap_index = 118843, .adv_w = 140, .box_w = 9, .box_h = 13, .ofs_x = 0, .ofs_y = -1}, - {.bitmap_index = 118902, .adv_w = 196, .box_w = 13, .box_h = 13, .ofs_x = 0, .ofs_y = -1}, - {.bitmap_index = 118987, .adv_w = 196, .box_w = 13, .box_h = 4, .ofs_x = 0, .ofs_y = 3}, - {.bitmap_index = 119013, .adv_w = 252, .box_w = 16, .box_h = 11, .ofs_x = 0, .ofs_y = 0}, - {.bitmap_index = 119101, .adv_w = 280, .box_w = 18, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 119236, .adv_w = 252, .box_w = 17, .box_h = 15, .ofs_x = -1, .ofs_y = -2}, - {.bitmap_index = 119364, .adv_w = 224, .box_w = 14, .box_h = 13, .ofs_x = 0, .ofs_y = -1}, - {.bitmap_index = 119455, .adv_w = 196, .box_w = 13, .box_h = 8, .ofs_x = 0, .ofs_y = 1}, - {.bitmap_index = 119507, .adv_w = 196, .box_w = 13, .box_h = 8, .ofs_x = 0, .ofs_y = 1}, - {.bitmap_index = 119559, .adv_w = 280, .box_w = 18, .box_h = 11, .ofs_x = 0, .ofs_y = 0}, - {.bitmap_index = 119658, .adv_w = 224, .box_w = 14, .box_h = 11, .ofs_x = 0, .ofs_y = 0}, - {.bitmap_index = 119735, .adv_w = 224, .box_w = 14, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 119840, .adv_w = 224, .box_w = 15, .box_h = 15, .ofs_x = -1, .ofs_y = -2}, - {.bitmap_index = 119953, .adv_w = 196, .box_w = 13, .box_h = 13, .ofs_x = 0, .ofs_y = -1}, - {.bitmap_index = 120038, .adv_w = 196, .box_w = 13, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 120136, .adv_w = 196, .box_w = 13, .box_h = 13, .ofs_x = 0, .ofs_y = -1}, - {.bitmap_index = 120221, .adv_w = 196, .box_w = 13, .box_h = 12, .ofs_x = 0, .ofs_y = -1}, - {.bitmap_index = 120299, .adv_w = 224, .box_w = 14, .box_h = 11, .ofs_x = 0, .ofs_y = 0}, - {.bitmap_index = 120376, .adv_w = 140, .box_w = 10, .box_h = 15, .ofs_x = -1, .ofs_y = -2}, - {.bitmap_index = 120451, .adv_w = 196, .box_w = 13, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 120549, .adv_w = 196, .box_w = 13, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 120647, .adv_w = 252, .box_w = 16, .box_h = 11, .ofs_x = 0, .ofs_y = 0}, - {.bitmap_index = 120735, .adv_w = 224, .box_w = 16, .box_h = 15, .ofs_x = -1, .ofs_y = -2}, - {.bitmap_index = 120855, .adv_w = 168, .box_w = 11, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 120938, .adv_w = 280, .box_w = 18, .box_h = 13, .ofs_x = 0, .ofs_y = -1}, - {.bitmap_index = 121055, .adv_w = 280, .box_w = 18, .box_h = 10, .ofs_x = 0, .ofs_y = 0}, - {.bitmap_index = 121145, .adv_w = 280, .box_w = 18, .box_h = 10, .ofs_x = 0, .ofs_y = 0}, - {.bitmap_index = 121235, .adv_w = 280, .box_w = 18, .box_h = 10, .ofs_x = 0, .ofs_y = 0}, - {.bitmap_index = 121325, .adv_w = 280, .box_w = 18, .box_h = 10, .ofs_x = 0, .ofs_y = 0}, - {.bitmap_index = 121415, .adv_w = 280, .box_w = 18, .box_h = 10, .ofs_x = 0, .ofs_y = 0}, - {.bitmap_index = 121505, .adv_w = 280, .box_w = 18, .box_h = 12, .ofs_x = 0, .ofs_y = -1}, - {.bitmap_index = 121613, .adv_w = 196, .box_w = 12, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 121703, .adv_w = 196, .box_w = 13, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 121801, .adv_w = 224, .box_w = 15, .box_h = 15, .ofs_x = -1, .ofs_y = -2}, - {.bitmap_index = 121914, .adv_w = 280, .box_w = 18, .box_h = 11, .ofs_x = 0, .ofs_y = 0}, - {.bitmap_index = 122013, .adv_w = 168, .box_w = 11, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 122096, .adv_w = 225, .box_w = 15, .box_h = 10, .ofs_x = 0, .ofs_y = 0}, - {.bitmap_index = 122171, .adv_w = 224, .box_w = 5, .box_h = 12, .ofs_x = 7, .ofs_y = -1}, - {.bitmap_index = 122201, .adv_w = 224, .box_w = 5, .box_h = 12, .ofs_x = 2, .ofs_y = -1}, - {.bitmap_index = 122231, .adv_w = 224, .box_w = 3, .box_h = 5, .ofs_x = 1, .ofs_y = -1}, - {.bitmap_index = 122239, .adv_w = 224, .box_w = 6, .box_h = 10, .ofs_x = 4, .ofs_y = 0}, - {.bitmap_index = 122269, .adv_w = 224, .box_w = 6, .box_h = 11, .ofs_x = 4, .ofs_y = 0} -}; - -/*--------------------- - * CHARACTER MAPPING - *--------------------*/ - -static const uint16_t unicode_list_1[] = { - 0x0, 0x1, 0x4, 0xb, 0xc, 0x40, 0x41, 0x42, - 0x43, 0x45, 0x46, 0x47 -}; - -static const uint8_t glyph_id_ofs_list_4[] = { - 0, 0, 0, 1, 2, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 3, 4, 5, 6, 0, 7, - 8, 9, 0, 10, 11, 12, 13, 14, - 15, 16, 17, 18, 19, 20, 21, 22, - 23, 24, 25, 26, 27, 28, 29, 0, - 30, 31, 32, 0, 33, 34, 0, 35, - 36, 37, 38, 39, 40, 0, 41, 42, - 43, 44, 45, 46, 47, 48, 49, 50, - 51, 0, 52, 53, 54, 55, 56, 57, - 58, 59, 60, 61, 62, 63, 64, 0, - 65, 66, 67, 68, 69, 70, 71 -}; - -static const uint16_t unicode_list_5[] = { - 0x0, 0x4, 0x7, 0xd, 0x1d11, 0x1d14, 0x1d18, 0x1d19, - 0x1d1a, 0x1d1b, 0x1d1c, 0x1d1e, 0x1d24, 0x1d25, 0x1d27, 0x1d32, - 0x1d37, 0x1d3e, 0x1d4c, 0x1d56, 0x1d5c, 0x1d5f, 0x1d60, 0x1d68, - 0x1d6e, 0x1d70, 0x1d97, 0x1d99, 0x1d9a, 0x1d9c, 0x1d9d, 0x1da5, - 0x1dac, 0x1db2, 0x1db5, 0x1db7, 0x1dbd, 0x1dcb, 0x1dd1, 0x1ddb, - 0x1ddc, 0x1dde, 0x1de6, 0x1de7, 0x1de9, 0x1df4, 0x1df5, 0x1df6, - 0x1dff, 0x1e07, 0x1e0c, 0x1e0e, 0x1e12, 0x1e1b, 0x1e22, 0x1e2b, - 0x1e2e, 0x1e49, 0x1e4d, 0x1e57, 0x1e5e, 0x1e5f, 0x1e60, 0x1e64, - 0x1e66, 0x1e6a, 0x1e6d, 0x1e71, 0x1e90, 0x1e97, 0x1e9c, 0x1eac, - 0x1eae, 0x1eb2, 0x1ed0, 0x1ed3, 0x1eee, 0x1ef2, 0x1eff, 0x1f1c, - 0x1f22, 0x1f2a, 0x1f30, 0x1f35, 0x1f4d, 0x1f6b, 0x1f6d, 0x1f76, - 0x1f85, 0x1faa, 0x1fc4, 0x1fd6, 0x1fde, 0x1fe0, 0x1fe6, 0x200a, - 0x2015, 0x203b, 0x2050, 0x2054, 0x2055, 0x2056, 0x2059, 0x205a, - 0x205c, 0x205e, 0x2063, 0x206b, 0x2076, 0x2078, 0x2079, 0x207a, - 0x207c, 0x207d, 0x207e, 0x2082, 0x2087, 0x2088, 0x2096, 0x2097, - 0x209b, 0x209e, 0x20aa, 0x20ac, 0x20bd, 0x20c8, 0x20de, 0x20ee, - 0x20f7, 0x210b, 0x2117, 0x2118, 0x211b, 0x2128, 0x212e, 0x2135, - 0x2136, 0x213a, 0x2141, 0x2147, 0x2149, 0x214c, 0x2158, 0x215b, - 0x215e, 0x216c, 0x2183, 0x2186, 0x2194, 0x21ac, 0x21b0, 0x21b1, - 0x21b9, 0x21ba, 0x21bb, 0x21c4, 0x21da, 0x21e6, 0x21ea, 0x21ee, - 0x21f5, 0x2206, 0x2216, 0x2227, 0x2228, 0x224c, 0x2251, 0x2252, - 0x2254, 0x2259, 0x225b, 0x2263, 0x2265, 0x2268, 0x2269, 0x2282, - 0x2284, 0x228c, 0x22ab, 0x22b0, 0x22c4, 0x22cc, 0x22d3, 0x22d4, - 0x22d9, 0x22db, 0x22dc, 0x22de, 0x22e7, 0x22e8, 0x22f4, 0x22f5, - 0x22f6, 0x22f7, 0x22fb, 0x22fc, 0x2300, 0x2301, 0x2303, 0x2304, - 0x2308, 0x2309, 0x2314, 0x2315, 0x2319, 0x231d, 0x231e, 0x2322, - 0x2337, 0x2338, 0x2351, 0x235b, 0x2373, 0x2379, 0x2384, 0x238d, - 0x238e, 0x239d, 0x23c3, 0x23d2, 0x23f2, 0x23fb, 0x2457, 0x245b, - 0x2460, 0x2477, 0x2495, 0x249a, 0x24ad, 0x24ae, 0x24bf, 0x24c7, - 0x24df, 0x2500, 0x252c, 0x25c5, 0x25ec, 0x25ef, 0x25f1, 0x2601, - 0x2604, 0x260e, 0x261c, 0x261e, 0x2623, 0x2629, 0x2630, 0x2634, - 0x2639, 0x2641, 0x2658, 0x265b, 0x2661, 0x269c, 0x26f0, 0x2708, - 0x270b, 0x2742, 0x2745, 0x275b, 0x277a, 0x2794, 0x27a8, 0x27af, - 0x27db, 0x27e4, 0x27fc, 0x2801, 0x2803, 0x281a, 0x2820, 0x2826, - 0x2827, 0x282b, 0x282d, 0x2831, 0x2838, 0x283a, 0x283b, 0x283c, - 0x283f, 0x2842, 0x2858, 0x2862, 0x2868, 0x2884, 0x288a, 0x288e, - 0x2893, 0x2898, 0x28c4, 0x28ca, 0x28cc, 0x28da, 0x28dc, 0x28e1, - 0x28e5, 0x2929, 0x296b, 0x2977, 0x29a3, 0x29ce, 0x29dd, 0x2a1a, - 0x2a61, 0x2a68, 0x2a69, 0x2a74, 0x2a77, 0x2a7a, 0x2a7c, 0x2a89, - 0x2a94, 0x2a96, 0x2a98, 0x2a99, 0x2a9a, 0x2a9d, 0x2aa9, 0x2aaa, - 0x2aab, 0x2aaf, 0x2ab0, 0x2ab3, 0x2ab5, 0x2ac4, 0x2ac6, 0x2ac7, - 0x2aca, 0x2ad0, 0x2ad5, 0x2ad7, 0x2add, 0x2ae3, 0x2aee, 0x2af0, - 0x2af7, 0x2afc, 0x2b0b, 0x2b0f, 0x2b15, 0x2b18, 0x2b19, 0x2b1e, - 0x2b1f, 0x2b20, 0x2b22, 0x2b2b, 0x2b35, 0x2b42, 0x2b4b, 0x2b51, - 0x2b56, 0x2b5b, 0x2b5c, 0x2b66, 0x2b76, 0x2b7d, 0x2b82, 0x2c07, - 0x2c5d, 0x2cee, 0x2cef, 0x2cf6, 0x2cf7, 0x2cff, 0x2d02, 0x2d03, - 0x2d13, 0x2d14, 0x2d19, 0x2d1d, 0x2d3c, 0x2d3e, 0x2d40, 0x2d41, - 0x2d44, 0x2d47, 0x2d49, 0x2d56, 0x2d84, 0x2d85, 0x2d89, 0x2d8f, - 0x2d94, 0x2d97, 0x2da6, 0x2da8, 0x2dad, 0x2db7, 0x2db8, 0x2dbc, - 0x2dbe, 0x2dc8, 0x2df1, 0x2e0b, 0x2e10, 0x2e20, 0x2e26, 0x2e30, - 0x2e42, 0x2e46, 0x2e48, 0x2e64, 0x2e73, 0x2e82, 0x2e8a, 0x2e8d, - 0x2e91, 0x2e96, 0x2e99, 0x2e9c, 0x2e9d, 0x2ea3, 0x2ea4, 0x2ea8, - 0x2eaf, 0x2eb2, 0x2eba, 0x2ed4, 0x2ed6, 0x2ee9, 0x2eea, 0x2efc, - 0x2f06, 0x2f1f, 0x2f23, 0x2f26, 0x2f2e, 0x2f36, 0x2f38, 0x2f80, - 0x2fb9, 0x2fbb, 0x2fc3, 0x2fd6, 0x3004, 0x3019, 0x3020, 0x302b, - 0x302c, 0x3030, 0x305c, 0x3074, 0x3078, 0x307f, 0x30da, 0x3109, - 0x3121, 0x3122, 0x3127, 0x3137, 0x3141, 0x314c, 0x3150, 0x3151, - 0x315c, 0x315e, 0x3164, 0x3166, 0x318f, 0x3191, 0x319b, 0x31a6, - 0x31cd, 0x31d6, 0x31da, 0x31ec, 0x31f2, 0x31fd, 0x31fe, 0x3210, - 0x3212, 0x3218, 0x322a, 0x3266, 0x3279, 0x3299, 0x32a3, 0x32ac, - 0x32b2, 0x32b3, 0x32b6, 0x32b8, 0x32b9, 0x32e0, 0x32e1, 0x32ec, - 0x32ff, 0x330b, 0x334b, 0x33d2, 0x33d8, 0x33e5, 0x33eb, 0x3440, - 0x344a, 0x344f, 0x3450, 0x3456, 0x3459, 0x3468, 0x346a, 0x3473, - 0x3481, 0x3485, 0x3498, 0x34aa, 0x34be, 0x34c1, 0x34c8, 0x34ca, - 0x34cd, 0x34ce, 0x34d2, 0x34d6, 0x34e0, 0x34f3, 0x34f6, 0x34f7, - 0x34fa, 0x3507, 0x3518, 0x351f, 0x3524, 0x3525, 0x3530, 0x3531, - 0x3536, 0x3539, 0x3540, 0x354d, 0x3553, 0x357a, 0x357f, 0x3580, - 0x3585, 0x358b, 0x3598, 0x35a2, 0x35a7, 0x35a8, 0x35d8, 0x35ed, - 0x3603, 0x3605, 0x3609, 0x360f, 0x3610, 0x3611, 0x3614, 0x3619, - 0x361a, 0x361c, 0x361e, 0x362c, 0x362e, 0x3630, 0x3639, 0x363b, - 0x363c, 0x363d, 0x363e, 0x364b, 0x3661, 0x3662, 0x3670, 0x3672, - 0x3676, 0x3680, 0x3682, 0x36a1, 0x36a8, 0x36ad, 0x36e1, 0x36f6, - 0x3702, 0x370c, 0x3710, 0x3722, 0x3732, 0x373b, 0x374a, 0x374d, - 0x3754, 0x3759, 0x37ae, 0x37c1, 0x37ff, 0x381e, 0x382d, 0x386b, - 0x387e, 0x3886, 0x388e, 0x3893, 0x38dc, 0x38e9, 0x3913, 0x392a, - 0x3932, 0x3934, 0x393b, 0x394a, 0x395c, 0x3970, 0x3a32, 0x3a43, - 0x3a5d, 0x3a61, 0x3a72, 0x3a73, 0x3a74, 0x3a75, 0x3a76, 0x3a7a, - 0x3a80, 0x3a83, 0x3a84, 0x3a88, 0x3a8c, 0x3a9b, 0x3a9c, 0x3ac6, - 0x3ade, 0x3adf, 0x3ae0, 0x3ae5, 0x3aec, 0x3b20, 0x3b22, 0x3b25, - 0x3b28, 0x3b45, 0x3b48, 0x3b49, 0x3b53, 0x3b6b, 0x3b71, 0x3b8b, - 0x3b99, 0x3ba3, 0x3bca, 0x3bcc, 0x3bd2, 0x3bdb, 0x3be6, 0x3bf3, - 0x3bf4, 0x3bf9, 0x3c04, 0x3c1c, 0x3c28, 0x3c43, 0x3c4c, 0x3c4f, - 0x3c52, 0x3c56, 0x3c85, 0x3c88, 0x3c99, 0x3ccd, 0x3d02, 0x3d08, - 0x3d16, 0x3d18, 0x3d19, 0x3d1a, 0x3d2c, 0x3d32, 0x3d3a, 0x3d40, - 0x3d67, 0x3da1, 0x3da7, 0x3dae, 0x3e10, 0x3e33, 0x3e49, 0x3ed4, - 0x3ef0, 0x3f74, 0x3f7c, 0x3f8e, 0x3fca, 0x3fcb, 0x4032, 0x4047, - 0x406a, 0x40c2, 0x40f0, 0x413e, 0x4147, 0x4149, 0x4158, 0x416c, - 0x4171, 0x417a, 0x418a, 0x41bd, 0x41c0, 0x41c7, 0x41d1, 0x41fd, - 0x41fe, 0x423c, 0x4250, 0x4283, 0x42ba, 0x430f, 0x4314, 0x4317, - 0x43c1, 0x4429, 0x442b, 0x4430, 0x4433, 0x4434, 0x4439, 0x4441, - 0x4442, 0x4444, 0x4446, 0x4448, 0x444b, 0x444c, 0x445d, 0x446a, - 0x447b, 0x447c, 0x4481, 0x4487, 0x44c3, 0x44d6, 0x44ec, 0x458b, - 0x458d, 0x458e, 0x458f, 0x4595, 0x4597, 0x45d0, 0x45e8, 0x45ff, - 0x4605, 0x4609, 0x461c, 0x4630, 0x4631, 0x464f, 0x4651, 0x46f6, - 0x46fe, 0x4704, 0x4713, 0x4725, 0x4745, 0x47cb, 0x484b, 0x484d, - 0x484f, 0x4867, 0x486e, 0x486f, 0x487e, 0x4892, 0x48d1, 0x48d2, - 0x48dc, 0x48de, 0x48e2, 0x48e9, 0x490c, 0x491c, 0x493f, 0x495e, - 0x4987, 0x498b, 0x49a4, 0x49dc, 0x49ea, 0x49f6, 0x4a00, 0x4a22, - 0x4a37, 0x4a3d, 0x4a57, 0x4a5a, 0x4a65, 0x4a67, 0x4aa8, 0x4ab2, - 0x4ad1, 0x4ad5, 0x4b32, 0x4b84, 0x4bcf, 0x4be7, 0x4c0c, 0x4c11, - 0x4c15, 0x4c2a, 0x4c31, 0x4c41, 0x4c4a, 0x4c53, 0x4c55, 0x4c5d, - 0x4c61, 0x4c72, 0x4c77, 0x4c82, 0x4c86, 0x4ca4, 0x4cab, 0x4cbe, - 0x4cc3, 0x4ce2, 0x4ce3, 0x4ceb, 0x4cf1, 0x4cfa, 0x4d05, 0x4d4e, - 0x4d4f, 0x4d65, 0x4d81, 0x4d8d, 0x4d9d, 0x4df0, 0x4e4b, 0x4e7f, - 0x4e9f, 0x4eba, 0x4ee3, 0x4f12, 0x4f14, 0x4f16, 0x4f1d, 0x4f44, - 0x4f6f, 0x4f80, 0x4f83, 0x4f88, 0x4f8e, 0x4f9a, 0x4fba, 0x4fc0, - 0x4fc3, 0x4fdd, 0x5009, 0x500e, 0x5042, 0x505b, 0x5066, 0x5077, - 0x5081, 0x50ae, 0x50da, 0x50fb, 0x5104, 0x510b, 0x5118, 0x5119, - 0x511a, 0x513b, 0x513d, 0x514a, 0x5180, 0x5183, 0x5193, 0x51c2, - 0x51f6, 0x51f7, 0x5202, 0x5247, 0x5288, 0x52e4, 0x52ed, 0x534e, - 0x535a, 0x5368, 0x5446, 0x5495, 0x54bd, 0x54ee, 0x5518, 0x5566, - 0x575d, 0x5764, 0x5779, 0x57bc, 0x57e0, 0x57ed, 0x57f2, 0x580e, - 0x5818, 0x5890, 0x5892, 0x589c, 0x58a0, 0x58a7, 0x58ab, 0x58bb, - 0x58cb, 0x58d1, 0x58e3, 0x58f4, 0x58f7, 0x5911, 0x5919, 0x591b, - 0x591f, 0x5924, 0x5929, 0x593b, 0x593e, 0x5942, 0x5944, 0x5945, - 0x5966, 0x5977, 0x5982, 0x5983, 0x5984, 0x599d, 0x599e, 0x59a6, - 0x59a9, 0x59af, 0x59bb, 0x59bd, 0x59be, 0x59c1, 0x59c3, 0x59d0, - 0x59d8, 0x59dc, 0x59e7, 0x5a09, 0x5a13, 0x5a2c, 0x5a2e, 0x5a69, - 0x5a81, 0x5a88, 0x5a9b, 0x5aa4, 0x5ab2, 0x5aef, 0x5b61, 0x5b72, - 0x5bb1, 0x5bb2, 0x5bb8, 0x5bba, 0x5bbd, 0x5bc8, 0x5bc9, 0x5bcc, - 0x5bd0, 0x5bd4, 0x5bd8, 0x5bfb, 0x5c0e, 0x5c4a, 0x5c75, 0x5c81, - 0x5c88, 0x5c96, 0x5c9b, 0x5cb4, 0x5cc4, 0x5cf0, 0x5d00, 0x5dbc, - 0x5ddb, 0x5df0, 0x5df3, 0x5e0e, 0x5e14, 0x5e1a, 0x5e26, 0x5e3b, - 0x5e49, 0x5eac, 0x5eaf, 0x5eb7, 0x5ec3, 0x5ecb, 0x5ecd, 0x5edf, - 0x5ee2, 0x5ee5, 0x5efc, 0x5f0e, 0x5f11, 0x5f12, 0x5f14, 0x5f20, - 0x5f21, 0x5f2a, 0x5f2b, 0x5f30, 0x5f31, 0x5f34, 0x5f3f, 0x5f42, - 0x5f43, 0x5f56, 0x5f5b, 0x5f5c, 0x5f5f, 0x5f64, 0x5f65, 0x5f66, - 0x5f71, 0x5f7a, 0x5f89, 0x5f90, 0x5f95, 0x5f9b, 0x5fb4, 0x5fbb, - 0x5ff9, 0x6006, 0x600e, 0x605e, 0x6063, 0x6065, 0x6089, 0x60bc, - 0x60de, 0x60df, 0x60e0, 0x60e2, 0x60ee, 0x6155, 0x616c, 0x6191, - 0x6233, 0x6240, 0x6243, 0x6488, 0x649a, 0x649c, 0x64a4, 0x64b3, - 0x64ed, 0x6501, 0x6544, 0x6555, 0x655e, 0x6561, 0x6573, 0x6575, - 0x6589, 0x658e, 0x659f, 0x65ac, 0x65ad, 0x65b4, 0x65b9, 0x65cc, - 0x65d7, 0x65e2, 0x65e7, 0x65ea, 0x65f3, 0x65f4, 0x65f9, 0x65fb, - 0x6603, 0x660c, 0x6611, 0x6618, 0x6663, 0x666a, 0x666f, 0x6673, - 0x667a, 0x6685, 0x6704, 0x6710, 0x6714, 0x6716, 0x6719, 0x6728, - 0x6729, 0x673e, 0x674d, 0x675d, 0x6765, 0x6769, 0x676f, 0x6780, - 0x67b9, 0x67ec, 0x67f0, 0x6800, 0x6803, 0x6839, 0x68a7, 0x68aa, - 0x68d5, 0x68d6, 0x6923, 0x6924, 0x6968, 0x69e5, 0x69e9, 0x69fb, - 0x6a6b, 0x6bf6, 0x6da8, 0x6dcd, 0x6dd5, 0x6de3, 0x6def, 0x6df9, - 0x6e24, 0x6e4c, 0xbf12, 0xbf19, 0xbf1c, 0xbf1d, 0xbf1e, 0xbf22, - 0xbf24, 0xbf26, 0xbf2a, 0xbf2d, 0xbf32, 0xbf37, 0xbf38, 0xbf39, - 0xbf4f, 0xbf54, 0xbf59, 0xbf5c, 0xbf5d, 0xbf5e, 0xbf62, 0xbf63, - 0xbf64, 0xbf65, 0xbf78, 0xbf79, 0xbf7f, 0xbf81, 0xbf82, 0xbf85, - 0xbf88, 0xbf89, 0xbf8a, 0xbf8c, 0xbfa4, 0xbfa6, 0xbfd5, 0xbfd6, - 0xbfd8, 0xbfda, 0xbff1, 0xbff8, 0xbffb, 0xc004, 0xc02d, 0xc035, - 0xc06c, 0xc0fc, 0xc151, 0xc152, 0xc153, 0xc154, 0xc155, 0xc198, - 0xc1a4, 0xc1fe, 0xc215, 0xc46b, 0xc6d3, 0xc7b3, 0xce19, 0xce1a, - 0xce1d, 0xce22, 0xce23 -}; - -/*Collect the unicode lists and glyph_id offsets*/ -static const lv_font_fmt_txt_cmap_t cmaps[] = { - { - .range_start = 32, .range_length = 96, .glyph_id_start = 1, - .unicode_list = NULL, .glyph_id_ofs_list = NULL, .list_length = 0, .type = LV_FONT_FMT_TXT_CMAP_FORMAT0_TINY - }, - { - .range_start = 12289, .range_length = 72, .glyph_id_start = 97, - .unicode_list = unicode_list_1, .glyph_id_ofs_list = NULL, .list_length = 12, .type = LV_FONT_FMT_TXT_CMAP_SPARSE_TINY - }, - { - .range_start = 12362, .range_length = 24, .glyph_id_start = 109, - .unicode_list = NULL, .glyph_id_ofs_list = NULL, .list_length = 0, .type = LV_FONT_FMT_TXT_CMAP_FORMAT0_TINY - }, - { - .range_start = 12387, .range_length = 43, .glyph_id_start = 133, - .unicode_list = NULL, .glyph_id_ofs_list = NULL, .list_length = 0, .type = LV_FONT_FMT_TXT_CMAP_FORMAT0_TINY - }, - { - .range_start = 12431, .range_length = 95, .glyph_id_start = 176, - .unicode_list = NULL, .glyph_id_ofs_list = glyph_id_ofs_list_4, .list_length = 95, .type = LV_FONT_FMT_TXT_CMAP_FORMAT0_FULL - }, - { - .range_start = 12527, .range_length = 52772, .glyph_id_start = 248, - .unicode_list = unicode_list_5, .glyph_id_ofs_list = NULL, .list_length = 1187, .type = LV_FONT_FMT_TXT_CMAP_SPARSE_TINY - } -}; - -/*-------------------- - * ALL CUSTOM DATA - *--------------------*/ - -#if LVGL_VERSION_MAJOR >= 8 -/*Store all the custom data of the font*/ - -static const lv_font_fmt_txt_dsc_t font_dsc = { -#else -static lv_font_fmt_txt_dsc_t font_dsc = { -#endif - .glyph_bitmap = glyph_bitmap, - .glyph_dsc = glyph_dsc, - .cmaps = cmaps, - .kern_dsc = NULL, - .kern_scale = 0, - .cmap_num = 6, - .bpp = 4, - .kern_classes = 0, - .bitmap_format = 0, - -}; - -/*----------------- - * PUBLIC FONT - *----------------*/ - -#ifdef _MSC_VER - #pragma deprecated(lv_font_simsun_14_cjk) -#else - #warning "LV_FONT_SIMSUN_14_CJK is deprecated, use LV_FONT_SOURCE_HAN_SANS_SC_14_CJK instead." -#endif - -/*Initialize a public general font descriptor*/ -#if LVGL_VERSION_MAJOR >= 8 -const lv_font_t lv_font_simsun_14_cjk = { -#else -lv_font_t lv_font_simsun_14_cjk = { -#endif - .get_glyph_dsc = lv_font_get_glyph_dsc_fmt_txt, /*Function pointer to get glyph's data*/ - .get_glyph_bitmap = lv_font_get_bitmap_fmt_txt, /*Function pointer to get glyph's bitmap*/ - .line_height = 15, /*The maximum line height required by the font*/ - .base_line = 2, /*Baseline measured from the bottom of the line*/ -#if !(LVGL_VERSION_MAJOR == 6 && LVGL_VERSION_MINOR == 0) - .subpx = LV_FONT_SUBPX_NONE, -#endif -#if LV_VERSION_CHECK(7, 4, 0) || LVGL_VERSION_MAJOR >= 8 - .underline_position = -2, - .underline_thickness = 1, -#endif - .dsc = &font_dsc /*The custom font data. Will be accessed by `get_glyph_bitmap/dsc` */ -}; - -#endif /*#if LV_FONT_SIMSUN_14_CJK*/ diff --git a/src/font/lv_font_simsun_16_cjk.c b/src/font/lv_font_simsun_16_cjk.c deleted file mode 100644 index 041f30e9e5..0000000000 --- a/src/font/lv_font_simsun_16_cjk.c +++ /dev/null @@ -1,24154 +0,0 @@ -/******************************************************************************* - * Size: 16 px - * Bpp: 4 - * Opts: --no-compress --no-prefilter --bpp 4 --size 16 --font SimSun.woff -r 0x20-0x7f --symbols (),盗提陽帯鼻画輕ッ冊ェル写父ぁフ結想正四O夫源庭場天續鳥れ講猿苦階給了製守8祝己妳薄泣塩帰ぺ吃変輪那着仍嗯爭熱創味保字宿捨準查達肯ァ薬得査障該降察ね網加昼料等図邪秋コ態品屬久原殊候路願楽確針上被怕悲風份重歡っ附ぷ既4黨價娘朝凍僅際洋止右航よ专角應酸師個比則響健昇豐筆歷適修據細忙跟管長令家ザ期般花越ミ域泳通些油乏ラ。營ス返調農叫樹刊愛間包知把ヤ貧橋拡普聞前ジ建当繰ネ送習渇用補ィ覺體法遊宙ョ酔余利壊語くつ払皆時辺追奇そ們只胸械勝住全沈力光ん深溝二類北面社值試9和五勵ゃ貿幾逐打課ゲて領3鼓辦発評1渉詳暇込计駄供嘛郵頃腦反構絵お容規借身妻国慮剛急乗静必議置克土オ乎荷更肉還混古渡授合主離條値決季晴東大尚央州が嗎験流先医亦林田星晩拿60旅婦量為痛テ孫う環友況玩務其ぼち揺坐一肩腰犯タょ希即果ぶ物練待み高九找やヶ都グ去」サ、气仮雑酒許終企笑録形リ銀切ギ快問滿役単黄集森毎實研喜蘇司鉛洲川条媽ノ才兩話言雖媒出客づ卻現異故り誌逮同訊已視本題ぞを横開音第席費持眾怎選元退限ー賽処喝就残無いガ多ケ沒義遠歌隣錢某雪析嬉採自透き側員予ゼ白婚电へ顯呀始均畫似懸格車騒度わ親店週維億締慣免帳電甚來園浴ゅ愈京と杯各海怒ぜ排敗挙老買7極模実紀ヒ携隻告シ並屋這孩讓質ワブ富賃争康由辞マ火於短樣削弟材注節另室ダ招擁ぃ若套底波行勤關著泊背疲狭作念推ぐ民貸祖介說ビ代温契你我レ入描變再札ソ派頭智遅私聽舉灣山伸放直安ト誕煙付符幅ふ絡她届耳飲忘参革團仕様載ど歩獲嫌息の汚交興魚指資雙與館初学年幸史位柱族走括び考青也共腕Lで販擔理病イ今逃當寺猫邊菓係ム秘示解池影ド文例斷曾事茶寫明科桃藝売便え導禁財飛替而亡到し具空寝辛業ウ府セ國何基菜厳市努張缺雲根外だ断万砂ゴ超使台实ぽ礼最慧算軟界段律像夕丈窓助刻月夏政呼ぴざ擇趣除動従涼方勉名線対存請子氏將5少否諸論美感或西者定食御表は參歳緑命進易性錯房も捕皿判中觀戦ニ緩町ピ番ず金千ろ?不た象治関ャ每看徒卒統じ手範訪押座步号ベ旁以母すほ密減成往歲件緒読歯效院种七謂凝濃嵌震喉繼クュ拭死円2積水欲如ポにさ寒道區精啦姐ア聯能足及停思壓2春且メ裏株官答概黒過氷柿戻厚ぱ党祭織引計け委暗複誘港バ失下村較続神ぇ尤強秀膝兒来績十書済化服破新廠1紹您情半式產系好教暑早め樂地休協良な哪常要揮周かエ麗境働避護ンツ香夜太見設非改広聲他検求危清彼經未在起葉控靴所差內造寄南望尺換向展備眠點完約ぎ裡分説申童優伝島机須塊日立拉,鉄軽單気信很転識支布数紙此迎受心輸坊モ處「訳三曇兄野顔戰增ナ伊列又髪両有取左毛至困吧昔赤狀相夠整別士経頼然簡ホ会發隨営需脱ヨば接永居冬迫圍甘醫誰部充消連弱宇會咲覚姉麼的増首统帶糖朋術商担移景功育庫曲總劃牛程駅犬報ロ學責因パ嚴八世後平負公げ曜陸專午之閉ぬ談ご災昨冷職悪謝對它近射敢意運船臉局難什産頗!球真記ま但蔵究制機案湖臺ひ害券男留内木驗雨施種特復句末濟キ色訴依せ百型る石牠討呢时任執飯歐宅組傳配小活ゆべ暖ズ漸站素らボ束価チ浅回女片独妹英目從認生違策僕楚ペ米こ掛む爸六状落漢プ投カ校做啊洗声探あ割体項履触々訓技ハ低工映是標速善点人デ口次可廿节宵植树端阳旦腊妇费愚劳动儿军师庆圣诞闰 --font FontAwesome5-Solid+Brands+Regular.woff -r 61441,61448,61451,61452,61452,61453,61457,61459,61461,61465,61468,61473,61478,61479,61480,61502,61507,61512,61515,61516,61517,61521,61522,61523,61524,61543,61544,61550,61552,61553,61556,61559,61560,61561,61563,61587,61589,61636,61637,61639,61641,61664,61671,61674,61683,61724,61732,61787,61931,62016,62017,62018,62019,62020,62087,62099,62212,62189,62810,63426,63650 --format lvgl -o lv_font_simsun_16_cjk.c --force-fast-kern-format - ******************************************************************************/ - -#ifdef LV_LVGL_H_INCLUDE_SIMPLE - #include "lvgl.h" -#else - #include "../../lvgl.h" -#endif - -#ifndef LV_FONT_SIMSUN_16_CJK - #define LV_FONT_SIMSUN_16_CJK 1 -#endif - -#if LV_FONT_SIMSUN_16_CJK - -/*----------------- - * BITMAPS - *----------------*/ - -/*Store the image of the glyphs*/ -static LV_ATTRIBUTE_LARGE_CONST const uint8_t glyph_bitmap[] = { - /* U+0020 " " */ - - /* U+0021 "!" */ - 0x97, 0xb9, 0xa8, 0x97, 0x75, 0x64, 0x53, 0x53, - 0x0, 0x0, 0xa8, 0xb9, - - /* U+0022 "\"" */ - 0x2, 0xe1, 0x98, 0xa, 0xc3, 0xf4, 0x2c, 0xa, - 0x60, 0x81, 0x27, 0x0, 0x0, 0x0, 0x0, - - /* U+0023 "#" */ - 0x0, 0x90, 0x3, 0x50, 0x0, 0x90, 0x4, 0x40, - 0x0, 0x90, 0x6, 0x40, 0x7f, 0xff, 0xff, 0xf6, - 0x13, 0xa3, 0x39, 0x41, 0x0, 0x80, 0x8, 0x0, - 0x1, 0x70, 0x9, 0x0, 0x3, 0x70, 0x9, 0x0, - 0x7f, 0xff, 0xff, 0xf6, 0x17, 0x73, 0x3a, 0x31, - 0x5, 0x30, 0x9, 0x0, 0x6, 0x20, 0x9, 0x0, - - /* U+0024 "$" */ - 0x0, 0x45, 0x0, 0x6, 0xaa, 0x80, 0x48, 0x45, - 0x86, 0x95, 0x45, 0xc7, 0x7b, 0x45, 0x20, 0x1e, - 0xc5, 0x0, 0x2, 0xec, 0x0, 0x0, 0x4f, 0xb0, - 0x0, 0x45, 0xd5, 0x52, 0x45, 0x6a, 0xe7, 0x45, - 0x49, 0xa4, 0x45, 0x74, 0x18, 0x9a, 0x60, 0x0, - 0x45, 0x0, 0x0, 0x45, 0x0, - - /* U+0025 "%" */ - 0x19, 0x80, 0x3, 0x20, 0x82, 0x64, 0x8, 0x0, - 0xb0, 0x47, 0x7, 0x0, 0xc0, 0x48, 0x61, 0x0, - 0xb0, 0x47, 0x70, 0x0, 0x73, 0x76, 0x50, 0x0, - 0x7, 0x67, 0x7, 0x60, 0x0, 0x7, 0x64, 0x64, - 0x0, 0x42, 0xa1, 0x38, 0x0, 0x70, 0xb1, 0x39, - 0x1, 0x50, 0x82, 0x47, 0x5, 0x0, 0x19, 0x91, - - /* U+0026 "&" */ - 0x0, 0x88, 0x50, 0x0, 0x6, 0x40, 0xc0, 0x0, - 0x9, 0x30, 0xd0, 0x0, 0x8, 0x53, 0x90, 0x0, - 0x6, 0x99, 0x10, 0x0, 0x5, 0xf0, 0x2a, 0x80, - 0x18, 0xd4, 0x9, 0x10, 0x84, 0x6a, 0x8, 0x0, - 0xc2, 0xe, 0x38, 0x0, 0xb3, 0x6, 0xe5, 0x0, - 0x6a, 0x0, 0xe9, 0x5, 0x9, 0xc9, 0x2b, 0xc3, - - /* U+0027 "'" */ - 0xb, 0xb0, 0x7, 0xf0, 0x0, 0xc0, 0x8, 0x30, - 0x1, 0x0, - - /* U+0028 "(" */ - 0x0, 0x6, 0x10, 0x4, 0x60, 0x0, 0xb0, 0x0, - 0x84, 0x0, 0xd, 0x0, 0x4, 0xa0, 0x0, 0x67, - 0x0, 0x8, 0x60, 0x0, 0x77, 0x0, 0x6, 0x80, - 0x0, 0x2c, 0x0, 0x0, 0xc1, 0x0, 0x5, 0x70, - 0x0, 0xa, 0x10, 0x0, 0x19, 0x0, 0x0, 0x21, - - /* U+0029 ")" */ - 0x16, 0x0, 0x0, 0x74, 0x0, 0x0, 0xb0, 0x0, - 0x5, 0x70, 0x0, 0xd, 0x0, 0x0, 0xb3, 0x0, - 0x8, 0x50, 0x0, 0x77, 0x0, 0x8, 0x60, 0x0, - 0x95, 0x0, 0xc, 0x10, 0x1, 0xb0, 0x0, 0x84, - 0x0, 0x29, 0x0, 0x9, 0x0, 0x1, 0x10, 0x0, - - /* U+002A "*" */ - 0x0, 0x7, 0x80, 0x0, 0x0, 0x8, 0x80, 0x0, - 0x5d, 0x26, 0x52, 0xd4, 0x18, 0xd6, 0x6d, 0x80, - 0x0, 0x1b, 0xa1, 0x0, 0x8, 0xd6, 0x6d, 0x80, - 0x5d, 0x27, 0x52, 0xd4, 0x0, 0x9, 0x70, 0x0, - 0x0, 0x9, 0x70, 0x0, - - /* U+002B "+" */ - 0x0, 0x2, 0x40, 0x0, 0x0, 0x3, 0x60, 0x0, - 0x0, 0x3, 0x60, 0x0, 0x0, 0x3, 0x60, 0x0, - 0x39, 0x9a, 0xc9, 0x94, 0x0, 0x3, 0x60, 0x0, - 0x0, 0x3, 0x60, 0x0, 0x0, 0x3, 0x60, 0x0, - 0x0, 0x2, 0x40, 0x0, - - /* U+002C "," */ - 0xb, 0xb0, 0x7, 0xf0, 0x0, 0xc0, 0x8, 0x40, - 0x2, 0x0, - - /* U+002D "-" */ - 0x49, 0x99, 0x99, 0x94, - - /* U+002E "." */ - 0x0, 0xcb, 0xbb, - - /* U+002F "/" */ - 0x0, 0x0, 0x0, 0x11, 0x0, 0x0, 0x0, 0x71, - 0x0, 0x0, 0x0, 0x80, 0x0, 0x0, 0x5, 0x20, - 0x0, 0x0, 0x8, 0x0, 0x0, 0x0, 0x44, 0x0, - 0x0, 0x0, 0x80, 0x0, 0x0, 0x2, 0x60, 0x0, - 0x0, 0x8, 0x0, 0x0, 0x0, 0x7, 0x0, 0x0, - 0x0, 0x71, 0x0, 0x0, 0x0, 0x80, 0x0, 0x0, - 0x5, 0x30, 0x0, 0x0, 0x8, 0x0, 0x0, 0x0, - 0x35, 0x0, 0x0, 0x0, 0x10, 0x0, 0x0, 0x0, - - /* U+0030 "0" */ - 0x0, 0x6a, 0x95, 0x0, 0x3, 0xc0, 0xb, 0x30, - 0xb, 0x60, 0x6, 0xa0, 0xf, 0x20, 0x2, 0xf0, - 0x2f, 0x0, 0x1, 0xf1, 0x3f, 0x0, 0x0, 0xf2, - 0x3f, 0x0, 0x0, 0xf2, 0x2f, 0x0, 0x1, 0xf1, - 0xf, 0x20, 0x2, 0xe0, 0xb, 0x50, 0x6, 0xa0, - 0x3, 0xc0, 0xb, 0x30, 0x0, 0x6a, 0x95, 0x0, - - /* U+0031 "1" */ - 0x0, 0x17, 0x0, 0x16, 0xd9, 0x0, 0x0, 0x79, - 0x0, 0x0, 0x79, 0x0, 0x0, 0x79, 0x0, 0x0, - 0x79, 0x0, 0x0, 0x79, 0x0, 0x0, 0x79, 0x0, - 0x0, 0x79, 0x0, 0x0, 0x79, 0x0, 0x0, 0x79, - 0x0, 0x16, 0xde, 0x72, - - /* U+0032 "2" */ - 0x0, 0x77, 0x89, 0x0, 0x92, 0x0, 0x88, 0xe, - 0x20, 0x4, 0xc0, 0xd5, 0x0, 0x3c, 0x0, 0x0, - 0x8, 0x80, 0x0, 0x1, 0xd1, 0x0, 0x0, 0x93, - 0x0, 0x0, 0x74, 0x0, 0x0, 0x55, 0x0, 0x0, - 0x28, 0x0, 0x6, 0x9, 0x0, 0x1, 0xa2, 0xff, - 0xff, 0xfb, - - /* U+0033 "3" */ - 0x1, 0x77, 0xa5, 0x0, 0xa2, 0x0, 0xd3, 0xd, - 0x40, 0x8, 0x80, 0x10, 0x0, 0x96, 0x0, 0x0, - 0x2c, 0x10, 0x0, 0x8d, 0x20, 0x0, 0x0, 0xb, - 0x30, 0x0, 0x0, 0x4c, 0x3, 0x0, 0x2, 0xf0, - 0xf4, 0x0, 0x3d, 0xd, 0x30, 0x9, 0x60, 0x28, - 0x78, 0x70, - - /* U+0034 "4" */ - 0x0, 0x0, 0x2b, 0x0, 0x0, 0x0, 0xac, 0x0, - 0x0, 0x3, 0x8c, 0x0, 0x0, 0x8, 0x4c, 0x0, - 0x0, 0x53, 0x4c, 0x0, 0x0, 0x80, 0x4c, 0x0, - 0x6, 0x20, 0x4c, 0x0, 0x7, 0x0, 0x4c, 0x0, - 0x47, 0x66, 0x8d, 0x62, 0x0, 0x0, 0x4c, 0x0, - 0x0, 0x0, 0x4c, 0x0, 0x0, 0x5, 0xaf, 0x71, - - /* U+0035 "5" */ - 0x5, 0xff, 0xff, 0xb0, 0x61, 0x0, 0x0, 0x7, - 0x0, 0x0, 0x0, 0x70, 0x0, 0x0, 0x7, 0x5a, - 0xca, 0x0, 0x85, 0x0, 0xa7, 0x1, 0x0, 0x3, - 0xd0, 0x0, 0x0, 0x1f, 0x7, 0x20, 0x1, 0xe0, - 0xf4, 0x0, 0x3c, 0xb, 0x10, 0x9, 0x50, 0x17, - 0x79, 0x80, - - /* U+0036 "6" */ - 0x0, 0x28, 0x7b, 0x20, 0x1, 0xa0, 0xa, 0x80, - 0x9, 0x40, 0x0, 0x0, 0xe, 0x10, 0x0, 0x0, - 0x1f, 0x2a, 0xbb, 0x10, 0x3f, 0x90, 0x7, 0xa0, - 0x3f, 0x20, 0x0, 0xf0, 0x3f, 0x0, 0x0, 0xe2, - 0x1f, 0x10, 0x0, 0xe2, 0xd, 0x40, 0x0, 0xe0, - 0x6, 0xb0, 0x4, 0x90, 0x0, 0x79, 0x88, 0x0, - - /* U+0037 "7" */ - 0xaf, 0xff, 0xff, 0xb, 0x30, 0x1, 0x80, 0x60, - 0x0, 0x71, 0x0, 0x0, 0x8, 0x0, 0x0, 0x7, - 0x30, 0x0, 0x0, 0xb0, 0x0, 0x0, 0x49, 0x0, - 0x0, 0x9, 0x50, 0x0, 0x0, 0xd3, 0x0, 0x0, - 0xf, 0x30, 0x0, 0x2, 0xf3, 0x0, 0x0, 0x1e, - 0x20, 0x0, - - /* U+0038 "8" */ - 0x1, 0x87, 0x78, 0x0, 0xa, 0x20, 0x4, 0x80, - 0xd, 0x0, 0x0, 0xd0, 0xe, 0x20, 0x0, 0xc0, - 0x7, 0xd3, 0x7, 0x50, 0x0, 0x9f, 0xc6, 0x0, - 0x5, 0x72, 0xbe, 0x10, 0xc, 0x0, 0x9, 0xb0, - 0x39, 0x0, 0x0, 0xf0, 0x3a, 0x0, 0x0, 0xe0, - 0xb, 0x10, 0x3, 0x90, 0x1, 0x87, 0x78, 0x0, - - /* U+0039 "9" */ - 0x1, 0x98, 0x86, 0x0, 0xa, 0x40, 0x9, 0x40, - 0x1e, 0x0, 0x4, 0xb0, 0x3c, 0x0, 0x2, 0xf0, - 0x4c, 0x0, 0x1, 0xf1, 0x2e, 0x0, 0x6, 0xf1, - 0xc, 0x70, 0x29, 0xf1, 0x1, 0x99, 0x73, 0xf0, - 0x0, 0x0, 0x5, 0xb0, 0x0, 0x0, 0x9, 0x50, - 0xa, 0x80, 0x1c, 0x0, 0x4, 0xb7, 0x91, 0x0, - - /* U+003A ":" */ - 0xc8, 0xb7, 0x0, 0x0, 0x0, 0x0, 0xb7, 0xc8, - - /* U+003B ";" */ - 0xda, 0x64, 0x0, 0x0, 0x0, 0x0, 0x65, 0xda, - 0x56, 0x90, - - /* U+003C "<" */ - 0x0, 0x0, 0x1, 0x0, 0x0, 0x38, 0x0, 0x2, - 0x90, 0x0, 0x19, 0x0, 0x1, 0xa0, 0x0, 0xa, - 0x10, 0x0, 0xa1, 0x0, 0x0, 0x56, 0x0, 0x0, - 0x6, 0x50, 0x0, 0x0, 0x74, 0x0, 0x0, 0x8, - 0x30, 0x0, 0x0, 0x92, 0x0, 0x0, 0x6, - - /* U+003D "=" */ - 0x49, 0x99, 0x99, 0x94, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x0, 0x0, 0x49, 0x99, 0x99, 0x94, - - /* U+003E ">" */ - 0x10, 0x0, 0x0, 0x83, 0x0, 0x0, 0x9, 0x20, - 0x0, 0x0, 0x91, 0x0, 0x0, 0xa, 0x10, 0x0, - 0x1, 0xa0, 0x0, 0x0, 0x1a, 0x0, 0x0, 0x65, - 0x0, 0x5, 0x60, 0x0, 0x47, 0x0, 0x3, 0x80, - 0x0, 0x29, 0x0, 0x0, 0x60, 0x0, 0x0, - - /* U+003F "?" */ - 0x0, 0x79, 0xa9, 0x10, 0x8, 0x10, 0x5, 0xb0, - 0x1a, 0x0, 0x0, 0xf1, 0x2f, 0x40, 0x0, 0xf1, - 0x5, 0x10, 0x5, 0xe0, 0x0, 0x0, 0x5d, 0x20, - 0x0, 0x3, 0xa0, 0x0, 0x0, 0x6, 0x10, 0x0, - 0x0, 0x6, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0xb, 0x70, 0x0, 0x0, 0xc, 0x80, 0x0, - - /* U+0040 "@" */ - 0x0, 0x38, 0x78, 0x10, 0x2, 0x90, 0x0, 0x90, - 0xa, 0x10, 0x79, 0x64, 0x1b, 0x8, 0x2b, 0x27, - 0x49, 0xa, 0xc, 0x9, 0x58, 0x57, 0xc, 0x8, - 0x58, 0x84, 0xb, 0x8, 0x39, 0x93, 0x39, 0x25, - 0x1b, 0x73, 0x78, 0x70, 0xa, 0x29, 0x3a, 0x41, - 0x3, 0x80, 0x0, 0x72, 0x0, 0x59, 0x88, 0x30, - - /* U+0041 "A" */ - 0x0, 0x5, 0x50, 0x0, 0x0, 0xc, 0xa0, 0x0, - 0x0, 0x8, 0xe0, 0x0, 0x0, 0x44, 0xd1, 0x0, - 0x0, 0x70, 0x95, 0x0, 0x0, 0x80, 0x68, 0x0, - 0x0, 0x80, 0x2c, 0x0, 0x3, 0x96, 0x6f, 0x0, - 0x7, 0x10, 0xc, 0x30, 0x8, 0x0, 0x8, 0x70, - 0x9, 0x0, 0x5, 0xa0, 0x8d, 0x20, 0x9, 0xf5, - - /* U+0042 "B" */ - 0x4e, 0xa6, 0x8a, 0x20, 0xb, 0x50, 0x6, 0xb0, - 0xb, 0x50, 0x2, 0xe0, 0xb, 0x50, 0x3, 0xd0, - 0xb, 0x50, 0xa, 0x50, 0xb, 0x96, 0xb7, 0x0, - 0xb, 0x50, 0x7, 0x90, 0xb, 0x50, 0x0, 0xe2, - 0xb, 0x50, 0x0, 0xc6, 0xb, 0x50, 0x0, 0xd5, - 0xb, 0x50, 0x3, 0xe1, 0x5e, 0xa6, 0x7a, 0x30, - - /* U+0043 "C" */ - 0x0, 0x49, 0x7c, 0xf0, 0x3, 0xb0, 0x0, 0xb2, - 0xc, 0x40, 0x0, 0x25, 0x2f, 0x0, 0x0, 0x0, - 0x6c, 0x0, 0x0, 0x0, 0x7b, 0x0, 0x0, 0x0, - 0x7b, 0x0, 0x0, 0x0, 0x6c, 0x0, 0x0, 0x0, - 0x4e, 0x0, 0x0, 0x2, 0xf, 0x20, 0x0, 0x42, - 0x7, 0xa0, 0x1, 0x70, 0x0, 0x7b, 0x98, 0x0, - - /* U+0044 "D" */ - 0x4e, 0xb6, 0x84, 0x0, 0xb, 0x50, 0xa, 0x50, - 0xb, 0x50, 0x3, 0xe0, 0xb, 0x50, 0x0, 0xe3, - 0xb, 0x50, 0x0, 0xd5, 0xb, 0x50, 0x0, 0xc6, - 0xb, 0x50, 0x0, 0xc6, 0xb, 0x50, 0x0, 0xd5, - 0xb, 0x50, 0x0, 0xf2, 0xb, 0x50, 0x3, 0xd0, - 0xb, 0x50, 0xb, 0x40, 0x4e, 0xb6, 0x94, 0x0, - - /* U+0045 "E" */ - 0x3d, 0xb6, 0x6b, 0xc0, 0xa, 0x60, 0x0, 0xb0, - 0xa, 0x60, 0x0, 0x22, 0xa, 0x60, 0x0, 0x0, - 0xa, 0x60, 0x6, 0x0, 0xa, 0xa6, 0x8b, 0x0, - 0xa, 0x60, 0x9, 0x0, 0xa, 0x60, 0x6, 0x0, - 0xa, 0x60, 0x0, 0x0, 0xa, 0x60, 0x0, 0x3, - 0xa, 0x60, 0x0, 0x63, 0x3d, 0xb6, 0x69, 0xe0, - - /* U+0046 "F" */ - 0x3d, 0xb6, 0x69, 0xf1, 0xa, 0x60, 0x0, 0x65, - 0xa, 0x60, 0x0, 0x5, 0xa, 0x60, 0x0, 0x0, - 0xa, 0x60, 0x6, 0x0, 0xa, 0xa6, 0x7e, 0x0, - 0xa, 0x60, 0x9, 0x0, 0xa, 0x60, 0x5, 0x0, - 0xa, 0x60, 0x0, 0x0, 0xa, 0x60, 0x0, 0x0, - 0xa, 0x60, 0x0, 0x0, 0x4d, 0xb2, 0x0, 0x0, - - /* U+0047 "G" */ - 0x0, 0x68, 0x9f, 0x50, 0x4, 0x90, 0x4, 0x80, - 0xd, 0x10, 0x0, 0x70, 0x3c, 0x0, 0x0, 0x0, - 0x6a, 0x0, 0x0, 0x0, 0x89, 0x0, 0x0, 0x0, - 0x89, 0x0, 0x29, 0xb4, 0x6a, 0x0, 0x5, 0xb0, - 0x4d, 0x0, 0x5, 0xb0, 0xe, 0x10, 0x5, 0xb0, - 0x7, 0x80, 0x6, 0xb0, 0x0, 0x88, 0x77, 0x20, - - /* U+0048 "H" */ - 0x4f, 0x80, 0x9, 0xf4, 0xe, 0x20, 0x3, 0xd0, - 0xe, 0x20, 0x3, 0xd0, 0xe, 0x20, 0x3, 0xd0, - 0xe, 0x20, 0x3, 0xd0, 0xe, 0x76, 0x68, 0xd0, - 0xe, 0x20, 0x3, 0xd0, 0xe, 0x20, 0x3, 0xd0, - 0xe, 0x20, 0x3, 0xd0, 0xe, 0x20, 0x3, 0xd0, - 0xe, 0x20, 0x3, 0xd0, 0x5f, 0x90, 0x9, 0xf4, - - /* U+0049 "I" */ - 0x36, 0xcc, 0x63, 0x0, 0x88, 0x0, 0x0, 0x88, - 0x0, 0x0, 0x88, 0x0, 0x0, 0x88, 0x0, 0x0, - 0x88, 0x0, 0x0, 0x88, 0x0, 0x0, 0x88, 0x0, - 0x0, 0x88, 0x0, 0x0, 0x88, 0x0, 0x0, 0x88, - 0x0, 0x36, 0xcc, 0x63, - - /* U+004A "J" */ - 0x0, 0x36, 0xbd, 0x64, 0x0, 0x0, 0x79, 0x0, - 0x0, 0x0, 0x79, 0x0, 0x0, 0x0, 0x79, 0x0, - 0x0, 0x0, 0x79, 0x0, 0x0, 0x0, 0x79, 0x0, - 0x0, 0x0, 0x79, 0x0, 0x0, 0x0, 0x79, 0x0, - 0x0, 0x0, 0x79, 0x0, 0x0, 0x0, 0x79, 0x0, - 0x0, 0x0, 0x78, 0x0, 0x1, 0x0, 0x87, 0x0, - 0x5d, 0x0, 0xb2, 0x0, 0x1b, 0x77, 0x40, 0x0, - - /* U+004B "K" */ - 0x4e, 0xa1, 0x2c, 0xb2, 0xb, 0x50, 0x9, 0x0, - 0xb, 0x50, 0x62, 0x0, 0xb, 0x51, 0x60, 0x0, - 0xb, 0x5a, 0x10, 0x0, 0xb, 0x9d, 0x60, 0x0, - 0xb, 0xa3, 0xd0, 0x0, 0xb, 0x50, 0xd3, 0x0, - 0xb, 0x50, 0x6a, 0x0, 0xb, 0x50, 0xe, 0x10, - 0xb, 0x50, 0x9, 0x70, 0x4e, 0xa1, 0xa, 0xf5, - - /* U+004C "L" */ - 0x2c, 0xc3, 0x0, 0x0, 0x8, 0x80, 0x0, 0x0, - 0x8, 0x80, 0x0, 0x0, 0x8, 0x80, 0x0, 0x0, - 0x8, 0x80, 0x0, 0x0, 0x8, 0x80, 0x0, 0x0, - 0x8, 0x80, 0x0, 0x0, 0x8, 0x80, 0x0, 0x0, - 0x8, 0x80, 0x0, 0x0, 0x8, 0x80, 0x0, 0x4, - 0x8, 0x80, 0x0, 0x63, 0x3c, 0xc6, 0x69, 0xf0, - - /* U+004D "M" */ - 0x7f, 0x0, 0x4, 0xf6, 0x1f, 0x30, 0x7, 0xf0, - 0x1c, 0x60, 0x6, 0xf0, 0x19, 0x90, 0x6, 0xf0, - 0x16, 0xc0, 0x14, 0xf0, 0x15, 0xd0, 0x51, 0xf0, - 0x15, 0xb3, 0x60, 0xf0, 0x15, 0x86, 0x60, 0xf0, - 0x15, 0x49, 0x60, 0xf0, 0x15, 0x1e, 0x40, 0xf0, - 0x15, 0xe, 0x10, 0xf0, 0x7a, 0x9, 0x6, 0xf6, - - /* U+004E "N" */ - 0x5f, 0x40, 0x4, 0xc6, 0xb, 0xc0, 0x0, 0x60, - 0x6, 0xd3, 0x0, 0x60, 0x6, 0x6a, 0x0, 0x60, - 0x6, 0xe, 0x20, 0x60, 0x6, 0x8, 0x90, 0x60, - 0x6, 0x1, 0xe1, 0x60, 0x6, 0x0, 0x98, 0x60, - 0x6, 0x0, 0x2e, 0x60, 0x6, 0x0, 0xb, 0xc0, - 0x6, 0x0, 0x3, 0xd0, 0x6c, 0x40, 0x0, 0x90, - - /* U+004F "O" */ - 0x0, 0x68, 0x87, 0x0, 0x5, 0x90, 0x6, 0x70, - 0xd, 0x20, 0x0, 0xe0, 0x2e, 0x0, 0x0, 0xd3, - 0x5c, 0x0, 0x0, 0xb6, 0x6c, 0x0, 0x0, 0xa8, - 0x6c, 0x0, 0x0, 0xa8, 0x5c, 0x0, 0x0, 0xa7, - 0x2e, 0x0, 0x0, 0xc4, 0xd, 0x20, 0x0, 0xe0, - 0x4, 0x80, 0x5, 0x70, 0x0, 0x57, 0x77, 0x0, - - /* U+0050 "P" */ - 0x3d, 0xb6, 0x79, 0x20, 0xa, 0x60, 0x1, 0xd0, - 0xa, 0x60, 0x0, 0xc4, 0xa, 0x60, 0x0, 0xb5, - 0xa, 0x60, 0x0, 0xd2, 0xa, 0x60, 0x6, 0xa0, - 0xa, 0xa6, 0x76, 0x0, 0xa, 0x60, 0x0, 0x0, - 0xa, 0x60, 0x0, 0x0, 0xa, 0x60, 0x0, 0x0, - 0xa, 0x60, 0x0, 0x0, 0x4d, 0xb2, 0x0, 0x0, - - /* U+0051 "Q" */ - 0x0, 0x88, 0x87, 0x0, 0x7, 0x80, 0x6, 0x60, - 0xe, 0x10, 0x0, 0xe0, 0x3d, 0x0, 0x0, 0xd3, - 0x6b, 0x0, 0x0, 0xb6, 0x7b, 0x0, 0x0, 0xb7, - 0x7b, 0x0, 0x0, 0xb7, 0x6b, 0x0, 0x0, 0xb6, - 0x4d, 0x5b, 0x60, 0xd4, 0xf, 0x90, 0xd1, 0xe0, - 0x7, 0x90, 0x9c, 0x80, 0x0, 0x78, 0xbe, 0x0, - 0x0, 0x0, 0xd, 0xe1, 0x0, 0x0, 0x0, 0x0, - - /* U+0052 "R" */ - 0x3c, 0xb6, 0x7a, 0x20, 0x9, 0x70, 0x5, 0xc0, - 0x9, 0x70, 0x0, 0xf0, 0x9, 0x70, 0x1, 0xf0, - 0x9, 0x70, 0x8, 0x80, 0x9, 0xa6, 0xc5, 0x0, - 0x9, 0x70, 0xd1, 0x0, 0x9, 0x70, 0x87, 0x0, - 0x9, 0x70, 0x3c, 0x0, 0x9, 0x70, 0xe, 0x20, - 0x9, 0x70, 0x8, 0x70, 0x3c, 0xc2, 0x3, 0xe4, - - /* U+0053 "S" */ - 0x1, 0x77, 0x9f, 0x70, 0xa, 0x0, 0x5, 0x90, - 0x1a, 0x0, 0x0, 0x40, 0x1c, 0x0, 0x0, 0x0, - 0xb, 0xb2, 0x0, 0x0, 0x0, 0x9f, 0x91, 0x0, - 0x0, 0x2, 0xae, 0x20, 0x0, 0x0, 0x7, 0xb0, - 0x0, 0x0, 0x0, 0xe0, 0x35, 0x0, 0x0, 0xd0, - 0xd, 0x10, 0x3, 0x90, 0xe, 0xe8, 0x78, 0x0, - - /* U+0054 "T" */ - 0x1e, 0x8c, 0xb8, 0xe0, 0x54, 0x9, 0x70, 0x53, - 0x40, 0x9, 0x70, 0x3, 0x0, 0x9, 0x70, 0x0, - 0x0, 0x9, 0x70, 0x0, 0x0, 0x9, 0x70, 0x0, - 0x0, 0x9, 0x70, 0x0, 0x0, 0x9, 0x70, 0x0, - 0x0, 0x9, 0x70, 0x0, 0x0, 0x9, 0x70, 0x0, - 0x0, 0x9, 0x70, 0x0, 0x0, 0x4c, 0xb3, 0x0, - - /* U+0055 "U" */ - 0x5f, 0x90, 0x4, 0xc4, 0xe, 0x20, 0x0, 0x60, - 0xe, 0x20, 0x0, 0x60, 0xe, 0x20, 0x0, 0x60, - 0xe, 0x20, 0x0, 0x60, 0xe, 0x20, 0x0, 0x60, - 0xe, 0x20, 0x0, 0x60, 0xe, 0x20, 0x0, 0x60, - 0xe, 0x20, 0x0, 0x60, 0xc, 0x20, 0x0, 0x50, - 0x8, 0x60, 0x3, 0x40, 0x0, 0x98, 0x86, 0x0, - - /* U+0056 "V" */ - 0x5f, 0x90, 0x5, 0xe4, 0xb, 0x50, 0x0, 0x70, - 0x8, 0x80, 0x4, 0x30, 0x4, 0xb0, 0x7, 0x0, - 0x1, 0xf0, 0x7, 0x0, 0x0, 0xd2, 0x7, 0x0, - 0x0, 0xa6, 0x34, 0x0, 0x0, 0x69, 0x60, 0x0, - 0x0, 0x3c, 0x70, 0x0, 0x0, 0xf, 0x70, 0x0, - 0x0, 0xc, 0x40, 0x0, 0x0, 0x8, 0x10, 0x0, - - /* U+0057 "W" */ - 0x8d, 0x2b, 0xc0, 0xa8, 0x2b, 0x5, 0x90, 0x50, - 0xd, 0x3, 0xb0, 0x60, 0xd, 0x4, 0xd0, 0x60, - 0xc, 0x17, 0xe0, 0x60, 0xa, 0x37, 0xd1, 0x60, - 0x8, 0x57, 0xa5, 0x40, 0x5, 0x86, 0x89, 0x20, - 0x3, 0xd3, 0x6d, 0x0, 0x1, 0xf1, 0x4d, 0x0, - 0x0, 0xd0, 0x2a, 0x0, 0x0, 0x80, 0x7, 0x0, - - /* U+0058 "X" */ - 0x2c, 0xc1, 0x9, 0xb2, 0x4, 0xb0, 0x6, 0x10, - 0x0, 0xd2, 0x7, 0x0, 0x0, 0x78, 0x43, 0x0, - 0x0, 0x1d, 0x80, 0x0, 0x0, 0xa, 0x70, 0x0, - 0x0, 0x8, 0xc0, 0x0, 0x0, 0x8, 0xd2, 0x0, - 0x0, 0x62, 0x79, 0x0, 0x0, 0x80, 0x1e, 0x0, - 0x3, 0x50, 0xa, 0x60, 0x3d, 0x70, 0xb, 0xe4, - - /* U+0059 "Y" */ - 0x4f, 0xa0, 0x7, 0xe4, 0x9, 0x70, 0x2, 0x50, - 0x3, 0xc0, 0x6, 0x0, 0x0, 0xe1, 0x7, 0x0, - 0x0, 0x86, 0x24, 0x0, 0x0, 0x3c, 0x60, 0x0, - 0x0, 0xd, 0x70, 0x0, 0x0, 0x9, 0x70, 0x0, - 0x0, 0x9, 0x70, 0x0, 0x0, 0x9, 0x70, 0x0, - 0x0, 0x9, 0x70, 0x0, 0x0, 0x4c, 0xb3, 0x0, - - /* U+005A "Z" */ - 0x8, 0xd7, 0x67, 0xf1, 0xb, 0x10, 0x7, 0x90, - 0x3, 0x0, 0xe, 0x20, 0x0, 0x0, 0x6a, 0x0, - 0x0, 0x0, 0xd2, 0x0, 0x0, 0x5, 0xb0, 0x0, - 0x0, 0xd, 0x30, 0x0, 0x0, 0x4c, 0x0, 0x0, - 0x0, 0xc4, 0x0, 0x0, 0x4, 0xc0, 0x0, 0x31, - 0xb, 0x50, 0x0, 0xa0, 0x3f, 0x66, 0x6b, 0xb0, - - /* U+005B "[" */ - 0xa9, 0x98, 0xa0, 0x0, 0xa0, 0x0, 0xa0, 0x0, - 0xa0, 0x0, 0xa0, 0x0, 0xa0, 0x0, 0xa0, 0x0, - 0xa0, 0x0, 0xa0, 0x0, 0xa0, 0x0, 0xa0, 0x0, - 0xa0, 0x0, 0xa0, 0x0, 0xa9, 0x98, - - /* U+005C "\\" */ - 0xa1, 0x0, 0x0, 0x4, 0x70, 0x0, 0x0, 0xb, - 0x0, 0x0, 0x0, 0x83, 0x0, 0x0, 0x2, 0x90, - 0x0, 0x0, 0xb, 0x0, 0x0, 0x0, 0x65, 0x0, - 0x0, 0x1, 0xa0, 0x0, 0x0, 0xa, 0x10, 0x0, - 0x0, 0x56, 0x0, 0x0, 0x0, 0xb0, 0x0, 0x0, - 0x9, 0x20, 0x0, 0x0, 0x38, 0x0, 0x0, 0x0, - 0xb0, 0x0, 0x0, 0x4, 0x10, - - /* U+005D "]" */ - 0x89, 0x99, 0x0, 0xa, 0x0, 0xa, 0x0, 0xa, - 0x0, 0xa, 0x0, 0xa, 0x0, 0xa, 0x0, 0xa, - 0x0, 0xa, 0x0, 0xa, 0x0, 0xa, 0x0, 0xa, - 0x0, 0xa, 0x0, 0xa, 0x99, 0x99, - - /* U+005E "^" */ - 0x2, 0xdd, 0x20, 0x7, 0x1, 0x70, - - /* U+005F "_" */ - 0x66, 0x66, 0x66, 0x66, - - /* U+0060 "`" */ - 0x3c, 0x90, 0x0, 0x43, - - /* U+0061 "a" */ - 0x2, 0x86, 0x68, 0x0, 0xd, 0x20, 0x9, 0x40, - 0x5, 0x0, 0x8, 0x50, 0x0, 0x68, 0x6a, 0x60, - 0xb, 0x50, 0x8, 0x60, 0x3d, 0x0, 0x8, 0x60, - 0x3e, 0x0, 0x9, 0x63, 0x7, 0x97, 0x76, 0xb4, - - /* U+0062 "b" */ - 0x2, 0x10, 0x0, 0x0, 0x4e, 0x30, 0x0, 0x0, - 0xb, 0x30, 0x0, 0x0, 0xb, 0x30, 0x0, 0x0, - 0xb, 0x30, 0x0, 0x0, 0xb, 0x48, 0x9b, 0x10, - 0xb, 0xa0, 0x5, 0xa0, 0xb, 0x40, 0x0, 0xf0, - 0xb, 0x30, 0x0, 0xe1, 0xb, 0x30, 0x0, 0xe1, - 0xb, 0x30, 0x0, 0xe0, 0xb, 0x60, 0x5, 0x80, - 0x8, 0x57, 0x89, 0x0, - - /* U+0063 "c" */ - 0x0, 0x67, 0x69, 0x0, 0x59, 0x0, 0x87, 0xc, - 0x20, 0x4, 0x30, 0xf0, 0x0, 0x0, 0xf, 0x0, - 0x0, 0x0, 0xd2, 0x0, 0x3, 0x6, 0x80, 0x0, - 0x60, 0x8, 0xa8, 0x80, - - /* U+0064 "d" */ - 0x0, 0x0, 0x0, 0x30, 0x0, 0x0, 0x2a, 0xa0, - 0x0, 0x0, 0x4, 0xa0, 0x0, 0x0, 0x4, 0xa0, - 0x0, 0x0, 0x4, 0xa0, 0x0, 0x89, 0x87, 0xa0, - 0x6, 0x80, 0x6, 0xa0, 0xd, 0x20, 0x4, 0xa0, - 0xf, 0x0, 0x4, 0xa0, 0xf, 0x0, 0x4, 0xa0, - 0xe, 0x10, 0x4, 0xa0, 0x7, 0x60, 0x9, 0xa0, - 0x0, 0x99, 0x86, 0xc3, - - /* U+0065 "e" */ - 0x6, 0x87, 0x90, 0x4, 0x70, 0x5, 0xa0, 0xb1, - 0x0, 0xf, 0xe, 0x66, 0x66, 0xb0, 0xe0, 0x0, - 0x0, 0xc, 0x30, 0x0, 0x20, 0x5a, 0x0, 0x16, - 0x0, 0x7a, 0x87, 0x0, - - /* U+0066 "f" */ - 0x0, 0x2, 0x76, 0xa2, 0x0, 0xb, 0x0, 0x87, - 0x0, 0x2b, 0x0, 0x0, 0x0, 0x3b, 0x0, 0x0, - 0x6, 0x8d, 0x66, 0x20, 0x0, 0x3b, 0x0, 0x0, - 0x0, 0x3b, 0x0, 0x0, 0x0, 0x3b, 0x0, 0x0, - 0x0, 0x3b, 0x0, 0x0, 0x0, 0x3b, 0x0, 0x0, - 0x0, 0x3b, 0x0, 0x0, 0x5, 0x9e, 0x64, 0x0, - - /* U+0067 "g" */ - 0x0, 0x86, 0x88, 0xb6, 0x7, 0x50, 0xb, 0x21, - 0xa, 0x30, 0x9, 0x40, 0x4, 0x80, 0xb, 0x10, - 0x3, 0x86, 0x72, 0x0, 0x8, 0x84, 0x10, 0x0, - 0x3, 0xaa, 0xde, 0x70, 0xc, 0x0, 0x0, 0xe0, - 0xc, 0x0, 0x0, 0xb0, 0x3, 0x86, 0x68, 0x30, - - /* U+0068 "h" */ - 0x3d, 0x40, 0x0, 0x0, 0xa, 0x40, 0x0, 0x0, - 0xa, 0x40, 0x0, 0x0, 0xa, 0x40, 0x0, 0x0, - 0xa, 0x59, 0x9b, 0x10, 0xa, 0xb0, 0x6, 0x70, - 0xa, 0x40, 0x4, 0x90, 0xa, 0x40, 0x4, 0xa0, - 0xa, 0x40, 0x4, 0xa0, 0xa, 0x40, 0x4, 0xa0, - 0xa, 0x40, 0x4, 0xa0, 0x3d, 0xa0, 0xa, 0xd3, - - /* U+0069 "i" */ - 0x0, 0x8a, 0x0, 0x0, 0x56, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x22, 0x0, 0x26, 0xc7, 0x0, 0x0, - 0x77, 0x0, 0x0, 0x77, 0x0, 0x0, 0x77, 0x0, - 0x0, 0x77, 0x0, 0x0, 0x77, 0x0, 0x0, 0x77, - 0x0, 0x26, 0xbc, 0x62, - - /* U+006A "j" */ - 0x0, 0x0, 0xd5, 0x0, 0x0, 0x92, 0x0, 0x0, - 0x0, 0x0, 0x0, 0x31, 0x0, 0x36, 0xe3, 0x0, - 0x0, 0xb3, 0x0, 0x0, 0xb3, 0x0, 0x0, 0xb3, - 0x0, 0x0, 0xb3, 0x0, 0x0, 0xb3, 0x0, 0x0, - 0xb2, 0x0, 0x0, 0xb1, 0x73, 0x0, 0xb0, 0x6c, - 0x88, 0x10, - - /* U+006B "k" */ - 0x3c, 0x50, 0x0, 0x0, 0x9, 0x50, 0x0, 0x0, - 0x9, 0x50, 0x0, 0x0, 0x9, 0x50, 0x0, 0x0, - 0x9, 0x50, 0x4e, 0x70, 0x9, 0x50, 0x63, 0x0, - 0x9, 0x54, 0x70, 0x0, 0x9, 0x7c, 0x80, 0x0, - 0x9, 0xb0, 0xd2, 0x0, 0x9, 0x50, 0x5a, 0x0, - 0x9, 0x50, 0xc, 0x30, 0x2c, 0xa1, 0xb, 0xd3, - - /* U+006C "l" */ - 0x26, 0xb7, 0x0, 0x0, 0x77, 0x0, 0x0, 0x77, - 0x0, 0x0, 0x77, 0x0, 0x0, 0x77, 0x0, 0x0, - 0x77, 0x0, 0x0, 0x77, 0x0, 0x0, 0x77, 0x0, - 0x0, 0x77, 0x0, 0x0, 0x77, 0x0, 0x0, 0x77, - 0x0, 0x26, 0xbb, 0x62, - - /* U+006D "m" */ - 0x8b, 0x7b, 0x68, 0xc1, 0x3d, 0x6, 0xa0, 0x94, - 0x3b, 0x6, 0x80, 0x95, 0x3b, 0x6, 0x80, 0x95, - 0x3b, 0x6, 0x80, 0x95, 0x3b, 0x6, 0x80, 0x95, - 0x3b, 0x6, 0x80, 0x95, 0x8d, 0x2b, 0xc2, 0xc9, - - /* U+006E "n" */ - 0x3d, 0x58, 0x8a, 0x10, 0xa, 0xa0, 0x6, 0x70, - 0xa, 0x40, 0x4, 0x90, 0xa, 0x40, 0x4, 0xa0, - 0xa, 0x40, 0x4, 0xa0, 0xa, 0x40, 0x4, 0xa0, - 0xa, 0x40, 0x4, 0xa0, 0x3d, 0xa0, 0xa, 0xd3, - - /* U+006F "o" */ - 0x0, 0x87, 0x78, 0x0, 0x7, 0x60, 0x6, 0x70, - 0xd, 0x0, 0x0, 0xd0, 0x2c, 0x0, 0x0, 0xd2, - 0x2c, 0x0, 0x0, 0xc2, 0xd, 0x0, 0x0, 0xd0, - 0x8, 0x50, 0x4, 0x80, 0x0, 0x87, 0x77, 0x0, - - /* U+0070 "p" */ - 0x5e, 0x59, 0x89, 0x10, 0xa, 0xa0, 0x3, 0xc0, - 0xa, 0x40, 0x0, 0xe1, 0xa, 0x40, 0x0, 0xc3, - 0xa, 0x40, 0x0, 0xc2, 0xa, 0x40, 0x0, 0xe0, - 0xa, 0x70, 0x5, 0x90, 0xa, 0x87, 0x8a, 0x0, - 0xa, 0x40, 0x0, 0x0, 0x3d, 0xa2, 0x0, 0x0, - - /* U+0071 "q" */ - 0x0, 0x88, 0x74, 0x70, 0x7, 0x60, 0x8, 0x90, - 0xe, 0x0, 0x5, 0x90, 0x1d, 0x0, 0x5, 0x90, - 0x2d, 0x0, 0x5, 0x90, 0xe, 0x0, 0x5, 0x90, - 0x9, 0x40, 0x9, 0x90, 0x1, 0xa9, 0x87, 0x90, - 0x0, 0x0, 0x5, 0x90, 0x0, 0x0, 0x2a, 0xd3, - - /* U+0072 "r" */ - 0x38, 0xe3, 0x58, 0xd2, 0x0, 0xb7, 0x40, 0x82, - 0x0, 0xb8, 0x0, 0x0, 0x0, 0xb3, 0x0, 0x0, - 0x0, 0xb3, 0x0, 0x0, 0x0, 0xb3, 0x0, 0x0, - 0x0, 0xb3, 0x0, 0x0, 0x36, 0xe9, 0x60, 0x0, - - /* U+0073 "s" */ - 0x6, 0x68, 0xe6, 0x46, 0x0, 0x28, 0x59, 0x0, - 0x2, 0xa, 0xd7, 0x10, 0x0, 0x29, 0xe3, 0x40, - 0x0, 0x3b, 0x92, 0x0, 0xa, 0x8e, 0x86, 0x72, - - /* U+0074 "t" */ - 0x0, 0x30, 0x0, 0x0, 0x80, 0x0, 0x5, 0xb0, - 0x0, 0x67, 0xd6, 0x61, 0x2, 0xc0, 0x0, 0x2, - 0xc0, 0x0, 0x2, 0xc0, 0x0, 0x2, 0xc0, 0x0, - 0x1, 0xc0, 0x1, 0x0, 0xd0, 0x6, 0x0, 0x7a, - 0x81, - - /* U+0075 "u" */ - 0x4e, 0x30, 0x1a, 0x90, 0xb, 0x30, 0x5, 0x90, - 0xb, 0x30, 0x5, 0x90, 0xb, 0x30, 0x5, 0x90, - 0xb, 0x30, 0x5, 0x90, 0xa, 0x30, 0x5, 0x90, - 0x8, 0x50, 0xa, 0x90, 0x1, 0xca, 0x96, 0xb3, - - /* U+0076 "v" */ - 0x2c, 0xb1, 0x9, 0xc2, 0x4, 0x90, 0x5, 0x20, - 0x0, 0xd0, 0x7, 0x0, 0x0, 0xb3, 0x7, 0x0, - 0x0, 0x68, 0x42, 0x0, 0x0, 0x1c, 0x60, 0x0, - 0x0, 0xc, 0x70, 0x0, 0x0, 0x7, 0x30, 0x0, - - /* U+0077 "w" */ - 0x9e, 0x2b, 0xb1, 0xb8, 0x1c, 0x4, 0x80, 0x70, - 0xc, 0x6, 0xb0, 0x60, 0x9, 0x26, 0xc0, 0x60, - 0x6, 0x66, 0xa4, 0x30, 0x2, 0xa4, 0x7b, 0x0, - 0x0, 0xf1, 0x4c, 0x0, 0x0, 0x90, 0x8, 0x0, - - /* U+0078 "x" */ - 0x8, 0xf5, 0x2c, 0x80, 0x0, 0xa5, 0x8, 0x0, - 0x0, 0x2e, 0x81, 0x0, 0x0, 0x9, 0x90, 0x0, - 0x0, 0x9, 0xd0, 0x0, 0x0, 0x44, 0x77, 0x0, - 0x0, 0x80, 0xd, 0x10, 0x2b, 0xb0, 0x2d, 0xc2, - - /* U+0079 "y" */ - 0x2b, 0xd2, 0x1a, 0xb2, 0x2, 0xc0, 0x7, 0x10, - 0x0, 0xc1, 0x8, 0x0, 0x0, 0x66, 0x16, 0x0, - 0x0, 0x1b, 0x61, 0x0, 0x0, 0xb, 0x90, 0x0, - 0x0, 0x5, 0x70, 0x0, 0x0, 0x5, 0x20, 0x0, - 0x2, 0x8, 0x0, 0x0, 0xb, 0xc3, 0x0, 0x0, - - /* U+007A "z" */ - 0xaa, 0x66, 0xe4, 0x90, 0x4, 0xb0, 0x30, 0xd, - 0x20, 0x0, 0x78, 0x0, 0x1, 0xd0, 0x0, 0xa, - 0x50, 0x5, 0x4c, 0x0, 0x9, 0xc9, 0x66, 0xc8, - - /* U+007B "{" */ - 0x0, 0x46, 0x1, 0x80, 0x3, 0x50, 0x4, 0x50, - 0x4, 0x50, 0x4, 0x50, 0x5, 0x40, 0x38, 0x0, - 0x27, 0x0, 0x5, 0x30, 0x4, 0x50, 0x4, 0x50, - 0x4, 0x50, 0x3, 0x50, 0x1, 0x80, 0x0, 0x46, - - /* U+007C "|" */ - 0x21, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, - 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, - 0x42, 0x42, - - /* U+007D "}" */ - 0x64, 0x0, 0x8, 0x10, 0x5, 0x30, 0x5, 0x40, - 0x5, 0x40, 0x5, 0x40, 0x4, 0x50, 0x0, 0x83, - 0x0, 0x72, 0x3, 0x50, 0x5, 0x40, 0x5, 0x40, - 0x5, 0x40, 0x5, 0x30, 0x8, 0x10, 0x64, 0x0, - - /* U+007E "~" */ - 0x4, 0x95, 0x0, 0x0, 0x5, 0xb, 0x30, 0x4, - 0x30, 0x1, 0xc1, 0x41, 0x0, 0x0, 0x3a, 0x50, - - /* U+007F "" */ - - /* U+3001 "、" */ - 0x3, 0x0, 0x0, 0x4d, 0x50, 0x0, 0x4f, 0x40, - 0x0, 0xa8, 0x0, 0x1, 0x0, - - /* U+3002 "。" */ - 0x4, 0x40, 0x74, 0x56, 0x80, 0x8, 0x48, 0x93, - 0x0, 0x0, - - /* U+3005 "々" */ - 0x0, 0x56, 0x0, 0x0, 0x0, 0x8, 0x60, 0x0, - 0x0, 0x0, 0xb0, 0x0, 0x15, 0x0, 0x5b, 0x86, - 0x58, 0xf1, 0x9, 0x21, 0x0, 0x85, 0x4, 0x0, - 0x0, 0xb, 0x0, 0x0, 0x0, 0x7, 0x30, 0x0, - 0x1, 0x0, 0x80, 0x0, 0x0, 0x9, 0xb1, 0x0, - 0x0, 0x0, 0xb, 0xa0, 0x0, 0x0, 0x0, 0x1e, - 0x20, 0x0, 0x0, 0x0, 0x20, 0x0, - - /* U+300C "「" */ - 0xda, 0xa8, 0xa0, 0x0, 0xa0, 0x0, 0xa0, 0x0, - 0xa0, 0x0, 0xa0, 0x0, 0xa0, 0x0, 0xa0, 0x0, - 0xa0, 0x0, 0xa0, 0x0, 0xa0, 0x0, 0xa0, 0x0, - 0xa0, 0x0, 0xa0, 0x0, - - /* U+300D "」" */ - 0x0, 0xa, 0x0, 0xa, 0x0, 0xa, 0x0, 0xa, - 0x0, 0xa, 0x0, 0xa, 0x0, 0xa, 0x0, 0xa, - 0x0, 0xa, 0x0, 0xa, 0x0, 0xa, 0x0, 0xa, - 0x0, 0xa, 0x8a, 0xad, - - /* U+3041 "ぁ" */ - 0x0, 0x3, 0x30, 0x0, 0x0, 0x0, 0x5, 0x61, - 0x50, 0x0, 0x2, 0x6b, 0xa8, 0x30, 0x0, 0x0, - 0x7, 0x3, 0x0, 0x0, 0x0, 0x8, 0x7c, 0x78, - 0x20, 0x0, 0x6c, 0x18, 0x0, 0xb0, 0x5, 0x56, - 0x92, 0x0, 0xb0, 0x8, 0x6, 0x80, 0x0, 0xa0, - 0xb, 0x87, 0xa0, 0xa, 0x20, 0x1, 0x20, 0x5, - 0x71, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - - /* U+3042 "あ" */ - 0x0, 0x0, 0x50, 0x0, 0x0, 0x0, 0x0, 0x0, - 0xc3, 0x0, 0x0, 0x0, 0x0, 0x0, 0xb1, 0x6b, - 0x40, 0x0, 0x4, 0x8a, 0xea, 0x51, 0x0, 0x0, - 0x0, 0x0, 0xb0, 0x30, 0x0, 0x0, 0x0, 0x0, - 0xa2, 0xca, 0x73, 0x0, 0x0, 0x4, 0xe6, 0xc1, - 0x29, 0x80, 0x0, 0x6a, 0xa2, 0xa0, 0x0, 0xc1, - 0x6, 0x90, 0xaa, 0x20, 0x0, 0x94, 0xb, 0x0, - 0xd8, 0x0, 0x0, 0xb1, 0x47, 0x3, 0xf3, 0x0, - 0x2, 0xa0, 0x2b, 0x89, 0x4a, 0x0, 0x2b, 0x10, - 0x3, 0x20, 0x0, 0x17, 0x80, 0x0, 0x0, 0x0, - 0x1, 0x40, 0x0, 0x0, - - /* U+3043 "ぃ" */ - 0xa, 0x0, 0x0, 0x0, 0x0, 0xb, 0x0, 0x0, - 0x34, 0x0, 0x9, 0x0, 0x0, 0x7, 0x40, 0x9, - 0x0, 0x0, 0x0, 0xb0, 0xa, 0x3, 0x0, 0x5, - 0xd0, 0x9, 0x93, 0x0, 0x2, 0x60, 0x1, 0xa0, - 0x0, 0x0, 0x0, - - /* U+3044 "い" */ - 0x29, 0x0, 0x0, 0x0, 0x0, 0x0, 0x1e, 0x0, - 0x0, 0x0, 0x60, 0x0, 0x49, 0x0, 0x0, 0x0, - 0x1a, 0x10, 0x66, 0x0, 0x0, 0x0, 0x2, 0xb0, - 0x75, 0x0, 0x0, 0x0, 0x0, 0xc1, 0x76, 0x3, - 0x0, 0x0, 0x20, 0xa3, 0x3c, 0x9, 0x0, 0x0, - 0x1b, 0xf1, 0xa, 0xd7, 0x0, 0x0, 0x0, 0x50, - 0x0, 0xa4, 0x0, 0x0, 0x0, 0x0, - - /* U+3046 "う" */ - 0x0, 0x5, 0x86, 0x30, 0x0, 0x0, 0x1, 0xce, - 0x30, 0x0, 0x0, 0x10, 0x0, 0x0, 0x0, 0x3, - 0x9a, 0x50, 0x0, 0x4a, 0x71, 0xa, 0x41, 0xb9, - 0x10, 0x0, 0x49, 0x0, 0x0, 0x0, 0x3, 0x90, - 0x0, 0x0, 0x0, 0x67, 0x0, 0x0, 0x0, 0xa, - 0x30, 0x0, 0x0, 0x3, 0xb0, 0x0, 0x0, 0x1, - 0xc1, 0x0, 0x0, 0x5, 0xa1, 0x0, 0x0, 0x6, - 0x30, 0x0, 0x0, - - /* U+3047 "ぇ" */ - 0x0, 0x0, 0x0, 0x0, 0x0, 0x5, 0x81, 0x0, - 0x0, 0x2, 0x71, 0x0, 0x0, 0x5, 0xb6, 0x0, - 0x9, 0x93, 0x93, 0x0, 0x0, 0x5, 0x60, 0x0, - 0x0, 0x39, 0x0, 0x0, 0x3, 0x96, 0x80, 0x0, - 0x4b, 0x0, 0xa0, 0x0, 0x90, 0x0, 0x99, 0xa6, - 0x0, 0x0, 0x0, 0x0, - - /* U+3048 "え" */ - 0x0, 0x0, 0x23, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x5e, 0x60, 0x0, 0x0, 0x0, 0x6, 0x84, 0x0, - 0x0, 0x0, 0x0, 0x6, 0x60, 0x0, 0x0, 0x3, - 0x78, 0x6d, 0x0, 0x0, 0x2c, 0x81, 0xb, 0x20, - 0x0, 0x0, 0x0, 0x9, 0x40, 0x0, 0x0, 0x0, - 0x5, 0x60, 0x0, 0x0, 0x0, 0x3, 0xd8, 0x10, - 0x0, 0x0, 0x1, 0xb1, 0x3a, 0x0, 0x0, 0x1, - 0xc2, 0x0, 0xc0, 0x0, 0x0, 0xe4, 0x0, 0xb, - 0x44, 0x88, 0x6, 0x0, 0x0, 0x17, 0x75, 0x10, - - /* U+304A "お" */ - 0x0, 0x13, 0x0, 0x0, 0x0, 0x0, 0x0, 0x1f, - 0x20, 0x0, 0x10, 0x0, 0x0, 0xd, 0x0, 0x0, - 0x4b, 0x90, 0x0, 0xc, 0x7d, 0x40, 0x6, 0xb4, - 0x29, 0xbe, 0x50, 0x0, 0x0, 0x0, 0x0, 0xc, - 0x4, 0x9a, 0x70, 0x0, 0x0, 0xd, 0xa5, 0x0, - 0x4b, 0x0, 0x0, 0x9d, 0x0, 0x0, 0x8, 0x50, - 0xa, 0x3c, 0x0, 0x0, 0x7, 0x70, 0x9, 0xc, - 0x5, 0x0, 0xc, 0x20, 0x1, 0xbf, 0x5, 0x86, - 0xb7, 0x0, 0x0, 0x4c, 0x0, 0x25, 0x10, 0x0, - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - - /* U+304B "か" */ - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0xc, 0x10, 0x0, 0x0, 0x0, 0x0, 0x0, - 0xf, 0x10, 0x0, 0x0, 0x0, 0x0, 0x0, 0x4a, - 0x0, 0x0, 0x0, 0x0, 0x1, 0x25, 0xcb, 0xac, - 0x20, 0x53, 0x0, 0xb, 0xb6, 0xd0, 0x6, 0x90, - 0x9, 0x50, 0x0, 0x6, 0x60, 0x5, 0x80, 0x0, - 0xe2, 0x0, 0xc, 0x0, 0x8, 0x50, 0x22, 0xb7, - 0x0, 0x66, 0x0, 0xc, 0x10, 0x9, 0xf4, 0x1, - 0xc0, 0x0, 0x2c, 0x0, 0x0, 0x20, 0xc, 0x40, - 0x86, 0xc5, 0x0, 0x0, 0x0, 0x6, 0x0, 0x3f, - 0x80, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x0, - - /* U+304C "が" */ - 0x0, 0x0, 0x0, 0x0, 0x0, 0xa, 0x50, 0x0, - 0x0, 0x8, 0x0, 0x3, 0x11, 0x80, 0x0, 0x0, - 0xe, 0x30, 0x1, 0xd2, 0x0, 0x0, 0x0, 0x2c, - 0x0, 0x0, 0x20, 0x0, 0x0, 0x0, 0x9a, 0x98, - 0x1, 0x10, 0x0, 0xb, 0xdb, 0xe2, 0x9, 0x70, - 0x84, 0x0, 0x0, 0x5, 0x70, 0x7, 0x60, 0xb, - 0x50, 0x0, 0xc, 0x10, 0xa, 0x30, 0x2, 0xe0, - 0x0, 0x48, 0x0, 0xd, 0x0, 0x43, 0xe3, 0x0, - 0xc1, 0x0, 0x3a, 0x0, 0x1b, 0xf1, 0x9, 0x71, - 0x60, 0xb4, 0x0, 0x0, 0x30, 0xb, 0x0, 0x6f, - 0xb0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x5, 0x0, - 0x0, 0x0, 0x0, - - /* U+304D "き" */ - 0x0, 0x47, 0x0, 0x0, 0x0, 0x0, 0x1e, 0x10, - 0x25, 0x0, 0x0, 0x5, 0x99, 0xa1, 0x0, 0x4, - 0x9a, 0xd4, 0x0, 0x10, 0x0, 0x0, 0x3a, 0x2a, - 0x70, 0x0, 0x2, 0x5e, 0xb2, 0x0, 0x0, 0x67, - 0x53, 0xc0, 0x0, 0x0, 0x0, 0x10, 0x5a, 0x0, - 0x7, 0xb9, 0x9b, 0xbe, 0x70, 0x4b, 0x0, 0x0, - 0x18, 0xb0, 0x4a, 0x0, 0x0, 0x0, 0x0, 0xc, - 0x70, 0x0, 0x21, 0x0, 0x0, 0x8d, 0xed, 0xa2, - 0x0, - - /* U+304E "ぎ" */ - 0x0, 0x33, 0x0, 0x0, 0x1, 0x78, 0x0, 0x5, - 0xd0, 0x1, 0x20, 0xb5, 0x90, 0x0, 0xa, 0x47, - 0xc4, 0x1, 0x70, 0x0, 0x56, 0xae, 0x40, 0x0, - 0x0, 0x0, 0x1, 0x20, 0x84, 0x3c, 0x60, 0x0, - 0x0, 0x0, 0x16, 0xf9, 0x10, 0x0, 0x0, 0x1, - 0x77, 0x54, 0x90, 0x0, 0x0, 0x0, 0x0, 0x11, - 0x7, 0x70, 0x0, 0x0, 0x7, 0xca, 0x9b, 0xbf, - 0x50, 0x0, 0x4, 0xa0, 0x0, 0x0, 0x78, 0x0, - 0x0, 0x58, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0xc8, 0x32, 0x58, 0x40, 0x0, 0x0, 0x0, 0x7b, - 0xb9, 0x50, 0x0, 0x0, 0x0, - - /* U+304F "く" */ - 0x0, 0x0, 0x0, 0x0, 0x0, 0x1, 0xe2, 0x0, - 0x0, 0x7d, 0x10, 0x0, 0x3d, 0x10, 0x0, 0x2b, - 0x10, 0x0, 0x2a, 0x0, 0x0, 0x9, 0x0, 0x0, - 0x0, 0x80, 0x0, 0x0, 0x1, 0xa3, 0x0, 0x0, - 0x0, 0xb6, 0x0, 0x0, 0x0, 0xd8, 0x0, 0x0, - 0x4, 0xf4, 0x0, 0x0, 0xc, 0x80, 0x0, 0x0, - 0x22, - - /* U+3050 "ぐ" */ - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x6, - 0x90, 0x0, 0x0, 0x0, 0x0, 0xcb, 0x0, 0x22, - 0x0, 0x0, 0x8a, 0x0, 0x10, 0xc4, 0x0, 0x59, - 0x0, 0x6, 0xa1, 0x10, 0x39, 0x0, 0x0, 0x7, - 0x0, 0x18, 0x0, 0x0, 0x0, 0x0, 0x3, 0x70, - 0x0, 0x0, 0x0, 0x0, 0x3, 0xa1, 0x0, 0x0, - 0x0, 0x0, 0x2, 0xd2, 0x0, 0x0, 0x0, 0x0, - 0x3, 0xe3, 0x0, 0x0, 0x0, 0x0, 0x9, 0xd0, - 0x0, 0x0, 0x0, 0x0, 0x1f, 0x20, 0x0, 0x0, - 0x0, 0x0, 0x50, 0x0, 0x0, - - /* U+3051 "け" */ - 0x6, 0x10, 0x0, 0x0, 0xb2, 0x0, 0xb, 0x60, - 0x0, 0x0, 0xc4, 0x0, 0xc, 0x20, 0x0, 0x0, - 0xa3, 0x23, 0xc, 0x0, 0x6, 0x9a, 0xec, 0x95, - 0x48, 0x0, 0x0, 0x0, 0xa2, 0x0, 0x84, 0x0, - 0x0, 0x0, 0xa2, 0x0, 0xa2, 0x10, 0x0, 0x0, - 0xb1, 0x0, 0xa3, 0x60, 0x0, 0x0, 0xc0, 0x0, - 0x87, 0x90, 0x0, 0x1, 0xc0, 0x0, 0x2f, 0x80, - 0x0, 0x8, 0x60, 0x0, 0x8, 0x50, 0x0, 0x4a, - 0x0, 0x0, 0x0, 0x0, 0x6, 0x70, 0x0, 0x0, - 0x0, 0x0, 0x10, 0x0, 0x0, 0x0, - - /* U+3052 "げ" */ - 0x0, 0x0, 0x0, 0x0, 0x0, 0x1, 0x50, 0x1, - 0x0, 0x0, 0x0, 0x30, 0x34, 0x5b, 0xc, 0x40, - 0x0, 0x0, 0xe4, 0x9, 0x63, 0xc, 0x30, 0x0, - 0x0, 0xb3, 0x0, 0x20, 0xd, 0x0, 0x0, 0x2, - 0xba, 0xc6, 0x0, 0x48, 0x0, 0x7, 0x98, 0xc5, - 0x0, 0x0, 0x75, 0x0, 0x0, 0x0, 0x93, 0x0, - 0x0, 0x84, 0x0, 0x0, 0x0, 0xa2, 0x0, 0x0, - 0x84, 0x10, 0x0, 0x0, 0xb1, 0x0, 0x0, 0x76, - 0x70, 0x0, 0x0, 0xd0, 0x0, 0x0, 0x3c, 0x90, - 0x0, 0x5, 0x80, 0x0, 0x0, 0xd, 0x70, 0x0, - 0x1c, 0x10, 0x0, 0x0, 0x2, 0x10, 0x2, 0xa2, - 0x0, 0x0, 0x0, 0x0, 0x0, 0x15, 0x0, 0x0, - 0x0, 0x0, - - /* U+3053 "こ" */ - 0x0, 0x58, 0x9a, 0xc7, 0x0, 0x0, 0x0, 0x3c, - 0x71, 0x0, 0x0, 0x0, 0x50, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x1, 0x0, 0x0, 0x0, 0x0, 0x50, 0x0, - 0x0, 0x0, 0x0, 0x90, 0x0, 0x0, 0x0, 0x0, - 0x59, 0x0, 0x0, 0x3, 0x70, 0x6, 0xcc, 0xcd, - 0xfd, 0x70, 0x0, 0x0, 0x11, 0x0, 0x0, - - /* U+3054 "ご" */ - 0x0, 0x0, 0x0, 0x0, 0x0, 0x20, 0x0, 0x0, - 0x0, 0x0, 0x1, 0x16, 0xa0, 0x0, 0x32, 0x1, - 0x31, 0xb, 0x56, 0x0, 0x1, 0x7a, 0xdf, 0x90, - 0x16, 0x0, 0x0, 0x0, 0x58, 0x10, 0x0, 0x0, - 0x0, 0x0, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x0, 0x0, 0x2, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x4, 0x20, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x36, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x98, 0x42, 0x34, 0x8d, 0x20, 0x0, 0x0, 0x49, - 0xbc, 0xb8, 0x30, 0x0, 0x0, - - /* U+3055 "さ" */ - 0x0, 0x24, 0x0, 0x0, 0x0, 0x4, 0xc0, 0x0, - 0x0, 0x0, 0x5, 0xb0, 0x7, 0x40, 0x0, 0x9, - 0xcc, 0x70, 0x3, 0xaa, 0x8b, 0x50, 0x0, 0x0, - 0x0, 0xd, 0x20, 0x0, 0x1, 0x20, 0x3d, 0x0, - 0x7b, 0x99, 0xbb, 0xd7, 0x4a, 0x0, 0x0, 0x1b, - 0x96, 0x70, 0x0, 0x0, 0x1, 0x1d, 0x30, 0x0, - 0x0, 0x0, 0x2a, 0xdc, 0xcd, 0x0, 0x0, 0x0, - 0x22, 0x0, 0x0, - - /* U+3056 "ざ" */ - 0x0, 0x0, 0x0, 0x0, 0x0, 0x60, 0x0, 0x25, - 0x0, 0x0, 0x16, 0x5b, 0x0, 0x2d, 0x20, 0x0, - 0x7, 0x81, 0x0, 0x2, 0xc1, 0x6, 0xb0, 0x10, - 0x0, 0x1, 0x6d, 0xb7, 0x0, 0x0, 0x1, 0x67, - 0x77, 0xa0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x96, - 0x0, 0x0, 0x0, 0x1, 0x10, 0xd, 0x20, 0x0, - 0x6, 0xba, 0xac, 0xbb, 0xa0, 0x0, 0x2c, 0x0, - 0x0, 0x19, 0xd0, 0x0, 0x3a, 0x0, 0x0, 0x0, - 0x10, 0x0, 0xb, 0x70, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x8d, 0xee, 0xe2, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x0, 0x0, - - /* U+3057 "し" */ - 0x7, 0x10, 0x0, 0x0, 0x0, 0xf, 0x40, 0x0, - 0x0, 0x0, 0xe, 0x0, 0x0, 0x0, 0x0, 0xd, - 0x0, 0x0, 0x0, 0x0, 0xd, 0x0, 0x0, 0x0, - 0x0, 0xd, 0x0, 0x0, 0x0, 0x0, 0xc, 0x0, - 0x0, 0x0, 0x0, 0xc, 0x0, 0x0, 0x0, 0x0, - 0xd, 0x0, 0x0, 0x0, 0x1, 0xe, 0x0, 0x0, - 0x2, 0x90, 0xb, 0x40, 0x0, 0x7a, 0x0, 0x2, - 0xda, 0xad, 0x70, 0x0, 0x0, 0x2, 0x20, 0x0, - 0x0, - - /* U+3058 "じ" */ - 0x1a, 0x10, 0x0, 0x0, 0x0, 0xf, 0x10, 0x0, - 0x86, 0x0, 0xe, 0x0, 0x2a, 0x3c, 0x0, 0x1d, - 0x0, 0x4, 0x90, 0x0, 0x1c, 0x0, 0x0, 0x0, - 0x0, 0x2b, 0x0, 0x0, 0x0, 0x0, 0x2b, 0x0, - 0x0, 0x0, 0x0, 0x2b, 0x0, 0x0, 0x0, 0x0, - 0x2b, 0x0, 0x0, 0x0, 0x11, 0xd, 0x0, 0x0, - 0x4, 0x80, 0xb, 0x50, 0x1, 0x99, 0x0, 0x2, - 0xcc, 0xcb, 0x30, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, - - /* U+3059 "す" */ - 0x0, 0x0, 0x0, 0x3b, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, 0xe, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0xc, 0x13, 0x57, 0x40, 0x5, 0x57, 0x99, - 0x9e, 0x87, 0x65, 0x50, 0x3, 0x74, 0x10, 0xb, - 0x0, 0x0, 0x0, 0x0, 0x0, 0xa, 0xae, 0x0, - 0x0, 0x0, 0x0, 0x0, 0x56, 0xc, 0x20, 0x0, - 0x0, 0x0, 0x0, 0x74, 0xd, 0x30, 0x0, 0x0, - 0x0, 0x0, 0x3b, 0x8f, 0x10, 0x0, 0x0, 0x0, - 0x0, 0x3, 0x5c, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0xa4, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8, - 0x60, 0x0, 0x0, 0x0, 0x0, 0x0, 0x62, 0x0, - 0x0, 0x0, 0x0, - - /* U+305A "ず" */ - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x13, 0x0, - 0x0, 0x0, 0x1, 0x40, 0x0, 0x31, 0x6a, 0x0, - 0x0, 0x0, 0x1f, 0x20, 0x0, 0xc3, 0x40, 0x0, - 0x0, 0x0, 0xd0, 0x0, 0x1, 0x20, 0x0, 0x0, - 0x24, 0x7e, 0xaa, 0xbc, 0x80, 0x0, 0x7d, 0xb8, - 0x52, 0xb0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x5, - 0x7c, 0x0, 0x0, 0x0, 0x0, 0x0, 0x6, 0x81, - 0xd2, 0x0, 0x0, 0x0, 0x0, 0x0, 0x92, 0xb, - 0x50, 0x0, 0x0, 0x0, 0x0, 0x7, 0x60, 0xd4, - 0x0, 0x0, 0x0, 0x0, 0x0, 0xa, 0xbf, 0x10, - 0x0, 0x0, 0x0, 0x0, 0x0, 0x5, 0x90, 0x0, - 0x0, 0x0, 0x0, 0x0, 0x3, 0xb0, 0x0, 0x0, - 0x0, 0x0, 0x0, 0x5, 0x80, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, - - /* U+305B "せ" */ - 0x0, 0x0, 0x0, 0x0, 0x69, 0x0, 0x0, 0x0, - 0xe, 0x20, 0x3, 0xc0, 0x0, 0x0, 0x0, 0xb1, - 0x0, 0x2a, 0x0, 0x0, 0x0, 0xb, 0x12, 0x58, - 0xec, 0xd8, 0x7, 0x8a, 0xe9, 0x74, 0x49, 0x0, - 0x0, 0x33, 0xb, 0x10, 0x3, 0x80, 0x0, 0x0, - 0x0, 0xa1, 0x5, 0x96, 0x0, 0x0, 0x0, 0xa, - 0x20, 0x3c, 0x0, 0x0, 0x0, 0x0, 0x74, 0x0, - 0x0, 0x0, 0x0, 0x0, 0x2, 0xc2, 0x0, 0x13, - 0x0, 0x0, 0x0, 0x3, 0xac, 0xcb, 0x90, 0x0, - - /* U+305C "ぜ" */ - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x0, 0x0, 0x0, 0x11, 0xa2, 0x0, - 0x0, 0x0, 0x0, 0x29, 0x4, 0xa3, 0x70, 0x0, - 0xc, 0x40, 0x0, 0xf0, 0x7, 0x10, 0x0, 0x0, - 0xa4, 0x0, 0xc, 0x0, 0x0, 0x0, 0x0, 0x9, - 0x21, 0x46, 0xeb, 0xc8, 0x0, 0x5, 0x69, 0xdb, - 0x96, 0x4b, 0x0, 0x0, 0x0, 0x55, 0x29, 0x20, - 0x1, 0xa0, 0x0, 0x0, 0x0, 0x0, 0x92, 0x4, - 0x87, 0x0, 0x0, 0x0, 0x0, 0x8, 0x30, 0x1c, - 0x10, 0x0, 0x0, 0x0, 0x0, 0x75, 0x0, 0x0, - 0x0, 0x0, 0x0, 0x0, 0x2, 0xd3, 0x0, 0x2, - 0x10, 0x0, 0x0, 0x0, 0x3, 0xad, 0xdd, 0xc4, - 0x0, 0x0, - - /* U+305D "そ" */ - 0x0, 0x0, 0x0, 0x5, 0x10, 0x0, 0x1, 0x56, - 0x98, 0x9e, 0x0, 0x0, 0x8, 0x60, 0x3d, 0x40, - 0x0, 0x0, 0x0, 0x5a, 0x10, 0x0, 0x0, 0x0, - 0x86, 0x0, 0x2, 0x0, 0x4, 0x82, 0x48, 0xcc, - 0xa6, 0x2c, 0xe9, 0x85, 0xa4, 0x0, 0x1, 0x62, - 0x0, 0xa1, 0x0, 0x0, 0x0, 0x0, 0x74, 0x0, - 0x0, 0x0, 0x0, 0xa, 0x10, 0x0, 0x0, 0x0, - 0x0, 0x85, 0x0, 0x0, 0x0, 0x0, 0x1, 0xd9, - 0x63, 0x0, 0x0, 0x0, 0x0, 0x7b, 0x80, 0x0, - - /* U+305E "ぞ" */ - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x4a, 0x30, 0x17, 0x90, 0x0, 0x57, - 0x88, 0x5d, 0x90, 0x96, 0x52, 0x0, 0x15, 0x11, - 0xb4, 0x0, 0x9, 0x0, 0x0, 0x0, 0x3a, 0x10, - 0x0, 0x0, 0x0, 0x0, 0x5, 0x70, 0x0, 0x35, - 0x30, 0x0, 0x1, 0x85, 0x58, 0xbd, 0x97, 0x50, - 0x0, 0x4e, 0xc8, 0x35, 0x80, 0x0, 0x0, 0x0, - 0x1, 0x0, 0x49, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0xb0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0xc0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x97, - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xa, 0xda, - 0x60, 0x0, 0x0, 0x0, 0x0, 0x0, 0x37, 0x30, - 0x0, 0x0, - - /* U+305F "た" */ - 0x0, 0x4, 0x20, 0x0, 0x0, 0x0, 0x0, 0x9, - 0x90, 0x0, 0x0, 0x0, 0x0, 0xa, 0x34, 0x70, - 0x0, 0x0, 0x14, 0x5d, 0xc9, 0x20, 0x1, 0x0, - 0x4, 0x5c, 0x0, 0x38, 0x8c, 0xd1, 0x0, 0x39, - 0x0, 0x0, 0x68, 0x30, 0x0, 0x75, 0x0, 0x0, - 0x0, 0x0, 0x0, 0xb0, 0x0, 0x0, 0x0, 0x0, - 0x2, 0xa0, 0x3, 0x0, 0x0, 0x0, 0x9, 0x50, - 0x8, 0x0, 0x0, 0x0, 0x2d, 0x0, 0xa, 0x10, - 0x0, 0x0, 0x64, 0x0, 0x2, 0xab, 0xce, 0xd1, - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - - /* U+3060 "だ" */ - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x40, 0x0, 0x0, 0x8, 0x40, 0x0, 0x0, - 0xc5, 0x0, 0x1, 0x92, 0xc0, 0x0, 0x0, 0xc1, - 0x64, 0x0, 0x29, 0x0, 0x3, 0x35, 0xeb, 0x50, - 0x0, 0x10, 0x0, 0x1, 0x57, 0x90, 0x5, 0x98, - 0xd8, 0x0, 0x0, 0x6, 0x50, 0x0, 0x7, 0x84, - 0x0, 0x0, 0xb, 0x10, 0x0, 0x10, 0x0, 0x0, - 0x0, 0xc, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x58, 0x0, 0x30, 0x0, 0x0, 0x0, 0x0, 0xb2, - 0x2, 0x50, 0x0, 0x0, 0x0, 0x4, 0xb0, 0x2, - 0xa1, 0x0, 0x11, 0x0, 0x7, 0x30, 0x0, 0x4a, - 0xbc, 0xd9, 0x0, - - /* U+3061 "ち" */ - 0x0, 0x0, 0xb1, 0x0, 0x0, 0x0, 0x0, 0xe, - 0x0, 0x0, 0x0, 0x0, 0x2, 0xa3, 0x6a, 0x40, - 0x0, 0x7a, 0xdb, 0x75, 0x20, 0x0, 0x0, 0xa, - 0x10, 0x0, 0x0, 0x0, 0x0, 0xb0, 0x16, 0x98, - 0x30, 0x0, 0x58, 0x88, 0x30, 0x4d, 0x40, 0xa, - 0xd2, 0x0, 0x0, 0x5b, 0x0, 0x63, 0x0, 0x0, - 0x5, 0xa0, 0x0, 0x0, 0x0, 0x0, 0xc4, 0x0, - 0x0, 0x0, 0x4, 0xb5, 0x0, 0x0, 0x1, 0x56, - 0x40, 0x0, - - /* U+3063 "っ" */ - 0x0, 0x5, 0x99, 0x99, 0x10, 0x6b, 0xa5, 0x0, - 0x4, 0xa0, 0x2, 0x0, 0x0, 0x0, 0xd0, 0x0, - 0x0, 0x0, 0x0, 0xd0, 0x0, 0x0, 0x0, 0x6, - 0x80, 0x0, 0x0, 0x2, 0x99, 0x0, 0x0, 0x16, - 0x87, 0x10, 0x0, - - /* U+3064 "つ" */ - 0x0, 0x0, 0x5, 0xaa, 0xab, 0x70, 0x0, 0x25, - 0x9b, 0x50, 0x0, 0x6, 0xc0, 0x9, 0xc3, 0x0, - 0x0, 0x0, 0xb, 0x50, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x78, 0x0, 0x0, 0x0, 0x0, 0x0, 0x9, - 0x60, 0x0, 0x0, 0x0, 0x0, 0x0, 0xe1, 0x0, - 0x0, 0x0, 0x0, 0x0, 0xb6, 0x0, 0x0, 0x0, - 0x0, 0x5, 0xc5, 0x0, 0x0, 0x0, 0x36, 0x79, - 0x60, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, - - /* U+3065 "づ" */ - 0x0, 0x0, 0x0, 0x0, 0x0, 0x1, 0x0, 0x0, - 0x0, 0x0, 0x0, 0x0, 0x31, 0xb6, 0x0, 0x0, - 0x0, 0x0, 0x0, 0x2c, 0x24, 0x0, 0x0, 0x26, - 0x99, 0xaa, 0x44, 0x20, 0x4, 0x7b, 0x93, 0x0, - 0x0, 0xb4, 0x0, 0xb, 0x81, 0x0, 0x0, 0x0, - 0x3c, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x1d, - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x3b, 0x0, - 0x0, 0x0, 0x0, 0x0, 0x0, 0xa5, 0x0, 0x0, - 0x0, 0x0, 0x0, 0x8, 0x90, 0x0, 0x0, 0x0, - 0x0, 0x5, 0xb6, 0x0, 0x0, 0x0, 0x1, 0x68, - 0x84, 0x0, 0x0, 0x0, - - /* U+3066 "て" */ - 0x0, 0x0, 0x1, 0x48, 0xbd, 0xd1, 0x37, 0x8a, - 0xa8, 0x49, 0xb6, 0x30, 0x15, 0x30, 0x1, 0xb4, - 0x0, 0x0, 0x0, 0x0, 0xb, 0x20, 0x0, 0x0, - 0x0, 0x0, 0x67, 0x0, 0x0, 0x0, 0x0, 0x0, - 0xc0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xd0, 0x0, - 0x0, 0x0, 0x0, 0x0, 0xc0, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x95, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x1c, 0x61, 0x0, 0x0, 0x0, 0x0, 0x1, 0x8d, - 0xc0, 0x0, - - /* U+3067 "で" */ - 0x0, 0x0, 0x0, 0x37, 0xad, 0xfb, 0x0, 0x66, - 0x8a, 0xa6, 0x4a, 0x82, 0x0, 0x4, 0x74, 0x0, - 0x2c, 0x20, 0x11, 0x0, 0x0, 0x0, 0x1c, 0x10, - 0x20, 0x95, 0x0, 0x0, 0xb, 0x30, 0x2, 0xc2, - 0x60, 0x0, 0x2, 0xc0, 0x0, 0x5, 0x20, 0x0, - 0x0, 0x58, 0x0, 0x0, 0x0, 0x0, 0x0, 0x5, - 0x90, 0x0, 0x0, 0x0, 0x0, 0x0, 0x1d, 0x0, - 0x0, 0x0, 0x0, 0x0, 0x0, 0x7c, 0x41, 0x0, - 0x0, 0x0, 0x0, 0x0, 0x5c, 0xf9, 0x0, 0x0, - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - - /* U+3068 "と" */ - 0x0, 0x24, 0x0, 0x0, 0x0, 0x3, 0xe0, 0x0, - 0x0, 0x0, 0x3a, 0x0, 0x0, 0x0, 0x2, 0xa0, - 0x0, 0x20, 0x0, 0xc, 0x0, 0x6e, 0x50, 0x0, - 0x7b, 0xc7, 0x20, 0x0, 0x5c, 0x50, 0x0, 0x0, - 0x7a, 0x0, 0x0, 0x0, 0xc, 0x0, 0x0, 0x0, - 0x2, 0xa0, 0x0, 0x0, 0x0, 0xd, 0x30, 0x0, - 0x1, 0x20, 0x2b, 0xdc, 0xce, 0xf9, 0x0, 0x0, - 0x12, 0x10, 0x0, - - /* U+3069 "ど" */ - 0x0, 0x8, 0x10, 0x0, 0x1, 0x70, 0x0, 0xd, - 0x30, 0x0, 0x46, 0x4b, 0x0, 0xb, 0x10, 0x0, - 0xb, 0x32, 0x0, 0xa, 0x10, 0x1, 0x40, 0x0, - 0x0, 0x8, 0x40, 0x7e, 0x90, 0x0, 0x0, 0x2, - 0xdc, 0x71, 0x0, 0x0, 0x0, 0x3c, 0x60, 0x0, - 0x0, 0x0, 0x3, 0xc1, 0x0, 0x0, 0x0, 0x0, - 0xa, 0x20, 0x0, 0x0, 0x0, 0x0, 0xc, 0x0, - 0x0, 0x0, 0x0, 0x0, 0x7, 0x91, 0x0, 0x0, - 0x40, 0x0, 0x0, 0x6c, 0xcc, 0xde, 0xc2, 0x0, - - /* U+306A "な" */ - 0x0, 0x0, 0x41, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x97, 0x0, 0x0, 0x0, 0x0, 0x0, 0xb1, 0x73, - 0x0, 0x0, 0x3, 0x8b, 0xca, 0x60, 0x47, 0x10, - 0x0, 0xa, 0x0, 0x0, 0x4, 0xd1, 0x0, 0x74, - 0x0, 0x4, 0xb7, 0xa5, 0x3, 0xa0, 0x0, 0xc, - 0x0, 0x0, 0x2e, 0x20, 0x0, 0xc, 0x0, 0x0, - 0x95, 0x0, 0x0, 0xb, 0x0, 0x0, 0x0, 0x5, - 0x99, 0x9d, 0x0, 0x0, 0x0, 0x1a, 0x0, 0xe, - 0xc2, 0x0, 0x0, 0xc, 0x42, 0x96, 0x5d, 0x0, - 0x0, 0x1, 0x78, 0x40, 0x3, 0x0, - - /* U+306B "に" */ - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xb3, 0x0, - 0x46, 0x7c, 0xd1, 0xc, 0x40, 0x1, 0x24, 0xa3, - 0x0, 0xd0, 0x0, 0x1, 0x40, 0x0, 0x48, 0x0, - 0x0, 0x0, 0x0, 0x7, 0x40, 0x0, 0x0, 0x0, - 0x0, 0x84, 0x0, 0x10, 0x0, 0x0, 0x8, 0x35, - 0x6, 0x0, 0x0, 0x0, 0x58, 0x80, 0x90, 0x0, - 0x0, 0x1, 0xf6, 0x8, 0x81, 0x1, 0x45, 0x6, - 0x30, 0x5, 0xac, 0xcb, 0x40, - - /* U+306C "ぬ" */ - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x2d, 0x0, 0x0, 0x0, 0x2, 0x10, 0x0, - 0xc2, 0x30, 0x0, 0x0, 0x4a, 0x1, 0x9c, 0x66, - 0xa7, 0x0, 0x0, 0xa4, 0x97, 0x50, 0x0, 0x95, - 0x0, 0xc, 0x80, 0xa1, 0x0, 0x2, 0xa0, 0x3, - 0xd4, 0x19, 0x0, 0x0, 0xc, 0x0, 0xa1, 0xb9, - 0x20, 0x0, 0x1, 0xa0, 0x19, 0x7, 0xb0, 0x7, - 0xa8, 0x96, 0x2, 0x80, 0xbb, 0x67, 0x60, 0x2f, - 0xa0, 0xc, 0xb4, 0x0, 0x76, 0x1a, 0x68, 0xa0, - 0x11, 0x0, 0x0, 0x79, 0x40, 0x3, - - /* U+306D "ね" */ - 0x0, 0x6, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0xd, 0x20, 0x0, 0x0, 0x0, 0x0, 0x0, 0xb, - 0x0, 0x0, 0x21, 0x0, 0x0, 0x0, 0xb, 0x40, - 0x89, 0x79, 0x80, 0x0, 0x18, 0xad, 0x2a, 0x20, - 0x0, 0x85, 0x0, 0x3, 0x3f, 0x80, 0x0, 0x0, - 0x3a, 0x0, 0x0, 0xae, 0x0, 0x0, 0x0, 0x2b, - 0x0, 0x1, 0xca, 0x0, 0x0, 0x0, 0x39, 0x0, - 0xa, 0x3a, 0x0, 0x6, 0x86, 0x86, 0x0, 0x4c, - 0x1a, 0x0, 0xa6, 0x25, 0xfb, 0x30, 0x81, 0xae, - 0x0, 0xc2, 0x29, 0x73, 0xd2, 0x0, 0x3c, 0x0, - 0x29, 0x94, 0x0, 0x10, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x0, - - /* U+306E "の" */ - 0x0, 0x0, 0x0, 0x45, 0x51, 0x0, 0x0, 0x0, - 0x8, 0xba, 0x56, 0xab, 0x10, 0x0, 0x1c, 0x30, - 0x80, 0x0, 0x4c, 0x0, 0xb, 0x20, 0x8, 0x10, - 0x0, 0xa5, 0x5, 0x80, 0x0, 0x81, 0x0, 0x6, - 0x90, 0xa2, 0x0, 0xa, 0x0, 0x0, 0x3a, 0xc, - 0x0, 0x0, 0xb0, 0x0, 0x4, 0x90, 0xb0, 0x0, - 0x57, 0x0, 0x0, 0x86, 0xa, 0x20, 0xc, 0x0, - 0x0, 0x1d, 0x10, 0x4b, 0x5c, 0x30, 0x0, 0x1c, - 0x40, 0x0, 0x48, 0x20, 0x0, 0x6a, 0x30, 0x0, - 0x0, 0x0, 0x1, 0x52, 0x0, 0x0, - - /* U+306F "は" */ - 0x0, 0x0, 0x0, 0x0, 0x80, 0x0, 0x0, 0xc1, - 0x0, 0x0, 0xe2, 0x0, 0x0, 0xd1, 0x0, 0x0, - 0xc0, 0x0, 0x1, 0xb0, 0x0, 0x0, 0xc7, 0xc5, - 0x4, 0x70, 0x3, 0x89, 0xe3, 0x0, 0x8, 0x30, - 0x0, 0x0, 0xb0, 0x0, 0xb, 0x0, 0x0, 0x0, - 0xb0, 0x0, 0xb, 0x0, 0x0, 0x0, 0xb0, 0x0, - 0xc, 0x60, 0x4, 0x65, 0xb0, 0x0, 0xd, 0xa0, - 0x77, 0x35, 0xea, 0x20, 0x8, 0xa0, 0xb1, 0x1, - 0xc3, 0xe2, 0x0, 0x30, 0x3c, 0xab, 0x20, 0x31, - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - - /* U+3070 "ば" */ - 0x0, 0x0, 0x0, 0x0, 0x0, 0x1, 0x0, 0x0, - 0x0, 0x0, 0x1, 0x0, 0x11, 0xb2, 0x9, 0x20, - 0x0, 0xd, 0x30, 0x3a, 0x45, 0xc, 0x10, 0x0, - 0xb, 0x10, 0x6, 0x10, 0xc, 0x0, 0x0, 0xb, - 0x49, 0x60, 0x0, 0x29, 0x0, 0x38, 0xae, 0x73, - 0x0, 0x0, 0x55, 0x0, 0x0, 0xb, 0x0, 0x0, - 0x0, 0x73, 0x0, 0x0, 0xb, 0x0, 0x0, 0x0, - 0xa1, 0x10, 0x0, 0xb, 0x0, 0x0, 0x0, 0xb4, - 0x10, 0x2, 0x1b, 0x0, 0x0, 0x0, 0xba, 0x3, - 0xc6, 0x7e, 0x70, 0x0, 0x0, 0x7a, 0x7, 0x70, - 0xa, 0x6d, 0x10, 0x0, 0x15, 0x2, 0xd9, 0xb4, - 0x5, 0x30, 0x0, 0x0, 0x0, 0x2, 0x0, 0x0, - 0x0, 0x0, - - /* U+3071 "ぱ" */ - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x30, 0x6, 0x75, 0xa, 0x10, 0x0, - 0xd, 0x30, 0x90, 0x60, 0xd1, 0x0, 0x0, 0xb0, - 0x1, 0x73, 0xb, 0x0, 0x0, 0xb, 0x5a, 0x60, - 0x3, 0x70, 0x3, 0x8a, 0xd5, 0x10, 0x0, 0x64, - 0x0, 0x0, 0xb, 0x0, 0x0, 0x9, 0x10, 0x0, - 0x0, 0xb0, 0x0, 0x0, 0xa0, 0x0, 0x0, 0xb, - 0x0, 0x0, 0xb, 0x50, 0x2, 0x43, 0xb0, 0x0, - 0x0, 0xba, 0x5, 0xa4, 0x5e, 0x80, 0x0, 0x7, - 0x90, 0x93, 0x1, 0xb4, 0xd1, 0x0, 0x3, 0x2, - 0xba, 0xb2, 0x3, 0x10, 0x0, - - /* U+3072 "ひ" */ - 0x0, 0x4a, 0xd1, 0x0, 0x82, 0x0, 0x6, 0xc6, - 0x99, 0x0, 0xd, 0x90, 0x0, 0x0, 0x49, 0x0, - 0x0, 0xac, 0x0, 0x0, 0xc, 0x0, 0x0, 0x9, - 0x86, 0x0, 0x7, 0x50, 0x0, 0x0, 0xa2, 0xd2, - 0x0, 0xc0, 0x0, 0x0, 0xc, 0x5, 0xd0, 0xc, - 0x0, 0x0, 0x1, 0xc0, 0x1, 0x0, 0xc0, 0x0, - 0x0, 0x67, 0x0, 0x0, 0xc, 0x10, 0x0, 0xd, - 0x10, 0x0, 0x0, 0x5a, 0x0, 0x1b, 0x50, 0x0, - 0x0, 0x0, 0x6c, 0xbb, 0x40, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - - /* U+3073 "び" */ - 0x0, 0x0, 0x0, 0x0, 0x0, 0x1, 0x10, 0x0, - 0x0, 0x0, 0x0, 0x0, 0x30, 0x95, 0x0, 0x16, - 0xc7, 0x0, 0x27, 0x1c, 0x14, 0xc, 0x94, 0xd4, - 0x0, 0x4f, 0x14, 0x10, 0x0, 0xb, 0x40, 0x0, - 0x2d, 0x60, 0x0, 0x0, 0x59, 0x0, 0x0, 0x29, - 0xc0, 0x0, 0x0, 0xc1, 0x0, 0x0, 0x29, 0x79, - 0x0, 0x3, 0xa0, 0x0, 0x0, 0x48, 0xc, 0x60, - 0x5, 0x60, 0x0, 0x0, 0x75, 0x0, 0x10, 0x6, - 0x50, 0x0, 0x0, 0xd1, 0x0, 0x0, 0x4, 0x80, - 0x0, 0x6, 0x90, 0x0, 0x0, 0x0, 0xc3, 0x0, - 0x5c, 0x10, 0x0, 0x0, 0x0, 0x2c, 0xcc, 0x91, - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, - - /* U+3074 "ぴ" */ - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x0, 0x0, 0x7, 0x70, 0x1, 0x38, - 0xc4, 0x0, 0x45, 0x16, 0x61, 0x2c, 0x75, 0xc2, - 0x0, 0x7e, 0x3, 0x30, 0x0, 0xc, 0x10, 0x0, - 0x4d, 0x30, 0x0, 0x0, 0x94, 0x0, 0x0, 0x49, - 0xa0, 0x0, 0x1, 0xb0, 0x0, 0x0, 0x46, 0xa4, - 0x0, 0x7, 0x60, 0x0, 0x0, 0x75, 0x1e, 0x20, - 0xa, 0x20, 0x0, 0x0, 0xa2, 0x1, 0x0, 0xb, - 0x10, 0x0, 0x0, 0xd0, 0x0, 0x0, 0x8, 0x40, - 0x0, 0x8, 0x70, 0x0, 0x0, 0x2, 0xc1, 0x0, - 0x6b, 0x0, 0x0, 0x0, 0x0, 0x5d, 0xbc, 0x80, - 0x0, 0x0, 0x0, 0x0, 0x0, 0x10, 0x0, 0x0, - 0x0, 0x0, - - /* U+3075 "ふ" */ - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x44, 0x0, 0x0, 0x0, 0x0, 0x0, 0x9, 0x70, - 0x0, 0x0, 0x0, 0x0, 0x4, 0xf5, 0x0, 0x0, - 0x0, 0x0, 0x3a, 0x20, 0x0, 0x0, 0x0, 0x0, - 0x82, 0x0, 0x0, 0x0, 0x0, 0x0, 0x36, 0x0, - 0x0, 0x0, 0x0, 0x0, 0x9, 0x20, 0x14, 0x0, - 0x0, 0x2, 0x1, 0xb0, 0x6, 0x90, 0x41, 0x83, - 0x0, 0xb1, 0x0, 0xc6, 0x8d, 0x24, 0x20, 0xc0, - 0x0, 0x35, 0x10, 0x0, 0x7a, 0x40, 0x0, 0x0, - - /* U+3076 "ぶ" */ - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x52, 0x0, 0x0, 0x50, 0x0, 0x0, 0x0, - 0xb7, 0x0, 0x53, 0xc0, 0x0, 0x0, 0x6, 0xf3, - 0x5, 0x92, 0x0, 0x0, 0x8, 0x71, 0x0, 0x2, - 0x0, 0x0, 0x0, 0xb0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x6, 0x60, 0x0, 0x0, 0x0, 0x0, 0x0, - 0xb, 0x10, 0x31, 0x0, 0x0, 0x0, 0x30, 0x3a, - 0x0, 0xa4, 0x0, 0x33, 0x80, 0x0, 0xc0, 0x1, - 0xe2, 0xe, 0xb0, 0x13, 0x1c, 0x0, 0x6, 0x30, - 0x30, 0x0, 0x38, 0x20, 0x0, 0x0, - - /* U+3077 "ぷ" */ - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x62, 0x0, 0x4, 0x61, 0x0, 0x0, 0x0, - 0xb7, 0x0, 0x60, 0x60, 0x0, 0x0, 0x8, 0xf2, - 0x3, 0x61, 0x0, 0x0, 0x9, 0x60, 0x0, 0x0, - 0x0, 0x0, 0x0, 0xb0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x7, 0x40, 0x0, 0x0, 0x0, 0x0, 0x0, - 0xb, 0x10, 0x32, 0x0, 0x0, 0x0, 0x20, 0x3a, - 0x0, 0xa5, 0x0, 0x43, 0x80, 0x0, 0xc0, 0x1, - 0xe1, 0xf, 0xa0, 0x51, 0x2c, 0x0, 0x7, 0x10, - 0x50, 0x1, 0x99, 0x20, 0x0, 0x0, - - /* U+3078 "へ" */ - 0x0, 0x0, 0x17, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x1b, 0x4a, 0x0, 0x0, 0x0, 0x0, 0x1b, 0x10, - 0x39, 0x0, 0x0, 0x0, 0x4d, 0x30, 0x0, 0x67, - 0x0, 0x0, 0x19, 0x30, 0x0, 0x0, 0xa5, 0x0, - 0x0, 0x0, 0x0, 0x0, 0x0, 0xb6, 0x0, 0x0, - 0x0, 0x0, 0x0, 0x0, 0xcb, 0x10, 0x0, 0x0, - 0x0, 0x0, 0x0, 0x67, - - /* U+3079 "べ" */ - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x0, 0x24, 0xa1, 0x0, 0x0, 0x15, - 0x0, 0x6, 0x95, 0x30, 0x0, 0x29, 0x4a, 0x0, - 0x8, 0x0, 0x0, 0x1a, 0x0, 0x39, 0x0, 0x0, - 0x0, 0x3c, 0x20, 0x0, 0x66, 0x0, 0x0, 0x1b, - 0x40, 0x0, 0x0, 0xa5, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, 0xc6, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x1, 0xcb, 0x20, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x78, - - /* U+307A "ぺ" */ - 0x0, 0x0, 0x0, 0x0, 0x1, 0x63, 0x0, 0x0, - 0x1, 0x50, 0x0, 0x60, 0x60, 0x0, 0x1, 0xb4, - 0xa0, 0x1, 0x64, 0x0, 0x1, 0xb1, 0x2, 0xa0, - 0x0, 0x0, 0x3, 0xc3, 0x0, 0x6, 0x70, 0x0, - 0x0, 0xa4, 0x0, 0x0, 0xa, 0x40, 0x0, 0x0, - 0x0, 0x0, 0x0, 0xc, 0x40, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x1c, 0x91, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x8, 0x70, - - /* U+307B "ほ" */ - 0x5, 0x20, 0x0, 0x2, 0x48, 0x10, 0x9, 0x60, - 0x7, 0x9d, 0x63, 0x0, 0xa, 0x10, 0x0, 0xb, - 0x20, 0x0, 0xb, 0x0, 0x0, 0xa, 0x0, 0x0, - 0x1a, 0x0, 0x0, 0xb, 0x49, 0x70, 0x46, 0x0, - 0x7, 0x9e, 0x72, 0x0, 0x64, 0x0, 0x0, 0xb, - 0x0, 0x0, 0x82, 0x40, 0x0, 0xb, 0x0, 0x0, - 0x88, 0x30, 0x35, 0x4b, 0x0, 0x0, 0x5f, 0x6, - 0x63, 0x5e, 0x91, 0x0, 0x9, 0xa, 0x0, 0x2a, - 0x4d, 0x20, 0x0, 0x2, 0xaa, 0xa1, 0x2, 0x20, - - /* U+307C "ぼ" */ - 0x2, 0x40, 0x0, 0x1, 0x36, 0x50, 0x0, 0x3, - 0xa0, 0x2, 0x8b, 0xb4, 0x11, 0x60, 0x7, 0x40, - 0x0, 0x3, 0xb0, 0x36, 0x49, 0xa, 0x0, 0x0, - 0x2, 0xa0, 0x8, 0x40, 0xa, 0x0, 0x0, 0x2, - 0xb6, 0xa2, 0x0, 0xa, 0x0, 0x3, 0x8a, 0xc5, - 0x10, 0x0, 0xa, 0x0, 0x0, 0x2, 0xa0, 0x0, - 0x0, 0x19, 0x50, 0x0, 0x2, 0xa0, 0x0, 0x0, - 0x1b, 0x70, 0x4, 0x54, 0xa0, 0x0, 0x0, 0xd, - 0x50, 0xa4, 0x38, 0xd5, 0x0, 0x0, 0x5, 0x21, - 0x90, 0x6, 0x79, 0xa0, 0x0, 0x0, 0x0, 0x7a, - 0xa9, 0x0, 0x50, 0x0, - - /* U+307D "ぽ" */ - 0x2, 0x40, 0x0, 0x1, 0x36, 0x40, 0x0, 0x3, - 0xa0, 0x2, 0x8b, 0xb4, 0x5, 0x85, 0x7, 0x40, - 0x0, 0x3, 0xb0, 0x5, 0x7, 0xa, 0x0, 0x0, - 0x2, 0xa0, 0x0, 0x51, 0xa, 0x0, 0x0, 0x2, - 0xb6, 0xa2, 0x0, 0xa, 0x0, 0x3, 0x8a, 0xc5, - 0x10, 0x0, 0xa, 0x0, 0x0, 0x2, 0xa0, 0x0, - 0x0, 0x19, 0x40, 0x0, 0x2, 0xa0, 0x0, 0x0, - 0x1b, 0x70, 0x4, 0x54, 0xa0, 0x0, 0x0, 0xd, - 0x50, 0xa4, 0x38, 0xd4, 0x0, 0x0, 0x6, 0x21, - 0x90, 0x6, 0x7b, 0x90, 0x0, 0x0, 0x0, 0x7a, - 0xa9, 0x0, 0x50, 0x0, - - /* U+307E "ま" */ - 0x0, 0x0, 0x3b, 0x0, 0x0, 0x0, 0x0, 0xd0, - 0x0, 0x0, 0x0, 0xc, 0x38, 0x80, 0x5, 0x9a, - 0xe7, 0x30, 0x0, 0x0, 0xc, 0x0, 0x0, 0x0, - 0x0, 0xd6, 0xb4, 0x0, 0x69, 0xad, 0x40, 0x0, - 0x0, 0x0, 0xc0, 0x0, 0x0, 0x56, 0x4c, 0x0, - 0x0, 0xb5, 0x27, 0xf8, 0x0, 0x1a, 0x0, 0x67, - 0x6d, 0x30, 0x8b, 0xba, 0x0, 0x3d, 0x0, 0x0, - 0x0, 0x0, 0x0, - - /* U+307F "み" */ - 0x0, 0x0, 0x0, 0x1, 0x0, 0x0, 0x0, 0x0, - 0x26, 0x7a, 0xd9, 0x0, 0x0, 0x0, 0x0, 0x42, - 0xc, 0x20, 0x0, 0x0, 0x0, 0x0, 0x5, 0x80, - 0x0, 0x0, 0x0, 0x0, 0x0, 0xc1, 0x0, 0x20, - 0x0, 0x0, 0x0, 0x67, 0x0, 0x1f, 0x0, 0x0, - 0x59, 0x9e, 0xa9, 0x43, 0xa0, 0x0, 0x85, 0x9, - 0x40, 0x17, 0xe7, 0x0, 0x1a, 0x4, 0x90, 0x0, - 0x2b, 0xb9, 0x2, 0x93, 0xb0, 0x0, 0xb, 0x10, - 0xa1, 0x8, 0x80, 0x0, 0xa, 0x20, 0x0, 0x0, - 0x0, 0x0, 0x27, 0x10, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x0, 0x0, 0x0, - - /* U+3080 "む" */ - 0x0, 0x49, 0x0, 0x0, 0x0, 0x0, 0x2, 0xb0, - 0x0, 0x0, 0x0, 0x1, 0x3c, 0x8b, 0x0, 0x46, - 0x0, 0x69, 0xc2, 0x0, 0x0, 0xa6, 0x0, 0x2a, - 0x0, 0x0, 0x2, 0xb2, 0x76, 0xa0, 0x0, 0x0, - 0x0, 0x90, 0x3c, 0x0, 0x0, 0x0, 0xa, 0x38, - 0xa0, 0x0, 0x1, 0x0, 0x3b, 0xd4, 0x0, 0x0, - 0x8, 0x0, 0xc, 0x0, 0x0, 0x0, 0xd3, 0x0, - 0xd4, 0x1, 0x35, 0xbb, 0x0, 0x1, 0x79, 0xa9, - 0x61, 0x0, - - /* U+3081 "め" */ - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x3, 0x10, - 0x0, 0xa6, 0x0, 0x0, 0x9, 0x70, 0x0, 0xa2, - 0x0, 0x0, 0x2, 0xa0, 0x49, 0xe9, 0x60, 0x0, - 0x0, 0xca, 0x53, 0x90, 0x6c, 0x10, 0x2, 0xd4, - 0x7, 0x40, 0x3, 0xb0, 0xb, 0x29, 0xb, 0x0, - 0x0, 0xc0, 0x64, 0xa, 0x95, 0x0, 0x0, 0xc0, - 0xb0, 0x4, 0xf1, 0x0, 0x2, 0xb0, 0xb0, 0x3b, - 0x55, 0x0, 0xa, 0x30, 0x4b, 0x81, 0x0, 0x1, - 0xa4, 0x0, 0x0, 0x0, 0x2, 0x67, 0x10, 0x0, - 0x0, 0x0, 0x1, 0x0, 0x0, 0x0, - - /* U+3082 "も" */ - 0x0, 0x2, 0x60, 0x0, 0x0, 0x0, 0x3d, 0x0, - 0x0, 0x0, 0x4, 0x80, 0x0, 0x0, 0x32, 0x74, - 0x0, 0x0, 0x0, 0x6e, 0xba, 0x10, 0x0, 0x0, - 0xc0, 0x0, 0x0, 0x0, 0xb, 0x0, 0x0, 0x11, - 0x88, 0xa2, 0x20, 0x5, 0x0, 0x8a, 0x88, 0x0, - 0x80, 0x6, 0x50, 0x0, 0xa, 0x0, 0x48, 0x0, - 0x2, 0x90, 0x0, 0xc4, 0x13, 0xc2, 0x0, 0x1, - 0x8a, 0x92, 0x0, - - /* U+3083 "ゃ" */ - 0x0, 0x0, 0x1, 0x0, 0x0, 0x0, 0x0, 0x20, - 0x39, 0x0, 0x0, 0x0, 0x57, 0x1, 0xa4, 0x51, - 0x0, 0x1, 0xa2, 0x99, 0x55, 0xc4, 0x0, 0x2d, - 0x91, 0x0, 0x4, 0x80, 0xa9, 0x49, 0x7, 0x65, - 0xc3, 0x0, 0x0, 0xb2, 0x3, 0x52, 0x0, 0x0, - 0x4, 0x90, 0x0, 0x0, 0x0, 0x0, 0xc, 0x0, - 0x0, 0x0, 0x0, 0x0, 0x61, 0x0, 0x0, - - /* U+3084 "や" */ - 0x0, 0x0, 0x0, 0x20, 0x0, 0x0, 0x0, 0x0, - 0x4, 0x10, 0x1a, 0x20, 0x0, 0x0, 0x0, 0x3a, - 0x0, 0x4c, 0x52, 0x31, 0x0, 0x0, 0xc, 0x0, - 0x4b, 0xb8, 0x7a, 0x80, 0x0, 0x7, 0xab, 0x71, - 0x0, 0x0, 0xd1, 0x0, 0x3b, 0xe1, 0x0, 0x0, - 0x0, 0xd0, 0x2c, 0x91, 0x77, 0x5, 0x40, 0x6, - 0xa0, 0x0, 0x0, 0xd, 0x0, 0x38, 0xa7, 0x0, - 0x0, 0x0, 0x8, 0x60, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x2, 0xd0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0xd2, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x85, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x11, - 0x0, 0x0, 0x0, - - /* U+3085 "ゅ" */ - 0x0, 0x0, 0x48, 0x0, 0x0, 0xd, 0x0, 0x3c, - 0xa5, 0x0, 0x1b, 0x9, 0x87, 0x56, 0x80, 0x47, - 0x76, 0x6, 0x50, 0xc0, 0x56, 0xa1, 0x7, 0x40, - 0xa2, 0x4d, 0x46, 0x19, 0x10, 0xd0, 0xe, 0x0, - 0xab, 0x18, 0x80, 0x2, 0x0, 0x8a, 0x94, 0x0, - 0x0, 0x6, 0x40, 0x0, 0x0, - - /* U+3086 "ゆ" */ - 0x0, 0x0, 0x0, 0x10, 0x0, 0x0, 0x0, 0x0, - 0x4, 0xa6, 0x0, 0x0, 0x8, 0x10, 0x0, 0x3e, - 0x51, 0x0, 0xb, 0x30, 0x3b, 0x8d, 0x5a, 0x70, - 0xc, 0x4, 0xb1, 0xb, 0x0, 0x95, 0x1a, 0x1c, - 0x0, 0xb, 0x0, 0x3b, 0x47, 0x94, 0x10, 0xc, - 0x0, 0xd, 0x47, 0xb0, 0x60, 0xc, 0x0, 0x2b, - 0x3d, 0x70, 0x72, 0x2a, 0x0, 0x77, 0xf, 0x40, - 0xb, 0x95, 0x17, 0xb0, 0x5, 0x10, 0x2, 0xda, - 0x95, 0x0, 0x0, 0x0, 0x3b, 0x20, 0x0, 0x0, - 0x0, 0x4, 0x50, 0x0, 0x0, 0x0, - - /* U+3087 "ょ" */ - 0x0, 0x9, 0x30, 0x0, 0x0, 0xa, 0x40, 0x0, - 0x0, 0x9, 0xab, 0x80, 0x0, 0x9, 0x30, 0x0, - 0x0, 0xa, 0x20, 0x0, 0x0, 0xa, 0x20, 0x0, - 0x29, 0x9e, 0xb8, 0x0, 0x83, 0x2d, 0x8, 0x40, - 0x2d, 0xd5, 0x0, 0x0, - - /* U+3088 "よ" */ - 0x0, 0x0, 0x20, 0x0, 0x0, 0x0, 0xe, 0x40, - 0x0, 0x0, 0x0, 0xb2, 0x1, 0x0, 0x0, 0xb, - 0x9c, 0xa2, 0x0, 0x0, 0xc0, 0x0, 0x0, 0x0, - 0xc, 0x0, 0x0, 0x0, 0x0, 0xc0, 0x0, 0x0, - 0x4, 0x4d, 0x0, 0x0, 0x2b, 0x65, 0xec, 0x80, - 0x6, 0x50, 0x49, 0x9, 0x70, 0x1b, 0xbb, 0x10, - 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, - - /* U+3089 "ら" */ - 0x0, 0x0, 0x30, 0x0, 0x0, 0x0, 0x0, 0x75, - 0x0, 0x0, 0x0, 0x2, 0x5c, 0xd0, 0x0, 0x0, - 0x67, 0x13, 0x90, 0x0, 0x1, 0xa0, 0x0, 0x0, - 0x0, 0x6, 0x40, 0x0, 0x0, 0x0, 0xb, 0x16, - 0xba, 0xba, 0x20, 0xe, 0xb5, 0x0, 0x3, 0xd0, - 0x3e, 0x20, 0x0, 0x0, 0xb2, 0x0, 0x0, 0x0, - 0x0, 0xc1, 0x0, 0x0, 0x0, 0x7, 0xa0, 0x0, - 0x1, 0x37, 0xb7, 0x0, 0x0, 0x24, 0x31, 0x0, - 0x0, - - /* U+308A "り" */ - 0x5, 0x0, 0x0, 0x0, 0x1f, 0x4, 0xbb, 0x40, - 0x3a, 0x3a, 0x1, 0xc0, 0x66, 0xc0, 0x0, 0xd0, - 0x98, 0x70, 0x0, 0xb1, 0xac, 0x10, 0x0, 0xb1, - 0x9b, 0x0, 0x0, 0xc0, 0x58, 0x0, 0x1, 0xb0, - 0x1, 0x0, 0x6, 0x60, 0x0, 0x0, 0xb, 0x0, - 0x0, 0x0, 0x84, 0x0, 0x0, 0x6, 0x50, 0x0, - 0x0, 0x53, 0x0, 0x0, - - /* U+308B "る" */ - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x48, - 0xca, 0x0, 0x1, 0xcb, 0x50, 0xb7, 0x0, 0x0, - 0x0, 0x8, 0x60, 0x0, 0x0, 0x0, 0x76, 0x0, - 0x0, 0x0, 0x6, 0x80, 0x0, 0x0, 0x0, 0x6d, - 0x9a, 0xab, 0x70, 0x8, 0xe6, 0x0, 0x0, 0x96, - 0x6d, 0x10, 0x0, 0x0, 0x3b, 0x21, 0x1a, 0x92, - 0x0, 0x49, 0x0, 0x85, 0x9, 0x10, 0xc3, 0x0, - 0x3b, 0x45, 0xbc, 0x40, 0x0, 0x2, 0x66, 0x40, - 0x0, - - /* U+308C "れ" */ - 0x0, 0x6, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0xc, 0x30, 0x0, 0x0, 0x0, 0x0, 0x0, 0xa, - 0x0, 0x18, 0x91, 0x0, 0x0, 0x0, 0xb, 0x63, - 0xb3, 0x57, 0x0, 0x0, 0x17, 0x9d, 0x88, 0x0, - 0x47, 0x0, 0x0, 0x3, 0x1f, 0x60, 0x0, 0x65, - 0x0, 0x0, 0x0, 0x7f, 0x0, 0x0, 0x82, 0x0, - 0x0, 0x0, 0xda, 0x0, 0x0, 0xa0, 0x0, 0x0, - 0x7, 0x6a, 0x0, 0x0, 0xb0, 0x0, 0x0, 0x1d, - 0x2a, 0x0, 0x0, 0xb0, 0x1, 0x60, 0x75, 0x9e, - 0x10, 0x0, 0x97, 0x79, 0x0, 0x0, 0x2d, 0x0, - 0x0, 0x4, 0x30, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x0, - - /* U+308D "ろ" */ - 0x0, 0x0, 0x0, 0x0, 0x0, 0x1, 0x34, 0x88, - 0xe4, 0x0, 0x1, 0x96, 0x3, 0xd2, 0x0, 0x0, - 0x0, 0x2b, 0x10, 0x0, 0x0, 0x1, 0xa1, 0x0, - 0x0, 0x0, 0x1a, 0x23, 0x42, 0x0, 0x2, 0xda, - 0x85, 0x58, 0xb1, 0x5e, 0x80, 0x0, 0x0, 0x4a, - 0xb3, 0x0, 0x0, 0x0, 0x1c, 0x0, 0x0, 0x0, - 0x0, 0x49, 0x0, 0x0, 0x0, 0x2, 0xc1, 0x0, - 0x4, 0x67, 0x99, 0x20, 0x0, 0x0, 0x0, 0x0, - 0x0, - - /* U+308F "わ" */ - 0x0, 0x2, 0x30, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x2e, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xc0, - 0x0, 0x0, 0x0, 0x0, 0x0, 0xd, 0x20, 0x35, - 0x41, 0x0, 0x1, 0x69, 0xf5, 0xa7, 0x56, 0xb7, - 0x0, 0x46, 0x4e, 0x90, 0x0, 0x0, 0x95, 0x0, - 0xc, 0xb0, 0x0, 0x0, 0x2, 0xa0, 0x5, 0xbb, - 0x0, 0x0, 0x0, 0x1b, 0x0, 0xd2, 0xb0, 0x0, - 0x0, 0x3, 0x80, 0x89, 0x1b, 0x0, 0x0, 0x0, - 0xa1, 0xc, 0x49, 0xb0, 0x0, 0x1, 0x93, 0x0, - 0x0, 0x79, 0x0, 0x4, 0x50, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x0, 0x0, 0x0, - - /* U+3092 "を" */ - 0x0, 0x0, 0x60, 0x0, 0x0, 0x0, 0x0, 0xd, - 0x10, 0x0, 0x0, 0x3, 0x5, 0x83, 0x99, 0x0, - 0x0, 0x59, 0xea, 0x73, 0x0, 0x0, 0x0, 0x84, - 0x0, 0x0, 0x0, 0x0, 0x4b, 0x89, 0x10, 0x1, - 0xa1, 0x4e, 0x70, 0x2a, 0x18, 0xc8, 0x1c, 0x40, - 0x2, 0xeb, 0x40, 0x0, 0x0, 0x8, 0xac, 0x0, - 0x0, 0x0, 0xb, 0x41, 0xb0, 0x0, 0x0, 0x2, - 0xa0, 0x14, 0x0, 0x0, 0x0, 0x1d, 0x10, 0x0, - 0x0, 0x0, 0x0, 0x4c, 0xcc, 0xdd, 0x20, 0x0, - - /* U+3093 "ん" */ - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x68, 0x0, 0x0, 0x0, 0x0, 0x0, 0xa, - 0x60, 0x0, 0x0, 0x0, 0x0, 0x2, 0xc0, 0x0, - 0x0, 0x0, 0x0, 0x0, 0x94, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x1b, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x8, 0x47, 0x91, 0x0, 0x0, 0x0, 0x1, 0xcb, - 0x46, 0x80, 0x0, 0x0, 0x0, 0x8e, 0x20, 0x39, - 0x0, 0x1, 0x30, 0x1f, 0x50, 0x3, 0x90, 0x0, - 0x80, 0xa, 0xa0, 0x0, 0x2a, 0x0, 0x55, 0x0, - 0xe1, 0x0, 0x0, 0xd5, 0x88, 0x0, 0x1, 0x0, - 0x0, 0x1, 0x62, 0x0, 0x0, - - /* U+30A1 "ァ" */ - 0x0, 0x0, 0x0, 0x0, 0x0, 0x23, 0x57, 0x8a, - 0xc0, 0x4b, 0x84, 0x0, 0xb8, 0x0, 0x0, 0x23, - 0x92, 0x0, 0x0, 0x7, 0xa0, 0x0, 0x0, 0x0, - 0x95, 0x0, 0x0, 0x0, 0xd, 0x0, 0x0, 0x0, - 0x5, 0x80, 0x0, 0x0, 0x1, 0xa0, 0x0, 0x0, - 0x0, 0x60, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, - - /* U+30A2 "ア" */ - 0x0, 0x0, 0x0, 0x0, 0x15, 0x60, 0x0, 0x1, - 0x36, 0x88, 0x89, 0xf3, 0x9, 0xfa, 0x62, 0x0, - 0x2e, 0x60, 0x0, 0x0, 0x0, 0x1, 0xb2, 0x0, - 0x0, 0x0, 0x6, 0x98, 0x0, 0x0, 0x0, 0x0, - 0x7, 0x80, 0x0, 0x0, 0x0, 0x0, 0xb, 0x30, - 0x0, 0x0, 0x0, 0x0, 0x1d, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x96, 0x0, 0x0, 0x0, 0x0, 0x2, - 0xc0, 0x0, 0x0, 0x0, 0x0, 0xb, 0x30, 0x0, - 0x0, 0x0, 0x0, 0x75, 0x0, 0x0, 0x0, 0x0, - 0x1, 0x20, 0x0, 0x0, 0x0, 0x0, - - /* U+30A3 "ィ" */ - 0x0, 0x0, 0x0, 0x10, 0x0, 0x0, 0x0, 0xa7, - 0x0, 0x0, 0x4, 0xd1, 0x0, 0x0, 0x4c, 0x10, - 0x0, 0x6, 0xc9, 0x0, 0x0, 0x86, 0xc, 0x0, - 0x15, 0x10, 0xb, 0x0, 0x0, 0x0, 0xb, 0x0, - 0x0, 0x0, 0x1b, 0x0, 0x0, 0x0, 0x2a, 0x0, - 0x0, 0x0, 0x2, 0x0, - - /* U+30A4 "イ" */ - 0x0, 0x0, 0x0, 0x0, 0x70, 0x0, 0x0, 0x0, - 0x3, 0xf3, 0x0, 0x0, 0x0, 0x1d, 0x40, 0x0, - 0x0, 0x0, 0xb5, 0x0, 0x0, 0x0, 0xb, 0x70, - 0x0, 0x0, 0x2, 0xb8, 0xc0, 0x0, 0x0, 0x69, - 0x13, 0xa0, 0x0, 0x27, 0x30, 0x2, 0xa0, 0x0, - 0x0, 0x0, 0x2, 0xa0, 0x0, 0x0, 0x0, 0x2, - 0xa0, 0x0, 0x0, 0x0, 0x3, 0xa0, 0x0, 0x0, - 0x0, 0x4, 0xa0, 0x0, 0x0, 0x0, 0x1, 0x70, - 0x0, - - /* U+30A6 "ウ" */ - 0x0, 0x0, 0x60, 0x0, 0x0, 0x0, 0x0, 0xd, - 0x30, 0x0, 0x0, 0x0, 0x0, 0xa4, 0x47, 0xb8, - 0x9, 0x9a, 0xaa, 0x85, 0x27, 0xc0, 0x94, 0x0, - 0x0, 0x0, 0xd3, 0x8, 0x50, 0x0, 0x0, 0x59, - 0x0, 0x86, 0x0, 0x0, 0xc, 0x10, 0x4, 0x40, - 0x0, 0x9, 0x50, 0x0, 0x0, 0x0, 0x5, 0xa0, - 0x0, 0x0, 0x0, 0x2, 0xb0, 0x0, 0x0, 0x0, - 0x2, 0xa1, 0x0, 0x0, 0x0, 0x3, 0x70, 0x0, - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - - /* U+30A7 "ェ" */ - 0x0, 0x1, 0x25, 0x94, 0x0, 0x3, 0xb9, 0xd5, - 0x20, 0x0, 0x0, 0x0, 0xa3, 0x0, 0x0, 0x0, - 0x0, 0xa2, 0x0, 0x0, 0x0, 0x0, 0xa1, 0x0, - 0x0, 0x25, 0x78, 0xdb, 0xbc, 0xd1, 0x17, 0x42, - 0x0, 0x0, 0x0, - - /* U+30A8 "エ" */ - 0x0, 0x0, 0x0, 0x2, 0x51, 0x0, 0x2, 0x99, - 0xac, 0xa9, 0x73, 0x0, 0x0, 0x33, 0xc, 0x40, - 0x0, 0x0, 0x0, 0x0, 0xa, 0x30, 0x0, 0x0, - 0x0, 0x0, 0xa, 0x20, 0x0, 0x0, 0x0, 0x0, - 0xa, 0x20, 0x0, 0x0, 0x0, 0x0, 0xa, 0x43, - 0x56, 0x72, 0x6c, 0xca, 0xa9, 0x76, 0x55, 0x64, - 0x2, 0x0, 0x0, 0x0, 0x0, 0x0, - - /* U+30AA "オ" */ - 0x0, 0x0, 0x0, 0x2, 0x30, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x3e, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0xb0, 0x0, 0x0, 0x0, 0x0, 0x1, 0x4c, - 0x8a, 0xc4, 0x0, 0x8d, 0xb9, 0x7e, 0xb2, 0x0, - 0x0, 0x0, 0x0, 0x7, 0x9a, 0x0, 0x0, 0x0, - 0x0, 0x4, 0xb0, 0xb0, 0x0, 0x0, 0x0, 0x3, - 0xb0, 0xb, 0x0, 0x0, 0x0, 0x3, 0xb1, 0x0, - 0xb0, 0x0, 0x0, 0x5, 0x90, 0x0, 0xb, 0x0, - 0x0, 0x4, 0x40, 0x0, 0x52, 0xc0, 0x0, 0x0, - 0x0, 0x0, 0x2, 0xf9, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x4, 0x10, 0x0, 0x0, - - /* U+30AB "カ" */ - 0x0, 0x0, 0x0, 0x30, 0x0, 0x0, 0x0, 0x0, - 0xf, 0x30, 0x0, 0x0, 0x0, 0x0, 0xe0, 0x0, - 0x0, 0x0, 0x0, 0x2b, 0x37, 0xb5, 0x3, 0x88, - 0xac, 0xb6, 0x38, 0xb0, 0x6, 0x30, 0xb1, 0x0, - 0xa4, 0x0, 0x0, 0x2b, 0x0, 0xe, 0x0, 0x0, - 0xb, 0x30, 0x3, 0xb0, 0x0, 0x4, 0x90, 0x0, - 0x86, 0x0, 0x1, 0xb0, 0x0, 0xd, 0x10, 0x1, - 0x91, 0x0, 0xac, 0xb0, 0x0, 0x50, 0x0, 0x2, - 0xc2, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - - /* U+30AC "ガ" */ - 0x0, 0x0, 0x0, 0x0, 0x0, 0x10, 0x0, 0x0, - 0x0, 0x20, 0x1, 0x6, 0x90, 0x0, 0x0, 0xc, - 0x60, 0x1b, 0x28, 0x0, 0x0, 0x0, 0xd2, 0x0, - 0x36, 0x0, 0x0, 0x0, 0xd, 0x4, 0x85, 0x0, - 0x0, 0x55, 0x8a, 0xd9, 0x67, 0xe0, 0x0, 0x6, - 0x62, 0x76, 0x0, 0x69, 0x0, 0x0, 0x0, 0xc, - 0x10, 0xa, 0x40, 0x0, 0x0, 0x4, 0x90, 0x0, - 0xd0, 0x0, 0x0, 0x0, 0xc1, 0x0, 0x3a, 0x0, - 0x0, 0x0, 0x85, 0x0, 0x8, 0x50, 0x0, 0x0, - 0x66, 0x0, 0x88, 0xe1, 0x0, 0x0, 0x32, 0x0, - 0x0, 0xe7, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x0, - - /* U+30AD "キ" */ - 0x0, 0x0, 0x22, 0x0, 0x0, 0x0, 0x0, 0x4, - 0xb0, 0x0, 0x0, 0x0, 0x0, 0xc, 0x0, 0x0, - 0x0, 0x0, 0x1, 0xc7, 0x9a, 0x90, 0x3, 0xca, - 0x7b, 0x30, 0x0, 0x0, 0x0, 0x0, 0x64, 0x0, - 0x0, 0x0, 0x0, 0x28, 0xba, 0xbb, 0x83, 0xcb, - 0xa7, 0x5a, 0x0, 0x0, 0x0, 0x0, 0x0, 0xb0, - 0x0, 0x0, 0x0, 0x0, 0xc, 0x0, 0x0, 0x0, - 0x0, 0x0, 0xb2, 0x0, 0x0, 0x0, 0x0, 0x8, - 0x30, 0x0, 0x0, 0x0, 0x0, 0x10, 0x0, 0x0, - - /* U+30AE "ギ" */ - 0x0, 0x0, 0x23, 0x0, 0x1, 0x83, 0x0, 0x0, - 0x3d, 0x0, 0x27, 0x29, 0x0, 0x0, 0xc, 0x0, - 0x5, 0x80, 0x0, 0x0, 0x2c, 0x8a, 0xb3, 0x0, - 0x2, 0xca, 0x6a, 0x30, 0x0, 0x0, 0x0, 0x0, - 0x5, 0x50, 0x1, 0x0, 0x0, 0x1, 0x38, 0xca, - 0xba, 0x80, 0x2c, 0xb9, 0x64, 0xb0, 0x0, 0x0, - 0x0, 0x0, 0x0, 0xb0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0xb0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xa3, - 0x0, 0x0, 0x0, 0x0, 0x0, 0x64, 0x0, 0x0, - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - - /* U+30AF "ク" */ - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x67, - 0x0, 0x0, 0x0, 0x0, 0xc6, 0x0, 0x0, 0x0, - 0x4, 0xe4, 0x46, 0x70, 0x0, 0xc, 0x56, 0x34, - 0xf4, 0x0, 0x94, 0x0, 0x9, 0x90, 0x7, 0x30, - 0x0, 0x3d, 0x0, 0x0, 0x0, 0x0, 0xc2, 0x0, - 0x0, 0x0, 0x9, 0x60, 0x0, 0x0, 0x0, 0x5a, - 0x0, 0x0, 0x0, 0x4, 0xb0, 0x0, 0x0, 0x0, - 0x5a, 0x0, 0x0, 0x0, 0x7, 0x50, 0x0, 0x0, - 0x0, 0x20, 0x0, 0x0, 0x0, 0x0, - - /* U+30B0 "グ" */ - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0xa, 0x40, 0x2, 0x93, 0x0, 0x0, 0x1e, 0x20, - 0x2a, 0x57, 0x0, 0x0, 0x9b, 0x55, 0x87, 0x60, - 0x0, 0x3, 0xb4, 0x42, 0x6f, 0x0, 0x0, 0x1b, - 0x10, 0x0, 0xd4, 0x0, 0x1, 0x70, 0x0, 0x7, - 0x80, 0x0, 0x0, 0x0, 0x0, 0x2c, 0x0, 0x0, - 0x0, 0x0, 0x0, 0xc2, 0x0, 0x0, 0x0, 0x0, - 0xa, 0x50, 0x0, 0x0, 0x0, 0x0, 0x87, 0x0, - 0x0, 0x0, 0x0, 0x9, 0x60, 0x0, 0x0, 0x0, - 0x2, 0x82, 0x0, 0x0, 0x0, 0x0, 0x1, 0x0, - 0x0, 0x0, 0x0, 0x0, - - /* U+30B1 "ケ" */ - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0xe2, 0x0, 0x0, 0x0, 0x0, 0x4, 0xe1, 0x0, - 0x0, 0x0, 0x0, 0xc, 0x31, 0x36, 0x9c, 0xb1, - 0x0, 0x7b, 0xca, 0x9b, 0x10, 0x0, 0x3, 0x90, - 0x0, 0x5c, 0x0, 0x0, 0x15, 0x0, 0x0, 0x95, - 0x0, 0x0, 0x0, 0x0, 0x0, 0xd0, 0x0, 0x0, - 0x0, 0x0, 0x7, 0x60, 0x0, 0x0, 0x0, 0x0, - 0x1a, 0x0, 0x0, 0x0, 0x0, 0x0, 0xa1, 0x0, - 0x0, 0x0, 0x0, 0x7, 0x10, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - - /* U+30B2 "ゲ" */ - 0x0, 0x0, 0x0, 0x0, 0x0, 0x30, 0x0, 0x0, - 0x1b, 0x0, 0x0, 0x21, 0xc2, 0x0, 0x6, 0xc0, - 0x0, 0x2, 0xc4, 0x30, 0x0, 0xc1, 0x1, 0x36, - 0x96, 0x20, 0x0, 0x8b, 0xb9, 0xba, 0x43, 0x0, - 0x0, 0x48, 0x0, 0x6, 0xb0, 0x0, 0x0, 0x25, - 0x0, 0x0, 0xb4, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x2b, 0x0, 0x0, 0x0, 0x0, 0x0, 0xb, 0x30, - 0x0, 0x0, 0x0, 0x0, 0x5, 0x80, 0x0, 0x0, - 0x0, 0x0, 0x2, 0x90, 0x0, 0x0, 0x0, 0x0, - 0x1, 0x60, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x0, 0x0, 0x0, - - /* U+30B3 "コ" */ - 0x0, 0x0, 0x0, 0x1, 0x10, 0x7, 0x78, 0x9a, - 0xab, 0xe1, 0x4, 0x53, 0x0, 0x3, 0xc0, 0x0, - 0x0, 0x0, 0x5, 0x80, 0x0, 0x0, 0x0, 0x7, - 0x50, 0x0, 0x0, 0x0, 0xa, 0x20, 0x0, 0x0, - 0x0, 0xc, 0x0, 0x2, 0x34, 0x68, 0xaf, 0x20, - 0x2b, 0x96, 0x42, 0x11, 0x0, - - /* U+30B4 "ゴ" */ - 0x0, 0x0, 0x0, 0x0, 0x1, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x20, 0xa5, 0x0, 0x0, 0x0, 0x0, - 0x4a, 0x18, 0x0, 0x0, 0x0, 0x2, 0x26, 0x30, - 0x15, 0x57, 0x99, 0x9b, 0xe0, 0x0, 0x7, 0x73, - 0x0, 0x4, 0xb0, 0x0, 0x0, 0x0, 0x0, 0x6, - 0x70, 0x0, 0x0, 0x0, 0x0, 0x9, 0x40, 0x0, - 0x0, 0x0, 0x0, 0xc, 0x10, 0x0, 0x0, 0x0, - 0x0, 0xd, 0x0, 0x0, 0x23, 0x45, 0x78, 0xae, - 0x0, 0x0, 0x29, 0x75, 0x32, 0x11, 0x0, 0x0, - - /* U+30B5 "サ" */ - 0x0, 0x0, 0x30, 0x0, 0xa2, 0x0, 0x0, 0x0, - 0x0, 0xf1, 0x0, 0xb4, 0x0, 0x0, 0x0, 0x0, - 0xc0, 0x0, 0xa2, 0x0, 0x0, 0x0, 0x1, 0xc4, - 0x68, 0xdb, 0xbc, 0xb0, 0x1c, 0xb8, 0xd4, 0x21, - 0xb1, 0x0, 0x0, 0x0, 0x0, 0xc0, 0x0, 0xc0, - 0x0, 0x0, 0x0, 0x0, 0xe0, 0x0, 0xd0, 0x0, - 0x0, 0x0, 0x0, 0x70, 0x2, 0xb0, 0x0, 0x0, - 0x0, 0x0, 0x0, 0x8, 0x50, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x2b, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x2, 0xb1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x16, - 0x0, 0x0, 0x0, 0x0, - - /* U+30B6 "ザ" */ - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x0, 0x0, 0x0, 0x6, 0x70, 0x0, - 0x0, 0x30, 0x0, 0xa1, 0x19, 0x28, 0x30, 0x0, - 0xd, 0x30, 0xc, 0x10, 0x2a, 0x0, 0x0, 0x0, - 0xa1, 0x0, 0xc0, 0x0, 0x0, 0x0, 0x0, 0xb, - 0x56, 0x8e, 0x99, 0xb9, 0x0, 0xb, 0xb9, 0xd5, - 0x20, 0xc0, 0x0, 0x0, 0x0, 0x0, 0xb, 0x10, - 0xc, 0x0, 0x0, 0x0, 0x0, 0x0, 0xd1, 0x0, - 0xb0, 0x0, 0x0, 0x0, 0x0, 0x6, 0x0, 0x38, - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xa, 0x20, - 0x0, 0x0, 0x0, 0x0, 0x0, 0x4, 0x80, 0x0, - 0x0, 0x0, 0x0, 0x0, 0x3, 0x70, 0x0, 0x0, - 0x0, 0x0, 0x0, 0x1, 0x40, 0x0, 0x0, 0x0, - 0x0, - - /* U+30B7 "シ" */ - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x69, - 0x20, 0x0, 0x0, 0x0, 0x0, 0x4, 0xe0, 0x0, - 0x0, 0x0, 0x0, 0x0, 0x30, 0x0, 0x0, 0x15, - 0x28, 0x40, 0x0, 0x0, 0x1, 0x90, 0x1, 0xc9, - 0x0, 0x0, 0x2b, 0x10, 0x0, 0x3, 0x0, 0x3, - 0xb1, 0x0, 0x0, 0x0, 0x0, 0x5a, 0x0, 0x0, - 0x0, 0x0, 0x2b, 0x90, 0x0, 0x0, 0x2, 0x6b, - 0xd4, 0x0, 0x0, 0x0, 0x3, 0xe6, 0x0, 0x0, - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - - /* U+30B8 "ジ" */ - 0x0, 0x0, 0x0, 0x0, 0x23, 0x0, 0x0, 0x0, - 0x0, 0x3, 0x29, 0x60, 0x0, 0x69, 0x20, 0x0, - 0xc3, 0x20, 0x0, 0x3, 0xe1, 0x0, 0x21, 0x0, - 0x0, 0x0, 0x20, 0x0, 0x0, 0x24, 0x7, 0x80, - 0x0, 0x0, 0x2, 0x90, 0x0, 0x7d, 0x0, 0x0, - 0x2b, 0x10, 0x0, 0x5, 0x0, 0x3, 0xc1, 0x0, - 0x0, 0x0, 0x0, 0x6b, 0x10, 0x0, 0x0, 0x0, - 0x1b, 0x80, 0x0, 0x0, 0x1, 0x6a, 0xc3, 0x0, - 0x0, 0x0, 0x1, 0xb7, 0x0, 0x0, 0x0, 0x0, - - /* U+30B9 "ス" */ - 0x0, 0x0, 0x0, 0x16, 0x90, 0x0, 0x5, 0x68, - 0xaa, 0x6f, 0x40, 0x0, 0x68, 0x30, 0x7, 0x90, - 0x0, 0x0, 0x0, 0x1, 0xd1, 0x0, 0x0, 0x0, - 0x0, 0xa6, 0x0, 0x0, 0x0, 0x0, 0x4d, 0x40, - 0x0, 0x0, 0x0, 0x2d, 0x16, 0x60, 0x0, 0x0, - 0x2d, 0x20, 0xa, 0x60, 0x0, 0x3c, 0x20, 0x0, - 0xe, 0x40, 0x68, 0x0, 0x0, 0x0, 0x6c, 0x21, - 0x0, 0x0, 0x0, 0x0, 0x60, - - /* U+30BA "ズ" */ - 0x0, 0x0, 0x0, 0x0, 0x0, 0x2, 0x0, 0x0, - 0x0, 0x0, 0x0, 0x2, 0x12, 0xc2, 0x0, 0x0, - 0x0, 0x5, 0x60, 0xa5, 0x22, 0x0, 0x55, 0x8a, - 0x99, 0xf1, 0x14, 0x0, 0x0, 0x97, 0x20, 0xa, - 0x70, 0x0, 0x0, 0x0, 0x0, 0x0, 0x2c, 0x0, - 0x0, 0x0, 0x0, 0x0, 0x0, 0xb3, 0x0, 0x0, - 0x0, 0x0, 0x0, 0x5, 0xd1, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x2c, 0x19, 0x30, 0x0, 0x0, 0x0, - 0x2, 0xb1, 0x0, 0xc5, 0x0, 0x0, 0x0, 0x3a, - 0x10, 0x0, 0x1e, 0x30, 0x0, 0x6, 0x60, 0x0, - 0x0, 0x7, 0x90, 0x0, 0x20, 0x0, 0x0, 0x0, - 0x0, 0x20, 0x0, - - /* U+30BB "セ" */ - 0x0, 0x2, 0x20, 0x0, 0x0, 0x0, 0x0, 0x4, - 0xf0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xe0, 0x0, - 0x19, 0x60, 0x0, 0x0, 0xd0, 0x49, 0x9a, 0xe0, - 0x0, 0x3, 0xe9, 0x60, 0x1c, 0x10, 0x39, 0xc8, - 0xd0, 0x0, 0x91, 0x0, 0x4, 0x0, 0xd0, 0x3, - 0x20, 0x0, 0x0, 0x0, 0xd0, 0x0, 0x0, 0x0, - 0x0, 0x0, 0xd0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0xb6, 0x22, 0x36, 0x70, 0x0, 0x0, 0x19, 0xbb, - 0x98, 0x30, - - /* U+30BC "ゼ" */ - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x0, 0x0, 0x96, 0x0, 0x1, 0x10, - 0x0, 0x0, 0xa5, 0x80, 0x0, 0x4e, 0x0, 0x0, - 0x1, 0x90, 0x0, 0x1, 0xd0, 0x0, 0x6, 0x40, - 0x0, 0x0, 0x1c, 0x2, 0x8a, 0xce, 0x0, 0x0, - 0x3, 0xea, 0x71, 0x2c, 0x10, 0x2, 0x7b, 0x9c, - 0x0, 0xa, 0x10, 0x0, 0x16, 0x1, 0xc0, 0x6, - 0x10, 0x0, 0x0, 0x0, 0x1c, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x0, 0xd0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0xd, 0x40, 0x12, 0x57, 0x0, 0x0, 0x0, - 0x3a, 0xbc, 0xba, 0x50, 0x0, - - /* U+30BD "ソ" */ - 0x0, 0x0, 0x0, 0x0, 0x40, 0x35, 0x0, 0x0, - 0x0, 0xf5, 0xb, 0x50, 0x0, 0x2, 0xe0, 0x4, - 0xe0, 0x0, 0x8, 0x80, 0x0, 0xa0, 0x0, 0x1e, - 0x10, 0x0, 0x0, 0x0, 0x97, 0x0, 0x0, 0x0, - 0x3, 0xc0, 0x0, 0x0, 0x0, 0x1c, 0x20, 0x0, - 0x0, 0x0, 0xb3, 0x0, 0x0, 0x0, 0xa, 0x30, - 0x0, 0x0, 0x2, 0x81, 0x0, 0x0, 0x0, 0x3, - 0x0, 0x0, 0x0, 0x0, - - /* U+30BF "タ" */ - 0x0, 0x0, 0x2, 0x10, 0x0, 0x0, 0x0, 0x0, - 0xaa, 0x0, 0x51, 0x0, 0x0, 0x2f, 0xaa, 0xaf, - 0x80, 0x0, 0xc, 0x42, 0x12, 0xe1, 0x0, 0xa, - 0xa0, 0x0, 0xa6, 0x0, 0xa, 0x43, 0xc3, 0x3c, - 0x0, 0x6, 0x10, 0x4, 0xed, 0x20, 0x0, 0x0, - 0x0, 0xc, 0x60, 0x0, 0x0, 0x0, 0x7, 0x90, - 0x0, 0x0, 0x0, 0x7, 0x90, 0x0, 0x0, 0x0, - 0x1a, 0x60, 0x0, 0x0, 0x0, 0x58, 0x20, 0x0, - 0x0, 0x0, 0x21, 0x0, 0x0, 0x0, 0x0, 0x0, - - /* U+30C0 "ダ" */ - 0x0, 0x0, 0x0, 0x0, 0x0, 0x5, 0x10, 0x0, - 0x0, 0x2, 0x0, 0x0, 0x52, 0xc2, 0x0, 0x0, - 0x1f, 0x20, 0x35, 0x2d, 0x31, 0x0, 0x0, 0x9d, - 0x8a, 0xaf, 0x13, 0x0, 0x0, 0x4, 0xc3, 0x20, - 0x97, 0x0, 0x0, 0x0, 0x3d, 0x30, 0x2, 0xd0, - 0x0, 0x0, 0x4, 0xa0, 0x98, 0xb, 0x40, 0x0, - 0x0, 0x24, 0x0, 0xb, 0xa9, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x4, 0xd0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x1d, 0x20, 0x0, 0x0, 0x0, 0x0, 0x1, - 0xb2, 0x0, 0x0, 0x0, 0x0, 0x0, 0x3a, 0x20, - 0x0, 0x0, 0x0, 0x0, 0x6, 0x70, 0x0, 0x0, - 0x0, 0x0, 0x0, 0x30, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, - - /* U+30C1 "チ" */ - 0x0, 0x0, 0x0, 0x0, 0x10, 0x0, 0x0, 0x0, - 0x0, 0x3b, 0xe1, 0x0, 0x0, 0x4, 0x8b, 0xc3, - 0x0, 0x0, 0x0, 0x22, 0x1, 0xf1, 0x0, 0x0, - 0x0, 0x0, 0x0, 0xe2, 0x35, 0x61, 0x49, 0x9a, - 0xaa, 0xe8, 0x77, 0x75, 0x3, 0x20, 0x3, 0xa0, - 0x0, 0x0, 0x0, 0x0, 0x7, 0x60, 0x0, 0x0, - 0x0, 0x0, 0xd, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x76, 0x0, 0x0, 0x0, 0x0, 0x4, 0x90, 0x0, - 0x0, 0x0, 0x0, 0x47, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x20, 0x0, 0x0, 0x0, 0x0, - - /* U+30C3 "ッ" */ - 0x0, 0x1, 0x0, 0x0, 0x0, 0x20, 0x73, 0x0, - 0xe3, 0x9, 0x41, 0xc0, 0x1f, 0x10, 0x39, 0x2, - 0x7, 0x80, 0x0, 0x0, 0x0, 0xd1, 0x0, 0x0, - 0x0, 0x94, 0x0, 0x0, 0x0, 0x68, 0x0, 0x0, - 0x0, 0x67, 0x0, 0x0, 0x0, 0x33, 0x0, 0x0, - 0x0, - - /* U+30C4 "ツ" */ - 0x0, 0x2, 0x0, 0x0, 0x0, 0x10, 0x9, 0x20, - 0x0, 0x75, 0x81, 0x2, 0xe0, 0x0, 0xa8, 0x3d, - 0x0, 0xc0, 0x1, 0xd0, 0xd, 0x10, 0x0, 0x9, - 0x50, 0x1, 0x0, 0x0, 0x2b, 0x0, 0x0, 0x0, - 0x0, 0xc2, 0x0, 0x0, 0x0, 0x8, 0x60, 0x0, - 0x0, 0x0, 0x59, 0x0, 0x0, 0x0, 0x5, 0x80, - 0x0, 0x0, 0x0, 0x55, 0x0, 0x0, 0x0, 0x1, - 0x0, 0x0, 0x0, 0x0, - - /* U+30C6 "テ" */ - 0x0, 0x2, 0x35, 0x7b, 0x70, 0x0, 0x0, 0x77, - 0x53, 0x10, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x1, 0x23, 0x45, 0x78, 0x9b, 0xda, 0x2a, 0x85, - 0x38, 0x90, 0x0, 0x0, 0x0, 0x0, 0x98, 0x0, - 0x0, 0x0, 0x0, 0xd, 0x10, 0x0, 0x0, 0x0, - 0x5, 0x80, 0x0, 0x0, 0x0, 0x0, 0xc0, 0x0, - 0x0, 0x0, 0x0, 0x94, 0x0, 0x0, 0x0, 0x0, - 0x74, 0x0, 0x0, 0x0, 0x0, 0x11, 0x0, 0x0, - 0x0, 0x0, - - /* U+30C7 "デ" */ - 0x0, 0x0, 0x0, 0x0, 0x0, 0x1, 0x0, 0x0, - 0x0, 0x0, 0x0, 0x0, 0x7, 0x80, 0x0, 0x3, - 0x35, 0x7a, 0x70, 0x95, 0x90, 0x0, 0x6, 0x64, - 0x21, 0x0, 0x7, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x0, 0x1, 0x24, 0x68, 0x9a, 0xbc, - 0x80, 0x0, 0x29, 0x75, 0x25, 0xb0, 0x0, 0x0, - 0x0, 0x0, 0x0, 0x8, 0x70, 0x0, 0x0, 0x0, - 0x0, 0x0, 0xd, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x67, 0x0, 0x0, 0x0, 0x0, 0x0, 0x1, - 0xc0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xa, 0x20, - 0x0, 0x0, 0x0, 0x0, 0x0, 0x73, 0x0, 0x0, - 0x0, 0x0, 0x0, 0x2, 0x10, 0x0, 0x0, 0x0, - 0x0, 0x0, - - /* U+30C8 "ト" */ - 0x0, 0x0, 0x0, 0x5, 0xb0, 0x0, 0x0, 0x3a, - 0x0, 0x0, 0x3, 0x90, 0x0, 0x0, 0x2b, 0x0, - 0x0, 0x2, 0x97, 0x81, 0x0, 0x29, 0x4, 0xe6, - 0x2, 0x90, 0x2, 0xd0, 0x29, 0x0, 0x0, 0x3, - 0x90, 0x0, 0x0, 0x49, 0x0, 0x0, 0x4, 0xa0, - 0x0, 0x0, 0x4, 0x0, 0x0, 0x0, - - /* U+30C9 "ド" */ - 0x0, 0x0, 0x0, 0x0, 0x1, 0xe1, 0x0, 0x2, - 0x50, 0xe, 0x0, 0x7, 0x36, 0x90, 0xc0, 0x0, - 0x1d, 0x2, 0xc, 0x10, 0x0, 0x10, 0x0, 0xc5, - 0x93, 0x0, 0x0, 0xc, 0x2, 0xd8, 0x0, 0x0, - 0xc0, 0x1, 0xd1, 0x0, 0xc, 0x0, 0x0, 0x0, - 0x0, 0xc0, 0x0, 0x0, 0x0, 0xe, 0x0, 0x0, - 0x0, 0x0, 0xd0, 0x0, 0x0, 0x0, 0x3, 0x0, - 0x0, 0x0, 0x0, - - /* U+30CA "ナ" */ - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x7, 0xb0, 0x0, 0x0, 0x0, 0x0, 0x4, 0xb0, - 0x0, 0x0, 0x0, 0x0, 0x3, 0xa0, 0x0, 0x0, - 0x0, 0x0, 0x27, 0xc8, 0xac, 0xc1, 0x5d, 0xca, - 0x78, 0x91, 0x0, 0x0, 0x0, 0x0, 0x6, 0x50, - 0x0, 0x0, 0x0, 0x0, 0xa, 0x20, 0x0, 0x0, - 0x0, 0x0, 0xc, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x75, 0x0, 0x0, 0x0, 0x0, 0x1, 0xa0, 0x0, - 0x0, 0x0, 0x0, 0x9, 0x10, 0x0, 0x0, 0x0, - 0x0, 0x30, 0x0, 0x0, 0x0, 0x0, - - /* U+30CB "ニ" */ - 0x0, 0x0, 0x0, 0x1, 0x23, 0x0, 0x0, 0x0, - 0x2c, 0xa9, 0x98, 0x83, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x0, 0x1, 0x23, 0x45, 0x62, 0xb, - 0xca, 0x99, 0x87, 0x65, 0x55, 0x40, 0x0, 0x0, - 0x0, 0x0, 0x0, 0x0, - - /* U+30CD "ネ" */ - 0x0, 0x0, 0x43, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x8, 0xc0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x30, - 0x0, 0x0, 0x0, 0x0, 0x4, 0x8c, 0xd0, 0x0, - 0x0, 0x6b, 0xa5, 0x1d, 0x40, 0x0, 0x0, 0x1, - 0x0, 0xb4, 0x0, 0x0, 0x0, 0x0, 0xc, 0x60, - 0x0, 0x0, 0x0, 0x1, 0xb6, 0xc0, 0x87, 0x0, - 0x0, 0x49, 0x11, 0xa0, 0x9, 0xb0, 0x6, 0x40, - 0x1, 0xa0, 0x0, 0x90, 0x0, 0x0, 0x1, 0xb0, - 0x0, 0x0, 0x0, 0x0, 0x3, 0xb0, 0x0, 0x0, - 0x0, 0x0, 0x0, 0x60, 0x0, 0x0, - - /* U+30CE "ノ" */ - 0x0, 0x0, 0x0, 0x0, 0x3, 0x10, 0x0, 0x0, - 0x0, 0x0, 0xb9, 0x0, 0x0, 0x0, 0x0, 0x2e, - 0x10, 0x0, 0x0, 0x0, 0xc, 0x50, 0x0, 0x0, - 0x0, 0x8, 0x90, 0x0, 0x0, 0x0, 0x4, 0xb0, - 0x0, 0x0, 0x0, 0x3, 0xc1, 0x0, 0x0, 0x0, - 0x3, 0xb1, 0x0, 0x0, 0x0, 0x5, 0xa0, 0x0, - 0x0, 0x0, 0x8, 0x60, 0x0, 0x0, 0x0, 0x15, - 0x10, 0x0, 0x0, 0x0, 0x0, - - /* U+30CF "ハ" */ - 0x0, 0x0, 0x17, 0x0, 0x10, 0x0, 0x0, 0x0, - 0x5, 0xf1, 0x0, 0x81, 0x0, 0x0, 0x0, 0xc5, - 0x0, 0x1, 0xb1, 0x0, 0x0, 0x79, 0x0, 0x0, - 0x5, 0xc0, 0x0, 0x2b, 0x0, 0x0, 0x0, 0xc, - 0x70, 0x1a, 0x10, 0x0, 0x0, 0x0, 0x4d, 0x6, - 0x0, 0x0, 0x0, 0x0, 0x0, 0x60, - - /* U+30D0 "バ" */ - 0x0, 0x0, 0x0, 0x0, 0x0, 0x5, 0x0, 0x0, - 0x0, 0x0, 0x0, 0x3, 0x34, 0xb0, 0x0, 0x0, - 0x0, 0x0, 0x0, 0xb4, 0x40, 0x0, 0x0, 0x5, - 0x0, 0x2, 0x11, 0x0, 0x0, 0x0, 0x5e, 0x0, - 0x6, 0x20, 0x0, 0x0, 0x0, 0xc4, 0x0, 0x0, - 0xa1, 0x0, 0x0, 0x5, 0x80, 0x0, 0x0, 0x4c, - 0x0, 0x0, 0x2a, 0x0, 0x0, 0x0, 0xb, 0x60, - 0x1, 0x91, 0x0, 0x0, 0x0, 0x4, 0xd0, 0x5, - 0x0, 0x0, 0x0, 0x0, 0x0, 0x70, - - /* U+30D1 "パ" */ - 0x0, 0x0, 0x0, 0x0, 0x0, 0x67, 0x10, 0x0, - 0x0, 0x0, 0x0, 0x0, 0x61, 0x60, 0x0, 0x0, - 0x0, 0x0, 0x0, 0x46, 0x10, 0x0, 0x0, 0x6, - 0x0, 0x4, 0x0, 0x0, 0x0, 0x0, 0x1f, 0x30, - 0x3, 0x60, 0x0, 0x0, 0x0, 0x88, 0x0, 0x0, - 0x94, 0x0, 0x0, 0x2, 0xb0, 0x0, 0x0, 0x1e, - 0x10, 0x0, 0xb, 0x10, 0x0, 0x0, 0x8, 0xa0, - 0x0, 0x83, 0x0, 0x0, 0x0, 0x1, 0xf1, 0x4, - 0x10, 0x0, 0x0, 0x0, 0x0, 0x70, - - /* U+30D2 "ヒ" */ - 0x11, 0x0, 0x0, 0x0, 0x2, 0xf0, 0x0, 0x0, - 0x0, 0xd, 0x0, 0x0, 0x0, 0x0, 0xd0, 0x1, - 0x5c, 0xc0, 0xe, 0x67, 0x75, 0x32, 0x0, 0xc0, - 0x0, 0x0, 0x0, 0xc, 0x0, 0x0, 0x0, 0x0, - 0xc0, 0x0, 0x0, 0x0, 0xd, 0x0, 0x0, 0x0, - 0x0, 0xc6, 0x21, 0x23, 0x65, 0x1, 0x7a, 0xaa, - 0x98, 0x40, - - /* U+30D3 "ビ" */ - 0x30, 0x0, 0x0, 0x5, 0x10, 0xd5, 0x0, 0x0, - 0x42, 0xd1, 0xb2, 0x0, 0x0, 0x4d, 0x30, 0xb2, - 0x0, 0x1, 0x82, 0x0, 0xb2, 0x1, 0x8d, 0xb3, - 0x0, 0xb6, 0x78, 0x30, 0x0, 0x0, 0xb3, 0x0, - 0x0, 0x0, 0x0, 0xb1, 0x0, 0x0, 0x0, 0x0, - 0xb2, 0x0, 0x0, 0x0, 0x0, 0x7a, 0x42, 0x23, - 0x68, 0x0, 0x5, 0x89, 0x99, 0x75, 0x0, - - /* U+30D4 "ピ" */ - 0x0, 0x0, 0x0, 0x0, 0x10, 0x3, 0x40, 0x0, - 0x0, 0x32, 0x60, 0x4d, 0x0, 0x0, 0x3, 0x9a, - 0x3, 0xa0, 0x0, 0x0, 0x1, 0x10, 0x2a, 0x0, - 0x4, 0xdb, 0x0, 0x2, 0xa0, 0x6a, 0x84, 0x0, - 0x0, 0x2c, 0x61, 0x0, 0x0, 0x0, 0x3, 0x90, - 0x0, 0x0, 0x0, 0x0, 0x39, 0x0, 0x0, 0x0, - 0x0, 0x1, 0xc0, 0x0, 0x0, 0x0, 0x0, 0x7, - 0xdc, 0xbc, 0xdd, 0x60, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, - - /* U+30D5 "フ" */ - 0x0, 0x0, 0x0, 0x0, 0x25, 0x30, 0x7, 0x78, - 0x9a, 0xa9, 0x7a, 0xe0, 0x3, 0x63, 0x10, 0x0, - 0xd, 0x50, 0x0, 0x0, 0x0, 0x0, 0x6a, 0x0, - 0x0, 0x0, 0x0, 0x1, 0xd1, 0x0, 0x0, 0x0, - 0x0, 0xb, 0x40, 0x0, 0x0, 0x0, 0x0, 0x97, - 0x0, 0x0, 0x0, 0x0, 0x9, 0x70, 0x0, 0x0, - 0x0, 0x0, 0x95, 0x0, 0x0, 0x0, 0x0, 0x29, - 0x20, 0x0, 0x0, 0x0, 0x1, 0x40, 0x0, 0x0, - 0x0, 0x0, - - /* U+30D6 "ブ" */ - 0x0, 0x0, 0x0, 0x0, 0x0, 0x1, 0x10, 0x0, - 0x0, 0x0, 0x0, 0x0, 0x30, 0xa4, 0x0, 0x0, - 0x0, 0x0, 0x0, 0x3c, 0x17, 0x0, 0x2, 0x36, - 0x8a, 0xbe, 0x25, 0x0, 0x5d, 0xb8, 0x64, 0x10, - 0x4e, 0x10, 0x0, 0x0, 0x0, 0x0, 0x0, 0xc4, - 0x0, 0x0, 0x0, 0x0, 0x0, 0x6, 0x90, 0x0, - 0x0, 0x0, 0x0, 0x0, 0x2c, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x1, 0xc2, 0x0, 0x0, 0x0, 0x0, - 0x0, 0xb, 0x40, 0x0, 0x0, 0x0, 0x0, 0x1, - 0xb3, 0x0, 0x0, 0x0, 0x0, 0x0, 0x3a, 0x20, - 0x0, 0x0, 0x0, 0x0, 0x5, 0x50, 0x0, 0x0, - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, - - /* U+30D7 "プ" */ - 0x0, 0x0, 0x0, 0x0, 0x0, 0x2, 0x40, 0x0, - 0x0, 0x0, 0x0, 0x0, 0x7, 0x34, 0x0, 0x0, - 0x0, 0x0, 0x0, 0x7, 0x73, 0x0, 0x0, 0x24, - 0x69, 0xbc, 0x10, 0x0, 0x7d, 0xca, 0x86, 0x31, - 0x4e, 0x10, 0x0, 0x0, 0x0, 0x0, 0x0, 0xc4, - 0x0, 0x0, 0x0, 0x0, 0x0, 0x6, 0x90, 0x0, - 0x0, 0x0, 0x0, 0x0, 0x2d, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x0, 0xc3, 0x0, 0x0, 0x0, 0x0, - 0x0, 0xb, 0x40, 0x0, 0x0, 0x0, 0x0, 0x0, - 0xb4, 0x0, 0x0, 0x0, 0x0, 0x0, 0x2a, 0x20, - 0x0, 0x0, 0x0, 0x0, 0x5, 0x60, 0x0, 0x0, - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, - - /* U+30D9 "ベ" */ - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x0, 0x0, 0x75, 0x0, 0x0, 0x0, - 0x12, 0x0, 0x2a, 0x1c, 0x0, 0x0, 0x3, 0xcb, - 0x50, 0x4, 0x60, 0x0, 0x0, 0x3c, 0x10, 0xb4, - 0x0, 0x0, 0x0, 0x4, 0xd1, 0x0, 0x1c, 0x40, - 0x0, 0x0, 0x3c, 0x20, 0x0, 0x1, 0xd4, 0x0, - 0x0, 0x0, 0x0, 0x0, 0x0, 0x2d, 0x50, 0x0, - 0x0, 0x0, 0x0, 0x0, 0x2, 0xd8, 0x0, 0x0, - 0x0, 0x0, 0x0, 0x0, 0x1b, 0xd0, 0x0, 0x0, - 0x0, 0x0, 0x0, 0x0, 0x10, - - /* U+30DA "ペ" */ - 0x0, 0x0, 0x0, 0x0, 0x42, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x4, 0x37, 0x0, 0x0, 0x0, 0x0, - 0x35, 0x2, 0x78, 0x0, 0x0, 0x0, 0x5, 0xb9, - 0x80, 0x0, 0x0, 0x0, 0x0, 0x5b, 0x0, 0x97, - 0x0, 0x0, 0x0, 0x7, 0xc0, 0x0, 0xb, 0x60, - 0x0, 0x0, 0x29, 0x10, 0x0, 0x0, 0xc6, 0x0, - 0x0, 0x0, 0x0, 0x0, 0x0, 0xc, 0x80, 0x0, - 0x0, 0x0, 0x0, 0x0, 0x0, 0xbb, 0x20, 0x0, - 0x0, 0x0, 0x0, 0x0, 0x8, 0xd0, 0x0, 0x0, - 0x0, 0x0, 0x0, 0x0, 0x0, - - /* U+30DB "ホ" */ - 0x0, 0x0, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, - 0xc6, 0x0, 0x0, 0x0, 0x0, 0x9, 0x40, 0x0, - 0x0, 0x0, 0x0, 0x93, 0x13, 0x52, 0x9, 0xaa, - 0xad, 0xb9, 0x88, 0x70, 0x11, 0x0, 0x93, 0x0, - 0x0, 0x0, 0x0, 0x9, 0x30, 0x20, 0x0, 0x7, - 0x0, 0x93, 0x2, 0x80, 0x3, 0x90, 0x9, 0x30, - 0x9, 0x61, 0xd3, 0x0, 0x83, 0x0, 0x2d, 0x13, - 0x0, 0x8d, 0x40, 0x0, 0x30, 0x0, 0x1, 0xc1, - 0x0, 0x0, - - /* U+30DC "ボ" */ - 0x0, 0x0, 0x0, 0x0, 0x1, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x20, 0xb3, 0x0, 0x0, 0xe, 0x20, - 0x5a, 0x37, 0x0, 0x0, 0xc, 0x10, 0x7, 0x0, - 0x0, 0x0, 0xb, 0x0, 0x24, 0x10, 0x19, 0x99, - 0x9e, 0x99, 0x88, 0x50, 0x2, 0x20, 0xb, 0x0, - 0x0, 0x0, 0x0, 0x0, 0xb, 0x0, 0x10, 0x0, - 0x0, 0x70, 0xb, 0x10, 0x27, 0x0, 0x2, 0x90, - 0xb, 0x10, 0x9, 0x60, 0xd, 0x40, 0xb, 0x10, - 0x2, 0xd0, 0x24, 0x1, 0x8d, 0x10, 0x0, 0x30, - 0x0, 0x0, 0x4c, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x0, 0x0, - - /* U+30DD "ポ" */ - 0x0, 0x0, 0x1, 0x2, 0x76, 0x0, 0x0, 0x0, - 0xe2, 0x42, 0x60, 0x0, 0x0, 0xc, 0x10, 0x64, - 0x0, 0x0, 0x0, 0xb0, 0x13, 0x51, 0x1a, 0xaa, - 0x9e, 0x98, 0x77, 0x50, 0x11, 0x0, 0xb0, 0x0, - 0x0, 0x0, 0x0, 0xb, 0x0, 0x20, 0x0, 0x7, - 0x0, 0xb1, 0x2, 0x80, 0x3, 0x90, 0xb, 0x10, - 0x9, 0x61, 0xd3, 0x0, 0xb1, 0x0, 0x2d, 0x13, - 0x1, 0x9e, 0x10, 0x0, 0x30, 0x0, 0x3, 0xb0, - 0x0, 0x0, - - /* U+30DE "マ" */ - 0x0, 0x0, 0x0, 0x1, 0x36, 0x60, 0x4c, 0xba, - 0x99, 0x98, 0x65, 0xf4, 0x0, 0x0, 0x0, 0x0, - 0xc, 0x70, 0x0, 0x0, 0x10, 0x1, 0xa3, 0x0, - 0x0, 0x0, 0x83, 0x18, 0x10, 0x0, 0x0, 0x0, - 0xc, 0x70, 0x0, 0x0, 0x0, 0x0, 0x4, 0xd0, - 0x0, 0x0, 0x0, 0x0, 0x0, 0xc5, 0x0, 0x0, - 0x0, 0x0, 0x0, 0x32, 0x0, 0x0, - - /* U+30DF "ミ" */ - 0x1, 0x67, 0x20, 0x0, 0x0, 0x3, 0xcc, 0x30, - 0x0, 0x0, 0x6, 0xb0, 0x0, 0x0, 0x0, 0x0, - 0x1, 0x78, 0x30, 0x0, 0x0, 0x2, 0xcc, 0x0, - 0x0, 0x0, 0x7, 0x20, 0x0, 0x0, 0x0, 0x0, - 0x5, 0x85, 0x0, 0x0, 0x0, 0x6, 0xd9, 0x10, - 0x0, 0x0, 0x9, 0xc0, 0x0, 0x0, 0x0, 0x40, - - /* U+30E0 "ム" */ - 0x0, 0x0, 0x4, 0x20, 0x0, 0x0, 0x0, 0x0, - 0xaa, 0x0, 0x0, 0x0, 0x0, 0xe, 0x20, 0x0, - 0x0, 0x0, 0x5, 0x90, 0x0, 0x0, 0x0, 0x0, - 0xc2, 0x0, 0x0, 0x0, 0x0, 0x49, 0x0, 0x20, - 0x0, 0x0, 0xb, 0x10, 0x3, 0x80, 0x0, 0x4, - 0x70, 0x0, 0x8, 0x90, 0x0, 0xb0, 0x26, 0x98, - 0x5d, 0x50, 0xbe, 0xd9, 0x40, 0x0, 0x6a, 0x5, - 0x50, 0x0, 0x0, 0x0, 0x30, - - /* U+30E1 "メ" */ - 0x0, 0x0, 0x0, 0x0, 0x6, 0x0, 0x0, 0x0, - 0x0, 0x0, 0xf5, 0x0, 0x0, 0x0, 0x0, 0x5c, - 0x0, 0x0, 0x4, 0x10, 0xd, 0x20, 0x0, 0x0, - 0x6, 0x88, 0x80, 0x0, 0x0, 0x0, 0x5, 0xf7, - 0x0, 0x0, 0x0, 0x0, 0xc3, 0xca, 0x0, 0x0, - 0x0, 0xa5, 0x1, 0xd1, 0x0, 0x0, 0x96, 0x0, - 0x1, 0x0, 0x0, 0x95, 0x0, 0x0, 0x0, 0x2, - 0x82, 0x0, 0x0, 0x0, 0x0, 0x20, 0x0, 0x0, - 0x0, 0x0, - - /* U+30E2 "モ" */ - 0x0, 0x0, 0x3, 0x59, 0xc7, 0x0, 0x2, 0xba, - 0xac, 0x31, 0x0, 0x0, 0x0, 0x0, 0xf, 0x0, - 0x0, 0x0, 0x0, 0x0, 0xc, 0x0, 0x13, 0x10, - 0x14, 0x57, 0x9e, 0x9a, 0xa9, 0x90, 0x17, 0x52, - 0xc, 0x0, 0x0, 0x0, 0x0, 0x0, 0xc, 0x0, - 0x0, 0x0, 0x0, 0x0, 0xc, 0x0, 0x0, 0x0, - 0x0, 0x0, 0xb, 0x42, 0x24, 0x20, 0x0, 0x0, - 0x1, 0x8a, 0xa9, 0x20, - - /* U+30E3 "ャ" */ - 0x0, 0xc, 0x40, 0x0, 0x0, 0x0, 0x0, 0x77, - 0x0, 0x5, 0x10, 0x0, 0x1, 0xc6, 0x98, 0xca, - 0x2, 0x7a, 0x9d, 0x30, 0xa, 0x0, 0x3, 0x0, - 0x75, 0x5, 0x10, 0x0, 0x0, 0x2, 0xa0, 0x10, - 0x0, 0x0, 0x0, 0xd, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x95, 0x0, 0x0, 0x0, 0x0, 0x3, 0x70, - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - - /* U+30E4 "ヤ" */ - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0xb, 0x80, 0x0, 0x0, 0x0, 0x0, 0x0, 0x4a, - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xd0, 0x0, - 0x49, 0xd3, 0x0, 0x0, 0xc, 0x7a, 0x96, 0x2e, - 0x30, 0x68, 0xaa, 0xa8, 0x0, 0x7, 0x50, 0x3, - 0x40, 0x2, 0xa0, 0x1, 0x80, 0x0, 0x0, 0x0, - 0xc, 0x0, 0x60, 0x0, 0x0, 0x0, 0x0, 0x83, - 0x0, 0x0, 0x0, 0x0, 0x0, 0x4, 0x70, 0x0, - 0x0, 0x0, 0x0, 0x0, 0x1c, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x0, 0xd0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x2, 0x0, 0x0, 0x0, - - /* U+30E5 "ュ" */ - 0x0, 0x0, 0x1, 0x20, 0x0, 0x2, 0xba, 0x99, - 0xf0, 0x0, 0x0, 0x0, 0x4, 0xa0, 0x0, 0x0, - 0x0, 0x9, 0x40, 0x0, 0x0, 0x0, 0xd, 0x0, - 0x0, 0x3c, 0xba, 0xac, 0xbc, 0xd5, 0x0, 0x0, - 0x0, 0x0, 0x0, - - /* U+30E7 "ョ" */ - 0x0, 0x0, 0x0, 0x10, 0x7, 0xcb, 0xbb, 0xf3, - 0x0, 0x0, 0x0, 0xd2, 0x0, 0x0, 0x0, 0xd0, - 0x5, 0xcb, 0xaa, 0xb0, 0x0, 0x0, 0x3, 0x90, - 0x0, 0x0, 0x6, 0x70, 0x2c, 0xba, 0xaa, 0x70, - - /* U+30E8 "ヨ" */ - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8, 0xaa, - 0xbb, 0xbd, 0xd0, 0x0, 0x2, 0x10, 0x0, 0x2f, - 0x0, 0x0, 0x0, 0x0, 0x3, 0xb0, 0x0, 0x0, - 0x0, 0x0, 0x58, 0x0, 0x8, 0xdc, 0xaa, 0xad, - 0x50, 0x0, 0x0, 0x0, 0x0, 0x93, 0x0, 0x0, - 0x0, 0x0, 0xc, 0x0, 0x0, 0x0, 0x0, 0x1, - 0xc0, 0x0, 0x7e, 0xcb, 0xaa, 0xab, 0x20, 0x0, - 0x0, 0x0, 0x0, 0x0, 0x0, - - /* U+30E9 "ラ" */ - 0x1, 0x43, 0x45, 0x7a, 0x60, 0x0, 0x78, 0x64, - 0x32, 0x10, 0x0, 0x0, 0x0, 0x0, 0x0, 0x11, - 0x23, 0x58, 0xab, 0xe8, 0x5c, 0x97, 0x53, 0x10, - 0xb6, 0x0, 0x0, 0x0, 0x4, 0xc0, 0x0, 0x0, - 0x0, 0x1d, 0x20, 0x0, 0x0, 0x0, 0xb4, 0x0, - 0x0, 0x0, 0xb, 0x50, 0x0, 0x0, 0x1, 0xb4, - 0x0, 0x0, 0x0, 0x59, 0x10, 0x0, 0x0, 0x2, - 0x20, 0x0, 0x0, 0x0, - - /* U+30EA "リ" */ - 0x0, 0x0, 0x1, 0x2, 0x90, 0x0, 0xc6, 0xf, - 0x0, 0x9, 0x60, 0xd0, 0x0, 0x94, 0xd, 0x0, - 0x9, 0x40, 0xd0, 0x0, 0xa3, 0xe, 0x0, 0xb, - 0x20, 0xa0, 0x0, 0xd0, 0x0, 0x0, 0x2b, 0x0, - 0x0, 0x9, 0x40, 0x0, 0x5, 0x90, 0x0, 0x4, - 0x80, 0x0, 0x3, 0x30, 0x0, 0x0, - - /* U+30EB "ル" */ - 0x0, 0x0, 0x0, 0x91, 0x0, 0x0, 0x0, 0x0, - 0x2, 0x0, 0xc5, 0x0, 0x0, 0x0, 0x0, 0x2f, - 0x0, 0xa3, 0x0, 0x0, 0x0, 0x0, 0xe, 0x0, - 0xa3, 0x0, 0x0, 0x50, 0x0, 0xd, 0x0, 0xa3, - 0x0, 0x4, 0x40, 0x0, 0x1b, 0x0, 0xa3, 0x0, - 0x48, 0x0, 0x0, 0x48, 0x0, 0xa3, 0x6, 0x90, - 0x0, 0x0, 0xa2, 0x0, 0xa5, 0xb8, 0x0, 0x0, - 0x4, 0x70, 0x0, 0xbf, 0x40, 0x0, 0x0, 0x5, - 0x0, 0x0, 0x12, 0x0, 0x0, 0x0, - - /* U+30EC "レ" */ - 0x9, 0x20, 0x0, 0x0, 0x0, 0xc, 0x60, 0x0, - 0x0, 0x0, 0xb, 0x40, 0x0, 0x0, 0x0, 0xb, - 0x30, 0x0, 0x0, 0x0, 0xb, 0x20, 0x0, 0x2, - 0x50, 0xb, 0x20, 0x0, 0x78, 0x0, 0xb, 0x20, - 0x5b, 0x40, 0x0, 0xb, 0x7c, 0x90, 0x0, 0x0, - 0xa, 0xd3, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, - - /* U+30ED "ロ" */ - 0x0, 0x0, 0x0, 0x0, 0x0, 0x36, 0x55, 0x79, - 0xbc, 0xe2, 0x4d, 0x64, 0x31, 0x0, 0xf4, 0xc, - 0x0, 0x0, 0x2, 0xc0, 0xd, 0x0, 0x0, 0x5, - 0x70, 0xc, 0x0, 0x0, 0x8, 0x30, 0xd, 0x0, - 0x0, 0xc, 0x0, 0xe, 0x67, 0x9b, 0xcf, 0x20, - 0xc, 0x43, 0x10, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, - - /* U+30EF "ワ" */ - 0x0, 0x0, 0x0, 0x0, 0x41, 0x9, 0x98, 0x9b, - 0xbb, 0xbc, 0xd0, 0x97, 0x21, 0x0, 0x0, 0x8a, - 0x8, 0x60, 0x0, 0x0, 0xd, 0x10, 0x86, 0x0, - 0x0, 0x6, 0x80, 0x7, 0x70, 0x0, 0x1, 0xc0, - 0x0, 0x1, 0x0, 0x0, 0xa4, 0x0, 0x0, 0x0, - 0x0, 0x68, 0x0, 0x0, 0x0, 0x0, 0x49, 0x0, - 0x0, 0x0, 0x0, 0x48, 0x0, 0x0, 0x0, 0x0, - 0x65, 0x0, 0x0, 0x0, 0x0, 0x31, 0x0, 0x0, - 0x0, 0x0, - - /* U+30F3 "ン" */ - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x6, 0x60, - 0x0, 0x0, 0x0, 0x0, 0x0, 0x7d, 0x20, 0x0, - 0x0, 0x2, 0x0, 0x7, 0x80, 0x0, 0x0, 0x90, - 0x0, 0x0, 0x0, 0x0, 0xa, 0x20, 0x0, 0x0, - 0x0, 0x0, 0xb3, 0x0, 0x0, 0x0, 0x0, 0x2b, - 0x20, 0x0, 0x0, 0x0, 0x5, 0xc1, 0x0, 0x0, - 0x0, 0x1, 0xa9, 0x0, 0x0, 0x0, 0x4, 0xbd, - 0x40, 0x0, 0x0, 0x0, 0x1, 0x70, 0x0, 0x0, - 0x0, 0x0, - - /* U+30F6 "ヶ" */ - 0x0, 0xa, 0x10, 0x0, 0x0, 0x0, 0x2d, 0x10, - 0x1, 0x0, 0x0, 0xba, 0x8a, 0xbb, 0x80, 0x5, - 0x72, 0x1a, 0x50, 0x0, 0x15, 0x0, 0xd, 0x10, - 0x0, 0x0, 0x0, 0x58, 0x0, 0x0, 0x0, 0x0, - 0xc0, 0x0, 0x0, 0x0, 0x7, 0x30, 0x0, 0x0, - 0x0, 0x13, 0x0, 0x0, 0x0, - - /* U+30FC "ー" */ - 0x0, 0x0, 0x0, 0x0, 0x2, 0x46, 0x81, 0x8, - 0xfe, 0xee, 0xdc, 0xcc, 0xbb, 0xbb, 0xa0, 0x4, - 0x42, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - - /* U+4E00 "一" */ - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x5, 0x10, - 0x7, 0x66, 0x66, 0x66, 0x66, 0x66, 0x7c, 0x80, - - /* U+4E03 "七" */ - 0x0, 0x0, 0x0, 0x7, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x0, 0xf, 0x10, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x0, 0xe, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x0, 0xe, 0x0, 0x0, 0x1, 0x0, - 0x0, 0x0, 0x0, 0xe, 0x0, 0x0, 0x2c, 0x80, - 0x0, 0x0, 0x0, 0xe, 0x15, 0x66, 0x40, 0x0, - 0x0, 0x0, 0x15, 0x6f, 0x40, 0x0, 0x0, 0x0, - 0x6, 0x66, 0x40, 0xe, 0x0, 0x0, 0x0, 0x0, - 0x1, 0x0, 0x0, 0xe, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x0, 0xe, 0x0, 0x0, 0x0, 0x30, - 0x0, 0x0, 0x0, 0xe, 0x0, 0x0, 0x0, 0x70, - 0x0, 0x0, 0x0, 0xe, 0x0, 0x0, 0x0, 0xa0, - 0x0, 0x0, 0x0, 0xf, 0x20, 0x0, 0x3, 0xf2, - 0x0, 0x0, 0x0, 0x6, 0xbc, 0xcc, 0xcc, 0xa1, - - /* U+4E07 "万" */ - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x10, 0x46, - 0x66, 0x66, 0x66, 0x66, 0x66, 0xe8, 0x11, 0x0, - 0xc, 0x50, 0x0, 0x0, 0x0, 0x0, 0x0, 0xd, - 0x40, 0x0, 0x0, 0x0, 0x0, 0x0, 0xe, 0x30, - 0x0, 0x2, 0x0, 0x0, 0x0, 0x1f, 0x66, 0x66, - 0x6e, 0x60, 0x0, 0x0, 0x3e, 0x0, 0x0, 0xe, - 0x10, 0x0, 0x0, 0x7a, 0x0, 0x0, 0xf, 0x0, - 0x0, 0x0, 0xc5, 0x0, 0x0, 0xf, 0x0, 0x0, - 0x2, 0xe0, 0x0, 0x0, 0x1e, 0x0, 0x0, 0xa, - 0x60, 0x0, 0x0, 0x3d, 0x0, 0x0, 0x4a, 0x0, - 0x0, 0x0, 0x6b, 0x0, 0x1, 0xa0, 0x0, 0x4, - 0x87, 0xd7, 0x0, 0x17, 0x0, 0x0, 0x0, 0x2d, - 0x90, 0x0, 0x30, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, - - /* U+4E08 "丈" */ - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x0, 0xa, 0x50, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x0, 0xb3, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, 0xb, 0x30, 0x0, 0x60, 0x5, 0x76, - 0x66, 0x66, 0xd8, 0x66, 0x7b, 0x60, 0x0, 0x10, - 0x0, 0xc, 0x30, 0x0, 0x0, 0x0, 0x2, 0x30, - 0x0, 0xc2, 0x0, 0x0, 0x0, 0x0, 0x9, 0x0, - 0xe, 0x0, 0x0, 0x0, 0x0, 0x0, 0x38, 0x1, - 0xe0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xa4, 0x4b, - 0x0, 0x0, 0x0, 0x0, 0x0, 0x1, 0xdb, 0x70, - 0x0, 0x0, 0x0, 0x0, 0x0, 0x5, 0xf7, 0x0, - 0x0, 0x0, 0x0, 0x0, 0x1, 0xd7, 0xdb, 0x30, - 0x0, 0x0, 0x0, 0x4, 0xc3, 0x1, 0x9f, 0xc8, - 0x42, 0x0, 0x39, 0x70, 0x0, 0x0, 0x2a, 0xfc, - 0x20, 0x43, 0x0, 0x0, 0x0, 0x0, 0x0, 0x10, - - /* U+4E09 "三" */ - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x25, 0x0, - 0x0, 0x76, 0x66, 0x66, 0x66, 0x66, 0x89, 0x10, - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x0, 0x0, 0x0, 0x5, 0x20, 0x0, - 0x0, 0x7, 0x66, 0x66, 0x66, 0x69, 0x80, 0x0, - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x1, 0x10, - 0x16, 0x66, 0x66, 0x66, 0x66, 0x66, 0x6c, 0xc1, - 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - - /* U+4E0A "上" */ - 0x0, 0x0, 0x0, 0xa, 0x20, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x0, 0xf, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x0, 0xe, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x0, 0xe, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x0, 0xe, 0x0, 0x0, 0x30, 0x0, - 0x0, 0x0, 0x0, 0xf, 0x66, 0x67, 0xd5, 0x0, - 0x0, 0x0, 0x0, 0xe, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x0, 0xe, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x0, 0xe, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x0, 0xe, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x0, 0xe, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x0, 0xe, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x0, 0xe, 0x0, 0x0, 0x7, 0x80, - 0x7, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x61, - - /* U+4E0B "下" */ - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x20, 0x46, - 0x66, 0x66, 0x66, 0x66, 0x67, 0xe6, 0x0, 0x0, - 0x0, 0xd1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0xd1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xd1, - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xd7, 0x50, - 0x0, 0x0, 0x0, 0x0, 0x0, 0xd1, 0x5d, 0x91, - 0x0, 0x0, 0x0, 0x0, 0xd1, 0x1, 0xdc, 0x0, - 0x0, 0x0, 0x0, 0xd1, 0x0, 0x1b, 0x0, 0x0, - 0x0, 0x0, 0xd1, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0xd1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0xd1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xe1, - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xe1, 0x0, - 0x0, 0x0, 0x0, 0x0, 0x0, 0x40, 0x0, 0x0, - 0x0, - - /* U+4E0D "不" */ - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8, 0x10, - 0x76, 0x66, 0x66, 0x9c, 0x66, 0x66, 0x85, 0x0, - 0x0, 0x0, 0xc, 0x70, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x3, 0xe0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0xcf, 0x60, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x7b, 0xb3, 0x6, 0x0, 0x0, 0x0, 0x0, 0x2d, - 0x1b, 0x30, 0x1a, 0x30, 0x0, 0x0, 0x1c, 0x20, - 0xb3, 0x0, 0x1d, 0x60, 0x0, 0x1b, 0x20, 0xb, - 0x30, 0x0, 0x2f, 0x60, 0x29, 0x10, 0x0, 0xb3, - 0x0, 0x0, 0x6a, 0x15, 0x0, 0x0, 0xb, 0x30, - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xb3, 0x0, - 0x0, 0x0, 0x0, 0x0, 0x0, 0xb, 0x30, 0x0, - 0x0, 0x0, 0x0, 0x0, 0x0, 0xc4, 0x0, 0x0, - 0x0, 0x0, 0x0, 0x0, 0x2, 0x0, 0x0, 0x0, - 0x0, - - /* U+4E13 "专" */ - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x0, 0x3c, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x0, 0x5a, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x36, 0x66, 0xaa, 0x66, 0x6a, 0xb0, 0x0, - 0x0, 0x1, 0x0, 0xa4, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x0, 0xd1, 0x0, 0x0, 0x0, 0x0, - 0x5, 0x66, 0x66, 0xf6, 0x66, 0x66, 0x6c, 0xa0, - 0x2, 0x0, 0x3, 0xb0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x7, 0x70, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, 0xe, 0x86, 0x66, 0x6a, 0x80, 0x0, - 0x0, 0x0, 0x2, 0x0, 0x0, 0x1d, 0x60, 0x0, - 0x0, 0x0, 0x0, 0x0, 0x0, 0xa2, 0x0, 0x0, - 0x0, 0x0, 0x3, 0x85, 0x7, 0x20, 0x0, 0x0, - 0x0, 0x0, 0x0, 0x6, 0xda, 0x10, 0x0, 0x0, - 0x0, 0x0, 0x0, 0x0, 0x1b, 0xa0, 0x0, 0x0, - 0x0, 0x0, 0x0, 0x0, 0x0, 0x40, 0x0, 0x0, - - /* U+4E14 "且" */ - 0x0, 0x0, 0x30, 0x0, 0x0, 0x4, 0x0, 0x0, - 0x0, 0x0, 0xe6, 0x66, 0x66, 0x6f, 0x10, 0x0, - 0x0, 0x0, 0xd1, 0x0, 0x0, 0x1d, 0x0, 0x0, - 0x0, 0x0, 0xd1, 0x0, 0x0, 0x1d, 0x0, 0x0, - 0x0, 0x0, 0xd1, 0x0, 0x0, 0x1d, 0x0, 0x0, - 0x0, 0x0, 0xd6, 0x66, 0x66, 0x6d, 0x0, 0x0, - 0x0, 0x0, 0xd1, 0x0, 0x0, 0x1d, 0x0, 0x0, - 0x0, 0x0, 0xd1, 0x0, 0x0, 0x1d, 0x0, 0x0, - 0x0, 0x0, 0xd1, 0x0, 0x0, 0x1d, 0x0, 0x0, - 0x0, 0x0, 0xd6, 0x66, 0x66, 0x6d, 0x0, 0x0, - 0x0, 0x0, 0xd1, 0x0, 0x0, 0x1d, 0x0, 0x0, - 0x0, 0x0, 0xd1, 0x0, 0x0, 0x1d, 0x0, 0x0, - 0x0, 0x0, 0xd1, 0x0, 0x0, 0x1d, 0x7, 0x40, - 0x28, 0x66, 0x86, 0x66, 0x66, 0x68, 0x69, 0x80, - - /* U+4E16 "世" */ - 0x0, 0x0, 0x0, 0x6, 0x0, 0x8, 0x20, 0x0, - 0x0, 0x6, 0x0, 0xe, 0x0, 0xe, 0x10, 0x0, - 0x0, 0xe, 0x20, 0xd, 0x0, 0xe, 0x0, 0x0, - 0x0, 0xe, 0x0, 0xd, 0x0, 0xe, 0x0, 0x0, - 0x0, 0xe, 0x0, 0xd, 0x0, 0xe, 0x7, 0x70, - 0x18, 0x6e, 0x66, 0x6e, 0x66, 0x6e, 0x66, 0x50, - 0x0, 0xe, 0x0, 0xd, 0x0, 0xe, 0x0, 0x0, - 0x0, 0xe, 0x0, 0xd, 0x0, 0xe, 0x0, 0x0, - 0x0, 0xe, 0x0, 0xd, 0x0, 0xe, 0x0, 0x0, - 0x0, 0xe, 0x0, 0xd, 0x0, 0xe, 0x0, 0x0, - 0x0, 0xe, 0x0, 0xe, 0x66, 0x6e, 0x0, 0x0, - 0x0, 0xe, 0x0, 0x7, 0x0, 0x5, 0x0, 0x0, - 0x0, 0xe, 0x0, 0x0, 0x0, 0x0, 0x3, 0x20, - 0x0, 0x2e, 0x66, 0x66, 0x66, 0x66, 0x6a, 0x90, - 0x0, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - - /* U+4E21 "両" */ - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x9, 0x40, - 0x7, 0x66, 0x66, 0x6d, 0x66, 0x66, 0x66, 0x50, - 0x0, 0x0, 0x0, 0xc, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x20, 0x0, 0xc, 0x0, 0x0, 0x3, 0x0, - 0x0, 0xd6, 0x66, 0x6d, 0x66, 0x66, 0x6e, 0x10, - 0x0, 0xd0, 0x0, 0xc, 0x0, 0x0, 0xd, 0x0, - 0x0, 0xd0, 0x2b, 0xc, 0x0, 0xc4, 0xd, 0x0, - 0x0, 0xd0, 0x1b, 0xc, 0x0, 0xc1, 0xd, 0x0, - 0x0, 0xd0, 0x1b, 0xc, 0x0, 0xc1, 0xd, 0x0, - 0x0, 0xd0, 0x1b, 0xc, 0x0, 0xc1, 0xd, 0x0, - 0x0, 0xd0, 0x3c, 0x69, 0x66, 0xd1, 0xd, 0x0, - 0x0, 0xd0, 0x0, 0x0, 0x0, 0x30, 0xd, 0x0, - 0x0, 0xd0, 0x0, 0x0, 0x0, 0x43, 0x4c, 0x0, - 0x0, 0xc0, 0x0, 0x0, 0x0, 0x6, 0xf8, 0x0, - 0x0, 0x10, 0x0, 0x0, 0x0, 0x0, 0x20, 0x0, - - /* U+4E26 "並" */ - 0x0, 0x4, 0x10, 0x0, 0x0, 0x82, 0x0, 0x0, - 0x0, 0xb, 0x30, 0x0, 0x2e, 0x30, 0x0, 0x0, - 0x0, 0x3f, 0x10, 0x9, 0x30, 0x0, 0x0, 0x0, - 0x0, 0xc2, 0x2, 0x50, 0x39, 0x0, 0x7, 0x66, - 0x6e, 0x66, 0xc7, 0x66, 0x61, 0x0, 0x10, 0x0, - 0xd0, 0xb, 0x30, 0x3, 0x0, 0x6, 0x20, 0xd, - 0x0, 0xb3, 0x2, 0xf3, 0x0, 0x1a, 0x0, 0xd0, - 0xb, 0x30, 0xa7, 0x0, 0x0, 0xc3, 0xd, 0x0, - 0xb3, 0x3a, 0x0, 0x0, 0x8, 0x90, 0xd0, 0xb, - 0x3a, 0x10, 0x0, 0x0, 0x68, 0xd, 0x0, 0xb8, - 0x20, 0x0, 0x0, 0x0, 0x0, 0xd0, 0xb, 0x50, - 0x0, 0x0, 0x0, 0x0, 0xd, 0x0, 0xb3, 0x0, - 0x72, 0x5, 0x76, 0x66, 0x96, 0x68, 0x66, 0x6a, - 0x80, - - /* U+4E2D "中" */ - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0xc4, 0x0, 0x0, 0x0, 0x0, 0x0, 0xd, - 0x10, 0x0, 0x0, 0x0, 0x0, 0x0, 0xd1, 0x0, - 0x0, 0x0, 0xa6, 0x66, 0x6e, 0x66, 0x66, 0x6e, - 0x2d, 0x10, 0x0, 0xd1, 0x0, 0x0, 0xe0, 0xd1, - 0x0, 0xd, 0x10, 0x0, 0xe, 0xd, 0x10, 0x0, - 0xd1, 0x0, 0x0, 0xe0, 0xd1, 0x0, 0xd, 0x10, - 0x0, 0xe, 0xd, 0x66, 0x66, 0xe6, 0x66, 0x66, - 0xe0, 0x60, 0x0, 0xd, 0x10, 0x0, 0x5, 0x0, - 0x0, 0x0, 0xd1, 0x0, 0x0, 0x0, 0x0, 0x0, - 0xd, 0x10, 0x0, 0x0, 0x0, 0x0, 0x0, 0xd1, - 0x0, 0x0, 0x0, 0x0, 0x0, 0xe, 0x20, 0x0, - 0x0, 0x0, 0x0, 0x0, 0x40, 0x0, 0x0, 0x0, - - /* U+4E3B "主" */ - 0x0, 0x0, 0x0, 0x60, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x2, 0xd3, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x7, 0xd0, 0x0, 0x0, 0x0, 0x26, - 0x66, 0x66, 0x6a, 0x66, 0x6c, 0xb0, 0x0, 0x20, - 0x0, 0xb, 0x30, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0xb3, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0xb, 0x30, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0xb3, 0x0, 0x33, 0x0, 0x0, 0x28, 0x66, 0x6d, - 0x86, 0x69, 0x80, 0x0, 0x0, 0x0, 0x0, 0xb3, - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xb, 0x30, - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xb3, 0x0, - 0x0, 0x0, 0x0, 0x0, 0x0, 0xb, 0x30, 0x0, - 0x7, 0x1, 0x86, 0x66, 0x66, 0x86, 0x66, 0x67, - 0xa5, - - /* U+4E45 "久" */ - 0x0, 0x0, 0x0, 0xc3, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x3, 0xe0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x8, 0x70, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, 0xe, 0x66, 0x6d, 0x60, 0x0, 0x0, - 0x0, 0x0, 0x67, 0x0, 0x2e, 0x0, 0x0, 0x0, - 0x0, 0x0, 0xb0, 0x0, 0x88, 0x0, 0x0, 0x0, - 0x0, 0x8, 0x20, 0x0, 0xe6, 0x0, 0x0, 0x0, - 0x0, 0x43, 0x0, 0x6, 0x97, 0x0, 0x0, 0x0, - 0x0, 0x20, 0x0, 0x1d, 0x13, 0x50, 0x0, 0x0, - 0x0, 0x0, 0x0, 0xa5, 0x0, 0xb0, 0x0, 0x0, - 0x0, 0x0, 0x7, 0x80, 0x0, 0x59, 0x0, 0x0, - 0x0, 0x0, 0x69, 0x0, 0x0, 0xb, 0x80, 0x0, - 0x0, 0x7, 0x60, 0x0, 0x0, 0x1, 0xeb, 0x30, - 0x2, 0x62, 0x0, 0x0, 0x0, 0x0, 0x2c, 0x60, - 0x3, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - - /* U+4E4B "之" */ - 0x0, 0x0, 0x0, 0x81, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x0, 0x3e, 0x20, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x0, 0xa, 0x30, 0x0, 0x0, 0x0, - 0x2, 0x76, 0x66, 0x66, 0x66, 0x8d, 0x10, 0x0, - 0x0, 0x10, 0x0, 0x0, 0x1, 0xd8, 0x0, 0x0, - 0x0, 0x0, 0x0, 0x0, 0xc, 0x60, 0x0, 0x0, - 0x0, 0x0, 0x0, 0x0, 0xb6, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x0, 0xb, 0x50, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x0, 0xa4, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, 0xa, 0x30, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x2, 0xb3, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x7b, 0x91, 0x0, 0x0, 0x0, 0x0, 0x0, - 0xe, 0x90, 0x1b, 0x95, 0x32, 0x22, 0x34, 0x51, - 0x3, 0x0, 0x0, 0x5a, 0xce, 0xef, 0xff, 0x30, - - /* U+4E4E "乎" */ - 0x0, 0x0, 0x0, 0x0, 0x2, 0x6c, 0x20, 0x0, - 0x0, 0x23, 0x68, 0xab, 0xa8, 0x62, 0x0, 0x4, - 0x54, 0x32, 0x4b, 0x0, 0x2, 0x0, 0x0, 0x3, - 0x30, 0x3, 0xb0, 0x3, 0xd1, 0x0, 0x0, 0xb, - 0x40, 0x3b, 0x0, 0xa3, 0x0, 0x0, 0x0, 0x4e, - 0x3, 0xb0, 0x37, 0x0, 0x0, 0x0, 0x0, 0x60, - 0x3b, 0x5, 0x0, 0x14, 0x6, 0x76, 0x66, 0x68, - 0xd6, 0x66, 0x69, 0xa1, 0x0, 0x0, 0x0, 0x3b, - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x3, 0xb0, - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x3b, 0x0, - 0x0, 0x0, 0x0, 0x0, 0x0, 0x3, 0xb0, 0x0, - 0x0, 0x0, 0x0, 0x0, 0x41, 0x6b, 0x0, 0x0, - 0x0, 0x0, 0x0, 0x2, 0xaf, 0x80, 0x0, 0x0, - 0x0, 0x0, 0x0, 0x0, 0x50, 0x0, 0x0, 0x0, - 0x0, - - /* U+4E4F "乏" */ - 0x0, 0x0, 0x0, 0x0, 0x0, 0x36, 0x0, 0x0, - 0x0, 0x0, 0x24, 0x7a, 0xed, 0xc3, 0x0, 0x5, - 0x66, 0x78, 0x42, 0x10, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x3c, 0x20, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x8a, 0x0, 0x0, 0x0, 0x0, 0x36, 0x66, - 0x66, 0x86, 0x6a, 0x70, 0x0, 0x0, 0x10, 0x0, - 0x0, 0x8, 0xb3, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x1b, 0x70, 0x0, 0x0, 0x0, 0x0, 0x0, 0x5a, - 0x20, 0x0, 0x0, 0x0, 0x0, 0x1, 0x96, 0x0, - 0x0, 0x0, 0x0, 0x0, 0x6, 0x81, 0x0, 0x0, - 0x0, 0x0, 0x0, 0x4a, 0x92, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x5d, 0x0, 0x7a, 0x63, 0x22, 0x23, - 0x45, 0x10, 0x20, 0x0, 0x16, 0xac, 0xde, 0xff, - 0x40, - - /* U+4E57 "乗" */ - 0x0, 0x0, 0x0, 0x0, 0x0, 0x36, 0xa7, 0x0, - 0x0, 0x45, 0x55, 0x67, 0xd9, 0x87, 0x66, 0x0, - 0x0, 0x0, 0x0, 0x0, 0xd0, 0x0, 0x0, 0x0, - 0x0, 0x46, 0x66, 0x66, 0xe6, 0x66, 0xab, 0x0, - 0x0, 0x11, 0x6, 0x0, 0xd0, 0x16, 0x0, 0x0, - 0x0, 0x0, 0x1c, 0x0, 0xd0, 0x3b, 0x2, 0x30, - 0x6, 0x76, 0x6d, 0x66, 0xe6, 0x7c, 0x68, 0x80, - 0x0, 0x0, 0x1c, 0x0, 0xd0, 0x3b, 0x0, 0x0, - 0x0, 0x46, 0x6d, 0x66, 0xe6, 0x7c, 0x9c, 0x10, - 0x0, 0x11, 0x0, 0x7b, 0xd6, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x4, 0xc1, 0xd1, 0x90, 0x0, 0x0, - 0x0, 0x0, 0x5b, 0x10, 0xd0, 0x4c, 0x10, 0x0, - 0x0, 0x8, 0x70, 0x0, 0xd0, 0x5, 0xe9, 0x30, - 0x5, 0x61, 0x0, 0x0, 0xe0, 0x0, 0x2c, 0xc3, - 0x0, 0x0, 0x0, 0x0, 0x20, 0x0, 0x0, 0x0, - - /* U+4E5D "九" */ - 0x0, 0x0, 0xa, 0x10, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, 0xe0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0xd, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x1, 0xc0, 0x0, 0x40, 0x0, 0x0, 0x5, 0x65, - 0x6d, 0x66, 0x6e, 0x20, 0x0, 0x0, 0x0, 0x2, - 0xa0, 0x0, 0xd0, 0x0, 0x0, 0x0, 0x0, 0x48, - 0x0, 0xd, 0x0, 0x0, 0x0, 0x0, 0x8, 0x50, - 0x0, 0xd0, 0x0, 0x0, 0x0, 0x0, 0xc1, 0x0, - 0xd, 0x0, 0x0, 0x0, 0x0, 0x2b, 0x0, 0x0, - 0xd0, 0x0, 0x0, 0x0, 0x9, 0x30, 0x0, 0xd, - 0x0, 0x3, 0x0, 0x4, 0x90, 0x0, 0x0, 0xd0, - 0x0, 0x70, 0x1, 0x90, 0x0, 0x0, 0xe, 0x0, - 0xb, 0x2, 0x70, 0x0, 0x0, 0x0, 0xbd, 0xcc, - 0xd2, 0x20, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, - - /* U+4E5F "也" */ - 0x0, 0x0, 0x0, 0x7, 0x20, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x0, 0xd2, 0x0, 0x0, 0x0, 0x0, - 0x7, 0x30, 0xc, 0x10, 0x0, 0x20, 0x0, 0x0, - 0xa3, 0x0, 0xc1, 0x1, 0x6f, 0x20, 0x0, 0xa, - 0x30, 0xc, 0x67, 0x61, 0xd0, 0x0, 0x0, 0xa4, - 0x57, 0xe2, 0x0, 0xd, 0x0, 0x0, 0x5c, 0x81, - 0xc, 0x10, 0x2, 0xb0, 0x0, 0x61, 0xa3, 0x0, - 0xc1, 0x0, 0x3a, 0x0, 0x0, 0xa, 0x30, 0xc, - 0x12, 0x18, 0x70, 0x0, 0x0, 0xa3, 0x0, 0xc1, - 0x4d, 0xe1, 0x0, 0x0, 0xa, 0x30, 0xd, 0x10, - 0x10, 0x5, 0x0, 0x0, 0xa3, 0x0, 0x50, 0x0, - 0x0, 0x70, 0x0, 0xa, 0x40, 0x0, 0x0, 0x0, - 0xa, 0x30, 0x0, 0x6e, 0xcc, 0xcc, 0xcc, 0xcc, - 0xe6, - - /* U+4E86 "了" */ - 0x0, 0x0, 0x0, 0x0, 0x0, 0x32, 0x3, 0x76, - 0x66, 0x66, 0x66, 0x7f, 0xb0, 0x0, 0x0, 0x0, - 0x0, 0x2b, 0x40, 0x0, 0x0, 0x0, 0x0, 0x47, - 0x0, 0x0, 0x0, 0x0, 0x3, 0x94, 0x0, 0x0, - 0x0, 0x0, 0x0, 0x3c, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x3, 0xb0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x3b, 0x0, 0x0, 0x0, 0x0, 0x0, 0x3, 0xb0, - 0x0, 0x0, 0x0, 0x0, 0x0, 0x3b, 0x0, 0x0, - 0x0, 0x0, 0x0, 0x3, 0xb0, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x3b, 0x0, 0x0, 0x0, 0x0, 0x2, - 0x5, 0xb0, 0x0, 0x0, 0x0, 0x0, 0x4c, 0xf8, - 0x0, 0x0, 0x0, 0x0, 0x0, 0x6, 0x0, 0x0, - 0x0, 0x0, - - /* U+4E88 "予" */ - 0x0, 0x0, 0x0, 0x0, 0x0, 0x12, 0x0, 0x0, - 0x6, 0x76, 0x66, 0x66, 0x7e, 0xc0, 0x0, 0x0, - 0x0, 0x0, 0x0, 0x3b, 0x50, 0x0, 0x0, 0x0, - 0x1, 0x76, 0x56, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x7e, 0x30, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0xb5, 0x0, 0x5, 0x20, 0x47, 0x66, 0x66, - 0x6e, 0x66, 0x66, 0xfa, 0x0, 0x0, 0x0, 0x1, - 0xd0, 0x0, 0x85, 0x0, 0x0, 0x0, 0x0, 0x1d, - 0x0, 0x13, 0x0, 0x0, 0x0, 0x0, 0x1, 0xd0, - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x1d, 0x0, - 0x0, 0x0, 0x0, 0x0, 0x0, 0x1, 0xd0, 0x0, - 0x0, 0x0, 0x0, 0x0, 0x21, 0x3d, 0x0, 0x0, - 0x0, 0x0, 0x0, 0x2, 0x8f, 0xa0, 0x0, 0x0, - 0x0, 0x0, 0x0, 0x0, 0x30, 0x0, 0x0, 0x0, - 0x0, - - /* U+4E89 "争" */ - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, 0xa, 0x80, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x4f, 0x76, 0x6b, 0x80, 0x0, 0x0, - 0x0, 0x1, 0xc2, 0x0, 0x3c, 0x20, 0x0, 0x0, - 0x0, 0xa, 0x10, 0x0, 0x90, 0x0, 0x20, 0x0, - 0x1, 0x75, 0x76, 0x6b, 0x76, 0x67, 0xd0, 0x0, - 0x4, 0x0, 0x0, 0xb, 0x20, 0x3, 0xa0, 0x0, - 0x0, 0x0, 0x0, 0xb, 0x20, 0x3, 0xa5, 0x60, - 0x7, 0x66, 0x66, 0x6d, 0x76, 0x67, 0xc6, 0x50, - 0x0, 0x0, 0x0, 0xb, 0x20, 0x3, 0xa0, 0x0, - 0x0, 0x26, 0x66, 0x6d, 0x76, 0x67, 0xa0, 0x0, - 0x0, 0x1, 0x0, 0xb, 0x20, 0x1, 0x40, 0x0, - 0x0, 0x0, 0x0, 0xb, 0x20, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x10, 0xd, 0x20, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x17, 0xef, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x0, 0x32, 0x0, 0x0, 0x0, 0x0, - - /* U+4E8B "事" */ - 0x0, 0x0, 0x0, 0x1, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x0, 0xd3, 0x0, 0x0, 0x10, 0x5, - 0x66, 0x66, 0x6e, 0x66, 0x66, 0xae, 0x20, 0x10, - 0x0, 0x0, 0xe0, 0x0, 0x0, 0x0, 0x0, 0x8, - 0x66, 0x6e, 0x66, 0x6c, 0x40, 0x0, 0x0, 0xa2, - 0x0, 0xe0, 0x0, 0xc2, 0x0, 0x0, 0xa, 0x76, - 0x6e, 0x66, 0x6d, 0x20, 0x0, 0x0, 0x40, 0x0, - 0xe0, 0x0, 0x50, 0x0, 0x0, 0x27, 0x66, 0x6e, - 0x66, 0x6d, 0x50, 0x0, 0x0, 0x0, 0x0, 0xe0, - 0x0, 0xc2, 0x81, 0x27, 0x66, 0x66, 0x6e, 0x66, - 0x6d, 0x77, 0x40, 0x0, 0x0, 0x0, 0xe0, 0x0, - 0xc2, 0x0, 0x0, 0x37, 0x66, 0x6e, 0x66, 0x6d, - 0x20, 0x0, 0x0, 0x0, 0x0, 0xe0, 0x0, 0x10, - 0x0, 0x0, 0x0, 0x28, 0xed, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x0, 0x4, 0x10, 0x0, 0x0, 0x0, - - /* U+4E8C "二" */ - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x60, 0x0, - 0x0, 0x27, 0x66, 0x66, 0x66, 0x67, 0xa4, 0x0, - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x2d, 0x40, - 0x7, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x50, - - /* U+4E94 "五" */ - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x11, 0x0, - 0x0, 0x76, 0x66, 0x68, 0x66, 0x66, 0xab, 0x0, - 0x0, 0x0, 0x0, 0x1d, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x0, 0x3a, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x0, 0x68, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x0, 0x85, 0x0, 0x2, 0x0, 0x0, - 0x0, 0x37, 0x66, 0xc8, 0x66, 0x6e, 0x40, 0x0, - 0x0, 0x0, 0x0, 0xd0, 0x0, 0xe, 0x0, 0x0, - 0x0, 0x0, 0x0, 0xd0, 0x0, 0xe, 0x0, 0x0, - 0x0, 0x0, 0x1, 0xc0, 0x0, 0xe, 0x0, 0x0, - 0x0, 0x0, 0x4, 0x90, 0x0, 0xd, 0x0, 0x0, - 0x0, 0x0, 0x6, 0x70, 0x0, 0x1d, 0x0, 0x0, - 0x0, 0x0, 0x9, 0x40, 0x0, 0x1c, 0x6, 0x40, - 0x7, 0x66, 0x68, 0x66, 0x66, 0x68, 0x68, 0x80, - - /* U+4E9B "些" */ - 0x0, 0x0, 0x8, 0x0, 0x8, 0x10, 0x0, 0x0, - 0x0, 0x0, 0xe, 0x0, 0xd, 0x0, 0x0, 0x0, - 0x0, 0x50, 0xd, 0x0, 0xd, 0x0, 0x2b, 0x10, - 0x0, 0xd2, 0xe, 0x6c, 0x2d, 0x2, 0xc5, 0x0, - 0x0, 0xd0, 0xd, 0x0, 0xd, 0x47, 0x0, 0x0, - 0x0, 0xd0, 0xd, 0x0, 0xd, 0x20, 0x0, 0x40, - 0x0, 0xd0, 0xd, 0x0, 0xd, 0x0, 0x0, 0x70, - 0x0, 0xd0, 0xd, 0x55, 0x2d, 0x20, 0x5, 0xc0, - 0xa, 0xe9, 0x74, 0x0, 0x4, 0xaa, 0xaa, 0x50, - 0x3, 0x0, 0x0, 0x0, 0x0, 0x3, 0x10, 0x0, - 0x0, 0x7, 0x66, 0x66, 0x66, 0x6a, 0x80, 0x0, - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x1b, 0x20, - 0x6, 0x66, 0x66, 0x66, 0x66, 0x66, 0x78, 0x60, - - /* U+4EA1 "亡" */ - 0x0, 0x0, 0x0, 0x17, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x0, 0x8, 0xc0, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x0, 0x1, 0xf1, 0x0, 0x0, 0x10, - 0x5, 0x66, 0x66, 0x66, 0x86, 0x66, 0x6b, 0xe2, - 0x1, 0x11, 0xd0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x1, 0xd0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x1, 0xd0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x1, 0xd0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x1, 0xd0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x1, 0xd0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x1, 0xd0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x1, 0xd0, 0x0, 0x0, 0x0, 0x3, 0x0, - 0x0, 0x4, 0xe6, 0x66, 0x66, 0x66, 0xad, 0x20, - 0x0, 0x0, 0x30, 0x0, 0x0, 0x0, 0x0, 0x0, - - /* U+4EA4 "交" */ - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x0, 0x2a, 0x10, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x0, 0x7, 0xb0, 0x0, 0x2, 0x0, - 0x5, 0x66, 0x66, 0x66, 0x96, 0x66, 0x6f, 0x80, - 0x1, 0x0, 0x5, 0x0, 0x2, 0x10, 0x0, 0x0, - 0x0, 0x0, 0x6d, 0x20, 0x0, 0x78, 0x10, 0x0, - 0x0, 0x5, 0xb1, 0x0, 0x0, 0x15, 0xe4, 0x0, - 0x0, 0x67, 0x5, 0x0, 0x5, 0xd1, 0x7b, 0x0, - 0x4, 0x20, 0x5, 0x20, 0xa, 0x60, 0x1, 0x0, - 0x0, 0x0, 0x0, 0x90, 0x1d, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x0, 0x65, 0xa5, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x0, 0xc, 0x90, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x0, 0x7a, 0xc5, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x3a, 0x50, 0x1a, 0xc6, 0x20, 0x0, - 0x0, 0x47, 0x60, 0x0, 0x0, 0x3a, 0xff, 0xb1, - 0x4, 0x10, 0x0, 0x0, 0x0, 0x0, 0x2, 0x10, - - /* U+4EA6 "亦" */ - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x19, 0x30, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x2f, 0x20, 0x0, 0x10, 0x4, 0x66, - 0x66, 0x66, 0xd6, 0x66, 0x6d, 0xb0, 0x11, 0x0, - 0xe, 0x0, 0x1c, 0x0, 0x0, 0x0, 0x0, 0x0, - 0xe0, 0x1, 0xc0, 0x0, 0x0, 0x0, 0xa6, 0xe, - 0x0, 0x1c, 0x21, 0x0, 0x0, 0xe, 0x10, 0xe0, - 0x1, 0xc0, 0x91, 0x0, 0x4, 0x80, 0x2c, 0x0, - 0x1c, 0x2, 0xc1, 0x0, 0xa1, 0x4, 0x90, 0x1, - 0xc0, 0x9, 0xa0, 0x26, 0x0, 0xa5, 0x0, 0x1c, - 0x0, 0x2f, 0x4, 0x0, 0x1c, 0x0, 0x1, 0xc0, - 0x0, 0x50, 0x0, 0xa, 0x30, 0x0, 0x1c, 0x0, - 0x0, 0x0, 0x8, 0x30, 0x3, 0x79, 0xc0, 0x0, - 0x0, 0x17, 0x10, 0x0, 0x2, 0xd5, 0x0, 0x0, - 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - - /* U+4EAC "京" */ - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x8, 0x60, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, 0xe, 0x10, 0x0, 0x50, 0x5, 0x76, - 0x66, 0x66, 0x86, 0x66, 0x6b, 0x80, 0x0, 0x0, - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xa6, - 0x66, 0x66, 0x6b, 0x40, 0x0, 0x0, 0xe, 0x0, - 0x0, 0x0, 0xd2, 0x0, 0x0, 0x0, 0xe0, 0x0, - 0x0, 0xd, 0x10, 0x0, 0x0, 0xe, 0x0, 0x0, - 0x0, 0xd1, 0x0, 0x0, 0x0, 0xf6, 0x66, 0xc6, - 0x6d, 0x10, 0x0, 0x0, 0x2, 0x20, 0x1d, 0x1, - 0x0, 0x0, 0x0, 0x0, 0x3e, 0x31, 0xd0, 0x38, - 0x0, 0x0, 0x0, 0x2c, 0x30, 0x1d, 0x0, 0x5c, - 0x10, 0x0, 0x3a, 0x10, 0x2, 0xd0, 0x0, 0x9b, - 0x0, 0x45, 0x0, 0x29, 0xeb, 0x0, 0x1, 0x80, - 0x0, 0x0, 0x0, 0x6, 0x10, 0x0, 0x0, 0x0, - - /* U+4EBA "人" */ - 0x0, 0x0, 0x0, 0x1b, 0x30, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x0, 0x1f, 0x50, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x0, 0x1f, 0x50, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x0, 0x3e, 0x70, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x0, 0x5c, 0x80, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x0, 0x6a, 0x90, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x0, 0xa7, 0x64, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x0, 0xe3, 0x1a, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x3, 0xd0, 0xb, 0x30, 0x0, 0x0, - 0x0, 0x0, 0xa, 0x60, 0x4, 0xc0, 0x0, 0x0, - 0x0, 0x0, 0x3c, 0x0, 0x0, 0xb8, 0x0, 0x0, - 0x0, 0x1, 0xc2, 0x0, 0x0, 0x1e, 0x70, 0x0, - 0x0, 0x2b, 0x20, 0x0, 0x0, 0x3, 0xfc, 0x50, - 0x4, 0x70, 0x0, 0x0, 0x0, 0x0, 0x3d, 0x61, - 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - - /* U+4EC0 "什" */ - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0xc, 0x40, 0x0, 0xb3, 0x0, 0x0, 0x0, - 0x2, 0xf1, 0x0, 0xc, 0x10, 0x0, 0x0, 0x0, - 0x79, 0x0, 0x0, 0xc1, 0x0, 0x0, 0x0, 0xd, - 0x20, 0x0, 0xc, 0x10, 0x0, 0x0, 0x4, 0xf3, - 0x0, 0x0, 0xc1, 0x0, 0x20, 0x0, 0xac, 0x47, - 0x66, 0x6d, 0x66, 0x6d, 0x60, 0x37, 0xa3, 0x0, - 0x0, 0xc1, 0x0, 0x0, 0x8, 0xa, 0x30, 0x0, - 0xc, 0x10, 0x0, 0x4, 0x10, 0xa3, 0x0, 0x0, - 0xc1, 0x0, 0x0, 0x0, 0xa, 0x30, 0x0, 0xc, - 0x10, 0x0, 0x0, 0x0, 0xa3, 0x0, 0x0, 0xc1, - 0x0, 0x0, 0x0, 0xa, 0x30, 0x0, 0xc, 0x10, - 0x0, 0x0, 0x0, 0xa3, 0x0, 0x0, 0xc1, 0x0, - 0x0, 0x0, 0xa, 0x40, 0x0, 0xd, 0x10, 0x0, - 0x0, 0x0, 0x40, 0x0, 0x0, 0x50, 0x0, 0x0, - - /* U+4ECA "今" */ - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x0, 0xd, 0x40, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x0, 0x6c, 0x60, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x1, 0xe2, 0x54, 0x0, 0x0, 0x0, - 0x0, 0x0, 0xb, 0x60, 0x9, 0x40, 0x0, 0x0, - 0x0, 0x0, 0x79, 0x10, 0x0, 0xc6, 0x0, 0x0, - 0x0, 0x6, 0x90, 0x3a, 0x10, 0xb, 0xc4, 0x0, - 0x0, 0x76, 0x0, 0x6, 0xc0, 0x0, 0x7f, 0xc1, - 0x16, 0x20, 0x0, 0x0, 0x60, 0x0, 0x2, 0x10, - 0x0, 0x5, 0x66, 0x66, 0x66, 0x6a, 0x50, 0x0, - 0x0, 0x1, 0x0, 0x0, 0x0, 0x2e, 0x10, 0x0, - 0x0, 0x0, 0x0, 0x0, 0x0, 0xd4, 0x0, 0x0, - 0x0, 0x0, 0x0, 0x0, 0x8, 0x80, 0x0, 0x0, - 0x0, 0x0, 0x0, 0x0, 0x3c, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x0, 0x0, 0xd2, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x0, 0x2, 0x40, 0x0, 0x0, 0x0, - - /* U+4ECB "介" */ - 0x0, 0x0, 0x0, 0x1, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x2, 0xe3, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x8b, 0x50, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x1e, 0x16, 0x20, 0x0, 0x0, 0x0, 0x0, - 0xa, 0x60, 0xa, 0x10, 0x0, 0x0, 0x0, 0x6, - 0xa0, 0x0, 0x1c, 0x30, 0x0, 0x0, 0x5, 0x82, - 0x0, 0x3, 0x2d, 0xa3, 0x0, 0x6, 0x50, 0xb6, - 0x0, 0xb6, 0x1a, 0xf6, 0x15, 0x10, 0xb, 0x20, - 0xb, 0x30, 0x1, 0x0, 0x0, 0x0, 0xb2, 0x0, - 0xa3, 0x0, 0x0, 0x0, 0x0, 0xc, 0x0, 0xa, - 0x30, 0x0, 0x0, 0x0, 0x1, 0xd0, 0x0, 0xa3, - 0x0, 0x0, 0x0, 0x0, 0x76, 0x0, 0xa, 0x30, - 0x0, 0x0, 0x0, 0x3a, 0x0, 0x0, 0xa3, 0x0, - 0x0, 0x0, 0x57, 0x0, 0x0, 0xa, 0x40, 0x0, - 0x0, 0x22, 0x0, 0x0, 0x0, 0x51, 0x0, 0x0, - - /* U+4ECD "仍" */ - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, 0xc2, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x4, 0xc2, 0x76, 0x66, 0x66, 0xc2, 0x0, - 0x0, 0x9, 0x50, 0x13, 0xa0, 0x1, 0xd0, 0x0, - 0x0, 0xc, 0x0, 0x4, 0x90, 0x5, 0x90, 0x0, - 0x0, 0x7e, 0x30, 0x4, 0x90, 0x8, 0x50, 0x0, - 0x0, 0xac, 0x10, 0x5, 0x80, 0xc, 0x21, 0x20, - 0x7, 0x2c, 0x10, 0x6, 0x70, 0x1c, 0x69, 0xb0, - 0x25, 0xc, 0x10, 0x8, 0x50, 0x0, 0x7, 0x70, - 0x0, 0xc, 0x10, 0xa, 0x20, 0x0, 0x8, 0x50, - 0x0, 0xc, 0x10, 0xd, 0x0, 0x0, 0xa, 0x30, - 0x0, 0xc, 0x10, 0x48, 0x0, 0x0, 0xd, 0x10, - 0x0, 0xc, 0x10, 0xa1, 0x0, 0x0, 0xe, 0x0, - 0x0, 0xc, 0x14, 0x60, 0x0, 0x43, 0x8b, 0x0, - 0x0, 0xd, 0x46, 0x0, 0x0, 0x1a, 0xe3, 0x0, - 0x0, 0x6, 0x30, 0x0, 0x0, 0x0, 0x0, 0x0, - - /* U+4ED5 "仕" */ - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0xb, 0x50, 0x0, 0x93, 0x0, 0x0, 0x0, - 0x1, 0xf2, 0x0, 0xe, 0x20, 0x0, 0x0, 0x0, - 0x6b, 0x0, 0x0, 0xd1, 0x0, 0x0, 0x0, 0xc, - 0x30, 0x0, 0xd, 0x10, 0x0, 0x0, 0x2, 0xf3, - 0x0, 0x0, 0xd1, 0x0, 0x30, 0x0, 0xae, 0x47, - 0x66, 0x6e, 0x66, 0x6b, 0x60, 0x28, 0xb3, 0x0, - 0x0, 0xd1, 0x0, 0x0, 0x8, 0xb, 0x30, 0x0, - 0xd, 0x10, 0x0, 0x3, 0x10, 0xb3, 0x0, 0x0, - 0xd1, 0x0, 0x0, 0x0, 0xb, 0x30, 0x0, 0xd, - 0x10, 0x0, 0x0, 0x0, 0xb3, 0x0, 0x0, 0xd1, - 0x0, 0x0, 0x0, 0xb, 0x30, 0x0, 0xd, 0x10, - 0x0, 0x0, 0x0, 0xb3, 0x0, 0x0, 0xd1, 0x4, - 0x80, 0x0, 0xb, 0x43, 0x76, 0x66, 0x66, 0x66, - 0x10, 0x0, 0x51, 0x0, 0x0, 0x0, 0x0, 0x0, - - /* U+4ED6 "他" */ - 0x0, 0x0, 0x10, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x1, 0xe2, 0x0, 0xc, 0x30, 0x0, 0x0, - 0x0, 0x5, 0xa0, 0x0, 0xd, 0x0, 0x0, 0x0, - 0x0, 0xb, 0x30, 0x0, 0xd, 0x0, 0x0, 0x0, - 0x0, 0x1c, 0x0, 0xd3, 0xd, 0x0, 0x26, 0x0, - 0x0, 0x7d, 0x20, 0xd0, 0xd, 0x66, 0x7b, 0x0, - 0x0, 0xbd, 0x24, 0xe6, 0x5d, 0x0, 0x3a, 0x0, - 0x6, 0x4c, 0x22, 0xd0, 0xd, 0x0, 0x3a, 0x0, - 0x7, 0xc, 0x10, 0xd0, 0xd, 0x0, 0x49, 0x0, - 0x20, 0xc, 0x10, 0xd0, 0xd, 0x2, 0x88, 0x0, - 0x0, 0xc, 0x10, 0xd0, 0xd, 0x5, 0xe3, 0x0, - 0x0, 0xc, 0x10, 0xd0, 0xd, 0x0, 0x0, 0x30, - 0x0, 0xc, 0x10, 0xd0, 0x4, 0x0, 0x0, 0x60, - 0x0, 0xc, 0x10, 0xc0, 0x0, 0x0, 0x0, 0xc0, - 0x0, 0xd, 0x10, 0x7c, 0xbb, 0xbb, 0xbc, 0xb1, - 0x0, 0x4, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - - /* U+4ED8 "付" */ - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x9, 0x70, 0x0, 0x0, 0xa3, 0x0, 0x0, - 0x0, 0xe2, 0x0, 0x0, 0xd, 0x20, 0x0, 0x0, - 0x4b, 0x0, 0x0, 0x0, 0xd2, 0x0, 0x0, 0xa, - 0x30, 0x0, 0x0, 0xd, 0x23, 0x0, 0x1, 0xf3, - 0x27, 0x66, 0x66, 0xe7, 0x96, 0x0, 0x9d, 0x30, - 0x0, 0x0, 0xd, 0x20, 0x0, 0x28, 0xa3, 0x1, - 0x20, 0x0, 0xd2, 0x0, 0x8, 0xa, 0x30, 0x9, - 0x30, 0xd, 0x20, 0x3, 0x10, 0xa3, 0x0, 0x2f, - 0x10, 0xd2, 0x0, 0x0, 0xa, 0x30, 0x0, 0xb1, - 0xd, 0x20, 0x0, 0x0, 0xa3, 0x0, 0x0, 0x0, - 0xd2, 0x0, 0x0, 0xa, 0x30, 0x0, 0x0, 0xd, - 0x20, 0x0, 0x0, 0xa3, 0x0, 0x0, 0x0, 0xd2, - 0x0, 0x0, 0xb, 0x40, 0x0, 0x16, 0xdf, 0x0, - 0x0, 0x0, 0x50, 0x0, 0x0, 0x3, 0x30, 0x0, - - /* U+4EE3 "代" */ - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x2c, 0x10, 0x15, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x7b, 0x0, 0x1e, 0x13, 0x92, 0x0, - 0x0, 0x0, 0xd2, 0x0, 0xd, 0x0, 0x4f, 0x20, - 0x0, 0x3, 0xa0, 0x0, 0xe, 0x0, 0x6, 0x10, - 0x0, 0xb, 0xa0, 0x0, 0xd, 0x0, 0x7, 0x50, - 0x0, 0x3c, 0xc1, 0x65, 0x6d, 0x76, 0x54, 0x30, - 0x0, 0xa3, 0xb0, 0x0, 0xa, 0x30, 0x0, 0x0, - 0x6, 0x32, 0xb0, 0x0, 0x7, 0x60, 0x0, 0x0, - 0x4, 0x2, 0xb0, 0x0, 0x4, 0x90, 0x0, 0x0, - 0x0, 0x2, 0xb0, 0x0, 0x0, 0xe0, 0x0, 0x0, - 0x0, 0x2, 0xb0, 0x0, 0x0, 0xa6, 0x0, 0x11, - 0x0, 0x2, 0xb0, 0x0, 0x0, 0x2e, 0x30, 0x60, - 0x0, 0x2, 0xb0, 0x0, 0x0, 0x6, 0xe3, 0xb0, - 0x0, 0x2, 0xc0, 0x0, 0x0, 0x0, 0x5e, 0xf1, - 0x0, 0x1, 0x40, 0x0, 0x0, 0x0, 0x1, 0x72, - - /* U+4EE4 "令" */ - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x0, 0xb, 0x80, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x0, 0x2f, 0x80, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x0, 0xb6, 0x27, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x6, 0xb0, 0x8, 0x40, 0x0, 0x0, - 0x0, 0x0, 0x3d, 0x32, 0x0, 0xc4, 0x0, 0x0, - 0x0, 0x2, 0xc2, 0xa, 0x70, 0x1d, 0x70, 0x0, - 0x0, 0x39, 0x10, 0x1, 0xf2, 0x1, 0xce, 0x81, - 0x5, 0x40, 0x0, 0x0, 0x40, 0x7, 0x16, 0x30, - 0x0, 0x4, 0x76, 0x66, 0x66, 0x9f, 0x70, 0x0, - 0x0, 0x0, 0x0, 0x0, 0x0, 0xc4, 0x0, 0x0, - 0x0, 0x0, 0x11, 0x0, 0x8, 0x30, 0x0, 0x0, - 0x0, 0x0, 0x5, 0x94, 0x44, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x0, 0x1a, 0xd3, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x0, 0x0, 0x8f, 0x10, 0x0, 0x0, - 0x0, 0x0, 0x0, 0x0, 0x6, 0x0, 0x0, 0x0, - - /* U+4EE5 "以" */ - 0x0, 0x0, 0x0, 0x0, 0x3, 0x60, 0x1, 0xe2, - 0x1, 0x0, 0x0, 0x4d, 0x0, 0xe, 0x0, 0x57, - 0x0, 0x4, 0xb0, 0x0, 0xe0, 0x0, 0xc8, 0x0, - 0x4b, 0x0, 0xe, 0x0, 0x5, 0xc0, 0x5, 0xa0, - 0x0, 0xe0, 0x0, 0x2, 0x0, 0x59, 0x0, 0xe, - 0x0, 0x0, 0x0, 0x6, 0x80, 0x0, 0xe0, 0x0, - 0x1, 0x0, 0x96, 0x0, 0xe, 0x0, 0x37, 0x0, - 0xd, 0x30, 0x0, 0xe0, 0x87, 0x0, 0x4, 0xf1, - 0x0, 0x1f, 0xe5, 0x0, 0x0, 0xc4, 0xa4, 0x2, - 0xe4, 0x0, 0x1, 0xb6, 0x1, 0xe5, 0x1, 0x0, - 0x4, 0xb3, 0x0, 0x6, 0xc0, 0x2, 0x67, 0x40, - 0x0, 0x0, 0x5, 0x2, 0x20, 0x0, 0x0, 0x0, - 0x0, 0x0, - - /* U+4EEE "仮" */ - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, 0xb5, 0x0, 0x0, 0x0, 0x5a, 0x0, - 0x0, 0x0, 0xe0, 0x36, 0x56, 0x89, 0x86, 0x20, - 0x0, 0x6, 0x80, 0x49, 0x0, 0x0, 0x0, 0x0, - 0x0, 0xc, 0x10, 0x49, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x4f, 0x10, 0x4b, 0x66, 0x66, 0x7a, 0x0, - 0x0, 0xad, 0x0, 0x48, 0x50, 0x0, 0x88, 0x0, - 0x5, 0x3d, 0x0, 0x58, 0x60, 0x0, 0xb1, 0x0, - 0x14, 0xd, 0x0, 0x67, 0x34, 0x1, 0xc0, 0x0, - 0x0, 0xd, 0x0, 0x85, 0x9, 0x7, 0x60, 0x0, - 0x0, 0xd, 0x0, 0xa2, 0x8, 0x2c, 0x0, 0x0, - 0x0, 0xd, 0x0, 0xc0, 0x1, 0xe7, 0x0, 0x0, - 0x0, 0xd, 0x3, 0x70, 0x4, 0xdb, 0x0, 0x0, - 0x0, 0xd, 0x7, 0x0, 0x69, 0x8, 0xc3, 0x0, - 0x0, 0xd, 0x34, 0x38, 0x40, 0x0, 0x5f, 0xa0, - 0x0, 0x2, 0x12, 0x30, 0x0, 0x0, 0x1, 0x0, - - /* U+4EF6 "件" */ - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, 0xa6, 0x0, 0x1, 0xd1, 0x0, 0x0, - 0x0, 0x1, 0xf2, 0x6, 0x0, 0xd0, 0x0, 0x0, - 0x0, 0x7, 0x90, 0x2e, 0x10, 0xd0, 0x0, 0x0, - 0x0, 0xc, 0x10, 0x59, 0x0, 0xd0, 0x5, 0x0, - 0x0, 0x5f, 0x40, 0x97, 0x66, 0xe6, 0x68, 0x30, - 0x0, 0xad, 0x10, 0x90, 0x0, 0xd0, 0x0, 0x0, - 0x6, 0x3c, 0x14, 0x20, 0x0, 0xd0, 0x0, 0x0, - 0x25, 0xc, 0x12, 0x0, 0x0, 0xd0, 0x1, 0x50, - 0x10, 0xc, 0x15, 0x76, 0x66, 0xe6, 0x66, 0x71, - 0x0, 0xc, 0x10, 0x0, 0x0, 0xd0, 0x0, 0x0, - 0x0, 0xc, 0x10, 0x0, 0x0, 0xd0, 0x0, 0x0, - 0x0, 0xc, 0x10, 0x0, 0x0, 0xd0, 0x0, 0x0, - 0x0, 0xc, 0x10, 0x0, 0x0, 0xe0, 0x0, 0x0, - 0x0, 0xd, 0x10, 0x0, 0x1, 0xe0, 0x0, 0x0, - 0x0, 0x5, 0x0, 0x0, 0x0, 0x50, 0x0, 0x0, - - /* U+4EFB "任" */ - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0xa, 0x50, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0xe2, 0x0, 0x0, 0x27, 0xd5, 0x0, 0x0, - 0x59, 0x25, 0x67, 0xd8, 0x53, 0x10, 0x0, 0xc, - 0x20, 0x0, 0xc, 0x10, 0x0, 0x0, 0x3, 0xe1, - 0x0, 0x0, 0xc1, 0x0, 0x0, 0x0, 0xae, 0x20, - 0x0, 0xc, 0x10, 0x0, 0x0, 0x46, 0xc1, 0x0, - 0x0, 0xc1, 0x0, 0x40, 0x7, 0xc, 0x17, 0x66, - 0x6d, 0x76, 0x6a, 0x43, 0x0, 0xc1, 0x0, 0x0, - 0xc1, 0x0, 0x0, 0x0, 0xc, 0x10, 0x0, 0xc, - 0x10, 0x0, 0x0, 0x0, 0xc1, 0x0, 0x0, 0xc1, - 0x0, 0x0, 0x0, 0xc, 0x10, 0x0, 0xc, 0x10, - 0x0, 0x0, 0x0, 0xc1, 0x0, 0x0, 0xc1, 0x0, - 0x40, 0x0, 0xd, 0x27, 0x66, 0x69, 0x66, 0x69, - 0x60, 0x0, 0x50, 0x0, 0x0, 0x0, 0x0, 0x0, - - /* U+4EFD "份" */ - 0x0, 0x0, 0x32, 0x0, 0x0, 0x43, 0x0, 0x0, - 0x0, 0x0, 0xb9, 0x0, 0xd3, 0x24, 0x0, 0x0, - 0x0, 0x1, 0xe0, 0x4, 0xb0, 0x8, 0x0, 0x0, - 0x0, 0x8, 0x60, 0xb, 0x30, 0x8, 0x10, 0x0, - 0x0, 0x1d, 0x0, 0x3a, 0x0, 0x2, 0xb0, 0x0, - 0x0, 0x8f, 0x30, 0xa1, 0x0, 0x0, 0x8b, 0x10, - 0x3, 0x6d, 0x16, 0x30, 0x0, 0x0, 0x4a, 0xc1, - 0x16, 0xd, 0x43, 0x16, 0xe6, 0x67, 0xd0, 0x0, - 0x10, 0xd, 0x10, 0x0, 0xe0, 0x2, 0xa0, 0x0, - 0x0, 0xd, 0x10, 0x1, 0xd0, 0x3, 0xa0, 0x0, - 0x0, 0xd, 0x10, 0x5, 0x90, 0x3, 0x90, 0x0, - 0x0, 0xd, 0x10, 0xb, 0x20, 0x4, 0x80, 0x0, - 0x0, 0xd, 0x10, 0x57, 0x1, 0x7, 0x70, 0x0, - 0x0, 0xd, 0x15, 0x60, 0x3, 0xcf, 0x20, 0x0, - 0x0, 0x6, 0x41, 0x0, 0x0, 0x1, 0x0, 0x0, - - /* U+4F01 "企" */ - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x0, 0x9, 0x90, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x0, 0x2f, 0x80, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x0, 0xb8, 0x17, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x7, 0xb0, 0x4, 0x80, 0x0, 0x0, - 0x0, 0x0, 0x4c, 0x0, 0x20, 0x7a, 0x0, 0x0, - 0x0, 0x4, 0xa0, 0x1, 0xe1, 0x6, 0xe6, 0x10, - 0x0, 0x66, 0x0, 0x1, 0xd0, 0x0, 0x4e, 0xa1, - 0x15, 0x10, 0x85, 0x1, 0xd0, 0x1, 0x0, 0x0, - 0x0, 0x0, 0xa4, 0x1, 0xe6, 0x6c, 0x70, 0x0, - 0x0, 0x0, 0xa3, 0x1, 0xd0, 0x0, 0x0, 0x0, - 0x0, 0x0, 0xa3, 0x1, 0xd0, 0x0, 0x0, 0x0, - 0x0, 0x0, 0xa3, 0x1, 0xd0, 0x0, 0x0, 0x0, - 0x0, 0x0, 0xa3, 0x1, 0xd0, 0x0, 0x7, 0x20, - 0x7, 0x66, 0x76, 0x66, 0x86, 0x66, 0x69, 0x70, - - /* U+4F0A "伊" */ - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x1, 0xe2, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x6, 0xb3, 0x66, 0x66, 0x66, 0xc3, 0x0, - 0x0, 0xb, 0x30, 0x10, 0xe0, 0x0, 0xe0, 0x0, - 0x0, 0x2b, 0x0, 0x0, 0xe0, 0x0, 0xe0, 0x0, - 0x0, 0x9e, 0x30, 0x0, 0xe0, 0x0, 0xe0, 0x30, - 0x1, 0x9d, 0x38, 0x66, 0xe6, 0x66, 0xe7, 0x90, - 0x7, 0xd, 0x10, 0x0, 0xe0, 0x0, 0xe0, 0x0, - 0x22, 0xd, 0x10, 0x0, 0xd0, 0x0, 0xe0, 0x0, - 0x0, 0xd, 0x10, 0x0, 0xd0, 0x0, 0xe0, 0x0, - 0x0, 0xd, 0x15, 0x78, 0xc6, 0x66, 0xe0, 0x0, - 0x0, 0xd, 0x10, 0x7, 0x60, 0x0, 0x20, 0x0, - 0x0, 0xd, 0x10, 0xc, 0x0, 0x0, 0x0, 0x0, - 0x0, 0xd, 0x10, 0x84, 0x0, 0x0, 0x0, 0x0, - 0x0, 0xd, 0x16, 0x30, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x5, 0x30, 0x0, 0x0, 0x0, 0x0, 0x0, - - /* U+4F11 "休" */ - 0x0, 0x0, 0x84, 0x0, 0xb, 0x30, 0x0, 0x0, - 0x0, 0x0, 0xe1, 0x0, 0xe, 0x0, 0x0, 0x0, - 0x0, 0x6, 0x80, 0x0, 0xd, 0x0, 0x0, 0x0, - 0x0, 0xc, 0x10, 0x0, 0xd, 0x0, 0x8, 0x0, - 0x0, 0x4d, 0x37, 0x66, 0xcf, 0x96, 0x66, 0x30, - 0x0, 0xbe, 0x20, 0x0, 0xee, 0x60, 0x0, 0x0, - 0x5, 0x5c, 0x10, 0x4, 0xad, 0x35, 0x0, 0x0, - 0x7, 0xc, 0x10, 0xb, 0x2d, 0xa, 0x0, 0x0, - 0x20, 0xc, 0x10, 0x49, 0xd, 0x7, 0x60, 0x0, - 0x0, 0xc, 0x10, 0xb1, 0xd, 0x0, 0xe3, 0x0, - 0x0, 0xc, 0x17, 0x30, 0xd, 0x0, 0x5e, 0x50, - 0x0, 0xc, 0x44, 0x0, 0xd, 0x0, 0x7, 0x50, - 0x0, 0xc, 0x20, 0x0, 0xe, 0x0, 0x0, 0x0, - 0x0, 0xd, 0x10, 0x0, 0xe, 0x0, 0x0, 0x0, - 0x0, 0x7, 0x0, 0x0, 0x7, 0x0, 0x0, 0x0, - - /* U+4F1A "会" */ - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x0, 0xd, 0x40, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x0, 0x7d, 0x50, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x1, 0xd2, 0x63, 0x0, 0x0, 0x0, - 0x0, 0x0, 0xc, 0x50, 0xa, 0x40, 0x0, 0x0, - 0x0, 0x0, 0x96, 0x0, 0x0, 0xa9, 0x10, 0x0, - 0x0, 0x8, 0x50, 0x0, 0x1, 0x78, 0xfa, 0x61, - 0x0, 0x73, 0x66, 0x66, 0x66, 0x61, 0x2a, 0x50, - 0x15, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x1, 0x66, 0x66, 0x66, 0x66, 0x66, 0x9d, 0x10, - 0x0, 0x20, 0x0, 0xc8, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x5, 0xc0, 0x3, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x2c, 0x10, 0x2, 0xa2, 0x0, 0x0, - 0x0, 0x2, 0xa1, 0x0, 0x0, 0x2e, 0x50, 0x0, - 0x0, 0xe, 0xcc, 0xba, 0x87, 0x67, 0xf0, 0x0, - 0x0, 0x4, 0x30, 0x0, 0x0, 0x0, 0x60, 0x0, - - /* U+4F1D "伝" */ - 0x0, 0x0, 0x64, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, 0xd8, 0x0, 0x0, 0x0, 0x60, 0x0, - 0x0, 0x2, 0xd0, 0x18, 0x66, 0x66, 0x62, 0x0, - 0x0, 0x9, 0x60, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x2e, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0xae, 0x40, 0x0, 0x0, 0x0, 0x8, 0x30, - 0x6, 0x4c, 0x14, 0x76, 0x6e, 0x76, 0x66, 0x50, - 0x25, 0xc, 0x10, 0x0, 0x3e, 0x20, 0x0, 0x0, - 0x0, 0xc, 0x10, 0x0, 0x86, 0x0, 0x0, 0x0, - 0x0, 0xc, 0x10, 0x0, 0xc0, 0x2, 0x0, 0x0, - 0x0, 0xc, 0x10, 0x7, 0x50, 0x2, 0x70, 0x0, - 0x0, 0xc, 0x10, 0x29, 0x0, 0x0, 0x96, 0x0, - 0x0, 0xc, 0x12, 0xc5, 0x55, 0x66, 0x7f, 0x0, - 0x0, 0xc, 0x21, 0xd9, 0x53, 0x10, 0xe, 0x10, - 0x0, 0x6, 0x0, 0x0, 0x0, 0x0, 0x1, 0x0, - - /* U+4F38 "伸" */ - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0xa, 0x10, 0x0, 0x3a, 0x0, 0x0, 0x0, - 0x4, 0xc0, 0x0, 0x2, 0xb0, 0x0, 0x0, 0x0, - 0xa4, 0x2, 0x0, 0x2b, 0x0, 0x50, 0x0, 0x1c, - 0x0, 0xe6, 0x67, 0xd6, 0x6e, 0x20, 0x9, 0xf1, - 0xe, 0x0, 0x2b, 0x0, 0xe0, 0x1, 0x9e, 0x0, - 0xe0, 0x2, 0xb0, 0xe, 0x0, 0x81, 0xe0, 0xe, - 0x66, 0x7d, 0x66, 0xe0, 0x22, 0xe, 0x0, 0xe0, - 0x2, 0xb0, 0xe, 0x0, 0x0, 0xe0, 0xe, 0x0, - 0x2b, 0x0, 0xe0, 0x0, 0xe, 0x0, 0xe6, 0x67, - 0xd6, 0x6e, 0x0, 0x0, 0xe0, 0x5, 0x0, 0x2b, - 0x0, 0x50, 0x0, 0xe, 0x0, 0x0, 0x2, 0xb0, - 0x0, 0x0, 0x0, 0xe0, 0x0, 0x0, 0x2b, 0x0, - 0x0, 0x0, 0xf, 0x0, 0x0, 0x3, 0xc0, 0x0, - 0x0, 0x0, 0x40, 0x0, 0x0, 0x14, 0x0, 0x0, - - /* U+4F3C "似" */ - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x2, 0xd2, 0x0, 0x0, 0x0, 0x20, 0x0, - 0x0, 0x7, 0xb0, 0x0, 0x0, 0x0, 0xa8, 0x0, - 0x0, 0xc, 0x20, 0x91, 0x40, 0x0, 0xa5, 0x0, - 0x0, 0x3a, 0x0, 0xd0, 0x1b, 0x0, 0xa4, 0x0, - 0x0, 0x9e, 0x20, 0xd0, 0xb, 0x60, 0xb4, 0x0, - 0x2, 0x9e, 0x0, 0xd0, 0x6, 0x30, 0xc3, 0x0, - 0x8, 0xe, 0x0, 0xd0, 0x0, 0x0, 0xe1, 0x0, - 0x22, 0xe, 0x0, 0xd0, 0x0, 0x1, 0xf0, 0x0, - 0x0, 0xe, 0x0, 0xd0, 0x0, 0x4, 0xc0, 0x0, - 0x0, 0xe, 0x0, 0xd0, 0x46, 0x9, 0x70, 0x0, - 0x0, 0xe, 0x0, 0xda, 0x50, 0x2e, 0x83, 0x0, - 0x0, 0xe, 0x0, 0xe5, 0x0, 0xc4, 0xc, 0x50, - 0x0, 0xe, 0x0, 0x10, 0x1b, 0x30, 0x4, 0xe0, - 0x0, 0xe, 0x0, 0x16, 0x60, 0x0, 0x0, 0x70, - 0x0, 0x5, 0x2, 0x30, 0x0, 0x0, 0x0, 0x0, - - /* U+4F46 "但" */ - 0x0, 0x0, 0xa2, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x2, 0xe1, 0x86, 0x66, 0x66, 0x6c, 0x10, - 0x0, 0x8, 0x70, 0xb3, 0x0, 0x0, 0xd, 0x0, - 0x0, 0xd, 0x10, 0xa3, 0x0, 0x0, 0xd, 0x0, - 0x0, 0x6d, 0x0, 0xa3, 0x0, 0x0, 0xd, 0x0, - 0x0, 0xce, 0x0, 0xa3, 0x0, 0x0, 0xd, 0x0, - 0x7, 0x4d, 0x0, 0xa8, 0x66, 0x66, 0x6d, 0x0, - 0x15, 0xd, 0x0, 0xa3, 0x0, 0x0, 0xd, 0x0, - 0x0, 0xd, 0x0, 0xa3, 0x0, 0x0, 0xd, 0x0, - 0x0, 0xd, 0x0, 0xb8, 0x66, 0x66, 0x6d, 0x0, - 0x0, 0xd, 0x0, 0xb3, 0x0, 0x0, 0xd, 0x0, - 0x0, 0xd, 0x0, 0x40, 0x0, 0x0, 0x0, 0x0, - 0x0, 0xd, 0x0, 0x0, 0x0, 0x0, 0x0, 0x60, - 0x0, 0xe, 0x27, 0x66, 0x66, 0x66, 0x66, 0x93, - 0x0, 0x4, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - - /* U+4F4D "位" */ - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, 0xd4, 0x0, 0x62, 0x0, 0x0, 0x0, - 0x0, 0x3, 0xd0, 0x0, 0x1e, 0x10, 0x0, 0x0, - 0x0, 0x8, 0x60, 0x0, 0xc, 0x20, 0x1, 0x0, - 0x0, 0xd, 0x4, 0x66, 0x66, 0x66, 0x7f, 0x40, - 0x0, 0x4e, 0x21, 0x10, 0x0, 0x1, 0x10, 0x0, - 0x0, 0xbe, 0x0, 0x20, 0x0, 0x4, 0xe1, 0x0, - 0x4, 0x5d, 0x0, 0x25, 0x0, 0x7, 0x90, 0x0, - 0x7, 0xd, 0x0, 0xc, 0x0, 0xa, 0x30, 0x0, - 0x10, 0xd, 0x0, 0xa, 0x60, 0xc, 0x0, 0x0, - 0x0, 0xd, 0x0, 0x7, 0xa0, 0x19, 0x0, 0x0, - 0x0, 0xd, 0x0, 0x5, 0x90, 0x54, 0x0, 0x0, - 0x0, 0xd, 0x0, 0x1, 0x10, 0x80, 0x0, 0x0, - 0x0, 0xd, 0x0, 0x0, 0x0, 0x70, 0x3, 0x60, - 0x0, 0xd, 0x17, 0x66, 0x66, 0x66, 0x66, 0x61, - 0x0, 0x3, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - - /* U+4F4E "低" */ - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, 0xc3, 0x0, 0x0, 0x0, 0x40, 0x0, - 0x0, 0x3, 0xd0, 0x0, 0x0, 0x5c, 0xd6, 0x0, - 0x0, 0xa, 0x40, 0x96, 0x68, 0xd1, 0x0, 0x0, - 0x0, 0x1c, 0x0, 0xd0, 0x0, 0xd0, 0x0, 0x0, - 0x0, 0x9e, 0x0, 0xd0, 0x0, 0xd0, 0x0, 0x0, - 0x2, 0x9d, 0x0, 0xd0, 0x0, 0xd0, 0x1, 0x0, - 0x8, 0xd, 0x0, 0xd6, 0x66, 0xe6, 0x6a, 0x60, - 0x11, 0xd, 0x0, 0xd0, 0x0, 0xa2, 0x0, 0x0, - 0x0, 0xd, 0x0, 0xd0, 0x0, 0x85, 0x0, 0x0, - 0x0, 0xd, 0x0, 0xd0, 0x0, 0x4a, 0x0, 0x0, - 0x0, 0xd, 0x0, 0xd0, 0x2, 0xd, 0x10, 0x40, - 0x0, 0xd, 0x0, 0xd3, 0x83, 0x6, 0xb0, 0x80, - 0x0, 0xd, 0x0, 0xfb, 0x75, 0x0, 0xbb, 0xb0, - 0x0, 0xe, 0x0, 0x40, 0xc, 0x30, 0x8, 0xd0, - 0x0, 0x4, 0x0, 0x0, 0x2, 0x0, 0x0, 0x0, - - /* U+4F4F "住" */ - 0x0, 0x0, 0x57, 0x0, 0x72, 0x0, 0x0, 0x0, - 0x0, 0xb, 0x70, 0x1, 0xe4, 0x0, 0x0, 0x0, - 0x2, 0xd0, 0x0, 0x8, 0x50, 0x1, 0x0, 0x0, - 0xa4, 0x36, 0x66, 0x66, 0x67, 0xe3, 0x0, 0x3e, - 0x10, 0x10, 0xe, 0x0, 0x0, 0x0, 0xa, 0xe2, - 0x0, 0x0, 0xe0, 0x0, 0x0, 0x6, 0x4c, 0x10, - 0x0, 0xe, 0x0, 0x0, 0x2, 0x50, 0xc1, 0x0, - 0x0, 0xe0, 0x6, 0x10, 0x0, 0xc, 0x11, 0x86, - 0x6e, 0x66, 0x75, 0x0, 0x0, 0xc1, 0x0, 0x0, - 0xe0, 0x0, 0x0, 0x0, 0xc, 0x10, 0x0, 0xe, - 0x0, 0x0, 0x0, 0x0, 0xc1, 0x0, 0x0, 0xe0, - 0x0, 0x0, 0x0, 0xd, 0x10, 0x0, 0xe, 0x0, - 0x4, 0x0, 0x0, 0xd3, 0x86, 0x66, 0xa6, 0x66, - 0xa5, 0x0, 0x4, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, - - /* U+4F53 "体" */ - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, 0xc2, 0x0, 0xb, 0x30, 0x0, 0x0, - 0x0, 0x3, 0xc0, 0x0, 0xc, 0x10, 0x0, 0x0, - 0x0, 0x9, 0x50, 0x0, 0xc, 0x10, 0x0, 0x0, - 0x0, 0x1c, 0x4, 0x66, 0x6d, 0x66, 0x6d, 0x60, - 0x0, 0x7c, 0x21, 0x10, 0xcf, 0x60, 0x0, 0x0, - 0x0, 0xad, 0x0, 0x2, 0xbc, 0x43, 0x0, 0x0, - 0x7, 0x1d, 0x0, 0xa, 0x4c, 0x18, 0x0, 0x0, - 0x23, 0xd, 0x0, 0x2a, 0xc, 0x17, 0x40, 0x0, - 0x0, 0xd, 0x0, 0xa1, 0xc, 0x10, 0xd1, 0x0, - 0x0, 0xd, 0x6, 0x40, 0xc, 0x10, 0x7d, 0x20, - 0x0, 0xd, 0x35, 0x46, 0x6d, 0x69, 0xab, 0x90, - 0x0, 0xd, 0x10, 0x0, 0xc, 0x10, 0x0, 0x0, - 0x0, 0xd, 0x0, 0x0, 0xc, 0x10, 0x0, 0x0, - 0x0, 0xd, 0x0, 0x0, 0xd, 0x20, 0x0, 0x0, - 0x0, 0x3, 0x0, 0x0, 0x3, 0x0, 0x0, 0x0, - - /* U+4F55 "何" */ - 0x0, 0x0, 0x83, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, 0xe2, 0x0, 0x0, 0x0, 0x3, 0x50, - 0x0, 0x5, 0x92, 0x76, 0x66, 0x66, 0xe6, 0x50, - 0x0, 0xb, 0x20, 0x0, 0x0, 0x0, 0xd0, 0x0, - 0x0, 0x3f, 0x20, 0x30, 0x0, 0x40, 0xd0, 0x0, - 0x0, 0xae, 0x0, 0xe6, 0x68, 0xc0, 0xd0, 0x0, - 0x4, 0x5d, 0x0, 0xd0, 0x3, 0xa0, 0xd0, 0x0, - 0x5, 0xd, 0x0, 0xd0, 0x3, 0xa0, 0xd0, 0x0, - 0x0, 0xd, 0x0, 0xd0, 0x3, 0xa0, 0xd0, 0x0, - 0x0, 0xd, 0x0, 0xe6, 0x68, 0xb0, 0xd0, 0x0, - 0x0, 0xd, 0x0, 0x80, 0x0, 0x0, 0xd0, 0x0, - 0x0, 0xd, 0x0, 0x0, 0x0, 0x0, 0xd0, 0x0, - 0x0, 0xd, 0x0, 0x0, 0x0, 0x0, 0xd0, 0x0, - 0x0, 0xd, 0x0, 0x0, 0x0, 0x5b, 0xe0, 0x0, - 0x0, 0x5, 0x0, 0x0, 0x0, 0x3, 0x30, 0x0, - - /* U+4F59 "余" */ - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x0, 0xe, 0x40, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x0, 0x8b, 0x60, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x3, 0xd1, 0x46, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x1d, 0x20, 0x6, 0x80, 0x0, 0x0, - 0x0, 0x1, 0xc3, 0x0, 0x0, 0x7c, 0x30, 0x0, - 0x0, 0x1a, 0x76, 0x66, 0x66, 0xd8, 0xfc, 0x60, - 0x5, 0x60, 0x10, 0xc, 0x10, 0x0, 0x2a, 0x30, - 0x21, 0x0, 0x0, 0xc, 0x10, 0x2, 0x50, 0x0, - 0x0, 0x67, 0x66, 0x6d, 0x66, 0x67, 0x70, 0x0, - 0x0, 0x0, 0x31, 0xc, 0x12, 0x0, 0x0, 0x0, - 0x0, 0x1, 0xe7, 0xc, 0x11, 0x95, 0x0, 0x0, - 0x0, 0xb, 0x50, 0xc, 0x10, 0xa, 0xb1, 0x0, - 0x0, 0xa4, 0x0, 0xd, 0x10, 0x0, 0xbb, 0x0, - 0x17, 0x10, 0x17, 0xcf, 0x0, 0x0, 0x17, 0x0, - 0x0, 0x0, 0x0, 0x33, 0x0, 0x0, 0x0, 0x0, - - /* U+4F5C "作" */ - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, 0xb5, 0x0, 0xb5, 0x0, 0x0, 0x0, - 0x0, 0x1, 0xe1, 0x2, 0xd0, 0x0, 0x0, 0x0, - 0x0, 0x6, 0x80, 0x9, 0x50, 0x0, 0x5, 0x30, - 0x0, 0xc, 0x10, 0x1c, 0x7c, 0x66, 0x66, 0x60, - 0x0, 0x4d, 0x20, 0x83, 0x2b, 0x0, 0x0, 0x0, - 0x0, 0xbd, 0x13, 0x60, 0x2b, 0x0, 0x0, 0x0, - 0x7, 0x3c, 0x15, 0x0, 0x2d, 0x66, 0x7d, 0x10, - 0x14, 0xc, 0x10, 0x0, 0x2b, 0x0, 0x0, 0x0, - 0x0, 0xc, 0x10, 0x0, 0x2b, 0x0, 0x0, 0x0, - 0x0, 0xc, 0x10, 0x0, 0x2b, 0x0, 0x4, 0x0, - 0x0, 0xc, 0x10, 0x0, 0x2d, 0x66, 0x69, 0x60, - 0x0, 0xc, 0x10, 0x0, 0x2b, 0x0, 0x0, 0x0, - 0x0, 0xc, 0x10, 0x0, 0x2b, 0x0, 0x0, 0x0, - 0x0, 0xd, 0x10, 0x0, 0x2c, 0x0, 0x0, 0x0, - 0x0, 0x4, 0x0, 0x0, 0x14, 0x0, 0x0, 0x0, - - /* U+4F60 "你" */ - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, 0xa8, 0x0, 0xa4, 0x0, 0x0, 0x0, - 0x0, 0x0, 0xf3, 0x1, 0xf2, 0x0, 0x0, 0x0, - 0x0, 0x6, 0x90, 0x7, 0x80, 0x0, 0x1, 0x0, - 0x0, 0xc, 0x10, 0xd, 0x76, 0x66, 0x6b, 0xb0, - 0x0, 0x5e, 0x20, 0x66, 0x1, 0x30, 0xb, 0x10, - 0x0, 0xbd, 0x11, 0x80, 0x3, 0xc0, 0x21, 0x0, - 0x7, 0x2c, 0x14, 0x3, 0x3, 0xb0, 0x0, 0x0, - 0x23, 0xc, 0x10, 0xd, 0x53, 0xb0, 0x60, 0x0, - 0x0, 0xc, 0x10, 0x3b, 0x3, 0xb0, 0x48, 0x0, - 0x0, 0xc, 0x10, 0x93, 0x3, 0xb0, 0xb, 0x60, - 0x0, 0xc, 0x12, 0x80, 0x3, 0xb0, 0x3, 0xe0, - 0x0, 0xc, 0x17, 0x0, 0x3, 0xb0, 0x0, 0xb0, - 0x0, 0xc, 0x31, 0x1, 0x4, 0xa0, 0x0, 0x0, - 0x0, 0xd, 0x20, 0x2, 0x9f, 0x80, 0x0, 0x0, - 0x0, 0x3, 0x0, 0x0, 0x3, 0x0, 0x0, 0x0, - - /* U+4F7F "使" */ - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0xd, 0x30, 0x0, 0xb3, 0x0, 0x0, 0x0, - 0x3, 0xd0, 0x0, 0xc, 0x10, 0x0, 0x0, 0x0, - 0x96, 0x46, 0x66, 0xd6, 0x66, 0xa8, 0x0, 0xd, - 0x0, 0x0, 0xc, 0x10, 0x0, 0x0, 0x7, 0xe2, - 0x8, 0x66, 0xd6, 0x66, 0x90, 0x0, 0xad, 0x0, - 0xd0, 0xc, 0x0, 0x1b, 0x0, 0x71, 0xd0, 0xd, - 0x0, 0xc0, 0x1, 0xb0, 0x23, 0xd, 0x0, 0xd6, - 0x6e, 0x66, 0x6b, 0x0, 0x0, 0xd0, 0x7, 0x10, - 0xc0, 0x1, 0x60, 0x0, 0xd, 0x0, 0x6, 0xc, - 0x0, 0x0, 0x0, 0x0, 0xd0, 0x0, 0x39, 0x90, - 0x0, 0x0, 0x0, 0xd, 0x0, 0x0, 0xc9, 0x0, - 0x0, 0x0, 0x0, 0xd0, 0x0, 0x86, 0x6c, 0x72, - 0x0, 0x0, 0xd, 0x4, 0x72, 0x0, 0x18, 0xee, - 0x80, 0x0, 0x32, 0x10, 0x0, 0x0, 0x0, 0x20, - - /* U+4F86 "來" */ - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x0, 0x95, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, 0xa, 0x40, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, 0xa4, 0x0, 0x5, 0x40, 0x2, 0x76, - 0x76, 0x6c, 0x86, 0x67, 0x66, 0x0, 0x0, 0x3e, - 0x10, 0xa4, 0x2, 0xe1, 0x0, 0x0, 0x7, 0x80, - 0xa, 0x40, 0x59, 0x0, 0x0, 0x0, 0xc7, 0x70, - 0xa4, 0xa, 0x79, 0x10, 0x0, 0x84, 0xb, 0x4f, - 0x93, 0x70, 0x5a, 0x0, 0x43, 0x0, 0x1b, 0xe8, - 0x80, 0x0, 0x20, 0x0, 0x0, 0x8, 0x9a, 0x48, - 0x40, 0x0, 0x0, 0x0, 0x6, 0xa0, 0xa4, 0xb, - 0x50, 0x0, 0x0, 0x8, 0x80, 0xa, 0x40, 0xc, - 0xa2, 0x0, 0x18, 0x30, 0x0, 0xa4, 0x0, 0x9, - 0xf8, 0x14, 0x0, 0x0, 0xb, 0x50, 0x0, 0x2, - 0x0, 0x0, 0x0, 0x0, 0x61, 0x0, 0x0, 0x0, - - /* U+4F8B "例" */ - 0x0, 0x3, 0xa0, 0x0, 0x0, 0x0, 0x6, 0x30, - 0x0, 0x79, 0x0, 0x0, 0x42, 0x0, 0xa3, 0x0, - 0xc, 0x36, 0x7e, 0x66, 0x40, 0xa, 0x30, 0x1, - 0xc0, 0x5, 0x80, 0x0, 0xc2, 0xa3, 0x0, 0x8d, - 0x10, 0x93, 0x6, 0xd, 0xa, 0x30, 0xb, 0xd0, - 0xc, 0x66, 0xe2, 0xd0, 0xa3, 0x6, 0x2d, 0x4, - 0x60, 0x3b, 0xd, 0xa, 0x30, 0x50, 0xd0, 0x88, - 0x17, 0x60, 0xd0, 0xa3, 0x0, 0xd, 0x43, 0x48, - 0xd1, 0xd, 0xa, 0x30, 0x0, 0xd0, 0x0, 0x5a, - 0x0, 0xd0, 0xa3, 0x0, 0xd, 0x0, 0xb, 0x10, - 0xb, 0xa, 0x30, 0x0, 0xd0, 0x6, 0x60, 0x0, - 0x0, 0xa3, 0x0, 0xd, 0x4, 0x70, 0x0, 0x0, - 0xa, 0x30, 0x0, 0xe4, 0x40, 0x0, 0x0, 0x4a, - 0xf1, 0x0, 0x4, 0x0, 0x0, 0x0, 0x0, 0x14, - 0x0, - - /* U+4F9B "供" */ - 0x0, 0x0, 0x86, 0x2, 0x80, 0x9, 0x10, 0x0, - 0x0, 0x0, 0xe4, 0x2, 0xa0, 0xd, 0x0, 0x0, - 0x0, 0x5, 0xa0, 0x2, 0xa0, 0xd, 0x0, 0x0, - 0x0, 0xc, 0x20, 0x2, 0xa0, 0xd, 0x7, 0x20, - 0x0, 0x4e, 0x23, 0x77, 0xc6, 0x6e, 0x66, 0x40, - 0x0, 0xbd, 0x0, 0x2, 0xa0, 0xd, 0x0, 0x0, - 0x6, 0x2d, 0x0, 0x2, 0xa0, 0xd, 0x0, 0x0, - 0x23, 0xd, 0x0, 0x2, 0xa0, 0xd, 0x0, 0x0, - 0x0, 0xd, 0x26, 0x67, 0xc6, 0x6e, 0x68, 0xd1, - 0x0, 0xd, 0x2, 0x0, 0x10, 0x0, 0x0, 0x0, - 0x0, 0xd, 0x0, 0x5, 0xd0, 0x15, 0x0, 0x0, - 0x0, 0xd, 0x0, 0x1d, 0x20, 0x3, 0xb2, 0x0, - 0x0, 0xd, 0x0, 0xb3, 0x0, 0x0, 0x4f, 0x30, - 0x0, 0xe, 0x8, 0x20, 0x0, 0x0, 0x7, 0x70, - 0x0, 0x6, 0x30, 0x0, 0x0, 0x0, 0x0, 0x0, - - /* U+4F9D "依" */ - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x2, 0xd1, 0x0, 0x55, 0x0, 0x0, 0x0, - 0x0, 0x7, 0x90, 0x0, 0xd, 0x40, 0x0, 0x0, - 0x0, 0xc, 0x25, 0x66, 0x6c, 0x76, 0x6d, 0x60, - 0x0, 0x2d, 0x11, 0x0, 0x2e, 0x10, 0x0, 0x0, - 0x0, 0x9e, 0x0, 0x0, 0xa9, 0x0, 0x0, 0x0, - 0x1, 0x8d, 0x0, 0x4, 0x95, 0x0, 0x27, 0x0, - 0x7, 0x1d, 0x0, 0x1b, 0x3, 0x40, 0xc7, 0x0, - 0x13, 0xd, 0x0, 0xae, 0x10, 0x98, 0x20, 0x0, - 0x0, 0xd, 0x8, 0x3d, 0x0, 0xa1, 0x0, 0x0, - 0x0, 0xd, 0x41, 0xd, 0x0, 0x58, 0x0, 0x0, - 0x0, 0xd, 0x0, 0xd, 0x0, 0x2d, 0x30, 0x0, - 0x0, 0xd, 0x0, 0xd, 0x17, 0x14, 0xe3, 0x0, - 0x0, 0xd, 0x0, 0xe, 0xb0, 0x0, 0x7f, 0x90, - 0x0, 0xd, 0x0, 0xb, 0x0, 0x0, 0x6, 0x10, - 0x0, 0x4, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - - /* U+4FA1 "価" */ - 0x0, 0x0, 0x95, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0xe, 0x10, 0x0, 0x0, 0x0, 0x73, 0x0, - 0x5, 0x94, 0x76, 0xd6, 0x6d, 0x66, 0x40, 0x0, - 0xc1, 0x0, 0xc, 0x0, 0xb0, 0x0, 0x0, 0x4f, - 0x30, 0x0, 0xc0, 0xb, 0x0, 0x0, 0xa, 0xc0, - 0xc, 0x6d, 0x66, 0xd6, 0xd3, 0x5, 0x3c, 0x0, - 0xd0, 0xc0, 0xb, 0xd, 0x1, 0x40, 0xc0, 0xd, - 0xc, 0x0, 0xb0, 0xd0, 0x0, 0xc, 0x0, 0xd0, - 0xc0, 0xb, 0xd, 0x0, 0x0, 0xc0, 0xd, 0xc, - 0x0, 0xb0, 0xd0, 0x0, 0xc, 0x0, 0xd0, 0xc0, - 0xb, 0xd, 0x0, 0x0, 0xc0, 0xd, 0xc, 0x0, - 0xb0, 0xd0, 0x0, 0xc, 0x0, 0xd6, 0x86, 0x68, - 0x6e, 0x0, 0x0, 0xc0, 0xd, 0x0, 0x0, 0x0, - 0xc0, 0x0, 0x4, 0x0, 0x30, 0x0, 0x0, 0x1, - 0x0, - - /* U+4FBF "便" */ - 0x0, 0x0, 0x91, 0x0, 0x0, 0x0, 0x0, 0x10, - 0x0, 0x2, 0xf7, 0x76, 0x67, 0x66, 0x69, 0xa0, - 0x0, 0x8, 0x70, 0x0, 0xa, 0x20, 0x0, 0x0, - 0x0, 0xd, 0x0, 0xa6, 0x6c, 0x76, 0x6d, 0x20, - 0x0, 0x6b, 0x0, 0xd0, 0xa, 0x20, 0xd, 0x0, - 0x0, 0xbe, 0x0, 0xd0, 0xa, 0x20, 0xd, 0x0, - 0x6, 0x3d, 0x0, 0xd6, 0x6c, 0x76, 0x6d, 0x0, - 0x6, 0xd, 0x0, 0xd0, 0xa, 0x20, 0xd, 0x0, - 0x0, 0xd, 0x0, 0xd6, 0x6c, 0x76, 0x6d, 0x0, - 0x0, 0xd, 0x0, 0x50, 0xc, 0x0, 0x1, 0x0, - 0x0, 0xd, 0x0, 0x6, 0xd, 0x0, 0x0, 0x0, - 0x0, 0xd, 0x0, 0x2, 0xa9, 0x0, 0x0, 0x0, - 0x0, 0xd, 0x0, 0x1, 0xcc, 0x40, 0x0, 0x0, - 0x0, 0xe, 0x0, 0x59, 0x21, 0x9e, 0xb9, 0x81, - 0x0, 0x6, 0x35, 0x20, 0x0, 0x0, 0x37, 0x40, - - /* U+4FC2 "係" */ - 0x0, 0x0, 0x96, 0x0, 0x0, 0x0, 0x14, 0x0, - 0x0, 0x0, 0xf3, 0x2, 0x46, 0x9b, 0xdc, 0x40, - 0x0, 0x5, 0xa1, 0x43, 0x2b, 0x80, 0x0, 0x0, - 0x0, 0xc, 0x30, 0x0, 0x89, 0x20, 0x90, 0x0, - 0x0, 0x3e, 0x20, 0x39, 0x40, 0xb, 0xb2, 0x0, - 0x0, 0xae, 0x0, 0xcb, 0x97, 0xd7, 0x0, 0x0, - 0x4, 0x6d, 0x0, 0x0, 0x29, 0x20, 0x44, 0x0, - 0x7, 0xd, 0x0, 0x17, 0x60, 0x0, 0xb, 0x20, - 0x0, 0xd, 0x0, 0xac, 0xa8, 0xd5, 0x48, 0xa0, - 0x0, 0xd, 0x0, 0x1, 0x0, 0xc1, 0x1, 0x30, - 0x0, 0xd, 0x0, 0x9, 0xa0, 0xc1, 0x92, 0x0, - 0x0, 0xd, 0x0, 0x3b, 0x0, 0xc0, 0x1d, 0x40, - 0x0, 0xd, 0x1, 0xa0, 0x0, 0xc0, 0x4, 0xd0, - 0x0, 0xd, 0x6, 0x1, 0x8a, 0xb0, 0x0, 0x30, - 0x0, 0x6, 0x0, 0x0, 0x8, 0x20, 0x0, 0x0, - - /* U+4FDD "保" */ - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, 0xb7, 0x11, 0x0, 0x0, 0x30, 0x0, - 0x0, 0x1, 0xe1, 0x3d, 0x66, 0x66, 0xd4, 0x0, - 0x0, 0x6, 0x80, 0x2b, 0x0, 0x0, 0xc0, 0x0, - 0x0, 0xc, 0x10, 0x2b, 0x0, 0x0, 0xc0, 0x0, - 0x0, 0x5e, 0x10, 0x2b, 0x0, 0x0, 0xc0, 0x0, - 0x0, 0xad, 0x0, 0x3d, 0x6b, 0x66, 0xd0, 0x0, - 0x7, 0x2d, 0x0, 0x11, 0xb, 0x10, 0x0, 0x0, - 0x12, 0xd, 0x16, 0x66, 0x6d, 0x66, 0x69, 0xa0, - 0x0, 0xd, 0x1, 0x0, 0x8e, 0x51, 0x0, 0x0, - 0x0, 0xd, 0x0, 0x1, 0xab, 0x18, 0x0, 0x0, - 0x0, 0xd, 0x0, 0xa, 0x2b, 0x16, 0x60, 0x0, - 0x0, 0xd, 0x0, 0x74, 0xb, 0x10, 0xb7, 0x0, - 0x0, 0xd, 0x4, 0x50, 0xb, 0x10, 0x1c, 0xb0, - 0x0, 0xe, 0x23, 0x0, 0xc, 0x20, 0x0, 0x0, - 0x0, 0x3, 0x0, 0x0, 0x3, 0x0, 0x0, 0x0, - - /* U+4FE1 "信" */ - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, 0xa5, 0x0, 0x8, 0x0, 0x0, 0x0, - 0x0, 0x0, 0xe1, 0x0, 0x6, 0xa0, 0x0, 0x0, - 0x0, 0x6, 0x93, 0x66, 0x67, 0xb6, 0x6a, 0x90, - 0x0, 0xc, 0x11, 0x10, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x4d, 0x10, 0x0, 0x0, 0x0, 0x26, 0x0, - 0x0, 0xbd, 0x0, 0x27, 0x66, 0x66, 0x65, 0x0, - 0x5, 0x5d, 0x0, 0x0, 0x0, 0x0, 0x3, 0x0, - 0x16, 0xd, 0x0, 0x47, 0x66, 0x66, 0x78, 0x0, - 0x0, 0xd, 0x0, 0x0, 0x0, 0x0, 0x1, 0x0, - 0x0, 0xd, 0x0, 0x2b, 0x66, 0x66, 0x7d, 0x0, - 0x0, 0xd, 0x0, 0x1b, 0x0, 0x0, 0x2a, 0x0, - 0x0, 0xd, 0x0, 0x1b, 0x0, 0x0, 0x2a, 0x0, - 0x0, 0xd, 0x0, 0x1d, 0x66, 0x66, 0x7a, 0x0, - 0x0, 0xd, 0x0, 0x2b, 0x0, 0x0, 0x2a, 0x0, - 0x0, 0x6, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - - /* U+4FEE "修" */ - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x1, 0xd0, 0x0, 0xe, 0x20, 0x0, 0x0, - 0x0, 0x6, 0x80, 0x0, 0x59, 0x0, 0x0, 0x0, - 0x0, 0xb, 0x20, 0x0, 0xb8, 0x66, 0x7e, 0x20, - 0x0, 0x2b, 0x7, 0x5, 0x57, 0x0, 0xb5, 0x0, - 0x0, 0x9e, 0xc, 0x16, 0x1, 0xab, 0x50, 0x0, - 0x1, 0x9c, 0xc, 0x10, 0x2, 0xbc, 0x30, 0x0, - 0x8, 0x1c, 0xc, 0x0, 0x67, 0x3, 0xac, 0x82, - 0x12, 0xc, 0xc, 0x34, 0x0, 0x7c, 0x12, 0x30, - 0x0, 0xc, 0xc, 0x0, 0x19, 0x60, 0x41, 0x0, - 0x0, 0xc, 0xc, 0x4, 0x61, 0x6, 0xd4, 0x0, - 0x0, 0xc, 0xc, 0x0, 0x2, 0xa7, 0x2, 0x80, - 0x0, 0xc, 0xa, 0x2, 0x77, 0x10, 0x6d, 0x70, - 0x0, 0xc, 0x0, 0x13, 0x0, 0x5b, 0x80, 0x0, - 0x0, 0xc, 0x0, 0x3, 0x79, 0x50, 0x0, 0x0, - 0x0, 0x5, 0x2, 0x53, 0x0, 0x0, 0x0, 0x0, - - /* U+500B "個" */ - 0x0, 0x0, 0xb5, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x1, 0xf3, 0xb6, 0x66, 0x66, 0x66, 0xb0, - 0x0, 0x7, 0x80, 0xd0, 0x3, 0x30, 0x3, 0xa0, - 0x0, 0xd, 0x10, 0xd0, 0x5, 0x70, 0x3, 0xa0, - 0x0, 0x5e, 0x10, 0xd3, 0x69, 0xa7, 0x93, 0xa0, - 0x0, 0xbd, 0x0, 0xd0, 0x5, 0x60, 0x3, 0xa0, - 0x4, 0x4d, 0x0, 0xd0, 0x5, 0x60, 0x3, 0xa0, - 0x5, 0xd, 0x0, 0xd0, 0xa8, 0x8d, 0x33, 0xa0, - 0x0, 0xd, 0x0, 0xd0, 0xc0, 0xc, 0x3, 0xa0, - 0x0, 0xd, 0x0, 0xd0, 0xc0, 0xc, 0x3, 0xa0, - 0x0, 0xd, 0x0, 0xd0, 0xc6, 0x6d, 0x3, 0xa0, - 0x0, 0xd, 0x0, 0xd0, 0x70, 0x5, 0x3, 0xa0, - 0x0, 0xd, 0x0, 0xd6, 0x66, 0x66, 0x67, 0xa0, - 0x0, 0xe, 0x0, 0xd0, 0x0, 0x0, 0x3, 0xa0, - 0x0, 0x4, 0x0, 0x20, 0x0, 0x0, 0x0, 0x0, - - /* U+5011 "們" */ - 0x0, 0x1, 0xc2, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x5, 0xc1, 0xa6, 0x6c, 0x39, 0x66, 0xd0, - 0x0, 0xa, 0x51, 0xd0, 0x2b, 0x3a, 0x1, 0xc0, - 0x0, 0xd, 0x1, 0xe6, 0x7b, 0x3c, 0x66, 0xc0, - 0x0, 0x5e, 0x11, 0xd0, 0x2b, 0x3a, 0x1, 0xc0, - 0x0, 0xad, 0x1, 0xd0, 0x2b, 0x3a, 0x1, 0xc0, - 0x2, 0x6d, 0x1, 0xe6, 0x79, 0x3a, 0x66, 0xc0, - 0x6, 0xd, 0x1, 0xd0, 0x0, 0x0, 0x1, 0xc0, - 0x0, 0xd, 0x1, 0xd0, 0x0, 0x0, 0x1, 0xc0, - 0x0, 0xd, 0x1, 0xd0, 0x0, 0x0, 0x1, 0xc0, - 0x0, 0xd, 0x1, 0xd0, 0x0, 0x0, 0x1, 0xc0, - 0x0, 0xd, 0x1, 0xd0, 0x0, 0x0, 0x1, 0xc0, - 0x0, 0xd, 0x1, 0xd0, 0x0, 0x0, 0x1, 0xc0, - 0x0, 0xe, 0x1, 0xd0, 0x0, 0x1, 0x7d, 0xa0, - 0x0, 0x4, 0x1, 0x30, 0x0, 0x0, 0x4, 0x10, - - /* U+5019 "候" */ - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, 0xc1, 0x0, 0x0, 0x0, 0x30, 0x0, - 0x0, 0x4, 0xb0, 0x2, 0x86, 0x67, 0xd1, 0x0, - 0x0, 0x9, 0x50, 0x0, 0x0, 0x4, 0x80, 0x0, - 0x0, 0xd, 0x9, 0x40, 0x0, 0x6, 0x60, 0x50, - 0x0, 0x4d, 0xa, 0x27, 0xb7, 0x66, 0x66, 0x50, - 0x0, 0xad, 0xa, 0x20, 0xc2, 0x0, 0x1, 0x0, - 0x4, 0x5d, 0xa, 0x22, 0xb6, 0xa6, 0x78, 0x0, - 0x5, 0xd, 0xa, 0x27, 0x10, 0xd0, 0x0, 0x0, - 0x0, 0xd, 0xa, 0x21, 0x0, 0xe0, 0x2, 0x50, - 0x0, 0xd, 0xa, 0x27, 0x67, 0xd9, 0x66, 0x50, - 0x0, 0xd, 0xa, 0x20, 0x6, 0x77, 0x0, 0x0, - 0x0, 0xd, 0xa, 0x20, 0xc, 0x13, 0x80, 0x0, - 0x0, 0xd, 0x0, 0x0, 0x95, 0x0, 0x98, 0x0, - 0x0, 0xe, 0x0, 0x8, 0x40, 0x0, 0xb, 0xd3, - 0x0, 0x7, 0x1, 0x50, 0x0, 0x0, 0x0, 0x20, - - /* U+501F "借" */ - 0x0, 0x0, 0x0, 0x1, 0x0, 0x1, 0x0, 0x0, - 0x0, 0x0, 0xa3, 0x6, 0xa0, 0xd, 0x20, 0x0, - 0x0, 0x1, 0xd0, 0x6, 0x70, 0xd, 0x0, 0x0, - 0x0, 0x6, 0x73, 0x69, 0xa6, 0x6e, 0x69, 0x70, - 0x0, 0xc, 0x10, 0x6, 0x70, 0xd, 0x0, 0x0, - 0x0, 0x59, 0x0, 0x6, 0x70, 0xd, 0x0, 0x0, - 0x0, 0xbe, 0x0, 0x6, 0x70, 0xd, 0x1, 0x60, - 0x7, 0x3d, 0x18, 0x66, 0x66, 0x66, 0x66, 0x71, - 0x24, 0xd, 0x0, 0x20, 0x0, 0x0, 0x30, 0x0, - 0x0, 0xd, 0x0, 0xd6, 0x66, 0x66, 0xd5, 0x0, - 0x0, 0xd, 0x0, 0xc1, 0x0, 0x0, 0xc1, 0x0, - 0x0, 0xd, 0x0, 0xc6, 0x66, 0x66, 0xd1, 0x0, - 0x0, 0xd, 0x0, 0xc1, 0x0, 0x0, 0xc1, 0x0, - 0x0, 0xd, 0x0, 0xc1, 0x0, 0x0, 0xc1, 0x0, - 0x0, 0xe, 0x0, 0xd6, 0x66, 0x66, 0xd1, 0x0, - 0x0, 0x7, 0x0, 0x40, 0x0, 0x0, 0x30, 0x0, - - /* U+5024 "値" */ - 0x0, 0x0, 0xa3, 0x0, 0x4, 0x90, 0x0, 0x0, - 0x0, 0x1, 0xd0, 0x0, 0x5, 0x90, 0x0, 0x10, - 0x0, 0x7, 0x76, 0x76, 0x6a, 0xb6, 0x67, 0xc1, - 0x0, 0xc, 0x10, 0x0, 0x9, 0x50, 0x0, 0x0, - 0x0, 0x4e, 0x10, 0x8, 0x6c, 0x86, 0x6b, 0x0, - 0x0, 0xbd, 0x4, 0xd, 0x0, 0x0, 0x2a, 0x0, - 0x5, 0x3d, 0xd, 0x2d, 0x0, 0x0, 0x2a, 0x0, - 0x15, 0xd, 0xd, 0xd, 0x66, 0x66, 0x7a, 0x0, - 0x0, 0xd, 0xd, 0xd, 0x0, 0x0, 0x2a, 0x0, - 0x0, 0xd, 0xd, 0xd, 0x66, 0x66, 0x7a, 0x0, - 0x0, 0xd, 0xd, 0xd, 0x0, 0x0, 0x2a, 0x0, - 0x0, 0xd, 0xd, 0xd, 0x66, 0x66, 0x7b, 0x0, - 0x0, 0xd, 0xd, 0x9, 0x0, 0x0, 0x16, 0x20, - 0x0, 0xe, 0xe, 0x66, 0x66, 0x66, 0x67, 0xf4, - 0x0, 0x8, 0x4, 0x0, 0x0, 0x0, 0x0, 0x0, - - /* U+503C "值" */ - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, 0xb1, 0x0, 0xc, 0x10, 0x0, 0x0, - 0x0, 0x3, 0xb0, 0x0, 0xe, 0x0, 0x3, 0x0, - 0x0, 0x9, 0x57, 0x76, 0x6e, 0x66, 0x7b, 0x30, - 0x0, 0xd, 0x0, 0x0, 0xd, 0x0, 0x0, 0x0, - 0x0, 0x6d, 0x10, 0x96, 0x6d, 0x66, 0xc2, 0x0, - 0x0, 0xbd, 0x0, 0xc0, 0x0, 0x0, 0xd0, 0x0, - 0x5, 0x4d, 0x0, 0xc6, 0x66, 0x66, 0xd0, 0x0, - 0x6, 0xd, 0x0, 0xc0, 0x0, 0x0, 0xd0, 0x0, - 0x10, 0xd, 0x0, 0xc0, 0x0, 0x0, 0xd0, 0x0, - 0x0, 0xd, 0x0, 0xc6, 0x66, 0x66, 0xd0, 0x0, - 0x0, 0xd, 0x0, 0xc0, 0x0, 0x0, 0xd0, 0x0, - 0x0, 0xd, 0x0, 0xc6, 0x66, 0x66, 0xd0, 0x0, - 0x0, 0xd, 0x0, 0xc0, 0x0, 0x0, 0xd0, 0x0, - 0x0, 0xd, 0x46, 0xd6, 0x66, 0x66, 0xe8, 0xd1, - 0x0, 0x7, 0x11, 0x0, 0x0, 0x0, 0x0, 0x0, - - /* U+505A "做" */ - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x1, 0xb0, 0x24, 0x0, 0xb, 0x10, 0x0, - 0x0, 0x5, 0xa0, 0x48, 0x0, 0x2c, 0x0, 0x0, - 0x0, 0xa, 0x30, 0x37, 0x0, 0x57, 0x0, 0x0, - 0x0, 0xc, 0x0, 0x37, 0x33, 0x83, 0x11, 0x60, - 0x0, 0x6c, 0x28, 0x8a, 0x65, 0xa5, 0x5e, 0x50, - 0x0, 0xba, 0x0, 0x37, 0x0, 0xa0, 0xc, 0x0, - 0x4, 0x7a, 0x0, 0x37, 0x5, 0x60, 0xb, 0x0, - 0x6, 0x2a, 0x9, 0x8a, 0xa4, 0x51, 0x39, 0x0, - 0x0, 0x2a, 0xc, 0x0, 0xb1, 0x25, 0x75, 0x0, - 0x0, 0x2a, 0xc, 0x0, 0xb1, 0x8, 0xb1, 0x0, - 0x0, 0x2a, 0xc, 0x0, 0xb1, 0x8, 0xa0, 0x0, - 0x0, 0x2a, 0xd, 0x66, 0xc1, 0x1c, 0xb0, 0x0, - 0x0, 0x2a, 0xc, 0x0, 0x82, 0xa2, 0x5b, 0x10, - 0x0, 0x3a, 0x6, 0x0, 0x47, 0x0, 0x6, 0xd2, - 0x0, 0x24, 0x0, 0x2, 0x10, 0x0, 0x0, 0x0, - - /* U+505C "停" */ - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x2, 0xb0, 0x0, 0x19, 0x20, 0x0, 0x0, - 0x0, 0x6, 0x90, 0x0, 0x5, 0x90, 0x2, 0x50, - 0x0, 0xb, 0x24, 0x76, 0x66, 0x66, 0x66, 0x60, - 0x0, 0x1b, 0x0, 0xa, 0x66, 0x66, 0xb2, 0x0, - 0x0, 0x8d, 0x0, 0xd, 0x0, 0x0, 0xd0, 0x0, - 0x0, 0xbc, 0x0, 0xe, 0x66, 0x66, 0xe0, 0x0, - 0x6, 0x3c, 0x2, 0x4, 0x0, 0x0, 0x20, 0x20, - 0x3, 0xc, 0xa, 0x66, 0x66, 0x66, 0x66, 0xe3, - 0x0, 0xc, 0x4a, 0x0, 0x0, 0x0, 0x25, 0x10, - 0x0, 0xc, 0x0, 0x67, 0x66, 0xb6, 0x77, 0x0, - 0x0, 0xc, 0x0, 0x0, 0x0, 0xd0, 0x0, 0x0, - 0x0, 0xc, 0x0, 0x0, 0x0, 0xd0, 0x0, 0x0, - 0x0, 0xc, 0x0, 0x0, 0x0, 0xc0, 0x0, 0x0, - 0x0, 0xc, 0x0, 0x0, 0x7c, 0xb0, 0x0, 0x0, - 0x0, 0x4, 0x0, 0x0, 0x5, 0x10, 0x0, 0x0, - - /* U+5065 "健" */ - 0x0, 0x0, 0xa3, 0x0, 0x0, 0x8, 0x0, 0x0, - 0x0, 0x1, 0xe0, 0x1, 0x0, 0xc, 0x1, 0x0, - 0x0, 0x6, 0x85, 0x7e, 0x6, 0x6d, 0x6d, 0x20, - 0x0, 0xb, 0x10, 0x66, 0x0, 0xc, 0xc, 0x30, - 0x0, 0x3b, 0x0, 0xc1, 0x46, 0x6d, 0x6d, 0x62, - 0x0, 0x9e, 0x3, 0xa1, 0x0, 0xc, 0xc, 0x0, - 0x4, 0x5d, 0xa, 0x8b, 0x64, 0x6d, 0x69, 0x0, - 0x5, 0xd, 0x0, 0xa, 0x10, 0xc, 0x6, 0x0, - 0x0, 0xd, 0x3, 0xc, 0x6, 0x6d, 0x66, 0x20, - 0x0, 0xd, 0x6, 0xb, 0x0, 0xc, 0x1, 0x50, - 0x0, 0xd, 0x4, 0x87, 0x46, 0x6d, 0x66, 0x50, - 0x0, 0xd, 0x0, 0xd4, 0x0, 0xc, 0x0, 0x0, - 0x0, 0xd, 0x4, 0x7a, 0x82, 0x4, 0x0, 0x0, - 0x0, 0xd, 0x35, 0x0, 0x4a, 0xcc, 0xcd, 0xb1, - 0x0, 0x0, 0x10, 0x0, 0x0, 0x0, 0x0, 0x0, - - /* U+5074 "側" */ - 0x0, 0x0, 0xc2, 0x0, 0x0, 0x0, 0x1, 0x70, - 0x0, 0x4, 0xc1, 0xb6, 0x6d, 0x10, 0x1, 0xc0, - 0x0, 0x9, 0x51, 0xb0, 0xc, 0xa, 0x31, 0xb0, - 0x0, 0xc, 0x1, 0xb0, 0xc, 0xc, 0x1, 0xb0, - 0x0, 0x4d, 0x1, 0xc6, 0x6c, 0xc, 0x1, 0xb0, - 0x0, 0xaa, 0x1, 0xb0, 0xc, 0xc, 0x1, 0xb0, - 0x3, 0x6a, 0x1, 0xb0, 0xc, 0xc, 0x1, 0xb0, - 0x5, 0x1a, 0x1, 0xc6, 0x6c, 0xc, 0x1, 0xb0, - 0x0, 0x1a, 0x1, 0xb0, 0xc, 0xc, 0x1, 0xb0, - 0x0, 0x1a, 0x1, 0xb0, 0xc, 0xc, 0x1, 0xb0, - 0x0, 0x1a, 0x1, 0xb6, 0x6a, 0x9, 0x1, 0xb0, - 0x0, 0x1a, 0x0, 0x75, 0x42, 0x0, 0x1, 0xb0, - 0x0, 0x1a, 0x2, 0xb1, 0xc, 0x20, 0x1, 0xa0, - 0x0, 0x2b, 0x8, 0x0, 0x7, 0x93, 0x8c, 0x90, - 0x0, 0x13, 0x20, 0x0, 0x1, 0x30, 0x6, 0x0, - - /* U+5099 "備" */ - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x95, 0x2, 0xc0, 0xb, 0x40, 0x0, - 0x0, 0x1, 0xf3, 0x2, 0xb0, 0xb, 0x14, 0x0, - 0x0, 0x6, 0x91, 0x87, 0xc6, 0x6d, 0x68, 0x50, - 0x0, 0xc, 0x20, 0x2, 0xb0, 0xb, 0x10, 0x30, - 0x0, 0x3e, 0x17, 0x67, 0xc6, 0x6a, 0x67, 0xc3, - 0x0, 0xad, 0x0, 0x8, 0xa0, 0x0, 0x0, 0x0, - 0x4, 0x4d, 0x0, 0x4e, 0x66, 0x86, 0x6d, 0x10, - 0x4, 0xd, 0x3, 0xbb, 0x1, 0xc0, 0xd, 0x0, - 0x0, 0xd, 0x46, 0x2c, 0x66, 0xd6, 0x6d, 0x0, - 0x0, 0xd, 0x0, 0x2b, 0x1, 0xc0, 0xd, 0x0, - 0x0, 0xd, 0x0, 0x2c, 0x66, 0xd6, 0x6d, 0x0, - 0x0, 0xd, 0x0, 0x2b, 0x1, 0xc0, 0xd, 0x0, - 0x0, 0xd, 0x0, 0x2b, 0x1, 0xc0, 0xc, 0x0, - 0x0, 0xe, 0x0, 0x2b, 0x1, 0xb5, 0xaa, 0x0, - 0x0, 0x4, 0x0, 0x13, 0x0, 0x0, 0x41, 0x0, - - /* U+50B3 "傳" */ - 0x0, 0x0, 0x0, 0x0, 0x1, 0x0, 0x0, 0x0, - 0x0, 0x0, 0xb3, 0x0, 0xe, 0x10, 0x0, 0x0, - 0x0, 0x3, 0xd4, 0x66, 0x6e, 0x66, 0x7e, 0x30, - 0x0, 0x9, 0x51, 0x30, 0xd, 0x0, 0x40, 0x0, - 0x0, 0xd, 0x0, 0xd6, 0x6e, 0x66, 0xd3, 0x0, - 0x0, 0x6e, 0x10, 0xd6, 0x6e, 0x66, 0xd1, 0x0, - 0x0, 0xad, 0x0, 0xd0, 0xd, 0x0, 0xc1, 0x0, - 0x6, 0x1d, 0x0, 0xd6, 0x6e, 0x66, 0xa1, 0x0, - 0x13, 0xd, 0x0, 0x0, 0xd, 0x1, 0x95, 0x0, - 0x0, 0xd, 0x9, 0xca, 0x88, 0x67, 0x3c, 0x0, - 0x0, 0xd, 0x1, 0x0, 0x0, 0xd, 0x14, 0x20, - 0x0, 0xd, 0x37, 0x86, 0x66, 0x6e, 0x67, 0x60, - 0x0, 0xd, 0x0, 0x5b, 0x0, 0xd, 0x0, 0x0, - 0x0, 0xd, 0x0, 0x7, 0x10, 0xd, 0x0, 0x0, - 0x0, 0xe, 0x0, 0x0, 0x27, 0xbc, 0x0, 0x0, - 0x0, 0x5, 0x0, 0x0, 0x0, 0x42, 0x0, 0x0, - - /* U+50C5 "僅" */ - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, 0xb2, 0x8, 0x40, 0xa, 0x40, 0x0, - 0x0, 0x4, 0xb0, 0x9, 0x30, 0xb, 0x21, 0x20, - 0x0, 0xa, 0x57, 0x6b, 0x76, 0x6c, 0x79, 0x90, - 0x0, 0xd, 0x0, 0x9, 0x30, 0xb, 0x20, 0x0, - 0x0, 0x6d, 0x10, 0x9, 0x7c, 0x7b, 0x10, 0x0, - 0x0, 0xcd, 0x0, 0x30, 0xb, 0x20, 0x23, 0x0, - 0x4, 0x5d, 0x0, 0xd6, 0x6c, 0x76, 0xa8, 0x0, - 0x6, 0xd, 0x0, 0xd0, 0xb, 0x20, 0x76, 0x0, - 0x0, 0xd, 0x0, 0xc6, 0x6c, 0x76, 0x83, 0x0, - 0x0, 0xd, 0x0, 0x66, 0x6c, 0x76, 0xb6, 0x0, - 0x0, 0xd, 0x0, 0x20, 0xb, 0x20, 0x0, 0x0, - 0x0, 0xd, 0x0, 0x56, 0x6c, 0x76, 0xd5, 0x0, - 0x0, 0xd, 0x0, 0x10, 0xb, 0x20, 0x0, 0x0, - 0x0, 0xe, 0x16, 0x66, 0x6c, 0x76, 0x6a, 0xc0, - 0x0, 0x4, 0x2, 0x0, 0x0, 0x0, 0x0, 0x0, - - /* U+50CD "働" */ - 0x0, 0xb, 0x40, 0x1, 0x50, 0x7, 0x30, 0x0, - 0x1, 0xf5, 0x6a, 0x97, 0x10, 0xb2, 0x0, 0x0, - 0x69, 0x0, 0xa2, 0x12, 0xa, 0x20, 0x0, 0xb, - 0x48, 0x6c, 0x77, 0x70, 0xa2, 0x20, 0x1, 0xf2, - 0x12, 0xa2, 0x42, 0x8c, 0x7c, 0x60, 0x8f, 0x2, - 0xcc, 0x7c, 0x50, 0xb2, 0xa2, 0xa, 0xb0, 0x2a, - 0xa2, 0xa2, 0xb, 0x1a, 0x15, 0x1b, 0x2, 0xcc, - 0x7c, 0x20, 0xc0, 0xb1, 0x0, 0xb0, 0x2c, 0xc7, - 0xc2, 0xc, 0xb, 0x0, 0xb, 0x1, 0x4a, 0x24, - 0x1, 0xa0, 0xc0, 0x0, 0xb0, 0x46, 0xc7, 0xb4, - 0x55, 0xc, 0x0, 0xb, 0x1, 0x1a, 0x20, 0x9, - 0x0, 0xc0, 0x0, 0xb1, 0x46, 0xc8, 0x54, 0x60, - 0xb, 0x0, 0xc, 0x1b, 0x61, 0x1, 0x70, 0x5d, - 0x80, 0x0, 0x40, 0x0, 0x0, 0x30, 0x0, 0x30, - 0x0, - - /* U+50CF "像" */ - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, 0xc1, 0x6, 0xc0, 0x0, 0x0, 0x0, - 0x0, 0x4, 0xb0, 0xd, 0x86, 0x6c, 0x60, 0x0, - 0x0, 0xa, 0x40, 0x84, 0x0, 0x47, 0x0, 0x0, - 0x0, 0x1d, 0x4, 0xd6, 0x67, 0xa6, 0x6e, 0x10, - 0x0, 0x8f, 0x23, 0xd0, 0x7, 0x50, 0xe, 0x0, - 0x1, 0x9e, 0x0, 0xd6, 0x6c, 0x86, 0x6e, 0x0, - 0x7, 0xe, 0x0, 0x60, 0x3a, 0x0, 0x15, 0x0, - 0x22, 0xe, 0x0, 0x3, 0xa7, 0x2, 0xd6, 0x0, - 0x0, 0xe, 0x1, 0x76, 0x1c, 0xaa, 0x10, 0x0, - 0x0, 0xe, 0x3, 0x3, 0xb2, 0xd4, 0x30, 0x0, - 0x0, 0xe, 0x1, 0x76, 0xa, 0xd5, 0xa0, 0x0, - 0x0, 0xe, 0x4, 0x2, 0xb4, 0x77, 0x6a, 0x0, - 0x0, 0xe, 0x0, 0x79, 0x10, 0x86, 0xc, 0xb1, - 0x0, 0xe, 0x36, 0x12, 0x7c, 0xe1, 0x1, 0x30, - 0x0, 0x4, 0x0, 0x0, 0x6, 0x20, 0x0, 0x0, - - /* U+50D5 "僕" */ - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, 0xc2, 0x0, 0xc1, 0xb3, 0x0, 0x0, - 0x0, 0x3, 0xb1, 0x30, 0xd0, 0xc0, 0x34, 0x0, - 0x0, 0x8, 0x50, 0xb1, 0xd0, 0xc0, 0xb7, 0x0, - 0x0, 0xc, 0x0, 0x62, 0xd0, 0xc5, 0x51, 0x10, - 0x0, 0x4e, 0x17, 0x66, 0xa6, 0xa8, 0x69, 0x90, - 0x0, 0xad, 0x0, 0x9, 0x30, 0xc, 0x10, 0x0, - 0x3, 0x6d, 0x0, 0x2, 0x80, 0x53, 0x34, 0x0, - 0x7, 0xd, 0x2, 0x66, 0x6c, 0x66, 0x66, 0x0, - 0x0, 0xd, 0x0, 0x0, 0xb, 0x1, 0x70, 0x0, - 0x0, 0xd, 0x0, 0x47, 0x6c, 0x66, 0x62, 0x0, - 0x0, 0xd, 0x7, 0x66, 0x7b, 0x66, 0x6b, 0x60, - 0x0, 0xd, 0x0, 0x0, 0xa1, 0x60, 0x0, 0x0, - 0x0, 0xd, 0x0, 0x9, 0x30, 0x1a, 0x20, 0x0, - 0x0, 0xe, 0x3, 0x82, 0x0, 0x1, 0xbc, 0x80, - 0x0, 0x3, 0x33, 0x0, 0x0, 0x0, 0x4, 0x10, - - /* U+50F9 "價" */ - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x7, 0xa0, 0x0, 0x0, 0x0, 0x4, 0x40, - 0x0, 0xb, 0x54, 0x76, 0xd6, 0x6d, 0x66, 0x50, - 0x0, 0xe, 0x0, 0x86, 0xd6, 0x6d, 0x6a, 0x10, - 0x0, 0x4c, 0x10, 0xb0, 0xc0, 0xb, 0xc, 0x0, - 0x0, 0xad, 0x0, 0xd6, 0xd6, 0x6d, 0x6d, 0x0, - 0x0, 0x9c, 0x0, 0x50, 0x0, 0x0, 0x4, 0x0, - 0x6, 0x2c, 0x0, 0x68, 0x66, 0x66, 0x96, 0x0, - 0x6, 0xc, 0x0, 0x65, 0x0, 0x0, 0x64, 0x0, - 0x10, 0xc, 0x0, 0x59, 0x66, 0x66, 0xa4, 0x0, - 0x0, 0xc, 0x0, 0x59, 0x66, 0x66, 0xa4, 0x0, - 0x0, 0xc, 0x0, 0x55, 0x0, 0x0, 0x64, 0x0, - 0x0, 0xc, 0x0, 0x58, 0x76, 0x67, 0x93, 0x0, - 0x0, 0xc, 0x0, 0x1b, 0x70, 0x3, 0x98, 0x20, - 0x0, 0xd, 0x3, 0x92, 0x0, 0x0, 0x6, 0xe1, - 0x0, 0x4, 0x12, 0x0, 0x0, 0x0, 0x0, 0x20, - - /* U+5104 "億" */ - 0x0, 0x3, 0xb0, 0x0, 0x64, 0x0, 0x0, 0x0, - 0x0, 0x89, 0x0, 0x0, 0xd0, 0x1, 0x30, 0x0, - 0xd, 0x21, 0x88, 0x67, 0x6b, 0x67, 0x0, 0x3, - 0xc0, 0x0, 0x58, 0x3, 0xa0, 0x0, 0x0, 0x9e, - 0x25, 0x66, 0xa6, 0xa6, 0x6b, 0x70, 0x19, 0xd0, - 0x22, 0x0, 0x0, 0x2, 0x0, 0x7, 0x1d, 0x0, - 0xb6, 0x66, 0x66, 0xe0, 0x1, 0x40, 0xd0, 0xb, - 0x66, 0x66, 0x6d, 0x0, 0x0, 0xd, 0x0, 0xb1, - 0x0, 0x0, 0xd0, 0x0, 0x0, 0xd0, 0xa, 0x66, - 0x76, 0x6a, 0x0, 0x0, 0xd, 0x0, 0x18, 0x38, - 0x40, 0x61, 0x0, 0x0, 0xd0, 0x53, 0xb2, 0x17, - 0x42, 0xd1, 0x0, 0xd, 0xd, 0x1b, 0x30, 0x9, - 0x17, 0x40, 0x0, 0xe1, 0x40, 0x7d, 0xcc, 0xd4, - 0x0, 0x0, 0x3, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, - - /* U+512A "優" */ - 0x0, 0x2, 0x80, 0x0, 0x0, 0x0, 0x6, 0x0, - 0x0, 0x6, 0xa1, 0x78, 0x6b, 0x66, 0x96, 0x20, - 0x0, 0xb, 0x30, 0xe, 0x55, 0x55, 0xe1, 0x0, - 0x0, 0xc, 0x0, 0xd, 0x66, 0x66, 0xd0, 0x0, - 0x0, 0x5c, 0x0, 0xd, 0x66, 0x66, 0xd0, 0x0, - 0x0, 0xbb, 0x8, 0x6d, 0x66, 0x66, 0xd6, 0xb0, - 0x3, 0x6b, 0x2b, 0x14, 0x49, 0x30, 0x14, 0x70, - 0x6, 0x1b, 0x12, 0x97, 0x51, 0x66, 0x67, 0x0, - 0x0, 0x1b, 0x8, 0x54, 0xca, 0xad, 0x5b, 0x0, - 0x0, 0x1b, 0x0, 0x6, 0x80, 0x0, 0x10, 0x0, - 0x0, 0x1b, 0x0, 0x2e, 0x86, 0x69, 0xe2, 0x0, - 0x0, 0x1b, 0x2, 0x91, 0x84, 0x6b, 0x10, 0x0, - 0x0, 0x1b, 0x3, 0x0, 0x2e, 0xd3, 0x0, 0x0, - 0x0, 0x2c, 0x0, 0x38, 0x81, 0x3a, 0xda, 0x60, - 0x0, 0x13, 0x15, 0x30, 0x0, 0x0, 0x15, 0x10, - - /* U+513F "儿" */ - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, 0xa, 0x30, 0xb, 0x30, 0x0, 0x0, - 0x0, 0x0, 0xc, 0x20, 0xc, 0x10, 0x0, 0x0, - 0x0, 0x0, 0xc, 0x20, 0xc, 0x10, 0x0, 0x0, - 0x0, 0x0, 0xc, 0x10, 0xc, 0x10, 0x0, 0x0, - 0x0, 0x0, 0xc, 0x10, 0xc, 0x10, 0x0, 0x0, - 0x0, 0x0, 0xd, 0x0, 0xc, 0x10, 0x0, 0x0, - 0x0, 0x0, 0xe, 0x0, 0xc, 0x10, 0x0, 0x0, - 0x0, 0x0, 0x1c, 0x0, 0xc, 0x10, 0x0, 0x0, - 0x0, 0x0, 0x59, 0x0, 0xc, 0x10, 0x0, 0x20, - 0x0, 0x0, 0xb2, 0x0, 0xc, 0x10, 0x0, 0x60, - 0x0, 0x3, 0xa0, 0x0, 0xc, 0x10, 0x0, 0x80, - 0x0, 0x1b, 0x10, 0x0, 0xc, 0x20, 0x1, 0xe1, - 0x2, 0x81, 0x0, 0x0, 0x6, 0xed, 0xde, 0xc1, - 0x4, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - - /* U+5143 "元" */ - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x20, 0x0, - 0x0, 0x5, 0x76, 0x66, 0x66, 0x69, 0xb1, 0x0, - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x3, 0x0, - 0x3, 0x76, 0x66, 0x86, 0x68, 0x66, 0x7c, 0x40, - 0x0, 0x0, 0x4, 0xb0, 0xf, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x6, 0x90, 0xf, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x8, 0x60, 0xf, 0x0, 0x0, 0x0, - 0x0, 0x0, 0xd, 0x30, 0xf, 0x0, 0x0, 0x10, - 0x0, 0x0, 0x2d, 0x0, 0xf, 0x0, 0x0, 0x60, - 0x0, 0x0, 0xb5, 0x0, 0xf, 0x0, 0x0, 0x80, - 0x0, 0x8, 0x80, 0x0, 0xe, 0x20, 0x4, 0xc0, - 0x0, 0x95, 0x0, 0x0, 0x8, 0xdd, 0xde, 0xa0, - 0x5, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - - /* U+5144 "兄" */ - 0x0, 0x40, 0x0, 0x0, 0x0, 0x51, 0x0, 0x0, - 0xe6, 0x66, 0x66, 0x66, 0xe4, 0x0, 0x0, 0xd1, - 0x0, 0x0, 0x0, 0xd1, 0x0, 0x0, 0xd1, 0x0, - 0x0, 0x0, 0xd1, 0x0, 0x0, 0xd1, 0x0, 0x0, - 0x0, 0xd1, 0x0, 0x0, 0xd1, 0x0, 0x0, 0x0, - 0xd1, 0x0, 0x0, 0xe6, 0x6d, 0x67, 0xc6, 0xe1, - 0x0, 0x0, 0x70, 0x2c, 0x3, 0xc0, 0x10, 0x0, - 0x0, 0x0, 0x5a, 0x3, 0xc0, 0x0, 0x0, 0x0, - 0x0, 0x87, 0x3, 0xc0, 0x0, 0x20, 0x0, 0x0, - 0xc3, 0x3, 0xc0, 0x0, 0x50, 0x0, 0x3, 0xc0, - 0x3, 0xc0, 0x0, 0x71, 0x0, 0x2c, 0x20, 0x2, - 0xc0, 0x0, 0xb7, 0x4, 0x91, 0x0, 0x0, 0xcd, - 0xdd, 0xf8, 0x43, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, - - /* U+5145 "充" */ - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, 0xa, 0x20, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x5b, 0x0, 0x0, 0x30, 0x6, 0x76, - 0x66, 0x68, 0x96, 0x66, 0x6b, 0x60, 0x0, 0x0, - 0x9, 0xd0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x6, - 0xb1, 0x2, 0x50, 0x0, 0x0, 0x0, 0x6, 0x80, - 0x0, 0x3, 0xb3, 0x0, 0x0, 0xc, 0xb8, 0x88, - 0x87, 0x68, 0xf4, 0x0, 0x0, 0x65, 0x6c, 0x10, - 0xe0, 0x8, 0x80, 0x0, 0x0, 0x5, 0x90, 0xe, - 0x0, 0x0, 0x0, 0x0, 0x0, 0x86, 0x0, 0xe0, - 0x0, 0x0, 0x0, 0x0, 0xe, 0x10, 0xe, 0x0, - 0x0, 0x60, 0x0, 0x5, 0x90, 0x0, 0xe0, 0x0, - 0x8, 0x0, 0x4, 0xa0, 0x0, 0xe, 0x0, 0x2, - 0xc0, 0x6, 0x60, 0x0, 0x0, 0x9d, 0xdd, 0xea, - 0x3, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - - /* U+5148 "先" */ - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x0, 0x95, 0x0, 0x0, 0x0, 0x0, - 0x3, 0x90, 0xa, 0x30, 0x0, 0x0, 0x0, 0x0, - 0x89, 0x0, 0xa3, 0x0, 0x10, 0x0, 0x0, 0xd, - 0x86, 0x6c, 0x86, 0x6b, 0xa0, 0x0, 0x4, 0x90, - 0x0, 0xa3, 0x0, 0x0, 0x0, 0x0, 0x90, 0x0, - 0xa, 0x30, 0x0, 0x0, 0x0, 0x11, 0x0, 0x0, - 0xa3, 0x0, 0x0, 0x50, 0x7, 0x66, 0x69, 0x88, - 0x89, 0x66, 0x7a, 0x30, 0x0, 0x0, 0x95, 0x4, - 0x90, 0x0, 0x0, 0x0, 0x0, 0xc, 0x20, 0x49, - 0x0, 0x0, 0x0, 0x0, 0x1, 0xd0, 0x4, 0x90, - 0x0, 0x40, 0x0, 0x0, 0x85, 0x0, 0x49, 0x0, - 0x6, 0x10, 0x0, 0x5a, 0x0, 0x4, 0xa0, 0x0, - 0x85, 0x1, 0x86, 0x0, 0x0, 0xc, 0xcc, 0xcd, - 0x60, 0x40, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - - /* U+5149 "光" */ - 0x0, 0x0, 0x0, 0x3, 0x80, 0x0, 0x0, 0x0, - 0x0, 0x1, 0x0, 0x4, 0xa0, 0x0, 0x0, 0x0, - 0x0, 0x1, 0x90, 0x3, 0xa0, 0x8, 0xa0, 0x0, - 0x0, 0x0, 0x6c, 0x3, 0xa0, 0xe, 0x20, 0x0, - 0x0, 0x0, 0xe, 0x13, 0xa0, 0x66, 0x0, 0x0, - 0x0, 0x0, 0x3, 0x3, 0xa0, 0x80, 0x3, 0x20, - 0x5, 0x76, 0x67, 0xa6, 0x8b, 0x66, 0x69, 0x80, - 0x0, 0x0, 0x3, 0xa0, 0xd, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x5, 0x90, 0xd, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x8, 0x50, 0xd, 0x0, 0x0, 0x0, - 0x0, 0x0, 0xd, 0x10, 0xd, 0x0, 0x0, 0x50, - 0x0, 0x0, 0x59, 0x0, 0xd, 0x0, 0x0, 0x70, - 0x0, 0x3, 0xa0, 0x0, 0xc, 0x10, 0x0, 0xd1, - 0x0, 0x67, 0x0, 0x0, 0x6, 0xdc, 0xcd, 0xc1, - 0x4, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - - /* U+514B "克" */ - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x0, 0xe2, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, 0xd, 0x0, 0x0, 0x31, 0x3, 0x76, - 0x66, 0x66, 0xd6, 0x66, 0x6a, 0x80, 0x0, 0x0, - 0x0, 0x1b, 0x0, 0x0, 0x0, 0x0, 0x0, 0xa6, - 0x67, 0xc6, 0x6c, 0x40, 0x0, 0x0, 0xd, 0x0, - 0x0, 0x0, 0xc0, 0x0, 0x0, 0x0, 0xd0, 0x0, - 0x0, 0xc, 0x0, 0x0, 0x0, 0xd, 0x0, 0x0, - 0x0, 0xc0, 0x0, 0x0, 0x0, 0xe6, 0x88, 0x6a, - 0x6d, 0x10, 0x0, 0x0, 0x6, 0x9, 0x50, 0xb0, - 0x20, 0x0, 0x0, 0x0, 0x0, 0xd1, 0xb, 0x0, - 0x0, 0x20, 0x0, 0x0, 0x4a, 0x0, 0xb0, 0x0, - 0x6, 0x0, 0x0, 0x2c, 0x10, 0xb, 0x0, 0x1, - 0xa0, 0x2, 0x77, 0x0, 0x0, 0x9b, 0xbb, 0xdc, - 0x13, 0x30, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - - /* U+514D "免" */ - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, 0xd, 0x50, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x4d, 0x0, 0x3, 0x0, 0x0, 0x0, - 0x0, 0x0, 0xd8, 0x66, 0x6e, 0x80, 0x0, 0x0, - 0x0, 0x7, 0x80, 0x0, 0x3a, 0x0, 0x0, 0x0, - 0x0, 0x3d, 0x0, 0x0, 0x80, 0x0, 0x60, 0x0, - 0x2, 0xab, 0x86, 0x6c, 0xa6, 0x66, 0xf2, 0x0, - 0x5, 0xa, 0x30, 0xa, 0x60, 0x0, 0xe0, 0x0, - 0x0, 0xa, 0x30, 0xc, 0x40, 0x0, 0xe0, 0x0, - 0x0, 0xb, 0x86, 0x6f, 0x8a, 0x66, 0xe0, 0x0, - 0x0, 0x3, 0x0, 0x2e, 0x3b, 0x0, 0x10, 0x0, - 0x0, 0x0, 0x0, 0x88, 0x3b, 0x0, 0x0, 0x60, - 0x0, 0x0, 0x3, 0xe1, 0x3b, 0x0, 0x0, 0x80, - 0x0, 0x0, 0x4d, 0x30, 0x2b, 0x0, 0x3, 0xc0, - 0x0, 0x39, 0x70, 0x0, 0xe, 0xcc, 0xce, 0xb1, - 0x4, 0x30, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - - /* U+5152 "兒" */ - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x8a, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x85, 0x74, 0x14, 0x76, 0x6e, 0x10, 0x0, 0xd, - 0x10, 0x0, 0x0, 0x0, 0xe0, 0x0, 0x0, 0xd1, - 0x5, 0x0, 0x0, 0xe, 0x0, 0x0, 0xd, 0x66, - 0x82, 0x18, 0x66, 0xe0, 0x0, 0x0, 0xd1, 0x0, - 0x0, 0x0, 0xe, 0x0, 0x0, 0xd, 0x10, 0x0, - 0x0, 0x0, 0xe0, 0x0, 0x0, 0xd6, 0x7d, 0x66, - 0xe6, 0x6c, 0x0, 0x0, 0x1, 0x3, 0xa0, 0xe, - 0x0, 0x0, 0x0, 0x0, 0x0, 0x67, 0x0, 0xe0, - 0x0, 0x0, 0x0, 0x0, 0xc, 0x10, 0xe, 0x0, - 0x0, 0x50, 0x0, 0x4, 0xa0, 0x0, 0xe0, 0x0, - 0x8, 0x0, 0x3, 0xa0, 0x0, 0xf, 0x21, 0x15, - 0xe1, 0x6, 0x70, 0x0, 0x0, 0x7a, 0xbb, 0xa7, - 0x3, 0x10, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - - /* U+515A "党" */ - 0x0, 0x0, 0x0, 0xa, 0x20, 0x0, 0x0, 0x0, - 0x0, 0x19, 0x30, 0xd0, 0xb, 0x80, 0x0, 0x0, - 0x0, 0x2f, 0xd, 0x3, 0xb0, 0x0, 0x0, 0x4, - 0x0, 0x40, 0xd0, 0x80, 0x0, 0x60, 0x2, 0xb6, - 0x66, 0x66, 0x66, 0x66, 0x8d, 0x40, 0xd5, 0x3, - 0x0, 0x0, 0x4, 0x5, 0x0, 0x1, 0x0, 0xc6, - 0x66, 0x66, 0xe3, 0x0, 0x0, 0x0, 0xb, 0x10, - 0x0, 0xd, 0x0, 0x0, 0x0, 0x0, 0xb6, 0x66, - 0x66, 0xe0, 0x0, 0x0, 0x0, 0x9, 0x1c, 0xb, - 0x15, 0x0, 0x0, 0x0, 0x0, 0x4, 0x90, 0xb1, - 0x0, 0x3, 0x0, 0x0, 0x0, 0xb2, 0xb, 0x10, - 0x0, 0x61, 0x0, 0x0, 0x88, 0x0, 0xb1, 0x0, - 0x7, 0x60, 0x16, 0x83, 0x0, 0x6, 0xdc, 0xcc, - 0xe7, 0x23, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, - - /* U+5165 "入" */ - 0x0, 0x0, 0x15, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x6, 0xc4, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x0, 0xc, 0x10, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x0, 0xb, 0x70, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x0, 0xf, 0xb0, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x0, 0x4b, 0x92, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x0, 0xa5, 0x49, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x2, 0xd0, 0xd, 0x10, 0x0, 0x0, - 0x0, 0x0, 0xa, 0x40, 0x6, 0xb0, 0x0, 0x0, - 0x0, 0x0, 0x4b, 0x0, 0x0, 0xd6, 0x0, 0x0, - 0x0, 0x1, 0xc1, 0x0, 0x0, 0x3f, 0x40, 0x0, - 0x0, 0x1a, 0x10, 0x0, 0x0, 0x6, 0xf7, 0x0, - 0x1, 0x91, 0x0, 0x0, 0x0, 0x0, 0x7f, 0xc1, - 0x26, 0x0, 0x0, 0x0, 0x0, 0x0, 0x4, 0x0, - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - - /* U+5167 "內" */ - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0xc1, 0x0, 0x0, 0x0, 0x0, 0x0, 0xa, - 0x10, 0x0, 0x0, 0x1, 0x0, 0x0, 0x64, 0x0, - 0x0, 0x20, 0xa7, 0x66, 0x68, 0xb6, 0x66, 0x7e, - 0xa, 0x30, 0x0, 0x4d, 0x0, 0x2, 0xc0, 0xa3, - 0x0, 0x8, 0xc3, 0x0, 0x2c, 0xa, 0x30, 0x0, - 0xc2, 0x90, 0x2, 0xc0, 0xa3, 0x0, 0x57, 0xb, - 0x20, 0x2c, 0xa, 0x30, 0xb, 0x0, 0x5c, 0x2, - 0xc0, 0xa3, 0x8, 0x10, 0x0, 0xbb, 0x3c, 0xa, - 0x36, 0x20, 0x0, 0x1, 0xa5, 0xc0, 0xa3, 0x10, - 0x0, 0x0, 0x0, 0x2b, 0xa, 0x30, 0x0, 0x0, - 0x1, 0x13, 0xb0, 0xa2, 0x0, 0x0, 0x0, 0x28, - 0xf7, 0x0, 0x0, 0x0, 0x0, 0x0, 0x2, 0x0, - - /* U+5168 "全" */ - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x0, 0x4d, 0x10, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x0, 0xc9, 0x40, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x6, 0xb0, 0x62, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x2d, 0x10, 0xb, 0x20, 0x0, 0x0, - 0x0, 0x1, 0xc3, 0x0, 0x0, 0xb6, 0x0, 0x0, - 0x0, 0x1b, 0x30, 0x0, 0x0, 0x4e, 0xd7, 0x30, - 0x3, 0x95, 0x76, 0x6d, 0x76, 0x65, 0x5d, 0x60, - 0x23, 0x0, 0x0, 0xb, 0x20, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x0, 0xb, 0x20, 0x1, 0x0, 0x0, - 0x0, 0x7, 0x76, 0x6d, 0x76, 0x6c, 0x30, 0x0, - 0x0, 0x0, 0x0, 0xb, 0x20, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x0, 0xb, 0x20, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x0, 0xb, 0x20, 0x0, 0x2, 0x0, - 0x4, 0x66, 0x66, 0x6d, 0x76, 0x66, 0x8f, 0x30, - 0x1, 0x10, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - - /* U+5169 "兩" */ - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x82, 0x5, - 0x76, 0x66, 0x6a, 0x76, 0x66, 0x69, 0x70, 0x0, - 0x0, 0x0, 0xa2, 0x0, 0x0, 0x0, 0x0, 0x20, - 0x0, 0xa, 0x20, 0x0, 0x2, 0x0, 0xe, 0x66, - 0x66, 0xc7, 0x66, 0x66, 0xe2, 0x0, 0xd0, 0x20, - 0xa, 0x22, 0x0, 0xd, 0x0, 0xd, 0x6, 0x10, - 0xa2, 0x16, 0x0, 0xd0, 0x0, 0xd0, 0xb, 0xa, - 0x20, 0x75, 0xd, 0x0, 0xd, 0x2, 0xe7, 0xa2, - 0xa, 0xd1, 0xd0, 0x0, 0xd0, 0x92, 0xea, 0x22, - 0x87, 0x9d, 0x0, 0xd, 0x35, 0xb, 0xb2, 0x80, - 0x2b, 0xd0, 0x0, 0xd5, 0x0, 0x1a, 0x60, 0x0, - 0x2d, 0x0, 0xd, 0x0, 0x0, 0xa2, 0x0, 0x0, - 0xe0, 0x0, 0xd0, 0x0, 0xa, 0x20, 0x16, 0xec, - 0x0, 0x2, 0x0, 0x0, 0x20, 0x0, 0x3, 0x10, - 0x0, - - /* U+516B "八" */ - 0x0, 0x0, 0x0, 0x0, 0x6, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x3, 0x60, 0x9, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x6, 0xc0, 0x9, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x7, 0x80, 0xa, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x8, 0x60, 0x8, 0x10, 0x0, 0x0, - 0x0, 0x0, 0xa, 0x30, 0x5, 0x50, 0x0, 0x0, - 0x0, 0x0, 0xd, 0x10, 0x2, 0x90, 0x0, 0x0, - 0x0, 0x0, 0x1d, 0x0, 0x0, 0xc0, 0x0, 0x0, - 0x0, 0x0, 0x68, 0x0, 0x0, 0x84, 0x0, 0x0, - 0x0, 0x0, 0xb2, 0x0, 0x0, 0x2c, 0x0, 0x0, - 0x0, 0x2, 0xa0, 0x0, 0x0, 0xb, 0x70, 0x0, - 0x0, 0xa, 0x10, 0x0, 0x0, 0x2, 0xf5, 0x0, - 0x0, 0x64, 0x0, 0x0, 0x0, 0x0, 0x6f, 0x70, - 0x4, 0x50, 0x0, 0x0, 0x0, 0x0, 0x8, 0x71, - 0x3, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - - /* U+516C "公" */ - 0x0, 0x0, 0x12, 0x0, 0x90, 0x0, 0x0, 0x0, - 0x0, 0x5, 0xe1, 0x9, 0x0, 0x0, 0x0, 0x0, - 0x0, 0xb5, 0x0, 0x73, 0x0, 0x0, 0x0, 0x0, - 0x3c, 0x0, 0x1, 0xb0, 0x0, 0x0, 0x0, 0xb, - 0x20, 0x0, 0x8, 0x70, 0x0, 0x0, 0x7, 0x60, - 0x2, 0x0, 0xc, 0x50, 0x0, 0x4, 0x70, 0x0, - 0xba, 0x0, 0x2e, 0x81, 0x3, 0x60, 0x0, 0x2e, - 0x10, 0x0, 0x2d, 0x70, 0x20, 0x0, 0xb, 0x40, - 0x0, 0x0, 0x0, 0x0, 0x0, 0x5, 0x80, 0x3, - 0x0, 0x0, 0x0, 0x0, 0x2, 0xb0, 0x0, 0x1a, - 0x0, 0x0, 0x0, 0x0, 0xa1, 0x0, 0x0, 0x4c, - 0x0, 0x0, 0x1, 0xd8, 0x77, 0x77, 0x65, 0xc9, - 0x0, 0x0, 0xa, 0x64, 0x20, 0x0, 0x4, 0xd0, - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x1, 0x0, - 0x0, - - /* U+516D "六" */ - 0x0, 0x0, 0x0, 0x64, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x0, 0xd, 0x60, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x0, 0x7, 0xe0, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x0, 0x1, 0x70, 0x0, 0x2, 0x10, - 0x7, 0x66, 0x66, 0x66, 0x66, 0x66, 0x6c, 0xb0, - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x6, 0x70, 0x4, 0x0, 0x0, 0x0, - 0x0, 0x0, 0xd, 0x90, 0x2, 0x80, 0x0, 0x0, - 0x0, 0x0, 0x4e, 0x0, 0x0, 0x59, 0x0, 0x0, - 0x0, 0x0, 0xc5, 0x0, 0x0, 0xa, 0x80, 0x0, - 0x0, 0x6, 0x90, 0x0, 0x0, 0x1, 0xf6, 0x0, - 0x0, 0x2b, 0x0, 0x0, 0x0, 0x0, 0x8f, 0x0, - 0x0, 0xa1, 0x0, 0x0, 0x0, 0x0, 0x1f, 0x10, - 0x7, 0x0, 0x0, 0x0, 0x0, 0x0, 0x4, 0x0, - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - - /* U+5171 "共" */ - 0x0, 0x0, 0x8, 0x10, 0x0, 0x91, 0x0, 0x0, - 0x0, 0x0, 0xe, 0x0, 0x0, 0xe0, 0x0, 0x0, - 0x0, 0x0, 0xe, 0x0, 0x0, 0xe0, 0x2, 0x0, - 0x3, 0x76, 0x6e, 0x66, 0x66, 0xe6, 0x6b, 0x60, - 0x0, 0x0, 0xe, 0x0, 0x0, 0xe0, 0x0, 0x0, - 0x0, 0x0, 0xe, 0x0, 0x0, 0xe0, 0x0, 0x0, - 0x0, 0x0, 0xe, 0x0, 0x0, 0xe0, 0x0, 0x0, - 0x0, 0x0, 0xe, 0x0, 0x0, 0xe0, 0x0, 0x20, - 0x17, 0x66, 0x6d, 0x66, 0x66, 0xd6, 0x6b, 0xd2, - 0x1, 0x0, 0x4, 0x20, 0x1, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x1e, 0x90, 0x4, 0x82, 0x0, 0x0, - 0x0, 0x1, 0xc6, 0x0, 0x0, 0x1b, 0x91, 0x0, - 0x0, 0x1b, 0x40, 0x0, 0x0, 0x0, 0xae, 0x0, - 0x3, 0x81, 0x0, 0x0, 0x0, 0x0, 0xb, 0x20, - 0x13, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - - /* U+5176 "其" */ - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, 0xc, 0x10, 0x0, 0xd2, 0x0, 0x0, - 0x0, 0x0, 0xe, 0x0, 0x0, 0xe0, 0x4, 0x0, - 0x1, 0x86, 0x6e, 0x66, 0x66, 0xe6, 0x7a, 0x30, - 0x0, 0x0, 0xe, 0x0, 0x0, 0xe0, 0x0, 0x0, - 0x0, 0x0, 0xe, 0x66, 0x66, 0xe0, 0x0, 0x0, - 0x0, 0x0, 0xe, 0x0, 0x0, 0xe0, 0x0, 0x0, - 0x0, 0x0, 0xe, 0x0, 0x0, 0xe0, 0x0, 0x0, - 0x0, 0x0, 0xe, 0x66, 0x66, 0xe0, 0x0, 0x0, - 0x0, 0x0, 0xe, 0x0, 0x0, 0xe0, 0x1, 0x0, - 0x5, 0x66, 0x6e, 0x66, 0x66, 0xe6, 0x6d, 0xc1, - 0x1, 0x0, 0x5, 0x40, 0x2, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x4e, 0x80, 0x0, 0x97, 0x0, 0x0, - 0x0, 0x6, 0xc2, 0x0, 0x0, 0x9, 0xe4, 0x0, - 0x1, 0x86, 0x0, 0x0, 0x0, 0x0, 0x8d, 0x0, - 0x2, 0x0, 0x0, 0x0, 0x0, 0x0, 0x3, 0x0, - - /* U+5177 "具" */ - 0x0, 0x0, 0x86, 0x66, 0x66, 0x6b, 0x10, 0x0, - 0x0, 0x0, 0xb1, 0x0, 0x0, 0x1c, 0x0, 0x0, - 0x0, 0x0, 0xb1, 0x0, 0x0, 0x1c, 0x0, 0x0, - 0x0, 0x0, 0xb6, 0x66, 0x66, 0x6c, 0x0, 0x0, - 0x0, 0x0, 0xb1, 0x0, 0x0, 0x1c, 0x0, 0x0, - 0x0, 0x0, 0xb6, 0x66, 0x66, 0x6c, 0x0, 0x0, - 0x0, 0x0, 0xb1, 0x0, 0x0, 0x1c, 0x0, 0x0, - 0x0, 0x0, 0xb6, 0x66, 0x66, 0x6c, 0x0, 0x0, - 0x0, 0x0, 0xb1, 0x0, 0x0, 0x1c, 0x0, 0x0, - 0x0, 0x0, 0xb1, 0x0, 0x0, 0x1c, 0xb, 0x40, - 0x7, 0x66, 0x68, 0x66, 0x66, 0x66, 0x66, 0x50, - 0x0, 0x0, 0x5e, 0x20, 0x0, 0x66, 0x0, 0x0, - 0x0, 0x8, 0xa1, 0x0, 0x0, 0x5, 0xd4, 0x0, - 0x2, 0x94, 0x0, 0x0, 0x0, 0x0, 0x3f, 0x0, - 0x13, 0x0, 0x0, 0x0, 0x0, 0x0, 0x2, 0x0, - - /* U+5185 "内" */ - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x2d, 0x20, 0x0, 0x0, 0x0, 0x0, 0x2, - 0xd0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x2d, 0x0, - 0x0, 0x0, 0x39, 0x66, 0x67, 0xe6, 0x66, 0x7d, - 0x2, 0xb0, 0x0, 0x3b, 0x0, 0x3, 0xb0, 0x2b, - 0x0, 0x6, 0x90, 0x0, 0x3b, 0x2, 0xb0, 0x0, - 0xb9, 0x20, 0x3, 0xb0, 0x2b, 0x0, 0x2c, 0xb, - 0x70, 0x3b, 0x2, 0xb0, 0xb, 0x20, 0xc, 0x93, - 0xb0, 0x2b, 0x19, 0x20, 0x0, 0x2e, 0x3b, 0x2, - 0xd6, 0x0, 0x0, 0x0, 0x33, 0xb0, 0x2b, 0x0, - 0x0, 0x0, 0x0, 0x3b, 0x2, 0xb0, 0x0, 0x0, - 0x2, 0x15, 0xa0, 0x2b, 0x0, 0x0, 0x0, 0x39, - 0xf6, 0x1, 0x30, 0x0, 0x0, 0x0, 0x4, 0x0, - - /* U+5186 "円" */ - 0x10, 0x0, 0x0, 0x0, 0x0, 0x2, 0xd, 0x66, - 0x66, 0xa6, 0x66, 0x68, 0xe0, 0xd1, 0x0, 0xd, - 0x0, 0x0, 0x3a, 0xc, 0x10, 0x0, 0xd0, 0x0, - 0x3, 0xa0, 0xc1, 0x0, 0xd, 0x0, 0x0, 0x3a, - 0xc, 0x10, 0x0, 0xd0, 0x0, 0x3, 0xa0, 0xc6, - 0x66, 0x6e, 0x66, 0x66, 0x8a, 0xc, 0x10, 0x0, - 0x0, 0x0, 0x3, 0xa0, 0xc1, 0x0, 0x0, 0x0, - 0x0, 0x3a, 0xc, 0x10, 0x0, 0x0, 0x0, 0x3, - 0xa0, 0xc1, 0x0, 0x0, 0x0, 0x0, 0x3a, 0xc, - 0x10, 0x0, 0x0, 0x0, 0x3, 0xa0, 0xd1, 0x0, - 0x0, 0x0, 0x0, 0x4a, 0xd, 0x10, 0x0, 0x0, - 0x5, 0xaf, 0x70, 0x10, 0x0, 0x0, 0x0, 0x0, - 0x40, 0x0, - - /* U+518A "冊" */ - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0xc, 0x66, 0x96, 0x69, 0x66, 0xe3, 0x0, - 0x0, 0xd, 0x0, 0xd0, 0xd, 0x0, 0xd0, 0x0, - 0x0, 0xd, 0x0, 0xd0, 0xd, 0x0, 0xd0, 0x0, - 0x0, 0xd, 0x0, 0xd0, 0xd, 0x0, 0xd0, 0x0, - 0x0, 0xd, 0x0, 0xd0, 0xd, 0x0, 0xd0, 0x0, - 0x0, 0xd, 0x0, 0xd0, 0xd, 0x0, 0xd6, 0x40, - 0x7, 0x6e, 0x66, 0xe6, 0x6e, 0x66, 0xe6, 0x60, - 0x0, 0xd, 0x0, 0xd0, 0xd, 0x0, 0xd0, 0x0, - 0x0, 0xd, 0x0, 0xd0, 0xd, 0x0, 0xd0, 0x0, - 0x0, 0xd, 0x0, 0xd0, 0xd, 0x0, 0xd0, 0x0, - 0x0, 0xd, 0x0, 0xd0, 0xd, 0x0, 0xd0, 0x0, - 0x0, 0xd, 0x0, 0xc0, 0xc, 0x0, 0xd0, 0x0, - 0x0, 0xd, 0x0, 0x10, 0x0, 0x6b, 0xd0, 0x0, - 0x0, 0x3, 0x0, 0x0, 0x0, 0x3, 0x20, 0x0, - - /* U+518D "再" */ - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x82, 0x0, - 0x28, 0x66, 0x66, 0xc6, 0x66, 0x68, 0x60, 0x0, - 0x0, 0x0, 0xd, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x86, 0x66, 0xe6, 0x66, 0xb4, 0x0, 0x0, 0xd, - 0x10, 0xd, 0x0, 0xc, 0x20, 0x0, 0x0, 0xc1, - 0x0, 0xd0, 0x0, 0xc1, 0x0, 0x0, 0xc, 0x66, - 0x6e, 0x66, 0x6d, 0x10, 0x0, 0x0, 0xc1, 0x0, - 0xd0, 0x0, 0xc1, 0x0, 0x0, 0xc, 0x10, 0xd, - 0x0, 0xc, 0x11, 0x1, 0x66, 0xd6, 0x66, 0xe6, - 0x66, 0xd7, 0xf6, 0x2, 0xc, 0x10, 0x0, 0x0, - 0xc, 0x10, 0x0, 0x0, 0xc1, 0x0, 0x0, 0x0, - 0xc1, 0x0, 0x0, 0xc, 0x10, 0x0, 0x0, 0xc, - 0x10, 0x0, 0x0, 0xd1, 0x0, 0x1, 0x7d, 0xf0, - 0x0, 0x0, 0x4, 0x0, 0x0, 0x0, 0x33, 0x0, - 0x0, - - /* U+5199 "写" */ - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x4, - 0x20, 0x0, 0x0, 0x0, 0x0, 0x91, 0x8, 0x86, - 0x66, 0x66, 0x66, 0x66, 0xf6, 0xe, 0x32, 0x30, - 0x0, 0x0, 0x6, 0x30, 0x25, 0x5, 0xb0, 0x0, - 0x0, 0x2, 0x0, 0x0, 0x7, 0xa6, 0x66, 0x66, - 0x7d, 0x20, 0x0, 0xa, 0x40, 0x0, 0x0, 0x0, - 0x0, 0x0, 0xd, 0x10, 0x0, 0x0, 0x0, 0x10, - 0x0, 0x2f, 0x66, 0x66, 0x66, 0x68, 0xc0, 0x0, - 0x1, 0x0, 0x0, 0x0, 0x5, 0x80, 0x0, 0x0, - 0x0, 0x0, 0x3, 0x7, 0x60, 0x57, 0x66, 0x66, - 0x66, 0x8b, 0x29, 0x40, 0x0, 0x0, 0x0, 0x0, - 0x0, 0xc, 0x20, 0x0, 0x0, 0x0, 0x0, 0x31, - 0x3e, 0x0, 0x0, 0x0, 0x0, 0x0, 0x3b, 0xf7, - 0x0, 0x0, 0x0, 0x0, 0x0, 0x1, 0x30, 0x0, - - /* U+519B "军" */ - 0x5, 0x0, 0x0, 0x0, 0x0, 0x0, 0x91, 0x0, - 0xb6, 0x66, 0x66, 0x66, 0x66, 0x6e, 0x60, 0x5c, - 0x0, 0x6, 0xb0, 0x0, 0x4, 0x10, 0x0, 0x0, - 0x0, 0xd2, 0x0, 0x0, 0x40, 0x0, 0x1, 0x66, - 0x9b, 0x66, 0x66, 0x67, 0x0, 0x0, 0x0, 0xc, - 0x10, 0x80, 0x0, 0x0, 0x0, 0x0, 0x7, 0x60, - 0xd, 0x0, 0x0, 0x0, 0x0, 0x3, 0xb0, 0x0, - 0xd0, 0x3, 0x50, 0x0, 0x0, 0x56, 0x66, 0x6e, - 0x66, 0x65, 0x0, 0x0, 0x0, 0x0, 0x0, 0xd0, - 0x0, 0x0, 0x0, 0x67, 0x66, 0x66, 0x6e, 0x66, - 0x66, 0xa9, 0x0, 0x0, 0x0, 0x0, 0xd0, 0x0, - 0x0, 0x0, 0x0, 0x0, 0x0, 0xd, 0x0, 0x0, - 0x0, 0x0, 0x0, 0x0, 0x0, 0xd0, 0x0, 0x0, - 0x0, 0x0, 0x0, 0x0, 0x6, 0x0, 0x0, 0x0, - 0x0, - - /* U+51AC "冬" */ - 0x0, 0x0, 0x3a, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0xa, 0x80, 0x0, 0x3, 0x0, 0x0, 0x0, - 0x3, 0xd6, 0x66, 0x6a, 0xe1, 0x0, 0x0, 0x0, - 0xb6, 0x30, 0x2, 0xe3, 0x0, 0x0, 0x0, 0x74, - 0x8, 0x21, 0xc4, 0x0, 0x0, 0x0, 0x54, 0x0, - 0xb, 0xc4, 0x0, 0x0, 0x0, 0x12, 0x0, 0x4, - 0xcc, 0x80, 0x0, 0x0, 0x0, 0x0, 0x19, 0x91, - 0x8, 0xd7, 0x10, 0x0, 0x1, 0x78, 0x21, 0x73, - 0x3, 0xaf, 0xb7, 0x5, 0x50, 0x0, 0x1, 0xca, - 0x0, 0x28, 0x10, 0x0, 0x0, 0x0, 0x0, 0x90, - 0x0, 0x0, 0x0, 0x0, 0x27, 0x97, 0x30, 0x0, - 0x0, 0x0, 0x0, 0x0, 0x0, 0x4d, 0xd2, 0x0, - 0x0, 0x0, 0x0, 0x0, 0x0, 0x9, 0xb0, 0x0, - 0x0, 0x0, 0x0, 0x0, 0x0, 0x1, 0x0, 0x0, - 0x0, - - /* U+51B7 "冷" */ - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x0, 0x0, 0x5c, 0x10, 0x0, 0x0, - 0x6, 0x10, 0x0, 0x0, 0xac, 0x10, 0x0, 0x0, - 0x2, 0xe2, 0x2, 0x0, 0xe1, 0x80, 0x0, 0x0, - 0x0, 0xa7, 0x5, 0x7, 0x80, 0x74, 0x0, 0x0, - 0x0, 0x20, 0x41, 0xc, 0x30, 0xc, 0x30, 0x0, - 0x0, 0x0, 0x70, 0x93, 0x1c, 0x12, 0xe7, 0x0, - 0x0, 0x3, 0x46, 0x40, 0x9, 0x70, 0x3e, 0xb2, - 0x0, 0xa, 0x42, 0x0, 0x1, 0x11, 0x21, 0x0, - 0x0, 0x69, 0x0, 0x76, 0x66, 0x6c, 0xc0, 0x0, - 0x7, 0xf4, 0x0, 0x0, 0x0, 0x2c, 0x10, 0x0, - 0x0, 0xd1, 0x0, 0x2, 0x10, 0x92, 0x0, 0x0, - 0x1, 0xf1, 0x0, 0x0, 0x99, 0x30, 0x0, 0x0, - 0x1, 0xe0, 0x0, 0x0, 0xd, 0x80, 0x0, 0x0, - 0x0, 0x0, 0x0, 0x0, 0x4, 0xc0, 0x0, 0x0, - 0x0, 0x0, 0x0, 0x0, 0x0, 0x10, 0x0, 0x0, - - /* U+51CD "凍" */ - 0x0, 0x0, 0x0, 0x0, 0xa4, 0x0, 0x0, 0x2, - 0x70, 0x0, 0x0, 0xb, 0x10, 0x2, 0x20, 0x7, - 0xc0, 0x76, 0x66, 0xd6, 0x66, 0x87, 0x0, 0xb, - 0x10, 0x30, 0xb, 0x10, 0x3, 0x0, 0x0, 0x5, - 0xe, 0x66, 0xd6, 0x66, 0xe0, 0x0, 0x0, 0x50, - 0xd0, 0xb, 0x10, 0xd, 0x0, 0x0, 0x42, 0xd, - 0x66, 0xd6, 0x66, 0xd0, 0x0, 0x9, 0x0, 0xd0, - 0xb, 0x10, 0xd, 0x0, 0x15, 0x90, 0xe, 0x69, - 0xe9, 0x66, 0xc0, 0x4, 0xe5, 0x0, 0x21, 0xcb, - 0x71, 0x0, 0x0, 0xa, 0x30, 0x0, 0x94, 0xb2, - 0x90, 0x0, 0x0, 0xd3, 0x0, 0x57, 0xb, 0x15, - 0x80, 0x0, 0xf, 0x30, 0x47, 0x0, 0xb1, 0x9, - 0xb2, 0x0, 0x41, 0x34, 0x0, 0xb, 0x10, 0x9, - 0x80, 0x0, 0x1, 0x0, 0x0, 0x50, 0x0, 0x0, - 0x0, - - /* U+51DD "凝" */ - 0x0, 0x0, 0xc, 0x11, 0x0, 0x0, 0x5, 0x10, - 0x6, 0x70, 0xc, 0x1b, 0x31, 0x76, 0x6e, 0x50, - 0x0, 0xd5, 0xc, 0x50, 0x30, 0x3, 0x53, 0x0, - 0x0, 0x41, 0x3c, 0x0, 0x90, 0x6, 0xb0, 0x0, - 0x0, 0x2, 0x28, 0xaa, 0x91, 0x0, 0xc0, 0x0, - 0x0, 0x6, 0xb, 0x20, 0x5, 0x76, 0x86, 0xc5, - 0x0, 0x7, 0x1c, 0x2, 0x40, 0x1, 0xb0, 0x80, - 0x0, 0x45, 0x76, 0xb7, 0x50, 0x91, 0xb0, 0x0, - 0x5, 0xd1, 0x40, 0x92, 0x10, 0xc1, 0xc6, 0xc1, - 0x3, 0xe1, 0x86, 0xb7, 0xb4, 0xc1, 0xb0, 0x0, - 0x2, 0xc0, 0x0, 0xc2, 0x0, 0xd1, 0xb0, 0x0, - 0x6, 0xb0, 0x2, 0xa8, 0x64, 0x88, 0xb0, 0x0, - 0x3, 0x70, 0xa, 0x11, 0xa8, 0x12, 0xc5, 0x10, - 0x0, 0x0, 0x72, 0x0, 0x26, 0x0, 0x19, 0xf5, - 0x0, 0x1, 0x0, 0x0, 0x20, 0x0, 0x0, 0x0, - - /* U+51E6 "処" */ - 0x0, 0x4, 0xa0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x7, 0x80, 0x0, 0x2, 0x0, 0x40, 0x0, - 0x0, 0xb, 0x20, 0x10, 0xe, 0x67, 0xd0, 0x0, - 0x0, 0xe, 0x66, 0xb8, 0xd, 0x2, 0xb0, 0x0, - 0x0, 0x67, 0x0, 0xa2, 0xc, 0x2, 0xb0, 0x0, - 0x0, 0xb3, 0x0, 0xc0, 0x1b, 0x2, 0xb0, 0x0, - 0x4, 0x55, 0x1, 0xb0, 0x39, 0x2, 0xb0, 0x0, - 0x7, 0x6, 0x15, 0x70, 0x74, 0x2, 0xb0, 0x0, - 0x0, 0x1, 0x7b, 0x20, 0xb0, 0x2, 0xb0, 0x40, - 0x0, 0x0, 0x9b, 0x7, 0x40, 0x2, 0xb0, 0x80, - 0x0, 0x0, 0xac, 0x34, 0x0, 0x0, 0xdb, 0xe3, - 0x0, 0x7, 0x53, 0xc4, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x56, 0x0, 0x2b, 0xd8, 0x53, 0x33, 0x42, - 0x6, 0x30, 0x0, 0x0, 0x27, 0xbd, 0xef, 0xb0, - 0x10, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - - /* U+51FA "出" */ - 0x0, 0x0, 0x0, 0x82, 0x0, 0x0, 0x0, 0x0, - 0x0, 0xe, 0x10, 0x0, 0x0, 0x4, 0x70, 0x0, - 0xe0, 0x0, 0xc, 0x10, 0x49, 0x0, 0xe, 0x0, - 0x0, 0xe0, 0x4, 0x90, 0x0, 0xe0, 0x0, 0xe, - 0x0, 0x49, 0x0, 0xe, 0x0, 0x0, 0xe0, 0x7, - 0xb6, 0x66, 0xe6, 0x66, 0x6e, 0x0, 0x1, 0x0, - 0xe, 0x0, 0x0, 0x60, 0x8, 0x20, 0x0, 0xe0, - 0x0, 0x4, 0x30, 0xc2, 0x0, 0xe, 0x0, 0x0, - 0x6a, 0xc, 0x10, 0x0, 0xe0, 0x0, 0x6, 0x80, - 0xc1, 0x0, 0xe, 0x0, 0x0, 0x68, 0xd, 0x10, - 0x0, 0xe0, 0x0, 0x6, 0x80, 0x96, 0x66, 0x66, - 0x66, 0x66, 0x98, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x1, 0x10, - - /* U+5206 "分" */ - 0x0, 0x0, 0x4, 0x0, 0x71, 0x0, 0x0, 0x0, - 0x0, 0x6, 0xd1, 0x5, 0x20, 0x0, 0x0, 0x0, - 0x0, 0xd4, 0x0, 0x18, 0x0, 0x0, 0x0, 0x0, - 0x6a, 0x0, 0x0, 0x82, 0x0, 0x0, 0x0, 0x1c, - 0x0, 0x0, 0x1, 0xc1, 0x0, 0x0, 0xb, 0x20, - 0x0, 0x0, 0x4, 0xe5, 0x0, 0x8, 0x46, 0x67, - 0x76, 0x66, 0xe4, 0xec, 0x25, 0x10, 0x0, 0x77, - 0x0, 0x2b, 0x0, 0x20, 0x0, 0x0, 0xa, 0x40, - 0x3, 0xb0, 0x0, 0x0, 0x0, 0x0, 0xd0, 0x0, - 0x4a, 0x0, 0x0, 0x0, 0x0, 0x58, 0x0, 0x5, - 0x90, 0x0, 0x0, 0x0, 0xc, 0x10, 0x0, 0x77, - 0x0, 0x0, 0x0, 0x9, 0x30, 0x0, 0xb, 0x40, - 0x0, 0x0, 0x28, 0x10, 0x0, 0x7f, 0xc0, 0x0, - 0x0, 0x13, 0x0, 0x0, 0x0, 0x40, 0x0, 0x0, - 0x0, - - /* U+5207 "切" */ - 0x0, 0x7, 0x10, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0xd2, 0x0, 0x0, 0x0, 0x0, 0x52, 0x0, - 0xc, 0x10, 0x28, 0x68, 0xd6, 0x6c, 0x60, 0x0, - 0xc1, 0x1, 0x10, 0x4b, 0x0, 0xb3, 0x0, 0xc, - 0x55, 0xa8, 0x5, 0xa0, 0xb, 0x31, 0x66, 0xd2, - 0x0, 0x0, 0x78, 0x0, 0xc3, 0x0, 0xc, 0x10, - 0x0, 0x9, 0x60, 0xc, 0x20, 0x0, 0xc1, 0x0, - 0x0, 0xc3, 0x0, 0xd1, 0x0, 0xc, 0x10, 0x2, - 0xe, 0x0, 0xe, 0x10, 0x0, 0xc1, 0x17, 0x16, - 0x90, 0x0, 0xe0, 0x0, 0xd, 0x79, 0x0, 0xd1, - 0x0, 0xe, 0x0, 0x0, 0xe9, 0x0, 0x87, 0x0, - 0x2, 0xd0, 0x0, 0x3, 0x0, 0x68, 0x0, 0x42, - 0x8a, 0x0, 0x0, 0x0, 0x65, 0x0, 0x2, 0xbf, - 0x30, 0x0, 0x0, 0x20, 0x0, 0x0, 0x1, 0x20, - 0x0, - - /* U+520A "刊" */ - 0x0, 0x0, 0x0, 0x3, 0x0, 0x0, 0xa, 0x20, - 0x67, 0x69, 0x66, 0xa3, 0x0, 0x0, 0xe0, 0x0, - 0x0, 0xb2, 0x0, 0x2, 0xb0, 0xe, 0x0, 0x0, - 0xb, 0x20, 0x0, 0x2c, 0x0, 0xe0, 0x0, 0x0, - 0xb2, 0x0, 0x2, 0xc0, 0xe, 0x0, 0x0, 0xb, - 0x20, 0x46, 0x2c, 0x0, 0xe0, 0x18, 0x66, 0xd7, - 0x66, 0x52, 0xc0, 0xe, 0x0, 0x0, 0xb, 0x20, - 0x0, 0x2c, 0x0, 0xe0, 0x0, 0x0, 0xb2, 0x0, - 0x2, 0xc0, 0xe, 0x0, 0x0, 0xb, 0x20, 0x0, - 0x2c, 0x0, 0xe0, 0x0, 0x0, 0xb2, 0x0, 0x2, - 0x60, 0xe, 0x0, 0x0, 0xb, 0x20, 0x0, 0x0, - 0x0, 0xe0, 0x0, 0x0, 0xb2, 0x0, 0x0, 0x24, - 0x4d, 0x0, 0x0, 0xc, 0x30, 0x0, 0x0, 0x5e, - 0x90, 0x0, 0x0, 0x20, 0x0, 0x0, 0x0, 0x20, - 0x0, - - /* U+5217 "列" */ - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x9, 0x20, - 0x36, 0x66, 0x66, 0x6e, 0x50, 0x0, 0xe0, 0x0, - 0x10, 0x98, 0x0, 0x0, 0x10, 0xe, 0x0, 0x0, - 0xd, 0x20, 0x0, 0xd, 0x20, 0xe0, 0x0, 0x3, - 0xe6, 0x6a, 0x50, 0xd0, 0xe, 0x0, 0x0, 0xa4, - 0x0, 0xd3, 0xd, 0x0, 0xe0, 0x0, 0x2d, 0x30, - 0x1d, 0x0, 0xd0, 0xe, 0x0, 0x9, 0x1c, 0x17, - 0x80, 0xd, 0x0, 0xe0, 0x5, 0x20, 0x95, 0xd2, - 0x0, 0xd0, 0xe, 0x0, 0x20, 0x2, 0x69, 0x0, - 0xd, 0x0, 0xe0, 0x0, 0x0, 0x1c, 0x0, 0x0, - 0xd0, 0xe, 0x0, 0x0, 0x1b, 0x20, 0x0, 0x1, - 0x0, 0xe0, 0x0, 0x2a, 0x20, 0x0, 0x0, 0x33, - 0x3f, 0x0, 0x46, 0x0, 0x0, 0x0, 0x0, 0x5f, - 0xb0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x30, - 0x0, - - /* U+521D "初" */ - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x5, 0x80, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, 0xd4, 0x0, 0x0, 0x0, 0x0, 0x10, - 0x0, 0x0, 0x33, 0x24, 0x68, 0x76, 0x66, 0xe3, - 0x6, 0x76, 0x6d, 0x70, 0x9, 0x40, 0x0, 0xe0, - 0x0, 0x0, 0x3b, 0x0, 0xa, 0x30, 0x0, 0xd0, - 0x0, 0x0, 0xc1, 0x46, 0xb, 0x20, 0x1, 0xc0, - 0x0, 0x9, 0xd0, 0xb2, 0xd, 0x0, 0x2, 0xb0, - 0x0, 0x65, 0xd9, 0x20, 0xd, 0x0, 0x3, 0xa0, - 0x5, 0x40, 0xd4, 0xd2, 0x2a, 0x0, 0x4, 0x90, - 0x1, 0x0, 0xd0, 0x54, 0x66, 0x0, 0x6, 0x80, - 0x0, 0x0, 0xd0, 0x0, 0xb0, 0x0, 0x7, 0x60, - 0x0, 0x0, 0xd0, 0x5, 0x60, 0x0, 0x9, 0x50, - 0x0, 0x0, 0xd0, 0x19, 0x0, 0x31, 0x1c, 0x20, - 0x0, 0x0, 0xe1, 0x70, 0x0, 0x3a, 0xfb, 0x0, - 0x0, 0x0, 0x41, 0x0, 0x0, 0x0, 0x40, 0x0, - - /* U+5224 "判" */ - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, 0xe2, 0x0, 0x0, 0x0, 0xb4, 0x0, - 0x20, 0xd, 0x0, 0x81, 0x0, 0xb, 0x10, 0x9, - 0x30, 0xd0, 0x3d, 0x21, 0x70, 0xb1, 0x0, 0x4e, - 0xd, 0xa, 0x10, 0x1b, 0xb, 0x10, 0x0, 0x90, - 0xd3, 0x30, 0x1, 0xb0, 0xb1, 0x1, 0x66, 0x6e, - 0x66, 0xd4, 0x1b, 0xb, 0x10, 0x2, 0x0, 0xc0, - 0x0, 0x1, 0xb0, 0xb1, 0x0, 0x0, 0xc, 0x0, - 0x0, 0x1b, 0xb, 0x10, 0x56, 0x67, 0xd6, 0x6b, - 0xb2, 0xb0, 0xb1, 0x1, 0x0, 0x67, 0x0, 0x0, - 0x1b, 0xb, 0x10, 0x0, 0xb, 0x10, 0x0, 0x2, - 0xc0, 0xb1, 0x0, 0x6, 0x70, 0x0, 0x0, 0x2, - 0xb, 0x10, 0x3, 0x80, 0x0, 0x0, 0x0, 0x21, - 0xc1, 0x4, 0x60, 0x0, 0x0, 0x0, 0x4, 0xdd, - 0x1, 0x10, 0x0, 0x0, 0x0, 0x0, 0x1, 0x10, - - /* U+5225 "別" */ - 0x0, 0x10, 0x0, 0x3, 0x0, 0x0, 0x6, 0x10, - 0xd, 0x66, 0x66, 0xd5, 0x0, 0x0, 0xc1, 0x0, - 0xd0, 0x0, 0xb, 0x10, 0x0, 0xc, 0x0, 0xd, - 0x0, 0x0, 0xb1, 0xc, 0x10, 0xc0, 0x0, 0xd6, - 0x66, 0x6d, 0x20, 0xd0, 0xc, 0x0, 0x8, 0x62, - 0x0, 0x50, 0xd, 0x0, 0xc0, 0x0, 0xc, 0x20, - 0x0, 0x0, 0xd0, 0xc, 0x0, 0x0, 0xc6, 0x66, - 0xa3, 0xd, 0x0, 0xc0, 0x0, 0xd, 0x0, 0xd, - 0x0, 0xd0, 0xc, 0x0, 0x1, 0xb0, 0x0, 0xe0, - 0xd, 0x0, 0xc0, 0x0, 0x66, 0x0, 0x2c, 0x0, - 0x70, 0xc, 0x0, 0xb, 0x0, 0x5, 0x90, 0x0, - 0x0, 0xc0, 0x4, 0x60, 0x22, 0xa5, 0x0, 0x1, - 0x2e, 0x0, 0x80, 0x0, 0xbc, 0x0, 0x1, 0x6e, - 0xc0, 0x20, 0x0, 0x1, 0x0, 0x0, 0x0, 0x21, - 0x0, - - /* U+5229 "利" */ - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x27, 0xe5, 0x0, 0x0, 0xc3, 0x2, - 0x56, 0x8f, 0x53, 0x10, 0x0, 0xc, 0x10, 0x0, - 0x0, 0xe0, 0x0, 0xb, 0x20, 0xc1, 0x0, 0x0, - 0xe, 0x0, 0x0, 0xd0, 0xc, 0x10, 0x56, 0x66, - 0xe6, 0x7e, 0x2d, 0x0, 0xc1, 0x1, 0x0, 0x3f, - 0x0, 0x0, 0xd0, 0xc, 0x10, 0x0, 0xa, 0xf4, - 0x0, 0xd, 0x0, 0xc1, 0x0, 0x3, 0xce, 0x5c, - 0x30, 0xd0, 0xc, 0x10, 0x0, 0xb2, 0xe0, 0x5d, - 0xd, 0x0, 0xc1, 0x0, 0x84, 0xe, 0x0, 0x30, - 0xd0, 0xc, 0x10, 0x64, 0x0, 0xe0, 0x0, 0x6, - 0x0, 0xc1, 0x13, 0x0, 0xe, 0x0, 0x0, 0x0, - 0xc, 0x10, 0x0, 0x0, 0xe0, 0x0, 0x3, 0x55, - 0xe1, 0x0, 0x0, 0xf, 0x0, 0x0, 0x2, 0xcd, - 0x0, 0x0, 0x0, 0x20, 0x0, 0x0, 0x1, 0x0, - - /* U+5230 "到" */ - 0x0, 0x0, 0x0, 0x4, 0x0, 0x0, 0x29, 0x3, - 0x76, 0x69, 0x66, 0x95, 0x0, 0x2, 0xa0, 0x0, - 0x6, 0xd1, 0x0, 0x2, 0x90, 0x2a, 0x0, 0x1, - 0xa0, 0x24, 0x0, 0x3b, 0x2, 0xa0, 0x1, 0x80, - 0x0, 0x78, 0x2, 0xa0, 0x2a, 0x1, 0xeb, 0x8b, - 0x65, 0xd7, 0x2a, 0x2, 0xa0, 0x2, 0x0, 0xf1, - 0x4, 0x42, 0xa0, 0x2a, 0x0, 0x0, 0xe, 0x0, - 0x0, 0x2a, 0x2, 0xa0, 0x26, 0x66, 0xe6, 0x6d, - 0x22, 0xa0, 0x2a, 0x0, 0x0, 0xe, 0x0, 0x0, - 0x3a, 0x2, 0xa0, 0x0, 0x0, 0xe0, 0x0, 0x3, - 0x90, 0x2a, 0x0, 0x0, 0xe, 0x14, 0x63, 0x0, - 0x2, 0xa0, 0x46, 0x9b, 0xb7, 0x20, 0x0, 0x10, - 0x4a, 0x7, 0xa4, 0x0, 0x0, 0x0, 0x3, 0x9f, - 0x70, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x40, - 0x0, - - /* U+5236 "制" */ - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, 0xb0, 0x0, 0x0, 0x0, 0x93, 0x0, - 0x43, 0xc, 0x0, 0x0, 0x0, 0xa, 0x20, 0x9, - 0x50, 0xc0, 0x21, 0x0, 0x60, 0xa2, 0x0, 0xc6, - 0x6d, 0x68, 0x70, 0x1c, 0xa, 0x20, 0x43, 0x0, - 0xc0, 0x0, 0x0, 0xb0, 0xa2, 0x8, 0x66, 0x6d, - 0x66, 0xb7, 0xb, 0xa, 0x20, 0x0, 0x0, 0xc0, - 0x0, 0x0, 0xb0, 0xa2, 0x0, 0xa6, 0x6d, 0x66, - 0xc1, 0xb, 0xa, 0x20, 0xc, 0x0, 0xc0, 0xc, - 0x0, 0xb0, 0xa2, 0x0, 0xc0, 0xc, 0x0, 0xc0, - 0xb, 0xa, 0x20, 0xc, 0x0, 0xc0, 0xc, 0x1, - 0x70, 0xa2, 0x0, 0xc0, 0xc, 0x49, 0xa0, 0x0, - 0xa, 0x20, 0x7, 0x0, 0xc0, 0x52, 0x0, 0x0, - 0xb2, 0x0, 0x0, 0xc, 0x0, 0x0, 0x5, 0xcf, - 0x0, 0x0, 0x0, 0x40, 0x0, 0x0, 0x0, 0x30, - - /* U+5238 "券" */ - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x5, 0x0, 0xe, 0x30, 0x33, 0x0, 0x0, - 0x0, 0x4, 0xc1, 0x2e, 0x0, 0xb7, 0x0, 0x0, - 0x0, 0x0, 0xc3, 0x69, 0x5, 0x40, 0x10, 0x0, - 0x1, 0x66, 0x76, 0xc9, 0x68, 0x67, 0xf4, 0x0, - 0x0, 0x20, 0x0, 0xd0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x5, 0xa0, 0x0, 0x0, 0x1b, 0x20, - 0x17, 0x66, 0x6e, 0x66, 0x6a, 0x76, 0x66, 0x40, - 0x0, 0x0, 0x96, 0x0, 0x0, 0x94, 0x0, 0x0, - 0x0, 0x9, 0x96, 0x66, 0x66, 0x9e, 0xc7, 0x40, - 0x4, 0x71, 0x1, 0xd0, 0x0, 0xa4, 0x3c, 0x80, - 0x11, 0x0, 0x6, 0x80, 0x0, 0xc2, 0x0, 0x0, - 0x0, 0x0, 0xc, 0x10, 0x0, 0xd0, 0x0, 0x0, - 0x0, 0x0, 0xa5, 0x1, 0x1, 0xd0, 0x0, 0x0, - 0x0, 0x49, 0x30, 0x1, 0x9f, 0x80, 0x0, 0x0, - 0x3, 0x30, 0x0, 0x0, 0x4, 0x0, 0x0, 0x0, - - /* U+523B "刻" */ - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x55, 0x0, 0x0, 0x0, 0x1, 0xd0, - 0x0, 0x0, 0xe, 0x20, 0x0, 0x0, 0x0, 0xc0, - 0x5, 0x66, 0x6b, 0x66, 0xb9, 0xa, 0x20, 0xc0, - 0x1, 0x10, 0x7a, 0x0, 0x0, 0xd, 0x0, 0xc0, - 0x0, 0x1, 0xc1, 0x7, 0x10, 0xd, 0x0, 0xc0, - 0x0, 0x9, 0x20, 0x2e, 0x30, 0xd, 0x0, 0xc0, - 0x0, 0xab, 0x75, 0xc4, 0x0, 0xd, 0x0, 0xc0, - 0x0, 0x21, 0x7, 0x80, 0xc3, 0xd, 0x0, 0xc0, - 0x0, 0x0, 0x68, 0x8, 0xa0, 0xd, 0x0, 0xc0, - 0x0, 0x7, 0x60, 0x5c, 0x0, 0xd, 0x0, 0xc0, - 0x2, 0x72, 0x3, 0xe3, 0x0, 0xb, 0x0, 0xc0, - 0x3, 0x0, 0x4b, 0x1a, 0x60, 0x0, 0x0, 0xc0, - 0x0, 0x7, 0x70, 0x1, 0xf1, 0x0, 0x1, 0xc0, - 0x4, 0x71, 0x0, 0x0, 0x50, 0x2, 0x8f, 0x90, - 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x5, 0x10, - - /* U+5247 "則" */ - 0x0, 0x20, 0x0, 0x4, 0x0, 0x0, 0x9, 0x20, - 0xe, 0x66, 0x66, 0xe2, 0x0, 0x0, 0xc0, 0x0, - 0xd0, 0x0, 0xd, 0x0, 0x60, 0xc, 0x0, 0xd, - 0x66, 0x66, 0xd0, 0xd, 0x0, 0xc0, 0x0, 0xd0, - 0x0, 0xd, 0x0, 0xd0, 0xc, 0x0, 0xd, 0x0, - 0x0, 0xd0, 0xd, 0x0, 0xc0, 0x0, 0xd6, 0x66, - 0x6d, 0x0, 0xd0, 0xc, 0x0, 0xd, 0x0, 0x0, - 0xd0, 0xd, 0x0, 0xc0, 0x0, 0xd6, 0x66, 0x6e, - 0x0, 0xd0, 0xc, 0x0, 0xd, 0x0, 0x0, 0xc0, - 0xd, 0x0, 0xc0, 0x0, 0x19, 0x22, 0x40, 0x0, - 0x40, 0xc, 0x0, 0x4, 0xb1, 0x8, 0x60, 0x0, - 0x0, 0xc0, 0x0, 0x90, 0x0, 0xd, 0x60, 0x0, - 0xd, 0x0, 0x70, 0x0, 0x0, 0x49, 0x1, 0x7e, - 0xd0, 0x11, 0x0, 0x0, 0x0, 0x10, 0x0, 0x21, - 0x0, - - /* U+524A "削" */ - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x1, 0xd1, 0x0, 0x0, 0x0, 0x82, 0x26, 0x0, - 0xd0, 0x1d, 0x0, 0x0, 0xd0, 0x9, 0x80, 0xd0, - 0x83, 0x1, 0x0, 0xd0, 0x1, 0xb0, 0xd2, 0x40, - 0xd, 0x20, 0xd0, 0x9, 0x66, 0xe6, 0x6a, 0xd, - 0x0, 0xd0, 0xe, 0x0, 0x0, 0x3a, 0xd, 0x0, - 0xd0, 0xe, 0x0, 0x0, 0x3a, 0xd, 0x0, 0xd0, - 0xe, 0x66, 0x66, 0x8a, 0xd, 0x0, 0xd0, 0xe, - 0x0, 0x0, 0x3a, 0xd, 0x0, 0xd0, 0xe, 0x66, - 0x66, 0x8a, 0xd, 0x0, 0xd0, 0xe, 0x0, 0x0, - 0x3a, 0xd, 0x0, 0xd0, 0xe, 0x0, 0x0, 0x3a, - 0x3, 0x0, 0xd0, 0xe, 0x0, 0x12, 0x6a, 0x0, - 0x21, 0xe0, 0xe, 0x0, 0x16, 0xf5, 0x0, 0x5e, - 0xc0, 0x3, 0x0, 0x0, 0x20, 0x0, 0x2, 0x10, - - /* U+524D "前" */ - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x27, 0x0, 0x0, 0x56, 0x0, 0x0, 0x0, - 0x0, 0xa8, 0x0, 0xa, 0x10, 0x0, 0x0, 0x0, - 0x3, 0x60, 0x4, 0x30, 0x8, 0x50, 0x57, 0x66, - 0x66, 0x66, 0x66, 0x66, 0x65, 0x0, 0x12, 0x0, - 0x5, 0x0, 0x0, 0xa4, 0x0, 0x2, 0xc6, 0x67, - 0xc0, 0x1b, 0xc, 0x10, 0x0, 0x2a, 0x0, 0x2b, - 0x1, 0xc0, 0xc1, 0x0, 0x2, 0xc6, 0x67, 0xb0, - 0x1c, 0xc, 0x10, 0x0, 0x2a, 0x0, 0x2b, 0x1, - 0xc0, 0xc1, 0x0, 0x2, 0xc6, 0x67, 0xb0, 0x1c, - 0xc, 0x10, 0x0, 0x2a, 0x0, 0x2b, 0x1, 0xc0, - 0xc1, 0x0, 0x2, 0xa0, 0x2, 0xb0, 0x18, 0xc, - 0x10, 0x0, 0x2a, 0x0, 0x3a, 0x1, 0x54, 0xe0, - 0x0, 0x3, 0xa0, 0x3d, 0x70, 0x2, 0xda, 0x0, - 0x0, 0x0, 0x0, 0x10, 0x0, 0x1, 0x0, 0x0, - - /* U+525B "剛" */ - 0x30, 0x0, 0x0, 0x5, 0x0, 0x0, 0x81, 0xd6, - 0x66, 0x66, 0x6e, 0x30, 0x0, 0xd0, 0xd0, 0x81, - 0xb, 0xd, 0x0, 0x30, 0xd0, 0xd0, 0x4a, 0x36, - 0xd, 0x0, 0xd0, 0xd0, 0xd2, 0x47, 0x78, 0x4d, - 0x0, 0xc0, 0xd0, 0xd1, 0x32, 0xb2, 0x1d, 0x0, - 0xc0, 0xd0, 0xd0, 0x10, 0xa2, 0xd, 0x0, 0xc0, - 0xd0, 0xd0, 0xc0, 0xaa, 0x2d, 0x0, 0xc0, 0xd0, - 0xd0, 0xb0, 0xaa, 0x1d, 0x0, 0xc0, 0xd0, 0xd0, - 0xb0, 0xaa, 0x1d, 0x0, 0xc0, 0xd0, 0xd1, 0xb6, - 0x8c, 0xd, 0x0, 0x50, 0xd0, 0xd0, 0x0, 0x0, - 0xd, 0x0, 0x0, 0xd0, 0xd0, 0x0, 0x0, 0xd, - 0x0, 0x10, 0xe0, 0xc0, 0x0, 0x6, 0xcd, 0x0, - 0x5d, 0xc0, 0x10, 0x0, 0x0, 0x42, 0x0, 0x1, - 0x20, - - /* U+5272 "割" */ - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x9, 0x30, 0x0, 0x0, 0x0, 0x92, 0x2, - 0x10, 0x37, 0x0, 0x30, 0x0, 0xc, 0x0, 0x86, - 0x67, 0x86, 0x6d, 0x50, 0x40, 0xc0, 0x2b, 0x0, - 0x2d, 0x2, 0x20, 0x1d, 0xc, 0x0, 0x36, 0x67, - 0xd6, 0x88, 0x0, 0xc0, 0xc0, 0x0, 0x0, 0x1b, - 0x0, 0x0, 0xc, 0xc, 0x0, 0x16, 0x66, 0xd6, - 0xa3, 0x0, 0xc0, 0xc0, 0x0, 0x0, 0x1b, 0x0, - 0x11, 0xc, 0xc, 0x1, 0x86, 0x67, 0xd6, 0x68, - 0x80, 0xc0, 0xc0, 0x0, 0x10, 0x17, 0x3, 0x0, - 0x1c, 0xc, 0x0, 0xd, 0x66, 0x66, 0xe1, 0x1, - 0x70, 0xc0, 0x0, 0xd0, 0x0, 0xd, 0x0, 0x0, - 0xc, 0x0, 0xd, 0x0, 0x0, 0xd0, 0x0, 0x0, - 0xc0, 0x0, 0xd6, 0x66, 0x6d, 0x0, 0x17, 0xbe, - 0x0, 0x4, 0x0, 0x0, 0x10, 0x0, 0x2, 0x30, - - /* U+5275 "創" */ - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, 0xc, 0x20, 0x0, 0x0, 0x1, 0x90, - 0x0, 0x0, 0x5b, 0x62, 0x0, 0x0, 0x0, 0xb0, - 0x0, 0x0, 0xc3, 0xa, 0xa0, 0x1, 0x0, 0xb0, - 0x0, 0x9, 0x35, 0x70, 0xb2, 0x2c, 0x0, 0xb0, - 0x0, 0x65, 0x0, 0xb0, 0x0, 0x1a, 0x0, 0xb0, - 0x5, 0x3b, 0x66, 0x66, 0xd0, 0x1a, 0x0, 0xb0, - 0x1, 0xc, 0x0, 0x0, 0xc0, 0x1a, 0x0, 0xb0, - 0x0, 0xd, 0x66, 0x66, 0xc0, 0x1a, 0x0, 0xb0, - 0x0, 0xd, 0x66, 0x66, 0xc0, 0x1a, 0x0, 0xb0, - 0x0, 0x1c, 0x0, 0x0, 0x20, 0x1a, 0x0, 0xb0, - 0x0, 0x4e, 0x76, 0x66, 0xc2, 0x13, 0x0, 0xb0, - 0x0, 0x99, 0x50, 0x0, 0xc0, 0x0, 0x0, 0xb0, - 0x1, 0x97, 0x50, 0x0, 0xc0, 0x0, 0x2, 0xb0, - 0x7, 0x17, 0x96, 0x66, 0xd0, 0x3, 0x9f, 0x80, - 0x12, 0x2, 0x0, 0x0, 0x10, 0x0, 0x3, 0x0, - - /* U+5283 "劃" */ - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, 0xc, 0x0, 0x0, 0x0, 0x1, 0x80, - 0x0, 0x46, 0x6d, 0x66, 0xa0, 0x0, 0x1, 0xa0, - 0x0, 0x11, 0xc, 0x0, 0xc2, 0x1, 0x1, 0xa0, - 0x6, 0x76, 0x6d, 0x66, 0xd8, 0x2d, 0x1, 0xa0, - 0x0, 0x35, 0x5d, 0x55, 0xc0, 0xc, 0x1, 0xa0, - 0x0, 0x12, 0x1c, 0x12, 0x50, 0xc, 0x1, 0xa0, - 0x0, 0x47, 0x6d, 0x66, 0x52, 0xc, 0x1, 0xa0, - 0x6, 0x76, 0x69, 0x66, 0x69, 0x1c, 0x1, 0xa0, - 0x0, 0x96, 0x68, 0x66, 0xb0, 0xc, 0x1, 0xa0, - 0x0, 0xc0, 0xc, 0x0, 0xc0, 0xd, 0x1, 0xa0, - 0x0, 0xc6, 0x6d, 0x66, 0xc0, 0x5, 0x1, 0xa0, - 0x0, 0xc6, 0x6d, 0x66, 0xc0, 0x0, 0x1, 0xa0, - 0x0, 0x50, 0x0, 0x0, 0x62, 0x0, 0x2, 0xa0, - 0x5, 0x9a, 0x98, 0x75, 0x31, 0x4, 0xaf, 0x80, - 0x3, 0x40, 0x0, 0x0, 0x0, 0x0, 0x5, 0x0, - - /* U+529B "力" */ - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x0, 0xb7, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, 0xc, 0x30, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, 0xc2, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0xd, 0x20, 0x0, 0x3, 0x0, 0x6, 0x66, - 0x66, 0xf6, 0x66, 0x66, 0xf4, 0x0, 0x0, 0x0, - 0x1d, 0x0, 0x0, 0xe, 0x0, 0x0, 0x0, 0x4, - 0xa0, 0x0, 0x2, 0xd0, 0x0, 0x0, 0x0, 0x95, - 0x0, 0x0, 0x3c, 0x0, 0x0, 0x0, 0x1d, 0x0, - 0x0, 0x5, 0xa0, 0x0, 0x0, 0x8, 0x70, 0x0, - 0x0, 0x69, 0x0, 0x0, 0x3, 0xc0, 0x0, 0x0, - 0x9, 0x70, 0x0, 0x1, 0xc1, 0x0, 0x0, 0x0, - 0xc4, 0x0, 0x1, 0xb2, 0x0, 0x2, 0x74, 0x6e, - 0x0, 0x3, 0x81, 0x0, 0x0, 0x1, 0xdf, 0x50, - 0x1, 0x30, 0x0, 0x0, 0x0, 0x2, 0x10, 0x0, - - /* U+529F "功" */ - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x0, 0x0, 0xd, 0x10, 0x0, 0x0, - 0x0, 0x0, 0x0, 0x0, 0xd0, 0x0, 0x0, 0x46, - 0x66, 0x6a, 0x70, 0xd, 0x0, 0x0, 0x1, 0x10, - 0xd0, 0x0, 0x0, 0xd0, 0x1, 0x0, 0x0, 0xd, - 0x0, 0x56, 0x6e, 0x66, 0xb8, 0x0, 0x0, 0xd0, - 0x0, 0x2, 0xb0, 0x8, 0x50, 0x0, 0xd, 0x0, - 0x0, 0x49, 0x0, 0x94, 0x0, 0x0, 0xd0, 0x0, - 0x7, 0x60, 0xa, 0x30, 0x0, 0xd, 0x0, 0x0, - 0xb3, 0x0, 0xb2, 0x0, 0x0, 0xd5, 0x64, 0x1c, - 0x0, 0xc, 0x10, 0x59, 0xc8, 0x20, 0x8, 0x50, - 0x0, 0xd0, 0x8, 0x60, 0x0, 0x4, 0xa0, 0x0, - 0xe, 0x0, 0x0, 0x0, 0x3, 0xa0, 0x24, 0x24, - 0xc0, 0x0, 0x0, 0x6, 0x60, 0x0, 0x3c, 0xf6, - 0x0, 0x0, 0x2, 0x10, 0x0, 0x0, 0x4, 0x0, - - /* U+52A0 "加" */ - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x3c, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x3, 0xb0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x2b, 0x0, 0x0, 0x20, 0x0, 0x20, 0x6, 0x67, - 0xd6, 0x6d, 0x1c, 0x66, 0x6c, 0x50, 0x0, 0x3a, - 0x0, 0xd0, 0xc0, 0x0, 0xa2, 0x0, 0x4, 0xa0, - 0xc, 0xc, 0x0, 0xa, 0x20, 0x0, 0x48, 0x0, - 0xc0, 0xc0, 0x0, 0xa2, 0x0, 0x6, 0x70, 0xb, - 0xc, 0x0, 0xa, 0x20, 0x0, 0x84, 0x1, 0xb0, - 0xc0, 0x0, 0xa2, 0x0, 0xb, 0x0, 0x29, 0xc, - 0x0, 0xa, 0x20, 0x2, 0xa0, 0x4, 0x80, 0xc0, - 0x0, 0xa2, 0x0, 0x92, 0x0, 0x76, 0xc, 0x66, - 0x6c, 0x30, 0x36, 0x18, 0xbe, 0x10, 0xc0, 0x0, - 0xa3, 0x6, 0x0, 0x6, 0x30, 0xb, 0x0, 0x5, - 0x10, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - - /* U+52A8 "动" */ - 0x0, 0x0, 0x0, 0x0, 0x0, 0xa1, 0x0, 0x0, - 0x0, 0x0, 0x4, 0x0, 0xd, 0x0, 0x0, 0x4, - 0x76, 0x66, 0x92, 0x0, 0xd0, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x0, 0xd, 0x0, 0x21, 0x0, 0x0, - 0x0, 0x2, 0x66, 0xe6, 0x6b, 0x70, 0x66, 0x67, - 0x67, 0xb1, 0xc, 0x0, 0x84, 0x0, 0x6, 0xd0, - 0x0, 0x0, 0xc0, 0x9, 0x40, 0x0, 0xc3, 0x0, - 0x0, 0x29, 0x0, 0x93, 0x0, 0x47, 0x5, 0x40, - 0x6, 0x60, 0xa, 0x30, 0x9, 0x0, 0xc, 0x30, - 0xa1, 0x0, 0xb2, 0x9, 0x56, 0x76, 0x8b, 0x2a, - 0x0, 0xb, 0x20, 0xc9, 0x40, 0x0, 0x7a, 0x10, - 0x0, 0xd0, 0x0, 0x0, 0x0, 0x6, 0x30, 0x31, - 0x2e, 0x0, 0x0, 0x0, 0x6, 0x30, 0x1, 0xaf, - 0x70, 0x0, 0x0, 0x3, 0x0, 0x0, 0x0, 0x30, - 0x0, - - /* U+52A9 "助" */ - 0x0, 0x0, 0x0, 0x0, 0x0, 0xa3, 0x0, 0x0, - 0x0, 0xa6, 0x66, 0xc2, 0x0, 0xd1, 0x0, 0x0, - 0x0, 0xd0, 0x0, 0xd0, 0x0, 0xd1, 0x0, 0x0, - 0x0, 0xd0, 0x0, 0xd0, 0x0, 0xd1, 0x0, 0x0, - 0x0, 0xd0, 0x0, 0xd2, 0x86, 0xe6, 0x67, 0xd0, - 0x0, 0xd6, 0x66, 0xd0, 0x0, 0xd0, 0x1, 0xb0, - 0x0, 0xd0, 0x0, 0xd0, 0x0, 0xe0, 0x2, 0xb0, - 0x0, 0xd0, 0x0, 0xd0, 0x0, 0xe0, 0x2, 0xa0, - 0x0, 0xd6, 0x66, 0xd0, 0x2, 0xc0, 0x3, 0xa0, - 0x0, 0xd0, 0x0, 0xd0, 0x6, 0x80, 0x3, 0x90, - 0x0, 0xd0, 0x0, 0xd1, 0x2c, 0x10, 0x4, 0x80, - 0x0, 0xd5, 0x87, 0x73, 0x76, 0x0, 0x6, 0x70, - 0x1f, 0xb6, 0x10, 0x5, 0x70, 0x35, 0x5d, 0x30, - 0x2, 0x0, 0x0, 0x64, 0x0, 0x3, 0xd8, 0x0, - 0x0, 0x0, 0x3, 0x0, 0x0, 0x0, 0x0, 0x0, - - /* U+52AA "努" */ - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, 0xc1, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x2, 0xb0, 0x11, 0x76, 0x66, 0x98, 0x0, - 0x7, 0x6a, 0x96, 0xc6, 0x24, 0x0, 0xb5, 0x0, - 0x0, 0xb, 0x0, 0xd0, 0x7, 0x3, 0xb0, 0x0, - 0x0, 0x48, 0x4, 0x90, 0x2, 0x9c, 0x10, 0x0, - 0x0, 0x15, 0x8e, 0x60, 0x0, 0xbc, 0x10, 0x0, - 0x0, 0x1, 0xa5, 0xb7, 0x1a, 0x43, 0xd7, 0x30, - 0x0, 0x57, 0x10, 0x28, 0x60, 0x0, 0x18, 0x80, - 0x15, 0x10, 0x0, 0x1b, 0x70, 0x0, 0x10, 0x0, - 0x0, 0x37, 0x66, 0x6e, 0x76, 0x66, 0xe3, 0x0, - 0x0, 0x0, 0x0, 0x4b, 0x0, 0x0, 0xe0, 0x0, - 0x0, 0x0, 0x0, 0xc3, 0x0, 0x3, 0xc0, 0x0, - 0x0, 0x0, 0x1b, 0x60, 0x11, 0x7, 0x90, 0x0, - 0x0, 0x16, 0x92, 0x0, 0x7, 0xef, 0x20, 0x0, - 0x3, 0x41, 0x0, 0x0, 0x0, 0x41, 0x0, 0x0, - - /* U+52B3 "劳" */ - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, 0xa, 0x50, 0x1, 0xc0, 0x0, 0x0, - 0x0, 0x0, 0xa, 0x20, 0x1, 0xc0, 0x4, 0x10, - 0x7, 0x66, 0x6c, 0x76, 0x66, 0xd6, 0x6a, 0x80, - 0x0, 0x0, 0xa, 0x20, 0x1, 0xc0, 0x0, 0x0, - 0x0, 0x30, 0x5, 0x10, 0x0, 0x30, 0x2, 0x0, - 0x0, 0xa6, 0x66, 0x66, 0x66, 0x66, 0x6e, 0x70, - 0x5, 0xb0, 0x0, 0x4b, 0x0, 0x0, 0x26, 0x0, - 0x2, 0x10, 0x0, 0x5b, 0x0, 0x0, 0x10, 0x0, - 0x0, 0x67, 0x66, 0x9b, 0x66, 0x6a, 0xb0, 0x0, - 0x0, 0x0, 0x0, 0x95, 0x0, 0x8, 0x60, 0x0, - 0x0, 0x0, 0x0, 0xe1, 0x0, 0xa, 0x50, 0x0, - 0x0, 0x0, 0x8, 0x90, 0x0, 0xc, 0x20, 0x0, - 0x0, 0x0, 0x7a, 0x0, 0x32, 0x2e, 0x0, 0x0, - 0x0, 0x39, 0x50, 0x0, 0x19, 0xf7, 0x0, 0x0, - 0x5, 0x30, 0x0, 0x0, 0x0, 0x30, 0x0, 0x0, - - /* U+52C9 "勉" */ - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0xb3, 0x0, 0x0, 0x9, 0x40, 0x0, 0x0, - 0x2b, 0x1, 0x30, 0x0, 0xc0, 0x0, 0x0, 0xa, - 0x76, 0xbc, 0x0, 0xc, 0x0, 0x0, 0x3, 0x90, - 0x9, 0x0, 0x0, 0xc0, 0x5, 0x0, 0x8b, 0x69, - 0x86, 0xd5, 0x5d, 0x55, 0xd1, 0x20, 0xc0, 0x94, - 0xc, 0x0, 0xb0, 0xc, 0x0, 0xc, 0x9, 0x30, - 0xc0, 0xb, 0x0, 0xc0, 0x0, 0xc5, 0xc6, 0x5d, - 0x2, 0x90, 0xc, 0x0, 0x8, 0x1c, 0xd1, 0x70, - 0x74, 0x0, 0xc0, 0x0, 0x2, 0xac, 0x0, 0xb, - 0x0, 0xb, 0x0, 0x0, 0x74, 0xc0, 0x7, 0x40, - 0x79, 0xa1, 0x0, 0x1b, 0xc, 0x3, 0x50, 0x0, - 0xa5, 0x20, 0x9, 0x10, 0xc0, 0x20, 0x0, 0x0, - 0x57, 0x7, 0x20, 0x8, 0xba, 0xaa, 0xaa, 0xac, - 0x72, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - - /* U+52D5 "動" */ - 0x0, 0x0, 0x0, 0x25, 0x0, 0x17, 0x0, 0x0, - 0x0, 0x46, 0x9a, 0xa8, 0x0, 0x1c, 0x0, 0x0, - 0x0, 0x0, 0xb1, 0x0, 0x0, 0x1c, 0x0, 0x0, - 0x7, 0x66, 0xc6, 0x69, 0x81, 0x2b, 0x11, 0x61, - 0x0, 0x10, 0xb1, 0x3, 0x7, 0x6c, 0x55, 0xd3, - 0x2, 0xc6, 0xc6, 0x6d, 0x10, 0x2a, 0x0, 0xc0, - 0x1, 0xc6, 0xc6, 0x6d, 0x0, 0x48, 0x0, 0xc0, - 0x1, 0xa0, 0xb1, 0xc, 0x0, 0x66, 0x0, 0xc0, - 0x1, 0xc6, 0xc6, 0x6d, 0x0, 0xa2, 0x0, 0xc0, - 0x1, 0x40, 0xb1, 0x5, 0x0, 0xc0, 0x0, 0xc0, - 0x3, 0x66, 0xc6, 0x6c, 0x24, 0x70, 0x2, 0xa0, - 0x0, 0x10, 0xb1, 0x0, 0xa, 0x0, 0x5, 0x80, - 0x0, 0x13, 0xc8, 0x65, 0x74, 0x15, 0x3b, 0x40, - 0x9, 0xc7, 0x20, 0x3, 0x50, 0x2, 0xdb, 0x0, - 0x0, 0x0, 0x0, 0x2, 0x0, 0x0, 0x20, 0x0, - - /* U+52D9 "務" */ - 0x0, 0x0, 0x0, 0x20, 0xb, 0x0, 0x0, 0x0, - 0x5, 0x76, 0x68, 0xe1, 0x5d, 0x66, 0x86, 0x0, - 0x0, 0x14, 0x18, 0x10, 0xa4, 0x0, 0xb4, 0x0, - 0x0, 0x6, 0xd0, 0x4, 0x37, 0x3, 0xa0, 0x0, - 0x0, 0x0, 0x95, 0x2, 0x1, 0xac, 0x10, 0x0, - 0x6, 0x76, 0x86, 0xa2, 0x1, 0xbc, 0x20, 0x0, - 0x0, 0x8, 0xf1, 0x91, 0x3a, 0x12, 0xda, 0x51, - 0x0, 0xc, 0xc1, 0x27, 0x58, 0x50, 0x6, 0x60, - 0x0, 0x56, 0xc1, 0x35, 0x6c, 0x86, 0x76, 0x0, - 0x0, 0xa0, 0xc1, 0x1, 0xc, 0x0, 0x76, 0x0, - 0x6, 0x20, 0xc1, 0x0, 0x49, 0x0, 0x84, 0x0, - 0x13, 0x0, 0xc1, 0x0, 0xb2, 0x0, 0xa2, 0x0, - 0x0, 0x32, 0xd0, 0x7, 0x60, 0x10, 0xd0, 0x0, - 0x0, 0x3b, 0xc0, 0x74, 0x0, 0x7e, 0xa0, 0x0, - 0x0, 0x1, 0x2, 0x0, 0x0, 0x3, 0x0, 0x0, - - /* U+52DD "勝" */ - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x96, 0x6a, 0x13, 0x3, 0xc0, 0x45, 0x0, - 0x0, 0xc0, 0xc, 0x9, 0x53, 0xa0, 0xb4, 0x0, - 0x0, 0xc0, 0xc, 0x1, 0xa4, 0x86, 0x10, 0x0, - 0x0, 0xc0, 0xc, 0x7, 0x69, 0xa6, 0x8a, 0x0, - 0x0, 0xd6, 0x6c, 0x0, 0xa, 0x20, 0x1, 0x10, - 0x0, 0xc0, 0xc, 0x76, 0x6d, 0x76, 0x69, 0x80, - 0x0, 0xc0, 0xc, 0x0, 0x76, 0x7, 0x10, 0x0, - 0x0, 0xc3, 0x3c, 0x4, 0x88, 0x51, 0xb6, 0x10, - 0x0, 0xc3, 0x3c, 0x46, 0xa, 0x20, 0x4a, 0xc2, - 0x0, 0xa0, 0xc, 0x17, 0x6d, 0x66, 0xc3, 0x0, - 0x3, 0x80, 0xc, 0x0, 0x1a, 0x0, 0xb0, 0x0, - 0x5, 0x40, 0xc, 0x0, 0x93, 0x0, 0xc0, 0x0, - 0x7, 0x0, 0xc, 0x4, 0x70, 0x0, 0xc0, 0x0, - 0x6, 0x6, 0xe9, 0x46, 0x1, 0x8d, 0x80, 0x0, - 0x10, 0x0, 0x32, 0x20, 0x0, 0x5, 0x0, 0x0, - - /* U+52E4 "勤" */ - 0x0, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0xd, 0x10, 0xa0, 0x0, 0x3c, 0x0, 0x0, - 0x5, 0x6e, 0x66, 0xc7, 0xd2, 0x3a, 0x0, 0x0, - 0x1, 0xd, 0x0, 0x90, 0x0, 0x39, 0x0, 0x0, - 0x0, 0xe, 0x67, 0xb0, 0x0, 0x39, 0x0, 0x20, - 0x0, 0x14, 0x1a, 0x22, 0x28, 0x8b, 0x66, 0xe0, - 0x0, 0xd6, 0x6c, 0x6d, 0x40, 0x48, 0x1, 0xb0, - 0x0, 0xd0, 0x1a, 0xc, 0x0, 0x48, 0x1, 0xb0, - 0x0, 0xe6, 0x6c, 0x6d, 0x0, 0x56, 0x2, 0xb0, - 0x0, 0x40, 0x1a, 0x6, 0x20, 0x75, 0x2, 0xa0, - 0x1, 0x76, 0x6c, 0x66, 0x50, 0xb1, 0x3, 0x90, - 0x0, 0x56, 0x6c, 0x6b, 0x41, 0xb0, 0x4, 0x80, - 0x0, 0x10, 0x1a, 0x0, 0x8, 0x40, 0x6, 0x70, - 0x0, 0x13, 0x6c, 0x65, 0x78, 0x5, 0x5d, 0x40, - 0xb, 0xb7, 0x30, 0x3, 0x60, 0x1, 0xc9, 0x0, - 0x0, 0x0, 0x0, 0x12, 0x0, 0x0, 0x0, 0x0, - - /* U+52F5 "勵" */ - 0x2, 0x0, 0x0, 0x1, 0x50, 0x38, 0x0, 0x0, - 0x9, 0x76, 0x76, 0x66, 0x61, 0x3a, 0x0, 0x0, - 0x9, 0x20, 0xb0, 0x44, 0x10, 0x39, 0x0, 0x0, - 0x8, 0x77, 0xc6, 0x88, 0x80, 0x29, 0x0, 0x30, - 0x8, 0x20, 0x30, 0x22, 0x28, 0x8b, 0x66, 0xd0, - 0x8, 0x2b, 0x6a, 0x6c, 0x20, 0x48, 0x0, 0xc0, - 0x8, 0x1b, 0x6c, 0x6c, 0x0, 0x56, 0x0, 0xc0, - 0x9, 0x1b, 0xb, 0xa, 0x0, 0x74, 0x0, 0xc0, - 0xa, 0x9, 0x6c, 0x69, 0x0, 0xa2, 0x0, 0xb0, - 0xa, 0x36, 0x6c, 0x66, 0x60, 0xc0, 0x1, 0xa0, - 0x9, 0x55, 0xb, 0x12, 0xa1, 0xa0, 0x2, 0x90, - 0x7, 0x56, 0x5c, 0x68, 0x97, 0x40, 0x4, 0x80, - 0x31, 0x55, 0x50, 0x6, 0x99, 0x4, 0x2a, 0x40, - 0x30, 0x55, 0x0, 0x1c, 0xa1, 0x1, 0xcb, 0x0, - 0x0, 0x11, 0x0, 0x0, 0x30, 0x0, 0x10, 0x0, - - /* U+5305 "包" */ - 0x0, 0x0, 0xb, 0x40, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x4d, 0x10, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, 0xc9, 0x66, 0x66, 0x66, 0xc3, 0x0, - 0x0, 0x5, 0x80, 0x0, 0x0, 0x0, 0xd0, 0x0, - 0x0, 0x1b, 0x10, 0x0, 0x1, 0x0, 0xd0, 0x0, - 0x0, 0x94, 0xc6, 0x66, 0x6d, 0x0, 0xd0, 0x0, - 0x6, 0x21, 0xb0, 0x0, 0xc, 0x0, 0xe0, 0x0, - 0x1, 0x1, 0xb0, 0x0, 0xc, 0x0, 0xe0, 0x0, - 0x0, 0x1, 0xd6, 0x66, 0x6a, 0x0, 0xd0, 0x0, - 0x0, 0x1, 0xb0, 0x0, 0x5, 0x25, 0xb0, 0x10, - 0x0, 0x1, 0xb0, 0x0, 0x0, 0x6e, 0x40, 0x60, - 0x0, 0x1, 0xb0, 0x0, 0x0, 0x0, 0x0, 0x80, - 0x0, 0x0, 0xd0, 0x0, 0x0, 0x0, 0x2, 0xe1, - 0x0, 0x0, 0x7c, 0xbb, 0xcc, 0xcc, 0xde, 0xa0, - - /* U+5316 "化" */ - 0x0, 0x0, 0x63, 0x0, 0x82, 0x0, 0x0, 0x0, - 0x0, 0xe, 0x30, 0xd, 0x20, 0x0, 0x0, 0x0, - 0x4, 0xb0, 0x0, 0xc1, 0x0, 0x0, 0x0, 0x0, - 0xb4, 0x0, 0xc, 0x10, 0x9, 0x10, 0x0, 0x3e, - 0x10, 0x0, 0xc1, 0x8, 0xb2, 0x0, 0xb, 0xe4, - 0x0, 0xc, 0x15, 0xc0, 0x0, 0x3, 0x7b, 0x20, - 0x0, 0xc5, 0xc1, 0x0, 0x0, 0x80, 0xb2, 0x0, - 0xc, 0xb0, 0x0, 0x0, 0x30, 0xb, 0x20, 0x8, - 0xf1, 0x0, 0x0, 0x0, 0x0, 0xb2, 0x19, 0x3c, - 0x10, 0x0, 0x0, 0x0, 0xb, 0x45, 0x0, 0xc1, - 0x0, 0x6, 0x0, 0x0, 0xb2, 0x0, 0xc, 0x10, - 0x0, 0x71, 0x0, 0xb, 0x20, 0x0, 0xc2, 0x0, - 0x9, 0x70, 0x0, 0xc2, 0x0, 0x6, 0xed, 0xdd, - 0xe6, 0x0, 0x6, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, - - /* U+5317 "北" */ - 0x0, 0x0, 0xa, 0x40, 0x1a, 0x10, 0x0, 0x0, - 0x0, 0x0, 0xc1, 0x0, 0xe0, 0x0, 0x0, 0x0, - 0x0, 0xc, 0x10, 0xd, 0x0, 0x0, 0x0, 0x0, - 0x0, 0xc1, 0x0, 0xd0, 0x0, 0x60, 0x5, 0x66, - 0x6d, 0x10, 0xd, 0x0, 0xbc, 0x20, 0x0, 0x0, - 0xc1, 0x0, 0xd2, 0xa5, 0x0, 0x0, 0x0, 0xc, - 0x10, 0xe, 0x50, 0x0, 0x0, 0x0, 0x0, 0xc1, - 0x0, 0xd0, 0x0, 0x0, 0x0, 0x0, 0xc, 0x10, - 0xd, 0x0, 0x0, 0x0, 0x0, 0x0, 0xc1, 0x0, - 0xd0, 0x0, 0x10, 0x0, 0x0, 0x4d, 0x10, 0xd, - 0x0, 0x5, 0x1, 0x6a, 0x92, 0xc1, 0x0, 0xd0, - 0x0, 0x61, 0xa, 0x20, 0xc, 0x10, 0xe, 0x0, - 0x9, 0x60, 0x0, 0x0, 0xd2, 0x0, 0xbe, 0xdd, - 0xe6, 0x0, 0x0, 0x5, 0x0, 0x0, 0x0, 0x0, - 0x0, - - /* U+533B "医" */ - 0x1, 0x0, 0x0, 0x0, 0x0, 0x3, 0x40, 0x1, - 0xd6, 0x66, 0x76, 0x66, 0x66, 0x99, 0x0, 0xd, - 0x0, 0xd, 0x30, 0x0, 0x0, 0x0, 0x0, 0xd0, - 0x2, 0xb0, 0x0, 0x5, 0x10, 0x0, 0xd, 0x0, - 0x78, 0x6b, 0x66, 0x85, 0x0, 0x0, 0xd0, 0x9, - 0x0, 0xd0, 0x0, 0x0, 0x0, 0xd, 0x6, 0x0, - 0xe, 0x0, 0x0, 0x10, 0x0, 0xd2, 0x76, 0x66, - 0xe6, 0x66, 0x6e, 0x30, 0xd, 0x0, 0x0, 0x3b, - 0x0, 0x0, 0x0, 0x0, 0xd0, 0x0, 0x9, 0x88, - 0x40, 0x0, 0x0, 0xd, 0x0, 0x4, 0xa0, 0x8, - 0xd4, 0x0, 0x0, 0xd0, 0x5, 0x90, 0x0, 0x5, - 0xf1, 0x0, 0xd, 0x16, 0x30, 0x0, 0x0, 0x4, - 0x51, 0x2, 0xd6, 0x66, 0x66, 0x66, 0x66, 0x6a, - 0x80, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, - - /* U+5340 "區" */ - 0x3, 0x0, 0x0, 0x0, 0x0, 0x8, 0x30, 0xe, - 0x66, 0x66, 0x66, 0x66, 0x66, 0x50, 0xd, 0x0, - 0x18, 0x66, 0x69, 0x40, 0x0, 0xd, 0x0, 0x1a, - 0x0, 0x8, 0x40, 0x0, 0xd, 0x0, 0x1a, 0x0, - 0x8, 0x40, 0x0, 0xd, 0x0, 0x1c, 0x66, 0x6b, - 0x40, 0x0, 0xd, 0x0, 0x3, 0x0, 0x3, 0x0, - 0x0, 0xd, 0x7, 0x66, 0x90, 0x86, 0x69, 0x0, - 0xd, 0xd, 0x0, 0xb0, 0xc0, 0xc, 0x0, 0xd, - 0xd, 0x0, 0xb0, 0xc0, 0xc, 0x0, 0xd, 0xd, - 0x0, 0xb0, 0xc0, 0xc, 0x0, 0xd, 0xd, 0x66, - 0xb0, 0xd6, 0x6c, 0x0, 0xd, 0x3, 0x0, 0x10, - 0x20, 0x1, 0x10, 0x1e, 0x66, 0x66, 0x66, 0x66, - 0x67, 0xf3, 0x3, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, - - /* U+5341 "十" */ - 0x0, 0x0, 0x0, 0x9, 0x30, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x0, 0xc, 0x30, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x0, 0xc, 0x20, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x0, 0xc, 0x20, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x0, 0xc, 0x20, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x0, 0xc, 0x20, 0x0, 0xa, 0x30, - 0x28, 0x66, 0x66, 0x6d, 0x76, 0x66, 0x66, 0x50, - 0x0, 0x0, 0x0, 0xc, 0x20, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x0, 0xc, 0x20, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x0, 0xc, 0x20, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x0, 0xc, 0x20, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x0, 0xc, 0x20, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x0, 0xc, 0x20, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x0, 0xc, 0x20, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x0, 0x6, 0x0, 0x0, 0x0, 0x0, - - /* U+5343 "千" */ - 0x0, 0x0, 0x0, 0x0, 0x1, 0x6a, 0x0, 0x0, - 0x0, 0x0, 0x3, 0x69, 0xcc, 0xa8, 0x30, 0x0, - 0x0, 0x25, 0x54, 0x2c, 0x30, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x0, 0xb, 0x30, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x0, 0xb, 0x30, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x0, 0xb, 0x30, 0x0, 0x7, 0x10, - 0x27, 0x66, 0x66, 0x6d, 0x86, 0x66, 0x69, 0x60, - 0x0, 0x0, 0x0, 0xb, 0x30, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x0, 0xb, 0x30, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x0, 0xb, 0x30, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x0, 0xb, 0x30, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x0, 0xb, 0x30, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x0, 0xb, 0x30, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x0, 0xb, 0x30, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x0, 0x4, 0x0, 0x0, 0x0, 0x0, - - /* U+5348 "午" */ - 0x0, 0x0, 0x10, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0xb, 0x80, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x1, 0xe1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x8b, 0x66, 0x66, 0x66, 0xca, 0x0, 0x0, 0x1b, - 0x0, 0xa, 0x40, 0x0, 0x0, 0x0, 0x8, 0x10, - 0x0, 0xa4, 0x0, 0x0, 0x0, 0x4, 0x20, 0x0, - 0xa, 0x40, 0x0, 0x0, 0x0, 0x10, 0x0, 0x0, - 0xa4, 0x0, 0x0, 0x20, 0x16, 0x66, 0x66, 0x6c, - 0x86, 0x66, 0x6e, 0x60, 0x10, 0x0, 0x0, 0xa4, - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xa, 0x40, - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xa4, 0x0, - 0x0, 0x0, 0x0, 0x0, 0x0, 0xa, 0x40, 0x0, - 0x0, 0x0, 0x0, 0x0, 0x0, 0xa4, 0x0, 0x0, - 0x0, 0x0, 0x0, 0x0, 0xa, 0x50, 0x0, 0x0, - 0x0, 0x0, 0x0, 0x0, 0x40, 0x0, 0x0, 0x0, - - /* U+534A "半" */ - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x0, 0xc, 0x40, 0x0, 0x0, 0x0, - 0x0, 0x2, 0x0, 0xc, 0x10, 0x8, 0x70, 0x0, - 0x0, 0x7, 0x70, 0xc, 0x10, 0x2d, 0x30, 0x0, - 0x0, 0x0, 0xb9, 0xc, 0x10, 0xa1, 0x0, 0x0, - 0x0, 0x0, 0x39, 0xc, 0x16, 0x10, 0x0, 0x0, - 0x1, 0x66, 0x66, 0x6d, 0x66, 0x66, 0xd7, 0x0, - 0x0, 0x20, 0x0, 0xc, 0x10, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x0, 0xc, 0x10, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x0, 0xc, 0x10, 0x0, 0x8, 0x20, - 0x7, 0x66, 0x66, 0x6d, 0x66, 0x66, 0x68, 0x60, - 0x0, 0x0, 0x0, 0xc, 0x10, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x0, 0xc, 0x10, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x0, 0xc, 0x10, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x0, 0xd, 0x10, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x0, 0x5, 0x0, 0x0, 0x0, 0x0, - - /* U+5352 "卒" */ - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x7, 0x40, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x2c, 0x0, 0x4, 0x50, 0x0, 0x67, - 0x69, 0x66, 0x66, 0x86, 0x66, 0x0, 0x0, 0x0, - 0xe3, 0x0, 0xd, 0x60, 0x0, 0x0, 0x0, 0x69, - 0x0, 0x5, 0xb0, 0x0, 0x0, 0x0, 0xb, 0x69, - 0x0, 0xb5, 0x91, 0x0, 0x0, 0x7, 0x40, 0xa5, - 0x83, 0x5, 0xe0, 0x0, 0x3, 0x50, 0x2, 0x77, - 0x0, 0xa, 0x0, 0x0, 0x20, 0x0, 0x1, 0xe1, - 0x0, 0x3, 0x50, 0x67, 0x66, 0x66, 0x6e, 0x66, - 0x66, 0x88, 0x10, 0x0, 0x0, 0x0, 0xd0, 0x0, - 0x0, 0x0, 0x0, 0x0, 0x0, 0xd, 0x0, 0x0, - 0x0, 0x0, 0x0, 0x0, 0x0, 0xd0, 0x0, 0x0, - 0x0, 0x0, 0x0, 0x0, 0xd, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x0, 0x0, 0x50, 0x0, 0x0, 0x0, - - /* U+5354 "協" */ - 0x0, 0x9, 0x10, 0x0, 0x6, 0x60, 0x0, 0x0, - 0x0, 0xd, 0x0, 0x0, 0x9, 0x40, 0x3, 0x0, - 0x0, 0xd, 0x0, 0x37, 0x6d, 0x66, 0x6d, 0x40, - 0x0, 0xd, 0x0, 0x0, 0x39, 0x0, 0xb, 0x0, - 0x6, 0x6e, 0x6b, 0x21, 0xa1, 0x0, 0x48, 0x0, - 0x1, 0xd, 0x0, 0x57, 0x0, 0x4a, 0xd1, 0x0, - 0x0, 0xd, 0x3, 0x23, 0x0, 0x2, 0x40, 0x0, - 0x0, 0xd, 0x1, 0x4b, 0x14, 0x0, 0xe0, 0x40, - 0x0, 0xd, 0x6, 0x99, 0x5c, 0x58, 0xd6, 0xc2, - 0x0, 0xd, 0x0, 0x83, 0xb, 0x3, 0x90, 0xa0, - 0x0, 0xd, 0x0, 0xb0, 0xb, 0x7, 0x60, 0xb0, - 0x0, 0xd, 0x2, 0x80, 0x29, 0xc, 0x10, 0xb0, - 0x0, 0xd, 0x8, 0x24, 0x85, 0x47, 0x0, 0xc0, - 0x0, 0xe, 0x44, 0x4, 0xc4, 0x70, 0x6b, 0xa0, - 0x0, 0x5, 0x20, 0x0, 0x13, 0x0, 0x5, 0x10, - - /* U+5357 "南" */ - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x0, 0xa4, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, 0xc, 0x20, 0x0, 0x5, 0x1, 0x76, - 0x66, 0x66, 0xe6, 0x66, 0x68, 0xc4, 0x0, 0x0, - 0x0, 0xd, 0x0, 0x0, 0x0, 0x0, 0x8, 0x66, - 0x66, 0xe6, 0x66, 0x6a, 0x40, 0x0, 0xb1, 0x3, - 0x0, 0x8, 0x0, 0xb2, 0x0, 0xb, 0x10, 0x3c, - 0x3, 0xa0, 0xb, 0x20, 0x0, 0xb1, 0x0, 0x90, - 0x71, 0x60, 0xb2, 0x0, 0xb, 0x16, 0x76, 0xd6, - 0x67, 0x1b, 0x20, 0x0, 0xb1, 0x0, 0xc, 0x0, - 0x61, 0xb2, 0x0, 0xb, 0x38, 0x66, 0xd6, 0x66, - 0x4b, 0x20, 0x0, 0xb1, 0x0, 0xc, 0x0, 0x0, - 0xb2, 0x0, 0xb, 0x10, 0x0, 0xc0, 0x23, 0x2d, - 0x10, 0x0, 0xc1, 0x0, 0xa, 0x0, 0x5e, 0xc0, - 0x0, 0x2, 0x0, 0x0, 0x0, 0x0, 0x20, 0x0, - - /* U+5358 "単" */ - 0x0, 0x3, 0x0, 0x52, 0x0, 0x67, 0x0, 0x0, - 0x0, 0x89, 0x1, 0xd1, 0xc, 0x40, 0x0, 0x0, - 0x0, 0xd3, 0xb, 0x35, 0x60, 0x0, 0x0, 0x2, - 0x89, 0x66, 0x76, 0xa6, 0xb1, 0x0, 0x0, 0x2a, - 0x0, 0xd, 0x0, 0xd, 0x0, 0x0, 0x2, 0xa0, - 0x0, 0xd0, 0x0, 0xd0, 0x0, 0x0, 0x2c, 0x66, - 0x6e, 0x66, 0x6d, 0x0, 0x0, 0x2, 0xa0, 0x0, - 0xd0, 0x0, 0xd0, 0x0, 0x0, 0x2c, 0x66, 0x6e, - 0x66, 0x6d, 0x0, 0x0, 0x1, 0x40, 0x0, 0xd0, - 0x0, 0x41, 0x30, 0x37, 0x66, 0x66, 0x6e, 0x66, - 0x66, 0xac, 0x20, 0x0, 0x0, 0x0, 0xd0, 0x0, - 0x0, 0x0, 0x0, 0x0, 0x0, 0xd, 0x0, 0x0, - 0x0, 0x0, 0x0, 0x0, 0x0, 0xd0, 0x0, 0x0, - 0x0, 0x0, 0x0, 0x0, 0x3, 0x0, 0x0, 0x0, - 0x0, - - /* U+5371 "危" */ - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, 0xd3, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x7d, 0x66, 0x67, 0x90, 0x0, 0x0, 0x0, - 0x2c, 0x0, 0x0, 0xb6, 0x0, 0x0, 0x0, 0x1b, - 0x10, 0x0, 0x55, 0x0, 0x2, 0x0, 0x28, 0xa6, - 0x66, 0x69, 0x66, 0x69, 0xb0, 0x4, 0xb, 0x20, - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xb2, 0xa, - 0x66, 0x66, 0xd0, 0x0, 0x0, 0xb, 0x20, 0xd0, - 0x0, 0xd, 0x0, 0x0, 0x0, 0xb2, 0xd, 0x0, - 0x0, 0xd0, 0x0, 0x0, 0xc, 0x10, 0xd0, 0x0, - 0xc, 0x0, 0x0, 0x0, 0xd0, 0xd, 0x1, 0x6d, - 0xa0, 0x50, 0x0, 0x3a, 0x0, 0xd0, 0x0, 0x30, - 0x7, 0x10, 0xa, 0x20, 0xc, 0x10, 0x0, 0x0, - 0x95, 0x6, 0x30, 0x0, 0x6d, 0xcc, 0xcc, 0xce, - 0x61, 0x10, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - - /* U+5373 "即" */ - 0x2, 0x0, 0x3, 0x0, 0x0, 0x0, 0x10, 0xe, - 0x66, 0x6e, 0x30, 0xc6, 0x66, 0xe1, 0xd, 0x0, - 0xd, 0x0, 0xd0, 0x0, 0xd0, 0xd, 0x66, 0x6e, - 0x0, 0xd0, 0x0, 0xd0, 0xd, 0x0, 0xd, 0x0, - 0xd0, 0x0, 0xd0, 0xd, 0x0, 0xd, 0x0, 0xd0, - 0x0, 0xd0, 0xd, 0x66, 0x6e, 0x0, 0xd0, 0x0, - 0xd0, 0xd, 0x0, 0x8, 0x0, 0xd0, 0x0, 0xd0, - 0xd, 0x3, 0x50, 0x0, 0xd0, 0x0, 0xd0, 0xd, - 0x0, 0x6a, 0x0, 0xd0, 0x0, 0xc0, 0xd, 0x1, - 0x5b, 0xa0, 0xd1, 0x8d, 0xa0, 0x1f, 0xa7, 0x11, - 0x90, 0xd0, 0x4, 0x0, 0x5, 0x0, 0x0, 0x0, - 0xd0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xd0, - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x40, 0x0, - 0x0, - - /* U+537B "卻" */ - 0x0, 0x3, 0x40, 0x61, 0x0, 0x0, 0x0, 0x0, - 0x0, 0xc, 0x60, 0x2d, 0x40, 0xa6, 0x66, 0xa1, - 0x0, 0x83, 0x0, 0x4, 0xc0, 0xd0, 0x0, 0xd0, - 0x5, 0x10, 0x3d, 0x0, 0x20, 0xd0, 0x0, 0xd0, - 0x0, 0x0, 0xb7, 0x70, 0x0, 0xd0, 0x0, 0xd0, - 0x0, 0x6, 0x60, 0x3c, 0x20, 0xd0, 0x0, 0xd0, - 0x0, 0x39, 0x0, 0x5, 0xd0, 0xd0, 0x0, 0xd0, - 0x2, 0x83, 0x0, 0x4, 0x70, 0xd0, 0x0, 0xd0, - 0x5, 0xe, 0x66, 0x6e, 0x20, 0xd0, 0x0, 0xd0, - 0x0, 0xd, 0x0, 0xd, 0x0, 0xd0, 0x0, 0xd0, - 0x0, 0xd, 0x0, 0xd, 0x0, 0xd1, 0x79, 0xc0, - 0x0, 0xd, 0x0, 0xd, 0x0, 0xd0, 0x8, 0x30, - 0x0, 0xe, 0x66, 0x6e, 0x0, 0xd0, 0x0, 0x0, - 0x0, 0x9, 0x0, 0x5, 0x0, 0xd0, 0x0, 0x0, - 0x0, 0x0, 0x0, 0x0, 0x0, 0x20, 0x0, 0x0, - - /* U+539A "厚" */ - 0x0, 0x40, 0x0, 0x0, 0x0, 0x0, 0xa3, 0x0, - 0xe, 0x66, 0x66, 0x66, 0x66, 0x66, 0x50, 0x0, - 0xd0, 0xc, 0x66, 0x66, 0x6c, 0x0, 0x0, 0xd, - 0x0, 0xd0, 0x0, 0x0, 0xd0, 0x0, 0x0, 0xd0, - 0xe, 0x66, 0x66, 0x6d, 0x0, 0x0, 0xd, 0x0, - 0xe6, 0x66, 0x66, 0xd0, 0x0, 0x0, 0xd0, 0xa, - 0x0, 0x0, 0x8, 0x0, 0x0, 0xd, 0x5, 0x66, - 0x66, 0x66, 0xc2, 0x0, 0x0, 0xc0, 0x0, 0x0, - 0x13, 0x85, 0x10, 0x0, 0x2a, 0x0, 0x0, 0xc, - 0x20, 0x2, 0x50, 0x5, 0x76, 0x66, 0x66, 0xe6, - 0x66, 0x77, 0x10, 0x92, 0x0, 0x0, 0xd, 0x0, - 0x0, 0x0, 0x9, 0x0, 0x0, 0x10, 0xd0, 0x0, - 0x0, 0x5, 0x10, 0x0, 0x4, 0xdb, 0x0, 0x0, - 0x0, 0x10, 0x0, 0x0, 0x1, 0x0, 0x0, 0x0, - 0x0, - - /* U+539F "原" */ - 0x0, 0x30, 0x0, 0x0, 0x0, 0x5, 0x80, 0x0, - 0xe6, 0x66, 0x68, 0x96, 0x66, 0x61, 0x0, 0xe0, - 0x0, 0x8, 0x40, 0x0, 0x0, 0x0, 0xe0, 0x1a, - 0x69, 0x66, 0x6c, 0x30, 0x0, 0xe0, 0xc, 0x0, - 0x0, 0xb, 0x10, 0x0, 0xe0, 0xd, 0x66, 0x66, - 0x6d, 0x10, 0x0, 0xd0, 0xc, 0x0, 0x0, 0xb, - 0x10, 0x0, 0xd0, 0xd, 0x66, 0x66, 0x6d, 0x10, - 0x0, 0xc0, 0x7, 0x0, 0xd0, 0x6, 0x0, 0x2, - 0xa0, 0x2, 0x50, 0xd1, 0x0, 0x0, 0x4, 0x70, - 0xd, 0x80, 0xd0, 0x77, 0x0, 0x9, 0x21, 0xb4, - 0x0, 0xd0, 0x6, 0xe3, 0x18, 0x18, 0x10, 0x57, - 0xe0, 0x0, 0x6a, 0x60, 0x10, 0x0, 0x8, 0x80, - 0x0, 0x2, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, - - /* U+53B3 "厳" */ - 0x0, 0x0, 0x81, 0x6, 0x20, 0xb, 0x20, 0x0, - 0x0, 0x4, 0xc0, 0x1e, 0x5, 0x70, 0x0, 0x0, - 0x52, 0x26, 0x22, 0x62, 0x62, 0x6b, 0x0, 0xb, - 0x64, 0x44, 0x44, 0x4a, 0x44, 0x41, 0x0, 0xa3, - 0x67, 0x97, 0x1, 0xd0, 0x0, 0x0, 0xa, 0x30, - 0xa, 0x14, 0x64, 0x3, 0x40, 0x0, 0xa5, 0x8c, - 0x6d, 0x5c, 0x66, 0xe5, 0x0, 0xa, 0x22, 0xc6, - 0xd4, 0x62, 0xd, 0x0, 0x0, 0xb2, 0x2a, 0xc, - 0x20, 0x62, 0xa0, 0x0, 0xc, 0x2, 0xc6, 0xd0, - 0x9, 0x75, 0x0, 0x0, 0xc0, 0x2a, 0xc, 0x0, - 0x6d, 0x0, 0x0, 0x28, 0x15, 0xc7, 0xd6, 0x27, - 0xe1, 0x0, 0x6, 0x25, 0xa4, 0xc, 0x3, 0x84, - 0xd3, 0x0, 0x60, 0x0, 0x0, 0xb3, 0x60, 0x5, - 0xd3, 0x11, 0x0, 0x0, 0x1, 0x10, 0x0, 0x0, - 0x0, - - /* U+53BB "去" */ - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x0, 0xb5, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, 0xb, 0x30, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, 0xb3, 0x0, 0x0, 0x0, 0x0, 0x26, - 0x66, 0x6d, 0x86, 0x6a, 0xc0, 0x0, 0x0, 0x10, - 0x0, 0xb3, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0xb, 0x30, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0xb3, 0x0, 0x0, 0x80, 0x8, 0x66, 0x66, 0x6d, - 0x66, 0x66, 0x7a, 0x40, 0x0, 0x0, 0x5, 0xe3, - 0x0, 0x0, 0x0, 0x0, 0x0, 0x1, 0xc2, 0x0, - 0x0, 0x0, 0x0, 0x0, 0x0, 0xa3, 0x0, 0x37, - 0x0, 0x0, 0x0, 0x0, 0x92, 0x0, 0x0, 0x3d, - 0x30, 0x0, 0x3, 0xd8, 0x77, 0x77, 0x76, 0x9f, - 0x20, 0x0, 0xb, 0x85, 0x32, 0x0, 0x0, 0xb4, - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - - /* U+53C2 "参" */ - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x0, 0x4c, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x6, 0xa2, 0x1, 0x50, 0x0, 0x0, - 0x0, 0x3, 0x74, 0x0, 0x0, 0x3c, 0x60, 0x0, - 0x0, 0xd, 0xb9, 0xbc, 0x65, 0x54, 0xe2, 0x0, - 0x0, 0x0, 0x0, 0xc3, 0x0, 0x0, 0x23, 0x40, - 0x6, 0x66, 0x6a, 0xb6, 0x69, 0x66, 0x67, 0x70, - 0x0, 0x0, 0x2c, 0x1, 0x44, 0x60, 0x0, 0x0, - 0x0, 0x1, 0xb1, 0x1c, 0x90, 0x5b, 0x20, 0x0, - 0x0, 0x39, 0x12, 0xc5, 0x4, 0x13, 0xdc, 0x71, - 0x5, 0x50, 0x68, 0x10, 0x5e, 0x50, 0x6, 0x40, - 0x0, 0x16, 0x10, 0x8, 0xa1, 0x4, 0x30, 0x0, - 0x0, 0x0, 0x6, 0x93, 0x0, 0x7e, 0x60, 0x0, - 0x0, 0x15, 0x62, 0x0, 0x4c, 0x91, 0x0, 0x0, - 0x0, 0x0, 0x1, 0x6c, 0x92, 0x0, 0x0, 0x0, - 0x1, 0x57, 0x88, 0x50, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - - /* U+53C3 "參" */ - 0x0, 0x0, 0x0, 0x2, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x0, 0x8b, 0x3, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x27, 0x30, 0x2, 0xd5, 0x0, 0x0, - 0x0, 0x0, 0x7a, 0x86, 0x43, 0x4a, 0x0, 0x0, - 0x0, 0x6, 0x80, 0x0, 0x0, 0xb4, 0x10, 0x0, - 0x0, 0xa, 0x5, 0x0, 0x19, 0x30, 0x34, 0x0, - 0x0, 0x71, 0x6, 0x52, 0x5f, 0xed, 0xbd, 0x0, - 0x1, 0xb7, 0x45, 0xbe, 0x65, 0x0, 0x9, 0x0, - 0x0, 0x0, 0x6, 0xb2, 0x36, 0x20, 0x0, 0x0, - 0x0, 0x5, 0x83, 0x7, 0xc1, 0x7b, 0xa8, 0x60, - 0x4, 0x40, 0x16, 0xa6, 0x27, 0x10, 0x37, 0x0, - 0x0, 0x25, 0x51, 0x5, 0xda, 0x30, 0x0, 0x0, - 0x0, 0x0, 0x28, 0xa7, 0x10, 0x6c, 0x10, 0x0, - 0x0, 0x57, 0x51, 0x0, 0x4c, 0xb4, 0x10, 0x0, - 0x0, 0x0, 0x2, 0x7c, 0xa3, 0x0, 0x0, 0x0, - 0x1, 0x67, 0x98, 0x40, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - - /* U+53C8 "又" */ - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x10, 0x0, - 0x0, 0x47, 0x76, 0x66, 0x66, 0x6a, 0xb0, 0x0, - 0x0, 0x0, 0x41, 0x0, 0x0, 0xb, 0x30, 0x0, - 0x0, 0x0, 0x5, 0x0, 0x0, 0x1d, 0x0, 0x0, - 0x0, 0x0, 0x7, 0x0, 0x0, 0x77, 0x0, 0x0, - 0x0, 0x0, 0x6, 0x10, 0x0, 0xc1, 0x0, 0x0, - 0x0, 0x0, 0x1, 0x80, 0x5, 0x90, 0x0, 0x0, - 0x0, 0x0, 0x0, 0x82, 0xd, 0x10, 0x0, 0x0, - 0x0, 0x0, 0x0, 0x1b, 0x97, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x0, 0x8, 0xe0, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x0, 0x5b, 0x7b, 0x10, 0x0, 0x0, - 0x0, 0x0, 0x8, 0x90, 0x5, 0xd6, 0x0, 0x0, - 0x0, 0x3, 0x94, 0x0, 0x0, 0x2c, 0xe9, 0x51, - 0x2, 0x65, 0x0, 0x0, 0x0, 0x0, 0x5c, 0x70, - 0x2, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - - /* U+53CA "及" */ - 0x0, 0x0, 0x0, 0x0, 0x0, 0x2, 0x0, 0x0, - 0x0, 0x6, 0x67, 0xb6, 0x66, 0xad, 0x0, 0x0, - 0x0, 0x0, 0x4, 0x90, 0x0, 0xa5, 0x0, 0x0, - 0x0, 0x0, 0x6, 0x70, 0x0, 0xd0, 0x0, 0x0, - 0x0, 0x0, 0x9, 0x80, 0x6, 0x80, 0x0, 0x0, - 0x0, 0x0, 0xc, 0x60, 0xb, 0x86, 0xc7, 0x0, - 0x0, 0x0, 0xd, 0x16, 0x0, 0x1, 0xe1, 0x0, - 0x0, 0x0, 0x48, 0x8, 0x0, 0x8, 0x70, 0x0, - 0x0, 0x0, 0xa3, 0x3, 0x70, 0x2c, 0x0, 0x0, - 0x0, 0x1, 0xb0, 0x0, 0xa4, 0xc3, 0x0, 0x0, - 0x0, 0x9, 0x30, 0x0, 0x1f, 0x70, 0x0, 0x0, - 0x0, 0x57, 0x0, 0x1, 0xb8, 0xd3, 0x0, 0x0, - 0x2, 0x70, 0x0, 0x79, 0x20, 0x3d, 0xa4, 0x0, - 0x15, 0x3, 0x67, 0x20, 0x0, 0x0, 0x8f, 0x90, - 0x0, 0x22, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - - /* U+53CB "友" */ - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x0, 0xe3, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x0, 0xf1, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x2, 0xd0, 0x0, 0x0, 0x9, 0x30, - 0x6, 0x76, 0x69, 0xc6, 0x66, 0x66, 0x67, 0x50, - 0x0, 0x0, 0x8, 0x70, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, 0xb, 0x40, 0x0, 0x2, 0x10, 0x0, - 0x0, 0x0, 0xe, 0x86, 0x66, 0x6d, 0x80, 0x0, - 0x0, 0x0, 0x4a, 0x16, 0x0, 0x1e, 0x0, 0x0, - 0x0, 0x0, 0xa4, 0x8, 0x0, 0x88, 0x0, 0x0, - 0x0, 0x2, 0xb0, 0x2, 0x91, 0xd1, 0x0, 0x0, - 0x0, 0xa, 0x30, 0x0, 0x7d, 0x50, 0x0, 0x0, - 0x0, 0x38, 0x0, 0x0, 0xac, 0xa1, 0x0, 0x0, - 0x0, 0x90, 0x0, 0x3b, 0x50, 0x5e, 0x82, 0x0, - 0x7, 0x10, 0x38, 0x70, 0x0, 0x2, 0xaf, 0xa1, - 0x11, 0x4, 0x20, 0x0, 0x0, 0x0, 0x2, 0x0, - - /* U+53CD "反" */ - 0x0, 0x0, 0x0, 0x0, 0x0, 0x26, 0xa1, 0x0, - 0x0, 0x6, 0x46, 0x78, 0x9a, 0xa8, 0x73, 0x0, - 0x0, 0xa, 0x40, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0xa, 0x30, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0xa, 0x30, 0x0, 0x0, 0x0, 0x30, 0x0, - 0x0, 0xa, 0x86, 0x86, 0x66, 0x66, 0xf5, 0x0, - 0x0, 0xa, 0x30, 0x70, 0x0, 0x6, 0xc0, 0x0, - 0x0, 0xb, 0x20, 0x53, 0x0, 0xd, 0x30, 0x0, - 0x0, 0xc, 0x10, 0xa, 0x0, 0x89, 0x0, 0x0, - 0x0, 0xd, 0x0, 0x2, 0xa4, 0xd0, 0x0, 0x0, - 0x0, 0x3a, 0x0, 0x0, 0x7f, 0x30, 0x0, 0x0, - 0x0, 0x93, 0x0, 0x4, 0xc9, 0xc3, 0x0, 0x0, - 0x1, 0x90, 0x2, 0x98, 0x0, 0x3e, 0xb5, 0x0, - 0x7, 0x3, 0x76, 0x0, 0x0, 0x0, 0x8f, 0xc2, - 0x10, 0x11, 0x0, 0x0, 0x0, 0x0, 0x1, 0x0, - - /* U+53D6 "取" */ - 0x0, 0x0, 0x0, 0x17, 0x0, 0x0, 0x0, 0x0, - 0x16, 0xd6, 0x66, 0xe6, 0x10, 0x0, 0x0, 0x0, - 0x0, 0xc0, 0x0, 0xd3, 0x66, 0x66, 0x8b, 0x0, - 0x0, 0xc0, 0x0, 0xd0, 0x22, 0x0, 0x89, 0x0, - 0x0, 0xc6, 0x66, 0xd0, 0x5, 0x0, 0xb4, 0x0, - 0x0, 0xc0, 0x0, 0xd0, 0x7, 0x0, 0xe0, 0x0, - 0x0, 0xc0, 0x0, 0xd0, 0x8, 0x4, 0xa0, 0x0, - 0x0, 0xc6, 0x66, 0xd0, 0x5, 0x3a, 0x50, 0x0, - 0x0, 0xc0, 0x0, 0xd0, 0x1, 0xad, 0x0, 0x0, - 0x0, 0xc0, 0x14, 0xe6, 0x30, 0xb7, 0x0, 0x0, - 0x17, 0xec, 0x84, 0xd0, 0x1, 0xdc, 0x0, 0x0, - 0x1a, 0x30, 0x0, 0xd0, 0xa, 0x25, 0xc2, 0x0, - 0x0, 0x0, 0x0, 0xd0, 0x83, 0x0, 0x7f, 0x90, - 0x0, 0x0, 0x0, 0xd6, 0x20, 0x0, 0x5, 0x30, - 0x0, 0x0, 0x0, 0x20, 0x0, 0x0, 0x0, 0x0, - - /* U+53D7 "受" */ - 0x0, 0x0, 0x0, 0x0, 0x2, 0x5a, 0xb0, 0x0, - 0x0, 0x25, 0x66, 0x89, 0xa9, 0x87, 0x51, 0x0, - 0x0, 0x3, 0x0, 0x33, 0x0, 0xb, 0x60, 0x0, - 0x0, 0x5, 0xa0, 0xd, 0x30, 0x1c, 0x0, 0x0, - 0x0, 0x30, 0xe1, 0x9, 0x60, 0x82, 0x2, 0x0, - 0x0, 0xa6, 0x86, 0x67, 0x66, 0x76, 0x6c, 0xb0, - 0x4, 0xc0, 0x0, 0x0, 0x0, 0x0, 0xa, 0x10, - 0x6, 0x44, 0x66, 0x66, 0x66, 0xa8, 0x20, 0x0, - 0x0, 0x0, 0x6, 0x0, 0x1, 0xe4, 0x0, 0x0, - 0x0, 0x0, 0x1, 0x80, 0xa, 0x60, 0x0, 0x0, - 0x0, 0x0, 0x0, 0x67, 0x99, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x0, 0x1e, 0xe1, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x7, 0xb3, 0x4d, 0x94, 0x20, 0x0, - 0x0, 0x37, 0x83, 0x0, 0x0, 0x5b, 0xff, 0x91, - 0x4, 0x20, 0x0, 0x0, 0x0, 0x0, 0x2, 0x0, - - /* U+53E3 "口" */ - 0x0, 0x0, 0x0, 0x0, 0x0, 0xc, 0x66, 0x66, - 0x66, 0x66, 0xe3, 0xe0, 0x0, 0x0, 0x0, 0xe, - 0xe, 0x0, 0x0, 0x0, 0x0, 0xe0, 0xe0, 0x0, - 0x0, 0x0, 0xe, 0xe, 0x0, 0x0, 0x0, 0x0, - 0xe0, 0xe0, 0x0, 0x0, 0x0, 0xe, 0xe, 0x0, - 0x0, 0x0, 0x0, 0xe0, 0xe0, 0x0, 0x0, 0x0, - 0xe, 0xe, 0x0, 0x0, 0x0, 0x0, 0xe0, 0xe6, - 0x66, 0x66, 0x66, 0x6e, 0xd, 0x0, 0x0, 0x0, - 0x0, 0x80, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - - /* U+53E4 "古" */ - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x0, 0xc1, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, 0xe, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, 0xe0, 0x0, 0x0, 0x20, 0x47, 0x66, - 0x66, 0x6e, 0x66, 0x66, 0x9b, 0x10, 0x0, 0x0, - 0x0, 0xe0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0xe, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0xe0, 0x0, 0x0, 0x0, 0x0, 0x19, 0x66, 0x6e, - 0x66, 0x6b, 0x20, 0x0, 0x1, 0xd0, 0x0, 0x0, - 0x0, 0xe0, 0x0, 0x0, 0xd, 0x0, 0x0, 0x0, - 0xe, 0x0, 0x0, 0x0, 0xd0, 0x0, 0x0, 0x0, - 0xe0, 0x0, 0x0, 0xd, 0x0, 0x0, 0x0, 0xe, - 0x0, 0x0, 0x1, 0xe6, 0x66, 0x66, 0x66, 0xe0, - 0x0, 0x0, 0x1d, 0x0, 0x0, 0x0, 0xe, 0x0, - 0x0, 0x0, 0x30, 0x0, 0x0, 0x0, 0x10, 0x0, - - /* U+53E5 "句" */ - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x2, 0xe2, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x89, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x1e, 0x76, 0x66, 0x66, 0x66, 0xb6, 0x0, 0xa, - 0x40, 0x0, 0x0, 0x0, 0xa, 0x30, 0x4, 0x80, - 0x0, 0x0, 0x0, 0x0, 0xa3, 0x2, 0x71, 0x20, - 0x0, 0x6, 0x0, 0xa, 0x30, 0x50, 0x3d, 0x66, - 0x66, 0xf1, 0x0, 0xa3, 0x0, 0x2, 0xb0, 0x0, - 0xe, 0x0, 0xa, 0x30, 0x0, 0x2b, 0x0, 0x0, - 0xe0, 0x0, 0xa3, 0x0, 0x2, 0xd6, 0x66, 0x6e, - 0x0, 0xa, 0x30, 0x0, 0x3b, 0x0, 0x0, 0x80, - 0x0, 0xb2, 0x0, 0x0, 0x10, 0x0, 0x0, 0x0, - 0xc, 0x10, 0x0, 0x0, 0x0, 0x0, 0x21, 0x2, - 0xd0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x6d, 0xf6, - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x43, 0x0, - - /* U+53E6 "另" */ - 0x0, 0x9, 0x66, 0x66, 0x66, 0x6b, 0x0, 0x0, - 0xe, 0x0, 0x0, 0x0, 0x2c, 0x0, 0x0, 0xe, - 0x0, 0x0, 0x0, 0x2b, 0x0, 0x0, 0xe, 0x0, - 0x0, 0x0, 0x2b, 0x0, 0x0, 0xe, 0x66, 0x66, - 0x66, 0x7b, 0x0, 0x0, 0xc, 0x0, 0x94, 0x0, - 0x27, 0x0, 0x0, 0x0, 0x0, 0xd3, 0x0, 0x0, - 0x10, 0x6, 0x66, 0x66, 0xe6, 0x66, 0x67, 0xe0, - 0x0, 0x0, 0x0, 0xe0, 0x0, 0x3, 0xb0, 0x0, - 0x0, 0x3, 0xa0, 0x0, 0x3, 0xa0, 0x0, 0x0, - 0x9, 0x40, 0x0, 0x4, 0xa0, 0x0, 0x0, 0x4a, - 0x0, 0x0, 0x5, 0x80, 0x0, 0x6, 0x90, 0x0, - 0x12, 0xa, 0x60, 0x4, 0x73, 0x0, 0x0, 0x5, - 0xee, 0x10, 0x31, 0x0, 0x0, 0x0, 0x0, 0x21, - 0x0, - - /* U+53EA "只" */ - 0x0, 0x4, 0x0, 0x0, 0x0, 0x52, 0x0, 0x0, - 0xe6, 0x66, 0x66, 0x6c, 0x50, 0x0, 0xd, 0x0, - 0x0, 0x0, 0xa3, 0x0, 0x0, 0xd0, 0x0, 0x0, - 0xa, 0x30, 0x0, 0xd, 0x0, 0x0, 0x0, 0xa3, - 0x0, 0x0, 0xd0, 0x0, 0x0, 0xa, 0x30, 0x0, - 0xd, 0x0, 0x0, 0x0, 0xa3, 0x0, 0x1, 0xe6, - 0x66, 0x66, 0x6c, 0x30, 0x0, 0x17, 0x4, 0x0, - 0x20, 0x30, 0x0, 0x0, 0x7, 0xd1, 0x1, 0x91, - 0x0, 0x0, 0x2, 0xd2, 0x0, 0x3, 0xd3, 0x0, - 0x0, 0xb3, 0x0, 0x0, 0x6, 0xf2, 0x0, 0x93, - 0x0, 0x0, 0x0, 0xc, 0x90, 0x82, 0x0, 0x0, - 0x0, 0x0, 0x37, 0x10, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, - - /* U+53EB "叫" */ - 0x0, 0x0, 0x0, 0x0, 0x0, 0x1, 0xb1, 0x0, - 0x0, 0x0, 0x1, 0x10, 0x0, 0xd0, 0x1c, 0x66, - 0xc6, 0x3, 0xd0, 0x0, 0xd0, 0xd, 0x0, 0xb2, - 0x2, 0xb0, 0x0, 0xd0, 0xd, 0x0, 0xb2, 0x2, - 0xb0, 0x0, 0xd0, 0xd, 0x0, 0xb2, 0x2, 0xb0, - 0x0, 0xd0, 0xd, 0x0, 0xb2, 0x2, 0xb0, 0x0, - 0xd0, 0xd, 0x0, 0xb2, 0x2, 0xb0, 0x0, 0xd0, - 0xd, 0x0, 0xb2, 0x3, 0xb3, 0x76, 0xd0, 0xe, - 0x66, 0xd2, 0x3, 0xf7, 0x0, 0xd0, 0x1d, 0x0, - 0x91, 0x0, 0x10, 0x0, 0xd0, 0x6, 0x0, 0x0, - 0x0, 0x0, 0x0, 0xd0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, 0xd0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x1, 0xe0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x30, - - /* U+53EF "可" */ - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x2, 0x0, - 0x6, 0x66, 0x66, 0x66, 0x66, 0x66, 0x6d, 0x90, - 0x1, 0x0, 0x0, 0x0, 0x0, 0xc, 0x10, 0x0, - 0x0, 0x0, 0x0, 0x0, 0x0, 0xc, 0x10, 0x0, - 0x0, 0xb, 0x66, 0x6c, 0x50, 0xc, 0x10, 0x0, - 0x0, 0xe, 0x0, 0xb, 0x20, 0xc, 0x10, 0x0, - 0x0, 0xe, 0x0, 0xb, 0x20, 0xc, 0x10, 0x0, - 0x0, 0xe, 0x0, 0xb, 0x20, 0xc, 0x10, 0x0, - 0x0, 0xe, 0x0, 0xb, 0x20, 0xc, 0x10, 0x0, - 0x0, 0xe, 0x66, 0x6d, 0x30, 0xc, 0x10, 0x0, - 0x0, 0xe, 0x0, 0x6, 0x10, 0xc, 0x10, 0x0, - 0x0, 0x2, 0x0, 0x0, 0x0, 0xc, 0x10, 0x0, - 0x0, 0x0, 0x0, 0x0, 0x25, 0x4e, 0x0, 0x0, - 0x0, 0x0, 0x0, 0x0, 0x3, 0xcb, 0x0, 0x0, - 0x0, 0x0, 0x0, 0x0, 0x0, 0x10, 0x0, 0x0, - - /* U+53F0 "台" */ - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0xd4, 0x0, 0x0, 0x0, 0x0, 0x0, 0xaa, - 0x10, 0x0, 0x0, 0x0, 0x0, 0x6a, 0x0, 0x0, - 0x0, 0x0, 0x0, 0x4a, 0x0, 0x0, 0x65, 0x0, - 0x0, 0x4a, 0x0, 0x0, 0x0, 0x7b, 0x20, 0x8e, - 0x55, 0x66, 0x77, 0x66, 0xce, 0x16, 0xd9, 0x64, - 0x21, 0x0, 0x0, 0xc1, 0x0, 0x0, 0x0, 0x0, - 0x1, 0x0, 0x0, 0x1d, 0x66, 0x66, 0x66, 0xc6, - 0x0, 0x0, 0xd0, 0x0, 0x0, 0xb, 0x30, 0x0, - 0xd, 0x0, 0x0, 0x0, 0xb3, 0x0, 0x0, 0xd0, - 0x0, 0x0, 0xb, 0x30, 0x0, 0xd, 0x0, 0x0, - 0x0, 0xb3, 0x0, 0x0, 0xe6, 0x66, 0x66, 0x6c, - 0x30, 0x0, 0x4, 0x0, 0x0, 0x0, 0x30, 0x0, - - /* U+53F2 "史" */ - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x0, 0x0, 0xd1, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x0, 0x0, 0xe0, 0x0, 0x0, 0x0, - 0x0, 0x2, 0x0, 0x0, 0xe0, 0x0, 0x3, 0x0, - 0x0, 0xe, 0x66, 0x66, 0xe6, 0x66, 0x8d, 0x0, - 0x0, 0xd, 0x10, 0x0, 0xe0, 0x0, 0x3a, 0x0, - 0x0, 0xd, 0x10, 0x0, 0xe0, 0x0, 0x3a, 0x0, - 0x0, 0xd, 0x66, 0x66, 0xe6, 0x66, 0x8b, 0x0, - 0x0, 0xa, 0x0, 0x0, 0xc0, 0x0, 0x25, 0x0, - 0x0, 0x0, 0x24, 0x2, 0xa0, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x6, 0x46, 0x70, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x0, 0x8d, 0x30, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x0, 0x7d, 0xc5, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x2a, 0x80, 0x29, 0xeb, 0x86, 0x51, - 0x0, 0x48, 0x81, 0x0, 0x0, 0x5, 0x9c, 0x80, - 0x4, 0x10, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - - /* U+53F3 "右" */ - 0x0, 0x0, 0x0, 0x9, 0x20, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x0, 0x1e, 0x10, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x0, 0x69, 0x0, 0x0, 0x8, 0x30, - 0x7, 0x66, 0x66, 0xd7, 0x66, 0x66, 0x67, 0x60, - 0x0, 0x0, 0x2, 0xd0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x9, 0x60, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x2d, 0x0, 0x0, 0x0, 0x10, 0x0, - 0x0, 0x0, 0xad, 0x66, 0x66, 0x66, 0xf2, 0x0, - 0x0, 0x6, 0x6c, 0x10, 0x0, 0x0, 0xe0, 0x0, - 0x0, 0x38, 0xc, 0x10, 0x0, 0x0, 0xe0, 0x0, - 0x2, 0x70, 0xc, 0x10, 0x0, 0x0, 0xe0, 0x0, - 0x14, 0x0, 0xc, 0x10, 0x0, 0x0, 0xe0, 0x0, - 0x0, 0x0, 0xd, 0x66, 0x66, 0x66, 0xe0, 0x0, - 0x0, 0x0, 0xc, 0x0, 0x0, 0x0, 0xc0, 0x0, - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - - /* U+53F7 "号" */ - 0x0, 0x9, 0x66, 0x66, 0x66, 0xb3, 0x0, 0x0, - 0xe, 0x0, 0x0, 0x0, 0xe0, 0x0, 0x0, 0xe, - 0x0, 0x0, 0x0, 0xe0, 0x0, 0x0, 0xe, 0x0, - 0x0, 0x0, 0xe0, 0x0, 0x0, 0xe, 0x66, 0x66, - 0x66, 0xe0, 0x0, 0x0, 0x5, 0x0, 0x0, 0x0, - 0x10, 0x31, 0x56, 0x66, 0x89, 0x66, 0x66, 0x66, - 0x97, 0x0, 0x0, 0xa5, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x3, 0xe0, 0x0, 0x0, 0x34, 0x0, 0x0, - 0x3, 0x96, 0x66, 0x66, 0xca, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x0, 0xc3, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, 0xf0, 0x0, 0x0, 0x0, 0x0, 0x20, - 0x5, 0xc0, 0x0, 0x0, 0x0, 0x0, 0x2b, 0xdf, - 0x40, 0x0, 0x0, 0x0, 0x0, 0x0, 0x72, 0x0, - 0x0, - - /* U+53F8 "司" */ - 0x0, 0x0, 0x0, 0x0, 0x0, 0x3, 0x0, 0x27, - 0x66, 0x66, 0x66, 0x66, 0xe3, 0x0, 0x0, 0x0, - 0x0, 0x0, 0xd, 0x0, 0x0, 0x0, 0x0, 0x4, - 0x20, 0xd0, 0x46, 0x66, 0x66, 0x66, 0x76, 0xd, - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xd0, 0x0, - 0xb6, 0x66, 0x6e, 0x20, 0xd, 0x0, 0xc, 0x10, - 0x0, 0xe0, 0x0, 0xd0, 0x0, 0xc1, 0x0, 0xe, - 0x0, 0xd, 0x0, 0xc, 0x10, 0x0, 0xe0, 0x0, - 0xd0, 0x0, 0xc6, 0x66, 0x6e, 0x0, 0xd, 0x0, - 0x8, 0x0, 0x0, 0x40, 0x0, 0xd0, 0x0, 0x0, - 0x0, 0x0, 0x0, 0xe, 0x0, 0x0, 0x0, 0x0, - 0x2, 0x8e, 0xd0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x32, 0x0, - - /* U+5403 "吃" */ - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, 0xa, 0x50, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x1f, 0x20, 0x0, 0x0, 0x96, 0x6b, 0x50, - 0x77, 0x0, 0x0, 0x30, 0xd1, 0xb, 0x30, 0xc6, - 0x66, 0x66, 0xa4, 0xd1, 0xb, 0x36, 0x40, 0x0, - 0x0, 0x0, 0xc1, 0xb, 0x46, 0x0, 0x0, 0x30, - 0x0, 0xc1, 0xb, 0x54, 0x66, 0x67, 0xf5, 0x0, - 0xc1, 0xb, 0x30, 0x0, 0xc, 0x60, 0x0, 0xc1, - 0xb, 0x30, 0x0, 0xa8, 0x0, 0x0, 0xd6, 0x6c, - 0x30, 0x8, 0xa0, 0x0, 0x0, 0xd1, 0x5, 0x10, - 0x5c, 0x0, 0x0, 0x60, 0x10, 0x0, 0x1, 0xe1, - 0x0, 0x0, 0x70, 0x0, 0x0, 0x5, 0xb0, 0x0, - 0x0, 0xa6, 0x0, 0x0, 0x1, 0xcc, 0xcc, 0xcc, - 0xf6, - - /* U+5404 "各" */ - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x8, 0x90, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x1f, 0x86, 0x66, 0xb4, 0x0, 0x0, - 0x0, 0x0, 0xb8, 0x0, 0x3, 0xd1, 0x0, 0x0, - 0x0, 0x7, 0x63, 0x40, 0xc, 0x30, 0x0, 0x0, - 0x0, 0x55, 0x0, 0x82, 0x88, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x0, 0xc, 0xc0, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x0, 0x89, 0xb9, 0x20, 0x0, 0x0, - 0x0, 0x0, 0x2a, 0x50, 0x5, 0xdc, 0x74, 0x10, - 0x0, 0x7, 0xd6, 0x66, 0x66, 0xa8, 0xbe, 0x60, - 0x5, 0x61, 0xd1, 0x0, 0x0, 0xb3, 0x0, 0x0, - 0x0, 0x0, 0xd1, 0x0, 0x0, 0xb2, 0x0, 0x0, - 0x0, 0x0, 0xd1, 0x0, 0x0, 0xb2, 0x0, 0x0, - 0x0, 0x0, 0xd1, 0x0, 0x0, 0xb2, 0x0, 0x0, - 0x0, 0x0, 0xd6, 0x66, 0x66, 0xd3, 0x0, 0x0, - 0x0, 0x0, 0x70, 0x0, 0x0, 0x50, 0x0, 0x0, - - /* U+5408 "合" */ - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x0, 0x9, 0x70, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x0, 0x2f, 0x80, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x0, 0xb6, 0x37, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x8, 0x90, 0x7, 0x70, 0x0, 0x0, - 0x0, 0x0, 0x6a, 0x0, 0x0, 0x8a, 0x10, 0x0, - 0x0, 0x9, 0x70, 0x0, 0x0, 0x38, 0xea, 0x40, - 0x4, 0x82, 0x76, 0x66, 0x66, 0x98, 0x2b, 0x91, - 0x12, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x30, 0x0, 0x0, 0x6, 0x0, 0x0, - 0x0, 0x0, 0xf6, 0x66, 0x66, 0x6f, 0x10, 0x0, - 0x0, 0x0, 0xe0, 0x0, 0x0, 0xe, 0x0, 0x0, - 0x0, 0x0, 0xe0, 0x0, 0x0, 0xe, 0x0, 0x0, - 0x0, 0x0, 0xe6, 0x66, 0x66, 0x6e, 0x0, 0x0, - 0x0, 0x0, 0xe0, 0x0, 0x0, 0xc, 0x0, 0x0, - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - - /* U+540C "同" */ - 0x40, 0x0, 0x0, 0x0, 0x0, 0x5, 0xd, 0x66, - 0x66, 0x66, 0x66, 0x66, 0xe2, 0xd1, 0x0, 0x0, - 0x0, 0x0, 0xe, 0xc, 0x15, 0x66, 0x66, 0x6b, - 0x90, 0xe0, 0xc1, 0x10, 0x0, 0x0, 0x0, 0xe, - 0xc, 0x10, 0x20, 0x0, 0x3, 0x0, 0xe0, 0xc1, - 0xd, 0x66, 0x66, 0xe1, 0xe, 0xc, 0x10, 0xd0, - 0x0, 0xd, 0x0, 0xe0, 0xc1, 0xd, 0x0, 0x0, - 0xd0, 0xe, 0xc, 0x10, 0xd6, 0x66, 0x6d, 0x0, - 0xe0, 0xc1, 0xc, 0x0, 0x0, 0xa0, 0xe, 0xc, - 0x10, 0x0, 0x0, 0x0, 0x0, 0xe0, 0xd1, 0x0, - 0x0, 0x0, 0x22, 0x3e, 0xe, 0x10, 0x0, 0x0, - 0x1, 0x7f, 0xa0, 0x30, 0x0, 0x0, 0x0, 0x0, - 0x30, 0x0, - - /* U+540D "名" */ - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, 0xb3, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x4, 0xd0, 0x0, 0x1, 0x0, 0x0, 0x0, 0xd, - 0x86, 0x66, 0x6c, 0xb0, 0x0, 0x0, 0x77, 0x0, - 0x0, 0x3e, 0x10, 0x0, 0x4, 0x98, 0x10, 0x1, - 0xd4, 0x0, 0x0, 0x47, 0x3, 0xe1, 0x1d, 0x50, - 0x0, 0x1, 0x30, 0x0, 0x72, 0xd5, 0x0, 0x0, - 0x0, 0x0, 0x0, 0x3d, 0x30, 0x0, 0x0, 0x0, - 0x0, 0xb, 0xe7, 0x66, 0x66, 0xb2, 0x0, 0x5, - 0xae, 0x10, 0x0, 0x0, 0xe0, 0x5, 0x63, 0xc, - 0x10, 0x0, 0x0, 0xe0, 0x0, 0x0, 0xc, 0x10, - 0x0, 0x0, 0xe0, 0x0, 0x0, 0xc, 0x66, 0x66, - 0x66, 0xe0, 0x0, 0x0, 0xc, 0x10, 0x0, 0x0, - 0x90, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - - /* U+5411 "向" */ - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x6, 0x90, 0x0, 0x0, 0x0, 0x0, 0x0, 0xa4, - 0x0, 0x0, 0x0, 0x4, 0x0, 0x8, 0x0, 0x0, - 0x0, 0x60, 0xd6, 0x66, 0x66, 0x66, 0x66, 0x6f, - 0x1c, 0x10, 0x0, 0x0, 0x0, 0x0, 0xe0, 0xc1, - 0x3, 0x0, 0x0, 0x40, 0xe, 0xc, 0x10, 0xd6, - 0x66, 0x8d, 0x0, 0xe0, 0xc1, 0xc, 0x10, 0x3, - 0xa0, 0xe, 0xc, 0x10, 0xc1, 0x0, 0x3a, 0x0, - 0xe0, 0xc1, 0xd, 0x66, 0x68, 0xa0, 0xe, 0xc, - 0x10, 0xd1, 0x0, 0x39, 0x0, 0xe0, 0xc1, 0x1, - 0x0, 0x0, 0x0, 0xe, 0xc, 0x10, 0x0, 0x0, - 0x2, 0x34, 0xd0, 0xd1, 0x0, 0x0, 0x0, 0x15, - 0xea, 0x4, 0x0, 0x0, 0x0, 0x0, 0x2, 0x0, - - /* U+5426 "否" */ - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x81, 0x18, - 0x66, 0x66, 0x9c, 0x66, 0x66, 0x85, 0x0, 0x0, - 0x1, 0xe8, 0x0, 0x0, 0x0, 0x0, 0x0, 0x1c, - 0x6c, 0x31, 0x0, 0x0, 0x0, 0x1, 0xc4, 0x2b, - 0x6, 0x94, 0x0, 0x0, 0x4b, 0x20, 0x2b, 0x0, - 0x1b, 0xc1, 0x17, 0x60, 0x0, 0x3b, 0x0, 0x0, - 0x89, 0x30, 0x0, 0x0, 0x26, 0x0, 0x1, 0x1, - 0x0, 0xd, 0x66, 0x66, 0x66, 0x7e, 0x10, 0x0, - 0xf, 0x0, 0x0, 0x0, 0x2c, 0x0, 0x0, 0xf, - 0x0, 0x0, 0x0, 0x2c, 0x0, 0x0, 0xf, 0x0, - 0x0, 0x0, 0x2c, 0x0, 0x0, 0xf, 0x66, 0x66, - 0x66, 0x7c, 0x0, 0x0, 0xf, 0x0, 0x0, 0x0, - 0x2d, 0x0, 0x0, 0x4, 0x0, 0x0, 0x0, 0x1, - 0x0, - - /* U+5427 "吧" */ - 0x0, 0x0, 0x0, 0x95, 0x55, 0x55, 0xa1, 0x3, - 0xb6, 0x6d, 0xe, 0x11, 0xe1, 0x2c, 0x0, 0x2b, - 0x2, 0xc0, 0xe0, 0xe, 0x2, 0xc0, 0x2, 0xb0, - 0x2c, 0xe, 0x0, 0xe0, 0x2c, 0x0, 0x2b, 0x2, - 0xc0, 0xe0, 0xe, 0x2, 0xc0, 0x2, 0xb0, 0x2c, - 0xe, 0x0, 0xe0, 0x2c, 0x0, 0x2b, 0x2, 0xc0, - 0xe6, 0x66, 0x67, 0xc0, 0x2, 0xb0, 0x2c, 0xe, - 0x0, 0x0, 0x1, 0x0, 0x3d, 0x67, 0xc0, 0xe0, - 0x0, 0x0, 0x0, 0x3, 0xb0, 0x2c, 0xe, 0x0, - 0x0, 0x0, 0x50, 0x38, 0x0, 0x10, 0xe0, 0x0, - 0x0, 0x7, 0x0, 0x0, 0x0, 0xd, 0x0, 0x0, - 0x0, 0xd1, 0x0, 0x0, 0x0, 0x8d, 0xcc, 0xcc, - 0xdd, 0x20, - - /* U+5440 "呀" */ - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x20, 0x2, - 0x0, 0x3, 0x27, 0x66, 0x69, 0x7b, 0x20, 0xb7, - 0x66, 0xe0, 0x30, 0x0, 0xe0, 0x0, 0xb, 0x20, - 0x1d, 0xb, 0x60, 0xe, 0x0, 0x0, 0xb2, 0x1, - 0xd0, 0xd0, 0x0, 0xe0, 0x0, 0xb, 0x20, 0x1d, - 0x3a, 0x0, 0xe, 0x5, 0x30, 0xb2, 0x1, 0xd5, - 0x86, 0x7e, 0xe6, 0x65, 0xb, 0x20, 0x1d, 0x0, - 0x9, 0x7e, 0x0, 0x0, 0xb7, 0x66, 0xd0, 0x2, - 0xd0, 0xe0, 0x0, 0xb, 0x20, 0x9, 0x0, 0xc3, - 0xe, 0x0, 0x0, 0x70, 0x0, 0x0, 0x95, 0x0, - 0xe0, 0x0, 0x0, 0x0, 0x0, 0x74, 0x0, 0xe, - 0x0, 0x0, 0x0, 0x0, 0x63, 0x2, 0x23, 0xe0, - 0x0, 0x0, 0x0, 0x40, 0x0, 0x16, 0xf9, 0x0, - 0x0, 0x0, 0x0, 0x0, 0x0, 0x2, 0x0, 0x0, - 0x0, - - /* U+544A "告" */ - 0x0, 0x2, 0x0, 0x1b, 0x10, 0x0, 0x0, 0x0, - 0xc, 0x60, 0x1e, 0x0, 0x0, 0x0, 0x0, 0x3b, - 0x0, 0xe, 0x0, 0x46, 0x0, 0x0, 0xa6, 0x66, - 0x6e, 0x66, 0x65, 0x0, 0x5, 0x40, 0x0, 0xe, - 0x0, 0x0, 0x0, 0x3, 0x0, 0x0, 0xe, 0x0, - 0x0, 0x50, 0x47, 0x66, 0x66, 0x6a, 0x66, 0x67, - 0xb5, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x1a, 0x66, 0x66, 0x66, 0xb6, 0x0, 0x0, - 0xd, 0x0, 0x0, 0x0, 0xa3, 0x0, 0x0, 0xd, - 0x0, 0x0, 0x0, 0xa3, 0x0, 0x0, 0xd, 0x0, - 0x0, 0x0, 0xa3, 0x0, 0x0, 0xe, 0x66, 0x66, - 0x66, 0xc3, 0x0, 0x0, 0xd, 0x0, 0x0, 0x0, - 0xa3, 0x0, 0x0, 0x4, 0x0, 0x0, 0x0, 0x0, - 0x0, - - /* U+5462 "呢" */ - 0x0, 0x0, 0x0, 0x30, 0x0, 0x0, 0x60, 0x86, - 0x6b, 0x21, 0xe6, 0x66, 0x66, 0xe1, 0xb2, 0xe, - 0x0, 0xd0, 0x0, 0x0, 0xe0, 0xb2, 0xe, 0x0, - 0xd0, 0x0, 0x0, 0xe0, 0xb2, 0xe, 0x0, 0xe6, - 0x66, 0x66, 0xe0, 0xb2, 0xe, 0x1, 0xc0, 0x20, - 0x0, 0x20, 0xb2, 0xe, 0x2, 0xb0, 0xe1, 0x1, - 0x40, 0xb2, 0xe, 0x4, 0x90, 0xd0, 0xb, 0xa0, - 0xb7, 0x6e, 0x7, 0x60, 0xd0, 0x96, 0x0, 0xb2, - 0xd, 0xb, 0x20, 0xe7, 0x30, 0x0, 0xc2, 0x2, - 0xc, 0x0, 0xe0, 0x0, 0x32, 0x10, 0x0, 0x75, - 0x0, 0xd0, 0x0, 0x44, 0x0, 0x0, 0x90, 0x0, - 0xe3, 0x11, 0x9a, 0x0, 0x7, 0x10, 0x0, 0x5a, - 0xaa, 0x93, 0x0, 0x12, 0x0, 0x0, 0x0, 0x0, - 0x0, - - /* U+5468 "周" */ - 0x0, 0x9, 0x66, 0x66, 0x66, 0x66, 0x6c, 0x10, - 0x0, 0xd0, 0x0, 0x4, 0x0, 0x0, 0xd0, 0x0, - 0xd, 0x0, 0x0, 0xd0, 0x0, 0xc, 0x0, 0x0, - 0xd0, 0x0, 0xc, 0x7, 0x0, 0xc0, 0x0, 0xd, - 0x5, 0x76, 0xd6, 0x63, 0xc, 0x0, 0x0, 0xd0, - 0x0, 0xc, 0x0, 0x50, 0xc0, 0x0, 0xd, 0x47, - 0x66, 0x76, 0x67, 0x2c, 0x0, 0x1, 0xc0, 0x13, - 0x0, 0x6, 0x0, 0xc0, 0x0, 0x3a, 0x1, 0xd6, - 0x66, 0xe1, 0xc, 0x0, 0x5, 0x60, 0x1b, 0x0, - 0xd, 0x0, 0xc0, 0x0, 0x92, 0x1, 0xb0, 0x0, - 0xd0, 0xc, 0x0, 0xa, 0x0, 0x1d, 0x66, 0x6d, - 0x0, 0xc0, 0x6, 0x30, 0x1, 0x40, 0x0, 0x30, - 0x2c, 0x1, 0x50, 0x0, 0x0, 0x0, 0x3, 0x9f, - 0x80, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x30, - 0x0, - - /* U+5473 "味" */ - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x0, 0xd, 0x20, 0x0, 0x0, 0x0, - 0x1, 0x0, 0x0, 0xe0, 0x0, 0x0, 0xb, 0x66, - 0xe2, 0x0, 0xd, 0x0, 0x71, 0x0, 0xd1, 0xe, - 0x6, 0x76, 0xe6, 0x66, 0x30, 0xc, 0x10, 0xe0, - 0x0, 0xd, 0x0, 0x0, 0x0, 0xc1, 0xe, 0x0, - 0x0, 0xd0, 0x0, 0x51, 0xc, 0x10, 0xe5, 0x76, - 0x9f, 0x86, 0x68, 0x60, 0xc1, 0xe, 0x0, 0xd, - 0xf4, 0x20, 0x0, 0xc, 0x66, 0xe0, 0x5, 0x9d, - 0x9, 0x0, 0x0, 0xd1, 0xb, 0x1, 0xc0, 0xd0, - 0x75, 0x0, 0x7, 0x0, 0x0, 0xa2, 0xd, 0x0, - 0xd5, 0x0, 0x0, 0x0, 0x83, 0x0, 0xd0, 0x3, - 0xfa, 0x10, 0x0, 0x72, 0x0, 0xd, 0x0, 0x4, - 0x10, 0x0, 0x30, 0x0, 0x0, 0xe0, 0x0, 0x0, - 0x0, 0x0, 0x0, 0x0, 0x5, 0x0, 0x0, 0x0, - - /* U+547C "呼" */ - 0x0, 0x0, 0x0, 0x0, 0x0, 0x5, 0x40, 0x1, - 0x0, 0x30, 0x1, 0x37, 0xac, 0xa7, 0x0, 0xb7, - 0x6e, 0x33, 0x42, 0x1e, 0x0, 0x0, 0xa, 0x20, - 0xe0, 0x41, 0x0, 0xe0, 0x9, 0x60, 0xa2, 0xe, - 0x0, 0xc1, 0xe, 0x2, 0xc0, 0xa, 0x20, 0xe0, - 0x8, 0x80, 0xe0, 0x91, 0x0, 0xa2, 0xe, 0x0, - 0x23, 0xe, 0x21, 0x1, 0xa, 0x20, 0xe4, 0x76, - 0x66, 0xe6, 0x69, 0xa0, 0xa2, 0xe, 0x0, 0x0, - 0xe, 0x0, 0x0, 0xa, 0x76, 0xe0, 0x0, 0x0, - 0xe0, 0x0, 0x0, 0xb2, 0xa, 0x0, 0x0, 0xe, - 0x0, 0x0, 0x2, 0x0, 0x0, 0x0, 0x0, 0xe0, - 0x0, 0x0, 0x0, 0x0, 0x0, 0x21, 0x1d, 0x0, - 0x0, 0x0, 0x0, 0x0, 0x1, 0x8f, 0x90, 0x0, - 0x0, 0x0, 0x0, 0x0, 0x0, 0x30, 0x0, 0x0, - 0x0, - - /* U+547D "命" */ - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x0, 0x7, 0xa0, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x0, 0x1e, 0x80, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x0, 0xc4, 0x18, 0x0, 0x0, 0x0, - 0x0, 0x0, 0xa, 0x50, 0x4, 0xa1, 0x0, 0x0, - 0x0, 0x0, 0xa4, 0x0, 0x1, 0x6d, 0x82, 0x0, - 0x0, 0x49, 0x37, 0x66, 0x66, 0x61, 0xaf, 0xb1, - 0x6, 0x40, 0x0, 0x10, 0x1, 0x0, 0x33, 0x0, - 0x0, 0xd, 0x66, 0xd2, 0xd, 0x66, 0xe3, 0x0, - 0x0, 0xd, 0x0, 0xd0, 0xd, 0x0, 0xd0, 0x0, - 0x0, 0xd, 0x0, 0xd0, 0xd, 0x0, 0xd0, 0x0, - 0x0, 0xd, 0x0, 0xd0, 0xd, 0x0, 0xd0, 0x0, - 0x0, 0xe, 0x66, 0xe0, 0xd, 0x0, 0xd0, 0x0, - 0x0, 0xd, 0x0, 0xa0, 0xd, 0x5c, 0xc0, 0x0, - 0x0, 0x5, 0x0, 0x0, 0xd, 0x1, 0x0, 0x0, - 0x0, 0x0, 0x0, 0x0, 0x4, 0x0, 0x0, 0x0, - - /* U+548C "和" */ - 0x0, 0x0, 0x0, 0x38, 0x0, 0x0, 0x0, 0x0, - 0x2, 0x48, 0xca, 0x81, 0x10, 0x0, 0x10, 0x0, - 0x31, 0xd, 0x0, 0xc, 0x66, 0x6c, 0x60, 0x0, - 0x0, 0xd0, 0x0, 0xc2, 0x0, 0xb3, 0x2, 0x66, - 0x6e, 0x6a, 0x5c, 0x20, 0xb, 0x30, 0x0, 0x8, - 0xd0, 0x0, 0xc2, 0x0, 0xb3, 0x0, 0x0, 0xde, - 0x50, 0xc, 0x20, 0xb, 0x30, 0x0, 0x68, 0xd4, - 0xd3, 0xc2, 0x0, 0xb3, 0x0, 0xb, 0xd, 0x4, - 0x8c, 0x20, 0xb, 0x30, 0x8, 0x20, 0xd0, 0x0, - 0xc2, 0x0, 0xb3, 0x4, 0x40, 0xd, 0x0, 0xc, - 0x76, 0x6c, 0x30, 0x30, 0x0, 0xd0, 0x0, 0xc2, - 0x0, 0xa3, 0x0, 0x0, 0xd, 0x0, 0x7, 0x0, - 0x0, 0x0, 0x0, 0x1, 0xe0, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x0, 0x1, 0x0, 0x0, 0x0, 0x0, - 0x0, - - /* U+54B2 "咲" */ - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x18, 0x0, 0x3, 0xb1, 0x0, 0x30, - 0x4, 0x0, 0x7b, 0x0, 0x97, 0x0, 0xe, 0x66, - 0xe2, 0x0, 0xe1, 0x9, 0x0, 0x0, 0xe0, 0xe, - 0x0, 0x2, 0x5, 0x11, 0x80, 0xe, 0x0, 0xe0, - 0x76, 0x6d, 0x76, 0x66, 0x20, 0xe0, 0xe, 0x0, - 0x0, 0xd1, 0x0, 0x0, 0xe, 0x0, 0xe0, 0x0, - 0xe, 0x0, 0x0, 0x10, 0xe0, 0xe, 0x57, 0x66, - 0xe6, 0x66, 0xaa, 0xe, 0x0, 0xe0, 0x0, 0x2c, - 0x60, 0x0, 0x0, 0xe6, 0x6e, 0x0, 0x6, 0x84, - 0x30, 0x0, 0xb, 0x0, 0x30, 0x0, 0xb3, 0xa, - 0x0, 0x0, 0x0, 0x0, 0x0, 0x4a, 0x0, 0x95, - 0x0, 0x0, 0x0, 0x0, 0x2a, 0x10, 0x1, 0xe4, - 0x0, 0x0, 0x0, 0x57, 0x0, 0x0, 0x5, 0xfa, - 0x0, 0x0, 0x41, 0x0, 0x0, 0x0, 0x4, 0x10, - - /* U+54C1 "品" */ - 0x0, 0x4, 0x0, 0x0, 0x2, 0x30, 0x0, 0x0, - 0xc, 0x76, 0x66, 0x69, 0xa0, 0x0, 0x0, 0xb, - 0x20, 0x0, 0x5, 0x70, 0x0, 0x0, 0xb, 0x20, - 0x0, 0x5, 0x70, 0x0, 0x0, 0xb, 0x20, 0x0, - 0x5, 0x80, 0x0, 0x0, 0xc, 0x76, 0x66, 0x69, - 0x80, 0x0, 0x0, 0x5, 0x0, 0x0, 0x2, 0x10, - 0x0, 0x9, 0x66, 0x7a, 0x0, 0x96, 0x66, 0xb1, - 0xe, 0x0, 0x3c, 0x0, 0xd0, 0x0, 0xe0, 0xe, - 0x0, 0x3b, 0x0, 0xd0, 0x0, 0xe0, 0xe, 0x0, - 0x3b, 0x0, 0xd0, 0x0, 0xe0, 0xe, 0x0, 0x3c, - 0x0, 0xd0, 0x0, 0xe0, 0xe, 0x66, 0x8c, 0x0, - 0xe6, 0x66, 0xe0, 0xd, 0x0, 0x26, 0x1, 0xb0, - 0x0, 0xa0, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, - - /* U+54E1 "員" */ - 0x0, 0x3, 0x0, 0x0, 0x0, 0x40, 0x0, 0x0, - 0xc6, 0x66, 0x66, 0x6e, 0x0, 0x0, 0xc, 0x10, - 0x0, 0x0, 0xd0, 0x0, 0x0, 0xc6, 0x66, 0x66, - 0x6d, 0x0, 0x0, 0xb, 0x0, 0x0, 0x0, 0x90, - 0x0, 0xa, 0x66, 0x66, 0x66, 0x66, 0xc1, 0x0, - 0xe0, 0x0, 0x0, 0x0, 0xd, 0x0, 0xe, 0x66, - 0x66, 0x66, 0x66, 0xd0, 0x0, 0xe0, 0x0, 0x0, - 0x0, 0xd, 0x0, 0xe, 0x66, 0x66, 0x66, 0x66, - 0xd0, 0x0, 0xe0, 0x0, 0x0, 0x0, 0xd, 0x0, - 0xe, 0x66, 0x66, 0x66, 0x66, 0xd0, 0x0, 0x40, - 0x2c, 0x20, 0x65, 0x1, 0x0, 0x0, 0x4c, 0x50, - 0x0, 0x5d, 0x91, 0x2, 0x75, 0x0, 0x0, 0x0, - 0xa, 0xb1, 0x30, 0x0, 0x0, 0x0, 0x0, 0x3, - - /* U+54EA "哪" */ - 0x0, 0x0, 0x0, 0x0, 0x10, 0x0, 0x0, 0x1, - 0x0, 0x17, 0x78, 0x6e, 0x1c, 0x68, 0xc0, 0xc6, - 0x7c, 0x2, 0x90, 0xd0, 0xc0, 0x85, 0xc, 0x2, - 0x90, 0x29, 0xd, 0xc, 0x9, 0x0, 0xc0, 0x29, - 0x37, 0xb6, 0xd0, 0xc1, 0x50, 0xc, 0x2, 0x90, - 0x29, 0xd, 0xc, 0x51, 0x0, 0xc0, 0x29, 0x3, - 0x80, 0xd0, 0xc0, 0x80, 0xc, 0x2, 0x90, 0x38, - 0xc, 0xc, 0x5, 0x50, 0xc6, 0x79, 0x5a, 0x96, - 0xd0, 0xc0, 0xb, 0xc, 0x2, 0x70, 0xa1, 0xd, - 0xc, 0x0, 0xc0, 0xb0, 0x0, 0x1a, 0x0, 0xc0, - 0xc5, 0x7c, 0x0, 0x0, 0x8, 0x20, 0x3a, 0xc, - 0xa, 0x20, 0x0, 0x4, 0x62, 0x9c, 0x50, 0xc0, - 0x0, 0x0, 0x3, 0x50, 0x2, 0x50, 0xc, 0x0, - 0x0, 0x0, 0x20, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, - - /* U+5546 "商" */ - 0x0, 0x0, 0x0, 0x10, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x2, 0xc2, 0x0, 0x0, 0x10, 0x5, - 0x66, 0x66, 0x6c, 0x86, 0x66, 0x9e, 0x20, 0x10, - 0x6, 0x0, 0x0, 0x29, 0x0, 0x0, 0x0, 0x0, - 0x3d, 0x0, 0x8, 0x40, 0x0, 0x0, 0x8, 0x66, - 0xd6, 0x66, 0xa6, 0x6a, 0x40, 0x0, 0xd0, 0x2, - 0x20, 0x10, 0x0, 0xa2, 0x0, 0xd, 0x0, 0xb7, - 0x0, 0x9a, 0x1a, 0x20, 0x0, 0xd0, 0x75, 0x0, - 0x0, 0x87, 0xa2, 0x0, 0xd, 0x33, 0x96, 0x66, - 0xb3, 0xa, 0x20, 0x0, 0xd0, 0xd, 0x0, 0xb, - 0x10, 0xa2, 0x0, 0xd, 0x0, 0xd0, 0x0, 0xb1, - 0xa, 0x20, 0x0, 0xd0, 0xd, 0x66, 0x6d, 0x10, - 0xa2, 0x0, 0xd, 0x0, 0xb0, 0x0, 0x60, 0xa, - 0x20, 0x0, 0xd0, 0x0, 0x0, 0x0, 0x3a, 0xf1, - 0x0, 0x5, 0x0, 0x0, 0x0, 0x0, 0x14, 0x0, - - /* U+554A "啊" */ - 0x0, 0x0, 0x53, 0x54, 0x0, 0x0, 0x25, 0x9, - 0x69, 0x2c, 0x3a, 0x65, 0x66, 0x6e, 0x50, 0xc0, - 0xc0, 0xc0, 0xa0, 0x0, 0x0, 0xd0, 0xc, 0xc, - 0xc, 0x8, 0x0, 0x0, 0xd, 0x0, 0xc0, 0xc0, - 0xc4, 0x30, 0xc6, 0xd1, 0xd0, 0xc, 0xc, 0xc, - 0x31, 0xc, 0xc, 0xd, 0x0, 0xc0, 0xc0, 0xc0, - 0x80, 0xc0, 0xc0, 0xd0, 0xc, 0xc, 0xc, 0x6, - 0x5c, 0xc, 0xd, 0x0, 0xc6, 0xd0, 0xc0, 0x57, - 0xd5, 0xd0, 0xd0, 0xc, 0x9, 0xc, 0x6b, 0x5a, - 0x6, 0xd, 0x0, 0x70, 0x0, 0xc1, 0x70, 0x0, - 0x0, 0xd0, 0x0, 0x0, 0xc, 0x0, 0x0, 0x0, - 0xd, 0x0, 0x0, 0x0, 0xc0, 0x0, 0x1, 0x42, - 0xd0, 0x0, 0x0, 0xc, 0x0, 0x0, 0x2, 0xd9, - 0x0, 0x0, 0x0, 0x10, 0x0, 0x0, 0x0, 0x0, - 0x0, - - /* U+554F "問" */ - 0x1a, 0x66, 0x6a, 0x50, 0x96, 0x66, 0xa3, 0xd, - 0x0, 0x9, 0x50, 0xd0, 0x0, 0xc1, 0xd, 0x0, - 0x9, 0x40, 0xd0, 0x0, 0xc1, 0xe, 0x66, 0x6b, - 0x40, 0xd6, 0x66, 0xd1, 0xd, 0x0, 0x9, 0x40, - 0xd0, 0x0, 0xc1, 0xe, 0x66, 0x6b, 0x40, 0xd6, - 0x66, 0xd1, 0xd, 0x0, 0x0, 0x0, 0x0, 0x0, - 0xc1, 0xd, 0x0, 0x96, 0x66, 0x6a, 0x0, 0xc1, - 0xd, 0x0, 0xd0, 0x0, 0x9, 0x0, 0xc1, 0xd, - 0x0, 0xd0, 0x0, 0x9, 0x0, 0xc1, 0xd, 0x0, - 0xd6, 0x66, 0x69, 0x0, 0xc1, 0xd, 0x0, 0xd0, - 0x0, 0x9, 0x0, 0xc1, 0xd, 0x0, 0x0, 0x0, - 0x1, 0x22, 0xe0, 0xd, 0x0, 0x0, 0x0, 0x0, - 0x4d, 0xc0, 0x1, 0x0, 0x0, 0x0, 0x0, 0x1, - 0x0, - - /* U+5566 "啦" */ - 0x0, 0x0, 0x2, 0x80, 0x1, 0x10, 0x0, 0x0, - 0x0, 0x0, 0x2a, 0x0, 0xb, 0x10, 0x0, 0x10, - 0x10, 0x2, 0xa0, 0x0, 0x88, 0x0, 0xc, 0x6c, - 0x60, 0x2a, 0x61, 0x14, 0x45, 0x40, 0xd0, 0xa3, - 0x88, 0xc5, 0x36, 0x55, 0x54, 0xd, 0xa, 0x20, - 0x2a, 0x0, 0x0, 0x7, 0x0, 0xd0, 0xa2, 0x2, - 0xa1, 0x44, 0x0, 0xf2, 0xd, 0xa, 0x20, 0x3d, - 0x50, 0x90, 0x2c, 0x0, 0xd0, 0xa6, 0xbb, 0xa0, - 0xa, 0x24, 0x80, 0xd, 0x6c, 0x34, 0x2a, 0x0, - 0x77, 0x73, 0x0, 0xd0, 0xa2, 0x2, 0xa0, 0x5, - 0x69, 0x0, 0x9, 0x0, 0x0, 0x2a, 0x0, 0x0, - 0x80, 0x0, 0x0, 0x1, 0x15, 0xa0, 0x0, 0x6, - 0x17, 0x0, 0x0, 0x28, 0xf6, 0x37, 0x66, 0x66, - 0x71, 0x0, 0x0, 0x3, 0x0, 0x0, 0x0, 0x0, - 0x0, - - /* U+5584 "善" */ - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x7, 0x40, 0x0, 0xb3, 0x0, 0x0, - 0x0, 0x0, 0x1, 0xf0, 0x5, 0x60, 0x4, 0x0, - 0x0, 0x76, 0x66, 0x96, 0x98, 0x66, 0x7b, 0x30, - 0x0, 0x0, 0x0, 0x2, 0xb0, 0x0, 0x80, 0x0, - 0x0, 0x7, 0x76, 0x67, 0xd6, 0x66, 0x62, 0x0, - 0x3, 0x66, 0x66, 0x67, 0xd6, 0x66, 0x6b, 0xa0, - 0x0, 0x10, 0x80, 0x2, 0xb0, 0x8, 0x40, 0x0, - 0x0, 0x0, 0x78, 0x2, 0xb0, 0x1a, 0x10, 0x20, - 0x5, 0x66, 0x78, 0x67, 0xc6, 0x96, 0x68, 0xe4, - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x10, 0x0, - 0x0, 0x0, 0xd6, 0x66, 0x66, 0x69, 0xa0, 0x0, - 0x0, 0x0, 0xd0, 0x0, 0x0, 0x5, 0x80, 0x0, - 0x0, 0x0, 0xd0, 0x0, 0x0, 0x5, 0x80, 0x0, - 0x0, 0x0, 0xe6, 0x66, 0x66, 0x69, 0x80, 0x0, - 0x0, 0x0, 0x40, 0x0, 0x0, 0x2, 0x20, 0x0, - - /* U+5589 "喉" */ - 0x0, 0x0, 0x0, 0x81, 0x0, 0x1, 0x0, 0x0, - 0x0, 0x0, 0x2c, 0x16, 0x6a, 0xa0, 0x0, 0x96, - 0x6d, 0x6, 0x60, 0x0, 0x94, 0x0, 0xa, 0x11, - 0xb0, 0xa0, 0x0, 0xc, 0x4, 0x30, 0xa1, 0x1b, - 0x1d, 0x38, 0xa6, 0x66, 0x64, 0xa, 0x11, 0xb7, - 0xc0, 0x4a, 0x0, 0x1, 0x0, 0xa1, 0x1b, 0x6c, - 0x9, 0x69, 0x67, 0x90, 0xa, 0x11, 0xb0, 0xc2, - 0x40, 0xc0, 0x0, 0x0, 0xa1, 0x1b, 0xc, 0x32, - 0x2d, 0x22, 0x45, 0xa, 0x66, 0xb0, 0xc4, 0x44, - 0xd8, 0x44, 0x30, 0xb1, 0x7, 0xc, 0x0, 0x2a, - 0x71, 0x0, 0x4, 0x0, 0x0, 0xc0, 0x8, 0x41, - 0xa0, 0x0, 0x0, 0x0, 0xc, 0x2, 0x90, 0x8, - 0x90, 0x0, 0x0, 0x0, 0xd2, 0x70, 0x0, 0xb, - 0x90, 0x0, 0x0, 0x3, 0x20, 0x0, 0x0, 0x0, - 0x0, - - /* U+559C "喜" */ - 0x0, 0x0, 0x0, 0x1, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x0, 0xc, 0x30, 0x0, 0x0, 0x0, - 0x0, 0x56, 0x66, 0x6d, 0x66, 0x66, 0xd8, 0x0, - 0x0, 0x10, 0x0, 0xc, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x1, 0x66, 0x6d, 0x66, 0x7d, 0x20, 0x0, - 0x0, 0x0, 0x50, 0x0, 0x0, 0x5, 0x0, 0x0, - 0x0, 0x0, 0xe6, 0x66, 0x66, 0x6e, 0x10, 0x0, - 0x0, 0x0, 0xd0, 0x0, 0x0, 0xd, 0x0, 0x0, - 0x0, 0x0, 0xd8, 0x66, 0x68, 0x7b, 0x0, 0x0, - 0x0, 0x0, 0x5, 0x90, 0x9, 0x50, 0x1, 0x0, - 0x6, 0x66, 0x66, 0xb6, 0x69, 0x66, 0x6d, 0x80, - 0x1, 0x0, 0x30, 0x0, 0x0, 0x4, 0x0, 0x0, - 0x0, 0x0, 0xe6, 0x66, 0x66, 0x6d, 0x30, 0x0, - 0x0, 0x0, 0xd0, 0x0, 0x0, 0xc, 0x10, 0x0, - 0x0, 0x0, 0xe6, 0x66, 0x66, 0x6d, 0x10, 0x0, - 0x0, 0x0, 0x60, 0x0, 0x0, 0x5, 0x0, 0x0, - - /* U+559D "喝" */ - 0x0, 0x0, 0x5, 0x76, 0x66, 0x6b, 0x30, 0x62, - 0x28, 0x6, 0x70, 0x0, 0xe, 0x0, 0xc4, 0x3e, - 0x16, 0xa6, 0x66, 0x6e, 0x0, 0xc1, 0xe, 0x6, - 0x70, 0x0, 0xe, 0x0, 0xc1, 0xe, 0x6, 0xa6, - 0x66, 0x6e, 0x0, 0xc1, 0xe, 0x5, 0x97, 0x0, - 0x5, 0x0, 0xc1, 0xe, 0x0, 0xd3, 0x0, 0x0, - 0x41, 0xc1, 0xe, 0x9, 0x76, 0x97, 0x66, 0xd6, - 0xc6, 0x6d, 0x6c, 0x0, 0xd5, 0x0, 0xc2, 0xc1, - 0x6, 0x4c, 0x6, 0x78, 0x50, 0xd1, 0x60, 0x1, - 0xc, 0x36, 0x0, 0xc0, 0xe0, 0x0, 0x0, 0xc, - 0x10, 0x1, 0x60, 0xe0, 0x0, 0x0, 0x2a, 0x66, - 0x66, 0x52, 0xc0, 0x0, 0x0, 0x0, 0x0, 0x4, - 0xae, 0x70, 0x0, 0x0, 0x0, 0x0, 0x0, 0x16, - 0x0, - - /* U+55AE "單" */ - 0x0, 0x20, 0x4, 0x0, 0x30, 0x1, 0x20, 0x0, - 0xe, 0x66, 0xe2, 0xe, 0x66, 0x8a, 0x0, 0x0, - 0xd0, 0xd, 0x0, 0xd0, 0x4, 0x80, 0x0, 0xd, - 0x0, 0xd0, 0xd, 0x0, 0x48, 0x0, 0x0, 0xc6, - 0x6a, 0x0, 0xd6, 0x67, 0x60, 0x0, 0x5, 0x76, - 0x66, 0x76, 0x66, 0xc0, 0x0, 0x0, 0x66, 0x0, - 0x68, 0x0, 0xc, 0x0, 0x0, 0x6, 0x96, 0x6a, - 0xb6, 0x66, 0xc0, 0x0, 0x0, 0x66, 0x0, 0x68, - 0x0, 0xc, 0x0, 0x0, 0x6, 0x60, 0x6, 0x80, - 0x0, 0xc0, 0x0, 0x0, 0x68, 0x66, 0xab, 0x66, - 0x6b, 0x0, 0x0, 0x0, 0x0, 0x6, 0x80, 0x0, - 0x3, 0x80, 0x57, 0x66, 0x66, 0xab, 0x66, 0x66, - 0x66, 0x10, 0x0, 0x0, 0x6, 0x80, 0x0, 0x0, - 0x0, 0x0, 0x0, 0x0, 0x68, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x0, 0x5, 0x40, 0x0, 0x0, 0x0, - - /* U+55B6 "営" */ - 0x0, 0x3, 0x10, 0x17, 0x0, 0x8, 0x0, 0x0, - 0x0, 0xc, 0x30, 0xa5, 0x4, 0xb1, 0x0, 0x0, - 0x0, 0x59, 0x5, 0x70, 0x90, 0x0, 0x0, 0x3, - 0x0, 0x0, 0x0, 0x21, 0x0, 0x40, 0x0, 0xb6, - 0x66, 0x66, 0x66, 0x66, 0x6e, 0x70, 0x78, 0x5, - 0x66, 0x66, 0x6a, 0x31, 0x70, 0x6, 0x10, 0x75, - 0x0, 0x0, 0xa2, 0x10, 0x0, 0x0, 0x7, 0x50, - 0x0, 0xa, 0x20, 0x0, 0x0, 0x0, 0x79, 0x66, - 0x66, 0xa2, 0x0, 0x0, 0x0, 0x1, 0x0, 0x0, - 0x0, 0x0, 0x0, 0x0, 0xc, 0x66, 0x66, 0x66, - 0x68, 0xb0, 0x0, 0x0, 0xd0, 0x0, 0x0, 0x0, - 0x48, 0x0, 0x0, 0xd, 0x0, 0x0, 0x0, 0x4, - 0x80, 0x0, 0x0, 0xe6, 0x66, 0x66, 0x66, 0x88, - 0x0, 0x0, 0x8, 0x0, 0x0, 0x0, 0x2, 0x30, - 0x0, - - /* U+55CE "嗎" */ - 0x30, 0x4, 0x6, 0x33, 0x33, 0x33, 0xa1, 0xe, - 0x66, 0xe1, 0xd3, 0x33, 0xd3, 0x33, 0x10, 0xd0, - 0xd, 0xd, 0x0, 0xd, 0x1, 0x40, 0xd, 0x0, - 0xd0, 0xd6, 0x66, 0xe6, 0x66, 0x0, 0xd0, 0xd, - 0xd, 0x0, 0xd, 0x0, 0x20, 0xd, 0x0, 0xd0, - 0xd6, 0x66, 0xe6, 0x6a, 0x10, 0xd0, 0xd, 0xd, - 0x0, 0xd, 0x0, 0x0, 0xd, 0x0, 0xd0, 0xd5, - 0x65, 0xd6, 0x67, 0xd0, 0xe6, 0x6e, 0x7, 0x0, - 0x0, 0x0, 0x1b, 0xd, 0x0, 0x20, 0x1, 0x3, - 0x5, 0x62, 0xa0, 0x20, 0x0, 0x6, 0x64, 0x1b, - 0xc, 0x79, 0x0, 0x0, 0x5, 0x61, 0xd0, 0xa3, - 0x69, 0x70, 0x0, 0x0, 0xd2, 0x9, 0x2, 0x0, - 0x95, 0x0, 0x0, 0x0, 0x0, 0x0, 0x38, 0xce, - 0x10, 0x0, 0x0, 0x0, 0x0, 0x0, 0x5, 0x20, - 0x0, - - /* U+55EF "嗯" */ - 0x0, 0x0, 0x3, 0x0, 0x0, 0x0, 0x40, 0x8, - 0x66, 0xb1, 0xd6, 0x67, 0x66, 0x8c, 0x0, 0xb1, - 0xd, 0xd, 0x0, 0x69, 0x3, 0x90, 0xb, 0x10, - 0xd0, 0xd3, 0x69, 0x9a, 0x59, 0x0, 0xb1, 0xd, - 0xd, 0x0, 0x94, 0x3, 0x90, 0xb, 0x10, 0xd0, - 0xd0, 0x2b, 0x69, 0x39, 0x0, 0xb1, 0xd, 0xd, - 0x28, 0x0, 0x95, 0x90, 0xb, 0x66, 0xd0, 0xd6, - 0x55, 0x55, 0x7a, 0x0, 0xb1, 0xd, 0x8, 0x0, - 0x20, 0x2, 0x40, 0xc, 0x10, 0x10, 0x3, 0x5, - 0xa0, 0x11, 0x0, 0x30, 0x0, 0x60, 0xb7, 0xc, - 0x10, 0xa6, 0x0, 0x0, 0x1d, 0xb, 0x30, 0x0, - 0x51, 0xe1, 0x0, 0x8, 0x80, 0xb4, 0x0, 0xa, - 0x4, 0x0, 0x0, 0x0, 0x6, 0xdb, 0xbb, 0xd2, - 0x0, - - /* U+561B "嘛" */ - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x0, 0xa, 0x20, 0x0, 0x0, 0x0, - 0x10, 0x20, 0x0, 0x57, 0x0, 0x50, 0xd, 0x6d, - 0x2c, 0x66, 0x76, 0x68, 0x78, 0x20, 0xd0, 0xd0, - 0xc1, 0xd, 0x0, 0x94, 0x0, 0xd, 0xd, 0xc, - 0x10, 0xc0, 0x9, 0x20, 0x0, 0xd0, 0xd0, 0xc6, - 0x6d, 0xa4, 0xc7, 0xb3, 0xd, 0xd, 0xd, 0x13, - 0xc0, 0xd, 0x70, 0x0, 0xd0, 0xd0, 0xd0, 0x8d, - 0x92, 0xf8, 0x0, 0xe, 0x6e, 0x1b, 0xc, 0xc6, - 0x9d, 0x81, 0x0, 0xd0, 0x84, 0x76, 0x5c, 0x9, - 0x94, 0x90, 0x6, 0x0, 0x83, 0x80, 0xc4, 0x49, - 0x2b, 0x40, 0x0, 0x8, 0x70, 0xc, 0x50, 0x92, - 0x38, 0x0, 0x6, 0x20, 0x0, 0xc0, 0x9, 0x20, - 0x0, 0x2, 0x30, 0x0, 0xc, 0x0, 0xa3, 0x0, - 0x0, 0x0, 0x0, 0x0, 0x0, 0x1, 0x0, 0x0, - - /* U+56B4 "嚴" */ - 0x0, 0x3, 0x0, 0x4, 0x2, 0x0, 0x2, 0x0, - 0x0, 0xb7, 0x66, 0xd0, 0xb6, 0x66, 0xc0, 0x0, - 0xa, 0x30, 0xc, 0xb, 0x0, 0xb, 0x0, 0x0, - 0xb7, 0x66, 0xd0, 0xb6, 0x66, 0xb0, 0x0, 0x34, - 0x0, 0x2, 0x3, 0x0, 0x8, 0x20, 0xa, 0x76, - 0x66, 0x66, 0x68, 0x66, 0x64, 0x0, 0xa3, 0x18, - 0x6d, 0x10, 0xd4, 0x0, 0x0, 0xa, 0x20, 0x1, - 0xa1, 0x1b, 0x0, 0x41, 0x0, 0xb4, 0x7a, 0x68, - 0xb8, 0x86, 0xaa, 0x30, 0xc, 0x11, 0xc6, 0x88, - 0x85, 0x9, 0x30, 0x0, 0xd0, 0x1a, 0x4, 0x94, - 0x60, 0xc0, 0x0, 0xc, 0x1, 0xc6, 0x88, 0x2, - 0x9a, 0x0, 0x2, 0x80, 0x1a, 0x4, 0x83, 0xc, - 0x70, 0x0, 0x62, 0x37, 0xd8, 0x9a, 0x6, 0x6b, - 0x50, 0x7, 0x5, 0x61, 0x4, 0x85, 0x50, 0x1c, - 0x80, 0x10, 0x0, 0x0, 0x12, 0x10, 0x0, 0x0, - - /* U+56DB "四" */ - 0x40, 0x0, 0x0, 0x0, 0x0, 0x6, 0xd, 0x66, - 0x6e, 0x66, 0xe6, 0x66, 0xf1, 0xd1, 0x1, 0xc0, - 0xe, 0x0, 0xe, 0xd, 0x10, 0x1c, 0x0, 0xe0, - 0x0, 0xe0, 0xd1, 0x1, 0xb0, 0xe, 0x0, 0xe, - 0xd, 0x10, 0x3a, 0x0, 0xe0, 0x0, 0xe0, 0xd1, - 0x5, 0x80, 0xe, 0x0, 0xe, 0xd, 0x10, 0x85, - 0x0, 0xe0, 0x0, 0xe0, 0xd1, 0xc, 0x0, 0xd, - 0x10, 0xe, 0xd, 0x17, 0x50, 0x0, 0x7c, 0xd8, - 0xe0, 0xd6, 0x50, 0x0, 0x0, 0x0, 0xe, 0xd, - 0x30, 0x0, 0x0, 0x0, 0x0, 0xe0, 0xd6, 0x66, - 0x66, 0x66, 0x66, 0x6e, 0xd, 0x10, 0x0, 0x0, - 0x0, 0x0, 0xe0, 0x20, 0x0, 0x0, 0x0, 0x0, - 0x3, 0x0, - - /* U+56DE "回" */ - 0x10, 0x0, 0x0, 0x0, 0x0, 0x2, 0xc, 0x66, - 0x66, 0x66, 0x66, 0x66, 0xe1, 0xd1, 0x0, 0x0, - 0x0, 0x0, 0xd, 0xc, 0x10, 0x0, 0x0, 0x0, - 0x0, 0xd0, 0xc1, 0x9, 0x66, 0x66, 0xb1, 0xd, - 0xc, 0x10, 0xd0, 0x0, 0xe, 0x0, 0xd0, 0xc1, - 0xd, 0x0, 0x0, 0xd0, 0xd, 0xc, 0x10, 0xd0, - 0x0, 0xd, 0x0, 0xd0, 0xc1, 0xd, 0x66, 0x66, - 0xe0, 0xd, 0xc, 0x10, 0xd0, 0x0, 0xb, 0x0, - 0xd0, 0xc1, 0x1, 0x0, 0x0, 0x0, 0xd, 0xc, - 0x10, 0x0, 0x0, 0x0, 0x0, 0xd0, 0xd6, 0x66, - 0x66, 0x66, 0x66, 0x6d, 0xd, 0x10, 0x0, 0x0, - 0x0, 0x0, 0xb0, 0x10, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, - - /* U+56E0 "因" */ - 0x3, 0x0, 0x0, 0x0, 0x0, 0x0, 0x50, 0xe, - 0x66, 0x66, 0x66, 0x66, 0x66, 0xe2, 0xd, 0x0, - 0x0, 0xb4, 0x0, 0x0, 0xe0, 0xd, 0x0, 0x0, - 0xc1, 0x0, 0x0, 0xe0, 0xd, 0x0, 0x0, 0xc1, - 0x1, 0x50, 0xe0, 0xd, 0x18, 0x66, 0xe6, 0x67, - 0x81, 0xe0, 0xd, 0x0, 0x0, 0xe0, 0x0, 0x0, - 0xe0, 0xd, 0x0, 0x1, 0xd7, 0x0, 0x0, 0xe0, - 0xd, 0x0, 0x7, 0x72, 0xc2, 0x0, 0xe0, 0xd, - 0x0, 0xc, 0x0, 0x5e, 0x10, 0xe0, 0xd, 0x0, - 0x93, 0x0, 0xc, 0x50, 0xe0, 0xd, 0x16, 0x20, - 0x0, 0x2, 0x10, 0xe0, 0xd, 0x0, 0x0, 0x0, - 0x0, 0x0, 0xe0, 0xe, 0x66, 0x66, 0x66, 0x66, - 0x66, 0xe0, 0x4, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x30, - - /* U+56F0 "困" */ - 0xa6, 0x66, 0x66, 0x66, 0x66, 0x6b, 0x1e, 0x0, - 0x0, 0x28, 0x0, 0x0, 0xe0, 0xe0, 0x0, 0x2, - 0xc0, 0x0, 0xe, 0xe, 0x0, 0x0, 0x2b, 0x0, - 0x10, 0xe0, 0xe1, 0x76, 0x69, 0xd6, 0x6d, 0x3e, - 0xe, 0x0, 0x2, 0xfb, 0x0, 0x0, 0xe0, 0xe0, - 0x0, 0x97, 0xd3, 0x0, 0xe, 0xe, 0x0, 0x3b, - 0x2b, 0x5b, 0x20, 0xe0, 0xe0, 0xa, 0x12, 0xb0, - 0x5f, 0x1e, 0xe, 0x8, 0x20, 0x2b, 0x0, 0x91, - 0xe0, 0xe5, 0x10, 0x2, 0xb0, 0x0, 0xe, 0xe, - 0x0, 0x0, 0x3c, 0x0, 0x0, 0xe0, 0xe0, 0x0, - 0x1, 0x20, 0x0, 0xe, 0xe, 0x66, 0x66, 0x66, - 0x66, 0x66, 0xe0, 0x50, 0x0, 0x0, 0x0, 0x0, - 0x2, 0x0, - - /* U+56F3 "図" */ - 0x3, 0x0, 0x0, 0x0, 0x0, 0x0, 0x14, 0x0, - 0xe6, 0x66, 0x66, 0x66, 0x66, 0x67, 0xd0, 0xd, - 0x0, 0x0, 0x0, 0x0, 0x0, 0x3b, 0x0, 0xd0, - 0x0, 0x1, 0x70, 0x2, 0x3, 0xb0, 0xd, 0x0, - 0x2a, 0x29, 0x61, 0xf2, 0x3b, 0x0, 0xd0, 0x6, - 0x4c, 0x36, 0x89, 0x3, 0xb0, 0xd, 0x0, 0x35, - 0x60, 0x1d, 0x0, 0x3b, 0x0, 0xd0, 0x0, 0x82, - 0xa, 0x50, 0x3, 0xb0, 0xd, 0x0, 0x1, 0xb5, - 0xa0, 0x0, 0x3b, 0x0, 0xd0, 0x0, 0x5, 0xf2, - 0x0, 0x3, 0xb0, 0xd, 0x0, 0x2, 0xa5, 0xd5, - 0x0, 0x3b, 0x0, 0xd0, 0x5, 0x80, 0x2, 0xdd, - 0x84, 0xb0, 0xd, 0x16, 0x30, 0x0, 0x0, 0x65, - 0x3b, 0x0, 0xd1, 0x0, 0x0, 0x0, 0x0, 0x3, - 0xb0, 0xe, 0x66, 0x66, 0x66, 0x66, 0x66, 0x7b, - 0x0, 0x40, 0x0, 0x0, 0x0, 0x0, 0x1, 0x30, - - /* U+56FD "国" */ - 0x96, 0x66, 0x66, 0x66, 0x66, 0x6b, 0x1d, 0x10, - 0x0, 0x0, 0x0, 0x0, 0xe0, 0xc1, 0x56, 0x66, - 0x66, 0x7d, 0x2e, 0xc, 0x11, 0x0, 0xc1, 0x0, - 0x0, 0xe0, 0xc1, 0x0, 0xc, 0x10, 0x0, 0xe, - 0xc, 0x10, 0x0, 0xc1, 0x7, 0x20, 0xe0, 0xc1, - 0x46, 0x6d, 0x76, 0x64, 0xe, 0xc, 0x10, 0x0, - 0xc1, 0x96, 0x0, 0xe0, 0xc1, 0x0, 0xc, 0x10, - 0xe2, 0xe, 0xc, 0x10, 0x0, 0xc1, 0x3, 0x30, - 0xe0, 0xc3, 0x86, 0x6b, 0x66, 0x8c, 0x3e, 0xc, - 0x10, 0x0, 0x0, 0x0, 0x0, 0xe0, 0xd6, 0x66, - 0x66, 0x66, 0x66, 0x6e, 0xd, 0x10, 0x0, 0x0, - 0x0, 0x0, 0xc0, 0x20, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, - - /* U+570B "國" */ - 0x3, 0x0, 0x0, 0x0, 0x0, 0x0, 0x14, 0x0, - 0xe6, 0x66, 0x66, 0x76, 0x66, 0x67, 0xc0, 0xd, - 0x0, 0x0, 0x6, 0xb8, 0x0, 0x3a, 0x0, 0xd0, - 0x0, 0x0, 0x56, 0x76, 0x33, 0xa0, 0xd, 0x28, - 0x66, 0x69, 0x96, 0x7b, 0x5a, 0x0, 0xd0, 0x0, - 0x0, 0x47, 0x0, 0x3, 0xa0, 0xd, 0xa, 0x66, - 0xc3, 0x80, 0x74, 0x3a, 0x0, 0xd0, 0xc0, 0xc, - 0xa, 0xc, 0x23, 0xa0, 0xd, 0xc, 0x0, 0xc0, - 0xb2, 0x90, 0x3a, 0x0, 0xd0, 0xc6, 0x6b, 0x8, - 0xc2, 0x3, 0xa0, 0xd, 0x3, 0x0, 0x32, 0x4e, - 0x2, 0x6a, 0x0, 0xd2, 0x89, 0x72, 0x2a, 0x6a, - 0x93, 0xa0, 0xd, 0x17, 0x0, 0x38, 0x0, 0x6f, - 0x4a, 0x0, 0xd0, 0x0, 0x13, 0x0, 0x0, 0x24, - 0xa0, 0xe, 0x66, 0x66, 0x66, 0x66, 0x66, 0x7a, - 0x0, 0x60, 0x0, 0x0, 0x0, 0x0, 0x1, 0x30, - - /* U+570D "圍" */ - 0x3, 0x0, 0x0, 0x0, 0x0, 0x0, 0x40, 0xe, - 0x66, 0x66, 0x76, 0x66, 0x66, 0xd4, 0xd, 0x0, - 0x0, 0xe1, 0x0, 0x0, 0xc1, 0xd, 0x0, 0x0, - 0xc0, 0x6, 0x0, 0xc1, 0xd, 0x3, 0x78, 0xc6, - 0x6d, 0x10, 0xc1, 0xd, 0x23, 0x37, 0x93, 0x3c, - 0x75, 0xc1, 0xd, 0x24, 0x53, 0x33, 0x37, 0x32, - 0xc1, 0xd, 0x0, 0xc6, 0x66, 0x6d, 0x10, 0xc1, - 0xd, 0x0, 0xb5, 0x59, 0x5b, 0x0, 0xc1, 0xd, - 0x4, 0x66, 0x6e, 0x68, 0x80, 0xc1, 0xd, 0x1, - 0xc0, 0xd, 0x0, 0x10, 0xc1, 0xd, 0x7, 0xa6, - 0x6e, 0x67, 0xc0, 0xc1, 0xd, 0x0, 0x0, 0xd, - 0x0, 0x0, 0xc1, 0xd, 0x0, 0x0, 0x8, 0x0, - 0x0, 0xc1, 0xe, 0x66, 0x66, 0x66, 0x66, 0x66, - 0xd1, 0x5, 0x0, 0x0, 0x0, 0x0, 0x0, 0x40, - - /* U+5712 "園" */ - 0x3, 0x0, 0x0, 0x0, 0x0, 0x0, 0x40, 0xe, - 0x66, 0x66, 0x96, 0x66, 0x66, 0xe2, 0xd, 0x0, - 0x0, 0xc3, 0x0, 0x0, 0xd0, 0xd, 0x0, 0x56, - 0xd6, 0x6d, 0x10, 0xd0, 0xd, 0x0, 0x10, 0xb1, - 0x0, 0x30, 0xd0, 0xd, 0x18, 0x66, 0x86, 0x66, - 0x93, 0xd0, 0xd, 0x0, 0x86, 0x66, 0x6a, 0x20, - 0xd0, 0xd, 0x0, 0xd0, 0x0, 0xd, 0x0, 0xd0, - 0xd, 0x0, 0xe6, 0x66, 0x6e, 0x0, 0xd0, 0xd, - 0x0, 0x5b, 0x30, 0x4, 0x90, 0xd0, 0xd, 0x0, - 0x7d, 0x33, 0x7, 0x50, 0xd0, 0xd, 0x6, 0x58, - 0x13, 0xb8, 0x0, 0xd0, 0xd, 0x41, 0x8, 0x10, - 0x9, 0xc0, 0xd0, 0xd, 0x0, 0x5, 0x0, 0x0, - 0x50, 0xd0, 0xe, 0x66, 0x66, 0x66, 0x66, 0x66, - 0xe0, 0x4, 0x0, 0x0, 0x0, 0x0, 0x0, 0x30, - - /* U+5718 "團" */ - 0x3, 0x0, 0x0, 0x0, 0x0, 0x0, 0x30, 0xe, - 0x66, 0x66, 0x68, 0x66, 0x66, 0xc4, 0xd, 0x0, - 0x0, 0x1c, 0x0, 0x13, 0xb3, 0xd, 0x19, 0x77, - 0x7d, 0x77, 0x76, 0xb3, 0xd, 0x2, 0x86, 0x6d, - 0x66, 0xc0, 0xb3, 0xd, 0x2, 0xb4, 0x4d, 0x44, - 0xc0, 0xb3, 0xd, 0x2, 0xa2, 0x3c, 0x22, 0xc0, - 0xb3, 0xd, 0x2, 0xa6, 0x6d, 0x6a, 0x70, 0xb3, - 0xd, 0x3, 0x56, 0x7c, 0x57, 0xc4, 0xb3, 0xd, - 0x2, 0x52, 0x0, 0x86, 0x24, 0xb3, 0xd, 0x7, - 0x77, 0x66, 0xb9, 0x92, 0xb3, 0xd, 0x0, 0xa, - 0x10, 0x85, 0x0, 0xb3, 0xd, 0x0, 0x5, 0x56, - 0xc4, 0x0, 0xb3, 0xd, 0x0, 0x0, 0x3, 0xa0, - 0x0, 0xb3, 0xe, 0x66, 0x66, 0x66, 0x66, 0x66, - 0xc3, 0x5, 0x0, 0x0, 0x0, 0x0, 0x0, 0x40, - - /* U+571F "土" */ - 0x0, 0x0, 0x0, 0xa, 0x40, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x0, 0xc, 0x20, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x0, 0xc, 0x20, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x0, 0xc, 0x20, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x0, 0xc, 0x20, 0x0, 0x10, 0x0, - 0x1, 0x66, 0x66, 0x6d, 0x76, 0x66, 0xe6, 0x0, - 0x0, 0x20, 0x0, 0xc, 0x20, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x0, 0xc, 0x20, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x0, 0xc, 0x20, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x0, 0xc, 0x20, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x0, 0xc, 0x20, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x0, 0xc, 0x20, 0x0, 0x3, 0x0, - 0x27, 0x66, 0x66, 0x6c, 0x76, 0x66, 0x6d, 0x80, - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - - /* U+5723 "圣" */ - 0x0, 0x0, 0x0, 0x0, 0x0, 0x7, 0x10, 0x0, - 0x0, 0x6, 0x78, 0x66, 0x66, 0x8f, 0x70, 0x0, - 0x0, 0x0, 0x5, 0x20, 0x0, 0xc7, 0x0, 0x0, - 0x0, 0x0, 0x0, 0x84, 0xa, 0x90, 0x0, 0x0, - 0x0, 0x0, 0x0, 0x8, 0xca, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x0, 0x2c, 0x9c, 0x83, 0x0, 0x0, - 0x0, 0x0, 0x29, 0x92, 0x60, 0x6d, 0xfc, 0xa2, - 0x2, 0x57, 0x50, 0x1, 0xf1, 0x0, 0x16, 0x40, - 0x2, 0x0, 0x0, 0x0, 0xe0, 0x0, 0x10, 0x0, - 0x0, 0x6, 0x66, 0x66, 0xf6, 0x66, 0xd8, 0x0, - 0x0, 0x1, 0x0, 0x0, 0xe0, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x0, 0x0, 0xe0, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x0, 0x0, 0xe0, 0x0, 0x4, 0x70, - 0x5, 0x76, 0x66, 0x66, 0x76, 0x66, 0x67, 0x71, - - /* U+5728 "在" */ - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x0, 0x5c, 0x10, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x0, 0x97, 0x0, 0x0, 0x1, 0x0, - 0x5, 0x66, 0x66, 0xf6, 0x66, 0x66, 0x8f, 0x40, - 0x1, 0x10, 0x7, 0x80, 0x3, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x1d, 0x0, 0xe, 0x10, 0x0, 0x0, - 0x0, 0x0, 0xb4, 0x0, 0xd, 0x0, 0x0, 0x0, - 0x0, 0xb, 0x80, 0x0, 0xd, 0x0, 0x23, 0x0, - 0x0, 0x5f, 0x14, 0x76, 0x6e, 0x66, 0x88, 0x0, - 0x4, 0x6c, 0x10, 0x0, 0xd, 0x0, 0x0, 0x0, - 0x33, 0xc, 0x10, 0x0, 0xd, 0x0, 0x0, 0x0, - 0x0, 0xc, 0x10, 0x0, 0xd, 0x0, 0x0, 0x0, - 0x0, 0xc, 0x10, 0x0, 0xd, 0x0, 0x1, 0x0, - 0x0, 0xc, 0x37, 0x66, 0x6d, 0x66, 0x6c, 0x90, - 0x0, 0xd, 0x10, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x2, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - - /* U+5730 "地" */ - 0x0, 0x5, 0x0, 0x0, 0x2, 0xb0, 0x0, 0x0, - 0x0, 0xe, 0x10, 0x0, 0x1, 0xb0, 0x0, 0x0, - 0x0, 0xe, 0x0, 0xc, 0x1, 0xb0, 0x0, 0x0, - 0x0, 0xe, 0x0, 0xd, 0x1, 0xb0, 0x7, 0x0, - 0x0, 0xe, 0x1, 0xd, 0x1, 0xc6, 0x6e, 0x0, - 0x8, 0x6e, 0x7a, 0xd, 0x56, 0xc0, 0xc, 0x0, - 0x0, 0xe, 0x4, 0x6d, 0x1, 0xb0, 0xc, 0x0, - 0x0, 0xe, 0x12, 0xd, 0x1, 0xb0, 0xc, 0x0, - 0x0, 0xe, 0x0, 0xd, 0x1, 0xb0, 0xc, 0x0, - 0x0, 0xe, 0x0, 0xd, 0x1, 0xb5, 0x9b, 0x0, - 0x0, 0xe, 0x3, 0x2d, 0x2, 0xc0, 0x73, 0x40, - 0x0, 0x4f, 0x82, 0xd, 0x1, 0x40, 0x0, 0x70, - 0x2e, 0xa2, 0x0, 0xd, 0x0, 0x0, 0x0, 0xc2, - 0x2, 0x0, 0x0, 0xa, 0xcc, 0xcc, 0xcd, 0xe3, - - /* U+5747 "均" */ - 0x0, 0xa, 0x20, 0x0, 0x86, 0x0, 0x0, 0x0, - 0x0, 0xd1, 0x0, 0xd, 0x30, 0x0, 0x0, 0x0, - 0xd, 0x0, 0x2, 0xc0, 0x0, 0x2, 0x0, 0x0, - 0xd0, 0x0, 0x88, 0x66, 0x66, 0xc6, 0x16, 0x6e, - 0x6b, 0x2a, 0x0, 0x0, 0xa, 0x30, 0x0, 0xd0, - 0x7, 0x23, 0x70, 0x0, 0xb2, 0x0, 0xd, 0x0, - 0x30, 0x9, 0x90, 0xb, 0x20, 0x0, 0xd0, 0x0, - 0x0, 0x2e, 0x0, 0xc2, 0x0, 0xd, 0x0, 0x0, - 0x0, 0x15, 0xd, 0x10, 0x0, 0xd1, 0x65, 0x0, - 0x58, 0x10, 0xe0, 0x1, 0x6e, 0x81, 0x6, 0xc5, - 0x0, 0xf, 0x3, 0xf9, 0x10, 0x9, 0xc1, 0x0, - 0x1, 0xe0, 0x2, 0x0, 0x0, 0x0, 0x3, 0x21, - 0x8a, 0x0, 0x0, 0x0, 0x0, 0x0, 0x6, 0xfe, - 0x20, 0x0, 0x0, 0x0, 0x0, 0x0, 0x2, 0x0, - 0x0, - - /* U+574A "坊" */ - 0x0, 0x7, 0x20, 0x0, 0x37, 0x0, 0x0, 0x0, - 0x0, 0xd2, 0x0, 0x0, 0x9a, 0x0, 0x0, 0x0, - 0xc, 0x10, 0x0, 0x2, 0xc0, 0x0, 0x0, 0x0, - 0xc1, 0x5, 0x66, 0x66, 0x66, 0xd6, 0x0, 0xc, - 0x17, 0x10, 0xb4, 0x0, 0x0, 0x0, 0x66, 0xd6, - 0x61, 0xc, 0x30, 0x0, 0x0, 0x0, 0xc, 0x10, - 0x0, 0xd7, 0x66, 0xa9, 0x0, 0x0, 0xc1, 0x0, - 0xf, 0x10, 0x9, 0x60, 0x0, 0xc, 0x10, 0x1, - 0xe0, 0x0, 0xa4, 0x0, 0x0, 0xc1, 0x34, 0x69, - 0x0, 0xc, 0x30, 0x1, 0x5e, 0x93, 0xc, 0x30, - 0x0, 0xd1, 0x2, 0xf9, 0x20, 0x5, 0x90, 0x0, - 0xe, 0x0, 0x1, 0x0, 0x2, 0xa0, 0x3, 0x4, - 0xc0, 0x0, 0x0, 0x4, 0x70, 0x0, 0x4d, 0xf6, - 0x0, 0x0, 0x2, 0x20, 0x0, 0x0, 0x13, 0x0, - 0x0, - - /* U+5750 "坐" */ - 0x0, 0x0, 0x0, 0x9, 0x40, 0x0, 0x0, 0x0, - 0x0, 0x1, 0x10, 0xa, 0x30, 0x2, 0x10, 0x0, - 0x0, 0x8, 0xc0, 0xa, 0x30, 0x8, 0xc0, 0x0, - 0x0, 0xc, 0x40, 0xa, 0x30, 0xd, 0x40, 0x0, - 0x0, 0x1f, 0x0, 0xa, 0x30, 0x3e, 0x20, 0x0, - 0x0, 0x87, 0xb3, 0xa, 0x30, 0x93, 0xa5, 0x0, - 0x0, 0xb0, 0x3f, 0x1a, 0x32, 0x90, 0x1f, 0x20, - 0x7, 0x20, 0x9, 0xa, 0x37, 0x0, 0x8, 0x10, - 0x23, 0x0, 0x0, 0xa, 0x51, 0x2, 0x30, 0x0, - 0x0, 0x27, 0x66, 0x6c, 0x86, 0x69, 0xa1, 0x0, - 0x0, 0x0, 0x0, 0xa, 0x30, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x0, 0xa, 0x30, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x0, 0xa, 0x30, 0x0, 0x9, 0x20, - 0x28, 0x66, 0x66, 0x67, 0x66, 0x66, 0x69, 0x70, - - /* U+578B "型" */ - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x23, 0x0, 0x0, 0xc1, 0x6, 0x6b, - 0x6b, 0x87, 0x4, 0x10, 0xd0, 0x0, 0x1b, 0xb, - 0x10, 0xb, 0x30, 0xd0, 0x0, 0x1b, 0xb, 0x16, - 0xb, 0x10, 0xd0, 0x47, 0x7c, 0x6d, 0x78, 0x4b, - 0x10, 0xd0, 0x0, 0x48, 0xb, 0x10, 0xb, 0x10, - 0xd0, 0x0, 0x93, 0xb, 0x10, 0x6, 0x0, 0xd0, - 0x2, 0xa0, 0xb, 0x20, 0x2, 0x33, 0xd0, 0x18, - 0x0, 0x7, 0x62, 0x0, 0x5e, 0x80, 0x30, 0x0, - 0x0, 0xa5, 0x0, 0x3, 0x0, 0x0, 0x67, 0x66, - 0xc8, 0x66, 0x9c, 0x10, 0x0, 0x0, 0x0, 0xa3, - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xa3, 0x0, - 0x0, 0x30, 0x46, 0x66, 0x66, 0xc8, 0x66, 0x67, - 0xf7, 0x11, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - - /* U+57DF "域" */ - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x8, 0x10, 0x0, 0x0, 0x76, 0x54, 0x0, - 0x0, 0xe, 0x0, 0x0, 0x0, 0x75, 0xc, 0x40, - 0x0, 0xe, 0x0, 0x0, 0x0, 0x75, 0x2, 0x70, - 0x0, 0xe, 0x5, 0x76, 0x66, 0xa9, 0x67, 0x82, - 0x5, 0x6e, 0x98, 0x0, 0x0, 0x76, 0x0, 0x0, - 0x1, 0xe, 0x0, 0xb6, 0x7c, 0x66, 0xb, 0x30, - 0x0, 0xe, 0x0, 0xc0, 0x29, 0x57, 0x1e, 0x0, - 0x0, 0xe, 0x0, 0xc0, 0x29, 0x49, 0x77, 0x0, - 0x0, 0xe, 0x0, 0xc6, 0x79, 0x1c, 0xc1, 0x0, - 0x0, 0xe, 0x44, 0x50, 0x1, 0xe, 0x90, 0x0, - 0x19, 0xc9, 0x20, 0x0, 0x45, 0x2e, 0x70, 0x4, - 0x7, 0x10, 0x2a, 0xb7, 0x20, 0xb4, 0xe3, 0x34, - 0x0, 0x0, 0x5, 0x0, 0x1a, 0x30, 0x4e, 0xb3, - 0x0, 0x0, 0x0, 0x3, 0x81, 0x0, 0x4, 0xe3, - 0x0, 0x0, 0x0, 0x12, 0x0, 0x0, 0x0, 0x11, - - /* U+57F7 "執" */ - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, 0xc1, 0x0, 0x1, 0xa1, 0x0, 0x0, - 0x0, 0x0, 0xd0, 0x10, 0x1, 0xc0, 0x0, 0x0, - 0x3, 0x66, 0xe6, 0xa2, 0x1, 0xc0, 0x0, 0x0, - 0x0, 0x0, 0xd0, 0x0, 0x1, 0xc0, 0x25, 0x0, - 0x0, 0x0, 0xd0, 0x24, 0x57, 0xd5, 0x8c, 0x0, - 0x7, 0xb6, 0x66, 0x95, 0x2, 0xb0, 0x57, 0x0, - 0x0, 0x69, 0x4, 0xb0, 0x45, 0xa0, 0x76, 0x0, - 0x0, 0x8, 0x7, 0x50, 0xa, 0xb0, 0x85, 0x0, - 0x5, 0x76, 0xe6, 0x63, 0x9, 0xcb, 0x84, 0x0, - 0x0, 0x0, 0xd0, 0x0, 0xc, 0x8, 0x94, 0x0, - 0x7, 0x66, 0xe6, 0x99, 0x3a, 0x0, 0x85, 0x10, - 0x0, 0x0, 0xd0, 0x0, 0xa1, 0x0, 0x58, 0x60, - 0x0, 0x0, 0xe0, 0x6, 0x50, 0x0, 0x1d, 0xb0, - 0x0, 0x0, 0xe0, 0x64, 0x0, 0x0, 0x4, 0xf1, - 0x0, 0x0, 0x12, 0x10, 0x0, 0x0, 0x0, 0x11, - - /* U+57FA "基" */ - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x2a, 0x0, 0x0, 0xb3, 0x0, 0x0, - 0x0, 0x0, 0x1c, 0x0, 0x0, 0xc2, 0x18, 0x0, - 0x0, 0x66, 0x6d, 0x66, 0x66, 0xd7, 0x66, 0x20, - 0x0, 0x0, 0x1d, 0x66, 0x66, 0xd2, 0x0, 0x0, - 0x0, 0x0, 0x1c, 0x0, 0x0, 0xc2, 0x0, 0x0, - 0x0, 0x0, 0x1d, 0x66, 0x66, 0xd2, 0x0, 0x0, - 0x0, 0x0, 0x1c, 0x0, 0x0, 0xc2, 0x5, 0x0, - 0x6, 0x76, 0x6d, 0x66, 0x66, 0xb6, 0x7c, 0x90, - 0x0, 0x0, 0x2c, 0x9, 0x30, 0x91, 0x0, 0x0, - 0x0, 0x2, 0xb1, 0xb, 0x20, 0x1b, 0x83, 0x0, - 0x0, 0x57, 0x46, 0x6c, 0x76, 0xd3, 0x7e, 0xb1, - 0x5, 0x10, 0x0, 0xb, 0x20, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x0, 0xb, 0x20, 0x0, 0x11, 0x0, - 0x0, 0x56, 0x66, 0x6c, 0x76, 0x66, 0xcc, 0x0, - 0x0, 0x20, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - - /* U+5831 "報" */ - 0x0, 0x0, 0xb0, 0x0, 0x30, 0x0, 0x3, 0x0, - 0x0, 0x0, 0xd0, 0x10, 0xd6, 0x66, 0x6d, 0x30, - 0x3, 0x76, 0xe6, 0x91, 0xd0, 0x0, 0xd, 0x0, - 0x0, 0x0, 0xd0, 0x0, 0xd0, 0x0, 0x1d, 0x0, - 0x15, 0x66, 0xe6, 0x98, 0xd0, 0x7, 0xe8, 0x0, - 0x1, 0x60, 0x4, 0x50, 0xd0, 0x0, 0x21, 0x0, - 0x0, 0x4b, 0x9, 0x20, 0xd7, 0x55, 0x5d, 0x50, - 0x3, 0x6c, 0x69, 0xa3, 0xd3, 0x20, 0x2d, 0x0, - 0x0, 0x10, 0xd0, 0x0, 0xd0, 0x80, 0x94, 0x0, - 0x0, 0x0, 0xd0, 0x0, 0xd0, 0x66, 0xb0, 0x0, - 0x17, 0x66, 0xe6, 0x98, 0xd0, 0xf, 0x30, 0x0, - 0x0, 0x0, 0xd0, 0x0, 0xd0, 0x78, 0xb0, 0x0, - 0x0, 0x0, 0xd0, 0x0, 0xd5, 0x40, 0x6d, 0x50, - 0x0, 0x0, 0xe0, 0x0, 0xd2, 0x0, 0x7, 0x60, - 0x0, 0x0, 0x40, 0x0, 0x40, 0x0, 0x0, 0x0, - - /* U+5834 "場" */ - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0xd, 0x10, 0x9, 0x66, 0x66, 0x6b, 0x10, - 0x0, 0xe, 0x0, 0xd, 0x0, 0x0, 0xe, 0x0, - 0x0, 0xe, 0x0, 0xd, 0x66, 0x66, 0x6e, 0x0, - 0x0, 0xe, 0x0, 0xd, 0x0, 0x0, 0xe, 0x0, - 0x18, 0x6e, 0x6b, 0x2e, 0x66, 0x66, 0x6e, 0x0, - 0x0, 0xe, 0x0, 0x8, 0x0, 0x0, 0x7, 0x10, - 0x0, 0xe, 0x2, 0x76, 0x76, 0x66, 0x66, 0xd3, - 0x0, 0xe, 0x0, 0x2, 0xd1, 0x0, 0x0, 0x10, - 0x0, 0xe, 0x1, 0x2b, 0x7b, 0x79, 0x98, 0xb0, - 0x0, 0xe, 0x76, 0x92, 0x4a, 0xd, 0x26, 0x70, - 0x18, 0xc7, 0x4, 0x2, 0xa0, 0x78, 0x8, 0x40, - 0x9, 0x10, 0x0, 0x47, 0x4, 0xa0, 0xb, 0x20, - 0x0, 0x0, 0x2, 0x20, 0x58, 0x0, 0xd, 0x0, - 0x0, 0x0, 0x0, 0x17, 0x40, 0x19, 0xd8, 0x0, - 0x0, 0x0, 0x0, 0x30, 0x0, 0x1, 0x60, 0x0, - - /* U+584A "塊" */ - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0xa, 0x10, 0x0, 0x8, 0x70, 0x0, 0x0, - 0x0, 0xe, 0x0, 0x30, 0x19, 0x0, 0x4, 0x0, - 0x0, 0xe, 0x0, 0xc6, 0x68, 0xc6, 0x6f, 0x10, - 0x0, 0xe, 0x0, 0xb1, 0x3, 0xa0, 0xe, 0x0, - 0x5, 0x6e, 0x88, 0xb6, 0x68, 0xc6, 0x6e, 0x0, - 0x1, 0xe, 0x0, 0xb1, 0x4, 0x90, 0xe, 0x0, - 0x0, 0xe, 0x0, 0xb1, 0x6, 0x70, 0xe, 0x0, - 0x0, 0xe, 0x0, 0xc6, 0x6c, 0xd6, 0x6d, 0x0, - 0x0, 0xe, 0x0, 0x20, 0xd, 0xb1, 0x41, 0x0, - 0x0, 0xe, 0x66, 0x0, 0x68, 0xa1, 0xa1, 0x0, - 0x4, 0x9a, 0x10, 0x2, 0xc0, 0xa6, 0x28, 0x0, - 0xb, 0x40, 0x0, 0x1b, 0x20, 0xab, 0x79, 0x90, - 0x0, 0x0, 0x2, 0xa2, 0x0, 0xa2, 0x1, 0x90, - 0x0, 0x0, 0x55, 0x0, 0x0, 0x6c, 0xaa, 0xc2, - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - - /* U+5869 "塩" */ - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x1c, 0x10, 0x0, 0xb3, 0x0, 0x0, 0x0, - 0x0, 0xc, 0x0, 0x2, 0xc0, 0x0, 0x2, 0x0, - 0x0, 0xc, 0x0, 0x8, 0x86, 0x66, 0x6c, 0x40, - 0x0, 0xc, 0x0, 0x9, 0x0, 0x0, 0x0, 0x0, - 0x7, 0x7d, 0x78, 0x66, 0x76, 0x66, 0x7a, 0x0, - 0x0, 0xc, 0x0, 0x16, 0x60, 0x0, 0x39, 0x0, - 0x0, 0xc, 0x0, 0x6, 0x60, 0x0, 0x39, 0x0, - 0x0, 0xc, 0x0, 0x6, 0x96, 0x66, 0x89, 0x0, - 0x0, 0xc, 0x0, 0x12, 0x0, 0x0, 0x2, 0x0, - 0x0, 0xd, 0x66, 0x4b, 0x6a, 0x6a, 0x6e, 0x20, - 0x4, 0xaa, 0x20, 0x2b, 0xc, 0xc, 0xd, 0x0, - 0x9, 0x40, 0x0, 0x2b, 0xc, 0xc, 0xd, 0x0, - 0x0, 0x0, 0x0, 0x2b, 0xc, 0xc, 0xd, 0x0, - 0x0, 0x0, 0x4, 0x7c, 0x6d, 0x6d, 0x6e, 0xc2, - 0x0, 0x0, 0x1, 0x10, 0x0, 0x0, 0x0, 0x0, - - /* U+5883 "境" */ - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x8, 0x10, 0x0, 0x9, 0x30, 0x0, 0x0, - 0x0, 0xe, 0x0, 0x0, 0x2, 0x60, 0x26, 0x0, - 0x0, 0xe, 0x0, 0x48, 0x76, 0x69, 0x65, 0x10, - 0x0, 0xe, 0x0, 0x0, 0xb2, 0xb, 0x50, 0x0, - 0x6, 0x6e, 0x8a, 0x0, 0x62, 0x26, 0x4, 0x50, - 0x0, 0xe, 0x3, 0x76, 0x66, 0x66, 0x66, 0x50, - 0x0, 0xe, 0x0, 0xc, 0x66, 0x66, 0xc6, 0x0, - 0x0, 0xe, 0x0, 0xd, 0x0, 0x0, 0xb1, 0x0, - 0x0, 0xe, 0x0, 0xe, 0x66, 0x66, 0xd1, 0x0, - 0x0, 0xe, 0x55, 0x2d, 0x0, 0x0, 0xb1, 0x0, - 0xb, 0xb6, 0x0, 0x9, 0xc9, 0xc7, 0x81, 0x20, - 0x2, 0x0, 0x0, 0x0, 0xd2, 0xa2, 0x0, 0x70, - 0x0, 0x0, 0x0, 0x8, 0x90, 0xa3, 0x0, 0xb0, - 0x0, 0x0, 0x26, 0x96, 0x0, 0x5d, 0xbc, 0xc1, - 0x0, 0x1, 0x30, 0x0, 0x0, 0x0, 0x0, 0x0, - - /* U+5897 "増" */ - 0x0, 0xb, 0x10, 0x5, 0x20, 0x0, 0x57, 0x0, - 0x0, 0xe, 0x0, 0x0, 0xd4, 0x0, 0xc5, 0x0, - 0x0, 0xe, 0x0, 0x0, 0x68, 0x5, 0x30, 0x0, - 0x0, 0xe, 0x0, 0xc6, 0x66, 0x96, 0x66, 0xe0, - 0x4, 0x4e, 0x57, 0xd1, 0x0, 0xd0, 0x1, 0xd0, - 0x3, 0x2e, 0x21, 0xc6, 0x66, 0xe6, 0x66, 0xd0, - 0x0, 0xe, 0x0, 0xd1, 0x0, 0xd0, 0x1, 0xd0, - 0x0, 0xe, 0x0, 0xd6, 0x66, 0xa6, 0x66, 0xd0, - 0x0, 0xe, 0x0, 0x32, 0x0, 0x0, 0x3, 0x20, - 0x0, 0xe, 0x5, 0x1f, 0x66, 0x66, 0x6f, 0x10, - 0x0, 0x2f, 0x91, 0xe, 0x0, 0x0, 0xe, 0x0, - 0xc, 0xd3, 0x0, 0xe, 0x66, 0x66, 0x6e, 0x0, - 0x4, 0x0, 0x0, 0xe, 0x0, 0x0, 0xe, 0x0, - 0x0, 0x0, 0x0, 0xf, 0x66, 0x66, 0x6f, 0x0, - 0x0, 0x0, 0x0, 0x7, 0x0, 0x0, 0x5, 0x0, - - /* U+589E "增" */ - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0xb1, 0x0, 0x27, 0x0, 0xc, 0x30, 0x0, - 0xd, 0x0, 0x0, 0x96, 0x5, 0x60, 0x0, 0x0, - 0xd0, 0x8, 0x67, 0x86, 0xa6, 0x78, 0x0, 0xd, - 0x0, 0xc0, 0x0, 0xc0, 0x4, 0x70, 0x76, 0xe9, - 0x8c, 0x47, 0xc, 0xb, 0x77, 0x0, 0xd, 0x0, - 0xc0, 0xd2, 0xc3, 0x74, 0x70, 0x0, 0xd0, 0xc, - 0x4, 0xc, 0x30, 0x47, 0x0, 0xd, 0x0, 0xc6, - 0x66, 0x96, 0x68, 0x80, 0x0, 0xd0, 0x2, 0x30, - 0x0, 0x0, 0x60, 0x0, 0xd, 0x4, 0xe, 0x66, - 0x66, 0x7c, 0x0, 0x16, 0xd6, 0x0, 0xd0, 0x0, - 0x2, 0xa0, 0x1e, 0x60, 0x0, 0xe, 0x66, 0x66, - 0x7a, 0x0, 0x0, 0x0, 0x0, 0xd0, 0x0, 0x2, - 0xa0, 0x0, 0x0, 0x0, 0xe, 0x66, 0x66, 0x7b, - 0x0, 0x0, 0x0, 0x0, 0x40, 0x0, 0x0, 0x10, - - /* U+58CA "壊" */ - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0xb, 0x0, 0x0, 0x1, 0xd0, 0x0, 0x0, - 0x0, 0xd, 0x2, 0x66, 0x66, 0xd6, 0x69, 0x90, - 0x0, 0xd, 0x0, 0x10, 0x1, 0xa0, 0x0, 0x0, - 0x0, 0xd, 0x0, 0x86, 0x68, 0xb7, 0x6b, 0x30, - 0x5, 0x6e, 0x79, 0xa1, 0xc, 0xc, 0xa, 0x10, - 0x1, 0xd, 0x0, 0xa1, 0xc, 0xc, 0xa, 0x10, - 0x0, 0xd, 0x0, 0xb6, 0x6d, 0x6d, 0x6c, 0x20, - 0x0, 0xd, 0x0, 0x50, 0x2, 0x70, 0x4, 0x0, - 0x0, 0xd, 0x2, 0x66, 0x66, 0xd6, 0x6c, 0x30, - 0x0, 0xd, 0x5, 0x20, 0x97, 0x50, 0x3, 0x0, - 0x0, 0x2e, 0x70, 0x6, 0xd0, 0x35, 0x5b, 0x10, - 0xb, 0xd3, 0x0, 0x78, 0xc0, 0xb, 0x60, 0x0, - 0x4, 0x0, 0x36, 0x12, 0xc1, 0x42, 0xd5, 0x0, - 0x0, 0x0, 0x10, 0x4, 0xf7, 0x0, 0x3e, 0xa0, - 0x0, 0x0, 0x0, 0x0, 0x40, 0x0, 0x1, 0x0, - - /* U+58D3 "壓" */ - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x76, 0x66, 0x66, 0x66, 0x66, 0x6d, 0x50, - 0x0, 0xa2, 0x64, 0x44, 0x70, 0x8, 0x20, 0x0, - 0x0, 0xa2, 0xc6, 0x66, 0xd0, 0xc, 0x3a, 0x0, - 0x0, 0xa2, 0xc2, 0x22, 0xc0, 0xc, 0x6, 0x0, - 0x0, 0xb1, 0x84, 0x44, 0x84, 0x6d, 0x6b, 0x10, - 0x0, 0xc0, 0xb6, 0x66, 0xd1, 0xb, 0x50, 0x0, - 0x0, 0xc0, 0xd6, 0x66, 0xc0, 0x47, 0x70, 0x0, - 0x2, 0x90, 0xb0, 0x0, 0xc0, 0x91, 0x81, 0x0, - 0x6, 0x30, 0xd6, 0x66, 0xc2, 0x70, 0x3b, 0x0, - 0x8, 0x0, 0xc0, 0x6, 0xb6, 0x0, 0xa, 0x70, - 0x22, 0x0, 0x10, 0x2, 0x90, 0x0, 0x0, 0x0, - 0x0, 0x7, 0x66, 0x67, 0xb6, 0x67, 0xa0, 0x0, - 0x0, 0x0, 0x0, 0x2, 0x90, 0x0, 0x1, 0x0, - 0x4, 0x66, 0x66, 0x67, 0xb6, 0x66, 0x6c, 0xb0, - 0x1, 0x10, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - - /* U+58EB "士" */ - 0x0, 0x0, 0x0, 0x7, 0x30, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x0, 0xb4, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, 0xb, 0x30, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, 0xb3, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0xb, 0x30, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0xb3, 0x0, 0x1, 0xb2, 0x7, 0x66, 0x66, - 0x6d, 0x86, 0x66, 0x66, 0x40, 0x0, 0x0, 0x0, - 0xb3, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xb, - 0x30, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xb3, - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xb, 0x30, - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xb3, 0x0, - 0x1, 0x0, 0x0, 0x46, 0x66, 0x6d, 0x86, 0x66, - 0xf6, 0x0, 0x1, 0x10, 0x0, 0x0, 0x0, 0x0, - 0x0, - - /* U+58F0 "声" */ - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x0, 0x1c, 0x10, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x0, 0xd0, 0x0, 0x4, 0x0, 0x37, - 0x66, 0x66, 0x6e, 0x66, 0x67, 0xb4, 0x0, 0x0, - 0x0, 0x0, 0xd0, 0x0, 0x10, 0x0, 0x0, 0x76, - 0x66, 0x6b, 0x66, 0x8b, 0x0, 0x0, 0x2, 0x0, - 0x0, 0x0, 0x0, 0x30, 0x0, 0x0, 0xc7, 0x66, - 0x6c, 0x66, 0x6d, 0x30, 0x0, 0xc, 0x20, 0x0, - 0xd0, 0x0, 0xc1, 0x0, 0x0, 0xc2, 0x0, 0xd, - 0x0, 0xc, 0x10, 0x0, 0xd, 0x66, 0x66, 0x66, - 0x66, 0xb1, 0x0, 0x0, 0xd0, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x0, 0x29, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x8, 0x20, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x4, 0x50, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x30, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - - /* U+58F2 "売" */ - 0x0, 0x0, 0x0, 0xa, 0x30, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x0, 0xb2, 0x0, 0x8, 0x10, 0x1, - 0x76, 0x66, 0x6d, 0x76, 0x66, 0x63, 0x0, 0x0, - 0x0, 0x0, 0xb2, 0x0, 0x60, 0x0, 0x0, 0x5, - 0x76, 0x66, 0x66, 0x67, 0x20, 0x0, 0x18, 0x66, - 0x66, 0x66, 0x66, 0x66, 0xa1, 0x6, 0x60, 0x0, - 0x0, 0x0, 0x0, 0x1c, 0x30, 0xb2, 0x0, 0x82, - 0x1, 0x60, 0x4, 0x0, 0x0, 0x0, 0xc, 0x40, - 0x2d, 0x0, 0x0, 0x0, 0x0, 0x0, 0xe0, 0x1, - 0xc0, 0x0, 0x0, 0x0, 0x0, 0x1e, 0x0, 0x1c, - 0x0, 0x1, 0x0, 0x0, 0x5, 0x90, 0x1, 0xc0, - 0x0, 0x60, 0x0, 0x1, 0xc2, 0x0, 0x1d, 0x0, - 0x8, 0x10, 0x5, 0x92, 0x0, 0x0, 0xdc, 0xcc, - 0xd4, 0x5, 0x20, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, - - /* U+5909 "変" */ - 0x0, 0x0, 0x0, 0x38, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x0, 0xb2, 0x0, 0x3, 0xa0, 0x7, - 0x66, 0x6d, 0x76, 0x6d, 0x76, 0x67, 0x20, 0x0, - 0x41, 0xd2, 0x0, 0xe2, 0x10, 0x0, 0x0, 0x1d, - 0x5d, 0x20, 0xe, 0x25, 0xa4, 0x0, 0xa, 0x20, - 0xd2, 0x0, 0xe2, 0x2, 0xd7, 0x17, 0x10, 0xa, - 0x10, 0x6, 0x0, 0x2, 0x70, 0x0, 0x0, 0xb8, - 0x0, 0x0, 0x20, 0x0, 0x0, 0x0, 0x7c, 0x66, - 0x66, 0xcd, 0x0, 0x0, 0x0, 0x67, 0x71, 0x0, - 0x5e, 0x30, 0x0, 0x0, 0x63, 0x0, 0xa1, 0x5d, - 0x10, 0x0, 0x0, 0x0, 0x0, 0x1, 0xec, 0x0, - 0x0, 0x0, 0x0, 0x0, 0x4, 0xa6, 0x9c, 0x61, - 0x0, 0x0, 0x3, 0x78, 0x40, 0x0, 0x29, 0xee, - 0xc6, 0x15, 0x30, 0x0, 0x0, 0x0, 0x0, 0x44, - 0x0, - - /* U+590F "夏" */ - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x83, 0x0, - 0x4, 0x76, 0x66, 0xaa, 0x66, 0x66, 0x65, 0x0, - 0x0, 0xa, 0x66, 0x96, 0x66, 0x6d, 0x30, 0x0, - 0x0, 0xc, 0x10, 0x0, 0x0, 0xe, 0x0, 0x0, - 0x0, 0xc, 0x66, 0x66, 0x66, 0x6e, 0x0, 0x0, - 0x0, 0xc, 0x66, 0x66, 0x66, 0x6e, 0x0, 0x0, - 0x0, 0xc, 0x10, 0x0, 0x0, 0xe, 0x0, 0x0, - 0x0, 0xc, 0x68, 0x86, 0x66, 0x6e, 0x0, 0x0, - 0x0, 0x4, 0xd, 0x20, 0x0, 0x51, 0x0, 0x0, - 0x0, 0x0, 0x9b, 0x66, 0x68, 0xf4, 0x0, 0x0, - 0x0, 0x7, 0x60, 0x80, 0x2d, 0x30, 0x0, 0x0, - 0x0, 0x74, 0x0, 0x1b, 0xd2, 0x0, 0x0, 0x0, - 0x4, 0x10, 0x2, 0x99, 0x8b, 0x62, 0x0, 0x0, - 0x0, 0x26, 0x86, 0x10, 0x1, 0x8d, 0xfd, 0x60, - 0x24, 0x30, 0x0, 0x0, 0x0, 0x0, 0x13, 0x0, - - /* U+5915 "夕" */ - 0x0, 0x0, 0x0, 0xa1, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x5, 0xf2, 0x0, 0x0, 0x0, 0x0, 0x0, - 0xb, 0x80, 0x0, 0x2, 0x0, 0x0, 0x0, 0x3f, - 0x66, 0x66, 0x6d, 0xb0, 0x0, 0x0, 0xa6, 0x0, - 0x0, 0x1f, 0x40, 0x0, 0x4, 0xc0, 0x0, 0x0, - 0x8c, 0x0, 0x0, 0xc, 0x94, 0x0, 0x0, 0xe4, - 0x0, 0x0, 0x75, 0xc, 0x80, 0x8, 0xa0, 0x0, - 0x4, 0x60, 0x2, 0xf4, 0x2e, 0x20, 0x0, 0x4, - 0x0, 0x0, 0x72, 0xd5, 0x0, 0x0, 0x0, 0x0, - 0x0, 0xb, 0x70, 0x0, 0x0, 0x0, 0x0, 0x1, - 0xc6, 0x0, 0x0, 0x0, 0x0, 0x0, 0x6b, 0x30, - 0x0, 0x0, 0x0, 0x2, 0x78, 0x30, 0x0, 0x0, - 0x0, 0x0, 0x43, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, - - /* U+5916 "外" */ - 0x0, 0x0, 0x77, 0x0, 0x0, 0xb3, 0x0, 0x0, - 0x0, 0xc, 0x60, 0x0, 0xe, 0x0, 0x0, 0x0, - 0x1, 0xe0, 0x0, 0x0, 0xe0, 0x0, 0x0, 0x0, - 0x6c, 0x66, 0xb6, 0xe, 0x0, 0x0, 0x0, 0xb, - 0x30, 0xd, 0x70, 0xe0, 0x0, 0x0, 0x2, 0xb0, - 0x2, 0xe0, 0xe, 0x40, 0x0, 0x0, 0x98, 0x80, - 0x68, 0x0, 0xe3, 0xb7, 0x0, 0x26, 0x9, 0x8c, - 0x20, 0xe, 0x1, 0xca, 0x5, 0x0, 0x7, 0xa0, - 0x0, 0xe0, 0x1, 0x90, 0x0, 0x0, 0xb3, 0x0, - 0xe, 0x0, 0x0, 0x0, 0x0, 0x67, 0x0, 0x0, - 0xe0, 0x0, 0x0, 0x0, 0x39, 0x0, 0x0, 0xe, - 0x0, 0x0, 0x0, 0x47, 0x0, 0x0, 0x0, 0xe0, - 0x0, 0x0, 0x53, 0x0, 0x0, 0x0, 0xe, 0x0, - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x40, 0x0, - 0x0, - - /* U+591A "多" */ - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x87, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x7, 0xc1, 0x0, 0x5, 0x0, 0x0, 0x0, 0x9a, - 0x66, 0x66, 0x8f, 0x60, 0x0, 0x39, 0x49, 0x30, - 0x3, 0xd4, 0x0, 0x6, 0x40, 0x3, 0xb0, 0x6b, - 0x20, 0x0, 0x0, 0x0, 0x0, 0x5a, 0x60, 0x0, - 0x0, 0x0, 0x0, 0x69, 0x8a, 0x10, 0x0, 0x0, - 0x25, 0x66, 0x20, 0xaa, 0x10, 0x0, 0x30, 0x0, - 0x0, 0x1b, 0x96, 0x66, 0x69, 0xf2, 0x0, 0x4, - 0xb7, 0x0, 0x0, 0x2d, 0x30, 0x2, 0x74, 0x3, - 0xb0, 0x3, 0xc2, 0x0, 0x0, 0x0, 0x0, 0xd0, - 0x7a, 0x10, 0x0, 0x0, 0x0, 0x1, 0x7a, 0x40, - 0x0, 0x0, 0x0, 0x26, 0x77, 0x30, 0x0, 0x0, - 0x0, 0x24, 0x30, 0x0, 0x0, 0x0, 0x0, 0x0, - - /* U+591C "夜" */ - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x0, 0x1a, 0x40, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x0, 0x4, 0xb0, 0x0, 0x2, 0x0, - 0x8, 0x66, 0x76, 0x66, 0x86, 0x66, 0x6b, 0x70, - 0x0, 0x0, 0xe5, 0x5, 0xd0, 0x0, 0x0, 0x0, - 0x0, 0x5, 0xc0, 0xa, 0x50, 0x0, 0x60, 0x0, - 0x0, 0xc, 0x30, 0x1d, 0x66, 0x67, 0xf2, 0x0, - 0x0, 0x4f, 0x40, 0x85, 0x53, 0x6, 0x90, 0x0, - 0x0, 0xbc, 0x21, 0xb5, 0xe, 0x1b, 0x30, 0x0, - 0x7, 0x2b, 0x28, 0x17, 0x15, 0x2c, 0x0, 0x0, - 0x13, 0xb, 0x42, 0x1, 0x90, 0x95, 0x0, 0x0, - 0x0, 0xb, 0x20, 0x0, 0x59, 0xc0, 0x0, 0x0, - 0x0, 0xb, 0x20, 0x0, 0x2f, 0x90, 0x0, 0x0, - 0x0, 0xb, 0x20, 0x3, 0xb2, 0x8c, 0x50, 0x0, - 0x0, 0xb, 0x21, 0x87, 0x0, 0x4, 0xdf, 0x90, - 0x0, 0x6, 0x35, 0x0, 0x0, 0x0, 0x4, 0x0, - - /* U+5920 "夠" */ - 0x0, 0x0, 0x85, 0x0, 0x1, 0x60, 0x0, 0x0, - 0x0, 0x3, 0xd2, 0x25, 0x6, 0xc0, 0x0, 0x0, - 0x0, 0x1b, 0x44, 0x6f, 0x3c, 0x10, 0x0, 0x50, - 0x1, 0x78, 0x50, 0xc4, 0x59, 0x66, 0x66, 0xe1, - 0x3, 0x1, 0x6a, 0x61, 0x90, 0x0, 0x0, 0xd0, - 0x0, 0x0, 0x96, 0x8, 0x10, 0x0, 0x20, 0xd0, - 0x0, 0x38, 0x7d, 0x10, 0x3c, 0x66, 0xd0, 0xd0, - 0x4, 0x30, 0xd8, 0x6c, 0x7a, 0x1, 0xc0, 0xd0, - 0x0, 0xa, 0x40, 0x2e, 0x4a, 0x1, 0xc1, 0xc0, - 0x0, 0x88, 0x40, 0x96, 0x2c, 0x66, 0xc1, 0xc0, - 0x4, 0x10, 0xd3, 0xc0, 0x37, 0x0, 0x72, 0xb0, - 0x0, 0x0, 0x2c, 0x20, 0x0, 0x0, 0x4, 0x90, - 0x0, 0x2, 0xb2, 0x0, 0x0, 0x22, 0x19, 0x70, - 0x0, 0x67, 0x0, 0x0, 0x0, 0x26, 0xef, 0x20, - 0x4, 0x0, 0x0, 0x0, 0x0, 0x0, 0x22, 0x0, - - /* U+5927 "大" */ - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x0, 0xc, 0x30, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x0, 0xe, 0x10, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x0, 0xd, 0x10, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x0, 0xd, 0x10, 0x0, 0x6, 0x10, - 0x6, 0x66, 0x66, 0x6e, 0x66, 0x66, 0x6a, 0x80, - 0x0, 0x0, 0x0, 0xf, 0x20, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x0, 0x1d, 0x60, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x0, 0x4a, 0x70, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x0, 0x95, 0x27, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x0, 0xe0, 0x8, 0x20, 0x0, 0x0, - 0x0, 0x0, 0x8, 0x70, 0x1, 0xc1, 0x0, 0x0, - 0x0, 0x0, 0x5b, 0x0, 0x0, 0x3c, 0x20, 0x0, - 0x0, 0x6, 0x90, 0x0, 0x0, 0x5, 0xf9, 0x20, - 0x2, 0x84, 0x0, 0x0, 0x0, 0x0, 0x3d, 0x60, - 0x13, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - - /* U+5929 "天" */ - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x40, 0x0, - 0x0, 0x28, 0x66, 0x69, 0x66, 0x69, 0xb2, 0x0, - 0x0, 0x0, 0x0, 0xd, 0x20, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x0, 0xd, 0x10, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x0, 0xe, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x0, 0xf, 0x0, 0x0, 0x3b, 0x0, - 0x6, 0x76, 0x66, 0x7e, 0x96, 0x66, 0x67, 0x30, - 0x0, 0x0, 0x0, 0x69, 0x42, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x0, 0xa5, 0x8, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x2, 0xd0, 0x7, 0x20, 0x0, 0x0, - 0x0, 0x0, 0xb, 0x50, 0x1, 0xc1, 0x0, 0x0, - 0x0, 0x0, 0x68, 0x0, 0x0, 0x5d, 0x20, 0x0, - 0x0, 0x5, 0x60, 0x0, 0x0, 0x6, 0xf8, 0x20, - 0x0, 0x64, 0x0, 0x0, 0x0, 0x0, 0x4e, 0x91, - 0x3, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - - /* U+592A "太" */ - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x0, 0xb, 0x50, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x0, 0xd, 0x20, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x0, 0xd, 0x20, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x0, 0xd, 0x10, 0x0, 0x8, 0x0, - 0x4, 0x76, 0x66, 0x6f, 0x86, 0x66, 0x7a, 0x50, - 0x0, 0x0, 0x0, 0x1d, 0x51, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x0, 0x5a, 0x26, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x0, 0x95, 0xa, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x0, 0xe0, 0x7, 0x50, 0x0, 0x0, - 0x0, 0x0, 0x7, 0x70, 0x0, 0xd1, 0x0, 0x0, - 0x0, 0x0, 0x2c, 0x54, 0x0, 0x5b, 0x0, 0x0, - 0x0, 0x1, 0xb1, 0xb, 0xa0, 0x9, 0xb0, 0x0, - 0x0, 0x2a, 0x10, 0x1, 0xf1, 0x0, 0xce, 0x60, - 0x4, 0x60, 0x0, 0x0, 0x20, 0x0, 0x1b, 0x61, - 0x11, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - - /* U+592B "夫" */ - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x0, 0xa5, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, 0xb, 0x30, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, 0xb3, 0x0, 0x6, 0x0, 0x0, 0x56, - 0x66, 0x6d, 0x86, 0x66, 0x83, 0x0, 0x0, 0x0, - 0x0, 0xc3, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0xc, 0x20, 0x0, 0x2, 0x0, 0x56, 0x66, 0x66, - 0xe6, 0x66, 0x68, 0xf5, 0x1, 0x0, 0x0, 0x1d, - 0x50, 0x0, 0x0, 0x0, 0x0, 0x0, 0x6, 0x81, - 0x60, 0x0, 0x0, 0x0, 0x0, 0x0, 0xd2, 0x9, - 0x10, 0x0, 0x0, 0x0, 0x0, 0x77, 0x0, 0x3b, - 0x0, 0x0, 0x0, 0x0, 0x69, 0x0, 0x0, 0x8a, - 0x0, 0x0, 0x0, 0x87, 0x0, 0x0, 0x0, 0x9d, - 0x50, 0x4, 0x72, 0x0, 0x0, 0x0, 0x0, 0x6e, - 0x71, 0x20, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - - /* U+592E "央" */ - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x0, 0xb5, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, 0xb, 0x30, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, 0xb3, 0x0, 0x20, 0x0, 0x0, 0xa, - 0x76, 0x6d, 0x86, 0x6d, 0x60, 0x0, 0x0, 0xa4, - 0x0, 0xb3, 0x0, 0xc3, 0x0, 0x0, 0xa, 0x40, - 0xb, 0x20, 0xc, 0x30, 0x0, 0x0, 0xa4, 0x0, - 0xc1, 0x0, 0xc3, 0x0, 0x0, 0xa, 0x40, 0xd, - 0x10, 0xc, 0x4b, 0x10, 0x57, 0x66, 0x66, 0xe9, - 0x66, 0x66, 0x63, 0x0, 0x0, 0x0, 0x4a, 0x33, - 0x0, 0x0, 0x0, 0x0, 0x0, 0xb, 0x40, 0x91, - 0x0, 0x0, 0x0, 0x0, 0x7, 0x90, 0x2, 0xb2, - 0x0, 0x0, 0x0, 0x8, 0x70, 0x0, 0x3, 0xe8, - 0x10, 0x0, 0x58, 0x10, 0x0, 0x0, 0x2, 0xcf, - 0x61, 0x41, 0x0, 0x0, 0x0, 0x0, 0x0, 0x20, - - /* U+5931 "失" */ - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x0, 0xa5, 0x0, 0x0, 0x0, 0x0, - 0x3, 0x40, 0xb, 0x30, 0x0, 0x0, 0x0, 0x0, - 0x8a, 0x0, 0xb3, 0x0, 0x0, 0x0, 0x0, 0xc, - 0x76, 0x6d, 0x86, 0x6a, 0xc1, 0x0, 0x1, 0x90, - 0x0, 0xc3, 0x0, 0x0, 0x0, 0x0, 0x71, 0x0, - 0xd, 0x10, 0x0, 0x0, 0x0, 0x3, 0x0, 0x0, - 0xe0, 0x0, 0x1, 0x80, 0x6, 0x76, 0x66, 0x7e, - 0x86, 0x66, 0x79, 0x40, 0x0, 0x0, 0x6, 0x94, - 0x10, 0x0, 0x0, 0x0, 0x0, 0x0, 0xc3, 0x9, - 0x0, 0x0, 0x0, 0x0, 0x0, 0x4a, 0x0, 0x57, - 0x0, 0x0, 0x0, 0x0, 0x1c, 0x10, 0x0, 0xa7, - 0x0, 0x0, 0x0, 0x3a, 0x10, 0x0, 0x0, 0xbc, - 0x30, 0x1, 0x66, 0x0, 0x0, 0x0, 0x0, 0xaf, - 0x80, 0x30, 0x0, 0x0, 0x0, 0x0, 0x0, 0x20, - - /* U+5947 "奇" */ - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x0, 0xa, 0x40, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x0, 0xe, 0x10, 0x0, 0x30, 0x0, - 0x0, 0x76, 0x66, 0x8d, 0x66, 0x68, 0xb2, 0x0, - 0x0, 0x0, 0x0, 0xc6, 0x76, 0x10, 0x0, 0x0, - 0x0, 0x0, 0x2a, 0x30, 0x4, 0xda, 0x0, 0x0, - 0x0, 0x46, 0x60, 0x0, 0x0, 0xa, 0x27, 0x10, - 0x18, 0x66, 0x66, 0x66, 0x66, 0x6a, 0x7a, 0x70, - 0x0, 0x0, 0x0, 0x0, 0x10, 0xd, 0x0, 0x0, - 0x0, 0xc, 0x66, 0x66, 0xe1, 0xd, 0x0, 0x0, - 0x0, 0xd, 0x10, 0x0, 0xe0, 0xd, 0x0, 0x0, - 0x0, 0xc, 0x10, 0x0, 0xe0, 0xd, 0x0, 0x0, - 0x0, 0xd, 0x66, 0x66, 0xe0, 0xd, 0x0, 0x0, - 0x0, 0xa, 0x0, 0x0, 0x50, 0xe, 0x0, 0x0, - 0x0, 0x0, 0x0, 0x0, 0x6, 0xed, 0x0, 0x0, - 0x0, 0x0, 0x0, 0x0, 0x0, 0x31, 0x0, 0x0, - - /* U+5951 "契" */ - 0x0, 0x0, 0x84, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, 0xa2, 0x24, 0x1, 0x11, 0x16, 0x20, - 0x4, 0x76, 0xc7, 0x65, 0x36, 0xe5, 0x5c, 0x50, - 0x0, 0x56, 0xc7, 0xa3, 0x0, 0xd0, 0xc, 0x20, - 0x0, 0x10, 0xa2, 0x0, 0x4, 0x90, 0xd, 0x0, - 0x4, 0x66, 0xc7, 0x7b, 0xb, 0x10, 0xd, 0x0, - 0x1, 0x10, 0xa2, 0x0, 0x94, 0x33, 0x6b, 0x0, - 0x0, 0x0, 0xb3, 0x37, 0x10, 0x6, 0xe3, 0x0, - 0x0, 0x0, 0x51, 0xc, 0x20, 0x0, 0x1, 0x0, - 0x5, 0x66, 0x66, 0x6f, 0x66, 0x66, 0x8f, 0x40, - 0x1, 0x0, 0x0, 0x87, 0x61, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x2, 0xd0, 0x9, 0x20, 0x0, 0x0, - 0x0, 0x0, 0x3c, 0x20, 0x0, 0xb8, 0x20, 0x0, - 0x0, 0x38, 0x70, 0x0, 0x0, 0x7, 0xfe, 0x80, - 0x15, 0x30, 0x0, 0x0, 0x0, 0x0, 0x15, 0x0, - - /* U+5957 "套" */ - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x0, 0xe, 0x30, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x0, 0x6b, 0x0, 0x0, 0x29, 0x0, - 0x0, 0x76, 0x66, 0xf6, 0x68, 0x76, 0x66, 0x20, - 0x0, 0x0, 0xa, 0x60, 0x0, 0x90, 0x0, 0x0, - 0x0, 0x0, 0x88, 0x0, 0x0, 0x7c, 0x40, 0x0, - 0x0, 0x8, 0x4e, 0x66, 0x66, 0x95, 0xdc, 0x81, - 0x2, 0x61, 0xe, 0x0, 0x0, 0x80, 0x7, 0x50, - 0x2, 0x0, 0xe, 0x66, 0x66, 0x63, 0x0, 0x0, - 0x0, 0x0, 0xe, 0x66, 0x66, 0x7b, 0x10, 0x0, - 0x0, 0x0, 0xe, 0x0, 0x0, 0x0, 0x5, 0x10, - 0x6, 0x76, 0x6b, 0x79, 0x66, 0x66, 0x6b, 0x90, - 0x0, 0x0, 0x0, 0xc4, 0x2, 0x40, 0x0, 0x0, - 0x0, 0x0, 0x19, 0x20, 0x0, 0x3c, 0x70, 0x0, - 0x0, 0x1, 0xeb, 0xa8, 0x76, 0x55, 0xd4, 0x0, - 0x0, 0x0, 0x42, 0x0, 0x0, 0x0, 0x11, 0x0, - - /* U+5973 "女" */ - 0x0, 0x0, 0x0, 0x96, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, 0xf, 0x40, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x4, 0xe0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x88, 0x0, 0x0, 0x2, 0x0, 0x56, 0x66, - 0x6d, 0x86, 0x66, 0x66, 0xdb, 0x0, 0x0, 0x2, - 0xd0, 0x0, 0x5b, 0x0, 0x0, 0x0, 0x0, 0x77, - 0x0, 0xb, 0x60, 0x0, 0x0, 0x0, 0xd, 0x10, - 0x0, 0xf1, 0x0, 0x0, 0x0, 0x4, 0xa0, 0x0, - 0x6a, 0x0, 0x0, 0x0, 0x0, 0x48, 0x61, 0xe, - 0x30, 0x0, 0x0, 0x0, 0x0, 0x1, 0x7d, 0xe2, - 0x0, 0x0, 0x0, 0x0, 0x0, 0x7, 0xc5, 0xdb, - 0x40, 0x0, 0x0, 0x0, 0x2b, 0x70, 0x0, 0x7f, - 0x70, 0x0, 0x5, 0x86, 0x10, 0x0, 0x0, 0x3b, - 0x0, 0x35, 0x10, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, - - /* U+5979 "她" */ - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x7, 0x70, 0x0, 0x0, 0x82, 0x0, 0x0, - 0x0, 0x9, 0x50, 0x0, 0x0, 0xd0, 0x0, 0x0, - 0x0, 0xb, 0x20, 0x2, 0x80, 0xd0, 0x0, 0x0, - 0x0, 0xd, 0x2, 0x32, 0xa0, 0xd0, 0x3, 0x0, - 0x6, 0x7d, 0x6a, 0x82, 0xa0, 0xd5, 0x6f, 0x20, - 0x0, 0x2a, 0x8, 0x68, 0xc6, 0xd0, 0xd, 0x0, - 0x0, 0x57, 0xb, 0x12, 0xa0, 0xd0, 0xe, 0x0, - 0x0, 0x83, 0xd, 0x2, 0xa0, 0xd0, 0xe, 0x0, - 0x0, 0xb0, 0x1b, 0x2, 0xa0, 0xd0, 0x1d, 0x0, - 0x0, 0xc0, 0x57, 0x2, 0xa0, 0xd3, 0xc8, 0x0, - 0x0, 0x59, 0xc3, 0x2, 0xa0, 0xd1, 0x0, 0x30, - 0x0, 0x2, 0xbd, 0x52, 0xa0, 0x70, 0x0, 0x70, - 0x0, 0x9, 0x2, 0xc2, 0xb0, 0x0, 0x0, 0xc0, - 0x1, 0x81, 0x0, 0x0, 0xdb, 0xbb, 0xbc, 0xd2, - 0x4, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - - /* U+597D "好" */ - 0x0, 0x7, 0x50, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0xb, 0x40, 0x4, 0x66, 0x66, 0x99, 0x0, - 0x0, 0xd, 0x0, 0x0, 0x0, 0x0, 0xc4, 0x0, - 0x26, 0x6e, 0x67, 0x80, 0x0, 0x7, 0x20, 0x0, - 0x0, 0x49, 0x6, 0x70, 0x0, 0xb6, 0x0, 0x0, - 0x0, 0x75, 0x9, 0x40, 0x0, 0xc1, 0x0, 0x0, - 0x0, 0xa1, 0xc, 0x10, 0x0, 0xc1, 0x3, 0x30, - 0x0, 0xc0, 0xd, 0x36, 0x66, 0xd6, 0x68, 0x70, - 0x3, 0x90, 0x39, 0x0, 0x0, 0xc1, 0x0, 0x0, - 0x5, 0x80, 0x85, 0x0, 0x0, 0xc1, 0x0, 0x0, - 0x0, 0x28, 0xf4, 0x0, 0x0, 0xc1, 0x0, 0x0, - 0x0, 0x8, 0x7c, 0xa0, 0x0, 0xc1, 0x0, 0x0, - 0x0, 0x66, 0x0, 0xa0, 0x0, 0xd1, 0x0, 0x0, - 0x7, 0x30, 0x0, 0x1, 0x7d, 0xe0, 0x0, 0x0, - 0x20, 0x0, 0x0, 0x0, 0x3, 0x20, 0x0, 0x0, - - /* U+5982 "如" */ - 0x0, 0x0, 0xa2, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x1e, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x4, 0xb0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x67, 0x0, 0x60, 0xb6, 0x66, 0xc4, 0x6, 0x7c, - 0x86, 0x8c, 0xd, 0x0, 0xb, 0x10, 0x0, 0xc0, - 0x5, 0x80, 0xd0, 0x0, 0xb1, 0x0, 0xc, 0x0, - 0x85, 0xd, 0x0, 0xb, 0x10, 0x3, 0x90, 0xb, - 0x20, 0xd0, 0x0, 0xb1, 0x0, 0x75, 0x0, 0xd0, - 0xd, 0x0, 0xb, 0x10, 0xb, 0x40, 0x3a, 0x0, - 0xd0, 0x0, 0xb1, 0x0, 0x4, 0x9c, 0x80, 0xd, - 0x0, 0xb, 0x10, 0x0, 0x3, 0xbb, 0xc0, 0xd6, - 0x66, 0xd1, 0x0, 0x3, 0xa0, 0x9, 0x2d, 0x0, - 0xb, 0x20, 0x6, 0x70, 0x0, 0x0, 0x70, 0x0, - 0x20, 0x4, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, - - /* U+5987 "妇" */ - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0xb4, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0xe, 0x10, 0x0, 0x0, 0x0, 0x1, 0x0, 0x1, - 0xd0, 0x0, 0x76, 0x66, 0x66, 0xe3, 0x16, 0x8c, - 0x66, 0xb0, 0x0, 0x0, 0xe, 0x0, 0x6, 0x70, - 0x4a, 0x0, 0x0, 0x0, 0xe0, 0x0, 0xa3, 0x6, - 0x70, 0x0, 0x0, 0xe, 0x0, 0xd, 0x0, 0x94, - 0x26, 0x66, 0x66, 0xe0, 0x1, 0xb0, 0xc, 0x0, - 0x20, 0x0, 0xe, 0x0, 0x48, 0x1, 0xc0, 0x0, - 0x0, 0x0, 0xe0, 0x0, 0x49, 0x97, 0x0, 0x0, - 0x0, 0xe, 0x0, 0x0, 0xd, 0xc3, 0x0, 0x0, - 0x0, 0xe0, 0x0, 0x6, 0x63, 0xd3, 0x66, 0x66, - 0x6e, 0x0, 0x3, 0x80, 0x3, 0x1, 0x0, 0x0, - 0xe0, 0x3, 0x60, 0x0, 0x0, 0x0, 0x0, 0xa, - 0x0, 0x20, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - - /* U+59B3 "妳" */ - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x5, 0xb0, 0x0, 0x8, 0x30, 0x0, 0x0, - 0x0, 0x8, 0x70, 0x0, 0xf, 0x20, 0x0, 0x0, - 0x0, 0xb, 0x30, 0x0, 0x49, 0x0, 0x0, 0x10, - 0x5, 0x6e, 0x66, 0xa0, 0xa8, 0x66, 0x66, 0xe2, - 0x1, 0x3b, 0x3, 0xc0, 0xa0, 0x0, 0x5, 0x60, - 0x0, 0x76, 0x6, 0x86, 0x20, 0x18, 0x4, 0x0, - 0x0, 0xb1, 0x9, 0x43, 0x0, 0x1c, 0x0, 0x0, - 0x0, 0xc0, 0xd, 0x0, 0x33, 0x1c, 0x10, 0x0, - 0x4, 0x80, 0x2c, 0x0, 0x99, 0x1c, 0x28, 0x0, - 0x1, 0x77, 0x87, 0x0, 0xc0, 0x1c, 0x8, 0x90, - 0x0, 0x2, 0xfb, 0x16, 0x30, 0x1c, 0x0, 0xf1, - 0x0, 0x8, 0x67, 0xc3, 0x0, 0x1c, 0x0, 0x30, - 0x0, 0x58, 0x0, 0x20, 0x0, 0x2c, 0x0, 0x0, - 0x5, 0x50, 0x0, 0x0, 0x7, 0xf8, 0x0, 0x0, - 0x1, 0x0, 0x0, 0x0, 0x0, 0x20, 0x0, 0x0, - - /* U+59B9 "妹" */ - 0x0, 0x0, 0x0, 0x0, 0x0, 0x10, 0x0, 0x0, - 0x0, 0x9, 0x80, 0x0, 0x0, 0xe1, 0x0, 0x0, - 0x0, 0xc, 0x30, 0x0, 0x0, 0xd0, 0x0, 0x0, - 0x0, 0xd, 0x0, 0x1, 0x22, 0xd2, 0x38, 0x0, - 0x16, 0x7d, 0x68, 0x74, 0x54, 0xd4, 0x44, 0x10, - 0x2, 0x66, 0x8, 0x50, 0x0, 0xd0, 0x0, 0x0, - 0x0, 0xa2, 0xb, 0x20, 0x0, 0xd0, 0x1, 0x40, - 0x0, 0xc0, 0xd, 0x37, 0x6a, 0xe7, 0x67, 0x80, - 0x2, 0x90, 0x2a, 0x0, 0xd, 0xd6, 0x0, 0x0, - 0x7, 0x50, 0x66, 0x0, 0x48, 0xd6, 0x10, 0x0, - 0x5, 0x83, 0xb1, 0x0, 0xb1, 0xd1, 0xa0, 0x0, - 0x0, 0x8, 0xf3, 0x5, 0x60, 0xd0, 0x84, 0x0, - 0x0, 0x9, 0x4d, 0x29, 0x0, 0xd0, 0x1d, 0x40, - 0x0, 0x64, 0x2, 0x80, 0x0, 0xd0, 0x4, 0xb2, - 0x4, 0x40, 0x2, 0x0, 0x0, 0xe0, 0x0, 0x0, - 0x1, 0x0, 0x0, 0x0, 0x0, 0x60, 0x0, 0x0, - - /* U+59BB "妻" */ - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x0, 0xd, 0x20, 0x0, 0x12, 0x0, - 0x6, 0x76, 0x66, 0x6e, 0x66, 0x66, 0xbc, 0x20, - 0x0, 0x0, 0x0, 0xe, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x7, 0x66, 0x6e, 0x66, 0x6d, 0x20, 0x0, - 0x0, 0x0, 0x0, 0xe, 0x0, 0xe, 0x4, 0x20, - 0x7, 0x66, 0x66, 0x6e, 0x66, 0x6e, 0x69, 0x80, - 0x0, 0x0, 0x0, 0xe, 0x0, 0xe, 0x0, 0x0, - 0x0, 0x18, 0x66, 0xa8, 0x66, 0x6e, 0x0, 0x0, - 0x0, 0x0, 0x3, 0xc0, 0x0, 0x0, 0x5, 0x20, - 0x28, 0x66, 0x6c, 0x86, 0x66, 0xb6, 0x69, 0x80, - 0x0, 0x0, 0x2b, 0x0, 0x6, 0xa0, 0x0, 0x0, - 0x0, 0x0, 0x79, 0x42, 0x2d, 0x10, 0x0, 0x0, - 0x0, 0x0, 0x0, 0x39, 0xfd, 0x94, 0x0, 0x0, - 0x0, 0x0, 0x2, 0x8a, 0x20, 0x5b, 0xe2, 0x0, - 0x3, 0x56, 0x76, 0x10, 0x0, 0x0, 0x34, 0x0, - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - - /* U+59C9 "姉" */ - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0xb6, 0x0, 0x0, 0xc, 0x30, 0x0, 0x0, - 0xe, 0x10, 0x0, 0x0, 0xd0, 0x0, 0x0, 0x2, - 0xc0, 0x0, 0x0, 0xd, 0x0, 0x20, 0x26, 0x9b, - 0x68, 0x68, 0x66, 0xe6, 0x69, 0x50, 0x29, 0x40, - 0x95, 0x0, 0xd, 0x0, 0x0, 0x0, 0xd0, 0xc, - 0x13, 0x0, 0xd0, 0x5, 0x0, 0x2b, 0x0, 0xd0, - 0xd6, 0x6e, 0x66, 0xe1, 0x6, 0x60, 0x49, 0xc, - 0x0, 0xd0, 0xd, 0x0, 0xa1, 0x8, 0x50, 0xc0, - 0xd, 0x0, 0xd0, 0x7, 0x72, 0xd0, 0xc, 0x0, - 0xd0, 0xd, 0x0, 0x0, 0xae, 0x50, 0xc0, 0xd, - 0x0, 0xd0, 0x0, 0xb, 0x3c, 0x6d, 0x0, 0xd3, - 0x9d, 0x0, 0x9, 0x20, 0x3, 0x20, 0xd, 0x2, - 0x20, 0x6, 0x20, 0x0, 0x0, 0x0, 0xd0, 0x0, - 0x2, 0x0, 0x0, 0x0, 0x0, 0x3, 0x0, 0x0, - - /* U+59CB "始" */ - 0x0, 0x0, 0x0, 0x0, 0x0, 0x10, 0x0, 0x0, - 0x0, 0x6, 0xa0, 0x0, 0x3, 0xe1, 0x0, 0x0, - 0x0, 0x9, 0x60, 0x0, 0x8, 0x80, 0x0, 0x0, - 0x0, 0xc, 0x10, 0x0, 0xc, 0x10, 0x20, 0x0, - 0x5, 0x6e, 0x66, 0xa0, 0x56, 0x0, 0x76, 0x0, - 0x2, 0x49, 0x4, 0xa0, 0xa0, 0x0, 0xc, 0x60, - 0x0, 0x85, 0x7, 0x7a, 0xb9, 0x87, 0x68, 0xe0, - 0x0, 0xc0, 0xa, 0x34, 0x61, 0x0, 0x0, 0x60, - 0x1, 0xb0, 0xd, 0x0, 0x20, 0x0, 0x3, 0x0, - 0x5, 0x70, 0x2b, 0x0, 0xe6, 0x66, 0x6e, 0x30, - 0x4, 0x84, 0x86, 0x0, 0xe0, 0x0, 0xe, 0x0, - 0x0, 0x5, 0xf8, 0x0, 0xe0, 0x0, 0xe, 0x0, - 0x0, 0x8, 0x6b, 0xa0, 0xe0, 0x0, 0xe, 0x0, - 0x0, 0x47, 0x0, 0x80, 0xe6, 0x66, 0x6e, 0x0, - 0x4, 0x50, 0x0, 0x0, 0xe0, 0x0, 0xd, 0x0, - 0x2, 0x0, 0x0, 0x0, 0x20, 0x0, 0x1, 0x0, - - /* U+59D0 "姐" */ - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x5, 0xa0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x8, 0x70, 0x0, 0xd6, 0x66, 0x6e, 0x10, - 0x0, 0xc, 0x20, 0x0, 0xe0, 0x0, 0xd, 0x0, - 0x16, 0x6e, 0x66, 0xa1, 0xe0, 0x0, 0xd, 0x0, - 0x0, 0x49, 0x2, 0xc0, 0xe0, 0x0, 0xd, 0x0, - 0x0, 0x85, 0x6, 0x80, 0xe6, 0x66, 0x6d, 0x0, - 0x0, 0xc0, 0x9, 0x40, 0xe0, 0x0, 0xd, 0x0, - 0x1, 0xb0, 0xd, 0x0, 0xe0, 0x0, 0xd, 0x0, - 0x6, 0x50, 0x2b, 0x0, 0xe0, 0x0, 0xd, 0x0, - 0x5, 0x84, 0x85, 0x0, 0xe6, 0x66, 0x6d, 0x0, - 0x0, 0x5, 0xf8, 0x0, 0xe0, 0x0, 0xd, 0x0, - 0x0, 0x9, 0x47, 0xd0, 0xe0, 0x0, 0xd, 0x0, - 0x0, 0x66, 0x0, 0x60, 0xe0, 0x0, 0xd, 0x20, - 0x5, 0x40, 0x0, 0x76, 0xa6, 0x66, 0x6a, 0xa3, - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - - /* U+59D4 "委" */ - 0x0, 0x0, 0x0, 0x0, 0x14, 0x7c, 0x70, 0x0, - 0x0, 0x3, 0x56, 0x7a, 0xd5, 0x43, 0x20, 0x0, - 0x0, 0x0, 0x0, 0x3, 0xb0, 0x0, 0x2, 0x30, - 0x4, 0x76, 0x66, 0x7b, 0xd8, 0x66, 0x69, 0xa0, - 0x0, 0x0, 0x2, 0xc5, 0xb4, 0x70, 0x0, 0x0, - 0x0, 0x0, 0x4b, 0x22, 0xb0, 0x4c, 0x61, 0x0, - 0x0, 0x18, 0x60, 0x5, 0x90, 0x1, 0xaf, 0xc3, - 0x4, 0x40, 0x0, 0x7c, 0x0, 0x0, 0x2, 0x40, - 0x5, 0x66, 0x66, 0xe7, 0x66, 0x66, 0x6b, 0xd1, - 0x1, 0x0, 0xb, 0x40, 0x0, 0xc4, 0x0, 0x0, - 0x0, 0x0, 0x5b, 0x30, 0x7, 0xa0, 0x0, 0x0, - 0x0, 0x0, 0x0, 0x37, 0xcf, 0x71, 0x0, 0x0, - 0x0, 0x0, 0x0, 0x3a, 0x82, 0x8e, 0xb2, 0x0, - 0x0, 0x25, 0x78, 0x61, 0x0, 0x0, 0x8e, 0x0, - 0x3, 0x20, 0x0, 0x0, 0x0, 0x0, 0x2, 0x0, - - /* U+5A18 "娘" */ - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x2, 0xc1, 0x0, 0x1, 0x91, 0x0, 0x0, - 0x0, 0x5, 0xb0, 0x0, 0x0, 0x69, 0x1, 0x0, - 0x0, 0x8, 0x60, 0x0, 0xc6, 0x77, 0x6e, 0x0, - 0x4, 0x5d, 0x75, 0x91, 0xd0, 0x0, 0xd, 0x0, - 0x1, 0x1d, 0x1, 0xc0, 0xd6, 0x66, 0x6d, 0x0, - 0x0, 0x39, 0x4, 0x90, 0xd0, 0x0, 0xd, 0x0, - 0x0, 0x75, 0x7, 0x50, 0xd0, 0x0, 0xd, 0x0, - 0x0, 0xb1, 0xa, 0x20, 0xd6, 0x86, 0x6d, 0x0, - 0x0, 0xc0, 0xc, 0x0, 0xd0, 0x80, 0x4, 0x80, - 0x0, 0x87, 0x69, 0x0, 0xd0, 0x55, 0x3a, 0x30, - 0x0, 0x2, 0xeb, 0x10, 0xd0, 0xc, 0x60, 0x0, - 0x0, 0x4, 0x97, 0xc0, 0xd0, 0x26, 0xb1, 0x0, - 0x0, 0x2a, 0x0, 0x40, 0xe9, 0x50, 0x7e, 0x71, - 0x2, 0x80, 0x0, 0x0, 0xd4, 0x0, 0x4, 0x80, - 0x2, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - - /* U+5A5A "婚" */ - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0xa, 0x60, 0x0, 0x0, 0x27, 0xd9, 0x0, - 0x0, 0xd, 0x20, 0xb, 0x56, 0xe2, 0x0, 0x0, - 0x0, 0xd, 0x0, 0xc, 0x0, 0xc0, 0x0, 0x0, - 0x5, 0x7c, 0x69, 0x4c, 0x66, 0xd7, 0x67, 0xa0, - 0x0, 0x76, 0xa, 0x3c, 0x0, 0x59, 0x0, 0x0, - 0x0, 0xb2, 0xd, 0xc, 0x2, 0x2c, 0x40, 0x50, - 0x0, 0xc0, 0xc, 0xe, 0xa5, 0x2, 0xd7, 0x90, - 0x3, 0x90, 0x39, 0x5, 0x0, 0x0, 0x8, 0xd0, - 0x7, 0x40, 0x85, 0x9, 0x66, 0x66, 0x6d, 0x0, - 0x4, 0x84, 0xc0, 0xa, 0x30, 0x0, 0xd, 0x0, - 0x0, 0x8, 0xe4, 0xa, 0x76, 0x66, 0x6d, 0x0, - 0x0, 0xb, 0x2d, 0x3a, 0x30, 0x0, 0xd, 0x0, - 0x0, 0x82, 0x2, 0x3a, 0x30, 0x0, 0xd, 0x0, - 0x6, 0x20, 0x0, 0xa, 0x76, 0x66, 0x6d, 0x0, - 0x10, 0x0, 0x0, 0x4, 0x0, 0x0, 0x2, 0x0, - - /* U+5A66 "婦" */ - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0xc, 0x30, 0x5, 0x66, 0x66, 0x6a, 0x0, - 0x0, 0xe, 0x0, 0x1, 0x0, 0x0, 0xd, 0x0, - 0x0, 0x3a, 0x0, 0x2, 0x86, 0x66, 0x6d, 0x0, - 0x14, 0x89, 0x48, 0x10, 0x0, 0x0, 0xd, 0x0, - 0x4, 0xb4, 0x2d, 0x26, 0x76, 0x66, 0x6d, 0x0, - 0x0, 0xc0, 0xd, 0x30, 0x0, 0x0, 0x0, 0x30, - 0x2, 0xa0, 0x3a, 0xa6, 0x66, 0xd6, 0x68, 0xd1, - 0x6, 0x60, 0x68, 0xc0, 0x0, 0xd0, 0x4, 0x0, - 0xa, 0x10, 0xb2, 0xa, 0x66, 0xe6, 0x6c, 0x0, - 0x6, 0x73, 0xc0, 0xc, 0x0, 0xd0, 0xd, 0x0, - 0x0, 0xb, 0xd3, 0xc, 0x0, 0xd0, 0xd, 0x0, - 0x0, 0x1b, 0x3e, 0x2c, 0x0, 0xd0, 0xc, 0x0, - 0x0, 0x91, 0x2, 0x1c, 0x0, 0xd3, 0xb8, 0x0, - 0x6, 0x10, 0x0, 0x0, 0x0, 0xe0, 0x0, 0x0, - 0x10, 0x0, 0x0, 0x0, 0x0, 0x60, 0x0, 0x0, - - /* U+5A92 "媒" */ - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x8, 0x70, 0x2, 0xa0, 0x0, 0xa3, 0x0, - 0x0, 0xa, 0x40, 0x1, 0xb0, 0x0, 0xd0, 0x10, - 0x0, 0xd, 0x0, 0x66, 0xd6, 0x66, 0xe7, 0xb1, - 0x3, 0x4d, 0x46, 0x51, 0xb0, 0x0, 0xd0, 0x0, - 0x3, 0x69, 0x28, 0x71, 0xd6, 0x66, 0xe0, 0x0, - 0x0, 0x84, 0xa, 0x31, 0xb0, 0x0, 0xd0, 0x0, - 0x0, 0xb0, 0xc, 0x2, 0xd6, 0x66, 0xe0, 0x0, - 0x0, 0xb0, 0xc, 0x1, 0x70, 0xa2, 0x40, 0x0, - 0x4, 0x70, 0x48, 0x0, 0x0, 0xd0, 0x4, 0x70, - 0x3, 0x84, 0x93, 0x67, 0x6d, 0xf9, 0x66, 0x51, - 0x0, 0x7, 0xf5, 0x0, 0x5a, 0xd7, 0x10, 0x0, - 0x0, 0xa, 0x4c, 0x42, 0xb0, 0xd1, 0xb1, 0x0, - 0x0, 0x56, 0x1, 0x5a, 0x0, 0xd0, 0x3e, 0x72, - 0x4, 0x60, 0x4, 0x60, 0x0, 0xe0, 0x3, 0x81, - 0x2, 0x0, 0x1, 0x0, 0x0, 0x70, 0x0, 0x0, - - /* U+5ABD "媽" */ - 0x0, 0x8, 0x40, 0x3, 0x0, 0x0, 0x7, 0x10, - 0x0, 0xd, 0x20, 0xd, 0x66, 0xe6, 0x66, 0x30, - 0x0, 0x1d, 0x0, 0xd, 0x0, 0xd0, 0x4, 0x0, - 0x16, 0x8b, 0x68, 0x4d, 0x55, 0xd5, 0x55, 0x0, - 0x2, 0x95, 0xa, 0x3d, 0x0, 0xd0, 0x1, 0x0, - 0x0, 0xc1, 0xc, 0xd, 0x66, 0xe6, 0x6b, 0x20, - 0x0, 0xc0, 0xc, 0xd, 0x0, 0xd0, 0x0, 0x0, - 0x4, 0x80, 0x39, 0xd, 0x0, 0xd0, 0x0, 0x50, - 0x8, 0x40, 0x75, 0xc, 0x66, 0x66, 0x66, 0xf1, - 0xa, 0x50, 0xc1, 0x0, 0x0, 0x20, 0x60, 0xe0, - 0x0, 0x3a, 0xe3, 0x4, 0x51, 0x94, 0x77, 0xd0, - 0x0, 0xa, 0x6d, 0x38, 0x38, 0x5b, 0x3b, 0xb0, - 0x0, 0x65, 0x1, 0xa7, 0x27, 0x2, 0x5, 0x90, - 0x4, 0x40, 0x0, 0x30, 0x0, 0x37, 0xae, 0x50, - 0x12, 0x0, 0x0, 0x0, 0x0, 0x0, 0x56, 0x0, - - /* U+5ACC "嫌" */ - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x2, 0xc0, 0x0, 0x27, 0x0, 0xb1, 0x0, 0x0, - 0x59, 0x0, 0x0, 0xb3, 0x37, 0x1, 0x0, 0x8, - 0x50, 0x27, 0x69, 0x6a, 0x68, 0xc1, 0x25, 0xc6, - 0x59, 0x0, 0x92, 0xb1, 0x0, 0x0, 0x2d, 0x13, - 0xa2, 0x6c, 0x7c, 0x6a, 0x30, 0x1, 0xb0, 0x57, - 0x0, 0x92, 0xb1, 0xb1, 0x0, 0x47, 0x8, 0x45, - 0x6b, 0x7c, 0x6c, 0xb5, 0x7, 0x30, 0xb0, 0x10, - 0x92, 0xb1, 0xb1, 0x0, 0xb0, 0xb, 0x3, 0x6c, - 0x7c, 0x6c, 0x10, 0x6, 0x88, 0x70, 0x3, 0xf2, - 0xb6, 0x50, 0x0, 0x0, 0xdc, 0x20, 0xbb, 0x2b, - 0x45, 0x0, 0x0, 0x65, 0x37, 0x74, 0x92, 0xb1, - 0xa2, 0x0, 0x28, 0x0, 0x54, 0x9, 0x2b, 0x12, - 0xe6, 0x16, 0x0, 0x33, 0x0, 0x92, 0xb1, 0x3, - 0x1, 0x0, 0x0, 0x0, 0x4, 0x3, 0x0, 0x0, - - /* U+5B09 "嬉" */ - 0x0, 0xb, 0x10, 0x0, 0x0, 0xc1, 0x0, 0x0, - 0x0, 0x2c, 0x0, 0x0, 0x0, 0xd0, 0x4, 0x40, - 0x0, 0x58, 0x0, 0x57, 0x66, 0xe6, 0x66, 0x50, - 0x13, 0x97, 0x38, 0x14, 0x66, 0xe6, 0x8b, 0x0, - 0x15, 0xc4, 0x3d, 0x3, 0x10, 0x0, 0x3, 0x0, - 0x0, 0xc0, 0x2a, 0xb, 0x66, 0x66, 0x7d, 0x0, - 0x3, 0x90, 0x57, 0xb, 0x10, 0x0, 0x2b, 0x0, - 0x7, 0x50, 0x93, 0x8, 0x96, 0x66, 0x96, 0x0, - 0xb, 0x10, 0xc0, 0x0, 0x68, 0x5, 0x70, 0x10, - 0xb, 0x53, 0xa1, 0x75, 0x68, 0x57, 0x56, 0xa1, - 0x0, 0x2d, 0xc2, 0x7, 0x66, 0x66, 0x6a, 0x10, - 0x0, 0x3a, 0x3d, 0xc, 0x0, 0x0, 0xd, 0x0, - 0x0, 0xa1, 0x1, 0xc, 0x0, 0x0, 0xd, 0x0, - 0x8, 0x20, 0x0, 0xd, 0x66, 0x66, 0x6d, 0x0, - 0x21, 0x0, 0x0, 0x5, 0x0, 0x0, 0x2, 0x0, - - /* U+5B50 "子" */ - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x52, 0x0, - 0x0, 0x6, 0x66, 0x66, 0x66, 0x68, 0xfa, 0x0, - 0x0, 0x0, 0x0, 0x0, 0x0, 0x4b, 0x30, 0x0, - 0x0, 0x0, 0x0, 0x0, 0x5, 0x60, 0x0, 0x0, - 0x0, 0x0, 0x0, 0x3, 0xd4, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x0, 0x2, 0xd0, 0x0, 0x1, 0x30, - 0x6, 0x66, 0x66, 0x67, 0xd6, 0x66, 0x6a, 0xc1, - 0x0, 0x0, 0x0, 0x2, 0xc0, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x0, 0x2, 0xc0, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x0, 0x2, 0xc0, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x0, 0x2, 0xc0, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x0, 0x2, 0xc0, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x2, 0x14, 0xc0, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x3, 0xaf, 0x80, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x0, 0x5, 0x0, 0x0, 0x0, 0x0, - - /* U+5B57 "字" */ - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x0, 0x9, 0x40, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x0, 0x2, 0xe0, 0x0, 0x0, 0x0, - 0x0, 0x28, 0x66, 0x66, 0x96, 0x66, 0x6b, 0x80, - 0x0, 0x94, 0x0, 0x0, 0x0, 0x0, 0x19, 0x10, - 0x1, 0xc2, 0x56, 0x66, 0x66, 0x6c, 0x40, 0x0, - 0x0, 0x0, 0x20, 0x0, 0x0, 0xa9, 0x20, 0x0, - 0x0, 0x0, 0x0, 0x0, 0x8, 0x30, 0x0, 0x0, - 0x0, 0x0, 0x0, 0x3, 0xd1, 0x0, 0x0, 0x10, - 0x6, 0x66, 0x66, 0x67, 0xd6, 0x66, 0x6a, 0xd1, - 0x0, 0x0, 0x0, 0x2, 0xb0, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x0, 0x2, 0xb0, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x0, 0x2, 0xb0, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x0, 0x2, 0xb0, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x5, 0xae, 0x90, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x0, 0x6, 0x0, 0x0, 0x0, 0x0, - - /* U+5B58 "存" */ - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x0, 0x2d, 0x20, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x0, 0x7b, 0x0, 0x0, 0xa, 0x30, - 0x4, 0x66, 0x66, 0xf7, 0x66, 0x66, 0x66, 0x50, - 0x0, 0x0, 0x5, 0xa0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, 0xc, 0x56, 0x66, 0x66, 0x99, 0x0, - 0x0, 0x0, 0xd6, 0x0, 0x0, 0x4, 0xb3, 0x0, - 0x0, 0x3, 0xe0, 0x0, 0x0, 0x76, 0x0, 0x0, - 0x0, 0x1b, 0xe0, 0x0, 0x0, 0xf1, 0x0, 0x0, - 0x0, 0xa1, 0xe0, 0x0, 0x0, 0xe0, 0x2, 0x80, - 0x7, 0x10, 0xe0, 0x76, 0x66, 0xe6, 0x66, 0x61, - 0x10, 0x0, 0xe0, 0x0, 0x0, 0xe0, 0x0, 0x0, - 0x0, 0x0, 0xe0, 0x0, 0x0, 0xe0, 0x0, 0x0, - 0x0, 0x0, 0xe0, 0x0, 0x0, 0xe0, 0x0, 0x0, - 0x0, 0x0, 0xf0, 0x1, 0x8d, 0xc0, 0x0, 0x0, - 0x0, 0x0, 0x50, 0x0, 0x5, 0x10, 0x0, 0x0, - - /* U+5B63 "季" */ - 0x0, 0x0, 0x0, 0x0, 0x3, 0x7c, 0x80, 0x0, - 0x0, 0x3, 0x45, 0x79, 0xd8, 0x64, 0x30, 0x0, - 0x0, 0x0, 0x0, 0x1, 0xb0, 0x0, 0x0, 0x20, - 0x6, 0x66, 0x66, 0x68, 0xd6, 0x66, 0x6a, 0xc1, - 0x0, 0x0, 0x1, 0xc6, 0xb6, 0x30, 0x0, 0x0, - 0x0, 0x0, 0x2c, 0x42, 0xb0, 0x79, 0x20, 0x0, - 0x0, 0x7, 0x91, 0x2, 0xb0, 0x4, 0xdd, 0xa3, - 0x5, 0x62, 0x56, 0x66, 0x66, 0x6c, 0x24, 0x50, - 0x0, 0x0, 0x0, 0x0, 0x5, 0x95, 0x20, 0x0, - 0x0, 0x0, 0x0, 0x1, 0xd2, 0x0, 0x3, 0x20, - 0x6, 0x76, 0x66, 0x66, 0xd6, 0x66, 0x6b, 0xa0, - 0x0, 0x0, 0x0, 0x1, 0xb0, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x0, 0x1, 0xb0, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x2, 0x9e, 0x90, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x0, 0x5, 0x0, 0x0, 0x0, 0x0, - - /* U+5B66 "学" */ - 0x0, 0x30, 0x3, 0x40, 0x0, 0x67, 0x0, 0x0, - 0x3, 0xc1, 0xd, 0x40, 0xc, 0x50, 0x0, 0x0, - 0xb, 0x80, 0x98, 0x3, 0x90, 0x0, 0x0, 0x40, - 0x43, 0x2, 0x10, 0x80, 0x0, 0x40, 0xa, 0x66, - 0x66, 0x66, 0x66, 0x66, 0xae, 0x11, 0xf0, 0x0, - 0x0, 0x0, 0x1, 0x9, 0x0, 0x37, 0x18, 0x66, - 0x66, 0x68, 0xe3, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x4, 0x92, 0x0, 0x0, 0x0, 0x0, 0x0, 0xa, - 0x40, 0x0, 0x20, 0x4, 0x66, 0x66, 0x66, 0xe6, - 0x66, 0x6d, 0xb0, 0x0, 0x0, 0x0, 0xd, 0x0, - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xd0, 0x0, - 0x0, 0x0, 0x0, 0x0, 0x10, 0x1d, 0x0, 0x0, - 0x0, 0x0, 0x0, 0x2, 0x9f, 0xa0, 0x0, 0x0, - 0x0, 0x0, 0x0, 0x0, 0x40, 0x0, 0x0, 0x0, - 0x0, - - /* U+5B69 "孩" */ - 0x0, 0x0, 0x0, 0x0, 0x5, 0x60, 0x0, 0x0, - 0x3, 0x66, 0x6c, 0x70, 0x0, 0xc5, 0x0, 0x0, - 0x0, 0x0, 0x39, 0x56, 0x66, 0x97, 0x69, 0xc0, - 0x0, 0x1, 0x60, 0x0, 0x1d, 0x10, 0x0, 0x0, - 0x0, 0xd, 0x20, 0x0, 0x86, 0x1, 0x50, 0x0, - 0x0, 0xd, 0x0, 0x22, 0x70, 0x8, 0xb0, 0x0, - 0x0, 0xd, 0x57, 0x1c, 0x97, 0x6e, 0x10, 0x0, - 0x1, 0x7f, 0x40, 0x3, 0x0, 0xb4, 0x18, 0x0, - 0x3f, 0x7d, 0x0, 0x0, 0x8, 0x60, 0x99, 0x0, - 0x2, 0xd, 0x0, 0x0, 0x86, 0x6, 0xb0, 0x0, - 0x0, 0xd, 0x0, 0x38, 0x20, 0x4e, 0x0, 0x0, - 0x0, 0xd, 0x2, 0x30, 0x6, 0xa2, 0xb2, 0x0, - 0x1, 0xd, 0x0, 0x2, 0x96, 0x0, 0x3e, 0x20, - 0x2, 0xbc, 0x4, 0x75, 0x0, 0x0, 0x9, 0x50, - 0x0, 0x10, 0x10, 0x0, 0x0, 0x0, 0x0, 0x0, - - /* U+5B6B "孫" */ - 0x0, 0x0, 0x0, 0x0, 0x0, 0x4, 0x8c, 0x0, - 0x5, 0x66, 0x6d, 0x55, 0x59, 0xb6, 0x42, 0x0, - 0x0, 0x0, 0x39, 0x10, 0xa, 0x80, 0x0, 0x0, - 0x0, 0x1, 0x70, 0x0, 0x58, 0x1, 0x80, 0x0, - 0x0, 0xe, 0x10, 0x7, 0x93, 0x4c, 0x70, 0x0, - 0x0, 0xd, 0x0, 0x8, 0x74, 0xa5, 0x0, 0x0, - 0x0, 0xd, 0x25, 0x0, 0x9, 0x40, 0x50, 0x0, - 0x0, 0x5e, 0x60, 0x4, 0x91, 0x0, 0x4a, 0x0, - 0x3e, 0x7d, 0x0, 0x2f, 0xa8, 0xe5, 0x49, 0x80, - 0x2, 0xd, 0x0, 0x1, 0x0, 0xd0, 0x1, 0x30, - 0x0, 0xd, 0x0, 0x7, 0x90, 0xd0, 0x70, 0x0, - 0x0, 0xd, 0x0, 0x2b, 0x0, 0xd0, 0x2c, 0x20, - 0x1, 0xd, 0x1, 0x81, 0x0, 0xd0, 0x6, 0xd0, - 0x3, 0xdb, 0x4, 0x1, 0x8f, 0xb0, 0x0, 0x70, - 0x0, 0x20, 0x0, 0x0, 0x5, 0x10, 0x0, 0x0, - - /* U+5B78 "學" */ - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x1, 0x39, 0x31, 0xb2, 0x0, 0x50, 0x0, - 0x0, 0xd, 0x30, 0xa, 0xb2, 0x76, 0xe2, 0x0, - 0x0, 0xc, 0x74, 0x32, 0x62, 0x66, 0xd0, 0x0, - 0x0, 0xb, 0x1, 0x21, 0xa2, 0x0, 0xc0, 0x0, - 0x0, 0xa, 0x77, 0xc, 0xa0, 0x66, 0xb0, 0x0, - 0x3, 0x9, 0x20, 0x52, 0x90, 0x1, 0xb0, 0x20, - 0x8, 0x77, 0x66, 0x66, 0x66, 0x66, 0x79, 0xd0, - 0xe, 0x10, 0x56, 0x66, 0x66, 0xa2, 0x8, 0x0, - 0x4, 0x0, 0x0, 0x0, 0x1a, 0x72, 0x0, 0x0, - 0x0, 0x0, 0x0, 0x9, 0x90, 0x0, 0x5, 0x10, - 0x6, 0x66, 0x66, 0x6c, 0x86, 0x66, 0x6b, 0x90, - 0x0, 0x0, 0x0, 0xa, 0x20, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x0, 0xa, 0x20, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x6, 0xbf, 0x10, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x0, 0x23, 0x0, 0x0, 0x0, 0x0, - - /* U+5B83 "它" */ - 0x0, 0x0, 0x0, 0x19, 0x10, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x0, 0x7c, 0x0, 0x0, 0x0, 0x2, - 0x96, 0x66, 0x67, 0xb6, 0x66, 0x6c, 0x10, 0x85, - 0x0, 0x0, 0x0, 0x0, 0x6, 0xa1, 0x2f, 0x30, - 0x20, 0x0, 0x0, 0x0, 0x70, 0x0, 0x0, 0xc, - 0x50, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xc1, - 0x0, 0x2, 0xc2, 0x0, 0x0, 0x0, 0xc, 0x10, - 0x7, 0xc7, 0x20, 0x0, 0x0, 0x0, 0xc3, 0x78, - 0x30, 0x0, 0x0, 0x0, 0x0, 0xc, 0x50, 0x0, - 0x0, 0x0, 0x0, 0x0, 0x0, 0xc1, 0x0, 0x0, - 0x0, 0x50, 0x0, 0x0, 0xc, 0x10, 0x0, 0x0, - 0x8, 0x0, 0x0, 0x0, 0xc2, 0x0, 0x0, 0x0, - 0xc3, 0x0, 0x0, 0x6, 0xdc, 0xcc, 0xcc, 0xcd, - 0x50, - - /* U+5B85 "宅" */ - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x0, 0x9, 0x10, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x0, 0x7, 0xa0, 0x0, 0x0, 0x0, - 0x0, 0x28, 0x66, 0x67, 0xa6, 0x66, 0x6a, 0x60, - 0x0, 0x85, 0x0, 0x0, 0x0, 0x30, 0xb, 0x30, - 0x0, 0xc2, 0x0, 0x2, 0x6b, 0xe8, 0x22, 0x0, - 0x0, 0x24, 0x56, 0x9d, 0x41, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x0, 0x1c, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x0, 0x1c, 0x0, 0x0, 0x7d, 0x20, - 0x0, 0x0, 0x0, 0x4d, 0x66, 0x66, 0x52, 0x0, - 0x6, 0x66, 0x65, 0x4c, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x0, 0x1c, 0x0, 0x0, 0x0, 0x40, - 0x0, 0x0, 0x0, 0x1c, 0x0, 0x0, 0x0, 0x60, - 0x0, 0x0, 0x0, 0x1d, 0x0, 0x0, 0x3, 0xa0, - 0x0, 0x0, 0x0, 0xb, 0xcc, 0xcc, 0xcd, 0xa0, - - /* U+5B87 "宇" */ - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x9, 0x30, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x4d, 0x0, 0x0, 0x0, 0x0, 0x19, - 0x66, 0x66, 0xa6, 0x66, 0x6b, 0x40, 0x7, 0x70, - 0x0, 0x0, 0x0, 0x0, 0xc3, 0x0, 0xc2, 0x0, - 0x0, 0x0, 0x3, 0x51, 0x0, 0x0, 0x26, 0x66, - 0x68, 0x66, 0xb8, 0x0, 0x0, 0x0, 0x0, 0x2, - 0xb0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x2b, - 0x0, 0x0, 0x32, 0x4, 0x76, 0x66, 0x67, 0xd6, - 0x66, 0x6b, 0xa0, 0x0, 0x0, 0x0, 0x2b, 0x0, - 0x0, 0x0, 0x0, 0x0, 0x0, 0x2, 0xb0, 0x0, - 0x0, 0x0, 0x0, 0x0, 0x0, 0x2b, 0x0, 0x0, - 0x0, 0x0, 0x0, 0x2, 0x15, 0xb0, 0x0, 0x0, - 0x0, 0x0, 0x0, 0x3a, 0xf7, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x0, 0x5, 0x0, 0x0, 0x0, 0x0, - - /* U+5B88 "守" */ - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x2, 0x90, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x9, 0xa0, 0x0, 0x0, 0x0, 0x5, - 0x0, 0x0, 0x35, 0x0, 0x1, 0x70, 0x0, 0xb6, - 0x66, 0x66, 0x66, 0x66, 0xad, 0x20, 0x3f, 0x0, - 0x0, 0x0, 0xb3, 0x8, 0x0, 0x1, 0x10, 0x0, - 0x0, 0xd, 0x10, 0x1, 0x0, 0x56, 0x66, 0x66, - 0x66, 0xe6, 0x68, 0xe3, 0x1, 0x11, 0x0, 0x0, - 0xd, 0x10, 0x0, 0x0, 0x0, 0xa, 0x10, 0x0, - 0xd1, 0x0, 0x0, 0x0, 0x0, 0x5d, 0x0, 0xd, - 0x10, 0x0, 0x0, 0x0, 0x0, 0xe0, 0x0, 0xd1, - 0x0, 0x0, 0x0, 0x0, 0x1, 0x0, 0xd, 0x10, - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xe1, 0x0, - 0x0, 0x0, 0x0, 0x0, 0x17, 0xee, 0x0, 0x0, - 0x0, 0x0, 0x0, 0x0, 0x3, 0x10, 0x0, 0x0, - - /* U+5B89 "安" */ - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x0, 0x8, 0x30, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x0, 0x2, 0xe0, 0x0, 0x0, 0x0, - 0x0, 0xa, 0x66, 0x66, 0xa6, 0x66, 0x6c, 0x30, - 0x0, 0x77, 0x0, 0x0, 0x0, 0x0, 0x3a, 0x10, - 0x0, 0xa2, 0x0, 0x77, 0x0, 0x0, 0x40, 0x0, - 0x0, 0x0, 0x0, 0xc3, 0x0, 0x0, 0x1, 0x0, - 0x5, 0x66, 0x66, 0xe6, 0x66, 0x66, 0x6e, 0x90, - 0x0, 0x0, 0x8, 0x60, 0x0, 0x97, 0x0, 0x0, - 0x0, 0x0, 0xc, 0x0, 0x2, 0xe0, 0x0, 0x0, - 0x0, 0x0, 0x86, 0x0, 0xa, 0x60, 0x0, 0x0, - 0x0, 0x0, 0x26, 0x78, 0x8c, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x0, 0x4, 0xda, 0xb5, 0x0, 0x0, - 0x0, 0x0, 0x1, 0x8a, 0x10, 0x29, 0xe6, 0x0, - 0x0, 0x15, 0x88, 0x20, 0x0, 0x0, 0x4e, 0x10, - 0x3, 0x42, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - - /* U+5B8C "完" */ - 0x0, 0x0, 0x0, 0x9, 0x10, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x0, 0x6, 0xa0, 0x0, 0x0, 0x0, - 0x0, 0x67, 0x66, 0x67, 0x96, 0x66, 0x69, 0x70, - 0x0, 0xb3, 0x0, 0x0, 0x0, 0x0, 0x9, 0x40, - 0x1, 0x90, 0x0, 0x0, 0x0, 0x24, 0x3, 0x0, - 0x0, 0x3, 0x76, 0x66, 0x66, 0x66, 0x0, 0x0, - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x1, 0x0, - 0x0, 0x56, 0x66, 0x66, 0x66, 0x66, 0x9e, 0x20, - 0x0, 0x10, 0x4, 0xa0, 0xd, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x6, 0x70, 0xd, 0x0, 0x0, 0x0, - 0x0, 0x0, 0xa, 0x40, 0xd, 0x0, 0x0, 0x30, - 0x0, 0x0, 0x1d, 0x0, 0xd, 0x0, 0x0, 0x60, - 0x0, 0x0, 0xa4, 0x0, 0xe, 0x0, 0x0, 0xc0, - 0x0, 0x49, 0x30, 0x0, 0x9, 0xdc, 0xcd, 0xb1, - 0x5, 0x20, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - - /* U+5B98 "官" */ - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x1a, 0x20, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x6b, 0x0, 0x0, 0x0, 0x0, 0x86, - 0x66, 0x66, 0x96, 0x66, 0x69, 0xa0, 0x2d, 0x0, - 0x0, 0x0, 0x0, 0x0, 0xa5, 0x7, 0x70, 0x96, - 0x66, 0x66, 0x6b, 0x23, 0x0, 0x0, 0xe, 0x0, - 0x0, 0x0, 0xd0, 0x0, 0x0, 0x0, 0xe0, 0x0, - 0x0, 0xd, 0x0, 0x0, 0x0, 0xe, 0x66, 0x66, - 0x66, 0xe0, 0x0, 0x0, 0x0, 0xe0, 0x0, 0x0, - 0x2, 0x0, 0x0, 0x0, 0xe, 0x66, 0x66, 0x66, - 0x96, 0x0, 0x0, 0x0, 0xe0, 0x0, 0x0, 0x8, - 0x60, 0x0, 0x0, 0xe, 0x0, 0x0, 0x0, 0x85, - 0x0, 0x0, 0x0, 0xe0, 0x0, 0x0, 0x8, 0x50, - 0x0, 0x0, 0xe, 0x66, 0x66, 0x66, 0xb5, 0x0, - 0x0, 0x0, 0x40, 0x0, 0x0, 0x1, 0x0, 0x0, - - /* U+5B99 "宙" */ - 0x0, 0x0, 0x0, 0x38, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x0, 0xb6, 0x0, 0x0, 0x0, 0x0, - 0x84, 0x44, 0x47, 0x64, 0x44, 0x49, 0x0, 0x3a, - 0x22, 0x22, 0x62, 0x22, 0x25, 0xb2, 0xa, 0x60, - 0x0, 0xd, 0x30, 0x0, 0x50, 0x0, 0x0, 0x0, - 0x0, 0xd0, 0x0, 0x0, 0x0, 0x0, 0xc, 0x66, - 0x6e, 0x66, 0x6b, 0x70, 0x0, 0x0, 0xe0, 0x0, - 0xd0, 0x0, 0xa4, 0x0, 0x0, 0xe, 0x0, 0xd, - 0x0, 0xa, 0x40, 0x0, 0x0, 0xe6, 0x66, 0xe6, - 0x66, 0xc4, 0x0, 0x0, 0xe, 0x0, 0xd, 0x0, - 0xa, 0x40, 0x0, 0x0, 0xe0, 0x0, 0xd0, 0x0, - 0xa4, 0x0, 0x0, 0xe, 0x0, 0xd, 0x0, 0xa, - 0x40, 0x0, 0x0, 0xe6, 0x66, 0x66, 0x66, 0xc4, - 0x0, 0x0, 0x7, 0x0, 0x0, 0x0, 0x4, 0x10, - 0x0, - - /* U+5B9A "定" */ - 0x0, 0x0, 0x0, 0x81, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x6, 0xa0, 0x0, 0x0, 0x0, 0x1, - 0x96, 0x66, 0x79, 0x66, 0x66, 0xb5, 0x0, 0x95, - 0x0, 0x0, 0x0, 0x0, 0xc, 0x40, 0x1c, 0x10, - 0x0, 0x0, 0x0, 0x4, 0x10, 0x0, 0x36, 0x66, - 0x66, 0x66, 0x66, 0xd9, 0x0, 0x0, 0x10, 0x0, - 0x3a, 0x0, 0x0, 0x0, 0x0, 0x0, 0x61, 0x3, - 0xa0, 0x0, 0x0, 0x0, 0x0, 0xf, 0x40, 0x3a, - 0x0, 0x15, 0x0, 0x0, 0x1, 0xe0, 0x3, 0xc6, - 0x67, 0x81, 0x0, 0x0, 0x6b, 0x30, 0x3a, 0x0, - 0x0, 0x0, 0x0, 0xb, 0x16, 0x43, 0xa0, 0x0, - 0x0, 0x0, 0x5, 0x70, 0x7, 0xcc, 0x42, 0x11, - 0x23, 0x3, 0x60, 0x0, 0x1, 0x7b, 0xde, 0xff, - 0x40, 0x10, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, - - /* U+5B9E "实" */ - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, 0xa, 0x50, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x3f, 0x0, 0x0, 0x0, 0x0, 0x66, - 0x66, 0x66, 0xb6, 0x66, 0x69, 0x50, 0xd, 0x0, - 0x0, 0x2, 0x0, 0x0, 0xc7, 0x7, 0xc0, 0x1a, - 0x40, 0x7c, 0x0, 0x42, 0x0, 0x0, 0x0, 0x3f, - 0x8, 0x80, 0x0, 0x0, 0x0, 0x6, 0x20, 0x50, - 0x96, 0x0, 0x0, 0x0, 0x0, 0x1e, 0x40, 0xa, - 0x40, 0x0, 0x0, 0x0, 0x0, 0x66, 0x0, 0xc2, - 0x0, 0x4, 0x20, 0x67, 0x66, 0x66, 0x6e, 0x66, - 0x66, 0xa9, 0x0, 0x0, 0x0, 0x5, 0xc0, 0x0, - 0x0, 0x0, 0x0, 0x0, 0x2, 0xd3, 0x8a, 0x50, - 0x0, 0x0, 0x0, 0x4, 0xc3, 0x0, 0x2c, 0xe3, - 0x0, 0x1, 0x5a, 0x70, 0x0, 0x0, 0x9, 0xb0, - 0x4, 0x51, 0x0, 0x0, 0x0, 0x0, 0x3, 0x0, - - /* U+5B9F "実" */ - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x1, 0xb3, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x6, 0xb0, 0x0, 0x0, 0x0, 0xa, - 0x66, 0x66, 0x79, 0x66, 0x66, 0xc2, 0x4, 0xa0, - 0x0, 0x4, 0x0, 0x0, 0x49, 0x20, 0xb5, 0x0, - 0x0, 0xb4, 0x0, 0x4, 0x0, 0x0, 0x36, 0x66, - 0x6d, 0x76, 0x6b, 0xa0, 0x0, 0x0, 0x10, 0x0, - 0xb2, 0x0, 0x0, 0x0, 0x0, 0x5, 0x66, 0x6d, - 0x76, 0x6e, 0x50, 0x0, 0x0, 0x0, 0x0, 0xb2, - 0x0, 0x1, 0x30, 0x4, 0x76, 0x66, 0x6e, 0x86, - 0x66, 0x9b, 0x10, 0x0, 0x0, 0x2, 0xd5, 0x10, - 0x0, 0x0, 0x0, 0x0, 0x0, 0xb5, 0x9, 0x10, - 0x0, 0x0, 0x0, 0x0, 0x98, 0x0, 0x2c, 0x61, - 0x0, 0x0, 0x6, 0xa4, 0x0, 0x0, 0x1b, 0xfb, - 0x30, 0x35, 0x20, 0x0, 0x0, 0x0, 0x3, 0x20, - - /* U+5BA2 "客" */ - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x0, 0x3b, 0x20, 0x0, 0x0, 0x0, - 0x0, 0x30, 0x0, 0x7, 0x70, 0x0, 0x2, 0x0, - 0x1, 0xb6, 0x67, 0x66, 0x66, 0x66, 0x6e, 0x70, - 0xa, 0x70, 0x9, 0xa0, 0x0, 0x0, 0x57, 0x0, - 0x5, 0x0, 0x3f, 0x76, 0x66, 0xd7, 0x20, 0x0, - 0x0, 0x1, 0xb2, 0x60, 0x8, 0xb0, 0x0, 0x0, - 0x0, 0x9, 0x10, 0x38, 0x7a, 0x0, 0x0, 0x0, - 0x0, 0x60, 0x0, 0xb, 0xe4, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x4, 0xb4, 0x8, 0xc7, 0x30, 0x0, - 0x0, 0x4, 0xa6, 0x0, 0x0, 0x1c, 0xef, 0xa1, - 0x15, 0x63, 0xd6, 0x66, 0x66, 0x6e, 0x13, 0x10, - 0x0, 0x0, 0xd0, 0x0, 0x0, 0xd, 0x0, 0x0, - 0x0, 0x0, 0xd0, 0x0, 0x0, 0xd, 0x0, 0x0, - 0x0, 0x0, 0xd6, 0x66, 0x66, 0x6d, 0x0, 0x0, - 0x0, 0x0, 0x40, 0x0, 0x0, 0x3, 0x0, 0x0, - - /* U+5BA4 "室" */ - 0x0, 0x0, 0x0, 0x1a, 0x20, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x0, 0x6, 0xa0, 0x0, 0x0, 0x0, - 0x0, 0x96, 0x66, 0x66, 0x76, 0x66, 0x6b, 0x10, - 0x4, 0xb0, 0x0, 0x0, 0x0, 0x0, 0x65, 0x0, - 0x6, 0x56, 0x66, 0x66, 0x66, 0x6e, 0x50, 0x0, - 0x0, 0x1, 0x0, 0xb5, 0x0, 0x20, 0x0, 0x0, - 0x0, 0x0, 0x19, 0x20, 0x0, 0x88, 0x0, 0x0, - 0x0, 0x8, 0xd6, 0x66, 0x66, 0x6e, 0x80, 0x0, - 0x0, 0x6, 0x95, 0x37, 0x20, 0x4, 0x80, 0x0, - 0x0, 0x0, 0x0, 0xb, 0x60, 0x1, 0x0, 0x0, - 0x0, 0x7, 0x66, 0x6c, 0x86, 0x6c, 0x70, 0x0, - 0x0, 0x0, 0x0, 0xa, 0x30, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x0, 0xa, 0x30, 0x0, 0x2, 0x0, - 0x5, 0x66, 0x66, 0x6c, 0x86, 0x66, 0x6e, 0x90, - 0x2, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - - /* U+5BB3 "害" */ - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, 0xa2, 0x0, 0x0, 0x0, 0x3, 0x0, - 0x0, 0x57, 0x0, 0x0, 0x40, 0xa, 0x66, 0x66, - 0x67, 0x66, 0x66, 0xe4, 0x5b, 0x0, 0x0, 0x1e, - 0x0, 0x25, 0x10, 0x0, 0x56, 0x66, 0x6d, 0x66, - 0x77, 0x0, 0x0, 0x0, 0x0, 0x1c, 0x0, 0x31, - 0x0, 0x0, 0x56, 0x66, 0x6d, 0x66, 0x75, 0x0, - 0x0, 0x0, 0x0, 0x1c, 0x0, 0x0, 0x82, 0x57, - 0x66, 0x66, 0x7d, 0x66, 0x66, 0x64, 0x0, 0x3, - 0x0, 0x29, 0x0, 0x40, 0x0, 0x0, 0xe, 0x66, - 0x66, 0x66, 0xc5, 0x0, 0x0, 0xd, 0x0, 0x0, - 0x0, 0xa2, 0x0, 0x0, 0xd, 0x0, 0x0, 0x0, - 0xa2, 0x0, 0x0, 0xe, 0x66, 0x66, 0x66, 0xc2, - 0x0, 0x0, 0x8, 0x0, 0x0, 0x0, 0x51, 0x0, - - /* U+5BB5 "宵" */ - 0x0, 0x0, 0x4, 0x91, 0x0, 0x0, 0x0, 0x1, - 0x0, 0x0, 0x87, 0x0, 0x0, 0x10, 0x6, 0x76, - 0x66, 0x66, 0x66, 0x66, 0xc7, 0xd, 0x34, 0x0, - 0x18, 0x0, 0x51, 0x80, 0x15, 0x7, 0xc0, 0x1d, - 0x8, 0x92, 0x0, 0x0, 0x0, 0xb2, 0x1d, 0x46, - 0x0, 0x0, 0x0, 0x28, 0x66, 0x6d, 0x76, 0xa4, - 0x0, 0x0, 0x2a, 0x0, 0x0, 0x0, 0xb2, 0x0, - 0x0, 0x2c, 0x66, 0x66, 0x66, 0xc2, 0x0, 0x0, - 0x2a, 0x0, 0x0, 0x0, 0xb2, 0x0, 0x0, 0x2c, - 0x66, 0x66, 0x66, 0xc2, 0x0, 0x0, 0x2a, 0x0, - 0x0, 0x0, 0xb2, 0x0, 0x0, 0x2a, 0x0, 0x0, - 0x0, 0xb2, 0x0, 0x0, 0x2a, 0x0, 0x0, 0x6c, - 0xe0, 0x0, 0x0, 0x12, 0x0, 0x0, 0x2, 0x20, - 0x0, - - /* U+5BB6 "家" */ - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x0, 0x1b, 0x40, 0x0, 0x0, 0x0, - 0x0, 0x30, 0x0, 0x4, 0x90, 0x0, 0x2, 0x10, - 0x0, 0xa6, 0x66, 0x66, 0x66, 0x66, 0x6d, 0x90, - 0x4, 0xc0, 0x0, 0x0, 0x0, 0x2, 0x16, 0x0, - 0x0, 0x4, 0x66, 0x7a, 0x66, 0x6a, 0x20, 0x0, - 0x0, 0x0, 0x2, 0xd4, 0x0, 0x2, 0x20, 0x0, - 0x0, 0x0, 0x5a, 0x29, 0x10, 0x3c, 0x70, 0x0, - 0x0, 0x47, 0x40, 0x4b, 0xb6, 0x90, 0x0, 0x0, - 0x3, 0x10, 0x6, 0x90, 0xb4, 0x70, 0x0, 0x0, - 0x0, 0x2, 0x95, 0x7, 0xe8, 0x36, 0x0, 0x0, - 0x2, 0x65, 0x0, 0x8a, 0x3b, 0xb, 0x30, 0x0, - 0x0, 0x0, 0x2a, 0x50, 0x3b, 0x1, 0xd9, 0x30, - 0x0, 0x17, 0x70, 0x0, 0x59, 0x0, 0x1a, 0x50, - 0x5, 0x40, 0x0, 0x6c, 0xe3, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x0, 0x3, 0x20, 0x0, 0x0, 0x0, - - /* U+5BB9 "容" */ - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, 0xa, 0x70, 0x0, 0x0, 0x0, 0x2, - 0x0, 0x0, 0x1d, 0x0, 0x0, 0x1, 0x0, 0x86, - 0x66, 0x66, 0x66, 0x66, 0x6a, 0xb0, 0x1e, 0x10, - 0x82, 0x0, 0x40, 0x0, 0x81, 0x1, 0x40, 0x6c, - 0x21, 0x71, 0x9a, 0x20, 0x0, 0x0, 0x59, 0x0, - 0xad, 0x0, 0x6f, 0x20, 0x0, 0x54, 0x0, 0x6b, - 0x17, 0x0, 0x63, 0x0, 0x0, 0x0, 0x6c, 0x0, - 0x3a, 0x10, 0x0, 0x0, 0x0, 0x6a, 0x0, 0x0, - 0x2c, 0x94, 0x0, 0x1, 0x88, 0xb6, 0x66, 0x66, - 0xe9, 0xed, 0x24, 0x50, 0x2b, 0x0, 0x0, 0xe, - 0x0, 0x10, 0x0, 0x2, 0xb0, 0x0, 0x0, 0xe0, - 0x0, 0x0, 0x0, 0x2b, 0x0, 0x0, 0xe, 0x0, - 0x0, 0x0, 0x3, 0xd6, 0x66, 0x66, 0xe0, 0x0, - 0x0, 0x0, 0x13, 0x0, 0x0, 0x4, 0x0, 0x0, - - /* U+5BBF "宿" */ - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x0, 0x95, 0x0, 0x0, 0x0, 0x0, - 0x10, 0x0, 0x2, 0xc0, 0x0, 0x1, 0x0, 0xb, - 0x66, 0x66, 0x66, 0x66, 0x67, 0xf2, 0x6, 0xa0, - 0xb5, 0x0, 0x0, 0x0, 0x63, 0x0, 0x62, 0x2d, - 0x26, 0x66, 0x66, 0x66, 0xd4, 0x0, 0x9, 0x40, - 0x10, 0xb, 0x40, 0x0, 0x0, 0x2, 0xe3, 0x0, - 0x0, 0x90, 0x1, 0x0, 0x0, 0x9d, 0x10, 0xd, - 0x68, 0x66, 0xe2, 0x0, 0x53, 0xc1, 0x0, 0xe0, - 0x0, 0xe, 0x0, 0x23, 0xc, 0x10, 0xe, 0x0, - 0x0, 0xe0, 0x0, 0x0, 0xc1, 0x0, 0xe6, 0x66, - 0x6e, 0x0, 0x0, 0xc, 0x10, 0xe, 0x0, 0x0, - 0xe0, 0x0, 0x0, 0xc1, 0x0, 0xe0, 0x0, 0xe, - 0x0, 0x0, 0xd, 0x10, 0xe, 0x66, 0x66, 0xf0, - 0x0, 0x0, 0x60, 0x0, 0x50, 0x0, 0x5, 0x0, - - /* U+5BC4 "寄" */ - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x0, 0xb1, 0x0, 0x0, 0x0, 0x0, - 0x30, 0x0, 0x6, 0x10, 0x0, 0x5, 0x0, 0xb, - 0x66, 0x66, 0x96, 0x66, 0x68, 0xd1, 0x8, 0x80, - 0x0, 0x3d, 0x0, 0x3, 0x40, 0x0, 0x0, 0x66, - 0x6d, 0x86, 0x66, 0x95, 0x0, 0x0, 0x0, 0x8, - 0x61, 0x78, 0x10, 0x0, 0x0, 0x0, 0x57, 0x30, - 0x0, 0x5b, 0x0, 0x40, 0x7, 0x76, 0x66, 0x66, - 0x66, 0x69, 0x6b, 0x70, 0x0, 0x30, 0x0, 0x30, - 0x0, 0xe0, 0x0, 0x0, 0xd, 0x66, 0x6d, 0x70, - 0xe, 0x0, 0x0, 0x0, 0xc1, 0x0, 0xb2, 0x0, - 0xe0, 0x0, 0x0, 0xc, 0x66, 0x6d, 0x40, 0xe, - 0x0, 0x0, 0x0, 0xc0, 0x0, 0x63, 0x0, 0xe0, - 0x0, 0x0, 0x0, 0x0, 0x0, 0x18, 0xfb, 0x0, - 0x0, 0x0, 0x0, 0x0, 0x0, 0x3, 0x10, 0x0, - - /* U+5BC6 "密" */ - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x0, 0xa0, 0x0, 0x0, 0x0, 0x0, - 0x30, 0x0, 0xa, 0x40, 0x0, 0x3, 0x10, 0xb, - 0x66, 0x66, 0x66, 0x66, 0x66, 0xd8, 0x8, 0x90, - 0x0, 0x48, 0x0, 0x93, 0x25, 0x0, 0x10, 0x0, - 0xb2, 0xd0, 0x8c, 0x30, 0x0, 0x0, 0x8, 0xd, - 0x1, 0x99, 0x0, 0x94, 0x0, 0x9, 0x90, 0xd2, - 0xb5, 0x4, 0x1, 0xf2, 0x0, 0x60, 0x2e, 0x91, - 0x0, 0x84, 0x6, 0x0, 0x25, 0x77, 0x8b, 0xbb, - 0xba, 0x40, 0x0, 0x1, 0x0, 0x0, 0xa, 0x30, - 0x0, 0x0, 0x0, 0x0, 0xc2, 0x0, 0xc0, 0x0, - 0x2c, 0x0, 0x0, 0xd, 0x0, 0xc, 0x0, 0x2, - 0xb0, 0x0, 0x0, 0xd0, 0x0, 0xc0, 0x0, 0x2b, - 0x0, 0x0, 0x1b, 0x66, 0x67, 0x66, 0x67, 0xb0, - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x1, 0x0, - - /* U+5BCC "富" */ - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x2, 0xb1, 0x0, 0x0, 0x0, 0x3, 0x0, - 0x0, 0x84, 0x0, 0x0, 0x30, 0xb, 0x66, 0x66, - 0x66, 0x66, 0x68, 0xe1, 0x79, 0x0, 0x0, 0x0, - 0x5, 0x46, 0x10, 0x0, 0x27, 0x66, 0x66, 0x66, - 0x50, 0x0, 0x0, 0x7, 0x66, 0x66, 0x6b, 0x40, - 0x0, 0x0, 0x9, 0x30, 0x0, 0xb, 0x10, 0x0, - 0x0, 0x9, 0x76, 0x66, 0x6d, 0x20, 0x0, 0x0, - 0x23, 0x0, 0x0, 0x0, 0x20, 0x0, 0x0, 0xd6, - 0x66, 0xc6, 0x66, 0xb7, 0x0, 0x0, 0xd1, 0x0, - 0xd0, 0x0, 0x94, 0x0, 0x0, 0xc6, 0x66, 0xe6, - 0x66, 0xb4, 0x0, 0x0, 0xd1, 0x0, 0xd0, 0x0, - 0x95, 0x0, 0x0, 0xd6, 0x66, 0x96, 0x66, 0xb5, - 0x0, 0x0, 0x50, 0x0, 0x0, 0x0, 0x20, 0x0, - - /* U+5BD2 "寒" */ - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x0, 0xb1, 0x0, 0x0, 0x0, 0x0, - 0x30, 0x0, 0x8, 0x30, 0x0, 0x6, 0x10, 0x68, - 0x66, 0x86, 0x66, 0x86, 0x66, 0xd5, 0x1d, 0x10, - 0xd, 0x10, 0xe, 0x13, 0x22, 0x0, 0x5, 0x66, - 0xe6, 0x66, 0xe6, 0x95, 0x0, 0x0, 0x0, 0xd, - 0x0, 0xd, 0x4, 0x10, 0x0, 0x3, 0x66, 0xe6, - 0x66, 0xe6, 0x75, 0x0, 0x0, 0x0, 0xd, 0x0, - 0xd, 0x0, 0x1a, 0x11, 0x66, 0x66, 0xf6, 0x66, - 0xa6, 0x66, 0x74, 0x0, 0x0, 0x88, 0x16, 0x3, - 0x60, 0x0, 0x0, 0x0, 0x5a, 0x0, 0x3e, 0x17, - 0xa2, 0x0, 0x0, 0x67, 0x2, 0x0, 0x40, 0x5, - 0xed, 0x41, 0x52, 0x0, 0x26, 0xa9, 0x40, 0x0, - 0x40, 0x0, 0x0, 0x0, 0x0, 0x5e, 0x70, 0x0, - 0x0, 0x0, 0x0, 0x0, 0x0, 0x13, 0x0, 0x0, - - /* U+5BDD "寝" */ - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x0, 0x1b, 0x50, 0x0, 0x0, 0x0, - 0x0, 0x20, 0x0, 0x1, 0x90, 0x0, 0x2, 0x0, - 0x0, 0xa6, 0x66, 0x66, 0x66, 0x66, 0x6d, 0x50, - 0x2, 0xd0, 0x50, 0x0, 0x0, 0x0, 0x53, 0x0, - 0x0, 0x10, 0xe1, 0x17, 0x66, 0x66, 0xe1, 0x0, - 0x2, 0x70, 0xd0, 0x4, 0x65, 0x55, 0xd0, 0x0, - 0x0, 0xc2, 0xd0, 0x16, 0x66, 0x66, 0xe0, 0x0, - 0x0, 0x50, 0xd0, 0x22, 0x0, 0x0, 0x22, 0x0, - 0x0, 0x6, 0xd0, 0xb6, 0x66, 0x66, 0x6e, 0x30, - 0x5, 0xb2, 0xd7, 0x75, 0x66, 0x68, 0x82, 0x0, - 0x9, 0x10, 0xd0, 0x0, 0x50, 0xc, 0x30, 0x0, - 0x0, 0x0, 0xd0, 0x0, 0x45, 0x95, 0x0, 0x0, - 0x0, 0x0, 0xd0, 0x0, 0xc, 0xc1, 0x0, 0x0, - 0x0, 0x0, 0xe0, 0x5, 0x82, 0x3b, 0xca, 0x70, - 0x0, 0x0, 0x62, 0x41, 0x0, 0x0, 0x14, 0x10, - - /* U+5BDF "察" */ - 0x0, 0x0, 0x0, 0x20, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x2, 0xc0, 0x0, 0x0, 0x0, 0x5, - 0x66, 0x66, 0x6b, 0x66, 0x66, 0x6c, 0x0, 0xc0, - 0x46, 0x0, 0x0, 0x0, 0x8, 0x50, 0x36, 0xb, - 0x70, 0x31, 0x30, 0x0, 0x70, 0x0, 0x5, 0xc6, - 0x6e, 0x58, 0x66, 0x8e, 0x30, 0x1, 0xb8, 0x46, - 0x90, 0x34, 0xa, 0x10, 0x0, 0x95, 0x19, 0xc1, - 0x0, 0x87, 0x10, 0x0, 0x40, 0xa2, 0xb9, 0x66, - 0x98, 0xb6, 0x0, 0x0, 0x4, 0xa2, 0x0, 0x0, - 0x1, 0xae, 0xa2, 0x4, 0xa6, 0x66, 0x67, 0x66, - 0xaa, 0x44, 0x4, 0x10, 0x4, 0x2, 0xb0, 0x0, - 0x0, 0x0, 0x0, 0x7, 0xc2, 0x2b, 0x6, 0x70, - 0x0, 0x0, 0x8, 0x70, 0x2, 0xb0, 0x4, 0xe3, - 0x0, 0x27, 0x20, 0x28, 0xd9, 0x0, 0x5, 0x90, - 0x0, 0x0, 0x0, 0x5, 0x10, 0x0, 0x0, 0x0, - - /* U+5BE6 "實" */ - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x9, 0x40, 0x0, 0x0, 0x0, 0x0, - 0x20, 0x0, 0x2a, 0x0, 0x0, 0x0, 0x0, 0x2a, - 0x66, 0x66, 0x66, 0x66, 0x6a, 0xa0, 0x9, 0x56, - 0x66, 0x66, 0x66, 0x69, 0x70, 0x0, 0x0, 0xa1, - 0x0, 0xb0, 0x4, 0x93, 0x90, 0x47, 0x6d, 0x66, - 0x8b, 0x66, 0xa9, 0x66, 0x10, 0x1, 0xc6, 0x67, - 0x86, 0x6a, 0x40, 0x0, 0x0, 0xa, 0x55, 0x55, - 0x55, 0x6a, 0x0, 0x0, 0x0, 0xe6, 0x66, 0x66, - 0x67, 0xa0, 0x0, 0x0, 0xd, 0x0, 0x0, 0x0, - 0x3a, 0x0, 0x0, 0x0, 0xe6, 0x66, 0x66, 0x68, - 0xa0, 0x0, 0x0, 0xe, 0x66, 0x66, 0x66, 0x7a, - 0x0, 0x0, 0x0, 0x23, 0xc1, 0x5, 0x75, 0x10, - 0x0, 0x0, 0x38, 0x82, 0x0, 0x1, 0x9e, 0x20, - 0x0, 0x42, 0x0, 0x0, 0x0, 0x0, 0x43, 0x0, - - /* U+5BEB "寫" */ - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x0, 0x92, 0x0, 0x0, 0x0, 0x0, - 0x10, 0x0, 0x5, 0xa0, 0x0, 0x0, 0x0, 0xa, - 0x66, 0x66, 0x67, 0x66, 0x66, 0xd4, 0x8, 0x70, - 0x3, 0xb1, 0x0, 0x5, 0x28, 0x0, 0x61, 0xb5, - 0x41, 0x6, 0x76, 0xe3, 0x0, 0x0, 0xb, 0x10, - 0x50, 0x0, 0xd, 0x0, 0x0, 0x0, 0xb6, 0x65, - 0x3, 0x76, 0xe0, 0x0, 0x0, 0xc, 0x68, 0x76, - 0x66, 0x6e, 0x0, 0x0, 0x0, 0x43, 0xc0, 0x0, - 0x0, 0x41, 0x10, 0x0, 0x2, 0xb7, 0x66, 0x66, - 0x66, 0xb9, 0x0, 0x6, 0x71, 0x20, 0x14, 0x9, - 0x19, 0x30, 0x2, 0x14, 0x33, 0x80, 0xc1, 0x58, - 0xb1, 0x0, 0x1, 0xe1, 0xc, 0x5, 0x0, 0x1d, - 0x0, 0x0, 0x4, 0x0, 0x0, 0x5, 0xab, 0x90, - 0x0, 0x0, 0x0, 0x0, 0x0, 0x4, 0x60, 0x0, - - /* U+5BFA "寺" */ - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x0, 0xd, 0x30, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x0, 0xe, 0x10, 0x0, 0x30, 0x0, - 0x0, 0x76, 0x66, 0x6e, 0x66, 0x67, 0xb3, 0x0, - 0x0, 0x0, 0x0, 0xd, 0x10, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x0, 0xd, 0x10, 0x0, 0x5, 0x10, - 0x28, 0x66, 0x66, 0x6a, 0x66, 0x66, 0x6a, 0x80, - 0x0, 0x0, 0x0, 0x0, 0x1, 0xe2, 0x0, 0x0, - 0x0, 0x0, 0x0, 0x0, 0x0, 0xe0, 0x4, 0x0, - 0x6, 0x76, 0x66, 0x66, 0x66, 0xf6, 0x7a, 0x30, - 0x0, 0x0, 0x72, 0x0, 0x0, 0xe0, 0x0, 0x0, - 0x0, 0x0, 0x2e, 0x10, 0x0, 0xe0, 0x0, 0x0, - 0x0, 0x0, 0xd, 0x20, 0x0, 0xe0, 0x0, 0x0, - 0x0, 0x0, 0x1, 0x0, 0x1, 0xe0, 0x0, 0x0, - 0x0, 0x0, 0x0, 0x2, 0x9f, 0xb0, 0x0, 0x0, - 0x0, 0x0, 0x0, 0x0, 0x5, 0x0, 0x0, 0x0, - - /* U+5BFE "対" */ - 0x0, 0x21, 0x0, 0x0, 0x0, 0x0, 0x80, 0x0, - 0x0, 0xd, 0x30, 0x0, 0x0, 0x0, 0xe0, 0x0, - 0x0, 0x7, 0xb0, 0x0, 0x0, 0x0, 0xe0, 0x0, - 0x0, 0x1, 0x20, 0x71, 0x0, 0x0, 0xe0, 0x0, - 0x4, 0x76, 0x6e, 0x73, 0x56, 0x66, 0xe6, 0xd2, - 0x0, 0x0, 0xe, 0x0, 0x10, 0x0, 0xe0, 0x0, - 0x0, 0x40, 0x2b, 0x1, 0x40, 0x0, 0xe0, 0x0, - 0x0, 0x28, 0x77, 0x0, 0xa5, 0x0, 0xe0, 0x0, - 0x0, 0x2, 0xf4, 0x0, 0x4e, 0x0, 0xe0, 0x0, - 0x0, 0x3, 0xce, 0x20, 0x9, 0x0, 0xe0, 0x0, - 0x0, 0xb, 0x17, 0xd0, 0x0, 0x0, 0xe0, 0x0, - 0x0, 0x84, 0x0, 0xd0, 0x0, 0x0, 0xe0, 0x0, - 0x7, 0x40, 0x0, 0x0, 0x4, 0x33, 0xd0, 0x0, - 0x12, 0x0, 0x0, 0x0, 0x1, 0x8f, 0x90, 0x0, - 0x0, 0x0, 0x0, 0x0, 0x0, 0x4, 0x0, 0x0, - - /* U+5C04 "射" */ - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, 0xb3, 0x0, 0x0, 0x2, 0xc0, 0x0, - 0x0, 0x20, 0x80, 0x30, 0x0, 0x2, 0xb0, 0x0, - 0x0, 0xd6, 0x66, 0xe2, 0x0, 0x2, 0xb0, 0x0, - 0x0, 0xd1, 0x0, 0xe0, 0x0, 0x2, 0xb0, 0x20, - 0x0, 0xc6, 0x66, 0xe3, 0x76, 0x67, 0xd8, 0xb1, - 0x0, 0xc1, 0x0, 0xe0, 0x0, 0x2, 0xb0, 0x0, - 0x0, 0xc6, 0x66, 0xe0, 0x40, 0x2, 0xb0, 0x0, - 0x0, 0xc1, 0x0, 0xe0, 0x3b, 0x2, 0xb0, 0x0, - 0x26, 0xd6, 0x66, 0xe0, 0xd, 0x42, 0xb0, 0x0, - 0x2, 0x0, 0xb4, 0xe0, 0x6, 0x2, 0xb0, 0x0, - 0x0, 0x5, 0x90, 0xe0, 0x0, 0x2, 0xb0, 0x0, - 0x0, 0x2b, 0x0, 0xe0, 0x0, 0x2, 0xb0, 0x0, - 0x1, 0x91, 0x10, 0xe0, 0x2, 0x3, 0xb0, 0x0, - 0x26, 0x0, 0x4d, 0xc0, 0x3, 0xaf, 0x80, 0x0, - 0x0, 0x0, 0x2, 0x0, 0x0, 0x4, 0x0, 0x0, - - /* U+5C07 "將" */ - 0x0, 0x0, 0xa, 0x10, 0x3, 0x80, 0x0, 0x0, - 0x2, 0x80, 0xd, 0x0, 0xb, 0x60, 0x3, 0x10, - 0x2, 0xa0, 0xd, 0x0, 0x6b, 0x66, 0x6e, 0xa0, - 0x2, 0xa0, 0xd, 0x3, 0x88, 0x70, 0x6b, 0x0, - 0x4, 0xc6, 0x6d, 0x36, 0x91, 0xb4, 0xb0, 0x0, - 0x0, 0x30, 0xd, 0x0, 0x74, 0x5a, 0x10, 0x0, - 0x0, 0x0, 0xd, 0x0, 0x19, 0x70, 0xc2, 0x0, - 0x4, 0x66, 0x6d, 0x36, 0x61, 0x0, 0xd0, 0x30, - 0x1, 0x69, 0xd, 0x67, 0x66, 0x66, 0xe6, 0xa2, - 0x0, 0x59, 0xd, 0x3, 0x30, 0x0, 0xd0, 0x0, - 0x0, 0x77, 0xd, 0x0, 0xd2, 0x0, 0xd0, 0x0, - 0x0, 0xa3, 0xd, 0x0, 0x95, 0x0, 0xd0, 0x0, - 0x1, 0xa0, 0xd, 0x0, 0x12, 0x10, 0xd0, 0x0, - 0x8, 0x0, 0xd, 0x0, 0x2, 0x9f, 0xb0, 0x0, - 0x0, 0x0, 0x2, 0x0, 0x0, 0x4, 0x10, 0x0, - - /* U+5C08 "專" */ - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x1, 0xd0, 0x0, 0x2, 0x0, 0x3, - 0x76, 0x66, 0x6e, 0x66, 0x69, 0xb1, 0x0, 0x0, - 0x10, 0x1, 0xd0, 0x1, 0x10, 0x0, 0x0, 0xe, - 0x66, 0x6e, 0x66, 0x9b, 0x0, 0x0, 0x0, 0xd0, - 0x1, 0xd0, 0x5, 0x80, 0x0, 0x0, 0xe, 0x66, - 0x6e, 0x66, 0x98, 0x0, 0x0, 0x1, 0xe6, 0x66, - 0xe6, 0x69, 0x80, 0x0, 0x0, 0x17, 0x0, 0x1d, - 0x2, 0x93, 0x0, 0x0, 0x16, 0x66, 0x78, 0xe7, - 0x68, 0xe4, 0x0, 0x0, 0x97, 0x43, 0x10, 0xb, - 0x13, 0x92, 0x3, 0x76, 0x66, 0x66, 0x66, 0xf6, - 0x6b, 0xb0, 0x0, 0x8, 0x40, 0x0, 0xf, 0x0, - 0x0, 0x0, 0x0, 0x1f, 0x0, 0x0, 0xf0, 0x0, - 0x0, 0x0, 0x0, 0x40, 0x7, 0xcd, 0x0, 0x0, - 0x0, 0x0, 0x0, 0x0, 0x4, 0x20, 0x0, 0x0, - - /* U+5C0D "對" */ - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0xb, 0x2a, 0x20, 0x0, 0x0, 0xb3, 0x0, - 0x6, 0xc, 0xb, 0x7, 0x10, 0x0, 0xd0, 0x0, - 0x6, 0x8c, 0xb, 0x49, 0x0, 0x0, 0xd0, 0x0, - 0x1, 0x4c, 0xb, 0x52, 0x20, 0x0, 0xd0, 0x0, - 0x28, 0x69, 0x69, 0x68, 0x80, 0x0, 0xd3, 0x50, - 0x0, 0x63, 0x7, 0x60, 0x18, 0x66, 0xe6, 0x50, - 0x0, 0x1d, 0x9, 0x10, 0x12, 0x0, 0xd0, 0x0, - 0x5, 0x79, 0x87, 0xb6, 0xb, 0x30, 0xd0, 0x0, - 0x0, 0x0, 0xb0, 0x0, 0x4, 0xe0, 0xd0, 0x0, - 0x0, 0x0, 0xb0, 0x40, 0x0, 0xc0, 0xd0, 0x0, - 0x2, 0x86, 0xc6, 0x73, 0x0, 0x0, 0xd0, 0x0, - 0x0, 0x0, 0xb0, 0x0, 0x0, 0x0, 0xd0, 0x0, - 0x0, 0x0, 0xb3, 0x54, 0x1, 0x10, 0xd0, 0x0, - 0x1b, 0xca, 0x73, 0x0, 0x1, 0x6e, 0xc0, 0x0, - 0x4, 0x0, 0x0, 0x0, 0x0, 0x2, 0x10, 0x0, - - /* U+5C0E "導" */ - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x7, 0x10, 0x0, 0x94, 0x5, 0x80, 0x0, 0x0, - 0x4c, 0x0, 0x1, 0x70, 0x80, 0x28, 0x0, 0x0, - 0x70, 0x77, 0x6a, 0x76, 0x67, 0x61, 0x3, 0x69, - 0x40, 0xe5, 0x65, 0x56, 0xd0, 0x0, 0x0, 0xb1, - 0xd, 0x55, 0x55, 0x6b, 0x0, 0x0, 0xb, 0x10, - 0xd6, 0x66, 0x67, 0xb0, 0x0, 0x0, 0xb1, 0xd, - 0x22, 0x22, 0x3b, 0x0, 0x0, 0x29, 0x72, 0x93, - 0x33, 0x34, 0x60, 0x0, 0x3a, 0x0, 0x6a, 0xbb, - 0xcc, 0xcd, 0xf6, 0x0, 0x0, 0x0, 0x0, 0x0, - 0xb1, 0x19, 0x0, 0x76, 0x66, 0x66, 0x66, 0x6e, - 0x68, 0xc6, 0x0, 0x0, 0x82, 0x0, 0x0, 0xe0, - 0x0, 0x0, 0x0, 0x2, 0xe0, 0x0, 0xe, 0x0, - 0x0, 0x0, 0x0, 0x5, 0x1, 0x7b, 0xc0, 0x0, - 0x0, 0x0, 0x0, 0x0, 0x0, 0x62, 0x0, 0x0, - - /* U+5C0F "小" */ - 0x0, 0x0, 0x0, 0x2a, 0x20, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x1e, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x1d, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x1d, 0x0, 0x0, 0x0, 0x0, 0x3, 0x90, 0x1d, - 0x4, 0x0, 0x0, 0x0, 0x8, 0xc0, 0x1d, 0x1, - 0x90, 0x0, 0x0, 0x1e, 0x10, 0x1d, 0x0, 0x3c, - 0x10, 0x0, 0x86, 0x0, 0x1d, 0x0, 0x8, 0xd0, - 0x2, 0x90, 0x0, 0x1d, 0x0, 0x0, 0xe8, 0x8, - 0x0, 0x0, 0x1d, 0x0, 0x0, 0x89, 0x40, 0x0, - 0x0, 0x1d, 0x0, 0x0, 0x12, 0x0, 0x0, 0x0, - 0x1d, 0x0, 0x0, 0x0, 0x0, 0x0, 0x44, 0x6d, - 0x0, 0x0, 0x0, 0x0, 0x0, 0x7, 0xf7, 0x0, - 0x0, 0x0, 0x0, 0x0, 0x0, 0x30, 0x0, 0x0, - 0x0, - - /* U+5C11 "少" */ - 0x0, 0x0, 0x0, 0x9, 0x40, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x0, 0xb3, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, 0xb, 0x30, 0x0, 0x0, 0x0, 0x0, - 0xa, 0x30, 0xb3, 0x16, 0x0, 0x0, 0x0, 0x2, - 0xf3, 0xb, 0x30, 0x2c, 0x60, 0x0, 0x0, 0xa7, - 0x0, 0xb3, 0x0, 0x1d, 0xb0, 0x0, 0x3b, 0x0, - 0xb, 0x30, 0x0, 0x2f, 0x50, 0xa, 0x10, 0x0, - 0xb3, 0x0, 0x40, 0x62, 0x7, 0x20, 0x0, 0xb, - 0x30, 0x3f, 0xa0, 0x1, 0x10, 0x0, 0x0, 0x81, - 0x3e, 0x90, 0x0, 0x0, 0x0, 0x0, 0x0, 0x5e, - 0x60, 0x0, 0x0, 0x0, 0x0, 0x1, 0x9c, 0x20, - 0x0, 0x0, 0x0, 0x0, 0x18, 0xc5, 0x0, 0x0, - 0x0, 0x0, 0x15, 0x88, 0x20, 0x0, 0x0, 0x0, - 0x0, 0x13, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, - - /* U+5C1A "尚" */ - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x2c, 0x10, 0x0, 0x0, 0x7, 0x30, 0x2, - 0xc0, 0x0, 0xc4, 0x0, 0xd, 0x70, 0x2c, 0x0, - 0x5d, 0x10, 0x0, 0x4f, 0x2, 0xc0, 0xb, 0x10, - 0x2, 0x0, 0x40, 0x2c, 0x7, 0x30, 0x30, 0xc7, - 0x66, 0x66, 0x86, 0x76, 0x6f, 0x3b, 0x20, 0x0, - 0x0, 0x0, 0x0, 0xe0, 0xb2, 0xa, 0x76, 0x66, - 0xe0, 0xe, 0xb, 0x20, 0xa3, 0x0, 0xd, 0x0, - 0xe0, 0xb2, 0xa, 0x30, 0x0, 0xd0, 0xe, 0xb, - 0x20, 0xa7, 0x66, 0x6d, 0x0, 0xe0, 0xb2, 0xa, - 0x20, 0x0, 0xa0, 0xe, 0xb, 0x20, 0x10, 0x0, - 0x4, 0x55, 0xe0, 0xc2, 0x0, 0x0, 0x0, 0x4, - 0xe9, 0x1, 0x0, 0x0, 0x0, 0x0, 0x2, 0x0, - - /* U+5C24 "尤" */ - 0x0, 0x0, 0x0, 0x95, 0x3, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x0, 0xb4, 0x2, 0xc9, 0x0, 0x0, - 0x0, 0x0, 0x0, 0xb3, 0x0, 0x1e, 0x30, 0x0, - 0x0, 0x0, 0x0, 0xb3, 0x0, 0x2, 0x5, 0x20, - 0x6, 0x76, 0x66, 0xc7, 0x69, 0x66, 0x6a, 0x90, - 0x0, 0x0, 0x0, 0xb2, 0x1c, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x0, 0xc1, 0x1c, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x0, 0xe0, 0x1c, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x0, 0xd0, 0x1c, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x5, 0xa0, 0x1c, 0x0, 0x0, 0x0, - 0x0, 0x0, 0xc, 0x30, 0x1c, 0x0, 0x0, 0x40, - 0x0, 0x0, 0x59, 0x0, 0x1c, 0x0, 0x0, 0x70, - 0x0, 0x4, 0xa0, 0x0, 0x1d, 0x0, 0x0, 0xc1, - 0x0, 0x76, 0x0, 0x0, 0xb, 0xdd, 0xdd, 0xd2, - 0x4, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - - /* U+5C31 "就" */ - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x2, 0x90, 0x0, 0x8, 0x50, 0x0, 0x0, - 0x0, 0x0, 0xa4, 0x0, 0x9, 0x32, 0x80, 0x0, - 0x5, 0x66, 0x76, 0x6c, 0x29, 0x30, 0x87, 0x0, - 0x1, 0x0, 0x0, 0x0, 0x9, 0x30, 0x12, 0x0, - 0x0, 0x86, 0x66, 0xa4, 0x6b, 0x86, 0x6a, 0x90, - 0x0, 0xd0, 0x0, 0xc1, 0x9, 0x3d, 0x0, 0x0, - 0x0, 0xd0, 0x0, 0xc0, 0x9, 0x3d, 0x0, 0x0, - 0x0, 0xd6, 0x86, 0xd1, 0xa, 0x2d, 0x0, 0x0, - 0x0, 0x40, 0xb0, 0x30, 0xc, 0xd, 0x0, 0x0, - 0x0, 0x93, 0xb2, 0x50, 0xc, 0xd, 0x0, 0x0, - 0x1, 0xb0, 0xb0, 0xa5, 0x47, 0xd, 0x0, 0x10, - 0x7, 0x20, 0xb0, 0x34, 0xa1, 0xd, 0x0, 0x60, - 0x15, 0x10, 0xc0, 0x5, 0x50, 0xd, 0x1, 0x90, - 0x0, 0x2b, 0xd0, 0x35, 0x0, 0x9, 0xcc, 0xb0, - 0x0, 0x0, 0x10, 0x30, 0x0, 0x0, 0x0, 0x0, - - /* U+5C3A "尺" */ - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x4, 0xa6, 0x66, 0x66, 0x66, 0xd3, 0x0, - 0x0, 0x4, 0xb0, 0x0, 0x0, 0x0, 0xd0, 0x0, - 0x0, 0x4, 0xb0, 0x0, 0x0, 0x0, 0xd0, 0x0, - 0x0, 0x4, 0xb0, 0x0, 0x0, 0x0, 0xd0, 0x0, - 0x0, 0x4, 0xd6, 0x66, 0x76, 0x66, 0xe1, 0x0, - 0x0, 0x4, 0xa0, 0x0, 0x60, 0x0, 0x70, 0x0, - 0x0, 0x4, 0x90, 0x0, 0x70, 0x0, 0x0, 0x0, - 0x0, 0x6, 0x70, 0x0, 0x45, 0x0, 0x0, 0x0, - 0x0, 0x8, 0x50, 0x0, 0xb, 0x0, 0x0, 0x0, - 0x0, 0xc, 0x10, 0x0, 0x5, 0xa0, 0x0, 0x0, - 0x0, 0x2a, 0x0, 0x0, 0x0, 0xaa, 0x0, 0x0, - 0x0, 0xa1, 0x0, 0x0, 0x0, 0xb, 0xd5, 0x0, - 0x6, 0x30, 0x0, 0x0, 0x0, 0x0, 0x9f, 0xa0, - 0x12, 0x0, 0x0, 0x0, 0x0, 0x0, 0x2, 0x0, - - /* U+5C40 "局" */ - 0x0, 0x1, 0x0, 0x0, 0x0, 0x0, 0x20, 0x0, - 0x0, 0xd6, 0x66, 0x66, 0x66, 0x6e, 0x30, 0x0, - 0xd, 0x10, 0x0, 0x0, 0x0, 0xe0, 0x0, 0x0, - 0xd6, 0x66, 0x66, 0x66, 0x6e, 0x0, 0x0, 0xd, - 0x10, 0x0, 0x0, 0x0, 0x60, 0x0, 0x0, 0xd1, - 0x0, 0x0, 0x0, 0x0, 0x30, 0x0, 0xd, 0x66, - 0x66, 0x66, 0x66, 0x6e, 0x40, 0x0, 0xd0, 0x0, - 0x0, 0x2, 0x0, 0xd1, 0x0, 0xd, 0x2, 0xc6, - 0x66, 0xe0, 0xd, 0x10, 0x2, 0xa0, 0x1b, 0x0, - 0xd, 0x0, 0xd1, 0x0, 0x56, 0x1, 0xd6, 0x66, - 0xd0, 0xd, 0x10, 0xa, 0x0, 0x2a, 0x0, 0x7, - 0x0, 0xe0, 0x2, 0x60, 0x0, 0x0, 0x0, 0x34, - 0x4e, 0x0, 0x60, 0x0, 0x0, 0x0, 0x0, 0x6f, - 0x60, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x10, - 0x0, - - /* U+5C45 "居" */ - 0x0, 0x3, 0x0, 0x0, 0x0, 0x0, 0x13, 0x0, - 0x0, 0xe, 0x66, 0x66, 0x66, 0x66, 0x9a, 0x0, - 0x0, 0xe, 0x0, 0x0, 0x0, 0x0, 0x68, 0x0, - 0x0, 0xe, 0x66, 0x66, 0x66, 0x66, 0x98, 0x0, - 0x0, 0xd, 0x0, 0x0, 0xb4, 0x0, 0x22, 0x0, - 0x0, 0xd, 0x0, 0x0, 0xb2, 0x0, 0x0, 0x0, - 0x0, 0xd, 0x76, 0x66, 0xd7, 0x66, 0x6b, 0x90, - 0x0, 0x1b, 0x0, 0x0, 0xb2, 0x0, 0x0, 0x0, - 0x0, 0x39, 0x0, 0x0, 0xb2, 0x0, 0x0, 0x0, - 0x0, 0x56, 0xc, 0x77, 0xb7, 0x77, 0xe1, 0x0, - 0x0, 0x82, 0xe, 0x0, 0x0, 0x0, 0xe0, 0x0, - 0x0, 0xa0, 0xe, 0x0, 0x0, 0x0, 0xe0, 0x0, - 0x4, 0x50, 0xe, 0x0, 0x0, 0x0, 0xe0, 0x0, - 0x7, 0x0, 0xf, 0x66, 0x66, 0x66, 0xe0, 0x0, - 0x10, 0x0, 0x5, 0x0, 0x0, 0x0, 0x0, 0x0, - - /* U+5C4A "届" */ - 0x0, 0x3, 0x0, 0x0, 0x0, 0x0, 0x5, 0x0, - 0x0, 0xe6, 0x66, 0x66, 0x66, 0x66, 0xe0, 0x0, - 0xe, 0x0, 0x0, 0x0, 0x0, 0x1c, 0x0, 0x0, - 0xe6, 0x66, 0x66, 0x66, 0x66, 0xd0, 0x0, 0xd, - 0x0, 0x0, 0x4, 0x0, 0x4, 0x0, 0x0, 0xd0, - 0x0, 0x0, 0xe2, 0x0, 0x0, 0x0, 0xc, 0x3, - 0x0, 0xe, 0x0, 0x5, 0x10, 0x1, 0xb0, 0xd6, - 0x66, 0xe6, 0x66, 0xd5, 0x0, 0x3a, 0xd, 0x10, - 0xe, 0x0, 0xb, 0x20, 0x5, 0x70, 0xd6, 0x66, - 0xe6, 0x66, 0xd2, 0x0, 0x83, 0xc, 0x10, 0xe, - 0x0, 0xb, 0x20, 0xa, 0x0, 0xc1, 0x0, 0xe0, - 0x0, 0xb2, 0x3, 0x60, 0xd, 0x66, 0x6e, 0x66, - 0x6d, 0x30, 0x70, 0x0, 0xc0, 0x0, 0x0, 0x0, - 0x92, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, - - /* U+5C4B "屋" */ - 0x0, 0x19, 0x66, 0x66, 0x66, 0x66, 0x6b, 0x0, - 0x0, 0x1d, 0x0, 0x0, 0x0, 0x0, 0x2b, 0x0, - 0x0, 0x1d, 0x0, 0x0, 0x0, 0x0, 0x2b, 0x0, - 0x0, 0x1e, 0x66, 0x66, 0x66, 0x66, 0x7b, 0x0, - 0x0, 0x1c, 0x0, 0x0, 0x0, 0x0, 0x14, 0x0, - 0x0, 0x1c, 0x47, 0x66, 0xa6, 0x66, 0x79, 0x10, - 0x0, 0x2b, 0x0, 0x5, 0xc3, 0x13, 0x0, 0x0, - 0x0, 0x3a, 0x0, 0x76, 0x0, 0x6, 0xb1, 0x0, - 0x0, 0x49, 0xc, 0xda, 0x87, 0x65, 0xab, 0x0, - 0x0, 0x66, 0x2, 0x20, 0xd, 0x10, 0x4, 0x0, - 0x0, 0xa2, 0x0, 0x0, 0xd, 0x0, 0x45, 0x0, - 0x0, 0xb0, 0x6, 0x76, 0x6e, 0x66, 0x65, 0x0, - 0x4, 0x50, 0x0, 0x0, 0xd, 0x0, 0x0, 0x10, - 0x7, 0x3, 0x66, 0x66, 0x6e, 0x66, 0x6a, 0xd1, - 0x11, 0x0, 0x10, 0x0, 0x0, 0x0, 0x0, 0x0, - - /* U+5C55 "展" */ - 0x0, 0x11, 0x0, 0x0, 0x0, 0x0, 0x51, 0x0, - 0x3, 0xc6, 0x66, 0x66, 0x66, 0x6d, 0x50, 0x0, - 0x3b, 0x0, 0x0, 0x0, 0x0, 0xb2, 0x0, 0x3, - 0xc6, 0x67, 0x66, 0x66, 0x6d, 0x30, 0x0, 0x3a, - 0x0, 0xb5, 0x0, 0xd0, 0x10, 0x0, 0x3, 0xa0, - 0xb, 0x20, 0xd, 0x7, 0x0, 0x0, 0x3c, 0x66, - 0xd7, 0x66, 0xe6, 0x62, 0x0, 0x4, 0x90, 0xb, - 0x20, 0xd, 0x0, 0x30, 0x0, 0x5a, 0x68, 0xa7, - 0x76, 0xa6, 0x7b, 0x30, 0x8, 0x50, 0xa2, 0x7, - 0x0, 0x57, 0x0, 0x0, 0xb1, 0xa, 0x20, 0x47, - 0x59, 0x20, 0x0, 0xb, 0x0, 0xa2, 0x0, 0xa9, - 0x0, 0x0, 0x5, 0x40, 0xa, 0x57, 0x50, 0x9c, - 0x63, 0x10, 0x70, 0x0, 0xbb, 0x10, 0x0, 0x4c, - 0xe5, 0x10, 0x0, 0x1, 0x0, 0x0, 0x0, 0x0, - 0x0, - - /* U+5C65 "履" */ - 0x0, 0x28, 0x66, 0x66, 0x66, 0x66, 0x6a, 0x20, - 0x0, 0x2b, 0x0, 0x0, 0x0, 0x0, 0xc, 0x0, - 0x0, 0x1d, 0x66, 0x66, 0x76, 0x66, 0x6d, 0x10, - 0x0, 0x1b, 0x4, 0x90, 0xb6, 0x0, 0x6, 0x0, - 0x0, 0x1b, 0xa, 0x10, 0xc6, 0x66, 0x68, 0x30, - 0x0, 0x2a, 0x63, 0x55, 0xc6, 0x66, 0x6c, 0x0, - 0x0, 0x2a, 0x26, 0xb6, 0xa1, 0x0, 0xc, 0x0, - 0x0, 0x39, 0xc, 0x20, 0xa7, 0x66, 0x6c, 0x0, - 0x0, 0x47, 0x7e, 0x20, 0xa8, 0x66, 0x6c, 0x0, - 0x0, 0x67, 0x5c, 0x0, 0x1c, 0x50, 0x11, 0x0, - 0x0, 0x91, 0xc, 0x0, 0x7b, 0x66, 0xc9, 0x0, - 0x0, 0x90, 0xc, 0x4, 0x42, 0x76, 0x90, 0x0, - 0x4, 0x40, 0xc, 0x1, 0x1, 0xbd, 0x40, 0x0, - 0x5, 0x0, 0xb, 0x2, 0x78, 0x20, 0x8d, 0xb1, - 0x0, 0x0, 0x0, 0x33, 0x0, 0x0, 0x0, 0x20, - - /* U+5C6C "屬" */ - 0x0, 0x11, 0x0, 0x0, 0x0, 0x0, 0x21, 0x0, - 0x2, 0xd6, 0x66, 0x66, 0x66, 0x6a, 0x70, 0x0, - 0x2b, 0x0, 0x0, 0x0, 0x0, 0x75, 0x0, 0x2, - 0xc6, 0x86, 0x69, 0x86, 0x9b, 0x30, 0x0, 0x2b, - 0x1, 0xa3, 0x75, 0x46, 0x20, 0x0, 0x2, 0xa7, - 0x85, 0x47, 0x44, 0x7a, 0x30, 0x0, 0x3a, 0x56, - 0x66, 0x86, 0x66, 0x94, 0x0, 0x3, 0x95, 0x60, - 0xa0, 0xb, 0xa, 0x10, 0x0, 0x58, 0x5a, 0x68, - 0x66, 0x86, 0xb1, 0x0, 0x6, 0x50, 0x9b, 0x66, - 0x66, 0x66, 0x90, 0x0, 0x92, 0x66, 0x0, 0xa0, - 0x1, 0x1a, 0x0, 0xb, 0x32, 0xb6, 0x6d, 0x67, - 0x92, 0x90, 0x1, 0x90, 0xb, 0x66, 0xd6, 0x77, - 0x38, 0x0, 0x62, 0x0, 0x33, 0x3c, 0x57, 0x75, - 0x60, 0x6, 0x0, 0x1a, 0x64, 0x10, 0x19, 0xc3, - 0x0, 0x10, 0x0, 0x0, 0x0, 0x0, 0x15, 0x0, - - /* U+5C71 "山" */ - 0x0, 0x0, 0x0, 0x61, 0x0, 0x0, 0x0, 0x0, - 0x0, 0xd, 0x20, 0x0, 0x0, 0x0, 0x0, 0x0, - 0xd0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xd, 0x0, - 0x0, 0x0, 0x9, 0x40, 0x0, 0xd0, 0x0, 0xa, - 0x30, 0xa3, 0x0, 0xd, 0x0, 0x0, 0xc1, 0xa, - 0x30, 0x0, 0xd0, 0x0, 0xc, 0x10, 0xa3, 0x0, - 0xd, 0x0, 0x0, 0xc1, 0xa, 0x30, 0x0, 0xd0, - 0x0, 0xc, 0x10, 0xa3, 0x0, 0xd, 0x0, 0x0, - 0xc1, 0xa, 0x30, 0x0, 0xd0, 0x0, 0xc, 0x10, - 0xa3, 0x0, 0xd, 0x0, 0x0, 0xc1, 0xd, 0x76, - 0x66, 0xa6, 0x66, 0x6d, 0x10, 0x10, 0x0, 0x0, - 0x0, 0x0, 0x91, - - /* U+5CF6 "島" */ - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, 0xb2, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x20, 0x7, 0x0, 0x0, 0x51, 0x0, 0x0, 0xc, - 0x66, 0x66, 0x66, 0x6d, 0x30, 0x0, 0x0, 0xc6, - 0x66, 0x66, 0x66, 0xd1, 0x0, 0x0, 0xc, 0x10, - 0x0, 0x0, 0xc, 0x10, 0x0, 0x0, 0xc6, 0x66, - 0x66, 0x66, 0xd1, 0x0, 0x0, 0xc, 0x10, 0x0, - 0x0, 0x1, 0x2, 0x70, 0x0, 0xc6, 0x66, 0x66, - 0x66, 0x66, 0x66, 0x10, 0xc, 0x66, 0x66, 0x66, - 0x66, 0x6a, 0x50, 0x0, 0x40, 0xa, 0x10, 0x0, - 0x0, 0x93, 0x1, 0xb0, 0x0, 0xd0, 0x0, 0xb1, - 0xb, 0x10, 0xc, 0x0, 0xd, 0x0, 0xd, 0x0, - 0xd0, 0x2, 0xc6, 0x66, 0x96, 0x66, 0xc0, 0x1c, - 0x0, 0x0, 0x0, 0x0, 0x0, 0x17, 0xce, 0x60, - 0x0, 0x0, 0x0, 0x0, 0x0, 0x3, 0x30, 0x0, - - /* U+5D4C "嵌" */ - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x1, 0x0, 0x6, 0x80, 0x0, 0x20, 0x0, 0x1, - 0xd0, 0x0, 0x66, 0x0, 0xb, 0x40, 0x0, 0x1b, - 0x0, 0x6, 0x60, 0x0, 0xb2, 0x0, 0x2, 0xb6, - 0x66, 0x66, 0x66, 0x6c, 0x20, 0x0, 0x19, 0x0, - 0xb2, 0x2, 0xe0, 0x0, 0x0, 0x1, 0xb0, 0xd, - 0x22, 0x78, 0x0, 0x21, 0x5, 0x7d, 0x66, 0xe7, - 0x6b, 0x66, 0x6c, 0x90, 0x1, 0xb0, 0xd, 0x5, - 0x77, 0x41, 0x70, 0x0, 0x1d, 0x66, 0xe0, 0x70, - 0xb6, 0x0, 0x0, 0x1, 0xb0, 0xd, 0x0, 0xd, - 0x50, 0x0, 0x0, 0x1b, 0x0, 0xd0, 0x3, 0xa6, - 0x20, 0x0, 0x1, 0xb0, 0xd, 0x0, 0x94, 0x1b, - 0x0, 0x0, 0x1d, 0x66, 0xe0, 0x48, 0x0, 0x7b, - 0x10, 0x2, 0x80, 0x5, 0x66, 0x0, 0x0, 0xbd, - 0x20, 0x0, 0x0, 0x31, 0x0, 0x0, 0x0, 0x10, - - /* U+5DDD "川" */ - 0x0, 0x25, 0x0, 0x0, 0x0, 0x5, 0x50, 0x2, - 0xc0, 0x0, 0x40, 0x0, 0x78, 0x0, 0x2b, 0x0, - 0xd, 0x30, 0x7, 0x70, 0x2, 0xb0, 0x0, 0xc1, - 0x0, 0x77, 0x0, 0x3a, 0x0, 0xc, 0x10, 0x6, - 0x70, 0x3, 0xa0, 0x0, 0xc1, 0x0, 0x67, 0x0, - 0x39, 0x0, 0xc, 0x10, 0x6, 0x70, 0x5, 0x70, - 0x0, 0xc1, 0x0, 0x67, 0x0, 0x65, 0x0, 0xc, - 0x10, 0x6, 0x70, 0x9, 0x20, 0x0, 0xc1, 0x0, - 0x67, 0x0, 0xc0, 0x0, 0xd, 0x10, 0x6, 0x70, - 0x36, 0x0, 0x0, 0x80, 0x0, 0x67, 0x8, 0x0, - 0x0, 0x0, 0x0, 0x7, 0x73, 0x30, 0x0, 0x0, - 0x0, 0x0, 0x77, 0x20, 0x0, 0x0, 0x0, 0x0, - 0x2, 0x0, - - /* U+5DDE "州" */ - 0x0, 0x0, 0x20, 0x0, 0x0, 0x0, 0x72, 0x0, - 0x0, 0xd2, 0x0, 0x93, 0x0, 0xb3, 0x0, 0x0, - 0xd0, 0x0, 0xb1, 0x0, 0xb2, 0x0, 0x0, 0xd0, - 0x0, 0xb1, 0x0, 0xb2, 0x0, 0x10, 0xd0, 0x0, - 0xb1, 0x10, 0xb2, 0x0, 0x70, 0xd0, 0x90, 0xb1, - 0x82, 0xb2, 0x1, 0xc0, 0xd0, 0xa5, 0xb1, 0x4b, - 0xb2, 0x9, 0x91, 0xb0, 0x64, 0xb1, 0x7, 0xb2, - 0x1, 0x4, 0x90, 0x0, 0xb1, 0x0, 0xb2, 0x0, - 0x7, 0x60, 0x0, 0xb1, 0x0, 0xb2, 0x0, 0xc, - 0x20, 0x0, 0xb1, 0x0, 0xb2, 0x0, 0x2b, 0x0, - 0x0, 0xb2, 0x0, 0xb2, 0x0, 0xa2, 0x0, 0x0, - 0x91, 0x0, 0xb2, 0x6, 0x40, 0x0, 0x0, 0x0, - 0x0, 0xb2, 0x13, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x30, - - /* U+5DE5 "工" */ - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x72, 0x0, - 0x28, 0x66, 0x66, 0xb7, 0x66, 0x68, 0x60, 0x0, - 0x0, 0x0, 0xb, 0x30, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, 0xb3, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0xb, 0x30, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0xb3, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0xb, 0x30, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0xb3, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xb, - 0x30, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xb3, - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xb, 0x30, - 0x0, 0x3, 0x1, 0x66, 0x66, 0x66, 0xd8, 0x66, - 0x68, 0xf6, 0x2, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, - - /* U+5DE6 "左" */ - 0x0, 0x0, 0x0, 0xb2, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x2e, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x4, 0xb0, 0x0, 0x0, 0x96, 0x0, 0x37, - 0x66, 0xaa, 0x66, 0x66, 0x66, 0x50, 0x0, 0x0, - 0xb, 0x30, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0xd0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x57, - 0x0, 0x0, 0x1, 0x0, 0x0, 0x0, 0xb, 0x66, - 0x67, 0x66, 0xb9, 0x0, 0x0, 0x4, 0x80, 0x0, - 0xb2, 0x0, 0x0, 0x0, 0x0, 0xa0, 0x0, 0xb, - 0x20, 0x0, 0x0, 0x0, 0x74, 0x0, 0x0, 0xb2, - 0x0, 0x0, 0x0, 0x36, 0x0, 0x0, 0xb, 0x20, - 0x0, 0x0, 0x15, 0x0, 0x0, 0x0, 0xb2, 0x0, - 0x27, 0x0, 0x0, 0x66, 0x66, 0x67, 0x66, 0x67, - 0x82, - - /* U+5DEE "差" */ - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x59, 0x0, 0x0, 0x6c, 0x0, 0x0, 0x0, - 0x0, 0x96, 0x0, 0xa, 0x10, 0x10, 0x0, 0x56, - 0x67, 0x76, 0x68, 0x86, 0x6e, 0x90, 0x1, 0x0, - 0x0, 0xc1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0xe, 0x0, 0x0, 0x81, 0x0, 0x0, 0x66, 0x68, - 0xc6, 0x66, 0x67, 0x40, 0x0, 0x0, 0x0, 0x85, - 0x0, 0x0, 0x4, 0x20, 0x46, 0x66, 0x6d, 0x66, - 0x66, 0x66, 0xa9, 0x0, 0x0, 0x7, 0x60, 0x0, - 0x0, 0x0, 0x0, 0x0, 0x2, 0xc6, 0x66, 0x66, - 0x6d, 0x30, 0x0, 0x0, 0xa1, 0x0, 0xd, 0x0, - 0x0, 0x0, 0x0, 0x92, 0x0, 0x0, 0xd0, 0x0, - 0x0, 0x1, 0x71, 0x0, 0x0, 0xd, 0x0, 0x0, - 0x10, 0x40, 0x36, 0x66, 0x66, 0xe6, 0x66, 0xbd, - 0x10, 0x0, 0x10, 0x0, 0x0, 0x0, 0x0, 0x0, - - /* U+5DF1 "己" */ - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x26, - 0x66, 0x66, 0x66, 0x66, 0xd2, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x0, 0xe0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, 0xe0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0xe0, 0x0, 0x3, 0x0, 0x0, 0x0, 0x0, - 0xe0, 0x0, 0xe, 0x66, 0x66, 0x66, 0x66, 0xf0, - 0x0, 0xd, 0x0, 0x0, 0x0, 0x0, 0x20, 0x0, - 0xd, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xd, - 0x0, 0x0, 0x0, 0x0, 0x0, 0x30, 0xd, 0x0, - 0x0, 0x0, 0x0, 0x0, 0x60, 0xd, 0x0, 0x0, - 0x0, 0x0, 0x0, 0xb0, 0xe, 0x42, 0x22, 0x22, - 0x22, 0x26, 0xf3, 0x5, 0xaa, 0xaa, 0xaa, 0xaa, - 0xaa, 0x70, - - /* U+5DF2 "已" */ - 0x0, 0x0, 0x0, 0x0, 0x0, 0x20, 0x0, 0x18, - 0x66, 0x66, 0x66, 0x66, 0xf2, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x0, 0xe0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, 0xe0, 0x0, 0x5, 0x0, 0x0, 0x0, - 0x0, 0xe0, 0x0, 0xf, 0x10, 0x0, 0x0, 0x0, - 0xe0, 0x0, 0xe, 0x66, 0x66, 0x66, 0x66, 0xe0, - 0x0, 0xe, 0x0, 0x0, 0x0, 0x0, 0x20, 0x0, - 0xe, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xe, - 0x0, 0x0, 0x0, 0x0, 0x0, 0x40, 0xe, 0x0, - 0x0, 0x0, 0x0, 0x0, 0x60, 0xe, 0x0, 0x0, - 0x0, 0x0, 0x1, 0x90, 0xe, 0x42, 0x22, 0x22, - 0x22, 0x27, 0xe1, 0x5, 0x99, 0x99, 0x99, 0x99, - 0x99, 0x50, - - /* U+5E02 "市" */ - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x48, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, 0xc5, 0x0, 0x0, 0x20, 0x4, 0x66, - 0x66, 0x69, 0x76, 0x66, 0x6f, 0x80, 0x11, 0x0, - 0x0, 0xb2, 0x0, 0x0, 0x0, 0x0, 0x1, 0x0, - 0xb, 0x20, 0x0, 0x20, 0x0, 0x0, 0xd6, 0x66, - 0xd7, 0x66, 0x6f, 0x20, 0x0, 0xd, 0x10, 0xb, - 0x20, 0x0, 0xe0, 0x0, 0x0, 0xd1, 0x0, 0xb2, - 0x0, 0xe, 0x0, 0x0, 0xd, 0x10, 0xb, 0x20, - 0x0, 0xe0, 0x0, 0x0, 0xd1, 0x0, 0xb2, 0x0, - 0xe, 0x0, 0x0, 0xd, 0x10, 0xb, 0x20, 0x0, - 0xe0, 0x0, 0x0, 0xd1, 0x0, 0xb2, 0x17, 0x9d, - 0x0, 0x0, 0xb, 0x0, 0xb, 0x20, 0xb, 0x40, - 0x0, 0x0, 0x0, 0x0, 0xc3, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x0, 0x5, 0x0, 0x0, 0x0, 0x0, - - /* U+5E03 "布" */ - 0x0, 0x0, 0x0, 0xa, 0x50, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x0, 0x1f, 0x40, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x0, 0x8a, 0x0, 0x0, 0x3, 0xa0, - 0x4, 0x66, 0x66, 0xf6, 0x66, 0x66, 0x66, 0x62, - 0x0, 0x0, 0x7, 0x70, 0x1b, 0x10, 0x0, 0x0, - 0x0, 0x0, 0x1c, 0x0, 0x1d, 0x0, 0x3, 0x0, - 0x0, 0x0, 0xbe, 0x66, 0x6e, 0x66, 0x7e, 0x10, - 0x0, 0x7, 0x4d, 0x0, 0xd, 0x0, 0x1c, 0x0, - 0x0, 0x64, 0xd, 0x0, 0xd, 0x0, 0x1c, 0x0, - 0x4, 0x30, 0xd, 0x0, 0xd, 0x0, 0x1c, 0x0, - 0x1, 0x0, 0xd, 0x0, 0xd, 0x0, 0x1c, 0x0, - 0x0, 0x0, 0xd, 0x0, 0xd, 0x5, 0x6c, 0x0, - 0x0, 0x0, 0x1b, 0x0, 0x1d, 0x2, 0xd6, 0x0, - 0x0, 0x0, 0x0, 0x0, 0x1d, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x0, 0x0, 0x16, 0x0, 0x0, 0x0, - - /* U+5E08 "师" */ - 0x0, 0xa, 0x40, 0x0, 0x0, 0x0, 0x5, 0x0, - 0x0, 0xc2, 0x47, 0x66, 0xb6, 0x66, 0x93, 0x9, - 0xc, 0x10, 0x0, 0xd, 0x0, 0x0, 0x0, 0xd0, - 0xb1, 0x0, 0x0, 0xd0, 0x0, 0x10, 0xd, 0xb, - 0x10, 0xd6, 0x6e, 0x66, 0x7d, 0x0, 0xd0, 0xb1, - 0xd, 0x0, 0xd0, 0x2, 0xb0, 0xd, 0xc, 0x0, - 0xd0, 0xd, 0x0, 0x2b, 0x0, 0xd0, 0xc0, 0xd, - 0x0, 0xd0, 0x2, 0xb0, 0xd, 0xc, 0x0, 0xd0, - 0xd, 0x0, 0x2b, 0x0, 0xb2, 0xa0, 0xd, 0x0, - 0xd0, 0x2, 0xb0, 0x0, 0x74, 0x0, 0xd0, 0xd, - 0x5, 0x8a, 0x0, 0xb, 0x0, 0x5, 0x0, 0xd0, - 0xa, 0x30, 0x7, 0x30, 0x0, 0x0, 0xd, 0x0, - 0x0, 0x3, 0x40, 0x0, 0x0, 0x0, 0xe0, 0x0, - 0x0, 0x20, 0x0, 0x0, 0x0, 0x6, 0x0, 0x0, - 0x0, - - /* U+5E0C "希" */ - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x1, 0x30, 0x0, 0x0, 0xba, 0x0, 0x0, - 0x0, 0x0, 0x16, 0x86, 0x4c, 0x70, 0x0, 0x0, - 0x0, 0x0, 0x0, 0x2c, 0xcb, 0x50, 0x0, 0x0, - 0x0, 0x0, 0x37, 0x83, 0x3, 0xbe, 0x30, 0x0, - 0x0, 0x25, 0x30, 0x9c, 0x0, 0x5, 0x61, 0x10, - 0x6, 0x66, 0x66, 0xf7, 0x66, 0x66, 0x6d, 0xb0, - 0x0, 0x0, 0xb, 0x40, 0xa1, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x86, 0x0, 0xd0, 0x0, 0x30, 0x0, - 0x0, 0x7, 0xf6, 0x66, 0xe6, 0x66, 0xf2, 0x0, - 0x0, 0x74, 0xe0, 0x0, 0xd0, 0x0, 0xe0, 0x0, - 0x16, 0x10, 0xe0, 0x0, 0xd0, 0x0, 0xe0, 0x0, - 0x0, 0x0, 0xe0, 0x0, 0xd0, 0x12, 0xd0, 0x0, - 0x0, 0x0, 0xe0, 0x0, 0xe0, 0x5e, 0x90, 0x0, - 0x0, 0x0, 0x30, 0x0, 0xe0, 0x1, 0x0, 0x0, - 0x0, 0x0, 0x0, 0x0, 0x60, 0x0, 0x0, 0x0, - - /* U+5E2B "師" */ - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0xb, 0x30, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x90, 0x2, 0x55, 0x55, 0x55, 0x5c, 0x19, 0x78, - 0x6b, 0x32, 0x11, 0xd1, 0x11, 0x10, 0xd0, 0x0, - 0xd0, 0x0, 0xd, 0x0, 0x0, 0xd, 0x0, 0xd, - 0x7, 0x66, 0xe6, 0x66, 0xb0, 0xd0, 0x0, 0xd0, - 0xd0, 0xd, 0x0, 0x2a, 0xd, 0x66, 0x6b, 0xd, - 0x0, 0xd0, 0x2, 0xa0, 0xd0, 0x0, 0x20, 0xd0, - 0xd, 0x0, 0x2a, 0xd, 0x66, 0x6e, 0x2d, 0x0, - 0xd0, 0x2, 0xa0, 0xd0, 0x0, 0xd0, 0xd0, 0xd, - 0x0, 0x2a, 0xd, 0x0, 0xd, 0xd, 0x0, 0xd0, - 0x24, 0xa0, 0xd0, 0x0, 0xd0, 0xb0, 0xd, 0x5, - 0xe6, 0xd, 0x66, 0x6d, 0x0, 0x0, 0xd0, 0x1, - 0x0, 0x90, 0x0, 0x10, 0x0, 0xd, 0x0, 0x0, - 0x0, 0x0, 0x0, 0x0, 0x0, 0x50, 0x0, 0x0, - - /* U+5E2D "席" */ - 0x0, 0x0, 0x0, 0x5, 0x60, 0x0, 0x0, 0x0, - 0x0, 0x30, 0x0, 0x0, 0xd0, 0x0, 0x4, 0x60, - 0x0, 0xb7, 0x66, 0x76, 0x66, 0x96, 0x66, 0x50, - 0x0, 0xb2, 0x0, 0x75, 0x0, 0xd3, 0x0, 0x0, - 0x0, 0xb3, 0x66, 0xa8, 0x66, 0xe6, 0x6d, 0x60, - 0x0, 0xb2, 0x0, 0x64, 0x0, 0xd0, 0x0, 0x0, - 0x0, 0xc1, 0x0, 0x68, 0x66, 0xe0, 0x0, 0x0, - 0x0, 0xc0, 0x0, 0x52, 0xb1, 0x70, 0x0, 0x0, - 0x0, 0xd0, 0x3, 0x0, 0xb1, 0x0, 0x5, 0x0, - 0x0, 0xd0, 0xe, 0x66, 0xd6, 0x66, 0x7c, 0x0, - 0x1, 0xa0, 0xd, 0x0, 0xb1, 0x0, 0x2a, 0x0, - 0x5, 0x50, 0xd, 0x0, 0xb1, 0x0, 0x2a, 0x0, - 0x8, 0x0, 0xd, 0x0, 0xb1, 0x28, 0xd8, 0x0, - 0x6, 0x0, 0x5, 0x0, 0xc2, 0x0, 0x50, 0x0, - 0x10, 0x0, 0x0, 0x0, 0x60, 0x0, 0x0, 0x0, - - /* U+5E2F "帯" */ - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x0, 0x7, 0x50, 0x1, 0x0, 0x0, - 0x0, 0x3, 0xa0, 0x7, 0x50, 0xb, 0x33, 0x0, - 0x4, 0x68, 0xb6, 0x6a, 0x96, 0x6d, 0x7c, 0x70, - 0x0, 0x3, 0x90, 0x7, 0x50, 0xb, 0x20, 0x0, - 0x0, 0x5, 0xb6, 0x69, 0x86, 0x6c, 0x20, 0x0, - 0x0, 0x40, 0x10, 0x0, 0x0, 0x3, 0x2, 0x10, - 0x2, 0xa6, 0x66, 0x68, 0x76, 0x66, 0x6b, 0xa0, - 0xb, 0x50, 0x0, 0x7, 0x70, 0x0, 0x7, 0x0, - 0x3, 0xb, 0x66, 0x6a, 0x96, 0x67, 0xc0, 0x0, - 0x0, 0xd, 0x0, 0x7, 0x50, 0x3, 0xa0, 0x0, - 0x0, 0xd, 0x0, 0x7, 0x50, 0x3, 0xa0, 0x0, - 0x0, 0xd, 0x0, 0x7, 0x50, 0x3, 0xa0, 0x0, - 0x0, 0xd, 0x0, 0x7, 0x50, 0x6c, 0x80, 0x0, - 0x0, 0x3, 0x0, 0x7, 0x50, 0x5, 0x0, 0x0, - 0x0, 0x0, 0x0, 0x4, 0x20, 0x0, 0x0, 0x0, - - /* U+5E30 "帰" */ - 0x0, 0x7, 0x40, 0x56, 0x66, 0x66, 0x6b, 0x0, - 0x0, 0x9, 0x30, 0x11, 0x0, 0x0, 0x1c, 0x0, - 0x0, 0x9, 0x30, 0x36, 0x66, 0x66, 0x6c, 0x0, - 0x6, 0x29, 0x30, 0x1, 0x0, 0x0, 0x1c, 0x0, - 0xb, 0x9, 0x30, 0x66, 0x66, 0x66, 0x6c, 0x0, - 0xb, 0xa, 0x22, 0x0, 0x0, 0x0, 0x4, 0x10, - 0xb, 0xb, 0x1a, 0x66, 0x6a, 0x66, 0x66, 0xe1, - 0xb, 0xc, 0x5a, 0x0, 0xd, 0x0, 0x4, 0x30, - 0x7, 0xc, 0x11, 0x76, 0x6e, 0x66, 0x6a, 0x0, - 0x0, 0x2a, 0x0, 0xd0, 0xd, 0x0, 0x1c, 0x0, - 0x0, 0x65, 0x0, 0xd0, 0xd, 0x0, 0x1c, 0x0, - 0x0, 0xa0, 0x0, 0xd0, 0xd, 0x0, 0x1c, 0x0, - 0x3, 0x60, 0x0, 0xd0, 0xd, 0x6, 0xab, 0x0, - 0x6, 0x0, 0x0, 0x50, 0xd, 0x0, 0x62, 0x0, - 0x10, 0x0, 0x0, 0x0, 0x7, 0x0, 0x0, 0x0, - - /* U+5E33 "帳" */ - 0x0, 0xb1, 0x0, 0x4, 0x0, 0x0, 0x71, 0x0, - 0xd, 0x0, 0x0, 0xd6, 0x66, 0x66, 0x30, 0x10, - 0xd0, 0x30, 0xd, 0x22, 0x24, 0x70, 0xe, 0x6e, - 0x6e, 0x30, 0xd3, 0x33, 0x32, 0x0, 0xd0, 0xd0, - 0xd0, 0xc, 0x0, 0x1, 0x60, 0xd, 0xd, 0xd, - 0x0, 0xd6, 0x66, 0x65, 0x0, 0xd0, 0xd0, 0xd0, - 0xc, 0x0, 0x0, 0x17, 0xd, 0xd, 0xd, 0x47, - 0xd6, 0x96, 0x66, 0x61, 0xd0, 0xd0, 0xd0, 0x1b, - 0x6, 0x0, 0x84, 0xd, 0xd, 0x3d, 0x1, 0xb0, - 0x44, 0x6a, 0x20, 0x90, 0xd4, 0x80, 0x1b, 0x0, - 0xc4, 0x0, 0x0, 0xd, 0x0, 0x1, 0xb0, 0x5, - 0xa0, 0x0, 0x0, 0xd0, 0x0, 0x1c, 0x76, 0x9, - 0xb2, 0x0, 0xe, 0x0, 0x4, 0xf5, 0x0, 0x9, - 0xd3, 0x0, 0x50, 0x0, 0x3, 0x0, 0x0, 0x0, - 0x0, - - /* U+5E36 "帶" */ - 0x0, 0x1, 0xb0, 0x92, 0x18, 0xb, 0x10, 0x0, - 0x0, 0x0, 0xd0, 0xc0, 0xb, 0xd, 0x4, 0x0, - 0x2, 0x66, 0xd6, 0xd6, 0x6d, 0x6e, 0x6b, 0x80, - 0x0, 0x4, 0x80, 0xc0, 0xb, 0xd, 0x0, 0x40, - 0x0, 0x1a, 0x0, 0xc6, 0x6c, 0xd, 0x57, 0xb0, - 0x1, 0x60, 0x0, 0x60, 0x4, 0x3, 0x55, 0x20, - 0x0, 0x96, 0x66, 0x67, 0x66, 0x66, 0x68, 0xb0, - 0x7, 0x50, 0x0, 0x6, 0xb0, 0x0, 0x7, 0x40, - 0xd, 0x18, 0x66, 0x69, 0xb6, 0x68, 0xb3, 0x0, - 0x0, 0xb, 0x20, 0x6, 0x90, 0x4, 0x90, 0x0, - 0x0, 0xb, 0x20, 0x6, 0x90, 0x4, 0x90, 0x0, - 0x0, 0xb, 0x20, 0x6, 0x90, 0x4, 0x90, 0x0, - 0x0, 0xb, 0x10, 0x6, 0x91, 0x8c, 0x80, 0x0, - 0x0, 0x0, 0x0, 0x6, 0xa0, 0x7, 0x0, 0x0, - 0x0, 0x0, 0x0, 0x4, 0x40, 0x0, 0x0, 0x0, - - /* U+5E38 "常" */ - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x15, 0x0, 0x93, 0x2, 0x60, 0x0, 0x0, 0x8, - 0xa0, 0xa2, 0xa, 0x60, 0x0, 0x2, 0x0, 0x90, - 0xa2, 0x43, 0x0, 0x30, 0xa, 0x66, 0x66, 0x76, - 0x66, 0x66, 0xe8, 0x78, 0x2, 0x10, 0x0, 0x4, - 0x2, 0x70, 0x61, 0x5, 0xa6, 0x66, 0x6d, 0x20, - 0x0, 0x0, 0x4, 0x70, 0x0, 0xc, 0x0, 0x0, - 0x0, 0x5, 0xa6, 0xb7, 0x6c, 0x0, 0x0, 0x0, - 0x21, 0x0, 0xa2, 0x0, 0x3, 0x0, 0x0, 0xd6, - 0x66, 0xc7, 0x66, 0x8c, 0x0, 0x0, 0xd1, 0x0, - 0xa2, 0x0, 0x39, 0x0, 0x0, 0xd1, 0x0, 0xa2, - 0x0, 0x39, 0x0, 0x0, 0xd1, 0x0, 0xa2, 0x18, - 0xd8, 0x0, 0x0, 0x40, 0x0, 0xb3, 0x0, 0x60, - 0x0, 0x0, 0x0, 0x0, 0x50, 0x0, 0x0, 0x0, - - /* U+5E45 "幅" */ - 0x0, 0x92, 0x0, 0x0, 0x0, 0x0, 0x10, 0x0, - 0xc0, 0x4, 0x76, 0x66, 0x66, 0x96, 0x10, 0xc0, - 0x30, 0x0, 0x0, 0x1, 0x0, 0xc6, 0xd6, 0xd3, - 0xd, 0x66, 0x6d, 0x30, 0xc0, 0xc0, 0xc0, 0xd, - 0x0, 0xc, 0x0, 0xc0, 0xc0, 0xc0, 0xd, 0x66, - 0x6d, 0x0, 0xc0, 0xc0, 0xc0, 0xb, 0x0, 0x6, - 0x0, 0xc0, 0xc0, 0xc0, 0x86, 0x66, 0x66, 0xa2, - 0xc0, 0xc0, 0xc0, 0xd0, 0xc, 0x0, 0xb2, 0xc0, - 0xc0, 0xc0, 0xd0, 0xc, 0x0, 0xb1, 0xc0, 0xc6, - 0xa0, 0xd6, 0x6d, 0x66, 0xd1, 0x10, 0xc0, 0x0, - 0xd0, 0xc, 0x0, 0xb1, 0x0, 0xc0, 0x0, 0xd6, - 0x6d, 0x66, 0xd1, 0x0, 0xc0, 0x0, 0xd0, 0x0, - 0x0, 0xb1, 0x0, 0x50, 0x0, 0x40, 0x0, 0x0, - 0x10, - - /* U+5E73 "平" */ - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x51, 0x0, - 0x0, 0x76, 0x66, 0x6b, 0x76, 0x66, 0x86, 0x0, - 0x0, 0x3, 0x0, 0xb, 0x30, 0x6, 0x30, 0x0, - 0x0, 0x6, 0x80, 0xb, 0x30, 0xe, 0x50, 0x0, - 0x0, 0x0, 0xd7, 0xb, 0x30, 0x74, 0x0, 0x0, - 0x0, 0x0, 0x68, 0xb, 0x32, 0x50, 0x1, 0x0, - 0x26, 0x66, 0x66, 0x6d, 0x87, 0x66, 0x6e, 0x80, - 0x1, 0x0, 0x0, 0xb, 0x30, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x0, 0xb, 0x30, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x0, 0xb, 0x30, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x0, 0xb, 0x30, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x0, 0xb, 0x30, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x0, 0xb, 0x40, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x0, 0xb, 0x30, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - - /* U+5E74 "年" */ - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, 0xd4, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x4, 0xc0, 0x0, 0x0, 0x0, 0x3, 0x0, - 0x0, 0xc, 0x86, 0x66, 0x86, 0x66, 0x8c, 0x20, - 0x0, 0x67, 0x0, 0x1, 0xd0, 0x0, 0x0, 0x0, - 0x1, 0x90, 0x0, 0x1, 0xd0, 0x0, 0x0, 0x0, - 0x7, 0x4, 0x0, 0x1, 0xd0, 0x2, 0x90, 0x0, - 0x10, 0xb, 0x86, 0x66, 0xe6, 0x66, 0x62, 0x0, - 0x0, 0xb, 0x30, 0x1, 0xd0, 0x0, 0x0, 0x0, - 0x0, 0xb, 0x30, 0x1, 0xd0, 0x0, 0x1, 0x0, - 0x27, 0x6c, 0x76, 0x66, 0xe6, 0x66, 0x6d, 0xa0, - 0x1, 0x0, 0x0, 0x1, 0xd0, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x0, 0x1, 0xd0, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x0, 0x1, 0xd0, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x0, 0x1, 0xe0, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x0, 0x1, 0x50, 0x0, 0x0, 0x0, - - /* U+5E78 "幸" */ - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x0, 0xb, 0x40, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x0, 0xb, 0x20, 0x5, 0x0, 0x0, - 0x0, 0x6, 0x66, 0x6d, 0x76, 0x69, 0x30, 0x0, - 0x0, 0x0, 0x0, 0xb, 0x20, 0x0, 0x1, 0x0, - 0x4, 0x66, 0x66, 0x6c, 0x76, 0x66, 0xad, 0x10, - 0x0, 0x0, 0x6, 0x0, 0x5, 0x60, 0x0, 0x0, - 0x0, 0x0, 0x7, 0x90, 0xa, 0x30, 0x0, 0x0, - 0x0, 0x0, 0x0, 0x50, 0x25, 0x4, 0x80, 0x0, - 0x0, 0x57, 0x66, 0x6d, 0x76, 0x66, 0x61, 0x0, - 0x0, 0x0, 0x0, 0xb, 0x20, 0x0, 0x1, 0x0, - 0x16, 0x66, 0x66, 0x6d, 0x76, 0x66, 0x6f, 0x80, - 0x2, 0x0, 0x0, 0xb, 0x20, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x0, 0xb, 0x20, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x0, 0xc, 0x30, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x0, 0x5, 0x0, 0x0, 0x0, 0x0, - - /* U+5E7E "幾" */ - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x83, 0x4, 0xa0, 0xa, 0x30, 0x0, - 0x0, 0x2, 0xa0, 0x3, 0x90, 0x49, 0x0, 0x0, - 0x0, 0x18, 0x1, 0x72, 0xa2, 0x70, 0x9, 0x0, - 0x0, 0xc9, 0x6c, 0x61, 0xba, 0x96, 0xc7, 0x0, - 0x0, 0x10, 0x83, 0x0, 0xc0, 0x8, 0x41, 0x0, - 0x0, 0x7, 0x24, 0x50, 0xc2, 0x94, 0x2a, 0x20, - 0x0, 0x8c, 0x86, 0xc0, 0xc2, 0xc7, 0x45, 0x90, - 0x0, 0x0, 0xb2, 0x10, 0xb1, 0x1c, 0x2, 0x10, - 0x4, 0x66, 0xd6, 0x66, 0xb8, 0x69, 0x6e, 0x80, - 0x0, 0x0, 0xc0, 0x0, 0x57, 0x0, 0x81, 0x0, - 0x0, 0x4, 0xc8, 0x10, 0x1c, 0x9, 0xc3, 0x0, - 0x0, 0xa, 0x14, 0xb0, 0x9, 0xd8, 0x0, 0x31, - 0x0, 0x64, 0x0, 0x30, 0x5b, 0xc7, 0x0, 0x70, - 0x4, 0x50, 0x0, 0x58, 0x40, 0x7, 0xd9, 0xd0, - 0x2, 0x0, 0x15, 0x10, 0x0, 0x0, 0x5, 0x91, - - /* U+5E83 "広" */ - 0x0, 0x0, 0x0, 0x2, 0x80, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x0, 0xa, 0x70, 0x0, 0x10, 0x0, - 0x28, 0x66, 0x66, 0x78, 0x66, 0x7f, 0x50, 0x2, - 0xd0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x1d, - 0x0, 0x0, 0x46, 0x0, 0x0, 0x0, 0x2, 0xc0, - 0x0, 0x9, 0xb0, 0x0, 0x0, 0x0, 0x2c, 0x0, - 0x0, 0xe2, 0x0, 0x0, 0x0, 0x3, 0xb0, 0x0, - 0x69, 0x0, 0x0, 0x0, 0x0, 0x59, 0x0, 0xc, - 0x10, 0x0, 0x0, 0x0, 0x7, 0x50, 0x5, 0x60, - 0x0, 0x40, 0x0, 0x0, 0xa1, 0x0, 0xa0, 0x0, - 0x1, 0xc2, 0x0, 0xa, 0x0, 0xa2, 0x0, 0x0, - 0x5, 0xe1, 0x5, 0x30, 0x7e, 0xcc, 0xba, 0x98, - 0x7d, 0x80, 0x70, 0x2, 0x62, 0x0, 0x0, 0x0, - 0x44, 0x2, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, - - /* U+5E86 "庆" */ - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x0, 0x7, 0x60, 0x0, 0x0, 0x0, - 0x0, 0x10, 0x0, 0x0, 0xf1, 0x0, 0x5, 0x0, - 0x0, 0x98, 0x66, 0x66, 0x96, 0x66, 0x7b, 0x40, - 0x0, 0x95, 0x0, 0x0, 0xc2, 0x0, 0x0, 0x0, - 0x0, 0x95, 0x0, 0x0, 0xf0, 0x0, 0x0, 0x0, - 0x0, 0x95, 0x0, 0x0, 0xe0, 0x0, 0x1, 0x0, - 0x0, 0xa5, 0x76, 0x66, 0xe6, 0x66, 0x6c, 0x50, - 0x0, 0xa3, 0x0, 0x0, 0xd5, 0x0, 0x0, 0x0, - 0x0, 0xb2, 0x0, 0x3, 0xa7, 0x0, 0x0, 0x0, - 0x0, 0xd0, 0x0, 0x8, 0x63, 0x60, 0x0, 0x0, - 0x0, 0xc0, 0x0, 0xd, 0x10, 0xa2, 0x0, 0x0, - 0x4, 0x80, 0x0, 0x77, 0x0, 0x2d, 0x30, 0x0, - 0x9, 0x10, 0x7, 0x80, 0x0, 0x4, 0xe8, 0x10, - 0x26, 0x3, 0x73, 0x0, 0x0, 0x0, 0x3d, 0x70, - 0x20, 0x32, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - - /* U+5E95 "底" */ - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x0, 0x5, 0x80, 0x0, 0x0, 0x0, - 0x0, 0x20, 0x0, 0x0, 0xd3, 0x0, 0x6, 0x10, - 0x0, 0xb8, 0x66, 0x66, 0x76, 0x66, 0x68, 0x60, - 0x0, 0xb3, 0x0, 0x0, 0x0, 0x3, 0x70, 0x0, - 0x0, 0xb3, 0x4, 0x24, 0x7a, 0xcb, 0x93, 0x0, - 0x0, 0xb3, 0x1d, 0x32, 0x2e, 0x0, 0x0, 0x0, - 0x0, 0xb3, 0xd, 0x0, 0xe, 0x0, 0x0, 0x0, - 0x0, 0xb3, 0xe, 0x66, 0x6e, 0x76, 0x6e, 0x40, - 0x0, 0xc1, 0xd, 0x0, 0x9, 0x50, 0x0, 0x0, - 0x0, 0xd0, 0xd, 0x0, 0x4, 0xb0, 0x0, 0x0, - 0x0, 0xb0, 0xd, 0x0, 0x23, 0xd2, 0x0, 0x20, - 0x5, 0x60, 0xd, 0x49, 0x50, 0x5c, 0x0, 0x70, - 0x8, 0x0, 0x2f, 0xa3, 0xa2, 0x8, 0xd3, 0xa0, - 0x25, 0x0, 0x5, 0x0, 0x4c, 0x0, 0x6e, 0xd0, - 0x20, 0x0, 0x0, 0x0, 0x1, 0x0, 0x0, 0x50, - - /* U+5E97 "店" */ - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x0, 0x4a, 0x0, 0x0, 0x0, 0x0, - 0x12, 0x0, 0x0, 0xc3, 0x0, 0x9, 0x10, 0x3, - 0xd6, 0x66, 0x68, 0x66, 0x66, 0x85, 0x0, 0x2c, - 0x0, 0x0, 0xd4, 0x0, 0x0, 0x0, 0x2, 0xc0, - 0x0, 0xc, 0x10, 0x0, 0x0, 0x0, 0x2b, 0x0, - 0x0, 0xc6, 0x66, 0xab, 0x0, 0x3, 0xb0, 0x0, - 0xc, 0x10, 0x0, 0x0, 0x0, 0x4a, 0x0, 0x0, - 0xc1, 0x0, 0x0, 0x0, 0x5, 0x90, 0x96, 0x6d, - 0x66, 0x6b, 0x40, 0x0, 0x77, 0xd, 0x10, 0x0, - 0x0, 0xc3, 0x0, 0xa, 0x30, 0xc1, 0x0, 0x0, - 0xc, 0x20, 0x0, 0xb0, 0xc, 0x10, 0x0, 0x0, - 0xc2, 0x0, 0x54, 0x0, 0xd6, 0x66, 0x66, 0x6d, - 0x30, 0x6, 0x0, 0xd, 0x10, 0x0, 0x0, 0x92, - 0x1, 0x0, 0x0, 0x10, 0x0, 0x0, 0x0, 0x0, - - /* U+5E9C "府" */ - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x0, 0x9, 0x80, 0x0, 0x0, 0x0, - 0x0, 0x20, 0x0, 0x0, 0xe1, 0x0, 0x5, 0x40, - 0x0, 0xb7, 0x66, 0x66, 0x76, 0x66, 0x67, 0x70, - 0x0, 0xb3, 0x0, 0xb5, 0x0, 0x2, 0xa0, 0x0, - 0x0, 0xb3, 0x1, 0xe1, 0x0, 0x1, 0xb0, 0x0, - 0x0, 0xb3, 0x8, 0x60, 0x0, 0x1, 0xb0, 0x60, - 0x0, 0xb2, 0xe, 0x45, 0x76, 0x66, 0xd6, 0x72, - 0x0, 0xc2, 0x7c, 0x20, 0x0, 0x1, 0xb0, 0x0, - 0x0, 0xd3, 0x5a, 0x21, 0xa2, 0x1, 0xb0, 0x0, - 0x0, 0xc4, 0xa, 0x20, 0x4e, 0x1, 0xb0, 0x0, - 0x0, 0xa0, 0xa, 0x20, 0x6, 0x1, 0xb0, 0x0, - 0x4, 0x50, 0xa, 0x20, 0x0, 0x1, 0xb0, 0x0, - 0x8, 0x0, 0xa, 0x20, 0x0, 0x1, 0xb0, 0x0, - 0x14, 0x0, 0xb, 0x20, 0x0, 0x7c, 0x90, 0x0, - 0x10, 0x0, 0x5, 0x0, 0x0, 0x5, 0x10, 0x0, - - /* U+5EA6 "度" */ - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x0, 0x86, 0x0, 0x0, 0x0, 0x0, - 0x40, 0x0, 0x1, 0xc0, 0x0, 0x29, 0x0, 0xb, - 0x86, 0x68, 0x66, 0x67, 0x66, 0x62, 0x0, 0xa3, - 0x0, 0xd2, 0x0, 0xb4, 0x0, 0x0, 0xa, 0x66, - 0x6e, 0x66, 0x6c, 0x79, 0xc0, 0x0, 0xb3, 0x0, - 0xd0, 0x0, 0xa2, 0x0, 0x0, 0xb, 0x20, 0xd, - 0x0, 0xa, 0x20, 0x0, 0x0, 0xc1, 0x0, 0xb6, - 0x66, 0xa1, 0x0, 0x0, 0xd, 0x1, 0x66, 0x66, - 0x66, 0xb1, 0x0, 0x0, 0xc0, 0x0, 0x51, 0x0, - 0x99, 0x0, 0x0, 0x38, 0x0, 0x0, 0x80, 0x5b, - 0x0, 0x0, 0x7, 0x30, 0x0, 0x1, 0xbb, 0x0, - 0x0, 0x0, 0x80, 0x0, 0x1, 0x99, 0xc8, 0x20, - 0x0, 0x33, 0x0, 0x38, 0x82, 0x0, 0x6d, 0xeb, - 0x42, 0x2, 0x52, 0x0, 0x0, 0x0, 0x2, 0x30, - - /* U+5EA7 "座" */ - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x0, 0x84, 0x0, 0x0, 0x0, 0x0, - 0x10, 0x0, 0x2, 0xd0, 0x0, 0x26, 0x0, 0xa, - 0x86, 0x66, 0x68, 0x66, 0x68, 0x92, 0x0, 0xa4, - 0x0, 0x0, 0x61, 0x0, 0x0, 0x0, 0xa, 0x40, - 0x83, 0xb, 0x20, 0x56, 0x0, 0x0, 0xa4, 0xd, - 0x10, 0xb1, 0xb, 0x60, 0x0, 0xa, 0x32, 0xc0, - 0xb, 0x11, 0xe4, 0x0, 0x0, 0xb3, 0x83, 0xc3, - 0xb1, 0x74, 0x7b, 0x0, 0xc, 0x27, 0x5, 0x8b, - 0x28, 0x0, 0xa3, 0x0, 0xd4, 0x0, 0x1, 0xb3, - 0x2, 0x91, 0x0, 0xb, 0x3, 0x76, 0x6d, 0x66, - 0x66, 0x20, 0x4, 0x60, 0x0, 0x0, 0xb1, 0x0, - 0x0, 0x0, 0x80, 0x0, 0x0, 0xb, 0x10, 0x0, - 0x10, 0x15, 0x5, 0x66, 0x66, 0xd6, 0x66, 0x7f, - 0x61, 0x0, 0x10, 0x0, 0x0, 0x0, 0x0, 0x0, - - /* U+5EAB "庫" */ - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x0, 0x59, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x0, 0xb3, 0x0, 0x3, 0x0, 0x2, - 0xc6, 0x66, 0x67, 0x66, 0x66, 0xb5, 0x0, 0x2c, - 0x0, 0x0, 0xd, 0x10, 0x0, 0x0, 0x1, 0xb3, - 0x76, 0x66, 0xe6, 0x6a, 0x80, 0x0, 0x1b, 0x2, - 0x0, 0xd, 0x0, 0x40, 0x0, 0x2, 0xb0, 0xa7, - 0x66, 0xe6, 0x6e, 0x20, 0x0, 0x3a, 0xa, 0x20, - 0xd, 0x0, 0xd0, 0x0, 0x4, 0x80, 0xa7, 0x66, - 0xe6, 0x6e, 0x0, 0x0, 0x65, 0xa, 0x76, 0x6e, - 0x66, 0xe0, 0x0, 0xa, 0x10, 0x61, 0x0, 0xd0, - 0x4, 0x30, 0x0, 0x90, 0x76, 0x66, 0x6e, 0x66, - 0x6d, 0x70, 0x53, 0x0, 0x0, 0x0, 0xd0, 0x0, - 0x0, 0x6, 0x0, 0x0, 0x0, 0xd, 0x0, 0x0, - 0x1, 0x0, 0x0, 0x0, 0x0, 0x60, 0x0, 0x0, - - /* U+5EAD "庭" */ - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x0, 0x4, 0xa0, 0x0, 0x0, 0x0, - 0x0, 0x40, 0x0, 0x0, 0xb4, 0x0, 0x9, 0x10, - 0x0, 0xe6, 0x66, 0x66, 0x66, 0x66, 0x66, 0x30, - 0x0, 0xe0, 0x0, 0x40, 0x0, 0x2, 0x7a, 0x0, - 0x0, 0xe3, 0x78, 0xf3, 0x35, 0x8d, 0x52, 0x0, - 0x0, 0xe0, 0xb, 0x40, 0x0, 0x2b, 0x0, 0x0, - 0x0, 0xd0, 0x78, 0x0, 0x0, 0x2b, 0x2, 0x0, - 0x0, 0xd3, 0xe6, 0xb8, 0x57, 0x7d, 0x6a, 0x60, - 0x0, 0xc0, 0x0, 0xc2, 0x0, 0x2b, 0x0, 0x0, - 0x0, 0xc0, 0x61, 0xc0, 0x0, 0x2b, 0x0, 0x0, - 0x2, 0x90, 0x5c, 0x61, 0x66, 0x7d, 0x67, 0xb0, - 0x6, 0x30, 0x4e, 0x80, 0x10, 0x0, 0x0, 0x0, - 0x7, 0x2, 0xb1, 0x6c, 0x84, 0x21, 0x11, 0x21, - 0x23, 0x57, 0x0, 0x0, 0x59, 0xce, 0xff, 0xa1, - 0x11, 0x20, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - - /* U+5EB7 "康" */ - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x0, 0x2, 0xb4, 0x0, 0x0, 0x0, - 0x0, 0x12, 0x0, 0x0, 0x47, 0x0, 0x8, 0x50, - 0x0, 0x3d, 0x66, 0x66, 0xa6, 0x66, 0x66, 0x50, - 0x0, 0x2b, 0x0, 0x0, 0xb3, 0x0, 0x40, 0x0, - 0x0, 0x2b, 0x18, 0x66, 0xc7, 0x66, 0xe0, 0x0, - 0x0, 0x3a, 0x0, 0x0, 0xa2, 0x0, 0xc4, 0x60, - 0x0, 0x3b, 0x76, 0x66, 0xc7, 0x66, 0xd6, 0x50, - 0x0, 0x49, 0x16, 0x66, 0xc7, 0x66, 0xc0, 0x0, - 0x0, 0x57, 0x3, 0x0, 0xa7, 0x0, 0x56, 0x0, - 0x0, 0x75, 0x8, 0x90, 0xa4, 0x50, 0x88, 0x10, - 0x0, 0xa1, 0x0, 0x96, 0xc2, 0x97, 0x20, 0x0, - 0x0, 0xa0, 0x6, 0x91, 0xa2, 0x1c, 0x20, 0x0, - 0x5, 0x35, 0xe5, 0x11, 0xc2, 0x2, 0xea, 0x50, - 0x7, 0x0, 0x30, 0x2b, 0xd0, 0x0, 0x19, 0x30, - 0x21, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - - /* U+5EE0 "廠" */ - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x0, 0xa, 0x40, 0x0, 0x0, 0x0, - 0x0, 0x20, 0x0, 0x3, 0x90, 0x0, 0x29, 0x0, - 0x0, 0x98, 0x66, 0x66, 0x66, 0x66, 0x67, 0x30, - 0x0, 0x94, 0x0, 0x52, 0x10, 0x55, 0x0, 0x0, - 0x0, 0x93, 0x83, 0x50, 0xc3, 0x95, 0x0, 0x0, - 0x0, 0x93, 0x1a, 0x53, 0x40, 0xb3, 0x39, 0x10, - 0x0, 0xa2, 0x86, 0x97, 0xa5, 0xa2, 0x68, 0x10, - 0x0, 0xa1, 0xc0, 0x0, 0xa7, 0x70, 0x74, 0x0, - 0x0, 0xb0, 0xc2, 0xac, 0xa5, 0x52, 0x92, 0x0, - 0x0, 0xb0, 0xc2, 0x9b, 0xa2, 0x27, 0xb0, 0x0, - 0x0, 0x90, 0xc2, 0xbb, 0xa2, 0xc, 0x70, 0x0, - 0x5, 0x40, 0xc1, 0x44, 0xa2, 0x1c, 0xa0, 0x0, - 0x7, 0x0, 0xc0, 0x4, 0xc1, 0x91, 0x8a, 0x0, - 0x13, 0x0, 0x90, 0x4, 0x96, 0x10, 0x9, 0xb0, - 0x0, 0x0, 0x0, 0x0, 0x10, 0x0, 0x0, 0x0, - - /* U+5EFA "建" */ - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x0, 0x0, 0xb, 0x20, 0x0, 0x0, - 0x0, 0x0, 0x31, 0x0, 0xd, 0x0, 0x20, 0x0, - 0x5, 0x66, 0xe4, 0x36, 0x6e, 0x66, 0xe3, 0x0, - 0x0, 0x5, 0x80, 0x0, 0xd, 0x0, 0xd3, 0x20, - 0x0, 0xc, 0x3, 0x66, 0x6e, 0x66, 0xe6, 0x60, - 0x0, 0x75, 0x0, 0x0, 0xd, 0x0, 0xd0, 0x0, - 0x3, 0xd6, 0x7a, 0x46, 0x6e, 0x66, 0xa0, 0x0, - 0x0, 0x10, 0x66, 0x0, 0xd, 0x0, 0x30, 0x0, - 0x0, 0x20, 0x93, 0x46, 0x6e, 0x66, 0x70, 0x0, - 0x0, 0x60, 0xc0, 0x0, 0xd, 0x0, 0x6, 0x0, - 0x0, 0x38, 0xa4, 0x66, 0x6e, 0x66, 0x68, 0x20, - 0x0, 0xb, 0x80, 0x0, 0xd, 0x0, 0x0, 0x0, - 0x0, 0x56, 0x7c, 0x63, 0x9, 0x0, 0x0, 0x21, - 0x5, 0x40, 0x1, 0x7b, 0xde, 0xee, 0xff, 0x80, - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - - /* U+5EFF "廿" */ - 0x0, 0x0, 0x9, 0x10, 0x0, 0x81, 0x0, 0x0, - 0x0, 0x0, 0xe, 0x0, 0x0, 0xe1, 0x0, 0x0, - 0x0, 0x0, 0xd, 0x0, 0x0, 0xe0, 0x0, 0x0, - 0x0, 0x0, 0xd, 0x0, 0x0, 0xe0, 0x0, 0x0, - 0x0, 0x0, 0xd, 0x0, 0x0, 0xe0, 0x6, 0x30, - 0x6, 0x66, 0x6e, 0x66, 0x66, 0xe6, 0x67, 0x70, - 0x0, 0x0, 0xd, 0x0, 0x0, 0xe0, 0x0, 0x0, - 0x0, 0x0, 0xd, 0x0, 0x0, 0xe0, 0x0, 0x0, - 0x0, 0x0, 0xd, 0x0, 0x0, 0xe0, 0x0, 0x0, - 0x0, 0x0, 0xd, 0x0, 0x0, 0xe0, 0x0, 0x0, - 0x0, 0x0, 0xd, 0x0, 0x0, 0xe0, 0x0, 0x0, - 0x0, 0x0, 0xd, 0x0, 0x0, 0xe0, 0x0, 0x0, - 0x0, 0x0, 0xe, 0x66, 0x66, 0xe0, 0x0, 0x0, - 0x0, 0x0, 0x1d, 0x0, 0x0, 0xd0, 0x0, 0x0, - 0x0, 0x0, 0x0, 0x0, 0x0, 0x10, 0x0, 0x0, - - /* U+5F0F "式" */ - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x0, 0x1c, 0x23, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x0, 0xe0, 0x6c, 0x10, 0x0, 0x0, - 0x0, 0x0, 0xe, 0x0, 0xa4, 0x0, 0x17, 0x66, - 0x66, 0x66, 0xf6, 0x66, 0xda, 0x0, 0x10, 0x0, - 0x0, 0xd, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0xc2, 0x0, 0x0, 0x0, 0x56, 0x66, 0x6e, - 0x4a, 0x40, 0x0, 0x0, 0x1, 0x2, 0xb0, 0x0, - 0x77, 0x0, 0x0, 0x0, 0x0, 0x2b, 0x0, 0x4, - 0xb0, 0x0, 0x0, 0x0, 0x2, 0xb0, 0x0, 0xe, - 0x10, 0x0, 0x0, 0x0, 0x2b, 0x0, 0x11, 0x88, - 0x0, 0x60, 0x0, 0x3, 0xd8, 0x64, 0x1, 0xe4, - 0x8, 0x5, 0xbd, 0x94, 0x0, 0x0, 0x4, 0xe7, - 0xb0, 0x26, 0x0, 0x0, 0x0, 0x0, 0x3, 0xdf, - 0x20, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x42, - - /* U+5F15 "引" */ - 0x0, 0x0, 0x0, 0x20, 0x0, 0x91, 0x37, 0x66, - 0x68, 0xd0, 0x0, 0xe0, 0x0, 0x0, 0x3, 0xa0, - 0x0, 0xe0, 0x0, 0x0, 0x3, 0xa0, 0x0, 0xe0, - 0xc, 0x66, 0x68, 0xb0, 0x0, 0xe0, 0xd, 0x0, - 0x1, 0x30, 0x0, 0xe0, 0x3a, 0x0, 0x0, 0x0, - 0x0, 0xe0, 0xaa, 0x66, 0x66, 0xb3, 0x0, 0xe0, - 0x21, 0x0, 0x0, 0xe0, 0x0, 0xe0, 0x0, 0x0, - 0x2, 0xb0, 0x0, 0xe0, 0x0, 0x0, 0x6, 0x80, - 0x0, 0xe0, 0x0, 0x0, 0xa, 0x40, 0x0, 0xe0, - 0x0, 0x45, 0x6e, 0x0, 0x0, 0xe0, 0x0, 0x7, - 0xe4, 0x0, 0x0, 0xf0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x40, - - /* U+5F1F "弟" */ - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x3, 0x50, 0x0, 0x9, 0x50, 0x0, 0x0, 0x0, - 0xb7, 0x0, 0x1c, 0x10, 0x0, 0x0, 0x0, 0x26, - 0x0, 0x61, 0x3, 0x0, 0x2, 0x76, 0x66, 0x7b, - 0x66, 0x6d, 0x50, 0x0, 0x0, 0x0, 0x2b, 0x0, - 0xc, 0x20, 0x0, 0x41, 0x0, 0x2b, 0x0, 0xc, - 0x20, 0x0, 0xa9, 0x66, 0x7d, 0x66, 0x6c, 0x10, - 0x0, 0xe0, 0x0, 0x2b, 0x0, 0x0, 0x0, 0x6, - 0xd6, 0x66, 0xad, 0x66, 0x66, 0xc4, 0x0, 0x10, - 0x8, 0xbb, 0x0, 0x0, 0xd1, 0x0, 0x0, 0x5b, - 0x2b, 0x0, 0x0, 0xe0, 0x0, 0x5, 0x90, 0x2b, - 0x0, 0x2, 0xc0, 0x0, 0x76, 0x0, 0x2b, 0x4, - 0xbd, 0x70, 0x36, 0x10, 0x0, 0x3c, 0x0, 0x26, - 0x0, 0x0, 0x0, 0x0, 0x13, 0x0, 0x0, 0x0, - - /* U+5F31 "弱" */ - 0x0, 0x0, 0x0, 0x60, 0x23, 0x33, 0x39, 0x0, - 0x17, 0x66, 0x6e, 0x13, 0x43, 0x33, 0xd0, 0x0, - 0x0, 0x0, 0xd0, 0x0, 0x0, 0xd, 0x0, 0x6, - 0x66, 0x6e, 0x0, 0xb5, 0x55, 0xd0, 0x0, 0xa2, - 0x0, 0x70, 0x2b, 0x0, 0x4, 0x0, 0xc, 0x0, - 0x0, 0x5, 0x80, 0x0, 0x0, 0x2, 0xe6, 0x66, - 0xd2, 0xa9, 0x66, 0x6c, 0x50, 0x3, 0x0, 0xe, - 0x1, 0x30, 0x0, 0xb2, 0x0, 0xc, 0x20, 0xd0, - 0x3, 0xc0, 0xb, 0x20, 0x0, 0x65, 0xd, 0x0, - 0xa, 0x20, 0xb2, 0x0, 0x0, 0x65, 0xd0, 0x0, - 0x27, 0x4c, 0x20, 0x39, 0x91, 0x1b, 0x5, 0xb7, - 0x0, 0xd1, 0xb, 0x50, 0x4, 0x90, 0xa2, 0x10, - 0xe, 0x0, 0x0, 0x4b, 0xe3, 0x0, 0x1, 0x9f, - 0x90, 0x0, 0x0, 0x23, 0x0, 0x0, 0x0, 0x40, - 0x0, - - /* U+5F35 "張" */ - 0x0, 0x0, 0x3, 0x3, 0x0, 0x0, 0x28, 0x0, - 0x4, 0x66, 0x6e, 0x1a, 0x76, 0x66, 0x66, 0x10, - 0x0, 0x0, 0xd, 0xa, 0x30, 0x0, 0x52, 0x0, - 0x0, 0x0, 0xd, 0xa, 0x76, 0x66, 0x64, 0x0, - 0x5, 0x86, 0x6e, 0xa, 0x30, 0x0, 0x34, 0x0, - 0x7, 0x60, 0x4, 0xa, 0x76, 0x66, 0x65, 0x0, - 0x8, 0x40, 0x0, 0xa, 0x30, 0x0, 0x4, 0x20, - 0xc, 0x20, 0x5, 0x7d, 0x69, 0x66, 0x67, 0x60, - 0x8, 0x66, 0x6d, 0x3d, 0x4, 0x20, 0x9, 0x0, - 0x0, 0x0, 0xd, 0xd, 0x0, 0x81, 0xa6, 0x10, - 0x0, 0x0, 0xc, 0xd, 0x0, 0x78, 0x0, 0x0, - 0x0, 0x0, 0x39, 0xd, 0x0, 0xc, 0x20, 0x0, - 0x0, 0x20, 0x85, 0xd, 0x48, 0x14, 0xe5, 0x0, - 0x0, 0x5e, 0xe0, 0xe, 0xa0, 0x0, 0x5f, 0x90, - 0x0, 0x4, 0x10, 0x3, 0x0, 0x0, 0x1, 0x0, - - /* U+5F37 "強" */ - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x4, 0x0, 0x5, 0xc0, 0x0, 0x0, - 0x6, 0x66, 0x6e, 0x20, 0xc, 0x20, 0x0, 0x0, - 0x0, 0x0, 0xd, 0x0, 0x82, 0x0, 0x31, 0x0, - 0x0, 0x0, 0xd, 0x18, 0x20, 0x12, 0x3d, 0x60, - 0x6, 0x86, 0x6e, 0x2e, 0xb8, 0xa4, 0x22, 0xe0, - 0x8, 0x50, 0x3, 0x0, 0x0, 0xd1, 0x0, 0x10, - 0x9, 0x30, 0x0, 0x8, 0x66, 0xe6, 0x6a, 0x20, - 0xd, 0x10, 0x5, 0xd, 0x0, 0xd0, 0xd, 0x0, - 0x7, 0x66, 0x6d, 0x4d, 0x0, 0xd0, 0xd, 0x0, - 0x0, 0x0, 0xd, 0xd, 0x66, 0xe6, 0x6e, 0x0, - 0x0, 0x0, 0x1d, 0x8, 0x0, 0xd0, 0x5, 0x0, - 0x0, 0x0, 0x5a, 0x0, 0x0, 0xd0, 0x7, 0x0, - 0x0, 0x42, 0xc4, 0x13, 0x45, 0xe7, 0x68, 0xb0, - 0x0, 0x2e, 0xa0, 0x1d, 0x95, 0x30, 0x0, 0xc0, - 0x0, 0x2, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - - /* U+5F53 "当" */ - 0x0, 0x0, 0x0, 0x95, 0x0, 0x0, 0x0, 0x2, - 0x30, 0x0, 0xb3, 0x0, 0x66, 0x0, 0x0, 0x99, - 0x0, 0xb2, 0x1, 0xe7, 0x0, 0x0, 0xd, 0x60, - 0xb2, 0x9, 0x40, 0x0, 0x0, 0x3, 0x20, 0xb2, - 0x42, 0x0, 0x0, 0x5, 0x66, 0x66, 0xd7, 0x66, - 0x66, 0xc2, 0x1, 0x0, 0x0, 0x0, 0x0, 0x1, - 0xe0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x1, 0xd0, - 0x0, 0x0, 0x0, 0x0, 0x0, 0x1, 0xd0, 0x1, - 0x86, 0x66, 0x66, 0x66, 0x66, 0xd0, 0x0, 0x0, - 0x0, 0x0, 0x0, 0x1, 0xd0, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x1, 0xd0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x1, 0xe0, 0x28, 0x66, 0x66, 0x66, 0x66, - 0x66, 0xe0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x50, - - /* U+5F62 "形" */ - 0x0, 0x0, 0x0, 0x0, 0x20, 0x0, 0x13, 0x0, - 0x4, 0x68, 0x76, 0x68, 0xa8, 0x0, 0xab, 0x0, - 0x0, 0x9, 0x40, 0x2a, 0x0, 0x5, 0xa0, 0x0, - 0x0, 0x9, 0x40, 0x2a, 0x0, 0x29, 0x0, 0x0, - 0x0, 0x9, 0x40, 0x2a, 0x2, 0x50, 0x2, 0x0, - 0x0, 0x9, 0x40, 0x2a, 0x46, 0x0, 0x2e, 0x40, - 0x6, 0x6c, 0x86, 0x7c, 0x65, 0x1, 0xd6, 0x0, - 0x0, 0xb, 0x20, 0x2a, 0x0, 0x1b, 0x30, 0x0, - 0x0, 0xc, 0x10, 0x2a, 0x2, 0x81, 0x0, 0x0, - 0x0, 0xc, 0x0, 0x2a, 0x3, 0x0, 0x7, 0xc0, - 0x0, 0x48, 0x0, 0x2a, 0x0, 0x0, 0x5d, 0x30, - 0x0, 0xa1, 0x0, 0x3a, 0x0, 0x6, 0xb1, 0x0, - 0x3, 0x60, 0x0, 0x3a, 0x0, 0x87, 0x0, 0x0, - 0x6, 0x0, 0x0, 0x25, 0x38, 0x20, 0x0, 0x0, - 0x10, 0x0, 0x0, 0x0, 0x20, 0x0, 0x0, 0x0, - - /* U+5F71 "影" */ - 0x0, 0x30, 0x0, 0x3, 0x10, 0x0, 0x21, 0x0, - 0x0, 0xe6, 0x66, 0x6b, 0x60, 0x0, 0xb9, 0x0, - 0x0, 0xd6, 0x66, 0x6b, 0x30, 0x7, 0x80, 0x0, - 0x0, 0xd0, 0x0, 0x9, 0x30, 0x46, 0x0, 0x0, - 0x0, 0xd6, 0x88, 0x6b, 0x33, 0x40, 0x1, 0x0, - 0x1, 0x11, 0x1c, 0x11, 0x80, 0x0, 0x1e, 0x50, - 0x6, 0x65, 0x55, 0x57, 0x52, 0x0, 0xb6, 0x0, - 0x0, 0xd6, 0x66, 0x6d, 0x30, 0x9, 0x40, 0x0, - 0x0, 0xd1, 0x0, 0xb, 0x11, 0x82, 0x0, 0x10, - 0x0, 0xd6, 0x68, 0x6d, 0x23, 0x0, 0x7, 0xd0, - 0x0, 0x43, 0xd, 0x13, 0x0, 0x0, 0x5c, 0x20, - 0x0, 0x3d, 0x1d, 0x4b, 0x20, 0x6, 0xa0, 0x0, - 0x1, 0xa1, 0xc, 0x6, 0x80, 0x97, 0x0, 0x0, - 0x6, 0x3, 0xca, 0x0, 0x67, 0x10, 0x0, 0x0, - 0x0, 0x0, 0x10, 0x2, 0x10, 0x0, 0x0, 0x0, - - /* U+5F79 "役" */ - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x2, 0xe2, 0x3, 0x76, 0x6a, 0x0, 0x0, - 0x0, 0xb, 0x60, 0x3, 0x90, 0xd, 0x0, 0x0, - 0x0, 0x77, 0x0, 0x4, 0x90, 0xd, 0x0, 0x0, - 0x4, 0x60, 0x52, 0x6, 0x60, 0xd, 0x0, 0x0, - 0x13, 0x1, 0xe6, 0xb, 0x10, 0xe, 0x21, 0x30, - 0x0, 0xa, 0x60, 0x83, 0x0, 0x5, 0x88, 0x80, - 0x0, 0x5f, 0x15, 0x25, 0x66, 0x66, 0xb0, 0x0, - 0x3, 0x8c, 0x10, 0x1, 0x40, 0x6, 0x90, 0x0, - 0x26, 0xc, 0x10, 0x0, 0x70, 0xc, 0x20, 0x0, - 0x10, 0xc, 0x10, 0x0, 0x53, 0x4a, 0x0, 0x0, - 0x0, 0xc, 0x10, 0x0, 0xa, 0xc1, 0x0, 0x0, - 0x0, 0xc, 0x10, 0x0, 0xc, 0xc0, 0x0, 0x0, - 0x0, 0xc, 0x10, 0x3, 0xb3, 0x4d, 0x60, 0x0, - 0x0, 0xc, 0x12, 0x76, 0x0, 0x2, 0xbf, 0x80, - 0x0, 0x4, 0x12, 0x0, 0x0, 0x0, 0x2, 0x0, - - /* U+5F7C "彼" */ - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x85, 0x0, 0x0, 0x1e, 0x0, 0x0, 0x0, - 0x1e, 0x20, 0x0, 0x0, 0xc0, 0x0, 0x0, 0x8, - 0x50, 0x7, 0x66, 0x6d, 0x66, 0xa7, 0x2, 0x70, - 0x91, 0x84, 0x0, 0xc0, 0xb, 0x30, 0x60, 0x3d, - 0x18, 0x40, 0xc, 0x3, 0x10, 0x0, 0xc, 0x40, - 0x84, 0x0, 0xc0, 0x0, 0x0, 0x5, 0xf0, 0x8, - 0x86, 0x6c, 0x69, 0x80, 0x1, 0xad, 0x0, 0x93, - 0x60, 0x0, 0xa3, 0x0, 0x70, 0xd0, 0xa, 0x22, - 0x60, 0x1c, 0x0, 0x10, 0xd, 0x0, 0xc0, 0xa, - 0x8, 0x40, 0x0, 0x0, 0xd0, 0xb, 0x0, 0x49, - 0xa0, 0x0, 0x0, 0xd, 0x4, 0x60, 0x2, 0xf5, - 0x0, 0x0, 0x0, 0xd0, 0x80, 0x6, 0x92, 0xc9, - 0x20, 0x0, 0xd, 0x33, 0x47, 0x20, 0x0, 0x9f, - 0x90, 0x0, 0x41, 0x20, 0x0, 0x0, 0x0, 0x10, - - /* U+5F80 "往" */ - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x1c, 0x10, 0x4, 0x20, 0x0, 0x0, 0x0, - 0x9, 0x80, 0x0, 0xc, 0x40, 0x0, 0x0, 0x4, - 0x90, 0x0, 0x0, 0x68, 0x0, 0x0, 0x1, 0x80, - 0x11, 0x66, 0x66, 0x66, 0x9c, 0x0, 0x50, 0xe, - 0x42, 0x0, 0xe0, 0x0, 0x0, 0x0, 0x8, 0xa0, - 0x0, 0xe, 0x0, 0x0, 0x0, 0x2, 0xf1, 0x0, - 0x0, 0xe0, 0x0, 0x0, 0x0, 0xbe, 0x10, 0x0, - 0xe, 0x0, 0x52, 0x0, 0x73, 0xc1, 0x6, 0x76, - 0xe6, 0x66, 0x40, 0x32, 0xc, 0x10, 0x0, 0xe, - 0x0, 0x0, 0x0, 0x0, 0xc1, 0x0, 0x0, 0xe0, - 0x0, 0x0, 0x0, 0xc, 0x10, 0x0, 0xe, 0x0, - 0x0, 0x0, 0x0, 0xc1, 0x0, 0x0, 0xe0, 0x0, - 0x61, 0x0, 0xd, 0x28, 0x66, 0x68, 0x66, 0x68, - 0x60, 0x0, 0x60, 0x0, 0x0, 0x0, 0x0, 0x0, - - /* U+5F85 "待" */ - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x2c, 0x0, 0x0, 0xc2, 0x0, 0x0, 0x0, - 0x9, 0x70, 0x0, 0xd, 0x0, 0x0, 0x0, 0x3, - 0xa0, 0x6, 0x66, 0xe6, 0x6c, 0x20, 0x0, 0x90, - 0x72, 0x0, 0xd, 0x0, 0x0, 0x0, 0x60, 0x1e, - 0x30, 0x0, 0xd0, 0x0, 0x10, 0x0, 0x9, 0x67, - 0x66, 0x6c, 0x66, 0x6b, 0x50, 0x3, 0xf1, 0x0, - 0x0, 0x0, 0x92, 0x0, 0x0, 0xad, 0x10, 0x0, - 0x0, 0xd, 0x7, 0x10, 0x71, 0xc1, 0x36, 0x66, - 0x66, 0xe6, 0x63, 0x10, 0xc, 0x10, 0x7, 0x30, - 0xd, 0x0, 0x0, 0x0, 0xc1, 0x0, 0x1e, 0x10, - 0xd0, 0x0, 0x0, 0xc, 0x10, 0x0, 0x70, 0xd, - 0x0, 0x0, 0x0, 0xd1, 0x0, 0x0, 0x0, 0xd0, - 0x0, 0x0, 0xd, 0x10, 0x0, 0x17, 0xbd, 0x0, - 0x0, 0x0, 0x40, 0x0, 0x0, 0x4, 0x20, 0x0, - - /* U+5F88 "很" */ - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x59, 0x0, 0x10, 0x0, 0x2, 0x0, 0x0, - 0xc, 0x40, 0xd, 0x66, 0x66, 0xe3, 0x0, 0x5, - 0x70, 0x0, 0xd0, 0x0, 0xd, 0x0, 0x1, 0x80, - 0x51, 0xd, 0x0, 0x0, 0xd0, 0x0, 0x50, 0xe, - 0x30, 0xd6, 0x66, 0x6e, 0x0, 0x0, 0x7, 0x70, - 0xd, 0x0, 0x0, 0xd0, 0x0, 0x1, 0xf0, 0x0, - 0xd6, 0x66, 0x6e, 0x0, 0x0, 0x9e, 0x0, 0xd, - 0x6, 0x0, 0x53, 0x0, 0x62, 0xd0, 0x0, 0xd0, - 0x70, 0x1c, 0x70, 0x22, 0xd, 0x0, 0xd, 0x2, - 0x87, 0x10, 0x0, 0x0, 0xd0, 0x0, 0xd0, 0x9, - 0x20, 0x0, 0x0, 0xd, 0x0, 0xd, 0x0, 0x3c, - 0x40, 0x0, 0x0, 0xd0, 0x0, 0xe9, 0x70, 0x2e, - 0xa4, 0x0, 0xd, 0x0, 0xd, 0x30, 0x0, 0x8, - 0x30, 0x0, 0x30, 0x0, 0x0, 0x0, 0x0, 0x0, - - /* U+5F8B "律" */ - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0xd, 0x30, 0x0, 0x1d, 0x10, 0x0, 0x0, - 0x0, 0x69, 0x0, 0x0, 0xd, 0x0, 0x10, 0x0, - 0x0, 0xb0, 0x0, 0x86, 0x6e, 0x66, 0xd4, 0x0, - 0x7, 0x12, 0xc1, 0x0, 0xd, 0x0, 0xc2, 0x10, - 0x1, 0x8, 0x96, 0x76, 0x6e, 0x66, 0xda, 0x90, - 0x0, 0x1e, 0x0, 0x0, 0xd, 0x0, 0xc1, 0x0, - 0x0, 0x9e, 0x0, 0x76, 0x6e, 0x66, 0xd1, 0x0, - 0x4, 0x6e, 0x0, 0x0, 0xd, 0x0, 0x20, 0x0, - 0x15, 0xe, 0x2, 0x76, 0x6e, 0x66, 0xb7, 0x0, - 0x0, 0xe, 0x0, 0x0, 0xd, 0x0, 0x0, 0x0, - 0x0, 0xe, 0x26, 0x66, 0x6e, 0x66, 0x6d, 0x60, - 0x0, 0xe, 0x1, 0x0, 0xd, 0x0, 0x0, 0x0, - 0x0, 0xe, 0x0, 0x0, 0xd, 0x0, 0x0, 0x0, - 0x0, 0xe, 0x0, 0x0, 0xe, 0x0, 0x0, 0x0, - 0x0, 0x3, 0x0, 0x0, 0x4, 0x0, 0x0, 0x0, - - /* U+5F8C "後" */ - 0x0, 0x1, 0xb1, 0x0, 0xb, 0x30, 0x0, 0x0, - 0x0, 0x9, 0x90, 0x0, 0x79, 0x1, 0x50, 0x0, - 0x0, 0x49, 0x0, 0x7, 0x70, 0xc, 0xa0, 0x0, - 0x2, 0x80, 0x52, 0x8e, 0x76, 0xc5, 0x0, 0x0, - 0x15, 0x1, 0xe5, 0x11, 0x3a, 0x22, 0x40, 0x0, - 0x0, 0xa, 0x60, 0x7, 0x70, 0x0, 0x97, 0x0, - 0x0, 0x5f, 0x10, 0xdd, 0xc7, 0x65, 0x4e, 0x0, - 0x2, 0x9d, 0x10, 0x11, 0xe3, 0x0, 0x2, 0x0, - 0x26, 0xc, 0x10, 0x9, 0xa6, 0x66, 0xd1, 0x0, - 0x0, 0xc, 0x10, 0x47, 0x60, 0x8, 0x90, 0x0, - 0x0, 0xc, 0x12, 0x70, 0x44, 0x3c, 0x0, 0x0, - 0x0, 0xc, 0x13, 0x0, 0xa, 0xd2, 0x0, 0x0, - 0x0, 0xc, 0x10, 0x0, 0x4b, 0xa7, 0x10, 0x0, - 0x0, 0xd, 0x10, 0x49, 0x60, 0x6, 0xdc, 0x80, - 0x0, 0x6, 0x14, 0x20, 0x0, 0x0, 0x4, 0x10, - - /* U+5F92 "徒" */ - 0x0, 0x5, 0x80, 0x0, 0x9, 0x50, 0x0, 0x0, - 0x0, 0xc, 0x40, 0x0, 0xa, 0x30, 0x0, 0x0, - 0x0, 0x67, 0x0, 0x0, 0xa, 0x30, 0x36, 0x0, - 0x2, 0x90, 0x61, 0x66, 0x6c, 0x86, 0x65, 0x0, - 0x7, 0x2, 0xf3, 0x0, 0xa, 0x30, 0x0, 0x0, - 0x0, 0x9, 0x60, 0x0, 0xa, 0x30, 0x6, 0x30, - 0x0, 0x3f, 0x16, 0x66, 0x6c, 0x86, 0x66, 0x50, - 0x0, 0xad, 0x10, 0x32, 0xa, 0x50, 0x0, 0x0, - 0x7, 0x1c, 0x10, 0x79, 0xa, 0x30, 0x27, 0x0, - 0x21, 0xc, 0x10, 0x95, 0xa, 0x86, 0x66, 0x10, - 0x0, 0xc, 0x10, 0xc6, 0xa, 0x30, 0x0, 0x0, - 0x0, 0xc, 0x11, 0xa3, 0x6a, 0x30, 0x0, 0x0, - 0x0, 0xc, 0x18, 0x20, 0x3d, 0x83, 0x10, 0x10, - 0x0, 0xd, 0x44, 0x0, 0x0, 0x5a, 0xdf, 0x90, - 0x0, 0x1, 0x10, 0x0, 0x0, 0x0, 0x0, 0x0, - - /* U+5F93 "従" */ - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x1, 0xc3, 0x4, 0x0, 0x0, 0x38, 0x0, - 0x0, 0x8, 0xb1, 0x5, 0xb0, 0x0, 0x99, 0x0, - 0x0, 0x3a, 0x0, 0x0, 0xb7, 0x1, 0xa0, 0x0, - 0x1, 0xa0, 0x21, 0x0, 0x25, 0x6, 0x0, 0x0, - 0x6, 0x0, 0xba, 0x36, 0x66, 0x67, 0x6c, 0x80, - 0x0, 0x5, 0xb0, 0x1, 0x0, 0xe0, 0x0, 0x0, - 0x0, 0x1e, 0x20, 0x4, 0x0, 0xe0, 0x0, 0x0, - 0x0, 0xae, 0x10, 0x1f, 0x20, 0xe0, 0x2, 0x0, - 0x7, 0x1c, 0x10, 0x1e, 0x0, 0xe6, 0x6a, 0x10, - 0x20, 0xc, 0x10, 0x2c, 0x0, 0xe0, 0x0, 0x0, - 0x0, 0xc, 0x10, 0x5c, 0x20, 0xe0, 0x0, 0x0, - 0x0, 0xc, 0x10, 0xa1, 0x93, 0xe0, 0x0, 0x0, - 0x0, 0xd, 0x12, 0x70, 0xa, 0xe3, 0x0, 0x0, - 0x0, 0xd, 0x16, 0x0, 0x0, 0x5c, 0xec, 0xa1, - 0x0, 0x3, 0x20, 0x0, 0x0, 0x0, 0x25, 0x20, - - /* U+5F97 "得" */ - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, 0xa5, 0x3, 0x0, 0x0, 0x22, 0x0, - 0x0, 0x5, 0xd2, 0xe, 0x66, 0x66, 0xa9, 0x0, - 0x0, 0x3b, 0x0, 0xd, 0x0, 0x0, 0x76, 0x0, - 0x3, 0x80, 0x1a, 0x1d, 0x66, 0x66, 0xa6, 0x0, - 0x4, 0x0, 0x8c, 0x1d, 0x0, 0x0, 0x77, 0x0, - 0x0, 0x3, 0xd1, 0xe, 0x66, 0x66, 0xa7, 0x0, - 0x0, 0x1e, 0x20, 0x4, 0x0, 0x0, 0x25, 0x10, - 0x0, 0xae, 0x10, 0x76, 0x66, 0x67, 0xc6, 0x40, - 0x7, 0x1c, 0x10, 0x0, 0x0, 0x3, 0xa0, 0x50, - 0x10, 0xc, 0x16, 0x77, 0x66, 0x68, 0xc6, 0x71, - 0x0, 0xc, 0x10, 0x8, 0x40, 0x3, 0xa0, 0x0, - 0x0, 0xc, 0x10, 0x1, 0xe0, 0x3, 0xa0, 0x0, - 0x0, 0xd, 0x10, 0x0, 0x40, 0x3, 0xa0, 0x0, - 0x0, 0xd, 0x10, 0x0, 0x2, 0x9d, 0x80, 0x0, - 0x0, 0x5, 0x0, 0x0, 0x0, 0x5, 0x0, 0x0, - - /* U+5F9E "從" */ - 0x0, 0x0, 0xa1, 0x5, 0x50, 0x1, 0x70, 0x0, - 0x0, 0x7, 0xc1, 0x9, 0x80, 0x3, 0xe1, 0x0, - 0x0, 0x2b, 0x0, 0xc, 0x20, 0x8, 0x60, 0x0, - 0x0, 0x90, 0x11, 0x1c, 0xa5, 0xc, 0x75, 0x0, - 0x5, 0x0, 0x9b, 0x64, 0x1e, 0x46, 0xc, 0x50, - 0x0, 0x3, 0xc1, 0x70, 0x1, 0x60, 0x2, 0x30, - 0x0, 0xd, 0x23, 0x0, 0x1, 0x60, 0x0, 0x0, - 0x0, 0xae, 0x10, 0x6, 0x10, 0xe0, 0x0, 0x0, - 0x7, 0x1d, 0x10, 0xf, 0x10, 0xd0, 0x24, 0x0, - 0x10, 0xd, 0x10, 0xd, 0x0, 0xe6, 0x65, 0x0, - 0x0, 0xd, 0x10, 0x2b, 0x0, 0xd0, 0x0, 0x0, - 0x0, 0xd, 0x10, 0x69, 0x81, 0xd0, 0x0, 0x0, - 0x0, 0xd, 0x10, 0xa0, 0x1a, 0xe3, 0x0, 0x0, - 0x0, 0xd, 0x16, 0x20, 0x0, 0x4b, 0xec, 0xa2, - 0x0, 0x5, 0x11, 0x0, 0x0, 0x0, 0x14, 0x30, - - /* U+5FA1 "御" */ - 0x0, 0x2, 0xa0, 0xc, 0x0, 0x0, 0x0, 0x0, - 0x0, 0xb, 0x70, 0x3a, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x58, 0x0, 0x78, 0x6b, 0x5b, 0x66, 0xd0, - 0x3, 0x70, 0x51, 0x81, 0xa0, 0xd, 0x1, 0xa0, - 0x4, 0x1, 0xe6, 0x41, 0xa0, 0xd, 0x1, 0xa0, - 0x0, 0x9, 0x61, 0x1, 0xa3, 0x4d, 0x1, 0xa0, - 0x0, 0x4e, 0x4, 0x66, 0xc6, 0x5d, 0x1, 0xa0, - 0x1, 0x8d, 0x1, 0x51, 0xa0, 0xd, 0x1, 0xa0, - 0x6, 0xd, 0x1, 0xb1, 0xc8, 0x6d, 0x1, 0xa0, - 0x0, 0xd, 0x1, 0xa1, 0xa0, 0xd, 0x1, 0xa0, - 0x0, 0xd, 0x1, 0xa1, 0xa0, 0xd, 0x1, 0xa0, - 0x0, 0xd, 0x1, 0xa4, 0xc5, 0x3d, 0x2b, 0x70, - 0x0, 0xd, 0xa, 0xd6, 0x0, 0xd, 0x1, 0x0, - 0x0, 0xd, 0x2, 0x0, 0x0, 0xd, 0x0, 0x0, - 0x0, 0x3, 0x0, 0x0, 0x0, 0x4, 0x0, 0x0, - - /* U+5FA9 "復" */ - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x1, 0xb1, 0x6, 0xa0, 0x0, 0x0, 0x0, - 0x0, 0xa, 0x90, 0xd, 0x30, 0x0, 0x6, 0x10, - 0x0, 0x49, 0x0, 0x59, 0x66, 0x66, 0x66, 0x40, - 0x3, 0x90, 0x1, 0x77, 0x66, 0x66, 0x6a, 0x10, - 0x16, 0x0, 0xc5, 0xc, 0x10, 0x0, 0xd, 0x0, - 0x0, 0x6, 0xb0, 0xb, 0x66, 0x66, 0x6d, 0x0, - 0x0, 0x1f, 0x10, 0xb, 0x10, 0x0, 0xd, 0x0, - 0x0, 0xae, 0x0, 0xc, 0x9a, 0x66, 0x6c, 0x0, - 0x7, 0x2d, 0x0, 0x0, 0xb2, 0x0, 0x12, 0x0, - 0x10, 0xd, 0x0, 0x7, 0xb6, 0x66, 0xcb, 0x0, - 0x0, 0xd, 0x0, 0x45, 0x16, 0x5, 0xc0, 0x0, - 0x0, 0xd, 0x3, 0x30, 0x5, 0xac, 0x0, 0x0, - 0x0, 0xd, 0x0, 0x0, 0x8, 0xcb, 0x20, 0x0, - 0x0, 0xd, 0x0, 0x16, 0x72, 0x4, 0xeb, 0x80, - 0x0, 0x4, 0x2, 0x30, 0x0, 0x0, 0x5, 0x20, - - /* U+5FC3 "心" */ - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x1, 0xa2, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x4, 0xf3, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x60, 0xc, 0x90, 0x0, 0x0, 0x0, 0x0, - 0xe, 0x30, 0x43, 0x0, 0x0, 0x0, 0x0, 0x20, - 0xe1, 0x0, 0x0, 0x4, 0x0, 0x0, 0x35, 0xe, - 0x10, 0x0, 0x0, 0x58, 0x0, 0x8, 0x50, 0xe1, - 0x0, 0x0, 0x0, 0xd6, 0x2, 0xf3, 0xe, 0x10, - 0x0, 0x2, 0x8, 0xc0, 0xac, 0x0, 0xe1, 0x0, - 0x0, 0x60, 0x37, 0x0, 0x0, 0xe, 0x10, 0x0, - 0x8, 0x0, 0x0, 0x0, 0x0, 0xd2, 0x0, 0x0, - 0xc4, 0x0, 0x0, 0x0, 0x9, 0xdb, 0xbb, 0xcf, - 0x70, 0x0, 0x0, 0x0, 0x1, 0x11, 0x11, 0x0, - 0x0, - - /* U+5FC5 "必" */ - 0x0, 0x0, 0x0, 0x40, 0x0, 0x1, 0x0, 0x0, - 0x0, 0x0, 0x4, 0x90, 0x0, 0xc6, 0x0, 0x0, - 0x0, 0x3, 0x9, 0x90, 0x1e, 0x0, 0x0, 0x0, - 0x0, 0xf1, 0x1b, 0x7, 0x80, 0x0, 0x0, 0x0, - 0xd, 0x0, 0x0, 0xd1, 0x0, 0x0, 0x4, 0x0, - 0xd0, 0x0, 0x69, 0x5, 0x0, 0x0, 0x71, 0xd, - 0x0, 0xd, 0x10, 0x39, 0x0, 0xc, 0x0, 0xd0, - 0x8, 0x70, 0x0, 0xc5, 0x6, 0xe0, 0xd, 0x3, - 0xc0, 0x0, 0x6, 0xa0, 0x33, 0x0, 0xd1, 0xc2, - 0x0, 0x50, 0x12, 0x0, 0x0, 0xe, 0xb3, 0x0, - 0x6, 0x10, 0x0, 0x0, 0x4, 0xf2, 0x0, 0x0, - 0x97, 0x0, 0x0, 0x58, 0x5b, 0xee, 0xee, 0xee, - 0x60, 0x0, 0x41, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, - - /* U+5FD8 "忘" */ - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x4, 0x80, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, 0xb, 0x90, 0x0, 0x3, 0x0, 0x66, - 0x66, 0x66, 0x9a, 0x66, 0x68, 0xe5, 0x1, 0x0, - 0xc1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xc, - 0x10, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xc1, - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xc, 0x10, - 0x0, 0x0, 0x9, 0x10, 0x0, 0x1, 0xc6, 0x67, - 0x66, 0x66, 0x63, 0x0, 0x0, 0x0, 0x0, 0x88, - 0x0, 0x0, 0x0, 0x0, 0x0, 0x5a, 0x0, 0xd5, - 0x0, 0x40, 0x0, 0x6, 0x14, 0x90, 0x5, 0x20, - 0x13, 0xc2, 0x0, 0xd0, 0x49, 0x0, 0x0, 0x6, - 0x8, 0xb0, 0x9c, 0x4, 0xa0, 0x0, 0x0, 0xc0, - 0x16, 0x0, 0x0, 0x1d, 0xcc, 0xcc, 0xdc, 0x10, - 0x0, - - /* U+5FD9 "忙" */ - 0x0, 0xa, 0x10, 0x0, 0x14, 0x0, 0x0, 0x0, - 0x0, 0xe, 0x0, 0x0, 0xa, 0x70, 0x0, 0x0, - 0x0, 0xe, 0x0, 0x0, 0x4, 0xc0, 0x0, 0x0, - 0x0, 0xe, 0x0, 0x0, 0x0, 0x20, 0x4, 0x70, - 0x1, 0xe, 0xa8, 0x6e, 0x66, 0x66, 0x66, 0x61, - 0x6, 0x2e, 0x4b, 0xe, 0x0, 0x0, 0x0, 0x0, - 0xb, 0x3e, 0x2, 0xe, 0x0, 0x0, 0x0, 0x0, - 0x1a, 0xe, 0x0, 0xe, 0x0, 0x0, 0x0, 0x0, - 0x0, 0xe, 0x0, 0xe, 0x0, 0x0, 0x0, 0x0, - 0x0, 0xe, 0x0, 0xe, 0x0, 0x0, 0x0, 0x0, - 0x0, 0xe, 0x0, 0xe, 0x0, 0x0, 0x0, 0x0, - 0x0, 0xe, 0x0, 0xe, 0x0, 0x0, 0x0, 0x0, - 0x0, 0xe, 0x0, 0xe, 0x0, 0x0, 0x6, 0x10, - 0x0, 0xe, 0x0, 0x2a, 0x66, 0x66, 0x67, 0x50, - 0x0, 0x4, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - - /* U+5FEB "快" */ - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0xe, 0x20, 0x0, 0x2c, 0x0, 0x0, 0x0, - 0x0, 0xe, 0x0, 0x0, 0x2c, 0x0, 0x0, 0x0, - 0x0, 0xe, 0x0, 0x0, 0x1c, 0x0, 0x51, 0x0, - 0x0, 0xe, 0x40, 0x66, 0x6d, 0x66, 0xd5, 0x0, - 0x2, 0x2e, 0x6b, 0x0, 0x1c, 0x0, 0xc1, 0x0, - 0x7, 0x4e, 0xc, 0x0, 0x1b, 0x0, 0xc1, 0x0, - 0xe, 0x2e, 0x0, 0x0, 0x2b, 0x0, 0xc1, 0x0, - 0x2, 0xe, 0x5, 0x66, 0x8c, 0x66, 0xdb, 0xc1, - 0x0, 0xe, 0x1, 0x0, 0x77, 0x50, 0x0, 0x0, - 0x0, 0xe, 0x0, 0x0, 0xb2, 0x70, 0x0, 0x0, - 0x0, 0xe, 0x0, 0x3, 0xb0, 0x37, 0x0, 0x0, - 0x0, 0xe, 0x0, 0xb, 0x20, 0xb, 0x40, 0x0, - 0x0, 0xe, 0x0, 0x94, 0x0, 0x2, 0xe7, 0x0, - 0x0, 0xf, 0x7, 0x30, 0x0, 0x0, 0x4f, 0xb1, - 0x0, 0x4, 0x30, 0x0, 0x0, 0x0, 0x2, 0x0, - - /* U+5FF5 "念" */ - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x0, 0xa, 0x80, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x0, 0x5e, 0x70, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x3, 0xd2, 0x9, 0x10, 0x0, 0x0, - 0x0, 0x0, 0x3c, 0x38, 0x0, 0xa6, 0x0, 0x0, - 0x0, 0x4, 0xb1, 0x7, 0x90, 0x7, 0xe9, 0x51, - 0x0, 0x76, 0x0, 0x2, 0x50, 0x1, 0x2a, 0x91, - 0x5, 0x10, 0x66, 0x66, 0x66, 0xbc, 0x0, 0x0, - 0x0, 0x0, 0x0, 0x0, 0x2, 0xe1, 0x0, 0x0, - 0x0, 0x0, 0x0, 0x42, 0xb, 0x60, 0x0, 0x0, - 0x0, 0x0, 0x1d, 0x2d, 0x34, 0x0, 0x10, 0x0, - 0x0, 0x7, 0xd, 0x8, 0x60, 0x1, 0x48, 0x0, - 0x0, 0x87, 0xd, 0x0, 0x0, 0x7, 0xc, 0x70, - 0x2, 0xc1, 0xe, 0x0, 0x0, 0xc, 0x14, 0x50, - 0x0, 0x0, 0xc, 0xdc, 0xcc, 0xdd, 0x20, 0x0, - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - - /* U+600E "怎" */ - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0xc3, 0x0, 0x0, 0x0, 0x0, 0x0, 0x5, - 0xb0, 0x0, 0x0, 0x1, 0x20, 0x0, 0xc, 0x79, - 0x66, 0x66, 0x69, 0xa0, 0x0, 0x75, 0xe, 0x0, - 0x0, 0x0, 0x0, 0x3, 0x70, 0xe, 0x66, 0x66, - 0xc7, 0x0, 0x16, 0x0, 0xe, 0x0, 0x0, 0x0, - 0x0, 0x10, 0x0, 0xe, 0x0, 0x0, 0xa, 0x10, - 0x0, 0x0, 0xe, 0x66, 0x66, 0x67, 0x30, 0x0, - 0x0, 0xe, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x62, 0x47, 0x0, 0x1, 0x0, 0x2, 0x40, 0xe0, - 0xc, 0x40, 0x4, 0x90, 0x9, 0x20, 0xd0, 0x3, - 0x0, 0x50, 0x9a, 0x5e, 0x0, 0xe0, 0x0, 0x0, - 0x91, 0x19, 0x22, 0x0, 0xcc, 0xcc, 0xcc, 0xe5, - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - - /* U+6012 "怒" */ - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, 0xa3, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, 0xd0, 0x1, 0x76, 0x66, 0x8b, 0x0, - 0x6, 0x69, 0xa6, 0xa9, 0x13, 0x0, 0x96, 0x0, - 0x0, 0xa, 0x10, 0xb2, 0x7, 0x2, 0xd0, 0x0, - 0x0, 0x1b, 0x2, 0xb0, 0x2, 0x9c, 0x30, 0x0, - 0x0, 0x4, 0x8e, 0x80, 0x0, 0xbc, 0x0, 0x0, - 0x0, 0x0, 0xa5, 0xb6, 0x1b, 0x45, 0xd5, 0x0, - 0x0, 0x58, 0x10, 0x18, 0x71, 0x0, 0x2c, 0xc1, - 0x4, 0x10, 0x0, 0x34, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x1, 0x9, 0x13, 0xc1, 0x0, 0x50, 0x0, - 0x0, 0x16, 0xe, 0x0, 0xa6, 0x0, 0x6b, 0x10, - 0x0, 0xa5, 0xe, 0x0, 0x10, 0x5, 0xb, 0x70, - 0x2, 0xb0, 0xe, 0x0, 0x0, 0xb, 0x2, 0x10, - 0x0, 0x0, 0xa, 0xdd, 0xdd, 0xdb, 0x10, 0x0, - - /* U+6015 "怕" */ - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x95, 0x0, 0x0, 0x3c, 0x10, 0x0, 0x0, - 0xa, 0x30, 0x0, 0x5, 0x70, 0x0, 0x0, 0x0, - 0xa3, 0x0, 0x0, 0x80, 0x0, 0x20, 0x0, 0xa, - 0x70, 0xd, 0x67, 0x66, 0x6f, 0x10, 0x14, 0xa8, - 0xa0, 0xd0, 0x0, 0x0, 0xe0, 0x5, 0x6a, 0x3a, - 0xd, 0x0, 0x0, 0xe, 0x0, 0xc5, 0xa3, 0x0, - 0xd0, 0x0, 0x0, 0xe0, 0x5, 0xa, 0x30, 0xe, - 0x66, 0x66, 0x6e, 0x0, 0x0, 0xa3, 0x0, 0xd0, - 0x0, 0x0, 0xe0, 0x0, 0xa, 0x30, 0xd, 0x0, - 0x0, 0xe, 0x0, 0x0, 0xa3, 0x0, 0xd0, 0x0, - 0x0, 0xe0, 0x0, 0xa, 0x30, 0xd, 0x0, 0x0, - 0xe, 0x0, 0x0, 0xa3, 0x0, 0xe6, 0x66, 0x66, - 0xe0, 0x0, 0xb, 0x40, 0xd, 0x0, 0x0, 0xe, - 0x0, 0x0, 0x40, 0x0, 0x30, 0x0, 0x0, 0x10, - - /* U+601D "思" */ - 0x0, 0x4, 0x0, 0x0, 0x0, 0x1, 0x50, 0x0, - 0x0, 0xd6, 0x66, 0xd7, 0x66, 0x8c, 0x0, 0x0, - 0xc, 0x10, 0xb, 0x20, 0x3, 0xa0, 0x0, 0x0, - 0xc1, 0x0, 0xb2, 0x0, 0x3a, 0x0, 0x0, 0xc, - 0x66, 0x6d, 0x76, 0x68, 0xa0, 0x0, 0x0, 0xc1, - 0x0, 0xb2, 0x0, 0x3a, 0x0, 0x0, 0xd, 0x10, - 0xb, 0x20, 0x3, 0xa0, 0x0, 0x0, 0xd6, 0x66, - 0x86, 0x66, 0x8b, 0x0, 0x0, 0x5, 0x0, 0x47, - 0x0, 0x1, 0x10, 0x0, 0x3, 0x5, 0x80, 0x9a, - 0x0, 0x4, 0x0, 0x0, 0x90, 0x57, 0x0, 0x70, - 0x4, 0x2c, 0x30, 0x3e, 0x5, 0x70, 0x0, 0x0, - 0x80, 0x7c, 0x9, 0x70, 0x58, 0x0, 0x0, 0xd, - 0x30, 0x50, 0x0, 0x2, 0xdd, 0xdd, 0xdd, 0xd3, - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, - - /* U+6025 "急" */ - 0x0, 0x0, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x4, 0xe1, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0xd9, 0x66, 0x6c, 0x20, 0x0, 0x0, 0x0, - 0x94, 0x0, 0x5, 0xb2, 0x0, 0x0, 0x0, 0x74, - 0x0, 0x1, 0x80, 0x3, 0x20, 0x0, 0x65, 0x76, - 0x66, 0x66, 0x66, 0xb9, 0x0, 0x31, 0x0, 0x0, - 0x0, 0x0, 0x9, 0x50, 0x0, 0x0, 0x57, 0x66, - 0x66, 0x66, 0xb5, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x9, 0x60, 0x0, 0x4, 0x76, 0x66, 0x66, - 0x66, 0xb6, 0x0, 0x0, 0x0, 0x50, 0x77, 0x0, - 0x4, 0x10, 0x0, 0x5, 0xe, 0x10, 0xb5, 0x3, - 0x49, 0x10, 0x4, 0x70, 0xd0, 0x1, 0x0, 0x60, - 0x7c, 0x2, 0xe2, 0xe, 0x0, 0x0, 0x1c, 0x0, - 0x70, 0x1, 0x0, 0xcd, 0xcc, 0xce, 0xc1, 0x0, - 0x0, - - /* U+6027 "性" */ - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0xd, 0x20, 0x0, 0x0, 0xb2, 0x0, 0x0, - 0x0, 0xe, 0x0, 0x4, 0x0, 0xd0, 0x0, 0x0, - 0x0, 0xe, 0x0, 0xe, 0x40, 0xd0, 0x0, 0x0, - 0x0, 0xe, 0x81, 0x1d, 0x0, 0xd0, 0x3, 0x0, - 0x2, 0x3e, 0x4b, 0x5a, 0x66, 0xe6, 0x6b, 0x50, - 0x7, 0x4e, 0x2, 0xa1, 0x0, 0xd0, 0x0, 0x0, - 0xe, 0x2e, 0x0, 0x80, 0x0, 0xd0, 0x0, 0x0, - 0x0, 0xe, 0x4, 0x0, 0x0, 0xd0, 0x5, 0x0, - 0x0, 0xe, 0x0, 0x18, 0x66, 0xe6, 0x78, 0x10, - 0x0, 0xe, 0x0, 0x0, 0x0, 0xd0, 0x0, 0x0, - 0x0, 0xe, 0x0, 0x0, 0x0, 0xd0, 0x0, 0x0, - 0x0, 0xe, 0x0, 0x0, 0x0, 0xd0, 0x0, 0x0, - 0x0, 0xe, 0x0, 0x0, 0x0, 0xd0, 0x4, 0x80, - 0x0, 0xf, 0x5, 0x76, 0x66, 0x66, 0x66, 0x61, - 0x0, 0x5, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - - /* U+606F "息" */ - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x1, 0xd1, 0x0, 0x0, 0x0, 0x0, 0x9, - 0x69, 0x86, 0x66, 0xb5, 0x0, 0x0, 0xe, 0x0, - 0x0, 0x0, 0xb3, 0x0, 0x0, 0xf, 0x66, 0x66, - 0x66, 0xd3, 0x0, 0x0, 0xe, 0x0, 0x0, 0x0, - 0xb3, 0x0, 0x0, 0xf, 0x66, 0x66, 0x66, 0xd3, - 0x0, 0x0, 0xe, 0x0, 0x0, 0x0, 0xb3, 0x0, - 0x0, 0xf, 0x66, 0x66, 0x66, 0xd3, 0x0, 0x0, - 0xa, 0x0, 0x60, 0x0, 0x71, 0x0, 0x0, 0x0, - 0x60, 0x5d, 0x10, 0x0, 0x0, 0x0, 0x50, 0xe1, - 0xc, 0x10, 0x15, 0x70, 0x7, 0x50, 0xd0, 0x0, - 0x0, 0x70, 0xc7, 0x4f, 0x20, 0xd0, 0x0, 0x1, - 0xb0, 0x57, 0x12, 0x0, 0x9c, 0xcc, 0xcc, 0xa0, - 0x0, - - /* U+60A8 "您" */ - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x2d, 0x10, 0x78, 0x0, 0x0, 0x0, 0x0, - 0x8, 0x80, 0xe, 0x30, 0x0, 0x1, 0x0, 0x1, - 0xe0, 0x5, 0xb6, 0x66, 0x68, 0xe2, 0x0, 0xae, - 0x1, 0x90, 0x6, 0x10, 0x94, 0x0, 0x65, 0xe0, - 0x60, 0x30, 0xd2, 0x2, 0x0, 0x14, 0xe, 0x0, - 0x4e, 0x2c, 0x16, 0x20, 0x0, 0x0, 0xe0, 0x1a, - 0x10, 0xc1, 0xc, 0x40, 0x0, 0xe, 0x7, 0x5, - 0x5e, 0x0, 0x3b, 0x0, 0x0, 0xd0, 0x0, 0x8, - 0xa0, 0x0, 0x10, 0x0, 0x0, 0x18, 0x19, 0x20, - 0x0, 0x10, 0x0, 0x2, 0x51, 0xd0, 0x3e, 0x0, - 0x26, 0x60, 0x0, 0xa4, 0x1d, 0x0, 0x50, 0x6, - 0xb, 0x70, 0x7e, 0x0, 0xd0, 0x0, 0x0, 0xd1, - 0x28, 0x0, 0x0, 0xb, 0xbb, 0xbb, 0xcb, 0x10, - 0x0, - - /* U+60AA "悪" */ - 0x0, 0x0, 0x0, 0x0, 0x0, 0x5, 0x50, 0x7, - 0x66, 0x6d, 0x66, 0xd6, 0x66, 0x60, 0x0, 0x10, - 0xe, 0x0, 0xe0, 0x3, 0x0, 0x0, 0xe6, 0x6e, - 0x66, 0xe6, 0x6f, 0x20, 0x0, 0xe0, 0xe, 0x0, - 0xe0, 0xe, 0x0, 0x0, 0xe6, 0x6e, 0x66, 0xe6, - 0x6e, 0x0, 0x0, 0x60, 0xe, 0x0, 0xe0, 0x5, - 0x10, 0x26, 0x66, 0x6e, 0x66, 0xe6, 0x68, 0xf5, - 0x2, 0x0, 0x0, 0x40, 0x0, 0x0, 0x0, 0x0, - 0x4, 0x90, 0x4c, 0x10, 0x3, 0x10, 0x1, 0x64, - 0xa0, 0x9, 0x60, 0x20, 0xb1, 0x9, 0x54, 0xa0, - 0x0, 0x0, 0x70, 0x6a, 0x7e, 0x13, 0xa0, 0x0, - 0x0, 0xc2, 0x6, 0x1, 0x1, 0xed, 0xdd, 0xdd, - 0xd3, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, - - /* U+60B2 "悲" */ - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, 0xc1, 0xb, 0x40, 0x0, 0x0, 0x0, - 0x0, 0xd, 0x0, 0xc1, 0x0, 0x61, 0x1, 0x66, - 0x66, 0xd0, 0xc, 0x66, 0x66, 0x30, 0x0, 0x0, - 0xd, 0x0, 0xc1, 0x2, 0x30, 0x0, 0x36, 0x66, - 0xd0, 0xc, 0x66, 0x66, 0x0, 0x0, 0x0, 0xd, - 0x0, 0xc1, 0x0, 0x10, 0x3, 0x66, 0x66, 0xd0, - 0xc, 0x66, 0x6a, 0x80, 0x0, 0x0, 0xd, 0x0, - 0xd1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x64, 0x15, - 0x0, 0x0, 0x0, 0x0, 0x11, 0xb0, 0x1d, 0x20, - 0x5, 0x30, 0x0, 0x43, 0xd, 0x0, 0x86, 0x1, - 0xc, 0x50, 0xd, 0x20, 0xd0, 0x0, 0x0, 0x60, - 0x39, 0x6, 0xa0, 0xe, 0x0, 0x0, 0xa, 0x40, - 0x0, 0x0, 0x0, 0xdc, 0xcc, 0xcc, 0xd4, 0x0, - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - - /* U+60C5 "情" */ - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x1c, 0x20, 0x0, 0xc, 0x30, 0x0, 0x0, - 0x0, 0xd, 0x0, 0x0, 0xd, 0x10, 0x15, 0x0, - 0x0, 0xe, 0x0, 0x76, 0x6d, 0x66, 0x67, 0x10, - 0x2, 0xe, 0xb4, 0x0, 0xc, 0x10, 0x60, 0x0, - 0x7, 0x2d, 0x37, 0x17, 0x6d, 0x66, 0x63, 0x0, - 0xd, 0x2d, 0x0, 0x0, 0xc, 0x10, 0x5, 0x40, - 0x17, 0xd, 0x6, 0x66, 0x66, 0x66, 0x66, 0x50, - 0x0, 0xd, 0x0, 0x29, 0x66, 0x66, 0xd2, 0x0, - 0x0, 0xd, 0x0, 0x2b, 0x0, 0x0, 0xd0, 0x0, - 0x0, 0xd, 0x0, 0x1d, 0x66, 0x66, 0xe0, 0x0, - 0x0, 0xd, 0x0, 0x1b, 0x0, 0x0, 0xd0, 0x0, - 0x0, 0xd, 0x0, 0x1d, 0x66, 0x66, 0xe0, 0x0, - 0x0, 0xd, 0x0, 0x1b, 0x0, 0x0, 0xd0, 0x0, - 0x0, 0xe, 0x0, 0x2b, 0x0, 0x5a, 0xe0, 0x0, - 0x0, 0x5, 0x0, 0x14, 0x0, 0x4, 0x30, 0x0, - - /* U+60F3 "想" */ - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, 0xc2, 0x0, 0x0, 0x0, 0x1, 0x0, - 0x0, 0x0, 0xd0, 0x0, 0xc6, 0x66, 0x6e, 0x10, - 0x0, 0x0, 0xd0, 0x70, 0xd0, 0x0, 0xd, 0x0, - 0x4, 0x66, 0xf6, 0x62, 0xd6, 0x66, 0x6d, 0x0, - 0x0, 0x6, 0xf6, 0x0, 0xd0, 0x0, 0xd, 0x0, - 0x0, 0xc, 0xe5, 0xd0, 0xd6, 0x66, 0x6d, 0x0, - 0x0, 0x74, 0xd0, 0x90, 0xd0, 0x0, 0xd, 0x0, - 0x3, 0x60, 0xd0, 0x0, 0xd6, 0x66, 0x6d, 0x0, - 0x4, 0x0, 0xd0, 0x0, 0xc0, 0x0, 0xa, 0x0, - 0x0, 0x0, 0x22, 0x9, 0x50, 0x0, 0x0, 0x0, - 0x0, 0x3, 0xe, 0x20, 0xe4, 0x1, 0x33, 0x0, - 0x0, 0x46, 0xd, 0x0, 0x41, 0x5, 0xb, 0x60, - 0x1, 0xd4, 0xd, 0x0, 0x0, 0xb, 0x3, 0xa0, - 0x1, 0x50, 0xa, 0xcb, 0xbb, 0xbc, 0x10, 0x0, - - /* U+6108 "愈" */ - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x0, 0xaa, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x8b, 0x63, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x98, 0x0, 0x86, 0x0, 0x0, 0x0, 0x4, - 0x98, 0x66, 0x6b, 0xad, 0x83, 0x10, 0x46, 0x70, - 0x0, 0x40, 0x0, 0x4a, 0xe4, 0x0, 0xc, 0x66, - 0x6b, 0x7, 0xc, 0x20, 0x0, 0x0, 0xc5, 0x56, - 0x90, 0xb0, 0xc0, 0x0, 0x0, 0xc, 0x66, 0x69, - 0xb, 0xc, 0x0, 0x0, 0x0, 0xc0, 0x2, 0x90, - 0x70, 0xc0, 0x0, 0x0, 0xc, 0x2, 0xb6, 0x0, - 0x8d, 0x0, 0x0, 0x0, 0x0, 0x91, 0x6a, 0x0, - 0x10, 0x0, 0x0, 0x14, 0xe, 0x0, 0xa2, 0x3, - 0x48, 0x0, 0xb, 0x40, 0xe0, 0x0, 0x2, 0x80, - 0x97, 0x2, 0x70, 0xc, 0xbb, 0xbb, 0xd9, 0x1, - 0x20, - - /* U+610F "意" */ - 0x0, 0x0, 0x0, 0x10, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x0, 0xc2, 0x0, 0x0, 0x0, 0x0, - 0x16, 0x66, 0x6c, 0x76, 0x6e, 0x40, 0x0, 0x0, - 0x0, 0x82, 0x0, 0xa4, 0x0, 0x0, 0x0, 0x0, - 0x3, 0x80, 0x28, 0x0, 0x7, 0x0, 0x76, 0x66, - 0x66, 0x67, 0x66, 0x67, 0x93, 0x0, 0x7, 0x66, - 0x66, 0x66, 0x6a, 0x0, 0x0, 0x0, 0xb2, 0x0, - 0x0, 0x0, 0xd0, 0x0, 0x0, 0xa, 0x76, 0x66, - 0x66, 0x6d, 0x0, 0x0, 0x0, 0xa2, 0x0, 0x0, - 0x0, 0xd0, 0x0, 0x0, 0xb, 0x76, 0x76, 0x66, - 0x6c, 0x0, 0x0, 0x1, 0x15, 0x32, 0xb3, 0x0, - 0x3, 0x0, 0x0, 0x80, 0x85, 0x4, 0x90, 0x30, - 0x6a, 0x0, 0x3c, 0x8, 0x40, 0x0, 0x7, 0x0, - 0xb6, 0x9, 0x40, 0x4d, 0xbb, 0xbb, 0xd4, 0x1, - 0x10, - - /* U+611A "愚" */ - 0x0, 0x86, 0x66, 0x66, 0x66, 0xb4, 0x0, 0x0, - 0xc0, 0x0, 0xd0, 0x0, 0xd2, 0x0, 0x0, 0xb6, - 0x66, 0xe6, 0x66, 0xe2, 0x0, 0x0, 0xc0, 0x0, - 0xd0, 0x0, 0xd2, 0x0, 0x0, 0xc6, 0x66, 0xe6, - 0x66, 0xe3, 0x0, 0x3, 0x30, 0x0, 0xd0, 0x0, - 0x20, 0x50, 0xd, 0x66, 0x66, 0xe6, 0x76, 0x67, - 0xc0, 0xc, 0x10, 0x0, 0xd0, 0x3b, 0x22, 0xa0, - 0xc, 0x1b, 0xc9, 0x86, 0x46, 0x92, 0xa0, 0xd, - 0x12, 0x5, 0x20, 0x0, 0x69, 0x90, 0x6, 0x6, - 0x21, 0xd4, 0x0, 0x9, 0x20, 0x6, 0xa, 0x40, - 0x44, 0x3, 0x8, 0x50, 0x2d, 0xa, 0x30, 0x0, - 0x6, 0x30, 0xd4, 0x65, 0x6, 0xdb, 0xbb, 0xbd, - 0x90, 0x41, - - /* U+611B "愛" */ - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x1, 0x47, 0xbc, 0x0, 0x1, 0x45, - 0x67, 0x97, 0x76, 0xb4, 0x10, 0x0, 0x9, 0x40, - 0x96, 0x6, 0x90, 0x0, 0x6, 0x68, 0xa6, 0x7b, - 0x6a, 0x66, 0xa3, 0x2d, 0x0, 0x30, 0x73, 0x0, - 0x1, 0xa3, 0x76, 0x70, 0xe0, 0x1e, 0x30, 0x46, - 0x40, 0x2, 0xc0, 0xd0, 0x3, 0x0, 0x90, 0xc7, - 0x6, 0x50, 0x9c, 0xcc, 0xcd, 0xa0, 0x26, 0x0, - 0x0, 0xc2, 0x0, 0x0, 0x0, 0x0, 0x0, 0x7, - 0xd6, 0x66, 0x6a, 0x10, 0x0, 0x0, 0x48, 0x35, - 0x0, 0x8c, 0x30, 0x0, 0x3, 0x50, 0x6, 0x89, - 0x90, 0x0, 0x0, 0x0, 0x0, 0x5, 0xde, 0x61, - 0x0, 0x0, 0x0, 0x36, 0x85, 0x1, 0x8e, 0xdb, - 0x91, 0x14, 0x10, 0x0, 0x0, 0x0, 0x25, 0x20, - - /* U+611F "感" */ - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x0, 0x0, 0x8, 0x66, 0x40, 0x0, - 0x0, 0x11, 0x0, 0x0, 0x7, 0x50, 0xa1, 0x50, - 0x0, 0x3c, 0x66, 0x66, 0x69, 0xa6, 0x67, 0x71, - 0x0, 0x3a, 0x0, 0x0, 0x53, 0x90, 0x6, 0x0, - 0x0, 0x3a, 0x56, 0x66, 0x63, 0xb0, 0x6c, 0x10, - 0x0, 0x48, 0x27, 0x66, 0x91, 0xe2, 0xd1, 0x0, - 0x0, 0x66, 0x3a, 0x0, 0xd0, 0x9e, 0x40, 0x0, - 0x0, 0x92, 0x2a, 0x0, 0xd0, 0x9e, 0x20, 0x50, - 0x0, 0x90, 0x3c, 0x66, 0xb7, 0x54, 0xd4, 0x80, - 0x6, 0x10, 0x0, 0x2, 0x42, 0x0, 0x3d, 0xf1, - 0x2, 0x2, 0x39, 0x5, 0xb1, 0x0, 0x81, 0x32, - 0x0, 0x54, 0x3a, 0x0, 0x93, 0x4, 0x3d, 0x0, - 0x3, 0xe1, 0x2a, 0x0, 0x0, 0x18, 0xa, 0x10, - 0x2, 0x40, 0x1d, 0xbb, 0xbb, 0xda, 0x0, 0x0, - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - - /* U+614B "態" */ - 0x0, 0x3a, 0x0, 0x1, 0x50, 0x0, 0x0, 0x0, - 0x1b, 0x31, 0x20, 0x2b, 0x0, 0x83, 0x0, 0x58, - 0x21, 0x1a, 0x52, 0xb5, 0x75, 0x40, 0x7, 0xa7, - 0x53, 0x39, 0x2a, 0x0, 0x6, 0x30, 0xb, 0x55, - 0x5d, 0x21, 0xba, 0xaa, 0xa3, 0x0, 0xd6, 0x66, - 0xd0, 0x3c, 0x0, 0x52, 0x0, 0xd, 0x0, 0xd, - 0x2, 0xa2, 0x9b, 0x50, 0x0, 0xd6, 0x66, 0xd0, - 0x2b, 0x30, 0x4, 0x0, 0xd, 0x0, 0xd, 0x2, - 0xc1, 0x11, 0x93, 0x0, 0xc0, 0x4b, 0xa2, 0x8, - 0xaa, 0xa8, 0x10, 0x1, 0x8, 0x60, 0x4b, 0x10, - 0x11, 0x60, 0x0, 0x71, 0xa2, 0x0, 0x76, 0x5, - 0x8, 0x90, 0x6d, 0xa, 0x30, 0x0, 0x0, 0xa0, - 0x1d, 0x4, 0x20, 0x6d, 0xcc, 0xcc, 0xdc, 0x10, - 0x0, - - /* U+6163 "慣" */ - 0x0, 0xa, 0x10, 0x8, 0x66, 0x66, 0x6a, 0x0, - 0x0, 0xd, 0x0, 0xe, 0x0, 0xd0, 0x1d, 0x0, - 0x0, 0xd, 0x15, 0x6e, 0x67, 0xd6, 0x7d, 0xc2, - 0x0, 0x4d, 0x81, 0x2b, 0x5, 0x80, 0x59, 0x0, - 0x4, 0x5d, 0x75, 0x6b, 0x6a, 0xa6, 0xa7, 0x0, - 0xb, 0x4d, 0x31, 0x12, 0x0, 0x0, 0x42, 0x0, - 0x6, 0xd, 0x0, 0xa6, 0x66, 0x66, 0x6b, 0x0, - 0x0, 0xd, 0x0, 0xd0, 0x0, 0x0, 0xd, 0x0, - 0x0, 0xd, 0x0, 0xd6, 0x66, 0x66, 0x6d, 0x0, - 0x0, 0xd, 0x0, 0xd6, 0x66, 0x66, 0x6d, 0x0, - 0x0, 0xd, 0x0, 0xd0, 0x0, 0x0, 0xd, 0x0, - 0x0, 0xd, 0x0, 0xd6, 0x66, 0x66, 0x6c, 0x0, - 0x0, 0xd, 0x0, 0x2b, 0x90, 0x4, 0x94, 0x0, - 0x0, 0xe, 0x2, 0x93, 0x0, 0x0, 0x2e, 0x60, - 0x0, 0x3, 0x13, 0x0, 0x0, 0x0, 0x2, 0x30, - - /* U+6167 "慧" */ - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x1c, 0x0, 0x0, 0xa3, 0x0, 0x0, 0x6, - 0x66, 0xd6, 0xa3, 0x6c, 0x76, 0xc4, 0x0, 0x10, - 0xc, 0x1, 0x0, 0xb2, 0x2, 0x0, 0x3, 0x76, - 0xd7, 0x52, 0x7c, 0x76, 0x80, 0x2, 0x66, 0x6d, - 0x6a, 0x36, 0xc7, 0x67, 0x90, 0x2, 0x0, 0xc0, - 0x0, 0x1b, 0x20, 0x0, 0x0, 0x6, 0x76, 0x66, - 0x66, 0x66, 0xc3, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0xd, 0x0, 0x0, 0x1, 0x86, 0x66, 0x66, - 0x66, 0xe0, 0x0, 0x0, 0x56, 0x66, 0x66, 0x66, - 0x6e, 0x0, 0x0, 0x1, 0x5, 0x7, 0x20, 0x0, - 0x50, 0x0, 0x0, 0x60, 0xd2, 0x1d, 0x2, 0x34, - 0x80, 0x0, 0x94, 0xd, 0x0, 0x20, 0x38, 0x7, - 0x90, 0x7, 0x0, 0x9c, 0xbb, 0xbd, 0x90, 0x3, - 0x0, - - /* U+616E "慮" */ - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x0, 0x0, 0xc1, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x0, 0x0, 0xe6, 0x69, 0x80, 0x0, - 0x0, 0x14, 0x0, 0x0, 0xd0, 0x0, 0x5, 0x0, - 0x0, 0x1e, 0x66, 0x66, 0xc6, 0x67, 0x6e, 0x60, - 0x0, 0x1c, 0x13, 0x55, 0xd5, 0x77, 0x44, 0x0, - 0x0, 0x1c, 0x4, 0x0, 0xd2, 0x22, 0x39, 0x0, - 0x0, 0x1b, 0x1, 0x0, 0x57, 0x88, 0xb3, 0x0, - 0x0, 0x2b, 0xe, 0x66, 0x99, 0x66, 0xe1, 0x0, - 0x0, 0x2a, 0xd, 0x66, 0x99, 0x66, 0xd0, 0x0, - 0x0, 0x48, 0xd, 0x0, 0x66, 0x0, 0xd0, 0x0, - 0x0, 0x65, 0xe, 0x66, 0x77, 0x66, 0xc0, 0x0, - 0x0, 0x90, 0x13, 0x40, 0x5a, 0x20, 0x17, 0x0, - 0x0, 0x80, 0x90, 0xf1, 0x5, 0x51, 0x5, 0xc0, - 0x6, 0x1c, 0x80, 0xe0, 0x0, 0x6, 0x10, 0x50, - 0x5, 0x2, 0x0, 0xcc, 0xcc, 0xcd, 0x50, 0x0, - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - - /* U+61C9 "應" */ - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x0, 0x7a, 0x0, 0x0, 0x10, 0x0, - 0x96, 0x66, 0x66, 0xc6, 0x66, 0x6e, 0x80, 0xb, - 0x40, 0x24, 0x36, 0x37, 0x0, 0x0, 0x0, 0xb3, - 0xa, 0xa9, 0x90, 0x81, 0x4, 0x0, 0xb, 0x35, - 0xd1, 0xe6, 0x6c, 0x66, 0x70, 0x0, 0xb6, 0x7c, - 0x6d, 0x66, 0xd6, 0x95, 0x0, 0xc, 0x21, 0xc2, - 0xd0, 0xc, 0x1, 0x0, 0x0, 0xd0, 0x1c, 0xd, - 0x66, 0xd6, 0x95, 0x0, 0xd, 0x1, 0xc0, 0xd0, - 0xc, 0x0, 0x71, 0x0, 0xd0, 0x1c, 0xd, 0x66, - 0x66, 0x66, 0x30, 0x2b, 0x0, 0x30, 0x30, 0x0, - 0x0, 0x0, 0x5, 0x70, 0x26, 0x32, 0xb4, 0x0, - 0x28, 0x0, 0x92, 0x27, 0x75, 0x3, 0xd0, 0x40, - 0x79, 0x8, 0x1d, 0x47, 0x40, 0x0, 0x8, 0x21, - 0x84, 0x21, 0x50, 0x3d, 0xcc, 0xcc, 0xd5, 0x0, - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - - /* U+61F8 "懸" */ - 0x0, 0x66, 0x66, 0xa2, 0x0, 0x25, 0x9b, 0x0, - 0x0, 0x92, 0x0, 0xc0, 0x45, 0x9c, 0x31, 0x0, - 0x0, 0x97, 0x66, 0xd0, 0x16, 0x71, 0x88, 0x0, - 0x0, 0x97, 0x55, 0xd0, 0x3b, 0x8d, 0x81, 0x0, - 0x0, 0x97, 0x66, 0xd0, 0x5, 0x82, 0x8, 0x10, - 0x0, 0x92, 0x0, 0xc4, 0x6f, 0xcd, 0x78, 0xa0, - 0x7, 0xa6, 0xc6, 0x88, 0x55, 0xd, 0x0, 0x30, - 0x0, 0xc4, 0xc3, 0x70, 0x2d, 0x2d, 0x9, 0x30, - 0x7, 0x44, 0xd0, 0x95, 0x91, 0xc, 0x2, 0xe0, - 0x0, 0x5, 0x70, 0x2, 0x3, 0xc9, 0x0, 0x40, - 0x0, 0x10, 0xa4, 0x8, 0x70, 0x0, 0x32, 0x0, - 0x0, 0x80, 0xa2, 0x0, 0xc5, 0x4, 0xb, 0x50, - 0x6, 0xb0, 0xa3, 0x0, 0x10, 0xb, 0x3, 0xb0, - 0x6, 0x20, 0x6d, 0xcc, 0xcc, 0xda, 0x0, 0x0, - - /* U+6210 "成" */ - 0x0, 0x0, 0x0, 0x0, 0xa3, 0x24, 0x0, 0x0, - 0x0, 0x0, 0x0, 0x0, 0xe3, 0xa, 0x80, 0x0, - 0x0, 0x0, 0x0, 0x0, 0xc3, 0x2, 0xb2, 0x0, - 0x0, 0x87, 0x66, 0x66, 0xd8, 0x66, 0x6d, 0x50, - 0x0, 0x96, 0x0, 0x0, 0x95, 0x0, 0x0, 0x0, - 0x0, 0x96, 0x0, 0x0, 0x77, 0x0, 0x63, 0x0, - 0x0, 0x95, 0x0, 0x41, 0x4a, 0x0, 0xd7, 0x0, - 0x0, 0x99, 0x66, 0xd6, 0x1d, 0x4, 0xd0, 0x0, - 0x0, 0xa3, 0x0, 0xc1, 0xd, 0x1b, 0x60, 0x0, - 0x0, 0xb2, 0x0, 0xc0, 0x8, 0xad, 0x0, 0x0, - 0x0, 0xc0, 0x0, 0xd0, 0x2, 0xf5, 0x0, 0x40, - 0x1, 0xa0, 0x78, 0xc0, 0x9, 0xbd, 0x10, 0x70, - 0x6, 0x40, 0xb, 0x40, 0x94, 0x8, 0xe6, 0xa0, - 0x8, 0x0, 0x0, 0x17, 0x20, 0x0, 0x5d, 0xc0, - 0x20, 0x0, 0x0, 0x20, 0x0, 0x0, 0x0, 0x30, - - /* U+6211 "我" */ - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x3, 0xa0, 0xd4, 0x0, 0x0, 0x0, - 0x2, 0x57, 0xd9, 0x61, 0xd1, 0x8, 0x60, 0x0, - 0x1, 0x0, 0xb2, 0x0, 0xd1, 0x0, 0xd7, 0x0, - 0x0, 0x0, 0xb2, 0x0, 0xc1, 0x0, 0x35, 0x0, - 0x16, 0x66, 0xd7, 0x66, 0xd7, 0x66, 0x7f, 0x30, - 0x2, 0x0, 0xb2, 0x0, 0xa3, 0x0, 0x10, 0x0, - 0x0, 0x0, 0xb2, 0x0, 0x85, 0x2, 0xe1, 0x0, - 0x0, 0x0, 0xb6, 0x63, 0x66, 0xb, 0x50, 0x0, - 0x1, 0x5a, 0xe5, 0x0, 0x49, 0x78, 0x0, 0x0, - 0x3f, 0x92, 0xb2, 0x0, 0xe, 0xb0, 0x0, 0x0, - 0x1, 0x0, 0xb2, 0x0, 0x5e, 0x70, 0x0, 0x40, - 0x0, 0x0, 0xb2, 0x8, 0x70, 0xc6, 0x0, 0x70, - 0x0, 0x43, 0xd5, 0x61, 0x0, 0x1c, 0xa4, 0x90, - 0x0, 0x1c, 0xc0, 0x0, 0x0, 0x0, 0x6d, 0xd0, - 0x0, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x20, - - /* U+6216 "或" */ - 0x0, 0x0, 0x0, 0x0, 0x18, 0x18, 0x50, 0x0, - 0x0, 0x0, 0x0, 0x0, 0x1e, 0x1, 0xe2, 0x0, - 0x0, 0x0, 0x0, 0x0, 0x1d, 0x0, 0x18, 0x20, - 0x6, 0x66, 0x66, 0x66, 0x6f, 0x66, 0x66, 0x40, - 0x0, 0x0, 0x0, 0x10, 0xe, 0x0, 0x10, 0x0, - 0x0, 0xd6, 0x66, 0xe3, 0xd, 0x10, 0x99, 0x0, - 0x0, 0xd1, 0x0, 0xe0, 0xb, 0x30, 0xe3, 0x0, - 0x0, 0xc1, 0x0, 0xe0, 0x9, 0x53, 0xc0, 0x0, - 0x0, 0xd6, 0x66, 0xe0, 0x5, 0x9a, 0x50, 0x0, - 0x0, 0xc0, 0x0, 0x80, 0x0, 0xec, 0x0, 0x0, - 0x0, 0x0, 0x0, 0x3, 0x42, 0xe9, 0x0, 0x40, - 0x14, 0x68, 0xa9, 0x62, 0x2c, 0x4d, 0x50, 0x70, - 0x1e, 0x94, 0x0, 0x5, 0x91, 0x2, 0xe8, 0xa0, - 0x0, 0x0, 0x2, 0x63, 0x0, 0x0, 0x1a, 0xd0, - 0x0, 0x0, 0x1, 0x0, 0x0, 0x0, 0x0, 0x10, - - /* U+6226 "戦" */ - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x2, - 0x14, 0x60, 0x8, 0x10, 0x5b, 0x20, 0x0, 0xc, - 0x2c, 0x41, 0xb0, 0x4, 0xa4, 0x80, 0x0, 0x63, - 0x30, 0x52, 0x0, 0x4a, 0xd, 0x20, 0x1d, 0x66, - 0xa6, 0xe3, 0x4, 0xa0, 0x12, 0x0, 0xc0, 0x1b, - 0xd, 0x2, 0x6c, 0x55, 0x82, 0xd, 0x66, 0xc6, - 0xe3, 0x44, 0xa0, 0x33, 0x0, 0xc0, 0x1b, 0xd, - 0x0, 0x1b, 0xa, 0x90, 0x1c, 0x1, 0xb0, 0xd0, - 0x0, 0xd2, 0xd0, 0x1, 0xd6, 0x6c, 0x6d, 0x0, - 0xd, 0xa4, 0x0, 0x1, 0x1, 0xb0, 0x0, 0x0, - 0xba, 0x0, 0x5, 0x66, 0x6c, 0x67, 0xc1, 0x1d, - 0xb0, 0x4, 0x0, 0x1, 0xb0, 0x0, 0xc, 0x3c, - 0x53, 0x60, 0x0, 0x1b, 0x0, 0x1a, 0x30, 0x2e, - 0xb4, 0x0, 0x1, 0xb0, 0x38, 0x0, 0x0, 0x4f, - 0x60, 0x0, 0x2, 0x1, 0x0, 0x0, 0x0, 0x24, - - /* U+6230 "戰" */ - 0x0, 0x0, 0x0, 0x0, 0x0, 0x10, 0x0, 0x0, - 0x7, 0x69, 0x18, 0x69, 0x20, 0xc5, 0x20, 0x0, - 0xb, 0xc, 0xc, 0xb, 0x0, 0xc2, 0x68, 0x0, - 0xb, 0xc, 0xc, 0xb, 0x0, 0xc2, 0xc, 0x0, - 0xc, 0x6d, 0xd, 0x6c, 0x0, 0xc2, 0x1, 0x0, - 0x5, 0x1, 0x2, 0x5, 0x0, 0xc6, 0x6a, 0x60, - 0x8, 0x86, 0xd6, 0x6d, 0x46, 0xc3, 0x3, 0x0, - 0x7, 0x40, 0xc0, 0x1b, 0x0, 0xa3, 0x2e, 0x30, - 0x7, 0x86, 0xd6, 0x6b, 0x0, 0x85, 0x96, 0x0, - 0x7, 0x40, 0xc0, 0x1b, 0x0, 0x69, 0xd0, 0x0, - 0x8, 0x86, 0xd6, 0x66, 0x0, 0x3f, 0x40, 0x0, - 0x0, 0x0, 0xc0, 0x5, 0x10, 0x6f, 0x20, 0x30, - 0x8, 0x66, 0xd6, 0x66, 0x33, 0xa5, 0xc0, 0x80, - 0x0, 0x0, 0xc0, 0x0, 0x38, 0x0, 0xaa, 0xc0, - 0x0, 0x0, 0xd0, 0x4, 0x40, 0x0, 0xb, 0xd0, - 0x0, 0x0, 0x30, 0x10, 0x0, 0x0, 0x0, 0x70, - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - - /* U+623B "戻" */ - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x0, 0xa2, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x5, 0xa0, 0x0, 0x0, 0x0, 0x0, - 0x78, 0x66, 0x68, 0x66, 0x6d, 0x30, 0x0, 0x7, - 0x70, 0x0, 0x0, 0x0, 0xd0, 0x0, 0x0, 0x87, - 0x0, 0x0, 0x0, 0xd, 0x0, 0x0, 0x8, 0xa6, - 0x66, 0x66, 0x66, 0xe0, 0x0, 0x0, 0xa5, 0x0, - 0x7, 0x20, 0x7, 0x0, 0x0, 0xb, 0x30, 0x0, - 0xe3, 0x0, 0x0, 0x0, 0x0, 0xe3, 0x66, 0x6e, - 0x66, 0x6b, 0x90, 0x0, 0x2a, 0x1, 0x7, 0x76, - 0x0, 0x0, 0x0, 0x8, 0x40, 0x1, 0xd0, 0x27, - 0x0, 0x0, 0x0, 0xb0, 0x0, 0xb3, 0x0, 0x78, - 0x0, 0x0, 0x63, 0x0, 0x93, 0x0, 0x0, 0x9d, - 0x61, 0x6, 0x4, 0x71, 0x0, 0x0, 0x0, 0x6e, - 0x51, 0x1, 0x10, 0x0, 0x0, 0x0, 0x0, 0x0, - - /* U+623F "房" */ - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x0, 0x77, 0x0, 0x0, 0x0, 0x0, - 0x4, 0x0, 0x0, 0xa0, 0x0, 0x32, 0x0, 0x0, - 0xd6, 0x66, 0x66, 0x66, 0x6b, 0x80, 0x0, 0xd, - 0x10, 0x0, 0x0, 0x0, 0x95, 0x0, 0x0, 0xd6, - 0x66, 0x66, 0x66, 0x6b, 0x50, 0x0, 0xd, 0x0, - 0x0, 0x84, 0x0, 0x20, 0x0, 0x0, 0xd0, 0x0, - 0x2, 0xc0, 0x0, 0x20, 0x0, 0xd, 0x26, 0x68, - 0x86, 0x66, 0x6a, 0x50, 0x2, 0xa0, 0x0, 0x87, - 0x0, 0x0, 0x0, 0x0, 0x57, 0x0, 0xb, 0x96, - 0x66, 0xb7, 0x0, 0x9, 0x10, 0x1, 0xe0, 0x0, - 0xb, 0x30, 0x0, 0x90, 0x0, 0x97, 0x0, 0x0, - 0xd1, 0x0, 0x62, 0x0, 0x6a, 0x0, 0x0, 0xe, - 0x0, 0x15, 0x0, 0x77, 0x0, 0x1, 0x7c, 0xa0, - 0x0, 0x0, 0x41, 0x0, 0x0, 0x0, 0x50, 0x0, - - /* U+6240 "所" */ - 0x0, 0x0, 0x2, 0xa2, 0x0, 0x0, 0x4b, 0x40, - 0x0, 0x86, 0x78, 0x52, 0x85, 0x68, 0x75, 0x30, - 0x0, 0xc2, 0x0, 0x0, 0xc3, 0x0, 0x0, 0x0, - 0x0, 0xc2, 0x0, 0x0, 0xc3, 0x0, 0x0, 0x0, - 0x0, 0xc7, 0x66, 0xb1, 0xb3, 0x0, 0x0, 0x20, - 0x0, 0xc2, 0x0, 0xe0, 0xb8, 0x66, 0xa7, 0xa1, - 0x0, 0xc1, 0x0, 0xe0, 0xc3, 0x0, 0xd0, 0x0, - 0x0, 0xc1, 0x0, 0xe0, 0xd1, 0x0, 0xd0, 0x0, - 0x0, 0xd6, 0x66, 0xe0, 0xe0, 0x0, 0xd0, 0x0, - 0x0, 0xe0, 0x0, 0x23, 0xa0, 0x0, 0xd0, 0x0, - 0x0, 0xc0, 0x0, 0x9, 0x40, 0x0, 0xd0, 0x0, - 0x4, 0x70, 0x0, 0x1b, 0x0, 0x0, 0xd0, 0x0, - 0x8, 0x10, 0x0, 0x82, 0x0, 0x0, 0xd0, 0x0, - 0x16, 0x0, 0x4, 0x40, 0x0, 0x0, 0xe0, 0x0, - 0x20, 0x0, 0x3, 0x0, 0x0, 0x0, 0x20, 0x0, - - /* U+624B "手" */ - 0x0, 0x0, 0x0, 0x0, 0x1, 0x5a, 0x80, 0x0, - 0x0, 0x35, 0x67, 0x8b, 0xba, 0x87, 0x60, 0x0, - 0x0, 0x10, 0x0, 0xd, 0x10, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x0, 0xd, 0x10, 0x0, 0x10, 0x0, - 0x0, 0x56, 0x66, 0x6e, 0x66, 0x6a, 0xe2, 0x0, - 0x0, 0x11, 0x0, 0xd, 0x10, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x0, 0xd, 0x10, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x0, 0xd, 0x10, 0x0, 0x9, 0x30, - 0x27, 0x66, 0x66, 0x6e, 0x66, 0x66, 0x68, 0x60, - 0x0, 0x0, 0x0, 0xd, 0x10, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x0, 0xd, 0x10, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x0, 0xd, 0x10, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x11, 0x1e, 0x10, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x18, 0xfd, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x0, 0x41, 0x0, 0x0, 0x0, 0x0, - - /* U+624D "才" */ - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x0, 0x0, 0xd, 0x40, 0x0, 0x0, - 0x0, 0x0, 0x0, 0x0, 0xf, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x0, 0x0, 0xf, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x0, 0x0, 0xf, 0x0, 0x6, 0x60, - 0x5, 0x76, 0x66, 0x66, 0xef, 0x66, 0x66, 0x60, - 0x0, 0x0, 0x0, 0x7, 0xbf, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x0, 0x1e, 0x1f, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x0, 0xb5, 0xf, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x8, 0x70, 0xf, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x59, 0x0, 0xf, 0x0, 0x0, 0x0, - 0x0, 0x5, 0x70, 0x0, 0xf, 0x0, 0x0, 0x0, - 0x0, 0x65, 0x0, 0x0, 0xf, 0x0, 0x0, 0x0, - 0x6, 0x10, 0x0, 0x10, 0xf, 0x0, 0x0, 0x0, - 0x10, 0x0, 0x0, 0x4b, 0xfb, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x0, 0x0, 0x81, 0x0, 0x0, 0x0, - - /* U+6253 "打" */ - 0x0, 0x0, 0xa1, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, 0xe0, 0x0, 0x0, 0x0, 0x0, 0x50, - 0x0, 0x0, 0xe0, 0x4, 0x66, 0x6c, 0x67, 0x81, - 0x5, 0x66, 0xe6, 0xc3, 0x0, 0x1d, 0x0, 0x0, - 0x0, 0x0, 0xe0, 0x0, 0x0, 0x1d, 0x0, 0x0, - 0x0, 0x0, 0xe0, 0x0, 0x0, 0x1d, 0x0, 0x0, - 0x0, 0x0, 0xe6, 0x61, 0x0, 0x1d, 0x0, 0x0, - 0x1, 0x5a, 0xe2, 0x0, 0x0, 0x1d, 0x0, 0x0, - 0xb, 0x91, 0xe0, 0x0, 0x0, 0x1d, 0x0, 0x0, - 0x0, 0x0, 0xe0, 0x0, 0x0, 0x1d, 0x0, 0x0, - 0x0, 0x0, 0xe0, 0x0, 0x0, 0x1d, 0x0, 0x0, - 0x0, 0x0, 0xe0, 0x0, 0x0, 0x1d, 0x0, 0x0, - 0x1, 0x21, 0xe0, 0x0, 0x11, 0x2d, 0x0, 0x0, - 0x0, 0x7f, 0xb0, 0x0, 0x17, 0xfa, 0x0, 0x0, - 0x0, 0x4, 0x10, 0x0, 0x0, 0x40, 0x0, 0x0, - - /* U+6255 "払" */ - 0x0, 0x0, 0x81, 0x0, 0x0, 0x10, 0x0, 0x0, - 0x0, 0x0, 0xe0, 0x0, 0x4, 0xe2, 0x0, 0x0, - 0x0, 0x0, 0xe0, 0x0, 0x7, 0xa0, 0x0, 0x0, - 0x5, 0x66, 0xe6, 0xc2, 0xb, 0x50, 0x0, 0x0, - 0x0, 0x0, 0xe0, 0x0, 0xe, 0x0, 0x0, 0x0, - 0x0, 0x0, 0xe0, 0x0, 0x3a, 0x0, 0x0, 0x0, - 0x0, 0x0, 0xe5, 0x61, 0x85, 0x0, 0x0, 0x0, - 0x0, 0x5a, 0xe2, 0x0, 0xc0, 0x0, 0x0, 0x0, - 0xc, 0xa2, 0xe0, 0x1, 0xa0, 0x0, 0x70, 0x0, - 0x1, 0x0, 0xe0, 0x6, 0x40, 0x0, 0x55, 0x0, - 0x0, 0x0, 0xe0, 0xa, 0x0, 0x0, 0xd, 0x10, - 0x0, 0x0, 0xe0, 0x29, 0x0, 0x0, 0x9, 0x80, - 0x1, 0x11, 0xd0, 0xcb, 0x9a, 0x98, 0x69, 0xd0, - 0x0, 0x7f, 0xa0, 0x68, 0x41, 0x0, 0x4, 0xd0, - 0x0, 0x4, 0x0, 0x0, 0x0, 0x0, 0x0, 0x10, - - /* U+627E "找" */ - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, 0xc1, 0x0, 0x1b, 0x10, 0x0, 0x0, - 0x0, 0x0, 0xe0, 0x0, 0x1e, 0x8, 0x80, 0x0, - 0x0, 0x0, 0xe0, 0x0, 0x1d, 0x0, 0xb7, 0x0, - 0x5, 0x66, 0xe6, 0xc1, 0x1d, 0x0, 0x15, 0x0, - 0x1, 0x10, 0xe0, 0x13, 0x5e, 0x66, 0x7b, 0x50, - 0x0, 0x0, 0xe0, 0x24, 0x3d, 0x0, 0x0, 0x0, - 0x0, 0x0, 0xe1, 0x61, 0xe, 0x0, 0x26, 0x0, - 0x0, 0x5, 0xf8, 0x0, 0xd, 0x0, 0xca, 0x0, - 0x8, 0xe9, 0xe0, 0x0, 0xd, 0x18, 0xb0, 0x0, - 0x9, 0x20, 0xe0, 0x0, 0xa, 0xac, 0x10, 0x0, - 0x0, 0x0, 0xe0, 0x0, 0x8, 0xd1, 0x0, 0x0, - 0x0, 0x0, 0xe0, 0x0, 0x6a, 0xd2, 0x0, 0x60, - 0x0, 0x0, 0xe0, 0x18, 0x40, 0x3d, 0x20, 0x90, - 0x2, 0x66, 0xd0, 0x40, 0x0, 0x4, 0xea, 0xb0, - 0x0, 0x2d, 0x60, 0x0, 0x0, 0x0, 0x2a, 0xd0, - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - - /* U+6280 "技" */ - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x3, 0xb0, 0x0, 0x0, 0xc3, 0x0, 0x0, - 0x0, 0x3, 0xb0, 0x0, 0x0, 0xe0, 0x0, 0x0, - 0x0, 0x2, 0xb0, 0x0, 0x0, 0xe0, 0x0, 0x0, - 0x6, 0x67, 0xd7, 0xa4, 0x66, 0xe6, 0x6a, 0x90, - 0x0, 0x2, 0xb0, 0x0, 0x0, 0xe0, 0x0, 0x0, - 0x0, 0x2, 0xb0, 0x0, 0x0, 0xe0, 0x0, 0x0, - 0x0, 0x2, 0xc6, 0x55, 0x66, 0xd6, 0x7b, 0x0, - 0x1, 0x6b, 0xd1, 0x0, 0x60, 0x0, 0x96, 0x0, - 0xb, 0x93, 0xb0, 0x0, 0x52, 0x0, 0xe0, 0x0, - 0x0, 0x2, 0xb0, 0x0, 0x8, 0x8, 0x70, 0x0, - 0x0, 0x2, 0xb0, 0x0, 0x7, 0x7d, 0x0, 0x0, - 0x0, 0x2, 0xb0, 0x0, 0x4, 0xf5, 0x0, 0x0, - 0x1, 0x3, 0xb0, 0x0, 0x89, 0x2c, 0x81, 0x0, - 0x1, 0x8f, 0x90, 0x68, 0x30, 0x0, 0x8f, 0xb2, - 0x0, 0x4, 0x4, 0x0, 0x0, 0x0, 0x1, 0x20, - - /* U+628A "把" */ - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x4, 0xc0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x3, 0xa0, 0x9, 0x66, 0x66, 0x6b, 0x30, - 0x0, 0x3, 0xa0, 0xd, 0x0, 0xd0, 0xe, 0x0, - 0x6, 0x68, 0xc9, 0x8d, 0x0, 0xd0, 0xe, 0x0, - 0x0, 0x3, 0xa0, 0xd, 0x0, 0xd0, 0xe, 0x0, - 0x0, 0x3, 0xa0, 0xd, 0x0, 0xd0, 0xe, 0x0, - 0x0, 0x3, 0xc7, 0x4d, 0x66, 0xa6, 0x6e, 0x0, - 0x3, 0x8c, 0xc0, 0xd, 0x0, 0x0, 0x4, 0x0, - 0xb, 0x73, 0xa0, 0xd, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x3, 0xa0, 0xd, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x3, 0xa0, 0xd, 0x0, 0x0, 0x0, 0x40, - 0x0, 0x3, 0xa0, 0xd, 0x0, 0x0, 0x0, 0x70, - 0x1, 0x4, 0xa0, 0xd, 0x10, 0x0, 0x0, 0xc0, - 0x2, 0x9f, 0x80, 0x8, 0xdc, 0xcc, 0xcc, 0xd1, - 0x0, 0x4, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - - /* U+6295 "投" */ - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0xa4, 0x0, 0x11, 0x0, 0x40, 0x0, 0x0, - 0xb, 0x20, 0x3, 0xc6, 0x6e, 0x20, 0x0, 0x0, - 0xb2, 0x0, 0x3a, 0x0, 0xe0, 0x0, 0x16, 0x6d, - 0x7d, 0x45, 0x80, 0xe, 0x0, 0x0, 0x0, 0xb2, - 0x0, 0xa2, 0x0, 0xd0, 0x0, 0x0, 0xb, 0x20, - 0x39, 0x0, 0x7, 0xaa, 0x80, 0x0, 0xb8, 0x78, - 0x66, 0x66, 0x89, 0x0, 0x5, 0xbe, 0x30, 0x1, - 0x40, 0x8, 0x80, 0x1, 0xb2, 0xb2, 0x0, 0x7, - 0x0, 0xd1, 0x0, 0x0, 0xb, 0x20, 0x0, 0x44, - 0x68, 0x0, 0x0, 0x0, 0xb2, 0x0, 0x0, 0xbc, - 0x0, 0x0, 0x0, 0xb, 0x20, 0x0, 0x2c, 0xc1, - 0x0, 0x0, 0x42, 0xd2, 0x0, 0x69, 0x13, 0xd8, - 0x20, 0x0, 0x9c, 0x4, 0x73, 0x0, 0x1, 0x9e, - 0x50, 0x0, 0x2, 0x10, 0x0, 0x0, 0x0, 0x0, - - /* U+62BC "押" */ - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0xb3, 0x0, 0x0, 0x0, 0x0, 0x30, 0x0, - 0xd, 0x0, 0x2c, 0x66, 0xb6, 0x6f, 0x20, 0x0, - 0xd0, 0x2, 0xc0, 0xd, 0x0, 0xe0, 0x16, 0x5e, - 0x7c, 0x4c, 0x0, 0xd0, 0xe, 0x0, 0x0, 0xd0, - 0x2, 0xd6, 0x6e, 0x66, 0xe0, 0x0, 0xd, 0x0, - 0x2c, 0x0, 0xd0, 0xe, 0x0, 0x0, 0xd6, 0x52, - 0xc0, 0xd, 0x0, 0xe0, 0x1, 0x8f, 0x20, 0x2c, - 0x0, 0xd0, 0xe, 0x4, 0xe5, 0xd0, 0x2, 0xd6, - 0x6e, 0x66, 0xe0, 0x2, 0xd, 0x0, 0x14, 0x0, - 0xd0, 0x1, 0x0, 0x0, 0xd0, 0x0, 0x0, 0xd, - 0x0, 0x0, 0x0, 0xd, 0x0, 0x0, 0x0, 0xd0, - 0x0, 0x0, 0x21, 0xe0, 0x0, 0x0, 0xd, 0x0, - 0x0, 0x4, 0xdc, 0x0, 0x0, 0x0, 0xe0, 0x0, - 0x0, 0x1, 0x0, 0x0, 0x0, 0x4, 0x0, 0x0, - - /* U+62C5 "担" */ - 0x0, 0x2, 0x70, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x2, 0xc0, 0x0, 0x40, 0x0, 0x5, 0x0, - 0x0, 0x2, 0xb0, 0x0, 0xe6, 0x66, 0x6e, 0x10, - 0x4, 0x67, 0xd7, 0xb1, 0xd0, 0x0, 0x1d, 0x0, - 0x0, 0x2, 0xb0, 0x0, 0xd0, 0x0, 0x1d, 0x0, - 0x0, 0x2, 0xb0, 0x10, 0xe6, 0x66, 0x6d, 0x0, - 0x0, 0x2, 0xc7, 0x40, 0xd0, 0x0, 0x1d, 0x0, - 0x0, 0x4b, 0xc0, 0x0, 0xd0, 0x0, 0x1d, 0x0, - 0xb, 0xc4, 0xb0, 0x0, 0xd0, 0x0, 0x1d, 0x0, - 0x2, 0x2, 0xb0, 0x0, 0xe6, 0x66, 0x6e, 0x0, - 0x0, 0x2, 0xb0, 0x0, 0xd0, 0x0, 0x1c, 0x0, - 0x0, 0x2, 0xb0, 0x0, 0x20, 0x0, 0x0, 0x0, - 0x0, 0x3, 0xb0, 0x0, 0x0, 0x0, 0x3, 0x90, - 0x1, 0x8e, 0x80, 0x76, 0x66, 0x66, 0x66, 0x61, - 0x0, 0x5, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - - /* U+62C9 "拉" */ - 0x0, 0x1, 0xa1, 0x0, 0x3, 0x0, 0x0, 0x0, - 0x0, 0x0, 0xd0, 0x0, 0x7, 0x80, 0x0, 0x0, - 0x0, 0x0, 0xd0, 0x0, 0x0, 0xf2, 0x0, 0x0, - 0x4, 0x55, 0xe6, 0xa0, 0x0, 0x50, 0x3, 0x0, - 0x1, 0x11, 0xd1, 0x15, 0x76, 0x66, 0x69, 0x50, - 0x0, 0x0, 0xd0, 0x0, 0x0, 0x0, 0x40, 0x0, - 0x0, 0x0, 0xd4, 0x60, 0x50, 0x0, 0xc7, 0x0, - 0x0, 0x6, 0xe3, 0x0, 0x90, 0x0, 0xe1, 0x0, - 0x8, 0xd7, 0xd0, 0x0, 0x77, 0x2, 0xb0, 0x0, - 0x5, 0x20, 0xd0, 0x0, 0x4d, 0x5, 0x60, 0x0, - 0x0, 0x0, 0xd0, 0x0, 0x2e, 0x9, 0x10, 0x0, - 0x0, 0x0, 0xd0, 0x0, 0x4, 0x9, 0x0, 0x0, - 0x0, 0x12, 0xd0, 0x0, 0x0, 0x16, 0x0, 0x60, - 0x0, 0x7f, 0xa0, 0x76, 0x66, 0x66, 0x67, 0x92, - 0x0, 0x3, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - - /* U+62DB "招" */ - 0x0, 0x8, 0x30, 0x0, 0x0, 0x0, 0x1, 0x0, - 0x0, 0xa2, 0x5, 0x67, 0x86, 0x66, 0xd5, 0x0, - 0xa, 0x20, 0x0, 0x69, 0x0, 0xd, 0x1, 0x66, - 0xc7, 0xb4, 0x9, 0x50, 0x0, 0xe0, 0x0, 0xa, - 0x20, 0x0, 0xd0, 0x0, 0x1d, 0x0, 0x0, 0xa2, - 0x0, 0x58, 0x3, 0x25, 0xa0, 0x0, 0xa, 0x56, - 0x2a, 0x0, 0xa, 0xf4, 0x0, 0x5, 0xd7, 0x17, - 0x20, 0x0, 0x1, 0x20, 0x3e, 0x8b, 0x21, 0xd, - 0x66, 0x66, 0x7d, 0x0, 0x20, 0xa2, 0x0, 0xd0, - 0x0, 0x2, 0xb0, 0x0, 0xa, 0x20, 0xd, 0x0, - 0x0, 0x2b, 0x0, 0x0, 0xa2, 0x0, 0xd0, 0x0, - 0x2, 0xb0, 0x0, 0xb, 0x20, 0xd, 0x66, 0x66, - 0x7b, 0x0, 0x4c, 0xf0, 0x0, 0xc0, 0x0, 0x2, - 0x90, 0x0, 0x12, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, - - /* U+62E1 "拡" */ - 0x0, 0xb, 0x20, 0x0, 0x7, 0x50, 0x0, 0x0, - 0x0, 0xe, 0x0, 0x0, 0x0, 0xe4, 0x0, 0x0, - 0x0, 0xe, 0x0, 0x24, 0x22, 0x63, 0x25, 0x70, - 0x0, 0xe, 0x6, 0x3c, 0x44, 0x44, 0x44, 0x30, - 0x16, 0x6e, 0x66, 0x4b, 0x0, 0x10, 0x0, 0x0, - 0x0, 0xe, 0x0, 0x3b, 0x0, 0x7b, 0x0, 0x0, - 0x0, 0xe, 0x5, 0x3b, 0x0, 0xb5, 0x0, 0x0, - 0x0, 0x1e, 0x80, 0x3a, 0x0, 0xd0, 0x0, 0x0, - 0x18, 0xdf, 0x0, 0x49, 0x5, 0x70, 0x0, 0x0, - 0x3b, 0x1e, 0x0, 0x58, 0xa, 0x0, 0x20, 0x0, - 0x0, 0xe, 0x0, 0x85, 0x18, 0x0, 0x28, 0x0, - 0x0, 0xe, 0x0, 0xc0, 0x81, 0x0, 0xa, 0x50, - 0x0, 0xe, 0x4, 0x72, 0xeb, 0xa8, 0x68, 0xd0, - 0x6, 0xdd, 0x8, 0x0, 0x51, 0x0, 0x1, 0x70, - 0x0, 0x31, 0x20, 0x0, 0x0, 0x0, 0x0, 0x0, - - /* U+62EC "括" */ - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x3, 0xb0, 0x0, 0x0, 0x0, 0x15, 0x0, - 0x0, 0x2, 0xb0, 0x0, 0x25, 0x8a, 0xca, 0x20, - 0x0, 0x2, 0xb0, 0x24, 0x42, 0xe0, 0x0, 0x0, - 0x6, 0x67, 0xd7, 0x90, 0x0, 0xe0, 0x0, 0x0, - 0x0, 0x2, 0xb0, 0x0, 0x0, 0xe0, 0x0, 0x40, - 0x0, 0x2, 0xb0, 0x67, 0x66, 0xe6, 0x67, 0x92, - 0x0, 0x2, 0xb4, 0x50, 0x0, 0xe0, 0x0, 0x0, - 0x0, 0x49, 0xd3, 0x0, 0x0, 0xe0, 0x0, 0x0, - 0xd, 0xb5, 0xb0, 0xb, 0x66, 0xb6, 0x6d, 0x30, - 0x1, 0x2, 0xb0, 0xd, 0x10, 0x0, 0xe, 0x0, - 0x0, 0x2, 0xb0, 0xc, 0x10, 0x0, 0xe, 0x0, - 0x0, 0x2, 0xb0, 0xc, 0x10, 0x0, 0xe, 0x0, - 0x1, 0x35, 0xb0, 0xd, 0x66, 0x66, 0x6e, 0x0, - 0x0, 0x5f, 0x70, 0xd, 0x10, 0x0, 0xb, 0x0, - 0x0, 0x2, 0x0, 0x1, 0x0, 0x0, 0x0, 0x0, - - /* U+62ED "拭" */ - 0x0, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0xb, 0x60, 0x0, 0x0, 0xc4, 0x41, 0x0, - 0x0, 0xb, 0x20, 0x0, 0x0, 0xc3, 0x2e, 0x10, - 0x0, 0xb, 0x20, 0x0, 0x0, 0xb3, 0x6, 0x10, - 0x26, 0x6d, 0x7c, 0x35, 0x66, 0xc7, 0x6c, 0x60, - 0x2, 0xb, 0x20, 0x1, 0x0, 0xa3, 0x0, 0x0, - 0x0, 0xb, 0x20, 0x0, 0x0, 0x94, 0x0, 0x0, - 0x0, 0xb, 0x36, 0x30, 0x4, 0x85, 0x0, 0x0, - 0x1, 0x5e, 0x81, 0x46, 0xe6, 0x77, 0x0, 0x0, - 0x4f, 0x8c, 0x20, 0x0, 0xe0, 0x3a, 0x0, 0x0, - 0x2, 0xb, 0x20, 0x0, 0xe0, 0xd, 0x0, 0x0, - 0x0, 0xb, 0x20, 0x0, 0xe0, 0xa, 0x40, 0x20, - 0x0, 0xb, 0x20, 0x3, 0xe7, 0x53, 0xd0, 0x60, - 0x0, 0xc, 0x23, 0xe9, 0x20, 0x0, 0x9b, 0x90, - 0x5, 0xce, 0x0, 0x10, 0x0, 0x0, 0x9, 0xc0, - 0x0, 0x22, 0x0, 0x0, 0x0, 0x0, 0x0, 0x30, - - /* U+62FF "拿" */ - 0x0, 0x0, 0x0, 0x1, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x2, 0xe3, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x3, 0xc3, 0x62, 0x0, 0x0, 0x0, 0x0, - 0x8, 0xa1, 0x0, 0x98, 0x20, 0x0, 0x0, 0x58, - 0x46, 0x66, 0x69, 0x4a, 0xda, 0x62, 0x52, 0x8, - 0x66, 0x66, 0x6c, 0x21, 0x60, 0x0, 0x0, 0xb2, - 0x0, 0x0, 0xe0, 0x0, 0x0, 0x0, 0xb, 0x76, - 0x66, 0x6e, 0x0, 0x0, 0x0, 0x0, 0x30, 0x1, - 0x35, 0x99, 0x0, 0x0, 0x4, 0x45, 0x66, 0xe7, - 0x55, 0x41, 0x0, 0x0, 0x0, 0x0, 0xd, 0x10, - 0x1a, 0x10, 0x0, 0x5, 0x76, 0x66, 0xe6, 0x66, - 0x63, 0x20, 0x28, 0x66, 0x66, 0x6e, 0x66, 0x66, - 0x9c, 0x20, 0x0, 0x0, 0x0, 0xe1, 0x0, 0x0, - 0x0, 0x0, 0x0, 0x16, 0xce, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x0, 0x4, 0x20, 0x0, 0x0, 0x0, - - /* U+6301 "持" */ - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0xb3, 0x0, 0x0, 0xa4, 0x0, 0x0, 0x0, - 0xd, 0x0, 0x0, 0xc, 0x20, 0x0, 0x0, 0x0, - 0xd0, 0x4, 0x66, 0xd7, 0x6a, 0x70, 0x16, 0x6e, - 0x6d, 0x20, 0xc, 0x20, 0x0, 0x0, 0x0, 0xd0, - 0x0, 0x0, 0xc2, 0x0, 0x10, 0x0, 0xd, 0x4, - 0x76, 0x6a, 0x66, 0x6a, 0x60, 0x0, 0xd2, 0x61, - 0x0, 0x5, 0x90, 0x0, 0x0, 0x5e, 0x60, 0x0, - 0x0, 0x59, 0x4, 0x1, 0xe8, 0xd0, 0x37, 0x66, - 0x69, 0xb6, 0x84, 0x1, 0xd, 0x0, 0x24, 0x0, - 0x59, 0x0, 0x0, 0x0, 0xd0, 0x0, 0xa7, 0x5, - 0x90, 0x0, 0x0, 0xd, 0x0, 0x2, 0x90, 0x59, - 0x0, 0x0, 0x0, 0xe0, 0x0, 0x0, 0x5, 0x90, - 0x0, 0x4, 0xce, 0x0, 0x0, 0x8, 0xe6, 0x0, - 0x0, 0x2, 0x20, 0x0, 0x0, 0x5, 0x0, 0x0, - - /* U+6307 "指" */ - 0x0, 0x27, 0x0, 0x26, 0x0, 0x0, 0x0, 0x0, - 0x2, 0xc0, 0x3, 0xc0, 0x0, 0x66, 0x0, 0x0, - 0x2b, 0x0, 0x2b, 0x3, 0xba, 0x50, 0x4, 0x67, - 0xd7, 0xb4, 0xc5, 0x40, 0x0, 0x40, 0x11, 0x2b, - 0x0, 0x2b, 0x0, 0x0, 0x8, 0x0, 0x2, 0xb0, - 0x2, 0xe3, 0x22, 0x25, 0xe1, 0x0, 0x2b, 0x54, - 0x6, 0x88, 0x88, 0x84, 0x0, 0x3a, 0xc0, 0x1, - 0x86, 0x66, 0x6a, 0x20, 0xac, 0x4b, 0x0, 0x1d, - 0x0, 0x0, 0xe0, 0x2, 0x2, 0xb0, 0x0, 0xd0, - 0x0, 0xe, 0x0, 0x0, 0x2b, 0x0, 0xe, 0x66, - 0x66, 0xe0, 0x0, 0x2, 0xb0, 0x0, 0xd0, 0x0, - 0xe, 0x0, 0x11, 0x4b, 0x0, 0x1e, 0x66, 0x66, - 0xe0, 0x0, 0x6f, 0x70, 0x1, 0xc0, 0x0, 0xe, - 0x0, 0x0, 0x20, 0x0, 0x1, 0x0, 0x0, 0x0, - 0x0, - - /* U+6319 "挙" */ - 0x0, 0x2, 0x0, 0x14, 0x0, 0x9, 0x20, 0x0, - 0x0, 0x3, 0xb0, 0xa, 0x60, 0x1e, 0x30, 0x0, - 0x0, 0x0, 0xa8, 0x4, 0xc0, 0x83, 0x0, 0x0, - 0x0, 0x0, 0x23, 0x0, 0x21, 0x60, 0xa, 0x20, - 0x7, 0x66, 0x8c, 0x66, 0x69, 0x66, 0x67, 0x50, - 0x0, 0x0, 0xb3, 0x0, 0x2, 0x91, 0x0, 0x0, - 0x0, 0x8, 0x61, 0x46, 0xbe, 0x8c, 0x60, 0x0, - 0x0, 0x85, 0x34, 0x3d, 0x10, 0x2, 0xcf, 0x70, - 0x36, 0x46, 0x66, 0x6d, 0x66, 0x6c, 0x93, 0x0, - 0x0, 0x1, 0x0, 0xc, 0x0, 0x0, 0x1, 0x0, - 0x5, 0x66, 0x66, 0x6d, 0x66, 0x66, 0x7f, 0x50, - 0x1, 0x0, 0x0, 0xc, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x0, 0xd, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x6, 0xde, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x0, 0x32, 0x0, 0x0, 0x0, 0x0, - - /* U+6355 "捕" */ - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0xd, 0x30, 0x0, 0xc, 0x53, 0x0, 0x0, - 0x0, 0xd, 0x0, 0x0, 0xc, 0x2, 0xd1, 0x0, - 0x0, 0xd, 0x0, 0x11, 0x1c, 0x11, 0x64, 0x70, - 0x5, 0x6e, 0x7b, 0x55, 0x5d, 0x55, 0x55, 0x50, - 0x0, 0xd, 0x0, 0x0, 0xc, 0x0, 0x1, 0x0, - 0x0, 0xd, 0x0, 0xc6, 0x6d, 0x66, 0x6f, 0x10, - 0x0, 0xd, 0x74, 0xd0, 0xc, 0x0, 0xd, 0x0, - 0x1, 0x8f, 0x10, 0xd6, 0x6d, 0x66, 0x6d, 0x0, - 0x2f, 0x6d, 0x0, 0xd0, 0xc, 0x0, 0xd, 0x0, - 0x1, 0xd, 0x0, 0xd0, 0xc, 0x0, 0xd, 0x0, - 0x0, 0xd, 0x0, 0xd6, 0x6d, 0x66, 0x6d, 0x0, - 0x0, 0xd, 0x0, 0xd0, 0xc, 0x0, 0xd, 0x0, - 0x0, 0xd, 0x0, 0xd0, 0xc, 0x0, 0xd, 0x0, - 0x5, 0xbd, 0x0, 0xd0, 0xd, 0x15, 0xab, 0x0, - 0x0, 0x21, 0x0, 0x50, 0x4, 0x0, 0x41, 0x0, - - /* U+6368 "捨" */ - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0xb, 0x40, 0x0, 0xa, 0x10, 0x0, 0x0, - 0x0, 0xd, 0x10, 0x0, 0x5d, 0x40, 0x0, 0x0, - 0x0, 0xd, 0x10, 0x0, 0xc1, 0x72, 0x0, 0x0, - 0x2, 0x2d, 0x39, 0x9, 0x30, 0xb, 0x40, 0x0, - 0x4, 0x4d, 0x44, 0x84, 0x0, 0x6, 0xcb, 0x50, - 0x0, 0xd, 0x15, 0x33, 0x6c, 0x66, 0x38, 0x40, - 0x0, 0xd, 0x14, 0x10, 0xb, 0x10, 0x1, 0x0, - 0x0, 0x1d, 0x92, 0x76, 0x6d, 0x66, 0x7b, 0x10, - 0x1a, 0xce, 0x10, 0x0, 0xb, 0x10, 0x0, 0x0, - 0x7, 0xd, 0x10, 0x12, 0xb, 0x10, 0x41, 0x0, - 0x0, 0xd, 0x10, 0x2c, 0x66, 0x66, 0xd5, 0x0, - 0x0, 0xd, 0x10, 0x2a, 0x0, 0x0, 0xb2, 0x0, - 0x1, 0xd, 0x0, 0x2a, 0x0, 0x0, 0xb2, 0x0, - 0x4, 0xdd, 0x0, 0x2c, 0x66, 0x66, 0xd3, 0x0, - 0x0, 0x21, 0x0, 0x13, 0x0, 0x0, 0x40, 0x0, - - /* U+6388 "授" */ - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0xa, 0x30, 0x0, 0x0, 0x1, 0x67, 0x0, - 0x0, 0xc, 0x10, 0x34, 0x56, 0x89, 0x87, 0x0, - 0x0, 0xc, 0x10, 0x11, 0x5, 0x0, 0x7b, 0x0, - 0x16, 0x6d, 0x7b, 0x1b, 0x17, 0x80, 0xc2, 0x0, - 0x0, 0xc, 0x10, 0x7, 0x53, 0x73, 0x60, 0x0, - 0x0, 0xc, 0x12, 0x86, 0x66, 0x6a, 0x69, 0x60, - 0x0, 0xc, 0x86, 0xa0, 0x0, 0x0, 0xa, 0x30, - 0x1, 0x9f, 0x15, 0x30, 0x0, 0x2, 0x51, 0x0, - 0x3e, 0x4c, 0x10, 0x7, 0x96, 0x6c, 0xb0, 0x0, - 0x2, 0xc, 0x10, 0x0, 0x70, 0x2d, 0x0, 0x0, - 0x0, 0xc, 0x10, 0x0, 0x29, 0xc2, 0x0, 0x0, - 0x0, 0xc, 0x10, 0x0, 0x1d, 0xb0, 0x0, 0x0, - 0x0, 0xc, 0x10, 0x3, 0xb3, 0x6c, 0x50, 0x0, - 0x5, 0xce, 0x2, 0x86, 0x0, 0x3, 0xbf, 0x90, - 0x0, 0x22, 0x13, 0x0, 0x0, 0x0, 0x2, 0x0, - - /* U+6392 "排" */ - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0xc, 0x20, 0x0, 0xb4, 0xc, 0x20, 0x0, - 0x0, 0xd, 0x0, 0x0, 0xc0, 0xd, 0x0, 0x0, - 0x0, 0xd, 0x0, 0x0, 0xc0, 0xd, 0x0, 0x20, - 0x16, 0x6e, 0x89, 0x66, 0xd0, 0xd, 0x66, 0x90, - 0x0, 0xd, 0x0, 0x0, 0xc0, 0xd, 0x0, 0x0, - 0x0, 0xd, 0x1, 0x0, 0xc0, 0xd, 0x0, 0x0, - 0x0, 0xd, 0x72, 0x56, 0xd0, 0xd, 0x67, 0x90, - 0x17, 0xce, 0x0, 0x0, 0xc0, 0xd, 0x0, 0x0, - 0x2b, 0x1d, 0x0, 0x0, 0xc0, 0xd, 0x0, 0x0, - 0x0, 0xd, 0x5, 0x66, 0xd0, 0xd, 0x66, 0xc1, - 0x0, 0xd, 0x0, 0x0, 0xc0, 0xd, 0x0, 0x0, - 0x0, 0xd, 0x0, 0x0, 0xc0, 0xd, 0x0, 0x0, - 0x2, 0x1e, 0x0, 0x0, 0xc0, 0xd, 0x0, 0x0, - 0x3, 0xca, 0x0, 0x0, 0xd0, 0xd, 0x0, 0x0, - 0x0, 0x10, 0x0, 0x0, 0x20, 0x2, 0x0, 0x0, - - /* U+639B "掛" */ - 0x0, 0x9, 0x10, 0x0, 0x60, 0x0, 0x72, 0x0, - 0x0, 0xd, 0x0, 0x0, 0xd0, 0x0, 0xd1, 0x0, - 0x0, 0xd, 0x0, 0x0, 0xc0, 0x0, 0xd0, 0x0, - 0x0, 0xd, 0x22, 0x66, 0xd7, 0x90, 0xd0, 0x0, - 0x6, 0x6e, 0x64, 0x0, 0xc0, 0x0, 0xd0, 0x0, - 0x0, 0xd, 0x0, 0x0, 0xc0, 0x40, 0xd5, 0x0, - 0x0, 0xd, 0x4, 0x66, 0x76, 0x63, 0xd4, 0xc0, - 0x0, 0x1e, 0x60, 0x0, 0xd1, 0x0, 0xd0, 0xa5, - 0x18, 0xcd, 0x0, 0x0, 0xc0, 0x10, 0xd0, 0x11, - 0x8, 0xd, 0x2, 0x66, 0xd6, 0xa1, 0xd0, 0x0, - 0x0, 0xd, 0x0, 0x0, 0xc0, 0x0, 0xd0, 0x0, - 0x0, 0xd, 0x0, 0x0, 0xc0, 0x0, 0xd0, 0x0, - 0x0, 0xd, 0x0, 0x13, 0xd6, 0x52, 0xd0, 0x0, - 0x5, 0xda, 0x8, 0xe8, 0x20, 0x0, 0xd0, 0x0, - 0x0, 0x20, 0x0, 0x0, 0x0, 0x0, 0x20, 0x0, - - /* U+63A1 "採" */ - 0x0, 0x9, 0x20, 0x0, 0x0, 0x2, 0x68, 0x0, - 0x0, 0xd, 0x0, 0x35, 0x68, 0x99, 0x87, 0x10, - 0x0, 0xd, 0x0, 0x10, 0x12, 0x0, 0x5, 0x70, - 0x0, 0xd, 0x16, 0x65, 0xb, 0x40, 0xc, 0x40, - 0x16, 0x6e, 0x66, 0x1e, 0x34, 0xa0, 0x65, 0x0, - 0x0, 0xd, 0x0, 0x6, 0x11, 0x41, 0x50, 0x0, - 0x0, 0xd, 0x4, 0x10, 0x2, 0xc0, 0x1, 0x20, - 0x0, 0xd, 0x82, 0x66, 0x6c, 0xd6, 0x68, 0x80, - 0x18, 0xce, 0x0, 0x0, 0x5d, 0xb6, 0x0, 0x0, - 0x1a, 0xd, 0x0, 0x0, 0xc4, 0xa8, 0x10, 0x0, - 0x0, 0xd, 0x0, 0x8, 0x52, 0xa2, 0xb0, 0x0, - 0x0, 0xd, 0x0, 0x57, 0x2, 0xa0, 0x8a, 0x0, - 0x1, 0xd, 0x3, 0x60, 0x2, 0xa0, 0xb, 0xc3, - 0x5, 0xdd, 0x3, 0x0, 0x2, 0xb0, 0x0, 0x20, - 0x0, 0x21, 0x0, 0x0, 0x1, 0x20, 0x0, 0x0, - - /* U+63A2 "探" */ - 0x0, 0x2, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0xd, 0x30, 0x5, 0x0, 0x0, 0x0, 0x40, - 0x0, 0xd, 0x0, 0x2a, 0x66, 0x66, 0x68, 0xe1, - 0x0, 0xd, 0x0, 0x96, 0x21, 0x0, 0x7, 0x20, - 0x16, 0x6e, 0x6c, 0x40, 0xb9, 0x7, 0x60, 0x0, - 0x0, 0xd, 0x0, 0x6, 0x90, 0x0, 0x8d, 0x10, - 0x0, 0xd, 0x2, 0x57, 0x2, 0xc0, 0x9, 0x20, - 0x0, 0xd, 0x73, 0x30, 0x1, 0xb0, 0x0, 0x20, - 0x1, 0x8f, 0x12, 0x86, 0x6a, 0xd7, 0x68, 0xa0, - 0x2e, 0x5d, 0x0, 0x0, 0x5d, 0xb6, 0x0, 0x0, - 0x1, 0xd, 0x0, 0x0, 0xc3, 0xb5, 0x40, 0x0, - 0x0, 0xd, 0x0, 0x8, 0x51, 0xb0, 0xb2, 0x0, - 0x0, 0xd, 0x0, 0x67, 0x1, 0xb0, 0x3e, 0x50, - 0x0, 0xd, 0x5, 0x50, 0x1, 0xb0, 0x4, 0xb3, - 0x3, 0xbc, 0x11, 0x0, 0x2, 0xb0, 0x0, 0x0, - 0x0, 0x11, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - - /* U+63A5 "接" */ - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0xc, 0x20, 0x0, 0x19, 0x10, 0x0, 0x0, - 0x0, 0xd, 0x0, 0x0, 0x6, 0x70, 0x2, 0x0, - 0x0, 0xd, 0x1, 0x57, 0x66, 0x66, 0x6a, 0x20, - 0x16, 0x6e, 0x6c, 0x22, 0x70, 0xb, 0x50, 0x0, - 0x0, 0xd, 0x0, 0x0, 0xa5, 0x1a, 0x0, 0x0, - 0x0, 0xd, 0x3, 0x66, 0x86, 0x97, 0x6a, 0x80, - 0x0, 0xd, 0x34, 0x0, 0x2c, 0x0, 0x0, 0x0, - 0x0, 0x6e, 0x40, 0x0, 0x87, 0x0, 0x0, 0x0, - 0x4e, 0x6d, 0x16, 0x66, 0xe6, 0x66, 0x78, 0xb0, - 0x1, 0xd, 0x0, 0x6, 0x60, 0xa, 0x50, 0x0, - 0x0, 0xd, 0x0, 0x1c, 0x0, 0x3c, 0x0, 0x0, - 0x0, 0xd, 0x0, 0x3, 0x79, 0xd6, 0x0, 0x0, - 0x1, 0xd, 0x0, 0x0, 0x3c, 0x59, 0xc4, 0x0, - 0x3, 0xcc, 0x0, 0x49, 0x81, 0x0, 0x3e, 0x30, - 0x0, 0x11, 0x25, 0x30, 0x0, 0x0, 0x1, 0x10, - - /* U+63A7 "控" */ - 0x0, 0xa, 0x30, 0x0, 0x5, 0x0, 0x0, 0x0, - 0x0, 0xd, 0x10, 0x0, 0x5, 0xd1, 0x0, 0x0, - 0x0, 0xd, 0x10, 0x12, 0x0, 0x80, 0x0, 0x40, - 0x16, 0x6e, 0x89, 0x77, 0x55, 0x55, 0x58, 0xa0, - 0x0, 0xd, 0x10, 0xa1, 0x39, 0x3, 0x5, 0x0, - 0x0, 0xd, 0x10, 0x1, 0xd5, 0x2, 0xb5, 0x0, - 0x0, 0xd, 0x56, 0x1a, 0x20, 0x0, 0x1e, 0x40, - 0x1, 0x7f, 0x51, 0x60, 0x0, 0x0, 0x16, 0x30, - 0x3f, 0x6d, 0x10, 0x26, 0x67, 0x96, 0x98, 0x0, - 0x1, 0xd, 0x10, 0x0, 0x3, 0xa0, 0x0, 0x0, - 0x0, 0xd, 0x10, 0x0, 0x3, 0xa0, 0x0, 0x0, - 0x0, 0xd, 0x10, 0x0, 0x3, 0xa0, 0x0, 0x0, - 0x0, 0xd, 0x10, 0x0, 0x3, 0xa0, 0x2, 0x80, - 0x6, 0xae, 0x4, 0x76, 0x66, 0x66, 0x66, 0x61, - 0x0, 0x33, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - - /* U+63A8 "推" */ - 0x0, 0xa, 0x30, 0x2, 0xa0, 0x60, 0x0, 0x0, - 0x0, 0xc0, 0x0, 0x69, 0x3, 0xd0, 0x0, 0x0, - 0xc, 0x0, 0xa, 0x40, 0x8, 0x6, 0x11, 0x66, - 0xd6, 0xc3, 0xe6, 0x6d, 0x66, 0x74, 0x0, 0xc, - 0x0, 0x4f, 0x0, 0xd0, 0x0, 0x0, 0x0, 0xc0, - 0x18, 0xd0, 0xd, 0x1, 0x30, 0x0, 0xc, 0x75, - 0x5d, 0x66, 0xe6, 0x67, 0x0, 0x3a, 0xe0, 0x30, - 0xd0, 0xd, 0x0, 0x0, 0x4d, 0x2c, 0x0, 0xd, - 0x0, 0xd0, 0x3, 0x0, 0x10, 0xc0, 0x0, 0xd6, - 0x6e, 0x67, 0xa2, 0x0, 0xc, 0x0, 0xd, 0x0, - 0xd0, 0x0, 0x0, 0x0, 0xc0, 0x0, 0xd0, 0xd, - 0x0, 0x0, 0x1, 0xd, 0x0, 0xd, 0x66, 0xe6, - 0x6d, 0x60, 0x4c, 0xd0, 0x0, 0xd0, 0x0, 0x0, - 0x0, 0x0, 0x11, 0x0, 0x2, 0x0, 0x0, 0x0, - 0x0, - - /* U+63CF "描" */ - 0x0, 0x2, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0xd4, 0x0, 0xc, 0x40, 0xa5, 0x0, 0x0, - 0xc, 0x10, 0x0, 0xd0, 0xa, 0x20, 0x0, 0x0, - 0xc1, 0x4, 0x4d, 0x44, 0xb5, 0xa4, 0x16, 0x6d, - 0x7c, 0x32, 0xd2, 0x2a, 0x42, 0x10, 0x10, 0xc1, - 0x0, 0xd, 0x0, 0xa2, 0x0, 0x0, 0xc, 0x10, - 0x0, 0x50, 0x3, 0x1, 0x0, 0x0, 0xc2, 0x49, - 0x66, 0x69, 0x66, 0xe2, 0x0, 0x3e, 0x80, 0xa3, - 0x0, 0xd0, 0xd, 0x2, 0xda, 0xd1, 0xa, 0x30, - 0xd, 0x0, 0xd0, 0x4, 0xc, 0x10, 0xa7, 0x66, - 0xe6, 0x6d, 0x0, 0x0, 0xc1, 0xa, 0x30, 0xd, - 0x0, 0xd0, 0x0, 0xc, 0x10, 0xa3, 0x0, 0xd0, - 0xd, 0x0, 0x31, 0xd1, 0xa, 0x76, 0x6e, 0x66, - 0xe0, 0x3, 0xcc, 0x0, 0xa2, 0x0, 0x0, 0xb, - 0x0, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - - /* U+63D0 "提" */ - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0xb, 0x30, 0x3, 0x0, 0x0, 0x50, 0x0, - 0x0, 0xd, 0x0, 0xd, 0x66, 0x66, 0xe1, 0x0, - 0x0, 0xd, 0x1, 0xd, 0x0, 0x0, 0xd0, 0x0, - 0x6, 0x6e, 0x6b, 0x1d, 0x66, 0x66, 0xd0, 0x0, - 0x0, 0xd, 0x0, 0xd, 0x0, 0x0, 0xd0, 0x0, - 0x0, 0xd, 0x0, 0xd, 0x66, 0x66, 0xe0, 0x0, - 0x0, 0xd, 0x64, 0x6, 0x0, 0x0, 0x31, 0x10, - 0x2, 0x9f, 0x16, 0x76, 0x66, 0x96, 0x69, 0xa0, - 0x2e, 0x4d, 0x0, 0x43, 0x0, 0xd0, 0x0, 0x0, - 0x0, 0xd, 0x0, 0x87, 0x0, 0xd0, 0x7, 0x0, - 0x0, 0xd, 0x0, 0xc4, 0x0, 0xe6, 0x66, 0x20, - 0x0, 0xd, 0x2, 0x96, 0x40, 0xd0, 0x0, 0x0, - 0x3, 0x2d, 0x9, 0x0, 0x8b, 0xd2, 0x0, 0x10, - 0x2, 0xb9, 0x52, 0x0, 0x3, 0x9c, 0xef, 0x70, - 0x0, 0x0, 0x10, 0x0, 0x0, 0x0, 0x0, 0x0, - - /* U+63DB "換" */ - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0xc, 0x10, 0x0, 0x96, 0x0, 0x0, 0x0, - 0x0, 0xd, 0x0, 0x3, 0xf7, 0x6b, 0x30, 0x0, - 0x0, 0xd, 0x0, 0x1a, 0x10, 0x4b, 0x20, 0x0, - 0x16, 0x6e, 0x86, 0x50, 0x0, 0x80, 0x0, 0x0, - 0x0, 0xd, 0x0, 0xc6, 0x67, 0x66, 0x6e, 0x10, - 0x0, 0xd, 0x3, 0xd0, 0x87, 0x42, 0xd, 0x0, - 0x0, 0xd, 0x71, 0xd0, 0xb0, 0xb, 0x3d, 0x0, - 0x5, 0xbe, 0x0, 0xd6, 0x14, 0x24, 0x9d, 0x0, - 0xb, 0x2d, 0x0, 0xa0, 0x9, 0x70, 0xa, 0x0, - 0x0, 0xd, 0x5, 0x66, 0x6d, 0x76, 0x67, 0xc1, - 0x0, 0xd, 0x1, 0x0, 0x4a, 0x42, 0x0, 0x0, - 0x0, 0xd, 0x0, 0x1, 0xc1, 0x9, 0x20, 0x0, - 0x0, 0xd, 0x0, 0x2b, 0x30, 0x1, 0xd7, 0x30, - 0x5, 0xdb, 0x26, 0x60, 0x0, 0x0, 0x1b, 0xb2, - 0x0, 0x20, 0x20, 0x0, 0x0, 0x0, 0x0, 0x0, - - /* U+63EE "揮" */ - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0xd, 0x10, 0x12, 0x0, 0x0, 0x1, 0x40, - 0x0, 0xd, 0x0, 0x58, 0x66, 0x66, 0x6a, 0xc0, - 0x0, 0xd, 0x0, 0xd2, 0x0, 0xc1, 0x7, 0x0, - 0x0, 0xd, 0x33, 0x12, 0x22, 0xd2, 0x28, 0x10, - 0x16, 0x6e, 0x65, 0x25, 0x44, 0xd4, 0x44, 0x20, - 0x0, 0xd, 0x0, 0x18, 0x66, 0xe6, 0x6a, 0x20, - 0x0, 0xd, 0x4, 0x2b, 0x0, 0xd0, 0xd, 0x0, - 0x0, 0xe, 0x71, 0x1d, 0x66, 0xe6, 0x6e, 0x0, - 0x16, 0xcd, 0x0, 0x1b, 0x0, 0xd0, 0xd, 0x0, - 0x1c, 0x1d, 0x0, 0x2d, 0x66, 0xe6, 0x6d, 0x0, - 0x0, 0xd, 0x0, 0x2, 0x0, 0xd0, 0x2, 0x20, - 0x0, 0xd, 0x1, 0x86, 0x66, 0xe6, 0x68, 0x80, - 0x0, 0xd, 0x0, 0x0, 0x0, 0xd0, 0x0, 0x0, - 0x7, 0xda, 0x0, 0x0, 0x0, 0xd0, 0x0, 0x0, - 0x0, 0x51, 0x0, 0x0, 0x0, 0x60, 0x0, 0x0, - - /* U+63FA "揺" */ - 0x0, 0x9, 0x10, 0x0, 0x0, 0x2, 0x69, 0x0, - 0x0, 0xd, 0x0, 0x35, 0x79, 0xaa, 0x98, 0x20, - 0x0, 0xd, 0x0, 0x20, 0x3, 0x0, 0xb, 0x50, - 0x0, 0xd, 0x23, 0x53, 0x8, 0x50, 0x2c, 0x10, - 0x6, 0x6e, 0x64, 0xd, 0x22, 0xd0, 0x81, 0x0, - 0x0, 0xd, 0x0, 0x6, 0x10, 0x21, 0x22, 0x0, - 0x0, 0xd, 0x15, 0x47, 0x66, 0xa6, 0x7a, 0x10, - 0x0, 0x2e, 0x60, 0x0, 0x0, 0xd0, 0x0, 0x0, - 0x2c, 0xbd, 0x4, 0x66, 0x66, 0xe6, 0x69, 0xb0, - 0x7, 0xd, 0x1, 0x10, 0x0, 0xd0, 0x0, 0x0, - 0x0, 0xd, 0x0, 0xa4, 0x0, 0xd0, 0x9, 0x20, - 0x0, 0xd, 0x0, 0xb0, 0x0, 0xd0, 0xd, 0x0, - 0x0, 0xe, 0x0, 0xb0, 0x0, 0xd0, 0xd, 0x0, - 0x6, 0xec, 0x0, 0xc6, 0x66, 0x86, 0x6e, 0x0, - 0x0, 0x21, 0x0, 0x0, 0x0, 0x0, 0x3, 0x0, - - /* U+643A "携" */ - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0xb3, 0x0, 0x19, 0x26, 0x0, 0x0, 0x0, - 0xd, 0x0, 0x7, 0x90, 0xa6, 0x3, 0x0, 0x0, - 0xd0, 0x0, 0xd6, 0x6c, 0x66, 0x93, 0x17, 0x6e, - 0x89, 0x8d, 0x0, 0xc0, 0x6, 0x0, 0x0, 0xd0, - 0x35, 0xd6, 0x6d, 0x66, 0x50, 0x0, 0xd, 0x5, - 0xd, 0x66, 0xd6, 0x6a, 0x0, 0x0, 0xd8, 0x20, - 0xd0, 0xc, 0x0, 0x10, 0x4, 0xbf, 0x0, 0xe, - 0x66, 0xb6, 0x6a, 0x64, 0xe3, 0xd0, 0x0, 0x70, - 0x0, 0x3, 0x0, 0x1, 0xd, 0x0, 0x66, 0xe6, - 0x69, 0xb0, 0x0, 0x0, 0xd0, 0x0, 0x1c, 0x0, - 0xc8, 0x77, 0x0, 0xd, 0x0, 0x9, 0x50, 0x3, - 0x8, 0x60, 0x0, 0xd0, 0x5, 0xa0, 0x0, 0x0, - 0xc1, 0x5, 0xcc, 0x7, 0x60, 0x0, 0x19, 0xc9, - 0x0, 0x2, 0x13, 0x0, 0x0, 0x0, 0x5, 0x0, - - /* U+64C1 "擁" */ - 0x0, 0x7, 0x0, 0x0, 0x8, 0x0, 0x0, 0x0, - 0x0, 0xd, 0x0, 0x0, 0x6, 0x90, 0x0, 0x40, - 0x0, 0xc, 0x3, 0x69, 0x66, 0x66, 0x66, 0x93, - 0x0, 0xc, 0x10, 0x1c, 0x2, 0xc9, 0x40, 0x0, - 0x6, 0x6d, 0x74, 0x72, 0x37, 0x90, 0xa0, 0x20, - 0x0, 0xc, 0x0, 0x62, 0xdd, 0x66, 0xa6, 0xa2, - 0x0, 0xc, 0x27, 0x8b, 0x6e, 0x10, 0xd0, 0x0, - 0x0, 0xe, 0x50, 0x36, 0x3c, 0x66, 0xe6, 0xa1, - 0x2, 0xcc, 0x0, 0x82, 0xbc, 0x10, 0xd0, 0x0, - 0xd, 0x5c, 0x9, 0x9a, 0x7c, 0x10, 0xd0, 0x0, - 0x1, 0xc, 0x3, 0x1b, 0xc, 0x66, 0xe6, 0xa0, - 0x0, 0xc, 0x0, 0x46, 0xc, 0x10, 0xd0, 0x0, - 0x0, 0xc, 0x0, 0x90, 0xc, 0x10, 0xd0, 0x40, - 0x5, 0xda, 0x6, 0x0, 0xc, 0x66, 0x76, 0x74, - 0x0, 0x30, 0x0, 0x0, 0x4, 0x0, 0x0, 0x0, - - /* U+64C7 "擇" */ - 0x0, 0xa, 0x10, 0x10, 0x0, 0x0, 0x2, 0x0, - 0x0, 0xd, 0x0, 0xa6, 0x6b, 0x6c, 0x6d, 0x20, - 0x0, 0xd, 0x0, 0xa1, 0xb, 0xc, 0xc, 0x0, - 0x0, 0xd, 0x22, 0xa6, 0x6b, 0x6c, 0x6d, 0x0, - 0x6, 0x6e, 0x65, 0x50, 0x1, 0xa0, 0x3, 0x0, - 0x0, 0xd, 0x0, 0x26, 0x66, 0xc6, 0xb5, 0x0, - 0x0, 0xd, 0x22, 0x2, 0x1, 0xa0, 0x0, 0x20, - 0x0, 0xd, 0x61, 0x86, 0x66, 0x96, 0x68, 0x90, - 0x0, 0x9e, 0x0, 0x0, 0xa3, 0x8, 0x60, 0x0, - 0xe, 0x6d, 0x0, 0x0, 0x49, 0x7, 0x24, 0x0, - 0x3, 0xd, 0x0, 0x57, 0x66, 0xc6, 0x65, 0x0, - 0x0, 0xd, 0x5, 0x66, 0x66, 0xc6, 0x69, 0x90, - 0x0, 0xd, 0x1, 0x10, 0x1, 0xa0, 0x0, 0x0, - 0x5, 0xbc, 0x0, 0x0, 0x1, 0xa0, 0x0, 0x0, - 0x0, 0x31, 0x0, 0x0, 0x1, 0x40, 0x0, 0x0, - - /* U+64D4 "擔" */ - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0xb, 0x30, 0x0, 0x8a, 0x0, 0x0, 0x0, - 0x0, 0xd, 0x0, 0x0, 0xe7, 0x67, 0x70, 0x0, - 0x0, 0xd, 0x0, 0x9, 0x40, 0x8, 0x50, 0x0, - 0x0, 0xd, 0x14, 0x3d, 0x66, 0x69, 0x69, 0x90, - 0x6, 0x6e, 0x65, 0x4d, 0xc, 0x40, 0x85, 0x0, - 0x0, 0xd, 0x0, 0xd, 0x62, 0x3a, 0x9, 0x10, - 0x0, 0xd, 0x16, 0xe, 0x66, 0x6a, 0x68, 0xb0, - 0x0, 0xd, 0x80, 0xc, 0x0, 0x0, 0x23, 0x0, - 0x3, 0xbe, 0x0, 0x2a, 0x27, 0x66, 0x65, 0x0, - 0x1e, 0x4d, 0x0, 0x47, 0x17, 0x66, 0x6a, 0x0, - 0x0, 0xd, 0x0, 0x83, 0x30, 0x0, 0x4, 0x0, - 0x0, 0xd, 0x0, 0xb0, 0x79, 0x66, 0x6e, 0x0, - 0x1, 0xd, 0x5, 0x20, 0x75, 0x0, 0xd, 0x0, - 0x3, 0xdc, 0x25, 0x0, 0x79, 0x66, 0x6c, 0x0, - 0x0, 0x11, 0x0, 0x0, 0x10, 0x0, 0x0, 0x0, - - /* U+64DA "據" */ - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0xb, 0x10, 0x0, 0xb, 0x20, 0x0, 0x0, - 0x0, 0xd, 0x0, 0x0, 0xd, 0x66, 0x97, 0x0, - 0x0, 0xd, 0x0, 0x52, 0x2d, 0x22, 0x23, 0x30, - 0x0, 0xd, 0x23, 0xd4, 0x4b, 0x64, 0x49, 0x70, - 0x16, 0x6e, 0x65, 0xd0, 0x1c, 0x69, 0x43, 0x0, - 0x0, 0xd, 0x0, 0xc4, 0x4c, 0x0, 0x52, 0x0, - 0x0, 0xd, 0x13, 0xc0, 0x5, 0x99, 0x95, 0x0, - 0x0, 0xe, 0x70, 0xc5, 0x67, 0x86, 0x6a, 0x50, - 0x2, 0xbd, 0x0, 0xb0, 0x1d, 0x20, 0x48, 0x0, - 0x1e, 0x3d, 0x1, 0xa2, 0x74, 0xb4, 0x91, 0x0, - 0x0, 0xd, 0x4, 0x71, 0x58, 0x7a, 0x40, 0x0, - 0x0, 0xd, 0x8, 0x36, 0x36, 0xac, 0x73, 0x0, - 0x0, 0xd, 0x8, 0x3, 0x95, 0xc, 0xc, 0x90, - 0x6, 0xcb, 0x41, 0x43, 0x5, 0x8d, 0x0, 0x10, - 0x0, 0x41, 0x10, 0x0, 0x0, 0x42, 0x0, 0x0, - - /* U+652F "支" */ - 0x0, 0x0, 0x0, 0xa, 0x30, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x0, 0xd1, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, 0xd, 0x10, 0x0, 0x2a, 0x0, 0x76, - 0x66, 0x66, 0xe6, 0x66, 0x66, 0x63, 0x0, 0x0, - 0x0, 0xd, 0x10, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0xd1, 0x4, 0x10, 0x0, 0x0, 0x6, 0x86, - 0x66, 0x66, 0xe7, 0x0, 0x0, 0x0, 0x0, 0x50, - 0x0, 0x4c, 0x0, 0x0, 0x0, 0x0, 0x7, 0x10, - 0xd, 0x30, 0x0, 0x0, 0x0, 0x0, 0x1a, 0x8, - 0x80, 0x0, 0x0, 0x0, 0x0, 0x0, 0x6c, 0xc0, - 0x0, 0x0, 0x0, 0x0, 0x0, 0x7, 0xdc, 0x20, - 0x0, 0x0, 0x0, 0x0, 0x2b, 0x80, 0x4d, 0xb5, - 0x10, 0x0, 0x3, 0x88, 0x10, 0x0, 0x6, 0xcf, - 0xf7, 0x15, 0x30, 0x0, 0x0, 0x0, 0x0, 0x13, - 0x0, - - /* U+6539 "改" */ - 0x0, 0x0, 0x0, 0x0, 0x58, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x30, 0x9, 0x70, 0x0, 0x0, 0x26, - 0x66, 0x6e, 0x30, 0xd1, 0x0, 0x0, 0x0, 0x0, - 0x0, 0xd0, 0x4a, 0x0, 0x2, 0x50, 0x0, 0x0, - 0xd, 0xa, 0x86, 0x6a, 0x95, 0x0, 0x0, 0x0, - 0xd1, 0x85, 0x0, 0x94, 0x0, 0x1e, 0x66, 0x6c, - 0x70, 0x70, 0xb, 0x20, 0x0, 0xd0, 0x0, 0x2, - 0x8, 0x0, 0xd0, 0x0, 0xd, 0x0, 0x0, 0x0, - 0x63, 0x3a, 0x0, 0x0, 0xd0, 0x0, 0x0, 0x1, - 0xa9, 0x40, 0x0, 0xd, 0x0, 0x3, 0x40, 0x8, - 0xc0, 0x0, 0x0, 0xd0, 0x69, 0x30, 0x1, 0xcc, - 0x40, 0x0, 0x2f, 0xd4, 0x0, 0x3, 0xa1, 0x1d, - 0x60, 0x0, 0x70, 0x0, 0x17, 0x60, 0x0, 0x1c, - 0xc2, 0x0, 0x0, 0x13, 0x0, 0x0, 0x0, 0x2, - 0x0, - - /* U+653E "放" */ - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x5, 0x20, 0x0, 0x4, 0xc0, 0x0, 0x0, - 0x0, 0x0, 0xd4, 0x0, 0x7, 0x90, 0x0, 0x0, - 0x0, 0x0, 0x44, 0x2, 0xb, 0x30, 0x1, 0x10, - 0x6, 0x6a, 0x66, 0x6a, 0x2d, 0x66, 0x7b, 0x80, - 0x0, 0xe, 0x0, 0x0, 0x48, 0x0, 0x95, 0x0, - 0x0, 0xe, 0x0, 0x20, 0x86, 0x0, 0xb3, 0x0, - 0x0, 0xe, 0x66, 0xc5, 0x67, 0x0, 0xe0, 0x0, - 0x0, 0x1c, 0x0, 0xb1, 0x6, 0x23, 0xb0, 0x0, - 0x0, 0x2a, 0x0, 0xc0, 0x2, 0x88, 0x50, 0x0, - 0x0, 0x58, 0x0, 0xd0, 0x0, 0xad, 0x0, 0x0, - 0x0, 0x84, 0x0, 0xd0, 0x0, 0xab, 0x0, 0x0, - 0x0, 0xb0, 0x1, 0xd0, 0x7, 0x79, 0x90, 0x0, - 0x4, 0x62, 0x8b, 0x80, 0x76, 0x0, 0xbb, 0x20, - 0x7, 0x0, 0x18, 0x27, 0x20, 0x0, 0x9, 0xb2, - 0x10, 0x0, 0x0, 0x20, 0x0, 0x0, 0x0, 0x0, - - /* U+653F "政" */ - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x0, 0x0, 0x8, 0x80, 0x0, 0x0, - 0x0, 0x0, 0x0, 0x13, 0xc, 0x40, 0x0, 0x0, - 0x7, 0x66, 0xa6, 0x89, 0x1e, 0x0, 0x1, 0x0, - 0x0, 0x0, 0xb1, 0x0, 0x4c, 0x66, 0x8a, 0x80, - 0x0, 0x10, 0xb1, 0x0, 0x84, 0x0, 0xb3, 0x0, - 0x0, 0xe1, 0xb1, 0x20, 0xa5, 0x0, 0xd1, 0x0, - 0x0, 0xd0, 0xb6, 0x96, 0x46, 0x0, 0xd0, 0x0, - 0x0, 0xd0, 0xb1, 0x5, 0x7, 0x3, 0xa0, 0x0, - 0x0, 0xd0, 0xb1, 0x0, 0x4, 0x58, 0x60, 0x0, - 0x0, 0xd0, 0xb1, 0x0, 0x0, 0xbd, 0x10, 0x0, - 0x0, 0xd0, 0xb4, 0x65, 0x0, 0xba, 0x0, 0x0, - 0x3, 0xea, 0xb6, 0x0, 0x8, 0x9b, 0x50, 0x0, - 0x1d, 0x72, 0x0, 0x0, 0x95, 0x1, 0xd8, 0x10, - 0x0, 0x0, 0x0, 0x57, 0x10, 0x0, 0x1c, 0xb1, - 0x0, 0x0, 0x3, 0x0, 0x0, 0x0, 0x0, 0x0, - - /* U+6545 "故" */ - 0x0, 0x0, 0x81, 0x0, 0x2, 0xb1, 0x0, 0x0, - 0x0, 0x0, 0xd1, 0x0, 0x5, 0xb0, 0x0, 0x0, - 0x0, 0x0, 0xd0, 0x0, 0x9, 0x50, 0x0, 0x0, - 0x0, 0x0, 0xd0, 0x6, 0xd, 0x11, 0x14, 0x50, - 0x6, 0x66, 0xe6, 0x66, 0x4d, 0x55, 0x9a, 0x40, - 0x0, 0x0, 0xd0, 0x0, 0x77, 0x0, 0x86, 0x0, - 0x0, 0x0, 0xd0, 0x0, 0x75, 0x0, 0xa3, 0x0, - 0x0, 0xa6, 0xc6, 0xc5, 0x3, 0x40, 0xd0, 0x0, - 0x0, 0xd0, 0x0, 0xd0, 0x0, 0x81, 0xc0, 0x0, - 0x0, 0xd0, 0x0, 0xd0, 0x0, 0xa7, 0x60, 0x0, - 0x0, 0xd0, 0x0, 0xd0, 0x0, 0x6e, 0x0, 0x0, - 0x0, 0xd0, 0x0, 0xd0, 0x1, 0xbd, 0x30, 0x0, - 0x0, 0xd6, 0x66, 0xe0, 0x2b, 0x42, 0xd5, 0x0, - 0x0, 0x90, 0x0, 0x27, 0x70, 0x0, 0x3d, 0xb1, - 0x0, 0x0, 0x0, 0x40, 0x0, 0x0, 0x1, 0x10, - - /* U+6548 "效" */ - 0x0, 0x14, 0x0, 0x0, 0x9, 0x60, 0x0, 0x0, - 0x0, 0x97, 0x0, 0x0, 0xe4, 0x0, 0x0, 0x0, - 0x3, 0xc0, 0x52, 0x1d, 0x0, 0x0, 0x2, 0x86, - 0x66, 0x66, 0x56, 0x70, 0x2, 0x60, 0x0, 0xa4, - 0x19, 0x20, 0xa6, 0x68, 0xc5, 0x0, 0x2c, 0x0, - 0x3e, 0x1d, 0x0, 0x57, 0x0, 0xa, 0x20, 0x2, - 0x66, 0x52, 0x8, 0x40, 0x6, 0x32, 0x2, 0xe1, - 0x51, 0x60, 0xc0, 0x0, 0x20, 0x36, 0x95, 0x0, - 0x9, 0x1b, 0x0, 0x0, 0x0, 0x5e, 0x0, 0x0, - 0x8a, 0x50, 0x0, 0x0, 0xb, 0x8b, 0x0, 0x4, - 0xe0, 0x0, 0x0, 0x7, 0x60, 0xb6, 0x1, 0xbb, - 0x50, 0x0, 0x4, 0x60, 0x2, 0x52, 0x90, 0x1d, - 0x60, 0x4, 0x50, 0x0, 0x5, 0x60, 0x0, 0x2e, - 0xa1, 0x10, 0x0, 0x4, 0x0, 0x0, 0x0, 0x10, - 0x0, - - /* U+6557 "敗" */ - 0x0, 0x0, 0x0, 0x2, 0x0, 0xa2, 0x0, 0x0, - 0x3, 0xc6, 0x66, 0x6f, 0x12, 0xf1, 0x0, 0x0, - 0x2, 0xa0, 0x0, 0xd, 0x5, 0x90, 0x0, 0x20, - 0x2, 0xa0, 0x0, 0xd, 0x9, 0x86, 0x69, 0xc3, - 0x2, 0xc6, 0x66, 0x6d, 0xc, 0x0, 0xd, 0x0, - 0x2, 0xa0, 0x0, 0xd, 0x3a, 0x0, 0x2b, 0x0, - 0x2, 0xc6, 0x66, 0x6d, 0x72, 0x30, 0x58, 0x0, - 0x2, 0xa0, 0x0, 0xd, 0x40, 0x70, 0x94, 0x0, - 0x2, 0xa0, 0x0, 0xd, 0x0, 0x70, 0xd0, 0x0, - 0x3, 0xc6, 0x66, 0x6d, 0x0, 0x3b, 0x80, 0x0, - 0x1, 0x26, 0x25, 0x11, 0x0, 0x1f, 0x30, 0x0, - 0x0, 0x2d, 0x21, 0xd4, 0x0, 0xa5, 0xd1, 0x0, - 0x0, 0xa2, 0x0, 0x37, 0x9, 0x20, 0x5d, 0x30, - 0x7, 0x10, 0x0, 0x2, 0x61, 0x0, 0x5, 0xf5, - 0x0, 0x0, 0x0, 0x12, 0x0, 0x0, 0x0, 0x10, - - /* U+6559 "教" */ - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, 0xb2, 0x0, 0x0, 0x88, 0x0, 0x0, - 0x0, 0x0, 0xd0, 0x3, 0x20, 0xc4, 0x0, 0x0, - 0x0, 0x66, 0xe8, 0x8c, 0x60, 0xd0, 0x0, 0x0, - 0x0, 0x0, 0xd0, 0x78, 0x3, 0xb3, 0x37, 0x80, - 0x5, 0x66, 0xe6, 0xe8, 0xa8, 0x52, 0x6a, 0x20, - 0x0, 0x0, 0xb, 0x20, 0xa, 0x20, 0x67, 0x0, - 0x0, 0x66, 0xb9, 0x7a, 0x34, 0x50, 0x84, 0x0, - 0x0, 0x8, 0x31, 0x93, 0x50, 0x70, 0xb1, 0x0, - 0x1, 0x71, 0x39, 0x0, 0x0, 0x80, 0xc0, 0x0, - 0x3, 0x0, 0x4b, 0x35, 0x30, 0x59, 0x70, 0x0, - 0x4, 0x8a, 0xbb, 0x20, 0x0, 0x1f, 0x0, 0x0, - 0x3, 0x50, 0x49, 0x0, 0x0, 0xaa, 0x70, 0x0, - 0x0, 0x0, 0x49, 0x0, 0x9, 0x30, 0xc7, 0x0, - 0x0, 0x6, 0xb7, 0x4, 0x71, 0x0, 0x1c, 0xb1, - 0x0, 0x0, 0x60, 0x31, 0x0, 0x0, 0x0, 0x0, - - /* U+6562 "敢" */ - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x0, 0x10, 0x0, 0xc1, 0x0, 0x0, - 0x1, 0x66, 0x6a, 0x90, 0x3, 0xb0, 0x0, 0x0, - 0x0, 0x0, 0xb, 0x20, 0x6, 0x70, 0x0, 0x0, - 0x26, 0x66, 0x6d, 0x6a, 0x8a, 0x76, 0x69, 0x90, - 0x0, 0xd0, 0x0, 0xd0, 0xd, 0x0, 0x94, 0x0, - 0x0, 0xd0, 0x0, 0xd0, 0x4b, 0x0, 0xb2, 0x0, - 0x0, 0xd6, 0x66, 0xd0, 0x83, 0x30, 0xd0, 0x0, - 0x0, 0xd0, 0x0, 0xd1, 0x50, 0x71, 0xc0, 0x0, - 0x0, 0xd6, 0x66, 0xd2, 0x0, 0x95, 0x80, 0x0, - 0x0, 0xd0, 0x0, 0xd0, 0x0, 0x7d, 0x20, 0x0, - 0x0, 0xd1, 0x35, 0xe6, 0x30, 0x4e, 0x0, 0x0, - 0x4c, 0xea, 0x62, 0xd0, 0x0, 0xb8, 0x90, 0x0, - 0x5, 0x0, 0x0, 0xd0, 0x9, 0x10, 0xaa, 0x10, - 0x0, 0x0, 0x0, 0xd1, 0x61, 0x0, 0x9, 0xb1, - 0x0, 0x0, 0x0, 0x12, 0x0, 0x0, 0x0, 0x0, - - /* U+6570 "数" */ - 0x0, 0x0, 0x1, 0x0, 0x0, 0x10, 0x0, 0x0, - 0x0, 0x10, 0x1e, 0x3, 0x20, 0xd6, 0x0, 0x0, - 0x0, 0x93, 0xc, 0xb, 0x41, 0xe0, 0x0, 0x0, - 0x0, 0x3b, 0xc, 0x44, 0x5, 0x80, 0x0, 0x0, - 0x3, 0x68, 0x6d, 0x69, 0x9a, 0x86, 0x66, 0xd2, - 0x0, 0x10, 0xcd, 0x40, 0xd, 0x10, 0x4a, 0x0, - 0x0, 0x9, 0x3c, 0x7b, 0x56, 0x30, 0x58, 0x0, - 0x0, 0x82, 0xc, 0x4, 0x60, 0x60, 0x76, 0x0, - 0x4, 0x0, 0x67, 0x0, 0x0, 0x80, 0xa3, 0x0, - 0x3, 0x66, 0xd9, 0x6a, 0x10, 0x90, 0xd0, 0x0, - 0x1, 0x13, 0x90, 0x3b, 0x0, 0x68, 0xa0, 0x0, - 0x0, 0xb, 0x61, 0xb2, 0x0, 0x1f, 0x40, 0x0, - 0x0, 0x0, 0x3e, 0xd8, 0x0, 0x9b, 0xa0, 0x0, - 0x0, 0x3, 0xa4, 0x8, 0x59, 0x50, 0x9c, 0x40, - 0x4, 0x65, 0x0, 0x4, 0x71, 0x0, 0x7, 0xb2, - 0x0, 0x0, 0x0, 0x21, 0x0, 0x0, 0x0, 0x0, - - /* U+6574 "整" */ - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, 0xa6, 0x0, 0x2, 0xd0, 0x0, 0x0, - 0x4, 0x66, 0xc8, 0x6a, 0x77, 0x70, 0x1, 0x30, - 0x1, 0x10, 0xa3, 0x1, 0xb, 0x66, 0xaa, 0x70, - 0x0, 0xb6, 0xc8, 0x6d, 0x3a, 0x30, 0xa3, 0x0, - 0x0, 0xc0, 0xa3, 0xc, 0x70, 0x71, 0xd0, 0x0, - 0x0, 0xc6, 0xe8, 0x6b, 0x10, 0x5b, 0x60, 0x0, - 0x0, 0x19, 0xd9, 0x91, 0x0, 0x6e, 0x50, 0x0, - 0x0, 0x84, 0xa3, 0x75, 0x18, 0x50, 0xba, 0x40, - 0x16, 0x10, 0x71, 0x4, 0x40, 0x0, 0x97, 0x70, - 0x0, 0x28, 0x66, 0x69, 0xb6, 0x66, 0x62, 0x0, - 0x0, 0x0, 0x72, 0x5, 0x90, 0x6, 0x20, 0x0, - 0x0, 0x0, 0xd0, 0x5, 0xb6, 0x66, 0x40, 0x0, - 0x0, 0x0, 0xd0, 0x5, 0x90, 0x0, 0x1, 0x0, - 0x4, 0x66, 0xe6, 0x69, 0xb6, 0x66, 0x6e, 0x60, - 0x1, 0x10, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - - /* U+6587 "文" */ - 0x0, 0x0, 0x0, 0x7, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x0, 0x8, 0x80, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x0, 0x2, 0x70, 0x0, 0x6, 0x10, - 0x5, 0x76, 0x67, 0x66, 0x66, 0x97, 0x6a, 0x80, - 0x0, 0x0, 0x6, 0x0, 0x0, 0xe0, 0x0, 0x0, - 0x0, 0x0, 0x7, 0x0, 0x2, 0xc0, 0x0, 0x0, - 0x0, 0x0, 0x6, 0x20, 0x8, 0x70, 0x0, 0x0, - 0x0, 0x0, 0x1, 0x90, 0xd, 0x10, 0x0, 0x0, - 0x0, 0x0, 0x0, 0x92, 0x5a, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x0, 0x1b, 0xd2, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x0, 0xc, 0xb0, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x1, 0xb4, 0x7c, 0x30, 0x0, 0x0, - 0x0, 0x0, 0x59, 0x20, 0x4, 0xdc, 0x73, 0x10, - 0x0, 0x57, 0x30, 0x0, 0x0, 0x5, 0xcf, 0x70, - 0x3, 0x0, 0x0, 0x0, 0x0, 0x0, 0x1, 0x0, - - /* U+6599 "料" */ - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, 0xc1, 0x0, 0x0, 0x0, 0xd2, 0x0, - 0x1, 0x0, 0xd0, 0x10, 0x0, 0x0, 0xe0, 0x0, - 0x4, 0x60, 0xd0, 0xb4, 0x39, 0x0, 0xe0, 0x0, - 0x0, 0xe1, 0xd1, 0x80, 0x9, 0x70, 0xe0, 0x0, - 0x0, 0x60, 0xd5, 0x0, 0x1, 0x20, 0xe0, 0x0, - 0x3, 0x66, 0xe6, 0xb8, 0x0, 0x0, 0xe0, 0x0, - 0x0, 0x6, 0xe0, 0x0, 0x58, 0x0, 0xe0, 0x0, - 0x0, 0xc, 0xe9, 0x40, 0xa, 0x50, 0xe0, 0x0, - 0x0, 0x39, 0xd1, 0xd4, 0x1, 0x10, 0xe0, 0x91, - 0x0, 0xa1, 0xd0, 0x21, 0x1, 0x46, 0xe6, 0x51, - 0x5, 0x30, 0xd0, 0x37, 0x64, 0x10, 0xe0, 0x0, - 0x14, 0x0, 0xd0, 0x0, 0x0, 0x0, 0xe0, 0x0, - 0x0, 0x0, 0xd0, 0x0, 0x0, 0x0, 0xe0, 0x0, - 0x0, 0x0, 0xe0, 0x0, 0x0, 0x0, 0xf0, 0x0, - 0x0, 0x0, 0x40, 0x0, 0x0, 0x0, 0x40, 0x0, - - /* U+65AD "断" */ - 0x3, 0x0, 0x83, 0x0, 0x0, 0x0, 0x45, 0x1, - 0xe0, 0xb, 0x21, 0x3, 0x76, 0x88, 0x60, 0xc, - 0x71, 0xb2, 0x7a, 0x3a, 0x0, 0x0, 0x0, 0xc3, - 0xab, 0x2b, 0x13, 0xa0, 0x0, 0x0, 0xc, 0x5, - 0xb5, 0x20, 0x3a, 0x0, 0x0, 0x0, 0xc6, 0x6d, - 0x77, 0xa4, 0xc6, 0x66, 0xd4, 0xc, 0x3, 0xf4, - 0x0, 0x39, 0x1, 0xc0, 0x0, 0xc0, 0x8e, 0x69, - 0x3, 0x90, 0x1c, 0x0, 0xc, 0x9, 0xb2, 0x97, - 0x48, 0x1, 0xc0, 0x0, 0xc5, 0x2b, 0x21, 0x35, - 0x70, 0x1c, 0x0, 0xc, 0x40, 0xb2, 0x0, 0x93, - 0x1, 0xc0, 0x0, 0xc0, 0x9, 0x32, 0xb, 0x0, - 0x1c, 0x0, 0x4d, 0x66, 0x68, 0x88, 0x30, 0x1, - 0xc0, 0x0, 0x0, 0x0, 0x5, 0x40, 0x0, 0x1c, - 0x0, 0x0, 0x0, 0x1, 0x20, 0x0, 0x0, 0x10, - 0x0, - - /* U+65B0 "新" */ - 0x0, 0x0, 0x71, 0x0, 0x0, 0x0, 0x5, 0x0, - 0x0, 0x0, 0x49, 0x3, 0x2, 0x56, 0xaa, 0x40, - 0x2, 0x86, 0x67, 0x89, 0x53, 0xa0, 0x0, 0x0, - 0x0, 0x38, 0x0, 0xb5, 0x3, 0xa0, 0x0, 0x0, - 0x0, 0xb, 0x21, 0x80, 0x2, 0xa0, 0x0, 0x0, - 0x5, 0x68, 0x69, 0x67, 0xc4, 0xc6, 0x69, 0xc0, - 0x0, 0x0, 0x2a, 0x0, 0x2, 0xa0, 0xc1, 0x0, - 0x0, 0x0, 0x2a, 0x3, 0x23, 0x90, 0xc1, 0x0, - 0x1, 0x66, 0x7c, 0x68, 0x74, 0x80, 0xc1, 0x0, - 0x0, 0x16, 0x2a, 0x30, 0x6, 0x60, 0xc1, 0x0, - 0x0, 0x7a, 0x2a, 0x68, 0xa, 0x20, 0xc1, 0x0, - 0x0, 0xb0, 0x2a, 0xc, 0x1b, 0x0, 0xc1, 0x0, - 0x6, 0x31, 0x3a, 0x0, 0x81, 0x0, 0xc1, 0x0, - 0x3, 0x5, 0xe7, 0x5, 0x30, 0x0, 0xc1, 0x0, - 0x0, 0x0, 0x10, 0x11, 0x0, 0x0, 0x40, 0x0, - - /* U+65B7 "斷" */ - 0x4, 0x13, 0x20, 0x15, 0x0, 0x0, 0x17, 0x20, - 0xb, 0x47, 0x20, 0x65, 0x8, 0x67, 0x86, 0x40, - 0xa, 0x59, 0xb3, 0xa9, 0x5a, 0x30, 0x0, 0x0, - 0xa, 0x35, 0x70, 0x48, 0x9, 0x30, 0x0, 0x0, - 0xa, 0x38, 0x63, 0x97, 0x39, 0x30, 0x0, 0x0, - 0xa, 0x58, 0x57, 0x74, 0x79, 0x86, 0x89, 0x90, - 0xa, 0x76, 0x66, 0x6a, 0x19, 0x30, 0xd0, 0x0, - 0xa, 0x26, 0x60, 0x66, 0x9, 0x30, 0xd0, 0x0, - 0xa, 0x28, 0x72, 0x77, 0x2a, 0x20, 0xd0, 0x0, - 0xa, 0x78, 0xa4, 0x9a, 0xb, 0x10, 0xd0, 0x0, - 0xa, 0x26, 0x50, 0x65, 0xb, 0x0, 0xd0, 0x0, - 0xa, 0x4b, 0x76, 0xc8, 0x5a, 0x0, 0xd0, 0x0, - 0xb, 0x20, 0x2, 0x73, 0x74, 0x0, 0xd0, 0x0, - 0x9, 0x66, 0x66, 0x64, 0x70, 0x0, 0xe0, 0x0, - 0x0, 0x0, 0x0, 0x2, 0x0, 0x0, 0x40, 0x0, - - /* U+65B9 "方" */ - 0x0, 0x0, 0x0, 0x28, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x0, 0x8, 0xb0, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x0, 0x1, 0x70, 0x0, 0x2, 0x60, - 0x7, 0x66, 0x66, 0x7b, 0x66, 0x66, 0x68, 0x81, - 0x0, 0x0, 0x0, 0x4a, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x0, 0x59, 0x0, 0x0, 0x10, 0x0, - 0x0, 0x0, 0x0, 0x8a, 0x66, 0x69, 0xc0, 0x0, - 0x0, 0x0, 0x0, 0xb2, 0x0, 0x8, 0x70, 0x0, - 0x0, 0x0, 0x0, 0xc0, 0x0, 0xa, 0x50, 0x0, - 0x0, 0x0, 0x7, 0x60, 0x0, 0xc, 0x20, 0x0, - 0x0, 0x0, 0x1b, 0x0, 0x0, 0xe, 0x0, 0x0, - 0x0, 0x0, 0xa3, 0x0, 0x0, 0x1d, 0x0, 0x0, - 0x0, 0x8, 0x30, 0x3, 0x30, 0x7a, 0x0, 0x0, - 0x1, 0x62, 0x0, 0x0, 0x6f, 0xf3, 0x0, 0x0, - 0x2, 0x0, 0x0, 0x0, 0x4, 0x10, 0x0, 0x0, - - /* U+65BC "於" */ - 0x0, 0x5, 0x40, 0x0, 0x0, 0xb3, 0x0, 0x0, - 0x0, 0x0, 0xe1, 0x0, 0x1, 0xe4, 0x0, 0x0, - 0x0, 0x0, 0x50, 0x46, 0x5, 0x98, 0x0, 0x0, - 0x6, 0x7e, 0x66, 0x65, 0xa, 0x46, 0x40, 0x0, - 0x0, 0xe, 0x0, 0x0, 0x1c, 0x0, 0xc0, 0x0, - 0x0, 0xe, 0x0, 0x50, 0x74, 0x0, 0x7b, 0x0, - 0x0, 0xe, 0x66, 0xe4, 0x81, 0x0, 0xc, 0xc1, - 0x0, 0xd, 0x0, 0xd6, 0x2, 0xa9, 0x11, 0x30, - 0x0, 0x1b, 0x0, 0xd0, 0x0, 0x9, 0x80, 0x0, - 0x0, 0x49, 0x0, 0xd0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x74, 0x1, 0xc0, 0x30, 0x0, 0x0, 0x0, - 0x0, 0xb0, 0x3, 0xa0, 0x18, 0xb7, 0x10, 0x0, - 0x2, 0x63, 0x5a, 0x60, 0x0, 0x2c, 0xe1, 0x0, - 0x7, 0x0, 0x8a, 0x0, 0x0, 0x0, 0x92, 0x0, - 0x11, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - - /* U+65BD "施" */ - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x8, 0x0, 0x0, 0xa, 0x50, 0x0, 0x0, - 0x0, 0x6, 0xb0, 0x0, 0xe, 0x10, 0x0, 0x0, - 0x0, 0x0, 0x80, 0x30, 0x6b, 0x66, 0x69, 0xb0, - 0x5, 0x6a, 0x66, 0x96, 0xb0, 0x30, 0x0, 0x0, - 0x0, 0x1b, 0x0, 0x7, 0x20, 0xd3, 0x0, 0x0, - 0x0, 0x1b, 0x2, 0x22, 0xb1, 0xd0, 0x6, 0x0, - 0x0, 0x1d, 0x6b, 0x60, 0xd0, 0xd6, 0x6e, 0x10, - 0x0, 0x2a, 0x8, 0x42, 0xe7, 0xe0, 0xd, 0x0, - 0x0, 0x39, 0x9, 0x65, 0xd0, 0xd0, 0xd, 0x0, - 0x0, 0x57, 0x9, 0x30, 0xd0, 0xd0, 0xd, 0x0, - 0x0, 0x83, 0xa, 0x20, 0xd0, 0xd2, 0xb8, 0x0, - 0x0, 0xa0, 0xb, 0x10, 0xd0, 0xd0, 0x0, 0x50, - 0x3, 0x55, 0x5e, 0x0, 0xd0, 0x10, 0x0, 0xa0, - 0x6, 0x1, 0xc5, 0x0, 0xad, 0xcc, 0xcd, 0xb0, - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - - /* U+65C1 "旁" */ - 0x0, 0x0, 0x0, 0x2a, 0x10, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x0, 0x7, 0x50, 0x0, 0x93, 0x0, - 0x0, 0x47, 0x69, 0x66, 0x66, 0xa6, 0x64, 0x0, - 0x0, 0x0, 0x9, 0x70, 0x4, 0xb0, 0x0, 0x0, - 0x0, 0x40, 0x2, 0x80, 0x7, 0x0, 0x4, 0x0, - 0x0, 0xb6, 0x66, 0x68, 0x66, 0x66, 0x6f, 0x40, - 0x7, 0x80, 0x0, 0x8, 0x80, 0x0, 0x52, 0x0, - 0x3, 0x66, 0x66, 0x67, 0xd6, 0x66, 0x6c, 0x90, - 0x0, 0x10, 0x0, 0xd2, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x0, 0xf6, 0x66, 0x6a, 0x60, 0x0, - 0x0, 0x0, 0x5, 0x90, 0x0, 0xb, 0x30, 0x0, - 0x0, 0x0, 0xc, 0x20, 0x0, 0xe, 0x0, 0x0, - 0x0, 0x0, 0xa4, 0x0, 0x31, 0x4c, 0x0, 0x0, - 0x0, 0x48, 0x20, 0x0, 0x1a, 0xf5, 0x0, 0x0, - 0x4, 0x10, 0x0, 0x0, 0x0, 0x20, 0x0, 0x0, - - /* U+65C5 "旅" */ - 0x0, 0x8, 0x10, 0x0, 0x1b, 0x20, 0x0, 0x0, - 0x0, 0x3, 0xe0, 0x0, 0x5b, 0x0, 0x0, 0x0, - 0x0, 0x0, 0xa0, 0x10, 0x93, 0x0, 0x5, 0x10, - 0x6, 0x68, 0x66, 0xa6, 0xb6, 0x66, 0x68, 0x50, - 0x0, 0x2b, 0x0, 0x5, 0x30, 0x0, 0x51, 0x0, - 0x0, 0x2b, 0x0, 0x44, 0x10, 0x5a, 0x94, 0x0, - 0x0, 0x2c, 0x66, 0xd0, 0xd5, 0x60, 0x0, 0x0, - 0x0, 0x39, 0x1, 0xb0, 0xd0, 0x60, 0xa, 0x10, - 0x0, 0x58, 0x2, 0xa0, 0xd0, 0x63, 0x94, 0x0, - 0x0, 0x75, 0x2, 0x90, 0xd0, 0x46, 0x0, 0x0, - 0x0, 0xb1, 0x4, 0x80, 0xd0, 0xb, 0x0, 0x0, - 0x1, 0x90, 0x6, 0x60, 0xd0, 0x7, 0x90, 0x0, - 0x7, 0x14, 0x9d, 0x10, 0xd5, 0x70, 0xbb, 0x30, - 0x14, 0x0, 0x63, 0x0, 0xe7, 0x0, 0x9, 0xb1, - 0x0, 0x0, 0x0, 0x0, 0x10, 0x0, 0x0, 0x0, - - /* U+65CF "族" */ - 0x0, 0x16, 0x0, 0x0, 0x59, 0x0, 0x0, 0x0, - 0x0, 0x9, 0x60, 0x0, 0xa5, 0x0, 0x0, 0x0, - 0x0, 0x3, 0x40, 0x40, 0xd2, 0x22, 0x28, 0x50, - 0x5, 0x6c, 0x66, 0x76, 0x99, 0x44, 0x44, 0x30, - 0x0, 0xd, 0x0, 0x8, 0x7a, 0x0, 0x2, 0x0, - 0x0, 0xe, 0x6a, 0x51, 0xb6, 0x95, 0x6a, 0x10, - 0x0, 0xc, 0xc, 0x15, 0x40, 0xc0, 0x0, 0x0, - 0x0, 0x1c, 0xc, 0x5, 0x0, 0xc0, 0x0, 0x0, - 0x0, 0x2a, 0xc, 0x46, 0x66, 0xe6, 0x68, 0xd1, - 0x0, 0x58, 0xc, 0x11, 0x1, 0xc5, 0x0, 0x0, - 0x0, 0x83, 0xd, 0x0, 0x6, 0x76, 0x20, 0x0, - 0x0, 0xb0, 0xd, 0x0, 0x1c, 0x1, 0xb0, 0x0, - 0x4, 0x45, 0xc9, 0x1, 0xb2, 0x0, 0x6b, 0x10, - 0x6, 0x0, 0x51, 0x58, 0x10, 0x0, 0x8, 0xe3, - 0x0, 0x0, 0x3, 0x10, 0x0, 0x0, 0x0, 0x10, - - /* U+65E2 "既" */ - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x13, 0x0, - 0xc6, 0x66, 0xe1, 0x66, 0x6c, 0x67, 0x80, 0xd, - 0x0, 0xd, 0x6, 0x20, 0xd0, 0x0, 0x0, 0xd0, - 0x0, 0xd0, 0xb3, 0x1c, 0x0, 0x0, 0xd, 0x66, - 0x6d, 0xc, 0x2, 0xb0, 0x0, 0x0, 0xd0, 0x0, - 0xd0, 0xc0, 0x49, 0x0, 0x10, 0xd, 0x66, 0x6d, - 0x2d, 0x5a, 0xa5, 0x7a, 0x10, 0xd0, 0x0, 0x80, - 0x0, 0xa8, 0x0, 0x0, 0xd, 0x1, 0x0, 0x0, - 0xd, 0xc2, 0x0, 0x0, 0xd0, 0x9, 0x20, 0x4, - 0x8c, 0x0, 0x0, 0xd, 0x0, 0x6e, 0x10, 0xc1, - 0xc0, 0x3, 0x0, 0xd5, 0x92, 0xb4, 0x76, 0xc, - 0x0, 0x60, 0x1f, 0x90, 0x1, 0x57, 0x0, 0xc0, - 0xa, 0x0, 0x30, 0x0, 0x65, 0x0, 0x8, 0xcb, - 0xe3, 0x0, 0x0, 0x20, 0x0, 0x0, 0x0, 0x0, - 0x0, - - /* U+65E5 "日" */ - 0x20, 0x0, 0x0, 0x0, 0x30, 0xd6, 0x66, 0x66, - 0x66, 0xd5, 0xd1, 0x0, 0x0, 0x0, 0xb3, 0xc1, - 0x0, 0x0, 0x0, 0xb3, 0xc1, 0x0, 0x0, 0x0, - 0xb3, 0xc1, 0x0, 0x0, 0x0, 0xb3, 0xc6, 0x66, - 0x66, 0x66, 0xc3, 0xc1, 0x0, 0x0, 0x0, 0xb3, - 0xc1, 0x0, 0x0, 0x0, 0xb3, 0xc1, 0x0, 0x0, - 0x0, 0xb3, 0xc1, 0x0, 0x0, 0x0, 0xb3, 0xc1, - 0x0, 0x0, 0x0, 0xb3, 0xd6, 0x66, 0x66, 0x66, - 0xc3, 0xc0, 0x0, 0x0, 0x0, 0x92, 0x0, 0x0, - 0x0, 0x0, 0x0, - - /* U+65E6 "旦" */ - 0x0, 0x0, 0x96, 0x66, 0x66, 0x6b, 0x20, 0x0, - 0x0, 0x0, 0xe0, 0x0, 0x0, 0xe, 0x0, 0x0, - 0x0, 0x0, 0xe0, 0x0, 0x0, 0xe, 0x0, 0x0, - 0x0, 0x0, 0xe0, 0x0, 0x0, 0xe, 0x0, 0x0, - 0x0, 0x0, 0xe6, 0x66, 0x66, 0x6e, 0x0, 0x0, - 0x0, 0x0, 0xe0, 0x0, 0x0, 0xe, 0x0, 0x0, - 0x0, 0x0, 0xe0, 0x0, 0x0, 0xe, 0x0, 0x0, - 0x0, 0x0, 0xe0, 0x0, 0x0, 0xe, 0x0, 0x0, - 0x0, 0x0, 0xf6, 0x66, 0x66, 0x6e, 0x0, 0x0, - 0x0, 0x0, 0xe0, 0x0, 0x0, 0xb, 0x0, 0x0, - 0x0, 0x0, 0x10, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xb, 0x30, - 0x7, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x50, - - /* U+65E9 "早" */ - 0x0, 0x0, 0x30, 0x0, 0x0, 0x4, 0x10, 0x0, - 0x0, 0x0, 0xe6, 0x66, 0x66, 0x6c, 0x60, 0x0, - 0x0, 0x0, 0xd0, 0x0, 0x0, 0xa, 0x30, 0x0, - 0x0, 0x0, 0xe6, 0x66, 0x66, 0x6c, 0x30, 0x0, - 0x0, 0x0, 0xd0, 0x0, 0x0, 0xa, 0x30, 0x0, - 0x0, 0x0, 0xd0, 0x0, 0x0, 0xa, 0x30, 0x0, - 0x0, 0x0, 0xe6, 0x66, 0x66, 0x6c, 0x30, 0x0, - 0x0, 0x1, 0xa0, 0x0, 0xe0, 0x7, 0x10, 0x0, - 0x0, 0x0, 0x0, 0x0, 0xe0, 0x0, 0x1, 0x0, - 0x6, 0x76, 0x66, 0x66, 0xe6, 0x66, 0x6c, 0xa0, - 0x0, 0x0, 0x0, 0x0, 0xe0, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x0, 0x1, 0xe0, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x0, 0x1, 0xe0, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x0, 0x1, 0xe0, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x0, 0x0, 0x20, 0x0, 0x0, 0x0, - - /* U+65F6 "时" */ - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x0, 0x0, 0xc2, 0x0, 0x0, 0x0, - 0x20, 0x0, 0x0, 0xe0, 0x0, 0xc6, 0x67, 0xe0, - 0x0, 0x0, 0xe0, 0x0, 0xc1, 0x2, 0xc0, 0x0, - 0x0, 0xe0, 0x81, 0xc1, 0x2, 0xc7, 0x66, 0x66, - 0xe6, 0x63, 0xc1, 0x2, 0xc0, 0x0, 0x0, 0xe0, - 0x0, 0xc6, 0x67, 0xc0, 0x82, 0x0, 0xe0, 0x0, - 0xc1, 0x2, 0xc0, 0x2e, 0x10, 0xe0, 0x0, 0xc1, - 0x2, 0xc0, 0xb, 0x30, 0xe0, 0x0, 0xc1, 0x2, - 0xc0, 0x1, 0x0, 0xe0, 0x0, 0xc6, 0x67, 0xc0, - 0x0, 0x0, 0xe0, 0x0, 0xd1, 0x2, 0xb0, 0x0, - 0x0, 0xe0, 0x0, 0x70, 0x0, 0x0, 0x2, 0x34, - 0xe0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x4e, 0x90, - 0x0, 0x0, 0x0, 0x0, 0x0, 0x1, 0x0, 0x0, - - /* U+6607 "昇" */ - 0x0, 0x8, 0x66, 0x66, 0x66, 0x66, 0xb2, 0x0, - 0x0, 0xd1, 0x0, 0x0, 0x0, 0xe, 0x10, 0x0, - 0xd, 0x10, 0x0, 0x0, 0x0, 0xe0, 0x0, 0x0, - 0xc6, 0x66, 0x66, 0x66, 0x6e, 0x0, 0x0, 0xc, - 0x10, 0x0, 0x0, 0x0, 0xe0, 0x0, 0x0, 0xc6, - 0x66, 0x76, 0x66, 0x6c, 0x0, 0x0, 0x1, 0x15, - 0xcd, 0x10, 0xa3, 0x0, 0x0, 0x3, 0x66, 0xe1, - 0x0, 0xd, 0x10, 0x0, 0x0, 0x0, 0xe, 0x0, - 0x0, 0xd1, 0x3, 0x0, 0x66, 0x66, 0xe6, 0x66, - 0x6e, 0x66, 0xd7, 0x0, 0x0, 0x1d, 0x0, 0x0, - 0xc1, 0x0, 0x0, 0x0, 0x6, 0x70, 0x0, 0xd, - 0x10, 0x0, 0x0, 0x2, 0xc0, 0x0, 0x0, 0xd1, - 0x0, 0x0, 0x5, 0x91, 0x0, 0x0, 0xd, 0x10, - 0x0, 0x5, 0x20, 0x0, 0x0, 0x0, 0x40, 0x0, - 0x0, - - /* U+660E "明" */ - 0x0, 0x0, 0x0, 0x74, 0x44, 0x4a, 0x18, 0x66, - 0x6a, 0xc, 0x32, 0x22, 0xd0, 0xd0, 0x1, 0xc0, - 0xc1, 0x0, 0xd, 0xd, 0x0, 0x1b, 0xc, 0x10, - 0x0, 0xd0, 0xd0, 0x1, 0xb0, 0xc7, 0x66, 0x6d, - 0xd, 0x66, 0x6b, 0xc, 0x10, 0x0, 0xd0, 0xd0, - 0x1, 0xb0, 0xc0, 0x0, 0xd, 0xd, 0x0, 0x1b, - 0xd, 0x0, 0x0, 0xd0, 0xd6, 0x66, 0xb0, 0xe5, - 0x55, 0x5d, 0xd, 0x0, 0x1a, 0x1d, 0x0, 0x0, - 0xd0, 0x60, 0x0, 0x6, 0x70, 0x0, 0xd, 0x0, - 0x0, 0x1, 0xc0, 0x0, 0x0, 0xd0, 0x0, 0x0, - 0x92, 0x0, 0x43, 0x4c, 0x0, 0x2, 0x71, 0x0, - 0x0, 0x5f, 0x70, 0x0, 0x20, 0x0, 0x0, 0x0, - 0x10, 0x0, - - /* U+6613 "易" */ - 0x0, 0x9, 0x66, 0x66, 0x66, 0xc1, 0x0, 0x0, - 0xd, 0x10, 0x0, 0x0, 0xe0, 0x0, 0x0, 0xc, - 0x10, 0x0, 0x0, 0xe0, 0x0, 0x0, 0xc, 0x66, - 0x66, 0x66, 0xe0, 0x0, 0x0, 0xd, 0x10, 0x0, - 0x0, 0xe0, 0x0, 0x0, 0xd, 0x96, 0x66, 0x66, - 0xe0, 0x0, 0x0, 0x2, 0xe4, 0x0, 0x0, 0x10, - 0x0, 0x0, 0xa, 0xb6, 0x86, 0x68, 0x67, 0xd0, - 0x0, 0x68, 0x6, 0xa0, 0x5a, 0x4, 0xa0, 0x5, - 0x50, 0x1d, 0x10, 0xc3, 0x7, 0x70, 0x11, 0x1, - 0xb3, 0x5, 0xa0, 0xa, 0x40, 0x0, 0x58, 0x10, - 0x3c, 0x10, 0xd, 0x10, 0x4, 0x20, 0x5, 0xb1, - 0x20, 0x3c, 0x0, 0x0, 0x3, 0x74, 0x0, 0x2b, - 0xf5, 0x0, 0x0, 0x31, 0x0, 0x0, 0x1, 0x20, - 0x0, - - /* U+6614 "昔" */ - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x7, 0x70, 0x1, 0xc1, 0x0, 0x0, - 0x0, 0x0, 0x7, 0x60, 0x1, 0xd0, 0x1, 0x0, - 0x0, 0x46, 0x6a, 0xa6, 0x66, 0xe6, 0x8e, 0x20, - 0x0, 0x11, 0x7, 0x60, 0x0, 0xd0, 0x0, 0x0, - 0x0, 0x0, 0x7, 0x60, 0x0, 0xd0, 0x0, 0x10, - 0x5, 0x66, 0x6a, 0xa6, 0x66, 0xe6, 0x6a, 0xd1, - 0x2, 0x10, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x1, 0xa6, 0x66, 0x66, 0x6a, 0x70, 0x0, - 0x0, 0x0, 0xd0, 0x0, 0x0, 0x9, 0x50, 0x0, - 0x0, 0x0, 0xd0, 0x0, 0x0, 0x9, 0x40, 0x0, - 0x0, 0x0, 0xe6, 0x66, 0x66, 0x6c, 0x40, 0x0, - 0x0, 0x0, 0xd0, 0x0, 0x0, 0x9, 0x40, 0x0, - 0x0, 0x0, 0xd0, 0x0, 0x0, 0x9, 0x40, 0x0, - 0x0, 0x1, 0xe6, 0x66, 0x66, 0x6c, 0x40, 0x0, - 0x0, 0x0, 0x20, 0x0, 0x0, 0x2, 0x0, 0x0, - - /* U+661F "星" */ - 0x0, 0x9, 0x66, 0x66, 0x66, 0x6b, 0x20, 0x0, - 0x0, 0xb2, 0x0, 0x0, 0x0, 0xe0, 0x0, 0x0, - 0xb, 0x20, 0x0, 0x0, 0xe, 0x0, 0x0, 0x0, - 0xb7, 0x66, 0x66, 0x66, 0xe0, 0x0, 0x0, 0xb, - 0x20, 0x0, 0x0, 0xe, 0x0, 0x0, 0x0, 0xb7, - 0x66, 0x66, 0x66, 0xe0, 0x0, 0x0, 0x6, 0x30, - 0xd, 0x30, 0x1, 0x0, 0x0, 0x0, 0xc5, 0x0, - 0xe0, 0x0, 0x85, 0x0, 0x0, 0x3b, 0x66, 0x6e, - 0x66, 0x66, 0x50, 0x0, 0xa, 0x10, 0x0, 0xe0, - 0x0, 0x10, 0x0, 0x6, 0x24, 0x66, 0x6e, 0x66, - 0xac, 0x0, 0x0, 0x10, 0x0, 0x0, 0xe0, 0x0, - 0x0, 0x0, 0x0, 0x0, 0x0, 0xe, 0x0, 0x0, - 0x34, 0x1, 0x86, 0x66, 0x66, 0xa6, 0x66, 0x6a, - 0xa1, - - /* U+6620 "映" */ - 0x0, 0x0, 0x0, 0x0, 0x84, 0x0, 0x0, 0x0, - 0x1, 0x0, 0x0, 0x93, 0x0, 0x0, 0xa6, 0x6d, - 0x41, 0x10, 0x93, 0x3, 0x0, 0xb2, 0xd, 0x2, - 0xc6, 0xc8, 0x6d, 0x30, 0xa2, 0xd, 0x2, 0xa0, - 0x93, 0xc, 0x0, 0xa2, 0xd, 0x2, 0xa0, 0xa2, - 0xc, 0x0, 0xa7, 0x6e, 0x2, 0xa0, 0xb1, 0xc, - 0x0, 0xa2, 0xd, 0x2, 0xa0, 0xc0, 0xc, 0x63, - 0xa2, 0xd, 0x36, 0x66, 0xd8, 0x66, 0x64, 0xa2, - 0xd, 0x0, 0x3, 0xa5, 0x0, 0x0, 0xa7, 0x6e, - 0x0, 0xa, 0x32, 0x60, 0x0, 0xb2, 0xa, 0x0, - 0x49, 0x0, 0x92, 0x0, 0x71, 0x0, 0x5, 0x90, - 0x0, 0x1d, 0x50, 0x0, 0x2, 0x75, 0x0, 0x0, - 0x3, 0xe7, 0x0, 0x14, 0x0, 0x0, 0x0, 0x0, - 0x10, - - /* U+6625 "春" */ - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x0, 0x5b, 0x10, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x0, 0x7b, 0x0, 0x0, 0x55, 0x0, - 0x3, 0x66, 0x66, 0xc9, 0x66, 0x66, 0x65, 0x0, - 0x0, 0x0, 0x0, 0xd1, 0x0, 0x8, 0x10, 0x0, - 0x0, 0x56, 0x69, 0xc6, 0x66, 0x66, 0x30, 0x0, - 0x26, 0x66, 0x6d, 0x86, 0x66, 0x66, 0x6d, 0x60, - 0x0, 0x0, 0x96, 0x0, 0x0, 0x70, 0x0, 0x0, - 0x0, 0x7, 0x90, 0x0, 0x0, 0x48, 0x0, 0x0, - 0x0, 0x85, 0xb7, 0x66, 0x66, 0xf7, 0xb4, 0x0, - 0x36, 0x10, 0xb3, 0x0, 0x0, 0xe0, 0x2c, 0xa1, - 0x0, 0x0, 0xa8, 0x66, 0x66, 0xe0, 0x0, 0x0, - 0x0, 0x0, 0xa3, 0x0, 0x0, 0xe0, 0x0, 0x0, - 0x0, 0x0, 0xa3, 0x0, 0x0, 0xe0, 0x0, 0x0, - 0x0, 0x0, 0xb8, 0x66, 0x66, 0xe0, 0x0, 0x0, - 0x0, 0x0, 0x40, 0x0, 0x0, 0x40, 0x0, 0x0, - - /* U+6628 "昨" */ - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x0, 0x97, 0x0, 0x0, 0x0, 0x10, - 0x0, 0x20, 0xd, 0x30, 0x0, 0x0, 0xc, 0x66, - 0x7d, 0x2, 0xc0, 0x0, 0x4, 0x0, 0xb1, 0x2, - 0xb0, 0x88, 0xa6, 0x66, 0xa7, 0xb, 0x10, 0x2b, - 0xa, 0xe, 0x0, 0x0, 0x0, 0xb1, 0x2, 0xb5, - 0x20, 0xe0, 0x0, 0x0, 0xb, 0x66, 0x7b, 0x40, - 0xe, 0x66, 0x9a, 0x0, 0xb1, 0x2, 0xb0, 0x0, - 0xe0, 0x0, 0x0, 0xb, 0x10, 0x2b, 0x0, 0xe, - 0x0, 0x0, 0x0, 0xb1, 0x2, 0xb0, 0x0, 0xe4, - 0x45, 0xd3, 0xb, 0x10, 0x2b, 0x0, 0xe, 0x11, - 0x11, 0x10, 0xb6, 0x67, 0xb0, 0x0, 0xe0, 0x0, - 0x0, 0xb, 0x10, 0x13, 0x0, 0xe, 0x0, 0x0, - 0x0, 0x0, 0x0, 0x0, 0x0, 0xe0, 0x0, 0x0, - 0x0, 0x0, 0x0, 0x0, 0x3, 0x0, 0x0, 0x0, - - /* U+662F "是" */ - 0x0, 0x0, 0x96, 0x66, 0x66, 0xa5, 0x0, 0x0, - 0x0, 0xd, 0x10, 0x0, 0xb, 0x30, 0x0, 0x0, - 0x0, 0xc1, 0x0, 0x0, 0xb3, 0x0, 0x0, 0x0, - 0xc, 0x66, 0x66, 0x6c, 0x30, 0x0, 0x0, 0x0, - 0xc1, 0x0, 0x0, 0xb3, 0x0, 0x0, 0x0, 0xd, - 0x66, 0x66, 0x6c, 0x30, 0x0, 0x0, 0x0, 0x40, - 0x0, 0x0, 0x20, 0x35, 0x0, 0x76, 0x66, 0x66, - 0xb6, 0x66, 0x68, 0x81, 0x0, 0x1, 0xd2, 0xc, - 0x20, 0x0, 0x0, 0x0, 0x0, 0x4c, 0x0, 0xc7, - 0x66, 0x9c, 0x10, 0x0, 0xa, 0x90, 0xc, 0x20, - 0x0, 0x0, 0x0, 0x2, 0xb0, 0x82, 0xc2, 0x0, - 0x0, 0x0, 0x0, 0xb1, 0x0, 0x9e, 0x73, 0x21, - 0x12, 0x20, 0x82, 0x0, 0x0, 0x17, 0xbd, 0xff, - 0xd2, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, - - /* U+663C "昼" */ - 0x0, 0x0, 0x30, 0x0, 0x0, 0x0, 0x50, 0x0, - 0x0, 0x0, 0xe6, 0x66, 0x66, 0x66, 0xd1, 0x0, - 0x0, 0x0, 0xd0, 0x0, 0x0, 0x0, 0xc0, 0x0, - 0x0, 0x0, 0xe6, 0x66, 0x66, 0x86, 0xc0, 0x0, - 0x0, 0x3, 0x90, 0x0, 0x0, 0x71, 0x0, 0x0, - 0x0, 0x7, 0x50, 0x0, 0x0, 0xa, 0x10, 0x0, - 0x0, 0xc, 0xa6, 0x66, 0x66, 0x6e, 0xc5, 0x0, - 0x0, 0x65, 0xa1, 0x0, 0x0, 0x1b, 0x1c, 0xd4, - 0x1, 0x80, 0xa7, 0x66, 0x66, 0x6b, 0x0, 0x40, - 0x5, 0x0, 0xa1, 0x0, 0x0, 0x1b, 0x0, 0x0, - 0x0, 0x0, 0xa1, 0x0, 0x0, 0x1b, 0x0, 0x0, - 0x0, 0x0, 0xb6, 0x66, 0x66, 0x6a, 0x0, 0x0, - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8, 0x20, - 0x0, 0x76, 0x66, 0x66, 0x66, 0x66, 0x67, 0x50, - - /* U+6642 "時" */ - 0x0, 0x0, 0x0, 0x0, 0x82, 0x0, 0x0, 0x52, - 0x26, 0x10, 0x0, 0xc0, 0x0, 0x0, 0xd4, 0x4c, - 0x40, 0x0, 0xc0, 0x6, 0x0, 0xd0, 0xb, 0x14, - 0x66, 0xd6, 0x66, 0x20, 0xd0, 0xb, 0x10, 0x0, - 0xc0, 0x0, 0x0, 0xd0, 0xb, 0x44, 0x44, 0xd5, - 0x45, 0xc2, 0xd6, 0x6d, 0x21, 0x11, 0x11, 0x83, - 0x10, 0xd0, 0xb, 0x10, 0x0, 0x0, 0xb2, 0x50, - 0xd0, 0xb, 0x67, 0x66, 0x66, 0xd6, 0x74, 0xd0, - 0xb, 0x10, 0x57, 0x0, 0xb1, 0x0, 0xd6, 0x6d, - 0x10, 0xa, 0x50, 0xb1, 0x0, 0xd0, 0xb, 0x10, - 0x1, 0x20, 0xb1, 0x0, 0x60, 0x1, 0x0, 0x0, - 0x0, 0xc1, 0x0, 0x0, 0x0, 0x0, 0x1, 0x7c, - 0xe0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x3, 0x10, - 0x0, - - /* U+6669 "晩" */ - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x0, 0xa9, 0x0, 0x0, 0x0, 0x30, - 0x4, 0x0, 0x1e, 0x20, 0x11, 0x0, 0xd, 0x66, - 0xe4, 0xa, 0x96, 0x6b, 0xa0, 0x0, 0xd0, 0xd, - 0x4, 0xa0, 0x1, 0x90, 0x0, 0xd, 0x0, 0xd1, - 0xb9, 0x66, 0xa6, 0x6b, 0x10, 0xd0, 0xd, 0x52, - 0xa0, 0xd, 0x0, 0xd0, 0xd, 0x66, 0xe0, 0x2a, - 0x0, 0xd0, 0xd, 0x0, 0xd0, 0xd, 0x2, 0xc6, - 0x6e, 0x66, 0xd0, 0xd, 0x0, 0xd0, 0x27, 0xf, - 0x49, 0x4, 0x0, 0xd0, 0xd, 0x0, 0x1, 0xf3, - 0x90, 0x0, 0xd, 0x66, 0xe0, 0x0, 0x6a, 0x39, - 0x0, 0x10, 0xd0, 0xa, 0x0, 0xd, 0x33, 0x90, - 0x5, 0x4, 0x0, 0x0, 0xb, 0x60, 0x29, 0x0, - 0x90, 0x0, 0x0, 0x48, 0x20, 0x1, 0xdb, 0xbd, - 0x10, 0x0, 0x2, 0x0, 0x0, 0x0, 0x0, 0x0, - - /* U+666E "普" */ - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x9, 0x30, 0x0, 0xd2, 0x0, 0x0, - 0x0, 0x0, 0x2, 0xf1, 0x7, 0x50, 0x2, 0x0, - 0x0, 0x66, 0x66, 0xd6, 0x6b, 0x66, 0x8d, 0x30, - 0x0, 0x3, 0x0, 0xe0, 0xe, 0x0, 0x70, 0x0, - 0x0, 0x6, 0x70, 0xe0, 0xe, 0x5, 0xb1, 0x0, - 0x0, 0x0, 0xf0, 0xe0, 0xe, 0xa, 0x10, 0x0, - 0x0, 0x0, 0x30, 0xe0, 0xe, 0x22, 0x7, 0x70, - 0x17, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x50, - 0x0, 0x0, 0xa6, 0x66, 0x66, 0x6c, 0x20, 0x0, - 0x0, 0x0, 0xe0, 0x0, 0x0, 0xe, 0x0, 0x0, - 0x0, 0x0, 0xe0, 0x0, 0x0, 0xe, 0x0, 0x0, - 0x0, 0x0, 0xe6, 0x66, 0x66, 0x6e, 0x0, 0x0, - 0x0, 0x0, 0xe0, 0x0, 0x0, 0xe, 0x0, 0x0, - 0x0, 0x0, 0xe6, 0x66, 0x66, 0x6f, 0x0, 0x0, - 0x0, 0x0, 0x50, 0x0, 0x0, 0x4, 0x0, 0x0, - - /* U+666F "景" */ - 0x0, 0x0, 0x96, 0x66, 0x66, 0x69, 0x60, 0x0, - 0x0, 0x0, 0xd0, 0x0, 0x0, 0x8, 0x60, 0x0, - 0x0, 0x0, 0xe6, 0x66, 0x66, 0x6b, 0x60, 0x0, - 0x0, 0x0, 0xd0, 0x0, 0x0, 0x8, 0x60, 0x0, - 0x0, 0x1, 0xd6, 0x69, 0x96, 0x6a, 0x40, 0x0, - 0x0, 0x0, 0x0, 0x0, 0xc2, 0x0, 0x7, 0x50, - 0x6, 0x76, 0x66, 0x66, 0x66, 0x66, 0x66, 0x50, - 0x0, 0x0, 0xb6, 0x66, 0x66, 0x6d, 0x30, 0x0, - 0x0, 0x0, 0xc2, 0x0, 0x0, 0xd, 0x0, 0x0, - 0x0, 0x0, 0xc7, 0x66, 0x86, 0x6e, 0x0, 0x0, - 0x0, 0x0, 0x34, 0x0, 0xe0, 0x12, 0x0, 0x0, - 0x0, 0x0, 0x9c, 0x20, 0xe0, 0x39, 0x30, 0x0, - 0x0, 0x2a, 0x50, 0x0, 0xe0, 0x0, 0xbb, 0x0, - 0x5, 0x50, 0x0, 0x6b, 0xc0, 0x0, 0xa, 0x50, - 0x0, 0x0, 0x0, 0x5, 0x10, 0x0, 0x0, 0x0, - - /* U+6674 "晴" */ - 0x0, 0x0, 0x0, 0x0, 0x10, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x0, 0xb5, 0x0, 0x0, 0x86, 0x6a, - 0x36, 0x66, 0xc7, 0x68, 0xb0, 0xc0, 0xd, 0x0, - 0x0, 0xb3, 0x0, 0x0, 0xc0, 0xd, 0x0, 0x56, - 0xc7, 0x6c, 0x50, 0xc0, 0xd, 0x0, 0x0, 0xb3, - 0x0, 0x0, 0xc1, 0x1d, 0x36, 0x66, 0xc7, 0x66, - 0xc6, 0xc5, 0x5d, 0x0, 0x10, 0x0, 0x2, 0x0, - 0xc0, 0xd, 0x0, 0xd6, 0x66, 0x6e, 0x20, 0xc0, - 0xd, 0x0, 0xe6, 0x66, 0x6e, 0x0, 0xc0, 0xd, - 0x0, 0xd0, 0x0, 0xd, 0x0, 0xc6, 0x6e, 0x0, - 0xd6, 0x66, 0x6e, 0x0, 0xd0, 0xa, 0x0, 0xd0, - 0x0, 0xd, 0x0, 0x20, 0x0, 0x0, 0xd0, 0x0, - 0xd, 0x0, 0x0, 0x0, 0x0, 0xd0, 0x5, 0xae, - 0x0, 0x0, 0x0, 0x0, 0x30, 0x0, 0x32, 0x0, - - /* U+667A "智" */ - 0x0, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0xd1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x3c, 0x66, 0x8b, 0x8, 0x66, 0x6b, 0x10, 0x9, - 0x12, 0xa0, 0x0, 0xd0, 0x0, 0xd0, 0x2, 0x30, - 0x48, 0x3, 0xd, 0x0, 0xd, 0x0, 0x76, 0x69, - 0xa6, 0xa4, 0xd0, 0x0, 0xd0, 0x0, 0x0, 0xb8, - 0x30, 0xd, 0x0, 0xd, 0x0, 0x0, 0x4a, 0x9, - 0xb0, 0xd6, 0x66, 0xd0, 0x0, 0x3a, 0x10, 0xa, - 0x15, 0x0, 0x3, 0x0, 0x55, 0xc, 0x66, 0x66, - 0x66, 0xd4, 0x0, 0x0, 0x0, 0xc0, 0x0, 0x0, - 0xd, 0x0, 0x0, 0x0, 0xc, 0x66, 0x66, 0x66, - 0xe0, 0x0, 0x0, 0x0, 0xc0, 0x0, 0x0, 0xd, - 0x0, 0x0, 0x0, 0xc, 0x0, 0x0, 0x0, 0xd0, - 0x0, 0x0, 0x0, 0xd6, 0x66, 0x66, 0x6e, 0x0, - 0x0, 0x0, 0x3, 0x0, 0x0, 0x0, 0x30, 0x0, - - /* U+6687 "暇" */ - 0x0, 0x0, 0x21, 0x14, 0x12, 0x22, 0x60, 0x8, - 0x66, 0xa5, 0x95, 0xc3, 0x44, 0x4d, 0x10, 0xc0, - 0xc, 0x46, 0xb, 0x0, 0x0, 0xc0, 0xc, 0x0, - 0xc4, 0x60, 0xb0, 0x0, 0xc, 0x0, 0xc0, 0xc, - 0x4a, 0x6d, 0x16, 0x66, 0xd0, 0xc, 0x66, 0xc4, - 0x60, 0x30, 0x0, 0x1, 0x0, 0xc0, 0xc, 0x46, - 0x2, 0x23, 0x33, 0x81, 0xc, 0x0, 0xc4, 0xa6, - 0x72, 0x73, 0x3e, 0x10, 0xc0, 0xc, 0x46, 0x0, - 0x6, 0x4, 0x90, 0xc, 0x66, 0xc4, 0xa6, 0xb2, - 0x44, 0xb3, 0x0, 0xc0, 0x8, 0x46, 0x0, 0x0, - 0xca, 0x0, 0x3, 0x0, 0x4, 0x60, 0x0, 0x2c, - 0xb0, 0x0, 0x0, 0x0, 0x56, 0x0, 0x39, 0x6, - 0xd5, 0x0, 0x0, 0x5, 0x60, 0x54, 0x0, 0x4, - 0x81, 0x0, 0x0, 0x0, 0x10, 0x0, 0x0, 0x0, - 0x0, - - /* U+6691 "暑" */ - 0x0, 0x0, 0x96, 0x66, 0x66, 0x6b, 0x20, 0x0, - 0x0, 0x0, 0xd0, 0x0, 0x0, 0xe, 0x0, 0x0, - 0x0, 0x0, 0xe6, 0x66, 0x66, 0x6e, 0x0, 0x0, - 0x0, 0x0, 0xe6, 0x66, 0x66, 0x6e, 0x10, 0x0, - 0x0, 0x0, 0x80, 0xd, 0x20, 0x6, 0xc9, 0x0, - 0x0, 0x3, 0x66, 0x6e, 0x6d, 0x2b, 0x90, 0x0, - 0x0, 0x0, 0x0, 0xe, 0x1, 0xc6, 0x3, 0x0, - 0x5, 0x76, 0x66, 0x6c, 0x8d, 0x96, 0x6c, 0x80, - 0x0, 0x0, 0x0, 0x29, 0x91, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x4d, 0xb7, 0x66, 0x6c, 0x70, 0x0, - 0x1, 0x57, 0x6b, 0x0, 0x0, 0xa, 0x40, 0x0, - 0x12, 0x0, 0x1d, 0x66, 0x66, 0x6c, 0x40, 0x0, - 0x0, 0x0, 0x1b, 0x0, 0x0, 0xa, 0x40, 0x0, - 0x0, 0x0, 0x2d, 0x66, 0x66, 0x6c, 0x40, 0x0, - 0x0, 0x0, 0x1, 0x0, 0x0, 0x2, 0x0, 0x0, - - /* U+6696 "暖" */ - 0x0, 0x0, 0x0, 0x0, 0x1, 0x59, 0x60, 0x30, - 0x4, 0x24, 0x56, 0x87, 0x66, 0x30, 0xd6, 0x6d, - 0x41, 0x50, 0x74, 0xe, 0x20, 0xd0, 0xb, 0x10, - 0x94, 0x29, 0x54, 0x0, 0xd0, 0xb, 0x16, 0x87, - 0x66, 0x97, 0xb0, 0xd0, 0xb, 0x10, 0x8, 0x50, - 0x0, 0x0, 0xd5, 0x5d, 0x36, 0x6c, 0x86, 0x66, - 0xb6, 0xd0, 0xb, 0x12, 0xd, 0x0, 0x0, 0x0, - 0xd0, 0xb, 0x10, 0x2d, 0x66, 0x6a, 0x30, 0xd0, - 0xb, 0x10, 0x97, 0x40, 0x4c, 0x10, 0xd6, 0x6d, - 0x21, 0xa0, 0x82, 0xd2, 0x0, 0xd0, 0x8, 0x1a, - 0x10, 0x2f, 0x50, 0x0, 0xa0, 0x0, 0x62, 0x1, - 0xa8, 0xd4, 0x0, 0x0, 0x1, 0x10, 0x58, 0x10, - 0x3d, 0xd7, 0x0, 0x0, 0x3, 0x10, 0x0, 0x0, - 0x50, - - /* U+6697 "暗" */ - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x0, 0xa2, 0x0, 0x0, 0x51, 0x15, - 0x0, 0x0, 0x58, 0x3, 0x30, 0xd5, 0x5d, 0x24, - 0x76, 0x66, 0x76, 0x50, 0xd0, 0xd, 0x0, 0x36, - 0x0, 0x97, 0x0, 0xd0, 0xd, 0x0, 0xb, 0x40, - 0xb0, 0x0, 0xd0, 0xd, 0x0, 0x4, 0x14, 0x30, - 0x72, 0xd6, 0x6e, 0x28, 0x66, 0x66, 0x66, 0x64, - 0xd0, 0xd, 0x0, 0x30, 0x0, 0x4, 0x0, 0xd0, - 0xd, 0x0, 0xe6, 0x66, 0x6e, 0x30, 0xd0, 0xd, - 0x0, 0xd0, 0x0, 0xd, 0x0, 0xd6, 0x6e, 0x0, - 0xd5, 0x55, 0x5e, 0x0, 0xd0, 0xb, 0x0, 0xd0, - 0x0, 0xd, 0x0, 0x40, 0x0, 0x0, 0xd6, 0x66, - 0x6e, 0x0, 0x0, 0x0, 0x0, 0xd0, 0x0, 0xc, - 0x10, 0x0, 0x0, 0x0, 0x10, 0x0, 0x0, 0x0, - - /* U+66C7 "曇" */ - 0x0, 0x11, 0x0, 0x0, 0x0, 0x40, 0x0, 0x0, - 0x4a, 0x66, 0x66, 0x66, 0xd3, 0x0, 0x0, 0x47, - 0x0, 0x0, 0x0, 0xc0, 0x0, 0x0, 0x4a, 0x66, - 0x66, 0x66, 0xd0, 0x0, 0x0, 0x4a, 0x66, 0x66, - 0x66, 0xc0, 0x0, 0x0, 0x33, 0x22, 0x22, 0x22, - 0x84, 0x0, 0x2, 0x33, 0x33, 0xc4, 0x33, 0x33, - 0x21, 0xa, 0x66, 0x66, 0xd6, 0x66, 0x66, 0xc8, - 0x77, 0x46, 0x60, 0xb1, 0x36, 0x61, 0x50, 0x0, - 0x46, 0x60, 0x80, 0x36, 0x60, 0x0, 0x0, 0x37, - 0x66, 0x66, 0x68, 0xa0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x2, 0xa0, 0x57, 0x66, 0x6a, 0xa6, - 0x66, 0x66, 0x62, 0x0, 0x0, 0x59, 0x20, 0x7, - 0x40, 0x0, 0x0, 0x2b, 0xa6, 0x67, 0x66, 0xd5, - 0x0, 0x0, 0x18, 0x53, 0x10, 0x0, 0x13, 0x0, - - /* U+66DC "曜" */ - 0x0, 0x0, 0x1, 0x11, 0x50, 0x11, 0x51, 0x96, - 0x6b, 0x38, 0x55, 0xd3, 0x75, 0xc3, 0xd0, 0xd, - 0x3, 0xc0, 0xc0, 0x97, 0xb1, 0xc0, 0xd, 0x0, - 0x41, 0xc0, 0x5, 0xb1, 0xc0, 0xd, 0x5, 0x75, - 0xc2, 0x86, 0xc1, 0xc6, 0x6d, 0xa5, 0x30, 0x79, - 0x30, 0x70, 0xc0, 0xd, 0x0, 0xe5, 0xb, 0x40, - 0x0, 0xc0, 0xd, 0x6, 0xa6, 0x6b, 0x86, 0xc2, - 0xc0, 0xd, 0x1e, 0x30, 0xb, 0x1, 0x0, 0xc6, - 0x6d, 0x6a, 0x75, 0x5d, 0x5a, 0x60, 0xd0, 0xd, - 0xa, 0x30, 0xb, 0x1, 0x0, 0xc0, 0x2, 0xa, - 0x76, 0x6d, 0x68, 0x60, 0x10, 0x0, 0xa, 0x30, - 0xb, 0x0, 0x40, 0x0, 0x0, 0xa, 0x76, 0x68, - 0x66, 0x94, 0x0, 0x0, 0x3, 0x0, 0x0, 0x0, - 0x0, - - /* U+66F2 "曲" */ - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x1, - 0xc0, 0xc, 0x20, 0x0, 0x0, 0x1, 0xc0, 0xd, - 0x0, 0x0, 0x0, 0x1, 0xc0, 0xd, 0x0, 0x0, - 0xa7, 0x66, 0xd6, 0x6e, 0x66, 0xc5, 0xb3, 0x1, - 0xc0, 0xd, 0x0, 0xc2, 0xb3, 0x1, 0xc0, 0xd, - 0x0, 0xc2, 0xa3, 0x1, 0xc0, 0xd, 0x0, 0xc2, - 0xa8, 0x66, 0xd6, 0x6e, 0x66, 0xd2, 0xa3, 0x1, - 0xc0, 0xd, 0x0, 0xc2, 0xa3, 0x1, 0xc0, 0xd, - 0x0, 0xc2, 0xa3, 0x1, 0xc0, 0xd, 0x0, 0xc2, - 0xb3, 0x1, 0xc0, 0xd, 0x0, 0xc2, 0xb8, 0x66, - 0xc6, 0x6c, 0x66, 0xd2, 0xb3, 0x0, 0x0, 0x0, - 0x0, 0xa1, 0x10, 0x0, 0x0, 0x0, 0x0, 0x0, - - /* U+66F4 "更" */ - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x7, 0x10, - 0x5, 0x76, 0x66, 0x67, 0xb6, 0x66, 0x68, 0x50, - 0x0, 0x0, 0x0, 0x2, 0xb0, 0x0, 0x10, 0x0, - 0x0, 0xd, 0x66, 0x67, 0xd6, 0x66, 0xf2, 0x0, - 0x0, 0xe, 0x0, 0x2, 0xb0, 0x0, 0xe0, 0x0, - 0x0, 0xe, 0x66, 0x67, 0xd6, 0x66, 0xe0, 0x0, - 0x0, 0xe, 0x0, 0x2, 0xb0, 0x0, 0xe0, 0x0, - 0x0, 0xe, 0x0, 0x3, 0xa0, 0x0, 0xe0, 0x0, - 0x0, 0xe, 0x66, 0x69, 0xb6, 0x66, 0xd0, 0x0, - 0x0, 0x0, 0x12, 0x8, 0x50, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x6, 0x3d, 0x10, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x0, 0xcb, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x2a, 0x75, 0xc8, 0x42, 0x10, 0x10, - 0x1, 0x57, 0x71, 0x0, 0x5, 0x9c, 0xef, 0x80, - 0x3, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - - /* U+66F8 "書" */ - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, 0xc, 0x30, 0x0, 0x0, 0x0, 0x0, - 0x36, 0x66, 0xe6, 0x66, 0x6b, 0x10, 0x0, 0x0, - 0x0, 0xd, 0x0, 0x0, 0xd1, 0x40, 0x47, 0x66, - 0x66, 0xe6, 0x66, 0x6e, 0x89, 0x10, 0x4, 0x66, - 0x6e, 0x66, 0x66, 0xd0, 0x0, 0x0, 0x0, 0x0, - 0xd0, 0x0, 0x5, 0x0, 0x0, 0x36, 0x66, 0x6e, - 0x66, 0x66, 0xa7, 0x0, 0x0, 0x0, 0x0, 0xd0, - 0x0, 0x0, 0x75, 0x5, 0x76, 0x66, 0x66, 0x66, - 0x66, 0x66, 0x50, 0x0, 0xc6, 0x66, 0x66, 0x66, - 0x6e, 0x10, 0x0, 0xd, 0x10, 0x0, 0x0, 0x0, - 0xd0, 0x0, 0x0, 0xc6, 0x66, 0x66, 0x66, 0x6d, - 0x0, 0x0, 0xc, 0x10, 0x0, 0x0, 0x0, 0xd0, - 0x0, 0x0, 0xd6, 0x66, 0x66, 0x66, 0x6e, 0x0, - 0x0, 0x4, 0x0, 0x0, 0x0, 0x0, 0x50, 0x0, - - /* U+66FE "曾" */ - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x9, - 0x10, 0x0, 0xb5, 0x0, 0x0, 0x4, 0xb0, 0x2, - 0xa0, 0x0, 0x9, 0x66, 0x96, 0x6a, 0x66, 0x88, - 0xd, 0x10, 0x0, 0xd0, 0x10, 0x67, 0xd, 0x1a, - 0x0, 0xd0, 0x97, 0x67, 0xd, 0x9, 0x60, 0xd1, - 0x90, 0x67, 0xd, 0x1, 0x10, 0xd3, 0x0, 0x67, - 0xd, 0x66, 0x66, 0x66, 0x66, 0x95, 0x0, 0x66, - 0x66, 0x66, 0x69, 0x20, 0x0, 0xa2, 0x0, 0x0, - 0xd, 0x0, 0x0, 0xa2, 0x0, 0x0, 0xd, 0x0, - 0x0, 0xa7, 0x66, 0x66, 0x6e, 0x0, 0x0, 0xa2, - 0x0, 0x0, 0xd, 0x0, 0x0, 0xa7, 0x66, 0x66, - 0x6e, 0x0, 0x0, 0x20, 0x0, 0x0, 0x2, 0x0, - - /* U+66FF "替" */ - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0xc0, 0x0, 0xc, 0x20, 0x0, 0x0, 0x0, - 0xd2, 0x40, 0xd, 0x5, 0x10, 0x3, 0x66, 0xd6, - 0x63, 0x6e, 0x66, 0x40, 0x0, 0x2, 0xa1, 0x30, - 0xd, 0x0, 0x50, 0x6, 0x69, 0xa6, 0x65, 0x7c, - 0x96, 0x71, 0x0, 0xb, 0x78, 0x0, 0x84, 0x71, - 0x0, 0x0, 0x57, 0x7, 0x75, 0x70, 0x1b, 0x30, - 0x4, 0x61, 0x0, 0x64, 0x0, 0x33, 0xd5, 0x22, - 0xe, 0x66, 0x66, 0x66, 0xd6, 0x0, 0x0, 0xd, - 0x0, 0x0, 0x0, 0xb2, 0x0, 0x0, 0xe, 0x66, - 0x66, 0x66, 0xd2, 0x0, 0x0, 0xd, 0x0, 0x0, - 0x0, 0xb2, 0x0, 0x0, 0xd, 0x0, 0x0, 0x0, - 0xb3, 0x0, 0x0, 0xe, 0x66, 0x66, 0x66, 0xd3, - 0x0, 0x0, 0x4, 0x0, 0x0, 0x0, 0x30, 0x0, - - /* U+6700 "最" */ - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x2, 0x86, 0x66, 0x66, 0x6b, 0x50, 0x0, - 0x0, 0x2, 0xd0, 0x0, 0x0, 0xb, 0x20, 0x0, - 0x0, 0x2, 0xe6, 0x66, 0x66, 0x6d, 0x20, 0x0, - 0x0, 0x2, 0xd0, 0x0, 0x0, 0xb, 0x20, 0x0, - 0x0, 0x2, 0xd6, 0x66, 0x66, 0x6c, 0x21, 0x0, - 0x5, 0x66, 0x66, 0x66, 0x66, 0x66, 0x7e, 0xa0, - 0x1, 0xe, 0x0, 0xd, 0x0, 0x0, 0x2, 0x0, - 0x0, 0xe, 0x66, 0x6d, 0x57, 0x66, 0xad, 0x0, - 0x0, 0xe, 0x0, 0xd, 0x5, 0x0, 0xc4, 0x0, - 0x0, 0xe, 0x66, 0x6d, 0x4, 0x24, 0xb0, 0x0, - 0x0, 0xe, 0x0, 0xd, 0x22, 0x9c, 0x10, 0x0, - 0x0, 0xe, 0x69, 0x8e, 0x30, 0x9a, 0x0, 0x0, - 0xb, 0xe9, 0x41, 0xd, 0x5, 0x68, 0xb3, 0x0, - 0x1, 0x0, 0x0, 0xd, 0x44, 0x0, 0x5e, 0xa1, - 0x0, 0x0, 0x0, 0x5, 0x10, 0x0, 0x0, 0x0, - - /* U+6703 "會" */ - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x0, 0x3e, 0x10, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x1, 0xc4, 0x70, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x1c, 0x30, 0x1a, 0x50, 0x0, 0x0, - 0x0, 0x3, 0xb8, 0x66, 0x6d, 0xed, 0x95, 0x31, - 0x0, 0x77, 0x0, 0x0, 0x0, 0x1, 0x9c, 0xb1, - 0x15, 0xb, 0x66, 0x69, 0x66, 0x66, 0xe1, 0x0, - 0x0, 0xd, 0x9, 0x2c, 0x3, 0xb0, 0xd0, 0x0, - 0x0, 0xd, 0x2, 0xac, 0x9, 0x20, 0xd0, 0x0, - 0x0, 0xc, 0x66, 0x69, 0x67, 0x66, 0xb0, 0x0, - 0x0, 0x0, 0x86, 0x66, 0x66, 0x69, 0x0, 0x0, - 0x0, 0x0, 0xc0, 0x0, 0x0, 0x2b, 0x0, 0x0, - 0x0, 0x0, 0xd6, 0x66, 0x66, 0x7a, 0x0, 0x0, - 0x0, 0x0, 0xc0, 0x0, 0x0, 0x2a, 0x0, 0x0, - 0x0, 0x0, 0xd6, 0x66, 0x66, 0x7b, 0x0, 0x0, - 0x0, 0x0, 0x60, 0x0, 0x0, 0x14, 0x0, 0x0, - - /* U+6708 "月" */ - 0x0, 0x0, 0x30, 0x0, 0x0, 0x5, 0x0, 0x0, - 0xd, 0x66, 0x66, 0x66, 0xe3, 0x0, 0x0, 0xd1, - 0x0, 0x0, 0xe, 0x0, 0x0, 0xd, 0x10, 0x0, - 0x0, 0xe0, 0x0, 0x0, 0xd6, 0x66, 0x66, 0x6e, - 0x0, 0x0, 0xd, 0x10, 0x0, 0x0, 0xe0, 0x0, - 0x0, 0xd0, 0x0, 0x0, 0xe, 0x0, 0x0, 0xe, - 0x0, 0x0, 0x0, 0xe0, 0x0, 0x0, 0xe6, 0x66, - 0x66, 0x6e, 0x0, 0x0, 0x1d, 0x0, 0x0, 0x0, - 0xe0, 0x0, 0x5, 0x90, 0x0, 0x0, 0xe, 0x0, - 0x0, 0xb2, 0x0, 0x0, 0x0, 0xe0, 0x0, 0x57, - 0x0, 0x0, 0x21, 0x1f, 0x0, 0x37, 0x0, 0x0, - 0x2, 0x7f, 0xc0, 0x3, 0x0, 0x0, 0x0, 0x0, - 0x30, 0x0, - - /* U+6709 "有" */ - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x0, 0xc, 0x40, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x0, 0x2e, 0x0, 0x0, 0x5, 0x10, - 0x6, 0x66, 0x66, 0xbb, 0x66, 0x66, 0x6c, 0x90, - 0x0, 0x0, 0x1, 0xd0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x9, 0x50, 0x0, 0x4, 0x10, 0x0, - 0x0, 0x0, 0x5d, 0x66, 0x66, 0x6c, 0x60, 0x0, - 0x0, 0x2, 0xcc, 0x0, 0x0, 0xb, 0x30, 0x0, - 0x0, 0x29, 0x2d, 0x66, 0x66, 0x6c, 0x30, 0x0, - 0x2, 0x70, 0x1c, 0x0, 0x0, 0xb, 0x30, 0x0, - 0x3, 0x0, 0x1c, 0x0, 0x0, 0xb, 0x30, 0x0, - 0x0, 0x0, 0x1d, 0x66, 0x66, 0x6c, 0x30, 0x0, - 0x0, 0x0, 0x1c, 0x0, 0x0, 0xb, 0x30, 0x0, - 0x0, 0x0, 0x1c, 0x0, 0x0, 0xb, 0x30, 0x0, - 0x0, 0x0, 0x2c, 0x0, 0x5, 0xbf, 0x10, 0x0, - 0x0, 0x0, 0x12, 0x0, 0x0, 0x23, 0x0, 0x0, - - /* U+670B "朋" */ - 0x0, 0x10, 0x0, 0x20, 0x0, 0x0, 0x2, 0x0, - 0xb, 0x66, 0x6e, 0x11, 0xc6, 0x66, 0xf1, 0x0, - 0xb1, 0x0, 0xd0, 0x1c, 0x0, 0xd, 0x0, 0xb, - 0x10, 0xd, 0x1, 0xc0, 0x0, 0xd0, 0x0, 0xb6, - 0x66, 0xd0, 0x1d, 0x66, 0x6d, 0x0, 0xb, 0x10, - 0xd, 0x1, 0xc0, 0x0, 0xd0, 0x0, 0xb1, 0x0, - 0xd0, 0x1c, 0x0, 0xd, 0x0, 0xb, 0x66, 0x6d, - 0x1, 0xd6, 0x66, 0xd0, 0x0, 0xc0, 0x0, 0xd0, - 0x2b, 0x0, 0xd, 0x0, 0xc, 0x0, 0xd, 0x3, - 0x90, 0x0, 0xd0, 0x0, 0xb0, 0x0, 0xd0, 0x66, - 0x0, 0xd, 0x0, 0x46, 0x0, 0xd, 0xa, 0x10, - 0x0, 0xd0, 0x8, 0x0, 0x68, 0xc3, 0x60, 0x0, - 0xd, 0x2, 0x40, 0x0, 0x95, 0x70, 0x2, 0x8f, - 0xa0, 0x10, 0x0, 0x0, 0x30, 0x0, 0x0, 0x40, - 0x0, - - /* U+670D "服" */ - 0x0, 0x20, 0x3, 0x0, 0x30, 0x0, 0x21, 0x0, - 0x0, 0xd6, 0x6c, 0x60, 0xe6, 0x66, 0xc8, 0x0, - 0x0, 0xd0, 0xa, 0x20, 0xd0, 0x0, 0xa3, 0x0, - 0x0, 0xd0, 0xa, 0x20, 0xd0, 0x0, 0xb2, 0x0, - 0x0, 0xd6, 0x6c, 0x20, 0xd0, 0x48, 0xe0, 0x0, - 0x0, 0xd0, 0xa, 0x20, 0xd0, 0x4, 0x20, 0x0, - 0x0, 0xd0, 0xa, 0x20, 0xd6, 0x55, 0x7c, 0x0, - 0x0, 0xd6, 0x6c, 0x20, 0xd3, 0x30, 0x78, 0x0, - 0x0, 0xc0, 0xa, 0x20, 0xd0, 0x70, 0xb2, 0x0, - 0x0, 0xc0, 0xa, 0x20, 0xd0, 0x74, 0xb0, 0x0, - 0x0, 0xb0, 0xa, 0x20, 0xd0, 0x1e, 0x30, 0x0, - 0x4, 0x60, 0xa, 0x20, 0xd0, 0x5a, 0xa0, 0x0, - 0x8, 0x4, 0x4c, 0x20, 0xd4, 0x60, 0x6e, 0x81, - 0x23, 0x0, 0x8c, 0x0, 0xe2, 0x0, 0x3, 0x30, - 0x0, 0x0, 0x0, 0x0, 0x10, 0x0, 0x0, 0x0, - - /* U+671B "望" */ - 0x0, 0x26, 0x0, 0x0, 0x0, 0x0, 0x10, 0x0, - 0x0, 0xc3, 0x0, 0x4a, 0x66, 0x6e, 0x30, 0x12, - 0x26, 0x25, 0x64, 0x80, 0x0, 0xd0, 0x3, 0x4d, - 0x44, 0x43, 0x4b, 0x66, 0x6e, 0x0, 0x0, 0xd0, - 0x0, 0x4, 0x70, 0x0, 0xd0, 0x0, 0xd, 0x0, - 0x34, 0x69, 0x66, 0x6e, 0x0, 0x1, 0xea, 0x93, - 0xa, 0x20, 0x0, 0xd0, 0x0, 0x1b, 0x30, 0x5, - 0x60, 0x4, 0xbc, 0x0, 0x0, 0x0, 0x4, 0x30, - 0x0, 0x2, 0x80, 0x0, 0x76, 0x66, 0x67, 0xd6, - 0x66, 0x66, 0x10, 0x0, 0x0, 0x0, 0x2b, 0x0, - 0x24, 0x0, 0x0, 0x6, 0x76, 0x67, 0xd6, 0x67, - 0x70, 0x0, 0x0, 0x0, 0x0, 0x2b, 0x0, 0x0, - 0x0, 0x4, 0x66, 0x66, 0x67, 0xd6, 0x66, 0x6c, - 0xc0, 0x11, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, - - /* U+671D "朝" */ - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0xa, 0x50, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0xa2, 0x2, 0x32, 0xb6, 0x6c, 0x60, 0x56, - 0x6c, 0x76, 0x76, 0x2b, 0x0, 0xa2, 0x0, 0x0, - 0xa2, 0x0, 0x1, 0xb0, 0xa, 0x20, 0xb, 0x6a, - 0x76, 0xe1, 0x1b, 0x0, 0xa2, 0x0, 0xd0, 0x0, - 0xd, 0x1, 0xd6, 0x6c, 0x20, 0xd, 0x66, 0x66, - 0xd0, 0x1b, 0x0, 0xa2, 0x0, 0xd0, 0x0, 0xd, - 0x2, 0xa0, 0xa, 0x20, 0xd, 0x67, 0x66, 0xd0, - 0x3c, 0x66, 0xc2, 0x0, 0x70, 0xa2, 0x3, 0x5, - 0x80, 0xa, 0x21, 0x66, 0x6c, 0x76, 0xa6, 0x94, - 0x0, 0xa2, 0x0, 0x0, 0xa2, 0x0, 0xc, 0x0, - 0xa, 0x20, 0x0, 0xa, 0x20, 0x8, 0x30, 0x20, - 0xb2, 0x0, 0x0, 0xa3, 0x5, 0x40, 0x2, 0xbe, - 0x0, 0x0, 0x3, 0x0, 0x10, 0x0, 0x0, 0x10, - - /* U+671F "期" */ - 0x0, 0xa, 0x10, 0x94, 0x0, 0x0, 0x0, 0x20, - 0x0, 0xe, 0x0, 0xb2, 0x2, 0xc6, 0x67, 0xd0, - 0x4, 0x6e, 0x66, 0xd9, 0xb3, 0xc0, 0x2, 0xb0, - 0x0, 0xe, 0x0, 0xb2, 0x1, 0xc0, 0x2, 0xb0, - 0x0, 0xe, 0x66, 0xd2, 0x1, 0xd6, 0x67, 0xb0, - 0x0, 0xe, 0x0, 0xb2, 0x1, 0xc0, 0x2, 0xb0, - 0x0, 0xe, 0x0, 0xb2, 0x1, 0xc0, 0x2, 0xb0, - 0x0, 0xe, 0x66, 0xd2, 0x2, 0xb0, 0x2, 0xb0, - 0x0, 0xe, 0x0, 0xb3, 0x23, 0xd5, 0x57, 0xb0, - 0x5, 0x69, 0x66, 0x89, 0x86, 0x90, 0x2, 0xb0, - 0x0, 0x8, 0x70, 0x70, 0x9, 0x60, 0x2, 0xb0, - 0x0, 0x2d, 0x10, 0x5c, 0x1d, 0x0, 0x2, 0xb0, - 0x0, 0xa1, 0x0, 0x7, 0x93, 0x0, 0x3, 0xb0, - 0x7, 0x10, 0x0, 0x7, 0x30, 0x1, 0x7f, 0x80, - 0x0, 0x0, 0x0, 0x20, 0x0, 0x0, 0x3, 0x0, - - /* U+6728 "木" */ - 0x0, 0x0, 0x0, 0xb, 0x40, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x0, 0xd, 0x10, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x0, 0xd, 0x10, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x0, 0xd, 0x10, 0x0, 0x6, 0x0, - 0x7, 0x66, 0x66, 0x9f, 0x86, 0x66, 0x8b, 0x40, - 0x0, 0x0, 0x0, 0xef, 0x60, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x5, 0xbd, 0x37, 0x0, 0x0, 0x0, - 0x0, 0x0, 0xd, 0x2d, 0x1a, 0x10, 0x0, 0x0, - 0x0, 0x0, 0x87, 0xd, 0x13, 0xb0, 0x0, 0x0, - 0x0, 0x4, 0xb0, 0xd, 0x10, 0x8a, 0x0, 0x0, - 0x0, 0x2a, 0x0, 0xd, 0x10, 0xb, 0xd5, 0x0, - 0x3, 0x80, 0x0, 0xd, 0x10, 0x0, 0xaf, 0x80, - 0x24, 0x0, 0x0, 0xe, 0x20, 0x0, 0x2, 0x0, - 0x0, 0x0, 0x0, 0xe, 0x20, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x0, 0x5, 0x0, 0x0, 0x0, 0x0, - - /* U+672A "未" */ - 0x0, 0x0, 0x0, 0xa, 0x50, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x0, 0xb3, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, 0xb, 0x30, 0x8, 0x40, 0x0, 0x1, - 0x86, 0x66, 0xd8, 0x66, 0x65, 0x0, 0x0, 0x0, - 0x0, 0xb, 0x30, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0xb3, 0x0, 0x0, 0x40, 0x6, 0x66, 0x66, - 0x8e, 0x96, 0x66, 0x8b, 0x20, 0x0, 0x0, 0xd, - 0xe6, 0x30, 0x0, 0x0, 0x0, 0x0, 0x8, 0x9b, - 0x39, 0x0, 0x0, 0x0, 0x0, 0x4, 0xb0, 0xb3, - 0x2b, 0x0, 0x0, 0x0, 0x3, 0xb0, 0xb, 0x30, - 0x6c, 0x20, 0x0, 0x5, 0x80, 0x0, 0xb3, 0x0, - 0x7f, 0x82, 0x6, 0x30, 0x0, 0xb, 0x30, 0x0, - 0x4d, 0x50, 0x0, 0x0, 0x0, 0xc4, 0x0, 0x0, - 0x0, 0x0, 0x0, 0x0, 0x4, 0x0, 0x0, 0x0, - 0x0, - - /* U+672B "末" */ - 0x0, 0x0, 0x0, 0x9, 0x40, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x0, 0xc4, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, 0xb, 0x30, 0x0, 0x3a, 0x0, 0x76, - 0x66, 0x66, 0xd8, 0x66, 0x66, 0x62, 0x0, 0x0, - 0x0, 0xb, 0x30, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0xb3, 0x0, 0x43, 0x0, 0x0, 0x37, 0x66, - 0xaf, 0xa6, 0x67, 0x70, 0x0, 0x0, 0x0, 0x1e, - 0xd5, 0x60, 0x0, 0x0, 0x0, 0x0, 0xb, 0x5b, - 0x38, 0x20, 0x0, 0x0, 0x0, 0x8, 0x70, 0xb3, - 0xc, 0x20, 0x0, 0x0, 0x7, 0x80, 0xb, 0x30, - 0x3e, 0x60, 0x0, 0x8, 0x50, 0x0, 0xb3, 0x0, - 0x3e, 0xe7, 0x16, 0x10, 0x0, 0xb, 0x30, 0x0, - 0x16, 0x0, 0x0, 0x0, 0x0, 0xc4, 0x0, 0x0, - 0x0, 0x0, 0x0, 0x0, 0x4, 0x0, 0x0, 0x0, - 0x0, - - /* U+672C "本" */ - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x0, 0xa, 0x70, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x0, 0xa, 0x40, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x0, 0xa, 0x40, 0x0, 0x1, 0x0, - 0x5, 0x66, 0x66, 0x6c, 0x96, 0x66, 0x7e, 0x30, - 0x0, 0x0, 0x0, 0x8f, 0x72, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x0, 0xec, 0x47, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x8, 0x7a, 0x46, 0x30, 0x0, 0x0, - 0x0, 0x0, 0x3c, 0xa, 0x40, 0xb1, 0x0, 0x0, - 0x0, 0x0, 0xc1, 0xa, 0x40, 0x4c, 0x10, 0x0, - 0x0, 0xa, 0x30, 0xa, 0x40, 0x7, 0xe4, 0x0, - 0x0, 0x93, 0x66, 0x6c, 0x86, 0xa8, 0x7f, 0x90, - 0x26, 0x0, 0x0, 0xa, 0x40, 0x0, 0x3, 0x0, - 0x0, 0x0, 0x0, 0xa, 0x40, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x0, 0xb, 0x40, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x0, 0x6, 0x20, 0x0, 0x0, 0x0, - - /* U+672D "札" */ - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, 0xe3, 0x0, 0xc, 0x40, 0x0, 0x0, - 0x0, 0x0, 0xe1, 0x0, 0xd, 0x10, 0x0, 0x0, - 0x0, 0x0, 0xe1, 0x0, 0xd, 0x10, 0x0, 0x0, - 0x5, 0x66, 0xe6, 0x9a, 0xd, 0x10, 0x0, 0x0, - 0x1, 0x0, 0xf1, 0x0, 0xd, 0x10, 0x0, 0x0, - 0x0, 0x4, 0xf2, 0x0, 0xd, 0x10, 0x0, 0x0, - 0x0, 0x9, 0xf9, 0x91, 0xd, 0x10, 0x0, 0x0, - 0x0, 0xc, 0xe1, 0xba, 0xd, 0x10, 0x0, 0x0, - 0x0, 0x74, 0xe1, 0x16, 0xd, 0x10, 0x0, 0x0, - 0x0, 0xa0, 0xe1, 0x0, 0xd, 0x10, 0x0, 0x0, - 0x6, 0x0, 0xe1, 0x0, 0xd, 0x10, 0x0, 0x50, - 0x2, 0x0, 0xe1, 0x0, 0xd, 0x10, 0x0, 0x80, - 0x0, 0x0, 0xe1, 0x0, 0xd, 0x20, 0x2, 0xe1, - 0x0, 0x0, 0xe1, 0x0, 0x9, 0xdc, 0xcd, 0xb0, - 0x0, 0x0, 0x60, 0x0, 0x0, 0x0, 0x0, 0x0, - - /* U+673A "机" */ - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0xc, 0x30, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0xc, 0x10, 0xa, 0x66, 0x6c, 0x40, 0x0, - 0x0, 0xc, 0x10, 0xd, 0x10, 0xe, 0x0, 0x0, - 0x0, 0xc, 0x17, 0xd, 0x10, 0xe, 0x0, 0x0, - 0x16, 0x6f, 0x66, 0x2c, 0x10, 0xe, 0x0, 0x0, - 0x0, 0x2f, 0x10, 0xc, 0x10, 0xe, 0x0, 0x0, - 0x0, 0x6f, 0x84, 0xc, 0x10, 0xe, 0x0, 0x0, - 0x0, 0xbe, 0x1c, 0x6c, 0x10, 0xe, 0x0, 0x0, - 0x1, 0x9c, 0x11, 0x4d, 0x0, 0xe, 0x0, 0x0, - 0x7, 0x2c, 0x10, 0xd, 0x0, 0xe, 0x0, 0x0, - 0x6, 0xc, 0x10, 0x39, 0x0, 0xe, 0x0, 0x20, - 0x40, 0xc, 0x10, 0x84, 0x0, 0xe, 0x0, 0x60, - 0x0, 0xc, 0x10, 0xa0, 0x0, 0xe, 0x1, 0xa0, - 0x0, 0xd, 0x27, 0x10, 0x0, 0xa, 0xdd, 0xc0, - 0x0, 0xa, 0x31, 0x0, 0x0, 0x0, 0x0, 0x0, - - /* U+6750 "材" */ - 0x0, 0x0, 0x10, 0x0, 0x0, 0x0, 0x10, 0x0, - 0x0, 0x1, 0xf2, 0x0, 0x0, 0x2, 0xe1, 0x0, - 0x0, 0x0, 0xe0, 0x0, 0x0, 0x1, 0xd0, 0x0, - 0x0, 0x0, 0xe0, 0x0, 0x0, 0x1, 0xd0, 0x0, - 0x5, 0x66, 0xf6, 0xc5, 0x46, 0x67, 0xe7, 0xd1, - 0x0, 0x2, 0xe0, 0x0, 0x0, 0x8, 0xd0, 0x0, - 0x0, 0x7, 0xf6, 0x0, 0x0, 0x1e, 0xd0, 0x0, - 0x0, 0xc, 0xe3, 0xd1, 0x0, 0x89, 0xd0, 0x0, - 0x0, 0x3b, 0xe0, 0x95, 0x3, 0xc1, 0xd0, 0x0, - 0x0, 0xa3, 0xe0, 0x0, 0xb, 0x11, 0xd0, 0x0, - 0x2, 0x70, 0xe0, 0x0, 0x92, 0x1, 0xd0, 0x0, - 0x7, 0x0, 0xe0, 0x7, 0x20, 0x1, 0xd0, 0x0, - 0x10, 0x0, 0xf0, 0x20, 0x0, 0x1, 0xd0, 0x0, - 0x0, 0x0, 0xf0, 0x0, 0x2, 0x34, 0xd0, 0x0, - 0x0, 0x1, 0xf0, 0x0, 0x0, 0x5e, 0x90, 0x0, - 0x0, 0x0, 0x40, 0x0, 0x0, 0x2, 0x0, 0x0, - - /* U+6751 "村" */ - 0x0, 0x0, 0x20, 0x0, 0x0, 0x0, 0x10, 0x0, - 0x0, 0x1, 0xf2, 0x0, 0x0, 0x0, 0xf2, 0x0, - 0x0, 0x0, 0xe0, 0x0, 0x0, 0x0, 0xe0, 0x0, - 0x0, 0x0, 0xe0, 0x0, 0x0, 0x0, 0xe0, 0x0, - 0x5, 0x66, 0xf6, 0xc4, 0x46, 0x66, 0xf7, 0xc1, - 0x0, 0x4, 0xe0, 0x0, 0x0, 0x0, 0xe0, 0x0, - 0x0, 0x8, 0xf4, 0x0, 0x20, 0x0, 0xe0, 0x0, - 0x0, 0xd, 0xe6, 0xb0, 0x76, 0x0, 0xe0, 0x0, - 0x0, 0x39, 0xe0, 0xb5, 0xe, 0x30, 0xe0, 0x0, - 0x0, 0xa2, 0xe0, 0x11, 0x8, 0x40, 0xe0, 0x0, - 0x2, 0x70, 0xe0, 0x0, 0x0, 0x0, 0xe0, 0x0, - 0x7, 0x0, 0xe0, 0x0, 0x0, 0x0, 0xe0, 0x0, - 0x1, 0x0, 0xf0, 0x0, 0x0, 0x0, 0xe0, 0x0, - 0x0, 0x0, 0xf0, 0x0, 0x3, 0x33, 0xe0, 0x0, - 0x0, 0x1, 0xf0, 0x0, 0x0, 0x5e, 0xb0, 0x0, - 0x0, 0x0, 0x40, 0x0, 0x0, 0x2, 0x0, 0x0, - - /* U+675F "束" */ - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x0, 0xc6, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, 0xc, 0x20, 0x0, 0x5, 0x20, 0x66, - 0x66, 0x66, 0xd7, 0x66, 0x66, 0x75, 0x0, 0x0, - 0x0, 0xc, 0x20, 0x0, 0x0, 0x0, 0x0, 0xc6, - 0x66, 0xd7, 0x66, 0x6e, 0x10, 0x0, 0xf, 0x0, - 0xc, 0x20, 0x1, 0xd0, 0x0, 0x0, 0xf0, 0x0, - 0xc2, 0x0, 0x1d, 0x0, 0x0, 0xf, 0x66, 0x6d, - 0x76, 0x66, 0xe0, 0x0, 0x0, 0xf0, 0xd, 0xe6, - 0x30, 0x19, 0x0, 0x0, 0x1, 0x9, 0x7c, 0x29, - 0x0, 0x0, 0x0, 0x0, 0x6, 0xa0, 0xc2, 0x1b, - 0x10, 0x0, 0x0, 0x5, 0x90, 0xc, 0x20, 0x3d, - 0x60, 0x0, 0x7, 0x60, 0x0, 0xc2, 0x0, 0x2d, - 0xf7, 0x16, 0x20, 0x0, 0xd, 0x30, 0x0, 0x5, - 0x0, 0x0, 0x0, 0x0, 0x30, 0x0, 0x0, 0x0, - - /* U+6761 "条" */ - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x8, 0xb0, 0x0, 0x1, 0x0, 0x0, - 0x0, 0x0, 0xe, 0x86, 0x66, 0x6f, 0x50, 0x0, - 0x0, 0x0, 0x89, 0x30, 0x0, 0x9b, 0x0, 0x0, - 0x0, 0x4, 0x80, 0x71, 0x4, 0xe1, 0x0, 0x0, - 0x0, 0x27, 0x0, 0xb, 0x5e, 0x30, 0x0, 0x0, - 0x0, 0x40, 0x0, 0x9, 0xf7, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x6, 0xb7, 0x5b, 0xd8, 0x42, 0x10, - 0x2, 0x57, 0x73, 0x0, 0xf2, 0x39, 0xdf, 0xa2, - 0x2, 0x0, 0x0, 0x0, 0xe0, 0x1, 0x80, 0x0, - 0x0, 0x6, 0x76, 0x66, 0xf6, 0x66, 0x62, 0x0, - 0x0, 0x0, 0xd, 0x40, 0xe1, 0x61, 0x0, 0x0, - 0x0, 0x0, 0xb8, 0x0, 0xe0, 0x1c, 0x60, 0x0, - 0x0, 0x9, 0x50, 0x0, 0xe0, 0x1, 0xd9, 0x0, - 0x1, 0x72, 0x2, 0x8d, 0xc0, 0x0, 0x3a, 0x0, - 0x1, 0x0, 0x0, 0x6, 0x20, 0x0, 0x0, 0x0, - - /* U+6765 "来" */ - 0x0, 0x0, 0x0, 0x1, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x0, 0xc, 0x60, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x0, 0xb, 0x30, 0x0, 0x0, 0x0, - 0x0, 0x56, 0x66, 0x6d, 0x86, 0x66, 0xca, 0x0, - 0x0, 0x23, 0x0, 0xb, 0x30, 0x6, 0x10, 0x0, - 0x0, 0x1, 0xc3, 0xb, 0x30, 0x2e, 0x40, 0x0, - 0x0, 0x0, 0x6c, 0xb, 0x30, 0xa4, 0x0, 0x0, - 0x0, 0x0, 0x4, 0xb, 0x34, 0x40, 0xa, 0x30, - 0x28, 0x66, 0x66, 0xbf, 0xb6, 0x66, 0x66, 0x50, - 0x0, 0x0, 0x1, 0xed, 0x47, 0x0, 0x0, 0x0, - 0x0, 0x0, 0xb, 0x5b, 0x36, 0x50, 0x0, 0x0, - 0x0, 0x0, 0x88, 0xb, 0x30, 0xb6, 0x0, 0x0, - 0x0, 0x6, 0x90, 0xb, 0x30, 0xc, 0xb2, 0x0, - 0x0, 0x76, 0x0, 0xb, 0x30, 0x0, 0xaf, 0x90, - 0x16, 0x20, 0x0, 0xc, 0x40, 0x0, 0x3, 0x0, - 0x0, 0x0, 0x0, 0x6, 0x10, 0x0, 0x0, 0x0, - - /* U+676F "杯" */ - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, 0xc1, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, 0xe0, 0x46, 0x66, 0x66, 0x69, 0xb0, - 0x0, 0x0, 0xe0, 0x0, 0x0, 0xa5, 0x0, 0x0, - 0x0, 0x0, 0xe0, 0x70, 0x0, 0xe0, 0x0, 0x0, - 0x6, 0x66, 0xe6, 0x62, 0x6, 0x80, 0x0, 0x0, - 0x0, 0x5, 0xe2, 0x0, 0xd, 0xb1, 0x0, 0x0, - 0x0, 0xb, 0xe9, 0x50, 0x59, 0xe2, 0x0, 0x0, - 0x0, 0x2a, 0xe1, 0xe0, 0xc1, 0xd1, 0x92, 0x0, - 0x0, 0x91, 0xe0, 0x39, 0x30, 0xd0, 0x2e, 0x30, - 0x3, 0x60, 0xe0, 0x54, 0x0, 0xd0, 0x8, 0x80, - 0x5, 0x0, 0xe2, 0x30, 0x0, 0xd0, 0x0, 0x10, - 0x10, 0x0, 0xe0, 0x0, 0x0, 0xe0, 0x0, 0x0, - 0x0, 0x0, 0xe0, 0x0, 0x0, 0xe0, 0x0, 0x0, - 0x0, 0x0, 0xe0, 0x0, 0x1, 0xe0, 0x0, 0x0, - 0x0, 0x0, 0x70, 0x0, 0x0, 0x50, 0x0, 0x0, - - /* U+6771 "東" */ - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x0, 0xc4, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, 0xd, 0x0, 0x0, 0x9, 0x0, 0x57, - 0x66, 0x66, 0xe6, 0x66, 0x66, 0x62, 0x0, 0x4, - 0x0, 0xd, 0x0, 0x1, 0x60, 0x0, 0x0, 0xd6, - 0x66, 0xe6, 0x66, 0x8d, 0x0, 0x0, 0xd, 0x10, - 0xd, 0x0, 0x3, 0xa0, 0x0, 0x0, 0xc6, 0x66, - 0xe6, 0x66, 0x8a, 0x0, 0x0, 0xd, 0x10, 0xd, - 0x0, 0x3, 0xb0, 0x0, 0x0, 0xd6, 0x6d, 0xfa, - 0x66, 0x78, 0x0, 0x0, 0x1, 0x4, 0xbd, 0x26, - 0x0, 0x0, 0x0, 0x0, 0x1, 0xc1, 0xd0, 0x74, - 0x0, 0x0, 0x0, 0x0, 0xa2, 0xd, 0x0, 0xa6, - 0x0, 0x0, 0x1, 0x92, 0x0, 0xd1, 0x0, 0x9d, - 0x62, 0x4, 0x70, 0x0, 0xd, 0x10, 0x0, 0x4c, - 0x51, 0x20, 0x0, 0x0, 0x50, 0x0, 0x0, 0x0, - - /* U+6790 "析" */ - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0xc3, 0x0, 0x0, 0x0, 0x39, 0x50, 0x0, - 0xd, 0x10, 0x9, 0x65, 0x76, 0x53, 0x0, 0x0, - 0xc1, 0x0, 0xa3, 0x0, 0x0, 0x0, 0x16, 0x6e, - 0x6c, 0x3a, 0x30, 0x0, 0x0, 0x0, 0x0, 0xe1, - 0x0, 0xa3, 0x0, 0x0, 0x0, 0x0, 0x2f, 0x30, - 0xa, 0x86, 0x67, 0x6b, 0x70, 0x7, 0xf9, 0x80, - 0xa3, 0x0, 0xc1, 0x0, 0x0, 0xbd, 0x1d, 0x2a, - 0x20, 0xc, 0x10, 0x0, 0x27, 0xc1, 0x20, 0xc1, - 0x0, 0xc1, 0x0, 0x7, 0xc, 0x10, 0xd, 0x0, - 0xc, 0x10, 0x2, 0x20, 0xc1, 0x2, 0xb0, 0x0, - 0xc1, 0x0, 0x0, 0xd, 0x10, 0x75, 0x0, 0xd, - 0x10, 0x0, 0x0, 0xd1, 0x1a, 0x0, 0x0, 0xd1, - 0x0, 0x0, 0xd, 0x27, 0x0, 0x0, 0xd, 0x20, - 0x0, 0x0, 0x51, 0x0, 0x0, 0x0, 0x30, 0x0, - - /* U+6797 "林" */ - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, 0xe2, 0x0, 0x0, 0xe1, 0x0, 0x0, - 0x0, 0x0, 0xe0, 0x0, 0x0, 0xe0, 0x0, 0x0, - 0x0, 0x0, 0xe0, 0x0, 0x0, 0xe0, 0x1, 0x0, - 0x4, 0x66, 0xe8, 0xb3, 0x66, 0xe6, 0x6d, 0x40, - 0x0, 0x1, 0xe0, 0x0, 0x8, 0xe3, 0x0, 0x0, - 0x0, 0x5, 0xf1, 0x0, 0xd, 0xe6, 0x0, 0x0, - 0x0, 0xb, 0xe9, 0x50, 0x3a, 0xe7, 0x0, 0x0, - 0x0, 0x2a, 0xe1, 0xe0, 0xa2, 0xe2, 0x70, 0x0, - 0x0, 0x91, 0xe0, 0x34, 0x70, 0xe0, 0xb2, 0x0, - 0x3, 0x50, 0xe0, 0x9, 0x0, 0xe0, 0x3e, 0x20, - 0x5, 0x0, 0xe0, 0x70, 0x0, 0xe0, 0x8, 0xc2, - 0x0, 0x0, 0xe2, 0x0, 0x0, 0xe0, 0x0, 0x0, - 0x0, 0x0, 0xe0, 0x0, 0x0, 0xe0, 0x0, 0x0, - 0x0, 0x0, 0xf0, 0x0, 0x0, 0xe0, 0x0, 0x0, - 0x0, 0x0, 0x40, 0x0, 0x0, 0x30, 0x0, 0x0, - - /* U+679C "果" */ - 0x0, 0x8, 0x66, 0x66, 0x66, 0x66, 0xa0, 0x0, - 0x0, 0xd1, 0x0, 0xd1, 0x0, 0x3c, 0x0, 0x0, - 0xc, 0x10, 0xd, 0x10, 0x3, 0xb0, 0x0, 0x0, - 0xc6, 0x66, 0xe6, 0x66, 0x7b, 0x0, 0x0, 0xc, - 0x10, 0xd, 0x10, 0x3, 0xb0, 0x0, 0x0, 0xd1, - 0x0, 0xd1, 0x0, 0x3b, 0x0, 0x0, 0xd, 0x66, - 0x6e, 0x66, 0x67, 0xa0, 0x0, 0x0, 0x10, 0x0, - 0xd1, 0x0, 0x0, 0x70, 0x6, 0x76, 0x66, 0xcf, - 0x96, 0x66, 0x68, 0x30, 0x0, 0x0, 0x6a, 0xd7, - 0x20, 0x0, 0x0, 0x0, 0x0, 0x4b, 0xd, 0x1a, - 0x40, 0x0, 0x0, 0x0, 0x4a, 0x0, 0xd1, 0xb, - 0x81, 0x0, 0x0, 0x76, 0x0, 0xe, 0x10, 0x8, - 0xe9, 0x31, 0x61, 0x0, 0x0, 0xe1, 0x0, 0x3, - 0x80, 0x0, 0x0, 0x0, 0x5, 0x0, 0x0, 0x0, - 0x0, - - /* U+67D0 "某" */ - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x1c, 0x10, 0x0, 0xc3, 0x0, 0x0, - 0x0, 0x0, 0xd, 0x0, 0x0, 0xd1, 0x5, 0x20, - 0x3, 0x76, 0x6e, 0x66, 0x66, 0xd6, 0x68, 0x70, - 0x0, 0x0, 0xd, 0x0, 0x0, 0xc1, 0x0, 0x0, - 0x0, 0x0, 0xe, 0x66, 0x66, 0xd1, 0x0, 0x0, - 0x0, 0x0, 0xd, 0x0, 0x0, 0xc1, 0x0, 0x0, - 0x0, 0x0, 0xe, 0x66, 0x66, 0xd1, 0x0, 0x0, - 0x0, 0x0, 0x5, 0x1, 0xc0, 0x40, 0x0, 0x10, - 0x5, 0x66, 0x66, 0x67, 0xd6, 0x66, 0x6a, 0xd2, - 0x0, 0x0, 0x0, 0xba, 0xc6, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x6, 0xb2, 0xc3, 0x70, 0x0, 0x0, - 0x0, 0x0, 0x6b, 0x1, 0xc0, 0x6a, 0x20, 0x0, - 0x0, 0x9, 0x70, 0x2, 0xc0, 0x5, 0xfa, 0x61, - 0x5, 0x72, 0x0, 0x2, 0xc0, 0x0, 0x1a, 0x91, - 0x0, 0x0, 0x0, 0x1, 0x40, 0x0, 0x0, 0x0, - - /* U+67E5 "查" */ - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x0, 0x3, 0xb0, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x0, 0x2, 0xb0, 0x0, 0x9, 0x30, - 0x3, 0x76, 0x66, 0x7f, 0xd9, 0x66, 0x66, 0x50, - 0x0, 0x0, 0x0, 0xc7, 0xb4, 0x50, 0x0, 0x0, - 0x0, 0x0, 0x1b, 0x52, 0xb0, 0x78, 0x0, 0x0, - 0x0, 0x3, 0xa2, 0x3, 0xb0, 0x7, 0xd7, 0x20, - 0x1, 0x66, 0xa6, 0x66, 0x66, 0x6b, 0x6b, 0x91, - 0x4, 0x0, 0xe0, 0x0, 0x0, 0xe, 0x0, 0x0, - 0x0, 0x0, 0xe0, 0x0, 0x0, 0xe, 0x0, 0x0, - 0x0, 0x0, 0xe6, 0x66, 0x66, 0x6e, 0x0, 0x0, - 0x0, 0x0, 0xe0, 0x0, 0x0, 0xe, 0x0, 0x0, - 0x0, 0x0, 0xe6, 0x66, 0x66, 0x6e, 0x0, 0x0, - 0x0, 0x0, 0xd0, 0x0, 0x0, 0x6, 0x2, 0x0, - 0x2, 0x66, 0x66, 0x66, 0x66, 0x66, 0x8f, 0x60, - 0x0, 0x10, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - - /* U+67F1 "柱" */ - 0x0, 0x9, 0x30, 0x0, 0x6, 0x0, 0x0, 0x0, - 0x0, 0xd, 0x10, 0x0, 0x5, 0xd0, 0x0, 0x0, - 0x0, 0xd, 0x10, 0x0, 0x0, 0xe2, 0x0, 0x0, - 0x0, 0xc, 0x17, 0x15, 0x55, 0x65, 0x5c, 0x80, - 0x18, 0x6e, 0x66, 0x23, 0x11, 0xe1, 0x11, 0x10, - 0x0, 0x1f, 0x10, 0x0, 0x0, 0xe0, 0x0, 0x0, - 0x0, 0x5f, 0x94, 0x0, 0x0, 0xe0, 0x0, 0x0, - 0x0, 0xae, 0x2f, 0x20, 0x0, 0xe0, 0x7, 0x0, - 0x2, 0x9c, 0x15, 0x17, 0x66, 0xe6, 0x67, 0x20, - 0x7, 0x1c, 0x10, 0x0, 0x0, 0xe0, 0x0, 0x0, - 0x23, 0xc, 0x10, 0x0, 0x0, 0xe0, 0x0, 0x0, - 0x10, 0xd, 0x10, 0x0, 0x0, 0xe0, 0x0, 0x0, - 0x0, 0xd, 0x10, 0x0, 0x0, 0xe0, 0x3, 0x20, - 0x0, 0xd, 0x13, 0x76, 0x66, 0xa6, 0x69, 0x90, - 0x0, 0x5, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - - /* U+67FB "査" */ - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x0, 0x9, 0x60, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x0, 0xa, 0x30, 0x0, 0x1, 0x0, - 0x4, 0x66, 0x66, 0x6c, 0x86, 0x66, 0x7f, 0x40, - 0x1, 0x10, 0x0, 0xae, 0x64, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x7, 0x8a, 0x37, 0x50, 0x0, 0x0, - 0x0, 0x0, 0x87, 0xa, 0x40, 0x8a, 0x30, 0x0, - 0x0, 0x29, 0x30, 0xb, 0x30, 0x5, 0xed, 0x90, - 0x5, 0x50, 0x96, 0x67, 0x66, 0x6d, 0x35, 0x20, - 0x0, 0x0, 0xd1, 0x0, 0x0, 0xe, 0x0, 0x0, - 0x0, 0x0, 0xc6, 0x66, 0x66, 0x6e, 0x0, 0x0, - 0x0, 0x0, 0xc1, 0x0, 0x0, 0xe, 0x0, 0x0, - 0x0, 0x0, 0xc6, 0x66, 0x66, 0x6e, 0x0, 0x0, - 0x0, 0x0, 0xc1, 0x0, 0x0, 0xe, 0x2, 0x0, - 0x15, 0x66, 0xd6, 0x66, 0x66, 0x6e, 0x6e, 0xa0, - 0x2, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - - /* U+67FF "柿" */ - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0xb, 0x30, 0x0, 0x8, 0x20, 0x0, 0x0, - 0x0, 0xd, 0x10, 0x0, 0x3, 0xf1, 0x0, 0x0, - 0x0, 0xc, 0x10, 0x0, 0x0, 0x90, 0x4, 0x10, - 0x0, 0xc, 0x16, 0x57, 0x66, 0xc6, 0x68, 0x60, - 0x16, 0x6f, 0x66, 0x20, 0x0, 0xe0, 0x0, 0x0, - 0x0, 0x1f, 0x10, 0x4, 0x0, 0xe0, 0x6, 0x0, - 0x0, 0x6f, 0x93, 0xe, 0x66, 0xe6, 0x6f, 0x10, - 0x0, 0xbe, 0x3e, 0xd, 0x0, 0xe0, 0xe, 0x0, - 0x1, 0x9c, 0x14, 0xd, 0x0, 0xe0, 0xe, 0x0, - 0x7, 0x2c, 0x10, 0xd, 0x0, 0xe0, 0xe, 0x0, - 0x15, 0xc, 0x10, 0xd, 0x0, 0xe0, 0xe, 0x0, - 0x10, 0xd, 0x10, 0xd, 0x0, 0xe3, 0xad, 0x0, - 0x0, 0xd, 0x10, 0x4, 0x0, 0xe0, 0x33, 0x0, - 0x0, 0xd, 0x10, 0x0, 0x0, 0xe0, 0x0, 0x0, - 0x0, 0x7, 0x0, 0x0, 0x0, 0x60, 0x0, 0x0, - - /* U+6811 "树" */ - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0xb, 0x30, 0x0, 0x0, 0x0, 0xb3, 0x0, - 0x0, 0xd, 0x10, 0x0, 0x0, 0x0, 0xe0, 0x0, - 0x0, 0xc, 0x12, 0x66, 0x6d, 0x10, 0xe0, 0x0, - 0x0, 0xc, 0x16, 0x0, 0x3b, 0x22, 0xe4, 0x70, - 0x16, 0x6e, 0x66, 0x20, 0x76, 0x44, 0xe4, 0x40, - 0x0, 0x1f, 0x10, 0x51, 0xb2, 0x0, 0xe0, 0x0, - 0x0, 0x5f, 0x94, 0x9, 0xc2, 0x40, 0xe0, 0x0, - 0x0, 0xae, 0x2e, 0x9, 0x80, 0xc1, 0xe0, 0x0, - 0x1, 0x9c, 0x13, 0xc, 0xd0, 0x85, 0xe0, 0x0, - 0x7, 0x1c, 0x10, 0x74, 0xa5, 0x21, 0xe0, 0x0, - 0x14, 0xc, 0x12, 0x70, 0x56, 0x0, 0xe0, 0x0, - 0x0, 0xd, 0x27, 0x0, 0x0, 0x0, 0xe0, 0x0, - 0x0, 0xd, 0x20, 0x0, 0x1, 0x10, 0xe0, 0x0, - 0x0, 0xd, 0x10, 0x0, 0x1, 0x7f, 0xd0, 0x0, - 0x0, 0x6, 0x0, 0x0, 0x0, 0x3, 0x10, 0x0, - - /* U+6821 "校" */ - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0xc, 0x30, 0x0, 0xa, 0x10, 0x0, 0x0, - 0x0, 0xd, 0x10, 0x0, 0x6, 0xc0, 0x0, 0x0, - 0x0, 0xc, 0x10, 0x45, 0x55, 0xc5, 0x5c, 0x70, - 0x16, 0x6e, 0x6c, 0x51, 0x31, 0x11, 0x11, 0x0, - 0x0, 0xe, 0x10, 0x0, 0xe6, 0x5, 0x50, 0x0, - 0x0, 0x2f, 0x93, 0x9, 0x60, 0x0, 0x9c, 0x10, - 0x0, 0x7f, 0x3d, 0x46, 0x0, 0x3, 0x1b, 0x60, - 0x0, 0xbd, 0x14, 0x42, 0x20, 0xa, 0xb1, 0x20, - 0x4, 0x6c, 0x10, 0x0, 0x60, 0xe, 0x20, 0x0, - 0x7, 0xc, 0x10, 0x0, 0x62, 0x78, 0x0, 0x0, - 0x22, 0xd, 0x10, 0x0, 0xa, 0xc0, 0x0, 0x0, - 0x0, 0xd, 0x10, 0x0, 0x1c, 0xc1, 0x0, 0x0, - 0x0, 0xd, 0x10, 0x3, 0xa2, 0x5e, 0x82, 0x0, - 0x0, 0xd, 0x23, 0x75, 0x0, 0x1, 0x9f, 0xb1, - 0x0, 0x2, 0x11, 0x0, 0x0, 0x0, 0x0, 0x0, - - /* U+682A "株" */ - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0xc, 0x40, 0x0, 0x1, 0xc2, 0x0, 0x0, - 0x0, 0xd, 0x10, 0x6, 0x80, 0xd0, 0x0, 0x0, - 0x0, 0xc, 0x10, 0xa, 0x50, 0xd0, 0x3, 0x0, - 0x5, 0x6e, 0x7d, 0x2c, 0x66, 0xe6, 0x79, 0x10, - 0x1, 0xe, 0x10, 0x46, 0x0, 0xd0, 0x0, 0x0, - 0x0, 0x2f, 0x20, 0x50, 0x0, 0xd0, 0x0, 0x10, - 0x0, 0x7f, 0xa7, 0x56, 0x66, 0xe6, 0x68, 0xc1, - 0x0, 0xbd, 0x2d, 0x0, 0x1e, 0xd5, 0x0, 0x0, - 0x4, 0x6d, 0x10, 0x0, 0x88, 0xd7, 0x10, 0x0, - 0x8, 0xd, 0x10, 0x2, 0xc0, 0xd1, 0xa0, 0x0, - 0x22, 0xd, 0x10, 0xb, 0x10, 0xd0, 0x96, 0x0, - 0x0, 0xd, 0x10, 0x83, 0x0, 0xd0, 0xd, 0xa1, - 0x0, 0xd, 0x16, 0x20, 0x0, 0xd0, 0x2, 0x71, - 0x0, 0xd, 0x20, 0x0, 0x0, 0xe0, 0x0, 0x0, - 0x0, 0x5, 0x0, 0x0, 0x0, 0x50, 0x0, 0x0, - - /* U+6839 "根" */ - 0x0, 0xa, 0x30, 0x2, 0x0, 0x0, 0x40, 0x0, - 0x0, 0xd, 0x10, 0x1e, 0x66, 0x66, 0xe4, 0x0, - 0x0, 0xc, 0x10, 0xd, 0x0, 0x0, 0xe0, 0x0, - 0x2, 0x2d, 0x37, 0x2d, 0x0, 0x0, 0xe0, 0x0, - 0x14, 0x4e, 0x44, 0x2e, 0x66, 0x66, 0xe0, 0x0, - 0x0, 0x1f, 0x20, 0xd, 0x0, 0x0, 0xe0, 0x0, - 0x0, 0x6f, 0x95, 0xe, 0x66, 0x66, 0xe0, 0x0, - 0x0, 0xad, 0x2e, 0xd, 0x6, 0x0, 0x56, 0x0, - 0x2, 0x7c, 0x13, 0xd, 0x6, 0x0, 0xca, 0x10, - 0x7, 0xd, 0x10, 0xd, 0x5, 0x58, 0x30, 0x0, - 0x22, 0xd, 0x10, 0xd, 0x0, 0xb0, 0x0, 0x0, - 0x0, 0xd, 0x10, 0xd, 0x0, 0x6a, 0x0, 0x0, - 0x0, 0xd, 0x10, 0xd, 0x37, 0x19, 0xd4, 0x0, - 0x0, 0xd, 0x10, 0x2f, 0x80, 0x0, 0x7f, 0x90, - 0x0, 0x5, 0x0, 0x4, 0x0, 0x0, 0x1, 0x0, - - /* U+683C "格" */ - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0xc, 0x30, 0x0, 0xc6, 0x0, 0x0, 0x0, - 0x0, 0xd, 0x0, 0x1, 0xe0, 0x0, 0x20, 0x0, - 0x0, 0xd, 0x0, 0x8, 0xb6, 0x67, 0xe2, 0x0, - 0x5, 0x6e, 0x6c, 0x39, 0x60, 0x9, 0x60, 0x0, - 0x0, 0xf, 0x0, 0x71, 0x27, 0x4c, 0x0, 0x0, - 0x0, 0x3f, 0x21, 0x10, 0x9, 0xd1, 0x0, 0x0, - 0x0, 0x8f, 0x77, 0x0, 0x1c, 0xc4, 0x0, 0x0, - 0x0, 0xad, 0xc, 0x3, 0xa1, 0x1c, 0xa4, 0x0, - 0x3, 0x5d, 0x0, 0x79, 0x0, 0x0, 0x9d, 0xa1, - 0x7, 0xd, 0x25, 0xd, 0x66, 0x66, 0xf1, 0x0, - 0x22, 0xd, 0x0, 0xd, 0x0, 0x0, 0xd0, 0x0, - 0x0, 0xd, 0x0, 0xd, 0x0, 0x0, 0xd0, 0x0, - 0x0, 0xd, 0x0, 0xd, 0x0, 0x0, 0xd0, 0x0, - 0x0, 0xd, 0x0, 0xe, 0x66, 0x66, 0xe0, 0x0, - 0x0, 0x7, 0x0, 0x7, 0x0, 0x0, 0x50, 0x0, - - /* U+6843 "桃" */ - 0x0, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0xd, 0x30, 0x0, 0xa4, 0x2c, 0x0, 0x0, - 0x0, 0xd, 0x0, 0x0, 0xd0, 0x1b, 0x0, 0x0, - 0x0, 0xd, 0x0, 0x0, 0xc0, 0x1b, 0x0, 0x0, - 0x5, 0x6e, 0x79, 0x50, 0xc0, 0x1b, 0xc, 0x20, - 0x0, 0xe, 0x0, 0x75, 0xc0, 0x1b, 0x66, 0x0, - 0x0, 0x2f, 0x20, 0x49, 0xc0, 0x1d, 0x40, 0x0, - 0x0, 0x7f, 0x87, 0x1, 0xc0, 0x1b, 0x0, 0x0, - 0x0, 0xbe, 0xc, 0x0, 0xd0, 0x1d, 0x60, 0x0, - 0x2, 0x8d, 0x0, 0x28, 0xe0, 0x1b, 0x5e, 0x20, - 0x8, 0xd, 0x6, 0xc0, 0xe0, 0x1b, 0x5, 0x40, - 0x23, 0xd, 0x2, 0x13, 0xa0, 0x1b, 0x0, 0x10, - 0x0, 0xd, 0x0, 0x9, 0x40, 0x1b, 0x0, 0x50, - 0x0, 0xd, 0x0, 0x3a, 0x0, 0x1c, 0x2, 0x80, - 0x0, 0xd, 0x2, 0x90, 0x0, 0xc, 0xcd, 0xa0, - 0x0, 0x8, 0x5, 0x0, 0x0, 0x0, 0x0, 0x0, - - /* U+6848 "案" */ - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x0, 0x1a, 0x20, 0x0, 0x0, 0x0, - 0x0, 0x2, 0x0, 0x4, 0x50, 0x0, 0x4, 0x0, - 0x0, 0x69, 0x66, 0x7c, 0x66, 0x66, 0x6e, 0x30, - 0x1, 0xd1, 0x0, 0x97, 0x0, 0x0, 0x46, 0x0, - 0x0, 0x66, 0x68, 0xc6, 0x66, 0xa6, 0x7b, 0x40, - 0x0, 0x0, 0x1c, 0x10, 0x6, 0x90, 0x0, 0x0, - 0x0, 0x0, 0x15, 0x67, 0xae, 0x30, 0x0, 0x0, - 0x0, 0x0, 0x1, 0x6a, 0x63, 0x9e, 0x70, 0x0, - 0x0, 0x25, 0x66, 0x23, 0xa0, 0x1, 0x81, 0x0, - 0x2, 0x66, 0x66, 0x67, 0xd6, 0x66, 0x6c, 0xb0, - 0x0, 0x0, 0x0, 0x9a, 0xb7, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x9, 0x82, 0xb1, 0xa2, 0x0, 0x0, - 0x0, 0x2, 0xa4, 0x3, 0xb0, 0x1b, 0xb5, 0x30, - 0x2, 0x66, 0x0, 0x3, 0xc0, 0x0, 0x5c, 0xb1, - 0x3, 0x0, 0x0, 0x1, 0x30, 0x0, 0x0, 0x0, - - /* U+689D "條" */ - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x1, 0xd2, 0x0, 0x1d, 0x20, 0x0, 0x0, - 0x0, 0x5, 0xb0, 0x0, 0x69, 0x0, 0x1, 0x0, - 0x0, 0xb, 0x40, 0x0, 0xc8, 0x66, 0xac, 0x0, - 0x0, 0x2d, 0x9, 0x4, 0x78, 0x2, 0xd1, 0x0, - 0x0, 0x9e, 0xd, 0x8, 0x5, 0x8c, 0x20, 0x0, - 0x2, 0x8d, 0xc, 0x10, 0x3, 0xea, 0x0, 0x0, - 0x7, 0xd, 0xc, 0x0, 0x68, 0x6, 0xe9, 0x51, - 0x0, 0xd, 0xc, 0x36, 0x20, 0xb3, 0x17, 0x80, - 0x0, 0xd, 0xc, 0x0, 0x0, 0xd0, 0x6, 0x20, - 0x0, 0xd, 0xd, 0x57, 0x66, 0xe6, 0x66, 0x40, - 0x0, 0xd, 0xd, 0x2, 0xa0, 0xd0, 0x40, 0x0, - 0x0, 0xd, 0x4, 0xa, 0x50, 0xd0, 0x4c, 0x20, - 0x0, 0xd, 0x0, 0x66, 0x0, 0xd0, 0x7, 0xc0, - 0x0, 0xe, 0x3, 0x40, 0x6b, 0xe0, 0x0, 0x50, - 0x0, 0x5, 0x0, 0x0, 0x3, 0x20, 0x0, 0x0, - - /* U+68B0 "械" */ - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0xd, 0x10, 0x0, 0x0, 0xa4, 0x62, 0x0, - 0x0, 0xd, 0x0, 0x0, 0x0, 0xa2, 0x1e, 0x0, - 0x0, 0xd, 0x0, 0x0, 0x0, 0xa2, 0x4, 0x10, - 0x5, 0x6e, 0x97, 0x76, 0x66, 0xc7, 0x68, 0x80, - 0x1, 0x1d, 0x0, 0x51, 0x50, 0x93, 0x0, 0x0, - 0x0, 0x3e, 0x91, 0x93, 0xb2, 0x93, 0x8, 0x50, - 0x0, 0x8e, 0x4a, 0x92, 0xb0, 0x74, 0xd, 0x30, - 0x0, 0xad, 0x18, 0xb7, 0xd9, 0x86, 0x3b, 0x0, - 0x4, 0x5d, 0x1, 0xa1, 0xb0, 0x49, 0xa3, 0x0, - 0x7, 0xd, 0x0, 0xb0, 0xb0, 0x1d, 0xb0, 0x0, - 0x21, 0xd, 0x0, 0xa0, 0xb0, 0xe, 0x40, 0x40, - 0x0, 0xd, 0x4, 0x50, 0xc0, 0x98, 0xb0, 0x70, - 0x0, 0xe, 0x8, 0x0, 0x68, 0x30, 0x8a, 0xa0, - 0x0, 0xe, 0x31, 0x2, 0x71, 0x0, 0x8, 0xe0, - 0x0, 0x3, 0x0, 0x2, 0x0, 0x0, 0x0, 0x10, - - /* U+68EE "森" */ - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x0, 0xa, 0x50, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x0, 0xa, 0x30, 0x0, 0x65, 0x0, - 0x3, 0x76, 0x66, 0xcf, 0xb7, 0x66, 0x65, 0x0, - 0x0, 0x0, 0x4, 0xcb, 0x49, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x4b, 0x1a, 0x32, 0xc3, 0x0, 0x0, - 0x0, 0x6, 0x80, 0xa, 0x40, 0x3d, 0xc6, 0x10, - 0x2, 0x63, 0xa1, 0xb, 0x40, 0xd3, 0x6a, 0x30, - 0x1, 0x0, 0xd0, 0x52, 0x0, 0xd0, 0x6, 0x0, - 0x6, 0x68, 0xf6, 0x64, 0x6b, 0xf9, 0x67, 0x30, - 0x0, 0x9, 0xf6, 0x0, 0xd, 0xe7, 0x0, 0x0, - 0x0, 0x39, 0xd4, 0xd0, 0x95, 0xd3, 0xa0, 0x0, - 0x0, 0x90, 0xd0, 0x45, 0x70, 0xd0, 0x99, 0x0, - 0x6, 0x0, 0xd0, 0x36, 0x0, 0xd0, 0xc, 0x80, - 0x10, 0x0, 0xe0, 0x20, 0x0, 0xd0, 0x0, 0x0, - 0x0, 0x0, 0x60, 0x0, 0x0, 0x60, 0x0, 0x0, - - /* U+690D "植" */ - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0xc, 0x40, 0x0, 0x9, 0x40, 0x0, 0x0, - 0x0, 0xd, 0x10, 0x0, 0xb, 0x20, 0x1, 0x0, - 0x0, 0xd, 0x10, 0x76, 0x6d, 0x76, 0x7d, 0x30, - 0x4, 0x4d, 0x69, 0x0, 0xb, 0x10, 0x0, 0x0, - 0x3, 0x2e, 0x22, 0xa, 0x6c, 0x66, 0xb2, 0x0, - 0x0, 0x1f, 0x40, 0xd, 0x0, 0x0, 0xd0, 0x0, - 0x0, 0x6f, 0x7a, 0xe, 0x66, 0x66, 0xe0, 0x0, - 0x0, 0xad, 0x1a, 0xd, 0x0, 0x0, 0xd0, 0x0, - 0x2, 0x7d, 0x10, 0xd, 0x66, 0x66, 0xe0, 0x0, - 0x7, 0xd, 0x10, 0xd, 0x0, 0x0, 0xd0, 0x0, - 0x14, 0xd, 0x10, 0xd, 0x0, 0x0, 0xd0, 0x0, - 0x0, 0xd, 0x10, 0xd, 0x66, 0x66, 0xe0, 0x0, - 0x0, 0xd, 0x10, 0xd, 0x0, 0x0, 0xd3, 0x30, - 0x0, 0xd, 0x27, 0x67, 0x66, 0x66, 0x77, 0x70, - 0x0, 0x6, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - - /* U+691C "検" */ - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0xc, 0x40, 0x0, 0x9, 0x90, 0x0, 0x0, - 0x0, 0xd, 0x10, 0x0, 0x1e, 0x80, 0x0, 0x0, - 0x0, 0xc, 0x10, 0x0, 0xa6, 0x1a, 0x20, 0x0, - 0x14, 0x4d, 0x5b, 0x16, 0x70, 0x1, 0xc9, 0x30, - 0x2, 0x2e, 0x32, 0x66, 0x66, 0x66, 0xc9, 0x90, - 0x0, 0x2f, 0x41, 0x20, 0x0, 0xc0, 0x0, 0x0, - 0x0, 0x7f, 0x99, 0xb, 0x66, 0xd6, 0x6c, 0x10, - 0x0, 0xbd, 0x1c, 0xd, 0x1, 0xb0, 0xd, 0x0, - 0x2, 0x7c, 0x10, 0xd, 0x2, 0xa0, 0xd, 0x0, - 0x7, 0xd, 0x10, 0xe, 0x68, 0xd6, 0x6d, 0x0, - 0x23, 0xd, 0x10, 0x4, 0x9, 0x95, 0x1, 0x0, - 0x0, 0xd, 0x10, 0x0, 0x2c, 0xa, 0x30, 0x0, - 0x0, 0xd, 0x10, 0x1, 0xb2, 0x1, 0xc6, 0x0, - 0x0, 0xd, 0x10, 0x39, 0x10, 0x0, 0x1c, 0xb1, - 0x0, 0x6, 0x3, 0x20, 0x0, 0x0, 0x0, 0x0, - - /* U+695A "楚" */ - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0xc, 0x10, 0x0, 0x2c, 0x0, 0x0, 0x0, - 0x0, 0xd0, 0x10, 0x2, 0xb0, 0x0, 0x0, 0x66, - 0x6e, 0x6a, 0x36, 0x9c, 0x69, 0x60, 0x0, 0xa, - 0xe4, 0x0, 0x1e, 0xc1, 0x0, 0x0, 0x4, 0xad, - 0x5a, 0xa, 0x5b, 0x88, 0x0, 0x1, 0xa0, 0xd0, - 0x48, 0x42, 0xb0, 0xa5, 0x1, 0x70, 0xe, 0x6, - 0x20, 0x2b, 0x0, 0x0, 0x14, 0x66, 0x76, 0x66, - 0x66, 0x66, 0xa3, 0x0, 0x11, 0x0, 0x0, 0xd0, - 0x0, 0x48, 0x20, 0x0, 0x5, 0xc0, 0xd, 0x0, - 0x3, 0x0, 0x0, 0x0, 0xa6, 0x0, 0xd6, 0x66, - 0x87, 0x0, 0x0, 0x1c, 0x80, 0xd, 0x0, 0x0, - 0x0, 0x0, 0x9, 0x33, 0x91, 0xd0, 0x0, 0x0, - 0x0, 0x4, 0x60, 0x3, 0xce, 0x54, 0x34, 0x46, - 0x42, 0x60, 0x0, 0x0, 0x5a, 0xce, 0xff, 0xc0, - 0x10, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - - /* U+696D "業" */ - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x42, 0x0, 0xc1, 0xc, 0x30, 0x50, 0x0, - 0x0, 0xb, 0x80, 0xd0, 0xd, 0xa, 0x90, 0x0, - 0x0, 0x1, 0xd0, 0xd0, 0xd, 0x63, 0x0, 0x0, - 0x4, 0x66, 0x66, 0xd6, 0x6d, 0x66, 0x6a, 0xa0, - 0x0, 0x0, 0x19, 0x20, 0x6, 0x60, 0x0, 0x0, - 0x0, 0x0, 0x3, 0x90, 0x8, 0x0, 0x61, 0x0, - 0x0, 0x26, 0x66, 0x6a, 0x76, 0x66, 0x95, 0x0, - 0x0, 0x0, 0x0, 0xa, 0x30, 0x5, 0x30, 0x0, - 0x0, 0x5, 0x66, 0x6c, 0x76, 0x66, 0x50, 0x0, - 0x3, 0x66, 0x66, 0x6c, 0x85, 0x55, 0x6d, 0x30, - 0x0, 0x0, 0x1, 0xce, 0x57, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x2c, 0x4a, 0x34, 0xa2, 0x0, 0x0, - 0x0, 0x6, 0xa1, 0xa, 0x30, 0x3c, 0xc7, 0x41, - 0x4, 0x73, 0x0, 0xa, 0x30, 0x0, 0x5b, 0x90, - 0x1, 0x0, 0x0, 0x3, 0x0, 0x0, 0x0, 0x0, - - /* U+6975 "極" */ - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0xc, 0x20, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0xd, 0x0, 0x16, 0x66, 0x66, 0xb4, 0x0, - 0x0, 0xd, 0x0, 0x0, 0x0, 0x7, 0x60, 0x0, - 0x15, 0x5e, 0x7a, 0x0, 0x0, 0xc2, 0x0, 0x0, - 0x0, 0xe, 0x0, 0x86, 0x92, 0xc4, 0x66, 0x90, - 0x0, 0x2f, 0x40, 0xc0, 0xc0, 0xc0, 0x7, 0x60, - 0x0, 0x6f, 0x6a, 0xc0, 0xc0, 0xc4, 0x1c, 0x10, - 0x0, 0xbe, 0xa, 0xc0, 0xc0, 0xc0, 0x9b, 0x0, - 0x2, 0x9d, 0x0, 0xc0, 0xc0, 0xc0, 0x7c, 0x0, - 0x7, 0x1d, 0x0, 0xc6, 0xd0, 0xc0, 0x96, 0x90, - 0x14, 0xd, 0x0, 0xc0, 0x50, 0xc5, 0x20, 0x80, - 0x0, 0xd, 0x0, 0x20, 0x55, 0xc3, 0x0, 0x0, - 0x0, 0xd, 0x0, 0x0, 0xa, 0x50, 0x0, 0x0, - 0x0, 0xd, 0x5, 0x66, 0x66, 0x66, 0x69, 0xd1, - 0x0, 0x6, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, - - /* U+697D "楽" */ - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x0, 0x75, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x3, 0x7, 0x3, 0x0, 0x2, 0x0, 0x8, - 0xa1, 0xd6, 0x66, 0xd4, 0xa, 0x90, 0x0, 0x9, - 0x6c, 0x0, 0xc, 0x18, 0x30, 0x0, 0x0, 0x0, - 0xc6, 0x66, 0xd4, 0x20, 0x0, 0x0, 0x5, 0x5d, - 0x0, 0xc, 0x15, 0xb9, 0x10, 0x8b, 0x20, 0xd6, - 0x66, 0xd1, 0x0, 0x8a, 0x2, 0x0, 0xa, 0x6, - 0x28, 0x0, 0x0, 0x10, 0x56, 0x66, 0x66, 0xd7, - 0x66, 0x69, 0xe2, 0x1, 0x0, 0x0, 0xcf, 0x71, - 0x0, 0x0, 0x0, 0x0, 0x0, 0xa6, 0xc1, 0xa2, - 0x0, 0x0, 0x0, 0x1, 0xa4, 0xc, 0x11, 0xc7, - 0x10, 0x0, 0x4, 0x81, 0x0, 0xc1, 0x0, 0x9f, - 0xb6, 0x26, 0x30, 0x0, 0xc, 0x10, 0x0, 0x26, - 0x0, 0x0, 0x0, 0x0, 0x30, 0x0, 0x0, 0x0, - - /* U+6982 "概" */ - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0xd, 0x10, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0xc, 0x0, 0xb6, 0xc4, 0x66, 0x97, 0x80, - 0x0, 0xc, 0x0, 0xc0, 0xb0, 0x0, 0xc0, 0x0, - 0x4, 0x5d, 0x95, 0xc0, 0xb0, 0x93, 0xc0, 0x0, - 0x1, 0x1d, 0x10, 0xd6, 0xc0, 0xb0, 0xc0, 0x0, - 0x0, 0x4e, 0x30, 0xc0, 0xb1, 0xa1, 0xb0, 0x0, - 0x0, 0x8e, 0x97, 0xc0, 0xb7, 0xb7, 0xc8, 0xb0, - 0x0, 0xbc, 0x1a, 0xd6, 0xb1, 0x16, 0x70, 0x0, - 0x3, 0x6c, 0x0, 0xc2, 0x10, 0xb, 0xe1, 0x0, - 0x8, 0xc, 0x0, 0xc0, 0xa1, 0x1b, 0xc0, 0x0, - 0x23, 0xc, 0x0, 0xc4, 0x98, 0x94, 0xc0, 0x0, - 0x0, 0xc, 0x0, 0xf6, 0x4, 0x90, 0xc0, 0x50, - 0x0, 0xd, 0x0, 0x40, 0x1a, 0x0, 0xc0, 0x80, - 0x0, 0xd, 0x0, 0x3, 0x70, 0x0, 0x9b, 0xd2, - 0x0, 0x4, 0x0, 0x12, 0x0, 0x0, 0x0, 0x0, - - /* U+69CB "構" */ - 0x0, 0x0, 0x0, 0x0, 0x20, 0x1, 0x0, 0x0, - 0x0, 0xd, 0x10, 0x0, 0x95, 0x8, 0x70, 0x0, - 0x0, 0xc, 0x0, 0x56, 0xb7, 0x6b, 0x8c, 0x70, - 0x0, 0xc, 0x0, 0x0, 0x92, 0x8, 0x41, 0x0, - 0x2, 0x2c, 0x29, 0x36, 0xb7, 0x6b, 0x9c, 0x20, - 0x4, 0x4d, 0x44, 0x20, 0x92, 0x8, 0x42, 0x40, - 0x0, 0x3e, 0x73, 0x66, 0x76, 0xc7, 0x67, 0x70, - 0x0, 0x7d, 0x78, 0x3, 0x0, 0xc0, 0x5, 0x0, - 0x0, 0xbc, 0x16, 0x1d, 0x66, 0xd6, 0x6d, 0x0, - 0x3, 0x8c, 0x0, 0xd, 0x66, 0xd6, 0x6c, 0x0, - 0x8, 0xc, 0x0, 0xb, 0x0, 0xc0, 0xc, 0x0, - 0x23, 0xc, 0x5, 0x6d, 0x66, 0xd6, 0x6e, 0xc1, - 0x0, 0xc, 0x0, 0xb, 0x0, 0x0, 0xc, 0x0, - 0x0, 0xc, 0x0, 0xb, 0x0, 0x0, 0xc, 0x0, - 0x0, 0xd, 0x0, 0x1b, 0x0, 0x7, 0xd9, 0x0, - 0x0, 0x2, 0x0, 0x2, 0x0, 0x0, 0x30, 0x0, - - /* U+69D8 "様" */ - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0xb, 0x20, 0x0, 0x92, 0x0, 0xb5, 0x0, - 0x0, 0xc, 0x0, 0x0, 0x3d, 0x1, 0x91, 0x0, - 0x0, 0xc, 0x0, 0x26, 0x69, 0x98, 0x69, 0x80, - 0x2, 0x2c, 0x28, 0x0, 0x0, 0xd0, 0x1, 0x0, - 0x4, 0x4d, 0x44, 0x15, 0x66, 0xe6, 0x6b, 0x10, - 0x0, 0x1f, 0x70, 0x0, 0x0, 0xd0, 0x0, 0x0, - 0x0, 0x5f, 0x5a, 0x46, 0x66, 0xd6, 0x69, 0xb0, - 0x0, 0xad, 0x7, 0x0, 0x0, 0xb3, 0x3, 0x0, - 0x1, 0x9c, 0x2, 0x66, 0x92, 0xd3, 0x1c, 0x40, - 0x7, 0x1c, 0x0, 0x0, 0xd2, 0xd7, 0x60, 0x0, - 0x23, 0xc, 0x0, 0x5, 0x80, 0xd2, 0x80, 0x0, - 0x0, 0xc, 0x0, 0xb, 0x0, 0xd0, 0xa6, 0x0, - 0x0, 0xc, 0x0, 0x92, 0x0, 0xd0, 0xd, 0xa0, - 0x0, 0xd, 0x6, 0x10, 0x7d, 0xd0, 0x1, 0x20, - 0x0, 0x2, 0x0, 0x0, 0x2, 0x10, 0x0, 0x0, - - /* U+6A02 "樂" */ - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0xd, 0x10, 0x7, 0x60, 0x1, 0xd1, 0x0, - 0x0, 0x3a, 0x0, 0x7a, 0x6a, 0x16, 0x70, 0x0, - 0x0, 0x91, 0x84, 0xc0, 0xc, 0xa, 0xa, 0x30, - 0x5, 0x84, 0xd2, 0xc0, 0xc, 0x76, 0x4b, 0x0, - 0x6, 0x6a, 0x40, 0xc6, 0x6c, 0x76, 0xb2, 0x0, - 0x0, 0x18, 0x20, 0xc0, 0xc, 0x3, 0x73, 0x0, - 0x0, 0x80, 0x64, 0xc6, 0x6c, 0x9, 0x7, 0x50, - 0x8, 0xd9, 0x6c, 0x92, 0x17, 0x9c, 0x85, 0xd0, - 0x0, 0x0, 0x4, 0x6, 0xa0, 0x10, 0x9, 0x30, - 0x6, 0x76, 0x66, 0xaf, 0xb8, 0x66, 0x67, 0x40, - 0x0, 0x0, 0x4, 0xd8, 0x77, 0x10, 0x0, 0x0, - 0x0, 0x0, 0x6a, 0x16, 0x70, 0xb5, 0x0, 0x0, - 0x0, 0x29, 0x50, 0x6, 0x70, 0xa, 0xd8, 0x50, - 0x5, 0x50, 0x0, 0x6, 0x70, 0x0, 0x4b, 0x50, - 0x0, 0x0, 0x0, 0x3, 0x20, 0x0, 0x0, 0x0, - - /* U+6A19 "標" */ - 0x0, 0x9, 0x30, 0x0, 0x0, 0x0, 0x5, 0x30, - 0x0, 0xc, 0x0, 0x67, 0x6c, 0x6c, 0x66, 0x50, - 0x0, 0xc, 0x0, 0x0, 0xb, 0xb, 0x1, 0x0, - 0x16, 0x6d, 0x6c, 0x5b, 0x5c, 0x5c, 0x5d, 0x30, - 0x0, 0xf, 0x0, 0x1a, 0xb, 0xb, 0xc, 0x0, - 0x0, 0x4f, 0x60, 0x1a, 0xb, 0xb, 0xc, 0x0, - 0x0, 0x9f, 0x69, 0x2c, 0x66, 0x66, 0x69, 0x0, - 0x0, 0xac, 0x9, 0x5, 0x66, 0x66, 0x87, 0x0, - 0x6, 0x3c, 0x0, 0x1, 0x0, 0x0, 0x0, 0x20, - 0x6, 0xc, 0x1, 0x86, 0x66, 0x96, 0x66, 0xa1, - 0x20, 0xc, 0x0, 0x5, 0x50, 0xb2, 0x20, 0x0, - 0x0, 0xc, 0x0, 0x2c, 0x20, 0xb0, 0x69, 0x0, - 0x0, 0xc, 0x3, 0x90, 0x0, 0xb0, 0x9, 0x90, - 0x0, 0xc, 0x25, 0x0, 0x5a, 0xb0, 0x0, 0x50, - 0x0, 0x5, 0x0, 0x0, 0x3, 0x10, 0x0, 0x0, - - /* U+6A21 "模" */ - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0xc, 0x30, 0x0, 0xc2, 0xd, 0x20, 0x0, - 0x0, 0xd, 0x0, 0x0, 0xd0, 0xd, 0x5, 0x30, - 0x0, 0xd, 0x2, 0x66, 0xe6, 0x6e, 0x66, 0x50, - 0x16, 0x6e, 0x6d, 0x20, 0xa0, 0x9, 0x0, 0x0, - 0x0, 0x1f, 0x0, 0xd, 0x66, 0x66, 0xa8, 0x0, - 0x0, 0x4f, 0x30, 0xd, 0x0, 0x0, 0x85, 0x0, - 0x0, 0x9f, 0x79, 0xd, 0x66, 0x66, 0xb5, 0x0, - 0x0, 0xad, 0xd, 0xd, 0x0, 0x0, 0x85, 0x0, - 0x6, 0x3d, 0x1, 0xe, 0x6b, 0x86, 0xa4, 0x0, - 0x6, 0xd, 0x0, 0x1, 0xa, 0x30, 0x2, 0x30, - 0x20, 0xd, 0x6, 0x76, 0x6e, 0x96, 0x67, 0x80, - 0x0, 0xd, 0x0, 0x0, 0x4a, 0x36, 0x0, 0x0, - 0x0, 0xd, 0x0, 0x1, 0xc1, 0x7, 0x91, 0x0, - 0x0, 0xd, 0x0, 0x49, 0x20, 0x0, 0x7f, 0xa0, - 0x0, 0x5, 0x14, 0x20, 0x0, 0x0, 0x2, 0x0, - - /* U+6A23 "樣" */ - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0xc, 0x30, 0x0, 0x92, 0x5, 0xa0, 0x0, - 0x0, 0xd, 0x0, 0x0, 0x39, 0x7, 0x16, 0x0, - 0x0, 0xd, 0x0, 0x56, 0x66, 0xd6, 0x66, 0x10, - 0x16, 0x6e, 0x6c, 0x36, 0x66, 0xd6, 0x89, 0x0, - 0x0, 0x1f, 0x0, 0x0, 0x1, 0xb0, 0x0, 0x10, - 0x0, 0x5f, 0x60, 0x66, 0x66, 0xa6, 0x67, 0x90, - 0x0, 0xaf, 0x5b, 0x0, 0x5, 0xc1, 0x0, 0x0, - 0x1, 0xad, 0x9, 0x0, 0x0, 0x70, 0x0, 0x0, - 0x7, 0x3d, 0x0, 0x16, 0x66, 0xe1, 0xd, 0x20, - 0x6, 0xd, 0x3, 0x66, 0x83, 0xd5, 0x83, 0x0, - 0x20, 0xd, 0x0, 0x2, 0xd2, 0xc7, 0x30, 0x0, - 0x0, 0xd, 0x0, 0xb, 0x30, 0xc0, 0xc2, 0x0, - 0x0, 0xd, 0x0, 0x84, 0x0, 0xd0, 0x2e, 0x71, - 0x0, 0xd, 0x17, 0x20, 0x6b, 0xd0, 0x2, 0x50, - 0x0, 0x4, 0x0, 0x0, 0x4, 0x20, 0x0, 0x0, - - /* U+6A2A "横" */ - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0xd, 0x10, 0x4, 0x90, 0xc, 0x20, 0x0, - 0x0, 0xd, 0x0, 0x3, 0x90, 0xd, 0x6, 0x0, - 0x0, 0xd, 0x2, 0x68, 0xb6, 0x6e, 0x66, 0x10, - 0x16, 0x6e, 0x87, 0x3, 0x90, 0xd, 0x0, 0x10, - 0x0, 0x3e, 0x7, 0x66, 0x89, 0x69, 0x67, 0x80, - 0x0, 0x6e, 0x10, 0x10, 0xa, 0x10, 0x2, 0x0, - 0x0, 0xad, 0x95, 0xc6, 0x6c, 0x66, 0x7c, 0x0, - 0x0, 0xad, 0x1b, 0xb0, 0xa, 0x10, 0x39, 0x0, - 0x6, 0x3d, 0x0, 0xb6, 0x6c, 0x66, 0x79, 0x0, - 0x8, 0xd, 0x0, 0xb0, 0xa, 0x10, 0x39, 0x0, - 0x21, 0xd, 0x0, 0xc6, 0x6b, 0x66, 0x79, 0x0, - 0x0, 0xd, 0x0, 0x71, 0x80, 0x14, 0x11, 0x0, - 0x0, 0xd, 0x0, 0x1c, 0x60, 0x2, 0xb5, 0x0, - 0x0, 0xe, 0x3, 0x82, 0x0, 0x0, 0xd, 0x40, - 0x0, 0x5, 0x13, 0x0, 0x0, 0x0, 0x1, 0x20, - - /* U+6A39 "樹" */ - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0xd, 0x10, 0x4, 0x90, 0x0, 0xb, 0x10, - 0x0, 0xd, 0x0, 0x4, 0x81, 0x40, 0xc, 0x0, - 0x0, 0xd, 0x4, 0x68, 0xb6, 0x50, 0xc, 0x0, - 0x6, 0x6e, 0x86, 0x3, 0x81, 0x2, 0x2c, 0x70, - 0x0, 0x1d, 0x0, 0x66, 0x88, 0x54, 0x4d, 0x41, - 0x0, 0x4e, 0x10, 0x76, 0x69, 0x10, 0xc, 0x0, - 0x0, 0x9e, 0xa5, 0xc0, 0xc, 0x18, 0xc, 0x0, - 0x0, 0xbd, 0x18, 0xc0, 0xc, 0xa, 0x4c, 0x0, - 0x5, 0x5d, 0x0, 0xc6, 0x6b, 0x5, 0x3c, 0x0, - 0x8, 0xd, 0x0, 0x50, 0xb, 0x20, 0xc, 0x0, - 0x21, 0xd, 0x0, 0x75, 0x29, 0x0, 0xc, 0x0, - 0x0, 0xd, 0x0, 0x25, 0x74, 0x50, 0xc, 0x0, - 0x0, 0xd, 0x7, 0xaa, 0x72, 0x0, 0xc, 0x0, - 0x0, 0xe, 0x5, 0x20, 0x0, 0x17, 0xdc, 0x0, - 0x0, 0x5, 0x0, 0x0, 0x0, 0x0, 0x31, 0x0, - - /* U+6A4B "橋" */ - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0xd, 0x20, 0x0, 0x2, 0x6a, 0xf6, 0x0, - 0x0, 0xd, 0x0, 0x35, 0x6d, 0x61, 0x0, 0x0, - 0x0, 0xd, 0x0, 0x12, 0x3d, 0x22, 0x26, 0x30, - 0x6, 0x6e, 0x87, 0x34, 0xc5, 0x49, 0x44, 0x30, - 0x0, 0x1e, 0x0, 0x8, 0x60, 0x2, 0xb6, 0x0, - 0x0, 0x5e, 0x10, 0x76, 0xb6, 0x6b, 0x78, 0xc2, - 0x0, 0x9e, 0xa7, 0x2, 0x90, 0x9, 0x40, 0x0, - 0x0, 0xbd, 0x18, 0x2, 0x96, 0x69, 0x20, 0x0, - 0x5, 0x4d, 0x0, 0xc5, 0x55, 0x55, 0x56, 0xd0, - 0x7, 0xd, 0x0, 0xd0, 0x66, 0x69, 0x31, 0xa0, - 0x21, 0xd, 0x0, 0xd0, 0xb0, 0xc, 0x11, 0xa0, - 0x0, 0xd, 0x0, 0xd0, 0xb6, 0x6d, 0x1, 0xa0, - 0x0, 0xd, 0x0, 0xd0, 0x40, 0x2, 0x2, 0xa0, - 0x0, 0xe, 0x0, 0xd0, 0x0, 0x4, 0x9d, 0x80, - 0x0, 0x4, 0x0, 0x40, 0x0, 0x0, 0x4, 0x0, - - /* U+6A5F "機" */ - 0x0, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0xf, 0x10, 0x8, 0x40, 0xd2, 0x49, 0x0, - 0x0, 0xd, 0x0, 0xb, 0x10, 0xd0, 0x93, 0x0, - 0x0, 0xd, 0x20, 0x62, 0x97, 0xc3, 0x65, 0x90, - 0x6, 0x6e, 0xa7, 0xda, 0xc0, 0xcb, 0xad, 0x20, - 0x0, 0x1d, 0x0, 0x8, 0x30, 0xc1, 0x45, 0x0, - 0x0, 0x4e, 0x10, 0x53, 0x55, 0xc2, 0x62, 0x90, - 0x0, 0x8e, 0xa5, 0xc7, 0x49, 0xc9, 0xa5, 0xb0, - 0x0, 0xad, 0x18, 0x9, 0x20, 0xb0, 0x65, 0x0, - 0x3, 0x5d, 0x2, 0x6d, 0x66, 0xd6, 0x6c, 0xd2, - 0x7, 0xd, 0x0, 0xc, 0x0, 0x92, 0x1, 0x0, - 0x13, 0xd, 0x0, 0xd, 0x0, 0x75, 0xe, 0x30, - 0x0, 0xd, 0x0, 0x38, 0xa3, 0x2b, 0xa9, 0x0, - 0x0, 0xd, 0x0, 0x91, 0x14, 0xd, 0xb0, 0x32, - 0x0, 0xd, 0x4, 0x60, 0x4, 0x94, 0xc8, 0x72, - 0x0, 0xd, 0x35, 0x0, 0x52, 0x0, 0x7, 0xd4, - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - - /* U+6B21 "次" */ - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x1, - 0x10, 0x0, 0x0, 0xb6, 0x0, 0x0, 0x0, 0xa, - 0x40, 0x0, 0xf, 0x20, 0x0, 0x0, 0x0, 0x2f, - 0x23, 0x4, 0xa0, 0x0, 0x0, 0x0, 0x0, 0x91, - 0x50, 0xa9, 0x66, 0x66, 0xb5, 0x0, 0x0, 0x42, - 0x1b, 0x3, 0x0, 0x1d, 0x50, 0x0, 0x7, 0x8, - 0x20, 0xc6, 0x6, 0x20, 0x0, 0x2, 0x52, 0x70, - 0xd, 0x40, 0x10, 0x0, 0x0, 0x80, 0x60, 0x0, - 0xd5, 0x0, 0x0, 0x1, 0x38, 0x0, 0x0, 0x3a, - 0x60, 0x0, 0x0, 0x4d, 0x40, 0x0, 0x8, 0x52, - 0x60, 0x0, 0x0, 0x94, 0x0, 0x0, 0xc0, 0xa, - 0x0, 0x0, 0xa, 0x50, 0x0, 0x93, 0x0, 0x5a, - 0x0, 0x0, 0xc7, 0x0, 0x75, 0x0, 0x0, 0xba, - 0x0, 0x3, 0x21, 0x83, 0x0, 0x0, 0x0, 0xcb, - 0x10, 0x1, 0x40, 0x0, 0x0, 0x0, 0x0, 0x0, - - /* U+6B32 "欲" */ - 0x0, 0x3, 0x1, 0x0, 0x3, 0xa0, 0x0, 0x0, - 0x0, 0x4d, 0x3, 0xa2, 0x6, 0x90, 0x0, 0x0, - 0x1, 0xb1, 0x0, 0x6a, 0xa, 0x20, 0x0, 0x0, - 0x8, 0x10, 0xb3, 0x2, 0xd, 0x66, 0x69, 0xb0, - 0x10, 0x4, 0xe2, 0x0, 0x54, 0x10, 0xa, 0x20, - 0x0, 0xc, 0x27, 0xc2, 0x70, 0xd4, 0x31, 0x0, - 0x0, 0x93, 0x0, 0x5a, 0x10, 0xc4, 0x0, 0x0, - 0x6, 0x40, 0x0, 0x10, 0x0, 0xc5, 0x0, 0x0, - 0x21, 0xb6, 0x66, 0xe0, 0x2, 0xa7, 0x0, 0x0, - 0x0, 0xc0, 0x0, 0xc0, 0x6, 0x68, 0x0, 0x0, - 0x0, 0xc0, 0x0, 0xc0, 0xb, 0x15, 0x60, 0x0, - 0x0, 0xc0, 0x0, 0xc0, 0x48, 0x0, 0xd0, 0x0, - 0x0, 0xc6, 0x66, 0xd1, 0xa0, 0x0, 0x7c, 0x10, - 0x0, 0x70, 0x0, 0x57, 0x0, 0x0, 0xc, 0xb1, - 0x0, 0x0, 0x0, 0x20, 0x0, 0x0, 0x0, 0x0, - - /* U+6B4C "歌" */ - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x0, 0x0, 0x40, 0x78, 0x0, 0x0, - 0x4, 0x76, 0x66, 0x6d, 0x61, 0xb4, 0x0, 0x0, - 0x0, 0x66, 0x68, 0xc, 0x0, 0xc0, 0x0, 0x0, - 0x0, 0x84, 0xb, 0xc, 0x5, 0x96, 0x66, 0xe3, - 0x0, 0x88, 0x6b, 0xc, 0x8, 0x5, 0x5, 0x60, - 0x0, 0x72, 0x6, 0x1b, 0x31, 0xf, 0x13, 0x0, - 0x6, 0x66, 0x66, 0x68, 0xb0, 0x1f, 0x10, 0x0, - 0x1, 0x0, 0x0, 0x3a, 0x0, 0x3b, 0x40, 0x0, - 0x1, 0xc6, 0x6c, 0x3a, 0x0, 0x68, 0x70, 0x0, - 0x0, 0xd0, 0xc, 0x3a, 0x0, 0xa4, 0x90, 0x0, - 0x0, 0xe6, 0x6c, 0x3a, 0x0, 0xc0, 0x64, 0x0, - 0x1, 0xb0, 0x5, 0x3a, 0x6, 0x60, 0x1c, 0x0, - 0x0, 0x0, 0x5, 0x7a, 0x29, 0x0, 0x9, 0xb0, - 0x0, 0x0, 0x1, 0xc5, 0x70, 0x0, 0x0, 0xa3, - 0x0, 0x0, 0x0, 0x3, 0x0, 0x0, 0x0, 0x0, - - /* U+6B50 "歐" */ - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x3, 0x0, 0x0, 0x16, 0x9, 0x60, 0x0, 0x0, - 0xc, 0x66, 0x66, 0x65, 0xc, 0x20, 0x0, 0x0, - 0xc, 0x6, 0x66, 0x85, 0xc, 0x0, 0x0, 0x0, - 0xc, 0x9, 0x10, 0x84, 0x5a, 0x66, 0x6d, 0x50, - 0xc, 0x9, 0x10, 0x83, 0x90, 0x51, 0x28, 0x0, - 0xc, 0xa, 0x66, 0xa5, 0x40, 0xa7, 0x30, 0x0, - 0xc, 0x3, 0x0, 0x0, 0x0, 0xb6, 0x0, 0x0, - 0xc, 0x46, 0xc4, 0x98, 0x60, 0xc6, 0x0, 0x0, - 0xc, 0x53, 0xd0, 0xb6, 0x40, 0xe7, 0x0, 0x0, - 0xc, 0x53, 0xd0, 0xb6, 0x42, 0xc5, 0x30, 0x0, - 0xc, 0x58, 0xe0, 0xca, 0x46, 0x71, 0xa0, 0x0, - 0xc, 0x41, 0x10, 0x51, 0xc, 0x10, 0xa4, 0x0, - 0xc, 0x0, 0x0, 0x50, 0x84, 0x0, 0x3f, 0x40, - 0x9, 0x66, 0x66, 0x6a, 0x40, 0x0, 0x7, 0xc1, - 0x0, 0x0, 0x0, 0x40, 0x0, 0x0, 0x0, 0x0, - - /* U+6B61 "歡" */ - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x7, 0x51, 0xb0, 0x0, 0x96, 0x0, 0x0, - 0x4, 0x7a, 0x86, 0xc8, 0x80, 0xd3, 0x0, 0x0, - 0x0, 0x6, 0x20, 0x80, 0x1, 0xd0, 0x0, 0x0, - 0x2, 0x96, 0xa8, 0x6b, 0x36, 0xb6, 0x69, 0xa0, - 0x2, 0xa2, 0x9a, 0xc, 0xa, 0x22, 0x9, 0x10, - 0x2, 0xa9, 0x87, 0x68, 0x26, 0x2d, 0x22, 0x0, - 0x0, 0x2d, 0x38, 0x0, 0x20, 0x3c, 0x0, 0x0, - 0x0, 0xa9, 0x6a, 0x69, 0x60, 0x4b, 0x0, 0x0, - 0x3, 0xd3, 0xc, 0x5, 0x0, 0x78, 0x30, 0x0, - 0x5, 0x88, 0x6d, 0x66, 0x10, 0xa3, 0x70, 0x0, - 0x0, 0x88, 0x6d, 0x69, 0x0, 0xd0, 0x90, 0x0, - 0x0, 0x83, 0xc, 0x2, 0x7, 0x60, 0x48, 0x0, - 0x0, 0x88, 0x69, 0x69, 0x59, 0x0, 0xd, 0x60, - 0x0, 0x92, 0x0, 0x4, 0x70, 0x0, 0x3, 0xc2, - 0x0, 0x0, 0x0, 0x32, 0x0, 0x0, 0x0, 0x0, - - /* U+6B62 "止" */ - 0x0, 0x0, 0x0, 0x0, 0xb4, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x0, 0x0, 0xd1, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x0, 0x0, 0xd1, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x0, 0x0, 0xd1, 0x0, 0x0, 0x0, - 0x0, 0x1, 0xe2, 0x0, 0xd1, 0x0, 0x4, 0x0, - 0x0, 0x0, 0xd0, 0x0, 0xd6, 0x66, 0x8a, 0x20, - 0x0, 0x0, 0xd0, 0x0, 0xc1, 0x0, 0x0, 0x0, - 0x0, 0x0, 0xd0, 0x0, 0xc1, 0x0, 0x0, 0x0, - 0x0, 0x0, 0xd0, 0x0, 0xc1, 0x0, 0x0, 0x0, - 0x0, 0x0, 0xd0, 0x0, 0xc1, 0x0, 0x0, 0x0, - 0x0, 0x0, 0xd0, 0x0, 0xc1, 0x0, 0x0, 0x0, - 0x0, 0x0, 0xd0, 0x0, 0xc1, 0x0, 0x1, 0x0, - 0x5, 0x66, 0xe6, 0x66, 0xd6, 0x66, 0x6d, 0xc0, - 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - - /* U+6B63 "正" */ - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x4, 0x0, - 0x0, 0x57, 0x66, 0x66, 0x96, 0x66, 0x6b, 0x60, - 0x0, 0x0, 0x0, 0x0, 0xe0, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x0, 0x0, 0xe0, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x10, 0x0, 0xe0, 0x0, 0x0, 0x0, - 0x0, 0x0, 0xf2, 0x0, 0xe0, 0x0, 0x0, 0x0, - 0x0, 0x0, 0xe0, 0x0, 0xe6, 0x66, 0xd8, 0x0, - 0x0, 0x0, 0xe0, 0x0, 0xe0, 0x0, 0x0, 0x0, - 0x0, 0x0, 0xe0, 0x0, 0xe0, 0x0, 0x0, 0x0, - 0x0, 0x0, 0xe0, 0x0, 0xe0, 0x0, 0x0, 0x0, - 0x0, 0x0, 0xe0, 0x0, 0xe0, 0x0, 0x0, 0x0, - 0x0, 0x0, 0xe0, 0x0, 0xe0, 0x0, 0x0, 0x0, - 0x0, 0x0, 0xe0, 0x0, 0xe0, 0x0, 0xb, 0x30, - 0x6, 0x76, 0x66, 0x66, 0x66, 0x66, 0x66, 0x50, - - /* U+6B64 "此" */ - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x8, 0x10, 0xd, 0x30, 0x0, 0x0, - 0x0, 0x0, 0xe, 0x0, 0xd, 0x0, 0x0, 0x0, - 0x0, 0x0, 0xe, 0x0, 0xd, 0x0, 0x0, 0x0, - 0x0, 0x40, 0xd, 0x0, 0xd, 0x0, 0x7, 0x10, - 0x0, 0xd3, 0xd, 0x0, 0xd, 0x0, 0x8e, 0x40, - 0x0, 0xc0, 0xd, 0x6b, 0x6d, 0x19, 0x60, 0x0, - 0x0, 0xc0, 0xd, 0x0, 0xd, 0x60, 0x0, 0x0, - 0x0, 0xc0, 0xd, 0x0, 0xd, 0x0, 0x0, 0x0, - 0x0, 0xc0, 0xd, 0x0, 0xd, 0x0, 0x0, 0x0, - 0x0, 0xc0, 0xd, 0x0, 0xd, 0x0, 0x0, 0x0, - 0x0, 0xc0, 0xd, 0x3, 0x3d, 0x0, 0x0, 0x50, - 0x0, 0xc0, 0x4d, 0x72, 0xd, 0x0, 0x0, 0x70, - 0x17, 0xec, 0x60, 0x0, 0xd, 0x10, 0x4, 0xd0, - 0x2c, 0x40, 0x0, 0x0, 0x6, 0xbc, 0xcb, 0x80, - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - - /* U+6B65 "步" */ - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x0, 0xe2, 0x0, 0x0, 0x0, 0x0, - 0x5, 0x0, 0xe, 0x0, 0x0, 0x0, 0x0, 0x0, - 0xe1, 0x0, 0xe6, 0x66, 0xa9, 0x0, 0x0, 0xd, - 0x0, 0xe, 0x0, 0x0, 0x0, 0x0, 0x0, 0xd0, - 0x0, 0xe0, 0x0, 0x0, 0x10, 0x56, 0x6d, 0x66, - 0x6d, 0x66, 0x66, 0xbc, 0x10, 0x0, 0x0, 0x0, - 0xa1, 0x0, 0x0, 0x0, 0x0, 0x3, 0x40, 0xe, - 0x0, 0x0, 0x60, 0x0, 0x0, 0xc7, 0x0, 0xe0, - 0x0, 0xad, 0x20, 0x0, 0x69, 0x0, 0xe, 0x0, - 0x8c, 0x10, 0x0, 0x2a, 0x0, 0x0, 0xf0, 0xaa, - 0x0, 0x0, 0x17, 0x0, 0x0, 0x6, 0xc6, 0x0, - 0x0, 0x1, 0x0, 0x0, 0x29, 0xa1, 0x0, 0x0, - 0x0, 0x0, 0x26, 0x76, 0x10, 0x0, 0x0, 0x0, - 0x3, 0x43, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - - /* U+6B69 "歩" */ - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x0, 0x0, 0xd2, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x72, 0x0, 0xe0, 0x0, 0x0, 0x0, - 0x0, 0x0, 0xd2, 0x0, 0xe6, 0x66, 0xd2, 0x0, - 0x0, 0x0, 0xd1, 0x0, 0xe0, 0x0, 0x0, 0x0, - 0x0, 0x0, 0xd1, 0x0, 0xe0, 0x0, 0x3, 0x20, - 0x6, 0x76, 0xa6, 0x66, 0xb6, 0x66, 0x6a, 0x90, - 0x0, 0x0, 0x0, 0x3, 0xd0, 0x23, 0x0, 0x0, - 0x0, 0x0, 0x98, 0x2, 0xb0, 0x4, 0xb4, 0x0, - 0x0, 0x4, 0xd2, 0x2, 0xb0, 0x1, 0x5e, 0x70, - 0x0, 0x1b, 0x10, 0x2, 0xb0, 0x1d, 0xc4, 0x90, - 0x1, 0x81, 0x0, 0x3, 0xb3, 0xe9, 0x0, 0x0, - 0x1, 0x0, 0x0, 0x0, 0x8d, 0x40, 0x0, 0x0, - 0x0, 0x0, 0x0, 0x6b, 0x60, 0x0, 0x0, 0x0, - 0x0, 0x3, 0x88, 0x40, 0x0, 0x0, 0x0, 0x0, - 0x3, 0x42, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - - /* U+6B6F "歯" */ - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x10, 0xa, 0x50, 0x0, 0x0, 0x0, - 0x0, 0x0, 0xe1, 0xa, 0x30, 0x2, 0x20, 0x0, - 0x0, 0x0, 0xd0, 0xa, 0x86, 0x68, 0x70, 0x0, - 0x0, 0x0, 0xd0, 0xa, 0x30, 0x0, 0x1, 0x0, - 0x5, 0x66, 0xe6, 0x6c, 0x86, 0x66, 0x6e, 0x80, - 0x1, 0x0, 0x0, 0x6, 0x30, 0x11, 0x0, 0x0, - 0x0, 0x92, 0x2a, 0x9, 0x40, 0xa9, 0x5, 0x0, - 0x0, 0xd0, 0x7, 0x59, 0x34, 0x70, 0xe, 0x10, - 0x0, 0xd1, 0x66, 0x6b, 0x8a, 0x6d, 0x4e, 0x0, - 0x0, 0xd0, 0x20, 0x9e, 0x94, 0x0, 0xe, 0x0, - 0x0, 0xd0, 0x4, 0x89, 0x39, 0xb1, 0xe, 0x0, - 0x0, 0xd0, 0x38, 0x9, 0x30, 0x98, 0xe, 0x0, - 0x0, 0xd2, 0x40, 0x8, 0x20, 0x1, 0xe, 0x0, - 0x1, 0xd6, 0x66, 0x66, 0x66, 0x66, 0x6e, 0x0, - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x1, 0x0, - - /* U+6B72 "歲" */ - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x10, 0xb, 0x50, 0x0, 0x0, 0x0, - 0x0, 0x0, 0xc2, 0xa, 0x76, 0x6b, 0x60, 0x0, - 0x0, 0x0, 0xc0, 0xa, 0x20, 0x0, 0x3, 0x20, - 0x7, 0x66, 0x96, 0x68, 0x86, 0x76, 0x69, 0x80, - 0x0, 0x0, 0x0, 0x0, 0x7a, 0xa, 0x41, 0x0, - 0x0, 0x96, 0x66, 0x66, 0x9c, 0x67, 0x8c, 0x30, - 0x0, 0xa3, 0x0, 0x0, 0x2c, 0x0, 0x30, 0x0, - 0x0, 0xa4, 0x77, 0x7b, 0x1e, 0x0, 0xe7, 0x0, - 0x0, 0xb2, 0x15, 0x50, 0xb, 0x36, 0xb0, 0x0, - 0x0, 0xc1, 0xb7, 0x5a, 0x66, 0x9d, 0x20, 0x0, - 0x0, 0xd2, 0x75, 0xac, 0x11, 0xf5, 0x0, 0x10, - 0x1, 0xa3, 0x7, 0xe1, 0xb, 0xba, 0x0, 0x60, - 0x6, 0x30, 0x4a, 0x11, 0xb5, 0xa, 0xb3, 0x90, - 0x7, 0x17, 0x50, 0x68, 0x10, 0x0, 0x8f, 0xc0, - 0x20, 0x30, 0x5, 0x10, 0x0, 0x0, 0x0, 0x40, - - /* U+6B73 "歳" */ - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x20, 0xa, 0x50, 0x1, 0x0, 0x0, - 0x0, 0x0, 0xc2, 0xa, 0x66, 0x6b, 0x60, 0x0, - 0x0, 0x0, 0xc0, 0xa, 0x10, 0x0, 0x6, 0x10, - 0x7, 0x66, 0x96, 0x68, 0x86, 0x76, 0x69, 0x70, - 0x0, 0x0, 0x0, 0x0, 0x8b, 0xb, 0x41, 0x0, - 0x0, 0x96, 0x66, 0x66, 0x9c, 0x67, 0x7c, 0x30, - 0x0, 0xc1, 0x0, 0x1, 0x2b, 0x0, 0x20, 0x0, - 0x0, 0xc5, 0x77, 0x79, 0x6e, 0x0, 0xe7, 0x0, - 0x0, 0xc0, 0x5, 0x60, 0xb, 0x36, 0xc0, 0x0, - 0x0, 0xc0, 0xc6, 0x69, 0x16, 0xad, 0x20, 0x0, - 0x0, 0xc5, 0x55, 0x64, 0xa1, 0xf5, 0x0, 0x0, - 0x2, 0xa5, 0x5, 0x60, 0x3b, 0xc9, 0x0, 0x50, - 0x6, 0x30, 0x6e, 0x21, 0xa4, 0xb, 0xa1, 0x80, - 0x8, 0x0, 0x1, 0x57, 0x0, 0x0, 0x9f, 0xb0, - 0x20, 0x0, 0x4, 0x0, 0x0, 0x0, 0x1, 0x40, - - /* U+6B77 "歷" */ - 0x0, 0x40, 0x0, 0x0, 0x0, 0x0, 0x9, 0x20, - 0x0, 0xd6, 0x66, 0x68, 0x66, 0x66, 0x67, 0x40, - 0x0, 0xd1, 0x37, 0xbb, 0x21, 0x48, 0xc8, 0x0, - 0x0, 0xd2, 0x15, 0x70, 0x3, 0x2c, 0x0, 0x0, - 0x0, 0xd4, 0x69, 0xab, 0x36, 0x6d, 0x69, 0x70, - 0x0, 0xd0, 0xe, 0x91, 0x1, 0xcc, 0x60, 0x0, - 0x0, 0xd0, 0x5a, 0x8c, 0x18, 0x4c, 0x57, 0x0, - 0x0, 0xd1, 0x75, 0x71, 0x64, 0xc, 0x9, 0x90, - 0x0, 0xc5, 0x5, 0x62, 0x35, 0x9, 0x0, 0x0, - 0x0, 0xa0, 0x0, 0x0, 0x1c, 0x0, 0x0, 0x0, - 0x3, 0x70, 0xd, 0x10, 0x1c, 0x66, 0xc3, 0x0, - 0x7, 0x20, 0xc, 0x0, 0x1b, 0x0, 0x0, 0x0, - 0x9, 0x0, 0xc, 0x0, 0x1b, 0x0, 0x0, 0x10, - 0x25, 0x56, 0x6d, 0x66, 0x6c, 0x66, 0x6b, 0xd1, - 0x10, 0x10, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - - /* U+6B7B "死" */ - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x6, 0x10, - 0x7, 0x66, 0x97, 0x66, 0x69, 0x66, 0x6a, 0x80, - 0x0, 0x0, 0xd2, 0x0, 0xc, 0x10, 0x0, 0x0, - 0x0, 0x1, 0xe0, 0x0, 0xc, 0x10, 0x0, 0x0, - 0x0, 0x5, 0x80, 0x15, 0xc, 0x10, 0xa, 0x20, - 0x0, 0xb, 0x76, 0x9d, 0xc, 0x10, 0x9b, 0x20, - 0x0, 0x2b, 0x0, 0x87, 0xc, 0x18, 0x60, 0x0, - 0x0, 0xa8, 0x50, 0xd2, 0xc, 0x72, 0x0, 0x0, - 0x4, 0x60, 0xe3, 0xc0, 0xc, 0x10, 0x0, 0x0, - 0x15, 0x0, 0x2a, 0x40, 0xc, 0x10, 0x0, 0x10, - 0x0, 0x0, 0x4b, 0x0, 0xc, 0x10, 0x0, 0x60, - 0x0, 0x1, 0xb1, 0x0, 0xc, 0x10, 0x1, 0x70, - 0x0, 0x1a, 0x10, 0x0, 0xc, 0x41, 0x16, 0xd1, - 0x3, 0x70, 0x0, 0x0, 0x5, 0xab, 0xba, 0x70, - 0x12, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - - /* U+6B8A "殊" */ - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x0, 0x0, 0x1, 0xc1, 0x0, 0x0, - 0x5, 0x66, 0x6b, 0x64, 0xc0, 0xd0, 0x0, 0x0, - 0x0, 0x3b, 0x0, 0x7, 0x70, 0xd0, 0x4, 0x0, - 0x0, 0x58, 0x0, 0xa, 0x66, 0xe6, 0x79, 0x10, - 0x0, 0x89, 0x6a, 0x38, 0x0, 0xd0, 0x0, 0x0, - 0x0, 0xb1, 0xe, 0x60, 0x0, 0xd0, 0x0, 0x20, - 0x0, 0xc0, 0x2b, 0x56, 0x68, 0xe6, 0x69, 0xb1, - 0x5, 0x88, 0x58, 0x0, 0x1e, 0xd6, 0x0, 0x0, - 0x7, 0xa, 0x94, 0x0, 0x87, 0xd7, 0x10, 0x0, - 0x10, 0x0, 0xc0, 0x2, 0xc0, 0xd2, 0x80, 0x0, - 0x0, 0x5, 0x70, 0xa, 0x10, 0xd0, 0xa5, 0x0, - 0x0, 0xa, 0x0, 0x83, 0x0, 0xd0, 0x1e, 0x70, - 0x0, 0x72, 0x7, 0x20, 0x0, 0xe0, 0x4, 0xa2, - 0x4, 0x30, 0x20, 0x0, 0x0, 0xe0, 0x0, 0x0, - 0x1, 0x0, 0x0, 0x0, 0x0, 0x30, 0x0, 0x0, - - /* U+6B8B "残" */ - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x0, 0x0, 0x9, 0x51, 0x0, 0x0, - 0x6, 0x67, 0x66, 0xc1, 0xa, 0x34, 0x90, 0x0, - 0x0, 0xc, 0x0, 0x0, 0xa, 0x40, 0xa5, 0x0, - 0x0, 0x39, 0x0, 0x0, 0x9, 0x40, 0x16, 0x0, - 0x0, 0x75, 0x1, 0x54, 0x6b, 0x96, 0x67, 0x20, - 0x0, 0xb6, 0x69, 0xb1, 0x8, 0x50, 0x0, 0x0, - 0x1, 0xc0, 0x7, 0x50, 0x7, 0x62, 0x4b, 0x50, - 0x6, 0x4b, 0xb, 0x26, 0x69, 0xb3, 0x13, 0x0, - 0x6, 0xa, 0x3c, 0x0, 0x3, 0xa0, 0x6c, 0x0, - 0x10, 0x0, 0x57, 0x0, 0x0, 0xe3, 0xd1, 0x0, - 0x0, 0x0, 0xb1, 0x0, 0x0, 0xbd, 0x10, 0x0, - 0x0, 0x6, 0x50, 0x0, 0x5, 0xcd, 0x10, 0x50, - 0x0, 0x37, 0x0, 0x1, 0x97, 0x6, 0xc2, 0x80, - 0x2, 0x60, 0x2, 0x56, 0x10, 0x0, 0x6e, 0xd0, - 0x2, 0x0, 0x0, 0x0, 0x0, 0x0, 0x1, 0x60, - - /* U+6BB5 "段" */ - 0x0, 0x0, 0x4, 0xa0, 0x10, 0x2, 0x0, 0x0, - 0x0, 0xa6, 0x86, 0x41, 0xc6, 0x6e, 0x30, 0x0, - 0x0, 0xc0, 0x0, 0x0, 0xc0, 0xd, 0x0, 0x0, - 0x0, 0xc0, 0x2, 0x0, 0xd0, 0xd, 0x0, 0x0, - 0x0, 0xc6, 0x68, 0x51, 0xb0, 0xc, 0x11, 0x0, - 0x0, 0xc0, 0x0, 0x8, 0x30, 0x6, 0xaa, 0x40, - 0x0, 0xc0, 0x3, 0x45, 0x22, 0x23, 0x80, 0x0, - 0x0, 0xc6, 0x66, 0x33, 0x73, 0x38, 0xb0, 0x0, - 0x0, 0xc0, 0x0, 0x0, 0x60, 0xc, 0x30, 0x0, - 0x0, 0xc0, 0x14, 0x62, 0x17, 0x3b, 0x0, 0x0, - 0x27, 0xeb, 0x83, 0x0, 0x8, 0xc2, 0x0, 0x0, - 0x18, 0xd0, 0x0, 0x0, 0xa, 0xd3, 0x0, 0x0, - 0x0, 0xc0, 0x0, 0x3, 0xa3, 0x2d, 0x81, 0x0, - 0x0, 0xd1, 0x4, 0x75, 0x0, 0x1, 0xaf, 0x90, - 0x0, 0x30, 0x31, 0x0, 0x0, 0x0, 0x2, 0x0, - - /* U+6BCD "母" */ - 0x0, 0x1, 0x40, 0x0, 0x0, 0x0, 0x60, 0x0, - 0x0, 0x3, 0xd6, 0x66, 0x66, 0x67, 0xe1, 0x0, - 0x0, 0x5, 0xa0, 0x2a, 0x10, 0x3, 0xb0, 0x0, - 0x0, 0x6, 0x80, 0x8, 0xa0, 0x4, 0xa0, 0x0, - 0x0, 0x8, 0x60, 0x1, 0x80, 0x5, 0x90, 0x0, - 0x16, 0x6b, 0x96, 0x66, 0x66, 0x6a, 0xbb, 0xb0, - 0x1, 0xb, 0x30, 0x20, 0x0, 0x7, 0x70, 0x0, - 0x0, 0xd, 0x10, 0x1c, 0x20, 0x8, 0x60, 0x0, - 0x0, 0xf, 0x0, 0x8, 0xb0, 0xa, 0x50, 0x0, - 0x0, 0x1d, 0x0, 0x1, 0x60, 0xb, 0x40, 0x0, - 0x0, 0x5d, 0x66, 0x66, 0x66, 0x6d, 0x8c, 0x90, - 0x0, 0x14, 0x0, 0x0, 0x0, 0xe, 0x10, 0x0, - 0x0, 0x0, 0x0, 0x0, 0x32, 0x3e, 0x0, 0x0, - 0x0, 0x0, 0x0, 0x0, 0x9, 0xf8, 0x0, 0x0, - 0x0, 0x0, 0x0, 0x0, 0x0, 0x40, 0x0, 0x0, - - /* U+6BCE "毎" */ - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, 0xc5, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x4, 0xf6, 0x66, 0x66, 0x66, 0xbb, 0x0, - 0x0, 0xc, 0x20, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x83, 0x30, 0x0, 0x0, 0x3, 0x30, 0x0, - 0x5, 0x22, 0xd6, 0x68, 0xc6, 0x6b, 0x90, 0x0, - 0x0, 0x4, 0xa0, 0x5, 0x80, 0x9, 0x40, 0x0, - 0x0, 0x5, 0x80, 0x7, 0x70, 0x9, 0x42, 0x0, - 0x26, 0x6a, 0xa6, 0x6b, 0x96, 0x6c, 0x8b, 0x80, - 0x0, 0xa, 0x40, 0xa, 0x30, 0xb, 0x20, 0x0, - 0x0, 0xc, 0x20, 0xc, 0x10, 0xc, 0x20, 0x0, - 0x0, 0xe, 0x0, 0xd, 0x0, 0xc, 0x14, 0x0, - 0x0, 0x3e, 0x66, 0x69, 0x66, 0x6e, 0x6a, 0x40, - 0x0, 0x1, 0x0, 0x0, 0x0, 0xe, 0x0, 0x0, - 0x0, 0x0, 0x0, 0x0, 0x39, 0xda, 0x0, 0x0, - 0x0, 0x0, 0x0, 0x0, 0x0, 0x70, 0x0, 0x0, - - /* U+6BCF "每" */ - 0x0, 0x0, 0x20, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, 0xe5, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x6, 0xe6, 0x66, 0x66, 0x66, 0xcb, 0x0, - 0x0, 0x1d, 0x10, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0xa4, 0x30, 0x0, 0x0, 0x4, 0x30, 0x0, - 0x6, 0x42, 0xd6, 0x77, 0x66, 0x6b, 0x80, 0x0, - 0x22, 0x3, 0xa0, 0xa, 0x80, 0x9, 0x40, 0x0, - 0x0, 0x5, 0x80, 0x1, 0xd0, 0xa, 0x32, 0x0, - 0x26, 0x6a, 0xa6, 0x66, 0x66, 0x6c, 0x8b, 0x90, - 0x0, 0x9, 0x40, 0x27, 0x0, 0xc, 0x20, 0x0, - 0x0, 0xb, 0x20, 0x8, 0xb0, 0xd, 0x10, 0x0, - 0x0, 0xd, 0x0, 0x1, 0x90, 0xe, 0x4, 0x0, - 0x0, 0x2e, 0x66, 0x66, 0x66, 0x6f, 0x6a, 0x50, - 0x0, 0x0, 0x0, 0x0, 0x0, 0x1d, 0x0, 0x0, - 0x0, 0x0, 0x0, 0x0, 0x39, 0xc9, 0x0, 0x0, - 0x0, 0x0, 0x0, 0x0, 0x0, 0x70, 0x0, 0x0, - - /* U+6BD4 "比" */ - 0x26, 0x0, 0x0, 0x9, 0x10, 0x0, 0x0, 0x2c, - 0x0, 0x0, 0xe, 0x0, 0x0, 0x0, 0x2b, 0x0, - 0x0, 0xd, 0x0, 0x3, 0x0, 0x2b, 0x0, 0x0, - 0xd, 0x0, 0x2f, 0x60, 0x2b, 0x0, 0x0, 0xd, - 0x1, 0xc5, 0x0, 0x2d, 0x66, 0x9b, 0xd, 0xa, - 0x30, 0x0, 0x2b, 0x0, 0x0, 0xe, 0x71, 0x0, - 0x0, 0x2b, 0x0, 0x0, 0xd, 0x0, 0x0, 0x0, - 0x2b, 0x0, 0x0, 0xd, 0x0, 0x0, 0x0, 0x2b, - 0x0, 0x0, 0xd, 0x0, 0x0, 0x10, 0x2b, 0x0, - 0x0, 0xd, 0x0, 0x0, 0x60, 0x2b, 0x4, 0x75, - 0xd, 0x0, 0x0, 0x80, 0x4e, 0xd6, 0x0, 0xf, - 0x21, 0x15, 0xe1, 0x9, 0x10, 0x0, 0x7, 0xbb, - 0xbb, 0x70, - - /* U+6BDB "毛" */ - 0x0, 0x0, 0x0, 0x0, 0x0, 0x46, 0x0, 0x0, - 0x0, 0x0, 0x0, 0x25, 0x9d, 0xdb, 0x20, 0x0, - 0x0, 0x35, 0x67, 0x7e, 0x20, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x0, 0xd, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x0, 0xd, 0x0, 0x5, 0x60, 0x0, - 0x0, 0x23, 0x46, 0x6e, 0x66, 0x66, 0x50, 0x0, - 0x0, 0x23, 0x10, 0xd, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x0, 0xd, 0x0, 0x0, 0x9, 0x40, - 0x0, 0x0, 0x23, 0x5e, 0x66, 0x66, 0x66, 0x40, - 0x6, 0x65, 0x32, 0x1d, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x0, 0xd, 0x0, 0x0, 0x0, 0x40, - 0x0, 0x0, 0x0, 0xd, 0x0, 0x0, 0x0, 0x70, - 0x0, 0x0, 0x0, 0xe, 0x0, 0x0, 0x1, 0xc0, - 0x0, 0x0, 0x0, 0xb, 0xdd, 0xdd, 0xdd, 0xb1, - - /* U+6C0F "氏" */ - 0x0, 0x0, 0x0, 0x0, 0x5, 0x0, 0x0, 0x1, - 0x0, 0x3, 0x69, 0xee, 0x80, 0x0, 0xd, 0x66, - 0x67, 0xb2, 0x0, 0x0, 0x0, 0xd, 0x0, 0x2, - 0xb0, 0x0, 0x0, 0x0, 0xd, 0x0, 0x1, 0xc0, - 0x0, 0x0, 0x0, 0xd, 0x0, 0x0, 0xd0, 0x0, - 0x1a, 0x10, 0xe, 0x66, 0x66, 0xe6, 0x66, 0x66, - 0x30, 0xd, 0x0, 0x0, 0xa3, 0x0, 0x0, 0x0, - 0xd, 0x0, 0x0, 0x69, 0x0, 0x0, 0x0, 0xd, - 0x0, 0x0, 0x1e, 0x10, 0x0, 0x0, 0xd, 0x0, - 0x4, 0x18, 0xb0, 0x0, 0x40, 0xd, 0x5, 0x92, - 0x0, 0xca, 0x0, 0x80, 0x1f, 0xd7, 0x0, 0x0, - 0xb, 0xd6, 0x90, 0x1d, 0x30, 0x0, 0x0, 0x0, - 0x6e, 0xc0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x30, - - /* U+6C11 "民" */ - 0x3, 0x0, 0x0, 0x0, 0x0, 0x50, 0x0, 0x0, - 0xb7, 0x66, 0x66, 0x66, 0x6e, 0x30, 0x0, 0xb, - 0x20, 0x0, 0x0, 0x0, 0xe0, 0x0, 0x0, 0xb2, - 0x0, 0x0, 0x0, 0xe, 0x0, 0x0, 0xb, 0x76, - 0x66, 0xc6, 0x66, 0xe0, 0x0, 0x0, 0xb2, 0x0, - 0xd, 0x0, 0x1, 0x0, 0x0, 0xb, 0x20, 0x0, - 0xb2, 0x0, 0x0, 0x50, 0x0, 0xb7, 0x66, 0x6b, - 0x86, 0x66, 0x89, 0x30, 0xb, 0x20, 0x0, 0x58, - 0x0, 0x0, 0x0, 0x0, 0xb2, 0x0, 0x0, 0xd0, - 0x0, 0x0, 0x0, 0xb, 0x20, 0x0, 0x8, 0x80, - 0x0, 0x11, 0x0, 0xb2, 0x6, 0x50, 0xd, 0x60, - 0x5, 0x20, 0xc, 0xac, 0x30, 0x0, 0x2d, 0x91, - 0x92, 0x0, 0xc9, 0x0, 0x0, 0x0, 0x19, 0xff, - 0x50, 0x0, 0x0, 0x0, 0x0, 0x0, 0x1, 0x43, - 0x0, - - /* U+6C14 "气" */ - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x97, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, 0xe2, 0x0, 0x0, 0x0, 0x13, 0x0, - 0x0, 0x7, 0xb6, 0x66, 0x66, 0x66, 0xaa, 0x10, - 0x0, 0xc, 0x0, 0x0, 0x0, 0x2, 0x0, 0x0, - 0x0, 0x83, 0x27, 0x66, 0x66, 0x69, 0x60, 0x0, - 0x3, 0x60, 0x0, 0x0, 0x0, 0x3, 0x0, 0x0, - 0x5, 0x7, 0x66, 0x66, 0x66, 0x8d, 0x0, 0x0, - 0x0, 0x0, 0x0, 0x0, 0x0, 0x2a, 0x0, 0x0, - 0x0, 0x0, 0x0, 0x0, 0x0, 0x2b, 0x0, 0x0, - 0x0, 0x0, 0x0, 0x0, 0x0, 0x1c, 0x0, 0x0, - 0x0, 0x0, 0x0, 0x0, 0x0, 0xe, 0x0, 0x0, - 0x0, 0x0, 0x0, 0x0, 0x0, 0xb, 0x30, 0x60, - 0x0, 0x0, 0x0, 0x0, 0x0, 0x4, 0xc1, 0x90, - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x6f, 0xc0, - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x1, 0x60, - - /* U+6C17 "気" */ - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, 0xc4, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x2, 0xe0, 0x0, 0x0, 0x0, 0x37, 0x0, - 0x0, 0x9, 0x86, 0x66, 0x66, 0x66, 0x66, 0x10, - 0x0, 0x2a, 0x46, 0x66, 0x66, 0x6a, 0x70, 0x0, - 0x0, 0xa1, 0x0, 0x0, 0x0, 0x1, 0x0, 0x0, - 0x6, 0x26, 0x76, 0x66, 0x66, 0x6d, 0x50, 0x0, - 0x12, 0x0, 0x0, 0x0, 0xb5, 0xd, 0x0, 0x0, - 0x0, 0x4, 0x0, 0x4, 0xd1, 0xd, 0x0, 0x0, - 0x0, 0x0, 0x66, 0x2d, 0x20, 0xc, 0x0, 0x0, - 0x0, 0x0, 0x3, 0xf9, 0x0, 0xa, 0x20, 0x0, - 0x0, 0x0, 0x9, 0x7c, 0xa0, 0x8, 0x50, 0x10, - 0x0, 0x0, 0x95, 0x0, 0xd7, 0x3, 0xb0, 0x50, - 0x0, 0x18, 0x20, 0x0, 0x35, 0x0, 0xc4, 0x80, - 0x1, 0x40, 0x0, 0x0, 0x0, 0x0, 0x2e, 0xd0, - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x60, - - /* U+6C34 "水" */ - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x0, 0xc, 0x50, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x0, 0xc, 0x20, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x0, 0xc, 0x30, 0x0, 0x30, 0x0, - 0x0, 0x0, 0x0, 0xc, 0x60, 0x2, 0xe6, 0x0, - 0x5, 0x66, 0x6d, 0x2c, 0x80, 0x2a, 0x20, 0x0, - 0x1, 0x0, 0x3c, 0xc, 0x67, 0x60, 0x0, 0x0, - 0x0, 0x0, 0x87, 0xc, 0x2a, 0x0, 0x0, 0x0, - 0x0, 0x0, 0xd1, 0xc, 0x27, 0x40, 0x0, 0x0, - 0x0, 0x5, 0x90, 0xc, 0x21, 0xd1, 0x0, 0x0, - 0x0, 0xc, 0x10, 0xc, 0x20, 0x7b, 0x0, 0x0, - 0x0, 0x76, 0x0, 0xc, 0x20, 0xb, 0xb0, 0x0, - 0x2, 0x80, 0x0, 0xc, 0x20, 0x1, 0xcd, 0x60, - 0x16, 0x0, 0x2, 0x1d, 0x20, 0x0, 0x9, 0x30, - 0x0, 0x0, 0x5, 0xde, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x0, 0x21, 0x0, 0x0, 0x0, 0x0, - - /* U+6C37 "氷" */ - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x0, 0xb5, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, 0xb, 0x30, 0x0, 0x0, 0x0, 0x5, - 0x20, 0x0, 0xb3, 0x0, 0x3, 0x0, 0x0, 0xb, - 0xb0, 0xb, 0x40, 0x6, 0xd0, 0x0, 0x0, 0xc, - 0x30, 0xb9, 0x3, 0xb1, 0x0, 0x0, 0x0, 0x3, - 0x1b, 0xa4, 0x80, 0x0, 0x0, 0x57, 0x66, 0xd6, - 0xb5, 0x90, 0x0, 0x0, 0x0, 0x0, 0x1d, 0xb, - 0x3b, 0x10, 0x0, 0x0, 0x0, 0x8, 0x60, 0xb3, - 0x5a, 0x0, 0x0, 0x0, 0x1, 0xc0, 0xb, 0x30, - 0xc7, 0x0, 0x0, 0x0, 0xa3, 0x0, 0xb3, 0x2, - 0xf7, 0x0, 0x0, 0x76, 0x0, 0xb, 0x30, 0x5, - 0xfb, 0x30, 0x66, 0x0, 0x0, 0xc3, 0x0, 0x4, - 0xb3, 0x32, 0x0, 0x6, 0xdf, 0x10, 0x0, 0x0, - 0x0, 0x0, 0x0, 0x1, 0x40, 0x0, 0x0, 0x0, - - /* U+6C38 "永" */ - 0x0, 0x0, 0x0, 0x39, 0x40, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x0, 0x2, 0xf2, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x0, 0x0, 0x40, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x47, 0x66, 0xe3, 0x0, 0x11, 0x0, - 0x0, 0x0, 0x0, 0x0, 0xf1, 0x0, 0x9b, 0x0, - 0x0, 0x0, 0x2, 0x0, 0xe6, 0x4, 0xb0, 0x0, - 0x2, 0x86, 0x6d, 0x70, 0xe7, 0x29, 0x0, 0x0, - 0x0, 0x0, 0x1e, 0x0, 0xe4, 0xa0, 0x0, 0x0, - 0x0, 0x0, 0x87, 0x0, 0xe0, 0xb1, 0x0, 0x0, - 0x0, 0x1, 0xd0, 0x0, 0xe0, 0x5b, 0x0, 0x0, - 0x0, 0x9, 0x40, 0x0, 0xe0, 0xa, 0x90, 0x0, - 0x0, 0x57, 0x0, 0x0, 0xe0, 0x0, 0xdc, 0x30, - 0x2, 0x70, 0x2, 0x44, 0xd0, 0x0, 0x1b, 0xa1, - 0x4, 0x0, 0x0, 0x4e, 0x90, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x0, 0x2, 0x0, 0x0, 0x0, 0x0, - - /* U+6C42 "求" */ - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x0, 0xb, 0x31, 0x40, 0x0, 0x0, - 0x0, 0x0, 0x0, 0xd, 0x10, 0x6d, 0x20, 0x0, - 0x0, 0x0, 0x0, 0xd, 0x10, 0x8, 0x42, 0x0, - 0x5, 0x66, 0x66, 0x6e, 0x66, 0x66, 0x8e, 0x20, - 0x0, 0x0, 0x0, 0xd, 0x50, 0x0, 0x0, 0x0, - 0x0, 0x28, 0x10, 0xd, 0x70, 0x0, 0x80, 0x0, - 0x0, 0x5, 0xf2, 0xd, 0x71, 0x8, 0xc3, 0x0, - 0x0, 0x0, 0xb4, 0xd, 0x38, 0x86, 0x0, 0x0, - 0x0, 0x0, 0x0, 0x4e, 0x1a, 0x30, 0x0, 0x0, - 0x0, 0x0, 0x49, 0x2d, 0x12, 0xd1, 0x0, 0x0, - 0x0, 0x4b, 0x70, 0xd, 0x10, 0x6d, 0x20, 0x0, - 0x2d, 0xc2, 0x0, 0xd, 0x10, 0x8, 0xf8, 0x20, - 0x6, 0x0, 0x1, 0x1e, 0x10, 0x0, 0x5e, 0x80, - 0x0, 0x0, 0x6, 0xfd, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x0, 0x31, 0x0, 0x0, 0x0, 0x0, - - /* U+6C5A "汚" */ - 0x0, 0x50, 0x0, 0x0, 0x0, 0x0, 0x25, 0x0, - 0x0, 0x2d, 0x11, 0x86, 0x7d, 0x66, 0x65, 0x0, - 0x0, 0xa, 0x20, 0x0, 0x3a, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x3, 0x0, 0x67, 0x0, 0x0, 0x0, - 0x19, 0x10, 0x46, 0x66, 0xb9, 0x66, 0x67, 0xc1, - 0x5, 0xd0, 0x60, 0x0, 0xb2, 0x0, 0x0, 0x0, - 0x0, 0x80, 0x60, 0x0, 0xd0, 0x0, 0x0, 0x0, - 0x0, 0x5, 0x20, 0x5, 0xd6, 0x66, 0x6b, 0x10, - 0x0, 0x9, 0x0, 0x1, 0x40, 0x0, 0x4c, 0x0, - 0x2, 0x49, 0x0, 0x0, 0x0, 0x0, 0x68, 0x0, - 0x4, 0xe5, 0x0, 0x0, 0x0, 0x0, 0x86, 0x0, - 0x0, 0xb3, 0x0, 0x0, 0x0, 0x0, 0xb3, 0x0, - 0x0, 0xd3, 0x0, 0x0, 0x4, 0x13, 0xe0, 0x0, - 0x0, 0xa3, 0x0, 0x0, 0x1, 0xbf, 0x70, 0x0, - 0x0, 0x0, 0x0, 0x0, 0x0, 0x14, 0x0, 0x0, - - /* U+6C60 "池" */ - 0x0, 0x71, 0x0, 0x0, 0x6, 0x10, 0x0, 0x0, - 0x3, 0xe0, 0x0, 0x0, 0xd0, 0x0, 0x0, 0x0, - 0x9, 0x10, 0x30, 0xd, 0x0, 0x0, 0x1, 0x0, - 0x4, 0xb, 0x30, 0xd0, 0x3, 0x10, 0x3a, 0x10, - 0x50, 0xb1, 0xd, 0x45, 0xb7, 0x0, 0x7a, 0x5, - 0x1c, 0x65, 0xd0, 0x8, 0x40, 0x1, 0x55, 0x34, - 0xb1, 0xd, 0x0, 0x84, 0x0, 0x0, 0x80, 0xb, - 0x10, 0xd0, 0x9, 0x30, 0x0, 0x17, 0x0, 0xb1, - 0xd, 0x0, 0xa3, 0x0, 0x9, 0x30, 0xb, 0x10, - 0xd4, 0xae, 0x0, 0x19, 0xf0, 0x0, 0xb1, 0xe, - 0x2, 0x33, 0x20, 0x1d, 0x0, 0xb, 0x10, 0x50, - 0x0, 0x44, 0x4, 0xd0, 0x0, 0xb3, 0x0, 0x0, - 0x7, 0xc0, 0x3c, 0x0, 0x4, 0xbc, 0xcc, 0xcc, - 0xb5, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, - - /* U+6C7A "決" */ - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x43, 0x0, 0x0, 0xd, 0x20, 0x0, 0x0, 0x0, - 0xd4, 0x0, 0x0, 0xe0, 0x0, 0x0, 0x0, 0x5, - 0x60, 0x10, 0xe, 0x0, 0x10, 0x0, 0x0, 0x0, - 0x53, 0x76, 0xe6, 0x6c, 0x60, 0x6, 0x60, 0x6, - 0x0, 0xd, 0x0, 0xb3, 0x0, 0xc, 0x54, 0x20, - 0x0, 0xd0, 0xb, 0x30, 0x0, 0x43, 0x80, 0x0, - 0xd, 0x0, 0xb3, 0x0, 0x0, 0x27, 0x56, 0x66, - 0xd6, 0x6c, 0x9c, 0x10, 0x9, 0x11, 0x10, 0x49, - 0x50, 0x0, 0x0, 0x46, 0xb0, 0x0, 0x9, 0x48, - 0x10, 0x0, 0x0, 0xa8, 0x0, 0x1, 0xd0, 0x2b, - 0x0, 0x0, 0x8, 0x70, 0x0, 0x95, 0x0, 0xa8, - 0x0, 0x0, 0xa7, 0x0, 0x68, 0x0, 0x1, 0xda, - 0x10, 0x4, 0x40, 0x57, 0x0, 0x0, 0x2, 0xdd, - 0x10, 0x0, 0x12, 0x0, 0x0, 0x0, 0x0, 0x0, - - /* U+6C88 "沈" */ - 0x0, 0x10, 0x0, 0x0, 0x3b, 0x0, 0x0, 0x0, - 0x0, 0x87, 0x0, 0x0, 0x3b, 0x0, 0x0, 0x0, - 0x0, 0xe, 0x0, 0x20, 0x3b, 0x0, 0x0, 0x0, - 0x0, 0x1, 0x11, 0xb6, 0x7c, 0x66, 0x6e, 0x30, - 0x15, 0x0, 0x48, 0x70, 0x3a, 0x0, 0x35, 0x0, - 0x8, 0x90, 0x52, 0x0, 0x49, 0x0, 0x10, 0x0, - 0x0, 0x63, 0x20, 0x0, 0x6d, 0x50, 0x0, 0x0, - 0x0, 0x7, 0x0, 0x0, 0x9c, 0x60, 0x0, 0x0, - 0x0, 0x8, 0x0, 0x0, 0xd8, 0x60, 0x0, 0x0, - 0x0, 0x65, 0x0, 0x3, 0xb7, 0x60, 0x0, 0x0, - 0x18, 0xf2, 0x0, 0xa, 0x37, 0x60, 0x0, 0x30, - 0x0, 0xf0, 0x0, 0x48, 0x7, 0x60, 0x0, 0x60, - 0x1, 0xf0, 0x2, 0x90, 0x6, 0x60, 0x0, 0xa0, - 0x3, 0xf0, 0x37, 0x0, 0x3, 0xdb, 0xbb, 0xc1, - 0x0, 0x31, 0x30, 0x0, 0x0, 0x0, 0x0, 0x0, - - /* U+6C92 "沒" */ - 0x0, 0x31, 0x0, 0x2, 0xb0, 0x0, 0x0, 0x0, - 0x0, 0x1d, 0x30, 0x7, 0x80, 0x0, 0x23, 0x0, - 0x0, 0x6, 0x71, 0xb, 0x66, 0x66, 0xaa, 0x0, - 0x0, 0x0, 0x5, 0x38, 0x0, 0x0, 0x85, 0x0, - 0x8, 0x20, 0x5, 0x90, 0x0, 0x0, 0xb2, 0x0, - 0x2, 0xe1, 0x47, 0x20, 0x0, 0x2b, 0xc0, 0x0, - 0x0, 0x81, 0x81, 0x66, 0x66, 0x67, 0x95, 0x0, - 0x0, 0x2, 0x60, 0x6, 0x0, 0x0, 0xd5, 0x0, - 0x0, 0x9, 0x10, 0x7, 0x0, 0x5, 0xa0, 0x0, - 0x4, 0x5a, 0x0, 0x2, 0x80, 0x1d, 0x10, 0x0, - 0x1, 0xc7, 0x0, 0x0, 0x95, 0xc4, 0x0, 0x0, - 0x0, 0x95, 0x0, 0x0, 0x1f, 0xa0, 0x0, 0x0, - 0x0, 0xb5, 0x0, 0x3, 0xc5, 0xab, 0x40, 0x0, - 0x0, 0x74, 0x3, 0x98, 0x10, 0x5, 0xee, 0xa2, - 0x0, 0x0, 0x54, 0x0, 0x0, 0x0, 0x5, 0x30, - - /* U+6CB9 "油" */ - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x0, 0x0, 0xb4, 0x0, 0x0, 0x0, - 0x4a, 0x10, 0x0, 0xb, 0x10, 0x0, 0x0, 0x0, - 0x96, 0x0, 0x0, 0xb1, 0x0, 0x0, 0x0, 0x1, - 0x14, 0x86, 0x6d, 0x66, 0x6b, 0x10, 0x60, 0x0, - 0x4d, 0x0, 0xb1, 0x0, 0xd0, 0x6, 0xb0, 0x50, - 0xd0, 0xb, 0x10, 0xd, 0x0, 0xa, 0x7, 0xd, - 0x0, 0xb1, 0x0, 0xd0, 0x0, 0x3, 0x60, 0xd0, - 0xb, 0x10, 0xd, 0x0, 0x0, 0x91, 0xd, 0x66, - 0xd6, 0x66, 0xd0, 0x0, 0x1b, 0x0, 0xd0, 0xb, - 0x10, 0xd, 0x0, 0x7e, 0x70, 0xd, 0x0, 0xb1, - 0x0, 0xd0, 0x0, 0xc4, 0x0, 0xd0, 0xb, 0x10, - 0xd, 0x0, 0xd, 0x40, 0xd, 0x66, 0xc6, 0x66, - 0xd0, 0x0, 0xe4, 0x0, 0xd0, 0x0, 0x0, 0xd, - 0x0, 0x1, 0x0, 0x1, 0x0, 0x0, 0x0, 0x10, - - /* U+6CBB "治" */ - 0x1, 0x0, 0x0, 0x0, 0x63, 0x0, 0x0, 0x0, - 0x1c, 0x40, 0x0, 0xe, 0x50, 0x0, 0x0, 0x0, - 0x5b, 0x1, 0x7, 0x60, 0x1, 0x0, 0x0, 0x0, - 0x21, 0x31, 0x90, 0x0, 0x83, 0x0, 0x50, 0x0, - 0x50, 0x90, 0x0, 0x0, 0xc5, 0x3, 0xd1, 0x6, - 0xbc, 0xa8, 0x76, 0x67, 0xf0, 0xb, 0x33, 0x44, - 0x30, 0x0, 0x0, 0x7, 0x0, 0x0, 0x80, 0x3, - 0x0, 0x0, 0x5, 0x0, 0x0, 0x19, 0x0, 0xe6, - 0x66, 0x67, 0xc0, 0x0, 0x8, 0x50, 0xd, 0x0, - 0x0, 0x2a, 0x0, 0x29, 0xf1, 0x0, 0xd0, 0x0, - 0x2, 0xa0, 0x0, 0x1f, 0x0, 0xd, 0x0, 0x0, - 0x2a, 0x0, 0x3, 0xe0, 0x0, 0xd6, 0x66, 0x67, - 0xa0, 0x0, 0x3d, 0x0, 0xd, 0x0, 0x0, 0x2a, - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, - - /* U+6CC1 "況" */ - 0x0, 0x30, 0x0, 0x30, 0x0, 0x0, 0x3, 0x0, - 0x0, 0x1d, 0x20, 0xb7, 0x66, 0x66, 0x7d, 0x0, - 0x0, 0x8, 0x61, 0xa2, 0x0, 0x0, 0x2b, 0x0, - 0x0, 0x0, 0x5, 0xa2, 0x0, 0x0, 0x2b, 0x0, - 0x27, 0x0, 0x41, 0xa2, 0x0, 0x0, 0x2b, 0x0, - 0x8, 0x90, 0x60, 0xa2, 0x0, 0x0, 0x2b, 0x0, - 0x1, 0x92, 0x50, 0xb7, 0xd6, 0xe6, 0x7a, 0x0, - 0x0, 0x8, 0x0, 0x10, 0xd0, 0xd0, 0x0, 0x0, - 0x0, 0x19, 0x0, 0x0, 0xd0, 0xd0, 0x0, 0x0, - 0x24, 0xa4, 0x0, 0x2, 0xb0, 0xd0, 0x0, 0x0, - 0x5, 0xf0, 0x0, 0x7, 0x60, 0xd0, 0x0, 0x20, - 0x0, 0xf0, 0x0, 0x1c, 0x0, 0xd0, 0x0, 0x60, - 0x3, 0xf0, 0x1, 0xb2, 0x0, 0xc0, 0x0, 0xb0, - 0x1, 0xa0, 0x38, 0x10, 0x0, 0x8c, 0xbb, 0xc1, - 0x0, 0x0, 0x30, 0x0, 0x0, 0x0, 0x0, 0x0, - - /* U+6CCA "泊" */ - 0x1, 0x0, 0x0, 0x0, 0x28, 0x0, 0x0, 0x1, - 0xb2, 0x0, 0x0, 0x5a, 0x0, 0x0, 0x0, 0x79, - 0x0, 0x0, 0x80, 0x0, 0x10, 0x0, 0x2, 0x5, - 0xc6, 0x76, 0x66, 0xd5, 0x41, 0x0, 0x51, 0xc0, - 0x0, 0x0, 0xd1, 0x1d, 0x30, 0x60, 0xc0, 0x0, - 0x0, 0xd1, 0x6, 0x84, 0x30, 0xc0, 0x0, 0x0, - 0xd1, 0x0, 0x8, 0x0, 0xd6, 0x66, 0x66, 0xe1, - 0x0, 0x27, 0x0, 0xc0, 0x0, 0x0, 0xd1, 0x0, - 0xa2, 0x0, 0xc0, 0x0, 0x0, 0xd1, 0x3b, 0xd0, - 0x0, 0xc0, 0x0, 0x0, 0xd1, 0x3, 0xb0, 0x0, - 0xc0, 0x0, 0x0, 0xd1, 0x5, 0xb0, 0x0, 0xd6, - 0x66, 0x66, 0xe1, 0x5, 0xb0, 0x1, 0xc0, 0x0, - 0x0, 0xc1, 0x0, 0x0, 0x0, 0x10, 0x0, 0x0, - 0x10, - - /* U+6CD5 "法" */ - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x40, 0x0, 0x0, 0xb, 0x50, 0x0, 0x0, - 0x0, 0x3d, 0x10, 0x0, 0xb, 0x10, 0x0, 0x0, - 0x0, 0xa, 0x31, 0x0, 0xb, 0x10, 0x1, 0x0, - 0x0, 0x0, 0x5, 0x76, 0x6d, 0x66, 0x79, 0x0, - 0x37, 0x0, 0x50, 0x0, 0xb, 0x10, 0x0, 0x0, - 0x9, 0x90, 0x60, 0x0, 0xb, 0x10, 0x0, 0x0, - 0x1, 0x83, 0x40, 0x0, 0xb, 0x10, 0x1, 0x40, - 0x0, 0x8, 0x18, 0x66, 0x6d, 0x66, 0x67, 0x70, - 0x0, 0x18, 0x0, 0x0, 0x6d, 0x10, 0x0, 0x0, - 0x23, 0xb3, 0x0, 0x1, 0xd2, 0x0, 0x0, 0x0, - 0x5, 0xf0, 0x0, 0x9, 0x40, 0x6, 0x30, 0x0, - 0x0, 0xe0, 0x0, 0x56, 0x0, 0x0, 0xb5, 0x0, - 0x3, 0xe0, 0x7, 0xb6, 0x78, 0x76, 0x6e, 0x40, - 0x1, 0xa0, 0x9, 0xb6, 0x30, 0x0, 0x8, 0x40, - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - - /* U+6CE2 "波" */ - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x50, 0x0, 0x0, 0x2, 0xc0, 0x0, 0x0, - 0x0, 0x3d, 0x0, 0x0, 0x1, 0xb0, 0x0, 0x0, - 0x0, 0xa, 0x11, 0x20, 0x1, 0xb0, 0x2, 0x20, - 0x0, 0x0, 0x5, 0xd6, 0x66, 0xd6, 0x6c, 0xb0, - 0x19, 0x10, 0x23, 0xd0, 0x1, 0xb0, 0x17, 0x0, - 0x4, 0xd0, 0x60, 0xd0, 0x1, 0xb0, 0x0, 0x0, - 0x0, 0x71, 0x60, 0xd5, 0x66, 0xd6, 0x6a, 0x0, - 0x0, 0x7, 0x10, 0xd0, 0x50, 0x0, 0x78, 0x0, - 0x0, 0xa, 0x0, 0xc0, 0x33, 0x0, 0xd0, 0x0, - 0x12, 0x86, 0x3, 0x90, 0x9, 0x9, 0x50, 0x0, - 0x5, 0xf2, 0x7, 0x40, 0x2, 0xc9, 0x0, 0x0, - 0x0, 0xe0, 0xb, 0x0, 0x4, 0xcb, 0x0, 0x0, - 0x0, 0xf0, 0x63, 0x0, 0x89, 0x5, 0xd5, 0x0, - 0x0, 0xb3, 0x50, 0x68, 0x30, 0x0, 0x3d, 0xc1, - 0x0, 0x2, 0x4, 0x10, 0x0, 0x0, 0x0, 0x0, - - /* U+6CE3 "泣" */ - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x30, 0x0, 0x0, 0x91, 0x0, 0x0, 0x0, - 0x0, 0x3d, 0x10, 0x0, 0x4d, 0x0, 0x0, 0x0, - 0x0, 0xa, 0x40, 0x0, 0xb, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x2, 0x66, 0x66, 0x66, 0xad, 0x10, - 0x8, 0x10, 0x4, 0x10, 0x0, 0x0, 0x0, 0x0, - 0x4, 0xe0, 0x50, 0x20, 0x0, 0xa, 0x60, 0x0, - 0x0, 0x90, 0x70, 0x52, 0x0, 0xd, 0x30, 0x0, - 0x0, 0x3, 0x50, 0xb, 0x0, 0xe, 0x0, 0x0, - 0x0, 0x9, 0x10, 0xc, 0x30, 0x39, 0x0, 0x0, - 0x1, 0x3b, 0x0, 0x9, 0x80, 0x64, 0x0, 0x0, - 0x5, 0xe7, 0x0, 0x7, 0x80, 0x90, 0x0, 0x0, - 0x0, 0xa5, 0x0, 0x1, 0x10, 0x80, 0x0, 0x0, - 0x0, 0xc5, 0x0, 0x0, 0x3, 0x40, 0x7, 0x60, - 0x0, 0xa4, 0x37, 0x66, 0x66, 0x66, 0x66, 0x50, - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - - /* U+6CE8 "注" */ - 0x0, 0x20, 0x0, 0x0, 0x60, 0x0, 0x0, 0x0, - 0x6, 0xa0, 0x0, 0x4, 0xe2, 0x0, 0x0, 0x0, - 0xd, 0x30, 0x0, 0xb, 0x30, 0x1, 0x0, 0x0, - 0x31, 0x56, 0x66, 0x66, 0x67, 0xf4, 0x32, 0x0, - 0x50, 0x20, 0xe, 0x0, 0x0, 0x0, 0xc6, 0x7, - 0x0, 0x0, 0xe0, 0x0, 0x0, 0x4, 0xb2, 0x50, - 0x0, 0xe, 0x0, 0x0, 0x0, 0x1, 0x81, 0x0, - 0x0, 0xe0, 0x7, 0x30, 0x0, 0xa, 0x2, 0x86, - 0x6e, 0x66, 0x65, 0x0, 0x6, 0x70, 0x0, 0x0, - 0xe0, 0x0, 0x0, 0x29, 0xf2, 0x0, 0x0, 0xe, - 0x0, 0x0, 0x0, 0x1f, 0x0, 0x0, 0x0, 0xe0, - 0x0, 0x0, 0x3, 0xe0, 0x0, 0x0, 0xe, 0x0, - 0x8, 0x30, 0x4e, 0x4, 0x76, 0x66, 0x66, 0x66, - 0x75, 0x0, 0x10, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, - - /* U+6CF3 "泳" */ - 0x0, 0x40, 0x0, 0x2, 0xa8, 0x0, 0x0, 0x0, - 0x2, 0xd2, 0x0, 0x0, 0xa7, 0x0, 0x0, 0x0, - 0x9, 0x40, 0x0, 0x5, 0x20, 0x0, 0x0, 0x0, - 0x2, 0x25, 0x76, 0xe4, 0x0, 0x20, 0x18, 0x10, - 0x50, 0x0, 0xe, 0x40, 0x5d, 0x10, 0x6d, 0x7, - 0x0, 0x30, 0xe6, 0x38, 0x0, 0x0, 0x82, 0x67, - 0x7f, 0x2e, 0x84, 0x0, 0x0, 0x0, 0x81, 0x3, - 0xa0, 0xe6, 0x30, 0x0, 0x0, 0xa, 0x0, 0x66, - 0xe, 0x19, 0x0, 0x0, 0x27, 0x80, 0xb, 0x10, - 0xe0, 0xb3, 0x0, 0x5, 0xf5, 0x3, 0x90, 0xe, - 0x3, 0xd1, 0x0, 0xe, 0x30, 0xa0, 0x0, 0xe0, - 0xa, 0xd3, 0x1, 0xf2, 0x62, 0x11, 0x1f, 0x0, - 0xb, 0x70, 0xc, 0x20, 0x0, 0x6f, 0xd0, 0x0, - 0x0, 0x0, 0x0, 0x0, 0x0, 0x31, 0x0, 0x0, - 0x0, - - /* U+6D0B "洋" */ - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x10, 0x0, 0x24, 0x0, 0x8, 0x70, 0x0, - 0x0, 0x78, 0x0, 0xa, 0x80, 0xd, 0x20, 0x0, - 0x0, 0xd, 0x30, 0x2, 0xd0, 0x46, 0x0, 0x0, - 0x0, 0x3, 0x4, 0x66, 0x76, 0xa6, 0x7e, 0x30, - 0x13, 0x0, 0x22, 0x20, 0xc, 0x10, 0x0, 0x0, - 0x9, 0xa0, 0x60, 0x0, 0xc, 0x10, 0x10, 0x0, - 0x1, 0xd0, 0x70, 0x66, 0x6d, 0x66, 0xa8, 0x0, - 0x0, 0x3, 0x50, 0x0, 0xc, 0x10, 0x0, 0x0, - 0x0, 0x9, 0x0, 0x0, 0xc, 0x10, 0x0, 0x0, - 0x0, 0x1b, 0x5, 0x66, 0x6d, 0x66, 0x6c, 0x90, - 0x6, 0xd8, 0x1, 0x0, 0xc, 0x10, 0x0, 0x0, - 0x0, 0xb5, 0x0, 0x0, 0xc, 0x10, 0x0, 0x0, - 0x0, 0xd4, 0x0, 0x0, 0xc, 0x10, 0x0, 0x0, - 0x0, 0xe4, 0x0, 0x0, 0xd, 0x10, 0x0, 0x0, - 0x0, 0x10, 0x0, 0x0, 0x5, 0x0, 0x0, 0x0, - - /* U+6D17 "洗" */ - 0x0, 0x10, 0x0, 0x0, 0x7, 0x20, 0x0, 0x0, - 0x0, 0x88, 0x0, 0x38, 0xb, 0x10, 0x0, 0x0, - 0x0, 0xe, 0x0, 0x79, 0xb, 0x0, 0x0, 0x0, - 0x0, 0x1, 0x4, 0xb8, 0x6c, 0x66, 0xc9, 0x0, - 0x16, 0x0, 0x41, 0x90, 0xb, 0x0, 0x0, 0x0, - 0x6, 0xc0, 0x66, 0x10, 0xb, 0x0, 0x0, 0x0, - 0x0, 0x90, 0x61, 0x0, 0xb, 0x0, 0x6, 0x30, - 0x0, 0x4, 0x47, 0x67, 0xc6, 0xb8, 0x66, 0x40, - 0x0, 0x9, 0x0, 0x3, 0xa0, 0x93, 0x0, 0x0, - 0x0, 0x1b, 0x0, 0x5, 0x80, 0x93, 0x0, 0x0, - 0x6, 0xe9, 0x0, 0x9, 0x50, 0x93, 0x0, 0x20, - 0x0, 0x97, 0x0, 0xd, 0x0, 0x93, 0x0, 0x60, - 0x0, 0xd6, 0x0, 0xa5, 0x0, 0x94, 0x1, 0xa0, - 0x0, 0xc6, 0x19, 0x40, 0x0, 0x4d, 0xbc, 0xb0, - 0x0, 0x1, 0x30, 0x0, 0x0, 0x0, 0x0, 0x0, - - /* U+6D32 "洲" */ - 0x0, 0x41, 0x0, 0x13, 0x0, 0x0, 0x8, 0x20, - 0x1, 0xd2, 0x3, 0xc0, 0x9, 0x10, 0xb2, 0x0, - 0x7, 0x32, 0x2a, 0x0, 0xc0, 0xb, 0x10, 0x0, - 0x0, 0x42, 0xa0, 0xc, 0x0, 0xb1, 0x8, 0x30, - 0x50, 0x29, 0x0, 0xc0, 0xb, 0x10, 0x3f, 0x6, - 0x53, 0x97, 0xc, 0x43, 0xb1, 0x0, 0x50, 0x6b, - 0x49, 0x76, 0xc0, 0xdb, 0x10, 0x0, 0x65, 0xb5, - 0x74, 0x3c, 0x5, 0xb1, 0x0, 0xa, 0x0, 0x75, - 0x0, 0xc0, 0xb, 0x10, 0x36, 0x90, 0xa, 0x20, - 0xc, 0x0, 0xb1, 0x3, 0xe6, 0x0, 0xb0, 0x0, - 0xc0, 0xb, 0x10, 0xb, 0x40, 0x66, 0x0, 0xc, - 0x0, 0xb1, 0x0, 0xe4, 0xa, 0x0, 0x0, 0xd0, - 0xb, 0x10, 0xa, 0x37, 0x10, 0x0, 0x1, 0x0, - 0xb2, 0x0, 0x0, 0x10, 0x0, 0x0, 0x0, 0x2, - 0x0, - - /* U+6D3B "活" */ - 0x0, 0x30, 0x0, 0x0, 0x0, 0x1, 0x70, 0x0, - 0x0, 0x2c, 0x10, 0x1, 0x47, 0xbe, 0xc5, 0x0, - 0x0, 0x8, 0x62, 0x55, 0x4d, 0x10, 0x0, 0x0, - 0x0, 0x0, 0x0, 0x0, 0xc, 0x0, 0x0, 0x0, - 0x17, 0x0, 0x40, 0x0, 0xc, 0x0, 0x0, 0x20, - 0x5, 0xc0, 0x56, 0x66, 0x6d, 0x66, 0x68, 0x80, - 0x0, 0xb1, 0x60, 0x0, 0xc, 0x0, 0x0, 0x0, - 0x0, 0x5, 0x20, 0x0, 0xc, 0x0, 0x0, 0x0, - 0x0, 0x9, 0x0, 0xa6, 0x6c, 0x66, 0xb6, 0x0, - 0x2, 0x58, 0x0, 0xd1, 0x0, 0x0, 0xb3, 0x0, - 0x4, 0xe4, 0x0, 0xd1, 0x0, 0x0, 0xb2, 0x0, - 0x0, 0xb3, 0x0, 0xd1, 0x0, 0x0, 0xb2, 0x0, - 0x0, 0xd2, 0x0, 0xd6, 0x66, 0x66, 0xd2, 0x0, - 0x0, 0xa2, 0x0, 0xd1, 0x0, 0x0, 0xb3, 0x0, - 0x0, 0x0, 0x0, 0x40, 0x0, 0x0, 0x40, 0x0, - - /* U+6D3E "派" */ - 0x0, 0x33, 0x0, 0x0, 0x0, 0x1, 0x74, 0x0, - 0x0, 0xc, 0x50, 0x53, 0x56, 0x8a, 0x85, 0x0, - 0x0, 0x4, 0x60, 0x96, 0x0, 0x0, 0x1, 0x0, - 0x0, 0x0, 0x13, 0x94, 0x10, 0x16, 0xd9, 0x0, - 0x1b, 0x20, 0x50, 0x94, 0xc5, 0x82, 0x0, 0x0, - 0x5, 0xc0, 0x60, 0x94, 0xc0, 0x60, 0x7, 0x10, - 0x0, 0x42, 0x50, 0x93, 0xc0, 0x60, 0x8a, 0x30, - 0x0, 0x8, 0x0, 0xa2, 0xc0, 0x77, 0x20, 0x0, - 0x0, 0xa, 0x0, 0xc0, 0xc0, 0x45, 0x0, 0x0, - 0x15, 0xa7, 0x0, 0xc0, 0xc0, 0xb, 0x0, 0x0, - 0x2, 0xe4, 0x4, 0x70, 0xc0, 0x9, 0x40, 0x0, - 0x0, 0xe3, 0xa, 0x10, 0xc0, 0x12, 0xd3, 0x0, - 0x1, 0xf2, 0x46, 0x0, 0xd9, 0x50, 0x6f, 0x70, - 0x0, 0x82, 0x70, 0x0, 0xa3, 0x0, 0x6, 0x30, - 0x0, 0x2, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - - /* U+6D41 "流" */ - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x10, 0x0, 0x0, 0x49, 0x0, 0x0, 0x0, - 0x0, 0x5a, 0x0, 0x0, 0xa, 0x30, 0x9, 0x10, - 0x0, 0xb, 0x53, 0x86, 0x6d, 0x66, 0x66, 0x30, - 0x0, 0x1, 0x2, 0x0, 0x86, 0x1, 0x0, 0x0, - 0x16, 0x0, 0x4, 0x5, 0x50, 0x7, 0x30, 0x0, - 0x7, 0xb0, 0x50, 0x79, 0x44, 0x45, 0xe2, 0x0, - 0x0, 0xa0, 0x70, 0x88, 0x53, 0x10, 0x84, 0x0, - 0x0, 0x3, 0x50, 0x95, 0x8, 0x9, 0x30, 0x0, - 0x0, 0x9, 0x0, 0xb2, 0xd, 0xc, 0x0, 0x0, - 0x0, 0x2a, 0x0, 0xc1, 0xd, 0xc, 0x0, 0x0, - 0x7, 0xf6, 0x0, 0xd0, 0xd, 0xc, 0x0, 0x10, - 0x0, 0xc4, 0x1, 0xb0, 0xd, 0xc, 0x0, 0x50, - 0x0, 0xe3, 0x9, 0x30, 0xd, 0xc, 0x0, 0x80, - 0x0, 0xf3, 0x65, 0x0, 0xd, 0x9, 0xcb, 0xc1, - 0x0, 0x12, 0x10, 0x0, 0x3, 0x0, 0x0, 0x0, - - /* U+6D45 "浅" */ - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x22, 0x0, 0x0, 0xc, 0x10, 0x0, 0x0, 0x0, - 0xb7, 0x0, 0x0, 0xe0, 0x88, 0x0, 0x0, 0x3, - 0xa0, 0x10, 0xe, 0x0, 0xd2, 0x0, 0x0, 0x0, - 0x40, 0x0, 0xe0, 0x1, 0x60, 0x8, 0x40, 0x6, - 0x34, 0x5e, 0x66, 0x67, 0x30, 0x1f, 0x31, 0x52, - 0x10, 0xd0, 0x0, 0x10, 0x0, 0x61, 0x70, 0x0, - 0xd, 0x13, 0x5c, 0x70, 0x0, 0x9, 0x46, 0x66, - 0xd5, 0x22, 0x0, 0x0, 0x5, 0x60, 0x0, 0x9, - 0x40, 0xb9, 0x0, 0x11, 0xc1, 0x0, 0x0, 0x59, - 0xa9, 0x0, 0x3, 0xcd, 0x0, 0x0, 0x1, 0xf8, - 0x0, 0x10, 0x5, 0xb0, 0x0, 0x3, 0xb9, 0xb0, - 0x6, 0x0, 0x89, 0x0, 0x17, 0x60, 0x9, 0xb2, - 0xa0, 0x8, 0x90, 0x33, 0x0, 0x0, 0x8, 0xfb, - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x1, 0x60, - - /* U+6D74 "浴" */ - 0x0, 0x40, 0x0, 0x0, 0x80, 0x3, 0x0, 0x0, - 0x0, 0x4d, 0x20, 0x7, 0xb0, 0x4, 0xb3, 0x0, - 0x0, 0xb, 0x41, 0x2b, 0x2, 0x0, 0x5f, 0x10, - 0x0, 0x0, 0x5, 0x80, 0xc, 0x80, 0x8, 0x0, - 0x19, 0x20, 0x44, 0x0, 0x5c, 0x70, 0x0, 0x0, - 0x4, 0xf0, 0x70, 0x1, 0xd1, 0x19, 0x0, 0x0, - 0x0, 0x80, 0x80, 0xb, 0x40, 0x4, 0xc2, 0x0, - 0x0, 0x4, 0x40, 0x97, 0x0, 0x0, 0x6f, 0xa2, - 0x0, 0xa, 0x17, 0x3d, 0x66, 0x66, 0xe6, 0x50, - 0x0, 0x2b, 0x20, 0xe, 0x0, 0x0, 0xe0, 0x0, - 0x5, 0xe8, 0x0, 0xe, 0x0, 0x0, 0xe0, 0x0, - 0x0, 0xa6, 0x0, 0xe, 0x0, 0x0, 0xe0, 0x0, - 0x0, 0xe6, 0x0, 0xe, 0x66, 0x66, 0xe0, 0x0, - 0x0, 0xb6, 0x0, 0xd, 0x0, 0x0, 0xd0, 0x0, - 0x0, 0x0, 0x0, 0x2, 0x0, 0x0, 0x20, 0x0, - - /* U+6D77 "海" */ - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x30, 0x0, 0x1c, 0x10, 0x0, 0x0, 0x0, - 0x0, 0x87, 0x0, 0x69, 0x0, 0x0, 0x4, 0x0, - 0x0, 0x1a, 0x0, 0xb6, 0x66, 0x66, 0x68, 0x40, - 0x10, 0x0, 0x33, 0x90, 0x0, 0x0, 0x20, 0x0, - 0xb, 0x10, 0x58, 0xa7, 0x66, 0x66, 0xe3, 0x0, - 0x6, 0x71, 0x70, 0xc1, 0x56, 0x0, 0xd0, 0x0, - 0x0, 0x15, 0x0, 0xe0, 0xc, 0x10, 0xd0, 0x0, - 0x0, 0x7, 0x57, 0xe6, 0x66, 0x66, 0xd6, 0xc2, - 0x0, 0x7, 0x4, 0x90, 0x41, 0x1, 0xb0, 0x0, - 0x1, 0x84, 0x6, 0x70, 0x2b, 0x1, 0xb0, 0x0, - 0x6, 0xf0, 0x9, 0x40, 0x7, 0x2, 0xa0, 0x30, - 0x0, 0xe0, 0xc, 0x66, 0x66, 0x68, 0xb6, 0x80, - 0x2, 0xf0, 0x0, 0x0, 0x2, 0x7, 0x70, 0x0, - 0x1, 0xc0, 0x0, 0x0, 0x3, 0xdf, 0x30, 0x0, - 0x0, 0x0, 0x0, 0x0, 0x0, 0x23, 0x0, 0x0, - - /* U+6D88 "消" */ - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x2, - 0x0, 0x0, 0x0, 0xc, 0x10, 0x10, 0x2, 0xc2, - 0x6, 0x60, 0xe, 0x0, 0xd5, 0x0, 0x78, 0x0, - 0xc6, 0xe, 0x7, 0x60, 0x0, 0x1, 0x4, 0x44, - 0xe, 0x25, 0x0, 0x63, 0x0, 0x42, 0x96, 0x6e, - 0x66, 0xc1, 0x1e, 0x40, 0x60, 0xd0, 0x0, 0x0, - 0xe0, 0x6, 0x31, 0x60, 0xd0, 0x0, 0x0, 0xe0, - 0x0, 0x7, 0x10, 0xe6, 0x66, 0x66, 0xe0, 0x0, - 0xa, 0x0, 0xd0, 0x0, 0x0, 0xe0, 0x0, 0x67, - 0x0, 0xe6, 0x66, 0x66, 0xe0, 0x38, 0xf3, 0x0, - 0xd0, 0x0, 0x0, 0xe0, 0x0, 0xe1, 0x0, 0xd0, - 0x0, 0x0, 0xe0, 0x0, 0xf0, 0x0, 0xd0, 0x0, - 0x1, 0xd0, 0x0, 0xf0, 0x1, 0xd0, 0x1, 0x7f, - 0xa0, 0x0, 0x10, 0x0, 0x20, 0x0, 0x3, 0x0, - - /* U+6DBC "涼" */ - 0x0, 0x10, 0x0, 0x0, 0x9, 0x20, 0x0, 0x0, - 0x0, 0x77, 0x0, 0x0, 0x3, 0xc0, 0x0, 0x0, - 0x0, 0xd, 0x31, 0x56, 0x66, 0x96, 0x66, 0xd1, - 0x0, 0x3, 0x4, 0x10, 0x0, 0x0, 0x0, 0x0, - 0x14, 0x0, 0x4, 0x9, 0x66, 0x66, 0x68, 0x0, - 0x8, 0x80, 0x60, 0xd, 0x0, 0x0, 0x1c, 0x0, - 0x0, 0xe0, 0x70, 0xd, 0x0, 0x0, 0x1b, 0x0, - 0x0, 0x14, 0x40, 0xd, 0x66, 0x66, 0x6b, 0x0, - 0x0, 0xa, 0x0, 0xa, 0x0, 0xd0, 0x16, 0x0, - 0x0, 0x48, 0x0, 0x5, 0x0, 0xd0, 0x30, 0x0, - 0x6, 0xf4, 0x0, 0x1e, 0x40, 0xd0, 0x57, 0x0, - 0x0, 0xc2, 0x0, 0xa3, 0x0, 0xd0, 0xa, 0x80, - 0x0, 0xe2, 0x6, 0x40, 0x0, 0xc0, 0x1, 0xf0, - 0x0, 0xc2, 0x33, 0x0, 0x7c, 0xa0, 0x0, 0x20, - 0x0, 0x0, 0x0, 0x0, 0x4, 0x10, 0x0, 0x0, - - /* U+6DF1 "深" */ - 0x0, 0x30, 0x0, 0x10, 0x0, 0x0, 0x0, 0x0, - 0x6, 0xa0, 0xa, 0x66, 0x66, 0x66, 0xb2, 0x0, - 0xc, 0x24, 0x90, 0x0, 0x0, 0x38, 0x0, 0x0, - 0x4, 0x31, 0x89, 0x1, 0x86, 0x0, 0x34, 0x0, - 0x50, 0x3a, 0x1, 0x0, 0xc7, 0x0, 0xb6, 0x24, - 0x16, 0x0, 0xa5, 0x1, 0x80, 0x2, 0x57, 0x2, - 0x0, 0xa, 0x30, 0x3, 0x0, 0x0, 0x80, 0x47, - 0x68, 0xd9, 0x66, 0xb6, 0x0, 0x36, 0x0, 0x0, - 0xdc, 0x82, 0x0, 0x0, 0xb, 0x20, 0x0, 0x87, - 0xa3, 0xa0, 0x0, 0x19, 0xf0, 0x0, 0x49, 0xa, - 0x35, 0x90, 0x0, 0x1e, 0x0, 0x49, 0x0, 0xa3, - 0xb, 0xb2, 0x4, 0xd0, 0x55, 0x0, 0xa, 0x30, - 0xb, 0x50, 0x3b, 0x0, 0x0, 0x0, 0xb4, 0x0, - 0x0, 0x0, 0x0, 0x0, 0x0, 0x2, 0x0, 0x0, - 0x0, - - /* U+6DF7 "混" */ - 0x0, 0x32, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0xc, 0x40, 0x87, 0x66, 0x66, 0x6d, 0x0, - 0x0, 0x4, 0x92, 0x85, 0x0, 0x0, 0x1b, 0x0, - 0x11, 0x0, 0x5, 0x89, 0x66, 0x66, 0x6b, 0x0, - 0xa, 0x40, 0x4, 0x85, 0x0, 0x0, 0x1b, 0x0, - 0x2, 0xe0, 0x60, 0x85, 0x0, 0x0, 0x1b, 0x0, - 0x0, 0x40, 0x70, 0x77, 0x66, 0x96, 0x68, 0x0, - 0x0, 0x3, 0x50, 0x92, 0x0, 0xd3, 0x3, 0x0, - 0x0, 0x9, 0x0, 0xd0, 0x20, 0xd0, 0x4d, 0x40, - 0x4, 0x5a, 0x0, 0xd6, 0x94, 0xd7, 0x70, 0x0, - 0x2, 0xc7, 0x0, 0xd0, 0x0, 0xd0, 0x0, 0x20, - 0x0, 0x95, 0x0, 0xd0, 0x1, 0xd0, 0x0, 0x60, - 0x0, 0xb5, 0x0, 0xe9, 0x70, 0xd0, 0x0, 0xb0, - 0x0, 0x74, 0x0, 0x92, 0x0, 0x8c, 0xcc, 0xc1, - - /* U+6E05 "清" */ - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x5, 0x0, 0x0, 0x0, 0xb1, 0x0, 0x0, 0x0, - 0x5d, 0x0, 0x0, 0xd, 0x0, 0x27, 0x0, 0x0, - 0xc1, 0x47, 0x66, 0xe6, 0x66, 0x61, 0x0, 0x0, - 0x10, 0x46, 0x6e, 0x66, 0xc1, 0x1, 0xa2, 0x4, - 0x1, 0x10, 0xd0, 0x0, 0x0, 0x4, 0xe0, 0x66, - 0x66, 0x6d, 0x66, 0x6b, 0x80, 0x5, 0x42, 0x10, - 0x0, 0x0, 0x1, 0x0, 0x0, 0x7, 0x0, 0xc6, - 0x66, 0x66, 0xc5, 0x0, 0x0, 0x90, 0xd, 0x0, - 0x0, 0xa, 0x20, 0x0, 0x56, 0x0, 0xd6, 0x66, - 0x66, 0xc2, 0x1, 0x8f, 0x30, 0xd, 0x66, 0x66, - 0x6c, 0x20, 0x0, 0xd1, 0x0, 0xd0, 0x0, 0x0, - 0xa2, 0x0, 0xf, 0x0, 0xd, 0x0, 0x0, 0xb, - 0x20, 0x1, 0xf0, 0x0, 0xd0, 0x0, 0x4b, 0xf0, - 0x0, 0x0, 0x0, 0x3, 0x0, 0x0, 0x12, 0x0, - - /* U+6E07 "渇" */ - 0x0, 0x31, 0x0, 0x86, 0x66, 0x66, 0x93, 0x0, - 0x1, 0xd3, 0xc, 0x0, 0x0, 0xb, 0x30, 0x0, - 0x6, 0x71, 0xc0, 0x0, 0x0, 0xb2, 0x0, 0x0, - 0x0, 0x5c, 0x66, 0x66, 0x6c, 0x20, 0x8, 0x10, - 0x5, 0xc0, 0x0, 0x0, 0xb2, 0x0, 0x3e, 0x5, - 0x1c, 0x76, 0x66, 0x6c, 0x20, 0x0, 0x90, 0x70, - 0x6c, 0x60, 0x0, 0x20, 0x0, 0x0, 0x45, 0x6, - 0xc6, 0x66, 0x66, 0xb3, 0x0, 0xa, 0x3, 0xa0, - 0x0, 0x10, 0xd, 0x10, 0x46, 0x93, 0x6a, 0x50, - 0x8b, 0x0, 0xd0, 0x2, 0xd5, 0x20, 0xa7, 0x72, - 0x1, 0xd, 0x0, 0xa, 0x40, 0xa, 0x30, 0x0, - 0x70, 0xd0, 0x0, 0xc4, 0x0, 0x5b, 0xbb, 0xa4, - 0xd, 0x0, 0x7, 0x30, 0x0, 0x0, 0x0, 0x4c, - 0xb0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x51, - 0x0, - - /* U+6E08 "済" */ - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x30, 0x0, 0x0, 0xa, 0x30, 0x0, 0x0, 0x1, - 0xc2, 0x0, 0x0, 0x5a, 0x0, 0x33, 0x0, 0x7, - 0x71, 0x79, 0x66, 0x66, 0xe7, 0x50, 0x0, 0x0, - 0x20, 0x54, 0x0, 0x96, 0x0, 0x6, 0x20, 0x5, - 0x0, 0xb3, 0x79, 0x0, 0x0, 0x1e, 0x22, 0x30, - 0x2, 0xfc, 0x0, 0x0, 0x0, 0x83, 0x70, 0x6, - 0xa4, 0x7c, 0x73, 0x10, 0x0, 0x18, 0x57, 0xa0, - 0x0, 0x1c, 0xcb, 0x10, 0x7, 0x20, 0x2d, 0x66, - 0x66, 0xe0, 0x0, 0x34, 0xc0, 0x2, 0xa0, 0x0, - 0xd, 0x0, 0x1, 0xb9, 0x0, 0x4b, 0x66, 0x66, - 0xd0, 0x0, 0x7, 0x70, 0x7, 0x40, 0x0, 0xd, - 0x0, 0x0, 0x97, 0x0, 0xb0, 0x0, 0x0, 0xd0, - 0x0, 0x6, 0x60, 0x64, 0x0, 0x0, 0xd, 0x0, - 0x0, 0x0, 0x12, 0x0, 0x0, 0x0, 0x60, 0x0, - - /* U+6E09 "渉" */ - 0x0, 0x31, 0x0, 0x0, 0x0, 0xc1, 0x0, 0x0, - 0x0, 0x1d, 0x30, 0x0, 0x0, 0xd0, 0x0, 0x0, - 0x0, 0x6, 0x71, 0xb, 0x20, 0xd0, 0x3, 0x0, - 0x0, 0x0, 0x5, 0xc, 0x0, 0xd6, 0x68, 0x10, - 0x8, 0x20, 0x5, 0xc, 0x0, 0xd0, 0x0, 0x0, - 0x1, 0xe1, 0x55, 0x6d, 0x66, 0xe6, 0x66, 0xd2, - 0x0, 0x81, 0x81, 0x10, 0x0, 0xd1, 0x0, 0x0, - 0x0, 0x3, 0x60, 0x8, 0x70, 0xd0, 0x63, 0x0, - 0x0, 0x9, 0x0, 0xd, 0x10, 0xd0, 0xb, 0x70, - 0x4, 0x7a, 0x0, 0x56, 0x0, 0xd0, 0xc4, 0xc0, - 0x0, 0xb7, 0x0, 0x90, 0x0, 0xdb, 0x80, 0x0, - 0x0, 0x85, 0x3, 0x10, 0x2, 0xc6, 0x0, 0x0, - 0x0, 0xb6, 0x0, 0x0, 0x6b, 0x20, 0x0, 0x0, - 0x0, 0x53, 0x0, 0x69, 0x50, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x15, 0x20, 0x0, 0x0, 0x0, 0x0, - - /* U+6E1B "減" */ - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x20, 0x0, 0x0, 0x0, 0x2b, 0x31, 0x0, - 0x0, 0x78, 0x0, 0x0, 0x0, 0xb, 0x1d, 0x10, - 0x0, 0xe, 0x11, 0x10, 0x0, 0xc, 0x4, 0x70, - 0x0, 0x2, 0x6, 0xc6, 0x66, 0x6d, 0x66, 0x71, - 0x24, 0x0, 0x42, 0xb0, 0x0, 0xc, 0x0, 0x0, - 0xa, 0x70, 0x61, 0xb4, 0x6a, 0x9c, 0x4, 0x50, - 0x1, 0xc1, 0x51, 0xa0, 0x0, 0xb, 0xa, 0x60, - 0x0, 0x7, 0x12, 0xa7, 0x66, 0xbb, 0x1d, 0x0, - 0x0, 0x9, 0x2, 0x99, 0x31, 0xa8, 0x79, 0x0, - 0x0, 0x76, 0x4, 0x89, 0x31, 0xa5, 0xe2, 0x0, - 0x17, 0xf1, 0x6, 0x69, 0x86, 0xa4, 0xd0, 0x20, - 0x0, 0xe0, 0xa, 0x28, 0x21, 0x7c, 0xa4, 0x60, - 0x1, 0xf0, 0x1a, 0x0, 0x0, 0xa2, 0x2c, 0x90, - 0x1, 0xe0, 0x81, 0x0, 0x19, 0x10, 0x5, 0xf1, - 0x0, 0x1, 0x20, 0x0, 0x40, 0x0, 0x0, 0x31, - - /* U+6E21 "渡" */ - 0x0, 0x60, 0x0, 0x0, 0x5, 0x50, 0x0, 0x0, - 0x0, 0x4c, 0x1, 0x0, 0x0, 0xd1, 0x0, 0x40, - 0x0, 0xb, 0x13, 0xc6, 0x66, 0x76, 0x66, 0x93, - 0x12, 0x0, 0x14, 0xa0, 0x2b, 0x1, 0xb0, 0x0, - 0xa, 0x50, 0x53, 0xa0, 0x1a, 0x1, 0xa2, 0x50, - 0x2, 0xd0, 0x62, 0xc6, 0x6c, 0x66, 0xc6, 0x50, - 0x0, 0x22, 0x53, 0x90, 0x1a, 0x1, 0xa0, 0x0, - 0x0, 0x8, 0x3, 0x90, 0x1a, 0x66, 0x80, 0x0, - 0x0, 0xa, 0x5, 0x72, 0x66, 0x66, 0x92, 0x0, - 0x14, 0x96, 0x7, 0x50, 0x33, 0x3, 0xc0, 0x0, - 0x2, 0xe3, 0x9, 0x20, 0x9, 0x2c, 0x20, 0x0, - 0x0, 0xd1, 0xc, 0x0, 0x2, 0xf6, 0x0, 0x0, - 0x0, 0xf2, 0x45, 0x0, 0x4b, 0x5c, 0x70, 0x0, - 0x0, 0x82, 0x80, 0x48, 0x60, 0x0, 0x9f, 0xc3, - 0x0, 0x2, 0x4, 0x10, 0x0, 0x0, 0x1, 0x30, - - /* U+6E29 "温" */ - 0x0, 0x40, 0x0, 0x20, 0x0, 0x0, 0x30, 0x0, - 0x0, 0x4c, 0x0, 0xd6, 0x66, 0x66, 0xf1, 0x0, - 0x0, 0x7, 0x1, 0xd1, 0x0, 0x0, 0xe0, 0x0, - 0x0, 0x0, 0x31, 0xd6, 0x66, 0x66, 0xe0, 0x0, - 0x9, 0x20, 0x50, 0xd1, 0x0, 0x0, 0xe0, 0x0, - 0x4, 0xb0, 0x60, 0xd1, 0x0, 0x0, 0xe0, 0x0, - 0x0, 0x23, 0x40, 0xe6, 0x66, 0x66, 0xe0, 0x0, - 0x0, 0x8, 0x0, 0x20, 0x0, 0x0, 0x0, 0x0, - 0x0, 0xa, 0xc, 0x66, 0x86, 0x96, 0x6d, 0x0, - 0x0, 0x58, 0xd, 0x1, 0xa0, 0xc0, 0xc, 0x0, - 0x7, 0xf5, 0xd, 0x1, 0xa0, 0xc0, 0xc, 0x0, - 0x0, 0xd3, 0xd, 0x1, 0xa0, 0xc0, 0xc, 0x0, - 0x0, 0xf2, 0xd, 0x1, 0xa0, 0xc0, 0xc, 0x0, - 0x0, 0xd4, 0x6e, 0x66, 0xc6, 0xd6, 0x6d, 0xd4, - 0x0, 0x0, 0x10, 0x0, 0x0, 0x0, 0x0, 0x0, - - /* U+6E2F "港" */ - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x60, 0x0, 0x8, 0x60, 0xd, 0x0, 0x0, - 0x0, 0x4d, 0x0, 0x8, 0x50, 0xd, 0x0, 0x0, - 0x0, 0xa, 0x12, 0x6b, 0x96, 0x6e, 0x6c, 0x10, - 0x2, 0x0, 0x40, 0x28, 0x50, 0xd, 0x0, 0x0, - 0x9, 0x70, 0x50, 0x8, 0x50, 0xd, 0x0, 0x20, - 0x1, 0xd1, 0x68, 0x6a, 0xa6, 0x6b, 0x66, 0xa1, - 0x0, 0x15, 0x10, 0xb, 0x40, 0x6, 0x0, 0x0, - 0x0, 0x8, 0x0, 0x5b, 0x0, 0x5, 0xa0, 0x0, - 0x0, 0x8, 0x2, 0xcd, 0x66, 0x6c, 0x5d, 0x71, - 0x2, 0x85, 0x29, 0x1c, 0x0, 0xb, 0x2, 0x70, - 0x5, 0xf3, 0x50, 0xd, 0x66, 0x6c, 0x11, 0x0, - 0x0, 0xe0, 0x0, 0xc, 0x0, 0x2, 0x5, 0x0, - 0x1, 0xf0, 0x0, 0xc, 0x0, 0x0, 0x7, 0x30, - 0x0, 0xb0, 0x0, 0xb, 0xcc, 0xcc, 0xbc, 0x40, - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - - /* U+6E56 "湖" */ - 0x0, 0x20, 0x0, 0x57, 0x0, 0x0, 0x0, 0x0, - 0x9, 0x60, 0x5, 0x70, 0xa, 0x66, 0xc3, 0x0, - 0x19, 0x20, 0x57, 0x0, 0xc0, 0xb, 0x0, 0x0, - 0x5, 0x59, 0xa9, 0x6c, 0x0, 0xb0, 0x28, 0x0, - 0x51, 0x57, 0x0, 0xb6, 0x6d, 0x0, 0x88, 0x15, - 0x5, 0x70, 0xb, 0x0, 0xb0, 0x1, 0x55, 0x12, - 0x57, 0x30, 0xb0, 0xb, 0x0, 0x0, 0x80, 0xd6, - 0x6d, 0xc, 0x0, 0xb0, 0x0, 0x8, 0xc, 0x0, - 0xc0, 0xd6, 0x6d, 0x1, 0x38, 0x50, 0xc0, 0xc, - 0xc, 0x0, 0xb0, 0x3, 0xe2, 0xd, 0x66, 0xc4, - 0x80, 0xb, 0x0, 0xd, 0x0, 0xc0, 0x7, 0xb1, - 0x0, 0xb0, 0x0, 0xf0, 0x8, 0x0, 0x65, 0x4, - 0x3c, 0x0, 0xa, 0x0, 0x0, 0x54, 0x0, 0x2c, - 0xb0, 0x0, 0x0, 0x0, 0x10, 0x0, 0x0, 0x0, - 0x0, - - /* U+6E90 "源" */ - 0x0, 0x50, 0x0, 0x0, 0x0, 0x0, 0x2, 0x40, - 0x0, 0x6c, 0x2, 0xc6, 0x66, 0x78, 0x68, 0x90, - 0x0, 0xc, 0x5, 0xb0, 0x0, 0x87, 0x0, 0x0, - 0x0, 0x0, 0x24, 0xb0, 0x86, 0xb6, 0x6b, 0x10, - 0x18, 0x10, 0x52, 0xb0, 0xd0, 0x0, 0xd, 0x0, - 0x6, 0xd0, 0x62, 0xb0, 0xd0, 0x0, 0xd, 0x0, - 0x0, 0x92, 0x53, 0xb0, 0xd6, 0x66, 0x6d, 0x0, - 0x0, 0x7, 0x13, 0x90, 0xd0, 0x0, 0xd, 0x0, - 0x0, 0x9, 0x6, 0x80, 0xe6, 0x79, 0x6d, 0x0, - 0x4, 0x78, 0x9, 0x40, 0x30, 0x3a, 0x1, 0x0, - 0x2, 0xe5, 0xc, 0x0, 0xd4, 0x3a, 0x82, 0x0, - 0x0, 0xb3, 0x37, 0x8, 0x60, 0x3a, 0x1d, 0x50, - 0x0, 0xe3, 0x80, 0x55, 0x0, 0x4a, 0x5, 0xc0, - 0x0, 0x86, 0x22, 0x30, 0x7, 0xf7, 0x0, 0x40, - 0x0, 0x1, 0x0, 0x0, 0x0, 0x30, 0x0, 0x0, - - /* U+6E96 "準" */ - 0x0, 0x72, 0x0, 0x1a, 0x4, 0x50, 0x0, 0x0, - 0x0, 0x2c, 0x1, 0x76, 0x0, 0xb0, 0x4, 0x0, - 0x2, 0x2, 0x41, 0xe6, 0x66, 0xa6, 0x69, 0x20, - 0x7, 0x70, 0x67, 0xd1, 0x0, 0xd0, 0x24, 0x0, - 0x0, 0x74, 0x63, 0xc6, 0x66, 0xe6, 0x66, 0x0, - 0x0, 0x9, 0x10, 0xc1, 0x0, 0xd1, 0x25, 0x0, - 0x4, 0x97, 0x0, 0xc6, 0x66, 0xd5, 0x54, 0x0, - 0x0, 0x85, 0x0, 0xc1, 0x0, 0xd0, 0x7, 0x10, - 0x0, 0x66, 0x0, 0x88, 0x66, 0x66, 0x66, 0x30, - 0x0, 0x23, 0x0, 0xd, 0x40, 0x0, 0x0, 0x10, - 0x7, 0x66, 0x66, 0x6e, 0x76, 0x66, 0x67, 0xa0, - 0x0, 0x0, 0x0, 0xc, 0x20, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x0, 0xc, 0x20, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x0, 0xd, 0x30, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x0, 0x6, 0x10, 0x0, 0x0, 0x0, - - /* U+6E9D "溝" */ - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x20, 0x0, 0x5, 0x70, 0xc, 0x0, 0x0, - 0x0, 0x69, 0x0, 0x5, 0x60, 0xd, 0x4, 0x0, - 0x0, 0xd, 0x25, 0x79, 0xa6, 0x6e, 0x67, 0x40, - 0x0, 0x2, 0x4, 0x59, 0xa6, 0x6e, 0x6b, 0x10, - 0x33, 0x0, 0x40, 0x16, 0x60, 0xd, 0x0, 0x10, - 0xa, 0x70, 0x65, 0x78, 0x89, 0x6a, 0x68, 0x90, - 0x2, 0xb2, 0x50, 0x10, 0xd, 0x0, 0x0, 0x0, - 0x0, 0x8, 0x0, 0xd6, 0x6e, 0x66, 0xa9, 0x0, - 0x0, 0x9, 0x0, 0xd0, 0xd, 0x0, 0x76, 0x0, - 0x0, 0x85, 0x0, 0xd6, 0x6e, 0x66, 0xa6, 0x0, - 0x18, 0xf0, 0x26, 0xe6, 0x6e, 0x66, 0xaa, 0xa0, - 0x0, 0xe0, 0x1, 0xd0, 0x0, 0x0, 0x76, 0x0, - 0x2, 0xe0, 0x0, 0xd0, 0x0, 0x0, 0x76, 0x0, - 0x2, 0xd0, 0x0, 0xd0, 0x0, 0x29, 0xd4, 0x0, - 0x0, 0x0, 0x0, 0x50, 0x0, 0x0, 0x70, 0x0, - - /* U+6EFF "滿" */ - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x30, 0x0, 0x0, 0xd0, 0x1, 0xb0, 0x0, 0x1, - 0xc2, 0x0, 0xd, 0x0, 0x1c, 0x5, 0x20, 0x7, - 0x75, 0x76, 0xe6, 0x66, 0xd6, 0x64, 0x0, 0x0, - 0x40, 0xd, 0x0, 0x1c, 0x0, 0x6, 0x20, 0x5, - 0x0, 0xe6, 0xc6, 0xc0, 0x0, 0xd, 0x32, 0x40, - 0x2, 0xd, 0x0, 0x0, 0x0, 0x65, 0x72, 0xb6, - 0x66, 0xe6, 0x67, 0xc0, 0x0, 0x8, 0x1b, 0x60, - 0xd, 0x50, 0x3a, 0x0, 0x5, 0x41, 0xb1, 0xb0, - 0xd1, 0xc3, 0xa0, 0x12, 0xc0, 0x1b, 0x3d, 0x8d, - 0x3d, 0xaa, 0x2, 0xbb, 0x1, 0xb7, 0x19, 0xd8, - 0x2b, 0xa0, 0x5, 0x90, 0x1c, 0x0, 0xd, 0x10, - 0x3a, 0x0, 0x89, 0x1, 0xb0, 0x0, 0xd0, 0x3, - 0xa0, 0x6, 0x80, 0x2b, 0x0, 0xd, 0x6, 0xa8, - 0x0, 0x0, 0x1, 0x50, 0x0, 0x20, 0x8, 0x10, - - /* U+6F22 "漢" */ - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x30, 0x0, 0xa, 0x30, 0xb, 0x20, 0x0, - 0x0, 0x4b, 0x5, 0x6c, 0x66, 0x6d, 0x69, 0x80, - 0x0, 0xb, 0x31, 0xa, 0x0, 0xc, 0x0, 0x0, - 0x0, 0x1, 0x4, 0xb, 0x68, 0x6d, 0x0, 0x0, - 0x7, 0x10, 0x6, 0x3, 0xc, 0x3, 0x0, 0x0, - 0x3, 0xd1, 0x44, 0xc6, 0x6d, 0x66, 0x98, 0x0, - 0x0, 0xa1, 0x71, 0xb0, 0xc, 0x0, 0x66, 0x0, - 0x0, 0x2, 0x61, 0xd6, 0x6d, 0x66, 0x96, 0x0, - 0x0, 0x9, 0x10, 0x20, 0xc, 0x0, 0x61, 0x0, - 0x2, 0x3a, 0x0, 0x76, 0x6d, 0x66, 0x63, 0x0, - 0x4, 0xd7, 0x5, 0x66, 0x6d, 0x66, 0x66, 0xa0, - 0x0, 0x95, 0x1, 0x0, 0x57, 0x61, 0x0, 0x0, - 0x0, 0xc5, 0x0, 0x3, 0xa0, 0xa, 0x60, 0x0, - 0x0, 0x94, 0x0, 0x78, 0x0, 0x0, 0x9e, 0x91, - 0x0, 0x0, 0x15, 0x10, 0x0, 0x0, 0x2, 0x0, - - /* U+6F38 "漸" */ - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x50, 0x0, 0xd, 0x10, 0x0, 0x0, 0x60, - 0x0, 0x3d, 0x0, 0xd, 0x3, 0x26, 0x79, 0x83, - 0x0, 0xa, 0x38, 0x6e, 0x68, 0x5a, 0x0, 0x0, - 0x0, 0x0, 0x3, 0xd, 0x5, 0x3a, 0x0, 0x0, - 0x9, 0x20, 0x4e, 0x6e, 0x6e, 0x4a, 0x0, 0x50, - 0x3, 0xe1, 0x5d, 0xd, 0xd, 0x2c, 0x5d, 0x63, - 0x0, 0x85, 0x1d, 0x6e, 0x6d, 0x29, 0xd, 0x0, - 0x0, 0x8, 0xd, 0xd, 0xd, 0x29, 0xd, 0x0, - 0x0, 0x9, 0xe, 0x6e, 0x6d, 0x39, 0xd, 0x0, - 0x1, 0x86, 0x4, 0xd, 0x3, 0x47, 0xd, 0x0, - 0x6, 0xf3, 0x67, 0x6e, 0x6a, 0x85, 0xd, 0x0, - 0x0, 0xe1, 0x0, 0xd, 0x0, 0xa1, 0xd, 0x0, - 0x0, 0xf1, 0x0, 0xd, 0x1, 0x90, 0xd, 0x0, - 0x0, 0xc0, 0x0, 0xe, 0x8, 0x10, 0xd, 0x0, - 0x0, 0x0, 0x0, 0x7, 0x21, 0x0, 0x7, 0x0, - - /* U+6FC3 "濃" */ - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x20, 0x0, 0x0, 0xc0, 0xa3, 0x0, 0x0, - 0x0, 0x78, 0x2, 0x86, 0xd6, 0xc6, 0x6a, 0x0, - 0x0, 0xe, 0x24, 0x90, 0xb0, 0xa1, 0xd, 0x0, - 0x0, 0x2, 0x43, 0xb6, 0xd6, 0xc6, 0x6d, 0x0, - 0x8, 0x10, 0x63, 0x90, 0xb0, 0xa1, 0xd, 0x0, - 0x3, 0xe1, 0x63, 0x96, 0x66, 0x66, 0x68, 0x0, - 0x0, 0x96, 0x19, 0x76, 0x66, 0x66, 0x6a, 0x30, - 0x0, 0x9, 0x9, 0x40, 0x0, 0x0, 0x32, 0x0, - 0x0, 0x28, 0x9, 0x47, 0x66, 0x66, 0x64, 0x0, - 0x5, 0xc3, 0x9, 0x89, 0x67, 0x66, 0x67, 0x90, - 0x2, 0xf0, 0xa, 0x2d, 0x6, 0x1, 0xc3, 0x0, - 0x0, 0xe0, 0xc, 0xd, 0x2, 0x97, 0x20, 0x0, - 0x1, 0xf0, 0x28, 0xd, 0x14, 0x3b, 0x50, 0x0, - 0x0, 0x80, 0x80, 0xe, 0x81, 0x1, 0xaf, 0x91, - 0x0, 0x1, 0x10, 0x1, 0x0, 0x0, 0x0, 0x0, - - /* U+6FDF "濟" */ - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x1, 0x20, 0x0, 0x0, 0x4a, 0x0, 0x0, 0x0, - 0x0, 0xa6, 0x0, 0x0, 0x8, 0x10, 0x6, 0x20, - 0x0, 0x2d, 0x17, 0x66, 0xa6, 0x98, 0x66, 0x40, - 0x0, 0x1, 0x40, 0x1, 0x94, 0xa3, 0x29, 0x0, - 0x29, 0x10, 0x56, 0xca, 0x89, 0x37, 0x91, 0x0, - 0x6, 0xb3, 0x21, 0xa7, 0x4c, 0xb, 0x45, 0x0, - 0x0, 0x77, 0x7, 0x49, 0x3c, 0xb, 0x3c, 0x20, - 0x0, 0x8, 0x18, 0x4d, 0xb, 0x1b, 0x25, 0xa1, - 0x0, 0x54, 0x20, 0xd2, 0x0, 0x0, 0x96, 0x0, - 0x13, 0xd0, 0x0, 0xe6, 0x66, 0x66, 0xb5, 0x0, - 0x7, 0xc0, 0x0, 0xd0, 0x0, 0x0, 0x95, 0x0, - 0x2, 0xb0, 0x0, 0xc6, 0x66, 0x66, 0xb5, 0x0, - 0x5, 0xb0, 0x6, 0x50, 0x0, 0x0, 0x95, 0x0, - 0x2, 0x80, 0x48, 0x0, 0x0, 0x0, 0x95, 0x0, - 0x0, 0x1, 0x30, 0x0, 0x0, 0x0, 0x52, 0x0, - - /* U+7063 "灣" */ - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x10, 0x9, 0x40, 0xa, 0x10, 0x57, 0x0, - 0x0, 0xa5, 0x26, 0x65, 0x79, 0x94, 0x65, 0x70, - 0x0, 0x2c, 0x88, 0xa0, 0x46, 0x76, 0x7b, 0x0, - 0x0, 0x2, 0x27, 0x32, 0x45, 0x50, 0x72, 0x50, - 0x46, 0x4, 0x99, 0x59, 0x54, 0x66, 0xb5, 0xb0, - 0xb, 0x66, 0x23, 0x21, 0xb6, 0xc2, 0x31, 0x30, - 0x3, 0x77, 0xa5, 0x6a, 0xb1, 0xb6, 0x5a, 0xb0, - 0x0, 0x35, 0x50, 0x22, 0x85, 0x86, 0x54, 0x20, - 0x0, 0x80, 0x6, 0x76, 0x66, 0x66, 0xe3, 0x0, - 0x1, 0xb0, 0x5, 0x86, 0x66, 0x66, 0xe0, 0x0, - 0x3c, 0x90, 0x8, 0x50, 0x0, 0x0, 0x34, 0x0, - 0x6, 0x80, 0x8, 0x66, 0x66, 0x66, 0x9c, 0x0, - 0x8, 0x70, 0x0, 0x0, 0x0, 0x0, 0x76, 0x0, - 0x8, 0x80, 0x0, 0x0, 0x1, 0x53, 0xd1, 0x0, - 0x0, 0x0, 0x0, 0x0, 0x0, 0x4e, 0x70, 0x0, - - /* U+706B "火" */ - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x0, 0xc, 0x60, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x0, 0xc, 0x40, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x0, 0xc, 0x40, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x0, 0xc, 0x40, 0x0, 0x30, 0x0, - 0x0, 0x2, 0x30, 0xc, 0x30, 0x4, 0xf2, 0x0, - 0x0, 0x9, 0x10, 0xd, 0x30, 0xc, 0x30, 0x0, - 0x0, 0x4d, 0x0, 0xe, 0x60, 0x92, 0x0, 0x0, - 0x2, 0xf5, 0x0, 0x1e, 0x46, 0x10, 0x0, 0x0, - 0x0, 0x0, 0x0, 0x69, 0x8, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x0, 0xc3, 0x6, 0x50, 0x0, 0x0, - 0x0, 0x0, 0x5, 0xb0, 0x0, 0xc3, 0x0, 0x0, - 0x0, 0x0, 0x2c, 0x10, 0x0, 0x2d, 0x40, 0x0, - 0x0, 0x3, 0xb1, 0x0, 0x0, 0x3, 0xea, 0x30, - 0x1, 0x76, 0x0, 0x0, 0x0, 0x0, 0x2c, 0x70, - 0x24, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - - /* U+707D "災" */ - 0x0, 0x0, 0xa0, 0x2, 0x80, 0x0, 0x91, 0x0, - 0x0, 0x7, 0x70, 0xa, 0x50, 0x7, 0x80, 0x0, - 0x0, 0x27, 0x0, 0x45, 0x0, 0x18, 0x0, 0x0, - 0x0, 0x70, 0x0, 0x80, 0x0, 0x80, 0x0, 0x0, - 0x0, 0x1b, 0x20, 0x4a, 0x10, 0x1a, 0x10, 0x0, - 0x0, 0x4, 0xb0, 0x6, 0xa0, 0x3, 0xd0, 0x0, - 0x0, 0x0, 0x30, 0x0, 0x20, 0x0, 0x60, 0x0, - 0x0, 0x0, 0x0, 0xb, 0x70, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x60, 0xd, 0x70, 0x7, 0x60, 0x0, - 0x0, 0x8, 0x60, 0xe, 0x51, 0x49, 0x10, 0x0, - 0x0, 0x4d, 0x10, 0x79, 0xa, 0x40, 0x0, 0x0, - 0x0, 0x0, 0x2, 0xd1, 0x4, 0x90, 0x0, 0x0, - 0x0, 0x0, 0x3d, 0x30, 0x0, 0x8c, 0x30, 0x0, - 0x0, 0x39, 0x91, 0x0, 0x0, 0x5, 0xec, 0x81, - 0x5, 0x40, 0x0, 0x0, 0x0, 0x0, 0x5, 0x0, - - /* U+70B9 "点" */ - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x3b, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x3b, 0x0, 0x0, 0x10, 0x0, 0x0, 0x0, - 0x3c, 0x66, 0x66, 0xd3, 0x0, 0x0, 0x0, 0x3b, - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x3b, 0x0, - 0x1, 0x0, 0x0, 0x1c, 0x66, 0x7a, 0x66, 0x6f, - 0x20, 0x0, 0xe, 0x0, 0x0, 0x0, 0xe, 0x0, - 0x0, 0xe, 0x0, 0x0, 0x0, 0xe, 0x0, 0x0, - 0xe, 0x0, 0x0, 0x0, 0xe, 0x0, 0x0, 0x1f, - 0x66, 0x66, 0x66, 0x6e, 0x0, 0x0, 0x6, 0x0, - 0x0, 0x0, 0x4, 0x0, 0x0, 0x60, 0x6, 0x0, - 0x52, 0x6, 0x30, 0x3, 0x80, 0x9, 0x50, 0x1d, - 0x0, 0xd3, 0x2f, 0x30, 0x5, 0x70, 0xa, 0x0, - 0x77, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - - /* U+70BA "為" */ - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x71, 0x6, 0xa0, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x3c, 0xa, 0x60, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x3, 0xe, 0x0, 0x2, 0x0, 0x0, - 0x0, 0x67, 0x66, 0xab, 0x66, 0x6e, 0x50, 0x0, - 0x0, 0x0, 0x0, 0xc1, 0x0, 0x1c, 0x0, 0x0, - 0x0, 0x0, 0x6, 0xb6, 0x66, 0x8a, 0x8a, 0x0, - 0x0, 0x0, 0x1c, 0x0, 0x0, 0x0, 0xa2, 0x0, - 0x0, 0x0, 0xa8, 0x66, 0x66, 0x66, 0xd7, 0xa0, - 0x0, 0x7, 0x50, 0x0, 0x0, 0x0, 0x4, 0xa0, - 0x0, 0x56, 0x11, 0x10, 0x51, 0x28, 0x6, 0x70, - 0x5, 0x40, 0x80, 0xa1, 0x1d, 0x18, 0x58, 0x50, - 0x1, 0x7, 0x80, 0x6a, 0x7, 0x21, 0x2a, 0x30, - 0x0, 0x1d, 0x20, 0x4, 0x0, 0x0, 0xe, 0x10, - 0x0, 0x0, 0x0, 0x0, 0x0, 0x6, 0xdc, 0x0, - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x31, 0x0, - - /* U+7121 "無" */ - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x1, 0xb0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x9, - 0x70, 0x0, 0x0, 0x5, 0x0, 0x0, 0x4f, 0x6b, - 0x66, 0xb6, 0xb7, 0x40, 0x1, 0x9d, 0xb, 0x0, - 0xb0, 0xd0, 0x0, 0x6, 0xd, 0xb, 0x0, 0xb0, - 0xd0, 0x0, 0x0, 0xd, 0xb, 0x0, 0xb0, 0xd0, - 0x60, 0x7, 0x6e, 0x6d, 0x66, 0xd6, 0xe6, 0x83, - 0x0, 0xd, 0xb, 0x0, 0xb0, 0xd0, 0x0, 0x0, - 0xd, 0xb, 0x0, 0xb0, 0xd0, 0x0, 0x0, 0xd, - 0xb, 0x0, 0xb0, 0xd0, 0x83, 0x47, 0x66, 0x66, - 0x66, 0x66, 0x66, 0x64, 0x0, 0x60, 0x34, 0x0, - 0x90, 0x6, 0x50, 0x6, 0x70, 0xc, 0x20, 0x5a, - 0x0, 0xd3, 0x5e, 0x10, 0x9, 0x60, 0xa, 0x0, - 0x74, 0x1, 0x0, 0x1, 0x0, 0x0, 0x0, 0x0, - - /* U+7136 "然" */ - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, 0xe3, 0x0, 0x1, 0xd2, 0x0, 0x0, - 0x0, 0x3, 0xd0, 0x0, 0x1, 0xd2, 0xa1, 0x0, - 0x0, 0x9, 0xa6, 0x6c, 0x11, 0xd0, 0x98, 0x0, - 0x0, 0xd, 0x0, 0x4b, 0x1, 0xc0, 0x25, 0x0, - 0x0, 0x77, 0xb3, 0x87, 0x87, 0xd6, 0x6b, 0x70, - 0x1, 0xb5, 0x27, 0xd1, 0x4, 0x96, 0x0, 0x0, - 0x7, 0xa, 0x55, 0x90, 0x7, 0x68, 0x0, 0x0, - 0x0, 0x2, 0x3c, 0x10, 0xc, 0x12, 0xa0, 0x0, - 0x0, 0x0, 0x95, 0x0, 0x76, 0x0, 0x98, 0x0, - 0x0, 0x8, 0x50, 0x6, 0x60, 0x0, 0xd, 0xd2, - 0x2, 0x72, 0x0, 0x51, 0x0, 0x0, 0x1, 0x10, - 0x1, 0x6, 0x2, 0x60, 0x8, 0x0, 0x83, 0x0, - 0x0, 0x4a, 0x0, 0xd2, 0x7, 0xa0, 0x1e, 0x20, - 0x1, 0xe5, 0x0, 0xb4, 0x2, 0xc0, 0xa, 0x40, - 0x0, 0x20, 0x0, 0x10, 0x0, 0x0, 0x0, 0x0, - - /* U+7159 "煙" */ - 0x0, 0x8, 0x20, 0x0, 0x0, 0x0, 0x3, 0x20, - 0x0, 0xd, 0x20, 0x67, 0x6c, 0x6c, 0x67, 0x60, - 0x0, 0xd, 0x10, 0x0, 0xd, 0xd, 0x0, 0x0, - 0x0, 0xd, 0x1a, 0x4a, 0x6e, 0x6e, 0x6c, 0x30, - 0x2, 0x2c, 0x68, 0xc, 0xd, 0xd, 0xd, 0x0, - 0x7, 0x3c, 0x60, 0xc, 0xd, 0xd, 0xd, 0x0, - 0x2e, 0x1c, 0x0, 0xc, 0xd, 0xd, 0xd, 0x0, - 0x13, 0xd, 0x0, 0xd, 0x69, 0x69, 0x6c, 0x0, - 0x0, 0xe, 0x0, 0x4, 0x0, 0xe1, 0x0, 0x0, - 0x0, 0xe, 0x60, 0x0, 0x0, 0xd0, 0x2, 0x0, - 0x0, 0x2a, 0x4c, 0x17, 0x66, 0xe6, 0x78, 0x0, - 0x0, 0x75, 0xa, 0x50, 0x0, 0xd0, 0x0, 0x0, - 0x0, 0xb0, 0x1, 0x0, 0x0, 0xd0, 0x0, 0x0, - 0x8, 0x20, 0x3, 0x66, 0x66, 0xe6, 0x67, 0xd1, - 0x22, 0x0, 0x0, 0x10, 0x0, 0x0, 0x0, 0x0, - - /* U+71B1 "熱" */ - 0x0, 0x0, 0xb3, 0x0, 0x3, 0x80, 0x0, 0x0, - 0x0, 0xc, 0x4, 0x0, 0x39, 0x0, 0x0, 0x0, - 0x76, 0xd6, 0x73, 0x25, 0xb4, 0xa0, 0x0, 0x0, - 0xc, 0x1, 0x44, 0x69, 0x3b, 0x0, 0x6, 0x79, - 0x68, 0x76, 0x5, 0x72, 0xa0, 0x0, 0x9, 0x82, - 0xa, 0x82, 0x75, 0x2a, 0x0, 0x7, 0x40, 0xc3, - 0xb, 0x3d, 0x51, 0xb0, 0x1, 0x26, 0x6d, 0x6c, - 0x21, 0xce, 0x4d, 0x2, 0x0, 0x20, 0xc0, 0x0, - 0x83, 0x34, 0x86, 0x60, 0x2, 0x5e, 0x75, 0x66, - 0x0, 0x1, 0xd9, 0x8, 0xb5, 0x10, 0x4, 0x0, - 0x0, 0x2, 0x70, 0x1, 0x60, 0x16, 0x1, 0x90, - 0x8, 0x30, 0x0, 0xa3, 0x0, 0xa4, 0x7, 0x90, - 0x1e, 0x10, 0x9b, 0x0, 0x5, 0x60, 0x18, 0x0, - 0xa3, 0x2, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, - - /* U+71DF "營" */ - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x6, 0x60, 0x0, 0x29, 0x0, 0x0, 0x0, - 0x6, 0x75, 0x95, 0x33, 0x83, 0xb0, 0x0, 0x9, - 0x49, 0x82, 0x2b, 0x5a, 0x60, 0x0, 0x0, 0x40, - 0xc7, 0x85, 0x3a, 0x57, 0x40, 0x0, 0x0, 0x83, - 0x6, 0x55, 0x70, 0xb, 0x70, 0x0, 0x41, 0x0, - 0x2, 0x40, 0x0, 0x18, 0x0, 0x2a, 0x66, 0x66, - 0x66, 0x66, 0x69, 0xd2, 0xd, 0x30, 0xa6, 0x66, - 0x66, 0xd3, 0x60, 0x0, 0x20, 0xb, 0x0, 0x0, - 0xc, 0x0, 0x0, 0x0, 0x0, 0xc6, 0x66, 0x66, - 0xd1, 0x0, 0x0, 0x0, 0x33, 0x0, 0x0, 0x1, - 0x50, 0x0, 0x0, 0xd, 0x66, 0x66, 0x66, 0x6d, - 0x50, 0x0, 0x0, 0xc1, 0x0, 0x0, 0x0, 0xb2, - 0x0, 0x0, 0xc, 0x66, 0x66, 0x66, 0x6d, 0x30, - 0x0, 0x0, 0x80, 0x0, 0x0, 0x0, 0x51, 0x0, - - /* U+722D "爭" */ - 0x0, 0x0, 0x0, 0x0, 0x2, 0x6b, 0x20, 0x0, - 0x4, 0x56, 0x78, 0x9a, 0x98, 0x73, 0x0, 0x0, - 0x31, 0x0, 0x81, 0x0, 0x1c, 0x10, 0x0, 0x0, - 0xc3, 0x2, 0xd0, 0x9, 0x40, 0x0, 0x0, 0x4, - 0x60, 0x6, 0x4, 0x50, 0x0, 0x0, 0x3, 0x66, - 0x66, 0x66, 0x76, 0xc4, 0x0, 0x0, 0x0, 0x0, - 0x2a, 0x0, 0xd, 0x0, 0x2, 0x66, 0x66, 0x67, - 0xc6, 0x66, 0xe6, 0xd3, 0x1, 0x0, 0x0, 0x2a, - 0x0, 0xd, 0x0, 0x0, 0x3, 0x66, 0x67, 0xc6, - 0x66, 0xe0, 0x0, 0x0, 0x1, 0x0, 0x2a, 0x0, - 0x7, 0x0, 0x0, 0x0, 0x0, 0x2, 0xa0, 0x0, - 0x0, 0x0, 0x0, 0x0, 0x20, 0x3a, 0x0, 0x0, - 0x0, 0x0, 0x0, 0x4, 0xbf, 0x70, 0x0, 0x0, - 0x0, 0x0, 0x0, 0x0, 0x50, 0x0, 0x0, 0x0, - 0x0, - - /* U+7236 "父" */ - 0x0, 0x0, 0x2, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, 0xe, 0x80, 0x2, 0x61, 0x0, 0x0, - 0x0, 0x0, 0xa9, 0x0, 0x0, 0x1a, 0x70, 0x0, - 0x0, 0x9, 0x70, 0x0, 0x0, 0x0, 0xbb, 0x0, - 0x0, 0x84, 0x10, 0x0, 0x0, 0x43, 0x1d, 0x20, - 0x6, 0x10, 0x23, 0x0, 0x0, 0xc6, 0x0, 0x0, - 0x0, 0x0, 0x8, 0x0, 0x3, 0xc0, 0x0, 0x0, - 0x0, 0x0, 0x4, 0x50, 0xb, 0x40, 0x0, 0x0, - 0x0, 0x0, 0x0, 0xa2, 0x4a, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x0, 0x2c, 0xc1, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x0, 0x1c, 0xd3, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x2, 0xb3, 0x2d, 0x81, 0x0, 0x0, - 0x0, 0x0, 0x79, 0x10, 0x0, 0x8f, 0xb6, 0x30, - 0x0, 0x68, 0x30, 0x0, 0x0, 0x1, 0x8d, 0x81, - 0x4, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - - /* U+7238 "爸" */ - 0x0, 0x0, 0x6, 0x60, 0x0, 0x54, 0x0, 0x0, - 0x0, 0x0, 0x5c, 0x30, 0x0, 0x5, 0xc4, 0x0, - 0x0, 0x7, 0x72, 0x40, 0x4, 0xc0, 0x3f, 0x0, - 0x1, 0x61, 0x0, 0x57, 0x4c, 0x10, 0x1, 0x0, - 0x0, 0x0, 0x0, 0xa, 0xf4, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x28, 0xb4, 0x8, 0xb8, 0x53, 0x31, - 0x4, 0x68, 0x92, 0x0, 0x0, 0x8, 0x8a, 0x91, - 0x0, 0x0, 0xd6, 0x67, 0xc6, 0x6e, 0x30, 0x0, - 0x0, 0x0, 0xc0, 0x3, 0xa0, 0xd, 0x0, 0x0, - 0x0, 0x0, 0xc0, 0x3, 0xa0, 0xd, 0x0, 0x0, - 0x0, 0x0, 0xd6, 0x66, 0x66, 0x6a, 0x2, 0x0, - 0x0, 0x0, 0xc0, 0x0, 0x0, 0x0, 0x6, 0x0, - 0x0, 0x0, 0xd0, 0x0, 0x0, 0x0, 0xb, 0x10, - 0x0, 0x0, 0xbc, 0xcc, 0xcc, 0xcc, 0xcd, 0x30, - - /* U+7247 "片" */ - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x2, 0x0, 0x0, 0xc3, 0x0, 0x0, 0x0, 0xf, - 0x20, 0x0, 0xd1, 0x0, 0x0, 0x0, 0xe, 0x0, - 0x0, 0xd1, 0x0, 0x0, 0x0, 0xe, 0x0, 0x0, - 0xd1, 0x0, 0x10, 0x0, 0xe, 0x66, 0x66, 0xe6, - 0x66, 0xf5, 0x0, 0xe, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, 0xe, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x1e, 0x66, 0x66, 0x6c, 0x30, 0x0, 0x0, - 0x3b, 0x0, 0x0, 0xd, 0x10, 0x0, 0x0, 0x67, - 0x0, 0x0, 0xd, 0x10, 0x0, 0x0, 0xb1, 0x0, - 0x0, 0xd, 0x10, 0x0, 0x3, 0x90, 0x0, 0x0, - 0xd, 0x10, 0x0, 0x9, 0x0, 0x0, 0x0, 0xd, - 0x10, 0x0, 0x50, 0x0, 0x0, 0x0, 0xd, 0x10, - 0x0, 0x0, 0x0, 0x0, 0x0, 0x2, 0x0, 0x0, - - /* U+725B "牛" */ - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x2, 0xd1, 0x0, 0x0, 0x0, 0x0, - 0x9, 0x60, 0x1d, 0x0, 0x0, 0x0, 0x0, 0x0, - 0xe3, 0x1, 0xd0, 0x0, 0x0, 0x0, 0x0, 0x4e, - 0x66, 0x6e, 0x66, 0x6b, 0xa0, 0x0, 0xa, 0x30, - 0x1, 0xd0, 0x0, 0x0, 0x0, 0x2, 0x90, 0x0, - 0x1d, 0x0, 0x0, 0x0, 0x0, 0x80, 0x0, 0x1, - 0xd0, 0x0, 0x0, 0x0, 0x1, 0x0, 0x0, 0x1d, - 0x0, 0x0, 0x84, 0x4, 0x76, 0x66, 0x66, 0xe6, - 0x66, 0x69, 0x80, 0x0, 0x0, 0x0, 0x1d, 0x0, - 0x0, 0x0, 0x0, 0x0, 0x0, 0x1, 0xd0, 0x0, - 0x0, 0x0, 0x0, 0x0, 0x0, 0x1d, 0x0, 0x0, - 0x0, 0x0, 0x0, 0x0, 0x1, 0xd0, 0x0, 0x0, - 0x0, 0x0, 0x0, 0x0, 0x2e, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x0, 0x1, 0x30, 0x0, 0x0, 0x0, - - /* U+7260 "牠" */ - 0x0, 0x0, 0xc1, 0x0, 0x0, 0x85, 0x0, 0x0, - 0x0, 0x10, 0xd0, 0x0, 0x0, 0xa2, 0x0, 0x0, - 0x0, 0xf4, 0xd0, 0x0, 0x90, 0xa2, 0x0, 0x0, - 0x1, 0xd0, 0xd0, 0x0, 0xc0, 0xa2, 0x5, 0x10, - 0x4, 0xb6, 0xe9, 0x80, 0xc0, 0xb7, 0x6c, 0x60, - 0x8, 0x20, 0xd0, 0x26, 0xd6, 0xb2, 0x9, 0x30, - 0x8, 0x0, 0xd0, 0x31, 0xc0, 0xa2, 0x9, 0x30, - 0x21, 0x0, 0xd0, 0x10, 0xc0, 0xa2, 0xa, 0x20, - 0x0, 0x0, 0xe7, 0x20, 0xc0, 0xa2, 0xc, 0x10, - 0x2, 0x79, 0xd0, 0x0, 0xc0, 0xa6, 0xcd, 0x0, - 0xb, 0x50, 0xd0, 0x0, 0xc0, 0xa2, 0x31, 0x20, - 0x0, 0x0, 0xd0, 0x0, 0xc0, 0x71, 0x0, 0x60, - 0x0, 0x0, 0xd0, 0x0, 0xd0, 0x0, 0x0, 0xc0, - 0x0, 0x0, 0xd0, 0x0, 0x9b, 0xbb, 0xbc, 0xb1, - 0x0, 0x0, 0x90, 0x0, 0x0, 0x0, 0x0, 0x0, - - /* U+7269 "物" */ - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, 0xc1, 0x0, 0x78, 0x0, 0x0, 0x0, - 0x0, 0x50, 0xd0, 0x0, 0xb4, 0x0, 0x0, 0x0, - 0x0, 0xe2, 0xd0, 0x1, 0xd0, 0x0, 0x0, 0x30, - 0x2, 0xb0, 0xd3, 0x36, 0x99, 0x97, 0xb6, 0xe0, - 0x6, 0x96, 0xe6, 0x5a, 0xb, 0x25, 0x91, 0xc0, - 0x8, 0x0, 0xd0, 0x52, 0xc, 0x8, 0x62, 0xb0, - 0x13, 0x0, 0xd0, 0x30, 0x75, 0xd, 0x13, 0xb0, - 0x0, 0x0, 0xd5, 0x41, 0xb0, 0x2c, 0x4, 0xa0, - 0x0, 0x39, 0xe1, 0x8, 0x10, 0x86, 0x5, 0x90, - 0xb, 0xa1, 0xd0, 0x43, 0x1, 0xc0, 0x6, 0x70, - 0x1, 0x0, 0xd0, 0x20, 0xa, 0x30, 0x8, 0x60, - 0x0, 0x0, 0xd0, 0x0, 0x74, 0x0, 0xa, 0x40, - 0x0, 0x0, 0xd0, 0x5, 0x40, 0x53, 0x4e, 0x10, - 0x0, 0x0, 0xe0, 0x41, 0x0, 0xa, 0xf6, 0x0, - 0x0, 0x0, 0x40, 0x0, 0x0, 0x1, 0x10, 0x0, - - /* U+7279 "特" */ - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x1, 0xc1, 0x0, 0x1, 0xb0, 0x0, 0x0, - 0x0, 0x0, 0xd0, 0x0, 0x1, 0xd0, 0x0, 0x0, - 0x3, 0xd1, 0xd0, 0x18, 0x66, 0xe6, 0xa8, 0x0, - 0x5, 0x90, 0xd0, 0x10, 0x1, 0xd0, 0x0, 0x0, - 0x7, 0x86, 0xe7, 0xb0, 0x1, 0xd0, 0x0, 0x20, - 0x9, 0x0, 0xd0, 0x76, 0x66, 0xb6, 0x69, 0xb0, - 0x6, 0x0, 0xd0, 0x0, 0x0, 0x8, 0x60, 0x0, - 0x0, 0x0, 0xe6, 0x50, 0x0, 0x9, 0x51, 0x60, - 0x0, 0x28, 0xe1, 0x57, 0x66, 0x6b, 0x96, 0x71, - 0xa, 0xc4, 0xd0, 0x7, 0x0, 0x9, 0x50, 0x0, - 0x3, 0x0, 0xd0, 0x5, 0xc0, 0x9, 0x50, 0x0, - 0x0, 0x0, 0xd0, 0x0, 0xd0, 0x9, 0x50, 0x0, - 0x0, 0x0, 0xd0, 0x0, 0x10, 0x9, 0x40, 0x0, - 0x0, 0x0, 0xe0, 0x0, 0x5, 0xdf, 0x20, 0x0, - 0x0, 0x0, 0x60, 0x0, 0x0, 0x22, 0x0, 0x0, - - /* U+72AC "犬" */ - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x0, 0xd, 0x30, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x0, 0xf, 0x3, 0x30, 0x0, 0x0, - 0x0, 0x0, 0x0, 0xf, 0x0, 0xb9, 0x0, 0x0, - 0x0, 0x0, 0x0, 0x1e, 0x0, 0x1f, 0x10, 0x0, - 0x0, 0x0, 0x0, 0x1d, 0x0, 0x4, 0x3, 0x20, - 0x5, 0x76, 0x66, 0x7d, 0x76, 0x66, 0x6a, 0xa0, - 0x0, 0x0, 0x0, 0x59, 0x60, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x0, 0x86, 0x52, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x0, 0xc2, 0x19, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x2, 0xd0, 0x8, 0x30, 0x0, 0x0, - 0x0, 0x0, 0x9, 0x60, 0x1, 0xc1, 0x0, 0x0, - 0x0, 0x0, 0x5b, 0x0, 0x0, 0x5d, 0x20, 0x0, - 0x0, 0x5, 0xa0, 0x0, 0x0, 0x7, 0xf7, 0x10, - 0x0, 0x86, 0x0, 0x0, 0x0, 0x0, 0x5f, 0xb1, - 0x4, 0x0, 0x0, 0x0, 0x0, 0x0, 0x1, 0x0, - - /* U+72AF "犯" */ - 0x0, 0x0, 0x0, 0x60, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x72, 0x8, 0xc2, 0xa6, 0x66, 0x6c, 0x20, - 0x0, 0x9, 0x7b, 0x0, 0xd0, 0x0, 0xe, 0x0, - 0x0, 0x3, 0xf0, 0x0, 0xd0, 0x0, 0xd, 0x0, - 0x0, 0x39, 0x84, 0x0, 0xd0, 0x0, 0xd, 0x0, - 0x4, 0x50, 0x49, 0x0, 0xd0, 0x0, 0xd, 0x0, - 0x0, 0x0, 0x9c, 0x0, 0xd0, 0x0, 0xd, 0x0, - 0x0, 0x3, 0xae, 0x0, 0xd0, 0x11, 0x1d, 0x0, - 0x0, 0x1a, 0xe, 0x0, 0xd0, 0x28, 0xfa, 0x0, - 0x0, 0x91, 0xe, 0x0, 0xd0, 0x0, 0x40, 0x0, - 0x6, 0x0, 0xd, 0x0, 0xd0, 0x0, 0x0, 0x40, - 0x0, 0x0, 0x2c, 0x0, 0xd0, 0x0, 0x0, 0x80, - 0x0, 0x0, 0x78, 0x0, 0xe0, 0x0, 0x0, 0xd3, - 0x0, 0x7d, 0xd1, 0x0, 0x7e, 0xdd, 0xdd, 0xd3, - 0x0, 0x4, 0x10, 0x0, 0x0, 0x0, 0x0, 0x0, - - /* U+72B6 "状" */ - 0x0, 0x0, 0xa3, 0x0, 0x19, 0x10, 0x0, 0x0, - 0x0, 0x0, 0xd1, 0x0, 0x1d, 0x4, 0x91, 0x0, - 0x1, 0x0, 0xd1, 0x0, 0xd, 0x0, 0x8c, 0x0, - 0x9, 0x30, 0xc1, 0x0, 0xd, 0x0, 0x6, 0x0, - 0x2, 0xe1, 0xc1, 0x0, 0xd, 0x0, 0x8, 0x20, - 0x0, 0xc1, 0xc4, 0x76, 0x6e, 0x86, 0x67, 0x50, - 0x0, 0x0, 0xc1, 0x0, 0x2b, 0x60, 0x0, 0x0, - 0x0, 0x3, 0xe1, 0x0, 0x59, 0x70, 0x0, 0x0, - 0x0, 0x65, 0xc1, 0x0, 0x76, 0x45, 0x0, 0x0, - 0x1a, 0x70, 0xc1, 0x0, 0xc2, 0xb, 0x0, 0x0, - 0x29, 0x0, 0xc1, 0x2, 0xb0, 0xa, 0x40, 0x0, - 0x0, 0x0, 0xc1, 0xa, 0x40, 0x3, 0xd1, 0x0, - 0x0, 0x0, 0xd1, 0x39, 0x0, 0x0, 0xad, 0x20, - 0x0, 0x0, 0xd4, 0x90, 0x0, 0x0, 0xd, 0x90, - 0x0, 0x0, 0x34, 0x0, 0x0, 0x0, 0x0, 0x0, - - /* U+72C0 "狀" */ - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, 0xb, 0x10, 0xa, 0x50, 0x0, 0x0, - 0x0, 0xc1, 0xd, 0x0, 0xb, 0x23, 0x70, 0x0, - 0x0, 0xd0, 0xd, 0x0, 0xb, 0x20, 0x97, 0x0, - 0x0, 0xd0, 0xd, 0x0, 0xb, 0x20, 0x14, 0x0, - 0x0, 0xd0, 0xd, 0x13, 0x3c, 0x53, 0x35, 0xa0, - 0x3, 0xc6, 0x6d, 0x24, 0x3c, 0x93, 0x33, 0x31, - 0x0, 0x0, 0xd, 0x0, 0xd, 0x70, 0x0, 0x0, - 0x0, 0x0, 0xd, 0x0, 0xd, 0x44, 0x0, 0x0, - 0x4, 0x9a, 0x6d, 0x0, 0x3b, 0x1a, 0x0, 0x0, - 0x0, 0x77, 0xd, 0x0, 0x76, 0xb, 0x20, 0x0, - 0x0, 0xa4, 0xd, 0x0, 0xc1, 0x5, 0xb0, 0x0, - 0x0, 0xc0, 0xd, 0x3, 0xa0, 0x0, 0xc6, 0x0, - 0x5, 0x50, 0xd, 0xa, 0x20, 0x0, 0x3f, 0x70, - 0x7, 0x0, 0xe, 0x54, 0x0, 0x0, 0x5, 0xa2, - 0x10, 0x0, 0x4, 0x30, 0x0, 0x0, 0x0, 0x0, - - /* U+72EC "独" */ - 0x0, 0x0, 0x5, 0x30, 0x0, 0xb1, 0x0, 0x0, - 0x2, 0x71, 0x1e, 0x40, 0x0, 0xe0, 0x0, 0x0, - 0x0, 0x1a, 0xb5, 0x0, 0x0, 0xe0, 0x0, 0x0, - 0x0, 0x9, 0xc0, 0xa, 0x66, 0xe6, 0x6b, 0x20, - 0x0, 0x84, 0xc2, 0xe, 0x0, 0xe0, 0xe, 0x0, - 0x6, 0x10, 0x96, 0xe, 0x0, 0xe0, 0xe, 0x0, - 0x0, 0x2, 0xe9, 0xe, 0x0, 0xe0, 0xe, 0x0, - 0x0, 0xa, 0x6b, 0xe, 0x0, 0xe0, 0xe, 0x0, - 0x0, 0x57, 0x2c, 0xf, 0x66, 0xe6, 0x6f, 0x0, - 0x3, 0x80, 0x2c, 0x8, 0x0, 0xe0, 0x4, 0x0, - 0x15, 0x0, 0x3b, 0x0, 0x0, 0xe0, 0x35, 0x0, - 0x0, 0x0, 0x5a, 0x0, 0x0, 0xe0, 0x9, 0x50, - 0x0, 0x10, 0xa6, 0x46, 0x79, 0xe8, 0x64, 0xf0, - 0x0, 0x4e, 0xb0, 0x7a, 0x62, 0x0, 0x0, 0x80, - 0x0, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - - /* U+72ED "狭" */ - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x6, 0x0, 0xc, 0x20, 0x0, 0x0, - 0x2, 0x60, 0x3b, 0x10, 0xe, 0x0, 0x0, 0x0, - 0x0, 0x3a, 0xb0, 0x0, 0xe, 0x0, 0x7, 0x0, - 0x0, 0x1d, 0x60, 0x76, 0x6e, 0x66, 0x68, 0x20, - 0x1, 0x92, 0xb0, 0x30, 0xe, 0x0, 0x91, 0x0, - 0x15, 0x0, 0xe0, 0x49, 0xe, 0x2, 0xc0, 0x0, - 0x0, 0x4, 0xf3, 0xe, 0x1e, 0x8, 0x10, 0x0, - 0x0, 0xb, 0x95, 0x4, 0xe, 0x3, 0x3, 0x30, - 0x0, 0x83, 0x78, 0x86, 0x6d, 0x86, 0x68, 0x70, - 0x4, 0x50, 0x77, 0x0, 0x58, 0x50, 0x0, 0x0, - 0x23, 0x0, 0x86, 0x0, 0xa3, 0x17, 0x0, 0x0, - 0x0, 0x0, 0xa4, 0x3, 0xa0, 0x9, 0x40, 0x0, - 0x1, 0x33, 0xe0, 0x1b, 0x10, 0x0, 0xd6, 0x0, - 0x0, 0x6e, 0x44, 0x81, 0x0, 0x0, 0x2d, 0xb1, - 0x0, 0x0, 0x22, 0x0, 0x0, 0x0, 0x1, 0x0, - - /* U+732B "猫" */ - 0x1, 0x0, 0x6, 0x20, 0x55, 0x6, 0x60, 0x0, - 0x2, 0x70, 0x1e, 0x50, 0x76, 0x8, 0x50, 0x0, - 0x0, 0x1a, 0xc4, 0x0, 0x75, 0x8, 0x51, 0x40, - 0x0, 0xa, 0xa2, 0x86, 0xa9, 0x6b, 0x97, 0x81, - 0x0, 0x82, 0xb1, 0x0, 0x75, 0x8, 0x50, 0x0, - 0x5, 0x0, 0x95, 0x0, 0x53, 0x5, 0x20, 0x0, - 0x0, 0x1, 0xe8, 0xc, 0x66, 0x86, 0x6d, 0x20, - 0x0, 0x9, 0x6a, 0xd, 0x0, 0xd0, 0xd, 0x0, - 0x0, 0x47, 0x2a, 0xd, 0x0, 0xd0, 0xd, 0x0, - 0x2, 0x70, 0x2a, 0xd, 0x66, 0xe6, 0x6e, 0x0, - 0x15, 0x0, 0x49, 0xd, 0x0, 0xd0, 0xd, 0x0, - 0x0, 0x0, 0x77, 0xd, 0x0, 0xd0, 0xd, 0x0, - 0x0, 0x44, 0xd2, 0xe, 0x66, 0xe6, 0x6e, 0x0, - 0x0, 0x1c, 0x70, 0xc, 0x0, 0x0, 0x9, 0x0, - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - - /* U+733F "猿" */ - 0x0, 0x0, 0x4, 0x0, 0xa, 0x20, 0x0, 0x0, - 0x5, 0x30, 0x5e, 0x10, 0xe, 0x0, 0x80, 0x0, - 0x0, 0x67, 0xd2, 0x27, 0x6e, 0x66, 0x62, 0x0, - 0x0, 0xe, 0x50, 0x0, 0xe, 0x0, 0x6, 0x50, - 0x0, 0x96, 0x85, 0x76, 0x66, 0x66, 0x66, 0x50, - 0x16, 0x11, 0xd0, 0x1a, 0x66, 0x66, 0xd2, 0x0, - 0x0, 0x6, 0xf0, 0xc, 0x0, 0x0, 0xd0, 0x0, - 0x0, 0xb, 0xb3, 0x1d, 0x66, 0x66, 0xe0, 0x0, - 0x0, 0x82, 0xb3, 0x15, 0x86, 0x50, 0x37, 0x30, - 0x4, 0x50, 0xb4, 0x3, 0xb0, 0x80, 0x7a, 0x30, - 0x23, 0x0, 0xc3, 0x3e, 0x70, 0x3c, 0x20, 0x0, - 0x0, 0x0, 0xe5, 0x65, 0x50, 0xa, 0x70, 0x0, - 0x0, 0x15, 0xd0, 0x4, 0x77, 0x30, 0xcc, 0x50, - 0x0, 0x6f, 0x40, 0x6, 0xc1, 0x0, 0x9, 0x80, - 0x0, 0x1, 0x0, 0x0, 0x10, 0x0, 0x0, 0x0, - - /* U+7372 "獲" */ - 0x0, 0x0, 0x3, 0x0, 0x63, 0x4, 0x80, 0x0, - 0x5, 0x30, 0x3e, 0x66, 0xb7, 0x68, 0xb8, 0xa0, - 0x0, 0x76, 0xc3, 0x11, 0x84, 0x14, 0x80, 0x0, - 0x0, 0xd, 0x60, 0x8, 0x40, 0xc1, 0x0, 0x0, - 0x0, 0x87, 0x80, 0x1e, 0x66, 0xa6, 0x6c, 0x10, - 0x7, 0x30, 0xc0, 0x9c, 0x0, 0xd0, 0x24, 0x0, - 0x10, 0x5, 0xf4, 0x2d, 0x66, 0xe6, 0x66, 0x0, - 0x0, 0xc, 0xc2, 0xd, 0x55, 0xe5, 0x77, 0x0, - 0x0, 0x56, 0x93, 0xd, 0x66, 0xc6, 0x69, 0x60, - 0x2, 0x90, 0x94, 0x6, 0x0, 0x0, 0x40, 0x0, - 0x7, 0x0, 0xa3, 0x7, 0x96, 0x67, 0xe4, 0x0, - 0x10, 0x0, 0xb2, 0x0, 0x37, 0x1b, 0x30, 0x0, - 0x0, 0x0, 0xe0, 0x0, 0x7, 0xf4, 0x0, 0x0, - 0x1, 0x8d, 0xa0, 0x2, 0x89, 0x4b, 0xa7, 0x60, - 0x0, 0x8, 0x14, 0x54, 0x0, 0x0, 0x37, 0x20, - - /* U+73A9 "玩" */ - 0x0, 0x0, 0x2, 0x0, 0x0, 0x0, 0x3, 0x0, - 0x18, 0x6a, 0x6a, 0x54, 0x76, 0x66, 0x78, 0x0, - 0x0, 0xd, 0x10, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0xd, 0x10, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0xd, 0x10, 0x0, 0x0, 0x0, 0x0, 0x40, - 0x5, 0x6e, 0x7c, 0x37, 0x98, 0x6b, 0x67, 0x90, - 0x1, 0xd, 0x10, 0x0, 0xa4, 0xe, 0x0, 0x0, - 0x0, 0xd, 0x10, 0x0, 0xb3, 0xe, 0x0, 0x0, - 0x0, 0xd, 0x10, 0x0, 0xe0, 0xe, 0x0, 0x0, - 0x0, 0xd, 0x10, 0x11, 0xd0, 0xe, 0x0, 0x0, - 0x0, 0xe, 0x86, 0x26, 0x80, 0xe, 0x0, 0x40, - 0x3c, 0xc5, 0x0, 0xd, 0x10, 0xe, 0x0, 0x70, - 0x6, 0x0, 0x0, 0xa4, 0x0, 0xe, 0x0, 0xb0, - 0x0, 0x0, 0x29, 0x30, 0x0, 0xc, 0xcc, 0xe2, - 0x0, 0x1, 0x30, 0x0, 0x0, 0x0, 0x0, 0x0, - - /* U+73FE "現" */ - 0x0, 0x0, 0x3, 0x2, 0x0, 0x0, 0x3, 0x0, - 0x7, 0x6a, 0x69, 0x3e, 0x66, 0x66, 0x6e, 0x10, - 0x0, 0xd, 0x0, 0xd, 0x0, 0x0, 0xc, 0x0, - 0x0, 0xd, 0x0, 0xd, 0x66, 0x66, 0x6c, 0x0, - 0x0, 0xd, 0x0, 0xd, 0x0, 0x0, 0xc, 0x0, - 0x0, 0xd, 0x5, 0xd, 0x33, 0x33, 0x3c, 0x0, - 0x6, 0x7e, 0x67, 0x2d, 0x33, 0x33, 0x3c, 0x0, - 0x0, 0xd, 0x0, 0xd, 0x0, 0x0, 0xc, 0x0, - 0x0, 0xd, 0x0, 0xe, 0x7b, 0x6c, 0x6c, 0x0, - 0x0, 0xd, 0x0, 0x3, 0x58, 0xd, 0x0, 0x0, - 0x0, 0xd, 0x14, 0x30, 0xa3, 0xd, 0x0, 0x10, - 0x16, 0x9b, 0x61, 0x2, 0xb0, 0xd, 0x0, 0x60, - 0x1a, 0x30, 0x0, 0x1b, 0x20, 0xd, 0x0, 0xa0, - 0x0, 0x0, 0x3, 0x92, 0x0, 0xc, 0xcc, 0xe3, - 0x0, 0x0, 0x23, 0x0, 0x0, 0x0, 0x0, 0x0, - - /* U+7403 "球" */ - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x0, 0x0, 0x2, 0xb0, 0x40, 0x0, - 0x0, 0x0, 0x4, 0x0, 0x1, 0xc0, 0x6a, 0x0, - 0x7, 0x6d, 0x68, 0x20, 0x1, 0xc0, 0x8, 0x10, - 0x0, 0xe, 0x0, 0x66, 0x66, 0xd6, 0x68, 0xc1, - 0x0, 0xe, 0x0, 0x0, 0x1, 0xe0, 0x0, 0x0, - 0x0, 0xe, 0x0, 0x56, 0x1, 0xe3, 0x8, 0x60, - 0x7, 0x6e, 0x6a, 0xc, 0x61, 0xc7, 0x3b, 0x20, - 0x0, 0xe, 0x0, 0x4, 0x51, 0xc8, 0x60, 0x0, - 0x0, 0xe, 0x0, 0x0, 0x4, 0xc3, 0x80, 0x0, - 0x0, 0xe, 0x2, 0x32, 0x84, 0xc0, 0xb3, 0x0, - 0x0, 0x3e, 0x85, 0x9b, 0x11, 0xc0, 0x2e, 0x40, - 0x2d, 0xa2, 0x1, 0x90, 0x1, 0xc0, 0x6, 0xd3, - 0x3, 0x0, 0x0, 0x1, 0x12, 0xc0, 0x0, 0x0, - 0x0, 0x0, 0x0, 0x1, 0x8f, 0x90, 0x0, 0x0, - 0x0, 0x0, 0x0, 0x0, 0x4, 0x0, 0x0, 0x0, - - /* U+7406 "理" */ - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x1, 0x0, - 0x0, 0x0, 0x7, 0xc, 0x66, 0x96, 0x6e, 0x0, - 0x7, 0x6d, 0x67, 0x2c, 0x0, 0xc0, 0xc, 0x0, - 0x0, 0xd, 0x0, 0xc, 0x0, 0xc0, 0xc, 0x0, - 0x0, 0xd, 0x0, 0xd, 0x66, 0xd6, 0x6c, 0x0, - 0x0, 0xd, 0x4, 0xc, 0x0, 0xc0, 0xc, 0x0, - 0x7, 0x6e, 0x69, 0x2c, 0x0, 0xc0, 0xc, 0x0, - 0x0, 0xd, 0x0, 0xd, 0x66, 0xd6, 0x6c, 0x0, - 0x0, 0xd, 0x0, 0x4, 0x0, 0xc0, 0x1, 0x0, - 0x0, 0xd, 0x0, 0x20, 0x0, 0xc0, 0x3, 0x0, - 0x0, 0xd, 0x87, 0x27, 0x66, 0xd6, 0x79, 0x10, - 0x1a, 0xd7, 0x0, 0x0, 0x0, 0xc0, 0x0, 0x0, - 0x6, 0x0, 0x0, 0x0, 0x0, 0xc0, 0x1, 0x40, - 0x0, 0x0, 0x7, 0x66, 0x66, 0x86, 0x67, 0x80, - - /* U+74B0 "環" */ - 0x0, 0x0, 0x1, 0x1, 0x0, 0x0, 0x4, 0x0, - 0x7, 0x68, 0x7b, 0x3b, 0x6c, 0x6c, 0x6d, 0x0, - 0x0, 0xc, 0x0, 0x29, 0xb, 0xb, 0xb, 0x0, - 0x0, 0xc, 0x0, 0x2b, 0x69, 0x69, 0x6b, 0x0, - 0x0, 0xc, 0x0, 0x0, 0x0, 0x0, 0x2, 0x40, - 0x3, 0x4d, 0x68, 0x76, 0x66, 0x66, 0x66, 0x50, - 0x3, 0x3c, 0x21, 0x7, 0x66, 0x66, 0x95, 0x0, - 0x0, 0xc, 0x0, 0xc, 0x0, 0x0, 0x75, 0x0, - 0x0, 0xc, 0x0, 0xc, 0x66, 0x66, 0xa5, 0x0, - 0x0, 0xc, 0x0, 0x6, 0x4a, 0x50, 0x25, 0x80, - 0x0, 0x1d, 0x75, 0x2, 0xe1, 0x35, 0x78, 0x20, - 0x1d, 0xc4, 0x0, 0x3a, 0xc0, 0x7, 0x50, 0x0, - 0x2, 0x0, 0x5, 0x50, 0xb1, 0x50, 0x9b, 0x40, - 0x0, 0x0, 0x10, 0x0, 0xe9, 0x0, 0x6, 0x70, - 0x0, 0x0, 0x0, 0x0, 0x30, 0x0, 0x0, 0x0, - - /* U+7518 "甘" */ - 0x0, 0x0, 0xa3, 0x0, 0x0, 0x93, 0x0, 0x0, - 0x0, 0xd, 0x10, 0x0, 0xd, 0x10, 0x0, 0x0, - 0x0, 0xc1, 0x0, 0x0, 0xc1, 0x0, 0x0, 0x0, - 0xc, 0x10, 0x0, 0xc, 0x10, 0xb3, 0x37, 0x66, - 0xd6, 0x66, 0x66, 0xd6, 0x66, 0x40, 0x0, 0xc, - 0x10, 0x0, 0xc, 0x10, 0x0, 0x0, 0x0, 0xc1, - 0x0, 0x0, 0xc1, 0x0, 0x0, 0x0, 0xc, 0x10, - 0x0, 0xc, 0x10, 0x0, 0x0, 0x0, 0xc6, 0x66, - 0x66, 0xd1, 0x0, 0x0, 0x0, 0xc, 0x10, 0x0, - 0xc, 0x10, 0x0, 0x0, 0x0, 0xd1, 0x0, 0x0, - 0xc1, 0x0, 0x0, 0x0, 0xd, 0x10, 0x0, 0xc, - 0x10, 0x0, 0x0, 0x0, 0xd6, 0x66, 0x66, 0xd2, - 0x0, 0x0, 0x0, 0xe, 0x10, 0x0, 0xc, 0x20, - 0x0, 0x0, 0x0, 0x40, 0x0, 0x0, 0x20, 0x0, - 0x0, - - /* U+751A "甚" */ - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x8, 0x70, 0x0, 0xd, 0x20, 0x0, 0x0, - 0x0, 0x75, 0x0, 0x0, 0xe0, 0x24, 0x0, 0x37, - 0x6a, 0x96, 0x66, 0x6e, 0x67, 0x80, 0x0, 0x0, - 0x75, 0x0, 0x0, 0xe0, 0x0, 0x0, 0x0, 0x7, - 0x96, 0x66, 0x6e, 0x0, 0x0, 0x0, 0x0, 0x75, - 0x0, 0x0, 0xe0, 0x0, 0x0, 0x0, 0x7, 0x96, - 0x66, 0x6e, 0x0, 0x0, 0x0, 0x0, 0x75, 0x0, - 0x0, 0xe0, 0x0, 0x2, 0x66, 0x6a, 0x96, 0x66, - 0x6e, 0x66, 0xc7, 0x1, 0xb, 0x20, 0x22, 0x0, - 0x0, 0x0, 0x0, 0x0, 0xb2, 0xc, 0x80, 0x1a, - 0x50, 0x0, 0x0, 0xb, 0x26, 0x80, 0x0, 0x1e, - 0x60, 0x0, 0x0, 0xb6, 0x70, 0x0, 0x0, 0x37, - 0x0, 0x0, 0xd, 0xa6, 0x66, 0x66, 0x66, 0xc8, - 0x0, 0x0, 0x30, 0x0, 0x0, 0x0, 0x0, 0x0, - - /* U+751F "生" */ - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x0, 0xa, 0x60, 0x0, 0x0, 0x0, - 0x0, 0x6, 0x90, 0xa, 0x40, 0x0, 0x0, 0x0, - 0x0, 0xb, 0x70, 0xa, 0x40, 0x0, 0x0, 0x0, - 0x0, 0x1d, 0x0, 0xa, 0x40, 0x0, 0x82, 0x0, - 0x0, 0x6a, 0x66, 0x6c, 0x86, 0x66, 0x75, 0x0, - 0x0, 0xb0, 0x0, 0xa, 0x40, 0x0, 0x0, 0x0, - 0x4, 0x50, 0x0, 0xa, 0x40, 0x0, 0x0, 0x0, - 0x7, 0x0, 0x0, 0xa, 0x40, 0x2, 0x30, 0x0, - 0x0, 0x6, 0x66, 0x6c, 0x86, 0x69, 0x90, 0x0, - 0x0, 0x0, 0x0, 0xa, 0x40, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x0, 0xa, 0x40, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x0, 0xa, 0x40, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x0, 0xa, 0x40, 0x0, 0x7, 0x20, - 0x18, 0x66, 0x66, 0x67, 0x66, 0x66, 0x69, 0x60, - - /* U+7522 "產" */ - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x0, 0xa1, 0x0, 0x0, 0x0, 0x0, - 0x36, 0x66, 0x6a, 0x76, 0x66, 0xa7, 0x0, 0x0, - 0x10, 0x34, 0x0, 0x3d, 0x40, 0x0, 0x0, 0x0, - 0x0, 0x29, 0xb8, 0x20, 0x0, 0x0, 0x0, 0x0, - 0x27, 0x75, 0xc5, 0x0, 0x0, 0x0, 0x30, 0x33, - 0x0, 0x0, 0xa0, 0x45, 0x0, 0xa, 0x86, 0x76, - 0x69, 0x66, 0x66, 0x50, 0x0, 0x94, 0xc, 0x30, - 0xd2, 0x0, 0x0, 0x0, 0xa, 0x33, 0xd6, 0x6e, - 0x66, 0x7b, 0x0, 0x0, 0xb1, 0x80, 0x0, 0xd0, - 0x0, 0x0, 0x0, 0xb, 0x23, 0x0, 0xd, 0x0, - 0x61, 0x0, 0x0, 0xa1, 0x7, 0x66, 0xe6, 0x66, - 0x30, 0x0, 0x44, 0x0, 0x0, 0xd, 0x0, 0x0, - 0x0, 0x7, 0x5, 0x66, 0x66, 0xe6, 0x66, 0x7e, - 0x31, 0x0, 0x10, 0x0, 0x0, 0x0, 0x0, 0x0, - - /* U+7523 "産" */ - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x0, 0xa2, 0x0, 0x0, 0x0, 0x0, - 0x36, 0x66, 0x6a, 0x86, 0x66, 0xd8, 0x0, 0x0, - 0x10, 0x50, 0x0, 0x37, 0x0, 0x0, 0x0, 0x0, - 0x5, 0x90, 0x7, 0x60, 0x0, 0x0, 0x3, 0x0, - 0x7, 0x0, 0x70, 0x1, 0x40, 0x0, 0xa8, 0x66, - 0x66, 0x86, 0x66, 0x77, 0x0, 0xa, 0x30, 0x83, - 0xd, 0x20, 0x0, 0x0, 0x0, 0xa3, 0xd, 0x10, - 0xd0, 0x0, 0x30, 0x0, 0xb, 0x26, 0x96, 0x6e, - 0x66, 0x69, 0x30, 0x0, 0xb0, 0x80, 0x0, 0xd0, - 0x0, 0x0, 0x0, 0xb, 0x31, 0x56, 0x6e, 0x66, - 0xa8, 0x0, 0x0, 0x90, 0x1, 0x0, 0xd0, 0x0, - 0x0, 0x0, 0x54, 0x0, 0x0, 0xd, 0x0, 0x0, - 0x0, 0x7, 0x5, 0x66, 0x66, 0xe6, 0x66, 0x7e, - 0x20, 0x10, 0x10, 0x0, 0x0, 0x0, 0x0, 0x0, - - /* U+7528 "用" */ - 0x0, 0x12, 0x0, 0x0, 0x0, 0x0, 0x6, 0x0, - 0x3, 0xd6, 0x66, 0x6d, 0x66, 0x66, 0xe0, 0x0, - 0x2b, 0x0, 0x1, 0xb0, 0x0, 0x1c, 0x0, 0x2, - 0xb0, 0x0, 0x1b, 0x0, 0x1, 0xc0, 0x0, 0x2d, - 0x66, 0x66, 0xd6, 0x66, 0x6c, 0x0, 0x2, 0xb0, - 0x0, 0x1b, 0x0, 0x1, 0xc0, 0x0, 0x3a, 0x0, - 0x1, 0xb0, 0x0, 0x1c, 0x0, 0x4, 0xa0, 0x0, - 0x1b, 0x0, 0x1, 0xc0, 0x0, 0x5b, 0x66, 0x66, - 0xd6, 0x66, 0x6c, 0x0, 0x7, 0x60, 0x0, 0x1b, - 0x0, 0x1, 0xc0, 0x0, 0xa3, 0x0, 0x1, 0xb0, - 0x0, 0x1c, 0x0, 0xc, 0x0, 0x0, 0x1b, 0x0, - 0x1, 0xc0, 0x4, 0x50, 0x0, 0x1, 0xc0, 0x22, - 0x5c, 0x0, 0x80, 0x0, 0x0, 0x29, 0x1, 0x6f, - 0x80, 0x11, 0x0, 0x0, 0x0, 0x0, 0x0, 0x30, - 0x0, - - /* U+7530 "田" */ - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x2, 0x86, - 0x66, 0x66, 0x66, 0x66, 0xb3, 0x2b, 0x0, 0x0, - 0xe0, 0x0, 0xc, 0x12, 0xb0, 0x0, 0xe, 0x0, - 0x0, 0xc1, 0x2b, 0x0, 0x0, 0xe0, 0x0, 0xc, - 0x12, 0xb0, 0x0, 0xe, 0x0, 0x0, 0xc1, 0x2b, - 0x0, 0x0, 0xe0, 0x0, 0xc, 0x12, 0xd6, 0x66, - 0x6e, 0x66, 0x66, 0xd1, 0x2b, 0x0, 0x0, 0xe0, - 0x0, 0xc, 0x12, 0xb0, 0x0, 0xe, 0x0, 0x0, - 0xc1, 0x2b, 0x0, 0x0, 0xe0, 0x0, 0xc, 0x12, - 0xb0, 0x0, 0xe, 0x0, 0x0, 0xc1, 0x2d, 0x66, - 0x66, 0x66, 0x66, 0x6d, 0x22, 0x50, 0x0, 0x0, - 0x0, 0x0, 0x40, - - /* U+7531 "由" */ - 0x0, 0x0, 0x0, 0x91, 0x0, 0x0, 0x0, 0x0, - 0x0, 0xe, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0xd0, 0x0, 0x0, 0x1, 0x20, 0x0, 0xd, 0x0, - 0x0, 0x60, 0x3d, 0x66, 0x66, 0xe6, 0x66, 0x6f, - 0x22, 0xb0, 0x0, 0xd, 0x0, 0x0, 0xe0, 0x2b, - 0x0, 0x0, 0xd0, 0x0, 0xe, 0x2, 0xb0, 0x0, - 0xd, 0x0, 0x0, 0xe0, 0x2d, 0x66, 0x66, 0xe6, - 0x66, 0x6e, 0x2, 0xb0, 0x0, 0xd, 0x0, 0x0, - 0xe0, 0x2b, 0x0, 0x0, 0xd0, 0x0, 0xe, 0x2, - 0xb0, 0x0, 0xd, 0x0, 0x0, 0xe0, 0x2b, 0x0, - 0x0, 0xd0, 0x0, 0xe, 0x3, 0xd6, 0x66, 0x66, - 0x66, 0x66, 0xe0, 0x1, 0x0, 0x0, 0x0, 0x0, - 0x1, 0x0, - - /* U+7533 "申" */ - 0x0, 0x0, 0x0, 0x10, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x1f, 0x10, 0x0, 0x0, 0x0, 0x0, 0x0, - 0xd0, 0x0, 0x0, 0x1, 0x96, 0x66, 0x6e, 0x66, - 0x66, 0xc1, 0x1d, 0x0, 0x0, 0xd0, 0x0, 0x1d, - 0x0, 0xd0, 0x0, 0xd, 0x0, 0x1, 0xd0, 0xd, - 0x0, 0x0, 0xd0, 0x0, 0x1d, 0x0, 0xe6, 0x66, - 0x6e, 0x66, 0x66, 0xd0, 0xd, 0x0, 0x0, 0xd0, - 0x0, 0x1d, 0x1, 0xd0, 0x0, 0xd, 0x0, 0x1, - 0xd0, 0x1e, 0x66, 0x66, 0xe6, 0x66, 0x6d, 0x1, - 0x70, 0x0, 0xd, 0x0, 0x0, 0x40, 0x0, 0x0, - 0x0, 0xd0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xd, - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xe0, 0x0, - 0x0, 0x0, 0x0, 0x0, 0x5, 0x0, 0x0, 0x0, - - /* U+7535 "电" */ - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x1, 0xc1, 0x0, 0x0, 0x0, 0x0, 0x0, 0xd, - 0x0, 0x0, 0x0, 0x1, 0x0, 0x0, 0xd0, 0x0, - 0x2, 0x0, 0xb7, 0x66, 0x6e, 0x66, 0x66, 0xf1, - 0xa, 0x30, 0x0, 0xd0, 0x0, 0x1d, 0x0, 0xa3, - 0x0, 0xd, 0x0, 0x1, 0xd0, 0xa, 0x86, 0x66, - 0xe6, 0x66, 0x6d, 0x0, 0xa3, 0x0, 0xd, 0x0, - 0x1, 0xd0, 0xa, 0x30, 0x0, 0xd0, 0x0, 0x1d, - 0x0, 0xb8, 0x66, 0x6e, 0x66, 0x66, 0xd0, 0xa, - 0x20, 0x0, 0xd0, 0x0, 0x3, 0x40, 0x0, 0x0, - 0xd, 0x0, 0x0, 0x6, 0x0, 0x0, 0x0, 0xe0, - 0x0, 0x0, 0x76, 0x0, 0x0, 0xb, 0xcc, 0xcc, - 0xce, 0x70, - - /* U+7537 "男" */ - 0x0, 0x86, 0x66, 0x66, 0x66, 0x6a, 0x0, 0x0, - 0xc0, 0x0, 0xd0, 0x0, 0x1d, 0x0, 0x0, 0xc0, - 0x0, 0xd0, 0x0, 0x1d, 0x0, 0x0, 0xc6, 0x66, - 0xe6, 0x66, 0x6d, 0x0, 0x0, 0xc0, 0x0, 0xd0, - 0x0, 0x1d, 0x0, 0x0, 0xc0, 0x0, 0xd0, 0x0, - 0x1d, 0x0, 0x0, 0xd6, 0x66, 0xa6, 0x66, 0x6c, - 0x0, 0x0, 0x10, 0x0, 0xe3, 0x0, 0x0, 0x0, - 0x6, 0x66, 0x66, 0xf6, 0x66, 0x66, 0xc0, 0x1, - 0x0, 0x3, 0xa0, 0x0, 0x4, 0xa0, 0x0, 0x0, - 0x9, 0x40, 0x0, 0x7, 0x60, 0x0, 0x0, 0x3b, - 0x0, 0x0, 0xa, 0x30, 0x0, 0x4, 0xc1, 0x2, - 0x41, 0x1d, 0x0, 0x2, 0x97, 0x0, 0x0, 0x3d, - 0xf7, 0x0, 0x43, 0x0, 0x0, 0x0, 0x2, 0x20, - 0x0, - - /* U+753A "町" */ - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x1, 0x7, - 0x66, 0x66, 0xb5, 0x76, 0x68, 0x69, 0xa0, 0xb1, - 0x1c, 0xd, 0x0, 0x0, 0xe0, 0x0, 0xb, 0x11, - 0xc0, 0xd0, 0x0, 0xe, 0x0, 0x0, 0xb1, 0x1c, - 0xd, 0x0, 0x0, 0xe0, 0x0, 0xb, 0x11, 0xc0, - 0xd0, 0x0, 0xe, 0x0, 0x0, 0xb6, 0x6d, 0x6d, - 0x0, 0x0, 0xe0, 0x0, 0xb, 0x11, 0xc0, 0xd0, - 0x0, 0xe, 0x0, 0x0, 0xb1, 0x1c, 0xd, 0x0, - 0x0, 0xe0, 0x0, 0xb, 0x11, 0xc0, 0xd0, 0x0, - 0xe, 0x0, 0x0, 0xc6, 0x6c, 0x6e, 0x0, 0x0, - 0xe0, 0x0, 0xc, 0x10, 0x0, 0xa0, 0x0, 0xe, - 0x0, 0x0, 0x40, 0x0, 0x0, 0x1, 0x11, 0xd0, - 0x0, 0x0, 0x0, 0x0, 0x0, 0x5, 0xea, 0x0, - 0x0, 0x0, 0x0, 0x0, 0x0, 0x3, 0x0, 0x0, - 0x0, - - /* U+753B "画" */ - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x70, 0x47, - 0x66, 0x66, 0x66, 0x66, 0x66, 0x83, 0x0, 0x0, - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x3, 0xa6, - 0x69, 0x66, 0xe0, 0x0, 0x2, 0x3, 0xa0, 0xc, - 0x0, 0xc0, 0xa2, 0xe, 0x12, 0xa0, 0xc, 0x0, - 0xc0, 0xd0, 0xd, 0x2, 0xa0, 0xc, 0x0, 0xc0, - 0xd0, 0xd, 0x2, 0xc6, 0x6d, 0x66, 0xc0, 0xd0, - 0xd, 0x2, 0xa0, 0xc, 0x0, 0xc0, 0xd0, 0xd, - 0x3, 0xa0, 0xc, 0x0, 0xc0, 0xd0, 0xd, 0x3, - 0xc6, 0x6d, 0x66, 0xd0, 0xd0, 0xd, 0x3, 0x70, - 0x0, 0x0, 0x60, 0xd0, 0x2e, 0x66, 0x66, 0x66, - 0x66, 0x66, 0xe0, 0x4, 0x0, 0x0, 0x0, 0x0, - 0x0, 0xb0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, - - /* U+754C "界" */ - 0x0, 0x4, 0x0, 0x0, 0x0, 0x0, 0x50, 0x0, - 0x0, 0xb, 0x76, 0x6e, 0x66, 0x67, 0xd0, 0x0, - 0x0, 0xa, 0x20, 0xd, 0x0, 0x3, 0xa0, 0x0, - 0x0, 0xa, 0x76, 0x6e, 0x66, 0x67, 0xa0, 0x0, - 0x0, 0xa, 0x20, 0xd, 0x0, 0x3, 0xa0, 0x0, - 0x0, 0xb, 0x76, 0x8b, 0x67, 0x67, 0xa0, 0x0, - 0x0, 0x3, 0x1, 0xd0, 0x8, 0x10, 0x10, 0x0, - 0x0, 0x0, 0xc, 0x50, 0x0, 0xa5, 0x0, 0x0, - 0x0, 0x3, 0xc6, 0xa0, 0x1, 0xa8, 0xea, 0x71, - 0x2, 0x77, 0x13, 0x60, 0x1, 0xc0, 0x17, 0x50, - 0x3, 0x0, 0x6, 0x20, 0x1, 0xc0, 0x0, 0x0, - 0x0, 0x0, 0x9, 0x0, 0x1, 0xc0, 0x0, 0x0, - 0x0, 0x0, 0x83, 0x0, 0x1, 0xc0, 0x0, 0x0, - 0x0, 0x37, 0x20, 0x0, 0x1, 0xc0, 0x0, 0x0, - 0x2, 0x10, 0x0, 0x0, 0x0, 0x20, 0x0, 0x0, - - /* U+7559 "留" */ - 0x0, 0x0, 0x29, 0x90, 0x0, 0x0, 0x0, 0x9, - 0x57, 0x63, 0x17, 0x77, 0x66, 0xc4, 0xd, 0x0, - 0x10, 0x0, 0x77, 0x0, 0xc1, 0xd, 0x0, 0x3a, - 0x10, 0xa3, 0x0, 0xd0, 0xd, 0x0, 0x39, 0xc1, - 0xb0, 0x0, 0xd0, 0xe, 0x89, 0x30, 0x6a, 0x22, - 0x68, 0x90, 0xa, 0x40, 0x1, 0x72, 0x0, 0x3b, - 0x10, 0x0, 0xa6, 0x68, 0x66, 0x66, 0x6b, 0x20, - 0x0, 0xe0, 0x0, 0x3a, 0x0, 0xe, 0x0, 0x0, - 0xe0, 0x0, 0x3a, 0x0, 0xe, 0x0, 0x0, 0xf6, - 0x66, 0x8c, 0x66, 0x6e, 0x0, 0x0, 0xe0, 0x0, - 0x3a, 0x0, 0xe, 0x0, 0x0, 0xe0, 0x0, 0x3a, - 0x0, 0xe, 0x0, 0x0, 0xf6, 0x66, 0x67, 0x66, - 0x6e, 0x0, 0x0, 0x50, 0x0, 0x0, 0x0, 0x2, - 0x0, - - /* U+756A "番" */ - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x0, 0x0, 0x2, 0x6b, 0xc0, 0x0, - 0x0, 0x24, 0x56, 0x89, 0xe8, 0x66, 0x20, 0x0, - 0x0, 0x0, 0x35, 0x0, 0xd0, 0x3d, 0x0, 0x0, - 0x0, 0x0, 0xd, 0x0, 0xd0, 0x81, 0x0, 0x20, - 0x4, 0x76, 0x68, 0x7a, 0xe7, 0x76, 0x68, 0x90, - 0x0, 0x0, 0x1, 0xc3, 0xd2, 0x70, 0x0, 0x0, - 0x0, 0x0, 0x3b, 0x20, 0xd0, 0x3b, 0x40, 0x0, - 0x0, 0x18, 0x60, 0x0, 0xe0, 0x1, 0xae, 0xa2, - 0x4, 0x51, 0xb6, 0x66, 0xa6, 0x66, 0xd4, 0x30, - 0x0, 0x0, 0xd0, 0x0, 0xd0, 0x0, 0xd0, 0x0, - 0x0, 0x0, 0xe6, 0x66, 0xe6, 0x66, 0xd0, 0x0, - 0x0, 0x0, 0xd0, 0x0, 0xd0, 0x0, 0xd0, 0x0, - 0x0, 0x0, 0xd0, 0x0, 0xd0, 0x0, 0xd0, 0x0, - 0x0, 0x0, 0xe6, 0x66, 0x66, 0x66, 0xc0, 0x0, - 0x0, 0x0, 0x20, 0x0, 0x0, 0x0, 0x0, 0x0, - - /* U+756B "畫" */ - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x0, 0xc2, 0x0, 0x0, 0x0, 0x0, - 0x6, 0x66, 0x6e, 0x66, 0x6b, 0x20, 0x0, 0x0, - 0x10, 0x0, 0xd0, 0x0, 0xd0, 0x70, 0x4, 0x76, - 0x66, 0x6e, 0x66, 0x6e, 0x66, 0x20, 0x0, 0x66, - 0x55, 0xe5, 0x55, 0xc0, 0x0, 0x0, 0x5, 0x66, - 0x6e, 0x66, 0x67, 0x80, 0x0, 0x0, 0x10, 0x0, - 0xd0, 0x0, 0x1, 0x30, 0x0, 0x76, 0x66, 0x67, - 0x66, 0x66, 0x66, 0x0, 0x0, 0xa6, 0x66, 0x76, - 0x66, 0xa6, 0x0, 0x0, 0xd, 0x0, 0xd, 0x0, - 0xa, 0x30, 0x0, 0x0, 0xd6, 0x66, 0xe6, 0x66, - 0xc3, 0x0, 0x0, 0xd, 0x66, 0x6e, 0x66, 0x6c, - 0x30, 0x0, 0x0, 0xb0, 0x0, 0x0, 0x0, 0x51, - 0x40, 0x16, 0x66, 0x66, 0x66, 0x66, 0x66, 0x7f, - 0x60, 0x20, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - - /* U+7570 "異" */ - 0x0, 0x3, 0x0, 0x0, 0x0, 0x0, 0x50, 0x0, - 0x0, 0xd6, 0x66, 0xd6, 0x66, 0x6e, 0x20, 0x0, - 0xd, 0x0, 0xb, 0x10, 0x0, 0xd0, 0x0, 0x0, - 0xd6, 0x66, 0xd6, 0x66, 0x6d, 0x0, 0x0, 0xd, - 0x0, 0xb, 0x10, 0x0, 0xd0, 0x0, 0x0, 0xd6, - 0x66, 0x96, 0x66, 0x6d, 0x0, 0x0, 0x5, 0xa, - 0x10, 0xa, 0x20, 0x30, 0x0, 0x0, 0x0, 0xd0, - 0x0, 0xd0, 0x1, 0x60, 0x0, 0x76, 0x6e, 0x66, - 0x6e, 0x66, 0x65, 0x0, 0x0, 0x0, 0xd0, 0x0, - 0xd0, 0x0, 0x0, 0x6, 0x76, 0x6b, 0x66, 0x6b, - 0x66, 0x6a, 0x70, 0x0, 0x0, 0x87, 0x0, 0x36, - 0x20, 0x0, 0x0, 0x2, 0xb9, 0x20, 0x0, 0x19, - 0xc4, 0x0, 0x28, 0x71, 0x0, 0x0, 0x0, 0x4, - 0xf2, 0x3, 0x0, 0x0, 0x0, 0x0, 0x0, 0x2, - 0x10, - - /* U+7576 "當" */ - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x20, 0x0, 0xc3, 0x0, 0x30, 0x0, 0x0, 0x2b, - 0x10, 0xc0, 0x6, 0xc0, 0x0, 0x1, 0x7, 0x40, - 0xc0, 0x9, 0x0, 0x0, 0x9, 0x66, 0x66, 0xb6, - 0x86, 0x66, 0xd7, 0x2b, 0x0, 0x0, 0x0, 0x1, - 0x3, 0x80, 0x75, 0x8, 0x86, 0x66, 0x6c, 0x52, - 0x0, 0x0, 0x7, 0x40, 0x0, 0xa, 0x20, 0x0, - 0x0, 0x7, 0x86, 0x66, 0x6c, 0x30, 0x0, 0x0, - 0x4, 0x10, 0x0, 0x4, 0x0, 0x0, 0x0, 0xc6, - 0x66, 0x76, 0x66, 0x7d, 0x0, 0x0, 0xd0, 0x0, - 0xa2, 0x0, 0x39, 0x0, 0x0, 0xd6, 0x66, 0xc7, - 0x66, 0x89, 0x0, 0x0, 0xd0, 0x0, 0xa2, 0x0, - 0x39, 0x0, 0x0, 0xe6, 0x66, 0xc7, 0x66, 0x8a, - 0x0, 0x0, 0x90, 0x0, 0x0, 0x0, 0x26, 0x0, - - /* U+75B2 "疲" */ - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x0, 0x2, 0x91, 0x0, 0x0, 0x0, - 0x0, 0x2, 0x0, 0x0, 0x87, 0x0, 0x3, 0x20, - 0x0, 0x8, 0x86, 0x66, 0x77, 0x66, 0x69, 0x70, - 0x4, 0x8, 0x40, 0x0, 0xd, 0x20, 0x0, 0x0, - 0x7, 0x68, 0x40, 0x96, 0x6e, 0x66, 0x6b, 0x10, - 0x3, 0x98, 0x40, 0xc0, 0xd, 0x0, 0x67, 0x0, - 0x0, 0x8, 0x40, 0xc0, 0xd, 0x0, 0x30, 0x0, - 0x0, 0x5b, 0x40, 0xc0, 0xd, 0x0, 0x60, 0x0, - 0x2d, 0x3a, 0x21, 0xd6, 0x86, 0x67, 0xe2, 0x0, - 0x1, 0xb, 0x3, 0xa0, 0x60, 0xa, 0x50, 0x0, - 0x0, 0xb, 0x7, 0x60, 0x27, 0x4b, 0x0, 0x0, - 0x0, 0x66, 0xc, 0x0, 0x9, 0xd1, 0x0, 0x0, - 0x0, 0xa0, 0x65, 0x0, 0x5b, 0x8a, 0x40, 0x0, - 0x6, 0x13, 0x60, 0x48, 0x50, 0x2, 0xaf, 0x90, - 0x1, 0x1, 0x3, 0x10, 0x0, 0x0, 0x1, 0x0, - - /* U+75C5 "病" */ - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x0, 0x1a, 0x10, 0x0, 0x0, 0x0, - 0x4, 0x0, 0x0, 0x76, 0x0, 0x5, 0x20, 0x0, - 0xc7, 0x66, 0x66, 0x66, 0x66, 0x64, 0x8, 0x2c, - 0x10, 0x0, 0x0, 0x0, 0x5, 0x0, 0x49, 0xc3, - 0x76, 0x66, 0xd6, 0x66, 0x82, 0x0, 0x1c, 0x10, - 0x0, 0xe, 0x0, 0x0, 0x0, 0x5, 0xd1, 0x86, - 0x66, 0xe6, 0x66, 0xb1, 0x2b, 0x2d, 0xd, 0x0, - 0x2b, 0x0, 0xe, 0x0, 0x30, 0xc0, 0xd0, 0x7, - 0x83, 0x0, 0xe0, 0x0, 0x1b, 0xc, 0x0, 0xc0, - 0x76, 0xe, 0x0, 0x4, 0x60, 0xc0, 0x83, 0x0, - 0xe1, 0xe0, 0x0, 0xa1, 0xc, 0x52, 0x0, 0x4, - 0xe, 0x0, 0x27, 0x0, 0xd0, 0x0, 0x1, 0x32, - 0xd0, 0x7, 0x0, 0xd, 0x0, 0x0, 0x5, 0xf9, - 0x1, 0x0, 0x0, 0x10, 0x0, 0x0, 0x1, 0x0, - - /* U+75DB "痛" */ - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x0, 0x0, 0x85, 0x0, 0x0, 0x0, - 0x0, 0x1, 0x10, 0x0, 0x2c, 0x0, 0x4, 0x50, - 0x0, 0x3, 0xc6, 0x66, 0x66, 0x66, 0x66, 0x60, - 0x8, 0x23, 0xb0, 0x76, 0x66, 0x66, 0xa8, 0x0, - 0x4, 0xc2, 0xb0, 0x0, 0x33, 0x18, 0x73, 0x0, - 0x0, 0x82, 0xb0, 0x20, 0xc, 0x60, 0x3, 0x0, - 0x0, 0x2, 0xb0, 0xe6, 0x6c, 0x76, 0x6e, 0x20, - 0x0, 0x59, 0xa0, 0xd0, 0xa, 0x20, 0xd, 0x0, - 0x2c, 0x74, 0x80, 0xe6, 0x6c, 0x76, 0x6e, 0x0, - 0x5, 0x7, 0x50, 0xd0, 0xa, 0x20, 0xd, 0x0, - 0x0, 0xb, 0x10, 0xd6, 0x6c, 0x76, 0x6e, 0x0, - 0x0, 0x2a, 0x0, 0xd0, 0xa, 0x20, 0xd, 0x0, - 0x0, 0x91, 0x0, 0xd0, 0xa, 0x20, 0xd, 0x0, - 0x5, 0x30, 0x0, 0xd0, 0xa, 0x35, 0xcd, 0x0, - 0x1, 0x0, 0x0, 0x40, 0x1, 0x0, 0x21, 0x0, - - /* U+767A "発" */ - 0x0, 0x0, 0x0, 0x43, 0x0, 0x32, 0x0, 0x0, - 0x46, 0x66, 0x8d, 0x43, 0x2c, 0x40, 0x0, 0x0, - 0x73, 0xb, 0x30, 0x95, 0x1, 0x90, 0x0, 0x2, - 0x97, 0x70, 0x3, 0x71, 0xa5, 0x0, 0x0, 0x6, - 0x80, 0x0, 0x6, 0xd2, 0x0, 0x0, 0x7, 0x60, - 0x0, 0x0, 0x19, 0xdc, 0x71, 0x36, 0x15, 0x7e, - 0x66, 0xe6, 0x50, 0x63, 0x0, 0x0, 0x0, 0xc0, - 0xd, 0x0, 0x0, 0x0, 0x0, 0x0, 0xc, 0x0, - 0xd0, 0x0, 0x40, 0x0, 0x76, 0x66, 0xd6, 0x6e, - 0x66, 0x68, 0x30, 0x0, 0x0, 0x58, 0x0, 0xd0, - 0x0, 0x0, 0x0, 0x0, 0xc, 0x10, 0xd, 0x0, - 0x5, 0x0, 0x0, 0x9, 0x30, 0x0, 0xc0, 0x0, - 0x74, 0x1, 0x57, 0x0, 0x0, 0x8, 0xcb, 0xbd, - 0x50, 0x20, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, - - /* U+767C "發" */ - 0x0, 0x0, 0x0, 0x51, 0x10, 0x32, 0x0, 0x0, - 0x3, 0x86, 0x6f, 0x55, 0xa, 0x20, 0x0, 0x0, - 0x38, 0x9, 0x70, 0x1a, 0x1, 0xc0, 0x0, 0x0, - 0x67, 0x80, 0x0, 0x38, 0x61, 0x0, 0x0, 0x8, - 0x60, 0x0, 0x0, 0x3b, 0x73, 0x10, 0x47, 0x67, - 0xb6, 0x7, 0x76, 0xc7, 0xb4, 0x1, 0x0, 0xb, - 0x20, 0x93, 0xd, 0x0, 0x0, 0x3, 0x11, 0xb2, - 0xb, 0x0, 0xd0, 0x0, 0x0, 0xb6, 0x59, 0x12, - 0x80, 0x7, 0xbb, 0x70, 0xc, 0x10, 0x11, 0x63, - 0x33, 0x37, 0x10, 0x0, 0xc6, 0x6c, 0x70, 0x43, - 0x35, 0xc1, 0x0, 0x0, 0x0, 0xc1, 0x4, 0x30, - 0xb2, 0x0, 0x0, 0x0, 0xd, 0x0, 0x3, 0xca, - 0x0, 0x0, 0x0, 0x1, 0xc0, 0x0, 0x96, 0x6b, - 0x10, 0x0, 0x18, 0xc7, 0x4, 0x72, 0x0, 0x6b, - 0x0, 0x0, 0x5, 0x3, 0x10, 0x0, 0x0, 0x20, - - /* U+767D "白" */ - 0x0, 0x0, 0x1b, 0x10, 0x0, 0x0, 0x0, 0x0, - 0x89, 0x0, 0x0, 0x0, 0x0, 0x0, 0x90, 0x0, - 0x0, 0x20, 0xd, 0x67, 0x66, 0x66, 0x66, 0xd6, - 0xe, 0x0, 0x0, 0x0, 0x0, 0xc1, 0xe, 0x0, - 0x0, 0x0, 0x0, 0xc1, 0xe, 0x0, 0x0, 0x0, - 0x0, 0xc1, 0xe, 0x66, 0x66, 0x66, 0x66, 0xd1, - 0xe, 0x0, 0x0, 0x0, 0x0, 0xc1, 0xe, 0x0, - 0x0, 0x0, 0x0, 0xc1, 0xe, 0x0, 0x0, 0x0, - 0x0, 0xc1, 0xe, 0x0, 0x0, 0x0, 0x0, 0xc1, - 0xe, 0x66, 0x66, 0x66, 0x66, 0xd1, 0xe, 0x0, - 0x0, 0x0, 0x0, 0xc2, 0x2, 0x0, 0x0, 0x0, - 0x0, 0x0, - - /* U+767E "百" */ - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x13, 0x2, - 0x86, 0x66, 0x68, 0x96, 0x66, 0x68, 0x90, 0x0, - 0x0, 0x0, 0x99, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0xa, 0x0, 0x0, 0x0, 0x0, 0x0, 0x29, - 0x66, 0x96, 0x66, 0x6c, 0x0, 0x0, 0x1, 0xd0, - 0x0, 0x0, 0x3, 0xc0, 0x0, 0x0, 0x1d, 0x0, - 0x0, 0x0, 0x3c, 0x0, 0x0, 0x1, 0xd0, 0x0, - 0x0, 0x3, 0xc0, 0x0, 0x0, 0x1e, 0x66, 0x66, - 0x66, 0x7c, 0x0, 0x0, 0x1, 0xd0, 0x0, 0x0, - 0x3, 0xc0, 0x0, 0x0, 0x1d, 0x0, 0x0, 0x0, - 0x3c, 0x0, 0x0, 0x1, 0xd0, 0x0, 0x0, 0x3, - 0xc0, 0x0, 0x0, 0x1e, 0x66, 0x66, 0x66, 0x7c, - 0x0, 0x0, 0x2, 0xd0, 0x0, 0x0, 0x3, 0xc0, - 0x0, 0x0, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, - - /* U+7684 "的" */ - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xb, - 0x30, 0x0, 0x2b, 0x10, 0x0, 0x0, 0xd0, 0x0, - 0x6, 0xc0, 0x0, 0x1, 0x44, 0x3, 0x0, 0xb3, - 0x0, 0x10, 0xe7, 0x66, 0xe4, 0x2d, 0x66, 0x6c, - 0x8d, 0x0, 0xd, 0x9, 0x30, 0x0, 0xb3, 0xd0, - 0x0, 0xd2, 0x60, 0x0, 0xb, 0x3d, 0x0, 0xd, - 0x41, 0x40, 0x0, 0xb3, 0xd6, 0x66, 0xd0, 0xa, - 0x40, 0xc, 0x2d, 0x0, 0xd, 0x0, 0x4b, 0x0, - 0xc2, 0xd0, 0x0, 0xd0, 0x0, 0x40, 0xd, 0x1d, - 0x0, 0xd, 0x0, 0x0, 0x0, 0xd1, 0xd0, 0x0, - 0xd0, 0x0, 0x0, 0xe, 0xe, 0x66, 0x6e, 0x0, - 0x5, 0x25, 0xd0, 0xd0, 0x0, 0xa0, 0x0, 0x1a, - 0xf6, 0x0, 0x0, 0x0, 0x0, 0x0, 0x2, 0x0, - - /* U+7686 "皆" */ - 0x28, 0x0, 0x0, 0x1b, 0x0, 0x10, 0x0, 0x2a, - 0x0, 0x0, 0x1c, 0x2, 0xe6, 0x0, 0x2c, 0x66, - 0xa8, 0x1c, 0x3b, 0x40, 0x0, 0x2a, 0x0, 0x0, - 0x1d, 0x40, 0x0, 0x40, 0x2a, 0x0, 0x14, 0x1c, - 0x0, 0x0, 0x70, 0x3d, 0xa9, 0x50, 0xd, 0x0, - 0x1, 0xe2, 0x2a, 0x20, 0xb, 0x28, 0xbb, 0xbb, - 0x80, 0x1, 0x0, 0x37, 0x0, 0x2, 0x0, 0x0, - 0x5, 0xc6, 0x66, 0x66, 0x6c, 0x60, 0x0, 0x4, - 0xa0, 0x0, 0x0, 0xb, 0x30, 0x0, 0x4, 0xc6, - 0x66, 0x66, 0x6c, 0x30, 0x0, 0x4, 0xa0, 0x0, - 0x0, 0xb, 0x30, 0x0, 0x4, 0xa0, 0x0, 0x0, - 0xb, 0x30, 0x0, 0x5, 0xc6, 0x66, 0x66, 0x6c, - 0x30, 0x0, 0x1, 0x10, 0x0, 0x0, 0x1, 0x0, - 0x0, - - /* U+76BF "皿" */ - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x20, 0x0, - 0x0, 0x1c, 0x66, 0xa6, 0x6a, 0x66, 0xf2, 0x0, - 0x0, 0x1c, 0x0, 0xd0, 0xd, 0x0, 0xe0, 0x0, - 0x0, 0x1c, 0x0, 0xd0, 0xd, 0x0, 0xe0, 0x0, - 0x0, 0x1c, 0x0, 0xd0, 0xd, 0x0, 0xe0, 0x0, - 0x0, 0x1c, 0x0, 0xd0, 0xd, 0x0, 0xe0, 0x0, - 0x0, 0x1c, 0x0, 0xd0, 0xd, 0x0, 0xe0, 0x0, - 0x0, 0x1c, 0x0, 0xd0, 0xd, 0x0, 0xe0, 0x0, - 0x0, 0x1c, 0x0, 0xd0, 0xd, 0x0, 0xe0, 0x0, - 0x0, 0x1c, 0x0, 0xd0, 0xd, 0x0, 0xe0, 0x0, - 0x0, 0x1c, 0x0, 0xd0, 0xd, 0x0, 0xe2, 0x90, - 0x6, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x62, - - /* U+76D7 "盗" */ - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x31, 0x0, 0x0, 0xa7, 0x0, 0x0, 0x0, 0x0, - 0xc3, 0x1, 0x1e, 0x20, 0x0, 0x10, 0x0, 0x4, - 0x74, 0x29, 0x96, 0x66, 0x6e, 0x60, 0x0, 0x1, - 0x83, 0x90, 0x86, 0x4, 0x60, 0x0, 0x0, 0xb2, - 0x70, 0xd, 0x70, 0x20, 0x0, 0x6, 0xe6, 0x0, - 0x4, 0xb6, 0x30, 0x0, 0x0, 0xd, 0x0, 0x0, - 0xc3, 0xb, 0x20, 0x0, 0x0, 0xf0, 0x0, 0x95, - 0x0, 0x3e, 0x82, 0x0, 0x8, 0x4, 0x71, 0x0, - 0x0, 0x38, 0x10, 0x0, 0x96, 0x66, 0x66, 0x66, - 0x6d, 0x20, 0x0, 0xd, 0x0, 0xd0, 0xd, 0x0, - 0xd0, 0x0, 0x0, 0xd0, 0xd, 0x0, 0xd0, 0xd, - 0x0, 0x0, 0xd, 0x0, 0xd0, 0xd, 0x0, 0xd0, - 0x0, 0x46, 0xe6, 0x6e, 0x66, 0xe6, 0x6e, 0xab, - 0x1, 0x10, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - - /* U+76EE "目" */ - 0x1, 0x0, 0x0, 0x0, 0x2, 0x1, 0xd6, 0x66, - 0x66, 0x67, 0xe1, 0x1e, 0x0, 0x0, 0x0, 0x3c, - 0x0, 0xe0, 0x0, 0x0, 0x3, 0xc0, 0xe, 0x0, - 0x0, 0x0, 0x3c, 0x0, 0xf6, 0x66, 0x66, 0x67, - 0xc0, 0xe, 0x0, 0x0, 0x0, 0x3c, 0x0, 0xe0, - 0x0, 0x0, 0x3, 0xc0, 0xf, 0x66, 0x66, 0x66, - 0x7c, 0x0, 0xe0, 0x0, 0x0, 0x3, 0xc0, 0xe, - 0x0, 0x0, 0x0, 0x3c, 0x0, 0xe0, 0x0, 0x0, - 0x3, 0xc0, 0xf, 0x66, 0x66, 0x66, 0x7c, 0x1, - 0xd0, 0x0, 0x0, 0x3, 0xc0, 0x1, 0x0, 0x0, - 0x0, 0x0, 0x0, - - /* U+76F4 "直" */ - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x0, 0x5, 0x90, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x0, 0x6, 0x70, 0x0, 0x37, 0x0, - 0x0, 0x76, 0x66, 0x6b, 0x86, 0x66, 0x66, 0x10, - 0x0, 0x0, 0x30, 0xb, 0x10, 0x5, 0x0, 0x0, - 0x0, 0x0, 0xe6, 0x66, 0x66, 0x6e, 0x20, 0x0, - 0x0, 0x0, 0xd0, 0x0, 0x0, 0xd, 0x0, 0x0, - 0x0, 0x0, 0xe6, 0x66, 0x66, 0x6e, 0x0, 0x0, - 0x0, 0x0, 0xd0, 0x0, 0x0, 0xd, 0x0, 0x0, - 0x0, 0x0, 0xe6, 0x66, 0x66, 0x6e, 0x0, 0x0, - 0x0, 0x0, 0xd0, 0x0, 0x0, 0xd, 0x0, 0x0, - 0x0, 0x0, 0xe6, 0x66, 0x66, 0x6e, 0x0, 0x0, - 0x0, 0x0, 0xd0, 0x0, 0x0, 0xd, 0x0, 0x0, - 0x0, 0x0, 0xd0, 0x0, 0x0, 0xd, 0x6, 0x40, - 0x6, 0x66, 0x76, 0x66, 0x66, 0x67, 0x67, 0x70, - - /* U+76F8 "相" */ - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0xd, 0x20, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0xd0, 0x0, 0x96, 0x66, 0x6c, 0x30, 0x0, - 0xd, 0x0, 0xd, 0x10, 0x0, 0xe0, 0x0, 0x0, - 0xd0, 0x52, 0xd1, 0x0, 0xe, 0x0, 0x67, 0x6f, - 0x67, 0x4c, 0x10, 0x0, 0xe0, 0x0, 0x4, 0xf0, - 0x0, 0xc6, 0x66, 0x6e, 0x0, 0x0, 0x9f, 0x95, - 0xc, 0x10, 0x0, 0xe0, 0x0, 0xc, 0xd1, 0xe0, - 0xc1, 0x0, 0xe, 0x0, 0x6, 0x5d, 0x3, 0xc, - 0x66, 0x66, 0xe0, 0x0, 0xa0, 0xd0, 0x0, 0xc1, - 0x0, 0xe, 0x0, 0x62, 0xd, 0x0, 0xc, 0x10, - 0x0, 0xe0, 0x13, 0x0, 0xd0, 0x0, 0xc1, 0x0, - 0xe, 0x0, 0x0, 0xe, 0x0, 0xd, 0x66, 0x66, - 0xe0, 0x0, 0x0, 0xe0, 0x0, 0xd1, 0x0, 0xd, - 0x0, 0x0, 0x3, 0x0, 0x2, 0x0, 0x0, 0x0, - - /* U+770B "看" */ - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x0, 0x0, 0x3, 0x7b, 0xc0, 0x0, - 0x0, 0x55, 0x67, 0x7e, 0x97, 0x53, 0x10, 0x0, - 0x0, 0x0, 0x0, 0x2c, 0x0, 0x0, 0x30, 0x0, - 0x0, 0x37, 0x66, 0xaa, 0x66, 0x68, 0x90, 0x0, - 0x0, 0x0, 0x0, 0xd1, 0x0, 0x0, 0x1, 0x30, - 0x7, 0x66, 0x69, 0xb6, 0x66, 0x66, 0x69, 0x90, - 0x0, 0x0, 0xc, 0x10, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x8d, 0x66, 0x66, 0x6c, 0x40, 0x0, - 0x0, 0x4, 0x8d, 0x0, 0x0, 0xb, 0x20, 0x0, - 0x0, 0x38, 0xe, 0x66, 0x66, 0x6d, 0x20, 0x0, - 0x4, 0x50, 0xd, 0x0, 0x0, 0xb, 0x20, 0x0, - 0x1, 0x0, 0xe, 0x66, 0x66, 0x6d, 0x20, 0x0, - 0x0, 0x0, 0xd, 0x0, 0x0, 0xb, 0x20, 0x0, - 0x0, 0x0, 0xe, 0x66, 0x66, 0x6d, 0x20, 0x0, - 0x0, 0x0, 0x9, 0x0, 0x0, 0x7, 0x10, 0x0, - - /* U+771F "真" */ - 0x0, 0x0, 0x0, 0x2, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x0, 0x8, 0x90, 0x0, 0x0, 0x0, - 0x0, 0x56, 0x66, 0x6b, 0x96, 0x66, 0x6e, 0x30, - 0x0, 0x20, 0x0, 0xb, 0x30, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x30, 0xc, 0x10, 0x7, 0x0, 0x0, - 0x0, 0x0, 0xd6, 0x66, 0x66, 0x6e, 0x0, 0x0, - 0x0, 0x0, 0xd6, 0x66, 0x66, 0x6c, 0x0, 0x0, - 0x0, 0x0, 0xc1, 0x0, 0x0, 0x1c, 0x0, 0x0, - 0x0, 0x0, 0xc6, 0x66, 0x66, 0x6c, 0x0, 0x0, - 0x0, 0x0, 0xc1, 0x0, 0x0, 0x1c, 0x0, 0x0, - 0x0, 0x0, 0xc6, 0x66, 0x66, 0x6c, 0x0, 0x0, - 0x5, 0x66, 0xd6, 0x66, 0x66, 0x6d, 0x68, 0xd1, - 0x1, 0x0, 0x6, 0x90, 0x3, 0x50, 0x0, 0x0, - 0x0, 0x0, 0x8a, 0x10, 0x0, 0x3c, 0x60, 0x0, - 0x0, 0x28, 0x40, 0x0, 0x0, 0x1, 0xc7, 0x0, - 0x0, 0x30, 0x0, 0x0, 0x0, 0x0, 0x14, 0x0, - - /* U+7720 "眠" */ - 0x0, 0x0, 0x5, 0x22, 0x22, 0x22, 0x70, 0xa, - 0x66, 0xc2, 0xb5, 0x44, 0x44, 0x4e, 0x0, 0xd0, - 0xd, 0xa, 0x20, 0x0, 0x0, 0xd0, 0xd, 0x0, - 0xd0, 0xa2, 0x0, 0x0, 0xd, 0x0, 0xd0, 0xd, - 0xa, 0x76, 0x7a, 0x66, 0xd0, 0xd, 0x66, 0xe0, - 0xa2, 0x3, 0xa0, 0x0, 0x0, 0xd0, 0xd, 0xa, - 0x20, 0x2a, 0x0, 0x21, 0xd, 0x0, 0xd0, 0xa7, - 0x56, 0xd5, 0x58, 0x50, 0xd6, 0x6e, 0xa, 0x20, - 0xd, 0x0, 0x0, 0xd, 0x0, 0xd0, 0xa2, 0x0, - 0xa3, 0x0, 0x0, 0xd0, 0xd, 0xa, 0x20, 0x5, - 0xa0, 0x4, 0xd, 0x66, 0xe0, 0xa2, 0x45, 0xd, - 0x50, 0x50, 0xd0, 0x8, 0xb, 0xc6, 0x0, 0x3e, - 0x77, 0x1, 0x0, 0x0, 0x95, 0x0, 0x0, 0x3d, - 0xc0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x3, - 0x0, - - /* U+773E "眾" */ - 0x1, 0x86, 0x66, 0x66, 0x66, 0x69, 0x70, 0x1, - 0xc0, 0xc, 0x0, 0x30, 0x8, 0x60, 0x0, 0xc0, - 0xc, 0x0, 0x30, 0x8, 0x40, 0x0, 0xc0, 0xc, - 0x0, 0x30, 0x8, 0x40, 0x1, 0xd6, 0x66, 0x66, - 0x66, 0x69, 0x30, 0x0, 0x10, 0x0, 0x0, 0x25, - 0x9c, 0x10, 0x4, 0x56, 0x78, 0x9c, 0x87, 0x54, - 0x10, 0x0, 0x3, 0x10, 0x29, 0x0, 0x50, 0x0, - 0x0, 0xa, 0x70, 0x29, 0x3, 0xe1, 0x0, 0x0, - 0x1e, 0x0, 0x29, 0x6, 0xc0, 0x0, 0x0, 0x88, - 0xb3, 0x29, 0xb, 0x85, 0x0, 0x3, 0xa0, 0x1e, - 0x49, 0x38, 0xc, 0x40, 0x37, 0x0, 0x4, 0x4a, - 0x70, 0x2, 0xe5, 0x0, 0x0, 0x0, 0x29, 0x0, - 0x0, 0x0, 0x0, 0x0, 0x0, 0x13, 0x0, 0x0, - 0x0, - - /* U+7740 "着" */ - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x83, 0x0, 0xc, 0x10, 0x0, 0x0, - 0x0, 0x2, 0xe0, 0x6, 0x40, 0x3, 0x0, 0x28, - 0x66, 0x69, 0x96, 0x86, 0x68, 0xb1, 0x0, 0x0, - 0x0, 0x1c, 0x0, 0x4, 0x0, 0x0, 0x0, 0x76, - 0x6a, 0xa6, 0x66, 0x93, 0x0, 0x0, 0x0, 0x0, - 0xc0, 0x0, 0x0, 0x6, 0x0, 0x76, 0x66, 0xb9, - 0x66, 0x66, 0x66, 0x84, 0x0, 0x0, 0x3e, 0x66, - 0x66, 0x69, 0x40, 0x0, 0x0, 0x29, 0xd0, 0x0, - 0x0, 0xa3, 0x0, 0x0, 0x38, 0xd, 0x66, 0x66, - 0x6c, 0x20, 0x0, 0x44, 0x0, 0xd0, 0x0, 0x0, - 0xa2, 0x0, 0x10, 0x0, 0xd, 0x66, 0x66, 0x6c, - 0x20, 0x0, 0x0, 0x0, 0xd0, 0x0, 0x0, 0xa2, - 0x0, 0x0, 0x0, 0xd, 0x66, 0x66, 0x6c, 0x30, - 0x0, 0x0, 0x0, 0x60, 0x0, 0x0, 0x40, 0x0, - - /* U+77E5 "知" */ - 0x0, 0x47, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x8, 0x60, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0xc1, 0x0, 0x20, 0x10, 0x0, 0x2, 0x0, 0x1c, - 0x68, 0x7b, 0x1a, 0x76, 0x67, 0xd0, 0x7, 0x22, - 0xb0, 0x0, 0xa2, 0x0, 0x2a, 0x0, 0x70, 0x2b, - 0x0, 0xa, 0x20, 0x2, 0xa0, 0x20, 0x2, 0xb0, - 0x31, 0xa2, 0x0, 0x2a, 0x5, 0x76, 0x7c, 0x69, - 0x6a, 0x20, 0x2, 0xa0, 0x0, 0x5, 0x80, 0x0, - 0xa2, 0x0, 0x2a, 0x0, 0x0, 0x89, 0x50, 0xa, - 0x20, 0x2, 0xa0, 0x0, 0xd, 0x7, 0x90, 0xa2, - 0x0, 0x2b, 0x0, 0x6, 0x70, 0xc, 0x7a, 0x76, - 0x67, 0xb0, 0x2, 0xa0, 0x0, 0x37, 0xa2, 0x0, - 0x2b, 0x2, 0x80, 0x0, 0x0, 0x5, 0x0, 0x1, - 0x40, 0x20, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, - - /* U+77ED "短" */ - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0xb, 0x40, 0x0, 0x0, 0x0, 0x0, 0x10, 0x0, - 0xe0, 0x0, 0x76, 0x66, 0x66, 0x89, 0x0, 0x58, - 0x0, 0x40, 0x0, 0x0, 0x0, 0x0, 0xb, 0x7c, - 0x67, 0x2, 0x0, 0x0, 0x30, 0x3, 0x70, 0xd0, - 0x0, 0xe6, 0x66, 0x6f, 0x10, 0x40, 0xd, 0x0, - 0xd, 0x0, 0x0, 0xd0, 0x1, 0x11, 0xd1, 0x81, - 0xd0, 0x0, 0xd, 0x0, 0x45, 0x5d, 0x44, 0x2e, - 0x66, 0x66, 0xd0, 0x0, 0x3, 0xb0, 0x0, 0xb0, - 0x0, 0x7, 0x0, 0x0, 0x59, 0x70, 0x3, 0x0, - 0xb, 0x60, 0x0, 0x9, 0x36, 0x90, 0x92, 0x0, - 0xe1, 0x0, 0x0, 0xb0, 0xc, 0x6, 0x90, 0x29, - 0x0, 0x0, 0x64, 0x0, 0x0, 0x24, 0x6, 0x10, - 0x40, 0x27, 0x0, 0x6, 0x76, 0x66, 0x86, 0x6a, - 0x42, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - - /* U+77F3 "石" */ - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x1, 0x0, - 0x4, 0x66, 0x66, 0x66, 0x66, 0x66, 0x6d, 0xb0, - 0x1, 0x0, 0x0, 0x6a, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x0, 0xd2, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x5, 0xa0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, 0xd, 0x10, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x9c, 0x66, 0x66, 0x66, 0xc2, 0x0, - 0x0, 0x5, 0x9e, 0x0, 0x0, 0x0, 0xe0, 0x0, - 0x0, 0x2a, 0xe, 0x0, 0x0, 0x0, 0xe0, 0x0, - 0x2, 0x80, 0xe, 0x0, 0x0, 0x0, 0xe0, 0x0, - 0x15, 0x0, 0xe, 0x0, 0x0, 0x0, 0xe0, 0x0, - 0x0, 0x0, 0xe, 0x0, 0x0, 0x0, 0xe0, 0x0, - 0x0, 0x0, 0xe, 0x66, 0x66, 0x66, 0xe0, 0x0, - 0x0, 0x0, 0xe, 0x0, 0x0, 0x0, 0xc0, 0x0, - 0x0, 0x0, 0x2, 0x0, 0x0, 0x0, 0x0, 0x0, - - /* U+7802 "砂" */ - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x0, 0x0, 0x0, 0xd1, 0x0, 0x0, - 0x16, 0x66, 0x69, 0xa0, 0x0, 0xd0, 0x0, 0x0, - 0x2, 0x2d, 0x0, 0x0, 0x0, 0xd0, 0x0, 0x0, - 0x0, 0x58, 0x0, 0x5, 0xb0, 0xd0, 0x61, 0x0, - 0x0, 0x93, 0x0, 0x8, 0x60, 0xd0, 0x1d, 0x40, - 0x0, 0xd0, 0x4, 0xb, 0x0, 0xd0, 0x5, 0xd0, - 0x4, 0xf6, 0x6e, 0x38, 0x0, 0xe0, 0x0, 0x50, - 0x9, 0xd0, 0xd, 0x61, 0x0, 0xe0, 0x24, 0x0, - 0x34, 0xc0, 0xd, 0x40, 0x0, 0xe0, 0xbb, 0x0, - 0x10, 0xc0, 0xd, 0x0, 0x0, 0x37, 0xc0, 0x0, - 0x0, 0xc0, 0xd, 0x0, 0x0, 0x5b, 0x0, 0x0, - 0x0, 0xc6, 0x6d, 0x0, 0x6, 0xa0, 0x0, 0x0, - 0x0, 0xd0, 0x7, 0x2, 0xa6, 0x0, 0x0, 0x0, - 0x0, 0x30, 0x3, 0x66, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x11, 0x0, 0x0, 0x0, 0x0, 0x0, - - /* U+7814 "研" */ - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x3, 0x50, - 0x4, 0x66, 0x6a, 0xa6, 0x7e, 0x66, 0xe6, 0x50, - 0x1, 0x1b, 0x20, 0x0, 0xd, 0x0, 0xd0, 0x0, - 0x0, 0xc, 0x0, 0x0, 0xd, 0x0, 0xd0, 0x0, - 0x0, 0x29, 0x0, 0x0, 0xd, 0x0, 0xd0, 0x0, - 0x0, 0x7b, 0x6b, 0x50, 0xd, 0x0, 0xd0, 0x10, - 0x0, 0xda, 0xb, 0x37, 0x6e, 0x66, 0xe6, 0xd2, - 0x4, 0x7a, 0xb, 0x20, 0x1c, 0x0, 0xd0, 0x0, - 0x6, 0x2a, 0xb, 0x20, 0x2a, 0x0, 0xd0, 0x0, - 0x0, 0x2a, 0xb, 0x20, 0x57, 0x0, 0xd0, 0x0, - 0x0, 0x2c, 0x6c, 0x20, 0xb2, 0x0, 0xd0, 0x0, - 0x0, 0x3a, 0x9, 0x13, 0x90, 0x0, 0xd0, 0x0, - 0x0, 0x24, 0x0, 0x1a, 0x0, 0x0, 0xe0, 0x0, - 0x0, 0x0, 0x3, 0x70, 0x0, 0x0, 0xe0, 0x0, - 0x0, 0x0, 0x2, 0x0, 0x0, 0x0, 0x10, 0x0, - - /* U+7834 "破" */ - 0x0, 0x0, 0x0, 0x0, 0x0, 0xb2, 0x0, 0x0, - 0x1, 0x11, 0x17, 0x20, 0x0, 0xd0, 0x0, 0x0, - 0x7, 0x5e, 0x75, 0x29, 0x66, 0xe6, 0x6b, 0x50, - 0x0, 0xe, 0x0, 0xc, 0x0, 0xd0, 0xb, 0x20, - 0x0, 0x58, 0x0, 0xc, 0x0, 0xd0, 0x11, 0x0, - 0x0, 0xa2, 0x5, 0xc, 0x0, 0xd0, 0x0, 0x0, - 0x1, 0xf6, 0x6e, 0xc, 0x66, 0xe6, 0x97, 0x0, - 0x8, 0xe0, 0xd, 0xd, 0x5, 0x0, 0xa3, 0x0, - 0x26, 0xc0, 0xd, 0xd, 0x7, 0x0, 0xc0, 0x0, - 0x20, 0xc0, 0xd, 0x1c, 0x4, 0x45, 0x70, 0x0, - 0x0, 0xc0, 0xd, 0x48, 0x0, 0xbc, 0x10, 0x0, - 0x0, 0xc6, 0x6d, 0x82, 0x0, 0xac, 0x10, 0x0, - 0x0, 0xd0, 0x7, 0x70, 0x9, 0x54, 0xd6, 0x10, - 0x0, 0x70, 0x6, 0x16, 0x71, 0x0, 0x2c, 0xa0, - 0x0, 0x0, 0x10, 0x10, 0x0, 0x0, 0x0, 0x0, - - /* U+78BA "確" */ - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x2, 0x0, 0x0, 0xa5, 0x0, 0x0, - 0x18, 0x79, 0x6a, 0x32, 0x0, 0xd1, 0x0, 0x40, - 0x0, 0x49, 0x0, 0x9, 0x68, 0xb6, 0x68, 0xc1, - 0x0, 0x65, 0x0, 0x2a, 0xa, 0x44, 0x4, 0x0, - 0x0, 0xa2, 0x2, 0x0, 0x2a, 0xb, 0x30, 0x0, - 0x0, 0xe5, 0x5e, 0x10, 0xc7, 0x6a, 0x78, 0x90, - 0x3, 0xf0, 0xc, 0x7, 0xc0, 0xd, 0x0, 0x0, - 0x8, 0xd0, 0xc, 0x56, 0xc0, 0xd, 0x4, 0x0, - 0x15, 0xc0, 0xc, 0x20, 0xd6, 0x6e, 0x66, 0x20, - 0x10, 0xc0, 0xc, 0x0, 0xc0, 0xd, 0x1, 0x0, - 0x0, 0xc6, 0x6c, 0x0, 0xd6, 0x6e, 0x6a, 0x20, - 0x0, 0xc0, 0x9, 0x0, 0xc0, 0xd, 0x0, 0x0, - 0x0, 0xa0, 0x0, 0x0, 0xc0, 0xd, 0x1, 0x50, - 0x0, 0x0, 0x0, 0x1, 0xd6, 0x66, 0x66, 0x50, - 0x0, 0x0, 0x0, 0x0, 0x40, 0x0, 0x0, 0x0, - - /* U+793A "示" */ - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x50, 0x0, - 0x0, 0x6, 0x66, 0x66, 0x66, 0x66, 0xa6, 0x0, - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x40, - 0x6, 0x76, 0x66, 0x66, 0x86, 0x66, 0x68, 0xb2, - 0x0, 0x0, 0x0, 0x3, 0xb0, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x59, 0x3, 0xb0, 0x30, 0x0, 0x0, - 0x0, 0x0, 0xc7, 0x3, 0xb0, 0x19, 0x10, 0x0, - 0x0, 0x6, 0xb0, 0x3, 0xb0, 0x2, 0xd3, 0x0, - 0x0, 0x2c, 0x0, 0x3, 0xb0, 0x0, 0x4f, 0x20, - 0x0, 0xa1, 0x0, 0x3, 0xb0, 0x0, 0xb, 0x90, - 0x7, 0x10, 0x4, 0x37, 0xb0, 0x0, 0x2, 0x30, - 0x0, 0x0, 0x1, 0xaf, 0x70, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x0, 0x4, 0x0, 0x0, 0x0, 0x0, - - /* U+793C "礼" */ - 0x0, 0x3, 0x30, 0x0, 0x2a, 0x0, 0x0, 0x0, - 0x0, 0xd, 0x30, 0x2, 0xb0, 0x0, 0x0, 0x0, - 0x0, 0x75, 0x0, 0x2b, 0x0, 0x0, 0x0, 0x36, - 0x66, 0x6b, 0x12, 0xb0, 0x0, 0x0, 0x0, 0x10, - 0x8, 0xa0, 0x2b, 0x0, 0x0, 0x0, 0x0, 0x2, - 0xc0, 0x2, 0xb0, 0x0, 0x0, 0x0, 0x0, 0xd3, - 0x0, 0x2b, 0x0, 0x0, 0x0, 0x0, 0xae, 0x97, - 0x2, 0xb0, 0x0, 0x0, 0x0, 0x92, 0xc1, 0xb5, - 0x2b, 0x0, 0x0, 0x1, 0x61, 0xc, 0x12, 0x22, - 0xb0, 0x0, 0x0, 0x0, 0x0, 0xc1, 0x0, 0x2b, - 0x0, 0x4, 0x0, 0x0, 0xd, 0x10, 0x2, 0xb0, - 0x0, 0x51, 0x0, 0x0, 0xd1, 0x0, 0x1c, 0x0, - 0x8, 0x60, 0x0, 0xd, 0x10, 0x0, 0xad, 0xdd, - 0xd6, 0x0, 0x0, 0x20, 0x0, 0x0, 0x0, 0x0, - 0x0, - - /* U+793E "社" */ - 0x0, 0x6, 0x20, 0x0, 0x0, 0x71, 0x0, 0x0, - 0x0, 0x1, 0xe1, 0x0, 0x0, 0xe1, 0x0, 0x0, - 0x0, 0x0, 0x71, 0x0, 0x0, 0xe0, 0x0, 0x0, - 0x4, 0x66, 0x6a, 0x90, 0x0, 0xe0, 0x0, 0x0, - 0x0, 0x0, 0xe, 0x30, 0x0, 0xe0, 0x0, 0x0, - 0x0, 0x0, 0x78, 0x0, 0x0, 0xe0, 0x8, 0x20, - 0x0, 0x2, 0xe1, 0x7, 0x66, 0xe6, 0x66, 0x40, - 0x0, 0xc, 0xdb, 0x60, 0x0, 0xe0, 0x0, 0x0, - 0x0, 0x85, 0xc1, 0xd0, 0x0, 0xe0, 0x0, 0x0, - 0x5, 0x31, 0xc0, 0x10, 0x0, 0xe0, 0x0, 0x0, - 0x1, 0x1, 0xc0, 0x0, 0x0, 0xe0, 0x0, 0x0, - 0x0, 0x1, 0xc0, 0x0, 0x0, 0xe0, 0x0, 0x0, - 0x0, 0x1, 0xc0, 0x56, 0x66, 0xe6, 0x67, 0xe2, - 0x0, 0x2, 0xd0, 0x10, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x1, 0x30, 0x0, 0x0, 0x0, 0x0, 0x0, - - /* U+7956 "祖" */ - 0x0, 0x26, 0x0, 0x0, 0x0, 0x0, 0x10, 0x0, - 0x0, 0xa, 0x80, 0xc, 0x66, 0x66, 0xe3, 0x0, - 0x0, 0x3, 0x50, 0xd, 0x10, 0x0, 0xe0, 0x0, - 0x7, 0x66, 0x9a, 0xd, 0x10, 0x0, 0xe0, 0x0, - 0x0, 0x0, 0xd2, 0xd, 0x10, 0x0, 0xe0, 0x0, - 0x0, 0x7, 0x80, 0xd, 0x66, 0x66, 0xe0, 0x0, - 0x0, 0x1e, 0x50, 0xc, 0x10, 0x0, 0xe0, 0x0, - 0x0, 0x9e, 0x6b, 0xc, 0x10, 0x0, 0xe0, 0x0, - 0x5, 0x4d, 0xc, 0x1c, 0x10, 0x0, 0xe0, 0x0, - 0x23, 0xd, 0x0, 0xc, 0x66, 0x66, 0xe0, 0x0, - 0x0, 0xd, 0x0, 0xc, 0x10, 0x0, 0xe0, 0x0, - 0x0, 0xd, 0x0, 0xc, 0x10, 0x0, 0xe0, 0x0, - 0x0, 0xd, 0x0, 0xc, 0x10, 0x0, 0xe2, 0x60, - 0x0, 0xd, 0x7, 0x66, 0x66, 0x66, 0x66, 0x60, - 0x0, 0x4, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - - /* U+795D "祝" */ - 0x0, 0x26, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0xb, 0x70, 0x9, 0x66, 0x66, 0x96, 0x0, - 0x0, 0x4, 0x50, 0xd, 0x0, 0x0, 0x74, 0x0, - 0x7, 0x66, 0x7d, 0x1d, 0x0, 0x0, 0x74, 0x0, - 0x0, 0x0, 0x96, 0xd, 0x0, 0x0, 0x74, 0x0, - 0x0, 0x2, 0xb0, 0xd, 0x0, 0x0, 0x74, 0x0, - 0x0, 0xc, 0x50, 0xe, 0x67, 0x68, 0xa5, 0x0, - 0x0, 0x7e, 0x89, 0x5, 0x48, 0x2b, 0x31, 0x0, - 0x4, 0x6b, 0x1d, 0x10, 0x48, 0x2b, 0x0, 0x0, - 0x25, 0xb, 0x11, 0x0, 0x75, 0x2b, 0x0, 0x0, - 0x0, 0xb, 0x10, 0x0, 0xb1, 0x2b, 0x0, 0x30, - 0x0, 0xb, 0x10, 0x3, 0x90, 0x2b, 0x0, 0x60, - 0x0, 0xc, 0x10, 0x1a, 0x0, 0x2b, 0x1, 0x90, - 0x0, 0xc, 0x22, 0x80, 0x0, 0xd, 0xbc, 0xb0, - 0x0, 0x5, 0x23, 0x0, 0x0, 0x0, 0x0, 0x0, - - /* U+795E "神" */ - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x70, 0x0, 0x0, 0xd, 0x10, 0x0, 0x0, - 0x9, 0x70, 0x0, 0x0, 0xd0, 0x0, 0x0, 0x0, - 0x35, 0x0, 0x30, 0xd, 0x0, 0x40, 0x17, 0x66, - 0x7c, 0xd, 0x66, 0xe6, 0x6e, 0x20, 0x0, 0x9, - 0x50, 0xd0, 0xd, 0x0, 0xd0, 0x0, 0x2, 0xa0, - 0xd, 0x66, 0xe6, 0x6e, 0x0, 0x0, 0xc8, 0x10, - 0xd0, 0xd, 0x0, 0xd0, 0x0, 0x8e, 0x2e, 0x1d, - 0x0, 0xd0, 0xd, 0x0, 0x63, 0xc0, 0x61, 0xd6, - 0x6e, 0x66, 0xe0, 0x32, 0xc, 0x0, 0xc, 0x0, - 0xd0, 0x9, 0x0, 0x0, 0xc0, 0x0, 0x0, 0xd, - 0x0, 0x0, 0x0, 0xc, 0x0, 0x0, 0x0, 0xd0, - 0x0, 0x0, 0x0, 0xc0, 0x0, 0x0, 0xd, 0x0, - 0x0, 0x0, 0xd, 0x10, 0x0, 0x0, 0xe0, 0x0, - 0x0, 0x0, 0x30, 0x0, 0x0, 0x4, 0x0, 0x0, - - /* U+796D "祭" */ - 0x0, 0x0, 0x10, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, 0xc5, 0x0, 0x5, 0x0, 0x0, 0x0, - 0x0, 0x2, 0xe6, 0x69, 0x58, 0x66, 0x7e, 0x20, - 0x0, 0xa, 0x70, 0xd, 0x26, 0x0, 0x96, 0x0, - 0x0, 0x39, 0x5b, 0x4a, 0x2, 0x64, 0x50, 0x0, - 0x0, 0xa7, 0x15, 0xc2, 0x0, 0xa6, 0x0, 0x0, - 0x6, 0x4, 0xa7, 0x70, 0x0, 0x1c, 0x10, 0x0, - 0x0, 0x0, 0x5b, 0x66, 0x66, 0xc5, 0xd6, 0x0, - 0x0, 0x5, 0x70, 0x20, 0x0, 0x0, 0x3d, 0xc1, - 0x1, 0x74, 0x0, 0x0, 0x0, 0x0, 0x71, 0x0, - 0x14, 0x7, 0x66, 0x66, 0xd6, 0x66, 0x73, 0x0, - 0x0, 0x0, 0x1e, 0x50, 0xd0, 0x64, 0x0, 0x0, - 0x0, 0x0, 0xc7, 0x0, 0xd0, 0x6, 0xc3, 0x0, - 0x0, 0x1a, 0x30, 0x0, 0xd0, 0x0, 0x4e, 0x0, - 0x1, 0x60, 0x2, 0x7c, 0xb0, 0x0, 0x4, 0x0, - 0x0, 0x0, 0x0, 0x5, 0x20, 0x0, 0x0, 0x0, - - /* U+7981 "禁" */ - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0xb, 0x10, 0x0, 0xc, 0x10, 0x0, 0x0, - 0x0, 0xc0, 0x20, 0x0, 0xd0, 0x2, 0x0, 0x66, - 0x7e, 0x6a, 0x27, 0x8f, 0x66, 0xa3, 0x0, 0xc, - 0xf6, 0x10, 0xb, 0xf7, 0x0, 0x0, 0x5, 0x8c, - 0x3d, 0x5, 0x8d, 0x39, 0x0, 0x2, 0xa0, 0xc0, - 0x53, 0x80, 0xd0, 0x6d, 0x61, 0x70, 0xc, 0x11, - 0x50, 0xc, 0x0, 0x40, 0x0, 0x5, 0x66, 0x66, - 0x66, 0x6c, 0x50, 0x0, 0x0, 0x10, 0x0, 0x0, - 0x0, 0x0, 0x30, 0x27, 0x66, 0x66, 0x69, 0x66, - 0x66, 0x6a, 0x60, 0x0, 0x6, 0x40, 0xc2, 0x4, - 0x0, 0x0, 0x0, 0x4, 0xd3, 0xc, 0x20, 0x2b, - 0x40, 0x0, 0x4, 0x90, 0x0, 0xc2, 0x0, 0x1d, - 0x60, 0x3, 0x40, 0x6, 0xcf, 0x0, 0x0, 0x27, - 0x0, 0x0, 0x0, 0x4, 0x30, 0x0, 0x0, 0x0, - - /* U+79C0 "秀" */ - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x0, 0x2, 0x46, 0x9d, 0xc0, 0x0, - 0x0, 0x4, 0x56, 0x67, 0xc2, 0x10, 0x0, 0x0, - 0x0, 0x0, 0x0, 0x1, 0xb0, 0x0, 0x2, 0x30, - 0x3, 0x76, 0x66, 0x8b, 0xd8, 0x66, 0x68, 0x80, - 0x0, 0x0, 0x2, 0xd4, 0xb2, 0x50, 0x0, 0x0, - 0x0, 0x0, 0x2c, 0x21, 0xb0, 0x59, 0x0, 0x0, - 0x0, 0x5, 0xa1, 0x2, 0x80, 0x4, 0xd8, 0x30, - 0x1, 0x75, 0x66, 0x86, 0x66, 0xd2, 0x19, 0xa2, - 0x3, 0x0, 0x0, 0xe0, 0x4, 0xa0, 0x0, 0x0, - 0x0, 0x0, 0x3, 0xb0, 0xd, 0x86, 0x97, 0x0, - 0x0, 0x0, 0x9, 0x50, 0x3, 0x0, 0xa3, 0x0, - 0x0, 0x0, 0x2c, 0x0, 0x0, 0x0, 0xd0, 0x0, - 0x0, 0x1, 0xb1, 0x0, 0x2, 0x2, 0xc0, 0x0, - 0x0, 0x48, 0x10, 0x0, 0x4, 0xcf, 0x50, 0x0, - 0x2, 0x20, 0x0, 0x0, 0x0, 0x22, 0x0, 0x0, - - /* U+79C1 "私" */ - 0x0, 0x0, 0x0, 0x28, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x14, 0x7b, 0xb8, 0x20, 0x1e, 0x20, 0x0, - 0x1, 0x32, 0x1d, 0x0, 0x0, 0x4d, 0x0, 0x0, - 0x0, 0x0, 0xd, 0x0, 0x0, 0x78, 0x0, 0x0, - 0x0, 0x0, 0xd, 0x4, 0x50, 0xa3, 0x0, 0x0, - 0x4, 0x76, 0x7e, 0x66, 0x50, 0xd0, 0x0, 0x0, - 0x0, 0x0, 0x7e, 0x10, 0x2, 0x90, 0x0, 0x0, - 0x0, 0x1, 0xdd, 0xa8, 0x7, 0x40, 0x0, 0x0, - 0x0, 0x9, 0x4d, 0xd, 0x3a, 0x0, 0x60, 0x0, - 0x0, 0x56, 0xd, 0x2, 0x28, 0x0, 0x38, 0x0, - 0x3, 0x50, 0xd, 0x0, 0x62, 0x0, 0xc, 0x40, - 0x3, 0x0, 0xd, 0x0, 0xa0, 0x1, 0x29, 0xd0, - 0x0, 0x0, 0x1d, 0x6, 0xfd, 0x96, 0x33, 0xf1, - 0x0, 0x0, 0x1e, 0x0, 0x40, 0x0, 0x0, 0x70, - 0x0, 0x0, 0x14, 0x0, 0x0, 0x0, 0x0, 0x0, - - /* U+79CB "秋" */ - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x3, 0x60, 0x2, 0xd1, 0x0, 0x0, - 0x0, 0x36, 0xca, 0x70, 0x2, 0xd0, 0x0, 0x0, - 0x1, 0x20, 0xe0, 0x0, 0x2, 0xc0, 0x0, 0x0, - 0x0, 0x0, 0xe0, 0x0, 0x32, 0xc0, 0xd, 0x30, - 0x5, 0x66, 0xe6, 0xd3, 0x83, 0xd0, 0x98, 0x0, - 0x1, 0x13, 0xf0, 0x3, 0xb4, 0xe5, 0x70, 0x0, - 0x0, 0x8, 0xf0, 0xa, 0x65, 0xd4, 0x0, 0x0, - 0x0, 0xc, 0xe9, 0x50, 0x7, 0x95, 0x0, 0x0, - 0x0, 0x64, 0xe1, 0xe0, 0xa, 0x49, 0x0, 0x0, - 0x0, 0x90, 0xe0, 0x30, 0xd, 0x19, 0x10, 0x0, - 0x6, 0x0, 0xe0, 0x0, 0x4a, 0x4, 0x90, 0x0, - 0x10, 0x0, 0xe0, 0x0, 0xc1, 0x0, 0xc4, 0x0, - 0x0, 0x0, 0xe0, 0x9, 0x30, 0x0, 0x3f, 0x50, - 0x0, 0x0, 0xe2, 0x82, 0x0, 0x0, 0x7, 0x91, - 0x0, 0x0, 0x22, 0x0, 0x0, 0x0, 0x0, 0x0, - - /* U+79CD "种" */ - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x2, 0x60, 0x0, 0x3b, 0x0, 0x0, - 0x1, 0x47, 0xba, 0x81, 0x0, 0x2a, 0x0, 0x0, - 0x1, 0x0, 0xd0, 0x0, 0x0, 0x2a, 0x0, 0x0, - 0x0, 0x0, 0xd0, 0x0, 0x41, 0x3a, 0x11, 0x70, - 0x6, 0x66, 0xe6, 0xd3, 0xe5, 0x6c, 0x56, 0xc0, - 0x0, 0x2, 0xd0, 0x0, 0xd0, 0x2a, 0x2, 0xa0, - 0x0, 0x7, 0xe6, 0x0, 0xd0, 0x2a, 0x2, 0xa0, - 0x0, 0xc, 0xd5, 0xd0, 0xd0, 0x2a, 0x2, 0xa0, - 0x0, 0x65, 0xd0, 0x80, 0xe6, 0x7c, 0x67, 0xb0, - 0x1, 0x90, 0xd0, 0x0, 0x80, 0x2a, 0x1, 0x30, - 0x7, 0x0, 0xd0, 0x0, 0x0, 0x2a, 0x0, 0x0, - 0x10, 0x0, 0xd0, 0x0, 0x0, 0x2a, 0x0, 0x0, - 0x0, 0x0, 0xd0, 0x0, 0x0, 0x2a, 0x0, 0x0, - 0x0, 0x0, 0xe0, 0x0, 0x0, 0x3b, 0x0, 0x0, - 0x0, 0x0, 0x50, 0x0, 0x0, 0x13, 0x0, 0x0, - - /* U+79D1 "科" */ - 0x0, 0x0, 0x1, 0x70, 0x0, 0x0, 0xc2, 0x0, - 0x0, 0x36, 0xbb, 0x81, 0x0, 0x0, 0xd0, 0x0, - 0x2, 0x20, 0xd0, 0x0, 0x56, 0x0, 0xd0, 0x0, - 0x0, 0x0, 0xd0, 0x0, 0xb, 0x50, 0xd0, 0x0, - 0x0, 0x0, 0xd0, 0x53, 0x2, 0x10, 0xd0, 0x0, - 0x7, 0x66, 0xf6, 0x64, 0x0, 0x0, 0xd0, 0x0, - 0x0, 0x4, 0xf1, 0x0, 0x57, 0x0, 0xd0, 0x0, - 0x0, 0xb, 0xe8, 0x80, 0xd, 0x10, 0xd0, 0x0, - 0x0, 0x48, 0xd0, 0xd1, 0x2, 0x0, 0xd4, 0xd1, - 0x0, 0xa0, 0xd0, 0x10, 0x35, 0x66, 0xd3, 0x0, - 0x7, 0x10, 0xd0, 0x26, 0x30, 0x0, 0xd0, 0x0, - 0x11, 0x0, 0xd0, 0x0, 0x0, 0x0, 0xd0, 0x0, - 0x0, 0x0, 0xd0, 0x0, 0x0, 0x0, 0xd0, 0x0, - 0x0, 0x0, 0xd0, 0x0, 0x0, 0x0, 0xe0, 0x0, - 0x0, 0x0, 0x60, 0x0, 0x0, 0x0, 0x80, 0x0, - - /* U+79D8 "秘" */ - 0x0, 0x0, 0x3, 0x40, 0x2, 0x0, 0x0, 0x0, - 0x0, 0x37, 0xbb, 0x80, 0x5, 0x90, 0x19, 0x0, - 0x3, 0x20, 0xc0, 0x0, 0x0, 0xd2, 0x4d, 0x0, - 0x0, 0x0, 0xc0, 0x0, 0x18, 0x40, 0x78, 0x0, - 0x0, 0x0, 0xc0, 0x70, 0x1d, 0x0, 0xb4, 0x0, - 0x6, 0x68, 0xd6, 0x62, 0xc, 0x0, 0xf0, 0x0, - 0x0, 0x9, 0xd5, 0x2, 0xc, 0x4, 0xb6, 0x0, - 0x0, 0xc, 0xc8, 0x88, 0xc, 0xb, 0x56, 0x80, - 0x0, 0x74, 0xc0, 0x5d, 0x1c, 0x2d, 0x1, 0xf1, - 0x1, 0x80, 0xc0, 0x5c, 0xc, 0xc4, 0x0, 0x90, - 0x6, 0x0, 0xc0, 0x0, 0xf, 0xa0, 0x4, 0x0, - 0x0, 0x0, 0xc0, 0x0, 0x6d, 0x0, 0x7, 0x0, - 0x0, 0x0, 0xc0, 0x7, 0x7d, 0x0, 0xc, 0x20, - 0x0, 0x1, 0xd2, 0x62, 0xb, 0xcc, 0xcc, 0x20, - 0x0, 0x1, 0x60, 0x0, 0x0, 0x0, 0x0, 0x0, - - /* U+79FB "移" */ - 0x0, 0x0, 0x3, 0x30, 0x0, 0x90, 0x0, 0x0, - 0x0, 0x37, 0xbb, 0x70, 0x7, 0x80, 0x1, 0x0, - 0x2, 0x31, 0xd0, 0x0, 0x2b, 0x66, 0x6e, 0x50, - 0x0, 0x0, 0xd0, 0x0, 0x88, 0x30, 0x79, 0x0, - 0x0, 0x0, 0xd0, 0x74, 0x2, 0xa6, 0xa0, 0x0, - 0x7, 0x67, 0xe6, 0x62, 0x0, 0x79, 0x0, 0x0, - 0x0, 0x7, 0xe0, 0x0, 0x18, 0x59, 0x10, 0x0, - 0x0, 0xc, 0xea, 0x54, 0x60, 0x8b, 0x10, 0x10, - 0x0, 0x47, 0xd1, 0xc0, 0x6, 0xc6, 0x67, 0xe1, - 0x0, 0xa0, 0xd0, 0x10, 0x6a, 0x0, 0xb, 0x50, - 0x5, 0x20, 0xd0, 0x6, 0x35, 0x80, 0x88, 0x0, - 0x3, 0x0, 0xe0, 0x10, 0x0, 0x88, 0x90, 0x0, - 0x0, 0x0, 0xe0, 0x0, 0x3, 0xa6, 0x0, 0x0, - 0x0, 0x0, 0xe0, 0x5, 0x87, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x32, 0x31, 0x0, 0x0, 0x0, 0x0, - - /* U+7A0B "程" */ - 0x0, 0x0, 0x17, 0x70, 0x30, 0x0, 0x3, 0x0, - 0x3, 0x58, 0xd6, 0x40, 0xe6, 0x66, 0x6e, 0x30, - 0x0, 0x1, 0xb0, 0x0, 0xd0, 0x0, 0xd, 0x0, - 0x0, 0x1, 0xb0, 0x0, 0xd0, 0x0, 0xd, 0x0, - 0x5, 0x66, 0xd6, 0xc1, 0xe6, 0x66, 0x6e, 0x0, - 0x2, 0x6, 0xb0, 0x0, 0xc0, 0x0, 0x8, 0x0, - 0x0, 0xa, 0xd5, 0x0, 0x0, 0x0, 0x4, 0x30, - 0x0, 0xd, 0xb7, 0x94, 0x76, 0x7c, 0x66, 0x40, - 0x0, 0x57, 0xb0, 0x80, 0x0, 0x3a, 0x0, 0x0, - 0x0, 0xa1, 0xb0, 0x0, 0x0, 0x3a, 0x5, 0x0, - 0x4, 0x31, 0xb0, 0x1, 0x86, 0x7c, 0x66, 0x30, - 0x5, 0x1, 0xb0, 0x0, 0x0, 0x3a, 0x0, 0x0, - 0x0, 0x1, 0xb0, 0x0, 0x0, 0x3a, 0x0, 0x30, - 0x0, 0x2, 0xc0, 0x47, 0x66, 0x68, 0x67, 0x91, - 0x0, 0x1, 0x30, 0x0, 0x0, 0x0, 0x0, 0x0, - - /* U+7A2E "種" */ - 0x0, 0x0, 0x2, 0x0, 0x0, 0x25, 0xa4, 0x0, - 0x1, 0x48, 0xba, 0x14, 0x56, 0xe5, 0x31, 0x0, - 0x3, 0x1b, 0x10, 0x0, 0x0, 0xd0, 0x3, 0x40, - 0x0, 0xb, 0x10, 0x57, 0x66, 0xe6, 0x66, 0x50, - 0x4, 0x5c, 0x6c, 0x23, 0x0, 0xd0, 0x3, 0x0, - 0x2, 0x2f, 0x21, 0xd, 0x66, 0xe6, 0x6e, 0x0, - 0x0, 0x4f, 0x81, 0xc, 0x0, 0xd0, 0x1c, 0x0, - 0x0, 0xae, 0x3b, 0xd, 0x66, 0xe6, 0x6c, 0x0, - 0x1, 0x9b, 0x18, 0xc, 0x0, 0xd0, 0x1c, 0x0, - 0x8, 0x1b, 0x10, 0xc, 0x66, 0xe6, 0x6a, 0x0, - 0x23, 0xb, 0x10, 0x0, 0x0, 0xd0, 0x4, 0x0, - 0x0, 0xb, 0x10, 0x28, 0x66, 0xe6, 0x69, 0x30, - 0x0, 0xb, 0x10, 0x0, 0x0, 0xd0, 0x0, 0x0, - 0x0, 0xc, 0x21, 0x66, 0x66, 0xe6, 0x6a, 0xc0, - 0x0, 0x4, 0x0, 0x20, 0x0, 0x0, 0x0, 0x0, - - /* U+7A4D "積" */ - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x45, 0x0, 0x0, 0xc1, 0x0, 0x0, - 0x3, 0x6c, 0x96, 0x26, 0x66, 0xe6, 0x6b, 0x50, - 0x0, 0xc, 0x0, 0x2, 0x0, 0xd0, 0x2, 0x0, - 0x0, 0xc, 0x2, 0x3, 0x76, 0xe6, 0x67, 0x0, - 0x18, 0x6e, 0x7a, 0x10, 0x0, 0xd0, 0x3, 0x60, - 0x0, 0x2f, 0x30, 0x57, 0x66, 0x66, 0x67, 0x50, - 0x0, 0x8f, 0x66, 0xb, 0x66, 0x66, 0x6e, 0x10, - 0x0, 0xbc, 0xc, 0xc, 0x0, 0x0, 0xd, 0x0, - 0x4, 0x5c, 0x0, 0xc, 0x66, 0x66, 0x6d, 0x0, - 0x8, 0xc, 0x0, 0xc, 0x66, 0x66, 0x6d, 0x0, - 0x31, 0xc, 0x0, 0xc, 0x0, 0x0, 0xd, 0x0, - 0x0, 0xc, 0x0, 0xc, 0x76, 0x66, 0x6d, 0x0, - 0x0, 0xd, 0x0, 0x2, 0xc7, 0x1, 0x66, 0x0, - 0x0, 0xc, 0x0, 0x58, 0x20, 0x0, 0x6, 0xb0, - 0x0, 0x1, 0x3, 0x10, 0x0, 0x0, 0x0, 0x50, - - /* U+7A76 "究" */ - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, 0xa, 0x30, 0x0, 0x0, 0x0, 0x0, - 0x20, 0x0, 0x4b, 0x0, 0x0, 0x30, 0x0, 0x39, - 0x67, 0x66, 0x76, 0x66, 0x7e, 0x10, 0xc, 0x31, - 0xd4, 0x0, 0x65, 0x7, 0x20, 0x0, 0x33, 0xb3, - 0x63, 0x0, 0x5e, 0x70, 0x0, 0x5, 0x50, 0xb, - 0x30, 0x0, 0x2c, 0x0, 0x0, 0x6, 0x77, 0xe7, - 0x77, 0xc0, 0x0, 0x0, 0x0, 0x10, 0xd, 0x0, - 0x2b, 0x0, 0x0, 0x0, 0x0, 0x3, 0xa0, 0x2, - 0xb0, 0x0, 0x0, 0x0, 0x0, 0x76, 0x0, 0x3a, - 0x0, 0x0, 0x0, 0x0, 0xd, 0x0, 0x3, 0xa0, - 0x0, 0x20, 0x0, 0x8, 0x70, 0x0, 0x3a, 0x0, - 0x15, 0x0, 0x5, 0xa0, 0x0, 0x3, 0xa0, 0x3, - 0xb0, 0x5, 0x70, 0x0, 0x0, 0xc, 0xcc, 0xd8, - 0x3, 0x20, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - - /* U+7A7A "空" */ - 0x0, 0x0, 0x0, 0x29, 0x10, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x0, 0x6a, 0x0, 0x0, 0x0, 0x0, - 0x76, 0x66, 0x66, 0x96, 0x66, 0x6a, 0x20, 0x2b, - 0x0, 0x41, 0x0, 0x0, 0x1, 0xc4, 0xa, 0x70, - 0x2e, 0x60, 0x4, 0x95, 0x41, 0x0, 0x0, 0x3c, - 0x30, 0x0, 0x0, 0x9e, 0x40, 0x0, 0x67, 0x0, - 0x0, 0x0, 0x0, 0x7c, 0x0, 0x41, 0x56, 0x66, - 0x66, 0x66, 0xd4, 0x10, 0x0, 0x1, 0x10, 0xb, - 0x30, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xb3, - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xb, 0x30, - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xb3, 0x0, - 0x0, 0x0, 0x0, 0x0, 0x0, 0xb, 0x30, 0x0, - 0x2, 0x0, 0x56, 0x66, 0x66, 0xd8, 0x66, 0x67, - 0xf4, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, - - /* U+7A93 "窓" */ - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x6, 0x70, 0x0, 0x0, 0x0, 0x0, - 0x10, 0x0, 0xe, 0x40, 0x0, 0x1, 0x0, 0x38, - 0x66, 0x66, 0x86, 0x66, 0x69, 0xd0, 0xd, 0x20, - 0x4c, 0x0, 0x47, 0x40, 0x81, 0x2, 0x51, 0x89, - 0x26, 0x70, 0x18, 0xe2, 0x0, 0x3, 0x50, 0x3, - 0xd5, 0x2, 0x4, 0x30, 0x0, 0x0, 0x4, 0xa1, - 0x0, 0x66, 0x0, 0x0, 0x0, 0xb, 0xb7, 0x77, - 0x66, 0xe4, 0x0, 0x0, 0x0, 0x88, 0x53, 0x10, - 0x6, 0x80, 0x0, 0x0, 0x2, 0x50, 0x84, 0x0, - 0x1, 0x0, 0x0, 0x5, 0x2d, 0x0, 0xe3, 0x2, - 0x46, 0x0, 0x3, 0x72, 0xb0, 0x4, 0x0, 0x60, - 0xa7, 0x4, 0xe2, 0x2c, 0x0, 0x0, 0x8, 0x43, - 0x90, 0x1, 0x0, 0xdd, 0xdd, 0xdd, 0xe6, 0x0, - 0x0, - - /* U+7ACB "立" */ - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x0, 0x48, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x0, 0xb, 0x80, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x0, 0x4, 0x60, 0x0, 0x15, 0x0, - 0x1, 0x86, 0x66, 0x66, 0x66, 0x66, 0x89, 0x20, - 0x0, 0x0, 0x0, 0x0, 0x0, 0x42, 0x0, 0x0, - 0x0, 0x0, 0x60, 0x0, 0x0, 0x9c, 0x0, 0x0, - 0x0, 0x0, 0x37, 0x0, 0x0, 0xc4, 0x0, 0x0, - 0x0, 0x0, 0xd, 0x10, 0x0, 0xd0, 0x0, 0x0, - 0x0, 0x0, 0x9, 0x80, 0x3, 0x90, 0x0, 0x0, - 0x0, 0x0, 0x6, 0xc0, 0x8, 0x30, 0x0, 0x0, - 0x0, 0x0, 0x4, 0xa0, 0x9, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x0, 0x0, 0x26, 0x0, 0x0, 0x10, - 0x16, 0x66, 0x66, 0x66, 0x96, 0x66, 0x6b, 0xd1, - 0x2, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - - /* U+7AD9 "站" */ - 0x0, 0x2, 0x0, 0x0, 0x0, 0x82, 0x0, 0x0, - 0x0, 0xa, 0x30, 0x0, 0x0, 0xd0, 0x0, 0x0, - 0x0, 0x6, 0xa0, 0x0, 0x0, 0xd0, 0x0, 0x0, - 0x0, 0x1, 0x40, 0x44, 0x0, 0xd1, 0x13, 0x80, - 0x6, 0x66, 0x66, 0x77, 0x0, 0xd5, 0x55, 0x50, - 0x0, 0x10, 0x8, 0x50, 0x0, 0xd0, 0x0, 0x0, - 0x0, 0x70, 0xc, 0x30, 0x0, 0xd0, 0x0, 0x0, - 0x0, 0x74, 0xd, 0x0, 0x96, 0xe6, 0x6c, 0x30, - 0x0, 0x5a, 0x19, 0x0, 0xd0, 0x0, 0xd, 0x0, - 0x0, 0x3b, 0x43, 0x0, 0xd0, 0x0, 0xd, 0x0, - 0x0, 0x2, 0x60, 0x33, 0xd0, 0x0, 0xd, 0x0, - 0x1, 0x48, 0xb7, 0x20, 0xd0, 0x0, 0xd, 0x0, - 0xa, 0xa3, 0x0, 0x0, 0xe6, 0x66, 0x6e, 0x0, - 0x0, 0x0, 0x0, 0x0, 0xd0, 0x0, 0xb, 0x0, - 0x0, 0x0, 0x0, 0x0, 0x20, 0x0, 0x0, 0x0, - - /* U+7AE5 "童" */ - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x0, 0x2, 0xb0, 0x0, 0x0, 0x0, - 0x0, 0x5, 0x66, 0x66, 0xd6, 0x66, 0xc6, 0x0, - 0x0, 0x2, 0x6, 0x60, 0x0, 0xc3, 0x0, 0x0, - 0x0, 0x0, 0x0, 0xd0, 0x4, 0x40, 0x4, 0x0, - 0x2, 0x76, 0x55, 0x65, 0x57, 0x55, 0x59, 0x50, - 0x0, 0x1, 0x86, 0x66, 0x66, 0x66, 0xa1, 0x0, - 0x0, 0x1, 0xb0, 0x0, 0xd0, 0x0, 0xd0, 0x0, - 0x0, 0x1, 0xd6, 0x66, 0xe6, 0x66, 0xe0, 0x0, - 0x0, 0x1, 0xb0, 0x0, 0xd0, 0x0, 0xd0, 0x0, - 0x0, 0x1, 0xd6, 0x66, 0xe6, 0x66, 0xe0, 0x0, - 0x0, 0x1, 0x30, 0x0, 0xd0, 0x0, 0x33, 0x0, - 0x0, 0x18, 0x66, 0x66, 0xe6, 0x66, 0x7a, 0x20, - 0x0, 0x0, 0x0, 0x0, 0xd0, 0x0, 0x0, 0x40, - 0x6, 0x76, 0x66, 0x66, 0xa6, 0x66, 0x66, 0xa5, - - /* U+7AEF "端" */ - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x41, 0x0, 0x2, 0x0, 0xb1, 0x0, 0x0, - 0x0, 0x1c, 0x0, 0xd, 0x10, 0xb0, 0xc, 0x20, - 0x0, 0x9, 0x0, 0xc, 0x0, 0xb0, 0xc, 0x0, - 0x5, 0x66, 0x6c, 0x2d, 0x66, 0xd6, 0x6d, 0x0, - 0x0, 0x0, 0x33, 0x4, 0x0, 0x0, 0x5, 0x0, - 0x1, 0x40, 0x78, 0x56, 0x66, 0x66, 0x66, 0xb1, - 0x0, 0x90, 0x92, 0x11, 0x6, 0x60, 0x0, 0x0, - 0x0, 0xb1, 0xa0, 0x12, 0x7, 0x0, 0x1, 0x40, - 0x0, 0xa1, 0x80, 0x2d, 0x6d, 0x6d, 0x6a, 0x90, - 0x0, 0x12, 0x41, 0x4b, 0xc, 0xc, 0x7, 0x60, - 0x0, 0x3a, 0x84, 0x1b, 0xc, 0xc, 0x7, 0x60, - 0xc, 0xa2, 0x0, 0x1b, 0xc, 0xc, 0x7, 0x60, - 0x0, 0x0, 0x0, 0x1b, 0xc, 0xb, 0x7, 0x60, - 0x0, 0x0, 0x0, 0x2b, 0x5, 0x2, 0x7d, 0x50, - 0x0, 0x0, 0x0, 0x12, 0x0, 0x0, 0x6, 0x0, - - /* U+7B11 "笑" */ - 0x0, 0x2, 0xa0, 0x0, 0x0, 0x91, 0x0, 0x0, - 0x0, 0x8, 0x80, 0x4, 0x5, 0xc0, 0x3, 0x10, - 0x0, 0x1d, 0x77, 0x69, 0x4c, 0x78, 0x69, 0x80, - 0x0, 0x93, 0xc, 0x10, 0x65, 0x5, 0xa0, 0x0, - 0x5, 0x40, 0x9, 0x32, 0x50, 0x1, 0xa0, 0x0, - 0x2, 0x0, 0x0, 0x14, 0x68, 0xcf, 0x50, 0x0, - 0x0, 0x4, 0x56, 0x6d, 0x62, 0x11, 0x0, 0x0, - 0x0, 0x0, 0x0, 0xd, 0x10, 0x0, 0x0, 0x0, - 0x5, 0x66, 0x66, 0x6e, 0x66, 0x66, 0x6e, 0x50, - 0x1, 0x0, 0x0, 0x3a, 0x41, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x0, 0xa4, 0x9, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x6, 0x90, 0x3, 0xb1, 0x0, 0x0, - 0x0, 0x0, 0x87, 0x0, 0x0, 0x3d, 0x82, 0x0, - 0x1, 0x57, 0x10, 0x0, 0x0, 0x1, 0xaf, 0x80, - 0x2, 0x0, 0x0, 0x0, 0x0, 0x0, 0x1, 0x0, - - /* U+7B26 "符" */ - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x1, 0xc1, 0x0, 0x0, 0x96, 0x0, 0x0, - 0x0, 0x8, 0x90, 0x2, 0x20, 0xd1, 0x0, 0x50, - 0x0, 0x1c, 0x69, 0x76, 0x57, 0x86, 0xb6, 0x72, - 0x0, 0x92, 0x1, 0xc0, 0x28, 0x0, 0x95, 0x0, - 0x5, 0x20, 0x7, 0x30, 0x70, 0x1, 0x31, 0x0, - 0x0, 0x0, 0x5c, 0x20, 0x0, 0x3, 0xc0, 0x0, - 0x0, 0x1, 0xd2, 0x56, 0x66, 0x67, 0xc6, 0xc5, - 0x0, 0xb, 0xc0, 0x11, 0x0, 0x3, 0xa0, 0x0, - 0x0, 0x76, 0xa0, 0x8, 0x10, 0x3, 0xa0, 0x0, - 0x6, 0x22, 0xa0, 0x3, 0xd0, 0x3, 0xa0, 0x0, - 0x0, 0x2, 0xa0, 0x0, 0xc0, 0x3, 0xa0, 0x0, - 0x0, 0x2, 0xa0, 0x0, 0x0, 0x3, 0xa0, 0x0, - 0x0, 0x2, 0xa0, 0x0, 0x0, 0x3, 0x90, 0x0, - 0x0, 0x2, 0xb0, 0x0, 0x3, 0x9d, 0x80, 0x0, - 0x0, 0x1, 0x20, 0x0, 0x0, 0x5, 0x0, 0x0, - - /* U+7B2C "第" */ - 0x0, 0x1, 0xb1, 0x0, 0x3, 0x90, 0x0, 0x0, - 0x0, 0x9a, 0x0, 0x70, 0x98, 0x0, 0x53, 0x0, - 0x4b, 0x7b, 0x66, 0x6b, 0x7b, 0x66, 0x40, 0x28, - 0x0, 0xa3, 0x18, 0x0, 0xb3, 0x0, 0x2, 0x5, - 0x68, 0x67, 0x66, 0x68, 0xb2, 0x0, 0x0, 0x10, - 0x0, 0xd, 0x0, 0xd, 0x0, 0x0, 0x3, 0x20, - 0x0, 0xd0, 0x0, 0xd0, 0x0, 0x0, 0x99, 0x66, - 0x6e, 0x66, 0x6c, 0x0, 0x0, 0xd, 0x10, 0x0, - 0xd0, 0x0, 0x1, 0x0, 0x3, 0xd6, 0x66, 0xae, - 0x66, 0x66, 0xc7, 0x0, 0x1, 0x0, 0xb5, 0xd0, - 0x0, 0xc, 0x10, 0x0, 0x1, 0xa5, 0xd, 0x0, - 0x0, 0xe0, 0x0, 0x4, 0xa2, 0x0, 0xd0, 0x19, - 0xd9, 0x0, 0x47, 0x40, 0x0, 0xd, 0x0, 0x6, - 0x0, 0x1, 0x0, 0x0, 0x0, 0x60, 0x0, 0x0, - 0x0, - - /* U+7B46 "筆" */ - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x4, 0xd0, 0x0, 0x0, 0xe2, 0x0, 0x0, - 0x0, 0xa, 0x60, 0x5, 0x16, 0xa0, 0x0, 0x70, - 0x0, 0x2d, 0x6b, 0x66, 0x5c, 0x67, 0xb6, 0x72, - 0x0, 0xa2, 0x5, 0xc0, 0x74, 0x0, 0x7b, 0x0, - 0x6, 0x30, 0x0, 0xa3, 0xb0, 0x0, 0x1a, 0x0, - 0x1, 0x1, 0x86, 0x68, 0xc6, 0x66, 0xe2, 0x0, - 0x0, 0x0, 0x0, 0x3, 0xa0, 0x0, 0xe4, 0x60, - 0x0, 0x76, 0x66, 0x68, 0xc6, 0x66, 0xe6, 0x50, - 0x0, 0x1, 0x66, 0x68, 0xc6, 0x66, 0xe0, 0x0, - 0x0, 0x0, 0x20, 0x3, 0xa0, 0x0, 0x40, 0x0, - 0x0, 0x3, 0x66, 0x68, 0xc6, 0x6a, 0xa0, 0x0, - 0x0, 0x0, 0x0, 0x3, 0xa0, 0x0, 0x8, 0x30, - 0x2, 0x86, 0x66, 0x68, 0xc6, 0x66, 0x66, 0x50, - 0x0, 0x0, 0x0, 0x3, 0xa0, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x0, 0x2, 0x30, 0x0, 0x0, 0x0, - - /* U+7B49 "等" */ - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x3, 0xc1, 0x0, 0x0, 0xc4, 0x0, 0x0, - 0x0, 0xa, 0xa0, 0x6, 0x23, 0xd0, 0x0, 0x60, - 0x0, 0x2d, 0x79, 0x66, 0x4a, 0x6a, 0x76, 0x61, - 0x0, 0xa1, 0xc, 0x20, 0x44, 0x2, 0xc0, 0x0, - 0x6, 0x20, 0x7, 0x30, 0xe1, 0x0, 0x80, 0x0, - 0x0, 0x4, 0x76, 0x66, 0xe6, 0x66, 0x9a, 0x0, - 0x0, 0x0, 0x0, 0x0, 0xe0, 0x0, 0x0, 0x0, - 0x5, 0x76, 0x66, 0x66, 0xd6, 0x66, 0x66, 0xc2, - 0x0, 0x0, 0x0, 0x0, 0x0, 0xa, 0x10, 0x0, - 0x0, 0x56, 0x66, 0x66, 0x66, 0x6e, 0x67, 0xc1, - 0x0, 0x10, 0x5, 0x0, 0x0, 0xd, 0x0, 0x0, - 0x0, 0x0, 0x6, 0x90, 0x0, 0xd, 0x0, 0x0, - 0x0, 0x0, 0x0, 0xd0, 0x0, 0xd, 0x0, 0x0, - 0x0, 0x0, 0x0, 0x0, 0x18, 0xeb, 0x0, 0x0, - 0x0, 0x0, 0x0, 0x0, 0x0, 0x51, 0x0, 0x0, - - /* U+7B54 "答" */ - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x2, 0xb1, 0x0, 0x5, 0xa0, 0x0, 0x0, - 0x0, 0x8, 0xb0, 0x4, 0xa, 0x60, 0x2, 0x20, - 0x0, 0xd, 0x87, 0x67, 0x6b, 0x6a, 0x67, 0x50, - 0x0, 0x84, 0xc, 0x3, 0x61, 0x5, 0xa0, 0x0, - 0x3, 0x60, 0x8, 0x3e, 0x70, 0x0, 0xb0, 0x0, - 0x2, 0x0, 0x2, 0xd4, 0x46, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x3c, 0x20, 0x4, 0xa4, 0x0, 0x0, - 0x0, 0x7, 0x80, 0x0, 0x0, 0x89, 0xda, 0x72, - 0x3, 0x73, 0x37, 0x66, 0x66, 0x61, 0x17, 0x70, - 0x1, 0x0, 0x30, 0x0, 0x0, 0x5, 0x0, 0x0, - 0x0, 0x0, 0xe6, 0x66, 0x66, 0x6e, 0x30, 0x0, - 0x0, 0x0, 0xd0, 0x0, 0x0, 0xe, 0x0, 0x0, - 0x0, 0x0, 0xd0, 0x0, 0x0, 0xe, 0x0, 0x0, - 0x0, 0x0, 0xe6, 0x66, 0x66, 0x6e, 0x0, 0x0, - 0x0, 0x0, 0x40, 0x0, 0x0, 0x3, 0x0, 0x0, - - /* U+7B56 "策" */ - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x4a, 0x0, 0x0, 0x68, 0x0, 0x0, 0x0, - 0xb, 0x50, 0x15, 0xd, 0x40, 0x6, 0x0, 0x5, - 0xa8, 0x86, 0x5a, 0x88, 0x96, 0x61, 0x2, 0x90, - 0xc, 0x3, 0x30, 0xd, 0x10, 0x0, 0x50, 0x0, - 0x40, 0xa4, 0x0, 0x40, 0x50, 0x6, 0x76, 0x66, - 0x6c, 0x76, 0x66, 0x6a, 0x40, 0x0, 0x20, 0x0, - 0xb2, 0x0, 0x4, 0x0, 0x0, 0xd, 0x66, 0x6c, - 0x76, 0x66, 0xe0, 0x0, 0x0, 0xc0, 0x0, 0xc2, - 0x0, 0xd, 0x0, 0x0, 0xc, 0x0, 0x7f, 0x70, - 0x56, 0xc0, 0x0, 0x0, 0xa0, 0x69, 0xb3, 0x70, - 0x85, 0x0, 0x0, 0x0, 0x87, 0xb, 0x22, 0xa2, - 0x0, 0x0, 0x2, 0x93, 0x0, 0xb2, 0x1, 0xab, - 0x63, 0x6, 0x50, 0x0, 0xb, 0x20, 0x0, 0x4b, - 0x31, 0x0, 0x0, 0x0, 0x40, 0x0, 0x0, 0x0, - - /* U+7B97 "算" */ - 0x0, 0x0, 0x20, 0x0, 0x0, 0x10, 0x0, 0x0, - 0x0, 0x2, 0xe1, 0x0, 0x0, 0xd3, 0x0, 0x0, - 0x0, 0x9, 0x96, 0x6b, 0x65, 0xc6, 0x66, 0xc1, - 0x0, 0x19, 0x7, 0x60, 0x9, 0x0, 0x94, 0x0, - 0x0, 0x91, 0x21, 0x60, 0x40, 0x0, 0x66, 0x0, - 0x4, 0x10, 0xe6, 0x66, 0x66, 0x67, 0xd0, 0x0, - 0x0, 0x0, 0xe6, 0x66, 0x66, 0x67, 0xb0, 0x0, - 0x0, 0x0, 0xd0, 0x0, 0x0, 0x3, 0xb0, 0x0, - 0x0, 0x0, 0xe6, 0x66, 0x66, 0x67, 0xb0, 0x0, - 0x0, 0x0, 0xe6, 0x66, 0x66, 0x67, 0xb0, 0x0, - 0x0, 0x0, 0x90, 0xf0, 0x0, 0xe1, 0x50, 0x0, - 0x0, 0x0, 0x1, 0xd0, 0x0, 0xe0, 0x0, 0x80, - 0x6, 0x76, 0x69, 0xc6, 0x66, 0xe6, 0x66, 0x73, - 0x0, 0x0, 0x1c, 0x20, 0x0, 0xe0, 0x0, 0x0, - 0x0, 0x4, 0xa2, 0x0, 0x0, 0xe0, 0x0, 0x0, - 0x0, 0x52, 0x0, 0x0, 0x0, 0x50, 0x0, 0x0, - - /* U+7BA1 "管" */ - 0x0, 0x1, 0x0, 0x0, 0x1, 0x0, 0x0, 0x0, - 0x0, 0xa7, 0x0, 0x0, 0xb5, 0x0, 0x0, 0x0, - 0x2e, 0x66, 0x88, 0x2d, 0x66, 0x6c, 0x20, 0xa, - 0x15, 0x40, 0x7, 0x3, 0x60, 0x0, 0x5, 0x20, - 0x1a, 0xa, 0x10, 0xb, 0x0, 0x0, 0x13, 0x0, - 0x0, 0x75, 0x0, 0x0, 0x62, 0x2, 0xb6, 0x66, - 0x66, 0x66, 0x66, 0x6e, 0x70, 0xc4, 0x9, 0x66, - 0x66, 0x6a, 0x43, 0x40, 0x0, 0x0, 0xd0, 0x0, - 0x0, 0xa2, 0x0, 0x0, 0x0, 0xd, 0x66, 0x66, - 0x6c, 0x20, 0x0, 0x0, 0x0, 0xd0, 0x0, 0x0, - 0x61, 0x0, 0x0, 0x0, 0xd, 0x0, 0x0, 0x0, - 0x60, 0x0, 0x0, 0x0, 0xd6, 0x66, 0x66, 0x6d, - 0x0, 0x0, 0x0, 0xd, 0x0, 0x0, 0x1, 0xb0, - 0x0, 0x0, 0x0, 0xe6, 0x66, 0x66, 0x6c, 0x0, - 0x0, 0x0, 0x6, 0x0, 0x0, 0x0, 0x20, 0x0, - - /* U+7BC0 "節" */ - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x4, 0xc0, 0x0, 0x4, 0xc0, 0x0, 0x0, 0x0, - 0xb9, 0x66, 0xc5, 0xa9, 0x66, 0x9c, 0x10, 0x48, - 0x7, 0x80, 0x19, 0x2, 0x92, 0x0, 0x18, 0x0, - 0xa, 0x16, 0x0, 0x3, 0xd0, 0x5, 0x3, 0x0, - 0x5, 0x3, 0x0, 0x7, 0x0, 0x0, 0xd6, 0x66, - 0xe1, 0xd6, 0x66, 0xe1, 0x0, 0xd, 0x66, 0x6d, - 0xd, 0x0, 0xd, 0x0, 0x0, 0xc0, 0x0, 0xd0, - 0xd0, 0x0, 0xd0, 0x0, 0xc, 0x0, 0xd, 0xd, - 0x0, 0xd, 0x0, 0x0, 0xd6, 0x66, 0xa0, 0xd0, - 0x0, 0xd0, 0x0, 0xc, 0x1, 0x60, 0xd, 0x0, - 0xd, 0x0, 0x0, 0xc0, 0x8, 0x80, 0xd0, 0x3b, - 0xa0, 0x0, 0x1d, 0x78, 0x3f, 0x1d, 0x0, 0x20, - 0x0, 0x0, 0xc4, 0x0, 0x60, 0xd0, 0x0, 0x0, - 0x0, 0x0, 0x0, 0x0, 0x5, 0x0, 0x0, 0x0, - - /* U+7BC4 "範" */ - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0xc5, 0x0, 0x0, 0x79, 0x0, 0x10, 0x0, - 0x4f, 0x76, 0x6d, 0x3d, 0x86, 0x6d, 0x30, 0xb, - 0x24, 0x80, 0x5, 0x60, 0x87, 0x0, 0x6, 0x30, - 0x49, 0x70, 0x70, 0x0, 0xb7, 0x1, 0x41, 0x1b, - 0x52, 0x70, 0x20, 0x5, 0x30, 0x2, 0x65, 0xc6, - 0x55, 0x1d, 0x66, 0xd3, 0x0, 0xa, 0x6c, 0x66, - 0xc1, 0xb0, 0xb, 0x0, 0x0, 0xc0, 0xa1, 0xb, - 0xb, 0x0, 0xb0, 0x0, 0xc, 0x6c, 0x66, 0xb0, - 0xb0, 0xb, 0x0, 0x0, 0xc0, 0xa1, 0xb, 0xb, - 0x0, 0xc0, 0x0, 0xb, 0x6c, 0x66, 0x90, 0xb3, - 0x8c, 0x0, 0x4, 0x66, 0xc6, 0x6b, 0x2b, 0x0, - 0x3, 0x0, 0x11, 0xa, 0x10, 0x0, 0xb0, 0x0, - 0x70, 0x0, 0x0, 0xb2, 0x0, 0xc, 0xbb, 0xbe, - 0x40, 0x0, 0x5, 0x0, 0x0, 0x0, 0x0, 0x0, - - /* U+7C21 "簡" */ - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0xa6, 0x0, 0x0, 0xf4, 0x0, 0x10, 0x0, - 0x2e, 0x76, 0x7b, 0x6d, 0x76, 0x6c, 0x60, 0xa, - 0x23, 0xa0, 0x9, 0x4, 0xb2, 0x0, 0x6, 0x20, - 0x8, 0x23, 0x0, 0x5, 0x51, 0x0, 0xc, 0x66, - 0x6c, 0x19, 0x76, 0x67, 0xd0, 0x0, 0xd0, 0x0, - 0xb0, 0x92, 0x0, 0x1b, 0x0, 0xd, 0x66, 0x6c, - 0x9, 0x76, 0x66, 0xb0, 0x0, 0xd6, 0x66, 0xc0, - 0xa7, 0x66, 0x6b, 0x0, 0xd, 0x0, 0x21, 0x2, - 0x5, 0x1, 0xb0, 0x0, 0xd0, 0xd, 0x66, 0x66, - 0xe1, 0x1b, 0x0, 0xd, 0x0, 0xc6, 0x66, 0x6d, - 0x1, 0xb0, 0x0, 0xd0, 0xc, 0x0, 0x1, 0xd0, - 0x1b, 0x0, 0xd, 0x0, 0xb6, 0x66, 0x6a, 0x1, - 0xb0, 0x0, 0xd0, 0x0, 0x0, 0x0, 0x26, 0xaa, - 0x0, 0x4, 0x0, 0x0, 0x0, 0x0, 0x6, 0x10, - - /* U+7C73 "米" */ - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x0, 0xc, 0x60, 0x0, 0x0, 0x0, - 0x0, 0x6, 0x0, 0xc, 0x20, 0xa, 0x90, 0x0, - 0x0, 0x5, 0xb0, 0xc, 0x20, 0x2e, 0x20, 0x0, - 0x0, 0x0, 0xe6, 0xc, 0x20, 0xa4, 0x0, 0x0, - 0x0, 0x0, 0x74, 0xc, 0x25, 0x50, 0x1, 0x0, - 0x5, 0x66, 0x66, 0x6d, 0x7a, 0x66, 0x6f, 0x50, - 0x1, 0x0, 0x0, 0xcf, 0x71, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x5, 0xbc, 0x38, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x1d, 0x1c, 0x27, 0x50, 0x0, 0x0, - 0x0, 0x0, 0xc4, 0xc, 0x20, 0xc4, 0x0, 0x0, - 0x0, 0xa, 0x50, 0xc, 0x20, 0x2e, 0x80, 0x0, - 0x0, 0x93, 0x0, 0xc, 0x20, 0x2, 0xee, 0x70, - 0x16, 0x10, 0x0, 0xc, 0x20, 0x0, 0x1a, 0x20, - 0x10, 0x0, 0x0, 0xd, 0x20, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x0, 0x5, 0x0, 0x0, 0x0, 0x0, - - /* U+7CBE "精" */ - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x9, 0x50, 0x0, 0x0, 0xd2, 0x0, 0x0, - 0x1, 0xa, 0x22, 0x10, 0x0, 0xd0, 0x5, 0x10, - 0x7, 0x3a, 0x29, 0x64, 0x76, 0xe6, 0x66, 0x30, - 0x1, 0xda, 0x38, 0x0, 0x0, 0xd0, 0x5, 0x0, - 0x0, 0x4a, 0x51, 0x1, 0x76, 0xe6, 0x65, 0x0, - 0x18, 0x6d, 0x7a, 0x60, 0x0, 0xd0, 0x2, 0x50, - 0x0, 0xf, 0x20, 0x7, 0x66, 0x66, 0x66, 0x50, - 0x0, 0x5f, 0x95, 0x1, 0xa6, 0x66, 0x7b, 0x0, - 0x0, 0xac, 0x2e, 0x21, 0xc0, 0x0, 0x3a, 0x0, - 0x2, 0x8a, 0x23, 0x1, 0xd6, 0x66, 0x7a, 0x0, - 0x8, 0x1a, 0x20, 0x1, 0xc0, 0x0, 0x3a, 0x0, - 0x23, 0xa, 0x20, 0x1, 0xd6, 0x66, 0x7a, 0x0, - 0x10, 0xa, 0x20, 0x1, 0xc0, 0x0, 0x3a, 0x0, - 0x0, 0xb, 0x30, 0x1, 0xc0, 0x17, 0x99, 0x0, - 0x0, 0x5, 0x0, 0x1, 0x60, 0x0, 0x92, 0x0, - - /* U+7CD6 "糖" */ - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0xa, 0x30, 0x0, 0x1, 0xb3, 0x0, 0x0, - 0x1, 0xc, 0x13, 0x3, 0x0, 0x34, 0x3, 0x60, - 0x8, 0x1c, 0x1d, 0x4e, 0x66, 0xb8, 0x66, 0x50, - 0x5, 0x8c, 0x66, 0xd, 0x0, 0xb1, 0x3, 0x0, - 0x2, 0x4c, 0x60, 0xd, 0x37, 0xd7, 0x6e, 0x0, - 0x6, 0x6d, 0x6b, 0x6d, 0x0, 0xb1, 0xd, 0x40, - 0x1, 0xf, 0x10, 0xc, 0x66, 0xd7, 0x6e, 0x61, - 0x0, 0x4f, 0x81, 0xc, 0x0, 0xb1, 0xd, 0x0, - 0x0, 0x9e, 0x4d, 0x1b, 0x37, 0xd7, 0x6c, 0x0, - 0x1, 0x9c, 0x16, 0x39, 0x10, 0x81, 0x3, 0x0, - 0x7, 0x1c, 0x10, 0x65, 0x87, 0x66, 0x6e, 0x10, - 0x14, 0xc, 0x10, 0xa0, 0x82, 0x0, 0xd, 0x0, - 0x0, 0xc, 0x12, 0x60, 0x82, 0x0, 0xd, 0x0, - 0x0, 0xc, 0x17, 0x0, 0x87, 0x66, 0x6e, 0x0, - 0x0, 0x5, 0x10, 0x0, 0x30, 0x0, 0x2, 0x0, - - /* U+7CFB "系" */ - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x0, 0x1, 0x47, 0xcf, 0x30, 0x0, - 0x14, 0x56, 0x7b, 0xa6, 0x42, 0x10, 0x0, 0x0, - 0x0, 0x2, 0xd7, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x3, 0xa1, 0x0, 0xb, 0x30, 0x0, 0x0, 0x28, - 0x93, 0x34, 0x5c, 0x71, 0x0, 0x0, 0x3, 0xe9, - 0x64, 0xa9, 0x10, 0x0, 0x0, 0x0, 0x0, 0x5, - 0x92, 0x1, 0x61, 0x0, 0x0, 0x0, 0x6a, 0x40, - 0x0, 0x15, 0xe6, 0x0, 0x0, 0xdf, 0xa8, 0x8e, - 0x54, 0x35, 0xf0, 0x0, 0x2, 0x3, 0x0, 0xe0, - 0x10, 0x4, 0x0, 0x0, 0x2, 0xf5, 0xe, 0x5, - 0x82, 0x0, 0x0, 0x2, 0xc4, 0x0, 0xe0, 0x3, - 0xe9, 0x0, 0x4, 0x91, 0x12, 0x1e, 0x0, 0x2, - 0xf5, 0x5, 0x30, 0x0, 0x4e, 0xc0, 0x0, 0x5, - 0x30, 0x0, 0x0, 0x0, 0x20, 0x0, 0x0, 0x0, - - /* U+7D00 "紀" */ - 0x0, 0x0, 0x90, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x6, 0x90, 0x4, 0x76, 0x66, 0x6e, 0x20, - 0x0, 0x1a, 0x0, 0x0, 0x0, 0x0, 0xe, 0x0, - 0x0, 0x91, 0xa, 0x50, 0x0, 0x0, 0xe, 0x0, - 0xa, 0xa7, 0x7b, 0x0, 0x0, 0x0, 0xe, 0x0, - 0x4, 0x41, 0xa1, 0x0, 0x86, 0x66, 0x6e, 0x0, - 0x0, 0xa, 0x15, 0x30, 0xe0, 0x0, 0x8, 0x0, - 0x2, 0xa2, 0x15, 0xe0, 0xe0, 0x0, 0x0, 0x0, - 0xa, 0xe9, 0x62, 0xc1, 0xe0, 0x0, 0x0, 0x0, - 0x2, 0x20, 0x2, 0x10, 0xe0, 0x0, 0x0, 0x0, - 0x1, 0x16, 0x12, 0xa0, 0xe0, 0x0, 0x0, 0x30, - 0x6, 0x24, 0xa0, 0xd4, 0xe0, 0x0, 0x0, 0x60, - 0xc, 0x31, 0xe0, 0x61, 0xd1, 0x0, 0x2, 0xa0, - 0x19, 0x0, 0x20, 0x0, 0x8e, 0xdd, 0xde, 0xc0, - - /* U+7D04 "約" */ - 0x0, 0x0, 0x81, 0x0, 0x4, 0x80, 0x0, 0x0, - 0x0, 0x2c, 0x10, 0x0, 0x99, 0x0, 0x0, 0x0, - 0xa, 0x10, 0x0, 0xd, 0x10, 0x0, 0x0, 0x8, - 0x40, 0x87, 0x4, 0xc6, 0x66, 0xb9, 0x8, 0xb7, - 0x6d, 0x10, 0x91, 0x0, 0x8, 0x50, 0x47, 0x2a, - 0x20, 0x44, 0x0, 0x0, 0x94, 0x0, 0x9, 0x34, - 0x41, 0x10, 0x0, 0xa, 0x30, 0x1a, 0x30, 0x1e, - 0x10, 0xb5, 0x0, 0xb3, 0x9, 0xea, 0x85, 0xa4, - 0x2, 0xf4, 0xb, 0x20, 0x12, 0x0, 0x3, 0x0, - 0x7, 0x20, 0xc1, 0x0, 0x33, 0x30, 0xa1, 0x0, - 0x0, 0xd, 0x0, 0x45, 0xd, 0x6, 0xa0, 0x0, - 0x0, 0xe0, 0xc, 0x50, 0xd2, 0x29, 0x0, 0x0, - 0x2c, 0x0, 0xa1, 0x3, 0x0, 0x0, 0x5, 0xcf, - 0x70, 0x0, 0x0, 0x0, 0x0, 0x0, 0x2, 0x40, - 0x0, - - /* U+7D19 "紙" */ - 0x0, 0x3, 0x70, 0x0, 0x0, 0x0, 0x34, 0x0, - 0x0, 0xb5, 0x0, 0x30, 0x36, 0xbb, 0x70, 0x0, - 0x57, 0x0, 0xa, 0x64, 0xb2, 0x0, 0x0, 0x29, - 0x0, 0xc2, 0xa1, 0xa, 0x20, 0x0, 0x1e, 0x87, - 0xa8, 0xa, 0x10, 0xa2, 0x0, 0x0, 0x73, 0x49, - 0x0, 0xa1, 0x9, 0x20, 0x50, 0x0, 0x39, 0x7, - 0xa, 0x66, 0xb8, 0x68, 0x40, 0x59, 0x1, 0xa6, - 0xa1, 0x6, 0x60, 0x0, 0xe, 0xc9, 0x66, 0xaa, - 0x10, 0x39, 0x0, 0x0, 0x20, 0x0, 0x11, 0xa1, - 0x0, 0xd0, 0x0, 0x3, 0x5, 0xa, 0x2a, 0x10, - 0xb, 0x30, 0x40, 0x90, 0xb2, 0x4a, 0xa1, 0x11, - 0x3c, 0x8, 0x2d, 0x9, 0x50, 0x2b, 0x85, 0x0, - 0x8d, 0x95, 0x70, 0x0, 0x0, 0xc4, 0x0, 0x0, - 0x7a, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, - - /* U+7D20 "素" */ - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x3, 0xb0, 0x0, 0x0, 0x0, 0x3, - 0x66, 0x66, 0x8c, 0x66, 0x68, 0xc0, 0x0, 0x0, - 0x0, 0x3, 0xa0, 0x0, 0x10, 0x0, 0x0, 0x28, - 0x66, 0x8c, 0x66, 0x88, 0x0, 0x0, 0x0, 0x0, - 0x3, 0xa0, 0x0, 0x1, 0x60, 0x67, 0x66, 0x6d, - 0xa6, 0x66, 0x66, 0x67, 0x10, 0x0, 0x29, 0x60, - 0x7, 0xc0, 0x0, 0x0, 0x0, 0x2f, 0x97, 0x6c, - 0x91, 0x0, 0x0, 0x0, 0x0, 0x20, 0x69, 0x20, - 0x57, 0x0, 0x0, 0x0, 0x38, 0xc7, 0x56, 0x76, - 0xac, 0x0, 0x0, 0x8, 0xc8, 0x55, 0xa0, 0x0, - 0xa0, 0x0, 0x0, 0x5, 0xd1, 0x3a, 0x17, 0x50, - 0x0, 0x0, 0x5, 0xb2, 0x3, 0xa0, 0x6, 0xe5, - 0x0, 0x17, 0x40, 0x39, 0xe9, 0x0, 0x4, 0xe0, - 0x1, 0x0, 0x0, 0x7, 0x0, 0x0, 0x1, 0x0, - - /* U+7D30 "細" */ - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x67, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0xc, 0x30, 0x8, 0x66, 0x66, 0x6c, 0x30, 0x7, - 0x50, 0x0, 0xd0, 0xd, 0x0, 0xd0, 0x3, 0x80, - 0xd, 0x1d, 0x0, 0xd0, 0xd, 0x2, 0xe7, 0x7a, - 0x70, 0xd0, 0xd, 0x0, 0xd0, 0x8, 0x35, 0x80, - 0xd, 0x0, 0xd0, 0xd, 0x0, 0x3, 0x92, 0x40, - 0xd0, 0xd, 0x0, 0xd0, 0x4, 0xa0, 0xc, 0x2d, - 0x66, 0xe6, 0x6e, 0x1, 0xfb, 0x97, 0xa7, 0xd0, - 0xd, 0x0, 0xd0, 0x4, 0x0, 0x2, 0x1d, 0x0, - 0xd0, 0xd, 0x0, 0x20, 0x50, 0xa0, 0xd0, 0xd, - 0x0, 0xd0, 0x9, 0xb, 0x27, 0x9d, 0x0, 0xd0, - 0xd, 0x1, 0xd0, 0x87, 0x15, 0xd6, 0x6c, 0x66, - 0xe0, 0x48, 0x1, 0x0, 0xd, 0x0, 0x0, 0xc, - 0x0, 0x0, 0x0, 0x0, 0x30, 0x0, 0x0, 0x20, - - /* U+7D39 "紹" */ - 0x0, 0x0, 0x70, 0x0, 0x0, 0x0, 0x1, 0x0, - 0x0, 0x4c, 0x10, 0x56, 0x88, 0x66, 0xc7, 0x0, - 0xb, 0x10, 0x0, 0x9, 0x50, 0xc, 0x20, 0x8, - 0x20, 0x75, 0x0, 0xb2, 0x0, 0xd0, 0x9, 0x95, - 0x5d, 0x20, 0x1d, 0x0, 0xe, 0x0, 0x78, 0x3b, - 0x20, 0x7, 0x60, 0x1, 0xd0, 0x0, 0x9, 0x36, - 0x1, 0x90, 0x17, 0xaa, 0x0, 0xa, 0x30, 0x59, - 0x60, 0x0, 0x9, 0x30, 0xb, 0xd9, 0x86, 0xd0, - 0xc6, 0x66, 0x6d, 0x40, 0x22, 0x0, 0x32, 0xd, - 0x0, 0x0, 0xc1, 0x0, 0x34, 0x22, 0xb0, 0xd0, - 0x0, 0xc, 0x10, 0x26, 0x1d, 0xb, 0x5d, 0x0, - 0x0, 0xc1, 0xa, 0x60, 0xd0, 0x21, 0xe6, 0x66, - 0x6d, 0x10, 0x91, 0x0, 0x0, 0xc, 0x0, 0x0, - 0xb1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, - - /* U+7D42 "終" */ - 0x0, 0x0, 0x80, 0x0, 0xb, 0x30, 0x0, 0x0, - 0x0, 0x7, 0x90, 0x0, 0x3d, 0x0, 0x2, 0x0, - 0x0, 0x1b, 0x0, 0x0, 0xa7, 0x66, 0x8e, 0x10, - 0x0, 0x91, 0xa, 0x43, 0x95, 0x0, 0xa5, 0x0, - 0xa, 0xa7, 0x7b, 0x16, 0x8, 0x3, 0xb0, 0x0, - 0x5, 0x52, 0xa0, 0x0, 0x2, 0xac, 0x10, 0x0, - 0x0, 0xa, 0x16, 0x10, 0x0, 0xda, 0x0, 0x0, - 0x1, 0xa2, 0x4, 0xb0, 0xa, 0x48, 0xc3, 0x0, - 0xa, 0xd9, 0x74, 0xb3, 0x72, 0x40, 0x6f, 0xb2, - 0x2, 0x10, 0x3, 0x32, 0x0, 0x6d, 0x11, 0x10, - 0x2, 0x16, 0x6, 0x60, 0x0, 0x9, 0x20, 0x0, - 0x6, 0x25, 0x80, 0xf0, 0x28, 0x61, 0x0, 0x0, - 0xd, 0x23, 0xb0, 0x30, 0x0, 0x5e, 0x80, 0x0, - 0x1a, 0x0, 0x0, 0x0, 0x0, 0x2, 0xe4, 0x0, - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x21, 0x0, - - /* U+7D44 "組" */ - 0x0, 0x0, 0x90, 0x0, 0x0, 0x0, 0x1, 0x0, - 0x0, 0x7, 0x90, 0x0, 0xd6, 0x66, 0x7e, 0x10, - 0x0, 0x1b, 0x0, 0x0, 0xe0, 0x0, 0x1c, 0x0, - 0x0, 0xa1, 0x9, 0x40, 0xe0, 0x0, 0x1c, 0x0, - 0xb, 0x97, 0x7c, 0x0, 0xe0, 0x0, 0x1c, 0x0, - 0x6, 0x52, 0xb0, 0x0, 0xe6, 0x66, 0x6c, 0x0, - 0x0, 0x1a, 0x16, 0x20, 0xe0, 0x0, 0x1c, 0x0, - 0x2, 0xb1, 0x3, 0xd0, 0xe0, 0x0, 0x1c, 0x0, - 0xc, 0xd9, 0x74, 0xd1, 0xe0, 0x0, 0x1c, 0x0, - 0x2, 0x10, 0x3, 0x20, 0xe6, 0x66, 0x6c, 0x0, - 0x1, 0x25, 0x15, 0x80, 0xe0, 0x0, 0x1c, 0x0, - 0x4, 0x43, 0xa0, 0xe0, 0xe0, 0x0, 0x1c, 0x0, - 0xb, 0x41, 0xd0, 0x20, 0xe0, 0x0, 0x1c, 0x10, - 0xa, 0x0, 0x1, 0x66, 0xe6, 0x66, 0x6e, 0xe3, - 0x0, 0x0, 0x0, 0x10, 0x0, 0x0, 0x0, 0x0, - - /* U+7D4C "経" */ - 0x0, 0x2, 0x70, 0x0, 0x0, 0x0, 0x3, 0x0, - 0x0, 0x9, 0x60, 0x17, 0xa6, 0x66, 0x8f, 0x20, - 0x0, 0x2a, 0x0, 0x0, 0x62, 0x0, 0xb6, 0x0, - 0x0, 0x90, 0xa, 0x10, 0xa, 0x6, 0xa0, 0x0, - 0xa, 0x85, 0x79, 0x0, 0x5, 0xbb, 0x0, 0x0, - 0x7, 0x75, 0xb0, 0x0, 0x6, 0xdb, 0x10, 0x0, - 0x0, 0xa, 0x15, 0x0, 0x87, 0x5, 0xeb, 0x71, - 0x0, 0xa2, 0x7, 0x66, 0x10, 0xb4, 0x7, 0x30, - 0xb, 0xb9, 0x78, 0xa0, 0x0, 0xb2, 0x1, 0x0, - 0x4, 0x40, 0x1, 0x34, 0x76, 0xd7, 0x6b, 0x20, - 0x1, 0x15, 0x8, 0x30, 0x0, 0xb2, 0x0, 0x0, - 0x7, 0x25, 0x72, 0xd0, 0x0, 0xb2, 0x0, 0x0, - 0x1e, 0x13, 0xb0, 0x80, 0x0, 0xb2, 0x2, 0x70, - 0x18, 0x0, 0x10, 0x57, 0x66, 0x66, 0x66, 0x50, - - /* U+7D50 "結" */ - 0x0, 0x1, 0x70, 0x0, 0x0, 0x93, 0x0, 0x0, - 0x0, 0x8, 0x80, 0x0, 0x0, 0xa2, 0x0, 0x0, - 0x0, 0x2a, 0x0, 0x0, 0x0, 0xa2, 0x0, 0x0, - 0x0, 0xa0, 0xa, 0x35, 0x66, 0xc7, 0x67, 0xc1, - 0xc, 0x86, 0x7b, 0x0, 0x0, 0xa2, 0x0, 0x0, - 0x7, 0x43, 0xa0, 0x0, 0x0, 0xa2, 0x0, 0x0, - 0x0, 0x2a, 0x6, 0x11, 0x66, 0xc7, 0x6c, 0x20, - 0x4, 0xa0, 0x16, 0xc0, 0x10, 0x0, 0x0, 0x0, - 0xd, 0xc9, 0x63, 0xd0, 0x96, 0x66, 0x6b, 0x10, - 0x1, 0x0, 0x4, 0x10, 0xd0, 0x0, 0xd, 0x0, - 0x2, 0x16, 0x23, 0xa0, 0xd0, 0x0, 0xd, 0x0, - 0x6, 0x33, 0xb0, 0xd2, 0xd0, 0x0, 0xd, 0x0, - 0xd, 0x21, 0xc0, 0x20, 0xe6, 0x66, 0x6d, 0x0, - 0x18, 0x0, 0x0, 0x0, 0xd0, 0x0, 0xc, 0x0, - 0x0, 0x0, 0x0, 0x0, 0x10, 0x0, 0x0, 0x0, - - /* U+7D61 "絡" */ - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x3, 0x30, 0x0, 0xd, 0x40, 0x0, 0x0, - 0x0, 0xa, 0x60, 0x0, 0x4c, 0x0, 0x0, 0x0, - 0x0, 0x29, 0x0, 0x0, 0xa8, 0x66, 0x6e, 0x20, - 0x0, 0x90, 0x9, 0x2, 0xc0, 0x0, 0x7a, 0x0, - 0xa, 0x63, 0x7a, 0x8, 0x18, 0x3, 0xc0, 0x0, - 0xa, 0x86, 0xb0, 0x31, 0x3, 0x9c, 0x10, 0x0, - 0x0, 0xa, 0x14, 0x0, 0x2, 0xcb, 0x10, 0x0, - 0x0, 0xa2, 0xa, 0x20, 0x59, 0x13, 0xd8, 0x30, - 0xc, 0xa8, 0x79, 0xa6, 0x40, 0x0, 0x19, 0xa2, - 0x7, 0x50, 0x2, 0x40, 0xe6, 0x66, 0x8c, 0x0, - 0x0, 0x12, 0x5, 0x0, 0xd0, 0x0, 0x2a, 0x0, - 0x2, 0x57, 0x27, 0x70, 0xd0, 0x0, 0x2a, 0x0, - 0x9, 0x45, 0x92, 0xa0, 0xd0, 0x0, 0x2a, 0x0, - 0x1e, 0x13, 0x50, 0x0, 0xe6, 0x66, 0x7b, 0x0, - 0x0, 0x0, 0x0, 0x0, 0x30, 0x0, 0x12, 0x0, - - /* U+7D66 "給" */ - 0x0, 0x0, 0x70, 0x0, 0x0, 0x84, 0x0, 0x0, - 0x0, 0x4, 0xb0, 0x0, 0x0, 0xf8, 0x0, 0x0, - 0x0, 0xb, 0x10, 0x0, 0x7, 0x86, 0x10, 0x0, - 0x0, 0x73, 0x9, 0x30, 0xc, 0x10, 0xa0, 0x0, - 0x5, 0xb6, 0x6b, 0x0, 0x93, 0x0, 0x5a, 0x0, - 0x3, 0x83, 0xb1, 0x6, 0x40, 0x0, 0x29, 0xd5, - 0x0, 0x8, 0x26, 0x43, 0x76, 0x66, 0xa4, 0x70, - 0x0, 0x94, 0x4, 0xa0, 0x0, 0x0, 0x0, 0x0, - 0x6, 0xea, 0x85, 0xd2, 0x96, 0x66, 0x6c, 0x10, - 0x0, 0x30, 0x2, 0x21, 0xb0, 0x0, 0xd, 0x0, - 0x0, 0x42, 0x56, 0x61, 0xb0, 0x0, 0xd, 0x0, - 0x4, 0x60, 0xd1, 0xf2, 0xb0, 0x0, 0xd, 0x0, - 0xd, 0x40, 0xd0, 0x42, 0xd6, 0x66, 0x6d, 0x0, - 0x5, 0x0, 0x0, 0x2, 0xb0, 0x0, 0xd, 0x0, - 0x0, 0x0, 0x0, 0x0, 0x20, 0x0, 0x0, 0x0, - - /* U+7D71 "統" */ - 0x0, 0x5, 0x50, 0x0, 0x8, 0x40, 0x0, 0x0, - 0x0, 0xc, 0x30, 0x0, 0x1, 0xf1, 0x0, 0x0, - 0x0, 0x75, 0x0, 0x36, 0x66, 0x96, 0x6c, 0x70, - 0x2, 0x80, 0x1c, 0x11, 0xb, 0x40, 0x0, 0x0, - 0x2e, 0x76, 0xb6, 0x0, 0x78, 0x2, 0x40, 0x0, - 0x8, 0x36, 0x70, 0x6, 0x60, 0x0, 0x96, 0x0, - 0x0, 0x38, 0x7, 0x2e, 0x97, 0x54, 0x4f, 0x0, - 0x5, 0x90, 0xa, 0x61, 0x62, 0x6, 0x14, 0x0, - 0x1f, 0xb9, 0x77, 0xa0, 0xb3, 0xd, 0x0, 0x0, - 0x3, 0x0, 0x5, 0x10, 0xc1, 0xd, 0x0, 0x0, - 0x4, 0x8, 0x8, 0x60, 0xd0, 0xd, 0x0, 0x10, - 0xa, 0xb, 0x22, 0xb3, 0xa0, 0xd, 0x0, 0x50, - 0x4c, 0x7, 0x10, 0x1b, 0x20, 0xd, 0x0, 0x80, - 0x11, 0x0, 0x3, 0x82, 0x0, 0x9, 0xdd, 0xc0, - 0x0, 0x0, 0x22, 0x0, 0x0, 0x0, 0x0, 0x0, - - /* U+7D75 "絵" */ - 0x0, 0x4, 0x30, 0x0, 0x1, 0x90, 0x0, 0x0, - 0x0, 0xc, 0x50, 0x0, 0x7, 0xe1, 0x0, 0x0, - 0x0, 0x58, 0x0, 0x0, 0xd, 0x28, 0x0, 0x0, - 0x1, 0x90, 0xa, 0x0, 0x86, 0x5, 0x80, 0x0, - 0x1c, 0x55, 0x98, 0x4, 0x80, 0x0, 0x99, 0x0, - 0xa, 0x56, 0x90, 0x46, 0x0, 0x2, 0x6a, 0xd2, - 0x0, 0x39, 0x6, 0x20, 0x76, 0x66, 0x50, 0x10, - 0x4, 0x90, 0x9, 0x50, 0x0, 0x0, 0x2, 0x0, - 0x1f, 0xb9, 0x77, 0xa7, 0x67, 0x66, 0x6a, 0x40, - 0x4, 0x0, 0x2, 0x10, 0x9, 0x90, 0x0, 0x0, - 0x2, 0x7, 0xa, 0x30, 0x3c, 0x0, 0x10, 0x0, - 0x8, 0x8, 0x64, 0xc0, 0xb1, 0x0, 0x82, 0x0, - 0xd, 0x5, 0x70, 0x5a, 0x53, 0x45, 0x7e, 0x10, - 0x16, 0x0, 0x0, 0xc, 0x95, 0x31, 0xa, 0x40, - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - - /* U+7D93 "經" */ - 0x0, 0x7, 0x20, 0x0, 0x0, 0x0, 0x3, 0x0, - 0x0, 0xc, 0x10, 0x47, 0x66, 0x66, 0x6a, 0x60, - 0x0, 0x74, 0x0, 0x3, 0x50, 0x92, 0x28, 0x0, - 0x1, 0x80, 0x46, 0x9, 0x62, 0xc0, 0x96, 0x0, - 0x1b, 0x44, 0xb3, 0x29, 0x9, 0x13, 0x70, 0x0, - 0xa, 0x58, 0x60, 0x53, 0x8, 0x5, 0x60, 0x0, - 0x0, 0x29, 0x21, 0xc, 0x33, 0xc0, 0xa7, 0x0, - 0x1, 0xa0, 0xb, 0x6, 0x90, 0xc1, 0x19, 0x0, - 0xe, 0x99, 0x8d, 0x30, 0x10, 0x0, 0x3, 0x0, - 0x8, 0x40, 0x4, 0x17, 0x66, 0xb6, 0x68, 0x30, - 0x1, 0x4, 0x9, 0x0, 0x0, 0xd0, 0x0, 0x0, - 0x6, 0x28, 0x36, 0x90, 0x0, 0xd0, 0x0, 0x0, - 0xc, 0x26, 0x81, 0x50, 0x0, 0xd0, 0x0, 0x10, - 0x1b, 0x1, 0x10, 0x46, 0x66, 0xe6, 0x6a, 0xc0, - 0x0, 0x0, 0x0, 0x11, 0x0, 0x0, 0x0, 0x0, - - /* U+7D9A "続" */ - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x4, 0x30, 0x0, 0x0, 0xb2, 0x0, 0x0, - 0x0, 0xb, 0x40, 0x0, 0x0, 0xd0, 0x1, 0x10, - 0x0, 0x38, 0x0, 0x18, 0x66, 0xe6, 0x69, 0x80, - 0x0, 0x90, 0x18, 0x0, 0x0, 0xd0, 0x1, 0x0, - 0x9, 0x74, 0x95, 0x0, 0x76, 0xb6, 0x7a, 0x0, - 0x8, 0x66, 0x80, 0x2, 0x0, 0x0, 0x0, 0x10, - 0x0, 0x9, 0x13, 0xa, 0x66, 0x66, 0x67, 0xe1, - 0x0, 0x91, 0xb, 0x4a, 0x23, 0x2, 0x7, 0x40, - 0xa, 0xb9, 0x7b, 0x51, 0x4c, 0xd, 0x22, 0x0, - 0x5, 0x50, 0x3, 0x10, 0x58, 0xd, 0x10, 0x0, - 0x1, 0x4, 0x8, 0x20, 0x75, 0xc, 0x10, 0x20, - 0x5, 0x26, 0x44, 0xb0, 0xb1, 0xc, 0x10, 0x50, - 0xa, 0x33, 0xa0, 0x66, 0x60, 0xc, 0x10, 0xa0, - 0x9, 0x0, 0x21, 0x75, 0x0, 0xa, 0xdc, 0xe1, - 0x0, 0x0, 0x4, 0x0, 0x0, 0x0, 0x0, 0x0, - - /* U+7DAD "維" */ - 0x0, 0x8, 0x10, 0x0, 0x67, 0x43, 0x0, 0x0, - 0x0, 0x2c, 0x0, 0x0, 0xa5, 0xe, 0x30, 0x0, - 0x0, 0x92, 0x0, 0x0, 0xe0, 0x6, 0x31, 0x20, - 0x4, 0x50, 0x76, 0x5, 0xd6, 0x6a, 0x68, 0x80, - 0x2c, 0x66, 0xd2, 0xb, 0xb0, 0x1c, 0x0, 0x0, - 0x8, 0x2a, 0x30, 0x46, 0xb0, 0x1c, 0x1, 0x0, - 0x0, 0x56, 0x42, 0x52, 0xc6, 0x6d, 0x6b, 0x50, - 0x5, 0x80, 0x1d, 0x2, 0xb0, 0x1c, 0x0, 0x0, - 0x2f, 0xa8, 0x6c, 0x32, 0xb0, 0x1c, 0x0, 0x0, - 0x5, 0x0, 0x12, 0x2, 0xc6, 0x6d, 0x6b, 0x50, - 0x3, 0x14, 0x1a, 0x12, 0xb0, 0x1c, 0x0, 0x0, - 0x8, 0xc, 0x18, 0x92, 0xb0, 0x1c, 0x0, 0x0, - 0x4b, 0xb, 0x31, 0x32, 0xb0, 0x1c, 0x3, 0x70, - 0x64, 0x1, 0x0, 0x2, 0xc6, 0x66, 0x66, 0x50, - 0x0, 0x0, 0x0, 0x1, 0x30, 0x0, 0x0, 0x0, - - /* U+7DB2 "網" */ - 0x0, 0x5, 0x10, 0x1, 0x0, 0x0, 0x0, 0x30, - 0x0, 0xc, 0x20, 0x1d, 0x66, 0x66, 0x76, 0xf2, - 0x0, 0x65, 0x0, 0x1b, 0x17, 0x1, 0xe1, 0xd0, - 0x1, 0x80, 0x48, 0x1b, 0x7, 0x77, 0x30, 0xd0, - 0xd, 0x76, 0xc2, 0x1b, 0x56, 0x8a, 0xa6, 0xd0, - 0x6, 0x27, 0x50, 0x1b, 0x13, 0x30, 0x0, 0xd0, - 0x0, 0x47, 0x24, 0x1b, 0x0, 0xc5, 0x0, 0xd0, - 0x4, 0x90, 0x1d, 0x3c, 0x56, 0x98, 0xb7, 0xd0, - 0xe, 0xc9, 0x6a, 0x5b, 0x1d, 0x0, 0x0, 0xd0, - 0x3, 0x0, 0x11, 0x1b, 0xd, 0x0, 0x0, 0xd0, - 0x4, 0x7, 0x29, 0x1b, 0x2e, 0x66, 0xc2, 0xd0, - 0x9, 0xc, 0xc, 0x5b, 0x3, 0x0, 0x0, 0xd0, - 0x3d, 0xb, 0x23, 0x2b, 0x0, 0x1, 0x11, 0xd0, - 0x34, 0x0, 0x0, 0x1b, 0x0, 0x1, 0x6f, 0x90, - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x2, 0x0, - - /* U+7DD1 "緑" */ - 0x0, 0x5, 0x20, 0x0, 0x0, 0x0, 0x50, 0x0, - 0x0, 0xc, 0x20, 0x7, 0x66, 0x66, 0xe2, 0x0, - 0x0, 0x64, 0x0, 0x0, 0x0, 0x0, 0xe0, 0x0, - 0x2, 0x80, 0x48, 0x3, 0x76, 0x66, 0xe0, 0x0, - 0xd, 0x76, 0xb2, 0x0, 0x0, 0x0, 0xe1, 0x20, - 0x7, 0x27, 0x40, 0x37, 0x66, 0xa6, 0xa8, 0x90, - 0x0, 0x47, 0x24, 0x0, 0x0, 0xe2, 0x5, 0x0, - 0x4, 0x80, 0x1d, 0x2a, 0x30, 0xe4, 0x5b, 0x20, - 0xe, 0xb8, 0x5a, 0x43, 0xd0, 0xe7, 0x40, 0x0, - 0x2, 0x1, 0x33, 0x0, 0x35, 0xe4, 0x30, 0x0, - 0x4, 0x19, 0xd, 0x10, 0x83, 0xe0, 0xa0, 0x0, - 0xa, 0xb, 0x37, 0x7b, 0x20, 0xe0, 0x4c, 0x10, - 0x4d, 0x6, 0x20, 0x81, 0x0, 0xe0, 0x8, 0xb1, - 0x12, 0x0, 0x0, 0x0, 0x6d, 0xd0, 0x0, 0x0, - 0x0, 0x0, 0x0, 0x0, 0x3, 0x20, 0x0, 0x0, - - /* U+7DD2 "緒" */ - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x7, 0x20, 0x0, 0x6, 0x60, 0x0, 0x0, - 0x0, 0xc, 0x10, 0x0, 0x6, 0x60, 0x9, 0x20, - 0x0, 0x73, 0x0, 0x5, 0x69, 0x9b, 0x7b, 0x0, - 0x2, 0x70, 0x58, 0x2, 0x5, 0x60, 0xc2, 0x0, - 0x1d, 0x66, 0xc2, 0x0, 0x5, 0x66, 0x80, 0x10, - 0x9, 0x48, 0x50, 0x76, 0x68, 0xae, 0x67, 0xc1, - 0x0, 0x37, 0x23, 0x0, 0x2, 0xb1, 0x0, 0x0, - 0x3, 0x90, 0xc, 0x10, 0x3b, 0x10, 0x4, 0x0, - 0xe, 0xb8, 0x7b, 0x55, 0xc6, 0x66, 0x6d, 0x0, - 0x4, 0x10, 0x2, 0x67, 0xa0, 0x0, 0xb, 0x0, - 0x3, 0x5, 0x38, 0x1, 0xc6, 0x66, 0x6b, 0x0, - 0x9, 0xc, 0xd, 0x21, 0xa0, 0x0, 0xb, 0x0, - 0x1d, 0xb, 0x36, 0x22, 0xa0, 0x0, 0xb, 0x0, - 0x35, 0x2, 0x0, 0x2, 0xc6, 0x66, 0x6b, 0x0, - 0x0, 0x0, 0x0, 0x1, 0x20, 0x0, 0x2, 0x0, - - /* U+7DDA "線" */ - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x5, 0x0, 0x0, 0x4, 0xa0, 0x0, 0x0, - 0x0, 0xd, 0x20, 0x2, 0x9, 0x10, 0x4, 0x0, - 0x0, 0x74, 0x0, 0xd, 0x66, 0x66, 0x6e, 0x0, - 0x2, 0x80, 0x44, 0xd, 0x0, 0x0, 0xd, 0x0, - 0x1c, 0x44, 0xc3, 0xd, 0x66, 0x66, 0x6d, 0x0, - 0xa, 0x59, 0x50, 0xd, 0x0, 0x0, 0xd, 0x0, - 0x0, 0x38, 0x40, 0xd, 0x66, 0xa6, 0x6c, 0x0, - 0x2, 0x90, 0x48, 0x2, 0x0, 0xf0, 0x1, 0x10, - 0x1e, 0xa8, 0x7e, 0x57, 0x95, 0xd5, 0xb, 0x70, - 0x6, 0x20, 0x23, 0x0, 0xc5, 0xd8, 0x82, 0x0, - 0x4, 0x25, 0x49, 0x3, 0x90, 0xd4, 0x70, 0x0, - 0xa, 0xd, 0xd, 0xa, 0x10, 0xd0, 0xb4, 0x0, - 0x79, 0xb, 0x1, 0x82, 0x0, 0xd0, 0x1e, 0x90, - 0x31, 0x0, 0x15, 0x11, 0x7c, 0xc0, 0x3, 0x10, - 0x0, 0x0, 0x0, 0x0, 0x5, 0x20, 0x0, 0x0, - - /* U+7DE0 "締" */ - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x5, 0x10, 0x0, 0x8, 0x70, 0x0, 0x0, - 0x0, 0xd, 0x20, 0x0, 0x0, 0xc2, 0x5, 0x10, - 0x0, 0x65, 0x0, 0x57, 0x66, 0x66, 0x77, 0x50, - 0x1, 0x80, 0x46, 0x0, 0xa3, 0x3, 0xd0, 0x0, - 0xb, 0x44, 0xb4, 0x0, 0x49, 0x8, 0x20, 0x0, - 0xa, 0x58, 0x60, 0x76, 0x66, 0x68, 0x66, 0xe2, - 0x0, 0x28, 0x23, 0xe0, 0x0, 0xb0, 0x4, 0x30, - 0x2, 0xa0, 0xb, 0x20, 0x0, 0xc0, 0x1, 0x0, - 0xe, 0xa8, 0x7c, 0x2a, 0x66, 0xd6, 0x6d, 0x10, - 0x6, 0x30, 0x13, 0xc, 0x0, 0xc0, 0xc, 0x0, - 0x2, 0x22, 0x38, 0xc, 0x0, 0xc0, 0xc, 0x0, - 0x8, 0xc, 0xc, 0x3c, 0x0, 0xc2, 0x3b, 0x0, - 0x2c, 0xc, 0x23, 0x9, 0x0, 0xc1, 0xa6, 0x0, - 0x45, 0x1, 0x0, 0x0, 0x0, 0xd0, 0x0, 0x0, - 0x0, 0x0, 0x0, 0x0, 0x0, 0x30, 0x0, 0x0, - - /* U+7DE9 "緩" */ - 0x0, 0x5, 0x20, 0x0, 0x0, 0x14, 0x8b, 0x10, - 0x0, 0xd, 0x40, 0x25, 0x68, 0x75, 0x63, 0x10, - 0x0, 0x58, 0x0, 0x6, 0x5, 0x60, 0x98, 0x0, - 0x1, 0x90, 0x47, 0x6, 0x70, 0xa0, 0xa0, 0x0, - 0xb, 0x55, 0xc4, 0x27, 0x76, 0x67, 0x7c, 0x30, - 0x7, 0x48, 0x60, 0x0, 0xd, 0x0, 0x0, 0x0, - 0x0, 0x38, 0x24, 0x56, 0x6d, 0x66, 0x67, 0xc1, - 0x3, 0x80, 0x1d, 0x31, 0x68, 0x0, 0x0, 0x0, - 0xe, 0xc9, 0x5a, 0x40, 0xa8, 0x66, 0x78, 0x0, - 0x2, 0x0, 0x11, 0x1, 0xc8, 0x0, 0xc5, 0x0, - 0x5, 0x8, 0x2a, 0x8, 0x42, 0x88, 0x80, 0x0, - 0xb, 0xb, 0x3c, 0x58, 0x0, 0xac, 0x0, 0x0, - 0x5b, 0x6, 0x24, 0x70, 0x7, 0x9a, 0xa1, 0x0, - 0x0, 0x0, 0x3, 0x2, 0x84, 0x0, 0x7f, 0xb2, - 0x0, 0x0, 0x0, 0x3, 0x0, 0x0, 0x1, 0x20, - - /* U+7DF4 "練" */ - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x6, 0x40, 0x0, 0x0, 0xb0, 0x0, 0x0, - 0x0, 0xc, 0x20, 0x0, 0x0, 0xc0, 0x0, 0x20, - 0x0, 0x55, 0x0, 0x57, 0x66, 0xd6, 0x67, 0x80, - 0x1, 0x80, 0x39, 0x0, 0x0, 0xc0, 0x0, 0x0, - 0xc, 0x76, 0xb3, 0xb, 0x66, 0xd6, 0x6d, 0x20, - 0x7, 0x36, 0x60, 0xc, 0x50, 0xc1, 0x9c, 0x0, - 0x0, 0x28, 0x14, 0xc, 0x49, 0xc6, 0x4c, 0x0, - 0x1, 0xa0, 0xb, 0x1c, 0x4, 0xc4, 0xc, 0x0, - 0xd, 0xb9, 0x7b, 0x5c, 0x6c, 0xe9, 0x6b, 0x0, - 0x4, 0x20, 0x3, 0x1, 0x2c, 0xc7, 0x0, 0x0, - 0x2, 0x5, 0xb, 0x10, 0xa3, 0xc2, 0x70, 0x0, - 0x7, 0x18, 0x47, 0x75, 0x60, 0xc0, 0x96, 0x0, - 0xd, 0x6, 0x81, 0x56, 0x0, 0xc0, 0xc, 0xb2, - 0x19, 0x0, 0x2, 0x40, 0x0, 0xd0, 0x1, 0x30, - 0x0, 0x0, 0x0, 0x0, 0x0, 0x30, 0x0, 0x0, - - /* U+7E3D "總" */ - 0x0, 0x5, 0x30, 0x0, 0x1, 0xc0, 0x0, 0x0, - 0x0, 0xc2, 0x0, 0x30, 0x64, 0x0, 0x40, 0x0, - 0x65, 0x0, 0xc, 0x56, 0xa5, 0x5e, 0x20, 0x18, - 0x3, 0x90, 0xc0, 0x9b, 0x68, 0xd0, 0xd, 0x87, - 0xc2, 0xc, 0x36, 0x6, 0x8d, 0x0, 0x62, 0x65, - 0x0, 0xc3, 0x39, 0xc0, 0xd0, 0x0, 0x29, 0x14, - 0xc, 0x2, 0xac, 0x6d, 0x0, 0x1a, 0x0, 0xb1, - 0xc3, 0x50, 0x5, 0xd0, 0xd, 0xa8, 0x7b, 0x5b, - 0x78, 0x77, 0x7b, 0x0, 0x42, 0x1, 0x21, 0x7, - 0x1b, 0x10, 0x20, 0x2, 0x22, 0x93, 0x41, 0xc0, - 0x69, 0x9, 0x60, 0x70, 0xc3, 0x9b, 0xc, 0x0, - 0x24, 0x1e, 0xd, 0xb, 0x5, 0xc0, 0xc0, 0x0, - 0x62, 0x14, 0x80, 0x0, 0x0, 0xd, 0xcc, 0xce, - 0x60, - - /* U+7E3E "績" */ - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x5, 0x40, 0x0, 0x0, 0xd0, 0x0, 0x0, - 0x0, 0xb, 0x20, 0x36, 0x66, 0xe6, 0x6d, 0x50, - 0x0, 0x46, 0x0, 0x11, 0x0, 0xd0, 0x12, 0x0, - 0x0, 0x90, 0x28, 0x5, 0x76, 0xe6, 0x78, 0x0, - 0xa, 0x75, 0xa4, 0x22, 0x22, 0xd2, 0x25, 0x90, - 0x7, 0x56, 0x70, 0x56, 0x44, 0x44, 0x46, 0x41, - 0x0, 0x19, 0x13, 0xe, 0x66, 0x66, 0x6e, 0x30, - 0x1, 0xa1, 0xb, 0x1d, 0x66, 0x66, 0x6e, 0x0, - 0xb, 0xc9, 0x8b, 0x5d, 0x0, 0x0, 0xd, 0x0, - 0x4, 0x30, 0x2, 0xe, 0x66, 0x66, 0x6e, 0x0, - 0x1, 0x15, 0xa, 0xe, 0x66, 0x66, 0x6e, 0x0, - 0x6, 0x2a, 0x38, 0x66, 0x22, 0x2, 0x6, 0x0, - 0xd, 0x17, 0x61, 0x11, 0xd7, 0x2, 0xa7, 0x0, - 0x6, 0x0, 0x0, 0x2a, 0x30, 0x0, 0xa, 0xb0, - 0x0, 0x0, 0x1, 0x30, 0x0, 0x0, 0x0, 0x40, - - /* U+7E54 "織" */ - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x6, 0x0, 0x6, 0x50, 0x9, 0x10, 0x0, - 0x0, 0x49, 0x0, 0x0, 0xa3, 0x2b, 0x20, 0x0, - 0x0, 0x90, 0x1, 0x96, 0x68, 0x4b, 0xb, 0x0, - 0x5, 0x30, 0x90, 0x73, 0xc, 0x2b, 0x8, 0x20, - 0x3b, 0x57, 0x90, 0x39, 0x26, 0xb, 0x0, 0x0, - 0x18, 0x3b, 0x4, 0x66, 0x96, 0x6c, 0x68, 0xb0, - 0x0, 0x82, 0x51, 0x30, 0x2, 0xa, 0x3, 0x0, - 0x6, 0x50, 0x85, 0xc6, 0x6d, 0x1a, 0xe, 0x10, - 0x3e, 0xa7, 0x79, 0xc0, 0xc, 0x9, 0x78, 0x0, - 0x5, 0x0, 0x11, 0xc6, 0x6c, 0x7, 0xe1, 0x0, - 0x2, 0x31, 0xa3, 0xc0, 0xc, 0x6, 0xb0, 0x20, - 0x9, 0x39, 0x59, 0xc0, 0xc, 0xb, 0xd0, 0x60, - 0x5b, 0xd, 0x1, 0xc6, 0x6b, 0x72, 0x6a, 0x90, - 0x43, 0x0, 0x0, 0x40, 0x6, 0x20, 0x8, 0xb0, - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x10, - - /* U+7E70 "繰" */ - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x9, 0x20, 0x2, 0x96, 0x66, 0x90, 0x0, - 0x0, 0x2b, 0x0, 0x2, 0xc0, 0x0, 0xb0, 0x0, - 0x0, 0x91, 0x0, 0x2, 0xc0, 0x0, 0xa0, 0x0, - 0x4, 0x50, 0x74, 0x2, 0xa6, 0x66, 0x70, 0x0, - 0x1e, 0x86, 0xc0, 0x66, 0x69, 0x8, 0x69, 0x20, - 0x5, 0xa, 0x20, 0x92, 0xc, 0xc, 0xb, 0x10, - 0x0, 0x65, 0x43, 0x97, 0x6c, 0xd, 0x6c, 0x10, - 0x5, 0x80, 0x2d, 0x71, 0x5, 0x28, 0x5, 0x0, - 0xf, 0xb9, 0x6c, 0x10, 0x0, 0xd0, 0x7, 0x30, - 0x4, 0x0, 0x11, 0x47, 0x6c, 0xe7, 0x66, 0x60, - 0x2, 0x32, 0x47, 0x0, 0x59, 0xb8, 0x0, 0x0, - 0x9, 0xd, 0xd, 0x3, 0x90, 0xb3, 0xb1, 0x0, - 0x59, 0xc, 0x12, 0x57, 0x0, 0xc0, 0x7e, 0x71, - 0x42, 0x0, 0x5, 0x20, 0x0, 0xc0, 0x7, 0x20, - 0x0, 0x0, 0x0, 0x0, 0x0, 0x20, 0x0, 0x0, - - /* U+7E7C "繼" */ - 0x0, 0x7, 0x0, 0x50, 0x20, 0x0, 0x10, 0x0, - 0x0, 0x2c, 0x0, 0xc1, 0xb2, 0x0, 0xb1, 0x0, - 0x0, 0x92, 0x0, 0xc6, 0x36, 0x87, 0x29, 0x40, - 0x4, 0x50, 0x83, 0xc9, 0x8a, 0xa, 0x88, 0x0, - 0x1d, 0x76, 0xb0, 0xc1, 0x84, 0x11, 0x83, 0x10, - 0x7, 0x19, 0x10, 0xca, 0x86, 0x9c, 0x74, 0xa0, - 0x0, 0x74, 0x51, 0xc1, 0x0, 0x12, 0x5, 0x30, - 0x6, 0x60, 0x4b, 0xc6, 0x76, 0x66, 0x88, 0x40, - 0x1f, 0xb8, 0x4c, 0xc0, 0xa3, 0x0, 0xa2, 0x0, - 0x3, 0x0, 0x0, 0xc5, 0x45, 0x76, 0x37, 0x50, - 0x3, 0x31, 0x81, 0xc7, 0x7a, 0xa, 0x98, 0x0, - 0x9, 0x29, 0x4a, 0xc0, 0x83, 0x3, 0x72, 0x60, - 0x4b, 0xd, 0x5, 0xc9, 0x86, 0x8c, 0x75, 0x90, - 0x42, 0x0, 0x0, 0xe6, 0x66, 0x86, 0x6b, 0xb0, - 0x0, 0x0, 0x0, 0x40, 0x0, 0x0, 0x0, 0x0, - - /* U+7E8C "續" */ - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x2, 0x10, 0x0, 0x0, 0xc1, 0x1, 0x0, - 0x0, 0x9, 0x70, 0x47, 0x66, 0xd6, 0x69, 0x80, - 0x0, 0x1a, 0x0, 0x3, 0x44, 0xd4, 0x59, 0x0, - 0x0, 0x91, 0x6, 0x4, 0x32, 0x22, 0x25, 0x0, - 0x7, 0x62, 0x79, 0xd, 0x6c, 0x6c, 0x6c, 0x40, - 0xa, 0x87, 0xb0, 0xc, 0xb, 0xb, 0xa, 0x10, - 0x0, 0xa, 0x13, 0xc, 0x68, 0x68, 0x6a, 0x10, - 0x0, 0x93, 0xa, 0x16, 0x76, 0x66, 0x6a, 0x0, - 0xa, 0xa8, 0x8b, 0x77, 0x60, 0x0, 0x1a, 0x0, - 0x5, 0x61, 0x2, 0x27, 0x96, 0x66, 0x7a, 0x0, - 0x1, 0x12, 0x24, 0x7, 0x95, 0x55, 0x6a, 0x0, - 0x7, 0xb, 0xc, 0x27, 0x96, 0x66, 0x7a, 0x0, - 0xd, 0xa, 0x46, 0x33, 0x8b, 0x2, 0x86, 0x0, - 0x29, 0x2, 0x0, 0x39, 0x60, 0x0, 0x9, 0xc0, - 0x0, 0x0, 0x2, 0x30, 0x0, 0x0, 0x0, 0x50, - - /* U+7EDF "统" */ - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0xc3, 0x0, 0x4, 0x80, 0x0, 0x0, 0x0, - 0x4c, 0x0, 0x0, 0xc, 0x40, 0x1, 0x0, 0xb, - 0x10, 0x17, 0x66, 0x96, 0x6a, 0xb0, 0x6, 0x50, - 0x5a, 0x0, 0x6a, 0x0, 0x0, 0x4, 0xa3, 0x4d, - 0x30, 0x19, 0x2, 0x0, 0x0, 0x59, 0x4a, 0x40, - 0x8, 0x0, 0xb, 0x70, 0x0, 0x7, 0x60, 0xb, - 0x98, 0x8b, 0x6d, 0x70, 0x6, 0x70, 0x1, 0x75, - 0xf0, 0xd0, 0x24, 0x4, 0xfb, 0x86, 0x20, 0x1d, - 0xd, 0x0, 0x0, 0x6, 0x0, 0x0, 0x2, 0xb0, - 0xd0, 0x0, 0x0, 0x0, 0x3, 0x50, 0x58, 0xd, - 0x0, 0x0, 0x49, 0xb8, 0x30, 0xb, 0x30, 0xd0, - 0x6, 0x4, 0x70, 0x0, 0x7, 0x90, 0xc, 0x0, - 0x90, 0x0, 0x0, 0x18, 0x50, 0x0, 0x8d, 0xcd, - 0x20, 0x0, 0x3, 0x0, 0x0, 0x0, 0x0, 0x0, - - /* U+7F3A "缺" */ - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0xa, 0x30, 0x0, 0x0, 0xd2, 0x0, 0x0, - 0x0, 0x1d, 0x0, 0x0, 0x0, 0xd0, 0x0, 0x0, - 0x0, 0x56, 0x0, 0x60, 0x0, 0xd0, 0x3, 0x0, - 0x0, 0xa6, 0xc6, 0x74, 0x77, 0xe6, 0x6d, 0x0, - 0x2, 0x50, 0xc0, 0x0, 0x0, 0xd0, 0x1b, 0x0, - 0x3, 0x0, 0xc0, 0x2, 0x0, 0xc0, 0x1b, 0x0, - 0x7, 0x66, 0xd6, 0x8b, 0x10, 0xc0, 0x1b, 0x0, - 0x0, 0x10, 0xc0, 0x14, 0x76, 0xd6, 0x6b, 0xa6, - 0x0, 0xd0, 0xc0, 0xa3, 0x4, 0x86, 0x0, 0x0, - 0x0, 0xc0, 0xc0, 0xb1, 0x9, 0x46, 0x10, 0x0, - 0x0, 0xc0, 0xc0, 0xb1, 0xc, 0x1, 0x90, 0x0, - 0x1, 0xd8, 0xb6, 0xc1, 0x84, 0x0, 0xa4, 0x0, - 0x0, 0xa2, 0x0, 0x36, 0x70, 0x0, 0x2e, 0x50, - 0x0, 0x0, 0x0, 0x65, 0x0, 0x0, 0x5, 0xd4, - 0x0, 0x0, 0x3, 0x0, 0x0, 0x0, 0x0, 0x0, - - /* U+7F6E "置" */ - 0x0, 0x28, 0x77, 0x77, 0x77, 0x77, 0x98, 0x0, - 0x0, 0x2b, 0x0, 0xe0, 0xc, 0x10, 0x78, 0x0, - 0x0, 0x2b, 0x0, 0xe0, 0xc, 0x10, 0x78, 0x0, - 0x0, 0x3d, 0x77, 0x99, 0x79, 0x77, 0xa7, 0x0, - 0x0, 0x0, 0x0, 0x9, 0x60, 0x0, 0x54, 0x0, - 0x0, 0x78, 0x77, 0x7d, 0x77, 0x77, 0x76, 0x0, - 0x0, 0x0, 0xa7, 0x7d, 0x77, 0x7d, 0x30, 0x0, - 0x0, 0x0, 0xe0, 0x0, 0x0, 0xe, 0x0, 0x0, - 0x0, 0x0, 0xf7, 0x77, 0x77, 0x7e, 0x0, 0x0, - 0x0, 0x0, 0xe0, 0x0, 0x0, 0xe, 0x0, 0x0, - 0x0, 0x0, 0xf7, 0x77, 0x77, 0x7e, 0x0, 0x0, - 0x0, 0x0, 0xf7, 0x77, 0x77, 0x7e, 0x0, 0x0, - 0x0, 0x0, 0xe0, 0x0, 0x0, 0xe, 0x0, 0x10, - 0x6, 0x77, 0xf7, 0x77, 0x77, 0x7e, 0x7b, 0xd1, - 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - - /* U+7F8E "美" */ - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x5, 0x50, 0x0, 0x88, 0x0, 0x0, 0x0, - 0x0, 0xd, 0x50, 0xb, 0x10, 0x10, 0x0, 0x27, - 0x66, 0xa7, 0x68, 0x76, 0x6e, 0x50, 0x0, 0x0, - 0x0, 0xd, 0x0, 0x0, 0x0, 0x0, 0x3, 0x66, - 0x66, 0xe6, 0x66, 0xb8, 0x0, 0x0, 0x2, 0x0, - 0xd, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0xd0, 0x0, 0x0, 0xb1, 0x18, 0x66, 0x66, 0x6b, - 0x66, 0x66, 0x66, 0x30, 0x0, 0x0, 0x0, 0xf2, - 0x0, 0x4, 0x0, 0x4, 0x76, 0x66, 0x8c, 0x86, - 0x66, 0x94, 0x0, 0x0, 0x0, 0xb, 0x47, 0x10, - 0x0, 0x0, 0x0, 0x0, 0x4, 0xb0, 0xa, 0x30, - 0x0, 0x0, 0x0, 0x4, 0xb1, 0x0, 0x1b, 0x93, - 0x0, 0x0, 0x48, 0x60, 0x0, 0x0, 0x7, 0xef, - 0x71, 0x42, 0x0, 0x0, 0x0, 0x0, 0x0, 0x40, - - /* U+7FA9 "義" */ - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, 0xa, 0x30, 0x1, 0xd1, 0x0, 0x0, - 0x0, 0x0, 0x4, 0x90, 0x7, 0x30, 0x73, 0x0, - 0x0, 0x66, 0x66, 0x6b, 0x76, 0x66, 0x76, 0x0, - 0x0, 0x5, 0x66, 0x6c, 0x76, 0x69, 0xb0, 0x0, - 0x0, 0x1, 0x0, 0xa, 0x20, 0x0, 0x5, 0x0, - 0x3, 0x76, 0x66, 0x69, 0x66, 0x66, 0x7b, 0x30, - 0x0, 0x0, 0x0, 0x48, 0x1b, 0x27, 0x20, 0x0, - 0x0, 0x45, 0x7d, 0x86, 0x1e, 0x2, 0xe1, 0x0, - 0x0, 0x0, 0xc, 0x0, 0xc, 0x10, 0x27, 0x40, - 0x8, 0x66, 0x6d, 0x66, 0x6b, 0x96, 0x76, 0x50, - 0x0, 0x0, 0xc, 0x4, 0x6, 0x70, 0xa9, 0x0, - 0x3, 0x57, 0xae, 0x61, 0x2, 0xc6, 0xc1, 0x0, - 0x4, 0xa4, 0xc, 0x0, 0x0, 0xdb, 0x0, 0x50, - 0x0, 0x3, 0x2c, 0x0, 0x4a, 0x7c, 0x51, 0x80, - 0x0, 0x2, 0xbb, 0x26, 0x30, 0x1, 0x8d, 0xf0, - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - - /* U+7FD2 "習" */ - 0x26, 0x66, 0x6b, 0x14, 0x66, 0x69, 0x70, 0x40, - 0x0, 0xe0, 0x32, 0x0, 0x86, 0x3, 0xd3, 0xd, - 0x1, 0xc7, 0x8, 0x60, 0x5, 0x40, 0xd0, 0x1, - 0x60, 0x86, 0x0, 0x16, 0x5d, 0x0, 0x27, 0x8a, - 0x64, 0xa8, 0x0, 0xe0, 0x8d, 0x40, 0x85, 0x44, - 0x0, 0x2, 0xc4, 0x0, 0x0, 0x0, 0x2, 0x0, - 0x46, 0x0, 0x0, 0x30, 0x0, 0xc6, 0x66, 0x66, - 0x66, 0x8d, 0x0, 0xc, 0x10, 0x0, 0x0, 0x3, - 0xb0, 0x0, 0xc6, 0x66, 0x66, 0x66, 0x7b, 0x0, - 0xc, 0x10, 0x0, 0x0, 0x3, 0xb0, 0x0, 0xc1, - 0x0, 0x0, 0x0, 0x3b, 0x0, 0xd, 0x66, 0x66, - 0x66, 0x67, 0xb0, 0x0, 0x40, 0x0, 0x0, 0x0, - 0x12, 0x0, - - /* U+8001 "老" */ - 0x0, 0x0, 0x0, 0x4a, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x0, 0x4a, 0x0, 0x2, 0xb1, 0x0, - 0x0, 0x0, 0x0, 0x4a, 0x12, 0x89, 0xb1, 0x0, - 0x0, 0x27, 0x66, 0x8c, 0x55, 0x8d, 0x10, 0x0, - 0x0, 0x0, 0x0, 0x4a, 0x1, 0xd2, 0x0, 0x0, - 0x5, 0x66, 0x66, 0x8c, 0x6c, 0xa6, 0x6d, 0x80, - 0x2, 0x0, 0x0, 0x0, 0xb6, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x0, 0x2c, 0x40, 0x1, 0x0, 0x0, - 0x0, 0x0, 0xd, 0xb1, 0x0, 0xad, 0x0, 0x0, - 0x0, 0x4, 0xbe, 0x10, 0x4c, 0x71, 0x0, 0x0, - 0x4, 0x86, 0xd, 0x58, 0x50, 0x0, 0x40, 0x0, - 0x12, 0x0, 0xd, 0x30, 0x0, 0x0, 0x60, 0x0, - 0x0, 0x0, 0xd, 0x20, 0x0, 0x0, 0x95, 0x0, - 0x0, 0x0, 0x8, 0xed, 0xdd, 0xdd, 0xf8, 0x0, - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - - /* U+8003 "考" */ - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x0, 0xd, 0x20, 0x0, 0x20, 0x0, - 0x0, 0x0, 0x0, 0xe, 0x0, 0x6, 0xd0, 0x0, - 0x0, 0x5, 0x66, 0x6e, 0x6c, 0x6d, 0x20, 0x0, - 0x0, 0x0, 0x0, 0xe, 0x1, 0xc2, 0x0, 0x0, - 0x0, 0x0, 0x0, 0xe, 0x1c, 0x30, 0x1, 0x80, - 0x7, 0x66, 0x66, 0x67, 0xe6, 0x66, 0x66, 0x62, - 0x0, 0x0, 0x0, 0x2c, 0x20, 0x0, 0x11, 0x0, - 0x0, 0x0, 0x5, 0xb9, 0x86, 0x66, 0x99, 0x0, - 0x0, 0x1, 0x95, 0x6, 0x70, 0x0, 0x0, 0x0, - 0x1, 0x56, 0x0, 0xd, 0x76, 0x66, 0xb3, 0x0, - 0x2, 0x0, 0x0, 0x3, 0x0, 0x0, 0xe0, 0x0, - 0x0, 0x0, 0x0, 0x0, 0x0, 0x2, 0xb0, 0x0, - 0x0, 0x0, 0x0, 0x1, 0x0, 0x6, 0x70, 0x0, - 0x0, 0x0, 0x0, 0x1, 0x6b, 0xae, 0x20, 0x0, - 0x0, 0x0, 0x0, 0x0, 0x3, 0x72, 0x0, 0x0, - - /* U+8005 "者" */ - 0x0, 0x0, 0x0, 0x19, 0x10, 0x0, 0x10, 0x0, - 0x0, 0x0, 0x0, 0x1c, 0x1, 0x5, 0xd0, 0x0, - 0x0, 0x6, 0x66, 0x6d, 0x7e, 0x4e, 0x30, 0x0, - 0x0, 0x0, 0x0, 0x1c, 0x0, 0xc5, 0x0, 0x0, - 0x0, 0x0, 0x0, 0x1c, 0xa, 0x60, 0x4, 0x40, - 0x6, 0x76, 0x66, 0x68, 0xc9, 0x66, 0x68, 0x80, - 0x0, 0x0, 0x0, 0xa, 0x50, 0x0, 0x0, 0x0, - 0x0, 0x0, 0xa, 0xd8, 0x66, 0x6c, 0x30, 0x0, - 0x0, 0x0, 0x7e, 0x0, 0x0, 0xe, 0x0, 0x0, - 0x0, 0x29, 0x4e, 0x0, 0x0, 0xe, 0x0, 0x0, - 0x5, 0x40, 0xe, 0x66, 0x66, 0x6e, 0x0, 0x0, - 0x0, 0x0, 0xe, 0x0, 0x0, 0xe, 0x0, 0x0, - 0x0, 0x0, 0xe, 0x0, 0x0, 0xe, 0x0, 0x0, - 0x0, 0x0, 0xe, 0x66, 0x66, 0x6e, 0x0, 0x0, - 0x0, 0x0, 0x5, 0x0, 0x0, 0x3, 0x0, 0x0, - - /* U+800C "而" */ - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x4, 0x2, - 0x86, 0x66, 0x66, 0x87, 0x66, 0x67, 0xc4, 0x0, - 0x0, 0x0, 0xd, 0x10, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x3, 0x70, 0x0, 0x0, 0x0, 0x0, 0x86, - 0x66, 0x96, 0x66, 0x66, 0xb3, 0x0, 0xb, 0x20, - 0x3a, 0x0, 0xd0, 0xe, 0x10, 0x0, 0xb2, 0x3, - 0xa0, 0xd, 0x0, 0xe0, 0x0, 0xb, 0x20, 0x3a, - 0x0, 0xd0, 0xe, 0x0, 0x0, 0xb2, 0x3, 0xa0, - 0xd, 0x0, 0xe0, 0x0, 0xb, 0x20, 0x3a, 0x0, - 0xd0, 0xe, 0x0, 0x0, 0xb2, 0x3, 0xa0, 0xd, - 0x0, 0xe0, 0x0, 0xb, 0x20, 0x3a, 0x0, 0xd0, - 0xe, 0x0, 0x0, 0xc2, 0x3, 0xa0, 0xd, 0x10, - 0xe0, 0x0, 0xb, 0x10, 0x12, 0x0, 0x35, 0xec, - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x2, 0x0, - 0x0, - - /* U+8033 "耳" */ - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8, 0x10, - 0x4, 0x76, 0xf6, 0x66, 0x66, 0xe6, 0x66, 0x30, - 0x0, 0x0, 0xf0, 0x0, 0x0, 0xd1, 0x0, 0x0, - 0x0, 0x0, 0xf0, 0x0, 0x0, 0xd1, 0x0, 0x0, - 0x0, 0x0, 0xf6, 0x66, 0x66, 0xe1, 0x0, 0x0, - 0x0, 0x0, 0xf0, 0x0, 0x0, 0xd1, 0x0, 0x0, - 0x0, 0x0, 0xf0, 0x0, 0x0, 0xd1, 0x0, 0x0, - 0x0, 0x0, 0xf6, 0x66, 0x66, 0xe1, 0x0, 0x0, - 0x0, 0x0, 0xf0, 0x0, 0x0, 0xd1, 0x0, 0x0, - 0x0, 0x0, 0xf0, 0x0, 0x0, 0xd1, 0x17, 0x90, - 0x2, 0x45, 0xe5, 0x55, 0x55, 0xe6, 0x43, 0x10, - 0x4, 0x20, 0x0, 0x0, 0x0, 0xe1, 0x0, 0x0, - 0x0, 0x0, 0x0, 0x0, 0x0, 0xe1, 0x0, 0x0, - 0x0, 0x0, 0x0, 0x0, 0x0, 0xe1, 0x0, 0x0, - 0x0, 0x0, 0x0, 0x0, 0x0, 0x40, 0x0, 0x0, - - /* U+805E "聞" */ - 0x19, 0x66, 0x68, 0x80, 0x96, 0x66, 0x7a, 0x0, - 0xc0, 0x0, 0x57, 0xd, 0x0, 0x2, 0xb0, 0xd, - 0x66, 0x69, 0x70, 0xd6, 0x66, 0x7b, 0x0, 0xc0, - 0x0, 0x57, 0xd, 0x0, 0x2, 0xb0, 0xd, 0x66, - 0x69, 0x60, 0xd6, 0x66, 0x7b, 0x0, 0xc0, 0x0, - 0x0, 0x0, 0x2, 0x2, 0xb0, 0xc, 0x6, 0x69, - 0x66, 0x78, 0xa6, 0x2b, 0x0, 0xc0, 0x1, 0xc0, - 0x5, 0x80, 0x2, 0xb0, 0xc, 0x0, 0x1d, 0x66, - 0x98, 0x0, 0x2b, 0x0, 0xc0, 0x1, 0xd6, 0x69, - 0x80, 0x2, 0xb0, 0xc, 0x0, 0x1c, 0x0, 0x58, - 0x3, 0x2b, 0x0, 0xc2, 0x35, 0xd5, 0x59, 0xb6, - 0xa5, 0xb0, 0xc, 0x12, 0x10, 0x0, 0x58, 0x12, - 0x3a, 0x1, 0xc0, 0x0, 0x0, 0x4, 0x50, 0x6f, - 0x80, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x20, - 0x0, - - /* U+806F "聯" */ - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x0, 0x20, 0xc5, 0x0, 0x56, 0x0, - 0x7, 0xa6, 0x6b, 0x95, 0x90, 0x10, 0xa0, 0x0, - 0x0, 0xd0, 0xd, 0x18, 0x8, 0x85, 0x31, 0xd1, - 0x0, 0xd0, 0xd, 0x7a, 0xa8, 0xd, 0x7b, 0x30, - 0x0, 0xd6, 0x6d, 0x2, 0x75, 0x2, 0x53, 0x50, - 0x0, 0xd0, 0xd, 0x27, 0x19, 0x46, 0x63, 0xc2, - 0x0, 0xd0, 0xd, 0x7a, 0x55, 0x56, 0x73, 0x62, - 0x0, 0xd6, 0x6d, 0x0, 0x2, 0x90, 0xb0, 0x0, - 0x0, 0xd0, 0xd, 0xb, 0x21, 0xa0, 0xc0, 0xb0, - 0x0, 0xd0, 0xd, 0x3c, 0x1, 0xa0, 0xc0, 0xc0, - 0x16, 0xea, 0x8d, 0xc, 0x57, 0xa0, 0xc0, 0xc0, - 0xb, 0x50, 0xd, 0x7, 0x44, 0x80, 0xd6, 0x90, - 0x0, 0x0, 0xd, 0x0, 0xa, 0x20, 0xc0, 0x0, - 0x0, 0x0, 0xe, 0x3, 0x84, 0x0, 0xc0, 0x0, - 0x0, 0x0, 0x3, 0x33, 0x0, 0x0, 0x40, 0x0, - - /* U+8072 "聲" */ - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, 0xb1, 0x1, 0x6, 0x33, 0x70, 0x0, - 0x6, 0x76, 0xd6, 0x7a, 0x1b, 0x33, 0xc0, 0x0, - 0x1, 0x33, 0xc3, 0x61, 0x37, 0x0, 0xd7, 0x91, - 0x0, 0x73, 0x33, 0x53, 0x82, 0x22, 0x56, 0x30, - 0x0, 0xd6, 0xc6, 0xd3, 0x29, 0x44, 0xc5, 0x0, - 0x0, 0xc0, 0xc0, 0xb0, 0x1, 0x9a, 0x50, 0x0, - 0x1, 0xc6, 0x66, 0x60, 0x4, 0x7a, 0x83, 0x10, - 0x5, 0x50, 0x0, 0x3, 0x41, 0x0, 0x8a, 0x90, - 0x7, 0x37, 0xa8, 0x66, 0x66, 0x6d, 0x64, 0x0, - 0x0, 0x0, 0x88, 0x66, 0x66, 0x6c, 0x0, 0x0, - 0x0, 0x0, 0x84, 0x0, 0x0, 0x1c, 0x0, 0x0, - 0x0, 0x0, 0x88, 0x66, 0x66, 0x6c, 0x2, 0x40, - 0x2, 0x45, 0xa8, 0x66, 0x66, 0x6d, 0x57, 0x80, - 0x1, 0x10, 0x0, 0x0, 0x0, 0x1d, 0x0, 0x0, - 0x0, 0x0, 0x0, 0x0, 0x0, 0x15, 0x0, 0x0, - - /* U+8077 "職" */ - 0x0, 0x0, 0x0, 0x40, 0x80, 0x4, 0x50, 0x0, - 0x7, 0xb6, 0x6b, 0x83, 0x75, 0x45, 0x82, 0x0, - 0x0, 0xc0, 0xc, 0x37, 0x66, 0x86, 0x88, 0x40, - 0x0, 0xc0, 0xc, 0x7, 0x2, 0xc4, 0x82, 0xa0, - 0x0, 0xd6, 0x6c, 0x7, 0x56, 0x24, 0x80, 0x0, - 0x0, 0xc0, 0xc, 0x57, 0x79, 0x68, 0xb8, 0xb0, - 0x0, 0xc0, 0xc, 0x12, 0x0, 0x13, 0x83, 0x50, - 0x0, 0xd6, 0x6c, 0xd, 0x69, 0x92, 0x98, 0x70, - 0x0, 0xc0, 0xc, 0xc, 0x5, 0x70, 0xab, 0x0, - 0x0, 0xc0, 0xc, 0x1d, 0x69, 0x70, 0xca, 0x0, - 0x4, 0xd9, 0x7d, 0x2c, 0x5, 0x70, 0xb4, 0x2, - 0x9, 0x50, 0xc, 0xd, 0x69, 0x73, 0xa9, 0x32, - 0x0, 0x0, 0xc, 0x8, 0x2, 0x38, 0xa, 0xc0, - 0x0, 0x0, 0xc, 0x0, 0x1, 0x60, 0x1, 0xd1, - 0x0, 0x0, 0x1, 0x0, 0x1, 0x0, 0x0, 0x0, - - /* U+807D "聽" */ - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x0, 0x40, 0x0, 0x4a, 0x0, 0x0, - 0x7, 0xb6, 0x6a, 0xaa, 0x44, 0x98, 0x47, 0xa0, - 0x0, 0xc6, 0x6b, 0x21, 0x10, 0x80, 0x1, 0x0, - 0x0, 0xc0, 0x9, 0x22, 0x96, 0xa7, 0x7b, 0x60, - 0x0, 0xc6, 0x6b, 0x21, 0xa1, 0xa5, 0x68, 0x40, - 0x0, 0xc0, 0x9, 0x21, 0xa1, 0xa5, 0x68, 0x40, - 0x7, 0xa6, 0x6b, 0x21, 0xa1, 0xa5, 0x68, 0x40, - 0x0, 0x0, 0x49, 0x22, 0xb6, 0x66, 0x69, 0x20, - 0x5, 0x8b, 0x59, 0x22, 0x22, 0x22, 0x25, 0x90, - 0x0, 0x38, 0x39, 0x23, 0x53, 0x53, 0x33, 0x30, - 0x4, 0x8b, 0x59, 0x20, 0x29, 0x4a, 0x4, 0x10, - 0x0, 0x38, 0x9, 0x24, 0x4c, 0x8, 0x14, 0xd1, - 0x8, 0x97, 0x39, 0x3e, 0xc, 0x0, 0x7, 0x71, - 0x3, 0x0, 0xa, 0x32, 0xb, 0xbb, 0xbc, 0x0, - 0x0, 0x0, 0x4, 0x0, 0x0, 0x0, 0x0, 0x0, - - /* U+8089 "肉" */ - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0xa6, 0x0, 0x0, 0x0, 0x10, 0x0, 0xa, - 0x40, 0x0, 0x1, 0xd, 0x66, 0x66, 0xd7, 0x66, - 0x67, 0xf1, 0xe1, 0x0, 0xe, 0x0, 0x0, 0x1d, - 0xd, 0x10, 0x7, 0x99, 0x70, 0x1, 0xd0, 0xd1, - 0x3, 0xa0, 0x8, 0xe2, 0x1d, 0xd, 0x14, 0x70, - 0xa7, 0x9, 0x61, 0xd0, 0xd3, 0x20, 0xe, 0x20, - 0x0, 0x1d, 0xd, 0x10, 0x6, 0xb7, 0x10, 0x1, - 0xd0, 0xd1, 0x2, 0xc0, 0x1c, 0x80, 0x1d, 0xd, - 0x12, 0xa1, 0x0, 0x1e, 0x41, 0xd0, 0xe3, 0x50, - 0x0, 0x0, 0x31, 0x1d, 0xe, 0x10, 0x0, 0x0, - 0x5, 0x68, 0xd0, 0xe1, 0x0, 0x0, 0x0, 0x4, - 0xf7, 0x1, 0x0, 0x0, 0x0, 0x0, 0x1, 0x0, - - /* U+80A9 "肩" */ - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x7, 0x80, 0x0, 0x0, 0x0, 0x3, - 0x0, 0x0, 0xa0, 0x0, 0x14, 0x0, 0xe, 0x66, - 0x66, 0x66, 0x66, 0x9a, 0x0, 0xe, 0x10, 0x0, - 0x0, 0x0, 0x68, 0x0, 0xd, 0x66, 0x66, 0x66, - 0x66, 0x98, 0x0, 0xd, 0x0, 0x0, 0x0, 0x0, - 0x20, 0x0, 0xd, 0xc, 0x66, 0x66, 0x66, 0xe3, - 0x0, 0xd, 0xc, 0x10, 0x0, 0x0, 0xe0, 0x0, - 0xd, 0xc, 0x66, 0x66, 0x66, 0xe0, 0x0, 0x2a, - 0xc, 0x10, 0x0, 0x0, 0xe0, 0x0, 0x75, 0xc, - 0x66, 0x66, 0x66, 0xe0, 0x0, 0xb0, 0xc, 0x10, - 0x0, 0x0, 0xe0, 0x5, 0x40, 0xc, 0x10, 0x1, - 0x10, 0xe0, 0x16, 0x0, 0xd, 0x10, 0x1, 0x7f, - 0xc0, 0x0, 0x0, 0x2, 0x0, 0x0, 0x2, 0x10, - - /* U+80AF "肯" */ - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x3, 0x0, 0xe, 0x10, 0x0, 0x0, 0x0, - 0x2, 0xf2, 0x0, 0xe0, 0x0, 0x70, 0x0, 0x0, - 0x1e, 0x0, 0xf, 0x66, 0x67, 0x30, 0x0, 0x1, - 0xe0, 0x0, 0xe0, 0x0, 0x5, 0x2, 0x86, 0x6a, - 0x66, 0x6a, 0x66, 0x66, 0xa6, 0x0, 0x1, 0x0, - 0x0, 0x0, 0x3, 0x0, 0x0, 0x0, 0xa8, 0x66, - 0x66, 0x66, 0xf4, 0x0, 0x0, 0xa, 0x40, 0x0, - 0x0, 0xe, 0x0, 0x0, 0x0, 0xa8, 0x66, 0x66, - 0x66, 0xf0, 0x0, 0x0, 0xa, 0x40, 0x0, 0x0, - 0xe, 0x0, 0x0, 0x0, 0xa8, 0x66, 0x66, 0x66, - 0xf0, 0x0, 0x0, 0xa, 0x40, 0x0, 0x0, 0xe, - 0x0, 0x0, 0x0, 0xa4, 0x0, 0x0, 0x0, 0xe0, - 0x0, 0x0, 0xb, 0x50, 0x0, 0x17, 0xee, 0x0, - 0x0, 0x0, 0x40, 0x0, 0x0, 0x3, 0x20, 0x0, - - /* U+80B2 "育" */ - 0x0, 0x0, 0x0, 0x93, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x48, 0x0, 0x1, 0x90, 0x47, 0x66, - 0x6d, 0xa6, 0x66, 0x66, 0x62, 0x0, 0x1, 0x98, - 0x10, 0x16, 0x20, 0x0, 0x0, 0x7a, 0x43, 0x34, - 0x46, 0xeb, 0x0, 0x0, 0x6a, 0x76, 0x43, 0x10, - 0xc, 0x20, 0x0, 0xa, 0x66, 0x66, 0x66, 0xc2, - 0x0, 0x0, 0xe, 0x0, 0x0, 0x0, 0xe0, 0x0, - 0x0, 0xe, 0x66, 0x66, 0x66, 0xe0, 0x0, 0x0, - 0xe, 0x0, 0x0, 0x0, 0xe0, 0x0, 0x0, 0xe, - 0x66, 0x66, 0x66, 0xe0, 0x0, 0x0, 0xe, 0x0, - 0x0, 0x0, 0xe0, 0x0, 0x0, 0xe, 0x0, 0x0, - 0x21, 0xe0, 0x0, 0x0, 0xe, 0x0, 0x0, 0x4c, - 0xc0, 0x0, 0x0, 0x4, 0x0, 0x0, 0x1, 0x0, - 0x0, - - /* U+80CC "背" */ - 0x0, 0x0, 0x3, 0x90, 0xa, 0x10, 0x0, 0x0, - 0x2, 0x66, 0x67, 0xb0, 0xe, 0x0, 0x8d, 0x0, - 0x0, 0x10, 0x3, 0xb0, 0xe, 0x67, 0x51, 0x10, - 0x0, 0x2, 0x57, 0xb0, 0xe, 0x0, 0x0, 0x60, - 0xb, 0xc6, 0x23, 0xb0, 0xc, 0xca, 0xac, 0xd0, - 0x0, 0x0, 0x2, 0x60, 0x0, 0x34, 0x33, 0x0, - 0x0, 0x0, 0xb6, 0x66, 0x66, 0x6c, 0x80, 0x0, - 0x0, 0x0, 0xe0, 0x0, 0x0, 0xb, 0x40, 0x0, - 0x0, 0x0, 0xf6, 0x66, 0x66, 0x6d, 0x30, 0x0, - 0x0, 0x0, 0xe0, 0x0, 0x0, 0xb, 0x30, 0x0, - 0x0, 0x0, 0xf6, 0x66, 0x66, 0x6d, 0x30, 0x0, - 0x0, 0x0, 0xe0, 0x0, 0x0, 0xb, 0x30, 0x0, - 0x0, 0x0, 0xe0, 0x0, 0x0, 0xc, 0x30, 0x0, - 0x0, 0x0, 0xe0, 0x0, 0x16, 0xcf, 0x10, 0x0, - 0x0, 0x0, 0x60, 0x0, 0x0, 0x23, 0x0, 0x0, - - /* U+80F8 "胸" */ - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x20, 0x3, 0x0, 0xb2, 0x0, 0x0, 0x0, - 0x0, 0xd6, 0x6e, 0x21, 0xc0, 0x0, 0x0, 0x0, - 0x0, 0xd0, 0xd, 0x7, 0x96, 0x66, 0x66, 0xb0, - 0x0, 0xd0, 0xd, 0xa, 0x0, 0x52, 0x0, 0xc0, - 0x0, 0xd6, 0x6e, 0x42, 0x50, 0xc6, 0x0, 0xc0, - 0x0, 0xd0, 0xd, 0x11, 0x44, 0xd0, 0x0, 0xc0, - 0x0, 0xd0, 0xd, 0xc, 0x1c, 0x70, 0xc0, 0xc0, - 0x0, 0xd0, 0xd, 0xc, 0xa, 0x40, 0xb0, 0xc0, - 0x0, 0xe6, 0x6e, 0xc, 0x19, 0xb0, 0xb0, 0xb0, - 0x0, 0xc0, 0xd, 0xc, 0x61, 0xb0, 0xb0, 0xb0, - 0x2, 0xa0, 0xd, 0xc, 0x30, 0x40, 0xb1, 0xb0, - 0x5, 0x60, 0xd, 0x9, 0x66, 0x66, 0xa2, 0xa0, - 0x8, 0x13, 0x3e, 0x0, 0x0, 0x14, 0x38, 0x80, - 0x6, 0x1, 0xba, 0x0, 0x0, 0x1, 0x8f, 0x30, - 0x10, 0x0, 0x0, 0x0, 0x0, 0x0, 0x1, 0x0, - - /* U+80FD "能" */ - 0x0, 0x9, 0x10, 0x0, 0x40, 0x0, 0x0, 0x0, - 0x6, 0xa1, 0x0, 0xc, 0x30, 0x21, 0x0, 0x2, - 0x90, 0x8, 0x0, 0xc1, 0x2d, 0x60, 0x3, 0x91, - 0x11, 0x7c, 0xc, 0x77, 0x10, 0x0, 0x6b, 0x85, - 0x42, 0xc1, 0xc1, 0x0, 0x23, 0x0, 0x40, 0x0, - 0x61, 0xb, 0x40, 0x5, 0x90, 0xe, 0x55, 0x5e, - 0x20, 0x4a, 0xaa, 0xa5, 0x0, 0xe6, 0x66, 0xe0, - 0x7, 0x10, 0x1, 0x0, 0xe, 0x0, 0xd, 0x0, - 0xe0, 0x9, 0xb0, 0x0, 0xe0, 0x0, 0xd0, 0xd, - 0x9, 0x70, 0x0, 0xe, 0x66, 0x6e, 0x0, 0xd5, - 0x0, 0x1, 0x0, 0xe0, 0x0, 0xd0, 0xd, 0x0, - 0x0, 0x60, 0xe, 0x0, 0xd, 0x0, 0xd0, 0x0, - 0x1a, 0x0, 0xe0, 0x4c, 0xd0, 0xa, 0xcc, 0xcd, - 0xb0, 0x3, 0x0, 0x21, 0x0, 0x0, 0x0, 0x0, - 0x0, - - /* U+8131 "脱" */ - 0x0, 0x30, 0x4, 0x1, 0x20, 0x1, 0x90, 0x0, - 0x0, 0xd6, 0x6e, 0x10, 0xb2, 0x6, 0x70, 0x0, - 0x0, 0xd0, 0xd, 0x0, 0x77, 0x9, 0x0, 0x0, - 0x0, 0xd0, 0xd, 0x5, 0x43, 0x37, 0x44, 0x0, - 0x0, 0xd6, 0x6d, 0xd, 0x44, 0x44, 0x87, 0x0, - 0x0, 0xd0, 0xd, 0xd, 0x0, 0x0, 0x56, 0x0, - 0x0, 0xd0, 0xd, 0xd, 0x0, 0x0, 0x56, 0x0, - 0x0, 0xd6, 0x6d, 0xd, 0x6b, 0x5a, 0x96, 0x0, - 0x0, 0xc0, 0xd, 0x7, 0x1d, 0xc, 0x10, 0x0, - 0x0, 0xc0, 0xd, 0x0, 0x2b, 0xc, 0x0, 0x0, - 0x0, 0xa0, 0xd, 0x0, 0x49, 0xc, 0x0, 0x10, - 0x3, 0x60, 0xd, 0x0, 0x85, 0xc, 0x0, 0x50, - 0x7, 0x13, 0x4d, 0x2, 0xc0, 0xd, 0x0, 0xa0, - 0x6, 0x0, 0x89, 0x38, 0x10, 0xb, 0xbb, 0xb0, - 0x10, 0x0, 0x1, 0x20, 0x0, 0x0, 0x0, 0x0, - - /* U+814A "腊" */ - 0x0, 0x30, 0x4, 0x0, 0x76, 0xa, 0x30, 0x0, - 0x0, 0xd6, 0x6e, 0x10, 0x84, 0xc, 0x0, 0x0, - 0x0, 0xd0, 0xd, 0x26, 0xb8, 0x6d, 0x7c, 0x10, - 0x0, 0xd0, 0xd, 0x1, 0x84, 0xc, 0x0, 0x0, - 0x0, 0xd6, 0x6d, 0x0, 0x84, 0xc, 0x0, 0x0, - 0x0, 0xd0, 0xd, 0x46, 0xb8, 0x6d, 0x6b, 0x90, - 0x0, 0xd0, 0xd, 0x10, 0x0, 0x0, 0x0, 0x0, - 0x0, 0xd3, 0x3d, 0x4, 0x0, 0x0, 0x33, 0x0, - 0x0, 0xd3, 0x3d, 0xc, 0x66, 0x66, 0xa9, 0x0, - 0x0, 0xc0, 0xd, 0xc, 0x0, 0x0, 0x66, 0x0, - 0x0, 0xb0, 0xd, 0xc, 0x66, 0x66, 0xa6, 0x0, - 0x3, 0x80, 0xd, 0xc, 0x0, 0x0, 0x66, 0x0, - 0x7, 0x22, 0x1d, 0xc, 0x66, 0x66, 0xa6, 0x0, - 0x6, 0x3, 0xca, 0xd, 0x0, 0x0, 0x66, 0x0, - 0x10, 0x0, 0x10, 0x1, 0x0, 0x0, 0x0, 0x0, - - /* U+8155 "腕" */ - 0x0, 0x0, 0x0, 0x0, 0x1, 0x80, 0x0, 0x0, - 0x0, 0xb6, 0x6d, 0x1, 0x0, 0x96, 0x0, 0x0, - 0x0, 0xd0, 0xd, 0xa, 0x66, 0x97, 0x67, 0xb0, - 0x0, 0xd0, 0xd, 0x49, 0x71, 0x0, 0x6, 0x20, - 0x0, 0xd3, 0x3d, 0x21, 0xd0, 0x0, 0x1, 0x0, - 0x0, 0xd2, 0x2d, 0x5, 0x82, 0x3a, 0x6d, 0x10, - 0x0, 0xd0, 0xd, 0xa, 0x6a, 0x9b, 0xc, 0x0, - 0x0, 0xd0, 0xd, 0x1a, 0x9, 0x4b, 0xc, 0x0, - 0x0, 0xe6, 0x6d, 0x67, 0x5c, 0x1b, 0xc, 0x0, - 0x0, 0xc0, 0xd, 0x10, 0x6b, 0xb, 0xc, 0x0, - 0x2, 0xa0, 0xd, 0x0, 0x84, 0xb, 0x99, 0x10, - 0x5, 0x60, 0xd, 0x2, 0xa0, 0xb, 0x0, 0x50, - 0x8, 0x11, 0x2c, 0x9, 0x0, 0xb, 0x0, 0xa0, - 0x7, 0x3, 0xc9, 0x71, 0x0, 0xc, 0xbb, 0xc2, - 0x10, 0x0, 0x2, 0x0, 0x0, 0x0, 0x0, 0x0, - - /* U+8166 "腦" */ - 0x0, 0x30, 0x4, 0x1, 0x90, 0x16, 0x4, 0x10, - 0xd, 0x66, 0xe1, 0x6a, 0x6, 0x90, 0xc5, 0x0, - 0xd0, 0xd, 0xa, 0x0, 0xa0, 0x28, 0x0, 0xd, - 0x0, 0xd4, 0x30, 0x62, 0x8, 0x0, 0x0, 0xd6, - 0x6d, 0xa, 0x21, 0xa2, 0x49, 0x10, 0xd, 0x0, - 0xd0, 0x4d, 0x33, 0xe0, 0x6c, 0x0, 0xd0, 0xd, - 0x0, 0x8b, 0x35, 0x0, 0x40, 0xd, 0x66, 0xd0, - 0xb6, 0x96, 0x66, 0xd3, 0x0, 0xc0, 0xd, 0xd, - 0x0, 0x4, 0x5c, 0x0, 0xc, 0x0, 0xd0, 0xd2, - 0x61, 0xc3, 0xc0, 0x0, 0xa0, 0xd, 0xd, 0x1, - 0xe8, 0xc, 0x0, 0x36, 0x0, 0xd0, 0xd0, 0x67, - 0xc5, 0xc0, 0x7, 0x10, 0xc, 0xd, 0x55, 0x2, - 0x9c, 0x0, 0x60, 0x6e, 0x90, 0xd6, 0x66, 0x66, - 0xd1, 0x20, 0x0, 0x30, 0x7, 0x0, 0x0, 0x6, - 0x0, - - /* U+8170 "腰" */ - 0x0, 0x30, 0x4, 0x0, 0x0, 0x0, 0x0, 0x10, - 0x0, 0xe6, 0x6e, 0x57, 0x69, 0x69, 0x69, 0x90, - 0x0, 0xd0, 0xc, 0x0, 0xc, 0xc, 0x0, 0x0, - 0x0, 0xd0, 0xc, 0x3a, 0x6d, 0x6d, 0x6c, 0x30, - 0x0, 0xd6, 0x6c, 0x29, 0xc, 0xc, 0xb, 0x10, - 0x0, 0xd0, 0xc, 0x29, 0xc, 0xc, 0xb, 0x10, - 0x0, 0xd0, 0xc, 0x3b, 0x6a, 0x6a, 0x6d, 0x20, - 0x0, 0xd3, 0x3c, 0x13, 0xc, 0x30, 0x3, 0x0, - 0x0, 0xd3, 0x3c, 0x0, 0x2c, 0x0, 0x2, 0x70, - 0x0, 0xc0, 0xc, 0x66, 0xc7, 0x68, 0xb6, 0x61, - 0x1, 0xa0, 0xc, 0x2, 0xa0, 0x8, 0x30, 0x0, - 0x4, 0x60, 0xc, 0x5, 0x85, 0x3a, 0x0, 0x0, - 0x7, 0x11, 0x1c, 0x0, 0x4, 0xdb, 0x82, 0x0, - 0x7, 0x4, 0xe9, 0x2, 0x88, 0x0, 0x5e, 0x30, - 0x10, 0x0, 0x22, 0x44, 0x0, 0x0, 0x1, 0x20, - - /* U+819D "膝" */ - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x30, 0x0, 0x0, 0xd0, 0x0, 0x0, - 0x1, 0xc6, 0xd5, 0x46, 0x66, 0xe6, 0x6d, 0x70, - 0x1, 0xb0, 0xc1, 0x11, 0x1c, 0xe3, 0x0, 0x0, - 0x1, 0xb0, 0xc1, 0x0, 0xa3, 0xc4, 0xb7, 0x0, - 0x1, 0xd6, 0xd1, 0x9, 0x22, 0x50, 0xc, 0x80, - 0x1, 0xb0, 0xc2, 0x70, 0xb, 0xc0, 0x1, 0x40, - 0x1, 0xb0, 0xc1, 0x0, 0x89, 0x9, 0x20, 0x0, - 0x1, 0xb0, 0xc1, 0x7, 0x80, 0x92, 0xb9, 0x30, - 0x1, 0xc6, 0xd1, 0x77, 0x0, 0xd0, 0x67, 0xc2, - 0x2, 0x90, 0xc3, 0x3, 0xb0, 0xd7, 0x82, 0x0, - 0x4, 0x70, 0xc1, 0x0, 0x35, 0xe2, 0x0, 0x0, - 0x7, 0x30, 0xc1, 0x4, 0x92, 0xd5, 0xb5, 0x0, - 0x8, 0x0, 0xc0, 0xab, 0x0, 0xd0, 0x1c, 0x60, - 0x6, 0x2a, 0xd0, 0x10, 0x4b, 0xc0, 0x1, 0x30, - 0x10, 0x0, 0x10, 0x0, 0x3, 0x30, 0x0, 0x0, - - /* U+81C9 "臉" */ - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x30, 0x3, 0x0, 0x5, 0xc0, 0x0, 0x0, - 0x0, 0xd6, 0x7c, 0x0, 0xc, 0x63, 0x0, 0x0, - 0x0, 0xc0, 0x29, 0x0, 0x66, 0x7, 0x20, 0x0, - 0x0, 0xb0, 0x29, 0x2, 0x80, 0x1, 0xa4, 0x0, - 0x0, 0xd6, 0x79, 0x26, 0x56, 0x69, 0x6a, 0xb1, - 0x0, 0xb0, 0x29, 0x31, 0x2, 0x2, 0x0, 0x30, - 0x0, 0xb0, 0x29, 0xd, 0x6d, 0x1d, 0x67, 0xb0, - 0x0, 0xc4, 0x69, 0xb, 0xb, 0xb, 0x1, 0x90, - 0x0, 0xb1, 0x39, 0xc, 0x6c, 0xd, 0x66, 0x90, - 0x1, 0xa0, 0x29, 0x6, 0x43, 0x5, 0x52, 0x20, - 0x2, 0x70, 0x29, 0x2, 0xb0, 0x0, 0xd1, 0x0, - 0x6, 0x30, 0x29, 0x7, 0x91, 0x2, 0xd1, 0x0, - 0x7, 0x4, 0x78, 0x9, 0x1d, 0x1a, 0x28, 0x90, - 0x14, 0x2, 0xc2, 0x61, 0x2, 0x63, 0x0, 0xa1, - 0x0, 0x0, 0x0, 0x10, 0x0, 0x10, 0x0, 0x0, - - /* U+81EA "自" */ - 0x0, 0x2, 0xc2, 0x0, 0x0, 0x0, 0x0, 0x69, - 0x0, 0x0, 0x0, 0x40, 0x9, 0x0, 0x0, 0x17, - 0xe, 0x66, 0x66, 0x66, 0x68, 0xd1, 0xe1, 0x0, - 0x0, 0x0, 0x3b, 0xd, 0x10, 0x0, 0x0, 0x3, - 0xb0, 0xd6, 0x66, 0x66, 0x66, 0x8b, 0xd, 0x10, - 0x0, 0x0, 0x3, 0xb0, 0xd1, 0x0, 0x0, 0x0, - 0x3b, 0xd, 0x66, 0x66, 0x66, 0x68, 0xb0, 0xd1, - 0x0, 0x0, 0x0, 0x3b, 0xd, 0x10, 0x0, 0x0, - 0x3, 0xb0, 0xe1, 0x0, 0x0, 0x0, 0x3b, 0xe, - 0x66, 0x66, 0x66, 0x68, 0xc0, 0x70, 0x0, 0x0, - 0x0, 0x25, 0x0, - - /* U+81F3 "至" */ - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x35, 0x0, - 0x47, 0x66, 0x6a, 0xa6, 0x66, 0x68, 0x81, 0x0, - 0x0, 0x1, 0xd2, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0xb3, 0x1, 0x73, 0x0, 0x0, 0x0, 0x0, - 0x93, 0x0, 0x0, 0xab, 0x10, 0x0, 0x4, 0xa4, - 0x23, 0x45, 0x66, 0xde, 0x10, 0x0, 0x7e, 0xa7, - 0x5c, 0x50, 0x0, 0xc1, 0x0, 0x0, 0x0, 0x0, - 0xb3, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xb, - 0x30, 0x2, 0x70, 0x0, 0x5, 0x76, 0x66, 0xd8, - 0x66, 0x88, 0x10, 0x0, 0x0, 0x0, 0xb, 0x30, - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xb3, 0x0, - 0x0, 0x0, 0x0, 0x0, 0x0, 0xb, 0x30, 0x0, - 0x1c, 0x31, 0x86, 0x66, 0x66, 0x66, 0x66, 0x66, - 0x64, - - /* U+81FA "臺" */ - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x0, 0x0, 0xe1, 0x0, 0x3, 0x90, - 0x4, 0x76, 0x66, 0x66, 0xe6, 0x66, 0x76, 0x62, - 0x0, 0x7, 0x66, 0x66, 0xc6, 0x66, 0xb5, 0x0, - 0x0, 0x2, 0x86, 0x66, 0x66, 0x66, 0xc1, 0x0, - 0x0, 0x2, 0xb0, 0x0, 0x0, 0x1, 0xd0, 0x0, - 0x0, 0x2, 0xc6, 0x66, 0x66, 0x66, 0xb0, 0x0, - 0x1, 0xa6, 0x66, 0x66, 0x66, 0x66, 0x66, 0xd1, - 0xb, 0x50, 0x0, 0x0, 0x0, 0x3, 0x65, 0x81, - 0x8, 0x6, 0x66, 0xcc, 0x66, 0x86, 0x52, 0x0, - 0x0, 0x1, 0x57, 0x30, 0x0, 0x19, 0x80, 0x0, - 0x0, 0x6, 0xeb, 0xa9, 0xe6, 0x54, 0xa7, 0x0, - 0x0, 0x0, 0x0, 0x1, 0xd0, 0x1, 0xa1, 0x0, - 0x0, 0x6, 0x66, 0x66, 0xe6, 0x66, 0x62, 0x0, - 0x2, 0x66, 0x66, 0x66, 0xe6, 0x66, 0x6c, 0x90, - 0x0, 0x10, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - - /* U+8207 "與" */ - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x1, 0x29, 0x50, 0x0, 0x0, 0x0, 0x0, - 0xa6, 0xa7, 0xa3, 0x3, 0x66, 0xb8, 0x0, 0xe, - 0x0, 0xa, 0x76, 0x81, 0x8, 0x50, 0x0, 0xd0, - 0x50, 0xa3, 0x0, 0x0, 0x94, 0x0, 0xc, 0x66, - 0x3d, 0x76, 0xd4, 0x7c, 0x30, 0x0, 0xc1, 0x0, - 0x20, 0xd, 0x0, 0xa3, 0x0, 0xc, 0x15, 0x1c, - 0x20, 0xc0, 0xa, 0x20, 0x0, 0xb7, 0x63, 0xd0, - 0xc, 0x27, 0xc2, 0x0, 0xb, 0x20, 0xd, 0x0, - 0xc0, 0xb, 0x20, 0x16, 0xc6, 0x55, 0xd5, 0x5d, - 0x55, 0xdb, 0x60, 0x31, 0x11, 0x51, 0x11, 0x22, - 0x11, 0x10, 0x0, 0x0, 0xad, 0x20, 0x0, 0x69, - 0x40, 0x0, 0x0, 0xa9, 0x0, 0x0, 0x0, 0x1c, - 0xc1, 0x3, 0xa3, 0x0, 0x0, 0x0, 0x0, 0xc, - 0x61, 0x30, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - - /* U+8208 "興" */ - 0x0, 0x0, 0x33, 0x0, 0x2, 0x10, 0x0, 0x0, - 0x9, 0x96, 0xc6, 0x66, 0x98, 0x7b, 0x70, 0x0, - 0xd0, 0xc, 0x0, 0x56, 0x50, 0x93, 0x0, 0xc, - 0x32, 0xc5, 0x66, 0x85, 0xa, 0x20, 0x0, 0xb5, - 0x3c, 0x36, 0x87, 0x65, 0xd1, 0x0, 0xa, 0x10, - 0xc6, 0x5b, 0x65, 0xc, 0x10, 0x0, 0xa5, 0x3c, - 0x65, 0xb5, 0x50, 0xd0, 0x0, 0xa, 0x74, 0xc6, - 0x9c, 0x56, 0x7e, 0x0, 0x0, 0xa3, 0xc, 0x10, - 0x15, 0x50, 0xd0, 0x1, 0x6c, 0x86, 0xd6, 0x66, - 0x99, 0x6e, 0xd6, 0x1, 0x0, 0x6, 0x0, 0x2, - 0x20, 0x0, 0x0, 0x0, 0x9, 0xd2, 0x0, 0x5, - 0xb6, 0x0, 0x0, 0x9, 0x80, 0x0, 0x0, 0x1, - 0xce, 0x10, 0x38, 0x20, 0x0, 0x0, 0x0, 0x0, - 0xc4, 0x2, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, - - /* U+8209 "舉" */ - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x22, 0x6d, 0x5c, 0x3, 0x12, 0x36, 0x0, - 0x0, 0x5a, 0x20, 0x1d, 0x68, 0x46, 0x7b, 0x0, - 0x0, 0x4a, 0x48, 0x1c, 0x0, 0x3, 0x68, 0x0, - 0x0, 0x2b, 0x33, 0x5d, 0x6c, 0x75, 0x86, 0x0, - 0x0, 0x2a, 0x7, 0x5, 0xb, 0x20, 0x65, 0x0, - 0x0, 0x1d, 0x66, 0x2d, 0xc, 0x47, 0xb4, 0x0, - 0x0, 0xc, 0x0, 0x1c, 0xc, 0x10, 0x86, 0x50, - 0x6, 0x76, 0x6d, 0x97, 0x76, 0x86, 0x66, 0x60, - 0x0, 0x0, 0x7b, 0x1, 0xa0, 0x8, 0x0, 0x0, - 0x0, 0x6, 0x96, 0x76, 0xb6, 0xb4, 0xb1, 0x0, - 0x1, 0x85, 0x0, 0x1, 0x90, 0x0, 0x6e, 0xa1, - 0x4, 0x6, 0x76, 0x66, 0xb6, 0x69, 0xb4, 0x20, - 0x0, 0x0, 0x0, 0x1, 0x90, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x0, 0x1, 0x90, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x0, 0x0, 0x20, 0x0, 0x0, 0x0, - - /* U+822A "航" */ - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, 0xd2, 0x0, 0x2, 0x20, 0x0, 0x0, - 0x0, 0x11, 0x80, 0x10, 0x0, 0xc2, 0x0, 0x0, - 0x0, 0xc7, 0x66, 0xe0, 0x0, 0x52, 0x5, 0x0, - 0x0, 0xc2, 0x0, 0xd5, 0x66, 0x66, 0x69, 0x30, - 0x0, 0xc1, 0xa0, 0xd0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0xc1, 0x91, 0xd0, 0x87, 0x66, 0xc0, 0x0, - 0x0, 0xc1, 0x0, 0xd0, 0x84, 0x1, 0xb0, 0x0, - 0x17, 0xd6, 0x66, 0xd0, 0x84, 0x1, 0xb0, 0x0, - 0x0, 0xc1, 0x50, 0xd0, 0x93, 0x1, 0xb0, 0x0, - 0x0, 0xb0, 0xa3, 0xd0, 0xa2, 0x1, 0xb0, 0x0, - 0x0, 0xa0, 0x42, 0xd0, 0xb0, 0x1, 0xb0, 0x0, - 0x3, 0x70, 0x0, 0xd0, 0xa0, 0x1, 0xb0, 0x60, - 0x7, 0x10, 0x33, 0xc5, 0x40, 0x1, 0xb0, 0xa0, - 0x15, 0x0, 0x3e, 0x86, 0x0, 0x0, 0xcc, 0xd1, - 0x10, 0x0, 0x0, 0x10, 0x0, 0x0, 0x0, 0x0, - - /* U+822C "般" */ - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, 0xd1, 0x0, 0x10, 0x0, 0x20, 0x0, - 0x0, 0x24, 0x40, 0x40, 0x3c, 0x66, 0xe1, 0x0, - 0x0, 0x98, 0x66, 0xe2, 0x39, 0x0, 0xd0, 0x0, - 0x0, 0x95, 0x50, 0xd0, 0x48, 0x0, 0xd0, 0x0, - 0x0, 0x93, 0xb2, 0xd0, 0x74, 0x0, 0xdc, 0xe4, - 0x0, 0x93, 0x41, 0xd0, 0xa0, 0x0, 0x0, 0x0, - 0x0, 0x93, 0x0, 0xd6, 0x44, 0x44, 0x78, 0x0, - 0x7, 0xc8, 0x66, 0xd0, 0x26, 0x22, 0x99, 0x0, - 0x0, 0xa5, 0x40, 0xd0, 0x6, 0x0, 0xd1, 0x0, - 0x0, 0xb1, 0xc2, 0xd0, 0x5, 0x35, 0x90, 0x0, - 0x0, 0xc0, 0x51, 0xd0, 0x0, 0xbd, 0x10, 0x0, - 0x1, 0xa0, 0x0, 0xd0, 0x0, 0xbc, 0x10, 0x0, - 0x6, 0x30, 0x32, 0xc0, 0x1a, 0x44, 0xe6, 0x0, - 0x7, 0x0, 0x3d, 0x75, 0x81, 0x0, 0x2d, 0xd2, - 0x20, 0x0, 0x1, 0x31, 0x0, 0x0, 0x0, 0x20, - - /* U+8239 "船" */ - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, 0xd2, 0x0, 0x4, 0x0, 0x50, 0x0, - 0x0, 0x25, 0x40, 0x40, 0xd, 0x66, 0xe2, 0x0, - 0x0, 0xd6, 0x66, 0xe1, 0xc, 0x0, 0xd0, 0x0, - 0x0, 0xd1, 0x20, 0xd0, 0xc, 0x0, 0xd0, 0x0, - 0x0, 0xd0, 0xb1, 0xd0, 0x2a, 0x0, 0xd0, 0x0, - 0x0, 0xd0, 0x51, 0xd0, 0x64, 0x0, 0xac, 0xd1, - 0x15, 0xe5, 0x55, 0xd2, 0x60, 0x0, 0x0, 0x0, - 0x2, 0xd1, 0x11, 0xd3, 0x11, 0x0, 0x5, 0x0, - 0x0, 0xc1, 0x50, 0xd0, 0x2d, 0x66, 0x6e, 0x10, - 0x0, 0xb0, 0xb2, 0xd0, 0x1b, 0x0, 0x1c, 0x0, - 0x0, 0xa0, 0x31, 0xd0, 0x1b, 0x0, 0x1c, 0x0, - 0x4, 0x50, 0x0, 0xd0, 0x1b, 0x0, 0x1c, 0x0, - 0x8, 0x0, 0x44, 0xc0, 0x2d, 0x66, 0x6c, 0x0, - 0x15, 0x0, 0x1b, 0x50, 0x2b, 0x0, 0x1a, 0x0, - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - - /* U+826F "良" */ - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x5, 0x80, 0x0, 0x0, 0x0, 0x0, 0x0, 0xc, - 0x40, 0x0, 0x0, 0x0, 0xb6, 0x66, 0x96, 0x66, - 0xe1, 0x0, 0xb, 0x20, 0x0, 0x0, 0x1d, 0x0, - 0x0, 0xb2, 0x0, 0x0, 0x1, 0xd0, 0x0, 0xb, - 0x76, 0x66, 0x66, 0x6d, 0x0, 0x0, 0xb2, 0x0, - 0x0, 0x1, 0xd0, 0x0, 0xb, 0x76, 0x66, 0x66, - 0x6d, 0x0, 0x0, 0xb2, 0x6, 0x0, 0x0, 0x77, - 0x0, 0xb, 0x20, 0x26, 0x0, 0x7c, 0x70, 0x0, - 0xb2, 0x0, 0x87, 0x73, 0x0, 0x0, 0xb, 0x20, - 0x13, 0xb6, 0x0, 0x0, 0x0, 0xb5, 0x86, 0x0, - 0x9d, 0x84, 0x10, 0xc, 0xb1, 0x0, 0x0, 0x2a, - 0xfe, 0x40, 0x10, 0x0, 0x0, 0x0, 0x0, 0x10, - - /* U+8272 "色" */ - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, 0xc, 0x60, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x5e, 0x66, 0x6a, 0xa0, 0x0, 0x0, - 0x0, 0x1, 0xd2, 0x0, 0x2d, 0x50, 0x0, 0x0, - 0x0, 0xa, 0x50, 0x0, 0x92, 0x0, 0x0, 0x0, - 0x0, 0x7d, 0x66, 0x68, 0x86, 0x66, 0xc1, 0x0, - 0x5, 0x4d, 0x0, 0xa, 0x20, 0x0, 0xd0, 0x0, - 0x1, 0xd, 0x0, 0xa, 0x20, 0x0, 0xd0, 0x0, - 0x0, 0xd, 0x0, 0xa, 0x20, 0x0, 0xd0, 0x0, - 0x0, 0xd, 0x66, 0x67, 0x66, 0x66, 0xd0, 0x0, - 0x0, 0xd, 0x0, 0x0, 0x0, 0x0, 0x50, 0x0, - 0x0, 0xd, 0x0, 0x0, 0x0, 0x0, 0x0, 0x50, - 0x0, 0xd, 0x0, 0x0, 0x0, 0x0, 0x0, 0x70, - 0x0, 0xd, 0x0, 0x0, 0x0, 0x0, 0x2, 0xc1, - 0x0, 0xa, 0xdc, 0xcc, 0xcc, 0xcc, 0xcd, 0xa0, - - /* U+8282 "节" */ - 0x0, 0x0, 0x7, 0x20, 0x1, 0x80, 0x0, 0x0, - 0x0, 0x0, 0xb, 0x30, 0x1, 0xd0, 0x2, 0x0, - 0x26, 0x66, 0x6d, 0x76, 0x66, 0xe6, 0x6e, 0x90, - 0x1, 0x0, 0xb, 0x20, 0x1, 0xd0, 0x0, 0x0, - 0x0, 0x0, 0xa, 0x10, 0x0, 0x90, 0x0, 0x0, - 0x0, 0x56, 0x66, 0x66, 0x66, 0x66, 0xc1, 0x0, - 0x0, 0x10, 0x0, 0x77, 0x0, 0x1, 0xe0, 0x0, - 0x0, 0x0, 0x0, 0x77, 0x0, 0x1, 0xd0, 0x0, - 0x0, 0x0, 0x0, 0x77, 0x0, 0x1, 0xd0, 0x0, - 0x0, 0x0, 0x0, 0x77, 0x0, 0x1, 0xd0, 0x0, - 0x0, 0x0, 0x0, 0x77, 0x4, 0x44, 0xd0, 0x0, - 0x0, 0x0, 0x0, 0x77, 0x0, 0x5e, 0x80, 0x0, - 0x0, 0x0, 0x0, 0x77, 0x0, 0x1, 0x0, 0x0, - 0x0, 0x0, 0x0, 0x78, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x0, 0x20, 0x0, 0x0, 0x0, 0x0, - - /* U+82B1 "花" */ - 0x0, 0x0, 0x7, 0x50, 0x4, 0x60, 0x0, 0x0, - 0x0, 0x0, 0x8, 0x60, 0x5, 0x80, 0x2, 0x10, - 0x7, 0x66, 0x6b, 0x96, 0x69, 0xb6, 0x6c, 0x90, - 0x0, 0x0, 0x8, 0x60, 0x5, 0x80, 0x0, 0x0, - 0x0, 0x0, 0x7, 0x20, 0x3, 0x30, 0x0, 0x0, - 0x0, 0x0, 0x5d, 0x0, 0x8, 0x0, 0x0, 0x0, - 0x0, 0x0, 0xc3, 0x0, 0xe, 0x0, 0x6d, 0x0, - 0x0, 0x6, 0xd0, 0x0, 0xd, 0x6, 0xc2, 0x0, - 0x0, 0x2b, 0xd0, 0x0, 0xe, 0xa8, 0x0, 0x0, - 0x1, 0x91, 0xd0, 0x0, 0x7e, 0x20, 0x0, 0x0, - 0x16, 0x0, 0xd0, 0x57, 0x2d, 0x0, 0x0, 0x20, - 0x0, 0x0, 0xd0, 0x0, 0xd, 0x0, 0x0, 0x60, - 0x0, 0x0, 0xe0, 0x0, 0xe, 0x0, 0x0, 0xb0, - 0x0, 0x0, 0xe0, 0x0, 0xc, 0xdc, 0xcd, 0xd1, - 0x0, 0x0, 0x40, 0x0, 0x0, 0x0, 0x0, 0x0, - - /* U+82E5 "若" */ - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x7, 0x70, 0x1, 0xd1, 0x0, 0x0, - 0x0, 0x0, 0x7, 0x60, 0x0, 0xd0, 0x5, 0x10, - 0x2, 0x76, 0x6a, 0xa6, 0x66, 0xe6, 0x68, 0x60, - 0x0, 0x0, 0x8, 0x64, 0x0, 0xe0, 0x0, 0x0, - 0x0, 0x0, 0x3, 0x1e, 0x50, 0x10, 0x0, 0x0, - 0x0, 0x0, 0x0, 0x4c, 0x0, 0x0, 0x1, 0x50, - 0x5, 0x66, 0x66, 0xd9, 0x66, 0x66, 0x68, 0x92, - 0x0, 0x0, 0x4, 0xb0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x1d, 0x10, 0x0, 0x2, 0x40, 0x0, - 0x0, 0x1, 0xce, 0x66, 0x66, 0x69, 0xb0, 0x0, - 0x0, 0x2a, 0x3d, 0x0, 0x0, 0x5, 0x80, 0x0, - 0x4, 0x60, 0xd, 0x0, 0x0, 0x5, 0x80, 0x0, - 0x1, 0x0, 0xe, 0x66, 0x66, 0x69, 0x90, 0x0, - 0x0, 0x0, 0xd, 0x0, 0x0, 0x5, 0x80, 0x0, - 0x0, 0x0, 0x2, 0x0, 0x0, 0x0, 0x0, 0x0, - - /* U+82E6 "苦" */ - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, 0xd, 0x20, 0x0, 0xb1, 0x0, 0x0, - 0x0, 0x0, 0xe, 0x0, 0x0, 0xd0, 0x6, 0x40, - 0x17, 0x66, 0x6e, 0x66, 0x66, 0xe6, 0x67, 0x70, - 0x0, 0x0, 0xe, 0x3, 0x0, 0xd0, 0x0, 0x0, - 0x0, 0x0, 0x3, 0xc, 0x40, 0x20, 0x0, 0x0, - 0x0, 0x0, 0x0, 0xc, 0x0, 0x0, 0x8, 0x30, - 0x27, 0x66, 0x66, 0x6e, 0x66, 0x66, 0x67, 0x50, - 0x0, 0x0, 0x0, 0xd, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x9, 0x66, 0x6e, 0x66, 0x68, 0x70, 0x0, - 0x0, 0xd, 0x0, 0x0, 0x0, 0x7, 0x60, 0x0, - 0x0, 0xd, 0x0, 0x0, 0x0, 0x7, 0x60, 0x0, - 0x0, 0xd, 0x0, 0x0, 0x0, 0x7, 0x60, 0x0, - 0x0, 0xd, 0x0, 0x0, 0x0, 0x7, 0x60, 0x0, - 0x0, 0xd, 0x66, 0x66, 0x66, 0x6a, 0x60, 0x0, - 0x0, 0x5, 0x0, 0x0, 0x0, 0x2, 0x0, 0x0, - - /* U+82F1 "英" */ - 0x0, 0x0, 0xb, 0x20, 0x1, 0x91, 0x0, 0x0, - 0x0, 0x0, 0xd, 0x0, 0x1, 0xc0, 0x7, 0x60, - 0x8, 0x66, 0x6e, 0x66, 0x66, 0xd6, 0x66, 0x50, - 0x0, 0x0, 0xd, 0x9, 0x31, 0xb0, 0x0, 0x0, - 0x0, 0x0, 0x2, 0xc, 0x10, 0x0, 0x0, 0x0, - 0x0, 0xa, 0x66, 0x6d, 0x66, 0x6b, 0x80, 0x0, - 0x0, 0xc, 0x0, 0xd, 0x0, 0x8, 0x50, 0x0, - 0x0, 0xc, 0x0, 0xd, 0x0, 0x8, 0x50, 0x0, - 0x0, 0xc, 0x0, 0xe, 0x0, 0x8, 0x54, 0x30, - 0x28, 0x68, 0x66, 0x8d, 0x86, 0x67, 0x68, 0x70, - 0x0, 0x0, 0x0, 0xa5, 0x26, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x6, 0xb0, 0x6, 0x80, 0x0, 0x0, - 0x0, 0x0, 0x6b, 0x10, 0x0, 0x5d, 0x61, 0x0, - 0x0, 0x48, 0x40, 0x0, 0x0, 0x2, 0xbf, 0x90, - 0x4, 0x10, 0x0, 0x0, 0x0, 0x0, 0x2, 0x0, - - /* U+8336 "茶" */ - 0x0, 0x0, 0xb, 0x40, 0x0, 0xb1, 0x0, 0x0, - 0x0, 0x0, 0xd, 0x10, 0x0, 0xd0, 0x6, 0x80, - 0x6, 0x66, 0x6e, 0x66, 0x66, 0xe6, 0x66, 0x61, - 0x0, 0x0, 0xd, 0x8, 0xb0, 0xc0, 0x0, 0x0, - 0x0, 0x0, 0x2, 0x4c, 0x44, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x4, 0xc1, 0x4, 0x70, 0x0, 0x0, - 0x0, 0x0, 0x79, 0x2, 0x40, 0x3c, 0x71, 0x0, - 0x0, 0x47, 0x20, 0x3, 0xc0, 0x0, 0x9f, 0xc3, - 0x4, 0x26, 0x66, 0x68, 0xc6, 0x6a, 0xd2, 0x10, - 0x0, 0x2, 0x1, 0x3, 0xa0, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x6d, 0x3, 0xa1, 0x83, 0x0, 0x0, - 0x0, 0x3, 0xb1, 0x3, 0xa0, 0xb, 0x80, 0x0, - 0x0, 0x39, 0x1, 0x4, 0xa0, 0x0, 0xc8, 0x0, - 0x2, 0x40, 0x0, 0x8f, 0x70, 0x0, 0x24, 0x0, - 0x0, 0x0, 0x0, 0x3, 0x0, 0x0, 0x0, 0x0, - - /* U+8377 "荷" */ - 0x0, 0x0, 0xa, 0x40, 0x5, 0x70, 0x0, 0x0, - 0x0, 0x0, 0xb, 0x20, 0x6, 0x80, 0x7, 0x20, - 0x7, 0x66, 0x6d, 0x76, 0x69, 0xb6, 0x68, 0x60, - 0x0, 0x0, 0xb, 0x20, 0x6, 0x80, 0x0, 0x0, - 0x0, 0x0, 0xd3, 0x0, 0x1, 0x10, 0x2, 0x10, - 0x0, 0x7, 0x84, 0x76, 0x66, 0x66, 0x9b, 0x90, - 0x0, 0x1d, 0x0, 0x0, 0x0, 0x0, 0xe0, 0x0, - 0x0, 0x9f, 0x33, 0x86, 0x6c, 0x10, 0xe0, 0x0, - 0x5, 0x5e, 0x4, 0xa0, 0xd, 0x0, 0xe0, 0x0, - 0x24, 0xe, 0x3, 0xa0, 0xd, 0x0, 0xe0, 0x0, - 0x0, 0xe, 0x3, 0xa0, 0xd, 0x0, 0xe0, 0x0, - 0x0, 0xe, 0x4, 0xc6, 0x6c, 0x0, 0xe0, 0x0, - 0x0, 0xe, 0x3, 0x60, 0x0, 0x0, 0xe0, 0x0, - 0x0, 0xe, 0x0, 0x0, 0x1, 0x6b, 0xd0, 0x0, - 0x0, 0x7, 0x0, 0x0, 0x0, 0x6, 0x30, 0x0, - - /* U+83D3 "菓" */ - 0x0, 0x0, 0xb, 0x10, 0x3, 0x90, 0x0, 0x0, - 0x0, 0x0, 0xd0, 0x0, 0x3b, 0x1, 0x90, 0x8, - 0x66, 0x6e, 0x66, 0x67, 0xc6, 0x67, 0x30, 0x0, - 0x0, 0xb0, 0x0, 0x29, 0x20, 0x0, 0x0, 0xc, - 0x66, 0x6a, 0x66, 0x6c, 0x70, 0x0, 0x0, 0xc0, - 0x0, 0xe0, 0x0, 0xb3, 0x0, 0x0, 0xc, 0x66, - 0x6e, 0x66, 0x6c, 0x30, 0x0, 0x0, 0xc0, 0x0, - 0xe0, 0x0, 0xb3, 0x0, 0x0, 0xa, 0x66, 0x6e, - 0x66, 0x69, 0x20, 0x0, 0x26, 0x66, 0x66, 0xe6, - 0x66, 0x6e, 0x70, 0x0, 0x10, 0x2, 0xce, 0x35, - 0x0, 0x0, 0x0, 0x0, 0x3, 0xb1, 0xe0, 0x68, - 0x0, 0x0, 0x0, 0x6, 0x80, 0xe, 0x0, 0x6d, - 0x61, 0x0, 0x46, 0x20, 0x0, 0xe0, 0x0, 0x3c, - 0xe3, 0x10, 0x0, 0x0, 0x4, 0x0, 0x0, 0x0, - 0x0, - - /* U+83DC "菜" */ - 0x0, 0x0, 0xa, 0x30, 0xb, 0x10, 0x0, 0x0, - 0x0, 0x0, 0xb2, 0x0, 0xe0, 0x1, 0xb2, 0x27, - 0x66, 0x6d, 0x76, 0x6e, 0x66, 0x66, 0x40, 0x0, - 0x0, 0x81, 0x0, 0x95, 0xa5, 0x0, 0x0, 0x35, - 0x56, 0x78, 0x98, 0x65, 0x30, 0x0, 0x0, 0x10, - 0x2, 0x70, 0x0, 0xa4, 0x0, 0x0, 0x7, 0x80, - 0x7, 0x70, 0x2c, 0x0, 0x0, 0x0, 0xd, 0x0, - 0x62, 0x9, 0x10, 0x0, 0x0, 0x0, 0x0, 0xd, - 0x42, 0x10, 0x1c, 0x23, 0x76, 0x66, 0x6e, 0xe9, - 0x76, 0x66, 0x64, 0x0, 0x0, 0x9, 0x6c, 0x18, - 0x0, 0x0, 0x0, 0x0, 0x9, 0x60, 0xc1, 0x1b, - 0x20, 0x0, 0x0, 0x29, 0x30, 0xc, 0x10, 0x2c, - 0xa4, 0x10, 0x56, 0x0, 0x0, 0xd1, 0x0, 0x7, - 0xe5, 0x20, 0x0, 0x0, 0x6, 0x0, 0x0, 0x0, - 0x0, - - /* U+843D "落" */ - 0x0, 0x0, 0x9, 0x20, 0xa, 0x30, 0x0, 0x0, - 0x0, 0x0, 0xd, 0x0, 0xc, 0x0, 0x6, 0x90, - 0x7, 0x66, 0x6e, 0x66, 0x6d, 0x66, 0x66, 0x61, - 0x0, 0x72, 0x6, 0x3, 0x94, 0x0, 0x0, 0x0, - 0x0, 0x2e, 0x2, 0x9, 0x86, 0x67, 0x80, 0x0, - 0x0, 0x3, 0x4, 0x19, 0x50, 0xc, 0x30, 0x0, - 0x9, 0x30, 0x50, 0x81, 0x53, 0xa4, 0x0, 0x0, - 0x2, 0xb0, 0x73, 0x30, 0x1f, 0x90, 0x0, 0x0, - 0x0, 0x5, 0x40, 0x1, 0xb3, 0x7b, 0x40, 0x0, - 0x0, 0xb, 0x0, 0x5a, 0x10, 0x2, 0xde, 0xa2, - 0x5, 0xaa, 0x25, 0x4c, 0x66, 0x67, 0xd2, 0x30, - 0x0, 0x97, 0x0, 0x2a, 0x0, 0x1, 0xb0, 0x0, - 0x0, 0x97, 0x0, 0x2a, 0x0, 0x1, 0xb0, 0x0, - 0x0, 0x86, 0x0, 0x2c, 0x66, 0x66, 0xc0, 0x0, - 0x0, 0x0, 0x0, 0x13, 0x0, 0x0, 0x20, 0x0, - - /* U+8449 "葉" */ - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, 0xa, 0x20, 0x1, 0xc0, 0x1, 0x0, - 0x6, 0x66, 0x6c, 0x66, 0x66, 0xd6, 0x6d, 0xa0, - 0x0, 0x0, 0xa, 0x0, 0x0, 0xb0, 0x0, 0x0, - 0x0, 0x0, 0xb1, 0x84, 0x0, 0x71, 0x0, 0x0, - 0x0, 0x0, 0xd0, 0xa3, 0x0, 0xd0, 0x25, 0x0, - 0x1, 0x76, 0xe6, 0xc7, 0x66, 0xe6, 0x66, 0x0, - 0x0, 0x0, 0xd0, 0xa5, 0x44, 0xd0, 0x0, 0x0, - 0x0, 0x0, 0xd0, 0x52, 0x22, 0x70, 0x60, 0x0, - 0x0, 0x1, 0xb6, 0x6b, 0x96, 0x66, 0x61, 0x0, - 0x0, 0x0, 0x0, 0xa, 0x50, 0x0, 0x2b, 0x0, - 0x3, 0x66, 0x66, 0xef, 0xa9, 0x66, 0x66, 0x20, - 0x0, 0x0, 0xb, 0x8a, 0x54, 0x60, 0x0, 0x0, - 0x0, 0x3, 0xb4, 0xa, 0x50, 0x4b, 0x50, 0x0, - 0x3, 0x65, 0x0, 0xa, 0x60, 0x1, 0xaf, 0x80, - 0x1, 0x0, 0x0, 0x6, 0x20, 0x0, 0x2, 0x0, - - /* U+8457 "著" */ - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x9, 0x50, 0xa, 0x60, 0x1, 0x0, - 0x3, 0x66, 0x6b, 0x86, 0x6c, 0x76, 0x6f, 0x60, - 0x0, 0x10, 0x9, 0x31, 0xa, 0x20, 0x0, 0x0, - 0x0, 0x0, 0x6, 0x1c, 0x35, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x0, 0xd, 0x8, 0x5, 0xd2, 0x0, - 0x0, 0x3, 0x76, 0x6e, 0x66, 0x8d, 0x40, 0x0, - 0x0, 0x0, 0x0, 0xd, 0x7, 0xb1, 0x7, 0x50, - 0x4, 0x76, 0x66, 0x66, 0xe8, 0x66, 0x66, 0x50, - 0x0, 0x0, 0x0, 0x3a, 0x30, 0x0, 0x30, 0x0, - 0x0, 0x0, 0x1e, 0x96, 0x66, 0x67, 0xd0, 0x0, - 0x0, 0x17, 0x8d, 0x0, 0x0, 0x2, 0xa0, 0x0, - 0x5, 0x40, 0xd, 0x66, 0x66, 0x67, 0xa0, 0x0, - 0x0, 0x0, 0xd, 0x0, 0x0, 0x2, 0xa0, 0x0, - 0x0, 0x0, 0xe, 0x66, 0x66, 0x67, 0xb0, 0x0, - 0x0, 0x0, 0x6, 0x0, 0x0, 0x1, 0x30, 0x0, - - /* U+8535 "蔵" */ - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, 0xa, 0x50, 0x6, 0x70, 0x1, 0x0, - 0x4, 0x66, 0x6c, 0x76, 0x69, 0xa6, 0x6e, 0xa0, - 0x1, 0x10, 0xa, 0x20, 0x6, 0x72, 0x0, 0x0, - 0x0, 0x0, 0x3, 0x0, 0x4, 0x38, 0x70, 0x0, - 0x0, 0x13, 0x0, 0x0, 0x4, 0xb0, 0x4a, 0x20, - 0x0, 0x3c, 0x66, 0x66, 0x67, 0xc6, 0x66, 0x40, - 0x0, 0x3a, 0x86, 0x87, 0xa2, 0xb0, 0x5, 0x0, - 0x0, 0x29, 0x81, 0x92, 0x10, 0xc0, 0x1f, 0x20, - 0x0, 0x39, 0x86, 0x86, 0xd2, 0xc0, 0x78, 0x0, - 0x0, 0x48, 0x81, 0x0, 0xc0, 0x94, 0xd1, 0x0, - 0x0, 0x66, 0x86, 0x96, 0xa0, 0x5e, 0x60, 0x0, - 0x0, 0x92, 0x81, 0x92, 0x40, 0x6f, 0x20, 0x60, - 0x0, 0x90, 0x86, 0x76, 0x88, 0x73, 0xd3, 0x80, - 0x5, 0x10, 0x0, 0x1, 0x73, 0x0, 0x3e, 0x90, - 0x2, 0x0, 0x0, 0x3, 0x0, 0x0, 0x0, 0x40, - - /* U+8584 "薄" */ - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x2, 0xb0, 0x3, 0xb0, 0x0, 0x0, 0x16, - 0x66, 0x7c, 0x66, 0x7c, 0x66, 0xca, 0x0, 0x40, - 0x2, 0xa0, 0x3, 0x87, 0x30, 0x0, 0x5, 0xa0, - 0x0, 0x0, 0xb3, 0x19, 0x51, 0x0, 0x9, 0x3, - 0x76, 0x6d, 0x66, 0x67, 0x50, 0x30, 0x2, 0x28, - 0x66, 0xd6, 0x69, 0x70, 0x1, 0xd1, 0x60, 0xa1, - 0xc, 0x10, 0x76, 0x0, 0x6, 0x16, 0xa, 0x76, - 0xd6, 0x6a, 0x60, 0x0, 0x7, 0x10, 0xa7, 0x6d, - 0x66, 0xa6, 0x0, 0x2, 0xa0, 0x8, 0x10, 0x90, - 0x55, 0x20, 0x4, 0xc8, 0x27, 0x66, 0x66, 0x6c, - 0x89, 0xa0, 0x6, 0x70, 0x2, 0x81, 0x0, 0xb2, - 0x0, 0x0, 0x97, 0x0, 0x5, 0x70, 0xb, 0x20, - 0x0, 0x9, 0x80, 0x0, 0x0, 0x5a, 0xe1, 0x0, - 0x0, 0x0, 0x0, 0x0, 0x0, 0x33, 0x0, 0x0, - - /* U+85AC "薬" */ - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, 0xa, 0x40, 0xa, 0x40, 0x1, 0x0, - 0x6, 0x66, 0x6c, 0x76, 0x6d, 0x66, 0x6d, 0x90, - 0x1, 0x0, 0xa, 0x13, 0xb, 0x10, 0x0, 0x0, - 0x0, 0x0, 0x0, 0xa, 0x20, 0x0, 0x0, 0x0, - 0x0, 0x76, 0x8, 0x78, 0x69, 0x60, 0x29, 0x0, - 0x0, 0xa, 0x4c, 0x0, 0x8, 0x36, 0xa4, 0x0, - 0x0, 0x0, 0x1c, 0x66, 0x6b, 0x61, 0x0, 0x0, - 0x1, 0x58, 0x5c, 0x0, 0x8, 0x47, 0x93, 0x0, - 0x9, 0x60, 0xc, 0x66, 0x6b, 0x40, 0x3e, 0x0, - 0x0, 0x0, 0x4, 0x7, 0x33, 0x0, 0x5, 0x0, - 0x7, 0x66, 0x66, 0x9d, 0x96, 0x66, 0x8c, 0x50, - 0x0, 0x0, 0x7, 0xba, 0x56, 0x0, 0x0, 0x0, - 0x0, 0x1, 0xa7, 0x9, 0x30, 0x98, 0x20, 0x0, - 0x2, 0x66, 0x10, 0x9, 0x40, 0x5, 0xdf, 0x70, - 0x11, 0x0, 0x0, 0x5, 0x10, 0x0, 0x2, 0x0, - - /* U+85DD "藝" */ - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x9, 0x60, 0x2, 0xb0, 0x1, 0x20, - 0x7, 0x66, 0x6b, 0x86, 0x67, 0xc6, 0x6b, 0xa0, - 0x0, 0x0, 0x26, 0x20, 0x1, 0x60, 0x0, 0x0, - 0x0, 0x0, 0xb2, 0x40, 0x0, 0xb1, 0x0, 0x0, - 0x0, 0x76, 0xc6, 0x65, 0x56, 0xd6, 0xc1, 0x0, - 0x4, 0x76, 0xa6, 0x7b, 0x20, 0xb0, 0xd0, 0x0, - 0x0, 0x95, 0xa2, 0x76, 0x5, 0xb0, 0xd0, 0x0, - 0x6, 0x37, 0xd6, 0x77, 0x8, 0x99, 0xc1, 0x20, - 0x0, 0x0, 0xb3, 0x51, 0x46, 0x3, 0x7a, 0x60, - 0x0, 0xca, 0x73, 0x13, 0x31, 0x47, 0x9, 0x60, - 0x0, 0x1, 0x75, 0x55, 0x55, 0x54, 0x63, 0x0, - 0x2, 0x86, 0x66, 0x9b, 0x66, 0x66, 0x77, 0x0, - 0x0, 0x0, 0x6, 0x93, 0x2, 0x85, 0x0, 0x0, - 0x0, 0x6, 0xeb, 0xa9, 0x76, 0x5b, 0x80, 0x0, - 0x0, 0x2, 0x52, 0x0, 0x0, 0x0, 0x20, 0x0, - - /* U+8607 "蘇" */ - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x9, 0x20, 0x3, 0x90, 0x0, 0x0, - 0x5, 0x66, 0x6c, 0x66, 0x67, 0xb6, 0x6b, 0xa0, - 0x1, 0x0, 0xa, 0x0, 0x2, 0x90, 0x0, 0x0, - 0x0, 0x8, 0x72, 0x0, 0x0, 0x11, 0x67, 0x0, - 0x0, 0x1e, 0x69, 0x70, 0x46, 0x9c, 0x64, 0x0, - 0x0, 0xa3, 0x8, 0x10, 0x0, 0x28, 0x0, 0x0, - 0x6, 0xd5, 0xa6, 0xc3, 0x56, 0x7b, 0x6c, 0x40, - 0x1, 0xb0, 0xb0, 0xb0, 0x22, 0xfd, 0x0, 0x0, - 0x0, 0xb6, 0xc6, 0xc0, 0x6, 0x99, 0x60, 0x0, - 0x0, 0xb0, 0xb0, 0xb0, 0xb, 0x38, 0x91, 0x0, - 0x0, 0xb6, 0xc6, 0xc0, 0x64, 0x28, 0x3b, 0x0, - 0x0, 0x30, 0x0, 0x32, 0x50, 0x28, 0x9, 0xb0, - 0x0, 0x57, 0x46, 0xa4, 0x0, 0x39, 0x0, 0x0, - 0x9, 0x68, 0x3a, 0x43, 0x0, 0x39, 0x0, 0x0, - 0x3, 0x0, 0x0, 0x0, 0x0, 0x11, 0x0, 0x0, - - /* U+8655 "處" */ - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x0, 0xd, 0x10, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x0, 0xe, 0x66, 0x69, 0xb0, 0x0, - 0x0, 0x30, 0x0, 0xd, 0x0, 0x0, 0x3, 0x20, - 0x0, 0x99, 0x66, 0x6c, 0x66, 0x66, 0x6c, 0x80, - 0x0, 0x94, 0x0, 0xe, 0x22, 0x4a, 0x26, 0x0, - 0x0, 0x86, 0x87, 0x7e, 0x53, 0x20, 0x4, 0x0, - 0x0, 0x84, 0x0, 0xd, 0x0, 0x0, 0x58, 0x0, - 0x0, 0x93, 0x9, 0x16, 0x9a, 0xaa, 0x94, 0x0, - 0x0, 0xa2, 0x3e, 0x66, 0x95, 0x75, 0xa0, 0x0, - 0x0, 0xb0, 0x93, 0x6, 0x86, 0x50, 0xc0, 0x10, - 0x0, 0xb2, 0x67, 0x1c, 0x9, 0x20, 0xc0, 0x60, - 0x2, 0x75, 0x3, 0xe5, 0x17, 0x0, 0xc9, 0xd0, - 0x6, 0x0, 0x1a, 0x6b, 0xa4, 0x20, 0x0, 0x0, - 0x23, 0x4, 0x71, 0x0, 0x38, 0xce, 0xff, 0xb1, - 0x0, 0x10, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - - /* U+884C "行" */ - 0x0, 0x6, 0x60, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x1, 0xd3, 0x2, 0x66, 0x66, 0x6e, 0x40, 0x0, - 0xa3, 0x0, 0x2, 0x0, 0x0, 0x0, 0x0, 0x63, - 0x8, 0x10, 0x0, 0x0, 0x0, 0x0, 0x21, 0x3, - 0xd2, 0x0, 0x0, 0x0, 0x3, 0x0, 0x0, 0xc3, - 0x37, 0x66, 0x68, 0x67, 0xb3, 0x0, 0x9d, 0x0, - 0x0, 0x2, 0xb0, 0x0, 0x0, 0x66, 0xe0, 0x0, - 0x0, 0x2b, 0x0, 0x0, 0x45, 0xd, 0x0, 0x0, - 0x2, 0xb0, 0x0, 0x1, 0x0, 0xd0, 0x0, 0x0, - 0x2b, 0x0, 0x0, 0x0, 0xd, 0x0, 0x0, 0x2, - 0xb0, 0x0, 0x0, 0x0, 0xd0, 0x0, 0x0, 0x2b, - 0x0, 0x0, 0x0, 0xd, 0x0, 0x3, 0x26, 0xa0, - 0x0, 0x0, 0x0, 0xd0, 0x0, 0x3a, 0xf7, 0x0, - 0x0, 0x0, 0x3, 0x0, 0x0, 0x4, 0x0, 0x0, - 0x0, - - /* U+8853 "術" */ - 0x0, 0x7, 0x50, 0x9, 0x20, 0x0, 0x0, 0x10, - 0x0, 0xc, 0x10, 0xd, 0x31, 0x4, 0x76, 0xb1, - 0x0, 0x83, 0x0, 0xd, 0xc, 0x20, 0x0, 0x0, - 0x3, 0x41, 0xb0, 0xd, 0x5, 0x10, 0x0, 0x0, - 0x2, 0x9, 0x84, 0x4d, 0x4a, 0x20, 0x0, 0x51, - 0x0, 0x2d, 0x3, 0x9f, 0x22, 0x17, 0x6e, 0x63, - 0x0, 0xae, 0x10, 0xbe, 0x30, 0x0, 0xd, 0x0, - 0x6, 0x2d, 0x0, 0xbd, 0x69, 0x0, 0xd, 0x0, - 0x1, 0xd, 0x4, 0x6d, 0xa, 0x50, 0xd, 0x0, - 0x0, 0xd, 0x8, 0xd, 0x1, 0x0, 0xd, 0x0, - 0x0, 0xd, 0x16, 0xd, 0x0, 0x0, 0xd, 0x0, - 0x0, 0xd, 0x50, 0xd, 0x0, 0x0, 0xd, 0x0, - 0x0, 0xd, 0x0, 0xd, 0x0, 0x0, 0xd, 0x0, - 0x0, 0xd, 0x0, 0xd, 0x0, 0x18, 0xdb, 0x0, - 0x0, 0x1, 0x0, 0x1, 0x0, 0x0, 0x40, 0x0, - - /* U+8868 "表" */ - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x0, 0xb, 0x30, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x0, 0xd, 0x10, 0x0, 0x26, 0x0, - 0x0, 0x76, 0x66, 0x6d, 0x66, 0x66, 0x77, 0x10, - 0x0, 0x0, 0x0, 0xc, 0x10, 0x1, 0x40, 0x0, - 0x0, 0x6, 0x66, 0x6d, 0x66, 0x67, 0x81, 0x0, - 0x0, 0x0, 0x0, 0xc, 0x10, 0x0, 0x3, 0x10, - 0x6, 0x66, 0x66, 0x6e, 0x66, 0x66, 0x6b, 0x90, - 0x0, 0x0, 0x0, 0xb8, 0x50, 0x1, 0xa0, 0x0, - 0x0, 0x0, 0x9, 0x90, 0x90, 0x1b, 0x50, 0x0, - 0x0, 0x0, 0xae, 0x0, 0x39, 0x70, 0x0, 0x0, - 0x0, 0x2a, 0x6d, 0x0, 0x9, 0x50, 0x0, 0x0, - 0x16, 0x50, 0x1d, 0x0, 0x20, 0xa8, 0x0, 0x0, - 0x0, 0x0, 0x1d, 0x38, 0x40, 0x7, 0xfa, 0x71, - 0x0, 0x0, 0x3f, 0x90, 0x0, 0x0, 0x29, 0x40, - 0x0, 0x0, 0x3, 0x0, 0x0, 0x0, 0x0, 0x0, - - /* U+88AB "被" */ - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x38, 0x0, 0x0, 0x0, 0xd1, 0x0, 0x0, - 0x0, 0xa, 0x50, 0x0, 0x0, 0xd0, 0x0, 0x0, - 0x0, 0x1, 0x11, 0x3, 0x0, 0xd0, 0x2, 0x20, - 0x6, 0x76, 0xba, 0xe, 0x66, 0xe6, 0x6c, 0xa0, - 0x0, 0x0, 0xd1, 0xd, 0x0, 0xd0, 0x17, 0x0, - 0x0, 0x6, 0x74, 0x1d, 0x0, 0xd0, 0x0, 0x0, - 0x0, 0xe, 0x1c, 0x2e, 0x66, 0xe6, 0x78, 0x0, - 0x0, 0x8e, 0x71, 0x1c, 0x31, 0x0, 0x88, 0x0, - 0x5, 0x3d, 0x77, 0x2a, 0x6, 0x0, 0xd1, 0x0, - 0x12, 0xd, 0xd, 0x48, 0x8, 0x16, 0x80, 0x0, - 0x0, 0xd, 0x1, 0x74, 0x1, 0xbc, 0x0, 0x0, - 0x0, 0xd, 0x0, 0xb0, 0x2, 0xd9, 0x0, 0x0, - 0x0, 0xd, 0x4, 0x60, 0x4a, 0x16, 0xc4, 0x0, - 0x0, 0xd, 0x18, 0x27, 0x50, 0x0, 0x4d, 0xb1, - 0x0, 0x2, 0x20, 0x20, 0x0, 0x0, 0x0, 0x0, - - /* U+88CF "裏" */ - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x78, 0x0, 0x0, 0x0, 0x36, 0x66, - 0x66, 0x6d, 0x66, 0x66, 0xc5, 0x0, 0x12, 0x0, - 0x0, 0x0, 0x5, 0x0, 0x0, 0x2c, 0x66, 0x6d, - 0x66, 0x6e, 0x0, 0x0, 0x2c, 0x66, 0x6d, 0x66, - 0x6d, 0x0, 0x0, 0x2a, 0x0, 0x1c, 0x0, 0xd, - 0x0, 0x0, 0x28, 0x66, 0x6d, 0x66, 0x66, 0x0, - 0x0, 0x76, 0x66, 0x6d, 0x66, 0x6b, 0x40, 0x0, - 0x0, 0x0, 0x1c, 0x0, 0x0, 0x53, 0x28, 0x66, - 0x66, 0xf9, 0x66, 0x69, 0x64, 0x0, 0x0, 0x2c, - 0x67, 0x0, 0x6c, 0x30, 0x0, 0x18, 0xd7, 0x1, - 0xa8, 0x40, 0x0, 0x16, 0x71, 0x77, 0x5, 0x49, - 0xb7, 0x42, 0x0, 0x0, 0x9d, 0x92, 0x0, 0x28, - 0xc4, 0x0, 0x0, 0x33, 0x0, 0x0, 0x0, 0x0, - - /* U+88DC "補" */ - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x19, 0x0, 0x0, 0x0, 0xb4, 0x20, 0x0, - 0x0, 0x6, 0xa0, 0x0, 0x0, 0xd0, 0xb4, 0x0, - 0x0, 0x0, 0x50, 0x0, 0x0, 0xd0, 0x38, 0x10, - 0x7, 0x66, 0xc8, 0x76, 0x66, 0xe6, 0x69, 0x70, - 0x0, 0x0, 0xd0, 0x2, 0x0, 0xd0, 0x4, 0x0, - 0x0, 0x6, 0x82, 0xe, 0x66, 0xe6, 0x6e, 0x20, - 0x0, 0xe, 0x1b, 0x4d, 0x0, 0xd0, 0xd, 0x0, - 0x0, 0x9e, 0x56, 0xd, 0x66, 0xe6, 0x6d, 0x0, - 0x5, 0x4c, 0x95, 0xd, 0x0, 0xd0, 0xd, 0x0, - 0x33, 0xc, 0x1e, 0x2d, 0x0, 0xd0, 0xd, 0x0, - 0x0, 0xc, 0x4, 0xd, 0x66, 0xe6, 0x6d, 0x0, - 0x0, 0xc, 0x0, 0xd, 0x0, 0xd0, 0xd, 0x0, - 0x0, 0xc, 0x0, 0xd, 0x0, 0xd0, 0xd, 0x0, - 0x0, 0xd, 0x10, 0xd, 0x0, 0xc3, 0x9c, 0x0, - 0x0, 0x4, 0x0, 0x6, 0x0, 0x20, 0x32, 0x0, - - /* U+88E1 "裡" */ - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x19, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x6, 0xa0, 0xb, 0x66, 0x66, 0x6d, 0x10, - 0x0, 0x0, 0x50, 0xc, 0x0, 0xd0, 0xc, 0x0, - 0x7, 0x66, 0xc9, 0xc, 0x0, 0xd0, 0xc, 0x0, - 0x0, 0x0, 0xe0, 0xd, 0x66, 0xe6, 0x6c, 0x0, - 0x0, 0x7, 0x82, 0xc, 0x0, 0xd0, 0xc, 0x0, - 0x0, 0x1e, 0x1b, 0x4c, 0x0, 0xd0, 0xc, 0x0, - 0x0, 0x9e, 0x56, 0xd, 0x66, 0xe6, 0x6c, 0x0, - 0x6, 0x3c, 0x95, 0xa, 0x0, 0xd0, 0x4, 0x0, - 0x33, 0xc, 0xe, 0x30, 0x0, 0xd0, 0x0, 0x0, - 0x0, 0xc, 0x4, 0x37, 0x66, 0xe6, 0x6d, 0x20, - 0x0, 0xc, 0x0, 0x1, 0x0, 0xd0, 0x0, 0x0, - 0x0, 0xc, 0x0, 0x0, 0x0, 0xd0, 0x0, 0x10, - 0x0, 0xd, 0x13, 0x66, 0x66, 0xe6, 0x6a, 0xc0, - 0x0, 0x4, 0x0, 0x10, 0x0, 0x0, 0x0, 0x0, - - /* U+88FD "製" */ - 0x0, 0x18, 0xb, 0x10, 0x0, 0x0, 0x6, 0x0, - 0x0, 0x85, 0xc, 0x2, 0x50, 0x0, 0xd, 0x0, - 0x3, 0x86, 0x6d, 0x66, 0x60, 0xb3, 0xc, 0x0, - 0x6, 0x75, 0x5d, 0x56, 0xb2, 0xd0, 0xc, 0x0, - 0x0, 0x76, 0x6d, 0x66, 0x80, 0xd0, 0xc, 0x0, - 0x0, 0xc0, 0xc, 0x2, 0x90, 0xd0, 0xc, 0x0, - 0x0, 0xc0, 0xc, 0x37, 0x80, 0x20, 0xc, 0x0, - 0x0, 0xb0, 0xd, 0x9, 0x20, 0x6, 0xca, 0x0, - 0x0, 0x0, 0x3, 0x4, 0xa0, 0x0, 0x38, 0x0, - 0x6, 0x76, 0x66, 0xc7, 0x96, 0x66, 0x89, 0x50, - 0x0, 0x0, 0x2c, 0x40, 0x42, 0x6, 0xc1, 0x0, - 0x0, 0x18, 0x9d, 0x0, 0x6, 0x76, 0x0, 0x0, - 0x15, 0x50, 0xd, 0x16, 0x60, 0x8a, 0x40, 0x0, - 0x0, 0x0, 0xf, 0xb2, 0x0, 0x3, 0xbf, 0x70, - 0x0, 0x0, 0x4, 0x0, 0x0, 0x0, 0x0, 0x0, - - /* U+8907 "複" */ - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x36, 0x0, 0x0, 0x95, 0x0, 0x0, 0x0, - 0x0, 0xa, 0x60, 0x0, 0xe1, 0x0, 0x3, 0x40, - 0x0, 0x2, 0x40, 0x4, 0xb6, 0x66, 0x66, 0x60, - 0x6, 0x55, 0xc7, 0xa, 0xa6, 0x66, 0x6a, 0x10, - 0x0, 0x1, 0xe0, 0x43, 0xd0, 0x0, 0xd, 0x0, - 0x0, 0x7, 0x72, 0x30, 0xd6, 0x66, 0x6d, 0x0, - 0x0, 0x1e, 0xb, 0x40, 0xd0, 0x0, 0xd, 0x0, - 0x0, 0x9d, 0x45, 0x0, 0xda, 0x86, 0x6b, 0x0, - 0x5, 0x4c, 0xa4, 0x0, 0x1c, 0x0, 0x13, 0x0, - 0x13, 0xc, 0xd, 0x20, 0x9a, 0x66, 0xba, 0x0, - 0x0, 0xc, 0x2, 0x6, 0x45, 0x11, 0xc0, 0x0, - 0x0, 0xc, 0x0, 0x21, 0x0, 0x9c, 0x20, 0x0, - 0x0, 0xc, 0x0, 0x0, 0x5, 0xcb, 0x30, 0x0, - 0x0, 0xd, 0x0, 0x16, 0x85, 0x2, 0xbc, 0x81, - 0x0, 0x3, 0x4, 0x30, 0x0, 0x0, 0x1, 0x10, - - /* U+897F "西" */ - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x3, 0x0, - 0x76, 0x66, 0x67, 0x66, 0x86, 0x66, 0xc5, 0x0, - 0x0, 0x3, 0xa0, 0xd, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x3a, 0x0, 0xd0, 0x0, 0x0, 0x0, 0x86, - 0x67, 0xc6, 0x6e, 0x66, 0x6c, 0x0, 0xd, 0x0, - 0x39, 0x0, 0xd0, 0x1, 0xb0, 0x0, 0xd0, 0x5, - 0x80, 0xd, 0x0, 0x1b, 0x0, 0xd, 0x0, 0x75, - 0x0, 0xd0, 0x1, 0xb0, 0x0, 0xd0, 0xb, 0x10, - 0xd, 0x0, 0x1b, 0x0, 0xd, 0x4, 0x60, 0x0, - 0xcc, 0xd4, 0xb0, 0x0, 0xd1, 0x70, 0x0, 0x0, - 0x0, 0x1b, 0x0, 0xd, 0x20, 0x0, 0x0, 0x0, - 0x1, 0xb0, 0x0, 0xd6, 0x66, 0x66, 0x66, 0x66, - 0x6c, 0x0, 0xd, 0x0, 0x0, 0x0, 0x0, 0x1, - 0xa0, 0x0, 0x10, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, - - /* U+8981 "要" */ - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x9, 0x0, - 0x2, 0x76, 0x66, 0xc6, 0x6c, 0x66, 0x68, 0x40, - 0x0, 0x0, 0x0, 0xd0, 0xd, 0x0, 0x10, 0x0, - 0x0, 0xd, 0x66, 0xe6, 0x6e, 0x66, 0xe3, 0x0, - 0x0, 0xd, 0x0, 0xd0, 0xd, 0x0, 0xd0, 0x0, - 0x0, 0xd, 0x0, 0xd0, 0xd, 0x0, 0xd0, 0x0, - 0x0, 0xe, 0x66, 0x96, 0x66, 0x66, 0xc0, 0x0, - 0x0, 0x1, 0x0, 0xd5, 0x0, 0x0, 0x1, 0x0, - 0x6, 0x66, 0x68, 0xd6, 0x66, 0x66, 0x6d, 0xa0, - 0x0, 0x0, 0xc, 0x20, 0x2, 0xd0, 0x0, 0x0, - 0x0, 0x0, 0x89, 0x10, 0xb, 0x40, 0x0, 0x0, - 0x0, 0x0, 0x3, 0x68, 0xdd, 0x40, 0x0, 0x0, - 0x0, 0x0, 0x0, 0x5b, 0x63, 0x9e, 0xa1, 0x0, - 0x0, 0x25, 0x88, 0x50, 0x0, 0x0, 0x8b, 0x0, - 0x4, 0x30, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - - /* U+898B "見" */ - 0x0, 0x3, 0x0, 0x0, 0x0, 0x6, 0x10, 0x0, - 0x0, 0xb, 0x86, 0x66, 0x66, 0x6e, 0x40, 0x0, - 0x0, 0xa, 0x30, 0x0, 0x0, 0xe, 0x0, 0x0, - 0x0, 0xa, 0x86, 0x66, 0x66, 0x6e, 0x0, 0x0, - 0x0, 0xa, 0x30, 0x0, 0x0, 0xe, 0x0, 0x0, - 0x0, 0xa, 0x86, 0x66, 0x66, 0x6e, 0x0, 0x0, - 0x0, 0xa, 0x30, 0x0, 0x0, 0xe, 0x0, 0x0, - 0x0, 0xa, 0x30, 0x0, 0x0, 0xe, 0x0, 0x0, - 0x0, 0xa, 0x87, 0xa6, 0x6a, 0x6f, 0x0, 0x0, - 0x0, 0x8, 0x13, 0xb0, 0x1d, 0x5, 0x0, 0x0, - 0x0, 0x0, 0x6, 0x90, 0x1d, 0x0, 0x0, 0x40, - 0x0, 0x0, 0xb, 0x40, 0x1d, 0x0, 0x0, 0x60, - 0x0, 0x0, 0x7a, 0x0, 0x1d, 0x0, 0x3, 0x90, - 0x0, 0x48, 0x60, 0x0, 0xd, 0xcc, 0xce, 0xb0, - 0x24, 0x10, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - - /* U+898F "規" */ - 0x0, 0x9, 0x30, 0x2, 0x0, 0x0, 0x5, 0x0, - 0x0, 0xb, 0x10, 0xe, 0x66, 0x66, 0x6e, 0x10, - 0x0, 0xb, 0x10, 0xd, 0x0, 0x0, 0xd, 0x0, - 0x5, 0x6d, 0x7b, 0x1d, 0x66, 0x66, 0x6d, 0x0, - 0x1, 0xb, 0x10, 0xd, 0x0, 0x0, 0xd, 0x0, - 0x0, 0xb, 0x10, 0xd, 0x33, 0x33, 0x3d, 0x0, - 0x26, 0x6d, 0x6a, 0x7d, 0x22, 0x22, 0x2d, 0x0, - 0x2, 0xc, 0x10, 0xd, 0x0, 0x0, 0xd, 0x0, - 0x0, 0xd, 0x10, 0xe, 0x6b, 0x6a, 0x6d, 0x0, - 0x0, 0xd, 0x74, 0x6, 0x1d, 0xd, 0x2, 0x0, - 0x0, 0x29, 0xa, 0x70, 0x3b, 0xd, 0x0, 0x0, - 0x0, 0x82, 0x1, 0x90, 0x86, 0xd, 0x0, 0x40, - 0x2, 0x70, 0x0, 0x3, 0xa0, 0xd, 0x0, 0x80, - 0x16, 0x0, 0x0, 0x66, 0x0, 0xd, 0xcc, 0xd1, - 0x10, 0x0, 0x4, 0x0, 0x0, 0x0, 0x0, 0x0, - - /* U+8996 "視" */ - 0x0, 0x8, 0x0, 0x3, 0x0, 0x0, 0x5, 0x0, - 0x0, 0x5, 0xb0, 0xe, 0x66, 0x66, 0x6e, 0x0, - 0x0, 0x0, 0x71, 0xd, 0x0, 0x0, 0xd, 0x0, - 0x7, 0x66, 0xab, 0xd, 0x66, 0x66, 0x6d, 0x0, - 0x0, 0x0, 0xc2, 0xd, 0x0, 0x0, 0xd, 0x0, - 0x0, 0x6, 0x70, 0xd, 0x66, 0x66, 0x6d, 0x0, - 0x0, 0x2f, 0x30, 0xd, 0x0, 0x0, 0xd, 0x0, - 0x0, 0x9c, 0x88, 0xd, 0x0, 0x0, 0xd, 0x0, - 0x7, 0x1b, 0x1b, 0x5e, 0x6b, 0x6a, 0x6d, 0x0, - 0x20, 0xb, 0x11, 0x15, 0x1d, 0xd, 0x2, 0x0, - 0x0, 0xb, 0x10, 0x0, 0x4a, 0xd, 0x0, 0x0, - 0x0, 0xb, 0x10, 0x0, 0xa4, 0xd, 0x0, 0x40, - 0x0, 0xb, 0x10, 0x5, 0x80, 0xd, 0x0, 0x70, - 0x0, 0xc, 0x11, 0x65, 0x0, 0xd, 0xcc, 0xc0, - 0x0, 0x2, 0x3, 0x0, 0x0, 0x0, 0x0, 0x0, - - /* U+899A "覚" */ - 0x0, 0x2, 0x0, 0x26, 0x0, 0x7, 0x40, 0x0, - 0x0, 0x0, 0xc3, 0xa, 0x60, 0xc, 0x30, 0x0, - 0x0, 0x30, 0x57, 0x3, 0x50, 0x54, 0x2, 0x10, - 0x2, 0xa6, 0x66, 0x66, 0x66, 0x76, 0x6b, 0xb0, - 0xc, 0x50, 0x10, 0x0, 0x0, 0x3, 0x9, 0x0, - 0x5, 0x0, 0xe6, 0x66, 0x66, 0x6e, 0x40, 0x0, - 0x0, 0x0, 0xd0, 0x0, 0x0, 0xd, 0x0, 0x0, - 0x0, 0x0, 0xd6, 0x66, 0x66, 0x6d, 0x0, 0x0, - 0x0, 0x0, 0xd6, 0x66, 0x66, 0x6d, 0x0, 0x0, - 0x0, 0x0, 0xd0, 0x0, 0x0, 0xd, 0x0, 0x0, - 0x0, 0x0, 0xd6, 0xb8, 0x6c, 0x6d, 0x0, 0x0, - 0x0, 0x0, 0x10, 0xe1, 0xd, 0x0, 0x0, 0x50, - 0x0, 0x0, 0x9, 0x80, 0xd, 0x0, 0x2, 0x70, - 0x0, 0x26, 0x84, 0x0, 0xd, 0xcc, 0xce, 0xa0, - 0x3, 0x20, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - - /* U+89AA "親" */ - 0x0, 0x4, 0x50, 0x0, 0x20, 0x0, 0x3, 0x0, - 0x0, 0x0, 0xc2, 0x31, 0xc6, 0x66, 0x6b, 0x50, - 0x3, 0x86, 0x78, 0xa4, 0xb0, 0x0, 0x9, 0x10, - 0x0, 0x54, 0x6, 0x70, 0xb6, 0x66, 0x6b, 0x10, - 0x0, 0xd, 0x7, 0x0, 0xb0, 0x0, 0x9, 0x10, - 0x7, 0x67, 0x88, 0x79, 0xb6, 0x66, 0x6b, 0x10, - 0x0, 0x0, 0xc0, 0x0, 0xb0, 0x0, 0x9, 0x10, - 0x0, 0x0, 0xc0, 0x40, 0xb0, 0x0, 0x9, 0x20, - 0x3, 0x76, 0xd6, 0x73, 0xb7, 0xa6, 0xab, 0x20, - 0x0, 0x30, 0xc1, 0x0, 0x54, 0x81, 0xa2, 0x0, - 0x0, 0xb5, 0xc2, 0x80, 0x6, 0x61, 0xa0, 0x0, - 0x3, 0x70, 0xc0, 0x79, 0xa, 0x21, 0xa0, 0x40, - 0x7, 0x10, 0xc0, 0x6, 0x39, 0x1, 0xa0, 0x70, - 0x0, 0x3c, 0xb0, 0x4, 0x60, 0x0, 0xcb, 0xe2, - 0x0, 0x0, 0x0, 0x21, 0x0, 0x0, 0x0, 0x0, - - /* U+89BA "覺" */ - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x23, 0x8a, 0x13, 0x49, 0x46, 0x96, 0x0, - 0x0, 0x3b, 0x0, 0x7, 0xc7, 0x10, 0x84, 0x0, - 0x0, 0x1c, 0x69, 0x31, 0x4, 0x37, 0xc2, 0x0, - 0x0, 0xb, 0x4, 0x6, 0x8a, 0x0, 0xb1, 0x0, - 0x0, 0xd, 0x65, 0x36, 0x98, 0x27, 0xd0, 0x0, - 0x5, 0x7b, 0x66, 0x66, 0x67, 0x66, 0xb8, 0xb0, - 0x1e, 0x10, 0x74, 0x44, 0x44, 0x48, 0x18, 0x10, - 0x2, 0x0, 0xd2, 0x22, 0x22, 0x2c, 0x0, 0x0, - 0x0, 0x0, 0xd6, 0x66, 0x66, 0x6d, 0x0, 0x0, - 0x0, 0x0, 0xd6, 0x66, 0x66, 0x6d, 0x0, 0x0, - 0x0, 0x0, 0xd6, 0x66, 0x66, 0x6d, 0x0, 0x0, - 0x0, 0x0, 0x50, 0xc1, 0xb, 0x4, 0x0, 0x50, - 0x0, 0x0, 0x8, 0x70, 0xb, 0x0, 0x0, 0x80, - 0x0, 0x15, 0x74, 0x0, 0xd, 0xbb, 0xbc, 0xd0, - 0x3, 0x20, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - - /* U+89C0 "觀" */ - 0x0, 0x47, 0x9, 0x10, 0x20, 0x0, 0x3, 0x0, - 0x0, 0x57, 0xc, 0x33, 0xc6, 0x66, 0x6c, 0x40, - 0x7, 0x9a, 0x6d, 0x64, 0xc0, 0x0, 0xa, 0x0, - 0x2, 0x36, 0x25, 0x12, 0xc6, 0x66, 0x6c, 0x0, - 0xb, 0x6c, 0x6a, 0x97, 0xc0, 0x0, 0xa, 0x0, - 0xb, 0x5c, 0x4a, 0x85, 0xc6, 0x66, 0x6c, 0x0, - 0x4, 0x74, 0x80, 0x0, 0xc0, 0x0, 0xa, 0x0, - 0x0, 0xc1, 0x72, 0x30, 0xc0, 0x0, 0xa, 0x10, - 0x7, 0xb6, 0xa6, 0x83, 0xc7, 0xa7, 0xac, 0x10, - 0x19, 0xb6, 0xc6, 0x91, 0x44, 0x82, 0x92, 0x0, - 0x3, 0x90, 0xb1, 0x0, 0x6, 0x62, 0x90, 0x0, - 0x3, 0xb6, 0xc6, 0xa1, 0xa, 0x22, 0x90, 0x40, - 0x3, 0x90, 0xb1, 0x40, 0x39, 0x2, 0x90, 0x70, - 0x3, 0xa6, 0x66, 0x67, 0x60, 0x0, 0xdb, 0xd1, - 0x0, 0x0, 0x0, 0x21, 0x0, 0x0, 0x0, 0x0, - - /* U+89D2 "角" */ - 0x0, 0x0, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x8a, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x1e, 0x76, 0x67, 0xc1, 0x0, 0x0, 0x0, - 0x9, 0x70, 0x0, 0x89, 0x10, 0x0, 0x0, 0x4, - 0xc0, 0x0, 0x8, 0x0, 0x2, 0x0, 0x2, 0xcd, - 0x66, 0x6b, 0x66, 0x68, 0xe0, 0x3, 0x80, 0xd0, - 0x0, 0xe0, 0x0, 0x3a, 0x0, 0x10, 0xe, 0x66, - 0x6e, 0x66, 0x68, 0xa0, 0x0, 0x0, 0xd0, 0x0, - 0xe0, 0x0, 0x3a, 0x0, 0x0, 0xd, 0x0, 0xe, - 0x0, 0x3, 0xa0, 0x0, 0x1, 0xd6, 0x66, 0xe6, - 0x66, 0x8a, 0x0, 0x0, 0x48, 0x0, 0xe, 0x0, - 0x3, 0xa0, 0x0, 0x9, 0x30, 0x0, 0xe0, 0x0, - 0x3a, 0x0, 0x3, 0xa0, 0x0, 0xe, 0x0, 0x3, - 0xa0, 0x2, 0x80, 0x0, 0x0, 0xe0, 0x49, 0xd9, - 0x0, 0x40, 0x0, 0x0, 0x1, 0x0, 0x7, 0x10, - - /* U+89E3 "解" */ - 0x0, 0x6, 0x60, 0x0, 0x0, 0x0, 0x2, 0x10, - 0x0, 0xc, 0x20, 0x0, 0x66, 0xd6, 0x6b, 0x60, - 0x0, 0x3c, 0x6c, 0x70, 0x3, 0xb0, 0x9, 0x30, - 0x0, 0xa2, 0xa, 0x0, 0xa, 0x40, 0xb, 0x20, - 0x4, 0xd6, 0x97, 0xa3, 0x58, 0x4, 0x9d, 0x0, - 0x15, 0xc0, 0xc0, 0xc3, 0x33, 0xa, 0x31, 0x0, - 0x0, 0xc1, 0xc1, 0xc0, 0xe, 0x2d, 0x0, 0x0, - 0x0, 0xd5, 0xd5, 0xd0, 0x6b, 0x6e, 0x6c, 0x30, - 0x0, 0xc0, 0xc0, 0xc0, 0xa0, 0xd, 0x0, 0x0, - 0x0, 0xd6, 0xd6, 0xd3, 0x10, 0xd, 0x0, 0x40, - 0x0, 0xb0, 0xc0, 0xc4, 0x76, 0x6e, 0x66, 0x81, - 0x2, 0x80, 0xc0, 0xc0, 0x0, 0xd, 0x0, 0x0, - 0x7, 0x20, 0xc0, 0xc0, 0x0, 0xd, 0x0, 0x0, - 0x7, 0x0, 0x56, 0xd0, 0x0, 0xe, 0x0, 0x0, - 0x20, 0x0, 0x0, 0x40, 0x0, 0x5, 0x0, 0x0, - - /* U+89E6 "触" */ - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x7, 0x80, 0x0, 0x0, 0x9, 0x10, 0x0, - 0x0, 0xc, 0x31, 0x0, 0x0, 0xc, 0x0, 0x0, - 0x0, 0x3c, 0x6c, 0x80, 0x0, 0xc, 0x0, 0x0, - 0x0, 0xb2, 0xa, 0x0, 0x20, 0xc, 0x3, 0x0, - 0x6, 0xd6, 0x97, 0xc3, 0xb6, 0x6d, 0x6c, 0x40, - 0x14, 0xc0, 0xb0, 0xb0, 0xa1, 0xc, 0xa, 0x10, - 0x0, 0xc6, 0xc6, 0xd0, 0xa1, 0xc, 0xa, 0x10, - 0x0, 0xc0, 0xb0, 0xb0, 0xa1, 0xc, 0xa, 0x10, - 0x0, 0xc0, 0xb0, 0xb0, 0xb4, 0x3c, 0x3b, 0x10, - 0x0, 0xd6, 0xc6, 0xd0, 0x93, 0x3c, 0x37, 0x10, - 0x0, 0xb0, 0xb0, 0xb0, 0x0, 0xc, 0x11, 0x0, - 0x2, 0x80, 0xb0, 0xb0, 0x0, 0xc, 0x9, 0x10, - 0x7, 0x10, 0xb0, 0xb2, 0x45, 0x6d, 0x57, 0xb0, - 0x6, 0x0, 0x56, 0xe4, 0xb6, 0x30, 0x0, 0x90, - 0x10, 0x0, 0x0, 0x30, 0x0, 0x0, 0x0, 0x0, - - /* U+8A00 "言" */ - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x2, 0xa2, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x7a, 0x0, 0x0, 0x10, 0x36, 0x66, 0x66, - 0x78, 0x66, 0x67, 0xe3, 0x1, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0xa2, 0x0, 0x0, 0x27, 0x66, 0x66, 0x66, 0x64, - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x20, 0x0, - 0x0, 0x37, 0x66, 0x66, 0x66, 0xa7, 0x0, 0x0, - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x1b, - 0x66, 0x66, 0x66, 0xd4, 0x0, 0x0, 0x1e, 0x0, - 0x0, 0x0, 0xd1, 0x0, 0x0, 0x1e, 0x0, 0x0, - 0x0, 0xd1, 0x0, 0x0, 0x1e, 0x66, 0x66, 0x66, - 0xe1, 0x0, 0x0, 0x1e, 0x0, 0x0, 0x0, 0xd1, - 0x0, 0x0, 0x1, 0x0, 0x0, 0x0, 0x10, 0x0, - - /* U+8A08 "計" */ - 0x0, 0x5, 0x50, 0x0, 0x0, 0xb, 0x10, 0x0, - 0x0, 0x0, 0xd3, 0x1, 0x0, 0xe, 0x0, 0x0, - 0x6, 0x66, 0xb6, 0x8c, 0x10, 0xd, 0x0, 0x0, - 0x0, 0x0, 0x0, 0x0, 0x0, 0xd, 0x0, 0x0, - 0x1, 0x44, 0x44, 0xa0, 0x0, 0xd, 0x0, 0x30, - 0x0, 0x32, 0x22, 0x22, 0x86, 0x6e, 0x66, 0x94, - 0x0, 0x0, 0x0, 0x60, 0x0, 0xd, 0x0, 0x0, - 0x1, 0x76, 0x66, 0x73, 0x0, 0xd, 0x0, 0x0, - 0x0, 0x0, 0x0, 0x10, 0x0, 0xd, 0x0, 0x0, - 0x3, 0xc6, 0x66, 0xe1, 0x0, 0xd, 0x0, 0x0, - 0x2, 0xa0, 0x0, 0xd0, 0x0, 0xd, 0x0, 0x0, - 0x2, 0xa0, 0x0, 0xd0, 0x0, 0xe, 0x0, 0x0, - 0x2, 0xc6, 0x66, 0xd0, 0x0, 0xe, 0x0, 0x0, - 0x3, 0xa0, 0x0, 0xd0, 0x0, 0x1e, 0x0, 0x0, - 0x1, 0x20, 0x0, 0x10, 0x0, 0x2, 0x0, 0x0, - - /* U+8A0A "訊" */ - 0x0, 0x7, 0x30, 0x0, 0x0, 0x1, 0x50, 0x0, - 0x0, 0x2, 0xf0, 0x17, 0xd7, 0x68, 0xc0, 0x0, - 0x6, 0x66, 0xc6, 0xa4, 0xb2, 0x3, 0xa0, 0x0, - 0x0, 0x0, 0x0, 0x0, 0xb2, 0x3, 0x90, 0x0, - 0x1, 0x66, 0x68, 0x70, 0xb2, 0x3, 0x90, 0x0, - 0x0, 0x20, 0x0, 0x0, 0xb2, 0x3, 0x90, 0x0, - 0x0, 0x0, 0x4, 0x27, 0xd8, 0xc4, 0x90, 0x0, - 0x1, 0x76, 0x66, 0x40, 0xb2, 0x1, 0xa0, 0x0, - 0x0, 0x0, 0x0, 0x10, 0xb2, 0x0, 0xc0, 0x0, - 0x3, 0xc6, 0x68, 0xc0, 0xb2, 0x0, 0xd0, 0x0, - 0x2, 0xa0, 0x3, 0xa0, 0xb2, 0x0, 0xb2, 0x30, - 0x2, 0xa0, 0x3, 0xa0, 0xb2, 0x0, 0x68, 0x70, - 0x2, 0xc6, 0x67, 0xa0, 0xb2, 0x0, 0xd, 0xc0, - 0x3, 0xa0, 0x3, 0xa0, 0xb2, 0x0, 0x3, 0xe0, - 0x1, 0x20, 0x0, 0x0, 0x10, 0x0, 0x0, 0x10, - - /* U+8A0E "討" */ - 0x0, 0x6, 0x20, 0x0, 0x0, 0x1, 0xb1, 0x0, - 0x0, 0x1, 0xe1, 0x0, 0x0, 0x1, 0xe0, 0x0, - 0x6, 0x66, 0xc6, 0xa8, 0x0, 0x1, 0xe0, 0x0, - 0x0, 0x0, 0x0, 0x0, 0x0, 0x1, 0xe0, 0x50, - 0x1, 0x66, 0x68, 0x94, 0x65, 0x56, 0xe6, 0x83, - 0x0, 0x20, 0x0, 0x0, 0x0, 0x1, 0xe0, 0x0, - 0x0, 0x0, 0x3, 0x11, 0x70, 0x1, 0xe0, 0x0, - 0x1, 0x76, 0x67, 0x50, 0x6a, 0x1, 0xe0, 0x0, - 0x0, 0x0, 0x0, 0x10, 0xe, 0x21, 0xe0, 0x0, - 0x3, 0xb6, 0x67, 0xd0, 0x3, 0x1, 0xe0, 0x0, - 0x2, 0xa0, 0x3, 0xa0, 0x0, 0x1, 0xe0, 0x0, - 0x2, 0xa0, 0x3, 0xa0, 0x0, 0x1, 0xe0, 0x0, - 0x2, 0xc6, 0x67, 0xa0, 0x2, 0x2, 0xe0, 0x0, - 0x3, 0xa0, 0x3, 0xa0, 0x3, 0xaf, 0xc0, 0x0, - 0x1, 0x20, 0x0, 0x10, 0x0, 0x6, 0x10, 0x0, - - /* U+8A13 "訓" */ - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x9, 0x30, 0x0, 0x74, 0x2, 0x0, 0xb0, - 0x0, 0x5, 0xc0, 0x10, 0xa4, 0xd, 0x20, 0xd0, - 0x6, 0x67, 0x86, 0x94, 0x93, 0xd, 0x0, 0xd0, - 0x0, 0x0, 0x0, 0x10, 0x93, 0xd, 0x0, 0xd0, - 0x1, 0x76, 0x67, 0x70, 0x93, 0xd, 0x0, 0xd0, - 0x0, 0x0, 0x0, 0x0, 0x93, 0xd, 0x0, 0xd0, - 0x0, 0x76, 0x69, 0x70, 0xa3, 0xd, 0x0, 0xd0, - 0x0, 0x0, 0x0, 0x0, 0xb2, 0xd, 0x0, 0xd0, - 0x2, 0x86, 0x67, 0x90, 0xc0, 0xd, 0x0, 0xd0, - 0x3, 0xa0, 0x3, 0xa0, 0xc0, 0xd, 0x0, 0xd0, - 0x2, 0xa0, 0x3, 0xa3, 0x90, 0xd, 0x0, 0xd0, - 0x2, 0xa0, 0x3, 0xa9, 0x30, 0xd, 0x0, 0xd0, - 0x3, 0xc6, 0x67, 0xa8, 0x0, 0x8, 0x0, 0xd0, - 0x2, 0x40, 0x1, 0x80, 0x0, 0x0, 0x0, 0xd0, - 0x0, 0x0, 0x3, 0x0, 0x0, 0x0, 0x0, 0x10, - - /* U+8A18 "記" */ - 0x0, 0x8, 0x10, 0x0, 0x0, 0x0, 0x2, 0x0, - 0x0, 0x6, 0xa0, 0x2, 0x76, 0x66, 0x6f, 0x30, - 0x7, 0x67, 0x96, 0xa5, 0x0, 0x0, 0xe, 0x0, - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xe, 0x0, - 0x1, 0x66, 0x66, 0xa0, 0x0, 0x0, 0xe, 0x0, - 0x0, 0x10, 0x0, 0x0, 0x85, 0x55, 0x5e, 0x0, - 0x0, 0x0, 0x3, 0x30, 0xc1, 0x0, 0x9, 0x0, - 0x1, 0x76, 0x66, 0x50, 0xc1, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x0, 0x20, 0xc1, 0x0, 0x0, 0x0, - 0x3, 0xc6, 0x66, 0xe0, 0xc1, 0x0, 0x0, 0x0, - 0x2, 0xa0, 0x0, 0xd0, 0xc1, 0x0, 0x0, 0x40, - 0x2, 0xa0, 0x0, 0xd0, 0xc1, 0x0, 0x0, 0x70, - 0x2, 0xc6, 0x66, 0xd0, 0xc2, 0x0, 0x0, 0xc0, - 0x3, 0xa0, 0x0, 0xd0, 0x5d, 0xdd, 0xde, 0xc1, - 0x1, 0x20, 0x0, 0x10, 0x0, 0x0, 0x0, 0x0, - - /* U+8A2A "訪" */ - 0x0, 0x54, 0x0, 0x0, 0x4, 0x70, 0x0, 0x0, - 0x0, 0xe, 0x20, 0x0, 0x0, 0xa9, 0x0, 0x0, - 0x37, 0x6b, 0x69, 0x70, 0x0, 0x37, 0x1, 0x10, - 0x0, 0x0, 0x0, 0x7, 0x5b, 0x55, 0x58, 0x70, - 0x5, 0x66, 0x6a, 0x0, 0xf, 0x0, 0x0, 0x0, - 0x1, 0x0, 0x0, 0x0, 0xe, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x3, 0x0, 0x1e, 0x66, 0x6e, 0x20, - 0x5, 0x66, 0x66, 0x0, 0x2a, 0x0, 0xe, 0x0, - 0x0, 0x0, 0x2, 0x0, 0x57, 0x0, 0xd, 0x0, - 0xb, 0x66, 0x6e, 0x10, 0x83, 0x0, 0xc, 0x0, - 0xb, 0x10, 0xd, 0x0, 0xb0, 0x0, 0x2b, 0x0, - 0xb, 0x10, 0xd, 0x4, 0x60, 0x0, 0x49, 0x0, - 0xb, 0x66, 0x6d, 0x9, 0x1, 0x30, 0x96, 0x0, - 0xc, 0x10, 0xc, 0x61, 0x0, 0x4e, 0xd0, 0x0, - 0x1, 0x0, 0x0, 0x10, 0x0, 0x2, 0x0, 0x0, - - /* U+8A2D "設" */ - 0x0, 0x10, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x68, 0x0, 0x0, 0x96, 0x6b, 0x40, 0x0, - 0x0, 0xd, 0x22, 0x0, 0xe0, 0xb, 0x20, 0x0, - 0x37, 0x69, 0x69, 0x50, 0xd0, 0xb, 0x20, 0x0, - 0x0, 0x0, 0x1, 0x0, 0xc0, 0xb, 0x20, 0x0, - 0x6, 0x66, 0x69, 0x5, 0x70, 0xa, 0x42, 0x30, - 0x0, 0x0, 0x0, 0xa, 0x0, 0x4, 0xaa, 0x70, - 0x3, 0x66, 0x79, 0x56, 0x66, 0x66, 0xd4, 0x0, - 0x0, 0x0, 0x0, 0x0, 0x50, 0x3, 0xf5, 0x0, - 0x3, 0x0, 0x4, 0x0, 0x60, 0xa, 0x90, 0x0, - 0xb, 0x66, 0x6d, 0x0, 0x27, 0x3d, 0x0, 0x0, - 0xb, 0x10, 0x1c, 0x0, 0xa, 0xc2, 0x0, 0x0, - 0xb, 0x10, 0x1c, 0x0, 0xa, 0xc1, 0x0, 0x0, - 0xb, 0x66, 0x6c, 0x0, 0x93, 0x4d, 0x40, 0x0, - 0xb, 0x10, 0x8, 0x38, 0x10, 0x4, 0xec, 0x71, - 0x1, 0x0, 0x2, 0x20, 0x0, 0x0, 0x18, 0x10, - - /* U+8A31 "許" */ - 0x0, 0x46, 0x0, 0x0, 0x48, 0x0, 0x0, 0x0, - 0x0, 0xd5, 0x0, 0x7, 0x70, 0x0, 0x0, 0x27, - 0x6a, 0x77, 0x80, 0xb1, 0x0, 0x12, 0x0, 0x0, - 0x0, 0x0, 0x1c, 0x6a, 0x67, 0x80, 0x4, 0x66, - 0x79, 0x7, 0x20, 0xc1, 0x0, 0x0, 0x0, 0x0, - 0x1, 0x70, 0xc, 0x10, 0x0, 0x3, 0x66, 0x78, - 0x30, 0x0, 0xc1, 0x0, 0x0, 0x1, 0x0, 0x0, - 0x22, 0x2d, 0x32, 0x95, 0x2, 0x0, 0x4, 0x5, - 0x33, 0xd4, 0x33, 0x30, 0xb6, 0x66, 0xe0, 0x0, - 0xc, 0x10, 0x0, 0xb, 0x10, 0x1c, 0x0, 0x0, - 0xc1, 0x0, 0x0, 0xb1, 0x1, 0xc0, 0x0, 0xc, - 0x10, 0x0, 0xb, 0x66, 0x6c, 0x0, 0x0, 0xd1, - 0x0, 0x0, 0xc1, 0x0, 0x90, 0x0, 0xd, 0x10, - 0x0, 0x1, 0x0, 0x0, 0x0, 0x0, 0x50, 0x0, - 0x0, - - /* U+8A33 "訳" */ - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x75, 0x0, 0x0, 0x0, 0x0, 0x1, 0x0, - 0x0, 0x1d, 0x1, 0x1a, 0x76, 0x66, 0x6e, 0x20, - 0x37, 0x67, 0x67, 0x5a, 0x30, 0x0, 0xd, 0x0, - 0x0, 0x0, 0x2, 0xa, 0x30, 0x0, 0xd, 0x0, - 0x4, 0x76, 0x66, 0xa, 0x30, 0x0, 0xd, 0x0, - 0x0, 0x0, 0x0, 0x9, 0x87, 0x66, 0x6e, 0x0, - 0x4, 0x66, 0x78, 0xa, 0x34, 0x20, 0x3, 0x0, - 0x0, 0x0, 0x0, 0xa, 0x21, 0x60, 0x0, 0x0, - 0x8, 0x66, 0x6a, 0xb, 0x10, 0x90, 0x0, 0x0, - 0xc, 0x0, 0xd, 0xc, 0x0, 0xa1, 0x0, 0x0, - 0xc, 0x0, 0xd, 0xb, 0x0, 0x49, 0x0, 0x0, - 0xc, 0x0, 0xd, 0x47, 0x0, 0xc, 0x40, 0x0, - 0xc, 0x66, 0x6d, 0x91, 0x0, 0x2, 0xe3, 0x0, - 0x7, 0x0, 0x4, 0x60, 0x0, 0x0, 0x6f, 0x90, - 0x0, 0x0, 0x5, 0x0, 0x0, 0x0, 0x4, 0x10, - - /* U+8A34 "訴" */ - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x6, 0x80, 0x0, 0x0, 0x0, 0x29, 0x60, 0x0, - 0xd, 0x30, 0x10, 0xa7, 0x99, 0x64, 0x2, 0x76, - 0x86, 0x77, 0xd, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x2, 0x0, 0xd0, 0x0, 0x0, 0x0, 0x37, 0x66, - 0x80, 0xe, 0x66, 0x66, 0xa8, 0x0, 0x0, 0x0, - 0x0, 0xd0, 0xc, 0x20, 0x0, 0x37, 0x66, 0x90, - 0xd, 0x10, 0xc2, 0x0, 0x0, 0x0, 0x0, 0x1, - 0xc0, 0x6e, 0x60, 0x0, 0x76, 0x66, 0xa1, 0x3a, - 0x0, 0xc9, 0xe3, 0xa, 0x20, 0xd, 0x5, 0x70, - 0xc, 0x25, 0x90, 0xa2, 0x0, 0xd0, 0xa2, 0x0, - 0xc2, 0x0, 0xa, 0x20, 0xd, 0x1b, 0x0, 0xc, - 0x20, 0x0, 0xa7, 0x66, 0xd8, 0x20, 0x0, 0xc2, - 0x0, 0x8, 0x10, 0x5, 0x50, 0x0, 0xc, 0x20, - 0x0, 0x0, 0x0, 0x30, 0x0, 0x0, 0x10, 0x0, - - /* U+8A55 "評" */ - 0x0, 0x54, 0x0, 0x0, 0x0, 0x0, 0x6, 0x0, - 0x0, 0xd, 0x40, 0x4, 0x66, 0xd6, 0x66, 0x20, - 0x27, 0x6a, 0x79, 0x64, 0x0, 0xc1, 0x8, 0x20, - 0x0, 0x0, 0x0, 0x5, 0x90, 0xc1, 0x1e, 0x20, - 0x4, 0x66, 0x78, 0x0, 0xe3, 0xc1, 0x66, 0x0, - 0x1, 0x0, 0x0, 0x0, 0xa3, 0xc1, 0x80, 0x0, - 0x0, 0x0, 0x23, 0x0, 0x0, 0xc2, 0x11, 0x10, - 0x5, 0x66, 0x64, 0x27, 0x66, 0xd6, 0x6a, 0x90, - 0x1, 0x0, 0x2, 0x0, 0x0, 0xc1, 0x0, 0x0, - 0xc, 0x66, 0x6e, 0x10, 0x0, 0xc1, 0x0, 0x0, - 0xb, 0x10, 0xd, 0x0, 0x0, 0xc1, 0x0, 0x0, - 0xb, 0x10, 0xd, 0x0, 0x0, 0xc1, 0x0, 0x0, - 0xb, 0x66, 0x6d, 0x0, 0x0, 0xd1, 0x0, 0x0, - 0xc, 0x10, 0xd, 0x0, 0x0, 0xd1, 0x0, 0x0, - 0x2, 0x0, 0x1, 0x0, 0x0, 0x20, 0x0, 0x0, - - /* U+8A66 "試" */ - 0x0, 0x53, 0x0, 0x0, 0x0, 0x92, 0x0, 0x0, - 0x0, 0xe2, 0x0, 0x0, 0xc, 0x19, 0x70, 0x26, - 0x6b, 0x68, 0x80, 0x0, 0xc1, 0xb, 0x0, 0x0, - 0x0, 0x4, 0x55, 0x5d, 0x55, 0xb4, 0x4, 0x66, - 0x78, 0x10, 0x0, 0xb1, 0x0, 0x0, 0x11, 0x0, - 0x0, 0x0, 0xa, 0x30, 0x0, 0x0, 0x0, 0x12, - 0x24, 0x49, 0x94, 0x0, 0x0, 0x56, 0x66, 0x61, - 0x2d, 0x27, 0x60, 0x0, 0x0, 0x0, 0x1, 0x0, - 0xd0, 0x48, 0x0, 0x0, 0xb6, 0x66, 0xe0, 0xd, - 0x0, 0xc0, 0x0, 0xb, 0x10, 0x1c, 0x0, 0xd0, - 0x2b, 0x20, 0x20, 0xb1, 0x1, 0xc2, 0x7d, 0x60, - 0x4a, 0x24, 0xb, 0x66, 0x6c, 0x57, 0x0, 0x0, - 0xbc, 0x40, 0xb1, 0x1, 0xc0, 0x0, 0x0, 0x1, - 0xb7, 0x4, 0x0, 0x1, 0x0, 0x0, 0x0, 0x0, - 0x10, - - /* U+8A71 "話" */ - 0x0, 0x54, 0x0, 0x0, 0x0, 0x0, 0x6, 0x20, - 0x0, 0xe, 0x20, 0x3, 0x57, 0x9b, 0xdc, 0x70, - 0x27, 0x6a, 0x68, 0x61, 0x11, 0xd0, 0x0, 0x0, - 0x0, 0x0, 0x0, 0x0, 0x0, 0xd0, 0x0, 0x0, - 0x3, 0x44, 0x56, 0x0, 0x0, 0xd0, 0x2, 0x70, - 0x2, 0x22, 0x21, 0x46, 0x66, 0xe6, 0x66, 0x50, - 0x0, 0x0, 0x13, 0x0, 0x0, 0xd0, 0x0, 0x0, - 0x5, 0x66, 0x64, 0x1, 0x0, 0xd0, 0x2, 0x0, - 0x1, 0x0, 0x2, 0xd, 0x66, 0x96, 0x7e, 0x0, - 0xb, 0x66, 0x7d, 0xd, 0x0, 0x0, 0x1c, 0x0, - 0xb, 0x10, 0x1c, 0xd, 0x0, 0x0, 0x1c, 0x0, - 0xb, 0x10, 0x1c, 0xd, 0x0, 0x0, 0x1c, 0x0, - 0xb, 0x66, 0x6c, 0xd, 0x66, 0x66, 0x6c, 0x0, - 0xb, 0x10, 0x1b, 0xd, 0x0, 0x0, 0x1c, 0x0, - 0x1, 0x0, 0x0, 0x2, 0x0, 0x0, 0x1, 0x0, - - /* U+8A72 "該" */ - 0x0, 0x52, 0x0, 0x0, 0x7, 0x40, 0x0, 0x0, - 0x0, 0x1e, 0x20, 0x0, 0x0, 0xe3, 0x0, 0x0, - 0x26, 0x6c, 0x68, 0x80, 0x0, 0x42, 0x1, 0x60, - 0x0, 0x0, 0x0, 0x17, 0x67, 0x96, 0x66, 0x71, - 0x4, 0x66, 0x78, 0x0, 0xa, 0x90, 0x10, 0x0, - 0x1, 0x10, 0x0, 0x0, 0x78, 0x0, 0x8c, 0x0, - 0x0, 0x0, 0x12, 0xa, 0xa6, 0x77, 0xe3, 0x0, - 0x5, 0x66, 0x66, 0x7, 0x74, 0x2c, 0x30, 0x0, - 0x0, 0x0, 0x1, 0x0, 0x1, 0xb3, 0x1e, 0x30, - 0xb, 0x66, 0x6e, 0x0, 0x49, 0x10, 0xb9, 0x0, - 0xb, 0x10, 0x1c, 0x26, 0x30, 0x9, 0x90, 0x0, - 0xb, 0x10, 0x1c, 0x0, 0x0, 0xa8, 0x96, 0x0, - 0xb, 0x66, 0x6c, 0x0, 0x2b, 0x50, 0xa, 0xa0, - 0xc, 0x10, 0x1c, 0x7, 0x81, 0x0, 0x1, 0xf0, - 0x4, 0x0, 0x1, 0x20, 0x0, 0x0, 0x0, 0x20, - - /* U+8A73 "詳" */ - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x45, 0x0, 0x1, 0x50, 0x0, 0xb7, 0x0, - 0x0, 0xe, 0x30, 0x10, 0x87, 0x1, 0xd1, 0x0, - 0x27, 0x69, 0x68, 0x80, 0x2d, 0x6, 0x40, 0x0, - 0x0, 0x0, 0x0, 0x36, 0x68, 0x6b, 0x6a, 0x90, - 0x4, 0x66, 0x79, 0x0, 0x0, 0xe0, 0x0, 0x0, - 0x1, 0x0, 0x0, 0x0, 0x0, 0xe0, 0x1, 0x0, - 0x0, 0x0, 0x23, 0x4, 0x76, 0xe6, 0x8a, 0x0, - 0x5, 0x66, 0x64, 0x0, 0x0, 0xe0, 0x0, 0x0, - 0x1, 0x0, 0x2, 0x0, 0x0, 0xe0, 0x0, 0x10, - 0xb, 0x65, 0x6e, 0x47, 0x66, 0xe6, 0x69, 0xa0, - 0xb, 0x10, 0x1c, 0x0, 0x0, 0xe0, 0x0, 0x0, - 0xb, 0x10, 0x1c, 0x0, 0x0, 0xe0, 0x0, 0x0, - 0xb, 0x66, 0x6c, 0x0, 0x0, 0xe0, 0x0, 0x0, - 0xb, 0x10, 0x9, 0x0, 0x0, 0xf0, 0x0, 0x0, - 0x0, 0x0, 0x0, 0x0, 0x0, 0x40, 0x0, 0x0, - - /* U+8A8C "誌" */ - 0x0, 0x64, 0x0, 0x0, 0x0, 0x92, 0x0, 0x0, - 0x0, 0xf, 0x20, 0x0, 0x0, 0xd0, 0x0, 0x0, - 0x27, 0x6b, 0x68, 0x70, 0x0, 0xd0, 0x3, 0x10, - 0x0, 0x0, 0x0, 0x17, 0x55, 0xe5, 0x59, 0x70, - 0x4, 0x66, 0x78, 0x0, 0x0, 0xd0, 0x0, 0x0, - 0x1, 0x10, 0x0, 0x0, 0x0, 0xd0, 0x3, 0x0, - 0x0, 0x0, 0x13, 0x4, 0x76, 0x96, 0x79, 0x0, - 0x5, 0x66, 0x65, 0x0, 0x2, 0x10, 0x0, 0x0, - 0x0, 0x0, 0x1, 0x0, 0x20, 0xb4, 0x0, 0x0, - 0xb, 0x66, 0x6e, 0x2, 0xd2, 0x4c, 0x6, 0x0, - 0xb, 0x10, 0x1c, 0x16, 0xd0, 0x1, 0x5, 0xd0, - 0xb, 0x10, 0x1c, 0x86, 0xd0, 0x0, 0x50, 0xb2, - 0xb, 0x66, 0x6c, 0xa1, 0xc2, 0x0, 0xa1, 0x0, - 0xb, 0x10, 0x1c, 0x0, 0x5b, 0xcc, 0xa1, 0x0, - 0x4, 0x0, 0x2, 0x0, 0x0, 0x0, 0x0, 0x0, - - /* U+8A8D "認" */ - 0x0, 0x56, 0x0, 0x0, 0x0, 0x0, 0x1, 0x0, - 0x0, 0xd, 0x30, 0x4, 0x77, 0x86, 0x6d, 0x40, - 0x27, 0x69, 0x68, 0x61, 0x6, 0x70, 0xd, 0x0, - 0x0, 0x0, 0x0, 0x7, 0x9, 0x50, 0xd, 0x0, - 0x4, 0x66, 0x78, 0x2d, 0xd, 0x0, 0xe, 0x0, - 0x1, 0x10, 0x0, 0x12, 0x68, 0x0, 0x3c, 0x0, - 0x0, 0x0, 0x12, 0x2, 0xb0, 0x38, 0xb7, 0x0, - 0x5, 0x66, 0x64, 0x17, 0x1, 0x43, 0x80, 0x0, - 0x2, 0x0, 0x2, 0x0, 0x20, 0x95, 0x0, 0x0, - 0xb, 0x66, 0x6e, 0x2, 0xd2, 0x4a, 0x14, 0x0, - 0xb, 0x10, 0x1c, 0x26, 0xd0, 0x0, 0x7, 0x80, - 0xb, 0x10, 0x1c, 0xa5, 0xd0, 0x0, 0x60, 0xc0, - 0xb, 0x66, 0x6c, 0x60, 0xc2, 0x0, 0xc1, 0x0, - 0xb, 0x10, 0x1c, 0x0, 0x4b, 0xcc, 0xa1, 0x0, - 0x3, 0x0, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, - - /* U+8A95 "誕" */ - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x81, 0x0, 0x0, 0x0, 0x0, 0x2, 0x0, - 0x0, 0x4a, 0x4, 0x76, 0xd1, 0x15, 0xad, 0x50, - 0x27, 0x69, 0x97, 0x5, 0xa0, 0x43, 0xc0, 0x0, - 0x0, 0x0, 0x0, 0xb, 0x20, 0x0, 0xc0, 0x0, - 0x5, 0x66, 0xa1, 0x2c, 0x0, 0x60, 0xc0, 0x0, - 0x0, 0x0, 0x0, 0xa5, 0x20, 0xc0, 0xd8, 0x50, - 0x4, 0x66, 0xa2, 0xb6, 0xd6, 0xc0, 0xc1, 0x0, - 0x0, 0x0, 0x0, 0x0, 0xe1, 0xc0, 0xc0, 0x0, - 0x7, 0x66, 0xa5, 0x11, 0xd0, 0xc0, 0xc0, 0x0, - 0xa, 0x10, 0xa3, 0x86, 0x70, 0xc0, 0xc1, 0x0, - 0xa, 0x10, 0xa2, 0x5e, 0x11, 0xc6, 0x98, 0x60, - 0xa, 0x10, 0xa2, 0x6b, 0xa0, 0x0, 0x0, 0x0, - 0xa, 0x66, 0xb4, 0x90, 0x5d, 0xa6, 0x43, 0x30, - 0x5, 0x0, 0x27, 0x0, 0x0, 0x5a, 0xdf, 0x60, - 0x0, 0x0, 0x30, 0x0, 0x0, 0x0, 0x0, 0x0, - - /* U+8A98 "誘" */ - 0x0, 0x82, 0x0, 0x0, 0x0, 0x37, 0xc6, 0x0, - 0x0, 0x3b, 0x10, 0x5, 0x78, 0xe5, 0x43, 0x0, - 0x27, 0x68, 0x87, 0x0, 0x0, 0xd0, 0x2, 0x10, - 0x0, 0x0, 0x10, 0x66, 0x6a, 0xe7, 0x68, 0x70, - 0x5, 0x66, 0xa1, 0x0, 0x4b, 0xd6, 0x10, 0x0, - 0x0, 0x0, 0x0, 0x4, 0xa0, 0xd0, 0xc3, 0x0, - 0x5, 0x65, 0xa1, 0x76, 0x0, 0xe0, 0x2d, 0x90, - 0x0, 0x0, 0x2, 0x15, 0x66, 0x86, 0x91, 0x10, - 0x8, 0x55, 0xa3, 0x2, 0x4a, 0x2, 0xc1, 0x0, - 0xb, 0x10, 0xb2, 0x0, 0x68, 0x8, 0x62, 0x20, - 0xb, 0x10, 0xb2, 0x0, 0xb4, 0x7, 0x6b, 0x90, - 0xb, 0x10, 0xb2, 0x2, 0xc0, 0x0, 0xa, 0x40, - 0xc, 0x66, 0xc2, 0x1b, 0x20, 0x0, 0xd, 0x10, - 0x6, 0x0, 0x14, 0x81, 0x0, 0x39, 0xc9, 0x0, - 0x0, 0x0, 0x21, 0x0, 0x0, 0x2, 0x60, 0x0, - - /* U+8A9E "語" */ - 0x0, 0x53, 0x0, 0x0, 0x0, 0x0, 0x3, 0x0, - 0x0, 0xe, 0x20, 0x37, 0x6b, 0x66, 0x79, 0x0, - 0x26, 0x6b, 0x6a, 0x30, 0x3c, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x0, 0x5, 0x9c, 0x55, 0xc1, 0x0, - 0x4, 0x66, 0x77, 0x0, 0x77, 0x0, 0xe0, 0x0, - 0x1, 0x10, 0x0, 0x0, 0x95, 0x0, 0xd0, 0x0, - 0x0, 0x0, 0x12, 0x11, 0xb5, 0x12, 0xd3, 0x90, - 0x5, 0x66, 0x65, 0x45, 0x55, 0x55, 0x55, 0x50, - 0x0, 0x0, 0x1, 0x4, 0x11, 0x11, 0x26, 0x0, - 0xb, 0x66, 0x6d, 0xb, 0x75, 0x55, 0x7c, 0x0, - 0xb, 0x10, 0x1c, 0xb, 0x30, 0x0, 0x3a, 0x0, - 0xb, 0x10, 0x1c, 0xb, 0x30, 0x0, 0x3a, 0x0, - 0xb, 0x66, 0x6c, 0xb, 0x76, 0x66, 0x8b, 0x0, - 0xb, 0x10, 0xb, 0xb, 0x20, 0x0, 0x3a, 0x0, - 0x1, 0x0, 0x0, 0x1, 0x0, 0x0, 0x0, 0x0, - - /* U+8AAA "說" */ - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x44, 0x0, 0x0, 0xc, 0x27, 0x0, 0x0, - 0x0, 0xd, 0x30, 0x0, 0x69, 0x8, 0x10, 0x0, - 0x27, 0x6a, 0x69, 0x70, 0xc0, 0x2, 0xa0, 0x0, - 0x0, 0x0, 0x0, 0x9, 0x30, 0x0, 0x7c, 0x20, - 0x4, 0x66, 0x79, 0x54, 0xa6, 0x66, 0x9e, 0x70, - 0x1, 0x0, 0x0, 0x10, 0xd0, 0x0, 0x75, 0x0, - 0x0, 0x0, 0x13, 0x0, 0xd0, 0x0, 0x75, 0x0, - 0x5, 0x66, 0x65, 0x0, 0xd0, 0x0, 0x76, 0x0, - 0x1, 0x0, 0x2, 0x0, 0xe9, 0x7a, 0xa5, 0x0, - 0xb, 0x66, 0x6f, 0x10, 0x1a, 0x2d, 0x0, 0x0, - 0xb, 0x10, 0xd, 0x0, 0xc, 0xd, 0x0, 0x0, - 0xb, 0x10, 0xd, 0x0, 0x2a, 0xd, 0x0, 0x40, - 0xb, 0x66, 0x6d, 0x0, 0x92, 0xd, 0x0, 0x70, - 0xb, 0x10, 0xc, 0x7, 0x30, 0xa, 0xbc, 0xa0, - 0x1, 0x0, 0x0, 0x41, 0x0, 0x0, 0x0, 0x0, - - /* U+8AAC "説" */ - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x64, 0x0, 0x3, 0x40, 0x0, 0xd3, 0x0, - 0x0, 0xf, 0x20, 0x0, 0xb3, 0x5, 0xb0, 0x0, - 0x27, 0x6b, 0x6a, 0x30, 0x79, 0xa, 0x10, 0x0, - 0x0, 0x0, 0x0, 0x6, 0x55, 0x58, 0x58, 0x0, - 0x5, 0x66, 0x6a, 0xd, 0x22, 0x22, 0x4b, 0x0, - 0x0, 0x0, 0x0, 0xd, 0x0, 0x0, 0x3a, 0x0, - 0x4, 0x66, 0x69, 0xd, 0x0, 0x0, 0x3a, 0x0, - 0x1, 0x10, 0x0, 0xd, 0x55, 0x55, 0x7a, 0x0, - 0x3, 0x0, 0x6, 0xb, 0x3b, 0x1d, 0x33, 0x0, - 0xb, 0x66, 0x6e, 0x0, 0x2a, 0xd, 0x0, 0x0, - 0xb, 0x10, 0xd, 0x0, 0x48, 0xd, 0x0, 0x30, - 0xb, 0x10, 0xd, 0x0, 0xa3, 0xd, 0x0, 0x60, - 0xb, 0x66, 0x6d, 0x5, 0x80, 0xd, 0x0, 0xa0, - 0x9, 0x0, 0x4, 0x77, 0x0, 0xa, 0xbb, 0xd1, - 0x0, 0x0, 0x5, 0x10, 0x0, 0x0, 0x0, 0x0, - - /* U+8AAD "読" */ - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x72, 0x0, 0x0, 0x1, 0xc0, 0x0, 0x0, - 0x0, 0x3a, 0x1, 0x0, 0x1, 0xd0, 0x2, 0x0, - 0x27, 0x68, 0x87, 0x57, 0x66, 0xe6, 0x6a, 0x60, - 0x0, 0x0, 0x10, 0x0, 0x1, 0xd0, 0x0, 0x0, - 0x5, 0x66, 0x93, 0x6, 0x66, 0xa6, 0x6a, 0x0, - 0x0, 0x0, 0x0, 0x12, 0x0, 0x0, 0x0, 0x10, - 0x5, 0x66, 0xa3, 0x68, 0x66, 0x66, 0x6a, 0xc0, - 0x0, 0x0, 0x0, 0xd1, 0x41, 0x3, 0x8, 0x10, - 0x8, 0x66, 0xa3, 0x0, 0xa6, 0xe, 0x10, 0x0, - 0xc, 0x10, 0xb2, 0x0, 0xb3, 0xd, 0x0, 0x0, - 0xb, 0x10, 0xb2, 0x0, 0xe0, 0xd, 0x0, 0x40, - 0xb, 0x10, 0xb2, 0x4, 0xa0, 0xd, 0x0, 0x50, - 0xc, 0x66, 0xc2, 0x1c, 0x10, 0xd, 0x2, 0x70, - 0x7, 0x0, 0x22, 0x92, 0x0, 0x9, 0xcd, 0xa0, - 0x0, 0x0, 0x24, 0x0, 0x0, 0x0, 0x0, 0x0, - - /* U+8AB0 "誰" */ - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x64, 0x0, 0x0, 0x69, 0x53, 0x0, 0x0, - 0x0, 0xe, 0x20, 0x0, 0xb3, 0xd, 0x40, 0x0, - 0x37, 0x6b, 0x6a, 0x61, 0xc0, 0x4, 0x14, 0x40, - 0x0, 0x0, 0x0, 0x6, 0xc6, 0x6d, 0x66, 0x50, - 0x5, 0x66, 0x78, 0xc, 0xb0, 0x1c, 0x0, 0x0, - 0x1, 0x0, 0x0, 0x66, 0xb0, 0x1c, 0x4, 0x0, - 0x0, 0x0, 0x13, 0x52, 0xc6, 0x6d, 0x68, 0x50, - 0x6, 0x66, 0x65, 0x2, 0xb0, 0x1c, 0x0, 0x0, - 0x0, 0x0, 0x1, 0x2, 0xb0, 0x1c, 0x0, 0x0, - 0xb, 0x66, 0x6e, 0x2, 0xc6, 0x6d, 0x6b, 0x50, - 0xb, 0x10, 0x1c, 0x2, 0xb0, 0x1c, 0x0, 0x0, - 0xb, 0x10, 0x1c, 0x2, 0xb0, 0x1c, 0x0, 0x0, - 0xb, 0x76, 0x6c, 0x2, 0xb0, 0x1c, 0x3, 0x70, - 0xb, 0x10, 0x1c, 0x2, 0xc6, 0x66, 0x66, 0x50, - 0x4, 0x0, 0x1, 0x1, 0x30, 0x0, 0x0, 0x0, - - /* U+8AB2 "課" */ - 0x0, 0x52, 0x0, 0x4, 0x0, 0x0, 0x5, 0x0, - 0x0, 0x1f, 0x0, 0xd, 0x66, 0xe6, 0x7d, 0x0, - 0x27, 0x6b, 0x6a, 0x2d, 0x0, 0xd0, 0x2b, 0x0, - 0x0, 0x0, 0x0, 0xd, 0x66, 0xe6, 0x7b, 0x0, - 0x5, 0x66, 0x88, 0xd, 0x0, 0xd0, 0x2b, 0x0, - 0x0, 0x0, 0x0, 0xd, 0x66, 0xe6, 0x7b, 0x0, - 0x4, 0x66, 0x87, 0x7, 0x0, 0xd0, 0x14, 0x0, - 0x1, 0x0, 0x0, 0x11, 0x11, 0xd1, 0x14, 0x70, - 0x7, 0x66, 0x69, 0x34, 0x3e, 0xe8, 0x33, 0x30, - 0xa, 0x20, 0x3a, 0x0, 0x4a, 0xd8, 0x0, 0x0, - 0xa, 0x20, 0x3a, 0x0, 0xc2, 0xd4, 0x70, 0x0, - 0xa, 0x20, 0x3a, 0x8, 0x50, 0xd0, 0xb3, 0x0, - 0xa, 0x76, 0x7a, 0x66, 0x0, 0xd0, 0x2e, 0x80, - 0x6, 0x10, 0x5, 0x30, 0x0, 0xe0, 0x2, 0x40, - 0x0, 0x0, 0x0, 0x0, 0x0, 0x40, 0x0, 0x0, - - /* U+8ABF "調" */ - 0x0, 0x83, 0x0, 0x4, 0x0, 0x0, 0x1, 0x60, - 0x0, 0x2f, 0x0, 0xe, 0x66, 0xa8, 0x67, 0xc0, - 0x27, 0x6a, 0x6a, 0x3d, 0x0, 0x84, 0x3, 0xa0, - 0x0, 0x0, 0x0, 0xd, 0x17, 0xb8, 0xa4, 0xa0, - 0x5, 0x76, 0x6a, 0xd, 0x0, 0x84, 0x3, 0xa0, - 0x0, 0x0, 0x0, 0xd, 0x0, 0x84, 0x44, 0xa0, - 0x2, 0x33, 0x37, 0xd, 0x66, 0x66, 0x66, 0xa0, - 0x2, 0x32, 0x22, 0xc, 0x8, 0x66, 0x93, 0xa0, - 0x3, 0x0, 0x4, 0xc, 0xc, 0x1, 0xb3, 0xa0, - 0xc, 0x66, 0x6e, 0x2b, 0xc, 0x1, 0xb3, 0xa0, - 0xb, 0x10, 0x1c, 0x48, 0xd, 0x66, 0xb3, 0xa0, - 0xb, 0x10, 0x1c, 0x83, 0x6, 0x0, 0x43, 0xa0, - 0xc, 0x66, 0x6a, 0xa0, 0x0, 0x3, 0x36, 0x90, - 0x4, 0x0, 0x5, 0x20, 0x0, 0x0, 0x5e, 0x50, - 0x0, 0x0, 0x2, 0x0, 0x0, 0x0, 0x1, 0x0, - - /* U+8AC7 "談" */ - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x93, 0x0, 0x0, 0x9, 0x40, 0x0, 0x0, - 0x0, 0x2f, 0x1, 0x0, 0x5a, 0x30, 0x4e, 0x20, - 0x37, 0x69, 0x6a, 0x34, 0x8a, 0x39, 0xb3, 0x0, - 0x0, 0x0, 0x0, 0x1e, 0x3b, 0xb2, 0x0, 0x0, - 0x6, 0x66, 0x97, 0x1, 0x1f, 0x77, 0x30, 0x0, - 0x0, 0x0, 0x0, 0x0, 0xa8, 0x1, 0xb9, 0x0, - 0x5, 0x66, 0x96, 0x19, 0x58, 0x60, 0xb, 0x0, - 0x1, 0x0, 0x0, 0x20, 0x9, 0x60, 0x2, 0x0, - 0x3, 0x0, 0x5, 0x0, 0x7b, 0x70, 0x9e, 0x10, - 0xb, 0x66, 0x6e, 0x1c, 0x4d, 0x99, 0x40, 0x0, - 0xb, 0x10, 0x1c, 0x26, 0x2c, 0x72, 0x0, 0x0, - 0xb, 0x10, 0x1c, 0x0, 0xa5, 0x1b, 0x0, 0x0, - 0xb, 0x66, 0x6c, 0x4, 0xa0, 0x9, 0xa1, 0x0, - 0xc, 0x10, 0x9, 0x58, 0x0, 0x0, 0xce, 0x81, - 0x2, 0x0, 0x5, 0x30, 0x0, 0x0, 0x7, 0x20, - - /* U+8ACB "請" */ - 0x0, 0x63, 0x0, 0x0, 0x0, 0xa1, 0x0, 0x0, - 0x0, 0xf, 0x10, 0x0, 0x0, 0xd0, 0x3, 0x10, - 0x26, 0x5a, 0x5a, 0x47, 0x66, 0xe6, 0x68, 0x60, - 0x0, 0x0, 0x0, 0x5, 0x66, 0xe6, 0x6b, 0x10, - 0x5, 0x76, 0x7a, 0x1, 0x0, 0xd0, 0x0, 0x0, - 0x0, 0x0, 0x0, 0x46, 0x66, 0xe6, 0x69, 0xc0, - 0x0, 0x0, 0x14, 0x11, 0x0, 0x0, 0x2, 0x0, - 0x5, 0x66, 0x65, 0xb, 0x66, 0x66, 0x6e, 0x10, - 0x1, 0x0, 0x2, 0xb, 0x21, 0x11, 0x1d, 0x0, - 0xb, 0x66, 0x6e, 0xb, 0x65, 0x55, 0x5d, 0x0, - 0xb, 0x10, 0x1c, 0xb, 0x76, 0x66, 0x6d, 0x0, - 0xb, 0x10, 0x1c, 0xb, 0x20, 0x0, 0xd, 0x0, - 0xb, 0x66, 0x6c, 0xb, 0x20, 0x0, 0xd, 0x0, - 0x8, 0x0, 0x6, 0xb, 0x20, 0x18, 0xeb, 0x0, - 0x0, 0x0, 0x0, 0x4, 0x0, 0x0, 0x41, 0x0, - - /* U+8AD6 "論" */ - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x61, 0x0, 0x0, 0x2, 0xc1, 0x0, 0x0, - 0x0, 0x2c, 0x0, 0x0, 0x9, 0xc0, 0x0, 0x0, - 0x27, 0x6b, 0x6c, 0x30, 0x2d, 0x26, 0x0, 0x0, - 0x0, 0x0, 0x0, 0x0, 0xb3, 0x9, 0x30, 0x0, - 0x3, 0x44, 0x92, 0xa, 0x40, 0x3, 0xd5, 0x0, - 0x2, 0x22, 0x22, 0x93, 0x76, 0x6a, 0x7d, 0xb1, - 0x0, 0x0, 0x44, 0x2, 0x0, 0x0, 0x4, 0x10, - 0x5, 0x66, 0x62, 0xd, 0x6c, 0x6c, 0x6d, 0x20, - 0x1, 0x0, 0x20, 0xc, 0xc, 0xc, 0xc, 0x0, - 0xa, 0x65, 0xd5, 0xd, 0x6d, 0x6d, 0x6d, 0x0, - 0xa, 0x10, 0xb1, 0xc, 0xc, 0xc, 0xc, 0x0, - 0xa, 0x10, 0xb1, 0xc, 0xc, 0xc, 0xc, 0x0, - 0xa, 0x66, 0xc1, 0xc, 0xb, 0x9, 0xc, 0x0, - 0xb, 0x10, 0xa1, 0xc, 0x0, 0x4, 0x9e, 0x0, - 0x3, 0x0, 0x10, 0x2, 0x0, 0x0, 0x34, 0x0, - - /* U+8AF8 "諸" */ - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x73, 0x0, 0x0, 0xc, 0x10, 0x0, 0x0, - 0x0, 0x1c, 0x1, 0x0, 0xd, 0x0, 0xb, 0x70, - 0x27, 0x68, 0x78, 0x26, 0x6e, 0x6c, 0x6d, 0x0, - 0x0, 0x0, 0x10, 0x2, 0xd, 0x0, 0xc3, 0x0, - 0x5, 0x66, 0xa2, 0x0, 0xd, 0x9, 0x61, 0x10, - 0x0, 0x0, 0x1, 0x76, 0x6a, 0xad, 0x69, 0x90, - 0x5, 0x66, 0xb1, 0x0, 0x7, 0xa0, 0x0, 0x0, - 0x0, 0x0, 0x0, 0x3, 0xa7, 0x0, 0x5, 0x0, - 0x3, 0x0, 0x40, 0x1d, 0x76, 0x66, 0x8d, 0x0, - 0xa, 0x76, 0xc8, 0x6b, 0x20, 0x0, 0x3a, 0x0, - 0xa, 0x20, 0xb2, 0xb, 0x76, 0x66, 0x7a, 0x0, - 0xa, 0x20, 0xb2, 0xb, 0x20, 0x0, 0x3a, 0x0, - 0xa, 0x75, 0xc2, 0xb, 0x76, 0x66, 0x7a, 0x0, - 0x7, 0x10, 0x61, 0xa, 0x10, 0x0, 0x28, 0x0, - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - - /* U+8B02 "謂" */ - 0x0, 0x56, 0x0, 0x3, 0x0, 0x0, 0x1, 0x30, - 0x0, 0xe, 0x31, 0xe, 0x66, 0xe6, 0x69, 0xb0, - 0x37, 0x59, 0x58, 0x5d, 0x0, 0xd0, 0x5, 0x80, - 0x0, 0x0, 0x1, 0xd, 0x66, 0xe6, 0x69, 0x80, - 0x6, 0x66, 0x6a, 0xd, 0x0, 0xd0, 0x5, 0x80, - 0x0, 0x0, 0x0, 0xe, 0x66, 0x86, 0x69, 0x70, - 0x5, 0x66, 0x6b, 0x4, 0x10, 0x0, 0x5, 0x0, - 0x0, 0x0, 0x0, 0x4, 0xb6, 0x66, 0x6e, 0x10, - 0x7, 0x66, 0x6a, 0x4, 0xb5, 0x55, 0x5d, 0x0, - 0xb, 0x10, 0xd, 0x4, 0x80, 0x0, 0xd, 0x0, - 0xb, 0x10, 0xd, 0x4, 0xb6, 0x66, 0x6d, 0x0, - 0xb, 0x10, 0xd, 0x4, 0x80, 0x0, 0xd, 0x0, - 0xc, 0x66, 0x6d, 0x4, 0x80, 0x0, 0xd, 0x0, - 0xa, 0x0, 0x9, 0x4, 0x80, 0x17, 0xda, 0x0, - 0x0, 0x0, 0x0, 0x1, 0x0, 0x0, 0x30, 0x0, - - /* U+8B1B "講" */ - 0x0, 0x61, 0x0, 0x0, 0x83, 0x4, 0x60, 0x0, - 0x0, 0x2e, 0x0, 0x0, 0xa2, 0x5, 0x62, 0x40, - 0x26, 0x5b, 0x69, 0x66, 0xc7, 0x69, 0xa6, 0x50, - 0x0, 0x0, 0x0, 0x16, 0xc7, 0x69, 0xa9, 0x30, - 0x5, 0x66, 0xb2, 0x2, 0xa2, 0x5, 0x60, 0x20, - 0x0, 0x0, 0x1, 0x76, 0x96, 0x77, 0x86, 0xa2, - 0x2, 0x33, 0x81, 0x2, 0x0, 0xd1, 0x4, 0x0, - 0x3, 0x33, 0x31, 0xc, 0x66, 0xd6, 0x6d, 0x0, - 0x4, 0x11, 0x60, 0xc, 0x0, 0xc0, 0xb, 0x0, - 0xc, 0x55, 0xd2, 0xc, 0x66, 0xd6, 0x6b, 0x0, - 0xc, 0x0, 0xc0, 0xc, 0x0, 0xc0, 0xb, 0x50, - 0xc, 0x0, 0xc1, 0x7d, 0x66, 0x76, 0x6d, 0x61, - 0xc, 0x66, 0xd0, 0xc, 0x0, 0x0, 0xb, 0x0, - 0x9, 0x0, 0x50, 0xc, 0x0, 0x6, 0xba, 0x0, - 0x0, 0x0, 0x0, 0x4, 0x0, 0x0, 0x42, 0x0, - - /* U+8B1D "謝" */ - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x70, 0x0, 0x3, 0xa0, 0x0, 0x9, 0x0, - 0x0, 0x6a, 0x0, 0x6, 0x22, 0x0, 0xc, 0x0, - 0x26, 0x7a, 0x96, 0xc7, 0x6d, 0x10, 0xc, 0x0, - 0x0, 0x0, 0x0, 0xc0, 0xc, 0x0, 0xc, 0x20, - 0x5, 0x66, 0xa0, 0xc6, 0x6d, 0x47, 0x6e, 0x90, - 0x1, 0x0, 0x0, 0xc0, 0xc, 0x0, 0xc, 0x0, - 0x0, 0x0, 0x50, 0xc6, 0x6d, 0x34, 0xc, 0x0, - 0x5, 0x66, 0x61, 0xc0, 0xc, 0xb, 0x4c, 0x0, - 0x2, 0x0, 0x25, 0xb5, 0x8d, 0x5, 0x5c, 0x0, - 0xa, 0x66, 0xd1, 0x1, 0xcc, 0x0, 0xc, 0x0, - 0xa, 0x10, 0xc0, 0x9, 0x3c, 0x0, 0xc, 0x0, - 0xa, 0x10, 0xc0, 0x47, 0xc, 0x0, 0xc, 0x0, - 0xa, 0x66, 0xd3, 0x70, 0xc, 0x1, 0x1c, 0x0, - 0x7, 0x0, 0x44, 0x3, 0xbd, 0x5, 0xe8, 0x0, - 0x0, 0x0, 0x0, 0x0, 0x11, 0x0, 0x20, 0x0, - - /* U+8B58 "識" */ - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x15, 0x0, 0x0, 0x80, 0x0, 0xa2, 0x0, 0x0, - 0xb5, 0x0, 0x8, 0x52, 0xb, 0x11, 0x2, 0x6a, - 0x7a, 0x57, 0x66, 0x93, 0xb0, 0xa4, 0x0, 0x0, - 0x1, 0x80, 0xd, 0x2b, 0x3, 0x80, 0x56, 0x78, - 0xb, 0x34, 0x50, 0xb0, 0x0, 0x0, 0x0, 0x5, - 0x86, 0xa6, 0x6d, 0x6c, 0x50, 0x22, 0x46, 0x11, - 0x0, 0x10, 0xb0, 0x61, 0x4, 0x44, 0x30, 0xd6, - 0x6d, 0xa, 0x1e, 0x20, 0x30, 0x15, 0xc, 0x0, - 0xc0, 0x97, 0xa0, 0xc, 0x55, 0xd0, 0xd6, 0x6c, - 0x6, 0xe3, 0x0, 0xc0, 0xc, 0xc, 0x0, 0xc0, - 0x5d, 0x2, 0xc, 0x0, 0xc0, 0xc0, 0xc, 0xd, - 0xd1, 0x60, 0xc6, 0x6c, 0xd, 0x66, 0xb8, 0x53, - 0xb9, 0xa, 0x0, 0x90, 0x40, 0x6, 0x50, 0x6, - 0xb0, 0x0, 0x0, 0x0, 0x0, 0x20, 0x0, 0x2, - - /* U+8B70 "議" */ - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x81, 0x0, 0x0, 0x84, 0x2, 0xd0, 0x0, - 0x0, 0x59, 0x0, 0x0, 0x1d, 0x7, 0x25, 0x0, - 0x37, 0x69, 0x89, 0x37, 0x67, 0xc6, 0x67, 0x40, - 0x0, 0x0, 0x0, 0x2, 0x33, 0xc3, 0x64, 0x0, - 0x5, 0x66, 0xa0, 0x2, 0x43, 0xc3, 0x32, 0x0, - 0x0, 0x0, 0x0, 0x46, 0x55, 0xc5, 0x59, 0x90, - 0x4, 0x66, 0xa0, 0x0, 0x6, 0x37, 0x21, 0x0, - 0x1, 0x0, 0x0, 0x47, 0xe6, 0x49, 0x1c, 0x0, - 0x5, 0x22, 0x71, 0x0, 0xc0, 0x1a, 0x4, 0x50, - 0xc, 0x44, 0xd3, 0x76, 0xd6, 0x6d, 0x67, 0x70, - 0xc, 0x0, 0xc0, 0x0, 0xc5, 0x2b, 0x2d, 0x0, - 0xc, 0x0, 0xc1, 0xaa, 0xd0, 0x8, 0xc2, 0x0, - 0xc, 0x66, 0xd0, 0x20, 0xc0, 0x1b, 0xc1, 0x40, - 0x8, 0x0, 0x70, 0x39, 0xe4, 0x70, 0x4d, 0xb0, - 0x0, 0x0, 0x0, 0x1, 0x20, 0x0, 0x1, 0x70, - - /* U+8B77 "護" */ - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x82, 0x0, 0x0, 0x85, 0x9, 0x40, 0x0, - 0x0, 0x2c, 0x1, 0x56, 0xa8, 0x6b, 0x87, 0xc0, - 0x37, 0x69, 0x79, 0x21, 0x75, 0x28, 0x30, 0x0, - 0x0, 0x0, 0x0, 0x9, 0x60, 0xd1, 0x3, 0x0, - 0x6, 0x65, 0xa1, 0x1f, 0x55, 0xc5, 0x5a, 0x30, - 0x0, 0x0, 0x0, 0x9d, 0x66, 0xd6, 0x78, 0x0, - 0x4, 0x55, 0xa5, 0x3c, 0x0, 0xc0, 0x13, 0x0, - 0x1, 0x11, 0x10, 0xc, 0x66, 0xd6, 0x67, 0x0, - 0x6, 0x33, 0x81, 0xc, 0x66, 0xa6, 0x69, 0x90, - 0xc, 0x22, 0xc1, 0x38, 0x66, 0x66, 0xa2, 0x0, - 0xc, 0x0, 0xc0, 0x1, 0x60, 0x4, 0xc3, 0x0, - 0xc, 0x0, 0xc0, 0x0, 0x28, 0x4a, 0x0, 0x0, - 0xc, 0x66, 0xd0, 0x0, 0xb, 0xe1, 0x0, 0x0, - 0xa, 0x0, 0x80, 0x6, 0xb4, 0x6e, 0x84, 0x20, - 0x0, 0x0, 0x5, 0x73, 0x0, 0x3, 0xae, 0x80, - - /* U+8B8A "變" */ - 0x0, 0x0, 0x0, 0x2, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x1d, 0x10, 0x8, 0x40, 0x0, 0x86, 0x0, - 0x0, 0xa6, 0x12, 0x76, 0x6a, 0x22, 0xc1, 0x0, - 0x9, 0x80, 0xc1, 0x56, 0x6a, 0x4d, 0x17, 0x50, - 0x6, 0x38, 0x30, 0x20, 0x4, 0x25, 0x38, 0x0, - 0x0, 0x54, 0x61, 0x88, 0x78, 0x1, 0x91, 0x60, - 0x4, 0xb2, 0x28, 0x86, 0x6b, 0xc, 0x50, 0xb0, - 0x0, 0x10, 0x40, 0xa1, 0xb, 0x2, 0x1, 0x0, - 0x2, 0x49, 0x48, 0x96, 0x69, 0x7, 0x63, 0xb0, - 0x9, 0x17, 0x3a, 0x0, 0x0, 0x35, 0x85, 0x50, - 0x0, 0x0, 0xc9, 0x66, 0x66, 0xc8, 0x74, 0x0, - 0x0, 0x9, 0x34, 0x20, 0x5, 0xb0, 0x0, 0x0, - 0x0, 0x61, 0x0, 0x83, 0x3c, 0x10, 0x0, 0x0, - 0x0, 0x0, 0x0, 0xd, 0xd1, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x5, 0xb6, 0x8c, 0x63, 0x10, 0x0, - 0x1, 0x57, 0x85, 0x0, 0x1, 0x8c, 0xfd, 0x40, - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - - /* U+8B93 "讓" */ - 0x0, 0x0, 0x0, 0x0, 0x1, 0x0, 0x0, 0x0, - 0x0, 0x70, 0x0, 0x0, 0x4, 0xb0, 0x0, 0x0, - 0x0, 0x69, 0x0, 0x56, 0x66, 0xe6, 0x6a, 0xb0, - 0x38, 0x8a, 0xa7, 0x12, 0x2, 0x1, 0x2, 0x0, - 0x0, 0x0, 0x0, 0xd, 0x6d, 0x2c, 0x6d, 0x20, - 0x5, 0x65, 0xa1, 0xc, 0x6c, 0xc, 0x6c, 0x0, - 0x0, 0x0, 0x0, 0x4, 0x43, 0x6, 0x3, 0x0, - 0x0, 0x0, 0x50, 0x22, 0x85, 0x29, 0x59, 0x30, - 0x6, 0x66, 0x50, 0x44, 0x95, 0x4a, 0x54, 0x20, - 0x3, 0x0, 0x30, 0x7, 0xa7, 0x6b, 0x7a, 0x20, - 0xb, 0x66, 0xc3, 0x0, 0x72, 0x8, 0x22, 0x70, - 0xb, 0x0, 0xb0, 0x76, 0x9d, 0xa6, 0x6a, 0x50, - 0xb, 0x0, 0xb0, 0x3, 0xe1, 0x56, 0x85, 0x0, - 0xb, 0x66, 0xc1, 0x78, 0xa0, 0x3a, 0xa1, 0x0, - 0x6, 0x0, 0x5, 0x10, 0xba, 0x20, 0x7f, 0x90, - 0x0, 0x0, 0x0, 0x0, 0x20, 0x0, 0x1, 0x0, - - /* U+8BA1 "计" */ - 0x0, 0x42, 0x0, 0x0, 0x7, 0x30, 0x0, 0x0, - 0x0, 0xc5, 0x0, 0x0, 0xb4, 0x0, 0x0, 0x0, - 0x3, 0xa0, 0x0, 0xb, 0x30, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x0, 0xb3, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, 0xb, 0x30, 0x0, 0x1, 0x66, 0xc4, - 0x36, 0x66, 0xd8, 0x66, 0xc7, 0x0, 0xd, 0x0, - 0x10, 0xb, 0x30, 0x0, 0x0, 0x0, 0xd0, 0x0, - 0x0, 0xb3, 0x0, 0x0, 0x0, 0xd, 0x0, 0x0, - 0xb, 0x30, 0x0, 0x0, 0x0, 0xd0, 0x0, 0x0, - 0xb3, 0x0, 0x0, 0x0, 0xd, 0x5, 0x20, 0xb, - 0x30, 0x0, 0x0, 0x0, 0xd7, 0x60, 0x0, 0xb3, - 0x0, 0x0, 0x0, 0xe, 0xb0, 0x0, 0xb, 0x30, - 0x0, 0x0, 0x0, 0x61, 0x0, 0x0, 0xc4, 0x0, - 0x0, 0x0, 0x0, 0x0, 0x0, 0x3, 0x0, 0x0, - 0x0, - - /* U+8BDE "诞" */ - 0x2, 0x0, 0x0, 0x0, 0x0, 0x0, 0x15, 0x0, - 0x3b, 0x4, 0x69, 0x70, 0x3, 0x9d, 0x90, 0x0, - 0xb2, 0x0, 0xb2, 0x36, 0x4d, 0x0, 0x0, 0x0, - 0x0, 0x1b, 0x0, 0x0, 0xd0, 0x0, 0x0, 0x0, - 0x7, 0x50, 0x7, 0xd, 0x0, 0x3, 0x7b, 0x61, - 0xd0, 0x40, 0xd0, 0xd6, 0xc3, 0x0, 0xa2, 0x29, - 0x7d, 0xc, 0xd, 0x0, 0x0, 0xa, 0x21, 0x3, - 0x90, 0xc0, 0xd0, 0x0, 0x0, 0xa2, 0x5, 0x66, - 0xc, 0xd, 0x0, 0x0, 0xa, 0x20, 0x8b, 0x20, - 0xc0, 0xd0, 0x71, 0x0, 0xa2, 0x64, 0xd0, 0x4b, - 0x66, 0x66, 0x30, 0xb, 0xb1, 0x9b, 0x70, 0x0, - 0x0, 0x0, 0x0, 0xa4, 0x66, 0x6, 0xc9, 0x64, - 0x22, 0x10, 0x0, 0x64, 0x0, 0x0, 0x59, 0xce, - 0xe3, 0x0, 0x20, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, - - /* U+8C50 "豐" */ - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x5, 0x10, 0xb0, 0xc2, 0xa, 0x3, 0x0, 0x0, - 0xb1, 0x2d, 0x7c, 0x26, 0xd6, 0xc1, 0x0, 0xb, - 0x12, 0xb1, 0xc0, 0xb, 0x1c, 0x0, 0x0, 0xb2, - 0x7d, 0x5c, 0x37, 0xd6, 0xc0, 0x0, 0xb, 0x26, - 0xd7, 0xc2, 0x6d, 0x7c, 0x0, 0x0, 0xd0, 0x1b, - 0xc, 0x1, 0xb0, 0xc0, 0x0, 0x8, 0x66, 0x66, - 0x66, 0x66, 0x67, 0x0, 0x2, 0x76, 0x66, 0x66, - 0x66, 0x66, 0xa9, 0x0, 0x0, 0x21, 0x0, 0x0, - 0x0, 0x30, 0x0, 0x0, 0x5, 0xb6, 0x66, 0x66, - 0x6d, 0x10, 0x0, 0x0, 0x59, 0x0, 0x0, 0x0, - 0xb0, 0x0, 0x0, 0x6, 0xa8, 0x66, 0x67, 0x9a, - 0x0, 0x0, 0x0, 0x0, 0x95, 0x0, 0x79, 0x0, - 0x10, 0x5, 0x66, 0x68, 0xa6, 0x6b, 0x66, 0x6e, - 0x70, 0x10, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - - /* U+8C61 "象" */ - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0xa, 0x80, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x8, 0xe6, 0x66, 0xab, 0x0, 0x0, 0x0, 0x7, - 0xa0, 0x0, 0x29, 0x10, 0x0, 0x0, 0x8, 0xe6, - 0x66, 0x6b, 0x66, 0x6d, 0x10, 0x5, 0x1d, 0x0, - 0xa, 0x50, 0x0, 0xe0, 0x0, 0x0, 0xd6, 0x66, - 0xf6, 0x66, 0x6e, 0x0, 0x0, 0x9, 0x0, 0xaa, - 0x0, 0x0, 0x80, 0x0, 0x0, 0x1, 0xa5, 0x85, - 0x3, 0xc9, 0x10, 0x0, 0x5, 0x71, 0x6a, 0xb7, - 0x80, 0x0, 0x0, 0x4, 0x1, 0x97, 0x1c, 0x76, - 0x20, 0x0, 0x0, 0x16, 0x81, 0x1b, 0x6b, 0xc, - 0x20, 0x0, 0x14, 0x0, 0x6a, 0x13, 0xb0, 0x3e, - 0x71, 0x0, 0x5, 0x95, 0x10, 0x79, 0x0, 0x3d, - 0xa1, 0x46, 0x20, 0x6, 0xfe, 0x20, 0x0, 0x0, - 0x0, 0x0, 0x0, 0x3, 0x10, 0x0, 0x0, 0x0, - - /* U+8CA0 "負" */ - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0xa, 0xa0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x5f, 0x76, 0x6a, 0x80, 0x0, 0x0, 0x3, 0xd2, - 0x0, 0x1d, 0x50, 0x0, 0x0, 0x3b, 0x10, 0x0, - 0x82, 0x0, 0x0, 0x5, 0x76, 0x33, 0x35, 0x63, - 0x39, 0x0, 0x1, 0xd, 0x33, 0x33, 0x33, 0x3e, - 0x10, 0x0, 0xd, 0x66, 0x66, 0x66, 0x6e, 0x0, - 0x0, 0xd, 0x10, 0x0, 0x0, 0xe, 0x0, 0x0, - 0xd, 0x66, 0x66, 0x66, 0x6e, 0x0, 0x0, 0xd, - 0x10, 0x0, 0x0, 0xe, 0x0, 0x0, 0xd, 0x66, - 0x66, 0x66, 0x6e, 0x0, 0x0, 0x7, 0x28, 0x0, - 0x5, 0x18, 0x0, 0x0, 0x3, 0xd7, 0x0, 0x1, - 0xab, 0x20, 0x0, 0x78, 0x10, 0x0, 0x0, 0x7, - 0xe0, 0x3, 0x10, 0x0, 0x0, 0x0, 0x0, 0x30, - - /* U+8CA1 "財" */ - 0x2, 0x0, 0x3, 0x0, 0x0, 0x1, 0xa0, 0x0, - 0xb, 0x76, 0x6d, 0x40, 0x0, 0x1, 0xc0, 0x0, - 0xa, 0x20, 0xc, 0x10, 0x0, 0x1, 0xc0, 0x0, - 0xa, 0x20, 0xc, 0x10, 0x0, 0x1, 0xc1, 0x70, - 0xa, 0x76, 0x6d, 0x16, 0x66, 0x6e, 0xd6, 0x61, - 0xa, 0x20, 0xc, 0x10, 0x0, 0x4c, 0xc0, 0x0, - 0xa, 0x76, 0x6d, 0x10, 0x0, 0xc3, 0xc0, 0x0, - 0xa, 0x20, 0xc, 0x10, 0x7, 0x81, 0xc0, 0x0, - 0xa, 0x20, 0xc, 0x10, 0x3b, 0x1, 0xc0, 0x0, - 0xa, 0x76, 0x6d, 0x11, 0xa0, 0x1, 0xc0, 0x0, - 0x8, 0x20, 0x6, 0x18, 0x0, 0x1, 0xc0, 0x0, - 0x0, 0xb6, 0x37, 0x40, 0x0, 0x1, 0xc0, 0x0, - 0x5, 0x90, 0x9, 0x60, 0x0, 0x1, 0xc0, 0x0, - 0x28, 0x0, 0x2, 0x80, 0x2, 0x8e, 0xa0, 0x0, - 0x20, 0x0, 0x0, 0x0, 0x0, 0x5, 0x10, 0x0, - - /* U+8CA7 "貧" */ - 0x0, 0x0, 0x37, 0x0, 0x25, 0x0, 0x0, 0x0, - 0x0, 0x2c, 0x40, 0x0, 0x73, 0x0, 0x0, 0x0, - 0x49, 0x10, 0x0, 0x0, 0xb9, 0x30, 0x1, 0x54, - 0x37, 0xc9, 0x66, 0x6e, 0x7c, 0xc2, 0x0, 0x0, - 0x79, 0x0, 0x1, 0xd0, 0x0, 0x0, 0x3, 0x94, - 0x0, 0x16, 0xb6, 0x0, 0x0, 0x4, 0x48, 0x66, - 0x66, 0x69, 0x6a, 0x0, 0x0, 0x1, 0xb0, 0x0, - 0x0, 0x0, 0xd0, 0x0, 0x0, 0x1d, 0x66, 0x66, - 0x66, 0x6d, 0x0, 0x0, 0x1, 0xd6, 0x66, 0x66, - 0x66, 0xd0, 0x0, 0x0, 0x1b, 0x0, 0x0, 0x0, - 0xd, 0x0, 0x0, 0x1, 0xc6, 0x76, 0x66, 0x66, - 0xa0, 0x0, 0x0, 0x1, 0x7d, 0x20, 0x5, 0x89, - 0x30, 0x0, 0x6, 0xa5, 0x0, 0x0, 0x0, 0x3d, - 0x50, 0x4, 0x10, 0x0, 0x0, 0x0, 0x0, 0x12, - 0x0, - - /* U+8CA9 "販" */ - 0x1, 0x10, 0x0, 0x30, 0x0, 0x0, 0x39, 0x50, - 0x3, 0xc6, 0x66, 0xe0, 0x86, 0x79, 0x86, 0x40, - 0x2, 0xa0, 0x0, 0xd0, 0xd0, 0x0, 0x0, 0x0, - 0x2, 0xb4, 0x44, 0xd0, 0xd0, 0x0, 0x0, 0x0, - 0x2, 0xb1, 0x11, 0xd0, 0xd6, 0x66, 0x6a, 0x10, - 0x2, 0xa0, 0x0, 0xd0, 0xc3, 0x20, 0x1d, 0x0, - 0x2, 0xc6, 0x66, 0xd0, 0xc0, 0x60, 0x49, 0x0, - 0x2, 0xa0, 0x0, 0xd0, 0xc0, 0x80, 0x84, 0x0, - 0x2, 0xa0, 0x0, 0xd0, 0xb0, 0x81, 0xd0, 0x0, - 0x2, 0xc6, 0x66, 0xd1, 0x90, 0x3b, 0x80, 0x0, - 0x2, 0x71, 0x20, 0x75, 0x50, 0xf, 0x20, 0x0, - 0x0, 0x6b, 0x2b, 0x8, 0x0, 0x96, 0xc0, 0x0, - 0x0, 0xb1, 0x9, 0x47, 0x8, 0x30, 0x6d, 0x20, - 0x7, 0x20, 0x0, 0x51, 0x61, 0x0, 0x7, 0xa1, - 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - - /* U+8CAC "責" */ - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x0, 0xd1, 0x0, 0x1, 0x0, 0x2, - 0x66, 0x66, 0x6e, 0x66, 0x67, 0xe2, 0x0, 0x0, - 0x0, 0x0, 0xe0, 0x0, 0x50, 0x0, 0x0, 0x27, - 0x66, 0x6e, 0x66, 0x68, 0x30, 0x0, 0x22, 0x22, - 0x22, 0xe2, 0x22, 0x25, 0xb0, 0x15, 0x55, 0x44, - 0x44, 0x44, 0x48, 0x44, 0x10, 0x3, 0xc6, 0x66, - 0x66, 0x66, 0xd3, 0x0, 0x0, 0x3c, 0x66, 0x66, - 0x66, 0x6d, 0x10, 0x0, 0x3, 0xa0, 0x0, 0x0, - 0x0, 0xc1, 0x0, 0x0, 0x3c, 0x66, 0x66, 0x66, - 0x6d, 0x10, 0x0, 0x3, 0xa0, 0x0, 0x0, 0x0, - 0xc1, 0x0, 0x0, 0x39, 0x6b, 0x66, 0x76, 0x69, - 0x10, 0x0, 0x0, 0x1b, 0xc2, 0x2, 0x8a, 0x71, - 0x0, 0x0, 0x7a, 0x30, 0x0, 0x0, 0x9, 0xe0, - 0x0, 0x51, 0x0, 0x0, 0x0, 0x0, 0x5, 0x0, - - /* U+8CB7 "買" */ - 0x3, 0x0, 0x0, 0x0, 0x0, 0x5, 0x0, 0xb7, - 0x67, 0xc6, 0x6e, 0x66, 0xe3, 0xb, 0x20, 0x3a, - 0x0, 0xd0, 0xd, 0x0, 0xb2, 0x3, 0xa0, 0xd, - 0x0, 0xd0, 0x9, 0x66, 0x66, 0x66, 0x66, 0x6a, - 0x0, 0x6, 0x66, 0x66, 0x66, 0x6c, 0x20, 0x0, - 0x96, 0x0, 0x0, 0x0, 0xe0, 0x0, 0x9, 0x96, - 0x66, 0x66, 0x6e, 0x0, 0x0, 0x96, 0x0, 0x0, - 0x0, 0xe0, 0x0, 0x9, 0x96, 0x66, 0x66, 0x6e, - 0x0, 0x0, 0x96, 0x0, 0x0, 0x0, 0xe0, 0x0, - 0x8, 0x88, 0x76, 0x66, 0x6a, 0x0, 0x0, 0x4, - 0xe8, 0x0, 0x38, 0x93, 0x0, 0x29, 0x81, 0x0, - 0x0, 0x2, 0xc6, 0x34, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x20, - - /* U+8CB8 "貸" */ - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, 0xa9, 0xb, 0x48, 0x50, 0x0, 0x0, - 0x0, 0xa8, 0x0, 0x85, 0x1c, 0x2, 0x0, 0x0, - 0xae, 0x15, 0x58, 0xc6, 0x66, 0xc2, 0x4, 0x71, - 0xd0, 0x0, 0x9, 0x40, 0x0, 0x10, 0x10, 0xd, - 0x0, 0x0, 0x1c, 0x40, 0x4, 0x0, 0x0, 0xb0, - 0x0, 0x0, 0x1c, 0xb8, 0x50, 0x0, 0x39, 0x66, - 0x66, 0x66, 0x6f, 0x96, 0x0, 0x3, 0xa0, 0x0, - 0x0, 0x1, 0xd0, 0x0, 0x0, 0x3c, 0x66, 0x66, - 0x66, 0x6d, 0x0, 0x0, 0x3, 0xc6, 0x66, 0x66, - 0x66, 0xd0, 0x0, 0x0, 0x3a, 0x0, 0x0, 0x0, - 0x1d, 0x0, 0x0, 0x3, 0xb6, 0x86, 0x66, 0x66, - 0xa0, 0x0, 0x0, 0x1, 0xbb, 0x0, 0x5, 0x98, - 0x20, 0x0, 0x7, 0xa4, 0x0, 0x0, 0x0, 0x5f, - 0x0, 0x4, 0x10, 0x0, 0x0, 0x0, 0x0, 0x30, - - /* U+8CBB "費" */ - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, 0xb2, 0xb, 0x10, 0x0, 0x0, 0x1, - 0x76, 0x6d, 0x66, 0xd6, 0x6c, 0x30, 0x0, 0x3, - 0x0, 0xc0, 0xc, 0x0, 0xc0, 0x0, 0x0, 0xe8, - 0x6d, 0x66, 0xd6, 0x69, 0x0, 0x0, 0x2e, 0x66, - 0xc6, 0x6d, 0x66, 0x66, 0xd0, 0x0, 0x1, 0xa2, - 0x0, 0xc0, 0x2, 0x68, 0x0, 0x15, 0x71, 0x0, - 0x8, 0x0, 0x7a, 0x10, 0x2, 0x1d, 0x66, 0x66, - 0x66, 0x7d, 0x0, 0x0, 0x1, 0xd6, 0x66, 0x66, - 0x67, 0xb0, 0x0, 0x0, 0x1b, 0x0, 0x0, 0x0, - 0x2b, 0x0, 0x0, 0x1, 0xd6, 0x66, 0x66, 0x67, - 0xb0, 0x0, 0x0, 0x1d, 0x66, 0x66, 0x66, 0x7b, - 0x0, 0x0, 0x0, 0x4c, 0x50, 0x4, 0x78, 0x40, - 0x0, 0x1, 0x8a, 0x30, 0x0, 0x0, 0x2b, 0xa0, - 0x1, 0x51, 0x0, 0x0, 0x0, 0x0, 0x5, 0x0, - - /* U+8CBF "貿" */ - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x6d, 0x40, 0x0, 0x0, 0x10, 0x2, 0xa6, - 0x40, 0x17, 0x88, 0x66, 0xc7, 0x2, 0xa0, 0x28, - 0x0, 0x85, 0x0, 0xb2, 0x2, 0xa0, 0x1a, 0x80, - 0xc1, 0x0, 0xd0, 0x4, 0xc9, 0x61, 0x48, 0x61, - 0x68, 0xb0, 0x1, 0x80, 0x0, 0x65, 0x0, 0x8, - 0x20, 0x0, 0x9, 0x67, 0x66, 0x66, 0x6c, 0x10, - 0x0, 0xd, 0x0, 0x0, 0x0, 0xe, 0x0, 0x0, - 0xe, 0x66, 0x66, 0x66, 0x6e, 0x0, 0x0, 0xe, - 0x66, 0x66, 0x66, 0x6e, 0x0, 0x0, 0xd, 0x0, - 0x0, 0x0, 0xe, 0x0, 0x0, 0xd, 0x68, 0x66, - 0x66, 0x6c, 0x0, 0x0, 0x1, 0xac, 0x10, 0x6, - 0xa7, 0x10, 0x0, 0x5a, 0x40, 0x0, 0x0, 0x7, - 0xe0, 0x4, 0x10, 0x0, 0x0, 0x0, 0x0, 0x20, - - /* U+8CC3 "賃" */ - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x69, 0x0, 0x0, 0x25, 0x95, 0x0, 0x0, - 0x2d, 0x24, 0x57, 0xd7, 0x55, 0x40, 0x0, 0x1c, - 0xa0, 0x0, 0xc, 0x10, 0x2, 0x40, 0x19, 0x3b, - 0x56, 0x66, 0xd6, 0x66, 0x77, 0x1, 0x1, 0xb0, - 0x0, 0xc, 0x10, 0x3, 0x0, 0x0, 0x18, 0x6, - 0x66, 0x96, 0x67, 0x90, 0x0, 0x1, 0x96, 0x66, - 0x66, 0x66, 0xc1, 0x0, 0x0, 0x1b, 0x0, 0x0, - 0x0, 0xd, 0x0, 0x0, 0x1, 0xd6, 0x66, 0x66, - 0x66, 0xd0, 0x0, 0x0, 0x1d, 0x66, 0x66, 0x66, - 0x6d, 0x0, 0x0, 0x1, 0xb0, 0x0, 0x0, 0x0, - 0xd0, 0x0, 0x0, 0x1c, 0x67, 0x66, 0x66, 0x6b, - 0x0, 0x0, 0x0, 0x1b, 0xa0, 0x2, 0x69, 0x50, - 0x0, 0x0, 0x6a, 0x30, 0x0, 0x0, 0x19, 0xb0, - 0x0, 0x41, 0x0, 0x0, 0x0, 0x0, 0x3, 0x0, - - /* U+8CC7 "資" */ - 0x0, 0x0, 0x0, 0x11, 0x0, 0x0, 0x0, 0x0, - 0x54, 0x0, 0x8, 0x90, 0x0, 0x0, 0x0, 0x0, - 0xd1, 0x51, 0xd7, 0x66, 0x66, 0xa0, 0x0, 0x1, - 0x62, 0x57, 0x7, 0x40, 0x64, 0x0, 0x24, 0x84, - 0x19, 0x0, 0xe7, 0x2, 0x0, 0x0, 0x6a, 0x3, - 0x0, 0x88, 0x66, 0x0, 0x0, 0x5, 0x80, 0x0, - 0x79, 0x0, 0xaa, 0x41, 0x0, 0x68, 0x13, 0x73, - 0x0, 0x0, 0x9c, 0x50, 0x0, 0x2d, 0x66, 0x66, - 0x66, 0x7e, 0x0, 0x0, 0x2, 0xd6, 0x66, 0x66, - 0x67, 0xc0, 0x0, 0x0, 0x2b, 0x0, 0x0, 0x0, - 0x2c, 0x0, 0x0, 0x2, 0xd6, 0x66, 0x66, 0x67, - 0xc0, 0x0, 0x0, 0x2d, 0x76, 0x66, 0x66, 0x7c, - 0x0, 0x0, 0x0, 0x3c, 0x90, 0x0, 0x59, 0x71, - 0x0, 0x0, 0x7a, 0x40, 0x0, 0x0, 0x6, 0xe0, - 0x0, 0x41, 0x0, 0x0, 0x0, 0x0, 0x3, 0x0, - - /* U+8CEA "質" */ - 0x0, 0x0, 0x3, 0x80, 0x0, 0x17, 0x70, 0x0, - 0x96, 0x76, 0x51, 0xb6, 0x86, 0x40, 0x0, 0xa3, - 0x0, 0x51, 0xd0, 0x0, 0x61, 0x0, 0xb7, 0x6e, - 0x63, 0xe6, 0x9a, 0x63, 0x1, 0xc0, 0xc, 0x4, - 0x90, 0x57, 0x0, 0x9, 0x20, 0xd, 0x1a, 0x0, - 0x57, 0x0, 0x41, 0x28, 0x67, 0xa6, 0x66, 0xa3, - 0x0, 0x0, 0x2c, 0x0, 0x0, 0x0, 0xb3, 0x0, - 0x0, 0x2d, 0x66, 0x66, 0x66, 0xd2, 0x0, 0x0, - 0x2c, 0x0, 0x0, 0x0, 0xb2, 0x0, 0x0, 0x2d, - 0x66, 0x66, 0x66, 0xd2, 0x0, 0x0, 0x2d, 0x66, - 0x66, 0x66, 0xc2, 0x0, 0x0, 0x1, 0x8b, 0x0, - 0x27, 0x83, 0x0, 0x0, 0x4a, 0x60, 0x0, 0x0, - 0x3d, 0x60, 0x4, 0x30, 0x0, 0x0, 0x0, 0x1, - 0x40, - - /* U+8CFD "賽" */ - 0x0, 0x0, 0x0, 0x10, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x0, 0xb, 0x20, 0x0, 0x0, 0x0, - 0x0, 0x66, 0x66, 0x6a, 0x86, 0x66, 0x6a, 0x10, - 0x4, 0xc0, 0x6, 0x30, 0x9, 0x10, 0x57, 0x0, - 0x0, 0x37, 0x6b, 0x86, 0x6d, 0x67, 0x90, 0x0, - 0x0, 0x4, 0x4a, 0x74, 0x4d, 0x46, 0x60, 0x0, - 0x0, 0x3, 0x19, 0x41, 0x1c, 0x11, 0x26, 0x0, - 0x3, 0x76, 0x7e, 0x66, 0x69, 0x76, 0x66, 0x10, - 0x0, 0x3, 0xf3, 0x11, 0x11, 0xc6, 0x0, 0x0, - 0x2, 0x76, 0xc4, 0x44, 0x44, 0xba, 0xd9, 0x71, - 0x13, 0x0, 0xc6, 0x66, 0x66, 0xc3, 0x6, 0x30, - 0x0, 0x0, 0xc6, 0x66, 0x66, 0xc3, 0x0, 0x0, - 0x0, 0x0, 0xd6, 0x66, 0x66, 0xc3, 0x0, 0x0, - 0x0, 0x0, 0x57, 0x80, 0x4, 0x70, 0x0, 0x0, - 0x0, 0x3, 0x96, 0x0, 0x0, 0x3d, 0x70, 0x0, - 0x0, 0x33, 0x0, 0x0, 0x0, 0x0, 0x60, 0x0, - - /* U+8D39 "费" */ - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0xc, 0x10, 0xc1, 0x0, 0x0, 0x3, 0x66, - 0x6e, 0x66, 0xe6, 0x6a, 0x30, 0x0, 0x10, 0xd, - 0x0, 0xd0, 0xb, 0x20, 0x2, 0xb6, 0x6e, 0x66, - 0xe6, 0x6d, 0x10, 0x6, 0x80, 0xd, 0x0, 0xd0, - 0x4, 0x22, 0x6, 0x76, 0xaa, 0x66, 0xe6, 0x66, - 0xc7, 0x0, 0x7, 0x70, 0x0, 0xd0, 0x18, 0xc0, - 0x15, 0x69, 0x66, 0x66, 0x86, 0x95, 0x10, 0x0, - 0xd, 0x0, 0x63, 0x0, 0xd1, 0x0, 0x0, 0xd, - 0x0, 0xc5, 0x0, 0xd0, 0x0, 0x0, 0xd, 0x0, - 0xf1, 0x0, 0xd0, 0x0, 0x0, 0x7, 0x7, 0xa2, - 0x63, 0x40, 0x0, 0x0, 0x0, 0x6c, 0x10, 0x17, - 0xe8, 0x0, 0x1, 0x58, 0x60, 0x0, 0x0, 0x2e, - 0x40, 0x13, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - - /* U+8D64 "赤" */ - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x1, 0xe1, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, 0xd, 0x0, 0x0, 0x0, 0x0, 0x5, - 0x66, 0x66, 0xe6, 0x66, 0xc7, 0x0, 0x0, 0x11, - 0x0, 0xd, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0xd0, 0x0, 0x0, 0x0, 0x36, 0x66, 0x66, - 0x6e, 0x66, 0x66, 0x6e, 0x40, 0x10, 0x0, 0xe0, - 0x2, 0xb0, 0x0, 0x0, 0x0, 0x5c, 0xe, 0x0, - 0x2b, 0x50, 0x0, 0x0, 0xc, 0x51, 0xc0, 0x2, - 0xb1, 0xa2, 0x0, 0x5, 0x70, 0x59, 0x0, 0x2b, - 0x2, 0xe2, 0x1, 0x70, 0xb, 0x30, 0x2, 0xb0, - 0x9, 0x80, 0x40, 0x4, 0xa0, 0x0, 0x2b, 0x0, - 0x12, 0x0, 0x2, 0x90, 0x0, 0x3, 0xb0, 0x0, - 0x0, 0x5, 0x60, 0x0, 0x29, 0xf9, 0x0, 0x0, - 0x2, 0x10, 0x0, 0x0, 0x4, 0x0, 0x0, 0x0, - - /* U+8D70 "走" */ - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x0, 0xb, 0x50, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x0, 0xb, 0x20, 0x1, 0x0, 0x0, - 0x0, 0x16, 0x66, 0x6d, 0x76, 0x6d, 0x80, 0x0, - 0x0, 0x1, 0x0, 0xb, 0x20, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x0, 0xb, 0x20, 0x0, 0x1, 0x0, - 0x16, 0x66, 0x66, 0x6d, 0x76, 0x66, 0x8f, 0x30, - 0x1, 0x0, 0x0, 0xa, 0x40, 0x0, 0x0, 0x0, - 0x0, 0x5, 0xa0, 0xb, 0x20, 0x0, 0x0, 0x0, - 0x0, 0x7, 0x90, 0xb, 0x20, 0x3, 0x70, 0x0, - 0x0, 0xa, 0x50, 0xb, 0x76, 0x66, 0x61, 0x0, - 0x0, 0xe, 0x60, 0xb, 0x20, 0x0, 0x0, 0x0, - 0x0, 0x58, 0x9, 0x2b, 0x20, 0x0, 0x0, 0x0, - 0x0, 0xb0, 0x1, 0xbf, 0x85, 0x43, 0x33, 0x40, - 0x8, 0x10, 0x0, 0x3, 0x7b, 0xde, 0xfe, 0x20, - 0x10, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - - /* U+8D77 "起" */ - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x1d, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, 0xc, 0x0, 0x0, 0x0, 0x4, 0x0, - 0x0, 0x56, 0x6d, 0x6d, 0x17, 0x66, 0x6e, 0x10, - 0x0, 0x10, 0xc, 0x0, 0x0, 0x0, 0xd, 0x0, - 0x0, 0x0, 0xc, 0x0, 0x0, 0x0, 0xd, 0x0, - 0x3, 0x66, 0x6d, 0x6b, 0x78, 0x66, 0x6e, 0x0, - 0x1, 0x10, 0xd, 0x10, 0xd, 0x0, 0x8, 0x0, - 0x0, 0x44, 0xd, 0x0, 0xd, 0x0, 0x0, 0x0, - 0x0, 0x79, 0xd, 0x7, 0xd, 0x0, 0x0, 0x50, - 0x0, 0x94, 0xd, 0x66, 0x2d, 0x0, 0x0, 0x70, - 0x0, 0xb4, 0xd, 0x0, 0xc, 0x21, 0x12, 0xd1, - 0x0, 0xb7, 0x3d, 0x0, 0x3, 0x9a, 0xa9, 0x60, - 0x2, 0x70, 0xae, 0x10, 0x0, 0x0, 0x0, 0x0, - 0x7, 0x10, 0x6, 0xd9, 0x53, 0x22, 0x23, 0x42, - 0x6, 0x0, 0x0, 0x4, 0x8a, 0xce, 0xee, 0x70, - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - - /* U+8D85 "超" */ - 0x0, 0x0, 0x10, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, 0xe2, 0x0, 0x0, 0x0, 0x1, 0x10, - 0x0, 0x0, 0xd0, 0x0, 0x67, 0xb6, 0x6a, 0x80, - 0x3, 0x66, 0xe6, 0xb5, 0x0, 0xe0, 0x9, 0x50, - 0x0, 0x10, 0xd0, 0x0, 0x3, 0xa0, 0xa, 0x30, - 0x0, 0x0, 0xd0, 0x0, 0x9, 0x30, 0xc, 0x10, - 0x5, 0x66, 0xe6, 0xb8, 0x38, 0x2, 0xcc, 0x0, - 0x2, 0x0, 0xd0, 0x3, 0x70, 0x0, 0x11, 0x0, - 0x0, 0x71, 0xd0, 0x1, 0x3a, 0x66, 0x6d, 0x40, - 0x0, 0xe0, 0xd0, 0x26, 0x2b, 0x0, 0xd, 0x0, - 0x0, 0xc0, 0xd6, 0x65, 0x3b, 0x0, 0xd, 0x0, - 0x2, 0xb0, 0xd0, 0x0, 0x2b, 0x0, 0xd, 0x0, - 0x4, 0x77, 0xd0, 0x0, 0x2d, 0x66, 0x6e, 0x0, - 0x8, 0x13, 0xe1, 0x0, 0x38, 0x0, 0x5, 0x0, - 0x7, 0x0, 0x2a, 0xa5, 0x31, 0x11, 0x1, 0x10, - 0x32, 0x0, 0x0, 0x26, 0x9b, 0xde, 0xef, 0x90, - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - - /* U+8D8A "越" */ - 0x0, 0x0, 0xa0, 0x0, 0x0, 0x83, 0x0, 0x0, - 0x0, 0x0, 0xd0, 0x0, 0x0, 0xa2, 0x86, 0x0, - 0x3, 0x55, 0xd5, 0xc3, 0x0, 0xa2, 0x1b, 0x0, - 0x1, 0x21, 0xd1, 0x10, 0x96, 0xc7, 0x6b, 0x80, - 0x0, 0x0, 0xd0, 0x0, 0xd0, 0x93, 0x0, 0x0, - 0x16, 0x66, 0xd6, 0x98, 0xd0, 0x84, 0xd, 0x10, - 0x0, 0x0, 0xb2, 0x0, 0xd0, 0x66, 0x5a, 0x0, - 0x0, 0xb3, 0xc1, 0x0, 0xd0, 0x3a, 0xb1, 0x0, - 0x0, 0xd1, 0xc6, 0xa7, 0xd2, 0x2e, 0x80, 0x30, - 0x0, 0xe0, 0xc1, 0x0, 0xe7, 0x1d, 0x80, 0x70, - 0x2, 0xd1, 0xc1, 0x0, 0x60, 0xa2, 0xb8, 0x80, - 0x5, 0x68, 0xd1, 0x0, 0x18, 0x10, 0xb, 0x90, - 0x8, 0x0, 0x7b, 0x73, 0x40, 0x0, 0x0, 0x30, - 0x16, 0x0, 0x1, 0x6b, 0xde, 0xee, 0xff, 0x80, - 0x10, 0x0, 0x0, 0x0, 0x0, 0x1, 0x11, 0x0, - - /* U+8DA3 "趣" */ - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0xa3, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0xa, 0x12, 0x66, 0x66, 0xb5, 0x0, 0x0, 0x0, - 0xa2, 0x71, 0xc0, 0xc0, 0x0, 0x20, 0x5, 0x6c, - 0x65, 0xc, 0xc, 0x27, 0x6b, 0x60, 0x0, 0xa1, - 0x0, 0xd5, 0xd0, 0x0, 0xc0, 0x26, 0x6c, 0x69, - 0x7c, 0xc, 0x5, 0xc, 0x0, 0x10, 0x66, 0x0, - 0xc0, 0xc0, 0x39, 0x80, 0x4, 0x46, 0x50, 0xd, - 0x6d, 0x0, 0xb4, 0x0, 0x77, 0x69, 0xa3, 0xc0, - 0xc0, 0x1a, 0xb0, 0x8, 0x46, 0x50, 0xc, 0x6d, - 0x58, 0x2a, 0x40, 0xa4, 0x65, 0x1d, 0x82, 0xc2, - 0x40, 0x44, 0xa, 0x4b, 0x50, 0x0, 0xc, 0x10, - 0x0, 0x1, 0x60, 0x3a, 0x73, 0x10, 0x40, 0x0, - 0x12, 0x40, 0x0, 0x3, 0x8c, 0xdf, 0xff, 0xff, - 0x50, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - - /* U+8DB3 "足" */ - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x96, 0x66, 0x66, 0x6c, 0x30, 0x0, - 0x0, 0x0, 0xd0, 0x0, 0x0, 0xd, 0x0, 0x0, - 0x0, 0x0, 0xd0, 0x0, 0x0, 0xd, 0x0, 0x0, - 0x0, 0x0, 0xd0, 0x0, 0x0, 0xd, 0x0, 0x0, - 0x0, 0x0, 0xd0, 0x0, 0x0, 0xd, 0x0, 0x0, - 0x0, 0x0, 0xe6, 0x67, 0xb6, 0x6e, 0x0, 0x0, - 0x0, 0x0, 0x10, 0x2, 0xb0, 0x2, 0x0, 0x0, - 0x0, 0x2, 0x30, 0x2, 0xb0, 0x0, 0x20, 0x0, - 0x0, 0x6, 0xd0, 0x2, 0xd6, 0x67, 0xd3, 0x0, - 0x0, 0xa, 0x60, 0x2, 0xb0, 0x0, 0x0, 0x0, - 0x0, 0xe, 0x81, 0x2, 0xb0, 0x0, 0x0, 0x0, - 0x0, 0x76, 0x1b, 0x42, 0xb0, 0x0, 0x0, 0x0, - 0x0, 0xa0, 0x0, 0xad, 0xd5, 0x42, 0x23, 0x40, - 0x7, 0x10, 0x0, 0x2, 0x8b, 0xde, 0xfe, 0x30, - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - - /* U+8DDF "跟" */ - 0x0, 0x0, 0x0, 0x10, 0x0, 0x0, 0x1, 0x0, - 0x0, 0xc6, 0x66, 0xe0, 0xc6, 0x66, 0x6f, 0x10, - 0x0, 0xc0, 0x1, 0xa0, 0xd0, 0x0, 0xd, 0x0, - 0x0, 0xc0, 0x1, 0xa0, 0xd0, 0x0, 0xd, 0x0, - 0x0, 0xc0, 0x1, 0xa0, 0xd6, 0x66, 0x6d, 0x0, - 0x0, 0xc6, 0xc7, 0x80, 0xd0, 0x0, 0xd, 0x0, - 0x0, 0x0, 0xc0, 0x0, 0xd6, 0x66, 0x6d, 0x0, - 0x0, 0xd0, 0xc0, 0x40, 0xd0, 0x60, 0x6, 0x10, - 0x0, 0xc0, 0xc6, 0x82, 0xd0, 0x80, 0xb, 0x80, - 0x0, 0xc0, 0xc0, 0x0, 0xd0, 0x56, 0x94, 0x0, - 0x0, 0xc0, 0xc0, 0x0, 0xd0, 0xc, 0x10, 0x0, - 0x0, 0xc0, 0xc6, 0x51, 0xd0, 0x24, 0xc1, 0x0, - 0x5, 0xeb, 0x70, 0x0, 0xd9, 0x40, 0x5e, 0x82, - 0xa, 0x40, 0x0, 0x0, 0xb4, 0x0, 0x2, 0x70, - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - - /* U+8DEF "路" */ - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x0, 0x0, 0xd, 0x30, 0x0, 0x0, - 0x0, 0xb6, 0x68, 0x90, 0x3c, 0x0, 0x4, 0x0, - 0x0, 0xd0, 0x4, 0x70, 0x88, 0x66, 0x7e, 0x20, - 0x0, 0xd0, 0x4, 0x70, 0xa5, 0x0, 0x95, 0x0, - 0x0, 0xd0, 0x4, 0x75, 0x26, 0x34, 0xb0, 0x0, - 0x0, 0xe6, 0xc8, 0x66, 0x0, 0xbd, 0x10, 0x0, - 0x0, 0x10, 0xc0, 0x0, 0x2, 0xdc, 0x80, 0x0, - 0x1, 0x90, 0xd6, 0x70, 0x3a, 0x10, 0x8e, 0x82, - 0x0, 0xb0, 0xc1, 0x15, 0xc6, 0x66, 0x6c, 0x91, - 0x0, 0xb0, 0xc0, 0x41, 0xa3, 0x0, 0x1c, 0x0, - 0x0, 0xb0, 0xc0, 0x0, 0xa3, 0x0, 0x1c, 0x0, - 0x0, 0xb3, 0xd6, 0x40, 0xa3, 0x0, 0x1c, 0x0, - 0xa, 0xc6, 0x10, 0x0, 0xa7, 0x66, 0x6c, 0x0, - 0x1, 0x0, 0x0, 0x0, 0xa2, 0x0, 0x1b, 0x0, - 0x0, 0x0, 0x0, 0x0, 0x20, 0x0, 0x0, 0x0, - - /* U+8EAB "身" */ - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x0, 0xd2, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x20, 0x64, 0x0, 0x4, 0x0, 0x0, 0x0, - 0xd, 0x66, 0x66, 0x66, 0xe2, 0x0, 0x0, 0x0, - 0xd1, 0x0, 0x0, 0xe, 0x0, 0x0, 0x0, 0xc, - 0x66, 0x66, 0x66, 0xe0, 0x40, 0x0, 0x0, 0xc1, - 0x0, 0x0, 0xe, 0x1e, 0x50, 0x0, 0xc, 0x66, - 0x66, 0x66, 0xeb, 0x50, 0x0, 0x0, 0xc1, 0x0, - 0x0, 0x1e, 0x60, 0x0, 0x36, 0x6d, 0x66, 0x66, - 0x6c, 0xf0, 0x0, 0x0, 0x10, 0x0, 0x0, 0x1b, - 0x4e, 0x0, 0x0, 0x0, 0x0, 0x0, 0x4b, 0x20, - 0xe0, 0x0, 0x0, 0x0, 0x1, 0x97, 0x0, 0xe, - 0x0, 0x0, 0x0, 0x7, 0x82, 0x0, 0x0, 0xe0, - 0x0, 0x3, 0x56, 0x10, 0x0, 0x17, 0xed, 0x0, - 0x0, 0x10, 0x0, 0x0, 0x0, 0x4, 0x10, 0x0, - - /* U+8ECA "車" */ - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x0, 0xc4, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, 0xc, 0x0, 0x0, 0x32, 0x0, 0x27, - 0x66, 0x66, 0xd6, 0x66, 0x68, 0x70, 0x0, 0x1, - 0x0, 0xc, 0x0, 0x3, 0x20, 0x0, 0x0, 0xd6, - 0x66, 0xd6, 0x66, 0xb8, 0x0, 0x0, 0xd, 0x0, - 0xc, 0x0, 0x9, 0x40, 0x0, 0x0, 0xd6, 0x66, - 0xd6, 0x66, 0xb4, 0x0, 0x0, 0xd, 0x0, 0xc, - 0x0, 0x9, 0x40, 0x0, 0x0, 0xd6, 0x66, 0xd6, - 0x66, 0xb4, 0x0, 0x0, 0xa, 0x0, 0xc, 0x0, - 0x5, 0x20, 0x0, 0x0, 0x0, 0x0, 0xc0, 0x0, - 0x0, 0xa2, 0x17, 0x66, 0x66, 0x6d, 0x66, 0x66, - 0x67, 0x50, 0x0, 0x0, 0x0, 0xc0, 0x0, 0x0, - 0x0, 0x0, 0x0, 0x0, 0xc, 0x10, 0x0, 0x0, - 0x0, 0x0, 0x0, 0x0, 0x60, 0x0, 0x0, 0x0, - - /* U+8EDF "軟" */ - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, 0xc3, 0x0, 0x4, 0xb0, 0x0, 0x0, - 0x0, 0x0, 0xc0, 0x22, 0x7, 0x70, 0x0, 0x0, - 0x4, 0x76, 0xd6, 0x77, 0xb, 0x10, 0x0, 0x0, - 0x0, 0x0, 0xc0, 0x20, 0x1d, 0x66, 0x69, 0xc0, - 0x2, 0xc6, 0xd6, 0xd4, 0x73, 0x83, 0x9, 0x30, - 0x1, 0xb0, 0xc0, 0xc0, 0x70, 0xc3, 0x2, 0x0, - 0x1, 0xd6, 0xd6, 0xd3, 0x0, 0xc4, 0x0, 0x0, - 0x1, 0xb0, 0xc0, 0xc0, 0x0, 0xd6, 0x0, 0x0, - 0x1, 0xd6, 0xd6, 0xd0, 0x1, 0xc7, 0x0, 0x0, - 0x1, 0x70, 0xc0, 0x50, 0x6, 0x88, 0x20, 0x0, - 0x5, 0x66, 0xd6, 0x7c, 0x1c, 0x13, 0x90, 0x0, - 0x1, 0x0, 0xc0, 0x0, 0x67, 0x0, 0xc4, 0x0, - 0x0, 0x0, 0xc0, 0x4, 0x90, 0x0, 0x2e, 0x60, - 0x0, 0x0, 0xd0, 0x46, 0x0, 0x0, 0x4, 0xa2, - 0x0, 0x0, 0x40, 0x10, 0x0, 0x0, 0x0, 0x0, - - /* U+8EE2 "転" */ - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, 0xd3, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, 0xc0, 0x13, 0x0, 0x0, 0x5, 0x0, - 0x4, 0x76, 0xd6, 0x77, 0x28, 0x66, 0x69, 0x20, - 0x0, 0x0, 0xc0, 0x10, 0x0, 0x0, 0x0, 0x0, - 0x2, 0xc6, 0xd6, 0xc5, 0x0, 0x0, 0x0, 0x0, - 0x1, 0xb0, 0xc0, 0xa1, 0x0, 0x0, 0x0, 0x30, - 0x1, 0xd6, 0xd6, 0xc3, 0x86, 0x76, 0x66, 0xa2, - 0x1, 0xb0, 0xc0, 0xa1, 0x0, 0x79, 0x0, 0x0, - 0x1, 0xd6, 0xd6, 0xc2, 0x0, 0xc1, 0x0, 0x0, - 0x1, 0x80, 0xc0, 0x51, 0x4, 0x70, 0x10, 0x0, - 0x5, 0x66, 0xd6, 0x9b, 0x9, 0x0, 0x37, 0x0, - 0x1, 0x0, 0xc0, 0x0, 0x72, 0x0, 0x8, 0x70, - 0x0, 0x0, 0xc0, 0x3, 0xec, 0x98, 0x65, 0xe0, - 0x0, 0x0, 0xd0, 0x0, 0x30, 0x0, 0x0, 0x60, - 0x0, 0x0, 0x50, 0x0, 0x0, 0x0, 0x0, 0x0, - - /* U+8EFD "軽" */ - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0xa, 0x80, 0x0, 0x0, 0x0, 0x15, 0x0, - 0x0, 0xa, 0x20, 0x54, 0x86, 0x66, 0xbb, 0x0, - 0x7, 0x6c, 0x76, 0x82, 0x32, 0x1, 0xc0, 0x0, - 0x1, 0xa, 0x20, 0x20, 0x8, 0xa, 0x30, 0x0, - 0xb, 0x7c, 0x76, 0xf1, 0x4, 0xc6, 0x0, 0x0, - 0xa, 0x2a, 0x20, 0xc0, 0x7, 0xaa, 0x10, 0x0, - 0xa, 0x7c, 0x76, 0xc0, 0x84, 0x3, 0xda, 0x50, - 0xa, 0x2a, 0x20, 0xd5, 0x0, 0xc4, 0x6, 0x10, - 0xa, 0x7c, 0x76, 0xc0, 0x0, 0xd0, 0x1, 0x0, - 0x8, 0x1a, 0x20, 0x52, 0x75, 0xe5, 0x7b, 0x10, - 0x26, 0x6c, 0x76, 0xa7, 0x0, 0xd0, 0x0, 0x0, - 0x1, 0xa, 0x20, 0x0, 0x0, 0xd0, 0x0, 0x0, - 0x0, 0xa, 0x20, 0x0, 0x0, 0xd0, 0x3, 0x20, - 0x0, 0xa, 0x20, 0x27, 0x66, 0x96, 0x69, 0x70, - 0x0, 0x6, 0x10, 0x0, 0x0, 0x0, 0x0, 0x0, - - /* U+8F03 "較" */ - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0xa, 0x80, 0x0, 0x1, 0xa2, 0x0, 0x0, - 0x0, 0xa, 0x20, 0x40, 0x0, 0x4b, 0x0, 0x0, - 0x7, 0x6c, 0x76, 0x92, 0x11, 0x13, 0x17, 0x20, - 0x0, 0xa, 0x20, 0x22, 0x68, 0x65, 0x55, 0x30, - 0xa, 0x7c, 0x76, 0xe2, 0xc, 0x60, 0x64, 0x0, - 0xa, 0x2a, 0x20, 0xc0, 0x58, 0x0, 0x8, 0xa0, - 0xa, 0x7c, 0x76, 0xc1, 0xa2, 0x0, 0x50, 0xc1, - 0xa, 0x2a, 0x20, 0xc7, 0x6, 0x0, 0xe3, 0x0, - 0xa, 0x7c, 0x76, 0xc0, 0x7, 0x14, 0x90, 0x0, - 0x8, 0x1a, 0x20, 0x50, 0x2, 0x9b, 0x20, 0x0, - 0x26, 0x6c, 0x76, 0xb7, 0x0, 0xaa, 0x0, 0x0, - 0x1, 0xa, 0x20, 0x0, 0x4, 0xac, 0x40, 0x0, - 0x0, 0xa, 0x20, 0x0, 0x77, 0x1, 0xd9, 0x30, - 0x0, 0xa, 0x20, 0x37, 0x20, 0x0, 0x9, 0x40, - 0x0, 0x4, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - - /* U+8F09 "載" */ - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, 0xd, 0x10, 0x3, 0xc3, 0x10, 0x0, - 0x0, 0x56, 0x6d, 0x6d, 0x33, 0xa0, 0xc3, 0x0, - 0x0, 0x10, 0xb, 0x0, 0x3, 0xa0, 0x43, 0x30, - 0x17, 0x66, 0x6a, 0x66, 0x67, 0xc6, 0x67, 0xb2, - 0x0, 0x0, 0x1c, 0x3, 0x12, 0xa0, 0x0, 0x0, - 0x2, 0x76, 0x6d, 0x68, 0x61, 0xa0, 0x4, 0x0, - 0x0, 0x86, 0x6d, 0x69, 0x30, 0xc0, 0xe, 0x40, - 0x0, 0xd0, 0xb, 0xc, 0x10, 0xd0, 0x4a, 0x0, - 0x0, 0xd6, 0x6d, 0x6d, 0x0, 0xc0, 0xc3, 0x0, - 0x0, 0xd0, 0xb, 0xc, 0x0, 0x8a, 0xa0, 0x0, - 0x0, 0xc6, 0x6d, 0x69, 0x0, 0x4f, 0x10, 0x0, - 0x5, 0x66, 0x6d, 0x69, 0xa1, 0xcc, 0x50, 0x5, - 0x1, 0x0, 0xb, 0x0, 0x2a, 0x21, 0xd5, 0x44, - 0x0, 0x0, 0x1c, 0x5, 0x70, 0x0, 0x1c, 0xe4, - 0x0, 0x0, 0x4, 0x1, 0x0, 0x0, 0x0, 0x43, - - /* U+8F15 "輕" */ - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0xa, 0x80, 0x0, 0x0, 0x0, 0x1, 0x0, - 0x0, 0xa, 0x20, 0x52, 0x76, 0x66, 0x6a, 0x70, - 0x17, 0x6c, 0x76, 0x82, 0x46, 0x57, 0xb, 0x30, - 0x1, 0xa, 0x20, 0x20, 0x93, 0xa3, 0x4b, 0x0, - 0xb, 0x7c, 0x76, 0xe3, 0x80, 0x60, 0x90, 0x0, - 0xa, 0x2a, 0x20, 0xc3, 0x51, 0x70, 0x92, 0x0, - 0xa, 0x7c, 0x76, 0xc0, 0x95, 0x77, 0x1e, 0x20, - 0xa, 0x2a, 0x20, 0xc0, 0x3b, 0x28, 0x6, 0x30, - 0xa, 0x4a, 0x32, 0xc0, 0x0, 0x0, 0x8, 0x0, - 0xa, 0x5b, 0x54, 0x80, 0x66, 0xd6, 0x66, 0x30, - 0x36, 0x6c, 0x76, 0x79, 0x0, 0xc1, 0x0, 0x0, - 0x1, 0xa, 0x20, 0x0, 0x0, 0xc1, 0x0, 0x0, - 0x0, 0xa, 0x20, 0x0, 0x0, 0xc1, 0x0, 0x10, - 0x0, 0xa, 0x20, 0x16, 0x66, 0xd6, 0x68, 0xe2, - 0x0, 0x9, 0x20, 0x1, 0x0, 0x0, 0x0, 0x0, - - /* U+8F2A "輪" */ - 0x0, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0xc, 0x30, 0x0, 0x1, 0xe2, 0x0, 0x0, - 0x0, 0xc, 0x5, 0x10, 0x6, 0xb2, 0x0, 0x0, - 0x7, 0x6d, 0x66, 0x40, 0xd, 0x29, 0x0, 0x0, - 0x1, 0xc, 0x2, 0x0, 0x87, 0x3, 0xb0, 0x0, - 0xc, 0x6d, 0x6d, 0x44, 0x80, 0x1, 0xae, 0x70, - 0xb, 0x1c, 0xc, 0x45, 0x37, 0x66, 0x54, 0x10, - 0xb, 0x6d, 0x6d, 0x12, 0x0, 0x0, 0x4, 0x0, - 0xb, 0x1c, 0xc, 0xc, 0x6c, 0x6c, 0x6d, 0x30, - 0xb, 0x6d, 0x6d, 0xc, 0xb, 0xb, 0xc, 0x0, - 0x8, 0xc, 0x5, 0xc, 0xb, 0xb, 0xc, 0x0, - 0x26, 0x6d, 0x6b, 0x7c, 0x6c, 0x6c, 0x6d, 0x0, - 0x1, 0xc, 0x0, 0xc, 0xb, 0xb, 0xc, 0x0, - 0x0, 0xc, 0x0, 0xc, 0xb, 0xb, 0xc, 0x0, - 0x0, 0xc, 0x0, 0xc, 0x7, 0x6, 0x7d, 0x0, - 0x0, 0x5, 0x0, 0x2, 0x0, 0x0, 0x2, 0x0, - - /* U+8F38 "輸" */ - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x9, 0x30, 0x0, 0x3, 0xb1, 0x0, 0x0, - 0x0, 0xc, 0x2, 0x0, 0x9, 0xb4, 0x0, 0x0, - 0x17, 0x6d, 0x69, 0x50, 0x2e, 0x27, 0x10, 0x0, - 0x0, 0xc, 0x1, 0x0, 0xc5, 0x2, 0xb1, 0x0, - 0xb, 0x6d, 0x6d, 0x58, 0x77, 0x68, 0x8e, 0x70, - 0xc, 0x1c, 0xc, 0x54, 0x0, 0x10, 0x6, 0x20, - 0xb, 0x6d, 0x6d, 0xb, 0x66, 0xd1, 0xc, 0x0, - 0xb, 0x1c, 0xc, 0xc, 0x1, 0xba, 0x2b, 0x0, - 0xc, 0x6d, 0x6d, 0xc, 0x56, 0xbb, 0xb, 0x0, - 0x9, 0xc, 0x5, 0xc, 0x1, 0xbb, 0xb, 0x0, - 0x26, 0x6d, 0x6b, 0x8c, 0x66, 0xbb, 0xb, 0x0, - 0x1, 0xc, 0x0, 0xc, 0x1, 0xba, 0x1b, 0x0, - 0x0, 0xc, 0x0, 0xc, 0x1, 0xb0, 0xb, 0x0, - 0x0, 0xc, 0x10, 0xc, 0x3b, 0x83, 0xab, 0x0, - 0x0, 0x4, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - - /* U+8F9B "辛" */ - 0x0, 0x0, 0x0, 0x65, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x0, 0xf4, 0x0, 0x1, 0x0, 0x0, - 0x46, 0x66, 0x6c, 0x76, 0x68, 0xd1, 0x0, 0x0, - 0x2, 0x20, 0x0, 0x39, 0x0, 0x0, 0x0, 0x0, - 0xc, 0x30, 0x8, 0x80, 0x0, 0x0, 0x0, 0x0, - 0x7a, 0x0, 0xa0, 0x0, 0x10, 0x5, 0x66, 0x67, - 0x96, 0x88, 0x66, 0x7f, 0x40, 0x10, 0x0, 0x0, - 0xb3, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xb, - 0x30, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xb3, - 0x0, 0x68, 0x0, 0x0, 0x47, 0x66, 0x6d, 0x86, - 0x66, 0x61, 0x0, 0x0, 0x0, 0x0, 0xb3, 0x0, - 0x0, 0x0, 0x0, 0x0, 0x0, 0xb, 0x30, 0x0, - 0x0, 0x0, 0x0, 0x0, 0x0, 0xb4, 0x0, 0x0, - 0x0, 0x0, 0x0, 0x0, 0x4, 0x0, 0x0, 0x0, - 0x0, - - /* U+8F9E "辞" */ - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x1, 0x30, 0x1, 0xb0, 0x0, 0x0, - 0x0, 0x26, 0xad, 0xa0, 0x0, 0x92, 0x2, 0x0, - 0x3, 0x43, 0xd0, 0x5, 0x76, 0x66, 0x69, 0x30, - 0x0, 0x0, 0xd0, 0x0, 0x40, 0x0, 0x92, 0x0, - 0x0, 0x0, 0xd0, 0x51, 0x49, 0x2, 0xe1, 0x0, - 0x6, 0x66, 0xe6, 0x63, 0xe, 0x7, 0x40, 0x0, - 0x0, 0x0, 0xd0, 0x1, 0x12, 0x18, 0x13, 0x50, - 0x0, 0x10, 0xd0, 0x36, 0x54, 0xd4, 0x44, 0x40, - 0x1, 0xe6, 0x76, 0xe0, 0x0, 0xd0, 0x0, 0x0, - 0x0, 0xd0, 0x1, 0xb0, 0x0, 0xd0, 0x6, 0x0, - 0x0, 0xd0, 0x1, 0xb5, 0x76, 0xe6, 0x66, 0x10, - 0x0, 0xd0, 0x1, 0xb0, 0x0, 0xd0, 0x0, 0x0, - 0x0, 0xe6, 0x66, 0xb0, 0x0, 0xd0, 0x0, 0x0, - 0x1, 0xb0, 0x0, 0x40, 0x0, 0xd0, 0x0, 0x0, - 0x0, 0x0, 0x0, 0x0, 0x0, 0x50, 0x0, 0x0, - - /* U+8FA6 "辦" */ - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x43, 0x0, 0xb, 0x20, 0x6, 0x50, 0x0, - 0x0, 0xe, 0x0, 0xc, 0x0, 0x0, 0xd0, 0x0, - 0x5, 0x6b, 0x95, 0xc, 0x1, 0x66, 0x78, 0x90, - 0x1, 0x0, 0x72, 0x6d, 0x6d, 0x20, 0x5, 0x20, - 0x1, 0xa0, 0xc0, 0xb, 0xb, 0x19, 0xc, 0x30, - 0x0, 0xa4, 0x50, 0xb, 0xb, 0xc, 0x28, 0x0, - 0x7, 0x6b, 0x7a, 0x2a, 0xb, 0x56, 0x96, 0xd2, - 0x0, 0xc, 0x0, 0x47, 0x19, 0x10, 0xc0, 0x0, - 0x0, 0xc, 0x10, 0x83, 0x28, 0x0, 0xc0, 0x0, - 0x5, 0x6c, 0x74, 0xb0, 0x47, 0x46, 0xd7, 0xa0, - 0x0, 0x38, 0x4, 0x60, 0x65, 0x10, 0xc0, 0x0, - 0x0, 0x83, 0xa, 0x0, 0xa2, 0x0, 0xc0, 0x0, - 0x1, 0x90, 0x72, 0x3c, 0xc0, 0x0, 0xc0, 0x0, - 0x7, 0x15, 0x30, 0x1, 0x0, 0x0, 0xd0, 0x0, - 0x10, 0x0, 0x0, 0x0, 0x0, 0x0, 0x40, 0x0, - - /* U+8FB2 "農" */ - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x1, 0xd0, 0xd, 0x20, 0x10, 0x0, - 0x0, 0xe, 0x66, 0xd6, 0x6e, 0x66, 0xd3, 0x0, - 0x0, 0xd, 0x0, 0xb0, 0xd, 0x0, 0xd0, 0x0, - 0x0, 0xd, 0x66, 0xd6, 0x6e, 0x66, 0xe0, 0x0, - 0x0, 0xd, 0x0, 0xb0, 0xd, 0x0, 0xd0, 0x0, - 0x0, 0xb, 0x66, 0x76, 0x67, 0x66, 0xa0, 0x0, - 0x0, 0x9, 0x66, 0x66, 0x66, 0x66, 0xb8, 0x0, - 0x0, 0xd, 0x0, 0x0, 0x0, 0x3, 0x0, 0x0, - 0x0, 0xd, 0x47, 0x66, 0x66, 0x68, 0x10, 0x0, - 0x0, 0xe, 0x66, 0x66, 0x66, 0x66, 0x7d, 0x20, - 0x0, 0x1c, 0xb, 0x11, 0x50, 0x4, 0x60, 0x0, - 0x0, 0x67, 0xb, 0x10, 0x47, 0x3a, 0x20, 0x0, - 0x0, 0xb0, 0xb, 0x11, 0x43, 0xd5, 0x0, 0x0, - 0x7, 0x20, 0xe, 0xc6, 0x0, 0x19, 0xeb, 0x60, - 0x21, 0x0, 0x4, 0x0, 0x0, 0x0, 0x5, 0x0, - - /* U+8FBA "辺" */ - 0x0, 0x82, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x2e, 0x20, 0x0, 0x0, 0x0, 0x7, 0x0, - 0x0, 0xa, 0x34, 0x76, 0xb9, 0x66, 0x6d, 0x10, - 0x0, 0x0, 0x0, 0x0, 0xa3, 0x0, 0x1b, 0x0, - 0x0, 0x7, 0x0, 0x0, 0xc1, 0x0, 0x2a, 0x0, - 0x27, 0x6e, 0x30, 0x0, 0xd0, 0x0, 0x39, 0x0, - 0x0, 0xd, 0x0, 0x4, 0x90, 0x0, 0x48, 0x0, - 0x0, 0xd, 0x0, 0x9, 0x40, 0x0, 0x67, 0x0, - 0x0, 0xd, 0x0, 0x1b, 0x0, 0x0, 0x76, 0x0, - 0x0, 0xd, 0x0, 0x82, 0x0, 0x0, 0xb3, 0x0, - 0x0, 0xd, 0x4, 0x50, 0x2, 0x56, 0xe0, 0x0, - 0x2, 0xa9, 0x74, 0x0, 0x0, 0x2d, 0x40, 0x0, - 0x2e, 0x30, 0x4b, 0x41, 0x0, 0x0, 0x1, 0x21, - 0x2, 0x0, 0x1, 0x8c, 0xef, 0xff, 0xff, 0x80, - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x1, 0x0, - - /* U+8FBC "込" */ - 0x0, 0x50, 0x0, 0x0, 0x50, 0x0, 0x0, 0x0, - 0x0, 0x6c, 0x0, 0x0, 0x70, 0x0, 0x0, 0x0, - 0x0, 0xd, 0x30, 0x0, 0x33, 0x0, 0x0, 0x0, - 0x0, 0x1, 0x0, 0x0, 0x8, 0x0, 0x0, 0x0, - 0x0, 0x3, 0x0, 0x0, 0x2e, 0x0, 0x0, 0x0, - 0x17, 0x6e, 0x50, 0x0, 0x79, 0x50, 0x0, 0x0, - 0x0, 0xd, 0x0, 0x0, 0xd0, 0xa0, 0x0, 0x0, - 0x0, 0xd, 0x0, 0x7, 0x60, 0x74, 0x0, 0x0, - 0x0, 0xd, 0x0, 0x2a, 0x0, 0x1d, 0x0, 0x0, - 0x0, 0xd, 0x0, 0x90, 0x0, 0x7, 0xb0, 0x0, - 0x0, 0xd, 0x6, 0x0, 0x0, 0x0, 0xbd, 0x40, - 0x2, 0xaa, 0x80, 0x0, 0x0, 0x0, 0x8, 0x40, - 0x1e, 0x50, 0x4a, 0x41, 0x0, 0x0, 0x0, 0x10, - 0x2, 0x0, 0x1, 0x7b, 0xde, 0xee, 0xff, 0x71, - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - - /* U+8FCE "迎" */ - 0x0, 0x30, 0x0, 0x0, 0x1a, 0x10, 0x0, 0x0, - 0x0, 0x69, 0x0, 0x56, 0x84, 0x10, 0x1, 0x0, - 0x0, 0xf, 0x10, 0xd0, 0x0, 0xd6, 0x6d, 0x30, - 0x0, 0x2, 0x0, 0xd0, 0x0, 0xd0, 0xd, 0x0, - 0x0, 0x1, 0x0, 0xd0, 0x0, 0xd0, 0xd, 0x0, - 0x7, 0x6e, 0x20, 0xd0, 0x0, 0xd0, 0xd, 0x0, - 0x0, 0xd, 0x0, 0xd0, 0x0, 0xd0, 0xd, 0x0, - 0x0, 0xd, 0x0, 0xd0, 0x2, 0xd0, 0xd, 0x0, - 0x0, 0xd, 0x0, 0xd7, 0x70, 0xd0, 0xd, 0x0, - 0x0, 0xd, 0x1, 0xf6, 0x0, 0xd3, 0xad, 0x0, - 0x0, 0xd, 0x0, 0x10, 0x0, 0xd0, 0x11, 0x0, - 0x4, 0xb6, 0x80, 0x0, 0x0, 0xd0, 0x0, 0x0, - 0x2d, 0x10, 0x2a, 0x74, 0x32, 0x42, 0x24, 0x51, - 0x0, 0x0, 0x0, 0x37, 0xab, 0xcd, 0xdd, 0x30, - - /* U+8FD1 "近" */ - 0x0, 0x40, 0x0, 0x0, 0x0, 0x0, 0x62, 0x0, - 0x0, 0x4b, 0x0, 0x16, 0x47, 0x9a, 0x85, 0x0, - 0x0, 0xc, 0x20, 0x1c, 0x10, 0x0, 0x0, 0x0, - 0x0, 0x1, 0x0, 0x1c, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x2, 0x0, 0x1c, 0x0, 0x0, 0x2, 0x30, - 0x18, 0x6e, 0x30, 0x1d, 0x66, 0x6c, 0x67, 0x60, - 0x0, 0xd, 0x0, 0x1b, 0x0, 0xd, 0x0, 0x0, - 0x0, 0xd, 0x0, 0x39, 0x0, 0xd, 0x0, 0x0, - 0x0, 0xd, 0x0, 0x65, 0x0, 0xd, 0x0, 0x0, - 0x0, 0xd, 0x0, 0xa0, 0x0, 0xd, 0x0, 0x0, - 0x0, 0xd, 0x4, 0x50, 0x0, 0xd, 0x0, 0x0, - 0x0, 0x5a, 0x43, 0x0, 0x0, 0xe, 0x0, 0x0, - 0x9, 0x80, 0x49, 0x30, 0x0, 0x2, 0x0, 0x10, - 0x19, 0x0, 0x1, 0x8c, 0xde, 0xff, 0xff, 0x91, - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x1, 0x0, - - /* U+8FD4 "返" */ - 0x0, 0x30, 0x0, 0x0, 0x0, 0x3, 0x80, 0x0, - 0x0, 0x3b, 0x0, 0x65, 0x78, 0x99, 0x82, 0x0, - 0x0, 0xc, 0x30, 0xa3, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x3, 0x0, 0xa3, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x0, 0xa8, 0x66, 0x66, 0xc2, 0x0, - 0x17, 0x6c, 0x30, 0xb2, 0x0, 0x2, 0xd0, 0x0, - 0x1, 0xd, 0x0, 0xc3, 0x10, 0x9, 0x50, 0x0, - 0x0, 0xd, 0x0, 0xc0, 0x47, 0x3c, 0x0, 0x0, - 0x0, 0xd, 0x1, 0xa0, 0x1, 0xf9, 0x0, 0x0, - 0x0, 0xd, 0x6, 0x30, 0x9, 0x68, 0xc1, 0x0, - 0x0, 0xd, 0x8, 0x0, 0x95, 0x0, 0x8b, 0x0, - 0x0, 0x1c, 0x40, 0x37, 0x10, 0x0, 0x5, 0x0, - 0x7, 0x90, 0x58, 0x51, 0x0, 0x0, 0x1, 0x20, - 0x19, 0x0, 0x1, 0x7c, 0xef, 0xff, 0xff, 0x60, - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - - /* U+8FEB "迫" */ - 0x0, 0x0, 0x0, 0x0, 0x28, 0x0, 0x0, 0x0, - 0x0, 0x74, 0x0, 0x0, 0x59, 0x0, 0x0, 0x0, - 0x0, 0xf, 0x30, 0x10, 0x80, 0x0, 0x30, 0x0, - 0x0, 0x9, 0x20, 0xb7, 0x76, 0x66, 0xf2, 0x0, - 0x0, 0x0, 0x0, 0xb3, 0x0, 0x0, 0xe0, 0x0, - 0x14, 0x4a, 0x20, 0xb3, 0x0, 0x0, 0xe0, 0x0, - 0x3, 0x1d, 0x10, 0xb7, 0x66, 0x66, 0xe0, 0x0, - 0x0, 0xd, 0x0, 0xb3, 0x0, 0x0, 0xe0, 0x0, - 0x0, 0xd, 0x0, 0xb3, 0x0, 0x0, 0xe0, 0x0, - 0x0, 0xd, 0x0, 0xb3, 0x0, 0x0, 0xe0, 0x0, - 0x0, 0xd, 0x0, 0xb7, 0x66, 0x66, 0xe0, 0x0, - 0x1, 0x99, 0x80, 0x91, 0x0, 0x0, 0x90, 0x0, - 0x2e, 0x40, 0x3a, 0x64, 0x22, 0x22, 0x34, 0x50, - 0x3, 0x0, 0x0, 0x58, 0xbc, 0xde, 0xee, 0x30, - - /* U+8FFD "追" */ - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x10, 0x0, 0x0, 0xc, 0x10, 0x0, 0x0, - 0x0, 0x95, 0x0, 0x0, 0x56, 0x0, 0x10, 0x0, - 0x0, 0x2f, 0x0, 0xb6, 0x86, 0x66, 0xe1, 0x0, - 0x0, 0x6, 0x0, 0xc0, 0x0, 0x0, 0xd0, 0x0, - 0x0, 0x0, 0x0, 0xc0, 0x0, 0x0, 0xd0, 0x0, - 0x16, 0x6b, 0x30, 0xc6, 0x55, 0x55, 0xd0, 0x0, - 0x1, 0xd, 0x0, 0xc0, 0x0, 0x0, 0x10, 0x0, - 0x0, 0xd, 0x0, 0xc6, 0x66, 0x66, 0x98, 0x0, - 0x0, 0xd, 0x0, 0xc0, 0x0, 0x0, 0x76, 0x0, - 0x0, 0xd, 0x0, 0xc0, 0x0, 0x0, 0x76, 0x0, - 0x0, 0xd, 0x0, 0xd6, 0x66, 0x66, 0xa6, 0x0, - 0x1, 0x99, 0x70, 0xd0, 0x0, 0x0, 0x64, 0x0, - 0x2e, 0x40, 0x3a, 0x61, 0x0, 0x0, 0x0, 0x20, - 0x4, 0x0, 0x1, 0x7b, 0xde, 0xee, 0xff, 0x60, - 0x0, 0x0, 0x0, 0x0, 0x0, 0x1, 0x11, 0x0, - - /* U+9000 "退" */ - 0x0, 0x20, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x87, 0x0, 0x4a, 0x66, 0x66, 0xe1, 0x0, - 0x0, 0x1f, 0x0, 0x3a, 0x0, 0x0, 0xe0, 0x0, - 0x0, 0x2, 0x0, 0x3c, 0x66, 0x66, 0xe0, 0x0, - 0x0, 0x0, 0x0, 0x3a, 0x0, 0x0, 0xe0, 0x0, - 0x6, 0x6c, 0x30, 0x3a, 0x0, 0x0, 0xe0, 0x0, - 0x1, 0xe, 0x0, 0x3c, 0x66, 0x66, 0xb2, 0x0, - 0x0, 0xe, 0x0, 0x3a, 0x10, 0x0, 0x8a, 0x0, - 0x0, 0xe, 0x0, 0x3a, 0x6, 0x77, 0x30, 0x0, - 0x0, 0xe, 0x0, 0x3a, 0x1, 0x4b, 0x70, 0x0, - 0x0, 0xe, 0x0, 0x3c, 0x85, 0x0, 0xab, 0x0, - 0x2, 0x97, 0x80, 0x3d, 0x20, 0x0, 0x9, 0x0, - 0x1e, 0x20, 0x1a, 0x74, 0x21, 0x11, 0x23, 0x41, - 0x0, 0x0, 0x0, 0x59, 0xbd, 0xef, 0xff, 0x40, - - /* U+9001 "送" */ - 0x0, 0x20, 0x0, 0x14, 0x0, 0x7, 0x30, 0x0, - 0x0, 0x78, 0x0, 0x9, 0x60, 0xd, 0x20, 0x0, - 0x0, 0xf, 0x10, 0x3, 0xb0, 0x46, 0x0, 0x0, - 0x0, 0x3, 0x0, 0x56, 0x66, 0xa6, 0x7c, 0x10, - 0x0, 0x0, 0x0, 0x10, 0xb, 0x20, 0x0, 0x0, - 0x27, 0x6d, 0x10, 0x0, 0xc, 0x10, 0x2, 0x10, - 0x0, 0xd, 0x6, 0x66, 0x6e, 0x66, 0x6a, 0x80, - 0x0, 0xd, 0x0, 0x0, 0x1d, 0x0, 0x0, 0x0, - 0x0, 0xd, 0x0, 0x0, 0x6b, 0x60, 0x0, 0x0, - 0x0, 0xd, 0x0, 0x1, 0xc1, 0x2c, 0x60, 0x0, - 0x0, 0xd, 0x0, 0xa, 0x20, 0x1, 0xd7, 0x0, - 0x0, 0x8b, 0x62, 0x71, 0x0, 0x0, 0x28, 0x0, - 0x2d, 0x50, 0x5b, 0x40, 0x0, 0x0, 0x1, 0x21, - 0x4, 0x0, 0x1, 0x8c, 0xcd, 0xee, 0xff, 0x70, - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x1, 0x0, - - /* U+9003 "逃" */ - 0x0, 0x10, 0x0, 0x0, 0x91, 0x92, 0x0, 0x0, - 0x0, 0x76, 0x0, 0x0, 0xd0, 0xd0, 0x0, 0x0, - 0x0, 0x1f, 0x4, 0x10, 0xd0, 0xd0, 0x3e, 0x10, - 0x0, 0x4, 0x1, 0xd0, 0xd0, 0xd2, 0xa1, 0x0, - 0x0, 0x0, 0x0, 0xa0, 0xd0, 0xd5, 0x0, 0x0, - 0x5, 0x6c, 0x20, 0x0, 0xd0, 0xd0, 0x0, 0x0, - 0x1, 0xd, 0x0, 0x7, 0xe0, 0xd7, 0x92, 0x0, - 0x0, 0xd, 0x5, 0xa1, 0xd0, 0xd0, 0x6d, 0x0, - 0x0, 0xd, 0x1b, 0x13, 0xa0, 0xd0, 0x3, 0x20, - 0x0, 0xd, 0x0, 0x9, 0x30, 0xd0, 0x0, 0x60, - 0x0, 0xd, 0x0, 0x37, 0x0, 0xc3, 0x14, 0xb0, - 0x0, 0x4b, 0x42, 0x50, 0x0, 0x49, 0x99, 0x50, - 0xc, 0x70, 0x59, 0x41, 0x0, 0x0, 0x12, 0x31, - 0x3, 0x0, 0x1, 0x7b, 0xde, 0xff, 0xff, 0x90, - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - - /* U+900F "透" */ - 0x0, 0x0, 0x0, 0x0, 0x0, 0x38, 0x60, 0x0, - 0x0, 0x93, 0x0, 0x45, 0x7d, 0x75, 0x30, 0x0, - 0x0, 0x3e, 0x0, 0x0, 0xc, 0x0, 0x5, 0x10, - 0x0, 0x4, 0x7, 0x66, 0xce, 0x96, 0x67, 0x50, - 0x0, 0x0, 0x0, 0x7, 0x6c, 0x28, 0x0, 0x0, - 0x14, 0x4a, 0x10, 0x75, 0xc, 0x3, 0xc8, 0x40, - 0x3, 0x1d, 0x26, 0x76, 0x6a, 0x69, 0x28, 0x40, - 0x0, 0xd, 0x0, 0x12, 0xc0, 0xc, 0x0, 0x0, - 0x0, 0xd, 0x0, 0x3, 0x90, 0x7a, 0xa5, 0x0, - 0x0, 0xd, 0x0, 0x9, 0x20, 0x10, 0xa3, 0x0, - 0x0, 0xd, 0x0, 0x38, 0x0, 0x0, 0xd0, 0x0, - 0x0, 0x6b, 0x32, 0x60, 0x2, 0x8b, 0x90, 0x0, - 0x1d, 0x50, 0x59, 0x30, 0x0, 0x17, 0x0, 0x10, - 0x5, 0x0, 0x2, 0x8c, 0xde, 0xee, 0xef, 0x70, - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x11, 0x0, - - /* U+9010 "逐" */ - 0x0, 0x40, 0x0, 0x0, 0x0, 0x0, 0x0, 0x10, - 0x0, 0x6a, 0x2, 0x76, 0x67, 0x76, 0x6a, 0xa0, - 0x0, 0xe, 0x10, 0x0, 0x1c, 0x20, 0x0, 0x0, - 0x0, 0x1, 0x0, 0x1, 0xa7, 0x0, 0x9, 0x30, - 0x0, 0x0, 0x0, 0x37, 0x6, 0x50, 0x88, 0x10, - 0x16, 0x6c, 0x32, 0x20, 0x2b, 0xc7, 0x20, 0x0, - 0x0, 0xd, 0x0, 0x4, 0x80, 0x85, 0x0, 0x0, - 0x0, 0xd, 0x1, 0x64, 0x2, 0xeb, 0x70, 0x0, - 0x0, 0xd, 0x2, 0x0, 0x3c, 0x5a, 0x3d, 0x20, - 0x0, 0xd, 0x0, 0x7, 0x90, 0x3a, 0x6, 0xc0, - 0x0, 0xd, 0x3, 0x73, 0x0, 0x68, 0x0, 0x60, - 0x0, 0x78, 0x61, 0x0, 0x5b, 0xe2, 0x0, 0x0, - 0x1d, 0x40, 0x39, 0x41, 0x3, 0x30, 0x0, 0x0, - 0x4, 0x0, 0x1, 0x7b, 0xde, 0xee, 0xef, 0xa1, - 0x0, 0x0, 0x0, 0x0, 0x0, 0x1, 0x11, 0x0, - - /* U+9019 "這" */ - 0x0, 0x70, 0x0, 0x0, 0x9, 0x10, 0x0, 0x0, - 0x0, 0x5d, 0x0, 0x0, 0x7, 0x70, 0x0, 0x0, - 0x0, 0xb, 0x3, 0x66, 0x67, 0x76, 0x8d, 0x10, - 0x0, 0x0, 0x0, 0x10, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x2, 0x0, 0x26, 0x66, 0x67, 0xd1, 0x0, - 0x18, 0x6f, 0x40, 0x2, 0x0, 0x0, 0x0, 0x0, - 0x0, 0xd, 0x0, 0x17, 0x66, 0x67, 0xc0, 0x0, - 0x0, 0xd, 0x0, 0x1, 0x0, 0x0, 0x0, 0x0, - 0x0, 0xd, 0x0, 0x39, 0x66, 0x66, 0xc4, 0x0, - 0x0, 0xd, 0x0, 0x2a, 0x0, 0x0, 0xd0, 0x0, - 0x0, 0xd, 0x0, 0x2a, 0x0, 0x0, 0xd0, 0x0, - 0x3, 0xb8, 0x70, 0x2c, 0x66, 0x66, 0xe0, 0x0, - 0x3e, 0x10, 0x2a, 0x76, 0x0, 0x0, 0x11, 0x31, - 0x1, 0x0, 0x0, 0x5a, 0xce, 0xff, 0xff, 0x60, - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - - /* U+901A "通" */ - 0x0, 0x10, 0x0, 0x56, 0x66, 0x66, 0xa2, 0x0, - 0x0, 0xb4, 0x0, 0x11, 0x20, 0x8, 0x83, 0x0, - 0x0, 0x4c, 0x0, 0x0, 0x4c, 0x61, 0x0, 0x0, - 0x0, 0x3, 0x1, 0xa6, 0x6d, 0x86, 0x6c, 0x10, - 0x0, 0x0, 0x0, 0xc0, 0xd, 0x0, 0xd, 0x0, - 0x17, 0x6d, 0x30, 0xc0, 0xd, 0x0, 0xd, 0x0, - 0x1, 0xd, 0x0, 0xd6, 0x6e, 0x66, 0x6d, 0x0, - 0x0, 0xd, 0x0, 0xc0, 0xd, 0x0, 0xd, 0x0, - 0x0, 0xd, 0x0, 0xd6, 0x6e, 0x66, 0x6d, 0x0, - 0x0, 0xd, 0x0, 0xc0, 0xd, 0x0, 0xd, 0x0, - 0x0, 0xd, 0x0, 0xc0, 0xd, 0x0, 0xd, 0x0, - 0x0, 0x6a, 0x51, 0xa0, 0x8, 0x5, 0xcb, 0x0, - 0x1c, 0x60, 0x49, 0x41, 0x0, 0x0, 0x22, 0x21, - 0x6, 0x0, 0x1, 0x7b, 0xef, 0xff, 0xff, 0x80, - 0x0, 0x0, 0x0, 0x0, 0x0, 0x1, 0x11, 0x0, - - /* U+901F "速" */ - 0x0, 0x0, 0x0, 0x0, 0xa, 0x20, 0x0, 0x0, - 0x1, 0x91, 0x0, 0x0, 0xd, 0x0, 0x2, 0x0, - 0x0, 0x7c, 0x7, 0x66, 0x6e, 0x66, 0x6a, 0x30, - 0x0, 0x16, 0x0, 0x0, 0xd, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x0, 0xa6, 0x6e, 0x66, 0xd4, 0x0, - 0x1, 0x16, 0x10, 0xd0, 0xd, 0x0, 0xd0, 0x0, - 0x17, 0x5d, 0x20, 0xd0, 0xd, 0x0, 0xd0, 0x0, - 0x0, 0xd, 0x0, 0xc6, 0x9f, 0x66, 0xc0, 0x0, - 0x0, 0xd, 0x0, 0x11, 0xbe, 0x51, 0x0, 0x0, - 0x0, 0xd, 0x0, 0xa, 0x2d, 0x1a, 0xa1, 0x0, - 0x0, 0xd, 0x1, 0x81, 0xd, 0x0, 0x7d, 0x0, - 0x0, 0x7a, 0x65, 0x0, 0xe, 0x0, 0x4, 0x0, - 0x1d, 0x50, 0x49, 0x30, 0x8, 0x0, 0x1, 0x21, - 0x3, 0x0, 0x1, 0x7c, 0xde, 0xef, 0xff, 0x70, - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - - /* U+9020 "造" */ - 0x0, 0x10, 0x0, 0x0, 0xa, 0x20, 0x0, 0x0, - 0x0, 0xa6, 0x0, 0x2b, 0x1d, 0x0, 0x0, 0x0, - 0x0, 0x2f, 0x0, 0x5b, 0xd, 0x0, 0x81, 0x0, - 0x0, 0x4, 0x0, 0x96, 0x6e, 0x66, 0x63, 0x0, - 0x0, 0x0, 0x0, 0x70, 0xd, 0x0, 0x0, 0x0, - 0x3, 0x39, 0x12, 0x0, 0xd, 0x0, 0x7, 0x40, - 0x5, 0x3d, 0x16, 0x66, 0x66, 0x66, 0x66, 0x50, - 0x0, 0xd, 0x0, 0x9, 0x66, 0x66, 0xa2, 0x0, - 0x0, 0xd, 0x0, 0xd, 0x0, 0x0, 0xd0, 0x0, - 0x0, 0xd, 0x0, 0xd, 0x0, 0x0, 0xd0, 0x0, - 0x0, 0xd, 0x0, 0xd, 0x0, 0x0, 0xd0, 0x0, - 0x2, 0xa9, 0x50, 0xe, 0x66, 0x66, 0xd0, 0x0, - 0x2e, 0x30, 0x5a, 0x43, 0x0, 0x0, 0x0, 0x11, - 0x2, 0x0, 0x1, 0x8b, 0xdd, 0xef, 0xff, 0x90, - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - - /* U+9023 "連" */ - 0x0, 0x50, 0x0, 0x0, 0xa, 0x30, 0x0, 0x0, - 0x0, 0x5a, 0x0, 0x0, 0xc, 0x0, 0x25, 0x0, - 0x0, 0xd, 0x13, 0x76, 0x6d, 0x66, 0x65, 0x0, - 0x0, 0x0, 0x0, 0x86, 0x6d, 0x66, 0xa3, 0x0, - 0x0, 0x4, 0x0, 0xc0, 0xc, 0x0, 0xb1, 0x0, - 0x27, 0x5e, 0x40, 0xc6, 0x6d, 0x66, 0xd0, 0x0, - 0x0, 0xd, 0x0, 0xc0, 0xc, 0x0, 0xb0, 0x0, - 0x0, 0xd, 0x0, 0xc6, 0x6d, 0x66, 0xd1, 0x0, - 0x0, 0xd, 0x0, 0x70, 0xc, 0x0, 0x50, 0x0, - 0x0, 0xd, 0x26, 0x66, 0x6d, 0x66, 0x6c, 0x50, - 0x0, 0x1e, 0x1, 0x0, 0xc, 0x0, 0x0, 0x0, - 0x6, 0xc5, 0x91, 0x0, 0xc, 0x0, 0x0, 0x0, - 0x2d, 0x10, 0x2b, 0x84, 0x27, 0x22, 0x34, 0x50, - 0x0, 0x0, 0x0, 0x38, 0xab, 0xcc, 0xcc, 0x20, - - /* U+902E "逮" */ - 0x0, 0x20, 0x0, 0x0, 0xb, 0x10, 0x0, 0x0, - 0x0, 0x78, 0x0, 0x0, 0xd, 0x0, 0x50, 0x0, - 0x0, 0xe, 0x10, 0x76, 0x6e, 0x66, 0xe2, 0x0, - 0x0, 0x1, 0x0, 0x0, 0xd, 0x0, 0xe3, 0x40, - 0x0, 0x0, 0x7, 0x66, 0x6e, 0x66, 0xe6, 0x50, - 0x17, 0x6e, 0x40, 0x56, 0x6e, 0x66, 0xe0, 0x0, - 0x0, 0xd, 0x1, 0x40, 0xd, 0x0, 0x40, 0x0, - 0x0, 0xd, 0x0, 0x7b, 0xd, 0x8, 0xc0, 0x0, - 0x0, 0xd, 0x0, 0x5, 0x3d, 0x73, 0x0, 0x0, - 0x0, 0xd, 0x0, 0x58, 0x3d, 0x78, 0x20, 0x0, - 0x0, 0xd, 0xd, 0x70, 0xd, 0x1, 0xc8, 0x0, - 0x0, 0x87, 0x50, 0x7, 0x8d, 0x0, 0x7, 0x0, - 0x1c, 0x30, 0x49, 0x30, 0x86, 0x0, 0x0, 0x10, - 0x4, 0x0, 0x1, 0x8c, 0xdd, 0xde, 0xff, 0xa0, - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x1, 0x0, - - /* U+9031 "週" */ - 0x0, 0x71, 0x0, 0x40, 0x0, 0x0, 0x5, 0x0, - 0x0, 0x2e, 0x20, 0xd6, 0x6a, 0xb6, 0x6e, 0x10, - 0x0, 0x8, 0x30, 0xc0, 0x7, 0x54, 0xc, 0x0, - 0x0, 0x0, 0x0, 0xc0, 0x7a, 0x97, 0x1c, 0x0, - 0x0, 0x6, 0x0, 0xc0, 0x7, 0x52, 0xc, 0x0, - 0x27, 0x6e, 0x30, 0xb4, 0x77, 0x68, 0x5c, 0x0, - 0x0, 0xd, 0x0, 0xb0, 0x86, 0x6a, 0xc, 0x0, - 0x0, 0xd, 0x0, 0xa0, 0xc0, 0xc, 0xc, 0x0, - 0x0, 0xd, 0x2, 0x60, 0xc0, 0xb, 0xc, 0x0, - 0x0, 0xd, 0x6, 0x20, 0xd6, 0x6b, 0xc, 0x0, - 0x0, 0xd, 0x7, 0x0, 0x40, 0x0, 0xb, 0x0, - 0x3, 0xa8, 0x82, 0x0, 0x0, 0x15, 0xd8, 0x0, - 0x2e, 0x20, 0x4a, 0x41, 0x0, 0x0, 0x10, 0x11, - 0x2, 0x0, 0x1, 0x7b, 0xde, 0xee, 0xff, 0xb1, - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - - /* U+9032 "進" */ - 0x0, 0x51, 0x0, 0x1a, 0x27, 0x30, 0x0, 0x0, - 0x0, 0x3e, 0x10, 0x5c, 0x11, 0xe0, 0x0, 0x0, - 0x0, 0xa, 0x30, 0xa4, 0x0, 0x50, 0x26, 0x0, - 0x0, 0x0, 0x1, 0xf7, 0x66, 0xc6, 0x66, 0x10, - 0x0, 0x5, 0x7, 0xc2, 0x0, 0xc0, 0x10, 0x0, - 0x7, 0x6e, 0x57, 0x97, 0x66, 0xd6, 0xa6, 0x0, - 0x0, 0xd, 0x10, 0x92, 0x0, 0xc0, 0x0, 0x0, - 0x0, 0xd, 0x0, 0x97, 0x66, 0xd6, 0xb7, 0x0, - 0x0, 0xd, 0x0, 0x92, 0x0, 0xc0, 0x0, 0x0, - 0x0, 0xd, 0x0, 0x92, 0x0, 0xc0, 0x1, 0x0, - 0x0, 0xd, 0x0, 0x97, 0x66, 0xc6, 0x8d, 0x20, - 0x3, 0xc8, 0x90, 0x81, 0x0, 0x0, 0x0, 0x0, - 0x2e, 0x30, 0x3b, 0x62, 0x0, 0x0, 0x12, 0x31, - 0x2, 0x0, 0x0, 0x7c, 0xef, 0xff, 0xff, 0x70, - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x1, 0x0, - - /* U+9045 "遅" */ - 0x0, 0x61, 0x0, 0x40, 0x0, 0x0, 0x4, 0x0, - 0x0, 0x3d, 0x0, 0xd6, 0x66, 0x66, 0x6e, 0x30, - 0x0, 0xb, 0x20, 0xd0, 0x0, 0x0, 0xd, 0x0, - 0x0, 0x0, 0x0, 0xd6, 0x66, 0x66, 0x6d, 0x0, - 0x0, 0x3, 0x0, 0xd0, 0x75, 0x4, 0xb0, 0x0, - 0x18, 0x6e, 0x50, 0xc0, 0xc, 0x9, 0x27, 0x0, - 0x0, 0xd, 0x0, 0xc6, 0x76, 0xe6, 0x66, 0x10, - 0x0, 0xd, 0x1, 0x93, 0x66, 0xe6, 0x88, 0x0, - 0x0, 0xd, 0x5, 0x40, 0x10, 0xd0, 0x0, 0x0, - 0x0, 0xd, 0x8, 0x47, 0x66, 0xe6, 0x69, 0xa0, - 0x0, 0xd, 0x23, 0x0, 0x0, 0xd0, 0x0, 0x0, - 0x2, 0xb9, 0x90, 0x0, 0x0, 0xd0, 0x0, 0x0, - 0x2e, 0x40, 0x4b, 0x40, 0x0, 0x60, 0x0, 0x10, - 0x3, 0x0, 0x1, 0x7c, 0xdd, 0xdd, 0xef, 0x81, - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x1, 0x0, - - /* U+904A "遊" */ - 0x0, 0x81, 0x0, 0x43, 0x0, 0x8, 0x0, 0x0, - 0x0, 0x3e, 0x10, 0xe, 0x0, 0x3b, 0x10, 0x0, - 0x0, 0x9, 0x10, 0x3, 0x10, 0xa7, 0x46, 0xa0, - 0x0, 0x0, 0x7, 0xa6, 0x89, 0x82, 0x22, 0x20, - 0x0, 0x5, 0x0, 0xb0, 0x15, 0x46, 0x6a, 0x60, - 0x27, 0x6f, 0x30, 0xc6, 0xc5, 0x0, 0x38, 0x10, - 0x0, 0xd, 0x0, 0xc0, 0xb1, 0x0, 0xd0, 0x0, - 0x0, 0xd, 0x1, 0xa0, 0xc3, 0x66, 0xc7, 0xc1, - 0x0, 0xd, 0x5, 0x50, 0xc0, 0x0, 0xb0, 0x0, - 0x0, 0xd, 0x9, 0x0, 0xc0, 0x0, 0xb0, 0x0, - 0x0, 0xd, 0x43, 0x36, 0x80, 0x0, 0xa0, 0x0, - 0x3, 0xaa, 0x60, 0x2c, 0x10, 0x4c, 0x80, 0x0, - 0x2e, 0x20, 0x68, 0x20, 0x0, 0x2, 0x0, 0x11, - 0x1, 0x0, 0x2, 0x8b, 0xcd, 0xdd, 0xef, 0x70, - 0x0, 0x0, 0x0, 0x0, 0x0, 0x1, 0x11, 0x0, - - /* U+904B "運" */ - 0x1, 0x70, 0x1, 0x40, 0x0, 0x0, 0x6, 0x0, - 0x0, 0x7c, 0x5, 0x96, 0x66, 0x66, 0x7e, 0x40, - 0x0, 0xd, 0xd, 0x20, 0xb, 0x30, 0x51, 0x0, - 0x0, 0x0, 0x3, 0x76, 0x6d, 0x66, 0x97, 0x0, - 0x0, 0x1, 0x0, 0x30, 0xb, 0x0, 0x40, 0x0, - 0x17, 0x6e, 0x30, 0xb6, 0x6d, 0x66, 0xd3, 0x0, - 0x0, 0xd, 0x0, 0xb6, 0x6d, 0x66, 0xd0, 0x0, - 0x0, 0xd, 0x0, 0xb0, 0xb, 0x0, 0xb0, 0x0, - 0x0, 0xd, 0x0, 0xb6, 0x6d, 0x66, 0xd1, 0x0, - 0x0, 0xd, 0x0, 0x30, 0xb, 0x0, 0x25, 0x0, - 0x0, 0xd, 0x7, 0x66, 0x6d, 0x66, 0x67, 0x40, - 0x2, 0xa9, 0x50, 0x0, 0xb, 0x0, 0x0, 0x0, - 0x2e, 0x30, 0x59, 0x30, 0x9, 0x0, 0x0, 0x10, - 0x2, 0x0, 0x1, 0x8c, 0xde, 0xee, 0xef, 0x60, - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - - /* U+904E "過" */ - 0x0, 0x70, 0x0, 0x4, 0x0, 0x0, 0x40, 0x0, - 0x0, 0x4d, 0x0, 0xf, 0x66, 0x66, 0xc0, 0x0, - 0x0, 0xc, 0x10, 0xf, 0x66, 0x91, 0xa0, 0x0, - 0x0, 0x0, 0x0, 0xe, 0x4, 0x81, 0xa0, 0x0, - 0x0, 0x5, 0x1, 0xe, 0x4, 0x71, 0xa2, 0x0, - 0x27, 0x6f, 0x2a, 0x78, 0x66, 0x76, 0x7d, 0x40, - 0x0, 0xd, 0xa, 0x20, 0x86, 0x69, 0x1c, 0x0, - 0x0, 0xd, 0x9, 0x20, 0xc0, 0xc, 0xc, 0x0, - 0x0, 0xd, 0x9, 0x20, 0xc0, 0xc, 0xc, 0x0, - 0x0, 0xd, 0x9, 0x20, 0xd6, 0x6d, 0xc, 0x0, - 0x0, 0xd, 0xa, 0x30, 0x60, 0x4, 0xd, 0x0, - 0x3, 0xa9, 0x56, 0x10, 0x0, 0x2, 0x9b, 0x0, - 0x3e, 0x20, 0x5a, 0x41, 0x0, 0x0, 0x0, 0x20, - 0x2, 0x0, 0x1, 0x7c, 0xde, 0xff, 0xff, 0x50, - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x1, 0x0, - - /* U+9053 "道" */ - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x60, 0x0, 0x7, 0x10, 0x6, 0x80, 0x0, - 0x0, 0x4d, 0x0, 0x3, 0xd0, 0xc, 0x20, 0x0, - 0x0, 0xc, 0x10, 0x0, 0x80, 0x53, 0x6, 0x40, - 0x0, 0x0, 0x6, 0x76, 0x6d, 0x66, 0x66, 0x50, - 0x0, 0x2, 0x0, 0x5, 0x29, 0x22, 0x72, 0x0, - 0x17, 0x6e, 0x40, 0x1d, 0x33, 0x33, 0xd2, 0x0, - 0x0, 0xd, 0x0, 0xd, 0x66, 0x66, 0xe0, 0x0, - 0x0, 0xd, 0x0, 0xc, 0x0, 0x0, 0xd0, 0x0, - 0x0, 0xd, 0x0, 0xd, 0x66, 0x66, 0xe0, 0x0, - 0x0, 0xd, 0x0, 0xc, 0x0, 0x0, 0xd0, 0x0, - 0x0, 0xd, 0x0, 0xd, 0x66, 0x66, 0xe0, 0x0, - 0x4, 0xa3, 0x80, 0x1a, 0x0, 0x0, 0x90, 0x0, - 0xb, 0x10, 0x1a, 0x73, 0x10, 0x0, 0x12, 0x30, - 0x0, 0x0, 0x0, 0x48, 0xbd, 0xee, 0xff, 0x60, - - /* U+9054 "達" */ - 0x0, 0x0, 0x0, 0x0, 0x2, 0x0, 0x0, 0x0, - 0x0, 0x85, 0x0, 0x0, 0xb, 0x70, 0x0, 0x0, - 0x0, 0xe, 0x20, 0x56, 0x6c, 0x76, 0xd3, 0x0, - 0x0, 0x5, 0x10, 0x10, 0xa, 0x20, 0x0, 0x0, - 0x0, 0x0, 0x5, 0x66, 0x6c, 0x76, 0x6c, 0x90, - 0x0, 0x7, 0x1, 0x6, 0x40, 0xa, 0x20, 0x0, - 0x28, 0x6e, 0x30, 0x1, 0xe0, 0x49, 0x4, 0x0, - 0x0, 0xd, 0x3, 0x76, 0x89, 0x96, 0x69, 0x30, - 0x0, 0xd, 0x0, 0x0, 0xa, 0x20, 0x60, 0x0, - 0x0, 0xd, 0x0, 0x57, 0x6c, 0x76, 0x72, 0x0, - 0x0, 0xd, 0x0, 0x0, 0xa, 0x20, 0x8, 0x10, - 0x0, 0xd, 0x6, 0x66, 0x6c, 0x76, 0x66, 0x30, - 0x5, 0xb8, 0x70, 0x0, 0xa, 0x20, 0x0, 0x0, - 0x3e, 0x20, 0x4a, 0x41, 0x8, 0x10, 0x0, 0x10, - 0x1, 0x0, 0x1, 0x7c, 0xde, 0xef, 0xff, 0x40, - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - - /* U+9055 "違" */ - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x70, 0x0, 0x0, 0x95, 0x0, 0x0, 0x0, - 0x0, 0x6d, 0x0, 0x57, 0xc6, 0x6b, 0x50, 0x0, - 0x0, 0xd, 0x10, 0x0, 0x90, 0xa, 0x10, 0x0, - 0x0, 0x0, 0x5, 0x66, 0xb6, 0x6c, 0x6c, 0x60, - 0x0, 0x4, 0x1, 0x22, 0x0, 0x0, 0x40, 0x0, - 0x37, 0x6f, 0x30, 0x1c, 0x66, 0x67, 0xc0, 0x0, - 0x0, 0xd, 0x0, 0x1c, 0x66, 0x67, 0xa0, 0x0, - 0x0, 0xd, 0x0, 0x14, 0xc, 0x1, 0x50, 0x0, - 0x0, 0xd, 0x4, 0x76, 0x6d, 0x66, 0xa3, 0x0, - 0x0, 0xd, 0x0, 0x95, 0xc, 0x0, 0x3, 0x0, - 0x0, 0xd, 0x2, 0xe6, 0x6d, 0x66, 0x69, 0x50, - 0x4, 0xb9, 0x50, 0x0, 0xc, 0x0, 0x0, 0x0, - 0x4e, 0x20, 0x79, 0x20, 0x7, 0x0, 0x0, 0x10, - 0x1, 0x0, 0x3, 0xad, 0xdd, 0xde, 0xff, 0x60, - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - - /* U+9060 "遠" */ - 0x0, 0x30, 0x0, 0x0, 0x8, 0x60, 0x0, 0x0, - 0x0, 0x3b, 0x0, 0x0, 0x8, 0x30, 0x70, 0x0, - 0x0, 0xb, 0x50, 0x76, 0x6b, 0x86, 0x63, 0x0, - 0x0, 0x1, 0x15, 0x66, 0x6b, 0x86, 0x69, 0x80, - 0x0, 0x1, 0x2, 0x20, 0x0, 0x0, 0x40, 0x0, - 0x28, 0x6f, 0x20, 0xc7, 0x66, 0x66, 0xe2, 0x0, - 0x0, 0xd, 0x0, 0xb1, 0x0, 0x0, 0xd0, 0x0, - 0x0, 0xd, 0x0, 0xc6, 0x7e, 0x66, 0xa0, 0x0, - 0x0, 0xd, 0x0, 0x12, 0xcd, 0x0, 0x78, 0x0, - 0x0, 0xd, 0x0, 0x69, 0x2c, 0x5a, 0x50, 0x0, - 0x0, 0xd, 0x25, 0x30, 0xc, 0x1, 0xa9, 0x0, - 0x3, 0xb9, 0x50, 0x0, 0x1d, 0x0, 0x8, 0x20, - 0x3e, 0x20, 0x49, 0x30, 0x6, 0x0, 0x0, 0x10, - 0x1, 0x0, 0x1, 0x7b, 0xcd, 0xee, 0xff, 0x81, - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - - /* U+9069 "適" */ - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x50, 0x0, 0x0, 0xa, 0x20, 0x0, 0x0, - 0x0, 0x79, 0x0, 0x0, 0x5, 0x40, 0x3, 0x0, - 0x0, 0x1e, 0x3, 0x77, 0x66, 0x69, 0x69, 0x50, - 0x0, 0x0, 0x0, 0x3, 0xa0, 0x1b, 0x10, 0x0, - 0x0, 0x3, 0x0, 0x96, 0xb6, 0xa7, 0x6a, 0x10, - 0x27, 0x6f, 0x40, 0xc0, 0x6, 0x70, 0xc, 0x0, - 0x0, 0xd, 0x0, 0xc3, 0x7a, 0x8a, 0x4c, 0x0, - 0x0, 0xd, 0x0, 0xc0, 0x6, 0x41, 0xc, 0x0, - 0x0, 0xd, 0x0, 0xc0, 0xd7, 0x7d, 0xc, 0x0, - 0x0, 0xd, 0x0, 0xc0, 0xc0, 0xc, 0xc, 0x0, - 0x0, 0xd, 0x0, 0xc0, 0xd6, 0x6c, 0xc, 0x0, - 0x3, 0xa9, 0x50, 0xa0, 0x30, 0x5, 0x7c, 0x0, - 0x3e, 0x20, 0x59, 0x30, 0x0, 0x0, 0x54, 0x11, - 0x2, 0x0, 0x1, 0x8c, 0xde, 0xee, 0xff, 0x71, - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x1, 0x0, - - /* U+9078 "選" */ - 0x0, 0x71, 0x0, 0x20, 0x20, 0x30, 0x4, 0x0, - 0x0, 0x3e, 0x10, 0xc6, 0xa3, 0xb6, 0x6d, 0x0, - 0x0, 0xa, 0x20, 0xc6, 0xa1, 0xb6, 0x6b, 0x0, - 0x0, 0x0, 0x0, 0xb0, 0x22, 0xb0, 0x6, 0x30, - 0x0, 0x3, 0x0, 0xb6, 0x69, 0x87, 0x57, 0x80, - 0x27, 0x6f, 0x30, 0x3, 0x91, 0x17, 0x32, 0x0, - 0x0, 0xd, 0x0, 0x0, 0xc0, 0x2d, 0x17, 0x0, - 0x0, 0xd, 0x1, 0x76, 0xd6, 0x7c, 0x66, 0x20, - 0x0, 0xd, 0x0, 0x0, 0xc0, 0x2b, 0x1, 0x30, - 0x0, 0xd, 0x17, 0x66, 0x96, 0x77, 0x66, 0x70, - 0x0, 0xd, 0x0, 0x7, 0xc0, 0x29, 0x70, 0x0, - 0x4, 0xca, 0x61, 0x85, 0x0, 0x0, 0x8a, 0x0, - 0x3f, 0x30, 0x5b, 0x30, 0x0, 0x0, 0x2, 0x0, - 0x2, 0x0, 0x1, 0x8b, 0xcc, 0xdd, 0xde, 0x91, - 0x0, 0x0, 0x0, 0x0, 0x0, 0x1, 0x11, 0x0, - - /* U+907F "避" */ - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x40, 0x0, 0x0, 0x0, 0x8, 0x30, 0x0, - 0x0, 0x79, 0x9, 0x66, 0xc3, 0x2, 0xb0, 0x40, - 0x0, 0xd, 0xa, 0x10, 0xc4, 0x76, 0x67, 0x60, - 0x0, 0x0, 0xa, 0x10, 0xc0, 0x70, 0xd, 0x10, - 0x0, 0x1, 0xa, 0x65, 0xd1, 0x67, 0x46, 0x0, - 0x17, 0x6f, 0x2b, 0x0, 0x24, 0x77, 0x96, 0xc2, - 0x0, 0xd, 0xb, 0x20, 0x22, 0x11, 0xa0, 0x0, - 0x0, 0xd, 0xa, 0xe6, 0xa7, 0x1, 0xa0, 0x0, - 0x0, 0xd, 0x26, 0xd0, 0x77, 0x77, 0xc6, 0xb1, - 0x0, 0xd, 0x60, 0xd0, 0x75, 0x1, 0xa0, 0x0, - 0x0, 0xd, 0x30, 0xe6, 0xa5, 0x1, 0xa0, 0x0, - 0x1, 0x97, 0x50, 0x80, 0x42, 0x2, 0xb0, 0x0, - 0xd, 0x20, 0x4a, 0x41, 0x0, 0x0, 0x20, 0x11, - 0x0, 0x0, 0x0, 0x7b, 0xde, 0xee, 0xff, 0xa1, - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - - /* U+9084 "還" */ - 0x0, 0x92, 0x0, 0x86, 0x66, 0x66, 0x6b, 0x10, - 0x0, 0x3e, 0x10, 0xd0, 0xb0, 0xb, 0xc, 0x0, - 0x0, 0xa, 0x10, 0xd0, 0xb0, 0xb, 0xc, 0x0, - 0x0, 0x0, 0x0, 0xd6, 0x86, 0x68, 0x6a, 0x10, - 0x0, 0x2, 0x6, 0x65, 0x55, 0x55, 0x57, 0xa0, - 0x17, 0x6f, 0x20, 0x56, 0x66, 0x66, 0x85, 0x0, - 0x0, 0xd, 0x0, 0x84, 0x0, 0x0, 0x65, 0x0, - 0x0, 0xd, 0x0, 0x88, 0x87, 0x66, 0x95, 0x0, - 0x0, 0xd, 0x0, 0x25, 0xc1, 0x0, 0x95, 0x0, - 0x0, 0xd, 0x0, 0x5d, 0x55, 0x99, 0x40, 0x0, - 0x0, 0xd, 0x7, 0x65, 0x50, 0x4b, 0xc3, 0x0, - 0x0, 0x9a, 0x50, 0x7, 0xd9, 0x30, 0x5d, 0x0, - 0x1d, 0x40, 0x68, 0x32, 0x40, 0x0, 0x1, 0x0, - 0x16, 0x0, 0x2, 0x8c, 0xdd, 0xee, 0xef, 0x71, - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x1, 0x0, - - /* U+908A "邊" */ - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x20, 0x0, 0x0, 0x7, 0x60, 0x10, 0x0, - 0x0, 0x79, 0x0, 0xd, 0x67, 0x66, 0xd2, 0x0, - 0x0, 0xe, 0x40, 0xd, 0x66, 0x66, 0xd0, 0x0, - 0x0, 0x4, 0x0, 0xd, 0x66, 0x66, 0xd0, 0x0, - 0x0, 0x0, 0x0, 0xd, 0x66, 0x66, 0xd1, 0x0, - 0x13, 0x3a, 0x10, 0x24, 0x5, 0x70, 0x32, 0x0, - 0x14, 0x3e, 0x25, 0x96, 0x86, 0x86, 0x6b, 0x70, - 0x0, 0xd, 0x7, 0x27, 0x86, 0x55, 0x94, 0x0, - 0x0, 0xd, 0x2, 0x75, 0x56, 0x95, 0x7c, 0x30, - 0x0, 0xd, 0x0, 0x0, 0xa8, 0x66, 0x93, 0x0, - 0x0, 0xd, 0x0, 0x6, 0x90, 0x0, 0xc1, 0x0, - 0x4, 0xc9, 0x80, 0x76, 0x0, 0x49, 0xa0, 0x0, - 0x3d, 0x10, 0x5d, 0x62, 0x0, 0x6, 0x11, 0x20, - 0x1, 0x0, 0x1, 0x8c, 0xee, 0xff, 0xff, 0x50, - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - - /* U+90A3 "那" */ - 0x0, 0x0, 0x0, 0x2, 0x2, 0x0, 0x2, 0x0, - 0x37, 0x6b, 0x66, 0xe3, 0xc6, 0x66, 0xf4, 0x0, - 0x0, 0xc1, 0xd, 0xc, 0x0, 0x3a, 0x0, 0x0, - 0xc, 0x10, 0xd0, 0xc0, 0x8, 0x20, 0x1, 0x66, - 0xd6, 0x6e, 0xc, 0x0, 0x80, 0x0, 0x2, 0xc, - 0x0, 0xd0, 0xc0, 0x23, 0x0, 0x0, 0x0, 0xc0, - 0xd, 0xc, 0x0, 0x70, 0x0, 0x0, 0xc, 0x0, - 0xd0, 0xc0, 0x2, 0x80, 0x3, 0x76, 0xd6, 0x6e, - 0xc, 0x0, 0xb, 0x10, 0x0, 0x37, 0x0, 0xd0, - 0xc0, 0x0, 0x94, 0x0, 0x8, 0x20, 0xd, 0xc, - 0x14, 0x4d, 0x40, 0x1, 0x90, 0x0, 0xd0, 0xc0, - 0x3d, 0xa0, 0x0, 0x91, 0x39, 0xcb, 0xc, 0x0, - 0x10, 0x0, 0x62, 0x0, 0x8, 0x10, 0xd1, 0x0, - 0x0, 0x10, 0x0, 0x0, 0x0, 0x5, 0x0, 0x0, - 0x0, - - /* U+90AA "邪" */ - 0x0, 0x0, 0x0, 0x0, 0x20, 0x0, 0x0, 0x10, - 0x1, 0x76, 0x66, 0xa8, 0xa4, 0xb6, 0x6a, 0xd0, - 0x0, 0x10, 0x0, 0xd0, 0x2, 0xa0, 0xb, 0x40, - 0x0, 0x6a, 0x0, 0xd0, 0x2, 0xa0, 0x1a, 0x0, - 0x0, 0xb3, 0x0, 0xd0, 0x2, 0xa0, 0x62, 0x0, - 0x3, 0xe6, 0x66, 0xe7, 0xe5, 0xa0, 0x70, 0x0, - 0x0, 0x20, 0xd, 0xd0, 0x2, 0xa0, 0x61, 0x0, - 0x0, 0x0, 0x68, 0xd0, 0x2, 0xa0, 0x9, 0x0, - 0x0, 0x1, 0xc0, 0xd0, 0x2, 0xa0, 0x5, 0x60, - 0x0, 0x9, 0x30, 0xd0, 0x2, 0xa0, 0x2, 0xc0, - 0x0, 0x65, 0x0, 0xd0, 0x2, 0xa2, 0x27, 0xc0, - 0x5, 0x40, 0x0, 0xd0, 0x2, 0xa1, 0x9f, 0x50, - 0x12, 0x1, 0x66, 0xc0, 0x2, 0xa0, 0x1, 0x0, - 0x0, 0x0, 0x1b, 0x60, 0x3, 0xa0, 0x0, 0x0, - 0x0, 0x0, 0x0, 0x0, 0x1, 0x10, 0x0, 0x0, - - /* U+90E8 "部" */ - 0x0, 0x0, 0x71, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x4c, 0x0, 0x0, 0x95, 0x55, 0x90, - 0x3, 0x66, 0x6b, 0x68, 0xb0, 0xd1, 0x17, 0x90, - 0x0, 0x11, 0x0, 0x25, 0x0, 0xd0, 0xb, 0x10, - 0x0, 0xb, 0x20, 0x79, 0x0, 0xd0, 0x19, 0x0, - 0x0, 0x6, 0x70, 0xa0, 0x0, 0xd0, 0x52, 0x0, - 0x16, 0x66, 0x67, 0x96, 0xb7, 0xd0, 0x60, 0x0, - 0x0, 0x0, 0x0, 0x0, 0x0, 0xd0, 0x18, 0x0, - 0x0, 0x86, 0x66, 0x6c, 0x20, 0xd0, 0x7, 0x40, - 0x0, 0xb2, 0x0, 0xd, 0x0, 0xd0, 0x2, 0xa0, - 0x0, 0xa2, 0x0, 0xd, 0x0, 0xd0, 0x3, 0xc0, - 0x0, 0xa2, 0x0, 0xd, 0x0, 0xd4, 0xae, 0x60, - 0x0, 0xb7, 0x66, 0x6d, 0x0, 0xd0, 0x24, 0x0, - 0x0, 0xa1, 0x0, 0x9, 0x0, 0xd0, 0x0, 0x0, - 0x0, 0x0, 0x0, 0x0, 0x0, 0x50, 0x0, 0x0, - - /* U+90F5 "郵" */ - 0x0, 0x0, 0x37, 0xc1, 0x2, 0x0, 0x2, 0x0, - 0x67, 0x9d, 0x64, 0x10, 0xc6, 0x6b, 0xd0, 0x0, - 0x0, 0xc0, 0x0, 0xc, 0x0, 0xc2, 0x4, 0x78, - 0x6d, 0x68, 0xa5, 0xc0, 0x37, 0x0, 0x0, 0xb0, - 0xc0, 0xc0, 0xc, 0x8, 0x0, 0x0, 0xb, 0xc, - 0xc, 0x0, 0xc0, 0x60, 0x0, 0x27, 0xd6, 0xd6, - 0xd8, 0x4c, 0x5, 0x30, 0x0, 0xb, 0xc, 0xc, - 0x0, 0xc0, 0x8, 0x20, 0x0, 0xb0, 0xc0, 0xc1, - 0xc, 0x0, 0xc, 0x5, 0x69, 0x6d, 0x69, 0x86, - 0xc0, 0x0, 0xa2, 0x0, 0x0, 0xc0, 0x0, 0xc, - 0x0, 0xd, 0x30, 0x0, 0xc, 0x56, 0x50, 0xc3, - 0x8f, 0xc0, 0x2c, 0xda, 0x62, 0x0, 0xc, 0x0, - 0x30, 0x0, 0x40, 0x0, 0x0, 0x0, 0xd0, 0x0, - 0x0, 0x0, 0x0, 0x0, 0x0, 0x2, 0x0, 0x0, - 0x0, - - /* U+90FD "都" */ - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x66, 0x0, 0x0, 0x0, 0x0, 0x10, - 0x0, 0x0, 0x65, 0x2, 0x90, 0xc6, 0x67, 0xe1, - 0x0, 0x76, 0xa9, 0xbb, 0xa0, 0xd0, 0x7, 0x70, - 0x0, 0x0, 0x65, 0x3d, 0x0, 0xd0, 0xb, 0x0, - 0x0, 0x0, 0x66, 0xc2, 0x31, 0xd0, 0x27, 0x0, - 0x7, 0x66, 0x6c, 0x96, 0x75, 0xd0, 0x60, 0x0, - 0x0, 0x0, 0x68, 0x1, 0x0, 0xd0, 0x44, 0x0, - 0x0, 0xb, 0xb6, 0x6d, 0x40, 0xd0, 0xa, 0x10, - 0x2, 0x7d, 0x0, 0xd, 0x0, 0xd0, 0x4, 0xa0, - 0x2, 0xd, 0x66, 0x6e, 0x0, 0xd0, 0x0, 0xe0, - 0x0, 0xd, 0x0, 0xd, 0x0, 0xd2, 0x36, 0xd0, - 0x0, 0xd, 0x0, 0xd, 0x0, 0xd0, 0x6f, 0x50, - 0x0, 0xd, 0x66, 0x6e, 0x10, 0xd0, 0x1, 0x0, - 0x0, 0xd, 0x0, 0x9, 0x0, 0xd0, 0x0, 0x0, - 0x0, 0x3, 0x0, 0x0, 0x0, 0x60, 0x0, 0x0, - - /* U+914D "配" */ - 0x0, 0x0, 0x0, 0x2, 0x0, 0x0, 0x1, 0x0, - 0x7, 0x67, 0x89, 0x69, 0x57, 0x66, 0x6d, 0x30, - 0x0, 0x5, 0x6c, 0x0, 0x0, 0x0, 0xc, 0x10, - 0x2, 0x79, 0xad, 0x6a, 0x10, 0x0, 0xc, 0x10, - 0x3, 0xa5, 0x5c, 0xd, 0x0, 0x0, 0xc, 0x10, - 0x2, 0xa6, 0x4c, 0xd, 0x8, 0x66, 0x6d, 0x10, - 0x2, 0xa9, 0xc, 0xd, 0xd, 0x0, 0x8, 0x0, - 0x2, 0xb7, 0x9, 0xbd, 0xd, 0x0, 0x0, 0x0, - 0x2, 0xc0, 0x0, 0xd, 0xd, 0x0, 0x0, 0x0, - 0x2, 0xc6, 0x66, 0x6d, 0xd, 0x0, 0x0, 0x0, - 0x2, 0xa0, 0x0, 0xd, 0xd, 0x0, 0x0, 0x40, - 0x2, 0xa0, 0x0, 0xd, 0xd, 0x0, 0x0, 0x60, - 0x2, 0xc6, 0x66, 0x6d, 0xc, 0x10, 0x0, 0xc0, - 0x3, 0xa0, 0x0, 0xd, 0x7, 0xcb, 0xbc, 0xc0, - 0x1, 0x30, 0x0, 0x3, 0x0, 0x0, 0x0, 0x0, - - /* U+9152 "酒" */ - 0x0, 0x20, 0x0, 0x0, 0x0, 0x0, 0x0, 0x40, - 0x0, 0x77, 0x7, 0x66, 0x6a, 0x69, 0x67, 0x80, - 0x0, 0xc, 0x1, 0x0, 0x1b, 0x28, 0x0, 0x0, - 0x0, 0x0, 0x5, 0x96, 0x6c, 0x7b, 0x6a, 0x20, - 0x8, 0x20, 0x51, 0xd0, 0x1a, 0x28, 0xd, 0x10, - 0x1, 0xe0, 0x70, 0xd0, 0x39, 0x28, 0xd, 0x0, - 0x0, 0x41, 0x70, 0xd0, 0x74, 0x19, 0xd, 0x0, - 0x0, 0x7, 0x20, 0xd0, 0x90, 0xc, 0x9e, 0x0, - 0x0, 0xb, 0x0, 0xd6, 0x10, 0x0, 0xd, 0x0, - 0x5, 0xba, 0x0, 0xe6, 0x66, 0x66, 0x6e, 0x0, - 0x0, 0x68, 0x0, 0xd0, 0x0, 0x0, 0xd, 0x0, - 0x0, 0x58, 0x0, 0xd0, 0x0, 0x0, 0xd, 0x0, - 0x0, 0x69, 0x0, 0xe6, 0x66, 0x66, 0x6e, 0x0, - 0x0, 0x26, 0x0, 0xd0, 0x0, 0x0, 0xc, 0x0, - 0x0, 0x0, 0x0, 0x20, 0x0, 0x0, 0x0, 0x0, - - /* U+9154 "酔" */ - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x0, 0x2, 0x0, 0xd1, 0x0, 0x0, - 0x27, 0x6a, 0x96, 0x79, 0x0, 0xc0, 0x0, 0x0, - 0x0, 0xb, 0xa0, 0x0, 0x56, 0xe6, 0xc4, 0x0, - 0x3, 0x1b, 0xa0, 0x51, 0x1, 0xb0, 0xa1, 0x0, - 0xb, 0x5c, 0xc6, 0xd3, 0x5, 0x70, 0xb0, 0x10, - 0xb, 0xa, 0xa0, 0xc0, 0xb, 0x0, 0xb0, 0x50, - 0xb, 0x18, 0xa0, 0xc0, 0x83, 0x13, 0xb7, 0xc1, - 0xb, 0x53, 0xa2, 0xc4, 0x20, 0x2b, 0x13, 0x20, - 0xb, 0x60, 0x39, 0xe0, 0x0, 0x28, 0x0, 0x0, - 0xb, 0x0, 0x0, 0xc4, 0x76, 0x7b, 0x69, 0x70, - 0xb, 0x66, 0x66, 0xd0, 0x0, 0x18, 0x0, 0x0, - 0xb, 0x0, 0x0, 0xc0, 0x0, 0x18, 0x0, 0x0, - 0xb, 0x66, 0x66, 0xd0, 0x0, 0x29, 0x0, 0x0, - 0xb, 0x0, 0x0, 0xb0, 0x0, 0x29, 0x0, 0x0, - 0x2, 0x0, 0x0, 0x10, 0x0, 0x11, 0x0, 0x0, - - /* U+9178 "酸" */ - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x0, 0x0, 0x0, 0xa4, 0x0, 0x0, - 0x27, 0x68, 0x86, 0x95, 0x8, 0x70, 0x31, 0x0, - 0x0, 0xb, 0xb0, 0x1, 0x73, 0x1, 0x3c, 0x30, - 0x3, 0xb, 0xb0, 0x55, 0xeb, 0x86, 0x46, 0xa0, - 0xb, 0x7c, 0xc6, 0xd0, 0x16, 0x20, 0x62, 0x10, - 0xa, 0x2a, 0xb0, 0xc0, 0x5a, 0x20, 0x1c, 0x80, - 0xa, 0x38, 0xb0, 0xc4, 0x54, 0xa0, 0x0, 0xd0, - 0xa, 0x64, 0x99, 0xc1, 0xb, 0x96, 0x69, 0x10, - 0xa, 0x70, 0x1, 0xc0, 0x49, 0x0, 0x87, 0x0, - 0xa, 0x10, 0x0, 0xc1, 0x87, 0x1, 0xc0, 0x0, - 0xa, 0x66, 0x66, 0xc5, 0x3, 0x6a, 0x40, 0x0, - 0xa, 0x10, 0x0, 0xc0, 0x0, 0xba, 0x0, 0x0, - 0xa, 0x66, 0x66, 0xc0, 0x6, 0x9b, 0x50, 0x0, - 0xb, 0x10, 0x0, 0xb1, 0x84, 0x0, 0xbd, 0x80, - 0x4, 0x0, 0x0, 0x34, 0x0, 0x0, 0x6, 0x20, - - /* U+91AB "醫" */ - 0x0, 0x96, 0x66, 0x8a, 0x8, 0x66, 0xb0, 0x0, - 0x0, 0xc1, 0xa0, 0x10, 0xc, 0x0, 0xb0, 0x0, - 0x0, 0xc7, 0x7a, 0x74, 0x37, 0x0, 0xa8, 0x30, - 0x0, 0xc6, 0x6c, 0x79, 0x56, 0x66, 0x92, 0x0, - 0x0, 0xc0, 0x68, 0x40, 0x5, 0x12, 0xb1, 0x0, - 0x0, 0xc2, 0x60, 0x81, 0x1, 0x9e, 0x70, 0x0, - 0x2, 0xd8, 0x66, 0x6a, 0x57, 0x70, 0x79, 0x0, - 0x5, 0x66, 0x66, 0x66, 0x96, 0x66, 0x66, 0xc1, - 0x1, 0x1, 0x0, 0xd0, 0xc, 0x0, 0x30, 0x0, - 0x0, 0xd, 0x66, 0xe6, 0x6d, 0x66, 0xd3, 0x0, - 0x0, 0xb, 0x6, 0x60, 0xc, 0x33, 0xb0, 0x0, - 0x0, 0xb, 0x33, 0x0, 0x3, 0x55, 0xc0, 0x0, - 0x0, 0xd, 0x66, 0x66, 0x66, 0x66, 0xc0, 0x0, - 0x0, 0xd, 0x66, 0x66, 0x66, 0x66, 0xd0, 0x0, - 0x0, 0x8, 0x0, 0x0, 0x0, 0x0, 0x60, 0x0, - - /* U+91CD "重" */ - 0x0, 0x0, 0x0, 0x0, 0x14, 0x8c, 0x10, 0x0, - 0x2, 0x45, 0x67, 0xe7, 0x54, 0x31, 0x0, 0x0, - 0x0, 0x0, 0xd, 0x0, 0x0, 0x35, 0x0, 0x57, - 0x66, 0x66, 0xe6, 0x66, 0x67, 0x70, 0x0, 0x3, - 0x0, 0xd, 0x0, 0x5, 0x0, 0x0, 0x0, 0xb8, - 0x66, 0xe6, 0x66, 0xe2, 0x0, 0x0, 0xa, 0x30, - 0xd, 0x0, 0xd, 0x0, 0x0, 0x0, 0xa8, 0x66, - 0xe6, 0x66, 0xe0, 0x0, 0x0, 0xa, 0x30, 0xd, - 0x0, 0xd, 0x0, 0x0, 0x0, 0xa7, 0x66, 0xe6, - 0x66, 0xc0, 0x0, 0x0, 0x0, 0x0, 0xd, 0x0, - 0x2, 0x60, 0x0, 0x6, 0x76, 0x66, 0xe6, 0x66, - 0x66, 0x10, 0x0, 0x0, 0x0, 0xd, 0x0, 0x0, - 0x5, 0x13, 0x76, 0x66, 0x66, 0xa6, 0x66, 0x66, - 0xa7, - - /* U+91CE "野" */ - 0x1, 0x20, 0x0, 0x4, 0x0, 0x0, 0x4, 0x0, - 0x1, 0xd6, 0xc7, 0x6e, 0x37, 0x66, 0x7e, 0x60, - 0x1, 0xb0, 0xa2, 0xd, 0x1, 0x40, 0x81, 0x0, - 0x1, 0xd6, 0xc7, 0x6e, 0x0, 0x5e, 0x20, 0x0, - 0x1, 0xb0, 0xa2, 0xd, 0x0, 0x9, 0x60, 0x10, - 0x1, 0xb0, 0xa2, 0xd, 0x57, 0x69, 0x68, 0xe1, - 0x1, 0xd6, 0xc7, 0x6e, 0x0, 0xd, 0x8, 0x30, - 0x1, 0x70, 0xa2, 0x7, 0x0, 0xd, 0x3, 0x0, - 0x0, 0x0, 0xa2, 0x2, 0x0, 0xd, 0x0, 0x0, - 0x3, 0x76, 0xc7, 0x6c, 0x50, 0xd, 0x0, 0x0, - 0x0, 0x0, 0xa2, 0x0, 0x0, 0xd, 0x0, 0x0, - 0x0, 0x0, 0xa2, 0x24, 0x40, 0xd, 0x0, 0x0, - 0x6, 0x8a, 0xb8, 0x40, 0x0, 0xd, 0x0, 0x0, - 0xa, 0x51, 0x0, 0x0, 0x6, 0xde, 0x0, 0x0, - 0x0, 0x0, 0x0, 0x0, 0x0, 0x22, 0x0, 0x0, - - /* U+91CF "量" */ - 0x0, 0x6, 0x66, 0x66, 0x66, 0x6b, 0x10, 0x0, - 0x0, 0x9, 0x30, 0x0, 0x0, 0xd, 0x0, 0x0, - 0x0, 0x9, 0x86, 0x66, 0x66, 0x6e, 0x0, 0x0, - 0x0, 0x9, 0x86, 0x66, 0x66, 0x6e, 0x0, 0x0, - 0x0, 0x7, 0x10, 0x0, 0x0, 0x5, 0x2, 0x30, - 0x27, 0x66, 0x66, 0x66, 0x66, 0x66, 0x68, 0x70, - 0x0, 0x8, 0x66, 0x66, 0x66, 0x69, 0x30, 0x0, - 0x0, 0xc, 0x0, 0xd, 0x0, 0xa, 0x20, 0x0, - 0x0, 0xc, 0x66, 0x6e, 0x66, 0x6c, 0x20, 0x0, - 0x0, 0xc, 0x0, 0xd, 0x0, 0xa, 0x20, 0x0, - 0x0, 0xb, 0x66, 0x6e, 0x66, 0x69, 0x10, 0x0, - 0x0, 0x46, 0x66, 0x6e, 0x66, 0x67, 0xc1, 0x0, - 0x0, 0x11, 0x0, 0xd, 0x0, 0x0, 0x1, 0x0, - 0x5, 0x66, 0x66, 0x6e, 0x66, 0x66, 0x6d, 0x90, - 0x2, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - - /* U+91D1 "金" */ - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x0, 0x3d, 0x10, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x0, 0xba, 0x30, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x4, 0xd0, 0x82, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x1d, 0x30, 0xb, 0x30, 0x0, 0x0, - 0x0, 0x0, 0xb3, 0x0, 0x1, 0xc7, 0x0, 0x0, - 0x0, 0x1a, 0x30, 0x0, 0x0, 0x3a, 0xe9, 0x50, - 0x5, 0x70, 0x67, 0x6b, 0x66, 0x93, 0x4b, 0x50, - 0x11, 0x0, 0x0, 0xe, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x0, 0xe, 0x0, 0x0, 0x70, 0x0, - 0x0, 0x57, 0x66, 0x6e, 0x66, 0x66, 0x61, 0x0, - 0x0, 0x3, 0x70, 0xe, 0x0, 0x79, 0x0, 0x0, - 0x0, 0x0, 0x9a, 0xe, 0x0, 0xd2, 0x0, 0x0, - 0x0, 0x0, 0x1e, 0xe, 0x5, 0x50, 0x0, 0x0, - 0x16, 0x66, 0x67, 0x6e, 0x6a, 0x66, 0x6c, 0x80, - 0x2, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - - /* U+91DD "針" */ - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, 0xb3, 0x0, 0x0, 0x1d, 0x20, 0x0, - 0x0, 0x4, 0xe3, 0x0, 0x0, 0xd, 0x0, 0x0, - 0x0, 0xb, 0x37, 0xb1, 0x0, 0xd, 0x0, 0x0, - 0x0, 0x49, 0x0, 0x86, 0x0, 0xd, 0x0, 0x0, - 0x0, 0xa0, 0x1, 0x10, 0x0, 0xd, 0x0, 0x0, - 0x7, 0x36, 0xa7, 0x60, 0x0, 0xd, 0x0, 0x80, - 0x1, 0x0, 0xd0, 0x2, 0x86, 0x6e, 0x66, 0x62, - 0x0, 0x0, 0xd0, 0x70, 0x0, 0xd, 0x0, 0x0, - 0x1, 0x86, 0xe6, 0x62, 0x0, 0xd, 0x0, 0x0, - 0x0, 0x60, 0xd0, 0xb3, 0x0, 0xd, 0x0, 0x0, - 0x0, 0x94, 0xd1, 0xb0, 0x0, 0xd, 0x0, 0x0, - 0x0, 0x65, 0xd5, 0x11, 0x0, 0xd, 0x0, 0x0, - 0x0, 0x25, 0xe8, 0x62, 0x0, 0xe, 0x0, 0x0, - 0x4, 0xd6, 0x10, 0x0, 0x0, 0xe, 0x0, 0x0, - 0x0, 0x0, 0x0, 0x0, 0x0, 0x8, 0x0, 0x0, - - /* U+9244 "鉄" */ - 0x0, 0x1, 0xb2, 0x0, 0x0, 0x74, 0x0, 0x0, - 0x0, 0x6, 0xd2, 0x0, 0x41, 0x94, 0x0, 0x0, - 0x0, 0xd, 0x28, 0xa0, 0xe4, 0x93, 0x0, 0x0, - 0x0, 0x67, 0x0, 0xa6, 0xc0, 0x93, 0x7, 0x0, - 0x1, 0x90, 0x4, 0x26, 0x96, 0xb8, 0x67, 0x20, - 0x7, 0x37, 0xe6, 0x3a, 0x0, 0xa2, 0x0, 0x0, - 0x0, 0x0, 0xd0, 0x13, 0x0, 0xb1, 0x0, 0x10, - 0x2, 0x66, 0xe6, 0xa6, 0x75, 0xd7, 0x57, 0xb1, - 0x0, 0x20, 0xd0, 0x30, 0x0, 0xc6, 0x0, 0x0, - 0x0, 0x90, 0xd1, 0xe1, 0x5, 0x88, 0x0, 0x0, - 0x0, 0xa3, 0xd6, 0x40, 0xc, 0x14, 0x80, 0x0, - 0x0, 0x51, 0xd5, 0x52, 0x67, 0x0, 0xb5, 0x0, - 0x4, 0x9b, 0xa5, 0x13, 0x80, 0x0, 0x2e, 0x80, - 0x4, 0x60, 0x0, 0x45, 0x0, 0x0, 0x3, 0xa2, - 0x0, 0x0, 0x0, 0x10, 0x0, 0x0, 0x0, 0x0, - - /* U+925B "鉛" */ - 0x0, 0x1, 0xc2, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x7, 0xd2, 0x0, 0x58, 0x66, 0xa4, 0x0, - 0x0, 0xd, 0x18, 0xb0, 0x59, 0x0, 0xb1, 0x0, - 0x0, 0x66, 0x0, 0x94, 0x58, 0x0, 0xb1, 0x0, - 0x1, 0xa1, 0x15, 0x10, 0x66, 0x0, 0xb1, 0x0, - 0x7, 0x26, 0xd5, 0x20, 0xa1, 0x0, 0xb2, 0x0, - 0x0, 0x0, 0xd0, 0x3, 0x70, 0x0, 0x5b, 0xb0, - 0x2, 0x55, 0xd6, 0xc5, 0x10, 0x0, 0x1, 0x0, - 0x0, 0x21, 0xd1, 0x30, 0xd6, 0x66, 0x8d, 0x0, - 0x0, 0x80, 0xd1, 0xe1, 0xd0, 0x0, 0x2a, 0x0, - 0x0, 0xa3, 0xd6, 0x40, 0xd0, 0x0, 0x2a, 0x0, - 0x0, 0x61, 0xd4, 0x42, 0xd0, 0x0, 0x2a, 0x0, - 0x3, 0x8a, 0xb6, 0x10, 0xd6, 0x66, 0x7a, 0x0, - 0x4, 0x70, 0x0, 0x0, 0xd0, 0x0, 0x27, 0x0, - 0x0, 0x0, 0x0, 0x0, 0x10, 0x0, 0x0, 0x0, - - /* U+9280 "銀" */ - 0x0, 0x9, 0x40, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x3f, 0x30, 0x9, 0x66, 0x66, 0xa3, 0x0, - 0x0, 0xa5, 0x6b, 0x1c, 0x10, 0x0, 0xd1, 0x0, - 0x2, 0xa0, 0x8, 0x7c, 0x10, 0x0, 0xd0, 0x0, - 0xa, 0x10, 0x22, 0xc, 0x66, 0x66, 0xe0, 0x0, - 0x42, 0x7d, 0x64, 0xc, 0x10, 0x0, 0xd0, 0x0, - 0x0, 0xc, 0x0, 0xc, 0x43, 0x33, 0xd0, 0x0, - 0x5, 0x6d, 0x6c, 0x2c, 0x27, 0x11, 0x65, 0x0, - 0x2, 0xc, 0x3, 0xc, 0x16, 0x10, 0x7a, 0x10, - 0x8, 0xc, 0xd, 0x3c, 0x11, 0x96, 0x40, 0x0, - 0x7, 0x7c, 0x36, 0xc, 0x10, 0x86, 0x0, 0x0, - 0x3, 0x3c, 0x45, 0x3c, 0x13, 0x2b, 0x91, 0x0, - 0x28, 0xba, 0x61, 0xd, 0xa3, 0x0, 0x8f, 0x70, - 0x18, 0x0, 0x0, 0x8, 0x10, 0x0, 0x0, 0x0, - - /* U+9322 "錢" */ - 0x0, 0x1, 0x0, 0x0, 0x30, 0x0, 0x0, 0x0, - 0x0, 0xe, 0x50, 0x0, 0xb6, 0xb, 0x40, 0x0, - 0x0, 0x5c, 0x72, 0x0, 0x69, 0x25, 0x9b, 0x10, - 0x0, 0xb2, 0x1d, 0x46, 0x6e, 0x31, 0x40, 0x0, - 0x5, 0x60, 0x3, 0x30, 0xb, 0x4a, 0xb1, 0x0, - 0x18, 0x56, 0x7a, 0x0, 0x6, 0xf7, 0x0, 0x20, - 0x20, 0x1a, 0x20, 0x3, 0x88, 0x7d, 0x40, 0x70, - 0x0, 0xa, 0x21, 0x53, 0x72, 0x66, 0xce, 0xc0, - 0x6, 0x6c, 0x7d, 0x30, 0x95, 0x2c, 0x4, 0x30, - 0x1, 0xa, 0x23, 0x0, 0x59, 0x36, 0x6b, 0x30, - 0x7, 0x1a, 0x2b, 0x78, 0x7e, 0x20, 0x10, 0x0, - 0x4, 0x9a, 0x3a, 0x0, 0xc, 0x25, 0xd0, 0x0, - 0x1, 0x4a, 0x53, 0x40, 0x5, 0xbd, 0x10, 0x0, - 0x4, 0x7d, 0x95, 0x0, 0x3, 0xf7, 0x0, 0x50, - 0xd, 0x60, 0x0, 0x1, 0x77, 0x2d, 0x93, 0x80, - 0x0, 0x0, 0x0, 0x34, 0x10, 0x0, 0x7c, 0xd0, - - /* U+932F "錯" */ - 0x0, 0xb, 0x40, 0x0, 0x85, 0xa, 0x30, 0x0, - 0x0, 0x4e, 0x40, 0x0, 0x95, 0xc, 0x20, 0x0, - 0x0, 0xb3, 0x5c, 0x36, 0xb9, 0x6d, 0x9b, 0x0, - 0x5, 0x70, 0x7, 0x50, 0x95, 0xc, 0x20, 0x0, - 0x19, 0x33, 0x55, 0x0, 0x95, 0xc, 0x20, 0x0, - 0x30, 0x4c, 0x32, 0x56, 0xb9, 0x6d, 0x7b, 0x80, - 0x0, 0xb, 0x10, 0x10, 0x0, 0x0, 0x0, 0x0, - 0x3, 0x3c, 0x5c, 0x4, 0x0, 0x0, 0x43, 0x0, - 0x4, 0x3c, 0x44, 0xb, 0x76, 0x66, 0xb8, 0x0, - 0x7, 0xb, 0x1c, 0x4b, 0x30, 0x0, 0x95, 0x0, - 0x6, 0x7b, 0x38, 0xb, 0x76, 0x66, 0xb5, 0x0, - 0x3, 0x5b, 0x54, 0x3b, 0x30, 0x0, 0x95, 0x0, - 0x17, 0xab, 0x72, 0xb, 0x76, 0x66, 0xb5, 0x0, - 0xa, 0x10, 0x0, 0xb, 0x20, 0x0, 0x62, 0x0, - 0x0, 0x0, 0x0, 0x2, 0x0, 0x0, 0x0, 0x0, - - /* U+9332 "録" */ - 0x0, 0x9, 0x20, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x5e, 0x20, 0x5, 0x76, 0x66, 0xc5, 0x0, - 0x0, 0xb3, 0x89, 0x0, 0x0, 0x0, 0xd0, 0x0, - 0x4, 0x80, 0xa, 0x40, 0x66, 0x66, 0xe0, 0x0, - 0xa, 0x22, 0x45, 0x0, 0x0, 0x0, 0xd0, 0x0, - 0x41, 0x5d, 0x32, 0x36, 0x66, 0x66, 0xe9, 0x90, - 0x0, 0xd, 0x0, 0x1, 0x0, 0xd0, 0x1, 0x0, - 0x16, 0x6e, 0x6d, 0x17, 0x40, 0xe0, 0x2e, 0x20, - 0x2, 0xd, 0x3, 0x0, 0xe0, 0xd6, 0x81, 0x0, - 0x8, 0xd, 0xd, 0x40, 0x21, 0xd7, 0x0, 0x0, - 0x7, 0x6d, 0x37, 0x0, 0x63, 0xd2, 0xa0, 0x0, - 0x3, 0x3d, 0x45, 0x4a, 0x20, 0xd0, 0x7b, 0x10, - 0x28, 0xba, 0x61, 0x94, 0x0, 0xd0, 0xa, 0x60, - 0x17, 0x0, 0x0, 0x0, 0x6e, 0xa0, 0x0, 0x0, - 0x0, 0x0, 0x0, 0x0, 0x2, 0x0, 0x0, 0x0, - - /* U+9577 "長" */ - 0x0, 0x0, 0x30, 0x0, 0x0, 0x0, 0x50, 0x0, - 0x0, 0x0, 0xb8, 0x66, 0x66, 0x66, 0x71, 0x0, - 0x0, 0x0, 0xb3, 0x0, 0x0, 0x2, 0x0, 0x0, - 0x0, 0x0, 0xb8, 0x66, 0x66, 0x6a, 0x30, 0x0, - 0x0, 0x0, 0xb3, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, 0xb8, 0x66, 0x66, 0x6c, 0x50, 0x0, - 0x0, 0x0, 0xb3, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, 0xb3, 0x0, 0x0, 0x0, 0x3, 0x70, - 0x6, 0x76, 0xe6, 0x6a, 0x66, 0x66, 0x66, 0x50, - 0x0, 0x1, 0xd0, 0x2, 0x60, 0x8, 0xb0, 0x0, - 0x0, 0x1, 0xd0, 0x0, 0x75, 0x85, 0x10, 0x0, - 0x0, 0x1, 0xd0, 0x3, 0xa, 0x60, 0x0, 0x0, - 0x0, 0x1, 0xd4, 0x82, 0x0, 0x8c, 0x51, 0x0, - 0x0, 0x3, 0xf9, 0x0, 0x0, 0x3, 0xbf, 0xa1, - 0x0, 0x0, 0x30, 0x0, 0x0, 0x0, 0x2, 0x0, - - /* U+9589 "閉" */ - 0x50, 0x0, 0x70, 0x4, 0x0, 0x7, 0xe, 0x66, - 0x6e, 0x10, 0xe6, 0x66, 0xf2, 0xe0, 0x0, 0xd0, - 0xd, 0x0, 0xe, 0xe, 0x66, 0x6d, 0x0, 0xd6, - 0x66, 0xe0, 0xe6, 0x66, 0xd0, 0xe, 0x66, 0x6e, - 0xe, 0x0, 0x4, 0x1, 0x60, 0x0, 0xe0, 0xe0, - 0x0, 0x0, 0xd1, 0x0, 0xe, 0xe, 0x5, 0x66, - 0x6e, 0x67, 0xa0, 0xe0, 0xe0, 0x10, 0x1c, 0xe0, - 0x0, 0xe, 0xe, 0x0, 0xb, 0x3d, 0x0, 0x0, - 0xe0, 0xe0, 0x19, 0x20, 0xd0, 0x0, 0xe, 0xe, - 0x26, 0x0, 0xd, 0x0, 0x0, 0xe0, 0xe0, 0x0, - 0x3b, 0xd0, 0x0, 0xd, 0xe, 0x0, 0x0, 0x11, - 0x1, 0x8e, 0xa0, 0x40, 0x0, 0x0, 0x0, 0x0, - 0x40, 0x0, - - /* U+958B "開" */ - 0x40, 0x0, 0x60, 0x4, 0x0, 0x6, 0xf, 0x66, - 0x6e, 0x10, 0xe6, 0x66, 0xf1, 0xe6, 0x66, 0xd0, - 0xe, 0x66, 0x6e, 0xe, 0x0, 0xd, 0x0, 0xe0, - 0x0, 0xe0, 0xe6, 0x66, 0xd0, 0xe, 0x66, 0x6e, - 0xe, 0x0, 0x3, 0x0, 0x60, 0x0, 0xe0, 0xe0, - 0x16, 0x66, 0x66, 0xb2, 0xe, 0xe, 0x0, 0x2c, - 0x2, 0xa0, 0x0, 0xe0, 0xe0, 0x0, 0xc0, 0x2a, - 0x2, 0xe, 0xe, 0x7, 0x6d, 0x67, 0xc7, 0xa0, - 0xe0, 0xe0, 0x0, 0xc0, 0x2a, 0x0, 0xe, 0xe, - 0x0, 0x57, 0x2, 0xa0, 0x0, 0xe0, 0xe0, 0x49, - 0x0, 0x2a, 0x0, 0xd, 0xe, 0x13, 0x0, 0x1, - 0x11, 0x7d, 0xb0, 0x30, 0x0, 0x0, 0x0, 0x0, - 0x41, 0x0, - - /* U+9593 "間" */ - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xa, 0x66, - 0x6b, 0x0, 0x96, 0x66, 0xc1, 0xe0, 0x1, 0xc0, - 0xd, 0x0, 0xe, 0xe, 0x66, 0x6c, 0x0, 0xd6, - 0x66, 0xe0, 0xe0, 0x1, 0xc0, 0xd, 0x0, 0xe, - 0xe, 0x66, 0x6c, 0x0, 0xd6, 0x66, 0xe0, 0xe0, - 0x0, 0x10, 0x4, 0x0, 0xe, 0xe, 0x0, 0x96, - 0x66, 0x97, 0x0, 0xe0, 0xe0, 0xd, 0x10, 0x8, - 0x50, 0xe, 0xe, 0x0, 0xd1, 0x0, 0x85, 0x0, - 0xe0, 0xe0, 0xd, 0x66, 0x6b, 0x50, 0xe, 0xe, - 0x0, 0xd1, 0x0, 0x85, 0x0, 0xe0, 0xe0, 0xd, - 0x66, 0x6b, 0x50, 0xe, 0xe, 0x0, 0x80, 0x0, - 0x42, 0x0, 0xd0, 0xe0, 0x0, 0x0, 0x0, 0x18, - 0xdb, 0x5, 0x0, 0x0, 0x0, 0x0, 0x5, 0x10, - - /* U+95A2 "関" */ - 0xa6, 0x66, 0xb1, 0xa, 0x66, 0x6c, 0x1e, 0x0, - 0xd, 0x0, 0xd0, 0x0, 0xe0, 0xe6, 0x66, 0xd0, - 0xd, 0x66, 0x6e, 0xe, 0x0, 0xd, 0x0, 0xd0, - 0x0, 0xe0, 0xe6, 0x66, 0xd0, 0xe, 0x66, 0x6e, - 0xe, 0x0, 0x34, 0x0, 0x70, 0x0, 0xe0, 0xe0, - 0x0, 0xc1, 0x1b, 0x0, 0xe, 0xe, 0x2, 0x68, - 0x69, 0x69, 0x40, 0xe0, 0xe0, 0x2, 0x7, 0x60, - 0x0, 0xe, 0xe, 0x6, 0x76, 0xb8, 0x66, 0xa0, - 0xe0, 0xe0, 0x0, 0x1d, 0x73, 0x0, 0xe, 0xe, - 0x0, 0x1b, 0x20, 0x7d, 0x10, 0xe0, 0xe0, 0x58, - 0x10, 0x0, 0x31, 0xe, 0xe, 0x0, 0x0, 0x0, - 0x1, 0x7b, 0xd0, 0x60, 0x0, 0x0, 0x0, 0x0, - 0x52, 0x0, - - /* U+95DC "關" */ - 0x96, 0x66, 0xa1, 0x8, 0x66, 0x6b, 0x3d, 0x0, - 0xb, 0x0, 0xd0, 0x0, 0xd0, 0xe6, 0x66, 0xc0, - 0xd, 0x66, 0x6e, 0xd, 0x66, 0x6c, 0x0, 0xd6, - 0x66, 0xe0, 0xd0, 0x1, 0x70, 0x6, 0x70, 0xd, - 0xd, 0x0, 0x73, 0x11, 0x92, 0x30, 0xd0, 0xd0, - 0xa9, 0xb6, 0x97, 0xa9, 0xd, 0xd, 0x2, 0x63, - 0x42, 0x72, 0x50, 0xd0, 0xd0, 0x98, 0x69, 0x69, - 0x59, 0xd, 0xd, 0x9, 0x15, 0x65, 0x70, 0x60, - 0xd0, 0xd0, 0xc6, 0x86, 0x4a, 0x6d, 0xd, 0xd, - 0x2, 0x6, 0x44, 0x70, 0x50, 0xd0, 0xd0, 0x3, - 0x80, 0x57, 0x0, 0xd, 0xd, 0x1, 0x30, 0x1, - 0x10, 0x6c, 0xc0, 0x30, 0x0, 0x0, 0x0, 0x0, - 0x21, 0x0, - - /* U+95F0 "闰" */ - 0x0, 0x83, 0x0, 0x0, 0x0, 0x0, 0x10, 0x0, - 0x2f, 0x2, 0x86, 0x66, 0x66, 0xe2, 0xa, 0x16, - 0x0, 0x0, 0x0, 0x0, 0xe0, 0xe, 0x0, 0x0, - 0x0, 0x1, 0x50, 0xe0, 0xd, 0x6, 0x76, 0x7c, - 0x66, 0x60, 0xe0, 0xd, 0x0, 0x0, 0x2b, 0x0, - 0x0, 0xe0, 0xd, 0x0, 0x0, 0x2b, 0x3, 0x0, - 0xe0, 0xd, 0x0, 0x76, 0x7d, 0x68, 0x40, 0xe0, - 0xd, 0x0, 0x0, 0x2b, 0x0, 0x0, 0xe0, 0xd, - 0x0, 0x0, 0x2b, 0x0, 0x0, 0xe0, 0xd, 0x26, - 0x66, 0x7d, 0x66, 0xe3, 0xe0, 0xd, 0x2, 0x0, - 0x0, 0x0, 0x0, 0xe0, 0xd, 0x0, 0x0, 0x0, - 0x0, 0x22, 0xe0, 0xd, 0x0, 0x0, 0x0, 0x0, - 0x5d, 0xc0, 0x1, 0x0, 0x0, 0x0, 0x0, 0x1, - 0x0, - - /* U+9633 "阳" */ - 0x40, 0x1, 0x40, 0x0, 0x0, 0x0, 0xe, 0x66, - 0xad, 0x19, 0x66, 0x66, 0xb2, 0xd0, 0xb, 0x20, - 0xc0, 0x0, 0xd, 0xd, 0x1, 0x90, 0xc, 0x0, - 0x0, 0xd0, 0xd0, 0x51, 0x0, 0xc0, 0x0, 0xd, - 0xd, 0x5, 0x10, 0xc, 0x0, 0x0, 0xd0, 0xd0, - 0x8, 0x10, 0xd6, 0x66, 0x6d, 0xd, 0x0, 0x18, - 0xc, 0x0, 0x0, 0xd0, 0xd0, 0x0, 0xb0, 0xc0, - 0x0, 0xd, 0xd, 0x24, 0x98, 0xc, 0x0, 0x0, - 0xd0, 0xd0, 0x8a, 0x0, 0xc0, 0x0, 0xd, 0xd, - 0x0, 0x0, 0xd, 0x66, 0x66, 0xd0, 0xd0, 0x0, - 0x0, 0xc0, 0x0, 0xd, 0xd, 0x0, 0x0, 0x6, - 0x0, 0x0, 0x60, 0x10, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, - - /* U+9644 "附" */ - 0x20, 0x3, 0x0, 0x73, 0x0, 0x82, 0x0, 0xe6, - 0x6e, 0x10, 0xd1, 0x0, 0xd0, 0x0, 0xd0, 0x56, - 0x4, 0x80, 0x0, 0xc0, 0x0, 0xd0, 0x90, 0xa, - 0x10, 0x0, 0xc0, 0x0, 0xd0, 0x80, 0x2f, 0x25, - 0x66, 0xd7, 0xa0, 0xd0, 0x50, 0x7c, 0x1, 0x0, - 0xc0, 0x0, 0xd0, 0x55, 0x2c, 0x2, 0x0, 0xc0, - 0x0, 0xd0, 0xa, 0xc, 0x3, 0xb1, 0xc0, 0x0, - 0xd0, 0xd, 0xc, 0x0, 0x85, 0xc0, 0x0, 0xd3, - 0x4c, 0xc, 0x0, 0x0, 0xc0, 0x0, 0xd4, 0xd3, - 0xc, 0x0, 0x0, 0xc0, 0x0, 0xd0, 0x0, 0xc, - 0x0, 0x0, 0xc0, 0x0, 0xd0, 0x0, 0xc, 0x0, - 0x21, 0xd0, 0x0, 0xd0, 0x0, 0xb, 0x0, 0x2c, - 0xc0, 0x0, 0x40, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, - - /* U+964D "降" */ - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x30, - 0x4, 0x0, 0x68, 0x0, 0x0, 0x0, 0xe6, 0x6f, - 0x30, 0xb7, 0x66, 0xaa, 0x0, 0xd0, 0x39, 0x2, - 0xc1, 0x2, 0xd1, 0x0, 0xd0, 0x72, 0x8, 0x18, - 0x1c, 0x20, 0x0, 0xd0, 0x60, 0x32, 0x3, 0xe3, - 0x0, 0x0, 0xd0, 0x60, 0x0, 0x2a, 0x6b, 0x61, - 0x0, 0xd0, 0x18, 0x5, 0x80, 0x83, 0x7d, 0xa1, - 0xd0, 0xa, 0x51, 0x0, 0xc1, 0x6, 0x0, 0xd0, - 0x8, 0x67, 0x66, 0xd6, 0x66, 0x10, 0xd5, 0x3d, - 0x3c, 0x20, 0xc0, 0x0, 0x0, 0xd2, 0xe7, 0x3a, - 0x0, 0xc0, 0x1, 0x60, 0xd0, 0x0, 0x57, 0x66, - 0xd6, 0x66, 0x50, 0xd0, 0x0, 0x0, 0x0, 0xc0, - 0x0, 0x0, 0xe0, 0x0, 0x0, 0x0, 0xc0, 0x0, - 0x0, 0x70, 0x0, 0x0, 0x0, 0x70, 0x0, 0x0, - - /* U+9650 "限" */ - 0x2, 0x0, 0x30, 0x20, 0x0, 0x3, 0x10, 0x0, - 0xe6, 0x7d, 0xd, 0x66, 0x66, 0xc6, 0x0, 0xd, - 0x6, 0x60, 0xd0, 0x0, 0xb, 0x30, 0x0, 0xd0, - 0x90, 0xd, 0x0, 0x0, 0xb3, 0x0, 0xd, 0x7, - 0x0, 0xd6, 0x66, 0x6c, 0x30, 0x0, 0xd0, 0x50, - 0xd, 0x0, 0x0, 0xb3, 0x0, 0xd, 0x6, 0x20, - 0xd6, 0x66, 0x6c, 0x30, 0x0, 0xd0, 0xa, 0xd, - 0x6, 0x0, 0x45, 0x0, 0xd, 0x0, 0xc0, 0xd0, - 0x61, 0x8, 0xd2, 0x0, 0xd2, 0x2e, 0xd, 0x2, - 0x88, 0x50, 0x0, 0xd, 0x4f, 0x90, 0xd0, 0xa, - 0x40, 0x0, 0x0, 0xd0, 0x20, 0xd, 0x1, 0x3d, - 0x30, 0x0, 0xd, 0x0, 0x0, 0xd8, 0x60, 0x2e, - 0xa4, 0x0, 0xe0, 0x0, 0xd, 0x50, 0x0, 0x2c, - 0x60, 0x5, 0x0, 0x0, 0x10, 0x0, 0x0, 0x0, - 0x0, - - /* U+9662 "院" */ - 0x0, 0x0, 0x0, 0x0, 0x34, 0x0, 0x0, 0x1, - 0xc6, 0x6e, 0x0, 0x0, 0xd0, 0x0, 0x0, 0xb, - 0x3, 0x72, 0x96, 0x6a, 0x66, 0xa6, 0x0, 0xb0, - 0x70, 0x86, 0x0, 0x0, 0x8, 0x0, 0xb, 0x5, - 0x4, 0x0, 0x0, 0x6, 0x0, 0x0, 0xb0, 0x30, - 0x2, 0x86, 0x66, 0x50, 0x0, 0xb, 0x5, 0x30, - 0x0, 0x0, 0x0, 0x10, 0x0, 0xb0, 0xb, 0x38, - 0x67, 0x68, 0x6b, 0x30, 0xb, 0x0, 0xb2, 0x3, - 0x91, 0xb0, 0x0, 0x0, 0xb2, 0x3d, 0x20, 0x57, - 0x1b, 0x0, 0x0, 0xb, 0x1c, 0x80, 0x9, 0x41, - 0xb0, 0x2, 0x0, 0xb0, 0x0, 0x0, 0xd0, 0x1b, - 0x0, 0x60, 0xb, 0x0, 0x0, 0xa4, 0x1, 0xb0, - 0xb, 0x1, 0xb0, 0x2, 0x82, 0x0, 0xc, 0xbc, - 0xc1, 0x15, 0x1, 0x20, 0x0, 0x0, 0x0, 0x0, - 0x0, - - /* U+9664 "除" */ - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x10, - 0x1, 0x10, 0x2, 0xd1, 0x0, 0x0, 0xa7, 0x6c, - 0x80, 0xa, 0x94, 0x0, 0x0, 0x92, 0xd, 0x0, - 0x3c, 0x8, 0x20, 0x0, 0x92, 0x55, 0x0, 0xb2, - 0x0, 0xc3, 0x0, 0x92, 0x70, 0x8, 0x40, 0x0, - 0x2d, 0xa3, 0x92, 0x60, 0x63, 0x76, 0x86, 0xb3, - 0x95, 0x92, 0x28, 0x0, 0x0, 0xc1, 0x0, 0x0, - 0x92, 0xb, 0x20, 0x0, 0xc1, 0x1, 0x40, 0x92, - 0x9, 0x68, 0x66, 0xd6, 0x67, 0x70, 0x96, 0x5d, - 0x30, 0x60, 0xc1, 0x20, 0x0, 0x93, 0xb6, 0x6, - 0xd1, 0xc1, 0x28, 0x0, 0x92, 0x0, 0x2b, 0x0, - 0xc1, 0x3, 0xd1, 0xa2, 0x1, 0x80, 0x0, 0xc0, - 0x0, 0x96, 0xa2, 0x2, 0x1, 0x6c, 0xe0, 0x0, - 0x10, 0x40, 0x0, 0x0, 0x3, 0x20, 0x0, 0x0, - - /* U+9678 "陸" */ - 0x11, 0x0, 0x20, 0x0, 0xc, 0x10, 0x0, 0x3, - 0xc6, 0x6d, 0x50, 0x0, 0xd0, 0x0, 0x0, 0x2a, - 0x1, 0xb0, 0x66, 0x6e, 0x66, 0xc2, 0x2, 0xa0, - 0x72, 0x1, 0x0, 0xd0, 0x0, 0x0, 0x2a, 0x6, - 0x0, 0x0, 0xd, 0x0, 0x5, 0x2, 0xa0, 0x51, - 0x86, 0x76, 0x76, 0x66, 0x82, 0x2a, 0x5, 0x30, - 0xc, 0x70, 0x39, 0x40, 0x2, 0xa0, 0xb, 0x9, - 0x50, 0xc1, 0x1d, 0x30, 0x2a, 0x0, 0xe4, 0x10, - 0xd, 0x0, 0x21, 0x2, 0xc6, 0xa9, 0x0, 0x0, - 0xd0, 0x5, 0x0, 0x2a, 0x28, 0x1, 0x86, 0x6e, - 0x66, 0x72, 0x2, 0xa0, 0x0, 0x0, 0x0, 0xd0, - 0x0, 0x0, 0x2a, 0x0, 0x0, 0x0, 0xd, 0x0, - 0x3, 0x3, 0xa0, 0x7, 0x66, 0x66, 0xa6, 0x67, - 0xa2, 0x12, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, - - /* U+967D "陽" */ - 0x40, 0x1, 0x40, 0x52, 0x22, 0x26, 0x10, 0xc6, - 0x6a, 0xb0, 0xd4, 0x44, 0x4d, 0x20, 0xb1, 0xb, - 0x10, 0xd6, 0x66, 0x6e, 0x0, 0xb1, 0x27, 0x0, - 0xd0, 0x0, 0xd, 0x0, 0xb1, 0x60, 0x0, 0xe6, - 0x66, 0x6e, 0x0, 0xb1, 0x51, 0x0, 0x70, 0x0, - 0x4, 0x0, 0xb1, 0xa, 0x27, 0x66, 0x66, 0x66, - 0xb4, 0xb1, 0x8, 0x40, 0x2d, 0x0, 0x0, 0x0, - 0xb1, 0x7, 0x70, 0xb8, 0x86, 0x86, 0xd3, 0xb6, - 0x7d, 0x39, 0x42, 0xb2, 0xb0, 0xd0, 0xb1, 0x85, - 0x62, 0xb, 0x19, 0x50, 0xd0, 0xb1, 0x0, 0x1, - 0x92, 0x4a, 0x2, 0xb0, 0xb1, 0x0, 0x15, 0x3, - 0xa0, 0x5, 0x90, 0xb1, 0x0, 0x0, 0x66, 0x5, - 0xbe, 0x30, 0x0, 0x0, 0x0, 0x0, 0x0, 0x43, - 0x0, - - /* U+968E "階" */ - 0x12, 0x0, 0x41, 0x60, 0x0, 0x90, 0x0, 0x3, - 0xb6, 0x6e, 0x4d, 0x0, 0xd, 0x3, 0x10, 0x29, - 0x4, 0x70, 0xd0, 0x51, 0xd2, 0xc5, 0x2, 0x90, - 0x90, 0xe, 0x66, 0x3e, 0x60, 0x10, 0x29, 0x24, - 0x0, 0xd0, 0x1, 0xd0, 0x5, 0x2, 0x90, 0x70, - 0xd, 0x76, 0xe, 0x0, 0xa0, 0x29, 0x4, 0x71, - 0xc3, 0x11, 0x8b, 0xba, 0x12, 0x90, 0xd, 0x0, - 0x7, 0x80, 0x0, 0x0, 0x29, 0x11, 0xe0, 0xa6, - 0xa6, 0x66, 0xb1, 0x2, 0x95, 0xf6, 0xd, 0x0, - 0x0, 0xd, 0x0, 0x29, 0x0, 0x0, 0xd6, 0x66, - 0x66, 0xd0, 0x2, 0x90, 0x0, 0xd, 0x0, 0x0, - 0xd, 0x0, 0x39, 0x0, 0x0, 0xd0, 0x0, 0x0, - 0xd0, 0x3, 0x90, 0x0, 0xd, 0x66, 0x66, 0x6d, - 0x0, 0x10, 0x0, 0x0, 0x30, 0x0, 0x0, 0x20, - 0x0, - - /* U+969B "際" */ - 0x0, 0x0, 0x0, 0x30, 0x0, 0x0, 0x0, 0x5, - 0x0, 0x44, 0xd, 0x50, 0x40, 0x0, 0x0, 0xc8, - 0x7d, 0x82, 0xf6, 0xa8, 0x66, 0xc3, 0xc, 0x1, - 0xc0, 0xa6, 0xc, 0x43, 0x1b, 0x0, 0xc0, 0x63, - 0x38, 0x95, 0xa0, 0x67, 0x10, 0xc, 0x6, 0x7, - 0x93, 0xa2, 0x7, 0x60, 0x0, 0xc0, 0x60, 0x2, - 0x57, 0x0, 0xc, 0x50, 0xc, 0x2, 0x80, 0x47, - 0x0, 0x2, 0x4c, 0x90, 0xc0, 0xb, 0x43, 0x18, - 0x66, 0x64, 0x0, 0xc, 0x0, 0xa4, 0x0, 0x0, - 0x0, 0x6, 0x0, 0xc4, 0xad, 0x6, 0x76, 0x6e, - 0x66, 0x62, 0xc, 0x3, 0x10, 0x6, 0x40, 0xd0, - 0x50, 0x0, 0xc0, 0x0, 0x4, 0xc3, 0xd, 0x3, - 0xc2, 0xc, 0x0, 0x5, 0x70, 0x0, 0xd0, 0x5, - 0xd0, 0xd0, 0x2, 0x20, 0x17, 0xdb, 0x0, 0x4, - 0x4, 0x0, 0x0, 0x0, 0x5, 0x10, 0x0, 0x0, - - /* U+969C "障" */ - 0x0, 0x0, 0x0, 0x4, 0x60, 0x0, 0x0, 0xb6, - 0x8d, 0x0, 0x0, 0xc0, 0x6, 0x0, 0xc1, 0x76, - 0x7, 0x97, 0x66, 0xd6, 0x30, 0xb1, 0xa0, 0x0, - 0xc, 0x4, 0x90, 0x0, 0xb1, 0x71, 0x66, 0x6c, - 0x6a, 0x66, 0xc5, 0xb2, 0x40, 0x22, 0x0, 0x0, - 0x3, 0x0, 0xb1, 0x43, 0xb, 0x76, 0x66, 0x6c, - 0x50, 0xb1, 0xb, 0xb, 0x20, 0x0, 0xb, 0x20, - 0xb1, 0xd, 0xb, 0x76, 0x66, 0x6c, 0x20, 0xb5, - 0x4e, 0xb, 0x76, 0x66, 0x6c, 0x20, 0xb3, 0xd5, - 0x5, 0x0, 0xd0, 0x4, 0x30, 0xb1, 0x2, 0x86, - 0x66, 0xe6, 0x66, 0xa6, 0xb1, 0x0, 0x0, 0x0, - 0xd0, 0x0, 0x0, 0xc1, 0x0, 0x0, 0x0, 0xd0, - 0x0, 0x0, 0x40, 0x0, 0x0, 0x0, 0x60, 0x0, - 0x0, - - /* U+96A3 "隣" */ - 0x20, 0x3, 0x0, 0x20, 0x29, 0x3, 0x0, 0xc, - 0x66, 0xe5, 0x8, 0x62, 0xb0, 0xd5, 0x0, 0xc0, - 0x3a, 0x0, 0x7, 0x2b, 0x64, 0x0, 0xc, 0x9, - 0x10, 0x67, 0x7a, 0xd9, 0x69, 0x60, 0xc2, 0x40, - 0x0, 0x1b, 0x4b, 0x72, 0x0, 0xc, 0x7, 0x0, - 0x58, 0x2, 0xb0, 0xac, 0x70, 0xc0, 0x37, 0x32, - 0x20, 0x29, 0x2, 0x21, 0xc, 0x0, 0xc0, 0x5c, - 0x0, 0x0, 0xd0, 0x0, 0xc1, 0xd, 0x1c, 0x78, - 0xc4, 0x7d, 0x69, 0xc, 0x4e, 0x88, 0x70, 0x95, - 0x51, 0xc0, 0x0, 0xc0, 0x13, 0x4a, 0x2c, 0xc, - 0x1c, 0x5, 0xc, 0x0, 0x0, 0x3a, 0x41, 0x86, - 0xd6, 0x61, 0xc0, 0x0, 0x7, 0x70, 0x0, 0xc, - 0x0, 0xd, 0x0, 0x7, 0x40, 0x0, 0x0, 0xd0, - 0x0, 0x30, 0x3, 0x0, 0x0, 0x0, 0x4, 0x0, - 0x0, - - /* U+96A8 "隨" */ - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x4, - 0x11, 0x50, 0x0, 0x0, 0xd2, 0x0, 0x0, 0xc5, - 0x7d, 0x30, 0x46, 0x6e, 0x66, 0xa3, 0xc, 0x7, - 0x34, 0x91, 0x19, 0x30, 0x2, 0x0, 0xc0, 0x70, - 0xc, 0x8, 0x96, 0xb6, 0x80, 0xc, 0x22, 0x0, - 0x5, 0x66, 0x6d, 0x67, 0x70, 0xc0, 0x90, 0x3, - 0x1, 0x10, 0x0, 0x10, 0xc, 0x4, 0x87, 0xd5, - 0x2b, 0x66, 0x6d, 0x0, 0xc0, 0xd, 0xc, 0x1, - 0xa0, 0x0, 0xc0, 0xc, 0x1, 0xd0, 0xc0, 0x1c, - 0x66, 0x6c, 0x0, 0xc5, 0xe4, 0xc, 0x1, 0xc6, - 0x66, 0xc0, 0xc, 0x0, 0x0, 0xc0, 0x2a, 0x0, - 0xc, 0x0, 0xc0, 0x0, 0x1a, 0x22, 0xa0, 0x38, - 0xa0, 0xc, 0x0, 0x3a, 0x6, 0x84, 0x10, 0x42, - 0x10, 0xb0, 0x5, 0x20, 0x2, 0x9d, 0xee, 0xf8, - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - - /* U+96BB "隻" */ - 0x0, 0x0, 0x0, 0x10, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x8, 0x5, 0x90, 0x0, 0x0, 0x0, 0x0, - 0x8, 0xb0, 0xd, 0x0, 0x0, 0x10, 0x0, 0x3, - 0xf6, 0x66, 0x76, 0x66, 0x9c, 0x10, 0x1, 0xac, - 0x0, 0xe, 0x0, 0x2, 0x0, 0x1, 0x71, 0xd6, - 0x66, 0xe6, 0x66, 0xa1, 0x0, 0x20, 0xc, 0x0, - 0xe, 0x0, 0x6, 0x0, 0x0, 0x0, 0xd6, 0x66, - 0xe6, 0x66, 0x62, 0x0, 0x0, 0xd, 0x66, 0x6e, - 0x66, 0x66, 0xd2, 0x0, 0x0, 0x60, 0x0, 0x0, - 0x2, 0x0, 0x0, 0x0, 0x77, 0x66, 0x66, 0x67, - 0xf3, 0x0, 0x0, 0x0, 0x8, 0x10, 0x2, 0xc4, - 0x0, 0x0, 0x0, 0x0, 0x9, 0x56, 0xc2, 0x0, - 0x0, 0x0, 0x0, 0x0, 0x5e, 0xe6, 0x10, 0x0, - 0x0, 0x0, 0x47, 0x85, 0x0, 0x6b, 0xcb, 0xa9, - 0x13, 0x41, 0x0, 0x0, 0x0, 0x0, 0x24, 0x20, - - /* U+96C6 "集" */ - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x4c, 0x5, 0x70, 0x0, 0x0, 0x0, - 0x0, 0x0, 0xb5, 0x0, 0xc2, 0x0, 0x2, 0x0, - 0x0, 0x4, 0xe6, 0x66, 0xa6, 0x66, 0x6b, 0x10, - 0x0, 0x1d, 0xa0, 0x0, 0xc0, 0x0, 0x20, 0x0, - 0x0, 0x94, 0xc6, 0x66, 0xd6, 0x66, 0x93, 0x0, - 0x6, 0x12, 0xa0, 0x0, 0xc0, 0x0, 0x60, 0x0, - 0x0, 0x2, 0xc6, 0x66, 0xd6, 0x66, 0x62, 0x0, - 0x0, 0x3, 0xc6, 0x66, 0xd6, 0x66, 0x7b, 0x0, - 0x0, 0x3, 0x90, 0x1, 0xa0, 0x0, 0x0, 0x0, - 0x5, 0x66, 0x66, 0x66, 0xd6, 0x66, 0x66, 0xd2, - 0x1, 0x0, 0x0, 0x98, 0xb5, 0x10, 0x0, 0x0, - 0x0, 0x0, 0x1a, 0x51, 0xb0, 0x94, 0x0, 0x0, - 0x0, 0x4, 0x92, 0x1, 0xb0, 0x9, 0xb5, 0x20, - 0x3, 0x64, 0x0, 0x2, 0xc0, 0x0, 0x3b, 0xd3, - 0x1, 0x0, 0x0, 0x1, 0x20, 0x0, 0x0, 0x0, - - /* U+96D1 "雑" */ - 0x0, 0xa, 0x10, 0x0, 0x2, 0x5, 0x0, 0x0, - 0x0, 0xd, 0x2, 0x0, 0x3e, 0x9, 0x60, 0x0, - 0x3, 0x6e, 0x6e, 0x10, 0x66, 0x4, 0x52, 0x0, - 0x0, 0x1b, 0xb, 0x0, 0xb7, 0x6a, 0x69, 0x60, - 0x0, 0x65, 0x38, 0x42, 0xf2, 0xd, 0x0, 0x0, - 0x2, 0x90, 0x2b, 0xb9, 0xc2, 0xd, 0x0, 0x0, - 0x15, 0x1, 0xb0, 0x5, 0xa7, 0x6e, 0x6b, 0x20, - 0x0, 0x1, 0xb0, 0x20, 0xa2, 0xd, 0x0, 0x0, - 0x6, 0x66, 0xd6, 0x84, 0xa2, 0xd, 0x0, 0x0, - 0x0, 0x31, 0xb2, 0x0, 0xa7, 0x6e, 0x6c, 0x20, - 0x0, 0xd4, 0xb4, 0x80, 0xa2, 0xd, 0x0, 0x0, - 0x5, 0x51, 0xb0, 0x88, 0xa2, 0xd, 0x0, 0x0, - 0x17, 0x1, 0xb0, 0x4, 0xb2, 0xd, 0x2, 0x50, - 0x0, 0x3a, 0xa0, 0x0, 0xb7, 0x66, 0x66, 0x50, - 0x0, 0x3, 0x10, 0x0, 0x50, 0x0, 0x0, 0x0, - - /* U+96D6 "雖" */ - 0x0, 0x0, 0x0, 0x0, 0x34, 0x30, 0x0, 0x0, - 0x86, 0x66, 0xd3, 0x7, 0xb7, 0xa0, 0x0, 0x8, - 0x20, 0xc, 0x0, 0xb2, 0xa, 0x1, 0x0, 0x82, - 0x0, 0xc0, 0x1d, 0x66, 0x86, 0xb2, 0x9, 0x7a, - 0x6d, 0x17, 0xc0, 0x1b, 0x0, 0x0, 0x20, 0xc0, - 0x0, 0x7c, 0x1, 0xb0, 0x0, 0x28, 0x6d, 0x66, - 0xb0, 0xd6, 0x6c, 0x6b, 0x2, 0x90, 0xc0, 0x4a, - 0xc, 0x1, 0xb0, 0x0, 0x29, 0xc, 0x4, 0xa0, - 0xc0, 0x1b, 0x0, 0x2, 0xb6, 0xd6, 0x8a, 0xd, - 0x66, 0xc6, 0xb0, 0x13, 0xc, 0x3, 0x10, 0xc0, - 0x1b, 0x0, 0x0, 0x0, 0xc0, 0x73, 0xc, 0x1, - 0xb0, 0x0, 0x45, 0x7d, 0x88, 0xc0, 0xc0, 0x1b, - 0x6, 0x26, 0x95, 0x10, 0xc, 0xd, 0x66, 0x66, - 0x63, 0x0, 0x0, 0x0, 0x0, 0x30, 0x0, 0x0, - 0x0, - - /* U+96D9 "雙" */ - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x7, 0x28, 0x0, 0x27, 0x39, 0x0, 0x0, - 0x0, 0x4c, 0xa, 0x10, 0x78, 0xa, 0x3, 0x0, - 0x0, 0xd7, 0x68, 0x85, 0xc6, 0x6a, 0x68, 0x20, - 0x7, 0xe0, 0x1a, 0x23, 0xf0, 0x1a, 0x2, 0x0, - 0x13, 0xc6, 0x6c, 0x76, 0xc6, 0x6c, 0x66, 0x0, - 0x0, 0xc0, 0x1a, 0x20, 0xc0, 0x1a, 0x2, 0x0, - 0x0, 0xc6, 0x6c, 0x62, 0xc6, 0x6c, 0x66, 0x0, - 0x0, 0xc3, 0x4b, 0x54, 0xc0, 0x1a, 0x5, 0x10, - 0x0, 0xa3, 0x33, 0x32, 0xa6, 0x66, 0x66, 0x30, - 0x0, 0x56, 0x76, 0x66, 0x66, 0x6b, 0x50, 0x0, - 0x0, 0x0, 0x26, 0x0, 0x0, 0x98, 0x0, 0x0, - 0x0, 0x0, 0x2, 0x82, 0x5a, 0x30, 0x0, 0x0, - 0x0, 0x0, 0x0, 0x4d, 0xd3, 0x0, 0x0, 0x0, - 0x0, 0x3, 0x78, 0x50, 0x17, 0xbb, 0x98, 0x83, - 0x4, 0x52, 0x0, 0x0, 0x0, 0x1, 0x46, 0x50, - - /* U+96E2 "離" */ - 0x0, 0x8, 0x0, 0x0, 0x24, 0x11, 0x0, 0x0, - 0x0, 0x84, 0x5, 0x16, 0xc0, 0xb1, 0x0, 0x46, - 0x66, 0x97, 0x62, 0x93, 0x7, 0x40, 0x0, 0x93, - 0x6b, 0x36, 0xd, 0x66, 0x86, 0xb2, 0xb, 0xa, - 0x80, 0xc3, 0xf0, 0xd, 0x0, 0x0, 0xc4, 0x9, - 0xc, 0x6d, 0x0, 0xd0, 0x0, 0x2c, 0x68, 0x66, - 0xc1, 0xd6, 0x6e, 0x6a, 0x0, 0x0, 0xc2, 0x2, - 0xd, 0x0, 0xd0, 0x0, 0x2a, 0x6b, 0x55, 0xd2, - 0xd0, 0xd, 0x0, 0x2, 0x97, 0x15, 0xb, 0xd, - 0x66, 0xe6, 0xb0, 0x2b, 0xc8, 0xa4, 0xb0, 0xd0, - 0xd, 0x0, 0x2, 0x94, 0x1, 0xb, 0xd, 0x0, - 0xd0, 0x0, 0x29, 0x0, 0x0, 0xb0, 0xd0, 0xd, - 0x5, 0x2, 0x90, 0x5, 0xcb, 0xd, 0x66, 0x66, - 0x63, 0x13, 0x0, 0x1, 0x0, 0x30, 0x0, 0x0, - 0x0, - - /* U+96E3 "難" */ - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x16, 0x2, 0x60, 0x4, 0xc5, 0x40, 0x0, - 0x0, 0x29, 0x2, 0xb0, 0x7, 0xa0, 0xe1, 0x0, - 0x5, 0x8b, 0x67, 0xd8, 0x5b, 0x20, 0x50, 0x60, - 0x0, 0x29, 0x2, 0xb0, 0x1f, 0x66, 0xd6, 0x72, - 0x0, 0x28, 0xc7, 0x70, 0x6e, 0x0, 0xc0, 0x0, - 0x0, 0x86, 0xd6, 0x69, 0x6d, 0x0, 0xc0, 0x0, - 0x0, 0xc0, 0xc0, 0xb, 0xd, 0x66, 0xd6, 0x90, - 0x0, 0xd6, 0xd6, 0x6b, 0xd, 0x0, 0xc0, 0x0, - 0x0, 0x30, 0xc0, 0x5, 0xd, 0x0, 0xc0, 0x0, - 0x0, 0x76, 0xd6, 0x66, 0xd, 0x66, 0xd6, 0xa0, - 0x5, 0x76, 0xd6, 0x6a, 0x4d, 0x0, 0xc0, 0x0, - 0x0, 0x1, 0x93, 0x10, 0xd, 0x0, 0xc0, 0x0, - 0x0, 0xa, 0x21, 0xd3, 0xd, 0x0, 0xc0, 0x40, - 0x1, 0x82, 0x0, 0x44, 0xd, 0x66, 0x76, 0x73, - 0x3, 0x0, 0x0, 0x0, 0x4, 0x0, 0x0, 0x0, - - /* U+96E8 "雨" */ - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x30, 0x67, - 0x66, 0x66, 0x86, 0x66, 0x68, 0xc1, 0x0, 0x0, - 0x0, 0xd0, 0x0, 0x0, 0x0, 0x2, 0x0, 0x0, - 0xd0, 0x0, 0x5, 0x0, 0xd, 0x66, 0x66, 0xe6, - 0x66, 0x6e, 0x20, 0xc, 0x16, 0x20, 0xd1, 0x50, - 0xe, 0x0, 0xc, 0x11, 0xe3, 0xd0, 0x6c, 0xe, - 0x0, 0xc, 0x10, 0x53, 0xd0, 0x8, 0xe, 0x0, - 0xc, 0x10, 0x0, 0xd0, 0x0, 0xe, 0x0, 0xc, - 0x1a, 0x50, 0xd1, 0x93, 0xe, 0x0, 0xc, 0x11, - 0xe0, 0xd0, 0x2e, 0xe, 0x0, 0xc, 0x10, 0x10, - 0xd0, 0x3, 0xe, 0x0, 0xc, 0x10, 0x0, 0xd0, - 0x15, 0x5f, 0x0, 0xc, 0x10, 0x0, 0x90, 0x2, - 0xca, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x10, - 0x0, - - /* U+96EA "雪" */ - 0x0, 0x0, 0x0, 0x0, 0x0, 0x5, 0x50, 0x0, - 0x4, 0x76, 0x66, 0xd6, 0x66, 0x66, 0x0, 0x1, - 0x20, 0x0, 0xd, 0x0, 0x0, 0x5, 0x10, 0x59, - 0x66, 0x66, 0xe6, 0x66, 0x66, 0xe5, 0xd, 0x45, - 0x66, 0x1d, 0x5, 0x66, 0x42, 0x0, 0x30, 0x0, - 0x0, 0xd0, 0x0, 0x0, 0x0, 0x0, 0x5, 0x66, - 0x1d, 0x5, 0x66, 0x20, 0x0, 0x0, 0x0, 0x0, - 0x70, 0x0, 0x10, 0x0, 0x0, 0x37, 0x66, 0x66, - 0x66, 0x6b, 0x90, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x76, 0x0, 0x0, 0x6, 0x66, 0x66, 0x66, - 0x6a, 0x60, 0x0, 0x0, 0x10, 0x0, 0x0, 0x0, - 0x76, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x7, - 0x60, 0x0, 0x6, 0x76, 0x66, 0x66, 0x66, 0xa6, - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x3, 0x10, - 0x0, - - /* U+96F2 "雲" */ - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x56, 0x66, 0x66, 0x66, 0x98, 0x0, 0x0, 0x20, - 0x0, 0xa3, 0x0, 0x0, 0x0, 0x9, 0x66, 0x66, - 0xc8, 0x66, 0x66, 0xb1, 0x59, 0x0, 0x0, 0xa3, - 0x0, 0x1, 0xc3, 0x82, 0x56, 0x60, 0xa3, 0x56, - 0x64, 0x10, 0x0, 0x0, 0x0, 0xa3, 0x0, 0x0, - 0x0, 0x0, 0x56, 0x60, 0xa2, 0x56, 0x61, 0x0, - 0x0, 0x0, 0x0, 0x0, 0x0, 0x30, 0x0, 0x0, - 0x76, 0x66, 0x66, 0x66, 0x95, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x0, 0x0, 0x70, 0x47, 0x66, 0x6b, - 0x76, 0x66, 0x66, 0x83, 0x0, 0x0, 0x8b, 0x40, - 0x35, 0x0, 0x0, 0x0, 0x49, 0x30, 0x0, 0x4, - 0xd4, 0x0, 0x5, 0xfc, 0xba, 0x87, 0x65, 0x7e, - 0x0, 0x0, 0x41, 0x0, 0x0, 0x0, 0x4, 0x0, - - /* U+96FB "電" */ - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x56, 0x66, 0x66, 0x66, 0x99, 0x0, 0x2, 0x10, - 0x0, 0xe0, 0x0, 0x0, 0x10, 0x9, 0x66, 0x66, - 0xe6, 0x66, 0x66, 0xd5, 0x5a, 0x0, 0x0, 0xe0, - 0x0, 0x0, 0x90, 0x42, 0x46, 0x60, 0xe0, 0x26, - 0x65, 0x20, 0x0, 0x45, 0x50, 0xd0, 0x26, 0x64, - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x1, 0x0, - 0x0, 0xc6, 0x66, 0x96, 0x66, 0x7e, 0x0, 0x0, - 0xd0, 0x0, 0xe0, 0x0, 0x1b, 0x0, 0x0, 0xd6, - 0x66, 0xe6, 0x66, 0x6b, 0x0, 0x0, 0xd0, 0x0, - 0xe0, 0x0, 0x1b, 0x0, 0x0, 0xd6, 0x66, 0xe6, - 0x66, 0x6b, 0x40, 0x0, 0x40, 0x0, 0xe0, 0x0, - 0x1, 0x72, 0x0, 0x0, 0x0, 0xbd, 0xbb, 0xbb, - 0xd6, - - /* U+9700 "需" */ - 0x0, 0x0, 0x0, 0x0, 0x0, 0x8, 0x20, 0x0, - 0x5, 0x66, 0x68, 0xb6, 0x66, 0x64, 0x0, 0x7, - 0x66, 0x66, 0x8b, 0x66, 0x66, 0x7c, 0x11, 0xd0, - 0x0, 0x4, 0x90, 0x0, 0x7, 0x20, 0x13, 0x6, - 0x63, 0x49, 0x46, 0x63, 0x10, 0x0, 0x1, 0x66, - 0x34, 0x94, 0x66, 0x30, 0x0, 0x0, 0x0, 0x0, - 0x11, 0x0, 0x0, 0x61, 0x0, 0x76, 0x66, 0x6d, - 0x66, 0x66, 0x66, 0x40, 0x0, 0x30, 0x4, 0x30, - 0x0, 0x0, 0x40, 0x0, 0xe, 0x66, 0xe6, 0x6e, - 0x66, 0x7c, 0x0, 0x0, 0xd0, 0xd, 0x0, 0xd0, - 0x2, 0xa0, 0x0, 0xd, 0x0, 0xd0, 0xd, 0x0, - 0x2a, 0x0, 0x0, 0xd0, 0xd, 0x0, 0xd0, 0x2, - 0xa0, 0x0, 0xd, 0x0, 0x90, 0x7, 0x5, 0xc9, - 0x0, 0x0, 0x40, 0x0, 0x0, 0x0, 0x3, 0x0, - 0x0, - - /* U+9707 "震" */ - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x46, 0x66, 0x66, 0x66, 0xd6, 0x0, 0x0, - 0x21, 0x10, 0xa, 0x20, 0x0, 0x2, 0x0, 0x9, - 0x66, 0x66, 0xc7, 0x66, 0x66, 0xf3, 0x3, 0xd2, - 0x66, 0x3a, 0x25, 0x66, 0x53, 0x0, 0x11, 0x0, - 0x0, 0xa3, 0x0, 0x0, 0x0, 0x0, 0x13, 0x66, - 0x38, 0x15, 0x66, 0x50, 0x0, 0x3, 0xb6, 0x66, - 0x66, 0x66, 0x6a, 0x40, 0x0, 0x3a, 0x16, 0x66, - 0x66, 0x6a, 0x50, 0x0, 0x3, 0xa0, 0x20, 0x0, - 0x0, 0x0, 0x40, 0x0, 0x3c, 0x69, 0x67, 0x66, - 0x66, 0x6b, 0x30, 0x5, 0x80, 0xd0, 0x25, 0x0, - 0xb4, 0x0, 0x0, 0x84, 0xd, 0x0, 0x66, 0x84, - 0x0, 0x0, 0xb, 0x0, 0xd0, 0x52, 0x7a, 0x30, - 0x0, 0x6, 0x20, 0xe, 0xa1, 0x0, 0x3b, 0xfc, - 0x70, 0x20, 0x0, 0x30, 0x0, 0x0, 0x1, 0x40, - - /* U+9752 "青" */ - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x0, 0xd, 0x30, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x0, 0xe, 0x0, 0x0, 0x58, 0x0, - 0x5, 0x76, 0x66, 0x6e, 0x66, 0x66, 0x66, 0x10, - 0x0, 0x26, 0x66, 0x6e, 0x66, 0x68, 0xb0, 0x0, - 0x0, 0x0, 0x0, 0xe, 0x0, 0x0, 0x0, 0x10, - 0x6, 0x66, 0x66, 0x6d, 0x66, 0x66, 0x6b, 0xc0, - 0x1, 0x0, 0x20, 0x0, 0x0, 0x4, 0x0, 0x0, - 0x0, 0x0, 0xe6, 0x66, 0x66, 0x6e, 0x20, 0x0, - 0x0, 0x0, 0xd0, 0x0, 0x0, 0xe, 0x0, 0x0, - 0x0, 0x0, 0xe6, 0x66, 0x66, 0x6e, 0x0, 0x0, - 0x0, 0x0, 0xd0, 0x0, 0x0, 0xe, 0x0, 0x0, - 0x0, 0x0, 0xe6, 0x66, 0x66, 0x6e, 0x0, 0x0, - 0x0, 0x0, 0xd0, 0x0, 0x0, 0xe, 0x0, 0x0, - 0x0, 0x0, 0xd0, 0x0, 0x6, 0xce, 0x0, 0x0, - 0x0, 0x0, 0x70, 0x0, 0x0, 0x43, 0x0, 0x0, - - /* U+9759 "静" */ - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x91, 0x0, 0xa, 0x40, 0x0, 0x0, - 0x0, 0x11, 0xc1, 0x42, 0x1d, 0x0, 0x60, 0x0, - 0x3, 0x65, 0xd5, 0x53, 0x87, 0x68, 0xd2, 0x0, - 0x1, 0x66, 0xd6, 0xa4, 0x60, 0x8, 0x10, 0x0, - 0x0, 0x10, 0xc0, 0x3, 0x76, 0x97, 0x6d, 0x30, - 0x7, 0x66, 0xa6, 0x79, 0x0, 0xc0, 0xc, 0x0, - 0x0, 0x30, 0x0, 0x40, 0x0, 0xc0, 0xc, 0x70, - 0x0, 0xd6, 0x66, 0xd4, 0x76, 0xd6, 0x6d, 0x52, - 0x0, 0xd6, 0x66, 0xb0, 0x0, 0xc0, 0xc, 0x0, - 0x0, 0xc0, 0x0, 0xb1, 0x66, 0xd6, 0x6d, 0x0, - 0x0, 0xd6, 0x66, 0xb0, 0x10, 0xc0, 0x4, 0x0, - 0x0, 0xc0, 0x0, 0xb0, 0x0, 0xc0, 0x0, 0x0, - 0x0, 0xc0, 0x0, 0xb0, 0x0, 0xc0, 0x0, 0x0, - 0x0, 0xc0, 0x5a, 0x90, 0x59, 0xd0, 0x0, 0x0, - 0x0, 0x40, 0x6, 0x10, 0x5, 0x40, 0x0, 0x0, - - /* U+975E "非" */ - 0x0, 0x0, 0x0, 0x91, 0xa, 0x20, 0x0, 0x0, - 0x0, 0x0, 0x0, 0xe0, 0xd, 0x10, 0x0, 0x0, - 0x0, 0x0, 0x0, 0xe0, 0xd, 0x10, 0x1, 0x0, - 0x4, 0x76, 0x66, 0xe0, 0xd, 0x66, 0x6a, 0x50, - 0x0, 0x0, 0x0, 0xe0, 0xd, 0x10, 0x0, 0x0, - 0x0, 0x0, 0x0, 0xe0, 0xd, 0x10, 0x0, 0x0, - 0x0, 0x56, 0x66, 0xe0, 0xd, 0x66, 0x6c, 0x20, - 0x0, 0x10, 0x0, 0xe0, 0xd, 0x10, 0x0, 0x0, - 0x0, 0x0, 0x0, 0xe0, 0xd, 0x10, 0x0, 0x0, - 0x0, 0x0, 0x0, 0xe0, 0xd, 0x10, 0x1, 0x50, - 0x7, 0x66, 0x66, 0xe0, 0xd, 0x66, 0x66, 0x70, - 0x0, 0x0, 0x0, 0xe0, 0xd, 0x10, 0x0, 0x0, - 0x0, 0x0, 0x0, 0xe0, 0xd, 0x10, 0x0, 0x0, - 0x0, 0x0, 0x0, 0xe0, 0xd, 0x10, 0x0, 0x0, - 0x0, 0x0, 0x0, 0x40, 0x3, 0x0, 0x0, 0x0, - - /* U+9762 "面" */ - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x3, 0xa0, - 0x18, 0x66, 0x66, 0x6f, 0x76, 0x66, 0x66, 0x61, - 0x0, 0x0, 0x0, 0x3a, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x20, 0x0, 0x61, 0x0, 0x0, 0x5, 0x0, - 0x0, 0xd6, 0x66, 0xd6, 0x6d, 0x66, 0x6e, 0x10, - 0x0, 0xd1, 0x0, 0xc0, 0xd, 0x0, 0xd, 0x0, - 0x0, 0xc1, 0x0, 0xd6, 0x6e, 0x0, 0xd, 0x0, - 0x0, 0xc1, 0x0, 0xc0, 0xd, 0x0, 0xd, 0x0, - 0x0, 0xc1, 0x0, 0xc0, 0xd, 0x0, 0xd, 0x0, - 0x0, 0xc1, 0x0, 0xd6, 0x6e, 0x0, 0xd, 0x0, - 0x0, 0xc1, 0x0, 0xc0, 0xd, 0x0, 0xe, 0x0, - 0x0, 0xc1, 0x0, 0xc0, 0xd, 0x0, 0xe, 0x0, - 0x0, 0xd6, 0x66, 0xd6, 0x6e, 0x66, 0x6e, 0x0, - 0x0, 0xd1, 0x0, 0x0, 0x0, 0x0, 0xe, 0x0, - 0x0, 0x10, 0x0, 0x0, 0x0, 0x0, 0x1, 0x0, - - /* U+9769 "革" */ - 0x0, 0x0, 0xa, 0x20, 0x0, 0x90, 0x0, 0x0, - 0x0, 0x0, 0xd, 0x0, 0x0, 0xd0, 0x8, 0x10, - 0x2, 0x86, 0x6e, 0x66, 0x66, 0xe6, 0x66, 0x30, - 0x0, 0x0, 0xd, 0x0, 0x0, 0xd0, 0x0, 0x0, - 0x0, 0x0, 0xd, 0x6b, 0x76, 0xa0, 0x0, 0x0, - 0x0, 0x2, 0x0, 0xb, 0x20, 0x0, 0x30, 0x0, - 0x0, 0xd, 0x66, 0x6d, 0x76, 0x66, 0xf1, 0x0, - 0x0, 0xd, 0x10, 0xb, 0x20, 0x0, 0xe0, 0x0, - 0x0, 0xd, 0x66, 0x6d, 0x76, 0x66, 0xe0, 0x0, - 0x0, 0x8, 0x0, 0xb, 0x20, 0x0, 0x30, 0x0, - 0x0, 0x0, 0x0, 0xb, 0x20, 0x0, 0x3, 0x90, - 0x7, 0x66, 0x66, 0x6d, 0x76, 0x66, 0x66, 0x61, - 0x0, 0x0, 0x0, 0xb, 0x20, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x0, 0xc, 0x30, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x0, 0x6, 0x10, 0x0, 0x0, 0x0, - - /* U+9774 "靴" */ - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x66, 0x7, 0x40, 0x8, 0x17, 0x10, 0x0, - 0x0, 0x66, 0x8, 0x52, 0xe, 0x1c, 0x0, 0x0, - 0x6, 0xa9, 0x6b, 0x84, 0x48, 0xc, 0x0, 0x0, - 0x0, 0x66, 0x8, 0x40, 0x81, 0xc, 0x4, 0xa0, - 0x0, 0x68, 0xc9, 0x30, 0xa0, 0xc, 0xb, 0x30, - 0x0, 0x20, 0xc0, 0x53, 0xe2, 0xc, 0x48, 0x0, - 0x0, 0xd6, 0xd6, 0xd6, 0xb0, 0xc, 0x90, 0x0, - 0x0, 0xc0, 0xc0, 0xc1, 0xb0, 0xd, 0x20, 0x0, - 0x0, 0xd6, 0xd6, 0xc0, 0xb0, 0x7d, 0x0, 0x0, - 0x0, 0x30, 0xc0, 0x10, 0xb3, 0x1c, 0x0, 0x0, - 0x5, 0x66, 0xd6, 0xa6, 0xb0, 0xc, 0x0, 0x10, - 0x1, 0x0, 0xc0, 0x0, 0xb0, 0xc, 0x0, 0x60, - 0x0, 0x0, 0xc0, 0x0, 0xb0, 0xb, 0x0, 0x90, - 0x0, 0x0, 0xd0, 0x0, 0xc1, 0x8, 0xcb, 0xe2, - 0x0, 0x0, 0x50, 0x0, 0x30, 0x0, 0x0, 0x0, - - /* U+97F3 "音" */ - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x1, 0xb2, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x7, 0x70, 0x0, 0x70, 0x0, 0x3, - 0x76, 0x76, 0x66, 0x68, 0x68, 0x30, 0x0, 0x0, - 0xa, 0x20, 0x1, 0xf2, 0x0, 0x0, 0x0, 0x0, - 0x5c, 0x0, 0x75, 0x0, 0x0, 0x0, 0x0, 0x1, - 0x60, 0x8, 0x0, 0x1b, 0x30, 0x76, 0x66, 0x66, - 0x66, 0x66, 0x66, 0x64, 0x0, 0x0, 0x40, 0x0, - 0x0, 0x7, 0x0, 0x0, 0x0, 0xe, 0x66, 0x66, - 0x66, 0xe2, 0x0, 0x0, 0x0, 0xe0, 0x0, 0x0, - 0xe, 0x0, 0x0, 0x0, 0xe, 0x66, 0x66, 0x66, - 0xe0, 0x0, 0x0, 0x0, 0xe0, 0x0, 0x0, 0xe, - 0x0, 0x0, 0x0, 0xe, 0x66, 0x66, 0x66, 0xe0, - 0x0, 0x0, 0x0, 0xe0, 0x0, 0x0, 0xd, 0x0, - 0x0, 0x0, 0x1, 0x0, 0x0, 0x0, 0x10, 0x0, - - /* U+97FF "響" */ - 0x0, 0x0, 0x0, 0x10, 0x0, 0x0, 0x0, 0x0, - 0x23, 0x1, 0x28, 0x10, 0x0, 0x10, 0x0, 0xb4, - 0xb, 0x66, 0xc3, 0xc6, 0xc3, 0x28, 0x15, 0x7b, - 0x66, 0xc0, 0xb2, 0x60, 0x49, 0x86, 0xb, 0x0, - 0xb0, 0xb4, 0x20, 0x5, 0x34, 0x8b, 0x68, 0x70, - 0xb0, 0x92, 0xa, 0x6b, 0x2b, 0x36, 0xa0, 0xb2, - 0x75, 0x0, 0x68, 0x9, 0x80, 0x40, 0xb3, 0xa0, - 0x36, 0x40, 0x0, 0x46, 0x0, 0x36, 0x0, 0x1, - 0x76, 0xb9, 0x66, 0xb8, 0x66, 0x10, 0x0, 0x0, - 0x18, 0x3, 0x81, 0x0, 0x71, 0x56, 0x58, 0x55, - 0x55, 0x55, 0x85, 0x53, 0x0, 0xd, 0x66, 0x66, - 0x66, 0xd2, 0x0, 0x0, 0xd, 0x66, 0x66, 0x66, - 0xd0, 0x0, 0x0, 0xd, 0x66, 0x66, 0x66, 0xd0, - 0x0, 0x0, 0x3, 0x0, 0x0, 0x0, 0x30, 0x0, - - /* U+9803 "頃" */ - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x44, 0x0, - 0xa1, 0x0, 0x7, 0x66, 0xe6, 0x66, 0x50, 0xd, - 0x0, 0x0, 0x0, 0x19, 0x0, 0x0, 0x0, 0xd0, - 0x0, 0x2, 0xb6, 0x76, 0x6d, 0x30, 0xd, 0x0, - 0x20, 0x2b, 0x0, 0x0, 0xd0, 0x0, 0xd6, 0x69, - 0x21, 0xd6, 0x66, 0x6e, 0x0, 0xd, 0x0, 0x0, - 0x1b, 0x0, 0x0, 0xd0, 0x0, 0xd0, 0x0, 0x1, - 0xd6, 0x66, 0x6e, 0x0, 0xd, 0x0, 0x0, 0x1b, - 0x0, 0x0, 0xd0, 0x0, 0xd0, 0x5, 0x31, 0xb0, - 0x0, 0xd, 0x0, 0xd, 0x5a, 0x20, 0x2a, 0x76, - 0x66, 0xa0, 0x0, 0xfa, 0x0, 0x0, 0xd, 0x30, - 0x71, 0x0, 0x3, 0x0, 0x0, 0xa, 0x50, 0x1, - 0xd3, 0x0, 0x0, 0x0, 0x17, 0x20, 0x0, 0x5, - 0xa0, 0x0, 0x0, 0x1, 0x0, 0x0, 0x0, 0x1, - 0x0, - - /* U+9805 "項" */ - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x4, 0x30, - 0x0, 0x0, 0x4, 0x7, 0x66, 0xd6, 0x66, 0x50, - 0x6, 0x7c, 0x67, 0x20, 0x1, 0x90, 0x0, 0x0, - 0x0, 0xd, 0x0, 0x3, 0x97, 0x76, 0x6c, 0x30, - 0x0, 0xd, 0x0, 0x3, 0xa0, 0x0, 0xd, 0x0, - 0x0, 0xd, 0x0, 0x2, 0xc6, 0x66, 0x6e, 0x0, - 0x0, 0xd, 0x0, 0x2, 0xa0, 0x0, 0xd, 0x0, - 0x0, 0xd, 0x0, 0x2, 0xa0, 0x0, 0xd, 0x0, - 0x0, 0xd, 0x0, 0x2, 0xc6, 0x66, 0x6e, 0x0, - 0x0, 0xd, 0x36, 0x32, 0xa0, 0x0, 0xd, 0x0, - 0x15, 0xac, 0x50, 0x3, 0xb6, 0x66, 0x6c, 0x0, - 0x1d, 0x50, 0x0, 0x0, 0xc, 0x30, 0x71, 0x0, - 0x0, 0x0, 0x0, 0x0, 0x96, 0x0, 0x2c, 0x20, - 0x0, 0x0, 0x0, 0x7, 0x30, 0x0, 0x6, 0xa0, - 0x0, 0x0, 0x0, 0x20, 0x0, 0x0, 0x0, 0x20, - - /* U+9808 "須" */ - 0x0, 0x2, 0x10, 0x0, 0x0, 0x0, 0x6, 0x0, - 0x0, 0x9a, 0x6, 0x66, 0xb8, 0x66, 0x73, 0x0, - 0x5a, 0x0, 0x0, 0xa, 0x10, 0x0, 0x0, 0x48, - 0x0, 0x0, 0xa6, 0x96, 0x66, 0xd0, 0x43, 0x0, - 0x20, 0xd, 0x0, 0x0, 0x2b, 0x0, 0x0, 0x1e, - 0x40, 0xe6, 0x66, 0x67, 0xb0, 0x0, 0xb, 0x50, - 0xd, 0x0, 0x0, 0x2b, 0x0, 0x1a, 0x30, 0x0, - 0xd0, 0x0, 0x2, 0xb0, 0x36, 0x0, 0x0, 0xe, - 0x66, 0x66, 0x7b, 0x0, 0x0, 0x3, 0xd1, 0xd0, - 0x0, 0x2, 0xb0, 0x0, 0x2, 0xd4, 0xd, 0x66, - 0x66, 0x79, 0x0, 0x3, 0xb2, 0x0, 0x8, 0x60, - 0x71, 0x0, 0x5, 0x70, 0x0, 0x5, 0xc1, 0x2, - 0xc2, 0x2, 0x10, 0x0, 0x6, 0x70, 0x0, 0x6, - 0xa0, 0x0, 0x0, 0x1, 0x10, 0x0, 0x0, 0x2, - 0x0, - - /* U+9817 "頗" */ - 0x0, 0x0, 0x92, 0x0, 0x0, 0x0, 0x0, 0x60, - 0x0, 0x0, 0xc0, 0x4, 0x76, 0xa8, 0x66, 0x82, - 0x0, 0x10, 0xc0, 0x20, 0x0, 0xb2, 0x0, 0x0, - 0x1, 0xc6, 0xd6, 0xc6, 0x96, 0x96, 0x67, 0xc0, - 0x1, 0xb0, 0xc0, 0x80, 0xd0, 0x0, 0x2, 0xa0, - 0x1, 0xb0, 0xc0, 0x20, 0xd4, 0x44, 0x45, 0xa0, - 0x1, 0xc6, 0xd6, 0xb2, 0xd2, 0x22, 0x24, 0xa0, - 0x2, 0xa0, 0x0, 0xc0, 0xd0, 0x0, 0x2, 0xa0, - 0x3, 0x92, 0x4, 0x70, 0xd6, 0x66, 0x67, 0xa0, - 0x4, 0x71, 0x8b, 0x20, 0xd0, 0x0, 0x2, 0xb0, - 0x6, 0x40, 0x6d, 0x0, 0xd6, 0x66, 0x67, 0x90, - 0x8, 0x2, 0x98, 0x80, 0x8, 0x80, 0x61, 0x0, - 0x6, 0x28, 0x0, 0x80, 0x4c, 0x10, 0x1c, 0x40, - 0x22, 0x40, 0x0, 0x5, 0x70, 0x0, 0x3, 0xd0, - 0x0, 0x0, 0x0, 0x12, 0x0, 0x0, 0x0, 0x20, - - /* U+9818 "領" */ - 0x0, 0x3, 0x50, 0x0, 0x0, 0x0, 0x4, 0x30, - 0x0, 0x8, 0x90, 0x6, 0x66, 0xc7, 0x66, 0x60, - 0x0, 0xd, 0x66, 0x0, 0x0, 0xa0, 0x0, 0x0, - 0x0, 0x49, 0x8, 0x90, 0xa6, 0x86, 0x6c, 0x30, - 0x0, 0xa3, 0x0, 0xd2, 0xd0, 0x0, 0xc, 0x0, - 0x5, 0x40, 0xb1, 0x20, 0xd6, 0x66, 0x6d, 0x0, - 0x15, 0x0, 0x74, 0x0, 0xd0, 0x0, 0xc, 0x0, - 0x1, 0x55, 0x55, 0xa0, 0xd0, 0x0, 0xc, 0x0, - 0x0, 0x31, 0x15, 0xb1, 0xd6, 0x66, 0x6d, 0x0, - 0x0, 0x0, 0xa, 0x0, 0xd0, 0x0, 0xc, 0x10, - 0x0, 0x71, 0x53, 0x0, 0xc6, 0x66, 0x6c, 0x0, - 0x0, 0xb, 0x80, 0x0, 0xa, 0x50, 0x62, 0x0, - 0x0, 0x1, 0xe3, 0x0, 0x79, 0x0, 0xc, 0x40, - 0x0, 0x0, 0x53, 0x6, 0x50, 0x0, 0x3, 0xd0, - 0x0, 0x0, 0x0, 0x11, 0x0, 0x0, 0x0, 0x20, - - /* U+982D "頭" */ - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x6, 0x5, - 0x76, 0x66, 0xa7, 0x76, 0x7c, 0x66, 0x73, 0x0, - 0x0, 0x0, 0x0, 0x3, 0x70, 0x0, 0x0, 0x96, - 0x66, 0xb2, 0x2a, 0x75, 0x55, 0xe1, 0xd, 0x0, - 0xd, 0x2, 0xb0, 0x0, 0xd, 0x0, 0xd0, 0x0, - 0xd0, 0x2c, 0x66, 0x66, 0xd0, 0xd, 0x0, 0xd, - 0x2, 0xb0, 0x0, 0xd, 0x0, 0xb6, 0x66, 0x80, - 0x2b, 0x0, 0x0, 0xd0, 0x3, 0x0, 0x35, 0x2, - 0xc6, 0x66, 0x6d, 0x0, 0x64, 0x8, 0x60, 0x2b, - 0x0, 0x0, 0xd0, 0x2, 0xb0, 0x90, 0x2, 0xb6, - 0x66, 0x6b, 0x0, 0x4, 0x29, 0x54, 0x1, 0xd2, - 0x53, 0x0, 0x8d, 0xa7, 0x30, 0x0, 0xb5, 0x0, - 0xa6, 0x1, 0x0, 0x0, 0x2, 0x82, 0x0, 0x1, - 0xf0, 0x0, 0x0, 0x0, 0x20, 0x0, 0x0, 0x3, - 0x0, - - /* U+983C "頼" */ - 0x0, 0x0, 0x93, 0x0, 0x0, 0x0, 0x0, 0x60, - 0x0, 0x0, 0xc0, 0x0, 0x67, 0x6d, 0x66, 0x72, - 0x4, 0x66, 0xd6, 0x6c, 0x10, 0xa, 0x0, 0x0, - 0x1, 0x10, 0xc0, 0x0, 0xa, 0x77, 0x66, 0xd1, - 0x1, 0x41, 0xc1, 0x15, 0xd, 0x0, 0x0, 0xd0, - 0x1, 0xb4, 0xd4, 0x5c, 0xe, 0x66, 0x66, 0xd0, - 0x1, 0xa0, 0xc0, 0x2b, 0xd, 0x0, 0x0, 0xd0, - 0x1, 0xa1, 0xc1, 0x2b, 0xc, 0x0, 0x0, 0xd0, - 0x2, 0x99, 0xf5, 0x56, 0xd, 0x66, 0x66, 0xd0, - 0x0, 0xb, 0xe7, 0x30, 0xd, 0x0, 0x0, 0xd0, - 0x0, 0x38, 0xc0, 0xc6, 0xd, 0x66, 0x66, 0xb0, - 0x0, 0x90, 0xc0, 0x19, 0x1, 0xd2, 0x53, 0x0, - 0x6, 0x0, 0xc0, 0x0, 0x9, 0x60, 0xa, 0x70, - 0x0, 0x0, 0xc0, 0x0, 0x64, 0x0, 0x1, 0xe0, - 0x0, 0x0, 0x30, 0x1, 0x10, 0x0, 0x0, 0x20, - - /* U+984C "題" */ - 0x0, 0x30, 0x0, 0x60, 0x0, 0x0, 0x1, 0x40, - 0x0, 0xc6, 0x66, 0xd2, 0x76, 0x79, 0x66, 0x70, - 0x0, 0xb0, 0x0, 0xc0, 0x0, 0x54, 0x1, 0x0, - 0x0, 0xc6, 0x66, 0xc0, 0x2b, 0x76, 0x6e, 0x10, - 0x0, 0xc1, 0x11, 0xc0, 0x1a, 0x0, 0xc, 0x0, - 0x0, 0xb5, 0x55, 0x90, 0x1c, 0x66, 0x6c, 0x0, - 0x0, 0x0, 0x0, 0x16, 0x1b, 0x22, 0x2c, 0x0, - 0x5, 0x76, 0xd6, 0x66, 0x3b, 0x44, 0x4c, 0x0, - 0x0, 0xa0, 0xc0, 0x0, 0x1c, 0x55, 0x5c, 0x0, - 0x0, 0xb0, 0xc6, 0x88, 0x14, 0x40, 0x12, 0x0, - 0x2, 0xc0, 0xc0, 0x0, 0x8, 0x80, 0x85, 0x0, - 0x5, 0x57, 0xc0, 0x0, 0x56, 0x0, 0xd, 0x10, - 0x8, 0x1, 0xd6, 0x11, 0x20, 0x0, 0x2, 0x21, - 0x5, 0x0, 0x6, 0xcd, 0xdd, 0xde, 0xef, 0x90, - 0x10, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - - /* U+9854 "顔" */ - 0x0, 0x1, 0x80, 0x0, 0x0, 0x0, 0x0, 0x60, - 0x0, 0x0, 0x76, 0x6, 0x76, 0x6c, 0x66, 0x72, - 0x2, 0x96, 0x66, 0xd6, 0x10, 0x28, 0x0, 0x0, - 0x0, 0xa, 0x2, 0xb0, 0x39, 0x86, 0x66, 0xd0, - 0x0, 0x8, 0x36, 0x12, 0x2a, 0x0, 0x1, 0xb0, - 0x3, 0xb6, 0x67, 0x69, 0x5c, 0x66, 0x66, 0xb0, - 0x2, 0x90, 0x0, 0xa2, 0x2a, 0x0, 0x1, 0xb0, - 0x2, 0x90, 0x2a, 0x50, 0x2c, 0x66, 0x66, 0xb0, - 0x3, 0x83, 0x40, 0x49, 0x2a, 0x0, 0x1, 0xc0, - 0x3, 0x80, 0x5, 0xc3, 0x2a, 0x0, 0x1, 0xc0, - 0x4, 0x62, 0x65, 0x2, 0x3b, 0x66, 0x66, 0x90, - 0x7, 0x21, 0x0, 0x6e, 0x32, 0xe1, 0x63, 0x0, - 0x7, 0x0, 0x2a, 0x80, 0xb, 0x30, 0xb, 0x60, - 0x13, 0x25, 0x61, 0x0, 0x82, 0x0, 0x2, 0xd0, - 0x0, 0x0, 0x0, 0x2, 0x0, 0x0, 0x0, 0x10, - - /* U+9858 "願" */ - 0x1, 0x0, 0x0, 0x20, 0x0, 0x0, 0x6, 0x20, - 0x8, 0x76, 0x86, 0x96, 0x76, 0xc8, 0x66, 0x40, - 0x8, 0x30, 0xa1, 0x0, 0x0, 0xa0, 0x0, 0x0, - 0x8, 0x57, 0x96, 0xa1, 0xb6, 0x86, 0x6d, 0x40, - 0x8, 0x58, 0x0, 0xb0, 0xd0, 0x0, 0xb, 0x10, - 0x8, 0x4b, 0x66, 0xc0, 0xd6, 0x66, 0x6d, 0x10, - 0x8, 0x48, 0x0, 0xb0, 0xc0, 0x0, 0xb, 0x10, - 0x9, 0x3b, 0x76, 0xc0, 0xc6, 0x66, 0x6d, 0x10, - 0xa, 0x11, 0x92, 0x10, 0xc0, 0x0, 0xb, 0x10, - 0x9, 0x18, 0x93, 0x10, 0xd0, 0x0, 0xb, 0x10, - 0x7, 0x75, 0x92, 0xa0, 0xc6, 0x66, 0x6b, 0x10, - 0x42, 0x70, 0x92, 0x86, 0xb, 0x60, 0x64, 0x0, - 0x23, 0x13, 0xb2, 0x22, 0x69, 0x0, 0xa, 0x70, - 0x0, 0x7, 0xd0, 0x4, 0x60, 0x0, 0x1, 0xe0, - 0x0, 0x0, 0x0, 0x2, 0x0, 0x0, 0x0, 0x10, - - /* U+985E "類" */ - 0x0, 0x0, 0x92, 0x0, 0x0, 0x0, 0x0, 0x70, - 0x3, 0x70, 0xd0, 0xb5, 0x67, 0x6d, 0x76, 0x62, - 0x0, 0xb3, 0xd2, 0x90, 0x0, 0xa, 0x0, 0x10, - 0x5, 0x76, 0xea, 0x6d, 0x2c, 0x67, 0x56, 0xe1, - 0x2, 0x1d, 0xe7, 0x30, 0xd, 0x0, 0x0, 0xc0, - 0x0, 0xa3, 0xd0, 0xb6, 0xe, 0x66, 0x66, 0xc0, - 0x7, 0x10, 0xd0, 0x14, 0xd, 0x0, 0x0, 0xc0, - 0x0, 0x0, 0x73, 0xa0, 0xd, 0x66, 0x66, 0xc0, - 0x0, 0x0, 0xd2, 0x53, 0xd, 0x0, 0x0, 0xc0, - 0x8, 0x76, 0xe6, 0x6c, 0x4d, 0x0, 0x0, 0xd0, - 0x0, 0x3, 0xc3, 0x0, 0xc, 0x66, 0x66, 0xa0, - 0x0, 0xa, 0x46, 0xb2, 0x0, 0xd4, 0x64, 0x0, - 0x0, 0x48, 0x0, 0x58, 0x9, 0x60, 0xa, 0x70, - 0x4, 0x60, 0x0, 0x0, 0x73, 0x0, 0x1, 0xe0, - 0x2, 0x0, 0x0, 0x1, 0x0, 0x0, 0x0, 0x10, - - /* U+986F "顯" */ - 0x0, 0x10, 0x0, 0x2, 0x0, 0x0, 0x0, 0x71, - 0x0, 0xd6, 0x66, 0x6e, 0x67, 0x6d, 0x76, 0x63, - 0x0, 0xd6, 0x66, 0x6c, 0x0, 0xb, 0x0, 0x10, - 0x0, 0xc0, 0x0, 0xc, 0xc, 0x78, 0x67, 0xe1, - 0x0, 0xd6, 0x66, 0x6a, 0xc, 0x0, 0x0, 0xc0, - 0x0, 0x47, 0x0, 0x53, 0xd, 0x66, 0x66, 0xc0, - 0x0, 0x82, 0x21, 0x84, 0x1c, 0x0, 0x0, 0xc0, - 0x7, 0x5b, 0x49, 0x6b, 0x2d, 0x66, 0x66, 0xc0, - 0x0, 0x84, 0x2, 0x74, 0xc, 0x0, 0x0, 0xc0, - 0xc, 0x87, 0xad, 0x78, 0x6c, 0x0, 0x0, 0xc0, - 0x2, 0x0, 0x41, 0x1, 0x3c, 0x66, 0x66, 0xa0, - 0x0, 0x56, 0x17, 0x18, 0x10, 0xd3, 0x72, 0x0, - 0x7, 0x64, 0x85, 0x85, 0x86, 0x70, 0xc, 0x40, - 0x8, 0x11, 0x20, 0x10, 0x46, 0x0, 0x3, 0xc0, - 0x0, 0x0, 0x0, 0x0, 0x20, 0x0, 0x0, 0x10, - - /* U+98A8 "風" */ - 0x0, 0x9, 0x66, 0x66, 0x66, 0x67, 0x90, 0x0, - 0x0, 0xd, 0x0, 0x0, 0x0, 0x14, 0x80, 0x0, - 0x0, 0xd, 0x0, 0x35, 0x9c, 0xc5, 0x80, 0x0, - 0x0, 0xd, 0x36, 0x5d, 0x0, 0x4, 0x80, 0x0, - 0x0, 0xd, 0x0, 0xd, 0x0, 0x4, 0x80, 0x0, - 0x0, 0xd, 0xb, 0x6e, 0x66, 0xc4, 0x80, 0x0, - 0x0, 0xd, 0xd, 0xd, 0x2, 0xa4, 0x80, 0x0, - 0x0, 0xd, 0xd, 0xd, 0x2, 0xa3, 0x80, 0x0, - 0x0, 0xc, 0xe, 0x6e, 0x67, 0xa3, 0x80, 0x0, - 0x0, 0x1b, 0x3, 0xd, 0x1, 0x21, 0xa0, 0x0, - 0x0, 0x48, 0x0, 0xd, 0x0, 0x92, 0xc0, 0x20, - 0x0, 0x93, 0x23, 0x5e, 0x98, 0x8c, 0xa3, 0x70, - 0x1, 0x90, 0xda, 0x62, 0x0, 0xb, 0x3c, 0xa0, - 0x7, 0x0, 0x0, 0x0, 0x0, 0x0, 0x6, 0xd0, - 0x10, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x10, - - /* U+98DB "飛" */ - 0x0, 0x56, 0x66, 0x66, 0x69, 0x50, 0x0, 0x0, - 0x0, 0x11, 0x0, 0x10, 0x7, 0x20, 0xa2, 0x0, - 0x0, 0x0, 0x37, 0xa5, 0x7, 0x1a, 0x82, 0x0, - 0x0, 0x3, 0xe6, 0xa1, 0x7, 0x82, 0x0, 0x0, - 0x0, 0x7b, 0x90, 0xa1, 0x5, 0x66, 0xa1, 0x0, - 0x2, 0x12, 0x90, 0xa1, 0x1, 0xd1, 0x43, 0x60, - 0x0, 0x2, 0x90, 0xa1, 0x3, 0x7e, 0x74, 0x80, - 0x8, 0x67, 0xb6, 0xc7, 0x6d, 0x25, 0xdf, 0xc0, - 0x0, 0x3, 0x80, 0xa1, 0xc, 0x2, 0x82, 0x40, - 0x0, 0x5, 0x70, 0xa1, 0xc, 0x57, 0x30, 0x0, - 0x0, 0x7, 0x40, 0xa1, 0xa, 0x4a, 0x50, 0x0, - 0x0, 0xb, 0x0, 0xa1, 0x7, 0x51, 0xc0, 0x20, - 0x0, 0x37, 0x0, 0xa2, 0x1, 0xc0, 0x0, 0x70, - 0x1, 0x80, 0x0, 0xa2, 0x0, 0x4b, 0x40, 0xa0, - 0x6, 0x0, 0x0, 0x60, 0x0, 0x2, 0x8c, 0xc0, - - /* U+98DF "食" */ - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x0, 0x1e, 0x40, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x0, 0xb9, 0x70, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x8, 0xb0, 0x19, 0x10, 0x0, 0x0, - 0x0, 0x0, 0x7a, 0xa, 0x21, 0xb7, 0x0, 0x0, - 0x0, 0x8, 0x70, 0x5, 0x90, 0xa, 0xfa, 0x72, - 0x3, 0x72, 0xd6, 0x66, 0x76, 0x8c, 0x29, 0x80, - 0x1, 0x0, 0xe0, 0x0, 0x0, 0x3a, 0x0, 0x0, - 0x0, 0x0, 0xe6, 0x66, 0x66, 0x8a, 0x0, 0x0, - 0x0, 0x0, 0xe0, 0x0, 0x0, 0x3a, 0x0, 0x0, - 0x0, 0x0, 0xe6, 0x66, 0x66, 0x89, 0x30, 0x0, - 0x0, 0x0, 0xe0, 0x25, 0x10, 0xa, 0x90, 0x0, - 0x0, 0x0, 0xe0, 0x1, 0x89, 0x91, 0x0, 0x0, - 0x0, 0x0, 0xe0, 0x47, 0x31, 0xad, 0x50, 0x0, - 0x0, 0x0, 0xfc, 0x40, 0x0, 0x5, 0xf2, 0x0, - 0x0, 0x0, 0x40, 0x0, 0x0, 0x0, 0x31, 0x0, - - /* U+98EF "飯" */ - 0x0, 0x0, 0xb2, 0x0, 0x0, 0x0, 0x5, 0x0, - 0x0, 0x4, 0xd1, 0x0, 0x54, 0x68, 0xaa, 0x40, - 0x0, 0xb, 0x27, 0x91, 0x94, 0x0, 0x0, 0x0, - 0x0, 0x74, 0x60, 0x69, 0x93, 0x0, 0x0, 0x0, - 0x3, 0x60, 0x76, 0x1, 0x93, 0x0, 0x1, 0x0, - 0x14, 0x96, 0x67, 0xb1, 0x98, 0x66, 0x6b, 0x80, - 0x0, 0xc0, 0x0, 0xc0, 0x93, 0x40, 0xb, 0x10, - 0x0, 0xc6, 0x66, 0xd0, 0x93, 0x50, 0xb, 0x0, - 0x0, 0xc0, 0x0, 0xc0, 0xa2, 0x60, 0x56, 0x0, - 0x0, 0xc6, 0x66, 0xb0, 0xb0, 0x35, 0xb0, 0x0, - 0x0, 0xc0, 0x8, 0x0, 0xb0, 0xb, 0x60, 0x0, - 0x0, 0xc0, 0x19, 0xa1, 0x90, 0x3c, 0x90, 0x0, - 0x0, 0xda, 0x80, 0xa6, 0x21, 0x90, 0x97, 0x0, - 0x0, 0x93, 0x0, 0x5, 0x17, 0x0, 0xc, 0xa1, - 0x0, 0x0, 0x0, 0x20, 0x40, 0x0, 0x0, 0x30, - - /* U+98F2 "飲" */ - 0x0, 0x0, 0xa2, 0x0, 0x6, 0x60, 0x0, 0x0, - 0x0, 0x4, 0xe1, 0x0, 0xa, 0x50, 0x0, 0x0, - 0x0, 0xb, 0x28, 0x90, 0xc, 0x0, 0x0, 0x0, - 0x0, 0x65, 0x50, 0x79, 0x3c, 0x66, 0x6c, 0x60, - 0x2, 0x70, 0x75, 0x1, 0x81, 0x10, 0xc, 0x10, - 0x14, 0x86, 0x77, 0xa3, 0x70, 0xf2, 0x35, 0x0, - 0x0, 0xc0, 0x0, 0xc5, 0x0, 0xf1, 0x40, 0x0, - 0x0, 0xc6, 0x66, 0xd0, 0x1, 0xe3, 0x0, 0x0, - 0x0, 0xc0, 0x0, 0xc0, 0x3, 0xa5, 0x0, 0x0, - 0x0, 0xc6, 0x66, 0xb0, 0x6, 0x77, 0x0, 0x0, - 0x0, 0xc0, 0x8, 0x0, 0xa, 0x28, 0x20, 0x0, - 0x0, 0xc0, 0x28, 0xa0, 0x1b, 0x2, 0xb0, 0x0, - 0x0, 0xdb, 0x70, 0x90, 0x81, 0x0, 0x89, 0x0, - 0x0, 0x72, 0x0, 0x6, 0x20, 0x0, 0xb, 0xc2, - 0x0, 0x0, 0x0, 0x20, 0x0, 0x0, 0x0, 0x10, - - /* U+9928 "館" */ - 0x0, 0x0, 0xa1, 0x0, 0x0, 0x74, 0x0, 0x0, - 0x0, 0x5, 0xd0, 0x0, 0x20, 0xe, 0x20, 0x20, - 0x0, 0xc, 0x3a, 0x62, 0x96, 0x68, 0x66, 0xe3, - 0x0, 0x86, 0x30, 0xce, 0x30, 0x0, 0x4, 0x50, - 0x4, 0x60, 0xb1, 0x0, 0x41, 0x11, 0x28, 0x0, - 0x14, 0x96, 0x96, 0xa0, 0xb5, 0x44, 0x5c, 0x0, - 0x0, 0xc0, 0x0, 0xc0, 0xa2, 0x0, 0x1b, 0x0, - 0x0, 0xd6, 0x66, 0xc0, 0xa7, 0x66, 0x6b, 0x0, - 0x0, 0xc0, 0x0, 0xc0, 0xa2, 0x0, 0x1, 0x0, - 0x0, 0xd6, 0x66, 0xa0, 0xa7, 0x66, 0x6c, 0x60, - 0x0, 0xc0, 0x7, 0x0, 0xa2, 0x0, 0xa, 0x20, - 0x0, 0xc0, 0x19, 0x90, 0xa2, 0x0, 0xa, 0x20, - 0x1, 0xeb, 0x70, 0xa0, 0xa7, 0x66, 0x6c, 0x20, - 0x0, 0xa2, 0x0, 0x0, 0xb2, 0x0, 0x8, 0x10, - 0x0, 0x0, 0x0, 0x0, 0x30, 0x0, 0x0, 0x0, - - /* U+9996 "首" */ - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x16, 0x0, 0x0, 0xc2, 0x0, 0x0, - 0x0, 0x0, 0x7, 0xa0, 0x4, 0x90, 0x0, 0x0, - 0x0, 0x0, 0x1, 0xd0, 0x8, 0x0, 0x8, 0x30, - 0x6, 0x66, 0x66, 0x6e, 0x66, 0x66, 0x67, 0x50, - 0x0, 0x0, 0x0, 0x38, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, 0xb6, 0x86, 0x66, 0x6d, 0x30, 0x0, - 0x0, 0x0, 0xd0, 0x0, 0x0, 0xd, 0x0, 0x0, - 0x0, 0x0, 0xd0, 0x0, 0x0, 0xd, 0x0, 0x0, - 0x0, 0x0, 0xe6, 0x66, 0x66, 0x6e, 0x0, 0x0, - 0x0, 0x0, 0xd0, 0x0, 0x0, 0xd, 0x0, 0x0, - 0x0, 0x0, 0xe6, 0x66, 0x66, 0x6e, 0x0, 0x0, - 0x0, 0x0, 0xd0, 0x0, 0x0, 0xd, 0x0, 0x0, - 0x0, 0x0, 0xe6, 0x66, 0x66, 0x6e, 0x0, 0x0, - 0x0, 0x0, 0xd0, 0x0, 0x0, 0xd, 0x0, 0x0, - 0x0, 0x0, 0x20, 0x0, 0x0, 0x2, 0x0, 0x0, - - /* U+9999 "香" */ - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x0, 0x1, 0x49, 0xe5, 0x0, 0x0, - 0x14, 0x56, 0x7d, 0x75, 0x31, 0x0, 0x0, 0x0, - 0x0, 0x0, 0xc1, 0x0, 0x0, 0x10, 0x5, 0x66, - 0x66, 0x6d, 0x66, 0x66, 0x6e, 0x30, 0x10, 0x0, - 0x3c, 0xd4, 0x50, 0x0, 0x0, 0x0, 0x0, 0x2c, - 0x1c, 0x16, 0x70, 0x0, 0x0, 0x0, 0x3a, 0x10, - 0xc1, 0x6, 0xc5, 0x0, 0x0, 0x57, 0x20, 0x7, - 0x0, 0x8, 0xcf, 0x71, 0x52, 0xd, 0x66, 0x66, - 0x66, 0xe1, 0x30, 0x0, 0x0, 0xd0, 0x0, 0x0, - 0xc, 0x0, 0x0, 0x0, 0xd, 0x66, 0x66, 0x66, - 0xc0, 0x0, 0x0, 0x0, 0xd0, 0x0, 0x0, 0xc, - 0x0, 0x0, 0x0, 0xd, 0x0, 0x0, 0x0, 0xc0, - 0x0, 0x0, 0x0, 0xd6, 0x66, 0x66, 0x6d, 0x0, - 0x0, 0x0, 0x3, 0x0, 0x0, 0x0, 0x20, 0x0, - - /* U+99C4 "駄" */ - 0x0, 0x0, 0x0, 0x0, 0x0, 0x10, 0x0, 0x0, - 0x0, 0x96, 0x66, 0x6b, 0x0, 0x97, 0x0, 0x0, - 0x0, 0xd0, 0xa1, 0x0, 0x0, 0x93, 0x0, 0x0, - 0x0, 0xd0, 0xa1, 0x23, 0x0, 0x93, 0x0, 0x0, - 0x0, 0xe6, 0xc6, 0x64, 0x0, 0x92, 0x0, 0x30, - 0x0, 0xd0, 0xa1, 0x12, 0x76, 0xc9, 0x67, 0x80, - 0x0, 0xd6, 0xc6, 0x75, 0x0, 0xb6, 0x0, 0x0, - 0x0, 0xd0, 0xa1, 0x0, 0x0, 0xc7, 0x0, 0x0, - 0x0, 0xe5, 0x95, 0x5e, 0x10, 0xb6, 0x10, 0x0, - 0x0, 0x90, 0x0, 0xd, 0x3, 0x84, 0x50, 0x0, - 0x0, 0x24, 0x29, 0xc, 0x8, 0x30, 0xa0, 0x0, - 0x5, 0x54, 0xc7, 0x3a, 0xb, 0x0, 0xb1, 0x0, - 0xb, 0x46, 0x30, 0x58, 0x57, 0x60, 0x5a, 0x0, - 0x4, 0x1, 0x21, 0xb4, 0x90, 0x77, 0xe, 0x50, - 0x0, 0x0, 0x5f, 0x97, 0x10, 0x16, 0x4, 0xd2, - 0x0, 0x0, 0x0, 0x11, 0x0, 0x0, 0x0, 0x0, - - /* U+99C5 "駅" */ - 0x0, 0x53, 0x33, 0x38, 0x13, 0x0, 0x0, 0x50, - 0x0, 0xd3, 0xb5, 0x33, 0x2d, 0x66, 0x67, 0xc0, - 0x0, 0xc0, 0xa2, 0x31, 0x1c, 0x0, 0x2, 0xa0, - 0x0, 0xd6, 0xc7, 0x63, 0x1c, 0x0, 0x2, 0xa0, - 0x0, 0xc0, 0xa2, 0x20, 0x1c, 0x0, 0x2, 0xa0, - 0x0, 0xd6, 0xc7, 0x74, 0xd, 0x68, 0x67, 0xa0, - 0x0, 0xc0, 0xa2, 0x0, 0xc, 0x6, 0x0, 0x0, - 0x0, 0xd5, 0x95, 0x6d, 0x2b, 0x7, 0x0, 0x0, - 0x0, 0x80, 0x0, 0x2a, 0x39, 0x8, 0x0, 0x0, - 0x1, 0x23, 0x39, 0x49, 0x56, 0x6, 0x50, 0x0, - 0x7, 0x45, 0xc4, 0x87, 0x82, 0x1, 0xc0, 0x0, - 0xd, 0x37, 0x30, 0x84, 0xa0, 0x0, 0x98, 0x0, - 0x4, 0x0, 0x10, 0xd4, 0x50, 0x0, 0xd, 0x80, - 0x0, 0x0, 0x5f, 0x77, 0x0, 0x0, 0x2, 0xa3, - 0x0, 0x0, 0x1, 0x20, 0x0, 0x0, 0x0, 0x0, - - /* U+9A12 "騒" */ - 0x0, 0x30, 0x0, 0x32, 0x12, 0x22, 0x27, 0x0, - 0x0, 0xe6, 0xd6, 0x63, 0x48, 0x44, 0x6e, 0x20, - 0x0, 0xd0, 0xc0, 0x20, 0x4, 0x40, 0x96, 0x0, - 0x0, 0xe6, 0xd6, 0x83, 0x0, 0xa5, 0xc0, 0x0, - 0x0, 0xd0, 0xc0, 0x0, 0x0, 0x3f, 0x40, 0x0, - 0x0, 0xd6, 0xd6, 0xa2, 0x4, 0x94, 0xca, 0x50, - 0x0, 0xd0, 0xc0, 0x1, 0x54, 0xd, 0x6, 0x71, - 0x0, 0xe5, 0xc5, 0x6b, 0x56, 0x6e, 0x69, 0x30, - 0x0, 0x40, 0x0, 0x39, 0x66, 0xd, 0xc, 0x10, - 0x0, 0x23, 0x38, 0x48, 0x66, 0xd, 0xc, 0x0, - 0x6, 0x36, 0xa8, 0x76, 0x79, 0x6e, 0x6d, 0x0, - 0xc, 0x29, 0x30, 0x84, 0x10, 0xd, 0x23, 0x0, - 0x14, 0x0, 0x0, 0xc1, 0x0, 0xd, 0x3c, 0x60, - 0x0, 0x2, 0x7e, 0x81, 0xdc, 0xa7, 0x41, 0xc0, - 0x0, 0x0, 0x2, 0x0, 0x20, 0x0, 0x0, 0x0, - - /* U+9A13 "験" */ - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x20, 0x0, 0x50, 0x0, 0x5a, 0x0, 0x0, - 0x0, 0xd6, 0xd6, 0x62, 0x0, 0xc8, 0x0, 0x0, - 0x0, 0xc0, 0xc0, 0x20, 0x7, 0x80, 0x80, 0x0, - 0x0, 0xd6, 0xd6, 0x71, 0x59, 0x0, 0x4d, 0x61, - 0x0, 0xc0, 0xc0, 0x5, 0x88, 0x6a, 0x78, 0x60, - 0x0, 0xd6, 0xd6, 0x91, 0x0, 0xd, 0x0, 0x0, - 0x0, 0xc0, 0xc0, 0x0, 0xb6, 0x6e, 0x6d, 0x20, - 0x0, 0xd5, 0xc5, 0x96, 0xc0, 0xd, 0xc, 0x0, - 0x0, 0x60, 0x0, 0x84, 0xc0, 0xd, 0xc, 0x0, - 0x1, 0x24, 0x29, 0x93, 0xc6, 0x6d, 0x6d, 0x0, - 0xa, 0x55, 0xa8, 0xb2, 0x30, 0x4b, 0x2, 0x0, - 0x2d, 0x36, 0x20, 0xb1, 0x0, 0xb3, 0x60, 0x0, - 0x12, 0x0, 0x1, 0xc0, 0x8, 0x50, 0x85, 0x0, - 0x0, 0x2, 0x7e, 0x62, 0x83, 0x0, 0xb, 0xb1, - 0x0, 0x0, 0x1, 0x13, 0x0, 0x0, 0x0, 0x10, - - /* U+9A57 "驗" */ - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x20, 0x0, 0x50, 0x0, 0x77, 0x0, 0x0, - 0x0, 0xd6, 0xc6, 0x71, 0x0, 0xc6, 0x0, 0x0, - 0x0, 0xc0, 0xc0, 0x10, 0x8, 0x44, 0x70, 0x0, - 0x0, 0xd6, 0xd6, 0x80, 0x38, 0x0, 0x99, 0x0, - 0x0, 0xc0, 0xc0, 0x3, 0x86, 0x66, 0xaa, 0xc2, - 0x0, 0xd6, 0xd6, 0x83, 0x0, 0x0, 0x1, 0x0, - 0x0, 0xc0, 0xc0, 0x1, 0xc6, 0xc6, 0x8c, 0x40, - 0x0, 0xd5, 0xc4, 0xa5, 0xb0, 0xb5, 0x49, 0x10, - 0x0, 0xa0, 0x0, 0xb2, 0xb0, 0xb5, 0x49, 0x10, - 0x1, 0x23, 0x26, 0xb1, 0xd6, 0xa6, 0x8b, 0x10, - 0x7, 0x63, 0xa8, 0xc0, 0x2c, 0x10, 0x65, 0x0, - 0xc, 0x54, 0x40, 0xc0, 0x5a, 0x0, 0xa2, 0x0, - 0x13, 0x0, 0x2, 0xb0, 0xb5, 0x70, 0xa9, 0x10, - 0x0, 0x1, 0x7f, 0x48, 0x30, 0xa7, 0x13, 0x90, - 0x0, 0x0, 0x1, 0x21, 0x0, 0x12, 0x0, 0x10, - - /* U+9AD4 "體" */ - 0x0, 0x10, 0x3, 0x0, 0x1, 0xb0, 0xb0, 0x0, - 0x0, 0xc6, 0x6d, 0x30, 0x1, 0xc0, 0xc0, 0x30, - 0x0, 0xc6, 0x7b, 0x0, 0xd6, 0xd5, 0xd7, 0xc0, - 0x0, 0xc3, 0x7b, 0x0, 0xd4, 0xd3, 0xc6, 0x90, - 0x3, 0xc3, 0x7b, 0x20, 0xd3, 0xc2, 0xc5, 0x90, - 0xb, 0x76, 0x67, 0xc5, 0xd4, 0xd3, 0xc6, 0xa0, - 0x47, 0x86, 0x69, 0x60, 0x71, 0x11, 0x12, 0x60, - 0x0, 0xd0, 0xa, 0x25, 0x76, 0x66, 0x66, 0x72, - 0x0, 0xd6, 0x6c, 0x10, 0x67, 0x66, 0x6a, 0x50, - 0x0, 0xd0, 0xa, 0x10, 0x84, 0x0, 0x9, 0x30, - 0x0, 0xd6, 0x6c, 0x10, 0x88, 0x66, 0x6b, 0x30, - 0x0, 0xd0, 0xa, 0x10, 0x46, 0x0, 0x77, 0x0, - 0x0, 0xd0, 0xa, 0x10, 0x4, 0x80, 0xa1, 0x0, - 0x0, 0xd1, 0x8e, 0x16, 0x66, 0x86, 0xa6, 0xc3, - 0x0, 0x30, 0x1, 0x2, 0x0, 0x0, 0x0, 0x0, - - /* U+9AD8 "高" */ - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x2b, 0x10, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x63, 0x0, 0x0, 0x15, 0x6, 0x76, - 0x66, 0x66, 0x66, 0x66, 0x66, 0x60, 0x0, 0x8, - 0x66, 0x66, 0x66, 0x80, 0x0, 0x0, 0x0, 0xd1, - 0x0, 0x0, 0x38, 0x0, 0x0, 0x0, 0xd, 0x66, - 0x66, 0x68, 0x80, 0x0, 0x0, 0x0, 0x90, 0x0, - 0x0, 0x24, 0x0, 0x0, 0xa, 0x66, 0x66, 0x66, - 0x66, 0x66, 0xd2, 0x0, 0xd0, 0x2, 0x0, 0x0, - 0x30, 0xe, 0x0, 0xd, 0x0, 0xe6, 0x66, 0x7d, - 0x0, 0xe0, 0x0, 0xd0, 0xd, 0x0, 0x1, 0xb0, - 0xe, 0x0, 0xd, 0x0, 0xe6, 0x66, 0x6b, 0x0, - 0xe0, 0x0, 0xd0, 0x9, 0x0, 0x1, 0x60, 0xe, - 0x0, 0xd, 0x0, 0x0, 0x0, 0x0, 0x6b, 0xd0, - 0x0, 0x30, 0x0, 0x0, 0x0, 0x0, 0x33, 0x0, - - /* U+9AEA "髪" */ - 0x0, 0x2, 0x0, 0x4, 0x0, 0x0, 0x30, 0x0, - 0x0, 0xe, 0x66, 0x66, 0x10, 0x6, 0xc3, 0x0, - 0x0, 0xe, 0x66, 0x6a, 0x3, 0xa6, 0x0, 0x0, - 0x0, 0xd, 0x0, 0x14, 0x24, 0x0, 0x5b, 0x0, - 0x0, 0xe, 0x55, 0x55, 0x10, 0x29, 0x71, 0x0, - 0x5, 0x7a, 0x96, 0x67, 0x95, 0x50, 0x4, 0x60, - 0x0, 0x8, 0x80, 0x73, 0x0, 0x3, 0xa9, 0x40, - 0x0, 0xcb, 0x76, 0x5c, 0x16, 0x75, 0x0, 0x0, - 0x0, 0x20, 0x0, 0x77, 0x10, 0x0, 0x3, 0x0, - 0x6, 0x65, 0x56, 0xd7, 0x55, 0x55, 0x6a, 0x70, - 0x0, 0x0, 0x9, 0xa6, 0x66, 0x68, 0x10, 0x0, - 0x0, 0x0, 0x78, 0x60, 0x0, 0xa9, 0x10, 0x0, - 0x0, 0x7, 0x60, 0x8, 0x5c, 0x50, 0x0, 0x0, - 0x1, 0x73, 0x0, 0x29, 0xab, 0x40, 0x0, 0x0, - 0x3, 0x2, 0x67, 0x61, 0x1, 0x7c, 0xca, 0x70, - 0x0, 0x33, 0x0, 0x0, 0x0, 0x0, 0x14, 0x10, - - /* U+9B5A "魚" */ - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, 0xb, 0x60, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x6, 0xc1, 0x0, 0x60, 0x0, 0x0, 0x0, - 0x3, 0xc6, 0x66, 0xbc, 0x20, 0x0, 0x0, 0x3, - 0xa0, 0x0, 0x9, 0x0, 0x10, 0x0, 0x3, 0x9b, - 0x66, 0x6b, 0x66, 0x6e, 0x50, 0x4, 0x41, 0xb0, - 0x0, 0xe0, 0x0, 0xd1, 0x0, 0x0, 0x1b, 0x0, - 0xe, 0x0, 0xd, 0x10, 0x0, 0x1, 0xd6, 0x66, - 0xe6, 0x66, 0xe1, 0x0, 0x0, 0x1b, 0x0, 0xe, - 0x0, 0xd, 0x10, 0x0, 0x1, 0xd6, 0x66, 0xd6, - 0x66, 0xe1, 0x0, 0x0, 0x16, 0x0, 0x0, 0x0, - 0x5, 0x0, 0x0, 0x6, 0x4, 0x30, 0x56, 0x1, - 0x92, 0x0, 0x5, 0xa0, 0xe, 0x0, 0xc5, 0x2, - 0xf4, 0x3, 0xe2, 0x0, 0xd2, 0x6, 0x70, 0x8, - 0x80, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - - /* U+9CE5 "鳥" */ - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, 0xc, 0x30, 0x0, 0x0, 0x0, 0x0, - 0x2, 0x3, 0x50, 0x0, 0x30, 0x0, 0x0, 0x0, - 0xd6, 0x66, 0x66, 0x6c, 0x50, 0x0, 0x0, 0xd, - 0x66, 0x66, 0x66, 0xc2, 0x0, 0x0, 0x0, 0xd0, - 0x0, 0x0, 0xa, 0x20, 0x0, 0x0, 0xd, 0x66, - 0x66, 0x66, 0xc3, 0x0, 0x0, 0x0, 0xd0, 0x0, - 0x0, 0x2, 0x0, 0x62, 0x0, 0xd, 0x66, 0x66, - 0x66, 0x66, 0x66, 0x40, 0x0, 0xd6, 0x66, 0x66, - 0x66, 0x67, 0xc0, 0x0, 0x6, 0x0, 0x0, 0x3, - 0x0, 0x4a, 0x0, 0x3, 0x4, 0x4, 0x70, 0x3b, - 0x6, 0x80, 0x0, 0x80, 0xa4, 0xa, 0x60, 0x96, - 0x85, 0x0, 0x78, 0x5, 0x80, 0x24, 0x11, 0x1c, - 0x30, 0x9, 0x10, 0x1, 0x0, 0x3, 0x9d, 0xd0, - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x61, 0x0, - - /* U+9E97 "麗" */ - 0x2, 0x33, 0x33, 0x54, 0x23, 0x33, 0x38, 0x10, - 0x2, 0x73, 0x33, 0x62, 0x27, 0x33, 0x63, 0x10, - 0x0, 0xc6, 0x86, 0xd0, 0xe, 0x86, 0xd2, 0x0, - 0x0, 0xc0, 0x81, 0xc0, 0xd, 0x29, 0xc0, 0x0, - 0x0, 0xa0, 0x10, 0x96, 0x6a, 0x2, 0x94, 0x0, - 0x0, 0x79, 0x66, 0xa6, 0x79, 0x66, 0x79, 0x20, - 0x0, 0x76, 0x0, 0xc0, 0x9, 0x20, 0x23, 0x0, - 0x0, 0x7a, 0x66, 0xd6, 0x6b, 0x76, 0x9a, 0x0, - 0x0, 0x7a, 0x66, 0xc6, 0x6b, 0x76, 0x97, 0x0, - 0x0, 0x85, 0xb, 0x0, 0x8, 0x40, 0x21, 0x0, - 0x0, 0xa3, 0xd, 0x68, 0x89, 0x25, 0xc8, 0x0, - 0x0, 0xc0, 0xc, 0x0, 0x9, 0x73, 0x0, 0x50, - 0x2, 0x70, 0xc, 0x47, 0x48, 0x20, 0x0, 0xb0, - 0x7, 0x0, 0x1d, 0x60, 0x5, 0xdc, 0xcd, 0xc0, - 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - - /* U+9EBC "麼" */ - 0x0, 0x0, 0x0, 0x5, 0x70, 0x0, 0x0, 0x0, - 0x0, 0x50, 0x0, 0x0, 0xb2, 0x0, 0x8, 0x40, - 0x0, 0xd6, 0x66, 0x96, 0x66, 0x68, 0x66, 0x50, - 0x0, 0xc0, 0x0, 0xd1, 0x0, 0x1c, 0x0, 0x0, - 0x0, 0xc3, 0x77, 0xd7, 0x57, 0x8d, 0x68, 0x40, - 0x0, 0xc0, 0xa, 0xd7, 0x10, 0xba, 0x70, 0x0, - 0x0, 0xc0, 0x65, 0xc3, 0x77, 0x6a, 0x4a, 0x20, - 0x0, 0xc5, 0x30, 0xc0, 0x33, 0x29, 0x5, 0x70, - 0x0, 0xb0, 0x0, 0x27, 0xb0, 0x0, 0x0, 0x0, - 0x0, 0xb0, 0x4, 0x73, 0x0, 0x5e, 0x20, 0x0, - 0x1, 0x90, 0x9d, 0x97, 0x6b, 0x81, 0x0, 0x0, - 0x4, 0x50, 0x0, 0x6, 0x71, 0x2, 0x60, 0x0, - 0x8, 0x0, 0x37, 0x73, 0x34, 0x55, 0xb6, 0x0, - 0x6, 0x0, 0x9d, 0xa7, 0x53, 0x10, 0x2b, 0x0, - 0x20, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - - /* U+9EC4 "黄" */ - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, 0xc2, 0x0, 0xb3, 0x0, 0x0, 0x0, - 0x0, 0xd, 0x0, 0xc, 0x10, 0x72, 0x0, 0x7, - 0x66, 0xe6, 0x66, 0xd6, 0x66, 0x40, 0x0, 0x0, - 0xd, 0x0, 0xc, 0x10, 0x4, 0x3, 0x76, 0x66, - 0xa6, 0xa6, 0x96, 0x66, 0xa6, 0x0, 0x1, 0x0, - 0xd, 0x0, 0x2, 0x0, 0x0, 0x0, 0xc6, 0x66, - 0xe6, 0x66, 0xc5, 0x0, 0x0, 0xc, 0x10, 0xd, - 0x0, 0xb, 0x20, 0x0, 0x0, 0xc6, 0x66, 0xe6, - 0x66, 0xc2, 0x0, 0x0, 0xc, 0x10, 0xd, 0x0, - 0xb, 0x20, 0x0, 0x0, 0xc6, 0x66, 0xd6, 0x66, - 0xc2, 0x0, 0x0, 0x6, 0x2c, 0x30, 0x4, 0x44, - 0x0, 0x0, 0x0, 0x3d, 0x70, 0x0, 0x3, 0xb9, - 0x10, 0x0, 0x89, 0x10, 0x0, 0x0, 0x0, 0x9d, - 0x0, 0x51, 0x0, 0x0, 0x0, 0x0, 0x0, 0x50, - - /* U+9ED2 "黒" */ - 0x0, 0x30, 0x0, 0x0, 0x0, 0x3, 0x0, 0x0, - 0xe6, 0x66, 0x7b, 0x66, 0x6e, 0x40, 0x0, 0xd0, - 0x0, 0x2a, 0x0, 0xd, 0x0, 0x0, 0xd6, 0x66, - 0x7c, 0x66, 0x6e, 0x0, 0x0, 0xd0, 0x0, 0x2a, - 0x0, 0xd, 0x0, 0x0, 0xe6, 0x66, 0x7c, 0x66, - 0x6e, 0x0, 0x0, 0x60, 0x0, 0x2a, 0x0, 0x3, - 0x0, 0x4, 0x66, 0x66, 0x7c, 0x66, 0x6d, 0x70, - 0x1, 0x10, 0x0, 0x2a, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x2a, 0x0, 0x1, 0xd3, 0x57, 0x66, - 0x66, 0x66, 0x66, 0x67, 0x64, 0x0, 0x60, 0x35, - 0x0, 0x90, 0x8, 0x20, 0x3, 0x90, 0xd, 0x0, - 0x87, 0x4, 0xd0, 0xd, 0x50, 0xa, 0x10, 0x36, - 0x0, 0xc0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, - - /* U+9EDE "點" */ - 0x3, 0x0, 0x0, 0x30, 0x0, 0xa3, 0x0, 0x0, - 0x9, 0x66, 0xc6, 0xd2, 0x0, 0xd0, 0x0, 0x0, - 0x9, 0x42, 0xb8, 0xc0, 0x0, 0xd0, 0x0, 0x0, - 0x9, 0x2a, 0xc4, 0xc0, 0x0, 0xd5, 0x56, 0xa0, - 0x9, 0x67, 0xd6, 0xd0, 0x0, 0xd0, 0x0, 0x0, - 0x6, 0x1, 0xb0, 0x50, 0x0, 0xd0, 0x0, 0x0, - 0x0, 0x11, 0xb1, 0x70, 0x0, 0xd0, 0x0, 0x0, - 0x4, 0x65, 0xc5, 0x51, 0x96, 0xe6, 0x6b, 0x10, - 0x0, 0x1, 0xb0, 0x41, 0xc0, 0x0, 0xd, 0x0, - 0x4, 0x69, 0xa5, 0x10, 0xc0, 0x0, 0xd, 0x0, - 0xb, 0x50, 0x0, 0x40, 0xc0, 0x0, 0xd, 0x0, - 0x2, 0x6, 0x9, 0x38, 0xc0, 0x0, 0xd, 0x0, - 0x9, 0x9, 0x2a, 0x8, 0xd6, 0x66, 0x6d, 0x0, - 0x2a, 0x2, 0x0, 0x0, 0xc0, 0x0, 0xd, 0x0, - 0x0, 0x0, 0x0, 0x0, 0x40, 0x0, 0x1, 0x0, - - /* U+9EE8 "黨" */ - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x2, 0x50, 0xb, 0x30, 0x18, 0x0, 0x0, - 0x0, 0x0, 0x88, 0xb, 0x0, 0x96, 0x0, 0x0, - 0x0, 0x95, 0x58, 0x5b, 0x57, 0x75, 0x5a, 0x70, - 0x6, 0x70, 0x47, 0x66, 0x66, 0x91, 0x18, 0x10, - 0x8, 0x10, 0x56, 0x0, 0x0, 0xc0, 0x10, 0x0, - 0x0, 0x0, 0x5a, 0x66, 0x66, 0xc0, 0x0, 0x0, - 0x0, 0xa, 0x66, 0x66, 0x66, 0x66, 0xb2, 0x0, - 0x0, 0xd, 0x8, 0x18, 0x30, 0x90, 0xc0, 0x0, - 0x0, 0xd, 0x3, 0x48, 0x35, 0x20, 0xc0, 0x0, - 0x0, 0xd, 0x66, 0x6b, 0x86, 0x66, 0xa0, 0x0, - 0x0, 0x47, 0x55, 0x5b, 0x85, 0x55, 0x97, 0x0, - 0x5, 0x66, 0x66, 0x6b, 0x86, 0x66, 0x6b, 0x80, - 0x1, 0x13, 0x2, 0x30, 0x5, 0x0, 0x13, 0x0, - 0x0, 0x94, 0x0, 0xb0, 0x9, 0x20, 0xb, 0x10, - 0x2, 0x70, 0x0, 0x30, 0x2, 0x0, 0x3, 0x0, - - /* U+9F13 "鼓" */ - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, 0xb4, 0x0, 0x0, 0xd, 0x10, 0x0, - 0x0, 0x0, 0xc0, 0x0, 0x20, 0xd, 0x0, 0x0, - 0x7, 0x66, 0xd6, 0x67, 0x60, 0xd, 0x0, 0x20, - 0x0, 0x0, 0xc0, 0x0, 0x57, 0x6e, 0x66, 0xa1, - 0x1, 0x86, 0xb6, 0x6a, 0x30, 0xd, 0x0, 0x0, - 0x0, 0x0, 0x0, 0x1, 0x0, 0xd, 0x0, 0x0, - 0x0, 0xd6, 0x66, 0x6e, 0x38, 0x69, 0x6b, 0x90, - 0x0, 0xd1, 0x0, 0x1b, 0x4, 0x10, 0xd, 0x10, - 0x0, 0xd6, 0x66, 0x6c, 0x0, 0x70, 0x59, 0x0, - 0x0, 0x70, 0x0, 0x25, 0x0, 0x81, 0xc1, 0x0, - 0x0, 0x26, 0x1, 0xd0, 0x0, 0x2e, 0x60, 0x0, - 0x0, 0xb, 0x4, 0x20, 0x0, 0x6d, 0x80, 0x0, - 0x0, 0x14, 0x48, 0x76, 0x47, 0x70, 0x9b, 0x10, - 0x1e, 0xc8, 0x41, 0x2, 0x73, 0x0, 0x8, 0xd3, - 0x0, 0x0, 0x0, 0x23, 0x0, 0x0, 0x0, 0x0, - - /* U+9F3B "鼻" */ - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, 0xc, 0x10, 0x1, 0x0, 0x0, 0x0, - 0xb, 0x67, 0x76, 0x66, 0xe1, 0x0, 0x0, 0x0, - 0xc6, 0x66, 0x66, 0x6c, 0x0, 0x0, 0x0, 0xc, - 0x10, 0x0, 0x0, 0xc0, 0x0, 0x0, 0x0, 0xc6, - 0x66, 0x66, 0x6c, 0x0, 0x0, 0x0, 0xc, 0x66, - 0x66, 0x66, 0xc0, 0x0, 0x0, 0xb, 0x65, 0x55, - 0x85, 0x55, 0xb5, 0x0, 0x0, 0xd6, 0x66, 0x6d, - 0x66, 0x6c, 0x20, 0x0, 0xc, 0x0, 0x0, 0xb0, - 0x0, 0xa2, 0x0, 0x0, 0xd6, 0x66, 0x68, 0x66, - 0x6c, 0x20, 0x4, 0x66, 0x66, 0x66, 0x66, 0x66, - 0x67, 0xc1, 0x11, 0x0, 0xa5, 0x0, 0xc, 0x0, - 0x0, 0x0, 0x0, 0x2c, 0x0, 0x0, 0xc0, 0x0, - 0x0, 0x0, 0x3a, 0x20, 0x0, 0xc, 0x0, 0x0, - 0x0, 0x33, 0x0, 0x0, 0x0, 0x40, 0x0, 0x0, - - /* U+F001 "" */ - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x49, 0xdc, - 0x0, 0x0, 0x0, 0x0, 0x16, 0xbf, 0xff, 0xff, - 0x0, 0x0, 0x3, 0x8d, 0xff, 0xff, 0xff, 0xff, - 0x0, 0x0, 0xcf, 0xff, 0xff, 0xff, 0xff, 0xff, - 0x0, 0x0, 0xff, 0xff, 0xff, 0xff, 0xc7, 0xff, - 0x0, 0x0, 0xff, 0xff, 0xea, 0x51, 0x0, 0xff, - 0x0, 0x0, 0xff, 0x83, 0x0, 0x0, 0x0, 0xff, - 0x0, 0x0, 0xff, 0x0, 0x0, 0x0, 0x0, 0xff, - 0x0, 0x0, 0xff, 0x0, 0x0, 0x0, 0x0, 0xff, - 0x0, 0x0, 0xff, 0x0, 0x0, 0x0, 0x0, 0xff, - 0x0, 0x0, 0xff, 0x0, 0x0, 0x2b, 0xff, 0xff, - 0x0, 0x0, 0xff, 0x0, 0x0, 0xdf, 0xff, 0xff, - 0x2b, 0xff, 0xff, 0x0, 0x0, 0xdf, 0xff, 0xfd, - 0xdf, 0xff, 0xff, 0x0, 0x0, 0x2b, 0xff, 0xb2, - 0xdf, 0xff, 0xfd, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x2b, 0xff, 0xb2, 0x0, 0x0, 0x0, 0x0, 0x0, - - /* U+F008 "" */ - 0xd0, 0xf, 0xff, 0xff, 0xff, 0xff, 0xf0, 0xd, - 0xff, 0xff, 0xc8, 0x88, 0x88, 0x8c, 0xff, 0xff, - 0xf0, 0xf, 0x80, 0x0, 0x0, 0x8, 0xf0, 0xf, - 0xf0, 0xf, 0x80, 0x0, 0x0, 0x8, 0xf0, 0xf, - 0xff, 0xff, 0x80, 0x0, 0x0, 0x8, 0xff, 0xff, - 0xf0, 0xf, 0xec, 0xcc, 0xcc, 0xce, 0xf0, 0xf, - 0xf0, 0xf, 0xec, 0xcc, 0xcc, 0xce, 0xf0, 0xf, - 0xff, 0xff, 0x80, 0x0, 0x0, 0x8, 0xff, 0xff, - 0xf0, 0xf, 0x80, 0x0, 0x0, 0x8, 0xf0, 0xf, - 0xf0, 0xf, 0x80, 0x0, 0x0, 0x8, 0xf0, 0xf, - 0xff, 0xff, 0xc8, 0x88, 0x88, 0x8c, 0xff, 0xff, - 0xd0, 0xf, 0xff, 0xff, 0xff, 0xff, 0xf0, 0xd, - - /* U+F00B "" */ - 0xdf, 0xff, 0x73, 0xff, 0xff, 0xff, 0xff, 0xfd, - 0xff, 0xff, 0xa5, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xa5, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xdf, 0xff, 0x73, 0xff, 0xff, 0xff, 0xff, 0xfd, - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0xdf, 0xff, 0x73, 0xff, 0xff, 0xff, 0xff, 0xfd, - 0xff, 0xff, 0xa5, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xa5, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xdf, 0xff, 0x73, 0xff, 0xff, 0xff, 0xff, 0xfd, - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0xdf, 0xff, 0x73, 0xff, 0xff, 0xff, 0xff, 0xfd, - 0xff, 0xff, 0xa5, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xa5, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xdf, 0xff, 0x73, 0xff, 0xff, 0xff, 0xff, 0xfd, - - /* U+F00C "" */ - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xa, 0xb1, - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xbf, 0xfc, - 0x0, 0x0, 0x0, 0x0, 0x0, 0xb, 0xff, 0xfb, - 0x0, 0x0, 0x0, 0x0, 0x0, 0xbf, 0xff, 0xc0, - 0x1b, 0xa0, 0x0, 0x0, 0xb, 0xff, 0xfc, 0x0, - 0xcf, 0xfb, 0x0, 0x0, 0xbf, 0xff, 0xc0, 0x0, - 0xbf, 0xff, 0xb0, 0xb, 0xff, 0xfc, 0x0, 0x0, - 0xc, 0xff, 0xfb, 0xbf, 0xff, 0xc0, 0x0, 0x0, - 0x0, 0xcf, 0xff, 0xff, 0xfb, 0x0, 0x0, 0x0, - 0x0, 0xc, 0xff, 0xff, 0xb0, 0x0, 0x0, 0x0, - 0x0, 0x0, 0xbf, 0xfb, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, 0xb, 0xb0, 0x0, 0x0, 0x0, 0x0, - - /* U+F00D "" */ - 0x3, 0x0, 0x0, 0x0, 0x3, 0x8, 0xfc, 0x10, - 0x0, 0x1c, 0xf8, 0xff, 0xfc, 0x10, 0x1c, 0xff, - 0xf5, 0xff, 0xfc, 0x2c, 0xff, 0xf5, 0x5, 0xff, - 0xff, 0xff, 0xf5, 0x0, 0x5, 0xff, 0xff, 0xf5, - 0x0, 0x0, 0x1d, 0xff, 0xfd, 0x10, 0x0, 0x1c, - 0xff, 0xff, 0xfc, 0x10, 0x1c, 0xff, 0xf9, 0xff, - 0xfc, 0x1c, 0xff, 0xf5, 0x5, 0xff, 0xfc, 0xdf, - 0xf5, 0x0, 0x5, 0xff, 0xd1, 0xa4, 0x0, 0x0, - 0x4, 0xa1, - - /* U+F011 "" */ - 0x0, 0x0, 0x0, 0x4f, 0xe0, 0x0, 0x0, 0x0, - 0x0, 0x2, 0x10, 0x6f, 0xf1, 0x3, 0x10, 0x0, - 0x0, 0x5f, 0xd0, 0x6f, 0xf1, 0x3f, 0xd1, 0x0, - 0x3, 0xff, 0xf1, 0x6f, 0xf1, 0x5f, 0xfd, 0x0, - 0xd, 0xff, 0x40, 0x6f, 0xf1, 0x9, 0xff, 0x70, - 0x4f, 0xf7, 0x0, 0x6f, 0xf1, 0x0, 0xcf, 0xe0, - 0x9f, 0xf0, 0x0, 0x6f, 0xf1, 0x0, 0x5f, 0xf3, - 0xbf, 0xc0, 0x0, 0x6f, 0xf1, 0x0, 0x2f, 0xf5, - 0xbf, 0xc0, 0x0, 0x4f, 0xe0, 0x0, 0x1f, 0xf6, - 0xaf, 0xe0, 0x0, 0x0, 0x0, 0x0, 0x4f, 0xf4, - 0x6f, 0xf4, 0x0, 0x0, 0x0, 0x0, 0xaf, 0xf0, - 0xf, 0xfe, 0x10, 0x0, 0x0, 0x5, 0xff, 0xa0, - 0x6, 0xff, 0xd3, 0x0, 0x0, 0x7f, 0xff, 0x20, - 0x0, 0x9f, 0xff, 0xda, 0xbe, 0xff, 0xf4, 0x0, - 0x0, 0x6, 0xff, 0xff, 0xff, 0xfd, 0x30, 0x0, - 0x0, 0x0, 0x17, 0xbd, 0xca, 0x50, 0x0, 0x0, - - /* U+F013 "" */ - 0x0, 0x0, 0x0, 0x8b, 0xb8, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0x0, - 0x0, 0x30, 0x6, 0xff, 0xff, 0x60, 0x3, 0x0, - 0x4, 0xfd, 0xdf, 0xff, 0xff, 0xfd, 0xef, 0x40, - 0xd, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xd0, - 0x4f, 0xff, 0xff, 0xf9, 0x9f, 0xff, 0xff, 0xf4, - 0x8, 0xff, 0xff, 0x20, 0x2, 0xff, 0xff, 0x80, - 0x0, 0xff, 0xf9, 0x0, 0x0, 0x9f, 0xff, 0x0, - 0x0, 0xff, 0xf9, 0x0, 0x0, 0x9f, 0xff, 0x0, - 0x8, 0xff, 0xff, 0x20, 0x2, 0xff, 0xff, 0x80, - 0x4f, 0xff, 0xff, 0xf9, 0x9f, 0xff, 0xff, 0xf4, - 0xd, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xd0, - 0x4, 0xfe, 0xdf, 0xff, 0xff, 0xfd, 0xdf, 0x40, - 0x0, 0x30, 0x6, 0xff, 0xff, 0x60, 0x3, 0x0, - 0x0, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x0, 0x8b, 0xb8, 0x0, 0x0, 0x0, - - /* U+F015 "" */ - 0x0, 0x0, 0x0, 0x3, 0xdd, 0x30, 0x3f, 0xf3, - 0x0, 0x0, 0x0, 0x0, 0x6f, 0xff, 0xf5, 0x4f, - 0xf4, 0x0, 0x0, 0x0, 0x9, 0xff, 0x99, 0xff, - 0xbf, 0xf4, 0x0, 0x0, 0x1, 0xbf, 0xf6, 0x22, - 0x6f, 0xff, 0xf4, 0x0, 0x0, 0x2d, 0xfe, 0x35, - 0xff, 0x53, 0xef, 0xf4, 0x0, 0x4, 0xff, 0xc1, - 0x8f, 0xff, 0xf8, 0x2d, 0xfe, 0x40, 0x7f, 0xfa, - 0x1a, 0xff, 0xff, 0xff, 0xa1, 0xaf, 0xf7, 0xcf, - 0x82, 0xdf, 0xff, 0xff, 0xff, 0xfd, 0x28, 0xfc, - 0x14, 0xe, 0xff, 0xff, 0xff, 0xff, 0xff, 0xe0, - 0x41, 0x0, 0xf, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xf0, 0x0, 0x0, 0xf, 0xff, 0xf9, 0x0, 0x8f, - 0xff, 0xf0, 0x0, 0x0, 0xf, 0xff, 0xf8, 0x0, - 0x8f, 0xff, 0xf0, 0x0, 0x0, 0xf, 0xff, 0xf8, - 0x0, 0x8f, 0xff, 0xf0, 0x0, 0x0, 0xe, 0xff, - 0xf6, 0x0, 0x6f, 0xff, 0xe0, 0x0, - - /* U+F019 "" */ - 0x0, 0x0, 0x0, 0xdf, 0xfd, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0x0, - 0x0, 0x4f, 0xff, 0xff, 0xff, 0xff, 0xf4, 0x0, - 0x0, 0xb, 0xff, 0xff, 0xff, 0xff, 0xb0, 0x0, - 0x0, 0x0, 0xbf, 0xff, 0xff, 0xfb, 0x0, 0x0, - 0x0, 0x0, 0xb, 0xff, 0xff, 0xb0, 0x0, 0x0, - 0x0, 0x0, 0x0, 0xbf, 0xfb, 0x0, 0x0, 0x0, - 0xdf, 0xff, 0xfc, 0x1b, 0xb1, 0xcf, 0xff, 0xfd, - 0xff, 0xff, 0xff, 0xc2, 0x2c, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xf0, 0xe0, 0xff, - 0xdf, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfd, - - /* U+F01C "" */ - 0x0, 0x4, 0xef, 0xff, 0xff, 0xff, 0xfe, 0x40, - 0x0, 0x0, 0x1e, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xe1, 0x0, 0x0, 0xaf, 0xb0, 0x0, 0x0, 0x0, - 0xb, 0xfa, 0x0, 0x5, 0xff, 0x10, 0x0, 0x0, - 0x0, 0x1, 0xff, 0x50, 0x1e, 0xf6, 0x0, 0x0, - 0x0, 0x0, 0x0, 0x6f, 0xe1, 0xaf, 0xb0, 0x0, - 0x0, 0x0, 0x0, 0x0, 0xb, 0xfa, 0xff, 0xff, - 0xff, 0x80, 0x0, 0x8, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xf1, 0x0, 0x1f, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0x8f, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xf8, - - /* U+F021 "" */ - 0x0, 0x0, 0x6, 0xbd, 0xda, 0x50, 0x2, 0xff, - 0x0, 0x5, 0xef, 0xff, 0xff, 0xfe, 0x42, 0xff, - 0x0, 0x7f, 0xff, 0xa7, 0x7b, 0xff, 0xf9, 0xff, - 0x5, 0xff, 0xc1, 0x0, 0x0, 0x2c, 0xff, 0xff, - 0xe, 0xfc, 0x0, 0x0, 0x2, 0x22, 0xdf, 0xff, - 0x5f, 0xf2, 0x0, 0x0, 0xf, 0xff, 0xff, 0xff, - 0x8f, 0xb0, 0x0, 0x0, 0xf, 0xff, 0xff, 0xff, - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0xff, 0xff, 0xff, 0xf0, 0x0, 0x0, 0xb, 0xf8, - 0xff, 0xff, 0xff, 0xf0, 0x0, 0x0, 0x2f, 0xf4, - 0xff, 0xfd, 0x22, 0x20, 0x0, 0x0, 0xcf, 0xe0, - 0xff, 0xff, 0xc2, 0x0, 0x0, 0x2c, 0xff, 0x40, - 0xff, 0x9f, 0xff, 0xb7, 0x6a, 0xff, 0xf7, 0x0, - 0xff, 0x24, 0xdf, 0xff, 0xff, 0xfe, 0x50, 0x0, - 0xff, 0x20, 0x5, 0xac, 0xdb, 0x60, 0x0, 0x0, - - /* U+F026 "" */ - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8d, - 0x0, 0x0, 0x8, 0xff, 0x0, 0x0, 0x8f, 0xff, - 0xdf, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xdf, 0xff, 0xff, 0xff, - 0x0, 0x0, 0x8f, 0xff, 0x0, 0x0, 0x8, 0xff, - 0x0, 0x0, 0x0, 0x8d, 0x0, 0x0, 0x0, 0x0, - - /* U+F027 "" */ - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x8d, 0x0, 0x0, 0x0, 0x0, 0x8, 0xff, - 0x0, 0x0, 0x0, 0x0, 0x8f, 0xff, 0x0, 0x0, - 0xcf, 0xff, 0xff, 0xff, 0x1, 0x50, 0xff, 0xff, - 0xff, 0xff, 0x6, 0xf7, 0xff, 0xff, 0xff, 0xff, - 0x0, 0xbe, 0xff, 0xff, 0xff, 0xff, 0x0, 0xae, - 0xff, 0xff, 0xff, 0xff, 0x5, 0xf8, 0xdf, 0xff, - 0xff, 0xff, 0x2, 0x60, 0x0, 0x0, 0x9f, 0xff, - 0x0, 0x0, 0x0, 0x0, 0x9, 0xff, 0x0, 0x0, - 0x0, 0x0, 0x0, 0x9e, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x0, 0x0, - - /* U+F028 "" */ - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x6, 0x10, - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x1f, - 0xd2, 0x0, 0x0, 0x0, 0x0, 0x8d, 0x0, 0x0, - 0x3, 0xee, 0x10, 0x0, 0x0, 0x8, 0xff, 0x0, - 0xa, 0xb1, 0x2f, 0xb0, 0x0, 0x0, 0x8f, 0xff, - 0x0, 0x5, 0xfc, 0x7, 0xf4, 0xdf, 0xff, 0xff, - 0xff, 0x2, 0x50, 0x5f, 0x60, 0xf9, 0xff, 0xff, - 0xff, 0xff, 0x6, 0xf7, 0xd, 0xc0, 0xbd, 0xff, - 0xff, 0xff, 0xff, 0x0, 0xae, 0x9, 0xf0, 0x9f, - 0xff, 0xff, 0xff, 0xff, 0x0, 0xae, 0x9, 0xf0, - 0x8f, 0xff, 0xff, 0xff, 0xff, 0x6, 0xf7, 0xd, - 0xc0, 0xad, 0xdf, 0xff, 0xff, 0xff, 0x2, 0x50, - 0x5f, 0x60, 0xe9, 0x0, 0x0, 0x8f, 0xff, 0x0, - 0x5, 0xfc, 0x6, 0xf4, 0x0, 0x0, 0x8, 0xff, - 0x0, 0xa, 0xb1, 0x2f, 0xb0, 0x0, 0x0, 0x0, - 0x8d, 0x0, 0x0, 0x2, 0xee, 0x10, 0x0, 0x0, - 0x0, 0x0, 0x0, 0x0, 0x1f, 0xd2, 0x0, 0x0, - 0x0, 0x0, 0x0, 0x0, 0x0, 0x6, 0x10, 0x0, - - /* U+F03E "" */ - 0x8f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf8, - 0xff, 0xfc, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0x20, 0x2f, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xfc, 0x0, 0xc, 0xff, 0xff, 0xee, 0xff, 0xff, - 0xff, 0x20, 0x2f, 0xff, 0xfe, 0x22, 0xef, 0xff, - 0xff, 0xfc, 0xff, 0xff, 0xe2, 0x0, 0x2e, 0xff, - 0xff, 0xfe, 0x4e, 0xfe, 0x20, 0x0, 0x2, 0xff, - 0xff, 0xe2, 0x2, 0xc2, 0x0, 0x0, 0x0, 0xff, - 0xff, 0x20, 0x0, 0x0, 0x0, 0x0, 0x0, 0xff, - 0xff, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0x8f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf8, - - /* U+F043 "" */ - 0x0, 0x0, 0x4e, 0x40, 0x0, 0x0, 0x0, 0xb, - 0xfb, 0x0, 0x0, 0x0, 0x1, 0xff, 0xf1, 0x0, - 0x0, 0x0, 0x9f, 0xff, 0x90, 0x0, 0x0, 0x2f, - 0xff, 0xff, 0x30, 0x0, 0xc, 0xff, 0xff, 0xfc, - 0x0, 0x7, 0xff, 0xff, 0xff, 0xf8, 0x2, 0xff, - 0xff, 0xff, 0xff, 0xf2, 0x9f, 0xff, 0xff, 0xff, - 0xff, 0x9e, 0xff, 0xff, 0xff, 0xff, 0xfe, 0xff, - 0x2f, 0xff, 0xff, 0xff, 0xfe, 0xf2, 0xbf, 0xff, - 0xff, 0xfe, 0x9f, 0xa1, 0xbf, 0xff, 0xff, 0x92, - 0xff, 0xa2, 0x2f, 0xff, 0xf2, 0x4, 0xff, 0xff, - 0xff, 0xf4, 0x0, 0x2, 0x9e, 0xfe, 0x92, 0x0, - - /* U+F048 "" */ - 0x0, 0x0, 0x0, 0x0, 0x0, 0xff, 0x30, 0x0, - 0x1, 0xcc, 0xff, 0x40, 0x0, 0x2d, 0xff, 0xff, - 0x40, 0x3, 0xef, 0xff, 0xff, 0x40, 0x3f, 0xff, - 0xff, 0xff, 0x44, 0xff, 0xff, 0xff, 0xff, 0x9f, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xaf, 0xff, - 0xff, 0xff, 0xff, 0x45, 0xff, 0xff, 0xff, 0xff, - 0x40, 0x4f, 0xff, 0xff, 0xff, 0x40, 0x3, 0xef, - 0xff, 0xff, 0x40, 0x0, 0x2e, 0xff, 0xff, 0x30, - 0x0, 0x1, 0xcc, 0x0, 0x0, 0x0, 0x0, 0x0, - - /* U+F04B "" */ - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8f, - 0x91, 0x0, 0x0, 0x0, 0x0, 0x0, 0xff, 0xff, - 0x70, 0x0, 0x0, 0x0, 0x0, 0xff, 0xff, 0xfd, - 0x40, 0x0, 0x0, 0x0, 0xff, 0xff, 0xff, 0xfa, - 0x10, 0x0, 0x0, 0xff, 0xff, 0xff, 0xff, 0xf7, - 0x0, 0x0, 0xff, 0xff, 0xff, 0xff, 0xff, 0xd5, - 0x0, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xb2, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfd, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xfd, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xb2, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xd5, 0x0, 0xff, 0xff, 0xff, 0xff, - 0xf7, 0x0, 0x0, 0xff, 0xff, 0xff, 0xfa, 0x10, - 0x0, 0x0, 0xff, 0xff, 0xfd, 0x40, 0x0, 0x0, - 0x0, 0xff, 0xff, 0x70, 0x0, 0x0, 0x0, 0x0, - 0x8e, 0xa1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - - /* U+F04C "" */ - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8f, - 0xff, 0xf8, 0x0, 0x8f, 0xff, 0xf8, 0xff, 0xff, - 0xff, 0x0, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0x0, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x0, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x0, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0x0, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0x0, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0x0, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0x0, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0x0, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0x0, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x0, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x0, 0xff, - 0xff, 0xff, 0x7f, 0xff, 0xf7, 0x0, 0x7f, 0xff, - 0xf7, - - /* U+F04D "" */ - 0x8f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf8, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0x8f, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xf8, - - /* U+F051 "" */ - 0x0, 0x0, 0x0, 0x0, 0x0, 0xcc, 0x10, 0x0, - 0x3, 0xff, 0xff, 0xd2, 0x0, 0x4, 0xff, 0xff, - 0xfe, 0x30, 0x4, 0xff, 0xff, 0xff, 0xf4, 0x4, - 0xff, 0xff, 0xff, 0xff, 0x54, 0xff, 0xff, 0xff, - 0xff, 0xf9, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xf9, 0xff, 0xff, 0xff, 0xff, 0x44, 0xff, 0xff, - 0xff, 0xf3, 0x4, 0xff, 0xff, 0xfe, 0x30, 0x4, - 0xff, 0xff, 0xd2, 0x0, 0x4, 0xff, 0xcc, 0x10, - 0x0, 0x3, 0xff, 0x0, 0x0, 0x0, 0x0, 0x0, - - /* U+F052 "" */ - 0x0, 0x0, 0x0, 0x2d, 0xd2, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x1, 0xef, 0xfe, 0x10, 0x0, 0x0, - 0x0, 0x0, 0x1d, 0xff, 0xff, 0xd1, 0x0, 0x0, - 0x0, 0x0, 0xcf, 0xff, 0xff, 0xfc, 0x0, 0x0, - 0x0, 0xb, 0xff, 0xff, 0xff, 0xff, 0xb0, 0x0, - 0x0, 0xaf, 0xff, 0xff, 0xff, 0xff, 0xfa, 0x0, - 0x9, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x90, - 0xf, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf0, - 0x8, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x80, - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0xc, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0, - 0xf, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf0, - 0xf, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf0, - 0xc, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0, - - /* U+F053 "" */ - 0x0, 0x0, 0x0, 0x1a, 0x40, 0x0, 0x0, 0x1, - 0xdf, 0xf0, 0x0, 0x0, 0x1d, 0xff, 0xa0, 0x0, - 0x1, 0xdf, 0xfa, 0x0, 0x0, 0x1d, 0xff, 0xa0, - 0x0, 0x1, 0xdf, 0xfa, 0x0, 0x0, 0xc, 0xff, - 0xa0, 0x0, 0x0, 0xd, 0xff, 0x80, 0x0, 0x0, - 0x1, 0xdf, 0xf8, 0x0, 0x0, 0x0, 0x1d, 0xff, - 0x80, 0x0, 0x0, 0x1, 0xdf, 0xf8, 0x0, 0x0, - 0x0, 0x1d, 0xff, 0x80, 0x0, 0x0, 0x1, 0xdf, - 0xf0, 0x0, 0x0, 0x0, 0x1b, 0x50, - - /* U+F054 "" */ - 0x4, 0xa1, 0x0, 0x0, 0x0, 0xf, 0xfd, 0x10, - 0x0, 0x0, 0xa, 0xff, 0xd1, 0x0, 0x0, 0x0, - 0xaf, 0xfd, 0x10, 0x0, 0x0, 0xa, 0xff, 0xd1, - 0x0, 0x0, 0x0, 0xaf, 0xfd, 0x10, 0x0, 0x0, - 0xa, 0xff, 0xc0, 0x0, 0x0, 0x8, 0xff, 0xd0, - 0x0, 0x0, 0x8f, 0xfd, 0x10, 0x0, 0x8, 0xff, - 0xd1, 0x0, 0x0, 0x8f, 0xfd, 0x10, 0x0, 0x8, - 0xff, 0xd1, 0x0, 0x0, 0xf, 0xfd, 0x10, 0x0, - 0x0, 0x5, 0xb1, 0x0, 0x0, 0x0, - - /* U+F067 "" */ - 0x0, 0x0, 0x4, 0xff, 0x40, 0x0, 0x0, 0x0, - 0x0, 0x8, 0xff, 0x80, 0x0, 0x0, 0x0, 0x0, - 0x8, 0xff, 0x80, 0x0, 0x0, 0x0, 0x0, 0x8, - 0xff, 0x80, 0x0, 0x0, 0x0, 0x0, 0x8, 0xff, - 0x80, 0x0, 0x0, 0x48, 0x88, 0x8c, 0xff, 0xc8, - 0x88, 0x84, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0x48, 0x88, 0x8c, 0xff, 0xc8, 0x88, 0x84, 0x0, - 0x0, 0x8, 0xff, 0x80, 0x0, 0x0, 0x0, 0x0, - 0x8, 0xff, 0x80, 0x0, 0x0, 0x0, 0x0, 0x8, - 0xff, 0x80, 0x0, 0x0, 0x0, 0x0, 0x8, 0xff, - 0x80, 0x0, 0x0, 0x0, 0x0, 0x4, 0xff, 0x40, - 0x0, 0x0, - - /* U+F068 "" */ - 0x14, 0x44, 0x44, 0x44, 0x44, 0x44, 0x41, 0xef, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0x7b, 0xbb, 0xbb, - 0xbb, 0xbb, 0xbb, 0xb7, - - /* U+F06E "" */ - 0x0, 0x0, 0x5, 0xad, 0xff, 0xda, 0x50, 0x0, - 0x0, 0x0, 0x4, 0xdf, 0xfc, 0x88, 0xcf, 0xfd, - 0x40, 0x0, 0x0, 0x7f, 0xfe, 0x40, 0x0, 0x4, - 0xef, 0xf7, 0x0, 0x7, 0xff, 0xf4, 0x0, 0x9e, - 0x80, 0x4f, 0xff, 0x70, 0x4f, 0xff, 0xc0, 0x0, - 0xaf, 0xf8, 0xc, 0xff, 0xf4, 0xdf, 0xff, 0x80, - 0x9a, 0xff, 0xfe, 0x8, 0xff, 0xfd, 0xdf, 0xff, - 0x80, 0xef, 0xff, 0xfe, 0x8, 0xff, 0xfd, 0x4f, - 0xff, 0xc0, 0x8f, 0xff, 0xf8, 0xc, 0xff, 0xf4, - 0x7, 0xff, 0xf4, 0x8, 0xee, 0x80, 0x4f, 0xff, - 0x70, 0x0, 0x7f, 0xfe, 0x40, 0x0, 0x4, 0xef, - 0xf8, 0x0, 0x0, 0x4, 0xdf, 0xfc, 0x88, 0xcf, - 0xfd, 0x40, 0x0, 0x0, 0x0, 0x5, 0xad, 0xff, - 0xda, 0x50, 0x0, 0x0, - - /* U+F070 "" */ - 0x8c, 0x20, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, 0xdf, 0xe4, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x0, 0x0, 0x1b, 0xff, 0x80, 0x49, - 0xdf, 0xfd, 0xa5, 0x0, 0x0, 0x0, 0x0, 0x7f, - 0xff, 0xff, 0xd8, 0x8c, 0xff, 0xd4, 0x0, 0x0, - 0x0, 0x4, 0xef, 0xf8, 0x0, 0x0, 0x4e, 0xff, - 0x70, 0x0, 0x0, 0x0, 0x1c, 0xff, 0x69, 0xe8, - 0x4, 0xff, 0xf7, 0x0, 0x4, 0xe3, 0x0, 0x9f, - 0xfe, 0xff, 0x80, 0xcf, 0xff, 0x40, 0xd, 0xff, - 0x70, 0x5, 0xff, 0xff, 0xe0, 0x8f, 0xff, 0xd0, - 0xd, 0xff, 0xf7, 0x0, 0x2d, 0xff, 0xe0, 0x8f, - 0xff, 0xd0, 0x4, 0xff, 0xfc, 0x0, 0x0, 0xaf, - 0xf8, 0xcf, 0xff, 0x30, 0x0, 0x7f, 0xff, 0x40, - 0x0, 0x6, 0xff, 0xff, 0xf7, 0x0, 0x0, 0x8, - 0xff, 0xf4, 0x0, 0x0, 0x3e, 0xff, 0xa0, 0x0, - 0x0, 0x0, 0x4d, 0xff, 0xc8, 0x82, 0x1, 0xbf, - 0xf7, 0x0, 0x0, 0x0, 0x0, 0x5a, 0xdf, 0xfc, - 0x10, 0x8, 0xff, 0xa0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x0, 0x0, 0x4e, 0xfd, 0x0, 0x0, - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x2, 0xc8, - - /* U+F071 "" */ - 0x0, 0x0, 0x0, 0x0, 0x2d, 0xd2, 0x0, 0x0, - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xbf, 0xfb, - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x5, - 0xff, 0xff, 0x50, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0xd, 0xff, 0xff, 0xd0, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x0, 0x7f, 0xff, 0xff, 0xf7, 0x0, - 0x0, 0x0, 0x0, 0x0, 0x1, 0xff, 0xd8, 0x8d, - 0xff, 0x10, 0x0, 0x0, 0x0, 0x0, 0xa, 0xff, - 0xa0, 0xa, 0xff, 0xa0, 0x0, 0x0, 0x0, 0x0, - 0x3f, 0xff, 0xb0, 0xb, 0xff, 0xf3, 0x0, 0x0, - 0x0, 0x0, 0xcf, 0xff, 0xc0, 0xc, 0xff, 0xfc, - 0x0, 0x0, 0x0, 0x5, 0xff, 0xff, 0xd0, 0xd, - 0xff, 0xff, 0x50, 0x0, 0x0, 0xe, 0xff, 0xff, - 0xf9, 0x9f, 0xff, 0xff, 0xe0, 0x0, 0x0, 0x8f, - 0xff, 0xff, 0xe2, 0x2e, 0xff, 0xff, 0xf8, 0x0, - 0x2, 0xff, 0xff, 0xff, 0x90, 0x9, 0xff, 0xff, - 0xff, 0x10, 0xa, 0xff, 0xff, 0xff, 0xe3, 0x3e, - 0xff, 0xff, 0xff, 0xa0, 0xf, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xf0, 0x8, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x80, - - /* U+F074 "" */ - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xd8, 0x0, - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xff, 0x80, - 0xff, 0xff, 0x70, 0x0, 0x7, 0xff, 0xff, 0xf8, - 0xff, 0xff, 0xf6, 0x0, 0x6f, 0xff, 0xff, 0xfd, - 0x78, 0x8e, 0xff, 0x15, 0xff, 0xe8, 0xff, 0xe2, - 0x0, 0x2, 0xe5, 0x4f, 0xfe, 0x20, 0xfe, 0x20, - 0x0, 0x0, 0x13, 0xff, 0xf3, 0x0, 0x52, 0x0, - 0x0, 0x0, 0x3f, 0xff, 0x31, 0x0, 0x52, 0x0, - 0x0, 0x2, 0xef, 0xf4, 0x5e, 0x20, 0xfe, 0x20, - 0x78, 0x8e, 0xff, 0x51, 0xff, 0xe8, 0xff, 0xe2, - 0xff, 0xff, 0xf6, 0x0, 0x6f, 0xff, 0xff, 0xfd, - 0xff, 0xff, 0x70, 0x0, 0x7, 0xff, 0xff, 0xf8, - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xff, 0x80, - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xd8, 0x0, - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - - /* U+F077 "" */ - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x1, 0xdd, 0x10, 0x0, 0x0, 0x0, 0x0, - 0x1d, 0xff, 0xd1, 0x0, 0x0, 0x0, 0x1, 0xdf, - 0xff, 0xfd, 0x10, 0x0, 0x0, 0x1d, 0xff, 0x99, - 0xff, 0xd1, 0x0, 0x1, 0xdf, 0xf9, 0x0, 0x9f, - 0xfd, 0x10, 0x1d, 0xff, 0x90, 0x0, 0x9, 0xff, - 0xd1, 0xbf, 0xf9, 0x0, 0x0, 0x0, 0x9f, 0xfb, - 0x5f, 0x90, 0x0, 0x0, 0x0, 0x9, 0xf5, 0x0, - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - - /* U+F078 "" */ - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x5f, - 0x90, 0x0, 0x0, 0x0, 0x9, 0xf5, 0xbf, 0xf9, - 0x0, 0x0, 0x0, 0x9f, 0xfb, 0x1d, 0xff, 0x90, - 0x0, 0x9, 0xff, 0xd1, 0x1, 0xdf, 0xf9, 0x0, - 0x9f, 0xfd, 0x10, 0x0, 0x1d, 0xff, 0x99, 0xff, - 0xd1, 0x0, 0x0, 0x1, 0xdf, 0xff, 0xfd, 0x10, - 0x0, 0x0, 0x0, 0x1d, 0xff, 0xd1, 0x0, 0x0, - 0x0, 0x0, 0x1, 0xdd, 0x10, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - - /* U+F079 "" */ - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x0, 0x1d, 0xd1, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x0, 0x0, 0x1, 0xdf, 0xfd, 0x10, - 0xef, 0xff, 0xff, 0xff, 0xd0, 0x0, 0x1d, 0xff, - 0xff, 0xd1, 0xaf, 0xff, 0xff, 0xff, 0xf0, 0x0, - 0xcf, 0xcf, 0xfc, 0xfc, 0x0, 0x0, 0x0, 0xf, - 0xf0, 0x0, 0x6b, 0x1f, 0xf1, 0xb6, 0x0, 0x0, - 0x0, 0xf, 0xf0, 0x0, 0x0, 0xf, 0xf0, 0x0, - 0x0, 0x0, 0x0, 0xf, 0xf0, 0x0, 0x0, 0xf, - 0xf0, 0x0, 0x0, 0x0, 0x0, 0xf, 0xf0, 0x0, - 0x0, 0xf, 0xf0, 0x0, 0x0, 0x0, 0x6b, 0x1f, - 0xf1, 0xb6, 0x0, 0xf, 0xf0, 0x0, 0x0, 0x0, - 0xcf, 0xcf, 0xfc, 0xfc, 0x0, 0xf, 0xff, 0xff, - 0xff, 0xfa, 0x1d, 0xff, 0xff, 0xd1, 0x0, 0xd, - 0xff, 0xff, 0xff, 0xfe, 0x1, 0xdf, 0xfd, 0x10, - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x1d, - 0xd1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x0, 0x0, - - /* U+F07B "" */ - 0x8f, 0xff, 0xff, 0xe2, 0x0, 0x0, 0x0, 0x0, - 0xff, 0xff, 0xff, 0xfe, 0x20, 0x0, 0x0, 0x0, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf8, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0x8f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf8, - - /* U+F093 "" */ - 0x0, 0x0, 0x0, 0xb, 0xb0, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x0, 0xbf, 0xfb, 0x0, 0x0, 0x0, - 0x0, 0x0, 0xb, 0xff, 0xff, 0xb0, 0x0, 0x0, - 0x0, 0x0, 0xbf, 0xff, 0xff, 0xfb, 0x0, 0x0, - 0x0, 0xb, 0xff, 0xff, 0xff, 0xff, 0xb0, 0x0, - 0x0, 0x4f, 0xff, 0xff, 0xff, 0xff, 0xf4, 0x0, - 0x0, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0x0, - 0xdf, 0xff, 0xf0, 0xdf, 0xfd, 0xf, 0xff, 0xfd, - 0xff, 0xff, 0xf9, 0x0, 0x0, 0x9f, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xf0, 0xe0, 0xff, - 0xdf, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfd, - - /* U+F095 "" */ - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xa, 0xea, - 0x62, 0x0, 0x0, 0x0, 0x0, 0x0, 0x2, 0xff, - 0xff, 0xf0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x9f, - 0xff, 0xff, 0x0, 0x0, 0x0, 0x0, 0x0, 0xf, - 0xff, 0xff, 0xd0, 0x0, 0x0, 0x0, 0x0, 0x2, - 0xff, 0xff, 0xfb, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x3, 0xef, 0xff, 0x70, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x4, 0xff, 0xf2, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, 0xbf, 0xfb, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x6f, 0xff, 0x30, 0x0, 0x0, 0x2, - 0x0, 0x0, 0x4f, 0xff, 0x90, 0x0, 0x2, 0x8f, - 0xf3, 0x0, 0x6f, 0xff, 0xd0, 0x0, 0xa, 0xff, - 0xff, 0xe4, 0xbf, 0xff, 0xd1, 0x0, 0x0, 0xef, - 0xff, 0xff, 0xff, 0xff, 0xd1, 0x0, 0x0, 0xa, - 0xff, 0xff, 0xff, 0xff, 0x90, 0x0, 0x0, 0x0, - 0x6f, 0xff, 0xff, 0xfb, 0x30, 0x0, 0x0, 0x0, - 0x2, 0xff, 0xdb, 0x72, 0x0, 0x0, 0x0, 0x0, - 0x0, - - /* U+F0C4 "" */ - 0x8, 0xee, 0x80, 0x0, 0x0, 0x6, 0x61, 0x8, - 0xff, 0xff, 0x80, 0x0, 0x2d, 0xff, 0xd0, 0xef, - 0x33, 0xfe, 0x0, 0x2e, 0xff, 0xf3, 0xe, 0xf3, - 0x3f, 0xe0, 0x2e, 0xff, 0xf3, 0x0, 0x8f, 0xff, - 0xff, 0x6e, 0xff, 0xf3, 0x0, 0x0, 0x8e, 0xff, - 0xff, 0xff, 0xf3, 0x0, 0x0, 0x0, 0x2, 0xef, - 0xff, 0xf3, 0x0, 0x0, 0x0, 0x0, 0x2e, 0xff, - 0xff, 0x30, 0x0, 0x0, 0x8, 0xef, 0xff, 0xff, - 0xff, 0x30, 0x0, 0x8, 0xff, 0xff, 0xf6, 0xef, - 0xff, 0x30, 0x0, 0xef, 0x33, 0xfe, 0x2, 0xef, - 0xff, 0x30, 0xe, 0xf3, 0x3f, 0xe0, 0x2, 0xef, - 0xff, 0x30, 0x8f, 0xff, 0xf8, 0x0, 0x2, 0xdf, - 0xfd, 0x0, 0x8e, 0xe8, 0x0, 0x0, 0x0, 0x66, - 0x10, - - /* U+F0C5 "" */ - 0x0, 0x0, 0xdf, 0xff, 0xff, 0xd, 0x20, 0x0, - 0x0, 0xff, 0xff, 0xff, 0xf, 0xe2, 0x0, 0x0, - 0xff, 0xff, 0xff, 0xf, 0xfd, 0xdf, 0xf0, 0xff, - 0xff, 0xff, 0x20, 0x0, 0xff, 0xf0, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xf0, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xf0, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xf0, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xf0, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xf0, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf0, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf0, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xf0, 0xdf, 0xff, - 0xff, 0xff, 0xfd, 0xff, 0xf9, 0x0, 0x0, 0x0, - 0x0, 0x0, 0xff, 0xff, 0xff, 0xff, 0xff, 0x0, - 0x0, 0xdf, 0xff, 0xff, 0xff, 0xfd, 0x0, 0x0, - - /* U+F0C7 "" */ - 0x8f, 0xff, 0xff, 0xff, 0xff, 0xc2, 0x0, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xfe, 0x20, 0xff, 0x0, - 0x0, 0x0, 0x1, 0xff, 0xe2, 0xff, 0x0, 0x0, - 0x0, 0x0, 0xff, 0xfc, 0xff, 0x0, 0x0, 0x0, - 0x0, 0xff, 0xff, 0xff, 0x0, 0x0, 0x0, 0x0, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xfb, 0x11, 0xbf, 0xff, 0xff, 0xff, - 0xff, 0xf1, 0x0, 0x1f, 0xff, 0xff, 0xff, 0xff, - 0xf1, 0x0, 0x1f, 0xff, 0xff, 0xff, 0xff, 0xfb, - 0x11, 0xbf, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0x8f, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xf8, - - /* U+F0C9 "" */ - 0x12, 0x22, 0x22, 0x22, 0x22, 0x22, 0x21, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0x12, 0x22, 0x22, - 0x22, 0x22, 0x22, 0x21, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x0, 0x12, 0x22, 0x22, 0x22, 0x22, - 0x22, 0x21, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0x12, 0x22, 0x22, 0x22, 0x22, 0x22, 0x21, 0x0, - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x12, 0x22, - 0x22, 0x22, 0x22, 0x22, 0x21, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0x12, 0x22, 0x22, 0x22, 0x22, - 0x22, 0x21, - - /* U+F0E0 "" */ - 0x8f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf8, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xcf, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfc, - 0x9, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x90, - 0xd2, 0x5f, 0xff, 0xff, 0xff, 0xff, 0xf5, 0x2d, - 0xff, 0x62, 0xcf, 0xff, 0xff, 0xfc, 0x26, 0xff, - 0xff, 0xfa, 0x18, 0xff, 0xff, 0x81, 0xaf, 0xff, - 0xff, 0xff, 0xe3, 0x4d, 0xd4, 0x3e, 0xff, 0xff, - 0xff, 0xff, 0xff, 0x81, 0x18, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0x8f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf8, - - /* U+F0E7 "" */ - 0x0, 0xdf, 0xff, 0xfd, 0x0, 0x0, 0x1, 0xff, - 0xff, 0xfc, 0x0, 0x0, 0x3, 0xff, 0xff, 0xf7, - 0x0, 0x0, 0x6, 0xff, 0xff, 0xf2, 0x0, 0x0, - 0x8, 0xff, 0xff, 0xd0, 0x0, 0x0, 0xa, 0xff, - 0xff, 0xff, 0xff, 0xd0, 0xc, 0xff, 0xff, 0xff, - 0xff, 0xa0, 0xe, 0xff, 0xff, 0xff, 0xff, 0x20, - 0xd, 0xff, 0xff, 0xff, 0xf8, 0x0, 0x0, 0x0, - 0xa, 0xff, 0xe0, 0x0, 0x0, 0x0, 0xe, 0xff, - 0x50, 0x0, 0x0, 0x0, 0x2f, 0xfc, 0x0, 0x0, - 0x0, 0x0, 0x5f, 0xf3, 0x0, 0x0, 0x0, 0x0, - 0x9f, 0xa0, 0x0, 0x0, 0x0, 0x0, 0xdf, 0x10, - 0x0, 0x0, 0x0, 0x0, 0xd7, 0x0, 0x0, 0x0, - - /* U+F0EA "" */ - 0x0, 0x4, 0xee, 0x40, 0x0, 0x0, 0x0, 0xdf, - 0xff, 0x99, 0xff, 0xfd, 0x0, 0x0, 0xff, 0xff, - 0x99, 0xff, 0xff, 0x0, 0x0, 0xff, 0xff, 0xff, - 0xff, 0xff, 0x0, 0x0, 0xff, 0xff, 0x90, 0x0, - 0x0, 0x0, 0x0, 0xff, 0xff, 0xd, 0xff, 0xff, - 0xd, 0x20, 0xff, 0xff, 0xf, 0xff, 0xff, 0xf, - 0xe2, 0xff, 0xff, 0xf, 0xff, 0xff, 0xf, 0xfd, - 0xff, 0xff, 0xf, 0xff, 0xff, 0x20, 0x0, 0xff, - 0xff, 0xf, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xf, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf, - 0xff, 0xff, 0xff, 0xff, 0xdf, 0xff, 0xf, 0xff, - 0xff, 0xff, 0xff, 0x0, 0x0, 0xf, 0xff, 0xff, - 0xff, 0xff, 0x0, 0x0, 0xf, 0xff, 0xff, 0xff, - 0xff, 0x0, 0x0, 0xd, 0xff, 0xff, 0xff, 0xfd, - - /* U+F0F3 "" */ - 0x0, 0x0, 0x0, 0xcc, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x2, 0xff, 0x30, 0x0, 0x0, 0x0, 0x1, - 0xbf, 0xff, 0xfc, 0x20, 0x0, 0x0, 0x1e, 0xff, - 0xff, 0xff, 0xe1, 0x0, 0x0, 0x9f, 0xff, 0xff, - 0xff, 0xf8, 0x0, 0x0, 0xef, 0xff, 0xff, 0xff, - 0xfd, 0x0, 0x0, 0xff, 0xff, 0xff, 0xff, 0xff, - 0x0, 0x1, 0xff, 0xff, 0xff, 0xff, 0xff, 0x0, - 0x3, 0xff, 0xff, 0xff, 0xff, 0xff, 0x30, 0x8, - 0xff, 0xff, 0xff, 0xff, 0xff, 0x80, 0x1e, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xe1, 0xcf, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xfc, 0xcf, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xfc, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x0, 0x0, 0xe, 0xff, 0xe0, 0x0, - 0x0, 0x0, 0x0, 0x4, 0xee, 0x40, 0x0, 0x0, - - /* U+F11C "" */ - 0x8f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xf8, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0x0, 0xf0, 0xf, 0x0, 0xf0, - 0xf, 0x0, 0xff, 0xff, 0x0, 0xf0, 0xf, 0x0, - 0xf0, 0xf, 0x0, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf8, 0x8, - 0x80, 0x88, 0x8, 0x80, 0x8f, 0xff, 0xff, 0xf8, - 0x8, 0x80, 0x88, 0x8, 0x80, 0x8f, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0x0, 0xf0, 0x0, 0x0, 0x0, 0xf, 0x0, - 0xff, 0xff, 0x0, 0xf0, 0x0, 0x0, 0x0, 0xf, - 0x0, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0x8f, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xf8, - - /* U+F124 "" */ - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x3, - 0xaf, 0x70, 0x0, 0x0, 0x0, 0x0, 0x0, 0x4, - 0xcf, 0xff, 0xf0, 0x0, 0x0, 0x0, 0x0, 0x6, - 0xdf, 0xff, 0xff, 0xa0, 0x0, 0x0, 0x0, 0x17, - 0xef, 0xff, 0xff, 0xff, 0x30, 0x0, 0x0, 0x18, - 0xff, 0xff, 0xff, 0xff, 0xfc, 0x0, 0x0, 0x2a, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xf4, 0x0, 0x8, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xd0, 0x0, - 0xf, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x60, - 0x0, 0x8, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe, - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xff, 0xff, - 0xf7, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xff, - 0xff, 0xf1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0xff, 0xff, 0x80, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0xff, 0xff, 0x10, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, 0xff, 0xfa, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x0, 0xff, 0xf2, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x0, 0x0, 0x8f, 0x80, 0x0, 0x0, - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, - - /* U+F15B "" */ - 0xdf, 0xff, 0xff, 0xf0, 0xd2, 0x0, 0xff, 0xff, - 0xff, 0xf0, 0xfe, 0x20, 0xff, 0xff, 0xff, 0xf0, - 0xff, 0xe2, 0xff, 0xff, 0xff, 0xf0, 0xff, 0xfd, - 0xff, 0xff, 0xff, 0xf2, 0x0, 0x0, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xdf, 0xff, 0xff, 0xff, 0xff, 0xfd, - - /* U+F1EB "" */ - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x0, 0x0, 0x4, 0x9c, 0xef, 0xfe, - 0xc9, 0x40, 0x0, 0x0, 0x0, 0x7, 0xef, 0xff, - 0xff, 0xff, 0xff, 0xfe, 0x70, 0x0, 0x4, 0xdf, - 0xff, 0xfc, 0xa8, 0x8a, 0xcf, 0xff, 0xfd, 0x40, - 0x6f, 0xff, 0xd5, 0x0, 0x0, 0x0, 0x0, 0x5d, - 0xff, 0xf6, 0xcf, 0xf6, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x6f, 0xfc, 0x1a, 0x30, 0x0, 0x5a, - 0xdf, 0xfd, 0xa5, 0x0, 0x3, 0xa1, 0x0, 0x0, - 0x4d, 0xff, 0xff, 0xff, 0xff, 0xd4, 0x0, 0x0, - 0x0, 0x5, 0xff, 0xfe, 0xa8, 0x8a, 0xef, 0xff, - 0x50, 0x0, 0x0, 0x1, 0xdf, 0x70, 0x0, 0x0, - 0x7, 0xfd, 0x10, 0x0, 0x0, 0x0, 0x12, 0x0, - 0x0, 0x0, 0x0, 0x21, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x4e, 0xe4, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x0, 0x0, 0xef, 0xfe, 0x0, 0x0, - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xef, 0xfe, - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x4e, 0xe4, 0x0, 0x0, 0x0, 0x0, - - /* U+F240 "" */ - 0x8f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0x80, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xf0, 0xff, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x0, 0x0, 0xf, 0xfd, 0xff, 0xf, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf, 0xff, - 0xff, 0xf, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0x0, 0xff, 0xff, 0xf, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0x0, 0xff, 0xff, 0xf, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xf, 0xff, 0xff, 0x0, - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xf, 0xfd, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xf0, 0x8f, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0x80, - - /* U+F241 "" */ - 0x8f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0x80, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xf0, 0xff, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x0, 0x0, 0xf, 0xfd, 0xff, 0xf, - 0xff, 0xff, 0xff, 0xff, 0xf0, 0x0, 0xf, 0xff, - 0xff, 0xf, 0xff, 0xff, 0xff, 0xff, 0xf0, 0x0, - 0x0, 0xff, 0xff, 0xf, 0xff, 0xff, 0xff, 0xff, - 0xf0, 0x0, 0x0, 0xff, 0xff, 0xf, 0xff, 0xff, - 0xff, 0xff, 0xf0, 0x0, 0xf, 0xff, 0xff, 0x0, - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xf, 0xfd, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xf0, 0x8f, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0x80, - - /* U+F242 "" */ - 0x8f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0x80, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xf0, 0xff, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x0, 0x0, 0xf, 0xfd, 0xff, 0xf, - 0xff, 0xff, 0xff, 0x0, 0x0, 0x0, 0xf, 0xff, - 0xff, 0xf, 0xff, 0xff, 0xff, 0x0, 0x0, 0x0, - 0x0, 0xff, 0xff, 0xf, 0xff, 0xff, 0xff, 0x0, - 0x0, 0x0, 0x0, 0xff, 0xff, 0xf, 0xff, 0xff, - 0xff, 0x0, 0x0, 0x0, 0xf, 0xff, 0xff, 0x0, - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xf, 0xfd, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xf0, 0x8f, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0x80, - - /* U+F243 "" */ - 0x8f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0x80, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xf0, 0xff, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x0, 0x0, 0xf, 0xfd, 0xff, 0xf, - 0xff, 0xf0, 0x0, 0x0, 0x0, 0x0, 0xf, 0xff, - 0xff, 0xf, 0xff, 0xf0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0xff, 0xff, 0xf, 0xff, 0xf0, 0x0, 0x0, - 0x0, 0x0, 0x0, 0xff, 0xff, 0xf, 0xff, 0xf0, - 0x0, 0x0, 0x0, 0x0, 0xf, 0xff, 0xff, 0x0, - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xf, 0xfd, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xf0, 0x8f, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0x80, - - /* U+F244 "" */ - 0x8f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0x80, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xf0, 0xff, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x0, 0x0, 0xf, 0xfd, 0xff, 0x0, - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xf, 0xff, - 0xff, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0xff, 0xff, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x0, 0x0, 0xf, 0xff, 0xff, 0x0, - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xf, 0xfd, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xf0, 0x8f, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0x80, - - /* U+F287 "" */ - 0x0, 0x0, 0x0, 0x0, 0x0, 0x1, 0x0, 0x0, - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x7, - 0xfd, 0x10, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x1, 0xcf, 0xff, 0xf5, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x0, 0xb9, 0x29, 0xfe, 0x10, 0x0, - 0x0, 0x0, 0x0, 0x0, 0x0, 0x3f, 0x10, 0x2, - 0x0, 0x0, 0x0, 0x0, 0x3, 0xdf, 0x80, 0xa, - 0x90, 0x0, 0x0, 0x0, 0x3, 0x70, 0x0, 0xdf, - 0xff, 0x77, 0xf7, 0x55, 0x55, 0x55, 0x55, 0x8f, - 0xd3, 0xf, 0xff, 0xfd, 0xcc, 0xdf, 0xdc, 0xcc, - 0xcc, 0xcd, 0xff, 0xb0, 0x8f, 0xfe, 0x10, 0x0, - 0xaa, 0x0, 0x0, 0x0, 0x4d, 0x40, 0x0, 0x46, - 0x10, 0x0, 0x1, 0xf2, 0x2, 0x33, 0x10, 0x0, - 0x0, 0x0, 0x0, 0x0, 0x0, 0x9, 0xb1, 0xcf, - 0xf9, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0xa, 0xff, 0xff, 0x90, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x0, 0x0, 0xbf, 0xf9, 0x0, 0x0, - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x1, 0x22, - 0x0, 0x0, 0x0, - - /* U+F293 "" */ - 0x0, 0x18, 0xdf, 0xfd, 0x92, 0x0, 0x2, 0xef, - 0xfb, 0xef, 0xff, 0x30, 0xd, 0xff, 0xfa, 0x2e, - 0xff, 0xe0, 0x4f, 0xff, 0xfa, 0x3, 0xff, 0xf5, - 0x9f, 0xfa, 0xfa, 0x35, 0x4f, 0xfa, 0xcf, 0xc0, - 0x8a, 0x3d, 0xb, 0xfd, 0xef, 0xfb, 0x3, 0x12, - 0x8f, 0xfe, 0xff, 0xff, 0xb0, 0x6, 0xff, 0xff, - 0xff, 0xff, 0xd1, 0x8, 0xff, 0xff, 0xef, 0xfd, - 0x11, 0x10, 0x9f, 0xff, 0xdf, 0xd1, 0x59, 0x3b, - 0xb, 0xfd, 0xaf, 0xd7, 0xfa, 0x38, 0x1d, 0xfb, - 0x5f, 0xff, 0xfa, 0x1, 0xdf, 0xf7, 0xd, 0xff, - 0xfa, 0x1d, 0xff, 0xf1, 0x3, 0xef, 0xfc, 0xdf, - 0xff, 0x50, 0x0, 0x18, 0xdf, 0xfe, 0xa3, 0x0, - - /* U+F2ED "" */ - 0x0, 0x0, 0x7f, 0xff, 0xf7, 0x0, 0x0, 0xef, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe, 0xef, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xfe, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x0, 0x0, 0xf, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xf0, 0xf, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xf0, 0xf, 0xf9, 0x9f, 0x99, 0xf9, 0x9f, - 0xf0, 0xf, 0xf8, 0x8f, 0x88, 0xf8, 0x8f, 0xf0, - 0xf, 0xf8, 0x8f, 0x88, 0xf8, 0x8f, 0xf0, 0xf, - 0xf8, 0x8f, 0x88, 0xf8, 0x8f, 0xf0, 0xf, 0xf8, - 0x8f, 0x88, 0xf8, 0x8f, 0xf0, 0xf, 0xf8, 0x8f, - 0x88, 0xf8, 0x8f, 0xf0, 0xf, 0xf8, 0x8f, 0x88, - 0xf8, 0x8f, 0xf0, 0xf, 0xf9, 0x9f, 0x99, 0xf9, - 0x9f, 0xf0, 0xf, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xf0, 0x8, 0xff, 0xff, 0xff, 0xff, 0xff, 0x80, - - /* U+F304 "" */ - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x7f, 0xa0, - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8f, 0xff, - 0xb0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xd, 0xff, - 0xff, 0xa0, 0x0, 0x0, 0x0, 0x0, 0x8a, 0x1d, - 0xff, 0xff, 0x0, 0x0, 0x0, 0x0, 0x8f, 0xfa, - 0x1d, 0xff, 0x70, 0x0, 0x0, 0x0, 0x8f, 0xff, - 0xfa, 0x1d, 0x80, 0x0, 0x0, 0x0, 0x8f, 0xff, - 0xff, 0xfa, 0x0, 0x0, 0x0, 0x0, 0x8f, 0xff, - 0xff, 0xff, 0x80, 0x0, 0x0, 0x0, 0x8f, 0xff, - 0xff, 0xff, 0x80, 0x0, 0x0, 0x0, 0x8f, 0xff, - 0xff, 0xff, 0x80, 0x0, 0x0, 0x0, 0x8f, 0xff, - 0xff, 0xff, 0x80, 0x0, 0x0, 0x0, 0x6f, 0xff, - 0xff, 0xff, 0x80, 0x0, 0x0, 0x0, 0xb, 0xff, - 0xff, 0xff, 0x80, 0x0, 0x0, 0x0, 0x0, 0xdf, - 0xff, 0xff, 0x80, 0x0, 0x0, 0x0, 0x0, 0xe, - 0xff, 0xff, 0x80, 0x0, 0x0, 0x0, 0x0, 0x0, - 0xde, 0xdb, 0x60, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, - - /* U+F55A "" */ - 0x0, 0x0, 0x1b, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xe4, 0x0, 0x1, 0xdf, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xfe, 0x0, 0x1d, 0xff, 0xff, - 0xfa, 0xef, 0xfe, 0xaf, 0xff, 0xff, 0x1, 0xdf, - 0xff, 0xff, 0xa0, 0x2e, 0xe2, 0xa, 0xff, 0xff, - 0x1d, 0xff, 0xff, 0xff, 0xe2, 0x2, 0x20, 0x2e, - 0xff, 0xff, 0xcf, 0xff, 0xff, 0xff, 0xfe, 0x20, - 0x2, 0xef, 0xff, 0xff, 0xcf, 0xff, 0xff, 0xff, - 0xfe, 0x20, 0x2, 0xef, 0xff, 0xff, 0x1d, 0xff, - 0xff, 0xff, 0xe2, 0x2, 0x20, 0x2e, 0xff, 0xff, - 0x1, 0xdf, 0xff, 0xff, 0xa0, 0x2e, 0xe2, 0xa, - 0xff, 0xff, 0x0, 0x1d, 0xff, 0xff, 0xfa, 0xef, - 0xfe, 0xaf, 0xff, 0xff, 0x0, 0x1, 0xdf, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe, 0x0, 0x0, - 0x1b, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xe4, - - /* U+F7C2 "" */ - 0x0, 0x8, 0xff, 0xff, 0xff, 0xe4, 0x0, 0x8f, - 0xff, 0xff, 0xff, 0xfe, 0x8, 0xf8, 0xf, 0xb, - 0x40, 0xff, 0x8f, 0xf8, 0xf, 0xb, 0x40, 0xff, - 0xff, 0xf8, 0xf, 0xb, 0x40, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xef, 0xff, 0xff, 0xff, - 0xff, 0xfe, 0x4e, 0xff, 0xff, 0xff, 0xff, 0xe4, - - /* U+F8A2 "" */ - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x1, - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x3, - 0xe0, 0x0, 0x0, 0x10, 0x0, 0x0, 0x0, 0x2, - 0xef, 0x10, 0x0, 0xbf, 0x0, 0x0, 0x0, 0x0, - 0x7f, 0xf1, 0x0, 0xcf, 0xf1, 0x0, 0x0, 0x0, - 0x7, 0xff, 0x11, 0xcf, 0xff, 0x77, 0x77, 0x77, - 0x77, 0xbf, 0xf1, 0xcf, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0x17, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xe0, 0x7, 0xff, 0xf1, 0x0, - 0x0, 0x0, 0x0, 0x0, 0x0, 0x6, 0xff, 0x10, - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x5, 0xa0, - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - - /* U+FF08 "(" */ - 0x0, 0x0, 0x0, 0x0, 0x42, 0x0, 0x73, 0x0, - 0x65, 0x0, 0x2b, 0x0, 0x8, 0x50, 0x0, 0xb3, - 0x0, 0xc, 0x20, 0x0, 0xa3, 0x0, 0x6, 0x70, - 0x0, 0xb, 0x0, 0x0, 0x29, 0x0, 0x0, 0x28, - 0x0, 0x0, 0x2, - - /* U+FF09 ")" */ - 0x0, 0x0, 0x2, 0x60, 0x0, 0x2, 0x80, 0x0, - 0x4, 0x80, 0x0, 0xb, 0x30, 0x0, 0x59, 0x0, - 0x2, 0xd0, 0x0, 0x1e, 0x0, 0x2, 0xb0, 0x0, - 0x68, 0x0, 0x1d, 0x10, 0xa, 0x30, 0x8, 0x30, - 0x2, 0x0, 0x0, - - /* U+FF0C "," */ - 0x4, 0x91, 0xb, 0xf6, 0x1, 0xc3, 0x2, 0x90, - 0x5, 0x0, - - /* U+FF11 "1" */ - 0x1, 0x74, 0x0, 0x26, 0xd5, 0x0, 0x0, 0xb5, - 0x0, 0x0, 0xb5, 0x0, 0x0, 0xb5, 0x0, 0x0, - 0xb5, 0x0, 0x0, 0xb5, 0x0, 0x0, 0xb5, 0x0, - 0x0, 0xb5, 0x0, 0x1, 0xc7, 0x0, 0x45, 0x55, - 0x50, - - /* U+FF12 "2" */ - 0x0, 0x4, 0x41, 0x0, 0x5, 0x92, 0x3c, 0x60, - 0xf, 0x40, 0x5, 0xf0, 0xc, 0x60, 0x5, 0xf0, - 0x0, 0x0, 0xa, 0xb0, 0x0, 0x0, 0x3d, 0x10, - 0x0, 0x1, 0xc2, 0x0, 0x0, 0xa, 0x20, 0x0, - 0x0, 0x93, 0x0, 0x0, 0x8, 0x30, 0x0, 0x70, - 0x2f, 0xdd, 0xdd, 0x80, 0x0, 0x0, 0x0, 0x0 -}; - -/*--------------------- - * GLYPH DESCRIPTION - *--------------------*/ - -static const lv_font_fmt_txt_glyph_dsc_t glyph_dsc[] = { - {.bitmap_index = 0, .adv_w = 0, .box_w = 0, .box_h = 0, .ofs_x = 0, .ofs_y = 0} /* id = 0 reserved */, - {.bitmap_index = 0, .adv_w = 128, .box_w = 0, .box_h = 0, .ofs_x = 0, .ofs_y = 0}, - {.bitmap_index = 0, .adv_w = 128, .box_w = 2, .box_h = 12, .ofs_x = 3, .ofs_y = 0}, - {.bitmap_index = 12, .adv_w = 128, .box_w = 6, .box_h = 5, .ofs_x = 1, .ofs_y = 9}, - {.bitmap_index = 27, .adv_w = 128, .box_w = 8, .box_h = 12, .ofs_x = 0, .ofs_y = 0}, - {.bitmap_index = 75, .adv_w = 128, .box_w = 6, .box_h = 15, .ofs_x = 1, .ofs_y = -2}, - {.bitmap_index = 120, .adv_w = 128, .box_w = 8, .box_h = 12, .ofs_x = 0, .ofs_y = 0}, - {.bitmap_index = 168, .adv_w = 128, .box_w = 8, .box_h = 12, .ofs_x = 0, .ofs_y = 0}, - {.bitmap_index = 216, .adv_w = 128, .box_w = 4, .box_h = 5, .ofs_x = 0, .ofs_y = 9}, - {.bitmap_index = 226, .adv_w = 128, .box_w = 5, .box_h = 16, .ofs_x = 3, .ofs_y = -2}, - {.bitmap_index = 266, .adv_w = 128, .box_w = 5, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 306, .adv_w = 128, .box_w = 8, .box_h = 9, .ofs_x = 0, .ofs_y = 2}, - {.bitmap_index = 342, .adv_w = 128, .box_w = 8, .box_h = 9, .ofs_x = 0, .ofs_y = 2}, - {.bitmap_index = 378, .adv_w = 128, .box_w = 4, .box_h = 5, .ofs_x = 0, .ofs_y = -3}, - {.bitmap_index = 388, .adv_w = 128, .box_w = 8, .box_h = 1, .ofs_x = 0, .ofs_y = 6}, - {.bitmap_index = 392, .adv_w = 128, .box_w = 2, .box_h = 3, .ofs_x = 1, .ofs_y = 0}, - {.bitmap_index = 395, .adv_w = 128, .box_w = 8, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 459, .adv_w = 128, .box_w = 8, .box_h = 12, .ofs_x = 0, .ofs_y = 0}, - {.bitmap_index = 507, .adv_w = 128, .box_w = 6, .box_h = 12, .ofs_x = 1, .ofs_y = 0}, - {.bitmap_index = 543, .adv_w = 128, .box_w = 7, .box_h = 12, .ofs_x = 0, .ofs_y = 0}, - {.bitmap_index = 585, .adv_w = 128, .box_w = 7, .box_h = 12, .ofs_x = 0, .ofs_y = 0}, - {.bitmap_index = 627, .adv_w = 128, .box_w = 8, .box_h = 12, .ofs_x = 0, .ofs_y = 0}, - {.bitmap_index = 675, .adv_w = 128, .box_w = 7, .box_h = 12, .ofs_x = 0, .ofs_y = 0}, - {.bitmap_index = 717, .adv_w = 128, .box_w = 8, .box_h = 12, .ofs_x = 0, .ofs_y = 0}, - {.bitmap_index = 765, .adv_w = 128, .box_w = 7, .box_h = 12, .ofs_x = 1, .ofs_y = 0}, - {.bitmap_index = 807, .adv_w = 128, .box_w = 8, .box_h = 12, .ofs_x = 0, .ofs_y = 0}, - {.bitmap_index = 855, .adv_w = 128, .box_w = 8, .box_h = 12, .ofs_x = 0, .ofs_y = 0}, - {.bitmap_index = 903, .adv_w = 128, .box_w = 2, .box_h = 8, .ofs_x = 3, .ofs_y = 0}, - {.bitmap_index = 911, .adv_w = 128, .box_w = 2, .box_h = 10, .ofs_x = 3, .ofs_y = -2}, - {.bitmap_index = 921, .adv_w = 128, .box_w = 6, .box_h = 13, .ofs_x = 1, .ofs_y = 0}, - {.bitmap_index = 960, .adv_w = 128, .box_w = 8, .box_h = 4, .ofs_x = 0, .ofs_y = 4}, - {.bitmap_index = 976, .adv_w = 128, .box_w = 6, .box_h = 13, .ofs_x = 1, .ofs_y = 0}, - {.bitmap_index = 1015, .adv_w = 128, .box_w = 8, .box_h = 12, .ofs_x = 0, .ofs_y = 0}, - {.bitmap_index = 1063, .adv_w = 128, .box_w = 8, .box_h = 12, .ofs_x = 0, .ofs_y = 0}, - {.bitmap_index = 1111, .adv_w = 128, .box_w = 8, .box_h = 12, .ofs_x = 0, .ofs_y = 0}, - {.bitmap_index = 1159, .adv_w = 128, .box_w = 8, .box_h = 12, .ofs_x = 0, .ofs_y = 0}, - {.bitmap_index = 1207, .adv_w = 128, .box_w = 8, .box_h = 12, .ofs_x = 0, .ofs_y = 0}, - {.bitmap_index = 1255, .adv_w = 128, .box_w = 8, .box_h = 12, .ofs_x = 0, .ofs_y = 0}, - {.bitmap_index = 1303, .adv_w = 128, .box_w = 8, .box_h = 12, .ofs_x = 0, .ofs_y = 0}, - {.bitmap_index = 1351, .adv_w = 128, .box_w = 8, .box_h = 12, .ofs_x = 0, .ofs_y = 0}, - {.bitmap_index = 1399, .adv_w = 128, .box_w = 8, .box_h = 12, .ofs_x = 0, .ofs_y = 0}, - {.bitmap_index = 1447, .adv_w = 128, .box_w = 8, .box_h = 12, .ofs_x = 0, .ofs_y = 0}, - {.bitmap_index = 1495, .adv_w = 128, .box_w = 6, .box_h = 12, .ofs_x = 1, .ofs_y = 0}, - {.bitmap_index = 1531, .adv_w = 128, .box_w = 8, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 1587, .adv_w = 128, .box_w = 8, .box_h = 12, .ofs_x = 0, .ofs_y = 0}, - {.bitmap_index = 1635, .adv_w = 128, .box_w = 8, .box_h = 12, .ofs_x = 0, .ofs_y = 0}, - {.bitmap_index = 1683, .adv_w = 128, .box_w = 8, .box_h = 12, .ofs_x = 0, .ofs_y = 0}, - {.bitmap_index = 1731, .adv_w = 128, .box_w = 8, .box_h = 12, .ofs_x = 0, .ofs_y = 0}, - {.bitmap_index = 1779, .adv_w = 128, .box_w = 8, .box_h = 12, .ofs_x = 0, .ofs_y = 0}, - {.bitmap_index = 1827, .adv_w = 128, .box_w = 8, .box_h = 12, .ofs_x = 0, .ofs_y = 0}, - {.bitmap_index = 1875, .adv_w = 128, .box_w = 8, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 1931, .adv_w = 128, .box_w = 8, .box_h = 12, .ofs_x = 0, .ofs_y = 0}, - {.bitmap_index = 1979, .adv_w = 128, .box_w = 8, .box_h = 12, .ofs_x = 0, .ofs_y = 0}, - {.bitmap_index = 2027, .adv_w = 128, .box_w = 8, .box_h = 12, .ofs_x = 0, .ofs_y = 0}, - {.bitmap_index = 2075, .adv_w = 128, .box_w = 8, .box_h = 12, .ofs_x = 0, .ofs_y = 0}, - {.bitmap_index = 2123, .adv_w = 128, .box_w = 8, .box_h = 12, .ofs_x = 0, .ofs_y = 0}, - {.bitmap_index = 2171, .adv_w = 128, .box_w = 8, .box_h = 12, .ofs_x = 0, .ofs_y = 0}, - {.bitmap_index = 2219, .adv_w = 128, .box_w = 8, .box_h = 12, .ofs_x = 0, .ofs_y = 0}, - {.bitmap_index = 2267, .adv_w = 128, .box_w = 8, .box_h = 12, .ofs_x = 0, .ofs_y = 0}, - {.bitmap_index = 2315, .adv_w = 128, .box_w = 8, .box_h = 12, .ofs_x = 0, .ofs_y = 0}, - {.bitmap_index = 2363, .adv_w = 128, .box_w = 4, .box_h = 15, .ofs_x = 3, .ofs_y = -1}, - {.bitmap_index = 2393, .adv_w = 128, .box_w = 7, .box_h = 15, .ofs_x = 1, .ofs_y = -3}, - {.bitmap_index = 2446, .adv_w = 128, .box_w = 4, .box_h = 15, .ofs_x = 1, .ofs_y = -1}, - {.bitmap_index = 2476, .adv_w = 128, .box_w = 6, .box_h = 2, .ofs_x = 1, .ofs_y = 12}, - {.bitmap_index = 2482, .adv_w = 128, .box_w = 8, .box_h = 1, .ofs_x = 0, .ofs_y = -3}, - {.bitmap_index = 2486, .adv_w = 128, .box_w = 4, .box_h = 2, .ofs_x = 1, .ofs_y = 12}, - {.bitmap_index = 2490, .adv_w = 128, .box_w = 8, .box_h = 8, .ofs_x = 0, .ofs_y = 0}, - {.bitmap_index = 2522, .adv_w = 128, .box_w = 8, .box_h = 13, .ofs_x = 0, .ofs_y = 0}, - {.bitmap_index = 2574, .adv_w = 128, .box_w = 7, .box_h = 8, .ofs_x = 0, .ofs_y = 0}, - {.bitmap_index = 2602, .adv_w = 128, .box_w = 8, .box_h = 13, .ofs_x = 0, .ofs_y = 0}, - {.bitmap_index = 2654, .adv_w = 128, .box_w = 7, .box_h = 8, .ofs_x = 1, .ofs_y = 0}, - {.bitmap_index = 2682, .adv_w = 128, .box_w = 8, .box_h = 12, .ofs_x = 0, .ofs_y = 0}, - {.bitmap_index = 2730, .adv_w = 128, .box_w = 8, .box_h = 10, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 2770, .adv_w = 128, .box_w = 8, .box_h = 12, .ofs_x = 0, .ofs_y = 0}, - {.bitmap_index = 2818, .adv_w = 128, .box_w = 6, .box_h = 12, .ofs_x = 1, .ofs_y = 0}, - {.bitmap_index = 2854, .adv_w = 128, .box_w = 6, .box_h = 14, .ofs_x = 1, .ofs_y = -2}, - {.bitmap_index = 2896, .adv_w = 128, .box_w = 8, .box_h = 12, .ofs_x = 0, .ofs_y = 0}, - {.bitmap_index = 2944, .adv_w = 128, .box_w = 6, .box_h = 12, .ofs_x = 1, .ofs_y = 0}, - {.bitmap_index = 2980, .adv_w = 128, .box_w = 8, .box_h = 8, .ofs_x = 0, .ofs_y = 0}, - {.bitmap_index = 3012, .adv_w = 128, .box_w = 8, .box_h = 8, .ofs_x = 0, .ofs_y = 0}, - {.bitmap_index = 3044, .adv_w = 128, .box_w = 8, .box_h = 8, .ofs_x = 0, .ofs_y = 0}, - {.bitmap_index = 3076, .adv_w = 128, .box_w = 8, .box_h = 10, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 3116, .adv_w = 128, .box_w = 8, .box_h = 10, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 3156, .adv_w = 128, .box_w = 8, .box_h = 8, .ofs_x = 0, .ofs_y = 0}, - {.bitmap_index = 3188, .adv_w = 128, .box_w = 6, .box_h = 8, .ofs_x = 1, .ofs_y = 0}, - {.bitmap_index = 3212, .adv_w = 128, .box_w = 6, .box_h = 11, .ofs_x = 1, .ofs_y = 0}, - {.bitmap_index = 3245, .adv_w = 128, .box_w = 8, .box_h = 8, .ofs_x = 0, .ofs_y = 0}, - {.bitmap_index = 3277, .adv_w = 128, .box_w = 8, .box_h = 8, .ofs_x = 0, .ofs_y = 0}, - {.bitmap_index = 3309, .adv_w = 128, .box_w = 8, .box_h = 8, .ofs_x = 0, .ofs_y = 0}, - {.bitmap_index = 3341, .adv_w = 128, .box_w = 8, .box_h = 8, .ofs_x = 0, .ofs_y = 0}, - {.bitmap_index = 3373, .adv_w = 128, .box_w = 8, .box_h = 10, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 3413, .adv_w = 128, .box_w = 6, .box_h = 8, .ofs_x = 1, .ofs_y = 0}, - {.bitmap_index = 3437, .adv_w = 128, .box_w = 4, .box_h = 16, .ofs_x = 3, .ofs_y = -2}, - {.bitmap_index = 3469, .adv_w = 128, .box_w = 2, .box_h = 18, .ofs_x = 3, .ofs_y = -2}, - {.bitmap_index = 3487, .adv_w = 128, .box_w = 4, .box_h = 16, .ofs_x = 1, .ofs_y = -2}, - {.bitmap_index = 3519, .adv_w = 128, .box_w = 8, .box_h = 4, .ofs_x = 0, .ofs_y = 11}, - {.bitmap_index = 3535, .adv_w = 128, .box_w = 0, .box_h = 0, .ofs_x = 0, .ofs_y = 0}, - {.bitmap_index = 3535, .adv_w = 256, .box_w = 5, .box_h = 5, .ofs_x = 1, .ofs_y = -1}, - {.bitmap_index = 3548, .adv_w = 256, .box_w = 4, .box_h = 5, .ofs_x = 2, .ofs_y = -1}, - {.bitmap_index = 3558, .adv_w = 256, .box_w = 9, .box_h = 12, .ofs_x = 4, .ofs_y = 0}, - {.bitmap_index = 3612, .adv_w = 256, .box_w = 4, .box_h = 14, .ofs_x = 10, .ofs_y = -1}, - {.bitmap_index = 3640, .adv_w = 256, .box_w = 4, .box_h = 14, .ofs_x = 2, .ofs_y = -1}, - {.bitmap_index = 3668, .adv_w = 256, .box_w = 10, .box_h = 11, .ofs_x = 3, .ofs_y = -2}, - {.bitmap_index = 3723, .adv_w = 256, .box_w = 12, .box_h = 14, .ofs_x = 2, .ofs_y = -1}, - {.bitmap_index = 3807, .adv_w = 256, .box_w = 10, .box_h = 7, .ofs_x = 3, .ofs_y = 0}, - {.bitmap_index = 3842, .adv_w = 256, .box_w = 12, .box_h = 9, .ofs_x = 2, .ofs_y = 1}, - {.bitmap_index = 3896, .adv_w = 256, .box_w = 9, .box_h = 13, .ofs_x = 3, .ofs_y = -1}, - {.bitmap_index = 3955, .adv_w = 256, .box_w = 8, .box_h = 11, .ofs_x = 4, .ofs_y = -2}, - {.bitmap_index = 3999, .adv_w = 256, .box_w = 11, .box_h = 13, .ofs_x = 2, .ofs_y = -1}, - {.bitmap_index = 4071, .adv_w = 256, .box_w = 12, .box_h = 13, .ofs_x = 2, .ofs_y = -1}, - {.bitmap_index = 4149, .adv_w = 256, .box_w = 14, .box_h = 13, .ofs_x = 1, .ofs_y = -1}, - {.bitmap_index = 4240, .adv_w = 256, .box_w = 14, .box_h = 13, .ofs_x = 1, .ofs_y = 0}, - {.bitmap_index = 4331, .adv_w = 256, .box_w = 10, .box_h = 13, .ofs_x = 3, .ofs_y = -1}, - {.bitmap_index = 4396, .adv_w = 256, .box_w = 13, .box_h = 13, .ofs_x = 2, .ofs_y = -1}, - {.bitmap_index = 4481, .adv_w = 256, .box_w = 7, .box_h = 14, .ofs_x = 4, .ofs_y = -1}, - {.bitmap_index = 4530, .adv_w = 256, .box_w = 11, .box_h = 14, .ofs_x = 3, .ofs_y = -1}, - {.bitmap_index = 4607, .adv_w = 256, .box_w = 12, .box_h = 13, .ofs_x = 2, .ofs_y = -1}, - {.bitmap_index = 4685, .adv_w = 256, .box_w = 14, .box_h = 14, .ofs_x = 1, .ofs_y = -1}, - {.bitmap_index = 4783, .adv_w = 256, .box_w = 10, .box_h = 11, .ofs_x = 3, .ofs_y = 0}, - {.bitmap_index = 4838, .adv_w = 256, .box_w = 13, .box_h = 13, .ofs_x = 2, .ofs_y = 0}, - {.bitmap_index = 4923, .adv_w = 256, .box_w = 9, .box_h = 13, .ofs_x = 3, .ofs_y = 0}, - {.bitmap_index = 4982, .adv_w = 256, .box_w = 12, .box_h = 14, .ofs_x = 2, .ofs_y = -1}, - {.bitmap_index = 5066, .adv_w = 256, .box_w = 10, .box_h = 13, .ofs_x = 3, .ofs_y = -1}, - {.bitmap_index = 5131, .adv_w = 256, .box_w = 10, .box_h = 13, .ofs_x = 3, .ofs_y = -1}, - {.bitmap_index = 5196, .adv_w = 256, .box_w = 14, .box_h = 13, .ofs_x = 1, .ofs_y = -1}, - {.bitmap_index = 5287, .adv_w = 256, .box_w = 15, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 5400, .adv_w = 256, .box_w = 13, .box_h = 11, .ofs_x = 1, .ofs_y = 0}, - {.bitmap_index = 5472, .adv_w = 256, .box_w = 15, .box_h = 13, .ofs_x = 0, .ofs_y = 0}, - {.bitmap_index = 5570, .adv_w = 256, .box_w = 11, .box_h = 13, .ofs_x = 2, .ofs_y = -1}, - {.bitmap_index = 5642, .adv_w = 256, .box_w = 14, .box_h = 14, .ofs_x = 1, .ofs_y = -1}, - {.bitmap_index = 5740, .adv_w = 256, .box_w = 12, .box_h = 13, .ofs_x = 2, .ofs_y = -1}, - {.bitmap_index = 5818, .adv_w = 256, .box_w = 14, .box_h = 13, .ofs_x = 1, .ofs_y = 0}, - {.bitmap_index = 5909, .adv_w = 256, .box_w = 11, .box_h = 12, .ofs_x = 2, .ofs_y = 0}, - {.bitmap_index = 5975, .adv_w = 256, .box_w = 10, .box_h = 7, .ofs_x = 3, .ofs_y = 0}, - {.bitmap_index = 6010, .adv_w = 256, .box_w = 13, .box_h = 10, .ofs_x = 1, .ofs_y = 0}, - {.bitmap_index = 6075, .adv_w = 256, .box_w = 14, .box_h = 12, .ofs_x = 1, .ofs_y = 1}, - {.bitmap_index = 6159, .adv_w = 256, .box_w = 12, .box_h = 11, .ofs_x = 2, .ofs_y = 0}, - {.bitmap_index = 6225, .adv_w = 256, .box_w = 13, .box_h = 12, .ofs_x = 1, .ofs_y = -1}, - {.bitmap_index = 6303, .adv_w = 256, .box_w = 9, .box_h = 13, .ofs_x = 3, .ofs_y = -1}, - {.bitmap_index = 6362, .adv_w = 256, .box_w = 12, .box_h = 12, .ofs_x = 2, .ofs_y = 0}, - {.bitmap_index = 6434, .adv_w = 256, .box_w = 12, .box_h = 13, .ofs_x = 2, .ofs_y = -1}, - {.bitmap_index = 6512, .adv_w = 256, .box_w = 11, .box_h = 11, .ofs_x = 2, .ofs_y = 0}, - {.bitmap_index = 6573, .adv_w = 256, .box_w = 13, .box_h = 12, .ofs_x = 1, .ofs_y = 0}, - {.bitmap_index = 6651, .adv_w = 256, .box_w = 14, .box_h = 13, .ofs_x = 1, .ofs_y = -1}, - {.bitmap_index = 6742, .adv_w = 256, .box_w = 13, .box_h = 12, .ofs_x = 1, .ofs_y = 0}, - {.bitmap_index = 6820, .adv_w = 256, .box_w = 12, .box_h = 13, .ofs_x = 1, .ofs_y = -1}, - {.bitmap_index = 6898, .adv_w = 256, .box_w = 14, .box_h = 14, .ofs_x = 1, .ofs_y = -1}, - {.bitmap_index = 6996, .adv_w = 256, .box_w = 13, .box_h = 13, .ofs_x = 1, .ofs_y = 0}, - {.bitmap_index = 7081, .adv_w = 256, .box_w = 13, .box_h = 12, .ofs_x = 2, .ofs_y = -1}, - {.bitmap_index = 7159, .adv_w = 256, .box_w = 14, .box_h = 14, .ofs_x = 1, .ofs_y = -1}, - {.bitmap_index = 7257, .adv_w = 256, .box_w = 14, .box_h = 14, .ofs_x = 1, .ofs_y = -1}, - {.bitmap_index = 7355, .adv_w = 256, .box_w = 12, .box_h = 12, .ofs_x = 2, .ofs_y = 0}, - {.bitmap_index = 7427, .adv_w = 256, .box_w = 13, .box_h = 12, .ofs_x = 1, .ofs_y = 0}, - {.bitmap_index = 7505, .adv_w = 256, .box_w = 13, .box_h = 12, .ofs_x = 1, .ofs_y = 0}, - {.bitmap_index = 7583, .adv_w = 256, .box_w = 13, .box_h = 8, .ofs_x = 1, .ofs_y = 2}, - {.bitmap_index = 7635, .adv_w = 256, .box_w = 13, .box_h = 10, .ofs_x = 1, .ofs_y = 2}, - {.bitmap_index = 7700, .adv_w = 256, .box_w = 13, .box_h = 9, .ofs_x = 1, .ofs_y = 2}, - {.bitmap_index = 7759, .adv_w = 256, .box_w = 12, .box_h = 12, .ofs_x = 2, .ofs_y = -1}, - {.bitmap_index = 7831, .adv_w = 256, .box_w = 14, .box_h = 12, .ofs_x = 1, .ofs_y = -1}, - {.bitmap_index = 7915, .adv_w = 256, .box_w = 14, .box_h = 12, .ofs_x = 1, .ofs_y = -1}, - {.bitmap_index = 7999, .adv_w = 256, .box_w = 9, .box_h = 13, .ofs_x = 3, .ofs_y = -1}, - {.bitmap_index = 8058, .adv_w = 256, .box_w = 13, .box_h = 13, .ofs_x = 1, .ofs_y = -1}, - {.bitmap_index = 8143, .adv_w = 256, .box_w = 11, .box_h = 12, .ofs_x = 2, .ofs_y = -1}, - {.bitmap_index = 8209, .adv_w = 256, .box_w = 12, .box_h = 13, .ofs_x = 2, .ofs_y = -1}, - {.bitmap_index = 8287, .adv_w = 256, .box_w = 9, .box_h = 13, .ofs_x = 3, .ofs_y = -1}, - {.bitmap_index = 8346, .adv_w = 256, .box_w = 11, .box_h = 10, .ofs_x = 2, .ofs_y = -1}, - {.bitmap_index = 8401, .adv_w = 256, .box_w = 14, .box_h = 13, .ofs_x = 1, .ofs_y = -1}, - {.bitmap_index = 8492, .adv_w = 256, .box_w = 10, .box_h = 9, .ofs_x = 3, .ofs_y = -1}, - {.bitmap_index = 8537, .adv_w = 256, .box_w = 12, .box_h = 13, .ofs_x = 2, .ofs_y = -1}, - {.bitmap_index = 8615, .adv_w = 256, .box_w = 8, .box_h = 9, .ofs_x = 4, .ofs_y = -1}, - {.bitmap_index = 8651, .adv_w = 256, .box_w = 9, .box_h = 12, .ofs_x = 3, .ofs_y = 0}, - {.bitmap_index = 8705, .adv_w = 256, .box_w = 10, .box_h = 13, .ofs_x = 3, .ofs_y = -1}, - {.bitmap_index = 8770, .adv_w = 256, .box_w = 8, .box_h = 13, .ofs_x = 4, .ofs_y = -1}, - {.bitmap_index = 8822, .adv_w = 256, .box_w = 10, .box_h = 13, .ofs_x = 3, .ofs_y = -1}, - {.bitmap_index = 8887, .adv_w = 256, .box_w = 14, .box_h = 13, .ofs_x = 1, .ofs_y = -1}, - {.bitmap_index = 8978, .adv_w = 256, .box_w = 10, .box_h = 13, .ofs_x = 3, .ofs_y = -1}, - {.bitmap_index = 9043, .adv_w = 256, .box_w = 13, .box_h = 13, .ofs_x = 1, .ofs_y = -1}, - {.bitmap_index = 9128, .adv_w = 256, .box_w = 11, .box_h = 13, .ofs_x = 3, .ofs_y = -1}, - {.bitmap_index = 9200, .adv_w = 256, .box_w = 13, .box_h = 13, .ofs_x = 1, .ofs_y = -1}, - {.bitmap_index = 9285, .adv_w = 256, .box_w = 9, .box_h = 11, .ofs_x = 4, .ofs_y = -2}, - {.bitmap_index = 9335, .adv_w = 256, .box_w = 12, .box_h = 13, .ofs_x = 2, .ofs_y = -1}, - {.bitmap_index = 9413, .adv_w = 256, .box_w = 8, .box_h = 11, .ofs_x = 3, .ofs_y = -1}, - {.bitmap_index = 9457, .adv_w = 256, .box_w = 10, .box_h = 13, .ofs_x = 2, .ofs_y = -1}, - {.bitmap_index = 9522, .adv_w = 256, .box_w = 11, .box_h = 13, .ofs_x = 3, .ofs_y = -1}, - {.bitmap_index = 9594, .adv_w = 256, .box_w = 10, .box_h = 7, .ofs_x = 3, .ofs_y = 1}, - {.bitmap_index = 9629, .adv_w = 256, .box_w = 12, .box_h = 9, .ofs_x = 2, .ofs_y = 1}, - {.bitmap_index = 9683, .adv_w = 256, .box_w = 13, .box_h = 13, .ofs_x = 1, .ofs_y = -1}, - {.bitmap_index = 9768, .adv_w = 256, .box_w = 11, .box_h = 13, .ofs_x = 2, .ofs_y = -1}, - {.bitmap_index = 9840, .adv_w = 256, .box_w = 13, .box_h = 14, .ofs_x = 2, .ofs_y = -1}, - {.bitmap_index = 9931, .adv_w = 256, .box_w = 11, .box_h = 13, .ofs_x = 2, .ofs_y = -1}, - {.bitmap_index = 10003, .adv_w = 256, .box_w = 12, .box_h = 13, .ofs_x = 2, .ofs_y = -1}, - {.bitmap_index = 10081, .adv_w = 256, .box_w = 10, .box_h = 14, .ofs_x = 3, .ofs_y = -1}, - {.bitmap_index = 10151, .adv_w = 256, .box_w = 12, .box_h = 14, .ofs_x = 1, .ofs_y = -1}, - {.bitmap_index = 10235, .adv_w = 256, .box_w = 12, .box_h = 13, .ofs_x = 2, .ofs_y = -1}, - {.bitmap_index = 10313, .adv_w = 256, .box_w = 13, .box_h = 13, .ofs_x = 1, .ofs_y = -1}, - {.bitmap_index = 10398, .adv_w = 256, .box_w = 10, .box_h = 9, .ofs_x = 3, .ofs_y = 1}, - {.bitmap_index = 10443, .adv_w = 256, .box_w = 12, .box_h = 12, .ofs_x = 2, .ofs_y = 1}, - {.bitmap_index = 10515, .adv_w = 256, .box_w = 14, .box_h = 12, .ofs_x = 1, .ofs_y = -1}, - {.bitmap_index = 10599, .adv_w = 256, .box_w = 15, .box_h = 14, .ofs_x = 0, .ofs_y = -1}, - {.bitmap_index = 10704, .adv_w = 256, .box_w = 12, .box_h = 12, .ofs_x = 2, .ofs_y = -1}, - {.bitmap_index = 10776, .adv_w = 256, .box_w = 12, .box_h = 12, .ofs_x = 2, .ofs_y = 0}, - {.bitmap_index = 10848, .adv_w = 256, .box_w = 11, .box_h = 11, .ofs_x = 2, .ofs_y = 0}, - {.bitmap_index = 10909, .adv_w = 256, .box_w = 14, .box_h = 13, .ofs_x = 1, .ofs_y = 0}, - {.bitmap_index = 11000, .adv_w = 256, .box_w = 12, .box_h = 11, .ofs_x = 2, .ofs_y = 0}, - {.bitmap_index = 11066, .adv_w = 256, .box_w = 13, .box_h = 13, .ofs_x = 1, .ofs_y = 0}, - {.bitmap_index = 11151, .adv_w = 256, .box_w = 10, .box_h = 12, .ofs_x = 3, .ofs_y = -1}, - {.bitmap_index = 11211, .adv_w = 256, .box_w = 11, .box_h = 13, .ofs_x = 2, .ofs_y = -1}, - {.bitmap_index = 11283, .adv_w = 256, .box_w = 14, .box_h = 14, .ofs_x = 1, .ofs_y = -1}, - {.bitmap_index = 11381, .adv_w = 256, .box_w = 12, .box_h = 13, .ofs_x = 2, .ofs_y = -1}, - {.bitmap_index = 11459, .adv_w = 256, .box_w = 9, .box_h = 9, .ofs_x = 3, .ofs_y = -1}, - {.bitmap_index = 11500, .adv_w = 256, .box_w = 10, .box_h = 12, .ofs_x = 3, .ofs_y = -1}, - {.bitmap_index = 11560, .adv_w = 256, .box_w = 11, .box_h = 12, .ofs_x = 2, .ofs_y = -1}, - {.bitmap_index = 11626, .adv_w = 256, .box_w = 14, .box_h = 14, .ofs_x = 1, .ofs_y = -1}, - {.bitmap_index = 11724, .adv_w = 256, .box_w = 7, .box_h = 13, .ofs_x = 6, .ofs_y = -1}, - {.bitmap_index = 11770, .adv_w = 256, .box_w = 9, .box_h = 13, .ofs_x = 5, .ofs_y = -1}, - {.bitmap_index = 11829, .adv_w = 256, .box_w = 12, .box_h = 13, .ofs_x = 2, .ofs_y = -1}, - {.bitmap_index = 11907, .adv_w = 256, .box_w = 13, .box_h = 8, .ofs_x = 1, .ofs_y = 1}, - {.bitmap_index = 11959, .adv_w = 256, .box_w = 12, .box_h = 13, .ofs_x = 2, .ofs_y = -1}, - {.bitmap_index = 12037, .adv_w = 256, .box_w = 11, .box_h = 11, .ofs_x = 2, .ofs_y = 0}, - {.bitmap_index = 12098, .adv_w = 256, .box_w = 13, .box_h = 7, .ofs_x = 1, .ofs_y = 2}, - {.bitmap_index = 12144, .adv_w = 256, .box_w = 14, .box_h = 10, .ofs_x = 1, .ofs_y = 2}, - {.bitmap_index = 12214, .adv_w = 256, .box_w = 14, .box_h = 10, .ofs_x = 1, .ofs_y = 2}, - {.bitmap_index = 12284, .adv_w = 256, .box_w = 9, .box_h = 11, .ofs_x = 3, .ofs_y = 0}, - {.bitmap_index = 12334, .adv_w = 256, .box_w = 10, .box_h = 11, .ofs_x = 4, .ofs_y = 0}, - {.bitmap_index = 12389, .adv_w = 256, .box_w = 11, .box_h = 12, .ofs_x = 4, .ofs_y = 0}, - {.bitmap_index = 12455, .adv_w = 256, .box_w = 12, .box_h = 11, .ofs_x = 2, .ofs_y = 0}, - {.bitmap_index = 12521, .adv_w = 256, .box_w = 14, .box_h = 14, .ofs_x = 1, .ofs_y = -1}, - {.bitmap_index = 12619, .adv_w = 256, .box_w = 14, .box_h = 14, .ofs_x = 1, .ofs_y = -1}, - {.bitmap_index = 12717, .adv_w = 256, .box_w = 14, .box_h = 11, .ofs_x = 1, .ofs_y = 1}, - {.bitmap_index = 12794, .adv_w = 256, .box_w = 14, .box_h = 11, .ofs_x = 1, .ofs_y = 1}, - {.bitmap_index = 12871, .adv_w = 256, .box_w = 11, .box_h = 12, .ofs_x = 2, .ofs_y = 0}, - {.bitmap_index = 12937, .adv_w = 256, .box_w = 12, .box_h = 14, .ofs_x = 2, .ofs_y = -1}, - {.bitmap_index = 13021, .adv_w = 256, .box_w = 11, .box_h = 12, .ofs_x = 2, .ofs_y = 0}, - {.bitmap_index = 13087, .adv_w = 256, .box_w = 12, .box_h = 9, .ofs_x = 2, .ofs_y = 0}, - {.bitmap_index = 13141, .adv_w = 256, .box_w = 8, .box_h = 12, .ofs_x = 4, .ofs_y = -1}, - {.bitmap_index = 13189, .adv_w = 256, .box_w = 11, .box_h = 11, .ofs_x = 2, .ofs_y = 0}, - {.bitmap_index = 13250, .adv_w = 256, .box_w = 11, .box_h = 12, .ofs_x = 2, .ofs_y = -1}, - {.bitmap_index = 13316, .adv_w = 256, .box_w = 12, .box_h = 10, .ofs_x = 2, .ofs_y = 0}, - {.bitmap_index = 13376, .adv_w = 256, .box_w = 11, .box_h = 10, .ofs_x = 3, .ofs_y = -2}, - {.bitmap_index = 13431, .adv_w = 256, .box_w = 13, .box_h = 13, .ofs_x = 1, .ofs_y = -1}, - {.bitmap_index = 13516, .adv_w = 256, .box_w = 10, .box_h = 7, .ofs_x = 3, .ofs_y = 0}, - {.bitmap_index = 13551, .adv_w = 256, .box_w = 8, .box_h = 8, .ofs_x = 4, .ofs_y = 0}, - {.bitmap_index = 13583, .adv_w = 256, .box_w = 11, .box_h = 11, .ofs_x = 2, .ofs_y = 0}, - {.bitmap_index = 13644, .adv_w = 256, .box_w = 10, .box_h = 12, .ofs_x = 3, .ofs_y = -1}, - {.bitmap_index = 13704, .adv_w = 256, .box_w = 7, .box_h = 13, .ofs_x = 4, .ofs_y = -1}, - {.bitmap_index = 13750, .adv_w = 256, .box_w = 14, .box_h = 10, .ofs_x = 1, .ofs_y = 0}, - {.bitmap_index = 13820, .adv_w = 256, .box_w = 10, .box_h = 10, .ofs_x = 3, .ofs_y = 0}, - {.bitmap_index = 13870, .adv_w = 256, .box_w = 10, .box_h = 10, .ofs_x = 3, .ofs_y = 0}, - {.bitmap_index = 13920, .adv_w = 256, .box_w = 11, .box_h = 12, .ofs_x = 3, .ofs_y = -1}, - {.bitmap_index = 13986, .adv_w = 256, .box_w = 12, .box_h = 11, .ofs_x = 2, .ofs_y = 0}, - {.bitmap_index = 14052, .adv_w = 256, .box_w = 10, .box_h = 9, .ofs_x = 3, .ofs_y = -1}, - {.bitmap_index = 14097, .adv_w = 256, .box_w = 15, .box_h = 3, .ofs_x = 1, .ofs_y = 5}, - {.bitmap_index = 14120, .adv_w = 256, .box_w = 16, .box_h = 2, .ofs_x = 0, .ofs_y = 6}, - {.bitmap_index = 14136, .adv_w = 256, .box_w = 16, .box_h = 14, .ofs_x = 0, .ofs_y = -1}, - {.bitmap_index = 14248, .adv_w = 256, .box_w = 14, .box_h = 15, .ofs_x = 1, .ofs_y = -2}, - {.bitmap_index = 14353, .adv_w = 256, .box_w = 15, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 14473, .adv_w = 256, .box_w = 16, .box_h = 13, .ofs_x = 0, .ofs_y = -1}, - {.bitmap_index = 14577, .adv_w = 256, .box_w = 16, .box_h = 14, .ofs_x = 0, .ofs_y = -1}, - {.bitmap_index = 14689, .adv_w = 256, .box_w = 14, .box_h = 15, .ofs_x = 1, .ofs_y = -2}, - {.bitmap_index = 14794, .adv_w = 256, .box_w = 15, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 14907, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 15035, .adv_w = 256, .box_w = 16, .box_h = 14, .ofs_x = 0, .ofs_y = -1}, - {.bitmap_index = 15147, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 15267, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 15387, .adv_w = 256, .box_w = 15, .box_h = 14, .ofs_x = 1, .ofs_y = -1}, - {.bitmap_index = 15492, .adv_w = 256, .box_w = 13, .box_h = 16, .ofs_x = 2, .ofs_y = -2}, - {.bitmap_index = 15596, .adv_w = 256, .box_w = 15, .box_h = 14, .ofs_x = 0, .ofs_y = -1}, - {.bitmap_index = 15701, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 15821, .adv_w = 256, .box_w = 16, .box_h = 14, .ofs_x = 0, .ofs_y = -1}, - {.bitmap_index = 15933, .adv_w = 256, .box_w = 15, .box_h = 15, .ofs_x = 1, .ofs_y = -2}, - {.bitmap_index = 16046, .adv_w = 256, .box_w = 15, .box_h = 14, .ofs_x = 1, .ofs_y = -1}, - {.bitmap_index = 16151, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 16271, .adv_w = 256, .box_w = 15, .box_h = 15, .ofs_x = 1, .ofs_y = -2}, - {.bitmap_index = 16384, .adv_w = 256, .box_w = 15, .box_h = 14, .ofs_x = 0, .ofs_y = -1}, - {.bitmap_index = 16489, .adv_w = 256, .box_w = 13, .box_h = 15, .ofs_x = 2, .ofs_y = -2}, - {.bitmap_index = 16587, .adv_w = 256, .box_w = 15, .box_h = 15, .ofs_x = 1, .ofs_y = -2}, - {.bitmap_index = 16700, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 16828, .adv_w = 256, .box_w = 15, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 16948, .adv_w = 256, .box_w = 16, .box_h = 11, .ofs_x = 0, .ofs_y = 0}, - {.bitmap_index = 17036, .adv_w = 256, .box_w = 16, .box_h = 14, .ofs_x = 0, .ofs_y = -1}, - {.bitmap_index = 17148, .adv_w = 256, .box_w = 16, .box_h = 14, .ofs_x = 0, .ofs_y = -1}, - {.bitmap_index = 17260, .adv_w = 256, .box_w = 16, .box_h = 14, .ofs_x = 0, .ofs_y = -1}, - {.bitmap_index = 17372, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 17500, .adv_w = 256, .box_w = 15, .box_h = 16, .ofs_x = 1, .ofs_y = -2}, - {.bitmap_index = 17620, .adv_w = 256, .box_w = 15, .box_h = 16, .ofs_x = 1, .ofs_y = -2}, - {.bitmap_index = 17740, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 17860, .adv_w = 256, .box_w = 15, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 17980, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 18108, .adv_w = 256, .box_w = 15, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 18228, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 18356, .adv_w = 256, .box_w = 15, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 18476, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 18604, .adv_w = 256, .box_w = 15, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 18724, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 18852, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 18980, .adv_w = 256, .box_w = 13, .box_h = 15, .ofs_x = 2, .ofs_y = -2}, - {.bitmap_index = 19078, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 19206, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 19334, .adv_w = 256, .box_w = 15, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 19454, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 19574, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -1}, - {.bitmap_index = 19694, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 19822, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 19942, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 20070, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 20190, .adv_w = 256, .box_w = 15, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 20310, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 20438, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 20558, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 20686, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 20814, .adv_w = 256, .box_w = 15, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 20927, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 21055, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 21175, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 21303, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 21431, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 21559, .adv_w = 256, .box_w = 15, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 21679, .adv_w = 256, .box_w = 15, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 21799, .adv_w = 256, .box_w = 15, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 21912, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 22032, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 22160, .adv_w = 256, .box_w = 15, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 22273, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 22393, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 22513, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 22641, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 22769, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 22897, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 23017, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 23137, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 23265, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 23393, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 23513, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 23641, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 23769, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 23897, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 24017, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 24137, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 24265, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 24393, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 24521, .adv_w = 256, .box_w = 15, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 24634, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 24762, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 24890, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 25018, .adv_w = 256, .box_w = 15, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 25131, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 25251, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 25371, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 25491, .adv_w = 256, .box_w = 14, .box_h = 15, .ofs_x = 1, .ofs_y = -2}, - {.bitmap_index = 25596, .adv_w = 256, .box_w = 15, .box_h = 16, .ofs_x = 1, .ofs_y = -2}, - {.bitmap_index = 25716, .adv_w = 256, .box_w = 15, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 25836, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 25956, .adv_w = 256, .box_w = 15, .box_h = 16, .ofs_x = 1, .ofs_y = -2}, - {.bitmap_index = 26076, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 26204, .adv_w = 256, .box_w = 15, .box_h = 16, .ofs_x = 1, .ofs_y = -2}, - {.bitmap_index = 26324, .adv_w = 256, .box_w = 15, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 26437, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 26557, .adv_w = 256, .box_w = 13, .box_h = 16, .ofs_x = 2, .ofs_y = -2}, - {.bitmap_index = 26661, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 26789, .adv_w = 256, .box_w = 15, .box_h = 15, .ofs_x = 1, .ofs_y = -2}, - {.bitmap_index = 26902, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 27022, .adv_w = 256, .box_w = 15, .box_h = 15, .ofs_x = 1, .ofs_y = -2}, - {.bitmap_index = 27135, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 27255, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 27375, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 27503, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 27623, .adv_w = 256, .box_w = 13, .box_h = 16, .ofs_x = 2, .ofs_y = -2}, - {.bitmap_index = 27727, .adv_w = 256, .box_w = 13, .box_h = 15, .ofs_x = 2, .ofs_y = -2}, - {.bitmap_index = 27825, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 27945, .adv_w = 256, .box_w = 15, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 28058, .adv_w = 256, .box_w = 14, .box_h = 16, .ofs_x = 1, .ofs_y = -2}, - {.bitmap_index = 28170, .adv_w = 256, .box_w = 15, .box_h = 15, .ofs_x = 1, .ofs_y = -2}, - {.bitmap_index = 28283, .adv_w = 256, .box_w = 15, .box_h = 15, .ofs_x = 1, .ofs_y = -2}, - {.bitmap_index = 28396, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 28524, .adv_w = 256, .box_w = 15, .box_h = 15, .ofs_x = 1, .ofs_y = -2}, - {.bitmap_index = 28637, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 28757, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 28877, .adv_w = 256, .box_w = 13, .box_h = 15, .ofs_x = 1, .ofs_y = -2}, - {.bitmap_index = 28975, .adv_w = 256, .box_w = 15, .box_h = 15, .ofs_x = 1, .ofs_y = -2}, - {.bitmap_index = 29088, .adv_w = 256, .box_w = 15, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 29201, .adv_w = 256, .box_w = 15, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 29314, .adv_w = 256, .box_w = 15, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 29427, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 29555, .adv_w = 256, .box_w = 15, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 29675, .adv_w = 256, .box_w = 15, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 29788, .adv_w = 256, .box_w = 15, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 29908, .adv_w = 256, .box_w = 15, .box_h = 15, .ofs_x = 1, .ofs_y = -2}, - {.bitmap_index = 30021, .adv_w = 256, .box_w = 15, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 30141, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 30269, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 30397, .adv_w = 256, .box_w = 15, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 30510, .adv_w = 256, .box_w = 14, .box_h = 16, .ofs_x = 1, .ofs_y = -2}, - {.bitmap_index = 30622, .adv_w = 256, .box_w = 15, .box_h = 16, .ofs_x = 1, .ofs_y = -2}, - {.bitmap_index = 30742, .adv_w = 256, .box_w = 14, .box_h = 15, .ofs_x = 1, .ofs_y = -2}, - {.bitmap_index = 30847, .adv_w = 256, .box_w = 15, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 30967, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 31095, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 31223, .adv_w = 256, .box_w = 15, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 31343, .adv_w = 256, .box_w = 15, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 31463, .adv_w = 256, .box_w = 15, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 31583, .adv_w = 256, .box_w = 15, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 31696, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 31816, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 31944, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 32072, .adv_w = 256, .box_w = 15, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 32192, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 32312, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 32432, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 32560, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 32688, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 32808, .adv_w = 256, .box_w = 16, .box_h = 14, .ofs_x = 0, .ofs_y = -1}, - {.bitmap_index = 32920, .adv_w = 256, .box_w = 15, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 33033, .adv_w = 256, .box_w = 15, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 33146, .adv_w = 256, .box_w = 15, .box_h = 15, .ofs_x = 1, .ofs_y = -2}, - {.bitmap_index = 33259, .adv_w = 256, .box_w = 14, .box_h = 15, .ofs_x = 1, .ofs_y = -2}, - {.bitmap_index = 33364, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 33484, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 33604, .adv_w = 256, .box_w = 15, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 33724, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 33852, .adv_w = 256, .box_w = 15, .box_h = 16, .ofs_x = 1, .ofs_y = -2}, - {.bitmap_index = 33972, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 34092, .adv_w = 256, .box_w = 15, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 34212, .adv_w = 256, .box_w = 15, .box_h = 15, .ofs_x = 1, .ofs_y = -2}, - {.bitmap_index = 34325, .adv_w = 256, .box_w = 15, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 34445, .adv_w = 256, .box_w = 14, .box_h = 15, .ofs_x = 1, .ofs_y = -2}, - {.bitmap_index = 34550, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 34670, .adv_w = 256, .box_w = 15, .box_h = 15, .ofs_x = 1, .ofs_y = -2}, - {.bitmap_index = 34783, .adv_w = 256, .box_w = 14, .box_h = 15, .ofs_x = 1, .ofs_y = -2}, - {.bitmap_index = 34888, .adv_w = 256, .box_w = 15, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 35001, .adv_w = 256, .box_w = 15, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 35121, .adv_w = 256, .box_w = 16, .box_h = 17, .ofs_x = 0, .ofs_y = -3}, - {.bitmap_index = 35257, .adv_w = 256, .box_w = 16, .box_h = 17, .ofs_x = 0, .ofs_y = -3}, - {.bitmap_index = 35393, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 35513, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 35633, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 35761, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 35881, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 36001, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 36121, .adv_w = 256, .box_w = 11, .box_h = 13, .ofs_x = 3, .ofs_y = -1}, - {.bitmap_index = 36193, .adv_w = 256, .box_w = 15, .box_h = 16, .ofs_x = 1, .ofs_y = -2}, - {.bitmap_index = 36313, .adv_w = 256, .box_w = 15, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 36433, .adv_w = 256, .box_w = 14, .box_h = 15, .ofs_x = 1, .ofs_y = -2}, - {.bitmap_index = 36538, .adv_w = 256, .box_w = 13, .box_h = 15, .ofs_x = 1, .ofs_y = -2}, - {.bitmap_index = 36636, .adv_w = 256, .box_w = 14, .box_h = 15, .ofs_x = 1, .ofs_y = -2}, - {.bitmap_index = 36741, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 36861, .adv_w = 256, .box_w = 13, .box_h = 16, .ofs_x = 2, .ofs_y = -2}, - {.bitmap_index = 36965, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 37093, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 37213, .adv_w = 256, .box_w = 14, .box_h = 15, .ofs_x = 1, .ofs_y = -2}, - {.bitmap_index = 37318, .adv_w = 256, .box_w = 13, .box_h = 15, .ofs_x = 1, .ofs_y = -2}, - {.bitmap_index = 37416, .adv_w = 256, .box_w = 14, .box_h = 15, .ofs_x = 1, .ofs_y = -1}, - {.bitmap_index = 37521, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 37649, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 37777, .adv_w = 256, .box_w = 13, .box_h = 15, .ofs_x = 2, .ofs_y = -2}, - {.bitmap_index = 37875, .adv_w = 256, .box_w = 14, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 37987, .adv_w = 256, .box_w = 13, .box_h = 16, .ofs_x = 2, .ofs_y = -2}, - {.bitmap_index = 38091, .adv_w = 256, .box_w = 14, .box_h = 15, .ofs_x = 1, .ofs_y = -2}, - {.bitmap_index = 38196, .adv_w = 256, .box_w = 15, .box_h = 13, .ofs_x = 1, .ofs_y = -1}, - {.bitmap_index = 38294, .adv_w = 256, .box_w = 15, .box_h = 15, .ofs_x = 1, .ofs_y = -2}, - {.bitmap_index = 38407, .adv_w = 256, .box_w = 14, .box_h = 15, .ofs_x = 1, .ofs_y = -2}, - {.bitmap_index = 38512, .adv_w = 256, .box_w = 14, .box_h = 15, .ofs_x = 1, .ofs_y = -2}, - {.bitmap_index = 38617, .adv_w = 256, .box_w = 15, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 38730, .adv_w = 256, .box_w = 15, .box_h = 16, .ofs_x = 1, .ofs_y = -2}, - {.bitmap_index = 38850, .adv_w = 256, .box_w = 15, .box_h = 15, .ofs_x = 1, .ofs_y = -2}, - {.bitmap_index = 38963, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 39091, .adv_w = 256, .box_w = 15, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 39204, .adv_w = 256, .box_w = 15, .box_h = 16, .ofs_x = 1, .ofs_y = -2}, - {.bitmap_index = 39324, .adv_w = 256, .box_w = 14, .box_h = 15, .ofs_x = 1, .ofs_y = -2}, - {.bitmap_index = 39429, .adv_w = 256, .box_w = 13, .box_h = 16, .ofs_x = 1, .ofs_y = -2}, - {.bitmap_index = 39533, .adv_w = 256, .box_w = 15, .box_h = 15, .ofs_x = 1, .ofs_y = -2}, - {.bitmap_index = 39646, .adv_w = 256, .box_w = 15, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 39766, .adv_w = 256, .box_w = 15, .box_h = 15, .ofs_x = 1, .ofs_y = -2}, - {.bitmap_index = 39879, .adv_w = 256, .box_w = 14, .box_h = 15, .ofs_x = 1, .ofs_y = -2}, - {.bitmap_index = 39984, .adv_w = 256, .box_w = 15, .box_h = 15, .ofs_x = 1, .ofs_y = -2}, - {.bitmap_index = 40097, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 40225, .adv_w = 256, .box_w = 15, .box_h = 15, .ofs_x = 1, .ofs_y = -2}, - {.bitmap_index = 40338, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 40466, .adv_w = 256, .box_w = 14, .box_h = 15, .ofs_x = 1, .ofs_y = -2}, - {.bitmap_index = 40571, .adv_w = 256, .box_w = 15, .box_h = 16, .ofs_x = 1, .ofs_y = -2}, - {.bitmap_index = 40691, .adv_w = 256, .box_w = 15, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 40804, .adv_w = 256, .box_w = 15, .box_h = 15, .ofs_x = 1, .ofs_y = -2}, - {.bitmap_index = 40917, .adv_w = 256, .box_w = 15, .box_h = 14, .ofs_x = 1, .ofs_y = -1}, - {.bitmap_index = 41022, .adv_w = 256, .box_w = 15, .box_h = 16, .ofs_x = 1, .ofs_y = -2}, - {.bitmap_index = 41142, .adv_w = 256, .box_w = 15, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 41262, .adv_w = 256, .box_w = 13, .box_h = 15, .ofs_x = 2, .ofs_y = -2}, - {.bitmap_index = 41360, .adv_w = 256, .box_w = 13, .box_h = 15, .ofs_x = 2, .ofs_y = -2}, - {.bitmap_index = 41458, .adv_w = 256, .box_w = 14, .box_h = 15, .ofs_x = 1, .ofs_y = -2}, - {.bitmap_index = 41563, .adv_w = 256, .box_w = 13, .box_h = 15, .ofs_x = 2, .ofs_y = -2}, - {.bitmap_index = 41661, .adv_w = 256, .box_w = 15, .box_h = 16, .ofs_x = 1, .ofs_y = -2}, - {.bitmap_index = 41781, .adv_w = 256, .box_w = 13, .box_h = 15, .ofs_x = 2, .ofs_y = -2}, - {.bitmap_index = 41879, .adv_w = 256, .box_w = 15, .box_h = 16, .ofs_x = 1, .ofs_y = -2}, - {.bitmap_index = 41999, .adv_w = 256, .box_w = 14, .box_h = 16, .ofs_x = 1, .ofs_y = -2}, - {.bitmap_index = 42111, .adv_w = 256, .box_w = 14, .box_h = 16, .ofs_x = 1, .ofs_y = -2}, - {.bitmap_index = 42223, .adv_w = 256, .box_w = 14, .box_h = 16, .ofs_x = 1, .ofs_y = -2}, - {.bitmap_index = 42335, .adv_w = 256, .box_w = 16, .box_h = 14, .ofs_x = 0, .ofs_y = -1}, - {.bitmap_index = 42447, .adv_w = 256, .box_w = 16, .box_h = 14, .ofs_x = 0, .ofs_y = -1}, - {.bitmap_index = 42559, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 42687, .adv_w = 256, .box_w = 16, .box_h = 14, .ofs_x = 0, .ofs_y = -1}, - {.bitmap_index = 42799, .adv_w = 256, .box_w = 15, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 42912, .adv_w = 256, .box_w = 15, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 43025, .adv_w = 256, .box_w = 16, .box_h = 14, .ofs_x = 0, .ofs_y = -1}, - {.bitmap_index = 43137, .adv_w = 256, .box_w = 14, .box_h = 16, .ofs_x = 1, .ofs_y = -2}, - {.bitmap_index = 43249, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 43377, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 43505, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 43633, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 43753, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 43881, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 44009, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 44137, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 44265, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 44385, .adv_w = 256, .box_w = 15, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 44505, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 44633, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 44761, .adv_w = 256, .box_w = 15, .box_h = 14, .ofs_x = 0, .ofs_y = -1}, - {.bitmap_index = 44866, .adv_w = 256, .box_w = 15, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 44986, .adv_w = 256, .box_w = 15, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 45099, .adv_w = 256, .box_w = 15, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 45212, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 45332, .adv_w = 256, .box_w = 14, .box_h = 15, .ofs_x = 1, .ofs_y = -2}, - {.bitmap_index = 45437, .adv_w = 256, .box_w = 15, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 45550, .adv_w = 256, .box_w = 14, .box_h = 16, .ofs_x = 1, .ofs_y = -2}, - {.bitmap_index = 45662, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 45790, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 45910, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 46038, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 46158, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 46286, .adv_w = 256, .box_w = 15, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 46406, .adv_w = 256, .box_w = 15, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 46526, .adv_w = 256, .box_w = 15, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 46646, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 46774, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 46894, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 47022, .adv_w = 256, .box_w = 15, .box_h = 15, .ofs_x = 1, .ofs_y = -2}, - {.bitmap_index = 47135, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 47263, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 47383, .adv_w = 256, .box_w = 15, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 47496, .adv_w = 256, .box_w = 15, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 47616, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 47744, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 47872, .adv_w = 256, .box_w = 16, .box_h = 17, .ofs_x = 0, .ofs_y = -3}, - {.bitmap_index = 48008, .adv_w = 256, .box_w = 15, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 48128, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 48256, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 48384, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 48504, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 48632, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 48760, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 48888, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 49016, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 49136, .adv_w = 256, .box_w = 15, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 49256, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 49376, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 49496, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 49624, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 49752, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 49872, .adv_w = 256, .box_w = 15, .box_h = 15, .ofs_x = 1, .ofs_y = -2}, - {.bitmap_index = 49985, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 50105, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 50225, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 50353, .adv_w = 256, .box_w = 15, .box_h = 14, .ofs_x = 0, .ofs_y = -1}, - {.bitmap_index = 50458, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -1}, - {.bitmap_index = 50578, .adv_w = 256, .box_w = 15, .box_h = 16, .ofs_x = 1, .ofs_y = -2}, - {.bitmap_index = 50698, .adv_w = 256, .box_w = 15, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 50818, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 50946, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 51066, .adv_w = 256, .box_w = 15, .box_h = 16, .ofs_x = 1, .ofs_y = -2}, - {.bitmap_index = 51186, .adv_w = 256, .box_w = 15, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 51299, .adv_w = 256, .box_w = 15, .box_h = 15, .ofs_x = 1, .ofs_y = -2}, - {.bitmap_index = 51412, .adv_w = 256, .box_w = 15, .box_h = 16, .ofs_x = 1, .ofs_y = -2}, - {.bitmap_index = 51532, .adv_w = 256, .box_w = 15, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 51652, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 51780, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 51900, .adv_w = 256, .box_w = 14, .box_h = 16, .ofs_x = 1, .ofs_y = -2}, - {.bitmap_index = 52012, .adv_w = 256, .box_w = 14, .box_h = 15, .ofs_x = 1, .ofs_y = -2}, - {.bitmap_index = 52117, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 52245, .adv_w = 256, .box_w = 15, .box_h = 16, .ofs_x = 1, .ofs_y = -2}, - {.bitmap_index = 52365, .adv_w = 256, .box_w = 15, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 52485, .adv_w = 256, .box_w = 15, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 52605, .adv_w = 256, .box_w = 15, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 52725, .adv_w = 256, .box_w = 14, .box_h = 16, .ofs_x = 1, .ofs_y = -2}, - {.bitmap_index = 52837, .adv_w = 256, .box_w = 15, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 52957, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 53085, .adv_w = 256, .box_w = 15, .box_h = 16, .ofs_x = 1, .ofs_y = -2}, - {.bitmap_index = 53205, .adv_w = 256, .box_w = 15, .box_h = 16, .ofs_x = 1, .ofs_y = -2}, - {.bitmap_index = 53325, .adv_w = 256, .box_w = 15, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 53445, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 53573, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 53693, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 53821, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 53941, .adv_w = 256, .box_w = 15, .box_h = 16, .ofs_x = 1, .ofs_y = -2}, - {.bitmap_index = 54061, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 54189, .adv_w = 256, .box_w = 15, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 54309, .adv_w = 256, .box_w = 14, .box_h = 15, .ofs_x = 1, .ofs_y = -2}, - {.bitmap_index = 54414, .adv_w = 256, .box_w = 15, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 54527, .adv_w = 256, .box_w = 13, .box_h = 16, .ofs_x = 2, .ofs_y = -2}, - {.bitmap_index = 54631, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 54751, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 54879, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 54999, .adv_w = 256, .box_w = 15, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 55112, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 55232, .adv_w = 256, .box_w = 15, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 55345, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 55465, .adv_w = 256, .box_w = 15, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 55578, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 55698, .adv_w = 256, .box_w = 15, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 55818, .adv_w = 256, .box_w = 13, .box_h = 14, .ofs_x = 1, .ofs_y = -1}, - {.bitmap_index = 55909, .adv_w = 256, .box_w = 15, .box_h = 16, .ofs_x = 1, .ofs_y = -2}, - {.bitmap_index = 56029, .adv_w = 256, .box_w = 15, .box_h = 16, .ofs_x = 1, .ofs_y = -2}, - {.bitmap_index = 56149, .adv_w = 256, .box_w = 13, .box_h = 15, .ofs_x = 1, .ofs_y = -2}, - {.bitmap_index = 56247, .adv_w = 256, .box_w = 14, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 56352, .adv_w = 256, .box_w = 15, .box_h = 13, .ofs_x = 0, .ofs_y = -1}, - {.bitmap_index = 56450, .adv_w = 256, .box_w = 15, .box_h = 14, .ofs_x = 0, .ofs_y = -1}, - {.bitmap_index = 56555, .adv_w = 256, .box_w = 15, .box_h = 16, .ofs_x = 1, .ofs_y = -2}, - {.bitmap_index = 56675, .adv_w = 256, .box_w = 14, .box_h = 14, .ofs_x = 2, .ofs_y = -1}, - {.bitmap_index = 56773, .adv_w = 256, .box_w = 14, .box_h = 14, .ofs_x = 2, .ofs_y = -1}, - {.bitmap_index = 56871, .adv_w = 256, .box_w = 15, .box_h = 16, .ofs_x = 1, .ofs_y = -2}, - {.bitmap_index = 56991, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 57111, .adv_w = 256, .box_w = 15, .box_h = 15, .ofs_x = 1, .ofs_y = -2}, - {.bitmap_index = 57224, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 57352, .adv_w = 256, .box_w = 15, .box_h = 16, .ofs_x = 1, .ofs_y = -2}, - {.bitmap_index = 57472, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 57592, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 57720, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 57840, .adv_w = 256, .box_w = 15, .box_h = 15, .ofs_x = 1, .ofs_y = -2}, - {.bitmap_index = 57953, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 58073, .adv_w = 256, .box_w = 14, .box_h = 16, .ofs_x = 1, .ofs_y = -2}, - {.bitmap_index = 58185, .adv_w = 256, .box_w = 14, .box_h = 15, .ofs_x = 1, .ofs_y = -2}, - {.bitmap_index = 58290, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 58410, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 58538, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 58666, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 58794, .adv_w = 256, .box_w = 15, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 58907, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 59035, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 59163, .adv_w = 256, .box_w = 15, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 59283, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 59411, .adv_w = 256, .box_w = 15, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 59531, .adv_w = 256, .box_w = 15, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 59651, .adv_w = 256, .box_w = 15, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 59771, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 59899, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 60027, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 60155, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 60283, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 60403, .adv_w = 256, .box_w = 15, .box_h = 16, .ofs_x = 1, .ofs_y = -2}, - {.bitmap_index = 60523, .adv_w = 256, .box_w = 12, .box_h = 15, .ofs_x = 2, .ofs_y = -2}, - {.bitmap_index = 60613, .adv_w = 256, .box_w = 14, .box_h = 16, .ofs_x = 1, .ofs_y = -2}, - {.bitmap_index = 60725, .adv_w = 256, .box_w = 15, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 60838, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 60958, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 61086, .adv_w = 256, .box_w = 14, .box_h = 15, .ofs_x = 1, .ofs_y = -2}, - {.bitmap_index = 61191, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 61311, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 61431, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 61559, .adv_w = 256, .box_w = 15, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 61679, .adv_w = 256, .box_w = 15, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 61799, .adv_w = 256, .box_w = 15, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 61919, .adv_w = 256, .box_w = 15, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 62039, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 62167, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 62287, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 62407, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 62535, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 62663, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 62783, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 62903, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 63031, .adv_w = 256, .box_w = 15, .box_h = 14, .ofs_x = 0, .ofs_y = -1}, - {.bitmap_index = 63136, .adv_w = 256, .box_w = 15, .box_h = 14, .ofs_x = 0, .ofs_y = -1}, - {.bitmap_index = 63241, .adv_w = 256, .box_w = 15, .box_h = 15, .ofs_x = 0, .ofs_y = -1}, - {.bitmap_index = 63354, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 63474, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 63602, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 63730, .adv_w = 256, .box_w = 14, .box_h = 16, .ofs_x = 1, .ofs_y = -2}, - {.bitmap_index = 63842, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -1}, - {.bitmap_index = 63962, .adv_w = 256, .box_w = 15, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 64082, .adv_w = 256, .box_w = 15, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 64195, .adv_w = 256, .box_w = 15, .box_h = 15, .ofs_x = 1, .ofs_y = -1}, - {.bitmap_index = 64308, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 64436, .adv_w = 256, .box_w = 14, .box_h = 15, .ofs_x = 1, .ofs_y = -1}, - {.bitmap_index = 64541, .adv_w = 256, .box_w = 15, .box_h = 15, .ofs_x = 0, .ofs_y = -1}, - {.bitmap_index = 64654, .adv_w = 256, .box_w = 14, .box_h = 15, .ofs_x = 1, .ofs_y = -2}, - {.bitmap_index = 64759, .adv_w = 256, .box_w = 15, .box_h = 16, .ofs_x = 1, .ofs_y = -2}, - {.bitmap_index = 64879, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 65007, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -1}, - {.bitmap_index = 65127, .adv_w = 256, .box_w = 15, .box_h = 15, .ofs_x = 0, .ofs_y = -1}, - {.bitmap_index = 65240, .adv_w = 256, .box_w = 15, .box_h = 15, .ofs_x = 0, .ofs_y = -1}, - {.bitmap_index = 65353, .adv_w = 256, .box_w = 14, .box_h = 14, .ofs_x = 1, .ofs_y = -1}, - {.bitmap_index = 65451, .adv_w = 256, .box_w = 14, .box_h = 16, .ofs_x = 1, .ofs_y = -2}, - {.bitmap_index = 65563, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 65691, .adv_w = 256, .box_w = 15, .box_h = 14, .ofs_x = 1, .ofs_y = -1}, - {.bitmap_index = 65796, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 65916, .adv_w = 256, .box_w = 15, .box_h = 15, .ofs_x = 1, .ofs_y = -1}, - {.bitmap_index = 66029, .adv_w = 256, .box_w = 16, .box_h = 17, .ofs_x = 0, .ofs_y = -3}, - {.bitmap_index = 66165, .adv_w = 256, .box_w = 15, .box_h = 17, .ofs_x = 0, .ofs_y = -3}, - {.bitmap_index = 66293, .adv_w = 256, .box_w = 16, .box_h = 14, .ofs_x = 0, .ofs_y = -1}, - {.bitmap_index = 66405, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 66525, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 66653, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 66773, .adv_w = 256, .box_w = 15, .box_h = 16, .ofs_x = 1, .ofs_y = -2}, - {.bitmap_index = 66893, .adv_w = 256, .box_w = 16, .box_h = 17, .ofs_x = 0, .ofs_y = -3}, - {.bitmap_index = 67029, .adv_w = 256, .box_w = 15, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 67149, .adv_w = 256, .box_w = 15, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 67269, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 67389, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 67509, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 67637, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 67757, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 67877, .adv_w = 256, .box_w = 16, .box_h = 17, .ofs_x = 0, .ofs_y = -3}, - {.bitmap_index = 68013, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 68141, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 68269, .adv_w = 256, .box_w = 15, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 68389, .adv_w = 256, .box_w = 15, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 68509, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 68629, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 68749, .adv_w = 256, .box_w = 15, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 68862, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 68982, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 69110, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 69238, .adv_w = 256, .box_w = 15, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 69358, .adv_w = 256, .box_w = 15, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 69478, .adv_w = 256, .box_w = 15, .box_h = 15, .ofs_x = 1, .ofs_y = -2}, - {.bitmap_index = 69591, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 69711, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 69839, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 69967, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 70095, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 70223, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 70343, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 70463, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 70591, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 70719, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 70839, .adv_w = 256, .box_w = 15, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 70952, .adv_w = 256, .box_w = 15, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 71072, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 71200, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 71328, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 71456, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 71576, .adv_w = 256, .box_w = 15, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 71696, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 71816, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 71936, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 72064, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 72192, .adv_w = 256, .box_w = 15, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 72305, .adv_w = 256, .box_w = 15, .box_h = 15, .ofs_x = 1, .ofs_y = -2}, - {.bitmap_index = 72418, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 72546, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 72674, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 72794, .adv_w = 256, .box_w = 15, .box_h = 15, .ofs_x = 1, .ofs_y = -2}, - {.bitmap_index = 72907, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 73027, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 73155, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 73283, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 73411, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 73539, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 73659, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 73787, .adv_w = 256, .box_w = 15, .box_h = 15, .ofs_x = 1, .ofs_y = -2}, - {.bitmap_index = 73900, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 74020, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 74140, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 74260, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 74380, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 74508, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 74628, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 74748, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 74868, .adv_w = 256, .box_w = 15, .box_h = 15, .ofs_x = 1, .ofs_y = -2}, - {.bitmap_index = 74981, .adv_w = 256, .box_w = 10, .box_h = 15, .ofs_x = 3, .ofs_y = -2}, - {.bitmap_index = 75056, .adv_w = 256, .box_w = 16, .box_h = 13, .ofs_x = 0, .ofs_y = -1}, - {.bitmap_index = 75160, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 75280, .adv_w = 256, .box_w = 14, .box_h = 16, .ofs_x = 1, .ofs_y = -2}, - {.bitmap_index = 75392, .adv_w = 256, .box_w = 15, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 75505, .adv_w = 256, .box_w = 13, .box_h = 15, .ofs_x = 2, .ofs_y = -2}, - {.bitmap_index = 75603, .adv_w = 256, .box_w = 14, .box_h = 15, .ofs_x = 1, .ofs_y = -2}, - {.bitmap_index = 75708, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 75836, .adv_w = 256, .box_w = 15, .box_h = 14, .ofs_x = 0, .ofs_y = -1}, - {.bitmap_index = 75941, .adv_w = 256, .box_w = 14, .box_h = 15, .ofs_x = 1, .ofs_y = -2}, - {.bitmap_index = 76046, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 76174, .adv_w = 256, .box_w = 15, .box_h = 16, .ofs_x = 1, .ofs_y = -2}, - {.bitmap_index = 76294, .adv_w = 256, .box_w = 15, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 76407, .adv_w = 256, .box_w = 16, .box_h = 14, .ofs_x = 0, .ofs_y = -1}, - {.bitmap_index = 76519, .adv_w = 256, .box_w = 14, .box_h = 15, .ofs_x = 1, .ofs_y = -2}, - {.bitmap_index = 76624, .adv_w = 256, .box_w = 15, .box_h = 16, .ofs_x = 1, .ofs_y = -2}, - {.bitmap_index = 76744, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 76872, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 76992, .adv_w = 256, .box_w = 14, .box_h = 16, .ofs_x = 1, .ofs_y = -2}, - {.bitmap_index = 77104, .adv_w = 256, .box_w = 15, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 77224, .adv_w = 256, .box_w = 15, .box_h = 15, .ofs_x = 1, .ofs_y = -2}, - {.bitmap_index = 77337, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 77457, .adv_w = 256, .box_w = 14, .box_h = 15, .ofs_x = 1, .ofs_y = -2}, - {.bitmap_index = 77562, .adv_w = 256, .box_w = 14, .box_h = 16, .ofs_x = 1, .ofs_y = -2}, - {.bitmap_index = 77674, .adv_w = 256, .box_w = 14, .box_h = 16, .ofs_x = 1, .ofs_y = -2}, - {.bitmap_index = 77786, .adv_w = 256, .box_w = 14, .box_h = 15, .ofs_x = 1, .ofs_y = -2}, - {.bitmap_index = 77891, .adv_w = 256, .box_w = 12, .box_h = 16, .ofs_x = 2, .ofs_y = -2}, - {.bitmap_index = 77987, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 78107, .adv_w = 256, .box_w = 15, .box_h = 16, .ofs_x = 1, .ofs_y = -2}, - {.bitmap_index = 78227, .adv_w = 256, .box_w = 12, .box_h = 16, .ofs_x = 2, .ofs_y = -2}, - {.bitmap_index = 78323, .adv_w = 256, .box_w = 14, .box_h = 16, .ofs_x = 1, .ofs_y = -2}, - {.bitmap_index = 78435, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 78563, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 78691, .adv_w = 256, .box_w = 13, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 78789, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 78917, .adv_w = 256, .box_w = 15, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 79030, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 79150, .adv_w = 256, .box_w = 15, .box_h = 15, .ofs_x = 1, .ofs_y = -2}, - {.bitmap_index = 79263, .adv_w = 256, .box_w = 15, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 79383, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 79503, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 79623, .adv_w = 256, .box_w = 15, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 79736, .adv_w = 256, .box_w = 15, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 79849, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 79977, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 80105, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 80233, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 80361, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 80489, .adv_w = 256, .box_w = 15, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 80609, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 80737, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 80865, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 80993, .adv_w = 256, .box_w = 15, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 81113, .adv_w = 256, .box_w = 15, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 81233, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 81361, .adv_w = 256, .box_w = 15, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 81474, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 81602, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 81730, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 81850, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 81978, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 82106, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 82234, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 82362, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 82490, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 82610, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 82738, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 82866, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 82994, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 83122, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 83250, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 83378, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 83506, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 83634, .adv_w = 256, .box_w = 15, .box_h = 17, .ofs_x = 1, .ofs_y = -3}, - {.bitmap_index = 83762, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 83890, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 84018, .adv_w = 256, .box_w = 15, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 84138, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 84266, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 84394, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 84522, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 84650, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 84770, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 84898, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 85026, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 85154, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 85282, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 85410, .adv_w = 256, .box_w = 16, .box_h = 17, .ofs_x = 0, .ofs_y = -3}, - {.bitmap_index = 85546, .adv_w = 256, .box_w = 15, .box_h = 16, .ofs_x = 1, .ofs_y = -2}, - {.bitmap_index = 85666, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 85786, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 85914, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 86042, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 86170, .adv_w = 256, .box_w = 16, .box_h = 14, .ofs_x = 0, .ofs_y = -1}, - {.bitmap_index = 86282, .adv_w = 256, .box_w = 16, .box_h = 14, .ofs_x = 0, .ofs_y = -1}, - {.bitmap_index = 86394, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 86522, .adv_w = 256, .box_w = 15, .box_h = 16, .ofs_x = 1, .ofs_y = -2}, - {.bitmap_index = 86642, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 86770, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 86898, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 87026, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 87154, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 87274, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 87394, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 87522, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 87650, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 87770, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 87890, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 88018, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 88146, .adv_w = 256, .box_w = 14, .box_h = 14, .ofs_x = 2, .ofs_y = -1}, - {.bitmap_index = 88244, .adv_w = 256, .box_w = 16, .box_h = 14, .ofs_x = 0, .ofs_y = -1}, - {.bitmap_index = 88356, .adv_w = 256, .box_w = 14, .box_h = 15, .ofs_x = 2, .ofs_y = -2}, - {.bitmap_index = 88461, .adv_w = 256, .box_w = 15, .box_h = 15, .ofs_x = 1, .ofs_y = -2}, - {.bitmap_index = 88574, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 88702, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 88830, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 88958, .adv_w = 256, .box_w = 15, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 89078, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 89198, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 89326, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 89446, .adv_w = 256, .box_w = 15, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 89559, .adv_w = 256, .box_w = 15, .box_h = 16, .ofs_x = 1, .ofs_y = -2}, - {.bitmap_index = 89679, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 89799, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 89919, .adv_w = 256, .box_w = 15, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 90039, .adv_w = 256, .box_w = 15, .box_h = 15, .ofs_x = 1, .ofs_y = -2}, - {.bitmap_index = 90152, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 90272, .adv_w = 256, .box_w = 14, .box_h = 15, .ofs_x = 1, .ofs_y = -2}, - {.bitmap_index = 90377, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 90505, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 90633, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 90761, .adv_w = 256, .box_w = 15, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 90874, .adv_w = 256, .box_w = 15, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 90987, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 91115, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 91235, .adv_w = 256, .box_w = 15, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 91348, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 91468, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 91588, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 91716, .adv_w = 256, .box_w = 15, .box_h = 16, .ofs_x = 1, .ofs_y = -2}, - {.bitmap_index = 91836, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 91956, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 92084, .adv_w = 256, .box_w = 14, .box_h = 16, .ofs_x = 1, .ofs_y = -2}, - {.bitmap_index = 92196, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 92316, .adv_w = 256, .box_w = 15, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 92429, .adv_w = 256, .box_w = 16, .box_h = 14, .ofs_x = 0, .ofs_y = -1}, - {.bitmap_index = 92541, .adv_w = 256, .box_w = 15, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 92661, .adv_w = 256, .box_w = 15, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 92774, .adv_w = 256, .box_w = 15, .box_h = 16, .ofs_x = 1, .ofs_y = -2}, - {.bitmap_index = 92894, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 93014, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 93142, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 93262, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 93382, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 93510, .adv_w = 256, .box_w = 15, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 93623, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 93743, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 93863, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 93991, .adv_w = 256, .box_w = 15, .box_h = 16, .ofs_x = 1, .ofs_y = -2}, - {.bitmap_index = 94111, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 94239, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 94367, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 94495, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 94623, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 94751, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 94879, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 94999, .adv_w = 256, .box_w = 14, .box_h = 16, .ofs_x = 1, .ofs_y = -2}, - {.bitmap_index = 95111, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 95239, .adv_w = 256, .box_w = 14, .box_h = 16, .ofs_x = 1, .ofs_y = -2}, - {.bitmap_index = 95351, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 95479, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 95599, .adv_w = 256, .box_w = 15, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 95712, .adv_w = 256, .box_w = 15, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 95832, .adv_w = 256, .box_w = 15, .box_h = 15, .ofs_x = 1, .ofs_y = -2}, - {.bitmap_index = 95945, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 96065, .adv_w = 256, .box_w = 16, .box_h = 14, .ofs_x = 0, .ofs_y = -1}, - {.bitmap_index = 96177, .adv_w = 256, .box_w = 14, .box_h = 16, .ofs_x = 1, .ofs_y = -2}, - {.bitmap_index = 96289, .adv_w = 256, .box_w = 15, .box_h = 16, .ofs_x = 1, .ofs_y = -2}, - {.bitmap_index = 96409, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 96529, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 96657, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 96785, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 96913, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 97033, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 97153, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 97281, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 97401, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 97529, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 97649, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 97769, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 97889, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 98009, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 98129, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 98257, .adv_w = 256, .box_w = 16, .box_h = 14, .ofs_x = 0, .ofs_y = -1}, - {.bitmap_index = 98369, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 98489, .adv_w = 256, .box_w = 15, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 98602, .adv_w = 256, .box_w = 15, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 98722, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -1}, - {.bitmap_index = 98842, .adv_w = 256, .box_w = 15, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 98962, .adv_w = 256, .box_w = 15, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 99082, .adv_w = 256, .box_w = 15, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 99195, .adv_w = 256, .box_w = 13, .box_h = 14, .ofs_x = 2, .ofs_y = -1}, - {.bitmap_index = 99286, .adv_w = 256, .box_w = 13, .box_h = 15, .ofs_x = 2, .ofs_y = -2}, - {.bitmap_index = 99384, .adv_w = 256, .box_w = 13, .box_h = 16, .ofs_x = 2, .ofs_y = -2}, - {.bitmap_index = 99488, .adv_w = 256, .box_w = 13, .box_h = 15, .ofs_x = 2, .ofs_y = -1}, - {.bitmap_index = 99586, .adv_w = 256, .box_w = 14, .box_h = 15, .ofs_x = 1, .ofs_y = -2}, - {.bitmap_index = 99691, .adv_w = 256, .box_w = 15, .box_h = 15, .ofs_x = 1, .ofs_y = -2}, - {.bitmap_index = 99804, .adv_w = 256, .box_w = 14, .box_h = 15, .ofs_x = 1, .ofs_y = -2}, - {.bitmap_index = 99909, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 100029, .adv_w = 256, .box_w = 14, .box_h = 15, .ofs_x = 1, .ofs_y = -2}, - {.bitmap_index = 100134, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 100262, .adv_w = 256, .box_w = 15, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 100382, .adv_w = 256, .box_w = 15, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 100495, .adv_w = 256, .box_w = 14, .box_h = 16, .ofs_x = 1, .ofs_y = -2}, - {.bitmap_index = 100607, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 100735, .adv_w = 256, .box_w = 15, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 100855, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 100983, .adv_w = 256, .box_w = 15, .box_h = 15, .ofs_x = 1, .ofs_y = -2}, - {.bitmap_index = 101096, .adv_w = 256, .box_w = 15, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 101216, .adv_w = 256, .box_w = 12, .box_h = 15, .ofs_x = 2, .ofs_y = -2}, - {.bitmap_index = 101306, .adv_w = 256, .box_w = 15, .box_h = 15, .ofs_x = 1, .ofs_y = -2}, - {.bitmap_index = 101419, .adv_w = 256, .box_w = 13, .box_h = 16, .ofs_x = 2, .ofs_y = -2}, - {.bitmap_index = 101523, .adv_w = 256, .box_w = 14, .box_h = 15, .ofs_x = 2, .ofs_y = -2}, - {.bitmap_index = 101628, .adv_w = 256, .box_w = 16, .box_h = 12, .ofs_x = 0, .ofs_y = 0}, - {.bitmap_index = 101724, .adv_w = 256, .box_w = 15, .box_h = 16, .ofs_x = 1, .ofs_y = -2}, - {.bitmap_index = 101844, .adv_w = 256, .box_w = 11, .box_h = 15, .ofs_x = 3, .ofs_y = -2}, - {.bitmap_index = 101927, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -1}, - {.bitmap_index = 102047, .adv_w = 256, .box_w = 15, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 102167, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 102295, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 102423, .adv_w = 256, .box_w = 15, .box_h = 15, .ofs_x = 1, .ofs_y = -2}, - {.bitmap_index = 102536, .adv_w = 256, .box_w = 14, .box_h = 15, .ofs_x = 1, .ofs_y = -2}, - {.bitmap_index = 102641, .adv_w = 256, .box_w = 15, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 102761, .adv_w = 256, .box_w = 15, .box_h = 15, .ofs_x = 1, .ofs_y = -2}, - {.bitmap_index = 102874, .adv_w = 256, .box_w = 15, .box_h = 16, .ofs_x = 1, .ofs_y = -2}, - {.bitmap_index = 102994, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 103114, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 103242, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 103362, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 103482, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 103610, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 103730, .adv_w = 256, .box_w = 15, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 103843, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 103963, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 104083, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 104203, .adv_w = 256, .box_w = 15, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 104323, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 104451, .adv_w = 256, .box_w = 15, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 104571, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 104699, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 104819, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 104947, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 105075, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 105195, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 105315, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 105435, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 105555, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 105675, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 105803, .adv_w = 256, .box_w = 15, .box_h = 16, .ofs_x = 1, .ofs_y = -2}, - {.bitmap_index = 105923, .adv_w = 256, .box_w = 15, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 106036, .adv_w = 256, .box_w = 15, .box_h = 15, .ofs_x = 1, .ofs_y = -1}, - {.bitmap_index = 106149, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -1}, - {.bitmap_index = 106269, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 106389, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -1}, - {.bitmap_index = 106509, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 106637, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 106757, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 106885, .adv_w = 256, .box_w = 15, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 106998, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 107126, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 107254, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 107382, .adv_w = 256, .box_w = 15, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 107502, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 107630, .adv_w = 256, .box_w = 15, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 107750, .adv_w = 256, .box_w = 15, .box_h = 16, .ofs_x = 1, .ofs_y = -2}, - {.bitmap_index = 107870, .adv_w = 256, .box_w = 15, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 107990, .adv_w = 256, .box_w = 15, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 108110, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 108238, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 108366, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 108494, .adv_w = 256, .box_w = 15, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 108614, .adv_w = 256, .box_w = 16, .box_h = 14, .ofs_x = 0, .ofs_y = -1}, - {.bitmap_index = 108726, .adv_w = 256, .box_w = 15, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 108839, .adv_w = 256, .box_w = 15, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 108952, .adv_w = 256, .box_w = 15, .box_h = 16, .ofs_x = 1, .ofs_y = -2}, - {.bitmap_index = 109072, .adv_w = 256, .box_w = 15, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 109192, .adv_w = 256, .box_w = 15, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 109305, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 109425, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 109545, .adv_w = 256, .box_w = 16, .box_h = 14, .ofs_x = 0, .ofs_y = -1}, - {.bitmap_index = 109657, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 109777, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 109905, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 110025, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 110145, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 110265, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 110385, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 110513, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 110633, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 110753, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 110873, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 111001, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 111129, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 111257, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 111377, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 111505, .adv_w = 256, .box_w = 15, .box_h = 14, .ofs_x = 0, .ofs_y = -1}, - {.bitmap_index = 111610, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 111738, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 111866, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 111994, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 112114, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 112242, .adv_w = 256, .box_w = 15, .box_h = 16, .ofs_x = 1, .ofs_y = -2}, - {.bitmap_index = 112362, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 112490, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 112610, .adv_w = 256, .box_w = 15, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 112730, .adv_w = 256, .box_w = 16, .box_h = 17, .ofs_x = 0, .ofs_y = -3}, - {.bitmap_index = 112866, .adv_w = 256, .box_w = 13, .box_h = 15, .ofs_x = 1, .ofs_y = -2}, - {.bitmap_index = 112964, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 113084, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 113212, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 113332, .adv_w = 256, .box_w = 15, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 113445, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 113565, .adv_w = 256, .box_w = 15, .box_h = 15, .ofs_x = 1, .ofs_y = -2}, - {.bitmap_index = 113678, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 113806, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 113934, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 114054, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 114182, .adv_w = 256, .box_w = 13, .box_h = 16, .ofs_x = 2, .ofs_y = -2}, - {.bitmap_index = 114286, .adv_w = 256, .box_w = 14, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 114398, .adv_w = 256, .box_w = 15, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 114518, .adv_w = 256, .box_w = 14, .box_h = 15, .ofs_x = 1, .ofs_y = -2}, - {.bitmap_index = 114623, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 114743, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 114871, .adv_w = 256, .box_w = 15, .box_h = 15, .ofs_x = 1, .ofs_y = -2}, - {.bitmap_index = 114984, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 115104, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 115224, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 115344, .adv_w = 256, .box_w = 15, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 115457, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 115577, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 115705, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 115833, .adv_w = 256, .box_w = 11, .box_h = 15, .ofs_x = 3, .ofs_y = -2}, - {.bitmap_index = 115916, .adv_w = 256, .box_w = 15, .box_h = 14, .ofs_x = 0, .ofs_y = -1}, - {.bitmap_index = 116021, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 116149, .adv_w = 256, .box_w = 15, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 116269, .adv_w = 256, .box_w = 15, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 116382, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 116510, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 116638, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 116766, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 116894, .adv_w = 256, .box_w = 13, .box_h = 16, .ofs_x = 2, .ofs_y = -2}, - {.bitmap_index = 116998, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -1}, - {.bitmap_index = 117118, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 117238, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 117358, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 117486, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 117614, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 117734, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 117854, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 117974, .adv_w = 256, .box_w = 15, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 118087, .adv_w = 256, .box_w = 15, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 118200, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 118320, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 118448, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 118576, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 118704, .adv_w = 256, .box_w = 15, .box_h = 16, .ofs_x = 1, .ofs_y = -2}, - {.bitmap_index = 118824, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 118952, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 119080, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 119208, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 119336, .adv_w = 256, .box_w = 15, .box_h = 15, .ofs_x = 1, .ofs_y = -2}, - {.bitmap_index = 119449, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 119569, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 119697, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 119825, .adv_w = 256, .box_w = 14, .box_h = 16, .ofs_x = 1, .ofs_y = -2}, - {.bitmap_index = 119937, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 120065, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 120193, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 120313, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 120441, .adv_w = 256, .box_w = 15, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 120554, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 120674, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 120794, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 120914, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 121034, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 121154, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 121274, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 121402, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 121522, .adv_w = 256, .box_w = 15, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 121642, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 121762, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 121890, .adv_w = 256, .box_w = 14, .box_h = 16, .ofs_x = 1, .ofs_y = -2}, - {.bitmap_index = 122002, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 122122, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 122242, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 122362, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 122490, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 122610, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 122730, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 122858, .adv_w = 256, .box_w = 15, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 122971, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 123099, .adv_w = 256, .box_w = 15, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 123219, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 123339, .adv_w = 256, .box_w = 15, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 123452, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 123572, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 123692, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 123820, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 123940, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 124060, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 124188, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 124308, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 124428, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 124556, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 124684, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 124812, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 124940, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 125060, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 125180, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 125308, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 125428, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 125556, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 125684, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 125804, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 125924, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 126052, .adv_w = 256, .box_w = 15, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 126172, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 126300, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 126428, .adv_w = 256, .box_w = 16, .box_h = 17, .ofs_x = 0, .ofs_y = -3}, - {.bitmap_index = 126564, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 126692, .adv_w = 256, .box_w = 15, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 126805, .adv_w = 256, .box_w = 15, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 126918, .adv_w = 256, .box_w = 15, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 127038, .adv_w = 256, .box_w = 15, .box_h = 16, .ofs_x = 1, .ofs_y = -2}, - {.bitmap_index = 127158, .adv_w = 256, .box_w = 14, .box_h = 16, .ofs_x = 1, .ofs_y = -2}, - {.bitmap_index = 127270, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 127390, .adv_w = 256, .box_w = 15, .box_h = 15, .ofs_x = 1, .ofs_y = -2}, - {.bitmap_index = 127503, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 127623, .adv_w = 256, .box_w = 15, .box_h = 16, .ofs_x = 1, .ofs_y = -2}, - {.bitmap_index = 127743, .adv_w = 256, .box_w = 13, .box_h = 15, .ofs_x = 1, .ofs_y = -2}, - {.bitmap_index = 127841, .adv_w = 256, .box_w = 15, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 127961, .adv_w = 256, .box_w = 15, .box_h = 16, .ofs_x = 1, .ofs_y = -2}, - {.bitmap_index = 128081, .adv_w = 256, .box_w = 14, .box_h = 16, .ofs_x = 1, .ofs_y = -2}, - {.bitmap_index = 128193, .adv_w = 256, .box_w = 15, .box_h = 16, .ofs_x = 1, .ofs_y = -2}, - {.bitmap_index = 128313, .adv_w = 256, .box_w = 15, .box_h = 16, .ofs_x = 1, .ofs_y = -2}, - {.bitmap_index = 128433, .adv_w = 256, .box_w = 14, .box_h = 15, .ofs_x = 1, .ofs_y = -2}, - {.bitmap_index = 128538, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 128666, .adv_w = 256, .box_w = 14, .box_h = 16, .ofs_x = 1, .ofs_y = -2}, - {.bitmap_index = 128778, .adv_w = 256, .box_w = 15, .box_h = 16, .ofs_x = 1, .ofs_y = -2}, - {.bitmap_index = 128898, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 129026, .adv_w = 256, .box_w = 16, .box_h = 17, .ofs_x = 0, .ofs_y = -3}, - {.bitmap_index = 129162, .adv_w = 256, .box_w = 16, .box_h = 17, .ofs_x = 0, .ofs_y = -3}, - {.bitmap_index = 129298, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 129418, .adv_w = 256, .box_w = 15, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 129538, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 129666, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 129786, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 129914, .adv_w = 256, .box_w = 15, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 130034, .adv_w = 256, .box_w = 15, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 130154, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 130282, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 130410, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 130538, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 130666, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 130794, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 130922, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 131050, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 131178, .adv_w = 256, .box_w = 15, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 131291, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 131419, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 131547, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 131675, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 131795, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 131915, .adv_w = 256, .box_w = 16, .box_h = 14, .ofs_x = 0, .ofs_y = -1}, - {.bitmap_index = 132027, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 132147, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 132267, .adv_w = 256, .box_w = 16, .box_h = 14, .ofs_x = 0, .ofs_y = -1}, - {.bitmap_index = 132379, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 132507, .adv_w = 256, .box_w = 16, .box_h = 14, .ofs_x = 0, .ofs_y = -1}, - {.bitmap_index = 132619, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 132739, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 132859, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 132979, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 133099, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 133219, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 133339, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 133459, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 133579, .adv_w = 256, .box_w = 16, .box_h = 14, .ofs_x = 0, .ofs_y = -1}, - {.bitmap_index = 133691, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 133811, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 133931, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 134051, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 134171, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 134291, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 134411, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 134531, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -1}, - {.bitmap_index = 134651, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 134779, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 134907, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 135027, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 135155, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 135275, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 135403, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 135523, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 135651, .adv_w = 256, .box_w = 15, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 135764, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 135884, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 136004, .adv_w = 256, .box_w = 15, .box_h = 15, .ofs_x = 1, .ofs_y = -2}, - {.bitmap_index = 136117, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 136245, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 136365, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 136485, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 136613, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 136741, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 136861, .adv_w = 256, .box_w = 15, .box_h = 14, .ofs_x = 0, .ofs_y = -1}, - {.bitmap_index = 136966, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 137086, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 137206, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 137334, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 137462, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 137582, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 137702, .adv_w = 256, .box_w = 16, .box_h = 14, .ofs_x = 0, .ofs_y = -1}, - {.bitmap_index = 137814, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 137942, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 138062, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 138182, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 138302, .adv_w = 256, .box_w = 13, .box_h = 15, .ofs_x = 2, .ofs_y = -2}, - {.bitmap_index = 138400, .adv_w = 256, .box_w = 13, .box_h = 15, .ofs_x = 2, .ofs_y = -2}, - {.bitmap_index = 138498, .adv_w = 256, .box_w = 13, .box_h = 16, .ofs_x = 2, .ofs_y = -2}, - {.bitmap_index = 138602, .adv_w = 256, .box_w = 13, .box_h = 15, .ofs_x = 2, .ofs_y = -2}, - {.bitmap_index = 138700, .adv_w = 256, .box_w = 13, .box_h = 15, .ofs_x = 2, .ofs_y = -2}, - {.bitmap_index = 138798, .adv_w = 256, .box_w = 14, .box_h = 15, .ofs_x = 1, .ofs_y = -2}, - {.bitmap_index = 138903, .adv_w = 256, .box_w = 13, .box_h = 15, .ofs_x = 2, .ofs_y = -2}, - {.bitmap_index = 139001, .adv_w = 256, .box_w = 14, .box_h = 15, .ofs_x = 2, .ofs_y = -2}, - {.bitmap_index = 139106, .adv_w = 256, .box_w = 14, .box_h = 16, .ofs_x = 2, .ofs_y = -2}, - {.bitmap_index = 139218, .adv_w = 256, .box_w = 15, .box_h = 15, .ofs_x = 1, .ofs_y = -2}, - {.bitmap_index = 139331, .adv_w = 256, .box_w = 15, .box_h = 15, .ofs_x = 1, .ofs_y = -2}, - {.bitmap_index = 139444, .adv_w = 256, .box_w = 14, .box_h = 16, .ofs_x = 1, .ofs_y = -2}, - {.bitmap_index = 139556, .adv_w = 256, .box_w = 15, .box_h = 15, .ofs_x = 1, .ofs_y = -2}, - {.bitmap_index = 139669, .adv_w = 256, .box_w = 14, .box_h = 15, .ofs_x = 1, .ofs_y = -2}, - {.bitmap_index = 139774, .adv_w = 256, .box_w = 15, .box_h = 15, .ofs_x = 1, .ofs_y = -2}, - {.bitmap_index = 139887, .adv_w = 256, .box_w = 15, .box_h = 16, .ofs_x = 1, .ofs_y = -2}, - {.bitmap_index = 140007, .adv_w = 256, .box_w = 14, .box_h = 15, .ofs_x = 1, .ofs_y = -2}, - {.bitmap_index = 140112, .adv_w = 256, .box_w = 15, .box_h = 15, .ofs_x = 1, .ofs_y = -2}, - {.bitmap_index = 140225, .adv_w = 256, .box_w = 15, .box_h = 16, .ofs_x = 1, .ofs_y = -2}, - {.bitmap_index = 140345, .adv_w = 256, .box_w = 15, .box_h = 16, .ofs_x = 1, .ofs_y = -2}, - {.bitmap_index = 140465, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 140593, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 140713, .adv_w = 256, .box_w = 15, .box_h = 15, .ofs_x = 1, .ofs_y = -2}, - {.bitmap_index = 140826, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 140954, .adv_w = 256, .box_w = 15, .box_h = 15, .ofs_x = 1, .ofs_y = -2}, - {.bitmap_index = 141067, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 141195, .adv_w = 256, .box_w = 14, .box_h = 15, .ofs_x = 1, .ofs_y = -2}, - {.bitmap_index = 141300, .adv_w = 256, .box_w = 15, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 141413, .adv_w = 256, .box_w = 14, .box_h = 16, .ofs_x = 1, .ofs_y = -2}, - {.bitmap_index = 141525, .adv_w = 256, .box_w = 14, .box_h = 15, .ofs_x = 1, .ofs_y = -1}, - {.bitmap_index = 141630, .adv_w = 256, .box_w = 15, .box_h = 15, .ofs_x = 1, .ofs_y = -2}, - {.bitmap_index = 141743, .adv_w = 256, .box_w = 15, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 141863, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 141991, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 142119, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 142239, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 142359, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 142479, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 142607, .adv_w = 256, .box_w = 15, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 142727, .adv_w = 256, .box_w = 14, .box_h = 16, .ofs_x = 1, .ofs_y = -2}, - {.bitmap_index = 142839, .adv_w = 256, .box_w = 15, .box_h = 15, .ofs_x = 1, .ofs_y = -2}, - {.bitmap_index = 142952, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 143072, .adv_w = 256, .box_w = 15, .box_h = 15, .ofs_x = 1, .ofs_y = -2}, - {.bitmap_index = 143185, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 143305, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 143425, .adv_w = 256, .box_w = 15, .box_h = 15, .ofs_x = 1, .ofs_y = -2}, - {.bitmap_index = 143538, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 143658, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 143778, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 143898, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 144018, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 144138, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 144258, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 144378, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 144498, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 144626, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 144746, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 144866, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 144986, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 145114, .adv_w = 256, .box_w = 15, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 145234, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 145362, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 145482, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 145602, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 145730, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 145858, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 145978, .adv_w = 256, .box_w = 15, .box_h = 16, .ofs_x = 1, .ofs_y = -2}, - {.bitmap_index = 146098, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 146226, .adv_w = 256, .box_w = 15, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 146346, .adv_w = 256, .box_w = 15, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 146466, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 146586, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 146706, .adv_w = 256, .box_w = 15, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 146826, .adv_w = 256, .box_w = 14, .box_h = 15, .ofs_x = 1, .ofs_y = -2}, - {.bitmap_index = 146931, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 147051, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 147179, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 147307, .adv_w = 256, .box_w = 15, .box_h = 16, .ofs_x = 1, .ofs_y = -2}, - {.bitmap_index = 147427, .adv_w = 256, .box_w = 16, .box_h = 17, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 147563, .adv_w = 256, .box_w = 16, .box_h = 12, .ofs_x = 0, .ofs_y = 0}, - {.bitmap_index = 147659, .adv_w = 256, .box_w = 16, .box_h = 14, .ofs_x = 0, .ofs_y = -1}, - {.bitmap_index = 147771, .adv_w = 256, .box_w = 16, .box_h = 12, .ofs_x = 0, .ofs_y = 0}, - {.bitmap_index = 147867, .adv_w = 176, .box_w = 11, .box_h = 12, .ofs_x = 0, .ofs_y = 0}, - {.bitmap_index = 147933, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 148061, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 148189, .adv_w = 288, .box_w = 18, .box_h = 14, .ofs_x = 0, .ofs_y = -1}, - {.bitmap_index = 148315, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 148443, .adv_w = 288, .box_w = 18, .box_h = 12, .ofs_x = 0, .ofs_y = 0}, - {.bitmap_index = 148551, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 148679, .adv_w = 128, .box_w = 8, .box_h = 14, .ofs_x = 0, .ofs_y = -1}, - {.bitmap_index = 148735, .adv_w = 192, .box_w = 12, .box_h = 14, .ofs_x = 0, .ofs_y = -1}, - {.bitmap_index = 148819, .adv_w = 288, .box_w = 18, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 148963, .adv_w = 256, .box_w = 16, .box_h = 12, .ofs_x = 0, .ofs_y = 0}, - {.bitmap_index = 149059, .adv_w = 176, .box_w = 11, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 149147, .adv_w = 224, .box_w = 10, .box_h = 16, .ofs_x = 2, .ofs_y = -2}, - {.bitmap_index = 149227, .adv_w = 224, .box_w = 14, .box_h = 18, .ofs_x = 0, .ofs_y = -3}, - {.bitmap_index = 149353, .adv_w = 224, .box_w = 14, .box_h = 15, .ofs_x = 0, .ofs_y = -1}, - {.bitmap_index = 149458, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -1}, - {.bitmap_index = 149556, .adv_w = 224, .box_w = 10, .box_h = 16, .ofs_x = 2, .ofs_y = -2}, - {.bitmap_index = 149636, .adv_w = 224, .box_w = 16, .box_h = 14, .ofs_x = -1, .ofs_y = -1}, - {.bitmap_index = 149748, .adv_w = 160, .box_w = 10, .box_h = 14, .ofs_x = 0, .ofs_y = -1}, - {.bitmap_index = 149818, .adv_w = 160, .box_w = 10, .box_h = 14, .ofs_x = 0, .ofs_y = -1}, - {.bitmap_index = 149888, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -1}, - {.bitmap_index = 149986, .adv_w = 224, .box_w = 14, .box_h = 4, .ofs_x = 0, .ofs_y = 4}, - {.bitmap_index = 150014, .adv_w = 288, .box_w = 18, .box_h = 12, .ofs_x = 0, .ofs_y = 0}, - {.bitmap_index = 150122, .adv_w = 320, .box_w = 20, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 150282, .adv_w = 288, .box_w = 20, .box_h = 16, .ofs_x = -1, .ofs_y = -2}, - {.bitmap_index = 150442, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 150570, .adv_w = 224, .box_w = 14, .box_h = 10, .ofs_x = 0, .ofs_y = 1}, - {.bitmap_index = 150640, .adv_w = 224, .box_w = 14, .box_h = 10, .ofs_x = 0, .ofs_y = 1}, - {.bitmap_index = 150710, .adv_w = 320, .box_w = 20, .box_h = 14, .ofs_x = 0, .ofs_y = -1}, - {.bitmap_index = 150850, .adv_w = 256, .box_w = 16, .box_h = 12, .ofs_x = 0, .ofs_y = 0}, - {.bitmap_index = 150946, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 151074, .adv_w = 256, .box_w = 17, .box_h = 17, .ofs_x = -1, .ofs_y = -2}, - {.bitmap_index = 151219, .adv_w = 224, .box_w = 15, .box_h = 14, .ofs_x = 0, .ofs_y = -1}, - {.bitmap_index = 151324, .adv_w = 224, .box_w = 14, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 151436, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -1}, - {.bitmap_index = 151534, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -1}, - {.bitmap_index = 151632, .adv_w = 256, .box_w = 16, .box_h = 12, .ofs_x = 0, .ofs_y = 0}, - {.bitmap_index = 151728, .adv_w = 160, .box_w = 12, .box_h = 16, .ofs_x = -1, .ofs_y = -2}, - {.bitmap_index = 151824, .adv_w = 224, .box_w = 14, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 151936, .adv_w = 224, .box_w = 14, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 152048, .adv_w = 288, .box_w = 18, .box_h = 12, .ofs_x = 0, .ofs_y = 0}, - {.bitmap_index = 152156, .adv_w = 256, .box_w = 18, .box_h = 18, .ofs_x = -1, .ofs_y = -3}, - {.bitmap_index = 152318, .adv_w = 192, .box_w = 12, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 152414, .adv_w = 320, .box_w = 20, .box_h = 15, .ofs_x = 0, .ofs_y = -1}, - {.bitmap_index = 152564, .adv_w = 320, .box_w = 20, .box_h = 10, .ofs_x = 0, .ofs_y = 1}, - {.bitmap_index = 152664, .adv_w = 320, .box_w = 20, .box_h = 10, .ofs_x = 0, .ofs_y = 1}, - {.bitmap_index = 152764, .adv_w = 320, .box_w = 20, .box_h = 10, .ofs_x = 0, .ofs_y = 1}, - {.bitmap_index = 152864, .adv_w = 320, .box_w = 20, .box_h = 10, .ofs_x = 0, .ofs_y = 1}, - {.bitmap_index = 152964, .adv_w = 320, .box_w = 20, .box_h = 10, .ofs_x = 0, .ofs_y = 1}, - {.bitmap_index = 153064, .adv_w = 320, .box_w = 21, .box_h = 14, .ofs_x = 0, .ofs_y = -1}, - {.bitmap_index = 153211, .adv_w = 224, .box_w = 12, .box_h = 16, .ofs_x = 1, .ofs_y = -2}, - {.bitmap_index = 153307, .adv_w = 224, .box_w = 14, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 153419, .adv_w = 256, .box_w = 17, .box_h = 17, .ofs_x = -1, .ofs_y = -3}, - {.bitmap_index = 153564, .adv_w = 320, .box_w = 20, .box_h = 12, .ofs_x = 0, .ofs_y = 0}, - {.bitmap_index = 153684, .adv_w = 192, .box_w = 12, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 153780, .adv_w = 258, .box_w = 17, .box_h = 11, .ofs_x = 0, .ofs_y = 1}, - {.bitmap_index = 153874, .adv_w = 256, .box_w = 5, .box_h = 14, .ofs_x = 9, .ofs_y = -1}, - {.bitmap_index = 153909, .adv_w = 256, .box_w = 5, .box_h = 14, .ofs_x = 2, .ofs_y = -1}, - {.bitmap_index = 153944, .adv_w = 256, .box_w = 4, .box_h = 5, .ofs_x = 1, .ofs_y = -1}, - {.bitmap_index = 153954, .adv_w = 256, .box_w = 6, .box_h = 11, .ofs_x = 5, .ofs_y = 0}, - {.bitmap_index = 153987, .adv_w = 256, .box_w = 8, .box_h = 12, .ofs_x = 4, .ofs_y = 0} -}; - -/*--------------------- - * CHARACTER MAPPING - *--------------------*/ - -static const uint16_t unicode_list_1[] = { - 0x0, 0x1, 0x4, 0xb, 0xc, 0x40, 0x41, 0x42, - 0x43, 0x45, 0x46, 0x47 -}; - -static const uint8_t glyph_id_ofs_list_4[] = { - 0, 0, 0, 1, 2, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 3, 4, 5, 6, 0, 7, - 8, 9, 0, 10, 11, 12, 13, 14, - 15, 16, 17, 18, 19, 20, 21, 22, - 23, 24, 25, 26, 27, 28, 29, 0, - 30, 31, 32, 0, 33, 34, 0, 35, - 36, 37, 38, 39, 40, 0, 41, 42, - 43, 44, 45, 46, 47, 48, 49, 50, - 51, 0, 52, 53, 54, 55, 56, 57, - 58, 59, 60, 61, 62, 63, 64, 0, - 65, 66, 67, 68, 69, 70, 71 -}; - -static const uint16_t unicode_list_5[] = { - 0x0, 0x4, 0x7, 0xd, 0x1d11, 0x1d14, 0x1d18, 0x1d19, - 0x1d1a, 0x1d1b, 0x1d1c, 0x1d1e, 0x1d24, 0x1d25, 0x1d27, 0x1d32, - 0x1d37, 0x1d3e, 0x1d4c, 0x1d56, 0x1d5c, 0x1d5f, 0x1d60, 0x1d68, - 0x1d6e, 0x1d70, 0x1d97, 0x1d99, 0x1d9a, 0x1d9c, 0x1d9d, 0x1da5, - 0x1dac, 0x1db2, 0x1db5, 0x1db7, 0x1dbd, 0x1dcb, 0x1dd1, 0x1ddb, - 0x1ddc, 0x1dde, 0x1de6, 0x1de7, 0x1de9, 0x1df4, 0x1df5, 0x1df6, - 0x1dff, 0x1e07, 0x1e0c, 0x1e0e, 0x1e12, 0x1e1b, 0x1e22, 0x1e2b, - 0x1e2e, 0x1e49, 0x1e4d, 0x1e57, 0x1e5e, 0x1e5f, 0x1e60, 0x1e64, - 0x1e66, 0x1e6a, 0x1e6d, 0x1e71, 0x1e90, 0x1e97, 0x1e9c, 0x1eac, - 0x1eae, 0x1eb2, 0x1ed0, 0x1ed3, 0x1eee, 0x1ef2, 0x1eff, 0x1f1c, - 0x1f22, 0x1f2a, 0x1f30, 0x1f35, 0x1f4d, 0x1f6b, 0x1f6d, 0x1f76, - 0x1f85, 0x1faa, 0x1fc4, 0x1fd6, 0x1fde, 0x1fe0, 0x1fe6, 0x200a, - 0x2015, 0x203b, 0x2050, 0x2054, 0x2055, 0x2056, 0x2059, 0x205a, - 0x205c, 0x205e, 0x2063, 0x206b, 0x2076, 0x2078, 0x2079, 0x207a, - 0x207c, 0x207d, 0x207e, 0x2082, 0x2087, 0x2088, 0x2096, 0x2097, - 0x209b, 0x209e, 0x20aa, 0x20ac, 0x20bd, 0x20c8, 0x20de, 0x20ee, - 0x20f7, 0x210b, 0x2117, 0x2118, 0x211b, 0x2128, 0x212e, 0x2135, - 0x2136, 0x213a, 0x2141, 0x2147, 0x2149, 0x214c, 0x2158, 0x215b, - 0x215e, 0x216c, 0x2183, 0x2186, 0x2194, 0x21ac, 0x21b0, 0x21b1, - 0x21b9, 0x21ba, 0x21bb, 0x21c4, 0x21da, 0x21e6, 0x21ea, 0x21ee, - 0x21f5, 0x2206, 0x2216, 0x2227, 0x2228, 0x224c, 0x2251, 0x2252, - 0x2254, 0x2259, 0x225b, 0x2263, 0x2265, 0x2268, 0x2269, 0x2282, - 0x2284, 0x228c, 0x22ab, 0x22b0, 0x22c4, 0x22cc, 0x22d3, 0x22d4, - 0x22d9, 0x22db, 0x22dc, 0x22de, 0x22e7, 0x22e8, 0x22f4, 0x22f5, - 0x22f6, 0x22f7, 0x22fb, 0x22fc, 0x2300, 0x2301, 0x2303, 0x2304, - 0x2308, 0x2309, 0x2314, 0x2315, 0x2319, 0x231d, 0x231e, 0x2322, - 0x2337, 0x2338, 0x2351, 0x235b, 0x2373, 0x2379, 0x2384, 0x238d, - 0x238e, 0x239d, 0x23c3, 0x23d2, 0x23f2, 0x23fb, 0x2457, 0x245b, - 0x2460, 0x2477, 0x2495, 0x249a, 0x24ad, 0x24ae, 0x24bf, 0x24c7, - 0x24df, 0x2500, 0x252c, 0x25c5, 0x25ec, 0x25ef, 0x25f1, 0x2601, - 0x2604, 0x260e, 0x261c, 0x261e, 0x2623, 0x2629, 0x2630, 0x2634, - 0x2639, 0x2641, 0x2658, 0x265b, 0x2661, 0x269c, 0x26f0, 0x2708, - 0x270b, 0x2742, 0x2745, 0x275b, 0x277a, 0x2794, 0x27a8, 0x27af, - 0x27db, 0x27e4, 0x27fc, 0x2801, 0x2803, 0x281a, 0x2820, 0x2826, - 0x2827, 0x282b, 0x282d, 0x2831, 0x2838, 0x283a, 0x283b, 0x283c, - 0x283f, 0x2842, 0x2858, 0x2862, 0x2868, 0x2884, 0x288a, 0x288e, - 0x2893, 0x2898, 0x28c4, 0x28ca, 0x28cc, 0x28da, 0x28dc, 0x28e1, - 0x28e5, 0x2929, 0x296b, 0x2977, 0x29a3, 0x29ce, 0x29dd, 0x2a1a, - 0x2a61, 0x2a68, 0x2a69, 0x2a74, 0x2a77, 0x2a7a, 0x2a7c, 0x2a89, - 0x2a94, 0x2a96, 0x2a98, 0x2a99, 0x2a9a, 0x2a9d, 0x2aa9, 0x2aaa, - 0x2aab, 0x2aaf, 0x2ab0, 0x2ab3, 0x2ab5, 0x2ac4, 0x2ac6, 0x2ac7, - 0x2aca, 0x2ad0, 0x2ad5, 0x2ad7, 0x2add, 0x2ae3, 0x2aee, 0x2af0, - 0x2af7, 0x2afc, 0x2b0b, 0x2b0f, 0x2b15, 0x2b18, 0x2b19, 0x2b1e, - 0x2b1f, 0x2b20, 0x2b22, 0x2b2b, 0x2b35, 0x2b42, 0x2b4b, 0x2b51, - 0x2b56, 0x2b5b, 0x2b5c, 0x2b66, 0x2b76, 0x2b7d, 0x2b82, 0x2c07, - 0x2c5d, 0x2cee, 0x2cef, 0x2cf6, 0x2cf7, 0x2cff, 0x2d02, 0x2d03, - 0x2d13, 0x2d14, 0x2d19, 0x2d1d, 0x2d3c, 0x2d3e, 0x2d40, 0x2d41, - 0x2d44, 0x2d47, 0x2d49, 0x2d56, 0x2d84, 0x2d85, 0x2d89, 0x2d8f, - 0x2d94, 0x2d97, 0x2da6, 0x2da8, 0x2dad, 0x2db7, 0x2db8, 0x2dbc, - 0x2dbe, 0x2dc8, 0x2df1, 0x2e0b, 0x2e10, 0x2e20, 0x2e26, 0x2e30, - 0x2e42, 0x2e46, 0x2e48, 0x2e64, 0x2e73, 0x2e82, 0x2e8a, 0x2e8d, - 0x2e91, 0x2e96, 0x2e99, 0x2e9c, 0x2e9d, 0x2ea3, 0x2ea4, 0x2ea8, - 0x2eaf, 0x2eb2, 0x2eba, 0x2ed4, 0x2ed6, 0x2ee9, 0x2eea, 0x2efc, - 0x2f06, 0x2f1f, 0x2f23, 0x2f26, 0x2f2e, 0x2f36, 0x2f38, 0x2f80, - 0x2fb9, 0x2fbb, 0x2fc3, 0x2fd6, 0x3004, 0x3019, 0x3020, 0x302b, - 0x302c, 0x3030, 0x305c, 0x3074, 0x3078, 0x307f, 0x30da, 0x3109, - 0x3121, 0x3122, 0x3127, 0x3137, 0x3141, 0x314c, 0x3150, 0x3151, - 0x315c, 0x315e, 0x3164, 0x3166, 0x318f, 0x3191, 0x319b, 0x31a6, - 0x31cd, 0x31d6, 0x31da, 0x31ec, 0x31f2, 0x31fd, 0x31fe, 0x3210, - 0x3212, 0x3218, 0x322a, 0x3266, 0x3279, 0x3299, 0x32a3, 0x32ac, - 0x32b2, 0x32b3, 0x32b6, 0x32b8, 0x32b9, 0x32e0, 0x32e1, 0x32ec, - 0x32ff, 0x330b, 0x334b, 0x33d2, 0x33d8, 0x33e5, 0x33eb, 0x3440, - 0x344a, 0x344f, 0x3450, 0x3456, 0x3459, 0x3468, 0x346a, 0x3473, - 0x3481, 0x3485, 0x3498, 0x34aa, 0x34be, 0x34c1, 0x34c8, 0x34ca, - 0x34cd, 0x34ce, 0x34d2, 0x34d6, 0x34e0, 0x34f3, 0x34f6, 0x34f7, - 0x34fa, 0x3507, 0x3518, 0x351f, 0x3524, 0x3525, 0x3530, 0x3531, - 0x3536, 0x3539, 0x3540, 0x354d, 0x3553, 0x357a, 0x357f, 0x3580, - 0x3585, 0x358b, 0x3598, 0x35a2, 0x35a7, 0x35a8, 0x35d8, 0x35ed, - 0x3603, 0x3605, 0x3609, 0x360f, 0x3610, 0x3611, 0x3614, 0x3619, - 0x361a, 0x361c, 0x361e, 0x362c, 0x362e, 0x3630, 0x3639, 0x363b, - 0x363c, 0x363d, 0x363e, 0x364b, 0x3661, 0x3662, 0x3670, 0x3672, - 0x3676, 0x3680, 0x3682, 0x36a1, 0x36a8, 0x36ad, 0x36e1, 0x36f6, - 0x3702, 0x370c, 0x3710, 0x3722, 0x3732, 0x373b, 0x374a, 0x374d, - 0x3754, 0x3759, 0x37ae, 0x37c1, 0x37ff, 0x381e, 0x382d, 0x386b, - 0x387e, 0x3886, 0x388e, 0x3893, 0x38dc, 0x38e9, 0x3913, 0x392a, - 0x3932, 0x3934, 0x393b, 0x394a, 0x395c, 0x3970, 0x3a32, 0x3a43, - 0x3a5d, 0x3a61, 0x3a72, 0x3a73, 0x3a74, 0x3a75, 0x3a76, 0x3a7a, - 0x3a80, 0x3a83, 0x3a84, 0x3a88, 0x3a8c, 0x3a9b, 0x3a9c, 0x3ac6, - 0x3ade, 0x3adf, 0x3ae0, 0x3ae5, 0x3aec, 0x3b20, 0x3b22, 0x3b25, - 0x3b28, 0x3b45, 0x3b48, 0x3b49, 0x3b53, 0x3b6b, 0x3b71, 0x3b8b, - 0x3b99, 0x3ba3, 0x3bca, 0x3bcc, 0x3bd2, 0x3bdb, 0x3be6, 0x3bf3, - 0x3bf4, 0x3bf9, 0x3c04, 0x3c1c, 0x3c28, 0x3c43, 0x3c4c, 0x3c4f, - 0x3c52, 0x3c56, 0x3c85, 0x3c88, 0x3c99, 0x3ccd, 0x3d02, 0x3d08, - 0x3d16, 0x3d18, 0x3d19, 0x3d1a, 0x3d2c, 0x3d32, 0x3d3a, 0x3d40, - 0x3d67, 0x3da1, 0x3da7, 0x3dae, 0x3e10, 0x3e33, 0x3e49, 0x3ed4, - 0x3ef0, 0x3f74, 0x3f7c, 0x3f8e, 0x3fca, 0x3fcb, 0x4032, 0x4047, - 0x406a, 0x40c2, 0x40f0, 0x413e, 0x4147, 0x4149, 0x4158, 0x416c, - 0x4171, 0x417a, 0x418a, 0x41bd, 0x41c0, 0x41c7, 0x41d1, 0x41fd, - 0x41fe, 0x423c, 0x4250, 0x4283, 0x42ba, 0x430f, 0x4314, 0x4317, - 0x43c1, 0x4429, 0x442b, 0x4430, 0x4433, 0x4434, 0x4439, 0x4441, - 0x4442, 0x4444, 0x4446, 0x4448, 0x444b, 0x444c, 0x445d, 0x446a, - 0x447b, 0x447c, 0x4481, 0x4487, 0x44c3, 0x44d6, 0x44ec, 0x458b, - 0x458d, 0x458e, 0x458f, 0x4595, 0x4597, 0x45d0, 0x45e8, 0x45ff, - 0x4605, 0x4609, 0x461c, 0x4630, 0x4631, 0x464f, 0x4651, 0x46f6, - 0x46fe, 0x4704, 0x4713, 0x4725, 0x4745, 0x47cb, 0x484b, 0x484d, - 0x484f, 0x4867, 0x486e, 0x486f, 0x487e, 0x4892, 0x48d1, 0x48d2, - 0x48dc, 0x48de, 0x48e2, 0x48e9, 0x490c, 0x491c, 0x493f, 0x495e, - 0x4987, 0x498b, 0x49a4, 0x49dc, 0x49ea, 0x49f6, 0x4a00, 0x4a22, - 0x4a37, 0x4a3d, 0x4a57, 0x4a5a, 0x4a65, 0x4a67, 0x4aa8, 0x4ab2, - 0x4ad1, 0x4ad5, 0x4b32, 0x4b84, 0x4bcf, 0x4be7, 0x4c0c, 0x4c11, - 0x4c15, 0x4c2a, 0x4c31, 0x4c41, 0x4c4a, 0x4c53, 0x4c55, 0x4c5d, - 0x4c61, 0x4c72, 0x4c77, 0x4c82, 0x4c86, 0x4ca4, 0x4cab, 0x4cbe, - 0x4cc3, 0x4ce2, 0x4ce3, 0x4ceb, 0x4cf1, 0x4cfa, 0x4d05, 0x4d4e, - 0x4d4f, 0x4d65, 0x4d81, 0x4d8d, 0x4d9d, 0x4df0, 0x4e4b, 0x4e7f, - 0x4e9f, 0x4eba, 0x4ee3, 0x4f12, 0x4f14, 0x4f16, 0x4f1d, 0x4f44, - 0x4f6f, 0x4f80, 0x4f83, 0x4f88, 0x4f8e, 0x4f9a, 0x4fba, 0x4fc0, - 0x4fc3, 0x4fdd, 0x5009, 0x500e, 0x5042, 0x505b, 0x5066, 0x5077, - 0x5081, 0x50ae, 0x50da, 0x50fb, 0x5104, 0x510b, 0x5118, 0x5119, - 0x511a, 0x513b, 0x513d, 0x514a, 0x5180, 0x5183, 0x5193, 0x51c2, - 0x51f6, 0x51f7, 0x5202, 0x5247, 0x5288, 0x52e4, 0x52ed, 0x534e, - 0x535a, 0x5368, 0x5446, 0x5495, 0x54bd, 0x54ee, 0x5518, 0x5566, - 0x575d, 0x5764, 0x5779, 0x57bc, 0x57e0, 0x57ed, 0x57f2, 0x580e, - 0x5818, 0x5890, 0x5892, 0x589c, 0x58a0, 0x58a7, 0x58ab, 0x58bb, - 0x58cb, 0x58d1, 0x58e3, 0x58f4, 0x58f7, 0x5911, 0x5919, 0x591b, - 0x591f, 0x5924, 0x5929, 0x593b, 0x593e, 0x5942, 0x5944, 0x5945, - 0x5966, 0x5977, 0x5982, 0x5983, 0x5984, 0x599d, 0x599e, 0x59a6, - 0x59a9, 0x59af, 0x59bb, 0x59bd, 0x59be, 0x59c1, 0x59c3, 0x59d0, - 0x59d8, 0x59dc, 0x59e7, 0x5a09, 0x5a13, 0x5a2c, 0x5a2e, 0x5a69, - 0x5a81, 0x5a88, 0x5a9b, 0x5aa4, 0x5ab2, 0x5aef, 0x5b61, 0x5b72, - 0x5bb1, 0x5bb2, 0x5bb8, 0x5bba, 0x5bbd, 0x5bc8, 0x5bc9, 0x5bcc, - 0x5bd0, 0x5bd4, 0x5bd8, 0x5bfb, 0x5c0e, 0x5c4a, 0x5c75, 0x5c81, - 0x5c88, 0x5c96, 0x5c9b, 0x5cb4, 0x5cc4, 0x5cf0, 0x5d00, 0x5dbc, - 0x5ddb, 0x5df0, 0x5df3, 0x5e0e, 0x5e14, 0x5e1a, 0x5e26, 0x5e3b, - 0x5e49, 0x5eac, 0x5eaf, 0x5eb7, 0x5ec3, 0x5ecb, 0x5ecd, 0x5edf, - 0x5ee2, 0x5ee5, 0x5efc, 0x5f0e, 0x5f11, 0x5f12, 0x5f14, 0x5f20, - 0x5f21, 0x5f2a, 0x5f2b, 0x5f30, 0x5f31, 0x5f34, 0x5f3f, 0x5f42, - 0x5f43, 0x5f56, 0x5f5b, 0x5f5c, 0x5f5f, 0x5f64, 0x5f65, 0x5f66, - 0x5f71, 0x5f7a, 0x5f89, 0x5f90, 0x5f95, 0x5f9b, 0x5fb4, 0x5fbb, - 0x5ff9, 0x6006, 0x600e, 0x605e, 0x6063, 0x6065, 0x6089, 0x60bc, - 0x60de, 0x60df, 0x60e0, 0x60e2, 0x60ee, 0x6155, 0x616c, 0x6191, - 0x6233, 0x6240, 0x6243, 0x6488, 0x649a, 0x649c, 0x64a4, 0x64b3, - 0x64ed, 0x6501, 0x6544, 0x6555, 0x655e, 0x6561, 0x6573, 0x6575, - 0x6589, 0x658e, 0x659f, 0x65ac, 0x65ad, 0x65b4, 0x65b9, 0x65cc, - 0x65d7, 0x65e2, 0x65e7, 0x65ea, 0x65f3, 0x65f4, 0x65f9, 0x65fb, - 0x6603, 0x660c, 0x6611, 0x6618, 0x6663, 0x666a, 0x666f, 0x6673, - 0x667a, 0x6685, 0x6704, 0x6710, 0x6714, 0x6716, 0x6719, 0x6728, - 0x6729, 0x673e, 0x674d, 0x675d, 0x6765, 0x6769, 0x676f, 0x6780, - 0x67b9, 0x67ec, 0x67f0, 0x6800, 0x6803, 0x6839, 0x68a7, 0x68aa, - 0x68d5, 0x68d6, 0x6923, 0x6924, 0x6968, 0x69e5, 0x69e9, 0x69fb, - 0x6a6b, 0x6bf6, 0x6da8, 0x6dcd, 0x6dd5, 0x6de3, 0x6def, 0x6df9, - 0x6e24, 0x6e4c, 0xbf12, 0xbf19, 0xbf1c, 0xbf1d, 0xbf1e, 0xbf22, - 0xbf24, 0xbf26, 0xbf2a, 0xbf2d, 0xbf32, 0xbf37, 0xbf38, 0xbf39, - 0xbf4f, 0xbf54, 0xbf59, 0xbf5c, 0xbf5d, 0xbf5e, 0xbf62, 0xbf63, - 0xbf64, 0xbf65, 0xbf78, 0xbf79, 0xbf7f, 0xbf81, 0xbf82, 0xbf85, - 0xbf88, 0xbf89, 0xbf8a, 0xbf8c, 0xbfa4, 0xbfa6, 0xbfd5, 0xbfd6, - 0xbfd8, 0xbfda, 0xbff1, 0xbff8, 0xbffb, 0xc004, 0xc02d, 0xc035, - 0xc06c, 0xc0fc, 0xc151, 0xc152, 0xc153, 0xc154, 0xc155, 0xc198, - 0xc1a4, 0xc1fe, 0xc215, 0xc46b, 0xc6d3, 0xc7b3, 0xce19, 0xce1a, - 0xce1d, 0xce22, 0xce23 -}; - -/*Collect the unicode lists and glyph_id offsets*/ -static const lv_font_fmt_txt_cmap_t cmaps[] = { - { - .range_start = 32, .range_length = 96, .glyph_id_start = 1, - .unicode_list = NULL, .glyph_id_ofs_list = NULL, .list_length = 0, .type = LV_FONT_FMT_TXT_CMAP_FORMAT0_TINY - }, - { - .range_start = 12289, .range_length = 72, .glyph_id_start = 97, - .unicode_list = unicode_list_1, .glyph_id_ofs_list = NULL, .list_length = 12, .type = LV_FONT_FMT_TXT_CMAP_SPARSE_TINY - }, - { - .range_start = 12362, .range_length = 24, .glyph_id_start = 109, - .unicode_list = NULL, .glyph_id_ofs_list = NULL, .list_length = 0, .type = LV_FONT_FMT_TXT_CMAP_FORMAT0_TINY - }, - { - .range_start = 12387, .range_length = 43, .glyph_id_start = 133, - .unicode_list = NULL, .glyph_id_ofs_list = NULL, .list_length = 0, .type = LV_FONT_FMT_TXT_CMAP_FORMAT0_TINY - }, - { - .range_start = 12431, .range_length = 95, .glyph_id_start = 176, - .unicode_list = NULL, .glyph_id_ofs_list = glyph_id_ofs_list_4, .list_length = 95, .type = LV_FONT_FMT_TXT_CMAP_FORMAT0_FULL - }, - { - .range_start = 12527, .range_length = 52772, .glyph_id_start = 248, - .unicode_list = unicode_list_5, .glyph_id_ofs_list = NULL, .list_length = 1187, .type = LV_FONT_FMT_TXT_CMAP_SPARSE_TINY - } -}; - -/*-------------------- - * ALL CUSTOM DATA - *--------------------*/ - -#if LVGL_VERSION_MAJOR >= 8 -/*Store all the custom data of the font*/ - -static const lv_font_fmt_txt_dsc_t font_dsc = { -#else -static lv_font_fmt_txt_dsc_t font_dsc = { -#endif - .glyph_bitmap = glyph_bitmap, - .glyph_dsc = glyph_dsc, - .cmaps = cmaps, - .kern_dsc = NULL, - .kern_scale = 0, - .cmap_num = 6, - .bpp = 4, - .kern_classes = 0, - .bitmap_format = 0, - -}; - -/*----------------- - * PUBLIC FONT - *----------------*/ - -#ifdef _MSC_VER - #pragma deprecated(lv_font_simsun_16_cjk) -#else - #warning "LV_FONT_SIMSUN_16_CJK is deprecated, use LV_FONT_SOURCE_HAN_SANS_SC_16_CJK instead." -#endif - -/*Initialize a public general font descriptor*/ -#if LVGL_VERSION_MAJOR >= 8 -const lv_font_t lv_font_simsun_16_cjk = { -#else -lv_font_t lv_font_simsun_16_cjk = { -#endif - .get_glyph_dsc = lv_font_get_glyph_dsc_fmt_txt, /*Function pointer to get glyph's data*/ - .get_glyph_bitmap = lv_font_get_bitmap_fmt_txt, /*Function pointer to get glyph's bitmap*/ - .line_height = 19, /*The maximum line height required by the font*/ - .base_line = 3, /*Baseline measured from the bottom of the line*/ -#if !(LVGL_VERSION_MAJOR == 6 && LVGL_VERSION_MINOR == 0) - .subpx = LV_FONT_SUBPX_NONE, -#endif -#if LV_VERSION_CHECK(7, 4, 0) || LVGL_VERSION_MAJOR >= 8 - .underline_position = -2, - .underline_thickness = 1, -#endif - .dsc = &font_dsc /*The custom font data. Will be accessed by `get_glyph_bitmap/dsc` */ -}; - -#endif /*#if LV_FONT_SIMSUN_16_CJK*/ diff --git a/src/font/lv_symbol_def.h b/src/font/lv_symbol_def.h index d78f3892d1..a3114d1bab 100644 --- a/src/font/lv_symbol_def.h +++ b/src/font/lv_symbol_def.h @@ -285,7 +285,7 @@ extern "C" { * The following list is generated using * cat src/font/lv_symbol_def.h | sed -E -n 's/^#define\s+LV_(SYMBOL_\w+).*".*$/ LV_STR_\1,/p' */ -enum { +enum _lv_str_symbol_id_t { LV_STR_SYMBOL_BULLET, LV_STR_SYMBOL_AUDIO, LV_STR_SYMBOL_VIDEO, diff --git a/src/indev/lv_indev.c b/src/indev/lv_indev.c index 84ac23f748..a4b16b5a0c 100644 --- a/src/indev/lv_indev.c +++ b/src/indev/lv_indev.c @@ -81,7 +81,6 @@ static void indev_gesture(lv_indev_t * indev); static bool indev_reset_check(lv_indev_t * indev); static void indev_read_core(lv_indev_t * indev, lv_indev_data_t * data); static void indev_reset_core(lv_indev_t * indev, lv_obj_t * obj); -static void indev_init_gesture_recognizers(lv_indev_t * indev); static lv_result_t send_event(lv_event_code_t code, void * param); static void indev_scroll_throw_anim_start(lv_indev_t * indev); @@ -143,7 +142,9 @@ lv_indev_t * lv_indev_create(void) indev->gesture_min_velocity = LV_INDEV_DEF_GESTURE_MIN_VELOCITY; indev->rotary_sensitivity = LV_INDEV_DEF_ROTARY_SENSITIVITY; - indev_init_gesture_recognizers(indev); +#if LV_USE_GESTURE_RECOGNITION + lv_indev_gesture_init(indev); +#endif return indev; } @@ -153,6 +154,7 @@ void lv_indev_delete(lv_indev_t * indev) LV_ASSERT_NULL(indev); lv_indev_send_event(indev, LV_EVENT_DELETE, NULL); + lv_event_mark_deleted(indev); lv_event_remove_all(&(indev->event_list)); /*Clean up the read timer first*/ @@ -195,6 +197,9 @@ void indev_read_core(lv_indev_t * indev, lv_indev_data_t * data) if(indev->read_cb) { LV_TRACE_INDEV("calling indev_read_cb"); indev->read_cb(indev, data); + + /*Set the time stamp to the current time is it was not set in the read_cb*/ + if(data->timestamp == 0) data->timestamp = lv_tick_get(); } else { LV_LOG_WARN("indev_read_cb is not registered"); @@ -245,11 +250,12 @@ void lv_indev_read(lv_indev_t * indev) indev->state = data.state; /*Save the last activity time*/ + indev->timestamp = data.timestamp; if(indev->state == LV_INDEV_STATE_PRESSED) { - indev->disp->last_activity_time = lv_tick_get(); + indev->disp->last_activity_time = data.timestamp; } else if(indev->type == LV_INDEV_TYPE_ENCODER && data.enc_diff) { - indev->disp->last_activity_time = lv_tick_get(); + indev->disp->last_activity_time = data.timestamp; } if(indev->type == LV_INDEV_TYPE_POINTER) { @@ -438,9 +444,8 @@ void lv_indev_stop_processing(lv_indev_t * indev) void lv_indev_reset_long_press(lv_indev_t * indev) { - indev->long_pr_sent = 0; - indev->longpr_rep_timestamp = lv_tick_get(); - indev->pr_timestamp = lv_tick_get(); + indev->long_pr_sent = 0; + indev->longpr_rep_timestamp = indev->pr_timestamp = lv_tick_get(); } void lv_indev_set_cursor(lv_indev_t * indev, lv_obj_t * cur_obj) @@ -666,21 +671,7 @@ uint32_t lv_indev_remove_event_cb_with_user_data(lv_indev_t * indev, lv_event_cb lv_result_t lv_indev_send_event(lv_indev_t * indev, lv_event_code_t code, void * param) { - - lv_event_t e; - lv_memzero(&e, sizeof(e)); - e.code = code; - e.current_target = indev; - e.original_target = indev; - e.param = param; - lv_result_t res; - res = lv_event_send(&indev->event_list, &e, true); - if(res != LV_RESULT_OK) return res; - - res = lv_event_send(&indev->event_list, &e, false); - if(res != LV_RESULT_OK) return res; - - return res; + return lv_event_push_and_send(&indev->event_list, code, indev, param); } /********************** @@ -792,7 +783,7 @@ static void indev_keypad_proc(lv_indev_t * i, lv_indev_data_t * data) /*Key press happened*/ if(data->state == LV_INDEV_STATE_PRESSED && prev_state == LV_INDEV_STATE_RELEASED) { LV_LOG_INFO("%" LV_PRIu32 " key is pressed", data->key); - i->pr_timestamp = lv_tick_get(); + i->pr_timestamp = i->timestamp; /*Move the focus on NEXT*/ if(data->key == LV_KEY_NEXT) { @@ -838,19 +829,19 @@ static void indev_keypad_proc(lv_indev_t * i, lv_indev_data_t * data) } /*Long press time has elapsed?*/ - if(i->long_pr_sent == 0 && lv_tick_elaps(i->pr_timestamp) > i->long_press_time) { + if(i->long_pr_sent == 0 && lv_tick_diff(i->timestamp, i->pr_timestamp) > i->long_press_time) { i->long_pr_sent = 1; if(data->key == LV_KEY_ENTER) { - i->longpr_rep_timestamp = lv_tick_get(); + i->longpr_rep_timestamp = i->timestamp; if(send_event(LV_EVENT_LONG_PRESSED, indev_act) == LV_RESULT_INVALID) return; } } /*Long press repeated time has elapsed?*/ else if(i->long_pr_sent != 0 && - lv_tick_elaps(i->longpr_rep_timestamp) > i->long_press_repeat_time) { + lv_tick_diff(i->timestamp, i->longpr_rep_timestamp) > i->long_press_repeat_time) { - i->longpr_rep_timestamp = lv_tick_get(); + i->longpr_rep_timestamp = i->timestamp; /*Send LONG_PRESS_REP on ENTER*/ if(data->key == LV_KEY_ENTER) { @@ -938,7 +929,7 @@ static void indev_encoder_proc(lv_indev_t * i, lv_indev_data_t * data) if(data->state == LV_INDEV_STATE_PRESSED && last_state == LV_INDEV_STATE_RELEASED) { LV_LOG_INFO("pressed"); - i->pr_timestamp = lv_tick_get(); + i->pr_timestamp = i->timestamp; if(data->key == LV_KEY_ENTER) { bool editable_or_scrollable = lv_obj_is_editable(indev_obj_act) || @@ -976,10 +967,10 @@ static void indev_encoder_proc(lv_indev_t * i, lv_indev_data_t * data) /*Pressing*/ else if(data->state == LV_INDEV_STATE_PRESSED && last_state == LV_INDEV_STATE_PRESSED) { /*Long press*/ - if(i->long_pr_sent == 0 && lv_tick_elaps(i->pr_timestamp) > i->long_press_time) { + if(i->long_pr_sent == 0 && lv_tick_diff(i->timestamp, i->pr_timestamp) > i->long_press_time) { i->long_pr_sent = 1; - i->longpr_rep_timestamp = lv_tick_get(); + i->longpr_rep_timestamp = i->timestamp; if(data->key == LV_KEY_ENTER) { /* Always send event to indev callbacks*/ @@ -1010,9 +1001,9 @@ static void indev_encoder_proc(lv_indev_t * i, lv_indev_data_t * data) i->long_pr_sent = 1; } /*Long press repeated time has elapsed?*/ - else if(i->long_pr_sent != 0 && lv_tick_elaps(i->longpr_rep_timestamp) > i->long_press_repeat_time) { + else if(i->long_pr_sent != 0 && lv_tick_diff(i->timestamp, i->longpr_rep_timestamp) > i->long_press_repeat_time) { - i->longpr_rep_timestamp = lv_tick_get(); + i->longpr_rep_timestamp = i->timestamp; if(data->key == LV_KEY_ENTER) { if(is_enabled) { @@ -1182,6 +1173,20 @@ static void indev_button_proc(lv_indev_t * i, lv_indev_data_t * data) i->pointer.last_point.y = i->pointer.act_point.y; } +/** + * Apply time decay to a scroll throw vector, such that there is no decay + * initially and full decay after a short period of time. + * @param x scroll throw vector component + * @param t expired time in milliseconds + * @return decayed vector component + */ +static int32_t indev_scroll_throw_decay(int32_t x, int32_t t) +{ + if(t <= 0) return x; + if(t >= 99) return 0; + return x * (512 - (512 * t) / 99) / 512; +} + /** * Process the pressed state of LV_INDEV_TYPE_POINTER input devices * @param indev pointer to an input device 'proc' @@ -1253,7 +1258,7 @@ static void indev_proc_press(lv_indev_t * indev) if(indev_obj_act != NULL) { /*Save the time when the obj pressed to count long press time.*/ - indev->pr_timestamp = lv_tick_get(); + indev->pr_timestamp = indev->timestamp; indev->long_pr_sent = 0; indev->pointer.scroll_sum.x = 0; indev->pointer.scroll_sum.y = 0; @@ -1291,12 +1296,21 @@ static void indev_proc_press(lv_indev_t * indev) } } - /*Calculate the vector and apply a low pass filter: new value = 0.5 * old_value + 0.5 * new_value*/ + /*Update vector and scroll throw vector*/ indev->pointer.vect.x = indev->pointer.act_point.x - indev->pointer.last_point.x; indev->pointer.vect.y = indev->pointer.act_point.y - indev->pointer.last_point.y; - indev->pointer.scroll_throw_vect.x = (indev->pointer.scroll_throw_vect.x + indev->pointer.vect.x) / 2; - indev->pointer.scroll_throw_vect.y = (indev->pointer.scroll_throw_vect.y + indev->pointer.vect.y) / 2; + indev->pointer.vect_hist[indev->pointer.vect_hist_index] = indev->pointer.vect; + indev->pointer.vect_hist_timestamp[indev->pointer.vect_hist_index] = indev->timestamp; + indev->pointer.vect_hist_index = (indev->pointer.vect_hist_index + 1) % LV_INDEV_VECT_HIST_SIZE; + + indev->pointer.scroll_throw_vect.x = 0; + indev->pointer.scroll_throw_vect.y = 0; + for(int i = 0; i < LV_INDEV_VECT_HIST_SIZE; i++) { + int32_t t = lv_tick_diff(indev->timestamp, indev->pointer.vect_hist_timestamp[i]); + indev->pointer.scroll_throw_vect.x += indev_scroll_throw_decay(indev->pointer.vect_hist[i].x, t); + indev->pointer.scroll_throw_vect.y += indev_scroll_throw_decay(indev->pointer.vect_hist[i].y, t); + } indev->pointer.scroll_throw_vect_ori = indev->pointer.scroll_throw_vect; @@ -1344,6 +1358,8 @@ static void indev_proc_press(lv_indev_t * indev) indev_gesture(indev); if(indev_reset_check(indev)) return; + /*In event driven mode resume the timer so that it can trigger long pressed and other time related events. + *As a side effect it will also call read_cb periodically in event driven mode. */ if(indev->mode == LV_INDEV_MODE_EVENT && indev->read_timer && lv_timer_get_paused(indev->read_timer)) { lv_timer_resume(indev->read_timer); } @@ -1351,7 +1367,7 @@ static void indev_proc_press(lv_indev_t * indev) /*If there is no scrolling then check for long press time*/ if(indev->pointer.scroll_obj == NULL && indev->long_pr_sent == 0) { /*Send a long press event if enough time elapsed*/ - if(lv_tick_elaps(indev->pr_timestamp) > indev_act->long_press_time) { + if(lv_tick_diff(indev->timestamp, indev->pr_timestamp) > indev_act->long_press_time) { if(is_enabled) { if(send_event(LV_EVENT_LONG_PRESSED, indev_act) == LV_RESULT_INVALID) return; } @@ -1359,16 +1375,16 @@ static void indev_proc_press(lv_indev_t * indev) indev->long_pr_sent = 1; /*Save the long press time stamp for the long press repeat handler*/ - indev->longpr_rep_timestamp = lv_tick_get(); + indev->longpr_rep_timestamp = indev->timestamp; } } if(indev->pointer.scroll_obj == NULL && indev->long_pr_sent == 1) { - if(lv_tick_elaps(indev->longpr_rep_timestamp) > indev_act->long_press_repeat_time) { + if(lv_tick_diff(indev->timestamp, indev->longpr_rep_timestamp) > indev_act->long_press_repeat_time) { if(is_enabled) { if(send_event(LV_EVENT_LONG_PRESSED_REPEAT, indev_act) == LV_RESULT_INVALID) return; } - indev->longpr_rep_timestamp = lv_tick_get(); + indev->longpr_rep_timestamp = indev->timestamp; } } } @@ -1475,9 +1491,9 @@ static void indev_proc_release(lv_indev_t * indev) lv_point_t pivot = { 0, 0 }; lv_obj_t * parent = scroll_obj; while(parent) { - angle += lv_obj_get_style_transform_rotation(parent, 0); - int32_t zoom_act_x = lv_obj_get_style_transform_scale_x_safe(parent, 0); - int32_t zoom_act_y = lv_obj_get_style_transform_scale_y_safe(parent, 0); + angle += lv_obj_get_style_transform_rotation(parent, LV_PART_MAIN); + int32_t zoom_act_x = lv_obj_get_style_transform_scale_x_safe(parent, LV_PART_MAIN); + int32_t zoom_act_y = lv_obj_get_style_transform_scale_y_safe(parent, LV_PART_MAIN); scale_x = (scale_x * zoom_act_x) >> 8; scale_y = (scale_x * zoom_act_y) >> 8; parent = lv_obj_get_parent(parent); @@ -1514,7 +1530,7 @@ static lv_result_t indev_proc_short_click(lv_indev_t * indev) { /*Update streak for clicks within small distance and short time*/ indev->pointer.short_click_streak++; - if(lv_tick_elaps(indev->pointer.last_short_click_timestamp) > indev->long_press_time) { + if(lv_tick_diff(indev->timestamp, indev->pointer.last_short_click_timestamp) > indev->long_press_time) { indev->pointer.short_click_streak = 1; } else if(indev->type == LV_INDEV_TYPE_POINTER || indev->type == LV_INDEV_TYPE_BUTTON) { @@ -1523,7 +1539,7 @@ static lv_result_t indev_proc_short_click(lv_indev_t * indev) if(dx * dx + dy * dy > indev->scroll_limit * indev->scroll_limit) indev->pointer.short_click_streak = 1; } - indev->pointer.last_short_click_timestamp = lv_tick_get(); + indev->pointer.last_short_click_timestamp = indev->timestamp; lv_indev_get_point(indev, &indev->pointer.last_short_click_point); /*Simple short click*/ @@ -1556,7 +1572,7 @@ static void indev_proc_pointer_diff(lv_indev_t * indev) if(editable) { uint32_t indev_sensitivity = indev->rotary_sensitivity; - uint32_t obj_sensitivity = lv_obj_get_style_rotary_sensitivity(indev_obj_act, 0); + uint32_t obj_sensitivity = lv_obj_get_style_rotary_sensitivity(indev_obj_act, LV_PART_MAIN); int32_t diff = (int32_t)((int32_t)indev->pointer.diff * indev_sensitivity * obj_sensitivity + 32768) >> 16; send_event(LV_EVENT_ROTARY, &diff); } @@ -1568,7 +1584,7 @@ static void indev_proc_pointer_diff(lv_indev_t * indev) lv_obj_t * scroll_obj = lv_indev_find_scroll_obj(indev); if(scroll_obj == NULL) return; uint32_t indev_sensitivity = indev->rotary_sensitivity; - uint32_t obj_sensitivity = lv_obj_get_style_rotary_sensitivity(scroll_obj, 0); + uint32_t obj_sensitivity = lv_obj_get_style_rotary_sensitivity(scroll_obj, LV_PART_MAIN); int32_t diff = (int32_t)((int32_t)indev->pointer.diff * indev_sensitivity * obj_sensitivity + 32768) >> 16; indev->pointer.scroll_throw_vect.y = diff; @@ -1608,6 +1624,7 @@ static void indev_proc_reset_query_handler(lv_indev_t * indev) indev->pointer.last_obj = NULL; indev->pointer.scroll_obj = NULL; indev->pointer.last_hovered = NULL; + indev->timestamp = lv_tick_get(); indev->long_pr_sent = 0; indev->pr_timestamp = 0; indev->longpr_rep_timestamp = 0; @@ -1882,21 +1899,3 @@ static void indev_scroll_throw_anim_start(lv_indev_t * indev) indev->scroll_throw_anim = lv_anim_start(&a); } - -/** - * Initialize this indev's recognizers. It specify their recognizer function - * @param indev pointer to the indev containing the recognizers to initialize - */ -static void indev_init_gesture_recognizers(lv_indev_t * indev) -{ -#if LV_USE_GESTURE_RECOGNITION - indev->recognizers[LV_INDEV_GESTURE_NONE].recog_fn = NULL; - indev->recognizers[LV_INDEV_GESTURE_PINCH].recog_fn = lv_indev_gesture_detect_pinch; - indev->recognizers[LV_INDEV_GESTURE_ROTATE].recog_fn = lv_indev_gesture_detect_rotation; - indev->recognizers[LV_INDEV_GESTURE_TWO_FINGERS_SWIPE].recog_fn = lv_indev_gesture_detect_two_fingers_swipe; - indev->recognizers[LV_INDEV_GESTURE_SCROLL].recog_fn = NULL; - indev->recognizers[LV_INDEV_GESTURE_SWIPE].recog_fn = NULL; -#else - LV_UNUSED(indev); -#endif -} diff --git a/src/indev/lv_indev.h b/src/indev/lv_indev.h index d6c60c4049..b59b0cd4a4 100644 --- a/src/indev/lv_indev.h +++ b/src/indev/lv_indev.h @@ -61,17 +61,18 @@ typedef enum { /** Data structure passed to an input driver to fill*/ typedef struct { + lv_indev_gesture_type_t gesture_type[LV_INDEV_GESTURE_CNT]; /* Current gesture types, per gesture */ + void * gesture_data[LV_INDEV_GESTURE_CNT]; /* Used to store data per gesture */ + + lv_indev_state_t state; /**< LV_INDEV_STATE_RELEASED or LV_INDEV_STATE_PRESSED*/ + lv_point_t point; /**< For LV_INDEV_TYPE_POINTER the currently pressed point*/ uint32_t key; /**< For LV_INDEV_TYPE_KEYPAD the currently pressed key*/ uint32_t btn_id; /**< For LV_INDEV_TYPE_BUTTON the currently pressed button*/ int16_t enc_diff; /**< For LV_INDEV_TYPE_ENCODER number of steps since the previous read*/ - lv_indev_state_t state; /**< LV_INDEV_STATE_RELEASED or LV_INDEV_STATE_PRESSED*/ + uint32_t timestamp; /**< Initialized to lv_tick_get(). Driver may provide more accurate timestamp for buffered events*/ bool continue_reading; /**< If set to true, the read callback is invoked again, unless the device is in event-driven mode*/ - - lv_indev_gesture_type_t gesture_type[LV_INDEV_GESTURE_CNT]; /* Current gesture types, per gesture */ - void * gesture_data[LV_INDEV_GESTURE_CNT]; /* Used to store data per gesture */ - } lv_indev_data_t; typedef void (*lv_indev_read_cb_t)(lv_indev_t * indev, lv_indev_data_t * data); diff --git a/src/indev/lv_indev_gesture.c b/src/indev/lv_indev_gesture.c index 928016bb29..29f3ff0bb3 100644 --- a/src/indev/lv_indev_gesture.c +++ b/src/indev/lv_indev_gesture.c @@ -51,6 +51,7 @@ static lv_indev_gesture_recognizer_t * lv_indev_get_gesture_recognizer(lv_event_ lv_indev_gesture_type_t type); static lv_dir_t calculate_swipe_dir(lv_indev_gesture_recognizer_t * recognizer); static lv_indev_gesture_type_t get_first_recognized_or_ended_gesture(lv_indev_t * indev); +static void indev_delete_event_cb(lv_event_t * e); /******************** * STATIC VARIABLES @@ -66,6 +67,19 @@ static lv_indev_gesture_type_t get_first_recognized_or_ended_gesture(lv_indev_t * GLOBAL FUNCTIONS ********************/ +void lv_indev_gesture_init(lv_indev_t * indev) +{ + LV_ASSERT_NULL(indev); + indev->recognizers[LV_INDEV_GESTURE_NONE].recog_fn = NULL; + indev->recognizers[LV_INDEV_GESTURE_PINCH].recog_fn = lv_indev_gesture_detect_pinch; + indev->recognizers[LV_INDEV_GESTURE_ROTATE].recog_fn = lv_indev_gesture_detect_rotation; + indev->recognizers[LV_INDEV_GESTURE_TWO_FINGERS_SWIPE].recog_fn = lv_indev_gesture_detect_two_fingers_swipe; + indev->recognizers[LV_INDEV_GESTURE_SCROLL].recog_fn = NULL; + indev->recognizers[LV_INDEV_GESTURE_SWIPE].recog_fn = NULL; + + lv_indev_add_event_cb(indev, indev_delete_event_cb, LV_EVENT_DELETE, NULL); +} + void lv_indev_set_pinch_up_threshold(lv_indev_t * indev, float threshold) { /* A up threshold MUST always be bigger than 1 */ @@ -221,20 +235,9 @@ void lv_indev_set_gesture_data(lv_indev_data_t * data, lv_indev_gesture_recogniz lv_indev_gesture_type_t type) { bool is_active; - lv_point_t cur_pnt; if(recognizer == NULL) return; - /* If there is a single contact point use its coords, - * when there are no contact points it's set to 0,0 - * - * Note: If a gesture was detected, the primary point is overwritten below - */ - - lv_indev_get_gesture_primary_point(recognizer, &cur_pnt); - data->point.x = cur_pnt.x; - data->point.y = cur_pnt.y; - data->gesture_type[type] = LV_INDEV_GESTURE_NONE; data->gesture_data[type] = NULL; @@ -251,9 +254,6 @@ void lv_indev_set_gesture_data(lv_indev_data_t * data, lv_indev_gesture_recogniz switch(recognizer->state) { case LV_INDEV_GESTURE_STATE_RECOGNIZED: - lv_indev_get_gesture_center_point(recognizer, &cur_pnt); - data->point.x = cur_pnt.x; - data->point.y = cur_pnt.y; data->gesture_type[type] = type; data->gesture_data[type] = (void *) recognizer; break; @@ -552,7 +552,7 @@ void lv_indev_gesture_recognizers_update(lv_indev_t * indev, lv_indev_touch_data /* Update all recognizers to let them process input */ indev->recognizers[i].recog_fn(&indev->recognizers[i], &touches[0], touch_cnt); - /* Then reset the recognizers which did not repport RECONIZED or ENDED */ + /* Then reset the recognizers which did not report RECOGNIZED or ENDED */ if(((lv_indev_gesture_type_t)i) != type) { reset_recognizer(&indev->recognizers[i]); } @@ -610,7 +610,7 @@ void lv_indev_gesture_recognizers_set_data(lv_indev_t * indev, lv_indev_data_t * ********************/ /** - * Caluclate the direction from the starting center of a two fingers swipe gesture + * Calculate the direction from the starting center of a two fingers swipe gesture * @param recognizer pointer to the recognizer handling the two fingers * swipe gesture * @return the direction of the swipe, from the starting center @@ -960,5 +960,22 @@ static lv_indev_gesture_type_t get_first_recognized_or_ended_gesture(lv_indev_t return LV_INDEV_GESTURE_NONE; } +static void indev_delete_event_cb(lv_event_t * e) +{ + lv_indev_t * indev = lv_event_get_current_target(e); + + for(uint8_t i = 0; i < LV_INDEV_GESTURE_CNT; i++) { + if(indev->recognizers[i].info) { + lv_free(indev->recognizers[i].info); + indev->recognizers[i].info = NULL; + } + + if(indev->recognizers[i].config) { + lv_free(indev->recognizers[i].config); + indev->recognizers[i].config = NULL; + } + } +} + #endif /* LV_USE_GESTURE_RECOGNITION */ diff --git a/src/indev/lv_indev_gesture.h b/src/indev/lv_indev_gesture.h index 08318b9157..111d7b2b4e 100644 --- a/src/indev/lv_indev_gesture.h +++ b/src/indev/lv_indev_gesture.h @@ -84,6 +84,11 @@ struct lv_indev_gesture_recognizer { * GLOBAL PROTOTYPES **********************/ +/** + * Initialize this indev's recognizers. It specifies their recognizer functions + * @param indev pointer to the indev containing the recognizers to initialize + */ +void lv_indev_gesture_init(lv_indev_t * indev); /* PINCH Gesture */ @@ -241,4 +246,4 @@ void lv_indev_gesture_recognizers_set_data(lv_indev_t * indev, lv_indev_data_t * } /*extern "C"*/ #endif -#endif /* END LV_INDEV_GESTURE_H */ +#endif /* LV_INDEV_GESTURE_H */ diff --git a/src/indev/lv_indev_gesture_private.h b/src/indev/lv_indev_gesture_private.h index 752672dfcc..e927f424a9 100644 --- a/src/indev/lv_indev_gesture_private.h +++ b/src/indev/lv_indev_gesture_private.h @@ -94,4 +94,4 @@ struct lv_indev_gesture_configuration { } /*extern "C"*/ #endif -#endif /* END LV_INDEV_GESTURE_PRIVATE_H */ +#endif /* LV_INDEV_GESTURE_PRIVATE_H */ diff --git a/src/indev/lv_indev_private.h b/src/indev/lv_indev_private.h index 83b65c77b8..6c8f5c2466 100644 --- a/src/indev/lv_indev_private.h +++ b/src/indev/lv_indev_private.h @@ -21,6 +21,7 @@ extern "C" { /********************* * DEFINES *********************/ +#define LV_INDEV_VECT_HIST_SIZE 8 /********************** * TYPEDEFS @@ -44,6 +45,7 @@ struct _lv_indev_t { uint8_t wait_until_release : 1; uint8_t stop_processing_query : 1; + uint32_t timestamp; /**< Timestamp of last event */ uint32_t pr_timestamp; /**< Pressed time stamp*/ uint32_t longpr_rep_timestamp; /**< Long press repeat time stamp*/ @@ -83,6 +85,9 @@ struct _lv_indev_t { lv_point_t last_point; /**< Last point of input device.*/ lv_point_t last_raw_point; /**< Last point read from read_cb. */ lv_point_t vect; /**< Difference between `act_point` and `last_point`.*/ + lv_point_t vect_hist[LV_INDEV_VECT_HIST_SIZE]; + uint32_t vect_hist_timestamp[LV_INDEV_VECT_HIST_SIZE]; + uint8_t vect_hist_index; lv_point_t scroll_sum; /*Count the dragged pixels to check LV_INDEV_DEF_SCROLL_LIMIT*/ lv_point_t scroll_throw_vect; lv_point_t scroll_throw_vect_ori; diff --git a/src/indev/lv_indev_scroll.c b/src/indev/lv_indev_scroll.c index 7996467a46..ae7d27537d 100644 --- a/src/indev/lv_indev_scroll.c +++ b/src/indev/lv_indev_scroll.c @@ -69,9 +69,9 @@ void lv_indev_scroll_handler(lv_indev_t * indev) int16_t scale_y = 256; lv_obj_t * parent = scroll_obj; while(parent) { - angle += lv_obj_get_style_transform_rotation(parent, 0); - int32_t zoom_act_x = lv_obj_get_style_transform_scale_x_safe(parent, 0); - int32_t zoom_act_y = lv_obj_get_style_transform_scale_y_safe(parent, 0); + angle += lv_obj_get_style_transform_rotation(parent, LV_PART_MAIN); + int32_t zoom_act_x = lv_obj_get_style_transform_scale_x_safe(parent, LV_PART_MAIN); + int32_t zoom_act_y = lv_obj_get_style_transform_scale_y_safe(parent, LV_PART_MAIN); scale_x = (scale_x * zoom_act_x) >> 8; scale_y = (scale_y * zoom_act_y) >> 8; parent = lv_obj_get_parent(parent); @@ -293,9 +293,9 @@ lv_obj_t * lv_indev_find_scroll_obj(lv_indev_t * indev) lv_point_t pivot = { 0, 0 }; lv_obj_t * parent = obj_act; while(parent) { - angle += lv_obj_get_style_transform_rotation(parent, 0); - int32_t zoom_act_x = lv_obj_get_style_transform_scale_x_safe(parent, 0); - int32_t zoom_act_y = lv_obj_get_style_transform_scale_y_safe(parent, 0); + angle += lv_obj_get_style_transform_rotation(parent, LV_PART_MAIN); + int32_t zoom_act_x = lv_obj_get_style_transform_scale_x_safe(parent, LV_PART_MAIN); + int32_t zoom_act_y = lv_obj_get_style_transform_scale_y_safe(parent, LV_PART_MAIN); scale_x = (scale_x * zoom_act_x) >> 8; scale_y = (scale_y * zoom_act_y) >> 8; parent = lv_obj_get_parent(parent); @@ -652,7 +652,7 @@ static int32_t elastic_diff(lv_obj_t * scroll_obj, int32_t diff, int32_t scroll_ * then respect the current position instead of going straight back to 0. */ const int32_t scroll_ended = diff > 0 ? scroll_start : scroll_end; - if(scroll_ended < 0) diff = 0; + if(scroll_ended <= 0) diff = 0; else if(scroll_ended - diff < 0) diff = scroll_ended; } /*Handle elastic scrolling*/ @@ -717,18 +717,18 @@ static void has_more_snap_points(lv_obj_t * scroll_obj, lv_dir_t dir, bool * has int32_t x = 0; switch(snap) { case LV_SCROLL_SNAP_CENTER: { - int32_t pad_left = lv_obj_get_style_pad_left(scroll_obj, 0); - int32_t pad_right = lv_obj_get_style_pad_right(scroll_obj, 0); + int32_t pad_left = lv_obj_get_style_pad_left(scroll_obj, LV_PART_MAIN); + int32_t pad_right = lv_obj_get_style_pad_right(scroll_obj, LV_PART_MAIN); x = scroll_obj->coords.x1; x += (lv_area_get_width(&scroll_obj->coords) - pad_left - pad_right) / 2; x += pad_left; } break; case LV_SCROLL_SNAP_START: - x = scroll_obj->coords.x1 + lv_obj_get_style_pad_left(scroll_obj, 0); + x = scroll_obj->coords.x1 + lv_obj_get_style_pad_left(scroll_obj, LV_PART_MAIN); break; case LV_SCROLL_SNAP_END: - x = scroll_obj->coords.x2 - lv_obj_get_style_pad_right(scroll_obj, 0); + x = scroll_obj->coords.x2 - lv_obj_get_style_pad_right(scroll_obj, LV_PART_MAIN); break; default: break; @@ -743,18 +743,18 @@ static void has_more_snap_points(lv_obj_t * scroll_obj, lv_dir_t dir, bool * has int32_t y = 0; switch(snap) { case LV_SCROLL_SNAP_CENTER: { - int32_t pad_top = lv_obj_get_style_pad_top(scroll_obj, 0); - int32_t pad_bottom = lv_obj_get_style_pad_bottom(scroll_obj, 0); + int32_t pad_top = lv_obj_get_style_pad_top(scroll_obj, LV_PART_MAIN); + int32_t pad_bottom = lv_obj_get_style_pad_bottom(scroll_obj, LV_PART_MAIN); y = scroll_obj->coords.y1; y += (lv_area_get_height(&scroll_obj->coords) - pad_top - pad_bottom) / 2; y += pad_top; } break; case LV_SCROLL_SNAP_START: - y = scroll_obj->coords.y1 + lv_obj_get_style_pad_top(scroll_obj, 0); + y = scroll_obj->coords.y1 + lv_obj_get_style_pad_top(scroll_obj, LV_PART_MAIN); break; case LV_SCROLL_SNAP_END: - y = scroll_obj->coords.y2 - lv_obj_get_style_pad_bottom(scroll_obj, 0); + y = scroll_obj->coords.y2 - lv_obj_get_style_pad_bottom(scroll_obj, LV_PART_MAIN); break; default: break; diff --git a/src/layouts/flex/lv_flex.c b/src/layouts/flex/lv_flex.c index 0f8b7d66a6..b9603c1e7d 100644 --- a/src/layouts/flex/lv_flex.c +++ b/src/layouts/flex/lv_flex.c @@ -339,7 +339,7 @@ static void children_repos(lv_obj_t * cont, flex_t * f, int32_t item_first_id, i int32_t (*area_get_main_size)(const lv_area_t *) = (f->row ? lv_area_get_width : lv_area_get_height); int32_t (*area_get_cross_size)(const lv_area_t *) = (!f->row ? lv_area_get_width : lv_area_get_height); - typedef int32_t (*margin_func_t)(const lv_obj_t *, uint32_t); + typedef int32_t (*margin_func_t)(const lv_obj_t *, lv_part_t); margin_func_t get_margin_main_start = (f->row ? lv_obj_get_style_margin_left : lv_obj_get_style_margin_top); margin_func_t get_margin_main_end = (f->row ? lv_obj_get_style_margin_right : lv_obj_get_style_margin_bottom); margin_func_t get_margin_cross_start = (!f->row ? lv_obj_get_style_margin_left : lv_obj_get_style_margin_top); @@ -386,7 +386,7 @@ static void children_repos(lv_obj_t * cont, flex_t * f, int32_t item_first_id, i int32_t place_gap = 0; place_content(f->main_place, max_main_size, t->track_main_size, t->item_cnt, &main_pos, &place_gap); - if(f->row && rtl) main_pos += lv_obj_get_content_width(cont); + if(f->row && rtl) main_pos = max_main_size - main_pos; lv_obj_t * item = lv_obj_get_child(cont, item_first_id); /*Reposition the children*/ diff --git a/src/layouts/grid/lv_grid.c b/src/layouts/grid/lv_grid.c index c688c2508f..7efd28d059 100644 --- a/src/layouts/grid/lv_grid.c +++ b/src/layouts/grid/lv_grid.c @@ -54,10 +54,10 @@ typedef struct { * STATIC PROTOTYPES **********************/ static void grid_update(lv_obj_t * cont, void * user_data); -static void calc(lv_obj_t * obj, lv_grid_calc_t * calc); +static lv_result_t calc(lv_obj_t * obj, lv_grid_calc_t * calc); static void calc_free(lv_grid_calc_t * calc); -static void calc_cols(lv_obj_t * cont, lv_grid_calc_t * c); -static void calc_rows(lv_obj_t * cont, lv_grid_calc_t * c); +static lv_result_t calc_cols(lv_obj_t * cont, lv_grid_calc_t * c); +static lv_result_t calc_rows(lv_obj_t * cont, lv_grid_calc_t * c); static void item_repos(lv_obj_t * item, lv_grid_calc_t * c, item_repos_hint_t * hint); static int32_t grid_align(int32_t cont_size, bool auto_size, lv_grid_align_t align, int32_t gap, uint32_t track_num, @@ -66,43 +66,43 @@ static uint32_t count_tracks(const int32_t * templ); static inline const int32_t * get_col_dsc(lv_obj_t * obj) { - return lv_obj_get_style_grid_column_dsc_array(obj, 0); + return lv_obj_get_style_grid_column_dsc_array(obj, LV_PART_MAIN); } static inline const int32_t * get_row_dsc(lv_obj_t * obj) { - return lv_obj_get_style_grid_row_dsc_array(obj, 0); + return lv_obj_get_style_grid_row_dsc_array(obj, LV_PART_MAIN); } static inline int32_t get_col_pos(lv_obj_t * obj) { - return lv_obj_get_style_grid_cell_column_pos(obj, 0); + return lv_obj_get_style_grid_cell_column_pos(obj, LV_PART_MAIN); } static inline int32_t get_row_pos(lv_obj_t * obj) { - return lv_obj_get_style_grid_cell_row_pos(obj, 0); + return lv_obj_get_style_grid_cell_row_pos(obj, LV_PART_MAIN); } static inline int32_t get_col_span(lv_obj_t * obj) { - return lv_obj_get_style_grid_cell_column_span(obj, 0); + return lv_obj_get_style_grid_cell_column_span(obj, LV_PART_MAIN); } static inline int32_t get_row_span(lv_obj_t * obj) { - return lv_obj_get_style_grid_cell_row_span(obj, 0); + return lv_obj_get_style_grid_cell_row_span(obj, LV_PART_MAIN); } static inline lv_grid_align_t get_cell_col_align(lv_obj_t * obj) { - return lv_obj_get_style_grid_cell_x_align(obj, 0); + return lv_obj_get_style_grid_cell_x_align(obj, LV_PART_MAIN); } static inline lv_grid_align_t get_cell_row_align(lv_obj_t * obj) { - return lv_obj_get_style_grid_cell_y_align(obj, 0); + return lv_obj_get_style_grid_cell_y_align(obj, LV_PART_MAIN); } static inline lv_grid_align_t get_grid_col_align(lv_obj_t * obj) { - return lv_obj_get_style_grid_column_align(obj, 0); + return lv_obj_get_style_grid_column_align(obj, LV_PART_MAIN); } static inline lv_grid_align_t get_grid_row_align(lv_obj_t * obj) { - return lv_obj_get_style_grid_row_align(obj, 0); + return lv_obj_get_style_grid_row_align(obj, LV_PART_MAIN); } static inline int32_t get_margin_hor(lv_obj_t * obj) { @@ -189,12 +189,9 @@ static void grid_update(lv_obj_t * cont, void * user_data) LV_LOG_INFO("update %p container", (void *)cont); LV_UNUSED(user_data); - // const int32_t * col_templ = get_col_dsc(cont); - // const int32_t * row_templ = get_row_dsc(cont); - // if(col_templ == NULL || row_templ == NULL) return; - lv_grid_calc_t c; - calc(cont, &c); + lv_result_t res = calc(cont, &c); + if(res != LV_RESULT_OK) return; item_repos_hint_t hint; lv_memzero(&hint, sizeof(hint)); @@ -230,15 +227,21 @@ static void grid_update(lv_obj_t * cont, void * user_data) * @param calc store the calculated cells sizes here * @note `lv_grid_calc_free(calc_out)` needs to be called when `calc_out` is not needed anymore */ -static void calc(lv_obj_t * cont, lv_grid_calc_t * calc_out) +static lv_result_t calc(lv_obj_t * cont, lv_grid_calc_t * calc_out) { if(lv_obj_get_child(cont, 0) == NULL) { lv_memzero(calc_out, sizeof(lv_grid_calc_t)); - return; + return LV_RESULT_INVALID; } - calc_rows(cont, calc_out); - calc_cols(cont, calc_out); + if(calc_rows(cont, calc_out) == LV_RESULT_INVALID) { + /* Warning is already logged inside `calc_rows` */ + return LV_RESULT_INVALID; + } + if(calc_cols(cont, calc_out) == LV_RESULT_INVALID) { + /* Warning is already logged inside `calc_cols` */ + return LV_RESULT_INVALID; + } int32_t col_gap = lv_obj_get_style_pad_column(cont, LV_PART_MAIN); int32_t row_gap = lv_obj_get_style_pad_row(cont, LV_PART_MAIN); @@ -258,6 +261,7 @@ static void calc(lv_obj_t * cont, lv_grid_calc_t * calc_out) calc_out->y, false); LV_ASSERT_MEM_INTEGRITY(); + return LV_RESULT_OK; } /** @@ -272,7 +276,7 @@ static void calc_free(lv_grid_calc_t * calc) lv_free(calc->h); } -static void calc_cols(lv_obj_t * cont, lv_grid_calc_t * c) +static lv_result_t calc_cols(lv_obj_t * cont, lv_grid_calc_t * c) { const int32_t * col_templ; @@ -283,7 +287,7 @@ static void calc_cols(lv_obj_t * cont, lv_grid_calc_t * c) col_templ = get_col_dsc(parent); if(col_templ == NULL) { LV_LOG_WARN("No col descriptor found even on the parent"); - return; + return LV_RESULT_INVALID; } int32_t pos = get_col_pos(cont); @@ -363,9 +367,10 @@ static void calc_cols(lv_obj_t * cont, lv_grid_calc_t * c) if(subgrid) { lv_free((void *)col_templ); } + return LV_RESULT_OK; } -static void calc_rows(lv_obj_t * cont, lv_grid_calc_t * c) +static lv_result_t calc_rows(lv_obj_t * cont, lv_grid_calc_t * c) { const int32_t * row_templ; row_templ = get_row_dsc(cont); @@ -375,7 +380,7 @@ static void calc_rows(lv_obj_t * cont, lv_grid_calc_t * c) row_templ = get_row_dsc(parent); if(row_templ == NULL) { LV_LOG_WARN("No row descriptor found even on the parent"); - return; + return LV_RESULT_INVALID; } int32_t pos = get_row_pos(cont); @@ -452,6 +457,7 @@ static void calc_rows(lv_obj_t * cont, lv_grid_calc_t * c) if(subgrid) { lv_free((void *)row_templ); } + return LV_RESULT_OK; } /** diff --git a/src/libs/FT800-FT813/EVE.h b/src/libs/FT800-FT813/EVE.h new file mode 100644 index 0000000000..ebce3687f7 --- /dev/null +++ b/src/libs/FT800-FT813/EVE.h @@ -0,0 +1,1257 @@ +/* +@file EVE.h +@brief Contains FT80x/FT81x/BT81x API definitions +@version 5.0 +@date 2024-01-28 +@author Rudolph Riedel + +@section LICENSE + +MIT License + +Copyright (c) 2016-2024 Rudolph Riedel + +Permission is hereby granted, free of charge, to any person obtaining a copy of +this software and associated documentation files (the "Software"), to deal in +the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, +and/or sell copies of the Software, and to permit persons to whom the Software +is furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS +FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR +COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER +IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +@section History + +5.0 +- started to add BT817 / BT818 defines +- cleanup: removed FT80x defines +- replaced BT81X_ENABLE with "EVE_GEN > 2" +- removed FT81X_ENABLE as FT81x already is the lowest supported chip revision now +- added more BT817 / BT818 defines +- removed undocumented registers and commands +- merged FT80x and FT81x definitions as FT81x is baseline now +- removed the history from before 4.0 +- fixed typo: REG_AH_CYCLE_MAX -> REG_AH_HCYCLE_MAX +- re-arranged the host commands, removed EVE_CLKINT for BT817/BT818, + removed FT80x EVE_CLK36M and EVE_CLK48M +- added EVE_OPT_OVERLAY +- removed the 4.0 history +- fixed some MISRA-C issues +- removed macro BEGIN(prim) - use (DL_BEGIN | EVE_BITMAPS) for example +- removed macro END() - use define DL_END +- removed macro RESTORE_CONTEXT() - use define DL_RESTORE_CONTEXT +- removed macro RETURN() - use define DL_RETURN +- removed macro SAVE_CONTEXT() - use define DL_SAVE_CONTEXT +- basic maintenance: checked for violations of white space and indent rules +- more linter fixes +- changed EVE_COMPRESSED_RGBA_ASTC_nxn_KHR to EVE_ASTC_nXn to fix linter + warnings and used the opportunity to make these shorter +- added DL_COLOR_A as alternative to the COLOR_A macro +- added defines for all DL_ display list commands +- cleaned up the macros +- fix: changed DL_CLEAR_RGB to DL_CLEAR_COLOR_RGB + as this is what the programming guide uses +- fix: renamed EVE_ROM_FONT_ADDR to EVE_ROM_FONTROOT +- added #ifdef __cplusplus / extern "C" to allow + adding EVE_ functions to C++ code +- fix: typo REG_COPRO_PATCH_DTR -> REG_COPRO_PATCH_PTR +- started to convert the function-like macros to static inline functions to be + a little friendlier towards C++ in regards of type-safety +- added type-casts to all simple macros +- converted some more function-like macros to static inline functions +- converted the rest of the function-like macros to static inline functions +- fix: forgot to comment out the EVE2 BITMAP_TRANSFORM_E when converting it to an inline function + +*/ + +#ifndef EVE_H +#define EVE_H + +#include "EVE_target.h" + +#ifdef __cplusplus +extern "C" +{ +#endif + +#include "EVE_config.h" +#include "EVE_commands.h" + +/* Memory */ +#define EVE_RAM_G ((uint32_t) 0x00000000UL) +#define EVE_ROM_CHIPID ((uint32_t) 0x000C0000UL) +#define EVE_ROM_FONT ((uint32_t) 0x001E0000UL) +#define EVE_ROM_FONTROOT ((uint32_t) 0x002FFFFCUL) +#define EVE_RAM_DL ((uint32_t) 0x00300000UL) +#define EVE_RAM_REG ((uint32_t) 0x00302000UL) +#define EVE_RAM_CMD ((uint32_t) 0x00308000UL) + +/* Memory buffer sizes */ +#define EVE_RAM_G_SIZE ((uint32_t) 1024U*1024UL) +#define EVE_CMDFIFO_SIZE ((uint32_t) 4U*1024UL) +#define EVE_RAM_DL_SIZE ((uint32_t) 8U*1024UL) + +/* diplay list list commands, most need OR's arguments */ +#define DL_DISPLAY ((uint32_t) 0x00000000UL) +#define DL_BITMAP_SOURCE ((uint32_t) 0x01000000UL) +#define DL_CLEAR_COLOR_RGB ((uint32_t) 0x02000000UL) +#define DL_TAG ((uint32_t) 0x03000000UL) +#define DL_COLOR_RGB ((uint32_t) 0x04000000UL) +#define DL_BITMAP_HANDLE ((uint32_t) 0x05000000UL) +#define DL_CELL ((uint32_t) 0x06000000UL) +#define DL_BITMAP_LAYOUT ((uint32_t) 0x07000000UL) +#define DL_BITMAP_SIZE ((uint32_t) 0x08000000UL) +#define DL_ALPHA_FUNC ((uint32_t) 0x09000000UL) +#define DL_STENCIL_FUNC ((uint32_t) 0x0A000000UL) +#define DL_BLEND_FUNC ((uint32_t) 0x0B000000UL) +#define DL_STENCIL_OP ((uint32_t) 0x0C000000UL) +#define DL_POINT_SIZE ((uint32_t) 0x0D000000UL) +#define DL_LINE_WIDTH ((uint32_t) 0x0E000000UL) +#define DL_CLEAR_COLOR_A ((uint32_t) 0x0F000000UL) +#define DL_COLOR_A ((uint32_t) 0x10000000UL) +#define DL_CLEAR_STENCIL ((uint32_t) 0x11000000UL) +#define DL_CLEAR_TAG ((uint32_t) 0x12000000UL) +#define DL_STENCIL_MASK ((uint32_t) 0x13000000UL) +#define DL_TAG_MASK ((uint32_t) 0x14000000UL) +#define DL_BITMAP_TRANSFORM_A ((uint32_t) 0x15000000UL) +#define DL_BITMAP_TRANSFORM_B ((uint32_t) 0x16000000UL) +#define DL_BITMAP_TRANSFORM_C ((uint32_t) 0x17000000UL) +#define DL_BITMAP_TRANSFORM_D ((uint32_t) 0x18000000UL) +#define DL_BITMAP_TRANSFORM_E ((uint32_t) 0x19000000UL) +#define DL_BITMAP_TRANSFORM_F ((uint32_t) 0x1A000000UL) +#define DL_SCISSOR_XY ((uint32_t) 0x1B000000UL) +#define DL_SCISSOR_SIZE ((uint32_t) 0x1C000000UL) +#define DL_CALL ((uint32_t) 0x1D000000UL) +#define DL_JUMP ((uint32_t) 0x1E000000UL) +#define DL_BEGIN ((uint32_t) 0x1F000000UL) +#define DL_COLOR_MASK ((uint32_t) 0x20000000UL) +#define DL_END ((uint32_t) 0x21000000UL) +#define DL_SAVE_CONTEXT ((uint32_t) 0x22000000UL) +#define DL_RESTORE_CONTEXT ((uint32_t) 0x23000000UL) +#define DL_RETURN ((uint32_t) 0x24000000UL) +#define DL_MACRO ((uint32_t) 0x25000000UL) +#define DL_CLEAR ((uint32_t) 0x26000000UL) +#define DL_VERTEX_FORMAT ((uint32_t) 0x27000000UL) +#define DL_BITMAP_LAYOUT_H ((uint32_t) 0x28000000UL) +#define DL_BITMAP_SIZE_H ((uint32_t) 0x29000000UL) +#define DL_PALETTE_SOURCE ((uint32_t) 0x2A000000UL) +#define DL_VERTEX_TRANSLATE_X ((uint32_t) 0x2B000000UL) +#define DL_VERTEX_TRANSLATE_Y ((uint32_t) 0x2C000000UL) +#define DL_NOP ((uint32_t) 0x2D000000UL) + +#define DL_VERTEX2F ((uint32_t) 0x40000000UL) +#define DL_VERTEX2II ((uint32_t) 0x80000000UL) + +#define CLR_COL ((uint8_t) 0x4U) +#define CLR_STN ((uint8_t) 0x2U) +#define CLR_TAG ((uint8_t) 0x1U) + +/* Host commands */ +#define EVE_ACTIVE ((uint8_t) 0x00U) /* place EVE in active state */ +#define EVE_STANDBY ((uint8_t) 0x41U) /* place EVE in Standby (clk running) */ +#define EVE_SLEEP ((uint8_t) 0x42U) /* place EVE in Sleep (clk off) */ +#define EVE_CLKEXT ((uint8_t) 0x44U) /* select external clock source */ +#define EVE_CLKINT ((uint8_t) 0x48U) /* select internal clock source, not a valid option for BT817 / BT818 */ +#define EVE_PWRDOWN ((uint8_t) 0x50U) /* place EVE in Power Down (core off) */ +#define EVE_CLKSEL ((uint8_t) 0x61U) /* configure system clock */ +#define EVE_RST_PULSE ((uint8_t) 0x68U) /* reset core - all registers default and processors reset */ +#define EVE_CORERST ((uint8_t) 0x68U) /* reset core - all registers default and processors reset */ +#define EVE_PINDRIVE ((uint8_t) 0x70U) /* setup drive strength for various pins */ +#define EVE_PIN_PD_STATE ((uint8_t) 0x71U) /* setup how pins behave during power down */ + +/* Graphic command defines */ +#define EVE_NEVER ((uint8_t) 0UL) +#define EVE_LESS ((uint8_t) 1UL) +#define EVE_LEQUAL ((uint8_t) 2UL) +#define EVE_GREATER ((uint8_t) 3UL) +#define EVE_GEQUAL ((uint8_t) 4UL) +#define EVE_EQUAL ((uint8_t) 5UL) +#define EVE_NOTEQUAL ((uint8_t) 6UL) +#define EVE_ALWAYS ((uint8_t) 7UL) + +/* Bitmap formats */ +#define EVE_ARGB1555 ((uint8_t) 0UL) +#define EVE_L1 ((uint8_t) 1UL) +#define EVE_L4 ((uint8_t) 2UL) +#define EVE_L8 ((uint8_t) 3UL) +#define EVE_RGB332 ((uint8_t) 4UL) +#define EVE_ARGB2 ((uint8_t) 5UL) +#define EVE_ARGB4 ((uint8_t) 6UL) +#define EVE_RGB565 ((uint8_t) 7UL) +#define EVE_PALETTED ((uint8_t) 8UL) +#define EVE_TEXT8X8 ((uint8_t) 9UL) +#define EVE_TEXTVGA ((uint8_t) 10UL) +#define EVE_BARGRAPH ((uint8_t) 11UL) + +/* Bitmap filter types */ +#define EVE_NEAREST ((uint8_t) 0UL) +#define EVE_BILINEAR ((uint8_t) 1UL) + +/* Bitmap wrap types */ +#define EVE_BORDER ((uint8_t) 0UL) +#define EVE_REPEAT ((uint8_t) 1UL) + +/* Stencil defines */ +#define EVE_KEEP ((uint8_t) 1UL) +#define EVE_REPLACE ((uint8_t) 2UL) +#define EVE_INCR ((uint8_t) 3UL) +#define EVE_DECR ((uint8_t) 4UL) +#define EVE_INVERT ((uint8_t) 5UL) + +/* Graphics display list swap defines */ +#define EVE_DLSWAP_DONE ((uint8_t) 0UL) +#define EVE_DLSWAP_LINE ((uint8_t) 1UL) +#define EVE_DLSWAP_FRAME ((uint8_t) 2UL) + +/* Interrupt bits */ +#define EVE_INT_SWAP ((uint8_t) 0x01) +#define EVE_INT_TOUCH ((uint8_t) 0x02) +#define EVE_INT_TAG ((uint8_t) 0x04) +#define EVE_INT_SOUND ((uint8_t) 0x08) +#define EVE_INT_PLAYBACK ((uint8_t) 0x10) +#define EVE_INT_CMDEMPTY ((uint8_t) 0x20) +#define EVE_INT_CMDFLAG ((uint8_t) 0x40) +#define EVE_INT_CONVCOMPLETE ((uint8_t) 0x80) + +/* Touch mode */ +#define EVE_TMODE_OFF ((uint8_t) 0U) +#define EVE_TMODE_ONESHOT ((uint8_t) 1U) +#define EVE_TMODE_FRAME ((uint8_t) 2U) +#define EVE_TMODE_CONTINUOUS ((uint8_t) 3U) + +/* Alpha blending */ +#define EVE_ZERO ((uint32_t) 0UL) +#define EVE_ONE ((uint32_t) 1UL) +#define EVE_SRC_ALPHA ((uint32_t) 2UL) +#define EVE_DST_ALPHA ((uint32_t) 3UL) +#define EVE_ONE_MINUS_SRC_ALPHA ((uint32_t) 4UL) +#define EVE_ONE_MINUS_DST_ALPHA ((uint32_t) 5UL) + +/* Graphics primitives */ +#define EVE_BITMAPS ((uint32_t) 1UL) +#define EVE_POINTS ((uint32_t) 2UL) +#define EVE_LINES ((uint32_t) 3UL) +#define EVE_LINE_STRIP ((uint32_t) 4UL) +#define EVE_EDGE_STRIP_R ((uint32_t) 5UL) +#define EVE_EDGE_STRIP_L ((uint32_t) 6UL) +#define EVE_EDGE_STRIP_A ((uint32_t) 7UL) +#define EVE_EDGE_STRIP_B ((uint32_t) 8UL) +#define EVE_RECTS ((uint32_t) 9UL) +#define EVE_INT_G8 ((uint32_t) 18UL) +#define EVE_INT_L8C ((uint32_t) 12UL) +#define EVE_INT_VGA ((uint32_t) 13UL) +#define EVE_PALETTED565 ((uint32_t) 14UL) +#define EVE_PALETTED4444 ((uint32_t) 15UL) +#define EVE_PALETTED8 ((uint32_t) 16UL) +#define EVE_L2 ((uint32_t) 17UL) + +/* Widget command options */ +#define EVE_OPT_MONO ((uint16_t) 1U) +#define EVE_OPT_NODL ((uint16_t) 2U) +#define EVE_OPT_FLAT ((uint16_t) 256U) +#define EVE_OPT_CENTERX ((uint16_t) 512U) +#define EVE_OPT_CENTERY ((uint16_t) 1024U) +#define EVE_OPT_CENTER (EVE_OPT_CENTERX | EVE_OPT_CENTERY) +#define EVE_OPT_NOBACK ((uint16_t) 4096U) +#define EVE_OPT_NOTICKS ((uint16_t) 8192U) +#define EVE_OPT_NOHM ((uint16_t) 16384U) +#define EVE_OPT_NOPOINTER ((uint16_t) 16384U) +#define EVE_OPT_NOSECS ((uint16_t) 32768U) +#define EVE_OPT_NOHANDS ((uint16_t) 49152U) +#define EVE_OPT_RIGHTX ((uint16_t) 2048U) +#define EVE_OPT_SIGNED ((uint16_t) 256U) + +#define EVE_OPT_MEDIAFIFO ((uint16_t) 16U) +#define EVE_OPT_FULLSCREEN ((uint16_t) 8U) +#define EVE_OPT_NOTEAR ((uint16_t) 4U) +#define EVE_OPT_SOUND ((uint16_t) 32U) + +/* ADC */ +#define EVE_ADC_DIFFERENTIAL ((uint32_t) 1UL) +#define EVE_ADC_SINGLE_ENDED ((uint32_t) 0UL) + +/* Fonts */ +#define EVE_NUMCHAR_PERFONT ((uint32_t) 128UL) /* number of font characters per bitmap handle */ +#define EVE_FONT_TABLE_SIZE ((uint32_t) 148UL) /* size of the font table - utilized for loopup by the graphics engine */ +#define EVE_FONT_TABLE_POINTER ((uint32_t) 0xFFFFCUL) /* pointer to the inbuilt font tables starting from bitmap handle 16 */ + +/* Audio sample type defines */ +#define EVE_LINEAR_SAMPLES ((uint32_t) 0UL) /* 8bit signed samples */ +#define EVE_ULAW_SAMPLES ((uint32_t) 1UL) /* 8bit ulaw samples */ +#define EVE_ADPCM_SAMPLES ((uint32_t) 2UL) /* 4bit ima adpcm samples */ + +/* Synthesized sound */ +#define EVE_SILENCE ((uint8_t) 0x00U) +#define EVE_SQUAREWAVE ((uint8_t) 0x01U) +#define EVE_SINEWAVE ((uint8_t) 0x02U) +#define EVE_SAWTOOTH ((uint8_t) 0x03U) +#define EVE_TRIANGLE ((uint8_t) 0x04U) +#define EVE_BEEPING ((uint8_t) 0x05U) +#define EVE_ALARM ((uint8_t) 0x06U) +#define EVE_WARBLE ((uint8_t) 0x07U) +#define EVE_CAROUSEL ((uint8_t) 0x08U) +#define EVE_PIPS(n) ((uint8_t) (0x0FU + (n))) +#define EVE_HARP ((uint8_t) 0x40U) +#define EVE_XYLOPHONE ((uint8_t) 0x41U) +#define EVE_TUBA ((uint8_t) 0x42U) +#define EVE_GLOCKENSPIEL ((uint8_t) 0x43U) +#define EVE_ORGAN ((uint8_t) 0x44U) +#define EVE_TRUMPET ((uint8_t) 0x45U) +#define EVE_PIANO ((uint8_t) 0x46U) +#define EVE_CHIMES ((uint8_t) 0x47U) +#define EVE_MUSICBOX ((uint8_t) 0x48U) +#define EVE_BELL ((uint8_t) 0x49U) +#define EVE_CLICK ((uint8_t) 0x50U) +#define EVE_SWITCH ((uint8_t) 0x51U) +#define EVE_COWBELL ((uint8_t) 0x52U) +#define EVE_NOTCH ((uint8_t) 0x53U) +#define EVE_HIHAT ((uint8_t) 0x54U) +#define EVE_KICKDRUM ((uint8_t) 0x55U) +#define EVE_POP ((uint8_t) 0x56U) +#define EVE_CLACK ((uint8_t) 0x57U) +#define EVE_CHACK ((uint8_t) 0x58U) +#define EVE_MUTE ((uint8_t) 0x60U) +#define EVE_UNMUTE ((uint8_t) 0x61U) + +/* Synthesized sound frequencies, midi note */ +#define EVE_MIDI_A0 ((uint8_t) 21U) +#define EVE_MIDI_A_0 ((uint8_t) 22U) +#define EVE_MIDI_B0 ((uint8_t) 23U) +#define EVE_MIDI_C1 ((uint8_t) 24U) +#define EVE_MIDI_C_1 ((uint8_t) 25U) +#define EVE_MIDI_D1 ((uint8_t) 26U) +#define EVE_MIDI_D_1 ((uint8_t) 27U) +#define EVE_MIDI_E1 ((uint8_t) 28U) +#define EVE_MIDI_F1 ((uint8_t) 29U) +#define EVE_MIDI_F_1 ((uint8_t) 30U) +#define EVE_MIDI_G1 ((uint8_t) 31U) +#define EVE_MIDI_G_1 ((uint8_t) 32U) +#define EVE_MIDI_A1 ((uint8_t) 33U) +#define EVE_MIDI_A_1 ((uint8_t) 34U) +#define EVE_MIDI_B1 ((uint8_t) 35U) +#define EVE_MIDI_C2 ((uint8_t) 36U) +#define EVE_MIDI_C_2 ((uint8_t) 37U) +#define EVE_MIDI_D2 ((uint8_t) 38U) +#define EVE_MIDI_D_2 ((uint8_t) 39U) +#define EVE_MIDI_E2 ((uint8_t) 40U) +#define EVE_MIDI_F2 ((uint8_t) 41U) +#define EVE_MIDI_F_2 ((uint8_t) 42U) +#define EVE_MIDI_G2 ((uint8_t) 43U) +#define EVE_MIDI_G_2 ((uint8_t) 44U) +#define EVE_MIDI_A2 ((uint8_t) 45U) +#define EVE_MIDI_A_2 ((uint8_t) 46U) +#define EVE_MIDI_B2 ((uint8_t) 47U) +#define EVE_MIDI_C3 ((uint8_t) 48U) +#define EVE_MIDI_C_3 ((uint8_t) 49U) +#define EVE_MIDI_D3 ((uint8_t) 50U) +#define EVE_MIDI_D_3 ((uint8_t) 51U) +#define EVE_MIDI_E3 ((uint8_t) 52U) +#define EVE_MIDI_F3 ((uint8_t) 53U) +#define EVE_MIDI_F_3 ((uint8_t) 54U) +#define EVE_MIDI_G3 ((uint8_t) 55U) +#define EVE_MIDI_G_3 ((uint8_t) 56U) +#define EVE_MIDI_A3 ((uint8_t) 57U) +#define EVE_MIDI_A_3 ((uint8_t) 58U) +#define EVE_MIDI_B3 ((uint8_t) 59U) +#define EVE_MIDI_C4 ((uint8_t) 60U) +#define EVE_MIDI_C_4 ((uint8_t) 61U) +#define EVE_MIDI_D4 ((uint8_t) 62U) +#define EVE_MIDI_D_4 ((uint8_t) 63U) +#define EVE_MIDI_E4 ((uint8_t) 64U) +#define EVE_MIDI_F4 ((uint8_t) 65U) +#define EVE_MIDI_F_4 ((uint8_t) 66U) +#define EVE_MIDI_G4 ((uint8_t) 67U) +#define EVE_MIDI_G_4 ((uint8_t) 68U) +#define EVE_MIDI_A4 ((uint8_t) 69U) +#define EVE_MIDI_A_4 ((uint8_t) 70U) +#define EVE_MIDI_B4 ((uint8_t) 71U) +#define EVE_MIDI_C5 ((uint8_t) 72U) +#define EVE_MIDI_C_5 ((uint8_t) 73U) +#define EVE_MIDI_D5 ((uint8_t) 74U) +#define EVE_MIDI_D_5 ((uint8_t) 75U) +#define EVE_MIDI_E5 ((uint8_t) 76U) +#define EVE_MIDI_F5 ((uint8_t) 77U) +#define EVE_MIDI_F_5 ((uint8_t) 78U) +#define EVE_MIDI_G5 ((uint8_t) 79U) +#define EVE_MIDI_G_5 ((uint8_t) 80U) +#define EVE_MIDI_A5 ((uint8_t) 81U) +#define EVE_MIDI_A_5 ((uint8_t) 82U) +#define EVE_MIDI_B5 ((uint8_t) 83U) +#define EVE_MIDI_C6 ((uint8_t) 84U) +#define EVE_MIDI_C_6 ((uint8_t) 85U) +#define EVE_MIDI_D6 ((uint8_t) 86U) +#define EVE_MIDI_D_6 ((uint8_t) 87U) +#define EVE_MIDI_E6 ((uint8_t) 88U) +#define EVE_MIDI_F6 ((uint8_t) 89U) +#define EVE_MIDI_F_6 ((uint8_t) 90U) +#define EVE_MIDI_G6 ((uint8_t) 91U) +#define EVE_MIDI_G_6 ((uint8_t) 92U) +#define EVE_MIDI_A6 ((uint8_t) 93U) +#define EVE_MIDI_A_6 ((uint8_t) 94U) +#define EVE_MIDI_B6 ((uint8_t) 95U) +#define EVE_MIDI_C7 ((uint8_t) 96U) +#define EVE_MIDI_C_7 ((uint8_t) 97U) +#define EVE_MIDI_D7 ((uint8_t) 98U) +#define EVE_MIDI_D_7 ((uint8_t) 99U) +#define EVE_MIDI_E7 ((uint8_t) 100U) +#define EVE_MIDI_F7 ((uint8_t) 101U) +#define EVE_MIDI_F_7 ((uint8_t) 102U) +#define EVE_MIDI_G7 ((uint8_t) 103U) +#define EVE_MIDI_G_7 ((uint8_t) 104U) +#define EVE_MIDI_A7 ((uint8_t) 105U) +#define EVE_MIDI_A_7 ((uint8_t) 106U) +#define EVE_MIDI_B7 ((uint8_t) 107U) +#define EVE_MIDI_C8 ((uint8_t) 108U) + +/* GPIO bits */ +#define EVE_GPIO0 ((uint8_t) 0U) +#define EVE_GPIO1 ((uint8_t) 1U) /* default gpio pin for audio shutdown, 1 - enable, 0 - disable */ +#define EVE_GPIO7 ((uint8_t) 7U) /* default gpio pin for display enable, 1 - enable, 0 - disable */ + +/* Display rotation */ +#define EVE_DISPLAY_0 ((uint8_t) 0U) /* 0 degrees rotation */ +#define EVE_DISPLAY_180 ((uint8_t) 1U) /* 180 degrees rotation */ + +/* Commands */ +#define CMD_APPEND ((uint32_t) 0xFFFFFF1EUL) +#define CMD_BGCOLOR ((uint32_t) 0xFFFFFF09UL) +#define CMD_BUTTON ((uint32_t) 0xFFFFFF0DUL) +#define CMD_CALIBRATE ((uint32_t) 0xFFFFFF15UL) +#define CMD_CLOCK ((uint32_t) 0xFFFFFF14UL) +#define CMD_COLDSTART ((uint32_t) 0xFFFFFF32UL) +#define CMD_DIAL ((uint32_t) 0xFFFFFF2DUL) +#define CMD_DLSTART ((uint32_t) 0xFFFFFF00UL) +#define CMD_FGCOLOR ((uint32_t) 0xFFFFFF0AUL) +#define CMD_GAUGE ((uint32_t) 0xFFFFFF13UL) +#define CMD_GETMATRIX ((uint32_t) 0xFFFFFF33UL) +#define CMD_GETPROPS ((uint32_t) 0xFFFFFF25UL) +#define CMD_GETPTR ((uint32_t) 0xFFFFFF23UL) +#define CMD_GRADCOLOR ((uint32_t) 0xFFFFFF34UL) +#define CMD_GRADIENT ((uint32_t) 0xFFFFFF0BUL) +#define CMD_INFLATE ((uint32_t) 0xFFFFFF22UL) +#define CMD_INTERRUPT ((uint32_t) 0xFFFFFF02UL) +#define CMD_KEYS ((uint32_t) 0xFFFFFF0EUL) +#define CMD_LOADIDENTITY ((uint32_t) 0xFFFFFF26UL) +#define CMD_LOADIMAGE ((uint32_t) 0xFFFFFF24UL) +#define CMD_LOGO ((uint32_t) 0xFFFFFF31UL) +#define CMD_MEDIAFIFO ((uint32_t) 0xFFFFFF39UL) +#define CMD_MEMCPY ((uint32_t) 0xFFFFFF1DUL) +#define CMD_MEMCRC ((uint32_t) 0xFFFFFF18UL) +#define CMD_MEMSET ((uint32_t) 0xFFFFFF1BUL) +#define CMD_MEMWRITE ((uint32_t) 0xFFFFFF1AUL) +#define CMD_MEMZERO ((uint32_t) 0xFFFFFF1CUL) +#define CMD_NUMBER ((uint32_t) 0xFFFFFF2EUL) +#define CMD_PLAYVIDEO ((uint32_t) 0xFFFFFF3AUL) +#define CMD_PROGRESS ((uint32_t) 0xFFFFFF0FUL) +#define CMD_REGREAD ((uint32_t) 0xFFFFFF19UL) +#define CMD_ROMFONT ((uint32_t) 0xFFFFFF3FUL) +#define CMD_ROTATE ((uint32_t) 0xFFFFFF29UL) +#define CMD_SCALE ((uint32_t) 0xFFFFFF28UL) +#define CMD_SCREENSAVER ((uint32_t) 0xFFFFFF2FUL) +#define CMD_SCROLLBAR ((uint32_t) 0xFFFFFF11UL) +#define CMD_SETBASE ((uint32_t) 0xFFFFFF38UL) +#define CMD_SETBITMAP ((uint32_t) 0xFFFFFF43UL) +#define CMD_SETFONT ((uint32_t) 0xFFFFFF2BUL) +#define CMD_SETFONT2 ((uint32_t) 0xFFFFFF3BUL) +#define CMD_SETMATRIX ((uint32_t) 0xFFFFFF2AUL) +#define CMD_SETROTATE ((uint32_t) 0xFFFFFF36UL) +#define CMD_SETSCRATCH ((uint32_t) 0xFFFFFF3CUL) +#define CMD_SKETCH ((uint32_t) 0xFFFFFF30UL) +#define CMD_SLIDER ((uint32_t) 0xFFFFFF10UL) +#define CMD_SNAPSHOT ((uint32_t) 0xFFFFFF1FUL) +#define CMD_SNAPSHOT2 ((uint32_t) 0xFFFFFF37UL) +#define CMD_SPINNER ((uint32_t) 0xFFFFFF16UL) +#define CMD_STOP ((uint32_t) 0xFFFFFF17UL) +#define CMD_SWAP ((uint32_t) 0xFFFFFF01UL) +#define CMD_TEXT ((uint32_t) 0xFFFFFF0CUL) +#define CMD_TOGGLE ((uint32_t) 0xFFFFFF12UL) +#define CMD_TRACK ((uint32_t) 0xFFFFFF2CUL) +#define CMD_TRANSLATE ((uint32_t) 0xFFFFFF27UL) +#define CMD_VIDEOFRAME ((uint32_t) 0xFFFFFF41UL) +#define CMD_VIDEOSTART ((uint32_t) 0xFFFFFF40UL) + +/* Registers */ +#define REG_ANA_COMP ((uint32_t) 0x00302184UL) /* only listed in datasheet */ +#define REG_BIST_EN ((uint32_t) 0x00302174UL) /* only listed in datasheet */ +#define REG_CLOCK ((uint32_t) 0x00302008UL) +#define REG_CMDB_SPACE ((uint32_t) 0x00302574UL) +#define REG_CMDB_WRITE ((uint32_t) 0x00302578UL) +#define REG_CMD_DL ((uint32_t) 0x00302100UL) +#define REG_CMD_READ ((uint32_t) 0x003020f8UL) +#define REG_CMD_WRITE ((uint32_t) 0x003020fcUL) +#define REG_CPURESET ((uint32_t) 0x00302020UL) +#define REG_CSPREAD ((uint32_t) 0x00302068UL) +#define REG_CTOUCH_EXTENDED ((uint32_t) 0x00302108UL) +#define REG_CTOUCH_TOUCH0_XY ((uint32_t) 0x00302124UL) /* only listed in datasheet */ +#define REG_CTOUCH_TOUCH4_X ((uint32_t) 0x0030216cUL) +#define REG_CTOUCH_TOUCH4_Y ((uint32_t) 0x00302120UL) +#define REG_CTOUCH_TOUCH1_XY ((uint32_t) 0x0030211cUL) +#define REG_CTOUCH_TOUCH2_XY ((uint32_t) 0x0030218cUL) +#define REG_CTOUCH_TOUCH3_XY ((uint32_t) 0x00302190UL) +#define REG_TOUCH_CONFIG ((uint32_t) 0x00302168UL) +#define REG_DATESTAMP ((uint32_t) 0x00302564UL) /* only listed in datasheet */ +#define REG_DITHER ((uint32_t) 0x00302060UL) +#define REG_DLSWAP ((uint32_t) 0x00302054UL) +#define REG_FRAMES ((uint32_t) 0x00302004UL) +#define REG_FREQUENCY ((uint32_t) 0x0030200cUL) +#define REG_GPIO ((uint32_t) 0x00302094UL) +#define REG_GPIOX ((uint32_t) 0x0030209cUL) +#define REG_GPIOX_DIR ((uint32_t) 0x00302098UL) +#define REG_GPIO_DIR ((uint32_t) 0x00302090UL) +#define REG_HCYCLE ((uint32_t) 0x0030202cUL) +#define REG_HOFFSET ((uint32_t) 0x00302030UL) +#define REG_HSIZE ((uint32_t) 0x00302034UL) +#define REG_HSYNC0 ((uint32_t) 0x00302038UL) +#define REG_HSYNC1 ((uint32_t) 0x0030203cUL) +#define REG_ID ((uint32_t) 0x00302000UL) +#define REG_INT_EN ((uint32_t) 0x003020acUL) +#define REG_INT_FLAGS ((uint32_t) 0x003020a8UL) +#define REG_INT_MASK ((uint32_t) 0x003020b0UL) +#define REG_MACRO_0 ((uint32_t) 0x003020d8UL) +#define REG_MACRO_1 ((uint32_t) 0x003020dcUL) +#define REG_MEDIAFIFO_READ ((uint32_t) 0x00309014UL) /* only listed in programmers guide */ +#define REG_MEDIAFIFO_WRITE ((uint32_t) 0x00309018UL) /* only listed in programmers guide */ +#define REG_OUTBITS ((uint32_t) 0x0030205cUL) +#define REG_PCLK ((uint32_t) 0x00302070UL) +#define REG_PCLK_POL ((uint32_t) 0x0030206cUL) +#define REG_PLAY ((uint32_t) 0x0030208cUL) +#define REG_PLAYBACK_FORMAT ((uint32_t) 0x003020c4UL) +#define REG_PLAYBACK_FREQ ((uint32_t) 0x003020c0UL) +#define REG_PLAYBACK_LENGTH ((uint32_t) 0x003020b8UL) +#define REG_PLAYBACK_LOOP ((uint32_t) 0x003020c8UL) +#define REG_PLAYBACK_PLAY ((uint32_t) 0x003020ccUL) +#define REG_PLAYBACK_READPTR ((uint32_t) 0x003020bcUL) +#define REG_PLAYBACK_START ((uint32_t) 0x003020b4UL) +#define REG_PWM_DUTY ((uint32_t) 0x003020d4UL) +#define REG_PWM_HZ ((uint32_t) 0x003020d0UL) +#define REG_RENDERMODE ((uint32_t) 0x00302010UL) /* only listed in datasheet */ +#define REG_ROTATE ((uint32_t) 0x00302058UL) +#define REG_SNAPFORMAT ((uint32_t) 0x0030201cUL) /* only listed in datasheet */ +#define REG_SNAPSHOT ((uint32_t) 0x00302018UL) /* only listed in datasheet */ +#define REG_SNAPY ((uint32_t) 0x00302014UL) /* only listed in datasheet */ +#define REG_SOUND ((uint32_t) 0x00302088UL) +#define REG_SPI_WIDTH ((uint32_t) 0x00302188UL) /* listed with false offset in programmers guide V1.1 */ +#define REG_SWIZZLE ((uint32_t) 0x00302064UL) +#define REG_TAG ((uint32_t) 0x0030207cUL) +#define REG_TAG_X ((uint32_t) 0x00302074UL) +#define REG_TAG_Y ((uint32_t) 0x00302078UL) +#define REG_TAP_CRC ((uint32_t) 0x00302024UL) /* only listed in datasheet */ +#define REG_TAP_MASK ((uint32_t) 0x00302028UL) /* only listed in datasheet */ +#define REG_TOUCH_ADC_MODE ((uint32_t) 0x00302108UL) +#define REG_TOUCH_CHARGE ((uint32_t) 0x0030210cUL) +#define REG_TOUCH_DIRECT_XY ((uint32_t) 0x0030218cUL) +#define REG_TOUCH_DIRECT_Z1Z2 ((uint32_t) 0x00302190UL) +#define REG_TOUCH_MODE ((uint32_t) 0x00302104UL) +#define REG_TOUCH_OVERSAMPLE ((uint32_t) 0x00302114UL) +#define REG_TOUCH_RAW_XY ((uint32_t) 0x0030211cUL) +#define REG_TOUCH_RZ ((uint32_t) 0x00302120UL) +#define REG_TOUCH_RZTHRESH ((uint32_t) 0x00302118UL) +#define REG_TOUCH_SCREEN_XY ((uint32_t) 0x00302124UL) +#define REG_TOUCH_SETTLE ((uint32_t) 0x00302110UL) +#define REG_TOUCH_TAG ((uint32_t) 0x0030212cUL) +#define REG_TOUCH_TAG1 ((uint32_t) 0x00302134UL) /* only listed in datasheet */ +#define REG_TOUCH_TAG1_XY ((uint32_t) 0x00302130UL) /* only listed in datasheet */ +#define REG_TOUCH_TAG2 ((uint32_t) 0x0030213cUL) /* only listed in datasheet */ +#define REG_TOUCH_TAG2_XY ((uint32_t) 0x00302138UL) /* only listed in datasheet */ +#define REG_TOUCH_TAG3 ((uint32_t) 0x00302144UL) /* only listed in datasheet */ +#define REG_TOUCH_TAG3_XY ((uint32_t) 0x00302140UL) /* only listed in datasheet */ +#define REG_TOUCH_TAG4 ((uint32_t) 0x0030214cUL)/* only listed in datasheet */ +#define REG_TOUCH_TAG4_XY ((uint32_t) 0x00302148UL) /* only listed in datasheet */ +#define REG_TOUCH_TAG_XY ((uint32_t) 0x00302128UL) +#define REG_TOUCH_TRANSFORM_A ((uint32_t) 0x00302150UL) +#define REG_TOUCH_TRANSFORM_B ((uint32_t) 0x00302154UL) +#define REG_TOUCH_TRANSFORM_C ((uint32_t) 0x00302158UL) +#define REG_TOUCH_TRANSFORM_D ((uint32_t) 0x0030215cUL) +#define REG_TOUCH_TRANSFORM_E ((uint32_t) 0x00302160UL) +#define REG_TOUCH_TRANSFORM_F ((uint32_t) 0x00302164UL) +#define REG_TRACKER ((uint32_t) 0x00309000UL) /* only listed in programmers guide */ +#define REG_TRACKER_1 ((uint32_t) 0x00309004UL) /* only listed in programmers guide */ +#define REG_TRACKER_2 ((uint32_t) 0x00309008UL) /* only listed in programmers guide */ +#define REG_TRACKER_3 ((uint32_t) 0x0030900cUL) /* only listed in programmers guide */ +#define REG_TRACKER_4 ((uint32_t) 0x00309010UL) /* only listed in programmers guide */ +#define REG_TRIM ((uint32_t) 0x00302180UL) +#define REG_VCYCLE ((uint32_t) 0x00302040UL) +#define REG_VOFFSET ((uint32_t) 0x00302044UL) +#define REG_VOL_PB ((uint32_t) 0x00302080UL) +#define REG_VOL_SOUND ((uint32_t) 0x00302084UL) +#define REG_VSIZE ((uint32_t) 0x00302048UL) +#define REG_VSYNC0 ((uint32_t) 0x0030204cUL) +#define REG_VSYNC1 ((uint32_t) 0x00302050UL) + + +/* Macros for static display list generation */ + +//#define ALPHA_FUNC(func,ref) ((DL_ALPHA_FUNC) | (((func) & 7UL) << 8U) | ((ref) & 0xFFUL)) +/** + * @brief Set the alpha test function. + * + * @return a 32 bit word for use with EVE_cmd_dl() + */ +static inline uint32_t ALPHA_FUNC(uint8_t func, uint8_t ref) +{ + uint32_t const funcv = ((uint32_t) func & 7U) << 8U; + return (DL_ALPHA_FUNC | funcv | ref); +} + +//#define BITMAP_HANDLE(handle) ((DL_BITMAP_HANDLE) | ((handle) & 0x1FUL)) +/** + * @brief Set the bitmap handle. + * @return a 32 bit word for use with EVE_cmd_dl() + */ +static inline uint32_t BITMAP_HANDLE(uint8_t handle) +{ + return (DL_BITMAP_HANDLE | ((handle) & 0x1FUL)); +} + +//#define BITMAP_LAYOUT(format,linestride,height) ((DL_BITMAP_LAYOUT) | (((format) & 0x1FUL) << 19U) | (((linestride) & 0x3FFUL) << 9U) | ((height) & 0x1FFUL)) +/** + * @brief Set the source bitmap memory format and layout for the current handle. + * @return a 32 bit word for use with EVE_cmd_dl() + */ +static inline uint32_t BITMAP_LAYOUT(uint8_t format, uint16_t linestride, uint16_t height) +{ + uint32_t const formatv = ((uint32_t) format & 0x1FUL) << 19U; + uint32_t const linestridev = ((uint32_t) linestride & 0x3FFUL) << 9U; + uint32_t const heightv = height & 0x1FFUL; + return (DL_BITMAP_LAYOUT | formatv | linestridev | heightv); +} + +//#define BITMAP_SIZE(filter,wrapx,wrapy,width,height) ((DL_BITMAP_SIZE) | (((filter) & 1UL) << 20U) | (((wrapx) & 1UL) << 19U) | (((wrapy) & 1UL) << 18U) | (((width) & 0x1FFUL) << 9U) | ((height) & 0x1FFUL)) +/** + * @brief Set the source bitmap memory format and layout for the current handle. + * @return a 32 bit word for use with EVE_cmd_dl() + */ +static inline uint32_t BITMAP_SIZE(uint8_t filter, uint8_t wrapx, uint8_t wrapy, uint16_t width, uint16_t height) +{ + uint32_t const filterv = (filter & 0x1UL) << 20U; + uint32_t const wrapxv = (wrapx & 0x1UL) << 19U; + uint32_t const wrapyv = (wrapy & 0x1UL) << 18U; + uint32_t const widthv = (width & 0x1FFUL) << 9U; + uint32_t const heightv = height & 0x1FFUL; + return (DL_BITMAP_SIZE | filterv | wrapxv | wrapyv | widthv | heightv); +} + +//#define BITMAP_LAYOUT_H(linestride,height) ((DL_BITMAP_LAYOUT_H) | (((((linestride) & 0xC00U) >> 10U)&3UL) << 2U) | ((((height) & 0x600U) >> 9U) & 3UL)) +/** + * @brief Set the 2 most significant bits of the source bitmap memory format and layout for the current handle. + * @param linestride 12-bit value specified to BITMAP_LAYOUT + * @param height 11-bit value specified to BITMAP_LAYOUT + * @note this is different to FTDIs implementation as this takes the original values as parameters and not only the upper bits + * @return a 32 bit word for use with EVE_cmd_dl() + */ +static inline uint32_t BITMAP_LAYOUT_H(uint16_t linestride, uint16_t height) +{ + uint32_t const linestridev = (uint32_t) ((((linestride & 0xC00U) >> 10U) &3UL) << 2U); + uint32_t const heightv = (uint32_t) (((height & 0x600U) >> 9U) & 3UL); + return (DL_BITMAP_LAYOUT_H | linestridev | heightv); +} + +//#define BITMAP_SIZE_H(width,height) ((DL_BITMAP_SIZE_H) | (((((width) & 0x600U) >> 9U) & 3UL) << 2U) | ((((height) & 0x600U) >> 9U) & 3UL)) +/** + * @brief Set the 2 most significant bits of bitmaps dimension for the current handle. + * @param linestride 11-bit value of bitmap width, the 2 most significant bits are used + * @param height 11-bit value of bitmap width, the 2 most significant bits are used + * @note this is different to FTDIs implementation as this takes the original values as parameters and not only the upper bits + * @return a 32 bit word for use with EVE_cmd_dl() + */ +static inline uint32_t BITMAP_SIZE_H(uint16_t width, uint16_t height) +{ + uint32_t const widthv = (uint32_t) ((((width & 0x600U) >> 9U) & 3UL) << 2U); + uint32_t const heightv = (uint32_t) (((height & 0x600U) >> 9U) & 3UL); + return ((DL_BITMAP_SIZE_H) | widthv | heightv); +} + +//#define BITMAP_SOURCE(addr) ((DL_BITMAP_SOURCE) | ((addr) & 0x3FFFFFUL)) +/** + * @brief Set the source address of bitmap data in RAM_G or flash memory. + * @return a 32 bit word for use with EVE_cmd_dl() + */ +static inline uint32_t BITMAP_SOURCE(uint32_t addr) +{ + return (DL_BITMAP_SOURCE | (addr & 0x3FFFFFUL)); +} + +#if EVE_GEN < 3 /* only define these for FT81x */ +//#define BITMAP_TRANSFORM_A(a) ((DL_BITMAP_TRANSFORM_A) | ((a) & 0x1FFFFUL)) +/** + * @brief Set the A coefficient of the bitmap transform matrix. + * @return a 32 bit word for use with EVE_cmd_dl() + */ +static inline uint32_t BITMAP_TRANSFORM_A(uint32_t val) +{ + return (DL_BITMAP_TRANSFORM_A | (val & 0x1FFFFUL)); +} + +//#define BITMAP_TRANSFORM_B(b) ((DL_BITMAP_TRANSFORM_B) | ((b) & 0x1FFFFUL)) +/** + * @brief Set the B coefficient of the bitmap transform matrix. + * @return a 32 bit word for use with EVE_cmd_dl() + */ +static inline uint32_t BITMAP_TRANSFORM_B(uint32_t val) +{ + return (DL_BITMAP_TRANSFORM_B | (val & 0x1FFFFUL)); +} + +//#define BITMAP_TRANSFORM_D(d) ((DL_BITMAP_TRANSFORM_D) | ((d) & 0x1FFFFUL)) +/** + * @brief Set the D coefficient of the bitmap transform matrix. + * @return a 32 bit word for use with EVE_cmd_dl() + */ +static inline uint32_t BITMAP_TRANSFORM_D(uint32_t val) +{ + return (DL_BITMAP_TRANSFORM_D | (val & 0x1FFFFUL)); +} + +//#define BITMAP_TRANSFORM_E(e) ((DL_BITMAP_TRANSFORM_E) | ((e) & 0x1FFFFUL)) +/** + * @brief Set he E coefficient of the bitmap transform matrix. + * @return a 32 bit word for use with EVE_cmd_dl() + */ +static inline uint32_t BITMAP_TRANSFORM_E(uint32_t val) +{ + return (DL_BITMAP_TRANSFORM_E | (val & 0x1FFFFUL)); +} + +#endif + +//#define BITMAP_TRANSFORM_C(c) ((DL_BITMAP_TRANSFORM_C) | ((c) & 0x1FFFFUL)) +/** + * @brief Set the C coefficient of the bitmap transform matrix. + * @return a 32 bit word for use with EVE_cmd_dl() + */ +static inline uint32_t BITMAP_TRANSFORM_C(uint32_t val) +{ + return (DL_BITMAP_TRANSFORM_C | (val & 0x1FFFFUL)); +} + +//#define BITMAP_TRANSFORM_F(f) ((DL_BITMAP_TRANSFORM_F) | ((f) & 0x1FFFFUL)) +/** + * @brief Set the F coefficient of the bitmap transform matrix. + * @return a 32 bit word for use with EVE_cmd_dl() + */ +static inline uint32_t BITMAP_TRANSFORM_F(uint32_t val) +{ + return (DL_BITMAP_TRANSFORM_F | (val & 0x1FFFFUL)); +} + +//#define BLEND_FUNC(src,dst) ((DL_BLEND_FUNC) | (((src) & 7UL) << 3U) | ((dst) & 7UL)) +/** + * @brief Execute a sequence of commands at another location in the display list. + * @return a 32 bit word for use with EVE_cmd_dl() + */ +static inline uint32_t BLEND_FUNC(uint8_t src, uint8_t dst) +{ + uint32_t const srcv = (uint32_t) ((src & 7UL) << 3U); + uint32_t const dstv = (uint32_t) (dst & 7UL); + return (DL_BLEND_FUNC | srcv | dstv); +} + +//#define CALL(dest) ((DL_CALL) | ((dest) & 0xFFFFUL)) +/** + * @brief Execute a sequence of commands at another location in the display list. + * @note valid range for dest is from zero to 2047 + * @return a 32 bit word for use with EVE_cmd_dl() + */ +static inline uint32_t CALL(uint16_t dest) +{ + return (DL_CALL | (dest & 0x7FFUL)); +} + +//#define JUMP(dest) ((DL_JUMP) | ((dest) & 0xFFFFUL)) +/** + * @brief Execute commands at another location in the display list. + * @note valid range for dest is from zero to 2047 + * @return a 32 bit word for use with EVE_cmd_dl() + */ +static inline uint32_t JUMP(uint16_t dest) +{ + return (DL_JUMP | (dest & 0x7FFUL)); +} + +//#define CELL(cell) ((DL_CELL) | ((cell) & 0x7FUL)) +/** + * @brief Set the bitmap cell number for the VERTEX2F command. + * @return a 32 bit word for use with EVE_cmd_dl() + */ +static inline uint32_t CELL(uint8_t cell) +{ + return (DL_CELL | (cell & 0x7FUL)); +} + +//#define CLEAR(c,s,t) ((DL_CLEAR) | (((c) & 1UL) << 2U) | (((s) & 1UL) << 1U) | ((t) & 1UL)) +/** + * @brief Clear buffers to preset values. + * @return a 32 bit word for use with EVE_cmd_dl() + */ +static inline uint32_t CLEAR(uint8_t color, uint8_t stencil, uint8_t tag) +{ + uint32_t const colorv = (color & 1UL) << 2U; + uint32_t const stencilv = (stencil & 1UL) << 1U; + uint32_t const tagv = (tag & 1UL); + return (DL_CLEAR | colorv | stencilv | tagv); +} + +//#define CLEAR_COLOR_A(alpha) ((DL_CLEAR_COLOR_A) | ((alpha) & 0xFFUL)) +/** + * @brief Set clear value for the alpha channel. + * @return a 32 bit word for use with EVE_cmd_dl() + */ +static inline uint32_t CLEAR_COLOR_A(uint8_t alpha) +{ + return (DL_CLEAR_COLOR_A | alpha); +} + +//#define CLEAR_COLOR_RGB(red,green,blue) ((DL_CLEAR_COLOR_RGB) | (((red) & 0xFFUL) << 16U) | (((green) & 0xFFUL) << 8U) | ((blue) & 0xFFUL)) +/** + * @brief Set clear values for red, green and blue channels. + * @return a 32 bit word for use with EVE_cmd_dl() + */ +static inline uint32_t CLEAR_COLOR_RGB(uint8_t red, uint8_t green, uint8_t blue) +{ + uint32_t const redv = ((red & 0xFFUL) << 16U); + uint32_t const greenv = ((green & 0xFFUL) << 8U); + uint32_t const bluev = (blue & 0xFFUL); + return (DL_CLEAR_COLOR_RGB | redv | greenv | bluev); +} + +//#define CLEAR_STENCIL(s) ((DL_CLEAR_STENCIL) | ((s) & 0xFFUL)) +/** + * @brief Set clear value for the stencil buffer. + * @return a 32 bit word for use with EVE_cmd_dl() + */ +static inline uint32_t CLEAR_STENCIL(uint8_t val) +{ + return (DL_CLEAR_STENCIL | val); +} + +//#define CLEAR_TAG(s) ((DL_CLEAR_TAG) | ((s) & 0xFFUL)) +/** + * @brief Set clear value for the tag buffer. + * @return a 32 bit word for use with EVE_cmd_dl() + */ +static inline uint32_t CLEAR_TAG(uint8_t val) +{ + return (DL_CLEAR_TAG | val); +} + +//#define COLOR_A(alpha) ((DL_COLOR_A) | ((alpha) & 0xFFUL)) +/** + * @brief Set the current color alpha. + * @return a 32 bit word for use with EVE_cmd_dl() + */ +static inline uint32_t COLOR_A(uint8_t alpha) +{ + return (DL_COLOR_A | alpha); +} + +//#define COLOR_MASK(r,g,b,a) ((DL_COLOR_MASK) | (((r) & 1UL) << 3U) | (((g) & 1UL) << 2U) | (((b) & 1UL) << 1U) | ((a) & 1UL)) +/** + * @brief Enable or disable writing of color components. + * @return a 32 bit word for use with EVE_cmd_dl() + */ +static inline uint32_t COLOR_MASK(uint8_t red, uint8_t green, uint8_t blue, uint8_t alpha) +{ + uint32_t const redv = ((red & 1UL) << 3U); + uint32_t const greenv = ((green & 1UL) << 2U); + uint32_t const bluev = ((blue & 1UL) << 1U); + uint32_t const alphav = (alpha & 1UL); + return (DL_COLOR_MASK | redv | greenv | bluev | alphav); +} + +//#define COLOR_RGB(red,green,blue) ((DL_COLOR_RGB) | (((red) & 0xFFUL) << 16U) | (((green) & 0xFFUL) << 8U) | ((blue) & 0xFFUL)) +/** + * @brief Set the current color red, green and blue. + * @return a 32 bit word for use with EVE_cmd_dl() + */ +static inline uint32_t COLOR_RGB(uint8_t red, uint8_t green, uint8_t blue) +{ + uint32_t const redv = ((red & 0xFFUL) << 16U); + uint32_t const greenv = ((green & 0xFFUL) << 8U); + uint32_t const bluev = (blue & 0xFFUL); + return (DL_COLOR_RGB | redv | greenv | bluev); +} + +//#define LINE_WIDTH(width) ((DL_LINE_WIDTH) | (((uint32_t) (width)) & 0xFFFUL)) +/** + * @brief Set the width of lines to be drawn with primitive LINES in 1/16 pixel precision. + * @return a 32 bit word for use with EVE_cmd_dl() + */ +static inline uint32_t LINE_WIDTH(uint16_t width) +{ + return (DL_LINE_WIDTH | (width & 0xFFFUL)); +} + +//#define MACRO(m) ((DL_MACRO) | ((m) & 1UL)) +/** + * @brief Execute a single command from a macro register. + * @return a 32 bit word for use with EVE_cmd_dl() + */ +static inline uint32_t MACRO(uint8_t macro) +{ + return (DL_MACRO | (macro & 0x1UL)); +} + +//#define PALETTE_SOURCE(addr) ((DL_PALETTE_SOURCE) | ((addr) & 0x3FFFFF3UL)) +/** + * @brief Set the base address of the palette. + * @note 2-byte alignment is required if pixel format is PALETTE4444 or PALETTE565. + * @return a 32 bit word for use with EVE_cmd_dl() + */ +static inline uint32_t PALETTE_SOURCE(uint32_t addr) +{ + return (DL_PALETTE_SOURCE | (addr & 0x3FFFFFUL)); +} + +//#define POINT_SIZE(size) ((DL_POINT_SIZE) | ((size) & 0x1FFFUL)) +/** + * @brief Set the radius of points to be drawn with primitive POINTS in 1/16 pixel precision. + * @return a 32 bit word for use with EVE_cmd_dl() + */ +static inline uint32_t POINT_SIZE(uint16_t size) +{ + return (DL_POINT_SIZE | (size & 0x1FFFUL)); +} + +//#define SCISSOR_SIZE(width,height) ((DL_SCISSOR_SIZE) | (((width) & 0xFFFUL) << 12U) | ((height) & 0xFFFUL)) +/** + * @brief Set the size of the scissor clip rectangle. + * @note valid range for width and height is from zero to 2048 + * @return a 32 bit word for use with EVE_cmd_dl() + */ +static inline uint32_t SCISSOR_SIZE(uint16_t width, uint16_t height) +{ + uint32_t const widthv = (uint32_t) ((width & 0xFFFUL) << 12U); + uint32_t const heightv = (uint32_t) (height & 0xFFFUL); + return (DL_SCISSOR_SIZE | widthv | heightv); +} + +//#define SCISSOR_XY(x,y) ((DL_SCISSOR_XY) | (((x) & 0x7FFUL) << 11U) | ((y) & 0x7FFUL)) +/** + * @brief Set the top left corner of the scissor clip rectangle. + * @note valid range for width and height is from zero to 2047 + * @return a 32 bit word for use with EVE_cmd_dl() + */ +static inline uint32_t SCISSOR_XY(uint16_t xc0, uint16_t yc0) +{ + uint32_t const xc0v = (uint32_t) ((xc0 & 0x7FFUL) << 11U); + uint32_t const yc0v = (uint32_t) (yc0 & 0x7FFUL); + return (DL_SCISSOR_XY | xc0v | yc0v); +} + +//#define STENCIL_FUNC(func,ref,mask) ((DL_STENCIL_FUNC) | (((func) & 7UL) << 16U) | (((ref) & 0xFFUL) << 8U)|((mask) & 0xFFUL)) +/** + * @brief Set function and reference value for stencil testing. + * @return a 32 bit word for use with EVE_cmd_dl() + */ +static inline uint32_t STENCIL_FUNC(uint8_t func, uint8_t ref, uint8_t mask) +{ + uint32_t const funcv = (uint32_t) ((func & 7UL) << 16U); + uint32_t const refv = (uint32_t) ((ref & 0xFFUL) << 8U); + uint32_t const maskv = (uint32_t) (mask & 0xFFUL); + return (DL_STENCIL_FUNC | funcv | refv | maskv); +} + +//#define STENCIL_MASK(mask) ((DL_STENCIL_MASK) | ((mask) & 0xFFUL)) +/** + * @brief Control the writing of individual bits in the stencil planes. + * @return a 32 bit word for use with EVE_cmd_dl() + */ +static inline uint32_t STENCIL_MASK(uint8_t mask) +{ + return (DL_STENCIL_MASK | mask); +} + +//#define STENCIL_OP(sfail,spass) ((DL_STENCIL_OP) | (((sfail) & 7UL) << 3U) | ((spass) & 7UL)) +/** + * @brief Set stencil test actions. + * @return a 32 bit word for use with EVE_cmd_dl() + */ +static inline uint32_t STENCIL_OP(uint8_t sfail, uint8_t spass) +{ + uint32_t const sfailv = (uint32_t) ((sfail & 0x07UL) << 3U); + uint32_t const spassv = (uint32_t) (spass & 0x07UL); + return (DL_STENCIL_OP | sfailv | spassv); +} + +//#define TAG(s) ((DL_TAG) | ((s) & 0xFFUL)) +/** + * @brief Attach the tag value for the following graphics objects drawn on the screen. + * @return a 32 bit word for use with EVE_cmd_dl() + */ +static inline uint32_t TAG(uint8_t tagval) +{ + return (DL_TAG | tagval); +} + +//#define TAG_MASK(mask) ((DL_TAG_MASK) | ((mask) & 1UL)) +/** + * @brief Control the writing of the tag buffer. + * @return a 32 bit word for use with EVE_cmd_dl() + */ +static inline uint32_t TAG_MASK(uint8_t mask) +{ + return (DL_TAG_MASK | ((mask) & 1UL)); +} + +//#define VERTEX2F(x,y) ((DL_VERTEX2F) | ((((uint32_t) (x)) & 0x7FFFUL) << 15U) | (((uint32_t) (y)) & 0x7FFFUL)) +/** + * @brief Set coordinates for graphics primitves. + * @return a 32 bit word for use with EVE_cmd_dl() + */ +static inline uint32_t VERTEX2F(int16_t xc0, int16_t yc0) +{ + uint32_t const xc0v = ((((uint32_t) ((uint16_t) xc0)) & 0x7FFFUL) << 15U); + uint32_t const yc0v = (((uint32_t) ((uint16_t) yc0)) & 0x7FFFUL); + return (DL_VERTEX2F | xc0v | yc0v); +} + +//#define VERTEX2II(x,y,handle,cell) ((DL_VERTEX2II) | (((x) & 0x1FFUL) << 21U) | (((y) & 0x1FFUL) << 12U) | (((handle) & 0x1FUL) << 7U) | ((cell) & 0x7FUL)) +/** + * @brief Set coordinates, bitmap-handle and cell-number for graphics primitves. + * @return a 32 bit word for use with EVE_cmd_dl() + */ +static inline uint32_t VERTEX2II(uint16_t xc0, uint16_t yc0, uint8_t handle, uint8_t cell) +{ + uint32_t const xc0v = ((((uint32_t) xc0) & 0x1FFUL) << 21U); + uint32_t const yc0v = ((((uint32_t) yc0) & 0x1FFUL) << 12U); + uint32_t const handlev = ((((uint32_t) handle) & 0x1FUL) << 7U); + uint32_t const cellv = (((uint32_t) cell) & 0x7FUL); + return (DL_VERTEX2II | xc0v | yc0v | handlev | cellv); +} + +//#define VERTEX_FORMAT(frac) ((DL_VERTEX_FORMAT) | ((frac) & 7UL)) +/** + * @brief Set the precision of VERTEX2F coordinates. + * @return a 32 bit word for use with EVE_cmd_dl() + */ +static inline uint32_t VERTEX_FORMAT(uint8_t frac) +{ + return (DL_VERTEX_FORMAT | ((frac) & 7UL)); +} + +//#define VERTEX_TRANSLATE_X(x) ((DL_VERTEX_TRANSLATE_X) | ((x) & 0x1FFFFUL)) +/** + * @brief Set the vertex transformations X translation component. + * @return a 32 bit word for use with EVE_cmd_dl() + */ +static inline uint32_t VERTEX_TRANSLATE_X(int32_t xco) +{ + return (DL_VERTEX_TRANSLATE_X | (((uint32_t) xco) & 0x1FFFFUL)); +} + +//#define VERTEX_TRANSLATE_Y(y) ((DL_VERTEX_TRANSLATE_Y) | ((y) & 0x1FFFFUL)) +/** + * @brief Set the vertex transformations Y translation component. + * @return a 32 bit word for use with EVE_cmd_dl() + */ +static inline uint32_t VERTEX_TRANSLATE_Y(int32_t yco) +{ + return (DL_VERTEX_TRANSLATE_Y | (((uint32_t) yco) & 0x1FFFFUL)); +} + +/* #define BEGIN(prim) ((DL_BEGIN) | ((prim) & 15UL)) */ /* use define DL_BEGIN */ +/* #define DISPLAY() ((DL_DISPLAY)) */ /* use define DL_DISPLAY */ +/* #define END() ((DL_END)) */ /* use define DL_END */ +/* #define RESTORE_CONTEXT() ((DL_RESTORE_CONTEXT)) */ /* use define DL_RESTORE_CONTEXT */ +/* #define RETURN() ((DL_RETURN)) */ /* use define DL_RETURN */ +/* #define SAVE_CONTEXT() ((DL_SAVE_CONTEXT)) */ /* use define DL_SAVE_CONTEXT */ +/* #define NOP() ((DL_NOP)) */ + +/* ########## EVE Generation 3: BT815 / BT816 definitions ########## */ + +#if EVE_GEN > 2 + +#define EVE_GLFORMAT ((uint32_t) 31UL) /* used with BITMAP_LAYOUT to indicate bitmap-format is specified by BITMAP_EXT_FORMAT */ + +#define DL_BITMAP_EXT_FORMAT ((uint32_t) 0x2E000000UL) /* requires OR'd arguments */ +#define DL_BITMAP_SWIZZLE ((uint32_t) 0x2F000000UL) +/* #define DL_INT_FRR ((uint32_t) 0x30000000UL) */ /* ESE displays "Internal: flash read result" - undocumented display list command */ + +/* Extended Bitmap formats */ +#define EVE_ASTC_4X4 ((uint32_t) 37808UL) +#define EVE_ASTC_5X4 ((uint32_t) 37809UL) +#define EVE_ASTC_5X5 ((uint32_t) 37810UL) +#define EVE_ASTC_6X5 ((uint32_t) 37811UL) +#define EVE_ASTC_6X6 ((uint32_t) 37812UL) +#define EVE_ASTC_8X5 ((uint32_t) 37813UL) +#define EVE_ASTC_8X6 ((uint32_t) 37814UL) +#define EVE_ASTC_8X8 ((uint32_t) 37815UL) +#define EVE_ASTC_10X5 ((uint32_t) 37816UL) +#define EVE_ASTC_10X6 ((uint32_t) 37817UL) +#define EVE_ASTC_10X8 ((uint32_t) 37818UL) +#define EVE_ASTC_10X10 ((uint32_t) 37819UL) +#define EVE_ASTC_12X10 ((uint32_t) 37820UL) +#define EVE_ASTC_12X12 ((uint32_t) 37821UL) + +#define EVE_RAM_ERR_REPORT ((uint32_t) 0x309800UL) /* max 128 bytes null terminated string */ +#define EVE_RAM_FLASH ((uint32_t) 0x800000UL) +#define EVE_RAM_FLASH_POSTBLOB ((uint32_t) 0x801000UL) + +#define EVE_OPT_FLASH ((uint16_t) 64U) +#define EVE_OPT_OVERLAY ((uint16_t) 128U) +#define EVE_OPT_FORMAT ((uint16_t) 4096U) +#define EVE_OPT_FILL ((uint16_t) 8192U) + +/* Commands for BT815 / BT816 */ +#define CMD_BITMAP_TRANSFORM ((uint32_t) 0xFFFFFF21UL) +#define CMD_SYNC ((uint32_t) 0xFFFFFF42UL) /* does not need a dedicated function, just use EVE_cmd_dl(CMD_SYNC) */ +#define CMD_FLASHERASE ((uint32_t) 0xFFFFFF44UL) /* does not need a dedicated function, just use EVE_cmd_dl(CMD_FLASHERASE) */ +#define CMD_FLASHWRITE ((uint32_t) 0xFFFFFF45UL) +#define CMD_FLASHREAD ((uint32_t) 0xFFFFFF46UL) +#define CMD_FLASHUPDATE ((uint32_t) 0xFFFFFF47UL) +#define CMD_FLASHDETACH ((uint32_t) 0xFFFFFF48UL) /* does not need a dedicated function, just use EVE_cmd_dl(CMD_FLASHDETACH) */ +#define CMD_FLASHATTACH ((uint32_t) 0xFFFFFF49UL) /* does not need a dedicated function, just use EVE_cmd_dl(CMD_FLASHATTACH) */ +#define CMD_FLASHFAST ((uint32_t) 0xFFFFFF4AUL) +#define CMD_FLASHSPIDESEL ((uint32_t) 0xFFFFFF4BUL) /* does not need a dedicated function, just use EVE_cmd_dl(CMD_FLASHSPIDESEL) */ +#define CMD_FLASHSPITX ((uint32_t) 0xFFFFFF4CUL) +#define CMD_FLASHSPIRX ((uint32_t) 0xFFFFFF4DUL) +#define CMD_FLASHSOURCE ((uint32_t) 0xFFFFFF4EUL) +#define CMD_CLEARCACHE ((uint32_t) 0xFFFFFF4FUL) /* does not need a dedicated function, just use EVE_cmd_dl(CMD_CLEARCACHE) */ +#define CMD_INFLATE2 ((uint32_t) 0xFFFFFF50UL) +#define CMD_ROTATEAROUND ((uint32_t) 0xFFFFFF51UL) +#define CMD_RESETFONTS ((uint32_t) 0xFFFFFF52UL) /* does not need a dedicated function, just use EVE_cmd_dl(CMD_RESETFONTS) */ +#define CMD_ANIMSTART ((uint32_t) 0xFFFFFF53UL) +#define CMD_ANIMSTOP ((uint32_t) 0xFFFFFF54UL) +#define CMD_ANIMXY ((uint32_t) 0xFFFFFF55UL) +#define CMD_ANIMDRAW ((uint32_t) 0xFFFFFF56UL) +#define CMD_GRADIENTA ((uint32_t) 0xFFFFFF57UL) +#define CMD_FILLWIDTH ((uint32_t) 0xFFFFFF58UL) +#define CMD_APPENDF ((uint32_t) 0xFFFFFF59UL) +#define CMD_ANIMFRAME ((uint32_t) 0xFFFFFF5AUL) +#define CMD_VIDEOSTARTF ((uint32_t) 0xFFFFFF5FUL) /* does not need a dedicated function, just use EVE_cmd_dl(CMD_VIDEOSTARTF) */ + +/* Registers for BT815 / BT816 */ +#define REG_ADAPTIVE_FRAMERATE ((uint32_t) 0x0030257cUL) +#define REG_PLAYBACK_PAUSE ((uint32_t) 0x003025ecUL) +#define REG_FLASH_STATUS ((uint32_t) 0x003025f0UL) +#define REG_FLASH_SIZE ((uint32_t) 0x00309024UL) +#define REG_PLAY_CONTROL ((uint32_t) 0x0030914eUL) +#define REG_COPRO_PATCH_PTR ((uint32_t) 0x00309162UL) + +/* Macros for BT815 / BT816 */ + +//#define BITMAP_EXT_FORMAT(format) ((DL_BITMAP_EXT_FORMAT) | ((format) & 0xFFFFUL)) +/** + * @brief Set the extended format of the bitmap. + * @return a 32 bit word for use with EVE_cmd_dl() + */ +static inline uint32_t BITMAP_EXT_FORMAT(uint16_t format) +{ + return (DL_BITMAP_EXT_FORMAT | format); +} + +//#define BITMAP_SWIZZLE(r,g,b,a) ((DL_BITMAP_SWIZZLE) | (((r) & 7UL) << 9U) | (((g) & 7UL) << 6U) | (((b) & 7UL) << 3U) | ((a) & 7UL)) +/** + * @brief Set the source for the red, green, blue and alpha channels of a bitmap. + * @return a 32 bit word for use with EVE_cmd_dl() + */ +static inline uint32_t BITMAP_SWIZZLE(uint8_t red, uint8_t green, uint8_t blue, uint8_t alpha) +{ + uint32_t const redv = ((red & 7UL) << 9U); + uint32_t const greenv = ((green & 7UL) << 6U); + uint32_t const bluev = ((blue & 7UL) << 3U); + uint32_t const alphav = (alpha & 7UL); + return (DL_BITMAP_SWIZZLE | redv | greenv | bluev | alphav); +} + +//#define BITMAP_TRANSFORM_A_EXT(p,v) ((DL_BITMAP_TRANSFORM_A) | (((p) & 1UL) << 17U) | ((v) & 0x1FFFFUL)) +/** + * @brief Set the A coefficient of the bitmap transform matrix. + * @return a 32 bit word for use with EVE_cmd_dl() + */ +static inline uint32_t BITMAP_TRANSFORM_A(uint8_t prc, uint32_t val) +{ + uint32_t const prcv = ((prc & 1UL) << 17U); + uint32_t const valv = (val & 0x1FFFFUL); + return (DL_BITMAP_TRANSFORM_A | prcv | valv); +} + +//#define BITMAP_TRANSFORM_B_EXT(p,v) ((DL_BITMAP_TRANSFORM_B) | (((p) & 1UL) << 17U) | ((v) & 0x1FFFFUL)) +/** + * @brief Set the B coefficient of the bitmap transform matrix. + * @return a 32 bit word for use with EVE_cmd_dl() + */ +static inline uint32_t BITMAP_TRANSFORM_B(uint8_t prc, uint32_t val) +{ + uint32_t const prcv = ((prc & 1UL) << 17U); + uint32_t const valv = (val & 0x1FFFFUL); + return (DL_BITMAP_TRANSFORM_B | prcv | valv); +} + +//#define BITMAP_TRANSFORM_D_EXT(p,v) ((DL_BITMAP_TRANSFORM_D) | (((p) & 1UL) << 17U) | ((v) & 0x1FFFFUL)) +/** + * @brief Set the D coefficient of the bitmap transform matrix. + * @return a 32 bit word for use with EVE_cmd_dl() + */ +static inline uint32_t BITMAP_TRANSFORM_D(uint8_t prc, uint32_t val) +{ + uint32_t const prcv = ((prc & 1UL) << 17U); + uint32_t const valv = (val & 0x1FFFFUL); + return (DL_BITMAP_TRANSFORM_D | prcv | valv); +} + +//#define BITMAP_TRANSFORM_E_EXT(p,v) ((DL_BITMAP_TRANSFORM_E) | (((p) & 1UL) << 17U) | ((v) & 0x1FFFFUL)) +/** + * @brief Set the E coefficient of the bitmap transform matrix. + * @return a 32 bit word for use with EVE_cmd_dl() + */ +static inline uint32_t BITMAP_TRANSFORM_E(uint8_t prc, uint32_t val) +{ + uint32_t const prcv = ((prc & 1UL) << 17U); + uint32_t const valv = (val & 0x1FFFFUL); + return (DL_BITMAP_TRANSFORM_E | prcv | valv); +} + +//#define BITMAP_TRANSFORM_A(a) BITMAP_TRANSFORM_A_EXT(0UL,(a)) +//#define BITMAP_TRANSFORM_B(b) BITMAP_TRANSFORM_B_EXT(0UL,(b)) +//#define BITMAP_TRANSFORM_D(d) BITMAP_TRANSFORM_D_EXT(0UL,(d)) +//#define BITMAP_TRANSFORM_E(e) BITMAP_TRANSFORM_E_EXT(0UL,(e)) + +#endif /* EVE_GEN > 2 */ + +/* ########## EVE Generation 4: BT817 / BT818 definitions ########## */ + +#if EVE_GEN > 3 + +/* Commands for BT817 / BT818 */ +#define CMD_ANIMFRAMERAM ((uint32_t) 0xFFFFFF6DUL) +#define CMD_ANIMSTARTRAM ((uint32_t) 0xFFFFFF6EUL) +#define CMD_APILEVEL ((uint32_t) 0xFFFFFF63UL) +#define CMD_CALIBRATESUB ((uint32_t) 0xFFFFFF60UL) +#define CMD_CALLLIST ((uint32_t) 0xFFFFFF67UL) +#define CMD_ENDLIST ((uint32_t) 0xFFFFFF69UL) /* does not need a dedicated function, just use EVE_cmd_dl(CMD_ENDLIST) */ +#define CMD_FLASHPROGRAM ((uint32_t) 0xFFFFFF70UL) +#define CMD_FONTCACHE ((uint32_t) 0xFFFFFF6BUL) +#define CMD_FONTCACHEQUERY ((uint32_t) 0xFFFFFF6CUL) +#define CMD_GETIMAGE ((uint32_t) 0xFFFFFF64UL) +#define CMD_HSF ((uint32_t) 0xFFFFFF62UL) +#define CMD_LINETIME ((uint32_t) 0xFFFFFF5EUL) +#define CMD_NEWLIST ((uint32_t) 0xFFFFFF68UL) +#define CMD_PCLKFREQ ((uint32_t) 0xFFFFFF6AUL) +#define CMD_RETURN ((uint32_t) 0xFFFFFF66UL) /* does not need a dedicated function, just use EVE_cmd_dl(CMD_RETURN) */ +#define CMD_RUNANIM ((uint32_t) 0xFFFFFF6FUL) +#define CMD_TESTCARD ((uint32_t) 0xFFFFFF61UL) /* does not need a dedicated function, just use EVE_cmd_dl(CMD_TESTCARD) */ +#define CMD_WAIT ((uint32_t) 0xFFFFFF65UL) + +/* Registers for BT817 / BT818 */ +#define REG_UNDERRUN ((uint32_t) 0x0030260cUL) +#define REG_AH_HCYCLE_MAX ((uint32_t) 0x00302610UL) +#define REG_PCLK_FREQ ((uint32_t) 0x00302614UL) +#define REG_PCLK_2X ((uint32_t) 0x00302618UL) +#define REG_ANIM_ACTIVE ((uint32_t) 0x0030902CUL) + +#endif /* EVE_GEN > 3 */ + +#ifdef __cplusplus +} +#endif + +#endif /* EVE_H */ diff --git a/src/libs/FT800-FT813/EVE_commands.c b/src/libs/FT800-FT813/EVE_commands.c new file mode 100644 index 0000000000..59e3d052f1 --- /dev/null +++ b/src/libs/FT800-FT813/EVE_commands.c @@ -0,0 +1,3926 @@ +#include "../../lv_conf_internal.h" +#if LV_USE_DRAW_EVE +/* +@file EVE_commands.c +@brief contains FT8xx / BT8xx functions +@version 5.0 +@date 2023-12-29 +@author Rudolph Riedel + +@section info + +At least for Arm Cortex-M0 and Cortex-M4 I have fastest execution with -O2. +The c-standard is C99. + + +@section LICENSE + +MIT License + +Copyright (c) 2016-2023 Rudolph Riedel + +Permission is hereby granted, free of charge, to any person obtaining a copy of +this software and associated documentation files (the "Software"), to deal in +the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, +and/or sell copies of the Software, and to permit persons to whom the Software +is furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS +FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR +COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER +IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + + +@section History + +5.0 +- added EVE_cmd_pclkfreq() +- put back writing of REG_CSSPREAD as it needs to be deactivated for higher frequencies +- added the configuration of the second PLL for the pixel clock in BT817/BT818 to EVE_init() in case the display config +has EVE_PCLK_FREQ defined +- replaced BT81X_ENABLE with "EVE_GEN > 2" +- removed FT81X_ENABLE as FT81x already is the lowest supported chip revision now +- removed the formerly as deprected marked EVE_get_touch_tag() +- changed EVE_color_rgb() to use a 32 bit value like the rest of the color commands +- removed the meta-commands EVE_cmd_point(), EVE_cmd_line() and EVE_cmd_rect() +- split all display-list commands into two functions: EVE_cmd_XXX() and EVE_cmd_XXX_burst() +- switched from using EVE_RAM_CMD + cmdOffset to REG_CMDB_WRITE +- as a side effect from switching to REG_CMDB_WRITE, every coprocessor command is automatically executed now +- renamed EVE_LIB_GetProps() back to EVE_cmd_getprops() since it does not do anything special to justify a special name +- added helper function EVE_memWrite_sram_buffer() +- added EVE_cmd_bitmap_transform() and EVE_cmd_bitmap_transform_burst() +- added zero-pointer protection to commands using block_transfer() +- added EVE_cmd_playvideo() +- changed EVE_cmd_setfont() to a display-list command and added EVE_cmd_setfont_burst() +- changed EVE_cmd_setfont2() to a display-list command and added EVE_cmd_setfont2_burst() +- added EVE_cmd_videoframe() +- restructured: functions are sorted by chip-generation and within their group in alphabetical order +- reimplementedEVE_cmd_getmatrix() again, it needs to read values, not write them +- added EVE_cmd_fontcache() and EVE_cmd_fontcachequery() +- added EVE_cmd_calibratesub() +- added EVE_cmd_animframeram(), EVE_cmd_animframeram_burst(), EVE_cmd_animstartram(), EVE_cmd_animstartram_burst() +- added EVE_cmd_apilevel(), EVE_cmd_apilevel_burst() +- added EVE_cmd_calllist(), EVE_cmd_calllist_burst() +- added EVE_cmd_hsf(), EVE_cmd_hsf_burst() +- added EVE_cmd_linetime() +- added EVE_cmd_newlist(), EVE_cmd_newlist_burst() +- added EVE_cmd_runanim(), EVE_cmd_runanim_burst() +- added a safeguard to EVE_start_cmd_burst() to protect it from overlapping transfers with DMA and segmented lists +- used spi_transmit_32() to shorten this file by around 600 lines with no functional change +- removed the history from before 4.0 +- removed a couple of spi_transmit_32() calls from EVE_cmd_getptr() to make it work again +- Bugfix: EVE_cmd_setfont2_burst() was using CMD_SETFONT instead of CMD_SETFONT2 +- removed a check for cmd_burst from EVE_cmd_getimage() as it is in the group of commands that are not used for display +lists +- moved EVE_cmd_newlist() to the group of commands that are not used for display lists +- removed EVE_cmd_newlist_burst() +- renamed spi_flash_write() to private_block_write() and made it static +- renamed EVE_write_string() to private_string_write() and made it static +- made EVE_start_command() static +- Bugfix: ESP8266 needs 32 bit alignment for 32 bit pointers, + changed private_string_write() for burst-mode to read 8-bit values +- Bugfix: somehow messed up private_string_write() for burst-mode + but only for 8-Bit controllers +- changed EVE_memRead8(), EVE_memRead16() and EVE_memRead32() to use + spi_transmit_32() for the initial address+zero byte transfer + This speeds up ESP32/ESP8266 by several us, has no measureable effect + for ATSAMD51 and is a little slower for AVR. +- Bugfix: not sure why but setting private_block_write() to static broke it, without "static" it works +- Bugfix: EVE_cmd_flashspirx() was using CMD_FLASHREAD +- fixed a warning in EVE_init() when compiling for EVE4 +- renamed internal function EVE_begin_cmd() to eve_begin_cmd() and made it static +- changed all the EVE_start_command() calls to eve_begin_cmd() calls following the report on Github from + Michael Wachs that these are identical - they weren't prior to V5 +- removed EVE_start_command() +- Bugfix: EVE_init() was only checking the first two bits of REG_CPURESET and ignored the bit for the audio-engine, not +an issue but not correct either. +- fixed a few clang-tidy warnings +- fixed a few cppcheck warnings +- fixed a few CERT warnings +- converted all TABs to SPACEs +- made EVE_TOUCH_RZTHRESH in EVE_init() optional to a) remove it from EVE_config.h and b) make it configureable +externally +- changed EVE_init() to write 1200U to REG_TOUCH_RZTHRESH if EVE_TOUCH_RZTHRESH is not defined +- changed EVE_init() to return E_OK = 0x00 in case of success and more meaningfull values in case of failure +- changed EVE_busy() to return EVE_IS_BUSY if EVE is busy and E_OK = 0x00 if EVE is not busy - no real change in +functionality +- finally removed EVE_cmd_start() after setting it to deprecatd with the first 5.0 release +- renamed EVE_cmd_execute() to EVE_execute_cmd() to be more consistent, this is is not an EVE command +- changed EVE_init_flash() to return E_OK in case of success and more meaningfull values in case of failure +- added the return-value of EVE_FIFO_HALF_EMPTY to EVE_busy() to indicate there is more than 2048 bytes available +- minor cleanup, less break and else statements +- added the burst code back into all the functions for which there is a _burst version, this allows to use the version +without the traling _burst in the name when exceution speed is not an issue - e.g. with all targets supporting DMA +- removed the 4.0 history +- added the optional parameter EVE_ROTATE as define to EVE_init() to allow for screen rotation during init + thanks for the idea to AndrejValand on Github! +- added the optional parameter EVE_BACKLIGHT_PWM to EVE_init() to allow setting the backlight during init +- modified EVE_calibrate_manual() to work better with bar type displays +- fixed a large number of MISRA-C issues - mostly more casts for explicit type conversion and more brackets +- changed the varargs versions of cmd_button, cmd_text and cmd_toggle to use an array of uint32_t values to comply with MISRA-C +- basic maintenance: checked for violations of white space and indent rules +- more linter fixes for minor issues like variables shorter than 3 characters +- added EVE_color_a() / EVE_color_a_burst() +- more minor tweaks and fixes to make the static analyzer happy +- changed the burst variant of private_string_write() back to the older and faster version +- refactoring of EVE_init() to single return +- added prototype for EVE_write_display_parameters() +- added EVE_memRead_sram_buffer() +- Bugfix issue #81: neither DISP or the pixel clock are enabled for EVE4 configurations not using EVE_PCLK_FREQ. + thanks for the report to grados73 on Github! +- added a few support lines for the Gameduino GD3X to EVE_init() +- switched from using CMD_PCLKFREQ to writing to REG_PCLK_FREQ directly +- added define EVE_SET_REG_PCLK_2X to set REG_PCLK_2X to 1 when necessary +- Bugfix: EVE_init() did not set the audio engine to "mute" as intended, but to "silent" +- Bugfix: EVE_busy() returns E_NOT_OK now on coprocessor faults. + thanks for the report to Z0ld3n on Github! +- Fix: reworked EVE_busy() to return EVE_FAULT_RECOVERED on deteced coprocessor faults, + removed the flash commands from the fault recovery sequence as these are project specific. +- added EVE_get_and_reset_fault_state() to check if EVE_busy() triggered a fault recovery +- added notes on how to use to EVE_cmd_setfont2() and EVE_cmd_romfont() +- new optional parameter in EVE_init(): EVE_BACKLIGHT_FREQ +- fixed a couple of minor issues from static code analysis +- reworked the burst part of private_string_write() to be less complex +- renamed chipid references to regid as suggested by #93 on github +- Bugfix: broke transfers of buffers larger than 3840 when fixing issues from static code analysis +- changed a number of function parameters from signed to unsigned following the + updated BT81x series programming guide V2.4 +- did another linter pass and fixed some things +- started to improve the embedded documentation +- added more documentation +- removed EVE_cmd_hsf_burst() + +*/ + +#include "EVE_commands.h" + +/* EVE Memory Commands - used with EVE_memWritexx and EVE_memReadxx */ +#define MEM_WRITE 0x80U /* EVE Host Memory Write */ +/* #define MEM_READ 0x00U */ /* EVE Host Memory Read */ + +/* define NULL if it not already is */ +#ifndef NULL +#include +#endif + +static volatile uint8_t cmd_burst = 0U; /* flag to indicate cmd-burst is active */ +static volatile uint8_t fault_recovered = E_OK; /* flag to indicate if EVE_busy triggered a fault recovery */ + +/* ################################################################## + helper functions +##################################################################### */ + +/** + * @brief Send a host command. + */ +void EVE_cmdWrite(uint8_t const command, uint8_t const parameter) +{ + EVE_cs_set(); + spi_transmit(command); + spi_transmit(parameter); + spi_transmit(0U); + EVE_cs_clear(); +} + +/** + * @brief Implementation of rd8() function, reads 8 bits. + */ +uint8_t EVE_memRead8(uint32_t const ft_address) +{ + uint8_t data; + EVE_cs_set(); + spi_transmit_32(((ft_address >> 16U) & 0x0000007fUL) + (ft_address & 0x0000ff00UL) + ((ft_address & 0x000000ffUL) << 16U)); + data = spi_receive(0U); /* read data byte by sending another dummy byte */ + EVE_cs_clear(); + return (data); +} + +/** + * @brief Implementation of rd16() function, reads 16 bits. + */ +uint16_t EVE_memRead16(uint32_t const ft_address) +{ + uint16_t data; + + EVE_cs_set(); + spi_transmit_32(((ft_address >> 16U) & 0x0000007fUL) + (ft_address & 0x0000ff00UL) + ((ft_address & 0x000000ffUL) << 16U)); + uint8_t const lowbyte = spi_receive(0U); /* read low byte */ + uint8_t const hibyte = spi_receive(0U); /* read high byte */ + data = ((uint16_t) hibyte * 256U) | lowbyte; + EVE_cs_clear(); + return (data); +} + +/** + * @brief Implementation of rd32() function, reads 32 bits. + */ +uint32_t EVE_memRead32(uint32_t const ft_address) +{ + uint32_t data; + EVE_cs_set(); + spi_transmit_32(((ft_address >> 16U) & 0x0000007fUL) + (ft_address & 0x0000ff00UL) + ((ft_address & 0x000000ffUL) << 16U)); + data = ((uint32_t) spi_receive(0U)); /* read low byte */ + data = ((uint32_t) spi_receive(0U) << 8U) | data; + data = ((uint32_t) spi_receive(0U) << 16U) | data; + data = ((uint32_t) spi_receive(0U) << 24U) | data; /* read high byte */ + EVE_cs_clear(); + return (data); +} + +/** + * @brief Implementation of wr8() function, writes 8 bits. + */ +void EVE_memWrite8(uint32_t const ft_address, uint8_t const ft_data) +{ + EVE_cs_set(); + spi_transmit((uint8_t) (ft_address >> 16U) | MEM_WRITE); + spi_transmit((uint8_t) (ft_address >> 8U)); + spi_transmit((uint8_t) (ft_address & 0x000000ffUL)); + spi_transmit(ft_data); + EVE_cs_clear(); +} + +/** + * @brief Implementation of wr16() function, writes 16 bits. + */ +void EVE_memWrite16(uint32_t const ft_address, uint16_t const ft_data) +{ + EVE_cs_set(); + spi_transmit((uint8_t) (ft_address >> 16U) | MEM_WRITE); /* send Memory Write plus high address byte */ + spi_transmit((uint8_t) (ft_address >> 8U)); /* send middle address byte */ + spi_transmit((uint8_t) (ft_address & 0x000000ffUL)); /* send low address byte */ + spi_transmit((uint8_t) (ft_data & 0x00ffU)); /* send data low byte */ + spi_transmit((uint8_t) (ft_data >> 8U)); /* send data high byte */ + EVE_cs_clear(); +} + +/** + * @brief Implementation of wr32() function, writes 32 bits. + */ +void EVE_memWrite32(uint32_t const ft_address, uint32_t const ft_data) +{ + EVE_cs_set(); + spi_transmit((uint8_t) (ft_address >> 16U) | MEM_WRITE); /* send Memory Write plus high address byte */ + spi_transmit((uint8_t) (ft_address >> 8U)); /* send middle address byte */ + spi_transmit((uint8_t) (ft_address & 0x000000ffUL)); /* send low address byte */ + spi_transmit_32(ft_data); + EVE_cs_clear(); +} + +/** + * @brief Helper function, write a block of memory from the FLASH of the host controller to EVE. + */ +void EVE_memWrite_flash_buffer(uint32_t const ft_address, const uint8_t *p_data, uint32_t const len) +{ + if (p_data != NULL) + { + EVE_cs_set(); + spi_transmit((uint8_t) (ft_address >> 16U) | MEM_WRITE); + spi_transmit((uint8_t) (ft_address >> 8U)); + spi_transmit((uint8_t) (ft_address & 0x000000ffUL)); + + lv_eve_target_spi_transmit_buf(p_data, len); + + EVE_cs_clear(); + } +} + +/** + * @brief Helper function, write a block of memory from the SRAM of the host controller to EVE. + */ +void EVE_memWrite_sram_buffer(uint32_t const ft_address, const uint8_t *p_data, uint32_t const len) +{ + if (p_data != NULL) + { + EVE_cs_set(); + spi_transmit((uint8_t) (ft_address >> 16U) | MEM_WRITE); + spi_transmit((uint8_t) (ft_address >> 8U)); + spi_transmit((uint8_t) (ft_address & 0x000000ffUL)); + + lv_eve_target_spi_transmit_buf(p_data, len); + + EVE_cs_clear(); + } +} + +/** + * @brief Helper function, read a block of memory from EVE to the SRAM of the host controller. + */ +void EVE_memRead_sram_buffer(uint32_t const ft_address, uint8_t *p_data, uint32_t const len) +{ + if (p_data != NULL) + { + EVE_cs_set(); + spi_transmit_32(((ft_address >> 16U) & 0x0000007fUL) + (ft_address & 0x0000ff00UL) + ((ft_address & 0x000000ffUL) << 16U)); + + for (uint32_t count = 0U; count < len; count++) + { + p_data[count] = spi_receive(0U); /* read data byte by sending another dummy byte */ + } + + EVE_cs_clear(); + } +} + +static void CoprocessorFaultRecover(void) +{ +#if EVE_GEN > 2 + uint16_t copro_patch_pointer; + copro_patch_pointer = EVE_memRead16(REG_COPRO_PATCH_PTR); +#endif + + EVE_memWrite8(REG_CPURESET, 1U); /* hold coprocessor engine in the reset condition */ + EVE_memWrite16(REG_CMD_READ, 0U); /* set REG_CMD_READ to 0 */ + EVE_memWrite16(REG_CMD_WRITE, 0U); /* set REG_CMD_WRITE to 0 */ + EVE_memWrite16(REG_CMD_DL, 0U); /* reset REG_CMD_DL to 0 as required by the BT81x programming guide, should not hurt FT8xx */ + +#if EVE_GEN > 2 + EVE_memWrite16(REG_COPRO_PATCH_PTR, copro_patch_pointer); + + /* restore REG_PCLK in case it was set to zero by an error */ +#if (EVE_GEN > 3) && (defined EVE_PCLK_FREQ) + EVE_memWrite16(REG_PCLK_FREQ, (uint16_t) EVE_PCLK_FREQ); + EVE_memWrite8(REG_PCLK, 1U); /* enable extsync mode */ +#else + EVE_memWrite8(REG_PCLK, EVE_PCLK); +#endif + +#endif + EVE_memWrite8(REG_CPURESET, 0U); /* set REG_CPURESET to 0 to restart the coprocessor engine*/ + DELAY_MS(10U); /* just to be safe */ +} + +/** + * @brief Check if the coprocessor completed executing the current command list. + * @return - E_OK - if EVE is not busy (no DMA transfer active and REG_CMDB_SPACE has the value 0xffc, meaning the CMD-FIFO is empty + * @return - EVE_IS_BUSY - if a DMA transfer is active or REG_CMDB_SPACE has a value smaller than 0xffc + * @return - EVE_FIFO_HALF_EMPTY - if no DMA transfer is active and REG_CMDB_SPACE shows more than 2048 bytes available + * @return - E_NOT_OK - if there was a coprocessor fault and the recovery sequence was executed + * @note - if there is a coprocessor fault the external flash is not reinitialized by EVE_busy() + */ +uint8_t EVE_busy(void) +{ + uint16_t space; + uint8_t ret = EVE_IS_BUSY; + +#if defined (EVE_DMA) + if (0 == EVE_dma_busy) + { +#endif + + space = EVE_memRead16(REG_CMDB_SPACE); + + /* (REG_CMDB_SPACE & 0x03) != 0 -> we have a coprocessor fault */ + if ((space & 3U) != 0U) /* we have a coprocessor fault, make EVE play with us again */ + { + ret = EVE_FAULT_RECOVERED; + fault_recovered = EVE_FAULT_RECOVERED; /* save fault recovery state */ + CoprocessorFaultRecover(); + } + else + { + if (0xffcU == space) + { + ret = E_OK; + } + else if (space > 0x800U) + { + ret = EVE_FIFO_HALF_EMPTY; + } + else + { + ret = EVE_IS_BUSY; + } + } + +#if defined (EVE_DMA) + } +#endif + + return (ret); +} + +/** + * @brief Helper function to check if EVE_busy() tried to recover from a coprocessor fault. + * The internal fault indicator is cleared so it could be set by EVE_busy() again. + * @return - EVE_FAULT_RECOVERED - if EVE_busy() detected a coprocessor fault + * @return - E_OK - if EVE_busy() did not detect a coprocessor fault + */ +uint8_t EVE_get_and_reset_fault_state(void) +{ + uint8_t ret = E_OK; + + if (EVE_FAULT_RECOVERED == fault_recovered) + { + ret = EVE_FAULT_RECOVERED; + fault_recovered = E_OK; + } + return (ret); +} + +/** + * @brief Helper function, wait for the coprocessor to complete the FIFO queue. + */ +void EVE_execute_cmd(void) +{ + while (EVE_busy() != E_OK) + { + } +} + +/* begin a coprocessor command, this is used for non-display-list and non-burst-mode commands.*/ +static void eve_begin_cmd(uint32_t command) +{ + EVE_cs_set(); + spi_transmit((uint8_t) 0xB0U); /* high-byte of REG_CMDB_WRITE + MEM_WRITE */ + spi_transmit((uint8_t) 0x25U); /* middle-byte of REG_CMDB_WRITE */ + spi_transmit((uint8_t) 0x78U); /* low-byte of REG_CMDB_WRITE */ + spi_transmit_32(command); +} + +static void private_block_write(const uint8_t *p_data, uint16_t len); /* prototype to comply with MISRA */ + +static void private_block_write(const uint8_t *p_data, uint16_t len) +{ + uint8_t padding; + + padding = (uint8_t) (len & 3U); /* 0, 1, 2 or 3 */ + padding = 4U - padding; /* 4, 3, 2 or 1 */ + padding &= 3U; /* 3, 2 or 1 */ + + for (uint16_t count = 0U; count < len; count++) + { + spi_transmit(fetch_flash_byte(&p_data[count])); + } + + while (padding > 0U) + { + spi_transmit(0U); + padding--; + } +} + +static void block_transfer(const uint8_t *p_data, uint32_t len); /* prototype to comply with MISRA */ + +static void block_transfer(const uint8_t *p_data, uint32_t len) +{ + uint32_t bytes_left; + uint32_t offset = 0U; + + bytes_left = len; + while (bytes_left > 0U) + { + uint32_t block_len; + + block_len = (bytes_left > 3840UL) ? 3840UL : bytes_left; + + EVE_cs_set(); + spi_transmit((uint8_t) 0xB0U); /* high-byte of REG_CMDB_WRITE + MEM_WRITE */ + spi_transmit((uint8_t) 0x25U); /* middle-byte of REG_CMDB_WRITE */ + spi_transmit((uint8_t) 0x78U); /* low-byte of REG_CMDB_WRITE */ + private_block_write(&p_data[offset], (uint16_t) block_len); + EVE_cs_clear(); + offset += block_len; + bytes_left -= block_len; + EVE_execute_cmd(); + } +} + +/* ################################################################## + coprocessor commands that are not used in displays lists, + these are not to be used with burst transfers +################################################################### */ + +/* BT817 / BT818 */ +#if EVE_GEN > 3 + +/** + * @brief Write "num" bytes from src in RAM_G to the previously erased external flash of a BT81x at address dest. + * @note - dest must be 4096-byte aligned, src must be 4-byte aligned, num must be a multiple of 4096 + * @note - EVE will not do anything if the alignment requirements are not met + * @note - the address ptr is relative to the flash so the first address is 0x000000 not 0x800000 + * @note - this looks exactly the same as EVE_cmd_flashupdate() but it needs the flash to be empty + * @note - Meant to be called outside display-list building. + * @note - Includes executing the command and waiting for completion. + * @note - Does not support burst-mode. + */ +void EVE_cmd_flashprogram(uint32_t dest, uint32_t src, uint32_t num) +{ + eve_begin_cmd(CMD_FLASHPROGRAM); + spi_transmit_32(dest); + spi_transmit_32(src); + spi_transmit_32(num); + EVE_cs_clear(); + EVE_execute_cmd(); +} + +/** + * @brief Enable the font cache. + * @note - Meant to be called outside display-list building. + * @note - Includes executing the command and waiting for completion. + * @note - Does not support burst-mode. + */ +void EVE_cmd_fontcache(uint32_t font, uint32_t ptr, uint32_t num) +{ + eve_begin_cmd(CMD_FONTCACHE); + spi_transmit_32(font); + spi_transmit_32(ptr); + spi_transmit_32(num); + EVE_cs_clear(); + EVE_execute_cmd(); +} + +/** + * @brief Queries the capacity and utilization of the font cache. + * @note - Meant to be called outside display-list building. + * @note - Includes executing the command and waiting for completion. + * @note - Does not support burst-mode. + */ +void EVE_cmd_fontcachequery(uint32_t *p_total, uint32_t *p_used) +{ + uint16_t cmdoffset; + + eve_begin_cmd(CMD_FONTCACHEQUERY); + spi_transmit_32(0UL); + spi_transmit_32(0UL); + EVE_cs_clear(); + EVE_execute_cmd(); + + cmdoffset = EVE_memRead16(REG_CMD_WRITE); /* read the coprocessor write pointer */ + + if (p_total != NULL) + { + *p_total = EVE_memRead32(EVE_RAM_CMD + ((cmdoffset - 8UL) & 0xfffUL)); + } + if (p_used != NULL) + { + *p_used = EVE_memRead32(EVE_RAM_CMD + ((cmdoffset - 4UL) & 0xfffUL)); + } +} + +/** + * @brief Returns all the attributes of the bitmap made by the previous CMD_LOADIMAGE, CMD_PLAYVIDEO, CMD_VIDEOSTART or CMD_VIDEOSTARTF. + * @note - Meant to be called outside display-list building. + * @note - Includes executing the command and waiting for completion. + * @note - Does not support burst-mode. + */ +void EVE_cmd_getimage(uint32_t *p_source, uint32_t *p_fmt, uint32_t *p_width, uint32_t *p_height, uint32_t *p_palette) +{ + uint16_t cmdoffset; + + eve_begin_cmd(CMD_GETIMAGE); + spi_transmit_32(0UL); + spi_transmit_32(0UL); + spi_transmit_32(0UL); + spi_transmit_32(0UL); + spi_transmit_32(0UL); + EVE_cs_clear(); + EVE_execute_cmd(); + + cmdoffset = EVE_memRead16(REG_CMD_WRITE); /* read the coprocessor write pointer */ + + if (p_palette != NULL) + { + *p_palette = EVE_memRead32(EVE_RAM_CMD + ((cmdoffset - 4UL) & 0xfffUL)); + } + if (p_height != NULL) + { + *p_height = EVE_memRead32(EVE_RAM_CMD + ((cmdoffset - 8UL) & 0xfffUL)); + } + if (p_width != NULL) + { + *p_width = EVE_memRead32(EVE_RAM_CMD + ((cmdoffset - 12UL) & 0xfffUL)); + } + if (p_fmt != NULL) + { + *p_fmt = EVE_memRead32(EVE_RAM_CMD + ((cmdoffset - 16UL) & 0xfffUL)); + } + if (p_source != NULL) + { + *p_source = EVE_memRead32(EVE_RAM_CMD + ((cmdoffset - 20UL) & 0xfffUL)); + } +} + +/** + * @brief Undocumented command. + * @note - Meant to be called outside display-list building. + * @note - Includes executing the command and waiting for completion. + * @note - Does not support burst-mode. + */ +void EVE_cmd_linetime(uint32_t dest) +{ + eve_begin_cmd(CMD_LINETIME); + spi_transmit_32(dest); + EVE_cs_clear(); + EVE_execute_cmd(); +} + +/** + * @brief Starts the compilation of a command list into RAM_G. + * @note - Meant to be called outside display-list building. + * @note - Includes executing the command and waiting for completion. + * @note - Does not support burst-mode. + */ +void EVE_cmd_newlist(uint32_t adr) +{ + eve_begin_cmd(CMD_NEWLIST); + spi_transmit_32(adr); + EVE_cs_clear(); + EVE_execute_cmd(); +} + +/** + * @brief Sets REG_PCLK_FREQ to generate the closest possible frequency to the one requested. + * @return - the frequency achieved or zero if no frequency was found + * @note - When using this command, the flash BLOB is required. + * @note - Meant to be called outside display-list building. + * @note - Includes executing the command and waiting for completion. + * @note - Does not support burst-mode. + */ +uint32_t EVE_cmd_pclkfreq(uint32_t ftarget, int32_t rounding) +{ + uint16_t cmdoffset; + + eve_begin_cmd(CMD_PCLKFREQ); + spi_transmit_32(ftarget); + spi_transmit_32((uint32_t) rounding); + spi_transmit_32(0UL); + EVE_cs_clear(); + EVE_execute_cmd(); + cmdoffset = EVE_memRead16(REG_CMD_WRITE); /* read the coprocessor write pointer */ + cmdoffset -= 4U; + cmdoffset &= 0x0fffU; + return (EVE_memRead32(EVE_RAM_CMD + cmdoffset)); +} + +/** + * @brief Waits for a specified number of microseconds. + * @note - Meant to be called outside display-list building. + * @note - Includes executing the command and waiting for completion. + * @note - Does not support burst-mode. + */ +void EVE_cmd_wait(uint32_t usec) +{ + eve_begin_cmd(CMD_WAIT); + spi_transmit_32(usec); + EVE_cs_clear(); + EVE_execute_cmd(); +} + +#endif /* EVE_GEN > 3 */ + +/* BT815 / BT816 */ +#if EVE_GEN > 2 + +/** + * @brief Clears the graphics engine’s internal flash cache. + * @note - This function includes clearing out the display list. + * @note - Meant to be called outside display-list building. + * @note - Includes executing the command and waiting for completion. + * @note - Does not support burst-mode. + */ +void EVE_cmd_clearcache(void) +{ + EVE_cmd_dl(CMD_DLSTART); + EVE_cmd_dl(CMD_SWAP); + EVE_execute_cmd(); + + EVE_cmd_dl(CMD_DLSTART); + EVE_cmd_dl(CMD_SWAP); + EVE_execute_cmd(); + + EVE_cmd_dl(CMD_CLEARCACHE); + EVE_execute_cmd(); +} + +/** + * @brief Re-connect to the attached SPI flash storage. + * @note - Meant to be called outside display-list building. + * @note - Includes executing the command and waiting for completion. + * @note - Does not support burst-mode. + */ +void EVE_cmd_flashattach(void) +{ + eve_begin_cmd(CMD_FLASHATTACH); + EVE_cs_clear(); + EVE_execute_cmd(); +} + +/** + * @brief Dis-connect from the attached SPI flash storage. + * @note - Meant to be called outside display-list building. + * @note - Includes executing the command and waiting for completion. + * @note - Does not support burst-mode. + */ +void EVE_cmd_flashdetach(void) +{ + eve_begin_cmd(CMD_FLASHDETACH); + EVE_cs_clear(); + EVE_execute_cmd(); +} + +/** + * @brief Erases the attached SPI flash storage. + * @note - Meant to be called outside display-list building. + * @note - Includes executing the command and waiting for completion. + * @note - Does not support burst-mode. + */ +void EVE_cmd_flasherase(void) +{ + eve_begin_cmd(CMD_FLASHERASE); + EVE_cs_clear(); + EVE_execute_cmd(); +} + +/** + * @brief Drive the attached SPI flash storage in full-speed mode, if possible. + * @return - Zero on success, error code on failure + * @note - When using this command, the flash BLOB is required. + * @note - Meant to be called outside display-list building. + * @note - Includes executing the command and waiting for completion. + * @note - Does not support burst-mode. + */ +uint32_t EVE_cmd_flashfast(void) +{ + uint16_t cmdoffset; + + eve_begin_cmd(CMD_FLASHFAST); + spi_transmit_32(0UL); + EVE_cs_clear(); + EVE_execute_cmd(); + cmdoffset = EVE_memRead16(REG_CMD_WRITE); /* read the coprocessor write pointer */ + cmdoffset -= 4U; + cmdoffset &= 0x0fffU; + return (EVE_memRead32(EVE_RAM_CMD + cmdoffset)); +} + +/** + * @brief De-asserts the SPI CS signal of the attached SPI flash storage. + * @note - Only works when the attached SPI flash storage has been detached. + * @note - Meant to be called outside display-list building. + * @note - Includes executing the command and waiting for completion. + * @note - Does not support burst-mode. + */ +void EVE_cmd_flashspidesel(void) +{ + eve_begin_cmd(CMD_FLASHSPIDESEL); + EVE_cs_clear(); + EVE_execute_cmd(); +} + +/** + * @brief Copies "num" bytes from "src" in attached SPI flash storage to "dest" in RAM_G. + * @note - src must be 64-byte aligned, dest must be 4-byte aligned, num must be a multiple of 4 + * @note - EVE will not do anything if the alignment requirements are not met + * @note - The src pointer is relative to the flash so the first address is 0x000000 not 0x800000. + * @note - Meant to be called outside display-list building. + * @note - Includes executing the command and waiting for completion. + * @note - Does not support burst-mode. + */ +void EVE_cmd_flashread(uint32_t dest, uint32_t src, uint32_t num) +{ + eve_begin_cmd(CMD_FLASHREAD); + spi_transmit_32(dest); + spi_transmit_32(src); + spi_transmit_32(num); + EVE_cs_clear(); + EVE_execute_cmd(); +} + +/** + * @brief Set the source address for flash data loaded by the CMD_LOADIMAGE, CMD_PLAYVIDEO, CMD_VIDEOSTARTF and CMD_INFLATE2 commands with the OPT_FLASH option. + * @note - Address must be 64-byte aligned. + * @note - EVE will not do anything if the alignment requirements are not met. + * @note - The pointer is relative to the flash, so the first address is 0x000000 not 0x800000. + * @note - Meant to be called outside display-list building. + * @note - Includes executing the command and waiting for completion. + * @note - Does not support burst-mode. + */ +void EVE_cmd_flashsource(uint32_t ptr) +{ + eve_begin_cmd(CMD_FLASHSOURCE); + spi_transmit_32(ptr); + EVE_cs_clear(); + EVE_execute_cmd(); +} + +/** + * @brief Receives bytes from the flash SPI interface and writes them to main memory. + * @note - Only works when the attached SPI flash storage has been detached. + * @note - Meant to be called outside display-list building. + * @note - Includes executing the command and waiting for completion. + * @note - Does not support burst-mode. + */ +void EVE_cmd_flashspirx(uint32_t dest, uint32_t num) +{ + eve_begin_cmd(CMD_FLASHSPIRX); + spi_transmit_32(dest); + spi_transmit_32(num); + EVE_cs_clear(); + EVE_execute_cmd(); +} + +/** + * @brief Transmits bytes over the flash SPI interface. + * @note - Only works when the attached SPI flash storage has been detached. + * @note - Meant to be called outside display-list building. + * @note - Includes executing the command and waiting for completion. + * @note - Does not support burst-mode. + */ +void EVE_cmd_flashspitx(uint32_t num, const uint8_t *p_data) +{ + eve_begin_cmd(CMD_FLASHSPITX); + spi_transmit_32(num); + EVE_cs_clear(); + block_transfer(p_data, num); +} + +/** + * @brief Write "num" bytes from src in RAM_G to the attached SPI flash storage at address dest. + * @note - dest must be 4096-byte aligned, src must be 4-byte aligned, num must be a multiple of 4096 + * @note - EVE will not do anything if the alignment requirements are not met. + * @note - The address ptr is relative to the flash so the first address is 0x000000 not 0x800000. + * @note - Meant to be called outside display-list building. + * @note - Includes executing the command and waiting for completion. + * @note - Does not support burst-mode. + */ +void EVE_cmd_flashupdate(uint32_t dest, uint32_t src, uint32_t num) +{ + eve_begin_cmd(CMD_FLASHUPDATE); + spi_transmit_32(dest); + spi_transmit_32(src); + spi_transmit_32(num); + EVE_cs_clear(); + EVE_execute_cmd(); +} + +/** + * @brief Write "num" bytes to the attached SPI flash storage at address dest. + * @note - dest must be 256-byte aligned, num must be a multiple of 256 + * @note - EVE will not do anything if the alignment requirements are not met. + * @note - The address ptr is relative to the flash so the first address is 0x000000 not 0x800000. + * @note - Meant to be called outside display-list building. + * @note - Includes executing the command and waiting for completion. + * @note - Does not support burst-mode. + */ +void EVE_cmd_flashwrite(uint32_t ptr, uint32_t num, const uint8_t *p_data) +{ + eve_begin_cmd(CMD_FLASHWRITE); + spi_transmit_32(ptr); + spi_transmit_32(num); + EVE_cs_clear(); + if (p_data != NULL) + { + block_transfer(p_data, num); + } +} + +/** + * @brief Decompress data into RAM_G. + * @note - The data must be correct and complete. + * @note - Meant to be called outside display-list building. + * @note - Includes executing the command and waiting for completion. + * @note - Does not support burst-mode. + */ +void EVE_cmd_inflate2(uint32_t ptr, uint32_t options, const uint8_t *p_data, uint32_t len) +{ + eve_begin_cmd(CMD_INFLATE2); + spi_transmit_32(ptr); + spi_transmit_32(options); + EVE_cs_clear(); + + if (0UL == options) /* direct data, not by Media-FIFO or Flash */ + { + if (p_data != NULL) + { + block_transfer(p_data, len); + } + } +} + +#endif /* EVE_GEN > 2 */ + +/** + * @brief Returns the source address and size of the bitmap loaded by the previous CMD_LOADIMAGE. + * @note - Meant to be called outside display-list building. + * @note - Includes executing the command and waiting for completion. + * @note - Does not support burst-mode. + */ +void EVE_cmd_getprops(uint32_t *p_pointer, uint32_t *p_width, uint32_t *p_height) +{ + uint16_t cmdoffset; + + eve_begin_cmd(CMD_GETPROPS); + spi_transmit_32(0UL); + spi_transmit_32(0UL); + spi_transmit_32(0UL); + EVE_cs_clear(); + EVE_execute_cmd(); + cmdoffset = EVE_memRead16(REG_CMD_WRITE); /* read the coprocessor write pointer */ + + if (p_pointer != NULL) + { + *p_pointer = EVE_memRead32(EVE_RAM_CMD + ((cmdoffset - 12UL) & 0xfffUL)); + } + if (p_width != NULL) + { + *p_width = EVE_memRead32(EVE_RAM_CMD + ((cmdoffset - 8UL) & 0xfffUL)); + } + if (p_height != NULL) + { + *p_height = EVE_memRead32(EVE_RAM_CMD + ((cmdoffset - 4UL) & 0xfffUL)); + } +} + +/** + * @brief Returns the next address after a CMD_INFLATE and other commands. + * @note - Meant to be called outside display-list building. + * @note - Includes executing the command and waiting for completion. + * @note - Does not support burst-mode. + */ +uint32_t EVE_cmd_getptr(void) +{ + uint16_t cmdoffset; + + eve_begin_cmd(CMD_GETPTR); + spi_transmit_32(0UL); + EVE_cs_clear(); + EVE_execute_cmd(); + cmdoffset = EVE_memRead16(REG_CMD_WRITE); /* read the coprocessor write pointer */ + cmdoffset -= 4U; + cmdoffset &= 0x0fffU; + return (EVE_memRead32(EVE_RAM_CMD + cmdoffset)); +} + +/** + * @brief Decompress data into RAM_G. + * @note - The data must be correct and complete. + * @note - Meant to be called outside display-list building. + * @note - Includes executing the command and waiting for completion. + * @note - Does not support burst-mode. + */ +void EVE_cmd_inflate(uint32_t ptr, const uint8_t *p_data, uint32_t len) +{ + eve_begin_cmd(CMD_INFLATE); + spi_transmit_32(ptr); + EVE_cs_clear(); + if (p_data != NULL) + { + block_transfer(p_data, len); + } +} + +/** + * @brief Trigger interrupt INT_CMDFLAG. + * @note - Meant to be called outside display-list building. + * @note - Includes executing the command and waiting for completion. + * @note - Does not support burst-mode. + */ +void EVE_cmd_interrupt(uint32_t msec) +{ + eve_begin_cmd(CMD_INTERRUPT); + spi_transmit_32(msec); + EVE_cs_clear(); + EVE_execute_cmd(); +} + +/** + * @brief Loads and decodes a JPEG/PNG image into RAM_G. + * @note - Decoding PNG images takes significantly more time than decoding JPEG images. + * @note - In doubt use the EVE Asset Builder to check if PNG/JPEG files are compatible. + * @note - If the image is in PNG format, the top 42kiB of RAM_G will be overwritten. + * @note - Meant to be called outside display-list building. + * @note - Includes executing the command and waiting for completion. + * @note - Does not support burst-mode. + */ +void EVE_cmd_loadimage(uint32_t ptr, uint32_t options, const uint8_t *p_data, uint32_t len) +{ + eve_begin_cmd(CMD_LOADIMAGE); + spi_transmit_32(ptr); + spi_transmit_32(options); + EVE_cs_clear(); + +#if EVE_GEN > 2 + if ((0UL == (options & EVE_OPT_MEDIAFIFO)) && + (0UL == (options & EVE_OPT_FLASH))) /* direct data, neither by Media-FIFO or from Flash */ +#else + if (0UL == (options & EVE_OPT_MEDIAFIFO)) /* direct data, not by Media-FIFO */ +#endif + { + if (p_data != NULL) + { + block_transfer(p_data, len); + } + } +} + +/** + * @brief Set up a streaming media FIFO in RAM_G. + * @note - Meant to be called outside display-list building. + * @note - Includes executing the command and waiting for completion. + * @note - Does not support burst-mode. + */ +void EVE_cmd_mediafifo(uint32_t ptr, uint32_t size) +{ + eve_begin_cmd(CMD_MEDIAFIFO); + spi_transmit_32(ptr); + spi_transmit_32(size); + EVE_cs_clear(); + EVE_execute_cmd(); +} + +/** + * @brief Copy a block of RAM_G. + * @note - Meant to be called outside display-list building. + * @note - Includes executing the command and waiting for completion. + * @note - Does not support burst-mode. + */ +void EVE_cmd_memcpy(uint32_t dest, uint32_t src, uint32_t num) +{ + eve_begin_cmd(CMD_MEMCPY); + spi_transmit_32(dest); + spi_transmit_32(src); + spi_transmit_32(num); + EVE_cs_clear(); + EVE_execute_cmd(); +} + +/** + * @brief Compute a CRC-32 for RAM_G. + * @note - Meant to be called outside display-list building. + * @note - Includes executing the command and waiting for completion. + * @note - Does not support burst-mode. + */ +uint32_t EVE_cmd_memcrc(uint32_t ptr, uint32_t num) +{ + uint16_t cmdoffset; + + eve_begin_cmd(CMD_MEMCRC); + spi_transmit_32(ptr); + spi_transmit_32(num); + spi_transmit_32(0UL); + EVE_cs_clear(); + EVE_execute_cmd(); + cmdoffset = EVE_memRead16(REG_CMD_WRITE); /* read the coprocessor write pointer */ + cmdoffset -= 4U; + cmdoffset &= 0x0fffU; + return (EVE_memRead32(EVE_RAM_CMD + cmdoffset)); +} + +/** + * @brief Fill RAM_G with a byte value. + * @note - Meant to be called outside display-list building. + * @note - Includes executing the command and waiting for completion. + * @note - Does not support burst-mode. + */ +void EVE_cmd_memset(uint32_t ptr, uint8_t value, uint32_t num) +{ + eve_begin_cmd(CMD_MEMSET); + spi_transmit_32(ptr); + spi_transmit_32((uint32_t)value); + spi_transmit_32(num); + EVE_cs_clear(); + EVE_execute_cmd(); +} + +/** + * @brief Write bytes into RAM_G using the coprocessor. + * @note - Commented out, just use one of the EVE_memWrite* helper functions to directly write to EVEs memory. + * @note - Meant to be called outside display-list building. + * @note - Includes executing the command and waiting for completion. + * @note - Does not support burst-mode. + */ +/* +void EVE_cmd_memwrite(uint32_t dest, uint32_t num, const uint8_t *p_data) +{ + eve_begin_cmd(CMD_MEMWRITE); + spi_transmit_32(dest); + spi_transmit_32(num); + + num = (num + 3U) & (~3U); + + for (uint32_t count = 0U; count 2 + if ((0UL == (options & EVE_OPT_MEDIAFIFO)) && + (0UL == (options & EVE_OPT_FLASH))) /* direct data, neither by Media-FIFO or from Flash */ +#else + if (0UL == (options & EVE_OPT_MEDIAFIFO)) /* direct data, not by Media-FIFO */ +#endif + { + if (p_data != NULL) + { + block_transfer(p_data, len); + } + } +} + +/** + * @brief Rotate the screen and set up transform matrix accordingly. + * @note - Meant to be called outside display-list building. + * @note - Includes executing the command and waiting for completion. + * @note - Does not support burst-mode. + */ +void EVE_cmd_setrotate(uint32_t rotation) +{ + eve_begin_cmd(CMD_SETROTATE); + spi_transmit_32(rotation); + EVE_cs_clear(); + EVE_execute_cmd(); +} + +/** + * @brief Take a snapshot of the current screen. + * @note - Meant to be called outside display-list building. + * @note - Includes executing the command and waiting for completion. + * @note - Does not support burst-mode. + */ +void EVE_cmd_snapshot(uint32_t ptr) +{ + eve_begin_cmd(CMD_SNAPSHOT); + spi_transmit_32(ptr); + EVE_cs_clear(); + EVE_execute_cmd(); +} + +/** + * @brief Take a snapshot of part of the current screen with format option. + * @note - Meant to be called outside display-list building. + * @note - Includes executing the command and waiting for completion. + * @note - Does not support burst-mode. + */ +void EVE_cmd_snapshot2(uint32_t fmt, uint32_t ptr, int16_t xc0, int16_t yc0, uint16_t wid, uint16_t hgt) +{ + eve_begin_cmd(CMD_SNAPSHOT2); + spi_transmit_32(fmt); + spi_transmit_32(ptr); + + spi_transmit((uint8_t) ((uint16_t) xc0)); + spi_transmit((uint8_t) (((uint16_t) xc0) >> 8U)); + spi_transmit((uint8_t) ((uint16_t) yc0)); + spi_transmit((uint8_t) (((uint16_t) yc0) >> 8U)); + + spi_transmit((uint8_t) (wid)); + spi_transmit((uint8_t) (wid >> 8U)); + spi_transmit((uint8_t) (hgt)); + spi_transmit((uint8_t) (hgt >> 8U)); + + EVE_cs_clear(); + EVE_execute_cmd(); +} + +/** + * @brief Track touches for a graphics object. + * @note - Meant to be called outside display-list building. + * @note - Includes executing the command and waiting for completion. + * @note - Does not support burst-mode. + */ +void EVE_cmd_track(int16_t xc0, int16_t yc0, uint16_t wid, uint16_t hgt, uint16_t tag) +{ + eve_begin_cmd(CMD_TRACK); + + spi_transmit((uint8_t) ((uint16_t) xc0)); + spi_transmit((uint8_t) (((uint16_t) xc0) >> 8U)); + spi_transmit((uint8_t) ((uint16_t) yc0)); + spi_transmit((uint8_t) (((uint16_t) yc0) >> 8U)); + + spi_transmit((uint8_t) (wid)); + spi_transmit((uint8_t) (wid >> 8U)); + spi_transmit((uint8_t) (hgt)); + spi_transmit((uint8_t) (hgt >> 8U)); + + spi_transmit((uint8_t) (tag)); + spi_transmit((uint8_t) (tag >> 8U)); + spi_transmit(0U); + spi_transmit(0U); + + EVE_cs_clear(); + EVE_execute_cmd(); +} + +/** + * @brief Load the next frame of a video. + * @note - Meant to be called outside display-list building. + * @note - Includes executing the command and waiting for completion. + * @note - Does not support burst-mode. + */ +void EVE_cmd_videoframe(uint32_t dest, uint32_t result_ptr) +{ + eve_begin_cmd(CMD_VIDEOFRAME); + spi_transmit_32(dest); + spi_transmit_32(result_ptr); + EVE_cs_clear(); + EVE_execute_cmd(); +} + +/* ################################################################## + patching and initialization +#################################################################### */ + +#if EVE_GEN > 2 + +/** + * @brief EVE flash initialization for BT81x, switches the FLASH attached to a BT81x to full-speed mode + * @return Returns E_OK in case of success, EVE_FAIL_FLASH_STATUS_INIT if the status remains init, + * EVE_FAIL_FLASH_STATUS_DETACHED if no flash chip was found, a number of different values for failures with + * cmd_flashfast and E_NOT_OK if a not supported status is returned in REG_FLASH_STATUS. + */ +uint8_t EVE_init_flash(void) +{ + uint8_t timeout = 0U; + uint8_t status; + uint8_t ret_val = E_NOT_OK; + + status = EVE_memRead8(REG_FLASH_STATUS); /* should be 0x02 - FLASH_STATUS_BASIC, power-up is done and the attached flash is detected */ + + /* we are somehow still in init, give it a litte more time, this should never happen */ + while (EVE_FLASH_STATUS_INIT == status) + { + status = EVE_memRead8(REG_FLASH_STATUS); + DELAY_MS(1U); + timeout++; + if (timeout > 100U) /* 100ms and still in init, lets call quits now and exit with an error */ + { + ret_val = EVE_FAIL_FLASH_STATUS_INIT; + break; + } + } + + /* no flash was found during init, no flash present or the detection failed, give it another try */ + if (EVE_FLASH_STATUS_DETACHED == status) + { + EVE_cmd_dl(CMD_FLASHATTACH); + EVE_execute_cmd(); + status = EVE_memRead8(REG_FLASH_STATUS); + if (status != 2U) /* still not in FLASH_STATUS_BASIC, time to give up */ + { + ret_val = EVE_FAIL_FLASH_STATUS_DETACHED; + } + } + + /* flash detected and ready for action, move it up to FLASH_STATUS_FULL */ + if (EVE_FLASH_STATUS_BASIC == status) + { + uint32_t result; + + result = EVE_cmd_flashfast(); + + switch (result) + { + case 0x0000UL: + ret_val = E_OK; + break; + + case 0xE001UL: + ret_val = EVE_FAIL_FLASHFAST_NOT_SUPPORTED; + break; + + case 0xE002UL: + ret_val = EVE_FAIL_FLASHFAST_NO_HEADER_DETECTED; + break; + + case 0xE003UL: + ret_val = EVE_FAIL_FLASHFAST_SECTOR0_FAILED; + break; + + case 0xE004UL: + ret_val = EVE_FAIL_FLASHFAST_BLOB_MISMATCH; + break; + + case 0xE005UL: + ret_val = EVE_FAIL_FLASHFAST_SPEED_TEST; + break; + + default: /* we have an unknown error, so just return failure */ + ret_val = E_NOT_OK; + break; + } + } + + if (EVE_FLASH_STATUS_FULL == status) /* we are already there, why has this function been called? */ + { + ret_val = E_OK; + } + + return (ret_val); +} + +#endif /* EVE_GEN > 2 */ + +#if EVE_GEN < 3 +#if defined (__AVR__) +#include +#else +#define PROGMEM +#endif +#endif + +static void use_gt911(void); + +static void use_gt911(void) +{ +#if EVE_GEN > 2 + EVE_memWrite16(REG_TOUCH_CONFIG, 0x05d0U); /* switch to Goodix touch controller */ +#else + +/* FT811 / FT813 binary-blob from FTDIs AN_336 to patch the touch-engine for Goodix GT911 / GT9271 touch controllers */ +const uint8_t eve_gt911_data[1184U] PROGMEM = +{ + 26, 255, 255, 255, 32, 32, 48, 0, 4, 0, 0, 0, 2, 0, 0, 0, 34, 255, 255, 255, 0, 176, 48, + 0, 120, 218, 237, 84, 221, 111, 84, 69, 20, 63, 51, 179, 93, 160, 148, 101, 111, 76, 5, 44, 141, 123, + 111, 161, 11, 219, 154, 16, 9, 16, 17, 229, 156, 75, 26, 11, 13, 21, 227, 3, 16, 252, 184, 179, 45, + 219, 143, 45, 41, 125, 144, 72, 67, 100, 150, 71, 189, 113, 18, 36, 17, 165, 100, 165, 198, 16, 32, 17, + 149, 196, 240, 128, 161, 16, 164, 38, 54, 240, 0, 209, 72, 130, 15, 38, 125, 48, 66, 82, 30, 76, 19, + 31, 172, 103, 46, 139, 24, 255, 4, 227, 157, 204, 156, 51, 115, 102, 206, 231, 239, 220, 5, 170, 94, 129, + 137, 75, 194, 216, 98, 94, 103, 117, 115, 121, 76, 131, 177, 125, 89, 125, 82, 123, 60, 243, 58, 142, 242, + 204, 185, 243, 188, 118, 156, 227, 155, 203, 238, 238, 195, 251, 205, 229, 71, 92, 28, 169, 190, 184, 84, 143, + 113, 137, 53, 244, 103, 181, 237, 87, 253, 113, 137, 233, 48, 12, 198, 165, 181, 104, 139, 25, 84, 253, 155, + 114, 74, 191, 0, 54, 138, 163, 12, 62, 131, 207, 129, 23, 217, 34, 91, 31, 128, 65, 246, 163, 175, 213, + 8, 147, 213, 107, 35, 203, 94, 108, 3, 111, 40, 171, 83, 24, 15, 165, 177, 222, 116, 97, 23, 188, 140, + 206, 150, 42, 102, 181, 87, 78, 86, 182, 170, 134, 215, 241, 121, 26, 243, 252, 2, 76, 115, 217, 139, 222, + 206, 173, 136, 132, 81, 61, 35, 185, 39, 113, 23, 46, 199, 76, 178, 54, 151, 183, 224, 0, 40, 189, 28, + 149, 182, 58, 131, 79, 152, 30, 76, 34, 98, 234, 162, 216, 133, 141, 102, 39, 170, 40, 192, 101, 53, 201, + 146, 191, 37, 77, 44, 177, 209, 74, 211, 5, 206, 187, 5, 6, 216, 47, 53, 96, 123, 22, 50, 103, 251, + 192, 84, 17, 74, 227, 185, 56, 106, 51, 91, 161, 96, 182, 163, 48, 171, 141, 139, 65, 152, 66, 66, 11, + 102, 43, 158, 75, 36, 80, 147, 184, 147, 139, 112, 17, 235, 216, 103, 111, 239, 245, 92, 10, 175, 194, 40, + 44, 58, 125, 5, 59, 112, 50, 103, 245, 4, 78, 192, 5, 156, 194, 51, 60, 191, 134, 75, 110, 173, 237, + 46, 192, 121, 156, 192, 115, 184, 218, 120, 67, 63, 115, 46, 11, 102, 10, 97, 232, 50, 235, 114, 182, 148, + 118, 178, 41, 188, 12, 135, 77, 202, 124, 12, 96, 238, 35, 161, 234, 189, 129, 23, 249, 212, 139, 230, 25, + 53, 48, 205, 52, 93, 163, 117, 53, 154, 170, 81, 85, 163, 178, 70, 69, 66, 167, 241, 14, 46, 241, 1, + 226, 136, 152, 179, 197, 59, 184, 148, 254, 49, 132, 48, 15, 176, 137, 192, 76, 131, 196, 105, 104, 162, 86, + 81, 160, 165, 255, 26, 173, 162, 137, 86, 145, 210, 183, 192, 55, 175, 194, 211, 60, 91, 120, 230, 184, 174, + 27, 41, 131, 155, 40, 224, 29, 87, 179, 232, 16, 55, 55, 7, 165, 147, 81, 23, 165, 49, 101, 54, 224, + 75, 180, 81, 108, 18, 29, 226, 69, 225, 110, 175, 224, 42, 212, 25, 47, 130, 193, 110, 234, 192, 215, 252, + 56, 74, 162, 24, 46, 251, 174, 54, 106, 68, 245, 14, 9, 155, 160, 22, 120, 207, 104, 240, 29, 90, 178, + 140, 28, 24, 220, 47, 166, 112, 61, 251, 208, 192, 111, 56, 239, 238, 93, 255, 251, 62, 99, 32, 193, 75, + 61, 190, 235, 123, 229, 110, 218, 194, 85, 79, 225, 59, 98, 20, 238, 227, 235, 220, 11, 221, 149, 25, 180, + 116, 194, 159, 111, 96, 192, 24, 213, 59, 139, 179, 156, 215, 69, 230, 19, 24, 35, 135, 117, 206, 171, 206, + 162, 67, 129, 234, 61, 235, 11, 104, 103, 84, 64, 223, 167, 254, 40, 163, 101, 92, 84, 43, 150, 46, 249, + 219, 205, 7, 116, 11, 91, 104, 61, 57, 75, 223, 8, 48, 25, 28, 119, 252, 222, 113, 49, 86, 249, 74, + 180, 211, 156, 181, 61, 215, 168, 157, 7, 251, 199, 150, 242, 250, 91, 58, 132, 94, 121, 7, 53, 151, 139, + 98, 6, 165, 153, 69, 214, 32, 110, 211, 100, 101, 31, 89, 45, 81, 98, 23, 205, 205, 197, 209, 109, 186, + 198, 35, 141, 191, 249, 25, 60, 132, 223, 153, 251, 98, 20, 239, 146, 139, 20, 217, 250, 41, 250, 137, 58, + 177, 90, 57, 79, 51, 108, 233, 20, 253, 194, 187, 49, 222, 205, 114, 141, 96, 48, 175, 219, 107, 54, 111, + 138, 22, 154, 103, 108, 79, 58, 252, 179, 178, 79, 164, 195, 2, 153, 36, 39, 170, 199, 201, 167, 197, 85, + 106, 8, 59, 177, 81, 46, 56, 2, 230, 75, 114, 17, 55, 112, 188, 65, 208, 137, 77, 114, 10, 115, 55, + 58, 208, 197, 173, 122, 87, 6, 140, 110, 42, 208, 124, 163, 70, 108, 241, 104, 18, 245, 98, 214, 187, 134, + 53, 42, 221, 22, 182, 133, 211, 116, 148, 177, 194, 209, 192, 85, 90, 199, 58, 55, 203, 2, 229, 19, 137, + 187, 161, 228, 154, 112, 203, 145, 125, 244, 188, 220, 118, 228, 41, 201, 181, 41, 195, 144, 215, 183, 51, 80, + 250, 21, 217, 16, 217, 200, 235, 109, 227, 188, 122, 218, 142, 60, 170, 224, 112, 240, 184, 130, 229, 224, 113, + 5, 223, 148, 163, 80, 165, 183, 130, 187, 132, 116, 64, 238, 161, 85, 220, 115, 139, 205, 98, 227, 244, 29, + 102, 125, 7, 37, 243, 123, 223, 11, 26, 92, 63, 243, 116, 61, 191, 138, 123, 244, 160, 84, 186, 74, 31, + 5, 174, 247, 119, 135, 199, 248, 253, 135, 242, 97, 102, 145, 190, 144, 14, 85, 238, 221, 231, 193, 158, 48, + 205, 25, 120, 248, 15, 220, 29, 158, 9, 70, 185, 30, 103, 229, 33, 254, 23, 237, 160, 172, 62, 193, 90, + 222, 224, 232, 14, 200, 56, 90, 104, 142, 227, 120, 110, 6, 21, 211, 203, 65, 150, 99, 151, 220, 247, 87, + 164, 50, 159, 49, 239, 234, 58, 142, 0, 109, 108, 123, 18, 79, 227, 36, 100, 248, 222, 205, 96, 127, 120, + 26, 171, 228, 69, 63, 36, 17, 252, 200, 17, 116, 242, 187, 227, 88, 143, 247, 2, 75, 191, 6, 130, 59, + 188, 11, 55, 240, 31, 243, 122, 152, 226, 183, 207, 154, 73, 188, 39, 219, 43, 105, 222, 87, 41, 143, 141, + 140, 175, 73, 112, 184, 252, 61, 184, 16, 90, 250, 35, 168, 82, 119, 176, 57, 116, 94, 200, 150, 22, 190, + 179, 44, 104, 12, 235, 84, 149, 102, 252, 89, 154, 193, 99, 228, 106, 242, 125, 248, 64, 194, 255, 223, 127, + 242, 83, 11, 255, 2, 70, 214, 226, 128, 0, 0 +}; + + EVE_cs_set(); + spi_transmit((uint8_t) 0xB0U); /* high-byte of REG_CMDB_WRITE + MEM_WRITE */ + spi_transmit((uint8_t) 0x25U); /* middle-byte of REG_CMDB_WRITE */ + spi_transmit((uint8_t) 0x78U); /* low-byte of REG_CMDB_WRITE */ + private_block_write(eve_gt911_data, sizeof(eve_gt911_data)); + EVE_cs_clear(); + EVE_execute_cmd(); + + EVE_memWrite8(REG_TOUCH_OVERSAMPLE, 0x0fU); /* setup oversample to 0x0f as "hidden" in binary-blob for AN_336 */ + EVE_memWrite16(REG_TOUCH_CONFIG, 0x05D0U); /* write magic cookie as requested by AN_336 */ + + /* specific to the EVE2 modules from Matrix-Orbital we have to use GPIO3 to reset GT911 */ + EVE_memWrite16(REG_GPIOX_DIR, 0x8008U); /* Reset-Value is 0x8000, adding 0x08 sets GPIO3 to output, default-value + for REG_GPIOX is 0x8000 -> Low output on GPIO3 */ + DELAY_MS(1U); /* wait more than 100us */ + EVE_memWrite8(REG_CPURESET, 0U); /* clear all resets */ + DELAY_MS(110U); /* wait more than 55ms - does not work with multitouch, for some reason a minimum delay of 108ms is + required */ + EVE_memWrite16(REG_GPIOX_DIR, 0x8000U); /* setting GPIO3 back to input */ +#endif +} + +/** + * @brief Waits for either reading REG_ID with a value of 0x7c, indicating that + * an EVE chip is present and ready to communicate, or untill a timeout of 400ms has passed. + * @return Returns E_OK in case of success, EVE_FAIL_REGID_TIMEOUT if the + * value of 0x7c could not be read. + */ +static uint8_t wait_regid(void) +{ + uint8_t ret = EVE_FAIL_REGID_TIMEOUT; + uint8_t regid = 0U; + + for (uint16_t timeout = 0U; timeout < 400U; timeout++) + { + DELAY_MS(1U); + + regid = EVE_memRead8(REG_ID); + if (0x7cU == regid) /* EVE is up and running */ + { + ret = E_OK; + break; + } + } + + return (ret); +} + +/** + * @brief Waits for either REG_CPURESET to indicate that the audio, touch and + * coprocessor units finished their respective reset cycles, + * or untill a timeout of 50ms has passed. + * @return Returns E_OK in case of success, EVE_FAIL_RESET_TIMEOUT if either the + * audio, touch or coprocessor unit indicate a fault by not returning from reset. + */ +static uint8_t wait_reset(void) +{ + uint8_t ret = EVE_FAIL_RESET_TIMEOUT; + uint8_t reset = 0U; + + for (uint16_t timeout = 0U; timeout < 50U; timeout++) + { + DELAY_MS(1U); + + reset = EVE_memRead8(REG_CPURESET) & 7U; + if (0U == reset) /* EVE reports all units running */ + { + ret = E_OK; + break; + } + } + + return (ret); +} + +/** + * @brief Writes all parameters defined for the display selected in EVE_config.h. + * to the corresponding registers. + * It is used by EVE_init() and can be used to refresh the register values if needed. + */ +void EVE_write_display_parameters(void) +{ + /* Initialize Display */ + EVE_memWrite16(REG_HSIZE, EVE_HSIZE); /* active display width */ + EVE_memWrite16(REG_HCYCLE, EVE_HCYCLE); /* total number of clocks per line, incl front/back porch */ + EVE_memWrite16(REG_HOFFSET, EVE_HOFFSET); /* start of active line */ + EVE_memWrite16(REG_HSYNC0, EVE_HSYNC0); /* start of horizontal sync pulse */ + EVE_memWrite16(REG_HSYNC1, EVE_HSYNC1); /* end of horizontal sync pulse */ + EVE_memWrite16(REG_VSIZE, EVE_VSIZE); /* active display height */ + EVE_memWrite16(REG_VCYCLE, EVE_VCYCLE); /* total number of lines per screen, including pre/post */ + EVE_memWrite16(REG_VOFFSET, EVE_VOFFSET); /* start of active screen */ + EVE_memWrite16(REG_VSYNC0, EVE_VSYNC0); /* start of vertical sync pulse */ + EVE_memWrite16(REG_VSYNC1, EVE_VSYNC1); /* end of vertical sync pulse */ + EVE_memWrite8(REG_SWIZZLE, EVE_SWIZZLE); /* FT8xx output to LCD - pin order */ + EVE_memWrite8(REG_PCLK_POL, EVE_PCLKPOL); /* LCD data is clocked in on this PCLK edge */ + EVE_memWrite8(REG_CSPREAD, EVE_CSPREAD); /* helps with noise, when set to 1 fewer signals are changed simultaneously, reset-default: 1 */ + + /* configure Touch */ + EVE_memWrite8(REG_TOUCH_MODE, EVE_TMODE_CONTINUOUS); /* enable touch */ +#if defined (EVE_TOUCH_RZTHRESH) + EVE_memWrite16(REG_TOUCH_RZTHRESH, EVE_TOUCH_RZTHRESH); /* configure the sensitivity of resistive touch */ +#else + EVE_memWrite16(REG_TOUCH_RZTHRESH, 1200U); /* set a reasonable default value if none is given */ +#endif + +#if defined (EVE_ROTATE) + EVE_memWrite8(REG_ROTATE, EVE_ROTATE & 7U); /* bit0 = invert, bit2 = portrait, bit3 = mirrored */ + /* reset default value is 0x0 - not inverted, landscape, not mirrored */ +#endif +} + +static void enable_pixel_clock(void) +{ + EVE_memWrite8(REG_GPIO, 0x80U); /* enable the DISP signal to the LCD panel, it is set to output in REG_GPIO_DIR by default */ + +#if (EVE_GEN > 3) && (defined EVE_PCLK_FREQ) + EVE_memWrite16(REG_PCLK_FREQ, (uint16_t) EVE_PCLK_FREQ); + +#if defined (EVE_SET_REG_PCLK_2X) + EVE_memWrite8(REG_PCLK_2X, 1U); +#endif + + EVE_memWrite8(REG_PCLK, 1U); /* enable extsync mode */ +#else + EVE_memWrite8(REG_PCLK, EVE_PCLK); /* start clocking data to the LCD panel */ +#endif +} + +/** + * @brief Initializes EVE according to the selected configuration from EVE_config.h. + * @return E_OK in case of success + * @note - Has to be executed with the SPI setup to 11 MHz or less as required by FT8xx / BT8xx! + * @note - Additional settings can be made through extra macros. + * @note - EVE_TOUCH_RZTHRESH - configure the sensitivity of resistive touch, defaults to 1200. + * @note - EVE_ROTATE - set the screen rotation: bit0 = invert, bit1 = portrait, bit2 = mirrored. + * @note - needs a set of calibration values for the selected rotation since this rotates before calibration! + * @note - EVE_BACKLIGHT_FREQ - configure the backlight frequency, default is not writing it which results in 250Hz. + * @note - EVE_BACKLIGHT_PWM - configure the backlight pwm, defaults to 0x20 / 25%. + */ +uint8_t EVE_init(void) +{ + uint8_t ret; + + EVE_pdn_set(); + DELAY_MS(6U); /* minimum time for power-down is 5ms */ + EVE_pdn_clear(); + DELAY_MS(21U); /* minimum time to allow from rising PD_N to first access is 20ms */ + +#if defined (EVE_GD3X) + EVE_cmdWrite(EVE_RST_PULSE,0U); /* reset, only required for warm-start if PowerDown line is not used */ +#endif + + if(EVE_HAS_CRYSTAL) { + EVE_cmdWrite(EVE_CLKEXT, 0U); /* setup EVE for external clock */ + } + else { + EVE_cmdWrite(EVE_CLKINT, 0U); /* setup EVE for internal clock */ + } + +#if EVE_GEN > 2 + EVE_cmdWrite(EVE_CLKSEL, 0x46U); /* set clock to 72 MHz */ +#endif + + EVE_cmdWrite(EVE_ACTIVE, 0U); /* start EVE */ + DELAY_MS(40U); /* give EVE a moment of silence to power up */ + + ret = wait_regid(); + if (E_OK == ret) + { + ret = wait_reset(); + if (E_OK == ret) + { +/* tell EVE that we changed the frequency from default to 72MHz for BT8xx */ +#if EVE_GEN > 2 + EVE_memWrite32(REG_FREQUENCY, 72000000UL); +#endif + +/* we have a display with a Goodix GT911 / GT9271 touch-controller on it, + so we patch our FT811 or FT813 according to AN_336 or setup a BT815 / BT817 accordingly */ + if(EVE_HAS_GT911) { + use_gt911(); + } + +#if defined (EVE_ADAM101) + EVE_memWrite8(REG_PWM_DUTY, 0x80U); /* turn off backlight for Glyn ADAM101 module, it uses inverted values */ +#else + EVE_memWrite8(REG_PWM_DUTY, 0U); /* turn off backlight for any other module */ +#endif + EVE_write_display_parameters(); + + /* disable Audio for now */ + EVE_memWrite8(REG_VOL_PB, 0U); /* turn recorded audio volume down, reset-default is 0xff */ + EVE_memWrite8(REG_VOL_SOUND, 0U); /* turn synthesizer volume down, reset-default is 0xff */ + EVE_memWrite16(REG_SOUND, EVE_MUTE); /* set synthesizer to mute */ + + /* write a basic display-list to get things started */ + EVE_memWrite32(EVE_RAM_DL, DL_CLEAR_COLOR_RGB); + EVE_memWrite32(EVE_RAM_DL + 4U, (DL_CLEAR | CLR_COL | CLR_STN | CLR_TAG)); + EVE_memWrite32(EVE_RAM_DL + 8U, DL_DISPLAY); /* end of display list */ + EVE_memWrite32(REG_DLSWAP, EVE_DLSWAP_FRAME); + /* nothing is being displayed yet... the pixel clock is still 0x00 */ + +#if defined (EVE_GD3X) + EVE_memWrite16(REG_OUTBITS,0x01B6U); /* the GD3X is only using 6 bits per color */ +#endif + + enable_pixel_clock(); + + EVE_memWrite16(REG_PWM_HZ, EVE_BACKLIGHT_FREQ); /* set backlight frequency to configured value */ + + EVE_memWrite8(REG_PWM_DUTY, EVE_BACKLIGHT_PWM); /* set backlight pwm to user requested level */ + DELAY_MS(1U); + EVE_execute_cmd(); /* just to be safe, wait for EVE to not be busy */ + +#if defined (EVE_DMA) + EVE_init_dma(); /* prepare DMA */ +#endif + } + } + + return (ret); +} + +/* ################################################################## + functions for display lists +##################################################################### */ + +/** + * @brief Begin a sequence of commands or prepare a DMA transfer if applicable. + * @note - Needs to be used with EVE_end_cmd_burst(). + * @note - Do not use any functions in the sequence that do not address the command-fifo as for example any of EVE_mem...() functions. + * @note - Do not use any of the functions that do not support burst-mode. + */ +void EVE_start_cmd_burst(void) +{ +#if defined (EVE_DMA) + if (EVE_dma_busy) + { + EVE_execute_cmd(); /* this is a safe-guard to protect segmented display-list building with DMA from overlapping */ + } +#endif + + cmd_burst = 42U; + +#if defined (EVE_DMA) + EVE_dma_buffer[0U] = 0x7825B000UL; /* REG_CMDB_WRITE + MEM_WRITE low mid hi 00 */ +// ((uint8_t) (ft_address >> 16U) | MEM_WRITE) | (ft_address & 0x0000ff00UL) | ((uint8_t) (ft_address) << 16U); +// EVE_dma_buffer[0U] = EVE_dma_buffer[0U] << 8U; + EVE_dma_buffer_index = 1U; +#else + EVE_cs_set(); + spi_transmit((uint8_t) 0xB0U); /* high-byte of REG_CMDB_WRITE + MEM_WRITE */ + spi_transmit((uint8_t) 0x25U); /* middle-byte of REG_CMDB_WRITE */ + spi_transmit((uint8_t) 0x78U); /* low-byte of REG_CMDB_WRITE */ +#endif +} + +/** + * @brief End a sequence of commands or trigger a prepared DMA transfer if applicable. + * @note - Needs to be used with EVE_start_cmd_burst(). + */ +void EVE_end_cmd_burst(void) +{ + cmd_burst = 0U; + +#if defined (EVE_DMA) + EVE_start_dma_transfer(); /* begin DMA transfer */ +#else + EVE_cs_clear(); +#endif +} + +/* write a string to coprocessor memory in context of a command: */ +/* no chip-select, just plain SPI-transfers */ +static void private_string_write(const char *p_text) +{ + /* treat the array as bunch of bytes */ + const uint8_t *const p_bytes = (const uint8_t *)p_text; + + if (0U == cmd_burst) + { + uint8_t textindex = 0U; + uint8_t padding; + + /* either leave on Zero or when the string is too long */ + while ((textindex < 249U) && (p_bytes[textindex] != 0U)) + { + spi_transmit(p_bytes[textindex]); + textindex++; + } + + /* transmit at least one 0x00 byte */ + /* and up to four if the string happens to be 4-byte aligned already */ + padding = textindex & 3U; /* 0, 1, 2 or 3 */ + padding = 4U - padding; /* 4, 3, 2 or 1 */ + + while (padding > 0U) + { + spi_transmit(0U); + padding--; + } + } + else /* we are in burst mode, so every transfer is 32 bits */ + { + for (uint8_t textindex = 0U; textindex < 249U; textindex += 4U) + { + uint32_t calc = 0U; + + for (uint8_t index = 0U; index < 4U; index++) + { + uint8_t data; + + data = p_bytes[textindex + index]; + + if (0U == data) + { + spi_transmit_burst(calc); + return; /* MISRA 2012 rule 15.5 (advisory) violation */ + } + + calc += ((uint32_t)data) << (index * 8U); + } + + spi_transmit_burst(calc); + } + + spi_transmit_burst(0U); /* executed when the line is too long */ + } +} + +/* BT817 / BT818 */ +#if EVE_GEN > 3 + +/** + * @brief Render one frame in RAM_G of an animation. + */ +void EVE_cmd_animframeram(int16_t xc0, int16_t yc0, uint32_t aoptr, uint32_t frame) +{ + if (0U == cmd_burst) + { + eve_begin_cmd(CMD_ANIMFRAMERAM); + spi_transmit((uint8_t) ((uint16_t) xc0)); + spi_transmit((uint8_t) (((uint16_t) xc0) >> 8U)); + spi_transmit((uint8_t) ((uint16_t) yc0)); + spi_transmit((uint8_t) (((uint16_t) yc0) >> 8U)); + spi_transmit_32(aoptr); + spi_transmit_32(frame); + EVE_cs_clear(); + } + else + { + spi_transmit_burst(CMD_ANIMFRAMERAM); + spi_transmit_burst(((uint32_t) ((uint16_t) xc0)) + (((uint32_t) ((uint16_t) yc0)) << 16U)); + spi_transmit_burst(aoptr); + spi_transmit_burst(frame); + } +} + +/** + * @brief Render one frame in RAM_G of an animation, only works in burst-mode. + */ +void EVE_cmd_animframeram_burst(int16_t xc0, int16_t yc0, uint32_t aoptr, + uint32_t frame) +{ + spi_transmit_burst(CMD_ANIMFRAMERAM); + spi_transmit_burst(((uint32_t) ((uint16_t) xc0)) + (((uint32_t) ((uint16_t) yc0)) << 16U)); + spi_transmit_burst(aoptr); + spi_transmit_burst(frame); +} + +/** + * @brief Start an animation in RAM_G. + */ +void EVE_cmd_animstartram(int32_t chnl, uint32_t aoptr, uint32_t loop) +{ + if (0U == cmd_burst) + { + eve_begin_cmd(CMD_ANIMSTARTRAM); + spi_transmit_32((uint32_t) chnl); + spi_transmit_32(aoptr); + spi_transmit_32(loop); + EVE_cs_clear(); + } + else + { + spi_transmit_burst(CMD_ANIMSTARTRAM); + spi_transmit_burst((uint32_t) chnl); + spi_transmit_burst(aoptr); + spi_transmit_burst(loop); + } +} + +/** + * @brief Start an animation in RAM_G, only works in burst-mode. + */ +void EVE_cmd_animstartram_burst(int32_t chnl, uint32_t aoptr, uint32_t loop) +{ + spi_transmit_burst(CMD_ANIMSTARTRAM); + spi_transmit_burst((uint32_t) chnl); + spi_transmit_burst(aoptr); + spi_transmit_burst(loop); +} + +/** + * @brief Sets the API level used by the coprocessor. + */ +void EVE_cmd_apilevel(uint32_t level) +{ + if (0U == cmd_burst) + { + eve_begin_cmd(CMD_APILEVEL); + spi_transmit_32(level); + EVE_cs_clear(); + } + else + { + spi_transmit_burst(CMD_APILEVEL); + spi_transmit_burst(level); + } +} + +/** + * @brief Sets the API level used by the coprocessor, only works in burst-mode. + */ +void EVE_cmd_apilevel_burst(uint32_t level) +{ + spi_transmit_burst(CMD_APILEVEL); + spi_transmit_burst(level); +} + +/** + * @brief Execute the touch screen calibration routine for a sub-window. + * @note - Does not support burst-mode. + */ +void EVE_cmd_calibratesub(uint16_t xc0, uint16_t yc0, uint16_t width, uint16_t height) +{ + if (0U == cmd_burst) + { + eve_begin_cmd(CMD_CALIBRATESUB); + spi_transmit((uint8_t) ((uint16_t) xc0)); + spi_transmit((uint8_t) (((uint16_t) xc0) >> 8U)); + spi_transmit((uint8_t) ((uint16_t) yc0)); + spi_transmit((uint8_t) (((uint16_t) yc0) >> 8U)); + spi_transmit((uint8_t) (width)); + spi_transmit((uint8_t) (width >> 8U)); + spi_transmit((uint8_t) (height)); + spi_transmit((uint8_t) (height >> 8U)); + EVE_cs_clear(); + } +} + +/** + * @brief Calls a command list in RAM_G. + */ +void EVE_cmd_calllist(uint32_t adr) +{ + if (0U == cmd_burst) + { + eve_begin_cmd(CMD_CALLLIST); + spi_transmit_32(adr); + EVE_cs_clear(); + } + else + { + spi_transmit_burst(CMD_CALLLIST); + spi_transmit_burst(adr); + } +} + +/** + * @brief Calls a command list in RAM_G, only works in burst-mode. + */ +void EVE_cmd_calllist_burst(uint32_t adr) +{ + spi_transmit_burst(CMD_CALLLIST); + spi_transmit_burst(adr); +} + +/** + * @brief Setup the Horizontal Scan out Filter for non-square pixel LCD support. + * @note - Does not support burst-mode. + */ +void EVE_cmd_hsf(uint32_t hsf) +{ + if (0U == cmd_burst) + { + eve_begin_cmd(CMD_HSF); + spi_transmit_32(hsf); + EVE_cs_clear(); + } +} + +/** + * @brief Play/run animations until complete. + */ +void EVE_cmd_runanim(uint32_t waitmask, uint32_t play) +{ + if (0U == cmd_burst) + { + eve_begin_cmd(CMD_RUNANIM); + spi_transmit_32(waitmask); + spi_transmit_32(play); + EVE_cs_clear(); + } + else + { + spi_transmit_burst(CMD_RUNANIM); + spi_transmit_burst(waitmask); + spi_transmit_burst(play); + } +} + +/** + * @brief Play/run animations until complete, only works in burst-mode. + */ +void EVE_cmd_runanim_burst(uint32_t waitmask, uint32_t play) +{ + spi_transmit_burst(CMD_RUNANIM); + spi_transmit_burst(waitmask); + spi_transmit_burst(play); +} + +#endif /* EVE_GEN > 3 */ + +/* BT815 / BT816 */ +#if EVE_GEN > 2 + +/** + * @brief Draw one or more active animations. + */ +void EVE_cmd_animdraw(int32_t chnl) +{ + if (0U == cmd_burst) + { + eve_begin_cmd(CMD_ANIMDRAW); + spi_transmit_32((uint32_t) chnl); + EVE_cs_clear(); + } + else + { + spi_transmit_burst(CMD_ANIMDRAW); + spi_transmit_burst((uint32_t) chnl); + } +} + +/** + * @brief Draw one or more active animations, only works in burst-mode. + */ +void EVE_cmd_animdraw_burst(int32_t chnl) +{ + spi_transmit_burst(CMD_ANIMDRAW); + spi_transmit_burst((uint32_t) chnl); +} + +/** + * @brief Draw the specified frame of an animation. + */ +void EVE_cmd_animframe(int16_t xc0, int16_t yc0, uint32_t aoptr, uint32_t frame) +{ + if (0U == cmd_burst) + { + eve_begin_cmd(CMD_ANIMFRAME); + spi_transmit((uint8_t) ((uint16_t) xc0)); + spi_transmit((uint8_t) (((uint16_t) xc0) >> 8U)); + spi_transmit((uint8_t) ((uint16_t) yc0)); + spi_transmit((uint8_t) (((uint16_t) yc0) >> 8U)); + spi_transmit_32(aoptr); + spi_transmit_32(frame); + EVE_cs_clear(); + } + else + { + spi_transmit_burst(CMD_ANIMFRAME); + spi_transmit_burst(((uint32_t) ((uint16_t) xc0)) + (((uint32_t) ((uint16_t) yc0)) << 16U)); + spi_transmit_burst(aoptr); + spi_transmit_burst(frame); + } +} + +/** + * @brief Draw the specified frame of an animation, only works in burst-mode. + */ +void EVE_cmd_animframe_burst(int16_t xc0, int16_t yc0, uint32_t aoptr, + uint32_t frame) +{ + spi_transmit_burst(CMD_ANIMFRAME); + spi_transmit_burst(((uint32_t) ((uint16_t) xc0)) + (((uint32_t) ((uint16_t) yc0)) << 16U)); + spi_transmit_burst(aoptr); + spi_transmit_burst(frame); +} + +/** + * @brief Start an animation. + */ +void EVE_cmd_animstart(int32_t chnl, uint32_t aoptr, uint32_t loop) +{ + if (0U == cmd_burst) + { + eve_begin_cmd(CMD_ANIMSTART); + spi_transmit_32((uint32_t) chnl); + spi_transmit_32(aoptr); + spi_transmit_32(loop); + EVE_cs_clear(); + } + else + { + spi_transmit_burst(CMD_ANIMSTART); + spi_transmit_burst((uint32_t) chnl); + spi_transmit_burst(aoptr); + spi_transmit_burst(loop); + } +} + +/** + * @brief Start an animation, only works in burst-mode. + */ +void EVE_cmd_animstart_burst(int32_t chnl, uint32_t aoptr, uint32_t loop) +{ + spi_transmit_burst(CMD_ANIMSTART); + spi_transmit_burst((uint32_t) chnl); + spi_transmit_burst(aoptr); + spi_transmit_burst(loop); +} + +/** + * @brief Stops one or more active animations. + */ +void EVE_cmd_animstop(int32_t chnl) +{ + if (0U == cmd_burst) + { + eve_begin_cmd(CMD_ANIMSTOP); + spi_transmit_32((uint32_t) chnl); + EVE_cs_clear(); + } + else + { + spi_transmit_burst(CMD_ANIMSTOP); + spi_transmit_burst((uint32_t) chnl); + } +} + +/** + * @brief Stops one or more active animations, only works in burst-mode. + */ +void EVE_cmd_animstop_burst(int32_t chnl) +{ + spi_transmit_burst(CMD_ANIMSTOP); + spi_transmit_burst((uint32_t) chnl); +} + +/** + * @brief Sets the coordinates of an animation. + */ +void EVE_cmd_animxy(int32_t chnl, int16_t xc0, int16_t yc0) +{ + if (0U == cmd_burst) + { + eve_begin_cmd(CMD_ANIMXY); + spi_transmit_32((uint32_t) chnl); + spi_transmit((uint8_t) ((uint16_t) xc0)); + spi_transmit((uint8_t) (((uint16_t) xc0) >> 8U)); + spi_transmit((uint8_t) ((uint16_t) yc0)); + spi_transmit((uint8_t) (((uint16_t) yc0) >> 8U)); + EVE_cs_clear(); + } + else + { + spi_transmit_burst(CMD_ANIMXY); + spi_transmit_burst((uint32_t) chnl); + spi_transmit_burst(((uint32_t) ((uint16_t) xc0)) + (((uint32_t) ((uint16_t) yc0)) << 16U)); + } +} + +/** + * @brief Sets the coordinates of an animation, only works in burst-mode. + */ +void EVE_cmd_animxy_burst(int32_t chnl, int16_t xc0, int16_t yc0) +{ + spi_transmit_burst(CMD_ANIMXY); + spi_transmit_burst((uint32_t) chnl); + spi_transmit_burst(((uint32_t) ((uint16_t) xc0)) + (((uint32_t) ((uint16_t) yc0)) << 16U)); +} + +/** + * @brief Append flash data to the display list. + */ +void EVE_cmd_appendf(uint32_t ptr, uint32_t num) +{ + if (0U == cmd_burst) + { + eve_begin_cmd(CMD_APPENDF); + spi_transmit_32(ptr); + spi_transmit_32(num); + EVE_cs_clear(); + } + else + { + spi_transmit_burst(CMD_APPENDF); + spi_transmit_burst(ptr); + spi_transmit_burst(num); + } +} + +/** + * @brief Append flash data to the display list, only works in burst-mode. + */ +void EVE_cmd_appendf_burst(uint32_t ptr, uint32_t num) +{ + spi_transmit_burst(CMD_APPENDF); + spi_transmit_burst(ptr); + spi_transmit_burst(num); +} + +/** + * @brief Computes a bitmap transform and appends commands BITMAP_TRANSFORM_A...BITMAP_TRANSFORM_F to the display list. + */ +uint16_t EVE_cmd_bitmap_transform(int32_t xc0, int32_t yc0, int32_t xc1, + int32_t yc1, int32_t xc2, int32_t yc2, + int32_t tx0, int32_t ty0, int32_t tx1, + int32_t ty1, int32_t tx2, int32_t ty2) +{ + uint16_t ret_val = 0U; + + if (0U == cmd_burst) + { + uint16_t cmdoffset; + + eve_begin_cmd(CMD_BITMAP_TRANSFORM); + spi_transmit_32((uint32_t) xc0); + spi_transmit_32((uint32_t) yc0); + spi_transmit_32((uint32_t) xc1); + spi_transmit_32((uint32_t) yc1); + spi_transmit_32((uint32_t) xc2); + spi_transmit_32((uint32_t) yc2); + spi_transmit_32((uint32_t) tx0); + spi_transmit_32((uint32_t) ty0); + spi_transmit_32((uint32_t) tx1); + spi_transmit_32((uint32_t) ty1); + spi_transmit_32((uint32_t) tx2); + spi_transmit_32((uint32_t) ty2); + spi_transmit_32(0UL); + EVE_cs_clear(); + EVE_execute_cmd(); + cmdoffset = EVE_memRead16(REG_CMD_WRITE); + cmdoffset -= 4U; + cmdoffset &= 0x0fffU; + ret_val = (uint16_t) EVE_memRead32(EVE_RAM_CMD + cmdoffset); + } + else /* note: the result parameter is ignored in burst mode */ + { + spi_transmit_burst(CMD_BITMAP_TRANSFORM); + spi_transmit_burst((uint32_t) xc0); + spi_transmit_burst((uint32_t) yc0); + spi_transmit_burst((uint32_t) xc1); + spi_transmit_burst((uint32_t) yc1); + spi_transmit_burst((uint32_t) xc2); + spi_transmit_burst((uint32_t) yc2); + spi_transmit_burst((uint32_t) tx0); + spi_transmit_burst((uint32_t) ty0); + spi_transmit_burst((uint32_t) tx1); + spi_transmit_burst((uint32_t) ty1); + spi_transmit_burst((uint32_t) tx2); + spi_transmit_burst((uint32_t) ty2); + spi_transmit_burst(0UL); + } + return (ret_val); +} + +/** + * @brief Computes a bitmap transform and appends commands BITMAP_TRANSFORM_A...BITMAP_TRANSFORM_F to the display list. + * @note - Only works in burst-mode, the result parameter is ignored. + */ +void EVE_cmd_bitmap_transform_burst(int32_t xc0, int32_t yc0, int32_t xc1, + int32_t yc1, int32_t xc2, int32_t yc2, + int32_t tx0, int32_t ty0, int32_t tx1, + int32_t ty1, int32_t tx2, int32_t ty2) +{ + spi_transmit_burst(CMD_BITMAP_TRANSFORM); + spi_transmit_burst((uint32_t) xc0); + spi_transmit_burst((uint32_t) yc0); + spi_transmit_burst((uint32_t) xc1); + spi_transmit_burst((uint32_t) yc1); + spi_transmit_burst((uint32_t) xc2); + spi_transmit_burst((uint32_t) yc2); + spi_transmit_burst((uint32_t) tx0); + spi_transmit_burst((uint32_t) ty0); + spi_transmit_burst((uint32_t) tx1); + spi_transmit_burst((uint32_t) ty1); + spi_transmit_burst((uint32_t) tx2); + spi_transmit_burst((uint32_t) ty2); + spi_transmit_burst(0UL); +} + +/** + * @brief Sets the pixel fill width for CMD_TEXT,CMD_BUTTON,CMD_BUTTON with the OPT_FILL option. + */ +void EVE_cmd_fillwidth(uint32_t pixel) +{ + if (0U == cmd_burst) + { + eve_begin_cmd(CMD_FILLWIDTH); + spi_transmit_32(pixel); + EVE_cs_clear(); + } + else + { + spi_transmit_burst(CMD_FILLWIDTH); + spi_transmit_burst(pixel); + } +} + +/** + * @brief Sets the pixel fill width for CMD_TEXT,CMD_BUTTON,CMD_BUTTON with the OPT_FILL option. + * @note - Only works in burst-mode. + */ +void EVE_cmd_fillwidth_burst(uint32_t pixel) +{ + spi_transmit_burst(CMD_FILLWIDTH); + spi_transmit_burst(pixel); +} + +/** + * @brief Draw a smooth color gradient with transparency. + */ +void EVE_cmd_gradienta(int16_t xc0, int16_t yc0, uint32_t argb0, int16_t xc1, int16_t yc1, uint32_t argb1) +{ + if (0U == cmd_burst) + { + eve_begin_cmd(CMD_GRADIENTA); + spi_transmit((uint8_t) ((uint16_t) xc0)); + spi_transmit((uint8_t) (((uint16_t) xc0) >> 8U)); + spi_transmit((uint8_t) ((uint16_t) yc0)); + spi_transmit((uint8_t) (((uint16_t) yc0) >> 8U)); + spi_transmit_32(argb0); + spi_transmit((uint8_t) ((uint16_t) xc1)); + spi_transmit((uint8_t) (((uint16_t) xc1) >> 8U)); + spi_transmit((uint8_t) ((uint16_t) yc1)); + spi_transmit((uint8_t) (((uint16_t) yc1) >> 8U)); + spi_transmit_32(argb1); + EVE_cs_clear(); + } + else + { + spi_transmit_burst(CMD_GRADIENTA); + spi_transmit_burst(((uint32_t) ((uint16_t) xc0)) + (((uint32_t) ((uint16_t) yc0)) << 16U)); + spi_transmit_burst(argb0); + spi_transmit_burst(((uint32_t) ((uint16_t) xc1)) + (((uint32_t) ((uint16_t) yc1)) << 16U)); + spi_transmit_burst(argb1); + } +} + +/** + * @brief Draw a smooth color gradient with transparency, only works in burst-mode. + */ +void EVE_cmd_gradienta_burst(int16_t xc0, int16_t yc0, uint32_t argb0, int16_t xc1, int16_t yc1, uint32_t argb1) +{ + spi_transmit_burst(CMD_GRADIENTA); + spi_transmit_burst(((uint32_t) ((uint16_t) xc0)) + (((uint32_t) ((uint16_t) yc0)) << 16U)); + spi_transmit_burst(argb0); + spi_transmit_burst(((uint32_t) ((uint16_t) xc1)) + (((uint32_t) ((uint16_t) yc1)) << 16U)); + spi_transmit_burst(argb1); +} + +/** + * @brief Apply a rotation and scale around a specified coordinate. + */ +void EVE_cmd_rotatearound(int32_t xc0, int32_t yc0, uint32_t angle, int32_t scale) +{ + if (0U == cmd_burst) + { + eve_begin_cmd(CMD_ROTATEAROUND); + spi_transmit_32((uint32_t) xc0); + spi_transmit_32((uint32_t) yc0); + spi_transmit_32(angle & 0xFFFFUL); + spi_transmit_32((uint32_t) scale); + EVE_cs_clear(); + } + else + { + spi_transmit_burst(CMD_ROTATEAROUND); + spi_transmit_burst((uint32_t) xc0); + spi_transmit_burst((uint32_t) yc0); + spi_transmit_burst(angle & 0xFFFFUL); + spi_transmit_burst((uint32_t) scale); + } +} + +/** + * @brief Apply a rotation and scale around a specified coordinate, only works in burst-mode. + */ +void EVE_cmd_rotatearound_burst(int32_t xc0, int32_t yc0, uint32_t angle, + int32_t scale) +{ + spi_transmit_burst(CMD_ROTATEAROUND); + spi_transmit_burst((uint32_t) xc0); + spi_transmit_burst((uint32_t) yc0); + spi_transmit_burst(angle & 0xFFFFUL); + spi_transmit_burst((uint32_t) scale); +} + +/** + * @brief Draw a button with a label, varargs version. + * @param p_arguments[] pointer to an array of values converted to uint32_t to be used when using EVE_OPT_FORMAT + * @param num_args the number of elements provided in p_arguments[] + */ +void EVE_cmd_button_var(int16_t xc0, int16_t yc0, uint16_t wid, uint16_t hgt, + uint16_t font, uint16_t options, const char *p_text, + uint8_t num_args, const uint32_t p_arguments[]) +{ + if (0U == cmd_burst) + { + eve_begin_cmd(CMD_BUTTON); + spi_transmit((uint8_t) ((uint16_t) xc0)); + spi_transmit((uint8_t) (((uint16_t) xc0) >> 8U)); + spi_transmit((uint8_t) ((uint16_t) yc0)); + spi_transmit((uint8_t) (((uint16_t) yc0) >> 8U)); + spi_transmit((uint8_t) (wid)); + spi_transmit((uint8_t) (wid >> 8U)); + spi_transmit((uint8_t) (hgt)); + spi_transmit((uint8_t) (hgt >> 8U)); + spi_transmit((uint8_t) (font)); + spi_transmit((uint8_t) (font >> 8U)); + spi_transmit((uint8_t) (options)); + spi_transmit((uint8_t) (options >> 8U)); + private_string_write(p_text); + + if ((options & EVE_OPT_FORMAT) != 0U) + { + if (p_arguments != NULL) + { + for (uint8_t counter = 0U; counter < num_args; counter++) + { + spi_transmit_32(p_arguments[counter]); + } + } + } + EVE_cs_clear(); + } + else + { + spi_transmit_burst(CMD_BUTTON); + spi_transmit_burst(((uint32_t) ((uint16_t) xc0)) + (((uint32_t) ((uint16_t) yc0)) << 16U)); + spi_transmit_burst(((uint32_t) wid) + ((uint32_t) hgt << 16U)); + spi_transmit_burst(((uint32_t) font) + ((uint32_t) options << 16U)); + private_string_write(p_text); + + if ((options & EVE_OPT_FORMAT) != 0U) + { + if (p_arguments != NULL) + { + for (uint8_t counter = 0U; counter < num_args; counter++) + { + spi_transmit_burst(p_arguments[counter]); + } + } + } + } +} + +/** + * @brief Draw a button with a label, varargs version, only works in burst-mode. + * @param p_arguments[] pointer to an array of values converted to uint32_t to be used when using EVE_OPT_FORMAT + * @param num_args the number of elements provided in p_arguments[] + */ +void EVE_cmd_button_var_burst(int16_t xc0, int16_t yc0, uint16_t wid, uint16_t hgt, + uint16_t font, uint16_t options, const char *p_text, + uint8_t num_args, const uint32_t p_arguments[]) +{ + spi_transmit_burst(CMD_BUTTON); + spi_transmit_burst(((uint32_t) ((uint16_t) xc0)) + (((uint32_t) ((uint16_t) yc0)) << 16U)); + spi_transmit_burst(((uint32_t) wid) + ((uint32_t) hgt << 16U)); + spi_transmit_burst(((uint32_t) font) + ((uint32_t) options << 16U)); + private_string_write(p_text); + + if ((options & EVE_OPT_FORMAT) != 0U) + { + if (p_arguments != NULL) + { + for (uint8_t counter = 0U; counter < num_args; counter++) + { + spi_transmit_burst(p_arguments[counter]); + } + } + } +} + +/** + * @brief Draw a text string, varargs version. + * @param p_arguments[] pointer to an array of values converted to uint32_t to be used when using EVE_OPT_FORMAT + * @param num_args the number of elements provided in p_arguments[] + */ +void EVE_cmd_text_var(int16_t xc0, int16_t yc0, uint16_t font, + uint16_t options, const char *p_text, + uint8_t num_args, const uint32_t p_arguments[]) +{ + if (0U == cmd_burst) + { + eve_begin_cmd(CMD_TEXT); + spi_transmit((uint8_t) ((uint16_t) xc0)); + spi_transmit((uint8_t) (((uint16_t) xc0) >> 8U)); + spi_transmit((uint8_t) ((uint16_t) yc0)); + spi_transmit((uint8_t) (((uint16_t) yc0) >> 8U)); + spi_transmit((uint8_t) (font)); + spi_transmit((uint8_t) (font >> 8U)); + spi_transmit((uint8_t) (options)); + spi_transmit((uint8_t) (options >> 8U)); + private_string_write(p_text); + + if ((options & EVE_OPT_FORMAT) != 0U) + { + if (p_arguments != NULL) + { + for (uint8_t counter = 0U; counter < num_args; counter++) + { + spi_transmit_32(p_arguments[counter]); + } + } + } + EVE_cs_clear(); + } + else + { + spi_transmit_burst(CMD_TEXT); + spi_transmit_burst(((uint32_t) ((uint16_t) xc0)) + (((uint32_t) ((uint16_t) yc0)) << 16U)); + spi_transmit_burst(((uint32_t) font) + (((uint32_t) options) << 16U)); + private_string_write(p_text); + + if ((options & EVE_OPT_FORMAT) != 0U) + { + if (p_arguments != NULL) + { + for (uint8_t counter = 0U; counter < num_args; counter++) + { + spi_transmit_burst(p_arguments[counter]); + } + } + } + } +} + +/** + * @brief Draw a text string, varargs version. + * @param p_arguments[] pointer to an array of values converted to uint32_t to be used when using EVE_OPT_FORMAT + * @param num_args the number of elements provided in p_arguments[] + */ +void EVE_cmd_text_var_burst(int16_t xc0, int16_t yc0, uint16_t font, + uint16_t options, const char *p_text, + uint8_t num_args, const uint32_t p_arguments[]) +{ + spi_transmit_burst(CMD_TEXT); + spi_transmit_burst(((uint32_t) ((uint16_t) xc0)) + (((uint32_t) ((uint16_t) yc0)) << 16U)); + spi_transmit_burst(((uint32_t) font) + (((uint32_t) options) << 16U)); + private_string_write(p_text); + + if ((options & EVE_OPT_FORMAT) != 0U) + { + if (p_arguments != NULL) + { + for (uint8_t counter = 0U; counter < num_args; counter++) + { + spi_transmit_burst(p_arguments[counter]); + } + } + } +} + +/** + * @brief Draw a toggle switch with labels, varargs version. + * @param p_arguments[] pointer to an array of values converted to uint32_t to be used when using EVE_OPT_FORMAT + * @param num_args the number of elements provided in p_arguments[] + */ +void EVE_cmd_toggle_var(int16_t xc0, int16_t yc0, uint16_t wid, uint16_t font, + uint16_t options, uint16_t state, const char *p_text, + uint8_t num_args, const uint32_t p_arguments[]) +{ + if (0U == cmd_burst) + { + eve_begin_cmd(CMD_TOGGLE); + spi_transmit((uint8_t) ((uint16_t) xc0)); + spi_transmit((uint8_t) (((uint16_t) xc0) >> 8U)); + spi_transmit((uint8_t) ((uint16_t) yc0)); + spi_transmit((uint8_t) (((uint16_t) yc0) >> 8U)); + spi_transmit((uint8_t) (wid)); + spi_transmit((uint8_t) (wid >> 8U)); + spi_transmit((uint8_t) (font)); + spi_transmit((uint8_t) (font >> 8U)); + spi_transmit((uint8_t) (options)); + spi_transmit((uint8_t) (options >> 8U)); + spi_transmit((uint8_t) (state)); + spi_transmit((uint8_t) (state >> 8U)); + private_string_write(p_text); + + if ((options & EVE_OPT_FORMAT) != 0U) + { + if (p_arguments != NULL) + { + for (uint8_t counter = 0U; counter < num_args; counter++) + { + spi_transmit_32(p_arguments[counter]); + } + } + } + EVE_cs_clear(); + } + else + { + spi_transmit_burst(CMD_TOGGLE); + spi_transmit_burst(((uint32_t) ((uint16_t) xc0)) + (((uint32_t) ((uint16_t) yc0)) << 16U)); + spi_transmit_burst(((uint32_t) wid) + (((uint32_t) font) << 16U)); + spi_transmit_burst(((uint32_t) options) + (((uint32_t) state) << 16U)); + private_string_write(p_text); + + if ((options & EVE_OPT_FORMAT) != 0U) + { + if (p_arguments != NULL) + { + for (uint8_t counter = 0U; counter < num_args; counter++) + { + spi_transmit_burst(p_arguments[counter]); + } + } + } + } +} + +/** + * @brief Draw a toggle switch with labels, varargs version, only works in burst-mode. + * @param p_arguments[] pointer to an array of values converted to uint32_t to be used when using EVE_OPT_FORMAT + * @param num_args the number of elements provided in p_arguments[] + */ +void EVE_cmd_toggle_var_burst(int16_t xc0, int16_t yc0, uint16_t wid, uint16_t font, + uint16_t options, uint16_t state, const char *p_text, + uint8_t num_args, const uint32_t p_arguments[]) +{ + spi_transmit_burst(CMD_TOGGLE); + spi_transmit_burst(((uint32_t) ((uint16_t) xc0)) + (((uint32_t) ((uint16_t) yc0)) << 16U)); + spi_transmit_burst(((uint32_t) wid) + (((uint32_t) font) << 16U)); + spi_transmit_burst(((uint32_t) options) + (((uint32_t) state) << 16U)); + private_string_write(p_text); + + if ((options & EVE_OPT_FORMAT) != 0U) + { + if (p_arguments != NULL) + { + for (uint8_t counter = 0U; counter < num_args; counter++) + { + spi_transmit_burst(p_arguments[counter]); + } + } + } +} + +#endif /* EVE_GEN > 2 */ + +/** + * @brief Generic function for display-list and coprocessor commands with no arguments, only works in burst-mode. + * @note - EVE_cmd_dl(CMD_DLSTART); + * @note - EVE_cmd_dl(CMD_SWAP); + * @note - EVE_cmd_dl(CMD_SCREENSAVER); + * @note - EVE_cmd_dl(VERTEX2F(0,0)); + * @note - EVE_cmd_dl(DL_BEGIN | EVE_RECTS); + */ +void EVE_cmd_dl(uint32_t command) +{ + if (0U == cmd_burst) + { + eve_begin_cmd(command); + EVE_cs_clear(); + } + else + { + spi_transmit_burst(command); + } +} + +/** + * @brief Generic function for display-list and coprocessor commands with no arguments, only works in burst-mode. + */ +void EVE_cmd_dl_burst(uint32_t command) +{ + spi_transmit_burst(command); +} + +/** + * @brief Appends commands from RAM_G to the display list. + */ +void EVE_cmd_append(uint32_t ptr, uint32_t num) +{ + if (0U == cmd_burst) + { + eve_begin_cmd(CMD_APPEND); + spi_transmit_32(ptr); + spi_transmit_32(num); + EVE_cs_clear(); + } + else + { + spi_transmit_burst(CMD_APPEND); + spi_transmit_burst(ptr); + spi_transmit_burst(num); + } +} + +/** + * @brief Appends commands from RAM_G to the display list, only works in burst-mode. + */ +void EVE_cmd_append_burst(uint32_t ptr, uint32_t num) +{ + spi_transmit_burst(CMD_APPEND); + spi_transmit_burst(ptr); + spi_transmit_burst(num); +} + +/** + * @brief Set the background color. + */ +void EVE_cmd_bgcolor(uint32_t color) +{ + if (0U == cmd_burst) + { + eve_begin_cmd(CMD_BGCOLOR); + spi_transmit((uint8_t) (color)); + spi_transmit((uint8_t) (color >> 8U)); + spi_transmit((uint8_t) (color >> 16U)); + spi_transmit(0U); + EVE_cs_clear(); + } + else + { + spi_transmit_burst(CMD_BGCOLOR); + spi_transmit_burst(color); + } +} + +/** + * @brief Set the background color, only works in burst-mode. + */ +void EVE_cmd_bgcolor_burst(uint32_t color) +{ + spi_transmit_burst(CMD_BGCOLOR); + spi_transmit_burst(color); +} + +/** + * @brief Draw a button with a label. + */ +void EVE_cmd_button(int16_t xc0, int16_t yc0, uint16_t wid, uint16_t hgt, + uint16_t font, uint16_t options, const char *p_text) +{ + if (0U == cmd_burst) + { + eve_begin_cmd(CMD_BUTTON); + spi_transmit((uint8_t) ((uint16_t) xc0)); + spi_transmit((uint8_t) (((uint16_t) xc0) >> 8U)); + spi_transmit((uint8_t) ((uint16_t) yc0)); + spi_transmit((uint8_t) (((uint16_t) yc0) >> 8U)); + spi_transmit((uint8_t) (wid)); + spi_transmit((uint8_t) (wid >> 8U)); + spi_transmit((uint8_t) (hgt)); + spi_transmit((uint8_t) (hgt >> 8U)); + spi_transmit((uint8_t) (font)); + spi_transmit((uint8_t) (font >> 8U)); + spi_transmit((uint8_t) (options)); + spi_transmit((uint8_t) (options >> 8U)); + private_string_write(p_text); + EVE_cs_clear(); + } + else + { + spi_transmit_burst(CMD_BUTTON); + spi_transmit_burst(((uint32_t) ((uint16_t) xc0)) + (((uint32_t) ((uint16_t) yc0)) << 16U)); + spi_transmit_burst(((uint32_t) wid) + (((uint32_t) hgt) << 16U)); + spi_transmit_burst(((uint32_t) font) + (((uint32_t) options) << 16U)); + private_string_write(p_text); + } +} + +/** + * @brief Draw a button with a label, only works in burst-mode. + */ +void EVE_cmd_button_burst(int16_t xc0, int16_t yc0, uint16_t wid, uint16_t hgt, + uint16_t font, uint16_t options, const char *p_text) +{ + spi_transmit_burst(CMD_BUTTON); + spi_transmit_burst(((uint32_t) ((uint16_t) xc0)) + (((uint32_t) ((uint16_t) yc0)) << 16U)); + spi_transmit_burst(((uint32_t) wid) + (((uint32_t) hgt) << 16U)); + spi_transmit_burst(((uint32_t) font) + (((uint32_t) options) << 16U)); + private_string_write(p_text); +} + +/** + * @brief Execute the touch screen calibration routine. + * @note - does not support burst-mode + */ +void EVE_cmd_calibrate(void) +{ + if (0U == cmd_burst) + { + eve_begin_cmd(CMD_CALIBRATE); + spi_transmit_32(0UL); + EVE_cs_clear(); + } +} + +/** + * @brief Draw an analog clock. + */ +void EVE_cmd_clock(int16_t xc0, int16_t yc0, uint16_t rad, uint16_t options, + uint16_t hours, uint16_t mins, uint16_t secs, uint16_t msecs) +{ + if (0U == cmd_burst) + { + eve_begin_cmd(CMD_CLOCK); + spi_transmit((uint8_t) ((uint16_t) xc0)); + spi_transmit((uint8_t) (((uint16_t) xc0) >> 8U)); + spi_transmit((uint8_t) ((uint16_t) yc0)); + spi_transmit((uint8_t) (((uint16_t) yc0) >> 8U)); + spi_transmit((uint8_t) (rad)); + spi_transmit((uint8_t) (rad >> 8U)); + spi_transmit((uint8_t) (options)); + spi_transmit((uint8_t) (options >> 8U)); + spi_transmit((uint8_t) (hours)); + spi_transmit((uint8_t) (hours >> 8U)); + spi_transmit((uint8_t) (mins)); + spi_transmit((uint8_t) (mins >> 8U)); + spi_transmit((uint8_t) (secs)); + spi_transmit((uint8_t) (secs >> 8U)); + spi_transmit((uint8_t) (msecs)); + spi_transmit((uint8_t) (msecs >> 8U)); + EVE_cs_clear(); + } + else + { + spi_transmit_burst(CMD_CLOCK); + spi_transmit_burst(((uint32_t) ((uint16_t) xc0)) + (((uint32_t) ((uint16_t) yc0)) << 16U)); + spi_transmit_burst(((uint32_t) rad) + (((uint32_t) options) << 16U)); + spi_transmit_burst(((uint32_t) hours) + (((uint32_t) mins) << 16U)); + spi_transmit_burst(((uint32_t) secs) + (((uint32_t) msecs) << 16U)); + } +} + +/** + * @brief Draw an analog clock, only works in burst-mode. + */ +void EVE_cmd_clock_burst(int16_t xc0, int16_t yc0, uint16_t rad, uint16_t options, uint16_t hours, + uint16_t mins, uint16_t secs, uint16_t msecs) +{ + spi_transmit_burst(CMD_CLOCK); + spi_transmit_burst(((uint32_t) ((uint16_t) xc0)) + (((uint32_t) ((uint16_t) yc0)) << 16U)); + spi_transmit_burst(((uint32_t) rad) + (((uint32_t) options) << 16U)); + spi_transmit_burst(((uint32_t) hours) + (((uint32_t) mins) << 16U)); + spi_transmit_burst(((uint32_t) secs) + (((uint32_t) msecs) << 16U)); +} + +/** + * @brief Draw a rotary dial control. + */ +void EVE_cmd_dial(int16_t xc0, int16_t yc0, uint16_t rad, uint16_t options, uint16_t val) +{ + if (0U == cmd_burst) + { + eve_begin_cmd(CMD_DIAL); + spi_transmit((uint8_t) ((uint16_t) xc0)); + spi_transmit((uint8_t) (((uint16_t) xc0) >> 8U)); + spi_transmit((uint8_t) ((uint16_t) yc0)); + spi_transmit((uint8_t) (((uint16_t) yc0) >> 8U)); + spi_transmit((uint8_t) (rad)); + spi_transmit((uint8_t) (rad >> 8U)); + spi_transmit((uint8_t) (options)); + spi_transmit((uint8_t) (options >> 8U)); + spi_transmit((uint8_t) (val)); + spi_transmit((uint8_t) (val >> 8U)); + spi_transmit(0U); + spi_transmit(0U); + EVE_cs_clear(); + } + else + { + spi_transmit_burst(CMD_DIAL); + spi_transmit_burst(((uint32_t) ((uint16_t) xc0)) + (((uint32_t) ((uint16_t) yc0)) << 16U)); + spi_transmit_burst(((uint32_t) rad) + (((uint32_t) options) << 16U)); + spi_transmit_burst(val); + } +} + +/** + * @brief Draw a rotary dial control, only works in burst-mode. + */ +void EVE_cmd_dial_burst(int16_t xc0, int16_t yc0, uint16_t rad, uint16_t options, + uint16_t val) +{ + spi_transmit_burst(CMD_DIAL); + spi_transmit_burst(((uint32_t) ((uint16_t) xc0)) + (((uint32_t) ((uint16_t) yc0)) << 16U)); + spi_transmit_burst(((uint32_t) rad) + (((uint32_t) options) << 16U)); + spi_transmit_burst(val); +} + +/** + * @brief Set the foreground color. + */ +void EVE_cmd_fgcolor(uint32_t color) +{ + if (0U == cmd_burst) + { + eve_begin_cmd(CMD_FGCOLOR); + spi_transmit((uint8_t) (color)); + spi_transmit((uint8_t) (color >> 8U)); + spi_transmit((uint8_t) (color >> 16U)); + spi_transmit(0U); + EVE_cs_clear(); + } + else + { + spi_transmit_burst(CMD_FGCOLOR); + spi_transmit_burst(color); + } +} + +/** + * @brief Set the foreground color, only works in burst-mode. + */ +void EVE_cmd_fgcolor_burst(uint32_t color) +{ + spi_transmit_burst(CMD_FGCOLOR); + spi_transmit_burst(color); +} + +/** + * @brief Draw a gauge. + */ +void EVE_cmd_gauge(int16_t xc0, int16_t yc0, uint16_t rad, uint16_t options, + uint16_t major, uint16_t minor, uint16_t val, uint16_t range) +{ + if (0U == cmd_burst) + { + eve_begin_cmd(CMD_GAUGE); + spi_transmit((uint8_t) ((uint16_t) xc0)); + spi_transmit((uint8_t) (((uint16_t) xc0) >> 8U)); + spi_transmit((uint8_t) ((uint16_t) yc0)); + spi_transmit((uint8_t) (((uint16_t) yc0) >> 8U)); + spi_transmit((uint8_t) (rad)); + spi_transmit((uint8_t) (rad >> 8U)); + spi_transmit((uint8_t) (options)); + spi_transmit((uint8_t) (options >> 8U)); + spi_transmit((uint8_t) (major)); + spi_transmit((uint8_t) (major >> 8U)); + spi_transmit((uint8_t) (minor)); + spi_transmit((uint8_t) (minor >> 8U)); + spi_transmit((uint8_t) (val)); + spi_transmit((uint8_t) (val >> 8U)); + spi_transmit((uint8_t) (range)); + spi_transmit((uint8_t) (range >> 8U)); + EVE_cs_clear(); + } + else + { + spi_transmit_burst(CMD_GAUGE); + spi_transmit_burst(((uint32_t) ((uint16_t) xc0)) + (((uint32_t) ((uint16_t) yc0)) << 16U)); + spi_transmit_burst(((uint32_t) rad) + (((uint32_t) options) << 16U)); + spi_transmit_burst(((uint32_t) major) + (((uint32_t) minor) << 16U)); + spi_transmit_burst(((uint32_t) val) + (((uint32_t) range) << 16U)); + } +} + +/** + * @brief Draw a gauge, only works in burst-mode. + */ +void EVE_cmd_gauge_burst(int16_t xc0, int16_t yc0, uint16_t rad, uint16_t options, + uint16_t major, uint16_t minor, uint16_t val, uint16_t range) +{ + spi_transmit_burst(CMD_GAUGE); + spi_transmit_burst(((uint32_t) ((uint16_t) xc0)) + (((uint32_t) ((uint16_t) yc0)) << 16U)); + spi_transmit_burst(((uint32_t) rad) + (((uint32_t) options) << 16U)); + spi_transmit_burst(((uint32_t) major) + (((uint32_t) minor) << 16U)); + spi_transmit_burst(((uint32_t) val) + (((uint32_t) range) << 16U)); +} + +/** + * @brief Retrieves the current matrix within the context of the coprocessor engine. + * @note - waits for completion and reads values from RAM_CMD after completion + * @note - can not be used with cmd-burst + */ +void EVE_cmd_getmatrix(int32_t *p_a, int32_t *p_b, int32_t *p_c, + int32_t *p_d, int32_t *p_e, int32_t *p_f) +{ + if (0U == cmd_burst) + { + uint16_t cmdoffset; + uint32_t address; + + eve_begin_cmd(CMD_GETMATRIX); + spi_transmit_32(0UL); + spi_transmit_32(0UL); + spi_transmit_32(0UL); + spi_transmit_32(0UL); + spi_transmit_32(0UL); + spi_transmit_32(0UL); + EVE_cs_clear(); + EVE_execute_cmd(); + cmdoffset = EVE_memRead16(REG_CMD_WRITE); + + if (p_f != NULL) + { + address = EVE_RAM_CMD + ((cmdoffset - 4UL) & 0xfffUL); + *p_f = (int32_t) EVE_memRead32(address); + } + if (p_e != NULL) + { + address = EVE_RAM_CMD + ((cmdoffset - 8UL) & 0xfffUL); + *p_e = (int32_t) EVE_memRead32(address); + } + if (p_d != NULL) + { + address = EVE_RAM_CMD + ((cmdoffset - 12UL) & 0xfffUL); + *p_d = (int32_t) EVE_memRead32(address); + } + if (p_c != NULL) + { + address = EVE_RAM_CMD + ((cmdoffset - 16UL) & 0xfffUL); + *p_c = (int32_t) EVE_memRead32(address); + } + if (p_b != NULL) + { + address = EVE_RAM_CMD + ((cmdoffset - 20UL) & 0xfffUL); + *p_b = (int32_t) EVE_memRead32(address); + } + if (p_a != NULL) + { + address = EVE_RAM_CMD + ((cmdoffset - 24UL) & 0xfffUL); + *p_a = (int32_t) EVE_memRead32(address); + } + } +} + +/** + * @brief Set up the highlight color used in 3D effects for CMD_BUTTON and CMD_KEYS. + */ +void EVE_cmd_gradcolor(uint32_t color) +{ + if (0U == cmd_burst) + { + eve_begin_cmd(CMD_GRADCOLOR); + spi_transmit((uint8_t) (color)); + spi_transmit((uint8_t) (color >> 8U)); + spi_transmit((uint8_t) (color >> 16U)); + spi_transmit(0U); + EVE_cs_clear(); + } + else + { + spi_transmit_burst(CMD_GRADCOLOR); + spi_transmit_burst(color); + } +} + +/** + * @brief Set up the highlight color used in 3D effects for CMD_BUTTON and CMD_KEYS, only works in burst-mode. + */ +void EVE_cmd_gradcolor_burst(uint32_t color) +{ + spi_transmit_burst(CMD_GRADCOLOR); + spi_transmit_burst(color); +} + +/** + * @brief Draw a smooth color gradient. + */ +void EVE_cmd_gradient(int16_t xc0, int16_t yc0, uint32_t rgb0, int16_t xc1, + int16_t yc1, uint32_t rgb1) +{ + if (0U == cmd_burst) + { + eve_begin_cmd(CMD_GRADIENT); + spi_transmit((uint8_t) ((uint16_t) xc0)); + spi_transmit((uint8_t) (((uint16_t) xc0) >> 8U)); + spi_transmit((uint8_t) ((uint16_t) yc0)); + spi_transmit((uint8_t) (((uint16_t) yc0) >> 8U)); + spi_transmit((uint8_t) (rgb0)); + spi_transmit((uint8_t) (rgb0 >> 8U)); + spi_transmit((uint8_t) (rgb0 >> 16U)); + spi_transmit(0U); + spi_transmit((uint8_t) ((uint16_t) xc1)); + spi_transmit((uint8_t) (((uint16_t) xc1) >> 8U)); + spi_transmit((uint8_t) ((uint16_t) yc1)); + spi_transmit((uint8_t) (((uint16_t) yc1) >> 8U)); + spi_transmit((uint8_t) (rgb1)); + spi_transmit((uint8_t) (rgb1 >> 8U)); + spi_transmit((uint8_t) (rgb1 >> 16U)); + spi_transmit(0U); + EVE_cs_clear(); + } + else + { + spi_transmit_burst(CMD_GRADIENT); + spi_transmit_burst(((uint32_t) ((uint16_t) xc0)) + (((uint32_t) ((uint16_t) yc0)) << 16U)); + spi_transmit_burst(rgb0); + spi_transmit_burst(((uint32_t) ((uint16_t) xc1)) + (((uint32_t) ((uint16_t) yc1)) << 16U)); + spi_transmit_burst(rgb1); + } +} + +/** + * @brief Draw a smooth color gradient, only works in burst-mode. + */ +void EVE_cmd_gradient_burst(int16_t xc0, int16_t yc0, uint32_t rgb0, int16_t xc1, + int16_t yc1, uint32_t rgb1) +{ + spi_transmit_burst(CMD_GRADIENT); + spi_transmit_burst(((uint32_t) ((uint16_t) xc0)) + (((uint32_t) ((uint16_t) yc0)) << 16U)); + spi_transmit_burst(rgb0); + spi_transmit_burst(((uint32_t) ((uint16_t) xc1)) + (((uint32_t) ((uint16_t) yc1)) << 16U)); + spi_transmit_burst(rgb1); +} + +/** + * @brief Draw a row of key buttons with labels. + * @note - The tag value of each button is set to the ASCII value of its label. + * @note - Does not work with UTF-8. + */ +void EVE_cmd_keys(int16_t xc0, int16_t yc0, uint16_t wid, uint16_t hgt, + uint16_t font, uint16_t options, const char *p_text) +{ + if (0U == cmd_burst) + { + eve_begin_cmd(CMD_KEYS); + spi_transmit((uint8_t) ((uint16_t) xc0)); + spi_transmit((uint8_t) (((uint16_t) xc0) >> 8U)); + spi_transmit((uint8_t) ((uint16_t) yc0)); + spi_transmit((uint8_t) (((uint16_t) yc0) >> 8U)); + spi_transmit((uint8_t) (wid)); + spi_transmit((uint8_t) (wid >> 8U)); + spi_transmit((uint8_t) (hgt)); + spi_transmit((uint8_t) (hgt >> 8U)); + spi_transmit((uint8_t) (font)); + spi_transmit((uint8_t) (font >> 8U)); + spi_transmit((uint8_t) (options)); + spi_transmit((uint8_t) (options >> 8U)); + private_string_write(p_text); + EVE_cs_clear(); + } + else + { + spi_transmit_burst(CMD_KEYS); + spi_transmit_burst(((uint32_t) ((uint16_t) xc0)) + (((uint32_t) ((uint16_t) yc0)) << 16U)); + spi_transmit_burst(((uint32_t) wid) + (((uint32_t) hgt) << 16U)); + spi_transmit_burst(((uint32_t) font) + (((uint32_t) options) << 16U)); + private_string_write(p_text); + } +} + +/** + * @brief Draw a row of key buttons with labels, only works in burst-mode. + * @note - The tag value of each button is set to the ASCII value of its label. + * @note - Does not work with UTF-8. + */ +void EVE_cmd_keys_burst(int16_t xc0, int16_t yc0, uint16_t wid, uint16_t hgt, + uint16_t font, uint16_t options, const char *p_text) +{ + spi_transmit_burst(CMD_KEYS); + spi_transmit_burst(((uint32_t) ((uint16_t) xc0)) + (((uint32_t) ((uint16_t) yc0)) << 16U)); + spi_transmit_burst(((uint32_t) wid) + (((uint32_t) hgt) << 16U)); + spi_transmit_burst(((uint32_t) font) + (((uint32_t) options) << 16U)); + private_string_write(p_text); +} + +/** + * @brief Draw a number. + */ +void EVE_cmd_number(int16_t xc0, int16_t yc0, uint16_t font, + uint16_t options, int32_t number) +{ + if (0U == cmd_burst) + { + eve_begin_cmd(CMD_NUMBER); + spi_transmit((uint8_t) ((uint16_t) xc0)); + spi_transmit((uint8_t) (((uint16_t) xc0) >> 8U)); + spi_transmit((uint8_t) ((uint16_t) yc0)); + spi_transmit((uint8_t) (((uint16_t) yc0) >> 8U)); + spi_transmit((uint8_t) (font)); + spi_transmit((uint8_t) (font >> 8U)); + spi_transmit((uint8_t) (options)); + spi_transmit((uint8_t) (options >> 8U)); + spi_transmit_32((uint32_t) number); + EVE_cs_clear(); + } + else + { + spi_transmit_burst(CMD_NUMBER); + spi_transmit_burst(((uint32_t) ((uint16_t) xc0)) + (((uint32_t) ((uint16_t) yc0)) << 16U)); + spi_transmit_burst(((uint32_t) font) + (((uint32_t) options) << 16U)); + spi_transmit_burst((uint32_t) number); + } +} + +/** + * @brief Draw a number, only works in burst-mode. + */ +void EVE_cmd_number_burst(int16_t xc0, int16_t yc0, uint16_t font, + uint16_t options, int32_t number) +{ + spi_transmit_burst(CMD_NUMBER); + spi_transmit_burst(((uint32_t) ((uint16_t) xc0)) + (((uint32_t) ((uint16_t) yc0)) << 16U)); + spi_transmit_burst(((uint32_t) font) + (((uint32_t) options) << 16U)); + spi_transmit_burst((uint32_t) number); +} + +/** + * @brief Draw a progress bar. + */ +void EVE_cmd_progress(int16_t xc0, int16_t yc0, uint16_t wid, uint16_t hgt, + uint16_t options, uint16_t val, uint16_t range) +{ + if (0U == cmd_burst) + { + eve_begin_cmd(CMD_PROGRESS); + spi_transmit((uint8_t) ((uint16_t) xc0)); + spi_transmit((uint8_t) (((uint16_t) xc0) >> 8U)); + spi_transmit((uint8_t) ((uint16_t) yc0)); + spi_transmit((uint8_t) (((uint16_t) yc0) >> 8U)); + spi_transmit((uint8_t) (wid)); + spi_transmit((uint8_t) (wid >> 8U)); + spi_transmit((uint8_t) (hgt)); + spi_transmit((uint8_t) (hgt >> 8U)); + spi_transmit((uint8_t) (options)); + spi_transmit((uint8_t) (options >> 8U)); + spi_transmit((uint8_t) (val)); + spi_transmit((uint8_t) (val >> 8U)); + spi_transmit((uint8_t) (range)); + spi_transmit((uint8_t) (range >> 8U)); + spi_transmit(0U); /* dummy byte for 4-byte alignment */ + spi_transmit(0U); /* dummy byte for 4-byte alignment */ + EVE_cs_clear(); + } + else + { + spi_transmit_burst(CMD_PROGRESS); + spi_transmit_burst(((uint32_t) ((uint16_t) xc0)) + (((uint32_t) ((uint16_t) yc0)) << 16U)); + spi_transmit_burst(((uint32_t) wid) + (((uint32_t) hgt) << 16U)); + spi_transmit_burst(((uint32_t) options) + (((uint32_t) val) << 16U)); + spi_transmit_burst((uint32_t) range); + } +} + +/** + * @brief Draw a progress bar, only works in burst-mode. + */ +void EVE_cmd_progress_burst(int16_t xc0, int16_t yc0, uint16_t wid, uint16_t hgt, + uint16_t options, uint16_t val, uint16_t range) +{ + spi_transmit_burst(CMD_PROGRESS); + spi_transmit_burst(((uint32_t) ((uint16_t) xc0)) + (((uint32_t) ((uint16_t) yc0)) << 16U)); + spi_transmit_burst(((uint32_t) wid) + (((uint32_t) hgt) << 16U)); + spi_transmit_burst(((uint32_t) options) + (((uint32_t) val) << 16U)); + spi_transmit_burst((uint32_t) range); +} + +/** + * @brief Load a ROM font into bitmap handle. + * @note - generates display list commands, so it needs to be put in a display list + */ +void EVE_cmd_romfont(uint32_t font, uint32_t romslot) +{ + if (0U == cmd_burst) + { + eve_begin_cmd(CMD_ROMFONT); + spi_transmit_32(font); + spi_transmit_32(romslot); + EVE_cs_clear(); + } + else + { + spi_transmit_burst(CMD_ROMFONT); + spi_transmit_burst(font); + spi_transmit_burst(romslot); + } +} + +/** + * @brief Load a ROM font into bitmap handle, only works in burst-mode. + * @note - generates display list commands, so it needs to be put in a display list + */ +void EVE_cmd_romfont_burst(uint32_t font, uint32_t romslot) +{ + spi_transmit_burst(CMD_ROMFONT); + spi_transmit_burst(font); + spi_transmit_burst(romslot); +} + +/** + * @brief Apply a rotation to the current matrix. + */ +void EVE_cmd_rotate(uint32_t angle) +{ + if (0U == cmd_burst) + { + eve_begin_cmd(CMD_ROTATE); + spi_transmit_32(angle & 0xFFFFUL); + EVE_cs_clear(); + } + else + { + spi_transmit_burst(CMD_ROTATE); + spi_transmit_burst(angle & 0xFFFFUL); + } +} + +/** + * @brief Apply a rotation to the current matrix, only works in burst-mode. + */ +void EVE_cmd_rotate_burst(uint32_t angle) +{ + spi_transmit_burst(CMD_ROTATE); + spi_transmit_burst(angle & 0xFFFFUL); +} + +/** + * @brief Apply a scale to the current matrix. + */ +void EVE_cmd_scale(int32_t scx, int32_t scy) +{ + if (0U == cmd_burst) + { + eve_begin_cmd(CMD_SCALE); + spi_transmit_32((uint32_t) scx); + spi_transmit_32((uint32_t) scy); + EVE_cs_clear(); + } + else + { + spi_transmit_burst(CMD_SCALE); + spi_transmit_burst((uint32_t) scx); + spi_transmit_burst((uint32_t) scy); + } +} + +/** + * @brief Apply a scale to the current matrix, only works in burst-mode. + */ +void EVE_cmd_scale_burst(int32_t scx, int32_t scy) +{ + spi_transmit_burst(CMD_SCALE); + spi_transmit_burst((uint32_t) scx); + spi_transmit_burst((uint32_t) scy); +} + +/** + * @brief Draw a scroll bar. + */ +void EVE_cmd_scrollbar(int16_t xc0, int16_t yc0, uint16_t wid, uint16_t hgt, + uint16_t options, uint16_t val, uint16_t size, uint16_t range) +{ + if (0U == cmd_burst) + { + eve_begin_cmd(CMD_SCROLLBAR); + spi_transmit((uint8_t) ((uint16_t) xc0)); + spi_transmit((uint8_t) (((uint16_t) xc0) >> 8U)); + spi_transmit((uint8_t) ((uint16_t) yc0)); + spi_transmit((uint8_t) (((uint16_t) yc0) >> 8U)); + spi_transmit((uint8_t) (wid)); + spi_transmit((uint8_t) (wid >> 8U)); + spi_transmit((uint8_t) (hgt)); + spi_transmit((uint8_t) (hgt >> 8U)); + spi_transmit((uint8_t) (options)); + spi_transmit((uint8_t) (options >> 8U)); + spi_transmit((uint8_t) (val)); + spi_transmit((uint8_t) (val >> 8U)); + spi_transmit((uint8_t) (size)); + spi_transmit((uint8_t) (size >> 8U)); + spi_transmit((uint8_t) (range)); + spi_transmit((uint8_t) (range >> 8U)); + EVE_cs_clear(); + } + else + { + spi_transmit_burst(CMD_SCROLLBAR); + spi_transmit_burst(((uint32_t) ((uint16_t) xc0)) + (((uint32_t) ((uint16_t) yc0)) << 16U)); + spi_transmit_burst(((uint32_t) wid) + (((uint32_t) hgt) << 16U)); + spi_transmit_burst(((uint32_t) options) + (((uint32_t) val) << 16U)); + spi_transmit_burst(((uint32_t) size) + (((uint32_t) range) << 16U)); + } +} + +/** + * @brief Draw a scroll bar, only works in burst-mode. + */ +void EVE_cmd_scrollbar_burst(int16_t xc0, int16_t yc0, uint16_t wid, uint16_t hgt, + uint16_t options, uint16_t val, uint16_t size, uint16_t range) +{ + spi_transmit_burst(CMD_SCROLLBAR); + spi_transmit_burst(((uint32_t) ((uint16_t) xc0)) + (((uint32_t) ((uint16_t) yc0)) << 16U)); + spi_transmit_burst(((uint32_t) wid) + (((uint32_t) hgt) << 16U)); + spi_transmit_burst(((uint32_t) options) + (((uint32_t) val) << 16U)); + spi_transmit_burst(((uint32_t) size) + (((uint32_t) range) << 16U)); +} + +/** + * @brief Set the base for number output. + */ +void EVE_cmd_setbase(uint32_t base) +{ + if (0U == cmd_burst) + { + eve_begin_cmd(CMD_SETBASE); + spi_transmit_32(base); + EVE_cs_clear(); + } + else + { + spi_transmit_burst(CMD_SETBASE); + spi_transmit_burst(base); + } +} + +/** + * @brief Set the base for number output, only works in burst-mode. + */ +void EVE_cmd_setbase_burst(uint32_t base) +{ + spi_transmit_burst(CMD_SETBASE); + spi_transmit_burst(base); +} + +/** + * @brief Generate the corresponding display list commands for given bitmap information. + */ +void EVE_cmd_setbitmap(uint32_t addr, uint16_t fmt, uint16_t width, + uint16_t height) +{ + if (0U == cmd_burst) + { + eve_begin_cmd(CMD_SETBITMAP); + spi_transmit_32(addr); + spi_transmit((uint8_t) (fmt)); + spi_transmit((uint8_t) (fmt >> 8U)); + spi_transmit((uint8_t) (width)); + spi_transmit((uint8_t) (width >> 8U)); + spi_transmit((uint8_t) (height)); + spi_transmit((uint8_t) (height >> 8U)); + spi_transmit(0U); + spi_transmit(0U); + EVE_cs_clear(); + } + else + { + spi_transmit_burst(CMD_SETBITMAP); + spi_transmit_burst(addr); + spi_transmit_burst(((uint32_t) fmt) + (((uint32_t) width) << 16U)); + spi_transmit_burst((uint32_t) height); + } +} + +/** + * @brief Generate the corresponding display list commands for given bitmap information, only works in burst-mode. + */ +void EVE_cmd_setbitmap_burst(uint32_t addr, uint16_t fmt, uint16_t width, + uint16_t height) +{ + spi_transmit_burst(CMD_SETBITMAP); + spi_transmit_burst(addr); + spi_transmit_burst(((uint32_t) fmt) + (((uint32_t) width) << 16U)); + spi_transmit_burst((uint32_t) height); +} + +/** + * @brief Register one custom font into the coprocessor engine. + * @note - does not set up the bitmap parameters of the font + */ +void EVE_cmd_setfont(uint32_t font, uint32_t ptr) +{ + if (0U == cmd_burst) + { + eve_begin_cmd(CMD_SETFONT); + spi_transmit_32(font); + spi_transmit_32(ptr); + EVE_cs_clear(); + } + else + { + spi_transmit_burst(CMD_SETFONT); + spi_transmit_burst(font); + spi_transmit_burst(ptr); + } +} + +/** + * @brief Register one custom font into the coprocessor engine, only works in burst-mode. + * @note - does not set up the bitmap parameters of the font + */ +void EVE_cmd_setfont_burst(uint32_t font, uint32_t ptr) +{ + spi_transmit_burst(CMD_SETFONT); + spi_transmit_burst(font); + spi_transmit_burst(ptr); +} + +/** + * @brief Set up a custom for use by the coprocessor engine. + * @note - generates display list commands, so it needs to be put in a display list + */ +void EVE_cmd_setfont2(uint32_t font, uint32_t ptr, uint32_t firstchar) +{ + if (0U == cmd_burst) + { + eve_begin_cmd(CMD_SETFONT2); + spi_transmit_32(font); + spi_transmit_32(ptr); + spi_transmit_32(firstchar); + EVE_cs_clear(); + } + else + { + spi_transmit_burst(CMD_SETFONT2); + spi_transmit_burst(font); + spi_transmit_burst(ptr); + spi_transmit_burst(firstchar); + } +} + +/** + * @brief Set up a custom for use by the coprocessor engine, only works in burst-mode. + * @note - generates display list commands, so it needs to be put in a display list + */ +void EVE_cmd_setfont2_burst(uint32_t font, uint32_t ptr, uint32_t firstchar) +{ + spi_transmit_burst(CMD_SETFONT2); + spi_transmit_burst(font); + spi_transmit_burst(ptr); + spi_transmit_burst(firstchar); +} + +/** + * @brief Set the scratch bitmap for widget use. + */ +void EVE_cmd_setscratch(uint32_t handle) +{ + if (0U == cmd_burst) + { + eve_begin_cmd(CMD_SETSCRATCH); + spi_transmit_32(handle); + EVE_cs_clear(); + } + else + { + spi_transmit_burst(CMD_SETSCRATCH); + spi_transmit_burst(handle); + } +} + +/** + * @brief Set the scratch bitmap for widget use, only works in burst-mode. + */ +void EVE_cmd_setscratch_burst(uint32_t handle) +{ + spi_transmit_burst(CMD_SETSCRATCH); + spi_transmit_burst(handle); +} + +/** + * @brief Start a continuous sketch update. + */ +void EVE_cmd_sketch(int16_t xc0, int16_t yc0, uint16_t wid, uint16_t hgt, + uint32_t ptr, uint16_t format) +{ + if (0U == cmd_burst) + { + eve_begin_cmd(CMD_SKETCH); + spi_transmit((uint8_t) ((uint16_t) xc0)); + spi_transmit((uint8_t) (((uint16_t) xc0) >> 8U)); + spi_transmit((uint8_t) ((uint16_t) yc0)); + spi_transmit((uint8_t) (((uint16_t) yc0) >> 8U)); + spi_transmit((uint8_t) ((uint16_t) wid)); + spi_transmit((uint8_t) (((uint16_t) wid) >> 8U)); + spi_transmit((uint8_t) ((uint16_t) hgt)); + spi_transmit((uint8_t) (((uint16_t) hgt) >> 8U)); + spi_transmit_32(ptr); + spi_transmit((uint8_t) (format)); + spi_transmit((uint8_t) (format >> 8U)); + spi_transmit(0U); + spi_transmit(0U); + EVE_cs_clear(); + } + else + { + spi_transmit_burst(CMD_SKETCH); + spi_transmit_burst(((uint32_t) ((uint16_t) xc0)) + (((uint32_t) ((uint16_t) yc0)) << 16U)); + spi_transmit_burst(((uint32_t) ((uint16_t) wid)) + (((uint32_t) ((uint16_t) hgt)) << 16U)); + spi_transmit_burst(ptr); + spi_transmit_burst((uint32_t) format); + } +} + +/** + * @brief Start a continuous sketch update, only works in burst-mode. + */ +void EVE_cmd_sketch_burst(int16_t xc0, int16_t yc0, uint16_t wid, uint16_t hgt, + uint32_t ptr, uint16_t format) +{ + spi_transmit_burst(CMD_SKETCH); + spi_transmit_burst(((uint32_t) ((uint16_t) xc0)) + (((uint32_t) ((uint16_t) yc0)) << 16U)); + spi_transmit_burst(((uint32_t) ((uint16_t) wid)) + (((uint32_t) ((uint16_t) hgt)) << 16U)); + spi_transmit_burst(ptr); + spi_transmit_burst((uint32_t) format); +} + +/** + * @brief Draw a slider. + */ +void EVE_cmd_slider(int16_t xc0, int16_t yc0, uint16_t wid, uint16_t hgt, + uint16_t options, uint16_t val, uint16_t range) +{ + if (0U == cmd_burst) + { + eve_begin_cmd(CMD_SLIDER); + spi_transmit((uint8_t) ((uint16_t) xc0)); + spi_transmit((uint8_t) (((uint16_t) xc0) >> 8U)); + spi_transmit((uint8_t) ((uint16_t) yc0)); + spi_transmit((uint8_t) (((uint16_t) yc0) >> 8U)); + spi_transmit((uint8_t) (wid)); + spi_transmit((uint8_t) (wid >> 8U)); + spi_transmit((uint8_t) (hgt)); + spi_transmit((uint8_t) (hgt >> 8U)); + spi_transmit((uint8_t) (options)); + spi_transmit((uint8_t) (options >> 8U)); + spi_transmit((uint8_t) (val)); + spi_transmit((uint8_t) (val >> 8U)); + spi_transmit((uint8_t) (range)); + spi_transmit((uint8_t) (range >> 8U)); + spi_transmit(0U); /* dummy byte for 4-byte alignment */ + spi_transmit(0U); /* dummy byte for 4-byte alignment */ + EVE_cs_clear(); + } + else + { + spi_transmit_burst(CMD_SLIDER); + spi_transmit_burst(((uint32_t) ((uint16_t) xc0)) + (((uint32_t) ((uint16_t) yc0)) << 16U)); + spi_transmit_burst(((uint32_t) wid) + (((uint32_t) hgt) << 16U)); + spi_transmit_burst(((uint32_t) options) + (((uint32_t) val) << 16U)); + spi_transmit_burst((uint32_t) range); + } +} + +/** + * @brief Draw a slider, only works in burst-mode. + */ +void EVE_cmd_slider_burst(int16_t xc0, int16_t yc0, uint16_t wid, uint16_t hgt, + uint16_t options, uint16_t val, uint16_t range) +{ + spi_transmit_burst(CMD_SLIDER); + spi_transmit_burst(((uint32_t) ((uint16_t) xc0)) + (((uint32_t) ((uint16_t) yc0)) << 16U)); + spi_transmit_burst(((uint32_t) wid) + (((uint32_t) hgt) << 16U)); + spi_transmit_burst(((uint32_t) options) + (((uint32_t) val) << 16U)); + spi_transmit_burst((uint32_t) range); +} + +/** + * @brief Start an animated spinner. + */ +void EVE_cmd_spinner(int16_t xc0, int16_t yc0, uint16_t style, uint16_t scale) +{ + if (0U == cmd_burst) + { + eve_begin_cmd(CMD_SPINNER); + spi_transmit((uint8_t) ((uint16_t) xc0)); + spi_transmit((uint8_t) (((uint16_t) xc0) >> 8U)); + spi_transmit((uint8_t) ((uint16_t) yc0)); + spi_transmit((uint8_t) (((uint16_t) yc0) >> 8U)); + spi_transmit((uint8_t) (style)); + spi_transmit((uint8_t) (style >> 8U)); + spi_transmit((uint8_t) (scale)); + spi_transmit((uint8_t) (scale >> 8U)); + EVE_cs_clear(); + } + else + { + spi_transmit_burst(CMD_SPINNER); + spi_transmit_burst(((uint32_t) ((uint16_t) xc0)) + (((uint32_t) ((uint16_t) yc0)) << 16U)); + spi_transmit_burst(((uint32_t) style) + (((uint32_t) scale) << 16U)); + } +} + +/** + * @brief Start an animated spinner, only works in burst-mode. + */ +void EVE_cmd_spinner_burst(int16_t xc0, int16_t yc0, uint16_t style, + uint16_t scale) +{ + spi_transmit_burst(CMD_SPINNER); + spi_transmit_burst(((uint32_t) ((uint16_t) xc0)) + (((uint32_t) ((uint16_t) yc0)) << 16U)); + spi_transmit_burst(((uint32_t) style) + (((uint32_t) scale) << 16U)); +} + +/** + * @brief Draw a text string. + */ +void EVE_cmd_text(int16_t xc0, int16_t yc0, uint16_t font, uint16_t options, + const char *p_text) +{ + if (0U == cmd_burst) + { + eve_begin_cmd(CMD_TEXT); + spi_transmit((uint8_t) ((uint16_t) xc0)); + spi_transmit((uint8_t) (((uint16_t) xc0) >> 8U)); + spi_transmit((uint8_t) ((uint16_t) yc0)); + spi_transmit((uint8_t) (((uint16_t) yc0) >> 8U)); + spi_transmit((uint8_t) (font)); + spi_transmit((uint8_t) (font >> 8U)); + spi_transmit((uint8_t) (options)); + spi_transmit((uint8_t) (options >> 8U)); + private_string_write(p_text); + EVE_cs_clear(); + } + else + { + spi_transmit_burst(CMD_TEXT); + spi_transmit_burst(((uint32_t) ((uint16_t) xc0)) + (((uint32_t) ((uint16_t) yc0)) << 16U)); + spi_transmit_burst(((uint32_t) font) + (((uint32_t) options) << 16U)); + private_string_write(p_text); + } +} + +/** + * @brief Draw a text string, only works in burst-mode. + */ +void EVE_cmd_text_burst(int16_t xc0, int16_t yc0, uint16_t font, + uint16_t options, const char *p_text) +{ + spi_transmit_burst(CMD_TEXT); + spi_transmit_burst(((uint32_t) ((uint16_t) xc0)) + (((uint32_t) ((uint16_t) yc0)) << 16U)); + spi_transmit_burst(((uint32_t) font) + (((uint32_t) options) << 16U)); + private_string_write(p_text); +} + +/** + * @brief Draw a toggle switch with labels. + */ +void EVE_cmd_toggle(int16_t xc0, int16_t yc0, uint16_t wid, uint16_t font, + uint16_t options, uint16_t state, const char *p_text) +{ + if (0U == cmd_burst) + { + eve_begin_cmd(CMD_TOGGLE); + spi_transmit((uint8_t) ((uint16_t) xc0)); + spi_transmit((uint8_t) (((uint16_t) xc0) >> 8U)); + spi_transmit((uint8_t) ((uint16_t) yc0)); + spi_transmit((uint8_t) (((uint16_t) yc0) >> 8U)); + spi_transmit((uint8_t) (wid)); + spi_transmit((uint8_t) (wid >> 8U)); + spi_transmit((uint8_t) (font)); + spi_transmit((uint8_t) (font >> 8U)); + spi_transmit((uint8_t) (options)); + spi_transmit((uint8_t) (options >> 8U)); + spi_transmit((uint8_t) (state)); + spi_transmit((uint8_t) (state >> 8U)); + private_string_write(p_text); + EVE_cs_clear(); + } + else + { + spi_transmit_burst(CMD_TOGGLE); + spi_transmit_burst(((uint32_t) ((uint16_t) xc0)) + (((uint32_t) ((uint16_t) yc0)) << 16U)); + spi_transmit_burst(((uint32_t) wid) + (((uint32_t) font) << 16U)); + spi_transmit_burst(((uint32_t) options) + (((uint32_t) state) << 16U)); + private_string_write(p_text); + } +} + +/** + * @brief Draw a toggle switch with labels, only works in burst-mode. + */ +void EVE_cmd_toggle_burst(int16_t xc0, int16_t yc0, uint16_t wid, uint16_t font, + uint16_t options, uint16_t state, const char *p_text) +{ + spi_transmit_burst(CMD_TOGGLE); + spi_transmit_burst(((uint32_t) ((uint16_t) xc0)) + (((uint32_t) ((uint16_t) yc0)) << 16U)); + spi_transmit_burst(((uint32_t) wid) + (((uint32_t) font) << 16U)); + spi_transmit_burst(((uint32_t) options) + (((uint32_t) state) << 16U)); + private_string_write(p_text); +} + +/** + * @brief Apply a translation to the current matrix. + */ +void EVE_cmd_translate(int32_t tr_x, int32_t tr_y) +{ + if (0U == cmd_burst) + { + eve_begin_cmd(CMD_TRANSLATE); + spi_transmit_32((uint32_t) tr_x); + spi_transmit_32((uint32_t) tr_y); + EVE_cs_clear(); + } + else + { + spi_transmit_burst(CMD_TRANSLATE); + spi_transmit_burst((uint32_t) tr_x); + spi_transmit_burst((uint32_t) tr_y); + } +} + +/** + * @brief Apply a translation to the current matrix, only works in burst-mode. + */ +void EVE_cmd_translate_burst(int32_t tr_x, int32_t tr_y) +{ + spi_transmit_burst(CMD_TRANSLATE); + spi_transmit_burst((uint32_t) tr_x); + spi_transmit_burst((uint32_t) tr_y); +} + +/** + * @brief Set the current color red, green and blue. + */ +void EVE_color_rgb(uint32_t color) +{ + EVE_cmd_dl(DL_COLOR_RGB | (color & 0x00ffffffUL)); +} + +/** + * @brief Set the current color red, green and blue, only works in burst-mode. + */ +void EVE_color_rgb_burst(uint32_t color) +{ + spi_transmit_burst(DL_COLOR_RGB | (color & 0x00ffffffUL)); +} + +/** + * @brief Set the current color alpha, green and blue. + */ +void EVE_color_a(uint8_t alpha) +{ + EVE_cmd_dl(DL_COLOR_A | ((uint32_t) alpha)); +} + +/** + * @brief Set the current color alpha, green and blue, only works in burst-mode. + */ +void EVE_color_a_burst(uint8_t alpha) +{ + spi_transmit_burst(DL_COLOR_A | ((uint32_t) alpha)); +} + + +/* ################################################################## + special purpose functions +##################################################################### */ + +/* This is meant to be called outside display-list building. */ +/* This function displays an interactive calibration screen, calculates the calibration values */ +/* and writes the new values to the touch matrix registers of EVE.*/ +/* Unlike the built-in cmd_calibrate() of EVE this also works with displays that are cut down from larger ones like + * EVE2-38A / EVE2-38G. */ +/* The dimensions are needed as parameter as EVE_VSIZE for the EVE2-38 is 272 but the visible size is only 116. */ +/* So the call would be EVE_calibrate_manual(EVE_HSIZE, 116); for the EVE2-38A and EVE2-38G while for most other + * displays */ +/* using EVE_calibrate_manual(EVE_VSIZE, EVE_VSIZE) would work - but for normal displays the built-in cmd_calibrate + * would work as expected anyways */ +/* This code was taken from the MatrixOrbital EVE2-Library on Github, adapted and modified */ +void EVE_calibrate_manual(uint16_t width, uint16_t height) +{ + int32_t display_x[3U]; + int32_t display_y[3U]; + int32_t touch_x[3U]; + int32_t touch_y[3U]; + uint32_t touch_value; + int32_t tmp; + int32_t divi; + int32_t trans_matrix[6U]; + uint8_t count = 0U; + uint8_t calc = 0U; + uint32_t calc32 = 0U; + char num[4U]; + uint8_t touch_lock = 1U; + + /* these values determine where your calibration points will be drawn on your display */ + display_x[0U] = (int32_t) width / 6; + display_y[0U] = (int32_t) height / 6; + + display_x[1U] = (int32_t) width - ((int32_t) width / 8); + display_y[1U] = (int32_t) height / 2; + + display_x[2U] = (int32_t) width / 2; + display_y[2U] = (int32_t) height - ((int32_t) height / 8); + + while (count < 3U) + { + EVE_cmd_dl(CMD_DLSTART); + EVE_cmd_dl(DL_CLEAR_COLOR_RGB); + EVE_cmd_dl(DL_CLEAR | CLR_COL | CLR_STN | CLR_TAG); + EVE_cmd_dl(DL_VERTEX_FORMAT); /* set to 0 - reduce precision for VERTEX2F to 1 pixel instead of 1/16 pixel default */ + + /* draw Calibration Point on screen */ + EVE_cmd_dl(DL_COLOR_RGB | 0x0000ffUL); + EVE_cmd_dl(POINT_SIZE(15U * 16U)); + EVE_cmd_dl((DL_BEGIN | EVE_POINTS)); + + int16_t xc0; + int16_t yc0; + + xc0 = (int16_t) display_x[count]; + yc0 = (int16_t) display_y[count]; + EVE_cmd_dl(VERTEX2F(xc0, yc0)); + EVE_cmd_dl(DL_END); + EVE_cmd_dl(DL_COLOR_RGB | 0xffffffUL); + EVE_cmd_text((int16_t) width / 2, 20, 26U, EVE_OPT_CENTER, "tap on the dot"); + calc = count + 0x31U; + num[0U] = (char) calc; + num[1U] = (char) 0U; /* null terminated string of one character */ + EVE_cmd_text((int16_t) display_x[count], (int16_t) display_y[count], 27U, EVE_OPT_CENTER, num); + + EVE_cmd_dl(DL_DISPLAY); + EVE_cmd_dl(CMD_SWAP); + EVE_execute_cmd(); + + for (;;) + { + touch_value = EVE_memRead32(REG_TOUCH_DIRECT_XY); /* read for any new touch tag inputs */ + + if (touch_lock != 0U) + { + if ((touch_value & 0x80000000UL) != 0UL) /* check if we have no touch */ + { + touch_lock = 0U; + } + } + else + { + if (0UL == (touch_value & 0x80000000UL)) /* check if a touch is detected */ + { + calc32 = ((touch_value >> 16U) & 0x03FFUL); + touch_x[count] = (int32_t) calc32; /* raw Touchscreen X coordinate */ + calc32 = touch_value & 0x03FFUL; + touch_y[count] = (int32_t) calc32; /* raw Touchscreen Y coordinate */ + touch_lock = 1U; + count++; + break; /* leave for (;;) */ + } + } + } + } + + divi = ((touch_x[0U] - touch_x[2U]) * (touch_y[1U] - touch_y[2U])) - ((touch_x[1U] - touch_x[2U]) * (touch_y[0U] - touch_y[2U])); + + tmp = (((display_x[0U] - display_x[2U]) * (touch_y[1U] - touch_y[2U])) - + ((display_x[1U] - display_x[2U]) * (touch_y[0U] - touch_y[2U]))); + trans_matrix[0U] = (int32_t) (((int64_t) tmp * 65536) / divi); + + tmp = (((touch_x[0U] - touch_x[2U]) * (display_x[1U] - display_x[2U])) - + ((display_x[0U] - display_x[2U]) * (touch_x[1U] - touch_x[2U]))); + trans_matrix[1U] = (int32_t) (((int64_t) tmp * 65536) / divi); + + tmp = ((touch_y[0U] * (((touch_x[2U] * display_x[1U]) - (touch_x[1U] * display_x[2U])))) + + (touch_y[1U] * (((touch_x[0U] * display_x[2U]) - (touch_x[2U] * display_x[0U])))) + + (touch_y[2U] * (((touch_x[1U] * display_x[0U]) - (touch_x[0U] * display_x[1U]))))); + trans_matrix[2U] = (int32_t) (((int64_t) tmp * 65536) / divi); + + tmp = (((display_y[0U] - display_y[2U]) * (touch_y[1U] - touch_y[2U])) - + ((display_y[1U] - display_y[2U]) * (touch_y[0U] - touch_y[2U]))); + trans_matrix[3U] = (int32_t) (((int64_t) tmp * 65536) / divi); + + tmp = (((touch_x[0U] - touch_x[2U]) * (display_y[1U] - display_y[2U])) - + ((display_y[0U] - display_y[2U]) * (touch_x[1U] - touch_x[2U]))); + trans_matrix[4U] = (int32_t) (((int64_t) tmp * 65536) / divi); + + tmp = ((touch_y[0U] * (((touch_x[2U] * display_y[1U]) - (touch_x[1U] * display_y[2U])))) + + (touch_y[1U] * (((touch_x[0U] * display_y[2U]) - (touch_x[2U] * display_y[0U])))) + + (touch_y[2U] * (((touch_x[1U] * display_y[0U]) - (touch_x[0U] * display_y[1U]))))); + trans_matrix[5U] = (int32_t) (((int64_t) tmp * 65536) / divi); + + EVE_memWrite32(REG_TOUCH_TRANSFORM_A, (uint32_t) trans_matrix[0U]); + EVE_memWrite32(REG_TOUCH_TRANSFORM_B, (uint32_t) trans_matrix[1U]); + EVE_memWrite32(REG_TOUCH_TRANSFORM_C, (uint32_t) trans_matrix[2U]); + EVE_memWrite32(REG_TOUCH_TRANSFORM_D, (uint32_t) trans_matrix[3U]); + EVE_memWrite32(REG_TOUCH_TRANSFORM_E, (uint32_t) trans_matrix[4U]); + EVE_memWrite32(REG_TOUCH_TRANSFORM_F, (uint32_t) trans_matrix[5U]); +} + +#endif /*LV_USE_DRAW_EVE*/ diff --git a/src/libs/FT800-FT813/EVE_commands.h b/src/libs/FT800-FT813/EVE_commands.h new file mode 100644 index 0000000000..144d7ed38f --- /dev/null +++ b/src/libs/FT800-FT813/EVE_commands.h @@ -0,0 +1,339 @@ +/* +@file EVE_commands.h +@brief contains FT8xx / BT8xx function prototypes +@version 5.0 +@date 2023-12-29 +@author Rudolph Riedel + +@section LICENSE + +MIT License + +Copyright (c) 2016-2023 Rudolph Riedel + +Permission is hereby granted, free of charge, to any person obtaining a copy of +this software and associated documentation files (the "Software"), to deal in +the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, +and/or sell copies of the Software, and to permit persons to whom the Software +is furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS +FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR +COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER +IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +@section History + +5.0 +- added prototype for EVE_cmd_plkfreq() +- replaced BT81X_ENABLE with "EVE_GEN > 2" +- removed FT81X_ENABLE as FT81x already is the lowest supported chip revision now +- removed the formerly as deprected marked EVE_get_touch_tag() +- changed EVE_color_rgb() to use a 32 bit value like the rest of the color commands +- removed the meta-commands EVE_cmd_point(), EVE_cmd_line() and EVE_cmd_rect() +- removed obsolete functions EVE_get_cmdoffset(void) and EVE_report_cmdoffset(void) - cmdoffset is gone +- renamed EVE_LIB_GetProps() back to EVE_cmd_getprops() since it does not do anything special to justify a special name +- added prototype for helper function EVE_memWrite_sram_buffer() +- added prototypes for EVE_cmd_bitmap_transform() and EVE_cmd_bitmap_transform_burst() +- added prototype for EVE_cmd_playvideo() +- added prototypes for EVE_cmd_setfont_burst() and EVE_cmd_setfont2_burst() +- added prototype for EVE_cmd_videoframe() +- restructured: functions are sorted by chip-generation and within their group in alphabetical order +- reimplementedEVE_cmd_getmatrix() again, it needs to read values, not write them +- added prototypes for EVE_cmd_fontcache() and EVE_cmd_fontcachequery() +- added prototype for EVE_cmd_flashprogram() +- added prototype for EVE_cmd_calibratesub() +- added prototypes for EVE_cmd_animframeram(), EVE_cmd_animframeram_burst(), EVE_cmd_animstartram(), +EVE_cmd_animstartram_burst() +- added prototypes for EVE_cmd_apilevel(), EVE_cmd_apilevel_burst() +- added prototypes for EVE_cmd_calllist(), EVE_cmd_calllist_burst() +- added prototype for EVE_cmd_getimage() +- added prototypes for EVE_cmd_hsf(), EVE_cmd_hsf_burst() +- added prototype for EVE_cmd_linetime() +- added prototypes for EVE_cmd_newlist(), EVE_cmd_newlist_burst() +- added prototypes for EVE_cmd_runanim(), EVE_cmd_runanim_burst() +- added prototype for EVE_cmd_wait() +- removed the history from before 4.0 +- added an enum with return codes to have the functions return something more meaningfull +- finally removed EVE_cmd_start() after setting it to deprecatd with the first 5.0 release +- renamed EVE_cmd_execute() to EVE_execute_cmd() to be more consistent, this is is not an EVE command +- added the return-value of EVE_FIFO_HALF_EMPTY to EVE_busy() to indicate there is more than 2048 bytes available +- removed the 4.0 history +- added parameter width to EVE_calibrate_manual() +- changed the varargs versions of cmd_button, cmd_text and cmd_toggle to use an array of uint32_t values to comply with MISRA-C +- fixed some MISRA-C issues +- basic maintenance: checked for violations of white space and indent rules +- more linter fixes for minor issues like variables shorter than 3 characters +- added EVE_color_a() / EVE_color_a_burst() +- removed EVE_cmd_newlist_burst() prototype as the function got removed earlier +- added prototype for EVE_write_display_parameters() +- added EVE_memRead_sram_buffer() +- added EVE_FAULT_RECOVERED to the list of return codes +- added defines for the state of the external flash +- added protype for EVE_get_and_reset_fault_state() +- put E_OK and E_NOT_OK in #ifndef/#endif guards as these are usually defined + already in AUTOSAR projects +- renamed EVE_FAIL_CHIPID_TIMEOUT to EVE_FAIL_REGID_TIMEOUT as suggested by #93 on github +- changed a number of function parameters from signed to unsigned following the + updated BT81x series programming guide V2.4 +- commented out EVE_cmd_regread() prototype +- removed prototype for EVE_cmd_hsf_burst() + +*/ + +#ifndef EVE_COMMANDS_H +#define EVE_COMMANDS_H + +#include "EVE.h" + +#if !defined E_OK +#define E_OK 0U +#endif + +#if !defined E_NOT_OK +#define E_NOT_OK 1U +#endif + +#define EVE_FAIL_REGID_TIMEOUT 2U +#define EVE_FAIL_RESET_TIMEOUT 3U +#define EVE_FAIL_PCLK_FREQ 4U +#define EVE_FAIL_FLASH_STATUS_INIT 5U +#define EVE_FAIL_FLASH_STATUS_DETACHED 6U +#define EVE_FAIL_FLASHFAST_NOT_SUPPORTED 7U +#define EVE_FAIL_FLASHFAST_NO_HEADER_DETECTED 8U +#define EVE_FAIL_FLASHFAST_SECTOR0_FAILED 9U +#define EVE_FAIL_FLASHFAST_BLOB_MISMATCH 10U +#define EVE_FAIL_FLASHFAST_SPEED_TEST 11U +#define EVE_IS_BUSY 12U +#define EVE_FIFO_HALF_EMPTY 13U +#define EVE_FAULT_RECOVERED 14U + +#define EVE_FLASH_STATUS_INIT 0U +#define EVE_FLASH_STATUS_DETACHED 1U +#define EVE_FLASH_STATUS_BASIC 2U +#define EVE_FLASH_STATUS_FULL 3U + +/* ################################################################## + helper functions +##################################################################### */ + +void EVE_cmdWrite(uint8_t const command, uint8_t const parameter); + +uint8_t EVE_memRead8(uint32_t const ft_address); +uint16_t EVE_memRead16(uint32_t const ft_address); +uint32_t EVE_memRead32(uint32_t const ft_address); +void EVE_memWrite8(uint32_t const ft_address, uint8_t const ft_data); +void EVE_memWrite16(uint32_t const ft_address, uint16_t const ft_data); +void EVE_memWrite32(uint32_t const ft_address, uint32_t const ft_data); +void EVE_memWrite_flash_buffer(uint32_t const ft_address, const uint8_t *p_data, uint32_t const len); +void EVE_memWrite_sram_buffer(uint32_t const ft_address, const uint8_t *p_data, uint32_t const len); +void EVE_memRead_sram_buffer(uint32_t const ft_address, uint8_t *p_data, uint32_t const len); +uint8_t EVE_busy(void); +uint8_t EVE_get_and_reset_fault_state(void); +void EVE_execute_cmd(void); + +/* ################################################################## + commands and functions to be used outside of display-lists +##################################################################### */ + +/* EVE4: BT817 / BT818 */ +#if EVE_GEN > 3 + +void EVE_cmd_flashprogram(uint32_t dest, uint32_t src, uint32_t num); +void EVE_cmd_fontcache(uint32_t font, uint32_t ptr, uint32_t num); +void EVE_cmd_fontcachequery(uint32_t *p_total, uint32_t *p_used); +void EVE_cmd_getimage(uint32_t *p_source, uint32_t *p_fmt, uint32_t *p_width, uint32_t *p_height, uint32_t *p_palette); +void EVE_cmd_linetime(uint32_t dest); +void EVE_cmd_newlist(uint32_t adr); +uint32_t EVE_cmd_pclkfreq(uint32_t ftarget, int32_t rounding); +void EVE_cmd_wait(uint32_t usec); + +#endif /* EVE_GEN > 3 */ + +/* EVE3: BT815 / BT816 */ +#if EVE_GEN > 2 + +void EVE_cmd_clearcache(void); +void EVE_cmd_flashattach(void); +void EVE_cmd_flashdetach(void); +void EVE_cmd_flasherase(void); +uint32_t EVE_cmd_flashfast(void); +void EVE_cmd_flashspidesel(void); +void EVE_cmd_flashread(uint32_t dest, uint32_t src, uint32_t num); +void EVE_cmd_flashsource(uint32_t ptr); +void EVE_cmd_flashspirx(uint32_t dest, uint32_t num); +void EVE_cmd_flashspitx(uint32_t num, const uint8_t *p_data); +void EVE_cmd_flashupdate(uint32_t dest, uint32_t src, uint32_t num); +void EVE_cmd_flashwrite(uint32_t ptr, uint32_t num, const uint8_t *p_data); +void EVE_cmd_inflate2(uint32_t ptr, uint32_t options, const uint8_t *p_data, uint32_t len); + +#endif /* EVE_GEN > 2 */ + +void EVE_cmd_getprops(uint32_t *p_pointer, uint32_t *p_width, uint32_t *p_height); +uint32_t EVE_cmd_getptr(void); +void EVE_cmd_inflate(uint32_t ptr, const uint8_t *p_data, uint32_t len); +void EVE_cmd_interrupt(uint32_t msec); +void EVE_cmd_loadimage(uint32_t ptr, uint32_t options, const uint8_t *p_data, uint32_t len); +void EVE_cmd_mediafifo(uint32_t ptr, uint32_t size); +void EVE_cmd_memcpy(uint32_t dest, uint32_t src, uint32_t num); +uint32_t EVE_cmd_memcrc(uint32_t ptr, uint32_t num); +void EVE_cmd_memset(uint32_t ptr, uint8_t value, uint32_t num); +void EVE_cmd_memzero(uint32_t ptr, uint32_t num); +void EVE_cmd_playvideo(uint32_t options, const uint8_t *p_data, uint32_t len); +void EVE_cmd_setrotate(uint32_t rotation); +void EVE_cmd_snapshot(uint32_t ptr); +void EVE_cmd_snapshot2(uint32_t fmt, uint32_t ptr, int16_t xc0, int16_t yc0, uint16_t wid, uint16_t hgt); +void EVE_cmd_track(int16_t xc0, int16_t yc0, uint16_t wid, uint16_t hgt, uint16_t tag); +void EVE_cmd_videoframe(uint32_t dest, uint32_t result_ptr); +/*void EVE_cmd_memwrite(uint32_t dest, uint32_t num, const uint8_t *p_data);*/ +/*uint32_t EVE_cmd_regread(uint32_t ptr);*/ + +/* ################################################################## + patching and initialization +##################################################################### */ + +#if EVE_GEN > 2 +uint8_t EVE_init_flash(void); +#endif /* EVE_GEN > 2 */ + +void EVE_write_display_parameters(void); +uint8_t EVE_init(void); + +/* ################################################################## + functions for display lists +##################################################################### */ + +void EVE_start_cmd_burst(void); +void EVE_end_cmd_burst(void); + +/* EVE4: BT817 / BT818 */ +#if EVE_GEN > 3 + +void EVE_cmd_animframeram(int16_t xc0, int16_t yc0, uint32_t aoptr, uint32_t frame); +void EVE_cmd_animframeram_burst(int16_t xc0, int16_t yc0, uint32_t aoptr, uint32_t frame); +void EVE_cmd_animstartram(int32_t chnl, uint32_t aoptr, uint32_t loop); +void EVE_cmd_animstartram_burst(int32_t chnl, uint32_t aoptr, uint32_t loop); +void EVE_cmd_apilevel(uint32_t level); +void EVE_cmd_apilevel_burst(uint32_t level); +void EVE_cmd_calibratesub(uint16_t xc0, uint16_t yc0, uint16_t width, uint16_t height); +void EVE_cmd_calllist(uint32_t adr); +void EVE_cmd_calllist_burst(uint32_t adr); +void EVE_cmd_hsf(uint32_t hsf); +void EVE_cmd_runanim(uint32_t waitmask, uint32_t play); +void EVE_cmd_runanim_burst(uint32_t waitmask, uint32_t play); + +#endif /* EVE_GEN > 3 */ + +/* EVE3: BT815 / BT816 */ +#if EVE_GEN > 2 + +void EVE_cmd_animdraw(int32_t chnl); +void EVE_cmd_animdraw_burst(int32_t chnl); +void EVE_cmd_animframe(int16_t xc0, int16_t yc0, uint32_t aoptr, uint32_t frame); +void EVE_cmd_animframe_burst(int16_t xc0, int16_t yc0, uint32_t aoptr, uint32_t frame); +void EVE_cmd_animstart(int32_t chnl, uint32_t aoptr, uint32_t loop); +void EVE_cmd_animstart_burst(int32_t chnl, uint32_t aoptr, uint32_t loop); +void EVE_cmd_animstop(int32_t chnl); +void EVE_cmd_animstop_burst(int32_t chnl); +void EVE_cmd_animxy(int32_t chnl, int16_t xc0, int16_t yc0); +void EVE_cmd_animxy_burst(int32_t chnl, int16_t xc0, int16_t yc0); +void EVE_cmd_appendf(uint32_t ptr, uint32_t num); +void EVE_cmd_appendf_burst(uint32_t ptr, uint32_t num); +uint16_t EVE_cmd_bitmap_transform(int32_t xc0, int32_t yc0, int32_t xc1, int32_t yc1, int32_t xc2, int32_t yc2, int32_t tx0, + int32_t ty0, int32_t tx1, int32_t ty1, int32_t tx2, int32_t ty2); +void EVE_cmd_bitmap_transform_burst(int32_t xc0, int32_t yc0, int32_t xc1, int32_t yc1, int32_t xc2, int32_t yc2, int32_t tx0, + int32_t ty0, int32_t tx1, int32_t ty1, int32_t tx2, int32_t ty2); +void EVE_cmd_fillwidth(uint32_t pixel); +void EVE_cmd_fillwidth_burst(uint32_t pixel); +void EVE_cmd_gradienta(int16_t xc0, int16_t yc0, uint32_t argb0, int16_t xc1, int16_t yc1, uint32_t argb1); +void EVE_cmd_gradienta_burst(int16_t xc0, int16_t yc0, uint32_t argb0, int16_t xc1, int16_t yc1, uint32_t argb1); +void EVE_cmd_rotatearound(int32_t xc0, int32_t yc0, uint32_t angle, int32_t scale); +void EVE_cmd_rotatearound_burst(int32_t xc0, int32_t yc0, uint32_t angle, int32_t scale); + +void EVE_cmd_button_var(int16_t xc0, int16_t yc0, uint16_t wid, uint16_t hgt, uint16_t font, uint16_t options, const char *p_text, uint8_t num_args, const uint32_t p_arguments[]); +void EVE_cmd_button_var_burst(int16_t xc0, int16_t yc0, uint16_t wid, uint16_t hgt, uint16_t font, uint16_t options, const char *p_text, uint8_t num_args, const uint32_t p_arguments[]); +void EVE_cmd_text_var(int16_t xc0, int16_t yc0, uint16_t font, uint16_t options, const char *p_text, uint8_t num_args, const uint32_t p_arguments[]); +void EVE_cmd_text_var_burst(int16_t xc0, int16_t yc0, uint16_t font, uint16_t options, const char *p_text, uint8_t num_args, const uint32_t p_arguments[]); +void EVE_cmd_toggle_var(int16_t xc0, int16_t yc0, uint16_t wid, uint16_t font, uint16_t options, uint16_t state, const char *p_text, uint8_t num_args, const uint32_t p_arguments[]); +void EVE_cmd_toggle_var_burst(int16_t xc0, int16_t yc0, uint16_t wid, uint16_t font, uint16_t options, uint16_t state, const char *p_text, uint8_t num_args, const uint32_t p_arguments[]); + +#endif /* EVE_GEN > 2 */ + +void EVE_cmd_dl(uint32_t command); +void EVE_cmd_dl_burst(uint32_t command); + +void EVE_cmd_append(uint32_t ptr, uint32_t num); +void EVE_cmd_append_burst(uint32_t ptr, uint32_t num); +void EVE_cmd_bgcolor(uint32_t color); +void EVE_cmd_bgcolor_burst(uint32_t color); +void EVE_cmd_button(int16_t xc0, int16_t yc0, uint16_t wid, uint16_t hgt, uint16_t font, uint16_t options, const char *p_text); +void EVE_cmd_button_burst(int16_t xc0, int16_t yc0, uint16_t wid, uint16_t hgt, uint16_t font, uint16_t options, const char *p_text); +void EVE_cmd_calibrate(void); +void EVE_cmd_clock(int16_t xc0, int16_t yc0, uint16_t rad, uint16_t options, uint16_t hours, uint16_t mins, uint16_t secs, uint16_t msecs); +void EVE_cmd_clock_burst(int16_t xc0, int16_t yc0, uint16_t rad, uint16_t options, uint16_t hours, uint16_t mins, uint16_t secs, uint16_t msecs); +void EVE_cmd_dial(int16_t xc0, int16_t yc0, uint16_t rad, uint16_t options, uint16_t val); +void EVE_cmd_dial_burst(int16_t xc0, int16_t yc0, uint16_t rad, uint16_t options, uint16_t val); +void EVE_cmd_fgcolor(uint32_t color); +void EVE_cmd_fgcolor_burst(uint32_t color); +void EVE_cmd_gauge(int16_t xc0, int16_t yc0, uint16_t rad, uint16_t options, uint16_t major, uint16_t minor, uint16_t val, uint16_t range); +void EVE_cmd_gauge_burst(int16_t xc0, int16_t yc0, uint16_t rad, uint16_t options, uint16_t major, uint16_t minor, uint16_t val, uint16_t range); +void EVE_cmd_getmatrix(int32_t *p_a, int32_t *p_b, int32_t *p_c, int32_t *p_d, int32_t *p_e, int32_t *p_f); +void EVE_cmd_gradcolor(uint32_t color); +void EVE_cmd_gradcolor_burst(uint32_t color); +void EVE_cmd_gradient(int16_t xc0, int16_t yc0, uint32_t rgb0, int16_t xc1, int16_t yc1, uint32_t rgb1); +void EVE_cmd_gradient_burst(int16_t xc0, int16_t yc0, uint32_t rgb0, int16_t xc1, int16_t yc1, uint32_t rgb1); +void EVE_cmd_keys(int16_t xc0, int16_t yc0, uint16_t wid, uint16_t hgt, uint16_t font, uint16_t options, const char *p_text); +void EVE_cmd_keys_burst(int16_t xc0, int16_t yc0, uint16_t wid, uint16_t hgt, uint16_t font, uint16_t options, const char *p_text); +void EVE_cmd_number(int16_t xc0, int16_t yc0, uint16_t font, uint16_t options, int32_t number); +void EVE_cmd_number_burst(int16_t xc0, int16_t yc0, uint16_t font, uint16_t options, int32_t number); +void EVE_cmd_progress(int16_t xc0, int16_t yc0, uint16_t wid, uint16_t hgt, uint16_t options, uint16_t val, uint16_t range); +void EVE_cmd_progress_burst(int16_t xc0, int16_t yc0, uint16_t wid, uint16_t hgt, uint16_t options, uint16_t val, uint16_t range); +void EVE_cmd_romfont(uint32_t font, uint32_t romslot); +void EVE_cmd_romfont_burst(uint32_t font, uint32_t romslot); +void EVE_cmd_rotate(uint32_t angle); +void EVE_cmd_rotate_burst(uint32_t angle); +void EVE_cmd_scale(int32_t scx, int32_t scy); +void EVE_cmd_scale_burst(int32_t scx, int32_t scy); +void EVE_cmd_scrollbar(int16_t xc0, int16_t yc0, uint16_t wid, uint16_t hgt, uint16_t options, uint16_t val, uint16_t size, uint16_t range); +void EVE_cmd_scrollbar_burst(int16_t xc0, int16_t yc0, uint16_t wid, uint16_t hgt, uint16_t options, uint16_t val, uint16_t size, uint16_t range); +void EVE_cmd_setbase(uint32_t base); +void EVE_cmd_setbase_burst(uint32_t base); +void EVE_cmd_setbitmap(uint32_t addr, uint16_t fmt, uint16_t width, uint16_t height); +void EVE_cmd_setbitmap_burst(uint32_t addr, uint16_t fmt, uint16_t width, uint16_t height); +void EVE_cmd_setfont(uint32_t font, uint32_t ptr); +void EVE_cmd_setfont_burst(uint32_t font, uint32_t ptr); +void EVE_cmd_setfont2(uint32_t font, uint32_t ptr, uint32_t firstchar); +void EVE_cmd_setfont2_burst(uint32_t font, uint32_t ptr, uint32_t firstchar); +void EVE_cmd_setscratch(uint32_t handle); +void EVE_cmd_setscratch_burst(uint32_t handle); +void EVE_cmd_sketch(int16_t xc0, int16_t yc0, uint16_t wid, uint16_t hgt, uint32_t ptr, uint16_t format); +void EVE_cmd_sketch_burst(int16_t xc0, int16_t yc0, uint16_t wid, uint16_t hgt, uint32_t ptr, uint16_t format); +void EVE_cmd_slider(int16_t xc0, int16_t yc0, uint16_t wid, uint16_t hgt, uint16_t options, uint16_t val, uint16_t range); +void EVE_cmd_slider_burst(int16_t xc0, int16_t yc0, uint16_t wid, uint16_t hgt, uint16_t options, uint16_t val, uint16_t range); +void EVE_cmd_spinner(int16_t xc0, int16_t yc0, uint16_t style, uint16_t scale); +void EVE_cmd_spinner_burst(int16_t xc0, int16_t yc0, uint16_t style, uint16_t scale); +void EVE_cmd_text(int16_t xc0, int16_t yc0, uint16_t font, uint16_t options, const char *p_text); +void EVE_cmd_text_burst(int16_t xc0, int16_t yc0, uint16_t font, uint16_t options, const char *p_text); +void EVE_cmd_toggle(int16_t xc0, int16_t yc0, uint16_t wid, uint16_t font, uint16_t options, uint16_t state, const char *p_text); +void EVE_cmd_toggle_burst(int16_t xc0, int16_t yc0, uint16_t wid, uint16_t font, uint16_t options, uint16_t state, const char *p_text); +void EVE_cmd_translate(int32_t tr_x, int32_t tr_y); +void EVE_cmd_translate_burst(int32_t tr_x, int32_t tr_y); + +void EVE_color_rgb(uint32_t color); +void EVE_color_rgb_burst(uint32_t color); +void EVE_color_a(uint8_t alpha); +void EVE_color_a_burst(uint8_t alpha); + +/* ################################################################## + special purpose functions +##################################################################### */ + +void EVE_calibrate_manual(uint16_t width, uint16_t height); + +#endif /* EVE_COMMANDS_H */ diff --git a/src/libs/FT800-FT813/EVE_config.h b/src/libs/FT800-FT813/EVE_config.h new file mode 100644 index 0000000000..0d51e63353 --- /dev/null +++ b/src/libs/FT800-FT813/EVE_config.h @@ -0,0 +1,26 @@ +#ifndef EVE_CONFIG_H +#define EVE_CONFIG_H + +#include "../../draw/eve/lv_draw_eve_private.h" + +#define EVE_HSIZE (lv_draw_eve_unit_g->params.hor_res) +#define EVE_VSIZE (lv_draw_eve_unit_g->params.ver_res) +#define EVE_VSYNC0 (lv_draw_eve_unit_g->params.vsync0) +#define EVE_VSYNC1 (lv_draw_eve_unit_g->params.vsync1) +#define EVE_VOFFSET (lv_draw_eve_unit_g->params.voffset) +#define EVE_VCYCLE (lv_draw_eve_unit_g->params.vcycle) +#define EVE_HSYNC0 (lv_draw_eve_unit_g->params.hsync0) +#define EVE_HSYNC1 (lv_draw_eve_unit_g->params.hsync1) +#define EVE_HOFFSET (lv_draw_eve_unit_g->params.hoffset) +#define EVE_HCYCLE (lv_draw_eve_unit_g->params.hcycle) +#define EVE_PCLK (lv_draw_eve_unit_g->params.pclk) +#define EVE_PCLKPOL (lv_draw_eve_unit_g->params.pclkpol) +#define EVE_SWIZZLE (lv_draw_eve_unit_g->params.swizzle) +#define EVE_CSPREAD (lv_draw_eve_unit_g->params.cspread) +#define EVE_HAS_CRYSTAL (lv_draw_eve_unit_g->params.has_crystal) +#define EVE_HAS_GT911 (lv_draw_eve_unit_g->params.has_gt911) +#define EVE_GEN LV_DRAW_EVE_EVE_GENERATION +#define EVE_BACKLIGHT_PWM (lv_draw_eve_unit_g->params.backlight_pwm) +#define EVE_BACKLIGHT_FREQ (lv_draw_eve_unit_g->params.backlight_freq) + +#endif /* EVE_CONFIG_H */ diff --git a/src/libs/FT800-FT813/EVE_supplemental.c b/src/libs/FT800-FT813/EVE_supplemental.c new file mode 100644 index 0000000000..988b62c739 --- /dev/null +++ b/src/libs/FT800-FT813/EVE_supplemental.c @@ -0,0 +1,145 @@ +#include "../../lv_conf_internal.h" +#if LV_USE_DRAW_EVE +/* +@file EVE_supplemental.h +@brief supplemental functions +@version 5.0 +@date 2023-12-23 +@author Rudolph Riedel + +@section LICENSE + +MIT License + +Copyright (c) 2016-2023 Rudolph Riedel + +Permission is hereby granted, free of charge, to any person obtaining a copy of +this software and associated documentation files (the "Software"), to deal in +the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, +and/or sell copies of the Software, and to permit persons to whom the Software +is furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS +FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR +COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER +IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +@section History + +5.0 +- added EVE_polar_cartesian() + +*/ + +#include "EVE_suppplemental.h" + +/* define NULL if it not already is */ +#ifndef NULL +#include +#endif + +#if defined (__AVR__) +#include +#else +#define PROGMEM +#endif + +/* + * @brief widget function to draw a circle + */ +void EVE_widget_circle(int16_t xc0, int16_t yc0, uint16_t radius, uint16_t border, uint32_t bgcolor) +{ + EVE_cmd_dl_burst(DL_SAVE_CONTEXT); + EVE_cmd_dl(DL_BEGIN | EVE_POINTS); + EVE_cmd_dl(POINT_SIZE(radius)); + EVE_cmd_dl(VERTEX2F(xc0, yc0)); + EVE_color_rgb(bgcolor); + EVE_cmd_dl(POINT_SIZE(radius - border)); + EVE_cmd_dl(VERTEX2F(xc0, yc0)); + EVE_cmd_dl(DL_END); + EVE_cmd_dl_burst(DL_RESTORE_CONTEXT); +} + +/* + * @brief widget function to draw a rectangle + */ +void EVE_widget_rectangle(int16_t xc0, int16_t yc0, int16_t wid, int16_t hgt, int16_t border, uint16_t linewidth, uint32_t bgcolor) +{ + EVE_cmd_dl_burst(DL_SAVE_CONTEXT); + EVE_cmd_dl(DL_BEGIN | EVE_RECTS); + EVE_cmd_dl(LINE_WIDTH(linewidth)); + EVE_cmd_dl(VERTEX2F(xc0, yc0)); + EVE_cmd_dl(VERTEX2F(xc0 + wid, yc0 + hgt)); + EVE_color_rgb(bgcolor); + EVE_cmd_dl(VERTEX2F(xc0 + border, yc0 + border)); + EVE_cmd_dl(VERTEX2F(xc0 + wid - border, yc0 + hgt - border)); + EVE_cmd_dl(DL_END); + EVE_cmd_dl_burst(DL_RESTORE_CONTEXT); +} + +static const int8_t sine_table[360] PROGMEM = +{ + 0, 2, 4, 7, 9, 11, 13, 15, 18, 20, 22, 24, 26, 29, 31, 33, 35, 37, 39, 41, + 43, 46, 48, 50, 52, 54, 56, 58, 60, 62, 63, 65, 67, 69, 71, 73, 75, 76, 78, + 80, 82, 83, 85, 87, 88, 90, 91, 93, 94, 96, 97, 99, 100, 101, 103, 104, 105, + 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, 119, 120, + 121, 121, 122, 123, 123, 124, 124, 125, 125, 125, 126, 126, 126, 127, 127, + 127, 127, 127, 127, 127, 127, 127, 127, 127, 126, 126, 126, 125, 125, 125, + 124, 124, 123, 123, 122, 121, 121, 120, 119, 119, 118, 117, 116, 115, 114, + 113, 112, 111, 110, 109, 108, 107, 105, 104, 103, 101, 100, 99, 97, 96, 94, + 93, 91, 90, 88, 87, 85, 83, 82, 80, 78, 76, 75, 73, 71, 69, 67, 65, 63, 62, + 60, 58, 56, 54, 52, 50, 48, 46, 43, 41, 39, 37, 35, 33, 31, 29, 26, 24, 22, + 20, 18, 15, 13, 11, 9, 7, 4, 2, 0, -2, -4, -7, -9, -11, -13, -15, -18, -20, + -22, -24, -26, -29, -31, -33, -35, -37, -39, -41, -43, -46, -48, -50, -52, + -54, -56, -58, -60, -62, -63, -65, -67, -69, -71, -73, -75, -76, -78, -80, + -82, -83, -85, -87, -88, -90, -91, -93, -94, -96, -97, -99,-100,-101,-103, + -104, -105, -107, -108, -109, -110, -111, -112, -113, -114, -115, -116, + -117, -118, -119, -119, -120, -121, -121, -122, -123, -123, -124, -124, + -125, -125, -125, -126, -126, -126, -127, -127, -127, -127, -127, -127, + -127, -127, -127, -127, -127, -126, -126, -126, -125, -125, -125, -124, + -124, -123, -123, -122, -121, -121, -120, -119, -119, -118, -117, -116, + -115, -114, -113, -112, -111, -110, -109, -108, -107, -105, -104, -103, + -101, -100, -99, -97, -96, -94, -93, -91, -90, -88, -87, -85, -83, -82, + -80, -78, -76, -75, -73, -71, -69, -67, -65, -63, -62, -60, -58, -56, -54, + -52, -50, -48, -46, -43, -41, -39, -37, -35, -33, -31, -29, -26, -24, + -22, -20, -18, -15, -13, -11, -9, -7, -4, -2 +}; + +/** + * @brief Calculate coordinates from an angle and a length. + * @param length distance from coordinate origin (0,0) + * @param angle rotation in degrees + * @return signed X/Y coordinates for use with VERTEX2F + * @note - resolution for angle is 1° and rotation is clockwise + * @note - angle should be limited to a (n*360)-1 + */ +void EVE_polar_cartesian(uint16_t length, uint16_t angle, int16_t *p_xc0, int16_t *p_yc0) +{ + uint16_t anglev; + anglev = angle % 360U; + + if (p_xc0 != NULL) + { + int32_t calc = (int16_t) length; + calc = ((calc * (sine_table[anglev])) + 64) / 128; + *p_xc0 = (int16_t) calc; + } + + if (p_yc0 != NULL) + { + anglev = anglev + 270U; + anglev = anglev % 360U; + + int32_t calc = (int16_t) length; + calc = ((calc * (sine_table[anglev])) + 64) / 128; + *p_yc0 = (int16_t) calc; + } +} + +#endif /*LV_USE_DRAW_EVE*/ diff --git a/src/libs/FT800-FT813/EVE_suppplemental.h b/src/libs/FT800-FT813/EVE_suppplemental.h new file mode 100644 index 0000000000..c55a8dc9cd --- /dev/null +++ b/src/libs/FT800-FT813/EVE_suppplemental.h @@ -0,0 +1,53 @@ +/* +@file EVE_supplemental.h +@brief prototypes for supplemental functions +@version 5.0 +@date 2023-12-23 +@author Rudolph Riedel + +@section LICENSE + +MIT License + +Copyright (c) 2016-2023 Rudolph Riedel + +Permission is hereby granted, free of charge, to any person obtaining a copy of +this software and associated documentation files (the "Software"), to deal in +the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, +and/or sell copies of the Software, and to permit persons to whom the Software +is furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS +FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR +COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER +IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +@section History + +5.0 +- added EVE_polar_cartesian() + +*/ + +#ifndef EVE_SUPPLEMENTAL_H +#define EVE_SUPPLEMENTAL_H + +#include "EVE.h" +#include "EVE_commands.h" + +#ifdef __cplusplus +extern "C" +{ +#endif + +void EVE_widget_circle(int16_t xc0, int16_t yc0, uint16_t radius, uint16_t border, uint32_t bgcolor); +void EVE_widget_rectangle(int16_t xc0, int16_t yc0, int16_t wid, int16_t hgt, int16_t border, uint16_t linewidth, uint32_t bgcolor); +void EVE_polar_cartesian(uint16_t length, uint16_t angle, int16_t *p_xc0, int16_t *p_yc0); + +#endif /* EVE_SUPPLEMENTAL_H */ diff --git a/src/libs/FT800-FT813/EVE_target.h b/src/libs/FT800-FT813/EVE_target.h new file mode 100644 index 0000000000..76a1f4a95d --- /dev/null +++ b/src/libs/FT800-FT813/EVE_target.h @@ -0,0 +1,111 @@ +#ifndef EVE_TARGET_H +#define EVE_TARGET_H + +#include "../../draw/eve/lv_draw_eve_private.h" +#include "../../tick/lv_tick.h" +#include "../../misc/lv_utils.h" +#include "../../core/lv_global.h" + +#define lv_eve_write_buf (LV_GLOBAL_DEFAULT()->draw_eve_unit->lv_eve_write_buf) +#define lv_eve_write_buf_len (LV_GLOBAL_DEFAULT()->draw_eve_unit->lv_eve_write_buf_len) + +static inline void lv_eve_target_flush_write_buf(void); + +static inline void DELAY_MS(uint16_t ms) +{ + lv_delay_ms(ms); +} + +static inline void EVE_cs_set(void) +{ + lv_draw_eve_unit_g->op_cb(lv_draw_eve_unit_g->disp, LV_DRAW_EVE_OPERATION_CS_ASSERT, NULL, 0); +} + +static inline void EVE_cs_clear(void) +{ + lv_eve_target_flush_write_buf(); + lv_draw_eve_unit_g->op_cb(lv_draw_eve_unit_g->disp, LV_DRAW_EVE_OPERATION_CS_DEASSERT, NULL, 0); +} + +static inline void EVE_pdn_set(void) +{ + lv_draw_eve_unit_g->op_cb(lv_draw_eve_unit_g->disp, LV_DRAW_EVE_OPERATION_POWERDOWN_SET, NULL, 0); +} + +static inline void EVE_pdn_clear(void) +{ + lv_draw_eve_unit_g->op_cb(lv_draw_eve_unit_g->disp, LV_DRAW_EVE_OPERATION_POWERDOWN_CLEAR, NULL, 0); +} + +static inline void spi_transmit(uint8_t data) +{ +#if LV_DRAW_EVE_WRITE_BUFFER_SIZE_INTERNAL + if(lv_eve_write_buf_len == sizeof(lv_eve_write_buf)) { + lv_eve_target_flush_write_buf(); + } + lv_eve_write_buf[lv_eve_write_buf_len++] = data; +#else + lv_draw_eve_unit_g->op_cb(lv_draw_eve_unit_g->disp, LV_DRAW_EVE_OPERATION_SPI_SEND, &data, sizeof(data)); +#endif +} + +static inline void spi_transmit_32(uint32_t data) +{ +#if LV_BIG_ENDIAN_SYSTEM + data = lv_swap_bytes_32(data); +#endif +#if LV_DRAW_EVE_WRITE_BUFFER_SIZE_INTERNAL + if(lv_eve_write_buf_len + 4 > sizeof(lv_eve_write_buf)) { + lv_eve_target_flush_write_buf(); + } + uint8_t * buf4 = (uint8_t *) &data; + lv_eve_write_buf[lv_eve_write_buf_len++] = buf4[0]; + lv_eve_write_buf[lv_eve_write_buf_len++] = buf4[1]; + lv_eve_write_buf[lv_eve_write_buf_len++] = buf4[2]; + lv_eve_write_buf[lv_eve_write_buf_len++] = buf4[3]; +#else + lv_draw_eve_unit_g->op_cb(lv_draw_eve_unit_g->disp, LV_DRAW_EVE_OPERATION_SPI_SEND, &data, sizeof(data)); +#endif +} + +static inline void lv_eve_target_spi_transmit_buf(const void * data, uint32_t size) +{ + lv_eve_target_flush_write_buf(); + lv_draw_eve_unit_g->op_cb(lv_draw_eve_unit_g->disp, LV_DRAW_EVE_OPERATION_SPI_SEND, (void *) data, size); +} + +static inline void lv_eve_target_flush_write_buf(void) +{ +#if LV_DRAW_EVE_WRITE_BUFFER_SIZE_INTERNAL + if(lv_eve_write_buf_len == 0) { + return; + } + lv_draw_eve_unit_g->op_cb(lv_draw_eve_unit_g->disp, LV_DRAW_EVE_OPERATION_SPI_SEND, lv_eve_write_buf, lv_eve_write_buf_len); + lv_eve_write_buf_len = 0; +#endif +} + +static inline void spi_transmit_burst(uint32_t data) +{ + spi_transmit_32(data); +} + +static inline uint8_t spi_receive(uint8_t data) +{ + /* `data` is 0 everywhere `spi_receive` is called in the FT800-FT813 library */ + LV_UNUSED(data); + + lv_eve_target_flush_write_buf(); + + uint8_t byte; + lv_draw_eve_unit_g->op_cb(lv_draw_eve_unit_g->disp, LV_DRAW_EVE_OPERATION_SPI_RECEIVE, &byte, 1); + + return byte; +} + +static inline uint8_t fetch_flash_byte(const uint8_t *p_data) +{ + return (*p_data); +} + +#endif /* EVE_TARGET_H_ */ diff --git a/src/libs/FT800-FT813/LICENSE b/src/libs/FT800-FT813/LICENSE new file mode 100644 index 0000000000..a6ab28bb71 --- /dev/null +++ b/src/libs/FT800-FT813/LICENSE @@ -0,0 +1,20 @@ +MIT License + +Copyright (c) 2016-2024 Rudolph Riedel + +Permission is hereby granted, free of charge, to any person obtaining a copy of +this software and associated documentation files (the "Software"), to deal in +the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, +and/or sell copies of the Software, and to permit persons to whom the Software +is furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS +FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR +COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER +IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. diff --git a/src/libs/FT800-FT813/README.md b/src/libs/FT800-FT813/README.md new file mode 100644 index 0000000000..211acb1eba --- /dev/null +++ b/src/libs/FT800-FT813/README.md @@ -0,0 +1,245 @@ +# EVE2 / EVE3 / EVE4 code library +This is a code library for EVE2/EVE3/EVE4 graphics controller ICs from FTDI/Bridgetek: + +http://www.ftdichip.com/EVE.htm +http://brtchip.com/eve/ +http://brtchip.com/ft81x/ +https://brtchip.com/bt81x/ + +It contains code for and has been used with various micro-controllers and displays. + +## Controllers + +I have used it so far with: + +- 8-Bit AVR, specifically the 90CAN series +- Arduino: Uno R3, mini-pro, ESP8266, ESP32, Metro-M4 (DMA), STM32 Nucleo_F446RE (DMA), XMC1100, Uno R4 +- Renesas F1L RH850 +- Infineon Aurix TC222 +- GD32VF103 +- ATSAMC21J18A (DMA) +- ATSAME51J19A (DMA) +- ESP32 (DMA) +- RP2040 Baremetal (DMA) + Arduino (DMA) - Raspberry Pi Pico +- S32K144 (DMA) +- GD32C103CBT6 (DMA) +- STM32G0B1CET6 + +I have reports of successfully using it with: + +- ATSAMV70 +- ATSAMD20 +- ATSAME4 +- MSP430 +- MSP432 +- some PICs +- ATxmega128A1 +- TMS320F28335 + +## Displays + +The TFTs tested so far: + +- FT810CB-HY50HD http://www.hotmcu.com/5-graphical-lcd-touchscreen-800x480-spi-ft810-p-286.html +- FT811CB-HY50HD http://www.hotmcu.com/5-graphical-lcd-capacitive-touch-screen-800x480-spi-ft811-p-301.html +- RVT70UQFNWC0x https://riverdi.com/product/rvt70uqfnwc0x/ +- RVT50 +- ADAM101-LCP-SWVGA-NEW from Glyn, 10.1" 1024x600 cap-touch +- EVE2-38A https://www.matrixorbital.com/eve2-38a +- EVE2-35G https://www.matrixorbital.com/eve2-35g +- EVE2-43G https://www.matrixorbital.com/eve2-43g +- EVE2-50G https://www.matrixorbital.com/eve2-50g +- EVE2-70G https://www.matrixorbital.com/eve2-70g +- NHD-3.5-320240FT-CSXV-CTP +- RVT43ULBNWC00 (RiTFT-43-CAP-UX) https://riverdi.com/product/ritft43capux/ +- RVT50AQBNWC00 (RiTFT-50-CAP) https://riverdi.com/product/ritft50cap/ +- EVE3-50G https://www.matrixorbital.com/eve3-50g +- PAF90B5WFNWC01 http://www.panadisplay.com/ftdi-intelligent-display/9-inch-lcd-with-touch-with-bt815-board.html +- EVE3-43G https://www.matrixorbital.com/eve3-43g +- EVE3-35G https://www.matrixorbital.com/eve3-35g +- CFAF240400C0-030SC https://www.crystalfontz.com/product/cfaf240400c0030sca11-240x400-eve-touchscreen-tft-ft813 +- CFAF320240F-035T https://www.crystalfontz.com/product/cfaf320240f035ttsa11-320x240-eve-tft-lcd-display-kit +- CFAF480128A0-039TC +- CFAF800480E0-050SC https://www.crystalfontz.com/product/cfaf800480e1050sca11-800x480-eve-accelerated-tft +- GEN4-FT813-50CTP-CLB https://4dsystems.com.au/gen4-ft813-50ctp-clb +- RVT101HVBNWC00-B https://riverdi.com/product/rvt101hvbnwc00-b/ +- RVT70HSBNWC00-B https://riverdi.com/product/rvt70hsbnwc00-b/ +- RVT50HQBNWC00-B https://riverdi.com/product/rvt50hqbnwc00-b/ +- CFAF1024600B0-070SC-A1 https://www.crystalfontz.com/product/cfaf1024600b0070sca1-1024x600-7-inch-eve-tft +- Sunflower shield from Cowfish Studios +- GD3X Gameduino shield + +## This is version 5 + +This is version 5 of this code library and there are a couple of changes from V4. + +First of all, support for FT80x is gone. The main reason is that this allowed a nice speed improvement modification that only works with FT81x and beyond. +Then there is a hard break from FT80x to FT81x with ony 256k of memory in FT80x but 1MB in FT81x. The memory map is different and all the registers are located elsewhere. +FT810, FT811, FT812, FT813, BT815, BT816, BT817 and BT818 can use the exact same code as long none of the new features of BT81x are used - and there are plenty of modules with these available to choose from + +As a side effect all commands are automatically started now. + +Second is that there are two sets of display-list building command functions now: EVE_cmd_xxx() and EVE_cmd_xxx_burst(). +The EVE_cmd_xxx_burst() functions are optimized for speed, these are pure data transfer functions and do not even check anymore if burst mode is active. + +## Structure + +This library currently has nine files that I hope are named to make clear what these do: + +- EVE.h - this has all defines for FT81x / BT81x itself, so here are options, registers, commands and macros defined +- EVE_commands.c - this has all the API functions that are to be called from an application +- EVE_commands.h - this contains the prototypes for the functions in EVE_commands.c +- EVE_config.h - this has all the parameters for the numerous supported display modules, here is definded which set of parameters is to be used +- EVE_target.c - this has non-portable specific code for a number of supported controllers, mostly to support DMA +- EVE_target.h - this has non-portable pin defines and code as "static inline" functions for all supported controllers +- EVE_target.cpp - this is for Arduino C++ targets +- EVE_cpp_wrapper.cpp - this is for Arduino C++ targets +- EVE_cpp_wrapper.h - this is for Arduino C++ targets + +Addtionally there are these two: +- EVE_supplemental.c +- EVE_suppplemental.h + +This has the prototype and implementation for extra functions, so far: +- EVE_widget_circle() - widget function to draw a circle +- EVE_widget_rectangle() - widget function to draw a rectangle +- EVE_polar_cartesian() - calculate coordinates from an angle and a length + +## Examples + +Generate a basic display list and tell EVE to use it: +```` +EVE_cmd_dl(CMD_DLSTART); // tells EVE to start a new display-list +EVE_cmd_dl(DL_CLEAR_COLOR_RGB | WHITE); // sets the background color +EVE_cmd_dl(DL_CLEAR | CLR_COL | CLR_STN | CLR_TAG); +EVE_color_rgb(BLACK); +EVE_cmd_text(5, 15, 28, 0, "Hello there!"); +EVE_cmd_dl(DL_DISPLAY); // put in the display list to mark its end +EVE_cmd_dl(CMD_SWAP); // tell EVE to use the new display list +while (EVE_busy()); +```` + +Note, these commands are executed one by one, for each command chip-select is pulled low, a three byte address is send, the data for the command and its parameters is send and then chip-select is pulled high again which also makes EVE execute the command. + +But there is a way to speed things up, we can get away with only sending the address once: +```` +EVE_start_cmd_burst(); +EVE_cmd_dl_burst(CMD_DLSTART); +EVE_cmd_dl_burst(DL_CLEAR_COLOR_RGB | WHITE); +EVE_cmd_dl_burst(DL_CLEAR | CLR_COL | CLR_STN | CLR_TAG); +EVE_color_rgb_burst(BLACK); +EVE_cmd_text_burst(5, 15, 28, 0, "Hello there!"); +EVE_cmd_dl_burst(DL_DISPLAY); +EVE_cmd_dl_burst(CMD_SWAP); +EVE_end_cmd_burst(); +while (EVE_busy()); +```` + +This does the same as the first example but faster. +The preceding EVE_start_cmd_burst() either sets chip-select to low and sends out the three byte address. +Or if DMA is available for the target you are compiling for with support code in EVE_target.c / EVE_target.cpp and EVE_target.h, it writes the address to EVE_dma_buffer and sets EVE_dma_buffer_index to 1. + +Note the trailing "_burst" in the following functions, these are special versions of these commands that can only be used within an EVE_start_cmd_burst()/EVE_end_cmd_bust() pair. +These functions are optimized to push out data and nothing else. + +The final EVE_end_cmd_burst() either pulls back the chip-select to high. +Or if we have DMA it calls EVE_start_dma_transfer() to start pushing out the buffer in the background. + +As we have 7 commands for EVE in these simple examples, the second one has the address overhead removed from six commands and therefore needs to transfer 18 bytes less over SPI. +So even with a small 8-bit controller that does not support DMA this is a usefull optimization for building display lists. + +Using DMA has one caveat: we need to limit the transfer to <4k as we are writing to the FIFO of EVEs command co-processor. This is usually not an issue though as we can shorten the display list generation with previously generated snippets that we attach to the current list with CMD_APPEND. And when we use widgets like CMD_BUTTON or CMD_CLOCK the generated display list grows by a larger amount than what we need to put into the command-FIFO so we likely reach the 8k limit of the display-list before we hit the 4k limit of the command-FIFO. +It is possible to use two or more DMA transfers to the FIFO to build a single display list, either to get around the 4k limit of the FIFO or in order to distribute the workload better of the time necessary between two display renewals. + +You could for example do this, spread over three consecutive calls: +```` +EVE_start_cmd_burst(); +EVE_cmd_dl_burst(CMD_DLSTART); +EVE_cmd_dl_burst(DL_CLEAR_COLOR_RGB | WHITE); +EVE_end_cmd_burst(); +```` + +```` +EVE_start_cmd_burst(); +EVE_cmd_dl_burst(DL_CLEAR | CLR_COL | CLR_STN | CLR_TAG); +EVE_color_rgb_burst(BLACK); +EVE_end_cmd_burst(); +```` + +```` +EVE_start_cmd_burst(); +EVE_cmd_text_burst(5, 15, 28, 0, "Hello there!"); +EVE_cmd_dl_burst(DL_DISPLAY); +EVE_cmd_dl_burst(CMD_SWAP); +EVE_end_cmd_burst(); +```` + +But you need to check with EVE_busy() before each of these blocks. +Maybe similar like this never compiled pseudo-code: + +thread_1ms_update_display() +{ + static uint8_t state = 0; + static uint8_t count = 0; + + count++; + + if (E_OK == EVE_busy()) + { + switch (state) + { + case 0: + update_first(); + state = 1; + break; + case 1: + update_second(); + state = 2; + break; + case 2: + if (counter > 19) + { + update_last_swap_list(); + count = 0; + state = 0; + } + break; + } + } +} + + +## Remarks + +The examples in the "example_projects" drawer are for use with AtmelStudio7. +For Arduino I am using PlatformIO with Visual Studio Code. + +The platform the code is compiled for is automatically detected thru compiler flags in EVE_target.h. + +The desired TFT is selected by adding a define for it to the build-environment, e.g. -DEVE_EVE3_50G +There is a list of available options at the start of EVE_config.h sorted by chipset. + +The pins used for Chip-Select and Power-Down setup in the EVE_target/EVE_target_XXXXX.h file for your target with defines and these defines can be bypassed with defines in the build-environment. +Check the apropriate header file for your desired target. + +When compiling for AVR you need to provide the clock it is running at in order to make the _delay_ms() calls used to initialize the TFT work with the intended timing. +For other plattforms you need to provide a DELAY_MS(ms) function that works at least between 1ms and 56ms and is not performing these delays shorter than requested. +The DELAY_MS(ms) is only used during initialization of the FT8xx/BT8xx. + +In Addition you need to initialize the pins used for Chip-Select and Power-Down in your hardware correctly to output. +Plus setup the SPI accordingly, mode-0, 8-bit, MSB-first, not more than 11MHz for the initialization. +A couple of targets already have a function EVE_init_spi() in EVE_target.c. + +A word of "warning", you have to take care yourself to not send more than 4kiB at once to the command co-processor +or to not generate display lists that are longer than 8kiB. +My library does not check and re-check the command-FIFO on every step. +Also there are no checks for the validity of function arguments. +This is optimized for speed, so the training wheels are off. + +## Post questions here + +Originally the project went public in the German mikrocontroller.net forum, the thread contains some insight: https://www.mikrocontroller.net/topic/395608 + +Feel free to add to the discussion with questions or remarks. + +New: Github has a discussions feature as well: https://github.com/RudolphRiedel/FT800-FT813/discussions diff --git a/src/libs/barcode/lv_barcode.c b/src/libs/barcode/lv_barcode.c index 68034fb505..524a175de2 100644 --- a/src/libs/barcode/lv_barcode.c +++ b/src/libs/barcode/lv_barcode.c @@ -13,6 +13,7 @@ #if LV_USE_BARCODE #include "code128.h" +#include "../../misc/cache/lv_cache.h" /********************* * DEFINES diff --git a/src/libs/bin_decoder/lv_bin_decoder.c b/src/libs/bin_decoder/lv_bin_decoder.c index 7015558dc8..9c31576196 100644 --- a/src/libs/bin_decoder/lv_bin_decoder.c +++ b/src/libs/bin_decoder/lv_bin_decoder.c @@ -1,5 +1,5 @@ /** - * @file lv_image_decoder.c + * @file lv_bin_decoder.c * */ @@ -351,7 +351,18 @@ lv_result_t lv_bin_decoder_open(lv_image_decoder_t * decoder, lv_image_decoder_d } dsc->decoded = adjusted; - if(use_directly || dsc->args.no_cache) return LV_RESULT_OK; /*Do not put image to cache if it can be used directly.*/ + /* Copy user flags to the decoded image */ + if(dsc->header.flags & LV_IMAGE_FLAGS_USER_MASK) { + lv_draw_buf_set_flag((lv_draw_buf_t *)dsc->decoded, dsc->header.flags & LV_IMAGE_FLAGS_USER_MASK); + } + + /*Do not put image to cache if it can be used directly.*/ + if(use_directly || dsc->args.no_cache) { + if(dsc->args.flush_cache && use_directly) { + dsc->args.flush_cache = false; + } + return LV_RESULT_OK; + } /*If the image cache is disabled, just return the decoded image*/ if(!lv_image_cache_is_enabled()) return LV_RESULT_OK; diff --git a/src/libs/ffmpeg/lv_ffmpeg.c b/src/libs/ffmpeg/lv_ffmpeg.c index 65f4b7ca66..a887520829 100644 --- a/src/libs/ffmpeg/lv_ffmpeg.c +++ b/src/libs/ffmpeg/lv_ffmpeg.c @@ -345,7 +345,7 @@ static lv_result_t decoder_open(lv_image_decoder_t * decoder, lv_image_decoder_d lv_draw_buf_set_flag(decoded, LV_IMAGE_FLAGS_MODIFIABLE); /* Empty handlers to avoid decoder asserts */ - lv_draw_buf_handlers_init(&ffmpeg_ctx->draw_buf_handlers, NULL, NULL, NULL, NULL, NULL, NULL); + lv_draw_buf_handlers_init(&ffmpeg_ctx->draw_buf_handlers, NULL, NULL, NULL, NULL, NULL, NULL, NULL); decoded->handlers = &ffmpeg_ctx->draw_buf_handlers; if(dsc->args.premultiply && ffmpeg_ctx->has_alpha) { diff --git a/src/libs/freetype/LiberationSans-LICENSE.txt b/src/libs/freetype/LiberationSans-LICENSE.txt new file mode 100644 index 0000000000..aba73e8a40 --- /dev/null +++ b/src/libs/freetype/LiberationSans-LICENSE.txt @@ -0,0 +1,102 @@ +Digitized data copyright (c) 2010 Google Corporation + with Reserved Font Arimo, Tinos and Cousine. +Copyright (c) 2012 Red Hat, Inc. + with Reserved Font Name Liberation. + +This Font Software is licensed under the SIL Open Font License, +Version 1.1. + +This license is copied below, and is also available with a FAQ at: +http://scripts.sil.org/OFL + +SIL OPEN FONT LICENSE Version 1.1 - 26 February 2007 + +PREAMBLE The goals of the Open Font License (OFL) are to stimulate +worldwide development of collaborative font projects, to support the font +creation efforts of academic and linguistic communities, and to provide +a free and open framework in which fonts may be shared and improved in +partnership with others. + +The OFL allows the licensed fonts to be used, studied, modified and +redistributed freely as long as they are not sold by themselves. +The fonts, including any derivative works, can be bundled, embedded, +redistributed and/or sold with any software provided that any reserved +names are not used by derivative works. The fonts and derivatives, +however, cannot be released under any other type of license. The +requirement for fonts to remain under this license does not apply to +any document created using the fonts or their derivatives. + + + +DEFINITIONS +"Font Software" refers to the set of files released by the Copyright +Holder(s) under this license and clearly marked as such. +This may include source files, build scripts and documentation. + +"Reserved Font Name" refers to any names specified as such after the +copyright statement(s). + +"Original Version" refers to the collection of Font Software components +as distributed by the Copyright Holder(s). + +"Modified Version" refers to any derivative made by adding to, deleting, +or substituting ? in part or in whole ? +any of the components of the Original Version, by changing formats or +by porting the Font Software to a new environment. + +"Author" refers to any designer, engineer, programmer, technical writer +or other person who contributed to the Font Software. + + +PERMISSION & CONDITIONS + +Permission is hereby granted, free of charge, to any person obtaining a +copy of the Font Software, to use, study, copy, merge, embed, modify, +redistribute, and sell modified and unmodified copies of the Font +Software, subject to the following conditions: + +1) Neither the Font Software nor any of its individual components,in + Original or Modified Versions, may be sold by itself. + +2) Original or Modified Versions of the Font Software may be bundled, + redistributed and/or sold with any software, provided that each copy + contains the above copyright notice and this license. These can be + included either as stand-alone text files, human-readable headers or + in the appropriate machine-readable metadata fields within text or + binary files as long as those fields can be easily viewed by the user. + +3) No Modified Version of the Font Software may use the Reserved Font + Name(s) unless explicit written permission is granted by the + corresponding Copyright Holder. This restriction only applies to the + primary font name as presented to the users. + +4) The name(s) of the Copyright Holder(s) or the Author(s) of the Font + Software shall not be used to promote, endorse or advertise any + Modified Version, except to acknowledge the contribution(s) of the + Copyright Holder(s) and the Author(s) or with their explicit written + permission. + +5) The Font Software, modified or unmodified, in part or in whole, must + be distributed entirely under this license, and must not be distributed + under any other license. The requirement for fonts to remain under + this license does not apply to any document created using the Font + Software. + + + +TERMINATION +This license becomes null and void if any of the above conditions are not met. + + + +DISCLAIMER +THE FONT SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT +OF COPYRIGHT, PATENT, TRADEMARK, OR OTHER RIGHT. IN NO EVENT SHALL THE +COPYRIGHT HOLDER BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, +INCLUDING ANY GENERAL, SPECIAL, INDIRECT, INCIDENTAL, OR CONSEQUENTIAL +DAMAGES, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +FROM, OUT OF THE USE OR INABILITY TO USE THE FONT SOFTWARE OR FROM OTHER +DEALINGS IN THE FONT SOFTWARE. + diff --git a/src/libs/freetype/LiberationSans-Regular.ttf b/src/libs/freetype/LiberationSans-Regular.ttf new file mode 100644 index 0000000000..8a67859c89 Binary files /dev/null and b/src/libs/freetype/LiberationSans-Regular.ttf differ diff --git a/src/libs/freetype/arial.ttf b/src/libs/freetype/arial.ttf deleted file mode 100644 index 886789b85b..0000000000 Binary files a/src/libs/freetype/arial.ttf and /dev/null differ diff --git a/src/libs/freetype/LICENSE.txt b/src/libs/freetype/freetype-LICENSE.txt similarity index 100% rename from src/libs/freetype/LICENSE.txt rename to src/libs/freetype/freetype-LICENSE.txt diff --git a/src/libs/freetype/lv_freetype.c b/src/libs/freetype/lv_freetype.c index 77e33244a4..ce8150b300 100755 --- a/src/libs/freetype/lv_freetype.c +++ b/src/libs/freetype/lv_freetype.c @@ -117,6 +117,10 @@ lv_result_t lv_freetype_init(uint32_t max_glyph_cnt) void lv_freetype_uninit(void) { lv_freetype_context_t * ctx = lv_freetype_get_context(); + if(!ctx) { + return; + } + lv_freetype_cleanup(ctx); lv_free(ft_ctx); diff --git a/src/libs/frogfs/LICENSE.txt b/src/libs/frogfs/LICENSE.txt new file mode 100644 index 0000000000..be2cc4dfb6 --- /dev/null +++ b/src/libs/frogfs/LICENSE.txt @@ -0,0 +1,362 @@ +Mozilla Public License, version 2.0 + +1. Definitions + +1.1. "Contributor" + + means each individual or legal entity that creates, contributes to the + creation of, or owns Covered Software. + +1.2. "Contributor Version" + + means the combination of the Contributions of others (if any) used by a + Contributor and that particular Contributor's Contribution. + +1.3. "Contribution" + + means Covered Software of a particular Contributor. + +1.4. "Covered Software" + + means Source Code Form to which the initial Contributor has attached the + notice in Exhibit A, the Executable Form of such Source Code Form, and + Modifications of such Source Code Form, in each case including portions + thereof. + +1.5. "Incompatible With Secondary Licenses" + means + + a. that the initial Contributor has attached the notice described in + Exhibit B to the Covered Software; or + + b. that the Covered Software was made available under the terms of + version 1.1 or earlier of the License, but not also under the terms of + a Secondary License. + +1.6. "Executable Form" + + means any form of the work other than Source Code Form. + +1.7. "Larger Work" + + means a work that combines Covered Software with other material, in a + separate file or files, that is not Covered Software. + +1.8. "License" + + means this document. + +1.9. "Licensable" + + means having the right to grant, to the maximum extent possible, whether + at the time of the initial grant or subsequently, any and all of the + rights conveyed by this License. + +1.10. "Modifications" + + means any of the following: + + a. any file in Source Code Form that results from an addition to, + deletion from, or modification of the contents of Covered Software; or + + b. any new file in Source Code Form that contains any Covered Software. + +1.11. "Patent Claims" of a Contributor + + means any patent claim(s), including without limitation, method, + process, and apparatus claims, in any patent Licensable by such + Contributor that would be infringed, but for the grant of the License, + by the making, using, selling, offering for sale, having made, import, + or transfer of either its Contributions or its Contributor Version. + +1.12. "Secondary License" + + means either the GNU General Public License, Version 2.0, the GNU Lesser + General Public License, Version 2.1, the GNU Affero General Public + License, Version 3.0, or any later versions of those licenses. + +1.13. "Source Code Form" + + means the form of the work preferred for making modifications. + +1.14. "You" (or "Your") + + means an individual or a legal entity exercising rights under this + License. For legal entities, "You" includes any entity that controls, is + controlled by, or is under common control with You. For purposes of this + definition, "control" means (a) the power, direct or indirect, to cause + the direction or management of such entity, whether by contract or + otherwise, or (b) ownership of more than fifty percent (50%) of the + outstanding shares or beneficial ownership of such entity. + + +2. License Grants and Conditions + +2.1. Grants + + Each Contributor hereby grants You a world-wide, royalty-free, + non-exclusive license: + + a. under intellectual property rights (other than patent or trademark) + Licensable by such Contributor to use, reproduce, make available, + modify, display, perform, distribute, and otherwise exploit its + Contributions, either on an unmodified basis, with Modifications, or + as part of a Larger Work; and + + b. under Patent Claims of such Contributor to make, use, sell, offer for + sale, have made, import, and otherwise transfer either its + Contributions or its Contributor Version. + +2.2. Effective Date + + The licenses granted in Section 2.1 with respect to any Contribution + become effective for each Contribution on the date the Contributor first + distributes such Contribution. + +2.3. Limitations on Grant Scope + + The licenses granted in this Section 2 are the only rights granted under + this License. No additional rights or licenses will be implied from the + distribution or licensing of Covered Software under this License. + Notwithstanding Section 2.1(b) above, no patent license is granted by a + Contributor: + + a. for any code that a Contributor has removed from Covered Software; or + + b. for infringements caused by: (i) Your and any other third party's + modifications of Covered Software, or (ii) the combination of its + Contributions with other software (except as part of its Contributor + Version); or + + c. under Patent Claims infringed by Covered Software in the absence of + its Contributions. + + This License does not grant any rights in the trademarks, service marks, + or logos of any Contributor (except as may be necessary to comply with + the notice requirements in Section 3.4). + +2.4. Subsequent Licenses + + No Contributor makes additional grants as a result of Your choice to + distribute the Covered Software under a subsequent version of this + License (see Section 10.2) or under the terms of a Secondary License (if + permitted under the terms of Section 3.3). + +2.5. Representation + + Each Contributor represents that the Contributor believes its + Contributions are its original creation(s) or it has sufficient rights to + grant the rights to its Contributions conveyed by this License. + +2.6. Fair Use + + This License is not intended to limit any rights You have under + applicable copyright doctrines of fair use, fair dealing, or other + equivalents. + +2.7. Conditions + + Sections 3.1, 3.2, 3.3, and 3.4 are conditions of the licenses granted in + Section 2.1. + + +3. Responsibilities + +3.1. Distribution of Source Form + + All distribution of Covered Software in Source Code Form, including any + Modifications that You create or to which You contribute, must be under + the terms of this License. You must inform recipients that the Source + Code Form of the Covered Software is governed by the terms of this + License, and how they can obtain a copy of this License. You may not + attempt to alter or restrict the recipients' rights in the Source Code + Form. + +3.2. Distribution of Executable Form + + If You distribute Covered Software in Executable Form then: + + a. such Covered Software must also be made available in Source Code Form, + as described in Section 3.1, and You must inform recipients of the + Executable Form how they can obtain a copy of such Source Code Form by + reasonable means in a timely manner, at a charge no more than the cost + of distribution to the recipient; and + + b. You may distribute such Executable Form under the terms of this + License, or sublicense it under different terms, provided that the + license for the Executable Form does not attempt to limit or alter the + recipients' rights in the Source Code Form under this License. + +3.3. Distribution of a Larger Work + + You may create and distribute a Larger Work under terms of Your choice, + provided that You also comply with the requirements of this License for + the Covered Software. If the Larger Work is a combination of Covered + Software with a work governed by one or more Secondary Licenses, and the + Covered Software is not Incompatible With Secondary Licenses, this + License permits You to additionally distribute such Covered Software + under the terms of such Secondary License(s), so that the recipient of + the Larger Work may, at their option, further distribute the Covered + Software under the terms of either this License or such Secondary + License(s). + +3.4. Notices + + You may not remove or alter the substance of any license notices + (including copyright notices, patent notices, disclaimers of warranty, or + limitations of liability) contained within the Source Code Form of the + Covered Software, except that You may alter any license notices to the + extent required to remedy known factual inaccuracies. + +3.5. Application of Additional Terms + + You may choose to offer, and to charge a fee for, warranty, support, + indemnity or liability obligations to one or more recipients of Covered + Software. However, You may do so only on Your own behalf, and not on + behalf of any Contributor. You must make it absolutely clear that any + such warranty, support, indemnity, or liability obligation is offered by + You alone, and You hereby agree to indemnify every Contributor for any + liability incurred by such Contributor as a result of warranty, support, + indemnity or liability terms You offer. You may include additional + disclaimers of warranty and limitations of liability specific to any + jurisdiction. + +4. Inability to Comply Due to Statute or Regulation + + If it is impossible for You to comply with any of the terms of this License + with respect to some or all of the Covered Software due to statute, + judicial order, or regulation then You must: (a) comply with the terms of + this License to the maximum extent possible; and (b) describe the + limitations and the code they affect. Such description must be placed in a + text file included with all distributions of the Covered Software under + this License. Except to the extent prohibited by statute or regulation, + such description must be sufficiently detailed for a recipient of ordinary + skill to be able to understand it. + +5. Termination + +5.1. The rights granted under this License will terminate automatically if You + fail to comply with any of its terms. However, if You become compliant, + then the rights granted under this License from a particular Contributor + are reinstated (a) provisionally, unless and until such Contributor + explicitly and finally terminates Your grants, and (b) on an ongoing + basis, if such Contributor fails to notify You of the non-compliance by + some reasonable means prior to 60 days after You have come back into + compliance. Moreover, Your grants from a particular Contributor are + reinstated on an ongoing basis if such Contributor notifies You of the + non-compliance by some reasonable means, this is the first time You have + received notice of non-compliance with this License from such + Contributor, and You become compliant prior to 30 days after Your receipt + of the notice. + +5.2. If You initiate litigation against any entity by asserting a patent + infringement claim (excluding declaratory judgment actions, + counter-claims, and cross-claims) alleging that a Contributor Version + directly or indirectly infringes any patent, then the rights granted to + You by any and all Contributors for the Covered Software under Section + 2.1 of this License shall terminate. + +5.3. In the event of termination under Sections 5.1 or 5.2 above, all end user + license agreements (excluding distributors and resellers) which have been + validly granted by You or Your distributors under this License prior to + termination shall survive termination. + +6. Disclaimer of Warranty + + Covered Software is provided under this License on an "as is" basis, + without warranty of any kind, either expressed, implied, or statutory, + including, without limitation, warranties that the Covered Software is free + of defects, merchantable, fit for a particular purpose or non-infringing. + The entire risk as to the quality and performance of the Covered Software + is with You. Should any Covered Software prove defective in any respect, + You (not any Contributor) assume the cost of any necessary servicing, + repair, or correction. This disclaimer of warranty constitutes an essential + part of this License. No use of any Covered Software is authorized under + this License except under this disclaimer. + +7. Limitation of Liability + + Under no circumstances and under no legal theory, whether tort (including + negligence), contract, or otherwise, shall any Contributor, or anyone who + distributes Covered Software as permitted above, be liable to You for any + direct, indirect, special, incidental, or consequential damages of any + character including, without limitation, damages for lost profits, loss of + goodwill, work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses, even if such party shall have been + informed of the possibility of such damages. This limitation of liability + shall not apply to liability for death or personal injury resulting from + such party's negligence to the extent applicable law prohibits such + limitation. Some jurisdictions do not allow the exclusion or limitation of + incidental or consequential damages, so this exclusion and limitation may + not apply to You. + +8. Litigation + + Any litigation relating to this License may be brought only in the courts + of a jurisdiction where the defendant maintains its principal place of + business and such litigation shall be governed by laws of that + jurisdiction, without reference to its conflict-of-law provisions. Nothing + in this Section shall prevent a party's ability to bring cross-claims or + counter-claims. + +9. Miscellaneous + + This License represents the complete agreement concerning the subject + matter hereof. If any provision of this License is held to be + unenforceable, such provision shall be reformed only to the extent + necessary to make it enforceable. Any law or regulation which provides that + the language of a contract shall be construed against the drafter shall not + be used to construe this License against a Contributor. + + +10. Versions of the License + +10.1. New Versions + + Mozilla Foundation is the license steward. Except as provided in Section + 10.3, no one other than the license steward has the right to modify or + publish new versions of this License. Each version will be given a + distinguishing version number. + +10.2. Effect of New Versions + + You may distribute the Covered Software under the terms of the version + of the License under which You originally received the Covered Software, + or under the terms of any subsequent version published by the license + steward. + +10.3. Modified Versions + + If you create software not governed by this License, and you want to + create a new license for such software, you may create and use a + modified version of this License if you rename the license and remove + any references to the name of the license steward (except to note that + such modified license differs from this License). + +10.4. Distributing Source Code Form that is Incompatible With Secondary + Licenses If You choose to distribute Source Code Form that is + Incompatible With Secondary Licenses under the terms of this version of + the License, the notice described in Exhibit B of this License must be + attached. + +Exhibit A - Source Code Form License Notice + + This Source Code Form is subject to the + terms of the Mozilla Public License, v. + 2.0. If a copy of the MPL was not + distributed with this file, You can + obtain one at + http://mozilla.org/MPL/2.0/. + +If it is not possible or desirable to put the notice in a particular file, +then You may include the notice in a location (such as a LICENSE file in a +relevant directory) where a recipient would be likely to look for such a +notice. + +You may add additional accurate notices of copyright ownership. + +Exhibit B - "Incompatible With Secondary Licenses" Notice + + This Source Code Form is "Incompatible + With Secondary Licenses", as defined by + the Mozilla Public License, v. 2.0. diff --git a/src/libs/frogfs/include/frogfs/frogfs.h b/src/libs/frogfs/include/frogfs/frogfs.h new file mode 100644 index 0000000000..fdc95acff2 --- /dev/null +++ b/src/libs/frogfs/include/frogfs/frogfs.h @@ -0,0 +1,260 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#pragma once + +#ifdef __cplusplus +extern "C" { +#endif + +#include "../../../../lv_conf_internal.h" +#include LV_STDDEF_INCLUDE +#include LV_STDINT_INCLUDE +#include "frogfs_types.h" + +/** + * \brief Magic number used in the frogfs file header + */ +#define FROGFS_MAGIC 0x474F5246 /** FROG */ + +/** + * \brief Major version this source distribution supports + */ +#define FROGFS_VER_MAJOR 1 + +/** + * \brief Minor version this source distribution supports + */ +#define FROGFS_VER_MINOR 0 + +/** + * \brief Flag for \a frogfs_open to open any file as raw. Useful to + * pass compressed data over a transport such as HTTP. + */ +#define FROGFS_OPEN_RAW (1 << 0) + +/** + * \brief Enum of frogfs entry types + */ +typedef enum frogfs_entry_type_t { + FROGFS_ENTRY_TYPE_DIR, + FROGFS_ENTRY_TYPE_FILE, +} frogfs_entry_type_t; + +/** + * \brief Compression algorithm ids + */ +typedef enum frogfs_comp_algo_t { + FROGFS_COMP_ALGO_NONE, + FROGFS_COMP_ALGO_ZLIB, + FROGFS_COMP_ALGO_HEATSHRINK, + FROGFS_COMP_ALGO_GZIP, +} frogfs_comp_algo_t; + +/** + * \brief Configuration for the \a frogfs_init function + */ +typedef struct frogfs_config_t { + const void *addr; /**< address of an frogfs filesystem in memory */ +} frogfs_config_t; + +/** + * \brief A frogfs filesystem handle + */ +typedef struct frogfs_fs_t frogfs_fs_t; + +/** + * \brief Structure filled by the \a frogfs_stat function + */ +typedef struct frogfs_stat_t { + frogfs_entry_type_t type; /**< entry type */ + size_t size; /**< uncompressed file size */ + frogfs_comp_algo_t compression; /**< compression type */ + size_t compressed_sz; /**< compressed file size */ +} frogfs_stat_t; + +/** + * \brief Fiilesystem entry pointer +*/ +typedef struct frogfs_entry_t frogfs_entry_t; +typedef struct frogfs_dh_t frogfs_dh_t; +typedef struct frogfs_fh_t frogfs_fh_t; + +#if !defined(FROGFS_PRIVATE_STRUCTS) +/** + * \brief A frogfs directory handle + */ +struct frogfs_dh_t { + const frogfs_fs_t *fs; /**< filesystem handle */ + frogfs_entry_t *entry; /**< directory entry */ +}; + +/** + * \brief A frogfs file handle + */ +struct frogfs_fh_t { + const frogfs_fs_t *fs; /**< filesystem handle */ + frogfs_entry_t *entry; /**< file entry */ +}; +#endif + +/** + * \brief Initialize and return a \a frogfs_fs_t instance + * \param[in] config frogfs configuration + * \return \a frogfs_fs_t pointer or \a NULL on error + */ +frogfs_fs_t *frogfs_init(const frogfs_config_t *conf); + +/** + * \brief Tear down a \a frogfs_fs_t instance + * \param[in] fs \a frogfs_fs_t pointer + */ +void frogfs_deinit(frogfs_fs_t *fs); + +/** + * \brief Get frogfs entry for path + * \param[in] fs \a frogfs_fs_t pointer + * \param[in] path path string + * \return \a frogfs_entry_t pointer or \a NULL if path was not + * found + */ +const frogfs_entry_t *frogfs_get_entry(const frogfs_fs_t *fs, + const char *path); + +/** + * \brief Get name for frogfs entry + * \param[in] entry \a frogfs_entry_t pointer + * \return name string, caller is expected to free + */ +char *frogfs_get_name(const frogfs_entry_t *entry); + +/** + * \brief Get full path for frogfs entry + * \param[in] fs \a frogfs_fs_t pointer + * \param[in] entry \a frogfs_entry_t pointer + * \return full path string or \a NULL if entry is NULL, caller is + * expected to free + */ +char *frogfs_get_path(const frogfs_fs_t *fs, const frogfs_entry_t *entry); + +/** + * \brief Return if entry is a directory + * \param[in] entry \a frogfs_entry_t pointer + * \return 1 if directory, 0 otherwise + */ +int frogfs_is_dir(const frogfs_entry_t *entry); + +/** + * \brief Return if entry is a file + * \param[in] entry \a frogfs_entry_t pointer + * \return 1 if file, 0 otherwise + */ +int frogfs_is_file(const frogfs_entry_t *entry); + +/** + * \brief Get information about a frogfs entry + * \param[in] fs \a frogfs_fs_t pointer + * \param[in] entry \a frogfs_entry_t pointer + * \param[out] st \a frogfs_stat_t structure + */ +void frogfs_stat(const frogfs_fs_t *fs, const frogfs_entry_t *entry, + frogfs_stat_t *st); + +/** + * \brief Open a frogfs entry as a file from a \a frogfs_fs_t instance + * \param[in] fs \a frogfs_fs_t poitner + * \param[in] entry \a frogfs_entry_t pointer + * \param[in] flags open flags + * \return \a frogfs_fh_t or \a NULL if not found + */ +frogfs_fh_t *frogfs_open(const frogfs_fs_t *fs, const frogfs_entry_t *entry, + unsigned int flags); + +/** + * \brief Close an open file entry + * \param[in] f \a frogfs_fh_t pointer + */ +void frogfs_close(frogfs_fh_t *fh); + +/** + * \brief Determine if file handle is opened raw. + * \param[in] f \a frogfs_fh_t pointer + * \return 1 if file is open raw, 0 otherwise +*/ +int frogfs_is_raw(frogfs_fh_t *fh); + +/** + * \brief Read data from an open file entry + * \param[in] f \a frogfs_fh_t pointer + * \param[out] buf buffer to read into + * \param[in] len maximum number of bytes to read + * \return actual number of bytes read, zero if end of file + * reached + */ +ssize_t frogfs_read(frogfs_fh_t *fh, void *buf, size_t len); + +/** + * \brief Seek to a position within an open file entry + * \param[in] f \a frogfs_fh_t pointer + * \param[in] offset file position (relative or absolute) + * \param[in] mode \a SEEK_SET, \a SEEK_CUR, or \a SEEK_END + * \return current position in file or < 0 upon error + */ +ssize_t frogfs_seek(frogfs_fh_t *fh, long offset, int mode); + +/** + * \brief Get the current position in an open file entry + * \param[in] f \a frogfs_fh_t pointer + * \return current position in file or < 0 upon error + */ +size_t frogfs_tell(frogfs_fh_t *fh); + +/** + * \brief Get raw memory for raw file entry + * \param[in] f \a frogfs_fh_t pointer + * \param[out] buf pointer pointer to buf + * \return length of raw data + */ +size_t frogfs_access(frogfs_fh_t *fh, const void **buf); + +/** + * \brief Open a directory for reading child entrys + * \param[in] fs \a frogfs_fs_t pointer + * \param[in] entry \a frogfs_entry_t pointer to root director + * \return \a frogfs_dh_t pointer or \a NULL if invalid + */ +frogfs_dh_t *frogfs_opendir(frogfs_fs_t *fs, const frogfs_entry_t *entry); + +/** + * \brief Close a directory + * \param[in] d \a frogfs_dh_t pointer + */ +void frogfs_closedir(frogfs_dh_t *dh); + +/** + * \brief Get the next child entry in directory + * \param[in] d \a frogfs_dh_t pointer + * \return \a frogfs_entry_t pointer or \a NULL if end has been + * reached + */ +const frogfs_entry_t *frogfs_readdir(frogfs_dh_t *dh); + +/** + * \brief Set dir entry index to a value returned by \a frogfs_telldir + * for the current \a frogfs_dh_t pointer + * \param[in] d \a frogfs_dh_t pointer + * \param[in] loc entry index + */ +void frogfs_seekdir(frogfs_dh_t *dh, long loc); + +/** + * \brief Return the current entry index for a directory + * \param[in] d \a frogfs_dh_t pointer + * \return entry index + */ +long frogfs_telldir(frogfs_dh_t *dh); + +#ifdef __cplusplus +} /* extern "C" */ +#endif diff --git a/src/libs/frogfs/include/frogfs/frogfs_types.h b/src/libs/frogfs/include/frogfs/frogfs_types.h new file mode 100644 index 0000000000..5ee1eed98c --- /dev/null +++ b/src/libs/frogfs/include/frogfs/frogfs_types.h @@ -0,0 +1,6 @@ +#pragma once + +#include "../../../../lv_conf_internal.h" +#include LV_STDINT_INCLUDE + +typedef intptr_t ssize_t; diff --git a/src/libs/frogfs/src/decomp_raw.c b/src/libs/frogfs/src/decomp_raw.c new file mode 100644 index 0000000000..044c74ebdc --- /dev/null +++ b/src/libs/frogfs/src/decomp_raw.c @@ -0,0 +1,77 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#include "../../../lv_conf_internal.h" +#include LV_STDDEF_INCLUDE +#include LV_STDINT_INCLUDE +#include "../../../stdlib/lv_string.h" +#include "../../../misc/lv_fs.h" + +#include "frogfs_priv.h" +#include "frogfs_format.h" +#include "../include/frogfs/frogfs.h" + + +static ssize_t read_raw(frogfs_fh_t *f, void *buf, size_t len) +{ + size_t remaining = f->data_sz - ((char *)f->data_ptr - (char *)f->data_start); + + if (len > remaining) { + len = remaining; + } + + if (buf) { + lv_memcpy(buf, f->data_ptr, len); + } + f->data_ptr = (char *)f->data_ptr + len; + + return len; +} + +static ssize_t seek_raw(frogfs_fh_t *f, long offset, int mode) +{ + ssize_t new_pos = (char *)f->data_ptr - (char *)f->data_start; + + if (mode == LV_FS_SEEK_SET) { + if (offset < 0) { + return -1; + } + if ((size_t)offset > f->data_sz) { + offset = f->data_sz; + } + new_pos = offset; + } else if (mode == LV_FS_SEEK_CUR) { + if (new_pos + offset < 0) { + new_pos = 0; + } else if ((size_t)new_pos > f->data_sz) { + new_pos = f->data_sz; + } else { + new_pos += offset; + } + } else if (mode == LV_FS_SEEK_END) { + if (offset > 0) { + return -1; + } + if (offset < -(ssize_t) f->data_sz) { + offset = 0; + } + new_pos = f->data_sz + offset; + } else { + return -1; + } + + f->data_ptr = (char *)f->data_start + new_pos; + return new_pos; +} + +static size_t tell_raw(frogfs_fh_t *f) +{ + return (char *)f->data_ptr - (char *)f->data_start; +} + +const frogfs_decomp_funcs_t frogfs_decomp_raw = { + .read = read_raw, + .seek = seek_raw, + .tell = tell_raw, +}; diff --git a/src/libs/frogfs/src/frogfs.c b/src/libs/frogfs/src/frogfs.c new file mode 100644 index 0000000000..4c2ed1ce06 --- /dev/null +++ b/src/libs/frogfs/src/frogfs.c @@ -0,0 +1,449 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +/** + * This is a read-only filesystem that uses a sorted hash table to locate + * entries in a monolithic binary. The binary is generated by the mkfrogfs + * tool that comes with this source distribution. + */ + +#include "../../../lv_conf_internal.h" +#if LV_USE_FS_FROGFS + +#include LV_INTTYPES_INCLUDE +#include LV_LIMITS_INCLUDE +#include LV_STDINT_INCLUDE +#include "../../../stdlib/lv_string.h" +#include "../../../stdlib/lv_mem.h" +#include "../../../misc/lv_log.h" +#include "../../../misc/lv_assert.h" +#include "../../../misc/lv_fs.h" + +#include "frogfs_priv.h" +#include "frogfs_format.h" +#include "../include/frogfs/frogfs.h" + + +typedef struct frogfs_fs_t { + const frogfs_head_t *head; /**< fs header pointer */ + const frogfs_hash_t *hash; /**< hash table pointer */ + const frogfs_dir_t *root; /**< root directory entry */ + int num_entries; /**< total number of file system entries */ +} frogfs_fs_t; + +// Returns the current or next highest multiple of 4. +static inline size_t align(size_t n) +{ + return ((n + 4 - 1) / 4) * 4; +} + +// String hashing function. +static inline uint32_t djb2_hash(const char *s) +{ + unsigned long hash = 5381; + + while (*s) { + /* hash = hash * 33 ^ c */ + hash = ((hash << 5) + hash) ^ *s++; + } + + return hash; +} + +static const char *get_name(const frogfs_entry_t *entry) +{ + if (FROGFS_IS_DIR(entry)) { + return (const void *) entry + 8 + (entry->u.child_count * 4); + } else if (FROGFS_IS_FILE(entry) && !FROGFS_IS_COMP(entry)) { + return (const void *) entry + 16; + } else { + return (const void *) entry + 20; + } +} + +frogfs_fs_t *frogfs_init(const frogfs_config_t *conf) +{ + frogfs_fs_t *fs = lv_calloc(1, sizeof(frogfs_fs_t)); + if (fs == NULL) { + LV_LOG_ERROR("calloc failed"); + return NULL; + } + + LV_LOG_TRACE("%p", fs); + + fs->head = (const void *) conf->addr; + if (fs->head == NULL) { + LV_LOG_ERROR("flash mmap not enabled and addr is NULL"); + goto err_out; + } + + if (fs->head->magic != FROGFS_MAGIC) { + LV_LOG_ERROR("frogfs magic not found"); + goto err_out; + } + + if (fs->head->ver_major != FROGFS_VER_MAJOR) { + LV_LOG_ERROR("frogfs major version mismatch. filesystem is v%d.%d and this " + "library is v%d.%d", fs->head->ver_major, fs->head->ver_minor, + FROGFS_VER_MAJOR, FROGFS_VER_MINOR); + goto err_out; + } + + fs->num_entries = fs->head->num_entries; + fs->hash = (const void *) fs->head + sizeof(frogfs_head_t); + fs->root = (const void *) fs->hash + (sizeof(frogfs_hash_t) * fs->num_entries); + + return fs; + +err_out: + frogfs_deinit(fs); + return NULL; +} + +void frogfs_deinit(frogfs_fs_t *fs) +{ + LV_LOG_TRACE("%p", fs); + + lv_free(fs); +} + +const frogfs_entry_t *frogfs_get_entry(const frogfs_fs_t *fs, const char *path) +{ + LV_ASSERT_NULL(fs); + LV_ASSERT_NULL(path); + + while (*path == '/') { + path++; + } + LV_LOG_TRACE("'%s'", path); + + uint32_t hash = djb2_hash(path); + LV_LOG_TRACE("hash %08"PRIx32, hash); + + int first = 0; + int last = fs->num_entries - 1; + int middle; + const frogfs_hash_t *e; + + while (first <= last) { + middle = first + (last - first) / 2; + e = &fs->hash[middle]; + if (e->hash == hash) { + break; + } else if (e->hash < hash) { + first = middle + 1; + } else { + last = middle - 1; + } + } + + if (first > last) { + LV_LOG_TRACE("no match"); + return NULL; + } + + /* move e to the first match */ + while (middle > 0) { + e = fs->hash + middle; + if ((e - 1)->hash != hash) { + break; + } + middle--; + } + + /* walk through canidates and look for a match */ + const frogfs_entry_t *entry; + do { + entry = (const void *) fs->head + e->offs; + char *match = frogfs_get_path(fs, entry); + if (lv_strcmp(path, match) == 0) { + lv_free(match); + LV_LOG_TRACE("entry %d", middle); + return entry; + } + lv_free(match); + entry++; + middle++; + } while ((middle < last) && (e->hash == hash)); + + LV_LOG_WARN("unable to find entry"); + return NULL; +} + +char *frogfs_get_name(const frogfs_entry_t *entry) +{ + char *name = lv_malloc(entry->seg_sz + 1); + lv_memcpy(name, get_name(entry), entry->seg_sz); + name[entry->seg_sz] = '\0'; + return name; +} + +char *frogfs_get_path(const frogfs_fs_t *fs, const frogfs_entry_t *entry) +{ + LV_ASSERT_NULL(entry); + + char *path = lv_calloc(LV_FS_MAX_PATH_LENGTH, 1); + size_t len = 0; + if (!path) { + return NULL; + } + + if (entry->parent == 0) { + return path; + } + + while (entry->parent != 0 && len + entry->seg_sz + 1 < LV_FS_MAX_PATH_LENGTH - 1) { + const frogfs_entry_t *parent = (const void *) fs->head + entry->parent; + if ((const void *) parent == (const void *) fs->root) { + lv_memmove(path + entry->seg_sz, path, len); + lv_memcpy(path, get_name(entry), entry->seg_sz); + len += entry->seg_sz; + break; + } else { + lv_memmove(path + entry->seg_sz + 1, path, len + 1); + path[0] = '/'; + lv_memcpy(path + 1, get_name(entry), entry->seg_sz); + len += entry->seg_sz + 1; + } + entry = parent; + } + + return path; +} + +int frogfs_is_dir(const frogfs_entry_t *entry) +{ + return FROGFS_IS_DIR(entry); +} + +int frogfs_is_file(const frogfs_entry_t *entry) +{ + return FROGFS_IS_FILE(entry); +} + +void frogfs_stat(const frogfs_fs_t *fs, const frogfs_entry_t *entry, + frogfs_stat_t *st) +{ + LV_ASSERT_NULL(fs); + LV_ASSERT_NULL(entry); + + lv_memset(st, 0, sizeof(*st)); + if (FROGFS_IS_DIR(entry)) { + st->type = FROGFS_ENTRY_TYPE_DIR; + } else { + st->type = FROGFS_ENTRY_TYPE_FILE; + const frogfs_file_t *file = (const void *) entry; + st->compression = entry->u.compression; + if (st->compression) { + const frogfs_comp_t *comp = (const void *) entry; + st->compressed_sz = comp->data_sz; + st->size = comp->real_sz; + } else { + st->compressed_sz = file->data_sz; + st->size = file->data_sz; + } + } +} + +frogfs_fh_t *frogfs_open(const frogfs_fs_t *fs, const frogfs_entry_t *entry, + unsigned int flags) +{ + LV_ASSERT_NULL(fs); + LV_ASSERT_NULL(entry); + + if (FROGFS_IS_DIR(entry)) { + return NULL; + } + + const frogfs_file_t *file = (const void *) entry; + + frogfs_fh_t *fh = lv_calloc(1, sizeof(frogfs_fh_t)); + if (fh == NULL) { + LV_LOG_ERROR("calloc failed"); + goto err_out; + } + + LV_LOG_TRACE("%p", fh); + + fh->fs = fs; + fh->file = file; + fh->data_start = (const void *) fs->head + file->data_offs; + fh->data_ptr = fh->data_start; + fh->data_sz = file->data_sz; + fh->flags = flags; + + if (entry->u.compression == 0 || flags & FROGFS_OPEN_RAW) { + fh->real_sz = file->data_sz; + fh->decomp_funcs = &frogfs_decomp_raw; + } +#if CONFIG_FROGFS_USE_MINIZ == 1 + else if ((entry->u.compression == FROGFS_COMP_ALGO_GZIP) || + (entry->u.compression == FROGFS_COMP_ALGO_ZLIB)) { + fh->real_sz = ((frogfs_comp_t *) file)->real_sz; + fh->decomp_funcs = &frogfs_decomp_miniz; + } +#endif +#if CONFIG_FROGFS_USE_ZLIB == 1 + else if ((entry->u.compression == FROGFS_COMP_ALGO_GZIP) || + (entry->u.compression == FROGFS_COMP_ALGO_ZLIB)) { + fh->real_sz = ((frogfs_comp_t *) file)->real_sz; + fh->decomp_funcs = &frogfs_decomp_zlib; + } +#endif +#if CONFIG_FROGFS_USE_HEATSHRINK == 1 + else if (entry->u.compression == FROGFS_COMP_ALGO_HEATSHRINK) { + fh->real_sz = ((frogfs_comp_t *) file)->real_sz; + fh->decomp_funcs = &frogfs_decomp_heatshrink; + } +#endif + else { + LV_LOG_ERROR("unsupported compression type %d", entry->u.compression); + goto err_out; + } + + if (fh->decomp_funcs->open) { + if (fh->decomp_funcs->open(fh, flags) < 0) { + LV_LOG_ERROR("decomp_funcs->fopen"); + goto err_out; + } + } + + return fh; + +err_out: + frogfs_close(fh); + return NULL; +} + +void frogfs_close(frogfs_fh_t *fh) +{ + if (fh == NULL) { + /* do nothing */ + return; + } + + if (fh->decomp_funcs && fh->decomp_funcs->close) { + fh->decomp_funcs->close(fh); + } + + LV_LOG_TRACE("%p", fh); + + lv_free(fh); +} + +int frogfs_is_raw(frogfs_fh_t *fh) +{ + return !!(fh->flags & FROGFS_OPEN_RAW); +} + +ssize_t frogfs_read(frogfs_fh_t *fh, void *buf, size_t len) +{ + LV_ASSERT_NULL(fh); + + if (fh->decomp_funcs->read) { + return fh->decomp_funcs->read(fh, buf, len); + } + + return -1; +} + +ssize_t frogfs_seek(frogfs_fh_t *fh, long offset, int mode) +{ + LV_ASSERT_NULL(fh); + + if (fh->decomp_funcs->seek) { + return fh->decomp_funcs->seek(fh, offset, mode); + } + + return -1; +} + +size_t frogfs_tell(frogfs_fh_t *fh) +{ + LV_ASSERT_NULL(fh); + + if (fh->decomp_funcs->tell) { + return fh->decomp_funcs->tell(fh); + } + + return -1; +} + +size_t frogfs_access(frogfs_fh_t *fh, const void **buf) +{ + LV_ASSERT_NULL(fh); + + *buf = fh->data_start; + return fh->data_sz; +} + +frogfs_dh_t *frogfs_opendir(frogfs_fs_t *fs, const frogfs_entry_t *entry) +{ + LV_ASSERT_NULL(fs); + + if (entry != NULL && FROGFS_IS_FILE(entry)) { + return NULL; + } + + frogfs_dh_t *dh = lv_calloc(1, sizeof(frogfs_dh_t)); + if (dh == NULL) { + LV_LOG_ERROR("calloc failed"); + return NULL; + } + + dh->fs = fs; + if (entry == NULL) { + dh->dir = fs->root; + } else { + dh->dir = (const void *) entry; + } + + return dh; +} + +void frogfs_closedir(frogfs_dh_t *dh) +{ + if (dh == NULL) { + return; + } + + lv_free(dh); +} + +const frogfs_entry_t *frogfs_readdir(frogfs_dh_t *dh) +{ + const frogfs_entry_t *entry = NULL; + + if (dh->dir == NULL) { + return NULL; + } + + if (dh->index < dh->dir->entry.u.child_count) { + entry = (const void *) dh->fs->head + dh->dir->children[dh->index]; + dh->index++; + } + + return entry; +} + +void frogfs_seekdir(frogfs_dh_t *dh, long loc) +{ + LV_ASSERT_NULL(dh); + LV_ASSERT(loc >= 0); + + if (loc < dh->dir->entry.u.child_count) { + dh->index = loc; + } else { + dh->index = dh->dir->entry.u.child_count; + } +} + +long frogfs_telldir(frogfs_dh_t *dh) +{ + LV_ASSERT_NULL(dh); + + return dh->index; +} + +#endif /*LV_USE_FS_FROGFS*/ diff --git a/src/libs/frogfs/src/frogfs_format.h b/src/libs/frogfs/src/frogfs_format.h new file mode 100644 index 0000000000..1cdc1d7687 --- /dev/null +++ b/src/libs/frogfs/src/frogfs_format.h @@ -0,0 +1,90 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#pragma once + +#include "../../../lv_conf_internal.h" +#include LV_STDINT_INCLUDE + + +/** + * \brief Is entry a directory? + */ +#define FROGFS_IS_DIR(e) (e->u.child_count < 0xFF00) + +/** + * \brief Is entry a file? + */ +#define FROGFS_IS_FILE(e) (e->u.child_count >= 0xFF00) + +/** + * \brief Is entry a compressed file? + */ +#define FROGFS_IS_COMP(e) (e->u.child_count > 0xFF00) + +/** + * \brief Filesystem header + */ +typedef struct frogfs_head_t { + uint32_t magic; /**< filesystem magic */ + uint8_t ver_major; /**< major version */ + uint8_t ver_minor; /**< minor version */ + uint16_t num_entries; /** entry count */ + uint32_t bin_sz; /**< binary length */ +} frogfs_head_t; + +/** + * \brief Hash table entry + */ +typedef struct frogfs_hash_t { + uint32_t hash; /**< path hash */ + uint32_t offs; /**< object offset */ +} frogfs_hash_t; + +/** + * \brief Entry header + */ +struct frogfs_entry_t { + uint32_t parent; /**< parent entry offset */ + union { + uint16_t child_count; /**< child entry count */ + uint8_t compression; /**< compression algorithm */ + } u; + uint8_t seg_sz; /**< path segment size (before alignment) */ + uint8_t opts; /**< compression opts */ +}; + +/** + * \brief Directory object header + */ +typedef struct frogfs_dir_t { + const frogfs_entry_t entry; + uint32_t children[]; +} frogfs_dir_t; + +/** + * \brief File object header + */ +typedef struct frogfs_file_t { + const frogfs_entry_t entry; + uint32_t data_offs; + uint32_t data_sz; +} frogfs_file_t; + +/** + * \brief Compressed file object header + */ +typedef struct frogfs_comp_t { + const frogfs_entry_t entry; + uint32_t data_offs; + uint32_t data_sz; /**< data size (before alignment) */ + uint32_t real_sz; /**< expanded size */ +} frogfs_comp_t; + +/** + * \brief Filesystem footer + */ +typedef struct frogfs_foot_t { + uint32_t crc32; /**< crc32 of entire file without this field */ +} frogfs_foot_t; diff --git a/src/libs/frogfs/src/frogfs_priv.h b/src/libs/frogfs/src/frogfs_priv.h new file mode 100644 index 0000000000..9c84b9b6bf --- /dev/null +++ b/src/libs/frogfs/src/frogfs_priv.h @@ -0,0 +1,71 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#pragma once + +#include "../include/frogfs/frogfs_types.h" + +#define FROGFS_PRIVATE_STRUCTS +#include "../include/frogfs/frogfs.h" +#include "frogfs_format.h" + + +typedef struct frogfs_decomp_funcs_t frogfs_decomp_funcs_t; + +/** + * \brief Structure describing a frogfs file entry + */ +struct frogfs_fh_t { + const frogfs_fs_t *fs; /**< frogfs fs pointer */ + const frogfs_file_t *file; /**< file header pointer */ + const void *data_start; /**< data start pointer */ + const void *data_ptr; /**< current data pointer */ + size_t data_sz; /**< data size */ + size_t real_sz; /**< real (expanded) size */ + unsigned int flags; /** open flags */ + const frogfs_decomp_funcs_t *decomp_funcs; /**< decompresor funcs */ + void *decomp_priv; /**< decompressor private data */ +}; + +/** + * \brief Structure describing a frogfs directory entry + */ +struct frogfs_dh_t { + const frogfs_fs_t *fs; /**< frogfs fs pointer */ + const frogfs_dir_t *dir; /**< frogfs entry */ + long index; /**< current index */ +}; + +/** + * \brief Structure of function pointers that describe a decompressor + */ +struct frogfs_decomp_funcs_t { + int (*open)(frogfs_fh_t *f, unsigned int flags); + void (*close)(frogfs_fh_t *f); + ssize_t (*read)(frogfs_fh_t *f, void *buf, size_t len); + ssize_t (*seek)(frogfs_fh_t *f, long offset, int mode); + size_t (*tell)(frogfs_fh_t *f); +}; + +/** + * \brief Raw decompressor functions + */ +extern const frogfs_decomp_funcs_t frogfs_decomp_raw; + +/** + * \brief Heatshrink decompressor functions + */ +extern const frogfs_decomp_funcs_t frogfs_decomp_heatshrink; + +/** + * \brief Miniz decompressor functions + */ +extern const frogfs_decomp_funcs_t frogfs_decomp_miniz; + +/** + * \brief Zlib decompressor functions + */ +extern const frogfs_decomp_funcs_t frogfs_decomp_zlib; + +#include "../include/frogfs/frogfs.h" diff --git a/src/libs/fsdrv/lv_fs_frogfs.c b/src/libs/fsdrv/lv_fs_frogfs.c new file mode 100644 index 0000000000..11a7bde606 --- /dev/null +++ b/src/libs/fsdrv/lv_fs_frogfs.c @@ -0,0 +1,341 @@ +/** + * @file lv_fs_frogfs.c + * + */ + +/********************* + * INCLUDES + *********************/ + +#include "../../../lvgl.h" +#if LV_USE_FS_FROGFS + +#include "../frogfs/include/frogfs/frogfs.h" +#include "../../core/lv_global.h" +#include "../../misc/lv_ll.h" + +#if !LV_FS_IS_VALID_LETTER(LV_FS_FROGFS_LETTER) + #error "Invalid drive letter" +#endif + +/********************* + * DEFINES + *********************/ + +/********************** + * TYPEDEFS + **********************/ + +typedef struct { + lv_ll_t blob_ll; +} fs_drv_data_t; + +typedef struct { + char * path_prefix; + frogfs_fs_t * blob_fs; +} blob_t; + +/********************** + * STATIC PROTOTYPES + **********************/ + +static bool get_blob_and_entry(const char * path, blob_t ** blob_dst, const frogfs_entry_t ** entry_dst); +static void destroy_blob(blob_t * blob); +static void * fs_open(lv_fs_drv_t * drv, const char * path, lv_fs_mode_t mode); +static lv_fs_res_t fs_close(lv_fs_drv_t * drv, void * file_p); +static lv_fs_res_t fs_read(lv_fs_drv_t * drv, void * file_p, void * buf, uint32_t btr, uint32_t * br); +static lv_fs_res_t fs_seek(lv_fs_drv_t * drv, void * file_p, uint32_t pos, lv_fs_whence_t whence); +static lv_fs_res_t fs_tell(lv_fs_drv_t * drv, void * file_p, uint32_t * pos_p); +static void * fs_dir_open(lv_fs_drv_t * drv, const char * path); +static lv_fs_res_t fs_dir_read(lv_fs_drv_t * drv, void * dir_p, char * fn, uint32_t fn_len); +static lv_fs_res_t fs_dir_close(lv_fs_drv_t * drv, void * dir_p); + +/********************** + * STATIC VARIABLES + **********************/ + +/********************** + * MACROS + **********************/ + +#define frogfs_fs_drv (&(LV_GLOBAL_DEFAULT()->frogfs_fs_drv)) + +/********************** + * GLOBAL FUNCTIONS + **********************/ + +void lv_fs_frogfs_init(void) +{ + fs_drv_data_t * data = lv_malloc(sizeof(*data)); + LV_ASSERT_MALLOC(data); + lv_ll_init(&data->blob_ll, sizeof(blob_t)); + + lv_fs_drv_t * fs_drv_p = frogfs_fs_drv; + lv_fs_drv_init(fs_drv_p); + + fs_drv_p->letter = LV_FS_FROGFS_LETTER; + + fs_drv_p->open_cb = fs_open; + fs_drv_p->close_cb = fs_close; + fs_drv_p->read_cb = fs_read; + fs_drv_p->seek_cb = fs_seek; + fs_drv_p->tell_cb = fs_tell; + + fs_drv_p->dir_close_cb = fs_dir_close; + fs_drv_p->dir_open_cb = fs_dir_open; + fs_drv_p->dir_read_cb = fs_dir_read; + + fs_drv_p->user_data = data; + + lv_fs_drv_register(fs_drv_p); +} + +void lv_fs_frogfs_deinit(void) +{ + lv_fs_drv_t * fs_drv_p = frogfs_fs_drv; + fs_drv_data_t * data = fs_drv_p->user_data; + + lv_ll_clear_custom(&data->blob_ll, (void (*)(void *)) destroy_blob); + + lv_free(data); +} + +lv_result_t lv_fs_frogfs_register_blob(const void * blob, const char * path_prefix) +{ + if(path_prefix[0] == '\0') { + LV_LOG_WARN("path prefix should not be zero-length"); + return LV_RESULT_INVALID; + } + + lv_fs_drv_t * fs_drv_p = frogfs_fs_drv; + fs_drv_data_t * data = fs_drv_p->user_data; + + frogfs_config_t frogfs_config = { + .addr = blob, + }; + + frogfs_fs_t * blob_fs = frogfs_init(&frogfs_config); + if(blob_fs == NULL) { + LV_LOG_WARN("Could not register frogfs blob 0x%p", blob); + return LV_RESULT_INVALID; + } + + blob_t * hdl = lv_ll_ins_head(&data->blob_ll); + LV_ASSERT_MALLOC(hdl); + + hdl->path_prefix = lv_strdup(path_prefix); + LV_ASSERT_MALLOC(hdl->path_prefix); + + hdl->blob_fs = blob_fs; + + return LV_RESULT_OK; +} + +void lv_fs_frogfs_unregister_blob(const char * path_prefix) +{ + lv_fs_drv_t * fs_drv_p = frogfs_fs_drv; + fs_drv_data_t * data = fs_drv_p->user_data; + + blob_t * blob_handle; + LV_LL_READ(&data->blob_ll, blob_handle) { + if(lv_streq(path_prefix, blob_handle->path_prefix)) { + break; + } + } + if(blob_handle == NULL) { + LV_LOG_WARN("No frogfs blob with path prefix '%s' to unregister", path_prefix); + return; + } + + destroy_blob(blob_handle); +} + +/********************** + * STATIC FUNCTIONS + **********************/ + +static bool get_blob_and_entry(const char * path, blob_t ** blob_dst, const frogfs_entry_t ** entry_dst) +{ + lv_fs_drv_t * fs_drv_p = frogfs_fs_drv; + fs_drv_data_t * data = fs_drv_p->user_data; + + blob_t * blob; + size_t path_prefix_length; + LV_LL_READ(&data->blob_ll, blob) { + path_prefix_length = lv_strlen(blob->path_prefix); + if(0 == lv_strncmp(path, blob->path_prefix, path_prefix_length) + && (blob->path_prefix[path_prefix_length - 1] == '/' + || blob->path_prefix[path_prefix_length - 1] == '\\' + || path[path_prefix_length] == '\0' + || path[path_prefix_length] == '/' + || path[path_prefix_length] == '\\')) { + break; + } + } + if(blob == NULL) { + LV_LOG_WARN("Path '%s' does not have a prefix that matches any of the registered frogfs blobs", path); + return false; + } + + path += path_prefix_length; + if(path[0] == '/' || path[0] == '\\') path++; + + const frogfs_entry_t * entry = frogfs_get_entry(blob->blob_fs, path); + if(entry == NULL) { + LV_LOG_WARN("No entry '%s' in frogfs blob registered under '%s'", path, blob->path_prefix); + return false; + } + + *blob_dst = blob; + *entry_dst = entry; + return true; +} + +static void destroy_blob(blob_t * blob) +{ + lv_fs_drv_t * fs_drv_p = frogfs_fs_drv; + fs_drv_data_t * data = fs_drv_p->user_data; + + lv_free(blob->path_prefix); + frogfs_deinit(blob->blob_fs); + + lv_ll_remove(&data->blob_ll, blob); + lv_free(blob); +} + +static void * fs_open(lv_fs_drv_t * drv, const char * path, lv_fs_mode_t mode) +{ + LV_UNUSED(drv); + + if(mode & LV_FS_MODE_WR) { + LV_LOG_WARN("Cannot open files for writing with frogfs"); + return NULL; + } + + blob_t * blob; + const frogfs_entry_t * entry; + if(!get_blob_and_entry(path, &blob, &entry)) { + return NULL; + } + + if(frogfs_is_dir(entry)) { + LV_LOG_WARN("Cannot open directory as file with frogfs"); + return NULL; + } + + frogfs_fh_t * fh = frogfs_open(blob->blob_fs, entry, 0); + if(fh == NULL) { + LV_LOG_WARN("Could not open '%s' even though the entry exists in frogfs", path); + return NULL; + } + + return fh; +} + +static lv_fs_res_t fs_close(lv_fs_drv_t * drv, void * file_p) +{ + LV_UNUSED(drv); + frogfs_close(file_p); + return LV_FS_RES_OK; +} + +static lv_fs_res_t fs_read(lv_fs_drv_t * drv, void * file_p, void * buf, uint32_t btr, uint32_t * br) +{ + LV_UNUSED(drv); + + ssize_t res = frogfs_read(file_p, buf, btr); + if(res < 0) { + LV_LOG_WARN("Error reading frogfs file"); + *br = 0; + return LV_FS_RES_UNKNOWN; + } + + *br = res; + return LV_FS_RES_OK; +} + +static lv_fs_res_t fs_seek(lv_fs_drv_t * drv, void * file_p, uint32_t pos, lv_fs_whence_t whence) +{ + LV_UNUSED(drv); + + ssize_t res = frogfs_seek(file_p, pos, whence); + + if(res < 0) { + LV_LOG_WARN("Error `seek`ing frogfs file"); + return LV_FS_RES_UNKNOWN; + } + + return LV_FS_RES_OK; +} + +static lv_fs_res_t fs_tell(lv_fs_drv_t * drv, void * file_p, uint32_t * pos_p) +{ + LV_UNUSED(drv); + + size_t res = frogfs_tell(file_p); + if(res == (size_t) -1) { + LV_LOG_WARN("Error `tell`ing frogfs file"); + return LV_FS_RES_UNKNOWN; + } + + *pos_p = res; + return LV_FS_RES_OK; +} + +static void * fs_dir_open(lv_fs_drv_t * drv, const char * path) +{ + LV_UNUSED(drv); + + blob_t * blob; + const frogfs_entry_t * entry; + if(!get_blob_and_entry(path, &blob, &entry)) { + return NULL; + } + + if(!frogfs_is_dir(entry)) { + LV_LOG_WARN("Cannot open non-directory as directory with frogfs"); + return NULL; + } + + frogfs_dh_t * dh = frogfs_opendir(blob->blob_fs, entry); + if(dh == NULL) { + LV_LOG_WARN("Could not open directory '%s' even though the entry exists in frogfs", path); + return NULL; + } + + return dh; +} + +static lv_fs_res_t fs_dir_read(lv_fs_drv_t * drv, void * dir_p, char * fn, uint32_t fn_len) +{ + LV_UNUSED(drv); + if(fn_len == 0) return LV_FS_RES_INV_PARAM; + + const frogfs_entry_t * entry = frogfs_readdir(dir_p); + if(entry == NULL) { + fn[0] = '\0'; + return LV_FS_RES_OK; + } + + char * name = frogfs_get_name(entry); + + if(frogfs_is_dir(entry)) { + lv_snprintf(fn, fn_len, "/%s", name); + } + else { + lv_strlcpy(fn, name, fn_len); + } + + lv_free(name); /* frogfs `malloc`d it */ + + return LV_FS_RES_OK; +} + +static lv_fs_res_t fs_dir_close(lv_fs_drv_t * drv, void * dir_p) +{ + LV_UNUSED(drv); + frogfs_closedir(dir_p); + return LV_FS_RES_OK; +} + +#endif /*LV_USE_FS_FROGFS*/ diff --git a/src/libs/fsdrv/lv_fsdrv.h b/src/libs/fsdrv/lv_fsdrv.h index cd0f5dd2aa..90c47cdd9e 100644 --- a/src/libs/fsdrv/lv_fsdrv.h +++ b/src/libs/fsdrv/lv_fsdrv.h @@ -67,6 +67,29 @@ void lv_fs_arduino_sd_init(void); void lv_fs_uefi_init(void); #endif +#if LV_USE_FS_FROGFS +void lv_fs_frogfs_init(void); +void lv_fs_frogfs_deinit(void); + +/** + * Mount a frogfs blob at the path prefix. If there is a file "foo.txt" + * in the blob and the blob is registered with `path_prefix` as "my_blob", + * it can be opened later at path "my_blob/foo.txt". + * @param blob a frogfs blob/image from mkfrogfs.py + * @param path_prefix a prefix that will be used to refer to this blob when accessing it. + * @return LV_RESULT_OK or LV_RESULT_INVALID if there was an issue with the blob + */ +lv_result_t lv_fs_frogfs_register_blob(const void * blob, const char * path_prefix); + +/** + * Unmount a frogfs blob that was previously mounted by `lv_fs_frogfs_register_blob`. + * All files and dirs should be closed before calling this. + * @param path_prefix the path prefix that the blob was registered with + */ +void lv_fs_frogfs_unregister_blob(const char * path_prefix); + +#endif /*LV_USE_FS_FROGFS*/ + /********************** * MACROS **********************/ diff --git a/src/libs/gif/AnimatedGIF/LICENSE b/src/libs/gif/AnimatedGIF/LICENSE new file mode 100644 index 0000000000..716f427d06 --- /dev/null +++ b/src/libs/gif/AnimatedGIF/LICENSE @@ -0,0 +1,204 @@ +Copyright 2020 BitBank Software, Inc. All rights reserved. + + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright [yyyy] [name of copyright owner] + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + diff --git a/src/libs/gif/AnimatedGIF/src/AnimatedGIF.h b/src/libs/gif/AnimatedGIF/src/AnimatedGIF.h new file mode 100644 index 0000000000..118ab66b2a --- /dev/null +++ b/src/libs/gif/AnimatedGIF/src/AnimatedGIF.h @@ -0,0 +1,227 @@ +// Copyright 2020 BitBank Software, Inc. All Rights Reserved. +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// http://www.apache.org/licenses/LICENSE-2.0 +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +//=========================================================================== + +#ifndef __ANIMATEDGIF__ +#define __ANIMATEDGIF__ + +#include "../../../../misc/lv_fs.h" +#include "../../../../lv_conf_internal.h" +#include LV_STDINT_INCLUDE +#include LV_LIMITS_INCLUDE +#include "../../../../stdlib/lv_string.h" + +// +// GIF Animator +// Written by Larry Bank +// Copyright (c) 2020 BitBank Software, Inc. +// bitbank@pobox.com +// +// Designed to decode images up to 480x320 on MCUs +// using less than 22K of RAM +// ...and decode any sized image when more RAM is available +// +// ** NEW ** +// Turbo mode added Feb 18, 2024. This option decodes images +// up to 30x faster if there is enough RAM (48K + full framebuffer) +// + +/* GIF Defines and variables */ +#define MAX_CHUNK_SIZE 255 +// +// These 2 macros can be changed to limit the amount of RAM +// required by the decoder. For example, decoding 1-bit images to +// a 128x32 display will not need a max code size of 12 nor a palette +// with 256 entries +// +#define TURBO_BUFFER_SIZE 0x6100 + +// If you intend to decode generic GIFs, you want this value to be 12. If you are using GIFs solely for animations in +// your own project, and you control the GIFs you intend to play, then you can save additional RAM here: +// the decoder must reserve a minimum of 4 byte * (1<10kB RAM, but you will not be able to decode arbitrary +// images anymore. One application to craft such GIFs can be found here (use option -d) +// https://create.stephan-brumme.com/flexigif-lossless-gif-lzw-optimization/ +#define MAX_CODE_SIZE 12 + +#define MAX_COLORS 256 +#define MAX_WIDTH 480 +#define LZW_BUF_SIZE (6*MAX_CHUNK_SIZE) +#define LZW_HIGHWATER (4*MAX_CHUNK_SIZE) +// This buffer is used to store the pixel sequence in reverse order +// it needs to be large enough to hold the longest possible +// sequence (1<iError = GIF_SUCCESS; + pGIF->pfnRead = readMem; + pGIF->pfnSeek = seekMem; + pGIF->pfnDraw = pfnDraw; + pGIF->pfnOpen = NULL; + pGIF->pfnClose = NULL; + pGIF->GIFFile.iSize = iDataSize; + pGIF->GIFFile.pData = pData; + return GIFInit(pGIF); +} /* GIF_openRAM() */ + +int GIF_openFile(GIFIMAGE *pGIF, const char *szFilename, GIF_DRAW_CALLBACK *pfnDraw) +{ + pGIF->iError = GIF_SUCCESS; + pGIF->pfnRead = readFile; + pGIF->pfnSeek = seekFile; + pGIF->pfnDraw = pfnDraw; + pGIF->pfnOpen = NULL; + pGIF->pfnClose = closeFile; + if (LV_FS_RES_OK != lv_fs_open(&pGIF->GIFFile.fHandle, szFilename, LV_FS_MODE_RD)) + return 0; + lv_fs_seek(&pGIF->GIFFile.fHandle, 0, LV_FS_SEEK_END); + uint32_t pos; + lv_fs_tell(&pGIF->GIFFile.fHandle, &pos); + pGIF->GIFFile.iSize = pos; + lv_fs_seek(&pGIF->GIFFile.fHandle, 0, LV_FS_SEEK_SET); + return GIFInit(pGIF); +} /* GIF_openFile() */ + +void GIF_close(GIFIMAGE *pGIF) +{ + if (pGIF->pfnClose) + (*pGIF->pfnClose)(&pGIF->GIFFile.fHandle); +} /* GIF_close() */ + +void GIF_begin(GIFIMAGE *pGIF, unsigned char ucPaletteType) +{ + lv_memset(pGIF, 0, sizeof(GIFIMAGE)); + pGIF->ucPaletteType = ucPaletteType; +} /* GIF_begin() */ + +void GIF_reset(GIFIMAGE *pGIF) +{ + (*pGIF->pfnSeek)(&pGIF->GIFFile, 0); +} /* GIF_reset() */ + +// +// Return value: +// 1 = good decode, more frames exist +// 0 = good decode, no more frames +// -1 = error +// +int GIF_playFrame(GIFIMAGE *pGIF, int *delayMilliseconds, void *pUser) +{ +int rc; + + if (delayMilliseconds) + *delayMilliseconds = 0; // clear any old valid + if (pGIF->GIFFile.iPos >= pGIF->GIFFile.iSize-1) // no more data exists + { + (*pGIF->pfnSeek)(&pGIF->GIFFile, 0); // seek to start + } + if (GIFParseInfo(pGIF, 0)) + { + pGIF->pUser = pUser; + if (pGIF->iError == GIF_EMPTY_FRAME) // don't try to decode it + return 0; + if (pGIF->pTurboBuffer) { // the presence of the Turbo buffer indicates Turbo mode + rc = DecodeLZWTurbo(pGIF, 0); + } else { + rc = DecodeLZW(pGIF, 0); + } + if (rc != 0) // problem + return 0; + } + else + { + return 0; // error parsing the frame info, we may be at the end of the file + } + // Return 1 for more frames or 0 if this was the last frame + if (delayMilliseconds) // if not NULL, return the frame delay time + *delayMilliseconds = pGIF->iFrameDelay; + return (pGIF->GIFFile.iPos < pGIF->GIFFile.iSize-1); +} /* GIF_playFrame() */ + +int GIF_getCanvasWidth(GIFIMAGE *pGIF) +{ + return pGIF->iCanvasWidth; +} /* GIF_getCanvasWidth() */ + +int GIF_getCanvasHeight(GIFIMAGE *pGIF) +{ + return pGIF->iCanvasHeight; +} /* GIF_getCanvasHeight() */ + +int GIF_getLoopCount(GIFIMAGE *pGIF) +{ + return pGIF->iRepeatCount; +} /* GIF_getLoopCount() */ + +int GIF_getComment(GIFIMAGE *pGIF, char *pDest) +{ +int32_t iOldPos; + + iOldPos = pGIF->GIFFile.iPos; // keep old position + (*pGIF->pfnSeek)(&pGIF->GIFFile, pGIF->iCommentPos); + (*pGIF->pfnRead)(&pGIF->GIFFile, (uint8_t *)pDest, pGIF->sCommentLen); + (*pGIF->pfnSeek)(&pGIF->GIFFile, iOldPos); + pDest[pGIF->sCommentLen] = 0; // zero terminate the string + return (int)pGIF->sCommentLen; + +} /* GIF_getComment() */ + +int GIF_getLastError(GIFIMAGE *pGIF) +{ + return pGIF->iError; +} /* GIF_getLastError() */ + +// +// Helper functions for memory based images +// +static int32_t readMem(GIFFILE *pFile, uint8_t *pBuf, int32_t iLen) +{ + int32_t iBytesRead; + + iBytesRead = iLen; + if ((pFile->iSize - pFile->iPos) < iLen) + iBytesRead = pFile->iSize - pFile->iPos; + if (iBytesRead <= 0) + return 0; + lv_memmove(pBuf, &pFile->pData[pFile->iPos], iBytesRead); + pFile->iPos += iBytesRead; + return iBytesRead; +} /* readMem() */ + +static int32_t seekMem(GIFFILE *pFile, int32_t iPosition) +{ + if (iPosition < 0) iPosition = 0; + else if (iPosition >= pFile->iSize) iPosition = pFile->iSize-1; + pFile->iPos = iPosition; + return iPosition; +} /* seekMem() */ + +static void closeFile(lv_fs_file_t *handle) +{ + lv_fs_close(handle); +} /* closeFile() */ + +static int32_t seekFile(GIFFILE *pFile, int32_t iPosition) +{ + if (iPosition < 0) iPosition = 0; + else if (iPosition >= pFile->iSize) iPosition = pFile->iSize-1; + pFile->iPos = iPosition; + lv_fs_seek(&pFile->fHandle, iPosition, LV_FS_SEEK_SET); + return iPosition; +} /* seekMem() */ + +static int32_t readFile(GIFFILE *pFile, uint8_t *pBuf, int32_t iLen) +{ + int32_t iBytesRead; + + iBytesRead = iLen; + if ((pFile->iSize - pFile->iPos) < iLen) + iBytesRead = pFile->iSize - pFile->iPos; + if (iBytesRead <= 0) + return 0; + uint32_t br; + lv_fs_read(&pFile->fHandle, pBuf, iBytesRead, &br); + iBytesRead = br; + pFile->iPos += iBytesRead; + return iBytesRead; +} /* readFile() */ + +// +// The following functions are written in plain C and have no +// 3rd party dependencies, not even the C runtime library +// +// +// Initialize a GIF file and callback access from a file on SD or memory +// returns 1 for success, 0 for failure +// Fills in the canvas size of the GIFIMAGE structure +// +static int GIFInit(GIFIMAGE *pGIF) +{ + pGIF->GIFFile.iPos = 0; // start at beginning of file + if (!GIFParseInfo(pGIF, 1)) // gather info for the first frame + return 0; // something went wrong; not a GIF file? + (*pGIF->pfnSeek)(&pGIF->GIFFile, 0); // seek back to start of the file + if (pGIF->iCanvasWidth > MAX_WIDTH || pGIF->iCanvasHeight > 32767) { // too big or corrupt + pGIF->iError = GIF_TOO_WIDE; + return 0; + } + return 1; +} /* GIFInit() */ + +// +// Parse the GIF header, gather the size and palette info +// If called with bInfoOnly set to true, it will test for a valid file +// and return the canvas size only +// Returns 1 for success, 0 for failure +// +static int GIFParseInfo(GIFIMAGE *pPage, int bInfoOnly) +{ + int i, j, iColorTableBits; + int iBytesRead; + unsigned char c, *p; + int32_t iOffset = 0; + int32_t iStartPos = pPage->GIFFile.iPos; // starting file position + int iReadSize; + + pPage->bUseLocalPalette = 0; // assume no local palette + pPage->bEndOfFrame = 0; // we're just getting started + pPage->iFrameDelay = 0; // may not have a gfx extension block + pPage->iRepeatCount = -1; // assume NETSCAPE loop count is not specified + iReadSize = MAX_CHUNK_SIZE; + // If you try to read past the EOF, the SD lib will return garbage data + if (iStartPos + iReadSize > pPage->GIFFile.iSize) + iReadSize = (pPage->GIFFile.iSize - iStartPos - 1); + p = pPage->ucFileBuf; + iBytesRead = (*pPage->pfnRead)(&pPage->GIFFile, pPage->ucFileBuf, iReadSize); // 255 is plenty for now + + if (iBytesRead != iReadSize) // we're at the end of the file + { + pPage->iError = GIF_EARLY_EOF; + return 0; + } + if (iStartPos == 0) // start of the file + { // canvas size + if (lv_memcmp(p, "GIF89", 5) != 0 && lv_memcmp(p, "GIF87", 5) != 0) // not a GIF file + { + pPage->iError = GIF_BAD_FILE; + return 0; + } + pPage->iCanvasWidth = pPage->iWidth = INTELSHORT(&p[6]); + pPage->iCanvasHeight = pPage->iHeight = INTELSHORT(&p[8]); + pPage->iBpp = ((p[10] & 0x70) >> 4) + 1; + iColorTableBits = (p[10] & 7) + 1; // Log2(size) of the color table + pPage->ucBackground = p[11]; // background color + pPage->ucGIFBits = 0; + iOffset = 13; + if (p[10] & 0x80) // global color table? + { // by default, convert to byte-reversed RGB565 for immediate use + // Read enough additional data for the color table + iBytesRead += (*pPage->pfnRead)(&pPage->GIFFile, &pPage->ucFileBuf[iBytesRead], 3*(1<ucPaletteType == GIF_PALETTE_RGB565_LE || pPage->ucPaletteType == GIF_PALETTE_RGB565_BE) { + for (i=0; i<(1<> 3) << 11); // R + usRGB565 |= ((p[iOffset+1] >> 2) << 5); // G + usRGB565 |= (p[iOffset+2] >> 3); // B + if (pPage->ucPaletteType == GIF_PALETTE_RGB565_LE) + pPage->pPalette[i] = usRGB565; + else + pPage->pPalette[i] = (usRGB565 << 8) | (usRGB565 >> 8); // SPI wants MSB first + iOffset += 3; + } + } else if (pPage->ucPaletteType == GIF_PALETTE_1BPP || pPage->ucPaletteType == GIF_PALETTE_1BPP_OLED) { + uint8_t *pPal1 = (uint8_t*)pPage->pPalette; + for (i=0; i<(1<= 512); // bright enough = 1 + iOffset += 3; + } + } else { // just copy it as-is (RGB888 & RGB8888 output) + lv_memcpy(pPage->pPalette, &p[iOffset], (1<ucGIFBits = p[iOffset+1]; // packed fields + pPage->iFrameDelay = (INTELSHORT(&p[iOffset+2]))*10; // delay in ms + if (pPage->iFrameDelay <= 1) // 0-1 is going to make it run at 60fps; use 100 (10fps) as a reasonable substitute + pPage->iFrameDelay = 100; + if (pPage->ucGIFBits & 1) // transparent color is used + pPage->ucTransparent = p[iOffset+4]; // transparent color index + iOffset += 6; + } + // else // error + break; + case 0xff: /* App extension */ + c = 1; + while (c) /* Skip all data sub-blocks */ + { + c = p[iOffset++]; /* Block length */ + if ((iBytesRead - iOffset) < (c+32)) // need to read more data first + { + lv_memmove(pPage->ucFileBuf, &pPage->ucFileBuf[iOffset], (iBytesRead-iOffset)); // move existing data down + iBytesRead -= iOffset; + iStartPos += iOffset; + iOffset = 0; + iBytesRead += (*pPage->pfnRead)(&pPage->GIFFile, &pPage->ucFileBuf[iBytesRead], c+32); + } + if (c == 11) // fixed block length + { // Netscape app block contains the repeat count + if (lv_memcmp(&p[iOffset], "NETSCAPE2.0", 11) == 0) + { + if (p[iOffset+11] == 3 && p[iOffset+12] == 1) // loop count + pPage->iRepeatCount = INTELSHORT(&p[iOffset+13]); + } + } + iOffset += (int)c; /* Skip to next sub-block */ + } + break; + case 0x01: /* Text extension */ + c = 1; + j = 0; + while (c) /* Skip all data sub-blocks */ + { + c = p[iOffset++]; /* Block length */ + if (j == 0) // use only first block + { + j = c; + if (j > 127) // max comment length = 127 + j = 127; + // memcpy(pPage->szInfo1, &p[iOffset], j); + // pPage->szInfo1[j] = '\0'; + j = 1; + } + iOffset += (int)c; /* Skip this sub-block */ + } + break; + case 0xfe: /* Comment */ + c = 1; + while (c) /* Skip all data sub-blocks */ + { + c = p[iOffset++]; /* Block length */ + if ((iBytesRead - iOffset) < (c+32)) // need to read more data first + { + lv_memmove(pPage->ucFileBuf, &pPage->ucFileBuf[iOffset], (iBytesRead-iOffset)); // move existing data down + iBytesRead -= iOffset; + iStartPos += iOffset; + iOffset = 0; + iBytesRead += (*pPage->pfnRead)(&pPage->GIFFile, &pPage->ucFileBuf[iBytesRead], c+32); + } + if (pPage->iCommentPos == 0) // Save first block info + { + pPage->iCommentPos = iStartPos + iOffset; + pPage->sCommentLen = c; + } + iOffset += (int)c; /* Skip this sub-block */ + } + break; + default: + /* Bad header info */ + pPage->iError = GIF_DECODE_ERROR; + return 0; + } /* switch */ + } + else // invalid byte, stop decoding + { + if (pPage->GIFFile.iSize - iStartPos < 32) // non-image bytes at end of file? + pPage->iError = GIF_EMPTY_FRAME; + else + /* Bad header info */ + pPage->iError = GIF_DECODE_ERROR; + return 0; + } + } /* while */ + if (bInfoOnly) + return 1; // we've got the info we needed, leave + if (p[iOffset] == ';') { // end of file, quit and return a correct error code + pPage->iError = GIF_EMPTY_FRAME; + return 1; + } + + if (p[iOffset] == ',') + iOffset++; + // This particular frame's size and position on the main frame (if animated) + pPage->iX = INTELSHORT(&p[iOffset]); + pPage->iY = INTELSHORT(&p[iOffset+2]); + pPage->iWidth = INTELSHORT(&p[iOffset+4]); + pPage->iHeight = INTELSHORT(&p[iOffset+6]); + if (pPage->iWidth > pPage->iCanvasWidth || pPage->iHeight > pPage->iCanvasHeight || + pPage->iWidth + pPage->iX > pPage->iCanvasWidth || pPage->iHeight + pPage->iY > pPage->iCanvasHeight) { + pPage->iError = GIF_DECODE_ERROR; // must be a corrupt file to encounter this error here + return 0; + } + iOffset += 8; + + /* Image descriptor + 7 6 5 4 3 2 1 0 M=0 - use global color map, ignore pixel + M I 0 0 0 pixel M=1 - local color map follows, use pixel + I=0 - Image in sequential order + I=1 - Image in interlaced order + pixel+1 = # bits per pixel for this image + */ + pPage->ucMap = p[iOffset++]; + if (pPage->ucMap & 0x80) // local color table? + {// by default, convert to byte-reversed RGB565 for immediate use + j = (1<<((pPage->ucMap & 7)+1)); + // Read enough additional data for the color table + iBytesRead += (*pPage->pfnRead)(&pPage->GIFFile, &pPage->ucFileBuf[iBytesRead], j*3); + if (pPage->ucPaletteType == GIF_PALETTE_RGB565_LE || pPage->ucPaletteType == GIF_PALETTE_RGB565_BE) + { + for (i=0; i> 3) << 11); // R + usRGB565 |= ((p[iOffset+1] >> 2) << 5); // G + usRGB565 |= (p[iOffset+2] >> 3); // B + if (pPage->ucPaletteType == GIF_PALETTE_RGB565_LE) + pPage->pLocalPalette[i] = usRGB565; + else + pPage->pLocalPalette[i] = (usRGB565 << 8) | (usRGB565 >> 8); // SPI wants MSB first + iOffset += 3; + } + } else if (pPage->ucPaletteType == GIF_PALETTE_1BPP || pPage->ucPaletteType == GIF_PALETTE_1BPP_OLED) { + uint8_t *pPal1 = (uint8_t*)pPage->pLocalPalette; + for (i=0; i= 512); // bright enough = 1 + iOffset += 3; + } + } else { // just copy it as-is + lv_memcpy(pPage->pLocalPalette, &p[iOffset], j * 3); + iOffset += j*3; + } + pPage->bUseLocalPalette = 1; + } + pPage->ucCodeStart = p[iOffset++]; /* initial code size */ + /* Since GIF can be 1-8 bpp, we only allow 1,4,8 */ + pPage->iBpp = cGIFBits[pPage->ucCodeStart]; + // we are re-using the same buffer turning GIF file data + // into "pure" LZW + pPage->iLZWSize = 0; // we're starting with no LZW data yet + c = 1; // get chunk length + while (c && iOffset < iBytesRead) + { +// Serial.printf("iOffset=%d, iBytesRead=%d\n", iOffset, iBytesRead); + c = p[iOffset++]; // get chunk length +// Serial.printf("Chunk size = %d\n", c); + if (c <= (iBytesRead - iOffset)) + { + lv_memcpy(&pPage->ucLZW[pPage->iLZWSize], &p[iOffset], c); + pPage->iLZWSize += c; + iOffset += c; + } + else // partial chunk in our buffer + { + int iPartialLen = (iBytesRead - iOffset); + lv_memcpy(&pPage->ucLZW[pPage->iLZWSize], &p[iOffset], iPartialLen); + pPage->iLZWSize += iPartialLen; + iOffset += iPartialLen; + (*pPage->pfnRead)(&pPage->GIFFile, &pPage->ucLZW[pPage->iLZWSize], c - iPartialLen); + pPage->iLZWSize += (c - iPartialLen); + } + if (c == 0) + pPage->bEndOfFrame = 1; // signal not to read beyond the end of the frame + } +// seeking on an SD card is VERY VERY SLOW, so use the data we've already read by de-chunking it +// in this case, there's too much data, so we have to seek backwards a bit + if (iOffset < iBytesRead) + { +// Serial.printf("Need to seek back %d bytes\n", iBytesRead - iOffset); + (*pPage->pfnSeek)(&pPage->GIFFile, iStartPos + iOffset); // position file to new spot + } + return 1; // we are now at the start of the chunk data +} /* GIFParseInfo() */ +// +// Gather info about an animated GIF file +// +int GIF_getInfo(GIFIMAGE *pPage, GIFINFO *pInfo) +{ + int iOff, iNumFrames; + int iDelay, iMaxDelay, iMinDelay, iTotalDelay; + int iReadAmount; + int iDataAvailable = 0; + int iDataRemaining = 0; + // uint32_t lFileOff = 0; + int bDone = 0; + int bExt; + uint8_t c, *cBuf; + + iMaxDelay = iTotalDelay = 0; + iMinDelay = 10000; + iNumFrames = 1; + iDataRemaining = pPage->GIFFile.iSize; + cBuf = (uint8_t *) pPage->ucFileBuf; + (*pPage->pfnSeek)(&pPage->GIFFile, 0); + iDataAvailable = (*pPage->pfnRead)(&pPage->GIFFile, cBuf, FILE_BUF_SIZE); + iDataRemaining -= iDataAvailable; + // lFileOff += iDataAvailable; + iOff = 10; + c = cBuf[iOff]; // get info bits + iOff += 3; /* Skip flags, background color & aspect ratio */ + if (c & 0x80) /* Deal with global color table */ + { + c &= 7; /* Get the number of colors defined */ + iOff += (2<pfnRead)(&pPage->GIFFile, &cBuf[iDataAvailable], FILE_BUF_SIZE-iDataAvailable); + iDataAvailable += iReadAmount; + iDataRemaining -= iReadAmount; + // lFileOff += iReadAmount; + } + switch(cBuf[iOff]) + { + case 0x3b: /* End of file */ + /* we were fooled into thinking there were more pages */ + iNumFrames--; + goto gifpagesz; + // F9 = Graphic Control Extension (fixed length of 4 bytes) + // FE = Comment Extension + // FF = Application Extension + // 01 = Plain Text Extension + case 0x21: /* Extension block */ + if (cBuf[iOff+1] == 0xf9 && cBuf[iOff+2] == 4) // Graphic Control Extension + { + //cBuf[iOff+3]; // page disposition flags + iDelay = cBuf[iOff+4]; // delay low byte + iDelay |= ((uint16_t)(cBuf[iOff+5]) << 8); // delay high byte + if (iDelay < 2) // too fast, provide a default + iDelay = 2; + iDelay *= 10; // turn JIFFIES into milliseconds + iTotalDelay += iDelay; + if (iDelay > iMaxDelay) iMaxDelay = iDelay; + else if (iDelay < iMinDelay) iMinDelay = iDelay; + // (cBuf[iOff+6]; // transparent color index + } + iOff += 2; /* skip to length */ + iOff += (int)cBuf[iOff]; /* Skip the data block */ + iOff++; + // block terminator or optional sub blocks + c = cBuf[iOff++]; /* Skip any sub-blocks */ + while (c) + { + iOff += (int)c; + c = cBuf[iOff++]; + if ((iDataAvailable - iOff) < (c+258)) // need to read more data first + { + lv_memmove(cBuf, &cBuf[iOff], (iDataAvailable-iOff)); // move existing data down + iDataAvailable -= iOff; + iOff = 0; + iReadAmount = (*pPage->pfnRead)(&pPage->GIFFile, &cBuf[iDataAvailable], FILE_BUF_SIZE-iDataAvailable); + iDataAvailable += iReadAmount; + iDataRemaining -= iReadAmount; + // lFileOff += iReadAmount; + } + } + if (c != 0) // problem, we went past the end + { + iNumFrames--; // possible corrupt data; stop + goto gifpagesz; + } + break; + case 0x2c: /* Start of image data */ + bExt = 0; /* Stop doing extension blocks */ + break; + default: + /* Corrupt data, stop here */ + iNumFrames--; + goto gifpagesz; + } // switch + } // while + if (iOff >= iDataAvailable) // problem + { + iNumFrames--; // possible corrupt data; stop + goto gifpagesz; + } + /* Start of image data */ + c = cBuf[iOff+9]; /* Get the flags byte */ + iOff += 10; /* Skip image position and size */ + if (c & 0x80) /* Local color table */ + { + c &= 7; + iOff += (2<pfnRead)(&pPage->GIFFile, &cBuf[iDataAvailable], FILE_BUF_SIZE-iDataAvailable); + iDataAvailable += iReadAmount; + iDataRemaining -= iReadAmount; + // lFileOff += iReadAmount; + } + c = cBuf[iOff++]; + while (c) /* While there are more data blocks */ + { + if (iOff > (3*FILE_BUF_SIZE/4) && iDataRemaining > 0) /* Near end of buffer, re-align */ + { + lv_memmove(cBuf, &cBuf[iOff], (iDataAvailable-iOff)); // move existing data down + iDataAvailable -= iOff; + iOff = 0; + iReadAmount = (FILE_BUF_SIZE - iDataAvailable); + if (iReadAmount > iDataRemaining) + iReadAmount = iDataRemaining; + iReadAmount = (*pPage->pfnRead)(&pPage->GIFFile, &cBuf[iDataAvailable], iReadAmount); + iDataAvailable += iReadAmount; + iDataRemaining -= iReadAmount; + // lFileOff += iReadAmount; + } + iOff += (int)c; /* Skip this data block */ +// if ((int)lFileOff + iOff > pPage->GIFFile.iSize) // past end of file, stop +// { +// iNumFrames--; // don't count this page +// break; // last page is corrupted, don't use it +// } + c = cBuf[iOff++]; /* Get length of next */ + } + /* End of image data, check for more pages... */ + if (cBuf[iOff] == 0x3b || (iDataRemaining == 0 && (iDataAvailable - iOff) < 32)) + { + bDone = 1; /* End of file has been reached */ + } + else /* More pages to scan */ + { + iNumFrames++; + // read new page data starting at this offset + if (pPage->GIFFile.iSize > FILE_BUF_SIZE && iDataRemaining > 0) // since we didn't read the whole file in one shot + { + lv_memmove(cBuf, &cBuf[iOff], (iDataAvailable-iOff)); // move existing data down + iDataAvailable -= iOff; + iOff = 0; + iReadAmount = (FILE_BUF_SIZE - iDataAvailable); + if (iReadAmount > iDataRemaining) + iReadAmount = iDataRemaining; + iReadAmount = (*pPage->pfnRead)(&pPage->GIFFile, &cBuf[iDataAvailable], iReadAmount); + iDataAvailable += iReadAmount; + iDataRemaining -= iReadAmount; + // lFileOff += iReadAmount; + } + } + } /* while !bDone */ +gifpagesz: + pInfo->iFrameCount = iNumFrames; + pInfo->iMaxDelay = iMaxDelay; + pInfo->iMinDelay = iMinDelay; + pInfo->iDuration = iTotalDelay; + return 1; +} /* GIF_getInfo() */ + +// +// Unpack more chunk data for decoding +// returns 1 to signify more data available for this image +// 0 indicates there is no more data +// +static int GIFGetMoreData(GIFIMAGE *pPage) +{ + int iDelta = (pPage->iLZWSize - pPage->iLZWOff); + int iLZWBufSize; + unsigned char c = 1; + + // Turbo mode uses combined buffers to read more compressed data + iLZWBufSize = (pPage->pTurboBuffer) ? LZW_BUF_SIZE_TURBO : LZW_BUF_SIZE; + // move any existing data down + if (pPage->bEndOfFrame || iDelta >= (iLZWBufSize - MAX_CHUNK_SIZE) || iDelta <= 0) + return 1; // frame is finished or buffer is already full; no need to read more data + if (pPage->iLZWOff != 0) + { +// NB: memcpy() fails on some systems because the src and dest ptrs overlap +// so copy the bytes in a simple loop to avoid problems + for (int i=0; iiLZWSize - pPage->iLZWOff; i++) { + pPage->ucLZW[i] = pPage->ucLZW[i + pPage->iLZWOff]; + } + pPage->iLZWSize -= pPage->iLZWOff; + pPage->iLZWOff = 0; + } + while (c && pPage->GIFFile.iPos < pPage->GIFFile.iSize && pPage->iLZWSize < (iLZWBufSize-MAX_CHUNK_SIZE)) + { + (*pPage->pfnRead)(&pPage->GIFFile, &c, 1); // current length + (*pPage->pfnRead)(&pPage->GIFFile, &pPage->ucLZW[pPage->iLZWSize], c); + pPage->iLZWSize += c; + } + if (c == 0) // end of frame + pPage->bEndOfFrame = 1; + return (c != 0 && pPage->GIFFile.iPos < pPage->GIFFile.iSize); // more data available? +} /* GIFGetMoreData() */ +// +// Draw and convert pixels when the user wants fully rendered output +// +static void DrawCooked(GIFIMAGE *pPage, GIFDRAW *pDraw, void *pDest) +{ + uint8_t c, *s, *d8, *pEnd; + uint8_t *pActivePalette; + + pActivePalette = (pPage->bUseLocalPalette) ? (uint8_t *)pPage->pLocalPalette : (uint8_t *)pPage->pPalette; + // d8 points to the line in the full sized canvas where the new opaque pixels will be merged + d8 = &pPage->pFrameBuffer[pDraw->iX + (pDraw->iY + pDraw->y) * pPage->iCanvasWidth]; + s = pDraw->pPixels; // s points to the newly decoded pixels of this line of the current frame + pEnd = s + pDraw->iWidth; // faster way to loop over the source pixels - eliminates a counter variable + + if (pPage->ucPaletteType == GIF_PALETTE_1BPP || pPage->ucPaletteType == GIF_PALETTE_1BPP_OLED) { // 1-bit mono + uint8_t *d = NULL; + uint8_t *pPal = pActivePalette; + uint8_t uc, ucMask; + int iPitch = 0; + if (pPage->ucPaletteType == GIF_PALETTE_1BPP) { // horizontal pixels + d = pPage->pFrameBuffer; + iPitch = (pPage->iCanvasWidth+7)/8; + d += (pPage->iCanvasWidth * pPage->iCanvasHeight); + d += pDraw->iX/8; // starting column + d += (pDraw->iY + pDraw->y) * iPitch; + // Apply the new pixels to the main image and generate 1-bpp output + if (pDraw->ucHasTransparency) { // if transparency used + uint8_t ucTransparent = pDraw->ucTransparent; + if (pDraw->ucDisposalMethod == 2) { // restore to background color + uint8_t u8BG = pPal[pDraw->ucBackground]; + if (u8BG == 1) u8BG = 0xff; // set all bits to use mask + uc = *d; ucMask = (0x80 >> (pDraw->iX & 7));; + while (s < pEnd) { + c = *s++; + if (c != ucTransparent) { + if (pPal[c]) + uc |= ucMask; + else + uc &= ~ucMask; + *d8++ = c; + } else { + uc |= (u8BG & ucMask); // transparent pixel is restored to background color + *d8++ = pDraw->ucBackground; + } + ucMask >>= 1; + if (ucMask == 0) { // write the completed byte + *d++ = uc; + uc = *d; + ucMask = 0x80; + } + } + *d = uc; // write last partial byte + } else { // no disposal, just write non-transparent pixels + uc = *d; ucMask = (0x80 >> (pDraw->iX & 7)); + while (s < pEnd) { + c = *s++; + if (c != ucTransparent) { + if (pPal[c]) + uc |= ucMask; + else + uc &= ~ucMask; + *d8 = c; + } + d8++; + ucMask >>= 1; + if (ucMask == 0) { + *d++ = uc; + uc = *d; + ucMask = 0x80; + } + } + *d = uc; + } + } else { // convert everything as opaque + uc = *d; ucMask = (0x80 >> (pDraw->iX & 7)); // left pixel is MSB + while (s < pEnd) { + c = *d8++ = *s++; // just write the new opaque pixels over the old + if (pPal[c]) // if non-zero, set white pixel + uc |= ucMask; + else + uc &= ~ucMask; + ucMask >>= 1; + if (ucMask == 0) { // time to write the current byte + *d++ = uc; + uc = *d; + ucMask = 0x80; + } + } + *d = uc; + } + } else { // vertical pixels + d = pPage->pFrameBuffer; + d += (pPage->iCanvasWidth * pPage->iCanvasHeight); + d += pDraw->iX; // starting column + d += ((pDraw->iY + pDraw->y)>>3) * pPage->iCanvasWidth; + ucMask = 1 << ((pDraw->iY + pDraw->y) & 7); + // Apply the new pixels to the main image and generate 1-bpp output + if (pDraw->ucHasTransparency) { // if transparency used + uint8_t ucTransparent = pDraw->ucTransparent; + if (pDraw->ucDisposalMethod == 2) { // restore to background color + uint8_t u8BG = pPal[pDraw->ucBackground]; + u8BG *= ucMask; // set the right bit + while (s < pEnd) { + c = *s++; + uc = *d & ~ucMask; // clear old pixel + if (c != ucTransparent) { + uc |= (pPal[c] * ucMask); + *d8++ = c; + } else { + uc |= u8BG; // transparent pixel is restored to background color + *d8++ = pDraw->ucBackground; + } + *d++ = uc; // write back the updated pixel + } + } else { // no disposal, just write non-transparent pixels + while (s < pEnd) { + c = *s++; + uc = *d & ~ucMask; + if (c != ucTransparent) { + *d = uc | (pPal[c] * ucMask); + *d8 = c; + } + d++; + d8++; + } + } + } else { // convert everything as opaque + while (s < pEnd) { + c = *d8++ = *s++; // just write the new opaque pixels over the old + uc = *d & ~ucMask; + *d++ = uc | (pPal[c] * ucMask); + } + } + } + } else if (pPage->ucPaletteType == GIF_PALETTE_RGB565_LE || pPage->ucPaletteType == GIF_PALETTE_RGB565_BE) { + uint16_t *d, *pPal = (uint16_t *)pActivePalette; + d = (uint16_t *)pDest; // dest pointer to the cooked pixels + // Apply the new pixels to the main image + if (pDraw->ucHasTransparency) { // if transparency used + uint8_t ucTransparent = pDraw->ucTransparent; + if (pDraw->ucDisposalMethod == 2) { // restore to background color + uint16_t u16BG = pPal[pDraw->ucBackground]; + while (s < pEnd) { + c = *s++; + if (c != ucTransparent) { + *d++ = pPal[c]; + *d8++ = c; + } else { + *d++ = u16BG; // transparent pixel is restored to background color + *d8++ = pDraw->ucBackground; + } + } + } else { // no disposal, just write non-transparent pixels + while (s < pEnd) { + c = *s++; + if (c != ucTransparent) { + *d = pPal[c]; + *d8 = c; + } + d++; + d8++; + } + } + } else { // convert all pixels through the palette without transparency +#if REGISTER_WIDTH == 64 + // parallelize the writes + // optimizing for the write buffer helps; reading 4 bytes at a time vs 1 doesn't on M1 + while (s < pEnd + 4) { // group 4 pixels + BIGUINT bu; + uint8_t s0, s1, s2, s3; + uint16_t d1, d2, d3; + *(uint32_t *)d8 = *(uint32_t *)s; // just copy new opaque pixels over the old + s0 = s[0]; s1 = s[1]; s2 = s[2]; s3 = s[3]; + bu = pPal[s0]; // not much difference on Apple M1 + d1 = pPal[s1]; // but other processors may gain + d2 = pPal[s2]; // from unrolling the reads + d3 = pPal[s3]; + bu |= (BIGUINT)d1 << 16; + bu |= (BIGUINT)d2 << 32; + bu |= (BIGUINT)d3 << 48; + s += 4; + d8 += 4; + *(BIGUINT *)d = bu; + d += 4; + } +#endif + while (s < pEnd) { + c = *d8++ = *s++; // just write the new opaque pixels over the old + *d++ = pPal[c]; // and create the cooked pixels through the palette + } + } + } else { // 24bpp or 32bpp + uint8_t pixel, *d, *pPal; + int x; + d = (uint8_t *)pDest; + pPal = pActivePalette; + if (pDraw->ucHasTransparency) { + uint8_t ucTransparent = pDraw->ucTransparent; + if (pDraw->ucDisposalMethod == 2) { // restore to background color + uint8_t * bg = &pPal[pDraw->ucBackground * 3]; + if (pPage->ucPaletteType == GIF_PALETTE_RGB888) { + while (s < pEnd) { + pixel = *s++; + if (pixel != ucTransparent) { + *d8++ = pixel; + d[0] = pPal[(pixel * 3) + 2]; + d[1] = pPal[(pixel * 3) + 1]; + d[2] = pPal[(pixel * 3) + 0]; + d += 3; + } else { + *d8++ = pDraw->ucBackground; + d[0] = bg[2]; + d[1] = bg[1]; + d[2] = bg[0]; + d += 3; + } + } + } else { /* GIF_PALETTE_RGB8888 */ + while (s < pEnd) { + pixel = *s++; + if (pixel != ucTransparent) { + *d8++ = pixel; + d[0] = pPal[(pixel * 3) + 2]; + d[1] = pPal[(pixel * 3) + 1]; + d[2] = pPal[(pixel * 3) + 0]; + d[3] = 0xFF; + d += 4; + } else { + *d8++ = pDraw->ucBackground; + d[3] = 0x00; + d += 4; + } + } + } + } else { // no disposal, just write non-transparent pixels + if (pPage->ucPaletteType == GIF_PALETTE_RGB888) { + for (x=0; xiWidth; x++) { + pixel = *s++; + if (pixel != ucTransparent) { + *d8 = pixel; + d[0] = pPal[(pixel * 3) + 2]; // convert to RGB888 pixels + d[1] = pPal[(pixel * 3) + 1]; + d[2] = pPal[(pixel * 3) + 0]; + } + d8++; + d += 3; + } + } else { // must be RGBA32 + for (x=0; xiWidth; x++) { + pixel = *s++; + if (pixel != ucTransparent) { + *d8 = pixel; + d[0] = pPal[(pixel * 3) + 2]; // convert to RGB8888 pixels + d[1] = pPal[(pixel * 3) + 1]; + d[2] = pPal[(pixel * 3) + 0]; + d[3] = 0xff; + } + d8++; + d += 4; + } + } + } + } else { // no transparency + if (pPage->ucPaletteType == GIF_PALETTE_RGB888) { + for (x=0; xiWidth; x++) { + pixel = *d8++ = *s++; + *d++ = pPal[(pixel * 3) + 2]; // convert to RGB888 pixels + *d++ = pPal[(pixel * 3) + 1]; + *d++ = pPal[(pixel * 3) + 0]; + } + } else { // must be RGBA32 + for (x=0; xiWidth; x++) { + pixel = *d8++ = *s++; + *d++ = pPal[(pixel * 3) + 2]; // convert to RGB8888 pixels + *d++ = pPal[(pixel * 3) + 1]; + *d++ = pPal[(pixel * 3) + 0]; + *d++ = 0xff; + } + } + } // opaque + } +} /* DrawCooked() */ + +// +// Handle transparent pixels and disposal method +// Used only when a frame buffer is allocated +// +static void DrawNewPixels(GIFIMAGE *pPage, GIFDRAW *pDraw) +{ + uint8_t *d, *s; + int x, iPitch = pPage->iCanvasWidth; + + s = pDraw->pPixels; + d = &pPage->pFrameBuffer[pDraw->iX + (pDraw->y + pDraw->iY) * iPitch]; // dest pointer in our complete canvas buffer + + // Apply the new pixels to the main image + if (pDraw->ucHasTransparency) { // if transparency used + uint8_t c, ucTransparent = pDraw->ucTransparent; + if (pDraw->ucDisposalMethod == 2) { + lv_memset(d, pDraw->ucBackground, pDraw->iWidth); // start with background color + } + for (x=0; xiWidth; x++) { + c = *s++; + if (c != ucTransparent) + *d = c; + d++; + } + } else { // disposal method doesn't matter when there aren't any transparent pixels + lv_memcpy(d, s, pDraw->iWidth); // just overwrite the old pixels + } +} /* DrawNewPixels() */ +// +// LZWCopyBytes +// +// Output the bytes for a single code (checks for buffer len) +// +static int LZWCopyBytes(unsigned char *buf, int iOffset, uint32_t *pSymbols, uint16_t *pLengths) +{ +int iLen; +uint8_t c, *s, *d, *pEnd; +uint32_t u32Offset; + + iLen = *pLengths; + u32Offset = *pSymbols; + // The string data frequently writes past the end of the framebuffer (past last pixel) + // ...but with the placement of our code tables AFTER the framebuffer, it doesn't matter + // Adding a check for buffer overrun here slows everything down about 10% + s = &buf[u32Offset & 0x7fffff]; + d = &buf[iOffset]; + pEnd = &d[iLen]; + while (d < pEnd) // most frequent are 1-8 bytes in length, copy 4 or 8 bytes in these cases too + { +#ifdef ALLOWS_UNALIGNED +// This is a significant perf improvement compared to copying 1 byte at a time +// even though it will often copy too many bytes + BIGUINT tmp = *(BIGUINT *) s; + s += sizeof(BIGUINT); + *(BIGUINT *)d = tmp; + d += sizeof(BIGUINT); +#else +// CPUs which enforce unaligned address exceptions must do it 1 byte at a time + *d++ = *s++; +#endif + } + if (u32Offset & 0x800000) // was a newly used code + { + d = pEnd; // in case we overshot + c = (uint8_t)(u32Offset >> 24); + iLen++; + // since the code with extension byte has now been written to the output, fix the code + *pSymbols = iOffset; +// pSymbols[SYM_EXTRAS] = 0xffffffff; + *d = c; + *pLengths = (uint16_t)iLen; + } + return iLen; +} /* LZWCopyBytes() */ +// +// Macro to extract a variable length code +// +#define GET_CODE_TURBO if (bitnum > (REGISTER_WIDTH - MAX_CODE_SIZE/*codesize*/)) { p += (bitnum >> 3); \ + bitnum &= 7; ulBits = INTELLONG(p); } \ + code = ((ulBits >> bitnum) & sMask); \ + bitnum += codesize; + +// +// DecodeLZWTurbo +// +// Theory of operation: +// +// The 'traditional' LZW decoder maintains a dictionary with a linked list of codes. +// These codes build into longer chains as more data is decoded. To output the pixels, +// the linked list is traversed backwards from the last node to the first, then these +// pixels are copied in reverse order to the output bitmap. +// +// My decoder takes a different approach. The output image becomes the dictionary and +// the tables keep track of where in the output image the 'run' begins and its length. +// ** NB ** +// These tables cannot be 16-bit values because a single dictionary's output can be +// bigger than 64K +// +// I also work with the compressed data differently. Most decoders wind their way through +// the chunked data by constantly checking if the current chunk has run out of data. I +// take a different approach since modern machines have plenty of memory - I 'de-chunk' +// the data first so that the inner loop can just decode as fast as possible. I also keep +// a set of codes in a 64-bit local variable to minimize memory reads. +// +// These 2 changes result in a much faster decoder. For poorly compressed images, the +// speed gain is about 2.5x compared to giflib. For well compressed images (long runs) +// the speed can be as much as 30x faster. This is because it doesn't have to walk +// backwards through the linked list of codes when outputting pixels. It also doesn't +// have to copy pixels in reverse order, then unwind them. +// +static int DecodeLZWTurbo(GIFIMAGE *pImage, int iOptions) +{ +int i, bitnum; +int iUncompressedLen; +uint32_t code, oldcode, codesize, nextcode, nextlim; +uint32_t cc, eoi; +uint32_t sMask; +uint8_t c, *p, *buf, codestart, *pHighWater; +BIGUINT ulBits; +int iLen, iColors; +int iErr = GIF_SUCCESS; +int iOffset; +uint32_t *pSymbols; +uint16_t *pLengths; + + (void)iOptions; + pImage->iYCount = pImage->iHeight; // count down the lines + pImage->iXCount = pImage->iWidth; + bitnum = 0; + pHighWater = pImage->ucLZW + LZW_HIGHWATER_TURBO; + pImage->iLZWOff = 0; // Offset into compressed data + GIFGetMoreData(pImage); // Read some data to start + codestart = pImage->ucCodeStart; + iColors = 1 << codestart; + sMask = UINT32_MAX << (codestart+1); + sMask = 0xffffffff - sMask; + cc = (sMask >> 1) + 1; /* Clear code */ + eoi = cc + 1; + iUncompressedLen = (pImage->iWidth * pImage->iHeight); + buf = (uint8_t *)pImage->pTurboBuffer; + pSymbols = (uint32_t *)&buf[iUncompressedLen+256]; // we need 32-bits (really 23) for the offsets + pLengths = (uint16_t *)&pSymbols[4096]; // but only 16-bits for the length of any single string + iOffset = 0; // output data offset + p = pImage->ucLZW; // un-chunked LZW data + ulBits = INTELLONG(p); // start by reading some LZW data + // set up the default symbols (0..iColors-1) + for (i = 0; i= nextlim && codesize < MAX_CODE_SIZE) { + codesize++; + nextlim <<= 1; + sMask = (sMask << 1) | 1; + } + if (p >= pHighWater) { + pImage->iLZWOff = (int)(p - pImage->ucLZW); // restore object member var + GIFGetMoreData(pImage); // We need to read more LZW data + p = &pImage->ucLZW[pImage->iLZWOff]; + } + oldcode = code; + GET_CODE_TURBO + } /* while not end of LZW code stream */ + } // while not end of frame + if (pImage->ucDrawType == GIF_DRAW_COOKED && pImage->pfnDraw && pImage->pFrameBuffer) { // convert each line through the palette + GIFDRAW gd; + gd.iX = pImage->iX; + gd.iY = pImage->iY; + gd.iWidth = pImage->iWidth; + gd.iHeight = pImage->iHeight; + gd.pPalette = (pImage->bUseLocalPalette) ? pImage->pLocalPalette : pImage->pPalette; + gd.pPalette24 = (uint8_t *)gd.pPalette; // just cast the pointer for RGB888 + gd.ucIsGlobalPalette = pImage->bUseLocalPalette==1?0:1; + gd.pUser = pImage->pUser; + gd.ucPaletteType = pImage->ucPaletteType; + for (int y=0; yiHeight; y++) { + gd.y = y; + gd.pPixels = &buf[(y * pImage->iWidth)]; // source pixels + // Ugly logic to handle the interlaced line position, but it + // saves having to have another set of state variables + if (pImage->ucMap & 0x40) { // interlaced? + int height = pImage->iHeight-1; + if (gd.y > height / 2) + gd.y = gd.y * 2 - (height | 1); + else if (gd.y > height / 4) + gd.y = gd.y * 4 - ((height & ~1) | 2); + else if (gd.y > height / 8) + gd.y = gd.y * 8 - ((height & ~3) | 4); + else + gd.y = gd.y * 8; + } + gd.ucDisposalMethod = (pImage->ucGIFBits & 0x1c)>>2; + gd.ucTransparent = pImage->ucTransparent; + gd.ucHasTransparency = pImage->ucGIFBits & 1; + gd.ucBackground = pImage->ucBackground; + gd.iCanvasWidth = pImage->iCanvasWidth; + DrawCooked(pImage, &gd, &buf[pImage->iCanvasHeight * pImage->iCanvasWidth]); // dest = past end of canvas + gd.pPixels = &buf[pImage->iCanvasHeight * pImage->iCanvasWidth]; // point to the line we just converted + (*pImage->pfnDraw)(&gd); // callback to handle this line + } + } + return iErr; +} /* DecodeLZWTurbo() */ + +// +// GIFMakePels +// +static void GIFMakePels(GIFIMAGE *pPage, unsigned int code) +{ + int iPixCount; + unsigned short *giftabs; + unsigned char *buf, *s, *pEnd, *gifpels; + /* Copy this string of sequential pixels to output buffer */ + // iPixCount = 0; + pEnd = pPage->ucFileBuf; + s = pEnd + FILE_BUF_SIZE; /* Pixels will come out in reversed order */ + buf = pPage->ucLineBuf + (pPage->iWidth - pPage->iXCount); + giftabs = pPage->usGIFTable; + gifpels = &pPage->ucGIFPixels[PIXEL_LAST]; + while (code < LINK_UNUSED) + { + if (s == pEnd) /* Houston, we have a problem */ + { + return; /* Exit with error */ + } + *(--s) = gifpels[code]; + code = giftabs[code]; + } + iPixCount = (int)(intptr_t)(pEnd + FILE_BUF_SIZE - s); + while (iPixCount && pPage->iYCount > 0) + { + if (pPage->iXCount > iPixCount) /* Pixels fit completely on the line */ + { + pEnd = buf + iPixCount; + while (buf < pEnd) { +#ifdef ALLOWS_UNALIGNED +// This is a significant perf improvement compared to copying 1 byte at a time +// even though it will often copy too many bytes. Since we're not at the end of +// the line, it's okay to copy a few extra pixels. + BIGUINT tmp = *(BIGUINT *) s; + s += sizeof(BIGUINT); + *(BIGUINT *)buf = tmp; + buf += sizeof(BIGUINT); +#else + *buf++ = *s++; +#endif + } + pPage->iXCount -= iPixCount; + // iPixCount = 0; + if (pPage->iLZWOff >= LZW_HIGHWATER) + GIFGetMoreData(pPage); // We need to read more LZW data + return; + } + else /* Pixels cross into next line */ + { + GIFDRAW gd; + pEnd = buf + pPage->iXCount; + while (buf < pEnd) + { + *buf++ = *s++; + } + iPixCount -= pPage->iXCount; + pPage->iXCount = pPage->iWidth; /* Reset pixel count */ + // Prepare GIDRAW structure for callback + gd.iX = pPage->iX; + gd.iY = pPage->iY; + gd.iWidth = pPage->iWidth; + gd.iHeight = pPage->iHeight; + gd.pPixels = pPage->ucLineBuf; + gd.pPalette = (pPage->bUseLocalPalette) ? pPage->pLocalPalette : pPage->pPalette; + gd.pPalette24 = (uint8_t *)gd.pPalette; // just cast the pointer for RGB888 + gd.ucIsGlobalPalette = pPage->bUseLocalPalette==1?0:1; + gd.y = pPage->iHeight - pPage->iYCount; + // Ugly logic to handle the interlaced line position, but it + // saves having to have another set of state variables + if (pPage->ucMap & 0x40) { // interlaced? + int height = pPage->iHeight-1; + if (gd.y > height / 2) + gd.y = gd.y * 2 - (height | 1); + else if (gd.y > height / 4) + gd.y = gd.y * 4 - ((height & ~1) | 2); + else if (gd.y > height / 8) + gd.y = gd.y * 8 - ((height & ~3) | 4); + else + gd.y = gd.y * 8; + } + gd.ucDisposalMethod = (pPage->ucGIFBits & 0x1c)>>2; + gd.ucTransparent = pPage->ucTransparent; + gd.ucHasTransparency = pPage->ucGIFBits & 1; + gd.ucBackground = pPage->ucBackground; + gd.iCanvasWidth = pPage->iCanvasWidth; + gd.pUser = pPage->pUser; + gd.ucPaletteType = pPage->ucPaletteType; + if (pPage->pFrameBuffer) // update the frame buffer + { + int iPitch = 0, iBpp = 1, iOffset = pPage->iCanvasWidth * pPage->iCanvasHeight; + if (pPage->ucDrawType == GIF_DRAW_COOKED) { + if (!pPage->pfnDraw) { // no draw callback, prepare the full frame + switch (pPage->ucPaletteType) { + case GIF_PALETTE_1BPP: + iPitch = (pPage->iCanvasWidth + 7) / 8; + break; + case GIF_PALETTE_RGB565_BE: + case GIF_PALETTE_RGB565_LE: + iPitch = (pPage->iCanvasWidth * 2); + iBpp = 2; + break; + case GIF_PALETTE_RGB888: + iPitch = pPage->iCanvasWidth * 3; + iBpp = 3; + break; + case GIF_PALETTE_RGB8888: + iPitch = pPage->iCanvasWidth * 4; + iBpp = 4; + break; + } + iOffset += (iBpp * pPage->iX) + ((gd.y + pPage->iY) * iPitch); + } + DrawCooked(pPage, &gd, &pPage->pFrameBuffer[iOffset]); + // pass the cooked pixel pointer to the GIFDraw callback + gd.pPixels = &pPage->pFrameBuffer[iOffset]; + } else { // the user will manage converting them through the palette + DrawNewPixels(pPage, &gd); // merge the new opaque pixels + } + } + if (pPage->pfnDraw) { + (*pPage->pfnDraw)(&gd); // callback to handle this line + } + pPage->iYCount--; + buf = pPage->ucLineBuf; + if (pPage->iLZWOff >= LZW_HIGHWATER) + GIFGetMoreData(pPage); // We need to read more LZW data + } + } /* while */ + if (pPage->iLZWOff >= LZW_HIGHWATER) + GIFGetMoreData(pPage); // We need to read more LZW data + return; +} /* GIFMakePels() */ +// +// Macro to extract a variable length code +// +#define GET_CODE if (bitnum > (REGISTER_WIDTH - codesize)) { pImage->iLZWOff += (bitnum >> 3); \ + bitnum &= 7; ulBits = INTELLONG(&p[pImage->iLZWOff]); } \ + code = (unsigned short) (ulBits >> bitnum); /* Read a REGISTER_WIDTH chunk */ \ + code &= sMask; bitnum += codesize; +// +// Decode LZW into an image +// +static int DecodeLZW(GIFIMAGE *pImage, int iOptions) +{ + int i, bitnum; + unsigned short oldcode, codesize, nextcode, nextlim; + unsigned short *giftabs, cc, eoi; + signed short sMask; + unsigned char c, *gifpels, *p; + // int iStripSize; + //unsigned char **index; + BIGUINT ulBits; + unsigned short code; + (void)iOptions; // not used for now + // if output can be used for string table, do it faster + // if (bGIF && (OutPage->cBitsperpixel == 8 && ((OutPage->iWidth & 3) == 0))) + // return PILFastLZW(InPage, OutPage, bGIF, iOptions); + if (pImage->ucDrawType == GIF_DRAW_COOKED && pImage->pFrameBuffer == NULL && pImage->pfnDraw == NULL) { // without a framebuffer and a GIFDRAW callback, we cannot continue + pImage->iError = GIF_INVALID_PARAMETER; + return 1; // indicate a problem + } + // If the user selected RAW output and there is no GIFDRAW callback, that won't work either + if (pImage->ucDrawType == GIF_DRAW_RAW && pImage->pfnDraw == NULL) { + pImage->iError = GIF_INVALID_PARAMETER; + return 1; // indicate a problem + } + p = pImage->ucLZW; // un-chunked LZW data + sMask = 0xffff << (pImage->ucCodeStart + 1); + sMask = 0xffff - sMask; + cc = (sMask >> 1) + 1; /* Clear code */ + eoi = cc + 1; + giftabs = pImage->usGIFTable; + gifpels = pImage->ucGIFPixels; + pImage->iYCount = pImage->iHeight; // count down the lines + pImage->iXCount = pImage->iWidth; + bitnum = 0; + pImage->iLZWOff = 0; // Offset into compressed data + GIFGetMoreData(pImage); // Read some data to start + + // Initialize code table + // this part only needs to be initialized once + for (i = 0; i < cc; i++) + { + gifpels[PIXEL_FIRST + i] = gifpels[PIXEL_LAST + i] = (unsigned short) i; + giftabs[i] = LINK_END; + } +init_codetable: + codesize = pImage->ucCodeStart + 1; + sMask = 0xffff << (pImage->ucCodeStart + 1); + sMask = 0xffff - sMask; + nextcode = cc + 2; + nextlim = (unsigned short) ((1 << codesize)); + // This part of the table needs to be reset multiple times + lv_memset(&giftabs[cc], (uint8_t) LINK_UNUSED, sizeof(pImage->usGIFTable) - sizeof(giftabs[0])*cc); + ulBits = INTELLONG(&p[pImage->iLZWOff]); // start by reading 4 bytes of LZW data + GET_CODE + if (code == cc) // we just reset the dictionary, so get another code + { + GET_CODE + } + c = oldcode = code; + GIFMakePels(pImage, code); // first code is output as the first pixel + // Main decode loop + while (code != eoi && pImage->iYCount > 0) // && y < pImage->iHeight+1) /* Loop through all lines of the image (or strip) */ + { + GET_CODE + if (code == cc) /* Clear code?, and not first code */ + goto init_codetable; + if (code != eoi) + { + if (nextcode < nextlim) // for deferred cc case, don't let it overwrite the last entry (fff) + { + giftabs[nextcode] = oldcode; + gifpels[PIXEL_FIRST + nextcode] = c; // oldcode pixel value + gifpels[PIXEL_LAST + nextcode] = c = gifpels[PIXEL_FIRST + code]; + } + nextcode++; + if (nextcode >= nextlim && codesize < MAX_CODE_SIZE) + { + codesize++; + nextlim <<= 1; + sMask = nextlim - 1; + } + GIFMakePels(pImage, code); + oldcode = code; + } + } /* while not end of LZW code stream */ + return 0; +//gif_forced_error: +// free(pImage->pPixels); +// pImage->pPixels = NULL; +// return -1; +} /* DecodeLZW() */ + + diff --git a/src/libs/gif/LICENSE.txt b/src/libs/gif/LICENSE.txt deleted file mode 100644 index c53d51993d..0000000000 --- a/src/libs/gif/LICENSE.txt +++ /dev/null @@ -1,2 +0,0 @@ -All of the source code and documentation for gifdec is released into the -public domain and provided without warranty of any kind. diff --git a/src/libs/gif/gifdec.c b/src/libs/gif/gifdec.c deleted file mode 100644 index 7c278d6eda..0000000000 --- a/src/libs/gif/gifdec.c +++ /dev/null @@ -1,823 +0,0 @@ -#include "gifdec.h" -#include "../../misc/lv_log.h" -#include "../../stdlib/lv_mem.h" -#include "../../misc/lv_color.h" -#if LV_USE_GIF - -#include -#include -#include - -#define MIN(A, B) ((A) < (B) ? (A) : (B)) -#define MAX(A, B) ((A) > (B) ? (A) : (B)) - -typedef struct Entry { - uint16_t length; - uint16_t prefix; - uint8_t suffix; -} Entry; - -typedef struct Table { - int bulk; - int nentries; - Entry * entries; -} Table; - -#if LV_GIF_CACHE_DECODE_DATA -#define LZW_MAXBITS 12 -#define LZW_TABLE_SIZE (1 << LZW_MAXBITS) -#define LZW_CACHE_SIZE (LZW_TABLE_SIZE * 4) -#endif - -static gd_GIF * gif_open(gd_GIF * gif); -static bool f_gif_open(gd_GIF * gif, const void * path, bool is_file); -static void f_gif_read(gd_GIF * gif, void * buf, size_t len); -static int f_gif_seek(gd_GIF * gif, size_t pos, int k); -static void f_gif_close(gd_GIF * gif); - -#if LV_USE_DRAW_SW_ASM == LV_DRAW_SW_ASM_HELIUM - #include "gifdec_mve.h" -#endif - -static uint16_t -read_num(gd_GIF * gif) -{ - uint8_t bytes[2]; - - f_gif_read(gif, bytes, 2); - return bytes[0] + (((uint16_t) bytes[1]) << 8); -} - -gd_GIF * -gd_open_gif_file(const char * fname) -{ - gd_GIF gif_base; - memset(&gif_base, 0, sizeof(gif_base)); - - bool res = f_gif_open(&gif_base, fname, true); - if(!res) return NULL; - - return gif_open(&gif_base); -} - -gd_GIF * -gd_open_gif_data(const void * data) -{ - gd_GIF gif_base; - memset(&gif_base, 0, sizeof(gif_base)); - - bool res = f_gif_open(&gif_base, data, false); - if(!res) return NULL; - - return gif_open(&gif_base); -} - -static gd_GIF * gif_open(gd_GIF * gif_base) -{ - uint8_t sigver[3]; - uint16_t width, height, depth; - uint8_t fdsz, bgidx, aspect; - uint8_t * bgcolor; - int gct_sz; - gd_GIF * gif = NULL; - - /* Header */ - f_gif_read(gif_base, sigver, 3); - if(memcmp(sigver, "GIF", 3) != 0) { - LV_LOG_WARN("invalid signature"); - goto fail; - } - /* Version */ - f_gif_read(gif_base, sigver, 3); - if(memcmp(sigver, "89a", 3) != 0) { - LV_LOG_WARN("invalid version"); - goto fail; - } - /* Width x Height */ - width = read_num(gif_base); - height = read_num(gif_base); - /* FDSZ */ - f_gif_read(gif_base, &fdsz, 1); - /* Presence of GCT */ - if(!(fdsz & 0x80)) { - LV_LOG_WARN("no global color table"); - goto fail; - } - /* Color Space's Depth */ - depth = ((fdsz >> 4) & 7) + 1; - /* Ignore Sort Flag. */ - /* GCT Size */ - gct_sz = 1 << ((fdsz & 0x07) + 1); - /* Background Color Index */ - f_gif_read(gif_base, &bgidx, 1); - /* Aspect Ratio */ - f_gif_read(gif_base, &aspect, 1); - /* Create gd_GIF Structure. */ - if(0 == width || 0 == height){ - LV_LOG_WARN("Zero size image"); - goto fail; - } -#if LV_GIF_CACHE_DECODE_DATA - if(0 == (INT_MAX - sizeof(gd_GIF) - LZW_CACHE_SIZE) / width / height / 5){ - LV_LOG_WARN("Image dimensions are too large"); - goto fail; - } - gif = lv_malloc(sizeof(gd_GIF) + 5 * width * height + LZW_CACHE_SIZE); - #else - if(0 == (INT_MAX - sizeof(gd_GIF)) / width / height / 5){ - LV_LOG_WARN("Image dimensions are too large"); - goto fail; - } - gif = lv_malloc(sizeof(gd_GIF) + 5 * width * height); - #endif - if(!gif) goto fail; - memcpy(gif, gif_base, sizeof(gd_GIF)); - gif->width = width; - gif->height = height; - gif->depth = depth; - /* Read GCT */ - gif->gct.size = gct_sz; - f_gif_read(gif, gif->gct.colors, 3 * gif->gct.size); - gif->palette = &gif->gct; - gif->bgindex = bgidx; - gif->canvas = (uint8_t *) &gif[1]; - gif->frame = &gif->canvas[4 * width * height]; - if(gif->bgindex) { - memset(gif->frame, gif->bgindex, gif->width * gif->height); - } - bgcolor = &gif->palette->colors[gif->bgindex * 3]; - #if LV_GIF_CACHE_DECODE_DATA - gif->lzw_cache = gif->frame + width * height; - #endif - -#ifdef GIFDEC_FILL_BG - GIFDEC_FILL_BG(gif->canvas, gif->width * gif->height, 1, gif->width * gif->height, bgcolor, 0xff); -#else - for(int i = 0; i < gif->width * gif->height; i++) { - gif->canvas[i * 4 + 0] = *(bgcolor + 2); - gif->canvas[i * 4 + 1] = *(bgcolor + 1); - gif->canvas[i * 4 + 2] = *(bgcolor + 0); - gif->canvas[i * 4 + 3] = 0xff; - } -#endif - gif->anim_start = f_gif_seek(gif, 0, LV_FS_SEEK_CUR); - gif->loop_count = -1; - goto ok; -fail: - f_gif_close(gif_base); -ok: - return gif; -} - -static void -discard_sub_blocks(gd_GIF * gif) -{ - uint8_t size; - - do { - f_gif_read(gif, &size, 1); - f_gif_seek(gif, size, LV_FS_SEEK_CUR); - } while(size); -} - -static void -read_plain_text_ext(gd_GIF * gif) -{ - if(gif->plain_text) { - uint16_t tx, ty, tw, th; - uint8_t cw, ch, fg, bg; - size_t sub_block; - f_gif_seek(gif, 1, LV_FS_SEEK_CUR); /* block size = 12 */ - tx = read_num(gif); - ty = read_num(gif); - tw = read_num(gif); - th = read_num(gif); - f_gif_read(gif, &cw, 1); - f_gif_read(gif, &ch, 1); - f_gif_read(gif, &fg, 1); - f_gif_read(gif, &bg, 1); - sub_block = f_gif_seek(gif, 0, LV_FS_SEEK_CUR); - gif->plain_text(gif, tx, ty, tw, th, cw, ch, fg, bg); - f_gif_seek(gif, sub_block, LV_FS_SEEK_SET); - } - else { - /* Discard plain text metadata. */ - f_gif_seek(gif, 13, LV_FS_SEEK_CUR); - } - /* Discard plain text sub-blocks. */ - discard_sub_blocks(gif); -} - -static void -read_graphic_control_ext(gd_GIF * gif) -{ - uint8_t rdit; - - /* Discard block size (always 0x04). */ - f_gif_seek(gif, 1, LV_FS_SEEK_CUR); - f_gif_read(gif, &rdit, 1); - gif->gce.disposal = (rdit >> 2) & 3; - gif->gce.input = rdit & 2; - gif->gce.transparency = rdit & 1; - gif->gce.delay = read_num(gif); - f_gif_read(gif, &gif->gce.tindex, 1); - /* Skip block terminator. */ - f_gif_seek(gif, 1, LV_FS_SEEK_CUR); -} - -static void -read_comment_ext(gd_GIF * gif) -{ - if(gif->comment) { - size_t sub_block = f_gif_seek(gif, 0, LV_FS_SEEK_CUR); - gif->comment(gif); - f_gif_seek(gif, sub_block, LV_FS_SEEK_SET); - } - /* Discard comment sub-blocks. */ - discard_sub_blocks(gif); -} - -static void -read_application_ext(gd_GIF * gif) -{ - char app_id[8]; - char app_auth_code[3]; - uint16_t loop_count; - - /* Discard block size (always 0x0B). */ - f_gif_seek(gif, 1, LV_FS_SEEK_CUR); - /* Application Identifier. */ - f_gif_read(gif, app_id, 8); - /* Application Authentication Code. */ - f_gif_read(gif, app_auth_code, 3); - if(!strncmp(app_id, "NETSCAPE", sizeof(app_id))) { - /* Discard block size (0x03) and constant byte (0x01). */ - f_gif_seek(gif, 2, LV_FS_SEEK_CUR); - loop_count = read_num(gif); - if(gif->loop_count < 0) { - if(loop_count == 0) { - gif->loop_count = 0; - } - else { - gif->loop_count = loop_count + 1; - } - } - /* Skip block terminator. */ - f_gif_seek(gif, 1, LV_FS_SEEK_CUR); - } - else if(gif->application) { - size_t sub_block = f_gif_seek(gif, 0, LV_FS_SEEK_CUR); - gif->application(gif, app_id, app_auth_code); - f_gif_seek(gif, sub_block, LV_FS_SEEK_SET); - discard_sub_blocks(gif); - } - else { - discard_sub_blocks(gif); - } -} - -static void -read_ext(gd_GIF * gif) -{ - uint8_t label; - - f_gif_read(gif, &label, 1); - switch(label) { - case 0x01: - read_plain_text_ext(gif); - break; - case 0xF9: - read_graphic_control_ext(gif); - break; - case 0xFE: - read_comment_ext(gif); - break; - case 0xFF: - read_application_ext(gif); - break; - default: - LV_LOG_WARN("unknown extension: %02X\n", label); - } -} - -static uint16_t -get_key(gd_GIF *gif, int key_size, uint8_t *sub_len, uint8_t *shift, uint8_t *byte) -{ - int bits_read; - int rpad; - int frag_size; - uint16_t key; - - key = 0; - for (bits_read = 0; bits_read < key_size; bits_read += frag_size) { - rpad = (*shift + bits_read) % 8; - if (rpad == 0) { - /* Update byte. */ - if (*sub_len == 0) { - f_gif_read(gif, sub_len, 1); /* Must be nonzero! */ - if (*sub_len == 0) return 0x1000; - } - f_gif_read(gif, byte, 1); - (*sub_len)--; - } - frag_size = MIN(key_size - bits_read, 8 - rpad); - key |= ((uint16_t) ((*byte) >> rpad)) << bits_read; - } - /* Clear extra bits to the left. */ - key &= (1 << key_size) - 1; - *shift = (*shift + key_size) % 8; - return key; -} - -#if LV_GIF_CACHE_DECODE_DATA -/* Decompress image pixels. - * Return 0 on success or -1 on out-of-memory (w.r.t. LZW code table) or parse error. */ -static int -read_image_data(gd_GIF *gif, int interlace) -{ - uint8_t sub_len, shift, byte; - int ret = 0; - int key_size; - int y, pass, linesize; - uint8_t *ptr = NULL; - uint8_t *ptr_row_start = NULL; - uint8_t *ptr_base = NULL; - size_t start, end; - uint16_t key, clear_code, stop_code, curr_code; - int frm_off, frm_size,curr_size,top_slot,new_codes,slot; - /* The first value of the value sequence corresponding to key */ - int first_value; - int last_key; - uint8_t *sp = NULL; - uint8_t *p_stack = NULL; - uint8_t *p_suffix = NULL; - uint16_t *p_prefix = NULL; - - /* get initial key size and clear code, stop code */ - f_gif_read(gif, &byte, 1); - key_size = (int) byte; - clear_code = 1 << key_size; - stop_code = clear_code + 1; - key = 0; - - start = f_gif_seek(gif, 0, LV_FS_SEEK_CUR); - discard_sub_blocks(gif); - end = f_gif_seek(gif, 0, LV_FS_SEEK_CUR); - f_gif_seek(gif, start, LV_FS_SEEK_SET); - - linesize = gif->width; - ptr_base = &gif->frame[gif->fy * linesize + gif->fx]; - ptr_row_start = ptr_base; - ptr = ptr_row_start; - sub_len = shift = 0; - /* decoder */ - pass = 0; - y = 0; - p_stack = gif->lzw_cache; - p_suffix = gif->lzw_cache + LZW_TABLE_SIZE; - p_prefix = (uint16_t*)(gif->lzw_cache + LZW_TABLE_SIZE * 2); - frm_off = 0; - frm_size = gif->fw * gif->fh; - curr_size = key_size + 1; - top_slot = 1 << curr_size; - new_codes = clear_code + 2; - slot = new_codes; - first_value = -1; - last_key = -1; - sp = p_stack; - - while (frm_off < frm_size) { - /* copy data to frame buffer */ - while (sp > p_stack) { - if(frm_off >= frm_size){ - LV_LOG_WARN("LZW table token overflows the frame buffer"); - return -1; - } - *ptr++ = *(--sp); - frm_off += 1; - /* read one line */ - if ((ptr - ptr_row_start) == gif->fw) { - if (interlace) { - switch(pass) { - case 0: - case 1: - y += 8; - ptr_row_start += linesize * 8; - break; - case 2: - y += 4; - ptr_row_start += linesize * 4; - break; - case 3: - y += 2; - ptr_row_start += linesize * 2; - break; - default: - break; - } - while (y >= gif->fh) { - y = 4 >> pass; - ptr_row_start = ptr_base + linesize * y; - pass++; - } - } else { - ptr_row_start += linesize; - } - ptr = ptr_row_start; - } - } - - key = get_key(gif, curr_size, &sub_len, &shift, &byte); - - if (key == stop_code || key >= LZW_TABLE_SIZE) - break; - - if (key == clear_code) { - curr_size = key_size + 1; - slot = new_codes; - top_slot = 1 << curr_size; - first_value = last_key = -1; - sp = p_stack; - continue; - } - - curr_code = key; - /* - * If the current code is a code that will be added to the decoding - * dictionary, it is composed of the data list corresponding to the - * previous key and its first data. - * */ - if (curr_code == slot && first_value >= 0) { - *sp++ = first_value; - curr_code = last_key; - }else if(curr_code >= slot) - break; - - while (curr_code >= new_codes) { - *sp++ = p_suffix[curr_code]; - curr_code = p_prefix[curr_code]; - } - *sp++ = curr_code; - - /* Add code to decoding dictionary */ - if (slot < top_slot && last_key >= 0) { - p_suffix[slot] = curr_code; - p_prefix[slot++] = last_key; - } - first_value = curr_code; - last_key = key; - if (slot >= top_slot) { - if (curr_size < LZW_MAXBITS) { - top_slot <<= 1; - curr_size += 1; - } - } - } - - if (key == stop_code) f_gif_read(gif, &sub_len, 1); /* Must be zero! */ - f_gif_seek(gif, end, LV_FS_SEEK_SET); - return ret; -} -#else -static Table * -new_table(int key_size) -{ - int key; - int init_bulk = MAX(1 << (key_size + 1), 0x100); - Table * table = lv_malloc(sizeof(*table) + sizeof(Entry) * init_bulk); - if(table) { - table->bulk = init_bulk; - table->nentries = (1 << key_size) + 2; - table->entries = (Entry *) &table[1]; - for(key = 0; key < (1 << key_size); key++) - table->entries[key] = (Entry) { - 1, 0xFFF, key - }; - } - return table; -} - -/* Add table entry. Return value: - * 0 on success - * +1 if key size must be incremented after this addition - * -1 if could not realloc table */ -static int -add_entry(Table ** tablep, uint16_t length, uint16_t prefix, uint8_t suffix) -{ - Table * table = *tablep; - if(table->nentries == table->bulk) { - table->bulk *= 2; - table = lv_realloc(table, sizeof(*table) + sizeof(Entry) * table->bulk); - if(!table) return -1; - table->entries = (Entry *) &table[1]; - *tablep = table; - } - table->entries[table->nentries] = (Entry) { - length, prefix, suffix - }; - table->nentries++; - if((table->nentries & (table->nentries - 1)) == 0) - return 1; - return 0; -} - -/* Compute output index of y-th input line, in frame of height h. */ -static int -interlaced_line_index(int h, int y) -{ - int p; /* number of lines in current pass */ - - p = (h - 1) / 8 + 1; - if(y < p) /* pass 1 */ - return y * 8; - y -= p; - p = (h - 5) / 8 + 1; - if(y < p) /* pass 2 */ - return y * 8 + 4; - y -= p; - p = (h - 3) / 4 + 1; - if(y < p) /* pass 3 */ - return y * 4 + 2; - y -= p; - /* pass 4 */ - return y * 2 + 1; -} - -/* Decompress image pixels. - * Return 0 on success or -1 on out-of-memory (w.r.t. LZW code table) or parse error. */ -static int -read_image_data(gd_GIF * gif, int interlace) -{ - uint8_t sub_len, shift, byte; - int init_key_size, key_size, table_is_full = 0; - int frm_off, frm_size, str_len = 0, i, p, x, y; - uint16_t key, clear, stop; - int ret; - Table * table; - Entry entry = {0}; - size_t start, end; - - f_gif_read(gif, &byte, 1); - key_size = (int) byte; - start = f_gif_seek(gif, 0, LV_FS_SEEK_CUR); - discard_sub_blocks(gif); - end = f_gif_seek(gif, 0, LV_FS_SEEK_CUR); - f_gif_seek(gif, start, LV_FS_SEEK_SET); - clear = 1 << key_size; - stop = clear + 1; - table = new_table(key_size); - key_size++; - init_key_size = key_size; - sub_len = shift = 0; - key = get_key(gif, key_size, &sub_len, &shift, &byte); /* clear code */ - frm_off = 0; - ret = 0; - frm_size = gif->fw * gif->fh; - while(frm_off < frm_size) { - if(key == clear) { - key_size = init_key_size; - table->nentries = (1 << (key_size - 1)) + 2; - table_is_full = 0; - } - else if(!table_is_full) { - ret = add_entry(&table, str_len + 1, key, entry.suffix); - if(ret == -1) { - lv_free(table); - return -1; - } - if(table->nentries == 0x1000) { - ret = 0; - table_is_full = 1; - } - } - key = get_key(gif, key_size, &sub_len, &shift, &byte); - if(key == clear) continue; - if(key == stop || key == 0x1000) break; - if(ret == 1) key_size++; - entry = table->entries[key]; - str_len = entry.length; - if(frm_off + str_len > frm_size){ - LV_LOG_WARN("LZW table token overflows the frame buffer"); - lv_free(table); - return -1; - } - for(i = 0; i < str_len; i++) { - p = frm_off + entry.length - 1; - x = p % gif->fw; - y = p / gif->fw; - if(interlace) - y = interlaced_line_index((int) gif->fh, y); - gif->frame[(gif->fy + y) * gif->width + gif->fx + x] = entry.suffix; - if(entry.prefix == 0xFFF) - break; - else - entry = table->entries[entry.prefix]; - } - frm_off += str_len; - if(key < table->nentries - 1 && !table_is_full) - table->entries[table->nentries - 1].suffix = entry.suffix; - } - lv_free(table); - if(key == stop) f_gif_read(gif, &sub_len, 1); /* Must be zero! */ - f_gif_seek(gif, end, LV_FS_SEEK_SET); - return 0; -} - -#endif - -/* Read image. - * Return 0 on success or -1 on out-of-memory (w.r.t. LZW code table) or parse error. */ -static int -read_image(gd_GIF * gif) -{ - uint8_t fisrz; - int interlace; - - /* Image Descriptor. */ - gif->fx = read_num(gif); - gif->fy = read_num(gif); - gif->fw = read_num(gif); - gif->fh = read_num(gif); - if(gif->fx + (uint32_t)gif->fw > gif->width || gif->fy + (uint32_t)gif->fh > gif->height){ - LV_LOG_WARN("Frame coordinates out of image bounds"); - return -1; - } - f_gif_read(gif, &fisrz, 1); - interlace = fisrz & 0x40; - /* Ignore Sort Flag. */ - /* Local Color Table? */ - if(fisrz & 0x80) { - /* Read LCT */ - gif->lct.size = 1 << ((fisrz & 0x07) + 1); - f_gif_read(gif, gif->lct.colors, 3 * gif->lct.size); - gif->palette = &gif->lct; - } - else - gif->palette = &gif->gct; - /* Image Data. */ - return read_image_data(gif, interlace); -} - -static void -render_frame_rect(gd_GIF * gif, uint8_t * buffer) -{ - int i = gif->fy * gif->width + gif->fx; -#ifdef GIFDEC_RENDER_FRAME - GIFDEC_RENDER_FRAME(&buffer[i * 4], gif->fw, gif->fh, gif->width, - &gif->frame[i], gif->palette->colors, - gif->gce.transparency ? gif->gce.tindex : 0x100); -#else - int j, k; - uint8_t index, * color; - - for(j = 0; j < gif->fh; j++) { - for(k = 0; k < gif->fw; k++) { - index = gif->frame[(gif->fy + j) * gif->width + gif->fx + k]; - color = &gif->palette->colors[index * 3]; - if(!gif->gce.transparency || index != gif->gce.tindex) { - buffer[(i + k) * 4 + 0] = *(color + 2); - buffer[(i + k) * 4 + 1] = *(color + 1); - buffer[(i + k) * 4 + 2] = *(color + 0); - buffer[(i + k) * 4 + 3] = 0xFF; - } - } - i += gif->width; - } -#endif -} - -static void -dispose(gd_GIF * gif) -{ - int i; - uint8_t * bgcolor; - switch(gif->gce.disposal) { - case 2: /* Restore to background color. */ - bgcolor = &gif->palette->colors[gif->bgindex * 3]; - - uint8_t opa = 0xff; - if(gif->gce.transparency) opa = 0x00; - - i = gif->fy * gif->width + gif->fx; -#ifdef GIFDEC_FILL_BG - GIFDEC_FILL_BG(&(gif->canvas[i * 4]), gif->fw, gif->fh, gif->width, bgcolor, opa); -#else - int j, k; - for(j = 0; j < gif->fh; j++) { - for(k = 0; k < gif->fw; k++) { - gif->canvas[(i + k) * 4 + 0] = *(bgcolor + 2); - gif->canvas[(i + k) * 4 + 1] = *(bgcolor + 1); - gif->canvas[(i + k) * 4 + 2] = *(bgcolor + 0); - gif->canvas[(i + k) * 4 + 3] = opa; - } - i += gif->width; - } -#endif - break; - case 3: /* Restore to previous, i.e., don't update canvas.*/ - break; - default: - /* Add frame non-transparent pixels to canvas. */ - render_frame_rect(gif, gif->canvas); - } -} - -/* Return 1 if got a frame; 0 if got GIF trailer; -1 if error. */ -int -gd_get_frame(gd_GIF * gif) -{ - char sep; - - dispose(gif); - f_gif_read(gif, &sep, 1); - while(sep != ',') { - if(sep == ';') { - f_gif_seek(gif, gif->anim_start, LV_FS_SEEK_SET); - if(gif->loop_count == 1 || gif->loop_count < 0) { - return 0; - } - else if(gif->loop_count > 1) { - gif->loop_count--; - } - } - else if(sep == '!') - read_ext(gif); - else return -1; - f_gif_read(gif, &sep, 1); - } - if(read_image(gif) == -1) - return -1; - return 1; -} - -void -gd_render_frame(gd_GIF * gif, uint8_t * buffer) -{ - render_frame_rect(gif, buffer); -} - -void -gd_rewind(gd_GIF * gif) -{ - gif->loop_count = -1; - f_gif_seek(gif, gif->anim_start, LV_FS_SEEK_SET); -} - -void -gd_close_gif(gd_GIF * gif) -{ - f_gif_close(gif); - lv_free(gif); -} - -static bool f_gif_open(gd_GIF * gif, const void * path, bool is_file) -{ - gif->f_rw_p = 0; - gif->data = NULL; - gif->is_file = is_file; - - if(is_file) { - lv_fs_res_t res = lv_fs_open(&gif->fd, path, LV_FS_MODE_RD); - if(res != LV_FS_RES_OK) return false; - else return true; - } - else { - gif->data = path; - return true; - } -} - -static void f_gif_read(gd_GIF * gif, void * buf, size_t len) -{ - if(gif->is_file) { - lv_fs_read(&gif->fd, buf, len, NULL); - } - else { - memcpy(buf, &gif->data[gif->f_rw_p], len); - gif->f_rw_p += len; - } -} - -static int f_gif_seek(gd_GIF * gif, size_t pos, int k) -{ - if(gif->is_file) { - lv_fs_seek(&gif->fd, pos, k); - uint32_t x; - lv_fs_tell(&gif->fd, &x); - return x; - } - else { - if(k == LV_FS_SEEK_CUR) gif->f_rw_p += pos; - else if(k == LV_FS_SEEK_SET) gif->f_rw_p = pos; - return gif->f_rw_p; - } -} - -static void f_gif_close(gd_GIF * gif) -{ - if(gif->is_file) { - lv_fs_close(&gif->fd); - } -} - -#endif /*LV_USE_GIF*/ diff --git a/src/libs/gif/gifdec.h b/src/libs/gif/gifdec.h deleted file mode 100644 index 21ff210ab5..0000000000 --- a/src/libs/gif/gifdec.h +++ /dev/null @@ -1,71 +0,0 @@ -#ifndef GIFDEC_H -#define GIFDEC_H - -#ifdef __cplusplus -extern "C" { -#endif - -#include "../../misc/lv_fs.h" - -#if LV_USE_GIF -#include - -typedef struct _gd_Palette { - int size; - uint8_t colors[0x100 * 3]; -} gd_Palette; - -typedef struct _gd_GCE { - uint16_t delay; - uint8_t tindex; - uint8_t disposal; - int input; - int transparency; -} gd_GCE; - - - -typedef struct _gd_GIF { - lv_fs_file_t fd; - const char * data; - uint8_t is_file; - uint32_t f_rw_p; - int32_t anim_start; - uint16_t width, height; - uint16_t depth; - int32_t loop_count; - gd_GCE gce; - gd_Palette * palette; - gd_Palette lct, gct; - void (*plain_text)( - struct _gd_GIF * gif, uint16_t tx, uint16_t ty, - uint16_t tw, uint16_t th, uint8_t cw, uint8_t ch, - uint8_t fg, uint8_t bg - ); - void (*comment)(struct _gd_GIF * gif); - void (*application)(struct _gd_GIF * gif, char id[8], char auth[3]); - uint16_t fx, fy, fw, fh; - uint8_t bgindex; - uint8_t * canvas, * frame; - #if LV_GIF_CACHE_DECODE_DATA - uint8_t *lzw_cache; - #endif -} gd_GIF; - -gd_GIF * gd_open_gif_file(const char * fname); - -gd_GIF * gd_open_gif_data(const void * data); - -void gd_render_frame(gd_GIF * gif, uint8_t * buffer); - -int gd_get_frame(gd_GIF * gif); -void gd_rewind(gd_GIF * gif); -void gd_close_gif(gd_GIF * gif); - -#endif /*LV_USE_GIF*/ - -#ifdef __cplusplus -} /* extern "C" */ -#endif - -#endif /* GIFDEC_H */ diff --git a/src/libs/gif/gifdec_mve.h b/src/libs/gif/gifdec_mve.h deleted file mode 100644 index 6d83393497..0000000000 --- a/src/libs/gif/gifdec_mve.h +++ /dev/null @@ -1,140 +0,0 @@ -/** - * @file gifdec_mve.h - * - */ - -#ifndef GIFDEC_MVE_H -#define GIFDEC_MVE_H - -#ifdef __cplusplus -extern "C" { -#endif - -/********************* - * INCLUDES - *********************/ -#include -#include "../../misc/lv_color.h" - -/********************* - * DEFINES - *********************/ - -#define GIFDEC_FILL_BG(dst, w, h, stride, color, opa) \ - _gifdec_fill_bg_mve(dst, w, h, stride, color, opa) - -#define GIFDEC_RENDER_FRAME(dst, w, h, stride, frame, pattern, tindex) \ - _gifdec_render_frame_mve(dst, w, h, stride, frame, pattern, tindex) - -/********************** - * MACROS - **********************/ - -/********************** - * TYPEDEFS - **********************/ - -/********************** - * GLOBAL PROTOTYPES - **********************/ - -static inline void _gifdec_fill_bg_mve(uint8_t * dst, uint16_t w, uint16_t h, uint16_t stride, uint8_t * color, - uint8_t opa) -{ - lv_color32_t c = lv_color32_make(*(color + 0), *(color + 1), *(color + 2), opa); - uint32_t color_32 = *(uint32_t *)&c; - - __asm volatile( - ".p2align 2 \n" - "vdup.32 q0, %[src] \n" - "3: \n" - "mov r0, %[dst] \n" - - "wlstp.32 lr, %[w], 1f \n" - "2: \n" - - "vstrw.32 q0, [r0], #16 \n" - "letp lr, 2b \n" - "1: \n" - "add %[dst], %[iTargetStride] \n" - "subs %[h], #1 \n" - "bne 3b \n" - : [dst] "+r"(dst), - [h] "+r"(h) - : [src] "r"(color_32), - [w] "r"(w), - [iTargetStride] "r"(stride * sizeof(uint32_t)) - : "r0", "q0", "memory", "r14", "cc"); -} - -static inline void _gifdec_render_frame_mve(uint8_t * dst, uint16_t w, uint16_t h, uint16_t stride, uint8_t * frame, - uint8_t * pattern, uint16_t tindex) -{ - if(w == 0 || h == 0) { - return; - } - - __asm volatile( - "vmov.u16 q3, #255 \n" - "vshl.u16 q3, q3, #8 \n" /* left shift 8 for a*/ - - "mov r0, #2 \n" - "vidup.u16 q6, r0, #4 \n" /* [2, 6, 10, 14, 18, 22, 26, 30] */ - "mov r0, #0 \n" - "vidup.u16 q7, r0, #4 \n" /* [0, 4, 8, 12, 16, 20, 24, 28] */ - - "3: \n" - "mov r1, %[dst] \n" - "mov r2, %[frame] \n" - - "wlstp.16 lr, %[w], 1f \n" - "2: \n" - - "mov r0, #3 \n" - "vldrb.u16 q4, [r2], #8 \n" - "vmul.u16 q5, q4, r0 \n" - - "mov r0, #1 \n" - "vldrb.u16 q2, [%[pattern], q5] \n" /* load 8 pixel r*/ - - "vadd.u16 q5, q5, r0 \n" - "vldrb.u16 q1, [%[pattern], q5] \n" /* load 8 pixel g*/ - - "vadd.u16 q5, q5, r0 \n" - "vldrb.u16 q0, [%[pattern], q5] \n" /* load 8 pixel b*/ - - "vshl.u16 q1, q1, #8 \n" /* left shift 8 for g*/ - - "vorr.u16 q0, q0, q1 \n" /* make 8 pixel gb*/ - "vorr.u16 q1, q2, q3 \n" /* make 8 pixel ar*/ - - "vcmp.i16 ne, q4, %[tindex] \n" - "vpstt \n" - "vstrht.16 q0, [r1, q7] \n" - "vstrht.16 q1, [r1, q6] \n" - "add r1, r1, #32 \n" - - "letp lr, 2b \n" - - "1: \n" - "mov r0, %[stride], LSL #2 \n" - "add %[dst], r0 \n" - "add %[frame], %[stride] \n" - "subs %[h], #1 \n" - "bne 3b \n" - - : [dst] "+r"(dst), - [frame] "+r"(frame), - [h] "+r"(h) - : [pattern] "r"(pattern), - [w] "r"(w), - [stride] "r"(stride), - [tindex] "r"(tindex) - : "r0", "r1", "r2", "q0", "q1", "q2", "q3", "q4", "q5", "q6", "q7", "memory", "r14", "cc"); -} - -#ifdef __cplusplus -} /*extern "C"*/ -#endif - -#endif /*GIFDEC_MVE_H*/ diff --git a/src/libs/gif/lv_gif.c b/src/libs/gif/lv_gif.c index 8dab9367d6..8a93c661a1 100644 --- a/src/libs/gif/lv_gif.c +++ b/src/libs/gif/lv_gif.c @@ -1,18 +1,18 @@ /** - * @file lv_gifenc.c + * @file lv_gif.c * */ /********************* * INCLUDES *********************/ -#include "lv_gif_private.h" +#include "lv_gif.h" #if LV_USE_GIF #include "../../misc/lv_timer_private.h" #include "../../misc/cache/lv_cache.h" #include "../../core/lv_obj_class_private.h" - -#include "gifdec.h" +#include "../../widgets/image/lv_image_private.h" +#include "AnimatedGIF/src/AnimatedGIF.h" /********************* * DEFINES @@ -23,11 +23,26 @@ * TYPEDEFS **********************/ +/* the type of the AnimatedGIF pallete type passed to `GIF_begin` */ +typedef unsigned char animatedgif_color_format_t; + +typedef struct { + lv_image_t img; + GIFIMAGE gif; + const void * src; + lv_color_format_t color_format; + lv_timer_t * timer; + lv_image_dsc_t imgdsc; + int32_t loop_count; + uint32_t is_open : 1; +} lv_gif_t; + /********************** * STATIC PROTOTYPES **********************/ static void lv_gif_constructor(const lv_obj_class_t * class_p, lv_obj_t * obj); static void lv_gif_destructor(const lv_obj_class_t * class_p, lv_obj_t * obj); +static void initialize(lv_gif_t * gifobj); static void next_frame_task_cb(lv_timer_t * t); /********************** @@ -59,63 +74,52 @@ lv_obj_t * lv_gif_create(lv_obj_t * parent) return obj; } -void lv_gif_set_src(lv_obj_t * obj, const void * src) +void lv_gif_set_color_format(lv_obj_t * obj, lv_color_format_t color_format) { lv_gif_t * gifobj = (lv_gif_t *) obj; - gd_GIF * gif = gifobj->gif; - /*Close previous gif if any*/ - if(gif != NULL) { - lv_image_cache_drop(lv_image_get_src(obj)); - - gd_close_gif(gif); - gifobj->gif = NULL; - gifobj->imgdsc.data = NULL; - } - - if(lv_image_src_get_type(src) == LV_IMAGE_SRC_VARIABLE) { - const lv_image_dsc_t * img_dsc = src; - gif = gd_open_gif_data(img_dsc->data); - } - else if(lv_image_src_get_type(src) == LV_IMAGE_SRC_FILE) { - gif = gd_open_gif_file(src); - } - if(gif == NULL) { - LV_LOG_WARN("Couldn't load the source"); + if(gifobj->color_format == color_format) { return; } - gifobj->gif = gif; - gifobj->imgdsc.data = gif->canvas; - gifobj->imgdsc.header.magic = LV_IMAGE_HEADER_MAGIC; - gifobj->imgdsc.header.flags = LV_IMAGE_FLAGS_MODIFIABLE; - gifobj->imgdsc.header.cf = LV_COLOR_FORMAT_ARGB8888; - gifobj->imgdsc.header.h = gif->height; - gifobj->imgdsc.header.w = gif->width; - gifobj->imgdsc.header.stride = gif->width * 4; - gifobj->imgdsc.data_size = gif->width * gif->height * 4; + switch(color_format) { + case LV_COLOR_FORMAT_RGB565: + case LV_COLOR_FORMAT_RGB565_SWAPPED: + case LV_COLOR_FORMAT_RGB888: + case LV_COLOR_FORMAT_ARGB8888: + break; + default: + LV_LOG_WARN("gif widget does not support this color format"); + return; + } - gifobj->last_call = lv_tick_get(); + gifobj->color_format = color_format; - lv_image_set_src(obj, &gifobj->imgdsc); + if(gifobj->src != NULL) { + initialize(gifobj); + } +} - lv_timer_resume(gifobj->timer); - lv_timer_reset(gifobj->timer); +void lv_gif_set_src(lv_obj_t * obj, const void * src) +{ + lv_gif_t * gifobj = (lv_gif_t *) obj; - next_frame_task_cb(gifobj->timer); + gifobj->src = src; + initialize(gifobj); } void lv_gif_restart(lv_obj_t * obj) { lv_gif_t * gifobj = (lv_gif_t *) obj; - if(gifobj->gif == NULL) { + if(!gifobj->is_open) { LV_LOG_WARN("Gif resource not loaded correctly"); return; } - gd_rewind(gifobj->gif); + GIF_reset(&gifobj->gif); + gifobj->loop_count = -1; /* match the behavior of the old library */ lv_timer_resume(gifobj->timer); lv_timer_reset(gifobj->timer); } @@ -130,7 +134,7 @@ void lv_gif_resume(lv_obj_t * obj) { lv_gif_t * gifobj = (lv_gif_t *) obj; - if(gifobj->gif == NULL) { + if(!gifobj->is_open) { LV_LOG_WARN("Gif resource not loaded correctly"); return; } @@ -142,30 +146,30 @@ bool lv_gif_is_loaded(lv_obj_t * obj) { lv_gif_t * gifobj = (lv_gif_t *) obj; - return (gifobj->gif != NULL); + return gifobj->is_open; } int32_t lv_gif_get_loop_count(lv_obj_t * obj) { lv_gif_t * gifobj = (lv_gif_t *) obj; - if(gifobj->gif == NULL) { + if(!gifobj->is_open) { return -1; } - return gifobj->gif->loop_count; + return gifobj->loop_count; } void lv_gif_set_loop_count(lv_obj_t * obj, int32_t count) { lv_gif_t * gifobj = (lv_gif_t *) obj; - if(gifobj->gif == NULL) { + if(!gifobj->is_open) { LV_LOG_WARN("Gif resource not loaded correctly"); return; } - gifobj->gif->loop_count = count; + gifobj->loop_count = count; } /********************** @@ -178,7 +182,8 @@ static void lv_gif_constructor(const lv_obj_class_t * class_p, lv_obj_t * obj) lv_gif_t * gifobj = (lv_gif_t *) obj; - gifobj->gif = NULL; + gifobj->color_format = LV_COLOR_FORMAT_ARGB8888; + gifobj->is_open = 0; gifobj->timer = lv_timer_create(next_frame_task_cb, 10, obj); lv_timer_pause(gifobj->timer); } @@ -190,29 +195,121 @@ static void lv_gif_destructor(const lv_obj_class_t * class_p, lv_obj_t * obj) lv_image_cache_drop(lv_image_get_src(obj)); - if(gifobj->gif) - gd_close_gif(gifobj->gif); + if(gifobj->is_open) { + void * framebuffer = gifobj->gif.pFrameBuffer; + GIF_close(&gifobj->gif); + lv_free(framebuffer); + } lv_timer_delete(gifobj->timer); } +static void initialize(lv_gif_t * gifobj) +{ + GIFIMAGE * gif = &gifobj->gif; + + /*Close previous gif if any*/ + if(gifobj->is_open) { + lv_image_cache_drop(lv_image_get_src((lv_obj_t *) gifobj)); + + void * framebuffer = gif->pFrameBuffer; + GIF_close(gif); + lv_free(framebuffer); + gifobj->is_open = 0; + gifobj->imgdsc.data = NULL; + } + + animatedgif_color_format_t decoder_cf; + uint32_t pixel_size_bytes; + switch(gifobj->color_format) { + case LV_COLOR_FORMAT_RGB565: + decoder_cf = GIF_PALETTE_RGB565_LE; + pixel_size_bytes = 2; + break; + case LV_COLOR_FORMAT_RGB565_SWAPPED: + decoder_cf = GIF_PALETTE_RGB565_BE; + pixel_size_bytes = 2; + break; + case LV_COLOR_FORMAT_RGB888: + decoder_cf = GIF_PALETTE_RGB888; + pixel_size_bytes = 3; + break; + case LV_COLOR_FORMAT_ARGB8888: + decoder_cf = GIF_PALETTE_RGB8888; + pixel_size_bytes = 4; + break; + default: + return; + } + + GIF_begin(gif, decoder_cf); + + if(lv_image_src_get_type(gifobj->src) == LV_IMAGE_SRC_VARIABLE) { + const lv_image_dsc_t * img_dsc = gifobj->src; + gifobj->is_open = GIF_openRAM(gif, (uint8_t *) img_dsc->data, img_dsc->data_size, NULL); + } + else if(lv_image_src_get_type(gifobj->src) == LV_IMAGE_SRC_FILE) { + gifobj->is_open = GIF_openFile(gif, gifobj->src, NULL); + } + if(gifobj->is_open == 0) { + LV_LOG_WARN("Couldn't load the source"); + return; + } + + uint32_t width = GIF_getCanvasWidth(gif); + uint32_t height = GIF_getCanvasHeight(gif); + gif->pFrameBuffer = lv_malloc(width * height * (pixel_size_bytes + 1)); + gif->ucDrawType = GIF_DRAW_COOKED; + LV_ASSERT_MALLOC(gif->pFrameBuffer); + if(gif->pFrameBuffer == NULL) { + LV_LOG_WARN("Couldn't allocate a buffer for a GIF"); + GIF_close(gif); + gifobj->is_open = 0; + return; + } + + gifobj->imgdsc.data = gif->pFrameBuffer + width * height; + gifobj->imgdsc.header.magic = LV_IMAGE_HEADER_MAGIC; + gifobj->imgdsc.header.flags = LV_IMAGE_FLAGS_MODIFIABLE; + gifobj->imgdsc.header.cf = gifobj->color_format; + gifobj->imgdsc.header.h = height; + gifobj->imgdsc.header.w = width; + gifobj->imgdsc.header.stride = width * pixel_size_bytes; + gifobj->imgdsc.data_size = width * height * pixel_size_bytes; + + lv_image_set_src((lv_obj_t *) gifobj, &gifobj->imgdsc); + + gifobj->loop_count = GIF_getLoopCount(&gifobj->gif); + + lv_timer_resume(gifobj->timer); + lv_timer_reset(gifobj->timer); + + next_frame_task_cb(gifobj->timer); + +} + static void next_frame_task_cb(lv_timer_t * t) { lv_obj_t * obj = t->user_data; lv_gif_t * gifobj = (lv_gif_t *) obj; - uint32_t elaps = lv_tick_elaps(gifobj->last_call); - if(elaps < gifobj->gif->gce.delay * 10) return; - gifobj->last_call = lv_tick_get(); - - int has_next = gd_get_frame(gifobj->gif); - if(has_next == 0) { + int ms_delay_next; + int has_next = GIF_playFrame(&gifobj->gif, &ms_delay_next, gifobj); + if(has_next <= 0) { /*It was the last repeat*/ lv_result_t res = lv_obj_send_event(obj, LV_EVENT_READY, NULL); - lv_timer_pause(t); + if(gifobj->loop_count > 0) { + if(gifobj->loop_count == 1) { + lv_timer_pause(t); + } + else { + gifobj->loop_count--; + } + } if(res != LV_RESULT_OK) return; } - - gd_render_frame(gifobj->gif, (uint8_t *)gifobj->imgdsc.data); + else { + lv_timer_set_period(gifobj->timer, ms_delay_next); + } lv_image_cache_drop(lv_image_get_src(obj)); lv_obj_invalidate(obj); diff --git a/src/libs/gif/lv_gif.h b/src/libs/gif/lv_gif.h index cf1bee4794..ff72e1a59a 100644 --- a/src/libs/gif/lv_gif.h +++ b/src/libs/gif/lv_gif.h @@ -16,14 +16,11 @@ extern "C" { #include "../../lv_conf_internal.h" #include "../../misc/lv_types.h" -#include "../../draw/lv_draw_buf.h" -#include "../../widgets/image/lv_image.h" -#include "../../core/lv_obj_class.h" #include LV_STDBOOL_INCLUDE #include LV_STDINT_INCLUDE #if LV_USE_GIF -#include "gifdec.h" +#include "../../misc/lv_color.h" /********************* * DEFINES @@ -46,6 +43,15 @@ LV_ATTRIBUTE_EXTERN_DATA extern const lv_obj_class_t lv_gif_class; */ lv_obj_t * lv_gif_create(lv_obj_t * parent); +/** + * Set the color format of the internally allocated framebuffer that the gif + * will be decoded to. The default is LV_COLOR_FORMAT_ARGB8888. + * Call this before `lv_gif_set_src` to avoid reallocating the framebuffer. + * @param obj pointer to a gif object + * @param color_format the color format of the gif framebuffer + */ +void lv_gif_set_color_format(lv_obj_t * obj, lv_color_format_t color_format); + /** * Set the gif data to display on the object * @param obj pointer to a gif object diff --git a/src/libs/gltf/fastgltf/lv_fastgltf.hpp b/src/libs/gltf/fastgltf/lv_fastgltf.hpp new file mode 100644 index 0000000000..f4465dc30b --- /dev/null +++ b/src/libs/gltf/fastgltf/lv_fastgltf.hpp @@ -0,0 +1,124 @@ +/** + * @file lv_fastgltf.hpp + * + */ + +/********************* + * INCLUDES + *********************/ + +#include "../../../lv_conf_internal.h" + +#if LV_USE_GLTF + +#include +#include +#include +#include + +namespace fastgltf +{ +FASTGLTF_EXPORT template +#if FASTGLTF_HAS_CONCEPTS +requires std::same_as, Asset> && + std::is_invocable_v +#endif + void namegen_iterate_scene_nodes(AssetType &&asset, + std::size_t sceneIndex, + Callback callback) +{ + auto &scene = asset.scenes[sceneIndex]; + + std::string _id = std::string(""); + std::string _ip = std::string(""); + if (asset.scenes.size() > 1) { + _id = "scene_" + std::to_string(sceneIndex); + _ip = std::to_string(sceneIndex); + } + auto function = [&](std::size_t nodeIndex, std::string &parentId, + std::string &parentIp, std::size_t __child_index, + auto &self) -> void { + assert(asset.nodes.size() > nodeIndex); + auto &node = asset.nodes[nodeIndex]; + std::string _nodeId = + parentId + std::string("/") + std::string(node.name); + std::string _nodeIp = parentIp + std::string(".") + + std::to_string(__child_index); + std::invoke(callback, node, _nodeId, _nodeIp, nodeIndex, + __child_index); + std::size_t ____child_index = 0; + for (auto &child : node.children) { + self(child, _nodeId, _nodeIp, ____child_index, self); + ____child_index += 1; + } + }; + std::size_t child_index = 0; + for (auto &sceneNode : scene.nodeIndices) { + function(sceneNode, _id, _ip, child_index, function); + child_index += 1; + } +} +FASTGLTF_EXPORT template +#if FASTGLTF_HAS_CONCEPTS +requires std::same_as, Asset> && + std::is_invocable_v +#endif + void + findlight_iterate_scene_nodes(AssetType &&asset, std::size_t sceneIndex, + math::fmat4x4 *initial, Callback callback) +{ + auto &scene = asset.scenes[sceneIndex]; + auto function = [&](std::size_t nodeIndex, + math::fmat4x4 &parentWorldMatrix, + auto &self) -> void { + assert(asset.nodes.size() > nodeIndex); + auto &node = asset.nodes[nodeIndex]; + auto _localMat = getTransformMatrix(node, math::fmat4x4()); + std::invoke(callback, node, parentWorldMatrix, _localMat); + for (auto &child : node.children) { + math::fmat4x4 _parentWorldTemp = + parentWorldMatrix * _localMat; + self(child, _parentWorldTemp, self); + } + }; + for (auto &sceneNode : scene.nodeIndices) { + auto tmat2 = fastgltf::math::fmat4x4(*initial); + function(sceneNode, tmat2, function); + } +} +FASTGLTF_EXPORT template +#if FASTGLTF_HAS_CONCEPTS + requires std::same_as, Asset> + && std::is_invocable_v +#endif +inline void custom_iterate_scene_nodes(AssetType&& asset, std::size_t sceneIndex, math::fmat4x4 * initial, + Callback callback) +{ + auto & scene = asset.scenes[sceneIndex]; + auto & nodes = asset.nodes; + auto function = [&](std::size_t nodeIndex, math::fmat4x4 & parentWorldMatrix, auto & self) -> void { + //assert(asset.nodes.size() > nodeIndex); + auto & node = nodes[nodeIndex]; + auto _localMat = getTransformMatrix(node, math::fmat4x4()); + std::invoke(callback, node, parentWorldMatrix, _localMat); + uint32_t num_children = node.children.size(); + if(num_children > 0) { + math::fmat4x4 _parentWorldTemp = parentWorldMatrix * _localMat; + if(num_children > 1) { + math::fmat4x4 per_child_copy = math::fmat4x4(_parentWorldTemp); + for(auto & child : node.children) self(child, per_child_copy, self); + } + else { + self(node.children[0], _parentWorldTemp, self); + } + } + }; + // auto tempmat = fastgltf::math::fmat4x4(*initial); + //for (auto& sceneNode : scene.nodeIndices) function(sceneNode, &tempmat, function); + for(auto & sceneNode : scene.nodeIndices) function(sceneNode, *initial, function); +} +} + + +#endif /*LV_USE_GLTF*/ diff --git a/src/libs/gltf/gltf_data/lv_gltf_bind.cpp b/src/libs/gltf/gltf_data/lv_gltf_bind.cpp new file mode 100644 index 0000000000..5c2a1f671d --- /dev/null +++ b/src/libs/gltf/gltf_data/lv_gltf_bind.cpp @@ -0,0 +1,153 @@ + +#include "lv_gltf_data_internal.hpp" + +#if LV_USE_GLTF +#include "../../../drivers/opengles/lv_opengles_private.h" + +#include + +#include +#include +#include + +#include "lv_gltf_bind.h" + +static uint32_t bind_count = 0; + +void lv_gltf_bind_set(lv_gltf_bind_t * bind, uint8_t channel, float data) +{ + LV_ASSERT_NULL(bind); + LV_ASSERT(channel < LV_GLTF_BIND_MAX_CHANNELS); + + if(data != bind->data[channel]) { + bind->data[channel] = data; + bind->dirty = true; + } +} + +float lv_gltf_bind_get(lv_gltf_bind_t * bind, uint8_t channel) +{ + LV_ASSERT_NULL(bind); + LV_ASSERT(channel < LV_GLTF_BIND_MAX_CHANNELS); + return bind->data[channel]; +} + +void lv_gltf_bind_bind_clean(lv_gltf_bind_t * bind) +{ + bind->dirty = false; +} + +lv_gltf_bind_t * add_by_node(lv_gltf_model_t * gltf_data, fastgltf::Node * node, lv_gltf_bind_prop_t which_prop, + uint32_t data_mask, + lv_gltf_bind_dir_t dir) +{ + if(node == nullptr) { + return nullptr; + } + + lv_gltf_bind_t new_bind; + new_bind.id = bind_count++; + new_bind.prop = which_prop; + new_bind.data_mask = data_mask; + new_bind.data[0] = new_bind.data[1] = new_bind.data[2] = which_prop == LV_GLTF_BIND_PROP_SCALE ? 1.f : 0.f; + new_bind.dir = dir; + new_bind.dirty = true; + new_bind.next_bind = nullptr; + + // Check if an bind already exists for this node + if(gltf_data->node_binds.find(node) != gltf_data->node_binds.end()) { + // Get the existing bind + lv_gltf_bind_t * existingbind = gltf_data->node_binds[node]; + + // Traverse to the end of the linked list of binds + while(existingbind->next_bind != nullptr) + existingbind = existingbind->next_bind; + + lv_array_push_back(&gltf_data->binds, &new_bind); + existingbind->next_bind = (lv_gltf_bind_t *)lv_array_at(&gltf_data->binds, lv_array_size(&gltf_data->binds) - 1); + return existingbind->next_bind; + } + else { + // No existing bind, insert the new one + lv_array_push_back(&gltf_data->binds, &new_bind); + gltf_data->node_binds[node] = (lv_gltf_bind_t *)lv_array_at(&gltf_data->binds, lv_array_size(&gltf_data->binds) - 1); + return gltf_data->node_binds[node]; + } + return nullptr; +} + +lv_gltf_bind_t * lv_gltf_bind_add_by_index(lv_gltf_model_t * data, size_t index, lv_gltf_bind_prop_t which_prop, + uint32_t data_mask, + lv_gltf_bind_dir_t dir) +{ + lv_gltf_data_node_t * node = lv_gltf_data_node_get_by_index(data, index); + if(!node) { + return nullptr; + } + + return add_by_node(data, node->node, which_prop, data_mask, dir); +} + +lv_gltf_bind_t * lv_gltf_bind_add_by_ip(lv_gltf_model_t * data, const char * ip, lv_gltf_bind_prop_t which_prop, + uint32_t data_mask, + lv_gltf_bind_dir_t dir) +{ + lv_gltf_data_node_t * node = lv_gltf_data_node_get_by_ip(data, ip); + if(!node) { + return nullptr; + } + return add_by_node(data, node->node, which_prop, data_mask, dir); +} + +lv_gltf_bind_t * lv_gltf_bind_add_by_path(lv_gltf_model_t * data, const char * path, lv_gltf_bind_prop_t which_prop, + uint32_t data_mask, lv_gltf_bind_dir_t dir) +{ + lv_gltf_data_node_t * node = lv_gltf_data_node_get_by_path(data, path); + + if(!node) { + return nullptr; + } + + return add_by_node(data, node->node, which_prop, data_mask, dir); +} + +lv_result_t lv_gltf_bind_remove(lv_gltf_model_t * gltf_data, lv_gltf_bind_t * bind_to_remove) +{ + for(auto pair : gltf_data->node_binds) { + lv_gltf_bind_t * currentbind = pair.second; + lv_gltf_bind_t * previousbind = nullptr; + + while(currentbind != nullptr) { + if(currentbind->id == bind_to_remove->id) { + // Found the bind to remove + if(previousbind != nullptr) { + // Link the previous bind to the next one + previousbind->next_bind = currentbind->next_bind; + } + else { + gltf_data->node_binds[pair.first] = currentbind->next_bind; + } + + for(uint32_t i = 0; i < lv_array_size(&gltf_data->binds); ++i) { + const lv_gltf_bind_t * current_entry = (const lv_gltf_bind_t *)lv_array_at(&gltf_data->binds, i); + if(current_entry->id == bind_to_remove->id) { + lv_array_remove(&gltf_data->binds, i); + } + } + return LV_RESULT_OK; + } + previousbind = currentbind; + if(currentbind != nullptr) { + if(currentbind->next_bind != nullptr) { + currentbind = currentbind->next_bind; + } + else { + currentbind = nullptr; + } + } + } + } + return LV_RESULT_INVALID; +} + +#endif /*LV_USE_GLTF*/ diff --git a/src/libs/gltf/gltf_data/lv_gltf_bind.h b/src/libs/gltf/gltf_data/lv_gltf_bind.h new file mode 100644 index 0000000000..1210fbf748 --- /dev/null +++ b/src/libs/gltf/gltf_data/lv_gltf_bind.h @@ -0,0 +1,106 @@ +#ifndef LV_GLTF_BIND_H +#define LV_GLTF_BIND_H + +#include "lv_gltf_model.h" + +#if LV_USE_GLTF + +#ifdef __cplusplus +extern "C" { +#endif + +typedef enum { + LV_GLTF_BIND_PROP_VISIBILITY, + LV_GLTF_BIND_PROP_POSITION, + LV_GLTF_BIND_PROP_ROTATION, + LV_GLTF_BIND_PROP_SCALE, + LV_GLTF_BIND_PROP_BASE_COLOR, + LV_GLTF_BIND_PROP_ALPHA_FACTOR, + LV_GLTF_BIND_PROP_EMIS_COLOR, + LV_GLTF_BIND_PROP_WORLD_POSITION +} lv_gltf_bind_prop_t; + +#define LV_GLTF_BIND_MAX_CHANNELS 4 +#define LV_GLTF_BIND_CHANNEL_0 (0x01) +#define LV_GLTF_BIND_CHANNEL_1 (0x02) +#define LV_GLTF_BIND_CHANNEL_2 (0x04) +#define LV_GLTF_BIND_CHANNEL_3 (0x08) + +typedef enum { LV_GLTF_BIND_DIR_READ, LV_GLTF_BIND_DIR_WRITE } lv_gltf_bind_dir_t; + +struct _lv_gltf_bind { + struct _lv_gltf_bind * next_bind; + lv_gltf_bind_prop_t prop; + lv_gltf_bind_dir_t dir; + uint32_t id; + uint32_t data_mask; + float data[LV_GLTF_BIND_MAX_CHANNELS]; + bool dirty; +}; + +typedef struct _lv_gltf_bind lv_gltf_bind_t; + +void lv_gltf_bind_set(lv_gltf_bind_t * bind, uint8_t channel, float data); +float lv_gltf_bind_get(lv_gltf_bind_t * bind, uint8_t channel); + +/** + * @brief Reset the dirty flag for a given bind. + * + * @param bind Pointer to the lv_gltf_bind_t to reset the dirty flag for. + */ +void lv_gltf_bind_bind_clean(lv_gltf_bind_t * bind); + +/** + * @brief Add an bind to a GLTF data object by node index. + * + * @param gltf_data Pointer to the lv_gltf_data_t object to which the bind will be added. + * @param nodeIndex The index of the node to bind. + * @param which_prop The property to bind. + * @param data_mask A mask indicating which data fields to bind. + * @return Pointer to the newly created lv_gltf_bind_t object, or NULL if the operation failed. + */ +lv_gltf_bind_t * lv_gltf_bind_add_by_index(lv_gltf_model_t * data, size_t index, lv_gltf_bind_prop_t which_prop, + uint32_t data_mask, + lv_gltf_bind_dir_t dir); + +/** + * @brief Add an bind to a GLTF data object by node IP address. + * + * @param gltf_data Pointer to the lv_gltf_data_t object to which the bind will be added. + * @param nodeIp The IP address of the node to bind. + * @param which_prop The property to bind. + * @param data_mask A mask indicating which data fields to bind. + * @return Pointer to the newly created lv_gltf_bind_t object, or NULL if the operation failed. + */ +lv_gltf_bind_t * lv_gltf_bind_add_by_ip(lv_gltf_model_t * data, const char * node_ip, lv_gltf_bind_prop_t which_prop, + uint32_t data_mask, lv_gltf_bind_dir_t dir); + +/** + * @brief Add an bind to a GLTF data object by node ID. + * + * @param gltf_data Pointer to the lv_gltf_data_t object to which the bind will be added. + * @param nodeId The ID of the node to bind. + * @param which_prop The property to bind. + * @param data_mask A mask indicating which data fields to bind. + * @return Pointer to the newly created lv_gltf_bind_t object, or NULL if the operation failed. + */ +lv_gltf_bind_t * lv_gltf_bind_add_by_path(lv_gltf_model_t * data, const char * path, lv_gltf_bind_prop_t which_prop, + uint32_t data_mask, lv_gltf_bind_dir_t dir); + +/** + * @brief Remove an bind from a GLTF data object. + * + * @param gltf_data Pointer to the lv_gltf_data_t object from which the bind will be removed. + * @param bind The bind to be removed. + * @param which_prop The property to bind. + * @param data_mask A mask indicating which data fields to bind. + * @return True on success, False on failure. + */ +lv_result_t lv_gltf_bind_remove(lv_gltf_model_t * _data, lv_gltf_bind_t * bind); + +#ifdef __cplusplus +} /*extern "C"*/ +#endif + +#endif /*LV_USE_GLTF*/ +#endif /*LV_GLTF_BIND_H*/ diff --git a/src/libs/gltf/gltf_data/lv_gltf_data.cpp b/src/libs/gltf/gltf_data/lv_gltf_data.cpp new file mode 100644 index 0000000000..60f2e6ed45 --- /dev/null +++ b/src/libs/gltf/gltf_data/lv_gltf_data.cpp @@ -0,0 +1,271 @@ +/** + * @file lv_gltf_data.c + * + */ + +/********************* + * INCLUDES + *********************/ + +#include "lv_gltf_data_internal.hpp" + +#if LV_USE_GLTF + +#include +#include "../../../misc/lv_assert.h" +#include "../../../core/lv_obj_pos.h" +#include "../../../misc/lv_timer.h" +#include "../gltf_view/lv_gltf_view_internal.h" + + +/********************* + * DEFINES + *********************/ + + +/********************** + * TYPEDEFS + **********************/ + +/********************** + * STATIC PROTOTYPES + **********************/ + +static void update_animation_cb(lv_timer_t * timer); + +/********************** + * STATIC VARIABLES + **********************/ + +/********************** + * MACROS + **********************/ + +/********************** + * GLOBAL FUNCTIONS + **********************/ +lv_gltf_model_t * lv_gltf_data_create_internal(const char * gltf_path, + fastgltf::Asset asset) +{ + lv_gltf_model_t * data = (lv_gltf_model_t *)lv_zalloc(sizeof(*data)); + LV_ASSERT_MALLOC(data); + new(data) lv_gltf_model_t; + new(&data->asset) fastgltf::Asset(std::move(asset)); + data->filename = gltf_path; + data->last_camera_index = -5; + data->last_anim_num = -5; + data->current_animation_max_time = 0; + data->local_timestamp = 0.0f; + data->last_material_index = 99999; + data->last_frame_was_antialiased = false; + data->last_frame_no_motion = false; + data->_last_frame_no_motion = false; + + data->animation_update_timer = lv_timer_create(update_animation_cb, LV_DEF_REFR_PERIOD, data); + lv_timer_pause(data->animation_update_timer); + LV_ASSERT_NULL(data->animation_update_timer); + + new(&data->node_binds) NodeOverrideMap(); + new(&data->node_transform_cache) NodeTransformMap(); + new(&data->opaque_nodes_by_material_index) MaterialIndexMap(); + new(&data->blended_nodes_by_material_index) MaterialIndexMap(); + new(&data->validated_skins) LongVector(); + new(&data->skin_tex) IntVector(); + new(&data->local_mesh_to_center_points_by_primitive) + NodePrimCenterMap(); + new(&data->node_by_light_index) NodeVector(); + new(&data->meshes) std::vector(); + new(&data->textures) std::vector(); + + lv_array_init(&data->binds, 0, sizeof(lv_gltf_bind_t)); + lv_array_init(&data->compiled_shaders, 1, sizeof(lv_gltf_compiled_shader_t)); + return data; +} + +void lv_gltf_data_destroy(lv_gltf_model_t * data) +{ + lv_gltf_data_destroy_textures(data); + lv_free(data); +} + +const char * lv_gltf_get_filename(const lv_gltf_model_t * data) +{ + LV_ASSERT_NULL(data); + return data->filename; +} + +size_t lv_gltf_model_get_image_count(const lv_gltf_model_t * data) +{ + LV_ASSERT_NULL(data); + return data->asset.images.size(); +} + +size_t lv_gltf_model_get_texture_count(const lv_gltf_model_t * data) +{ + LV_ASSERT_NULL(data); + return data->asset.textures.size(); +} + +GLuint lv_gltf_data_get_texture(lv_gltf_model_t * data, size_t index) +{ + LV_ASSERT_NULL(data); + LV_ASSERT(index < data->textures.size()); + return data->textures[index]; +} + +size_t lv_gltf_model_get_material_count(const lv_gltf_model_t * data) +{ + LV_ASSERT_NULL(data); + return data->asset.materials.size(); +} +size_t lv_gltf_model_get_camera_count(const lv_gltf_model_t * data) +{ + LV_ASSERT_NULL(data); + return data->asset.cameras.size(); +} +size_t lv_gltf_model_get_node_count(const lv_gltf_model_t * data) +{ + LV_ASSERT_NULL(data); + return data->asset.nodes.size(); +} +size_t lv_gltf_model_get_mesh_count(const lv_gltf_model_t * data) +{ + LV_ASSERT_NULL(data); + return data->asset.meshes.size(); +} +size_t lv_gltf_model_get_scene_count(const lv_gltf_model_t * data) +{ + LV_ASSERT_NULL(data); + return data->asset.scenes.size(); +} +size_t lv_gltf_model_get_animation_count(const lv_gltf_model_t * data) +{ + LV_ASSERT_NULL(data); + return data->asset.animations.size(); +} + +lv_result_t lv_gltf_model_play_animation(lv_gltf_model_t * model, size_t index) +{ + LV_ASSERT_NULL(model); + if(index >= model->asset.animations.size()) { + return LV_RESULT_INVALID; + } + + if(lv_timer_get_paused(model->animation_update_timer)) { + model->last_tick = lv_tick_get(); + lv_timer_resume(model->animation_update_timer); + } + + model->current_animation_max_time = lv_gltf_data_get_animation_total_time(model, index); + model->current_animation = index; + model->is_animation_enabled = true; + return LV_RESULT_OK; +} + +void lv_gltf_model_pause_animation(lv_gltf_model_t * model) +{ + LV_ASSERT_NULL(model); + model->is_animation_enabled = false; + lv_timer_pause(model->animation_update_timer); +} + +bool lv_gltf_model_is_animation_paused(lv_gltf_model_t * model) +{ + + LV_ASSERT_NULL(model); + return !model->is_animation_enabled; +} + +size_t lv_gltf_model_get_animation(lv_gltf_model_t * model) +{ + + LV_ASSERT_NULL(model); + return model->current_animation; +} + +lv_gltf_model_t * +lv_gltf_data_load_from_file(const char * file_path, + lv_opengl_shader_manager_t * shader_manager) +{ + return lv_gltf_data_load_internal(file_path, 0, shader_manager); +} + +lv_gltf_model_t * +lv_gltf_data_load_from_bytes(const uint8_t * data, size_t data_size, + lv_opengl_shader_manager_t * shader_manager) +{ + return lv_gltf_data_load_internal(data, data_size, shader_manager); +} + +fastgltf::Asset * lv_gltf_data_get_asset(lv_gltf_model_t * data) +{ + LV_ASSERT_NULL(data); + return &data->asset; +} +double lv_gltf_data_get_radius(lv_gltf_model_t * data) +{ + LV_ASSERT_NULL(data); + return data->bound_radius; +} +fastgltf::math::fvec3 lv_gltf_data_get_center(const lv_gltf_model_t * data) +{ + LV_ASSERT_NULL(data); + return data->vertex_cen; +} +fastgltf::math::fvec3 lv_gltf_data_get_bounds_min(const lv_gltf_model_t * data) +{ + LV_ASSERT_NULL(data); + return data->vertex_min; +} +fastgltf::math::fvec3 lv_gltf_data_get_bounds_max(const lv_gltf_model_t * data) +{ + LV_ASSERT_NULL(data); + return data->vertex_max; +} + + + + +void lv_gltf_data_copy_bounds_info(lv_gltf_model_t * to, lv_gltf_model_t * from) +{ + { + to->vertex_min[0] = from->vertex_min[0]; + to->vertex_min[1] = from->vertex_min[1]; + to->vertex_min[2] = from->vertex_min[2]; + } + { + to->vertex_max[0] = from->vertex_max[0]; + to->vertex_max[1] = from->vertex_max[1]; + to->vertex_max[2] = from->vertex_max[2]; + } + { + to->vertex_cen[0] = from->vertex_cen[0]; + to->vertex_cen[1] = from->vertex_cen[1]; + to->vertex_cen[2] = from->vertex_cen[2]; + } + to->bound_radius = from->bound_radius; +} + + +/********************** + * STATIC FUNCTIONS + **********************/ + +static void update_animation_cb(lv_timer_t * timer) +{ + lv_gltf_model_t * model = (lv_gltf_model_t *)lv_timer_get_user_data(timer); + + const uint32_t current_tick = lv_tick_get(); + const uint32_t delta = lv_tick_diff(current_tick, model->last_tick); + + model->last_tick = current_tick; + model->local_timestamp += (delta * model->viewer->desc.animation_speed_ratio) / 1000; + + if(model->local_timestamp >= model->current_animation_max_time) { + model->local_timestamp = 50; + } + lv_obj_invalidate((lv_obj_t *)model->viewer); +} + +#endif /*LV_USE_GLTF*/ + diff --git a/src/libs/gltf/gltf_data/lv_gltf_data_animations.cpp b/src/libs/gltf/gltf_data/lv_gltf_data_animations.cpp new file mode 100644 index 0000000000..1d8da05ea4 --- /dev/null +++ b/src/libs/gltf/gltf_data/lv_gltf_data_animations.cpp @@ -0,0 +1,244 @@ +/** + * @file lv_gltf_data_animations.cpp + * + */ + +/********************* + * INCLUDES + *********************/ + +#include "lv_gltf_data_internal.hpp" + +#if LV_USE_GLTF +#include + +/********************* + * DEFINES + *********************/ + +#define TIME_LOC_PREPASS_COUNT 16 + +/********************** + * TYPEDEFS + **********************/ + +/********************** + * STATIC PROTOTYPES + **********************/ + +#include "fastgltf/math.hpp" +#include "lv_gltf_data_internal.hpp" +static fastgltf::math::fvec3 animation_get_vec3_at_timestamp(lv_gltf_model_t * data, + fastgltf::AnimationSampler * sampler, + float seconds); + +static fastgltf::math::fquat animation_get_quat_at_timestamp(lv_gltf_model_t * data, + fastgltf::AnimationSampler * sampler, + float _seconds); + +/********************** + * STATIC VARIABLES + **********************/ + +/********************** + * MACROS + **********************/ + +/********************** + * GLOBAL FUNCTIONS + **********************/ + +uint32_t lv_gltf_data_get_animation_total_time(lv_gltf_model_t * data, uint32_t index) +{ + LV_ASSERT(data->asset.animations.size() > index); + auto & animation = data->asset.animations[index]; + float max_time = -1.0f; + for(uint64_t i = 0; i < animation.channels.size(); i++) { + auto & accessor = data->asset.accessors[animation.samplers[i].inputAccessor]; + max_time = std::max(max_time, fastgltf::getAccessorElement(data->asset, accessor, accessor.count - 1)); + } + return (uint32_t)(max_time * 1000); +} + +std::vector * lv_gltf_data_animation_get_channel_set(std::size_t anim_num, lv_gltf_model_t * data, + fastgltf::Node & node) +{ + const auto & asset = lv_gltf_data_get_asset(data); + size_t animation_count = lv_gltf_model_get_animation_count(data); + if(data->channel_set_cache.find(&node) == data->channel_set_cache.end()) { + std::vector new_cache = std::vector(); + if(animation_count > anim_num) { + auto & anim = asset->animations[anim_num]; + + for(uint64_t c = 0; c < anim.channels.size(); c++) { + auto & channel = anim.channels[c]; + if(&(asset->nodes[channel.nodeIndex.value()]) == &node) { + new_cache.push_back(c); + } + } + } + data->channel_set_cache[&node] = new_cache; + } + return &data->channel_set_cache[&node]; +} + +void lv_gltf_data_animation_matrix_apply(float timestamp, std::size_t anim_num, lv_gltf_model_t * gltf_data, + fastgltf::Node & node, + fastgltf::math::fmat4x4 & matrix) +{ + const auto & asset = lv_gltf_data_get_asset(gltf_data); + + size_t animation_count = lv_gltf_model_get_animation_count(gltf_data); + auto _channel_set = lv_gltf_data_animation_get_channel_set(anim_num, gltf_data, node); + if(_channel_set->size() == 0) { + return; + } + if(animation_count > anim_num) { + auto & anim = asset->animations[anim_num]; + fastgltf::math::fvec3 newPos, newScale; + fastgltf::math::fmat3x3 rotmat; + for(const auto & c : (*_channel_set)) { + switch(anim.channels[c].path) { + case fastgltf::AnimationPath::Translation: + newPos = animation_get_vec3_at_timestamp(gltf_data, &anim.samplers[c], timestamp); + matrix[3][0] = newPos[0]; + matrix[3][1] = newPos[1]; + matrix[3][2] = newPos[2]; + break; + case fastgltf::AnimationPath::Rotation: + rotmat = fastgltf::math::asMatrix(animation_get_quat_at_timestamp(gltf_data, &anim.samplers[c], timestamp)); + matrix[0][0] = rotmat[0][0]; + matrix[0][1] = rotmat[0][1]; + matrix[0][2] = rotmat[0][2]; + + matrix[1][0] = rotmat[1][0]; + matrix[1][1] = rotmat[1][1]; + matrix[1][2] = rotmat[1][2]; + + matrix[2][0] = rotmat[2][0]; + matrix[2][1] = rotmat[2][1]; + matrix[2][2] = rotmat[2][2]; + break; + case fastgltf::AnimationPath::Scale: + newScale = animation_get_vec3_at_timestamp(gltf_data, &anim.samplers[c], timestamp); + for(int32_t rs = 0; rs < 3; ++rs) { + matrix[0][rs] *= newScale[0]; + matrix[1][rs] *= newScale[1]; + matrix[2][rs] *= newScale[2]; + } + break; + case fastgltf::AnimationPath::Weights: + LV_LOG_WARN("Unhandled weights animation"); + break; + } + } + } +} + +/********************** + * STATIC FUNCTIONS + **********************/ + +static fastgltf::math::fquat animation_get_quat_at_timestamp(lv_gltf_model_t * data, + fastgltf::AnimationSampler * sampler, + float _seconds) +{ + const auto & asset = lv_gltf_data_get_asset(data); + auto & _inAcc = asset->accessors[sampler->inputAccessor]; + auto & _outAcc = asset->accessors[sampler->outputAccessor]; + std::size_t _inAccCount = _inAcc.count; + float _maxTime = fastgltf::getAccessorElement(*asset, _inAcc, _inAccCount - 1); + std::size_t _lowerIndex = 0; + float _lowerTimestamp = 0.0f; + + if(_seconds < 0.001f) { + _lowerIndex = 0; + } + else { + std::size_t _firstCheckOffset = 0; + std::size_t _lastCheckOffset = _inAccCount; + std::size_t _prepassLeft = TIME_LOC_PREPASS_COUNT; + while(_prepassLeft > 0) { + _prepassLeft -= 1; + if(_seconds >= fastgltf::getAccessorElement(*asset, _inAcc, (_firstCheckOffset + _lastCheckOffset) >> 1)) { + _firstCheckOffset = (_firstCheckOffset + _lastCheckOffset) >> 1; + } + else { + _lastCheckOffset = (_firstCheckOffset + _lastCheckOffset) >> 1; + if(_lastCheckOffset <= _firstCheckOffset + 1) { + _prepassLeft = 0; + } + } + } + for(uint64_t ii = _firstCheckOffset; ii < _inAccCount; ii++) { + float _stampTime = fastgltf::getAccessorElement(*asset, _inAcc, ii); + if(_stampTime > _seconds) { + _lowerIndex = ii - 1; + break; + } + _lowerTimestamp = _stampTime; + } + } + + fastgltf::math::fquat _lowerValue = fastgltf::getAccessorElement(*asset, _outAcc, _lowerIndex); + if(_seconds >= _maxTime || _seconds <= 0.0f) { + return _lowerValue; + } + std::size_t _upperIndex = _lowerIndex + 1; + float _linDist = fastgltf::getAccessorElement(*asset, _inAcc, _upperIndex) - _lowerTimestamp; + return fastgltf::math::slerp(_lowerValue, fastgltf::getAccessorElement(*asset, _outAcc, + _upperIndex), (_seconds - _lowerTimestamp) / _linDist); +} + +fastgltf::math::fvec3 animation_get_vec3_at_timestamp(lv_gltf_model_t * data, fastgltf::AnimationSampler * sampler, + float _seconds) +{ + const auto & asset = lv_gltf_data_get_asset(data); + auto & _inAcc = asset->accessors[sampler->inputAccessor]; + auto & _outAcc = asset->accessors[sampler->outputAccessor]; + std::size_t _inAccCount = _inAcc.count; + float _maxTime = fastgltf::getAccessorElement(*asset, _inAcc, _inAccCount - 1); + std::size_t _lowerIndex = 0; + float _lowerTimestamp = 0.0f; + + if(_seconds < 0.001f) { + _lowerIndex = 0; + } + else { + std::size_t _firstCheckOffset = 0; + std::size_t _lastCheckOffset = _inAccCount; + std::size_t _prepassLeft = TIME_LOC_PREPASS_COUNT; + while(_prepassLeft > 0) { + _prepassLeft -= 1; + if(_seconds >= fastgltf::getAccessorElement(*asset, _inAcc, (_firstCheckOffset + _lastCheckOffset) >> 1)) { + _firstCheckOffset = (_firstCheckOffset + _lastCheckOffset) >> 1; + } + else { + _lastCheckOffset = (_firstCheckOffset + _lastCheckOffset) >> 1; + if(_lastCheckOffset <= _firstCheckOffset + 1) { + _prepassLeft = 0; + } + } + } + for(uint64_t ii = _firstCheckOffset; ii < _inAccCount; ii++) { + float _stampTime = fastgltf::getAccessorElement(*asset, _inAcc, ii); + if(_stampTime > _seconds) { + _lowerIndex = ii - 1; + break; + } + _lowerTimestamp = _stampTime; + } + } + + fastgltf::math::fvec3 _lowerValue = fastgltf::getAccessorElement(*asset, _outAcc, _lowerIndex); + if(_seconds >= _maxTime || _seconds <= 0.0f) { + return _lowerValue; + } + std::size_t _upperIndex = _lowerIndex + 1; + fastgltf::math::fvec3 _upperValue = fastgltf::getAccessorElement(*asset, _outAcc, _upperIndex); + float _upperTimestamp = fastgltf::getAccessorElement(*asset, _inAcc, _upperIndex); + return fastgltf::math::lerp(_lowerValue, _upperValue, + (_seconds - _lowerTimestamp) / (_upperTimestamp - _lowerTimestamp)); +} + +#endif /*LV_USE_GLTF*/ diff --git a/src/libs/gltf/gltf_data/lv_gltf_data_cache.cpp b/src/libs/gltf/gltf_data/lv_gltf_data_cache.cpp new file mode 100644 index 0000000000..69bae4e7ad --- /dev/null +++ b/src/libs/gltf/gltf_data/lv_gltf_data_cache.cpp @@ -0,0 +1,103 @@ +/** + * @file lv_gltf_data_cache.cpp + * + */ + +/********************* + * INCLUDES + *********************/ + +#include "lv_gltf_data_internal.hpp" + +#if LV_USE_GLTF +/********************* + * DEFINES + *********************/ + +/********************** + * TYPEDEFS + **********************/ + +/********************** + * STATIC PROTOTYPES + **********************/ + +/********************** + * STATIC VARIABLES + **********************/ + +/********************** + * MACROS + **********************/ + +/********************** + * GLOBAL FUNCTIONS + **********************/ + +fastgltf::math::fmat4x4 lv_gltf_data_get_cached_transform(lv_gltf_model_t * data, + fastgltf::Node * node) +{ + return data->node_transform_cache[node]; +} + +bool lv_gltf_data_has_cached_transform(lv_gltf_model_t * data, fastgltf::Node * node) +{ + return (data->node_transform_cache.find(node) != + data->node_transform_cache.end()); +} +void lv_gltf_data_set_cached_transform(lv_gltf_model_t * data, fastgltf::Node * node, + fastgltf::math::fmat4x4 M) +{ + data->node_transform_cache[node] = M; +} +void lv_gltf_data_clear_transform_cache(lv_gltf_model_t * data) +{ + data->node_transform_cache.clear(); +} +bool lv_gltf_data_transform_cache_is_empty(lv_gltf_model_t * data) +{ + return data->node_transform_cache.size() == 0; +} + +void recache_centerpoint(lv_gltf_model_t * data, size_t index_mesh, int32_t primitive) +{ + data->local_mesh_to_center_points_by_primitive[index_mesh][primitive] = + lv_gltf_get_primitive_centerpoint(data, data->asset.meshes[index_mesh], + primitive); +} + +fastgltf::math::fvec3 lv_gltf_data_get_centerpoint(lv_gltf_model_t * gltf_data, + fastgltf::math::fmat4x4 matrix, + size_t mesh_index, int32_t elem) +{ + if(!lv_gltf_data_centerpoint_cache_contains(gltf_data, mesh_index, elem)) { + recache_centerpoint(gltf_data, mesh_index, elem); + } + return get_cached_centerpoint(gltf_data, mesh_index, elem, matrix); +} +bool lv_gltf_data_centerpoint_cache_contains(lv_gltf_model_t * data, size_t index, int32_t element) +{ + return data->local_mesh_to_center_points_by_primitive.find(index) != + data->local_mesh_to_center_points_by_primitive.end() && + data->local_mesh_to_center_points_by_primitive[index].find(element) != + data->local_mesh_to_center_points_by_primitive[index].end(); +} + +fastgltf::math::fvec3 get_cached_centerpoint(lv_gltf_model_t * data, size_t index, + int32_t element, + fastgltf::math::fmat4x4 matrix) +{ + fastgltf::math::fvec4 tv = fastgltf::math::fvec4( + data->local_mesh_to_center_points_by_primitive[index][element]); + tv[3] = 1.f; + tv = matrix * tv; + return fastgltf::math::fvec3(tv[0], tv[1], tv[2]); +} + + + +/********************** + * STATIC FUNCTIONS + **********************/ + +#endif /*LV_USE_GLTF*/ diff --git a/src/libs/gltf/gltf_data/lv_gltf_data_injest.cpp b/src/libs/gltf/gltf_data/lv_gltf_data_injest.cpp new file mode 100644 index 0000000000..a6b9e18a86 --- /dev/null +++ b/src/libs/gltf/gltf_data/lv_gltf_data_injest.cpp @@ -0,0 +1,843 @@ +/** + * @file lv_gltf_data_injest.cpp + * + */ + +/********************* + * INCLUDES + *********************/ +#include "lv_gltf_data_internal.hpp" + +#if LV_USE_GLTF + +#include +#include +#include +#include +#include "../fastgltf/lv_fastgltf.hpp" +#include "../../../misc/lv_assert.h" +#include "../../../misc/lv_log.h" +#include "../../../misc/lv_math.h" +#include "../../../stdlib/lv_sprintf.h" +#include "../../../misc/lv_fs.h" + +#include "../stb_image/stb_image.h" +#include + +/********************* + * DEFINES + *********************/ +constexpr auto SUPPORTED_EXTENSIONS = + //fastgltf::Extensions::KHR_draco_mesh_compression | + //fastgltf::Extensions::EXT_meshopt_compression | + fastgltf::Extensions::KHR_mesh_quantization | fastgltf::Extensions::KHR_texture_transform | + fastgltf::Extensions::KHR_lights_punctual | fastgltf::Extensions::KHR_materials_anisotropy | + fastgltf::Extensions::KHR_materials_clearcoat | fastgltf::Extensions::KHR_materials_dispersion | + fastgltf::Extensions::KHR_materials_emissive_strength | fastgltf::Extensions::KHR_materials_ior | + fastgltf::Extensions::KHR_materials_iridescence | fastgltf::Extensions::KHR_materials_sheen | + fastgltf::Extensions::KHR_materials_specular | + fastgltf::Extensions:: + KHR_materials_pbrSpecularGlossiness + | // Depreciated, to enable support make sure to define FASTGLTF_ENABLE_DEPRECATED_EXT + fastgltf::Extensions::KHR_materials_transmission | + fastgltf::Extensions::KHR_materials_volume | fastgltf::Extensions::KHR_materials_unlit | + fastgltf::Extensions::EXT_texture_webp | + //fastgltf::Extensions::KHR_materials_diffuse_transmission | + fastgltf::Extensions::KHR_materials_variants; + +constexpr auto GLTF_OPTIONS = fastgltf::Options::DontRequireValidAssetMember | fastgltf::Options::AllowDouble | + fastgltf::Options::LoadExternalBuffers | fastgltf::Options::LoadExternalImages | + fastgltf::Options::GenerateMeshIndices; + +/********************** + * TYPEDEFS + **********************/ + +typedef struct { + fastgltf::math::fvec3 position; + fastgltf::math::fvec3 normal; + fastgltf::math::fvec4 tangent; + fastgltf::math::fvec2 uv; + fastgltf::math::fvec2 uv2; + fastgltf::math::fvec4 joints; + fastgltf::math::fvec4 joints2; + fastgltf::math::fvec4 weights; + fastgltf::math::fvec4 weights2; +} vertex_t; + +/********************** + * STATIC PROTOTYPES + **********************/ + +static void set_bounds_info(lv_gltf_model_t * data, fastgltf::math::fvec3 v_min, fastgltf::math::fvec3 v_max, + fastgltf::math::fvec3 v_cen, float radius); +static lv_gltf_model_t * create_data_from_bytes(const uint8_t * bytes, size_t data_size); + +static lv_gltf_model_t * create_data_from_file(const char * path); + +static void injest_grow_bounds_to_include(lv_gltf_model_t * data, const fastgltf::math::fmat4x4 & matrix, + const fastgltf::Mesh & mesh); + +static void injest_set_initial_bounds(lv_gltf_model_t * data, const fastgltf::math::fmat4x4 & matrix, + const fastgltf::Mesh & mesh); + +static bool injest_image(lv_opengl_shader_manager_t * shader_manager, lv_gltf_model_t * data, fastgltf::Image & image, + uint32_t index); + +static bool injest_image_from_buffer_view(lv_gltf_model_t * data, fastgltf::sources::BufferView & view, + GLuint texture_id); +static void injest_light(lv_gltf_model_t * data, size_t light_index, fastgltf::Light & light, size_t scene_index); +static bool injest_mesh(lv_gltf_model_t * data, fastgltf::Mesh & mesh); + +static void make_small_magenta_texture(uint32_t new_magenta_tex); + +template +static size_t injest_vec_attribute(uint8_t vec_size, int32_t current_attrib_index, lv_gltf_model_t * data, + const fastgltf::Primitive * prim, const char * attrib_id, GLuint primitive_vertex_buffer, + size_t offset, Func &&functor); + +static int32_t injest_get_any_image_index(fastgltf::Optional tex); +static bool injest_check_any_image_index_valid(fastgltf::Optional tex); + +static inline GLsizei get_level_count(int32_t width, int32_t height) +{ + return static_cast(1 + floor(log2(width > height ? width : height))); +} + +static void load_mesh_texture_impl(lv_gltf_model_t * data, const fastgltf::TextureInfo & material_prop, + GLuint * primitive_tex_prop, + GLint * primitive_tex_uv_id); +static void load_mesh_texture(lv_gltf_model_t * data, const fastgltf::Optional & material_prop, + GLuint * primitive_tex_prop, GLint * primitive_tex_uv_id); + +static void load_mesh_texture(lv_gltf_model_t * data, + const fastgltf::Optional & material_prop, + GLuint * primitive_tex_prop, GLint * primitive_tex_uv_id); + +static void load_mesh_texture(lv_gltf_model_t * data, + const fastgltf::Optional & material_prop, + GLuint * primitive_tex_prop, GLint * primitive_tex_uv_id); + +/********************** + * STATIC VARIABLES + **********************/ + +/********************** + * MACROS + **********************/ + +/********************** + * GLOBAL FUNCTIONS + **********************/ + +lv_gltf_model_t * lv_gltf_data_load_internal(const void * data_source, size_t data_size, + lv_opengl_shader_manager_t * shaders) +{ + lv_gltf_model_t * data = NULL; + if(data_size > 0) { + data = create_data_from_bytes((const uint8_t *)data_source, data_size); + } + else { + data = create_data_from_file((const char *)data_source); + } + + LV_ASSERT_MSG(data, "Failed to create gltf data"); + if(!data) { + return NULL; + } + + // Parse the visible node structure to get a world transform matrix for each mesh component + // instance per node, and apply that matrix to the min/max of the untransformed mesh, then + // grow a bounding volume to include those transformed points + + int32_t scene_index = 0; + bool first_visible_mesh = true; + fastgltf::iterateSceneNodes( + data->asset, scene_index, fastgltf::math::fmat4x4(), [&](fastgltf::Node & node, fastgltf::math::fmat4x4 matrix) { + if(!node.meshIndex.has_value()) { + return; + } + if(first_visible_mesh) { + injest_set_initial_bounds(data, matrix, data->asset.meshes[node.meshIndex.value()]); + } + else { + injest_grow_bounds_to_include(data, matrix, data->asset.meshes[node.meshIndex.value()]); + } + first_visible_mesh = false; + }); + lv_gltf_data_nodes_init(data, data->asset.nodes.size()); + + fastgltf::namegen_iterate_scene_nodes(data->asset, scene_index, + [&](fastgltf::Node & node, const std::string & node_path, const std::string & node_ip, + size_t node_index, std::size_t child_index) { + LV_UNUSED(node_index); + LV_UNUSED(child_index); + lv_gltf_data_node_t data_node; + lv_gltf_data_node_init(&data_node, &node, node_path.c_str(), node_ip.c_str()); + lv_gltf_data_node_add(data, &data_node); + }); + + { + uint32_t i = 0; + for(auto & image : data->asset.images) { + injest_image(shaders, data, image, i); + i++; + } + } + uint16_t lightnum = 0; + for(auto & light : data->asset.lights) { + injest_light(data, lightnum, light, 0); + lightnum += 1; + } + for(auto & mesh : data->asset.meshes) { + injest_mesh(data, mesh); + } + + if(data->asset.defaultScene.has_value()) { + LV_LOG_INFO("Default scene = #%d", data->asset.defaultScene.value()); + } + + return data; +} + +/********************** + * STATIC FUNCTIONS + **********************/ + +static lv_gltf_model_t * create_data_from_file(const char * path) +{ +#if !FASTGLTF_HAS_MEMORY_MAPPED_FILE +#error This version of fastgltf can not open GLTF files from filesystem. Either encode your GLB into a source file and create or build fastgltf with FASTGLTF_HAS_MEMORY_MAPPED_FILE set to '1' +#endif + + lv_fs_file_t file; + lv_fs_res_t res = lv_fs_open(&file, path, LV_FS_MODE_RD); + if(res != LV_FS_RES_OK) { + LV_LOG_ERROR("Failed to open file '%s': %d", path, res); + return NULL; + } + res = lv_fs_seek(&file, 0, LV_FS_SEEK_END); + if(res != LV_FS_RES_OK) { + LV_LOG_ERROR("Failed to seek end of file '%s': %d", path, res); + return NULL; + } + uint32_t file_size; + res = lv_fs_tell(&file, &file_size); + if(res != LV_FS_RES_OK) { + LV_LOG_ERROR("Failed to get file count size '%s': %d", path, res); + return NULL; + } + + res = lv_fs_seek(&file, 0, LV_FS_SEEK_SET); + if(res != LV_FS_RES_OK) { + LV_LOG_ERROR("Failed to seek start of file '%s': %d", path, res); + return NULL; + } + + uint8_t * bytes = (uint8_t *) lv_malloc(file_size); + + uint32_t bytes_read; + res = lv_fs_read(&file, bytes, file_size, &bytes_read); + if(res != LV_FS_RES_OK) { + LV_LOG_ERROR("Failed to seek start of file '%s': %d", path, res); + return NULL; + } + if(bytes_read != file_size) { + LV_LOG_ERROR("Failed to read the entire gltf file '%s': %d", path, res); + return NULL; + } + lv_fs_close(&file); + + lv_gltf_model_t * model = create_data_from_bytes(bytes, file_size); + lv_free(bytes); + + model->filename = path; + return model; +} + +static lv_gltf_model_t * create_data_from_bytes(const uint8_t * bytes, size_t data_size) +{ + fastgltf::Parser parser(SUPPORTED_EXTENSIONS); + auto gltf_buffer = fastgltf::GltfDataBuffer::FromBytes(reinterpret_cast(bytes), data_size); + if(!gltf_buffer) { + LV_LOG_ERROR("Failed to create glTF buffer from bytes: %s", + std::string(fastgltf::getErrorMessage(gltf_buffer.error())).c_str()); + return NULL; + } + auto asset = parser.loadGltf(gltf_buffer.get(), ".", GLTF_OPTIONS); + if(!asset) { + LV_LOG_ERROR("Failed to decode glTF bytes: %s", std::string(fastgltf::getErrorMessage(asset.error())).c_str()); + return NULL; + } + return lv_gltf_data_create_internal("from_bytes", std::move(asset.get())); +} + +static void make_small_magenta_texture(uint32_t new_magenta_tex) +{ + GL_CALL(glBindTexture(GL_TEXTURE_2D, new_magenta_tex)); + unsigned char clearBytes[4] = { 255, 0, 255, 255 }; // RGBA format + GL_CALL(glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 1, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE, clearBytes)); + // Set texture parameters (optional but recommended) + GL_CALL(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST)); + GL_CALL(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST)); + GL_CALL(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE)); + GL_CALL(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE)); + GL_CALL(glGenerateMipmap(GL_TEXTURE_2D)); + GL_CALL(glBindTexture(GL_TEXTURE_2D, 0)); + return; +} + +static void load_mesh_texture_impl(lv_gltf_model_t * data, const fastgltf::TextureInfo & material_prop, + GLuint * primitive_tex_prop, + GLint * primitive_tex_uv_id) +{ + const auto & texture = data->asset.textures[material_prop.textureIndex]; + if(!injest_check_any_image_index_valid(texture)) { + return; + } + *primitive_tex_prop = data->textures[injest_get_any_image_index(texture)]; + if(material_prop.transform && material_prop.transform->texCoordIndex.has_value()) { + *primitive_tex_uv_id = material_prop.transform->texCoordIndex.value(); + } + else { + *primitive_tex_uv_id = material_prop.texCoordIndex; + } + LV_LOG_TRACE("Prim tex prop: %d Prim tex uv id %d", *primitive_tex_prop, *primitive_tex_uv_id); +} + +static void load_mesh_texture(lv_gltf_model_t * data, + const fastgltf::Optional & material_prop, + GLuint * primitive_tex_prop, GLint * primitive_tex_uv_id) +{ + if(!material_prop) { + return; + } + load_mesh_texture_impl(data, material_prop.value(), primitive_tex_prop, primitive_tex_uv_id); +} + +static void load_mesh_texture(lv_gltf_model_t * data, const fastgltf::Optional & material_prop, + GLuint * primitive_tex_prop, GLint * primitive_tex_uv_id) +{ + if(!material_prop) { + return; + } + load_mesh_texture_impl(data, material_prop.value(), primitive_tex_prop, primitive_tex_uv_id); +} + +static void load_mesh_texture(lv_gltf_model_t * data, + const fastgltf::Optional & material_prop, + GLuint * primitive_tex_prop, GLint * primitive_tex_uv_id) +{ + if(!material_prop) { + return; + } + load_mesh_texture_impl(data, material_prop.value(), primitive_tex_prop, primitive_tex_uv_id); +} + +static int32_t injest_get_any_image_index(fastgltf::Optional tex) +{ + if(tex->imageIndex.has_value()) { + return tex->imageIndex.value(); + } + + if(tex->webpImageIndex.has_value()) { + return tex->webpImageIndex.value(); + } + return 0; +} +static bool injest_check_any_image_index_valid(fastgltf::Optional tex) +{ + if(tex->imageIndex.has_value()) + return true; + if(tex->webpImageIndex.has_value()) + return true; + return false; +} + +static void injest_grow_bounds_to_include(lv_gltf_model_t * data, const fastgltf::math::fmat4x4 & matrix, + const fastgltf::Mesh & mesh) +{ + /* Grow the bounds to include the specified mesh. */ + fastgltf::math::fvec3 v_min{ data->vertex_min[0], data->vertex_min[1], data->vertex_min[2] }; + + fastgltf::math::fvec3 v_max{ + data->vertex_max[0], + data->vertex_max[1], + data->vertex_max[2], + }; + fastgltf::math::fvec3 v_cen{ data->vertex_cen[0], data->vertex_cen[1], data->vertex_cen[2] }; + + float new_bound_radius = data->bound_radius; + if(mesh.primitives.size() > 0) { + set_bounds_info(data, v_min, v_max, v_cen, new_bound_radius); + return; + } + size_t accessor_index = mesh.primitives[0].findAttribute("POSITION")->accessorIndex; + const auto & accessor = data->asset.accessors[accessor_index]; + + if(!accessor.bufferViewIndex.has_value() || !(accessor.min.has_value() && accessor.max.has_value())) { + set_bounds_info(data, v_min, v_max, v_cen, new_bound_radius); + return; + } + + fastgltf::math::fvec4 t_min{ (float)(accessor.min.value().get(0)), (float)(accessor.min.value().get(1)), + (float)(accessor.min.value().get(2)), 1.f }; + fastgltf::math::fvec4 t_max{ (float)(accessor.max.value().get(0)), (float)(accessor.max.value().get(1)), + (float)(accessor.max.value().get(2)), 1.f }; + + t_min = matrix * t_min; + t_max = matrix * t_max; + v_max[0] = LV_MAX(LV_MAX(v_max[0], t_min.x()), t_max.x()); + v_max[1] = LV_MAX(LV_MAX(v_max[1], t_min.y()), t_max.y()); + v_max[2] = LV_MAX(LV_MAX(v_max[2], t_min.z()), t_max.z()); + v_min[0] = LV_MIN(LV_MIN(v_min[0], t_min.x()), t_max.x()); + v_min[1] = LV_MIN(LV_MIN(v_min[1], t_min.y()), t_max.y()); + v_min[2] = LV_MIN(LV_MIN(v_min[2], t_min.z()), t_max.z()); + v_cen[0] = (v_max[0] + v_min[0]) / 2.0f; + v_cen[1] = (v_max[1] + v_min[1]) / 2.0f; + v_cen[2] = (v_max[2] + v_min[2]) / 2.0f; + + float size_x = v_max[0] - v_min[0]; + float size_y = v_max[1] - v_min[1]; + float size_z = v_max[2] - v_min[2]; + new_bound_radius = std::sqrt((size_x * size_x) + (size_y * size_y) + (size_z * size_z)) / 2.0f; + + set_bounds_info(data, v_min, v_max, v_cen, new_bound_radius); +} +static void injest_set_initial_bounds(lv_gltf_model_t * data, const fastgltf::math::fmat4x4 & matrix, + const fastgltf::Mesh & mesh) +{ + fastgltf::math::fvec3 v_min, v_max, v_cen; + float radius = 0.f; + if(mesh.primitives.size() == 0) { + set_bounds_info(data, v_min, v_max, v_cen, radius); + return; + } + + size_t accessor_index = mesh.primitives[0].findAttribute("POSITION")->accessorIndex; + const auto & accessor = data->asset.accessors[accessor_index]; + + if(!accessor.bufferViewIndex.has_value() || !(accessor.min.has_value() && accessor.max.has_value())) { + set_bounds_info(data, v_min, v_max, v_cen, radius); + return; + } + + fastgltf::math::fvec4 t_min{ (float)(accessor.min.value().get(0)), (float)(accessor.min.value().get(1)), + (float)(accessor.min.value().get(2)), 1.f }; + + fastgltf::math::fvec4 t_max{ (float)(accessor.max.value().get(0)), (float)(accessor.max.value().get(1)), + (float)(accessor.max.value().get(2)), 1.f }; + + t_min = matrix * t_min; + t_max = matrix * t_max; + + v_max[0] = LV_MAX(t_min.x(), t_max.x()); + v_max[1] = LV_MAX(t_min.y(), t_max.y()); + v_max[2] = LV_MAX(t_min.z(), t_max.z()); + v_min[0] = LV_MIN(t_min.x(), t_max.x()); + v_min[1] = LV_MIN(t_min.y(), t_max.y()); + v_min[2] = LV_MIN(t_min.z(), t_max.z()); + v_cen[0] = (v_max[0] + v_min[0]) / 2.0f; + v_cen[1] = (v_max[1] + v_min[1]) / 2.0f; + v_cen[2] = (v_max[2] + v_min[2]) / 2.0f; + const float size_x = v_max[0] - v_min[0]; + const float size_y = v_max[1] - v_min[1]; + const float size_z = v_max[2] - v_min[2]; + radius = std::sqrt((size_x * size_x) + (size_y * size_y) + (size_z * size_z)) / 2.0f; + + set_bounds_info(data, v_min, v_max, v_cen, radius); +} + +bool injest_image(lv_opengl_shader_manager_t * shader_manager, lv_gltf_model_t * data, fastgltf::Image & image, + uint32_t index) +{ + std::string _tex_id = std::string(lv_gltf_get_filename(data)) + "_IMG" + std::to_string(index); + + char tmp[512]; + lv_snprintf(tmp, sizeof(tmp), "%s_img_%u", data->filename, index); + const uint32_t hash = lv_opengl_shader_hash(tmp); + GLuint texture_id = lv_opengl_shader_manager_get_texture(shader_manager, hash); + + if(texture_id != GL_NONE) { + LV_LOG_TRACE("Emplacing back already cached texture from previous injest iteration %u", texture_id); + data->textures.emplace_back(texture_id); + return true; + } + + LV_LOG_TRACE("Image (%s) [%d] [%u]", image.name.c_str(), texture_id, hash); + glGenTextures(1, &texture_id); + glBindTexture(GL_TEXTURE_2D, texture_id); + + GL_CALL(glPixelStorei(GL_UNPACK_ALIGNMENT, 1)); + bool image_invalidated = false; + std::visit(fastgltf::visitor{ + [](auto & arg) + { + LV_UNUSED(arg); + LV_LOG_ERROR("Unexpected image source"); + }, + [&](fastgltf::sources::URI & file_path) + { + LV_ASSERT_MSG(file_path.fileByteOffset == 0, "Offsets aren't supported with stbi"); + LV_ASSERT_MSG(file_path.uri.isLocalPath(), "We're only capable of loading local files."); + + int32_t width, height, nrChannels; + LV_LOG_TRACE("Loading image: %s", image.name.c_str()); + const std::string path(file_path.uri.path().begin(), file_path.uri.path().end()); + unsigned char * data = stbi_load(path.c_str(), &width, &height, &nrChannels, 4); + glTexStorage2D(GL_TEXTURE_2D, get_level_count(width, height), GL_RGBA8, width, height); + glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, width, height, GL_RGBA, GL_UNSIGNED_BYTE, data); + stbi_image_free(data); + }, + [&](fastgltf::sources::Array & vector) + { + int32_t width, height, nrChannels; + LV_LOG_TRACE("Unpacking image data: %s", image.name.c_str()); + + unsigned char * data = stbi_load_from_memory( + reinterpret_cast(vector.bytes.data()), + static_cast(vector.bytes.size()), &width, &height, &nrChannels, 4); + glTexStorage2D(GL_TEXTURE_2D, get_level_count(width, height), GL_RGBA8, width, height); + glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, width, height, GL_RGBA, GL_UNSIGNED_BYTE, data); + stbi_image_free(data); + }, + [&](fastgltf::sources::BufferView & view) + { + LV_LOG_TRACE("Injesting image from bufferview: %s", image.name.c_str()); + image_invalidated |= injest_image_from_buffer_view(data, view, texture_id); + }, + }, image.data); + + if(!image_invalidated) { + glGenerateMipmap(GL_TEXTURE_2D); + } + else { + LV_LOG_ERROR("Failed to load image %s", image.name.c_str()); + } + LV_LOG_TRACE("Storing texture with hash: %u %u", hash, texture_id); + lv_opengl_shader_manager_store_texture(shader_manager, hash, texture_id); + GL_CALL(glBindTexture(GL_TEXTURE_2D, 0)); + data->textures.emplace_back(texture_id); + return true; +} + +static bool injest_image_from_buffer_view(lv_gltf_model_t * data, fastgltf::sources::BufferView & view, + GLuint texture_id) +{ + /* Yes, we've already loaded every buffer into some GL buffer. However, with GL it's simpler + to just copy the buffer data again for the texture. Besides, this is just an example. */ + auto & buffer_view = data->asset.bufferViews[view.bufferViewIndex]; + auto & buffer = data->asset.buffers[buffer_view.bufferIndex]; + LV_LOG_INFO("Unpacking image bufferView: %s from %d bytes", image.name, bufferView.byteLenght); + return std::visit( + fastgltf::visitor{ + // We only care about VectorWithMime here, because we specify LoadExternalBuffers, meaning + // all buffers are already loaded into a vector. + [](auto & arg) + { + LV_UNUSED(arg); + LV_LOG_ERROR("Unexpected image source"); + return false; + }, + [&](fastgltf::sources::Array & vector) + { + LV_LOG_TRACE("[WEBP] width: %d height: %d", width, height); + int32_t width, height, nrChannels; + int32_t webpRes = WebPGetInfo( + reinterpret_cast(vector.bytes.data() + buffer_view.byteOffset), + static_cast(buffer_view.byteLength), &width, &height); + + if(!webpRes) { + unsigned char * data = stbi_load_from_memory( + reinterpret_cast(vector.bytes.data() + buffer_view.byteOffset), + static_cast(buffer_view.byteLength), &width, &height, &nrChannels, 4); + if((width <= 0) || (height <= 0)) { + LV_LOG_ERROR("Failed to load image from memory"); + make_small_magenta_texture(texture_id); + return true; + } + LV_LOG_TRACE("[WEBP] width: %d height: %d", width, height); + glTexStorage2D(GL_TEXTURE_2D, get_level_count(width, height), GL_RGBA8, width, height); + glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, width, height, GL_RGBA, GL_UNSIGNED_BYTE, data); + stbi_image_free(data); + return false; + } + WebPBitstreamFeatures features = WebPBitstreamFeatures(); + auto status_code = WebPGetFeatures( + reinterpret_cast(vector.bytes.data() + buffer_view.byteOffset), + static_cast(buffer_view.byteLength), &features); + if(status_code != VP8_STATUS_OK) { + LV_LOG_ERROR("Failed to load webp image %d", status_code); + make_small_magenta_texture(texture_id); + return true; + } + if(features.has_alpha) { + uint8_t * unpacked = WebPDecodeRGBA( + reinterpret_cast(vector.bytes.data() + buffer_view.byteOffset), + static_cast(buffer_view.byteLength), &width, &height); + glTexStorage2D(GL_TEXTURE_2D, get_level_count(width, height), GL_RGBA8, width, height); + glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, width, height, GL_RGBA, GL_UNSIGNED_BYTE, + unpacked); + WebPFree(unpacked); + } + else { + uint8_t * unpacked = WebPDecodeRGB( + reinterpret_cast(vector.bytes.data() + buffer_view.byteOffset), + static_cast(buffer_view.byteLength), &width, &height); + glTexStorage2D(GL_TEXTURE_2D, get_level_count(width, height), GL_RGB8, width, height); + glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, width, height, GL_RGB, GL_UNSIGNED_BYTE, + unpacked); + WebPFree(unpacked); + } + return false; + } }, + buffer.data); +} +static void injest_light(lv_gltf_model_t * data, size_t light_index, fastgltf::Light & light, size_t scene_index) +{ + fastgltf::math::fmat4x4 tmat; + // It would seem like we'd need this info but not really, just the index will do at the loading phase, the rest is pulled during frame updates. + LV_UNUSED(light); + + fastgltf::findlight_iterate_scene_nodes(data->asset, scene_index, &tmat, + [&](fastgltf::Node & node, const fastgltf::math::fmat4x4 & parentworldmatrix, + const fastgltf::math::fmat4x4 & localmatrix) { + LV_UNUSED(parentworldmatrix); + LV_UNUSED(localmatrix); + if(!node.lightIndex.has_value() || + node.lightIndex.value() != light_index) { + return; + } + LV_LOG_INFO("SCENE LIGHT BEING ADDED #%d\n", light_index); + data->node_by_light_index.push_back(&node); + }); +} + +static bool injest_mesh(lv_gltf_model_t * data, fastgltf::Mesh & mesh) +{ + /*const auto &asset = GET_ASSET(data);*/ + const auto & outMesh = lv_gltf_get_new_meshdata(data); + outMesh->primitives.resize(mesh.primitives.size()); + + for(auto it = mesh.primitives.begin(); it != mesh.primitives.end(); ++it) { + if(it->dracoCompression) { + LV_LOG_WARN("Unhandled draco compression"); + } + auto * positionIt = it->findAttribute("POSITION"); + // A mesh primitive is required to hold the POSITION attribute. + // + assert(positionIt != it->attributes.end()); + assert(it->indicesAccessor.has_value()); // We specify GenerateMeshIndices, so we should always have indices + + auto index = std::distance(mesh.primitives.begin(), it); + auto & primitive = outMesh->primitives[index]; + + // Generate the VAO + GLuint vao; + glGenVertexArrays(1, &vao); + glBindVertexArray(vao); + primitive.primitiveType = fastgltf::to_underlying(it->type); + primitive.vertexArray = vao; + + if(it->materialIndex.has_value()) { + // Adjust for default material + primitive.materialUniformsIndex = it->materialIndex.value() + 1; + auto & material = data->asset.materials[it->materialIndex.value()]; + load_mesh_texture(data, material.pbrData.baseColorTexture, &primitive.albedoTexture, + &primitive.baseColorTexcoordIndex); + + load_mesh_texture(data, material.pbrData.metallicRoughnessTexture, &primitive.metalRoughTexture, + &primitive.metallicRoughnessTexcoordIndex); + load_mesh_texture(data, material.normalTexture, &primitive.normalTexture, &primitive.normalTexcoordIndex); + load_mesh_texture(data, material.occlusionTexture, &primitive.occlusionTexture, + &primitive.occlusionTexcoordIndex); + load_mesh_texture(data, material.emissiveTexture, &primitive.emissiveTexture, + &primitive.emissiveTexcoordIndex); + if(material.volume) + load_mesh_texture(data, material.volume->thicknessTexture, &primitive.thicknessTexture, + &primitive.thicknessTexcoordIndex); + if(material.transmission) + load_mesh_texture(data, material.transmission->transmissionTexture, + &primitive.transmissionTexture, (GLint *)&primitive.transmissionTexcoordIndex); + if(material.clearcoat) { + load_mesh_texture(data, material.clearcoat->clearcoatTexture, + (GLuint *)&primitive.clearcoatTexture, &primitive.clearcoatTexcoordIndex); + load_mesh_texture(data, material.clearcoat->clearcoatRoughnessTexture, + (GLuint *)&primitive.clearcoatRoughnessTexture, + &primitive.clearcoatRoughnessTexcoordIndex); + load_mesh_texture(data, material.clearcoat->clearcoatNormalTexture, + (GLuint *)&primitive.clearcoatNormalTexture, + &primitive.clearcoatNormalTexcoordIndex); + } + if(material.diffuseTransmission) { + load_mesh_texture(data, material.diffuseTransmission->diffuseTransmissionTexture, + &primitive.diffuseTransmissionTexture, + &primitive.diffuseTransmissionTexcoordIndex); + load_mesh_texture(data, material.diffuseTransmission->diffuseTransmissionColorTexture, + &primitive.diffuseTransmissionColorTexture, + &primitive.diffuseTransmissionColorTexcoordIndex); + } + } + else { + primitive.materialUniformsIndex = 0; + } + + auto & positionAccessor = data->asset.accessors[positionIt->accessorIndex]; + if(!positionAccessor.bufferViewIndex.has_value()) { + continue; + } + + // Create the vertex buffer for this primitive, and use the accessor tools to copy directly into the mapped buffer. + GL_CALL(glGenBuffers(1, &primitive.vertexBuffer)); + GL_CALL(glBindBuffer(GL_ARRAY_BUFFER, primitive.vertexBuffer)); + + std::vector vertices_vec(positionAccessor.count); + vertex_t * vertices = vertices_vec.data(); + glBufferData(GL_ARRAY_BUFFER, positionAccessor.count * sizeof(*vertices), nullptr, GL_STATIC_DRAW); + { + int32_t attr_index = 0; + attr_index = injest_vec_attribute( + 3, attr_index, data, &(*it), "POSITION", primitive.vertexBuffer, offsetof(vertex_t, position), + [&](fastgltf::math::fvec3 vec, size_t idx) { + vertices[idx].position = vec; + }); + attr_index = injest_vec_attribute( + 4, attr_index, data, &(*it), "JOINTS_0", primitive.vertexBuffer, offsetof(vertex_t, joints), + [&](fastgltf::math::fvec4 vec, size_t idx) { + vertices[idx].joints = vec; + }); + attr_index = injest_vec_attribute( + 4, attr_index, data, &(*it), "JOINTS_1", primitive.vertexBuffer, offsetof(vertex_t, joints2), + [&](fastgltf::math::fvec4 vec, std::size_t idx) { + vertices[idx].joints2 = vec; + }); + attr_index = injest_vec_attribute( + 4, attr_index, data, &(*it), "WEIGHTS_0", primitive.vertexBuffer, offsetof(vertex_t, weights), + [&](fastgltf::math::fvec4 vec, std::size_t idx) { + vertices[idx].weights = vec; + }); + attr_index = injest_vec_attribute( + 4, attr_index, data, &(*it), "WEIGHTS_1", primitive.vertexBuffer, offsetof(vertex_t, weights2), + [&](fastgltf::math::fvec4 vec, size_t idx) { + vertices[idx].weights2 = vec; + }); + attr_index = injest_vec_attribute( + 3, attr_index, data, &(*it), "NORMAL", primitive.vertexBuffer, offsetof(vertex_t, normal), + [&](fastgltf::math::fvec3 vec, std::size_t idx) { + vertices[idx].normal = vec; + }); + attr_index = injest_vec_attribute( + 4, attr_index, data, &(*it), "TANGENT", primitive.vertexBuffer, offsetof(vertex_t, tangent), + [&](fastgltf::math::fvec4 vec, size_t idx) { + vertices[idx].tangent = vec; + }); + attr_index = injest_vec_attribute( + 2, attr_index, data, &(*it), "TEXCOORD_0", primitive.vertexBuffer, offsetof(vertex_t, uv), + [&](fastgltf::math::fvec2 vec, size_t idx) { + vertices[idx].uv = vec; + }); + attr_index = injest_vec_attribute( + 2, attr_index, data, &(*it), "TEXCOORD_1", primitive.vertexBuffer, offsetof(vertex_t, uv2), + [&](fastgltf::math::fvec2 vec, size_t idx) { + vertices[idx].uv2 = vec; + }); + } + glBindVertexArray(vao); + glBindBuffer(GL_ARRAY_BUFFER, primitive.vertexBuffer); + glBufferData(GL_ARRAY_BUFFER, positionAccessor.count * sizeof(vertex_t), vertices_vec.data(), GL_STATIC_DRAW); + + // Generate the indirect draw command + auto & draw = primitive.draw; + draw.instanceCount = 1; + draw.baseInstance = 0; + draw.baseVertex = 0; + draw.firstIndex = 0; + + auto & indexAccessor = data->asset.accessors[it->indicesAccessor.value()]; + if(!indexAccessor.bufferViewIndex.has_value()) + return false; + draw.count = static_cast(indexAccessor.count); + + // Create the index buffer and copy the indices into it. + glGenBuffers(1, &primitive.indexBuffer); + glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, primitive.indexBuffer); + if(indexAccessor.componentType == fastgltf::ComponentType::UnsignedByte || + indexAccessor.componentType == fastgltf::ComponentType::UnsignedShort) { + primitive.indexType = GL_UNSIGNED_SHORT; + std::uint16_t * tempIndices = new std::uint16_t[indexAccessor.count]; + fastgltf::copyFromAccessor(data->asset, indexAccessor, tempIndices); + glBufferData(GL_ELEMENT_ARRAY_BUFFER, + static_cast(indexAccessor.count * sizeof(std::uint16_t)), tempIndices, + GL_STATIC_DRAW); + delete[] tempIndices; + } + else { + primitive.indexType = GL_UNSIGNED_INT; + //std::uint32_t tempIndices[indexAccessor.count]; + std::uint32_t * tempIndices = new std::uint32_t[indexAccessor.count]; + fastgltf::copyFromAccessor(data->asset, indexAccessor, tempIndices); + glBufferData(GL_ELEMENT_ARRAY_BUFFER, + static_cast(indexAccessor.count * sizeof(std::uint32_t)), tempIndices, + GL_STATIC_DRAW); + delete[] tempIndices; + } + } + + glBindVertexArray(0); + return true; +} +template +static size_t injest_vec_attribute(uint8_t vec_size, int32_t current_attrib_index, lv_gltf_model_t * data, + const fastgltf::Primitive * prim, const char * attrib_id, GLuint primitive_vertex_buffer, + size_t offset, Func &&functor + + ) +{ + const auto & asset = data->asset; + if(const auto * _attrib = prim->findAttribute(std::string(attrib_id)); _attrib != prim->attributes.end()) { + auto & accessor = asset.accessors[_attrib->accessorIndex]; + if(accessor.bufferViewIndex.has_value()) { + glBindBuffer(GL_ARRAY_BUFFER, primitive_vertex_buffer); + fastgltf::iterateAccessorWithIndex(asset, accessor, functor); + // Specify the layout of the vertex data + glVertexAttribPointer(current_attrib_index, // Attribute index + vec_size, // Number of components per vertex + GL_FLOAT, // Data type + GL_FALSE, // Normalized + sizeof(vertex_t), // Stride (size of one vertex) + (void *)offset); // Offset in the buffer + glEnableVertexAttribArray(current_attrib_index); + } + else { + glDisableVertexAttribArray(current_attrib_index); + } + current_attrib_index++; + } + return current_attrib_index; +} + +static void set_bounds_info(lv_gltf_model_t * data, fastgltf::math::fvec3 v_min, fastgltf::math::fvec3 v_max, + fastgltf::math::fvec3 v_cen, float radius) +{ + { + auto _d = v_min.data(); + data->vertex_min[0] = _d[0]; + data->vertex_min[1] = _d[1]; + data->vertex_min[2] = _d[2]; + } + { + auto _d = v_max.data(); + data->vertex_max[0] = _d[0]; + data->vertex_max[1] = _d[1]; + data->vertex_max[2] = _d[2]; + } + { + auto _d = v_cen.data(); + data->vertex_cen[0] = _d[0]; + data->vertex_cen[1] = _d[1]; + data->vertex_cen[2] = _d[2]; + } + data->bound_radius = radius; +} + +#endif /*LV_USE_GLTF*/ diff --git a/src/libs/gltf/gltf_data/lv_gltf_data_internal.h b/src/libs/gltf/gltf_data/lv_gltf_data_internal.h new file mode 100644 index 0000000000..f8615a2320 --- /dev/null +++ b/src/libs/gltf/gltf_data/lv_gltf_data_internal.h @@ -0,0 +1,252 @@ +#ifndef LV_GLTFDATA_PRIVATE_H +#define LV_GLTFDATA_PRIVATE_H + +#include "../../../lv_conf_internal.h" +#if LV_USE_GLTF +#include "../../../drivers/opengles/opengl_shader/lv_opengl_shader_internal.h" +#include "../../../draw/lv_image_dsc.h" +#include "../../../misc/lv_types.h" + +typedef struct { + GLuint count; + GLuint instanceCount; + GLuint firstIndex; + GLint baseVertex; + GLuint baseInstance; +} IndirectDrawCommand; + +typedef struct { + IndirectDrawCommand draw; + GLenum primitiveType; + GLenum indexType; + GLuint vertexArray; + + GLuint vertexBuffer; + GLuint indexBuffer; + + GLuint materialUniformsIndex; + GLuint albedoTexture; + GLuint emissiveTexture; + GLuint metalRoughTexture; + GLuint occlusionTexture; + GLuint normalTexture; + GLuint diffuseTransmissionTexture; + GLuint diffuseTransmissionColorTexture; + GLuint transmissionTexture; + GLuint transmissionTexcoordIndex; + + GLint baseColorTexcoordIndex; + GLint emissiveTexcoordIndex; + + GLint metallicRoughnessTexcoordIndex; + GLint occlusionTexcoordIndex; + GLint normalTexcoordIndex; + GLint diffuseTransmissionTexcoordIndex; + GLint diffuseTransmissionColorTexcoordIndex; + + GLint clearcoatTexture; + GLint clearcoatRoughnessTexture; + GLint clearcoatNormalTexture; + GLint clearcoatTexcoordIndex; + GLint clearcoatRoughnessTexcoordIndex; + GLint clearcoatNormalTexcoordIndex; + + GLuint thicknessTexture; + GLint thicknessTexcoordIndex; + + GLuint diffuseTexture; + GLint diffuseTexcoordIndex; + + GLuint specularGlossinessTexture; + GLint specularGlossinessTexcoordIndex; + +} lv_gltf_primitive_t; + +typedef struct { + GLint camera; + GLint view_projection_matrix; + GLint model_matrix; + GLint view_matrix; + GLint projection_matrix; + + GLint env_intensity; + GLint env_diffuse_sampler; + GLint env_specular_sampler; + GLint env_sheen_sampler; + GLint env_ggx_lut_sampler; + GLint env_charlie_lut_sampler; + GLint env_mip_count; + + GLint exposure; + GLint roughness_factor; + + GLint base_color_factor; + GLint base_color_sampler; + GLint base_color_uv_set; + GLint base_color_uv_transform; + + GLint emissive_factor; + GLint emissive_sampler; + GLint emissive_uv_set; + GLint emissive_uv_transform; + GLint emissive_strength; + + GLint metallic_factor; + GLint metallic_roughness_sampler; + GLint metallic_roughness_uv_set; + GLint metallic_roughness_uv_transform; + + GLint occlusion_strength; + GLint occlusion_sampler; + GLint occlusion_uv_set; + GLint occlusion_uv_transform; + + GLint normal_scale; + GLint normal_sampler; + GLint normal_uv_set; + GLint normal_uv_transform; + + GLint clearcoat_factor; + GLint clearcoat_roughness_factor; + GLint clearcoat_sampler; + GLint clearcoat_uv_set; + GLint clearcoat_uv_transform; + GLint clearcoat_roughness_sampler; + GLint clearcoat_roughness_uv_set; + GLint clearcoat_roughness_uv_transform; + GLint clearcoat_normal_scale; + GLint clearcoat_normal_sampler; + GLint clearcoat_normal_uv_set; + GLint clearcoat_normal_uv_transform; + + GLint thickness; + GLint thickness_sampler; + GLint thickness_uv_set; + GLint thickness_uv_transform; + + GLint diffuse_transmission_sampler; + GLint diffuse_transmission_uv_set; + GLint diffuse_transmission_uv_transform; + + GLint diffuse_transmission_color_sampler; + GLint diffuse_transmission_color_uv_set; + GLint diffuse_transmission_color_uv_transform; + + GLint sheen_color_factor; + GLint sheen_roughness_factor; + + GLint specular_color_factor; + GLint specular_factor; + + GLint diffuse_transmission_color_factor; + GLint diffuse_transmission_factor; + + GLint ior; + GLint alpha_cutoff; + + GLint dispersion; + GLint screen_size; + GLint transmission_factor; + GLint transmission_sampler; + GLint transmission_uv_set; + GLint transmission_uv_transform; + GLint transmission_framebuffer_sampler; + GLint transmission_framebuffer_size; + + GLint attenuation_distance; + GLint attenuation_color; + + GLint joints_sampler; + + GLint diffuse_factor; + GLint glossiness_factor; + + GLint diffuse_sampler; + GLint diffuse_uv_set; + GLint diffuse_uv_transform; + GLint specular_glossiness_sampler; + GLint specular_glossiness_uv_set; + GLint specular_glossiness_uv_transform; + +} lv_gltf_uniform_locations_t; + +lv_gltf_uniform_locations_t lv_gltf_uniform_locations_create(GLuint program); + +typedef struct { + GLuint program; + uint32_t bg_program; + uint32_t vert; + uint32_t frag; +} lv_gltf_shaderset_t; + +typedef struct { + lv_gltf_uniform_locations_t uniforms; + lv_gltf_shaderset_t shaderset; +} lv_gltf_compiled_shader_t; + +void lv_gltf_store_compiled_shader(lv_gltf_model_t * data, size_t identifier, lv_gltf_compiled_shader_t * shader); +lv_gltf_compiled_shader_t * lv_gltf_get_compiled_shader(lv_gltf_model_t * data, size_t identifier); + +/** + * @brief Load the gltf file at the specified filepath + * + * @param gltf_path The gltf filename + * @param ret_data Pointer to the data container that will be populated. + * @param shaders Pointer to the shader cache object this file uses. + */ +lv_gltf_model_t * +lv_gltf_data_load_from_file(const char * file_path, + lv_opengl_shader_manager_t * shader_manager); + +/** + * @brief Load the gltf file encoded within the supplied byte array + * + * @param gltf_path The gltf filename + * @param gltf_data_size if gltf_path is instead a byte array, pass the size of that array in through this variable (or 0 if it's a file path). + * @param ret_data Pointer to the data container that will be populated. + * @param shaders Pointer to the shader cache object this file uses. + */ + +lv_gltf_model_t * +lv_gltf_data_load_from_bytes(const uint8_t * data, size_t data_size, + lv_opengl_shader_manager_t * shader_manager); + + +/** + * @brief Retrieve the radius of the GLTF data object. + * + * @param D Pointer to the lv_gltf_data_t object from which to get the radius. + * @return The radius of the GLTF data object. + */ +double lv_gltf_data_get_radius(lv_gltf_model_t * D); + + +/** + * @brief Destroy a GLTF data object and free associated resources. + * + * @param _data Pointer to the lv_gltf_data_t object to be destroyed. + */ +void lv_gltf_data_destroy(lv_gltf_model_t * _data); + +/** + * @brief Copy the bounds information from one GLTF data object to another. + * + * @param to Pointer to the destination lv_gltf_data_t object. + * @param from Pointer to the source lv_gltf_data_t object. + */ +void lv_gltf_data_copy_bounds_info(lv_gltf_model_t * to, lv_gltf_model_t * from); + +/** + * @brief Swap the red and blue channels in a pixel buffer. + * + * @param pixel_buffer Pointer to the pixel buffer containing the image data. + * @param byte_total_count The total number of bytes in the pixel buffer. + * @param has_alpha Flag indicating whether the pixel buffer includes an alpha channel. + */ +void lv_gltf_data_rgb_to_bgr(uint8_t * pixel_buffer, + size_t byte_total_count, + bool has_alpha); + + +#endif /*LV_USE_GLTF*/ +#endif /* LV_GLTFDATA_PRIVATE_H */ diff --git a/src/libs/gltf/gltf_data/lv_gltf_data_internal.hpp b/src/libs/gltf/gltf_data/lv_gltf_data_internal.hpp new file mode 100644 index 0000000000..c254aafd42 --- /dev/null +++ b/src/libs/gltf/gltf_data/lv_gltf_data_internal.hpp @@ -0,0 +1,373 @@ +#ifndef LV_GLTFDATA_HPP +#define LV_GLTFDATA_HPP + +#include "../../../lv_conf_internal.h" + +#if LV_USE_GLTF + +#include +#include "lv_gltf_data_internal.h" +#include "lv_gltf_bind.h" + +#include "../../../misc/lv_array.h" +#include "../../../drivers/opengles/lv_opengles_private.h" + +#ifdef __cplusplus + +#include +#include +#include +#include + +// Vector of int32_t's +using UintVector = std::vector; +// Vector of int32_t's +using IntVector = std::vector; +// Vector of int64_t's +using LongVector = std::vector; +// Pointer to fastgltf::Node +using NodePtr = fastgltf::Node *; +// A standard 4x4 transform matrix +using Transform = fastgltf::math::fmat4x4; +// Pair of Node pointer and int32_t +using NodeIndexPair = std::pair; +// Pair of float and Node/Index pair +using NodeIndexDistancePair = std::pair; +// Vector of NodeIndexPair +using NodePairVector = std::vector; +// Vector of NodeIndexDistancePair +using NodeDistanceVector = std::vector; +// Map of uint32_t to NodePairVector +using MaterialIndexMap = std::map; +// Map of Node Pointers to Transforms +using NodeTransformMap = std::map; +// Map of Nodes by string (name) +using StringNodeMap = std::map; +// Map of Nodes by string (name) +using NodeIntMap = std::map; +// Map of Nodes by string (name) +using NodeVector = std::vector; +// Map of Node Index to Map of Prim Index to CenterXYZ+RadiusW Vec4 +using NodePrimCenterMap = std::map >; +// Map of Overrides by Node +using NodeOverrideMap = std::map; +// Map of Overrides by Node +using OverrideVector = std::vector; + +typedef struct { + GLuint drawsBuffer; + std::vector primitives; +} lv_gltf_mesh_data_t; + +typedef struct { + const char *ip; + const char *path; + fastgltf::Node *node; +} lv_gltf_data_node_t; + + +struct _lv_gltf_model_t { + const char *filename; + fastgltf::Asset asset; + lv_array_t nodes; + NodeVector node_by_light_index; + NodeTransformMap node_transform_cache; + MaterialIndexMap opaque_nodes_by_material_index; + MaterialIndexMap blended_nodes_by_material_index; + NodeOverrideMap node_binds; + lv_array_t binds; + std::vector validated_skins; + std::vector skin_tex; + NodePrimCenterMap local_mesh_to_center_points_by_primitive; + lv_gltf_t* viewer; + + std::vector meshes; + std::vector textures; + lv_array_t compiled_shaders; + std::map > channel_set_cache; + fastgltf::math::fmat4x4 view_mat; + fastgltf::math::fvec3 view_pos; + fastgltf::math::fvec3 vertex_max; + fastgltf::math::fvec3 vertex_min; + fastgltf::math::fvec3 vertex_cen; + + lv_timer_t* animation_update_timer; + + size_t current_animation; + size_t last_material_index; + + uint32_t last_camera_index; + int32_t last_anim_num; + + float bound_radius; + + uint32_t current_animation_max_time; + uint32_t local_timestamp; + uint32_t last_tick; + uint32_t camera; + + bool is_animation_enabled; + bool last_pass_was_transmission; + bool last_frame_was_antialiased; + bool last_frame_no_motion; + bool _last_frame_no_motion; + struct _lv_gltf_model_t *linked_view_source; +}; + +/** + * @brief Retrieve a specific texture from the GLTF model data. + * + * @param data Pointer to the lv_gltf_data_t object containing the model data. + * @param index The index of the texture to retrieve. + * @return Pointer to the texture object. + */ +GLuint lv_gltf_data_get_texture(lv_gltf_model_t *data, size_t index); + + +/** + * @brief Retrieve the minimum bounds (X/Y/Z) of the model from the GLTF data. + * + * @param data Pointer to the lv_gltf_data_t object containing the model data. + * @return Pointer to a 3-element float array representing the minimum bounds. + */ +fastgltf::math::fvec3 lv_gltf_data_get_bounds_min(const lv_gltf_model_t *data); + +/** + * @brief Retrieve the maximum bounds (X/Y/Z) of the model from the GLTF data. + * + * @param D Pointer to the lv_gltf_data_t object containing the model data. + * @return Pointer to a 3-element float array representing the maximum bounds. + */ +fastgltf::math::fvec3 lv_gltf_data_get_bounds_max(const lv_gltf_model_t *data); + +/** + * @brief Retrieve the center coordinates of the GLTF data object. + * + * @param D Pointer to the lv_gltf_data_t object from which to get the center. + * @return Pointer to an array containing the center coordinates (x, y, z). + */ +fastgltf::math::fvec3 lv_gltf_data_get_center(const lv_gltf_model_t *data); + +/** + * @brief Retrieve the filename of the GLTF model. + * + * @param D Pointer to the lv_gltf_data_t object containing the model data. + * @return Pointer to a constant character string representing the filename. + */ +const char *lv_gltf_get_filename(const lv_gltf_model_t *data); + +/** + * @brief Check if the centerpoint cache contains a specific entry. + * + * @param data Pointer to the lv_gltf_data_t object containing the model data. + * @param index The index of the entry to check. + * @param element The specific parameter to check within the cache. + * @return True if the cache contains the entry, false otherwise. + */ +bool lv_gltf_data_centerpoint_cache_contains(lv_gltf_model_t *data, size_t index, int32_t element); + +/** + * @brief Retrieve a specific primitive from a mesh. + * + * @param M Pointer to the MeshData structure containing the mesh data. + * @param I The index of the primitive to retrieve. + * @return Pointer to the primitive data. + */ +lv_gltf_primitive_t *lv_gltf_data_get_primitive_from_mesh(lv_gltf_mesh_data_t *M, size_t I); + +/** + * @brief Retrieve the asset associated with the GLTF model data. + * + * @param D Pointer to the lv_gltf_data_t object containing the model data. + * @return Pointer to the asset data. + */ +fastgltf::Asset *lv_gltf_data_get_asset(lv_gltf_model_t *data); + +/** + * @brief Retrieve mesh data for a specific index from the GLTF model data. + * + * @param D Pointer to the lv_gltf_data_t object containing the model data. + * @param I The index of the mesh data to retrieve. + * @return Pointer to the MeshData structure containing the mesh data. + */ +lv_gltf_mesh_data_t *lv_gltf_data_get_mesh(lv_gltf_model_t *data, size_t index); + +/** + * @brief Retrieve the skin texture index for a specific entry in the GLTF model data. + * + * @param data Pointer to the lv_gltf_data_t object containing the model data. + * @param index The index of the entry for which to retrieve the skin texture index. + * @return The skin texture index. + */ +GLuint lv_gltf_data_get_skin_texture_at(lv_gltf_model_t *data, size_t index); + +/** + * @brief Check if the validated skins contain a specific entry. + * + * @param data Pointer to the lv_gltf_data_t object containing the model data. + * @param index The index of the skin to check. + * @return True if the validated skins contain the entry, false otherwise. + */ +bool lv_gltf_data_validated_skins_contains(lv_gltf_model_t *data, size_t index); + +/** + * @brief Validate a specific skin in the GLTF model data. + * + * @param data Pointer to the lv_gltf_data_t object containing the model data. + * @param index The index of the skin to validate. + */ +void lv_gltf_data_validate_skin(lv_gltf_model_t *data, size_t index); + +/** + * @brief Add an opaque node primitive to the GLTF model data. + * + * @param D Pointer to the lv_gltf_data_t object containing the model data. + * @param I The index of the primitive to add. + * @param N Pointer to the NodePtr representing the node to add. + * @param P The specific parameter associated with the primitive. + */ +void lv_gltf_data_add_opaque_node_primitive(lv_gltf_model_t *data, size_t index, fastgltf::Node *node, size_t primitive_index); + +/** + * @brief Add a blended node primitive to the GLTF model data. + * + * @param D Pointer to the lv_gltf_data_t object containing the model data. + * @param I The index of the primitive to add. + * @param N Pointer to the NodePtr representing the node to add. + * @param P The specific parameter associated with the primitive. + */ +void lv_gltf_data_add_blended_node_primitive(lv_gltf_model_t *data, size_t mesh_index, fastgltf::Node *node, + size_t primitive_index); + +/** + * @brief Set the cached transformation matrix for a specific node in the GLTF model data. + * + * @param D Pointer to the lv_gltf_data_t object containing the model data. + * @param N Pointer to the NodePtr representing the node for which to set the transformation. + * @param M The transformation matrix to cache. + */ +void lv_gltf_data_set_cached_transform(lv_gltf_model_t* data, fastgltf::Node* node, fastgltf::math::fmat4x4 M); + +/** + * @brief Clear the transformation cache for the GLTF model data. + * + * @param D Pointer to the lv_gltf_data_t object containing the model data. + */ +void lv_gltf_data_clear_transform_cache(lv_gltf_model_t* data); + +/** + * @brief Retrieve the cached transformation matrix for a specific node in the GLTF model data. + * + * @param D Pointer to the lv_gltf_data_t object containing the model data. + * @param N Pointer to the NodePtr representing the node for which to retrieve the transformation. + * @return The cached transformation matrix. + */ +fastgltf::math::fmat4x4 lv_gltf_data_get_cached_transform(lv_gltf_model_t* data, fastgltf::Node* node); + +/** + * @brief Check if a cached transformation matrix exists for a given node. + * + * @param D Pointer to the lv_gltf_data_t object containing the model data. + * @param N Pointer to the NodePtr representing the node for which to retrieve the transformation. + * @return true if a cache item exists, false otherwise + int32_t*/ +bool lv_gltf_data_has_cached_transform(lv_gltf_model_t* data, fastgltf::Node* node); + +/** + * @brief Check if the transformation cache is empty. + * + * @param D Pointer to the lv_gltf_data_t object containing the model data. + * @return True if the transformation cache is empty, false otherwise. + */ +bool lv_gltf_data_transform_cache_is_empty(lv_gltf_model_t* data); + +/** + * @brief Retrieve the size of the skins in the GLTF model data. + * + * @param D Pointer to the lv_gltf_data_t object containing the model data. + * @return The size of the skins. + */ +size_t lv_gltf_data_get_skins_size(lv_gltf_model_t *data); + +/** + * @brief Retrieve a specific skin from the GLTF model data. + * + * @param D Pointer to the lv_gltf_data_t object containing the model data. + * @param I The index of the skin to retrieve. + * @return The skin index. + */ +size_t lv_gltf_data_get_skin(lv_gltf_model_t *data, size_t index); + +/** + * @brief Ingest and discover defines for a specific node and primitive in the GLTF model data. + * + * @param data_obj Pointer to the lv_gltf_data_t object containing the model data. + * @param node Pointer to the node for which to ingest defines. + * @param prim Pointer to the primitive for which to ingest defines. + */ +void lv_gltf_data_injest_discover_defines(lv_gltf_model_t *data, fastgltf::Node *node, fastgltf::Primitive *prim); + +/** + * @brief Retrieve the center point of a specific mesh element from the GLTF model data. + * + * @param gltf_data Pointer to the lv_gltf_data_t object containing the model data. + * @param matrix The transformation matrix to apply when calculating the center point. + * @param meshIndex The index of the mesh from which to retrieve the center point. + * @param elem The specific element index within the mesh. + * @return The center point as a fastgltf::math::fvec3 structure. + */ +fastgltf::math::fvec3 lv_gltf_data_get_centerpoint(lv_gltf_model_t *gltf_data, fastgltf::math::fmat4x4 matrix, size_t mesh_index, + int32_t elem); + + +lv_gltf_mesh_data_t *lv_gltf_get_new_meshdata(lv_gltf_model_t *_data); + +lv_gltf_model_t *lv_gltf_data_create_internal(const char *gltf_path, fastgltf::Asset); + +lv_gltf_model_t *lv_gltf_data_load_internal(const void *data_source, size_t data_size, lv_opengl_shader_manager_t *shaders); + +/*void set_node_at_path(lv_gltf_data_t *data, const std::string &path,*/ +/* fastgltf::Node *node);*/ +/*void set_node_at_ip(lv_gltf_data_t *data, const std::string &ip,*/ +/* fastgltf::Node *node);*/ +/*void set_node_index(lv_gltf_data_t *data, size_t index, fastgltf::Node *node);*/ + +fastgltf::math::fvec4 lv_gltf_get_primitive_centerpoint(lv_gltf_model_t *data, fastgltf::Mesh &mesh, uint32_t prim_num); + +fastgltf::math::fvec3 get_cached_centerpoint(lv_gltf_model_t *data, size_t index, int32_t element, + fastgltf::math::fmat4x4 matrix); + +void lv_gltf_data_destroy_textures(lv_gltf_model_t *data); +GLuint lv_gltf_data_create_texture(lv_gltf_model_t *data); +void lv_gltf_data_nodes_init(lv_gltf_model_t *data, size_t size); +void lv_gltf_data_node_init(lv_gltf_data_node_t * node, fastgltf::Node * fastgltf_node, const char * path, const char * ip); +void lv_gltf_data_node_add(lv_gltf_model_t *data, const lv_gltf_data_node_t *data_node); +void lv_gltf_data_node_delete(lv_gltf_data_node_t *node); + +/** + * @brief Retrieve the pixel data for a specific texture in a GLTF model. + * + * @param pixels Pointer to the memory where the pixel data will be stored. + * @param data_obj Pointer to the lv_gltf_data_t object containing the model data. + * @param model_texture_index The index of the texture in the model. + * @param mipmapnum The mipmap level to retrieve pixel data for. + * @param width The width of the texture. + * @param height The height of the texture. + * @param has_alpha Flag indicating whether the texture includes an alpha channel. + * @return True if the pixel data was successfully retrieved, false otherwise. + */ +bool lv_gltf_data_get_texture_pixels(void *pixels, lv_gltf_model_t *data_obj, uint32_t model_texture_index, uint32_t mipmapnum, + uint32_t width, uint32_t height, bool has_alpha); + +lv_gltf_data_node_t *lv_gltf_data_node_get_by_index(lv_gltf_model_t *data, size_t index); +lv_gltf_data_node_t *lv_gltf_data_node_get_by_ip(lv_gltf_model_t *data, const char *ip); +lv_gltf_data_node_t *lv_gltf_data_node_get_by_path(lv_gltf_model_t *data, const char *path); +uint32_t lv_gltf_data_get_animation_total_time(lv_gltf_model_t *data, uint32_t index); +std::vector *lv_gltf_data_animation_get_channel_set(std::size_t anim_num, lv_gltf_model_t *data, fastgltf::Node &node); +void lv_gltf_data_animation_matrix_apply(float timestamp, std::size_t anim_num, lv_gltf_model_t *gltf_data, fastgltf::Node &node, + fastgltf::math::fmat4x4 &matrix); + +#endif + +#endif /*LV_USE_GLTF*/ +#endif /*LV_GLTFVIEW_H*/ diff --git a/src/libs/gltf/gltf_data/lv_gltf_data_mesh.cpp b/src/libs/gltf/gltf_data/lv_gltf_data_mesh.cpp new file mode 100644 index 0000000000..623add4737 --- /dev/null +++ b/src/libs/gltf/gltf_data/lv_gltf_data_mesh.cpp @@ -0,0 +1,52 @@ +/** + * @file lv_gltf_data_mesh.cpp + * + */ + +/********************* + * INCLUDES + *********************/ +#include "lv_gltf_data_internal.hpp" +#if LV_USE_GLTF + +/********************* + * DEFINES + *********************/ + +/********************** + * TYPEDEFS + **********************/ + + +/********************** + * STATIC PROTOTYPES + **********************/ + +/********************** + * STATIC VARIABLES + **********************/ + +/********************** + * MACROS + **********************/ + +/********************** + * GLOBAL FUNCTIONS + **********************/ + +lv_gltf_mesh_data_t * lv_gltf_get_new_meshdata(lv_gltf_model_t * data) +{ + data->meshes.emplace_back(lv_gltf_mesh_data_t {}); + return &(data->meshes[data->meshes.size() - 1]); +} + + +lv_gltf_mesh_data_t * lv_gltf_data_get_mesh(lv_gltf_model_t * data, size_t index) +{ + return &data->meshes[index]; +} + +/********************** + * STATIC FUNCTIONS + **********************/ +#endif /*LV_USE_GLTF*/ diff --git a/src/libs/gltf/gltf_data/lv_gltf_data_node.cpp b/src/libs/gltf/gltf_data/lv_gltf_data_node.cpp new file mode 100644 index 0000000000..068d62fe31 --- /dev/null +++ b/src/libs/gltf/gltf_data/lv_gltf_data_node.cpp @@ -0,0 +1,103 @@ +/** + * @file lv_gltf_data_node.cpp + * + */ + +/********************* + * INCLUDES + *********************/ + +#include "lv_gltf_data_internal.hpp" +#if LV_USE_GLTF +#include "fastgltf/types.hpp" +#include "lv_gltf_model.h" +#include "lv_gltf_data_internal.hpp" +#include "../../../misc/lv_array.h" +#include "../../../misc/lv_assert.h" +#include "../../../misc/lv_types.h" +#include "../../../stdlib/lv_string.h" + +/********************* + * DEFINES + *********************/ + +/********************** + * TYPEDEFS + **********************/ + +/********************** + * STATIC PROTOTYPES + **********************/ + +/********************** + * STATIC VARIABLES + **********************/ + +/********************** + * MACROS + **********************/ + +/********************** + * GLOBAL FUNCTIONS + **********************/ + +void lv_gltf_data_nodes_init(lv_gltf_model_t * data, size_t size) +{ + lv_array_init(&data->nodes, size, sizeof(lv_gltf_data_node_t)); +} + +void lv_gltf_data_node_init(lv_gltf_data_node_t * node, fastgltf::Node * fastgltf_node, const char * path, + const char * ip) +{ + LV_ASSERT_NULL(node); + node->node = fastgltf_node; + node->path = lv_strdup(path); + node->ip = lv_strdup(ip); + + LV_ASSERT_MALLOC(path); + LV_ASSERT_MALLOC(ip); +} + +void lv_gltf_data_node_add(lv_gltf_model_t * data, const lv_gltf_data_node_t * data_node) +{ + LV_ASSERT_NULL(data); + lv_array_push_back(&data->nodes, data_node); +} + +lv_gltf_data_node_t * lv_gltf_data_node_get_by_index(lv_gltf_model_t * data, size_t index) +{ + LV_ASSERT_NULL(data); + if(index >= lv_array_size(&data->nodes)) { + return nullptr; + } + return (lv_gltf_data_node_t *)lv_array_at(&data->nodes, index); +} + +lv_gltf_data_node_t * lv_gltf_data_node_get_by_ip(lv_gltf_model_t * data, const char * ip) +{ + for(size_t i = 0; i < data->nodes.size; ++i) { + lv_gltf_data_node_t * entry = (lv_gltf_data_node_t *) lv_array_at(&data->nodes, i); + if(lv_streq(entry->ip, ip)) { + return entry; + } + } + return nullptr; +} + +lv_gltf_data_node_t * lv_gltf_data_node_get_by_path(lv_gltf_model_t * data, const char * path) +{ + + for(size_t i = 0; i < data->nodes.size; ++i) { + lv_gltf_data_node_t * entry = (lv_gltf_data_node_t *) lv_array_at(&data->nodes, i); + if(lv_streq(entry->path, path)) { + return entry; + } + } + return nullptr; +} + +/********************** + * STATIC FUNCTIONS + **********************/ + +#endif /*LV_USE_GLTF*/ diff --git a/src/libs/gltf/gltf_data/lv_gltf_data_primitive.cpp b/src/libs/gltf/gltf_data/lv_gltf_data_primitive.cpp new file mode 100644 index 0000000000..0343dfea1d --- /dev/null +++ b/src/libs/gltf/gltf_data/lv_gltf_data_primitive.cpp @@ -0,0 +1,126 @@ +/** + * @file lv_gltf_data_primitive.c + * + */ + +/********************* + * INCLUDES + *********************/ + +#include "lv_gltf_data_internal.hpp" +#if LV_USE_GLTF +#include "../../../misc/lv_math.h" + +/********************* + * DEFINES + *********************/ + +/********************** + * TYPEDEFS + **********************/ + +/********************** + * STATIC PROTOTYPES + **********************/ + +/********************** + * STATIC VARIABLES + **********************/ + +/********************** + * MACROS + **********************/ + +/********************** + * GLOBAL FUNCTIONS + **********************/ + +lv_gltf_primitive_t * lv_gltf_data_get_primitive_from_mesh(lv_gltf_mesh_data_t * mesh, uint64_t index) +{ + return &(mesh->primitives[index]); +} + +void lv_gltf_data_add_opaque_node_primitive(lv_gltf_model_t * data, size_t index, + fastgltf::Node * node, size_t primitive_index) +{ + data->opaque_nodes_by_material_index[index].emplace_back( + std::make_pair(node, primitive_index)); +} + +void lv_gltf_data_add_blended_node_primitive(lv_gltf_model_t * data, size_t index, + fastgltf::Node * node, size_t primitive_index) +{ + data->blended_nodes_by_material_index[index].push_back( + std::make_pair(node, primitive_index)); +} + +fastgltf::math::fvec4 lv_gltf_get_primitive_centerpoint(lv_gltf_model_t * data, + fastgltf::Mesh & mesh, + uint32_t prim_num) +{ + fastgltf::math::fvec4 result{ 0.f }; + fastgltf::math::fvec3 v_min{ 999999999.f }; + fastgltf::math::fvec3 v_max{ -999999999.f }; + fastgltf::math::fvec3 v_cen{ 0.f }; + float radius = 0.f; + + if(mesh.primitives.size() <= prim_num) { + return result; + } + const auto & it = mesh.primitives[prim_num]; + const auto & asset = data->asset; + + const auto * positionIt = it.findAttribute("POSITION"); + const auto & positionAccessor = + asset.accessors[positionIt->accessorIndex]; + if(!positionAccessor.bufferViewIndex.has_value()) { + return result; + } + + if(!(positionAccessor.min.has_value() && + positionAccessor.max.has_value())) { + LV_LOG_ERROR( + "Could not get primitive center point. Missing min/max values"); + return result; + } + + fastgltf::math::fvec4 t_min{ + (float)(positionAccessor.min.value().get((size_t)0)), + (float)(positionAccessor.min.value().get((size_t)1)), + (float)(positionAccessor.min.value().get((size_t)2)), + 0.f + }; + fastgltf::math::fvec4 t_max{ + (float)(positionAccessor.max.value().get((size_t)0)), + (float)(positionAccessor.max.value().get((size_t)1)), + (float)(positionAccessor.max.value().get((size_t)2)), + 0.f + }; + + v_max[0] = LV_MAX(t_min.x(), t_max.x()); + v_max[1] = LV_MAX(t_min.y(), t_max.y()); + v_max[2] = LV_MAX(t_min.z(), t_max.z()); + v_min[0] = LV_MIN(t_min.x(), t_max.x()); + v_min[1] = LV_MIN(t_min.y(), t_max.y()); + v_min[2] = LV_MIN(t_min.z(), t_max.z()); + v_cen[0] = (v_max[0] + v_min[0]) / 2.0f; + v_cen[1] = (v_max[1] + v_min[1]) / 2.0f; + v_cen[2] = (v_max[2] + v_min[2]) / 2.0f; + float size_x = v_max[0] - v_min[0]; + float size_y = v_max[1] - v_min[1]; + float size_z = v_max[2] - v_min[2]; + radius = std::sqrt((size_x * size_x) + (size_y * size_y) + + (size_z * size_z)) / + 2.0f; + result[0] = v_cen[0]; + result[1] = v_cen[1]; + result[2] = v_cen[2]; + result[3] = radius; + return result; +} + +/********************** + * STATIC FUNCTIONS + **********************/ + +#endif /*LV_USE_GLTF*/ diff --git a/src/libs/gltf/gltf_data/lv_gltf_data_shader.cpp b/src/libs/gltf/gltf_data/lv_gltf_data_shader.cpp new file mode 100644 index 0000000000..3364d0a449 --- /dev/null +++ b/src/libs/gltf/gltf_data/lv_gltf_data_shader.cpp @@ -0,0 +1,60 @@ +/** + * @file lv_gltf_data_shader.cpp + * + */ + +/********************* + * INCLUDES + *********************/ + +#include "lv_gltf_data_internal.hpp" + +#if LV_USE_GLTF +#include "../../../misc/lv_array.h" +/********************* + * DEFINES + *********************/ + +/********************** + * TYPEDEFS + **********************/ + +/********************** + * STATIC PROTOTYPES + **********************/ + +/********************** + * STATIC VARIABLES + **********************/ + +/********************** + * MACROS + **********************/ + +/********************** + * GLOBAL FUNCTIONS + **********************/ + +void lv_gltf_store_compiled_shader(lv_gltf_model_t * data, size_t identifier, lv_gltf_compiled_shader_t * shader) +{ + const size_t index = identifier - 1; + bool has_to_resize = index >= lv_array_size(&data->compiled_shaders); + if(!has_to_resize) { + lv_array_assign(&data->compiled_shaders, index, shader); + } + while(index >= lv_array_size(&data->compiled_shaders)) { + lv_array_push_back(&data->compiled_shaders, shader); + } +} + +lv_gltf_compiled_shader_t * lv_gltf_get_compiled_shader(lv_gltf_model_t * data, size_t identifier) +{ + const size_t index = identifier - 1; + LV_ASSERT(index < lv_array_size(&data->compiled_shaders)); + return (lv_gltf_compiled_shader_t *)lv_array_at(&data->compiled_shaders, index); +} + +/********************** + * STATIC FUNCTIONS + **********************/ +#endif /*LV_USE_GLTF*/ diff --git a/src/libs/gltf/gltf_data/lv_gltf_data_skin.cpp b/src/libs/gltf/gltf_data/lv_gltf_data_skin.cpp new file mode 100644 index 0000000000..d67b53cd9d --- /dev/null +++ b/src/libs/gltf/gltf_data/lv_gltf_data_skin.cpp @@ -0,0 +1,68 @@ +/** + * @file lv_gltf_data_skin.cpp + * + */ + +/********************* + * INCLUDES + *********************/ + +#include "lv_gltf_data_internal.hpp" + +#if LV_USE_GLTF +#include + +/********************* + * DEFINES + *********************/ + +/********************** + * TYPEDEFS + **********************/ + +/********************** + * STATIC PROTOTYPES + **********************/ + +/********************** + * STATIC VARIABLES + **********************/ + +/********************** + * MACROS + **********************/ + +/********************** + * GLOBAL FUNCTIONS + **********************/ + +GLuint lv_gltf_data_get_skin_texture_at(lv_gltf_model_t * data, size_t index) +{ + return data->skin_tex[index]; +} + +bool lv_gltf_data_validated_skins_contains(lv_gltf_model_t * data, size_t index) +{ + return ((std::find(data->validated_skins.begin(), + data->validated_skins.end(), + index) != data->validated_skins.end())); +} + +void lv_gltf_data_validate_skin(lv_gltf_model_t * data, size_t index) +{ + data->validated_skins.push_back(index); +} + +size_t lv_gltf_data_get_skins_size(lv_gltf_model_t * data) +{ + return data->validated_skins.size(); +} +size_t lv_gltf_data_get_skin(lv_gltf_model_t * data, size_t index) +{ + return data->validated_skins[index]; +} + +/********************** + * STATIC FUNCTIONS + **********************/ +#endif /*LV_USE_GLTF*/ diff --git a/src/libs/gltf/gltf_data/lv_gltf_data_texture.cpp b/src/libs/gltf/gltf_data/lv_gltf_data_texture.cpp new file mode 100644 index 0000000000..5545b9fceb --- /dev/null +++ b/src/libs/gltf/gltf_data/lv_gltf_data_texture.cpp @@ -0,0 +1,87 @@ +/** + * @file lv_gltf_data_texture.cpp + * + */ + +/********************* + * INCLUDES + *********************/ + +#include "lv_gltf_data_internal.hpp" +#if LV_USE_GLTF + +#include +#include "../../../misc/lv_color.h" + +/********************* + * DEFINES + *********************/ + +/********************** + * TYPEDEFS + **********************/ + +/********************** + * STATIC PROTOTYPES + **********************/ + +/********************** + * STATIC VARIABLES + **********************/ + +/********************** + * MACROS + **********************/ + +/********************** + * GLOBAL FUNCTIONS + **********************/ + +void lv_gltf_data_destroy_textures(lv_gltf_model_t * data) +{ + glDeleteTextures(data->skin_tex.size(), data->skin_tex.data()); + data->skin_tex.clear(); +} + +GLuint lv_gltf_data_create_texture(lv_gltf_model_t * data) +{ + GLuint texture; + GL_CALL(glGenTextures(1, &texture)); + data->skin_tex.push_back(texture); + return texture; +} + +void lv_gltf_data_rgb_to_bgr(uint8_t * pixels, size_t byte_total_count, bool has_alpha) +{ + size_t bytes_per_pixel = has_alpha ? 4 : 3; + size_t pixel_count = (byte_total_count / bytes_per_pixel); + if(bytes_per_pixel == 4) { + for(size_t p = 0; p < pixel_count; p++) { + size_t index = p << 2; + uint8_t r = pixels[index + 0]; + uint8_t g = pixels[index + 1]; + uint8_t b = pixels[index + 2]; + uint8_t a = pixels[index + 3]; + pixels[index + 0] = b; + pixels[index + 1] = g; + pixels[index + 2] = r; + pixels[index + 3] = a; + } + } + else { + for(size_t p = 0; p < pixel_count; p++) { + size_t index = p * 3; + uint8_t r = pixels[index + 0]; + uint8_t g = pixels[index + 1]; + uint8_t b = pixels[index + 2]; + pixels[index + 0] = b; + pixels[index + 1] = g; + pixels[index + 2] = r; + } + } +} + +/********************** + * STATIC FUNCTIONS + **********************/ +#endif /*LV_USE_GLTF*/ diff --git a/src/libs/gltf/gltf_data/lv_gltf_model.h b/src/libs/gltf/gltf_data/lv_gltf_model.h new file mode 100644 index 0000000000..600cd93d92 --- /dev/null +++ b/src/libs/gltf/gltf_data/lv_gltf_model.h @@ -0,0 +1,135 @@ +#ifndef LV_GLTF_MODEL_H +#define LV_GLTF_MODEL_H + +#include "../../../lv_conf_internal.h" +#if LV_USE_GLTF + +#include "../../../misc/lv_types.h" + +#ifdef __cplusplus +extern "C" { +#endif +/** + * @brief Get the number of images in the glTF model + * + * Images in glTF are used as sources for textures and can be stored either as external files + * or embedded as base64-encoded model within the glTF file. + * + * @param model Pointer to the glTF model data structure + * @return Number of images in the model + */ +size_t lv_gltf_model_get_image_count(const lv_gltf_model_t * model); + +/** + * @brief Get the number of textures in the glTF model + * + * Textures define how images are sampled and applied to materials. Each texture references + * an image and may specify sampling parameters like filtering and wrapping modes. + * + * @param model Pointer to the glTF model data structure + * @return Number of textures in the model + */ +size_t lv_gltf_model_get_texture_count(const lv_gltf_model_t * model); + +/** + * @brief Get the number of materials in the glTF model + * + * Materials define the visual appearance of mesh primitives, including properties like + * base color, metallic/roughness values, normal maps, and other surface characteristics. + * + * @param model Pointer to the glTF model data structure + * @return Number of materials in the model + */ +size_t lv_gltf_model_get_material_count(const lv_gltf_model_t * model); + +/** + * @brief Get the number of cameras in the glTF model + * + * Cameras define viewpoints within the 3D scene and can be either perspective or + * orthographic. They are typically attached to nodes in the scene graph. + * + * @param model Pointer to the glTF model data structure + * @return Number of cameras in the model + */ +size_t lv_gltf_model_get_camera_count(const lv_gltf_model_t * model); + +/** + * @brief Get the number of nodes in the glTF model + * + * Nodes form the scene graph hierarchy and can contain transformations, meshes, cameras, + * or other nodes as children. They define the spatial relationships between objects in the scene. + * + * @param model Pointer to the glTF model data structure + * @return Number of nodes in the model + */ +size_t lv_gltf_model_get_node_count(const lv_gltf_model_t * model); + +/** + * @brief Get the number of meshes in the glTF model + * + * Meshes contain the geometric model for 3D objects, including vertex positions, normals, + * texture coordinates, and indices. Each mesh can have multiple primitives with different materials. + * + * @param model Pointer to the glTF model data structure + * @return Number of meshes in the model + */ +size_t lv_gltf_model_get_mesh_count(const lv_gltf_model_t * model); + +/** + * @brief Get the number of scenes in the glTF model + * + * Scenes define the root nodes of the scene graph. A glTF file can contain multiple scenes, + * though typically only one is designated as the default scene to be displayed. + * + * @param model Pointer to the glTF model data structure + * @return Number of scenes in the model + */ +size_t lv_gltf_model_get_scene_count(const lv_gltf_model_t * model); + +/** + * @brief Get the number of animations in the glTF model + * + * Animations define keyframe-based motion for nodes in the scene, including transformations + * like translation, rotation, and scaling over time. + * + * @param model Pointer to the glTF model data structure + * @return Number of animations in the model + */ +size_t lv_gltf_model_get_animation_count(const lv_gltf_model_t * model); + +/** + * @brief Select and start playing an animation + * + * @param model Pointer to the glTF model structure + * @param index Animation number to start playing + * @return LV_RESULT_OK if the animation was started else LV_RESULT_INVALID + */ +lv_result_t lv_gltf_model_play_animation(lv_gltf_model_t * model, size_t index); + +/** + * @brief Pause the current animation + * + * @param model Pointer to the glTF model structure + */ +void lv_gltf_model_pause_animation(lv_gltf_model_t * model); + +/** + * @brief Check if an animation is currently being played + * + * @param model Pointer to the glTF model structure + */ +bool lv_gltf_model_is_animation_paused(lv_gltf_model_t * model); + +/** + * @brief Get the current selected animation. To see if it's playing see `lv_gltf_model_is_animation_paused` + * + * @param model Pointer to the glTF model structure + */ +size_t lv_gltf_model_get_animation(lv_gltf_model_t * model); + +#ifdef __cplusplus +} /*extern "C"*/ +#endif + +#endif /*LV_USE_GLTF*/ +#endif /*LV_GLTF_MODEL_H*/ diff --git a/src/libs/gltf/gltf_data/lv_gltf_uniform_locations.cpp b/src/libs/gltf/gltf_data/lv_gltf_uniform_locations.cpp new file mode 100644 index 0000000000..0a213d661a --- /dev/null +++ b/src/libs/gltf/gltf_data/lv_gltf_uniform_locations.cpp @@ -0,0 +1,115 @@ + +#include "lv_gltf_data_internal.hpp" +#if LV_USE_GLTF + +lv_gltf_uniform_locations_t lv_gltf_uniform_locations_create(GLuint program) +{ + lv_gltf_uniform_locations_t uniforms; + lv_memset(&uniforms, 0, sizeof(uniforms)); + + // *** IMAGE QUALITY UNIFORMS *********************************************************************** + uniforms.exposure = glGetUniformLocation(program, "u_Exposure"); + // *** CAMERA/VIEW/PROJECTION/MODEL MATRIX UNIFORMS ************************************************* + uniforms.camera = glGetUniformLocation(program, "u_Camera"); + uniforms.model_matrix = glGetUniformLocation(program, "u_ModelMatrix"); + uniforms.view_projection_matrix = glGetUniformLocation(program, "u_ViewProjectionMatrix"); + uniforms.view_matrix = glGetUniformLocation(program, "u_ViewMatrix"); + uniforms.projection_matrix = glGetUniformLocation(program, "u_ProjectionMatrix"); + // *** IMAGE BASED LIGHTING (IBL) UNIFORMS ********************************************************** + uniforms.env_intensity = glGetUniformLocation(program, "u_EnvIntensity"); + uniforms.env_diffuse_sampler = glGetUniformLocation(program, "u_LambertianEnvSampler"); + uniforms.env_specular_sampler = glGetUniformLocation(program, "u_GGXEnvSampler"); + uniforms.env_sheen_sampler = glGetUniformLocation(program, "u_CharlieEnvSampler"); + uniforms.env_ggx_lut_sampler = glGetUniformLocation(program, "u_GGXLUT"); + uniforms.env_charlie_lut_sampler = glGetUniformLocation(program, "u_CharlieLUT"); + uniforms.env_mip_count = glGetUniformLocation(program, "u_MipCount"); + // *** BASE COLOR / TEXTURE UNIFORMS **************************************************************** + uniforms.base_color_factor = glGetUniformLocation(program, "u_BaseColorFactor"); + uniforms.base_color_sampler = glGetUniformLocation(program, "u_BaseColorSampler"); + uniforms.base_color_uv_set = glGetUniformLocation(program, "u_BaseColorUVSet"); + uniforms.base_color_uv_transform = glGetUniformLocation(program, "u_BaseColorUVTransform"); + // *** CUTOFF / IOR / DISPERSION UNIFORMS *********************************************************** + uniforms.alpha_cutoff = glGetUniformLocation(program, "u_AlphaCutoff"); + uniforms.ior = glGetUniformLocation(program, "u_Ior"); + uniforms.dispersion = glGetUniformLocation(program, "u_Dispersion"); + // *** METALLIC / ROUGHNESS UNIFORMS **************************************************************** + uniforms.metallic_factor = glGetUniformLocation(program, "u_MetallicFactor"); + uniforms.roughness_factor = glGetUniformLocation(program, "u_RoughnessFactor"); + uniforms.metallic_roughness_sampler = glGetUniformLocation(program, "u_MetallicRoughnessSampler"); + uniforms.metallic_roughness_uv_set = glGetUniformLocation(program, "u_MetallicRoughnessUVSet"); + uniforms.metallic_roughness_uv_transform = glGetUniformLocation(program, "u_MetallicRoughnessUVTransform"); + // *** EMISSION UNIFORMS **************************************************************************** + uniforms.emissive_factor = glGetUniformLocation(program, "u_EmissiveFactor"); + uniforms.emissive_sampler = glGetUniformLocation(program, "u_EmissiveSampler"); + uniforms.emissive_uv_set = glGetUniformLocation(program, "u_EmissiveUVSet"); + uniforms.emissive_uv_transform = glGetUniformLocation(program, "u_EmissiveUVTransform"); + uniforms.emissive_strength = glGetUniformLocation(program, "u_EmissiveStrength"); + // *** OCCLUSION UNIFORMS *************************************************************************** + uniforms.occlusion_strength = glGetUniformLocation(program, "u_OcclusionStrength"); + uniforms.occlusion_sampler = glGetUniformLocation(program, "u_OcclusionSampler"); + uniforms.occlusion_uv_set = glGetUniformLocation(program, "u_OcclusionUVSet"); + uniforms.occlusion_uv_transform = glGetUniformLocation(program, "u_OcclusionUVTransform"); + // *** NORMAL MAP UNIFORMS ************************************************************************** + uniforms.normal_sampler = glGetUniformLocation(program, "u_NormalSampler"); + uniforms.normal_scale = glGetUniformLocation(program, "u_NormalScale"); + uniforms.normal_uv_set = glGetUniformLocation(program, "u_NormalUVSet"); + uniforms.normal_uv_transform = glGetUniformLocation(program, "u_NormalUVTransform"); + // *** VOLUME / TRANSMISSION UNIFORMS *************************************************************** + uniforms.attenuation_distance = glGetUniformLocation(program, "u_AttenuationDistance"); + uniforms.attenuation_color = glGetUniformLocation(program, "u_AttenuationColor"); + uniforms.transmission_factor = glGetUniformLocation(program, "u_TransmissionFactor"); + uniforms.transmission_sampler = glGetUniformLocation(program, "u_TransmissionSampler"); + uniforms.transmission_uv_set = glGetUniformLocation(program, "u_TransmissionUVSet"); + uniforms.transmission_uv_transform = glGetUniformLocation(program, "u_TransmissionUVTransform"); + uniforms.transmission_framebuffer_sampler = glGetUniformLocation(program, "u_TransmissionFramebufferSampler"); + uniforms.transmission_framebuffer_size = glGetUniformLocation(program, "u_TransmissionFramebufferSize"); + uniforms.screen_size = glGetUniformLocation(program, "u_ScreenSize"); + uniforms.thickness = glGetUniformLocation(program, "u_ThicknessFactor"); + uniforms.thickness_sampler = glGetUniformLocation(program, "u_ThicknessSampler"); + uniforms.thickness_uv_set = glGetUniformLocation(program, "u_ThicknessUVSet"); + uniforms.thickness_uv_transform = glGetUniformLocation(program, "u_ThicknessUVTransform"); + // *** CLEARCOAT UNIFORMS *************************************************************************** + uniforms.clearcoat_factor = glGetUniformLocation(program, "u_ClearcoatFactor"); + uniforms.clearcoat_roughness_factor = glGetUniformLocation(program, "u_ClearcoatRoughnessFactor"); + uniforms.clearcoat_sampler = glGetUniformLocation(program, "u_ClearcoatSampler"); + uniforms.clearcoat_uv_set = glGetUniformLocation(program, "u_ClearcoatUVSet"); + uniforms.clearcoat_uv_transform = glGetUniformLocation(program, "u_ClearcoatUVTransform"); + uniforms.clearcoat_roughness_sampler = glGetUniformLocation(program, "u_ClearcoatRoughnessSampler"); + uniforms.clearcoat_roughness_uv_set = glGetUniformLocation(program, "u_ClearcoatRoughnessUVSet"); + uniforms.clearcoat_roughness_uv_transform = glGetUniformLocation(program, "u_ClearcoatRoughnessUVTransform"); + uniforms.clearcoat_normal_scale = glGetUniformLocation(program, "u_ClearcoatNormalScale"); + uniforms.clearcoat_normal_sampler = glGetUniformLocation(program, "u_ClearcoatNormalSampler"); + uniforms.clearcoat_normal_uv_set = glGetUniformLocation(program, "u_ClearcoatNormalUVSet"); + uniforms.clearcoat_normal_uv_transform = glGetUniformLocation(program, "u_ClearcoatNormalUVTransform"); + // *** DIFFUSE TRANSMISSION UNIFORMS **************************************************************** + uniforms.diffuse_transmission_factor = glGetUniformLocation(program, "u_DiffuseTransmissionFactor"); + uniforms.diffuse_transmission_sampler = glGetUniformLocation(program, "u_DiffuseTransmissionSampler"); + uniforms.diffuse_transmission_uv_set = glGetUniformLocation(program, "u_DiffuseTransmissionUVSet"); + uniforms.diffuse_transmission_uv_transform = glGetUniformLocation(program, "u_DiffuseTransmissionUVTransform"); + uniforms.diffuse_transmission_color_factor = glGetUniformLocation(program, "u_DiffuseTransmissionColorFactor"); + uniforms.diffuse_transmission_color_sampler = glGetUniformLocation(program, "u_DiffuseTransmissionColorSampler"); + uniforms.diffuse_transmission_color_uv_set = glGetUniformLocation(program, "u_DiffuseTransmissionColorUVSet"); + uniforms.diffuse_transmission_color_uv_transform = glGetUniformLocation(program, + "u_DiffuseTransmissionColorUVTransform"); + // *** LEGACY SUPPORT - PBR_SPECULARGLOSS *********************************************************** + uniforms.diffuse_factor = glGetUniformLocation(program, "u_DiffuseFactor"); + uniforms.specular_factor = glGetUniformLocation(program, "u_SpecularFactor"); + uniforms.glossiness_factor = glGetUniformLocation(program, "u_GlossinessFactor"); + uniforms.diffuse_sampler = glGetUniformLocation(program, "u_DiffuseSampler"); + uniforms.diffuse_uv_set = glGetUniformLocation(program, "u_DiffuseUVSet"); + uniforms.diffuse_uv_transform = glGetUniformLocation(program, "u_DiffuseUVTransform"); + uniforms.specular_glossiness_sampler = glGetUniformLocation(program, "u_SpecularGlossinessSampler"); + uniforms.specular_glossiness_uv_set = glGetUniformLocation(program, "u_SpecularGlossinessUVSet"); + uniforms.specular_glossiness_uv_transform = glGetUniformLocation(program, "u_SpecularGlossinessUVTransform"); + // *** [PARTIALLY SUPPORTED / IN DEVELOPMENT] UNIFORMS ********************************************** + uniforms.sheen_color_factor = glGetUniformLocation(program, "u_SheenColorFactor"); + uniforms.sheen_roughness_factor = glGetUniformLocation(program, "u_SheenRoughnessFactor"); + // + uniforms.specular_color_factor = glGetUniformLocation(program, "u_KHR_materials_specular_specularColorFactor"); + uniforms.specular_factor = glGetUniformLocation(program, "u_KHR_materials_specular_specularFactor"); + // + uniforms.joints_sampler = glGetUniformLocation(program, "u_jointsSampler"); + return uniforms; +} + +#endif /*LV_USE_GLTF*/ diff --git a/src/libs/gltf/gltf_view/assets/chromatic.c b/src/libs/gltf/gltf_view/assets/chromatic.c new file mode 100644 index 0000000000..34520f010e --- /dev/null +++ b/src/libs/gltf/gltf_view/assets/chromatic.c @@ -0,0 +1,7545 @@ +#include "../../../../lv_conf_internal.h" + +#if LV_USE_GLTF +unsigned char chromatic_jpg[] = { + 0xff, 0xd8, 0xff, 0xe0, 0x00, 0x10, 0x4a, 0x46, 0x49, 0x46, 0x00, 0x01, + 0x01, 0x01, 0x00, 0x48, 0x00, 0x48, 0x00, 0x00, 0xff, 0xe2, 0x02, 0xd8, + 0x49, 0x43, 0x43, 0x5f, 0x50, 0x52, 0x4f, 0x46, 0x49, 0x4c, 0x45, 0x00, + 0x01, 0x01, 0x00, 0x00, 0x02, 0xc8, 0x6c, 0x63, 0x6d, 0x73, 0x04, 0x30, + 0x00, 0x00, 0x6d, 0x6e, 0x74, 0x72, 0x52, 0x47, 0x42, 0x20, 0x58, 0x59, + 0x5a, 0x20, 0x07, 0xe4, 0x00, 0x05, 0x00, 0x07, 0x00, 0x05, 0x00, 0x12, + 0x00, 0x37, 0x61, 0x63, 0x73, 0x70, 0x4d, 0x53, 0x46, 0x54, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xf6, 0xd6, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0xd3, 0x2d, 0x6c, 0x63, + 0x6d, 0x73, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x0b, 0x77, 0x74, 0x70, 0x74, 0x00, 0x00, 0x01, 0x08, 0x00, 0x00, + 0x00, 0x14, 0x64, 0x65, 0x73, 0x63, 0x00, 0x00, 0x01, 0x1c, 0x00, 0x00, + 0x00, 0x6a, 0x72, 0x58, 0x59, 0x5a, 0x00, 0x00, 0x01, 0x88, 0x00, 0x00, + 0x00, 0x14, 0x67, 0x58, 0x59, 0x5a, 0x00, 0x00, 0x01, 0x9c, 0x00, 0x00, + 0x00, 0x14, 0x62, 0x58, 0x59, 0x5a, 0x00, 0x00, 0x01, 0xb0, 0x00, 0x00, + 0x00, 0x14, 0x72, 0x54, 0x52, 0x43, 0x00, 0x00, 0x01, 0xc4, 0x00, 0x00, + 0x00, 0x20, 0x67, 0x54, 0x52, 0x43, 0x00, 0x00, 0x01, 0xe4, 0x00, 0x00, + 0x00, 0x20, 0x62, 0x54, 0x52, 0x43, 0x00, 0x00, 0x02, 0x04, 0x00, 0x00, + 0x00, 0x20, 0x64, 0x6d, 0x6e, 0x64, 0x00, 0x00, 0x02, 0x24, 0x00, 0x00, + 0x00, 0x24, 0x64, 0x6d, 0x64, 0x64, 0x00, 0x00, 0x02, 0x48, 0x00, 0x00, + 0x00, 0x46, 0x63, 0x70, 0x72, 0x74, 0x00, 0x00, 0x02, 0x90, 0x00, 0x00, + 0x00, 0x36, 0x58, 0x59, 0x5a, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xf6, 0xd6, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0xd3, 0x2d, 0x6d, 0x6c, + 0x75, 0x63, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, + 0x00, 0x0c, 0x65, 0x6e, 0x55, 0x53, 0x00, 0x00, 0x00, 0x4e, 0x00, 0x00, + 0x00, 0x1c, 0x00, 0x73, 0x00, 0x52, 0x00, 0x47, 0x00, 0x42, 0x00, 0x20, + 0x00, 0x54, 0x00, 0x52, 0x00, 0x43, 0x00, 0x20, 0x00, 0x66, 0x00, 0x72, + 0x00, 0x6f, 0x00, 0x6d, 0x00, 0x20, 0x00, 0x47, 0x00, 0x49, 0x00, 0x4d, + 0x00, 0x50, 0x00, 0x20, 0x00, 0x62, 0x00, 0x75, 0x00, 0x69, 0x00, 0x6c, + 0x00, 0x74, 0x00, 0x2d, 0x00, 0x69, 0x00, 0x6e, 0x00, 0x20, 0x00, 0x4c, + 0x00, 0x69, 0x00, 0x6e, 0x00, 0x65, 0x00, 0x61, 0x00, 0x72, 0x00, 0x20, + 0x00, 0x73, 0x00, 0x52, 0x00, 0x47, 0x00, 0x42, 0x00, 0x00, 0x58, 0x59, + 0x5a, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x6f, 0xa0, 0x00, 0x00, + 0x38, 0xf5, 0x00, 0x00, 0x03, 0x90, 0x58, 0x59, 0x5a, 0x20, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x62, 0x97, 0x00, 0x00, 0xb7, 0x87, 0x00, 0x00, + 0x18, 0xd9, 0x58, 0x59, 0x5a, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x24, 0x9f, 0x00, 0x00, 0x0f, 0x84, 0x00, 0x00, 0xb6, 0xc4, 0x70, 0x61, + 0x72, 0x61, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x02, + 0x66, 0x66, 0x00, 0x00, 0xf2, 0xa7, 0x00, 0x00, 0x0d, 0x59, 0x00, 0x00, + 0x13, 0xd0, 0x00, 0x00, 0x0a, 0x5b, 0x70, 0x61, 0x72, 0x61, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x02, 0x66, 0x66, 0x00, 0x00, + 0xf2, 0xa7, 0x00, 0x00, 0x0d, 0x59, 0x00, 0x00, 0x13, 0xd0, 0x00, 0x00, + 0x0a, 0x5b, 0x70, 0x61, 0x72, 0x61, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, + 0x00, 0x00, 0x00, 0x02, 0x66, 0x66, 0x00, 0x00, 0xf2, 0xa7, 0x00, 0x00, + 0x0d, 0x59, 0x00, 0x00, 0x13, 0xd0, 0x00, 0x00, 0x0a, 0x5b, 0x6d, 0x6c, + 0x75, 0x63, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, + 0x00, 0x0c, 0x65, 0x6e, 0x55, 0x53, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, + 0x00, 0x1c, 0x00, 0x47, 0x00, 0x49, 0x00, 0x4d, 0x00, 0x50, 0x6d, 0x6c, + 0x75, 0x63, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, + 0x00, 0x0c, 0x65, 0x6e, 0x55, 0x53, 0x00, 0x00, 0x00, 0x2a, 0x00, 0x00, + 0x00, 0x1c, 0x00, 0x47, 0x00, 0x49, 0x00, 0x4d, 0x00, 0x50, 0x00, 0x20, + 0x00, 0x66, 0x00, 0x72, 0x00, 0x6f, 0x00, 0x6d, 0x00, 0x20, 0x00, 0x4c, + 0x00, 0x69, 0x00, 0x6e, 0x00, 0x65, 0x00, 0x61, 0x00, 0x72, 0x00, 0x20, + 0x00, 0x73, 0x00, 0x52, 0x00, 0x47, 0x00, 0x42, 0x00, 0x00, 0x6d, 0x6c, + 0x75, 0x63, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, + 0x00, 0x0c, 0x65, 0x6e, 0x55, 0x53, 0x00, 0x00, 0x00, 0x1a, 0x00, 0x00, + 0x00, 0x1c, 0x00, 0x50, 0x00, 0x75, 0x00, 0x62, 0x00, 0x6c, 0x00, 0x69, + 0x00, 0x63, 0x00, 0x20, 0x00, 0x44, 0x00, 0x6f, 0x00, 0x6d, 0x00, 0x61, + 0x00, 0x69, 0x00, 0x6e, 0x00, 0x00, 0xff, 0xdb, 0x00, 0x43, 0x00, 0x03, + 0x02, 0x02, 0x03, 0x02, 0x02, 0x03, 0x03, 0x03, 0x03, 0x04, 0x03, 0x03, + 0x04, 0x05, 0x08, 0x05, 0x05, 0x04, 0x04, 0x05, 0x0a, 0x07, 0x07, 0x06, + 0x08, 0x0c, 0x0a, 0x0c, 0x0c, 0x0b, 0x0a, 0x0b, 0x0b, 0x0d, 0x0e, 0x12, + 0x10, 0x0d, 0x0e, 0x11, 0x0e, 0x0b, 0x0b, 0x10, 0x16, 0x10, 0x11, 0x13, + 0x14, 0x15, 0x15, 0x15, 0x0c, 0x0f, 0x17, 0x18, 0x16, 0x14, 0x18, 0x12, + 0x14, 0x15, 0x14, 0xff, 0xdb, 0x00, 0x43, 0x01, 0x03, 0x04, 0x04, 0x05, + 0x04, 0x05, 0x09, 0x05, 0x05, 0x09, 0x14, 0x0d, 0x0b, 0x0d, 0x14, 0x14, + 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, + 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, + 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, + 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, + 0xff, 0xc2, 0x00, 0x11, 0x08, 0x02, 0x00, 0x04, 0x00, 0x03, 0x01, 0x11, + 0x00, 0x02, 0x11, 0x01, 0x03, 0x11, 0x01, 0xff, 0xc4, 0x00, 0x1c, 0x00, + 0x00, 0x02, 0x03, 0x01, 0x01, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, + 0x08, 0xff, 0xc4, 0x00, 0x1a, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, + 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, + 0x02, 0x03, 0x04, 0x05, 0x06, 0xff, 0xda, 0x00, 0x0c, 0x03, 0x01, 0x00, + 0x02, 0x10, 0x03, 0x10, 0x00, 0x00, 0x01, 0xf9, 0x8e, 0x7c, 0xed, 0x0a, + 0x40, 0x82, 0x80, 0x82, 0x80, 0x00, 0x00, 0x02, 0x40, 0x15, 0x88, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x0a, 0x10, 0x14, 0x3a, 0x40, + 0x3a, 0x50, 0x05, 0x00, 0x82, 0x80, 0x85, 0x01, 0x08, 0x6a, 0x81, 0x15, + 0x28, 0x53, 0x5a, 0xbc, 0xdd, 0xef, 0xf2, 0xec, 0x2c, 0xe1, 0xd2, 0xfe, + 0x3b, 0xb3, 0x1a, 0xb3, 0x9e, 0xe7, 0x9b, 0x2c, 0x69, 0xe4, 0xd6, 0x4a, + 0xf2, 0x74, 0xf3, 0x58, 0x29, 0x0e, 0x1c, 0xa5, 0x38, 0x25, 0x11, 0x85, + 0x39, 0x41, 0xc1, 0x04, 0xa5, 0x3b, 0x0a, 0x70, 0x50, 0x14, 0x40, 0x3a, + 0x59, 0x01, 0x45, 0x02, 0x80, 0x48, 0x41, 0x4a, 0x81, 0x6a, 0x14, 0xac, + 0x34, 0x8c, 0x46, 0xe5, 0x6a, 0x57, 0xb9, 0x5f, 0x5c, 0xe7, 0xed, 0xcf, + 0x0f, 0xbf, 0xcd, 0x97, 0xdb, 0xc2, 0x1a, 0x17, 0x28, 0x00, 0x00, 0x01, + 0x00, 0x82, 0x88, 0x00, 0x00, 0x10, 0x50, 0x00, 0x00, 0x48, 0x28, 0x00, + 0x82, 0x80, 0x31, 0x00, 0x20, 0x14, 0x08, 0x62, 0x42, 0x80, 0x00, 0x04, + 0x29, 0x41, 0x40, 0x00, 0x20, 0xa8, 0x04, 0x45, 0x63, 0x15, 0x94, 0xcd, + 0x5f, 0xe3, 0xf4, 0xfb, 0x2f, 0xcc, 0x7d, 0x49, 0x71, 0xae, 0x88, 0x21, + 0xaa, 0x87, 0xa3, 0x83, 0x42, 0x09, 0x5e, 0xa1, 0x2b, 0xa2, 0xc2, 0x1c, + 0xa0, 0xed, 0x70, 0x40, 0x11, 0x20, 0x86, 0xae, 0x9c, 0x4b, 0x71, 0xe6, + 0x99, 0xa1, 0x2a, 0x74, 0x0e, 0x00, 0x00, 0xb1, 0x2b, 0x10, 0xa0, 0x82, + 0x94, 0x3a, 0x40, 0x02, 0x0a, 0x79, 0x01, 0x61, 0x6a, 0x90, 0x53, 0x64, + 0x44, 0xe2, 0xfd, 0xdf, 0x17, 0x0f, 0xd1, 0xef, 0xe5, 0x7d, 0xbf, 0x87, + 0x2d, 0x65, 0x82, 0x00, 0x00, 0x30, 0x1a, 0x10, 0x0e, 0x25, 0x23, 0x1c, + 0x92, 0x92, 0x52, 0x4b, 0x32, 0x52, 0x31, 0x80, 0x0c, 0x00, 0x00, 0x00, + 0x00, 0x01, 0x0b, 0x44, 0x00, 0x00, 0x07, 0x42, 0x12, 0x81, 0x40, 0xc0, + 0x02, 0x0a, 0x00, 0x42, 0x80, 0x8c, 0xb5, 0x99, 0xe6, 0xa5, 0xe5, 0xf4, + 0x7b, 0xdf, 0xcb, 0xfd, 0x5b, 0xa5, 0x79, 0xa4, 0x10, 0x04, 0x01, 0x69, + 0x11, 0x08, 0x42, 0xb0, 0xa2, 0x81, 0x58, 0xf5, 0x44, 0x28, 0x18, 0x0a, + 0x09, 0x4c, 0x98, 0xb2, 0x94, 0xaf, 0x47, 0x4e, 0x59, 0x0e, 0x0a, 0x20, + 0xc9, 0x2b, 0x1d, 0x85, 0x2c, 0x96, 0x44, 0xa6, 0xc8, 0x08, 0x5d, 0x57, + 0x7a, 0x43, 0x7a, 0xad, 0xb5, 0xad, 0x45, 0xa8, 0x6a, 0xc2, 0x6a, 0x3b, + 0xd4, 0x65, 0x8c, 0xab, 0x55, 0x42, 0x53, 0x45, 0x25, 0x67, 0x03, 0xf4, + 0xbf, 0x07, 0x2f, 0xd4, 0xf9, 0x4d, 0x1d, 0x10, 0x00, 0x00, 0x21, 0x4c, + 0x40, 0xad, 0x05, 0x01, 0x00, 0x02, 0x59, 0x93, 0xcc, 0xb7, 0x19, 0xb7, + 0x39, 0x68, 0x00, 0x00, 0x0c, 0x00, 0x02, 0x88, 0x60, 0x01, 0x40, 0x0c, + 0x00, 0x21, 0xd1, 0x0e, 0x9a, 0x88, 0x02, 0x88, 0xd6, 0x49, 0x33, 0x6a, + 0xef, 0xb7, 0x71, 0xb2, 0x6b, 0xbb, 0xf3, 0xfd, 0x9d, 0x8e, 0x1d, 0x2d, + 0xb2, 0xca, 0xb4, 0x74, 0xa5, 0x8c, 0x43, 0x36, 0xbc, 0x5a, 0xb1, 0x68, + 0xe7, 0xaa, 0x39, 0xeb, 0x37, 0x3d, 0x65, 0xe5, 0xaa, 0x31, 0xaa, 0x8a, + 0xc8, 0x10, 0xa8, 0xd9, 0x1b, 0x63, 0x08, 0x50, 0xb2, 0x50, 0x66, 0x99, + 0x10, 0xd5, 0x8c, 0x90, 0xf4, 0x61, 0x9a, 0x41, 0x29, 0x98, 0x5a, 0xa0, + 0xc9, 0xd4, 0x57, 0x3f, 0x4e, 0xb9, 0xba, 0x77, 0xcf, 0xae, 0xd4, 0xba, + 0x45, 0xa5, 0x83, 0xd1, 0x40, 0x2d, 0x14, 0x24, 0x50, 0x50, 0x10, 0xe8, + 0xa7, 0x4a, 0x0b, 0x28, 0xf4, 0xf1, 0xf3, 0xbf, 0xaf, 0xfc, 0xa4, 0xb5, + 0x80, 0x28, 0x80, 0x04, 0x31, 0x05, 0x84, 0x14, 0x00, 0x86, 0x20, 0x00, + 0x10, 0x54, 0xa4, 0xbb, 0x18, 0xd3, 0xcf, 0x0d, 0x18, 0x02, 0x03, 0x01, + 0x80, 0xd4, 0x00, 0x01, 0x80, 0x2b, 0x1c, 0x03, 0x1a, 0xb1, 0x96, 0x1d, + 0x5b, 0x7d, 0x32, 0xf7, 0xda, 0xee, 0xdb, 0xd9, 0x5e, 0x92, 0xe9, 0x56, + 0x00, 0x20, 0x82, 0x90, 0x4a, 0x91, 0x08, 0x42, 0x22, 0xb1, 0x44, 0xb1, + 0x84, 0x53, 0x9b, 0x97, 0x86, 0xf1, 0xf1, 0xde, 0x0e, 0x1d, 0x39, 0xbe, + 0x6e, 0x9c, 0xbf, 0x37, 0x5c, 0x5c, 0xf5, 0x4c, 0xb4, 0xe5, 0x08, 0x84, + 0x47, 0x24, 0x2c, 0xd3, 0x23, 0x35, 0xd4, 0x89, 0x0c, 0x70, 0x29, 0x00, + 0x42, 0xcd, 0x51, 0x1d, 0x6b, 0x0f, 0x7f, 0x56, 0x1d, 0x7a, 0xab, 0xc6, + 0x85, 0x54, 0x40, 0x20, 0x10, 0x0a, 0x0d, 0x43, 0x45, 0x93, 0xcd, 0x95, + 0x85, 0x2a, 0x00, 0x06, 0x8e, 0xde, 0x1f, 0xea, 0x3f, 0x3b, 0x8b, 0xe9, + 0x7c, 0xc0, 0x11, 0x00, 0x28, 0x80, 0x50, 0x02, 0x00, 0x40, 0x54, 0x00, + 0x58, 0x80, 0x60, 0x85, 0x59, 0x26, 0xfe, 0x3c, 0xad, 0x99, 0x9b, 0x56, + 0x4d, 0x4d, 0x5c, 0x3b, 0x1a, 0x21, 0x59, 0x14, 0x88, 0x80, 0x42, 0x00, + 0x1c, 0xa1, 0x25, 0xe8, 0x35, 0xea, 0xdb, 0xf5, 0xab, 0xeb, 0x9b, 0xec, + 0x2c, 0xea, 0x52, 0x48, 0x90, 0xd5, 0xa0, 0xac, 0x42, 0x44, 0x02, 0x55, + 0x08, 0x89, 0x1a, 0x51, 0x1a, 0x51, 0x18, 0x8d, 0xb1, 0x22, 0x42, 0x22, + 0x46, 0x20, 0xb1, 0x8a, 0xe5, 0xe7, 0xf9, 0xba, 0x71, 0x7c, 0x5d, 0xb8, + 0x3e, 0x0f, 0x46, 0x1e, 0x5b, 0xa2, 0x2b, 0x8a, 0xb2, 0x8c, 0x2c, 0xd5, + 0x91, 0x2c, 0xcb, 0x74, 0x78, 0x02, 0x95, 0x64, 0xb2, 0x8c, 0xab, 0x2c, + 0xfe, 0x8e, 0xfc, 0xbe, 0xbe, 0xfa, 0xf3, 0xb0, 0x50, 0x80, 0x04, 0x00, + 0x10, 0x05, 0x85, 0x03, 0x51, 0x0a, 0x11, 0x00, 0xe8, 0x8b, 0x36, 0x75, + 0xca, 0xfb, 0xbf, 0x1b, 0x97, 0xf6, 0xfe, 0x20, 0x88, 0x04, 0x02, 0x01, + 0x00, 0x90, 0xa0, 0x11, 0x50, 0x24, 0x74, 0xc6, 0x4c, 0xdd, 0x2f, 0x73, + 0x37, 0xb5, 0x9b, 0xd6, 0xcd, 0xeb, 0xe3, 0x5d, 0x1c, 0xdd, 0x35, 0x69, + 0x61, 0x2b, 0x12, 0xc4, 0x44, 0x48, 0x15, 0x99, 0xcc, 0xb2, 0x62, 0xb3, + 0x0a, 0x74, 0xb7, 0xcb, 0x2b, 0x36, 0x2f, 0x75, 0xaf, 0x4b, 0x37, 0xdc, + 0x5b, 0x49, 0x96, 0x12, 0x26, 0x48, 0x99, 0x22, 0x50, 0xc1, 0x5a, 0x21, + 0x01, 0x11, 0x11, 0x22, 0x44, 0x89, 0x05, 0x8a, 0x42, 0x58, 0x11, 0x20, + 0x41, 0x62, 0x42, 0x48, 0x2c, 0x25, 0x89, 0x02, 0x31, 0x02, 0x9c, 0xde, + 0x0f, 0x83, 0xd1, 0xe6, 0x7e, 0x57, 0xaf, 0x0f, 0x9f, 0x74, 0xc4, 0x22, + 0x04, 0x30, 0x8e, 0x6c, 0xe2, 0x7a, 0x10, 0xaa, 0x02, 0x8c, 0xb0, 0x73, + 0x57, 0xd3, 0xd5, 0xce, 0xe9, 0xef, 0x4a, 0x4a, 0x64, 0x50, 0x01, 0x0e, + 0x80, 0xa1, 0x0a, 0x20, 0xa2, 0x8d, 0x1e, 0xa1, 0x60, 0x10, 0x43, 0x1a, + 0xdf, 0xed, 0xe2, 0x8e, 0x6f, 0xd3, 0xf9, 0x9c, 0x8f, 0xaf, 0xf0, 0xd2, + 0x2a, 0x42, 0x10, 0x84, 0x02, 0xa4, 0x24, 0x29, 0x05, 0x8c, 0x91, 0xd0, + 0x97, 0xd6, 0xe2, 0xfa, 0x2c, 0xdf, 0x51, 0x8d, 0x74, 0xc9, 0x00, 0xd4, + 0x46, 0xa2, 0x32, 0x54, 0xc9, 0x8c, 0x95, 0x48, 0x9a, 0x4a, 0x26, 0x4e, + 0xd9, 0xc4, 0xea, 0xc8, 0xb1, 0x2c, 0x2c, 0x2c, 0x2c, 0x2c, 0xa9, 0xc5, + 0x89, 0x35, 0xb2, 0x27, 0x53, 0x89, 0x12, 0x24, 0x8e, 0x50, 0x48, 0x95, + 0x11, 0x11, 0x14, 0x85, 0x41, 0x60, 0x40, 0x81, 0x02, 0xb2, 0x12, 0xd6, + 0x56, 0x40, 0xac, 0x8a, 0xc0, 0x84, 0x41, 0x60, 0x42, 0x22, 0x40, 0xcb, + 0xcf, 0x5c, 0x6f, 0x9f, 0xe8, 0xaf, 0x35, 0xea, 0x4b, 0x59, 0x95, 0x1a, + 0x8f, 0x40, 0x8d, 0x53, 0x19, 0x39, 0x6b, 0xe2, 0xde, 0xb9, 0xe7, 0xfa, + 0xf3, 0xa3, 0x2d, 0x5e, 0x5f, 0x6f, 0xa7, 0xf8, 0x3f, 0x72, 0xfe, 0x5b, + 0x96, 0x6c, 0x95, 0xe6, 0xb4, 0x21, 0xda, 0xe8, 0x1e, 0xe3, 0xa3, 0x51, + 0xee, 0x3a, 0x34, 0x76, 0x3d, 0x49, 0x58, 0x05, 0x34, 0x74, 0x27, 0xec, + 0x4f, 0xd2, 0x7e, 0x61, 0x45, 0x36, 0x73, 0xba, 0x63, 0x31, 0x85, 0x38, + 0xd5, 0xc6, 0xb3, 0xcd, 0x6a, 0x79, 0x5d, 0x4f, 0x1c, 0x73, 0xf3, 0x22, + 0x91, 0xa8, 0xd8, 0x0d, 0x2d, 0x5f, 0x63, 0xce, 0xfb, 0xae, 0x7d, 0x3d, + 0x24, 0xb2, 0x82, 0x84, 0x60, 0x31, 0x8d, 0x5a, 0x0b, 0x22, 0x55, 0x22, + 0x43, 0xb2, 0x44, 0xc9, 0xc4, 0xea, 0xc2, 0x72, 0x59, 0x56, 0xcb, 0x61, + 0x6a, 0x5b, 0x56, 0x25, 0xa5, 0x85, 0xb1, 0x61, 0x6c, 0x59, 0x6d, 0x91, + 0x61, 0x32, 0x65, 0x91, 0x64, 0x4c, 0x48, 0xa5, 0x55, 0x12, 0x04, 0x48, + 0x24, 0x0a, 0xd6, 0xaa, 0xae, 0x48, 0x5b, 0x52, 0x57, 0x6d, 0x71, 0x51, + 0x59, 0x55, 0xb5, 0xc5, 0x64, 0x08, 0x4b, 0x12, 0xb2, 0x05, 0x64, 0x0a, + 0xe5, 0x84, 0x41, 0x63, 0x11, 0x48, 0xda, 0x51, 0x45, 0x02, 0x11, 0xf0, + 0xae, 0x7b, 0xcd, 0xe9, 0xe3, 0xed, 0xf1, 0xaf, 0x49, 0x8d, 0xcf, 0xcb, + 0xeb, 0xe4, 0xf9, 0x3d, 0x5c, 0x6f, 0x1f, 0xb3, 0x87, 0xe4, 0xf5, 0xe7, + 0xe3, 0xa2, 0x1c, 0xae, 0x9d, 0x14, 0xf7, 0x25, 0xb8, 0xf7, 0x99, 0x75, + 0xcd, 0xbd, 0x67, 0x7b, 0xd5, 0xc3, 0xd4, 0xf7, 0xf3, 0xfa, 0xbd, 0xf9, + 0xfb, 0xbd, 0x79, 0x75, 0x6f, 0x3b, 0xb7, 0x2c, 0xb9, 0xda, 0xcd, 0xfa, + 0xcf, 0x5b, 0x9e, 0x00, 0x00, 0x00, 0x00, 0x2b, 0xd6, 0x78, 0xfe, 0x8c, + 0x78, 0x7e, 0x97, 0xc4, 0x49, 0xe1, 0x93, 0xc5, 0x59, 0x85, 0x9f, 0x71, + 0xcb, 0x7f, 0x46, 0xe5, 0xd3, 0xa2, 0x28, 0x40, 0x02, 0xa0, 0x63, 0x04, + 0x63, 0x56, 0x48, 0x91, 0x2a, 0x92, 0x4d, 0x67, 0x64, 0xcb, 0x22, 0xca, + 0xb0, 0xb4, 0xb4, 0xb5, 0x2d, 0x2c, 0x2d, 0x2e, 0x8b, 0x52, 0xe2, 0xe8, + 0xb5, 0x6e, 0x4b, 0x65, 0xb5, 0x2d, 0x5b, 0x22, 0x71, 0x25, 0x72, 0xb5, + 0x04, 0x80, 0x52, 0x48, 0xa4, 0x12, 0xb5, 0xaa, 0xaa, 0x2b, 0x2a, 0x2a, + 0x8a, 0xaa, 0xa2, 0xab, 0x69, 0x4a, 0x8a, 0x96, 0x9b, 0x2a, 0x58, 0x44, + 0x16, 0x11, 0x02, 0xa2, 0x16, 0xd7, 0x24, 0x25, 0xac, 0x81, 0x12, 0x22, + 0x55, 0x62, 0x50, 0x04, 0x7c, 0xbf, 0x9e, 0xfd, 0x57, 0xa7, 0x9f, 0xa7, + 0xe5, 0x58, 0xd6, 0x45, 0xb6, 0x5a, 0x72, 0xbc, 0xde, 0xcf, 0x2b, 0xf3, + 0xbe, 0x8f, 0x8f, 0xf9, 0xdf, 0x47, 0x37, 0x3d, 0x14, 0xfa, 0x66, 0x7d, + 0xb1, 0xea, 0x7d, 0xfe, 0x6f, 0xa0, 0x7a, 0x7c, 0x5e, 0xc3, 0xbf, 0x9f, + 0xd8, 0xf4, 0xf2, 0xf4, 0xb3, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x04, 0x9c, 0xcf, 0x4f, 0x3f, 0x3f, 0xb7, 0x27, 0x2e, 0x6e, + 0x6f, 0x08, 0xd7, 0x8b, 0x9a, 0x5a, 0xa1, 0x08, 0x4a, 0x02, 0x00, 0x3a, + 0x21, 0xd3, 0x89, 0x53, 0x26, 0x4a, 0xa4, 0x58, 0x93, 0x2c, 0xab, 0x4b, + 0x0b, 0x8b, 0x92, 0xd2, 0xd2, 0xd2, 0xf2, 0xe2, 0xe8, 0xb8, 0xbe, 0x2e, + 0x4b, 0xe5, 0xb8, 0xbc, 0xb6, 0x27, 0x34, 0xe5, 0x14, 0x00, 0x00, 0x00, + 0x00, 0x44, 0x89, 0x2b, 0xb2, 0xb2, 0xa2, 0xa2, 0xaa, 0xa6, 0x2a, 0xaa, + 0x4c, 0xeb, 0x41, 0x55, 0x53, 0x54, 0xc5, 0x55, 0x5c, 0x56, 0xb0, 0x20, + 0x56, 0x54, 0xb5, 0xc4, 0x0a, 0xe2, 0x35, 0x08, 0x56, 0xc5, 0x12, 0xa0, + 0x11, 0xf2, 0x19, 0xaf, 0xab, 0xeb, 0x1a, 0xa6, 0x98, 0xcb, 0x4b, 0xac, + 0xd1, 0x66, 0x9d, 0x35, 0xd5, 0xed, 0x79, 0x1f, 0x9d, 0xf5, 0x3c, 0x8f, + 0x9f, 0xd7, 0xf4, 0x4f, 0x67, 0x87, 0xe8, 0xfe, 0x8f, 0x17, 0x6b, 0x3c, + 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, + 0x27, 0x13, 0xd7, 0xcb, 0xcd, 0xaf, 0x2f, 0x37, 0x06, 0x59, 0x25, 0xcb, + 0x9b, 0x44, 0x40, 0x42, 0x05, 0x00, 0x11, 0x85, 0x38, 0x75, 0x22, 0x44, + 0xc9, 0x54, 0xcb, 0x12, 0xc2, 0xda, 0xb4, 0xb8, 0xb9, 0x2d, 0x2e, 0x2e, + 0x2e, 0x8b, 0xd7, 0x41, 0x7c, 0x9a, 0x0b, 0xe2, 0xf8, 0xbd, 0x2e, 0x5b, + 0x65, 0x94, 0xd0, 0xa0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x24, 0x8d, + 0xcc, 0x22, 0xa2, 0x9a, 0xa4, 0xa4, 0xcf, 0x6e, 0x72, 0x82, 0x82, 0x9a, + 0xa8, 0xa2, 0xaa, 0x29, 0x96, 0xb4, 0x8a, 0xc2, 0x5a, 0xac, 0xaa, 0x5a, + 0xc8, 0x10, 0x20, 0x44, 0x8a, 0xc4, 0x42, 0x03, 0xe4, 0xd6, 0xfd, 0x6a, + 0x49, 0x82, 0xcd, 0x2e, 0xab, 0xeb, 0x45, 0x9a, 0xab, 0x7e, 0xa7, 0x77, + 0x6f, 0x47, 0xcb, 0x3a, 0xf8, 0xec, 0x50, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0c, 0xfd, 0x39, 0x79, 0x5f, + 0x4c, 0xe0, 0x62, 0xf3, 0x71, 0x71, 0x4b, 0x92, 0x5c, 0xf9, 0xb5, 0xc2, + 0xa5, 0x00, 0x0c, 0x04, 0x3b, 0x18, 0xc9, 0x2c, 0xd2, 0x75, 0x2a, 0xb1, + 0x2c, 0x5b, 0x6a, 0xe2, 0xe2, 0xe4, 0xb8, 0xb8, 0xb8, 0xbd, 0x2e, 0x97, + 0x44, 0x69, 0x34, 0xc6, 0x94, 0xd0, 0x5d, 0x17, 0x16, 0xc4, 0xa6, 0xc5, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0xca, 0xb1, 0x49, 0x0a, 0xac, + 0x81, 0x49, 0x9e, 0xdc, 0xf1, 0x49, 0x45, 0x50, 0x50, 0x51, 0x54, 0x94, + 0x94, 0x15, 0x15, 0xac, 0x22, 0x0b, 0x51, 0x59, 0x59, 0x59, 0x02, 0x04, + 0x48, 0xaa, 0x10, 0xa3, 0xe6, 0x3b, 0xbf, 0x52, 0xc9, 0x8c, 0xb2, 0xcb, + 0x8d, 0x15, 0xa6, 0xcd, 0x95, 0xd8, 0xe9, 0x3d, 0x2e, 0xb3, 0xd4, 0xf3, + 0xae, 0xc5, 0x73, 0x42, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x08, 0x0a, 0xe6, 0x9d, 0xe3, 0x83, 0xea, 0x9e, 0x4f, + 0x9e, 0xb9, 0x58, 0xb8, 0x65, 0xc9, 0x2e, 0x78, 0xab, 0x35, 0x08, 0x00, + 0x60, 0x00, 0x3a, 0x91, 0x22, 0x45, 0x96, 0x4e, 0xac, 0x2d, 0x2d, 0x2e, + 0x4b, 0xcb, 0xaa, 0xe2, 0xf2, 0xf2, 0xf8, 0xd0, 0x68, 0x8d, 0x06, 0x94, + 0xd5, 0x1a, 0x0b, 0x89, 0xc9, 0x35, 0x70, 0xd5, 0xcd, 0x30, 0x05, 0x12, + 0x36, 0x08, 0x86, 0x4a, 0x68, 0x23, 0x73, 0x1b, 0x20, 0x8a, 0x55, 0x4a, + 0x20, 0x42, 0xa8, 0x29, 0x2a, 0x5a, 0x4a, 0x4a, 0x22, 0x9a, 0xa2, 0x5c, + 0xf6, 0x50, 0xb4, 0x94, 0xa5, 0x2b, 0x5d, 0x28, 0xa8, 0xa9, 0x6a, 0x2b, + 0x2b, 0x20, 0x45, 0x62, 0x44, 0x44, 0x72, 0xf9, 0xf7, 0x5b, 0xf4, 0x7c, + 0x02, 0x45, 0xb6, 0x5c, 0x68, 0xb3, 0x55, 0x74, 0xb7, 0x3d, 0x1f, 0x4c, + 0xf7, 0x13, 0x57, 0x15, 0xfc, 0xeb, 0x51, 0x1c, 0xae, 0x56, 0xa0, 0x28, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x91, 0xb9, 0x8d, 0xc4, 0x68, + 0x48, 0xe9, 0x9b, 0xac, 0xe5, 0x74, 0x79, 0x5e, 0x7b, 0xe2, 0xe6, 0xe1, + 0xcd, 0xc9, 0x2e, 0x7c, 0xda, 0x61, 0x08, 0x04, 0x30, 0x56, 0x08, 0xc6, + 0x4a, 0xa6, 0x58, 0x59, 0x56, 0x59, 0x69, 0x7d, 0x5e, 0x5c, 0x97, 0x97, + 0x97, 0xc6, 0x83, 0x41, 0xa2, 0x5d, 0x09, 0xa0, 0xd0, 0x5f, 0x25, 0xd5, + 0x71, 0x64, 0x92, 0xb4, 0x48, 0x84, 0x03, 0xb4, 0x84, 0x99, 0x96, 0x02, + 0x24, 0x5d, 0x9a, 0x54, 0x6c, 0x07, 0x0e, 0x90, 0x11, 0x4a, 0x65, 0xac, + 0xae, 0xda, 0xa2, 0xa2, 0x92, 0xa8, 0xa6, 0xda, 0x22, 0x82, 0x92, 0x8a, + 0xa4, 0xa0, 0xa4, 0xa8, 0x52, 0xd2, 0x52, 0x56, 0x57, 0x50, 0x20, 0xb1, + 0x22, 0x06, 0x7c, 0x5f, 0x27, 0xd9, 0xed, 0xf0, 0x09, 0x96, 0x59, 0x79, + 0xa2, 0xcd, 0x9a, 0x76, 0x37, 0x3d, 0x2f, 0x4c, 0x74, 0x92, 0xfc, 0x54, + 0x32, 0x71, 0x2c, 0xa7, 0x17, 0x73, 0x4f, 0x3b, 0x6d, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x26, 0x6b, 0xdf, 0x2c, 0xfd, 0x25, 0x5b, 0x57, + 0xa5, 0x7a, 0x53, 0x5c, 0xf3, 0xcd, 0xf3, 0xdf, 0x13, 0x1a, 0xc1, 0x96, + 0x49, 0x68, 0x8a, 0xa5, 0x84, 0x20, 0x10, 0x29, 0x0e, 0x9c, 0x3b, 0x24, + 0x48, 0xb0, 0x9d, 0x59, 0x56, 0xa5, 0xd5, 0x79, 0xa2, 0xae, 0x4d, 0x06, + 0x83, 0x44, 0x68, 0x34, 0x46, 0x85, 0xbd, 0x2e, 0x2e, 0x2e, 0x4b, 0x2a, + 0x43, 0x24, 0x22, 0x23, 0x04, 0x8c, 0xb5, 0x04, 0x50, 0xb9, 0xa5, 0x66, + 0xa4, 0xd1, 0x57, 0xd3, 0x47, 0x50, 0x10, 0xc2, 0x33, 0x91, 0x84, 0x41, + 0x6b, 0x2a, 0x8a, 0x8a, 0xa2, 0x9b, 0x6a, 0x8a, 0x56, 0x82, 0x83, 0x39, + 0x41, 0x49, 0x49, 0x02, 0xb5, 0xa4, 0xac, 0xad, 0x2b, 0x58, 0x10, 0xa8, + 0x8d, 0x79, 0xf8, 0xbc, 0x9e, 0xb3, 0xd3, 0xe4, 0x44, 0xaa, 0xc2, 0xeb, + 0x35, 0x59, 0xbf, 0x4e, 0xf7, 0x4c, 0xf7, 0x37, 0x9d, 0x56, 0x29, 0x6d, + 0xb2, 0xd5, 0x69, 0x64, 0x5f, 0x86, 0x9e, 0x4d, 0x1c, 0xf6, 0xe6, 0xc0, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x23, 0x79, 0xe6, 0xeb, 0xcf, 0x1f, + 0x66, 0x5d, 0xb3, 0x15, 0x15, 0x99, 0xe5, 0xe1, 0x63, 0x5c, 0x1c, 0x5c, + 0x39, 0xb9, 0x33, 0x68, 0x8a, 0x96, 0xb8, 0x8c, 0x25, 0x10, 0x50, 0x64, + 0x86, 0x48, 0xb0, 0x99, 0x6d, 0x5b, 0x56, 0x97, 0x55, 0xf1, 0x76, 0xa6, + 0xb2, 0xf4, 0xbc, 0xd3, 0x1a, 0x0d, 0x05, 0xe5, 0xa9, 0x75, 0x58, 0x8c, + 0x44, 0x49, 0xad, 0xa6, 0xb1, 0xa4, 0x29, 0x45, 0x6b, 0x54, 0xb9, 0xb3, + 0x73, 0x15, 0x43, 0xb7, 0x53, 0x3a, 0xeb, 0x4a, 0x5b, 0x65, 0x8b, 0x3b, + 0x26, 0x48, 0xca, 0x65, 0x20, 0x54, 0x12, 0xd7, 0x10, 0x2a, 0x96, 0xa2, + 0xa2, 0x98, 0xa6, 0x5a, 0x0a, 0x17, 0x2c, 0xb9, 0x0c, 0x72, 0xe6, 0x33, + 0xd9, 0x1c, 0xd7, 0x6c, 0x08, 0x59, 0x14, 0x2a, 0x16, 0x40, 0x9a, 0xf1, + 0xb3, 0x5f, 0x59, 0xd8, 0xc9, 0x92, 0x2c, 0x2d, 0x4d, 0x3a, 0x9d, 0x3d, + 0xce, 0xee, 0xe7, 0x4b, 0x59, 0xb6, 0xad, 0x4b, 0xd6, 0x65, 0xb6, 0x69, + 0x35, 0x61, 0xaf, 0x8d, 0xd1, 0xcb, 0x6d, 0xa0, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x85, 0xe7, 0x97, 0xb7, 0x3c, 0x5d, 0x98, 0xf4, 0xc7, 0x2e, + 0x58, 0xa4, 0xac, 0xa8, 0xe6, 0x66, 0xf0, 0x71, 0xae, 0x7e, 0x6e, 0x4c, + 0xda, 0x65, 0xaa, 0x2b, 0x22, 0x29, 0x50, 0x08, 0x22, 0x0b, 0xce, 0x2c, + 0xe7, 0xbd, 0x55, 0x32, 0x75, 0x32, 0xd2, 0x64, 0x96, 0xcb, 0x37, 0x59, + 0xa4, 0xd6, 0x6b, 0x37, 0x46, 0xab, 0x3a, 0x56, 0x6d, 0xde, 0x15, 0x90, + 0x24, 0x4a, 0xad, 0x2f, 0x34, 0xa6, 0xba, 0xd9, 0x99, 0x12, 0xbd, 0x2a, + 0x96, 0x99, 0x72, 0xe6, 0xe0, 0x97, 0x24, 0xbc, 0xf9, 0x6f, 0x8e, 0xd6, + 0xb3, 0xbb, 0x52, 0xea, 0xb6, 0xcb, 0xac, 0x91, 0x55, 0x62, 0x88, 0x08, + 0x52, 0xe7, 0x28, 0x28, 0x85, 0x2e, 0x6c, 0x6f, 0x99, 0xc7, 0xb6, 0x2c, + 0xef, 0x06, 0xb9, 0xe7, 0xde, 0x39, 0xf2, 0xd4, 0x09, 0x0a, 0x85, 0x8c, + 0xca, 0x52, 0x46, 0x5a, 0x8a, 0x65, 0xcf, 0x2d, 0x2b, 0xc5, 0xb9, 0xdf, + 0xb8, 0xf1, 0xbe, 0xd7, 0x5c, 0xf4, 0x58, 0x91, 0x2b, 0x2c, 0x2d, 0x34, + 0xea, 0x74, 0xf5, 0x3a, 0xfb, 0x9a, 0xac, 0xaf, 0xc9, 0xd2, 0xbf, 0x9d, + 0xda, 0x1c, 0x35, 0x77, 0xa3, 0x1d, 0xff, 0x00, 0xad, 0xe7, 0xec, 0x7a, + 0xb1, 0xb3, 0x2d, 0xbc, 0x1a, 0x79, 0x74, 0x73, 0x40, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x01, 0x5e, 0xb9, 0x60, 0xf4, 0x63, 0x95, 0xd5, 0xcb, 0xc5, + 0xc3, 0x2e, 0x58, 0xa8, 0xae, 0xa0, 0x63, 0x97, 0x8b, 0x8d, 0x73, 0xb3, + 0x73, 0x66, 0xd2, 0x57, 0x10, 0x96, 0x04, 0x48, 0xc5, 0x33, 0x44, 0xb9, + 0xcc, 0x19, 0xa4, 0xbe, 0x82, 0x69, 0x75, 0xe5, 0x32, 0x75, 0x34, 0x95, + 0xba, 0x6c, 0xb9, 0x6d, 0x4b, 0xaa, 0xe2, 0x50, 0x2c, 0x86, 0x55, 0x73, + 0xd4, 0xcd, 0xe9, 0xaf, 0x46, 0xce, 0xb6, 0xf1, 0xaf, 0x59, 0xd1, 0x57, + 0x17, 0x1a, 0x52, 0x7c, 0xb5, 0x8b, 0x87, 0x6e, 0x6c, 0xdf, 0x1b, 0x3a, + 0xe4, 0xe7, 0x5c, 0xe9, 0x79, 0xb1, 0x52, 0x70, 0x71, 0x54, 0xbe, 0x93, + 0xa6, 0x6c, 0x5b, 0x26, 0xb4, 0xd9, 0xd9, 0xd4, 0xdf, 0xbc, 0x74, 0x75, + 0x35, 0xf4, 0xe7, 0xab, 0xaf, 0x12, 0xca, 0x25, 0xa4, 0xae, 0x5f, 0x25, + 0xe0, 0xfa, 0x5e, 0x0b, 0xe5, 0xfd, 0x7f, 0x3f, 0xe4, 0xf5, 0xd5, 0x8a, + 0x13, 0xde, 0x7a, 0xbe, 0xef, 0x9f, 0xe8, 0x7e, 0xaf, 0xc6, 0x9f, 0x4e, + 0x35, 0x54, 0x08, 0x11, 0x30, 0x92, 0x32, 0x90, 0x29, 0xa8, 0x26, 0x79, + 0xae, 0x07, 0x97, 0xbf, 0x88, 0xf5, 0x79, 0xe5, 0x9d, 0x3d, 0xba, 0xfc, + 0xba, 0x7a, 0xec, 0xde, 0x8d, 0x97, 0xeb, 0x3d, 0x2e, 0x98, 0xe8, 0x74, + 0xc7, 0x4b, 0x73, 0x7f, 0x1b, 0xcc, 0xfc, 0x77, 0xd2, 0xcd, 0xf2, 0xfb, + 0x91, 0x1d, 0x66, 0x5e, 0x9e, 0x7d, 0x2f, 0x67, 0x1f, 0x69, 0xfa, 0x1f, + 0x27, 0x7f, 0xed, 0xf9, 0xfa, 0x39, 0x74, 0x3c, 0xda, 0xb3, 0x3d, 0x00, + 0x00, 0x00, 0x00, 0x32, 0xe3, 0x5a, 0xb7, 0x90, 0x84, 0xd3, 0x48, 0xef, + 0x8f, 0x13, 0xd7, 0x8e, 0x42, 0xf3, 0xf3, 0x71, 0x46, 0x45, 0xcb, 0x19, + 0x8a, 0x25, 0xce, 0x73, 0xe5, 0xe6, 0xcc, 0xe5, 0xce, 0xa1, 0x9d, 0x57, + 0x2d, 0x59, 0xd6, 0x39, 0x79, 0xf9, 0xd6, 0x69, 0xaa, 0x8e, 0x5c, 0xb2, + 0xb2, 0x3b, 0xc6, 0xeb, 0x9f, 0x71, 0xcf, 0xa4, 0x3a, 0x73, 0x8d, 0x4c, + 0xba, 0xb4, 0x59, 0x71, 0x69, 0x60, 0xd6, 0x51, 0xa2, 0xb8, 0xbd, 0x79, + 0x79, 0x0f, 0x4f, 0x1e, 0x6e, 0xf1, 0x59, 0x29, 0x7d, 0x2f, 0x3e, 0x9f, + 0x48, 0xf2, 0xfa, 0x3a, 0xf8, 0xd6, 0xcb, 0x9e, 0xf6, 0xf1, 0xb3, 0x97, + 0x5e, 0x3f, 0x1e, 0xbe, 0x43, 0xcd, 0xdf, 0xcf, 0x4d, 0x67, 0xeb, 0xc3, + 0x16, 0xb3, 0x87, 0x53, 0x66, 0xb9, 0xca, 0xce, 0x55, 0x5e, 0x69, 0x8e, + 0x7d, 0x48, 0xb9, 0x39, 0xbe, 0x6f, 0x47, 0x33, 0xa6, 0x3b, 0x5d, 0x79, + 0x76, 0x57, 0x42, 0xe9, 0xce, 0xf7, 0x73, 0xe9, 0xe8, 0xab, 0xa6, 0x6d, + 0xef, 0xe7, 0xe3, 0xf3, 0xf4, 0x7c, 0xbf, 0xf3, 0x9f, 0xa8, 0xcb, 0x8b, + 0x46, 0x15, 0x64, 0xf4, 0x9e, 0xb2, 0xa5, 0xe9, 0xfd, 0x0f, 0x9d, 0xea, + 0xbe, 0xdf, 0xc1, 0xa6, 0x0b, 0x29, 0x15, 0x61, 0x2a, 0x89, 0x99, 0x6c, + 0x8d, 0x52, 0x07, 0x23, 0x8f, 0x5f, 0x9e, 0xf5, 0xe7, 0x9e, 0xc7, 0x0a, + 0x5b, 0x6b, 0x5c, 0x74, 0xe5, 0xdd, 0x9d, 0xfa, 0x05, 0xf4, 0x9a, 0x9d, + 0x2f, 0x97, 0xd5, 0x7e, 0x3b, 0xe8, 0x31, 0x5c, 0xc7, 0xae, 0x5f, 0x7e, + 0x7b, 0xfd, 0x3c, 0xbd, 0x87, 0xab, 0x9f, 0xac, 0xfd, 0xa7, 0xce, 0xe9, + 0x4b, 0xd2, 0xf2, 0xf4, 0x94, 0xd0, 0x00, 0x00, 0x00, 0x67, 0xcd, 0xd1, + 0xa8, 0x00, 0x26, 0x6b, 0x79, 0x55, 0xcf, 0xb3, 0x87, 0xbc, 0xf2, 0x65, + 0xa2, 0xb2, 0xeb, 0x38, 0x0c, 0x71, 0x52, 0xd6, 0xe5, 0xc9, 0xe9, 0xe0, + 0xe1, 0x65, 0x9b, 0x1a, 0x9c, 0xeb, 0x57, 0x3f, 0x5f, 0x9a, 0xcf, 0x6c, + 0x6b, 0x39, 0x76, 0xf3, 0xe9, 0x6e, 0x77, 0x54, 0x57, 0x65, 0xe7, 0x7f, + 0x19, 0xf4, 0x3d, 0xf3, 0x5e, 0xf1, 0x6d, 0x59, 0x4d, 0x2e, 0xb6, 0x69, + 0x25, 0xb4, 0xd3, 0x65, 0xd0, 0xcf, 0x95, 0x7b, 0xbc, 0x99, 0x3a, 0x62, + 0x4b, 0x08, 0x92, 0xeb, 0x8f, 0x59, 0xc7, 0xb7, 0xd3, 0x3c, 0x7e, 0x89, + 0xd9, 0xaf, 0x3a, 0xc1, 0x35, 0xe5, 0xf8, 0xf4, 0xf9, 0xdf, 0x87, 0xd5, + 0x9f, 0x78, 0xf4, 0x3e, 0xcf, 0x2e, 0xfd, 0xe3, 0x0d, 0xcd, 0x4a, 0x93, + 0x12, 0x74, 0xab, 0x2c, 0x54, 0x5c, 0x4e, 0xce, 0x3f, 0x0e, 0xf8, 0xfb, + 0x73, 0xf5, 0x1a, 0xc5, 0xf2, 0xe5, 0xaa, 0xcd, 0x6b, 0xf4, 0x49, 0x7b, + 0xb2, 0xc2, 0x5c, 0x39, 0xed, 0xf3, 0x3f, 0xcd, 0xfe, 0x9f, 0x34, 0x66, + 0xc2, 0x18, 0xb2, 0xdc, 0xb3, 0x72, 0x39, 0x6b, 0xf6, 0x78, 0xfd, 0x87, + 0xde, 0xfc, 0xec, 0x6c, 0xae, 0xa0, 0x91, 0x5a, 0x0a, 0x52, 0xa5, 0x69, + 0x4d, 0x56, 0x94, 0xda, 0xb9, 0x75, 0xf9, 0x96, 0xb9, 0xf2, 0xec, 0xbb, + 0x52, 0x51, 0x12, 0x42, 0x95, 0xcb, 0x0c, 0x6b, 0xb1, 0xac, 0xfb, 0x5f, + 0x8f, 0xe9, 0xf6, 0x5f, 0x93, 0xfa, 0x12, 0x92, 0x1b, 0x90, 0xde, 0x5f, + 0x7c, 0x6d, 0xf4, 0x72, 0xf6, 0x1e, 0xae, 0x5e, 0x97, 0xf6, 0x5e, 0x1e, + 0x87, 0x2d, 0xef, 0xe5, 0xbe, 0x84, 0xb7, 0x5c, 0xbb, 0x00, 0x00, 0x01, + 0x1e, 0x44, 0x8e, 0xa5, 0x57, 0x39, 0x56, 0x0c, 0xf2, 0xc6, 0x96, 0x6e, + 0x52, 0x72, 0xf3, 0x7e, 0x35, 0xcf, 0xae, 0x79, 0x77, 0x69, 0xaa, 0xce, + 0xc7, 0x5f, 0x25, 0x3d, 0x7c, 0x1c, 0x2e, 0x7b, 0xcf, 0x9d, 0x25, 0xc6, + 0xdf, 0x93, 0xe7, 0xef, 0x42, 0x97, 0x57, 0x0f, 0x45, 0xdc, 0xba, 0xb8, + 0x8a, 0xdb, 0xd3, 0x9f, 0xb5, 0xd6, 0x7a, 0xdd, 0x39, 0xc7, 0x51, 0x12, + 0xab, 0x6c, 0xd0, 0x3a, 0xd0, 0x58, 0x05, 0x85, 0xb1, 0xf2, 0x3f, 0xa1, + 0xe3, 0x8e, 0xb3, 0x29, 0x6b, 0x25, 0x2e, 0xa3, 0xd9, 0x71, 0xed, 0xf4, + 0x8f, 0x1f, 0xa2, 0x83, 0xa1, 0x35, 0xd2, 0xb3, 0xd2, 0x5c, 0xf3, 0xeb, + 0xe6, 0x3e, 0x7e, 0xff, 0x00, 0x26, 0xe3, 0xbe, 0xaf, 0x4e, 0x4a, 0x34, + 0x59, 0x9f, 0x59, 0x31, 0xb9, 0xa3, 0x33, 0x2d, 0xa9, 0x0a, 0xe1, 0xe3, + 0x7a, 0xfa, 0x63, 0xa2, 0x55, 0x63, 0xaf, 0xa4, 0x6f, 0x1f, 0x65, 0xaa, + 0xab, 0x8b, 0x9b, 0xcc, 0x9a, 0xe6, 0xe3, 0xb7, 0xcc, 0x3f, 0x37, 0xfa, + 0x7c, 0xd9, 0x51, 0x84, 0x33, 0x67, 0xa9, 0x66, 0xa2, 0x96, 0xdf, 0x47, + 0x97, 0xd5, 0x7e, 0x8f, 0xf3, 0x71, 0x04, 0x74, 0x92, 0xba, 0x49, 0x59, + 0x49, 0x5d, 0x55, 0x48, 0x97, 0x3e, 0x9f, 0x37, 0xb8, 0xe5, 0xea, 0x55, + 0x63, 0x4a, 0x65, 0x64, 0x86, 0x4c, 0xb2, 0x3d, 0x57, 0xc6, 0xf5, 0x7d, + 0x1f, 0xf2, 0x7f, 0x42, 0x44, 0x6c, 0x86, 0xf2, 0x76, 0xc6, 0xaf, 0x47, + 0x3f, 0x5b, 0xea, 0xe5, 0xec, 0x7f, 0x55, 0xe1, 0xe9, 0xee, 0xf4, 0x63, + 0x24, 0x67, 0xb6, 0xb3, 0x44, 0xd6, 0xa2, 0xf2, 0x64, 0x0e, 0x6c, 0x53, + 0xbc, 0xf2, 0xab, 0x92, 0x9c, 0xb3, 0x99, 0x1c, 0xd3, 0x04, 0xb8, 0xe3, + 0x19, 0x51, 0xe2, 0xeb, 0xce, 0x92, 0x26, 0x9e, 0xb3, 0x7e, 0x4f, 0x53, + 0xdb, 0xc5, 0xc2, 0xc6, 0xe8, 0xce, 0xa2, 0xb9, 0x5a, 0xf1, 0xdc, 0xbe, + 0x80, 0x0b, 0x67, 0x3e, 0xba, 0xf9, 0x75, 0xab, 0x59, 0x76, 0x69, 0xb9, + 0xfa, 0x5c, 0xd5, 0x9d, 0x39, 0xba, 0x9d, 0x8c, 0x2a, 0xfa, 0x99, 0x3a, + 0xb0, 0xb0, 0x9c, 0x33, 0xe4, 0x1f, 0x43, 0xc5, 0x75, 0x84, 0xb5, 0x2c, + 0xe5, 0xd3, 0x1e, 0xd3, 0x8f, 0x6f, 0x7b, 0xe4, 0xf4, 0x44, 0xea, 0x4b, + 0xd7, 0x4f, 0x57, 0xac, 0xec, 0x93, 0x3b, 0x58, 0x6c, 0xf8, 0x56, 0x37, + 0xf3, 0xec, 0xc6, 0x66, 0x15, 0x97, 0xa6, 0x49, 0x72, 0x2d, 0x84, 0x25, + 0xe7, 0xe7, 0x5b, 0x77, 0x8d, 0x16, 0x7a, 0x3b, 0x3f, 0x43, 0x57, 0xad, + 0x9a, 0xba, 0xce, 0x54, 0xbc, 0x63, 0x9b, 0x9b, 0xce, 0xcf, 0x5f, 0x95, + 0x7e, 0x6b, 0xf5, 0x19, 0xa2, 0x8e, 0x68, 0xe6, 0xd9, 0xb9, 0x3d, 0x43, + 0x36, 0x5d, 0x78, 0x7b, 0x0f, 0xd4, 0x7e, 0x62, 0x29, 0x1a, 0x48, 0x91, + 0x15, 0x54, 0x4a, 0xca, 0x52, 0x15, 0x05, 0x31, 0xbf, 0x9c, 0xc7, 0x93, + 0xdf, 0x3d, 0xe5, 0x53, 0xab, 0x73, 0x2c, 0x99, 0x22, 0x65, 0xc9, 0xeb, + 0xfe, 0x27, 0xaf, 0xe8, 0x1f, 0x95, 0xfa, 0x12, 0xca, 0xbb, 0x21, 0xbc, + 0x9d, 0x71, 0xa7, 0xd1, 0xcf, 0xd3, 0x7a, 0xb9, 0xf2, 0x7f, 0x55, 0xe2, + 0x86, 0xc2, 0xf4, 0xed, 0xec, 0x1d, 0x83, 0xaf, 0x5d, 0x25, 0xd8, 0x97, + 0x52, 0x8c, 0xe9, 0xcd, 0xde, 0x39, 0xc7, 0x34, 0xe6, 0x9c, 0xf8, 0xe7, + 0x46, 0x05, 0xc5, 0x18, 0xa3, 0x3a, 0xf9, 0x7a, 0xf9, 0xb4, 0x02, 0xaf, + 0x79, 0xbf, 0x17, 0xb0, 0xeb, 0xe4, 0xe1, 0x63, 0x54, 0x67, 0x68, 0xce, + 0xbe, 0x2b, 0x97, 0xd2, 0x60, 0x63, 0xac, 0xf6, 0x31, 0x9e, 0x97, 0x37, + 0xea, 0x5c, 0x7b, 0x4b, 0xaf, 0x39, 0x12, 0xa9, 0x54, 0xac, 0xb5, 0x65, + 0x53, 0x49, 0x92, 0x27, 0x15, 0xd9, 0xf2, 0x4f, 0x7f, 0x93, 0x41, 0x12, + 0xa5, 0x9c, 0xba, 0x63, 0xdc, 0x70, 0xef, 0xed, 0xfc, 0xbd, 0xc3, 0xab, + 0x2f, 0x48, 0xeb, 0xd9, 0xd2, 0x5e, 0xd9, 0x6c, 0xae, 0xe7, 0xe6, 0x56, + 0x7e, 0x72, 0xe5, 0xbe, 0x06, 0x29, 0x2d, 0xfa, 0x93, 0x4c, 0xd9, 0xd3, + 0x28, 0x9a, 0xa4, 0xd9, 0xac, 0xfd, 0x8f, 0xaf, 0x2f, 0xbb, 0xea, 0x5d, + 0x2c, 0x26, 0xb4, 0x67, 0x59, 0x93, 0x81, 0x58, 0x63, 0x99, 0x9d, 0xfc, + 0x9b, 0xf3, 0x7f, 0xa9, 0xc9, 0x85, 0x18, 0x2c, 0xdb, 0x77, 0x27, 0xa8, + 0xb3, 0x4d, 0x73, 0xf5, 0xff, 0x00, 0xab, 0xfc, 0xa4, 0x04, 0x8a, 0x92, + 0x15, 0x58, 0x92, 0x25, 0x74, 0xaa, 0x21, 0xcb, 0xaf, 0xcc, 0xae, 0x7c, + 0xa6, 0xf1, 0xa2, 0x58, 0xa4, 0x80, 0x64, 0x89, 0x97, 0x9e, 0xcb, 0xe2, + 0x7a, 0xfd, 0xff, 0x00, 0xe5, 0x7d, 0xf2, 0xca, 0xb4, 0xaf, 0x79, 0x3a, + 0xe2, 0xfe, 0xf8, 0xf4, 0x1e, 0xae, 0x5c, 0x6f, 0xd5, 0x79, 0x2c, 0xeb, + 0x3a, 0x95, 0xd3, 0xb3, 0xa9, 0x5d, 0x3a, 0xe9, 0x1b, 0x8d, 0x49, 0x65, + 0x05, 0x27, 0x1a, 0xe7, 0x14, 0x61, 0x30, 0x98, 0x8c, 0x11, 0x86, 0x5c, + 0x66, 0x39, 0x72, 0x9c, 0xe3, 0xe3, 0x52, 0xa1, 0x9e, 0xf3, 0xa7, 0x87, + 0xd6, 0x74, 0xf2, 0x70, 0xf1, 0xd2, 0x89, 0xa0, 0xa0, 0xf1, 0x7c, 0xfe, + 0x92, 0x95, 0x98, 0xac, 0xcf, 0x52, 0x25, 0x67, 0xb5, 0xc5, 0xfa, 0x37, + 0x2f, 0x42, 0xeb, 0xca, 0x51, 0x2a, 0x74, 0x59, 0x35, 0xb2, 0xac, 0x49, + 0x12, 0x26, 0x65, 0xb3, 0xe5, 0x5e, 0xff, 0x00, 0x26, 0x98, 0x81, 0x54, + 0xb3, 0x97, 0x49, 0xee, 0xbc, 0xfe, 0x8f, 0x63, 0xe6, 0xed, 0x74, 0xbd, + 0x45, 0xe9, 0x47, 0x5a, 0xce, 0xba, 0xf5, 0xe5, 0x9a, 0xd8, 0xcc, 0x0e, + 0x36, 0xb3, 0xf9, 0xf2, 0x6b, 0xe3, 0xdc, 0xe8, 0x9b, 0xc7, 0x2b, 0x31, + 0x1d, 0x4a, 0xfd, 0x0d, 0xd3, 0x1f, 0x47, 0xb2, 0xc8, 0x6a, 0xb3, 0xad, + 0xb2, 0x67, 0x9b, 0xe2, 0x59, 0xc6, 0x4e, 0x7c, 0xdf, 0xc7, 0xff, 0x00, + 0x35, 0xfa, 0x9c, 0x5c, 0xd4, 0x73, 0x32, 0xce, 0x92, 0x62, 0xcd, 0x8b, + 0x3e, 0xc7, 0xf5, 0x9f, 0x94, 0x86, 0xb3, 0x12, 0x36, 0x20, 0x4a, 0x6a, + 0x42, 0xb2, 0x01, 0x62, 0xb6, 0x7c, 0xba, 0xfc, 0xde, 0xe3, 0xc6, 0xeb, + 0x3d, 0x99, 0xba, 0x18, 0xc4, 0x00, 0x22, 0x44, 0xcf, 0x67, 0xf0, 0xfd, + 0x7f, 0x46, 0xfc, 0xaf, 0xbd, 0xe6, 0xd5, 0x73, 0x0d, 0x65, 0x75, 0xcd, + 0xdd, 0xb1, 0xdb, 0xf5, 0xf1, 0xcb, 0xfa, 0xaf, 0x25, 0xbe, 0x8c, 0xf4, + 0x0e, 0x8d, 0x9d, 0x03, 0x75, 0x6d, 0xad, 0x69, 0xa6, 0xac, 0x02, 0xa3, + 0x8d, 0x26, 0x73, 0x21, 0x90, 0xc6, 0x62, 0x8c, 0x72, 0xe4, 0x32, 0x2e, + 0x58, 0x92, 0x7c, 0x29, 0xaa, 0x61, 0x9e, 0xff, 0x00, 0xa7, 0x83, 0xd3, + 0xf4, 0xf2, 0xf0, 0xf1, 0xd2, 0x99, 0xa4, 0x56, 0x78, 0xbe, 0x7f, 0x4a, + 0x32, 0x86, 0x4d, 0x4c, 0xe3, 0x42, 0xdf, 0x4b, 0x9b, 0xf5, 0x0e, 0x1d, + 0xb5, 0xf6, 0xe5, 0x05, 0x42, 0xab, 0x6a, 0xfa, 0x92, 0x4c, 0x64, 0x89, + 0x18, 0x35, 0x9f, 0x98, 0xfb, 0xbc, 0x9a, 0x25, 0xaa, 0x5a, 0xd6, 0xc8, + 0xd2, 0xbe, 0xf3, 0xcd, 0xdf, 0xd5, 0xf9, 0xfb, 0x6d, 0xcd, 0xe9, 0x2f, + 0x40, 0xea, 0x57, 0x66, 0x5e, 0xdc, 0xb3, 0x25, 0x72, 0x89, 0x59, 0x9a, + 0xbe, 0x09, 0x27, 0xe7, 0x06, 0x2b, 0x2b, 0x52, 0x3a, 0xb9, 0xd7, 0xec, + 0x45, 0xef, 0x6f, 0x3d, 0x09, 0xa9, 0x8a, 0x54, 0x74, 0x33, 0x29, 0xce, + 0xb8, 0x5a, 0xbc, 0x6b, 0x30, 0x4d, 0x7c, 0x5b, 0xf3, 0x7f, 0xa9, 0xc1, + 0xc5, 0x4e, 0x12, 0x2c, 0xdc, 0x90, 0x66, 0xc2, 0x4f, 0x63, 0xfa, 0xdf, + 0xca, 0xc3, 0x78, 0x82, 0x44, 0xae, 0xc7, 0x65, 0x01, 0x05, 0x16, 0x2a, + 0x75, 0xa3, 0x97, 0x5f, 0x9d, 0x6f, 0x1e, 0x19, 0x9d, 0xa4, 0x52, 0xb9, + 0x40, 0x10, 0x80, 0xf6, 0x5f, 0x0f, 0xd7, 0xf4, 0xbf, 0xca, 0x7d, 0x02, + 0x2b, 0xd6, 0x6a, 0xb9, 0x3a, 0x66, 0xce, 0xd8, 0xec, 0x7a, 0xb9, 0x2f, + 0xd5, 0xf8, 0xec, 0xf4, 0xe7, 0x75, 0x6d, 0x4d, 0xd5, 0xac, 0xd5, 0x66, + 0x9a, 0xb8, 0x98, 0x10, 0x4e, 0x5c, 0x50, 0x67, 0x33, 0x19, 0x63, 0x19, + 0x91, 0x73, 0x46, 0x53, 0x2c, 0xa8, 0xf9, 0x1a, 0xf0, 0x92, 0x71, 0xf4, + 0x0e, 0xbe, 0x0f, 0x45, 0xbf, 0x37, 0x0f, 0x1d, 0x2a, 0xce, 0x95, 0x95, + 0x9e, 0x3b, 0x9f, 0xd2, 0xae, 0x50, 0xc9, 0x59, 0xb5, 0x09, 0x66, 0x7d, + 0x1f, 0x37, 0xd7, 0x71, 0xed, 0xa3, 0xb7, 0x29, 0x16, 0x11, 0xd0, 0x25, + 0x53, 0x59, 0x59, 0x32, 0x51, 0x23, 0x95, 0xbc, 0x7c, 0xe3, 0xdb, 0xe5, + 0xd1, 0x2d, 0x12, 0xc2, 0x5b, 0x17, 0x49, 0xef, 0x7c, 0xbe, 0x8f, 0x4b, + 0xe7, 0xed, 0xd3, 0x97, 0xa2, 0x6f, 0x3a, 0x6b, 0xde, 0xce, 0xbb, 0x89, + 0x15, 0x92, 0x4f, 0x59, 0x9d, 0xcd, 0x07, 0xc5, 0x57, 0xf2, 0x7e, 0xb9, + 0x40, 0x04, 0x74, 0xb1, 0xaf, 0xdb, 0x78, 0xed, 0xd7, 0xde, 0x37, 0xca, + 0xe1, 0xac, 0x0d, 0x59, 0x39, 0x39, 0xad, 0xf9, 0xcb, 0x32, 0x5b, 0xf0, + 0xef, 0xce, 0x7e, 0xa3, 0x9d, 0xe7, 0xb5, 0x65, 0x22, 0x7a, 0x92, 0x82, + 0x58, 0x49, 0xec, 0x3f, 0x59, 0xf9, 0x79, 0x74, 0xe7, 0x12, 0x9b, 0x95, + 0x51, 0x4a, 0xac, 0x10, 0xaa, 0xc2, 0xa6, 0x59, 0xcb, 0xaf, 0xca, 0x75, + 0x8f, 0x33, 0xac, 0xe9, 0x94, 0x46, 0x00, 0x22, 0x22, 0x3d, 0x87, 0xc3, + 0xf5, 0xfd, 0x37, 0xf2, 0x7f, 0x41, 0x65, 0x4e, 0xf3, 0x5e, 0xb2, 0x6b, + 0x33, 0xed, 0x8e, 0xa7, 0xaf, 0x95, 0xff, 0x00, 0xab, 0xf1, 0xcb, 0xd5, + 0x9d, 0x86, 0xdb, 0x35, 0xa6, 0x9a, 0xbc, 0xbe, 0xac, 0x26, 0x81, 0x13, + 0x9c, 0x54, 0x50, 0x67, 0x33, 0xc6, 0x63, 0x2a, 0xe6, 0x8c, 0xc6, 0x58, + 0xa5, 0x7e, 0x7a, 0x78, 0xd8, 0x99, 0xf4, 0x1e, 0xbf, 0x3f, 0xbf, 0xbf, + 0x3f, 0x0f, 0x9f, 0x4a, 0xa6, 0x82, 0x16, 0x78, 0xfe, 0x7f, 0x4a, 0xb9, + 0x51, 0x93, 0x4c, 0xc8, 0x5a, 0x47, 0xba, 0x97, 0xe9, 0x1c, 0x7d, 0x07, + 0x5e, 0x10, 0xa4, 0x59, 0x53, 0xa9, 0x12, 0xa9, 0x0c, 0x94, 0x48, 0xe3, + 0x74, 0xe7, 0xf3, 0xef, 0x67, 0x9a, 0xf9, 0x68, 0x96, 0x32, 0xcd, 0x74, + 0xc7, 0xb9, 0xf3, 0x7a, 0x3d, 0x07, 0x9f, 0xb7, 0x76, 0x6b, 0xa1, 0x1d, + 0x05, 0xea, 0xc7, 0xab, 0x3a, 0xba, 0xe5, 0x83, 0x1d, 0xed, 0x2e, 0xd7, + 0x39, 0x59, 0x96, 0x6b, 0xe0, 0x76, 0x7e, 0x65, 0xdf, 0x18, 0x80, 0x12, + 0x3f, 0x6d, 0xf9, 0xfd, 0x3e, 0xbb, 0xa6, 0x76, 0xe5, 0x73, 0x32, 0x21, + 0x35, 0x4c, 0xd5, 0xba, 0xe7, 0xa7, 0x78, 0xf2, 0x9c, 0x7d, 0x19, 0x6b, + 0xf3, 0xcf, 0xe7, 0xff, 0x00, 0x4d, 0xcc, 0xe1, 0xaa, 0xb9, 0x27, 0x52, + 0xd4, 0x79, 0x29, 0x60, 0x9e, 0xcb, 0xf5, 0x3f, 0x9a, 0xb7, 0xb7, 0x1a, + 0x6e, 0x62, 0x46, 0xa3, 0x66, 0x66, 0x65, 0x48, 0x80, 0xe8, 0xb2, 0xde, + 0x5d, 0xbe, 0x5d, 0x79, 0xf9, 0xbd, 0xe6, 0x72, 0xb4, 0x90, 0x01, 0x11, + 0x11, 0x3d, 0x7f, 0xc3, 0xf5, 0xfd, 0x37, 0xf2, 0x5f, 0x41, 0x45, 0x1a, + 0xcc, 0x35, 0x93, 0x59, 0x97, 0x6c, 0xf4, 0x7d, 0x7c, 0xb6, 0x7e, 0xab, + 0xc5, 0x2f, 0x66, 0x75, 0x26, 0xba, 0xd2, 0x5f, 0x65, 0xc5, 0xb5, 0x22, + 0x60, 0x88, 0xc5, 0x15, 0x55, 0x25, 0x26, 0x78, 0xce, 0x67, 0x96, 0x83, + 0x39, 0x9a, 0x32, 0xaf, 0x8f, 0x3e, 0x79, 0x16, 0x9f, 0x41, 0xeb, 0xf3, + 0xbb, 0x7b, 0xe1, 0xc3, 0xe7, 0xd2, 0x13, 0x45, 0x45, 0x3c, 0x87, 0x3f, + 0xa3, 0x54, 0xd2, 0x31, 0xe9, 0x4a, 0x4d, 0x6b, 0x3e, 0x89, 0x9d, 0x7d, + 0x5f, 0x97, 0xa7, 0x8b, 0xdb, 0xcd, 0x51, 0x02, 0xb3, 0x45, 0x4a, 0xdb, + 0xac, 0xb0, 0x71, 0x22, 0x47, 0x07, 0xa7, 0x3f, 0x09, 0xec, 0xf3, 0x5b, + 0x2d, 0x13, 0x4a, 0x59, 0xc6, 0x95, 0xf7, 0x7e, 0x5f, 0x47, 0x73, 0x87, + 0x5f, 0x45, 0x9d, 0xef, 0x3a, 0x32, 0xf5, 0x63, 0xd5, 0x1a, 0x35, 0x9e, + 0x4c, 0xde, 0xa3, 0x51, 0x7d, 0xcc, 0x0f, 0xcd, 0xec, 0xfe, 0x78, 0xe9, + 0xc6, 0x22, 0x12, 0x49, 0x7f, 0x67, 0x79, 0xfd, 0x3f, 0x43, 0xd4, 0xd8, + 0x4e, 0x64, 0x08, 0xa1, 0xab, 0xb7, 0xcf, 0x57, 0x4e, 0x7c, 0x3f, 0x37, + 0xaf, 0x9f, 0x6f, 0xe6, 0xdf, 0x83, 0xfa, 0x4e, 0x4f, 0x9a, 0xd7, 0xce, + 0xca, 0xc9, 0x04, 0x44, 0x82, 0x7b, 0x2f, 0xd3, 0xfe, 0x76, 0xef, 0x47, + 0x9e, 0x09, 0x1a, 0xa2, 0xc9, 0x98, 0x2e, 0x58, 0xd1, 0x54, 0xac, 0x76, + 0xdd, 0xcb, 0xa7, 0xce, 0x75, 0x8e, 0x26, 0xa7, 0x3e, 0x15, 0x92, 0x01, + 0x42, 0x22, 0x44, 0xf6, 0x1f, 0x13, 0xd7, 0xf4, 0xdf, 0xc8, 0xfd, 0x08, + 0xc5, 0x1b, 0xc4, 0x2e, 0x4d, 0x47, 0xd3, 0x3b, 0xbd, 0x9c, 0xba, 0x1f, + 0xaa, 0xf1, 0x4b, 0xdb, 0x9d, 0x26, 0x84, 0xd1, 0x57, 0x16, 0xd9, 0x61, + 0x32, 0x68, 0x11, 0xac, 0x71, 0x0a, 0xa8, 0xa6, 0x29, 0x28, 0x28, 0x8a, + 0x17, 0x39, 0x4c, 0x66, 0x38, 0xcb, 0xf2, 0x28, 0xb0, 0xfa, 0x27, 0x5f, + 0x9b, 0xdc, 0xdf, 0x0f, 0x39, 0xcf, 0xb2, 0x95, 0x91, 0xb3, 0xc8, 0xe3, + 0xe8, 0xd3, 0x9d, 0x06, 0x4d, 0x20, 0x94, 0x5b, 0x18, 0xf6, 0x58, 0xd7, + 0xd5, 0xb9, 0xf4, 0xab, 0xaf, 0x27, 0x6a, 0xa0, 0x2a, 0x6b, 0x62, 0x3a, + 0x71, 0x32, 0x47, 0x9e, 0xeb, 0xcb, 0xc4, 0xfa, 0xfc, 0xf2, 0xce, 0xaa, + 0x95, 0x2c, 0xa3, 0x52, 0xfb, 0xef, 0x2f, 0xa3, 0xb9, 0xc3, 0xaf, 0x7b, + 0x3a, 0xd8, 0xbd, 0x08, 0xe9, 0xaf, 0x72, 0x6a, 0x56, 0x63, 0xb9, 0xd6, + 0xba, 0xcb, 0x92, 0x35, 0xf9, 0xf2, 0x67, 0xf3, 0xdf, 0x4e, 0x30, 0x25, + 0x15, 0x16, 0x57, 0xec, 0x2f, 0x3f, 0xab, 0xe9, 0x1a, 0xce, 0xc5, 0x45, + 0x05, 0x11, 0x41, 0x09, 0x7b, 0xd3, 0x1e, 0x7f, 0x3d, 0xb9, 0x9d, 0x39, + 0xfc, 0x0b, 0xf3, 0xff, 0x00, 0xa6, 0xe3, 0xf9, 0x75, 0x0c, 0x59, 0x58, + 0xe9, 0x61, 0x56, 0x41, 0xeb, 0xff, 0x00, 0x4f, 0xf9, 0xed, 0x3e, 0xbf, + 0x2c, 0x6c, 0x81, 0x5a, 0x15, 0x4a, 0x53, 0x62, 0x1d, 0x8e, 0xc9, 0x2e, + 0xbe, 0x7d, 0x3e, 0x75, 0x73, 0xe1, 0xb7, 0x8b, 0xa5, 0x76, 0x48, 0x41, + 0x11, 0x22, 0x40, 0xf6, 0x1f, 0x17, 0xd7, 0xf4, 0xef, 0xc8, 0x7d, 0x08, + 0x66, 0x53, 0xd3, 0x30, 0xb9, 0x07, 0xd7, 0x1a, 0xfd, 0x7c, 0xfa, 0x7f, + 0xab, 0xf1, 0x3f, 0x6e, 0x2f, 0x4d, 0x15, 0x71, 0x6d, 0x5a, 0x96, 0x12, + 0x1d, 0x34, 0x46, 0x75, 0x82, 0x54, 0x56, 0x52, 0x52, 0x52, 0x53, 0x2d, + 0x05, 0x31, 0x9c, 0xa4, 0xf9, 0x42, 0xf1, 0xe3, 0xea, 0x3d, 0xbe, 0x66, + 0x9b, 0xcb, 0x81, 0xcf, 0xa8, 0xac, 0x56, 0x79, 0x1c, 0x7d, 0x1a, 0x33, + 0xa0, 0xc9, 0x5a, 0x17, 0x9d, 0x50, 0x4f, 0x6d, 0xcf, 0x7f, 0x44, 0xc6, + 0xf4, 0x75, 0xe7, 0x55, 0x21, 0x55, 0xf4, 0xd6, 0x49, 0x3a, 0x71, 0x32, + 0x67, 0x9c, 0xed, 0xcb, 0xc7, 0x7a, 0x7c, 0xee, 0x6a, 0xa9, 0x45, 0x72, + 0xea, 0x3d, 0xef, 0x97, 0xd1, 0xdd, 0xe1, 0xd7, 0xb9, 0x9d, 0x6b, 0x3a, + 0x2b, 0xd0, 0x97, 0xa9, 0x2c, 0xac, 0xcd, 0xac, 0xeb, 0x97, 0x49, 0x6d, + 0x95, 0x59, 0xf9, 0xea, 0x4f, 0x87, 0x6f, 0x94, 0x0b, 0x65, 0xba, 0x31, + 0xea, 0x7e, 0xb1, 0xe1, 0xe9, 0xfa, 0x4e, 0xf1, 0x7a, 0x91, 0x59, 0x02, + 0x99, 0x69, 0x97, 0xa9, 0xcf, 0x6a, 0x6b, 0xce, 0xf5, 0xe3, 0xf0, 0xff, + 0x00, 0x81, 0xfa, 0x6e, 0x2f, 0x8f, 0xa5, 0x79, 0x4e, 0xc5, 0x95, 0x1c, + 0xaa, 0xa9, 0x6e, 0x7a, 0xcf, 0xd1, 0xfc, 0x1d, 0xde, 0xef, 0x14, 0x48, + 0x58, 0x92, 0xab, 0x22, 0x56, 0x16, 0x42, 0xc8, 0xd4, 0xcb, 0x31, 0xd3, + 0xe6, 0x17, 0x1e, 0x5f, 0x59, 0xba, 0x59, 0x58, 0xe0, 0xa8, 0xc2, 0x20, + 0x44, 0xf5, 0xdf, 0x1b, 0xd5, 0xf5, 0x0f, 0xc7, 0x7d, 0x18, 0x49, 0x4f, + 0x4c, 0x41, 0x0d, 0x43, 0x73, 0x57, 0xaf, 0x97, 0x57, 0xf5, 0x5e, 0x23, + 0xdf, 0x8b, 0xcb, 0xec, 0xb4, 0xb4, 0xb2, 0xac, 0x49, 0x12, 0xa4, 0x06, + 0x62, 0x09, 0x02, 0xb2, 0xb2, 0x98, 0xa8, 0xa5, 0x69, 0x2a, 0x28, 0x8c, + 0xe7, 0x93, 0x5f, 0x9e, 0x47, 0xd3, 0x3b, 0x7c, 0xb6, 0xc7, 0x33, 0x1d, + 0x11, 0x25, 0x56, 0x79, 0x1c, 0x7d, 0x0a, 0x33, 0xb0, 0xc9, 0xa6, 0xc8, + 0x2a, 0x07, 0xab, 0xe7, 0xaf, 0x49, 0x9e, 0x9d, 0xdd, 0x60, 0xdc, 0x81, + 0x5d, 0x5a, 0x5b, 0x4e, 0xa4, 0x48, 0x94, 0x4c, 0xf3, 0x5d, 0xb8, 0xf9, + 0x2f, 0x4f, 0x05, 0x35, 0x09, 0x54, 0xb2, 0x5d, 0x27, 0xbd, 0xf2, 0xfa, + 0x3b, 0xbc, 0x3b, 0x76, 0xf3, 0x75, 0x1d, 0x09, 0x76, 0x9b, 0xd6, 0x76, + 0x53, 0xac, 0xe9, 0x96, 0xe4, 0x9a, 0xd0, 0x9f, 0x02, 0x8f, 0x8b, 0x74, + 0xe3, 0x10, 0xcd, 0xaf, 0x51, 0x9f, 0xa8, 0x38, 0x77, 0xfa, 0x67, 0x4c, + 0x6a, 0xcd, 0x9d, 0x45, 0xaa, 0xa2, 0xa3, 0x34, 0xbb, 0xb1, 0xab, 0xb3, + 0xbe, 0x1f, 0x4e, 0x7f, 0x15, 0xf8, 0x1f, 0xa4, 0xe1, 0xf8, 0xfa, 0xc7, + 0x26, 0x95, 0xf1, 0xa5, 0x5f, 0xdf, 0x36, 0x57, 0x7b, 0xef, 0xfc, 0x1d, + 0xbe, 0xdf, 0x24, 0x50, 0xb2, 0x08, 0xec, 0x46, 0x7a, 0xaa, 0x15, 0x8a, + 0xc5, 0x5a, 0x71, 0xd3, 0xe5, 0x17, 0x1e, 0x77, 0x59, 0xb6, 0x59, 0xa3, + 0x10, 0x88, 0x90, 0x22, 0x7a, 0xef, 0x8f, 0xea, 0xfa, 0x97, 0xe3, 0x3e, + 0x8d, 0x7a, 0xcd, 0x1a, 0xca, 0xb0, 0xb0, 0xd4, 0xbf, 0xd5, 0xcb, 0xad, + 0xfa, 0xbf, 0x19, 0xef, 0xe7, 0x75, 0x97, 0x16, 0x96, 0x54, 0xc9, 0xa4, + 0x89, 0x50, 0x05, 0x49, 0x0a, 0x81, 0x59, 0x08, 0xa8, 0xaa, 0xaa, 0x96, + 0xa4, 0xa5, 0x68, 0x28, 0x8c, 0x27, 0xc8, 0x57, 0xe8, 0x5d, 0x7e, 0x62, + 0x98, 0xc5, 0x9d, 0x83, 0x52, 0xcf, 0x23, 0x8f, 0xa1, 0x9f, 0x3b, 0x0c, + 0x9a, 0x69, 0x39, 0xca, 0xa4, 0xf5, 0xf8, 0xd6, 0xb9, 0xbf, 0xa4, 0x56, + 0x7d, 0x62, 0x34, 0xaa, 0xd1, 0xd5, 0x95, 0x22, 0x51, 0x32, 0x47, 0x98, + 0xef, 0xc7, 0xcb, 0xfa, 0x38, 0xc3, 0x36, 0x13, 0x40, 0xd7, 0x4c, 0xbe, + 0xef, 0xcd, 0xdf, 0xbf, 0xc3, 0xb7, 0x66, 0x5d, 0x11, 0xba, 0x5d, 0xb5, + 0xb0, 0xb2, 0xca, 0xac, 0xd1, 0x16, 0xd9, 0x22, 0xa3, 0xe0, 0x07, 0xc8, + 0x75, 0xca, 0x22, 0x96, 0x9b, 0x26, 0x7e, 0x97, 0xe1, 0xdf, 0xea, 0x7d, + 0x31, 0xa2, 0x50, 0x82, 0xd2, 0x55, 0x19, 0xe5, 0xd7, 0x34, 0xf3, 0xae, + 0x7d, 0x9f, 0x1c, 0xf8, 0x3f, 0xa3, 0xe0, 0xf8, 0xba, 0xa8, 0x5c, 0x8a, + 0x2c, 0xed, 0x25, 0xb1, 0x27, 0xa2, 0xfd, 0x1f, 0xe7, 0xf5, 0xfa, 0x7c, + 0xca, 0xc7, 0x65, 0x26, 0x8b, 0x12, 0x67, 0xb2, 0x04, 0x0a, 0xec, 0x55, + 0x3e, 0x7b, 0xf9, 0x56, 0xb1, 0xe7, 0xf5, 0x2d, 0x96, 0x48, 0xc4, 0x22, + 0x24, 0x08, 0x1e, 0xb7, 0xe4, 0xfa, 0x7e, 0xab, 0xf8, 0xcf, 0xa5, 0x4b, + 0x35, 0x6b, 0x11, 0xa3, 0x50, 0xb9, 0xbb, 0xd3, 0xcf, 0xad, 0xfa, 0xbf, + 0x1b, 0xfa, 0x1c, 0xef, 0x4b, 0x2a, 0xc2, 0xc2, 0x76, 0x4c, 0x91, 0x20, + 0xa1, 0x29, 0x22, 0x42, 0xa3, 0x15, 0x95, 0xd5, 0x51, 0x51, 0x59, 0x49, + 0x4a, 0xd0, 0x53, 0x1e, 0x21, 0x77, 0x74, 0xf9, 0x95, 0xcc, 0x53, 0x34, + 0x02, 0x95, 0xe4, 0x71, 0xf4, 0x33, 0xe7, 0x6c, 0xc7, 0xa6, 0xa2, 0x22, + 0x8f, 0x43, 0x9d, 0x71, 0xa6, 0xfe, 0xcf, 0x95, 0x3d, 0x70, 0x05, 0x5d, + 0x56, 0x0e, 0x91, 0x22, 0x51, 0x33, 0xcb, 0x77, 0xe3, 0xe6, 0xbd, 0x1c, + 0x6b, 0xce, 0x94, 0xa2, 0xb2, 0xf9, 0x7d, 0xdf, 0x97, 0xbf, 0xa1, 0xe1, + 0xd7, 0xaa, 0xba, 0x17, 0x64, 0x6c, 0x35, 0x16, 0xd9, 0x1b, 0x24, 0x5c, + 0x3b, 0x2b, 0x3f, 0x38, 0x49, 0xf3, 0xad, 0x62, 0x23, 0x96, 0x8b, 0x19, + 0xf7, 0xde, 0x5d, 0x7e, 0xc5, 0xbc, 0xe8, 0x57, 0x10, 0x5a, 0xe5, 0xa4, + 0xaa, 0x5b, 0x73, 0x63, 0x35, 0x49, 0xf2, 0x4f, 0x87, 0xfa, 0x2f, 0x3f, + 0xf3, 0xfb, 0x2c, 0x0c, 0xd7, 0x64, 0xfa, 0x43, 0x41, 0x3d, 0x27, 0xe9, + 0x3f, 0x3d, 0xa3, 0xd1, 0xe7, 0x56, 0x49, 0x29, 0xab, 0xec, 0x99, 0x95, + 0x02, 0x09, 0x87, 0x52, 0xf5, 0xe7, 0xe3, 0x5f, 0x39, 0xd6, 0x38, 0x1a, + 0x97, 0x4b, 0x24, 0x04, 0x22, 0x04, 0x08, 0x9e, 0xaf, 0xe5, 0x7a, 0x7e, + 0xaf, 0xf8, 0xaf, 0xa5, 0x4b, 0x15, 0x74, 0xca, 0x43, 0x50, 0xd4, 0xb3, + 0xbe, 0x3a, 0xdf, 0xaa, 0xf1, 0x4f, 0xe9, 0x73, 0xb4, 0xb5, 0x26, 0x59, + 0x64, 0x89, 0x92, 0xa6, 0x31, 0x59, 0x02, 0x2b, 0x14, 0x81, 0x0a, 0xac, + 0xae, 0x2a, 0x2b, 0x2a, 0x29, 0x29, 0x5a, 0x23, 0x2d, 0x70, 0x37, 0xf3, + 0xb2, 0x67, 0x11, 0x50, 0x61, 0x6f, 0x90, 0xc7, 0xd0, 0xcd, 0x9d, 0xb2, + 0xa5, 0xd2, 0x64, 0xaa, 0x8f, 0x4d, 0xcf, 0x58, 0x1a, 0xfa, 0xc4, 0xb6, + 0xf5, 0xe7, 0x15, 0x85, 0x96, 0x92, 0xa9, 0x54, 0x8b, 0x09, 0x0e, 0x3c, + 0xc7, 0xa3, 0x8f, 0x9a, 0xef, 0xc6, 0xbc, 0xe9, 0x4a, 0x0e, 0x5b, 0x97, + 0xdd, 0xf9, 0x7d, 0x1e, 0x8b, 0x8f, 0x5e, 0x9c, 0xba, 0x13, 0x5c, 0xba, + 0xcd, 0x15, 0x72, 0x16, 0x2b, 0x2d, 0x84, 0x46, 0xcf, 0xcb, 0xf7, 0x3e, + 0x41, 0x22, 0x39, 0x55, 0x95, 0x9f, 0x5d, 0xe7, 0xbf, 0xbf, 0x6d, 0x74, + 0x0b, 0x18, 0x82, 0xd3, 0x10, 0x9a, 0x9c, 0xb5, 0x4b, 0x5c, 0xbf, 0x2d, + 0xf8, 0x7f, 0xa0, 0xf3, 0x9f, 0x37, 0xd0, 0x64, 0xf3, 0x67, 0xd2, 0x3d, + 0x04, 0x8c, 0x9e, 0x9f, 0xf5, 0x3f, 0x9c, 0xb3, 0xb7, 0x17, 0x64, 0x0b, + 0x2c, 0x9d, 0x93, 0x8c, 0xc3, 0x4c, 0x35, 0x1d, 0x49, 0x9e, 0x57, 0x37, + 0xc8, 0xb3, 0xc2, 0xd4, 0xb9, 0x5a, 0x02, 0x22, 0x44, 0x81, 0x13, 0xd4, + 0x7c, 0xcf, 0x47, 0xd6, 0xbf, 0x11, 0xf4, 0xe9, 0xb8, 0xab, 0xa6, 0x00, + 0xb0, 0xd4, 0x97, 0x6c, 0x75, 0xff, 0x00, 0x55, 0xe2, 0x9f, 0xd3, 0xe7, + 0x69, 0x6a, 0x4c, 0x9d, 0x4d, 0x26, 0xad, 0x25, 0x40, 0x54, 0x08, 0x91, + 0x48, 0x10, 0xa8, 0x15, 0xc5, 0x75, 0x54, 0x56, 0x54, 0x52, 0x52, 0x50, + 0xbc, 0x1d, 0x7c, 0xfe, 0x5c, 0xe6, 0x84, 0x35, 0x75, 0xe4, 0x31, 0xf4, + 0x72, 0xe7, 0xa3, 0x2f, 0xc6, 0xb5, 0x96, 0x45, 0xa7, 0x46, 0xb9, 0x79, + 0xd7, 0xa8, 0xaf, 0x59, 0xd3, 0x35, 0xd9, 0x5d, 0x58, 0x5b, 0x45, 0x49, + 0x2c, 0x59, 0x0e, 0x3c, 0xc7, 0xa3, 0x87, 0x9a, 0xed, 0xca, 0xb9, 0xa2, + 0x51, 0x5c, 0x5c, 0xbe, 0xef, 0xcb, 0xe8, 0xf4, 0x5c, 0x7a, 0xf4, 0x63, + 0x41, 0xa9, 0x75, 0x9a, 0x12, 0xd2, 0x56, 0x16, 0x4c, 0x81, 0x0d, 0x67, + 0xe0, 0x9c, 0xda, 0x99, 0xc0, 0x64, 0xac, 0x1a, 0x9c, 0x69, 0xaf, 0xa0, + 0x66, 0xfd, 0xfb, 0x4b, 0x56, 0x12, 0xc4, 0xae, 0x5a, 0x65, 0x94, 0xb5, + 0xcb, 0x44, 0x42, 0x5f, 0x9c, 0x7c, 0x3f, 0xd0, 0x79, 0xaf, 0x9b, 0xe9, + 0x96, 0x53, 0xd2, 0x4a, 0xac, 0x2c, 0x86, 0x5e, 0xab, 0xf5, 0x9f, 0x99, + 0x7d, 0x39, 0x96, 0x56, 0x3b, 0x3a, 0x09, 0x5a, 0xd5, 0x66, 0x73, 0x32, + 0x46, 0xaf, 0x4f, 0x9e, 0xcb, 0xc9, 0x4e, 0x3d, 0x95, 0xd0, 0x80, 0x88, + 0x88, 0x89, 0x03, 0xd2, 0x7c, 0xee, 0xff, 0x00, 0x5d, 0xfc, 0x37, 0xd3, + 0xa7, 0x58, 0x8e, 0xf2, 0x58, 0xa9, 0x5c, 0xbe, 0xd9, 0xeb, 0x7e, 0xa7, + 0xc7, 0x77, 0xd4, 0xe5, 0x61, 0x62, 0x4c, 0x99, 0x3b, 0x24, 0xad, 0x25, + 0x4c, 0x55, 0x01, 0x11, 0x48, 0x90, 0x20, 0x41, 0x2b, 0x2b, 0x5a, 0xea, + 0xb8, 0xa8, 0xa4, 0xa4, 0xe0, 0xef, 0xe7, 0xe0, 0x9c, 0xa0, 0xb1, 0x22, + 0xa8, 0xf2, 0x9c, 0xfe, 0x96, 0x4c, 0xf4, 0x0d, 0xd9, 0xd7, 0x5a, 0xca, + 0x9a, 0xb7, 0x1a, 0xd1, 0xd7, 0x8f, 0x96, 0x9b, 0xd0, 0x7d, 0x6a, 0x69, + 0xf4, 0xe7, 0x09, 0xa7, 0x52, 0xb2, 0x55, 0x34, 0xb1, 0x64, 0x11, 0xe6, + 0x7d, 0x1c, 0x3c, 0xcf, 0x6e, 0x70, 0xcd, 0x6a, 0x95, 0xc5, 0xcb, 0xee, + 0xfc, 0xbe, 0x9f, 0x45, 0xc7, 0xa7, 0x42, 0x34, 0x1a, 0xcd, 0x45, 0xe5, + 0xa4, 0xac, 0x95, 0x93, 0xb2, 0x47, 0x25, 0x3e, 0x31, 0x87, 0xd0, 0xf5, + 0x80, 0x0f, 0x2f, 0xa7, 0xca, 0xb3, 0xaf, 0xa2, 0x65, 0xf7, 0x5d, 0x34, + 0x5b, 0x4c, 0xb5, 0xcb, 0x54, 0x55, 0x35, 0x19, 0x67, 0x2e, 0x32, 0x12, + 0xfc, 0xff, 0x00, 0xe2, 0x7d, 0xff, 0x00, 0x39, 0xf2, 0xbd, 0x76, 0x12, + 0xa4, 0x46, 0x48, 0xd9, 0x18, 0xf5, 0x7f, 0xae, 0xfc, 0xc3, 0xde, 0x20, + 0x08, 0x6a, 0x74, 0xa3, 0x29, 0x1d, 0x4c, 0x85, 0x28, 0x1b, 0x0f, 0x94, + 0xd5, 0x51, 0x9b, 0x3b, 0xe6, 0xef, 0x15, 0x5c, 0x02, 0x22, 0x22, 0x24, + 0xe3, 0xd1, 0x78, 0x3b, 0xfd, 0x5f, 0xf0, 0xdf, 0x4a, 0x9d, 0x60, 0xd4, + 0x96, 0xa4, 0x6c, 0x86, 0xb2, 0xfa, 0x67, 0xab, 0xfa, 0x8f, 0x26, 0x8f, + 0xab, 0xca, 0xc4, 0x99, 0x32, 0x64, 0xc9, 0x53, 0x49, 0x50, 0x15, 0x14, + 0x44, 0x48, 0xd4, 0x62, 0x05, 0x69, 0x0a, 0x84, 0x56, 0xb5, 0xd5, 0x71, + 0x51, 0x49, 0xe7, 0xb7, 0xf3, 0xb9, 0xee, 0x6e, 0x15, 0xa8, 0xa5, 0x71, + 0xf9, 0xfe, 0x9b, 0xce, 0xeb, 0xab, 0xec, 0xe1, 0xda, 0x65, 0x16, 0xba, + 0x5b, 0xc7, 0x12, 0x6f, 0x3d, 0x9f, 0x4f, 0xe7, 0xd3, 0xa3, 0xdb, 0x9d, + 0xa4, 0x26, 0xac, 0xd6, 0x65, 0x53, 0x4b, 0x16, 0x48, 0x4b, 0xe6, 0xfb, + 0xf0, 0xf2, 0xfd, 0xb1, 0x08, 0x14, 0x50, 0xba, 0x5f, 0x79, 0xe5, 0xf4, + 0xfa, 0x5e, 0x3b, 0xdc, 0xba, 0x4d, 0x71, 0xa5, 0x2f, 0xab, 0x49, 0x97, + 0x6b, 0x33, 0x49, 0xd9, 0xe6, 0x32, 0xcb, 0x73, 0xa9, 0x27, 0x05, 0x56, + 0x73, 0xcd, 0xd2, 0xec, 0xce, 0xbd, 0x1e, 0x90, 0x5a, 0x33, 0x69, 0x5a, + 0x16, 0x12, 0xcf, 0x37, 0x2c, 0xb5, 0x2f, 0x81, 0xf8, 0x7f, 0x77, 0xcc, + 0xfc, 0x9f, 0x6c, 0xc6, 0x29, 0x00, 0xd0, 0xb9, 0xf5, 0x9f, 0xaf, 0xfc, + 0xca, 0xd6, 0x60, 0x86, 0xa7, 0x42, 0x33, 0x91, 0xb2, 0x8b, 0x33, 0x96, + 0xa5, 0x2b, 0xe5, 0xf1, 0x7c, 0x96, 0xb3, 0x9e, 0xc7, 0xe2, 0xf5, 0x51, + 0xe9, 0xe3, 0xdc, 0xe1, 0xd3, 0x2f, 0xa3, 0x85, 0x98, 0x92, 0xd9, 0xd9, + 0xa4, 0xb2, 0x5d, 0x9e, 0x5e, 0x9e, 0xd7, 0xf1, 0x3f, 0x46, 0x37, 0x0a, + 0xa3, 0xa9, 0x1d, 0xe0, 0xd4, 0x76, 0x75, 0x3f, 0x4f, 0xe4, 0xd3, 0xf5, + 0x39, 0x58, 0x4e, 0xa6, 0x4c, 0x95, 0x92, 0x24, 0x3a, 0x02, 0xa8, 0xb9, + 0x94, 0xa1, 0x1a, 0x44, 0x52, 0x24, 0x08, 0x10, 0x20, 0x56, 0x52, 0x52, + 0x79, 0xcd, 0xfc, 0xee, 0x6c, 0xc4, 0x42, 0x12, 0xd5, 0x6d, 0x7e, 0x6f, + 0xa5, 0x65, 0xdc, 0x73, 0x69, 0x9a, 0xc5, 0x4e, 0x20, 0x15, 0xc5, 0xd4, + 0xbe, 0xbb, 0x76, 0xfa, 0x9c, 0xeb, 0x6f, 0x4c, 0x6c, 0x5a, 0xea, 0xfb, + 0x1a, 0x4d, 0x66, 0x28, 0xf2, 0x7e, 0x8f, 0x3f, 0x07, 0xb6, 0x14, 0xb0, + 0x52, 0x50, 0x9c, 0xbf, 0x40, 0xf2, 0xfa, 0x7d, 0x3f, 0x1d, 0xe9, 0x5d, + 0x89, 0xb4, 0xd2, 0x5f, 0x65, 0xc5, 0x85, 0xe8, 0xf5, 0x9c, 0x13, 0x30, + 0x4a, 0xc8, 0x90, 0x00, 0x89, 0x12, 0x26, 0x4a, 0x6b, 0x55, 0x59, 0x35, + 0x4a, 0xe6, 0x96, 0x13, 0x51, 0x96, 0x89, 0x68, 0x8f, 0x0d, 0xf1, 0x3e, + 0xef, 0x97, 0xf9, 0x1e, 0xe3, 0x26, 0x3b, 0x01, 0xd8, 0xac, 0xf5, 0xbf, + 0xaf, 0xfc, 0xc9, 0xbc, 0xab, 0x26, 0x6d, 0x67, 0x8c, 0xba, 0x75, 0x9c, + 0xc9, 0x32, 0x0b, 0xa2, 0x3c, 0x06, 0x66, 0x0b, 0x39, 0x5a, 0x9b, 0xf3, + 0x78, 0xf5, 0xdb, 0x8d, 0xde, 0x7d, 0x3f, 0x46, 0x34, 0x72, 0xd6, 0xec, + 0xab, 0x8c, 0x9d, 0xa5, 0xbe, 0x6e, 0x9e, 0xbb, 0xf1, 0x3f, 0x46, 0x1d, + 0x39, 0xd7, 0x64, 0x75, 0x1d, 0x8e, 0xc7, 0xa9, 0xd5, 0xfd, 0x2f, 0x93, + 0x4f, 0xd5, 0xe5, 0x32, 0x64, 0xaa, 0x64, 0x87, 0x42, 0x14, 0xac, 0x49, + 0xe7, 0x7b, 0xfc, 0x78, 0x4e, 0x9e, 0x93, 0x9f, 0xd1, 0xb2, 0x6d, 0x11, + 0x22, 0x40, 0x81, 0x02, 0xb2, 0xb2, 0x92, 0x93, 0xcd, 0x6f, 0xe6, 0xf3, + 0x26, 0x22, 0x0a, 0x8a, 0x95, 0xf9, 0xfe, 0x9e, 0x5c, 0x75, 0x16, 0xf4, + 0x63, 0x95, 0x54, 0x0a, 0x0c, 0x56, 0xee, 0xd4, 0xbb, 0xcf, 0xdb, 0xd1, + 0x7a, 0xf8, 0xdb, 0x67, 0x53, 0x4b, 0x33, 0x64, 0x3b, 0x10, 0xcf, 0x19, + 0xea, 0xf3, 0x71, 0xba, 0x64, 0x94, 0x05, 0x25, 0x72, 0xfd, 0x0f, 0xcb, + 0xe8, 0xf5, 0x1c, 0x7a, 0x5a, 0x9d, 0x03, 0x79, 0xba, 0xcd, 0x5a, 0x97, + 0xd9, 0x42, 0x62, 0x92, 0x99, 0x1c, 0xa8, 0x42, 0x10, 0x0c, 0x68, 0xd6, + 0x50, 0x52, 0x2b, 0x21, 0x2d, 0x13, 0x6e, 0x6a, 0xf9, 0x73, 0x95, 0xcb, + 0xe2, 0x3e, 0x27, 0xdd, 0xf2, 0xdf, 0x1b, 0xde, 0x64, 0x00, 0x23, 0xdc, + 0x67, 0xae, 0xfd, 0x87, 0xe6, 0x67, 0xd3, 0x9c, 0x23, 0x4d, 0x99, 0xac, + 0x76, 0x42, 0xc2, 0x58, 0x12, 0x8c, 0x7c, 0xfa, 0x78, 0xad, 0x72, 0xcb, + 0x4c, 0x9c, 0x79, 0xfa, 0xf4, 0xf2, 0x65, 0xe7, 0x75, 0x91, 0xe9, 0x33, + 0x57, 0x42, 0x4b, 0x57, 0x4f, 0x97, 0x7e, 0x8f, 0xf1, 0x3f, 0x4a, 0x3d, + 0xb9, 0x46, 0xc8, 0xd8, 0x0d, 0x1e, 0xa7, 0x5b, 0xf4, 0xde, 0x4d, 0x3f, + 0x5b, 0x94, 0xc9, 0x93, 0x49, 0x2c, 0xac, 0xad, 0x9f, 0x2b, 0xd7, 0xe6, + 0xcf, 0x5c, 0xef, 0xa9, 0x25, 0xd9, 0xeb, 0xb2, 0xcc, 0x9a, 0xe5, 0x39, + 0xd6, 0xf9, 0xdb, 0x46, 0x7d, 0x16, 0xce, 0x91, 0x96, 0x09, 0x05, 0xad, + 0x20, 0x55, 0x54, 0xaf, 0x97, 0xdf, 0xcc, 0xe5, 0x4c, 0x29, 0x52, 0xa2, + 0xaa, 0xf4, 0x7c, 0xfe, 0x8c, 0xf3, 0xd7, 0x04, 0xc6, 0x0e, 0x9e, 0x3a, + 0xb7, 0xcb, 0x4e, 0x7a, 0x0b, 0x9e, 0xe2, 0x89, 0xaa, 0xba, 0x7a, 0xcf, + 0x46, 0x2c, 0xf2, 0xf6, 0xd9, 0xe3, 0xf4, 0xe8, 0xf5, 0x71, 0xb7, 0x1a, + 0xd9, 0x2e, 0xf9, 0xad, 0xd6, 0x54, 0x85, 0x78, 0xaf, 0x67, 0x93, 0x9d, + 0xb9, 0x19, 0x40, 0x55, 0x2c, 0xcf, 0xa3, 0x79, 0x3d, 0x3e, 0x9f, 0x96, + 0xec, 0x37, 0x1d, 0x0b, 0x85, 0x61, 0xc3, 0xbe, 0x0f, 0x17, 0xbb, 0x4f, + 0xb3, 0xc3, 0x77, 0x6e, 0x0d, 0x31, 0xaf, 0x9c, 0xce, 0xf5, 0x4d, 0xfa, + 0x5d, 0xf0, 0xb4, 0xd9, 0xab, 0x87, 0x32, 0x2a, 0xe0, 0x44, 0xb1, 0x58, + 0xa5, 0x65, 0x45, 0x0b, 0x5c, 0xb2, 0x9a, 0x94, 0xbe, 0x4b, 0xe2, 0x7d, + 0xdf, 0x29, 0xf0, 0xfe, 0x91, 0x20, 0x03, 0xa3, 0x50, 0x4f, 0x5f, 0xfa, + 0xff, 0x00, 0xcd, 0x9d, 0x78, 0xce, 0xc9, 0x55, 0x89, 0x1b, 0x25, 0x2d, + 0x38, 0xdd, 0x56, 0x73, 0x8f, 0x3d, 0xce, 0xe7, 0xe9, 0xce, 0xd2, 0x51, + 0xab, 0xc5, 0xbf, 0x01, 0xef, 0xe7, 0xdf, 0x48, 0xe1, 0x23, 0xab, 0x57, + 0x69, 0xd4, 0xde, 0x77, 0xea, 0x69, 0xf3, 0xeb, 0x3f, 0xe0, 0x3e, 0xb4, + 0x3b, 0x72, 0x2c, 0x2c, 0x28, 0x45, 0xa9, 0xd7, 0xfd, 0x37, 0x93, 0x5f, + 0xd6, 0xe3, 0x62, 0xc9, 0x26, 0x4a, 0xa4, 0x71, 0xb5, 0xe6, 0xf3, 0xdb, + 0xf0, 0x4e, 0xd6, 0x96, 0x56, 0xc6, 0xb6, 0xeb, 0x14, 0xdc, 0xc4, 0x8a, + 0x65, 0x44, 0xd5, 0xf9, 0xed, 0x74, 0xed, 0x6c, 0xe9, 0x6c, 0xe9, 0x29, + 0xb4, 0x52, 0x79, 0x2d, 0xfc, 0xde, 0x54, 0xc2, 0x55, 0x2c, 0x16, 0xba, + 0xd3, 0x3a, 0x2b, 0x84, 0x91, 0x5e, 0x8e, 0x7b, 0x73, 0xb5, 0xca, 0x23, + 0x5b, 0x35, 0xdf, 0x9d, 0xe8, 0xe9, 0x22, 0x41, 0x63, 0x19, 0x29, 0x74, + 0x66, 0xe9, 0x96, 0xc9, 0x67, 0x9b, 0xe7, 0xfb, 0x71, 0xad, 0x54, 0xd2, + 0x05, 0x09, 0xcb, 0xdc, 0xcb, 0xbf, 0xc7, 0xa7, 0x77, 0x96, 0xe8, 0xe9, + 0x8a, 0xba, 0x63, 0xaf, 0xcb, 0xa7, 0x98, 0xfc, 0xa7, 0xeb, 0xb5, 0xfc, + 0xdf, 0x6f, 0x47, 0x3d, 0x37, 0x75, 0xe5, 0xaf, 0xd7, 0xe4, 0xe3, 0xfa, + 0x7c, 0xa7, 0x97, 0xb7, 0x3b, 0xec, 0xfc, 0x5f, 0x75, 0xea, 0xe3, 0x5f, + 0xcc, 0xfa, 0xb4, 0x7c, 0x9f, 0xa7, 0x3e, 0xbc, 0xf5, 0x7a, 0x7c, 0xd2, + 0xd4, 0xc5, 0xe3, 0xf6, 0xd5, 0xe6, 0xf4, 0xc3, 0x1d, 0x76, 0x7e, 0xaf, + 0xf2, 0x36, 0xfa, 0xfc, 0x54, 0xe7, 0x55, 0x73, 0xed, 0x4f, 0x2e, 0xc7, + 0xab, 0xc5, 0x55, 0x9e, 0x6f, 0xe1, 0xfd, 0xef, 0x39, 0xf0, 0x7e, 0xab, + 0xb0, 0x04, 0x05, 0x60, 0x9d, 0xdf, 0xd6, 0xfe, 0x73, 0x5f, 0xa7, 0x84, + 0xc9, 0x81, 0x13, 0x2e, 0x35, 0x95, 0x69, 0x5e, 0x13, 0x94, 0x39, 0xeb, + 0x57, 0x87, 0xdd, 0x74, 0xe9, 0x3e, 0x9f, 0x37, 0xd5, 0x7e, 0x57, 0xd3, + 0xf1, 0x8f, 0xdb, 0x79, 0x3a, 0xde, 0x77, 0xbb, 0xf8, 0x7d, 0xf5, 0x70, + 0xd6, 0xed, 0xe1, 0xfd, 0x3e, 0x4b, 0xdd, 0xcc, 0xf6, 0xf3, 0x8e, 0x35, + 0x8b, 0xf0, 0x3f, 0x56, 0x3d, 0xb9, 0x9a, 0xc9, 0x44, 0x8a, 0xc7, 0x67, + 0x67, 0xf4, 0x9e, 0x5d, 0x7f, 0x63, 0x8c, 0xc9, 0x96, 0x62, 0xe9, 0xf0, + 0x74, 0xd9, 0xf2, 0x7a, 0xd5, 0xe3, 0x78, 0x3f, 0xd5, 0xfc, 0x7e, 0x67, + 0xbb, 0xcc, 0x51, 0x51, 0x93, 0xa9, 0xb9, 0xa6, 0xc7, 0x64, 0x12, 0xa4, + 0xa0, 0x8d, 0x40, 0xae, 0x48, 0x15, 0xd2, 0x9a, 0x81, 0x86, 0x67, 0x1e, + 0x77, 0x19, 0xa4, 0xa9, 0x6b, 0x4c, 0xb3, 0xa4, 0xd6, 0xc4, 0xb2, 0xcd, + 0x12, 0xc2, 0xb3, 0x75, 0xeb, 0x56, 0xfa, 0x5a, 0xe9, 0x9f, 0x79, 0x99, + 0x22, 0x55, 0x24, 0x06, 0xa2, 0x0a, 0x04, 0x61, 0xb9, 0xb2, 0x6a, 0x32, + 0xa9, 0x41, 0x2c, 0xce, 0x9a, 0x5f, 0x64, 0xcb, 0xd7, 0xd6, 0x71, 0xdf, + 0x9a, 0xef, 0xcf, 0x0f, 0x1e, 0xf0, 0xf9, 0x9f, 0x4e, 0x5f, 0x23, 0xe9, + 0xf5, 0x3e, 0x67, 0xd0, 0xe8, 0x70, 0xeb, 0xbb, 0x3b, 0xd5, 0x9d, 0x5d, + 0x9b, 0x6c, 0xd4, 0xa5, 0x64, 0xa1, 0xd3, 0xa7, 0xa8, 0xec, 0x54, 0xba, + 0xf3, 0x8d, 0x43, 0x1a, 0xae, 0xca, 0xee, 0x7a, 0x1f, 0x63, 0xe3, 0xf1, + 0xf9, 0x74, 0xe5, 0xf8, 0xfd, 0x3c, 0x4f, 0x9f, 0xe8, 0x2c, 0x76, 0x10, + 0x6a, 0x08, 0x8f, 0x45, 0xfa, 0xdf, 0xcd, 0xe8, 0xf6, 0x79, 0x60, 0x57, + 0x2d, 0x7c, 0xfa, 0x55, 0xcb, 0xa4, 0x38, 0x77, 0xaf, 0x87, 0x78, 0x79, + 0x7d, 0x10, 0xf2, 0xfa, 0x7c, 0xe7, 0xb7, 0xc9, 0x76, 0x34, 0xab, 0x5f, + 0xa7, 0xe6, 0x63, 0xe5, 0x3c, 0x97, 0xd4, 0xf2, 0xfd, 0xa7, 0xf1, 0xbe, + 0xce, 0x17, 0xd0, 0xe7, 0xc7, 0xf6, 0xf3, 0xed, 0x79, 0x37, 0xeb, 0x3e, + 0x4f, 0x4d, 0x58, 0xb3, 0x8a, 0x36, 0xf3, 0xf8, 0xea, 0xbb, 0xf2, 0x37, + 0x04, 0x02, 0x49, 0x61, 0xe9, 0x3e, 0x9f, 0x1e, 0xb7, 0xa2, 0x4f, 0xc9, + 0xb7, 0xe2, 0xdd, 0xfe, 0x3e, 0x86, 0x68, 0x15, 0xcb, 0xfa, 0xde, 0x4f, + 0x07, 0xfb, 0xaf, 0xce, 0xc2, 0xb3, 0x4d, 0x79, 0xfc, 0xaf, 0xb3, 0xa7, + 0x67, 0x47, 0x53, 0x56, 0xa4, 0xec, 0xad, 0x9a, 0xec, 0x81, 0x51, 0x5a, + 0x40, 0x80, 0x33, 0x9a, 0x5e, 0x6e, 0x77, 0x44, 0xdc, 0x06, 0xb0, 0x23, + 0x35, 0x75, 0x5e, 0x97, 0x2b, 0x28, 0xde, 0xe8, 0xed, 0xdd, 0x6b, 0x51, + 0x58, 0x09, 0x44, 0x90, 0xc6, 0x03, 0x50, 0x44, 0x63, 0x25, 0xcd, 0xb3, + 0x4a, 0x58, 0xaa, 0x14, 0x49, 0x7a, 0x77, 0x37, 0x13, 0xab, 0x93, 0xaf, + 0xcf, 0x78, 0xf7, 0x88, 0x68, 0xe5, 0xcd, 0x35, 0xde, 0xf9, 0x7f, 0x43, + 0x3f, 0x97, 0xd5, 0x97, 0xc9, 0xea, 0x87, 0x8f, 0xd9, 0x7f, 0x8b, 0xd5, + 0xaf, 0xcd, 0xdf, 0x46, 0x77, 0x76, 0x6d, 0xd5, 0x39, 0x66, 0xae, 0x1c, + 0x14, 0xa2, 0x05, 0x65, 0x31, 0x8a, 0xcc, 0xb6, 0x5f, 0xa8, 0xd3, 0x97, + 0x9e, 0x65, 0x8e, 0xc0, 0x10, 0xd4, 0x51, 0xd2, 0xea, 0xbb, 0x76, 0xb8, + 0x58, 0xd2, 0x95, 0x42, 0xa4, 0x8a, 0x3c, 0xc7, 0xd6, 0xf9, 0xdd, 0xdf, + 0x9b, 0xed, 0x9f, 0x3e, 0x95, 0xd8, 0xb7, 0x9d, 0x38, 0xd5, 0x99, 0xf9, + 0xde, 0x83, 0xc9, 0xe2, 0xd5, 0x73, 0x2b, 0x9e, 0x37, 0xb7, 0x97, 0x91, + 0xfb, 0x1c, 0xbd, 0x7f, 0xca, 0xeb, 0xdf, 0xf9, 0xbd, 0x14, 0x79, 0xed, + 0xf4, 0x5d, 0xf9, 0xbb, 0x1a, 0x30, 0xca, 0x5c, 0x5e, 0xc3, 0x85, 0xed, + 0x6c, 0x44, 0x73, 0x5d, 0x4e, 0xc7, 0x4e, 0x9f, 0xa7, 0x3c, 0xbf, 0xdc, + 0x7c, 0x8f, 0x13, 0xef, 0xf9, 0x78, 0x56, 0x77, 0x1c, 0x89, 0xac, 0x91, + 0x54, 0x0d, 0x6f, 0xad, 0x76, 0x5d, 0x72, 0xec, 0x85, 0xcd, 0x44, 0x12, + 0xb2, 0xd4, 0x99, 0x52, 0x52, 0x54, 0x46, 0x69, 0x4d, 0xb9, 0xd2, 0xbb, + 0xcc, 0x69, 0x4a, 0x0a, 0x82, 0x17, 0x75, 0xef, 0xa4, 0x37, 0xd2, 0xbd, + 0x6e, 0xaa, 0x84, 0x0a, 0x80, 0x4a, 0x88, 0xc5, 0x4b, 0x0b, 0x8b, 0x66, + 0x94, 0xa8, 0x88, 0x81, 0x7a, 0x29, 0x7d, 0x97, 0x54, 0xc9, 0xc3, 0xb2, + 0x4b, 0x68, 0x4b, 0xeb, 0x3c, 0x3e, 0xae, 0xcf, 0x1d, 0xc0, 0xa8, 0xc6, + 0xd7, 0x37, 0xc3, 0xf4, 0x0f, 0xc6, 0x7e, 0xaa, 0x19, 0xd5, 0x09, 0x5d, + 0x16, 0x21, 0x54, 0x8d, 0x31, 0xa9, 0x68, 0xed, 0x8b, 0x71, 0x65, 0x8d, + 0x4b, 0x71, 0x6f, 0x38, 0x24, 0xe3, 0xe7, 0x9b, 0xd6, 0x4b, 0x0a, 0x10, + 0xb1, 0x1a, 0x9b, 0xb7, 0xa0, 0x87, 0x61, 0x0b, 0x34, 0x15, 0x95, 0xef, + 0x3c, 0xfe, 0xbc, 0xb7, 0x79, 0xfa, 0xc7, 0xa1, 0xe2, 0x68, 0xe5, 0xe6, + 0xe8, 0xf0, 0xf3, 0x6e, 0xbe, 0x49, 0xb3, 0x38, 0x3a, 0x48, 0x76, 0x5b, + 0xe6, 0xbf, 0x2d, 0xfd, 0x47, 0x93, 0xe8, 0xbf, 0x99, 0xf5, 0x3e, 0x1b, + 0xc7, 0xdc, 0xfb, 0xf3, 0x94, 0x8e, 0x25, 0x9a, 0xf8, 0xac, 0xf3, 0xeb, + 0xd7, 0x79, 0xef, 0x5b, 0xb6, 0x4d, 0x49, 0xe8, 0xd1, 0x8c, 0x74, 0x6a, + 0x2e, 0xb9, 0xf3, 0x1f, 0xa9, 0xf9, 0x3e, 0x77, 0xf4, 0x7f, 0x2d, 0xa2, + 0x11, 0x0b, 0x38, 0xd3, 0xa6, 0xee, 0x3f, 0x47, 0x2d, 0xc5, 0x37, 0x92, + 0xbc, 0xdd, 0xc3, 0xb9, 0x76, 0x2b, 0x9d, 0x8b, 0x64, 0xd4, 0xe6, 0xec, + 0x9b, 0xb2, 0x74, 0xb6, 0x75, 0x93, 0x7e, 0x77, 0xa7, 0xcd, 0xcc, 0xc4, + 0x15, 0x2a, 0x10, 0xc1, 0x45, 0x73, 0x45, 0xba, 0x27, 0xb7, 0x17, 0x69, + 0x8f, 0xa4, 0xae, 0xc8, 0x2c, 0x48, 0x45, 0x6b, 0x9a, 0x48, 0xd9, 0x74, + 0xd0, 0xa8, 0x89, 0x5c, 0x33, 0xa7, 0xac, 0xe8, 0x2e, 0x2c, 0x19, 0x22, + 0x64, 0x95, 0x9d, 0x3e, 0x1d, 0xbd, 0xaf, 0x8b, 0xb9, 0x00, 0x2f, 0x3f, + 0xe1, 0xfd, 0xea, 0xbf, 0x3b, 0xf7, 0x8c, 0x52, 0x90, 0x05, 0x10, 0x0c, + 0x35, 0x0a, 0xcc, 0x8f, 0xd9, 0xe6, 0x5e, 0x2f, 0x55, 0x26, 0x0c, 0xb9, + 0x5a, 0xe0, 0x6f, 0x26, 0xa0, 0x85, 0x86, 0xa2, 0x96, 0x53, 0x57, 0x68, + 0xf3, 0xab, 0x69, 0xd8, 0x44, 0x82, 0x08, 0x08, 0xf5, 0xe5, 0xbf, 0x5f, + 0x33, 0xa1, 0xe5, 0xf3, 0x3c, 0xc0, 0x51, 0x19, 0x0a, 0xab, 0xeb, 0xf0, + 0xc5, 0xfa, 0x7f, 0x29, 0xe2, 0xe9, 0xcd, 0xf3, 0x6b, 0xce, 0x79, 0xba, + 0x7b, 0x3f, 0xca, 0x7b, 0x27, 0xf4, 0x79, 0x4f, 0x79, 0x9c, 0x92, 0xe7, + 0x65, 0xe4, 0xd5, 0x9e, 0x4d, 0x5f, 0xe7, 0xd7, 0xac, 0x4e, 0x87, 0xab, + 0x12, 0xe9, 0x25, 0xd2, 0x4a, 0x9e, 0xe1, 0x51, 0xd3, 0x1f, 0x5c, 0x72, + 0xbd, 0x9c, 0x39, 0xfe, 0xef, 0x3f, 0x3b, 0xf5, 0x3f, 0x1e, 0xbe, 0xb8, + 0x00, 0x8d, 0x99, 0x13, 0xa3, 0x8f, 0x6f, 0x7f, 0x1e, 0xc8, 0x88, 0x44, + 0x44, 0x21, 0x11, 0x22, 0x44, 0x8a, 0xd3, 0x73, 0xe6, 0xba, 0xfc, 0xbc, + 0x8e, 0x70, 0x58, 0xca, 0x11, 0x05, 0x01, 0x5a, 0xb5, 0x6d, 0x75, 0x31, + 0xeb, 0xea, 0xe7, 0xd0, 0x2e, 0x5d, 0x4c, 0x9b, 0xce, 0x5d, 0x4c, 0x9a, + 0xce, 0x5d, 0x4c, 0xb6, 0x66, 0xaa, 0x86, 0x59, 0x17, 0xcb, 0xbb, 0x37, + 0xa3, 0x9b, 0xc8, 0xe9, 0x8a, 0xfa, 0x66, 0xf9, 0x64, 0x04, 0x86, 0x32, + 0x4b, 0xa7, 0x97, 0x4f, 0x7d, 0xe0, 0xf4, 0x0a, 0xc2, 0x5e, 0x3f, 0xe4, + 0xbf, 0x61, 0x2f, 0x07, 0xaa, 0x53, 0x4c, 0x52, 0x16, 0x96, 0x12, 0x90, + 0x58, 0x68, 0x11, 0xcd, 0x5e, 0xcf, 0x1e, 0xbf, 0xd2, 0x7e, 0x7e, 0x9f, + 0x27, 0xab, 0x93, 0xf3, 0xfd, 0xfc, 0x2f, 0x9d, 0xea, 0x37, 0x85, 0x60, + 0x1a, 0x8b, 0x35, 0x73, 0xdd, 0x99, 0xd5, 0xfb, 0x92, 0x95, 0xe7, 0x52, + 0x17, 0xab, 0x89, 0xdf, 0x83, 0xf4, 0xf9, 0xa7, 0xe9, 0xf3, 0x59, 0xea, + 0xf2, 0x6c, 0xd7, 0x9f, 0xa5, 0xf9, 0x6f, 0x5a, 0xe1, 0x4c, 0xd5, 0x94, + 0x51, 0x10, 0x4c, 0x9f, 0x73, 0x86, 0x6f, 0xd1, 0xf9, 0x91, 0x18, 0xf1, + 0xd1, 0xd6, 0xe3, 0xbe, 0xef, 0xc9, 0xed, 0x3e, 0x6b, 0x23, 0x4f, 0xcc, + 0xeb, 0xa7, 0xc5, 0xbd, 0xdc, 0x2f, 0x50, 0xdf, 0xe9, 0xc3, 0xed, 0x95, + 0xda, 0x57, 0xdb, 0x34, 0xf7, 0xcd, 0x1e, 0x9c, 0xf1, 0x3d, 0xde, 0x0a, + 0xbe, 0xa7, 0x82, 0x3e, 0x8e, 0x2a, 0xc5, 0x49, 0x22, 0xa0, 0x08, 0xa6, + 0xe7, 0x19, 0xea, 0x79, 0x7d, 0x5d, 0xb3, 0xaa, 0x11, 0x11, 0x08, 0x44, + 0x48, 0x88, 0xa6, 0xe7, 0xcf, 0x75, 0xf9, 0xb8, 0x6f, 0x18, 0x4b, 0x12, + 0x32, 0xa0, 0x12, 0xa1, 0xab, 0x59, 0x2c, 0x97, 0xa7, 0x8f, 0x5f, 0x4b, + 0x3e, 0x89, 0x4d, 0x30, 0xb4, 0x84, 0x02, 0xb1, 0x08, 0x63, 0x24, 0x59, + 0x2f, 0x03, 0xbf, 0x2f, 0x29, 0xea, 0xe3, 0xa6, 0x2c, 0x96, 0x54, 0x44, + 0x86, 0x31, 0xa9, 0x2f, 0xd0, 0x3e, 0x77, 0xae, 0xfc, 0x85, 0xa7, 0xcf, + 0xe9, 0xe6, 0x7e, 0x3f, 0xf5, 0xf6, 0xe3, 0x6f, 0x35, 0x80, 0x85, 0x0e, + 0xc6, 0xa5, 0x88, 0x52, 0xa1, 0x45, 0x7b, 0xe7, 0xb3, 0xf5, 0x1f, 0x9b, + 0x7e, 0xff, 0x00, 0x0f, 0x23, 0xcb, 0xea, 0xa2, 0x6a, 0x36, 0x47, 0x51, + 0x8f, 0x97, 0x49, 0x66, 0xca, 0xe5, 0xeb, 0x33, 0xb1, 0xef, 0x0b, 0xb7, + 0x23, 0xaf, 0x0b, 0x47, 0x0e, 0x27, 0xe6, 0xde, 0xef, 0xca, 0xfb, 0x67, + 0xe3, 0xb0, 0xdc, 0x21, 0x66, 0xa4, 0x8c, 0x54, 0x98, 0xff, 0x00, 0x49, + 0xe6, 0xcb, 0xf7, 0x78, 0x15, 0x28, 0x49, 0xf3, 0xea, 0xf7, 0xf9, 0xbd, + 0x09, 0x2e, 0x2e, 0xab, 0xcb, 0xec, 0xba, 0xcb, 0x34, 0x9a, 0x3a, 0x76, + 0x48, 0xa2, 0xe3, 0xcb, 0x75, 0xf9, 0x5a, 0x2c, 0x28, 0x12, 0x04, 0x40, + 0x00, 0x85, 0x66, 0x66, 0x33, 0xaf, 0xb0, 0xe5, 0xf5, 0x1a, 0xa1, 0x11, + 0x10, 0x88, 0x88, 0xaa, 0xe7, 0xcf, 0xf5, 0xf9, 0x98, 0x9c, 0xab, 0x20, + 0xa8, 0x44, 0x41, 0x62, 0x12, 0x8a, 0xd6, 0x65, 0x8d, 0x75, 0xf1, 0xec, + 0xd9, 0x9e, 0xf2, 0x56, 0xb2, 0x05, 0x21, 0x00, 0x00, 0x0c, 0x99, 0xc3, + 0xeb, 0xcf, 0xc6, 0x7b, 0x3c, 0xfa, 0x25, 0xb0, 0x9a, 0xb1, 0xc3, 0x18, + 0xc6, 0x39, 0xaf, 0x55, 0xe3, 0xf4, 0x77, 0x38, 0xec, 0x8e, 0x7f, 0xc9, + 0xfb, 0x39, 0xff, 0x00, 0x37, 0xfa, 0x1b, 0x33, 0xa7, 0x28, 0x30, 0x12, + 0x10, 0xa8, 0x01, 0x40, 0x21, 0x66, 0xd1, 0x8b, 0x3f, 0xb3, 0xf2, 0x35, + 0x7e, 0x93, 0xe0, 0xd7, 0xd3, 0x9d, 0x6b, 0x11, 0x09, 0x1d, 0x82, 0x3a, + 0x10, 0x04, 0x61, 0x04, 0x5b, 0xf3, 0xfb, 0x6b, 0xfc, 0xc7, 0xb2, 0xef, + 0x2d, 0x26, 0x61, 0xa0, 0x12, 0xac, 0x84, 0xab, 0x53, 0x9d, 0xfb, 0x7f, + 0x0d, 0x5e, 0xcc, 0x42, 0x14, 0x44, 0xe7, 0x1e, 0x6b, 0xa6, 0x7e, 0x97, + 0x9b, 0xa2, 0x2d, 0x2c, 0xab, 0x2c, 0xb1, 0x25, 0x52, 0x25, 0x4d, 0x1d, + 0x79, 0xbd, 0x7c, 0xfc, 0xfd, 0x3c, 0xd6, 0x85, 0x24, 0x01, 0x62, 0x00, + 0x20, 0xaa, 0x93, 0x23, 0x3d, 0x3c, 0x7b, 0x3d, 0x16, 0x3d, 0xd1, 0x10, + 0x84, 0x21, 0x19, 0xaf, 0x3e, 0x07, 0x5f, 0x9b, 0x9a, 0xf3, 0xae, 0x58, + 0x91, 0x10, 0x08, 0x4a, 0xa5, 0x01, 0x5a, 0xb5, 0xb1, 0xae, 0x84, 0xf4, + 0xf5, 0x39, 0xfa, 0x5a, 0xc8, 0x6a, 0xc2, 0x50, 0x62, 0x00, 0x24, 0x71, + 0x3a, 0xf3, 0xf1, 0x9e, 0xce, 0x16, 0x16, 0x44, 0x89, 0x2c, 0x82, 0x18, + 0xc0, 0x63, 0x97, 0xa1, 0xc7, 0xaf, 0xb6, 0xf1, 0xf7, 0x23, 0x8b, 0xf9, + 0x8f, 0xd5, 0xd9, 0xf3, 0x7d, 0xf2, 0xc6, 0x9e, 0x6b, 0xb0, 0xa0, 0x32, + 0x54, 0x41, 0x45, 0x28, 0x29, 0x42, 0x88, 0xe6, 0xd3, 0xce, 0xd3, 0xd7, + 0x96, 0x9f, 0xd1, 0xfc, 0x2d, 0x3f, 0x6b, 0xe4, 0x2b, 0x22, 0x88, 0x54, + 0xd0, 0x00, 0x46, 0x24, 0x78, 0xd5, 0xff, 0x00, 0x07, 0xd7, 0xa7, 0xe0, + 0x7a, 0x2e, 0xe5, 0x0c, 0xc3, 0x44, 0x28, 0x21, 0xc3, 0xb2, 0x9f, 0xa1, + 0xcb, 0x9d, 0xfb, 0x7f, 0x09, 0x40, 0xe9, 0x92, 0x4b, 0x0b, 0xa2, 0x64, + 0xc9, 0x54, 0xd2, 0x44, 0x89, 0x53, 0x1a, 0x73, 0xf5, 0xc3, 0xcf, 0x74, + 0xf9, 0xba, 0x6a, 0x54, 0x80, 0x06, 0x44, 0x04, 0x02, 0x15, 0x95, 0x26, + 0x34, 0xee, 0xf3, 0xfa, 0x1d, 0xac, 0xfa, 0x90, 0x11, 0x22, 0x72, 0xba, + 0x78, 0xf9, 0x3b, 0xf1, 0xd7, 0x24, 0x08, 0x91, 0x01, 0x09, 0x62, 0x0a, + 0x08, 0x15, 0xcb, 0x25, 0xb1, 0xab, 0x1b, 0xf4, 0x3c, 0xbd, 0xe0, 0xd5, + 0xab, 0x1c, 0x0a, 0x00, 0x08, 0xf2, 0xbe, 0x9e, 0x1e, 0x6f, 0xd1, 0xca, + 0xc2, 0xc5, 0x94, 0x31, 0x92, 0x52, 0x18, 0xc0, 0x07, 0x2c, 0xa6, 0xbd, + 0xcf, 0x83, 0xd3, 0x67, 0x9b, 0xd7, 0xc9, 0xfc, 0x7f, 0xeb, 0x74, 0x63, + 0x6f, 0x9e, 0x9d, 0x38, 0x54, 0xc0, 0x20, 0xa2, 0x10, 0x52, 0x14, 0x2d, + 0x16, 0x4b, 0x2a, 0xf3, 0x69, 0xe7, 0x61, 0xeb, 0xf3, 0x6a, 0xfb, 0xff, + 0x00, 0x13, 0x57, 0xd8, 0xf9, 0x6f, 0x7c, 0xd0, 0x20, 0x00, 0x11, 0x3f, + 0x97, 0xdf, 0x4f, 0xe7, 0xfd, 0x57, 0xf8, 0x75, 0x3c, 0x1c, 0x8e, 0x90, + 0x06, 0x4e, 0x25, 0x4f, 0x59, 0xc5, 0xfa, 0x1f, 0x36, 0x3f, 0xd3, 0x79, + 0x98, 0xea, 0x43, 0x24, 0x4d, 0x24, 0x48, 0x91, 0x24, 0x91, 0x2a, 0x64, + 0x81, 0x2b, 0xb9, 0xf2, 0x9b, 0xf9, 0x96, 0x6f, 0x9d, 0xaa, 0x59, 0x11, + 0x80, 0xc8, 0x80, 0x08, 0x04, 0x24, 0xaa, 0xcc, 0x89, 0xd1, 0xcf, 0xab, + 0xd1, 0xe3, 0xdf, 0x29, 0x71, 0x6b, 0x8f, 0x1f, 0xa7, 0x83, 0x2d, 0xe7, + 0x08, 0x89, 0x11, 0x2a, 0x01, 0x08, 0x40, 0x0a, 0x81, 0x65, 0x2c, 0x96, + 0x4b, 0x4a, 0x7a, 0x8e, 0x7f, 0x4a, 0xd9, 0xa1, 0x58, 0xd5, 0xc0, 0xac, + 0x0a, 0x2c, 0xf1, 0x5e, 0xbf, 0x3f, 0x37, 0xae, 0x6c, 0x18, 0xe1, 0x8c, + 0x60, 0xae, 0x18, 0x00, 0x4a, 0x0c, 0xe9, 0xf0, 0xed, 0xd9, 0xfc, 0x8f, + 0xea, 0xdf, 0xc8, 0xfa, 0x96, 0xab, 0xc6, 0x80, 0x82, 0x0a, 0x29, 0x80, + 0x00, 0x84, 0x12, 0x25, 0x29, 0x48, 0xa5, 0x8c, 0x57, 0x9b, 0x5e, 0x15, + 0xf5, 0xe7, 0x7f, 0xd6, 0xf9, 0xba, 0x3e, 0xb7, 0xcc, 0xd1, 0xf4, 0x3c, + 0x0f, 0x7c, 0xcf, 0x3e, 0xec, 0xf9, 0x1e, 0x8d, 0x1f, 0x13, 0xbd, 0xde, + 0x4d, 0x4e, 0x49, 0x48, 0x50, 0x3a, 0x32, 0x72, 0x89, 0x2c, 0xa7, 0xa8, + 0xba, 0x67, 0x9d, 0xfa, 0xff, 0x00, 0x1e, 0x7f, 0xad, 0xc9, 0x8e, 0xc6, + 0xb2, 0x46, 0x32, 0x54, 0xc9, 0x0c, 0x92, 0x32, 0x43, 0x12, 0x79, 0x6e, + 0x9f, 0x3a, 0xad, 0x70, 0xd1, 0x4e, 0xa2, 0x80, 0xc0, 0x64, 0x01, 0x44, + 0x04, 0x02, 0xa4, 0x95, 0x94, 0x20, 0xde, 0xe9, 0xd6, 0x9b, 0xc2, 0x04, + 0x08, 0x01, 0x10, 0x10, 0x80, 0x40, 0xa0, 0x02, 0x83, 0x56, 0xa4, 0x52, + 0xcf, 0x5a, 0x7a, 0xfb, 0x5c, 0xfd, 0x62, 0xb1, 0x8e, 0x50, 0x85, 0x79, + 0xde, 0xfc, 0xbc, 0xcf, 0xa3, 0x94, 0x6a, 0xd1, 0x88, 0x21, 0x8d, 0x40, + 0x1c, 0x00, 0x0a, 0x40, 0x0b, 0xaf, 0xe4, 0xfd, 0x6e, 0xef, 0xe2, 0xff, + 0x00, 0x59, 0xab, 0x3b, 0x96, 0x2b, 0x50, 0x21, 0x00, 0xa1, 0xd1, 0x4c, + 0x04, 0x10, 0xb2, 0x36, 0x04, 0x8a, 0x01, 0x66, 0xaa, 0x8e, 0x44, 0xc6, + 0x8c, 0x79, 0xb5, 0x6b, 0xc7, 0xb3, 0xa7, 0x86, 0xff, 0x00, 0x3a, 0x58, + 0x34, 0x2c, 0x03, 0x50, 0xa1, 0x1a, 0xbc, 0xa4, 0x3c, 0x25, 0xa3, 0x48, + 0x76, 0xcf, 0x27, 0xf7, 0xbf, 0x3e, 0x3d, 0x72, 0xe9, 0xd3, 0x18, 0xc0, + 0x95, 0x31, 0x8c, 0x92, 0x03, 0x1d, 0x9e, 0x67, 0x5e, 0x0c, 0x9b, 0xf3, + 0x5f, 0x56, 0x05, 0x89, 0x52, 0x35, 0x68, 0x10, 0x50, 0x10, 0x50, 0x48, + 0x52, 0x11, 0x04, 0x81, 0x5a, 0x44, 0x09, 0x2b, 0x22, 0x20, 0x05, 0x48, + 0x09, 0x58, 0x84, 0xa0, 0xd5, 0x8c, 0x22, 0xb6, 0x46, 0xbd, 0x57, 0x3f, + 0xa7, 0x7c, 0xd8, 0x11, 0x9b, 0x53, 0x81, 0xdf, 0x9f, 0x9e, 0xef, 0xce, + 0x9d, 0x4b, 0x25, 0x98, 0xe0, 0x10, 0xc1, 0x40, 0x86, 0x00, 0x12, 0x94, + 0xe0, 0x27, 0xcf, 0xb7, 0x6b, 0xf0, 0x7f, 0xb6, 0xdf, 0xe3, 0xf4, 0xdd, + 0x2b, 0xcd, 0x74, 0xb3, 0x41, 0x08, 0x06, 0x08, 0x68, 0x66, 0x90, 0x00, + 0x86, 0x20, 0x45, 0x48, 0xe8, 0xe3, 0xc3, 0xd6, 0xe3, 0xf3, 0xef, 0xe7, + 0xc5, 0xd8, 0x22, 0xa5, 0x08, 0x8e, 0xa2, 0x85, 0xa8, 0xa8, 0x46, 0x32, + 0x52, 0xcb, 0x16, 0x49, 0x21, 0x6a, 0x63, 0xfb, 0x5c, 0x39, 0xff, 0x00, + 0xab, 0xf2, 0x1a, 0x8e, 0xc7, 0x40, 0xc6, 0x3a, 0x63, 0x1a, 0x31, 0x8e, + 0xa2, 0x9e, 0x6b, 0x5e, 0x1c, 0x5a, 0xf3, 0x68, 0xd4, 0xb1, 0x5a, 0x2a, + 0x40, 0x8d, 0x58, 0x10, 0x00, 0x10, 0x00, 0x02, 0x2a, 0x42, 0x22, 0x56, + 0xcd, 0x65, 0x49, 0x35, 0xb1, 0x41, 0x88, 0x4b, 0x11, 0xa8, 0x21, 0x28, + 0x03, 0x18, 0xd0, 0x66, 0x12, 0x69, 0x9e, 0x8e, 0xe6, 0x7d, 0xfc, 0xce, + 0x99, 0xe3, 0x76, 0xc7, 0x2f, 0xa6, 0x15, 0x39, 0x66, 0xb2, 0x80, 0x04, + 0x00, 0xa0, 0x40, 0x00, 0x39, 0x40, 0x18, 0x2f, 0x4f, 0xf2, 0x9f, 0xa9, + 0xe9, 0xfe, 0x7b, 0xed, 0x69, 0x6a, 0x70, 0xe5, 0x20, 0x85, 0x29, 0x0a, + 0x80, 0xb1, 0xd2, 0x82, 0x90, 0xc0, 0x58, 0xa5, 0x10, 0x05, 0x11, 0xab, + 0x1e, 0x2f, 0x47, 0xc3, 0xe4, 0x58, 0xc9, 0x0a, 0xc3, 0x48, 0xd8, 0xa9, + 0x6a, 0x29, 0x01, 0x50, 0x39, 0x1d, 0x4b, 0x36, 0x59, 0xb3, 0xc8, 0xb2, + 0xbe, 0x93, 0x93, 0xfb, 0x7f, 0x0d, 0x5e, 0xbc, 0x14, 0xec, 0x76, 0x3b, + 0x44, 0x63, 0xa6, 0x30, 0x46, 0x62, 0x28, 0xb3, 0x8b, 0xbf, 0x9d, 0x55, + 0xe3, 0x75, 0x5b, 0x4d, 0x0b, 0x52, 0x21, 0x80, 0xc0, 0xe1, 0xe7, 0xd1, + 0xa5, 0x9d, 0xd7, 0x93, 0xb0, 0x00, 0x01, 0x08, 0x62, 0xb1, 0x11, 0x22, + 0x95, 0x15, 0xa2, 0x27, 0x6b, 0x89, 0x2a, 0x50, 0x6b, 0x11, 0x09, 0x50, + 0x88, 0xa6, 0xd9, 0x5d, 0xe6, 0xa4, 0xa5, 0x72, 0xf4, 0xe9, 0x8b, 0xbf, + 0xa0, 0x56, 0xa2, 0xb5, 0x21, 0x08, 0x8a, 0xa0, 0x80, 0x63, 0x05, 0x00, + 0x11, 0xca, 0x0d, 0x76, 0xfe, 0x7f, 0xef, 0xf5, 0xbf, 0x2b, 0xfa, 0x2d, + 0x58, 0xdd, 0xb6, 0x90, 0xe5, 0x50, 0x42, 0x94, 0x00, 0x1d, 0x20, 0xb0, + 0x15, 0x8a, 0x8b, 0x14, 0xa0, 0xb1, 0x48, 0x05, 0x06, 0xd6, 0x38, 0xf7, + 0x7c, 0xdf, 0x2b, 0xa5, 0x8f, 0x20, 0x3d, 0xc8, 0xc8, 0xa9, 0x58, 0xa9, + 0x22, 0xb5, 0x45, 0xb6, 0x4d, 0x1a, 0xcf, 0x27, 0x9b, 0x59, 0xcf, 0xfd, + 0x37, 0x9b, 0x1f, 0xdd, 0xf3, 0xab, 0x1d, 0x3b, 0x0a, 0x74, 0xd1, 0x8e, + 0x98, 0x01, 0x44, 0xcf, 0xca, 0x27, 0x4d, 0x16, 0x68, 0xbc, 0xf7, 0xef, + 0xcd, 0xd0, 0xdf, 0x9a, 0xeb, 0x82, 0xc1, 0x10, 0x28, 0x22, 0xa9, 0xac, + 0x33, 0xa4, 0x39, 0x7d, 0x0c, 0x57, 0x9f, 0x67, 0xaf, 0x82, 0xfb, 0x86, + 0x30, 0x00, 0x41, 0x44, 0x04, 0x21, 0x0a, 0xa2, 0x91, 0x20, 0x40, 0x88, + 0x95, 0xcb, 0x26, 0x85, 0x42, 0x20, 0x75, 0xf1, 0xe9, 0xef, 0x67, 0xd1, + 0x83, 0xb7, 0x2e, 0x56, 0xb1, 0x42, 0xcd, 0xab, 0xf3, 0xad, 0xd9, 0x42, + 0xdc, 0x87, 0x9c, 0xc6, 0xb8, 0x2d, 0x4f, 0x53, 0x67, 0x6e, 0x56, 0xea, + 0x3a, 0x99, 0x2b, 0x19, 0x21, 0x80, 0xc4, 0xa0, 0xe2, 0xdf, 0x2f, 0xaf, + 0xa5, 0xf9, 0x5f, 0xd2, 0xee, 0xf8, 0xff, 0x00, 0x4f, 0x46, 0x35, 0x6f, + 0x43, 0x83, 0x34, 0x0a, 0x58, 0xab, 0x34, 0x00, 0xa7, 0x63, 0xa4, 0x3a, + 0x52, 0x16, 0xab, 0x16, 0x4b, 0x44, 0x90, 0x88, 0x11, 0xb1, 0x59, 0x0b, + 0x0e, 0xb8, 0xd7, 0xf5, 0xbe, 0x17, 0x9a, 0xf6, 0x78, 0xaa, 0xf4, 0xf2, + 0x92, 0x6a, 0xe4, 0xf4, 0xff, 0x00, 0x23, 0xb7, 0x43, 0xc1, 0xd6, 0xff, + 0x00, 0x26, 0xec, 0xc2, 0xca, 0xba, 0xcb, 0x24, 0x96, 0x81, 0x1c, 0xdc, + 0x1f, 0xa4, 0xf3, 0xe4, 0xfb, 0x5c, 0x0a, 0x07, 0x63, 0x1d, 0x08, 0xec, + 0x29, 0x8c, 0xcb, 0x79, 0xf2, 0xaf, 0x9b, 0x95, 0xaf, 0x37, 0x0b, 0x8f, + 0xd0, 0xc9, 0x7b, 0xdb, 0x52, 0x24, 0x5f, 0xae, 0x7a, 0xb5, 0xc3, 0x4d, + 0xe3, 0x7d, 0xe5, 0x65, 0xc1, 0x5c, 0xfe, 0x7e, 0xc8, 0x67, 0xd3, 0x7a, + 0x74, 0x2d, 0xa2, 0x66, 0xcb, 0x23, 0x79, 0xf3, 0x6e, 0x2a, 0x99, 0xdf, + 0xbe, 0x3a, 0x6e, 0x1a, 0x31, 0x00, 0x08, 0x41, 0x4a, 0x11, 0x15, 0x49, + 0x15, 0x89, 0x12, 0x22, 0x54, 0x40, 0xad, 0x6a, 0x2f, 0xcf, 0x63, 0x3e, + 0x84, 0xb6, 0xd5, 0xab, 0x64, 0x4d, 0x6d, 0x1d, 0xae, 0x39, 0xb9, 0xbe, + 0x3a, 0xde, 0xaf, 0xaf, 0xcf, 0xa3, 0x52, 0x55, 0x21, 0x80, 0xc0, 0x62, + 0x52, 0x5b, 0xfe, 0x7f, 0xd0, 0xdb, 0xf0, 0xbe, 0xce, 0xef, 0x87, 0xf5, + 0xee, 0xe7, 0xbb, 0x65, 0x9e, 0x92, 0x00, 0x52, 0x14, 0x19, 0xa8, 0x20, + 0xa6, 0x30, 0xd0, 0xc8, 0xa6, 0x16, 0x0a, 0xa4, 0x02, 0x95, 0x2d, 0x48, + 0xe5, 0x12, 0x17, 0x2b, 0xdb, 0xe6, 0xc5, 0xf6, 0x3e, 0x5c, 0x7d, 0x1e, + 0x1d, 0xfd, 0xfc, 0xfa, 0x3a, 0x64, 0xa0, 0xae, 0x1e, 0x77, 0x3e, 0x76, + 0xcc, 0x4a, 0x31, 0x3c, 0xc7, 0x2d, 0x6d, 0xf1, 0xeb, 0xaf, 0xcf, 0x5a, + 0x3e, 0xaf, 0x3e, 0x1f, 0xb2, 0x60, 0x64, 0xa9, 0x44, 0xd7, 0x46, 0xb1, + 0xdd, 0xd6, 0x7a, 0xd1, 0x53, 0x39, 0x2f, 0x2c, 0x5a, 0xe5, 0x82, 0xf9, + 0xf3, 0xeb, 0x9d, 0x89, 0x3a, 0x59, 0xd7, 0x93, 0xe1, 0xf5, 0xa5, 0xab, + 0x65, 0x30, 0x10, 0x0c, 0x95, 0x9a, 0x2e, 0x6f, 0x3a, 0x55, 0xa5, 0x3c, + 0x7e, 0x3a, 0x00, 0x02, 0x44, 0xb1, 0x42, 0xe6, 0xcb, 0xce, 0x5a, 0xe5, + 0x6d, 0xe7, 0xd0, 0xd7, 0x2e, 0x95, 0xe7, 0x21, 0x00, 0x08, 0x4a, 0x84, + 0x44, 0x4b, 0x18, 0x81, 0x54, 0xd5, 0x2d, 0x67, 0x33, 0x2c, 0x17, 0x5e, + 0x3b, 0xd7, 0x37, 0x9e, 0x5c, 0x4b, 0x49, 0x54, 0xb0, 0x58, 0x10, 0x5a, + 0x22, 0x3a, 0xd7, 0x63, 0x59, 0xd7, 0xd7, 0x9e, 0xde, 0xdc, 0xf5, 0xef, + 0x2e, 0xc7, 0x02, 0xa2, 0x7e, 0x3f, 0x7e, 0xff, 0x00, 0x85, 0xf6, 0x36, + 0x7c, 0x7f, 0xab, 0x77, 0x8b, 0xbd, 0x96, 0xd9, 0x35, 0x2b, 0x25, 0x69, + 0x05, 0x18, 0x2b, 0x4a, 0x20, 0x82, 0x00, 0x56, 0x08, 0xe9, 0xe8, 0x0c, + 0x59, 0x14, 0x40, 0x3e, 0xfc, 0xe3, 0xcb, 0x72, 0xe9, 0x99, 0xfb, 0x7c, + 0x79, 0x7d, 0xde, 0x5e, 0x37, 0xaf, 0xcd, 0xe5, 0xbd, 0x5e, 0x3c, 0xae, + 0x7d, 0xad, 0xe2, 0x76, 0x46, 0xc8, 0x59, 0x1b, 0x9a, 0xac, 0xa6, 0xcc, + 0xa6, 0x38, 0xaa, 0x59, 0x44, 0xc8, 0x35, 0x9b, 0x1d, 0xb3, 0xd9, 0x34, + 0x96, 0x75, 0x12, 0xad, 0x61, 0xef, 0x9f, 0xa3, 0xe9, 0xe6, 0xf5, 0xcf, + 0x1a, 0xb9, 0x92, 0x4e, 0xa4, 0x92, 0xb6, 0x43, 0x0a, 0xcd, 0xcf, 0xa7, + 0x91, 0xe3, 0xf5, 0x2d, 0xd2, 0xda, 0x01, 0x01, 0x80, 0x0a, 0x98, 0x45, + 0x4a, 0x20, 0xad, 0x10, 0x2a, 0x02, 0x26, 0x58, 0xe4, 0x5c, 0xd1, 0x2d, + 0xd7, 0x3d, 0x6d, 0x71, 0xea, 0x6b, 0x97, 0x52, 0xf1, 0xe8, 0xeb, 0x9b, + 0x31, 0x4d, 0xf1, 0x71, 0xe9, 0xcb, 0x9e, 0x94, 0x5d, 0xac, 0xdd, 0x32, + 0xb5, 0xe7, 0xdd, 0x64, 0x95, 0xc9, 0x65, 0x97, 0x25, 0x9b, 0x9d, 0x6c, + 0xe6, 0xaa, 0xcd, 0x97, 0x2b, 0x56, 0xd2, 0xc8, 0x63, 0x05, 0x6b, 0x29, + 0x63, 0x0c, 0xd9, 0xd6, 0xf6, 0x7d, 0xbe, 0x27, 0xa8, 0x95, 0x45, 0x6b, + 0x56, 0x37, 0x2f, 0x3f, 0xaa, 0xdf, 0x17, 0xaa, 0xdf, 0x27, 0xae, 0xff, + 0x00, 0x37, 0xa6, 0xdf, 0x37, 0x6c, 0xdb, 0xe5, 0x8f, 0xd1, 0xe7, 0xa7, + 0xb7, 0x28, 0x6b, 0x0b, 0x50, 0x96, 0x59, 0xad, 0x4c, 0xe9, 0xc4, 0x86, + 0x6a, 0xf5, 0x79, 0xca, 0xb1, 0x34, 0xd9, 0xbe, 0xca, 0xfe, 0x5f, 0xd6, + 0xb7, 0xc3, 0xeb, 0xdf, 0xe8, 0xe3, 0xb7, 0xbf, 0x9a, 0xef, 0x4f, 0x9a, + 0x8f, 0x5f, 0x9b, 0xcc, 0x74, 0xcf, 0x03, 0x9f, 0x4c, 0x39, 0x95, 0xeb, + 0x9f, 0x2f, 0xa6, 0x29, 0x93, 0xa1, 0x34, 0xac, 0x8e, 0xb0, 0x90, 0x25, + 0x66, 0xa8, 0xeb, 0xa4, 0xb5, 0x04, 0xab, 0x57, 0x99, 0x9b, 0x54, 0xb5, + 0x4b, 0x4b, 0x51, 0x8b, 0xaa, 0xcc, 0x23, 0x73, 0xbf, 0xaf, 0x9f, 0xd4, + 0xf4, 0xf1, 0x68, 0x49, 0x28, 0x8c, 0x29, 0x94, 0x4d, 0x72, 0x71, 0xdb, + 0x8d, 0x9e, 0xdc, 0xde, 0x7e, 0x8d, 0x4d, 0xed, 0xd4, 0x95, 0x8c, 0x02, + 0x98, 0x00, 0x05, 0x81, 0x56, 0x74, 0x20, 0x00, 0xa9, 0x10, 0x8a, 0x0e, + 0x55, 0x65, 0xca, 0xc5, 0xb0, 0x68, 0x01, 0x65, 0x9a, 0xee, 0x68, 0x9d, + 0x2d, 0x4b, 0xe3, 0x5c, 0x8b, 0x4c, 0x96, 0xf3, 0xe5, 0xae, 0x18, 0xd2, + 0x76, 0x5d, 0x99, 0x0e, 0xae, 0xaf, 0x29, 0x4b, 0x59, 0x64, 0xe7, 0x56, + 0x4d, 0xb5, 0x59, 0xb0, 0xb2, 0x18, 0xcb, 0xd6, 0xec, 0x75, 0x26, 0xa1, + 0x13, 0xed, 0xcd, 0x74, 0xe2, 0x8a, 0xe2, 0x32, 0xc3, 0x36, 0xb9, 0xa8, + 0x42, 0x2b, 0x88, 0x2c, 0x8d, 0x46, 0x84, 0xbb, 0x16, 0xd8, 0xd7, 0x8c, + 0xac, 0xae, 0xcc, 0x9a, 0x38, 0xab, 0x4a, 0x75, 0x4b, 0x72, 0x74, 0xb4, + 0x5b, 0x55, 0x55, 0x57, 0x45, 0x36, 0x46, 0x6a, 0x65, 0xf6, 0x2a, 0xa6, + 0x09, 0x6d, 0xc6, 0xee, 0xc7, 0x56, 0xb5, 0x48, 0x75, 0xe3, 0x1e, 0x9c, + 0x92, 0x15, 0x12, 0x8a, 0xcb, 0x2d, 0xb9, 0x9a, 0x16, 0xe3, 0x76, 0x67, + 0x3f, 0xb1, 0xf3, 0x43, 0x4a, 0xe5, 0x8c, 0xd4, 0x17, 0x55, 0x9b, 0xe3, + 0x46, 0x25, 0x9a, 0xc5, 0xfa, 0xe4, 0xee, 0x69, 0xd5, 0xb2, 0x4c, 0x98, + 0xe9, 0xc5, 0xcf, 0x6c, 0x13, 0xa1, 0x56, 0x1b, 0xcd, 0xd6, 0x4e, 0xc6, + 0x3a, 0x43, 0x00, 0x00, 0x0a, 0x12, 0xbc, 0xd0, 0x28, 0x84, 0x44, 0xa6, + 0xcc, 0x46, 0x02, 0xa9, 0x67, 0x13, 0x5b, 0x0b, 0x4b, 0x25, 0xbd, 0x2e, + 0xa9, 0xa3, 0xb2, 0x15, 0x51, 0x9c, 0xa2, 0x55, 0x0e, 0xc9, 0x05, 0x8e, + 0xae, 0xcc, 0xa5, 0x74, 0xf5, 0x9b, 0xb8, 0x4c, 0x2d, 0x62, 0xb2, 0x8d, + 0x4a, 0xed, 0x65, 0xb6, 0x69, 0x2f, 0x4b, 0x61, 0x4b, 0x16, 0xa3, 0x0e, + 0x68, 0xce, 0xd4, 0xaa, 0xc8, 0x9d, 0x2f, 0x3b, 0x4f, 0x39, 0xcb, 0xf5, + 0xe3, 0x27, 0x49, 0x58, 0x4a, 0x1a, 0xac, 0xd2, 0x92, 0x9a, 0xdd, 0x96, + 0xdc, 0x4d, 0xfc, 0xa4, 0x52, 0xc8, 0x9c, 0x92, 0xc8, 0x2b, 0xd5, 0x55, + 0xcf, 0xef, 0x79, 0xfb, 0xd6, 0x1d, 0x48, 0xaf, 0x4f, 0xc3, 0xd7, 0xd9, + 0x7c, 0xde, 0x9c, 0x6f, 0x74, 0xf2, 0x1f, 0x43, 0x2b, 0x96, 0xae, 0x5b, + 0x09, 0x05, 0xcc, 0x37, 0x88, 0x6f, 0x9d, 0x77, 0x35, 0xd9, 0x51, 0x4d, + 0xb4, 0x94, 0x4b, 0x5c, 0xb7, 0xe7, 0x3b, 0xa5, 0xd4, 0x5e, 0xba, 0x19, + 0xc3, 0xde, 0x65, 0xe7, 0xab, 0xa6, 0x68, 0xdd, 0x86, 0x42, 0x92, 0xa5, + 0x9d, 0x68, 0x4b, 0xe5, 0xb6, 0x49, 0x4b, 0x54, 0xb4, 0x2e, 0x75, 0xcf, + 0x65, 0x44, 0x12, 0x55, 0xa8, 0xd3, 0x66, 0x82, 0xd2, 0x6b, 0x24, 0x90, + 0x0c, 0x05, 0x4e, 0x39, 0x20, 0x20, 0x12, 0x44, 0x4a, 0x13, 0x89, 0x13, + 0x26, 0xae, 0xc2, 0x15, 0x56, 0x44, 0x82, 0x25, 0x11, 0x00, 0x58, 0x00, + 0xd1, 0xc0, 0x55, 0xab, 0x67, 0x49, 0xd1, 0xe5, 0x9b, 0x39, 0xeb, 0x1a, + 0xe0, 0xac, 0xdd, 0x24, 0xb5, 0x2e, 0x2d, 0x8b, 0x09, 0xa4, 0x96, 0x70, + 0x42, 0x52, 0x51, 0x58, 0x41, 0x40, 0x0c, 0x62, 0x00, 0x04, 0x14, 0x00, + 0x41, 0x40, 0x18, 0x00, 0x90, 0x20, 0xb1, 0xa8, 0x11, 0x84, 0x21, 0x02, + 0x48, 0x92, 0x4e, 0xa4, 0x8c, 0x62, 0xa8, 0x15, 0xd4, 0x22, 0x05, 0x76, + 0xd6, 0x42, 0x22, 0x59, 0x9b, 0xab, 0x2d, 0x71, 0xb1, 0x98, 0x75, 0x9c, + 0xee, 0x9a, 0xaf, 0x9d, 0xb7, 0x31, 0x91, 0xa5, 0x48, 0x4a, 0x40, 0x25, + 0x06, 0x48, 0x99, 0x64, 0x31, 0x2a, 0x23, 0x11, 0xa2, 0x15, 0x00, 0x48, + 0x64, 0x80, 0x62, 0x31, 0x5c, 0x20, 0x05, 0x00, 0x00, 0x60, 0x34, 0x15, + 0x80, 0x05, 0x4c, 0xb1, 0x27, 0x12, 0x1c, 0x00, 0x21, 0x50, 0x15, 0x3a, + 0xb7, 0x32, 0xec, 0xa7, 0x94, 0x56, 0xb9, 0x6b, 0x2a, 0x5a, 0xac, 0xae, + 0xa1, 0x4a, 0x80, 0xa6, 0x80, 0xc6, 0x30, 0x18, 0xc0, 0x00, 0x60, 0x30, + 0x1a, 0x0a, 0x00, 0x00, 0x08, 0x00, 0x00, 0x60, 0x02, 0x00, 0x12, 0x0a, + 0xa9, 0x04, 0x02, 0x01, 0x08, 0x41, 0x08, 0x4a, 0x0e, 0x25, 0x13, 0x8b, + 0x62, 0xe2, 0xd2, 0xd4, 0x76, 0x43, 0x4a, 0xb4, 0xab, 0x56, 0xb8, 0x41, + 0x00, 0x08, 0x00, 0x40, 0x02, 0x00, 0x18, 0xc0, 0x06, 0x48, 0x02, 0x23, + 0x50, 0x22, 0x44, 0x88, 0x8f, 0xff, 0xc4, 0x00, 0x32, 0x10, 0x00, 0x02, + 0x02, 0x01, 0x03, 0x02, 0x05, 0x02, 0x06, 0x03, 0x01, 0x01, 0x01, 0x01, + 0x01, 0x00, 0x00, 0x01, 0x02, 0x03, 0x11, 0x04, 0x05, 0x12, 0x10, 0x13, + 0x06, 0x14, 0x20, 0x21, 0x31, 0x22, 0x30, 0x15, 0x23, 0x32, 0x33, 0x34, + 0x40, 0x07, 0x24, 0x41, 0x16, 0x42, 0x50, 0x25, 0x26, 0xff, 0xda, 0x00, + 0x08, 0x01, 0x01, 0x00, 0x01, 0x05, 0x02, 0xff, 0x00, 0xf2, 0x32, 0x64, + 0xc9, 0x93, 0x26, 0x4c, 0x99, 0x32, 0x64, 0xc9, 0x93, 0x26, 0x4c, 0x9c, + 0x8e, 0x47, 0x23, 0x91, 0xc8, 0xe6, 0x77, 0x0e, 0xea, 0x2b, 0xae, 0x56, + 0x9e, 0x56, 0xc3, 0xca, 0xd8, 0x2d, 0x24, 0x85, 0xa3, 0x89, 0xe5, 0x2b, + 0x3c, 0xb5, 0x47, 0x97, 0xa8, 0xec, 0xd4, 0x76, 0x6b, 0x3b, 0x55, 0x9d, + 0xaa, 0xce, 0xdd, 0x67, 0x6e, 0x07, 0x6e, 0xb3, 0xb7, 0x03, 0x84, 0x0e, + 0x11, 0x38, 0x44, 0xe1, 0x13, 0x84, 0x4e, 0x11, 0x38, 0xc4, 0xe3, 0x13, + 0x8c, 0x4e, 0x31, 0x38, 0x44, 0xe1, 0x13, 0x84, 0x4e, 0x11, 0x38, 0x44, + 0xe1, 0x13, 0x84, 0x4e, 0x11, 0x3b, 0x71, 0x3b, 0x71, 0x3b, 0x71, 0x3b, + 0x71, 0x3b, 0x71, 0x3b, 0x51, 0x3b, 0x51, 0x3b, 0x51, 0x3b, 0x51, 0x3b, + 0x51, 0x3b, 0x51, 0x3b, 0x51, 0x3b, 0x50, 0x3b, 0x50, 0x3b, 0x30, 0x3b, + 0x30, 0x3b, 0x30, 0x3b, 0x30, 0x3b, 0x15, 0x9d, 0x8a, 0xcf, 0x2f, 0x59, + 0xe5, 0xeb, 0x3c, 0xb5, 0x67, 0x96, 0xa8, 0xf2, 0xb5, 0x1e, 0x4e, 0xa1, + 0xe8, 0x6a, 0x1e, 0xdf, 0x02, 0x5b, 0x7b, 0x27, 0xa6, 0x9d, 0x7d, 0x32, + 0x8e, 0x48, 0xe4, 0x8e, 0x48, 0xe4, 0x8e, 0x48, 0xe4, 0x8e, 0x46, 0x4c, + 0x99, 0x32, 0x64, 0xc9, 0x93, 0x3d, 0x33, 0xff, 0x00, 0xe4, 0x63, 0xd0, + 0xc6, 0xcd, 0x3c, 0xa7, 0xdc, 0x8f, 0xc7, 0x5c, 0x18, 0x31, 0xd3, 0x06, + 0x0c, 0x18, 0xe9, 0x8f, 0xbd, 0x9f, 0xff, 0x00, 0x0d, 0xb4, 0x6a, 0xf4, + 0xe6, 0xab, 0x4e, 0x27, 0xf6, 0x72, 0x64, 0xcb, 0x32, 0xce, 0x4c, 0xe6, + 0xce, 0x6c, 0xe6, 0x73, 0x39, 0x9c, 0xcc, 0xff, 0x00, 0xf8, 0xd8, 0x38, + 0x8e, 0x24, 0xa2, 0x51, 0x5d, 0x8e, 0xca, 0xeb, 0x72, 0x87, 0x64, 0xed, + 0x1d, 0xa3, 0xb4, 0x76, 0x8e, 0xd1, 0xda, 0x3b, 0x67, 0x03, 0x81, 0xc0, + 0xe0, 0x71, 0x38, 0x9c, 0x4e, 0x27, 0x13, 0x06, 0x0c, 0x18, 0x30, 0x63, + 0xfb, 0x3c, 0x92, 0x3b, 0xb1, 0x47, 0x98, 0x89, 0xe6, 0x51, 0xe6, 0x8f, + 0x34, 0xcf, 0x34, 0xcf, 0x31, 0x23, 0xbf, 0x23, 0xbd, 0x23, 0xba, 0xce, + 0xeb, 0x3b, 0x87, 0x33, 0x99, 0xcb, 0xa6, 0xaa, 0xae, 0xdc, 0xff, 0x00, + 0xa5, 0x93, 0x27, 0x23, 0xb8, 0x2b, 0x11, 0x9c, 0xff, 0x00, 0x7b, 0x06, + 0x0e, 0x02, 0xa5, 0xb2, 0x1b, 0x76, 0xa2, 0xc2, 0x1b, 0x0e, 0xb6, 0x64, + 0x3c, 0x2d, 0xaf, 0x98, 0xbc, 0x1b, 0xac, 0x91, 0xa1, 0xf0, 0xad, 0xfa, + 0x58, 0x2f, 0x0f, 0xd8, 0x2f, 0x0f, 0xc8, 0x5b, 0x00, 0xb6, 0x08, 0x9f, + 0x80, 0xc0, 0xfc, 0x06, 0x07, 0xe0, 0x31, 0x3f, 0x01, 0x43, 0xd8, 0x47, + 0xb0, 0xc8, 0x7b, 0x1d, 0x83, 0xd9, 0xae, 0x44, 0xb6, 0xbb, 0x51, 0x2d, + 0x0c, 0xd0, 0xf4, 0xcc, 0x74, 0x1d, 0x93, 0xb6, 0x70, 0x38, 0x9c, 0x4c, + 0x7f, 0x59, 0x92, 0xbe, 0x28, 0x7a, 0xa1, 0xea, 0x24, 0xc7, 0x36, 0xff, + 0x00, 0xa5, 0x75, 0x7d, 0xda, 0xff, 0x00, 0xaf, 0x9c, 0x11, 0xb4, 0x4f, + 0x3f, 0xd8, 0xc0, 0xa0, 0xd9, 0xa7, 0xda, 0x35, 0x5a, 0x92, 0x8f, 0x07, + 0x6b, 0x2c, 0x29, 0xf0, 0x4c, 0x51, 0x57, 0x84, 0xb4, 0x35, 0x95, 0xec, + 0x7a, 0x2a, 0x88, 0x69, 0x6a, 0xac, 0xe0, 0x71, 0x38, 0x9c, 0x4c, 0x18, + 0x38, 0x9c, 0x4c, 0x18, 0x30, 0x60, 0xc1, 0x83, 0x06, 0x0c, 0x18, 0x30, + 0x3a, 0xe2, 0xc9, 0x68, 0xea, 0x91, 0x2d, 0xae, 0x96, 0x4f, 0x67, 0x45, + 0x9b, 0x55, 0x91, 0x2c, 0xd1, 0xca, 0x03, 0xa8, 0x70, 0x38, 0x9c, 0x4c, + 0x7f, 0x45, 0xc9, 0x45, 0x4f, 0x54, 0x4a, 0xc7, 0x2f, 0x46, 0x7f, 0xa7, + 0xaa, 0x87, 0x1b, 0x7f, 0xb1, 0x1c, 0xa2, 0x2b, 0x2b, 0x80, 0xa9, 0x93, + 0x16, 0x9a, 0x6c, 0xf2, 0x96, 0x1e, 0x4e, 0xc3, 0xca, 0x4c, 0xf2, 0xb2, + 0x3c, 0xb4, 0x8f, 0x2f, 0x23, 0xb2, 0xce, 0xd9, 0xdb, 0x38, 0x1c, 0x0e, + 0x27, 0x13, 0x89, 0xc4, 0xc1, 0xc4, 0xd3, 0xed, 0xda, 0x8d, 0x51, 0xa6, + 0xf0, 0x7e, 0xb2, 0xe3, 0x4b, 0xe0, 0xbd, 0x3d, 0x66, 0x9b, 0x67, 0xd2, + 0x69, 0x05, 0x03, 0x89, 0xc4, 0xe2, 0x71, 0x38, 0x9c, 0x4e, 0x27, 0x13, + 0x81, 0xc0, 0xe0, 0x71, 0x38, 0x9c, 0x4e, 0x27, 0x13, 0x06, 0x0c, 0x18, + 0x30, 0x60, 0xc1, 0x83, 0x1e, 0x97, 0x1c, 0x96, 0x68, 0x6a, 0xb0, 0xbb, + 0x6b, 0x68, 0xb3, 0x4e, 0xe0, 0xdc, 0x07, 0x11, 0xa3, 0x1e, 0x95, 0xea, + 0xc9, 0x9e, 0x96, 0x5d, 0xc0, 0x94, 0xdc, 0x9f, 0xf5, 0xb0, 0x60, 0xd6, + 0xaf, 0xe9, 0xe0, 0xc0, 0xa0, 0x53, 0xa0, 0xbe, 0xf2, 0xaf, 0x0d, 0x6b, + 0xac, 0x2a, 0xf0, 0x7d, 0xcc, 0xaf, 0xc1, 0xf5, 0x22, 0xaf, 0x0d, 0xe9, + 0x6b, 0x23, 0xb3, 0xe9, 0x60, 0x2d, 0xbb, 0x4e, 0x8f, 0x25, 0x42, 0x3c, + 0xad, 0x27, 0x95, 0xa8, 0xfc, 0x3f, 0x4e, 0xcf, 0xc3, 0x34, 0xc7, 0xe1, + 0x7a, 0x63, 0xf0, 0x9d, 0x31, 0xf8, 0x36, 0x99, 0x8f, 0x61, 0xd3, 0xb1, + 0xf8, 0x76, 0x96, 0x4b, 0xc3, 0x11, 0x27, 0xe1, 0x79, 0x92, 0xf0, 0xd5, + 0xd9, 0x8f, 0x83, 0xf3, 0x09, 0xf8, 0x3a, 0xe2, 0xbf, 0x05, 0xd8, 0xca, + 0x3c, 0x1d, 0xa5, 0x81, 0xa7, 0xd9, 0x34, 0x7a, 0x61, 0x43, 0x06, 0x0e, + 0x27, 0x13, 0x89, 0xc4, 0xe2, 0x71, 0x38, 0x9c, 0x4e, 0x07, 0x03, 0x81, + 0xc0, 0xe0, 0x70, 0x38, 0x1c, 0x4e, 0x27, 0x13, 0x89, 0xc4, 0xc1, 0xc4, + 0xc1, 0x83, 0x06, 0x0c, 0x18, 0xfb, 0x13, 0xae, 0x33, 0x5a, 0x8d, 0xb1, + 0x32, 0xda, 0x1d, 0x6d, 0xc4, 0xc1, 0x83, 0x06, 0x0c, 0x08, 0xc9, 0x93, + 0x27, 0x21, 0xcd, 0x22, 0x5a, 0x98, 0x21, 0x5d, 0x19, 0x16, 0x6a, 0x14, + 0x47, 0x3c, 0x99, 0xfe, 0x96, 0x0c, 0x18, 0x30, 0x60, 0xe2, 0x71, 0x35, + 0xb0, 0xfa, 0x78, 0x1c, 0x4e, 0x27, 0x13, 0x06, 0x0c, 0x7d, 0xac, 0x1a, + 0x7d, 0x0d, 0xfa, 0xa7, 0xa7, 0xf0, 0x96, 0xa2, 0xc5, 0xa6, 0xf0, 0x9e, + 0x9e, 0xb2, 0x8d, 0xb7, 0x4b, 0xa6, 0xfe, 0xb6, 0x04, 0x84, 0x8c, 0x18, + 0x38, 0x98, 0x38, 0x9c, 0x4e, 0x27, 0x13, 0x81, 0xc0, 0xe0, 0x70, 0x38, + 0x9c, 0x4e, 0x27, 0x13, 0x89, 0xc4, 0xe2, 0x71, 0x38, 0x9c, 0x4e, 0x27, + 0x13, 0x89, 0x83, 0x06, 0x06, 0x8c, 0x7d, 0xbb, 0x69, 0x8d, 0xaa, 0x7b, + 0x54, 0x1b, 0xfc, 0x22, 0xb3, 0xf0, 0x9a, 0x4f, 0xc3, 0x28, 0x3f, 0x0e, + 0xd3, 0x9f, 0x86, 0xe9, 0xcf, 0xc3, 0x34, 0xc7, 0xe1, 0x9a, 0x63, 0xf0, + 0xbd, 0x30, 0xf6, 0x8d, 0x3b, 0x2d, 0xd9, 0x6a, 0xe1, 0xad, 0x94, 0xe1, + 0x2c, 0x4a, 0x72, 0x79, 0x8b, 0xa3, 0x51, 0x64, 0x65, 0x09, 0x36, 0xb3, + 0xf7, 0x30, 0x60, 0xc1, 0x83, 0x07, 0x13, 0x89, 0xc0, 0xe2, 0x71, 0x38, + 0x9f, 0x84, 0x68, 0x4f, 0xc1, 0xf4, 0x04, 0xf6, 0x1d, 0xb6, 0xc2, 0x7e, + 0x11, 0xd9, 0xec, 0x3f, 0xf1, 0x3b, 0x21, 0x77, 0xf8, 0xff, 0x00, 0x65, + 0xb4, 0xb3, 0xfc, 0x63, 0xb6, 0x48, 0xbf, 0xfc, 0x57, 0x53, 0x2f, 0xff, + 0x00, 0x17, 0xeb, 0xe0, 0xf5, 0x7e, 0x07, 0xdd, 0xb4, 0xa6, 0xa3, 0x6f, + 0xd4, 0x69, 0x5f, 0x13, 0x1e, 0x8c, 0x10, 0xaa, 0x56, 0x3d, 0x17, 0x86, + 0x35, 0x3a, 0x83, 0x49, 0xe1, 0xdd, 0x1e, 0x98, 0x8a, 0x50, 0x5d, 0x72, + 0x64, 0xcf, 0xdf, 0x5d, 0x52, 0x12, 0x12, 0x12, 0x12, 0x12, 0x12, 0x14, + 0x45, 0x11, 0x44, 0xe2, 0x71, 0x38, 0x0a, 0x07, 0x68, 0x55, 0x23, 0xb6, + 0x8e, 0x08, 0xe0, 0x70, 0x38, 0x1d, 0xb3, 0x81, 0xc0, 0xe0, 0x38, 0x1c, + 0x4e, 0x27, 0x13, 0x88, 0xe2, 0x34, 0x34, 0x34, 0x34, 0x3f, 0xe8, 0xe4, + 0xcf, 0x5f, 0x14, 0xcd, 0x4f, 0x5f, 0xb5, 0xe9, 0xe1, 0x64, 0xe9, 0xf0, + 0x8e, 0x96, 0xe3, 0x4f, 0xe1, 0xfd, 0xbf, 0x4c, 0xac, 0xd8, 0xb4, 0x76, + 0x16, 0xf8, 0x66, 0x05, 0xbe, 0x1f, 0xd5, 0x56, 0x5b, 0xa5, 0xb2, 0x97, + 0x8f, 0xb1, 0x83, 0x02, 0xad, 0xc8, 0xd3, 0x78, 0x7f, 0x70, 0xd5, 0x1a, + 0x6f, 0x01, 0x6e, 0x56, 0xba, 0x7f, 0xc7, 0x31, 0xc5, 0x5e, 0x02, 0xdb, + 0xa0, 0x47, 0xc1, 0xdb, 0x42, 0x17, 0x84, 0xf6, 0x94, 0x47, 0xc2, 0xdb, + 0x54, 0x48, 0x6c, 0x5b, 0x75, 0x67, 0xe1, 0x1a, 0x1f, 0xb5, 0x28, 0x29, + 0x1a, 0x8d, 0x24, 0x64, 0xb5, 0x7e, 0x19, 0xdb, 0xaf, 0x7a, 0xcf, 0x02, + 0xe8, 0xec, 0x35, 0x7e, 0x09, 0xd6, 0x52, 0x6a, 0xb6, 0xed, 0x46, 0x8d, + 0xc6, 0xb7, 0x27, 0xb7, 0x78, 0x5a, 0xeb, 0xcd, 0x26, 0xdd, 0xa7, 0xd0, + 0xc7, 0xa6, 0x4c, 0x99, 0xe9, 0x93, 0x26, 0x4c, 0x99, 0x32, 0x64, 0xc9, + 0x93, 0x3e, 0xb4, 0x21, 0x08, 0x42, 0x12, 0x12, 0x12, 0x14, 0x44, 0x85, + 0x11, 0x44, 0x51, 0x14, 0x05, 0x11, 0x44, 0xe2, 0x63, 0xd5, 0x83, 0x07, + 0x11, 0xc4, 0xe2, 0x38, 0x8e, 0x23, 0x88, 0xe2, 0x38, 0x8e, 0x23, 0x88, + 0xd0, 0xd0, 0xd0, 0xc6, 0x3f, 0xbb, 0x93, 0x26, 0x4c, 0x99, 0x32, 0x78, + 0xc6, 0xdc, 0xcb, 0xc3, 0xfa, 0x7f, 0x2f, 0xb6, 0xfa, 0x11, 0xc5, 0x49, + 0x5d, 0xb1, 0x69, 0x35, 0x06, 0xab, 0xc2, 0xb6, 0xc0, 0xbb, 0x49, 0x6e, + 0x9a, 0x58, 0x30, 0x60, 0x50, 0x6c, 0xd0, 0x78, 0x63, 0x70, 0xdc, 0x1e, + 0x93, 0xfc, 0x73, 0x36, 0x69, 0xbc, 0x0b, 0xb6, 0x50, 0x69, 0x36, 0xed, + 0x2e, 0x81, 0x7f, 0x4f, 0xe4, 0xbe, 0x82, 0xda, 0xf0, 0x4e, 0x25, 0xb5, + 0xc6, 0x6a, 0xbd, 0xaf, 0x4b, 0xa6, 0xba, 0x43, 0xe9, 0x93, 0x26, 0x4c, + 0x99, 0x32, 0x64, 0xc9, 0x93, 0x26, 0x4c, 0xf4, 0xcf, 0xa9, 0x08, 0x42, + 0x10, 0x84, 0x24, 0x24, 0x24, 0x24, 0x24, 0x28, 0x8a, 0x22, 0x88, 0xa2, + 0x24, 0x63, 0xee, 0xe0, 0x71, 0x1c, 0x47, 0x11, 0xa1, 0xc4, 0xe2, 0x34, + 0x34, 0x34, 0x34, 0x31, 0x8c, 0x7e, 0x96, 0x3f, 0xb3, 0x93, 0x26, 0x4f, + 0x12, 0x3e, 0xfe, 0xef, 0x44, 0x3b, 0x75, 0x75, 0x42, 0x11, 0x12, 0x28, + 0x96, 0x92, 0xbd, 0x54, 0x35, 0xde, 0x06, 0xee, 0xaa, 0x7c, 0x1d, 0xba, + 0x5d, 0x76, 0xdd, 0xfe, 0x3c, 0xaa, 0xb3, 0x45, 0xb3, 0x68, 0xb6, 0xef, + 0xec, 0xb5, 0x93, 0x53, 0x49, 0x6c, 0x49, 0xa2, 0x44, 0x89, 0x0c, 0xc9, + 0x93, 0x26, 0x4c, 0x99, 0x32, 0x64, 0xc9, 0x93, 0x26, 0x7a, 0x67, 0xa2, + 0xea, 0x84, 0x21, 0x08, 0x42, 0x10, 0x84, 0x84, 0x84, 0x85, 0x11, 0x44, + 0x48, 0x48, 0xc7, 0xf4, 0x9a, 0x1a, 0x1a, 0x1a, 0x1a, 0x1a, 0x18, 0xd0, + 0xc6, 0x31, 0x8c, 0x7d, 0x58, 0xfe, 0xce, 0x4c, 0x99, 0x2c, 0x5e, 0x67, + 0xc5, 0x0b, 0xaa, 0x10, 0x88, 0x91, 0x2b, 0x46, 0x9e, 0xa2, 0xa8, 0xe3, + 0xfb, 0xb6, 0xc7, 0x31, 0xd4, 0xc3, 0x05, 0x84, 0xc9, 0x12, 0x19, 0x93, + 0x26, 0x4c, 0x99, 0x32, 0x64, 0xc9, 0x93, 0x26, 0x4c, 0xfa, 0x50, 0x84, + 0x21, 0x08, 0x42, 0x10, 0x84, 0x44, 0x48, 0x48, 0x48, 0x48, 0x4b, 0xfa, + 0x79, 0x1b, 0xea, 0xc9, 0x0c, 0x63, 0x18, 0xc6, 0x31, 0x8c, 0x7d, 0x58, + 0xc7, 0xd1, 0xfa, 0x72, 0x67, 0xa6, 0xcc, 0xbb, 0xde, 0x20, 0x33, 0xd1, + 0x08, 0x44, 0x48, 0x14, 0x43, 0x25, 0x30, 0xc2, 0x8f, 0xf7, 0x64, 0xcd, + 0x52, 0x2e, 0x26, 0x49, 0x92, 0x63, 0x66, 0x4c, 0x99, 0x32, 0x64, 0xc9, + 0x93, 0x26, 0x4c, 0x99, 0x32, 0x64, 0xcf, 0x54, 0x21, 0x08, 0x42, 0x10, + 0x84, 0x44, 0x42, 0x22, 0x44, 0x42, 0xfb, 0x59, 0x32, 0x72, 0x39, 0x75, + 0xc9, 0x93, 0x91, 0x93, 0x91, 0x9e, 0x8d, 0x8d, 0x8d, 0x8d, 0x8c, 0x63, + 0x18, 0xc6, 0x31, 0x8c, 0x7d, 0x58, 0xc6, 0xc6, 0xcc, 0x99, 0x32, 0x64, + 0xc9, 0x92, 0x4f, 0x11, 0xf0, 0xb4, 0x79, 0x5f, 0x93, 0x3d, 0x10, 0x99, + 0x12, 0x25, 0x46, 0x9e, 0x24, 0x48, 0x99, 0x39, 0x19, 0xfe, 0xb6, 0x4e, + 0x47, 0x23, 0x91, 0x29, 0x17, 0xbf, 0x6d, 0x47, 0xcc, 0xc9, 0x12, 0x63, + 0x66, 0x4c, 0x99, 0x32, 0x64, 0xc9, 0x93, 0x26, 0x4c, 0x99, 0x32, 0x64, + 0x46, 0x44, 0xc4, 0x21, 0x08, 0x42, 0x10, 0x84, 0x44, 0x42, 0x10, 0x98, + 0x98, 0x99, 0x93, 0x27, 0x23, 0x99, 0xdc, 0x39, 0x99, 0x32, 0x3b, 0x20, + 0x3b, 0xe2, 0x77, 0xd1, 0xdf, 0x47, 0x78, 0xef, 0x9d, 0xec, 0x8e, 0xd4, + 0x77, 0xa2, 0x72, 0xc9, 0x93, 0x3d, 0x1b, 0x1b, 0x32, 0x36, 0x31, 0x8c, + 0x63, 0x18, 0xc6, 0x31, 0x8c, 0x66, 0x46, 0x31, 0xfa, 0x32, 0x64, 0xc9, + 0x93, 0x53, 0x2e, 0x3a, 0x7f, 0x0a, 0xc7, 0x1a, 0x3c, 0x99, 0x32, 0x26, + 0x26, 0x45, 0x90, 0x28, 0x45, 0x24, 0x59, 0xcc, 0xee, 0x1c, 0xce, 0x67, + 0x31, 0x48, 0x4f, 0xfa, 0x4d, 0x8e, 0x47, 0x23, 0xb8, 0x3b, 0x07, 0x32, + 0xd9, 0x1a, 0x82, 0xc6, 0x49, 0x8d, 0x8c, 0x6c, 0xc9, 0x93, 0x26, 0x4c, + 0x99, 0x32, 0x64, 0xc9, 0x93, 0x3d, 0x50, 0x84, 0x44, 0x42, 0x10, 0x84, + 0x22, 0x22, 0x10, 0x98, 0x84, 0xce, 0x47, 0x70, 0xee, 0x9d, 0xc3, 0xb8, + 0x8e, 0x66, 0x64, 0x7b, 0x9e, 0xc7, 0xd2, 0x8e, 0xf6, 0x09, 0x5e, 0x3b, + 0xc5, 0x71, 0x1b, 0x0e, 0x67, 0x23, 0x97, 0x4e, 0x31, 0x3b, 0x67, 0x17, + 0x97, 0xc9, 0x0e, 0x6c, 0xe6, 0x99, 0x9e, 0x8c, 0x63, 0x18, 0xc6, 0x31, + 0x8d, 0x8c, 0x63, 0x19, 0x91, 0x8f, 0xae, 0x4c, 0x99, 0x33, 0xd3, 0x71, + 0x97, 0x1d, 0x07, 0x87, 0x57, 0x0d, 0xab, 0x26, 0x4c, 0x89, 0x8a, 0x44, + 0x64, 0x56, 0xcd, 0x39, 0x09, 0x1d, 0xc3, 0xb8, 0x29, 0x1c, 0x8e, 0x42, + 0x62, 0x23, 0xfd, 0x16, 0x49, 0x92, 0x91, 0x29, 0x8e, 0xc3, 0xb8, 0x3b, + 0x09, 0xcc, 0xd4, 0x32, 0xc6, 0x49, 0x92, 0x63, 0x63, 0x66, 0x4c, 0x99, + 0x32, 0x64, 0xc9, 0xc8, 0xe4, 0x72, 0x39, 0x0a, 0x47, 0x34, 0x29, 0x26, + 0x26, 0x21, 0x09, 0xe0, 0x83, 0xc8, 0x84, 0x21, 0x08, 0x42, 0x10, 0x99, + 0x93, 0x99, 0xcc, 0xee, 0x19, 0x6c, 0x58, 0x23, 0x8e, 0x8f, 0x23, 0xc9, + 0x86, 0x49, 0x32, 0x48, 0x6b, 0xa2, 0x91, 0x19, 0x91, 0x90, 0x98, 0xbd, + 0x1f, 0x04, 0xe4, 0x39, 0x75, 0x79, 0x43, 0x9f, 0x46, 0xc6, 0x36, 0x36, + 0x36, 0x31, 0x8e, 0xc8, 0x93, 0xd4, 0x56, 0x89, 0x6b, 0x2a, 0x1e, 0xb6, + 0xb2, 0x5a, 0xd8, 0x21, 0x6b, 0xab, 0x94, 0x7c, 0xdd, 0x6c, 0x7a, 0xaa, + 0xcf, 0x31, 0x59, 0xde, 0x83, 0x39, 0xa1, 0xc9, 0x1c, 0xb2, 0x72, 0x37, + 0x79, 0xe3, 0x6d, 0xda, 0x17, 0x0d, 0xb7, 0x26, 0x4c, 0x99, 0x13, 0x22, + 0xca, 0x8a, 0x99, 0x19, 0x9c, 0xc5, 0x21, 0x4c, 0xe6, 0x29, 0x11, 0x64, + 0x48, 0xff, 0x00, 0x41, 0xb2, 0x53, 0x25, 0x61, 0x2b, 0x09, 0x58, 0x39, + 0x8e, 0xc3, 0xb8, 0x39, 0x97, 0x32, 0xc6, 0x4a, 0x43, 0x90, 0xd8, 0xd9, + 0x93, 0x26, 0x4c, 0x9c, 0x8e, 0x47, 0x21, 0xdb, 0xc5, 0x4f, 0x74, 0xac, + 0xaa, 0x73, 0x91, 0x93, 0xe4, 0x47, 0x2c, 0x09, 0xb1, 0x36, 0x2c, 0xb2, + 0x11, 0x70, 0x71, 0xba, 0xc8, 0x91, 0xd5, 0x58, 0x88, 0xeb, 0xac, 0x44, + 0x77, 0x16, 0x43, 0x5e, 0x99, 0xe7, 0xeb, 0xc5, 0x16, 0xc2, 0xe3, 0x0d, + 0x1c, 0xce, 0xe1, 0x96, 0xc4, 0x93, 0x16, 0x53, 0x51, 0x23, 0x02, 0x08, + 0xe3, 0x91, 0xc0, 0x71, 0x38, 0x92, 0x89, 0x38, 0x92, 0x44, 0x8b, 0xb5, + 0x3d, 0x97, 0xa6, 0xd5, 0x2b, 0xa5, 0x01, 0x08, 0x42, 0x5d, 0x27, 0x21, + 0xf4, 0xc1, 0xf0, 0x49, 0x8c, 0xff, 0x00, 0xbe, 0xe5, 0x9a, 0x9a, 0xab, + 0x25, 0xba, 0xe9, 0x11, 0x66, 0xf5, 0xa3, 0x4b, 0xf1, 0xa5, 0x61, 0x2d, + 0x65, 0xd6, 0x13, 0x56, 0x58, 0x76, 0xfd, 0xbb, 0x49, 0x9d, 0xa4, 0x3a, + 0xd0, 0xeb, 0x58, 0x51, 0x49, 0xd9, 0x52, 0x89, 0xc5, 0x35, 0x28, 0x23, + 0x87, 0xb3, 0x8e, 0x4e, 0x53, 0x89, 0x76, 0xe5, 0x7e, 0x82, 0xcd, 0x1e, + 0xff, 0x00, 0x5e, 0xaa, 0x5b, 0xc6, 0xae, 0x33, 0xdb, 0x74, 0x76, 0x42, + 0x3a, 0x6e, 0x46, 0x4c, 0x99, 0x14, 0x88, 0xb2, 0xa9, 0x10, 0x98, 0xac, + 0x25, 0xac, 0x85, 0x67, 0xe2, 0xd0, 0x47, 0xe3, 0x44, 0x37, 0xa8, 0x9a, + 0x7d, 0x5d, 0x77, 0x91, 0x64, 0x64, 0x46, 0x5f, 0xd0, 0x64, 0xcb, 0x66, + 0x4e, 0x64, 0xa6, 0x3b, 0x19, 0xde, 0x3b, 0xc3, 0xb4, 0xb2, 0xc2, 0xd9, + 0x12, 0x63, 0x63, 0x66, 0x4c, 0x99, 0x39, 0x0e, 0x78, 0x1d, 0xf1, 0x3b, + 0xac, 0x96, 0xa7, 0x88, 0xf7, 0x05, 0x29, 0xc2, 0xfe, 0x37, 0x63, 0x0b, + 0x22, 0xf7, 0xe9, 0x94, 0x84, 0xdb, 0x12, 0xc2, 0x42, 0x12, 0xe9, 0xcd, + 0x23, 0xbc, 0xcc, 0x4e, 0x63, 0x85, 0x55, 0x9e, 0x77, 0x48, 0x9d, 0x1b, + 0xa8, 0xb7, 0x0b, 0x1b, 0xaf, 0x59, 0x54, 0x8a, 0xff, 0x00, 0x31, 0x46, + 0x22, 0x88, 0x90, 0x90, 0xbe, 0x3b, 0xb1, 0xac, 0xb7, 0x77, 0xd2, 0x56, + 0xec, 0xdf, 0x74, 0xe8, 0xbb, 0xc4, 0xb5, 0x56, 0x5b, 0xe2, 0x8c, 0xc2, + 0x5b, 0xf5, 0xb6, 0xc5, 0x6f, 0x56, 0x5f, 0x19, 0x6a, 0xef, 0x91, 0x7a, + 0xd5, 0x4a, 0x51, 0xd4, 0xea, 0x69, 0x9a, 0xd7, 0x58, 0x8f, 0xc5, 0x6d, + 0x8b, 0xff, 0x00, 0xd0, 0x59, 0x44, 0x69, 0xf1, 0x5f, 0x32, 0x1e, 0x26, + 0xc9, 0xff, 0x00, 0xa6, 0x51, 0x23, 0xbc, 0xd1, 0x61, 0x1d, 0x5d, 0x36, + 0x1e, 0xcc, 0x63, 0xe9, 0x83, 0x59, 0xe2, 0x1a, 0x28, 0x35, 0x7b, 0xc6, + 0xab, 0x52, 0xe5, 0x26, 0xde, 0x4c, 0x99, 0x28, 0xdc, 0x25, 0x59, 0x55, + 0xf1, 0xbe, 0x22, 0x3f, 0xeb, 0xf9, 0x7e, 0xe9, 0xfb, 0xc5, 0x3c, 0xa9, + 0x2e, 0x0c, 0xcf, 0x19, 0x4a, 0x25, 0x9f, 0x1a, 0xc6, 0xeb, 0xb2, 0x7a, + 0x87, 0x55, 0xfb, 0x8e, 0xe5, 0xe6, 0x21, 0x4e, 0xe3, 0x7f, 0x18, 0xef, + 0x52, 0x89, 0x56, 0xae, 0x52, 0x4b, 0x55, 0x74, 0x45, 0xaf, 0x81, 0x5d, + 0xd0, 0x99, 0x12, 0xa2, 0x56, 0xaa, 0xa1, 0x3d, 0x4c, 0xe6, 0x64, 0xc9, + 0x91, 0x32, 0x89, 0x61, 0xe9, 0x35, 0x32, 0x99, 0x06, 0x40, 0x8f, 0xda, + 0xd3, 0xea, 0x6b, 0xd5, 0x57, 0xd1, 0xce, 0x31, 0x14, 0x94, 0x89, 0x7b, + 0x2b, 0xac, 0x26, 0xc9, 0xb2, 0x4c, 0x93, 0x1b, 0x25, 0x34, 0x87, 0x71, + 0x3b, 0x89, 0xd8, 0x8b, 0x2e, 0x81, 0xdd, 0x8b, 0x39, 0x0e, 0x58, 0x15, + 0x9c, 0xcb, 0x35, 0x2a, 0xa7, 0x66, 0xba, 0x27, 0x9b, 0x91, 0x2d, 0x55, + 0xc4, 0x9b, 0xee, 0x43, 0xe9, 0x9d, 0x96, 0xa8, 0x3d, 0x62, 0xee, 0x6b, + 0x24, 0x65, 0x23, 0x93, 0x91, 0x86, 0x28, 0x91, 0xf7, 0x33, 0xee, 0x99, + 0xcf, 0x07, 0x31, 0x65, 0x91, 0xac, 0xd7, 0xee, 0xf0, 0xd0, 0xbb, 0xb7, + 0x5d, 0x4d, 0xe3, 0x93, 0x93, 0x22, 0xcd, 0x1e, 0xef, 0xa8, 0xd3, 0x1a, + 0x0d, 0x4d, 0x7b, 0x85, 0x6a, 0xa5, 0x02, 0x1b, 0x95, 0x95, 0x1a, 0x6d, + 0xce, 0xbb, 0x9c, 0xb5, 0xf5, 0x56, 0x6a, 0x3c, 0x41, 0x5d, 0x06, 0xab, + 0xc5, 0xf1, 0x47, 0xe3, 0x97, 0xea, 0xc7, 0x6d, 0xf3, 0x2c, 0x9c, 0x4c, + 0x14, 0x6a, 0x1d, 0x71, 0xb3, 0x5d, 0x74, 0xca, 0x6c, 0xd4, 0x57, 0x7a, + 0x9d, 0xf6, 0x42, 0x11, 0x94, 0xea, 0x95, 0x33, 0x84, 0xff, 0x00, 0x36, + 0xc9, 0x46, 0x36, 0x63, 0x5d, 0x2b, 0x21, 0x0e, 0xe6, 0x16, 0x83, 0x55, + 0xdb, 0x92, 0xd6, 0xc9, 0x0b, 0x71, 0x64, 0x77, 0x64, 0x8a, 0xf7, 0xce, + 0x0e, 0xad, 0xf6, 0xd4, 0x57, 0xbf, 0xd7, 0x32, 0x5b, 0x92, 0x6b, 0x5d, + 0xa9, 0xba, 0xcd, 0x23, 0x64, 0x86, 0xcc, 0x99, 0x32, 0x64, 0xdb, 0xac, + 0x71, 0xd4, 0x36, 0x61, 0xe5, 0xe0, 0x6d, 0x19, 0x3e, 0x25, 0xf0, 0x7e, + 0xa4, 0xd6, 0x1c, 0x97, 0x25, 0xcb, 0x03, 0x46, 0xbe, 0xbe, 0x5a, 0x5b, + 0xa9, 0x5e, 0x6b, 0x51, 0x05, 0xc2, 0xb5, 0xda, 0x73, 0x92, 0xee, 0x24, + 0xa4, 0xab, 0xba, 0x74, 0x91, 0xde, 0x35, 0x18, 0xab, 0x75, 0xd3, 0xc8, + 0xd3, 0x6b, 0x53, 0x2b, 0xdc, 0xae, 0xd3, 0xa9, 0x6e, 0x15, 0x6a, 0xab, + 0x4c, 0xc9, 0x93, 0x22, 0x65, 0x2f, 0xdf, 0x6f, 0x7f, 0x99, 0x02, 0xb1, + 0x7c, 0x7d, 0x8b, 0xf5, 0x10, 0xd3, 0x57, 0xe8, 0x95, 0x11, 0xb0, 0x7b, + 0x6f, 0xd5, 0x66, 0x8b, 0x55, 0x02, 0xe9, 0xea, 0x69, 0x3c, 0xfe, 0x5d, + 0x9a, 0xc4, 0x87, 0xa9, 0x84, 0x89, 0xde, 0xd8, 0xe6, 0x72, 0x33, 0xc8, + 0xd4, 0x32, 0x7d, 0x15, 0xb2, 0x4a, 0xed, 0x6b, 0xa2, 0xbb, 0xb7, 0x0b, + 0xf5, 0x07, 0x70, 0xf3, 0x32, 0xc5, 0x56, 0xe6, 0x39, 0xc9, 0x3f, 0xaa, + 0x39, 0xcc, 0x57, 0x19, 0x3d, 0x3a, 0x52, 0xdc, 0xe6, 0xfd, 0xf8, 0x89, + 0x09, 0x19, 0x48, 0x8b, 0x3e, 0x0c, 0x89, 0x11, 0x89, 0xc9, 0x23, 0x99, + 0xb8, 0x4b, 0x96, 0xb5, 0x75, 0x44, 0x4d, 0x82, 0x52, 0xf3, 0x91, 0xad, + 0xc8, 0x8b, 0x8c, 0x67, 0x27, 0xcd, 0x4b, 0x4d, 0x0b, 0x56, 0xe1, 0xe0, + 0xe9, 0xd9, 0x1d, 0x4e, 0x92, 0xdd, 0x24, 0xe9, 0xbe, 0x7a, 0x69, 0xc2, + 0xf8, 0x4d, 0xc6, 0xca, 0xd1, 0xac, 0xb6, 0xa8, 0xc1, 0xea, 0xd4, 0xe9, + 0xa7, 0x53, 0x64, 0xaa, 0xd5, 0x4a, 0x6a, 0x71, 0xba, 0xc8, 0xa8, 0xd9, + 0x6d, 0x52, 0xba, 0xf7, 0xca, 0xa7, 0x6a, 0x83, 0x9c, 0xe2, 0x6b, 0x2c, + 0xe7, 0x2a, 0xb9, 0x4e, 0xc8, 0xcb, 0xb6, 0x96, 0xae, 0xb3, 0xbd, 0x0b, + 0x2c, 0x76, 0x42, 0xa3, 0x47, 0xb7, 0x5f, 0xa9, 0xb3, 0x41, 0xe1, 0x49, + 0x8b, 0x47, 0x55, 0x50, 0x35, 0x6f, 0xfd, 0x66, 0x49, 0x8d, 0xf4, 0x5d, + 0x74, 0x4f, 0x1a, 0x9e, 0x63, 0x96, 0x7a, 0xe0, 0xb5, 0x62, 0x6d, 0x7b, + 0xbf, 0x61, 0xfb, 0x8f, 0xd8, 0x6b, 0x91, 0xef, 0x12, 0xda, 0xfb, 0xb4, + 0x5e, 0xdc, 0x35, 0x93, 0xfd, 0x2a, 0x2e, 0x45, 0x95, 0xba, 0xad, 0x32, + 0x3f, 0x73, 0xfe, 0x28, 0xb6, 0x69, 0x37, 0x3d, 0x4e, 0x81, 0xed, 0x7b, + 0xaf, 0x9f, 0xb9, 0x33, 0x26, 0x4c, 0x89, 0x95, 0x33, 0x6e, 0x97, 0xe6, + 0x47, 0x57, 0x5d, 0x64, 0x37, 0x1a, 0x51, 0x5e, 0xb9, 0xdc, 0x47, 0x9b, + 0x31, 0xeb, 0xcf, 0xbd, 0x57, 0x5b, 0xa5, 0x8d, 0x9b, 0x9d, 0x8c, 0x5b, + 0xdc, 0xab, 0x1e, 0xfb, 0x0e, 0x56, 0x78, 0x9a, 0x27, 0xfe, 0x9b, 0x04, + 0x7c, 0x4c, 0x8f, 0xfd, 0x17, 0x22, 0xcd, 0xce, 0x1a, 0x85, 0x3f, 0x2d, + 0x9d, 0x7e, 0xa5, 0xe9, 0xf5, 0xb1, 0xdd, 0xad, 0x44, 0x77, 0xcb, 0xe2, + 0xa1, 0xe2, 0x0a, 0x64, 0x69, 0x75, 0xd5, 0x6a, 0x67, 0xa9, 0x64, 0xcc, + 0xf4, 0xd4, 0xfe, 0xd6, 0x4c, 0x99, 0x21, 0x39, 0x71, 0xfa, 0xce, 0x03, + 0x8a, 0x28, 0x94, 0x63, 0x7e, 0x8a, 0xb5, 0xe7, 0xdf, 0xcf, 0xb4, 0x4f, + 0x79, 0x1c, 0x58, 0xa2, 0x63, 0xe9, 0x48, 0x4b, 0x07, 0x23, 0x39, 0x17, + 0x4d, 0x44, 0xb9, 0x6a, 0x17, 0x46, 0x22, 0x27, 0x87, 0x1f, 0xfb, 0x8e, + 0xcf, 0x6a, 0x9f, 0xd7, 0x93, 0x4d, 0x35, 0x07, 0x1d, 0xc3, 0x8c, 0x75, + 0x54, 0xad, 0xda, 0x1b, 0xa7, 0x80, 0xae, 0xc6, 0x2d, 0xd0, 0x6a, 0x73, + 0x08, 0x11, 0xd4, 0x42, 0x22, 0xd4, 0xcc, 0x8d, 0xcd, 0x59, 0x77, 0xd6, + 0xaa, 0xbb, 0x9d, 0x6e, 0xd8, 0xb2, 0x76, 0x7e, 0x67, 0x7e, 0x4c, 0x73, + 0x98, 0xee, 0x8c, 0xdd, 0x16, 0x61, 0xab, 0xe5, 0x02, 0x5a, 0xcc, 0x91, + 0x9c, 0x2e, 0x9e, 0xd1, 0xe0, 0x69, 0xea, 0x0d, 0x36, 0x97, 0x4f, 0xa3, + 0xd2, 0xdd, 0x28, 0xa8, 0x4d, 0x7d, 0x32, 0x35, 0x7f, 0xc6, 0x91, 0x21, + 0xf4, 0x5d, 0x19, 0xa7, 0xfd, 0xf3, 0xdc, 0xc1, 0x8e, 0x96, 0xaf, 0xcb, + 0x1a, 0x1a, 0x1f, 0x4c, 0xe4, 0x8f, 0xb1, 0xad, 0xaa, 0xb7, 0xaf, 0xbb, + 0x4f, 0x5c, 0x23, 0x0f, 0x8b, 0xbf, 0x77, 0x26, 0x7d, 0x1f, 0x26, 0xc1, + 0x05, 0x0d, 0x52, 0x7d, 0x32, 0x64, 0xc9, 0x5b, 0x36, 0xf9, 0x7d, 0x70, + 0xd8, 0xb4, 0xd5, 0x94, 0xdb, 0xb7, 0xd6, 0xfc, 0xe0, 0xf7, 0x6a, 0x62, + 0xbf, 0x1b, 0xd3, 0xa8, 0xfe, 0x35, 0x02, 0x1b, 0x97, 0xb4, 0x75, 0x73, + 0x91, 0xdf, 0x91, 0xdd, 0x91, 0x2b, 0x26, 0x5f, 0x29, 0xd9, 0x0b, 0x22, + 0x59, 0x12, 0xc8, 0x96, 0x40, 0xb2, 0x04, 0xe0, 0x4e, 0x04, 0xa2, 0x49, + 0x08, 0xdf, 0x33, 0x4e, 0xa7, 0xcc, 0x0a, 0xfc, 0x12, 0xd6, 0xcb, 0x1e, + 0x19, 0xbe, 0x73, 0xb3, 0x50, 0x4f, 0xad, 0xff, 0x00, 0xb7, 0x93, 0x26, + 0x45, 0x3c, 0x24, 0xf9, 0x0e, 0xda, 0x91, 0xe6, 0x69, 0x46, 0x92, 0xea, + 0xed, 0xd5, 0xe9, 0x6b, 0xe2, 0x60, 0x49, 0x23, 0x27, 0x23, 0x39, 0x18, + 0x9f, 0x55, 0xd1, 0xbf, 0x69, 0x3c, 0xcd, 0x0f, 0xa2, 0x22, 0x78, 0x77, + 0xf9, 0x13, 0x96, 0x16, 0x9e, 0x59, 0x68, 0xd3, 0xfb, 0x1a, 0x7b, 0xa8, + 0x44, 0xb5, 0xf5, 0x41, 0x47, 0x53, 0x7e, 0xa5, 0xeb, 0xf6, 0x2d, 0x36, + 0xe7, 0x5e, 0xf5, 0xe0, 0xdd, 0x5e, 0xd6, 0xe3, 0xab, 0xe3, 0x2b, 0x35, + 0xdf, 0x4c, 0xef, 0x6e, 0x11, 0xd4, 0xb7, 0x1d, 0x06, 0xaa, 0x5c, 0x5e, + 0xaa, 0x6a, 0x52, 0xba, 0x5c, 0x96, 0xa2, 0x6a, 0x32, 0xd4, 0x49, 0x47, + 0x96, 0x15, 0x57, 0x71, 0x5e, 0x6d, 0x9b, 0x36, 0xc5, 0xac, 0xdf, 0x25, + 0xb4, 0x78, 0x7b, 0x4d, 0xb3, 0xc2, 0x89, 0x28, 0xbb, 0x63, 0x05, 0x19, + 0x55, 0x93, 0x50, 0xfd, 0xe4, 0x8d, 0x57, 0xec, 0x48, 0x90, 0xfa, 0x2e, + 0xb4, 0xbf, 0xce, 0xc9, 0xc8, 0xc9, 0x93, 0x24, 0xbf, 0x6a, 0x2f, 0xe9, + 0x18, 0xcc, 0x0c, 0x53, 0xc1, 0xbf, 0xe9, 0x9d, 0xb7, 0xe9, 0xf2, 0x47, + 0xe1, 0x4e, 0x46, 0x4c, 0x99, 0x32, 0x21, 0x1b, 0x1f, 0xf2, 0x57, 0x46, + 0xcc, 0x99, 0x20, 0xcd, 0x0c, 0xbd, 0xf5, 0x5b, 0x95, 0x9d, 0xef, 0xc4, + 0xb5, 0x76, 0xa8, 0xa7, 0x22, 0xa8, 0x15, 0x40, 0xaa, 0x05, 0x71, 0x20, + 0x2e, 0x8c, 0x92, 0x27, 0x22, 0x6c, 0x99, 0x32, 0x68, 0x9a, 0x26, 0x89, + 0x22, 0x48, 0xc7, 0xbf, 0x89, 0x29, 0xe5, 0xa4, 0xeb, 0xe1, 0x5f, 0xdc, + 0xd4, 0x13, 0xeb, 0x6f, 0xe8, 0xeb, 0x77, 0xea, 0xeb, 0xb0, 0x52, 0xae, + 0xdc, 0x6a, 0xaf, 0x10, 0x32, 0x67, 0xab, 0xfd, 0x4b, 0xd3, 0x6b, 0xc5, + 0x5f, 0xf5, 0x0f, 0xa2, 0x22, 0x78, 0x77, 0xf7, 0x6c, 0x7f, 0x4e, 0x98, + 0x89, 0x51, 0x0e, 0x4c, 0xa6, 0x88, 0xe6, 0x2d, 0x61, 0x0f, 0xe3, 0xc4, + 0x1e, 0x09, 0xd2, 0xee, 0xc6, 0xeb, 0xb5, 0x6a, 0x76, 0x8d, 0x46, 0x54, + 0x5a, 0x94, 0x53, 0xa2, 0xc5, 0x0d, 0x45, 0x92, 0x82, 0x97, 0x76, 0x07, + 0x72, 0x24, 0xec, 0x47, 0x2f, 0x78, 0x29, 0x5b, 0x3f, 0x0e, 0x78, 0x25, + 0xea, 0x0a, 0xaa, 0x85, 0x35, 0x98, 0x22, 0xbd, 0xa5, 0x73, 0x55, 0x3a, + 0xa5, 0x22, 0x71, 0xc1, 0xa9, 0x5f, 0x93, 0x22, 0x5d, 0x57, 0x58, 0x7e, + 0xbe, 0xb9, 0x32, 0x3f, 0xd3, 0x1f, 0xd2, 0x3f, 0x44, 0x57, 0xbf, 0x89, + 0xfe, 0x9d, 0x6d, 0x0c, 0x93, 0x6a, 0x2b, 0xd2, 0xa4, 0x46, 0x49, 0x9b, + 0x1b, 0x5e, 0x65, 0x74, 0x7d, 0x32, 0x41, 0x9a, 0x39, 0x7b, 0xea, 0x23, + 0xfe, 0xc5, 0x71, 0x20, 0x8a, 0xca, 0xc8, 0x32, 0xb9, 0x11, 0x98, 0xa4, + 0x73, 0x39, 0x8e, 0x44, 0xa6, 0x4a, 0x44, 0xd9, 0x26, 0x4c, 0x99, 0x32, + 0x44, 0xba, 0x6e, 0x95, 0x77, 0xb6, 0xde, 0xbe, 0x16, 0xf9, 0xbc, 0x9f, + 0x59, 0xfc, 0x75, 0xbf, 0xf5, 0x75, 0xf0, 0xa4, 0x39, 0xee, 0x7a, 0x77, + 0xca, 0x8e, 0x58, 0x39, 0x23, 0xd8, 0xc0, 0x93, 0xcb, 0x6f, 0x92, 0x17, + 0xa3, 0x56, 0xf1, 0xa5, 0xff, 0x00, 0xa3, 0xe8, 0x88, 0x9e, 0x1d, 0xfd, + 0x56, 0xbf, 0x6d, 0x37, 0xc4, 0x4a, 0xca, 0xd9, 0x51, 0x1f, 0x8e, 0x8c, + 0xdc, 0xb6, 0x5d, 0x2e, 0xeb, 0x47, 0x88, 0x3f, 0xc7, 0xba, 0x9d, 0x19, + 0x2a, 0xed, 0x8c, 0xbc, 0xbe, 0xa3, 0x9b, 0xd1, 0x6a, 0xee, 0x16, 0xd3, + 0xae, 0x3f, 0x0d, 0xd6, 0xa2, 0x7a, 0x0d, 0x4b, 0x7b, 0x76, 0xc5, 0xac, + 0xdc, 0x2e, 0xd8, 0x3c, 0x27, 0xa6, 0xda, 0x54, 0x56, 0x3a, 0xf2, 0x84, + 0x48, 0x4e, 0x56, 0xc6, 0x09, 0x2a, 0xf5, 0x33, 0xf7, 0x92, 0x35, 0x11, + 0xfc, 0xa9, 0xfc, 0xcb, 0xd4, 0xbe, 0x7a, 0xe7, 0xa6, 0x7d, 0xa2, 0xfe, + 0x9f, 0x4c, 0x3e, 0x7c, 0x59, 0x1c, 0x6a, 0x34, 0x7d, 0xb7, 0x67, 0x63, + 0xcb, 0xea, 0xb5, 0xbc, 0x7c, 0xdf, 0xa3, 0x9e, 0x0e, 0x51, 0x67, 0x87, + 0xe4, 0x9e, 0xa5, 0x74, 0x6f, 0xac, 0x59, 0xa5, 0x7f, 0x55, 0xff, 0x00, + 0xc8, 0xac, 0x81, 0x06, 0x41, 0x91, 0x91, 0x19, 0x91, 0x98, 0xac, 0x3b, + 0x87, 0x70, 0x76, 0x0e, 0x64, 0xa4, 0x4a, 0x44, 0x99, 0x26, 0x49, 0x92, + 0x24, 0x48, 0x66, 0x39, 0x46, 0xd8, 0x76, 0xed, 0xe9, 0xe1, 0x8f, 0xd1, + 0x79, 0x3e, 0xb2, 0xf8, 0x7f, 0x3d, 0x2e, 0xf9, 0xeb, 0xb1, 0x5f, 0x6d, + 0x5a, 0xed, 0x1d, 0x9c, 0xaa, 0xc2, 0x38, 0x1c, 0x0e, 0x2c, 0x8e, 0x73, + 0xcb, 0xdf, 0xe7, 0xd3, 0xb8, 0x3c, 0x68, 0x97, 0xc8, 0xfa, 0x22, 0x27, + 0x87, 0x8b, 0x59, 0xa7, 0xfd, 0x31, 0x2b, 0x65, 0x6c, 0xa0, 0x8f, 0xc7, + 0x5f, 0x82, 0xdb, 0xe3, 0x08, 0xf8, 0xf3, 0x68, 0x9d, 0xba, 0x79, 0x6b, + 0x35, 0x18, 0x7a, 0xbb, 0xda, 0xf3, 0x16, 0xe3, 0xcc, 0xdb, 0x8d, 0xaa, + 0x2f, 0x5b, 0xb8, 0xe9, 0x34, 0xf0, 0xa6, 0x34, 0xac, 0xd9, 0x83, 0x8e, + 0x0c, 0x0b, 0x09, 0xc7, 0x36, 0x15, 0xc7, 0xdb, 0x54, 0x92, 0x72, 0x2f, + 0x5f, 0x97, 0x67, 0xcc, 0xba, 0x2f, 0x47, 0xfd, 0x5f, 0xa7, 0xd1, 0xff, + 0x00, 0x17, 0xb4, 0x7d, 0x19, 0x20, 0x78, 0xbe, 0xd8, 0xca, 0xfd, 0x33, + 0xc0, 0xa5, 0xf5, 0x58, 0xf9, 0x59, 0xea, 0xf0, 0xef, 0xf2, 0x57, 0x47, + 0xd6, 0x2c, 0xd3, 0x4b, 0xde, 0xff, 0x00, 0xdf, 0x81, 0x12, 0x04, 0x59, + 0x19, 0x11, 0x90, 0xa6, 0x29, 0x9d, 0xc3, 0xb8, 0x3b, 0x07, 0x21, 0xc8, + 0x6c, 0x93, 0x24, 0x48, 0x91, 0x22, 0x44, 0x88, 0xb3, 0x7a, 0xaf, 0xb5, + 0xb9, 0x74, 0xf0, 0xdf, 0xec, 0x5d, 0xf1, 0x3e, 0xb2, 0x27, 0xfa, 0xba, + 0x5d, 0xf3, 0xd1, 0x1b, 0x05, 0xda, 0x6b, 0xec, 0xdb, 0xd7, 0xe4, 0x3c, + 0xa1, 0x4b, 0xa3, 0x23, 0xcb, 0x97, 0x23, 0x97, 0xa7, 0x74, 0x78, 0xd0, + 0xaf, 0x91, 0xf4, 0x44, 0x4f, 0x0f, 0xfc, 0x5a, 0xfd, 0xe8, 0xfd, 0x30, + 0x20, 0x56, 0x69, 0xcf, 0xf9, 0x93, 0x3d, 0x38, 0xf2, 0x1e, 0x9e, 0x07, + 0xf9, 0x33, 0x51, 0xc7, 0x62, 0x7e, 0x8d, 0xba, 0xde, 0xc6, 0xb6, 0x8f, + 0x9d, 0x3a, 0xf6, 0xc0, 0x91, 0x8e, 0x90, 0x6c, 0xab, 0xe7, 0x59, 0x04, + 0x89, 0xa2, 0xd8, 0xfd, 0x16, 0xfe, 0xa9, 0x74, 0x5e, 0x98, 0x7b, 0xd7, + 0x8e, 0x8d, 0x98, 0x25, 0xfa, 0x56, 0x1c, 0x7d, 0x1f, 0xa4, 0x87, 0xcf, + 0x89, 0x3d, 0xf5, 0xfa, 0x72, 0x7f, 0xb5, 0xeb, 0xf0, 0xe7, 0xf2, 0x97, + 0x47, 0xd5, 0x1a, 0x77, 0xf5, 0x5d, 0xfb, 0xd1, 0x20, 0xc8, 0xb2, 0x32, + 0x14, 0x85, 0x21, 0x48, 0xe4, 0x72, 0x39, 0x9c, 0xc7, 0x21, 0xc8, 0x72, + 0x1b, 0x24, 0xc9, 0x31, 0x92, 0x19, 0x23, 0x3e, 0xfe, 0x26, 0xaf, 0x1a, + 0x9e, 0x9e, 0x1e, 0xfe, 0x25, 0xbf, 0x13, 0xf9, 0xe8, 0xcb, 0x3f, 0x5f, + 0x4b, 0xbe, 0x7a, 0x64, 0xf0, 0x8e, 0x9f, 0xcd, 0xee, 0xda, 0x7a, 0x7b, + 0x35, 0xe4, 0x67, 0x2c, 0x1d, 0xc2, 0x32, 0x6e, 0x5e, 0xad, 0xdd, 0xff, + 0x00, 0xa3, 0x1f, 0x96, 0x3e, 0x88, 0x81, 0xb2, 0x4f, 0x84, 0x1d, 0x9c, + 0xa5, 0x47, 0xe9, 0x81, 0x59, 0x52, 0x34, 0x55, 0x7b, 0x4d, 0x7b, 0x72, + 0x10, 0x8c, 0xe0, 0xb1, 0xca, 0xd3, 0xfc, 0xab, 0x66, 0x34, 0x3d, 0x7f, + 0xf9, 0x87, 0xce, 0xdb, 0x77, 0x98, 0xd0, 0xd4, 0xb0, 0x94, 0x05, 0x59, + 0xc0, 0xe0, 0x61, 0x9a, 0x78, 0x60, 0x94, 0x14, 0xd5, 0xfa, 0x6e, 0x32, + 0x95, 0x1f, 0x4d, 0xff, 0x00, 0xae, 0x5d, 0x17, 0xa6, 0x8f, 0xd9, 0x1f, + 0x46, 0xcf, 0xfe, 0x20, 0xbe, 0x9c, 0x75, 0x47, 0xc8, 0xbe, 0x3c, 0x49, + 0x0c, 0x6a, 0xb4, 0xff, 0x00, 0xa6, 0xdf, 0xda, 0x5f, 0x1e, 0xaf, 0x0e, + 0xff, 0x00, 0x29, 0x0c, 0x7d, 0x51, 0x43, 0xfa, 0xad, 0xfd, 0xd8, 0x91, + 0x64, 0x58, 0x98, 0xa4, 0x29, 0x0a, 0x47, 0x23, 0x91, 0xc8, 0xe4, 0x39, + 0x0e, 0x43, 0x63, 0x63, 0x64, 0x98, 0xc9, 0x0c, 0x91, 0x23, 0xc4, 0x71, + 0xe5, 0xa5, 0xe9, 0xb0, 0xfb, 0x68, 0xa6, 0xf3, 0x19, 0x3f, 0x7e, 0x8c, + 0xb7, 0xf7, 0x3a, 0x5d, 0xf3, 0x15, 0xc9, 0xcd, 0xc5, 0x0a, 0x5e, 0xfe, + 0x11, 0xba, 0x3a, 0x6d, 0xe3, 0x5b, 0x44, 0x74, 0xe3, 0x59, 0xe8, 0xd3, + 0x30, 0xca, 0xd6, 0x1a, 0x17, 0xa7, 0x7a, 0x7f, 0xe9, 0xc4, 0x7d, 0x51, + 0x03, 0x64, 0x8f, 0x2a, 0xb8, 0xfd, 0x54, 0xfb, 0x28, 0x15, 0xb2, 0xa6, + 0x69, 0x2d, 0xc2, 0xbe, 0xff, 0x00, 0xa5, 0x59, 0x92, 0x16, 0xe5, 0x46, + 0x67, 0x32, 0x53, 0xf6, 0xff, 0x00, 0x29, 0x4a, 0x32, 0xb3, 0xaf, 0xfc, + 0x89, 0xe1, 0x49, 0x29, 0xec, 0x75, 0x61, 0x0a, 0x46, 0x4c, 0x9c, 0xf0, + 0x3b, 0x3d, 0xe8, 0x92, 0x68, 0xd5, 0x5a, 0x94, 0xf9, 0xe6, 0x3a, 0x9f, + 0xdc, 0x97, 0xaf, 0x4b, 0xef, 0xa7, 0x7d, 0x1f, 0x48, 0xfd, 0x42, 0x52, + 0x4b, 0x9b, 0x66, 0x7a, 0x27, 0xd2, 0x1f, 0x3e, 0x27, 0xab, 0xf3, 0x76, + 0x8e, 0xd3, 0x2e, 0xfd, 0xa5, 0xf1, 0xea, 0xf0, 0xf7, 0xf2, 0x90, 0xc7, + 0xd5, 0x14, 0xbf, 0xaa, 0xdf, 0xdc, 0x89, 0x11, 0x09, 0x89, 0x89, 0x9c, + 0x8e, 0x47, 0x23, 0x91, 0xc8, 0xc9, 0x91, 0xb1, 0x8c, 0x63, 0x24, 0x31, + 0x8c, 0xdc, 0x74, 0xbe, 0x6b, 0x49, 0xd3, 0x66, 0x8e, 0x74, 0x36, 0xc3, + 0x85, 0x4d, 0xfb, 0xf4, 0x65, 0xdf, 0xbb, 0xd2, 0xef, 0x9a, 0x72, 0xed, + 0x97, 0xc9, 0xb0, 0xe5, 0x4b, 0xcc, 0xf7, 0x68, 0xee, 0xa3, 0xb8, 0x8e, + 0xe2, 0x33, 0x11, 0x38, 0xa1, 0x49, 0x19, 0x46, 0x4c, 0xf5, 0xde, 0xdf, + 0xfa, 0xd1, 0x1f, 0x54, 0x40, 0xd8, 0xff, 0x00, 0x65, 0x7e, 0xe5, 0x6f, + 0xda, 0x0f, 0xde, 0x0c, 0xad, 0x95, 0x4f, 0xda, 0x76, 0x7b, 0x46, 0x7e, + 0xf1, 0x9e, 0x24, 0xa6, 0x73, 0x1c, 0xcf, 0xf2, 0x8c, 0x72, 0x9f, 0x45, + 0xee, 0x3f, 0x62, 0xbf, 0xd5, 0xe0, 0xdb, 0x54, 0xb6, 0x1a, 0xd9, 0xdc, + 0x47, 0x74, 0x76, 0x8e, 0xd2, 0x56, 0x15, 0x5c, 0xe1, 0x28, 0xea, 0x39, + 0x47, 0x59, 0xf3, 0xcf, 0x11, 0xd5, 0xfe, 0xf4, 0xbd, 0x19, 0x39, 0x99, + 0x34, 0x72, 0xff, 0x00, 0x55, 0xbe, 0x92, 0xe9, 0x07, 0x89, 0x31, 0xaf, + 0x42, 0x28, 0x9f, 0x0b, 0xbc, 0x51, 0x6f, 0xfb, 0x34, 0x3c, 0x16, 0xfe, + 0xda, 0xf8, 0xf5, 0x78, 0x7b, 0xf9, 0x8b, 0xe1, 0x8f, 0xd1, 0x53, 0xf7, + 0xb3, 0xf5, 0xa1, 0x31, 0x31, 0x31, 0x33, 0x26, 0x4c, 0x99, 0x32, 0x64, + 0xc8, 0xd8, 0xd8, 0xc6, 0xc6, 0x31, 0x8c, 0x63, 0x3f, 0xee, 0xf1, 0xa5, + 0xf2, 0xba, 0xe3, 0x61, 0x7f, 0xff, 0x00, 0x3b, 0x5b, 0x3c, 0xae, 0xac, + 0xbf, 0xf7, 0x7a, 0x5d, 0xf3, 0xa0, 0x5c, 0xb5, 0x33, 0xfd, 0x46, 0xc6, + 0xdf, 0x63, 0x47, 0xc5, 0xd2, 0xf0, 0x65, 0x19, 0x46, 0x08, 0xfe, 0x9c, + 0x7a, 0xb7, 0xc7, 0xf9, 0x11, 0x1f, 0xa2, 0x06, 0xcb, 0xfb, 0x10, 0xfd, + 0x70, 0x20, 0xfd, 0xe0, 0x41, 0x90, 0x9f, 0xb3, 0x97, 0xb2, 0x97, 0xd4, + 0xa4, 0x46, 0x67, 0x32, 0x56, 0x1f, 0xe4, 0xab, 0x5b, 0xb7, 0xa4, 0x70, + 0xa3, 0x7c, 0xaa, 0xb1, 0x23, 0xc0, 0xf3, 0xff, 0x00, 0xfc, 0xf4, 0x2c, + 0x3b, 0x87, 0x31, 0xc8, 0x73, 0x1c, 0x8a, 0xad, 0xe3, 0x28, 0x5a, 0x5e, + 0xd4, 0x8b, 0x65, 0x87, 0xad, 0xfd, 0xf9, 0x75, 0x6c, 0x62, 0x8b, 0x67, + 0x06, 0x68, 0x7f, 0x8d, 0x8e, 0xac, 0x8f, 0xbc, 0xe6, 0xdc, 0x5e, 0x72, + 0x33, 0x3d, 0x33, 0x82, 0x9f, 0x79, 0xf8, 0x92, 0x5c, 0xb5, 0x94, 0xb2, + 0xdf, 0xd0, 0xbe, 0x3d, 0x5e, 0x1e, 0xfe, 0x6a, 0x18, 0xfd, 0x15, 0xfc, + 0xd9, 0xfa, 0x90, 0x84, 0x26, 0x26, 0x26, 0x64, 0xc9, 0x93, 0x27, 0x23, + 0x3d, 0x33, 0xd1, 0x8c, 0x63, 0x18, 0xc6, 0x33, 0xc4, 0x1a, 0x7e, 0xee, + 0x94, 0xd9, 0x5e, 0x36, 0xed, 0x44, 0xb3, 0xe8, 0x65, 0xff, 0x00, 0xbd, + 0xd2, 0xef, 0x9d, 0xbf, 0x3c, 0xa5, 0xb7, 0xcb, 0x3e, 0x41, 0x9b, 0x75, + 0x5e, 0x5e, 0x8d, 0x97, 0x50, 0x9e, 0xa7, 0x3c, 0x65, 0xf2, 0x38, 0xf4, + 0x5f, 0xa5, 0x19, 0xf4, 0xef, 0x8f, 0xf2, 0xe2, 0x3f, 0x44, 0x0d, 0x9f, + 0xf8, 0xf5, 0x7e, 0xa8, 0x91, 0x7e, 0xf0, 0x64, 0x64, 0x46, 0x5e, 0xdc, + 0x8e, 0x5e, 0xea, 0x42, 0x91, 0xcc, 0x94, 0xcf, 0xf2, 0x27, 0xd7, 0x77, + 0x47, 0xfa, 0x39, 0x7d, 0x28, 0xf0, 0x2c, 0xff, 0x00, 0xfe, 0x14, 0x64, + 0x27, 0xd3, 0x27, 0x21, 0xcc, 0x84, 0xdf, 0x75, 0x58, 0x73, 0xc9, 0xa8, + 0x7e, 0xfa, 0xff, 0x00, 0xe4, 0x4b, 0xd0, 0x90, 0x8c, 0x9a, 0x2f, 0xe3, + 0xf5, 0x9f, 0xd3, 0x1a, 0xa2, 0x4d, 0xfd, 0x58, 0x1f, 0xc8, 0x8f, 0x97, + 0x5a, 0xf7, 0xdf, 0xbf, 0x93, 0x4f, 0xcd, 0xbf, 0xa5, 0x7c, 0x7a, 0xbc, + 0x3f, 0xfc, 0xdf, 0xf8, 0xfd, 0x35, 0xfc, 0xcf, 0xe5, 0x08, 0x4c, 0xc8, + 0x99, 0x93, 0x26, 0x4c, 0x99, 0x33, 0xe8, 0xcf, 0x46, 0x31, 0x8c, 0x63, + 0x19, 0x7d, 0x6a, 0xda, 0xac, 0xad, 0xd5, 0x66, 0xd2, 0xf1, 0xb6, 0x5c, + 0xfd, 0x0c, 0xd4, 0x7e, 0xf7, 0x4b, 0xbe, 0x68, 0xf6, 0xa2, 0x6d, 0xe5, + 0x3c, 0x1b, 0x4d, 0xae, 0xd3, 0x6f, 0xd4, 0xf6, 0x37, 0xfb, 0xbe, 0xa6, + 0x99, 0x96, 0x77, 0x44, 0xf9, 0x47, 0x1e, 0xad, 0xf1, 0xfb, 0x2f, 0x87, + 0xe8, 0x81, 0xb4, 0x7f, 0x1e, 0x9f, 0xd5, 0x16, 0x44, 0x83, 0xf6, 0x8b, + 0x23, 0x2f, 0x6c, 0x8d, 0x91, 0x91, 0xc8, 0xe4, 0x72, 0xf7, 0xff, 0x00, + 0x21, 0x5f, 0xcf, 0x5b, 0xd3, 0xff, 0x00, 0x9f, 0xf8, 0x8f, 0x01, 0x4d, + 0x4f, 0x67, 0x8c, 0x8e, 0x67, 0x31, 0xcc, 0x72, 0x1c, 0x88, 0xcd, 0x2b, + 0xb9, 0xe4, 0xe6, 0x5e, 0xf2, 0x6e, 0x1f, 0xc9, 0x7e, 0x85, 0xd2, 0x5f, + 0x1a, 0x3f, 0xe3, 0xf4, 0x65, 0xac, 0x5f, 0x44, 0x66, 0x92, 0x94, 0x96, + 0x06, 0x8c, 0x12, 0x78, 0x12, 0x2d, 0x9f, 0x0a, 0x37, 0xdf, 0xe4, 0xd2, + 0x59, 0xf0, 0xbd, 0x7b, 0x03, 0xff, 0x00, 0x7b, 0xfe, 0x4b, 0xd3, 0x0f, + 0x99, 0x08, 0x42, 0x32, 0x64, 0xcf, 0xa3, 0x3d, 0x32, 0x67, 0xab, 0xe8, + 0xfa, 0x31, 0x8c, 0x63, 0x3c, 0x41, 0xa3, 0x36, 0xd7, 0x8d, 0xb2, 0xc7, + 0xef, 0xe8, 0xd4, 0x7e, 0xf7, 0x4b, 0xbe, 0x57, 0xd3, 0xa4, 0x7e, 0x5c, + 0xc6, 0x98, 0xda, 0xd5, 0x6a, 0x3a, 0xc9, 0xba, 0xb7, 0x19, 0x4d, 0x59, + 0x49, 0xf0, 0x7c, 0x10, 0x6b, 0x19, 0xe9, 0x9f, 0x46, 0xf7, 0xf0, 0xbe, + 0x3d, 0x10, 0x36, 0x9f, 0xe3, 0xd3, 0xf3, 0x12, 0x24, 0x5f, 0xb4, 0x18, + 0x9f, 0xb6, 0x47, 0xf3, 0x19, 0x19, 0x32, 0x72, 0xfa, 0xbc, 0x65, 0x6f, + 0x77, 0x5d, 0xd3, 0xff, 0x00, 0x8f, 0xf8, 0x8f, 0xf1, 0xdd, 0xd9, 0xd3, + 0xc6, 0x42, 0x97, 0xb7, 0x23, 0x90, 0xe4, 0x72, 0x22, 0xf3, 0x66, 0x70, + 0x72, 0x2c, 0x66, 0xe5, 0xfc, 0xa7, 0xea, 0x66, 0x9b, 0xda, 0x8e, 0x8d, + 0xfb, 0x41, 0x73, 0x9e, 0x79, 0x5d, 0x7e, 0x54, 0xf9, 0xe4, 0xf9, 0x25, + 0xec, 0x7e, 0xa6, 0xbd, 0x8d, 0xce, 0xce, 0xd6, 0x93, 0x7b, 0xfe, 0x4d, + 0x25, 0x9f, 0x1e, 0xbd, 0x89, 0xff, 0x00, 0xbd, 0xff, 0x00, 0x25, 0xe9, + 0x8f, 0xcb, 0x10, 0x84, 0x67, 0xd1, 0x93, 0x26, 0x4c, 0xfa, 0x98, 0xfa, + 0x31, 0x8c, 0x63, 0x2e, 0xae, 0x37, 0x55, 0x4d, 0x6f, 0x4d, 0xa4, 0x6f, + 0xd3, 0xa8, 0xfd, 0xee, 0x92, 0x83, 0x99, 0x3a, 0xdf, 0x66, 0x54, 0x4d, + 0xcb, 0xb1, 0x61, 0xb4, 0x45, 0xc2, 0xbd, 0x5e, 0x16, 0xe1, 0xb5, 0x5b, + 0xdd, 0xdb, 0xff, 0x00, 0x48, 0xd1, 0x91, 0x61, 0xa5, 0xea, 0xde, 0xbe, + 0x3f, 0xe7, 0xa2, 0x06, 0xd3, 0xfb, 0x14, 0x91, 0x22, 0x44, 0x83, 0x13, + 0x32, 0x37, 0xf5, 0x26, 0x64, 0xc8, 0x9f, 0xb6, 0xfb, 0x67, 0x76, 0x46, + 0x4c, 0xfd, 0x3c, 0x1b, 0xac, 0xff, 0x00, 0x1f, 0xde, 0xe1, 0xb9, 0x09, + 0xfd, 0x39, 0x33, 0xd1, 0xb1, 0x3f, 0xcd, 0x93, 0x39, 0x0d, 0xe4, 0xdd, + 0x7f, 0x97, 0xea, 0x65, 0x3f, 0xb5, 0xd1, 0xb2, 0x1f, 0x45, 0x7a, 0x55, + 0x99, 0xdb, 0x95, 0x64, 0xa3, 0xee, 0x59, 0x2c, 0x9f, 0xa5, 0x2f, 0x79, + 0x78, 0x82, 0xdc, 0x4f, 0x7a, 0xfe, 0x45, 0x44, 0xfe, 0x3d, 0x7b, 0x1b, + 0xff, 0x00, 0x7b, 0xfe, 0x3f, 0x4a, 0xf9, 0xff, 0x00, 0x88, 0x42, 0xfb, + 0x59, 0x33, 0xe8, 0x7d, 0x1f, 0x46, 0x31, 0x8d, 0x1a, 0xd7, 0xf5, 0xfa, + 0x75, 0x3f, 0xbf, 0xd2, 0x3f, 0x16, 0x91, 0xd4, 0xd9, 0x05, 0xe6, 0xed, + 0x34, 0xf7, 0x4a, 0x75, 0xea, 0x33, 0xde, 0xf0, 0xe6, 0xab, 0xbb, 0x64, + 0x96, 0x25, 0xff, 0x00, 0x1a, 0x21, 0xf1, 0xd5, 0x75, 0xde, 0x87, 0xe9, + 0x89, 0xb4, 0xff, 0x00, 0x1e, 0xa2, 0x22, 0xf9, 0x89, 0x12, 0x26, 0x46, + 0x7f, 0xd1, 0x97, 0x4b, 0x85, 0x76, 0x69, 0xa3, 0x99, 0x6d, 0x15, 0xf1, + 0xb3, 0x65, 0x9c, 0x93, 0xf0, 0xfd, 0xcc, 0xd4, 0xec, 0xb2, 0xd3, 0xc7, + 0x8d, 0x69, 0x78, 0x3e, 0xa7, 0x56, 0xe7, 0xff, 0x00, 0x17, 0xe9, 0xc9, + 0x93, 0x26, 0x7d, 0xe3, 0x86, 0xde, 0x50, 0xe4, 0x67, 0xea, 0xdd, 0xbf, + 0x96, 0x2f, 0x4b, 0x21, 0xfb, 0x7d, 0x17, 0xbb, 0xb2, 0x45, 0x11, 0xe3, + 0x19, 0x7b, 0xcd, 0xfd, 0x44, 0x99, 0x81, 0x7b, 0x95, 0xc4, 0xdf, 0x25, + 0xcf, 0x78, 0xdd, 0xa1, 0xcf, 0x57, 0xd8, 0xed, 0x29, 0x7d, 0x8d, 0x9b, + 0xf9, 0xff, 0x00, 0xfc, 0xbe, 0x98, 0xea, 0x88, 0xfe, 0x94, 0x2e, 0xb9, + 0x32, 0x64, 0xc9, 0x93, 0x3f, 0x61, 0x8f, 0xd0, 0xc6, 0x33, 0x57, 0xfb, + 0xb8, 0x30, 0x71, 0x38, 0x8e, 0x38, 0x5a, 0x8a, 0x66, 0xed, 0xed, 0x4c, + 0xed, 0xcc, 0xa3, 0x4b, 0x75, 0xa4, 0xb6, 0xeb, 0x27, 0x2f, 0xc3, 0xac, + 0x89, 0xe4, 0xed, 0xc7, 0x09, 0xc6, 0x8d, 0x5f, 0x3e, 0x7b, 0x5e, 0xa3, + 0xca, 0xeb, 0x67, 0x25, 0x29, 0x72, 0xc9, 0xf0, 0x2f, 0x5e, 0xf3, 0xf2, + 0xfd, 0x31, 0x36, 0x9f, 0xe3, 0x54, 0x21, 0x7c, 0xc4, 0x88, 0xba, 0x7f, + 0xce, 0x98, 0x37, 0x2b, 0x38, 0x69, 0xfb, 0x5d, 0xfd, 0xcb, 0xca, 0x9e, + 0x50, 0xf2, 0xc8, 0xde, 0x34, 0x96, 0x4b, 0x4c, 0xa8, 0x9f, 0x73, 0x60, + 0xd3, 0x4a, 0x92, 0xa9, 0x2b, 0x6b, 0x5f, 0x0c, 0x63, 0x19, 0x11, 0xcb, + 0x29, 0x99, 0xfa, 0xf7, 0x9f, 0x6d, 0x52, 0xc3, 0x38, 0x2e, 0xad, 0xf5, + 0x5f, 0x03, 0x3e, 0x14, 0x23, 0xca, 0x52, 0xf6, 0x1f, 0xea, 0xc9, 0x26, + 0x7c, 0x92, 0x78, 0x23, 0x25, 0x5c, 0x31, 0xe6, 0x35, 0x3b, 0x84, 0xa3, + 0x6e, 0xa6, 0x34, 0xbd, 0x4c, 0x2e, 0xae, 0x55, 0x4b, 0xd5, 0x1a, 0xa5, + 0x33, 0x6b, 0xaa, 0x75, 0xeb, 0xff, 0x00, 0xf9, 0xeb, 0x93, 0x22, 0x65, + 0x7f, 0xa1, 0x7f, 0x59, 0x8c, 0x66, 0xb3, 0xf7, 0x7a, 0xe4, 0x93, 0x38, + 0x9d, 0xb3, 0xb6, 0xdb, 0x9c, 0x9c, 0x61, 0x28, 0xde, 0xa5, 0xc7, 0x54, + 0x7f, 0xb4, 0x55, 0x98, 0xe9, 0xae, 0xad, 0xd8, 0xe3, 0x16, 0xa7, 0xb6, + 0xeb, 0x21, 0xaa, 0xa1, 0x49, 0x0d, 0x60, 0xfd, 0x3d, 0x57, 0x5f, 0xfb, + 0xbc, 0xb1, 0xaf, 0x4c, 0x4d, 0xab, 0xf8, 0xb0, 0x11, 0x1f, 0x98, 0x88, + 0x5d, 0x54, 0x3d, 0x94, 0x07, 0xf4, 0x2b, 0xea, 0x96, 0xaa, 0xf9, 0x68, + 0x22, 0x28, 0xbe, 0xae, 0x19, 0x35, 0xba, 0x77, 0x6e, 0x9e, 0x35, 0xbc, + 0x68, 0xec, 0x96, 0x9e, 0x50, 0x79, 0x24, 0x86, 0x32, 0x47, 0xc3, 0x90, + 0xc5, 0xfa, 0xb7, 0xcf, 0xe4, 0xe0, 0xc9, 0x93, 0x3e, 0xb6, 0x69, 0xe1, + 0xc5, 0x4a, 0xce, 0x2e, 0x43, 0x96, 0x0f, 0x91, 0x2c, 0x1f, 0x2f, 0x72, + 0xd7, 0x37, 0x65, 0x55, 0x4a, 0xbb, 0x35, 0x13, 0xee, 0xd9, 0x04, 0xa0, + 0xb5, 0x0f, 0x95, 0xb3, 0x50, 0xb4, 0xf2, 0x10, 0x63, 0xd9, 0x9f, 0x2f, + 0xc1, 0xdc, 0x45, 0xa1, 0xa9, 0x0a, 0x88, 0x44, 0xe2, 0x69, 0xd7, 0xfb, + 0x1f, 0xf3, 0x89, 0x8e, 0xb8, 0x38, 0x95, 0x7e, 0x85, 0xf6, 0xfb, 0x88, + 0xcf, 0xab, 0x1e, 0x86, 0x31, 0x9a, 0xcf, 0xdd, 0xf4, 0x48, 0x5f, 0x12, + 0xb7, 0x94, 0x73, 0x84, 0xce, 0xd7, 0xd5, 0xc4, 0xe2, 0xc6, 0xa5, 0xc6, + 0x7a, 0x59, 0x72, 0xd2, 0xea, 0x27, 0x45, 0xfa, 0x8e, 0xdd, 0x76, 0x57, + 0x72, 0xbe, 0xaa, 0x6f, 0x43, 0x88, 0xbe, 0x93, 0x1e, 0x9d, 0xe1, 0xfe, + 0x77, 0x4c, 0x74, 0xc1, 0x1f, 0x67, 0xb4, 0xff, 0x00, 0x1a, 0x3f, 0x0b, + 0xe6, 0x3f, 0x31, 0x42, 0x42, 0x42, 0x47, 0x12, 0x35, 0xb6, 0x4a, 0xe5, + 0x41, 0x29, 0x3b, 0x1b, 0xeb, 0x83, 0x08, 0xe2, 0x8c, 0x18, 0x30, 0x2c, + 0xc0, 0x5a, 0x94, 0x7b, 0x31, 0x8c, 0xff, 0x00, 0xeb, 0xf4, 0x93, 0xe9, + 0xbe, 0x7f, 0x23, 0xd6, 0xbe, 0x0c, 0x15, 0xc3, 0xb9, 0x2b, 0xec, 0x55, + 0x41, 0x27, 0x3b, 0x33, 0x84, 0xd6, 0x45, 0x11, 0xfd, 0x6f, 0x8a, 0x84, + 0x75, 0x3f, 0xca, 0x95, 0xbc, 0x4b, 0x20, 0xec, 0xb9, 0x51, 0x59, 0xa8, + 0x82, 0x8d, 0xfe, 0x55, 0x11, 0x8f, 0xd3, 0xc4, 0x8d, 0x93, 0x89, 0x0d, + 0x4f, 0x2a, 0xfb, 0x95, 0x48, 0x92, 0x5c, 0xa8, 0x5f, 0x9d, 0xff, 0x00, + 0x39, 0x19, 0xeb, 0x93, 0x25, 0x5f, 0xa3, 0xd7, 0x93, 0x91, 0xc8, 0xe6, + 0x87, 0xee, 0x57, 0x6c, 0xab, 0xb2, 0x33, 0x8c, 0x8c, 0x7d, 0x86, 0x31, + 0x9a, 0xdf, 0xdd, 0xf4, 0x32, 0x35, 0xf2, 0x8d, 0xb4, 0xd8, 0xda, 0xaa, + 0x79, 0xe0, 0x70, 0x47, 0x68, 0xec, 0x8e, 0xa6, 0x87, 0x56, 0x49, 0x69, + 0x92, 0x75, 0x41, 0x76, 0xb4, 0x33, 0x75, 0x49, 0xd4, 0x57, 0x7c, 0xaa, + 0x22, 0xe1, 0x72, 0xed, 0xb8, 0x9f, 0x26, 0x0c, 0xfb, 0xa3, 0x76, 0x7f, + 0xed, 0xfa, 0x51, 0xb4, 0x2f, 0xf5, 0x62, 0x8c, 0x10, 0x44, 0x23, 0x92, + 0x35, 0x32, 0x34, 0x8a, 0x0a, 0x24, 0xb5, 0x70, 0x89, 0x2b, 0xe7, 0x67, + 0x4c, 0x99, 0xfb, 0x39, 0xe9, 0xf0, 0x4a, 0x73, 0x3b, 0xf3, 0x89, 0xdf, + 0x8c, 0x9f, 0x2c, 0x92, 0x66, 0x4d, 0xef, 0xf7, 0xbd, 0x70, 0xfd, 0xbe, + 0x38, 0x23, 0x1e, 0xe3, 0xee, 0xf1, 0x5d, 0xbe, 0x4d, 0x63, 0x92, 0x59, + 0x1a, 0x31, 0x91, 0x25, 0x12, 0xcb, 0x94, 0xa5, 0x7f, 0xe6, 0xcd, 0xd7, + 0x93, 0xb4, 0x2a, 0xcd, 0x42, 0xff, 0x00, 0x6b, 0x8e, 0x0b, 0x6c, 0x87, + 0x28, 0xb7, 0x25, 0x29, 0x34, 0x46, 0xdf, 0xcc, 0x8a, 0x66, 0x0a, 0x63, + 0xf9, 0x9f, 0xf0, 0xc1, 0x83, 0x06, 0x3a, 0x53, 0xfb, 0x66, 0x0c, 0x74, + 0xc1, 0x82, 0xd9, 0x76, 0xeb, 0xf3, 0x16, 0x58, 0x29, 0xb3, 0x91, 0x93, + 0x47, 0xa6, 0x96, 0xb2, 0x57, 0x6d, 0xd3, 0xd1, 0xa1, 0x5d, 0x38, 0x8b, + 0x56, 0x2b, 0xe1, 0x2f, 0x56, 0x06, 0x86, 0x8d, 0x6f, 0xee, 0xfa, 0x19, + 0xa3, 0x4a, 0x5a, 0x59, 0xd1, 0x51, 0x28, 0x54, 0x4d, 0x62, 0x44, 0x35, + 0x16, 0xd7, 0x17, 0xaa, 0xb8, 0x94, 0x9c, 0xc9, 0x19, 0xcf, 0x48, 0x3e, + 0x12, 0x5a, 0xd9, 0xc0, 0x8e, 0xbd, 0x48, 0xf3, 0x55, 0x22, 0xbd, 0xdb, + 0x81, 0x0d, 0xcb, 0x4d, 0x68, 0xa7, 0x19, 0x1c, 0x94, 0x5f, 0x7e, 0x39, + 0xdc, 0x67, 0xcf, 0x5b, 0xe9, 0x46, 0xcd, 0x25, 0xe5, 0x22, 0xcc, 0x94, + 0x5f, 0x5c, 0x8f, 0x39, 0x5c, 0x4f, 0x3d, 0x36, 0x3d, 0x4f, 0xd3, 0xe6, + 0x62, 0xda, 0xb5, 0x33, 0x26, 0x48, 0x6a, 0xa2, 0xf5, 0x50, 0xde, 0xe6, + 0xec, 0x86, 0xf1, 0x27, 0x2c, 0x90, 0xe2, 0xdf, 0x6e, 0xa6, 0x4b, 0x09, + 0xe4, 0xc9, 0x93, 0x26, 0x4c, 0x8d, 0x8d, 0x8f, 0xdc, 0xcb, 0x47, 0x79, + 0x9d, 0xe8, 0x9b, 0xdf, 0xee, 0x7a, 0xea, 0x9a, 0x8d, 0x3c, 0x93, 0x6d, + 0xf2, 0x12, 0x38, 0xb6, 0x42, 0xa5, 0x01, 0x8c, 0x6f, 0x05, 0xf7, 0xa8, + 0x43, 0xcd, 0x2c, 0xf2, 0x47, 0x13, 0x81, 0x0d, 0x1c, 0xa7, 0x0b, 0x67, + 0xcf, 0x51, 0xa8, 0xba, 0x50, 0x7f, 0x85, 0x5d, 0x4d, 0x34, 0x53, 0x67, + 0x3e, 0x09, 0x90, 0xd1, 0x39, 0x38, 0x68, 0x19, 0x0d, 0x25, 0x50, 0x24, + 0x92, 0x87, 0xfc, 0xf5, 0x51, 0xfb, 0x7e, 0xad, 0xce, 0xce, 0x35, 0x23, + 0x27, 0x21, 0x58, 0x68, 0xe7, 0x65, 0x51, 0xb2, 0xd9, 0xdb, 0xd5, 0x92, + 0x14, 0xe5, 0x11, 0x6a, 0xec, 0x42, 0xd7, 0x0b, 0x59, 0x5b, 0x3b, 0xf5, + 0xb3, 0x29, 0x98, 0x1a, 0x35, 0xdf, 0xbd, 0xe8, 0x91, 0x55, 0xf2, 0x8d, + 0x6e, 0x79, 0x39, 0x19, 0x16, 0x82, 0xd7, 0x5f, 0x45, 0x17, 0x27, 0xa8, + 0xd3, 0x5b, 0x4c, 0x3d, 0x71, 0xbe, 0x70, 0x16, 0xbe, 0xd3, 0xf1, 0x0b, + 0x0f, 0xc4, 0x64, 0x5b, 0x3e, 0xe5, 0xde, 0x94, 0x51, 0x7c, 0xe1, 0x5e, + 0x97, 0x5b, 0x0e, 0x35, 0xdf, 0x44, 0x8d, 0x56, 0xe1, 0xe5, 0x67, 0x1d, + 0xe2, 0x64, 0x37, 0x8d, 0x37, 0x1b, 0x37, 0x2e, 0xed, 0xd5, 0xeb, 0x08, + 0x6a, 0xc8, 0x6a, 0x45, 0xaa, 0x65, 0xfa, 0x69, 0x5b, 0x75, 0xba, 0x5e, + 0xe9, 0x66, 0x8b, 0x85, 0x70, 0xb5, 0x38, 0xdb, 0x77, 0x17, 0xe6, 0x24, + 0x79, 0x99, 0x11, 0xd5, 0xc3, 0x1e, 0x72, 0x07, 0x98, 0x90, 0xed, 0x93, + 0x39, 0x64, 0xa5, 0xae, 0x0d, 0x8d, 0x8e, 0x68, 0xee, 0x21, 0x99, 0x37, + 0x5f, 0xb1, 0x4c, 0x92, 0xaf, 0xcc, 0x56, 0x8f, 0x39, 0x52, 0x16, 0xb6, + 0xb3, 0xcd, 0x23, 0xcc, 0xac, 0x4b, 0x52, 0x3d, 0x43, 0x27, 0xa8, 0x4a, + 0x37, 0xdf, 0xe6, 0x08, 0xd4, 0x2d, 0x3b, 0x63, 0xd3, 0xe2, 0x3a, 0x6d, + 0x37, 0x7a, 0x51, 0x8a, 0x8a, 0xd4, 0xe2, 0x1a, 0x9d, 0x04, 0xec, 0xda, + 0x6c, 0xa7, 0x77, 0xd3, 0xeb, 0x56, 0x86, 0x8f, 0x2b, 0x0e, 0xdc, 0x33, + 0xda, 0x3b, 0x4c, 0xe2, 0xc9, 0xaf, 0xa3, 0xd7, 0x47, 0xed, 0xe0, 0xc7, + 0x45, 0x16, 0xc8, 0xe9, 0xe4, 0xc8, 0xe9, 0xa2, 0x8d, 0x4e, 0x82, 0x8d, + 0x4a, 0xd7, 0xe9, 0x7c, 0x9d, 0xf9, 0x32, 0x64, 0xaf, 0x54, 0x43, 0x51, + 0x93, 0x9e, 0x4c, 0xf4, 0x7d, 0x5f, 0xa3, 0x9c, 0x90, 0xed, 0xb0, 0xb5, + 0xe7, 0xa6, 0x7a, 0xc8, 0xe6, 0xd1, 0xcd, 0x99, 0x11, 0x19, 0x4d, 0x2f, + 0x81, 0xcc, 0xee, 0x4d, 0x3b, 0x75, 0x37, 0x5c, 0x8c, 0xfd, 0xa5, 0xf3, + 0xe9, 0x45, 0x7f, 0xa4, 0xc9, 0x5f, 0xd7, 0x3b, 0x76, 0x3b, 0x2b, 0xa5, + 0x92, 0xab, 0x27, 0xe6, 0x40, 0xf3, 0xbd, 0xb2, 0xbd, 0x61, 0x0d, 0x61, + 0x1d, 0x60, 0xb5, 0x28, 0x57, 0x26, 0x73, 0x47, 0x23, 0x27, 0x23, 0x91, + 0xc8, 0xe4, 0x72, 0x39, 0x1c, 0xce, 0x67, 0x21, 0xb3, 0x96, 0x1f, 0x9d, + 0x8c, 0xa2, 0xf5, 0x7e, 0xfa, 0xeb, 0x7b, 0x8b, 0xd7, 0xa7, 0xfd, 0x8c, + 0x1c, 0x47, 0x08, 0x9d, 0xaa, 0x87, 0x55, 0x27, 0x1a, 0x86, 0xa0, 0x38, + 0xc5, 0x8d, 0x46, 0x2b, 0xbf, 0x76, 0xbe, 0xde, 0xc6, 0xb2, 0xa3, 0xb9, + 0xb8, 0x44, 0x86, 0xaf, 0x72, 0x84, 0x6c, 0xdd, 0x37, 0x1c, 0xb9, 0x4a, + 0x53, 0xa2, 0x1d, 0xcd, 0x36, 0xaf, 0xc3, 0xf4, 0xda, 0x67, 0x71, 0xda, + 0xcd, 0x27, 0x88, 0xa8, 0xb0, 0xaa, 0xd8, 0x5f, 0x1c, 0x18, 0x45, 0xd1, + 0xfc, 0xaf, 0x5e, 0x8a, 0x8e, 0xed, 0x4b, 0x46, 0x4b, 0x4d, 0x18, 0x0a, + 0x31, 0x46, 0x4c, 0xb3, 0xdf, 0xa6, 0xe3, 0xa5, 0xf3, 0x74, 0x76, 0x8e, + 0xd9, 0x6f, 0xe5, 0xc5, 0xf3, 0xa8, 0xaf, 0x52, 0x57, 0xaa, 0x21, 0xa9, + 0xc8, 0xad, 0x4c, 0xc8, 0xfa, 0xbf, 0x46, 0x0b, 0x6a, 0x6c, 0x94, 0x5a, + 0x1b, 0x39, 0xa3, 0x90, 0xd8, 0xaa, 0x6c, 0x54, 0x8a, 0xa1, 0x43, 0x1d, + 0x27, 0x06, 0xcc, 0x34, 0x61, 0x33, 0x81, 0xc4, 0xe3, 0xf6, 0x59, 0x1f, + 0x52, 0x2b, 0xfd, 0x39, 0x10, 0x8a, 0x37, 0x4d, 0x46, 0x9e, 0xbb, 0x2e, + 0x95, 0xb3, 0xe9, 0x6d, 0x4a, 0x71, 0x86, 0xd7, 0x0b, 0x69, 0x96, 0xd9, + 0x74, 0x07, 0x56, 0xa2, 0xb3, 0xbe, 0xe2, 0x47, 0x56, 0x85, 0xa9, 0x16, + 0xa8, 0x5a, 0xa1, 0x6a, 0x4f, 0x32, 0x79, 0x83, 0xcc, 0x23, 0xbe, 0x8e, + 0xf9, 0xde, 0x3b, 0xc3, 0xbc, 0x7a, 0x82, 0x7a, 0xa1, 0xdd, 0x39, 0x14, + 0xc6, 0x6d, 0xea, 0x56, 0x23, 0xeb, 0xa6, 0x4f, 0xb7, 0xc9, 0x99, 0x33, + 0xe9, 0xc9, 0xab, 0xd4, 0x4b, 0x59, 0x6d, 0x15, 0xc7, 0x4f, 0x53, 0x98, + 0xe4, 0x2f, 0x71, 0x7b, 0x15, 0x69, 0x6b, 0xb2, 0xd8, 0x72, 0x42, 0x66, + 0x0d, 0x56, 0xd1, 0xa7, 0xd5, 0x17, 0xed, 0xda, 0x8d, 0xa2, 0x5b, 0x66, + 0xe8, 0xb5, 0xd0, 0xe4, 0x5b, 0xfb, 0x3e, 0xbd, 0xb3, 0xf6, 0x3a, 0x70, + 0x47, 0x03, 0x89, 0xc0, 0xe0, 0x28, 0x23, 0x5d, 0xa2, 0xa1, 0xd5, 0xc4, + 0xd5, 0x55, 0xca, 0xa9, 0xe9, 0xe3, 0x32, 0xcd, 0xaa, 0x12, 0x6f, 0x6d, + 0xb6, 0x23, 0xa6, 0xea, 0x88, 0x6a, 0x48, 0xea, 0x88, 0xde, 0x77, 0x13, + 0xe8, 0xd7, 0x47, 0xd1, 0x2e, 0x8d, 0x0e, 0x27, 0x6c, 0xed, 0x1d, 0xa2, + 0x54, 0xca, 0x11, 0xc1, 0x83, 0x06, 0x0c, 0x18, 0x1d, 0x69, 0x9d, 0x93, + 0xb6, 0xc7, 0x11, 0xc4, 0xc1, 0x8f, 0x4e, 0x49, 0x4b, 0xda, 0x1e, 0xb8, + 0x3f, 0xa5, 0x0b, 0xae, 0x44, 0xfa, 0x33, 0x6b, 0xb3, 0x9e, 0x9f, 0x89, + 0xc0, 0x74, 0x45, 0x93, 0xd0, 0x55, 0x32, 0xdd, 0xaa, 0x98, 0xc6, 0x3a, + 0x28, 0x25, 0x2d, 0x10, 0xf4, 0x93, 0x3b, 0x17, 0x23, 0xb5, 0x71, 0xc2, + 0xe3, 0x17, 0x89, 0x5e, 0x42, 0x9b, 0x59, 0xe5, 0xc9, 0xe9, 0x39, 0x38, + 0xe9, 0x21, 0x15, 0xd8, 0x8a, 0x38, 0xe3, 0xa6, 0xab, 0xf4, 0x7a, 0xea, + 0x96, 0x23, 0x9f, 0x5c, 0xe1, 0xce, 0x34, 0xe8, 0xa3, 0xa7, 0x38, 0x0e, + 0x02, 0xad, 0xb2, 0x1a, 0x49, 0xb2, 0x1a, 0x58, 0xc4, 0x5e, 0xdd, 0x32, + 0x4e, 0x6e, 0x31, 0x86, 0xa6, 0x32, 0x24, 0xd3, 0x5a, 0xc8, 0x4f, 0x67, + 0xdc, 0x69, 0xd7, 0x46, 0xda, 0xa7, 0xac, 0x6e, 0x3e, 0xa4, 0x8d, 0xb5, + 0x7e, 0x47, 0xaf, 0x03, 0x8e, 0x56, 0xbf, 0x47, 0x1a, 0xd3, 0xeb, 0x81, + 0xa2, 0xed, 0x25, 0x53, 0xb1, 0xec, 0x0b, 0x0f, 0x67, 0xd4, 0xc0, 0x7a, + 0x2d, 0x54, 0x0e, 0x17, 0xc4, 0xe7, 0x24, 0x77, 0x51, 0xca, 0x2c, 0xc0, + 0xaa, 0x93, 0x3c, 0xb5, 0x8c, 0xf2, 0x56, 0x1f, 0x87, 0xc8, 0x5b, 0x7c, + 0x45, 0xa3, 0xae, 0x24, 0xf8, 0x51, 0x1b, 0xac, 0x76, 0xcb, 0xd7, 0x83, + 0x06, 0x09, 0x68, 0xfb, 0xd0, 0x96, 0x86, 0xd8, 0x92, 0xa9, 0xc4, 0xe2, + 0x71, 0x30, 0x60, 0x68, 0x9a, 0x22, 0xcc, 0x99, 0x32, 0x64, 0x72, 0x44, + 0x7e, 0xa2, 0x2b, 0x8a, 0x42, 0x5e, 0xbd, 0xb6, 0xc7, 0x1d, 0x57, 0xa3, + 0x50, 0xfe, 0xae, 0xb8, 0x30, 0x60, 0xc1, 0x8f, 0x44, 0xf2, 0x85, 0xcb, + 0x03, 0x2f, 0xfd, 0x3e, 0xb8, 0xf5, 0x5e, 0xac, 0x1c, 0xe3, 0x12, 0x88, + 0xc6, 0xc3, 0x1e, 0x9c, 0x96, 0xcb, 0xe9, 0xc8, 0xac, 0x94, 0x4d, 0xc6, + 0xbf, 0x3b, 0xa7, 0xd9, 0xb5, 0x7d, 0xab, 0x1a, 0xc7, 0xa9, 0x22, 0x31, + 0xc9, 0xa2, 0x8b, 0xae, 0xaf, 0x4f, 0x24, 0x77, 0x0b, 0x35, 0x91, 0x89, + 0x66, 0xe4, 0x89, 0x6b, 0x79, 0x12, 0xe3, 0x9f, 0x45, 0x8b, 0x26, 0xdf, + 0xa9, 0xc7, 0xa7, 0x06, 0x3d, 0x73, 0x92, 0x84, 0x6e, 0xb1, 0xdb, 0x2f, + 0xb7, 0xa5, 0xf8, 0x43, 0x59, 0x25, 0xa4, 0xaa, 0x44, 0xb6, 0xda, 0x99, + 0x2d, 0xa8, 0x96, 0xd7, 0x62, 0x25, 0xb6, 0xdc, 0x4b, 0x41, 0x72, 0x25, + 0xa0, 0xb0, 0xf2, 0x36, 0x9e, 0x42, 0xd1, 0x6d, 0x96, 0xb2, 0x3b, 0x3d, + 0x8c, 0x86, 0xcd, 0x32, 0x1b, 0x33, 0x35, 0x95, 0x46, 0x99, 0xc1, 0x7d, + 0x8d, 0x2c, 0xfb, 0x7a, 0x8f, 0x43, 0x97, 0x39, 0xfd, 0xb6, 0x46, 0x7d, + 0xb7, 0xf4, 0xd8, 0xa5, 0x42, 0x66, 0xa6, 0x9e, 0x30, 0xf5, 0xc5, 0x18, + 0xe9, 0x8e, 0x9c, 0xe2, 0x8e, 0x68, 0xcc, 0x98, 0xab, 0xb1, 0x8b, 0x4d, + 0x92, 0xad, 0x3c, 0x51, 0xc7, 0x0b, 0x06, 0x3d, 0x0c, 0xb3, 0xe0, 0xc1, + 0x83, 0x78, 0xd1, 0x38, 0x3d, 0xbb, 0x55, 0xe6, 0xe9, 0x59, 0xc7, 0xd4, + 0x25, 0x22, 0x35, 0x91, 0xa6, 0x24, 0x34, 0xf5, 0x95, 0x42, 0xb8, 0x0a, + 0xd8, 0xa3, 0xbf, 0x13, 0xcc, 0x0f, 0x52, 0xc7, 0xa8, 0xb0, 0x76, 0x5c, + 0xcb, 0xb5, 0x57, 0xc6, 0xde, 0xf4, 0xe4, 0x67, 0xec, 0x48, 0x97, 0xb1, + 0xa4, 0xd4, 0x79, 0x8a, 0xbe, 0xd4, 0xe6, 0xa0, 0xaf, 0xb9, 0xda, 0xfe, + 0xde, 0x0d, 0x3a, 0xf5, 0xe3, 0xa6, 0x0c, 0x18, 0x30, 0x60, 0xc1, 0xb8, + 0xee, 0x3d, 0xa2, 0x28, 0x5f, 0x66, 0x9b, 0x3b, 0x95, 0x74, 0xba, 0x5c, + 0x6b, 0x8f, 0xab, 0x26, 0x4c, 0xfa, 0xb2, 0xe0, 0xe1, 0x72, 0x99, 0x38, + 0xa9, 0xc6, 0x5a, 0x48, 0x1e, 0x52, 0x27, 0x95, 0x89, 0xe5, 0xa2, 0x79, + 0x78, 0x9d, 0x88, 0x9d, 0x98, 0x9d, 0xa8, 0x9d, 0x94, 0x76, 0xa2, 0x76, + 0xd1, 0x2a, 0xa3, 0x21, 0x55, 0x18, 0x9c, 0x4c, 0x74, 0x8c, 0x79, 0x11, + 0x8e, 0x06, 0x63, 0xa6, 0x0c, 0x18, 0x19, 0x6f, 0xa2, 0x75, 0xab, 0x23, + 0x65, 0x73, 0xda, 0x35, 0xba, 0x7b, 0x63, 0xa8, 0xad, 0x21, 0x44, 0x51, + 0x14, 0x44, 0x85, 0xea, 0xba, 0xde, 0xcd, 0x69, 0xf2, 0x7f, 0x65, 0x92, + 0x45, 0x17, 0x3d, 0x3d, 0xaa, 0x4a, 0x4b, 0xec, 0x4e, 0x6a, 0x0a, 0xfb, + 0x9d, 0xb2, 0x7f, 0x71, 0x14, 0x2f, 0xa7, 0xec, 0x63, 0xae, 0x3a, 0x6e, + 0x3a, 0xff, 0x00, 0x2f, 0x1f, 0x96, 0xbe, 0xd6, 0xd7, 0x77, 0x2a, 0xba, + 0x6a, 0xa4, 0x47, 0xef, 0xc9, 0x11, 0xd4, 0x38, 0x99, 0x52, 0x4d, 0x18, + 0x30, 0x60, 0xc1, 0x83, 0x06, 0x3d, 0x71, 0x86, 0x48, 0xc7, 0xd5, 0x83, + 0x04, 0x91, 0x35, 0xef, 0xc4, 0xe2, 0x60, 0xf7, 0x35, 0xb5, 0x2d, 0x4d, + 0x3b, 0x6d, 0xb6, 0xe8, 0x6f, 0x8a, 0xca, 0x48, 0xc7, 0x45, 0xeb, 0xd6, + 0x5f, 0xdd, 0xb2, 0x3f, 0x6d, 0x93, 0x46, 0xdf, 0xa9, 0xe2, 0xfd, 0x76, + 0xdf, 0x1a, 0x95, 0xb6, 0xbb, 0x5f, 0xdd, 0x46, 0x92, 0x5f, 0x57, 0xda, + 0xc7, 0x4d, 0x7e, 0xe0, 0xb4, 0xeb, 0xde, 0x72, 0x5f, 0x6f, 0x43, 0x67, + 0x0d, 0x4f, 0x4b, 0x25, 0xce, 0xd5, 0xfd, 0x06, 0x8f, 0x78, 0x38, 0xea, + 0x0f, 0x93, 0x06, 0x3e, 0xce, 0x08, 0xc0, 0x51, 0x31, 0xe8, 0xc1, 0x83, + 0x06, 0x09, 0xfb, 0x18, 0x30, 0x71, 0x38, 0x9c, 0x0e, 0x08, 0x50, 0x5f, + 0x6f, 0x5b, 0xa8, 0xed, 0x42, 0x22, 0xfb, 0x92, 0x44, 0x91, 0xa4, 0xd7, + 0x72, 0xf4, 0xb7, 0x82, 0xed, 0x58, 0xde, 0x7f, 0xa1, 0x44, 0xb8, 0xdf, + 0xf6, 0xa4, 0xd4, 0x56, 0xb3, 0x74, 0xe4, 0x7c, 0x89, 0x7d, 0xdd, 0x2d, + 0xea, 0xfa, 0xae, 0xb3, 0x84, 0x21, 0xfd, 0x26, 0x87, 0x11, 0x39, 0x56, + 0x47, 0x50, 0x84, 0xd4, 0x8c, 0x7a, 0xd4, 0x32, 0x46, 0xb1, 0x44, 0xc7, + 0xa7, 0x06, 0x0c, 0x18, 0x2e, 0xf8, 0xc1, 0x83, 0x06, 0x0c, 0x18, 0xfb, + 0x76, 0x5a, 0xaa, 0x84, 0xec, 0x76, 0xce, 0x3d, 0x73, 0xf6, 0xda, 0x25, + 0x13, 0x4d, 0xae, 0x75, 0x10, 0xb2, 0x36, 0x44, 0xb7, 0x53, 0x1a, 0xcb, + 0x2e, 0x95, 0x9f, 0xd2, 0x6f, 0x0e, 0xb9, 0xf7, 0x21, 0xf6, 0x2e, 0xba, + 0x14, 0x43, 0x59, 0xaf, 0x96, 0xa9, 0xa4, 0x63, 0xef, 0x68, 0x35, 0x1d, + 0x9b, 0xae, 0xb3, 0xbb, 0x35, 0xfd, 0x4c, 0x0e, 0x26, 0x30, 0x2b, 0xe4, + 0x85, 0xa8, 0x8b, 0x13, 0x4f, 0xa7, 0xc8, 0xab, 0x6c, 0x8d, 0x78, 0x14, + 0x0c, 0x7a, 0xf0, 0x60, 0xc0, 0xcb, 0x7e, 0x7e, 0xfb, 0x92, 0x8a, 0xd4, + 0xea, 0x1e, 0xa2, 0x71, 0x42, 0xfb, 0xec, 0x71, 0x21, 0x64, 0xe9, 0x94, + 0xb5, 0xd2, 0xb3, 0xd1, 0x9f, 0xe8, 0x33, 0x41, 0x6f, 0xae, 0x73, 0x8d, + 0x71, 0xd4, 0x6f, 0x09, 0x16, 0x5b, 0x3b, 0xe4, 0x97, 0xf4, 0x28, 0x87, + 0x29, 0x45, 0x7f, 0x5f, 0x02, 0xa9, 0xc8, 0x8e, 0x8a, 0x72, 0x23, 0xa0, + 0x8a, 0x23, 0x42, 0x89, 0xc0, 0xc1, 0x8f, 0xb1, 0x8f, 0x43, 0x25, 0xee, + 0xfe, 0xf6, 0x70, 0xb5, 0x7a, 0xae, 0xfb, 0x8a, 0xeb, 0x93, 0x3e, 0xac, + 0x99, 0x33, 0xea, 0x7d, 0x1a, 0x3d, 0xd1, 0xdc, 0x3e, 0x7f, 0xa2, 0xc8, + 0xc9, 0xc2, 0x55, 0x58, 0xad, 0x87, 0x5b, 0x75, 0x15, 0xd0, 0x5f, 0xbb, + 0x96, 0xdd, 0x3b, 0x98, 0x97, 0xf4, 0x22, 0xb9, 0x3a, 0xe1, 0xc5, 0x47, + 0xfa, 0xad, 0x95, 0x68, 0xe5, 0x32, 0xbd, 0x34, 0x2a, 0x38, 0xa4, 0x60, + 0xc7, 0x4c, 0x18, 0xe9, 0x8f, 0xb4, 0xcb, 0x65, 0x85, 0xf7, 0xa5, 0x25, + 0x15, 0xaa, 0xd5, 0xf7, 0x84, 0x85, 0xf7, 0xb3, 0xeb, 0xc0, 0xd1, 0xee, + 0x8e, 0xe1, 0x94, 0xff, 0x00, 0xa3, 0xa7, 0xb9, 0xd3, 0x27, 0xac, 0xa6, + 0x31, 0xb7, 0x77, 0xae, 0x25, 0xbb, 0x95, 0xf6, 0x8f, 0x2c, 0xc1, 0xc4, + 0xc7, 0xf4, 0x68, 0xaf, 0x04, 0x50, 0xbe, 0xf6, 0x4c, 0xfa, 0xf4, 0xfa, + 0x97, 0xa7, 0x21, 0x64, 0x6d, 0x8f, 0xdb, 0xc1, 0x8f, 0x4c, 0x89, 0xcb, + 0x93, 0xfb, 0x96, 0x6b, 0x68, 0xa5, 0xfe, 0x27, 0x47, 0x1b, 0xb5, 0x32, + 0xd4, 0x34, 0x85, 0xf6, 0x96, 0xeb, 0x41, 0x0d, 0x7d, 0x13, 0x14, 0xd4, + 0x8c, 0xfd, 0xbc, 0x0e, 0x23, 0x89, 0x96, 0x8e, 0xe1, 0xcd, 0x19, 0xf5, + 0x64, 0xc9, 0xc8, 0xe6, 0x46, 0xa9, 0xe3, 0x89, 0x81, 0xb8, 0xa2, 0x7d, + 0xb9, 0x1c, 0x4c, 0x18, 0x31, 0xd7, 0x26, 0x4c, 0x99, 0x33, 0xf6, 0xea, + 0xa0, 0x8c, 0x44, 0xbf, 0xa7, 0x93, 0x26, 0x4c, 0x9c, 0x8a, 0xed, 0x75, + 0x4a, 0x9d, 0x74, 0x66, 0x72, 0x32, 0x64, 0xcf, 0xa7, 0x26, 0x45, 0xe9, + 0x6c, 0xb6, 0xcc, 0xfd, 0xdb, 0xda, 0x55, 0x27, 0xc6, 0xcc, 0x91, 0xb9, + 0xc4, 0x86, 0xad, 0x11, 0xb6, 0x32, 0x32, 0x64, 0xcf, 0x4c, 0x99, 0x32, + 0x4e, 0xe8, 0xc0, 0x96, 0xe5, 0x44, 0x4b, 0x3c, 0x38, 0xe4, 0x79, 0x0d, + 0x4e, 0x9c, 0x82, 0xe2, 0x67, 0xef, 0xe0, 0xc1, 0x8e, 0x9c, 0x9a, 0x39, + 0x9c, 0xce, 0x68, 0xe6, 0x87, 0x24, 0x69, 0x76, 0xff, 0x00, 0x30, 0xab, + 0xd2, 0x55, 0xa7, 0x35, 0x15, 0xd9, 0x63, 0x7a, 0x39, 0x0f, 0x41, 0x91, + 0x68, 0x11, 0x1d, 0x15, 0x79, 0xf2, 0x5a, 0x61, 0xe8, 0x68, 0x2c, 0xdb, + 0x6b, 0x6a, 0xfd, 0x25, 0xf0, 0x27, 0xa9, 0xb2, 0x0e, 0x1a, 0xa9, 0xb1, + 0x5b, 0x26, 0x72, 0x33, 0xf6, 0xe1, 0x07, 0x32, 0xba, 0x54, 0x48, 0xc4, + 0x4b, 0xfa, 0xb8, 0xf4, 0x64, 0xc9, 0x2d, 0x57, 0x93, 0x8d, 0x9e, 0x23, + 0xd4, 0xda, 0xd6, 0xb3, 0x70, 0xb8, 0x9d, 0x5a, 0xeb, 0x23, 0xa6, 0xa7, + 0x71, 0x83, 0xd3, 0xbd, 0x4a, 0x5e, 0x64, 0x56, 0x9c, 0x84, 0xc4, 0x67, + 0xa6, 0x47, 0x32, 0xcb, 0xb2, 0x67, 0xed, 0xd9, 0xaa, 0xae, 0xa2, 0xdd, + 0xc9, 0xb2, 0x52, 0x95, 0x8f, 0x5d, 0x4f, 0x17, 0x09, 0xe5, 0x19, 0x14, + 0x88, 0xea, 0x25, 0x12, 0x3a, 0xd6, 0x2d, 0x5c, 0x58, 0xae, 0x8b, 0x39, + 0x74, 0xb6, 0x8d, 0x55, 0xa4, 0x7c, 0x3d, 0xc8, 0x5e, 0x1d, 0x8a, 0x3f, + 0x1a, 0xc9, 0xf8, 0x85, 0x47, 0x9f, 0xa8, 0xf3, 0x3a, 0x79, 0x1a, 0x9d, + 0x67, 0x60, 0xaf, 0x74, 0x84, 0x88, 0xea, 0xab, 0x99, 0x9c, 0xff, 0x00, + 0x51, 0xb3, 0x9b, 0x89, 0x1d, 0xd7, 0x51, 0x58, 0xf7, 0x3d, 0x42, 0x7f, + 0x8d, 0x5e, 0x85, 0xbe, 0xa1, 0x6f, 0x5a, 0x66, 0x7e, 0x2b, 0xa3, 0x62, + 0xdc, 0xb4, 0xac, 0xf3, 0xb4, 0xb1, 0xdd, 0x5c, 0x85, 0x24, 0x6b, 0x7c, + 0xb3, 0x8c, 0x65, 0x53, 0x94, 0x38, 0xc8, 0xe2, 0x63, 0xec, 0xc6, 0x99, + 0x32, 0x1a, 0x64, 0x85, 0x01, 0x21, 0x2f, 0xeb, 0xe0, 0xc1, 0xc4, 0xe0, + 0x76, 0x8b, 0x27, 0x3c, 0xd5, 0xa2, 0x8c, 0x08, 0xa9, 0xc1, 0xf7, 0xa4, + 0x77, 0x4e, 0xf1, 0xcf, 0xdf, 0x98, 0xac, 0x91, 0xdf, 0xb5, 0x16, 0x6e, + 0x4e, 0xb5, 0x6f, 0x8a, 0xaf, 0xa2, 0xca, 0xbc, 0x62, 0xd9, 0x5f, 0x89, + 0x6a, 0xb4, 0x96, 0xe9, 0x19, 0x46, 0xdf, 0x11, 0x69, 0xea, 0x1f, 0x8a, + 0x11, 0xff, 0x00, 0xa8, 0x3f, 0xf5, 0x02, 0xf1, 0x42, 0x2b, 0xf1, 0x24, + 0x66, 0x69, 0x37, 0x2a, 0xf5, 0x7d, 0x25, 0x74, 0x22, 0x4b, 0x5f, 0x54, + 0x49, 0xee, 0x52, 0x64, 0xf5, 0x16, 0x58, 0x60, 0xc1, 0x82, 0x51, 0x52, + 0x8d, 0xf5, 0x3d, 0x35, 0x8a, 0x59, 0xf4, 0xe4, 0xc9, 0xcd, 0x91, 0xd5, + 0x59, 0x11, 0x6b, 0xa6, 0x88, 0xef, 0x77, 0x24, 0xb7, 0xe9, 0xf5, 0xc9, + 0x93, 0x3d, 0x30, 0x8c, 0xca, 0x27, 0x9c, 0xba, 0xb3, 0xf1, 0x87, 0x02, + 0x3b, 0xed, 0x45, 0x7b, 0x9e, 0x9e, 0xd1, 0x4b, 0x3f, 0x73, 0x28, 0x95, + 0x91, 0x43, 0xbe, 0xb2, 0x5a, 0x9a, 0x91, 0x2d, 0x5d, 0x42, 0x97, 0x71, + 0xf9, 0x6b, 0xa6, 0x4b, 0x41, 0xa8, 0x25, 0xa1, 0xd4, 0x22, 0x55, 0xb8, + 0xb9, 0x57, 0x83, 0x89, 0xc0, 0xed, 0x8e, 0x94, 0xcb, 0x69, 0x84, 0x61, + 0xa7, 0x16, 0x51, 0x1d, 0x44, 0xa2, 0x43, 0x51, 0x19, 0x7a, 0xa3, 0xc5, + 0x90, 0xd3, 0xc1, 0x91, 0xa9, 0x21, 0x44, 0xe2, 0x63, 0xfb, 0x38, 0x38, + 0x32, 0xcb, 0xa9, 0xa8, 0xbb, 0x75, 0x48, 0xd5, 0xee, 0x36, 0xc8, 0xd1, + 0x6f, 0x77, 0x50, 0x7f, 0xe8, 0x20, 0x7e, 0x3f, 0x59, 0xf8, 0xf4, 0x4f, + 0xc7, 0xcf, 0xc7, 0xac, 0x1e, 0xfb, 0xa8, 0x25, 0xbd, 0x6a, 0xa4, 0x4b, + 0x71, 0xd4, 0xcc, 0x95, 0x93, 0x99, 0x81, 0x7b, 0x19, 0x7d, 0x2d, 0xb2, + 0xc9, 0x8b, 0xa6, 0x4e, 0xe2, 0x43, 0xd4, 0x60, 0x5a, 0xa9, 0x9b, 0x54, + 0xaf, 0x95, 0x8e, 0x72, 0x91, 0x83, 0x06, 0x3d, 0x57, 0xd6, 0xad, 0x84, + 0xd3, 0xa6, 0x51, 0x9e, 0x4c, 0x99, 0x33, 0xea, 0xc9, 0x93, 0x3d, 0x33, + 0xd3, 0x26, 0x4c, 0x99, 0x32, 0x59, 0xc7, 0x13, 0xe2, 0x60, 0xae, 0xdb, + 0x2a, 0x2b, 0xde, 0x2f, 0x81, 0x5e, 0xfb, 0x06, 0x57, 0xb9, 0xe9, 0xac, + 0x23, 0x35, 0x21, 0xb2, 0x7a, 0xba, 0xe0, 0x5b, 0xb9, 0x58, 0xdf, 0x9b, + 0xb9, 0x8f, 0x57, 0x60, 0xbb, 0xd3, 0x22, 0xb0, 0x39, 0x60, 0xb7, 0x52, + 0x73, 0x93, 0x39, 0x31, 0x4d, 0x8a, 0xc9, 0x15, 0xea, 0x25, 0xcb, 0xcd, + 0x4a, 0xa5, 0xf8, 0xdd, 0xd0, 0x2f, 0xde, 0x25, 0x7c, 0x7c, 0xc5, 0x68, + 0x8d, 0xb1, 0x97, 0xa1, 0xc6, 0x33, 0x23, 0x5c, 0x62, 0x63, 0xad, 0x36, + 0xb8, 0x34, 0xf2, 0xba, 0xb5, 0x93, 0x80, 0xa7, 0x6c, 0x05, 0xae, 0xbe, + 0x02, 0xdd, 0xe7, 0x11, 0x6f, 0x70, 0x3f, 0x1b, 0xa0, 0x9e, 0xfd, 0x04, + 0x4b, 0x7e, 0xb1, 0x8f, 0x79, 0xd4, 0x33, 0xf1, 0x4d, 0x4b, 0x3f, 0x13, + 0xd5, 0x1f, 0x89, 0xea, 0x8f, 0xc5, 0x75, 0x27, 0xe2, 0xfa, 0x84, 0x7e, + 0x33, 0x79, 0xf8, 0xcd, 0xe7, 0xe3, 0x17, 0x9f, 0x8c, 0x6a, 0x0f, 0xc7, + 0xf5, 0x27, 0xe3, 0xfa, 0x81, 0x78, 0x8e, 0xf4, 0x47, 0xc5, 0x16, 0x22, + 0xbf, 0x16, 0xd6, 0x89, 0xef, 0xfa, 0x5b, 0x67, 0x0d, 0xd3, 0x4d, 0x32, + 0x1a, 0x8a, 0x66, 0x46, 0x11, 0x91, 0xda, 0x45, 0xd6, 0xd3, 0xa6, 0x8d, + 0xfb, 0xfa, 0x45, 0xdb, 0x9d, 0x97, 0x0e, 0xfc, 0x9d, 0xcc, 0x9a, 0x86, + 0xcd, 0x2c, 0xce, 0xdb, 0x67, 0x69, 0x9c, 0x4c, 0x18, 0x30, 0x8a, 0x74, + 0xee, 0xe2, 0x3b, 0x36, 0x4f, 0xc3, 0x2a, 0x16, 0xd9, 0x5b, 0x76, 0xe8, + 0x21, 0x58, 0xe9, 0xc0, 0xe1, 0x11, 0xd3, 0x06, 0x76, 0x6b, 0x3b, 0x35, + 0x0b, 0x45, 0x54, 0x87, 0xb6, 0xc0, 0x8e, 0xd7, 0x02, 0xad, 0xab, 0x4f, + 0x9a, 0xa9, 0x85, 0x31, 0xc1, 0x8f, 0x46, 0x49, 0xdf, 0x0a, 0x8b, 0x37, + 0x8a, 0x20, 0x5b, 0xbd, 0xd9, 0x21, 0xd9, 0x76, 0xa0, 0xae, 0xbc, 0x0b, + 0xdb, 0xa6, 0x4c, 0x99, 0x32, 0x64, 0xc9, 0x93, 0x26, 0x7a, 0x67, 0xd3, + 0x93, 0x24, 0xac, 0xc1, 0x65, 0xd9, 0xe8, 0x9f, 0x4c, 0x23, 0x84, 0x4e, + 0xdc, 0x48, 0xfe, 0x58, 0xf5, 0x56, 0xc9, 0x2c, 0x9c, 0x24, 0xc8, 0xd0, + 0x88, 0xc3, 0x03, 0x9c, 0x62, 0x4f, 0x56, 0x91, 0x2b, 0x1c, 0xfa, 0xe4, + 0x47, 0xc2, 0xab, 0xde, 0x4d, 0xfb, 0x36, 0x4d, 0x93, 0x48, 0xcf, 0x17, + 0x1d, 0x4b, 0x15, 0xcd, 0x99, 0x93, 0x3e, 0xa1, 0x26, 0x47, 0xd8, 0xc9, + 0xc5, 0x33, 0xb6, 0xc8, 0x5b, 0x6d, 0x49, 0xea, 0xed, 0x3c, 0xdd, 0xa7, + 0x99, 0xb8, 0x77, 0xda, 0xc7, 0x6c, 0xce, 0x67, 0x24, 0x77, 0x22, 0x77, + 0xeb, 0x47, 0x99, 0x80, 0xae, 0x94, 0x88, 0x3b, 0x3a, 0x76, 0xe4, 0x47, + 0x4f, 0x29, 0x0b, 0x6e, 0x94, 0x8f, 0x25, 0x5a, 0x6b, 0x41, 0x03, 0xc8, + 0x44, 0xfc, 0x3a, 0x23, 0xdb, 0xa2, 0x79, 0x08, 0x36, 0xf6, 0xe9, 0xc4, + 0x95, 0x13, 0x89, 0x2a, 0xe5, 0x05, 0x91, 0xb9, 0x37, 0xe5, 0xee, 0xc6, + 0x30, 0x64, 0xe6, 0xd1, 0x1d, 0x4d, 0xd1, 0x25, 0x7d, 0xb3, 0x39, 0x48, + 0xe4, 0xc5, 0x19, 0x31, 0x53, 0x22, 0x50, 0x82, 0x4a, 0xca, 0xe0, 0x77, + 0x72, 0x67, 0xab, 0x25, 0x6f, 0x13, 0xcc, 0xb2, 0x36, 0x4e, 0x42, 0x52, + 0x62, 0x83, 0x23, 0xed, 0x1b, 0x66, 0xd4, 0x95, 0x8d, 0x8e, 0x46, 0x4c, + 0x9e, 0xe8, 0x86, 0xa9, 0xc4, 0x8e, 0xa2, 0x13, 0x32, 0x2b, 0xa7, 0x12, + 0x3a, 0xd9, 0xa1, 0xee, 0x72, 0x47, 0xe3, 0x0c, 0x5b, 0xba, 0x2d, 0xdd, + 0xac, 0x65, 0xba, 0xbd, 0x4d, 0xa7, 0x16, 0x60, 0x4d, 0x27, 0x09, 0x64, + 0x4c, 0xcf, 0x4c, 0x99, 0x32, 0x67, 0xd1, 0x93, 0x3d, 0x32, 0x64, 0xc9, + 0x93, 0x91, 0x2b, 0x52, 0x27, 0xa9, 0x25, 0x6f, 0x23, 0x3d, 0x56, 0x4e, + 0x2c, 0x55, 0xc8, 0x5a, 0x79, 0x1e, 0x5d, 0x9d, 0xb4, 0x8e, 0x55, 0xc4, + 0xf3, 0x35, 0xa1, 0xeb, 0x19, 0x2b, 0xa7, 0x23, 0xe4, 0xc7, 0xa3, 0x02, + 0xfa, 0x49, 0x4b, 0x25, 0x31, 0x25, 0xf1, 0x27, 0x82, 0x56, 0x21, 0xfd, + 0x47, 0x65, 0xb3, 0xcb, 0xc8, 0x5a, 0x79, 0xa2, 0x30, 0x9a, 0x12, 0x6b, + 0xa6, 0x4e, 0xe6, 0x0e, 0xf9, 0xe6, 0x0f, 0x35, 0x23, 0xcd, 0x48, 0xf3, + 0x19, 0x39, 0xc4, 0xab, 0x57, 0x4c, 0x09, 0x6e, 0x10, 0x65, 0xbc, 0xae, + 0x3c, 0xae, 0x4f, 0x26, 0x79, 0x33, 0xca, 0x15, 0xd7, 0xc0, 0xc9, 0x19, + 0x71, 0x6b, 0x55, 0x12, 0xad, 0x6c, 0x20, 0x2d, 0xc2, 0xb6, 0x3b, 0x74, + 0xb3, 0x6a, 0xca, 0x4e, 0xe5, 0x47, 0x76, 0xa4, 0x79, 0x8a, 0x8e, 0xfe, + 0x9a, 0x2e, 0x5b, 0x85, 0x45, 0xba, 0xc8, 0x4c, 0x9e, 0xa7, 0x28, 0x6c, + 0xdb, 0x75, 0xbe, 0x5a, 0xc7, 0xbe, 0x6d, 0xa8, 0xd6, 0xee, 0xba, 0x3d, + 0x44, 0x27, 0x05, 0x63, 0x54, 0x21, 0x42, 0x28, 0xf6, 0x47, 0x70, 0xee, + 0x9d, 0xd3, 0xb8, 0x33, 0x11, 0x1f, 0x04, 0x3b, 0x22, 0x87, 0x78, 0xee, + 0x91, 0x9c, 0x90, 0x23, 0x32, 0x36, 0x0a, 0x64, 0x5f, 0xb5, 0xc4, 0x64, + 0x7c, 0x8c, 0xc9, 0x9e, 0xaa, 0x72, 0x89, 0x1d, 0x54, 0xd0, 0xb5, 0x68, + 0x57, 0xd6, 0xcf, 0xa6, 0x43, 0xa7, 0x23, 0xd3, 0xc8, 0x74, 0xcd, 0x0e, + 0x32, 0x3d, 0xcc, 0x8a, 0xcc, 0x11, 0xd5, 0xe0, 0x5a, 0xc4, 0x2d, 0x54, + 0x59, 0xdf, 0x89, 0xdc, 0x89, 0xc9, 0x19, 0x33, 0xe9, 0xe4, 0x8e, 0x51, + 0x39, 0x44, 0xe5, 0x03, 0x35, 0x9f, 0x94, 0x62, 0x83, 0x14, 0x1f, 0x90, + 0x72, 0xa8, 0xee, 0x44, 0xef, 0x1d, 0xe9, 0x9d, 0xdb, 0x8e, 0x57, 0x33, + 0x16, 0xb3, 0xb7, 0x33, 0xb4, 0xce, 0xdb, 0x38, 0xb3, 0x8b, 0x38, 0xb3, + 0x8b, 0x38, 0xb3, 0x8b, 0x38, 0x98, 0xc1, 0xcd, 0x21, 0xc9, 0xb2, 0x10, + 0x21, 0x1c, 0x12, 0x24, 0x89, 0xc0, 0xf7, 0x42, 0x9e, 0x05, 0x68, 0xad, + 0x3b, 0x88, 0xe4, 0x8c, 0x9c, 0xcc, 0x9e, 0xc6, 0x22, 0x61, 0x18, 0x30, + 0x60, 0xc3, 0x30, 0xcf, 0x73, 0xdc, 0xcb, 0x39, 0x33, 0x2c, 0xe4, 0x72, + 0x39, 0x1c, 0x8e, 0x47, 0x23, 0x91, 0xc8, 0xe6, 0x73, 0x39, 0x1c, 0x8e, + 0x5d, 0x30, 0x70, 0x3b, 0x67, 0x68, 0xec, 0x1d, 0x83, 0xcb, 0x9d, 0x96, + 0x76, 0xe6, 0x71, 0x91, 0x87, 0xd7, 0xdb, 0xa3, 0x82, 0x3b, 0x31, 0x3c, + 0xbc, 0x07, 0x4c, 0x0e, 0xd4, 0x0e, 0x31, 0xe8, 0xa4, 0xc8, 0xc9, 0x91, + 0x22, 0x4d, 0x64, 0x94, 0x0e, 0x4d, 0x0a, 0x67, 0xb3, 0x38, 0x98, 0xfb, + 0x1c, 0x9a, 0x15, 0xb3, 0x47, 0x98, 0xb0, 0xf3, 0x12, 0x3b, 0xc7, 0x72, + 0x2c, 0xcd, 0x66, 0x29, 0x38, 0x52, 0x70, 0xa4, 0xe1, 0x51, 0xc6, 0xb3, + 0x10, 0x3e, 0x93, 0xe9, 0x32, 0x8c, 0xa3, 0x92, 0x3c, 0xb9, 0xe5, 0xcf, + 0x2e, 0x79, 0x73, 0xcb, 0x9e, 0x5c, 0xf2, 0xe7, 0x97, 0x3c, 0xb9, 0xd8, + 0x3b, 0x07, 0x60, 0xec, 0x1d, 0x86, 0x76, 0x19, 0xd9, 0x91, 0xda, 0x99, + 0xc6, 0x68, 0xfc, 0xc3, 0x36, 0x19, 0xb0, 0xfc, 0xc3, 0xf3, 0x0c, 0x58, + 0x70, 0xb0, 0xec, 0xcc, 0xf2, 0xec, 0x5a, 0x71, 0x55, 0x81, 0x2c, 0x75, + 0x68, 0x70, 0x1d, 0x43, 0xd3, 0x9e, 0x58, 0xf2, 0xec, 0xec, 0x48, 0xec, + 0xcc, 0xed, 0xd8, 0x70, 0xb0, 0xc5, 0x87, 0xe6, 0x19, 0xb0, 0xe5, 0x61, + 0xca, 0x67, 0x39, 0x9c, 0xe4, 0x73, 0x91, 0xdc, 0x91, 0xdc, 0x91, 0xdc, + 0x91, 0xdd, 0x91, 0xdd, 0x91, 0xdd, 0x67, 0x75, 0x9d, 0xd6, 0x77, 0x59, + 0xdd, 0x67, 0x75, 0x9d, 0xd6, 0x77, 0x59, 0xdd, 0x67, 0x75, 0x9d, 0xd6, + 0x77, 0x59, 0xdd, 0x67, 0x75, 0x9d, 0xd6, 0x77, 0x59, 0xdd, 0x67, 0x75, + 0x9d, 0xc6, 0x77, 0x24, 0x77, 0x24, 0x77, 0x24, 0x73, 0x99, 0xce, 0x67, + 0x39, 0x9c, 0xa6, 0x72, 0xb0, 0xcd, 0x87, 0xe6, 0x1f, 0x9a, 0x62, 0xd3, + 0x85, 0xa7, 0x6a, 0xc3, 0xb1, 0x33, 0xcb, 0x48, 0xf2, 0xcc, 0x5a, 0x61, + 0x50, 0x2a, 0xc5, 0x1e, 0xae, 0x39, 0x1d, 0x49, 0x8f, 0x4e, 0x79, 0x63, + 0xb1, 0x23, 0xb3, 0x33, 0xb7, 0x33, 0x84, 0xce, 0x12, 0x38, 0x48, 0xe0, + 0xce, 0x0c, 0xe0, 0xce, 0x0c, 0xe0, 0xce, 0x07, 0x06, 0x70, 0x38, 0x1c, + 0x0e, 0x07, 0x13, 0x06, 0x3a, 0x61, 0x9c, 0x59, 0xdb, 0x91, 0xda, 0x91, + 0xd9, 0x67, 0x61, 0x9f, 0xff, 0xc4, 0x00, 0x32, 0x11, 0x00, 0x01, 0x03, + 0x02, 0x03, 0x08, 0x01, 0x04, 0x02, 0x02, 0x03, 0x01, 0x01, 0x00, 0x00, + 0x00, 0x01, 0x00, 0x02, 0x11, 0x03, 0x12, 0x20, 0x30, 0x31, 0x04, 0x10, + 0x13, 0x21, 0x32, 0x40, 0x41, 0x51, 0x14, 0x05, 0x22, 0x50, 0x61, 0x33, + 0x42, 0x52, 0x60, 0x15, 0x23, 0x81, 0x71, 0x24, 0xff, 0xda, 0x00, 0x08, + 0x01, 0x03, 0x01, 0x01, 0x3f, 0x01, 0xfc, 0x64, 0xe3, 0x95, 0x3b, 0xe5, + 0x4a, 0x95, 0x3b, 0xe7, 0x70, 0xa2, 0x4a, 0xf8, 0xee, 0x5f, 0x1d, 0xc8, + 0x6c, 0xde, 0xca, 0xf8, 0xcd, 0xf6, 0xbe, 0x3b, 0x17, 0x02, 0x9a, 0xe0, + 0xd3, 0xf4, 0xb8, 0x54, 0xfd, 0x2e, 0x13, 0x3d, 0x2e, 0x1d, 0x3f, 0x4b, + 0x86, 0xcf, 0x4b, 0x86, 0xcf, 0x4a, 0xc6, 0x7a, 0x56, 0x33, 0xd2, 0xb1, + 0xbe, 0x95, 0x8d, 0xf4, 0xac, 0x6f, 0xa5, 0x63, 0x7d, 0x2b, 0x1b, 0xe9, + 0x58, 0xdf, 0x4a, 0xd6, 0xfa, 0x56, 0x0f, 0x4a, 0xd1, 0xe9, 0x5a, 0xd5, + 0x68, 0x56, 0xb7, 0xd2, 0xb4, 0x7a, 0x56, 0xb7, 0xd2, 0xb5, 0xaa, 0xd6, + 0xab, 0x5a, 0xad, 0x6a, 0xb4, 0x2b, 0x42, 0xb4, 0x2b, 0x42, 0xb0, 0x2b, + 0x42, 0xb5, 0xbe, 0x95, 0x8d, 0xf4, 0xac, 0x6f, 0xa5, 0x63, 0x7d, 0x2b, + 0x07, 0xa5, 0x6b, 0x7d, 0x2b, 0x5b, 0xe9, 0x58, 0xdf, 0x4a, 0xc6, 0xfa, + 0x56, 0x37, 0xd2, 0xb1, 0xbe, 0x97, 0x0d, 0xbe, 0x97, 0x0d, 0x9e, 0x97, + 0x0d, 0x9e, 0x97, 0x0d, 0x9e, 0x97, 0x09, 0x9e, 0x97, 0x09, 0x9e, 0x97, + 0x09, 0x9e, 0x97, 0x05, 0x9e, 0x97, 0x02, 0x9f, 0xa5, 0xf1, 0xe9, 0xaf, + 0x8e, 0xc5, 0xf1, 0x9a, 0x8e, 0xcb, 0xe9, 0x3a, 0x8b, 0x9a, 0xa2, 0x11, + 0x04, 0x2e, 0x6b, 0x9e, 0xe8, 0xdd, 0x0a, 0x3f, 0x31, 0x4a, 0xe9, 0xe5, + 0x82, 0x37, 0xc7, 0xe5, 0xa1, 0x42, 0xb5, 0x56, 0xa0, 0x75, 0x01, 0x6d, + 0x3b, 0x34, 0xfd, 0xed, 0x44, 0x66, 0xc2, 0x85, 0x0a, 0xd5, 0x6a, 0x85, + 0x1f, 0x8b, 0xa7, 0x33, 0x23, 0xf2, 0x36, 0xb8, 0xf8, 0x5c, 0x27, 0xfa, + 0x5c, 0x07, 0x2f, 0x8e, 0x57, 0xc7, 0xfd, 0xae, 0x03, 0x57, 0x01, 0xab, + 0x82, 0xcf, 0x4b, 0x84, 0xc1, 0xe1, 0x58, 0xdf, 0x4a, 0xd1, 0xe9, 0x40, + 0x51, 0x87, 0x6c, 0xa3, 0x69, 0xb8, 0x76, 0xb0, 0xad, 0x51, 0xf8, 0x48, + 0x2a, 0xd2, 0xad, 0x2a, 0x9d, 0x5b, 0x04, 0x42, 0xe3, 0xfe, 0x97, 0x1c, + 0xfa, 0x5f, 0x20, 0xfa, 0x5c, 0x73, 0xe9, 0x7c, 0x83, 0xe9, 0x71, 0xcf, + 0xa5, 0xc7, 0xfd, 0x2f, 0x91, 0xfa, 0x5c, 0x7f, 0xd2, 0xe3, 0x85, 0xc7, + 0x6a, 0xe3, 0x35, 0x71, 0x1b, 0xed, 0x5e, 0x14, 0xa9, 0xef, 0x45, 0x27, + 0x14, 0x36, 0x7f, 0x68, 0x52, 0x68, 0x56, 0x81, 0xd9, 0x56, 0xa7, 0xc4, + 0x61, 0x6a, 0x70, 0xb4, 0xc1, 0xee, 0x21, 0x1e, 0x59, 0x13, 0xd9, 0x42, + 0xb5, 0x5a, 0xad, 0x0a, 0x07, 0x6b, 0x28, 0x3d, 0xde, 0xd7, 0x15, 0xc8, + 0x56, 0x42, 0xab, 0x4a, 0x0e, 0x07, 0xb6, 0x00, 0xbb, 0x44, 0xda, 0x1f, + 0xe4, 0x83, 0x43, 0x74, 0xed, 0xf6, 0xea, 0x76, 0xbe, 0x7d, 0xf7, 0x3a, + 0xa3, 0xba, 0x0a, 0xb1, 0xde, 0x97, 0x0d, 0xcb, 0x84, 0xe5, 0x63, 0x95, + 0xa7, 0xd2, 0xb4, 0xfa, 0x56, 0x95, 0x07, 0x2e, 0x0a, 0xb5, 0x5a, 0xa3, + 0xf0, 0x02, 0xa3, 0x82, 0x15, 0xbd, 0xa0, 0xe0, 0x74, 0xec, 0x99, 0x4a, + 0xe4, 0x1a, 0x06, 0x9d, 0xcf, 0xd4, 0x3f, 0xa9, 0xed, 0xa1, 0x42, 0xb5, + 0x40, 0x5c, 0xbd, 0x29, 0x57, 0x15, 0x25, 0x49, 0x52, 0xa4, 0xab, 0x8a, + 0xb8, 0xab, 0x8a, 0xb8, 0xab, 0x94, 0xfe, 0x97, 0xdb, 0xe9, 0x5a, 0xcf, + 0x4b, 0x86, 0xc4, 0x69, 0xfa, 0x5c, 0x32, 0xb8, 0x6a, 0xc0, 0xa0, 0x7e, + 0x18, 0x18, 0x4d, 0xac, 0x46, 0xa9, 0xae, 0x0e, 0xd3, 0x36, 0xe0, 0xa4, + 0x2a, 0x54, 0xee, 0xe6, 0x7b, 0x9b, 0x95, 0xcb, 0x6e, 0x32, 0xc1, 0xd9, + 0xda, 0xa3, 0xfd, 0x08, 0x12, 0x34, 0x42, 0xb1, 0x5c, 0x73, 0xe9, 0x71, + 0xdc, 0xb8, 0xce, 0x5c, 0x67, 0xae, 0x33, 0xd7, 0x1a, 0xa7, 0xb5, 0xc6, + 0x7f, 0xb5, 0xc6, 0x7a, 0xe3, 0x3d, 0x71, 0xdc, 0x9c, 0xe2, 0x4a, 0x95, + 0x2a, 0x8d, 0x67, 0x83, 0x08, 0x1c, 0xd9, 0x52, 0xa5, 0x4a, 0x95, 0x2a, + 0x54, 0xa9, 0x57, 0x2b, 0x95, 0xee, 0xf6, 0xb8, 0x8f, 0xf6, 0x8b, 0x9c, + 0x75, 0x3b, 0xa1, 0x42, 0x85, 0x6a, 0x8d, 0xd1, 0x91, 0x6a, 0x8f, 0xf5, + 0x22, 0x82, 0x0e, 0x2d, 0xe6, 0x13, 0x76, 0xba, 0xad, 0xf2, 0x9b, 0xb7, + 0x9f, 0xec, 0xd4, 0xdd, 0xb2, 0x8b, 0xbf, 0x49, 0xae, 0x6b, 0xba, 0x4c, + 0xe4, 0xca, 0x95, 0x28, 0xd6, 0x63, 0x75, 0x29, 0xdb, 0x65, 0x31, 0xa2, + 0x3b, 0x6f, 0xa0, 0x8e, 0xd7, 0x50, 0xaf, 0x93, 0x57, 0xda, 0xf9, 0x15, + 0x7d, 0xae, 0x3d, 0x4f, 0x6b, 0x8a, 0xf3, 0xe5, 0x5e, 0xef, 0x79, 0x51, + 0xba, 0x77, 0x42, 0x8d, 0xc0, 0x7e, 0x2a, 0x14, 0x28, 0x50, 0xa1, 0x42, + 0x85, 0x0a, 0x3f, 0x04, 0x31, 0x83, 0x09, 0x9b, 0x5d, 0x56, 0x79, 0x95, + 0x4f, 0x6f, 0x63, 0xba, 0xc4, 0x26, 0xb8, 0x3c, 0x4b, 0x4c, 0xef, 0x95, + 0x72, 0x7e, 0xd0, 0xc6, 0x6a, 0x53, 0xb6, 0xdf, 0xf1, 0x08, 0xed, 0x75, + 0x0e, 0x89, 0xcf, 0x73, 0xfa, 0x8f, 0xfa, 0x0c, 0x66, 0x47, 0xe0, 0x7c, + 0x65, 0x35, 0xee, 0x61, 0x96, 0x95, 0x4b, 0x6f, 0x3a, 0x54, 0x09, 0xdb, + 0x5d, 0x20, 0x24, 0x14, 0xfd, 0xb0, 0x9e, 0x90, 0x9d, 0x55, 0xef, 0xd4, + 0xff, 0x00, 0xa1, 0xc7, 0xe3, 0xce, 0x9f, 0x88, 0x3f, 0xeb, 0x07, 0x30, + 0x77, 0x64, 0xfe, 0x46, 0x54, 0xa9, 0x53, 0xbe, 0x54, 0xfe, 0x04, 0xe6, + 0xca, 0x95, 0x2a, 0x54, 0xf6, 0x44, 0xa9, 0x52, 0xa7, 0xfd, 0xf0, 0xfe, + 0x5a, 0x3f, 0x34, 0x3b, 0x03, 0xdf, 0x47, 0xe4, 0x61, 0x42, 0xb4, 0xab, + 0x4a, 0x85, 0x0a, 0xd5, 0x0a, 0x14, 0x77, 0x03, 0x3c, 0x9e, 0xe0, 0x35, + 0x72, 0x5c, 0x94, 0x8f, 0x2b, 0x92, 0x90, 0xae, 0x57, 0x2b, 0x8a, 0x95, + 0x21, 0x7d, 0xaa, 0x02, 0xb4, 0x2b, 0x51, 0x6f, 0x67, 0x1d, 0x80, 0x63, + 0x9d, 0xa0, 0x43, 0x66, 0xaa, 0x7f, 0xaa, 0xf8, 0xb5, 0xbf, 0xc5, 0x1a, + 0x4f, 0x67, 0x50, 0xdd, 0x72, 0x92, 0xa4, 0xa9, 0x38, 0xa4, 0xab, 0x95, + 0xcb, 0x92, 0x2d, 0x29, 0xad, 0xb9, 0x16, 0x10, 0xad, 0x76, 0x50, 0xa6, + 0xe7, 0x68, 0x10, 0xd9, 0x9c, 0xbe, 0x37, 0xed, 0x1a, 0x04, 0x79, 0x4e, + 0x69, 0x6e, 0xb8, 0x01, 0xcf, 0x3d, 0x9d, 0xa5, 0x5b, 0xfb, 0x50, 0xdf, + 0x68, 0xdb, 0xe1, 0x08, 0x84, 0x74, 0xce, 0x95, 0x70, 0x53, 0x2a, 0x14, + 0x23, 0x88, 0x34, 0x9d, 0x02, 0x14, 0x1e, 0x7c, 0x2f, 0x8e, 0x7c, 0x95, + 0xc1, 0x67, 0xb4, 0x19, 0x4f, 0xd2, 0xfb, 0x07, 0xf5, 0x57, 0x0f, 0xd2, + 0xbf, 0xf6, 0x8d, 0x40, 0x53, 0x6a, 0x80, 0xb8, 0xc7, 0xda, 0xe2, 0xff, + 0x00, 0xf1, 0x07, 0x83, 0xfd, 0x42, 0x3c, 0x3f, 0x2d, 0x56, 0xd1, 0x3e, + 0x0a, 0x34, 0xa9, 0xff, 0x00, 0x57, 0x2f, 0x8e, 0x7c, 0x14, 0x68, 0xd4, + 0x1e, 0x14, 0x61, 0xa5, 0xb0, 0xbd, 0xfc, 0xdf, 0xc9, 0x53, 0xd9, 0x69, + 0x53, 0xf0, 0xa3, 0x05, 0x5d, 0x8d, 0xaf, 0xe6, 0xde, 0x4a, 0xa5, 0x27, + 0x52, 0x30, 0xec, 0xd9, 0x53, 0xce, 0x51, 0x71, 0x2a, 0xe7, 0x04, 0x2a, + 0x18, 0xe6, 0xae, 0x61, 0xd4, 0x2b, 0x58, 0x74, 0x2b, 0x87, 0xe9, 0x16, + 0x11, 0xbd, 0xad, 0xbc, 0xc0, 0x4c, 0xa2, 0xd6, 0xe0, 0x28, 0xa7, 0xb3, + 0xc8, 0xde, 0x32, 0x8b, 0x4b, 0x75, 0xde, 0x1a, 0x5d, 0xa0, 0x44, 0x11, + 0xaa, 0x76, 0x5d, 0xc1, 0x5c, 0x0e, 0xfb, 0x7d, 0xae, 0x4b, 0xff, 0x00, + 0x17, 0x35, 0x6a, 0xb4, 0x20, 0x13, 0x94, 0x27, 0x66, 0x39, 0xf0, 0x8b, + 0x89, 0xc0, 0x1e, 0x42, 0x06, 0x77, 0x42, 0xb5, 0x0a, 0x0f, 0x28, 0x51, + 0x6f, 0x92, 0x83, 0x1a, 0x34, 0x6a, 0x73, 0xc8, 0xd4, 0xa2, 0xf5, 0x79, + 0x57, 0x1f, 0x7b, 0xf9, 0x61, 0x95, 0x46, 0x25, 0x3c, 0xc9, 0xdf, 0x28, + 0x3d, 0xc1, 0x71, 0x8f, 0x95, 0x34, 0x9d, 0xa8, 0x5c, 0x06, 0xbb, 0xa5, + 0xc8, 0xb2, 0x0c, 0x2a, 0x00, 0x71, 0x5b, 0x91, 0xb6, 0x36, 0x69, 0xce, + 0x6f, 0x8d, 0xf2, 0xa7, 0x00, 0x7b, 0x82, 0xbc, 0x1e, 0xa0, 0xac, 0x63, + 0xb4, 0x2a, 0x8d, 0x32, 0xd7, 0xf3, 0xc2, 0x51, 0x47, 0x78, 0xc9, 0x02, + 0x74, 0xc3, 0x2e, 0x1a, 0x15, 0x2e, 0xf6, 0xa7, 0xd8, 0x5f, 0x61, 0x56, + 0xb7, 0xda, 0xb0, 0xf8, 0x50, 0x46, 0x0a, 0x8f, 0xb0, 0x4a, 0x2e, 0x2e, + 0xd7, 0x7b, 0x5e, 0x5a, 0x99, 0x5a, 0xee, 0x45, 0x48, 0x57, 0x2b, 0xd0, + 0x33, 0xbb, 0x44, 0x5a, 0x88, 0xe4, 0x9b, 0xa2, 0x76, 0x63, 0xb5, 0xc5, + 0x4f, 0x5c, 0x12, 0x50, 0xaf, 0xe1, 0xc1, 0x02, 0xd7, 0x74, 0xa7, 0x09, + 0x47, 0x96, 0x5b, 0x3e, 0xd6, 0x93, 0x91, 0x3b, 0xa8, 0xff, 0x00, 0x23, + 0x72, 0x36, 0xaf, 0xe2, 0x39, 0xad, 0xd3, 0x26, 0x7d, 0x6e, 0xa1, 0x37, + 0x60, 0x28, 0xa2, 0x8a, 0xb4, 0x9d, 0x17, 0x0c, 0x8d, 0x79, 0x28, 0x60, + 0xf2, 0xa5, 0xbe, 0x02, 0x9c, 0x83, 0xba, 0x3d, 0x6e, 0x85, 0xcd, 0x41, + 0x56, 0xee, 0xe6, 0x83, 0x8a, 0xbb, 0xda, 0xfb, 0x55, 0xa3, 0xc1, 0x5b, + 0x40, 0x86, 0xe1, 0x66, 0xb8, 0x19, 0xa6, 0xe8, 0x51, 0x28, 0xc2, 0x1a, + 0x23, 0xae, 0x61, 0xc5, 0x4f, 0x5c, 0x30, 0xb4, 0xe6, 0x10, 0xad, 0xfe, + 0x48, 0xfd, 0xe3, 0x92, 0xb1, 0xca, 0xc2, 0xad, 0x1e, 0xd7, 0xda, 0xbe, + 0xc5, 0x2c, 0xf4, 0xa5, 0xbe, 0x94, 0xb7, 0xd2, 0x96, 0xfa, 0x52, 0xdf, + 0x48, 0xda, 0xbe, 0xd5, 0x0d, 0xf6, 0xac, 0xfd, 0xab, 0x08, 0xdc, 0x70, + 0x51, 0xfe, 0x46, 0xe4, 0x6d, 0x03, 0xfe, 0xb3, 0x9a, 0xc4, 0x72, 0xa8, + 0x6b, 0x84, 0xa2, 0x8a, 0x35, 0x0f, 0x9d, 0xd3, 0x86, 0x14, 0x28, 0x51, + 0xd8, 0x6d, 0x1a, 0x0c, 0x2d, 0xd7, 0x03, 0x4f, 0x25, 0x2a, 0xe4, 0x1d, + 0x1e, 0x53, 0x9c, 0x10, 0xec, 0xe9, 0x62, 0x85, 0x0b, 0x9b, 0x74, 0x57, + 0x93, 0xae, 0x48, 0x08, 0xe5, 0x52, 0xeb, 0x19, 0x15, 0xba, 0x0e, 0x6b, + 0x75, 0x4e, 0xdf, 0x7f, 0x28, 0x21, 0x1f, 0xd6, 0x2a, 0x1a, 0xe1, 0x28, + 0xa2, 0xa1, 0x40, 0xc7, 0x2a, 0x7b, 0x1d, 0xa3, 0xc6, 0x11, 0xae, 0x4f, + 0x8c, 0xc3, 0xa6, 0x3a, 0x58, 0xe3, 0x74, 0x28, 0x84, 0x21, 0x40, 0x50, + 0x11, 0x8d, 0xc3, 0xf5, 0xbb, 0x54, 0x74, 0x50, 0x89, 0xf5, 0x86, 0x37, + 0xd3, 0xeb, 0x19, 0x15, 0x3a, 0x4e, 0x6b, 0x35, 0x4e, 0xd7, 0x2b, 0x67, + 0xd7, 0x11, 0x47, 0xbb, 0xda, 0x3c, 0x6e, 0x1b, 0xc7, 0x6a, 0xed, 0x31, + 0xd2, 0xcd, 0x95, 0x2a, 0x42, 0x0e, 0x01, 0x5e, 0x15, 0xc1, 0x5c, 0x89, + 0x9c, 0x3c, 0xbc, 0xe0, 0x67, 0x50, 0xc8, 0x76, 0x88, 0xe6, 0x33, 0x54, + 0xed, 0x77, 0x47, 0x29, 0xc8, 0xa1, 0xae, 0x22, 0x8a, 0x3a, 0xf7, 0x5b, + 0x46, 0xa3, 0x70, 0xee, 0x1d, 0xa6, 0x3a, 0x79, 0x90, 0x8f, 0xb5, 0x2a, + 0x54, 0x95, 0x71, 0x4d, 0xe6, 0x61, 0x3b, 0x54, 0x30, 0xe8, 0xa7, 0x7b, + 0x75, 0xc8, 0x3a, 0x27, 0x6b, 0x98, 0xcd, 0x51, 0xd7, 0x78, 0xc7, 0x43, + 0x5c, 0x45, 0x14, 0x75, 0xee, 0xb6, 0x8e, 0xa1, 0xb8, 0x60, 0x1a, 0x76, + 0x8f, 0xd3, 0x1d, 0x2c, 0x98, 0xdd, 0x30, 0xae, 0x47, 0x90, 0xc2, 0xdd, + 0x55, 0x4e, 0xa2, 0x86, 0x22, 0xb5, 0xdc, 0x35, 0xc9, 0xa9, 0xd6, 0x73, + 0x18, 0x9d, 0xae, 0x55, 0x0d, 0x71, 0x14, 0x53, 0xb5, 0xee, 0xb6, 0x8e, + 0xac, 0x43, 0x4c, 0x87, 0x08, 0x24, 0x66, 0x3f, 0x4c, 0x74, 0xf1, 0x38, + 0xc0, 0x4d, 0x3c, 0xf7, 0x95, 0x12, 0xa2, 0x13, 0xba, 0x46, 0x2a, 0x9d, + 0x5b, 0xe5, 0x4a, 0x9d, 0xce, 0x28, 0x38, 0x85, 0xaa, 0x84, 0x32, 0x2a, + 0xf5, 0x9c, 0xc6, 0x27, 0x65, 0x50, 0xd7, 0x11, 0x45, 0x3b, 0x5e, 0xea, + 0xbf, 0x5e, 0x26, 0xe9, 0x8c, 0x6a, 0xaa, 0x7f, 0x97, 0xbc, 0xca, 0x9a, + 0x63, 0xa7, 0xa6, 0x27, 0x09, 0x41, 0xb1, 0x82, 0x37, 0x3f, 0x41, 0x88, + 0xf8, 0xdd, 0x0a, 0x14, 0x2b, 0x50, 0x09, 0xe3, 0x73, 0x74, 0xdc, 0x34, + 0xc8, 0xaf, 0xfc, 0x87, 0x31, 0x88, 0xe5, 0x50, 0xd7, 0x11, 0x45, 0x3b, + 0x5e, 0xea, 0xb7, 0x5e, 0x26, 0xe9, 0x8d, 0xba, 0xa2, 0x79, 0x66, 0x54, + 0xc7, 0x4f, 0x4c, 0xda, 0x9e, 0x31, 0x1d, 0x06, 0x29, 0xdd, 0xc3, 0xde, + 0xdd, 0x32, 0x36, 0x9f, 0xe5, 0x39, 0x8c, 0xd5, 0x3b, 0x2a, 0x86, 0xb8, + 0x8a, 0x29, 0xfa, 0xf7, 0x55, 0xba, 0xd0, 0xc2, 0xde, 0x9c, 0x03, 0x78, + 0x51, 0x39, 0x95, 0x31, 0xd3, 0xd3, 0x36, 0xa7, 0x8c, 0x07, 0x71, 0xe9, + 0x19, 0x03, 0x7b, 0x3a, 0x46, 0x46, 0xd5, 0xfc, 0xa7, 0x31, 0x9a, 0xa3, + 0x95, 0x43, 0xab, 0x19, 0x4f, 0xd7, 0xba, 0xad, 0xd6, 0x86, 0x16, 0x74, + 0xe3, 0x0b, 0xca, 0x3a, 0xe5, 0xd4, 0xc7, 0x4f, 0x4c, 0xda, 0x9b, 0xfc, + 0x6f, 0xfe, 0xa3, 0x28, 0xaa, 0x7d, 0x03, 0x23, 0x6a, 0xfe, 0x53, 0x98, + 0xd4, 0x72, 0xa8, 0x75, 0x6e, 0x38, 0x4a, 0x7e, 0xbd, 0xd5, 0x6e, 0xb4, + 0x30, 0xb3, 0xa7, 0x18, 0x47, 0x54, 0x72, 0xea, 0x63, 0xa7, 0xa6, 0x6d, + 0x4d, 0x77, 0xf8, 0xdf, 0xfd, 0x46, 0x51, 0x54, 0xba, 0x06, 0x46, 0xd1, + 0xfc, 0x87, 0x30, 0x68, 0x51, 0xca, 0xa3, 0xd5, 0xb8, 0xe1, 0x29, 0xfa, + 0xf7, 0x55, 0x7a, 0xce, 0x26, 0x74, 0xe3, 0x08, 0xea, 0x8e, 0x99, 0x75, + 0x31, 0xd3, 0xd3, 0x35, 0xfa, 0xef, 0xf1, 0xbc, 0x74, 0xe5, 0xd1, 0xfe, + 0x31, 0x8c, 0xaa, 0xff, 0x00, 0xc8, 0x73, 0x3c, 0x23, 0x95, 0x47, 0xab, + 0x19, 0x4f, 0xd7, 0xba, 0xab, 0xd6, 0x71, 0x33, 0xa4, 0x60, 0x8d, 0xe0, + 0x27, 0x6a, 0x86, 0x5d, 0x4c, 0x74, 0xf4, 0xcd, 0x38, 0x86, 0x87, 0x2e, + 0x87, 0xf1, 0x8c, 0x8a, 0xbd, 0x67, 0x33, 0xc2, 0x39, 0x54, 0x7a, 0xb1, + 0x94, 0xfd, 0x7b, 0xaa, 0x9d, 0x67, 0x13, 0x3a, 0x46, 0xf1, 0xbe, 0x14, + 0xc2, 0x26, 0x50, 0x47, 0x5c, 0xaa, 0x98, 0xd9, 0xa6, 0x7c, 0xa9, 0xde, + 0x32, 0xf6, 0x7f, 0xe2, 0x19, 0x0f, 0xea, 0x39, 0x87, 0x2e, 0x97, 0x56, + 0x45, 0x4d, 0x7b, 0xaa, 0x9d, 0x67, 0x13, 0x3a, 0x46, 0xfd, 0x37, 0x05, + 0xa2, 0xf3, 0xb8, 0x27, 0x65, 0x54, 0xc6, 0xcd, 0x3b, 0xed, 0x9b, 0xf8, + 0x86, 0x43, 0xb5, 0xcb, 0x89, 0x45, 0x6a, 0x9b, 0x4d, 0xcf, 0xe9, 0x44, + 0x16, 0xf2, 0x39, 0x14, 0xba, 0xb2, 0x2a, 0x6b, 0xdd, 0x54, 0xeb, 0x38, + 0x98, 0x7e, 0xd0, 0xa7, 0x70, 0xe7, 0xae, 0x0f, 0x3b, 0xf5, 0xca, 0xa9, + 0x8d, 0x9a, 0x66, 0x4a, 0x9e, 0xc7, 0x65, 0xfe, 0x21, 0x90, 0x73, 0x21, + 0x6a, 0x53, 0x45, 0x31, 0xfd, 0x95, 0x48, 0x9e, 0x48, 0xf0, 0xbc, 0x28, + 0x0a, 0xd5, 0x18, 0x29, 0xf5, 0x23, 0x8e, 0xa6, 0xb9, 0x92, 0x33, 0xaa, + 0xf5, 0x9c, 0x54, 0xfa, 0x42, 0x0b, 0x5c, 0x80, 0x88, 0xc9, 0xa9, 0xae, + 0x36, 0x69, 0xda, 0xce, 0x4e, 0xc7, 0xfc, 0x79, 0x0e, 0xd7, 0x3f, 0xc6, + 0xe8, 0xe5, 0x23, 0x74, 0x95, 0x7a, 0x91, 0xb9, 0x9d, 0x48, 0xe3, 0xa9, + 0xae, 0x54, 0xa9, 0x1b, 0x98, 0xf2, 0xc2, 0x83, 0xda, 0xed, 0x33, 0x2a, + 0xf5, 0x9c, 0x54, 0xba, 0x46, 0xf2, 0x40, 0xd5, 0x48, 0x38, 0x26, 0x77, + 0x83, 0x22, 0xdc, 0x31, 0x81, 0xfa, 0xe3, 0x6e, 0x98, 0xa5, 0x4f, 0x63, + 0x2a, 0x70, 0xec, 0x5f, 0xc7, 0x90, 0xfe, 0xa3, 0x94, 0x07, 0x9c, 0x61, + 0x11, 0xba, 0x37, 0xb3, 0xa9, 0x1c, 0x75, 0x35, 0xc6, 0x4c, 0x09, 0x46, + 0xa3, 0x9d, 0xe7, 0x03, 0x29, 0x97, 0xa7, 0xd3, 0x2c, 0xd7, 0x70, 0xaa, + 0xe6, 0xa1, 0xb4, 0x7b, 0x42, 0xa3, 0x4f, 0x9c, 0x9a, 0xbd, 0x67, 0x15, + 0x3e, 0x95, 0x2b, 0x8a, 0xd5, 0x55, 0xd7, 0x3b, 0x70, 0x7b, 0x82, 0xe2, + 0x3b, 0xda, 0x92, 0x75, 0x4d, 0x71, 0x6e, 0x88, 0xbe, 0xed, 0xcc, 0xaa, + 0x69, 0x99, 0x4f, 0xae, 0xca, 0x9e, 0x15, 0xc3, 0x7f, 0x3c, 0x0f, 0xd7, + 0x1b, 0x74, 0xc5, 0x4e, 0x8d, 0x4a, 0xbd, 0x01, 0x3b, 0xe9, 0xb5, 0x80, + 0x90, 0x9f, 0xb3, 0xd5, 0xa7, 0xd4, 0xdc, 0x14, 0xdb, 0x71, 0x87, 0x82, + 0x3f, 0xf1, 0x3a, 0x98, 0x1e, 0x73, 0xa5, 0x4a, 0x95, 0xb0, 0xf4, 0x1c, + 0x8a, 0xbd, 0x67, 0x1d, 0x8a, 0x37, 0x13, 0x82, 0xc3, 0xaa, 0x3b, 0x86, + 0x09, 0x52, 0xa9, 0xf5, 0x04, 0x71, 0xd4, 0xd7, 0x1d, 0x63, 0x0d, 0x8c, + 0x37, 0xb9, 0xbc, 0x82, 0x2e, 0x27, 0x5c, 0x21, 0xc4, 0x68, 0x85, 0x77, + 0x04, 0x36, 0x8f, 0x61, 0x0a, 0xec, 0x5c, 0x46, 0xfb, 0x53, 0xbe, 0xaf, + 0x59, 0xc5, 0x7b, 0x80, 0x80, 0xa4, 0x9d, 0xfc, 0x27, 0x44, 0xe0, 0x0c, + 0x23, 0x99, 0xc7, 0x25, 0x5c, 0x55, 0xe5, 0x5e, 0x55, 0xe8, 0xeb, 0x8e, + 0xe2, 0x10, 0x7f, 0xb5, 0x29, 0xce, 0x85, 0x7a, 0xbc, 0x2d, 0x98, 0xb5, + 0x94, 0xc3, 0x42, 0xb9, 0x4a, 0x75, 0x2a, 0x6f, 0xea, 0x09, 0xdb, 0x05, + 0x07, 0x78, 0x84, 0x7e, 0x96, 0xdf, 0xea, 0xe5, 0x57, 0x65, 0xaa, 0x7a, + 0x1c, 0xaa, 0x6c, 0x5b, 0x50, 0x7c, 0xdb, 0x3f, 0xb4, 0x76, 0x7a, 0xad, + 0xd5, 0xa5, 0x6c, 0x3b, 0x13, 0x2a, 0xb4, 0xba, 0xa8, 0x47, 0xe9, 0xbb, + 0x39, 0xf0, 0xbf, 0xe2, 0xe8, 0x7b, 0x29, 0xdf, 0x49, 0xe7, 0xc9, 0xc8, + 0x7d, 0x27, 0xdb, 0xd0, 0xfa, 0x76, 0xce, 0x3c, 0x26, 0xec, 0xd4, 0x59, + 0xa3, 0x55, 0x8d, 0xf4, 0xb6, 0xc6, 0xbd, 0xb5, 0x48, 0x76, 0xe0, 0xc7, + 0x1d, 0x02, 0x1b, 0x3d, 0x53, 0xfd, 0x50, 0xd8, 0xab, 0x7a, 0x44, 0x41, + 0x83, 0xbb, 0xe9, 0xfd, 0x07, 0x22, 0xbf, 0x2a, 0x8e, 0xc3, 0x08, 0x29, + 0x52, 0x89, 0x94, 0xd6, 0x39, 0xda, 0x04, 0xcd, 0x85, 0xee, 0xea, 0xe4, + 0xaa, 0xec, 0x36, 0x32, 0x5a, 0x53, 0x5b, 0x3b, 0x9c, 0x84, 0xb7, 0xc2, + 0x69, 0x05, 0x01, 0x08, 0xb0, 0x14, 0x69, 0x7a, 0x5c, 0x37, 0x2b, 0x48, + 0x4c, 0xea, 0x08, 0xe3, 0xa9, 0xae, 0x08, 0x42, 0x9b, 0x8a, 0x14, 0x7d, + 0xa7, 0xec, 0xec, 0x7e, 0xaa, 0xb5, 0x2e, 0x13, 0xa3, 0x04, 0x65, 0xca, + 0xbc, 0xae, 0x23, 0xbd, 0xa9, 0x9c, 0x43, 0x05, 0xc7, 0x70, 0x67, 0xb4, + 0x00, 0x1a, 0x29, 0x27, 0xb3, 0x3b, 0xf5, 0x45, 0x84, 0x6e, 0x65, 0x67, + 0xd3, 0xe9, 0x2a, 0x9f, 0xd4, 0x08, 0xeb, 0x0a, 0x9e, 0xdb, 0x4d, 0xfe, + 0x50, 0xa9, 0x2a, 0xf5, 0x72, 0x95, 0x2a, 0x54, 0xa9, 0xc6, 0xe6, 0x35, + 0xda, 0x85, 0x63, 0x46, 0x83, 0x79, 0x13, 0xc8, 0xaa, 0x9b, 0x04, 0xba, + 0x58, 0x86, 0xc1, 0x4c, 0x8e, 0x7a, 0xaa, 0x1b, 0x38, 0xa1, 0x30, 0x72, + 0x36, 0x91, 0xff, 0x00, 0x69, 0xdf, 0x69, 0x3e, 0x10, 0xa5, 0x50, 0xe8, + 0xd4, 0x36, 0x5a, 0xc7, 0xc2, 0x1b, 0x15, 0x62, 0x87, 0xd3, 0xcf, 0xf6, + 0x72, 0x6e, 0xc1, 0x4c, 0x6a, 0x85, 0x0a, 0x54, 0xf9, 0xc2, 0x9a, 0x95, + 0xcc, 0x33, 0x90, 0x5c, 0x1d, 0xa1, 0x9d, 0x0f, 0x5f, 0xfe, 0xc1, 0xe9, + 0x39, 0x95, 0x43, 0xba, 0x53, 0x99, 0x58, 0x78, 0x46, 0x54, 0x22, 0xc0, + 0x54, 0xb9, 0xa8, 0x3c, 0x79, 0xc1, 0x08, 0xe3, 0x75, 0x3b, 0x8a, 0xe0, + 0xa1, 0x49, 0xab, 0x86, 0xd0, 0xa3, 0x06, 0xd1, 0x4b, 0x88, 0xce, 0x5a, + 0xe0, 0xff, 0x00, 0xe6, 0xf8, 0xec, 0x6e, 0x57, 0x29, 0xde, 0xd7, 0x42, + 0x0e, 0x07, 0xb9, 0xbc, 0x8e, 0x58, 0x01, 0x4d, 0xa8, 0xe1, 0xa1, 0x4d, + 0xda, 0xea, 0x04, 0xdd, 0xbb, 0xd8, 0x4d, 0xdb, 0x29, 0x94, 0xda, 0xcd, + 0x76, 0x85, 0x07, 0x66, 0xc6, 0xe2, 0x32, 0x78, 0x6c, 0x3c, 0xc8, 0x5c, + 0x36, 0x0f, 0x0a, 0x00, 0xc7, 0x55, 0xe6, 0xb3, 0xb8, 0x6d, 0x4c, 0x01, + 0x82, 0x02, 0x95, 0x76, 0xfd, 0xa0, 0x53, 0x99, 0xf2, 0xa4, 0x28, 0x50, + 0x8b, 0x01, 0x44, 0x16, 0x73, 0x09, 0xae, 0xbb, 0x79, 0xca, 0x9c, 0x2e, + 0x98, 0xe4, 0xaa, 0xd1, 0x11, 0x38, 0x2e, 0x2a, 0xe5, 0x76, 0xe8, 0x50, + 0xa1, 0x46, 0x58, 0x05, 0x1a, 0x64, 0x09, 0x38, 0xc1, 0x21, 0x0a, 0x85, + 0x0a, 0x81, 0x4c, 0xf7, 0x4d, 0x32, 0x30, 0x4a, 0xd8, 0xcb, 0xdf, 0x54, + 0x09, 0x40, 0x46, 0x2f, 0xfc, 0x5f, 0xf9, 0xbd, 0xc0, 0x9d, 0x0a, 0x1c, + 0xbb, 0x47, 0x36, 0xe1, 0x09, 0x94, 0x43, 0x34, 0x51, 0xb8, 0x90, 0x35, + 0x4e, 0xda, 0x18, 0x34, 0x4e, 0xda, 0x1c, 0xed, 0x11, 0x3b, 0xcb, 0xa3, + 0x54, 0x1c, 0xd7, 0x68, 0xa1, 0x1f, 0xb1, 0xc8, 0x73, 0x50, 0x8e, 0x28, + 0x47, 0x26, 0x25, 0x6d, 0x3b, 0x35, 0xa2, 0xf6, 0x62, 0xa6, 0xfb, 0x0a, + 0xb1, 0xa5, 0x1a, 0x43, 0xc2, 0x34, 0x4a, 0x34, 0xdc, 0xad, 0x2a, 0xc5, + 0x61, 0x56, 0x3b, 0xd2, 0xe1, 0xbb, 0xd2, 0xe0, 0xbf, 0xd2, 0x14, 0x1c, + 0x86, 0xcc, 0x7d, 0xa1, 0xb3, 0x84, 0x28, 0xb0, 0x22, 0x43, 0x04, 0xa7, + 0xbc, 0xbc, 0xe5, 0xc5, 0xc2, 0x55, 0xa5, 0x47, 0x6e, 0xc3, 0x87, 0xe9, + 0xcc, 0xd5, 0xf9, 0xa3, 0x69, 0xa6, 0x4d, 0xa4, 0xc1, 0xde, 0x51, 0xec, + 0x5f, 0x51, 0xac, 0xea, 0x29, 0xfb, 0x4d, 0xdd, 0x05, 0x49, 0x38, 0xaa, + 0x69, 0xb8, 0x3d, 0xc1, 0x39, 0xf7, 0x0e, 0x6a, 0x93, 0xbf, 0xae, 0xe3, + 0x82, 0x14, 0x28, 0x47, 0x20, 0xb9, 0xad, 0xd4, 0xa3, 0xb4, 0xd2, 0x6f, + 0x94, 0x76, 0xda, 0x67, 0x94, 0x27, 0xdb, 0x3f, 0x6e, 0x98, 0xa8, 0xd4, + 0xfe, 0xa7, 0x34, 0x9b, 0x44, 0x94, 0xf7, 0x97, 0x9c, 0xca, 0x67, 0x96, + 0xf8, 0x0a, 0xc0, 0xac, 0x56, 0x15, 0x69, 0x56, 0x95, 0x05, 0x73, 0x5c, + 0xd4, 0x15, 0x6b, 0x95, 0x85, 0x70, 0xd3, 0xa0, 0x64, 0xb3, 0x5c, 0x3b, + 0x3d, 0x3e, 0x1d, 0x30, 0xdc, 0xdd, 0xa3, 0x66, 0x6d, 0x71, 0xfb, 0x45, + 0xd5, 0xb6, 0x63, 0x6c, 0xc2, 0x67, 0xd4, 0x2a, 0x0e, 0xae, 0x6a, 0x9e, + 0xda, 0x2b, 0x1b, 0x61, 0x4a, 0x95, 0x38, 0x00, 0x51, 0x84, 0xbd, 0x8d, + 0xd4, 0xa7, 0x6d, 0x54, 0x5b, 0xfd, 0x93, 0xb6, 0xfa, 0x63, 0x44, 0xef, + 0xa8, 0x3b, 0xfa, 0x84, 0xed, 0xaa, 0xab, 0xfc, 0xa0, 0x0b, 0xca, 0x02, + 0x31, 0xd4, 0xd3, 0x08, 0x71, 0xf0, 0xb8, 0x83, 0xca, 0xe2, 0x05, 0xc4, + 0x08, 0x55, 0x62, 0xe2, 0xb7, 0xda, 0xe2, 0x37, 0xda, 0xe2, 0x37, 0xda, + 0xbd, 0xbe, 0xd5, 0xed, 0xf6, 0xb8, 0x8d, 0xf6, 0xb8, 0xac, 0x5c, 0x66, + 0xae, 0x3f, 0xe9, 0x56, 0xda, 0xde, 0x0c, 0x35, 0x3a, 0xb5, 0x47, 0x6a, + 0x72, 0xb4, 0x54, 0xdf, 0x7b, 0x72, 0xc9, 0x0d, 0x12, 0x55, 0x4a, 0x97, + 0x9c, 0xda, 0x79, 0xee, 0x77, 0x8c, 0xa1, 0x83, 0x66, 0x65, 0xf5, 0x40, + 0x43, 0x3a, 0xa5, 0x26, 0x56, 0x10, 0xf5, 0xb4, 0x6c, 0x8f, 0xa3, 0xcc, + 0x73, 0x08, 0x38, 0xb4, 0xc8, 0x43, 0x6a, 0xab, 0xed, 0x7c, 0xaa, 0x9e, + 0xd7, 0xc9, 0xa9, 0xed, 0x7c, 0x8a, 0x9e, 0xd0, 0xda, 0x2a, 0x0f, 0x2b, + 0xe6, 0x55, 0xf6, 0xbe, 0x6d, 0x6f, 0x6b, 0xe7, 0x56, 0xf6, 0xbe, 0x6d, + 0x6f, 0x6b, 0xe6, 0xd6, 0xf6, 0xbe, 0x5d, 0x6f, 0xf2, 0x4e, 0xad, 0x51, + 0xfd, 0x47, 0x0b, 0x5a, 0x5c, 0x80, 0xb4, 0x64, 0x55, 0xec, 0x9e, 0xeb, + 0x44, 0xa2, 0x67, 0x32, 0x9b, 0xec, 0x39, 0x44, 0x86, 0x89, 0x2a, 0xa3, + 0xcb, 0xce, 0x75, 0x3d, 0x33, 0x9c, 0xe8, 0xcc, 0x69, 0xe5, 0xbf, 0xe9, + 0xf4, 0xf9, 0x97, 0xa1, 0x9f, 0xaa, 0xda, 0x36, 0x06, 0xbb, 0xee, 0xa7, + 0xc9, 0x3d, 0x8e, 0xa6, 0x61, 0xc3, 0x7c, 0xe6, 0x32, 0x9d, 0xc8, 0x00, + 0x34, 0xc9, 0x71, 0x93, 0x8a, 0x73, 0x2b, 0x3e, 0xe3, 0x03, 0x3a, 0x85, + 0x4f, 0xea, 0x72, 0x1e, 0xf0, 0xcd, 0x53, 0xde, 0x5e, 0x73, 0xe9, 0x1f, + 0x19, 0xae, 0x74, 0x66, 0xb3, 0x5d, 0xfb, 0x25, 0x3e, 0x1d, 0x20, 0x3b, + 0x2a, 0x94, 0x99, 0x54, 0x43, 0x82, 0xad, 0xb0, 0x39, 0xbc, 0xe9, 0xf3, + 0x44, 0x11, 0xc8, 0xe5, 0x81, 0x29, 0x94, 0xa3, 0x5c, 0xa7, 0x18, 0x1d, + 0x95, 0x57, 0xda, 0x3b, 0x0a, 0x55, 0xa7, 0x93, 0xb1, 0x3e, 0xbf, 0x86, + 0xa2, 0x67, 0x5e, 0xc2, 0x99, 0x87, 0x66, 0x39, 0xfe, 0xb3, 0x82, 0xd5, + 0x6c, 0xf4, 0xb8, 0xb5, 0x00, 0x40, 0x76, 0x95, 0x76, 0x7a, 0x75, 0x7a, + 0x82, 0xab, 0xf4, 0xf7, 0x37, 0x9b, 0x39, 0xa7, 0x31, 0xcc, 0xe4, 0xe1, + 0x90, 0xda, 0x44, 0xea, 0x83, 0x43, 0x74, 0xcb, 0xaa, 0x7b, 0x17, 0x1b, + 0x44, 0x94, 0xe7, 0x5c, 0x64, 0xf6, 0x34, 0xeb, 0xc7, 0x27, 0x20, 0x41, + 0xe6, 0x37, 0x3e, 0xa8, 0x62, 0x7d, 0x42, 0xfd, 0x7b, 0x29, 0x40, 0xc8, + 0xc9, 0x26, 0x11, 0x74, 0xf6, 0x0c, 0x3e, 0x16, 0xc5, 0x47, 0x86, 0xc9, + 0x3a, 0x9e, 0xdd, 0xcc, 0x6b, 0x84, 0x10, 0xaa, 0x7d, 0x3e, 0x9b, 0xba, + 0x79, 0x27, 0xec, 0x15, 0x5b, 0xa7, 0x34, 0xe6, 0x39, 0x9d, 0x43, 0x70, + 0x63, 0x8a, 0x14, 0x7d, 0xa0, 0xd0, 0xdd, 0x33, 0x6a, 0x1e, 0x7d, 0x8d, + 0x47, 0xdd, 0xd9, 0xb5, 0xe5, 0x9a, 0x27, 0x56, 0x2e, 0xed, 0x68, 0xbb, + 0xc6, 0x39, 0x45, 0xfe, 0x94, 0xcf, 0x63, 0xb0, 0x6c, 0xfc, 0x57, 0xde, + 0xed, 0x02, 0x1d, 0xc1, 0x7b, 0x5b, 0xa9, 0x4e, 0xda, 0x58, 0x34, 0x4f, + 0xda, 0x0b, 0xb9, 0x42, 0x81, 0xae, 0x79, 0x47, 0x5e, 0xc2, 0xa5, 0x4b, + 0xb9, 0x0f, 0xc5, 0x34, 0xda, 0x65, 0x34, 0xdc, 0x27, 0x04, 0x80, 0x8b, + 0xfd, 0x29, 0x9e, 0xca, 0x95, 0x33, 0x55, 0xc1, 0x8d, 0x54, 0x69, 0x0a, + 0x4c, 0x0d, 0x1d, 0xbb, 0xf6, 0xa6, 0xb7, 0xa5, 0x3e, 0xb3, 0xdf, 0xaa, + 0x9e, 0xca, 0xa1, 0x81, 0x9f, 0x30, 0xaa, 0x54, 0xbb, 0x90, 0xfc, 0x65, + 0x37, 0xda, 0xae, 0x08, 0xbd, 0x17, 0x13, 0xda, 0xec, 0x1b, 0x37, 0x09, + 0xb7, 0xbb, 0x53, 0xdc, 0x56, 0xd9, 0xc3, 0xf9, 0x8d, 0x53, 0x9a, 0x5a, + 0x60, 0xf6, 0x6e, 0x32, 0x73, 0x89, 0x84, 0xf7, 0x97, 0x66, 0x70, 0x1c, + 0x8d, 0x27, 0x0f, 0x0a, 0x3b, 0xcb, 0x08, 0xd7, 0x03, 0x6e, 0x1d, 0xac, + 0x4a, 0xd8, 0xf6, 0x13, 0xd7, 0x55, 0x01, 0xdb, 0xca, 0x95, 0x52, 0x9b, + 0x6a, 0x6a, 0xaa, 0x6c, 0xee, 0x66, 0x9d, 0x8b, 0xdf, 0xe0, 0x66, 0x92, + 0x06, 0xbb, 0xdc, 0xc6, 0xbb, 0x54, 0xed, 0x9f, 0xd2, 0x34, 0xdc, 0xdd, + 0x72, 0x03, 0x49, 0xd1, 0x70, 0x9c, 0x87, 0x24, 0xf6, 0x82, 0x88, 0x3d, + 0xa0, 0x2a, 0x7f, 0x4a, 0x47, 0xa5, 0x23, 0xd2, 0xe4, 0xb9, 0x26, 0xd1, + 0x9d, 0x50, 0x60, 0x6e, 0x89, 0xcd, 0x5c, 0x35, 0x62, 0xb1, 0x58, 0x15, + 0xa1, 0x5a, 0x15, 0xa1, 0x43, 0x55, 0xa1, 0x16, 0x85, 0x03, 0x36, 0x8e, + 0xcd, 0x52, 0xb7, 0x48, 0x5b, 0x3e, 0xc4, 0xca, 0x3c, 0xf5, 0x28, 0x0e, + 0xea, 0x51, 0x30, 0x15, 0x6a, 0xe0, 0x98, 0xb6, 0x0a, 0x2e, 0x71, 0x5f, + 0x72, 0xb8, 0xfb, 0x42, 0xa4, 0x6a, 0x50, 0xaa, 0x3d, 0xa0, 0xf0, 0x54, + 0xe4, 0x3d, 0xfe, 0x06, 0x61, 0x7b, 0x5b, 0xaa, 0x75, 0x7f, 0x48, 0xb8, + 0x9d, 0x55, 0x07, 0xdc, 0x2d, 0x38, 0x4b, 0x1a, 0x75, 0x46, 0x80, 0xf0, + 0x8d, 0x07, 0x78, 0x46, 0x9b, 0x87, 0x85, 0x0a, 0x15, 0x36, 0x0f, 0x2b, + 0xff, 0x00, 0x9b, 0xa0, 0xa8, 0x72, 0xb4, 0x94, 0x69, 0x2e, 0x0a, 0x34, + 0x0a, 0x34, 0xdc, 0x3b, 0x60, 0x48, 0xd1, 0x36, 0xb3, 0x94, 0xce, 0xe8, + 0x51, 0x86, 0x14, 0x23, 0x28, 0xce, 0x50, 0x04, 0xe8, 0xa9, 0xec, 0x35, + 0xaa, 0x78, 0x85, 0x47, 0xe9, 0xd4, 0xd9, 0xcd, 0xdc, 0xd0, 0x68, 0x1d, + 0xed, 0x4a, 0xd4, 0xe9, 0xea, 0x55, 0x5a, 0x8c, 0xab, 0xe1, 0x39, 0xde, + 0x95, 0x84, 0xea, 0xac, 0x56, 0x2b, 0x14, 0x20, 0x61, 0x71, 0x17, 0x11, + 0x71, 0x4f, 0x84, 0x2a, 0x9f, 0x2b, 0x88, 0x15, 0xe1, 0x17, 0x17, 0x72, + 0x0a, 0xc2, 0xa1, 0x42, 0xb5, 0x5b, 0x80, 0xb8, 0x04, 0x6a, 0xb4, 0x23, + 0x5f, 0xd0, 0x46, 0xa3, 0x8e, 0x06, 0x9b, 0x4c, 0xa6, 0xba, 0xf1, 0x39, + 0x10, 0xad, 0x0a, 0xd5, 0x0a, 0x31, 0xc2, 0x2d, 0x05, 0x1a, 0x4d, 0x46, + 0x80, 0x46, 0x81, 0xf0, 0x8d, 0x37, 0x05, 0x19, 0xb0, 0x55, 0x8e, 0xf4, + 0xb8, 0x6f, 0xf4, 0xb8, 0x2f, 0xf4, 0x85, 0x22, 0x35, 0x40, 0x65, 0xc2, + 0x2c, 0x45, 0x87, 0x15, 0x2d, 0x98, 0x54, 0xd5, 0xe0, 0x2a, 0x7f, 0x4e, + 0xa3, 0xe4, 0xca, 0xa7, 0x42, 0x9d, 0x3e, 0x90, 0xa3, 0xb9, 0xfb, 0xa7, + 0x5d, 0xc5, 0xed, 0x6e, 0xa5, 0x3b, 0x6d, 0xa2, 0xdf, 0x28, 0xed, 0xaf, + 0x77, 0x43, 0x53, 0x9f, 0x51, 0xfd, 0x6e, 0x4f, 0x20, 0x68, 0xaf, 0x2a, + 0x4a, 0x97, 0x29, 0x72, 0xfb, 0x97, 0x35, 0x0a, 0x02, 0x81, 0xbe, 0x77, + 0x04, 0x1e, 0xa7, 0x7c, 0x84, 0x5c, 0xa5, 0x55, 0xa9, 0x1c, 0x82, 0x2e, + 0x27, 0x26, 0x9b, 0xad, 0x28, 0x7d, 0xdd, 0xc1, 0x68, 0x28, 0xd0, 0x69, + 0x46, 0x81, 0xf0, 0x8d, 0x37, 0x0f, 0x0a, 0x23, 0x73, 0x69, 0xb9, 0xc8, + 0x51, 0x1e, 0x57, 0x09, 0xbe, 0x97, 0x0d, 0xbe, 0x95, 0xad, 0x1e, 0x14, + 0x63, 0x21, 0x44, 0xa8, 0x50, 0xa3, 0x1c, 0x6f, 0x2d, 0x0e, 0x08, 0x88, + 0xc2, 0x1e, 0xe6, 0xe8, 0x53, 0x76, 0xba, 0xcd, 0xd1, 0xc9, 0xbf, 0x51, + 0xae, 0x13, 0x7e, 0xa6, 0xff, 0x00, 0x2d, 0x43, 0xea, 0x4d, 0xf2, 0xd5, + 0xff, 0x00, 0x21, 0x49, 0x1f, 0xa9, 0x37, 0xc3, 0x51, 0xfa, 0x8b, 0xfc, + 0x04, 0x7e, 0xa1, 0x55, 0x7c, 0xea, 0xde, 0xd7, 0xcd, 0xad, 0xed, 0x7c, + 0xea, 0xde, 0xd7, 0xcf, 0xad, 0xed, 0x7c, 0xfa, 0xcb, 0xe7, 0xd6, 0x5f, + 0xf2, 0x15, 0x97, 0xfc, 0x85, 0x55, 0xff, 0x00, 0x21, 0x55, 0x7c, 0xaa, + 0xbe, 0xd7, 0xca, 0xab, 0xed, 0x7c, 0x9a, 0x9f, 0xe4, 0xbe, 0x43, 0xff, + 0x00, 0xc8, 0xae, 0x2b, 0x8f, 0xf6, 0x2a, 0x86, 0xda, 0xd6, 0xb6, 0x1e, + 0xbe, 0x6d, 0x1f, 0x68, 0xfd, 0x41, 0x83, 0x40, 0x9d, 0xf5, 0x23, 0xe1, + 0xa9, 0xdf, 0x50, 0xac, 0x74, 0x47, 0x68, 0xad, 0x53, 0xfb, 0x2f, 0xb7, + 0xfb, 0x19, 0x42, 0xab, 0x5b, 0xd2, 0x11, 0xae, 0x51, 0xa9, 0x2a, 0xe9, + 0x52, 0x54, 0x38, 0xa2, 0x08, 0xd5, 0x4a, 0x9c, 0x7c, 0xf2, 0x0f, 0xe9, + 0x3d, 0xee, 0x1e, 0x11, 0xc6, 0x1a, 0x4e, 0x88, 0x50, 0x71, 0xd5, 0x0a, + 0x0d, 0x1a, 0xa0, 0xc0, 0x34, 0xef, 0x21, 0x40, 0x5c, 0x36, 0xfa, 0x51, + 0x98, 0x50, 0xca, 0x94, 0x08, 0x56, 0x85, 0x6f, 0xa4, 0xe6, 0x17, 0x2e, + 0x1a, 0xb0, 0x2b, 0x42, 0xb4, 0x28, 0x19, 0x77, 0x2b, 0x94, 0xa9, 0x52, + 0xae, 0x52, 0x55, 0xca, 0x70, 0xce, 0xee, 0x6a, 0x54, 0xee, 0xd5, 0x0a, + 0x6e, 0x28, 0x50, 0x3e, 0x55, 0x8c, 0x6e, 0xa8, 0xd5, 0x03, 0x40, 0x9d, + 0x51, 0xc7, 0x14, 0x28, 0x50, 0xa1, 0x14, 0x32, 0x4d, 0x36, 0x9f, 0x08, + 0xd0, 0x0b, 0xe3, 0xfe, 0xd7, 0xc7, 0xfd, 0xaf, 0x8f, 0xfb, 0x42, 0x83, + 0x50, 0x63, 0x42, 0xe4, 0xb9, 0x7e, 0x02, 0x54, 0xef, 0x8c, 0x92, 0x86, + 0x09, 0x53, 0x8a, 0x0a, 0x82, 0xa4, 0xab, 0xd7, 0x11, 0x5c, 0x3d, 0x2b, + 0x9b, 0xe9, 0x5c, 0xdf, 0x4a, 0xec, 0x13, 0x83, 0x4d, 0xd0, 0xad, 0x56, + 0xa8, 0x2a, 0x0a, 0xb4, 0xab, 0x4a, 0xb4, 0xab, 0x55, 0xbb, 0xa1, 0x42, + 0x6c, 0x79, 0x5f, 0xf5, 0x28, 0xa6, 0xad, 0x6f, 0xb5, 0x0d, 0xf6, 0xbe, + 0xc5, 0x7b, 0x02, 0xe3, 0x00, 0xb8, 0xe5, 0x1a, 0xae, 0x57, 0x12, 0xa7, + 0x0c, 0x62, 0x28, 0x66, 0x72, 0x52, 0x17, 0x25, 0x0a, 0x3b, 0x89, 0x53, + 0xbb, 0xff, 0x00, 0x57, 0xfe, 0xee, 0x80, 0xa0, 0x76, 0x03, 0x32, 0x55, + 0xca, 0xe5, 0x21, 0x48, 0x5c, 0x97, 0x25, 0xc9, 0x40, 0x50, 0xa1, 0x42, + 0xb5, 0x42, 0xb5, 0x5a, 0xad, 0x2a, 0xd2, 0xa0, 0xab, 0x4a, 0xb4, 0xab, + 0x4a, 0xb4, 0xab, 0x4a, 0xb4, 0xab, 0x4a, 0xb4, 0xab, 0x4a, 0xb5, 0x5a, + 0xad, 0x50, 0xa1, 0x72, 0x5c, 0xb2, 0xe5, 0x4f, 0x65, 0x38, 0xa5, 0x73, + 0x52, 0x54, 0xa9, 0x53, 0xf8, 0x49, 0x53, 0x9b, 0x0a, 0x14, 0x28, 0x50, + 0xa1, 0x42, 0x85, 0x0a, 0x14, 0x6f, 0x85, 0x18, 0x23, 0x32, 0x37, 0x42, + 0x85, 0x1b, 0xa1, 0x42, 0x85, 0x0a, 0x14, 0x28, 0x50, 0xa1, 0x42, 0x8c, + 0xe9, 0xef, 0x3f, 0xff, 0xc4, 0x00, 0x38, 0x11, 0x00, 0x01, 0x03, 0x01, + 0x06, 0x04, 0x04, 0x05, 0x03, 0x04, 0x02, 0x03, 0x01, 0x00, 0x00, 0x00, + 0x01, 0x00, 0x02, 0x11, 0x03, 0x04, 0x10, 0x12, 0x20, 0x21, 0x31, 0x13, + 0x30, 0x41, 0x51, 0x05, 0x32, 0x40, 0x52, 0x14, 0x22, 0x33, 0x42, 0x61, + 0x15, 0x50, 0x71, 0x23, 0x60, 0x81, 0xa1, 0x62, 0x91, 0x24, 0xb1, 0xf0, + 0xd1, 0xff, 0xda, 0x00, 0x08, 0x01, 0x02, 0x01, 0x01, 0x3f, 0x01, 0xfd, + 0xd6, 0x14, 0x28, 0x50, 0xa1, 0x42, 0x85, 0x0a, 0x14, 0x2a, 0x95, 0xdb, + 0x4f, 0x75, 0xf1, 0xf4, 0x97, 0xc7, 0xd2, 0x4e, 0xf1, 0x11, 0xd0, 0x2f, + 0xd4, 0x5d, 0xd0, 0x23, 0x6f, 0xab, 0xd9, 0x7c, 0x75, 0x72, 0x8d, 0xb2, + 0xbf, 0x75, 0xf1, 0x76, 0x8e, 0xeb, 0xe2, 0xad, 0x1e, 0xe5, 0xf1, 0x36, + 0x8f, 0x72, 0xf8, 0x8a, 0xfe, 0xe5, 0xf1, 0x35, 0xbd, 0xcb, 0x8d, 0x5b, + 0xdc, 0xb8, 0xd5, 0x7d, 0xc5, 0x71, 0xaa, 0xfb, 0x8a, 0xe3, 0x55, 0xf7, + 0x7f, 0xb5, 0xc5, 0xab, 0xee, 0xff, 0x00, 0x6b, 0x8d, 0x57, 0xdd, 0xfe, + 0xd7, 0x1e, 0xa7, 0xb9, 0x71, 0x9f, 0xee, 0x5c, 0x7a, 0x9d, 0xd7, 0x1d, + 0xfd, 0xd7, 0x1d, 0xdd, 0xd7, 0x19, 0xfd, 0xca, 0xe2, 0xbf, 0xba, 0xe2, + 0xbf, 0xba, 0xe2, 0xd4, 0xee, 0xb8, 0xcf, 0xee, 0xb8, 0xb5, 0x3b, 0xae, + 0x35, 0x4e, 0xeb, 0x8d, 0x53, 0xba, 0xe2, 0xd4, 0xee, 0xb8, 0xaf, 0xef, + 0xff, 0x00, 0xb5, 0xc5, 0x7f, 0x75, 0xc5, 0x7f, 0x75, 0xc5, 0x7f, 0x75, + 0xc5, 0xa9, 0xdd, 0x71, 0xaa, 0x77, 0x5c, 0x5a, 0x9d, 0xd7, 0x16, 0xa7, + 0xbb, 0xfd, 0xae, 0x2d, 0x4f, 0x72, 0xe2, 0xd4, 0xf7, 0x2e, 0x2b, 0xfd, + 0xc5, 0x71, 0x2a, 0x7b, 0x8a, 0xe2, 0x54, 0xf7, 0x2e, 0x2d, 0x4f, 0x71, + 0x5c, 0x5a, 0x9e, 0xe2, 0xb8, 0xb5, 0x3d, 0xc5, 0x71, 0xaa, 0xfb, 0x8a, + 0xe3, 0xd5, 0xf7, 0x2f, 0x88, 0xab, 0xee, 0x5f, 0x11, 0x57, 0xdc, 0xbe, + 0x22, 0xaf, 0xb9, 0x7c, 0x45, 0x5f, 0x72, 0xf8, 0x8a, 0xde, 0xe2, 0xbe, + 0x26, 0xb7, 0xb8, 0xaf, 0x8b, 0xae, 0x3e, 0xe5, 0xf1, 0x95, 0xc7, 0xdc, + 0xbe, 0x3a, 0xba, 0x1e, 0x21, 0x59, 0x7e, 0xa3, 0x53, 0xa8, 0x4d, 0xf1, + 0x2e, 0xed, 0x54, 0xad, 0x74, 0xea, 0x6c, 0xa5, 0x05, 0x0a, 0x0a, 0x82, + 0xa0, 0xa8, 0x2a, 0x14, 0x7e, 0xef, 0x2a, 0xd0, 0x58, 0x1b, 0x2e, 0x4f, + 0xd4, 0xc8, 0x5a, 0xf5, 0xb8, 0x1b, 0xf1, 0x77, 0x40, 0xcd, 0xd2, 0x8c, + 0x9b, 0xa5, 0x69, 0x9a, 0x14, 0x2c, 0x2b, 0x0a, 0x85, 0x0a, 0x2e, 0xdf, + 0xad, 0xe5, 0x40, 0x51, 0x76, 0x1b, 0xe2, 0xf8, 0x52, 0x2e, 0x8b, 0xf5, + 0x5a, 0xe5, 0x9b, 0xbf, 0x0a, 0x0a, 0x95, 0xba, 0x85, 0x06, 0xec, 0x25, + 0x00, 0xe0, 0xac, 0xb5, 0xcc, 0xe1, 0x72, 0xb2, 0xda, 0xe7, 0xe4, 0x72, + 0x1c, 0xb8, 0x50, 0x16, 0x10, 0xb0, 0x85, 0x80, 0x2c, 0x0b, 0x02, 0xc0, + 0x56, 0x13, 0xfb, 0x5d, 0x62, 0xcc, 0x30, 0xe2, 0x9c, 0x35, 0xd1, 0x60, + 0x58, 0x54, 0x77, 0x51, 0x0b, 0x09, 0x0b, 0x0f, 0x75, 0x84, 0xa0, 0xd5, + 0x17, 0x42, 0x82, 0xb5, 0x17, 0x42, 0x85, 0x85, 0x61, 0x50, 0xa1, 0x61, + 0x58, 0x54, 0x28, 0x50, 0xa2, 0xe8, 0x51, 0x17, 0x7f, 0x2b, 0x45, 0x01, + 0x10, 0x6e, 0x2a, 0x32, 0x41, 0x46, 0x14, 0x29, 0xbe, 0x09, 0xe8, 0xb0, + 0x3d, 0x70, 0x9c, 0x17, 0x0f, 0xf2, 0x85, 0x20, 0x0e, 0xe8, 0xd3, 0x6f, + 0x75, 0x81, 0x9d, 0x02, 0x86, 0x76, 0x50, 0x06, 0xb0, 0x83, 0xa1, 0x62, + 0xd5, 0x12, 0x56, 0x22, 0x16, 0x22, 0xa4, 0xa9, 0xee, 0xb1, 0x2e, 0xaa, + 0xc5, 0x5f, 0x88, 0xdc, 0x27, 0x7f, 0x4b, 0x01, 0x60, 0x58, 0x4a, 0x8f, + 0xd8, 0x61, 0x45, 0xd0, 0xa1, 0x56, 0xb2, 0x71, 0x5d, 0x8a, 0x57, 0xe9, + 0xff, 0x00, 0xf2, 0x5f, 0xa7, 0x0f, 0x72, 0xfd, 0x3d, 0xbd, 0xd7, 0xe9, + 0xec, 0xee, 0xbf, 0x4e, 0x6f, 0x75, 0xfa, 0x7b, 0x7b, 0xaf, 0xd3, 0x87, + 0x74, 0x7c, 0x3f, 0xfe, 0x4b, 0xf4, 0xe3, 0xdd, 0x7e, 0x9c, 0xfe, 0x85, + 0x7c, 0x05, 0x41, 0xb2, 0x36, 0x1a, 0xbd, 0x91, 0xb2, 0xd4, 0x1d, 0x11, + 0xa2, 0xe1, 0xd1, 0x60, 0x58, 0x61, 0x45, 0xd0, 0xa1, 0x42, 0x8f, 0x40, + 0x56, 0x15, 0x0a, 0x02, 0x85, 0xb2, 0x82, 0x57, 0x0d, 0x06, 0x34, 0x2f, + 0x97, 0xb2, 0xc4, 0x51, 0x37, 0xca, 0xd7, 0x24, 0xdd, 0xaa, 0x9b, 0xbf, + 0x19, 0x28, 0x55, 0xe1, 0x3f, 0x12, 0x69, 0x91, 0x23, 0xd4, 0x16, 0x28, + 0x8c, 0xb1, 0xfb, 0x71, 0x68, 0x28, 0xd0, 0xa6, 0x7a, 0x23, 0x64, 0xa4, + 0x76, 0x4e, 0xb1, 0x0e, 0x85, 0x3a, 0xc9, 0x50, 0x6c, 0x9d, 0x4d, 0xcd, + 0xdc, 0x64, 0x84, 0x42, 0x85, 0x08, 0x85, 0x0a, 0x14, 0x0b, 0xe2, 0xfd, + 0xae, 0xd1, 0x13, 0x70, 0x61, 0x76, 0xc8, 0x35, 0xa3, 0x75, 0xbd, 0xd0, + 0xa6, 0x16, 0xab, 0x45, 0xb5, 0xdb, 0xaf, 0xc2, 0xda, 0xe3, 0x7c, 0xad, + 0xd6, 0xeb, 0xa6, 0x4d, 0x55, 0x86, 0xa6, 0x3a, 0x71, 0xdb, 0xd4, 0xc4, + 0xa8, 0x8b, 0xe4, 0x2c, 0x41, 0x62, 0x0a, 0x42, 0x95, 0x3c, 0xd8, 0xfd, + 0x8a, 0x13, 0xa8, 0x31, 0xdd, 0x13, 0xec, 0x87, 0xed, 0x4e, 0xa6, 0xe6, + 0xef, 0xc8, 0x82, 0x82, 0x8b, 0xb6, 0x44, 0xa9, 0x5b, 0xde, 0xd6, 0x69, + 0x25, 0x49, 0xbb, 0xf3, 0x98, 0xdd, 0x11, 0x70, 0x51, 0xc9, 0x2a, 0x14, + 0x2f, 0x0e, 0xd8, 0x8f, 0x4d, 0x20, 0x2c, 0x61, 0x63, 0x58, 0x9c, 0x8e, + 0xbb, 0x95, 0x85, 0x61, 0x0a, 0x02, 0x80, 0xa0, 0x28, 0x0a, 0x02, 0x80, + 0xb0, 0x85, 0x84, 0x2c, 0x2b, 0x0a, 0x8f, 0xca, 0xd5, 0x6b, 0x76, 0x97, + 0x4f, 0xec, 0xe5, 0xa1, 0xdb, 0xaa, 0x96, 0x40, 0x7c, 0xaa, 0xa5, 0x27, + 0x53, 0x3a, 0xdf, 0x17, 0x14, 0x77, 0xc9, 0x0b, 0x0a, 0xc3, 0x2b, 0x83, + 0x53, 0xa0, 0x46, 0x9b, 0xc6, 0xe1, 0x31, 0x9f, 0x71, 0x5b, 0xef, 0xc9, + 0xd6, 0xe2, 0x2f, 0x28, 0x0b, 0xa1, 0x42, 0xc3, 0xd9, 0x61, 0x50, 0xa1, + 0x47, 0x65, 0xc2, 0x2b, 0x86, 0x55, 0x89, 0xb8, 0x5c, 0x7d, 0x14, 0xc2, + 0xc6, 0xb1, 0x1f, 0xec, 0x27, 0x34, 0x3b, 0x42, 0x9d, 0x62, 0x69, 0x3a, + 0x15, 0xf0, 0x0d, 0xf7, 0x2f, 0x81, 0xa7, 0xdc, 0xaf, 0x82, 0xa4, 0xbe, + 0x0a, 0x8f, 0x65, 0xf0, 0x36, 0x7f, 0x6a, 0xf8, 0x0b, 0x3f, 0xb7, 0xff, + 0x00, 0x6b, 0xe0, 0x2c, 0xfe, 0xdf, 0xfd, 0xaf, 0x81, 0xa1, 0xdb, 0xfd, + 0xaf, 0x80, 0xa1, 0xd9, 0x3a, 0xc1, 0x4c, 0x6c, 0x99, 0x46, 0x9b, 0x07, + 0xca, 0x16, 0x15, 0x0a, 0xad, 0x0a, 0x6e, 0x09, 0xcd, 0x8c, 0xfa, 0x5d, + 0x08, 0x28, 0x40, 0x2c, 0x2b, 0x02, 0x0c, 0x58, 0x16, 0x05, 0x81, 0x60, + 0x58, 0x16, 0x05, 0xc3, 0x5c, 0x25, 0xc4, 0x7f, 0x75, 0x89, 0xdd, 0xd0, + 0x71, 0x6e, 0xcb, 0x8c, 0xff, 0x00, 0xfe, 0x01, 0x71, 0x9f, 0xff, 0x00, + 0xc0, 0x21, 0x57, 0xb8, 0x5c, 0x51, 0xd5, 0xab, 0x88, 0xce, 0xca, 0x58, + 0x7a, 0xac, 0x3d, 0x8a, 0xc2, 0x79, 0x05, 0xeb, 0x11, 0x3f, 0xda, 0x2d, + 0x40, 0x23, 0x01, 0x18, 0x76, 0x85, 0x3a, 0xcd, 0x49, 0xdd, 0x13, 0xac, + 0x0d, 0x3e, 0x52, 0x9d, 0x61, 0xaa, 0xdd, 0xb5, 0x4e, 0xa4, 0xe6, 0x79, + 0x82, 0x8c, 0x91, 0x2a, 0x10, 0x0a, 0x10, 0x6a, 0xc2, 0x9b, 0x49, 0xce, + 0x3a, 0x21, 0x64, 0xa9, 0xd4, 0x21, 0x65, 0x1f, 0x73, 0x90, 0xb3, 0xd3, + 0x1f, 0x95, 0xc3, 0xa6, 0x3e, 0xd5, 0x85, 0xbd, 0x02, 0xd3, 0xb0, 0xff, + 0x00, 0xa0, 0xb1, 0x7e, 0x07, 0xfd, 0x05, 0x88, 0xf4, 0x5c, 0x47, 0xf7, + 0xe5, 0x07, 0x10, 0x9a, 0xe9, 0x58, 0x8a, 0x9f, 0xc2, 0xd1, 0x45, 0xc5, + 0xdd, 0x91, 0xd7, 0xfb, 0x4c, 0x6e, 0x53, 0xf7, 0x8c, 0xef, 0xb2, 0xd2, + 0x7f, 0x45, 0x53, 0xc3, 0xdd, 0xf6, 0x14, 0xfa, 0x4e, 0x61, 0x87, 0x05, + 0x0b, 0x0a, 0x0d, 0x4d, 0xa4, 0x5d, 0xa0, 0x4d, 0xb1, 0x3c, 0xf9, 0xb4, + 0x42, 0xcd, 0x4c, 0x6f, 0xaa, 0x0c, 0xa6, 0xdd, 0x9a, 0xb1, 0x1d, 0xbd, + 0x2b, 0x5d, 0x39, 0x09, 0x27, 0x7f, 0xed, 0x5a, 0x5a, 0xb9, 0x1d, 0x4f, + 0x24, 0xb4, 0x3b, 0x42, 0xaa, 0xd8, 0x5b, 0xbb, 0x34, 0x4c, 0xb1, 0xbb, + 0xee, 0xd1, 0x36, 0x85, 0x26, 0x7e, 0x56, 0x23, 0xb0, 0xf5, 0x4d, 0x32, + 0x3f, 0xb6, 0x29, 0x77, 0xe5, 0xb8, 0xfa, 0xd6, 0x18, 0xfe, 0xd7, 0x29, + 0x9a, 0x33, 0x92, 0x11, 0x47, 0xd6, 0x81, 0x71, 0xfd, 0xc2, 0x3f, 0x65, + 0x76, 0xcb, 0xec, 0xe4, 0x84, 0x51, 0xba, 0x14, 0x7a, 0x68, 0x50, 0xa1, + 0x42, 0x02, 0xe3, 0xfb, 0x44, 0x28, 0x51, 0xc8, 0x85, 0x1f, 0xb1, 0x3b, + 0x64, 0x76, 0x1c, 0x81, 0x71, 0x50, 0xb0, 0xa8, 0x50, 0xb0, 0xa8, 0x47, + 0xd1, 0x04, 0x02, 0x85, 0x85, 0x45, 0xe7, 0xfb, 0x55, 0xc9, 0xdc, 0x81, + 0xc8, 0x28, 0xfa, 0x20, 0x10, 0x19, 0x8f, 0xa6, 0x95, 0x3f, 0xb8, 0x4a, + 0x90, 0xb1, 0x2c, 0x4a, 0x56, 0x25, 0x89, 0x4a, 0x95, 0x39, 0x4a, 0x76, + 0xfc, 0x81, 0xc8, 0x28, 0xfa, 0x00, 0x10, 0x6a, 0x8f, 0x4c, 0x5c, 0xb5, + 0x5a, 0xa8, 0x2b, 0x55, 0x05, 0x61, 0x58, 0x56, 0x10, 0xb0, 0xa8, 0x2b, + 0xe6, 0x5f, 0x32, 0x92, 0xb1, 0x20, 0xe1, 0xca, 0x9e, 0x44, 0xa9, 0xf4, + 0x05, 0xc0, 0x6e, 0x8d, 0x7a, 0x63, 0xaa, 0xf8, 0x8a, 0x5d, 0xd0, 0xa8, + 0xd7, 0x6c, 0x6e, 0x85, 0x01, 0x40, 0x51, 0x9a, 0x14, 0x28, 0x5a, 0x84, + 0xd7, 0x8d, 0x8a, 0x2e, 0x81, 0x2b, 0x18, 0x71, 0x45, 0xe0, 0x9e, 0x55, + 0x5b, 0x65, 0x0a, 0x3e, 0x67, 0x27, 0x78, 0xc5, 0x11, 0xb0, 0x95, 0xfa, + 0xc8, 0xf6, 0x26, 0x78, 0xb3, 0x1d, 0xe6, 0x6a, 0xa5, 0x68, 0xa5, 0x5b, + 0xc8, 0x6e, 0x21, 0x11, 0xe8, 0x02, 0x6e, 0x69, 0xe6, 0x62, 0x0b, 0x12, + 0x92, 0xb5, 0x46, 0x7a, 0x21, 0xbf, 0x3f, 0x09, 0xec, 0xb0, 0xc2, 0xd5, + 0x4a, 0x04, 0x1c, 0xce, 0x70, 0x1b, 0x95, 0xc5, 0x60, 0xea, 0xb8, 0xdd, + 0x82, 0x35, 0x9d, 0xd9, 0x1a, 0x8f, 0xde, 0x54, 0xb8, 0xf5, 0x5a, 0xfe, + 0x56, 0x1f, 0xc2, 0xc0, 0xfe, 0x88, 0xb1, 0xe5, 0x70, 0xff, 0x00, 0x0b, + 0x86, 0x8b, 0x4b, 0x75, 0x92, 0x81, 0x7f, 0x47, 0x2c, 0x55, 0x47, 0x54, + 0x2a, 0xbf, 0xa8, 0x42, 0xd0, 0x3a, 0x84, 0x2b, 0x53, 0x3d, 0x54, 0xce, + 0xd9, 0x6a, 0x5a, 0xd8, 0xcd, 0x06, 0xa9, 0xf6, 0x9a, 0x8f, 0xea, 0x8b, + 0x8d, 0xe0, 0xaa, 0x76, 0xa7, 0x37, 0x47, 0x26, 0x54, 0x15, 0x04, 0x8e, + 0x6b, 0x9a, 0x80, 0xd2, 0x13, 0x58, 0x1a, 0x56, 0x16, 0x94, 0x69, 0x89, + 0xd1, 0x43, 0xc6, 0xc5, 0x63, 0x70, 0xdc, 0x21, 0x54, 0x75, 0x41, 0xe0, + 0xdc, 0x15, 0x7a, 0xe2, 0xce, 0xcc, 0x6e, 0x56, 0x8f, 0x10, 0xad, 0x5b, + 0x49, 0x80, 0x89, 0x9b, 0x82, 0x6a, 0x61, 0x23, 0x50, 0xac, 0xb6, 0xd2, + 0x4e, 0x0a, 0x97, 0x14, 0x79, 0x4d, 0x70, 0x76, 0xd7, 0x93, 0x1b, 0xa9, + 0x07, 0x64, 0x10, 0x11, 0xc8, 0x9c, 0xd8, 0x96, 0xb7, 0x68, 0xb1, 0x2c, + 0x48, 0xa6, 0xa9, 0x01, 0x37, 0x98, 0xd6, 0x62, 0x41, 0x8d, 0x19, 0x0d, + 0x30, 0x53, 0x9a, 0x5b, 0xbd, 0xd2, 0x83, 0xbb, 0xa3, 0x5d, 0x83, 0x44, + 0xea, 0xee, 0xec, 0x9d, 0x54, 0x9d, 0xca, 0x68, 0xc5, 0xb0, 0x41, 0xa7, + 0xba, 0xe1, 0x8e, 0xab, 0x0b, 0x79, 0x10, 0xab, 0xcc, 0x2a, 0x6d, 0xc2, + 0xdb, 0xe1, 0x60, 0x05, 0x70, 0xc7, 0x45, 0xfd, 0x46, 0xec, 0x57, 0x1d, + 0xcd, 0xf3, 0x04, 0x1f, 0x21, 0x54, 0x3f, 0x29, 0x47, 0x20, 0xbe, 0xca, + 0xe8, 0x7c, 0x73, 0x48, 0xf9, 0x90, 0xba, 0x25, 0x61, 0x85, 0x17, 0x6e, + 0xb0, 0x34, 0xac, 0x24, 0x79, 0x4a, 0xe2, 0x39, 0xbb, 0x85, 0xe2, 0x75, + 0x5a, 0xea, 0x1a, 0x5e, 0x10, 0x4d, 0x41, 0x33, 0x74, 0x13, 0x91, 0xe4, + 0x93, 0x87, 0x7c, 0xa6, 0x0f, 0x45, 0xf2, 0xaf, 0xe0, 0xa9, 0x7a, 0xc6, + 0x7a, 0x85, 0xc4, 0x0b, 0x10, 0x39, 0x06, 0xaa, 0x22, 0xf8, 0x58, 0x14, + 0x15, 0x85, 0x61, 0x44, 0x45, 0xe0, 0xa0, 0x75, 0x85, 0x50, 0x4b, 0x9a, + 0x9b, 0xcc, 0x66, 0xd9, 0xaa, 0xf9, 0x72, 0x40, 0x29, 0xd6, 0x79, 0xd5, + 0xa9, 0xcc, 0x75, 0x3f, 0x32, 0x6b, 0xa1, 0x03, 0x37, 0x8e, 0x43, 0xfe, + 0x67, 0x01, 0xca, 0x7f, 0x94, 0xde, 0x6e, 0x9b, 0xa5, 0x59, 0xbc, 0xe3, + 0x9a, 0xed, 0xd7, 0x4b, 0x86, 0x68, 0xef, 0x77, 0x89, 0xfd, 0x1c, 0x81, + 0x35, 0x35, 0x35, 0x07, 0xb4, 0x0d, 0x4a, 0x75, 0x40, 0x76, 0x50, 0xe5, + 0x07, 0xba, 0x8e, 0x48, 0x91, 0x93, 0x45, 0xa2, 0xc4, 0xa5, 0x68, 0x8b, + 0x42, 0x8e, 0xca, 0x5c, 0xb1, 0x9e, 0xa1, 0x35, 0xd2, 0x79, 0x2f, 0xde, + 0xe9, 0x53, 0x08, 0x03, 0xba, 0x76, 0xe8, 0x6d, 0xcc, 0x6e, 0xd9, 0xaa, + 0xf9, 0x73, 0x7f, 0x28, 0xd9, 0xc1, 0xf2, 0xa8, 0x34, 0xce, 0xab, 0x1b, + 0x7b, 0xae, 0x20, 0xe8, 0xb1, 0x1e, 0xcb, 0xe6, 0x85, 0xfd, 0x4f, 0xc2, + 0x8a, 0x9d, 0xd6, 0x17, 0xfb, 0x96, 0x17, 0x7b, 0x96, 0x17, 0xfb, 0x96, + 0x17, 0xfb, 0x90, 0x0f, 0xee, 0xbe, 0x75, 0x2f, 0xec, 0xb1, 0x9e, 0xc8, + 0x3e, 0x6e, 0x1b, 0xe4, 0x77, 0x94, 0xde, 0x6e, 0x17, 0x15, 0x67, 0x3f, + 0x38, 0xe6, 0xbd, 0x0d, 0xae, 0x08, 0xe7, 0xf1, 0x4f, 0xa4, 0x3f, 0x9c, + 0x81, 0x35, 0x35, 0x35, 0x35, 0xa0, 0x0d, 0x96, 0xaa, 0x39, 0x50, 0xa3, + 0x9a, 0xcd, 0xf9, 0x2e, 0x0a, 0x21, 0x61, 0x28, 0xb4, 0x9e, 0x88, 0x34, + 0x84, 0x77, 0xf4, 0x75, 0x76, 0xcb, 0x37, 0xe8, 0x74, 0x2b, 0x86, 0x3e, + 0xdc, 0xbd, 0x72, 0x1d, 0x02, 0x6e, 0xdc, 0xa7, 0x6d, 0x94, 0x5c, 0x55, + 0x0f, 0x38, 0xe6, 0xbf, 0x64, 0xd3, 0x7c, 0x67, 0xf1, 0x4f, 0xa4, 0x3f, + 0x9c, 0xa1, 0x35, 0x35, 0x31, 0xdf, 0x28, 0xe4, 0x45, 0xd1, 0xe8, 0x1b, + 0xbf, 0x24, 0x64, 0x2b, 0xaf, 0x30, 0x6f, 0x9e, 0xae, 0xd7, 0x1e, 0x44, + 0xce, 0xe8, 0xc8, 0x5a, 0xaf, 0x99, 0x09, 0xea, 0x8c, 0xf7, 0x47, 0xf9, + 0x51, 0xf9, 0xb8, 0x4a, 0x92, 0x80, 0xef, 0x97, 0x6b, 0xce, 0xd7, 0x9c, + 0x85, 0x52, 0xd1, 0xdc, 0xd7, 0xec, 0x9b, 0xca, 0xf1, 0x4f, 0xa4, 0x3f, + 0x94, 0x72, 0x04, 0xd4, 0xd5, 0x4b, 0xc8, 0x3d, 0x53, 0x39, 0xa5, 0x75, + 0xe6, 0x37, 0x7c, 0xf5, 0x79, 0x61, 0x10, 0x3a, 0x28, 0x50, 0xb5, 0x45, + 0xa4, 0xac, 0x2a, 0x14, 0x20, 0x23, 0x37, 0x5b, 0xca, 0x28, 0xe6, 0xa6, + 0x7e, 0x64, 0x36, 0xe6, 0x54, 0xd9, 0x0b, 0x81, 0xd7, 0x91, 0xe2, 0x9f, + 0x4c, 0x7f, 0x28, 0xde, 0x10, 0x4d, 0x41, 0x51, 0xfa, 0x6d, 0xf5, 0x4c, + 0xcc, 0x6f, 0x1e, 0x85, 0xbb, 0xe7, 0xab, 0xcc, 0x95, 0xa2, 0xc2, 0x16, + 0x10, 0xb0, 0x85, 0x80, 0x14, 0xe1, 0x01, 0x37, 0x64, 0x73, 0x1c, 0x87, + 0x74, 0x6e, 0x19, 0x1b, 0xe6, 0x4d, 0xd8, 0x73, 0x2a, 0x5e, 0x37, 0x47, + 0x7c, 0xfe, 0x29, 0xf4, 0xc7, 0xf2, 0x8d, 0xc2, 0xe0, 0x9a, 0x9a, 0xa8, + 0x7d, 0x26, 0xfa, 0xa6, 0x66, 0x37, 0x8f, 0x42, 0xcf, 0x36, 0x7a, 0xbd, + 0x39, 0x90, 0x86, 0xf9, 0x5f, 0xe5, 0x29, 0x9e, 0x54, 0x79, 0x4e, 0xdd, + 0x1c, 0xc3, 0x75, 0x4f, 0xca, 0x39, 0x95, 0x13, 0x76, 0xe5, 0x78, 0xa7, + 0xd3, 0x1f, 0xca, 0x76, 0x56, 0xa6, 0xab, 0x37, 0xd2, 0x6f, 0xaa, 0x6e, + 0x63, 0x9c, 0xf3, 0x69, 0xf9, 0xb3, 0xd5, 0xcc, 0x35, 0x47, 0x2c, 0xca, + 0x1b, 0x9c, 0xd4, 0xfc, 0xb9, 0xc0, 0x95, 0x02, 0xf7, 0xf9, 0x8a, 0x28, + 0xe6, 0xa5, 0xe4, 0x1c, 0xca, 0x89, 0xbc, 0xaf, 0x14, 0xfa, 0x43, 0xf9, + 0x47, 0x20, 0x4d, 0x4d, 0x56, 0x5f, 0xa2, 0xdf, 0x54, 0xdc, 0xc7, 0x39, + 0xd1, 0x75, 0xe6, 0x53, 0xdf, 0x3d, 0x5c, 0xc0, 0xc2, 0x99, 0xcc, 0xdd, + 0xf3, 0x37, 0xae, 0x76, 0x9b, 0x8e, 0xf7, 0x54, 0xf3, 0x14, 0x73, 0xd0, + 0xfa, 0x63, 0x98, 0xf4, 0x36, 0xe5, 0x78, 0xa7, 0xd2, 0x1f, 0xca, 0x28, + 0x64, 0x6a, 0x6a, 0xb2, 0x7d, 0x11, 0xea, 0x9b, 0x98, 0xde, 0x32, 0x39, + 0x37, 0x99, 0x4f, 0x7c, 0xf5, 0x77, 0xe6, 0xb3, 0xae, 0x61, 0xb9, 0xcd, + 0x08, 0xac, 0x46, 0xfa, 0xbe, 0x62, 0x8d, 0xc2, 0xe2, 0x54, 0xdd, 0x66, + 0xfa, 0x43, 0x99, 0x53, 0x56, 0xa1, 0xdf, 0x95, 0xe2, 0x9f, 0x48, 0x7f, + 0x29, 0xc8, 0x64, 0x6a, 0x6a, 0xb1, 0xfd, 0x11, 0xea, 0x9b, 0xb2, 0x39, + 0x4d, 0xe1, 0x1b, 0xdc, 0xb6, 0xe6, 0x53, 0xdf, 0x3d, 0x5d, 0xf9, 0xac, + 0xeb, 0x90, 0x68, 0x22, 0xe1, 0xe6, 0x3c, 0x83, 0x7d, 0x6f, 0x31, 0x46, + 0xf2, 0x51, 0x28, 0x09, 0xd9, 0x61, 0x2a, 0xc9, 0xf4, 0x87, 0x31, 0xfb, + 0x21, 0xca, 0xf1, 0x3f, 0xa3, 0xfe, 0x51, 0x42, 0xe1, 0x70, 0x4c, 0x56, + 0x3f, 0xa2, 0x3d, 0x53, 0x76, 0x47, 0x29, 0xc8, 0x6f, 0x2a, 0x34, 0x43, + 0x97, 0x4f, 0x3d, 0x5d, 0xf9, 0xac, 0xbf, 0xad, 0xe3, 0xcc, 0x73, 0x9b, + 0xc2, 0xad, 0xe7, 0x28, 0xdc, 0x74, 0x44, 0xa0, 0x25, 0x0d, 0x14, 0xab, + 0x27, 0xd2, 0x1c, 0xc7, 0x21, 0xca, 0xf1, 0x3f, 0xa3, 0xfe, 0x51, 0x43, + 0x20, 0x4c, 0x56, 0x2f, 0xa5, 0xea, 0x9b, 0xb2, 0x39, 0x4e, 0x72, 0x86, + 0xc9, 0xbc, 0xba, 0x59, 0xea, 0xef, 0xcd, 0x6e, 0xd7, 0xf5, 0xbf, 0xee, + 0x39, 0xcd, 0xe1, 0x57, 0xf3, 0x9b, 0xcd, 0xc0, 0x5c, 0x55, 0x9f, 0xe9, + 0x8e, 0x63, 0x90, 0xe5, 0x78, 0x97, 0xd1, 0x4e, 0xd1, 0x04, 0x2f, 0x09, + 0x8a, 0xc3, 0xf4, 0xbd, 0x50, 0xdb, 0x31, 0xce, 0x50, 0xd9, 0x0d, 0xf9, + 0x74, 0xb3, 0xd5, 0xdf, 0x9a, 0xdb, 0xfa, 0xdf, 0xf7, 0xf2, 0xed, 0x1e, + 0x73, 0x79, 0x42, 0xfe, 0xaa, 0x87, 0xd3, 0x1c, 0xce, 0xa8, 0x72, 0xbc, + 0x47, 0xe8, 0x23, 0x99, 0x8a, 0xc3, 0xf4, 0xbd, 0x57, 0x4c, 0xc6, 0xf9, + 0x52, 0xa5, 0x4a, 0x71, 0x4d, 0xdb, 0x99, 0x4b, 0x3d, 0x5d, 0xfd, 0x19, + 0xdc, 0x1e, 0x5d, 0xa7, 0xce, 0x6e, 0x39, 0x7a, 0xaa, 0x5e, 0x41, 0xcc, + 0xea, 0x87, 0x2b, 0xc4, 0x3e, 0x81, 0x45, 0x0c, 0x81, 0x35, 0x58, 0x3e, + 0x97, 0xaa, 0xe9, 0x98, 0xde, 0x6e, 0x95, 0x2a, 0x25, 0x44, 0x22, 0x86, + 0xdc, 0xaa, 0x59, 0xea, 0xef, 0xcd, 0x85, 0x0a, 0x14, 0x0b, 0xcf, 0x2e, + 0xd7, 0xe7, 0x28, 0xe7, 0x67, 0x94, 0x73, 0x02, 0x0a, 0x79, 0x36, 0xff, + 0x00, 0xa0, 0xe4, 0x77, 0x43, 0x28, 0x56, 0x0f, 0xa5, 0xfb, 0x01, 0x3a, + 0xdf, 0xbd, 0xd0, 0x16, 0x85, 0x0b, 0x8a, 0x6f, 0x2a, 0x96, 0x7a, 0x9b, + 0xf3, 0x0a, 0xe9, 0x98, 0xa1, 0xca, 0xb5, 0xf9, 0xd6, 0x8a, 0x06, 0x66, + 0xec, 0x39, 0x64, 0xc5, 0xdb, 0x29, 0x0d, 0xdd, 0x6f, 0xc8, 0xb6, 0xeb, + 0x41, 0xc8, 0x8d, 0x72, 0x42, 0x08, 0x2f, 0x0f, 0xfa, 0x67, 0xf6, 0x07, + 0x6e, 0xa1, 0x68, 0xa6, 0x36, 0x44, 0xad, 0x16, 0x99, 0x36, 0xe5, 0x52, + 0xcf, 0x53, 0x7e, 0x66, 0xfc, 0x8d, 0xb9, 0x56, 0xdf, 0x3d, 0xd3, 0x74, + 0xde, 0x10, 0xdb, 0x99, 0x21, 0x7f, 0x09, 0xce, 0xac, 0x7e, 0xd5, 0x4f, + 0x16, 0x1f, 0x9b, 0x74, 0xd3, 0x5e, 0x75, 0x88, 0x58, 0x8f, 0x65, 0xc6, + 0x1d, 0x74, 0x42, 0xa0, 0x3b, 0x29, 0xbe, 0xd5, 0xf4, 0x5c, 0xba, 0xe7, + 0xf0, 0xff, 0x00, 0xa6, 0x7d, 0x57, 0x4c, 0xce, 0xdd, 0x1d, 0x96, 0xd9, + 0xa6, 0xe3, 0xa8, 0x4d, 0x77, 0x26, 0x96, 0xd9, 0xea, 0x6f, 0xeb, 0xad, + 0xde, 0x61, 0x9c, 0x14, 0xdd, 0x87, 0xa1, 0xc6, 0x5a, 0xfc, 0x2f, 0xeb, + 0xb5, 0xc6, 0x9b, 0x0e, 0xe1, 0x70, 0x1b, 0xf6, 0x92, 0x10, 0x65, 0x41, + 0xf7, 0x2f, 0xe5, 0x5a, 0x7e, 0x93, 0x97, 0x5c, 0xc1, 0x78, 0x7f, 0xd3, + 0x3c, 0xd2, 0x25, 0x47, 0x33, 0xa6, 0x67, 0x6f, 0xc9, 0xdd, 0x6b, 0xd5, + 0x3d, 0xbf, 0x30, 0x7c, 0xa1, 0x92, 0x72, 0x53, 0xdb, 0x3d, 0x4d, 0xf3, + 0x42, 0x8b, 0xa7, 0xd2, 0xdb, 0xc7, 0xcc, 0x11, 0x39, 0xd9, 0xe5, 0x1c, + 0xa7, 0x1e, 0x99, 0x45, 0xcf, 0x69, 0x23, 0xe5, 0xdd, 0x31, 0xf8, 0x86, + 0xfb, 0x5d, 0x37, 0xda, 0x7e, 0x8b, 0x97, 0x5c, 0xc1, 0x78, 0x77, 0xd3, + 0x3c, 0x88, 0xc8, 0x5d, 0x08, 0x19, 0xba, 0x16, 0x15, 0x1c, 0x9e, 0x99, + 0xf0, 0x85, 0x81, 0x34, 0x40, 0xba, 0x02, 0x81, 0x71, 0x12, 0xa9, 0xd3, + 0xc3, 0xad, 0xd5, 0xec, 0xed, 0xae, 0xdc, 0x0a, 0x8d, 0x96, 0xad, 0x0f, + 0x97, 0x14, 0x85, 0x85, 0xc8, 0xe8, 0xb1, 0x2d, 0x0e, 0x4a, 0x7e, 0x5c, + 0xf5, 0x37, 0xcb, 0x2a, 0xa5, 0x66, 0xd3, 0xf3, 0x14, 0x3c, 0x42, 0x91, + 0x30, 0x53, 0x6b, 0xd3, 0x7f, 0x95, 0xd7, 0x94, 0xe7, 0x48, 0x8a, 0x3a, + 0x9f, 0xce, 0x9f, 0xed, 0x02, 0xff, 0x00, 0xb8, 0x5f, 0xa7, 0x2e, 0x2f, + 0xf1, 0x0e, 0x9c, 0x8a, 0x5f, 0x4c, 0x67, 0x2f, 0x40, 0xdd, 0x19, 0x1f, + 0x6c, 0xa7, 0x4d, 0xd8, 0x0a, 0x0a, 0x13, 0xf6, 0x40, 0x83, 0x74, 0x15, + 0x81, 0x61, 0x0a, 0xd3, 0xf4, 0x5c, 0xb7, 0x39, 0xfc, 0x37, 0xe9, 0x9c, + 0xe3, 0x2c, 0x0e, 0xb9, 0xf0, 0xac, 0x2b, 0x0a, 0x8e, 0x76, 0x21, 0x91, + 0x90, 0x4e, 0x7c, 0x20, 0xac, 0x0d, 0xec, 0xb8, 0x6d, 0x5c, 0x20, 0xb8, + 0x41, 0x01, 0x03, 0x3e, 0x00, 0x75, 0x29, 0xd4, 0xbd, 0xab, 0x01, 0x09, + 0x94, 0xf1, 0x2e, 0x08, 0x5c, 0x27, 0x2b, 0x5b, 0x1c, 0xea, 0x84, 0x94, + 0x58, 0x6e, 0x6d, 0x7a, 0x8c, 0xf2, 0xb9, 0x37, 0xc4, 0x2b, 0x37, 0x7d, + 0x50, 0xf1, 0x33, 0xf7, 0x35, 0x36, 0xd0, 0xca, 0x12, 0xea, 0x44, 0x93, + 0xff, 0x00, 0x2d, 0x42, 0xa3, 0x6e, 0xa2, 0xea, 0x7f, 0xd4, 0x30, 0x53, + 0x6b, 0x53, 0x76, 0xce, 0x56, 0xeb, 0x63, 0xa8, 0x90, 0xda, 0x6b, 0xf5, + 0x3b, 0x40, 0xec, 0xbf, 0x55, 0xad, 0xd8, 0x26, 0xf8, 0xae, 0x9a, 0xb5, + 0x7e, 0xa9, 0xd9, 0xa9, 0xde, 0x23, 0x5c, 0xa7, 0xda, 0xab, 0x3f, 0x77, + 0x21, 0x55, 0xdd, 0xd5, 0x95, 0xcd, 0x75, 0x30, 0x5b, 0x71, 0x70, 0x08, + 0xd6, 0xa6, 0x37, 0x72, 0xf8, 0xba, 0x3b, 0x4a, 0x06, 0x75, 0xbb, 0xc4, + 0xbe, 0xdc, 0xe5, 0x59, 0xf5, 0xa4, 0xdb, 0xe5, 0x4a, 0x94, 0x54, 0x28, + 0x5b, 0x22, 0xf0, 0xdd, 0xca, 0x7d, 0xba, 0x9b, 0x36, 0xd5, 0x51, 0xb7, + 0x71, 0x1f, 0x85, 0xc2, 0x15, 0xae, 0xd3, 0xc1, 0x6c, 0x0d, 0xd1, 0x71, + 0x26, 0x55, 0x22, 0x70, 0x09, 0x55, 0x38, 0x76, 0xaf, 0x95, 0xaf, 0x88, + 0x55, 0xe8, 0xd7, 0xa2, 0x64, 0x99, 0x0a, 0xbd, 0x61, 0x54, 0x87, 0x34, + 0xaa, 0x56, 0xba, 0xd4, 0xb6, 0x29, 0x9e, 0x2b, 0xef, 0x6a, 0x6f, 0x88, + 0xd0, 0x76, 0xe6, 0x13, 0x6b, 0xd2, 0x7f, 0x95, 0xca, 0xd4, 0x7f, 0xa2, + 0xe4, 0x37, 0xcf, 0xe1, 0x9f, 0x48, 0xff, 0x00, 0x39, 0x1c, 0xf6, 0xb3, + 0x57, 0x15, 0x53, 0xc4, 0x28, 0x33, 0xac, 0xaa, 0xbe, 0x2a, 0xf3, 0xa5, + 0x31, 0x09, 0x9e, 0x23, 0x68, 0x61, 0x9c, 0x52, 0xac, 0x96, 0x9f, 0x89, + 0xa7, 0x8b, 0xae, 0x49, 0xe6, 0xc7, 0x2e, 0x2e, 0x0c, 0xee, 0xb0, 0x04, + 0x1a, 0x06, 0xde, 0x9b, 0x64, 0x2b, 0x02, 0x60, 0xdc, 0xfa, 0x2c, 0xa9, + 0xe6, 0x0a, 0xa7, 0x87, 0x35, 0xde, 0x55, 0x57, 0xc3, 0xde, 0xde, 0x89, + 0xd4, 0x4b, 0x56, 0x08, 0x50, 0xa1, 0x10, 0xa1, 0x42, 0x8b, 0xf4, 0x5a, + 0x2d, 0x16, 0x89, 0xb5, 0x1c, 0xdd, 0x8a, 0xe2, 0x38, 0xf5, 0x58, 0x94, + 0xa0, 0x60, 0xe8, 0xa9, 0xdb, 0x80, 0x10, 0xf4, 0xeb, 0x7b, 0x81, 0xf9, + 0x76, 0x56, 0x9b, 0x49, 0xae, 0x04, 0x8e, 0x45, 0x90, 0xcd, 0x16, 0xdf, + 0x21, 0x1a, 0xb4, 0xc6, 0xe5, 0x1b, 0x4d, 0x11, 0xf7, 0x23, 0x6e, 0xa2, + 0x13, 0xbc, 0x45, 0xbf, 0x6b, 0x53, 0xbc, 0x46, 0xa1, 0xd8, 0x23, 0x68, + 0xaf, 0x54, 0xc4, 0xa2, 0x29, 0xd9, 0x84, 0xd4, 0xf9, 0x9c, 0xb8, 0xf6, + 0x67, 0x7d, 0x46, 0x2c, 0x56, 0x2f, 0xca, 0x75, 0x0b, 0x3d, 0x51, 0x8c, + 0x94, 0xcb, 0x3d, 0x8b, 0xba, 0x11, 0x1a, 0x6c, 0x9e, 0x43, 0x6a, 0x1c, + 0x0a, 0x8f, 0x88, 0x54, 0x66, 0x8e, 0xd4, 0x2f, 0xfc, 0x4b, 0x57, 0xe0, + 0xaa, 0xbe, 0x1d, 0x55, 0xba, 0xb3, 0x54, 0xe6, 0xb9, 0x86, 0x1c, 0x2e, + 0x95, 0xc4, 0x7c, 0x40, 0x29, 0xa8, 0x65, 0x95, 0x64, 0xb7, 0xb6, 0xce, + 0xc2, 0xd8, 0x94, 0xef, 0x16, 0x77, 0x46, 0xaa, 0x9e, 0x29, 0x5f, 0xa4, + 0x27, 0x5b, 0xeb, 0xbf, 0x77, 0x27, 0x3c, 0xbb, 0x75, 0x25, 0x6a, 0xa5, + 0x78, 0x7d, 0xa7, 0x81, 0x57, 0x5d, 0x8e, 0x48, 0xba, 0x54, 0xfa, 0x18, + 0x51, 0x91, 0xba, 0x29, 0xf5, 0x26, 0x9b, 0x49, 0x94, 0x04, 0x5e, 0x53, + 0x98, 0x0e, 0x84, 0x27, 0x59, 0x69, 0x3b, 0xa2, 0x75, 0x81, 0xa7, 0xca, + 0x53, 0xac, 0x15, 0x06, 0xc9, 0xf6, 0x7a, 0x8d, 0xdc, 0x28, 0x85, 0xa2, + 0x9c, 0xbb, 0x29, 0xba, 0x54, 0x95, 0x2b, 0x12, 0x92, 0x9a, 0x51, 0x3c, + 0x86, 0xd5, 0xa8, 0xd1, 0x0d, 0x2b, 0x8d, 0x53, 0xa9, 0x58, 0x9c, 0x7a, + 0xa9, 0x2a, 0x54, 0xdf, 0x0a, 0x8b, 0x05, 0x9d, 0x9c, 0x47, 0xee, 0x9e, + 0xe7, 0x54, 0x76, 0x22, 0xb0, 0x92, 0xb0, 0x28, 0x46, 0x1b, 0xba, 0x75, + 0xa1, 0xe5, 0xb8, 0x01, 0xd2, 0xe9, 0x52, 0xa9, 0x5a, 0xea, 0xd2, 0xd8, + 0xaa, 0x76, 0x9a, 0x56, 0xbf, 0xe9, 0xd5, 0x1a, 0xab, 0x5d, 0x94, 0xd9, + 0x8e, 0x9b, 0x5d, 0x09, 0xa3, 0x33, 0x8a, 0x0e, 0x52, 0xa5, 0x10, 0x2e, + 0xd2, 0xfa, 0x06, 0x90, 0xa8, 0x38, 0xa3, 0x45, 0x4a, 0xbd, 0x32, 0x43, + 0x1a, 0xec, 0x90, 0xb0, 0xa8, 0xba, 0x54, 0xa9, 0xe6, 0xce, 0x79, 0x2b, + 0x1a, 0xc4, 0x14, 0xfa, 0xaa, 0x82, 0x1d, 0x96, 0xd8, 0x43, 0x68, 0xb8, + 0xc2, 0x74, 0x95, 0x28, 0x19, 0x5f, 0x2a, 0xd3, 0xba, 0x91, 0xdd, 0x48, + 0xee, 0x8c, 0x0e, 0xab, 0xf8, 0x52, 0x53, 0x1c, 0x1a, 0x7e, 0x61, 0x29, + 0xc3, 0x16, 0xaa, 0x22, 0xf7, 0x67, 0x21, 0x37, 0x90, 0xd7, 0xe0, 0x32, + 0xaa, 0x57, 0x75, 0x43, 0x25, 0x62, 0x40, 0xca, 0x2e, 0x84, 0x6a, 0x13, + 0xb2, 0x32, 0x75, 0x51, 0x7d, 0x2a, 0x26, 0xab, 0xf0, 0x35, 0x54, 0xb2, + 0xd6, 0xa3, 0xe6, 0x08, 0x15, 0x45, 0xed, 0xb6, 0xd0, 0xc0, 0xed, 0xd5, + 0x46, 0x9a, 0x4e, 0x2d, 0x72, 0x2e, 0x4d, 0xc8, 0x51, 0x74, 0x27, 0x39, + 0x35, 0xd2, 0xa7, 0x34, 0x20, 0x10, 0x96, 0x99, 0x0b, 0xc3, 0xed, 0xe5, + 0xee, 0xe1, 0x55, 0x3a, 0xe6, 0x22, 0x6f, 0x95, 0x2a, 0x54, 0xa9, 0x52, + 0xa4, 0x2c, 0x41, 0x62, 0x58, 0x96, 0x25, 0x2b, 0x75, 0x1c, 0xb6, 0xbf, + 0x0e, 0xeb, 0x88, 0x14, 0xcf, 0xa7, 0xaa, 0x34, 0xcb, 0xe2, 0x4f, 0xd9, + 0x88, 0x85, 0x0a, 0x14, 0x28, 0x5a, 0x28, 0x50, 0xa1, 0x45, 0xc3, 0x4d, + 0xd1, 0xb2, 0x54, 0x0d, 0xc4, 0xdd, 0x47, 0xe1, 0x19, 0x0a, 0x54, 0xcd, + 0xf0, 0xa2, 0x6f, 0x29, 0xb7, 0xce, 0x68, 0x29, 0xb4, 0x9c, 0xff, 0x00, + 0x28, 0x55, 0x29, 0x3e, 0x97, 0x9b, 0x34, 0x2f, 0x0e, 0x6c, 0xd5, 0x9b, + 0xaa, 0x59, 0x28, 0xd5, 0xf3, 0x35, 0x52, 0xb1, 0xfc, 0x3b, 0xf1, 0x53, + 0x3a, 0x2f, 0x12, 0xb3, 0x71, 0x1b, 0xc5, 0x66, 0xea, 0x08, 0x3a, 0xa0, + 0x2f, 0x26, 0x13, 0xaa, 0x00, 0x8d, 0x44, 0xe7, 0x2a, 0x68, 0x04, 0x2e, + 0x85, 0x0a, 0x2e, 0x6d, 0x2a, 0x8f, 0xf2, 0xb4, 0xa6, 0xf8, 0x75, 0xa5, + 0xff, 0x00, 0x6c, 0x26, 0xf8, 0x45, 0x66, 0xfc, 0xc1, 0xc2, 0x55, 0x3c, + 0x78, 0x7f, 0xa9, 0xbe, 0x62, 0x39, 0xa3, 0x55, 0xb7, 0x30, 0xdf, 0x88, + 0x85, 0xc4, 0x2b, 0x8a, 0xb8, 0xa1, 0x71, 0x1a, 0xb1, 0xb5, 0x4b, 0x54, + 0x8e, 0xea, 0x5b, 0xdd, 0x62, 0x6a, 0xc6, 0xd5, 0xc4, 0x6a, 0xe2, 0xa6, + 0x12, 0xed, 0x79, 0x2f, 0x12, 0xdc, 0xb6, 0xaa, 0x9c, 0x4a, 0x84, 0xa3, + 0x9b, 0xaa, 0x8b, 0xb6, 0xb8, 0xab, 0x35, 0xa9, 0xd6, 0x73, 0xf8, 0x43, + 0x83, 0x69, 0x6e, 0x28, 0x94, 0xff, 0x00, 0x0e, 0xa2, 0xed, 0xb4, 0x55, + 0x7c, 0x3f, 0x84, 0x0b, 0xc1, 0x58, 0x56, 0x15, 0x0a, 0x14, 0x5c, 0x5c, + 0x81, 0x53, 0x74, 0x42, 0x05, 0x36, 0x95, 0x47, 0x6c, 0x10, 0xb1, 0x56, + 0x77, 0x44, 0xdf, 0x0f, 0x7f, 0x52, 0x9b, 0xe1, 0xed, 0x1e, 0x62, 0x9b, + 0x66, 0xa4, 0xde, 0x8a, 0xad, 0x46, 0xd1, 0x6c, 0x95, 0x52, 0xab, 0xaa, + 0x3b, 0x11, 0x45, 0x12, 0x8d, 0xf2, 0xbc, 0x37, 0xce, 0x72, 0xbe, 0x8b, + 0x1f, 0xe6, 0x0a, 0xa5, 0x85, 0xd3, 0xf2, 0x21, 0x61, 0xa9, 0xd5, 0x3e, + 0xc1, 0x52, 0x3e, 0x52, 0x9f, 0xe1, 0xb6, 0xaf, 0xfe, 0x29, 0xde, 0x1f, + 0x6b, 0x1f, 0x62, 0x36, 0x2b, 0x5f, 0xb0, 0xa1, 0xe1, 0xd6, 0x87, 0x79, + 0x98, 0x53, 0x6c, 0x15, 0x87, 0xd8, 0x50, 0xb0, 0xd7, 0xf6, 0x14, 0x2c, + 0x16, 0x8f, 0x62, 0x1e, 0x1b, 0x69, 0x3d, 0x10, 0xf0, 0xaa, 0xdd, 0x48, + 0x4d, 0xf0, 0x8f, 0x73, 0xd5, 0x3f, 0x0a, 0xa0, 0xdd, 0xf5, 0x4c, 0xb3, + 0xd2, 0xa7, 0xe5, 0x6f, 0x2c, 0x88, 0xe5, 0xee, 0x80, 0x8e, 0x69, 0xe7, + 0xb1, 0x93, 0xa9, 0xe5, 0x14, 0x44, 0x5f, 0x5d, 0xfc, 0x3a, 0x65, 0xc8, + 0xf2, 0xc5, 0xdf, 0xc2, 0xa5, 0x59, 0xf4, 0x1d, 0x89, 0xaa, 0xcd, 0x6c, + 0x65, 0xa0, 0x76, 0x28, 0x80, 0x44, 0x14, 0x6c, 0xb4, 0xbb, 0x2f, 0x84, + 0xa5, 0xd9, 0x7c, 0x2d, 0x2e, 0xcb, 0xe1, 0xe9, 0x76, 0x46, 0xcf, 0x48, + 0xfd, 0xa8, 0xd8, 0xa8, 0x1e, 0x8b, 0xe0, 0x28, 0x76, 0x5f, 0x01, 0x43, + 0xb2, 0xf8, 0x1a, 0x1e, 0xd5, 0xf0, 0x54, 0x3d, 0xab, 0xe1, 0x68, 0xfb, + 0x53, 0x69, 0x53, 0x67, 0x94, 0x65, 0xad, 0x59, 0xb4, 0x5b, 0x2e, 0x56, + 0x8b, 0x43, 0xab, 0x3a, 0x4a, 0x95, 0x39, 0xbc, 0x2d, 0xba, 0x39, 0xd9, + 0xa1, 0x42, 0x85, 0x0a, 0x39, 0x23, 0x98, 0x44, 0xf2, 0xb7, 0x40, 0x47, + 0x38, 0xf3, 0x98, 0xcc, 0x5a, 0x9e, 0x65, 0x41, 0x06, 0x6f, 0xf1, 0x0a, + 0x90, 0xc0, 0xd4, 0x79, 0x73, 0x93, 0x65, 0x66, 0xf1, 0x22, 0xdf, 0x96, + 0xae, 0xa9, 0x95, 0x1b, 0x50, 0x4b, 0x4f, 0x3e, 0xd1, 0x6b, 0x6d, 0x2d, + 0x06, 0xea, 0xb5, 0x67, 0x55, 0x32, 0xec, 0x92, 0xa5, 0x4a, 0x94, 0x15, + 0x96, 0x9f, 0x0e, 0x90, 0x19, 0x80, 0x9e, 0x60, 0xe7, 0x11, 0xc8, 0x02, + 0x56, 0xdc, 0xf3, 0xcd, 0x63, 0x31, 0x2d, 0xb9, 0x95, 0x07, 0xcb, 0x7d, + 0xb1, 0xf8, 0xea, 0x94, 0x72, 0xce, 0x48, 0xce, 0x55, 0x3a, 0xd5, 0x28, + 0x3a, 0x58, 0x55, 0x9f, 0xc4, 0x98, 0xfd, 0x2a, 0x68, 0x81, 0x07, 0x51, + 0xcb, 0x73, 0x83, 0x44, 0x95, 0x69, 0xb7, 0xfd, 0xb4, 0xd3, 0x9f, 0x2a, + 0x56, 0xea, 0x51, 0x52, 0xa6, 0xfb, 0x2d, 0x3e, 0x25, 0x50, 0xd4, 0x3d, + 0x08, 0xf4, 0x04, 0x66, 0x0d, 0xf5, 0xad, 0xa5, 0xd5, 0xdc, 0xf7, 0x0c, + 0x26, 0x15, 0x6a, 0x9c, 0x36, 0x17, 0x22, 0x64, 0xa3, 0xe8, 0x61, 0x44, + 0x2a, 0x36, 0xaa, 0x94, 0x3c, 0xa5, 0x51, 0xf1, 0x3a, 0x6f, 0xd1, 0xfa, + 0x26, 0xbd, 0xaf, 0xd5, 0xa7, 0x39, 0x20, 0x6e, 0xab, 0xdb, 0xe9, 0xd3, + 0xd1, 0xba, 0x95, 0x5a, 0xd4, 0xfa, 0xdb, 0x94, 0x4c, 0xa3, 0x90, 0x9c, + 0xbe, 0x16, 0xcf, 0x98, 0xbb, 0xf6, 0x32, 0xdb, 0xc0, 0x95, 0x11, 0xe8, + 0xcf, 0x24, 0x02, 0x53, 0x19, 0x87, 0xd0, 0x55, 0x6c, 0x89, 0x56, 0xea, + 0xf8, 0xdd, 0x80, 0x6c, 0x39, 0xbb, 0xe6, 0x85, 0x08, 0x85, 0x10, 0x99, + 0x51, 0xf4, 0xcc, 0xb4, 0xaa, 0x5e, 0x27, 0x51, 0xba, 0x3f, 0x55, 0x4f, + 0xc4, 0x28, 0xbf, 0x7d, 0x13, 0x5e, 0xd7, 0xf9, 0x4d, 0xd5, 0x2d, 0x14, + 0xa9, 0x79, 0x9c, 0xaa, 0xf8, 0xa3, 0x46, 0x94, 0xc2, 0xab, 0x6b, 0xa9, + 0x54, 0xfc, 0xc5, 0x49, 0x39, 0x8d, 0xe2, 0xe0, 0xbc, 0x3a, 0x9e, 0x0a, + 0x53, 0xdf, 0xd0, 0x8f, 0x47, 0x12, 0xa3, 0xd2, 0x9c, 0xe0, 0x4a, 0x6d, + 0x2e, 0xe8, 0x08, 0xf4, 0x36, 0xfb, 0x4f, 0x01, 0x98, 0x46, 0xe5, 0x3b, + 0x7c, 0xda, 0x64, 0x8c, 0xba, 0xe4, 0xde, 0xed, 0xd4, 0x28, 0x47, 0x45, + 0x88, 0x26, 0xd5, 0x2d, 0xf2, 0xa7, 0x5a, 0xeb, 0x3b, 0x42, 0xe4, 0x5d, + 0x3b, 0xa9, 0x53, 0x70, 0xcd, 0xbe, 0x46, 0x37, 0x1b, 0x80, 0x0a, 0x9b, + 0x70, 0x34, 0x0f, 0x40, 0x07, 0xed, 0x67, 0x20, 0x69, 0x3b, 0x26, 0xd2, + 0xee, 0x80, 0x03, 0x6f, 0x45, 0x52, 0xa0, 0xa6, 0xd2, 0xe7, 0x2b, 0x4d, + 0x73, 0x5e, 0xa1, 0x71, 0xb8, 0xe6, 0x17, 0x42, 0x9c, 0xc2, 0xe9, 0x5b, + 0xdd, 0xba, 0x2f, 0x68, 0x4e, 0x79, 0x37, 0xc5, 0xd1, 0x7c, 0x5d, 0x0b, + 0x6d, 0xd4, 0x5e, 0x72, 0x78, 0x75, 0x1c, 0x4f, 0xc6, 0x7a, 0x7a, 0x08, + 0xfd, 0xb7, 0x09, 0x28, 0x52, 0x3d, 0x50, 0xa6, 0x07, 0xa5, 0xf1, 0x2b, + 0x56, 0x33, 0xc3, 0x6e, 0xc3, 0x29, 0xcd, 0x0b, 0xf3, 0x7e, 0xf7, 0x91, + 0x76, 0xe7, 0x23, 0x99, 0x8b, 0x65, 0xf8, 0xcd, 0xa5, 0xf0, 0xa3, 0x90, + 0xc6, 0xe2, 0x20, 0x05, 0x67, 0xa4, 0x28, 0xb3, 0x08, 0xf5, 0x78, 0x94, + 0xfa, 0xd9, 0xc8, 0xd9, 0x1e, 0x9a, 0xdb, 0xe2, 0x01, 0xa3, 0x05, 0x24, + 0x5d, 0x3e, 0x88, 0xa8, 0x50, 0xa1, 0x42, 0x85, 0x10, 0xb0, 0xce, 0x85, + 0x1a, 0x64, 0x6c, 0xb7, 0xba, 0x08, 0x42, 0xe1, 0x9c, 0xa8, 0xba, 0x25, + 0x58, 0x6c, 0x58, 0x3f, 0xa8, 0xfd, 0xf9, 0xa6, 0x50, 0xd6, 0xf9, 0x53, + 0xc9, 0x9b, 0xb6, 0xf5, 0x65, 0xca, 0x7b, 0xa1, 0x0b, 0x13, 0x7b, 0x2c, + 0x63, 0xb2, 0xe2, 0x2e, 0x29, 0x5c, 0x47, 0x2e, 0x23, 0x97, 0x11, 0xcb, + 0x1b, 0x96, 0x33, 0xdd, 0x07, 0x92, 0x81, 0x3c, 0xda, 0xd6, 0x9a, 0x74, + 0x04, 0xbc, 0xab, 0x57, 0x88, 0x3e, 0xbe, 0x8d, 0xd0, 0x29, 0x9c, 0x85, + 0x4c, 0xed, 0x76, 0xf7, 0x6d, 0x77, 0xe5, 0x4c, 0xdf, 0x39, 0x77, 0xb8, + 0x5d, 0x17, 0x04, 0xd6, 0x82, 0x75, 0x4d, 0xf0, 0xda, 0x6f, 0xf9, 0x89, + 0x4d, 0xb1, 0xd0, 0xa5, 0xd1, 0x7f, 0x4c, 0x88, 0x84, 0x28, 0x33, 0xd8, + 0x3f, 0xe9, 0x54, 0xb1, 0xb1, 0xde, 0x56, 0xb7, 0xfe, 0x95, 0x4f, 0x0e, + 0xa9, 0xf6, 0xb0, 0x7f, 0x83, 0xff, 0x00, 0xea, 0x7d, 0x8a, 0xbb, 0x37, + 0x6a, 0x34, 0xdc, 0xde, 0x8a, 0x2e, 0x37, 0x42, 0x2d, 0x28, 0x30, 0xb8, + 0xc0, 0x56, 0x4b, 0x0f, 0x0f, 0xe7, 0x7e, 0xea, 0x39, 0x91, 0x71, 0x18, + 0x4e, 0x59, 0x58, 0x96, 0x25, 0x37, 0x99, 0xe8, 0xa2, 0xe9, 0xbe, 0x54, + 0xac, 0x6a, 0x7d, 0x3e, 0x10, 0xa5, 0x4a, 0x90, 0xb4, 0xcd, 0x29, 0xb1, + 0x28, 0x41, 0xe5, 0x4c, 0x2a, 0xb6, 0xfa, 0x14, 0xba, 0xaa, 0xfe, 0x2a, + 0xf7, 0xe9, 0x4f, 0x44, 0xe7, 0xb9, 0xc6, 0x4e, 0x6d, 0x96, 0x9c, 0xad, + 0x54, 0x5c, 0x54, 0xa9, 0xcc, 0x27, 0xa2, 0xa7, 0x66, 0xab, 0x53, 0x60, + 0xa9, 0x52, 0x75, 0x0e, 0xab, 0xf9, 0x41, 0xed, 0x0b, 0x1a, 0xc4, 0xb1, + 0x14, 0x5c, 0xe5, 0x04, 0xa3, 0x41, 0xae, 0xdc, 0x2f, 0x82, 0xa2, 0x77, + 0x6a, 0xfd, 0x36, 0x81, 0xfb, 0x53, 0xfc, 0x2e, 0x84, 0x7c, 0xa5, 0x1f, + 0x0c, 0xf6, 0xb9, 0x7e, 0x9c, 0xfe, 0xea, 0x85, 0x89, 0xb6, 0x7d, 0x5d, + 0xba, 0xc4, 0xa6, 0xe9, 0x53, 0x74, 0x75, 0xbe, 0x14, 0x28, 0xc8, 0x44, + 0xf2, 0xa5, 0x4a, 0x95, 0x3c, 0x89, 0x58, 0x96, 0x25, 0x89, 0x4f, 0x3e, + 0x42, 0x90, 0xb1, 0x05, 0x39, 0x37, 0xe4, 0x62, 0x42, 0xa2, 0x0f, 0x07, + 0x35, 0x5a, 0xe6, 0x9e, 0xcc, 0x25, 0x56, 0xf1, 0x3a, 0xe3, 0x66, 0xc2, + 0xab, 0x6a, 0xad, 0x57, 0xcc, 0x51, 0x24, 0xdd, 0x0b, 0x7b, 0xf5, 0x28, + 0xa8, 0x85, 0xb5, 0xc5, 0x69, 0x7c, 0x14, 0x2e, 0xdd, 0x42, 0xd6, 0x14, + 0x2d, 0x45, 0xc3, 0x75, 0x2c, 0x23, 0x56, 0xa8, 0x4d, 0xa6, 0xf7, 0x79, + 0x42, 0x6d, 0x82, 0xab, 0xb7, 0x09, 0xbe, 0x1e, 0xc1, 0xab, 0xca, 0x6d, + 0x3a, 0x54, 0xfc, 0x8d, 0x42, 0x4e, 0xe8, 0xb4, 0x4c, 0xad, 0x14, 0x05, + 0xf2, 0xaf, 0x95, 0x48, 0x58, 0x96, 0x25, 0x88, 0xa9, 0x39, 0x70, 0xe5, + 0x8b, 0xa3, 0x4e, 0x53, 0x84, 0xa9, 0xf5, 0x12, 0xb1, 0x15, 0x89, 0x62, + 0x17, 0x92, 0xb1, 0x2c, 0x45, 0x4a, 0xc5, 0xc8, 0x1a, 0xac, 0x7d, 0x14, + 0xad, 0x39, 0x6c, 0x79, 0x08, 0x19, 0xca, 0x5a, 0x0e, 0xe9, 0xd6, 0x6a, + 0x2e, 0xdd, 0xa9, 0xde, 0x1b, 0x67, 0x3d, 0x13, 0xbc, 0x2a, 0x8f, 0x47, + 0x27, 0x78, 0x67, 0x67, 0xaf, 0xd3, 0x6a, 0x0d, 0x8a, 0x1e, 0x18, 0x7e, + 0xe7, 0x21, 0xe1, 0xd4, 0xc6, 0xe5, 0x0b, 0x0d, 0x1e, 0xcb, 0xe0, 0xa8, + 0x7b, 0x57, 0xc1, 0xd1, 0xf6, 0xaf, 0x82, 0xa1, 0xed, 0x5f, 0x03, 0x43, + 0xda, 0xbe, 0x06, 0x8f, 0x65, 0xf0, 0x14, 0x3b, 0x2f, 0x80, 0xa3, 0xd9, + 0x7e, 0x9f, 0x45, 0x7e, 0x9f, 0x43, 0xb2, 0xf8, 0x7a, 0x5e, 0xd5, 0xc0, + 0xa5, 0xed, 0x5c, 0x0a, 0x5e, 0xd5, 0xc1, 0xa7, 0xd9, 0x70, 0xdb, 0xd9, + 0x5a, 0x6c, 0x65, 0xe7, 0x13, 0x10, 0xb0, 0x55, 0x43, 0xc3, 0x9e, 0x77, + 0x28, 0x78, 0x6b, 0x7a, 0xb9, 0x36, 0xc1, 0x44, 0x26, 0xd9, 0xa9, 0xb7, + 0xca, 0xd5, 0xb6, 0xc8, 0x87, 0x1e, 0xab, 0x86, 0xb0, 0x20, 0x11, 0x52, + 0x16, 0x99, 0x64, 0x05, 0x37, 0x6c, 0x84, 0x66, 0xd5, 0x49, 0x52, 0x84, + 0x72, 0x24, 0x2c, 0x6b, 0x11, 0x44, 0xa8, 0xf5, 0xb2, 0xa5, 0x4a, 0x9b, + 0xa1, 0x68, 0xa7, 0x29, 0x43, 0x6c, 0xa0, 0xf2, 0x65, 0x36, 0xac, 0x2e, + 0x31, 0x5c, 0x57, 0x2e, 0x23, 0x96, 0x37, 0x2c, 0x4e, 0x52, 0x79, 0x18, + 0x94, 0xf7, 0x46, 0xa0, 0x58, 0xd6, 0x35, 0x8d, 0x71, 0x17, 0x11, 0x71, + 0x17, 0x10, 0x29, 0x53, 0x7e, 0xfb, 0x28, 0x39, 0x26, 0xfc, 0x6d, 0x08, + 0xd5, 0x1d, 0x10, 0x7b, 0x8e, 0xcb, 0x87, 0x3e, 0x62, 0x83, 0x00, 0xcb, + 0x17, 0x4a, 0x95, 0x37, 0x74, 0xcd, 0xa1, 0x58, 0x56, 0xa1, 0x62, 0x2b, + 0x88, 0xb1, 0xac, 0x4b, 0x12, 0xc4, 0xe5, 0xaf, 0xaf, 0x95, 0x2b, 0x55, + 0x05, 0x42, 0x85, 0xa2, 0x9c, 0xe4, 0xa0, 0x11, 0xbe, 0x14, 0x28, 0xcf, + 0x21, 0x68, 0xa0, 0x28, 0x58, 0x54, 0x28, 0x3d, 0xd3, 0xa8, 0x17, 0x7d, + 0xe5, 0x0b, 0x29, 0x1b, 0xbc, 0x9f, 0xf2, 0x9a, 0xc0, 0xdc, 0xe4, 0x4a, + 0x88, 0x4e, 0x64, 0xae, 0x11, 0x58, 0x1e, 0xb0, 0xbf, 0xb2, 0xc2, 0xfe, + 0xcb, 0x03, 0xbb, 0x2e, 0x1b, 0xbb, 0x2e, 0x1b, 0xca, 0x14, 0x4a, 0x6b, + 0x21, 0x45, 0xf6, 0x96, 0x54, 0x78, 0xfe, 0x91, 0x82, 0x85, 0x0f, 0x10, + 0xea, 0xf5, 0x41, 0x96, 0xaa, 0x67, 0xfa, 0x8f, 0x94, 0x5e, 0x4f, 0x45, + 0xaa, 0xf9, 0x96, 0x17, 0x2e, 0x19, 0x5c, 0x25, 0xc3, 0x6a, 0xc2, 0x2f, + 0x85, 0x1c, 0x90, 0x88, 0x84, 0x0e, 0x69, 0x5a, 0x28, 0x0b, 0x0a, 0xc2, + 0x54, 0x1b, 0xa5, 0x4a, 0x9f, 0x4f, 0x0b, 0x45, 0xa2, 0xd1, 0x68, 0xa4, + 0x76, 0x52, 0xa4, 0xa9, 0xe4, 0xca, 0x95, 0xa9, 0x41, 0xb7, 0x13, 0x78, + 0x2a, 0x79, 0x10, 0xa1, 0x42, 0x85, 0x05, 0x41, 0x5a, 0xad, 0x54, 0xa9, + 0x52, 0xa5, 0x4a, 0x95, 0x2a, 0x54, 0x85, 0x21, 0x48, 0x52, 0x14, 0x85, + 0x21, 0x48, 0x52, 0x14, 0x85, 0x21, 0x48, 0x52, 0xb1, 0x2c, 0x4b, 0x12, + 0x95, 0x2a, 0x54, 0xf3, 0x61, 0x42, 0x81, 0x94, 0x15, 0xba, 0x2d, 0x5a, + 0x85, 0x3c, 0xad, 0x6f, 0xd1, 0x68, 0xa0, 0x28, 0x0a, 0x2f, 0xff, 0x00, + 0x3e, 0xa2, 0x54, 0xe4, 0x85, 0x03, 0xba, 0x80, 0xbe, 0x55, 0xf2, 0xa9, + 0x6a, 0xc4, 0x16, 0x35, 0x8b, 0x34, 0xa9, 0x58, 0x96, 0x25, 0x89, 0x62, + 0x58, 0x96, 0x20, 0xb1, 0x05, 0x88, 0x29, 0x0a, 0x42, 0x90, 0xa4, 0x29, + 0x0a, 0x42, 0x90, 0xa4, 0x29, 0x0b, 0x45, 0xa2, 0xd1, 0x68, 0xb4, 0x5a, + 0x2d, 0x16, 0x8b, 0x45, 0xa2, 0xd1, 0x68, 0xb4, 0x5a, 0x2d, 0x16, 0x8b, + 0x45, 0x21, 0x48, 0x52, 0x14, 0x85, 0x21, 0x48, 0x52, 0x14, 0x85, 0x21, + 0x48, 0x52, 0x16, 0x20, 0xb1, 0x05, 0x88, 0x2c, 0x41, 0x62, 0x58, 0x96, + 0x25, 0x89, 0x4a, 0x9c, 0xd8, 0x96, 0x35, 0x88, 0x29, 0x0b, 0xe5, 0x5a, + 0x2d, 0x3b, 0xaf, 0xf2, 0xbf, 0xcf, 0xa7, 0xff, 0xc4, 0x00, 0x44, 0x10, + 0x00, 0x01, 0x02, 0x03, 0x03, 0x08, 0x07, 0x05, 0x06, 0x04, 0x07, 0x00, + 0x03, 0x00, 0x00, 0x00, 0x01, 0x00, 0x02, 0x03, 0x11, 0x21, 0x20, 0x31, + 0x32, 0x10, 0x12, 0x22, 0x30, 0x41, 0x51, 0x71, 0x91, 0x04, 0x13, 0x33, + 0x40, 0x61, 0x81, 0xa1, 0x23, 0x42, 0x52, 0x62, 0x72, 0x34, 0x50, 0x82, + 0x92, 0xb1, 0xd1, 0x60, 0xa2, 0xc1, 0xe1, 0x14, 0x24, 0x43, 0x53, 0x63, + 0x93, 0xf0, 0x70, 0x83, 0xc2, 0xff, 0xda, 0x00, 0x08, 0x01, 0x01, 0x00, + 0x06, 0x3f, 0x02, 0xfb, 0xfe, 0x8b, 0x62, 0xbc, 0x2a, 0xba, 0x4b, 0x19, + 0x5e, 0xf2, 0xb9, 0x61, 0x58, 0x16, 0x10, 0xb0, 0x05, 0x80, 0x72, 0x58, + 0x1b, 0xc9, 0x60, 0x6f, 0x25, 0x81, 0xbc, 0x96, 0x06, 0xf2, 0x58, 0x1b, + 0xc9, 0x61, 0x6f, 0x25, 0x84, 0x72, 0x58, 0x47, 0x25, 0x84, 0x72, 0x58, + 0x47, 0x25, 0x84, 0x72, 0x58, 0x47, 0x25, 0x84, 0x72, 0x58, 0x42, 0xc2, + 0x16, 0x10, 0xb0, 0x85, 0x84, 0x2c, 0x21, 0x61, 0x0b, 0x08, 0x58, 0x42, + 0xc2, 0x16, 0x10, 0xb0, 0x85, 0x84, 0x2c, 0x21, 0x61, 0x0b, 0x08, 0x58, + 0x42, 0xc2, 0x16, 0x10, 0xb0, 0x85, 0x84, 0x2c, 0x23, 0x92, 0xc2, 0x39, + 0x2c, 0x23, 0x92, 0xc2, 0xde, 0x4b, 0x0b, 0x79, 0x2c, 0x0d, 0xe4, 0xb0, + 0x37, 0x92, 0xc0, 0xde, 0x4b, 0x03, 0x79, 0x2c, 0x03, 0x92, 0xc0, 0x16, + 0x00, 0xb0, 0x2c, 0x2a, 0xe2, 0xaf, 0x2a, 0x8e, 0x55, 0x19, 0x6f, 0x57, + 0xe5, 0xbd, 0x5f, 0xf7, 0xc8, 0x0d, 0x2a, 0xb7, 0xfd, 0xff, 0x00, 0x9c, + 0xd9, 0x2c, 0xf6, 0x72, 0xfb, 0xfe, 0x70, 0xda, 0x5c, 0x46, 0xe4, 0x09, + 0x12, 0x3f, 0x78, 0x5e, 0xaf, 0xcb, 0x76, 0x5b, 0xd5, 0xea, 0xf5, 0x7a, + 0xbe, 0xd6, 0x70, 0xb8, 0xfd, 0xf3, 0x72, 0xd1, 0x82, 0xf7, 0x70, 0x6a, + 0xa7, 0x46, 0x89, 0xe6, 0x17, 0x61, 0x2e, 0x24, 0x2a, 0xf5, 0x63, 0xf1, + 0x29, 0x4e, 0x1c, 0xce, 0xd9, 0xff, 0x00, 0x65, 0x89, 0x8b, 0x1b, 0x57, + 0x69, 0xe8, 0xbb, 0x4f, 0x45, 0x8c, 0xf2, 0x58, 0xfd, 0x16, 0x3f, 0x45, + 0x8f, 0xd1, 0x63, 0x0b, 0x13, 0x56, 0xc5, 0x85, 0x60, 0x2b, 0x09, 0x57, + 0x77, 0xed, 0xea, 0x81, 0x5f, 0xdc, 0xc8, 0xef, 0x35, 0xef, 0x7e, 0xce, + 0x03, 0xdd, 0xe3, 0x25, 0xa7, 0x99, 0x0f, 0x89, 0x5e, 0xd3, 0xa4, 0x13, + 0xf4, 0x85, 0x50, 0xf7, 0xf1, 0x2a, 0x9d, 0x19, 0x9e, 0x62, 0x6b, 0x46, + 0x1b, 0x5b, 0xc0, 0x77, 0x4a, 0xb4, 0x15, 0x80, 0x2b, 0x88, 0x5a, 0x2e, + 0xe6, 0xa8, 0x27, 0xc1, 0x55, 0xb2, 0xee, 0xd5, 0x5a, 0x2a, 0xbd, 0xdf, + 0x8f, 0x7c, 0xb9, 0x61, 0x2b, 0x0a, 0xc2, 0xb0, 0xac, 0x27, 0x92, 0xc2, + 0x79, 0x2b, 0x8a, 0xbb, 0x57, 0xec, 0xa0, 0xbd, 0xfc, 0x02, 0xd3, 0xcd, + 0x82, 0x3c, 0x4a, 0x9c, 0x68, 0xae, 0x89, 0xe0, 0x28, 0xbd, 0x9c, 0x06, + 0x83, 0xbe, 0xf3, 0xf7, 0x06, 0x19, 0x70, 0x5a, 0x35, 0x55, 0x12, 0xee, + 0x5e, 0x2a, 0xbd, 0xe5, 0xbd, 0xdb, 0xd9, 0xc2, 0x7b, 0xf8, 0x05, 0xd9, + 0x66, 0x7d, 0x45, 0x69, 0xc5, 0x63, 0x78, 0x55, 0x69, 0x47, 0x71, 0xe0, + 0x17, 0xbc, 0x57, 0x66, 0xbb, 0x20, 0xbb, 0x16, 0x72, 0x5d, 0x93, 0x3f, + 0x2a, 0xec, 0xdb, 0xc9, 0x76, 0x7e, 0xab, 0xb3, 0xf5, 0x2b, 0xb3, 0xf5, + 0x2b, 0x07, 0xaa, 0xb9, 0xdc, 0xd5, 0xef, 0x54, 0x7f, 0xa2, 0xa3, 0xdb, + 0xf9, 0x55, 0x33, 0x0f, 0x9a, 0xc0, 0x79, 0x85, 0xa5, 0x1f, 0x35, 0xdf, + 0x4a, 0xd1, 0x8b, 0x0c, 0xf1, 0xa2, 0xd3, 0x8e, 0xd1, 0xc0, 0x4d, 0x7b, + 0x47, 0xbe, 0x27, 0xa2, 0xd0, 0xe8, 0xec, 0x9e, 0xf3, 0x5f, 0xb9, 0xa4, + 0x44, 0xd4, 0xe1, 0xf2, 0x52, 0x22, 0x5a, 0xdc, 0x43, 0x9a, 0xa3, 0x82, + 0x90, 0xbf, 0xbd, 0xb7, 0xb9, 0x4a, 0x14, 0x27, 0x3f, 0x80, 0x53, 0x88, + 0xf6, 0x42, 0xf0, 0xbc, 0xa9, 0xc5, 0x88, 0xe8, 0xbe, 0x02, 0x8b, 0xd9, + 0xc0, 0x60, 0xf1, 0x95, 0x7f, 0x80, 0x74, 0x84, 0xd5, 0x1d, 0x25, 0x88, + 0xab, 0xdc, 0xb0, 0x9e, 0x6b, 0x07, 0xaa, 0xc1, 0xea, 0xbb, 0x3f, 0x55, + 0xd9, 0xfa, 0xac, 0x1e, 0xaa, 0xe3, 0xcd, 0x3b, 0x34, 0xbf, 0x3b, 0x8a, + 0x88, 0x22, 0x92, 0x1c, 0x0c, 0xb3, 0x54, 0xb2, 0x5e, 0x5d, 0xe1, 0xde, + 0x7e, 0xc5, 0xd1, 0xff, 0x00, 0xea, 0x0b, 0xec, 0x3d, 0x1b, 0xfe, 0xa6, + 0xad, 0x2e, 0x81, 0xd1, 0xff, 0x00, 0xea, 0x0a, 0xbd, 0x02, 0x17, 0x95, + 0x17, 0xd8, 0x5b, 0xf9, 0xdd, 0xfb, 0xaa, 0x40, 0x74, 0x2f, 0xa2, 0x21, + 0xfe, 0xab, 0x46, 0x37, 0x48, 0x6f, 0x98, 0x3f, 0xd1, 0x7b, 0x1e, 0x9c, + 0xe1, 0xe0, 0xf8, 0x6b, 0xd9, 0xc7, 0x81, 0x10, 0x79, 0x85, 0xf6, 0x6e, + 0xb0, 0x6f, 0x86, 0x66, 0xa5, 0x1a, 0x0b, 0xe1, 0xfd, 0x4d, 0x95, 0xb9, + 0x34, 0x12, 0x77, 0x05, 0x38, 0xbe, 0xc1, 0xbe, 0x37, 0xaa, 0xb3, 0xad, + 0x76, 0xf7, 0xa9, 0x01, 0x21, 0xe1, 0xf7, 0x4d, 0xdf, 0x73, 0x99, 0xf4, + 0x53, 0x0e, 0x5e, 0xf7, 0xc4, 0x9a, 0x03, 0xb3, 0x87, 0xfb, 0x6d, 0x0b, + 0xac, 0x8b, 0xd6, 0xb4, 0xfc, 0x33, 0x5a, 0x3d, 0x1d, 0xa7, 0xea, 0xaa, + 0xec, 0xf3, 0x3e, 0x92, 0xbd, 0x9c, 0x52, 0x3e, 0xa0, 0xa8, 0x04, 0x41, + 0xf2, 0x95, 0xa6, 0xc7, 0x37, 0x88, 0xd5, 0xd0, 0x21, 0xd5, 0xf4, 0x48, + 0xa4, 0x1d, 0xb9, 0xb2, 0x0b, 0xda, 0x08, 0x70, 0x07, 0xcc, 0xe9, 0xfe, + 0x8b, 0xda, 0x74, 0xca, 0xfc, 0xac, 0x5a, 0x46, 0x34, 0x4f, 0xc4, 0xbe, + 0xcb, 0x3e, 0x2f, 0x77, 0xee, 0xbe, 0xc6, 0xdf, 0xcc, 0xef, 0xdd, 0x7d, + 0x89, 0x9e, 0x73, 0x54, 0xe8, 0x50, 0x3f, 0x20, 0x5f, 0x62, 0xe8, 0xff, + 0x00, 0xf5, 0x0d, 0x5c, 0x9c, 0xd0, 0xe1, 0xe2, 0x89, 0x7f, 0x44, 0x87, + 0x3f, 0x94, 0x49, 0x1e, 0xa5, 0xef, 0x82, 0x79, 0x84, 0x7a, 0xa7, 0xb2, + 0x30, 0xe4, 0x54, 0xa3, 0x41, 0x74, 0x3e, 0x21, 0x48, 0x09, 0x94, 0x1f, + 0xd2, 0x3d, 0x8b, 0x37, 0x7b, 0xca, 0x50, 0xa1, 0x80, 0x7e, 0x2d, 0xbf, + 0xc2, 0x70, 0x61, 0xf9, 0xa8, 0x74, 0xab, 0xab, 0x6a, 0x44, 0x4c, 0x78, + 0xae, 0xcf, 0x30, 0xef, 0x65, 0x11, 0x30, 0x1c, 0x22, 0x0d, 0xc6, 0x85, + 0x66, 0xc4, 0x61, 0x61, 0xf1, 0x16, 0x47, 0x57, 0xd1, 0xdc, 0xd6, 0x9f, + 0x7d, 0xf4, 0x0b, 0xfc, 0xc7, 0x4b, 0x6b, 0x7c, 0x21, 0xb6, 0x6b, 0x49, + 0xb1, 0x23, 0xfd, 0x6e, 0xfd, 0x94, 0xba, 0x3c, 0x06, 0x42, 0xfa, 0x47, + 0x78, 0x93, 0x80, 0x23, 0x71, 0x46, 0x2c, 0x38, 0x0d, 0x6b, 0xf7, 0x8f, + 0xe1, 0x56, 0x43, 0xe0, 0x13, 0x1b, 0xb8, 0x6a, 0x73, 0x22, 0xc3, 0x0f, + 0x6f, 0x8a, 0x2f, 0xe8, 0x6f, 0xcd, 0x3f, 0xed, 0xbf, 0xf7, 0x46, 0x1f, + 0xf8, 0x62, 0xc9, 0x5e, 0xe7, 0x99, 0x04, 0x1d, 0xd3, 0x23, 0x98, 0x87, + 0xe0, 0x87, 0x41, 0xcd, 0x7f, 0x97, 0xe8, 0xcc, 0x61, 0xf8, 0xa5, 0x33, + 0xcf, 0xf8, 0xca, 0x5b, 0x9d, 0xff, 0x00, 0xc0, 0x1d, 0x21, 0xfb, 0xa7, + 0xfc, 0x7e, 0x57, 0x4b, 0x89, 0xe3, 0x2f, 0xe1, 0x5b, 0xd5, 0xeb, 0x18, + 0xe6, 0xaf, 0x5b, 0x79, 0x2d, 0xbc, 0x96, 0xde, 0x4b, 0x6f, 0x25, 0xb7, + 0x92, 0xbd, 0x62, 0x1c, 0xfe, 0xe0, 0x88, 0x77, 0x34, 0xa8, 0xae, 0xf8, + 0x9f, 0xfc, 0x23, 0x7a, 0xb8, 0x95, 0xb0, 0x2c, 0x5c, 0x95, 0xe7, 0x9a, + 0xb8, 0x6a, 0xb0, 0x85, 0xb6, 0x7c, 0x55, 0x1c, 0x56, 0xc2, 0xae, 0x57, + 0xf3, 0xef, 0x51, 0xcf, 0xc8, 0x54, 0x3f, 0x12, 0x4f, 0xdf, 0x77, 0xf7, + 0x3a, 0x55, 0x6c, 0x0a, 0xb3, 0x2a, 0x82, 0x5d, 0xce, 0x99, 0x29, 0x3f, + 0x25, 0x2b, 0xd6, 0xed, 0x4e, 0x20, 0xb1, 0x85, 0x8b, 0xd1, 0x6d, 0x5b, + 0x54, 0xea, 0x15, 0xea, 0xff, 0x00, 0x45, 0x89, 0x62, 0x1c, 0xd5, 0xf6, + 0x23, 0xfd, 0x2b, 0xa3, 0x8f, 0x97, 0xef, 0x79, 0xac, 0xd0, 0x4c, 0xd6, + 0xdc, 0xdd, 0xe6, 0xf5, 0x79, 0x57, 0x73, 0x54, 0xa7, 0x05, 0xb7, 0x9d, + 0x89, 0xb6, 0xf5, 0x89, 0x6d, 0x57, 0x2a, 0xb5, 0x61, 0x57, 0xc9, 0x49, + 0x8e, 0x0e, 0xb1, 0xb9, 0x56, 0xba, 0xd1, 0x34, 0x40, 0xd9, 0xad, 0xf0, + 0x5b, 0xb8, 0x2a, 0x85, 0xa4, 0xf6, 0xb7, 0xea, 0x2b, 0xb7, 0x62, 0xa4, + 0x6c, 0xee, 0x01, 0x68, 0x32, 0x67, 0x8a, 0xf8, 0x55, 0x5c, 0xaf, 0xcb, + 0x72, 0x0b, 0xc1, 0x53, 0x2d, 0x15, 0xea, 0xf5, 0x30, 0xde, 0xb1, 0xa6, + 0xf0, 0xb3, 0x4b, 0x1c, 0xd7, 0x28, 0xb2, 0x50, 0x9b, 0x9c, 0x28, 0xd1, + 0xaa, 0xab, 0x96, 0x12, 0x57, 0x67, 0xea, 0xb4, 0x98, 0x47, 0x05, 0xa2, + 0xea, 0xee, 0xfb, 0x9b, 0x14, 0xf8, 0x2a, 0x31, 0xca, 0xa5, 0x8d, 0xe2, + 0xf0, 0xb3, 0x36, 0x6d, 0x70, 0xb9, 0x66, 0x4f, 0x34, 0x1f, 0x95, 0x01, + 0x6a, 0xb6, 0xa8, 0x15, 0x4a, 0xf6, 0x8e, 0x03, 0x89, 0x54, 0x8f, 0x0c, + 0x7e, 0x25, 0x28, 0x7d, 0x2c, 0x3f, 0xc3, 0x3a, 0x6b, 0x4d, 0x81, 0xc3, + 0x92, 0xf7, 0xa1, 0xf1, 0x0a, 0x60, 0x87, 0x0f, 0x0b, 0x5a, 0x4e, 0x0d, + 0xe2, 0x54, 0x8c, 0x66, 0xe7, 0x6e, 0x0a, 0x93, 0x2b, 0xdd, 0x1c, 0x5c, + 0xb3, 0x83, 0x9b, 0x9b, 0x39, 0x4c, 0x04, 0xe7, 0x02, 0xf7, 0x4b, 0x73, + 0x64, 0xa6, 0xd1, 0x11, 0xdf, 0x89, 0x61, 0x03, 0x8b, 0x96, 0x73, 0xa3, + 0x01, 0x24, 0x06, 0x7b, 0x1f, 0x9c, 0x27, 0x72, 0xec, 0xd9, 0xe4, 0xe2, + 0xb0, 0x99, 0xf8, 0x44, 0x53, 0x7b, 0x9e, 0xc1, 0xf5, 0x4d, 0x4c, 0x47, + 0x98, 0x58, 0xda, 0xe4, 0x27, 0x0b, 0x3f, 0xe9, 0xa2, 0xf7, 0x82, 0xa3, + 0xc7, 0x9d, 0x15, 0xf3, 0xe1, 0x64, 0xb6, 0x10, 0xeb, 0x5d, 0xbf, 0x62, + 0xac, 0x52, 0xd1, 0xb9, 0xb4, 0x55, 0x33, 0xb1, 0x27, 0x69, 0x05, 0x9c, + 0xdb, 0x25, 0x4d, 0x55, 0x78, 0x58, 0x9a, 0x06, 0x92, 0x22, 0x93, 0x09, + 0xae, 0x68, 0x9d, 0x67, 0x9a, 0x83, 0x44, 0x23, 0x08, 0x6d, 0x19, 0xd7, + 0xa9, 0x67, 0x94, 0x05, 0xc7, 0x82, 0xd1, 0x8f, 0x0d, 0xe7, 0x76, 0x7f, + 0xee, 0xb4, 0xa1, 0x13, 0xc0, 0x21, 0x9c, 0x0b, 0x55, 0x1c, 0x0e, 0x59, + 0x95, 0x7c, 0x85, 0x91, 0x25, 0x23, 0x5d, 0x6e, 0x7c, 0x27, 0x67, 0x36, + 0xe9, 0xe5, 0xa9, 0x03, 0x8a, 0xa1, 0x9e, 0xb3, 0x10, 0x54, 0x23, 0x2e, + 0x80, 0x73, 0xfe, 0x90, 0xb4, 0xdf, 0x0d, 0x9e, 0x13, 0xce, 0x3e, 0x8a, + 0x9d, 0x63, 0xbf, 0x94, 0x2a, 0x31, 0x83, 0x8d, 0x55, 0x62, 0xba, 0x5f, + 0x2d, 0x14, 0x9e, 0x73, 0x81, 0xda, 0xe2, 0x88, 0xde, 0x83, 0x76, 0x94, + 0xc8, 0x72, 0xda, 0x2c, 0xd7, 0x51, 0xd5, 0xb5, 0xb9, 0xf1, 0x3d, 0x02, + 0xac, 0x52, 0xd1, 0xb9, 0xb4, 0x53, 0x26, 0x67, 0x28, 0xd3, 0xcf, 0x67, + 0xc2, 0xe5, 0x9c, 0xd3, 0x51, 0x7b, 0x77, 0x29, 0x87, 0x16, 0x9d, 0xe1, + 0x48, 0x9e, 0xb0, 0x78, 0xde, 0xa4, 0x41, 0x86, 0xef, 0x99, 0x54, 0xcf, + 0x82, 0xf7, 0x59, 0xf5, 0x94, 0x73, 0x62, 0x93, 0xf4, 0x22, 0x61, 0x30, + 0x01, 0xf1, 0x3d, 0xcb, 0x4e, 0x3b, 0x58, 0x7e, 0x50, 0xaa, 0xf8, 0x91, + 0x4f, 0x8b, 0x96, 0x06, 0xb7, 0x8a, 0x10, 0xc8, 0x6b, 0xe1, 0x3c, 0xd3, + 0xea, 0x59, 0xac, 0x90, 0x6e, 0xe0, 0x14, 0x56, 0x6f, 0xd3, 0x0b, 0x3a, + 0xa4, 0x78, 0x15, 0x3c, 0xea, 0x6c, 0xd2, 0x4d, 0xae, 0xc4, 0xe6, 0x89, + 0xd2, 0x93, 0xce, 0x54, 0x7c, 0xbc, 0xd6, 0x9b, 0xa6, 0x13, 0x5a, 0xa6, + 0xe6, 0x4e, 0x9b, 0x55, 0x05, 0x7c, 0x0a, 0xd2, 0x57, 0xcb, 0x81, 0x4d, + 0x02, 0x2e, 0x6b, 0x8e, 0xc9, 0x7e, 0xca, 0xba, 0x7c, 0x2a, 0xae, 0xaf, + 0x82, 0x19, 0x8c, 0x2e, 0xe3, 0x45, 0x1a, 0x6e, 0xcd, 0x12, 0xb9, 0xba, + 0x89, 0x6c, 0x39, 0x6f, 0x54, 0xc8, 0xe6, 0xdb, 0xce, 0xda, 0xda, 0xa7, + 0x09, 0xce, 0x4b, 0xcd, 0x4d, 0xa0, 0x79, 0x89, 0xa9, 0xe6, 0xca, 0x7b, + 0x1a, 0xa8, 0x56, 0x83, 0xdc, 0xce, 0x06, 0x4b, 0x4c, 0xb6, 0x2b, 0x7f, + 0xe4, 0x6c, 0xd6, 0x9c, 0x17, 0xc2, 0xf1, 0x84, 0xef, 0xe8, 0x57, 0xb0, + 0xe9, 0x6c, 0x27, 0xe0, 0x8b, 0xa0, 0x7d, 0x68, 0xbf, 0xcc, 0x74, 0x77, + 0x34, 0x7c, 0x52, 0xa7, 0x3b, 0x90, 0xcc, 0x35, 0x9d, 0xd6, 0xdb, 0xac, + 0xcf, 0x88, 0xec, 0xd6, 0xef, 0xb3, 0xa7, 0xa7, 0xf5, 0x00, 0x89, 0x05, + 0xbe, 0x53, 0x6f, 0xf5, 0x5a, 0x33, 0x3f, 0x4b, 0xe7, 0xfa, 0x85, 0xa7, + 0x0d, 0xfe, 0x70, 0xe7, 0xea, 0x15, 0xcd, 0x27, 0xc1, 0xdf, 0xba, 0xd2, + 0x0e, 0x60, 0xde, 0x45, 0x16, 0x8b, 0x83, 0xb8, 0x6a, 0x2f, 0x53, 0x64, + 0x26, 0x38, 0xed, 0x7b, 0xf4, 0x8f, 0x2b, 0x97, 0xb4, 0x8a, 0xe7, 0x37, + 0x76, 0xce, 0x4a, 0xe5, 0xb1, 0x57, 0x24, 0x95, 0xf5, 0x4d, 0x32, 0x05, + 0xca, 0x20, 0x35, 0xb8, 0xe4, 0xae, 0x5d, 0xe8, 0xdb, 0x8d, 0xf5, 0x5a, + 0xd1, 0xf8, 0x56, 0x91, 0xc9, 0x5b, 0xb7, 0x27, 0x0a, 0x89, 0xfc, 0x24, + 0xd1, 0x75, 0x9d, 0x1e, 0x29, 0x79, 0xf8, 0x22, 0x9d, 0x2e, 0x7f, 0xba, + 0xea, 0xa3, 0xc3, 0x74, 0x18, 0x83, 0x7e, 0xd4, 0x48, 0x34, 0x34, 0x73, + 0x77, 0xa9, 0xde, 0xd3, 0x75, 0x64, 0xb0, 0x80, 0xb4, 0x68, 0xe3, 0xb4, + 0x2c, 0xc6, 0x89, 0x52, 0x54, 0x08, 0x0c, 0xc3, 0x9c, 0x98, 0x48, 0x20, + 0xe1, 0xe6, 0xa4, 0xd0, 0x88, 0x34, 0x06, 0xa8, 0x2a, 0x35, 0x4c, 0xf9, + 0xa0, 0xd3, 0xb2, 0xb9, 0x2e, 0x98, 0xb9, 0x69, 0x5f, 0xe2, 0x10, 0x33, + 0x6c, 0xb6, 0x4d, 0x1a, 0xe7, 0x4e, 0xe0, 0x06, 0xd5, 0xec, 0xda, 0x62, + 0xc6, 0x3f, 0x0e, 0xc5, 0x9f, 0xd3, 0x22, 0x91, 0x2a, 0xf5, 0x6c, 0xfe, + 0xa5, 0x38, 0x31, 0x92, 0xae, 0x48, 0xdf, 0x49, 0xd4, 0x33, 0x25, 0xf6, + 0x1b, 0x6e, 0x23, 0x77, 0x84, 0xec, 0xca, 0xd3, 0xfa, 0x21, 0xc5, 0x5f, + 0x24, 0xe0, 0x5f, 0x9d, 0x2d, 0xa2, 0xc5, 0x14, 0xdd, 0xc9, 0x7b, 0x08, + 0xef, 0x87, 0xe0, 0x0d, 0x39, 0x22, 0x1f, 0xd1, 0xe1, 0x32, 0x28, 0x13, + 0xeb, 0x21, 0x8c, 0xd9, 0xf1, 0x17, 0x5b, 0x6a, 0xf6, 0x8f, 0x0c, 0xe2, + 0x55, 0x33, 0x9d, 0xc0, 0x2d, 0x08, 0x5a, 0x3b, 0xe7, 0x3f, 0xd1, 0x69, + 0x73, 0x03, 0x51, 0x2d, 0xab, 0x35, 0xb7, 0x6e, 0x21, 0x56, 0x1c, 0x33, + 0xc4, 0x2a, 0xc1, 0x6f, 0xe1, 0xa2, 0x99, 0x81, 0x13, 0xca, 0x39, 0x54, + 0x64, 0x56, 0xf0, 0x70, 0xfd, 0x91, 0xd2, 0xe9, 0x23, 0xcd, 0x87, 0xff, + 0x00, 0xca, 0xfb, 0x54, 0x51, 0xf5, 0xc1, 0x69, 0xfd, 0x17, 0xda, 0x3a, + 0x3b, 0xf8, 0xb5, 0xcc, 0xfd, 0xd4, 0xa2, 0x41, 0x85, 0x1b, 0xe9, 0x88, + 0xd7, 0x7e, 0xaa, 0x6d, 0x83, 0xd2, 0x20, 0x9f, 0xf8, 0xe6, 0xa3, 0x30, + 0x03, 0x20, 0xea, 0x19, 0xc8, 0xaa, 0x46, 0x70, 0xf0, 0x78, 0x5a, 0x4c, + 0x11, 0x1b, 0xbd, 0xab, 0x48, 0x16, 0xa9, 0x31, 0xd3, 0xa4, 0xec, 0xbb, + 0x85, 0x8a, 0x2a, 0x95, 0x7e, 0x46, 0xb7, 0x6c, 0xe9, 0x25, 0xd2, 0x1f, + 0xb4, 0x64, 0xde, 0x72, 0xef, 0xd4, 0x44, 0x3f, 0x31, 0xb4, 0xe3, 0xf2, + 0x58, 0xa8, 0x9a, 0xa4, 0x10, 0xba, 0xb8, 0xdd, 0x14, 0x45, 0x66, 0xe9, + 0x27, 0x3f, 0xa2, 0x6c, 0xaf, 0x56, 0xf3, 0xfd, 0x53, 0xa1, 0x47, 0x86, + 0xe6, 0xec, 0x73, 0x0d, 0xeb, 0x7b, 0x51, 0xd1, 0x0a, 0x6d, 0x61, 0x46, + 0x67, 0x31, 0xe4, 0xcd, 0xad, 0x4e, 0xce, 0x6f, 0xf3, 0x20, 0xe0, 0xca, + 0x71, 0x2a, 0xe6, 0x9e, 0x69, 0xba, 0x2c, 0xaf, 0xfe, 0xde, 0xbd, 0xd1, + 0xcd, 0x7b, 0x87, 0xcd, 0x4f, 0x34, 0x0d, 0x97, 0xaa, 0x37, 0xd5, 0x61, + 0x3e, 0x4a, 0x5b, 0x10, 0x0d, 0x87, 0xd6, 0x38, 0xd0, 0x34, 0x21, 0x1f, + 0xa7, 0x7b, 0x16, 0x9f, 0xf4, 0xd8, 0x6a, 0xba, 0xae, 0x8c, 0xc0, 0xc6, + 0x05, 0x26, 0x99, 0xef, 0xcb, 0x13, 0xe9, 0x3a, 0x86, 0x71, 0xb5, 0x3d, + 0xc6, 0xd5, 0x55, 0x14, 0x60, 0xf7, 0xf5, 0x6b, 0x39, 0xb1, 0x44, 0x4a, + 0xa2, 0x9d, 0xc6, 0xdb, 0xbe, 0x9b, 0x6d, 0x5d, 0x64, 0x58, 0xa4, 0xed, + 0xf8, 0x42, 0x1d, 0x48, 0x6c, 0x47, 0x0d, 0xb0, 0xda, 0x62, 0x1e, 0x6a, + 0x6e, 0x84, 0xe8, 0x6d, 0xf8, 0xa2, 0x10, 0x07, 0xea, 0x8e, 0x7c, 0x68, + 0x20, 0xec, 0xcc, 0x7e, 0x7a, 0xc6, 0x62, 0x1d, 0xec, 0x64, 0xbf, 0x55, + 0x26, 0xb1, 0xef, 0xf1, 0x75, 0x15, 0x21, 0xf3, 0x74, 0xd5, 0xc1, 0x6c, + 0x5b, 0x16, 0xe4, 0x5a, 0x5d, 0xa2, 0x75, 0x6d, 0x74, 0xe4, 0x1c, 0x37, + 0x2b, 0xc2, 0x9e, 0xdd, 0xe0, 0xad, 0x99, 0xdb, 0xc8, 0xaa, 0x8a, 0x0b, + 0xb4, 0x65, 0x86, 0xcb, 0xb8, 0x58, 0xbd, 0x56, 0x7e, 0x6e, 0x92, 0xa9, + 0x6f, 0xea, 0xaf, 0x1c, 0x94, 0x16, 0xb4, 0x19, 0x97, 0x85, 0x1d, 0xdb, + 0xde, 0x56, 0xed, 0x61, 0xb4, 0xff, 0x00, 0xa6, 0xc5, 0xc0, 0xaa, 0x89, + 0x79, 0x2a, 0x55, 0x4a, 0x18, 0x0c, 0x1f, 0x11, 0x45, 0xb1, 0x9b, 0xd6, + 0x3b, 0xe2, 0x75, 0xe9, 0xee, 0xe8, 0xe0, 0xf4, 0x88, 0x1c, 0x26, 0xe6, + 0xfe, 0xe8, 0xcc, 0x01, 0xe4, 0x8c, 0xa6, 0x4a, 0x1b, 0xc6, 0x48, 0xb0, + 0x83, 0xa9, 0x3b, 0x94, 0xe8, 0xb1, 0x29, 0x67, 0x51, 0x5e, 0x82, 0xa2, + 0xb9, 0x68, 0x34, 0xb6, 0x1c, 0xeb, 0x15, 0xd7, 0x20, 0x58, 0x33, 0xe3, + 0xca, 0xb1, 0x1c, 0x8b, 0x4d, 0xc8, 0x97, 0x0a, 0xc9, 0x53, 0x9a, 0xcd, + 0x19, 0x22, 0x7d, 0x27, 0x50, 0xce, 0x36, 0x9e, 0x85, 0xb7, 0x45, 0x67, + 0x2d, 0xa9, 0xd9, 0x26, 0x40, 0x1c, 0x2d, 0xbb, 0xe9, 0xb6, 0x13, 0xc3, + 0x61, 0xc2, 0x6c, 0x8e, 0x2c, 0xc9, 0x9f, 0x55, 0x27, 0x74, 0x88, 0x92, + 0xdc, 0x1d, 0x45, 0x5a, 0xf7, 0x48, 0x71, 0x3e, 0x17, 0x4a, 0xc7, 0x48, + 0xe0, 0x2c, 0x9d, 0x44, 0x29, 0xdc, 0x08, 0xbb, 0x8a, 0x27, 0x38, 0x9f, + 0x09, 0xab, 0xac, 0x9b, 0x4f, 0x3e, 0x16, 0xe2, 0x70, 0xb3, 0x7a, 0x9b, + 0x8a, 0x93, 0x68, 0xdc, 0xae, 0x8d, 0x03, 0xfc, 0xbf, 0x49, 0xdf, 0xb0, + 0xf1, 0x5d, 0x4f, 0x49, 0x69, 0x6b, 0xb6, 0x11, 0x71, 0x5b, 0x72, 0x48, + 0x09, 0x67, 0x04, 0x66, 0x15, 0x1b, 0x55, 0x70, 0x9a, 0xba, 0xf5, 0xfd, + 0xd6, 0x6b, 0x1a, 0x4b, 0x8e, 0xc0, 0x9b, 0x1f, 0xa7, 0x37, 0x35, 0xbb, + 0x21, 0xfe, 0xe9, 0xad, 0x86, 0xd0, 0xc6, 0x6e, 0x19, 0x04, 0xd5, 0xce, + 0x71, 0x54, 0x95, 0xc8, 0x92, 0x25, 0x3c, 0x91, 0x3e, 0x93, 0xa8, 0x6f, + 0x1b, 0x45, 0x0b, 0x74, 0xa5, 0x02, 0x76, 0xa5, 0xdf, 0x4d, 0xb0, 0xa2, + 0x7d, 0x47, 0xbb, 0x47, 0x1f, 0x2c, 0xec, 0x74, 0x8f, 0x2b, 0x27, 0x50, + 0xcd, 0xdf, 0xf8, 0xa9, 0xeb, 0x22, 0xfd, 0x26, 0xdc, 0x5e, 0x1a, 0xb3, + 0x0b, 0xa4, 0xc3, 0xeb, 0x06, 0xc3, 0xb9, 0x3a, 0x27, 0x42, 0x3f, 0xe2, + 0x21, 0x7c, 0x07, 0x10, 0xfd, 0xd6, 0x69, 0x86, 0xf0, 0xe1, 0x78, 0x92, + 0x6b, 0x84, 0x27, 0x99, 0x1d, 0xcb, 0x43, 0xa3, 0x45, 0x3f, 0x85, 0x4c, + 0xf4, 0x58, 0x9f, 0x95, 0x57, 0xa3, 0xbf, 0xf2, 0xaa, 0xc1, 0x7f, 0x24, + 0x59, 0x0e, 0x0b, 0xa7, 0xbd, 0xd4, 0x4d, 0xce, 0xf6, 0xb1, 0xce, 0x27, + 0x1b, 0x13, 0x7c, 0xd6, 0x80, 0xcc, 0x6a, 0xc3, 0x55, 0x2b, 0xf2, 0x3f, + 0x86, 0xb8, 0xa1, 0x6d, 0xa7, 0xe5, 0x1f, 0xd5, 0x66, 0xc4, 0x7f, 0x56, + 0x0f, 0xbd, 0x25, 0x0d, 0xae, 0x2d, 0x70, 0xeb, 0x07, 0x02, 0xa3, 0x66, + 0x48, 0x37, 0x3c, 0xca, 0x56, 0xaa, 0x13, 0xe4, 0x25, 0xa3, 0x6c, 0x28, + 0x9c, 0x7b, 0xb1, 0x69, 0xb8, 0xa7, 0x30, 0xde, 0xd3, 0x2c, 0xbd, 0x20, + 0xf0, 0xb4, 0x6d, 0xb0, 0xc3, 0xbc, 0x4e, 0x53, 0xe0, 0x9c, 0x33, 0x65, + 0x23, 0x62, 0xf4, 0x2a, 0x6d, 0xc5, 0xe1, 0x6e, 0x2f, 0x96, 0xb3, 0x48, + 0x4f, 0xc1, 0x7f, 0x8e, 0xe8, 0xce, 0x74, 0x27, 0x36, 0x40, 0xb2, 0x78, + 0x96, 0x6f, 0x5a, 0xf1, 0xe6, 0xa5, 0xd6, 0xbb, 0x9a, 0xed, 0x1c, 0xa5, + 0xd6, 0x3a, 0x4b, 0xa2, 0xc0, 0x89, 0x10, 0x86, 0x3e, 0x20, 0x69, 0xe6, + 0x9b, 0x0e, 0x1b, 0x43, 0x1b, 0x70, 0x01, 0x13, 0x92, 0xfc, 0x93, 0xcd, + 0x9a, 0xaf, 0x20, 0x9d, 0xc4, 0xe5, 0x77, 0x04, 0x75, 0x02, 0xc9, 0x42, + 0xdc, 0x36, 0x36, 0xf6, 0xb0, 0x67, 0x7a, 0xa7, 0x50, 0x1e, 0x22, 0x69, + 0xae, 0x3f, 0x12, 0x71, 0xf1, 0xb6, 0xff, 0x00, 0xa7, 0x50, 0xfe, 0x3d, + 0xde, 0x37, 0x89, 0xce, 0xcb, 0x1b, 0xea, 0xb4, 0x6d, 0xc7, 0xeb, 0x58, + 0xce, 0xb3, 0x36, 0x4d, 0x9d, 0xe5, 0x44, 0x95, 0xd9, 0xd6, 0x45, 0x15, + 0xd6, 0xa2, 0x5b, 0x8b, 0xe5, 0xac, 0x9b, 0x90, 0x95, 0x33, 0xe2, 0x86, + 0x8b, 0x30, 0x22, 0x7c, 0x2f, 0x05, 0x4f, 0xc2, 0xd5, 0x4c, 0xbc, 0x13, + 0xf8, 0xe5, 0x72, 0x3a, 0x86, 0xf0, 0xb2, 0xee, 0x08, 0x5a, 0x9a, 0x8d, + 0xe4, 0x9c, 0x8e, 0xa1, 0xff, 0x00, 0x4d, 0xb0, 0x9d, 0xdd, 0xe1, 0xbf, + 0xe2, 0x6c, 0xb2, 0xc4, 0xfa, 0xed, 0x3b, 0x8d, 0xb8, 0x50, 0xbe, 0x32, + 0x1b, 0xcc, 0xa8, 0xad, 0xdc, 0xeb, 0x21, 0x5f, 0x69, 0xdc, 0x45, 0xb8, + 0x9e, 0x59, 0x05, 0x89, 0xda, 0x96, 0xc5, 0xd1, 0x21, 0xff, 0x00, 0xc9, + 0x3f, 0x4b, 0x07, 0x8e, 0x4e, 0x8c, 0xe6, 0xff, 0x00, 0xa8, 0xc0, 0xeb, + 0x54, 0xa2, 0x71, 0xf1, 0x55, 0x08, 0xa2, 0x8e, 0xa1, 0x9c, 0x2c, 0xbb, + 0x82, 0x15, 0xb7, 0x9d, 0xb4, 0xa7, 0xa3, 0xa8, 0x7f, 0xd3, 0xa8, 0x3d, + 0xde, 0x1b, 0xbe, 0x17, 0x65, 0x77, 0xd7, 0x69, 0xdc, 0x6c, 0x00, 0xa4, + 0xd1, 0xe6, 0x55, 0xc0, 0xa8, 0x11, 0xfd, 0xd6, 0x90, 0xe2, 0x38, 0x10, + 0x99, 0x9b, 0x5e, 0xb2, 0x1b, 0x22, 0x73, 0x68, 0x36, 0x2f, 0x58, 0xad, + 0xfe, 0x2b, 0x71, 0x2d, 0xd1, 0x11, 0x67, 0xa2, 0x35, 0xce, 0x23, 0x35, + 0xae, 0x2d, 0x96, 0xdb, 0xac, 0x1e, 0x39, 0x3a, 0x1c, 0xbe, 0x09, 0x5b, + 0x3c, 0x72, 0x11, 0x91, 0xdc, 0x75, 0x10, 0xf8, 0x59, 0x96, 0xa0, 0x38, + 0x02, 0x69, 0x5a, 0x5d, 0x55, 0xd2, 0x1b, 0x18, 0xe6, 0xb4, 0xb2, 0xff, + 0x00, 0x14, 0x75, 0x0e, 0xfa, 0x6d, 0x8e, 0xf1, 0x11, 0x82, 0xf9, 0x4c, + 0x65, 0x6f, 0x12, 0x89, 0x36, 0x5f, 0xc6, 0xc3, 0x65, 0x7c, 0xf2, 0xbc, + 0xec, 0xcd, 0x3f, 0xd1, 0x43, 0xce, 0x7c, 0xdc, 0x1a, 0x07, 0xa5, 0x93, + 0x5b, 0x6d, 0xfa, 0xad, 0xc4, 0xe3, 0xa9, 0xe3, 0x63, 0xa1, 0x3f, 0x79, + 0x78, 0x9f, 0xe5, 0xcb, 0x29, 0x79, 0xa2, 0x3c, 0x50, 0x5d, 0x1a, 0x54, + 0x95, 0x35, 0x1e, 0x2a, 0x7b, 0x4e, 0x47, 0xf1, 0xd4, 0x32, 0xc8, 0xb6, + 0xd3, 0x20, 0x65, 0x59, 0x11, 0x42, 0x9e, 0xd9, 0x36, 0x47, 0x4a, 0x5b, + 0xb8, 0x27, 0x6a, 0x5d, 0xf4, 0xdb, 0x1d, 0xe5, 0xf2, 0xc2, 0xed, 0x21, + 0x91, 0xbc, 0x4d, 0xa7, 0x71, 0xca, 0x10, 0xf0, 0x04, 0xa3, 0x92, 0x2d, + 0x56, 0x70, 0xa9, 0xb9, 0xd6, 0x4d, 0xb6, 0x71, 0xb6, 0xfe, 0x3a, 0xde, + 0x88, 0xcd, 0x83, 0x38, 0xfe, 0x99, 0x4a, 0x06, 0x1b, 0x33, 0x25, 0x7d, + 0x67, 0x33, 0x92, 0x07, 0x9f, 0xeb, 0x6d, 0xfc, 0x55, 0x72, 0xc4, 0xe3, + 0xa8, 0x6d, 0xa3, 0x4a, 0x5b, 0xff, 0x00, 0xdb, 0xd3, 0xb5, 0x27, 0xe9, + 0xd4, 0x79, 0x77, 0x86, 0xc5, 0x17, 0xc3, 0x3e, 0x99, 0x1b, 0xc4, 0xda, + 0x7f, 0x1c, 0xa1, 0x44, 0x97, 0xc3, 0x24, 0x7d, 0xac, 0x3e, 0x6b, 0xb5, + 0x87, 0xcd, 0x39, 0xa6, 0x44, 0x9a, 0xcc, 0x2e, 0x93, 0x04, 0x9a, 0x51, + 0xc0, 0x22, 0x36, 0x58, 0xc4, 0xaf, 0xb5, 0x0e, 0xdb, 0xf8, 0xeb, 0x60, + 0x3b, 0x60, 0x98, 0xcb, 0xe6, 0xa5, 0x92, 0x1f, 0x81, 0x36, 0xe2, 0x79, + 0x58, 0x89, 0xf5, 0x1d, 0x43, 0x6c, 0x84, 0x77, 0x5b, 0xf2, 0xfe, 0xa8, + 0xa1, 0xa8, 0xfc, 0x3a, 0x81, 0xc3, 0xbc, 0x3d, 0x86, 0xe7, 0x09, 0x27, + 0x31, 0xd4, 0x20, 0xc9, 0x33, 0xce, 0xd3, 0xf8, 0xe5, 0x0a, 0x21, 0xde, + 0xe6, 0x84, 0x72, 0x44, 0x9e, 0xc0, 0x02, 0x1b, 0x9d, 0xa2, 0xbc, 0x75, + 0x70, 0xbc, 0xed, 0xbb, 0x8e, 0xb6, 0x1b, 0x7e, 0x1f, 0xd8, 0x7e, 0xf9, + 0x4f, 0x1c, 0xbf, 0x4b, 0xe5, 0x2b, 0x67, 0x85, 0x88, 0xbf, 0x51, 0xd4, + 0x36, 0xc8, 0xde, 0x51, 0x08, 0xd9, 0x7b, 0x97, 0x92, 0x28, 0x6a, 0x3f, + 0x0e, 0xa0, 0x70, 0xef, 0x23, 0xa4, 0x34, 0x78, 0x39, 0x43, 0xf3, 0xfd, + 0x6d, 0x3b, 0x8d, 0x86, 0xf8, 0xc4, 0x55, 0xcf, 0x9a, 0xbd, 0xea, 0x2f, + 0x56, 0x49, 0xba, 0xf5, 0x9c, 0x2f, 0x04, 0x14, 0xc8, 0x8d, 0x17, 0x89, + 0xac, 0xed, 0x87, 0x29, 0xb7, 0x0b, 0xce, 0xdb, 0xb8, 0xea, 0x0d, 0x97, + 0x1f, 0xf9, 0x1c, 0x3f, 0x4c, 0xbe, 0x79, 0x7a, 0x54, 0x3d, 0xd2, 0x75, + 0xba, 0xee, 0xb1, 0x17, 0xea, 0xd4, 0x32, 0xc4, 0xd3, 0x46, 0xe4, 0x65, + 0x6a, 0x5f, 0x13, 0xda, 0x3d, 0x57, 0x92, 0x28, 0x6a, 0x07, 0x0d, 0x43, + 0x78, 0x77, 0x97, 0x43, 0x76, 0x17, 0x09, 0x26, 0xc3, 0x75, 0xe2, 0x7f, + 0xad, 0xa7, 0xf1, 0xb1, 0x04, 0x71, 0x28, 0x99, 0x2c, 0x2a, 0x34, 0xc6, + 0xd6, 0xa7, 0x12, 0x09, 0xb9, 0x01, 0xb9, 0x78, 0x15, 0x2c, 0x86, 0xdc, + 0x2f, 0x3b, 0x67, 0x8e, 0x41, 0xaa, 0x2b, 0x3f, 0xe2, 0x8b, 0x14, 0xfa, + 0xe5, 0x28, 0xbb, 0x24, 0x48, 0x7b, 0x1d, 0x0a, 0x76, 0xfc, 0xb2, 0x95, + 0x17, 0x8e, 0xa1, 0x9c, 0x2c, 0x4d, 0x4d, 0x39, 0x0c, 0x92, 0xcb, 0xd1, + 0x61, 0xfc, 0xd3, 0x5e, 0x48, 0xa1, 0xa8, 0x67, 0x0d, 0x43, 0x78, 0x77, + 0xa9, 0x5a, 0x7d, 0x86, 0x8f, 0x05, 0x20, 0xea, 0x2c, 0x5e, 0x81, 0x3e, + 0x75, 0x33, 0x68, 0x4f, 0x73, 0x84, 0x93, 0xa0, 0x93, 0x29, 0x89, 0xa2, + 0xd5, 0x23, 0x78, 0xc8, 0x6d, 0xc2, 0xb7, 0xf8, 0xb5, 0x02, 0xc3, 0xbe, + 0x56, 0x92, 0xa0, 0xc3, 0xcf, 0xa1, 0x24, 0x67, 0x49, 0x68, 0x97, 0x17, + 0x6f, 0x21, 0x50, 0x81, 0xe4, 0xbb, 0x40, 0xa6, 0x5c, 0x0f, 0x92, 0x39, + 0xd3, 0xe2, 0x14, 0x38, 0x9e, 0xe9, 0xd1, 0x27, 0x54, 0x54, 0x4d, 0x43, + 0x78, 0x58, 0x96, 0x42, 0x72, 0xcf, 0x24, 0xd4, 0x36, 0xfc, 0x39, 0xa1, + 0x49, 0x12, 0x9b, 0xa8, 0x87, 0xff, 0x00, 0xb6, 0x6a, 0x1b, 0xf7, 0x03, + 0x88, 0x14, 0x57, 0x2c, 0x25, 0x68, 0xc3, 0x73, 0xa5, 0xb9, 0x76, 0x6f, + 0xe4, 0xbb, 0x18, 0xa4, 0x7d, 0x2b, 0xec, 0xee, 0x1f, 0x80, 0xa9, 0x3a, + 0x86, 0x63, 0xc1, 0x69, 0x28, 0x4f, 0x9d, 0x27, 0x54, 0x64, 0x43, 0xb7, + 0xc9, 0x78, 0x85, 0xe0, 0x8d, 0xb8, 0x56, 0xfc, 0xf2, 0x0d, 0x51, 0x1e, + 0xf3, 0xe8, 0xba, 0x34, 0x37, 0x35, 0xf2, 0x2f, 0x9e, 0x76, 0x6e, 0x13, + 0x35, 0x71, 0x55, 0x12, 0xc9, 0x1c, 0xb1, 0xb3, 0x71, 0x93, 0x5a, 0x3c, + 0x36, 0xa0, 0xd7, 0x33, 0x88, 0x2a, 0x71, 0x21, 0xc4, 0x6c, 0x4c, 0xfa, + 0x6c, 0x01, 0x07, 0x8b, 0x8d, 0xaf, 0x1b, 0x0f, 0xd4, 0x0b, 0x12, 0x41, + 0xa8, 0xd9, 0xce, 0x3b, 0x04, 0xd7, 0x5f, 0x14, 0xe9, 0x17, 0xe7, 0x06, + 0x84, 0xd3, 0x82, 0x95, 0x28, 0x86, 0x10, 0xe2, 0x10, 0x6b, 0x84, 0x8d, + 0xba, 0x34, 0x95, 0x0a, 0x6d, 0x96, 0xa0, 0x7d, 0xc1, 0x72, 0xdd, 0x93, + 0x31, 0x94, 0x6e, 0xdf, 0x14, 0x00, 0x88, 0xd7, 0x4c, 0x4e, 0x8b, 0x18, + 0x5d, 0xa7, 0xaa, 0x3d, 0x6e, 0x74, 0xe7, 0x88, 0x29, 0xb5, 0xf9, 0xf2, + 0xde, 0x9a, 0x08, 0x4e, 0x68, 0x97, 0x5a, 0xc3, 0x5f, 0x11, 0x93, 0xc1, + 0x56, 0xed, 0xf6, 0xe1, 0x79, 0xdb, 0xf3, 0xd5, 0xcc, 0xd1, 0x67, 0x9c, + 0x23, 0x08, 0x53, 0x0c, 0x68, 0x77, 0x05, 0x32, 0x24, 0xae, 0x57, 0x2c, + 0x21, 0x16, 0xb2, 0x13, 0x4b, 0x89, 0x1f, 0xaa, 0xc2, 0xde, 0x48, 0xb5, + 0xfd, 0x99, 0xb8, 0xee, 0x52, 0xe5, 0x66, 0x6a, 0x63, 0x21, 0xd6, 0xe7, + 0x15, 0x3f, 0x78, 0xda, 0x6c, 0x36, 0x9d, 0x16, 0x9d, 0x2f, 0x15, 0xd6, + 0x49, 0xce, 0x3c, 0x28, 0xb4, 0x84, 0x9c, 0xb1, 0x91, 0xc1, 0x03, 0x32, + 0xef, 0x12, 0xab, 0x03, 0x90, 0x92, 0x15, 0x2d, 0xfe, 0x88, 0x06, 0xc5, + 0x6b, 0xa7, 0xb9, 0x69, 0x67, 0xf9, 0x05, 0x74, 0xf8, 0xaa, 0x34, 0x0f, + 0x2c, 0x8c, 0xa4, 0xb5, 0x03, 0x59, 0x78, 0xd7, 0x1b, 0x6c, 0x6b, 0xaf, + 0x6d, 0xcb, 0xc4, 0xe4, 0x9e, 0x72, 0xbc, 0xe4, 0x94, 0xe8, 0xb3, 0x83, + 0xaa, 0x9b, 0x9c, 0xd6, 0xbc, 0x78, 0xa8, 0x1d, 0x37, 0xa1, 0xce, 0x10, + 0x7e, 0x26, 0x7c, 0x25, 0x75, 0x82, 0x87, 0x72, 0x91, 0xb9, 0x6f, 0x0b, + 0xc2, 0xd4, 0x31, 0xe1, 0x6c, 0x71, 0xc8, 0x2d, 0xd2, 0x6a, 0x53, 0xcf, + 0x7f, 0x82, 0x9b, 0xb9, 0x6a, 0xa9, 0x76, 0xe5, 0x27, 0xd3, 0xc4, 0xd8, + 0x97, 0x85, 0x81, 0xc3, 0x50, 0x32, 0xcf, 0x62, 0x92, 0x0e, 0x36, 0xbc, + 0xd1, 0x6a, 0x0e, 0x91, 0x58, 0x54, 0x85, 0xca, 0x8f, 0x70, 0xf3, 0x40, + 0x00, 0xe2, 0xe1, 0x89, 0xdb, 0x32, 0x51, 0xc5, 0x3b, 0x3c, 0x87, 0xbc, + 0x7b, 0xa5, 0xab, 0x4a, 0x00, 0xfc, 0x26, 0x48, 0xe6, 0x89, 0x35, 0x37, + 0x50, 0x35, 0x77, 0xe4, 0x12, 0xbb, 0x72, 0xa1, 0xd6, 0x1b, 0x7a, 0x26, + 0x8a, 0xb6, 0xe9, 0x44, 0xe8, 0x5b, 0x09, 0xa2, 0xcd, 0x71, 0xa1, 0x53, + 0x0a, 0x46, 0xe5, 0xa2, 0x6b, 0x6b, 0x80, 0xb6, 0x38, 0xdb, 0x99, 0x2b, + 0x40, 0x67, 0x15, 0x53, 0xe4, 0x35, 0xd4, 0xa7, 0x05, 0x8b, 0x9a, 0xd2, + 0x6e, 0x70, 0xde, 0xd5, 0xbb, 0x8e, 0x52, 0x9b, 0xf4, 0xea, 0x1b, 0xc1, + 0x4c, 0xad, 0xcd, 0x52, 0x65, 0x54, 0xdc, 0xbf, 0x65, 0x75, 0x89, 0x4d, + 0x17, 0x78, 0xd8, 0xf3, 0xc8, 0xd6, 0xb9, 0xd2, 0x3b, 0x82, 0x0e, 0xcd, + 0x90, 0x37, 0x02, 0xae, 0x54, 0x32, 0xca, 0x35, 0x02, 0xdb, 0x9d, 0xb9, + 0x55, 0xca, 0xfc, 0xa5, 0xad, 0x32, 0x96, 0xd4, 0x1c, 0xf2, 0xda, 0xee, + 0xc9, 0x7f, 0x35, 0xa4, 0xde, 0x4b, 0x16, 0xa4, 0xda, 0x6c, 0xda, 0x0a, + 0xf8, 0x7c, 0xd5, 0x22, 0x22, 0x2f, 0xc9, 0x26, 0xbc, 0x80, 0xbb, 0x47, + 0x2d, 0x22, 0x4f, 0x1b, 0x13, 0x54, 0xe4, 0xb4, 0xda, 0x5b, 0xea, 0xa8, + 0x48, 0xe0, 0x15, 0x6a, 0x38, 0x2a, 0x9c, 0xd2, 0xb4, 0x5e, 0x0e, 0x4d, + 0xa9, 0xe4, 0x5b, 0x1c, 0x72, 0x99, 0xb8, 0x51, 0x68, 0x82, 0x7c, 0x95, + 0x1b, 0x2e, 0x2b, 0x4e, 0x3e, 0x61, 0xdc, 0x15, 0x5c, 0x4f, 0x15, 0x7e, + 0x58, 0x90, 0xdc, 0x73, 0x5a, 0xd6, 0x83, 0x35, 0x27, 0x31, 0xb9, 0xbb, + 0x08, 0x4d, 0x9c, 0x36, 0x86, 0x17, 0x66, 0xcf, 0x3b, 0xfa, 0x64, 0xd2, + 0x32, 0x0a, 0x8f, 0x54, 0x33, 0xd5, 0x50, 0x90, 0xaa, 0x27, 0xc1, 0x6e, + 0xe2, 0x99, 0xc3, 0x50, 0xcd, 0xa6, 0x4a, 0xb5, 0xb0, 0x6c, 0x12, 0x4c, + 0x82, 0xd1, 0x21, 0xc8, 0xe8, 0xe5, 0xce, 0x12, 0x92, 0xce, 0x96, 0xd4, + 0xd8, 0x6c, 0x19, 0xd1, 0x5d, 0x70, 0x09, 0xf1, 0x22, 0x31, 0xd9, 0xfb, + 0x49, 0x08, 0x45, 0x18, 0x1c, 0x2b, 0x92, 0x62, 0x1f, 0x9a, 0xd2, 0x74, + 0xb8, 0x2b, 0xb3, 0xb8, 0xa3, 0x21, 0x2d, 0x78, 0x67, 0xc5, 0x64, 0xe6, + 0xbc, 0xb6, 0x7b, 0x02, 0xd2, 0x71, 0x77, 0x1b, 0x34, 0x32, 0x5b, 0xd5, + 0x5a, 0xb6, 0x85, 0x88, 0x2b, 0xf2, 0xba, 0xd6, 0x68, 0x74, 0x82, 0xa9, + 0x9e, 0x50, 0xf0, 0x04, 0xb8, 0xe5, 0x90, 0xaa, 0x0e, 0x73, 0x08, 0x69, + 0xdb, 0xa8, 0xa1, 0x57, 0xcf, 0xc9, 0x5c, 0xd5, 0x81, 0xa9, 0xce, 0xdf, + 0x6c, 0x00, 0xe2, 0x17, 0xb5, 0x26, 0x7b, 0xd5, 0x1c, 0xd4, 0x18, 0xc0, + 0x09, 0x55, 0x60, 0x43, 0x38, 0x44, 0x07, 0x6c, 0x82, 0x71, 0x9d, 0x26, + 0xaf, 0xc9, 0x42, 0xaf, 0x9a, 0x7c, 0x46, 0xc5, 0xcd, 0x2e, 0x4d, 0x14, + 0x86, 0x06, 0xd8, 0x74, 0x28, 0xe6, 0xe7, 0x39, 0xd3, 0x98, 0x42, 0xaa, + 0x43, 0x2d, 0x61, 0xcc, 0xf1, 0x5d, 0x97, 0xf3, 0x64, 0xbd, 0x5f, 0x62, + 0xfb, 0x0d, 0xd4, 0x36, 0x6c, 0x71, 0x58, 0x5d, 0xcb, 0x25, 0x08, 0xb3, + 0x37, 0x3a, 0x41, 0x48, 0x0d, 0x15, 0x72, 0xdd, 0x93, 0xe5, 0x52, 0x51, + 0x84, 0xbd, 0xea, 0x21, 0x16, 0x27, 0x46, 0x98, 0x76, 0xd2, 0xb3, 0x01, + 0x33, 0x3e, 0xe3, 0x93, 0x99, 0x52, 0xc9, 0xcd, 0xb3, 0xd8, 0xa7, 0x9a, + 0x01, 0xcb, 0x72, 0x3a, 0xdd, 0xca, 0xa6, 0x6b, 0x49, 0xb5, 0x1b, 0x42, + 0xcd, 0xbd, 0xa6, 0xa0, 0xf7, 0x0b, 0xca, 0xc4, 0x79, 0xaa, 0xea, 0xa4, + 0x1c, 0x65, 0xbb, 0x25, 0x14, 0xc1, 0x97, 0x05, 0x27, 0xc4, 0x73, 0x86, + 0xee, 0xe6, 0x32, 0x89, 0x99, 0x78, 0xae, 0xb1, 0x8f, 0x11, 0x7c, 0x00, + 0xcb, 0xbd, 0x69, 0x68, 0xf7, 0x3b, 0xd4, 0xa2, 0x09, 0x9d, 0xe1, 0x1a, + 0x4b, 0x8a, 0x6e, 0xa1, 0xb9, 0x6e, 0x0a, 0xe6, 0xab, 0x82, 0xb9, 0x61, + 0x58, 0x1b, 0xc9, 0x4e, 0x81, 0x16, 0xc0, 0x3d, 0x5c, 0x31, 0xef, 0x29, + 0x43, 0x8a, 0x1c, 0x3c, 0x55, 0xcd, 0x2a, 0x90, 0x61, 0xf3, 0xfe, 0xeb, + 0x0e, 0x67, 0xd2, 0xd5, 0x5b, 0xc9, 0xaa, 0x67, 0x58, 0xd1, 0x32, 0xda, + 0x85, 0x38, 0x7e, 0xc9, 0xde, 0x8b, 0xfd, 0xd8, 0x5c, 0xc2, 0x94, 0x56, + 0x98, 0x4e, 0xdf, 0x78, 0x59, 0xd0, 0xde, 0x1e, 0xdd, 0xe0, 0xe5, 0x77, + 0x0d, 0x45, 0xea, 0xf5, 0xbd, 0x5d, 0x67, 0xe7, 0x6d, 0x46, 0x59, 0xaa, + 0xeb, 0xa6, 0x2a, 0xb0, 0x9c, 0x97, 0xea, 0x28, 0xaa, 0x3b, 0xce, 0x63, + 0x22, 0x49, 0xa8, 0xb9, 0xc6, 0x6e, 0x36, 0x18, 0xe6, 0xe8, 0x92, 0x36, + 0x2d, 0x17, 0xcf, 0x8a, 0xab, 0x27, 0xc1, 0x69, 0x35, 0xcd, 0xf2, 0x58, + 0xb5, 0xf4, 0x05, 0x69, 0x04, 0x35, 0x02, 0xaa, 0xfd, 0x47, 0xf8, 0x78, + 0x57, 0x7b, 0xc5, 0x06, 0x36, 0xce, 0x7f, 0x56, 0x27, 0xbe, 0x4b, 0x7e, + 0x59, 0x96, 0x66, 0xbb, 0xe2, 0x6d, 0x17, 0x5d, 0x06, 0x21, 0x74, 0x3d, + 0xa4, 0x5e, 0x38, 0xa9, 0x1a, 0x45, 0x17, 0x8c, 0x8e, 0xe1, 0xa8, 0xf3, + 0xd4, 0x92, 0x24, 0xc7, 0x5f, 0x3c, 0x8e, 0xa2, 0xa8, 0x54, 0xd1, 0x2a, + 0x8e, 0x07, 0x8a, 0xab, 0x79, 0x6b, 0xee, 0xc9, 0x3c, 0xd3, 0x6e, 0xe5, + 0x42, 0xae, 0xef, 0x79, 0xbb, 0x5b, 0x96, 0xe5, 0x56, 0x05, 0x31, 0x31, + 0xc0, 0xad, 0xbc, 0xd5, 0x09, 0x54, 0x70, 0x5b, 0x39, 0xab, 0x87, 0x35, + 0x87, 0xd5, 0x60, 0xf5, 0x58, 0x3d, 0x55, 0x64, 0x15, 0xeb, 0xb4, 0x21, + 0x6d, 0x77, 0x15, 0x77, 0x73, 0x21, 0x1c, 0xdd, 0xb9, 0x68, 0x26, 0xab, + 0xa2, 0xab, 0x5b, 0x13, 0x02, 0x7e, 0x0b, 0x71, 0xdc, 0x54, 0x93, 0x62, + 0x43, 0xc1, 0x78, 0xfd, 0x93, 0x5e, 0xdb, 0x8a, 0x22, 0x5a, 0x8f, 0x3d, + 0x4d, 0x56, 0x7c, 0x3f, 0x31, 0x68, 0x17, 0xb6, 0x8a, 0x70, 0xe3, 0x11, + 0xc6, 0xaa, 0x8e, 0x63, 0xfd, 0x17, 0x64, 0x7c, 0x8a, 0xac, 0x37, 0xf2, + 0x55, 0x69, 0xe5, 0x92, 0xfc, 0x98, 0x4f, 0x25, 0x85, 0x5d, 0x25, 0x57, + 0x05, 0x57, 0x15, 0x74, 0xf8, 0xa9, 0xc8, 0x05, 0x33, 0xab, 0x69, 0x86, + 0x1a, 0xd2, 0xb0, 0x72, 0x55, 0x12, 0xd6, 0xd0, 0x6a, 0x80, 0xf8, 0xa9, + 0x64, 0x0d, 0x66, 0x8f, 0x25, 0x71, 0xee, 0xb5, 0x2a, 0x65, 0xbc, 0xf5, + 0x37, 0xa2, 0xc2, 0x34, 0x85, 0x41, 0x47, 0xa3, 0x44, 0xb8, 0xdd, 0xa9, + 0xae, 0xa2, 0xf5, 0x49, 0x95, 0xa4, 0xd2, 0x5b, 0xb8, 0x2d, 0x19, 0xcb, + 0xe6, 0xb5, 0xd5, 0x3b, 0xf0, 0xeb, 0x66, 0x54, 0xce, 0xb2, 0x59, 0x70, + 0x0f, 0x25, 0x49, 0x85, 0x47, 0xfa, 0x2a, 0x16, 0x95, 0x87, 0xd5, 0x76, + 0x65, 0x76, 0x6e, 0xe4, 0xb0, 0xbf, 0x92, 0xc2, 0xfe, 0x4b, 0x03, 0x97, + 0x67, 0xcd, 0x7b, 0xa1, 0x55, 0xe3, 0x92, 0x10, 0xda, 0xfc, 0xe2, 0x2f, + 0xd4, 0xb1, 0xde, 0x36, 0x49, 0xd6, 0xf8, 0x29, 0xeb, 0xf1, 0x05, 0xb4, + 0xf9, 0x2a, 0x43, 0x3e, 0x6b, 0x63, 0x56, 0x93, 0x89, 0x54, 0x1a, 0xce, + 0xbd, 0x9e, 0x6a, 0xfd, 0x31, 0x7e, 0x4b, 0xb2, 0x62, 0xf4, 0x58, 0xb2, + 0x6c, 0x57, 0xe5, 0xb9, 0x50, 0x2b, 0xda, 0x3d, 0x51, 0x6f, 0x5b, 0x76, + 0xe0, 0xaa, 0xe2, 0x75, 0x7f, 0x30, 0xbf, 0x57, 0x32, 0xbc, 0x3b, 0xe7, + 0x57, 0x0f, 0x1e, 0xd3, 0xbb, 0x56, 0xd7, 0x6f, 0x19, 0x4e, 0xbe, 0x61, + 0x6e, 0x2a, 0x46, 0xc5, 0xca, 0xe5, 0x72, 0xb9, 0x5d, 0x92, 0xe5, 0x72, + 0xa8, 0x57, 0x77, 0x12, 0xd3, 0x50, 0x56, 0x70, 0xc1, 0xfa, 0x84, 0x1e, + 0xda, 0x83, 0xac, 0x2e, 0x53, 0x37, 0xeb, 0x33, 0xb6, 0x6d, 0x40, 0x8b, + 0xb5, 0x33, 0x2b, 0xc3, 0xbe, 0x66, 0x33, 0xb4, 0x3e, 0x8a, 0x7a, 0xb2, + 0xcd, 0xad, 0xca, 0x1b, 0xdc, 0x64, 0xea, 0x85, 0x4e, 0xfc, 0x58, 0xe1, + 0xc0, 0xac, 0xc7, 0x0f, 0x67, 0xb7, 0x59, 0x9a, 0x30, 0xb7, 0x5d, 0xd5, + 0x3a, 0xed, 0x9a, 0x8a, 0xdf, 0xb9, 0x57, 0x5e, 0xe6, 0xeb, 0x73, 0x59, + 0x58, 0x9f, 0xa2, 0x24, 0xd4, 0xeb, 0x19, 0x5b, 0xe9, 0x94, 0xf7, 0x29, + 0x85, 0xa5, 0x4e, 0xfd, 0x76, 0xaf, 0x34, 0x62, 0x3d, 0xc3, 0x32, 0x25, + 0xfb, 0xed, 0x49, 0x9c, 0xd5, 0x7b, 0x80, 0xd5, 0xcc, 0xd0, 0x2c, 0xc8, + 0x34, 0x1f, 0x16, 0xbc, 0x1e, 0x68, 0xef, 0xee, 0xb4, 0x2b, 0x4a, 0x8a, + 0x9f, 0x72, 0x97, 0x14, 0x5c, 0x7b, 0x8e, 0x6b, 0xf4, 0x9a, 0xa6, 0xd3, + 0x31, 0x93, 0x79, 0x55, 0xe5, 0xdc, 0xa6, 0x81, 0xd4, 0xe7, 0x3c, 0xc8, + 0x29, 0x0d, 0x18, 0x7b, 0xbb, 0x80, 0x1e, 0xeb, 0x97, 0x80, 0xee, 0xf4, + 0x55, 0xaa, 0xad, 0x15, 0x0f, 0xdc, 0x33, 0x37, 0x2f, 0x94, 0x5d, 0xdc, + 0xe6, 0xd3, 0x25, 0x2c, 0x3d, 0xd4, 0xb0, 0xf9, 0x5b, 0x9b, 0x8e, 0x68, + 0xf1, 0x52, 0x84, 0x27, 0xe2, 0x56, 0x73, 0xdd, 0x9c, 0x7b, 0x8c, 0xf6, + 0x77, 0x9a, 0x09, 0xaa, 0xd1, 0x5e, 0x7e, 0xe0, 0xaa, 0xcd, 0x6e, 0x0f, + 0xd7, 0xee, 0xa0, 0x42, 0x98, 0xb1, 0xa6, 0xe0, 0x14, 0xa1, 0x37, 0xcc, + 0xa9, 0xbd, 0xc5, 0xdd, 0xca, 0x5d, 0xe2, 0x67, 0x44, 0x2a, 0x0a, 0xef, + 0x3f, 0x71, 0x4c, 0xd0, 0x2c, 0xd6, 0xd1, 0x9f, 0xaf, 0x79, 0xa2, 0xaf, + 0x72, 0xf0, 0x53, 0x31, 0x00, 0x5a, 0x0d, 0x2e, 0xf4, 0x57, 0xe6, 0x0f, + 0x97, 0xba, 0xcf, 0xbc, 0x4b, 0x14, 0x3d, 0xdb, 0x94, 0xda, 0x66, 0x3e, + 0xe0, 0x93, 0xa2, 0x00, 0x77, 0x29, 0x87, 0x4f, 0xc1, 0x57, 0x0e, 0xed, + 0x65, 0xe7, 0x92, 0xed, 0x07, 0x9a, 0xa7, 0x70, 0xbb, 0x59, 0x32, 0xd9, + 0x0c, 0xb7, 0x85, 0x88, 0x4f, 0xbb, 0x4c, 0xf7, 0xa9, 0xb0, 0xc9, 0x49, + 0xda, 0x2e, 0xee, 0x32, 0x1a, 0xd7, 0x4d, 0xd9, 0xb4, 0xbd, 0x39, 0xa7, + 0x2d, 0x55, 0xfa, 0x8d, 0x27, 0x01, 0xc5, 0x63, 0x9f, 0x05, 0x5e, 0x90, + 0xe3, 0xf5, 0x37, 0xfb, 0xa1, 0xd5, 0x3d, 0xb1, 0x58, 0x3d, 0xd5, 0x87, + 0x37, 0xcb, 0xba, 0xdc, 0x16, 0x15, 0x84, 0xf3, 0x57, 0x1e, 0x6a, 0xe5, + 0x33, 0x11, 0xb2, 0xdc, 0x2f, 0x5a, 0x2d, 0x99, 0xde, 0x55, 0x27, 0x25, + 0x8f, 0xd5, 0x54, 0xac, 0x5e, 0x8a, 0xae, 0x25, 0x7b, 0xcb, 0x6f, 0x35, + 0xa3, 0x1b, 0x37, 0x8a, 0x9b, 0x22, 0x75, 0x83, 0x84, 0x95, 0x67, 0x3f, + 0x15, 0x7f, 0x35, 0x51, 0xf7, 0x55, 0xea, 0xf7, 0xc5, 0xf9, 0x5a, 0xd5, + 0x28, 0x30, 0xc3, 0x3d, 0x55, 0x4b, 0xcf, 0xd2, 0x64, 0xb4, 0x1b, 0x15, + 0xae, 0xf1, 0x88, 0xb4, 0xdd, 0x17, 0xca, 0x2a, 0xd2, 0x73, 0x8f, 0x83, + 0xa5, 0xaa, 0x90, 0xd6, 0x55, 0xde, 0x4b, 0x40, 0x4b, 0xc4, 0xa9, 0xb8, + 0xcd, 0x75, 0x82, 0xcd, 0xea, 0xb9, 0x2f, 0xcb, 0x8d, 0x90, 0x5a, 0xb4, + 0xfa, 0x41, 0x3c, 0x1a, 0xa9, 0x1a, 0x20, 0xf2, 0x5e, 0xf4, 0xb8, 0xab, + 0x8e, 0x4c, 0x52, 0xf2, 0x53, 0x67, 0xb5, 0x1e, 0xaa, 0xad, 0x2d, 0x58, + 0x87, 0x76, 0xa1, 0x92, 0x96, 0x76, 0x70, 0xf9, 0x94, 0xdb, 0x15, 0xcd, + 0xf0, 0xd8, 0xb4, 0xb3, 0x1f, 0xc5, 0xab, 0x4b, 0xa3, 0xb7, 0xf0, 0xb8, + 0x85, 0x58, 0x51, 0x1b, 0xc0, 0x85, 0x8a, 0x23, 0x7f, 0x0a, 0xfb, 0x44, + 0xb8, 0x85, 0x4e, 0x93, 0x0f, 0x9a, 0xed, 0x58, 0x7f, 0x18, 0x58, 0x9b, + 0xf9, 0x82, 0xf6, 0xae, 0x60, 0xf3, 0x5a, 0x2e, 0x32, 0x0a, 0x9a, 0xbd, + 0xca, 0xb5, 0xef, 0xe6, 0x1c, 0x27, 0x4c, 0x6d, 0x55, 0xd2, 0x2a, 0x6d, + 0xa2, 0xa9, 0x57, 0xab, 0xf2, 0xd2, 0x6a, 0xf2, 0xb4, 0xba, 0x43, 0x19, + 0xe6, 0x14, 0x83, 0xe1, 0xc6, 0x6e, 0xf9, 0x2d, 0x38, 0x23, 0xc9, 0x60, + 0x97, 0x9a, 0x9c, 0xf3, 0x5b, 0xe2, 0xa4, 0x26, 0xfe, 0x0a, 0x90, 0x3f, + 0x99, 0x7d, 0x9f, 0xf9, 0x97, 0xd9, 0xff, 0x00, 0x99, 0x76, 0x1f, 0xcc, + 0xbb, 0x03, 0xcd, 0x48, 0x68, 0xbb, 0x71, 0xc9, 0x57, 0x85, 0x49, 0xbb, + 0x82, 0xd1, 0x6c, 0xb8, 0xaa, 0xba, 0xc4, 0x94, 0xb6, 0x6a, 0x2f, 0x54, + 0x71, 0x5b, 0xd4, 0x95, 0x67, 0xcf, 0x51, 0x47, 0x2b, 0xe6, 0xb4, 0x9a, + 0xaa, 0xd2, 0x15, 0x22, 0x01, 0xc5, 0x50, 0xcf, 0x5b, 0x57, 0x05, 0x8c, + 0x2c, 0x4b, 0x6f, 0x25, 0xa2, 0xd7, 0x15, 0x48, 0x7f, 0xcc, 0x16, 0x01, + 0xf9, 0x97, 0x62, 0xef, 0x25, 0x27, 0x68, 0x9f, 0x9a, 0x9a, 0x9d, 0xeb, + 0x75, 0xac, 0x60, 0x2b, 0xf3, 0x95, 0xdd, 0xfb, 0x4a, 0x20, 0xe0, 0x17, + 0xb3, 0x6f, 0x99, 0x58, 0xd6, 0x69, 0x67, 0x58, 0xd5, 0xf6, 0x77, 0x8f, + 0x35, 0xd8, 0xbf, 0x9a, 0xa7, 0x47, 0x3f, 0x99, 0x53, 0xa3, 0x8f, 0x37, + 0x2a, 0x42, 0x86, 0x15, 0x04, 0x31, 0xf8, 0x57, 0x69, 0x2e, 0x01, 0x56, + 0x33, 0xf9, 0xad, 0x27, 0x13, 0xc4, 0xab, 0xac, 0x55, 0xc6, 0x56, 0xa8, + 0xb3, 0xc1, 0xcd, 0x0a, 0xae, 0x27, 0x53, 0x22, 0xb7, 0x8e, 0xed, 0x4c, + 0x9a, 0x0f, 0x2d, 0xe0, 0xab, 0x27, 0xf1, 0x5a, 0x6c, 0x23, 0x82, 0xed, + 0x00, 0xe2, 0xa8, 0x41, 0xe1, 0x93, 0x14, 0xf8, 0x2d, 0x1a, 0x2a, 0xc4, + 0x92, 0xed, 0x1c, 0x55, 0x5e, 0xe1, 0xe6, 0xaf, 0x25, 0x54, 0xa9, 0x35, + 0x54, 0xab, 0xd5, 0xeb, 0x12, 0x95, 0xea, 0x60, 0x03, 0xc4, 0x4d, 0x5f, + 0x2f, 0xc2, 0xa4, 0xf2, 0x3f, 0x2a, 0xc4, 0xa8, 0x6c, 0x54, 0x2a, 0x09, + 0x58, 0xf0, 0xb5, 0xb9, 0x52, 0x23, 0xb9, 0xac, 0x60, 0xf1, 0x55, 0x6b, + 0x0a, 0xd2, 0x67, 0x22, 0xae, 0x7a, 0xd1, 0x86, 0x7c, 0xca, 0xd1, 0x63, + 0x56, 0xc1, 0xe4, 0xb1, 0x2c, 0x4b, 0x12, 0xbd, 0x5e, 0x15, 0xed, 0x57, + 0xb5, 0x7b, 0xab, 0x62, 0xc1, 0x0f, 0xf2, 0xae, 0xce, 0x1f, 0xe5, 0x5d, + 0x8c, 0x2f, 0xca, 0xab, 0xd1, 0xa1, 0x1f, 0xc2, 0xb4, 0xba, 0x23, 0x7c, + 0x8a, 0x98, 0x6b, 0xd8, 0xbb, 0x59, 0x71, 0x54, 0x8d, 0x0f, 0xf3, 0x2c, + 0x40, 0xf0, 0xc9, 0x37, 0x99, 0x29, 0x42, 0x67, 0x99, 0x5a, 0x4e, 0x36, + 0x33, 0x55, 0xd6, 0x6f, 0x5a, 0x25, 0xa3, 0xea, 0x74, 0x95, 0x7a, 0x44, + 0x31, 0xc1, 0x76, 0xe4, 0xf0, 0x6a, 0xed, 0x5f, 0xf9, 0x42, 0xa4, 0x69, + 0xfe, 0x15, 0x57, 0x05, 0x89, 0x6d, 0xe4, 0xbd, 0xe5, 0x7b, 0x96, 0x22, + 0xb1, 0x9e, 0x4b, 0xb4, 0xf4, 0x55, 0x88, 0xe3, 0xe4, 0xb3, 0x5b, 0x41, + 0x6f, 0x49, 0xe1, 0xbc, 0x55, 0x09, 0x79, 0xf0, 0x5a, 0x0d, 0x0c, 0x53, + 0x7c, 0x43, 0x2e, 0xf7, 0x72, 0xb9, 0x68, 0xd3, 0x82, 0x91, 0x79, 0x21, + 0x5d, 0x92, 0xb5, 0x54, 0x12, 0x55, 0x2b, 0x47, 0x59, 0x4c, 0x9b, 0x16, + 0xc5, 0x7a, 0xc6, 0x56, 0x29, 0xe5, 0xa1, 0x5b, 0xd7, 0xf6, 0x5f, 0xd9, + 0x5e, 0x56, 0x23, 0xcd, 0x62, 0xf5, 0x58, 0xc7, 0x35, 0x8c, 0x2c, 0x4b, + 0x69, 0x54, 0x6f, 0x32, 0xb4, 0x5a, 0xd5, 0x59, 0x64, 0xba, 0x5c, 0x55, + 0xe5, 0x57, 0xf5, 0x52, 0x9c, 0xcf, 0x80, 0x57, 0x2f, 0xee, 0xae, 0xf5, + 0x58, 0x4a, 0x90, 0x74, 0x8e, 0xeb, 0x95, 0x17, 0xee, 0xa6, 0x45, 0x32, + 0x4b, 0x34, 0x79, 0xa9, 0x98, 0x14, 0xde, 0xd2, 0xb0, 0xbd, 0xab, 0x17, + 0xa2, 0xc4, 0xa9, 0x10, 0xf9, 0x39, 0x69, 0x17, 0x3f, 0x89, 0x57, 0x15, + 0x71, 0xe4, 0xae, 0x57, 0xad, 0x2a, 0xad, 0x10, 0x02, 0xbe, 0xd5, 0x02, + 0xb8, 0x2d, 0x96, 0x2f, 0xb1, 0x43, 0x25, 0x55, 0xb9, 0x50, 0xac, 0x44, + 0x2d, 0x8e, 0x5d, 0x97, 0xaa, 0xac, 0x3f, 0x55, 0x87, 0xd5, 0x68, 0x06, + 0x8e, 0x2a, 0xb1, 0x39, 0x15, 0x5e, 0xf9, 0x76, 0x5b, 0x8a, 0xfe, 0xeb, + 0x13, 0x42, 0xc6, 0xa8, 0x26, 0xa8, 0x24, 0xaf, 0x55, 0x3a, 0xfb, 0xd5, + 0xf6, 0x36, 0xab, 0x8a, 0xc2, 0x56, 0x05, 0x81, 0x55, 0x8a, 0xb0, 0xd7, + 0xd8, 0xe1, 0x3b, 0x88, 0x5a, 0x1d, 0x0f, 0xa3, 0xb3, 0xff, 0x00, 0xae, + 0x6a, 0xa4, 0x0e, 0x0d, 0x92, 0xbd, 0x62, 0x57, 0xd8, 0x9a, 0xa8, 0xe4, + 0xaf, 0x55, 0x2a, 0x73, 0x91, 0xf0, 0x2a, 0x91, 0x8a, 0xed, 0x82, 0xed, + 0x42, 0xed, 0xbf, 0x45, 0x39, 0xcc, 0xef, 0x57, 0xad, 0xaa, 0x40, 0x48, + 0x65, 0xf6, 0x92, 0x2c, 0xdd, 0x7a, 0xec, 0x67, 0xf8, 0x42, 0x94, 0x28, + 0x39, 0x8e, 0xdf, 0x45, 0x3c, 0xee, 0x4b, 0x11, 0xc9, 0x76, 0xa6, 0x93, + 0x57, 0xeb, 0xe8, 0x72, 0x55, 0xaa, 0xf2, 0x15, 0x1e, 0xb6, 0x2b, 0x95, + 0xca, 0xe5, 0x75, 0xab, 0xd5, 0xfa, 0x8e, 0xd9, 0xdf, 0x95, 0x76, 0xce, + 0xe4, 0xbb, 0x57, 0x72, 0x5d, 0xab, 0xf9, 0x2e, 0xd1, 0xeb, 0x1b, 0xd7, + 0xbf, 0xcd, 0x61, 0x77, 0x35, 0xd9, 0x9e, 0x6b, 0xb2, 0xf5, 0x54, 0x82, + 0x39, 0xae, 0xc9, 0x8b, 0x03, 0x02, 0xd8, 0x16, 0x25, 0x89, 0x5e, 0x55, + 0xcb, 0x0a, 0xb9, 0x5c, 0xae, 0x57, 0x2b, 0xbb, 0x8d, 0xf9, 0x6e, 0xb1, + 0x7d, 0xab, 0x95, 0xca, 0xe5, 0x72, 0xb9, 0x5c, 0xae, 0x57, 0x15, 0xb5, + 0x5c, 0x56, 0xd5, 0x71, 0x57, 0x1c, 0x97, 0x2b, 0x95, 0xda, 0x8b, 0xca, + 0xc4, 0xb1, 0xac, 0x4a, 0xfd, 0x45, 0xea, 0xfe, 0xe9, 0x79, 0x58, 0x96, + 0x25, 0xee, 0x9f, 0x25, 0x81, 0x8b, 0xb2, 0x6a, 0xec, 0x7d, 0x57, 0x67, + 0xea, 0xb0, 0x3b, 0x9a, 0xb9, 0xfc, 0xd5, 0xef, 0x58, 0xa2, 0x2e, 0xd1, + 0xfc, 0x97, 0x6a, 0xfe, 0x4b, 0xb5, 0x7f, 0x25, 0xdb, 0x3b, 0xf2, 0xae, + 0xd9, 0xdf, 0x95, 0x76, 0xce, 0xfc, 0xab, 0x6a, 0xda, 0xb6, 0xe4, 0xb9, + 0x5c, 0xae, 0x2a, 0xe2, 0xae, 0x2a, 0xe2, 0xae, 0x58, 0x4a, 0xc2, 0x55, + 0xc5, 0x7b, 0xcb, 0xde, 0x5e, 0xf2, 0xf7, 0x96, 0xd5, 0x72, 0xc2, 0xae, + 0x57, 0x65, 0xbf, 0xb8, 0xdc, 0xae, 0x58, 0x56, 0x15, 0x85, 0x61, 0x58, + 0x0a, 0xc0, 0x56, 0x02, 0xb0, 0x95, 0x84, 0xac, 0x25, 0x61, 0x2b, 0x0b, + 0x96, 0x17, 0x2c, 0x2e, 0x58, 0x5c, 0xb0, 0x9e, 0x4b, 0x09, 0xe4, 0xb0, + 0x95, 0x84, 0xf2, 0x58, 0x4f, 0x25, 0x84, 0xf2, 0x58, 0x4f, 0x25, 0x84, + 0xac, 0x25, 0x61, 0x2b, 0x09, 0x58, 0x4a, 0xc2, 0xe5, 0x85, 0xcb, 0x09, + 0x58, 0x4a, 0xc0, 0x56, 0x02, 0xb0, 0x15, 0x84, 0xac, 0x0b, 0x02, 0xc2, + 0xb0, 0xab, 0x95, 0xca, 0xed, 0x7d, 0xea, 0xfc, 0xb7, 0x2c, 0x2b, 0x0a, + 0xc2, 0xb0, 0x95, 0x84, 0xab, 0x8a, 0xb8, 0xab, 0x8a, 0xda, 0xb6, 0xf2, + 0x5b, 0x79, 0x2d, 0xbc, 0x96, 0xde, 0x4b, 0x6f, 0x25, 0x71, 0xe4, 0xae, + 0x3c, 0x96, 0xde, 0x4a, 0xf3, 0xc9, 0x5e, 0xee, 0x4b, 0x13, 0xb9, 0x2c, + 0x45, 0x5e, 0x56, 0xd5, 0xff, 0xc4, 0x00, 0x29, 0x10, 0x00, 0x02, 0x01, + 0x02, 0x05, 0x03, 0x04, 0x03, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x01, 0x11, 0x21, 0x31, 0x10, 0x41, 0x51, 0x61, 0x71, 0x20, + 0x81, 0x91, 0xa1, 0xb1, 0xc1, 0xf0, 0x30, 0xd1, 0xf1, 0xe1, 0x40, 0xff, + 0xda, 0x00, 0x08, 0x01, 0x01, 0x00, 0x01, 0x3f, 0x21, 0xff, 0x00, 0x96, + 0x7a, 0x27, 0x09, 0xe9, 0x92, 0x49, 0x24, 0x92, 0x49, 0x27, 0xf0, 0x80, + 0x40, 0x81, 0x12, 0x24, 0x48, 0x91, 0x20, 0x40, 0x81, 0x12, 0x24, 0x48, + 0x1c, 0x82, 0x89, 0xb7, 0x73, 0x7b, 0xcc, 0xfe, 0xe8, 0xf5, 0xbe, 0x08, + 0xcc, 0x37, 0x84, 0x24, 0x5d, 0xb0, 0xb5, 0x9e, 0x44, 0x9f, 0xf6, 0xcd, + 0xa6, 0x0d, 0xfc, 0xde, 0x81, 0x43, 0x3f, 0xc0, 0x1f, 0xc4, 0x1f, 0xc8, + 0x61, 0xcf, 0xe6, 0x8f, 0xe2, 0xba, 0x94, 0xad, 0x6b, 0x5f, 0xcd, 0x3f, + 0x86, 0x7f, 0x00, 0xfe, 0x21, 0xfc, 0x43, 0xf9, 0x87, 0xf0, 0x0f, 0xe4, + 0x9f, 0xc9, 0x3f, 0x80, 0x7f, 0x00, 0xfe, 0x01, 0xfc, 0x83, 0xf9, 0x07, + 0xf0, 0x0f, 0xe0, 0x9f, 0xc1, 0x3f, 0x8a, 0x7f, 0x14, 0xfe, 0x29, 0xfc, + 0x5c, 0x4d, 0x6f, 0xe1, 0x8f, 0xe1, 0x0f, 0xe3, 0x0f, 0xe7, 0x4f, 0xe0, + 0x7a, 0x2a, 0x8f, 0x7f, 0x1f, 0x02, 0x9b, 0x27, 0xa9, 0x3f, 0xfb, 0x63, + 0x19, 0x1d, 0xc6, 0x2c, 0xb3, 0x25, 0xbe, 0x54, 0x19, 0xf2, 0xb5, 0x58, + 0x45, 0x9a, 0x36, 0x1e, 0x4d, 0xa1, 0xbc, 0x8d, 0xe4, 0x6d, 0x30, 0x10, + 0xd4, 0x8e, 0xa4, 0x75, 0x39, 0xf5, 0x62, 0x70, 0x49, 0x24, 0x92, 0x4f, + 0xe5, 0x9f, 0xc7, 0x04, 0x10, 0x41, 0x04, 0x10, 0x41, 0x04, 0x11, 0x82, + 0x06, 0x87, 0x24, 0xb0, 0x9d, 0x89, 0x39, 0x24, 0x96, 0x53, 0x9a, 0x31, + 0x82, 0x44, 0x89, 0x10, 0xc9, 0x12, 0x25, 0x82, 0x37, 0xc1, 0x0c, 0xae, + 0xa5, 0x4a, 0x95, 0x2b, 0xd5, 0x52, 0x77, 0x16, 0xe2, 0x45, 0xff, 0x00, + 0x24, 0x92, 0x49, 0x38, 0xd7, 0x18, 0x62, 0x19, 0x29, 0x66, 0x41, 0x87, + 0x02, 0xb2, 0xda, 0xa4, 0x5c, 0xee, 0x09, 0x49, 0xeb, 0x96, 0x4b, 0x52, + 0x7a, 0xb3, 0x70, 0xde, 0x66, 0xf0, 0xb5, 0x30, 0xa6, 0x23, 0x11, 0x26, + 0xa2, 0x47, 0xff, 0x00, 0x0c, 0x75, 0x41, 0x04, 0x10, 0x41, 0x04, 0x10, + 0x41, 0x04, 0x10, 0x41, 0x04, 0x60, 0x78, 0x18, 0xf2, 0x15, 0xb4, 0x70, + 0x1e, 0x25, 0x8a, 0xcc, 0x5b, 0x09, 0x93, 0xc3, 0x2d, 0x09, 0x68, 0x4b, + 0x43, 0x89, 0x3d, 0x06, 0xf8, 0x64, 0x4f, 0xf1, 0xa4, 0x10, 0x41, 0x1d, + 0x0b, 0xf0, 0x49, 0x3d, 0x33, 0xd0, 0xef, 0x13, 0xc8, 0xf2, 0xd1, 0xa7, + 0x52, 0x1c, 0x98, 0xc1, 0xe4, 0x24, 0x3d, 0x51, 0x93, 0x78, 0x3d, 0x67, + 0x91, 0xeb, 0xb0, 0x12, 0x27, 0xa9, 0x32, 0x63, 0xa9, 0x4e, 0x3f, 0x78, + 0xbf, 0x3c, 0x92, 0x4e, 0x22, 0x75, 0x98, 0x9f, 0x31, 0xab, 0xd0, 0x49, + 0x65, 0x7a, 0x27, 0x09, 0xff, 0x00, 0x8e, 0x30, 0x82, 0x08, 0xc5, 0x4c, + 0xf2, 0x2c, 0x4e, 0xcf, 0x58, 0xe1, 0x9f, 0x0e, 0x9f, 0x73, 0xe0, 0x95, + 0xf2, 0x2b, 0xa3, 0x94, 0x39, 0xbb, 0x59, 0x2e, 0x51, 0x99, 0x47, 0x77, + 0xfa, 0x33, 0x1e, 0x26, 0x6a, 0xaf, 0x6f, 0xf6, 0x23, 0x76, 0xed, 0x87, + 0x9b, 0xd0, 0xca, 0x65, 0x33, 0x26, 0x76, 0x32, 0x20, 0x9d, 0xa7, 0xdc, + 0xd7, 0x3c, 0x33, 0xf4, 0xf1, 0x75, 0x57, 0x28, 0x48, 0x35, 0x64, 0x36, + 0x59, 0x0d, 0xc6, 0xe3, 0x2f, 0x02, 0x08, 0xfc, 0x08, 0x5d, 0x51, 0x84, + 0x93, 0x83, 0x24, 0xa5, 0xb8, 0x46, 0x6f, 0xd8, 0x7f, 0xba, 0x69, 0x6e, + 0x0b, 0x9b, 0x6c, 0x96, 0x77, 0xc6, 0x70, 0x92, 0x49, 0x24, 0xaf, 0x5f, + 0xa0, 0x62, 0x4d, 0x4a, 0x77, 0x5d, 0x33, 0xd5, 0x24, 0xfe, 0x09, 0x24, + 0x91, 0x3d, 0x8c, 0x68, 0x4a, 0x51, 0x93, 0xff, 0x00, 0x2c, 0x11, 0x82, + 0xca, 0xa4, 0x66, 0xa0, 0x1e, 0xc2, 0xf2, 0x40, 0x36, 0x4f, 0x23, 0xf4, + 0x3c, 0x74, 0x42, 0x5f, 0x37, 0xef, 0x62, 0x2b, 0xed, 0x9a, 0x89, 0x57, + 0x6f, 0xd0, 0x93, 0x4e, 0x91, 0x7f, 0x8a, 0x7a, 0x65, 0x96, 0x1e, 0xd3, + 0xd7, 0x41, 0x17, 0xee, 0xd5, 0x0b, 0x4f, 0x05, 0x8e, 0xfb, 0x28, 0x59, + 0x0e, 0x61, 0x95, 0x6e, 0x48, 0x7a, 0xcb, 0x0d, 0x96, 0x18, 0x6b, 0xa5, + 0x0b, 0x08, 0x20, 0x8e, 0x86, 0xc9, 0x26, 0x0d, 0x04, 0x14, 0x4e, 0xec, + 0x67, 0x53, 0x78, 0x32, 0x63, 0x04, 0x92, 0x49, 0x24, 0xf4, 0xc1, 0x18, + 0x49, 0x24, 0xe1, 0x04, 0x12, 0xcd, 0x59, 0x67, 0xfe, 0x68, 0x20, 0x81, + 0x9b, 0x41, 0x93, 0x21, 0x39, 0x60, 0x67, 0xd8, 0xb3, 0x78, 0xcd, 0xe9, + 0xf4, 0x34, 0x6e, 0x3c, 0x10, 0xe0, 0x11, 0x0f, 0xea, 0x1a, 0xf3, 0x12, + 0x24, 0x4c, 0x96, 0x84, 0xf0, 0xf0, 0xc5, 0x4c, 0x36, 0x55, 0x4c, 0xdb, + 0x1e, 0x48, 0xe7, 0xdf, 0x27, 0xe8, 0x42, 0x31, 0xf0, 0x45, 0x0a, 0x2d, + 0x9d, 0x7a, 0x8c, 0x83, 0x21, 0x7e, 0x47, 0xf1, 0x61, 0x97, 0x80, 0xf0, + 0xd9, 0x61, 0xe0, 0x32, 0xc3, 0x0d, 0x0d, 0x0d, 0x0d, 0x0a, 0x48, 0x69, + 0x35, 0xb9, 0xac, 0x3a, 0x89, 0xe6, 0xe9, 0x74, 0xcc, 0x8f, 0x3d, 0xb7, + 0x23, 0xc4, 0x58, 0x8e, 0x92, 0x44, 0x12, 0x36, 0x48, 0xf0, 0x64, 0x52, + 0x42, 0xa8, 0x99, 0x34, 0xe1, 0x24, 0x92, 0x4f, 0xfc, 0x31, 0x89, 0x77, + 0xc9, 0x18, 0x47, 0xe7, 0x8c, 0x56, 0x3c, 0x8f, 0x28, 0x8f, 0x64, 0x6c, + 0xc5, 0xaa, 0x51, 0x55, 0xdb, 0x24, 0x3c, 0x3c, 0xc2, 0x27, 0x8f, 0x2c, + 0x7e, 0x85, 0x94, 0x97, 0x72, 0xc7, 0xdc, 0x96, 0x2f, 0x94, 0x28, 0xb2, + 0xbc, 0x42, 0x4f, 0xd3, 0x33, 0x6b, 0xe5, 0xfb, 0x25, 0xfb, 0xbd, 0xc9, + 0xfe, 0xaf, 0x71, 0xbf, 0x32, 0xef, 0x1e, 0x40, 0xe0, 0xd8, 0x55, 0xdd, + 0x7e, 0x8b, 0xe0, 0xb9, 0x56, 0x31, 0x73, 0xcc, 0x0f, 0x84, 0x1d, 0x09, + 0xc3, 0xbc, 0x9c, 0x8a, 0xde, 0xc2, 0xa4, 0xbd, 0xc4, 0xdd, 0x37, 0x97, + 0xc0, 0xf5, 0x23, 0xbf, 0x41, 0xba, 0x6c, 0xf4, 0x94, 0x84, 0x55, 0x33, + 0x26, 0x5e, 0xa2, 0x96, 0x12, 0x49, 0x6c, 0x22, 0x82, 0x08, 0x22, 0x8a, + 0x2b, 0xab, 0x06, 0x18, 0x78, 0x2f, 0x1c, 0xc3, 0x2c, 0x32, 0xcb, 0x0c, + 0x30, 0xc3, 0x43, 0x43, 0x43, 0x43, 0x43, 0x43, 0x44, 0x29, 0xa6, 0xe2, + 0x87, 0x41, 0xea, 0x19, 0x1a, 0x6d, 0xf0, 0xd9, 0x65, 0x97, 0x8c, 0xa3, + 0x03, 0xc2, 0x41, 0x2d, 0xc0, 0xc4, 0xd7, 0xe1, 0xc3, 0x14, 0x48, 0x24, + 0x60, 0x9e, 0xa8, 0xc6, 0x31, 0x82, 0x08, 0x20, 0x8e, 0xa0, 0x4f, 0x42, + 0x43, 0x1d, 0x0c, 0xc9, 0x13, 0x24, 0x4b, 0xa2, 0x41, 0x1d, 0x70, 0x29, + 0x93, 0x90, 0x76, 0x10, 0xa9, 0xf5, 0x02, 0xc3, 0x14, 0xd1, 0xa1, 0x11, + 0x02, 0x93, 0x59, 0xa5, 0xe4, 0xc5, 0x09, 0x52, 0x84, 0x92, 0x49, 0x24, + 0x92, 0x4e, 0x29, 0x92, 0x2c, 0x10, 0x84, 0x84, 0x84, 0x84, 0x84, 0x85, + 0x89, 0x11, 0x45, 0x04, 0x50, 0x41, 0x14, 0x50, 0x41, 0x75, 0x1e, 0xc3, + 0x0f, 0x60, 0xe6, 0x32, 0xcb, 0x0c, 0x30, 0xcb, 0x2f, 0x08, 0xc3, 0x43, + 0x43, 0x43, 0x43, 0x43, 0x43, 0x43, 0x18, 0xc8, 0x32, 0xc3, 0x53, 0x62, + 0x69, 0x06, 0xa7, 0x6e, 0x04, 0x8b, 0xb3, 0xba, 0xfd, 0x10, 0xe6, 0x72, + 0x3e, 0x96, 0x25, 0xbf, 0xac, 0x7d, 0x0e, 0x7d, 0x0c, 0x36, 0x66, 0x5d, + 0xc6, 0x44, 0xf0, 0x26, 0xd1, 0x0a, 0x8a, 0x17, 0xf0, 0x46, 0xda, 0x86, + 0x71, 0x02, 0x82, 0x39, 0x6f, 0x42, 0x77, 0x28, 0x13, 0x92, 0x53, 0x55, + 0x44, 0x09, 0x13, 0x09, 0x89, 0xfe, 0x08, 0x23, 0xa5, 0xd6, 0x1c, 0xf1, + 0x66, 0x4c, 0xfb, 0xaf, 0xc1, 0xf7, 0x2f, 0x81, 0x6c, 0x32, 0xb8, 0x7e, + 0x0b, 0x4e, 0xef, 0xf6, 0xb2, 0xf6, 0x71, 0x94, 0xf7, 0xff, 0x00, 0xd8, + 0x1e, 0xb1, 0xe6, 0x4c, 0x3d, 0x15, 0x07, 0xea, 0x98, 0xe9, 0xba, 0x5b, + 0x67, 0xb0, 0xc5, 0xcc, 0x2c, 0x8f, 0xa2, 0xe4, 0x80, 0xfb, 0xc1, 0xb0, + 0xc3, 0x44, 0x11, 0x81, 0x45, 0xd7, 0x64, 0x4b, 0x64, 0x24, 0x1d, 0xdf, + 0x81, 0x02, 0xe0, 0xb7, 0x57, 0x8b, 0x09, 0x89, 0x2a, 0xc9, 0x21, 0x22, + 0x49, 0x27, 0xa0, 0x49, 0x24, 0x92, 0x26, 0x26, 0x49, 0x24, 0x88, 0x42, + 0x10, 0xb0, 0x24, 0x25, 0xf8, 0xc0, 0x05, 0x15, 0x05, 0xb4, 0x41, 0xa2, + 0x19, 0x86, 0x6c, 0xbc, 0x23, 0x5d, 0x07, 0xb4, 0x67, 0x80, 0xcb, 0x2f, + 0x00, 0xcb, 0x0c, 0x3e, 0xa0, 0xa8, 0x83, 0x43, 0x1a, 0x1a, 0x18, 0xc6, + 0x31, 0x8c, 0x63, 0x1e, 0x12, 0x4e, 0x24, 0x92, 0x25, 0x5c, 0xd0, 0xe5, + 0xe4, 0x4c, 0xcc, 0xab, 0x61, 0xb5, 0xdf, 0x32, 0xfa, 0xc7, 0x94, 0x97, + 0xb1, 0x1a, 0x71, 0xac, 0xdf, 0xd4, 0x94, 0x87, 0x6d, 0x58, 0x86, 0xbc, + 0x64, 0x9e, 0xa8, 0xae, 0xfd, 0xc1, 0x72, 0x0c, 0xf7, 0x79, 0x13, 0x44, + 0x10, 0x41, 0x04, 0x10, 0x46, 0x04, 0x5d, 0x43, 0x1f, 0x08, 0x93, 0x5b, + 0xe7, 0x7f, 0x23, 0xa0, 0xb5, 0xb8, 0x17, 0xf2, 0x08, 0xa4, 0xef, 0x32, + 0xf9, 0xdb, 0x17, 0xa9, 0xcc, 0xe5, 0x12, 0xf4, 0x42, 0x1f, 0x5c, 0x4b, + 0x27, 0x71, 0xc1, 0xb4, 0xae, 0xe9, 0xbe, 0x47, 0x93, 0x3f, 0x77, 0x7b, + 0x9f, 0x75, 0xf8, 0xfc, 0x4b, 0x6a, 0x87, 0xb6, 0x06, 0x49, 0x28, 0x98, + 0x89, 0x9f, 0xc1, 0x27, 0x99, 0x11, 0x4f, 0xbd, 0x5f, 0x52, 0x50, 0x89, + 0x65, 0x3e, 0xf7, 0xec, 0xe5, 0xe2, 0xa0, 0xfb, 0x88, 0x0c, 0x32, 0x89, + 0x21, 0x0b, 0x92, 0xd7, 0x5b, 0xf4, 0x6b, 0x24, 0x9a, 0xad, 0xdc, 0x92, + 0x7a, 0x04, 0xfe, 0x00, 0x08, 0x20, 0x82, 0x62, 0x62, 0x62, 0x62, 0x16, + 0x04, 0x10, 0x41, 0x04, 0xfc, 0x80, 0x88, 0x22, 0xa0, 0x84, 0x10, 0x41, + 0x04, 0x62, 0xbc, 0x03, 0xfc, 0x60, 0x40, 0x14, 0x41, 0x30, 0x31, 0x8c, + 0x63, 0x18, 0xc6, 0x31, 0x8c, 0x6f, 0xac, 0x0a, 0x85, 0x93, 0x0b, 0xb1, + 0x2a, 0x64, 0x92, 0x48, 0x84, 0x29, 0x4b, 0x49, 0x24, 0x56, 0xee, 0xfe, + 0x85, 0x63, 0xef, 0x2a, 0x8d, 0x07, 0x14, 0xee, 0x51, 0x63, 0x20, 0xe6, + 0x12, 0x97, 0xb1, 0xa5, 0xcd, 0x3e, 0xbb, 0x13, 0x27, 0xbc, 0xef, 0x5b, + 0x8f, 0x62, 0xb6, 0xe3, 0x85, 0x7b, 0x0d, 0xf6, 0x37, 0x55, 0xf2, 0xef, + 0xff, 0x00, 0x23, 0x49, 0x21, 0x94, 0x9b, 0x45, 0x61, 0x10, 0xe2, 0xeb, + 0xba, 0x25, 0x31, 0xf0, 0xbe, 0x45, 0xb8, 0xd3, 0x15, 0xbf, 0xc8, 0x00, + 0x10, 0x4c, 0x41, 0x31, 0x31, 0x31, 0x31, 0x3e, 0x80, 0x98, 0x89, 0xf8, + 0x62, 0x70, 0xa1, 0xc1, 0x50, 0xfc, 0x90, 0x39, 0x75, 0x00, 0x8f, 0xa4, + 0xf4, 0x82, 0x08, 0x20, 0xc6, 0xc6, 0x3c, 0x46, 0x36, 0x36, 0x36, 0x36, + 0x49, 0x24, 0xf4, 0x06, 0xa0, 0xac, 0x20, 0x52, 0xdb, 0x29, 0x09, 0x92, + 0x27, 0xd4, 0xd4, 0xf8, 0x6c, 0x96, 0x45, 0x67, 0x03, 0x2d, 0x3b, 0x7e, + 0xc5, 0x76, 0x14, 0x24, 0xf2, 0xe7, 0xd8, 0xfa, 0xc4, 0x92, 0x55, 0x7e, + 0x82, 0xe5, 0x07, 0xfe, 0x8a, 0xbf, 0xf4, 0xa1, 0x21, 0x91, 0x4b, 0x44, + 0x6f, 0xa0, 0x98, 0x6f, 0xc8, 0x00, 0x10, 0x4c, 0x41, 0x31, 0x84, 0xc4, + 0xc6, 0xea, 0x02, 0x0a, 0x2f, 0xe0, 0xbc, 0xb5, 0x7f, 0xc2, 0x6b, 0xad, + 0x76, 0x97, 0x09, 0x44, 0x13, 0xa0, 0x36, 0x37, 0x88, 0xc6, 0x36, 0x31, + 0xb2, 0x46, 0xc9, 0xe8, 0x10, 0x57, 0x2f, 0x64, 0x62, 0x49, 0x1b, 0xa3, + 0x29, 0x29, 0x24, 0x0b, 0x55, 0xff, 0x00, 0x6a, 0x9c, 0x4e, 0x66, 0x71, + 0x87, 0x18, 0x71, 0xfe, 0x30, 0x00, 0x82, 0x64, 0x89, 0x89, 0x8c, 0x37, + 0x58, 0x28, 0x2e, 0x14, 0xea, 0xa9, 0x17, 0xfc, 0x33, 0x88, 0x6e, 0x47, + 0x88, 0xa2, 0x8a, 0x28, 0xa2, 0xf4, 0xf3, 0x63, 0x78, 0x8c, 0x36, 0x30, + 0xd9, 0x23, 0x63, 0x78, 0x93, 0x43, 0x36, 0x54, 0xfe, 0xa2, 0x78, 0x13, + 0x18, 0x71, 0xf0, 0x24, 0xb2, 0x42, 0x22, 0x86, 0xa0, 0x9f, 0xfd, 0x6d, + 0x94, 0xc9, 0x53, 0x65, 0x2d, 0x8f, 0xd1, 0x13, 0xfc, 0x60, 0x01, 0x04, + 0x10, 0x4c, 0x4c, 0x61, 0xba, 0xe5, 0x51, 0x05, 0x14, 0x4c, 0x56, 0x13, + 0x13, 0x24, 0x9e, 0xa8, 0x11, 0xc1, 0x02, 0xf8, 0x30, 0xcb, 0xc5, 0x32, + 0xdf, 0xe0, 0x00, 0x6b, 0xd7, 0xab, 0x70, 0x37, 0x81, 0xb1, 0x06, 0x18, + 0x61, 0xe2, 0x27, 0x1a, 0x22, 0x67, 0xcd, 0x3d, 0xd8, 0x89, 0x8d, 0x84, + 0xc3, 0x89, 0x2d, 0x16, 0xca, 0x50, 0xc2, 0x44, 0x44, 0xac, 0x4c, 0x92, + 0x7f, 0xe2, 0x6c, 0x78, 0x4c, 0xbc, 0x3c, 0xac, 0x35, 0x43, 0x8f, 0x89, + 0x3f, 0xc2, 0x04, 0x58, 0x08, 0x20, 0xc2, 0xc0, 0x30, 0xf8, 0x5b, 0xa3, + 0xa8, 0xa2, 0x0b, 0x85, 0xc8, 0x09, 0xc4, 0x08, 0x21, 0x12, 0x9c, 0x12, + 0x79, 0x93, 0x11, 0xcc, 0xa0, 0xac, 0xbd, 0xd0, 0x43, 0x5f, 0x15, 0x23, + 0x7f, 0xbc, 0xda, 0xf3, 0x11, 0x79, 0x79, 0x84, 0xa9, 0x46, 0x5d, 0xe2, + 0x5d, 0x9e, 0x64, 0xab, 0x97, 0x29, 0xa3, 0x97, 0x0b, 0x52, 0x56, 0xd8, + 0x58, 0x92, 0x0c, 0x17, 0x80, 0x61, 0x86, 0x1b, 0xa2, 0xa0, 0xb8, 0x5b, + 0x0d, 0x03, 0x0c, 0x30, 0xd8, 0xd8, 0xd8, 0xc3, 0xc0, 0x43, 0x76, 0xc7, + 0xa1, 0xbc, 0xaf, 0xb6, 0x22, 0xe8, 0x10, 0xc4, 0xcd, 0x14, 0x25, 0x85, + 0x15, 0x81, 0x48, 0x41, 0x61, 0x66, 0x17, 0xfc, 0x0c, 0x8b, 0x09, 0xc4, + 0x63, 0x70, 0x9d, 0x14, 0x98, 0xf5, 0x7d, 0x0f, 0x37, 0xe0, 0x3f, 0x5d, + 0x18, 0x82, 0x62, 0x63, 0x0c, 0x38, 0xc3, 0x7e, 0x0f, 0xaf, 0x80, 0xc4, + 0x02, 0x10, 0x58, 0x6a, 0x1a, 0x68, 0xd1, 0x3d, 0x0d, 0x9d, 0xb4, 0x7b, + 0x89, 0x8e, 0x23, 0x76, 0x64, 0xdc, 0xeb, 0x82, 0x1a, 0xce, 0xde, 0xf1, + 0xef, 0x5a, 0xc0, 0xe1, 0xa5, 0x38, 0x37, 0x0d, 0xd2, 0x4c, 0x05, 0x26, + 0x57, 0x44, 0x69, 0x42, 0xb5, 0x47, 0x7a, 0xa7, 0x02, 0x48, 0x49, 0x43, + 0x63, 0x50, 0x71, 0x13, 0x4f, 0x78, 0x83, 0xef, 0xd7, 0xec, 0xaa, 0x97, + 0x5b, 0xaa, 0xa2, 0x44, 0x51, 0xe0, 0xc6, 0x1b, 0x18, 0x61, 0xb0, 0x36, + 0x23, 0xf4, 0xd1, 0xb0, 0xb8, 0xc3, 0x63, 0x63, 0x0c, 0x30, 0xc2, 0x67, + 0xdc, 0x8a, 0x13, 0x9f, 0xec, 0x62, 0x2e, 0x83, 0x53, 0x0c, 0x94, 0x11, + 0x8a, 0x25, 0x59, 0xe1, 0xa2, 0xa7, 0x82, 0xe3, 0x0b, 0xfe, 0x06, 0xe9, + 0xce, 0x78, 0x19, 0x11, 0x78, 0xa9, 0xd3, 0xa2, 0xff, 0x00, 0x0f, 0xe1, + 0x20, 0x8d, 0x45, 0xa0, 0x2c, 0x8d, 0x60, 0x30, 0xe4, 0x2a, 0x8b, 0xb5, + 0xce, 0x15, 0xe8, 0xee, 0x30, 0xd8, 0x0a, 0x26, 0xd1, 0xf8, 0x89, 0x1e, + 0x6e, 0x3f, 0xb1, 0x42, 0x72, 0x8f, 0x22, 0xe6, 0x72, 0xb2, 0x85, 0x2e, + 0x03, 0x92, 0xa2, 0x10, 0x30, 0x84, 0x37, 0x01, 0xb4, 0x85, 0xac, 0x2c, + 0xe2, 0x96, 0x34, 0x84, 0xa1, 0x50, 0x4a, 0x13, 0x85, 0x95, 0xe4, 0x45, + 0x21, 0xd5, 0xbd, 0x46, 0x95, 0x9e, 0x5a, 0x06, 0x75, 0x9b, 0x15, 0x04, + 0x67, 0xe4, 0x37, 0x38, 0x0d, 0xd0, 0x13, 0x0e, 0x95, 0xc5, 0x3f, 0x61, + 0x77, 0xec, 0x39, 0x37, 0x4e, 0xe3, 0x59, 0xe0, 0x2f, 0x9f, 0x60, 0xb9, + 0x29, 0x35, 0x43, 0xff, 0x00, 0x00, 0xd4, 0x57, 0x70, 0xf4, 0x86, 0x40, + 0x52, 0x64, 0xf2, 0x6a, 0x8a, 0x98, 0x67, 0xfc, 0x0e, 0x0c, 0xbf, 0x38, + 0xe8, 0x2c, 0x74, 0xf5, 0x16, 0x92, 0xc1, 0x58, 0xf1, 0x09, 0xba, 0x05, + 0x7e, 0x78, 0x07, 0xac, 0x7d, 0x1a, 0xe3, 0x8c, 0x51, 0x27, 0x4c, 0xaf, + 0xd3, 0x4a, 0xfa, 0xbc, 0xa4, 0x5b, 0x1a, 0xc8, 0x45, 0x34, 0x4f, 0xa2, + 0x97, 0xe1, 0x49, 0x5a, 0x75, 0xf3, 0x2e, 0xe0, 0x4a, 0xb3, 0xbb, 0x89, + 0x8a, 0x8f, 0xf0, 0x89, 0xb3, 0x0c, 0x3b, 0xc7, 0x79, 0x2a, 0x5c, 0xc2, + 0x2c, 0xe6, 0x56, 0xac, 0x74, 0xb8, 0xbb, 0x3f, 0x45, 0x2a, 0x52, 0xdc, + 0xb2, 0xf5, 0x2e, 0xc2, 0xae, 0xef, 0x08, 0xbb, 0x38, 0x92, 0xd2, 0xcf, + 0x19, 0x8b, 0x93, 0x22, 0x56, 0x9a, 0x8e, 0xe1, 0x14, 0x0d, 0x27, 0x57, + 0xa2, 0x16, 0x8d, 0xbd, 0x46, 0x17, 0x36, 0xe3, 0xd0, 0xd5, 0x32, 0x6b, + 0x5b, 0x02, 0x01, 0x2a, 0x9b, 0x38, 0x2f, 0xa0, 0x15, 0x0c, 0x46, 0x40, + 0xf3, 0x3d, 0x48, 0x03, 0x16, 0xee, 0x28, 0x90, 0x8a, 0x13, 0x90, 0xb5, + 0x20, 0x1e, 0x48, 0xc3, 0x6d, 0x28, 0x40, 0x86, 0x6e, 0xf4, 0xd0, 0x55, + 0xb3, 0x49, 0xe8, 0x42, 0x57, 0x33, 0x8b, 0x92, 0x3e, 0x34, 0x1f, 0xd7, + 0xb4, 0xe4, 0x62, 0x68, 0x6d, 0x18, 0x24, 0xa1, 0x5b, 0xa5, 0x53, 0x8f, + 0x02, 0x51, 0xba, 0x77, 0x64, 0xe0, 0xe5, 0xb9, 0x5b, 0x32, 0x57, 0x6a, + 0x09, 0x3a, 0x89, 0x84, 0x58, 0x6f, 0x4d, 0x55, 0x90, 0xd6, 0x50, 0x7b, + 0xd9, 0x0a, 0x6b, 0x1a, 0x0d, 0x5b, 0xbc, 0x83, 0x61, 0x15, 0x0d, 0x88, + 0x4e, 0xbb, 0x8a, 0x4f, 0xcd, 0x69, 0x9a, 0x0c, 0x08, 0xa5, 0x2f, 0x34, + 0x2a, 0xdd, 0xcb, 0x4b, 0x2d, 0xc5, 0x1a, 0x92, 0x89, 0xd8, 0x52, 0xb3, + 0x11, 0x45, 0x63, 0x3a, 0xc4, 0x58, 0x0c, 0x29, 0x4e, 0x97, 0x1d, 0x9f, + 0xa3, 0x2e, 0xa7, 0xdf, 0xb0, 0xe3, 0xf2, 0x89, 0x2d, 0xb3, 0xd4, 0xa3, + 0x37, 0xc5, 0x0a, 0x13, 0x9f, 0xf8, 0x34, 0x90, 0x8f, 0x1f, 0xa9, 0xae, + 0x1b, 0x21, 0xe0, 0x26, 0x44, 0xb3, 0xd1, 0xeb, 0x2c, 0xbc, 0x38, 0x12, + 0xda, 0x5c, 0x89, 0xd2, 0xa6, 0x95, 0x12, 0x2a, 0xb5, 0xab, 0x50, 0x84, + 0xb1, 0x71, 0xe2, 0x87, 0x95, 0x36, 0x9d, 0xca, 0xf5, 0xab, 0x26, 0xa9, + 0x2e, 0xc6, 0xd6, 0xac, 0x82, 0xb1, 0x2b, 0x84, 0x93, 0xa2, 0x39, 0x2c, + 0xb2, 0x8b, 0x45, 0xcf, 0x05, 0x58, 0x6a, 0x15, 0xde, 0x19, 0x58, 0x88, + 0x57, 0x02, 0x45, 0x43, 0xb3, 0x45, 0x09, 0x92, 0xd1, 0x0a, 0xf3, 0x8d, + 0xaf, 0x49, 0xdb, 0x0a, 0x10, 0xd3, 0x27, 0x6b, 0xca, 0x11, 0x6e, 0x34, + 0xf2, 0x6a, 0xdf, 0x5c, 0x56, 0x05, 0x22, 0xaa, 0x86, 0x9c, 0xae, 0xd6, + 0x02, 0x4d, 0xd0, 0x99, 0xa5, 0xc0, 0xd6, 0x94, 0xef, 0x08, 0x79, 0x67, + 0x95, 0x12, 0xda, 0xe2, 0xae, 0x82, 0x48, 0xd1, 0x51, 0x98, 0xed, 0xb1, + 0x00, 0xe4, 0xb5, 0x58, 0xd5, 0x09, 0xfc, 0xc9, 0xbe, 0x4c, 0xe5, 0x3a, + 0x8b, 0x24, 0x2b, 0xf7, 0xc2, 0xcb, 0xaf, 0xd9, 0x17, 0x4f, 0x81, 0xf2, + 0x24, 0x49, 0x23, 0x41, 0x36, 0x1a, 0xe0, 0xc9, 0x08, 0xb7, 0x23, 0x8f, + 0x91, 0xe8, 0xae, 0xb6, 0xfd, 0x32, 0x44, 0xf9, 0x38, 0xaa, 0x8d, 0xea, + 0x44, 0xca, 0xe0, 0x86, 0x7a, 0x2b, 0x6f, 0x90, 0x95, 0x94, 0x04, 0x81, + 0xc6, 0x34, 0x49, 0xb7, 0xe4, 0x7b, 0x05, 0xf0, 0xf3, 0xcc, 0x79, 0x7a, + 0xcf, 0x80, 0xd4, 0xd8, 0xcf, 0x36, 0x30, 0x82, 0x65, 0x59, 0x86, 0x79, + 0xe6, 0xcc, 0x9a, 0x93, 0x93, 0x59, 0xa1, 0xab, 0xad, 0x47, 0x1d, 0xd8, + 0x4d, 0x03, 0x38, 0xa0, 0xcd, 0x48, 0x26, 0x21, 0x9f, 0xd4, 0x4a, 0xaa, + 0x2c, 0x32, 0x66, 0x64, 0x09, 0x61, 0x55, 0x5c, 0x9b, 0x8a, 0xcf, 0x02, + 0xe4, 0x04, 0xf5, 0x13, 0x3a, 0xd8, 0x66, 0xbd, 0xb0, 0xc3, 0x48, 0x8a, + 0x4b, 0xb9, 0x36, 0x37, 0x2c, 0x4b, 0xa7, 0xca, 0x17, 0x36, 0xa1, 0x67, + 0xc4, 0x08, 0x88, 0x07, 0x9b, 0x3d, 0xd4, 0x93, 0x91, 0xcb, 0xb4, 0xa2, + 0x3a, 0x73, 0x49, 0x18, 0x91, 0x74, 0x47, 0xa6, 0x85, 0x88, 0xf0, 0x8f, + 0x79, 0xa1, 0xa2, 0x31, 0xf2, 0xc9, 0x8f, 0x32, 0x96, 0xfe, 0x2b, 0xda, + 0xf6, 0x1a, 0xae, 0x3e, 0xb3, 0xa8, 0x14, 0x4a, 0x93, 0x66, 0x3a, 0xa8, + 0x39, 0xb6, 0x95, 0xba, 0xb2, 0xfc, 0xd0, 0x48, 0x96, 0x86, 0x26, 0xa2, + 0x0e, 0xbe, 0x71, 0xde, 0x2e, 0x18, 0xc2, 0xd2, 0x5b, 0x49, 0x6e, 0x3a, + 0x6a, 0x36, 0xf5, 0x12, 0xee, 0x47, 0x1a, 0xfd, 0xd4, 0x24, 0xc4, 0x9d, + 0x69, 0xf2, 0x32, 0x45, 0x3b, 0xda, 0x37, 0xf5, 0xfd, 0x0c, 0x51, 0x06, + 0xfa, 0xd2, 0x07, 0xe4, 0x58, 0xa4, 0x88, 0x17, 0x40, 0x15, 0x48, 0x9d, + 0x74, 0xc6, 0x4a, 0x5a, 0xbf, 0xcc, 0x0b, 0x65, 0x34, 0xc0, 0xe4, 0x04, + 0x8a, 0x21, 0x4a, 0xea, 0x92, 0x64, 0x92, 0x21, 0xbb, 0x02, 0x02, 0x4c, + 0x41, 0xd4, 0x37, 0xaa, 0xd7, 0xb8, 0x37, 0x7d, 0x89, 0x86, 0x06, 0x19, + 0x9b, 0x1b, 0x1e, 0x9d, 0x07, 0x28, 0x9b, 0x50, 0x9f, 0xe1, 0x2a, 0x2a, + 0xf5, 0x70, 0xea, 0x33, 0xcc, 0x86, 0x3f, 0xec, 0xa7, 0xb8, 0xd0, 0x9b, + 0x24, 0xa7, 0x91, 0x7d, 0x66, 0x59, 0xac, 0x8b, 0x6b, 0xcb, 0x0f, 0xa0, + 0xf9, 0x36, 0x25, 0x84, 0x3a, 0xf2, 0x91, 0xac, 0xec, 0x57, 0x36, 0xc7, + 0xee, 0xc7, 0x69, 0xa4, 0x9b, 0x03, 0xd0, 0xab, 0xd4, 0xa7, 0xd4, 0x89, + 0x00, 0xa1, 0x34, 0xc8, 0xe7, 0xd3, 0xc1, 0x09, 0x9a, 0xa4, 0x39, 0xe5, + 0xb2, 0x58, 0xc2, 0x6f, 0x25, 0xfd, 0x7d, 0xc6, 0x99, 0xd5, 0x52, 0xe8, + 0x9c, 0x8c, 0x9a, 0xe5, 0x71, 0x5a, 0x8e, 0xa5, 0x7d, 0xd0, 0xaa, 0x06, + 0xe2, 0x67, 0x27, 0x94, 0xb5, 0x74, 0xdb, 0xf4, 0x25, 0xa4, 0x3a, 0xd5, + 0x9a, 0x89, 0xa6, 0x9b, 0x71, 0x2c, 0x4c, 0xaa, 0x50, 0x4f, 0x21, 0x29, + 0x45, 0x2b, 0x20, 0xa4, 0x7b, 0x90, 0xe9, 0x24, 0xdc, 0x94, 0x21, 0xc6, + 0xcc, 0x26, 0xa9, 0xf7, 0x0a, 0xf2, 0x77, 0x2f, 0xd5, 0x89, 0x61, 0xa3, + 0x4b, 0xaa, 0x1f, 0x86, 0x48, 0x94, 0xee, 0xe9, 0xa1, 0x7d, 0x10, 0xf4, + 0x61, 0x3f, 0x9c, 0x26, 0xc1, 0x61, 0x15, 0x84, 0x87, 0x2a, 0x2e, 0x56, + 0x06, 0x41, 0x52, 0x44, 0xcd, 0xda, 0x8f, 0xde, 0x31, 0x45, 0xc9, 0x71, + 0xec, 0x4b, 0x32, 0xa3, 0x63, 0x8a, 0x32, 0x2e, 0x4a, 0xe2, 0x55, 0xb3, + 0xb9, 0x31, 0x99, 0xb3, 0xc0, 0x86, 0xc1, 0xb4, 0x3e, 0x8d, 0xd5, 0xc1, + 0x12, 0x3c, 0x4a, 0x11, 0x79, 0x26, 0x6b, 0xb2, 0x14, 0x42, 0x03, 0x76, + 0xe8, 0xa9, 0xbd, 0xdf, 0x0b, 0x32, 0xb7, 0x61, 0x1e, 0xab, 0x90, 0x89, + 0xa6, 0xf5, 0x7d, 0x37, 0x21, 0xf9, 0x61, 0xc1, 0x77, 0xa8, 0x9c, 0x26, + 0xd5, 0xfc, 0x44, 0xfa, 0x85, 0x76, 0x7d, 0x2b, 0x94, 0x31, 0x19, 0xaa, + 0x51, 0x13, 0x61, 0xd6, 0xa2, 0xc7, 0xe1, 0x3b, 0xc6, 0xe8, 0xe1, 0x3d, + 0x2f, 0x1b, 0x86, 0x84, 0xd4, 0x7a, 0x0f, 0x68, 0x25, 0x10, 0x97, 0xc6, + 0x8f, 0xa1, 0x34, 0xd9, 0x7a, 0x2d, 0xbe, 0xdb, 0x9e, 0xf4, 0x1f, 0x52, + 0x35, 0x62, 0x69, 0xae, 0xa3, 0x7e, 0x11, 0x08, 0xe7, 0x54, 0x2f, 0x55, + 0x84, 0x13, 0xc8, 0x0b, 0x55, 0x07, 0x3c, 0xc6, 0x64, 0xd0, 0x36, 0xaa, + 0x68, 0x3d, 0x46, 0xc8, 0x12, 0x68, 0x14, 0x11, 0x2a, 0xe7, 0xb4, 0xdf, + 0x02, 0x61, 0x64, 0x29, 0xc2, 0x76, 0x53, 0x0a, 0x04, 0x51, 0xdc, 0x4f, + 0xb8, 0x26, 0xe9, 0x04, 0x7f, 0x91, 0x14, 0x8b, 0xe4, 0x2a, 0xda, 0x11, + 0x46, 0xe3, 0xbb, 0xb4, 0xc9, 0xdc, 0xd3, 0x78, 0x6d, 0x1f, 0xc2, 0xd5, + 0x29, 0x62, 0xce, 0xe3, 0x9d, 0xa8, 0xb5, 0x34, 0x1d, 0x35, 0x32, 0xb5, + 0x0f, 0x72, 0xd8, 0x4f, 0xb8, 0x93, 0x27, 0x21, 0x10, 0x64, 0xc9, 0x16, + 0xf5, 0x89, 0xb1, 0xea, 0x30, 0x83, 0xa6, 0xbb, 0x49, 0x5e, 0x81, 0x11, + 0x04, 0xa6, 0x0c, 0x91, 0xe8, 0x10, 0xc6, 0x35, 0x1a, 0x0d, 0xb5, 0x50, + 0xc6, 0x57, 0x45, 0x6e, 0x1d, 0x9f, 0xa1, 0x90, 0x40, 0x42, 0x17, 0xed, + 0xc8, 0xf4, 0x57, 0x05, 0x90, 0xa1, 0xa9, 0xaa, 0xd5, 0x0d, 0x9e, 0xe2, + 0x48, 0x5d, 0xe4, 0x9d, 0xe2, 0xa6, 0x44, 0xc1, 0xbd, 0x0b, 0xcb, 0xb9, + 0x3a, 0x94, 0xbb, 0x82, 0x75, 0x02, 0x5c, 0x05, 0xd8, 0x28, 0x41, 0xd3, + 0xa0, 0x95, 0x60, 0x56, 0xfd, 0x9d, 0x7b, 0xa1, 0x7a, 0x94, 0xd5, 0xb6, + 0xc7, 0xd1, 0x28, 0xdc, 0x3c, 0x80, 0x96, 0x6a, 0xaf, 0xd0, 0xae, 0xba, + 0x49, 0x21, 0x85, 0x43, 0x56, 0x2d, 0x01, 0xbf, 0x23, 0xa6, 0x92, 0x1e, + 0x47, 0x34, 0x35, 0xaa, 0x74, 0x1a, 0xee, 0x14, 0xb3, 0x1d, 0x36, 0x44, + 0xe5, 0x7a, 0x0d, 0x98, 0xfa, 0x59, 0x79, 0x11, 0x9e, 0x72, 0x9c, 0xd9, + 0x69, 0xe0, 0x9f, 0x7b, 0xd8, 0x1f, 0xa0, 0x10, 0x48, 0x68, 0xaa, 0x35, + 0xf8, 0x12, 0xab, 0x28, 0x33, 0xd2, 0x1a, 0x43, 0x84, 0x42, 0x49, 0x14, + 0x5d, 0x41, 0xe6, 0x12, 0x2c, 0x96, 0xa2, 0xc8, 0x4a, 0x5a, 0x77, 0x14, + 0xb1, 0x91, 0xbd, 0x3a, 0x18, 0x6a, 0xe8, 0x2a, 0xa0, 0xf2, 0x86, 0xe5, + 0xb5, 0xa1, 0x22, 0x94, 0x7a, 0xc0, 0x83, 0x93, 0x44, 0x14, 0x64, 0x92, + 0x11, 0x46, 0x72, 0xc8, 0xb0, 0x3f, 0x91, 0x09, 0x56, 0xa1, 0x50, 0xe6, + 0xc6, 0x57, 0x96, 0x09, 0xee, 0x27, 0xaa, 0x0a, 0x18, 0x1e, 0x21, 0x55, + 0x60, 0x73, 0xb4, 0xbd, 0xa3, 0xe1, 0x0a, 0xbc, 0xb8, 0x42, 0xa4, 0xea, + 0x29, 0xfe, 0x43, 0xf7, 0x25, 0x34, 0xd1, 0xc2, 0xf9, 0x65, 0x89, 0x36, + 0xde, 0xfd, 0x70, 0x49, 0x25, 0x2b, 0x21, 0xc9, 0xaa, 0xb9, 0x07, 0xa9, + 0x1a, 0xfe, 0x45, 0xf1, 0x0f, 0x46, 0x2b, 0x7d, 0x11, 0xc8, 0x41, 0x79, + 0x41, 0xee, 0xc3, 0x9d, 0x22, 0x37, 0x32, 0xa0, 0x79, 0x0d, 0xab, 0xfd, + 0xb7, 0xd4, 0x8d, 0x0e, 0x65, 0x88, 0xf0, 0xb4, 0xf4, 0x88, 0x0b, 0x5a, + 0x0a, 0x36, 0xb4, 0x78, 0x94, 0x4e, 0x91, 0xae, 0x15, 0x93, 0x79, 0x4f, + 0x63, 0xd6, 0x75, 0x2f, 0x2b, 0xf4, 0x4c, 0x35, 0x65, 0x3e, 0xc5, 0x21, + 0xff, 0x00, 0x91, 0xee, 0x75, 0x65, 0x15, 0x18, 0xf5, 0x18, 0x92, 0xae, + 0x70, 0xf1, 0x0a, 0x46, 0xc9, 0xb8, 0xd4, 0xac, 0xf7, 0x1d, 0x32, 0xdd, + 0x8d, 0x42, 0x91, 0xc5, 0x6b, 0x30, 0xc9, 0xe6, 0x38, 0xb4, 0xba, 0x1e, + 0xbf, 0xe0, 0xcd, 0xbc, 0x55, 0x8d, 0xdc, 0xe2, 0x3b, 0x6b, 0x43, 0x2b, + 0x22, 0x31, 0x25, 0x7c, 0x4b, 0xc8, 0xd2, 0x15, 0x71, 0x15, 0x62, 0x78, + 0x09, 0xc1, 0xb8, 0xcc, 0xf5, 0xc2, 0xc6, 0x1c, 0x62, 0x2d, 0x03, 0x7b, + 0xa1, 0xcc, 0x48, 0xc5, 0x84, 0xc8, 0x6b, 0x83, 0xc5, 0x34, 0x9f, 0x36, + 0x13, 0xd6, 0x6f, 0xe0, 0xab, 0x4c, 0x8f, 0x40, 0xbf, 0x7f, 0x22, 0x71, + 0x9a, 0x70, 0xd0, 0x9b, 0x93, 0xea, 0xb4, 0x1b, 0x76, 0x2e, 0xd1, 0xb7, + 0xcc, 0x21, 0x96, 0xa1, 0x1f, 0x2a, 0x45, 0xac, 0x4d, 0x72, 0xdb, 0xb7, + 0x06, 0xe4, 0x6d, 0x4f, 0xb5, 0x09, 0x87, 0x9e, 0x72, 0x47, 0x30, 0x89, + 0xf6, 0x9d, 0x59, 0x3f, 0xf6, 0x36, 0x8b, 0xd2, 0x3d, 0x75, 0x41, 0xc8, + 0x96, 0xa9, 0x89, 0x8f, 0xd8, 0x88, 0xe1, 0x78, 0xdf, 0x23, 0xc3, 0xc4, + 0x75, 0xe7, 0x14, 0xc8, 0x9c, 0x67, 0xfc, 0x8f, 0x2f, 0xa5, 0x9c, 0x1a, + 0x10, 0x93, 0x6d, 0x3b, 0xaa, 0x68, 0x53, 0x9a, 0x60, 0xab, 0x7c, 0x1b, + 0x1a, 0xd4, 0x75, 0xa4, 0xd9, 0x11, 0x2a, 0xd9, 0x2b, 0xee, 0xdd, 0xd9, + 0x92, 0xe6, 0x58, 0x85, 0x59, 0x79, 0x5f, 0xd6, 0xa0, 0xc3, 0x0c, 0x48, + 0xc2, 0x78, 0x1e, 0x08, 0xdb, 0x2a, 0x25, 0x82, 0x07, 0x5d, 0x06, 0xa5, + 0x2c, 0x56, 0xeb, 0x8e, 0xe3, 0x4b, 0x12, 0x84, 0x4d, 0x55, 0x34, 0x23, + 0x5e, 0x51, 0x17, 0xa8, 0xa3, 0x44, 0x28, 0xb2, 0x1f, 0xd1, 0x32, 0xf5, + 0x52, 0xae, 0x24, 0x92, 0x26, 0x24, 0xa0, 0x9a, 0x5d, 0x90, 0xd0, 0x57, + 0xcf, 0xdd, 0x14, 0x89, 0x18, 0x61, 0x0a, 0xa8, 0x84, 0x1f, 0x55, 0xd5, + 0x55, 0x7e, 0xef, 0x53, 0x2e, 0x84, 0x54, 0x76, 0x26, 0xca, 0x16, 0x82, + 0xfc, 0xcc, 0xf4, 0x37, 0xb9, 0xc3, 0xcd, 0x24, 0x86, 0xb9, 0x4d, 0xe6, + 0xa1, 0xe4, 0x27, 0x2d, 0xd8, 0xd5, 0xed, 0x1e, 0xe2, 0xd5, 0xcb, 0xf0, + 0x32, 0x4c, 0x4d, 0xcb, 0xc0, 0xda, 0xf0, 0x32, 0x4f, 0xb1, 0x0e, 0xcc, + 0xee, 0x28, 0x42, 0x7a, 0x3c, 0x97, 0xa7, 0x45, 0x1a, 0x79, 0x95, 0x21, + 0xb9, 0x94, 0xaf, 0xa8, 0x96, 0xbf, 0x29, 0xa1, 0xad, 0x0a, 0x72, 0x62, + 0xec, 0xd3, 0xd0, 0xa7, 0x77, 0x26, 0xfc, 0xaa, 0xd2, 0x3a, 0x27, 0xa8, + 0xf5, 0x63, 0x54, 0x6c, 0x92, 0xae, 0x70, 0xf1, 0xc8, 0x42, 0x70, 0x5b, + 0x21, 0x68, 0x93, 0x35, 0x21, 0x31, 0x5d, 0x27, 0x32, 0x15, 0x65, 0x6d, + 0x9c, 0x8d, 0x20, 0x2a, 0xb7, 0x2d, 0x43, 0x36, 0x79, 0xc3, 0x4c, 0x1b, + 0x62, 0x13, 0x2c, 0xaa, 0x4a, 0xe6, 0xfb, 0x10, 0x4d, 0x28, 0x98, 0x43, + 0x38, 0x14, 0x89, 0x60, 0x4c, 0x81, 0x9e, 0xc4, 0x83, 0x57, 0x81, 0x86, + 0xc7, 0x18, 0xbf, 0xfb, 0xaa, 0x1c, 0x32, 0x23, 0x4b, 0x1d, 0x35, 0x50, + 0xdc, 0x44, 0xa2, 0x6d, 0x45, 0xf0, 0xe0, 0x87, 0x5d, 0x0f, 0x66, 0x05, + 0x48, 0x65, 0x3f, 0x71, 0x55, 0x76, 0x1c, 0xd8, 0xb9, 0xfa, 0x50, 0xf5, + 0xd8, 0x8b, 0xb4, 0x9a, 0xca, 0xd0, 0x44, 0x8d, 0x91, 0xd0, 0x47, 0x2a, + 0x66, 0x3d, 0x44, 0x88, 0xa6, 0xb5, 0x12, 0x71, 0x5a, 0xea, 0x54, 0x71, + 0xcc, 0xa3, 0x2a, 0xb0, 0x5a, 0x14, 0x85, 0xb0, 0xaa, 0x67, 0x03, 0x65, + 0xb3, 0xbc, 0x0c, 0x53, 0xee, 0x1c, 0x76, 0xce, 0xa4, 0xfa, 0xbb, 0x23, + 0x1d, 0x9a, 0x9b, 0xd5, 0x66, 0x7d, 0xb4, 0x1a, 0x44, 0x6e, 0xb3, 0x2b, + 0xcd, 0x33, 0x5f, 0xc2, 0xd5, 0xe6, 0x6a, 0xd0, 0x82, 0x64, 0xbd, 0x88, + 0x04, 0xfb, 0x99, 0x0c, 0x30, 0xc4, 0xe0, 0x4c, 0x64, 0x4e, 0xda, 0x38, + 0x0c, 0x3c, 0x36, 0x1e, 0x55, 0xb1, 0x27, 0x10, 0xf0, 0x23, 0x1b, 0x2c, + 0x86, 0x6b, 0x22, 0xe1, 0xe5, 0xb1, 0x03, 0xb0, 0xd2, 0x6d, 0xdc, 0x59, + 0xa7, 0x61, 0xa1, 0x26, 0xda, 0xa6, 0x63, 0x43, 0xee, 0x39, 0x32, 0x87, + 0x2a, 0x03, 0x98, 0x82, 0x08, 0x30, 0xe7, 0xd0, 0xdd, 0x0f, 0x42, 0x70, + 0x18, 0x42, 0x16, 0x42, 0x52, 0xd8, 0x35, 0x50, 0xb9, 0xc8, 0xee, 0x97, + 0x8b, 0xc1, 0x0f, 0x25, 0x9b, 0x6a, 0xf1, 0x48, 0x08, 0x05, 0x48, 0x88, + 0xa0, 0x80, 0xac, 0x59, 0xc5, 0xeb, 0xb7, 0xe8, 0x01, 0x56, 0x67, 0x0d, + 0x7f, 0x88, 0x78, 0x32, 0x86, 0x7d, 0xa5, 0x8c, 0x3d, 0x49, 0x24, 0xab, + 0x87, 0xa1, 0xe8, 0x53, 0x96, 0x08, 0x42, 0x6a, 0x72, 0x15, 0x43, 0xb1, + 0x7c, 0x8f, 0x5a, 0x9b, 0x6d, 0x4a, 0x8b, 0x95, 0x45, 0x6c, 0x10, 0xb8, + 0x93, 0x95, 0x41, 0x72, 0x33, 0x10, 0x42, 0x10, 0x8d, 0xbe, 0x77, 0xe8, + 0x4d, 0x65, 0x83, 0x8d, 0x8e, 0x31, 0x7b, 0xf7, 0x5c, 0x02, 0x66, 0x5c, + 0x49, 0x59, 0xc0, 0xf0, 0xaa, 0x06, 0xfb, 0x88, 0xa4, 0x52, 0x78, 0x19, + 0x4d, 0x35, 0x29, 0xe4, 0x2d, 0x80, 0xf5, 0x31, 0x5e, 0x37, 0xc9, 0x41, + 0xa5, 0x35, 0x49, 0xd9, 0x8d, 0x2c, 0xc9, 0x3c, 0xc8, 0x2c, 0x3e, 0xec, + 0x5e, 0x90, 0xd4, 0xd0, 0x41, 0xa2, 0x5b, 0x99, 0xa9, 0x93, 0x26, 0xa9, + 0xf8, 0x28, 0x26, 0x9b, 0x98, 0x96, 0x93, 0x57, 0x60, 0xaf, 0x43, 0xd4, + 0x27, 0x32, 0x8b, 0x35, 0xb6, 0xc7, 0x4c, 0x10, 0xef, 0xdf, 0xeb, 0x2f, + 0xe0, 0x83, 0xa1, 0x42, 0x4c, 0x21, 0x2b, 0xa1, 0xc9, 0x35, 0xcb, 0x36, + 0xe8, 0x89, 0x1a, 0x5c, 0xee, 0x21, 0xa4, 0x49, 0xb1, 0x54, 0x75, 0xba, + 0x0c, 0x55, 0x0a, 0xa7, 0xd0, 0x32, 0x2f, 0x63, 0x0d, 0x8a, 0xf8, 0x24, + 0x63, 0xc3, 0xb6, 0x0d, 0x8d, 0x8d, 0xe0, 0x62, 0xae, 0x31, 0xbc, 0x43, + 0x63, 0xd3, 0x06, 0xb0, 0x43, 0xd4, 0x5d, 0xd4, 0x50, 0x34, 0x31, 0xd6, + 0xea, 0xe0, 0xa3, 0x5a, 0x4b, 0x82, 0x89, 0xe6, 0x84, 0x92, 0x27, 0xb9, + 0x2f, 0x92, 0x1b, 0xa6, 0x59, 0x18, 0xd2, 0x53, 0xaf, 0xec, 0x35, 0x06, + 0xc6, 0x1b, 0x10, 0xa8, 0x40, 0x52, 0x7d, 0xca, 0x88, 0xc3, 0x52, 0x8c, + 0x65, 0x5a, 0xe0, 0xa0, 0xfa, 0x9f, 0xb3, 0x62, 0x20, 0xa3, 0x55, 0x33, + 0xe5, 0xa8, 0x7b, 0x57, 0xe0, 0x64, 0xe1, 0x43, 0x76, 0xf9, 0x8f, 0x41, + 0xea, 0x49, 0x25, 0x64, 0xee, 0x49, 0x25, 0x8e, 0x04, 0x2c, 0x1b, 0x96, + 0x92, 0xab, 0xd9, 0xfe, 0x83, 0x33, 0x55, 0x27, 0x90, 0x4e, 0x25, 0xf3, + 0x2b, 0xb3, 0x20, 0xad, 0x72, 0x7a, 0x84, 0xb3, 0x18, 0x4c, 0x4c, 0x4c, + 0x9f, 0xfd, 0xa0, 0x41, 0x58, 0x72, 0x47, 0xa8, 0xc5, 0xc6, 0xcc, 0x5b, + 0x78, 0xd8, 0x4a, 0xa5, 0x67, 0x80, 0xae, 0x56, 0x35, 0x12, 0x68, 0x25, + 0x9b, 0x2e, 0x5f, 0x8e, 0x82, 0xe6, 0x88, 0xda, 0xe2, 0xfa, 0x7c, 0x8f, + 0xad, 0x84, 0x31, 0xe5, 0x31, 0xc0, 0xff, 0x00, 0x21, 0xca, 0xb2, 0x1d, + 0x53, 0x9e, 0x1c, 0x4b, 0x0d, 0x49, 0x4c, 0x22, 0xb4, 0x23, 0x29, 0x0b, + 0x80, 0x92, 0x94, 0xb4, 0x5d, 0xc7, 0x1a, 0xc6, 0x94, 0xa9, 0xc2, 0xd8, + 0xae, 0x8c, 0x98, 0x95, 0x1a, 0x84, 0x45, 0x44, 0xfd, 0x92, 0xf0, 0x4a, + 0x9f, 0x92, 0xe2, 0x24, 0x58, 0x84, 0x69, 0x49, 0x6e, 0x49, 0x6e, 0x3f, + 0xa1, 0x31, 0xe4, 0x3e, 0xc5, 0xe1, 0x89, 0x10, 0x89, 0xc1, 0xa1, 0x79, + 0x32, 0x18, 0xc6, 0x24, 0x7e, 0x2e, 0x64, 0x94, 0x91, 0x23, 0xb0, 0xc7, + 0x61, 0x29, 0x63, 0x56, 0x91, 0xba, 0xbf, 0x47, 0x82, 0xa7, 0x19, 0x4a, + 0xe2, 0x5c, 0xd4, 0x71, 0xb9, 0x22, 0x55, 0x51, 0x47, 0x3c, 0x39, 0x19, + 0xa3, 0x50, 0xa4, 0xa4, 0x4f, 0x44, 0xc0, 0x9b, 0x70, 0x88, 0x24, 0x22, + 0x2f, 0x90, 0xf4, 0x1b, 0xc0, 0x6c, 0x4c, 0x81, 0x90, 0xf2, 0x09, 0xe4, + 0x89, 0xf8, 0x13, 0x49, 0xcc, 0x7b, 0xff, 0x00, 0x05, 0xb3, 0xcf, 0x85, + 0x0a, 0x44, 0x96, 0xc1, 0x0c, 0x7d, 0xe8, 0x5b, 0xb6, 0x29, 0x1a, 0x86, + 0xbe, 0xe3, 0x50, 0x6a, 0x92, 0x36, 0x3d, 0x45, 0x3c, 0xd8, 0xda, 0xe3, + 0x04, 0xc9, 0x19, 0xea, 0x6b, 0x74, 0xb6, 0x5c, 0x19, 0x31, 0xdb, 0x21, + 0x39, 0x8a, 0x22, 0x41, 0xab, 0xd4, 0xef, 0x20, 0xb3, 0x22, 0x29, 0x99, + 0x55, 0x48, 0x2e, 0x7e, 0x85, 0x3c, 0x31, 0x4c, 0x93, 0xc6, 0x78, 0x59, + 0x0f, 0x89, 0x8f, 0x6b, 0xe4, 0x52, 0xc2, 0x7a, 0xe2, 0x57, 0x2c, 0x05, + 0x71, 0x97, 0x28, 0xa3, 0x62, 0x42, 0x87, 0x7d, 0x25, 0x0b, 0x30, 0xa3, + 0x7a, 0x8b, 0xb3, 0xd4, 0x56, 0xa9, 0x92, 0x54, 0x7a, 0x13, 0x22, 0xa0, + 0xb7, 0x34, 0xc1, 0x65, 0x23, 0x48, 0x4b, 0x27, 0x54, 0x9d, 0x5e, 0xe2, + 0x92, 0x98, 0x41, 0x92, 0x34, 0xad, 0x51, 0x0a, 0xb6, 0x57, 0xcc, 0x9e, + 0x58, 0x16, 0x79, 0x5f, 0x71, 0x91, 0x30, 0x8e, 0xd1, 0x2a, 0x9b, 0x6e, + 0x3d, 0xe1, 0xef, 0xd9, 0x61, 0x93, 0x94, 0x52, 0x4c, 0x3c, 0x08, 0x92, + 0x49, 0x0f, 0x2c, 0xd8, 0x6c, 0xb9, 0x51, 0xb8, 0x3d, 0xb1, 0x50, 0x1e, + 0x0d, 0x3d, 0x4b, 0x0a, 0x54, 0x42, 0x25, 0x4c, 0xc4, 0xe0, 0xe3, 0x1a, + 0x55, 0xe5, 0xfd, 0x9a, 0x25, 0xb4, 0xaa, 0x5b, 0xf7, 0x11, 0xb1, 0x98, + 0x46, 0xfc, 0xa1, 0x48, 0xaa, 0x9b, 0xbf, 0x5e, 0xb7, 0xfa, 0xb5, 0x1a, + 0x83, 0x63, 0x0d, 0x93, 0x81, 0x43, 0xd0, 0x8b, 0x74, 0xeb, 0xee, 0x88, + 0xbe, 0xa1, 0xd8, 0xd3, 0x85, 0x86, 0x18, 0x62, 0x26, 0x46, 0xe2, 0x14, + 0x4e, 0xea, 0x71, 0x48, 0x76, 0xa9, 0xec, 0x38, 0x6a, 0x92, 0x36, 0x58, + 0xcf, 0x56, 0xf1, 0xb5, 0xc6, 0x09, 0x8e, 0x93, 0x52, 0x3a, 0x25, 0x28, + 0x0d, 0xd0, 0x82, 0x34, 0xc5, 0xa3, 0xa5, 0x1c, 0x2c, 0x14, 0xf7, 0x55, + 0x26, 0x4a, 0x06, 0x69, 0x68, 0x9d, 0x48, 0x27, 0x56, 0x20, 0xc4, 0xc9, + 0x13, 0x24, 0xf1, 0xb5, 0xea, 0xb0, 0xa6, 0x83, 0x60, 0xc3, 0x9f, 0x73, + 0x92, 0x44, 0x28, 0x42, 0xe1, 0xc7, 0x16, 0x5a, 0x12, 0x8c, 0x04, 0xe8, + 0x4d, 0x3c, 0x04, 0xf3, 0x92, 0xd4, 0xc8, 0x4a, 0xaa, 0xd1, 0x4b, 0xf8, + 0x2b, 0x6d, 0xbb, 0xe3, 0x19, 0xe4, 0x55, 0xf8, 0xf4, 0xf6, 0x22, 0xd5, + 0x4a, 0x82, 0x1e, 0x75, 0xc1, 0x0a, 0xbc, 0xe0, 0x6a, 0x1d, 0xa5, 0xee, + 0x29, 0x6d, 0x02, 0x4d, 0x7f, 0x31, 0x23, 0x76, 0x2e, 0x12, 0x71, 0x33, + 0xd6, 0x17, 0xe2, 0x4c, 0x92, 0x46, 0xea, 0x3c, 0xbd, 0xa3, 0x93, 0x28, + 0x89, 0xa8, 0xb0, 0x30, 0x1e, 0x01, 0x8c, 0x63, 0x65, 0xc4, 0xe0, 0x3d, + 0xcc, 0xc6, 0xa6, 0x7f, 0x68, 0xb3, 0xb0, 0xa4, 0x55, 0x57, 0x43, 0xc5, + 0xbe, 0xad, 0x4b, 0x06, 0xc6, 0x1b, 0x24, 0x72, 0x1f, 0xc2, 0x69, 0x14, + 0xad, 0xe7, 0x3c, 0x0f, 0xac, 0x16, 0x8f, 0xd0, 0xa8, 0x1a, 0x07, 0xe8, + 0x9f, 0xfa, 0x2c, 0x28, 0x6e, 0xbf, 0x04, 0x38, 0x61, 0x24, 0x96, 0x9e, + 0xa9, 0x8d, 0xac, 0x27, 0x05, 0x75, 0x8a, 0x8f, 0x0a, 0xf9, 0x19, 0x32, + 0xeb, 0xae, 0x6d, 0x85, 0x27, 0x31, 0x36, 0x61, 0x36, 0x88, 0xa4, 0x49, + 0x2d, 0x48, 0xe5, 0xd8, 0x4b, 0x19, 0x24, 0x8f, 0x77, 0x00, 0x6a, 0x0d, + 0x83, 0x0c, 0x4c, 0xf5, 0xfd, 0x88, 0x01, 0xa7, 0x03, 0x71, 0x23, 0x14, + 0xe4, 0x10, 0x8b, 0x4a, 0x3d, 0xe0, 0x68, 0x20, 0x37, 0x5a, 0x14, 0x0d, + 0x33, 0x89, 0x57, 0x66, 0xde, 0x1f, 0xe8, 0x78, 0xa7, 0xe2, 0x7c, 0x8d, + 0x0a, 0x5c, 0x83, 0x97, 0xe5, 0x09, 0x52, 0xbb, 0x18, 0xcd, 0x42, 0x28, + 0x68, 0x87, 0x3d, 0x29, 0x35, 0x62, 0xb3, 0x55, 0xd4, 0x7c, 0x48, 0x23, + 0xea, 0xc7, 0xaf, 0x14, 0x72, 0x97, 0xe2, 0x92, 0x49, 0x1b, 0x1a, 0x78, + 0xe3, 0x63, 0x4b, 0x68, 0x4a, 0x08, 0xc6, 0xbc, 0xa1, 0x0e, 0x29, 0x0c, + 0x32, 0x47, 0x1b, 0x97, 0x05, 0x48, 0xb7, 0x13, 0x63, 0x0d, 0x7b, 0x50, + 0x4f, 0x43, 0x01, 0x6b, 0xa1, 0x8f, 0x07, 0xfb, 0x75, 0x45, 0x83, 0x0d, + 0x84, 0x8d, 0x52, 0x80, 0x7f, 0x4f, 0xd8, 0x6e, 0xb1, 0xe0, 0x58, 0xf7, + 0xd6, 0x07, 0xe6, 0xe9, 0x4d, 0x5b, 0x83, 0xb3, 0x5f, 0xe0, 0x98, 0x8a, + 0xb6, 0xaf, 0xec, 0x89, 0xcc, 0x24, 0x92, 0x5a, 0x7a, 0xb1, 0x24, 0x96, + 0x48, 0x56, 0xed, 0xc0, 0xe6, 0xc1, 0x53, 0x50, 0x85, 0x25, 0x4d, 0x18, + 0xae, 0xaa, 0xf1, 0xca, 0x53, 0x2b, 0x13, 0x66, 0x95, 0xcd, 0xc7, 0xa9, + 0xc4, 0x63, 0x4e, 0xd8, 0x2e, 0x01, 0x51, 0xaa, 0x13, 0xb0, 0xd5, 0xbb, + 0x19, 0x6f, 0xd3, 0x04, 0x35, 0x4f, 0x92, 0xf1, 0xc6, 0xf1, 0x31, 0x2b, + 0xdd, 0x0a, 0x11, 0x16, 0x11, 0xc4, 0x49, 0x5d, 0x0a, 0x8d, 0x88, 0xa0, + 0x47, 0xd4, 0x22, 0xde, 0x79, 0x92, 0x88, 0x21, 0x30, 0xda, 0xc2, 0x02, + 0x4c, 0x9d, 0x53, 0xe8, 0x3b, 0xe3, 0x3e, 0x27, 0xc9, 0x71, 0x20, 0x25, + 0x24, 0x96, 0x70, 0xa8, 0x32, 0x30, 0x26, 0x52, 0x34, 0x13, 0xc1, 0x79, + 0x16, 0xf3, 0x2e, 0x78, 0x2b, 0x95, 0x63, 0x4f, 0x39, 0x47, 0x28, 0x6a, + 0x92, 0x22, 0x49, 0x1b, 0x1b, 0x19, 0x88, 0x8d, 0x91, 0x03, 0x41, 0x39, + 0x95, 0x9e, 0x46, 0xa0, 0x5b, 0x88, 0x62, 0xb8, 0x16, 0x56, 0x87, 0x83, + 0x33, 0x42, 0xc3, 0xa0, 0xda, 0x2a, 0x69, 0xd9, 0x52, 0x2a, 0x4f, 0x43, + 0x40, 0x65, 0x37, 0x52, 0x08, 0x28, 0x1c, 0xd4, 0xb5, 0x8c, 0x8d, 0x8c, + 0x9a, 0x8f, 0xf7, 0xea, 0x8b, 0x06, 0x18, 0x92, 0x46, 0x20, 0x06, 0xad, + 0xec, 0xbd, 0x86, 0x18, 0x7e, 0x80, 0x50, 0x46, 0x18, 0xac, 0x3c, 0x23, + 0x8d, 0x85, 0xc6, 0xc5, 0x51, 0xdf, 0x3c, 0x85, 0x52, 0xcc, 0x43, 0x90, + 0x59, 0xb8, 0x5b, 0xb5, 0x62, 0x88, 0x90, 0x49, 0x25, 0x87, 0xa8, 0x13, + 0x85, 0x81, 0x53, 0xa4, 0xc1, 0x41, 0xaa, 0xe4, 0x9a, 0x8f, 0x03, 0xa2, + 0xa0, 0xa9, 0xd0, 0x1e, 0x65, 0xa4, 0x91, 0x2f, 0x45, 0x81, 0x2f, 0xfa, + 0x3d, 0x29, 0x27, 0xce, 0x09, 0xca, 0xc9, 0xa0, 0xfe, 0x66, 0xe1, 0x11, + 0x09, 0x24, 0xa5, 0xfd, 0x51, 0x97, 0x8e, 0x3c, 0x18, 0x7a, 0x8f, 0x1c, + 0x41, 0xe4, 0x40, 0xa7, 0xa0, 0x2b, 0x10, 0x91, 0x89, 0x2f, 0x22, 0x7e, + 0x4e, 0x03, 0x04, 0xb0, 0xf4, 0x9d, 0x3b, 0xa2, 0xb4, 0x5f, 0xb6, 0x2d, + 0xe2, 0x7c, 0x05, 0x93, 0x32, 0xfd, 0x8a, 0xac, 0x3a, 0xe7, 0x62, 0x04, + 0x38, 0x5c, 0x5e, 0xa9, 0x91, 0xdc, 0x48, 0x43, 0x48, 0xc3, 0x94, 0x7c, + 0x42, 0x1a, 0x21, 0xd9, 0x8b, 0x50, 0x4b, 0x4e, 0x6a, 0x09, 0xaf, 0x14, + 0x72, 0x0b, 0xb0, 0x58, 0x38, 0x0d, 0x0a, 0x8f, 0x59, 0xf7, 0xc0, 0x91, + 0xa4, 0x6b, 0x0a, 0x22, 0x56, 0xa1, 0x54, 0x49, 0xce, 0x08, 0x41, 0x6e, + 0xe7, 0xd5, 0x5a, 0x0c, 0x9a, 0xd0, 0x9e, 0x28, 0xac, 0xc4, 0x99, 0xb0, + 0xda, 0x19, 0xc0, 0xde, 0xb2, 0xd1, 0x24, 0xe0, 0xd8, 0xd9, 0x23, 0x7d, + 0x3a, 0xac, 0x07, 0x18, 0x92, 0x44, 0xf0, 0x2f, 0x69, 0x0f, 0xd3, 0x62, + 0x8a, 0xc3, 0x5d, 0x5e, 0x0d, 0x84, 0xe3, 0x63, 0xae, 0x1b, 0x08, 0x92, + 0x47, 0xaf, 0xff, 0x00, 0xb2, 0x22, 0x8b, 0xf4, 0x92, 0x89, 0x90, 0xef, + 0x84, 0x96, 0x1e, 0xac, 0x49, 0x23, 0x78, 0x09, 0xc6, 0x5e, 0x90, 0xc6, + 0xf2, 0xb1, 0x5c, 0x5a, 0x36, 0x4a, 0xb1, 0x5d, 0x90, 0xcd, 0x26, 0x1e, + 0xe7, 0xd9, 0x16, 0xe4, 0xa8, 0x6c, 0x60, 0xcd, 0xd9, 0x88, 0xd4, 0xda, + 0xe1, 0x54, 0x24, 0x4c, 0x4c, 0x4c, 0xa0, 0xfd, 0xd3, 0x0b, 0x92, 0x48, + 0x87, 0x1a, 0x38, 0xc3, 0xc9, 0x6a, 0x23, 0xd0, 0x8e, 0x55, 0x78, 0x1a, + 0xe2, 0x07, 0x24, 0x44, 0x88, 0x42, 0xe3, 0xd1, 0x0d, 0xd7, 0xd2, 0xfc, + 0x0f, 0x07, 0x98, 0x75, 0x74, 0xb5, 0x87, 0x38, 0x8a, 0xbe, 0xf5, 0xb1, + 0x19, 0xb9, 0x9e, 0xef, 0xf3, 0x21, 0x39, 0x13, 0x25, 0x20, 0xe4, 0xa1, + 0x56, 0x39, 0x04, 0xe5, 0x2f, 0x8a, 0x16, 0xe1, 0xdc, 0x20, 0x4c, 0x91, + 0xd0, 0xa3, 0x93, 0xee, 0x5d, 0x82, 0xc0, 0x69, 0x2c, 0x28, 0x87, 0x22, + 0x4d, 0x0d, 0x56, 0x5f, 0xb8, 0xf8, 0x19, 0x8c, 0x49, 0x1e, 0x3d, 0x13, + 0x2f, 0x11, 0xd8, 0x89, 0x87, 0x51, 0x35, 0xc0, 0x68, 0x66, 0xc4, 0xb3, + 0xdb, 0xe4, 0x44, 0xd0, 0x6a, 0x39, 0x2c, 0x12, 0x49, 0x24, 0x8d, 0x93, + 0x51, 0xbc, 0xbf, 0x74, 0x58, 0x38, 0xd8, 0x48, 0x98, 0xf4, 0x0d, 0x47, + 0x0c, 0x2c, 0x37, 0x40, 0x08, 0x2e, 0x86, 0x61, 0xb1, 0x86, 0xc6, 0x1b, + 0xac, 0x78, 0x81, 0x9c, 0xe5, 0xfe, 0xc0, 0x8f, 0xb3, 0x2e, 0x4c, 0x1b, + 0x24, 0x4c, 0x6a, 0x61, 0x13, 0x83, 0x78, 0x08, 0x1e, 0x92, 0xfd, 0xe6, + 0x89, 0x04, 0x35, 0xd7, 0xfa, 0x16, 0x5b, 0x78, 0xff, 0x00, 0x24, 0xea, + 0x40, 0xe5, 0x53, 0x4f, 0x81, 0x96, 0xb3, 0x46, 0xd0, 0xfe, 0x07, 0xe0, + 0xa1, 0xf0, 0xc1, 0x86, 0xb5, 0x43, 0xa7, 0x7a, 0xfa, 0x0c, 0xf7, 0x15, + 0x09, 0x92, 0x26, 0x26, 0x50, 0x77, 0x65, 0xa3, 0xe2, 0x98, 0xf5, 0x1e, + 0x3e, 0x9b, 0x0f, 0x25, 0xec, 0x56, 0x71, 0x81, 0x5b, 0x0c, 0xe9, 0x1d, + 0x17, 0xd1, 0x48, 0xd4, 0x0c, 0xd5, 0xb5, 0x2b, 0xeb, 0x59, 0xa6, 0x5d, + 0x86, 0x32, 0xd6, 0xc2, 0x49, 0xb2, 0x4e, 0x17, 0x34, 0x4d, 0x97, 0xa9, + 0x3e, 0xe3, 0x20, 0x4d, 0x8c, 0x31, 0xc0, 0x2d, 0x16, 0x72, 0xb0, 0xd4, + 0x88, 0x22, 0xd4, 0xa9, 0x28, 0xfb, 0x95, 0x2e, 0xc1, 0xb8, 0x43, 0x72, + 0x48, 0x52, 0x38, 0x22, 0xe3, 0x56, 0xfd, 0xc6, 0x66, 0x3c, 0x86, 0x90, + 0x89, 0xa7, 0x91, 0xc9, 0x57, 0x66, 0xc7, 0x21, 0x1a, 0x0c, 0xb8, 0x56, + 0x09, 0x25, 0x6e, 0x47, 0x9f, 0xa6, 0x6c, 0x0b, 0x79, 0x86, 0xa0, 0x92, + 0x49, 0x1b, 0x1b, 0x1b, 0x1a, 0xbe, 0x7e, 0xe8, 0x4c, 0x38, 0xdf, 0x43, + 0x50, 0x34, 0xe0, 0x8d, 0x84, 0xb0, 0x08, 0xae, 0x9f, 0x36, 0x36, 0x36, + 0x30, 0xd8, 0xdd, 0x61, 0xdc, 0x4c, 0x30, 0xac, 0x2a, 0xc4, 0x72, 0x17, + 0xee, 0x2b, 0x5e, 0x49, 0xc1, 0x32, 0xce, 0x80, 0xf4, 0x03, 0xfd, 0xe1, + 0x6d, 0xfc, 0x10, 0x29, 0x77, 0x1b, 0x63, 0x62, 0xfb, 0x29, 0x5a, 0x5a, + 0x15, 0x93, 0x84, 0xcf, 0xba, 0xa7, 0xa9, 0x5b, 0x0a, 0x2e, 0x44, 0xa8, + 0x68, 0xaa, 0x66, 0xf4, 0x65, 0x39, 0xe8, 0x20, 0x93, 0x24, 0x4c, 0x91, + 0x1f, 0x49, 0xb6, 0x13, 0x62, 0x87, 0xa8, 0xdf, 0x7e, 0x98, 0x16, 0x07, + 0xab, 0x28, 0x8a, 0xf8, 0x4b, 0x4a, 0x2f, 0x66, 0x53, 0x16, 0xe1, 0x9c, + 0xc1, 0xb3, 0xb4, 0x92, 0x7c, 0xca, 0x1e, 0x0f, 0xd2, 0x7c, 0x93, 0x57, + 0x23, 0x0f, 0xca, 0xcd, 0x8d, 0x92, 0xc9, 0xcf, 0xa8, 0xb4, 0x2a, 0x7a, + 0x63, 0x55, 0x76, 0xa5, 0x7d, 0xd8, 0xd1, 0x77, 0x39, 0x92, 0xb5, 0x29, + 0xfa, 0x15, 0x2e, 0xc1, 0x90, 0x24, 0x0a, 0xe3, 0x8f, 0x77, 0xef, 0x84, + 0xd4, 0xb0, 0x91, 0xa4, 0xb5, 0x39, 0x06, 0x10, 0xe0, 0x2b, 0x3a, 0x16, + 0x42, 0x56, 0x3b, 0x88, 0x30, 0x65, 0x66, 0xee, 0x6c, 0x42, 0x82, 0xaf, + 0xa6, 0x6c, 0x6f, 0x69, 0xeb, 0xc6, 0xa2, 0x24, 0x9c, 0x1b, 0x24, 0x6c, + 0x83, 0xb9, 0xf0, 0x20, 0xc3, 0xe8, 0x6a, 0x0a, 0xba, 0x20, 0x82, 0x08, + 0x26, 0x26, 0x4e, 0x09, 0x18, 0x61, 0xb1, 0xb1, 0x86, 0xc6, 0x1e, 0x07, + 0xc5, 0x43, 0x73, 0xad, 0xfa, 0x33, 0xec, 0x59, 0x89, 0x71, 0x48, 0xec, + 0x31, 0xa4, 0x91, 0xa9, 0xe0, 0x78, 0x39, 0xcd, 0xe1, 0x7f, 0xa4, 0x8d, + 0xd2, 0xcf, 0x11, 0x71, 0x68, 0x44, 0x00, 0x57, 0xf7, 0x31, 0xad, 0xd0, + 0x91, 0xe1, 0x10, 0x28, 0x82, 0x5c, 0x8e, 0x2c, 0xdc, 0xd8, 0x99, 0x41, + 0xab, 0x21, 0x28, 0x9d, 0x26, 0xc2, 0x47, 0x64, 0x4d, 0x2f, 0x81, 0x32, + 0x49, 0x1b, 0xe8, 0xdb, 0x01, 0xbe, 0x86, 0xa8, 0xff, 0x00, 0x4e, 0x98, + 0x4d, 0x61, 0xca, 0x0c, 0x0a, 0xe3, 0xe4, 0x35, 0x1c, 0x4f, 0x32, 0xb4, + 0xd1, 0x54, 0xfb, 0x2a, 0x49, 0x7e, 0x09, 0xc3, 0x30, 0x77, 0x72, 0x31, + 0x54, 0x6f, 0x8b, 0x95, 0x1f, 0x18, 0x14, 0x38, 0x1e, 0x01, 0xd4, 0x23, + 0x4d, 0xfb, 0x8f, 0x5c, 0xb5, 0x12, 0x27, 0xc9, 0x4f, 0x28, 0xbb, 0x15, + 0x8d, 0x70, 0x8a, 0x46, 0xc3, 0x64, 0x95, 0x06, 0xd0, 0x1c, 0x32, 0xc3, + 0x3b, 0x94, 0x9e, 0x42, 0x24, 0x3a, 0x56, 0x4b, 0x3a, 0x73, 0x9b, 0x21, + 0xf3, 0x7a, 0x00, 0x79, 0x6f, 0xab, 0x8d, 0x53, 0xea, 0xc4, 0xe8, 0x49, + 0x23, 0x63, 0x63, 0x64, 0x91, 0x73, 0xc4, 0x18, 0x7d, 0x0e, 0x1a, 0x56, + 0x20, 0xc2, 0x09, 0x89, 0x89, 0x8b, 0xa6, 0x18, 0xc6, 0x3c, 0x47, 0xd4, + 0x14, 0x2b, 0x32, 0x05, 0xef, 0xb5, 0xf5, 0x13, 0x32, 0x49, 0x24, 0x76, + 0x1c, 0x92, 0x48, 0xf1, 0x34, 0xd0, 0xba, 0x31, 0x49, 0x3c, 0xff, 0x00, + 0x82, 0xf1, 0x34, 0xdc, 0x8d, 0x59, 0x8a, 0x37, 0x3f, 0x90, 0x82, 0x53, + 0x42, 0x1a, 0xee, 0x95, 0xaa, 0xe9, 0x90, 0xa1, 0xa0, 0xa0, 0x97, 0xba, + 0xb3, 0xd5, 0x0a, 0x34, 0xba, 0x1e, 0x09, 0x45, 0x4a, 0x09, 0x13, 0x16, + 0x0d, 0xc0, 0xff, 0x00, 0x46, 0xc5, 0x83, 0x78, 0xa1, 0xab, 0x87, 0xdc, + 0x30, 0x6b, 0xf2, 0x3d, 0x11, 0x40, 0xa6, 0xf0, 0xd0, 0x70, 0x40, 0xf0, + 0x33, 0x52, 0xd6, 0x83, 0xd7, 0x72, 0x02, 0xde, 0x0f, 0x90, 0x2a, 0x0d, + 0x09, 0xa5, 0x7a, 0x95, 0x57, 0x46, 0xa1, 0x53, 0x94, 0xd7, 0xed, 0x93, + 0x0c, 0xa0, 0x2f, 0x43, 0xa8, 0x6c, 0xca, 0x13, 0x1f, 0x5f, 0x72, 0x26, + 0x3b, 0x39, 0x33, 0x4c, 0xca, 0x00, 0xef, 0x82, 0x42, 0x58, 0xe5, 0x28, + 0xe2, 0x12, 0x6a, 0x4c, 0xe0, 0xa7, 0xcd, 0x04, 0xfb, 0x8d, 0x25, 0x66, + 0xc8, 0x0a, 0x62, 0x49, 0x90, 0x17, 0x70, 0x78, 0xb6, 0x1e, 0xb7, 0x77, + 0xc9, 0x77, 0xea, 0xe3, 0xd4, 0xfa, 0xd1, 0x3a, 0x12, 0x48, 0xd8, 0xc7, + 0x84, 0x1c, 0xcf, 0x61, 0x3a, 0x47, 0x1b, 0x24, 0x9c, 0x1c, 0x5f, 0x18, + 0x30, 0x98, 0x84, 0x27, 0xd3, 0x23, 0x0c, 0x36, 0x36, 0x3c, 0x0f, 0x03, + 0xc0, 0xa2, 0xe0, 0x36, 0xc6, 0x44, 0x32, 0x30, 0x91, 0xba, 0x0d, 0xe4, + 0x24, 0x9c, 0x2f, 0x01, 0x7f, 0x62, 0xfc, 0x74, 0xa2, 0x50, 0x85, 0xa6, + 0xfb, 0x6c, 0x51, 0xeb, 0x14, 0x84, 0x96, 0x65, 0xb0, 0x35, 0x12, 0xcb, + 0xa0, 0x76, 0x12, 0xe2, 0xd9, 0x31, 0xec, 0x2c, 0x32, 0xb5, 0x2c, 0x3f, + 0xa0, 0x26, 0x89, 0xa8, 0x9e, 0x26, 0xcb, 0xfb, 0x86, 0xe8, 0x45, 0xe5, + 0xd1, 0x7b, 0x1a, 0xc3, 0xd4, 0x35, 0x07, 0xa2, 0x1a, 0xa5, 0x83, 0xd5, + 0xb0, 0x4e, 0x09, 0x92, 0xff, 0x00, 0x00, 0x71, 0xee, 0xe8, 0x17, 0xb0, + 0xd4, 0x74, 0xcb, 0x4b, 0xc0, 0xc2, 0x9e, 0xea, 0x10, 0xc3, 0x7a, 0xdd, + 0x19, 0xbf, 0xee, 0x16, 0x44, 0xa6, 0x7e, 0xea, 0x78, 0xf7, 0x91, 0xdb, + 0x31, 0x18, 0x4e, 0x07, 0x13, 0x55, 0x4f, 0x82, 0xf2, 0x1a, 0x8c, 0x0c, + 0x30, 0xf3, 0x86, 0x69, 0x6c, 0x4d, 0xad, 0x56, 0xb8, 0xea, 0x9e, 0x51, + 0xe0, 0x48, 0x8c, 0x1e, 0x0a, 0x51, 0xb3, 0x09, 0x3d, 0x71, 0x23, 0x49, + 0x64, 0x77, 0x8a, 0xb1, 0xf9, 0xba, 0x95, 0xa4, 0xbc, 0x28, 0x54, 0x24, + 0xa5, 0x95, 0x82, 0xe4, 0x29, 0xe6, 0x4c, 0xfc, 0x95, 0x9e, 0x6b, 0xe4, + 0x84, 0xc3, 0x73, 0x42, 0xdc, 0x52, 0x3c, 0x1e, 0x0f, 0x1d, 0xff, 0x00, + 0x70, 0x9d, 0x05, 0x4c, 0x81, 0x88, 0xc2, 0xe1, 0xa7, 0x8b, 0x03, 0x08, + 0x4c, 0x41, 0x61, 0x2c, 0x5c, 0x8f, 0x16, 0x31, 0xe2, 0x31, 0x8f, 0x02, + 0x08, 0x50, 0xfc, 0x0d, 0x18, 0xcb, 0xc1, 0x63, 0xa5, 0x93, 0xbd, 0x67, + 0x71, 0xab, 0xfd, 0x0b, 0xfc, 0x81, 0x2c, 0x5f, 0x0e, 0x13, 0x03, 0xe3, + 0x7a, 0x34, 0x9f, 0xc9, 0x25, 0x25, 0xb5, 0x38, 0x98, 0xcb, 0x67, 0x57, + 0xc9, 0x34, 0xb9, 0x20, 0xa5, 0x85, 0x84, 0xb6, 0x63, 0x9e, 0xc1, 0x21, + 0xc1, 0x94, 0x61, 0x33, 0x2c, 0x24, 0x5a, 0xfe, 0xc1, 0xa5, 0xcb, 0x6d, + 0x8c, 0xa2, 0x44, 0xc4, 0xc4, 0x48, 0xee, 0x2f, 0xa9, 0x86, 0x71, 0x45, + 0xc7, 0xbb, 0xf8, 0x33, 0x8f, 0xd2, 0x8e, 0x43, 0xab, 0x19, 0x21, 0x21, + 0x22, 0x7a, 0xb2, 0x0d, 0x75, 0x7c, 0x33, 0x12, 0x26, 0xcd, 0xd5, 0x29, + 0xa5, 0x1b, 0xff, 0x00, 0x82, 0x60, 0x50, 0x40, 0x87, 0x6e, 0xc5, 0x1b, + 0xd9, 0x1a, 0xde, 0xdd, 0xfe, 0x11, 0x31, 0x14, 0x7c, 0x01, 0x05, 0xfd, + 0x41, 0xb4, 0x92, 0xbb, 0xa9, 0x6c, 0x56, 0x7b, 0x89, 0x8c, 0x71, 0x87, + 0x6d, 0xb8, 0xc9, 0x38, 0x1d, 0xc2, 0xab, 0xc1, 0x52, 0xd6, 0x3d, 0x85, + 0xcd, 0x86, 0x24, 0x10, 0x91, 0x61, 0x04, 0x8c, 0x8a, 0x56, 0xd8, 0x35, + 0xc4, 0xe6, 0x64, 0x0f, 0x73, 0x1a, 0x6a, 0xbc, 0xd4, 0x92, 0x8f, 0x51, + 0xc0, 0x81, 0x8e, 0xbd, 0x88, 0x30, 0x8b, 0xd4, 0x54, 0x85, 0x7d, 0xc6, + 0x09, 0x92, 0x5f, 0x34, 0x75, 0xba, 0xcb, 0x2f, 0xd3, 0xa5, 0x31, 0xee, + 0x46, 0x7b, 0xba, 0xea, 0x67, 0xa1, 0x42, 0x27, 0x59, 0x2b, 0x5e, 0xcc, + 0x9a, 0x46, 0xc9, 0x24, 0x61, 0xe0, 0x1a, 0x70, 0x08, 0x42, 0x62, 0x10, + 0x85, 0x8c, 0x92, 0x48, 0xd8, 0xd8, 0xc6, 0x31, 0x8c, 0x68, 0x62, 0x08, + 0x21, 0x70, 0x92, 0x49, 0xc1, 0x32, 0x1c, 0x9e, 0x61, 0x23, 0xbb, 0x41, + 0x44, 0x25, 0x2d, 0xd1, 0x0d, 0x0f, 0xd8, 0x59, 0xb5, 0x2f, 0x70, 0x03, + 0xd3, 0xd8, 0x68, 0xfd, 0x83, 0x44, 0x77, 0x8e, 0xcd, 0x05, 0x92, 0x20, + 0x41, 0x64, 0x78, 0x6b, 0xe0, 0x7a, 0x35, 0x2f, 0x41, 0x46, 0x24, 0x45, + 0xf0, 0x12, 0x8e, 0x43, 0x89, 0xcf, 0x33, 0x88, 0x12, 0x64, 0x85, 0x3a, + 0x0a, 0x74, 0x67, 0x06, 0x5a, 0xc5, 0x7f, 0xc1, 0x26, 0x64, 0x46, 0x32, + 0x3d, 0x4f, 0x76, 0x52, 0x24, 0xc0, 0x91, 0xd0, 0xca, 0xc4, 0x13, 0x50, + 0x6a, 0x0a, 0x9b, 0x02, 0x2d, 0x4b, 0x7a, 0xa4, 0xc1, 0x07, 0x18, 0x55, + 0x31, 0x9d, 0x27, 0x58, 0x9b, 0x15, 0x59, 0x07, 0x2e, 0xea, 0xc4, 0x38, + 0x65, 0xfe, 0x03, 0x28, 0x4f, 0xa0, 0x9b, 0x52, 0x6f, 0x34, 0x36, 0x2b, + 0x45, 0x70, 0x89, 0x4e, 0xf5, 0xdc, 0x46, 0xc9, 0x60, 0xb0, 0x4e, 0x93, + 0x2c, 0x03, 0xcb, 0x19, 0x49, 0xd8, 0x4a, 0xf7, 0x48, 0x92, 0xb0, 0x9c, + 0x9f, 0x4b, 0x25, 0x86, 0x63, 0x45, 0x7c, 0x12, 0xf9, 0x55, 0x22, 0x5a, + 0xad, 0xa2, 0xd0, 0x47, 0x2d, 0xaf, 0x23, 0x85, 0x58, 0x85, 0x36, 0x22, + 0xd2, 0xee, 0x3d, 0x32, 0x91, 0x0c, 0xda, 0x50, 0xba, 0xcf, 0x48, 0xb1, + 0xa5, 0x47, 0x22, 0x58, 0xaa, 0xa3, 0x22, 0x36, 0xaa, 0x26, 0x6f, 0x1a, + 0xf2, 0xdf, 0x54, 0x81, 0x85, 0x6e, 0x82, 0xf3, 0xad, 0x7c, 0xfc, 0x3f, + 0xd2, 0x0c, 0x7b, 0x73, 0x0e, 0xdc, 0xc0, 0xe6, 0xb3, 0x2d, 0x47, 0xa7, + 0xc0, 0x55, 0xd8, 0x5c, 0xc9, 0x2a, 0xb2, 0x22, 0x57, 0x05, 0x23, 0xa1, + 0x7c, 0x2b, 0x16, 0x26, 0x21, 0x31, 0x31, 0x12, 0x49, 0x24, 0x92, 0x7f, + 0x58, 0x52, 0xc1, 0x8c, 0x68, 0x68, 0x61, 0xa1, 0xa1, 0xa1, 0x30, 0x27, + 0x4c, 0x65, 0x82, 0x20, 0x9b, 0x6e, 0x86, 0xd8, 0x83, 0x7b, 0x0f, 0x61, + 0xd6, 0xa4, 0x93, 0xac, 0x3b, 0x0d, 0xb5, 0x87, 0xac, 0xcb, 0x81, 0x98, + 0x51, 0xbb, 0xb0, 0xa8, 0x90, 0x59, 0x65, 0x31, 0xa5, 0x8a, 0xb9, 0x3a, + 0xab, 0x81, 0x79, 0x5a, 0x89, 0xa9, 0xf4, 0x08, 0x29, 0xca, 0xa8, 0x3d, + 0xae, 0xbe, 0xd1, 0x49, 0x4a, 0xaa, 0xc1, 0x16, 0x57, 0x33, 0x38, 0x43, + 0x3c, 0x1a, 0x1b, 0x11, 0x82, 0x48, 0x25, 0xde, 0x8b, 0xea, 0x1c, 0x50, + 0x58, 0xe8, 0xa6, 0xb2, 0xcc, 0x41, 0x54, 0xf6, 0x59, 0x39, 0x24, 0x8c, + 0xe9, 0x91, 0x60, 0x63, 0x52, 0x34, 0xd0, 0xda, 0x36, 0x04, 0xba, 0x09, + 0x74, 0x22, 0xd5, 0x8b, 0x4f, 0xd2, 0xe0, 0x75, 0x49, 0xb0, 0x1b, 0xb0, + 0xc5, 0x2b, 0x62, 0x69, 0x69, 0x07, 0x54, 0x64, 0x53, 0x52, 0xc9, 0xf2, + 0x7a, 0x28, 0xc5, 0xd2, 0xc5, 0x4f, 0x88, 0x74, 0x28, 0xab, 0xb0, 0xf9, + 0x16, 0x09, 0x19, 0xf4, 0x35, 0xb0, 0xa0, 0xe5, 0x6f, 0x90, 0xd7, 0x10, + 0x97, 0xc9, 0x28, 0x55, 0x50, 0xd8, 0x89, 0x6c, 0x51, 0x97, 0xd0, 0x3a, + 0x50, 0x5f, 0xe2, 0xa4, 0xb9, 0x82, 0x17, 0xc5, 0x88, 0x0a, 0x8a, 0x05, + 0xec, 0x10, 0x5b, 0x54, 0xd9, 0x64, 0x04, 0x2d, 0x6f, 0x69, 0x34, 0xf8, + 0x2b, 0xb4, 0xd4, 0xeb, 0x3f, 0x07, 0xbe, 0x0c, 0x0e, 0x39, 0x99, 0x09, + 0xb3, 0xce, 0x8a, 0xd1, 0x86, 0xe4, 0x93, 0x85, 0x48, 0x52, 0x42, 0x10, + 0x84, 0x22, 0x71, 0x22, 0xb3, 0x22, 0xc8, 0x3c, 0x09, 0xbe, 0xdb, 0x3a, + 0xea, 0x2c, 0x23, 0x7a, 0x60, 0x81, 0xa1, 0xa1, 0xa1, 0x8c, 0x6b, 0x02, + 0x89, 0x80, 0x78, 0xbc, 0x28, 0x5b, 0x6c, 0xa2, 0x0a, 0x22, 0x5b, 0xa9, + 0x54, 0x74, 0xd9, 0x4a, 0xc0, 0x48, 0xf2, 0x63, 0x7c, 0x93, 0x2e, 0x8a, + 0x39, 0x2d, 0x9a, 0x91, 0x35, 0xd4, 0x91, 0xea, 0x39, 0x4f, 0x6b, 0xc8, + 0x62, 0x45, 0x14, 0xde, 0xea, 0x1d, 0xc3, 0x22, 0x60, 0x85, 0xa0, 0x52, + 0xe1, 0x72, 0xb2, 0x62, 0x4a, 0xcb, 0xe8, 0x5e, 0x41, 0xb2, 0x59, 0x08, + 0x4c, 0xab, 0x44, 0x78, 0x4e, 0x37, 0x93, 0xf3, 0x88, 0xc7, 0x52, 0x2a, + 0x60, 0x1e, 0xc8, 0x6a, 0xbd, 0x04, 0x50, 0x92, 0x45, 0x2f, 0x76, 0xc8, + 0xd2, 0x3e, 0x04, 0x26, 0x95, 0xb0, 0xb1, 0x3d, 0x49, 0x93, 0x85, 0xb4, + 0xc8, 0x55, 0xc9, 0xf7, 0x41, 0x90, 0xaf, 0x64, 0x93, 0xa8, 0xea, 0x1f, + 0x04, 0x1d, 0x65, 0x65, 0x61, 0x4e, 0xb7, 0x26, 0x65, 0x82, 0xb6, 0xec, + 0xe9, 0x92, 0x47, 0x63, 0xb8, 0x68, 0x50, 0xb2, 0x86, 0xcc, 0xe8, 0x8d, + 0x20, 0xa5, 0xae, 0x44, 0xa4, 0xa5, 0x99, 0x4a, 0xc6, 0x41, 0x85, 0x03, + 0xad, 0x46, 0xfb, 0x50, 0xb4, 0xb6, 0x24, 0xae, 0x4d, 0x36, 0x6d, 0x03, + 0x5a, 0x5c, 0xb6, 0x22, 0xd4, 0x5b, 0xec, 0x13, 0x20, 0xbb, 0x2c, 0x93, + 0x2c, 0x36, 0x20, 0x8d, 0x5a, 0xc5, 0x60, 0xba, 0x8b, 0xd6, 0x3b, 0xa3, + 0x5a, 0x8d, 0x55, 0xa2, 0x81, 0xed, 0xa9, 0x58, 0xcb, 0x83, 0xe8, 0x38, + 0x8c, 0x22, 0x42, 0x08, 0x24, 0x20, 0x82, 0x1c, 0xe4, 0x91, 0xb8, 0xdb, + 0x61, 0xe4, 0xa8, 0x3d, 0x76, 0x7c, 0x89, 0x5e, 0x64, 0x22, 0x82, 0x58, + 0x22, 0x4b, 0x61, 0xbd, 0x8d, 0xe1, 0x26, 0xae, 0x16, 0x99, 0xad, 0x2a, + 0x17, 0xa1, 0xb8, 0xb5, 0xa2, 0x7a, 0x3a, 0x13, 0x23, 0x18, 0xd0, 0xd0, + 0xfa, 0x05, 0xde, 0x2f, 0x0a, 0xe6, 0xf3, 0x75, 0xb9, 0x0a, 0x5a, 0xe4, + 0x83, 0xce, 0x3c, 0xc8, 0x44, 0xc2, 0x85, 0x25, 0x10, 0x42, 0x22, 0xc9, + 0x0d, 0x7e, 0xe1, 0xf4, 0xf2, 0xa9, 0x12, 0x2a, 0xae, 0x4a, 0xf1, 0x16, + 0x0c, 0xb2, 0xc5, 0x4d, 0x0b, 0xca, 0x78, 0x12, 0x25, 0x96, 0xac, 0x2c, + 0x1b, 0x99, 0x8b, 0x29, 0xcb, 0x02, 0x39, 0x42, 0x39, 0x9f, 0x6a, 0x91, + 0xc1, 0xc3, 0x78, 0x10, 0xe1, 0x2a, 0x8b, 0xd0, 0x78, 0xce, 0x17, 0x88, + 0x25, 0xde, 0x42, 0x46, 0x8e, 0x2a, 0x38, 0x6c, 0x85, 0xd4, 0x54, 0xbc, + 0x00, 0x76, 0x97, 0x31, 0x44, 0xf6, 0x80, 0x4e, 0xf9, 0x36, 0x6d, 0x16, + 0xb5, 0xc7, 0xa6, 0x5c, 0x82, 0xcd, 0xb7, 0xbe, 0xc4, 0x78, 0x5e, 0x6e, + 0x1f, 0x82, 0x00, 0x8f, 0x9b, 0xbc, 0x4e, 0x24, 0xb6, 0x9d, 0xe5, 0x93, + 0x2a, 0x26, 0xb1, 0xd4, 0x77, 0x8d, 0x63, 0x75, 0x4f, 0xf4, 0xe0, 0x97, + 0x6b, 0x70, 0x9e, 0xee, 0x5d, 0x85, 0x6c, 0xbe, 0xde, 0x7a, 0x63, 0x17, + 0xc2, 0xb7, 0xed, 0x41, 0xcd, 0x57, 0xd1, 0x58, 0xcc, 0xdb, 0x4c, 0x86, + 0x90, 0x34, 0x13, 0x31, 0x04, 0xb2, 0x42, 0x48, 0x92, 0x9c, 0xe8, 0xd4, + 0x97, 0x7c, 0xba, 0xfe, 0xca, 0xb6, 0xa5, 0xd2, 0x1d, 0x85, 0x35, 0x62, + 0x23, 0x1d, 0x21, 0x4d, 0x73, 0x2e, 0xfa, 0x4d, 0x69, 0x72, 0x22, 0xfd, + 0x46, 0x9b, 0xd8, 0x6c, 0x80, 0xca, 0x5a, 0x50, 0x89, 0xf1, 0x01, 0x75, + 0x63, 0xb9, 0x42, 0x95, 0x56, 0xa4, 0x3d, 0x69, 0x74, 0xa8, 0xcd, 0xad, + 0xab, 0x89, 0x64, 0x24, 0x59, 0x19, 0x07, 0xd4, 0x94, 0x09, 0x09, 0x09, + 0x09, 0x09, 0x09, 0x11, 0x93, 0xab, 0x57, 0x81, 0xa1, 0x61, 0x51, 0x10, + 0x3c, 0x92, 0xe7, 0x60, 0x60, 0x9b, 0xe5, 0x45, 0x29, 0xc6, 0x05, 0xdb, + 0x17, 0x57, 0x83, 0x2f, 0xad, 0x73, 0x47, 0xf8, 0xec, 0xbb, 0x77, 0x10, + 0xac, 0x7b, 0xce, 0x0c, 0xba, 0x3e, 0x18, 0xf1, 0x49, 0xe2, 0xcb, 0x04, + 0xd6, 0x11, 0xa0, 0xc7, 0x96, 0x36, 0xe4, 0x0a, 0x98, 0xee, 0x26, 0x53, + 0x17, 0x0d, 0x40, 0xc8, 0x92, 0xdb, 0x45, 0x88, 0x09, 0x0b, 0xa5, 0x33, + 0x2e, 0xfb, 0x21, 0x1b, 0xaf, 0x24, 0x16, 0x73, 0x3b, 0x0b, 0x31, 0x85, + 0x16, 0x89, 0x58, 0x7d, 0x37, 0x8a, 0x44, 0xec, 0x52, 0xab, 0xf9, 0x9c, + 0x10, 0x52, 0xf6, 0x6c, 0x7b, 0x2e, 0x29, 0x73, 0x90, 0xbd, 0xcf, 0x0d, + 0xa2, 0xd2, 0x9d, 0x83, 0x5e, 0xe5, 0x47, 0x4a, 0x89, 0xd0, 0x48, 0x43, + 0xcc, 0x86, 0xea, 0xee, 0x69, 0xc1, 0x83, 0x23, 0xca, 0x8a, 0x2a, 0x40, + 0x8a, 0x0d, 0xce, 0x87, 0xd0, 0x8d, 0x4b, 0x9a, 0xcc, 0xa2, 0x4c, 0x59, + 0x8b, 0x48, 0xf4, 0x35, 0x72, 0x2d, 0x74, 0xfb, 0x1c, 0x02, 0xea, 0x9d, + 0x98, 0xd4, 0x47, 0x97, 0xe6, 0x1b, 0x73, 0x48, 0x71, 0x78, 0xdd, 0x62, + 0x5e, 0x44, 0x16, 0x1b, 0x7a, 0xcb, 0xc0, 0x4e, 0xa2, 0x19, 0x07, 0x3c, + 0x27, 0x2f, 0x61, 0x86, 0x11, 0x56, 0xb7, 0x17, 0x5d, 0xb0, 0x2b, 0xa6, + 0x85, 0x7c, 0x9e, 0x46, 0xc9, 0x72, 0x31, 0xf2, 0x06, 0xec, 0xc7, 0x27, + 0x51, 0xce, 0xc4, 0xbb, 0x91, 0xa7, 0xb8, 0x51, 0x3d, 0x07, 0x77, 0x98, + 0xe7, 0x6c, 0x1c, 0x73, 0x1a, 0x72, 0xd0, 0xe9, 0x5a, 0xa2, 0xe2, 0x4a, + 0x28, 0x42, 0xaa, 0xd1, 0x34, 0x8a, 0xd7, 0x1f, 0xd9, 0x2a, 0x5c, 0x5c, + 0x32, 0x95, 0x0e, 0x1d, 0x06, 0x35, 0xca, 0xa0, 0x1e, 0x81, 0x23, 0x23, + 0x8c, 0xd2, 0xa9, 0x5d, 0x9b, 0xee, 0x43, 0x94, 0x91, 0x5d, 0x8f, 0x00, + 0x65, 0xd4, 0x85, 0xa0, 0x41, 0x04, 0x8b, 0x42, 0x6f, 0x83, 0x23, 0xee, + 0x3d, 0x32, 0x08, 0x93, 0xaa, 0x09, 0xf0, 0xd0, 0xe8, 0x2d, 0xa5, 0x2b, + 0x3c, 0x4a, 0x08, 0xb3, 0x13, 0x98, 0x49, 0x6b, 0xc0, 0xc5, 0x1a, 0x1a, + 0x10, 0x63, 0x1b, 0x32, 0xca, 0xef, 0x80, 0xcf, 0x69, 0x69, 0x7a, 0xb1, + 0xbc, 0x12, 0x36, 0x35, 0x09, 0x10, 0x26, 0x09, 0x9e, 0x06, 0x95, 0x2f, + 0x74, 0x74, 0x1a, 0x85, 0x58, 0xe5, 0x60, 0xa5, 0x8b, 0xeb, 0x40, 0x94, + 0x90, 0xcc, 0xe8, 0x26, 0x20, 0x9f, 0x5c, 0x92, 0x34, 0xbb, 0x1e, 0x33, + 0x89, 0x89, 0x08, 0x2a, 0x4e, 0x3b, 0x70, 0xdf, 0x22, 0xd1, 0x64, 0xe6, + 0x96, 0xda, 0x9a, 0x49, 0xf2, 0x9b, 0x4c, 0x4a, 0xc3, 0x80, 0x99, 0xa2, + 0x7c, 0xac, 0x39, 0xaa, 0x31, 0x9a, 0x93, 0x66, 0x3c, 0x66, 0x82, 0x71, + 0x0d, 0x4e, 0x67, 0x23, 0x97, 0x4e, 0x49, 0x59, 0xc0, 0xd9, 0xe6, 0x31, + 0xba, 0x53, 0x35, 0x06, 0xb4, 0x15, 0x15, 0x21, 0x2c, 0x51, 0x68, 0xd2, + 0xcb, 0x5a, 0x23, 0xf0, 0x57, 0xc3, 0x81, 0xa3, 0xc8, 0x6e, 0xfd, 0xc1, + 0xe6, 0x02, 0x15, 0xf0, 0xa1, 0xa2, 0xd2, 0x34, 0x77, 0xce, 0x0c, 0x1f, + 0x59, 0x21, 0x55, 0xb8, 0x35, 0x0d, 0x7a, 0xc7, 0xcd, 0x2e, 0xff, 0x00, + 0x93, 0xf7, 0x3a, 0x12, 0x5b, 0x2b, 0x56, 0x92, 0x1e, 0x65, 0x17, 0x8c, + 0x87, 0xef, 0x23, 0xec, 0xee, 0xe4, 0xb3, 0x1f, 0x4f, 0x24, 0xea, 0x84, + 0x8f, 0x1c, 0xab, 0xe2, 0x3b, 0xf9, 0x46, 0xbf, 0xd9, 0x11, 0x5f, 0x72, + 0x32, 0x2e, 0xb1, 0x35, 0x48, 0x4a, 0x52, 0x14, 0x6c, 0xba, 0x60, 0x48, + 0x74, 0xaa, 0x10, 0xe0, 0x5e, 0x7e, 0x22, 0x24, 0xeb, 0xc9, 0x99, 0x64, + 0x50, 0xb6, 0x14, 0x89, 0x62, 0xe1, 0x4b, 0xe8, 0xb4, 0x38, 0xe4, 0xc6, + 0x6e, 0x16, 0x1a, 0xcd, 0x9b, 0xa6, 0xe8, 0x94, 0xb9, 0x9c, 0x90, 0x62, + 0x0d, 0x0f, 0x0d, 0xc6, 0x86, 0x21, 0x4e, 0x78, 0x17, 0x24, 0x76, 0x12, + 0xaf, 0x43, 0x60, 0x41, 0xe6, 0x49, 0xb8, 0xfe, 0x60, 0x62, 0xc2, 0x46, + 0xe1, 0xad, 0x28, 0x7e, 0xd8, 0x3b, 0x9d, 0x6e, 0x65, 0x07, 0x8e, 0x88, + 0xc2, 0x49, 0x24, 0x92, 0x70, 0x68, 0x4f, 0xae, 0xc3, 0xd3, 0xd0, 0x36, + 0x3e, 0x13, 0x49, 0xc7, 0x92, 0xe2, 0x60, 0xdc, 0x41, 0x25, 0xc7, 0x04, + 0xd4, 0x93, 0xdc, 0x85, 0x8f, 0x48, 0x83, 0xd7, 0x18, 0x5e, 0xbc, 0x03, + 0x94, 0x49, 0x3c, 0x8f, 0xd4, 0xde, 0x37, 0x30, 0x52, 0x09, 0x71, 0x28, + 0x6a, 0x47, 0x51, 0xe1, 0x29, 0x0c, 0x59, 0x97, 0x71, 0xd8, 0x77, 0x91, + 0x2f, 0xc2, 0xa5, 0x90, 0x98, 0x7a, 0xc1, 0xbb, 0xcf, 0x04, 0x93, 0x84, + 0x8e, 0x22, 0x93, 0x76, 0xa2, 0x71, 0xa2, 0xcf, 0x5c, 0x29, 0x30, 0x15, + 0x5c, 0x58, 0x37, 0xa5, 0x71, 0xe8, 0xb8, 0x42, 0x4b, 0x8d, 0x59, 0x24, + 0x9b, 0x37, 0x44, 0x75, 0x0d, 0x07, 0x03, 0x34, 0x3e, 0x31, 0x58, 0xd9, + 0xee, 0x84, 0xe3, 0x3e, 0xe8, 0xcb, 0xa6, 0x04, 0x8a, 0x5c, 0x26, 0x5e, + 0xe4, 0x8e, 0x44, 0x82, 0x52, 0x04, 0x09, 0x35, 0x23, 0x6b, 0x38, 0x65, + 0x7c, 0x8d, 0x74, 0x12, 0x95, 0x4e, 0x28, 0x5a, 0xd6, 0x4e, 0x1d, 0xea, + 0x22, 0xcb, 0xbd, 0x85, 0xe9, 0x6b, 0x5a, 0x86, 0xa7, 0x13, 0x55, 0x91, + 0x36, 0x62, 0x58, 0x81, 0x29, 0xe0, 0x35, 0x1d, 0x4b, 0x97, 0x21, 0xa6, + 0x83, 0x4d, 0x05, 0x56, 0x44, 0x93, 0x06, 0xea, 0x0a, 0xd5, 0x7a, 0xa1, + 0x73, 0x41, 0xc2, 0xe7, 0x71, 0xaf, 0x57, 0x04, 0x37, 0x51, 0xd0, 0x51, + 0xd0, 0xc5, 0x67, 0x59, 0x32, 0x97, 0x0b, 0x09, 0x88, 0x8a, 0x18, 0xdd, + 0x84, 0x54, 0x85, 0xcd, 0xbb, 0x1d, 0x88, 0x31, 0xab, 0xc8, 0xbc, 0xa3, + 0x2e, 0xeb, 0xb0, 0xe4, 0x96, 0xf0, 0x09, 0x1f, 0x20, 0x8c, 0xb0, 0x8d, + 0xc7, 0x28, 0x76, 0x93, 0x11, 0xfd, 0x7e, 0xc4, 0x79, 0x03, 0x46, 0xb0, + 0xd6, 0x55, 0xc9, 0xf6, 0x0a, 0xe4, 0x4d, 0x15, 0xf1, 0x43, 0x53, 0x09, + 0xe7, 0x44, 0x44, 0xbb, 0x8e, 0x5f, 0xa5, 0x44, 0x72, 0x10, 0x2d, 0x1c, + 0xf5, 0xb2, 0x83, 0xb9, 0xcc, 0x9c, 0x27, 0x18, 0x25, 0x56, 0xd4, 0xa8, + 0xa1, 0x5c, 0x5a, 0xcd, 0x22, 0x72, 0x06, 0x5c, 0x46, 0xd8, 0x6f, 0x62, + 0x15, 0x2a, 0xbb, 0x8a, 0x92, 0x22, 0x04, 0xc4, 0x23, 0x5a, 0x17, 0x91, + 0x41, 0xaf, 0x10, 0x35, 0x32, 0x94, 0xe8, 0xd1, 0x48, 0xa7, 0x70, 0x6d, + 0x98, 0xaa, 0x9a, 0xe5, 0x19, 0xc9, 0x50, 0x4e, 0x98, 0xa2, 0x04, 0x8a, + 0x85, 0x60, 0x62, 0xe9, 0xa9, 0x21, 0x2c, 0x4d, 0x29, 0xdd, 0x11, 0xde, + 0x12, 0xfe, 0xe2, 0x4a, 0x20, 0x8c, 0x0b, 0x82, 0x67, 0xd2, 0xab, 0x57, + 0x81, 0xd4, 0x4a, 0x75, 0x56, 0x0f, 0x9c, 0x81, 0x76, 0x66, 0xea, 0x64, + 0x9a, 0x2e, 0xf3, 0x2e, 0x79, 0x09, 0xd7, 0x34, 0x01, 0x4d, 0xd2, 0xbc, + 0x0b, 0xa8, 0xd0, 0xb3, 0xde, 0xe2, 0x7d, 0xd3, 0x93, 0x16, 0x40, 0xe2, + 0xa6, 0x60, 0x70, 0xa0, 0xf9, 0xa8, 0x33, 0x30, 0x3a, 0x25, 0x72, 0xda, + 0x16, 0x4b, 0x41, 0xa2, 0x08, 0x20, 0x82, 0x08, 0xc4, 0x73, 0x50, 0xd4, + 0xa1, 0x50, 0xa8, 0xae, 0x52, 0x5e, 0x19, 0xae, 0xe1, 0x84, 0x31, 0xb7, + 0x43, 0x2d, 0x86, 0x5e, 0x01, 0xb1, 0xd3, 0x06, 0x82, 0x59, 0xa1, 0x9b, + 0x54, 0x7d, 0x88, 0x94, 0xca, 0xb0, 0x51, 0x13, 0x98, 0x92, 0x58, 0x26, + 0x48, 0xa7, 0x59, 0x1b, 0x13, 0xd1, 0x3e, 0x8e, 0xac, 0x58, 0x34, 0x43, + 0x04, 0x08, 0x10, 0x23, 0x07, 0x5b, 0x8a, 0xb9, 0xab, 0x70, 0xcd, 0x27, + 0x10, 0xdc, 0xe1, 0xac, 0xbe, 0xa6, 0x3c, 0x48, 0x84, 0xda, 0x1a, 0x70, + 0x58, 0xc6, 0x06, 0xc4, 0x22, 0x74, 0x12, 0x4d, 0xda, 0x22, 0x54, 0xa8, + 0xa1, 0x10, 0x40, 0xf0, 0x41, 0xaa, 0x03, 0x16, 0x46, 0x8d, 0x04, 0x26, + 0xed, 0x2d, 0x47, 0x3c, 0x43, 0x2f, 0xc9, 0xe8, 0x3c, 0x27, 0x41, 0x3c, + 0x10, 0xb0, 0x24, 0x46, 0x64, 0x65, 0x22, 0x5c, 0x92, 0x48, 0xb0, 0x95, + 0xa9, 0x08, 0xd1, 0x17, 0x35, 0x5d, 0xcb, 0x59, 0x3b, 0x23, 0xba, 0x73, + 0x14, 0x95, 0xae, 0x3c, 0xaa, 0xe4, 0x4e, 0x2c, 0x84, 0x48, 0x4f, 0xe4, + 0xfd, 0xb1, 0x78, 0x31, 0x0d, 0x08, 0xc1, 0x8c, 0x64, 0x0f, 0x4e, 0x84, + 0x86, 0x9b, 0x19, 0x2d, 0x06, 0x34, 0x41, 0x04, 0x11, 0xd1, 0x04, 0x0e, + 0xd3, 0x64, 0xc0, 0x95, 0x86, 0x93, 0x5b, 0x97, 0xff, 0x00, 0x48, 0x5f, + 0x5c, 0x6c, 0xff, 0x00, 0x5c, 0x7b, 0xb0, 0x08, 0xeb, 0xe1, 0x0f, 0x80, + 0x54, 0x8c, 0xdf, 0xce, 0x34, 0xbc, 0xc1, 0x34, 0xdf, 0x26, 0xc9, 0xfb, + 0x21, 0x1a, 0x7e, 0xe8, 0x95, 0x97, 0x12, 0x33, 0xb9, 0x6a, 0x54, 0x5b, + 0x10, 0x21, 0x62, 0xb0, 0x4f, 0x0d, 0x96, 0x42, 0x49, 0x24, 0x93, 0x9d, + 0xc9, 0x13, 0xc6, 0x49, 0xc6, 0x70, 0x9c, 0x0e, 0xa1, 0x5c, 0xc8, 0x8a, + 0x62, 0x65, 0xb9, 0xb4, 0x3d, 0xce, 0x65, 0x0d, 0x63, 0x38, 0x49, 0x71, + 0xe2, 0x09, 0x60, 0x4f, 0x53, 0x35, 0xe4, 0x34, 0x3b, 0x0c, 0x2f, 0x84, + 0x08, 0xfe, 0x9c, 0x7a, 0x23, 0x98, 0x18, 0x42, 0xd7, 0x62, 0x2a, 0x4b, + 0x03, 0x10, 0x41, 0x02, 0x1e, 0xf6, 0x0c, 0x32, 0x82, 0x98, 0xad, 0x99, + 0x3d, 0x48, 0xfb, 0x69, 0xac, 0xfa, 0x94, 0xc9, 0xa9, 0x7a, 0xa3, 0x63, + 0x8f, 0x5d, 0x24, 0x21, 0xde, 0x21, 0xeb, 0xbb, 0xf4, 0x33, 0x4d, 0x3e, + 0x5c, 0x88, 0x28, 0xd7, 0x81, 0x15, 0x84, 0x03, 0x55, 0x64, 0x64, 0xdc, + 0x73, 0x27, 0x96, 0x5a, 0xfc, 0xbf, 0xd0, 0x8c, 0xa6, 0xae, 0xa7, 0xfb, + 0x1a, 0x3e, 0x79, 0xe0, 0x92, 0x49, 0xc2, 0x49, 0xc1, 0x24, 0x56, 0xd2, + 0xa8, 0xd6, 0x62, 0x90, 0xde, 0x82, 0x62, 0xc9, 0xe8, 0x63, 0xc1, 0xcd, + 0xf0, 0x8d, 0x36, 0xb6, 0x43, 0x18, 0xc8, 0xea, 0x82, 0x04, 0x20, 0x42, + 0xc6, 0x08, 0x23, 0x04, 0x74, 0xba, 0x2a, 0x05, 0x4b, 0xe7, 0xed, 0x72, + 0x48, 0xe5, 0xd5, 0xbc, 0xca, 0x05, 0xd1, 0x38, 0xcc, 0x31, 0x5a, 0x50, + 0xc9, 0x24, 0x97, 0xed, 0x05, 0xb8, 0x49, 0x24, 0x93, 0xd0, 0x24, 0x92, + 0x49, 0x18, 0xa7, 0x18, 0x29, 0x0f, 0x84, 0x70, 0x44, 0xa6, 0x4e, 0xa2, + 0x6b, 0xb8, 0xf7, 0x7c, 0x9b, 0x0f, 0xc9, 0xf7, 0x3c, 0x3e, 0xdc, 0x58, + 0x08, 0x92, 0xf3, 0xc0, 0x43, 0x90, 0x4d, 0x09, 0x65, 0xb9, 0x57, 0x61, + 0x22, 0xcb, 0x04, 0x0d, 0x61, 0x2a, 0x20, 0xc4, 0x62, 0x30, 0xa2, 0xd9, + 0x11, 0x82, 0x11, 0x4c, 0x28, 0x68, 0x54, 0x95, 0xb5, 0x81, 0xf7, 0xc2, + 0xe9, 0xde, 0x8b, 0x02, 0x64, 0x92, 0x49, 0x22, 0xd9, 0xe5, 0x65, 0xab, + 0x1c, 0xda, 0xcc, 0xe5, 0x89, 0x92, 0x4e, 0x12, 0x49, 0x24, 0x93, 0x8a, + 0x5b, 0xcd, 0xa2, 0x6c, 0x38, 0xa9, 0x6a, 0xa7, 0x83, 0xeb, 0x63, 0x6c, + 0x24, 0x4a, 0xac, 0xb6, 0x58, 0x1e, 0x30, 0x46, 0x31, 0x82, 0x16, 0x09, + 0xe4, 0x2e, 0x88, 0x20, 0x82, 0x30, 0x41, 0x02, 0x09, 0x09, 0x73, 0xa4, + 0xa9, 0x37, 0x33, 0x96, 0xee, 0xd8, 0xb0, 0x21, 0x63, 0x38, 0x49, 0x38, + 0x4c, 0x2e, 0xa4, 0xae, 0x30, 0x92, 0x9e, 0xb5, 0x59, 0x61, 0x38, 0xcf, + 0x54, 0xf4, 0x3c, 0x1f, 0x32, 0x19, 0x8a, 0x59, 0xa5, 0x60, 0xb0, 0xfa, + 0x80, 0x82, 0x08, 0x20, 0x82, 0x0b, 0xa7, 0x62, 0x14, 0x24, 0x34, 0x34, + 0x41, 0x18, 0xb4, 0x49, 0x5c, 0x65, 0xb8, 0xdb, 0x42, 0x53, 0x21, 0xd8, + 0xe6, 0xf0, 0x59, 0x8f, 0x2e, 0xb6, 0x74, 0x69, 0xba, 0x22, 0x1e, 0xb8, + 0x28, 0x25, 0x81, 0x09, 0x92, 0x22, 0x49, 0x2a, 0x47, 0xcc, 0xca, 0x30, + 0x92, 0x49, 0x27, 0xa2, 0x70, 0x5c, 0x1a, 0xb3, 0x55, 0xef, 0x27, 0xa7, + 0x4c, 0x93, 0x85, 0x60, 0x9c, 0x82, 0x5a, 0xd4, 0xc9, 0x0d, 0x8c, 0x64, + 0x11, 0x84, 0x10, 0x47, 0x4a, 0x12, 0x77, 0x04, 0x10, 0x41, 0x04, 0x61, + 0x04, 0x10, 0x40, 0x82, 0x43, 0x73, 0x93, 0xfe, 0xa4, 0x6d, 0x86, 0xdb, + 0x56, 0xd8, 0x82, 0xc1, 0x62, 0xb1, 0x4c, 0x91, 0xd1, 0x91, 0x26, 0x94, + 0xe1, 0x24, 0x97, 0x25, 0x45, 0x82, 0x49, 0x24, 0x92, 0x7f, 0x03, 0x78, + 0x32, 0x62, 0xf1, 0x86, 0x2d, 0xd1, 0x65, 0xae, 0x45, 0x12, 0x55, 0x50, + 0xf0, 0x20, 0x82, 0x08, 0x20, 0x82, 0x08, 0x14, 0x8d, 0x7c, 0x24, 0x20, + 0x82, 0x31, 0x16, 0x1a, 0x41, 0xbe, 0x94, 0x49, 0xa0, 0xb4, 0x91, 0x2e, + 0x63, 0x3c, 0x09, 0x09, 0x09, 0x08, 0x42, 0x10, 0x89, 0x24, 0xa8, 0xbf, + 0x1a, 0x13, 0x04, 0x92, 0x49, 0x24, 0x92, 0x4e, 0x12, 0x48, 0xc9, 0x06, + 0xa7, 0x28, 0xa2, 0x6c, 0x65, 0x7c, 0xc9, 0xc5, 0x88, 0x49, 0x6e, 0x11, + 0x77, 0xc8, 0x1e, 0xed, 0xb4, 0xb7, 0x9b, 0x1b, 0x1f, 0x5c, 0x10, 0x41, + 0x04, 0x08, 0x47, 0x3f, 0xa1, 0x1f, 0x86, 0x06, 0xa6, 0x24, 0x66, 0xc7, + 0xc9, 0x8f, 0x33, 0xf5, 0x2a, 0xd3, 0x77, 0xab, 0xc0, 0x4b, 0x15, 0xd1, + 0x38, 0x49, 0x22, 0x70, 0xe4, 0x41, 0xdd, 0x6c, 0x9b, 0x93, 0x6c, 0xd4, + 0x42, 0x08, 0x92, 0x49, 0x24, 0x4c, 0x92, 0x49, 0x27, 0x09, 0xc2, 0x49, + 0xc1, 0xe2, 0x6f, 0x3d, 0x2c, 0x86, 0xa8, 0x92, 0xd5, 0x08, 0x25, 0x93, + 0xc1, 0x04, 0x10, 0x41, 0x04, 0x0c, 0x08, 0x58, 0x88, 0x20, 0x82, 0x30, + 0x20, 0x83, 0x1e, 0xa7, 0x40, 0x41, 0x04, 0x12, 0x10, 0x85, 0x82, 0xe8, + 0x92, 0xd3, 0x6b, 0xd4, 0xb8, 0xdb, 0xcb, 0x41, 0x09, 0x27, 0x04, 0x92, + 0x49, 0x24, 0x92, 0x49, 0x24, 0x8c, 0x9c, 0x81, 0x90, 0xd2, 0x6a, 0xe6, + 0x84, 0x05, 0x19, 0xa1, 0x25, 0x33, 0xb6, 0x87, 0xb5, 0x53, 0x45, 0x86, + 0xc6, 0xc6, 0xc7, 0xf8, 0xa0, 0x81, 0x08, 0x81, 0x4b, 0xaa, 0x88, 0x43, + 0x66, 0xba, 0xe0, 0x81, 0xa1, 0x1f, 0x78, 0xaf, 0x34, 0x79, 0x73, 0x82, + 0x8c, 0x74, 0xce, 0x32, 0x49, 0x24, 0x92, 0x31, 0x83, 0xc8, 0x65, 0x35, + 0x6d, 0x16, 0x8b, 0xa2, 0x70, 0x92, 0x49, 0x24, 0x9f, 0xc0, 0xd0, 0xf0, + 0x92, 0x79, 0x68, 0x7b, 0x1a, 0x5a, 0x67, 0x07, 0x2c, 0xa3, 0xe0, 0xb0, + 0x93, 0xb1, 0x49, 0x74, 0xa0, 0x9c, 0x02, 0x89, 0x04, 0x11, 0x84, 0x11, + 0x81, 0x04, 0x14, 0x79, 0x8e, 0x84, 0x10, 0x41, 0x04, 0x0b, 0xa5, 0x12, + 0x4e, 0x12, 0x3d, 0xb2, 0x12, 0xec, 0xa2, 0xa9, 0x69, 0xf3, 0x88, 0x9c, + 0x64, 0x92, 0x49, 0x24, 0x92, 0x49, 0x24, 0x91, 0x89, 0x38, 0x7c, 0xc9, + 0x16, 0x4c, 0x49, 0x2e, 0x71, 0x99, 0x32, 0x89, 0x1b, 0xc1, 0x3f, 0x95, + 0x0d, 0xe1, 0xf5, 0x16, 0x08, 0xe9, 0x68, 0x55, 0x19, 0xb1, 0x37, 0x3f, + 0xdb, 0xf0, 0x4c, 0x56, 0xe6, 0x0a, 0x51, 0xf9, 0xeb, 0x85, 0x41, 0x10, + 0xac, 0x2c, 0x24, 0x9c, 0x27, 0x09, 0x24, 0x92, 0x49, 0x24, 0x9e, 0xb6, + 0x86, 0x6e, 0x7f, 0x04, 0x64, 0x05, 0x2a, 0x0d, 0x9c, 0x50, 0xc8, 0xbc, + 0xd4, 0x48, 0xb1, 0xa3, 0xa2, 0x08, 0x23, 0x04, 0x10, 0x46, 0x17, 0x9d, + 0x90, 0x47, 0xe4, 0x91, 0xab, 0x9b, 0x42, 0x57, 0x63, 0x65, 0x21, 0x30, + 0x08, 0x4e, 0x31, 0x24, 0x92, 0x70, 0x9e, 0x81, 0x24, 0x92, 0x48, 0xc4, + 0x91, 0xa9, 0x44, 0xa4, 0xd9, 0x66, 0xea, 0x08, 0x58, 0x9f, 0xcc, 0xc4, + 0x2f, 0x34, 0x85, 0x8e, 0xf6, 0x11, 0x82, 0xe9, 0xd9, 0x73, 0xf0, 0x35, + 0xcc, 0x0f, 0xbd, 0x89, 0x0c, 0x37, 0x12, 0x9c, 0x18, 0xeb, 0x92, 0x7a, + 0xda, 0x94, 0x14, 0x84, 0x84, 0x17, 0x4c, 0x93, 0x8c, 0x92, 0x49, 0x38, + 0xc9, 0x24, 0x93, 0x84, 0x15, 0x62, 0x74, 0xc4, 0xde, 0xec, 0xac, 0x49, + 0xdc, 0x0a, 0xc1, 0x10, 0x20, 0x42, 0x21, 0x82, 0x30, 0x41, 0x18, 0x40, + 0x90, 0x91, 0x04, 0x09, 0x14, 0x1c, 0xdb, 0xfc, 0xec, 0x6d, 0x48, 0xbb, + 0x63, 0xde, 0xba, 0x30, 0x4a, 0x26, 0x49, 0x24, 0x92, 0x49, 0x24, 0x92, + 0x4e, 0x12, 0x4e, 0x09, 0x24, 0x9c, 0x5a, 0x18, 0x94, 0x8b, 0xa8, 0x16, + 0x87, 0x74, 0x2b, 0x47, 0x84, 0x74, 0x4e, 0x33, 0x84, 0x92, 0x4e, 0x2d, + 0x12, 0xbc, 0xf7, 0x47, 0x12, 0x54, 0xd7, 0xc1, 0x44, 0x73, 0xab, 0xa0, + 0x99, 0x4b, 0x69, 0x47, 0xa9, 0x22, 0x5b, 0x96, 0xf5, 0x24, 0x20, 0x8c, + 0x74, 0xc9, 0x3d, 0x33, 0xd3, 0x0e, 0x57, 0x78, 0x0b, 0x1d, 0x33, 0xd5, + 0x24, 0x93, 0x89, 0x24, 0x93, 0x84, 0x97, 0x1b, 0xca, 0x7c, 0x8e, 0x02, + 0x82, 0x8e, 0xd3, 0x18, 0x23, 0xaa, 0x08, 0xc0, 0x84, 0x09, 0x09, 0x0c, + 0x68, 0x2b, 0xf9, 0x7e, 0x5d, 0xb0, 0xe1, 0xcb, 0x1c, 0xa9, 0x7d, 0x09, + 0xa2, 0xa6, 0x46, 0x45, 0xb6, 0x02, 0x08, 0x91, 0xb2, 0x49, 0x24, 0x4c, + 0x92, 0x46, 0xb2, 0x45, 0x95, 0x1e, 0x02, 0x89, 0x64, 0xd6, 0xab, 0x04, + 0x92, 0x49, 0x24, 0x92, 0x4e, 0x2c, 0x62, 0x4c, 0x15, 0x66, 0xfc, 0x92, + 0xcf, 0xc0, 0x4e, 0xce, 0x08, 0xbc, 0xc9, 0x11, 0x24, 0x93, 0xd0, 0xa9, + 0x1d, 0x9c, 0xca, 0x9c, 0xca, 0x06, 0x6f, 0x8a, 0xe5, 0x91, 0x6e, 0x6a, + 0x55, 0x2e, 0xd7, 0xa3, 0x46, 0x27, 0xd0, 0xd2, 0x49, 0x3d, 0x13, 0xd0, + 0xe6, 0xd7, 0x87, 0x0a, 0x90, 0xb0, 0x9c, 0x64, 0x92, 0x7f, 0x0c, 0x93, + 0x8b, 0x1c, 0x6a, 0xb2, 0xb3, 0x59, 0x32, 0x3f, 0xbb, 0x59, 0xf7, 0x22, + 0xf3, 0x23, 0x82, 0x04, 0x92, 0x49, 0x38, 0x8c, 0x2c, 0x11, 0x38, 0x17, + 0xd7, 0x2f, 0xf2, 0xac, 0x2a, 0x59, 0x06, 0x38, 0x4b, 0x4e, 0xfa, 0x8a, + 0x19, 0x8f, 0xae, 0x65, 0x25, 0xb9, 0x3b, 0xf4, 0x09, 0xc4, 0xa4, 0x47, + 0x28, 0x77, 0x41, 0xf0, 0xc1, 0xb2, 0xa3, 0x07, 0x6c, 0x90, 0xaa, 0xa9, + 0x55, 0x68, 0xda, 0xee, 0x41, 0xcf, 0x77, 0xb0, 0x42, 0x49, 0x24, 0x9c, + 0x27, 0xa2, 0x71, 0x63, 0x43, 0x2c, 0xb3, 0x0d, 0x59, 0x8b, 0x3c, 0x9f, + 0x28, 0x9e, 0xbf, 0x91, 0xff, 0x00, 0x26, 0x7d, 0x47, 0xe8, 0xfa, 0xcf, + 0xd0, 0xd5, 0x99, 0x72, 0xca, 0x25, 0x6a, 0x64, 0x26, 0x9e, 0xe3, 0xb1, + 0x8b, 0xbc, 0xb2, 0x1d, 0x99, 0x7e, 0x1b, 0x1a, 0xa3, 0xb4, 0x8a, 0xe8, + 0x11, 0xab, 0x82, 0x1e, 0x5a, 0xee, 0x63, 0x76, 0x68, 0x58, 0x1b, 0x7b, + 0x4c, 0x9a, 0x49, 0x7a, 0x48, 0x41, 0xa1, 0xd0, 0x90, 0x64, 0x3e, 0x06, + 0x50, 0x6e, 0x99, 0x26, 0x29, 0x0a, 0x48, 0xc5, 0x75, 0x59, 0x95, 0x35, + 0x2b, 0x97, 0x7a, 0xe2, 0x4b, 0x06, 0xc9, 0xc6, 0x7a, 0x26, 0x7f, 0x0b, + 0x43, 0x0d, 0x0e, 0x49, 0x1c, 0x44, 0xad, 0xa4, 0xe0, 0xb5, 0x2b, 0xe9, + 0x38, 0x94, 0xd3, 0x5e, 0x72, 0x1c, 0x51, 0x35, 0x75, 0x16, 0x0f, 0xd1, + 0xbe, 0xc1, 0x31, 0xea, 0xca, 0x1f, 0x07, 0xa2, 0x0d, 0xec, 0xe4, 0x4e, + 0x7c, 0xe9, 0x7e, 0x50, 0xaa, 0x87, 0x46, 0x4b, 0x98, 0xa7, 0x80, 0xc2, + 0x12, 0x53, 0x81, 0x7c, 0xd3, 0x37, 0x82, 0x49, 0x27, 0x19, 0xc2, 0x49, + 0x24, 0xb1, 0x73, 0xa2, 0xac, 0xa1, 0x7a, 0xf0, 0x9c, 0x97, 0xdc, 0x84, + 0x4a, 0x5a, 0xe2, 0x54, 0x0c, 0x56, 0x65, 0x8d, 0x84, 0x2c, 0x92, 0xfd, + 0x28, 0xb3, 0xaf, 0x71, 0x2b, 0xcd, 0x32, 0x5b, 0xb5, 0x47, 0xb0, 0x9d, + 0x3c, 0xdd, 0x60, 0x6b, 0x4b, 0x97, 0x7f, 0xf6, 0x67, 0xa1, 0x47, 0xfb, + 0x32, 0x9a, 0x4e, 0xe0, 0x9f, 0xf2, 0xa4, 0x4a, 0xaa, 0xdc, 0x70, 0x3c, + 0xd1, 0xf6, 0x61, 0x09, 0x22, 0xd1, 0x48, 0x7b, 0x0d, 0x16, 0xae, 0xf5, + 0x04, 0xb6, 0x34, 0xc9, 0x24, 0x92, 0x70, 0x92, 0x49, 0xe8, 0x63, 0x18, + 0xd0, 0xd6, 0x0c, 0x78, 0x0d, 0xc9, 0x73, 0x2c, 0xd3, 0x3c, 0x03, 0x54, + 0x55, 0xff, 0x00, 0xca, 0xe7, 0xc0, 0xcb, 0x3b, 0x7f, 0xb1, 0x9a, 0xe0, + 0x7a, 0xb6, 0x63, 0xe6, 0xa9, 0x7b, 0x16, 0x2e, 0xf6, 0x85, 0x7e, 0xf9, + 0x88, 0x96, 0xdf, 0x60, 0xcb, 0xbc, 0x25, 0x5b, 0xde, 0x32, 0x37, 0x48, + 0x75, 0x28, 0x40, 0xa8, 0x50, 0x10, 0x48, 0x82, 0x3a, 0x62, 0x6d, 0x73, + 0x25, 0x86, 0xe5, 0x42, 0xa1, 0x16, 0x58, 0xa2, 0xc2, 0x49, 0x24, 0x92, + 0x49, 0x27, 0xa2, 0x7f, 0x0c, 0x60, 0x65, 0x87, 0x32, 0xac, 0xa1, 0x6a, + 0xc6, 0xa4, 0x05, 0xd7, 0x42, 0xf9, 0x55, 0xa5, 0x90, 0x90, 0xda, 0x32, + 0xc8, 0xd0, 0x13, 0xd8, 0x9e, 0x92, 0x4b, 0x38, 0xe5, 0x29, 0x67, 0x70, + 0x8d, 0xc6, 0x1d, 0x8e, 0x46, 0x99, 0x1d, 0xe5, 0xf0, 0x30, 0x69, 0x82, + 0x24, 0x47, 0x92, 0x68, 0x4f, 0x12, 0x7e, 0xe2, 0x6c, 0x4c, 0xc6, 0xc3, + 0x86, 0x97, 0xf6, 0x22, 0x55, 0x56, 0xb7, 0xff, 0x00, 0x27, 0xdb, 0xf9, + 0x12, 0xfd, 0x7f, 0x46, 0xa3, 0xf7, 0xc0, 0xc2, 0xcf, 0x68, 0xed, 0xa5, + 0xa0, 0x24, 0xb3, 0xdd, 0xa4, 0xbe, 0x38, 0x05, 0x83, 0xdd, 0x51, 0x7f, + 0xe3, 0x45, 0x44, 0x20, 0x82, 0x0d, 0x4e, 0x94, 0x3d, 0x46, 0x39, 0x4b, + 0xd9, 0x91, 0x89, 0x24, 0x92, 0x70, 0x27, 0x59, 0x89, 0x4c, 0x5a, 0x47, + 0x72, 0xfc, 0xd7, 0x24, 0x2d, 0x33, 0x50, 0xb9, 0x32, 0x67, 0xe0, 0xc9, + 0x3d, 0x01, 0xc3, 0xba, 0x3b, 0x5c, 0x0a, 0xea, 0x42, 0xcf, 0x13, 0xc9, + 0xae, 0x46, 0x7d, 0x2a, 0xa3, 0xe8, 0x61, 0xa5, 0x22, 0x16, 0x50, 0x9b, + 0x3c, 0x24, 0x9c, 0x67, 0xa1, 0x92, 0x34, 0x5d, 0xa2, 0xc6, 0x3b, 0x9f, + 0xeb, 0x4d, 0x53, 0xc2, 0x6c, 0x62, 0xcd, 0xf8, 0x71, 0x7e, 0x96, 0x25, + 0xf2, 0x25, 0xbd, 0xc0, 0x42, 0xfe, 0x29, 0x73, 0x8b, 0x72, 0x64, 0x20, + 0x7a, 0x48, 0x19, 0x72, 0x18, 0x61, 0x86, 0x95, 0x52, 0x4c, 0xdd, 0x1e, + 0x45, 0x30, 0x35, 0x82, 0xfd, 0x46, 0xe5, 0x19, 0xd7, 0xb8, 0xa1, 0xda, + 0xa4, 0x11, 0x8a, 0x32, 0xbc, 0xb6, 0x20, 0x9f, 0x13, 0x2c, 0xb0, 0xc1, + 0x41, 0x18, 0x16, 0x12, 0x49, 0x38, 0xce, 0x33, 0xf8, 0xee, 0xad, 0x52, + 0x09, 0x64, 0x27, 0x5e, 0x8b, 0x73, 0x3d, 0x1c, 0x8c, 0x97, 0x42, 0xcf, + 0xcb, 0x46, 0x99, 0x12, 0xa8, 0xcd, 0xdc, 0x59, 0xcf, 0x6c, 0xbf, 0xa2, + 0x4f, 0x9d, 0x07, 0x9e, 0x79, 0x5f, 0xd0, 0xd8, 0x2b, 0xf7, 0x91, 0xb6, + 0x37, 0xe8, 0x3f, 0xe8, 0xb1, 0x76, 0x74, 0x7b, 0x4b, 0x89, 0xea, 0x86, + 0xb2, 0x2e, 0xe8, 0x68, 0x24, 0xb8, 0x46, 0xf3, 0x1b, 0x8a, 0xaa, 0x3d, + 0x8a, 0x23, 0x09, 0x94, 0x88, 0xc4, 0xcd, 0xc3, 0xcd, 0x88, 0xb0, 0x5a, + 0xe4, 0x89, 0x59, 0x46, 0x6b, 0x33, 0xd4, 0xed, 0x8b, 0x05, 0x14, 0x84, + 0xb0, 0x92, 0x46, 0x32, 0x7b, 0x53, 0xb8, 0x99, 0x07, 0xa0, 0x49, 0x24, + 0x92, 0x4f, 0x40, 0x9c, 0x13, 0xd2, 0x0c, 0xb5, 0xc4, 0x2b, 0x3a, 0x2a, + 0x32, 0xd6, 0x79, 0x21, 0x4f, 0x75, 0x6d, 0x28, 0x9b, 0xeb, 0xc9, 0x64, + 0x77, 0x4a, 0x44, 0xf2, 0xb7, 0x56, 0x92, 0x15, 0x2d, 0xc0, 0xb9, 0xd0, + 0xfa, 0x34, 0x8c, 0x14, 0xaf, 0x12, 0x3f, 0xd6, 0x08, 0x7a, 0x89, 0xbd, + 0x99, 0x22, 0x56, 0x72, 0x19, 0x9c, 0x6a, 0xdc, 0x91, 0x7d, 0x02, 0xac, + 0x12, 0xf6, 0x33, 0x8c, 0xec, 0x2d, 0x4f, 0x91, 0x3c, 0xc3, 0x19, 0x84, + 0xa6, 0x84, 0xe0, 0x45, 0xb9, 0x26, 0xbd, 0x29, 0x41, 0x26, 0xf4, 0x55, + 0x24, 0xa3, 0x02, 0x53, 0x4c, 0x82, 0x9a, 0x09, 0xe9, 0xbe, 0x70, 0x58, + 0xdf, 0x26, 0x43, 0xd5, 0x95, 0xd5, 0x89, 0x49, 0xb9, 0x0b, 0x53, 0x56, + 0xc5, 0x89, 0x0d, 0x66, 0x55, 0x5b, 0x16, 0x0c, 0x3d, 0x81, 0x91, 0xe8, + 0x50, 0xe0, 0x5a, 0xea, 0xee, 0x14, 0xb3, 0xb4, 0x85, 0xfb, 0x2e, 0x8b, + 0xb4, 0x58, 0x57, 0x96, 0x58, 0xd0, 0x34, 0xc5, 0xd9, 0x1b, 0x1f, 0x4f, + 0xd0, 0xb4, 0x9e, 0x11, 0x0e, 0x5f, 0x08, 0xcf, 0x78, 0xd1, 0xf4, 0x90, + 0xbf, 0x90, 0x2f, 0xe6, 0x46, 0xc7, 0x89, 0x07, 0xeb, 0x11, 0xfe, 0x91, + 0x7a, 0x67, 0xde, 0xe5, 0xa7, 0xb9, 0x21, 0xb2, 0x8d, 0xf7, 0xd0, 0x71, + 0x55, 0x79, 0x34, 0x99, 0x91, 0x38, 0xda, 0x2e, 0x7b, 0xb0, 0xb0, 0x73, + 0x02, 0x18, 0xce, 0x41, 0x8b, 0x08, 0xce, 0xcb, 0x4c, 0x8d, 0x43, 0x1e, + 0xe1, 0x58, 0x5c, 0x6c, 0xcc, 0xa3, 0x10, 0x65, 0xea, 0x53, 0x96, 0x18, + 0x14, 0x2a, 0x1a, 0xf7, 0x15, 0x07, 0x2c, 0xed, 0xd5, 0x7c, 0x89, 0x6e, + 0x1b, 0xc3, 0x16, 0x83, 0x76, 0x17, 0xf1, 0xf4, 0x7f, 0xec, 0x47, 0xc4, + 0x0d, 0xfe, 0x88, 0xbe, 0x37, 0xe1, 0x86, 0x83, 0x25, 0xd5, 0xcb, 0x2d, + 0x0b, 0xee, 0x34, 0xbe, 0x21, 0x2a, 0xae, 0x97, 0xde, 0xa4, 0x54, 0xee, + 0x94, 0x0b, 0x29, 0x08, 0xeb, 0x86, 0x30, 0x9c, 0x0b, 0xa7, 0x9a, 0x14, + 0xfd, 0xa5, 0x29, 0x6a, 0x35, 0x75, 0x63, 0x39, 0x5d, 0x12, 0x2d, 0x69, + 0x31, 0xc8, 0xa9, 0x68, 0x4f, 0xe2, 0x00, 0x4e, 0x09, 0x24, 0x92, 0x70, + 0x32, 0xb5, 0xab, 0x1c, 0xf0, 0x84, 0xe5, 0xe0, 0x4c, 0x92, 0x64, 0x49, + 0x90, 0xd8, 0x95, 0xa6, 0x4f, 0xab, 0x41, 0xb5, 0x6c, 0x6c, 0x96, 0xde, + 0x81, 0x5f, 0xb8, 0x33, 0x26, 0x12, 0xb4, 0x10, 0xce, 0xce, 0x0a, 0x02, + 0x78, 0x2f, 0xce, 0x10, 0xa1, 0x12, 0x84, 0x1a, 0x49, 0x36, 0xaa, 0x46, + 0xa2, 0x44, 0x0f, 0xe4, 0x27, 0xac, 0x14, 0xba, 0x5e, 0x4b, 0x4f, 0xa8, + 0x4a, 0x5c, 0x43, 0x65, 0xec, 0x8c, 0xd0, 0x26, 0xa7, 0x21, 0x26, 0x63, + 0xce, 0x78, 0x1f, 0xee, 0x48, 0x22, 0x84, 0x34, 0x70, 0x79, 0x43, 0x63, + 0xfd, 0x06, 0x40, 0x76, 0x0c, 0xdf, 0xcc, 0xcb, 0x3e, 0xe4, 0x87, 0x9f, + 0xd8, 0x43, 0x5d, 0xdf, 0xb2, 0x1e, 0x63, 0xbc, 0x6f, 0x21, 0x6c, 0x5e, + 0xa3, 0x2e, 0x98, 0x15, 0xd6, 0xba, 0x2b, 0x93, 0xaa, 0xa7, 0xa8, 0x3e, + 0xa3, 0x38, 0x50, 0x7e, 0xea, 0x2b, 0x35, 0xd1, 0x90, 0x73, 0x37, 0xa1, + 0xb6, 0xbe, 0xb8, 0x24, 0xfa, 0x7c, 0x1f, 0xa5, 0x43, 0x17, 0x27, 0x92, + 0x91, 0x7a, 0x37, 0xc3, 0xfd, 0x8d, 0xbf, 0x42, 0x68, 0x16, 0xa5, 0x52, + 0x5b, 0x32, 0x18, 0x76, 0xec, 0x45, 0x30, 0xf4, 0x07, 0xec, 0x36, 0xbb, + 0x98, 0x88, 0xcd, 0x1b, 0xb8, 0x56, 0x09, 0xec, 0x59, 0x37, 0x28, 0xe6, + 0x5e, 0x72, 0x8f, 0x48, 0x26, 0xb7, 0x90, 0x67, 0x2e, 0xf4, 0x33, 0x08, + 0x8a, 0xb0, 0xcf, 0x93, 0xe8, 0x19, 0xdc, 0xf3, 0x22, 0x48, 0x63, 0x40, + 0x90, 0xe6, 0x84, 0xb3, 0x22, 0xbb, 0xe0, 0x5c, 0xfb, 0x5e, 0x31, 0x80, + 0x51, 0x90, 0x76, 0xa3, 0x0c, 0x26, 0xd9, 0xc2, 0x5a, 0xf9, 0x56, 0xc2, + 0x95, 0xb6, 0x59, 0x7b, 0xa2, 0xef, 0xdc, 0xa1, 0xa9, 0xf8, 0xff, 0x00, + 0x24, 0x36, 0x57, 0x38, 0x1d, 0xe6, 0xbd, 0xa4, 0xb9, 0x71, 0xa4, 0x43, + 0x6b, 0x96, 0x97, 0xbb, 0x22, 0xb3, 0x45, 0x69, 0x51, 0x78, 0xb4, 0xf4, + 0x84, 0x92, 0x4e, 0x24, 0xf4, 0x83, 0x45, 0x99, 0x9b, 0x89, 0xc8, 0x73, + 0x5f, 0x02, 0x62, 0x7b, 0x08, 0xd9, 0x84, 0xdc, 0x86, 0xb2, 0x7e, 0x07, + 0x7f, 0x50, 0x95, 0x74, 0x97, 0x21, 0x5d, 0x91, 0xdd, 0x4b, 0x84, 0x3b, + 0x83, 0x96, 0x03, 0x5d, 0xa0, 0x34, 0xef, 0x18, 0x94, 0x84, 0x42, 0x47, + 0x08, 0x52, 0x11, 0x24, 0x93, 0xa0, 0x89, 0xce, 0x16, 0xb9, 0x9b, 0xa1, + 0x9d, 0x86, 0xc8, 0x5a, 0xeb, 0xc9, 0x94, 0x0c, 0x80, 0x5c, 0x9a, 0x64, + 0x32, 0x83, 0xec, 0x45, 0xdf, 0x11, 0x35, 0x61, 0xdc, 0x60, 0x9b, 0x58, + 0x09, 0xae, 0x64, 0xee, 0x5c, 0x79, 0x73, 0xf9, 0x11, 0xc6, 0xe7, 0x5b, + 0xd5, 0x8c, 0xda, 0x16, 0x8b, 0x5f, 0x41, 0xff, 0x00, 0x28, 0xdb, 0xf8, + 0xc3, 0x9a, 0xd0, 0x63, 0xe5, 0x82, 0x15, 0x2e, 0x86, 0x32, 0xde, 0xa3, + 0x40, 0x72, 0x85, 0xd4, 0x09, 0x02, 0x56, 0x70, 0x09, 0xd9, 0x2d, 0xda, + 0x37, 0xce, 0x60, 0x56, 0xdd, 0x98, 0x1e, 0x7b, 0x76, 0x63, 0xc8, 0xc9, + 0xc8, 0x8d, 0x90, 0x6d, 0x9b, 0x84, 0x29, 0xf3, 0xcd, 0x49, 0x44, 0x2a, + 0x91, 0xe4, 0x4d, 0x1b, 0x77, 0x80, 0x41, 0x7b, 0x7d, 0x33, 0x22, 0x07, + 0x50, 0x85, 0x02, 0x2e, 0x09, 0x08, 0xe6, 0xf7, 0x37, 0x0e, 0x44, 0xed, + 0x8a, 0x06, 0xc3, 0x6d, 0x46, 0xcf, 0x31, 0x93, 0xba, 0x43, 0xd0, 0x43, + 0x06, 0x74, 0xfc, 0x9a, 0x8f, 0x21, 0x8c, 0xe4, 0xee, 0x6c, 0x82, 0x10, + 0x84, 0x12, 0x92, 0x05, 0x21, 0xa0, 0xe8, 0x26, 0xb2, 0x64, 0x89, 0x12, + 0xc8, 0xd8, 0xb9, 0x05, 0xde, 0xa3, 0x58, 0x4e, 0x1b, 0xb4, 0x3e, 0x51, + 0x93, 0x6f, 0xc3, 0x32, 0xed, 0xd8, 0xce, 0x3e, 0x04, 0xb3, 0x0e, 0x17, + 0x61, 0xb6, 0x83, 0xed, 0x63, 0x2e, 0xa8, 0xfd, 0xcc, 0xe8, 0x4d, 0xc8, + 0x27, 0x64, 0x26, 0xcc, 0x8e, 0xb8, 0x24, 0x92, 0x49, 0x3e, 0xa3, 0xf7, + 0xd1, 0x1f, 0xb1, 0xea, 0xfd, 0x91, 0x3a, 0xdf, 0x04, 0x97, 0x6f, 0xd8, + 0x2d, 0x77, 0xb0, 0x50, 0xb3, 0x79, 0x29, 0x16, 0xf3, 0x29, 0x3e, 0xe4, + 0x26, 0x56, 0x41, 0xa3, 0xd8, 0x22, 0x4b, 0x76, 0x90, 0xcd, 0x77, 0x8e, + 0x37, 0x5d, 0x9d, 0xc7, 0x9a, 0xcf, 0xb9, 0x06, 0x63, 0x7a, 0x6e, 0x4d, + 0xc1, 0xb8, 0xf0, 0x6e, 0x0d, 0x88, 0x13, 0x90, 0xb8, 0x76, 0x18, 0x0b, + 0x1b, 0xa9, 0x00, 0xb0, 0x9b, 0x05, 0xa1, 0x60, 0x8c, 0x48, 0x98, 0x4d, + 0x98, 0x94, 0x72, 0x44, 0x5e, 0x49, 0x95, 0x0d, 0x8c, 0x38, 0xe4, 0xfd, + 0x4f, 0xa4, 0x9c, 0xcd, 0xe3, 0x77, 0xd0, 0xed, 0xf0, 0x4e, 0x94, 0x6d, + 0x8d, 0x87, 0x93, 0xec, 0x64, 0xbf, 0xb3, 0x93, 0xc9, 0x2d, 0x47, 0x26, + 0x03, 0x88, 0x80, 0x71, 0xc4, 0x07, 0x16, 0x73, 0x15, 0x66, 0x1b, 0x9c, + 0xc3, 0x9e, 0x4c, 0x6a, 0xf2, 0x78, 0x7b, 0xfc, 0x9d, 0xde, 0x4e, 0xff, + 0x00, 0x24, 0xb7, 0xf2, 0x47, 0x64, 0x77, 0x12, 0x33, 0xf9, 0x16, 0x68, + 0x82, 0xe9, 0xe0, 0x4b, 0xe9, 0x14, 0xd4, 0x61, 0xa4, 0xf3, 0x19, 0xd7, + 0xc8, 0xdb, 0xaf, 0x91, 0xee, 0x79, 0x12, 0xcd, 0xf9, 0x1a, 0x73, 0x0d, + 0x36, 0x62, 0x62, 0xd8, 0x27, 0x72, 0x24, 0xc6, 0xa6, 0x09, 0xe9, 0xd0, + 0x57, 0x22, 0x1d, 0xce, 0x01, 0xee, 0x26, 0x43, 0x5d, 0x30, 0x8b, 0x66, + 0xfc, 0x8a, 0xdb, 0xcc, 0x59, 0x1c, 0x4a, 0xd7, 0xca, 0x25, 0xba, 0xe4, + 0x1b, 0x9d, 0xd8, 0xcd, 0x13, 0x6d, 0xd3, 0xb3, 0x12, 0x67, 0x5c, 0x0d, + 0xb3, 0x83, 0xb6, 0x8d, 0x94, 0xdb, 0xbb, 0x1a, 0x69, 0x11, 0x84, 0xaf, + 0xd5, 0x7e, 0xcf, 0xb0, 0xfd, 0x9f, 0x41, 0xfb, 0x25, 0xfc, 0x32, 0x5f, + 0xc3, 0x27, 0xa7, 0x83, 0x38, 0xbf, 0x0c, 0xe6, 0xf0, 0xce, 0x4f, 0x0c, + 0xfa, 0x13, 0x3e, 0xa4, 0xcf, 0xa9, 0x32, 0x7f, 0xe4, 0xc9, 0xeb, 0xf0, + 0xc9, 0x7f, 0x83, 0x25, 0xfd, 0x0f, 0xa6, 0xcd, 0x9f, 0x23, 0x7f, 0xcc, + 0x48, 0xcf, 0xcc, 0x46, 0x28, 0x64, 0x77, 0x38, 0x09, 0xc3, 0xa7, 0xc9, + 0x13, 0x66, 0x89, 0x2e, 0x35, 0x19, 0x06, 0x62, 0x02, 0x44, 0x8d, 0xc9, + 0x29, 0x29, 0x29, 0x26, 0x43, 0x0f, 0x2f, 0x0e, 0x12, 0x22, 0x1c, 0x88, + 0xcd, 0x27, 0x74, 0x6e, 0x8d, 0xf9, 0xb9, 0xeb, 0xc8, 0x13, 0xb1, 0xfe, + 0x49, 0xfc, 0xc3, 0xf9, 0x87, 0xf2, 0x0f, 0xe0, 0x62, 0x29, 0x7f, 0x37, + 0xa6, 0x42, 0x10, 0xbf, 0x82, 0x7f, 0x14, 0xfe, 0x69, 0xfc, 0xd3, 0xf9, + 0xa7, 0xf1, 0x0f, 0xe2, 0x1f, 0xcf, 0x3f, 0x97, 0xd3, 0x09, 0x1d, 0xba, + 0x37, 0xc6, 0xf4, 0x97, 0x36, 0x1c, 0x0c, 0xc2, 0x62, 0x62, 0x6c, 0x04, + 0x50, 0x10, 0x64, 0x40, 0x40, 0x2c, 0x11, 0x81, 0x12, 0xf3, 0x1b, 0x64, + 0x22, 0xb0, 0x87, 0x34, 0x6d, 0xae, 0x8e, 0xae, 0xef, 0x1e, 0x8f, 0xe5, + 0x9f, 0xcb, 0x27, 0xfe, 0x26, 0xd7, 0x89, 0x3d, 0x0a, 0x5a, 0x14, 0x8b, + 0x81, 0x71, 0x28, 0xe0, 0x02, 0x01, 0xb8, 0x4d, 0xe4, 0x6c, 0x07, 0xf0, + 0x59, 0xfc, 0x76, 0x6e, 0x78, 0xb3, 0xff, 0xda, 0x00, 0x0c, 0x03, 0x01, + 0x00, 0x02, 0x00, 0x03, 0x00, 0x00, 0x00, 0x10, 0xcc, 0x4b, 0x27, 0x92, + 0x48, 0x48, 0xfe, 0x09, 0x24, 0x83, 0x6d, 0x26, 0x02, 0x4d, 0x09, 0xe6, + 0xf1, 0xb4, 0x9f, 0x6e, 0x4b, 0xe9, 0x3b, 0x74, 0xf7, 0x0f, 0xba, 0x74, + 0x36, 0x9c, 0x9d, 0x42, 0x3a, 0xba, 0x3b, 0x27, 0xad, 0x2b, 0xb9, 0xff, + 0x00, 0xa1, 0x07, 0x6a, 0x2e, 0x39, 0x1d, 0xc1, 0x29, 0x87, 0xf5, 0x92, + 0x25, 0x96, 0x5a, 0x4d, 0x90, 0x09, 0xb2, 0x6f, 0x26, 0x13, 0x3a, 0x04, + 0x5e, 0x9e, 0x93, 0x1e, 0x4a, 0x9a, 0x6c, 0x87, 0x67, 0x1c, 0xf2, 0xa4, + 0x73, 0xeb, 0x95, 0xea, 0xc4, 0x86, 0x2d, 0x0c, 0xda, 0x8b, 0x44, 0xa7, + 0xf0, 0xd9, 0xbe, 0x40, 0x29, 0x20, 0xeb, 0xc0, 0xa8, 0x8a, 0x02, 0xdb, + 0xec, 0x15, 0x33, 0x16, 0x97, 0xe0, 0x91, 0x90, 0x64, 0xda, 0x6f, 0x2d, + 0xfb, 0x60, 0x56, 0x90, 0x01, 0xa9, 0x37, 0x3d, 0x66, 0xf4, 0x5d, 0x7f, + 0xca, 0x29, 0xed, 0x54, 0x79, 0x9b, 0xb3, 0x3e, 0xcd, 0x89, 0x15, 0xe6, + 0x4a, 0xf4, 0xa3, 0x68, 0xe4, 0x9b, 0x97, 0x43, 0x31, 0x30, 0xf0, 0xb6, + 0xdb, 0xd3, 0x61, 0x08, 0x93, 0x3c, 0x40, 0x93, 0x6f, 0x6d, 0xe9, 0xdf, + 0x40, 0xd3, 0x6f, 0xbc, 0x82, 0x45, 0x07, 0xf8, 0x45, 0xef, 0xbb, 0x49, + 0x6e, 0xbb, 0xd2, 0xcf, 0x10, 0x11, 0xf7, 0x5e, 0x15, 0x64, 0x82, 0x1e, + 0xd0, 0x66, 0x03, 0x24, 0x52, 0x35, 0xed, 0xff, 0x00, 0x46, 0x38, 0xac, + 0x12, 0x59, 0x6b, 0xe9, 0x39, 0x5d, 0xd6, 0x87, 0xe8, 0x03, 0x6f, 0xbe, + 0x92, 0x51, 0x98, 0x1f, 0x69, 0x45, 0x1e, 0x0e, 0x0b, 0x4d, 0xc4, 0xc7, + 0xeb, 0x7a, 0xcc, 0x6e, 0x2b, 0x8c, 0xb3, 0xac, 0xc2, 0x91, 0x67, 0xed, + 0x2a, 0x00, 0xda, 0x69, 0x3e, 0xc3, 0x98, 0xc9, 0xba, 0x80, 0xa9, 0x64, + 0xff, 0x00, 0xdf, 0xd2, 0x24, 0xee, 0xe4, 0x6e, 0x4e, 0xc8, 0xca, 0x0a, + 0x34, 0x4a, 0xc9, 0x69, 0x57, 0x1a, 0x35, 0xa7, 0xd6, 0x38, 0x31, 0xa4, + 0x65, 0xa7, 0xa7, 0xd0, 0x79, 0x75, 0xcc, 0xde, 0xe7, 0x90, 0x06, 0x2f, + 0xca, 0x43, 0xb7, 0x5f, 0x82, 0xda, 0x40, 0xdf, 0x97, 0x1b, 0xed, 0xcf, + 0x43, 0x04, 0x10, 0x65, 0xe8, 0x75, 0x72, 0x12, 0x92, 0x3b, 0xca, 0x5c, + 0xe7, 0xb3, 0x9c, 0x2b, 0xfd, 0xf7, 0xd7, 0x04, 0xb5, 0x3c, 0x24, 0x40, + 0x1e, 0x9c, 0x3b, 0x3b, 0x83, 0xd8, 0x4d, 0x0e, 0x28, 0xa0, 0x63, 0xa4, + 0xe6, 0xab, 0xa4, 0x22, 0xa7, 0x2d, 0x32, 0xdf, 0x80, 0x95, 0x7c, 0x7a, + 0x7f, 0x4f, 0xbb, 0xb1, 0x38, 0xd3, 0x60, 0x4e, 0xae, 0xaa, 0x3f, 0x31, + 0xfb, 0x0f, 0x61, 0x4c, 0xca, 0x48, 0x67, 0xb0, 0x58, 0x14, 0x2e, 0x58, + 0xbb, 0x05, 0x02, 0xa6, 0xcd, 0x05, 0x89, 0x81, 0x49, 0x0e, 0x20, 0x42, + 0xd4, 0x3f, 0x9b, 0x6c, 0x68, 0x1a, 0x0e, 0xd0, 0x5c, 0xe8, 0x4f, 0xfe, + 0xf0, 0xe1, 0x8e, 0x46, 0x2a, 0x71, 0xab, 0xa5, 0x3f, 0x90, 0x72, 0x81, + 0x09, 0x34, 0x3e, 0xaf, 0xc5, 0x35, 0xf7, 0x27, 0x16, 0x63, 0x74, 0x5b, + 0x52, 0xaf, 0x16, 0x3e, 0xe6, 0xff, 0x00, 0x1e, 0x91, 0xde, 0x27, 0x92, + 0x0a, 0x45, 0xcd, 0x94, 0x42, 0xd9, 0x7a, 0x87, 0xd3, 0xae, 0x48, 0x91, + 0x92, 0x49, 0x24, 0x8e, 0xcb, 0xf5, 0xc8, 0xbe, 0x9d, 0x90, 0x5b, 0x3f, + 0xc3, 0xeb, 0x10, 0x24, 0x13, 0xa2, 0xd7, 0xe3, 0xb8, 0xde, 0xe4, 0xbf, + 0x05, 0x34, 0x69, 0x2e, 0xf1, 0x5e, 0xb7, 0xcc, 0xf8, 0xef, 0x56, 0x71, + 0xdd, 0x64, 0x69, 0x08, 0x30, 0x70, 0x41, 0xff, 0x00, 0x2c, 0x92, 0x49, + 0x24, 0x92, 0x49, 0x24, 0x93, 0x91, 0x6d, 0x7b, 0xbd, 0xa5, 0x68, 0xeb, + 0xc5, 0x43, 0x3f, 0x4c, 0x14, 0x8c, 0x82, 0x0a, 0xa4, 0x20, 0x32, 0x49, + 0x24, 0x90, 0xf7, 0x49, 0x67, 0x97, 0xf0, 0x9a, 0xb9, 0x29, 0x91, 0x73, + 0xc5, 0x99, 0x67, 0xc0, 0x8b, 0x30, 0x06, 0x2b, 0x49, 0x24, 0x92, 0x49, + 0x24, 0x92, 0x49, 0x24, 0x92, 0x69, 0x87, 0x19, 0xb3, 0x64, 0x84, 0xde, + 0x49, 0x26, 0x3e, 0x6c, 0xbd, 0xaf, 0xb7, 0xb9, 0x3c, 0x14, 0x92, 0x49, + 0x24, 0x92, 0x43, 0xeb, 0x45, 0xb1, 0x26, 0x0e, 0x9c, 0xca, 0x3a, 0x34, + 0x9a, 0xcb, 0x83, 0xcc, 0xf5, 0x71, 0x41, 0x32, 0x49, 0x24, 0x92, 0x49, + 0x24, 0x92, 0x49, 0x24, 0x92, 0x4f, 0x0f, 0x51, 0x31, 0xbf, 0x4b, 0x5f, + 0xf3, 0x33, 0xe8, 0x05, 0x6b, 0x18, 0x0e, 0xc7, 0xe6, 0xa4, 0x92, 0x49, + 0x24, 0x92, 0x4c, 0x1d, 0x97, 0x4c, 0x8d, 0xd4, 0x9f, 0xc7, 0xd1, 0x0c, + 0x37, 0xc9, 0xb2, 0xc4, 0xbd, 0x1c, 0x28, 0x36, 0x49, 0x24, 0x92, 0x49, + 0x24, 0x92, 0x49, 0x24, 0x85, 0x94, 0x3b, 0x02, 0xe5, 0x3f, 0x24, 0x78, + 0x86, 0x75, 0x2d, 0xfa, 0xd8, 0x02, 0xe5, 0xd8, 0x31, 0xee, 0x26, 0x18, + 0x51, 0x26, 0x4b, 0xa2, 0xc0, 0x10, 0x2f, 0x2a, 0xcd, 0xf0, 0x3c, 0x49, + 0x2c, 0x5b, 0xfa, 0x66, 0x3d, 0xf2, 0xcb, 0xc0, 0xde, 0x8c, 0x92, 0x49, + 0x24, 0x92, 0x49, 0x0c, 0xf9, 0x01, 0xd5, 0x51, 0x73, 0xdf, 0x78, 0x15, + 0xad, 0x6a, 0xe1, 0x1a, 0x99, 0x1d, 0x6c, 0x60, 0x30, 0x63, 0xe3, 0x05, + 0x68, 0x6e, 0x96, 0x70, 0xbb, 0x84, 0x63, 0x0f, 0xb8, 0x78, 0xa9, 0xf6, + 0x0c, 0x30, 0xfa, 0x52, 0xaf, 0x8c, 0x92, 0x4c, 0xa0, 0xfc, 0x92, 0x49, + 0x24, 0x92, 0x49, 0x3d, 0xe9, 0x0c, 0x20, 0x22, 0xcf, 0x41, 0x0a, 0x6a, + 0x6b, 0xa5, 0x9c, 0x7d, 0x2c, 0xb0, 0x4e, 0x60, 0x08, 0xb2, 0xff, 0x00, + 0xb3, 0xd7, 0x01, 0x05, 0x2e, 0xaa, 0x82, 0xeb, 0x8d, 0x41, 0x34, 0x46, + 0x40, 0x62, 0x06, 0x2c, 0x7f, 0xd5, 0xac, 0x8e, 0x22, 0xf7, 0x4c, 0x92, + 0x49, 0x24, 0x92, 0x49, 0x2d, 0xd8, 0x4b, 0xb5, 0x39, 0x8f, 0xf3, 0xda, + 0x9a, 0x85, 0x13, 0x4d, 0x11, 0xaf, 0x65, 0xcb, 0xcd, 0xc1, 0xbd, 0x60, + 0x28, 0xe1, 0x1d, 0xa2, 0xda, 0xca, 0x87, 0x52, 0x15, 0x73, 0xae, 0xd7, + 0x85, 0x2a, 0xfd, 0xe7, 0x4c, 0x0e, 0x94, 0xeb, 0x4a, 0xa5, 0x3c, 0x92, + 0x49, 0x24, 0x92, 0x49, 0x9c, 0x93, 0x7e, 0x9d, 0x34, 0x6a, 0x56, 0xd1, + 0xc0, 0x43, 0x01, 0x75, 0xaa, 0x25, 0xe5, 0xbe, 0x59, 0x87, 0x0b, 0x36, + 0xba, 0x6b, 0xc2, 0x43, 0x22, 0x09, 0x63, 0xe0, 0x31, 0x43, 0x78, 0x81, + 0xd4, 0x5b, 0x4e, 0xe9, 0x51, 0x2e, 0x92, 0xe9, 0x70, 0x08, 0x44, 0x92, + 0x49, 0x24, 0x92, 0x49, 0xb5, 0xe1, 0xba, 0xf6, 0x0a, 0xd5, 0x93, 0xa2, + 0xfb, 0x4b, 0xcc, 0x15, 0xe8, 0x6a, 0x0f, 0xee, 0x0e, 0x48, 0x6c, 0xfc, + 0xdb, 0xd6, 0xc2, 0x58, 0x12, 0xc5, 0xbd, 0xf8, 0x63, 0x89, 0xea, 0x47, + 0xd3, 0x07, 0x90, 0x89, 0x95, 0x7f, 0x27, 0x78, 0xee, 0x04, 0x14, 0x92, + 0x49, 0x24, 0xd0, 0x48, 0xd2, 0x4c, 0x6e, 0xac, 0xb3, 0x25, 0x94, 0x90, + 0x40, 0xbd, 0xa2, 0xf6, 0xc6, 0x1c, 0x17, 0xa4, 0x88, 0xfe, 0x42, 0x43, + 0xf5, 0x0e, 0x06, 0x9e, 0x44, 0x50, 0xa4, 0x73, 0x23, 0xe6, 0x15, 0xc3, + 0x2d, 0xc6, 0x6f, 0x53, 0xa5, 0xc0, 0xbe, 0xb1, 0x27, 0x87, 0x24, 0x92, + 0x49, 0x21, 0x12, 0x13, 0x35, 0x54, 0xe2, 0x3e, 0x1f, 0x5e, 0x93, 0xcd, + 0x4f, 0x94, 0x5c, 0x3c, 0xaa, 0xe8, 0xcb, 0x1e, 0x65, 0x0b, 0x08, 0x54, + 0x4e, 0x7f, 0xb6, 0x55, 0xa2, 0x8b, 0xdb, 0xdf, 0x54, 0xb1, 0xb8, 0xf9, + 0x74, 0xd7, 0x01, 0xfa, 0x81, 0x51, 0xf2, 0x1d, 0xf2, 0xd8, 0xde, 0x12, + 0x49, 0x20, 0x5c, 0x9f, 0xf8, 0x1f, 0xf0, 0xa5, 0xd9, 0x3b, 0x70, 0x4d, + 0x89, 0x62, 0x1f, 0xdd, 0xa9, 0x72, 0xe3, 0xdd, 0x6e, 0x15, 0x82, 0xb9, + 0xf0, 0xe8, 0x45, 0x54, 0x27, 0xb1, 0xcd, 0x43, 0x17, 0xda, 0x73, 0x1d, + 0x76, 0xe4, 0x92, 0x87, 0xc4, 0x10, 0x3b, 0xfb, 0x2a, 0x4e, 0x6b, 0xb5, + 0x2e, 0xd7, 0xeb, 0x9f, 0x73, 0xa7, 0x00, 0x57, 0x8e, 0x7f, 0xc4, 0xa4, + 0xb3, 0xa5, 0xf4, 0xb8, 0x06, 0x58, 0xe0, 0x91, 0x40, 0x31, 0x6f, 0x6f, + 0x33, 0x7a, 0xc3, 0x6d, 0xd8, 0x26, 0xf5, 0xd3, 0x4b, 0xbc, 0x1c, 0x8f, + 0x8d, 0xad, 0xb6, 0x7e, 0x1d, 0x02, 0x16, 0xdf, 0x2c, 0xc0, 0x78, 0x58, + 0xef, 0x7f, 0x6c, 0x54, 0xe5, 0xf9, 0x7d, 0x00, 0xa2, 0x3d, 0x28, 0x07, + 0x6f, 0xbf, 0x87, 0x2e, 0xef, 0xf9, 0x59, 0xb1, 0xb6, 0xc3, 0xa2, 0xbe, + 0x3d, 0x0c, 0xb0, 0x1e, 0x1c, 0x0a, 0x2e, 0x01, 0x80, 0xcc, 0x53, 0x0e, + 0xae, 0xc4, 0x7a, 0x59, 0x6c, 0xb2, 0x01, 0x4b, 0xed, 0xfb, 0xd1, 0xa1, + 0x67, 0x6c, 0x3f, 0xc2, 0xf5, 0x43, 0xec, 0x9f, 0x50, 0x73, 0x8f, 0x90, + 0xb0, 0x14, 0x5f, 0x0f, 0x6d, 0xd3, 0x16, 0xec, 0xba, 0x64, 0xfe, 0x5d, + 0xc3, 0x36, 0xd2, 0x4b, 0xce, 0x20, 0x72, 0x57, 0x34, 0x4c, 0x8a, 0x29, + 0xa5, 0x53, 0x09, 0x5d, 0x8d, 0xb0, 0x06, 0x46, 0x71, 0x7c, 0x51, 0x79, + 0x73, 0xd7, 0xc0, 0x09, 0x75, 0x90, 0xed, 0x9e, 0x52, 0x3d, 0xb1, 0x0e, + 0x67, 0x63, 0xda, 0x7f, 0xbd, 0xd7, 0x68, 0xc7, 0x2c, 0xe1, 0x4a, 0x3c, + 0x83, 0x44, 0xef, 0x35, 0x75, 0x7a, 0xd8, 0x37, 0x34, 0x87, 0x23, 0xd6, + 0xd7, 0xad, 0xca, 0x1f, 0xef, 0x90, 0x0a, 0x22, 0xe7, 0x35, 0x67, 0x9a, + 0x91, 0x21, 0x49, 0x0f, 0x61, 0x20, 0x6a, 0xca, 0x08, 0xf3, 0xfe, 0xba, + 0x56, 0x4f, 0xae, 0xaa, 0x1b, 0x40, 0xfc, 0x87, 0xde, 0xf8, 0xad, 0x64, + 0x48, 0xa2, 0x88, 0x5b, 0xe6, 0x6e, 0x6c, 0x73, 0x5d, 0xa7, 0x04, 0xa2, + 0xbe, 0x66, 0xb7, 0x50, 0x86, 0x42, 0x0a, 0xb6, 0xc7, 0xdb, 0x32, 0x67, + 0xad, 0xfa, 0x09, 0x4c, 0xc0, 0x3c, 0x7f, 0xf0, 0x6b, 0x7c, 0xf8, 0xe3, + 0x0b, 0xab, 0x73, 0xdb, 0x69, 0x20, 0xb6, 0x3e, 0xd3, 0xe5, 0x2b, 0xce, + 0x15, 0xb2, 0x04, 0xc9, 0xca, 0x60, 0x63, 0xe5, 0x14, 0x8a, 0xc7, 0x70, + 0x72, 0x96, 0xb0, 0x98, 0x92, 0x58, 0x4f, 0xc6, 0x4d, 0x07, 0x38, 0x45, + 0x88, 0x21, 0xf2, 0x8a, 0x74, 0x2e, 0x7e, 0xfc, 0x6a, 0x36, 0xf9, 0x7a, + 0x8f, 0x0b, 0xee, 0x53, 0xf9, 0xf4, 0xc8, 0xf6, 0xda, 0x87, 0x28, 0xb0, + 0xea, 0x92, 0x33, 0x51, 0xe0, 0x26, 0x60, 0xb9, 0xac, 0xfe, 0x27, 0x10, + 0x13, 0xe3, 0x96, 0xcb, 0x04, 0xcb, 0x06, 0x14, 0xef, 0x9e, 0x06, 0x8a, + 0xcd, 0xdc, 0x60, 0x6b, 0x5a, 0x8b, 0xaf, 0xff, 0x00, 0x1b, 0x70, 0xd8, + 0xf4, 0xb6, 0xf1, 0x56, 0x23, 0x99, 0x67, 0x30, 0xc5, 0x06, 0x30, 0x05, + 0x03, 0x84, 0x93, 0xf1, 0x20, 0x26, 0x81, 0xe9, 0xb8, 0xf3, 0xf5, 0x69, + 0xa8, 0x2b, 0x33, 0xd9, 0xd1, 0x04, 0x49, 0x41, 0x78, 0x28, 0xe8, 0xb9, + 0xd1, 0xb5, 0x2b, 0x0f, 0x23, 0x4a, 0x8b, 0xf7, 0xf2, 0x4b, 0x20, 0xdb, + 0x40, 0xe3, 0x83, 0x54, 0x31, 0xb3, 0x8c, 0x93, 0x05, 0x3f, 0x94, 0x94, + 0x48, 0xda, 0x94, 0xd0, 0x60, 0x99, 0x4b, 0xa6, 0x94, 0xe4, 0xe8, 0xaa, + 0x88, 0x9d, 0x0c, 0x50, 0x00, 0x10, 0xcb, 0x0b, 0xd3, 0xfe, 0x57, 0x31, + 0x8a, 0x3e, 0x60, 0x96, 0x91, 0xde, 0xc1, 0xbc, 0xdb, 0x5d, 0x6a, 0xd9, + 0x66, 0xa8, 0xe6, 0x9c, 0xc0, 0x79, 0x7e, 0x9e, 0x09, 0x9c, 0xb7, 0xc1, + 0xdf, 0x5d, 0x93, 0x4b, 0xfe, 0xc6, 0xa1, 0x93, 0xc0, 0xa4, 0x7b, 0xe6, + 0x9f, 0xf1, 0x86, 0x52, 0x09, 0xb6, 0xdb, 0x09, 0xce, 0x09, 0x75, 0xad, + 0xc3, 0x7f, 0x72, 0xb6, 0xd7, 0xe8, 0x32, 0xbe, 0x44, 0x48, 0x33, 0xfd, + 0xb1, 0xb5, 0x16, 0x1e, 0xc9, 0xd5, 0xe9, 0xef, 0x55, 0x83, 0x61, 0x8c, + 0x44, 0xc9, 0xb5, 0xcb, 0x93, 0x7d, 0x66, 0x1a, 0x80, 0xf4, 0x0b, 0x54, + 0x2a, 0x7b, 0x73, 0x3f, 0xc9, 0xb6, 0xca, 0x4a, 0x21, 0x9b, 0x91, 0x9d, + 0x8a, 0xdf, 0xe7, 0xbe, 0xbe, 0x3f, 0x16, 0x4c, 0x9d, 0x2d, 0xfb, 0xdc, + 0x05, 0xc9, 0xee, 0xc5, 0xc9, 0x73, 0xc3, 0x2c, 0x77, 0x76, 0x3f, 0xcd, + 0xc9, 0xde, 0x91, 0xc8, 0x57, 0x62, 0x31, 0xc8, 0x02, 0x9d, 0xd4, 0xdc, + 0x68, 0x0b, 0xbb, 0xac, 0xc0, 0xb6, 0xc2, 0x04, 0x3e, 0xfe, 0xac, 0x13, + 0xc5, 0xb3, 0xf5, 0xbb, 0xf0, 0x17, 0x46, 0x8c, 0x03, 0x59, 0x8b, 0xdd, + 0x12, 0x3c, 0x10, 0x09, 0x08, 0x43, 0x04, 0xab, 0xee, 0x08, 0xa7, 0x1e, + 0xb5, 0xbb, 0xb2, 0xcb, 0xcf, 0x38, 0x60, 0x0c, 0x7e, 0x5b, 0x76, 0xff, + 0x00, 0x00, 0x5c, 0xf0, 0x9f, 0xa0, 0x96, 0xca, 0x4b, 0x15, 0x47, 0x67, + 0x23, 0x52, 0xae, 0xf4, 0x1b, 0xfb, 0x30, 0xcc, 0x93, 0x32, 0x5d, 0x5b, + 0x96, 0x3d, 0xdc, 0xe7, 0x38, 0x8b, 0x03, 0x3e, 0xf9, 0xc9, 0x0e, 0xc0, + 0xd3, 0x6f, 0xd9, 0x6a, 0xa0, 0x33, 0x2c, 0xd8, 0x76, 0xe9, 0x2a, 0x94, + 0x7d, 0xb1, 0x49, 0x14, 0xfa, 0x48, 0x34, 0x80, 0x4b, 0x54, 0x27, 0xcc, + 0x21, 0xe8, 0x8e, 0x5d, 0x89, 0xbf, 0x9b, 0xd1, 0x2b, 0xc7, 0xde, 0x3b, + 0xde, 0x31, 0x91, 0xf3, 0x20, 0xaf, 0x03, 0xb3, 0xb9, 0xc8, 0x9f, 0x03, + 0xf7, 0x75, 0x55, 0x66, 0x1b, 0x33, 0x67, 0x18, 0x5a, 0x02, 0xb3, 0x99, + 0xce, 0x67, 0xf3, 0x3b, 0xb2, 0x48, 0x00, 0x82, 0x6d, 0xbd, 0x10, 0x94, + 0x0d, 0xb1, 0x0e, 0x64, 0x2f, 0x94, 0xb9, 0x7a, 0x25, 0x94, 0x72, 0xc0, + 0x8e, 0x5d, 0x45, 0x79, 0xf1, 0xa6, 0x0e, 0x73, 0xe1, 0x6c, 0x60, 0x4f, + 0x4a, 0x3f, 0x8b, 0x79, 0x26, 0xfd, 0x5f, 0x86, 0xf9, 0xdd, 0x1f, 0xef, + 0x23, 0x28, 0x22, 0x98, 0xef, 0xf2, 0xc3, 0x9d, 0xe0, 0x3d, 0x8f, 0xbb, + 0xfd, 0x92, 0xd6, 0x74, 0x19, 0x40, 0x49, 0x94, 0x92, 0x40, 0x8d, 0x0f, + 0x78, 0x0f, 0xae, 0xcd, 0x28, 0x03, 0x22, 0xe5, 0xc4, 0x14, 0x70, 0xfc, + 0x56, 0x7a, 0x1a, 0x69, 0xef, 0xd5, 0xc9, 0x52, 0x8f, 0xa2, 0x47, 0x3e, + 0xe0, 0x17, 0x6c, 0xc7, 0xce, 0xa6, 0x25, 0x43, 0xac, 0x1f, 0x87, 0x44, + 0xda, 0x89, 0x0e, 0xa4, 0x0a, 0x73, 0x2d, 0x8a, 0xaf, 0xf8, 0xb4, 0x90, + 0xf2, 0xde, 0x94, 0xbd, 0xbf, 0x6e, 0x69, 0xa1, 0xfc, 0x91, 0x4d, 0x3c, + 0x04, 0x37, 0x64, 0x96, 0x06, 0x28, 0x1b, 0x23, 0x3f, 0x8a, 0x13, 0x50, + 0x07, 0x94, 0xa8, 0x78, 0xf2, 0x6d, 0x59, 0x23, 0xdb, 0x00, 0xb0, 0xf5, + 0x24, 0x78, 0xbd, 0x41, 0x9d, 0x6b, 0x6a, 0xeb, 0xbb, 0x0c, 0xf1, 0x91, + 0x4f, 0x8a, 0x26, 0xed, 0x1f, 0x1b, 0x7c, 0x4b, 0x53, 0xac, 0x12, 0x7b, + 0x0d, 0x4c, 0x50, 0x58, 0x61, 0x37, 0xbb, 0x72, 0xee, 0xf3, 0xf8, 0x0b, + 0x29, 0x9a, 0xa0, 0x96, 0x11, 0x12, 0xbf, 0xf0, 0xe6, 0xbe, 0xf0, 0xe8, + 0xd7, 0x64, 0x4e, 0x38, 0x34, 0x43, 0xcb, 0x1c, 0x63, 0xd0, 0x2f, 0x0f, + 0xd9, 0x92, 0x41, 0xb7, 0xaf, 0xb6, 0x4e, 0x7d, 0x70, 0x4f, 0xb2, 0x55, + 0xbc, 0xf5, 0xe3, 0x4e, 0x1a, 0xef, 0xba, 0xea, 0x3e, 0x04, 0x9c, 0x5e, + 0x60, 0x02, 0xbe, 0xb8, 0xf3, 0x19, 0x68, 0x6f, 0xfb, 0x63, 0x0f, 0x9f, + 0xff, 0x00, 0xd3, 0xf9, 0xfd, 0x61, 0x5a, 0xf4, 0x8d, 0xd4, 0xfd, 0xd2, + 0x3f, 0x9d, 0x6b, 0x50, 0x5e, 0x86, 0x82, 0x02, 0xa6, 0xe7, 0x8a, 0xda, + 0x09, 0x5f, 0x38, 0x9e, 0x05, 0x2f, 0x76, 0xac, 0x02, 0x9e, 0x56, 0x28, + 0x3d, 0x04, 0x83, 0xe8, 0xdd, 0xe0, 0xf6, 0x01, 0x15, 0x68, 0x18, 0x7a, + 0xba, 0x95, 0x43, 0xe8, 0xee, 0x51, 0xb0, 0x3d, 0x20, 0xd8, 0x55, 0x16, + 0x55, 0x1a, 0xc1, 0x37, 0xe5, 0x49, 0xf0, 0x06, 0xf5, 0xc9, 0xf1, 0xd1, + 0x97, 0x17, 0xf1, 0x87, 0xe6, 0x3c, 0x66, 0x15, 0x8f, 0xd2, 0x1d, 0x29, + 0x9a, 0xd7, 0xb2, 0x40, 0xa3, 0xc2, 0xb9, 0x34, 0xbe, 0xaa, 0x22, 0x62, + 0x5e, 0x32, 0x87, 0xac, 0x38, 0xf0, 0x62, 0x24, 0xc4, 0x1a, 0xd3, 0x35, + 0x65, 0xe6, 0x54, 0xe9, 0x39, 0xeb, 0xf9, 0x08, 0x73, 0x3f, 0xe5, 0x32, + 0x6a, 0x06, 0xca, 0xb9, 0x54, 0x29, 0xda, 0xad, 0x16, 0x03, 0x69, 0x69, + 0x3c, 0xee, 0x27, 0x6e, 0x91, 0xed, 0xb3, 0xc5, 0xad, 0x91, 0xa3, 0x62, + 0x84, 0x6c, 0xb4, 0x0f, 0xcc, 0x7f, 0x75, 0xe5, 0x2b, 0x9a, 0x3e, 0x6f, + 0xcc, 0xe8, 0x10, 0x92, 0x8f, 0x60, 0xc3, 0xc7, 0x68, 0x09, 0xb5, 0x75, + 0x5a, 0x45, 0x03, 0xf1, 0x47, 0xd3, 0xd3, 0x95, 0x5e, 0x4e, 0x3c, 0xdb, + 0x95, 0xce, 0x12, 0x16, 0xf4, 0xfa, 0x59, 0xe2, 0x27, 0xa5, 0x63, 0x1b, + 0xbf, 0x99, 0x54, 0x4e, 0xc0, 0x89, 0x14, 0x9f, 0xe6, 0xb7, 0xff, 0x00, + 0x62, 0x0f, 0x79, 0xfb, 0xc0, 0x24, 0x26, 0xf4, 0xdf, 0x96, 0x11, 0x9f, + 0x29, 0x52, 0x6c, 0x4f, 0x05, 0xbc, 0x1e, 0x59, 0xbc, 0x32, 0xcc, 0xe3, + 0xe8, 0xf8, 0x56, 0x82, 0x46, 0x33, 0x2d, 0x2a, 0x5b, 0x4d, 0xaf, 0x50, + 0x18, 0x83, 0xc1, 0xba, 0x66, 0xcb, 0x50, 0x6b, 0xb6, 0x8b, 0x64, 0x34, + 0x56, 0x40, 0x76, 0x6a, 0xc8, 0x0f, 0x3b, 0xcd, 0x95, 0x34, 0x92, 0x40, + 0xb8, 0x62, 0x4c, 0xb1, 0xe6, 0x4d, 0x6c, 0x66, 0x8d, 0xd0, 0x81, 0xd8, + 0x32, 0xc1, 0x42, 0xe3, 0xc4, 0x3d, 0xbb, 0xcb, 0xeb, 0xd1, 0x3d, 0x9a, + 0x03, 0x38, 0x95, 0x20, 0xa8, 0x2b, 0xf9, 0xb1, 0xf7, 0xad, 0xfa, 0x6a, + 0xa5, 0x30, 0x0d, 0x15, 0x49, 0x6b, 0xfe, 0x10, 0xb6, 0xd9, 0x63, 0xaa, + 0xf2, 0x7e, 0x0d, 0x04, 0x12, 0xc8, 0x88, 0x37, 0xeb, 0xb7, 0x31, 0xa5, + 0x92, 0x53, 0x41, 0x94, 0xbf, 0x60, 0x74, 0x8c, 0x62, 0x1d, 0xb3, 0xe2, + 0x5a, 0x3b, 0xc7, 0x2a, 0x20, 0xc8, 0xd1, 0x61, 0x1b, 0x5b, 0xda, 0x6a, + 0xe7, 0x6c, 0x0b, 0x3b, 0x65, 0x81, 0xd8, 0x93, 0xaa, 0xc9, 0x1e, 0x02, + 0xf0, 0x64, 0x2d, 0xec, 0x32, 0xb2, 0x76, 0xbb, 0xe8, 0xf3, 0x25, 0x89, + 0xa0, 0xe8, 0x76, 0xea, 0x85, 0x07, 0x08, 0x24, 0x89, 0x5e, 0x4b, 0x7f, + 0x72, 0xcc, 0x37, 0x16, 0xdb, 0x36, 0x0b, 0x6d, 0x5f, 0x5b, 0xba, 0x88, + 0x4d, 0x58, 0x45, 0x00, 0x95, 0xc3, 0x5e, 0xc2, 0xe2, 0x5b, 0x7f, 0xe7, + 0xf6, 0x66, 0x4d, 0xc0, 0xc7, 0x75, 0x50, 0xcf, 0x87, 0x5b, 0xc8, 0xe0, + 0x9e, 0x3c, 0xdb, 0xf7, 0xb3, 0xbb, 0x85, 0xb8, 0x6c, 0x50, 0x6c, 0x4a, + 0xcd, 0x94, 0xb9, 0x55, 0x1e, 0x26, 0xeb, 0x65, 0xbd, 0xf4, 0xb4, 0x67, + 0xfc, 0x43, 0x29, 0xaa, 0x44, 0xdf, 0xe6, 0x59, 0xf0, 0x89, 0x21, 0x37, + 0x66, 0x61, 0x2e, 0xc5, 0x1a, 0x76, 0x9e, 0x84, 0x92, 0x91, 0xe4, 0xd1, + 0x8b, 0xa2, 0x89, 0x96, 0x43, 0x74, 0xc2, 0xd6, 0x5c, 0x4e, 0x37, 0xc4, + 0x19, 0xf4, 0x94, 0x48, 0x7a, 0xe3, 0x69, 0xbe, 0xe1, 0x8a, 0x44, 0x84, + 0x19, 0x0c, 0xfa, 0xdc, 0x5b, 0x36, 0x36, 0x52, 0x88, 0xb7, 0x02, 0x33, + 0x12, 0x22, 0x66, 0xb3, 0x51, 0x40, 0x59, 0x65, 0x00, 0xdb, 0xc1, 0x6b, + 0x40, 0x40, 0xa9, 0xdb, 0x24, 0x08, 0x27, 0x8c, 0x2f, 0x65, 0xb5, 0x8a, + 0x59, 0xfe, 0x71, 0x8a, 0xab, 0x1f, 0x89, 0xa5, 0xad, 0x0f, 0x14, 0x40, + 0x94, 0x8e, 0xf2, 0x5a, 0x02, 0x16, 0x28, 0x07, 0x56, 0x0a, 0xb7, 0xd8, + 0x99, 0x1b, 0xa2, 0xe3, 0x17, 0x9e, 0x1e, 0x41, 0xe8, 0xd9, 0xe3, 0x1d, + 0x96, 0x50, 0x88, 0x11, 0x19, 0xdb, 0x0a, 0xe9, 0x94, 0x26, 0xfd, 0x42, + 0x6d, 0x93, 0xb5, 0xcc, 0x6b, 0x16, 0x00, 0x49, 0xb3, 0x24, 0x8b, 0xf9, + 0x35, 0xf1, 0x44, 0xd0, 0x43, 0x21, 0xec, 0x68, 0xce, 0x9b, 0xbe, 0xc0, + 0xd6, 0xd5, 0xb2, 0x16, 0x49, 0x1b, 0x8e, 0x4a, 0x68, 0x80, 0xe1, 0xd6, + 0x5a, 0xed, 0x05, 0x13, 0xb9, 0xbd, 0x30, 0xf6, 0x6c, 0xcc, 0x7f, 0x42, + 0xa5, 0x8a, 0xb2, 0xe0, 0xc0, 0x11, 0xa9, 0xfa, 0x5b, 0x59, 0x13, 0x0c, + 0xfc, 0x77, 0x28, 0xb6, 0x91, 0xc4, 0x48, 0x56, 0xe4, 0x5c, 0x80, 0x91, + 0x22, 0x4b, 0xb9, 0xd4, 0x8e, 0xb6, 0x9c, 0x61, 0x12, 0x60, 0xa1, 0x89, + 0x5a, 0xa3, 0x07, 0x4d, 0x79, 0xc3, 0x05, 0x08, 0x3e, 0x7a, 0x16, 0x00, + 0xc4, 0x27, 0x8e, 0x86, 0xe9, 0x36, 0xc8, 0x98, 0x20, 0x23, 0xb6, 0xfc, + 0xa6, 0xf6, 0xbe, 0xdd, 0xfa, 0x8d, 0xe1, 0x75, 0x94, 0x15, 0x44, 0x69, + 0x34, 0xc0, 0xfb, 0x4c, 0x96, 0xcb, 0x9b, 0x6a, 0x69, 0xe3, 0xf8, 0xfc, + 0x8e, 0x6b, 0x9a, 0xd8, 0x07, 0x13, 0x76, 0xda, 0x31, 0x43, 0xbb, 0x55, + 0xfc, 0x58, 0xb0, 0x3f, 0xb1, 0x75, 0x5c, 0x4c, 0xa4, 0xc3, 0xf7, 0xf0, + 0x4b, 0x35, 0xb5, 0x86, 0xc2, 0x72, 0x31, 0xf6, 0x36, 0x7d, 0x00, 0xb2, + 0xc6, 0x5c, 0x04, 0xd0, 0x90, 0x9a, 0x9e, 0x93, 0x2c, 0xdc, 0x56, 0xf1, + 0x21, 0xe1, 0x13, 0xf9, 0x37, 0x77, 0x7e, 0xce, 0x18, 0x54, 0xa4, 0x1c, + 0x67, 0xae, 0x7a, 0x81, 0x02, 0xe7, 0x49, 0x26, 0x30, 0x01, 0xda, 0xbf, + 0x36, 0x41, 0x44, 0xb8, 0xd2, 0xdc, 0x2c, 0xf9, 0x47, 0x11, 0xfd, 0x5a, + 0x8b, 0x87, 0xc5, 0x1a, 0x39, 0x26, 0x27, 0x0f, 0xc4, 0x5e, 0x12, 0x78, + 0x13, 0x55, 0x1f, 0xcf, 0x40, 0xf7, 0xe0, 0xaa, 0xb0, 0x10, 0x06, 0x5c, + 0x48, 0x23, 0xc4, 0xfd, 0x97, 0x03, 0xdf, 0x3e, 0xb0, 0x98, 0xa0, 0x03, + 0x3b, 0xbf, 0x58, 0xea, 0x7a, 0x87, 0xc4, 0x2c, 0x08, 0x37, 0xb6, 0xe4, + 0xd1, 0x87, 0xa4, 0xde, 0x23, 0x59, 0x0c, 0xc1, 0x0f, 0xdf, 0xcd, 0xac, + 0x81, 0x2a, 0x61, 0x3a, 0x74, 0xa9, 0xa1, 0xce, 0x5b, 0xd6, 0x8e, 0xa0, + 0x9b, 0xf8, 0xbb, 0xd0, 0x28, 0x89, 0x5d, 0xf5, 0xfb, 0x65, 0xe1, 0xff, + 0x00, 0x3a, 0x50, 0x84, 0xc7, 0x6e, 0xdf, 0x8d, 0x7e, 0x10, 0xe5, 0x0d, + 0xe8, 0xb5, 0x89, 0x3a, 0x02, 0xf4, 0x73, 0xae, 0xd0, 0xa2, 0x39, 0x89, + 0x4c, 0xde, 0x17, 0x53, 0x38, 0x6f, 0x2f, 0x00, 0xd4, 0x94, 0xf7, 0x38, + 0x8a, 0xf4, 0xd5, 0xd9, 0x8b, 0x6c, 0xa1, 0xfe, 0xbe, 0x8d, 0xb1, 0xca, + 0x77, 0x1e, 0x9a, 0x46, 0xa0, 0xc5, 0x85, 0xfe, 0x9d, 0x55, 0x2e, 0x73, + 0xfb, 0xc7, 0x93, 0x66, 0x6e, 0x37, 0x6d, 0xee, 0x8c, 0x34, 0x1c, 0x64, + 0x82, 0x46, 0x44, 0x7c, 0x3b, 0x55, 0x54, 0x21, 0xcf, 0x56, 0x16, 0x32, + 0xcc, 0xb3, 0xd4, 0x4d, 0x9d, 0xf6, 0xeb, 0xeb, 0x67, 0xd5, 0x7d, 0xa2, + 0xc2, 0x5d, 0x1d, 0xad, 0xdf, 0x1d, 0x7b, 0x2a, 0x99, 0xb1, 0x01, 0xdf, + 0x86, 0x36, 0x01, 0x02, 0xab, 0x0b, 0xa4, 0x0a, 0x77, 0xa4, 0xc9, 0x2e, + 0x98, 0x7b, 0x2d, 0x17, 0x45, 0x54, 0x35, 0x36, 0x15, 0x81, 0x08, 0xc0, + 0x16, 0x4e, 0x0f, 0x58, 0x14, 0xd7, 0x5f, 0x35, 0xa4, 0x14, 0x40, 0xc1, + 0x34, 0x47, 0x4d, 0xdf, 0xaf, 0x8e, 0x0d, 0xef, 0x77, 0xea, 0x06, 0xd6, + 0xb6, 0x4b, 0x65, 0x96, 0x69, 0x24, 0x94, 0x92, 0x60, 0x96, 0x4b, 0xe1, + 0x11, 0xa1, 0xba, 0xde, 0x05, 0xfe, 0x72, 0xd9, 0x8f, 0x76, 0x59, 0xac, + 0x9f, 0xbd, 0x92, 0xf9, 0xbe, 0xf6, 0xfd, 0xff, 0xc4, 0x00, 0x2a, 0x11, + 0x00, 0x03, 0x00, 0x01, 0x03, 0x03, 0x03, 0x03, 0x05, 0x01, 0x01, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x11, 0x10, 0x20, 0x21, 0x31, 0x41, + 0x51, 0x61, 0x30, 0x71, 0x91, 0x40, 0x81, 0xa1, 0xb1, 0xc1, 0xd1, 0xe1, + 0xf0, 0xf1, 0x50, 0xff, 0xda, 0x00, 0x08, 0x01, 0x03, 0x01, 0x01, 0x3f, + 0x10, 0x78, 0x84, 0x36, 0x26, 0x36, 0xfa, 0x4d, 0x8d, 0xb4, 0xec, 0x54, + 0x5c, 0x54, 0x52, 0x94, 0xa8, 0xa8, 0xb8, 0x52, 0x94, 0xa5, 0x2a, 0x20, + 0x82, 0x97, 0x08, 0x20, 0x82, 0xa2, 0xa2, 0x04, 0xd3, 0x15, 0xd4, 0xcf, + 0x3a, 0x17, 0x79, 0x60, 0x17, 0x51, 0x84, 0xae, 0x68, 0x91, 0xd0, 0x40, + 0x80, 0xf0, 0xcf, 0x17, 0xe0, 0xf0, 0xcf, 0x0f, 0xe0, 0xf1, 0x3e, 0x0f, + 0x13, 0xe0, 0xf1, 0xbe, 0x0f, 0x0b, 0xe0, 0xf0, 0xbe, 0x0f, 0x0b, 0xe0, + 0xf0, 0x0f, 0x00, 0xf1, 0x0f, 0x08, 0xf1, 0x8f, 0x12, 0xf8, 0x3c, 0x68, + 0xf1, 0x0f, 0x18, 0xf1, 0x0f, 0x12, 0x3c, 0x4b, 0xe0, 0xf1, 0x2f, 0x83, + 0xc4, 0xbe, 0x11, 0xe3, 0x47, 0x8d, 0x7c, 0x1e, 0x35, 0xf0, 0x78, 0xd7, + 0xc1, 0xe1, 0x5f, 0x07, 0x8d, 0x7c, 0x1e, 0x27, 0xc1, 0xfe, 0x08, 0xf0, + 0x0f, 0x00, 0xf0, 0xbe, 0x0f, 0x13, 0xe0, 0xf1, 0x3e, 0x0f, 0x03, 0xe0, + 0xf1, 0x3e, 0x0f, 0x03, 0xe0, 0xf1, 0xbe, 0x0f, 0x0b, 0xe1, 0x1e, 0x27, + 0xc2, 0x3c, 0x4f, 0x83, 0xc5, 0xf8, 0x3c, 0x0f, 0x84, 0x78, 0x9f, 0x07, + 0x8e, 0x36, 0xf4, 0x14, 0x0f, 0xb0, 0x3e, 0xd8, 0xdf, 0xc6, 0xc7, 0x70, + 0x74, 0x61, 0xb7, 0x23, 0xa0, 0x13, 0xb0, 0x82, 0x31, 0xb1, 0x3c, 0x14, + 0x51, 0x34, 0x6f, 0x9b, 0x8b, 0x8a, 0x52, 0x97, 0x14, 0xba, 0xa9, 0x4a, + 0x52, 0x94, 0xac, 0xf7, 0xcd, 0x29, 0x74, 0x3f, 0x1a, 0xe0, 0x89, 0x99, + 0x84, 0x84, 0x8b, 0x22, 0x6d, 0x85, 0x56, 0xcf, 0x34, 0x42, 0x61, 0x18, + 0x88, 0x42, 0x10, 0x8c, 0x8f, 0x42, 0x29, 0x4a, 0x73, 0xaf, 0xee, 0x5c, + 0x5c, 0x55, 0xaf, 0x72, 0x8f, 0xce, 0x62, 0xd1, 0x45, 0x95, 0x9b, 0x84, + 0x9b, 0x29, 0x09, 0x9f, 0x41, 0xb3, 0x52, 0x0d, 0xa3, 0x2d, 0x5f, 0x29, + 0x07, 0xbe, 0x9a, 0x5c, 0xc2, 0x22, 0x2e, 0xc4, 0x44, 0x10, 0x49, 0x18, + 0x59, 0x44, 0xd3, 0xce, 0x9b, 0xab, 0x7c, 0xef, 0xa6, 0x7a, 0x70, 0x84, + 0xd0, 0x85, 0x92, 0x68, 0x96, 0xc5, 0xc7, 0x8c, 0x55, 0x8d, 0x8f, 0x63, + 0x62, 0x62, 0x1b, 0x6a, 0xb8, 0x4c, 0xb8, 0xa5, 0x2e, 0x2e, 0x3d, 0x8a, + 0xf1, 0x58, 0x9f, 0xa3, 0x71, 0x71, 0x2f, 0x02, 0xe2, 0x04, 0xc0, 0x9b, + 0xcc, 0x42, 0xea, 0x31, 0x27, 0x50, 0xba, 0xcd, 0x89, 0x22, 0x07, 0x60, + 0x36, 0xf6, 0x41, 0x2f, 0xa0, 0xf0, 0x10, 0x44, 0x31, 0xaa, 0x3d, 0xd6, + 0xe2, 0xe7, 0xec, 0xc7, 0xf4, 0x8d, 0x19, 0x03, 0x74, 0x34, 0xd6, 0x6e, + 0x6e, 0x2e, 0x85, 0xa6, 0x7a, 0x53, 0x5c, 0x7d, 0x8f, 0x00, 0x99, 0xd3, + 0x21, 0xd7, 0xff, 0x00, 0x47, 0xfa, 0x3f, 0xeb, 0x40, 0xc1, 0x12, 0xc2, + 0xee, 0xfc, 0x84, 0xa3, 0xbe, 0x98, 0x99, 0xdc, 0xf2, 0x89, 0xe1, 0x37, + 0x86, 0x45, 0xc2, 0x97, 0x32, 0xbd, 0x11, 0xfa, 0x73, 0x1c, 0x62, 0xf6, + 0xd0, 0x93, 0x6e, 0x23, 0x9f, 0x50, 0x47, 0x51, 0xd3, 0x85, 0xc0, 0x5a, + 0x5e, 0x9b, 0x89, 0xa2, 0x14, 0x43, 0x0e, 0xa3, 0xd9, 0xc8, 0xbe, 0x81, + 0xea, 0xa6, 0xdd, 0x46, 0xbd, 0x0e, 0x83, 0x29, 0x4a, 0x52, 0x94, 0xb8, + 0x52, 0x94, 0xa5, 0x29, 0x4b, 0x8a, 0x5c, 0x5d, 0x29, 0xdf, 0x08, 0x4d, + 0x8c, 0x04, 0x51, 0x63, 0x63, 0x91, 0x6e, 0x31, 0xb2, 0xe2, 0xe6, 0x96, + 0x13, 0xb1, 0x71, 0x31, 0x7b, 0x89, 0x97, 0x0c, 0x41, 0x6c, 0xc2, 0x47, + 0x91, 0xbd, 0x51, 0xca, 0x6c, 0x70, 0x0c, 0x4f, 0x09, 0xdc, 0x71, 0x8b, + 0x9b, 0x4a, 0xcf, 0x7f, 0x46, 0x0f, 0x22, 0x0a, 0xe5, 0x85, 0xd1, 0x34, + 0xef, 0xea, 0x52, 0xe2, 0xe5, 0x13, 0xfa, 0x2b, 0xae, 0xe2, 0x94, 0xa5, + 0x29, 0x4a, 0x35, 0xd4, 0x23, 0x4e, 0x1b, 0x89, 0xfc, 0x21, 0x3b, 0x81, + 0xe3, 0x23, 0xd0, 0x6a, 0xe5, 0x1e, 0x71, 0xe7, 0x1e, 0x16, 0x34, 0x74, + 0x23, 0x37, 0xc5, 0x29, 0x4a, 0x52, 0x94, 0x4c, 0xe8, 0x27, 0x12, 0x2e, + 0x44, 0x8b, 0x82, 0x69, 0xb7, 0x2c, 0x4c, 0xba, 0x28, 0xf7, 0x29, 0xbb, + 0x25, 0x2c, 0x29, 0x44, 0x58, 0x72, 0x42, 0xc4, 0x5c, 0xde, 0xa8, 0xea, + 0x22, 0x9f, 0x13, 0x71, 0x0b, 0x3b, 0xea, 0xb8, 0xe7, 0x44, 0x20, 0xed, + 0xef, 0x81, 0x6c, 0x41, 0x7a, 0x34, 0xf2, 0x31, 0x66, 0x94, 0xa8, 0xba, + 0x2c, 0x28, 0xbb, 0x7b, 0x9a, 0x2f, 0xa3, 0x71, 0x4b, 0x8b, 0xa1, 0x33, + 0xe0, 0xbe, 0xa4, 0x77, 0x17, 0x68, 0x4f, 0xb0, 0x27, 0x5c, 0x1e, 0x43, + 0xc8, 0x79, 0x8a, 0xee, 0x76, 0x99, 0xe5, 0x3c, 0xa7, 0x97, 0x15, 0x92, + 0xf9, 0x43, 0x77, 0x2a, 0x36, 0x72, 0x1b, 0x3a, 0xb4, 0x23, 0xa8, 0x60, + 0x9b, 0xab, 0x12, 0xb9, 0x12, 0x38, 0x58, 0xe7, 0x34, 0xdb, 0xa6, 0x2e, + 0x89, 0xab, 0x7e, 0x98, 0xde, 0x17, 0x1c, 0x14, 0xa5, 0xc7, 0x25, 0xd1, + 0xc6, 0x96, 0x6e, 0x46, 0xd1, 0xbc, 0x41, 0x5b, 0x4c, 0xc7, 0x1a, 0x2e, + 0x21, 0xc8, 0x9d, 0xc3, 0x11, 0xd9, 0x09, 0x25, 0xc6, 0x6e, 0xae, 0x34, + 0x72, 0x22, 0x94, 0xa5, 0x29, 0x4a, 0x52, 0x92, 0x49, 0x41, 0xe4, 0x7e, + 0x9d, 0xcd, 0xca, 0x4d, 0xf0, 0x26, 0x6a, 0xb1, 0x29, 0x27, 0x18, 0x9d, + 0xf4, 0x23, 0x6d, 0x5b, 0x7a, 0x54, 0xa3, 0xd0, 0xd8, 0xb3, 0xb9, 0xc1, + 0x30, 0xbb, 0x63, 0x9d, 0x16, 0x0f, 0xd1, 0xa7, 0x41, 0x3f, 0x46, 0x8d, + 0x6b, 0x09, 0x28, 0xd0, 0xfa, 0x48, 0x3e, 0x82, 0x47, 0x94, 0xf2, 0x7e, + 0x83, 0xef, 0x9f, 0xe9, 0x07, 0xff, 0x00, 0x12, 0x3b, 0xaf, 0xf1, 0x89, + 0x5b, 0x74, 0x8e, 0x59, 0xb0, 0xd9, 0x15, 0xd0, 0x5f, 0x57, 0x50, 0xe6, + 0xa8, 0x9b, 0x29, 0x4b, 0x8a, 0x5c, 0xdc, 0x37, 0x91, 0xa6, 0xa2, 0x48, + 0xd1, 0x12, 0x79, 0xff, 0x00, 0x2c, 0xf2, 0x7e, 0x58, 0xb6, 0x39, 0xaf, + 0x72, 0x22, 0x3b, 0x12, 0x35, 0x20, 0x72, 0x42, 0x96, 0x8b, 0x9e, 0x44, + 0xcc, 0x4a, 0xbd, 0x1d, 0xf1, 0x3d, 0x09, 0xab, 0x63, 0xd8, 0xf7, 0xc7, + 0x07, 0x3a, 0x79, 0xd1, 0x71, 0x51, 0xd4, 0x90, 0xea, 0x72, 0x4c, 0xa3, + 0x86, 0x3c, 0x3c, 0xf2, 0x7b, 0xe8, 0x5e, 0xb6, 0xd8, 0x6f, 0x43, 0xd9, + 0x4c, 0x59, 0xc1, 0xd5, 0x1a, 0x66, 0xd5, 0xb9, 0x79, 0x5f, 0xe6, 0x2d, + 0xc4, 0xfd, 0xb6, 0x39, 0x96, 0xfd, 0xcb, 0xf8, 0x10, 0xd5, 0x7b, 0x19, + 0xc7, 0x3a, 0x28, 0xd8, 0xd8, 0xd8, 0xc3, 0x0d, 0x4e, 0x39, 0x3a, 0x81, + 0xfd, 0xbf, 0x91, 0xff, 0x00, 0xda, 0x70, 0x89, 0x21, 0xbb, 0xfa, 0x2f, + 0xe0, 0x6e, 0xfe, 0xab, 0xf8, 0x1b, 0x7a, 0xc7, 0xca, 0x7f, 0x93, 0xcf, + 0xf9, 0x7e, 0x93, 0x57, 0xc0, 0xea, 0x3c, 0x88, 0x98, 0xfc, 0xc6, 0xcb, + 0x15, 0xe4, 0x49, 0x2e, 0x33, 0x3e, 0x87, 0x9d, 0x14, 0x5e, 0x92, 0x3a, + 0x0d, 0x97, 0x09, 0x5c, 0x89, 0x11, 0x04, 0x13, 0x91, 0xb6, 0x10, 0xd6, + 0x21, 0x33, 0x34, 0x6d, 0x8b, 0xa3, 0x93, 0x8d, 0x89, 0xea, 0xec, 0x4c, + 0xea, 0xde, 0xa6, 0x35, 0x4e, 0x1b, 0x7e, 0xc7, 0x9d, 0xff, 0x00, 0xb2, + 0x12, 0xb3, 0xba, 0xdd, 0x7f, 0x24, 0xa2, 0x4f, 0x05, 0x1b, 0x18, 0x63, + 0xb9, 0x1f, 0x22, 0x7b, 0xbe, 0xe7, 0x4b, 0x2f, 0xb7, 0xf2, 0x3e, 0xac, + 0x7f, 0x48, 0xd5, 0x1a, 0x98, 0x42, 0x27, 0xd0, 0x75, 0xf5, 0xd6, 0x66, + 0x3c, 0x0b, 0x12, 0x88, 0x25, 0xea, 0x26, 0x79, 0x2e, 0x51, 0xce, 0x8e, + 0x34, 0x2c, 0xed, 0xae, 0x0b, 0x4f, 0x08, 0x2d, 0x4c, 0x45, 0x28, 0x22, + 0x7e, 0x0e, 0xa9, 0x79, 0x5c, 0xfc, 0x1b, 0x80, 0xfe, 0xa6, 0xdd, 0x2f, + 0x73, 0x98, 0x9f, 0xd4, 0xb5, 0x50, 0xf9, 0x82, 0x11, 0x71, 0xc6, 0xb7, + 0xf4, 0xd2, 0xe3, 0x92, 0x13, 0x2a, 0x84, 0xbd, 0x66, 0x35, 0x95, 0x8e, + 0x07, 0x95, 0x98, 0x72, 0x71, 0xaa, 0x97, 0x7f, 0x4b, 0x67, 0xa4, 0xa5, + 0xee, 0x2f, 0xac, 0xda, 0xc4, 0xf0, 0xb5, 0x4f, 0xa3, 0xf1, 0x98, 0x4c, + 0xbc, 0x53, 0xa6, 0x10, 0xb8, 0xf5, 0xdb, 0x29, 0x71, 0xc9, 0xd7, 0xd3, + 0xdb, 0x1c, 0x17, 0x13, 0x47, 0x18, 0x5a, 0x7b, 0x7d, 0x16, 0xf2, 0xc2, + 0xfa, 0x8a, 0x8a, 0x8e, 0xc0, 0xdd, 0x16, 0x39, 0x10, 0x85, 0xf4, 0x1c, + 0xeb, 0xe7, 0x53, 0x39, 0xcd, 0xc5, 0x28, 0x9f, 0x62, 0x9c, 0xe2, 0xa5, + 0x9a, 0xb1, 0x4e, 0xee, 0x36, 0x31, 0x4f, 0x4f, 0x39, 0x73, 0x47, 0x1e, + 0xb6, 0xfa, 0x66, 0x37, 0x3d, 0x0f, 0x43, 0x1b, 0xb9, 0x4e, 0x14, 0x50, + 0x84, 0x61, 0xcf, 0xd0, 0x3c, 0x1b, 0x86, 0xcc, 0xa3, 0x71, 0x88, 0x42, + 0xc2, 0xfa, 0x1e, 0x7d, 0x19, 0x87, 0xad, 0x6b, 0x64, 0x21, 0x08, 0x27, + 0x8d, 0x88, 0x4f, 0x5d, 0xad, 0x5b, 0x7a, 0x4b, 0x91, 0xee, 0xf5, 0xb1, + 0x8c, 0xa5, 0xcd, 0x1b, 0xc2, 0x17, 0xd0, 0x9e, 0x68, 0xb0, 0x85, 0xa9, + 0x13, 0x47, 0x22, 0xfa, 0xb8, 0x75, 0x16, 0x21, 0x08, 0x20, 0x90, 0xd1, + 0x09, 0x48, 0xf3, 0xed, 0xa2, 0x2d, 0x0b, 0x0b, 0x0b, 0x33, 0x44, 0x26, + 0x66, 0xb8, 0x2e, 0x7d, 0x17, 0xb6, 0x78, 0x29, 0x72, 0xbe, 0x8a, 0xfa, + 0x66, 0x50, 0xbd, 0x79, 0x8d, 0x88, 0x42, 0x61, 0x08, 0x42, 0x13, 0xd0, + 0x84, 0x20, 0xb3, 0x35, 0x21, 0xac, 0xbd, 0x17, 0x4e, 0xe5, 0xca, 0xee, + 0x5d, 0x10, 0x94, 0xa2, 0xdf, 0x4c, 0x85, 0xc2, 0xd9, 0x45, 0x97, 0xd8, + 0xa2, 0x4d, 0x08, 0xeb, 0xa9, 0xe1, 0x8f, 0x6c, 0x32, 0x6a, 0x4f, 0x5d, + 0xfc, 0x21, 0xf7, 0x18, 0x91, 0x31, 0x32, 0x85, 0x85, 0xe9, 0xb5, 0x39, + 0x36, 0x2b, 0x21, 0xbd, 0x85, 0x38, 0x15, 0x7a, 0x1e, 0x23, 0xd8, 0x57, + 0x6c, 0x1b, 0xf9, 0x47, 0x71, 0x1e, 0xc2, 0xbd, 0x4a, 0x75, 0x1b, 0x74, + 0x63, 0x17, 0x41, 0xac, 0x4d, 0x14, 0xb8, 0xa5, 0xca, 0xd0, 0x95, 0x1b, + 0x24, 0x34, 0x35, 0x8a, 0x4c, 0x4d, 0x33, 0x2b, 0xc9, 0xcc, 0x4f, 0xd8, + 0xe0, 0x9b, 0xe0, 0xf3, 0x0d, 0xf1, 0xeb, 0xec, 0x29, 0xd8, 0xd9, 0xd3, + 0x35, 0xe4, 0x2b, 0xd1, 0x5f, 0x46, 0x79, 0x0a, 0x47, 0xb0, 0xad, 0xd0, + 0xe5, 0x24, 0x31, 0xa2, 0x37, 0x76, 0x35, 0x6f, 0x06, 0x9a, 0x2e, 0xa7, + 0x8d, 0xf8, 0x19, 0xe5, 0xa4, 0x26, 0x5f, 0xd0, 0xe3, 0x07, 0x0c, 0xd0, + 0x87, 0xb7, 0xaf, 0xb5, 0x94, 0xdc, 0x4b, 0x30, 0x98, 0x48, 0x5e, 0x82, + 0x57, 0x81, 0x3f, 0xa1, 0xb3, 0x94, 0x20, 0x11, 0x17, 0x71, 0x0a, 0x7b, + 0x8e, 0x67, 0xa7, 0x09, 0x06, 0x88, 0xdc, 0xe4, 0x48, 0x21, 0x8f, 0xb5, + 0x88, 0xd7, 0x38, 0xa5, 0xc7, 0x03, 0xb8, 0xe7, 0xec, 0x32, 0x9b, 0x3d, + 0xf6, 0x12, 0x38, 0xd7, 0xe4, 0x49, 0xe5, 0xdf, 0xb2, 0x12, 0x71, 0x33, + 0x7e, 0x5c, 0x1d, 0x22, 0x45, 0xee, 0xc8, 0x70, 0xbe, 0x03, 0x9e, 0x11, + 0x7b, 0x22, 0x06, 0xff, 0x00, 0x81, 0x87, 0x27, 0xf8, 0x21, 0x5f, 0x29, + 0xbe, 0xc3, 0x79, 0x4f, 0xc0, 0xce, 0xe4, 0xfe, 0xe3, 0xe4, 0x20, 0x7b, + 0x76, 0x7d, 0xd0, 0xdf, 0xc6, 0xfe, 0xe7, 0x3a, 0xff, 0x00, 0x6d, 0xff, + 0x00, 0x41, 0xb2, 0x7b, 0xe2, 0x61, 0x2b, 0xb2, 0x25, 0x6c, 0x3f, 0x22, + 0x0d, 0xad, 0xf7, 0x7b, 0x89, 0x12, 0x8b, 0x0c, 0x69, 0x35, 0x18, 0xfb, + 0x95, 0xf8, 0x24, 0x6f, 0x42, 0x94, 0xe4, 0xa2, 0x62, 0x92, 0x97, 0x70, + 0xe5, 0xd9, 0xb4, 0x49, 0x8d, 0x6c, 0x5c, 0x03, 0xb5, 0x06, 0xfd, 0x54, + 0xe4, 0xd0, 0xf0, 0xf4, 0x96, 0xe7, 0x2b, 0x21, 0x07, 0x82, 0xde, 0x44, + 0xa5, 0x85, 0x1c, 0xfd, 0x29, 0x0b, 0xab, 0x3c, 0xd4, 0xfd, 0x8d, 0x95, + 0x21, 0xc8, 0x42, 0xd5, 0x09, 0x89, 0xf2, 0xd0, 0xb8, 0x4f, 0x09, 0x37, + 0xc1, 0x4b, 0x94, 0x12, 0x5f, 0x22, 0x4f, 0xa4, 0x11, 0xf9, 0x64, 0x2d, + 0xd9, 0x45, 0xb2, 0x10, 0x9c, 0x25, 0x34, 0x8a, 0x69, 0x43, 0x62, 0x59, + 0x7a, 0x61, 0x31, 0x44, 0x6c, 0x47, 0x56, 0x2b, 0xcf, 0x31, 0xb8, 0xb5, + 0xa8, 0xdc, 0x6a, 0xfa, 0x0d, 0x97, 0x02, 0xbb, 0x22, 0xf3, 0xb0, 0xaf, + 0x5f, 0xc2, 0x5f, 0xb9, 0xc1, 0xdf, 0x7d, 0xc4, 0x32, 0x1e, 0xca, 0x08, + 0x6e, 0xcb, 0xee, 0xce, 0xca, 0x48, 0x6d, 0xe4, 0x37, 0x5d, 0x22, 0xeb, + 0x85, 0x4b, 0xa1, 0x54, 0xdc, 0xa9, 0x95, 0x10, 0xc4, 0x66, 0x68, 0xae, + 0xd0, 0xf7, 0x5b, 0x0a, 0xae, 0xa5, 0x7b, 0x9c, 0x2b, 0x68, 0xae, 0xca, + 0x9f, 0xba, 0x3b, 0x07, 0xd8, 0xe8, 0xaf, 0xbe, 0xc3, 0x19, 0x54, 0x52, + 0x9d, 0xd0, 0xb3, 0x46, 0xcb, 0x85, 0x31, 0xb9, 0x5e, 0xa5, 0x13, 0xb6, + 0x3c, 0x96, 0xd8, 0x5c, 0x26, 0xd7, 0x1b, 0x1d, 0x5a, 0x8c, 0x6f, 0x61, + 0x7b, 0x94, 0xdc, 0x21, 0x30, 0xc7, 0x91, 0x30, 0x85, 0xdb, 0xd1, 0x6b, + 0xcd, 0x04, 0xa0, 0xb9, 0x1a, 0xf6, 0x1d, 0xee, 0xef, 0x74, 0x98, 0xfb, + 0x1f, 0xd3, 0xf4, 0x2f, 0x41, 0xaf, 0xbf, 0xf2, 0x53, 0x88, 0xf7, 0x5f, + 0xc5, 0x2d, 0xd0, 0xfd, 0x98, 0xf6, 0x8d, 0x09, 0x67, 0x61, 0x72, 0x6f, + 0xcc, 0x2c, 0x70, 0xcc, 0xec, 0x0f, 0x63, 0xb2, 0x85, 0xe2, 0x5f, 0x44, + 0x39, 0x29, 0x28, 0x93, 0x6e, 0x06, 0x72, 0x5e, 0xc7, 0x49, 0xce, 0x49, + 0x66, 0xfa, 0x2d, 0xbb, 0x57, 0x36, 0x39, 0x20, 0x90, 0x92, 0xa2, 0x94, + 0xfb, 0xa4, 0x25, 0xac, 0x25, 0x63, 0x11, 0xb4, 0x63, 0xa2, 0x6d, 0xb8, + 0x35, 0xb8, 0xd0, 0xb9, 0x39, 0x1a, 0x42, 0x54, 0x69, 0x0d, 0x2e, 0x83, + 0x7c, 0x08, 0xf6, 0x54, 0x7d, 0xcd, 0xc5, 0x4a, 0xf1, 0xc0, 0xb7, 0x63, + 0xf3, 0x96, 0x2e, 0x21, 0x31, 0x04, 0xa9, 0xf5, 0x20, 0xfb, 0xd0, 0xc7, + 0xa2, 0x94, 0x4d, 0x75, 0x1a, 0xc8, 0x1a, 0xa6, 0xe3, 0x7d, 0xbd, 0x00, + 0x5c, 0x75, 0x17, 0x32, 0xbd, 0xcf, 0xf8, 0xdc, 0x48, 0x4a, 0x7e, 0xcb, + 0xf7, 0x6d, 0x7e, 0x83, 0xea, 0x1f, 0x77, 0xfc, 0x4f, 0xd4, 0xe5, 0x52, + 0xff, 0x00, 0x7d, 0xfd, 0x04, 0x6f, 0xa8, 0xf7, 0xd9, 0x9b, 0x37, 0x8f, + 0x81, 0xee, 0x26, 0x5f, 0xf5, 0x91, 0x38, 0xfd, 0xc6, 0xde, 0x4f, 0xb8, + 0x49, 0xae, 0xa2, 0x61, 0x35, 0xb3, 0x37, 0x70, 0x4f, 0xfd, 0xe0, 0x8d, + 0xd2, 0x0d, 0x81, 0x02, 0xf7, 0x10, 0x85, 0x8d, 0x8b, 0xa1, 0xd9, 0x8c, + 0xf7, 0x09, 0x12, 0x0e, 0x89, 0xa6, 0x4c, 0x8f, 0x5b, 0x5e, 0xe2, 0xd1, + 0xb9, 0xe8, 0x58, 0xe6, 0x20, 0xb0, 0xc6, 0x12, 0x6f, 0x48, 0xc6, 0xad, + 0x93, 0xee, 0x84, 0x54, 0x62, 0x9d, 0x0e, 0xfb, 0x48, 0x6a, 0xe5, 0x08, + 0x8e, 0x36, 0xcd, 0xbd, 0xd8, 0xfb, 0x81, 0x7f, 0xde, 0x2b, 0x7f, 0x73, + 0xfd, 0xd9, 0x5e, 0x43, 0x2e, 0xcd, 0x31, 0xb7, 0xdb, 0x72, 0xfc, 0x08, + 0x7c, 0x20, 0xd0, 0xb4, 0x49, 0x14, 0x25, 0x5e, 0x7f, 0x29, 0x7e, 0xba, + 0xd1, 0x6f, 0x6c, 0x86, 0xc5, 0x45, 0x43, 0x7e, 0x87, 0x26, 0x8b, 0x4f, + 0x61, 0xb3, 0xa0, 0xb8, 0xd5, 0x58, 0xfb, 0xf2, 0xc7, 0xa0, 0x3a, 0xe3, + 0x6c, 0x26, 0xb9, 0x48, 0x70, 0x57, 0xc0, 0xef, 0x04, 0x7d, 0x49, 0xa4, + 0x21, 0x46, 0xca, 0x52, 0xe2, 0xfa, 0x0e, 0xc1, 0x08, 0x58, 0x6d, 0xba, + 0x25, 0x02, 0x66, 0xb8, 0xfc, 0xc1, 0xa7, 0x56, 0xbf, 0x2c, 0x4f, 0x0f, + 0xc0, 0x61, 0x38, 0xef, 0xd8, 0x7d, 0x90, 0xde, 0xfa, 0xe9, 0x72, 0xde, + 0xc3, 0xd5, 0xc9, 0x8c, 0x58, 0x63, 0x4c, 0x4c, 0xc9, 0x5c, 0x93, 0x71, + 0xe0, 0xd0, 0xe9, 0xc4, 0x64, 0x83, 0x44, 0xd8, 0x8a, 0x6c, 0x42, 0x21, + 0x0d, 0xc1, 0x6b, 0xac, 0x68, 0x87, 0x02, 0x11, 0x1c, 0xd8, 0x91, 0x09, + 0x61, 0xa3, 0xfc, 0xaf, 0xd7, 0x4b, 0xca, 0xdf, 0x6d, 0xfe, 0x83, 0xd0, + 0xde, 0x8a, 0x52, 0xe3, 0x8c, 0x4d, 0xea, 0xc2, 0x1a, 0x38, 0x0e, 0x75, + 0xe1, 0xfe, 0x06, 0x4d, 0xec, 0x9a, 0xb9, 0xfd, 0xb2, 0xc7, 0x91, 0x0e, + 0x74, 0xf1, 0x1c, 0x62, 0x94, 0xa5, 0xc9, 0x46, 0xe9, 0x4b, 0x9a, 0x5c, + 0x22, 0xe1, 0x68, 0xe3, 0xf7, 0x61, 0x67, 0x8b, 0x43, 0xd1, 0xd1, 0x8d, + 0x46, 0xf5, 0x1f, 0x70, 0xc5, 0xa7, 0xa8, 0x62, 0xc3, 0x44, 0xc7, 0x73, + 0x1a, 0x37, 0x31, 0xb7, 0x01, 0x1b, 0x96, 0x6e, 0xf2, 0x3f, 0x28, 0x9d, + 0x02, 0xdb, 0xa1, 0x49, 0xec, 0x2b, 0xb6, 0x1d, 0xcc, 0x85, 0x0c, 0x4a, + 0x95, 0xe8, 0x29, 0xec, 0x21, 0x04, 0x3d, 0xd0, 0xa8, 0x84, 0x36, 0x7b, + 0xab, 0xf5, 0xca, 0xc3, 0xc2, 0x16, 0xab, 0xc3, 0xc3, 0xc4, 0xf4, 0xb7, + 0xc1, 0x7a, 0x1c, 0xa2, 0xcb, 0x1e, 0x47, 0xc9, 0x71, 0x4a, 0x52, 0x96, + 0x14, 0xb0, 0xa5, 0x2e, 0xb5, 0x95, 0xce, 0x87, 0xdd, 0x3d, 0xff, 0x00, + 0x61, 0x68, 0x72, 0x16, 0x5e, 0x8e, 0x8c, 0xe8, 0xf4, 0x3f, 0x43, 0x90, + 0x7c, 0xea, 0xea, 0x18, 0xb4, 0x2c, 0x33, 0x6c, 0x3d, 0xdd, 0x42, 0x6d, + 0xbe, 0x4d, 0x83, 0x56, 0x74, 0x5e, 0x39, 0x53, 0xa0, 0xb8, 0xa8, 0xd1, + 0xba, 0x31, 0xe7, 0x42, 0x10, 0x84, 0x22, 0x72, 0xac, 0x49, 0xc1, 0xe3, + 0x91, 0xe5, 0x0b, 0x43, 0xca, 0xd6, 0x42, 0x6f, 0xa6, 0x7a, 0x30, 0x8d, + 0xb6, 0xf6, 0x16, 0xbe, 0x61, 0x61, 0x8c, 0x79, 0x39, 0x32, 0xf4, 0x3d, + 0x0f, 0xd7, 0x70, 0x59, 0x31, 0x0b, 0x8c, 0xbd, 0x1e, 0x05, 0x66, 0x2f, + 0xa4, 0xfb, 0xc7, 0x84, 0x2c, 0xf1, 0x63, 0x16, 0x52, 0x12, 0xc3, 0xe0, + 0x43, 0x39, 0x1b, 0xb2, 0xed, 0x6e, 0x3a, 0xe8, 0x50, 0x95, 0xc0, 0x97, + 0x63, 0x1d, 0xa5, 0x8e, 0x74, 0x26, 0xf4, 0x99, 0xe4, 0xd8, 0xa8, 0x83, + 0xc6, 0xc5, 0xf7, 0x17, 0x19, 0x79, 0x42, 0x84, 0x8e, 0xb1, 0xc9, 0x20, + 0xf3, 0x73, 0x46, 0xce, 0x63, 0x9b, 0x1d, 0x0e, 0x0b, 0x5f, 0x30, 0x86, + 0x31, 0x8f, 0x27, 0x37, 0xd5, 0x7e, 0x00, 0xb2, 0x62, 0xe4, 0xe0, 0xcb, + 0xd0, 0xba, 0x21, 0x75, 0xfa, 0x37, 0x83, 0x18, 0xb4, 0x24, 0x37, 0x5e, + 0xc4, 0x21, 0x8d, 0x35, 0x81, 0xbb, 0xd9, 0x21, 0x63, 0xef, 0xfb, 0x69, + 0x78, 0xac, 0x48, 0x48, 0x43, 0x62, 0x09, 0x0d, 0x76, 0x46, 0xc4, 0x84, + 0xe2, 0x90, 0xe0, 0x17, 0x19, 0x7a, 0x1f, 0x02, 0x44, 0xf9, 0x64, 0x38, + 0x1b, 0x12, 0x1e, 0x98, 0x48, 0x6f, 0x6f, 0x22, 0xe3, 0xd0, 0xe7, 0x10, + 0xc6, 0x31, 0xe4, 0xe4, 0xfa, 0x3f, 0x7d, 0x1d, 0x33, 0xc1, 0xec, 0x21, + 0x65, 0x72, 0x71, 0x65, 0xe8, 0x45, 0x3b, 0xa5, 0xd4, 0xb5, 0x3e, 0xb7, + 0x17, 0x85, 0x88, 0x24, 0x71, 0x5d, 0x46, 0x3c, 0x1a, 0x29, 0x09, 0x39, + 0x09, 0x54, 0xb5, 0xe4, 0x6f, 0xf6, 0xd2, 0x8d, 0xd5, 0xde, 0x09, 0x41, + 0xec, 0x35, 0x11, 0x54, 0x6c, 0x6d, 0x24, 0x70, 0x02, 0x50, 0x9a, 0x14, + 0x33, 0x82, 0x16, 0x1e, 0x87, 0xc0, 0xb3, 0xdf, 0x78, 0x64, 0x83, 0x21, + 0x74, 0x2c, 0x73, 0x67, 0x2a, 0x74, 0x17, 0x1e, 0x87, 0x38, 0x86, 0x31, + 0x8f, 0x27, 0x3e, 0x99, 0xf4, 0x4b, 0x2f, 0x7e, 0xc1, 0x72, 0x2c, 0x31, + 0x1c, 0x3e, 0xd9, 0x7a, 0x12, 0xa7, 0xfb, 0xa1, 0xba, 0xf9, 0x1f, 0xe5, + 0xaf, 0x5c, 0x5a, 0x17, 0x71, 0x04, 0x2c, 0x22, 0x38, 0x8e, 0x7b, 0x39, + 0x42, 0xdd, 0x0f, 0x7c, 0x20, 0xea, 0x1f, 0xee, 0x7f, 0xad, 0x56, 0xd3, + 0x78, 0x14, 0x1a, 0x31, 0xa1, 0xb8, 0xdc, 0x40, 0x62, 0x8f, 0x1b, 0x56, + 0x8c, 0xde, 0x82, 0xd4, 0xc4, 0x9e, 0xee, 0x26, 0x20, 0x8d, 0x89, 0x8b, + 0x97, 0xdd, 0xac, 0x7a, 0x31, 0x71, 0xe8, 0x72, 0x88, 0x63, 0x18, 0xf2, + 0x73, 0xfd, 0x3a, 0xcb, 0xee, 0x16, 0xec, 0x58, 0x78, 0xe3, 0xf6, 0xcb, + 0xc7, 0x5c, 0x70, 0x8e, 0x7b, 0xbd, 0x4e, 0x08, 0xeb, 0xab, 0x9c, 0x5c, + 0xe1, 0x68, 0x62, 0x65, 0x8c, 0xa5, 0x29, 0xb1, 0x7b, 0x7f, 0x7c, 0xa5, + 0x5c, 0x1a, 0x8e, 0x3c, 0x35, 0x78, 0x8d, 0x8d, 0x8a, 0x53, 0xc0, 0x5b, + 0xf2, 0x45, 0xab, 0x81, 0xa8, 0x37, 0xb9, 0xc3, 0xed, 0xe8, 0x24, 0xff, + 0x00, 0x3d, 0x34, 0xf5, 0x1e, 0x1e, 0x84, 0x0d, 0xb9, 0xd0, 0x5e, 0x87, + 0x28, 0x86, 0x3d, 0x27, 0x2f, 0xa5, 0x3e, 0x83, 0x9f, 0xec, 0x28, 0xb4, + 0x71, 0x65, 0x91, 0x77, 0x1e, 0x39, 0x9b, 0x13, 0x1e, 0x7d, 0x2e, 0x08, + 0x5a, 0xb9, 0xc5, 0xa5, 0x0c, 0x4c, 0xe4, 0xa3, 0x78, 0xe6, 0xde, 0x32, + 0x9c, 0x1a, 0xb6, 0xf0, 0xd3, 0xef, 0x96, 0x14, 0xb9, 0x42, 0x18, 0x63, + 0x37, 0x3b, 0xc2, 0xd4, 0xf0, 0xb3, 0xec, 0x6a, 0x84, 0x21, 0x34, 0x1c, + 0xde, 0x17, 0x1e, 0x87, 0x27, 0xb0, 0x86, 0x75, 0xc3, 0x1e, 0x1c, 0xbe, + 0x9b, 0xf5, 0x56, 0x39, 0xc5, 0xd3, 0xc1, 0x96, 0x27, 0x0a, 0x53, 0x91, + 0x64, 0x0b, 0x1b, 0x17, 0xd1, 0xe8, 0x16, 0xb5, 0x61, 0x68, 0x78, 0xa5, + 0xcf, 0x25, 0x3b, 0x2c, 0xfe, 0xfc, 0xb7, 0xf9, 0xcb, 0x72, 0xb2, 0x98, + 0x98, 0x9d, 0x42, 0x6e, 0x7e, 0x0a, 0xd2, 0xce, 0x70, 0xd7, 0xec, 0x7e, + 0x83, 0xd2, 0xf2, 0xf3, 0xb1, 0xb3, 0x9e, 0x17, 0xa1, 0xfa, 0x02, 0xc1, + 0xe1, 0x8f, 0x1e, 0x5d, 0x57, 0xe8, 0x96, 0x39, 0x7e, 0xda, 0x9c, 0x1a, + 0x16, 0x79, 0x7d, 0x8d, 0xa3, 0x6b, 0x4d, 0x8d, 0x65, 0x6b, 0xe8, 0x10, + 0xb5, 0x2b, 0x4d, 0x1b, 0x1b, 0x16, 0x6b, 0x1a, 0xa6, 0x57, 0x2c, 0xf5, + 0xb0, 0x99, 0x4b, 0x94, 0x21, 0x3c, 0x37, 0x7b, 0x6b, 0xf4, 0xca, 0xc3, + 0x79, 0x7b, 0xf6, 0xbf, 0x4d, 0x4f, 0x4a, 0x43, 0x46, 0x1c, 0xde, 0x17, + 0xa1, 0xfa, 0x42, 0xe3, 0x07, 0x97, 0xf5, 0x7d, 0x1f, 0xed, 0xec, 0x2c, + 0xac, 0x70, 0x65, 0x9d, 0x33, 0xc9, 0xfb, 0x3c, 0x7b, 0xa8, 0x5b, 0xeb, + 0x59, 0xe9, 0x10, 0xb2, 0xb2, 0xac, 0x23, 0xa6, 0x95, 0x8b, 0x8f, 0xf1, + 0xf7, 0xd5, 0x6e, 0x3e, 0x71, 0x73, 0x70, 0x84, 0x26, 0x3e, 0xe3, 0x5f, + 0x65, 0x1c, 0x61, 0x0f, 0x3c, 0x18, 0xf7, 0x46, 0xc6, 0x6c, 0xc9, 0xa3, + 0x84, 0x2d, 0x9c, 0xe5, 0x85, 0xc7, 0xa3, 0xae, 0x06, 0x3c, 0x31, 0xbf, + 0xac, 0x7f, 0xe5, 0xed, 0xe8, 0x89, 0x70, 0x84, 0x2d, 0x7c, 0x21, 0x63, + 0xa1, 0xea, 0x87, 0x0c, 0x7b, 0xab, 0xe8, 0xf4, 0x8b, 0x42, 0xca, 0xb5, + 0xf5, 0xd2, 0xd6, 0x3c, 0xae, 0x1a, 0xcb, 0xec, 0x09, 0xdc, 0xac, 0xad, + 0x0d, 0x7d, 0xbd, 0x6f, 0x81, 0xeb, 0xfc, 0xb1, 0xe5, 0x8c, 0x6a, 0xe7, + 0x9c, 0x35, 0x47, 0xb7, 0xb8, 0xe5, 0x8e, 0x9e, 0x8b, 0xd0, 0x79, 0x63, + 0xf4, 0xdb, 0xf4, 0xd6, 0xae, 0x66, 0x2e, 0x2e, 0x99, 0xc0, 0x42, 0x48, + 0x81, 0x23, 0x35, 0xdd, 0x14, 0x51, 0xd2, 0x50, 0x58, 0x13, 0x27, 0xa1, + 0xcd, 0x0b, 0x42, 0xce, 0xb5, 0xbe, 0x47, 0x97, 0xc3, 0x2f, 0x48, 0x53, + 0xc0, 0x6c, 0xf1, 0x3b, 0x8d, 0x36, 0x16, 0xda, 0x50, 0xb6, 0x16, 0x11, + 0xbf, 0x5a, 0xf8, 0x1e, 0xbf, 0xcb, 0xd0, 0xf0, 0xf6, 0xd8, 0xb8, 0x62, + 0x47, 0x1b, 0x9c, 0x12, 0x1a, 0xdc, 0x6a, 0x1d, 0x3d, 0x0e, 0x31, 0xf0, + 0x3c, 0xd1, 0x8f, 0xd1, 0x66, 0x6f, 0xae, 0xf8, 0x2e, 0x50, 0xa1, 0x30, + 0x9c, 0x6e, 0x27, 0xb1, 0x4d, 0xec, 0x8d, 0xdb, 0x85, 0xf2, 0x37, 0x6c, + 0x6b, 0x64, 0xce, 0x42, 0x71, 0x85, 0xba, 0xf4, 0x39, 0x21, 0x6b, 0xd6, + 0x3a, 0xe8, 0x63, 0xe0, 0x78, 0xac, 0xea, 0x25, 0xbe, 0x8a, 0x84, 0x26, + 0x3d, 0x8b, 0xa1, 0x0b, 0x28, 0xdf, 0xf7, 0x7f, 0x5c, 0x43, 0x8d, 0x0c, + 0xdc, 0xcc, 0x78, 0x78, 0x83, 0xd2, 0x99, 0xa0, 0x8d, 0xee, 0x6e, 0xdb, + 0xec, 0x24, 0x6d, 0x2c, 0x36, 0xc2, 0x3f, 0x43, 0x62, 0x8d, 0xec, 0x36, + 0x31, 0xec, 0x51, 0xb1, 0xbf, 0xfc, 0x06, 0x21, 0x4a, 0xcc, 0xdf, 0xc2, + 0x2b, 0x95, 0x89, 0xc8, 0x25, 0xe0, 0x48, 0xdc, 0x90, 0x37, 0xb4, 0x10, + 0xa2, 0x41, 0xa8, 0x79, 0x39, 0x1e, 0x94, 0x73, 0x42, 0xc2, 0xf4, 0xd7, + 0x8b, 0x39, 0x1b, 0x29, 0xb7, 0x64, 0x52, 0x29, 0x4b, 0x8b, 0x0a, 0x26, + 0x9f, 0xbe, 0x13, 0xb8, 0x53, 0x0b, 0x28, 0x7b, 0xf7, 0x35, 0xbe, 0x04, + 0xdd, 0xe8, 0x62, 0x1b, 0xdc, 0x6f, 0x44, 0xdb, 0x64, 0xfe, 0x06, 0xd6, + 0xc1, 0xdd, 0xc1, 0xb5, 0xa5, 0xed, 0xff, 0x00, 0x06, 0x6b, 0x6a, 0x8d, + 0xbe, 0x54, 0x7d, 0x26, 0x36, 0xe9, 0xb8, 0xdd, 0x72, 0x45, 0x9e, 0x03, + 0x82, 0x29, 0x46, 0xca, 0xfd, 0x77, 0xce, 0x5f, 0x55, 0xb5, 0x0a, 0xac, + 0x27, 0x51, 0xaa, 0x9d, 0x31, 0x33, 0x37, 0xa3, 0x44, 0x63, 0xb4, 0xf7, + 0x25, 0xbf, 0x46, 0x71, 0x8b, 0x4e, 0x34, 0xb6, 0xc1, 0x69, 0x5a, 0x5b, + 0x8a, 0x52, 0x8d, 0xae, 0xa3, 0x65, 0xd5, 0x34, 0x26, 0x45, 0x57, 0x61, + 0x32, 0x8b, 0x71, 0x61, 0x3c, 0x35, 0xfb, 0xde, 0xb6, 0x8d, 0x8f, 0xef, + 0x87, 0xb8, 0xf6, 0xc5, 0x1b, 0xd3, 0xbd, 0x1a, 0xdc, 0xdf, 0x0f, 0x86, + 0x1a, 0x3f, 0x91, 0x84, 0xae, 0xa3, 0x6a, 0x93, 0x54, 0x6c, 0xe9, 0x8e, + 0x23, 0x80, 0xd8, 0xde, 0x1e, 0x1f, 0xa4, 0x52, 0x3b, 0x8d, 0x5c, 0xb1, + 0x8b, 0x1b, 0xec, 0x73, 0x82, 0xe8, 0x7a, 0xdb, 0x50, 0xc4, 0x8e, 0x0e, + 0x55, 0x05, 0xc4, 0x65, 0xc5, 0x12, 0x70, 0x65, 0x4b, 0x91, 0x35, 0x6a, + 0x1c, 0xc8, 0xa3, 0x4d, 0x38, 0xf2, 0xb7, 0x1c, 0x10, 0x99, 0xd6, 0x94, + 0x71, 0xe2, 0xe2, 0x94, 0x78, 0x2b, 0xf5, 0xa1, 0xb8, 0x99, 0x09, 0x44, + 0xee, 0x28, 0x86, 0xdd, 0xef, 0xfc, 0x13, 0x43, 0xc3, 0xe0, 0xe0, 0x79, + 0x67, 0x27, 0x03, 0x78, 0x6f, 0x0b, 0x08, 0x4a, 0x54, 0x3c, 0x4c, 0x3e, + 0x16, 0x19, 0x27, 0xbf, 0x04, 0x19, 0x08, 0xeb, 0x97, 0xd8, 0x70, 0x1e, + 0x96, 0x70, 0x6b, 0xbc, 0xc3, 0x8d, 0xc3, 0x6d, 0xf3, 0x97, 0x2d, 0x2d, + 0x84, 0xb5, 0x96, 0x38, 0xa7, 0x7d, 0xc5, 0x74, 0x9c, 0x58, 0xb7, 0xd1, + 0x0b, 0x4b, 0xed, 0x36, 0xf2, 0xc9, 0xb8, 0xd9, 0xc4, 0x70, 0xb0, 0x92, + 0x26, 0x37, 0x87, 0xcc, 0x0e, 0x2b, 0x0e, 0x44, 0x26, 0x28, 0xf3, 0x37, + 0x26, 0xc9, 0x89, 0xfc, 0x31, 0x34, 0xf8, 0x20, 0x9a, 0x0d, 0xae, 0xa5, + 0x45, 0x43, 0x6f, 0x16, 0x94, 0x71, 0xe5, 0xf7, 0x1b, 0x1b, 0x47, 0x5d, + 0x7f, 0x4f, 0x92, 0x81, 0x4f, 0xc7, 0x0f, 0xf8, 0xfc, 0x9c, 0x90, 0xbe, + 0xdb, 0x7c, 0x8d, 0x61, 0x25, 0x1b, 0x65, 0xf4, 0x19, 0xcd, 0x3f, 0xd8, + 0xe2, 0xff, 0x00, 0x63, 0xf8, 0xe7, 0x10, 0x8f, 0x4a, 0x26, 0x94, 0xe8, + 0x45, 0x23, 0x1e, 0xfb, 0xdf, 0xb2, 0xf4, 0x12, 0x2f, 0xcb, 0xc3, 0xc5, + 0xc4, 0xbc, 0x09, 0x9a, 0xa3, 0x92, 0x4e, 0x4e, 0x8e, 0x26, 0x13, 0x10, + 0xd9, 0x28, 0xdf, 0x63, 0x63, 0x1a, 0x6b, 0x15, 0x0f, 0xb4, 0x6d, 0x85, + 0xc0, 0x7a, 0x28, 0xce, 0x2d, 0x7b, 0x63, 0xa9, 0x09, 0x88, 0x24, 0x1b, + 0x65, 0x39, 0xb5, 0xc5, 0xcf, 0x2e, 0x87, 0x35, 0xb8, 0x9e, 0x01, 0x8e, + 0x5c, 0x13, 0x78, 0x41, 0x23, 0xe1, 0x94, 0xa3, 0x02, 0x62, 0x79, 0x6c, + 0x48, 0x19, 0xb0, 0xf9, 0x0c, 0x84, 0x13, 0x60, 0x89, 0x36, 0xc2, 0x4d, + 0xec, 0x8d, 0xb8, 0xd6, 0x95, 0xc3, 0x27, 0xd4, 0x58, 0x2b, 0xec, 0x35, + 0xa1, 0x6a, 0xe3, 0x26, 0x5d, 0x6e, 0xdc, 0x4a, 0xfa, 0x95, 0x44, 0x5f, + 0x61, 0x34, 0xec, 0xbb, 0xf9, 0x12, 0xb1, 0x59, 0xc4, 0xef, 0xec, 0x6f, + 0xe9, 0xbd, 0x8f, 0xf9, 0xa7, 0x11, 0xbf, 0x75, 0xfc, 0x41, 0x12, 0x52, + 0x9e, 0x59, 0xc0, 0x55, 0xde, 0x97, 0xe9, 0xc9, 0xfb, 0x52, 0x63, 0x52, + 0x73, 0x12, 0xe3, 0xfb, 0x38, 0x46, 0x5f, 0x76, 0x37, 0x71, 0xf2, 0x2f, + 0xe0, 0x43, 0x7d, 0xb5, 0xd2, 0xaa, 0xff, 0x00, 0x61, 0x1f, 0xd1, 0xfd, + 0x9c, 0xe3, 0x3f, 0x76, 0xff, 0x00, 0x68, 0x71, 0xdf, 0xc5, 0xfd, 0x47, + 0x38, 0x93, 0xe0, 0xdd, 0x07, 0xb6, 0xcb, 0x8f, 0xb1, 0x0e, 0x54, 0x7f, + 0x63, 0x8b, 0x7f, 0x81, 0x95, 0x5c, 0xfb, 0xb4, 0x3d, 0xdc, 0x88, 0x87, + 0x17, 0xce, 0x66, 0x96, 0x49, 0x79, 0x2a, 0x7d, 0x4d, 0xbb, 0x91, 0x13, + 0x04, 0x48, 0x81, 0xaa, 0x5b, 0x16, 0x0d, 0x63, 0x9f, 0xd8, 0xde, 0xda, + 0x3f, 0x27, 0x39, 0x9a, 0xff, 0x00, 0x6c, 0x5d, 0xbf, 0x04, 0x21, 0xb8, + 0x2e, 0xeb, 0x08, 0xe2, 0xe4, 0x82, 0x33, 0x9b, 0x47, 0x74, 0x35, 0x79, + 0x1f, 0x29, 0x1f, 0x9c, 0x70, 0x18, 0xf4, 0x33, 0x8b, 0x42, 0x67, 0xb2, + 0x47, 0x44, 0x82, 0xba, 0x85, 0x71, 0x07, 0xcd, 0xc7, 0x4c, 0xc1, 0x89, + 0x32, 0xf4, 0xd2, 0x94, 0x84, 0x9e, 0x19, 0x0e, 0xa2, 0xda, 0xb1, 0x31, + 0x31, 0x3c, 0x33, 0x81, 0xb6, 0x28, 0x90, 0xa2, 0x62, 0xdc, 0xb6, 0xe1, + 0xed, 0x0f, 0x68, 0xdf, 0xa9, 0xd4, 0x5a, 0x2e, 0x39, 0x65, 0x2a, 0x8d, + 0x8b, 0x6a, 0xdc, 0x4c, 0x79, 0xc0, 0x6c, 0xd4, 0xf6, 0x36, 0x85, 0x0f, + 0xc8, 0xbd, 0xd4, 0x48, 0x24, 0x11, 0x46, 0x44, 0x84, 0x14, 0xac, 0xdf, + 0xb9, 0xb9, 0xb9, 0xbf, 0x71, 0xa2, 0x6a, 0x7e, 0xe8, 0x5c, 0x01, 0x7d, + 0x88, 0x86, 0x84, 0xab, 0x45, 0x4c, 0x7d, 0x84, 0x97, 0x66, 0x24, 0xef, + 0x5e, 0x0f, 0x6f, 0xcd, 0x10, 0xa5, 0x13, 0x1a, 0xd7, 0x23, 0x84, 0x17, + 0x19, 0x8e, 0x58, 0xf8, 0x67, 0x16, 0xff, 0x00, 0xa1, 0xce, 0x45, 0xf7, + 0xfe, 0x0f, 0xe2, 0x88, 0xe4, 0xad, 0xfd, 0xc4, 0xd0, 0xbb, 0x77, 0xdf, + 0xf5, 0x2d, 0xb6, 0x7d, 0x47, 0xb4, 0xb2, 0xf3, 0xfe, 0x63, 0x5b, 0x1b, + 0xbe, 0x3f, 0xa1, 0x91, 0x72, 0xf0, 0xb6, 0x39, 0x37, 0xf8, 0xa2, 0x56, + 0xfc, 0x89, 0x9a, 0x54, 0xdf, 0x11, 0xee, 0x90, 0xdf, 0x60, 0x9a, 0x7b, + 0xac, 0x41, 0x2d, 0x4e, 0x1c, 0x07, 0xa6, 0x0e, 0x53, 0xa2, 0x4e, 0xac, + 0xea, 0x85, 0xd0, 0x09, 0x57, 0x04, 0x58, 0x85, 0x8e, 0x86, 0xe8, 0x6c, + 0xa2, 0x74, 0xe7, 0x91, 0xee, 0x35, 0x70, 0x68, 0x84, 0xf4, 0x14, 0xea, + 0x26, 0x23, 0x71, 0x3c, 0x42, 0x53, 0x0d, 0xc5, 0x28, 0x86, 0xac, 0xe1, + 0x9e, 0x6e, 0x1b, 0xf4, 0x96, 0xa7, 0xa1, 0x24, 0x1b, 0xae, 0xe1, 0x31, + 0x89, 0x9b, 0xab, 0x91, 0xca, 0xbb, 0x8e, 0xe6, 0x5c, 0x38, 0x20, 0x43, + 0x13, 0x29, 0x4a, 0xca, 0x52, 0xe8, 0x84, 0x18, 0x88, 0xec, 0x0d, 0x6c, + 0x31, 0xea, 0xe3, 0x96, 0xfd, 0x8e, 0x91, 0x7e, 0x10, 0xb8, 0x09, 0x15, + 0x69, 0x6e, 0x72, 0x74, 0x03, 0xd5, 0x89, 0xa6, 0x95, 0x0c, 0x54, 0xf7, + 0x13, 0x6f, 0x64, 0x2f, 0x15, 0x7f, 0xde, 0x7c, 0x8d, 0x83, 0xec, 0x1e, + 0x40, 0xc2, 0x92, 0xe1, 0x3d, 0xc7, 0x1e, 0x98, 0x4d, 0x89, 0x84, 0xc5, + 0x29, 0x4a, 0x33, 0x03, 0x8f, 0x31, 0xf7, 0xc2, 0x73, 0x92, 0xb4, 0x4b, + 0x67, 0xb9, 0x1d, 0x88, 0xea, 0x73, 0x83, 0x0f, 0x03, 0x47, 0x1a, 0x21, + 0x08, 0x6e, 0x2a, 0x34, 0xf6, 0x47, 0x04, 0xd0, 0x84, 0x52, 0x97, 0x1c, + 0x23, 0x10, 0xe5, 0x0c, 0xf2, 0x24, 0xe0, 0xc6, 0xe1, 0x75, 0x41, 0x8b, + 0x55, 0x18, 0xde, 0xb4, 0x40, 0x13, 0x29, 0x44, 0xeb, 0x86, 0x51, 0x29, + 0xcb, 0x10, 0x90, 0x84, 0x66, 0xfd, 0x8d, 0xfb, 0x11, 0xf6, 0x37, 0x1b, + 0xb1, 0xbf, 0x62, 0x09, 0x38, 0x8d, 0xb9, 0x68, 0xda, 0x18, 0xc7, 0xc0, + 0xc7, 0x96, 0x31, 0x09, 0xec, 0x51, 0xea, 0x43, 0x1b, 0xa8, 0x8e, 0x1d, + 0xa2, 0x42, 0xfa, 0xd0, 0xee, 0x21, 0x74, 0xd8, 0x86, 0x3c, 0x58, 0x21, + 0x68, 0xe4, 0x03, 0xad, 0x98, 0x8e, 0xc8, 0xd8, 0xa8, 0x5d, 0x78, 0xbd, + 0x10, 0x41, 0x08, 0x4d, 0x14, 0xa3, 0xdc, 0x68, 0x91, 0xf0, 0x22, 0x06, + 0xdd, 0x56, 0x88, 0x34, 0x73, 0x3c, 0x3e, 0x47, 0xbb, 0x83, 0x5c, 0x8e, + 0x81, 0x88, 0x72, 0x87, 0xda, 0x1b, 0x3e, 0x83, 0xe9, 0xa1, 0xf7, 0x1f, + 0x02, 0x6f, 0x50, 0x99, 0x83, 0x63, 0x90, 0x9f, 0x2c, 0xe9, 0x05, 0xb3, + 0x64, 0x5d, 0x3e, 0x05, 0xa5, 0x17, 0x2b, 0x92, 0x14, 0x84, 0x8a, 0x5c, + 0xe8, 0xa5, 0x29, 0x26, 0x2e, 0x2e, 0x28, 0xde, 0xfe, 0x8b, 0xac, 0xd3, + 0x34, 0xfe, 0xbb, 0x2f, 0xdc, 0x4c, 0xa5, 0x29, 0x4a, 0x58, 0x51, 0xb2, + 0xe1, 0xde, 0x50, 0xe3, 0x31, 0xd1, 0xed, 0xfd, 0x7c, 0x09, 0xa6, 0x41, + 0x62, 0x18, 0x65, 0x2e, 0x28, 0xb0, 0xb1, 0x34, 0x42, 0x0d, 0xa1, 0x15, + 0x42, 0x14, 0xf1, 0xd0, 0x7b, 0x86, 0xca, 0x5d, 0x0f, 0x27, 0x1c, 0x6b, + 0x36, 0x64, 0xdc, 0x9b, 0xa1, 0x48, 0x36, 0x52, 0x13, 0x31, 0x14, 0x14, + 0x6f, 0x46, 0xf9, 0xe3, 0xa5, 0xee, 0xce, 0xfd, 0xf6, 0xdc, 0xb0, 0xcc, + 0xd3, 0xf6, 0xfe, 0x44, 0x47, 0xbb, 0xa4, 0xd1, 0x6f, 0xc4, 0x4c, 0xc2, + 0x13, 0x5a, 0xd8, 0x16, 0x4f, 0x8d, 0x29, 0xe5, 0x0b, 0x08, 0x73, 0x86, + 0x2c, 0x37, 0x74, 0x18, 0x3f, 0x3c, 0x0f, 0xb4, 0x3e, 0xc1, 0x1e, 0x84, + 0xec, 0x27, 0x69, 0x5e, 0x98, 0x3b, 0x82, 0xee, 0x62, 0x32, 0x2f, 0x45, + 0xa2, 0x68, 0x5b, 0x9d, 0xee, 0x4b, 0xf2, 0x2c, 0xd2, 0xe5, 0x94, 0xb8, + 0x47, 0x69, 0xaf, 0x0f, 0xf6, 0x7e, 0x0a, 0x73, 0x7e, 0x8f, 0xe0, 0xd9, + 0xd1, 0x7e, 0x1f, 0xef, 0x81, 0x53, 0x69, 0x8e, 0x86, 0x18, 0xa5, 0x39, + 0xe0, 0x68, 0xc4, 0x10, 0x9a, 0x63, 0x4a, 0x53, 0x8c, 0x17, 0xdd, 0x1c, + 0xa2, 0x7d, 0xb7, 0xfd, 0x0e, 0x18, 0xd8, 0xc7, 0x47, 0xdd, 0xd3, 0x6a, + 0x72, 0xbc, 0x6c, 0x6f, 0x67, 0x44, 0xac, 0x5a, 0x99, 0xc5, 0x9a, 0x51, + 0x2d, 0xd8, 0x4e, 0x5d, 0xc3, 0x47, 0x02, 0xbe, 0xeb, 0x01, 0x09, 0x76, + 0x43, 0xe8, 0x20, 0xdd, 0xd0, 0x78, 0x03, 0x4f, 0x21, 0xa3, 0xa8, 0xd7, + 0xc2, 0x63, 0x4e, 0x81, 0xa2, 0x48, 0xe4, 0x77, 0xf7, 0x1b, 0x18, 0xf5, + 0x31, 0x36, 0xd5, 0x0a, 0x43, 0xeb, 0xd7, 0xd3, 0xb8, 0x36, 0x1d, 0xb5, + 0xc2, 0xd5, 0x75, 0x21, 0x20, 0xb2, 0xbd, 0x38, 0xec, 0x17, 0xa2, 0xd1, + 0xd2, 0xdd, 0xf1, 0x4e, 0xc5, 0xdb, 0xf1, 0xbe, 0x0b, 0x4d, 0x2e, 0xaa, + 0x48, 0xd7, 0xf6, 0xf6, 0x1c, 0xbf, 0x71, 0xfe, 0x45, 0x46, 0xc6, 0x21, + 0xfd, 0x57, 0xf0, 0x57, 0xfa, 0x22, 0xbf, 0xd5, 0x7f, 0x03, 0x6f, 0xfc, + 0x8c, 0xb6, 0xfd, 0x22, 0x4f, 0xf4, 0x5f, 0xc1, 0x2e, 0x8f, 0x84, 0x3e, + 0xc3, 0xe0, 0x7f, 0xf1, 0x21, 0xff, 0x00, 0xc6, 0x86, 0xff, 0x00, 0xf8, + 0xfe, 0x05, 0x91, 0xaf, 0xee, 0x5c, 0xd1, 0x84, 0x42, 0xe0, 0x86, 0x4d, + 0x4d, 0xba, 0x59, 0x83, 0x13, 0x83, 0xd8, 0xa5, 0x29, 0x7d, 0x04, 0x3d, + 0x86, 0x33, 0x6f, 0xd0, 0x84, 0x20, 0xc7, 0xd7, 0xa7, 0x51, 0x34, 0xd5, + 0x5a, 0xe6, 0x70, 0x78, 0x51, 0x3d, 0x15, 0x84, 0x21, 0x39, 0x0b, 0xd5, + 0xe2, 0x2e, 0x7d, 0x34, 0x5b, 0xd9, 0x9b, 0x3d, 0xd3, 0x65, 0x82, 0xf5, + 0x68, 0xe2, 0x46, 0x55, 0xdd, 0x76, 0xe9, 0xfd, 0x1b, 0x37, 0x32, 0x97, + 0x0a, 0x52, 0x97, 0x14, 0x6f, 0x4b, 0x37, 0x3d, 0x90, 0xa6, 0x06, 0x3d, + 0x4d, 0x97, 0x59, 0x4a, 0x5c, 0x34, 0x98, 0xd5, 0x6c, 0xf1, 0x71, 0x4b, + 0xaf, 0xb0, 0x0b, 0x5c, 0xd1, 0xc8, 0xc6, 0xa1, 0xfb, 0x07, 0xa0, 0x9b, + 0xb8, 0xac, 0x7c, 0x7a, 0x13, 0x52, 0x37, 0x5f, 0xaa, 0x4e, 0xc5, 0xc8, + 0xdd, 0xc2, 0xf4, 0x50, 0xdc, 0x30, 0x8a, 0x17, 0x2f, 0x77, 0xf7, 0x16, + 0xd8, 0x45, 0xc4, 0x9a, 0xd6, 0x50, 0x99, 0xb8, 0x72, 0x2e, 0x6d, 0xbb, + 0x75, 0xfe, 0xc7, 0x30, 0x8c, 0xa5, 0xcd, 0x2e, 0x96, 0x34, 0x42, 0x37, + 0x1e, 0x07, 0x89, 0x98, 0x31, 0x96, 0x18, 0xf7, 0xfa, 0x06, 0x6c, 0x4b, + 0x96, 0x3f, 0x55, 0x8a, 0xae, 0x04, 0x2f, 0x5b, 0x4b, 0x69, 0x2a, 0xc9, + 0x7e, 0xa8, 0xc6, 0xad, 0xbe, 0x95, 0x95, 0xa5, 0x08, 0x47, 0xdd, 0x7d, + 0x36, 0xd2, 0xdd, 0x94, 0xdb, 0xd6, 0x34, 0x62, 0x69, 0x2a, 0x19, 0x07, + 0x6e, 0x5f, 0xb1, 0x25, 0x05, 0xf4, 0x14, 0xa7, 0x22, 0x19, 0xb9, 0xdf, + 0xa9, 0x79, 0xb1, 0xdb, 0xa8, 0xe2, 0x84, 0xfc, 0xeb, 0x49, 0xb7, 0x11, + 0xba, 0x6c, 0x17, 0x06, 0xca, 0x5c, 0xa2, 0x65, 0x9b, 0x09, 0x7d, 0x0a, + 0x58, 0x0e, 0xf5, 0xa1, 0x8d, 0x1c, 0x0c, 0xeb, 0x10, 0x86, 0x9b, 0x63, + 0x66, 0xe5, 0x8c, 0xb7, 0x6d, 0xd8, 0x98, 0x98, 0x84, 0x26, 0xab, 0x94, + 0x27, 0xb6, 0xe2, 0x86, 0x98, 0xb5, 0x35, 0xe8, 0xa5, 0x77, 0x1d, 0xf4, + 0x19, 0x3a, 0x36, 0xeb, 0xfc, 0x6c, 0x21, 0x7d, 0x15, 0x13, 0x39, 0x26, + 0x93, 0x46, 0xf2, 0xf5, 0xf8, 0x37, 0x99, 0x41, 0xf4, 0x62, 0x21, 0xc4, + 0xa3, 0xae, 0xe2, 0xed, 0x85, 0x1e, 0x66, 0x97, 0x86, 0x5a, 0x7e, 0x81, + 0xb4, 0x95, 0x63, 0xde, 0x2e, 0x07, 0xeb, 0xef, 0x88, 0x3a, 0xae, 0x2e, + 0x8b, 0x63, 0x91, 0x62, 0x0f, 0x54, 0xca, 0x44, 0xd1, 0x46, 0xca, 0xab, + 0xd6, 0xd1, 0x2a, 0xf0, 0x9b, 0x36, 0xff, 0x00, 0x43, 0xb6, 0x1f, 0xb8, + 0xc4, 0x8b, 0x61, 0x7d, 0x12, 0xdb, 0x14, 0xa5, 0xee, 0x71, 0x92, 0x36, + 0xed, 0xc2, 0x56, 0x88, 0x97, 0xc8, 0xde, 0xf6, 0x2b, 0x86, 0x3c, 0x3c, + 0x3c, 0xad, 0x0c, 0x68, 0xa8, 0xd5, 0x99, 0x3d, 0x0e, 0x35, 0x36, 0x92, + 0xac, 0xf1, 0x8d, 0x1d, 0x7d, 0x46, 0x4c, 0x34, 0x42, 0x12, 0x15, 0x17, + 0xd2, 0x58, 0x5a, 0x18, 0xc6, 0xa1, 0x04, 0xc0, 0x2c, 0xbe, 0x63, 0x1a, + 0x1b, 0x35, 0x7f, 0x44, 0x9a, 0x37, 0x67, 0x1e, 0x68, 0x5a, 0xde, 0x5f, + 0xa3, 0xc6, 0x1b, 0x85, 0x84, 0x95, 0x8c, 0x77, 0x6d, 0xd8, 0x6c, 0xc6, + 0xd9, 0x71, 0x4f, 0x7d, 0x17, 0x14, 0xba, 0x69, 0xb2, 0x2e, 0xbe, 0xbb, + 0x44, 0xac, 0xf1, 0x8d, 0x7e, 0x7d, 0x29, 0xa2, 0x10, 0x83, 0x47, 0x05, + 0x16, 0x3d, 0xf0, 0x84, 0xb2, 0x84, 0x42, 0x65, 0xe1, 0x38, 0x5d, 0x1f, + 0x02, 0x9d, 0xa2, 0x57, 0x1a, 0x12, 0x7a, 0x7c, 0x6a, 0x48, 0x64, 0x0f, + 0xda, 0x42, 0x50, 0x9a, 0xd8, 0xf1, 0xc6, 0x8a, 0x52, 0xea, 0xe9, 0x38, + 0x60, 0x4c, 0x7e, 0x83, 0x29, 0x74, 0xa4, 0x3c, 0x3d, 0x95, 0x1f, 0x6f, + 0x57, 0x92, 0x5b, 0x28, 0xfe, 0x3d, 0xbc, 0x0f, 0x5c, 0x26, 0x21, 0xec, + 0x9c, 0x90, 0x6c, 0xb6, 0x68, 0x98, 0x9e, 0x84, 0xa4, 0x21, 0x0d, 0xd3, + 0x29, 0x4e, 0x48, 0x22, 0x10, 0x4b, 0x13, 0x1c, 0xec, 0x86, 0x95, 0xd8, + 0x34, 0x7b, 0x09, 0x37, 0xc2, 0x29, 0xd9, 0x0a, 0xe8, 0x9a, 0xe7, 0xa2, + 0x99, 0xa2, 0x12, 0x69, 0x5e, 0xcb, 0xf9, 0xfe, 0x08, 0x69, 0x5e, 0xaa, + 0x29, 0x4a, 0x5c, 0x88, 0xe2, 0x8e, 0xae, 0xe4, 0x70, 0x5c, 0x5c, 0x32, + 0xe2, 0x10, 0x65, 0x13, 0x2e, 0x29, 0x6c, 0x0f, 0x53, 0xd3, 0xb8, 0xb0, + 0xe3, 0xdd, 0x61, 0x0e, 0xc3, 0xb9, 0x38, 0x86, 0xb8, 0x70, 0x2a, 0x27, + 0xf4, 0x82, 0x2e, 0x08, 0x4c, 0xdb, 0x5b, 0xf7, 0x14, 0xe7, 0x2c, 0x99, + 0xdb, 0x44, 0x21, 0x29, 0x08, 0x42, 0x10, 0x9d, 0x46, 0x22, 0x3b, 0x3f, + 0x3f, 0xc9, 0x4f, 0xec, 0x79, 0x5f, 0x3f, 0xd1, 0x7b, 0x5f, 0xcf, 0xf4, + 0x3a, 0x71, 0x21, 0x69, 0x5b, 0xe0, 0xd9, 0x90, 0x43, 0xd8, 0x49, 0xd9, + 0x0a, 0x78, 0x17, 0x90, 0xba, 0x8f, 0x3c, 0x95, 0xc8, 0xbb, 0x02, 0x67, + 0x41, 0x2d, 0xe0, 0xfa, 0x0c, 0x83, 0xf4, 0xa0, 0xf7, 0xa1, 0xdd, 0xf0, + 0x6f, 0x65, 0xe5, 0x7f, 0xb6, 0x0d, 0xb2, 0xb5, 0x72, 0x78, 0xd7, 0x09, + 0xa3, 0x72, 0x8d, 0xb1, 0x87, 0xd1, 0x2a, 0x3c, 0x37, 0xde, 0x7e, 0xc7, + 0x08, 0x38, 0x76, 0xc1, 0xab, 0x97, 0xf9, 0x1b, 0xc8, 0x3a, 0xff, 0x00, + 0xc3, 0xf8, 0x38, 0x26, 0x24, 0x65, 0x29, 0xc8, 0xca, 0x26, 0x59, 0xbb, + 0x2b, 0xa4, 0x99, 0x7a, 0x39, 0xc0, 0xce, 0x14, 0x73, 0x58, 0xee, 0x82, + 0x26, 0x61, 0xc6, 0x87, 0xf9, 0x41, 0x2e, 0x54, 0xe5, 0x83, 0x65, 0xc8, + 0xab, 0x82, 0x3a, 0x97, 0xfd, 0xd8, 0xe3, 0x61, 0x2f, 0x38, 0x9f, 0x48, + 0x7c, 0xa4, 0x25, 0xef, 0x07, 0x6f, 0x61, 0x15, 0xb3, 0x39, 0x04, 0x34, + 0xd1, 0x3d, 0x08, 0x4c, 0x42, 0x11, 0x10, 0x9d, 0x48, 0x88, 0x42, 0x76, + 0x37, 0x46, 0x82, 0x0e, 0x3d, 0xc9, 0xe8, 0x26, 0x14, 0x42, 0x32, 0x32, + 0x14, 0xd8, 0x99, 0x6e, 0x3c, 0x41, 0x13, 0x92, 0x97, 0x4c, 0xc4, 0x1a, + 0xc4, 0xac, 0xdf, 0x9c, 0x3c, 0xff, 0x00, 0x1c, 0x93, 0x77, 0x7f, 0x8f, + 0x81, 0x4a, 0x49, 0x6c, 0x25, 0x16, 0x19, 0x4f, 0x6c, 0xf1, 0x8e, 0x37, + 0x19, 0x74, 0x37, 0xa1, 0x66, 0x1c, 0x66, 0x21, 0xa4, 0x77, 0x7b, 0xb1, + 0xbe, 0x2e, 0x3d, 0x5f, 0x22, 0x16, 0xc1, 0xbf, 0x46, 0xdc, 0x36, 0x09, + 0x50, 0x91, 0x08, 0x9e, 0xe3, 0x4f, 0x70, 0xc2, 0xd8, 0x27, 0x72, 0x84, + 0x0f, 0x06, 0x1c, 0xb1, 0xcf, 0x52, 0xc4, 0xdd, 0xcb, 0xee, 0x34, 0xd3, + 0x1b, 0x8e, 0x31, 0x9c, 0x93, 0x38, 0xed, 0xc7, 0x87, 0x32, 0xc7, 0xbe, + 0x5a, 0x84, 0xe8, 0x2e, 0x63, 0x8d, 0x6d, 0x1f, 0x27, 0x5e, 0x10, 0x33, + 0x78, 0x9a, 0x20, 0xd0, 0xe5, 0x10, 0xd7, 0x43, 0xa1, 0x62, 0x1c, 0x8e, + 0x79, 0x14, 0x89, 0x8f, 0x62, 0x75, 0x26, 0x52, 0x20, 0xd6, 0x20, 0x9d, + 0xb2, 0x47, 0x9c, 0x2e, 0x93, 0x14, 0x0d, 0xa8, 0x80, 0x8d, 0x8d, 0xc4, + 0xee, 0x95, 0xc8, 0xd5, 0x18, 0x43, 0x10, 0xe0, 0x6a, 0x6d, 0xa3, 0x93, + 0xf5, 0xb0, 0xdc, 0x59, 0x26, 0xff, 0x00, 0xbe, 0x2f, 0xf7, 0xdc, 0x43, + 0x16, 0x84, 0x84, 0x82, 0x3c, 0x2c, 0xec, 0xb1, 0x6e, 0x36, 0x2e, 0x38, + 0x19, 0x73, 0x61, 0x4a, 0x5e, 0xb8, 0xa3, 0x22, 0xec, 0x49, 0xed, 0xfd, + 0xfe, 0xc5, 0xee, 0x28, 0xaa, 0x46, 0xd3, 0xbd, 0xf8, 0xdc, 0xda, 0x36, + 0xfb, 0xbd, 0x8f, 0xd3, 0x15, 0xb7, 0xf6, 0x6c, 0x8b, 0x05, 0x39, 0xc8, + 0xfb, 0x27, 0x88, 0x6c, 0x1b, 0xee, 0x1a, 0xeb, 0x63, 0xf3, 0x3b, 0xcc, + 0x91, 0x11, 0xb2, 0xc2, 0xb1, 0x84, 0x25, 0x10, 0xeb, 0x1b, 0x12, 0x13, + 0xd0, 0x74, 0x72, 0x0d, 0xce, 0x49, 0x9b, 0x8d, 0x10, 0x64, 0xc2, 0xc3, + 0x56, 0xd0, 0xc9, 0x2a, 0x1a, 0xfa, 0x59, 0xd8, 0xd8, 0xe5, 0xd1, 0xc5, + 0x6c, 0x25, 0xc8, 0xe5, 0xc3, 0x66, 0xdf, 0x1c, 0x02, 0x16, 0x5b, 0xc4, + 0x90, 0x89, 0xdb, 0x08, 0xe8, 0x84, 0x90, 0xab, 0xe3, 0x2c, 0x68, 0xea, + 0x0b, 0x05, 0x32, 0xe0, 0xa7, 0xb9, 0x26, 0x85, 0xb0, 0xb7, 0x28, 0x8f, + 0x10, 0x4d, 0x6e, 0x3d, 0xe3, 0xd0, 0x9f, 0x61, 0xe5, 0x72, 0x39, 0x23, + 0xf5, 0x39, 0xd8, 0xfe, 0xc7, 0x77, 0x8f, 0xf3, 0x2f, 0x81, 0x2d, 0x70, + 0xff, 0x00, 0xdf, 0x71, 0x6e, 0x67, 0xee, 0xc7, 0xb8, 0x50, 0xcf, 0x11, + 0x7d, 0x86, 0xdf, 0xea, 0x8f, 0xf7, 0x48, 0x49, 0xfe, 0xa8, 0x49, 0xfe, + 0x88, 0xf2, 0x2f, 0x81, 0x78, 0xbe, 0x0f, 0x63, 0xe0, 0xf6, 0x7e, 0x07, + 0xe1, 0xf8, 0x1b, 0x1d, 0xbf, 0x96, 0x79, 0xbf, 0x27, 0x9d, 0xf2, 0xc6, + 0xde, 0x7e, 0x41, 0xf2, 0xbe, 0x46, 0x2e, 0xbd, 0xd5, 0xd4, 0x6a, 0x55, + 0x57, 0xd8, 0xe7, 0x96, 0x25, 0xfb, 0xef, 0xfa, 0x3a, 0x29, 0x7d, 0x86, + 0xd1, 0xb7, 0xe8, 0x4a, 0xae, 0x63, 0xa2, 0x23, 0x03, 0x43, 0x06, 0x8e, + 0x05, 0xc2, 0x4f, 0x00, 0xf7, 0x61, 0x4a, 0xfa, 0x11, 0x8d, 0xc1, 0xb6, + 0x56, 0x25, 0xc9, 0x94, 0xa2, 0x62, 0x65, 0x2a, 0x66, 0xc6, 0xd5, 0x52, + 0x88, 0xe8, 0x6a, 0xeb, 0x12, 0xf3, 0x9a, 0xf1, 0xc9, 0xc3, 0x8e, 0xd4, + 0x3b, 0xe0, 0xe2, 0xd0, 0xe3, 0x81, 0xe2, 0x66, 0x66, 0x66, 0x13, 0x44, + 0xd3, 0x08, 0x44, 0x44, 0x42, 0x06, 0xee, 0x51, 0xbf, 0x46, 0xc3, 0x64, + 0x5e, 0xc8, 0x69, 0xbe, 0x58, 0x92, 0x12, 0x64, 0xef, 0xa1, 0x9c, 0xbc, + 0x90, 0x98, 0xe4, 0x9a, 0x54, 0x0c, 0x14, 0x2d, 0x72, 0x39, 0xc4, 0x35, + 0x5c, 0xa3, 0xc2, 0x2e, 0xd9, 0xe1, 0x3c, 0x04, 0x98, 0xa6, 0xe4, 0x67, + 0xb9, 0xb1, 0xec, 0x49, 0xc9, 0x52, 0x1a, 0x2e, 0x85, 0x3e, 0x06, 0xe3, + 0x72, 0xca, 0x13, 0x8f, 0x34, 0x4b, 0x2f, 0x72, 0x9b, 0x0d, 0xa4, 0x47, + 0x46, 0x6e, 0xca, 0x85, 0x15, 0x21, 0x68, 0x93, 0xe0, 0x8e, 0x84, 0x31, + 0xca, 0x1d, 0x6a, 0x9b, 0x09, 0x72, 0xec, 0x7b, 0xfa, 0x01, 0x61, 0x4d, + 0x09, 0xc3, 0x66, 0x46, 0x57, 0xd4, 0x69, 0x33, 0x90, 0x0c, 0xf0, 0xda, + 0x17, 0xf9, 0x47, 0xfa, 0x85, 0x7f, 0xc0, 0xbf, 0x35, 0x9c, 0x7a, 0x44, + 0x4c, 0x36, 0x1e, 0xfa, 0x27, 0xaf, 0x74, 0xc6, 0x46, 0x42, 0x11, 0x22, + 0xae, 0xe4, 0x11, 0xd8, 0xdf, 0xb1, 0x1f, 0x56, 0x42, 0x38, 0x29, 0x4a, + 0x32, 0x9c, 0x88, 0x6c, 0x2e, 0x2e, 0x10, 0x55, 0xa2, 0x36, 0x78, 0x88, + 0x09, 0x7d, 0x44, 0xeb, 0x94, 0x7b, 0x06, 0xee, 0x70, 0x09, 0x41, 0xa3, + 0xe1, 0x41, 0xb4, 0xfa, 0x9f, 0x72, 0xe1, 0x4d, 0xc8, 0xc4, 0xdb, 0x0e, + 0x31, 0xd1, 0x45, 0x74, 0x3c, 0x45, 0xba, 0x1e, 0x03, 0xc1, 0x82, 0xba, + 0x89, 0x11, 0xc2, 0x85, 0x09, 0x88, 0xed, 0x24, 0xec, 0x43, 0x7f, 0x61, + 0x70, 0x20, 0x95, 0xc8, 0xab, 0xcb, 0x3a, 0x24, 0x74, 0xc8, 0x7d, 0x24, + 0x37, 0xd4, 0x7c, 0xe6, 0x57, 0x72, 0x94, 0xdc, 0x57, 0x09, 0x34, 0x5c, + 0x58, 0x68, 0xe3, 0x34, 0xa5, 0xa6, 0xc4, 0x9c, 0x1b, 0x96, 0x72, 0x84, + 0xc7, 0x90, 0xad, 0xd7, 0x0a, 0x23, 0x1a, 0x65, 0x65, 0x29, 0x7d, 0x2d, + 0xbb, 0x1b, 0x76, 0x2a, 0xec, 0x55, 0xdb, 0xf2, 0x55, 0xdb, 0xf2, 0x55, + 0xdb, 0xf2, 0x5f, 0x1f, 0x92, 0xf8, 0x45, 0x78, 0x2b, 0xc1, 0x5f, 0x72, + 0xb1, 0x18, 0x9e, 0x4f, 0x26, 0x0d, 0xbb, 0x14, 0xa5, 0x65, 0x29, 0x4a, + 0x52, 0x9b, 0x90, 0x90, 0x6f, 0x27, 0x88, 0x42, 0x6a, 0x4d, 0xae, 0xa5, + 0xf7, 0x28, 0xf6, 0x1e, 0x23, 0xc2, 0x53, 0xef, 0x27, 0x71, 0xe4, 0x27, + 0xb9, 0x3d, 0xcf, 0x79, 0xee, 0x2c, 0xa2, 0xbd, 0x50, 0x80, 0x00, 0x0a, + 0xee, 0x57, 0x73, 0xdc, 0x7b, 0xc8, 0xee, 0x4e, 0xe2, 0x77, 0x1b, 0x77, + 0x36, 0xd7, 0x4a, 0x51, 0x45, 0x7a, 0x28, 0xf7, 0x38, 0x13, 0x21, 0x33, + 0x4a, 0x52, 0x97, 0x0a, 0x54, 0x54, 0x44, 0x71, 0xd4, 0xae, 0xe5, 0xee, + 0x3c, 0x85, 0x15, 0xe0, 0xf6, 0x17, 0xc1, 0x7c, 0x7e, 0x4f, 0xb1, 0xf6, + 0x3e, 0xc7, 0xd8, 0xfb, 0x1f, 0x66, 0x6d, 0xd9, 0xe8, 0xa5, 0x2e, 0x29, + 0x4a, 0x52, 0x94, 0xa5, 0x2e, 0x7e, 0xe7, 0xdc, 0xfb, 0xe3, 0x62, 0xa2, + 0xa2, 0xad, 0x04, 0x20, 0x8b, 0xa6, 0x11, 0x13, 0x58, 0x14, 0x51, 0x45, + 0x14, 0x46, 0x4c, 0x91, 0x90, 0x8c, 0xa2, 0x32, 0x32, 0x32, 0x32, 0x32, + 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x88, 0xca, 0x28, 0xa2, 0x32, 0x8a, + 0xf4, 0x00, 0x41, 0x04, 0x44, 0x44, 0x5a, 0x36, 0xc3, 0x23, 0x23, 0x37, + 0x2b, 0xc2, 0xa2, 0xa2, 0xa3, 0x63, 0x63, 0x63, 0x63, 0xee, 0x7d, 0xf5, + 0x52, 0x94, 0xa5, 0x65, 0x65, 0x66, 0xfa, 0xbf, 0xff, 0xc4, 0x00, 0x2a, + 0x11, 0x00, 0x03, 0x00, 0x01, 0x03, 0x03, 0x03, 0x04, 0x03, 0x01, 0x01, + 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x11, 0x21, 0x10, 0x31, 0x41, + 0x20, 0x51, 0x61, 0x30, 0x71, 0x91, 0x81, 0xa1, 0xb1, 0xd1, 0x40, 0xc1, + 0xf0, 0xe1, 0xf1, 0x50, 0xff, 0xda, 0x00, 0x08, 0x01, 0x02, 0x01, 0x01, + 0x3f, 0x10, 0xe9, 0xbd, 0x19, 0xe8, 0xa5, 0x2b, 0x2b, 0x2b, 0x29, 0x4a, + 0x56, 0x56, 0x56, 0x52, 0x94, 0xac, 0xac, 0xa5, 0x29, 0x4a, 0xca, 0xca, + 0xf4, 0xce, 0xb9, 0xd3, 0x24, 0x64, 0x66, 0x48, 0xc8, 0xc8, 0xc8, 0xc8, + 0xc8, 0xc8, 0xca, 0x28, 0xa2, 0x8a, 0x28, 0xb2, 0xca, 0x1b, 0x21, 0x3d, + 0x2d, 0x4e, 0x47, 0xf1, 0xff, 0x00, 0x46, 0xae, 0x1f, 0xdb, 0xf6, 0x27, + 0xbe, 0x37, 0xec, 0xfc, 0x8d, 0xaa, 0x90, 0x7b, 0x06, 0xbe, 0x0e, 0xcc, + 0x36, 0xf1, 0xff, 0x00, 0x7d, 0x06, 0x4a, 0x86, 0xbd, 0xdb, 0xee, 0x57, + 0x9f, 0xdf, 0xf6, 0x5f, 0x9f, 0xcb, 0x1f, 0xfd, 0xe3, 0xbf, 0xf2, 0x0f, + 0xbe, 0x1d, 0xf7, 0xf9, 0x1e, 0x6f, 0xc8, 0xee, 0x37, 0xcb, 0x3c, 0xef, + 0x97, 0xfb, 0x3b, 0x2e, 0xfe, 0xac, 0xef, 0xb7, 0xcb, 0x2f, 0xcf, 0xe5, + 0x89, 0xdf, 0xb9, 0x9e, 0x6f, 0xcb, 0xfd, 0x9d, 0xb7, 0xf9, 0x7f, 0xb3, + 0xbc, 0xff, 0x00, 0x27, 0x65, 0xfe, 0x5f, 0xec, 0x6a, 0xe7, 0xf2, 0xff, + 0x00, 0x67, 0x9b, 0xf2, 0xff, 0x00, 0x62, 0xee, 0x3e, 0x5f, 0xec, 0x5d, + 0xc7, 0xcb, 0xfd, 0x9e, 0x57, 0xcf, 0xec, 0x2e, 0xf3, 0xe5, 0x9e, 0x5f, + 0xcb, 0x3c, 0xbf, 0x96, 0x79, 0x1f, 0x2c, 0xf2, 0x3e, 0x59, 0xe4, 0xfc, + 0xb1, 0xff, 0x00, 0xe8, 0x15, 0xd9, 0xbe, 0x5f, 0xec, 0xee, 0xb7, 0xcb, + 0xfd, 0x8b, 0xfe, 0xa3, 0x3f, 0xf6, 0x1f, 0xec, 0x6a, 0xe5, 0xf2, 0xcf, + 0xfd, 0x86, 0x7f, 0xeb, 0x33, 0xff, 0x00, 0x58, 0x97, 0xee, 0x62, 0x57, + 0x3f, 0x96, 0x79, 0x5f, 0x2f, 0xf6, 0x79, 0xff, 0x00, 0x2f, 0xf6, 0x26, + 0xf3, 0xf9, 0x66, 0x5c, 0x3f, 0xcb, 0x17, 0xfd, 0xa2, 0x1f, 0xb8, 0x7c, + 0x89, 0xff, 0x00, 0x90, 0x25, 0x73, 0xf6, 0x2b, 0x8d, 0x7d, 0x84, 0xad, + 0x86, 0x55, 0x96, 0x05, 0xa3, 0xec, 0xc5, 0x42, 0x36, 0x8b, 0xec, 0x78, + 0x0f, 0x01, 0xe0, 0x3c, 0x05, 0x14, 0x46, 0x46, 0x4d, 0x67, 0xa3, 0x35, + 0x9d, 0x13, 0x48, 0x4d, 0x26, 0x90, 0x84, 0x21, 0x08, 0x42, 0x13, 0xa6, + 0xf4, 0x5d, 0x29, 0x59, 0x4a, 0x52, 0x8d, 0x94, 0x40, 0xb4, 0x96, 0x61, + 0xf7, 0x23, 0x6e, 0x31, 0xde, 0x89, 0xd8, 0x95, 0x5a, 0x26, 0xf8, 0x63, + 0x6a, 0x37, 0x08, 0x69, 0xa7, 0x5b, 0x14, 0xec, 0x36, 0xe1, 0x51, 0x09, + 0x0a, 0x8b, 0x08, 0xf9, 0x1c, 0xda, 0x11, 0xf2, 0x35, 0xe0, 0xa3, 0x3d, + 0x8f, 0x21, 0xa1, 0xe2, 0x61, 0xb9, 0x6f, 0x29, 0x19, 0x5c, 0xa1, 0x5f, + 0xfc, 0x04, 0x9a, 0x72, 0x89, 0x3e, 0xd4, 0x4a, 0xe7, 0xec, 0x7c, 0xdf, + 0x82, 0x44, 0x96, 0xc9, 0x94, 0x44, 0xb1, 0x09, 0x78, 0xd2, 0xea, 0xdc, + 0x49, 0x70, 0x86, 0x9b, 0xbc, 0x0d, 0x18, 0x68, 0x4a, 0xed, 0xa3, 0x3b, + 0x19, 0x5c, 0x8a, 0xde, 0x10, 0xe1, 0xe4, 0xae, 0x8d, 0xe7, 0x22, 0x9c, + 0x26, 0x37, 0xce, 0x7e, 0x04, 0x9d, 0xc8, 0xf8, 0x83, 0x6e, 0xd0, 0x90, + 0xfc, 0x11, 0xfe, 0x44, 0x82, 0x96, 0x13, 0x12, 0x1c, 0x86, 0xf8, 0x68, + 0x86, 0x50, 0xd2, 0xaa, 0x86, 0xd1, 0x2c, 0x53, 0x26, 0xfb, 0x31, 0xaa, + 0xe8, 0x84, 0xe8, 0x84, 0x44, 0xf6, 0x3c, 0x47, 0x80, 0xf1, 0x68, 0x3f, + 0x21, 0xb7, 0x71, 0x83, 0x47, 0x04, 0x6b, 0xd6, 0x9f, 0xcb, 0x82, 0x4c, + 0x92, 0xa3, 0x13, 0x6e, 0xec, 0x53, 0xcb, 0x1e, 0x71, 0x0d, 0xd2, 0x0d, + 0x52, 0x64, 0x5b, 0x41, 0xd2, 0xc2, 0x8e, 0x18, 0x12, 0x96, 0x50, 0xfb, + 0x10, 0xd7, 0x63, 0x66, 0x51, 0xc0, 0x25, 0xb0, 0x34, 0xee, 0x49, 0x7c, + 0x9d, 0x88, 0x4d, 0xdf, 0x07, 0x83, 0xd2, 0xb8, 0xe8, 0x51, 0x9a, 0x36, + 0x7a, 0x5c, 0xec, 0x36, 0x7b, 0x8d, 0x39, 0x82, 0x9e, 0x11, 0x59, 0x19, + 0x69, 0x33, 0x1c, 0x49, 0x58, 0x43, 0x73, 0xec, 0xc4, 0x1f, 0x71, 0x2b, + 0xb8, 0x8b, 0x9c, 0x11, 0xb8, 0xa2, 0xec, 0x38, 0xf3, 0x05, 0x95, 0x13, + 0x3b, 0x8c, 0x44, 0x74, 0x8d, 0xca, 0x58, 0x82, 0x57, 0x74, 0x87, 0x38, + 0x42, 0x60, 0x5b, 0x64, 0xc4, 0x83, 0x6e, 0x21, 0x77, 0xa7, 0xc1, 0xfa, + 0x04, 0x6f, 0x2d, 0x84, 0x8c, 0xb3, 0xe4, 0x86, 0x7f, 0xb1, 0x15, 0x27, + 0xc0, 0x88, 0xc2, 0xf8, 0x1b, 0x70, 0xff, 0x00, 0x7c, 0x18, 0x0d, 0x31, + 0x25, 0x86, 0x4b, 0x7a, 0x27, 0xf2, 0x3d, 0xb4, 0x27, 0x59, 0x15, 0x4a, + 0xd3, 0x19, 0xc2, 0x85, 0xfc, 0x19, 0xa4, 0x1b, 0xb8, 0x1a, 0x3d, 0x86, + 0xad, 0x8a, 0x5b, 0xe9, 0x08, 0x42, 0x13, 0x49, 0xac, 0x27, 0xf1, 0x53, + 0x3d, 0x91, 0xe4, 0x42, 0x06, 0x19, 0x74, 0xaf, 0x6f, 0xfa, 0x24, 0xe7, + 0xec, 0xff, 0x00, 0xa2, 0xe5, 0x6f, 0x83, 0x25, 0xb1, 0x28, 0xbd, 0x9b, + 0xfb, 0x1e, 0x68, 0xdb, 0xff, 0x00, 0x22, 0x66, 0x3e, 0xc1, 0xf0, 0x2f, + 0xc0, 0xd1, 0xb2, 0x37, 0xb6, 0x0a, 0xff, 0x00, 0xd0, 0x9b, 0x2e, 0x27, + 0xcb, 0xaf, 0xa1, 0x49, 0x6c, 0x20, 0x66, 0x34, 0x64, 0x24, 0x24, 0x85, + 0xa3, 0x1b, 0x1b, 0xc9, 0xee, 0x3a, 0x61, 0xac, 0x22, 0x25, 0x89, 0x4c, + 0xbc, 0x7e, 0x89, 0x9c, 0x9e, 0x1a, 0xff, 0x00, 0x7c, 0x11, 0x70, 0x2c, + 0xf0, 0x36, 0xbb, 0x8d, 0xf6, 0x19, 0xbc, 0x0a, 0x32, 0x98, 0x93, 0x9f, + 0xe8, 0x6c, 0xd8, 0x69, 0xc1, 0xe0, 0x2d, 0x9e, 0x44, 0xcf, 0x78, 0x8c, + 0x9e, 0x5f, 0xd8, 0xa8, 0xb6, 0x14, 0x71, 0x0c, 0x6f, 0x24, 0x69, 0x65, + 0x8f, 0x13, 0x8f, 0xf7, 0xb1, 0x0b, 0x72, 0xfb, 0x08, 0xe5, 0x2d, 0x46, + 0x12, 0x9b, 0x95, 0x62, 0x13, 0xef, 0xf0, 0x34, 0x9b, 0x0d, 0x9e, 0x3e, + 0x4c, 0x36, 0x38, 0xf0, 0x7b, 0x1b, 0xac, 0x21, 0x3d, 0x89, 0xf5, 0x26, + 0xa6, 0xdc, 0x89, 0x56, 0xc3, 0xfe, 0x3c, 0x4f, 0x71, 0x0f, 0x61, 0xb0, + 0x84, 0x21, 0x34, 0x42, 0x10, 0x84, 0x21, 0x08, 0x42, 0x10, 0x84, 0x27, + 0x52, 0x57, 0x62, 0x4d, 0xc8, 0x4f, 0x06, 0xc5, 0x22, 0xe7, 0x45, 0xa5, + 0xbb, 0xf4, 0x3d, 0xb4, 0x9d, 0x19, 0xd3, 0x07, 0xb1, 0x06, 0x91, 0xbb, + 0x21, 0xce, 0x54, 0xdb, 0x10, 0xfd, 0xac, 0xee, 0xad, 0x1a, 0x6a, 0x0d, + 0x10, 0xdd, 0x81, 0x8c, 0x61, 0xb1, 0x41, 0x9c, 0x15, 0x23, 0x96, 0x8a, + 0xb8, 0x50, 0x75, 0x3c, 0x0d, 0x9b, 0xa2, 0x4b, 0x91, 0xdd, 0xa1, 0x1f, + 0x90, 0xeb, 0x1c, 0x6f, 0x82, 0x89, 0x24, 0xc6, 0xdf, 0x61, 0x7e, 0x06, + 0x5f, 0x36, 0x58, 0x8b, 0x06, 0x6f, 0x71, 0xb6, 0xe8, 0x6d, 0xb9, 0x15, + 0x9c, 0x1e, 0x51, 0x8b, 0x70, 0xb1, 0x4f, 0x01, 0xb4, 0x12, 0xa1, 0x54, + 0xa9, 0xb1, 0x52, 0xcd, 0xde, 0x46, 0xeb, 0xc1, 0x55, 0x51, 0xe5, 0x52, + 0x3b, 0x99, 0x97, 0x0c, 0xcf, 0x62, 0x37, 0x9a, 0x35, 0xd8, 0x4d, 0x10, + 0xdb, 0xb7, 0xc3, 0xf8, 0x30, 0x84, 0x21, 0x08, 0x42, 0x0d, 0x13, 0x23, + 0xa4, 0x21, 0x52, 0x25, 0xc9, 0xe4, 0x3c, 0x85, 0x08, 0x20, 0xa8, 0xc6, + 0xb0, 0x9a, 0x42, 0x10, 0x84, 0xa3, 0x8d, 0xc8, 0x8c, 0x70, 0x89, 0x77, + 0x17, 0x63, 0x6d, 0x61, 0x34, 0xc6, 0xb3, 0x5d, 0x88, 0x43, 0x72, 0x76, + 0x1e, 0x90, 0xdb, 0xa3, 0x7d, 0x25, 0x22, 0xd1, 0xa3, 0xc3, 0x46, 0xfe, + 0x12, 0xcb, 0x51, 0x8c, 0x58, 0x35, 0x07, 0x83, 0xdc, 0xa8, 0xdf, 0x28, + 0x6a, 0x8d, 0x43, 0x05, 0x30, 0xdc, 0x6d, 0x98, 0xc9, 0x46, 0xeb, 0x23, + 0x1e, 0x20, 0x93, 0x61, 0xe5, 0x92, 0xf3, 0xc0, 0xb2, 0xc7, 0xe0, 0x96, + 0x73, 0x8e, 0xc3, 0x69, 0x36, 0xd7, 0xe4, 0x89, 0x8a, 0xd3, 0xa2, 0xce, + 0x78, 0x1e, 0x5d, 0x12, 0xb8, 0x4c, 0x71, 0x0c, 0xdb, 0x89, 0x0c, 0x74, + 0x13, 0xe1, 0x32, 0xb9, 0x1d, 0x64, 0xb4, 0x5d, 0xc8, 0xf6, 0xc8, 0x93, + 0x98, 0x2c, 0x25, 0x54, 0xcb, 0xdf, 0x91, 0x34, 0xb1, 0x60, 0xd1, 0x5e, + 0x04, 0xed, 0x41, 0xbb, 0xc1, 0x87, 0xb2, 0xd6, 0x7a, 0x50, 0x9a, 0x42, + 0x13, 0xa1, 0xef, 0x18, 0xf8, 0x32, 0x37, 0xe1, 0x0d, 0xdd, 0x84, 0x6d, + 0x42, 0x39, 0x10, 0x78, 0x88, 0x70, 0x78, 0x8b, 0x70, 0x78, 0x8f, 0x11, + 0xe0, 0xd0, 0x93, 0xdc, 0x5f, 0x02, 0x2e, 0xcc, 0x4c, 0xd5, 0xc9, 0x79, + 0x15, 0x1e, 0x08, 0xaf, 0xb9, 0x26, 0xb3, 0xa1, 0xf4, 0x5d, 0x36, 0xe9, + 0x85, 0xe9, 0xbd, 0x70, 0x9a, 0x35, 0xa3, 0x42, 0xa8, 0x94, 0xc9, 0xe0, + 0xc8, 0x45, 0x1a, 0x20, 0xc3, 0xd1, 0x41, 0xc6, 0xf7, 0x32, 0xb6, 0x37, + 0x64, 0x3c, 0x0d, 0x8a, 0x0d, 0x8e, 0xb3, 0xe0, 0x73, 0x5c, 0x89, 0xe1, + 0x1d, 0xad, 0xc7, 0x16, 0x15, 0x4d, 0x88, 0x93, 0x92, 0x8f, 0xc1, 0x1e, + 0xcb, 0x63, 0x0a, 0x0a, 0x25, 0x78, 0x25, 0x75, 0x19, 0x19, 0xab, 0x02, + 0x13, 0x22, 0x5b, 0x11, 0x25, 0x91, 0x1c, 0xf7, 0x18, 0xb7, 0x42, 0x4d, + 0xec, 0xa8, 0x9d, 0x17, 0xb9, 0x86, 0x45, 0x5c, 0x21, 0xbb, 0xdb, 0x93, + 0xbe, 0x18, 0xa8, 0x3c, 0x02, 0x26, 0x79, 0x2b, 0xd6, 0x84, 0xd5, 0xa6, + 0xe6, 0x35, 0xe1, 0x0d, 0xdb, 0x60, 0x6d, 0xbd, 0xd9, 0xed, 0xd3, 0x9e, + 0x89, 0xae, 0x7a, 0x61, 0x9e, 0x98, 0x3d, 0x67, 0x53, 0x7a, 0x5d, 0x69, + 0x4b, 0xa2, 0x7d, 0x57, 0xaf, 0xd8, 0xdf, 0x46, 0xb4, 0x7e, 0x08, 0x42, + 0x09, 0x21, 0x4b, 0xa6, 0xa4, 0x2e, 0x56, 0xfb, 0x0b, 0x91, 0x9f, 0x5f, + 0xf8, 0x24, 0x70, 0xfe, 0x59, 0xfe, 0x2d, 0xfe, 0xc4, 0xcd, 0xfe, 0xe7, + 0xfb, 0x17, 0xfe, 0xaf, 0xd8, 0x49, 0xdb, 0xee, 0xfd, 0x8e, 0xdf, 0xde, + 0xfd, 0x8f, 0x81, 0xbe, 0x58, 0x8a, 0xbb, 0xf9, 0x5f, 0xa1, 0x01, 0x7d, + 0x42, 0x56, 0xc8, 0x6b, 0x23, 0xc8, 0xe4, 0xda, 0x8f, 0xb8, 0x86, 0x69, + 0x11, 0x23, 0x29, 0xe4, 0xc7, 0x24, 0x4d, 0xe0, 0x91, 0xb3, 0x65, 0xb0, + 0xd2, 0x1e, 0x4c, 0x84, 0x76, 0xa3, 0x73, 0x85, 0x44, 0xb5, 0x10, 0x40, + 0x4a, 0x64, 0xea, 0x13, 0xf2, 0x3b, 0x45, 0x33, 0x68, 0x99, 0xa9, 0x0a, + 0xec, 0x70, 0x5f, 0xcb, 0x1b, 0xb7, 0x6f, 0x91, 0xf5, 0xdd, 0xec, 0x9f, + 0xe4, 0x4a, 0xed, 0xfe, 0x3c, 0x1e, 0xc7, 0xf8, 0xf0, 0x35, 0x6c, 0xbf, + 0x95, 0xf8, 0x68, 0xaf, 0xf4, 0x37, 0xfd, 0xd1, 0x33, 0x76, 0x5f, 0x54, + 0xfe, 0xd1, 0x7e, 0x44, 0xb6, 0x1b, 0xea, 0xbf, 0xe9, 0x0f, 0x28, 0x7f, + 0xef, 0x30, 0x6b, 0xcc, 0xe8, 0x9a, 0xb7, 0x04, 0x2d, 0xb2, 0x3d, 0xc3, + 0x27, 0xa4, 0xb4, 0x5a, 0xdf, 0x4d, 0x6b, 0x8d, 0x5f, 0x4d, 0x2b, 0x65, + 0x39, 0x2f, 0xa1, 0x4d, 0xca, 0x52, 0x94, 0x5d, 0x2f, 0xae, 0x77, 0x37, + 0x1e, 0x90, 0x84, 0x12, 0x11, 0x74, 0xa3, 0xd8, 0xef, 0x7f, 0xf8, 0x21, + 0xa7, 0xc8, 0x8e, 0xc2, 0xa2, 0xa2, 0x0a, 0x7b, 0x18, 0x67, 0x3e, 0xc6, + 0xf8, 0xaf, 0xb8, 0xe3, 0x14, 0x9e, 0xf1, 0x99, 0xa6, 0x2f, 0xa0, 0xdf, + 0x76, 0x48, 0x4e, 0x04, 0xbe, 0xda, 0x14, 0xf7, 0x19, 0xc8, 0xaf, 0x23, + 0x05, 0xcd, 0x08, 0x49, 0x5b, 0x7e, 0x07, 0x78, 0x3d, 0xda, 0x5f, 0x96, + 0x99, 0xba, 0x47, 0xd1, 0x36, 0xfe, 0xf1, 0x7d, 0xc6, 0x79, 0xa9, 0xf1, + 0xfb, 0x16, 0xda, 0xbd, 0xdb, 0xfe, 0x9a, 0x12, 0xdd, 0x4a, 0xfa, 0x5f, + 0xcd, 0x2f, 0xf9, 0x1f, 0x83, 0xfc, 0xbf, 0x50, 0x94, 0xec, 0x27, 0xe1, + 0x25, 0xf8, 0x48, 0x6c, 0xdd, 0xfe, 0x5f, 0xa5, 0xb4, 0x88, 0xc9, 0x6e, + 0x3e, 0x57, 0x7d, 0xf2, 0x4f, 0x3f, 0x0c, 0x7e, 0xca, 0xfc, 0xcf, 0xf7, + 0x82, 0xb7, 0x59, 0x1f, 0x76, 0x25, 0x06, 0x6d, 0x9d, 0x6f, 0xf1, 0x27, + 0x56, 0xda, 0x3d, 0x18, 0xd9, 0x4a, 0x5d, 0x29, 0x4a, 0x52, 0x94, 0xa5, + 0x29, 0x4b, 0xaa, 0xd3, 0x3a, 0xd8, 0x67, 0x55, 0xab, 0xd2, 0x0f, 0x4d, + 0xf4, 0x9a, 0xcd, 0x39, 0xd6, 0xe9, 0x74, 0xcb, 0xe9, 0x1c, 0x4e, 0x31, + 0xd1, 0xbe, 0x8d, 0x27, 0x83, 0x22, 0xe5, 0xf7, 0x58, 0x32, 0x9d, 0x17, + 0x67, 0xbf, 0xc9, 0x54, 0x10, 0xb9, 0x8a, 0x87, 0xac, 0x21, 0xd4, 0x2b, + 0x7d, 0x8b, 0x0e, 0x7d, 0xfb, 0xfc, 0x6f, 0xf6, 0x37, 0xf3, 0xf8, 0x2f, + 0xdf, 0xe1, 0x0a, 0x31, 0x7b, 0xba, 0xff, 0x00, 0xb9, 0xf6, 0x1b, 0x17, + 0x05, 0xd9, 0x61, 0x7c, 0x2c, 0x7f, 0x11, 0x36, 0xb2, 0x8d, 0xab, 0x1a, + 0x1a, 0x32, 0xb2, 0x8d, 0xe5, 0xa3, 0xf4, 0xe7, 0xa7, 0x34, 0x84, 0xe8, + 0x7a, 0xde, 0x9a, 0x37, 0xea, 0x5d, 0x29, 0x74, 0x43, 0x77, 0xa5, 0x69, + 0x69, 0x75, 0x67, 0x3a, 0x4b, 0xa4, 0x21, 0x09, 0xe8, 0x27, 0xc8, 0x35, + 0x1f, 0x4c, 0x10, 0x84, 0x26, 0x8d, 0x43, 0x49, 0xb7, 0xd9, 0xc0, 0xd3, + 0x6d, 0x92, 0x7b, 0xdf, 0xb2, 0xac, 0xe2, 0xaf, 0xce, 0x17, 0xc2, 0x7f, + 0xdf, 0xd0, 0x48, 0x5b, 0x0b, 0xb2, 0xc7, 0xe3, 0x7f, 0xaf, 0xf2, 0x53, + 0x69, 0xd4, 0x24, 0x98, 0xff, 0x00, 0x85, 0x7a, 0xf6, 0x3c, 0x93, 0x4e, + 0x7a, 0x68, 0xd9, 0x4a, 0x6c, 0x52, 0xff, 0x00, 0x13, 0xc7, 0x5d, 0x38, + 0xf4, 0x56, 0x93, 0xab, 0x63, 0x14, 0xfc, 0x1f, 0xdf, 0xa9, 0x68, 0xbb, + 0x89, 0x09, 0x16, 0xc2, 0xfe, 0x6d, 0x03, 0x43, 0x18, 0xf4, 0x7e, 0xa3, + 0x62, 0xd2, 0x74, 0xde, 0xa6, 0xfd, 0x07, 0xfc, 0x29, 0xe8, 0x5e, 0xb7, + 0xeb, 0x34, 0x4c, 0xcd, 0x7e, 0xcb, 0x55, 0xa2, 0xd5, 0x21, 0x06, 0x88, + 0x41, 0xff, 0x00, 0x2a, 0x09, 0x19, 0x85, 0xb0, 0x83, 0x18, 0xd8, 0xfd, + 0x54, 0x21, 0x6b, 0x3a, 0x5b, 0x39, 0xf4, 0xa6, 0x93, 0xaa, 0x13, 0x44, + 0xd5, 0x22, 0x10, 0x84, 0xd1, 0x22, 0x69, 0x0f, 0x1e, 0xaa, 0xf4, 0x9b, + 0x31, 0x28, 0xab, 0xce, 0x93, 0xa9, 0x08, 0x66, 0x20, 0xd3, 0x65, 0x98, + 0x0d, 0x10, 0x9f, 0xc2, 0x48, 0x5a, 0xb5, 0xa7, 0x98, 0xd0, 0xc6, 0x3f, + 0x5a, 0x97, 0x55, 0xe9, 0x2d, 0x61, 0x35, 0x84, 0xd4, 0x82, 0x23, 0x08, + 0x59, 0x23, 0xed, 0xa6, 0x48, 0x57, 0xfa, 0x14, 0x84, 0x99, 0x1f, 0x28, + 0xe4, 0xc6, 0x90, 0x6b, 0x49, 0xe9, 0xdd, 0x5e, 0xb7, 0xd0, 0xdd, 0x31, + 0x5f, 0x8f, 0xef, 0xa1, 0x68, 0x84, 0x20, 0xb0, 0x21, 0x99, 0x03, 0xd7, + 0x32, 0x90, 0x7f, 0xc0, 0x42, 0x5d, 0x05, 0x62, 0x09, 0x44, 0x92, 0x1e, + 0x86, 0x36, 0x31, 0xf5, 0x52, 0xf5, 0xdd, 0x2f, 0x4d, 0xeb, 0x9a, 0x4d, + 0x66, 0x9e, 0xc4, 0x66, 0xc3, 0x4b, 0x4b, 0x06, 0xe9, 0x4b, 0xd0, 0xa6, + 0x88, 0xac, 0xc7, 0x62, 0x22, 0x11, 0x8f, 0xcf, 0xa5, 0x4b, 0xa5, 0x29, + 0x7d, 0x3d, 0x9f, 0x06, 0xe4, 0xbc, 0x2e, 0x94, 0xc4, 0xc5, 0xaa, 0xf6, + 0xd2, 0x13, 0x48, 0x20, 0x83, 0xfe, 0x02, 0x5a, 0xc4, 0x85, 0xc1, 0x4b, + 0xa9, 0x8f, 0xd5, 0x65, 0xd3, 0x62, 0x94, 0xa4, 0x21, 0x23, 0x29, 0x4a, + 0x5e, 0x88, 0x4e, 0xbc, 0xbd, 0x61, 0x06, 0x87, 0xe8, 0xcd, 0x26, 0xa8, + 0x88, 0x84, 0x7a, 0xce, 0x8a, 0x58, 0x41, 0x22, 0x08, 0x24, 0x82, 0x09, + 0x25, 0x89, 0x04, 0xfa, 0x38, 0x9b, 0xeb, 0xa5, 0x68, 0x86, 0x11, 0xbe, + 0x94, 0xbd, 0x07, 0x1f, 0xaf, 0x41, 0x4c, 0x4a, 0x8a, 0x52, 0x94, 0xa5, + 0x18, 0xc6, 0x3f, 0x4d, 0x3a, 0x64, 0xc6, 0x99, 0xdc, 0x43, 0x66, 0x47, + 0xe4, 0xef, 0x33, 0xdc, 0x47, 0x7d, 0x2f, 0x06, 0x76, 0x19, 0x3b, 0x8a, + 0x9c, 0x12, 0xdd, 0x1e, 0x68, 0x63, 0x92, 0x94, 0xdf, 0x6d, 0x17, 0x82, + 0x10, 0x48, 0x90, 0x70, 0xf2, 0x26, 0x9e, 0xac, 0x7a, 0xb4, 0x44, 0xd8, + 0x26, 0x84, 0x41, 0x7a, 0x52, 0xee, 0x35, 0xd8, 0xdc, 0xd0, 0xdd, 0x94, + 0xa3, 0xda, 0x6d, 0xb3, 0x23, 0x7c, 0x9e, 0x6f, 0x58, 0x8e, 0xc4, 0x42, + 0xd6, 0x26, 0x47, 0x62, 0x4f, 0x16, 0x60, 0xdc, 0xdd, 0x02, 0xbb, 0x41, + 0x24, 0x48, 0x75, 0x77, 0x91, 0x34, 0xf6, 0xe9, 0x4c, 0x42, 0x28, 0xd2, + 0x2e, 0xf6, 0xdd, 0xfd, 0x8d, 0xe7, 0xf8, 0x22, 0xcf, 0x1f, 0x77, 0xfc, + 0x37, 0x81, 0x7b, 0x3b, 0xfa, 0x16, 0xf2, 0xf6, 0xd9, 0xe9, 0x41, 0xe3, + 0x53, 0xf8, 0x26, 0xc3, 0x63, 0x65, 0x62, 0x78, 0xd1, 0x46, 0xc6, 0xc6, + 0x3e, 0xa6, 0xd2, 0xdc, 0x61, 0xe0, 0x8a, 0xec, 0x84, 0xef, 0x26, 0x60, + 0xba, 0x92, 0x2f, 0x5d, 0xd3, 0x22, 0x54, 0xb6, 0xed, 0xf0, 0x36, 0xdc, + 0x9a, 0x30, 0xe4, 0x4e, 0xb7, 0x46, 0x01, 0x3d, 0x21, 0xb6, 0xbb, 0x58, + 0x87, 0x99, 0x97, 0xb1, 0xb7, 0x2b, 0xfb, 0x0d, 0xad, 0x8b, 0xdd, 0x90, + 0x52, 0xa5, 0xe1, 0x51, 0x23, 0x5b, 0xfc, 0x42, 0x3f, 0x1f, 0x2f, 0xfa, + 0x26, 0x7b, 0xbf, 0xc9, 0x0b, 0x02, 0x6a, 0xd9, 0x1f, 0xfa, 0x3c, 0x2a, + 0xff, 0x00, 0x7b, 0x88, 0x30, 0x97, 0xb9, 0x05, 0x67, 0xc0, 0xb6, 0xc8, + 0xfe, 0x82, 0xfb, 0x7f, 0x3f, 0xfa, 0x25, 0xbe, 0x8f, 0xda, 0x04, 0x99, + 0x37, 0x43, 0x63, 0x87, 0x95, 0xf6, 0x3b, 0x61, 0x78, 0x18, 0x79, 0xc9, + 0x5f, 0x22, 0x63, 0x16, 0x51, 0xce, 0x88, 0xb4, 0x7a, 0xe1, 0x04, 0x89, + 0x08, 0x34, 0x56, 0xcd, 0xcd, 0xcf, 0x28, 0xa4, 0x48, 0x59, 0xad, 0x1b, + 0x8a, 0x69, 0x05, 0xfe, 0x47, 0xe0, 0xe0, 0x21, 0xb1, 0xb1, 0x64, 0x41, + 0xd7, 0x8b, 0xee, 0xc6, 0xaf, 0xd8, 0x16, 0x0e, 0x43, 0x13, 0xc1, 0x5c, + 0x0e, 0x35, 0x4c, 0x8c, 0x56, 0x7e, 0xfb, 0x3f, 0xd9, 0x74, 0xef, 0xf4, + 0x92, 0xb7, 0xc3, 0x54, 0x25, 0x68, 0x2d, 0xc2, 0x8a, 0xdb, 0xc1, 0x00, + 0xc6, 0x32, 0x17, 0x4a, 0x30, 0xdd, 0x1a, 0x1e, 0x8d, 0xa5, 0xb9, 0x1c, + 0x64, 0x6f, 0xda, 0x37, 0xdd, 0x95, 0x38, 0x32, 0xd8, 0x6c, 0xb3, 0x46, + 0x6d, 0x51, 0x5b, 0x4d, 0x89, 0x5c, 0xbc, 0xc1, 0x32, 0xfa, 0x17, 0x45, + 0xd6, 0x0f, 0xcb, 0x83, 0x84, 0x22, 0x5b, 0x6b, 0xb5, 0xa8, 0xc6, 0x10, + 0x63, 0x91, 0x32, 0xd8, 0xec, 0x20, 0xee, 0x1d, 0x7e, 0x0e, 0x02, 0x2f, + 0x77, 0xfd, 0x18, 0x56, 0xbf, 0x6c, 0x1b, 0x84, 0x7d, 0x72, 0x45, 0x1c, + 0x7b, 0x60, 0x5d, 0xd3, 0xfa, 0x89, 0x5b, 0x24, 0x25, 0x36, 0x12, 0x63, + 0xad, 0xef, 0xb9, 0x1b, 0x12, 0xce, 0x08, 0x4d, 0x12, 0x59, 0xb1, 0x01, + 0x32, 0x41, 0x90, 0x3d, 0xd2, 0x1e, 0xfe, 0x1e, 0xc2, 0x5c, 0x8f, 0xb9, + 0xdd, 0x3e, 0xc4, 0x26, 0x94, 0xf7, 0x1f, 0x74, 0xf8, 0x7f, 0x81, 0x86, + 0xc6, 0xcb, 0x4c, 0x87, 0x45, 0xe4, 0x72, 0x13, 0x67, 0xd3, 0x2f, 0x5b, + 0x5a, 0x0d, 0x82, 0x59, 0x1e, 0xd3, 0x6f, 0xe9, 0x83, 0x26, 0xf4, 0x63, + 0x23, 0x49, 0x23, 0x54, 0x7c, 0x28, 0x26, 0x05, 0x72, 0xaf, 0x62, 0x6d, + 0xb3, 0x50, 0xdb, 0x59, 0x7a, 0x24, 0xc8, 0x8b, 0x43, 0x8d, 0x12, 0x1b, + 0x13, 0x1b, 0x03, 0x67, 0xd1, 0x5a, 0x5e, 0x93, 0x60, 0x61, 0x70, 0x4a, + 0x7f, 0xbc, 0x41, 0x3e, 0xea, 0xfb, 0xfe, 0x69, 0x0d, 0x9d, 0xfa, 0x7e, + 0x89, 0x87, 0x71, 0x4f, 0xf7, 0x81, 0x6c, 0x18, 0xde, 0xa9, 0x51, 0x91, + 0xb0, 0x7a, 0x34, 0x63, 0x8c, 0xee, 0x64, 0xdc, 0xf7, 0x0d, 0x7b, 0x96, + 0x44, 0x54, 0x86, 0xd3, 0xe4, 0x4e, 0xcc, 0x9f, 0x60, 0x7b, 0x6b, 0x8b, + 0xf8, 0xff, 0x00, 0xa6, 0xcd, 0x67, 0x54, 0xd5, 0x22, 0xfa, 0x15, 0x83, + 0x2c, 0xca, 0x13, 0x4d, 0x8f, 0xb3, 0xdb, 0xfd, 0xf2, 0x32, 0x89, 0x81, + 0xcf, 0x50, 0x84, 0xa8, 0x43, 0xd8, 0x6e, 0x05, 0xd8, 0x7b, 0x69, 0x94, + 0xe8, 0xcf, 0x26, 0x4f, 0x01, 0xdf, 0x44, 0x67, 0x59, 0x49, 0x76, 0x22, + 0x57, 0x45, 0xbe, 0xd3, 0x1b, 0x18, 0xc8, 0xb0, 0x5c, 0x34, 0x79, 0x3a, + 0x61, 0xa4, 0xba, 0x27, 0x52, 0x16, 0x23, 0x16, 0xe1, 0x6e, 0x64, 0xc6, + 0xee, 0xb0, 0x69, 0xcc, 0x0b, 0x3a, 0x2b, 0x43, 0xa6, 0x8e, 0x66, 0xff, + 0x00, 0x4c, 0x79, 0x63, 0x4e, 0x2d, 0x6c, 0x31, 0xc4, 0x48, 0x92, 0x36, + 0x5b, 0x7f, 0xef, 0x30, 0xab, 0xd9, 0x2f, 0x77, 0xfe, 0xfc, 0x98, 0x33, + 0xf0, 0x5f, 0xba, 0x34, 0x71, 0xf6, 0xf4, 0x12, 0x83, 0x60, 0x4d, 0x8f, + 0x3b, 0x8d, 0xb7, 0xff, 0x00, 0x88, 0xaa, 0x6c, 0xbf, 0xdf, 0x52, 0xf2, + 0x45, 0x29, 0x16, 0xcf, 0x43, 0x4d, 0xc0, 0xeb, 0xd8, 0x51, 0xb9, 0xaf, + 0xa8, 0x91, 0xcd, 0x12, 0x01, 0x58, 0x10, 0xc7, 0xd6, 0xa2, 0xad, 0x0d, + 0x9a, 0x8c, 0x44, 0x2a, 0x2e, 0xd0, 0x58, 0x9a, 0xc2, 0x69, 0x3a, 0x92, + 0x27, 0x57, 0xe6, 0xd1, 0xe8, 0x8c, 0xb1, 0xe5, 0x4c, 0x97, 0x91, 0xd5, + 0x79, 0xe3, 0xfd, 0xff, 0x00, 0x4c, 0x32, 0x93, 0x14, 0xca, 0x37, 0xf4, + 0x13, 0xf6, 0x7f, 0xac, 0x1d, 0xd2, 0x49, 0x19, 0xf3, 0xf7, 0x09, 0xdc, + 0x3e, 0x3f, 0xe9, 0x7f, 0xf8, 0x43, 0x9f, 0xe8, 0x8f, 0xf4, 0x48, 0x48, + 0xdb, 0xec, 0x43, 0x0d, 0xb8, 0xf8, 0x12, 0x4e, 0xc4, 0x1e, 0xc7, 0xf5, + 0x21, 0x96, 0xe2, 0x1a, 0x47, 0xf0, 0x6f, 0xb0, 0xa9, 0x50, 0xf0, 0x31, + 0xa3, 0x3f, 0x61, 0x8d, 0xb1, 0xef, 0xa1, 0xe7, 0x46, 0xe2, 0x48, 0xc6, + 0x2f, 0x7b, 0x4c, 0x90, 0x84, 0x17, 0x5a, 0x61, 0x12, 0xe9, 0x9b, 0x3c, + 0x1b, 0x91, 0xba, 0xf5, 0x44, 0x26, 0xd7, 0xf9, 0x18, 0xd4, 0x30, 0x24, + 0x86, 0x98, 0x1b, 0x43, 0x8a, 0xad, 0x09, 0x38, 0xc2, 0xf8, 0x3c, 0xd9, + 0x11, 0x16, 0xe8, 0x71, 0xe5, 0x60, 0x79, 0xcb, 0x22, 0x22, 0x21, 0x06, + 0xae, 0xa4, 0x21, 0x06, 0x88, 0x42, 0x69, 0x30, 0x42, 0x09, 0x08, 0xb6, + 0x0c, 0x7d, 0x74, 0x75, 0x0d, 0x39, 0x7d, 0xa8, 0xb8, 0x2f, 0xd9, 0x1f, + 0xf5, 0x02, 0x2c, 0xa1, 0x68, 0x4a, 0x10, 0x42, 0x37, 0xd6, 0x13, 0xa1, + 0x6d, 0xd4, 0xf8, 0xfb, 0xe8, 0xf4, 0x45, 0x0d, 0x88, 0x6d, 0x11, 0xa8, + 0x9e, 0x7e, 0x03, 0x4d, 0x61, 0x94, 0xdf, 0x71, 0x33, 0x19, 0x19, 0xd3, + 0x3c, 0x0c, 0xd8, 0xcc, 0x23, 0x54, 0x98, 0xd0, 0xf0, 0x26, 0xaa, 0xa3, + 0x75, 0x8f, 0x1a, 0x6e, 0x8e, 0x51, 0x8d, 0xb1, 0x55, 0xb8, 0x9a, 0x42, + 0x43, 0x4a, 0x77, 0x5d, 0x30, 0xe7, 0x49, 0xa4, 0x21, 0x91, 0xb3, 0x10, + 0x94, 0x63, 0x4b, 0x4a, 0x4e, 0xa6, 0x2b, 0xcf, 0x57, 0xf8, 0x3c, 0x31, + 0xba, 0xdd, 0x2f, 0x02, 0xc8, 0x98, 0xe9, 0x8c, 0x30, 0xec, 0x5d, 0x97, + 0xe0, 0xad, 0xf3, 0xa4, 0x21, 0x08, 0x41, 0x09, 0xa2, 0x13, 0xa2, 0x6b, + 0x34, 0x82, 0xdb, 0xa6, 0x63, 0x1e, 0xaf, 0x54, 0x26, 0xae, 0xf6, 0x45, + 0xfb, 0xfa, 0x56, 0xe2, 0xea, 0xd8, 0x16, 0xdd, 0x5b, 0x5d, 0x05, 0xa6, + 0x0a, 0x52, 0xc2, 0x31, 0xf9, 0x8b, 0xb0, 0xa9, 0x66, 0xcf, 0xb9, 0x7c, + 0x08, 0xe6, 0x0a, 0x3c, 0x7d, 0x82, 0x36, 0xa3, 0x15, 0x27, 0xe0, 0x34, + 0xd6, 0x28, 0x8c, 0xf0, 0xfe, 0xc5, 0x1c, 0xaa, 0x8f, 0x5a, 0xd9, 0xc8, + 0xdd, 0x17, 0xbe, 0x9b, 0xc3, 0xdc, 0x7b, 0x10, 0x61, 0x3c, 0x8b, 0x2a, + 0xd2, 0x8d, 0xc0, 0xf1, 0xf7, 0x16, 0xda, 0xde, 0xa9, 0xd1, 0xae, 0x07, + 0xa4, 0x9d, 0x6f, 0xb3, 0xfe, 0x46, 0x6e, 0x9d, 0xcb, 0x0b, 0x10, 0xb2, + 0xc8, 0xc0, 0xfc, 0x8d, 0xb1, 0x93, 0xfc, 0x2f, 0xc1, 0x09, 0xa4, 0x11, + 0x08, 0x4d, 0x21, 0x3d, 0x35, 0xbf, 0x46, 0xe1, 0x8f, 0xa1, 0xef, 0xaa, + 0xdb, 0xa3, 0x7a, 0x43, 0xfc, 0xfa, 0x16, 0x99, 0xea, 0xd9, 0x10, 0xfa, + 0x76, 0xad, 0x1e, 0xb4, 0x65, 0xe8, 0x68, 0x78, 0x4f, 0xf7, 0xfb, 0xf6, + 0x39, 0xdc, 0x4c, 0x41, 0xcc, 0x0d, 0xa6, 0xff, 0x00, 0x82, 0xf7, 0x13, + 0xec, 0x21, 0x29, 0x7a, 0x1b, 0x6f, 0x61, 0x85, 0xa6, 0xc6, 0x62, 0xd9, + 0xe5, 0xa2, 0xc8, 0xa2, 0xc0, 0xf0, 0xab, 0x1f, 0x26, 0x0e, 0x06, 0xc3, + 0xa6, 0xf4, 0xad, 0x36, 0x05, 0x8b, 0x4d, 0xa8, 0xfa, 0xdd, 0xff, 0x00, + 0xb7, 0x0c, 0xf2, 0x28, 0xdf, 0x91, 0x39, 0x30, 0xdc, 0x6c, 0xd1, 0xc7, + 0xbe, 0xd2, 0xd1, 0x13, 0xd6, 0x7d, 0x29, 0x8f, 0x0f, 0x5d, 0xcc, 0x63, + 0xe8, 0xdc, 0xfa, 0xcf, 0xb8, 0xf7, 0xe8, 0x4b, 0xd0, 0xdb, 0xd1, 0xe8, + 0xf5, 0xe3, 0xa3, 0xd6, 0x8f, 0x62, 0xf4, 0x27, 0x08, 0x32, 0x51, 0xe0, + 0x81, 0xc1, 0x0e, 0x08, 0x3d, 0xd2, 0x14, 0xf6, 0x91, 0xb6, 0xce, 0xc2, + 0x94, 0xa3, 0x1e, 0x4c, 0x98, 0x9e, 0x34, 0x7b, 0x18, 0xb0, 0xd0, 0x6b, + 0x86, 0x39, 0x46, 0xf0, 0x73, 0x47, 0x8a, 0x3d, 0x77, 0x8d, 0x68, 0xb3, + 0xa4, 0xe9, 0x43, 0x61, 0x7b, 0x89, 0xa6, 0xb1, 0xfe, 0xc2, 0xd3, 0x60, + 0xc1, 0xba, 0xf6, 0xbf, 0xe6, 0x19, 0x83, 0x15, 0x68, 0x84, 0x2c, 0x3c, + 0x0d, 0xa5, 0x8f, 0xb4, 0x5f, 0xc7, 0x7a, 0xf2, 0x18, 0xfa, 0x37, 0x3e, + 0xb3, 0xa8, 0x7b, 0xf4, 0x2f, 0x43, 0x6b, 0xd0, 0x90, 0xf5, 0x63, 0x7a, + 0x52, 0xc1, 0x1b, 0x89, 0x10, 0xd5, 0xbd, 0xbf, 0xb5, 0xd2, 0x97, 0xd8, + 0x1e, 0xa0, 0xc5, 0xd2, 0x94, 0x63, 0xdc, 0x4e, 0x63, 0x4e, 0x0c, 0x5c, + 0xa5, 0x93, 0x3c, 0x89, 0xdc, 0x9c, 0x97, 0x35, 0x8f, 0x3b, 0x90, 0x90, + 0x6a, 0xef, 0x08, 0xa6, 0xe2, 0x45, 0xd7, 0x1a, 0xd3, 0x71, 0xb0, 0xbd, + 0xf5, 0x18, 0xfa, 0xff, 0x00, 0xdd, 0xe1, 0xe8, 0x5b, 0xd1, 0x60, 0x4f, + 0x91, 0x3c, 0xc8, 0x36, 0x46, 0x1a, 0xfb, 0x5d, 0x4b, 0xf8, 0x2f, 0x6d, + 0x79, 0x8c, 0x7d, 0x1b, 0x9e, 0xab, 0xa3, 0x61, 0xca, 0xf5, 0x13, 0x0e, + 0xbd, 0xeb, 0x47, 0xa5, 0x1b, 0x12, 0xa0, 0x98, 0xd1, 0x0b, 0x25, 0x85, + 0x60, 0x67, 0x0e, 0x27, 0xf7, 0xd1, 0xc8, 0xf6, 0x1a, 0x40, 0xc6, 0xca, + 0x32, 0x8d, 0x96, 0x56, 0x37, 0x0d, 0xc7, 0x04, 0xc5, 0x80, 0xae, 0xe8, + 0x53, 0x93, 0xd8, 0xf7, 0x36, 0xc8, 0xb2, 0xd0, 0xf5, 0xfe, 0x08, 0x6c, + 0x6e, 0x2d, 0x37, 0x26, 0xbb, 0x88, 0xe0, 0x35, 0xc1, 0xc8, 0xfd, 0x0f, + 0xf5, 0x78, 0x66, 0xfd, 0x85, 0x1b, 0x15, 0x6f, 0x2c, 0x46, 0xcc, 0x0c, + 0x39, 0x97, 0xf8, 0xe5, 0xfa, 0x94, 0xbe, 0x92, 0xd9, 0xeb, 0xb7, 0x47, + 0xd1, 0xbb, 0x55, 0xd0, 0xd1, 0x45, 0x9e, 0x84, 0xf4, 0xd7, 0xd0, 0xf9, + 0x5a, 0x31, 0xeb, 0x40, 0xc3, 0x62, 0x4c, 0x6b, 0xc1, 0x49, 0xa6, 0xdf, + 0xef, 0xdf, 0x56, 0x39, 0x77, 0x1b, 0x62, 0x1e, 0x94, 0x7d, 0xd8, 0x8a, + 0xd6, 0x93, 0x50, 0x46, 0x3e, 0xe1, 0xe2, 0x3d, 0xc8, 0x98, 0xe2, 0x37, + 0x32, 0xf6, 0x2a, 0x50, 0x6b, 0xed, 0x97, 0xa1, 0x8e, 0xf4, 0x2d, 0x17, + 0x09, 0x8f, 0xb0, 0x63, 0xdf, 0xd0, 0xff, 0x00, 0x07, 0x86, 0x2e, 0x48, + 0x3d, 0x84, 0xe8, 0xae, 0xc6, 0x19, 0x63, 0xd6, 0x87, 0xfb, 0xbf, 0x97, + 0xfc, 0x75, 0xaa, 0xe0, 0x6a, 0x0f, 0xa3, 0x77, 0x41, 0xed, 0xa3, 0x36, + 0x09, 0x9e, 0x9b, 0xd0, 0xf5, 0xde, 0xeb, 0xda, 0x38, 0xd1, 0xac, 0x74, + 0x2c, 0x0d, 0x1b, 0xad, 0x61, 0x93, 0x7f, 0x2b, 0x56, 0xe6, 0x44, 0xea, + 0x4d, 0x0f, 0x5f, 0x08, 0x42, 0x0a, 0xb7, 0x13, 0xb1, 0x8a, 0x31, 0x3a, + 0x25, 0x83, 0xef, 0x9e, 0x86, 0xe6, 0x86, 0xdb, 0x21, 0x96, 0x4b, 0x73, + 0x71, 0xbb, 0xb0, 0xf7, 0xa7, 0xd9, 0x09, 0xe8, 0xb5, 0xa2, 0x51, 0x31, + 0x6b, 0xd0, 0xfd, 0x0d, 0xd7, 0xf9, 0x86, 0x40, 0xd7, 0x63, 0x2b, 0x0c, + 0x48, 0x4c, 0x61, 0xf6, 0x1b, 0xee, 0xfe, 0x7f, 0x90, 0xfb, 0xeb, 0x3f, + 0x4e, 0xfe, 0x83, 0xc5, 0xac, 0x72, 0x27, 0x83, 0xf5, 0x37, 0x86, 0x3e, + 0x9d, 0xa1, 0xe9, 0xc7, 0x42, 0x38, 0x36, 0x1a, 0xd5, 0x22, 0xf7, 0x6a, + 0xd5, 0x15, 0xa1, 0xb8, 0xd1, 0x7e, 0xd9, 0xbe, 0x98, 0xd5, 0x8d, 0x08, + 0x21, 0x6c, 0x61, 0xef, 0xb2, 0xe9, 0x81, 0x65, 0x10, 0x28, 0xc6, 0xb6, + 0x02, 0x0b, 0x93, 0xf3, 0xd3, 0xb1, 0x59, 0x4a, 0x53, 0x7d, 0x32, 0x83, + 0x6e, 0x8f, 0xd0, 0xda, 0xf6, 0x7e, 0x19, 0x9e, 0x4a, 0x90, 0xcc, 0xd0, + 0x87, 0x1b, 0x23, 0xfc, 0x8f, 0xd4, 0xbe, 0xbc, 0xdd, 0x3b, 0xf5, 0x42, + 0x5d, 0x5c, 0x78, 0x18, 0xf5, 0x0b, 0xd2, 0xde, 0xc6, 0x3e, 0x9d, 0xa1, + 0xfa, 0x8d, 0x86, 0x9f, 0x7d, 0x7f, 0xae, 0xa9, 0x7e, 0x99, 0xb7, 0x59, + 0xa2, 0x43, 0x61, 0xb5, 0xf2, 0xcb, 0x79, 0xd1, 0xb9, 0x08, 0x7a, 0x44, + 0x81, 0xc2, 0xc0, 0x91, 0x9d, 0x4b, 0xab, 0x34, 0x85, 0x88, 0x63, 0xe7, + 0xd0, 0x4a, 0xbe, 0xcf, 0xc3, 0x26, 0xc3, 0xb8, 0x59, 0x44, 0x6c, 0x4a, + 0xe0, 0xb4, 0x37, 0x61, 0xb1, 0xf7, 0x7a, 0x5e, 0x8b, 0xa5, 0xd2, 0xfa, + 0xdb, 0x0f, 0x1d, 0x41, 0x1b, 0xf5, 0x43, 0xd5, 0x50, 0x94, 0xec, 0x68, + 0x5a, 0x5f, 0x43, 0x73, 0x18, 0xfa, 0x76, 0x47, 0xac, 0xd2, 0x74, 0xc2, + 0x72, 0x2c, 0xad, 0x5e, 0xdf, 0x67, 0xfd, 0x6a, 0xac, 0x99, 0x30, 0x4d, + 0x27, 0x41, 0x8d, 0x68, 0x59, 0xef, 0x8c, 0xaa, 0x60, 0xb1, 0x2b, 0x92, + 0x79, 0x39, 0xc9, 0xc1, 0x21, 0x67, 0x44, 0xb4, 0x5b, 0x74, 0x21, 0x8b, + 0x5a, 0x5a, 0x9f, 0x3e, 0x87, 0xe5, 0x5f, 0xd9, 0x0d, 0x46, 0x54, 0xa2, + 0xdd, 0x3b, 0x44, 0x1b, 0xef, 0x7f, 0xc9, 0xdd, 0x69, 0x3e, 0x84, 0x6f, + 0xd5, 0x69, 0x93, 0x26, 0xdd, 0x27, 0x90, 0x31, 0x7a, 0x3c, 0x87, 0xd5, + 0xb0, 0x3d, 0x1f, 0x42, 0x17, 0x46, 0xf8, 0x36, 0x7f, 0xbb, 0x75, 0x5a, + 0xdd, 0xe0, 0x5a, 0x34, 0x2d, 0x5a, 0x83, 0x43, 0x42, 0x30, 0x37, 0xbe, + 0xe6, 0xc3, 0x70, 0x2a, 0x4f, 0x61, 0x3e, 0x45, 0x97, 0x91, 0x35, 0x14, + 0x56, 0xa9, 0xd5, 0x5c, 0xc1, 0x4b, 0xa2, 0x2d, 0x1a, 0xab, 0xa1, 0x8f, + 0x9f, 0x43, 0x73, 0xdd, 0x18, 0xb8, 0x24, 0xf4, 0xdf, 0x08, 0x5e, 0x44, + 0xa6, 0xc6, 0xe1, 0xef, 0xd6, 0xff, 0x00, 0xaf, 0xe5, 0x2c, 0x74, 0x91, + 0xbf, 0x58, 0x44, 0x68, 0x83, 0x60, 0x6a, 0xa3, 0xc3, 0x37, 0x46, 0xcf, + 0xd1, 0xe4, 0x3e, 0xad, 0x9d, 0x5e, 0xb3, 0x4e, 0x3a, 0x12, 0xc0, 0x94, + 0x6d, 0x6a, 0xf7, 0x4c, 0xe7, 0x45, 0xf9, 0x83, 0x50, 0xe0, 0x7a, 0x3d, + 0x1c, 0xd1, 0xe8, 0xa4, 0xe6, 0xef, 0x72, 0xb6, 0x23, 0xbb, 0x89, 0x41, + 0x89, 0xe4, 0xaa, 0x28, 0xb1, 0x7e, 0x3a, 0x78, 0x16, 0x07, 0xa2, 0xd1, + 0x0b, 0x2f, 0xe3, 0x43, 0x1f, 0xa0, 0x97, 0xdd, 0x5f, 0x91, 0x5d, 0x1c, + 0x9b, 0x0a, 0xec, 0xc5, 0x20, 0x86, 0xe1, 0xb2, 0xf7, 0x7f, 0x85, 0xfc, + 0x0b, 0xe9, 0x70, 0xe9, 0x46, 0xfd, 0x77, 0x8f, 0x82, 0x93, 0x28, 0xa9, + 0x6f, 0x81, 0x4a, 0x21, 0x1d, 0xa3, 0xd0, 0xc5, 0xe8, 0x72, 0x18, 0xfa, + 0x76, 0x7d, 0xba, 0x66, 0xa8, 0x44, 0xba, 0x6d, 0x0c, 0x95, 0xba, 0x56, + 0x79, 0x12, 0x36, 0x5a, 0xe4, 0xd3, 0xec, 0x6e, 0x85, 0xb6, 0xaf, 0x47, + 0xd1, 0x87, 0xfa, 0xe0, 0xdd, 0x91, 0xc6, 0x24, 0xb7, 0x47, 0x38, 0x2e, + 0x07, 0xb9, 0x15, 0x31, 0x57, 0x8e, 0x84, 0x51, 0x65, 0x13, 0x56, 0x23, + 0x93, 0x1b, 0x14, 0x54, 0x3f, 0x41, 0x3e, 0xd7, 0xe5, 0x19, 0x04, 0x4b, + 0x7d, 0x52, 0x13, 0xce, 0x46, 0xd8, 0xde, 0xf7, 0xfe, 0x97, 0x4d, 0xf5, + 0xaf, 0x5f, 0x0b, 0xa2, 0x09, 0x0a, 0x15, 0x15, 0x0f, 0x2c, 0x0d, 0x23, + 0x91, 0xb1, 0xa4, 0x44, 0xdd, 0x12, 0x28, 0x27, 0x96, 0x25, 0x4c, 0x7d, + 0x36, 0xd1, 0x75, 0x72, 0x1f, 0xad, 0xad, 0xc5, 0xab, 0x44, 0x3b, 0xd0, + 0x4b, 0x23, 0xc0, 0x9b, 0x8d, 0x7a, 0x58, 0xd6, 0xac, 0xc5, 0xa8, 0xeb, + 0x9d, 0x26, 0xd3, 0xd8, 0xbb, 0x0d, 0xc2, 0xe4, 0xb9, 0x46, 0x2a, 0xf1, + 0xd4, 0xaf, 0x4c, 0x0d, 0x89, 0xa5, 0x82, 0x24, 0xc0, 0xdc, 0xf2, 0x13, + 0x49, 0x57, 0x5d, 0x86, 0x0d, 0x78, 0xfc, 0xa3, 0x72, 0x84, 0xa2, 0xa2, + 0x49, 0x09, 0x36, 0x84, 0x9b, 0x08, 0x2e, 0x4f, 0xba, 0xfe, 0x97, 0xf2, + 0xb8, 0x5d, 0x28, 0x46, 0xd8, 0xf2, 0x17, 0x60, 0xed, 0x02, 0x39, 0x28, + 0xa1, 0x34, 0xd5, 0x12, 0x5b, 0xe8, 0xab, 0x89, 0xd3, 0xc3, 0x36, 0x17, + 0x57, 0x21, 0xf5, 0xef, 0xd0, 0x97, 0x61, 0x22, 0x41, 0xaa, 0x22, 0x63, + 0x44, 0x26, 0x9b, 0xa6, 0x8d, 0xf7, 0x37, 0x5e, 0x04, 0x35, 0xa3, 0xd1, + 0xea, 0xc5, 0xc3, 0xd8, 0x6b, 0xb1, 0x5c, 0x95, 0x8b, 0x91, 0x5e, 0xc2, + 0xd9, 0x0f, 0x94, 0x6d, 0x6a, 0xb4, 0x64, 0x26, 0xac, 0xbd, 0xda, 0xf9, + 0x14, 0xa5, 0x30, 0x95, 0xc8, 0x6d, 0x85, 0xfa, 0xff, 0x00, 0xe8, 0xd0, + 0x89, 0xd8, 0x86, 0x17, 0x17, 0xd5, 0x46, 0xb4, 0xef, 0xdc, 0x28, 0xb6, + 0xae, 0x3b, 0xa1, 0x1d, 0x64, 0xca, 0x2b, 0x7a, 0x2d, 0x47, 0x83, 0x91, + 0xb9, 0x10, 0x90, 0x92, 0xd9, 0x09, 0x0a, 0x5c, 0x1f, 0x7d, 0xfd, 0x2f, + 0x52, 0x3f, 0x5b, 0x87, 0x4a, 0x1d, 0xd1, 0xc0, 0x27, 0x17, 0x9d, 0x1b, + 0xa5, 0x29, 0x78, 0x12, 0x72, 0x55, 0x05, 0x5e, 0xc0, 0x87, 0x53, 0xdd, + 0x09, 0xdd, 0x24, 0x2f, 0x43, 0x13, 0x26, 0x3d, 0x61, 0x0d, 0xba, 0x78, + 0x4d, 0x60, 0x93, 0xe0, 0xb0, 0x6e, 0xef, 0xd5, 0x7a, 0x21, 0xc6, 0x46, + 0x41, 0xe0, 0x7a, 0x35, 0xa6, 0x3e, 0xd0, 0xeb, 0x13, 0x4c, 0xca, 0x74, + 0x6d, 0x32, 0xd1, 0x52, 0x0e, 0x19, 0xbb, 0xc6, 0x90, 0xa2, 0x21, 0x3a, + 0x19, 0xba, 0x16, 0x50, 0xa2, 0x45, 0x62, 0xce, 0xe5, 0x13, 0x96, 0x24, + 0xbe, 0xa3, 0xee, 0x43, 0x69, 0x04, 0xa5, 0x7d, 0x81, 0xfe, 0xcd, 0x86, + 0xd7, 0x94, 0x85, 0x67, 0x71, 0xf6, 0x43, 0x94, 0x90, 0x95, 0xc9, 0x32, + 0x6c, 0x4e, 0xe2, 0x88, 0xdc, 0x7d, 0xf7, 0xf5, 0xe8, 0x21, 0x22, 0x11, + 0xe8, 0x84, 0x1b, 0x2d, 0xfd, 0x4e, 0x1d, 0x28, 0xdd, 0x2a, 0x1b, 0xa2, + 0x4d, 0xec, 0x86, 0x9a, 0xe0, 0xc9, 0x9d, 0x32, 0xb7, 0x15, 0xc1, 0x11, + 0x36, 0x10, 0x42, 0x26, 0x1f, 0x94, 0x43, 0x55, 0x09, 0xf7, 0xd1, 0xa9, + 0xb1, 0xd8, 0x52, 0xf1, 0xa2, 0x97, 0xd2, 0xf5, 0x56, 0xb0, 0x41, 0x77, + 0x15, 0x22, 0x9f, 0xae, 0xd0, 0xd3, 0x3d, 0xf4, 0x9a, 0x7c, 0x4f, 0xf6, + 0x76, 0x06, 0xd7, 0x22, 0x63, 0x78, 0x29, 0x57, 0x61, 0x38, 0x3d, 0x77, + 0x84, 0x42, 0xd1, 0x2e, 0xfa, 0x25, 0xa3, 0x10, 0xcc, 0xa9, 0x0d, 0xb6, + 0x36, 0x29, 0x46, 0xd1, 0x8d, 0xa2, 0x8d, 0x9b, 0x56, 0x31, 0x4c, 0x59, + 0x3c, 0x1f, 0xbf, 0x25, 0x13, 0x2d, 0xb5, 0xac, 0x1d, 0x8e, 0x66, 0xf9, + 0x14, 0xba, 0x52, 0xec, 0x51, 0xf7, 0x5f, 0xd2, 0xeb, 0x4a, 0xb8, 0x24, + 0x48, 0x58, 0x2e, 0x88, 0xde, 0x2f, 0x6e, 0x8d, 0x18, 0xfb, 0x46, 0xeb, + 0x82, 0x7a, 0x1c, 0x3a, 0x50, 0xd2, 0x6d, 0x8d, 0x9c, 0x0d, 0xf8, 0x31, + 0xda, 0x37, 0x70, 0x78, 0x84, 0x92, 0xd8, 0x42, 0x46, 0x2b, 0x26, 0xe3, + 0x48, 0x61, 0x6c, 0x5e, 0x50, 0x92, 0x13, 0xcd, 0x89, 0xf9, 0x25, 0xba, + 0x2b, 0x72, 0x9a, 0x1b, 0x04, 0xbb, 0x33, 0x25, 0x13, 0x01, 0xfa, 0x2a, + 0x69, 0x89, 0xe8, 0xd9, 0xe4, 0x67, 0x82, 0xf3, 0xc7, 0xef, 0xec, 0x6d, + 0x63, 0xfa, 0xff, 0x00, 0x42, 0x7a, 0x60, 0xd4, 0x38, 0xa1, 0xdd, 0x34, + 0x7e, 0x46, 0xc2, 0x2d, 0x6f, 0x32, 0xbe, 0x76, 0x7e, 0xfa, 0x2d, 0xf3, + 0xa1, 0xf8, 0xf4, 0x9a, 0x32, 0x33, 0xdc, 0x94, 0xfe, 0xb1, 0xe4, 0xbe, + 0x04, 0x9b, 0xca, 0x37, 0x23, 0x16, 0x06, 0xb3, 0x81, 0xd3, 0x6f, 0x84, + 0x5b, 0xa4, 0xd5, 0xb4, 0x84, 0x27, 0x20, 0x97, 0x91, 0xbb, 0xb0, 0xb9, + 0x3d, 0xca, 0x52, 0x96, 0xa3, 0x6f, 0xc0, 0x8f, 0x81, 0x35, 0xc9, 0x6f, + 0xb2, 0x18, 0xe4, 0xf2, 0x51, 0x3b, 0x61, 0x37, 0x2c, 0x48, 0x16, 0x7b, + 0x66, 0x05, 0x58, 0x43, 0x73, 0x66, 0x25, 0x0d, 0xb0, 0x7d, 0xd7, 0xf4, + 0xba, 0xf7, 0xd2, 0x94, 0xa5, 0x13, 0x9d, 0x09, 0x25, 0xb7, 0x4b, 0x49, + 0x8d, 0x19, 0xe2, 0x36, 0x29, 0x70, 0x47, 0xaf, 0x1d, 0x28, 0x8b, 0x73, + 0xdb, 0x5c, 0x93, 0x5d, 0x8e, 0x4b, 0x49, 0xd1, 0x07, 0xba, 0x45, 0x83, + 0x2f, 0x29, 0xda, 0x64, 0xa5, 0xd6, 0xdb, 0x80, 0xeb, 0x53, 0x03, 0xdd, + 0x21, 0x49, 0x58, 0xf8, 0x18, 0xd4, 0xf1, 0x04, 0x7d, 0xe3, 0xe8, 0x21, + 0x86, 0x3a, 0x99, 0x98, 0x62, 0xfa, 0x98, 0x26, 0x5e, 0xe4, 0x7e, 0xb0, + 0xc5, 0x4d, 0x3e, 0xe9, 0x97, 0xd0, 0xdb, 0x3f, 0xd0, 0xbf, 0x95, 0x59, + 0x59, 0x49, 0x7d, 0x36, 0x36, 0x61, 0xfd, 0x50, 0xcc, 0x15, 0x79, 0xbb, + 0x89, 0xc5, 0x6b, 0xe8, 0x24, 0x6f, 0xf0, 0x3f, 0xd8, 0x99, 0xde, 0xf0, + 0xc7, 0x6b, 0xfb, 0x7f, 0xe1, 0xb2, 0xb4, 0xbe, 0x9f, 0xba, 0x6e, 0x4f, + 0xcc, 0xfc, 0x0f, 0xba, 0xdd, 0xfd, 0x4f, 0xaa, 0xc7, 0xb9, 0x4d, 0xc9, + 0x9b, 0x39, 0xf2, 0x87, 0x48, 0xb7, 0xe1, 0x36, 0x21, 0x12, 0x6d, 0xa2, + 0x25, 0x4f, 0xc8, 0x99, 0x7b, 0xe9, 0x57, 0x27, 0xb9, 0xce, 0x0d, 0x82, + 0xd5, 0xe1, 0x19, 0x5c, 0x15, 0xf6, 0xe8, 0x0d, 0x45, 0x3b, 0x14, 0xf7, + 0x2a, 0x48, 0x85, 0x55, 0x49, 0x79, 0x31, 0x0b, 0x5e, 0x36, 0x11, 0x80, + 0x1e, 0xd9, 0x13, 0x67, 0x3f, 0xb7, 0x91, 0xc9, 0x84, 0x9f, 0xd8, 0xbf, + 0x03, 0x26, 0xf6, 0xec, 0x73, 0x22, 0x73, 0x48, 0x76, 0xe5, 0xaf, 0xae, + 0xf0, 0xcd, 0x09, 0x28, 0xf7, 0x13, 0x25, 0x74, 0xbb, 0xe4, 0x7a, 0xc7, + 0xd6, 0x5f, 0xa7, 0xfb, 0x37, 0xe3, 0xdc, 0xbf, 0x54, 0xda, 0x07, 0xf5, + 0x42, 0x2f, 0xe1, 0x99, 0x40, 0x84, 0xb0, 0x48, 0x4b, 0xb6, 0x94, 0xdc, + 0xff, 0x00, 0x98, 0x5d, 0x08, 0x20, 0x4b, 0xcb, 0x82, 0x77, 0x2d, 0xe3, + 0xf7, 0xb1, 0x85, 0x29, 0xdd, 0xe5, 0xfe, 0x8d, 0xa2, 0x1f, 0x0f, 0x6f, + 0xf9, 0xf4, 0x14, 0xa7, 0xc2, 0x61, 0xae, 0x84, 0x53, 0x45, 0xeb, 0x5a, + 0x42, 0x22, 0x06, 0x87, 0xd0, 0x87, 0xbf, 0x44, 0x6e, 0x41, 0xaf, 0x22, + 0x1b, 0xa3, 0x67, 0x7f, 0x09, 0x8b, 0x57, 0x51, 0xb4, 0x89, 0x22, 0x10, + 0x41, 0x28, 0x66, 0x9e, 0x7b, 0x8b, 0xee, 0x5e, 0xc6, 0x02, 0x0d, 0x85, + 0x72, 0x8c, 0xb7, 0x32, 0x8d, 0xf8, 0x29, 0xbd, 0xc6, 0xcd, 0xac, 0x8d, + 0x67, 0x24, 0x5d, 0x84, 0xe2, 0x41, 0x3e, 0x48, 0x4f, 0xb0, 0xa9, 0xc0, + 0x92, 0x49, 0x78, 0x70, 0x7b, 0xc6, 0x65, 0x3e, 0x45, 0x4e, 0x93, 0x9b, + 0x46, 0x4c, 0x95, 0xf7, 0x43, 0x7e, 0xef, 0x2d, 0xfe, 0xc2, 0xd2, 0x30, + 0x42, 0x94, 0xe0, 0xdc, 0x5b, 0x12, 0xec, 0x5c, 0x14, 0x1e, 0x34, 0xa3, + 0x56, 0xec, 0xd8, 0x1f, 0x94, 0x6f, 0x29, 0xf9, 0x36, 0xb6, 0xdf, 0xb2, + 0xfd, 0x89, 0xf2, 0x7b, 0xb3, 0x68, 0x97, 0xdc, 0x58, 0x57, 0xcf, 0x6c, + 0x7e, 0x04, 0xf4, 0x53, 0x81, 0x66, 0xcd, 0xf8, 0xff, 0x00, 0x21, 0x39, + 0xdc, 0x1f, 0xd4, 0xbe, 0x6e, 0xf3, 0x57, 0xf7, 0xfa, 0x2e, 0xcd, 0x35, + 0xdd, 0xcf, 0xc4, 0x36, 0x4f, 0xb0, 0xba, 0xb0, 0x9b, 0x8c, 0x8f, 0xfd, + 0xb7, 0xcf, 0xec, 0x4b, 0x6b, 0x3f, 0xd3, 0xfe, 0x31, 0x0b, 0x6a, 0x5f, + 0x87, 0xfa, 0xfb, 0x96, 0x51, 0x3f, 0x25, 0x6f, 0x08, 0xc0, 0x83, 0x33, + 0x3d, 0xd8, 0x99, 0xac, 0xdc, 0x5a, 0x88, 0x35, 0xa3, 0xec, 0x18, 0xd7, + 0x66, 0xee, 0xf3, 0x81, 0xad, 0xb5, 0xee, 0xef, 0xe8, 0xec, 0xcf, 0xa7, + 0xee, 0x98, 0xe6, 0xfd, 0x31, 0xf8, 0x83, 0x6a, 0xf5, 0xf9, 0x13, 0x9d, + 0x62, 0x61, 0x19, 0xe9, 0xf8, 0x9f, 0xf4, 0xfe, 0x9f, 0x8a, 0x24, 0x41, + 0xe1, 0x53, 0x01, 0x54, 0x20, 0x85, 0x2f, 0xa2, 0xd0, 0xd3, 0x27, 0x45, + 0x68, 0x84, 0x21, 0x0d, 0x58, 0x95, 0xec, 0xf5, 0x9f, 0xc6, 0xb2, 0x21, + 0x09, 0x16, 0xa8, 0x98, 0xe9, 0xd4, 0x76, 0x07, 0xb1, 0xc6, 0x1e, 0xe6, + 0x6e, 0x59, 0xba, 0xa3, 0x7d, 0xe3, 0x7d, 0xc6, 0x19, 0xa2, 0x69, 0x98, + 0x2c, 0xd8, 0xd8, 0xac, 0x53, 0xdc, 0xad, 0x32, 0x8c, 0x86, 0xd1, 0x3b, + 0xd8, 0x7b, 0xcf, 0x06, 0xea, 0x6c, 0xb4, 0x14, 0x39, 0xc1, 0x5d, 0x16, + 0xc2, 0xc8, 0x94, 0xc8, 0xd5, 0x2f, 0x2a, 0x5e, 0xec, 0xa6, 0xef, 0xcb, + 0x1e, 0x6b, 0x67, 0xf5, 0x1f, 0x70, 0xa5, 0x84, 0x52, 0x16, 0x0d, 0x90, + 0xbc, 0x08, 0x2b, 0x2d, 0x90, 0xc1, 0xba, 0x3c, 0xd4, 0x5d, 0xac, 0x4e, + 0x94, 0x37, 0xcc, 0x60, 0xab, 0xfc, 0xc7, 0xb1, 0x95, 0x9d, 0x0b, 0xb0, + 0xc2, 0xdd, 0x76, 0x79, 0x15, 0xc2, 0xb8, 0x7f, 0xc7, 0xc1, 0x53, 0x93, + 0xec, 0xff, 0x00, 0x63, 0x9b, 0x8e, 0x11, 0xb4, 0x24, 0x43, 0x91, 0x8e, + 0x22, 0x26, 0xe0, 0xd6, 0x60, 0x75, 0x86, 0x34, 0xe9, 0x17, 0x22, 0x4c, + 0x28, 0x24, 0x96, 0x0c, 0xd0, 0x7f, 0x99, 0x16, 0x01, 0xb9, 0x85, 0x78, + 0xd1, 0xaa, 0x8c, 0x0d, 0x5e, 0x8b, 0x46, 0xc2, 0xd0, 0x42, 0xfa, 0x33, + 0x46, 0xd2, 0x12, 0x37, 0x17, 0x5a, 0x56, 0xcc, 0x4c, 0xb7, 0x13, 0x84, + 0x8f, 0x61, 0xfa, 0x2c, 0x7d, 0x33, 0x49, 0xd3, 0x35, 0xb8, 0xfb, 0xf4, + 0xb3, 0x28, 0xdc, 0x8b, 0xdd, 0x8d, 0x91, 0xfe, 0x3f, 0x46, 0x2f, 0x39, + 0x13, 0xb9, 0x31, 0x3e, 0xe6, 0xbe, 0x9f, 0xf4, 0xdf, 0xbb, 0xe3, 0xfe, + 0x8e, 0xdf, 0xa8, 0x99, 0xff, 0x00, 0x23, 0x66, 0x7f, 0x69, 0x57, 0x2f, + 0xf7, 0xc9, 0x4d, 0x8b, 0x4f, 0xbe, 0x5f, 0x82, 0xd8, 0x49, 0x2f, 0x1f, + 0xea, 0x27, 0xc9, 0xb2, 0x47, 0x81, 0x6e, 0xf0, 0x54, 0xa2, 0x62, 0xf2, + 0x25, 0x9a, 0x41, 0x78, 0x12, 0xc8, 0xcd, 0xc4, 0x5b, 0x92, 0xa2, 0xe2, + 0x23, 0x28, 0x7d, 0x8b, 0x0e, 0x49, 0x72, 0x3d, 0x6a, 0xf2, 0xbb, 0xe9, + 0x25, 0x96, 0xa4, 0x14, 0xd9, 0x79, 0x2c, 0x04, 0xc8, 0x64, 0x0d, 0x2e, + 0x06, 0xa8, 0x8b, 0x81, 0xb3, 0xb6, 0x6b, 0x95, 0x95, 0xff, 0x00, 0x3e, + 0xa4, 0x1a, 0x6b, 0x74, 0x30, 0x78, 0x4f, 0xdf, 0xb9, 0xba, 0x52, 0xc0, + 0x89, 0x10, 0xad, 0x10, 0x7d, 0xca, 0x34, 0x38, 0x02, 0xf7, 0x65, 0x8c, + 0x9d, 0x90, 0x9d, 0x32, 0x8d, 0xf7, 0x1a, 0xde, 0x09, 0x65, 0x16, 0xcc, + 0xa3, 0xa1, 0x81, 0xa1, 0x3a, 0xe6, 0xd9, 0xff, 0x00, 0x4f, 0xfa, 0xe9, + 0x44, 0xa4, 0x6b, 0x66, 0x56, 0x20, 0xb5, 0x10, 0x47, 0x73, 0xc8, 0x79, + 0x06, 0x83, 0x14, 0x36, 0x62, 0x4c, 0x28, 0x58, 0xf4, 0xdb, 0x86, 0x42, + 0x6f, 0x22, 0x4d, 0x8f, 0x58, 0x42, 0x10, 0xb7, 0xa6, 0x9b, 0xec, 0x25, + 0xe8, 0xa9, 0xdf, 0x6d, 0x66, 0x96, 0x4b, 0x7e, 0x5f, 0xf5, 0xfd, 0x89, + 0xa3, 0x4e, 0x07, 0x03, 0xb7, 0x38, 0x17, 0x8e, 0x46, 0xa8, 0x9b, 0x91, + 0x67, 0x91, 0x53, 0xa6, 0x19, 0x1c, 0xd8, 0x88, 0x4f, 0x81, 0x51, 0x56, + 0xd9, 0xe5, 0xff, 0x00, 0x7e, 0xc2, 0x61, 0x6a, 0x19, 0xec, 0x36, 0x68, + 0x24, 0xe0, 0xa4, 0x17, 0x2d, 0x09, 0x88, 0x2a, 0x2a, 0x39, 0xb4, 0x6d, + 0x94, 0x5e, 0xe8, 0x58, 0x8f, 0x6a, 0x2a, 0xd6, 0x0e, 0x06, 0xd1, 0x56, + 0xc5, 0x10, 0xfb, 0x2b, 0xfc, 0x11, 0xb6, 0x51, 0xa5, 0x4c, 0x6e, 0x6c, + 0x35, 0x36, 0x12, 0x17, 0x01, 0x6c, 0x7e, 0x10, 0xd5, 0x2f, 0x42, 0xbe, + 0x56, 0x1f, 0xd8, 0xfa, 0xe1, 0x27, 0xfb, 0xff, 0x00, 0x83, 0x54, 0xac, + 0x37, 0x5d, 0xd7, 0xfc, 0x1c, 0x04, 0x86, 0xc0, 0xd7, 0x0c, 0x78, 0x42, + 0xf2, 0x62, 0xc8, 0x87, 0xc8, 0x31, 0xa2, 0xdd, 0x24, 0x24, 0x12, 0xba, + 0x52, 0xc1, 0x41, 0x0d, 0xdf, 0x7b, 0x26, 0x3b, 0xe0, 0xf2, 0xd2, 0xfb, + 0x6f, 0xf6, 0x1d, 0x25, 0x48, 0xea, 0xdf, 0xf3, 0xff, 0x00, 0x07, 0x65, + 0x84, 0xb9, 0x4d, 0xba, 0xb9, 0x97, 0x4e, 0x3d, 0x04, 0x6d, 0x10, 0x92, + 0xc1, 0x7a, 0x8b, 0x9b, 0xaa, 0xdb, 0x31, 0x73, 0x8b, 0xb9, 0x0b, 0x94, + 0x4c, 0xe4, 0x4c, 0xe4, 0xb7, 0x28, 0xff, 0x00, 0x27, 0xa0, 0x8f, 0x23, + 0x4f, 0x24, 0xb6, 0x43, 0x5e, 0x10, 0x9a, 0x94, 0x5e, 0x8d, 0x85, 0xd0, + 0xce, 0xd2, 0xf1, 0xf4, 0x21, 0xba, 0xc5, 0x91, 0xc6, 0x34, 0x93, 0xa4, + 0xd3, 0x0f, 0x21, 0x60, 0xc8, 0xb2, 0x34, 0x82, 0xce, 0x37, 0x3c, 0x11, + 0x99, 0xba, 0xfb, 0xaf, 0xd7, 0x91, 0x52, 0x44, 0x47, 0xf3, 0xfb, 0x33, + 0x17, 0xf5, 0x5f, 0xc8, 0xcb, 0x8c, 0xf1, 0xff, 0x00, 0xa2, 0x65, 0xb0, + 0x9b, 0x91, 0x3c, 0xc6, 0x85, 0x1b, 0xa2, 0xcc, 0x36, 0x2a, 0x11, 0xb0, + 0x56, 0x4b, 0x96, 0x53, 0x51, 0xd6, 0x1b, 0x82, 0xfe, 0x8c, 0xcc, 0x63, + 0xef, 0x83, 0x87, 0x2f, 0xf7, 0xb1, 0xbb, 0x2f, 0xdb, 0x1f, 0xb3, 0x3e, + 0xaf, 0xdf, 0x23, 0x79, 0x3d, 0xbf, 0xfe, 0x10, 0xdd, 0xd0, 0x6b, 0xb0, + 0xfb, 0x97, 0x18, 0x16, 0xca, 0x2e, 0x7f, 0x1f, 0xde, 0x90, 0x94, 0x4a, + 0x33, 0x18, 0x97, 0xee, 0x8a, 0xed, 0x94, 0x1a, 0xdc, 0x97, 0xfb, 0xd8, + 0x7f, 0x0e, 0xf9, 0xa3, 0x99, 0x49, 0x3f, 0xf3, 0xc2, 0x1a, 0x7f, 0x56, + 0x9f, 0xf6, 0x21, 0xfd, 0x0b, 0xf4, 0x64, 0xa8, 0xf6, 0x62, 0x3c, 0x7c, + 0x0c, 0x63, 0x1f, 0x60, 0x77, 0x66, 0xfb, 0x7e, 0xce, 0x30, 0xbe, 0xab, + 0xfa, 0xa3, 0xfb, 0x2f, 0x9f, 0xd0, 0x9f, 0xd0, 0xbf, 0xe9, 0x92, 0xbf, + 0x73, 0xfd, 0x43, 0x6f, 0xd7, 0xd1, 0x11, 0x13, 0xd1, 0xa2, 0x7a, 0x69, + 0x3c, 0x11, 0x07, 0xf3, 0x1e, 0x38, 0x6d, 0xe8, 0xe4, 0x50, 0xd6, 0xbe, + 0x06, 0x43, 0xbb, 0x91, 0xe5, 0xa4, 0x3f, 0x03, 0xbb, 0x09, 0x94, 0xc6, + 0xc3, 0x46, 0x44, 0xfb, 0x8d, 0xe0, 0xd8, 0x58, 0x34, 0xed, 0x17, 0x6c, + 0x4f, 0xe1, 0xfb, 0x8a, 0x09, 0xfb, 0x3f, 0xa2, 0x08, 0xa8, 0x6d, 0xdf, + 0xee, 0x47, 0xfe, 0xd9, 0x1f, 0xfd, 0x89, 0x1c, 0x4c, 0x03, 0x43, 0x70, + 0xfb, 0xdf, 0xec, 0xaf, 0xfd, 0xbf, 0xd9, 0xfe, 0x6d, 0x89, 0x3b, 0x7d, + 0xcf, 0xf6, 0x7f, 0x83, 0x62, 0x5f, 0x11, 0xed, 0x4a, 0xf6, 0x5d, 0x0c, + 0x64, 0x71, 0x40, 0x63, 0x84, 0x2b, 0x78, 0x1b, 0xe2, 0x0d, 0x96, 0x32, + 0xf6, 0x36, 0xc9, 0x48, 0xc9, 0xbe, 0x3a, 0x21, 0xba, 0x83, 0xe9, 0x02, + 0x42, 0x44, 0x27, 0x42, 0x54, 0x4f, 0x52, 0x0f, 0x49, 0x27, 0x82, 0x20, + 0x9e, 0xb6, 0xef, 0x5a, 0xee, 0x01, 0x29, 0x8f, 0x49, 0x9e, 0xfa, 0xd6, + 0x12, 0xf7, 0xcf, 0xc1, 0x4b, 0x45, 0xb9, 0xe5, 0x0f, 0x6c, 0x0e, 0xd2, + 0x64, 0x6b, 0x06, 0x36, 0x36, 0x3c, 0x1d, 0xc8, 0x59, 0xd8, 0x6e, 0x8d, + 0x26, 0x87, 0x5a, 0xac, 0x3e, 0xe4, 0xec, 0x6e, 0xfc, 0xfd, 0x7b, 0xfe, + 0x4c, 0xdf, 0x2d, 0x21, 0x34, 0x9a, 0xce, 0xa6, 0x21, 0x79, 0xbf, 0x0f, + 0x72, 0xa6, 0xa3, 0x76, 0x8b, 0x2c, 0xad, 0xd1, 0xa6, 0xcc, 0xd9, 0x91, + 0xc3, 0xac, 0x8e, 0x0c, 0xda, 0x3b, 0x8f, 0x2b, 0xfa, 0x90, 0x84, 0x64, + 0x65, 0x68, 0x62, 0x90, 0x84, 0x21, 0x3a, 0xd3, 0xd6, 0xe6, 0xf4, 0x18, + 0x12, 0x5b, 0x3d, 0x75, 0xab, 0xd5, 0x6b, 0x57, 0xb0, 0x92, 0x48, 0xbd, + 0x4b, 0x36, 0xb8, 0xe6, 0xcb, 0x1f, 0xef, 0xa9, 0x43, 0x7d, 0xc7, 0x85, + 0x4c, 0xda, 0x2c, 0x3c, 0x19, 0x21, 0x6f, 0x58, 0xdb, 0x43, 0xdc, 0xf3, + 0x37, 0x1a, 0x6f, 0x62, 0x41, 0xb6, 0x9e, 0x05, 0x77, 0x1a, 0x52, 0xb1, + 0x33, 0x4c, 0x40, 0x3f, 0xc9, 0x13, 0x3b, 0xbf, 0x1f, 0xf0, 0x42, 0x99, + 0x56, 0x90, 0x9a, 0x4e, 0xa6, 0x66, 0xc4, 0x52, 0xe0, 0x5d, 0xff, 0x00, + 0x43, 0xf7, 0x32, 0x5e, 0x06, 0xd3, 0x65, 0x0b, 0x80, 0xce, 0xec, 0x6c, + 0x1b, 0x76, 0x13, 0x12, 0xdc, 0xfb, 0x94, 0x24, 0x53, 0xa9, 0x93, 0xd2, + 0x4a, 0x25, 0xeb, 0x6e, 0x47, 0x2b, 0xa5, 0x23, 0xb9, 0xfc, 0x19, 0x53, + 0x5a, 0x4f, 0x45, 0x57, 0x85, 0xa4, 0x6d, 0xea, 0xb5, 0x50, 0xd6, 0x30, + 0xa7, 0x1f, 0x4f, 0x72, 0xfb, 0x1a, 0x9e, 0x46, 0x61, 0xb1, 0x21, 0x67, + 0x03, 0x8d, 0x15, 0x3c, 0x0a, 0xca, 0xc8, 0x98, 0x94, 0xc1, 0xbb, 0x8c, + 0x6b, 0xb9, 0xb6, 0xe6, 0x4a, 0x44, 0xda, 0x1c, 0x0d, 0x9a, 0xa1, 0x9f, + 0x17, 0x67, 0xb1, 0x01, 0x35, 0xdf, 0x81, 0x5c, 0x0d, 0x75, 0xa4, 0xad, + 0x10, 0x91, 0xff, 0x00, 0x48, 0x3a, 0xe2, 0xec, 0x54, 0xd9, 0x4b, 0x63, + 0x67, 0x93, 0xd9, 0x18, 0xdc, 0xae, 0x4b, 0x98, 0xd0, 0xfb, 0x21, 0x5b, + 0x96, 0x28, 0xf8, 0x2e, 0xda, 0xd8, 0x5e, 0x84, 0xf4, 0x12, 0xa2, 0x42, + 0xfe, 0x07, 0x22, 0x24, 0xc6, 0x8d, 0xdc, 0x24, 0xd9, 0xfc, 0x25, 0x86, + 0x24, 0x73, 0xd1, 0x6b, 0x10, 0x94, 0xaf, 0x7d, 0x2f, 0xad, 0x81, 0x6e, + 0x8f, 0xfd, 0x94, 0x62, 0x7b, 0x8d, 0xdc, 0x9b, 0x3c, 0x64, 0xa3, 0x9b, + 0x8b, 0x3a, 0x63, 0x24, 0x2f, 0x61, 0x6c, 0x55, 0x0c, 0xec, 0x46, 0xd1, + 0x18, 0xdc, 0x95, 0xee, 0x4a, 0x4a, 0xb0, 0x64, 0xa6, 0x94, 0xee, 0x52, + 0x15, 0x81, 0x7d, 0x48, 0x28, 0xfc, 0x08, 0x89, 0xeb, 0xc8, 0x9a, 0xa1, + 0xfb, 0x68, 0x82, 0xa9, 0x17, 0x28, 0x7d, 0xd9, 0x96, 0x13, 0xb0, 0xd8, + 0xa2, 0x6a, 0x4e, 0xc3, 0xcb, 0x12, 0x68, 0xab, 0x82, 0x67, 0x61, 0x22, + 0xc9, 0x8e, 0xc3, 0x5c, 0x08, 0xf7, 0x15, 0x32, 0xc1, 0x91, 0x79, 0x0b, + 0xd2, 0x9d, 0x49, 0x04, 0xbf, 0x83, 0x46, 0x9b, 0x84, 0xab, 0xf8, 0xab, + 0x55, 0xeb, 0x63, 0x44, 0x31, 0xe4, 0xa5, 0x62, 0x5f, 0xc1, 0xce, 0xbf, + 0xd4, 0xbb, 0x8c, 0xdd, 0x31, 0xc5, 0x91, 0xe5, 0xe1, 0x19, 0x4a, 0x98, + 0x45, 0x43, 0x48, 0xf4, 0x4a, 0xba, 0x2c, 0xb3, 0x75, 0x16, 0x39, 0x3c, + 0x32, 0xa6, 0xf6, 0x1b, 0xb8, 0xec, 0x55, 0x62, 0x77, 0x66, 0x6d, 0x69, + 0x7c, 0x8f, 0x0f, 0x25, 0x5c, 0x8e, 0x88, 0xb9, 0x26, 0x6c, 0x2b, 0xc9, + 0xe0, 0x68, 0xca, 0x64, 0x67, 0x5f, 0x22, 0x0b, 0xa7, 0xb8, 0xcd, 0xc3, + 0x2c, 0x8b, 0xb8, 0xb5, 0x76, 0x37, 0x46, 0x65, 0xe5, 0x12, 0x64, 0xdf, + 0x81, 0xf6, 0x1c, 0x5b, 0x0f, 0x0c, 0x8e, 0x52, 0x64, 0xc2, 0x59, 0x67, + 0x79, 0x42, 0x92, 0xf0, 0x84, 0x5f, 0x5a, 0x02, 0x5f, 0xfc, 0xa4, 0x8f, + 0xa3, 0x61, 0x1c, 0x8e, 0x61, 0x53, 0xd1, 0xbe, 0x8b, 0x3a, 0xc2, 0x39, + 0x23, 0xff, 0x00, 0x41, 0xef, 0x82, 0x96, 0xe2, 0xbc, 0x13, 0xb9, 0xbe, + 0xc2, 0x86, 0x53, 0xa4, 0x33, 0x1c, 0x18, 0x7b, 0x11, 0x09, 0xc0, 0xed, + 0x83, 0xc1, 0x99, 0x11, 0x73, 0x46, 0xc6, 0x59, 0x63, 0xc2, 0x2c, 0xaf, + 0x2a, 0x5c, 0x93, 0xbc, 0x61, 0x16, 0x4c, 0x32, 0x73, 0xd8, 0x6a, 0xef, + 0x92, 0x55, 0xb0, 0xd1, 0x64, 0x8d, 0xe0, 0xcb, 0x0c, 0x4a, 0xbc, 0x09, + 0x32, 0xd6, 0x50, 0xb7, 0xc8, 0xd0, 0x75, 0x03, 0x49, 0x5b, 0x12, 0x99, + 0x43, 0x49, 0x88, 0x9c, 0x64, 0xab, 0x22, 0x46, 0xf9, 0x83, 0xe5, 0x63, + 0xf2, 0x17, 0x4c, 0xf4, 0x90, 0x42, 0xfe, 0x5c, 0xf5, 0xda, 0xa2, 0x6a, + 0x24, 0x31, 0xba, 0x1b, 0xd2, 0xa4, 0x9f, 0xc3, 0x62, 0x6f, 0xf7, 0x3c, + 0xb1, 0xf7, 0x13, 0x7c, 0x8d, 0x3d, 0x98, 0xd6, 0x86, 0xd2, 0x70, 0x7d, + 0xc8, 0xec, 0x12, 0x84, 0x58, 0x63, 0x4a, 0x2c, 0x84, 0xdb, 0x5b, 0x0d, + 0xdd, 0x85, 0x97, 0x92, 0x36, 0x46, 0xf6, 0x47, 0x60, 0x49, 0xac, 0x0e, + 0x82, 0x4d, 0xec, 0x38, 0xf9, 0x12, 0x6c, 0x4d, 0x3d, 0xdf, 0x92, 0x34, + 0xeb, 0x73, 0x88, 0x8c, 0xb6, 0x27, 0x72, 0x2c, 0x9b, 0x6e, 0x46, 0x12, + 0x5c, 0x8b, 0x39, 0x23, 0x83, 0x2c, 0x89, 0x3e, 0xd8, 0x26, 0x72, 0x24, + 0x86, 0xb7, 0x68, 0x73, 0xb1, 0xec, 0x3a, 0x3b, 0x3a, 0xa2, 0x42, 0x3d, + 0xc5, 0xeb, 0x24, 0x90, 0xbd, 0x38, 0x5b, 0x92, 0xcb, 0x7d, 0x6b, 0xeb, + 0x43, 0xc2, 0xe8, 0x67, 0x61, 0x16, 0xf4, 0xd2, 0x94, 0xba, 0xdf, 0x45, + 0xb4, 0xb2, 0x34, 0x3a, 0xbe, 0x5f, 0x6f, 0x61, 0x6d, 0x58, 0x9d, 0x46, + 0x12, 0xb4, 0x5e, 0x4d, 0xc7, 0x6e, 0x4d, 0xb6, 0x1f, 0xd8, 0x6c, 0x69, + 0xc1, 0x61, 0x51, 0x3c, 0x26, 0x4b, 0x21, 0xba, 0xc8, 0x9a, 0x5b, 0x8d, + 0xb6, 0xb7, 0x1e, 0x30, 0xb7, 0x25, 0xf7, 0x36, 0x54, 0x35, 0x83, 0x73, + 0x2d, 0x88, 0x1f, 0x70, 0xe9, 0x06, 0x8b, 0x0a, 0x2f, 0x6f, 0x22, 0x3d, + 0xc3, 0x4e, 0xc2, 0x0a, 0xd6, 0x0c, 0x96, 0x30, 0x43, 0x70, 0x94, 0x42, + 0xb4, 0x71, 0x70, 0x5c, 0x54, 0xfe, 0xc2, 0x58, 0x12, 0x49, 0xe4, 0x4c, + 0xc1, 0xb4, 0xcb, 0x30, 0x26, 0x7c, 0x2a, 0x21, 0x52, 0x7c, 0x3c, 0x09, + 0x0b, 0xd3, 0x56, 0x58, 0x1a, 0x2e, 0x89, 0xb4, 0x2e, 0xf1, 0x23, 0xe8, + 0x5d, 0x0d, 0xc2, 0x09, 0x45, 0x5a, 0x09, 0xdf, 0xe0, 0x52, 0x97, 0x5f, + 0xa9, 0xf5, 0x32, 0x67, 0x48, 0xb8, 0x8a, 0x7b, 0x87, 0x55, 0x92, 0x42, + 0x5b, 0x07, 0x3b, 0x22, 0xbc, 0x1e, 0x41, 0x77, 0x07, 0xdd, 0x43, 0xe5, + 0x63, 0x58, 0xc7, 0x53, 0x94, 0x8a, 0x5f, 0x4f, 0x7b, 0x0e, 0xdc, 0x95, + 0x3f, 0x73, 0xee, 0xc6, 0xcf, 0x08, 0xd0, 0xae, 0x0f, 0x72, 0x78, 0x30, + 0x06, 0xa6, 0xc3, 0xce, 0x4d, 0x89, 0x30, 0x8c, 0x26, 0x48, 0x88, 0x92, + 0x0b, 0x63, 0x81, 0x65, 0x11, 0xdc, 0x99, 0x32, 0x99, 0x4a, 0x19, 0xde, + 0x8d, 0xa6, 0xa5, 0x31, 0xb0, 0x79, 0xd8, 0x48, 0x86, 0x92, 0x1c, 0x09, + 0x26, 0x84, 0xce, 0x1d, 0x26, 0x9a, 0x5f, 0xa8, 0xaf, 0x27, 0xda, 0x23, + 0xbd, 0x5f, 0x91, 0x2c, 0x2d, 0xae, 0xd2, 0xa1, 0x97, 0x14, 0x3d, 0x82, + 0xdc, 0x67, 0xe7, 0xf4, 0x83, 0xb8, 0xf7, 0x0c, 0x5f, 0x6a, 0x37, 0x3f, + 0xe9, 0x9f, 0xc1, 0xbf, 0x32, 0xfa, 0x17, 0x44, 0xb2, 0x79, 0x09, 0x77, + 0x38, 0x9b, 0xc4, 0x20, 0x2a, 0xb6, 0x26, 0x13, 0xec, 0xec, 0x21, 0x04, + 0xba, 0x17, 0x4a, 0x54, 0x5d, 0xe4, 0x3d, 0x81, 0xf4, 0xa6, 0x45, 0xf2, + 0x24, 0x23, 0xb9, 0x46, 0xc6, 0x6c, 0x0a, 0xe4, 0x68, 0x83, 0x1c, 0x98, + 0xe1, 0x89, 0xbb, 0x98, 0x89, 0x39, 0x12, 0x31, 0x3b, 0xfc, 0x0a, 0x52, + 0x97, 0x46, 0x93, 0xdc, 0x7b, 0xcb, 0x05, 0xac, 0x32, 0x7b, 0x68, 0x5e, + 0xe2, 0xae, 0xe7, 0xc7, 0xc9, 0x08, 0xfb, 0x0c, 0x69, 0xb0, 0x89, 0x4c, + 0xe0, 0x10, 0x9e, 0x83, 0x44, 0xad, 0x88, 0x1d, 0xb7, 0xd9, 0x67, 0xfe, + 0x18, 0x6e, 0x3b, 0xf2, 0x5d, 0xad, 0xb6, 0x27, 0x98, 0x57, 0xc0, 0x96, + 0x3b, 0x93, 0x94, 0x55, 0xb3, 0x14, 0xa9, 0x93, 0x15, 0x45, 0x96, 0x99, + 0x6b, 0xfe, 0xcd, 0xd4, 0x36, 0xc0, 0xb2, 0x99, 0x87, 0x87, 0xb8, 0xd5, + 0xdf, 0xfd, 0xfb, 0x1e, 0x52, 0x84, 0xca, 0x9c, 0x0a, 0xb3, 0x70, 0x2e, + 0xe1, 0xda, 0x8a, 0x13, 0x36, 0x53, 0xcd, 0x2a, 0x46, 0x37, 0x64, 0x6d, + 0xd1, 0xc7, 0x85, 0xb9, 0x5c, 0x11, 0xe0, 0x9b, 0x81, 0x7c, 0x1b, 0xf5, + 0xbe, 0xc6, 0x5b, 0xa5, 0x24, 0x42, 0x76, 0x59, 0x41, 0x8e, 0x07, 0xbf, + 0x86, 0xc9, 0xbf, 0xa0, 0xf6, 0xaf, 0xc4, 0x1f, 0x60, 0xfa, 0xbf, 0xd8, + 0xa5, 0x35, 0x78, 0x4f, 0xfe, 0x32, 0x6e, 0xfc, 0xab, 0xf5, 0x07, 0xb6, + 0x91, 0x8a, 0xed, 0x44, 0x70, 0x8c, 0x8a, 0x88, 0x24, 0x5b, 0x0e, 0x14, + 0x6d, 0xa2, 0x4c, 0x4c, 0xc4, 0x52, 0x10, 0x84, 0x27, 0x82, 0xa9, 0xc7, + 0xe8, 0x56, 0x8a, 0xd3, 0x1d, 0x84, 0xbe, 0x82, 0x61, 0x30, 0x9b, 0x91, + 0x28, 0x95, 0x95, 0x3f, 0x52, 0x95, 0x12, 0xe4, 0xf3, 0x68, 0x67, 0xb0, + 0xd3, 0x32, 0xf6, 0x2c, 0xdc, 0x4b, 0x86, 0x7a, 0x2e, 0x97, 0x25, 0x82, + 0x8d, 0x99, 0x3d, 0xf4, 0x0d, 0xfa, 0x57, 0xfc, 0x01, 0x84, 0xfa, 0xf4, + 0xdb, 0xfd, 0x0c, 0x33, 0xbf, 0xc7, 0xc6, 0xc6, 0x68, 0x43, 0xa7, 0x48, + 0x1b, 0x49, 0xce, 0x4b, 0x36, 0x26, 0x44, 0x53, 0x70, 0xc9, 0x58, 0xea, + 0x64, 0x59, 0x68, 0x45, 0x5a, 0x1c, 0x3a, 0xf7, 0x3c, 0xc1, 0x72, 0x9e, + 0xe2, 0x84, 0x66, 0x56, 0x9b, 0x2d, 0xc4, 0x92, 0x0e, 0xf7, 0x22, 0x0c, + 0xaa, 0x42, 0xdc, 0xe0, 0x59, 0xe0, 0xa5, 0x02, 0x88, 0xc4, 0xfc, 0x3f, + 0xdf, 0xec, 0x71, 0x60, 0xf6, 0x31, 0xfd, 0x0e, 0x26, 0x5e, 0x4f, 0xc2, + 0xb3, 0x98, 0x1f, 0x71, 0x44, 0xb4, 0x30, 0x24, 0xdb, 0x9e, 0x51, 0x2e, + 0xe2, 0xf6, 0x1e, 0x12, 0x38, 0x45, 0xf6, 0xd3, 0xbf, 0x25, 0x6f, 0x92, + 0x22, 0x21, 0x90, 0xdd, 0x64, 0x4b, 0x58, 0xd8, 0xb4, 0xa8, 0x87, 0xc8, + 0x92, 0x26, 0xb3, 0xa6, 0x61, 0x43, 0x8c, 0xbf, 0xc4, 0x9a, 0xa6, 0x42, + 0x05, 0xde, 0x26, 0x15, 0x3d, 0xb4, 0x86, 0xe3, 0x8d, 0x8a, 0x6c, 0x36, + 0xe5, 0x8d, 0xb8, 0x2b, 0x7b, 0xb1, 0x57, 0xb1, 0x12, 0x59, 0x2d, 0xd1, + 0x0d, 0xc5, 0x4c, 0x54, 0xa4, 0x33, 0x25, 0x54, 0x5a, 0x34, 0xfa, 0x24, + 0x2a, 0x63, 0x29, 0x60, 0xd6, 0x37, 0x81, 0x09, 0x7a, 0x1a, 0x30, 0x08, + 0x6d, 0xaf, 0xc1, 0xb5, 0xcf, 0xb3, 0x1c, 0xde, 0x5f, 0x71, 0x2b, 0x6b, + 0xe0, 0x6c, 0x61, 0x9f, 0x5f, 0xd0, 0xe2, 0x9f, 0x02, 0x37, 0xe1, 0xfc, + 0x21, 0x3d, 0xd9, 0xfd, 0x58, 0x93, 0xff, 0x00, 0xaf, 0xd9, 0xfe, 0x57, + 0xf6, 0x36, 0x3b, 0xfd, 0xbf, 0x63, 0x67, 0xfd, 0x3f, 0xd8, 0x93, 0xb7, + 0xde, 0xc6, 0xe7, 0x6b, 0xe5, 0x89, 0x3c, 0xbe, 0x59, 0xcb, 0x1f, 0xcb, + 0x12, 0x39, 0x7c, 0xb1, 0x25, 0x48, 0xf8, 0x3c, 0x4f, 0x82, 0x5b, 0x27, + 0xc0, 0x91, 0xb2, 0xfc, 0x2f, 0xd1, 0x0d, 0x93, 0xe0, 0x8b, 0x57, 0x9e, + 0x06, 0x5e, 0x52, 0x5f, 0x53, 0x38, 0x94, 0x7e, 0xac, 0x6e, 0x0a, 0xfb, + 0xb3, 0x6a, 0x06, 0x96, 0x2a, 0x6e, 0xb1, 0xec, 0x25, 0x5b, 0x89, 0x11, + 0x01, 0x52, 0x75, 0x8d, 0x3b, 0xb1, 0x36, 0xd8, 0x4b, 0xc1, 0x08, 0x24, + 0x3d, 0xc0, 0x91, 0x8d, 0x4d, 0xff, 0x00, 0x23, 0x81, 0x1d, 0x56, 0x35, + 0x9c, 0x1e, 0xfa, 0x32, 0x5d, 0x99, 0x38, 0x0d, 0x1c, 0x0a, 0xf7, 0x2d, + 0x94, 0x6f, 0x9e, 0xb6, 0xad, 0xd8, 0xd3, 0x81, 0xb8, 0x6b, 0xc6, 0xe2, + 0xad, 0xfd, 0x7a, 0x5e, 0x9d, 0xb5, 0xa5, 0x29, 0x4a, 0x27, 0x5b, 0x31, + 0xd3, 0xaf, 0x45, 0x1b, 0x94, 0x44, 0xdc, 0x7d, 0xa7, 0xbe, 0xa9, 0x0d, + 0x70, 0x60, 0x1e, 0x5e, 0x9b, 0x88, 0x61, 0xb8, 0xd7, 0x43, 0xf6, 0x19, + 0x61, 0x3c, 0x8d, 0xda, 0x2f, 0x09, 0x61, 0xf7, 0x8b, 0x72, 0x5b, 0x96, + 0x36, 0x6e, 0xcc, 0x91, 0x90, 0xc1, 0x8d, 0x1b, 0x9b, 0x99, 0x6c, 0xa8, + 0xdd, 0x2b, 0x80, 0x87, 0x23, 0x69, 0x66, 0x3d, 0xcf, 0x6f, 0xe4, 0xbe, + 0xdf, 0x62, 0x7b, 0x09, 0x48, 0x4a, 0xb4, 0xc4, 0xde, 0x45, 0x4b, 0x02, + 0xa7, 0x0d, 0xc7, 0x10, 0xbd, 0xc1, 0xab, 0x74, 0xc7, 0x16, 0xe2, 0x6b, + 0x87, 0xa5, 0x49, 0x74, 0xa9, 0x6e, 0x3d, 0xe3, 0x38, 0x4a, 0x6c, 0x68, + 0x5b, 0xda, 0x1b, 0x5a, 0x14, 0x5b, 0x74, 0x20, 0xe2, 0x25, 0x69, 0x61, + 0x6e, 0x35, 0x42, 0xc6, 0xad, 0x26, 0x26, 0xd6, 0xf9, 0x2e, 0x06, 0x35, + 0x7b, 0x10, 0x12, 0x8f, 0x24, 0x48, 0x95, 0x8d, 0xe6, 0x10, 0xdf, 0xe0, + 0x6d, 0xb7, 0xa6, 0x4a, 0xc7, 0x58, 0x94, 0xd6, 0x97, 0xa2, 0x97, 0xd3, + 0x85, 0x29, 0x74, 0xa8, 0xba, 0x8a, 0xb6, 0x3c, 0x02, 0x72, 0x16, 0xec, + 0xc0, 0xf1, 0x1b, 0x64, 0x21, 0x08, 0x4e, 0x4e, 0x04, 0x5d, 0xe4, 0x68, + 0xa1, 0xc9, 0x44, 0xcc, 0xb1, 0x32, 0xd1, 0x36, 0x8a, 0x6e, 0x6c, 0x54, + 0x86, 0x14, 0x36, 0x0d, 0x5e, 0xcc, 0xf7, 0x17, 0xdc, 0x6e, 0x50, 0x6d, + 0xcb, 0xf6, 0x6b, 0xf4, 0x38, 0xbf, 0xee, 0x76, 0x10, 0xe1, 0x7c, 0xb6, + 0xff, 0x00, 0x26, 0x4c, 0x91, 0x88, 0x70, 0xc0, 0x84, 0x8c, 0x4f, 0xb1, + 0x9c, 0x91, 0xf1, 0x31, 0x23, 0x1b, 0xe9, 0x9b, 0x43, 0x7e, 0xfa, 0x34, + 0x11, 0xec, 0x72, 0x19, 0xc1, 0x62, 0x54, 0xeb, 0x65, 0x46, 0x0c, 0xb6, + 0xee, 0x58, 0x3a, 0xbf, 0xb5, 0xfe, 0x8b, 0xa6, 0x2f, 0x6c, 0xbf, 0xd6, + 0x94, 0x6d, 0xf8, 0x23, 0x15, 0xe4, 0xb6, 0xec, 0x4b, 0xcb, 0x12, 0x84, + 0x8e, 0x04, 0xb4, 0xc8, 0x82, 0x2d, 0x1b, 0x63, 0xc9, 0x08, 0x64, 0xb9, + 0x33, 0x45, 0x87, 0x01, 0x2e, 0xc3, 0x21, 0x3b, 0x9b, 0x6c, 0x51, 0x5b, + 0x74, 0x57, 0x61, 0xf6, 0xbd, 0x28, 0xf0, 0x56, 0xb7, 0xd1, 0x04, 0x17, + 0x48, 0x4d, 0x33, 0xa5, 0x29, 0x4a, 0x52, 0x94, 0xf8, 0x33, 0xdd, 0x19, + 0xee, 0x8c, 0xf7, 0x46, 0x7b, 0x99, 0xee, 0x47, 0xdf, 0xec, 0x4f, 0x3f, + 0x62, 0x3b, 0x93, 0xb9, 0x93, 0xc8, 0xf6, 0xb2, 0xa7, 0x1a, 0x0f, 0x05, + 0xa5, 0x4c, 0xcf, 0x72, 0x11, 0x2e, 0x8c, 0x18, 0x21, 0x13, 0xc1, 0x03, + 0xba, 0x44, 0x91, 0x6d, 0x60, 0x24, 0x2a, 0x30, 0x42, 0x11, 0x99, 0x27, + 0x82, 0x09, 0xd3, 0x5c, 0x33, 0xc9, 0xa1, 0x05, 0xec, 0x2b, 0xb1, 0xec, + 0x3d, 0x87, 0xb0, 0x9e, 0xc4, 0x90, 0x47, 0xa9, 0x40, 0x00, 0x14, 0x90, + 0x41, 0x1a, 0x7d, 0xa7, 0xb4, 0xae, 0xc5, 0x7d, 0x8a, 0xfb, 0x19, 0xec, + 0x64, 0xcf, 0x45, 0x63, 0x65, 0x26, 0x88, 0xe4, 0x60, 0xd2, 0x1b, 0x48, + 0xba, 0x48, 0x70, 0x76, 0x74, 0x3c, 0xca, 0x99, 0xb9, 0x08, 0x42, 0x10, + 0xc9, 0x9e, 0xe5, 0xee, 0x1b, 0x7c, 0x91, 0x3e, 0x11, 0x3b, 0x09, 0xdb, + 0xa1, 0xee, 0x11, 0xdc, 0x9e, 0x49, 0xe7, 0xec, 0x41, 0x9e, 0xe7, 0xd4, + 0xfa, 0xa3, 0x3d, 0xd1, 0xf5, 0x47, 0xd5, 0x1f, 0x54, 0x56, 0x64, 0xc9, + 0x93, 0x26, 0x48, 0xc8, 0xcc, 0x91, 0x91, 0x91, 0x99, 0xee, 0x67, 0xb9, + 0x92, 0x9f, 0x41, 0xf4, 0x17, 0xd8, 0xfa, 0xa2, 0x79, 0x23, 0xbe, 0x83, + 0xca, 0x4e, 0xe3, 0x12, 0x5b, 0x12, 0xd8, 0x61, 0xb3, 0x29, 0x75, 0xa5, + 0x22, 0xca, 0xd7, 0x92, 0x3a, 0xc0, 0xfb, 0xc8, 0x79, 0x0f, 0x21, 0xe4, + 0x3c, 0x87, 0x90, 0xbd, 0xc5, 0xee, 0x2f, 0x71, 0x7b, 0x8b, 0xdc, 0x5e, + 0xe2, 0xf7, 0x17, 0xb8, 0xbd, 0xc5, 0xee, 0x2f, 0x71, 0x7b, 0x8b, 0xdc, + 0x5e, 0xe2, 0xf7, 0x17, 0xb8, 0xba, 0x0f, 0x21, 0xe4, 0x3c, 0x87, 0x90, + 0xf3, 0x9e, 0x6d, 0x2f, 0x31, 0xe6, 0xea, 0x80, 0x27, 0xb1, 0xed, 0xd3, + 0x65, 0x94, 0x56, 0xfa, 0x13, 0x14, 0x08, 0x5b, 0x72, 0xe6, 0x44, 0xef, + 0x20, 0x45, 0xa1, 0x9e, 0xe8, 0xcf, 0x74, 0x67, 0xc1, 0x5f, 0x83, 0x3e, + 0x0a, 0xca, 0xff, 0x00, 0xcc, 0xac, 0xac, 0xfa, 0x1f, 0x42, 0xf8, 0x3e, + 0x86, 0x7b, 0x69, 0xf4, 0x3e, 0x87, 0xd0, 0xfa, 0x7e, 0x0b, 0xe3, 0xf0, + 0x7f, 0xb8, 0xd3, 0xff, 0xc4, 0x00, 0x29, 0x10, 0x01, 0x00, 0x02, 0x01, + 0x03, 0x03, 0x04, 0x03, 0x01, 0x01, 0x01, 0x01, 0x01, 0x00, 0x00, 0x00, + 0x01, 0x00, 0x11, 0x21, 0x31, 0x41, 0x51, 0x61, 0x71, 0x81, 0x10, 0x91, + 0xa1, 0xb1, 0xc1, 0xd1, 0xf0, 0xf1, 0xe1, 0x20, 0x30, 0x40, 0xff, 0xda, + 0x00, 0x08, 0x01, 0x01, 0x00, 0x01, 0x3f, 0x10, 0x85, 0x71, 0xf3, 0x1a, + 0xf4, 0x12, 0x58, 0xe9, 0x3c, 0xcb, 0xa9, 0x7f, 0xd5, 0x2c, 0x97, 0xe9, + 0x71, 0x4e, 0x25, 0xf4, 0x8f, 0x69, 0x64, 0xb2, 0x5a, 0x4b, 0xeb, 0x2f, + 0xac, 0xa7, 0xf3, 0x2c, 0x98, 0x98, 0xe6, 0x52, 0x59, 0xc4, 0xa7, 0x12, + 0xce, 0x22, 0x92, 0xce, 0x65, 0x9c, 0xca, 0xf3, 0x2b, 0xfc, 0x4a, 0xca, + 0xca, 0x74, 0x95, 0x95, 0x89, 0xe9, 0x29, 0xd2, 0x52, 0x23, 0xa4, 0xf0, + 0x94, 0xe0, 0x94, 0x38, 0x95, 0xe9, 0x29, 0x1f, 0xfc, 0xdb, 0xbc, 0x12, + 0xae, 0x93, 0x04, 0x2e, 0x9d, 0x26, 0x30, 0xab, 0x78, 0x87, 0x31, 0x0d, + 0x46, 0x21, 0xff, 0x00, 0x13, 0x03, 0x4e, 0x56, 0x3f, 0x11, 0xb3, 0x1e, + 0xf3, 0xf5, 0x3f, 0xd9, 0x7e, 0xa7, 0xdc, 0x15, 0xfa, 0x82, 0xf8, 0x84, + 0x86, 0x5f, 0x75, 0x4f, 0xd4, 0x3e, 0xab, 0xdd, 0xcd, 0xd8, 0xf7, 0xfd, + 0x90, 0xdb, 0xf2, 0xaf, 0xee, 0x07, 0xfa, 0xe0, 0x11, 0xd7, 0xfa, 0x52, + 0x8f, 0xca, 0x61, 0xff, 0x00, 0x1d, 0x02, 0xe5, 0xfe, 0xb6, 0x81, 0x7f, + 0x17, 0xc4, 0xa7, 0xf9, 0x3e, 0x27, 0xf8, 0xcf, 0xd4, 0xfe, 0x73, 0xf1, + 0x2b, 0x3f, 0xa3, 0xda, 0x1f, 0xf1, 0x93, 0xfc, 0x77, 0xea, 0x57, 0xfa, + 0x93, 0xfc, 0xe7, 0xea, 0x1f, 0xf2, 0x90, 0x6f, 0xd5, 0x86, 0xdf, 0xb1, + 0x9f, 0xe7, 0xe7, 0xf9, 0x79, 0xfe, 0x4e, 0x7f, 0x83, 0x9f, 0xe7, 0xe1, + 0xff, 0x00, 0x3b, 0x3f, 0xce, 0xcb, 0x63, 0xff, 0x00, 0x37, 0x0f, 0xf9, + 0xf9, 0xfe, 0x1e, 0x7f, 0x9f, 0xfd, 0x4f, 0xf2, 0xf2, 0x93, 0x3e, 0xce, + 0x5b, 0xfa, 0x32, 0xad, 0x7d, 0x8c, 0x7f, 0xe2, 0x7f, 0x52, 0x9f, 0xd5, + 0xfd, 0x4f, 0xf1, 0xf2, 0xef, 0xd0, 0xfd, 0x45, 0xbf, 0x43, 0xf5, 0x1f, + 0xd8, 0xfe, 0x89, 0xfc, 0x87, 0xe2, 0x75, 0xff, 0x00, 0xeb, 0x89, 0x6e, + 0xe4, 0x16, 0x32, 0x7f, 0xc7, 0x12, 0xdf, 0xd2, 0xfd, 0x4b, 0x1a, 0xf6, + 0xcc, 0x45, 0xcf, 0xb2, 0x8a, 0xca, 0xb6, 0xbe, 0x11, 0x23, 0xf8, 0xdb, + 0xfb, 0x44, 0x5a, 0x87, 0xa7, 0xee, 0x9a, 0x17, 0x67, 0x39, 0xee, 0xfa, + 0x0c, 0x30, 0xbd, 0x2e, 0x4b, 0xb6, 0x83, 0x76, 0xc8, 0x94, 0xd6, 0x91, + 0xd4, 0x5d, 0xde, 0x27, 0x07, 0xfa, 0x33, 0xfd, 0xf9, 0xfe, 0xb4, 0xff, + 0x00, 0x42, 0x2d, 0xb3, 0xde, 0x65, 0xd1, 0xef, 0x2f, 0xd9, 0x3a, 0x49, + 0x5f, 0xf5, 0x29, 0xc9, 0x29, 0xcc, 0xaf, 0x32, 0x9c, 0xca, 0xca, 0xb2, + 0x90, 0xf4, 0xde, 0xaf, 0x4e, 0x52, 0xd6, 0x5c, 0xbb, 0x97, 0x2e, 0x5c, + 0xcc, 0xb9, 0x6c, 0xb6, 0x5b, 0x2f, 0xd1, 0x6c, 0xb7, 0x78, 0x36, 0xea, + 0x12, 0xfa, 0xcb, 0x79, 0x8d, 0xcc, 0xfa, 0x52, 0xe9, 0x2a, 0x1d, 0x53, + 0xba, 0x5b, 0xff, 0x00, 0x02, 0xcb, 0xbc, 0xbf, 0x30, 0xef, 0x97, 0xeb, + 0x2f, 0xd6, 0x30, 0xa8, 0xa4, 0xa2, 0x21, 0xcc, 0x52, 0xe3, 0xbe, 0x6e, + 0x58, 0xf3, 0x31, 0xba, 0x9c, 0x86, 0x22, 0xdf, 0x59, 0x4e, 0x10, 0xb9, + 0x6d, 0x28, 0xae, 0x92, 0xad, 0xdf, 0x68, 0x59, 0xac, 0xa1, 0xce, 0x20, + 0xdb, 0x44, 0xb7, 0xc4, 0xb1, 0xc6, 0x25, 0xba, 0xac, 0x5d, 0xea, 0x90, + 0x51, 0x6d, 0x6f, 0xe2, 0x01, 0xbc, 0xae, 0xe4, 0xee, 0xb9, 0x7d, 0xf0, + 0x74, 0x54, 0x1e, 0x8f, 0x4c, 0xde, 0x92, 0xae, 0x38, 0x4a, 0x6a, 0x64, + 0xca, 0xc1, 0x50, 0x77, 0x08, 0xf2, 0xf1, 0x0b, 0xb4, 0xb2, 0x97, 0xcc, + 0xbb, 0xff, 0x00, 0x26, 0x1d, 0x6e, 0x07, 0x56, 0x15, 0xcb, 0xe6, 0x54, + 0x1a, 0x97, 0xcf, 0xee, 0x51, 0x17, 0x68, 0x1f, 0xd5, 0x12, 0xf2, 0xe6, + 0x59, 0xc4, 0x5e, 0x91, 0x0e, 0xd2, 0xbb, 0xcd, 0xe2, 0x5e, 0x84, 0x70, + 0xe6, 0x59, 0x1c, 0xba, 0x4f, 0x29, 0xab, 0x56, 0xa6, 0xf8, 0x5e, 0xd0, + 0xb3, 0x69, 0x56, 0x94, 0xc4, 0x6b, 0xfe, 0xc4, 0x31, 0xf9, 0x81, 0xac, + 0xfc, 0xc5, 0x9e, 0x25, 0x47, 0x0f, 0x78, 0x84, 0xa8, 0xe1, 0x9b, 0x3c, + 0x0b, 0xfb, 0xd1, 0x9a, 0x94, 0x99, 0x3d, 0xfa, 0x91, 0x77, 0x41, 0xf3, + 0x2e, 0x2c, 0x56, 0x66, 0x5b, 0x33, 0xcc, 0x39, 0x18, 0x72, 0x2b, 0xbc, + 0xa7, 0xf6, 0x4e, 0xb7, 0xde, 0x55, 0xfb, 0xa1, 0xc9, 0x81, 0x83, 0x92, + 0x07, 0x17, 0x88, 0x26, 0xb8, 0x89, 0x8d, 0x11, 0x20, 0xd9, 0xa9, 0x06, + 0x5c, 0xb9, 0x72, 0xfa, 0xcb, 0x97, 0xe9, 0x6b, 0x2e, 0xf7, 0xf5, 0xb9, + 0x51, 0x33, 0x0f, 0x45, 0x4f, 0x12, 0xba, 0x4a, 0x26, 0x88, 0x7a, 0x35, + 0x9d, 0x9e, 0x82, 0xe4, 0xaf, 0xa4, 0xc6, 0x76, 0xc7, 0x2f, 0x42, 0x65, + 0x53, 0x48, 0xdf, 0x69, 0x66, 0xd1, 0x53, 0x03, 0x12, 0xd9, 0x46, 0xdb, + 0xa2, 0xde, 0xd7, 0x78, 0x34, 0xd0, 0xa5, 0x48, 0xf1, 0x10, 0xfc, 0x23, + 0xc5, 0x30, 0x16, 0x37, 0x2c, 0x6c, 0xcf, 0xec, 0x45, 0x61, 0xbe, 0x85, + 0x15, 0x54, 0xb8, 0xe2, 0xca, 0x52, 0xd1, 0x8a, 0x0d, 0x3e, 0x25, 0x43, + 0x88, 0x16, 0xdf, 0x12, 0xe3, 0x93, 0xcc, 0xcb, 0x68, 0xa9, 0x71, 0x9a, + 0xf4, 0x95, 0xe2, 0x32, 0x63, 0xac, 0xa0, 0xf5, 0x8e, 0x17, 0x73, 0xca, + 0x61, 0x39, 0x3f, 0x04, 0xda, 0x02, 0xc0, 0xa8, 0xae, 0x1d, 0x60, 0xdf, + 0xfb, 0x0f, 0xeb, 0x94, 0xf7, 0xf4, 0x7f, 0xb1, 0x2f, 0x7b, 0x87, 0x61, + 0x32, 0x9b, 0x6b, 0xef, 0x01, 0x67, 0x5c, 0x4d, 0x38, 0x99, 0xcb, 0xe9, + 0x14, 0xbe, 0xb1, 0x73, 0xa6, 0x26, 0x94, 0xfa, 0x22, 0x19, 0x9b, 0x3a, + 0x0c, 0x22, 0x85, 0x3d, 0x08, 0xa3, 0x0d, 0xe6, 0xa1, 0x1a, 0x1f, 0x2c, + 0xa5, 0x85, 0x1b, 0xa0, 0x3c, 0x44, 0xba, 0xbc, 0x04, 0xbb, 0x5f, 0x1b, + 0x14, 0xe6, 0xbe, 0xe8, 0x8f, 0xdd, 0x15, 0xdc, 0xf7, 0x67, 0x32, 0xbe, + 0x66, 0x1f, 0xda, 0x34, 0xea, 0xcb, 0x8c, 0xb6, 0x70, 0xc1, 0xbb, 0xd9, + 0x86, 0x34, 0x9b, 0x21, 0xa1, 0x19, 0xfa, 0xd4, 0x25, 0x4f, 0x3e, 0x97, + 0xa7, 0xa5, 0xcb, 0x97, 0x2e, 0x5f, 0x9f, 0xfc, 0x3e, 0x89, 0x73, 0x7a, + 0x9a, 0x52, 0x87, 0xd0, 0x33, 0x5a, 0x3d, 0xd0, 0x8b, 0x54, 0xe9, 0x16, + 0x5e, 0x65, 0xcd, 0x12, 0xfd, 0x03, 0xd6, 0x5f, 0xa6, 0x7d, 0x2a, 0x7c, + 0x4c, 0x74, 0x98, 0xb9, 0x7d, 0x26, 0x67, 0x8a, 0xf4, 0xcc, 0xae, 0x92, + 0xba, 0x4a, 0x20, 0x7a, 0x2b, 0xd1, 0x79, 0x79, 0x77, 0x68, 0x37, 0x15, + 0x17, 0xd4, 0xf8, 0x89, 0x83, 0x4f, 0x04, 0x14, 0x40, 0x74, 0x7e, 0xa8, + 0x85, 0x14, 0x07, 0x74, 0xfc, 0x51, 0x43, 0x41, 0xde, 0x63, 0xe5, 0x19, + 0x57, 0xb0, 0xc5, 0x98, 0x53, 0x78, 0xc8, 0xfa, 0xbc, 0x9f, 0x84, 0x4e, + 0x45, 0xd9, 0xa6, 0x1d, 0x6f, 0x56, 0x0a, 0x2e, 0x78, 0x3f, 0x31, 0xff, + 0x00, 0x88, 0xfd, 0xc6, 0x9c, 0x7b, 0x3f, 0xdc, 0x1e, 0x8f, 0xfb, 0xde, + 0x6d, 0x8f, 0x9f, 0xfa, 0x87, 0xbf, 0x3c, 0xc8, 0x7d, 0x47, 0x94, 0xfc, + 0x4f, 0xab, 0x33, 0x98, 0x07, 0x62, 0xfe, 0x60, 0xad, 0xbf, 0x6b, 0x7d, + 0x40, 0xdf, 0x3e, 0x93, 0x0e, 0xa3, 0xc7, 0xa1, 0x77, 0xa1, 0x0d, 0xb4, + 0x26, 0x2b, 0xda, 0x21, 0x8a, 0x89, 0xde, 0x35, 0x8d, 0x7a, 0x46, 0x13, + 0xa4, 0x1b, 0x82, 0x5f, 0x13, 0x99, 0x8a, 0xda, 0xe6, 0x07, 0x98, 0x56, + 0xed, 0x4c, 0x9b, 0x9a, 0xb2, 0x4a, 0x21, 0x7e, 0x27, 0xf6, 0x25, 0xaf, + 0x49, 0x7e, 0x61, 0x48, 0x95, 0xda, 0x30, 0x45, 0xd9, 0x15, 0x03, 0x91, + 0x66, 0x2f, 0x37, 0x06, 0x31, 0x75, 0x07, 0x2a, 0xe0, 0xdb, 0x1d, 0x15, + 0x16, 0xca, 0x75, 0x65, 0xef, 0x12, 0xdd, 0xe1, 0xc6, 0xf1, 0x75, 0xde, + 0x5a, 0xb3, 0x88, 0xbd, 0xa7, 0x8d, 0x4f, 0x94, 0x7d, 0xb2, 0xff, 0x00, + 0xf2, 0x2c, 0x03, 0xda, 0x01, 0x9c, 0x62, 0x51, 0x28, 0xe3, 0x32, 0xcc, + 0x4b, 0xbe, 0xf0, 0xd1, 0x32, 0x96, 0x9d, 0x9d, 0xa3, 0xa2, 0x44, 0xa4, + 0xe1, 0x81, 0x8f, 0x5b, 0x8f, 0x44, 0xbf, 0x42, 0x5c, 0xba, 0xf5, 0x2d, + 0x97, 0x2e, 0x0f, 0xa5, 0xcb, 0x8f, 0xa8, 0x6a, 0xd0, 0x7a, 0x30, 0x18, + 0x16, 0x72, 0x40, 0x4d, 0x84, 0xb4, 0xb9, 0x72, 0xe5, 0xcb, 0xeb, 0x7e, + 0x94, 0xc0, 0x65, 0x32, 0xa5, 0x30, 0x25, 0x4a, 0x95, 0x98, 0x10, 0x2e, + 0x55, 0xca, 0x95, 0x70, 0xb4, 0x24, 0xbe, 0xd1, 0x80, 0x5f, 0x09, 0xb0, + 0x18, 0x5b, 0xee, 0xa8, 0xf9, 0x97, 0x55, 0xb5, 0x2b, 0xbc, 0x04, 0xf9, + 0x89, 0x0f, 0x30, 0x3f, 0x92, 0xbf, 0x52, 0xbd, 0x35, 0xbd, 0x67, 0xc0, + 0x84, 0x84, 0xa6, 0xf6, 0xbd, 0xed, 0x09, 0x0e, 0x34, 0x3e, 0x90, 0x80, + 0xd8, 0x76, 0x20, 0x2f, 0x04, 0xed, 0x9d, 0x91, 0xe9, 0x9d, 0x0d, 0xa6, + 0x5b, 0x62, 0x22, 0xf4, 0xc4, 0xed, 0xcc, 0x6c, 0xc4, 0xd4, 0x7a, 0x71, + 0x13, 0xa1, 0x18, 0x76, 0x6b, 0x2c, 0xb9, 0xd4, 0xb9, 0xe0, 0xa8, 0x0e, + 0xa1, 0x87, 0xa7, 0x62, 0x58, 0x1e, 0x3b, 0xd1, 0xf8, 0x4b, 0xb5, 0x8e, + 0xf7, 0xdc, 0xb4, 0x44, 0xe3, 0xf2, 0x48, 0x72, 0x86, 0x6f, 0xf8, 0x18, + 0x98, 0xee, 0x51, 0x2f, 0xe1, 0x4d, 0xa3, 0x8c, 0x52, 0xe2, 0x9b, 0x4a, + 0x63, 0x88, 0xc5, 0xf2, 0xfa, 0x72, 0x48, 0xae, 0xaa, 0x6f, 0x89, 0x93, + 0x09, 0xc3, 0x99, 0x52, 0xa2, 0x85, 0x6d, 0x01, 0xd1, 0x8f, 0x94, 0xae, + 0x13, 0xd5, 0x86, 0x9a, 0x12, 0xb8, 0x79, 0x49, 0x6b, 0x57, 0xe8, 0xa6, + 0xa2, 0x5a, 0xe3, 0x94, 0xc4, 0x66, 0xbf, 0xc4, 0x6d, 0x18, 0xbc, 0xc7, + 0xae, 0x23, 0xde, 0x53, 0x50, 0x5a, 0x90, 0x11, 0x73, 0x1b, 0x4c, 0x0e, + 0x93, 0x2b, 0xdb, 0xa4, 0xce, 0xba, 0x4c, 0xf4, 0xf4, 0x10, 0x3a, 0xf7, + 0x1d, 0x18, 0x8c, 0xa4, 0x95, 0x29, 0x8e, 0x9e, 0x9b, 0x4a, 0xff, 0x00, + 0xd3, 0x16, 0x66, 0xe5, 0xc5, 0x8b, 0x2f, 0x12, 0x9b, 0x96, 0x49, 0x68, + 0x3d, 0x86, 0x09, 0x53, 0x5b, 0x90, 0x50, 0x61, 0x89, 0xda, 0xa6, 0x53, + 0xb3, 0x26, 0x6a, 0x03, 0xbb, 0x83, 0xec, 0xf7, 0xa2, 0x01, 0xaa, 0x3b, + 0xfe, 0xc8, 0x1e, 0xbe, 0x1b, 0x47, 0xf6, 0xb4, 0x4f, 0xf7, 0xa3, 0xac, + 0x2e, 0xee, 0x6a, 0x21, 0xdc, 0x89, 0x62, 0x27, 0xb4, 0x4f, 0x68, 0x94, + 0x55, 0xb4, 0xb1, 0xb4, 0xbc, 0x5b, 0x88, 0x3e, 0x25, 0xad, 0x2e, 0x17, + 0x16, 0xaa, 0xf0, 0xfd, 0x0f, 0x79, 0x65, 0x5b, 0xa9, 0x47, 0xe2, 0xc7, + 0xcc, 0x5c, 0x8f, 0x94, 0x45, 0xfb, 0x7e, 0x66, 0xce, 0xb1, 0xf6, 0xc1, + 0x80, 0x68, 0xa0, 0x6c, 0x4e, 0x9c, 0x3a, 0x21, 0x25, 0x5d, 0x2e, 0x5d, + 0xda, 0x76, 0xe3, 0xb4, 0xd3, 0xd2, 0x3d, 0x31, 0xc3, 0x98, 0xad, 0xc8, + 0xd2, 0x63, 0x78, 0xf7, 0x8b, 0xc4, 0x47, 0x15, 0x3a, 0x31, 0x7c, 0x45, + 0xe2, 0xe3, 0x5d, 0x09, 0xc8, 0x41, 0xe2, 0x61, 0x71, 0x19, 0xe8, 0x4a, + 0x25, 0x12, 0xfd, 0xa5, 0xac, 0x1f, 0x45, 0x32, 0xd6, 0xc2, 0xe1, 0xea, + 0x85, 0xe8, 0xfc, 0x69, 0x3a, 0xa9, 0xa6, 0x21, 0xa1, 0x16, 0xc2, 0xa3, + 0x6c, 0x95, 0xed, 0xe8, 0xb9, 0x1f, 0x09, 0x75, 0xac, 0x59, 0x69, 0xbd, + 0xcc, 0xa6, 0x28, 0x03, 0xb7, 0x59, 0x83, 0x3e, 0x59, 0x5a, 0xd6, 0x6a, + 0x66, 0x2a, 0x6f, 0xcd, 0xc4, 0x74, 0x71, 0xec, 0x44, 0xa9, 0x52, 0x8d, + 0xdf, 0x68, 0x8d, 0xa2, 0xee, 0x5d, 0x96, 0x97, 0x2e, 0x5d, 0xe2, 0x75, + 0x9a, 0x32, 0xfc, 0x4a, 0x89, 0x98, 0x16, 0xeb, 0x0c, 0x4b, 0x34, 0x8b, + 0xd2, 0x2c, 0x33, 0x99, 0x57, 0x50, 0x31, 0x3f, 0x8c, 0xb3, 0x2c, 0xca, + 0x9d, 0xdc, 0x2f, 0xda, 0x52, 0x24, 0xa4, 0xa2, 0x21, 0x10, 0x89, 0xea, + 0xfa, 0xbe, 0xba, 0xca, 0x84, 0x0a, 0x0d, 0xda, 0x68, 0x69, 0x94, 0xf4, + 0xce, 0x29, 0x9e, 0xe1, 0x2d, 0x80, 0xbc, 0x2f, 0xc5, 0xdf, 0xc4, 0x38, + 0x0f, 0xb8, 0xa7, 0xd1, 0x28, 0x16, 0x37, 0x08, 0xfb, 0x61, 0x75, 0x51, + 0xcf, 0xf6, 0x42, 0x82, 0x03, 0x96, 0x7d, 0x54, 0xa8, 0xb3, 0xdd, 0xf6, + 0x31, 0xcc, 0x5b, 0xd4, 0x43, 0xe8, 0x7f, 0x9e, 0x25, 0x7a, 0x40, 0xe0, + 0x0f, 0xc4, 0x59, 0x7d, 0x45, 0x1f, 0xd4, 0x70, 0x10, 0x3d, 0x47, 0xa4, + 0x1f, 0x43, 0xbf, 0x6c, 0x13, 0x1f, 0xd4, 0xdc, 0x84, 0x7b, 0xa3, 0x90, + 0x6b, 0x92, 0xfe, 0xec, 0x43, 0xdb, 0x9f, 0xef, 0x85, 0x83, 0xb4, 0x9e, + 0xd7, 0x5e, 0xc9, 0x50, 0x69, 0xad, 0x6a, 0xb0, 0xf9, 0xb8, 0x64, 0x05, + 0xce, 0x25, 0xd2, 0xe9, 0x0e, 0xdc, 0xdd, 0x6f, 0x7b, 0x0a, 0x22, 0x53, + 0xef, 0xf9, 0xc8, 0x28, 0x23, 0x50, 0x9f, 0x80, 0xbf, 0x98, 0x9a, 0x06, + 0x85, 0x5f, 0xcd, 0x98, 0x70, 0x6b, 0x00, 0x28, 0x97, 0x9a, 0x4e, 0x84, + 0xbf, 0x69, 0xd1, 0x99, 0x34, 0x9b, 0x95, 0x30, 0x69, 0x34, 0x31, 0x0b, + 0xed, 0x0e, 0x88, 0x5f, 0x6b, 0x8f, 0x45, 0x4d, 0x15, 0x51, 0x0d, 0xbc, + 0x45, 0xc5, 0x15, 0x10, 0xda, 0x2e, 0xac, 0x26, 0xed, 0x46, 0x19, 0xe8, + 0xca, 0x71, 0x3a, 0x1e, 0x8d, 0x5c, 0xcc, 0x35, 0x59, 0xeb, 0x35, 0x71, + 0xe8, 0x70, 0x7a, 0x2b, 0x53, 0x5b, 0xd1, 0xd5, 0xc4, 0xe4, 0x81, 0x9b, + 0x23, 0xb5, 0x2d, 0x84, 0x7d, 0xb7, 0x2f, 0xc3, 0xd9, 0x85, 0x4c, 0xec, + 0x23, 0x1b, 0x4a, 0x9c, 0x92, 0xfd, 0x08, 0xbc, 0x46, 0x33, 0x4c, 0x50, + 0xdd, 0x31, 0x66, 0x08, 0x60, 0x8b, 0x7d, 0x04, 0x09, 0x9c, 0x4a, 0xe1, + 0x1d, 0x65, 0x31, 0x2e, 0xe0, 0x9a, 0xab, 0xf4, 0x18, 0xb2, 0xd3, 0xd5, + 0xe2, 0x33, 0x2b, 0x6b, 0x32, 0x0b, 0x88, 0x83, 0x73, 0x12, 0xae, 0x04, + 0xab, 0x8c, 0x26, 0x92, 0xbd, 0x14, 0x0c, 0xae, 0x63, 0xe8, 0x9c, 0x26, + 0x52, 0xe9, 0x15, 0xb1, 0x89, 0x6f, 0x3d, 0x60, 0xa1, 0xd1, 0x30, 0x31, + 0x32, 0xea, 0x95, 0x6c, 0xc4, 0xa1, 0x61, 0x9a, 0x74, 0x8f, 0x0b, 0x1e, + 0x36, 0x3c, 0x51, 0x0d, 0xa5, 0x89, 0x73, 0x69, 0xd9, 0x19, 0x7a, 0x25, + 0x47, 0xd1, 0x95, 0x72, 0x96, 0x0d, 0x8f, 0xb2, 0xe0, 0xab, 0x5a, 0x95, + 0x9e, 0xe3, 0xa1, 0xe6, 0x05, 0x15, 0x2e, 0xca, 0x5d, 0xcc, 0x3e, 0x61, + 0xc0, 0xfc, 0x87, 0xbd, 0x2b, 0xf2, 0x42, 0x81, 0x0c, 0x07, 0xe6, 0x1f, + 0x98, 0xa9, 0x00, 0x1a, 0x07, 0xa4, 0x3c, 0xc2, 0x43, 0x01, 0x00, 0xc2, + 0xdb, 0x42, 0xaa, 0x0d, 0x4c, 0x10, 0xdc, 0xb1, 0x41, 0xe2, 0x29, 0x93, + 0xeb, 0x59, 0x71, 0xe9, 0xdb, 0x2f, 0x9d, 0x0c, 0x4c, 0xb2, 0xfe, 0xb3, + 0x1e, 0x93, 0xfa, 0x7d, 0x1c, 0x7a, 0x4b, 0xf6, 0xc4, 0xc5, 0x82, 0x59, + 0xb4, 0x6e, 0xd3, 0x06, 0x93, 0xa1, 0x50, 0x30, 0x27, 0xfc, 0x95, 0xe9, + 0xe2, 0x27, 0x8c, 0x44, 0xd1, 0x8a, 0x9a, 0xb8, 0xc4, 0xb7, 0x68, 0xb5, + 0x1c, 0x08, 0x78, 0xa8, 0x19, 0xc4, 0xe9, 0xfa, 0x36, 0xe5, 0x82, 0x4d, + 0x6e, 0x26, 0x3a, 0x71, 0x29, 0xd2, 0x7b, 0x13, 0xdb, 0xf4, 0xeb, 0xff, + 0x00, 0xc8, 0xf0, 0xe9, 0x04, 0x72, 0xab, 0x5d, 0x97, 0x53, 0xcc, 0x4a, + 0x3f, 0x4a, 0x5a, 0xf3, 0x71, 0xdc, 0xfd, 0x82, 0x2f, 0xf4, 0x74, 0x09, + 0xcf, 0x78, 0x7e, 0x21, 0xc5, 0x7b, 0xfe, 0xd8, 0x73, 0x1e, 0x87, 0xf9, + 0x94, 0x72, 0xfe, 0x79, 0x8a, 0x16, 0x53, 0xfb, 0xe6, 0x09, 0xf1, 0x3f, + 0x74, 0xd3, 0x3b, 0xf7, 0xf3, 0x0a, 0x9c, 0x95, 0xe8, 0x69, 0x82, 0x2d, + 0x84, 0xc7, 0x3f, 0x08, 0x4f, 0x87, 0x00, 0xd4, 0x59, 0x05, 0xba, 0x13, + 0x0d, 0xc4, 0x90, 0x5a, 0x55, 0xf6, 0x31, 0x82, 0xc2, 0xec, 0xcd, 0xe4, + 0x58, 0x8c, 0x1b, 0xd6, 0x5d, 0x5c, 0x1c, 0x4b, 0xd6, 0x5c, 0xab, 0xda, + 0x02, 0xb0, 0xd5, 0x0e, 0x98, 0x5b, 0xd0, 0x74, 0x43, 0xa2, 0x2a, 0x62, + 0x09, 0xda, 0x62, 0xd1, 0x96, 0xce, 0x20, 0xf8, 0x87, 0x17, 0xc4, 0xe9, + 0x31, 0x52, 0xb1, 0x71, 0x3a, 0xda, 0xa4, 0x3b, 0xdc, 0xea, 0x3e, 0x80, + 0x97, 0x59, 0x0e, 0x3f, 0x55, 0x31, 0x77, 0x0f, 0xe3, 0x51, 0xd0, 0xf5, + 0x6a, 0xaf, 0xca, 0x43, 0x2e, 0xfa, 0x67, 0xd6, 0x7f, 0xa8, 0x21, 0x21, + 0xfa, 0x9c, 0x0d, 0x4f, 0x67, 0xaf, 0xf7, 0x12, 0x7a, 0x88, 0xfd, 0xac, + 0x7c, 0x23, 0x3d, 0x27, 0xaf, 0xbe, 0x21, 0x36, 0xa8, 0xbd, 0xa5, 0x11, + 0xf4, 0x06, 0xc5, 0x7c, 0xb4, 0x82, 0x3a, 0x04, 0x72, 0xf5, 0x2e, 0xcd, + 0xa7, 0x42, 0xe3, 0xca, 0x41, 0xdf, 0xdf, 0x59, 0x3a, 0x1f, 0xb0, 0xc1, + 0x6f, 0xf4, 0x27, 0x60, 0x13, 0x46, 0x23, 0xd7, 0x33, 0x84, 0x72, 0x84, + 0x12, 0x3a, 0x85, 0x61, 0x39, 0x60, 0x79, 0x85, 0x9d, 0x61, 0x02, 0x97, + 0x9a, 0x89, 0xe7, 0xe9, 0x37, 0x07, 0xaf, 0x85, 0x4b, 0x39, 0x83, 0xc4, + 0xd0, 0xc7, 0xa3, 0xa1, 0x7e, 0x8d, 0x89, 0x88, 0x18, 0xc4, 0x0e, 0x25, + 0x75, 0x88, 0xaf, 0x44, 0x4b, 0x31, 0xef, 0x15, 0x64, 0xbb, 0x56, 0xa5, + 0x02, 0xcf, 0x04, 0xac, 0xd5, 0x7a, 0xd4, 0xe3, 0x5e, 0x59, 0x6b, 0x19, + 0xc1, 0x78, 0x77, 0x81, 0x7a, 0x11, 0x17, 0x02, 0xba, 0x4a, 0xcd, 0x26, + 0x47, 0x04, 0xc8, 0xd1, 0x0b, 0x8a, 0xf4, 0xeb, 0x95, 0x4a, 0x36, 0xf4, + 0x35, 0x31, 0x3a, 0x12, 0x99, 0xd1, 0xf4, 0x84, 0xe9, 0x7a, 0x46, 0xbd, + 0x7d, 0x71, 0x4c, 0xfa, 0xcb, 0xef, 0x11, 0xe8, 0x4c, 0xfa, 0x30, 0x8e, + 0x1e, 0x86, 0x5a, 0xc6, 0x00, 0x1c, 0x17, 0xb4, 0xa8, 0xb5, 0x00, 0xb1, + 0x1d, 0x86, 0x99, 0x47, 0xf2, 0x29, 0xad, 0x67, 0x84, 0xfc, 0xc7, 0x4d, + 0x5a, 0xba, 0x3d, 0xcd, 0x78, 0x97, 0x46, 0x1c, 0x33, 0xc3, 0x67, 0xc4, + 0xb0, 0x78, 0x03, 0xdb, 0xd8, 0xfa, 0x97, 0x83, 0x9b, 0x9d, 0xfb, 0x51, + 0xf6, 0x9b, 0x2a, 0x3a, 0xb1, 0xf7, 0xd6, 0x28, 0xa4, 0x4e, 0xf0, 0x82, + 0x08, 0xd1, 0x33, 0x85, 0x75, 0x84, 0x9d, 0x12, 0xcd, 0x08, 0x65, 0x3b, + 0xa1, 0x64, 0x17, 0x59, 0x46, 0x3e, 0x23, 0xe5, 0x37, 0x7a, 0xca, 0xca, + 0xe8, 0x7e, 0xb8, 0xff, 0x00, 0xb5, 0x90, 0x3c, 0x7e, 0x0c, 0x79, 0x33, + 0xbb, 0xfe, 0x05, 0x3d, 0xe0, 0xb1, 0xb8, 0xe4, 0xfe, 0x04, 0x3e, 0x95, + 0xfc, 0x19, 0x8b, 0x12, 0x3d, 0x1f, 0xe5, 0x40, 0xc3, 0x0d, 0x17, 0x7e, + 0x0c, 0x57, 0x56, 0xef, 0xff, 0x00, 0xcb, 0xac, 0x02, 0xf9, 0x98, 0x54, + 0x12, 0x14, 0x3b, 0x30, 0x42, 0xc9, 0xbb, 0x0c, 0xef, 0x99, 0x9e, 0xb2, + 0xd1, 0x79, 0xa2, 0x0f, 0x10, 0x38, 0x33, 0x58, 0x34, 0xf1, 0x84, 0x21, + 0x75, 0x74, 0x2c, 0xed, 0x68, 0x7c, 0x31, 0xff, 0x00, 0x0d, 0x15, 0xab, + 0xc0, 0x45, 0x89, 0x52, 0xc2, 0xc7, 0xb6, 0x9e, 0x59, 0xe9, 0x05, 0x52, + 0x15, 0xef, 0x5a, 0xcf, 0x83, 0x11, 0xf4, 0xda, 0x46, 0x29, 0x19, 0x3d, + 0x02, 0x7a, 0xe9, 0x85, 0xe1, 0x06, 0x7f, 0xf8, 0x02, 0xd9, 0x9f, 0xd7, + 0x9c, 0x76, 0xe6, 0x0c, 0xf3, 0x19, 0xf4, 0x69, 0xaf, 0x4e, 0xd9, 0x62, + 0x4d, 0xda, 0x9d, 0x29, 0x8a, 0x0f, 0x13, 0x37, 0x33, 0xa7, 0x05, 0x9c, + 0x47, 0xc4, 0xf0, 0xc1, 0x0c, 0x90, 0x83, 0x48, 0x07, 0xa4, 0x07, 0xa2, + 0x92, 0xb1, 0x2c, 0xa4, 0x0d, 0x65, 0x97, 0x89, 0x5e, 0xd3, 0x2e, 0x09, + 0xd1, 0x80, 0x3a, 0x66, 0x74, 0xe5, 0x3b, 0x45, 0x73, 0x2a, 0xda, 0x74, + 0xe6, 0xa4, 0xa9, 0x7d, 0x1a, 0xee, 0x0a, 0x9a, 0x65, 0x38, 0xf4, 0x9d, + 0x6e, 0x1a, 0x86, 0x38, 0xe2, 0x8e, 0xa2, 0xa9, 0xa9, 0xbf, 0xa1, 0x8a, + 0x46, 0x1f, 0x46, 0xb0, 0xd0, 0x83, 0xbb, 0x5f, 0x89, 0x76, 0x8b, 0x02, + 0xb2, 0xde, 0x9f, 0x10, 0x93, 0xc2, 0x18, 0xcd, 0x7e, 0x92, 0xea, 0x66, + 0xa0, 0x0f, 0x86, 0x30, 0x27, 0x78, 0xe1, 0xfc, 0x71, 0x06, 0x03, 0xda, + 0x7b, 0x1e, 0x72, 0xf7, 0x3b, 0x4d, 0xf2, 0x99, 0x13, 0xd4, 0xbd, 0x4e, + 0xa4, 0xb6, 0x6c, 0x98, 0x46, 0x60, 0x05, 0xa6, 0x80, 0x87, 0xa7, 0x16, + 0x36, 0xbe, 0x6a, 0xcf, 0x62, 0xd8, 0xb1, 0xab, 0x16, 0xc0, 0x71, 0x7d, + 0x5f, 0x28, 0xb1, 0x4e, 0xe4, 0x7b, 0x3a, 0x05, 0xfb, 0xac, 0x72, 0x71, + 0xc0, 0x87, 0x79, 0xcb, 0xcb, 0xff, 0x00, 0xe4, 0x70, 0x16, 0x30, 0x50, + 0xec, 0x62, 0xab, 0x10, 0xad, 0x8c, 0xc1, 0x50, 0xb4, 0x10, 0x3a, 0x8c, + 0x03, 0x1b, 0x5f, 0x54, 0xd3, 0xc0, 0x25, 0x33, 0x37, 0x4a, 0x5c, 0xc6, + 0x1e, 0xab, 0xf5, 0x32, 0x96, 0x21, 0x39, 0x57, 0xa0, 0xbc, 0x3a, 0xa7, + 0x56, 0x65, 0x9d, 0x49, 0x96, 0x5f, 0xd7, 0xff, 0x00, 0x1d, 0x2d, 0x3d, + 0x19, 0xcc, 0x50, 0x5c, 0x3b, 0xc7, 0x99, 0x2e, 0x5f, 0x52, 0x9c, 0x54, + 0xe2, 0xd6, 0x64, 0xd2, 0x5d, 0x9a, 0x8e, 0xd6, 0x25, 0x3b, 0x4a, 0x86, + 0x20, 0x40, 0x80, 0xff, 0x00, 0xe6, 0xc1, 0x0d, 0x27, 0x42, 0x74, 0x66, + 0xc4, 0xe9, 0xcd, 0x49, 0x9a, 0x55, 0x77, 0xa4, 0xc1, 0x29, 0xda, 0x6a, + 0x35, 0x2b, 0xf4, 0x57, 0xd2, 0xc7, 0xd0, 0x56, 0x4c, 0xc8, 0xaa, 0x28, + 0xea, 0xfd, 0x2a, 0xb4, 0x98, 0x35, 0xf4, 0x58, 0x65, 0xf5, 0x8f, 0x54, + 0x71, 0xac, 0x18, 0x72, 0xe7, 0xf3, 0x09, 0x9a, 0x0a, 0x1d, 0x0a, 0xf4, + 0x49, 0xbb, 0xd3, 0x4a, 0x83, 0x48, 0x32, 0x46, 0x52, 0x30, 0xd9, 0x65, + 0xa7, 0x53, 0x87, 0xa9, 0x03, 0x9b, 0xea, 0x0b, 0xe9, 0xa8, 0x76, 0xb7, + 0x72, 0x62, 0xab, 0x80, 0x1e, 0xa5, 0xd0, 0xf9, 0xca, 0xa0, 0xb4, 0xa7, + 0x9f, 0x71, 0x0a, 0x3b, 0x1d, 0xd3, 0x62, 0xdd, 0xfc, 0xeb, 0xf2, 0xff, + 0x00, 0xf4, 0xa3, 0x0b, 0x19, 0x80, 0x25, 0x91, 0x52, 0xa5, 0x86, 0xae, + 0x6f, 0xbd, 0x26, 0xa4, 0xae, 0xf7, 0x8f, 0x84, 0xef, 0x8c, 0x65, 0xbf, + 0xa1, 0xea, 0x9d, 0xd0, 0xf4, 0x4a, 0x43, 0xaa, 0x68, 0x47, 0xf5, 0x3b, + 0x77, 0xf4, 0xbd, 0xef, 0x52, 0x6e, 0x18, 0xb4, 0x9a, 0xfd, 0x6b, 0x43, + 0x12, 0xed, 0x33, 0x2c, 0x97, 0x15, 0x50, 0xf9, 0x9a, 0x58, 0xcc, 0xc9, + 0x2f, 0x95, 0x15, 0x03, 0xff, 0x00, 0xb3, 0x12, 0x07, 0x10, 0x1d, 0xa0, + 0x5e, 0x92, 0xc7, 0x49, 0x45, 0xe1, 0xf4, 0x42, 0x51, 0xb6, 0x92, 0xdd, + 0x67, 0x09, 0x3a, 0x9e, 0x99, 0xa9, 0xd9, 0x07, 0xa1, 0xb1, 0x14, 0x51, + 0xc7, 0xe9, 0x3a, 0xe2, 0x6a, 0x47, 0xcb, 0xd0, 0x71, 0x8c, 0x6a, 0x8c, + 0x5d, 0x38, 0xf5, 0xec, 0x4f, 0xd4, 0xa0, 0x21, 0x9c, 0x3d, 0x22, 0x8a, + 0xe2, 0xa7, 0x99, 0x62, 0x45, 0x41, 0x58, 0x88, 0xec, 0x63, 0xac, 0xc2, + 0x50, 0xff, 0x00, 0xf6, 0x02, 0x24, 0xd0, 0xd0, 0xd3, 0x69, 0x4d, 0xc3, + 0xb6, 0x6a, 0xcd, 0x49, 0x43, 0xaf, 0x9f, 0x43, 0xe8, 0x67, 0x09, 0x60, + 0xf6, 0xc2, 0x4b, 0x43, 0xaa, 0x75, 0x3d, 0x32, 0xfe, 0xbf, 0xd4, 0xf4, + 0x19, 0x33, 0x8f, 0xac, 0x77, 0xd2, 0x18, 0x34, 0xf4, 0xba, 0x19, 0x9d, + 0xb3, 0x2f, 0x48, 0x4d, 0x62, 0x79, 0xe6, 0x8c, 0xd0, 0xe6, 0x11, 0xed, + 0x30, 0x38, 0x83, 0x8f, 0xfe, 0xeb, 0x1f, 0x28, 0xd2, 0xfd, 0x5c, 0x4b, + 0x95, 0x08, 0xb5, 0xcc, 0xb1, 0xb8, 0x46, 0xb1, 0x5b, 0xda, 0x61, 0x97, + 0x5e, 0xd3, 0x23, 0x07, 0x8f, 0x40, 0xf4, 0xd5, 0xbc, 0xb4, 0x8b, 0x99, + 0xba, 0x6a, 0x7f, 0xe2, 0x27, 0xaa, 0x75, 0x65, 0x11, 0xe5, 0x1c, 0xa3, + 0x9a, 0x59, 0xe5, 0x93, 0x7a, 0xb5, 0x3e, 0xfd, 0x55, 0xac, 0xf3, 0x4e, + 0x49, 0x9a, 0x2d, 0xf5, 0x95, 0x1f, 0x51, 0xb6, 0x50, 0xb4, 0x12, 0x9c, + 0x3e, 0x25, 0xc6, 0x3f, 0xfd, 0x36, 0x4b, 0x39, 0x94, 0xc3, 0xb9, 0xbc, + 0x2d, 0x52, 0x0e, 0x14, 0xa5, 0x63, 0x66, 0x64, 0x65, 0x13, 0x36, 0xb1, + 0xbf, 0xfe, 0x1f, 0x7c, 0x2d, 0x1e, 0xaf, 0x41, 0x07, 0x54, 0xcb, 0xe9, + 0x59, 0x0f, 0x99, 0x7f, 0xa5, 0xa1, 0x14, 0x7a, 0x47, 0x72, 0xd3, 0x3a, + 0x82, 0xfd, 0x0c, 0xb3, 0x34, 0xe3, 0xd2, 0x69, 0x40, 0x62, 0x50, 0x20, + 0x79, 0x9c, 0x3e, 0xd1, 0xea, 0xf0, 0x77, 0x87, 0x54, 0x04, 0x12, 0x5f, + 0xaa, 0x84, 0x4a, 0xb3, 0x3a, 0xd7, 0x2b, 0x61, 0xb7, 0x33, 0xa9, 0x04, + 0x02, 0x69, 0x16, 0x00, 0x2d, 0xc1, 0x3d, 0x0c, 0xef, 0x31, 0xc1, 0x9d, + 0x08, 0x2e, 0x65, 0x46, 0xb1, 0xf9, 0x9c, 0x9b, 0xcb, 0x2e, 0x0b, 0x57, + 0xc5, 0xcc, 0xbf, 0x53, 0x7c, 0xb2, 0xe0, 0xa9, 0xba, 0x1e, 0xb5, 0xe8, + 0xc7, 0x31, 0x12, 0xd4, 0xb4, 0xc4, 0x7a, 0xcc, 0xb0, 0x3d, 0x0e, 0xbc, + 0x1d, 0xee, 0x0f, 0xa2, 0xd2, 0x65, 0x2c, 0xfd, 0x15, 0xf8, 0x89, 0x9d, + 0x53, 0x2f, 0x55, 0x3f, 0x89, 0x50, 0xd6, 0x77, 0xfa, 0x79, 0xfd, 0x0d, + 0x1a, 0x73, 0x2c, 0x4c, 0xfb, 0xca, 0xc1, 0x08, 0x15, 0x5c, 0x61, 0x57, + 0xb4, 0xb5, 0x1d, 0x21, 0x19, 0x62, 0x1b, 0xc0, 0xee, 0x82, 0xef, 0x2b, + 0xff, 0x00, 0xe2, 0x32, 0x98, 0x06, 0xf1, 0x29, 0xae, 0x60, 0x10, 0xeb, + 0x59, 0xad, 0x98, 0x79, 0xdb, 0x4a, 0xa1, 0x95, 0x87, 0x98, 0x05, 0xc0, + 0x6f, 0xd6, 0x30, 0xcf, 0x7c, 0x24, 0xa6, 0xf1, 0xb7, 0xa9, 0x2b, 0x32, + 0xcb, 0xb7, 0xf4, 0x7a, 0xd2, 0xcf, 0x4e, 0xc8, 0xf7, 0xf4, 0xba, 0xa2, + 0x83, 0x4c, 0xce, 0x94, 0x6d, 0xa0, 0x62, 0xa6, 0x02, 0x6b, 0x20, 0x00, + 0xcf, 0xf1, 0x44, 0xe8, 0x9b, 0x86, 0xe6, 0x9d, 0x63, 0xa4, 0xc3, 0x96, + 0x21, 0xbc, 0x4c, 0x5c, 0xd2, 0x57, 0xc0, 0x09, 0x69, 0xb6, 0x06, 0x5a, + 0x4a, 0xb3, 0xd3, 0x13, 0xf7, 0x10, 0x43, 0xc3, 0x7e, 0x92, 0xe1, 0xcb, + 0xb7, 0xeb, 0x96, 0xb8, 0x6f, 0xeb, 0x88, 0x0a, 0x8b, 0x9d, 0x2a, 0x45, + 0x28, 0x4d, 0x54, 0x9f, 0x88, 0x86, 0x3c, 0xdf, 0xae, 0x5a, 0x5d, 0x0e, + 0x99, 0xee, 0x47, 0x01, 0x77, 0x0a, 0x40, 0xcc, 0x1d, 0x45, 0xc6, 0x81, + 0xb1, 0xc4, 0xa0, 0xcb, 0x0d, 0xfa, 0x0c, 0xa5, 0xac, 0xbd, 0xab, 0x9d, + 0x79, 0x74, 0xb3, 0x48, 0xc7, 0x5e, 0xd2, 0xcb, 0x97, 0x69, 0x16, 0x21, + 0xcd, 0xc3, 0xad, 0x4b, 0xa6, 0x48, 0xb5, 0xcc, 0xaa, 0x29, 0x9a, 0x58, + 0x4a, 0xfd, 0x5d, 0x3d, 0x0a, 0x3d, 0x06, 0x2c, 0x75, 0x99, 0x1a, 0xbe, + 0x11, 0x4b, 0x64, 0xce, 0x5f, 0x20, 0x0f, 0xdf, 0xa4, 0xea, 0x9d, 0x79, + 0x6f, 0xa7, 0x67, 0x79, 0x75, 0x4e, 0x82, 0x94, 0x98, 0x68, 0xcc, 0x03, + 0xa9, 0x1b, 0xe8, 0xc4, 0xd4, 0xca, 0x0d, 0x66, 0x5d, 0x62, 0x3b, 0xdf, + 0xff, 0x00, 0x8d, 0x94, 0x3a, 0xca, 0xb7, 0xf4, 0xdd, 0x68, 0x23, 0xc2, + 0x1a, 0x66, 0x5a, 0x56, 0xcb, 0x5a, 0x50, 0xb9, 0x97, 0x5c, 0xcc, 0xdb, + 0x07, 0x98, 0x37, 0x88, 0xda, 0x77, 0xc6, 0x1b, 0xfa, 0x4e, 0xa9, 0x64, + 0x20, 0x93, 0x29, 0xd4, 0x8e, 0xfa, 0x7d, 0x5f, 0x4e, 0xd9, 0x65, 0x4c, + 0xa5, 0x47, 0x71, 0xc7, 0x33, 0xaf, 0x4a, 0xc1, 0x00, 0x54, 0xa2, 0x7f, + 0xbc, 0xe7, 0x71, 0x04, 0x42, 0x1b, 0x61, 0xa0, 0x61, 0xc2, 0x1b, 0x6c, + 0x73, 0xab, 0x47, 0x2f, 0x89, 0x77, 0x04, 0x73, 0x80, 0xf8, 0x4d, 0x4c, + 0x5b, 0x93, 0xf6, 0xc7, 0xdc, 0xeb, 0x5e, 0x04, 0x7c, 0xdb, 0xf3, 0x15, + 0xac, 0xf2, 0xfd, 0x03, 0x51, 0xa3, 0x6e, 0x32, 0x22, 0xbe, 0xf0, 0x68, + 0x60, 0xe8, 0xa8, 0x0d, 0xb9, 0x75, 0x88, 0x38, 0x87, 0x7a, 0xcb, 0xab, + 0x33, 0x14, 0x3a, 0xeb, 0x30, 0x5d, 0x55, 0xab, 0x1a, 0x03, 0x5b, 0x29, + 0x8d, 0x1e, 0x6f, 0x31, 0xe2, 0x9e, 0x98, 0xb3, 0x6c, 0xba, 0x14, 0x34, + 0x30, 0x3b, 0x5d, 0x43, 0x24, 0x4d, 0xa1, 0x43, 0xe0, 0x7e, 0x61, 0x3b, + 0xbe, 0x85, 0x32, 0xbf, 0x4e, 0x1a, 0x68, 0x0f, 0x6c, 0xbe, 0xd0, 0x0c, + 0x05, 0x57, 0x59, 0x1e, 0x1c, 0xcb, 0x34, 0xb7, 0xac, 0xd4, 0xdd, 0x35, + 0x96, 0x69, 0x29, 0x96, 0xc5, 0x46, 0xb3, 0x50, 0x8e, 0xe7, 0xb6, 0x01, + 0x35, 0xa2, 0x5f, 0x4b, 0x9d, 0x68, 0x6d, 0x67, 0x57, 0xd1, 0xe3, 0x95, + 0xff, 0x00, 0xe2, 0x8a, 0x77, 0x98, 0xe2, 0xdd, 0x52, 0x67, 0xf2, 0x26, + 0x30, 0xa5, 0x3f, 0x2c, 0xfc, 0x7a, 0x08, 0xaf, 0xd1, 0xd2, 0x99, 0x0c, + 0xc0, 0x44, 0x01, 0x6b, 0x0c, 0x19, 0x94, 0x8a, 0x65, 0x9e, 0x61, 0x37, + 0x61, 0x86, 0xb7, 0x15, 0x73, 0xd2, 0x33, 0x52, 0xf4, 0xbf, 0x72, 0x69, + 0x31, 0xd8, 0x7f, 0xf8, 0x00, 0x20, 0x97, 0x99, 0x5b, 0x96, 0x51, 0x79, + 0x8b, 0x75, 0x73, 0xad, 0x3a, 0x9f, 0x30, 0x9f, 0x32, 0xd7, 0x84, 0xc8, + 0xcc, 0xa1, 0x66, 0x59, 0xd7, 0x99, 0x25, 0x04, 0x7a, 0xe3, 0xe9, 0x53, + 0x98, 0x63, 0x09, 0x04, 0x2c, 0x76, 0x98, 0x99, 0x83, 0xd9, 0xef, 0x31, + 0x6c, 0x3c, 0xcc, 0x52, 0x9e, 0x06, 0x01, 0x59, 0xf9, 0x86, 0xcc, 0x90, + 0x2f, 0x41, 0xde, 0x50, 0xa0, 0x3a, 0x40, 0xe2, 0x21, 0x2f, 0xac, 0x71, + 0xd5, 0x4d, 0x08, 0xfb, 0x4e, 0x69, 0xa1, 0xb4, 0xad, 0x29, 0x54, 0xb3, + 0xc4, 0x54, 0x5b, 0xad, 0xd7, 0xb4, 0x15, 0x47, 0x58, 0xe3, 0xf0, 0xf9, + 0x85, 0xa2, 0x7a, 0x26, 0x7f, 0x80, 0xf9, 0x87, 0x72, 0x3b, 0x98, 0xbd, + 0x8a, 0x3e, 0x25, 0x44, 0x23, 0x83, 0x43, 0x38, 0xca, 0x97, 0x36, 0x74, + 0xa8, 0xde, 0x95, 0x1d, 0xaa, 0xc5, 0x5a, 0xd8, 0x45, 0x16, 0x55, 0x76, + 0xcd, 0x68, 0xb8, 0x99, 0x88, 0x18, 0x6e, 0x66, 0xcb, 0x33, 0x4d, 0xbb, + 0x99, 0x93, 0x7f, 0x30, 0x6d, 0xe7, 0x89, 0x72, 0xf3, 0xcc, 0xc2, 0x68, + 0xe6, 0x0b, 0xad, 0x7a, 0xcb, 0x54, 0x1a, 0x5f, 0x82, 0x29, 0x46, 0x5f, + 0x2d, 0xa2, 0x15, 0xcd, 0x1c, 0xfe, 0xe0, 0x10, 0x8d, 0x03, 0xe3, 0xd9, + 0xc4, 0x02, 0x97, 0x32, 0xe8, 0x3b, 0xa6, 0xaf, 0x82, 0x6c, 0xcd, 0x77, + 0xd1, 0xee, 0x63, 0xe6, 0x56, 0xb3, 0x23, 0x9b, 0x95, 0x4b, 0x59, 0xb4, + 0xce, 0x29, 0x6d, 0xcb, 0xa1, 0xaa, 0x80, 0xe5, 0x97, 0x56, 0x3d, 0xcc, + 0xfe, 0x1e, 0x3b, 0x41, 0xa8, 0x25, 0xd3, 0xf4, 0x45, 0x98, 0x4f, 0x6c, + 0x41, 0xb6, 0x5d, 0x01, 0x5f, 0x98, 0xea, 0xa0, 0xd2, 0xb4, 0x99, 0x21, + 0xb1, 0xbb, 0xee, 0x3f, 0x44, 0x75, 0xb5, 0x1d, 0x44, 0x9a, 0xd7, 0x78, + 0x7e, 0xe2, 0x7c, 0x3f, 0x61, 0x04, 0xb4, 0x1e, 0xd3, 0x14, 0xb9, 0x46, + 0x56, 0x4e, 0xab, 0xdc, 0x84, 0x2a, 0x2a, 0xd3, 0xf6, 0x5f, 0xe7, 0xd0, + 0x47, 0x56, 0x75, 0xa6, 0x59, 0x9c, 0x97, 0x09, 0x9d, 0xb3, 0x08, 0x0c, + 0xc1, 0x77, 0xf6, 0x96, 0xd6, 0x65, 0x05, 0x5d, 0x4b, 0xf7, 0xcc, 0xee, + 0x25, 0x9d, 0x66, 0x61, 0x0b, 0x88, 0x28, 0xff, 0x00, 0xee, 0xe1, 0x97, + 0xd8, 0x8d, 0x9b, 0xb8, 0x19, 0xb6, 0x31, 0x6a, 0x3a, 0xf0, 0x0d, 0xf1, + 0x3a, 0xd2, 0xf5, 0x98, 0x48, 0xbb, 0x99, 0x93, 0x33, 0x98, 0x79, 0xcc, + 0xb6, 0x59, 0x72, 0xa8, 0xe5, 0x1e, 0xb2, 0x77, 0xc6, 0x9b, 0xc5, 0x73, + 0x1e, 0x42, 0x37, 0xad, 0x76, 0xd4, 0x2f, 0x05, 0x82, 0xaf, 0xa8, 0x0a, + 0x52, 0xa5, 0x17, 0x2c, 0xa1, 0xad, 0x45, 0x56, 0xbf, 0x13, 0x5b, 0xf6, + 0x6f, 0xa0, 0x94, 0x32, 0x13, 0x94, 0xbf, 0x72, 0x98, 0xdb, 0x95, 0x7e, + 0x4c, 0x2a, 0xaf, 0x7a, 0xa5, 0xf8, 0x95, 0xca, 0x87, 0x54, 0xa2, 0x86, + 0x64, 0x50, 0xac, 0xd0, 0x39, 0x1a, 0x3e, 0xd2, 0xd7, 0x0c, 0xa8, 0xe1, + 0x7b, 0x42, 0x8b, 0xc3, 0x84, 0xdf, 0xdc, 0x4c, 0x1e, 0x61, 0xf7, 0x29, + 0x2b, 0x3c, 0x22, 0x54, 0x04, 0x72, 0x9f, 0x86, 0x39, 0x47, 0x39, 0x17, + 0xf2, 0x4c, 0x87, 0x15, 0x35, 0xa1, 0xf7, 0x86, 0x1c, 0xaa, 0x2f, 0xa3, + 0xae, 0x59, 0xaa, 0x84, 0x46, 0x17, 0xe2, 0x2a, 0x82, 0xf7, 0x16, 0x2a, + 0x79, 0x4b, 0x6b, 0xf1, 0xf7, 0x19, 0x50, 0x45, 0xb7, 0xc8, 0xf6, 0xd2, + 0x50, 0x85, 0x2a, 0xa8, 0xf9, 0x58, 0x59, 0xae, 0x25, 0x95, 0x7a, 0x90, + 0xd8, 0x87, 0x79, 0x74, 0x02, 0xf7, 0x21, 0x11, 0x49, 0xa4, 0x07, 0x15, + 0x28, 0x1c, 0x4a, 0x4d, 0x33, 0x1c, 0x5c, 0x40, 0xa1, 0xd2, 0xf3, 0x0b, + 0x48, 0x2d, 0x59, 0x00, 0x9a, 0x9d, 0xd1, 0x70, 0x65, 0xb5, 0x90, 0x22, + 0xa1, 0x59, 0x5a, 0x46, 0x70, 0x16, 0xfc, 0x13, 0x23, 0x7b, 0xd5, 0xed, + 0x3a, 0x07, 0x27, 0x56, 0x0a, 0x2d, 0xa6, 0x87, 0x59, 0x5d, 0x2e, 0x2b, + 0x55, 0xc4, 0xbe, 0xcd, 0x5e, 0xf1, 0x0e, 0xba, 0x75, 0x8a, 0x20, 0x3a, + 0xab, 0x56, 0x0a, 0x1a, 0x0e, 0xb5, 0xbc, 0xca, 0x14, 0x34, 0x1a, 0xb1, + 0x3c, 0x0a, 0x47, 0x74, 0xd1, 0xf3, 0x1c, 0xea, 0x9b, 0x5a, 0xbf, 0x4f, + 0x98, 0x65, 0x84, 0x32, 0x0b, 0x3d, 0xd2, 0x28, 0x31, 0xff, 0x00, 0xbd, + 0x5c, 0xad, 0x81, 0xc5, 0xfb, 0xe5, 0x02, 0x07, 0x64, 0xe2, 0x43, 0xc1, + 0x98, 0x7c, 0xc6, 0xed, 0xb3, 0xce, 0xb3, 0x00, 0x1e, 0xb6, 0x37, 0x02, + 0xc1, 0x36, 0x66, 0x56, 0xc8, 0x75, 0xb1, 0xa8, 0xbe, 0x6b, 0xbb, 0x0d, + 0x40, 0x61, 0xa5, 0x46, 0xd0, 0x6d, 0x71, 0xed, 0x08, 0x0e, 0xea, 0xd2, + 0xe0, 0x53, 0x06, 0x95, 0xcc, 0xb2, 0x00, 0x0c, 0x39, 0x80, 0xa2, 0xcf, + 0x5b, 0x69, 0x1c, 0x0a, 0x76, 0x05, 0x4a, 0x40, 0x5b, 0x41, 0xe7, 0x88, + 0xd5, 0x25, 0x68, 0x2a, 0xf6, 0x95, 0x50, 0xc0, 0x53, 0x3d, 0x44, 0x1a, + 0xbc, 0xcd, 0xb8, 0x91, 0xcb, 0x34, 0x9b, 0x3f, 0x11, 0xe6, 0xcd, 0xa5, + 0xe9, 0x59, 0x78, 0x7e, 0x2d, 0x1c, 0x08, 0x42, 0xc1, 0x39, 0x1f, 0x46, + 0x99, 0xd7, 0x99, 0x89, 0x98, 0xcc, 0xc0, 0x8c, 0x0c, 0xf8, 0x94, 0x9a, + 0xca, 0x10, 0x86, 0xcc, 0xbd, 0x88, 0x6d, 0x35, 0xe0, 0x7d, 0xcc, 0x32, + 0x53, 0xad, 0x60, 0xa8, 0x3b, 0xaa, 0x3f, 0x06, 0xa5, 0x39, 0x5a, 0xb4, + 0xe9, 0xf0, 0xfe, 0x21, 0x15, 0x63, 0xb4, 0xc0, 0x6e, 0xa1, 0xf5, 0x61, + 0x8c, 0x7f, 0xf7, 0x38, 0x63, 0x2c, 0xc3, 0x48, 0x31, 0x4b, 0x98, 0x0b, + 0xa4, 0x43, 0x5d, 0x46, 0xb1, 0x01, 0xde, 0x1f, 0x30, 0x16, 0x22, 0xa4, + 0x5b, 0x99, 0x75, 0x9a, 0xb9, 0xf4, 0xd1, 0xde, 0x55, 0xb9, 0x7c, 0x46, + 0x8c, 0x0a, 0x9b, 0xca, 0xa8, 0xbd, 0x07, 0x1a, 0xfd, 0x2e, 0x5f, 0x21, + 0xbf, 0xe9, 0x96, 0x32, 0x10, 0xe0, 0xcb, 0xe0, 0x61, 0x84, 0x70, 0x9d, + 0xc8, 0xf6, 0x7d, 0x42, 0x57, 0xf5, 0x8e, 0xc0, 0xdd, 0xa3, 0xae, 0xb1, + 0xc5, 0x88, 0x0a, 0x29, 0x7a, 0xea, 0xc3, 0x0c, 0x0b, 0x05, 0x4a, 0xa2, + 0x66, 0x5d, 0x35, 0x61, 0xa5, 0xee, 0x44, 0xb0, 0x4b, 0xde, 0x6a, 0x30, + 0xcd, 0x4c, 0xc1, 0x4a, 0x38, 0x81, 0xdc, 0xcd, 0xd8, 0x4e, 0xfe, 0x49, + 0xbf, 0xcf, 0x42, 0x23, 0x0f, 0xa9, 0xcc, 0xf1, 0x68, 0xba, 0x3d, 0xa1, + 0x46, 0xf0, 0xc6, 0x3e, 0x58, 0x0f, 0xa4, 0x6a, 0x95, 0xec, 0xc1, 0xa1, + 0x86, 0x2b, 0xf2, 0x57, 0x2f, 0x1d, 0x53, 0x5b, 0xed, 0x64, 0x2c, 0x2d, + 0x1d, 0x33, 0xf3, 0x3e, 0x42, 0x74, 0x2b, 0xbc, 0x9e, 0x4d, 0x3c, 0xc0, + 0x53, 0x50, 0xd3, 0x74, 0x24, 0x28, 0x2c, 0x99, 0x86, 0xbc, 0x4e, 0x84, + 0xdd, 0xe2, 0x20, 0x1d, 0x39, 0x36, 0x86, 0x6a, 0x2b, 0x08, 0x1f, 0x76, + 0x01, 0x65, 0xa6, 0xe3, 0xb9, 0x2a, 0x2a, 0xeb, 0xc6, 0x1f, 0x77, 0x14, + 0x56, 0xa8, 0x7e, 0xaa, 0x3e, 0xe5, 0x53, 0x18, 0x6b, 0xea, 0x5b, 0x6b, + 0x73, 0x93, 0xde, 0x31, 0x22, 0x65, 0x27, 0x2a, 0xa7, 0x5e, 0xad, 0xf8, + 0x85, 0xad, 0x12, 0xa8, 0xb1, 0x12, 0xb1, 0x91, 0x13, 0xc4, 0xb0, 0x16, + 0x39, 0x08, 0xb5, 0x51, 0xa2, 0x2f, 0x20, 0x4a, 0xac, 0xea, 0x7b, 0x4b, + 0x3a, 0xe8, 0x75, 0x00, 0x1b, 0x06, 0xb4, 0xf6, 0x82, 0x51, 0x11, 0x1a, + 0xbd, 0x36, 0x0f, 0xbe, 0x25, 0xe0, 0xe8, 0x59, 0x37, 0xda, 0x11, 0x45, + 0xd0, 0x59, 0xf0, 0x87, 0xbb, 0x11, 0x8b, 0x70, 0xd1, 0x20, 0x5c, 0xe9, + 0xdd, 0x0f, 0x3e, 0xf1, 0x14, 0x6a, 0x59, 0x83, 0xf0, 0xfe, 0x23, 0x40, + 0x6e, 0x3f, 0x50, 0xb9, 0x50, 0x99, 0xe6, 0x7b, 0xc3, 0x36, 0xed, 0xb6, + 0xf2, 0x92, 0x11, 0x62, 0x55, 0x40, 0x5a, 0x9c, 0x07, 0x31, 0x55, 0xb9, + 0x28, 0xd0, 0xfc, 0xbc, 0x31, 0xd6, 0x3f, 0x9b, 0xa3, 0x8c, 0xe3, 0x19, + 0x7c, 0xac, 0x44, 0x85, 0x6a, 0x5a, 0xcc, 0xfa, 0xe6, 0x59, 0x31, 0x24, + 0x19, 0x13, 0x68, 0x98, 0x29, 0xe2, 0xcd, 0x13, 0xbe, 0xfe, 0x66, 0x3c, + 0xc6, 0x46, 0x13, 0x86, 0x01, 0x56, 0xc9, 0xf2, 0xca, 0x0c, 0xe9, 0x10, + 0xa4, 0x73, 0x52, 0xa0, 0x05, 0xd8, 0x75, 0x34, 0x82, 0x83, 0x75, 0x6d, + 0xcb, 0x40, 0x69, 0x57, 0x11, 0x6a, 0xd9, 0x09, 0x71, 0x62, 0x90, 0xce, + 0x17, 0x8f, 0x58, 0x45, 0x8b, 0x06, 0x95, 0x0d, 0x04, 0xb2, 0x00, 0xac, + 0x04, 0x8d, 0x39, 0x5a, 0x93, 0x6a, 0xaf, 0x31, 0x3e, 0x5b, 0x19, 0x2f, + 0x65, 0xc3, 0x3e, 0xd1, 0x28, 0x52, 0xd0, 0x4a, 0xca, 0xd7, 0x8a, 0xf9, + 0x94, 0x39, 0x90, 0xb4, 0xfb, 0x4a, 0xc6, 0x29, 0x34, 0x41, 0x8b, 0xb6, + 0xef, 0xc4, 0xb0, 0x42, 0x0e, 0x75, 0xd8, 0x54, 0x0b, 0x6b, 0xc9, 0x0f, + 0xb0, 0x81, 0xd6, 0x9a, 0x74, 0xeb, 0xfd, 0x51, 0x50, 0xc7, 0xa0, 0xfb, + 0x6b, 0x1b, 0x1b, 0xc7, 0x61, 0xb4, 0xef, 0x11, 0x36, 0x18, 0x03, 0x77, + 0x89, 0x6a, 0x65, 0x6e, 0xd7, 0xcc, 0xcb, 0x57, 0x31, 0x1c, 0xfa, 0x06, + 0xb1, 0x42, 0xba, 0xc4, 0x69, 0x26, 0x6b, 0x83, 0xab, 0xe6, 0x29, 0x33, + 0x12, 0xf2, 0x21, 0xc5, 0xff, 0x00, 0xe5, 0x4b, 0x57, 0x68, 0xc0, 0x6a, + 0x52, 0x0f, 0xa5, 0xca, 0x8c, 0xe6, 0x94, 0xdb, 0xde, 0x75, 0x71, 0xc4, + 0x9f, 0x11, 0xc2, 0xa8, 0x96, 0xe0, 0x08, 0xd9, 0xfc, 0xc5, 0x56, 0x6b, + 0xca, 0x2e, 0xe7, 0x5e, 0x6b, 0xa7, 0x10, 0x37, 0xf9, 0x89, 0x09, 0x92, + 0x50, 0xeb, 0x17, 0x00, 0x78, 0x4c, 0x4e, 0x95, 0xe8, 0xb2, 0xfd, 0xe2, + 0xa1, 0xad, 0xd5, 0x11, 0x14, 0x5d, 0xcb, 0xb8, 0xd0, 0x7b, 0xc7, 0x85, + 0x2d, 0x38, 0x2f, 0x7a, 0xbc, 0xb3, 0x48, 0x16, 0x6d, 0x6b, 0xdb, 0x07, + 0xb4, 0x5a, 0xe4, 0x9e, 0xed, 0xba, 0x8c, 0x14, 0x6b, 0x04, 0x14, 0xf1, + 0x82, 0x21, 0xd2, 0x86, 0xa7, 0x2c, 0x76, 0x1a, 0x31, 0x01, 0xb2, 0xff, + 0x00, 0xca, 0x22, 0x15, 0x34, 0x0a, 0xb3, 0x3d, 0xe1, 0xfe, 0x92, 0x49, + 0x80, 0x03, 0x3e, 0x61, 0x18, 0x60, 0xc6, 0xb2, 0x9f, 0x2f, 0x59, 0x6e, + 0x85, 0x11, 0x71, 0x2d, 0x75, 0x99, 0xfb, 0x38, 0x41, 0x40, 0x85, 0xab, + 0x88, 0x37, 0x56, 0x81, 0xc1, 0x0a, 0xad, 0x21, 0xa0, 0xa1, 0xf7, 0x9b, + 0x76, 0x53, 0x5d, 0xc3, 0x73, 0x66, 0x35, 0x10, 0x96, 0x8d, 0x5b, 0xa5, + 0xb5, 0x5e, 0x87, 0xb9, 0x16, 0x98, 0xb8, 0x5a, 0x8e, 0x31, 0x97, 0xca, + 0xcc, 0xe0, 0x81, 0x55, 0x5f, 0x33, 0x3e, 0xb0, 0x1a, 0x91, 0xe4, 0x81, + 0xf6, 0x6b, 0x5b, 0x5d, 0x17, 0x3e, 0x1e, 0xd3, 0x46, 0xd4, 0x5e, 0x6f, + 0xc8, 0xec, 0xc0, 0xfa, 0x00, 0x58, 0x79, 0x21, 0x90, 0x16, 0xdf, 0x40, + 0x1f, 0x37, 0x09, 0x30, 0x62, 0x89, 0x3f, 0x0f, 0x7a, 0x8e, 0x55, 0x0a, + 0x12, 0x1f, 0x3a, 0x7c, 0xc6, 0xb4, 0x4a, 0xc1, 0x2c, 0x7f, 0x39, 0x82, + 0xb1, 0xff, 0x00, 0x79, 0x8f, 0xb6, 0x09, 0x9d, 0xa2, 0x9a, 0xd8, 0x26, + 0x42, 0xed, 0x70, 0xda, 0x91, 0xb7, 0x3b, 0xc5, 0x8c, 0x15, 0x6f, 0xd1, + 0x0f, 0x61, 0x51, 0x2d, 0xe7, 0xa6, 0x0f, 0x29, 0x65, 0x6d, 0x8e, 0x24, + 0x69, 0x11, 0x28, 0xba, 0x5f, 0x7e, 0x11, 0x92, 0x68, 0xca, 0x11, 0x8b, + 0x43, 0x69, 0xa6, 0x30, 0x5b, 0x82, 0xe0, 0x00, 0x1d, 0x75, 0x06, 0xda, + 0xd1, 0xc1, 0x62, 0xa9, 0x05, 0x8c, 0xc0, 0x3a, 0x80, 0x7b, 0x41, 0xe8, + 0x26, 0x41, 0x15, 0x95, 0xba, 0xff, 0x00, 0x65, 0x2d, 0x85, 0x29, 0xf4, + 0xf3, 0x7c, 0xb2, 0xc8, 0x8b, 0x29, 0xc0, 0x8d, 0x33, 0xad, 0x62, 0x09, + 0x2b, 0x28, 0x73, 0x7d, 0x69, 0x7d, 0xc4, 0x57, 0x8e, 0x2c, 0x61, 0x57, + 0x90, 0xd9, 0x65, 0xab, 0x5d, 0x90, 0x06, 0x85, 0xfb, 0x7c, 0xcc, 0x9d, + 0x03, 0x98, 0x79, 0x07, 0xaf, 0xc4, 0xd2, 0x81, 0x68, 0x43, 0x88, 0x36, + 0x7a, 0x34, 0x0d, 0x3d, 0xcc, 0xcb, 0x68, 0xf8, 0xc4, 0x7b, 0x36, 0x4b, + 0x7a, 0x4e, 0xf6, 0x1b, 0xea, 0x57, 0x5a, 0xa8, 0x7e, 0xc8, 0x9f, 0xbf, + 0x30, 0xc6, 0x98, 0x40, 0x94, 0x3e, 0x6f, 0x96, 0x6c, 0x4b, 0xe7, 0xa2, + 0xe5, 0x7c, 0x1e, 0x61, 0x47, 0xb9, 0x54, 0x95, 0xa2, 0xe5, 0x79, 0x62, + 0xdb, 0x2f, 0x94, 0x0c, 0xb6, 0x66, 0xd6, 0x61, 0xd6, 0x3b, 0xae, 0x18, + 0xea, 0x27, 0x35, 0x0a, 0x4d, 0x04, 0xcd, 0x37, 0x37, 0xc7, 0x26, 0x85, + 0x77, 0x95, 0x30, 0x3e, 0x58, 0x4b, 0x05, 0xba, 0x29, 0x1e, 0x85, 0x0d, + 0xed, 0x11, 0xd3, 0x05, 0xaa, 0xf6, 0x65, 0xcc, 0x69, 0x03, 0x1b, 0x27, + 0x32, 0x97, 0x54, 0xd5, 0x77, 0x96, 0x8d, 0x0e, 0x21, 0x50, 0xf3, 0x97, + 0x69, 0x90, 0xa1, 0xf4, 0xc3, 0xad, 0x50, 0x07, 0x04, 0xdd, 0xf7, 0x2c, + 0x45, 0xb1, 0xc7, 0xbc, 0x5e, 0xd0, 0x0e, 0x2a, 0xc3, 0xd5, 0x2e, 0x30, + 0x42, 0xca, 0x0a, 0x57, 0xb0, 0x12, 0xf9, 0x6a, 0x1a, 0xd1, 0x0e, 0xee, + 0xdd, 0x0b, 0xc5, 0xfb, 0x6b, 0x19, 0x09, 0xde, 0xd4, 0xf1, 0x16, 0xe4, + 0x45, 0x8f, 0x86, 0x52, 0x61, 0x0a, 0xe0, 0xf6, 0x55, 0xbc, 0xcb, 0xd2, + 0xb9, 0x6d, 0x4f, 0x9e, 0x8e, 0xc2, 0x2e, 0x2d, 0xf8, 0x4c, 0xad, 0x06, + 0x43, 0xb6, 0x0c, 0x32, 0x56, 0x03, 0xa3, 0xc9, 0x61, 0x17, 0x7f, 0x01, + 0x82, 0x02, 0x9f, 0x1e, 0xcf, 0xa2, 0xc2, 0x34, 0x96, 0x4d, 0x65, 0xca, + 0x61, 0x4e, 0x73, 0x69, 0x2a, 0xa1, 0x2c, 0x04, 0xa0, 0xed, 0xff, 0x00, + 0xc4, 0x27, 0x2c, 0x42, 0xa2, 0xb4, 0x60, 0x16, 0x62, 0xfa, 0xfa, 0x85, + 0x43, 0xa0, 0x76, 0x3f, 0xb7, 0x5f, 0xcc, 0x6b, 0xa0, 0x86, 0xe5, 0x06, + 0xfd, 0x63, 0x7c, 0xa1, 0x7b, 0x17, 0xf3, 0x65, 0x51, 0x62, 0x88, 0xde, + 0xb0, 0xee, 0x93, 0xe2, 0x3e, 0xc0, 0xa1, 0xcb, 0xf9, 0x6a, 0xe7, 0xf3, + 0x4a, 0x61, 0xbf, 0x94, 0x56, 0x57, 0x92, 0x4f, 0x89, 0x6a, 0x61, 0x8e, + 0x5a, 0x98, 0xfc, 0xcc, 0xc9, 0x4c, 0x5b, 0x08, 0xdc, 0xe8, 0xda, 0x67, + 0x7a, 0x4f, 0xb6, 0xa7, 0x35, 0xda, 0x54, 0x06, 0x85, 0xb1, 0xca, 0x00, + 0x77, 0x51, 0x45, 0xb6, 0xaf, 0x8c, 0xa0, 0x78, 0x23, 0x5c, 0x55, 0x2a, + 0xa9, 0x65, 0x2a, 0xd4, 0x55, 0x85, 0x7e, 0xe1, 0xba, 0xdc, 0x8e, 0xa4, + 0xc8, 0xa1, 0x5d, 0xb2, 0x8c, 0xb0, 0x16, 0xd3, 0xb3, 0x29, 0x59, 0x5a, + 0xaa, 0x1b, 0x29, 0x8f, 0x90, 0x0b, 0x01, 0x0e, 0x9f, 0x70, 0x0a, 0xb1, + 0x42, 0xb0, 0xf3, 0xcf, 0x91, 0x1a, 0xf4, 0xd2, 0xb1, 0xa1, 0x17, 0xea, + 0x40, 0x31, 0xeb, 0xa2, 0x64, 0x2e, 0x4a, 0x18, 0x5d, 0xc3, 0xa4, 0xcc, + 0xab, 0x54, 0x28, 0xc6, 0x61, 0x40, 0xc4, 0xba, 0x8f, 0xd7, 0x02, 0xaa, + 0xd4, 0x03, 0x19, 0x65, 0x1a, 0xd0, 0xe9, 0x16, 0xfe, 0xfe, 0x93, 0x5f, + 0x89, 0xa6, 0x2d, 0x1e, 0xb4, 0xd3, 0x88, 0x80, 0x46, 0x0d, 0x12, 0xcf, + 0xcd, 0x40, 0x2c, 0xf0, 0x5c, 0x28, 0x2f, 0xb2, 0x3d, 0x05, 0x0d, 0x29, + 0xf4, 0x8f, 0x51, 0xd3, 0x6e, 0x8b, 0xb0, 0x11, 0xec, 0xcc, 0x1a, 0xc8, + 0x46, 0xcc, 0xb5, 0x81, 0x2e, 0xb0, 0x3b, 0xa3, 0xbe, 0x21, 0xa1, 0xc8, + 0xe8, 0x1d, 0x86, 0x25, 0x7d, 0x85, 0x82, 0x70, 0xde, 0xbc, 0x3b, 0x47, + 0x55, 0xa0, 0x4a, 0x8a, 0x30, 0xb7, 0x5b, 0x35, 0xa7, 0xc9, 0x19, 0x10, + 0x75, 0xbf, 0xb2, 0x0f, 0x08, 0xa3, 0x22, 0x81, 0xaa, 0x66, 0xaf, 0x6e, + 0xe9, 0x1b, 0x08, 0xde, 0xad, 0x6b, 0x6d, 0x44, 0xaf, 0x86, 0x40, 0xd4, + 0x8d, 0x2f, 0x3a, 0xff, 0x00, 0x64, 0x8c, 0x10, 0xd8, 0x36, 0x60, 0x47, + 0xc8, 0x54, 0x00, 0x00, 0x00, 0x38, 0x25, 0xec, 0xd9, 0x8a, 0x25, 0xcd, + 0x56, 0x82, 0xfd, 0x92, 0xf1, 0x6f, 0xe3, 0x65, 0xbf, 0x88, 0x58, 0x57, + 0x50, 0xca, 0xbc, 0xb8, 0x5b, 0xe2, 0x52, 0x68, 0x14, 0x80, 0xe3, 0x9c, + 0x71, 0xf5, 0x70, 0xbe, 0x2f, 0x21, 0x7a, 0x7f, 0x60, 0xf3, 0x2b, 0x89, + 0x54, 0x5a, 0xdd, 0x0c, 0x04, 0x1a, 0x60, 0xd1, 0x96, 0x21, 0xbf, 0x49, + 0x65, 0x50, 0x59, 0x75, 0x6a, 0x72, 0xf6, 0x20, 0x44, 0x00, 0x6a, 0xf4, + 0xca, 0xfe, 0x3a, 0x77, 0x97, 0xf1, 0xf3, 0x0a, 0xe3, 0x8c, 0xb4, 0xe8, + 0xba, 0x67, 0x88, 0xf1, 0x1c, 0xb6, 0x47, 0x03, 0x00, 0x1c, 0xa9, 0xcb, + 0x18, 0x33, 0x00, 0x5a, 0x6a, 0xf0, 0xe0, 0x76, 0xc9, 0x03, 0x63, 0xa4, + 0xc5, 0xa8, 0xc5, 0xae, 0x70, 0x63, 0x2c, 0x4a, 0xe3, 0x48, 0x1c, 0x74, + 0x61, 0x34, 0x6c, 0x07, 0xb4, 0x65, 0x66, 0xbc, 0x66, 0x39, 0x81, 0x05, + 0x25, 0x7a, 0x30, 0xdd, 0x7a, 0xb1, 0x8e, 0xe8, 0xb9, 0x42, 0xe5, 0xcc, + 0xbb, 0xa1, 0xea, 0xcc, 0x9a, 0x68, 0x73, 0x01, 0x20, 0x90, 0x51, 0x50, + 0x8f, 0xc1, 0xdc, 0x33, 0x0c, 0x02, 0xce, 0xf0, 0x22, 0x8c, 0x24, 0x60, + 0xea, 0x45, 0xb0, 0xc9, 0x75, 0x88, 0x82, 0xc5, 0xb4, 0x11, 0xda, 0x64, + 0x69, 0x70, 0x0e, 0x36, 0xae, 0x14, 0xc4, 0xab, 0xb9, 0x53, 0x48, 0xa5, + 0xeb, 0xa4, 0x2b, 0x65, 0xe7, 0x00, 0x58, 0x48, 0x41, 0x97, 0x23, 0xac, + 0x33, 0x9d, 0x3a, 0x14, 0x6f, 0x0e, 0xa9, 0x70, 0x5b, 0x67, 0x0c, 0x47, + 0x25, 0x68, 0x18, 0x0e, 0xb1, 0x34, 0x99, 0x34, 0x20, 0x10, 0x2b, 0x25, + 0xac, 0x3b, 0xf5, 0x95, 0xe6, 0xde, 0xa9, 0xdf, 0x2f, 0xc8, 0x31, 0xd1, + 0xb2, 0xd8, 0x96, 0x08, 0xab, 0x2a, 0x8d, 0x03, 0x87, 0x99, 0x89, 0x1a, + 0x57, 0xa6, 0xf1, 0x99, 0x66, 0x7a, 0xe9, 0x97, 0xa6, 0x99, 0x20, 0x4a, + 0xc9, 0x56, 0x41, 0xf7, 0x83, 0x89, 0xa8, 0xbb, 0x7a, 0x7f, 0x93, 0x31, + 0xa2, 0x2d, 0x44, 0x88, 0xf5, 0xab, 0xf0, 0x80, 0x1a, 0x6b, 0x00, 0xa3, + 0xe6, 0xcf, 0x62, 0x19, 0xc4, 0x39, 0x52, 0xf7, 0xaa, 0xff, 0x00, 0xda, + 0xe0, 0x40, 0xa8, 0xe5, 0x0d, 0x68, 0x8a, 0x0f, 0x75, 0x52, 0x2b, 0xd4, + 0xa7, 0xe6, 0x15, 0xa5, 0xcc, 0xbe, 0x6f, 0x98, 0xfd, 0xa5, 0x6f, 0x1b, + 0xe0, 0xfc, 0x02, 0x55, 0xcc, 0xea, 0xd2, 0x5d, 0x09, 0x16, 0x3d, 0xb5, + 0xc6, 0x8f, 0x4b, 0x94, 0x86, 0xcf, 0x8e, 0xf9, 0xf2, 0xc3, 0x2f, 0xc3, + 0x8f, 0x28, 0x25, 0xa0, 0x8d, 0x7d, 0x8f, 0x6f, 0xe2, 0x0a, 0xbc, 0x50, + 0xaa, 0x72, 0x0a, 0x29, 0x81, 0x57, 0xb6, 0x73, 0xa8, 0xb0, 0x45, 0x8a, + 0x52, 0xb1, 0xc7, 0xd8, 0x83, 0xdc, 0x4a, 0x26, 0xda, 0x88, 0x7b, 0xaa, + 0x3c, 0x91, 0xb1, 0x2b, 0x54, 0xc0, 0xfa, 0x96, 0x9e, 0xc5, 0x48, 0x02, + 0xc3, 0x7e, 0xfe, 0x87, 0x9f, 0xe8, 0x32, 0xbf, 0x99, 0xa7, 0xa0, 0xe5, + 0x1b, 0x6f, 0x05, 0xd4, 0x1d, 0x4e, 0x58, 0xba, 0x76, 0x38, 0x7d, 0x45, + 0x42, 0x47, 0xa2, 0xc4, 0x1d, 0xa8, 0xdd, 0xe8, 0xc7, 0xa3, 0x64, 0x00, + 0xbc, 0x29, 0xee, 0x4d, 0xd1, 0x12, 0xb8, 0x2d, 0x7e, 0xd0, 0x10, 0xd8, + 0xf8, 0x23, 0xd6, 0xfa, 0x6d, 0x08, 0xaf, 0x9b, 0xe2, 0x62, 0x56, 0x85, + 0x4e, 0x10, 0xf6, 0x2b, 0xe2, 0x01, 0x15, 0xcc, 0xec, 0x21, 0xad, 0x05, + 0x79, 0x60, 0xd6, 0x8b, 0x86, 0x95, 0x39, 0xcd, 0x43, 0x9c, 0xc2, 0x13, + 0x7b, 0x73, 0x9d, 0xd4, 0x58, 0x8b, 0x13, 0x2c, 0xcd, 0x34, 0x60, 0x3c, + 0x5c, 0x22, 0x2a, 0x68, 0xa9, 0x74, 0x73, 0x9d, 0xe6, 0x54, 0x82, 0x42, + 0x38, 0x81, 0x50, 0xc6, 0xbb, 0xbb, 0xc4, 0x39, 0x13, 0x1c, 0x77, 0x80, + 0xf5, 0x43, 0xd6, 0x22, 0xac, 0x06, 0xd7, 0x8e, 0x50, 0x5e, 0xc0, 0x13, + 0xba, 0x58, 0x6f, 0xfb, 0xe8, 0x03, 0xef, 0xc2, 0x77, 0x18, 0x60, 0x74, + 0xa5, 0x5b, 0xff, 0x00, 0x8e, 0xfa, 0x7d, 0x39, 0x5a, 0xd8, 0x6f, 0xa0, + 0x0a, 0x1e, 0xfd, 0xe0, 0xe4, 0x18, 0x50, 0x02, 0xdb, 0x50, 0x81, 0xdc, + 0x20, 0xb5, 0xf2, 0xc8, 0x20, 0x6b, 0x77, 0x66, 0x24, 0x4c, 0x96, 0x1b, + 0xb2, 0x1d, 0x47, 0x50, 0x7b, 0x10, 0xea, 0x10, 0x2b, 0xd2, 0x74, 0xc0, + 0x19, 0x9e, 0x17, 0xcd, 0x63, 0x19, 0x1c, 0x36, 0x65, 0x44, 0xee, 0xa5, + 0xaa, 0x58, 0x2c, 0x61, 0x1c, 0xd5, 0xe5, 0xf8, 0xad, 0x67, 0xb4, 0xb0, + 0x08, 0xf5, 0xfd, 0x9c, 0xc2, 0x09, 0x05, 0x5d, 0x78, 0xd7, 0x1a, 0x1e, + 0x22, 0x2b, 0x21, 0x2f, 0x88, 0xfb, 0x27, 0x2a, 0x32, 0xe2, 0xbe, 0xb7, + 0x1e, 0xe6, 0x50, 0x74, 0xe3, 0x16, 0x66, 0x2e, 0xeb, 0xca, 0xdd, 0xb1, + 0x0e, 0xd1, 0xa6, 0x94, 0xe1, 0x36, 0xb5, 0x8e, 0x15, 0xcf, 0x4d, 0x08, + 0x1f, 0x3d, 0x36, 0x5b, 0xac, 0xa0, 0x57, 0x95, 0xff, 0x00, 0x28, 0x14, + 0x1b, 0xa0, 0xde, 0x9d, 0xe3, 0x92, 0x5a, 0xb6, 0xac, 0xa9, 0xa0, 0x04, + 0x4f, 0x88, 0x29, 0xe9, 0xfb, 0x13, 0x56, 0x64, 0x99, 0x59, 0x93, 0x30, + 0x4c, 0x13, 0x29, 0x7d, 0xe8, 0x3d, 0xe5, 0x92, 0xa5, 0x26, 0xb3, 0x5f, + 0x68, 0x3a, 0xcc, 0x59, 0xbe, 0x25, 0x78, 0xb5, 0x4e, 0x4d, 0x07, 0xf8, + 0x82, 0xe2, 0xa9, 0xc9, 0x01, 0x13, 0x6b, 0x84, 0x22, 0x3a, 0x47, 0x5f, + 0x92, 0x1a, 0xb0, 0x37, 0xd2, 0x60, 0x13, 0xa9, 0x14, 0x89, 0xc9, 0x6d, + 0x2c, 0x6f, 0xc5, 0x6c, 0x0a, 0x35, 0xa1, 0xe9, 0x12, 0x28, 0xe0, 0x73, + 0x83, 0x4f, 0xf1, 0x2b, 0x7b, 0xfe, 0x32, 0xe2, 0xe0, 0x62, 0x69, 0xac, + 0x24, 0x90, 0x30, 0x8c, 0xd0, 0x10, 0x40, 0x50, 0x80, 0xf3, 0xe7, 0xcc, + 0x29, 0xdb, 0xa1, 0x4d, 0xe2, 0x18, 0x11, 0xc7, 0x5d, 0x3d, 0x2a, 0x26, + 0x69, 0x56, 0xd4, 0xb9, 0x5d, 0x66, 0x35, 0x37, 0x70, 0x29, 0xdc, 0xe5, + 0x0e, 0x53, 0xf8, 0x72, 0x72, 0xa5, 0x79, 0x66, 0x12, 0x77, 0xda, 0x61, + 0xa7, 0xcd, 0xba, 0x44, 0xed, 0x34, 0xbd, 0xe0, 0x84, 0xce, 0x86, 0x58, + 0x9e, 0x18, 0xfc, 0xcc, 0x07, 0x6a, 0xd4, 0x63, 0xb5, 0x59, 0xa2, 0xa9, + 0x85, 0x0f, 0x76, 0xcf, 0xbc, 0xfc, 0x49, 0x5f, 0xcc, 0xd6, 0x2d, 0xe8, + 0xff, 0x00, 0x70, 0x53, 0xf2, 0x3f, 0x71, 0x59, 0x1e, 0xc3, 0xf3, 0x72, + 0xaf, 0x81, 0x82, 0xba, 0x6c, 0xc8, 0x5e, 0xa1, 0x1a, 0x2d, 0x42, 0xcd, + 0x10, 0xf3, 0x09, 0xbc, 0x4c, 0x8b, 0x3b, 0x43, 0x16, 0x01, 0x68, 0x47, + 0x2f, 0x12, 0xab, 0xc4, 0xc0, 0x50, 0x71, 0x71, 0x87, 0x3b, 0x68, 0x08, + 0x94, 0xef, 0xc4, 0x0c, 0xfc, 0x84, 0xfc, 0xc3, 0x78, 0x6d, 0x00, 0x0e, + 0xce, 0x18, 0xa4, 0x9f, 0xae, 0x03, 0xed, 0xb9, 0x6f, 0xb7, 0x48, 0xba, + 0x18, 0x50, 0x0a, 0x01, 0x67, 0x99, 0x72, 0x5c, 0xce, 0x89, 0x18, 0x74, + 0xb9, 0xfa, 0xa6, 0x49, 0x69, 0x78, 0xe1, 0xd9, 0xb4, 0x05, 0x7d, 0xee, + 0x55, 0x17, 0x54, 0xa1, 0x5d, 0xab, 0x63, 0x48, 0x8d, 0x74, 0x67, 0xfb, + 0x63, 0x38, 0x1c, 0xae, 0x3e, 0x6a, 0x35, 0x81, 0x84, 0x43, 0x46, 0x75, + 0x96, 0x51, 0x5b, 0x0d, 0xf0, 0x34, 0x71, 0xd7, 0x99, 0x8d, 0x6e, 0xea, + 0x1c, 0xbd, 0xd9, 0xa0, 0xe5, 0xe6, 0x0c, 0xc5, 0x5d, 0x60, 0x15, 0x97, + 0x26, 0x71, 0x97, 0x18, 0x41, 0x6b, 0xd2, 0x33, 0xce, 0xf2, 0x9d, 0x00, + 0x25, 0xda, 0xb0, 0xb9, 0x94, 0x3d, 0x1b, 0xf9, 0xc0, 0x99, 0x61, 0xb9, + 0x55, 0xf7, 0x9a, 0x49, 0x40, 0xcc, 0xbe, 0x96, 0x84, 0x17, 0xc6, 0x52, + 0x5c, 0x84, 0x7b, 0x12, 0xa0, 0x86, 0x1d, 0xe4, 0x7e, 0xe4, 0x66, 0x1a, + 0x65, 0x24, 0xf7, 0x98, 0x34, 0xb6, 0x08, 0x19, 0xba, 0x08, 0xd8, 0x0e, + 0x6b, 0x4b, 0xf8, 0x80, 0x5c, 0xf1, 0xed, 0xbc, 0x95, 0x65, 0xe4, 0x15, + 0xb4, 0x59, 0x95, 0xba, 0x00, 0x75, 0x0c, 0x9a, 0x60, 0x3c, 0x0b, 0x00, + 0x3a, 0x86, 0xc1, 0x54, 0x1b, 0x9d, 0x26, 0x22, 0x2d, 0x51, 0x68, 0xf6, + 0xe9, 0x50, 0x57, 0xa9, 0x66, 0x77, 0x75, 0xbd, 0xdb, 0xbe, 0xec, 0xa3, + 0xe0, 0x0a, 0xb0, 0xc7, 0x4e, 0x60, 0xd1, 0xa9, 0x4a, 0xb1, 0x64, 0xf1, + 0x78, 0x8e, 0xe4, 0x56, 0x91, 0xc2, 0x9a, 0x3d, 0xe0, 0x0b, 0xa0, 0x36, + 0xbb, 0xac, 0x8c, 0xa0, 0x55, 0x88, 0xa3, 0x78, 0x8c, 0x54, 0x29, 0x5d, + 0x62, 0xcd, 0x41, 0x69, 0x1b, 0xae, 0x66, 0xac, 0x85, 0x97, 0xaa, 0x66, + 0x42, 0x81, 0xc2, 0xd3, 0xf5, 0x2d, 0xa1, 0xe1, 0xa2, 0x93, 0xb9, 0x18, + 0xe9, 0x8a, 0xb8, 0x1c, 0x5a, 0xa3, 0x2d, 0xac, 0x9c, 0x57, 0xb1, 0x09, + 0x35, 0xc2, 0x07, 0x63, 0x43, 0x19, 0x97, 0xa0, 0x51, 0xb1, 0x2e, 0x9e, + 0x88, 0xb5, 0xa3, 0xb3, 0x1a, 0x9d, 0xf8, 0xa8, 0x5d, 0x61, 0x23, 0x15, + 0xc4, 0x2a, 0x6b, 0x8d, 0x6e, 0x5c, 0x47, 0xf0, 0xa5, 0x4b, 0x33, 0xbe, + 0x81, 0x94, 0x56, 0x4f, 0x04, 0x78, 0x97, 0x46, 0xcb, 0xf2, 0x40, 0xd9, + 0x28, 0xe9, 0xe2, 0x2c, 0x61, 0x5d, 0xe5, 0xe3, 0x59, 0xdf, 0xdc, 0x65, + 0xa7, 0xa2, 0x3b, 0xb8, 0x71, 0x2d, 0x31, 0x8b, 0xa4, 0xdd, 0x90, 0x71, + 0x15, 0x1a, 0x6a, 0x8f, 0xb1, 0xbb, 0xb2, 0xe0, 0xa6, 0xea, 0x2d, 0x14, + 0x02, 0x30, 0x14, 0x86, 0xb1, 0x12, 0x25, 0x2a, 0x47, 0x78, 0x7b, 0x3b, + 0x05, 0x14, 0x75, 0xda, 0x58, 0xba, 0xae, 0xd3, 0xa9, 0xea, 0x16, 0x32, + 0x84, 0x98, 0xaf, 0x57, 0xa0, 0x1c, 0x65, 0x9e, 0xb5, 0x53, 0x30, 0xf7, + 0x78, 0x02, 0xcd, 0xec, 0x60, 0x8b, 0xbc, 0x0f, 0x6a, 0x89, 0xa9, 0x56, + 0xa8, 0x23, 0x8b, 0x03, 0xe2, 0x04, 0x7d, 0xca, 0xaa, 0xc4, 0xc6, 0x25, + 0xa1, 0x88, 0x74, 0x2a, 0x18, 0x25, 0x44, 0xb9, 0x82, 0x90, 0xa3, 0x35, + 0x16, 0x40, 0x6e, 0xd8, 0x6d, 0xe6, 0x12, 0xac, 0x06, 0xe0, 0x66, 0x58, + 0xac, 0x0c, 0xc0, 0xa7, 0x10, 0xf3, 0x00, 0x46, 0x72, 0x2c, 0x86, 0xdf, + 0xb5, 0xee, 0x7a, 0x16, 0xcf, 0x47, 0x60, 0x0f, 0xf1, 0xda, 0x5e, 0x33, + 0x2a, 0x30, 0xc6, 0x27, 0x96, 0x7c, 0x45, 0xcc, 0x3d, 0x17, 0x29, 0x5b, + 0x2f, 0xac, 0xbb, 0xeb, 0xde, 0x3b, 0x99, 0x43, 0x65, 0xdb, 0x54, 0x14, + 0x08, 0x9d, 0x62, 0xef, 0x6c, 0x35, 0x29, 0xe7, 0x95, 0xe6, 0xd8, 0x70, + 0x7c, 0x33, 0x96, 0xb0, 0x38, 0xa8, 0x56, 0xc1, 0x9a, 0x40, 0xe7, 0x66, + 0x23, 0xd4, 0x22, 0x1a, 0xfa, 0x69, 0x1f, 0x58, 0xba, 0xcc, 0xd9, 0x5f, + 0x1c, 0xa1, 0x64, 0xeb, 0x1f, 0xa1, 0xc9, 0x33, 0x12, 0x8a, 0x83, 0xc2, + 0x9f, 0x09, 0x52, 0xb8, 0x0a, 0xc6, 0x66, 0x5c, 0x16, 0x5d, 0x19, 0x50, + 0x51, 0xe0, 0xfc, 0x41, 0xd8, 0x26, 0x68, 0xe2, 0x15, 0x29, 0x19, 0x43, + 0x2c, 0xbd, 0x8c, 0x67, 0x48, 0x00, 0x00, 0xa5, 0x17, 0x64, 0x6e, 0x77, + 0x30, 0xba, 0xd0, 0x7f, 0xd6, 0x9a, 0xd5, 0x4f, 0x9d, 0x88, 0x54, 0xc5, + 0x7f, 0x64, 0x65, 0x6d, 0xd2, 0xaa, 0xc7, 0x6d, 0xe2, 0x63, 0x4e, 0xba, + 0x07, 0x8a, 0x22, 0xa2, 0x6c, 0xba, 0xa2, 0xab, 0x36, 0x33, 0xac, 0x74, + 0x54, 0x05, 0x96, 0xb7, 0x5a, 0xc4, 0x93, 0x13, 0x68, 0xb0, 0x34, 0xe1, + 0x9d, 0x1d, 0xcd, 0x7d, 0xef, 0x43, 0x37, 0x2a, 0x8f, 0xbc, 0xbc, 0x8d, + 0xab, 0x2d, 0x51, 0x9e, 0x60, 0x82, 0xbd, 0x35, 0xab, 0xfe, 0x26, 0x5a, + 0xb8, 0x1b, 0x50, 0x0a, 0xb5, 0xe9, 0x2f, 0x01, 0x05, 0x0d, 0xcc, 0x8a, + 0x35, 0xec, 0xc7, 0x37, 0x98, 0x24, 0x98, 0x3c, 0x00, 0x56, 0x84, 0xd4, + 0xcc, 0x3b, 0x5c, 0x5a, 0x4b, 0x88, 0xa8, 0x9f, 0xd7, 0x2d, 0xe1, 0x54, + 0x27, 0xe9, 0x1f, 0x1c, 0x35, 0x94, 0xb5, 0x9b, 0x6f, 0xe3, 0x32, 0xaa, + 0x55, 0x7a, 0x56, 0x74, 0x21, 0x6a, 0xd8, 0xd5, 0x97, 0x75, 0x28, 0xf7, + 0x47, 0x52, 0xd5, 0x9d, 0x68, 0xa1, 0x62, 0x10, 0xf1, 0x3a, 0x38, 0x9f, + 0x33, 0x14, 0x48, 0x26, 0xe4, 0x44, 0xa6, 0xaf, 0x58, 0xa9, 0xab, 0xae, + 0x81, 0x83, 0x85, 0xd0, 0x6f, 0x29, 0xb7, 0x69, 0x63, 0xa7, 0x5a, 0x89, + 0x68, 0x59, 0x03, 0x03, 0x2b, 0x35, 0xac, 0xa5, 0xa5, 0xab, 0x49, 0x71, + 0x77, 0x4a, 0x14, 0x69, 0x70, 0xc2, 0x12, 0x28, 0x95, 0xdf, 0x58, 0xed, + 0xb4, 0x38, 0xc9, 0x5e, 0xf1, 0x24, 0x2e, 0x05, 0x42, 0xe8, 0x3c, 0xac, + 0x26, 0xbc, 0x41, 0xe4, 0x40, 0xf4, 0x48, 0xd9, 0xee, 0xa6, 0x63, 0x00, + 0x2b, 0xc4, 0x11, 0x88, 0xc8, 0x1d, 0x30, 0x98, 0xd2, 0x82, 0x61, 0xf4, + 0xe8, 0x66, 0x24, 0xd5, 0x3b, 0xc0, 0x57, 0x5b, 0xe5, 0x2f, 0x18, 0x86, + 0x54, 0x12, 0xb1, 0x19, 0x4c, 0x4a, 0x42, 0x52, 0x16, 0xca, 0x05, 0x46, + 0x3d, 0x48, 0x21, 0xac, 0xbb, 0x79, 0x79, 0xac, 0x4c, 0xe6, 0xa5, 0xd7, + 0x99, 0x6a, 0xcb, 0xf8, 0x97, 0xdc, 0x5a, 0xca, 0x66, 0x1e, 0x61, 0x66, + 0x55, 0x26, 0x39, 0x65, 0x56, 0xb6, 0xc9, 0x2c, 0xcd, 0x15, 0x16, 0xe7, + 0x61, 0x0c, 0xda, 0x9d, 0xa6, 0x4c, 0x61, 0xc2, 0x60, 0xb9, 0x19, 0x82, + 0x82, 0xf4, 0xea, 0x7f, 0xb9, 0x83, 0x4f, 0x4d, 0xc0, 0x05, 0x32, 0x9b, + 0x88, 0x53, 0xbd, 0x37, 0xc4, 0x76, 0x4a, 0x29, 0xd7, 0x19, 0xcf, 0xe6, + 0x2c, 0xcd, 0x09, 0xae, 0x81, 0xde, 0x1b, 0x41, 0x1d, 0x72, 0xa8, 0x2d, + 0x51, 0x4c, 0x3d, 0xe2, 0xe9, 0x21, 0x6e, 0x92, 0xff, 0x00, 0xfa, 0x96, + 0x17, 0x5a, 0xca, 0x39, 0xf4, 0x6c, 0x99, 0xdf, 0x4f, 0xbd, 0x1e, 0x5d, + 0xe3, 0xa8, 0xd7, 0x8e, 0x7e, 0x83, 0x46, 0x1f, 0x11, 0xf9, 0x65, 0x54, + 0xb9, 0x8a, 0x63, 0xb8, 0xa9, 0x21, 0x59, 0x6d, 0x75, 0x88, 0xb0, 0xf2, + 0x6e, 0x1a, 0x20, 0x55, 0xe5, 0xcc, 0xcb, 0xa3, 0xa4, 0xc3, 0x83, 0xa3, + 0x93, 0xc4, 0x53, 0xc1, 0x99, 0xfb, 0x42, 0x29, 0xab, 0x55, 0xaa, 0xce, + 0xd2, 0xd2, 0x0a, 0x80, 0x03, 0xab, 0x4a, 0x71, 0x8d, 0x81, 0xaa, 0x57, + 0x41, 0xf1, 0x0b, 0x08, 0x89, 0x86, 0x55, 0xb8, 0x96, 0xf6, 0x37, 0xdb, + 0x88, 0xd0, 0xc3, 0x5c, 0x98, 0x73, 0x50, 0x68, 0xba, 0x99, 0xd2, 0x34, + 0x78, 0xcc, 0xa1, 0x15, 0x32, 0x2c, 0x07, 0x72, 0x55, 0x00, 0xa0, 0x2e, + 0xb5, 0xed, 0x07, 0x08, 0xa3, 0x49, 0x42, 0xd4, 0x56, 0x35, 0xad, 0x78, + 0x81, 0x23, 0x4b, 0xb3, 0x4b, 0x0d, 0xb6, 0x75, 0xde, 0xe2, 0xa3, 0x8b, + 0x61, 0x46, 0x85, 0xc6, 0x2b, 0x80, 0xae, 0xb7, 0x14, 0xa7, 0x19, 0x82, + 0x81, 0x23, 0x46, 0x2d, 0xe3, 0x78, 0xb8, 0x0c, 0xd2, 0x27, 0xe7, 0x48, + 0x06, 0x13, 0x7c, 0xea, 0x61, 0xce, 0x9b, 0x47, 0x52, 0x86, 0xc5, 0xb4, + 0x1d, 0x2e, 0x22, 0x5d, 0x5e, 0x03, 0x11, 0x5b, 0xcf, 0xf5, 0x45, 0x5d, + 0xd6, 0x66, 0x8e, 0x5a, 0xc7, 0x98, 0xe1, 0x87, 0x48, 0xb8, 0x97, 0xbe, + 0x03, 0x1c, 0x8c, 0xed, 0x03, 0x15, 0x06, 0x76, 0x9c, 0x17, 0x02, 0x36, + 0xe6, 0x0a, 0x58, 0x73, 0xb1, 0x63, 0x48, 0xf8, 0x86, 0x2b, 0x0e, 0x25, + 0xc0, 0x2e, 0x3b, 0x17, 0x98, 0xc1, 0xd5, 0x88, 0xcb, 0x99, 0xb9, 0x79, + 0x20, 0x55, 0x58, 0x19, 0x79, 0xcc, 0x5a, 0x4a, 0x1b, 0xf2, 0x20, 0x0c, + 0x22, 0x6b, 0x7d, 0xd5, 0xe0, 0xa3, 0x3a, 0x97, 0xda, 0x3b, 0x90, 0xcd, + 0x4d, 0x2e, 0xa0, 0x11, 0x23, 0x08, 0xb8, 0x36, 0xd0, 0x06, 0x85, 0x45, + 0x9a, 0xfa, 0x59, 0x61, 0x9c, 0x50, 0xeb, 0x36, 0x5d, 0xe4, 0x82, 0xf6, + 0xd2, 0xf7, 0x70, 0x9b, 0x89, 0x97, 0x12, 0xaf, 0x43, 0x2c, 0xa9, 0x62, + 0x64, 0xe2, 0x2e, 0xeb, 0x3f, 0xba, 0xca, 0x2a, 0x2a, 0xa9, 0x55, 0x42, + 0x03, 0x33, 0x10, 0x8c, 0x2a, 0x22, 0x81, 0xfb, 0x8f, 0xbc, 0x30, 0x21, + 0x88, 0xb4, 0x73, 0x72, 0xed, 0xe6, 0xae, 0x49, 0xa9, 0x99, 0x7d, 0xcd, + 0x49, 0x75, 0xc0, 0x6e, 0x21, 0xb9, 0xad, 0x33, 0x4a, 0x34, 0x56, 0x5c, + 0x89, 0x4c, 0xc5, 0xa7, 0x71, 0x92, 0x3f, 0x5e, 0x89, 0x73, 0xfc, 0x39, + 0x8f, 0xde, 0x5a, 0xe6, 0x7c, 0xd7, 0xe8, 0x59, 0xd8, 0x86, 0x87, 0x0a, + 0x2d, 0x45, 0xf4, 0x61, 0xa2, 0x61, 0x85, 0xa6, 0x90, 0x0b, 0xfe, 0x84, + 0xae, 0x53, 0x1e, 0xd1, 0xf4, 0x87, 0xde, 0x29, 0x8a, 0xdd, 0x65, 0x43, + 0x09, 0xd1, 0x8f, 0x6a, 0x3b, 0x44, 0x9a, 0x3e, 0xe8, 0x3b, 0x11, 0xc1, + 0x0a, 0xbb, 0x8c, 0xeb, 0x88, 0xa3, 0x26, 0x77, 0x8d, 0xc3, 0x5d, 0x90, + 0x43, 0x46, 0x09, 0x30, 0x43, 0x09, 0x6f, 0xeb, 0xf7, 0x21, 0xf9, 0x8a, + 0x06, 0xa6, 0xf6, 0x5e, 0x63, 0xc9, 0x2e, 0xa9, 0x80, 0xe0, 0xc6, 0x26, + 0x06, 0x34, 0x02, 0x93, 0x40, 0xb8, 0x97, 0x6e, 0x0c, 0x21, 0xb8, 0x08, + 0x59, 0xb6, 0xe4, 0x2b, 0x04, 0x6b, 0xe4, 0x86, 0x86, 0xd3, 0xac, 0x4b, + 0x24, 0x45, 0x02, 0x3d, 0x22, 0x32, 0xc1, 0xaf, 0x71, 0x4d, 0x08, 0x39, + 0xaa, 0x85, 0x6c, 0x40, 0x16, 0x17, 0x15, 0x01, 0x66, 0xb7, 0x7b, 0xb8, + 0x94, 0xc5, 0x5b, 0xa5, 0xeb, 0xa4, 0x56, 0x59, 0x94, 0x1c, 0x45, 0xab, + 0x7e, 0x0f, 0x68, 0x01, 0xc6, 0x13, 0x61, 0x6d, 0xb5, 0xe6, 0x62, 0xab, + 0x7f, 0x0c, 0x53, 0x8d, 0x5e, 0x58, 0x5f, 0xac, 0x68, 0x02, 0xfd, 0x9e, + 0x63, 0xea, 0x05, 0x42, 0x7f, 0x74, 0xf6, 0x95, 0xdc, 0xd5, 0xbf, 0x11, + 0xc9, 0xc2, 0x59, 0xc1, 0x88, 0xa4, 0x0a, 0x9c, 0x46, 0x78, 0xba, 0x28, + 0x69, 0x84, 0x77, 0x77, 0xf1, 0x05, 0xc0, 0x2d, 0x5e, 0x0c, 0xd3, 0xe1, + 0x20, 0x21, 0x42, 0xba, 0x19, 0x60, 0x4b, 0x5c, 0x74, 0x95, 0xba, 0xff, + 0x00, 0x36, 0x2f, 0x21, 0x99, 0xe2, 0xb6, 0x3c, 0xc7, 0x08, 0x63, 0x46, + 0x0f, 0x30, 0x5f, 0x89, 0x44, 0x54, 0x18, 0x8e, 0x1c, 0x4b, 0x9c, 0xb0, + 0x01, 0xb4, 0x6f, 0x9a, 0xe9, 0x04, 0x07, 0x15, 0xa9, 0x05, 0x2d, 0x6b, + 0x0d, 0xb2, 0x4b, 0x18, 0xb4, 0xa7, 0x74, 0x62, 0xe1, 0x37, 0x63, 0x75, + 0x73, 0xde, 0xeb, 0x17, 0x2c, 0x91, 0xb8, 0x83, 0x59, 0x54, 0xd9, 0xca, + 0xa7, 0x1d, 0xa5, 0x6d, 0x59, 0x46, 0x8b, 0x2e, 0x94, 0x6a, 0x03, 0x70, + 0x6f, 0x56, 0xd1, 0x05, 0x3e, 0x8a, 0x6a, 0xac, 0x54, 0xac, 0xfa, 0x31, + 0x3d, 0x0a, 0x9e, 0xd7, 0xfa, 0x4a, 0x84, 0xc1, 0xac, 0xa6, 0xe6, 0x68, + 0x4e, 0x49, 0x57, 0x74, 0x82, 0xd3, 0x75, 0x33, 0x0a, 0x97, 0x69, 0xb9, + 0x4d, 0x66, 0x68, 0xe2, 0x55, 0x53, 0x47, 0x31, 0x8a, 0xcc, 0x5c, 0x46, + 0x0a, 0xb9, 0x85, 0xcc, 0xc1, 0xac, 0x1a, 0xd6, 0x07, 0x33, 0xaf, 0xe8, + 0xd4, 0x73, 0x1d, 0x2e, 0x66, 0xb7, 0xa0, 0xdb, 0xcc, 0x8c, 0xc2, 0x4a, + 0x66, 0x89, 0xd4, 0xa9, 0x7c, 0xac, 0xbc, 0xca, 0x94, 0x7e, 0xa1, 0xf6, + 0xff, 0x00, 0xa9, 0x92, 0xcc, 0xf9, 0xaf, 0xd0, 0x52, 0xc4, 0xfa, 0x5f, + 0x3e, 0x97, 0x16, 0x5f, 0xe6, 0x65, 0xe2, 0x60, 0x88, 0x5a, 0x07, 0x35, + 0x13, 0xb5, 0x34, 0xe0, 0xad, 0x0a, 0x98, 0xc6, 0x9d, 0x61, 0x68, 0x23, + 0x0d, 0x26, 0x34, 0xe9, 0x12, 0x5d, 0x5c, 0x2c, 0x28, 0x82, 0x8a, 0xa9, + 0x61, 0x60, 0xdc, 0xd8, 0x63, 0xb7, 0x0d, 0xe0, 0xee, 0x57, 0x7b, 0x82, + 0x71, 0x66, 0xd9, 0x84, 0x9c, 0xf9, 0x85, 0x3d, 0x03, 0xaa, 0x6b, 0x3c, + 0xa4, 0xa7, 0x6b, 0xbc, 0x69, 0x37, 0x2c, 0xbc, 0xcc, 0xd3, 0x21, 0x15, + 0x2c, 0x14, 0x11, 0xf7, 0x71, 0xde, 0x1c, 0xca, 0x1c, 0xcc, 0x84, 0x7a, + 0x53, 0x5a, 0x81, 0x14, 0x5a, 0x62, 0x1c, 0x9e, 0x90, 0x80, 0x8a, 0x9d, + 0x46, 0x20, 0xee, 0x06, 0xd8, 0x8c, 0x1d, 0xa8, 0x0c, 0x5f, 0x6d, 0xe5, + 0xdc, 0x2a, 0x6d, 0x5d, 0x56, 0x56, 0x65, 0x62, 0x2e, 0xb0, 0x5b, 0x02, + 0xf1, 0x7f, 0xe4, 0x43, 0xac, 0xbb, 0xec, 0xbf, 0x88, 0x43, 0x6c, 0xdf, + 0x73, 0x83, 0xe0, 0xf9, 0x8c, 0x0a, 0xea, 0x55, 0x41, 0xb7, 0xad, 0x33, + 0x52, 0xa2, 0xf0, 0xef, 0x34, 0x38, 0x9e, 0xc1, 0x08, 0x12, 0xc8, 0xe8, + 0x36, 0xf1, 0xb4, 0xba, 0x61, 0x6b, 0x1a, 0xb4, 0x3a, 0x41, 0x0e, 0x4f, + 0x1a, 0xb2, 0x9c, 0x8a, 0xe9, 0x2a, 0xb5, 0xaf, 0xd5, 0x31, 0x1e, 0xa8, + 0xb2, 0x8b, 0x6c, 0x5b, 0xca, 0x18, 0x52, 0x61, 0x30, 0x3b, 0xca, 0x83, + 0x75, 0xf8, 0x26, 0xad, 0xa4, 0xab, 0x31, 0x5d, 0xe3, 0xee, 0x61, 0x57, + 0x3a, 0xca, 0x73, 0x60, 0x4c, 0x74, 0xa0, 0xa0, 0xa6, 0x50, 0x4c, 0xc4, + 0x04, 0xb1, 0xb2, 0x5a, 0x03, 0x78, 0x56, 0xba, 0xb1, 0x01, 0x46, 0x47, + 0x8c, 0xcb, 0xc5, 0x81, 0x90, 0x1d, 0x32, 0xc7, 0x0e, 0xaf, 0x98, 0xed, + 0xda, 0x26, 0x89, 0xdc, 0x8d, 0xb1, 0x6d, 0x72, 0xac, 0xa9, 0x5e, 0x63, + 0xe8, 0x61, 0xac, 0xa8, 0x7f, 0xb8, 0x45, 0xae, 0x6b, 0x4a, 0x9f, 0x40, + 0x9c, 0xb3, 0xcc, 0x21, 0xcb, 0xca, 0x3f, 0x04, 0x55, 0x10, 0x42, 0xa5, + 0x33, 0x4a, 0x69, 0x54, 0x6c, 0x66, 0x75, 0xa6, 0x96, 0xc8, 0x56, 0x1c, + 0x35, 0x26, 0xb6, 0x62, 0xc6, 0x6f, 0x42, 0x3d, 0x74, 0x97, 0x8f, 0xa1, + 0x8d, 0x65, 0xf7, 0x16, 0xb1, 0xde, 0xf3, 0x77, 0xa6, 0xab, 0xf5, 0x4b, + 0xbb, 0x7e, 0x04, 0x56, 0xc2, 0x78, 0xe1, 0xfd, 0x77, 0x97, 0x3c, 0xd1, + 0x2f, 0x70, 0xb4, 0x61, 0xe7, 0xda, 0x62, 0x7c, 0x7d, 0x92, 0xe3, 0x17, + 0xb3, 0xaf, 0x99, 0x78, 0x86, 0x0f, 0xa1, 0x4c, 0x19, 0x73, 0x6c, 0x9c, + 0x16, 0x48, 0xaf, 0xda, 0x80, 0xdb, 0xb4, 0xab, 0x85, 0x44, 0xd9, 0x96, + 0xaf, 0x0e, 0xe4, 0x4c, 0x3d, 0xf3, 0x94, 0x3c, 0xb0, 0xf5, 0xb2, 0xba, + 0x3d, 0x25, 0xad, 0x53, 0x0a, 0xf3, 0x88, 0x28, 0x18, 0xf9, 0x82, 0xf1, + 0xf1, 0x05, 0x8b, 0xbf, 0x68, 0x5a, 0xe5, 0x13, 0x81, 0xf3, 0x7f, 0x88, + 0xe2, 0x88, 0xcc, 0xc1, 0xf4, 0x2c, 0xa8, 0x68, 0x6e, 0x11, 0x8a, 0x69, + 0x73, 0xc0, 0xa5, 0x95, 0xef, 0xfa, 0x96, 0x96, 0x01, 0x26, 0xa2, 0x83, + 0xe6, 0x29, 0x42, 0x82, 0x05, 0x64, 0xa6, 0xdf, 0xc4, 0x25, 0xae, 0x38, + 0x96, 0x98, 0xa9, 0x62, 0x16, 0x71, 0x1d, 0x02, 0xed, 0x46, 0xfd, 0x23, + 0x02, 0x02, 0x8e, 0x6e, 0x19, 0xd7, 0x2b, 0x2c, 0x5a, 0x88, 0x09, 0xbf, + 0xd3, 0x36, 0xce, 0xb0, 0x13, 0x5c, 0x01, 0xd8, 0x50, 0x83, 0xd4, 0x5a, + 0xba, 0xd2, 0x37, 0xa6, 0xb0, 0x6b, 0x26, 0x22, 0xc1, 0x70, 0xe7, 0x07, + 0x83, 0xf3, 0x30, 0x16, 0xad, 0x2b, 0x4e, 0xc4, 0xca, 0x82, 0x4f, 0x25, + 0x58, 0xf5, 0x16, 0x55, 0xd6, 0x63, 0xe6, 0xd6, 0x41, 0x25, 0xb6, 0xe8, + 0x80, 0x86, 0xaf, 0x0e, 0x2c, 0xa2, 0xd3, 0xde, 0x2c, 0x10, 0x8d, 0x31, + 0x91, 0x11, 0x8e, 0xee, 0x76, 0x7a, 0x4a, 0xdd, 0x6e, 0xe3, 0x81, 0x8c, + 0xeb, 0x33, 0x29, 0x7a, 0x4c, 0x82, 0x33, 0x72, 0xdd, 0xd6, 0x76, 0x8e, + 0x8c, 0x38, 0x75, 0x81, 0x6b, 0x79, 0x8e, 0x87, 0xac, 0x48, 0x39, 0x97, + 0xb6, 0x93, 0x55, 0xd2, 0x15, 0x32, 0xda, 0x19, 0x4f, 0x2a, 0x95, 0x43, + 0x73, 0xf8, 0x4d, 0x87, 0xbf, 0x8d, 0x62, 0xae, 0xa3, 0xf9, 0x27, 0xc2, + 0xf4, 0xb9, 0x71, 0x11, 0x62, 0x2d, 0x4a, 0x46, 0x07, 0x8c, 0xf1, 0x46, + 0x74, 0x8a, 0xdc, 0x01, 0x30, 0xab, 0x12, 0xbc, 0xbb, 0xcb, 0x9b, 0x91, + 0x7c, 0x26, 0x22, 0x31, 0x53, 0x39, 0xe8, 0xa1, 0x53, 0xad, 0x14, 0x89, + 0xbe, 0x60, 0xaa, 0xe5, 0xdd, 0x5a, 0x8f, 0xcd, 0xc1, 0xac, 0xe2, 0x5f, + 0x71, 0xea, 0x58, 0x33, 0x52, 0x5a, 0x54, 0xb3, 0x56, 0x22, 0x98, 0xae, + 0x0b, 0xb2, 0x0a, 0xff, 0x00, 0x90, 0xc5, 0x2d, 0xad, 0xe1, 0x1f, 0x91, + 0x32, 0x45, 0x71, 0xdf, 0x6f, 0x66, 0x5d, 0x09, 0x2e, 0x70, 0x86, 0x15, + 0xb8, 0xe8, 0xbf, 0xab, 0x7d, 0x0c, 0x27, 0xc3, 0xf9, 0x89, 0xa4, 0x10, + 0xbe, 0x56, 0xa6, 0xad, 0xea, 0x9a, 0xd7, 0xcd, 0x68, 0x1d, 0x21, 0xb8, + 0x93, 0x92, 0xa1, 0xf6, 0xa6, 0x3e, 0xa1, 0x98, 0xb6, 0x8c, 0x1e, 0x2a, + 0x37, 0xfd, 0x51, 0xd0, 0xd9, 0x94, 0x6e, 0x9e, 0xa4, 0x2b, 0xa9, 0x94, + 0x5a, 0x35, 0x83, 0x35, 0x1c, 0xa9, 0xe8, 0x41, 0xe3, 0xb4, 0x0d, 0xd9, + 0xab, 0x89, 0xb6, 0xb4, 0xbd, 0x20, 0xe9, 0x06, 0x0b, 0x58, 0x94, 0xdb, + 0x03, 0xf0, 0xbd, 0x1c, 0x13, 0x34, 0x18, 0xb2, 0x4b, 0x98, 0x6c, 0x6d, + 0xf5, 0xb2, 0xac, 0x67, 0x30, 0x46, 0xc2, 0xb4, 0xec, 0xc1, 0x6d, 0x82, + 0x50, 0xdf, 0x79, 0x7f, 0xa6, 0xda, 0x0a, 0x1f, 0x72, 0xeb, 0x7a, 0x1e, + 0xb1, 0x10, 0x68, 0x60, 0x75, 0x98, 0x19, 0xcc, 0x04, 0xd9, 0x94, 0x26, + 0x1a, 0x94, 0x47, 0x6c, 0x6c, 0x23, 0x45, 0x55, 0x72, 0xd5, 0xe2, 0x99, + 0x2e, 0x58, 0xb0, 0xa8, 0x7f, 0x35, 0x2f, 0x18, 0xe3, 0x48, 0x34, 0xcc, + 0x41, 0x6f, 0x18, 0x80, 0x40, 0xa6, 0x3d, 0x60, 0x85, 0x19, 0x62, 0x35, + 0x39, 0x9a, 0x80, 0x42, 0x20, 0x17, 0x74, 0xd0, 0x43, 0x40, 0x05, 0x5e, + 0x73, 0xe8, 0x53, 0x00, 0x53, 0xdd, 0x33, 0x1e, 0x76, 0xf0, 0xbb, 0x86, + 0x97, 0x1f, 0x64, 0xcc, 0xcc, 0x72, 0x8f, 0x1c, 0xc2, 0x91, 0xf4, 0xb7, + 0xb1, 0x18, 0xe2, 0x7b, 0x2c, 0x42, 0xee, 0xbc, 0xff, 0x00, 0x71, 0x12, + 0x9f, 0x78, 0xc5, 0xc4, 0xc9, 0xb3, 0x89, 0x4c, 0xfd, 0x8f, 0x71, 0x30, + 0x7a, 0x4b, 0xb1, 0xd2, 0x15, 0x4c, 0xb3, 0x98, 0x8a, 0x82, 0x58, 0xa6, + 0xf1, 0xd4, 0x88, 0x59, 0xac, 0xcf, 0x43, 0x2e, 0xb0, 0x03, 0x14, 0x1d, + 0x6e, 0xbc, 0x40, 0x1c, 0x1d, 0x72, 0xc6, 0xa3, 0xd4, 0x24, 0x66, 0xf5, + 0x8c, 0x22, 0x9c, 0x01, 0xac, 0x20, 0x50, 0xc4, 0x4d, 0xf2, 0x47, 0xed, + 0xcb, 0xa9, 0x71, 0xf4, 0x0b, 0xd2, 0xc5, 0xf5, 0x49, 0xe1, 0x2a, 0x99, + 0xa3, 0x1d, 0xd2, 0x87, 0xa4, 0xf3, 0x09, 0xdc, 0xdf, 0x4a, 0x51, 0x4c, + 0xc8, 0x41, 0xb2, 0xe5, 0x55, 0x99, 0x9f, 0x58, 0x37, 0xad, 0xca, 0xf7, + 0x97, 0x6b, 0xe9, 0x35, 0x8c, 0x5d, 0x18, 0x8a, 0xdc, 0x54, 0x8c, 0x0e, + 0xf1, 0x58, 0xe2, 0x6a, 0x4c, 0x0c, 0x53, 0x7c, 0xba, 0xe5, 0x81, 0xe9, + 0x66, 0xf8, 0x87, 0x9a, 0xaf, 0x32, 0x9a, 0x34, 0x48, 0xb1, 0x02, 0x75, + 0x1f, 0x43, 0xa8, 0x7e, 0x23, 0x60, 0xbd, 0x01, 0xde, 0x5a, 0x5c, 0x23, + 0x32, 0x3c, 0xb8, 0x8e, 0x8b, 0xfa, 0xbf, 0x42, 0xc7, 0xbb, 0x8a, 0xd2, + 0x67, 0x15, 0x45, 0xaa, 0xe9, 0xb8, 0xb9, 0xca, 0x6d, 0x8e, 0x21, 0x73, + 0x32, 0x7d, 0xae, 0xb7, 0xca, 0xbe, 0x20, 0x49, 0x1f, 0xcd, 0x0a, 0x2e, + 0xe6, 0x0c, 0x30, 0x7a, 0xb1, 0xb8, 0x6b, 0xb0, 0xc1, 0xf1, 0x8b, 0xa3, + 0x2a, 0xdb, 0x73, 0xb3, 0x0c, 0x55, 0x0a, 0x60, 0x6e, 0xff, 0x00, 0xc8, + 0x16, 0xbb, 0x72, 0xe2, 0x1b, 0x42, 0x64, 0xa1, 0x99, 0xb4, 0x66, 0x7b, + 0x40, 0xca, 0xee, 0x6a, 0x5a, 0xed, 0xfb, 0x23, 0xcb, 0xd3, 0x57, 0xe9, + 0x92, 0x60, 0x4d, 0x5b, 0xaf, 0xd0, 0xca, 0xa6, 0xc7, 0x33, 0x58, 0x18, + 0x26, 0x9f, 0xa2, 0x62, 0x3b, 0xcb, 0x87, 0x42, 0x3d, 0x63, 0x58, 0xaf, + 0x88, 0x86, 0x3a, 0x11, 0x8d, 0x9f, 0xa4, 0x6f, 0x7f, 0xb2, 0x39, 0x59, + 0xf9, 0x98, 0xcc, 0xcb, 0xa8, 0xb8, 0x38, 0x59, 0xf6, 0x52, 0xd2, 0x56, + 0x80, 0xd7, 0xdb, 0x6d, 0xd6, 0x6e, 0x2e, 0x61, 0x5a, 0x37, 0x94, 0x16, + 0xa6, 0xaf, 0x15, 0xa6, 0xb1, 0x1a, 0x16, 0x03, 0x5d, 0x21, 0x53, 0xab, + 0x01, 0x4e, 0xbc, 0xa1, 0xb1, 0x0c, 0xd1, 0x62, 0x44, 0xf7, 0x17, 0xcc, + 0x20, 0x5c, 0x26, 0x04, 0xd5, 0x41, 0x6a, 0xb8, 0x59, 0xa7, 0xcc, 0x7b, + 0x0b, 0x1a, 0xb0, 0xae, 0xd7, 0xf7, 0x0e, 0x57, 0x28, 0xaf, 0x3a, 0xcc, + 0xc4, 0x0a, 0x0e, 0x43, 0x50, 0x65, 0x01, 0xca, 0x99, 0x81, 0xe3, 0xee, + 0x62, 0xca, 0x5e, 0x75, 0x8e, 0xcc, 0x4b, 0xa8, 0x66, 0xd6, 0x5d, 0xe6, + 0x57, 0x4b, 0x09, 0xb1, 0x6c, 0x06, 0x3b, 0xa6, 0xad, 0x7f, 0xd9, 0xa9, + 0xcd, 0xbd, 0xe5, 0x29, 0x66, 0xb0, 0x71, 0x87, 0x39, 0xb2, 0x30, 0xd6, + 0x96, 0xe3, 0x68, 0xcd, 0x88, 0x64, 0xa5, 0xed, 0x1b, 0x4c, 0x61, 0xeb, + 0x2c, 0x6a, 0x90, 0x75, 0xdd, 0x87, 0x67, 0x54, 0x57, 0x17, 0xca, 0x55, + 0x49, 0xb9, 0x17, 0x0f, 0xac, 0x1a, 0x01, 0x03, 0x40, 0x18, 0x0e, 0x25, + 0x46, 0xc2, 0x28, 0x9b, 0x66, 0x57, 0x4b, 0xd4, 0x7d, 0xc5, 0xed, 0x46, + 0xd1, 0x85, 0xf4, 0x31, 0xc3, 0x29, 0xe7, 0x5c, 0x96, 0x1e, 0x86, 0x47, + 0xd4, 0xcd, 0x2a, 0xef, 0x45, 0x61, 0xbd, 0x7e, 0xa9, 0xd5, 0x95, 0x6f, + 0x3c, 0x92, 0xb9, 0xd4, 0xa8, 0x6c, 0xe3, 0x83, 0xe7, 0x31, 0x7c, 0xc5, + 0xc5, 0x84, 0x43, 0xab, 0x06, 0x6a, 0x4a, 0xe7, 0x52, 0x61, 0xd6, 0x5c, + 0xf4, 0x88, 0xb7, 0x12, 0x8e, 0xd0, 0x33, 0x09, 0x2f, 0x34, 0xcc, 0x70, + 0xc1, 0xa0, 0x6a, 0x3c, 0x51, 0xed, 0x16, 0x25, 0x0e, 0x71, 0x7f, 0xca, + 0x2a, 0x97, 0x08, 0xf2, 0x83, 0xc4, 0x30, 0x8b, 0x38, 0xa8, 0xff, 0x00, + 0xab, 0x87, 0xa9, 0x0b, 0xc2, 0xec, 0xf5, 0xb5, 0x7e, 0x6a, 0x9f, 0xc5, + 0x6f, 0x1e, 0xa9, 0x66, 0x8b, 0x49, 0x14, 0xea, 0x7d, 0x45, 0x42, 0x8b, + 0xaa, 0xf0, 0x04, 0xbd, 0xf0, 0x09, 0x5a, 0x8d, 0xb4, 0x88, 0xad, 0xa9, + 0x76, 0x97, 0x04, 0x5a, 0x37, 0xc3, 0x06, 0x93, 0x92, 0x64, 0x38, 0x60, + 0x06, 0xc0, 0xf6, 0x95, 0xd4, 0x1e, 0xd0, 0x7b, 0x7c, 0x4a, 0x5d, 0x52, + 0x75, 0x67, 0x52, 0x77, 0x12, 0x7f, 0x9e, 0x7d, 0x63, 0x94, 0xd5, 0x1e, + 0x66, 0x42, 0x5c, 0x7f, 0xaa, 0x95, 0x1d, 0xe6, 0x1a, 0x7f, 0x57, 0x59, + 0x5a, 0x76, 0x9e, 0xd9, 0x18, 0xb0, 0xe6, 0xe5, 0xb9, 0xb7, 0x09, 0x4a, + 0xd9, 0xcc, 0xa3, 0xce, 0x4c, 0x92, 0x8d, 0xbc, 0xcc, 0x1a, 0xd4, 0xa1, + 0x27, 0x73, 0xcc, 0x6a, 0xb1, 0x09, 0xd5, 0x03, 0xfc, 0xe6, 0x38, 0xb9, + 0x8b, 0x4e, 0x1e, 0x46, 0x43, 0x83, 0x25, 0xdd, 0xe7, 0x1b, 0x11, 0xba, + 0xa0, 0x32, 0x76, 0x37, 0x95, 0x6e, 0xd0, 0x94, 0x0a, 0x5e, 0xd2, 0xd1, + 0xc9, 0xbb, 0x37, 0x58, 0xa0, 0x2d, 0x86, 0x3c, 0x22, 0xc6, 0xac, 0x5d, + 0xcc, 0x33, 0x82, 0xe1, 0xdb, 0x09, 0xd2, 0x1d, 0xfd, 0x25, 0xcb, 0x96, + 0xfc, 0xca, 0x01, 0xc0, 0xc4, 0xa8, 0x97, 0x14, 0xfa, 0x26, 0x0a, 0xfc, + 0x1f, 0xca, 0x2c, 0xbd, 0x1e, 0x25, 0x64, 0x77, 0xac, 0x5b, 0xe6, 0x83, + 0xf1, 0x6e, 0xd1, 0xa0, 0x00, 0x09, 0x08, 0x39, 0x69, 0xde, 0x35, 0xa2, + 0x8c, 0x71, 0x1d, 0xcd, 0x84, 0x21, 0x9a, 0x6b, 0x79, 0x88, 0x54, 0x62, + 0x90, 0xa4, 0xcc, 0x12, 0x15, 0x67, 0x58, 0x15, 0x88, 0xc5, 0xb0, 0x30, + 0xbe, 0xab, 0xa8, 0x91, 0x7b, 0xed, 0x13, 0x80, 0x2d, 0xcc, 0xc3, 0x79, + 0x87, 0x60, 0x3f, 0x11, 0xb0, 0x14, 0x86, 0xd3, 0x07, 0xc8, 0xfb, 0x8f, + 0xd8, 0xf4, 0x30, 0xc3, 0x17, 0x31, 0xa4, 0x50, 0x1c, 0xc9, 0x53, 0x45, + 0xfa, 0x17, 0x4f, 0xa3, 0x24, 0xcb, 0x75, 0x96, 0x2f, 0x3f, 0x44, 0x5e, + 0x99, 0xf3, 0x00, 0x75, 0x81, 0x88, 0x30, 0xf7, 0x67, 0x52, 0x70, 0x5a, + 0x98, 0x6f, 0x13, 0xbb, 0x01, 0x23, 0x73, 0x64, 0x6a, 0xf4, 0xec, 0x8c, + 0xe6, 0xa3, 0x58, 0xe3, 0x89, 0xf4, 0x26, 0xd8, 0x57, 0xa5, 0x46, 0x6b, + 0x84, 0x7d, 0xbe, 0x46, 0x29, 0x7d, 0x5f, 0xf5, 0xcb, 0xfc, 0xcc, 0x90, + 0xf4, 0x19, 0x11, 0xd7, 0x79, 0xe8, 0xbf, 0x48, 0x25, 0xaa, 0x2c, 0x4d, + 0x2b, 0x2e, 0x9c, 0x5c, 0x5b, 0x04, 0xa7, 0x3c, 0xd0, 0xfb, 0xf2, 0xcc, + 0x3a, 0x02, 0xb5, 0x28, 0x70, 0x06, 0x89, 0x57, 0xea, 0x8d, 0x4d, 0xb8, + 0x21, 0x5b, 0xd4, 0xad, 0xf6, 0x38, 0x80, 0xdc, 0xba, 0xd1, 0x1d, 0xd0, + 0x17, 0x92, 0x0d, 0x6d, 0xa3, 0x70, 0x8b, 0x04, 0x1d, 0x2b, 0xd1, 0x00, + 0x69, 0x3d, 0x4a, 0x87, 0x14, 0xe0, 0x21, 0x59, 0x8c, 0x94, 0x53, 0x35, + 0xa5, 0xdb, 0xfc, 0x11, 0x54, 0xe4, 0x8b, 0x2e, 0x64, 0x98, 0x12, 0xf7, + 0xc8, 0x8c, 0x86, 0x75, 0x94, 0x82, 0x7b, 0x52, 0x61, 0x7b, 0xcd, 0xa4, + 0xaa, 0x97, 0xfd, 0x89, 0x63, 0xce, 0xe4, 0xaa, 0xd6, 0xe9, 0x2f, 0x35, + 0x94, 0xe2, 0xe2, 0x83, 0x54, 0x94, 0x85, 0x72, 0xdb, 0x13, 0x67, 0x19, + 0xe8, 0xcc, 0x77, 0x56, 0x59, 0xd2, 0x3c, 0xc4, 0xc4, 0xe1, 0x72, 0x97, + 0xe4, 0x2b, 0xe9, 0x86, 0x02, 0x10, 0xbc, 0x74, 0x7f, 0x51, 0x64, 0x94, + 0x28, 0x57, 0x0f, 0x7b, 0xf9, 0x8a, 0xb0, 0xf8, 0x44, 0xd8, 0x94, 0xb5, + 0xa9, 0x52, 0xe5, 0x95, 0x65, 0x71, 0x04, 0x70, 0x2e, 0xab, 0x2e, 0x1e, + 0x05, 0x26, 0x1a, 0x27, 0xe2, 0x05, 0x1b, 0xb1, 0xd1, 0x95, 0x5b, 0xc3, + 0x32, 0xa1, 0x18, 0x28, 0xff, 0x00, 0x16, 0x8a, 0xd4, 0x26, 0xa8, 0xfa, + 0x6b, 0x70, 0x8c, 0xac, 0x54, 0xbf, 0x77, 0x96, 0x59, 0xb9, 0xd7, 0xaa, + 0x6a, 0x6a, 0xbd, 0xe2, 0xe1, 0x6e, 0xdb, 0x47, 0x47, 0x0b, 0x96, 0x93, + 0x57, 0x07, 0x98, 0x4b, 0x6b, 0x63, 0xdd, 0x04, 0xc8, 0xd8, 0x53, 0xac, + 0x02, 0xa1, 0xa0, 0xe9, 0x29, 0x94, 0xa3, 0xcc, 0x17, 0xd2, 0x0b, 0xb3, + 0xa1, 0x13, 0x95, 0x5d, 0x78, 0x23, 0x55, 0xa1, 0x58, 0x56, 0x03, 0x69, + 0x48, 0xdd, 0xe5, 0xa4, 0x1b, 0x88, 0xc5, 0x19, 0x98, 0x0e, 0x4f, 0xdc, + 0xab, 0xb1, 0x18, 0x61, 0xf4, 0x79, 0x25, 0xac, 0xaf, 0xab, 0x12, 0xa1, + 0xe8, 0x5d, 0x2f, 0xac, 0xbb, 0xde, 0x0c, 0xa7, 0xbd, 0x3c, 0x21, 0xf9, + 0x8e, 0xbd, 0x2c, 0x3c, 0xc6, 0xda, 0x78, 0x23, 0x10, 0x13, 0x88, 0x23, + 0xac, 0x14, 0xb3, 0xac, 0x69, 0x06, 0xb8, 0xff, 0x00, 0xcb, 0xd7, 0x42, + 0x2c, 0x66, 0x23, 0xd2, 0xfa, 0x4d, 0x5a, 0x42, 0xd3, 0x05, 0x8b, 0xf3, + 0xd1, 0x57, 0x10, 0x1a, 0xca, 0xd9, 0x18, 0x80, 0x1a, 0x72, 0xfc, 0xe0, + 0xe2, 0x60, 0xde, 0x39, 0x4b, 0xaf, 0x49, 0x65, 0x17, 0xbc, 0x83, 0x16, + 0x2b, 0xfe, 0x9a, 0xcc, 0xda, 0x88, 0xc9, 0xdc, 0x7d, 0x20, 0x16, 0xc0, + 0xb1, 0x7d, 0x60, 0x54, 0x2e, 0xcc, 0xb6, 0x00, 0x3f, 0xa0, 0x17, 0xf2, + 0xb6, 0xbd, 0x56, 0x55, 0xd0, 0x6c, 0x95, 0x74, 0xfd, 0x04, 0xa0, 0x90, + 0xcb, 0x56, 0x66, 0xf4, 0x74, 0x4e, 0x1e, 0x23, 0x36, 0x2a, 0x5d, 0x68, + 0x5e, 0xd2, 0xcd, 0xa2, 0x57, 0x18, 0x26, 0x22, 0x9a, 0x3e, 0x20, 0x8b, + 0x4f, 0x13, 0x0a, 0x0c, 0x32, 0xc7, 0xa1, 0x0c, 0xb8, 0x22, 0xd3, 0xb4, + 0x0a, 0xba, 0xa8, 0x75, 0x19, 0xa5, 0xc2, 0x2a, 0x66, 0x04, 0xab, 0xa9, + 0xf8, 0x23, 0x15, 0xd1, 0x84, 0x70, 0x99, 0x4b, 0xd8, 0x94, 0x75, 0x2e, + 0x54, 0x26, 0x13, 0x75, 0x99, 0xd6, 0xdc, 0x9b, 0x8e, 0x6d, 0x98, 0x19, + 0xcc, 0xae, 0x28, 0x35, 0x8d, 0x42, 0x6e, 0x9d, 0x26, 0x0c, 0x94, 0xf5, + 0xad, 0x03, 0xf2, 0x8a, 0xe2, 0xe6, 0x3f, 0xe8, 0xda, 0x15, 0xe1, 0x7e, + 0x63, 0xd9, 0x89, 0x4d, 0x2b, 0x31, 0xbb, 0x6e, 0x1b, 0xba, 0xb6, 0xed, + 0x00, 0xc0, 0x1d, 0xa5, 0x47, 0xac, 0x47, 0x33, 0x16, 0xa4, 0xb2, 0xe9, + 0x95, 0xd1, 0xcc, 0xb9, 0xc7, 0x92, 0x1a, 0xd7, 0xec, 0x98, 0x1b, 0x86, + 0xec, 0xd2, 0x39, 0x0b, 0xbf, 0x69, 0x72, 0xdd, 0x8d, 0x59, 0x8b, 0xfe, + 0x2d, 0x1e, 0x5b, 0xc1, 0x82, 0xf5, 0x81, 0xbb, 0xa9, 0xaa, 0xf4, 0x93, + 0xce, 0x50, 0x3f, 0xe6, 0x51, 0x68, 0x73, 0x51, 0xb8, 0xe2, 0x6b, 0xbc, + 0x33, 0x52, 0xcd, 0x1a, 0x8e, 0xee, 0xd3, 0xf3, 0x31, 0x8a, 0x0b, 0x58, + 0x71, 0x29, 0x65, 0x10, 0xad, 0x21, 0x5e, 0x29, 0x83, 0x10, 0x50, 0x67, + 0xa4, 0x2a, 0x19, 0x5d, 0x63, 0xd8, 0xf9, 0x7a, 0x0e, 0x21, 0x18, 0xd6, + 0x23, 0xd5, 0x40, 0xf9, 0x62, 0xc9, 0x8a, 0x9a, 0xb4, 0xf4, 0xfc, 0xa2, + 0xf6, 0xbf, 0x73, 0xd8, 0xa3, 0x0c, 0x2e, 0x3d, 0x26, 0xb7, 0xe8, 0x54, + 0x75, 0x3f, 0x98, 0x74, 0x73, 0xe8, 0x2b, 0x96, 0x4b, 0x83, 0x2b, 0xee, + 0x45, 0x97, 0xa3, 0xed, 0x8f, 0x49, 0x5e, 0x62, 0xa0, 0xf4, 0x8a, 0x62, + 0x33, 0x30, 0xeb, 0xe8, 0x85, 0x26, 0xad, 0x65, 0x62, 0xcb, 0x67, 0x5f, + 0x1e, 0x8f, 0x56, 0x75, 0xdf, 0x41, 0xf4, 0x89, 0x4f, 0x41, 0xd9, 0x07, + 0xbc, 0xa9, 0x82, 0x38, 0xca, 0x08, 0xdf, 0xfb, 0x1f, 0x13, 0x88, 0x5b, + 0x25, 0xd5, 0x37, 0xe9, 0x70, 0xca, 0x3c, 0xe7, 0xb8, 0xbd, 0x0f, 0x54, + 0xb2, 0x9f, 0xe5, 0xcf, 0xde, 0x04, 0x19, 0x01, 0xa7, 0x71, 0xda, 0x72, + 0xa8, 0xbd, 0x7c, 0x63, 0xf5, 0x1a, 0x6f, 0x16, 0x9a, 0xad, 0x0a, 0xc4, + 0xbd, 0x53, 0x43, 0x64, 0x42, 0x51, 0x5b, 0xd4, 0xd4, 0x18, 0xd5, 0x70, + 0x04, 0xdd, 0xcc, 0x5d, 0x8d, 0x25, 0x99, 0xc1, 0x87, 0x2d, 0x22, 0xd7, + 0x67, 0xd0, 0x44, 0x19, 0x7b, 0x19, 0x92, 0x03, 0x33, 0x5d, 0xe3, 0xa4, + 0x33, 0xde, 0x63, 0xed, 0x2c, 0x80, 0xaa, 0x73, 0x4b, 0xf4, 0x35, 0x95, + 0x19, 0xfc, 0x5e, 0x13, 0x55, 0xdd, 0x6e, 0x5b, 0x37, 0xdf, 0x54, 0x25, + 0x76, 0x72, 0xfd, 0xc5, 0x13, 0xa1, 0x28, 0xef, 0x44, 0x86, 0xba, 0xc5, + 0xbc, 0x82, 0xe3, 0x51, 0x07, 0xad, 0xcd, 0x39, 0x01, 0x02, 0x73, 0x39, + 0xdd, 0x6a, 0x59, 0x8d, 0xa4, 0x3e, 0xa3, 0x17, 0x31, 0x6f, 0xa4, 0x3e, + 0x98, 0xbd, 0x97, 0xd3, 0x2a, 0xc4, 0xb4, 0x55, 0x89, 0x6c, 0x37, 0x2f, + 0xac, 0x43, 0x0c, 0xb5, 0xae, 0x16, 0xa9, 0x8d, 0xce, 0x9b, 0x47, 0xd4, + 0x69, 0x8d, 0x66, 0xee, 0xbc, 0x47, 0x00, 0x6d, 0xac, 0x60, 0xa9, 0x55, + 0xcd, 0x41, 0xa2, 0x34, 0x2f, 0xb4, 0x17, 0xdb, 0x7c, 0x9e, 0x90, 0xd6, + 0xfe, 0x6d, 0x8f, 0x28, 0x4e, 0xd0, 0x67, 0x48, 0x1b, 0xc0, 0xcc, 0x74, + 0xb2, 0xb3, 0x03, 0xd7, 0x0f, 0xcb, 0x2e, 0x80, 0xc3, 0xad, 0x40, 0x34, + 0x71, 0x18, 0x91, 0x81, 0x88, 0x39, 0xf3, 0x90, 0x2f, 0xc8, 0x74, 0x62, + 0x85, 0x38, 0x45, 0x59, 0x31, 0x39, 0x99, 0x03, 0x24, 0xd0, 0x62, 0x55, + 0x37, 0x2b, 0x55, 0x2b, 0x37, 0xcd, 0x8d, 0x7b, 0x33, 0x9d, 0x63, 0xf7, + 0x95, 0x07, 0x42, 0x2f, 0x65, 0xf6, 0xcc, 0x5e, 0xde, 0x96, 0x28, 0xf5, + 0x87, 0x29, 0x50, 0xe4, 0x7e, 0xa3, 0xc6, 0x64, 0xd6, 0x2f, 0x12, 0xfb, + 0xcb, 0x97, 0x99, 0x40, 0x7a, 0xcd, 0x45, 0xb3, 0xed, 0x8a, 0xb7, 0xb8, + 0x8d, 0x9f, 0x42, 0xad, 0xa5, 0x87, 0x58, 0xe4, 0x52, 0x6c, 0x4d, 0x73, + 0x03, 0x0c, 0xbc, 0x53, 0x89, 0x48, 0xbd, 0x26, 0x53, 0xff, 0x00, 0x0b, + 0x36, 0x76, 0xc3, 0xac, 0x1a, 0xe6, 0x5a, 0x32, 0x83, 0x8b, 0xdc, 0xea, + 0x39, 0xf1, 0x30, 0x1c, 0xb5, 0xd9, 0xd2, 0x4e, 0x89, 0x4f, 0x99, 0x6a, + 0xdc, 0x2b, 0x33, 0xde, 0x6c, 0x8f, 0x3e, 0xd2, 0x8e, 0xf3, 0xd7, 0x31, + 0x40, 0x29, 0xb9, 0xd4, 0x53, 0x5c, 0xd7, 0xea, 0x1c, 0x53, 0xa1, 0x37, + 0x2e, 0x7e, 0xc2, 0x3f, 0x71, 0x59, 0x18, 0x0c, 0x8e, 0xe8, 0x81, 0xe8, + 0x06, 0x40, 0x68, 0x2d, 0xc3, 0xa7, 0x49, 0x98, 0x45, 0x52, 0xb6, 0xea, + 0xf0, 0xa7, 0xe2, 0x16, 0xac, 0xe3, 0x4e, 0x22, 0x58, 0x58, 0xdc, 0x8d, + 0x70, 0xe8, 0x4c, 0x8c, 0x41, 0xf4, 0xc4, 0xaa, 0xab, 0x8d, 0x99, 0x55, + 0xb1, 0xad, 0x07, 0xc4, 0xbc, 0xfe, 0xe0, 0xdb, 0x30, 0xa9, 0xde, 0x0b, + 0x47, 0x6f, 0x42, 0xee, 0x0b, 0x16, 0x65, 0x06, 0x2f, 0x32, 0xfa, 0x23, + 0xa7, 0xd2, 0x64, 0x8c, 0xbd, 0x22, 0x61, 0x3c, 0xfc, 0xb3, 0x06, 0x62, + 0x77, 0xc4, 0x6c, 0x39, 0x75, 0x19, 0x57, 0x13, 0x17, 0x45, 0xe8, 0xc2, + 0xe1, 0x2b, 0x35, 0xb6, 0x30, 0x9d, 0x58, 0x3b, 0x4c, 0xa9, 0x25, 0x5e, + 0x13, 0x5f, 0x15, 0x28, 0x6f, 0x68, 0xe5, 0x8d, 0x22, 0x69, 0x5a, 0xd3, + 0xf0, 0xfc, 0xc0, 0x1a, 0x5e, 0x0e, 0x4b, 0x1d, 0x0f, 0x10, 0x2a, 0xb4, + 0xc5, 0x98, 0x8c, 0x2c, 0x3e, 0xce, 0x8d, 0xf1, 0x23, 0xb4, 0x65, 0xdd, + 0x88, 0x56, 0xce, 0x19, 0x7a, 0xd2, 0xe5, 0xf7, 0x99, 0x6a, 0x5f, 0x5d, + 0x58, 0xd0, 0xc8, 0x60, 0x5b, 0x4f, 0xd2, 0x0d, 0x18, 0xb3, 0x59, 0x8f, + 0x2d, 0x6d, 0x51, 0xe8, 0x2d, 0x97, 0xd0, 0x41, 0x57, 0xad, 0x8f, 0xbb, + 0xd1, 0x17, 0x59, 0x54, 0x08, 0xe2, 0x2c, 0xc1, 0x4d, 0x75, 0x9b, 0xe2, + 0x60, 0x3f, 0x98, 0x25, 0x6c, 0x94, 0x21, 0xc3, 0xaf, 0xb4, 0x42, 0x1a, + 0xa3, 0x69, 0x23, 0x6b, 0x15, 0x4a, 0xaf, 0xc7, 0xf6, 0x20, 0x82, 0xa8, + 0xcb, 0x32, 0xe1, 0x92, 0xe3, 0x5d, 0xe5, 0xd5, 0x82, 0xaa, 0xd7, 0x1c, + 0x3a, 0x99, 0x79, 0x8c, 0x76, 0xa3, 0x9a, 0xc0, 0x1f, 0x6c, 0x6b, 0xd3, + 0x27, 0xce, 0x19, 0xd8, 0x23, 0xbe, 0xdb, 0xf3, 0x30, 0x3b, 0x7a, 0x1f, + 0x40, 0xa2, 0x8b, 0x73, 0xb9, 0x87, 0xed, 0xf8, 0x9e, 0xd5, 0x33, 0xb3, + 0xc9, 0x2d, 0x34, 0x4b, 0x94, 0x08, 0x36, 0xef, 0x87, 0xcb, 0xe8, 0x55, + 0x34, 0x33, 0x2c, 0x8e, 0xe2, 0xa9, 0x44, 0x2a, 0xf3, 0x00, 0x5c, 0x4a, + 0xad, 0x62, 0x87, 0x58, 0xcd, 0x0e, 0xb0, 0xa5, 0xb1, 0xd7, 0xd2, 0xf8, + 0x8e, 0xa2, 0xd6, 0x1e, 0x61, 0xb8, 0xb2, 0xd8, 0xd2, 0xbc, 0x24, 0x06, + 0x84, 0x57, 0x29, 0x15, 0xc4, 0xc9, 0x0a, 0xcc, 0x9e, 0xd2, 0xaf, 0x43, + 0xca, 0x31, 0x36, 0x9a, 0xb1, 0x02, 0x49, 0xf9, 0xe7, 0xed, 0x1a, 0x49, + 0xf2, 0x0a, 0x3c, 0x90, 0xfb, 0xf7, 0xcc, 0x0f, 0xbb, 0x58, 0x22, 0xcb, + 0xa0, 0x46, 0xae, 0x13, 0x56, 0xaa, 0xc6, 0x9e, 0xf8, 0x88, 0x34, 0xca, + 0x75, 0x25, 0x7b, 0x27, 0xb4, 0x62, 0xb3, 0x74, 0x2a, 0x98, 0xee, 0xce, + 0xa7, 0xa3, 0xc4, 0xa0, 0x2a, 0xd6, 0x46, 0x58, 0x4b, 0x68, 0xd3, 0xe6, + 0x23, 0xa3, 0x10, 0xe1, 0xa4, 0xcd, 0x71, 0x59, 0x77, 0x07, 0x39, 0xd6, + 0x10, 0xbc, 0xeb, 0x16, 0x1e, 0x9f, 0x8c, 0xc4, 0x45, 0xf4, 0x18, 0xa2, + 0xc6, 0x6a, 0xf9, 0x5f, 0x44, 0x5e, 0xeb, 0x31, 0x73, 0xa9, 0xe6, 0x02, + 0x60, 0x57, 0x12, 0x9e, 0xe4, 0xca, 0xf7, 0x86, 0x4c, 0xf0, 0x7c, 0xce, + 0xd8, 0x6a, 0x2d, 0x0e, 0xb0, 0xc2, 0x25, 0x40, 0xd5, 0x8b, 0xaf, 0xfc, + 0x88, 0xaa, 0x17, 0x3b, 0x72, 0x0e, 0x62, 0x69, 0x25, 0xdd, 0x56, 0xb1, + 0x36, 0xb4, 0x59, 0x7d, 0x28, 0xad, 0xf5, 0xbf, 0x11, 0x5b, 0xfa, 0xd6, + 0xb2, 0x38, 0x4a, 0xd9, 0x3f, 0x70, 0x3e, 0x04, 0xf9, 0xc2, 0x95, 0xaf, + 0x4d, 0x0e, 0xe2, 0x0d, 0xa8, 0x54, 0xc1, 0x69, 0xbe, 0x75, 0xf2, 0x22, + 0x06, 0xb3, 0x00, 0x17, 0xd0, 0xca, 0xeb, 0xf4, 0x82, 0x9e, 0xe3, 0x5e, + 0xf1, 0x9e, 0xc4, 0x6a, 0x93, 0x3c, 0xad, 0x79, 0x94, 0x5b, 0x95, 0xc5, + 0x10, 0xdd, 0x69, 0xe3, 0x2c, 0x49, 0xd0, 0x14, 0x09, 0x71, 0xd4, 0xb6, + 0xa1, 0x8b, 0x97, 0x19, 0x2f, 0x7b, 0x87, 0x33, 0x83, 0xf0, 0x47, 0x96, + 0x21, 0x25, 0xda, 0x69, 0x3a, 0x26, 0x91, 0x4d, 0x91, 0x8d, 0xba, 0x15, + 0x78, 0x26, 0x11, 0x8d, 0x0c, 0x42, 0xff, 0x00, 0x2c, 0x4d, 0x01, 0x1e, + 0x65, 0x1d, 0xe1, 0x16, 0x40, 0x21, 0x56, 0xf4, 0x78, 0xbf, 0xf2, 0x2c, + 0x1c, 0x53, 0x55, 0x28, 0xa0, 0xe6, 0xa0, 0x27, 0xc3, 0x19, 0xfc, 0x44, + 0xb1, 0x52, 0xeb, 0x43, 0x96, 0x5a, 0x62, 0x8b, 0x4e, 0x0a, 0x11, 0x00, + 0x88, 0x81, 0xe4, 0xee, 0x65, 0x68, 0xd4, 0x51, 0xda, 0x55, 0xbf, 0x9f, + 0xdc, 0x1b, 0x09, 0x7d, 0x63, 0x84, 0x51, 0x6d, 0xa9, 0x8a, 0xc5, 0x4b, + 0x9d, 0xf2, 0x18, 0x76, 0x0a, 0x8a, 0xcc, 0xcc, 0x49, 0xc1, 0x16, 0x45, + 0x4d, 0x71, 0x16, 0x0c, 0xb5, 0x7f, 0x32, 0xc5, 0x8f, 0x41, 0xf5, 0x94, + 0x4a, 0x1f, 0x48, 0xa4, 0xb6, 0xae, 0x00, 0x99, 0x95, 0xaf, 0xa5, 0x5c, + 0x4f, 0x68, 0x87, 0x68, 0x89, 0x5f, 0x48, 0xc4, 0x10, 0xc3, 0xac, 0x30, + 0xeb, 0xe8, 0x66, 0x9d, 0x86, 0x9f, 0x53, 0x68, 0x83, 0x2d, 0x8b, 0x74, + 0x88, 0x81, 0x5c, 0x46, 0x83, 0x70, 0x04, 0x7e, 0x20, 0x96, 0xfc, 0x5f, + 0xb8, 0xa2, 0xc6, 0xed, 0x0c, 0x9e, 0x8c, 0xad, 0x0b, 0xab, 0x8c, 0x19, + 0xde, 0x10, 0x16, 0x0c, 0x01, 0x41, 0x5a, 0x9d, 0x10, 0x18, 0xd6, 0xc1, + 0xb3, 0xba, 0x35, 0xec, 0xc5, 0x93, 0x2f, 0x45, 0x53, 0xa9, 0x33, 0xf0, + 0x4d, 0x26, 0x07, 0xd2, 0x2e, 0x68, 0xf2, 0xc3, 0x90, 0xa8, 0xb7, 0x26, + 0x4b, 0x8c, 0xb4, 0x74, 0x5c, 0x69, 0x37, 0xe1, 0x8c, 0xce, 0xd0, 0xa4, + 0xda, 0xac, 0x1d, 0xee, 0x91, 0x81, 0x5a, 0xeb, 0x5b, 0xb2, 0x62, 0x0d, + 0x6c, 0xb9, 0xf1, 0x1d, 0x2c, 0x03, 0x43, 0x77, 0xae, 0x60, 0x87, 0x58, + 0x26, 0xb9, 0x8c, 0xbd, 0x5e, 0x23, 0x85, 0x36, 0xb8, 0x71, 0x0e, 0x26, + 0x6f, 0x9a, 0xfd, 0x45, 0x52, 0x8f, 0xa5, 0xc5, 0x98, 0xec, 0x4d, 0x47, + 0xa9, 0xf1, 0x06, 0xa8, 0xef, 0x2a, 0x3d, 0x93, 0x05, 0xd2, 0x69, 0x08, + 0x94, 0xa8, 0xdd, 0x6a, 0x0b, 0x7e, 0x95, 0xf7, 0x2f, 0x85, 0x9d, 0x65, + 0x5a, 0x47, 0x4c, 0x24, 0xb8, 0x10, 0x63, 0xc2, 0x80, 0xdc, 0xff, 0x00, + 0x97, 0xdc, 0x75, 0x5e, 0xad, 0x99, 0x2b, 0x00, 0x2a, 0xac, 0xbc, 0x0b, + 0x24, 0x6b, 0x45, 0xc7, 0xf7, 0x31, 0x4d, 0xb9, 0xc6, 0xbf, 0x53, 0x7d, + 0x5d, 0xd4, 0x95, 0xb9, 0x05, 0x64, 0x29, 0x98, 0xea, 0xb0, 0x9c, 0x41, + 0xb6, 0x29, 0xb8, 0x16, 0x12, 0xcf, 0x6e, 0x20, 0x16, 0xa2, 0xc6, 0xb1, + 0x08, 0x03, 0x92, 0xaa, 0x9d, 0xbb, 0xc5, 0x90, 0x41, 0x83, 0xa6, 0xe3, + 0xde, 0x18, 0x7c, 0xc0, 0xdd, 0x56, 0x8c, 0x55, 0xd3, 0xa4, 0x72, 0x51, + 0x99, 0x78, 0xea, 0xa0, 0x3c, 0x5b, 0x89, 0x9e, 0xaa, 0x6b, 0x35, 0x1b, + 0x6e, 0x1f, 0xfb, 0x02, 0x97, 0x3a, 0xeb, 0xcc, 0x58, 0x6a, 0xa3, 0xaf, + 0x09, 0xab, 0xa8, 0x67, 0x2e, 0xe5, 0x4c, 0x45, 0x23, 0x61, 0x1b, 0x33, + 0x22, 0x74, 0x80, 0x90, 0x72, 0xd1, 0x59, 0x95, 0xd3, 0x99, 0xcd, 0x0e, + 0x08, 0xba, 0xf6, 0x6d, 0xfc, 0x4b, 0xa5, 0x48, 0x35, 0xd7, 0xa1, 0x12, + 0xa2, 0x85, 0x15, 0xc4, 0x11, 0xa5, 0x57, 0x10, 0x15, 0xd3, 0x78, 0x50, + 0x20, 0xcf, 0x59, 0x8c, 0x4e, 0xc1, 0xf2, 0xad, 0x0f, 0x2d, 0x46, 0xef, + 0x1b, 0x65, 0x8d, 0x82, 0x19, 0x0b, 0x03, 0x5b, 0x38, 0x89, 0xea, 0xe1, + 0x18, 0x05, 0x09, 0x8d, 0x2f, 0x11, 0x71, 0x31, 0x6d, 0xae, 0xbd, 0x06, + 0x7b, 0xc5, 0x87, 0xa9, 0x69, 0xe7, 0x88, 0x69, 0x16, 0x2f, 0xa5, 0x54, + 0x0b, 0x18, 0x28, 0x1d, 0xd1, 0x22, 0x0d, 0xd3, 0x90, 0xce, 0xf1, 0x31, + 0x7b, 0xda, 0x6e, 0x40, 0x93, 0x4f, 0x30, 0x09, 0x63, 0x02, 0xe7, 0x68, + 0xd9, 0x31, 0x25, 0xfd, 0x56, 0x52, 0x97, 0x14, 0x43, 0x0a, 0x96, 0x76, + 0xf4, 0x37, 0x8c, 0xd9, 0xe8, 0x2b, 0x8d, 0xa9, 0xbe, 0x7c, 0xe1, 0xe9, + 0x2e, 0x87, 0xd1, 0xd7, 0xf4, 0x0d, 0x76, 0xcf, 0xa9, 0x8c, 0xd7, 0x13, + 0xc4, 0x41, 0xa4, 0xb0, 0x88, 0xcd, 0x93, 0xa6, 0x35, 0xf2, 0xcf, 0x6d, + 0x7b, 0xb4, 0xf0, 0x7e, 0xe2, 0x2b, 0x80, 0xb5, 0xc6, 0xbe, 0x3e, 0xe5, + 0xa2, 0x74, 0x72, 0x53, 0xba, 0x46, 0xf5, 0x6d, 0x5f, 0xe5, 0x89, 0x6b, + 0x33, 0x70, 0x0e, 0xa3, 0x63, 0x23, 0x86, 0x05, 0x82, 0xed, 0xff, 0x00, + 0x10, 0x36, 0x04, 0xec, 0xbf, 0x51, 0x2b, 0xa9, 0x21, 0xb7, 0x64, 0x87, + 0x94, 0xd4, 0x83, 0x91, 0xa1, 0x4f, 0x7b, 0x94, 0xd0, 0xf0, 0x1d, 0x59, + 0xdb, 0x98, 0xc4, 0xad, 0xa0, 0x49, 0x46, 0x1b, 0x81, 0x47, 0x4a, 0x8d, + 0x2a, 0xe0, 0x74, 0xdc, 0x82, 0x1c, 0x55, 0xd2, 0x56, 0x89, 0xc0, 0x16, + 0xdd, 0x19, 0x7b, 0xd7, 0x10, 0x5a, 0x57, 0xbc, 0xaa, 0xec, 0x7c, 0x31, + 0x83, 0x54, 0xed, 0x11, 0xef, 0x20, 0x5e, 0x05, 0x97, 0x88, 0xb8, 0xaf, + 0x85, 0x45, 0x28, 0x45, 0xa8, 0x46, 0x04, 0x55, 0xdd, 0xf8, 0x21, 0x69, + 0xd4, 0xc4, 0x7a, 0x8c, 0x4b, 0x0b, 0xd6, 0x0c, 0x18, 0xcc, 0x38, 0x97, + 0x02, 0x05, 0xca, 0x14, 0xd7, 0x31, 0x0a, 0xb8, 0x08, 0xee, 0x86, 0x2f, + 0x61, 0x5a, 0xc5, 0x2b, 0xa3, 0x54, 0x5d, 0x72, 0x8e, 0x97, 0xfa, 0x9c, + 0x18, 0x11, 0x37, 0xd5, 0x21, 0x6c, 0x0a, 0x55, 0xfb, 0xba, 0x30, 0x74, + 0xbd, 0xf7, 0xf7, 0x16, 0x98, 0x70, 0xac, 0xd3, 0x97, 0x35, 0xbc, 0xa9, + 0x0a, 0x36, 0x04, 0x09, 0x93, 0xd0, 0xcb, 0xc3, 0x51, 0xc0, 0x9a, 0x8b, + 0x0d, 0x01, 0xd4, 0xe8, 0xc4, 0x28, 0x5e, 0x75, 0xf9, 0x11, 0xec, 0xaa, + 0x74, 0x60, 0x10, 0xaa, 0xd8, 0x3f, 0x12, 0xe5, 0x03, 0xe6, 0x30, 0x96, + 0x08, 0x29, 0xbe, 0x5b, 0x95, 0x7a, 0x99, 0xa3, 0x79, 0x94, 0xad, 0x36, + 0x96, 0x2e, 0x73, 0xf1, 0x0f, 0xdc, 0xc1, 0xec, 0xac, 0x76, 0xa9, 0x76, + 0xf4, 0x4a, 0x5a, 0xb3, 0xad, 0x2c, 0x9a, 0xcb, 0x97, 0x52, 0xea, 0x5d, + 0xbd, 0x6c, 0x4d, 0x14, 0x63, 0x9b, 0x62, 0x08, 0xbd, 0xae, 0xc2, 0x18, + 0xdd, 0x16, 0xbd, 0xdd, 0x88, 0x0f, 0xe9, 0x3b, 0xa7, 0x2c, 0x43, 0xcb, + 0x7a, 0xa6, 0xee, 0x61, 0x6d, 0x6f, 0x2d, 0xed, 0x11, 0x16, 0xeb, 0xd6, + 0x64, 0xd4, 0x0d, 0xd8, 0xd8, 0x6e, 0xad, 0xd0, 0x3c, 0x90, 0xae, 0xa5, + 0xa5, 0x36, 0x1a, 0xe7, 0x5f, 0x12, 0xa5, 0x12, 0xc9, 0x81, 0x6d, 0x58, + 0x63, 0x48, 0x2a, 0x4a, 0x94, 0xa8, 0xb5, 0x9b, 0xf5, 0x79, 0x83, 0x02, + 0xe0, 0x6c, 0x5f, 0x19, 0x8a, 0xec, 0xa1, 0x4b, 0x6e, 0xf7, 0x98, 0xad, + 0xcb, 0xf7, 0x45, 0x12, 0xe3, 0x2c, 0x06, 0xb8, 0x16, 0x79, 0x64, 0xf7, + 0x4c, 0xd7, 0xa6, 0x27, 0x23, 0x34, 0x8b, 0x47, 0xbc, 0xf2, 0xea, 0x92, + 0x1e, 0x4b, 0x8f, 0xc5, 0xc0, 0x45, 0x53, 0xb9, 0x1c, 0xbe, 0xac, 0x17, + 0xef, 0x06, 0x8d, 0x10, 0xd9, 0xdf, 0xda, 0x10, 0xa6, 0x6f, 0x2b, 0x47, + 0x95, 0x85, 0x3a, 0xa6, 0x26, 0x8c, 0x37, 0x11, 0xba, 0x33, 0x0b, 0xb8, + 0x8c, 0x09, 0x89, 0x77, 0x75, 0x13, 0xef, 0x91, 0x42, 0xb8, 0xbd, 0x2b, + 0xa2, 0x84, 0x11, 0x5f, 0x5f, 0x21, 0xa8, 0xed, 0x48, 0x23, 0x08, 0x8f, + 0x11, 0x62, 0x81, 0x88, 0xc5, 0x7a, 0x40, 0x9d, 0x3f, 0x5f, 0x03, 0x68, + 0x66, 0x4e, 0x90, 0xd7, 0x60, 0xfa, 0x8b, 0x2d, 0x96, 0x91, 0x45, 0x94, + 0xa0, 0x51, 0x80, 0x86, 0xd9, 0x53, 0x88, 0x06, 0x99, 0x2a, 0xb7, 0x89, + 0x83, 0x01, 0x48, 0xd7, 0x5a, 0x77, 0xd3, 0xb5, 0xf3, 0x29, 0x50, 0x0e, + 0xd1, 0xae, 0xb3, 0xa0, 0x66, 0x4c, 0x9b, 0x44, 0x4d, 0xd3, 0xf9, 0x96, + 0x6d, 0x2d, 0x82, 0xe8, 0xc6, 0x62, 0x36, 0xee, 0xe3, 0xee, 0x47, 0x86, + 0x8d, 0x8d, 0x3b, 0x0a, 0x73, 0xd6, 0x04, 0x14, 0x5c, 0x56, 0xc0, 0xea, + 0xbc, 0xe1, 0xe2, 0x18, 0x84, 0xd6, 0x69, 0xb8, 0xed, 0x18, 0x5d, 0x6b, + 0x98, 0xd9, 0xa2, 0xd3, 0x52, 0xa5, 0x26, 0xcd, 0x93, 0x57, 0xf7, 0x20, + 0x83, 0x8f, 0x91, 0x37, 0x80, 0x9c, 0xfb, 0x4c, 0x03, 0x35, 0x2d, 0x0b, + 0x8b, 0xbd, 0x6d, 0xcb, 0xae, 0xfe, 0x51, 0xff, 0x00, 0x91, 0x73, 0x01, + 0x80, 0xd2, 0x5e, 0x5d, 0x86, 0xc3, 0x48, 0x30, 0x5d, 0xef, 0x82, 0x3b, + 0xad, 0x12, 0x29, 0xbb, 0x9c, 0xc6, 0x4d, 0x47, 0x4c, 0x25, 0xf4, 0x57, + 0x59, 0xa3, 0x88, 0x8e, 0xd0, 0x40, 0xa2, 0xfa, 0x4c, 0x5f, 0x50, 0xd0, + 0x25, 0x1e, 0xa6, 0x42, 0xb7, 0xb9, 0xa1, 0x08, 0x85, 0x19, 0x0f, 0xe1, + 0x7a, 0xc2, 0x6d, 0x44, 0xb4, 0xdc, 0x03, 0xde, 0x2f, 0x53, 0xe2, 0x74, + 0xb0, 0xb3, 0x67, 0x98, 0x17, 0x57, 0xbc, 0x1b, 0xfb, 0x41, 0x01, 0x09, + 0xc3, 0x98, 0xa8, 0x4b, 0x0d, 0x8b, 0x45, 0xd5, 0xb4, 0xce, 0x8b, 0x40, + 0x57, 0xbb, 0xa4, 0x32, 0xec, 0x1d, 0x11, 0xb1, 0xf3, 0x08, 0xb9, 0x6a, + 0x8c, 0x1c, 0xc2, 0x28, 0xa4, 0x0e, 0xf9, 0x61, 0x72, 0x2f, 0x6c, 0x7a, + 0x5a, 0xb3, 0x57, 0x59, 0x02, 0xff, 0x00, 0x78, 0x87, 0x35, 0x55, 0xa7, + 0xdc, 0x5b, 0x7a, 0x2f, 0x79, 0x72, 0xfd, 0x16, 0x23, 0x3e, 0xb6, 0x1f, + 0x89, 0x40, 0x42, 0xa7, 0x18, 0xe7, 0x78, 0x48, 0x29, 0xb1, 0x8d, 0x61, + 0xcb, 0x65, 0xd7, 0xe2, 0x28, 0x88, 0x02, 0x9d, 0x3a, 0x10, 0x16, 0x5f, + 0x15, 0xb1, 0x12, 0xbb, 0x72, 0xb8, 0x96, 0x2d, 0x7a, 0xb0, 0x44, 0x46, + 0x41, 0xd6, 0x01, 0x38, 0xc6, 0x58, 0x8b, 0x36, 0x10, 0x8e, 0x88, 0xb1, + 0x3a, 0x4b, 0xa0, 0xed, 0x29, 0x30, 0xd0, 0x06, 0x03, 0xde, 0xf4, 0x8a, + 0xad, 0x43, 0xa8, 0x3f, 0x0c, 0x42, 0xc4, 0x80, 0x55, 0x4f, 0x2c, 0x25, + 0x28, 0xf4, 0x3f, 0x51, 0x4b, 0x96, 0xe0, 0x8b, 0xc2, 0x6f, 0x7d, 0x33, + 0x17, 0x5c, 0xca, 0x5a, 0xd3, 0x91, 0x3d, 0x98, 0x97, 0xd8, 0xd2, 0xca, + 0x1b, 0xe8, 0x5b, 0xd5, 0x89, 0x5b, 0x19, 0xe8, 0x0f, 0x05, 0x11, 0xe5, + 0xb4, 0xcd, 0x3a, 0x17, 0x7e, 0x6e, 0x30, 0x94, 0xe3, 0xf0, 0x8b, 0xd9, + 0x8d, 0xa0, 0x46, 0x45, 0x30, 0x64, 0x11, 0x19, 0x4b, 0xbb, 0x8c, 0x3e, + 0x8b, 0x32, 0xd2, 0xd5, 0x12, 0x42, 0x6a, 0x6f, 0x11, 0xc9, 0x1d, 0xb0, + 0xf3, 0x1d, 0x70, 0x77, 0x66, 0x37, 0x62, 0x54, 0xac, 0x43, 0x70, 0x37, + 0xc4, 0x27, 0xce, 0x14, 0xfb, 0x4d, 0x31, 0xac, 0xb7, 0xd4, 0x8c, 0x3d, + 0x3d, 0x21, 0x32, 0x7a, 0x58, 0xf8, 0xbe, 0xa2, 0xcc, 0xb8, 0xc5, 0x88, + 0xf0, 0xc5, 0x80, 0x2d, 0xe8, 0xca, 0xa1, 0xc5, 0x0c, 0xfc, 0x25, 0x56, + 0x34, 0x10, 0x30, 0x74, 0x20, 0x32, 0x01, 0xd8, 0x8b, 0xd5, 0xa9, 0x07, + 0x11, 0x0e, 0x69, 0x8e, 0xd5, 0x3d, 0xa6, 0x51, 0x4b, 0xc2, 0xa1, 0x04, + 0x1d, 0x92, 0xc7, 0xa9, 0xd2, 0xe9, 0x77, 0x16, 0x89, 0xb4, 0x74, 0x14, + 0x7e, 0x57, 0x1b, 0x81, 0x66, 0xb4, 0x1e, 0xd1, 0xea, 0xf9, 0x74, 0xd1, + 0x65, 0x8d, 0xee, 0x9b, 0x42, 0xc9, 0x5b, 0x98, 0x6a, 0x72, 0x9b, 0xd8, + 0x39, 0xe8, 0xf5, 0x9a, 0xaa, 0x86, 0xab, 0x59, 0x6a, 0x77, 0x89, 0x52, + 0xf4, 0x4d, 0x55, 0xe7, 0x59, 0xd1, 0x35, 0xf6, 0xfe, 0x7d, 0x03, 0xe8, + 0xc4, 0x58, 0xac, 0xcb, 0xa6, 0xdf, 0xaa, 0x54, 0x71, 0x86, 0x21, 0x7c, + 0x3a, 0x63, 0x31, 0x58, 0x04, 0x06, 0x87, 0x28, 0x2e, 0x74, 0x2c, 0x5c, + 0x10, 0xd5, 0xc1, 0x05, 0x7d, 0xb1, 0x3e, 0x7f, 0x51, 0xe6, 0xf3, 0x6e, + 0x13, 0xf2, 0xf9, 0x82, 0xd0, 0x03, 0x80, 0x8f, 0x54, 0xb6, 0x32, 0xb7, + 0xbc, 0xf3, 0x2b, 0xac, 0xc7, 0x30, 0xae, 0x60, 0x10, 0x24, 0x72, 0x9a, + 0xe0, 0x32, 0xd2, 0xbc, 0x86, 0xfa, 0x45, 0x19, 0xcd, 0x94, 0x0f, 0xc4, + 0x6b, 0xba, 0x70, 0x3e, 0xef, 0xdc, 0xa3, 0x0d, 0xca, 0x0a, 0xd7, 0x50, + 0xcc, 0x08, 0x98, 0x53, 0x46, 0x02, 0x2b, 0x75, 0x35, 0xb5, 0xbd, 0x8c, + 0xe2, 0x4b, 0x67, 0xbb, 0x1c, 0xb0, 0x65, 0xcb, 0x98, 0x43, 0xd0, 0x52, + 0xdd, 0x52, 0xaf, 0x04, 0x45, 0xd0, 0x19, 0x07, 0x56, 0x77, 0x76, 0x1c, + 0x5c, 0x1d, 0x4c, 0x28, 0xa5, 0x08, 0xab, 0x67, 0xca, 0xae, 0x91, 0xd2, + 0xa4, 0x85, 0x34, 0x3c, 0xb2, 0xa9, 0x41, 0xd1, 0x6e, 0x5e, 0x3e, 0x46, + 0x63, 0x6f, 0x93, 0xac, 0x46, 0xe0, 0xeb, 0x14, 0x51, 0xca, 0x43, 0x6c, + 0xa2, 0x11, 0xc6, 0xd1, 0x51, 0xa5, 0xb5, 0x5b, 0x59, 0x8b, 0x44, 0x9c, + 0x84, 0x6b, 0x2d, 0x41, 0xf8, 0x21, 0x8b, 0x06, 0xa3, 0x30, 0xc6, 0xdc, + 0x26, 0xce, 0xd9, 0xeb, 0x07, 0x87, 0x24, 0x11, 0x64, 0x2e, 0xb7, 0x82, + 0xb8, 0x6a, 0x53, 0x83, 0x10, 0x03, 0xd9, 0x93, 0xea, 0x04, 0x04, 0xee, + 0xc1, 0xd1, 0xa0, 0xed, 0x12, 0x82, 0x2b, 0x50, 0xd2, 0x0f, 0xb5, 0x12, + 0xf5, 0x80, 0xc7, 0xd0, 0x01, 0xac, 0xa5, 0x02, 0x0b, 0xee, 0x3e, 0xbc, + 0x93, 0x2e, 0xbe, 0xa3, 0x90, 0xd1, 0xeb, 0xcb, 0xb1, 0x39, 0xa9, 0x42, + 0x9f, 0x12, 0x83, 0x88, 0xb5, 0x70, 0xc9, 0xae, 0x8a, 0xfa, 0xca, 0x9d, + 0x26, 0x14, 0x1d, 0x03, 0xcf, 0xe2, 0x33, 0x1e, 0x3b, 0x69, 0xaa, 0xd2, + 0x1f, 0xd5, 0x1a, 0x5b, 0x75, 0xe9, 0x30, 0x2e, 0x5d, 0x04, 0x16, 0x1b, + 0xa8, 0xbf, 0x86, 0x7c, 0xe5, 0x17, 0xcc, 0x40, 0xb2, 0x99, 0xa6, 0x1b, + 0xed, 0x32, 0xcb, 0xfd, 0x2c, 0x51, 0x0d, 0xa0, 0xf8, 0x3e, 0xbd, 0x0c, + 0x5f, 0x46, 0x23, 0x29, 0xd1, 0x27, 0x13, 0xba, 0x5d, 0x53, 0xf4, 0x07, + 0xce, 0x21, 0xd2, 0x8e, 0x9a, 0xa7, 0xb9, 0x88, 0x20, 0x23, 0xe0, 0xb1, + 0x10, 0x9d, 0xe2, 0x4a, 0x28, 0xb9, 0x47, 0x7e, 0x36, 0x7d, 0x41, 0xc9, + 0x39, 0x5f, 0xb4, 0xad, 0x65, 0x0d, 0xc8, 0x90, 0xa6, 0x90, 0x64, 0x4c, + 0x24, 0x10, 0x24, 0xb5, 0xbd, 0xe6, 0x7c, 0xc6, 0xe7, 0x11, 0x5c, 0xbf, + 0x54, 0x05, 0xf6, 0x6f, 0xe2, 0x1d, 0xa2, 0x30, 0xfa, 0x87, 0x54, 0x97, + 0x01, 0xaf, 0x24, 0x60, 0x2d, 0x5a, 0x3f, 0x00, 0xd4, 0xc7, 0x5d, 0xdd, + 0xb7, 0xdc, 0x9a, 0x6f, 0xd6, 0xf0, 0x0c, 0x23, 0xd4, 0x48, 0x52, 0x0e, + 0x84, 0xe8, 0x26, 0xa8, 0xb2, 0xe2, 0xa5, 0xdc, 0x78, 0x47, 0x88, 0xc9, + 0xa7, 0xbc, 0x21, 0xae, 0x3a, 0xcb, 0x90, 0x31, 0xd6, 0x71, 0x68, 0x01, + 0x97, 0xa4, 0x22, 0xcf, 0xd8, 0x1f, 0x2c, 0x7a, 0x8e, 0xe6, 0xc7, 0xd8, + 0xfd, 0xc3, 0xa8, 0xb5, 0xe0, 0xdb, 0xd4, 0x32, 0xca, 0xb2, 0x47, 0x0d, + 0x1d, 0x41, 0xd3, 0xda, 0x57, 0x5d, 0x78, 0xbc, 0xc2, 0x4e, 0xa8, 0xbd, + 0xaa, 0x60, 0xae, 0x35, 0xb0, 0x50, 0x17, 0xcc, 0x59, 0x61, 0x8a, 0x50, + 0x34, 0xb0, 0xe3, 0x11, 0x3e, 0x98, 0x12, 0x91, 0xaf, 0x05, 0xeb, 0x58, + 0x85, 0x8b, 0xb8, 0x73, 0xa0, 0xd6, 0x85, 0x58, 0x96, 0xee, 0xf4, 0x3f, + 0x32, 0xdd, 0x4f, 0xa1, 0x70, 0x8a, 0xfa, 0x58, 0x4f, 0x33, 0xaf, 0x13, + 0x31, 0x26, 0x68, 0x01, 0xc2, 0x4c, 0x36, 0x97, 0x6b, 0xa7, 0xb3, 0xf8, + 0x80, 0x20, 0x7b, 0xe0, 0x5f, 0x0f, 0xee, 0x02, 0xab, 0x76, 0xe8, 0xd3, + 0xdf, 0x4f, 0x99, 0x42, 0xd0, 0x38, 0xbd, 0xc8, 0x8b, 0xa1, 0x89, 0x4f, + 0x10, 0x33, 0x2a, 0xe3, 0x69, 0x55, 0x1c, 0x10, 0x64, 0xb3, 0x5f, 0x4c, + 0x13, 0x20, 0xf6, 0x34, 0x9d, 0xdd, 0xe2, 0xd2, 0x96, 0x34, 0x25, 0x0f, + 0x13, 0xa1, 0x0e, 0x08, 0x52, 0xe0, 0x40, 0x80, 0x2b, 0xb2, 0xe2, 0xdd, + 0x60, 0x41, 0x83, 0xa4, 0xd5, 0x09, 0x50, 0x96, 0xd0, 0x83, 0x39, 0xf5, + 0x54, 0x5e, 0xc4, 0x45, 0x14, 0x72, 0x80, 0xb3, 0xa2, 0x8b, 0xf7, 0x8e, + 0x55, 0xe4, 0x01, 0x45, 0x7d, 0xb4, 0x80, 0x4b, 0x4b, 0x34, 0x60, 0x7c, + 0x40, 0x94, 0x20, 0x0d, 0x1a, 0x71, 0x89, 0x71, 0x73, 0x08, 0xd0, 0x07, + 0x35, 0xd2, 0x37, 0xb4, 0x96, 0x80, 0x16, 0x90, 0xdd, 0x1d, 0x25, 0x59, + 0x29, 0xd1, 0xcc, 0x14, 0x8c, 0x04, 0x1a, 0x16, 0x83, 0x16, 0x63, 0x9f, + 0xcf, 0x31, 0xdc, 0x4b, 0x2c, 0x00, 0x34, 0x09, 0x5d, 0x96, 0x52, 0x3c, + 0x30, 0xb7, 0xe2, 0x08, 0x34, 0x1c, 0x8f, 0x83, 0x10, 0xeb, 0x1c, 0x06, + 0x88, 0x77, 0xb1, 0xea, 0xc7, 0xa2, 0xed, 0x2a, 0xd9, 0xef, 0x2f, 0xa5, + 0x8e, 0x70, 0xff, 0x00, 0xe0, 0x04, 0xac, 0xac, 0x8e, 0x8c, 0xfd, 0xd4, + 0x22, 0x81, 0xe6, 0x06, 0xe9, 0x6b, 0x2c, 0x40, 0x96, 0x2d, 0x83, 0x5a, + 0x2b, 0xaf, 0x88, 0x23, 0x96, 0xc7, 0x41, 0xe6, 0x2d, 0x62, 0x35, 0xc4, + 0xc1, 0x4c, 0xa0, 0xea, 0x18, 0xf7, 0xa0, 0x94, 0x20, 0x9f, 0xd6, 0x93, + 0x3d, 0x51, 0xd7, 0xf1, 0x30, 0x1c, 0xd7, 0xb9, 0xf5, 0x73, 0x4e, 0xff, + 0x00, 0xc3, 0x58, 0x12, 0xfb, 0x78, 0xfa, 0xce, 0x01, 0xc2, 0x7d, 0x45, + 0x16, 0x2c, 0x51, 0x65, 0x1b, 0x40, 0x34, 0x50, 0x72, 0xde, 0xba, 0xce, + 0xb8, 0x01, 0x5b, 0x19, 0x27, 0x01, 0x4c, 0xa3, 0x20, 0xb5, 0x00, 0xe5, + 0xbc, 0x7c, 0xc6, 0x54, 0xea, 0x7a, 0x0a, 0xa5, 0xe8, 0x36, 0xb3, 0x0d, + 0xd1, 0x11, 0x81, 0xe1, 0xe1, 0xef, 0x06, 0x2a, 0x86, 0x92, 0xa0, 0x40, + 0xa8, 0x86, 0x8b, 0x29, 0x34, 0x5c, 0xa7, 0xd9, 0x3f, 0xbc, 0x87, 0x42, + 0x1b, 0xe5, 0xdf, 0xee, 0x20, 0xf6, 0xcb, 0x3f, 0x31, 0x99, 0x17, 0x5a, + 0x68, 0x74, 0x9a, 0xa3, 0xe8, 0xcb, 0x9a, 0x10, 0x2d, 0x9b, 0x41, 0xd6, + 0xf1, 0xb8, 0x77, 0x04, 0xa8, 0xeb, 0x4e, 0xbe, 0x20, 0x61, 0xa7, 0x41, + 0x0b, 0xe1, 0x97, 0x97, 0x8f, 0x6a, 0x0e, 0x85, 0x15, 0x00, 0x3a, 0xff, + 0x00, 0xfd, 0x08, 0x84, 0xd2, 0xa0, 0x57, 0xa3, 0x92, 0x78, 0x82, 0x5d, + 0x80, 0x3a, 0x82, 0xe0, 0xf6, 0x8a, 0x0f, 0xca, 0x06, 0x59, 0x7c, 0xc5, + 0xa7, 0x65, 0x30, 0x87, 0x34, 0x1c, 0x24, 0xb2, 0x50, 0xb2, 0xe8, 0x00, + 0x29, 0x1d, 0xaf, 0xcb, 0x11, 0x31, 0x0d, 0xe4, 0x54, 0x00, 0xb4, 0xe3, + 0x57, 0xbd, 0x4b, 0xee, 0xe3, 0x2b, 0x45, 0xc5, 0x6a, 0x38, 0x05, 0x8b, + 0xa2, 0xee, 0x64, 0xd4, 0x2d, 0xd5, 0x02, 0xfc, 0x88, 0x03, 0x51, 0xf8, + 0x7f, 0x70, 0x5d, 0xf3, 0x44, 0x2f, 0x42, 0xa5, 0x5a, 0x67, 0xaa, 0x7e, + 0xa6, 0x93, 0xd8, 0x92, 0xd8, 0xd3, 0xc0, 0xd4, 0x6a, 0xac, 0x4d, 0x4a, + 0x30, 0x8d, 0x83, 0x0a, 0xe6, 0xe5, 0xa6, 0xb0, 0xda, 0x83, 0xcc, 0xd5, + 0xbd, 0xf9, 0x5d, 0x64, 0xd8, 0x2c, 0x5a, 0xb4, 0x4b, 0xe4, 0xaf, 0x48, + 0x09, 0x02, 0xcd, 0x04, 0x4c, 0xc3, 0x28, 0xef, 0x31, 0x1f, 0x47, 0x46, + 0x3a, 0x8a, 0x1c, 0xe1, 0xf7, 0x70, 0x80, 0x77, 0xab, 0xf6, 0x13, 0x99, + 0xdd, 0xd3, 0xf3, 0x00, 0xc9, 0x7a, 0x09, 0xa1, 0x97, 0xb3, 0x0f, 0x52, + 0x59, 0xd0, 0x60, 0x15, 0x84, 0x4a, 0x06, 0x1d, 0x22, 0xa2, 0x0d, 0xd5, + 0x67, 0x88, 0xd5, 0x0d, 0xca, 0x6b, 0xd9, 0x02, 0x2c, 0x5e, 0x84, 0x22, + 0x9d, 0x47, 0x98, 0xa1, 0x8d, 0x93, 0x92, 0x07, 0x50, 0xb9, 0x73, 0xd2, + 0x13, 0x00, 0x28, 0x08, 0xcb, 0xec, 0xfe, 0x50, 0xbe, 0x1f, 0x15, 0x06, + 0x52, 0xc1, 0x50, 0xbb, 0xe7, 0x05, 0xe1, 0xcf, 0x68, 0xf1, 0x06, 0x10, + 0x3d, 0x94, 0x80, 0xb4, 0xf8, 0x58, 0xa6, 0x8d, 0x0c, 0xb0, 0xe5, 0x5c, + 0xd3, 0xbf, 0x58, 0xa6, 0xf1, 0x6d, 0x45, 0xe6, 0x28, 0xdd, 0x0e, 0x04, + 0x76, 0xae, 0xc6, 0x1a, 0x51, 0xe2, 0x55, 0x10, 0xd9, 0x22, 0xfa, 0x5c, + 0xbb, 0x89, 0x05, 0xb2, 0xfe, 0xfb, 0xeb, 0x49, 0x15, 0xa7, 0x7a, 0x2e, + 0x3c, 0x59, 0x1c, 0xb9, 0x50, 0xb3, 0xe1, 0x82, 0x06, 0x80, 0x5a, 0x7f, + 0x01, 0xf2, 0x31, 0xd0, 0x21, 0xab, 0x8d, 0xc6, 0xb1, 0x63, 0xf8, 0xf4, + 0x35, 0x8d, 0x17, 0x1a, 0x90, 0x79, 0x70, 0x56, 0x08, 0xda, 0x3b, 0x97, + 0x0b, 0x32, 0x37, 0x30, 0x40, 0x97, 0x8e, 0x39, 0xbd, 0x47, 0x03, 0xb6, + 0x22, 0x2a, 0xc3, 0xdf, 0x4b, 0x3a, 0x73, 0x29, 0x6b, 0x2a, 0x7a, 0x44, + 0x11, 0x2c, 0xc1, 0x32, 0x25, 0xd8, 0x70, 0x4e, 0x66, 0x31, 0xac, 0xb2, + 0xc0, 0x80, 0xb4, 0x88, 0x8e, 0xa4, 0xdb, 0x0e, 0xf3, 0x1d, 0x67, 0x56, + 0x00, 0x1d, 0x6c, 0x5b, 0x1e, 0x49, 0xa3, 0x01, 0xbe, 0x9b, 0x48, 0xe6, + 0xbe, 0xb0, 0x43, 0xd2, 0xfd, 0x2e, 0x77, 0x4c, 0x73, 0x3a, 0xd4, 0xc1, + 0x18, 0xc6, 0x2e, 0x3c, 0xc6, 0x4a, 0xf1, 0x1d, 0x4a, 0x77, 0x83, 0x7c, + 0xe2, 0x54, 0x3a, 0x5b, 0xd0, 0x88, 0x69, 0xba, 0x31, 0xe4, 0x56, 0xf8, + 0x7b, 0x5c, 0x0d, 0x28, 0x44, 0xd6, 0x32, 0xec, 0x02, 0x4d, 0x3d, 0xf6, + 0x98, 0x5d, 0x3a, 0x98, 0xfb, 0xb4, 0x82, 0x95, 0x47, 0x86, 0x12, 0xad, + 0x79, 0x87, 0x4b, 0x8d, 0x6d, 0x3d, 0xe6, 0xa4, 0x26, 0x9a, 0x9e, 0xf0, + 0x47, 0x10, 0x66, 0x65, 0x2d, 0xfe, 0xa5, 0xe0, 0xe4, 0xc3, 0xaa, 0x02, + 0x54, 0xe2, 0x05, 0x6d, 0xb6, 0xb4, 0xd4, 0xd6, 0x1b, 0xdd, 0x97, 0x6f, + 0x01, 0xe0, 0x42, 0xc3, 0x3a, 0xc5, 0x64, 0x9b, 0x14, 0xc1, 0x29, 0x7b, + 0xe9, 0x51, 0xc6, 0x82, 0xd0, 0x0a, 0x3b, 0x98, 0x96, 0x6a, 0x2b, 0x9a, + 0xc0, 0xf4, 0x3d, 0xa6, 0xbe, 0xac, 0x63, 0x7b, 0x7e, 0x58, 0x86, 0x6b, + 0x41, 0xf1, 0x35, 0x7f, 0xd8, 0x46, 0x63, 0xd9, 0x11, 0x7c, 0x27, 0x98, + 0x7d, 0x6a, 0x22, 0xec, 0x3b, 0x64, 0x5a, 0xf2, 0x9a, 0x28, 0x53, 0xde, + 0x10, 0xfb, 0xc0, 0x80, 0x44, 0xc6, 0x75, 0x56, 0xdf, 0x67, 0xea, 0x53, + 0x8e, 0x65, 0x10, 0x4e, 0xfa, 0x9f, 0x68, 0xea, 0x6a, 0xef, 0xfe, 0x71, + 0x38, 0x9b, 0x7e, 0xbd, 0x4f, 0xa9, 0x42, 0x11, 0xb6, 0x4b, 0x5d, 0x68, + 0xb8, 0x96, 0xbb, 0x7a, 0xbb, 0x5e, 0x6b, 0xab, 0xb4, 0x04, 0xa0, 0x36, + 0x09, 0xa2, 0xca, 0x7f, 0x32, 0xfe, 0xab, 0x9a, 0x6c, 0x7e, 0x9e, 0x1f, + 0x11, 0x1f, 0x7e, 0xc8, 0xef, 0xff, 0x00, 0x28, 0x9b, 0x7b, 0x0e, 0xeb, + 0xb0, 0xb3, 0xc9, 0xe6, 0x68, 0x24, 0x81, 0x7c, 0x51, 0x9a, 0xb0, 0xd8, + 0x5c, 0xbf, 0xd1, 0x62, 0xa8, 0x38, 0x4b, 0xf4, 0xac, 0xca, 0x84, 0x66, + 0x83, 0x48, 0x57, 0x22, 0xf8, 0x8f, 0xab, 0xfc, 0x2a, 0x12, 0x0d, 0x97, + 0xfe, 0x11, 0x70, 0x2f, 0xea, 0x5f, 0xdc, 0xa3, 0x40, 0x3a, 0x04, 0xb9, + 0xde, 0x5d, 0xcc, 0x0a, 0xe3, 0xbb, 0x6e, 0xb9, 0xab, 0xfb, 0x0f, 0x90, + 0x8b, 0x83, 0x64, 0xa3, 0x66, 0xe6, 0x66, 0x92, 0x88, 0xd6, 0xc3, 0x0e, + 0x3e, 0x62, 0xa0, 0x97, 0xec, 0xc7, 0x02, 0x44, 0x08, 0x80, 0x68, 0xf7, + 0x89, 0x70, 0xc0, 0x73, 0x33, 0x41, 0x35, 0x63, 0x59, 0x56, 0x84, 0x2c, + 0x30, 0xd7, 0x48, 0x93, 0x41, 0x5a, 0x1a, 0x7e, 0x62, 0xef, 0xbd, 0x6b, + 0xde, 0x6a, 0xac, 0x39, 0x9f, 0xee, 0x40, 0x18, 0x0f, 0x99, 0x51, 0x0c, + 0xb8, 0x32, 0xb2, 0xd8, 0x65, 0xe6, 0x6a, 0x44, 0x5c, 0x5e, 0x3b, 0xcd, + 0x99, 0x84, 0xaa, 0x10, 0x28, 0xb1, 0x6f, 0x22, 0x98, 0xc1, 0x38, 0x16, + 0x7b, 0xcd, 0xe8, 0x63, 0x71, 0x71, 0xa6, 0xd1, 0xa6, 0xd0, 0x50, 0x2c, + 0x20, 0xff, 0x00, 0xc0, 0x2c, 0x35, 0x70, 0x33, 0x5b, 0x18, 0xc4, 0x8c, + 0xd2, 0x64, 0xf4, 0x33, 0x29, 0x94, 0x74, 0x4b, 0xaf, 0x36, 0xd1, 0x7a, + 0x44, 0x34, 0x74, 0x96, 0xb6, 0xb4, 0xc5, 0x9e, 0x68, 0x02, 0x05, 0x94, + 0x08, 0x47, 0x02, 0x71, 0x18, 0xa5, 0x72, 0xab, 0x34, 0x5c, 0x61, 0x68, + 0x9a, 0x00, 0xc5, 0xf4, 0xc6, 0xea, 0x44, 0xa9, 0x23, 0x99, 0x3e, 0x22, + 0x1d, 0x8c, 0xd1, 0xf6, 0x61, 0x6a, 0xec, 0x72, 0x31, 0x49, 0x7e, 0x3e, + 0xf0, 0x5a, 0xcc, 0x76, 0xac, 0xe5, 0xc3, 0x9a, 0x17, 0x65, 0x97, 0xe9, + 0x0f, 0x02, 0x57, 0xd7, 0xb4, 0xa7, 0x7a, 0x95, 0xac, 0x92, 0xf6, 0xa3, + 0x49, 0xfe, 0x45, 0x5e, 0xf1, 0xe5, 0x99, 0x85, 0x63, 0xdc, 0xdd, 0x66, + 0xfe, 0x86, 0xbe, 0x8e, 0x66, 0xd1, 0xd2, 0x15, 0x00, 0x2e, 0x05, 0xe6, + 0x50, 0xcf, 0xb9, 0x16, 0xca, 0x7a, 0x5c, 0x7a, 0xe2, 0xd8, 0xa7, 0x78, + 0xbd, 0x63, 0x5c, 0xca, 0x0a, 0xca, 0x6b, 0x97, 0x8d, 0x46, 0xa5, 0xf0, + 0x7c, 0xc2, 0x98, 0x1e, 0x77, 0x2d, 0xd6, 0x51, 0xa4, 0x4e, 0x55, 0x08, + 0xa9, 0x65, 0x5e, 0x1d, 0xa1, 0x6e, 0x01, 0x69, 0x39, 0x5a, 0x6b, 0x29, + 0x53, 0x90, 0x61, 0xf6, 0xff, 0x00, 0xb0, 0x8f, 0x28, 0x1e, 0x84, 0xe4, + 0xa9, 0xac, 0xbd, 0x6b, 0x0f, 0x92, 0x3d, 0x74, 0x61, 0xd1, 0xf6, 0x3a, + 0x9f, 0x50, 0x3a, 0x69, 0x6b, 0x03, 0xf8, 0xb3, 0x6f, 0x66, 0x31, 0xc3, + 0x19, 0x6b, 0xfe, 0x50, 0x6c, 0x42, 0x05, 0xc2, 0xe0, 0x66, 0x11, 0x9e, + 0x60, 0x7a, 0xfe, 0x89, 0x87, 0x11, 0x03, 0x40, 0x48, 0xd6, 0x0a, 0x7a, + 0x4c, 0x0f, 0x44, 0x40, 0x98, 0x8e, 0xcd, 0xea, 0x3c, 0x8e, 0x02, 0x52, + 0x39, 0x4a, 0xec, 0xfc, 0x46, 0xdc, 0x1f, 0x6d, 0xe0, 0xeb, 0xb3, 0x08, + 0x4b, 0x0e, 0x91, 0x33, 0x26, 0xed, 0x45, 0xef, 0x8d, 0x0b, 0x7b, 0x9f, + 0xa8, 0x1d, 0x96, 0xd5, 0x69, 0xfb, 0x8e, 0xdd, 0x71, 0x2b, 0x53, 0xbc, + 0xc4, 0x18, 0xa7, 0xb7, 0xe6, 0x1f, 0xa9, 0x1d, 0x3b, 0x2e, 0x8a, 0xef, + 0x69, 0x94, 0x72, 0xe9, 0x30, 0x18, 0x89, 0x88, 0x4e, 0xd0, 0x76, 0x23, + 0x76, 0xfb, 0x4b, 0x3f, 0x82, 0x18, 0x00, 0xbd, 0x80, 0x95, 0x82, 0xbd, + 0x1a, 0xc7, 0xcd, 0x5f, 0x89, 0x7c, 0x0a, 0xe4, 0x26, 0x06, 0x0a, 0x23, + 0x2f, 0xb6, 0x33, 0x7a, 0xd2, 0x35, 0x77, 0xb9, 0x30, 0xfb, 0xcd, 0x92, + 0xe8, 0x6e, 0x6b, 0x00, 0xf2, 0xa6, 0xfc, 0xef, 0x2a, 0x64, 0x6b, 0xe2, + 0x2a, 0x58, 0x8a, 0x94, 0xc5, 0x62, 0xb2, 0xa8, 0xa0, 0x5e, 0xa5, 0x45, + 0x64, 0x7d, 0x12, 0x31, 0x95, 0x32, 0xa3, 0x35, 0x89, 0x1b, 0x73, 0x05, + 0x31, 0x2c, 0x96, 0x08, 0xea, 0x60, 0xaa, 0xa1, 0xd6, 0x2a, 0xa8, 0x2d, + 0x9a, 0xa6, 0x73, 0x3a, 0x95, 0x1f, 0xb3, 0xc4, 0x6f, 0x62, 0x1d, 0x04, + 0x51, 0xdd, 0x49, 0x7d, 0xde, 0xa1, 0xc2, 0xa4, 0x01, 0x2c, 0xc3, 0xe0, + 0x4d, 0x6a, 0xa7, 0xdb, 0x2e, 0x2f, 0x45, 0x69, 0x27, 0xc9, 0xa2, 0x7e, + 0x62, 0xd4, 0x3a, 0xf6, 0x3f, 0x13, 0x9f, 0x79, 0x45, 0xad, 0x7e, 0xdf, + 0xf3, 0x14, 0xc7, 0xb1, 0x8b, 0xfb, 0xbf, 0xd0, 0x4a, 0x1b, 0x77, 0x8f, + 0xc0, 0x8d, 0xcb, 0x60, 0x69, 0xb2, 0x82, 0x2f, 0x6c, 0x4c, 0x84, 0x8e, + 0xb7, 0x17, 0xf1, 0xec, 0x41, 0xd6, 0xae, 0x40, 0xb8, 0xe8, 0x04, 0x6b, + 0xa6, 0x26, 0xf3, 0x70, 0xc2, 0x6f, 0x2a, 0xe6, 0x9e, 0x98, 0x4d, 0x71, + 0x9b, 0x46, 0xf0, 0x96, 0x5f, 0xa2, 0xfa, 0xfa, 0x2b, 0x68, 0x04, 0x85, + 0xc5, 0x53, 0x2b, 0x77, 0x4b, 0x4a, 0xd7, 0xcc, 0x76, 0xaa, 0xf9, 0x98, + 0xaa, 0xa8, 0xbd, 0x70, 0x22, 0xb0, 0x0b, 0xdc, 0x1b, 0x7d, 0x89, 0x50, + 0x09, 0xf8, 0xfb, 0x40, 0x40, 0x03, 0x40, 0x2a, 0x0c, 0x28, 0xbf, 0x70, + 0x8a, 0x29, 0xd1, 0xe6, 0x51, 0xa5, 0x5b, 0x36, 0xbe, 0x9b, 0x3e, 0x20, + 0x3a, 0x32, 0x82, 0xc4, 0x75, 0x19, 0x62, 0x7c, 0x4e, 0x5e, 0xa7, 0x6d, + 0x3b, 0x54, 0xae, 0xe2, 0xda, 0xf2, 0x72, 0x3d, 0x48, 0x69, 0x14, 0x54, + 0xcc, 0x7f, 0x42, 0x08, 0x7a, 0x1b, 0x86, 0x20, 0xf9, 0x7f, 0x44, 0xc3, + 0x46, 0x18, 0x15, 0x50, 0xc6, 0x20, 0xe2, 0xe0, 0xb0, 0x15, 0x41, 0xde, + 0x21, 0x42, 0x12, 0x26, 0x89, 0x38, 0xee, 0xc3, 0x80, 0xe1, 0xf9, 0x26, + 0xdd, 0x71, 0xb4, 0x4c, 0x43, 0xb4, 0x73, 0x25, 0x00, 0x6a, 0x63, 0x95, + 0xad, 0x24, 0x3c, 0xf5, 0x48, 0x10, 0x74, 0xcb, 0x99, 0x7d, 0x41, 0xdd, + 0x3f, 0x31, 0x1a, 0x04, 0xd8, 0x5f, 0x77, 0xf1, 0x3e, 0x63, 0xaa, 0xf7, + 0xa8, 0x7c, 0xad, 0x09, 0x84, 0xc7, 0xbc, 0x74, 0xa4, 0xf7, 0x22, 0x1d, + 0xcb, 0xbd, 0x50, 0x61, 0xdb, 0x53, 0x34, 0x73, 0xf0, 0x3e, 0xe7, 0xc4, + 0x93, 0xf8, 0x8c, 0xcf, 0x63, 0x3f, 0xa4, 0x06, 0x55, 0xe9, 0x7e, 0xd1, + 0x2b, 0x5b, 0xe5, 0x18, 0xb1, 0x07, 0x41, 0x0a, 0xe0, 0x8b, 0xda, 0x9c, + 0x1e, 0x82, 0x51, 0x1e, 0x31, 0xac, 0xce, 0x32, 0x45, 0x7d, 0x15, 0x86, + 0xe0, 0x4d, 0x93, 0x11, 0x62, 0x1a, 0x1d, 0x08, 0xed, 0x2c, 0x91, 0xdb, + 0xb3, 0xe2, 0x66, 0x74, 0x33, 0xcc, 0x3f, 0x31, 0x48, 0x0d, 0x49, 0xd0, + 0x8f, 0xc4, 0x48, 0xd5, 0x45, 0xd4, 0x30, 0xfd, 0xc0, 0xb1, 0x11, 0x1c, + 0xc1, 0x6e, 0x45, 0x29, 0x2f, 0x30, 0x41, 0xd4, 0xf0, 0x3d, 0xd8, 0xd9, + 0xaa, 0xee, 0x43, 0x84, 0xc5, 0x98, 0x13, 0x6a, 0xef, 0x2f, 0xa9, 0x78, + 0x80, 0x60, 0x82, 0x7a, 0x1a, 0x22, 0x6f, 0x88, 0x57, 0x15, 0x4a, 0x3f, + 0x10, 0xea, 0x97, 0xe8, 0xc1, 0x37, 0x41, 0xf8, 0x8f, 0xcc, 0x54, 0x4c, + 0x3b, 0x40, 0xe2, 0x28, 0xe9, 0x89, 0x4e, 0x23, 0xc1, 0x3a, 0x10, 0xb3, + 0x42, 0x02, 0xe1, 0x88, 0x43, 0x42, 0xc9, 0x87, 0x55, 0xd5, 0x2a, 0xfb, + 0x30, 0x99, 0x48, 0xbb, 0xab, 0x3d, 0xc8, 0x63, 0x88, 0xd2, 0xf3, 0x1e, + 0x0d, 0x73, 0x04, 0x25, 0x54, 0xab, 0x8e, 0x9e, 0x9a, 0x22, 0x80, 0x73, + 0x12, 0xf7, 0x88, 0x69, 0x29, 0x75, 0x88, 0x99, 0x81, 0x65, 0x54, 0xab, + 0x9a, 0xa1, 0x84, 0x2c, 0x17, 0x06, 0x57, 0xc6, 0xb3, 0x46, 0x9e, 0x15, + 0x03, 0xe3, 0xf6, 0x43, 0x41, 0x06, 0xc1, 0x53, 0xb6, 0x61, 0x01, 0x15, + 0x22, 0x9a, 0xca, 0x41, 0xc2, 0x84, 0x74, 0xa7, 0x24, 0x02, 0x8d, 0xc9, + 0x93, 0xda, 0x31, 0x16, 0xc3, 0x27, 0x0f, 0x31, 0xfe, 0xb0, 0xb7, 0x5f, + 0xf5, 0x7d, 0xcc, 0xa2, 0x4a, 0x44, 0x26, 0x09, 0x11, 0x33, 0xd2, 0x5d, + 0x50, 0x84, 0xe5, 0x68, 0x1a, 0xc4, 0x17, 0x34, 0x87, 0x5d, 0x20, 0x18, + 0x61, 0x8c, 0xc4, 0xc0, 0xd2, 0xe5, 0x3a, 0x88, 0xeb, 0x52, 0x17, 0x76, + 0x57, 0x78, 0x4b, 0x82, 0xe4, 0x41, 0xa8, 0xf5, 0x17, 0xdb, 0x44, 0xb8, + 0xdb, 0x30, 0x29, 0x9e, 0x71, 0xf3, 0x1a, 0x01, 0x39, 0xa0, 0x74, 0x9a, + 0x53, 0xc9, 0xe8, 0xb9, 0x78, 0x99, 0x92, 0xc2, 0x68, 0xc9, 0xfc, 0xbf, + 0x88, 0x98, 0x89, 0x06, 0x34, 0x89, 0xb4, 0x07, 0x62, 0x3b, 0x60, 0xf1, + 0x12, 0x38, 0x08, 0x83, 0x05, 0x41, 0x04, 0x6d, 0x28, 0x94, 0xbc, 0xbd, + 0x23, 0xf4, 0x9a, 0x2f, 0xc0, 0xf5, 0xcc, 0x30, 0xf8, 0x41, 0x4a, 0xde, + 0x54, 0x21, 0xa2, 0x17, 0xda, 0x21, 0x9c, 0x1b, 0x20, 0xc1, 0x3a, 0x31, + 0xa1, 0x72, 0xc6, 0xaa, 0xee, 0x2f, 0xf1, 0x52, 0xc3, 0xc1, 0x29, 0xf2, + 0x42, 0x6d, 0xf0, 0x7e, 0x61, 0x8f, 0x35, 0xbd, 0xc3, 0xf2, 0x4b, 0x3a, + 0x3d, 0x68, 0xfc, 0xc4, 0x91, 0x6f, 0xe1, 0xa4, 0x4b, 0x01, 0xe4, 0x27, + 0xe0, 0x89, 0xe8, 0xfc, 0x9f, 0x64, 0xdd, 0xcf, 0x3f, 0xd4, 0x63, 0xf1, + 0x91, 0x21, 0x7c, 0xbf, 0x29, 0x8f, 0xab, 0x07, 0x5f, 0xd0, 0x61, 0x87, + 0x93, 0x3f, 0x22, 0x3b, 0x37, 0x58, 0x27, 0xba, 0x73, 0xf5, 0x28, 0x2f, + 0x58, 0xf1, 0x07, 0x10, 0x62, 0xa8, 0x3e, 0x80, 0xe2, 0x5b, 0x55, 0x42, + 0x6f, 0x87, 0x0f, 0xc3, 0x09, 0x24, 0x86, 0xb9, 0x9c, 0x00, 0xd0, 0xec, + 0x60, 0x9e, 0xc9, 0x63, 0x16, 0x5d, 0x7a, 0xd7, 0x72, 0xf5, 0x98, 0x4b, + 0xeb, 0xe9, 0xca, 0x24, 0x72, 0x7f, 0xd4, 0x81, 0x80, 0x2e, 0xf5, 0x49, + 0x00, 0x6c, 0x7b, 0xdc, 0xab, 0xe0, 0x78, 0x99, 0x25, 0x4b, 0xc4, 0xa7, + 0x32, 0xcb, 0xa9, 0xab, 0x59, 0x7b, 0x33, 0xda, 0x59, 0x54, 0xa2, 0x54, + 0x17, 0x05, 0xda, 0x08, 0xc9, 0x31, 0xd6, 0x35, 0xbb, 0x34, 0x01, 0xe8, + 0x99, 0x7e, 0x97, 0xda, 0xe7, 0xcd, 0x54, 0xc0, 0xf7, 0xa8, 0x3e, 0xd7, + 0xe2, 0x6a, 0xe9, 0x70, 0x5b, 0xfc, 0x4b, 0x3e, 0x31, 0x47, 0xc5, 0x4a, + 0x71, 0xf7, 0x48, 0x09, 0x14, 0x10, 0xf4, 0x2b, 0x36, 0x8d, 0xf3, 0x1b, + 0xca, 0x23, 0x4a, 0x45, 0x5c, 0xb2, 0x5b, 0x11, 0xe6, 0x07, 0xdb, 0x3c, + 0xbe, 0xfb, 0xcd, 0x74, 0x2d, 0x5a, 0x5f, 0xfd, 0x44, 0x19, 0x91, 0xa8, + 0x66, 0x00, 0x0b, 0x5d, 0xd0, 0x3e, 0xe3, 0x58, 0x9e, 0x45, 0x7f, 0x12, + 0x93, 0xda, 0x3f, 0xdb, 0x13, 0x29, 0xb8, 0x7f, 0xe0, 0x98, 0x9f, 0xc7, + 0xb7, 0x61, 0xab, 0x5e, 0xa2, 0x10, 0x06, 0xed, 0x36, 0x4d, 0xf6, 0x9a, + 0xf0, 0xf6, 0x26, 0xe2, 0x79, 0x0f, 0xcc, 0x05, 0x07, 0xb3, 0x3e, 0xae, + 0x1d, 0xe6, 0x57, 0xe0, 0x8a, 0xd2, 0x80, 0xa4, 0x6f, 0x8c, 0xab, 0x8d, + 0xe5, 0x10, 0x4e, 0x16, 0xa3, 0x8e, 0xb1, 0xc6, 0x32, 0xda, 0x0c, 0x69, + 0xe8, 0x5b, 0x95, 0xb3, 0x0d, 0xba, 0xab, 0x06, 0x11, 0x8a, 0x59, 0x8f, + 0xae, 0xe7, 0xcc, 0x58, 0xc5, 0x18, 0x5f, 0x11, 0x62, 0xc5, 0xe8, 0x48, + 0x3c, 0x4f, 0x77, 0x79, 0x7b, 0xcf, 0xfb, 0xb7, 0xac, 0x77, 0xe8, 0x19, + 0x8d, 0x22, 0x11, 0x23, 0x2d, 0x60, 0x5e, 0xd7, 0x01, 0x50, 0x9b, 0x99, + 0x78, 0xd5, 0x43, 0x44, 0x25, 0x7b, 0xfa, 0x18, 0x65, 0x86, 0x5e, 0x99, + 0xdb, 0x03, 0xc4, 0x3a, 0x25, 0xfb, 0x4a, 0xd3, 0x07, 0xd0, 0xa0, 0xc9, + 0xd2, 0x7f, 0x2a, 0x33, 0xba, 0xab, 0x56, 0x55, 0x82, 0x84, 0x57, 0x16, + 0x1f, 0x30, 0x7d, 0x03, 0x06, 0x14, 0x13, 0x58, 0x2f, 0x6e, 0xf3, 0xbd, + 0x67, 0xe7, 0xd0, 0x4d, 0x36, 0xe7, 0x07, 0x77, 0x13, 0x13, 0x06, 0x1a, + 0x9b, 0xf5, 0x9c, 0xa6, 0xc8, 0x41, 0x6d, 0xe5, 0x22, 0x1d, 0xea, 0x27, + 0x98, 0x9e, 0x66, 0x5d, 0xa6, 0x42, 0x1b, 0x9b, 0x3d, 0xe0, 0x7e, 0x61, + 0xbf, 0x68, 0x63, 0x8d, 0x91, 0x86, 0x48, 0x9d, 0x14, 0xe0, 0x79, 0xc3, + 0xff, 0x00, 0x71, 0x3a, 0xe7, 0xca, 0x03, 0xb1, 0xee, 0xb3, 0xfb, 0x98, + 0x3d, 0x3e, 0x6c, 0x3a, 0x4e, 0xcb, 0x2d, 0x0a, 0x8e, 0x16, 0x1f, 0xe8, + 0x61, 0xa6, 0xf3, 0x4a, 0x71, 0xb8, 0x4c, 0x42, 0x3d, 0xae, 0x90, 0x0c, + 0x0f, 0x04, 0xa9, 0xa1, 0x0a, 0x4a, 0x80, 0x51, 0xbb, 0x2b, 0x01, 0x2d, + 0xc7, 0xa1, 0x8c, 0x61, 0x9a, 0x62, 0x97, 0x70, 0x1a, 0xbb, 0xb1, 0xac, + 0x2c, 0x94, 0x82, 0xfd, 0x26, 0x68, 0x8c, 0xbb, 0x25, 0xb5, 0xb2, 0x39, + 0x1e, 0xa7, 0xfd, 0x80, 0x6e, 0xc8, 0xe4, 0x77, 0x1e, 0xa4, 0xb6, 0xa5, + 0xd0, 0x71, 0x0c, 0xdb, 0xd4, 0x2a, 0x84, 0x16, 0x84, 0x11, 0x45, 0x0a, + 0x2b, 0xda, 0x08, 0x92, 0x29, 0x27, 0x2b, 0xac, 0xa8, 0xd6, 0x77, 0x7a, + 0x56, 0xf3, 0x1c, 0x21, 0x0d, 0x3b, 0xcc, 0x99, 0xdd, 0x0d, 0xdf, 0x12, + 0xc1, 0x82, 0xeb, 0x70, 0x3d, 0xff, 0x00, 0x63, 0x58, 0x08, 0x8a, 0x03, + 0x44, 0x62, 0xdc, 0x51, 0x6e, 0x2c, 0x63, 0x12, 0x30, 0xa2, 0xf2, 0xb7, + 0x96, 0x07, 0xf4, 0xef, 0xbc, 0x5e, 0x94, 0x62, 0x47, 0x75, 0x4a, 0x5c, + 0x48, 0x97, 0x15, 0x01, 0x25, 0x8d, 0xa3, 0xb9, 0x5b, 0x20, 0x51, 0xe6, + 0xa1, 0xa2, 0x04, 0x08, 0x12, 0x95, 0xff, 0x00, 0x9e, 0xc6, 0x76, 0x4b, + 0x99, 0x49, 0x08, 0x18, 0x35, 0x33, 0x47, 0x77, 0xaf, 0x07, 0x9e, 0xed, + 0x09, 0xd7, 0x90, 0xac, 0xa4, 0x45, 0x1c, 0xbb, 0x83, 0x98, 0x40, 0xc2, + 0x0c, 0x22, 0xe6, 0x16, 0x9c, 0x03, 0xab, 0xfe, 0xdf, 0xbc, 0xbf, 0x46, + 0x34, 0xea, 0xfd, 0x53, 0x13, 0x08, 0x1c, 0xf4, 0x97, 0xe8, 0x63, 0xac, + 0x65, 0x84, 0xbe, 0xb1, 0x8b, 0x97, 0x88, 0xb0, 0x89, 0x2c, 0x6c, 0xc2, + 0x6f, 0x1a, 0x05, 0xd2, 0x0e, 0x8f, 0xdc, 0xa5, 0x76, 0xdc, 0x85, 0xc4, + 0xd5, 0x83, 0xc7, 0xa7, 0xb6, 0xa1, 0x5f, 0xfe, 0x04, 0x3a, 0x62, 0xd2, + 0xd3, 0x86, 0xec, 0x22, 0x02, 0x89, 0x49, 0x2c, 0x22, 0xcc, 0x36, 0x9d, + 0x93, 0x26, 0x36, 0x87, 0x6c, 0x46, 0xa5, 0x90, 0x6a, 0x23, 0xb4, 0x0e, + 0xd7, 0x05, 0xba, 0x3a, 0x15, 0x29, 0x72, 0xe1, 0xd9, 0xe6, 0xed, 0xcc, + 0xcb, 0xaa, 0xce, 0xff, 0x00, 0x92, 0x56, 0x83, 0x42, 0xcb, 0x27, 0x4b, + 0xd2, 0xaa, 0x08, 0xa8, 0xf4, 0x48, 0x50, 0x82, 0x35, 0xf4, 0x88, 0x56, + 0x9b, 0x8f, 0xe2, 0x1a, 0x41, 0x89, 0x8c, 0x35, 0xed, 0x0e, 0x70, 0x6e, + 0x2d, 0x4b, 0xf4, 0x2a, 0xcb, 0xc6, 0x63, 0x68, 0x9a, 0x69, 0x5f, 0x98, + 0x79, 0x45, 0x8b, 0x71, 0x63, 0xde, 0x30, 0xc2, 0xcb, 0x15, 0x81, 0x83, + 0x56, 0x63, 0xd8, 0x68, 0xb8, 0x25, 0xd1, 0x4c, 0xa3, 0x58, 0xad, 0xa5, + 0x46, 0x58, 0xa4, 0x4f, 0x43, 0xa4, 0x05, 0xda, 0x66, 0xb8, 0xaa, 0x38, + 0xa0, 0x1f, 0x10, 0x92, 0x49, 0xc2, 0x10, 0x03, 0xb7, 0xfe, 0x03, 0xe8, + 0x28, 0x82, 0x70, 0x2a, 0x8c, 0x9d, 0x7d, 0x5d, 0x23, 0x47, 0x5b, 0x2b, + 0x56, 0x10, 0x43, 0x44, 0x22, 0x83, 0x2e, 0x98, 0xb9, 0x97, 0x06, 0xbd, + 0x06, 0xd1, 0xb3, 0x81, 0x89, 0x1d, 0xbd, 0xea, 0x0c, 0x69, 0x33, 0xad, + 0xb5, 0xdd, 0x08, 0xe8, 0x3a, 0x42, 0x0a, 0x4d, 0x53, 0x54, 0x2d, 0x2e, + 0xe5, 0xd3, 0x16, 0x6b, 0x16, 0x2c, 0xbf, 0x31, 0x18, 0xb6, 0x41, 0x8c, + 0xc3, 0xbe, 0x20, 0x58, 0x7d, 0x2d, 0xe3, 0x67, 0x49, 0x75, 0x7e, 0xa5, + 0x05, 0x44, 0xc8, 0x99, 0xbf, 0x45, 0xff, 0x00, 0xe0, 0xd2, 0xd6, 0x26, + 0x01, 0x71, 0x6c, 0x45, 0xbc, 0x32, 0x9a, 0x5c, 0xb3, 0x14, 0xce, 0x3e, + 0x71, 0xab, 0xe8, 0xbf, 0x12, 0xc8, 0xe2, 0xce, 0x92, 0x17, 0x1b, 0xb6, + 0xc3, 0xa2, 0x53, 0x89, 0x56, 0xb1, 0x11, 0xb3, 0xda, 0x2b, 0x7b, 0xc4, + 0x10, 0xb2, 0x34, 0x69, 0x64, 0x13, 0x69, 0x49, 0xa4, 0xab, 0xd0, 0xa2, + 0xa8, 0xa2, 0xa8, 0x61, 0x08, 0xd1, 0xc0, 0xa0, 0x9a, 0xee, 0x3f, 0xdf, + 0x89, 0x57, 0x78, 0xe8, 0x3d, 0x2d, 0xfd, 0x24, 0x10, 0x43, 0x2b, 0x73, + 0x08, 0xd2, 0x2b, 0x25, 0x09, 0x9c, 0x02, 0x64, 0x4d, 0xa1, 0x83, 0x4b, + 0x18, 0xc7, 0x4b, 0xc3, 0xd7, 0x79, 0x94, 0x5c, 0x45, 0x8b, 0x68, 0xac, + 0xc1, 0x95, 0x5a, 0xa9, 0x5d, 0x3b, 0x74, 0x4b, 0xe8, 0x8e, 0x55, 0xd6, + 0xa5, 0xbe, 0x8a, 0x8b, 0x9f, 0x56, 0x88, 0xe6, 0x2d, 0x7a, 0x8e, 0x78, + 0x80, 0xde, 0x03, 0x10, 0xa4, 0x3b, 0xd4, 0xb1, 0xad, 0x0e, 0xfe, 0x7d, + 0x21, 0x50, 0x20, 0x40, 0xb9, 0x55, 0x2b, 0xd1, 0x2e, 0x10, 0x25, 0xc2, + 0xd4, 0xa0, 0x20, 0xda, 0x50, 0xa3, 0x2f, 0xe1, 0xde, 0x36, 0x55, 0xb3, + 0x6e, 0x45, 0x63, 0xef, 0x08, 0x84, 0x18, 0xae, 0x13, 0x68, 0x30, 0x81, + 0xf4, 0x10, 0xe4, 0x1a, 0x46, 0xc4, 0xd4, 0x98, 0x2b, 0x4c, 0x8c, 0x83, + 0x58, 0x06, 0xb4, 0x14, 0xf5, 0x94, 0x84, 0x78, 0x96, 0xda, 0x6a, 0x94, + 0x9a, 0xbd, 0x02, 0xd1, 0x8b, 0x1e, 0x8b, 0xda, 0xe3, 0x97, 0x11, 0x6a, + 0xf7, 0x23, 0xfe, 0x3d, 0x0b, 0x05, 0xc0, 0x65, 0xd9, 0x96, 0x04, 0x0d, + 0xd6, 0x57, 0x88, 0xe0, 0x9e, 0xf0, 0x4a, 0xe1, 0x79, 0x18, 0xff, 0x00, + 0xe1, 0xf0, 0xdb, 0xd1, 0xaa, 0x57, 0xa9, 0x44, 0xd0, 0x35, 0xde, 0x57, + 0xb4, 0x29, 0x58, 0x84, 0xe8, 0x8c, 0x37, 0x87, 0xb6, 0x74, 0x65, 0xb0, + 0xeb, 0x49, 0x80, 0x39, 0x7a, 0x0f, 0xfd, 0x20, 0x02, 0x0a, 0x82, 0x06, + 0x26, 0x10, 0xef, 0x06, 0x0c, 0xf7, 0x46, 0x86, 0x8f, 0x06, 0xeb, 0x60, + 0x8f, 0xce, 0x5c, 0x6c, 0x1b, 0x04, 0x1d, 0xf4, 0x9a, 0x0c, 0xce, 0xf8, + 0xda, 0x1c, 0xa1, 0x26, 0x3a, 0xc3, 0xdf, 0x3f, 0xa4, 0xee, 0x8f, 0xac, + 0x56, 0x42, 0x0c, 0x7b, 0x2b, 0x12, 0xbf, 0x83, 0x06, 0xaf, 0xde, 0x4d, + 0x14, 0x28, 0xa8, 0xd6, 0x58, 0x96, 0x8d, 0xec, 0x1d, 0xd9, 0x76, 0xaf, + 0x6e, 0x01, 0x35, 0xe5, 0xcf, 0xa0, 0xba, 0xc5, 0xcf, 0x31, 0x6e, 0x5d, + 0x4d, 0x63, 0x88, 0x99, 0xe9, 0x2a, 0x78, 0x97, 0x7b, 0x4b, 0x3b, 0x42, + 0xd0, 0x45, 0x46, 0x63, 0x63, 0x89, 0x46, 0x35, 0xf7, 0x6b, 0xb3, 0xbc, + 0xa8, 0x10, 0x99, 0x67, 0xb4, 0xab, 0x99, 0x40, 0x10, 0x72, 0x0d, 0x2f, + 0x55, 0xc0, 0x6e, 0xc4, 0x64, 0x86, 0x2d, 0x9e, 0xbf, 0xd2, 0x23, 0x50, + 0x08, 0x02, 0x6b, 0x34, 0xc4, 0x21, 0x08, 0x19, 0x77, 0xff, 0x00, 0xa0, + 0xd3, 0x41, 0xb3, 0xb8, 0x1d, 0x98, 0x96, 0xb7, 0x87, 0xa9, 0xdd, 0x86, + 0x84, 0x50, 0x7d, 0xe5, 0xcb, 0x35, 0x99, 0xb2, 0xea, 0x22, 0x13, 0xab, + 0xd0, 0x88, 0xb7, 0xb4, 0x68, 0x97, 0xd6, 0x31, 0x6e, 0x39, 0x89, 0x89, + 0x6e, 0xb0, 0x91, 0x67, 0x47, 0x10, 0xbd, 0x05, 0xba, 0xa9, 0x52, 0x03, + 0xa9, 0x87, 0xde, 0x55, 0x83, 0xa8, 0x2c, 0x85, 0xd8, 0x3d, 0x57, 0x14, + 0xd4, 0x84, 0x5f, 0x3f, 0x58, 0x63, 0xde, 0x67, 0x9d, 0x38, 0x26, 0xc9, + 0xe7, 0x78, 0x06, 0xc4, 0x0d, 0x04, 0x2b, 0x3e, 0xde, 0x80, 0x8e, 0x13, + 0x38, 0x61, 0x2a, 0xcf, 0xa0, 0x01, 0x2a, 0x46, 0xc8, 0x49, 0x04, 0x10, + 0x40, 0x84, 0x20, 0xc1, 0x8b, 0x10, 0x82, 0x06, 0x10, 0x47, 0xcb, 0x69, + 0xa0, 0x43, 0x19, 0x3b, 0xbb, 0xd5, 0xd6, 0x72, 0x13, 0x03, 0x49, 0x8c, + 0x55, 0xd2, 0x5d, 0x46, 0x30, 0x82, 0x9a, 0x3a, 0xc2, 0x59, 0xd9, 0x19, + 0x3d, 0x05, 0x70, 0xc3, 0x01, 0x71, 0x2e, 0x9d, 0x77, 0x3b, 0x84, 0x27, + 0x8d, 0x55, 0x6e, 0x3c, 0xa3, 0x98, 0x22, 0x73, 0xcc, 0x6f, 0x7b, 0x43, + 0x37, 0x96, 0xbd, 0x23, 0xe1, 0x2e, 0x33, 0x15, 0xe8, 0xc4, 0xb6, 0x54, + 0x31, 0xe9, 0x89, 0x88, 0x1e, 0x7d, 0x15, 0x1d, 0x62, 0x59, 0x5a, 0x80, + 0xe4, 0xf9, 0x25, 0x4c, 0x20, 0x66, 0x05, 0xc0, 0x84, 0xd7, 0xcf, 0x55, + 0x09, 0xc3, 0xd7, 0x55, 0x1e, 0xda, 0x9f, 0x35, 0x1f, 0x22, 0x69, 0x6c, + 0x1d, 0x03, 0x43, 0xd2, 0x11, 0xe9, 0xbc, 0xd2, 0x10, 0xd2, 0x32, 0xe5, + 0xf1, 0x2e, 0x5c, 0xba, 0x97, 0x52, 0xee, 0x66, 0x55, 0xda, 0x5c, 0x75, + 0x65, 0x02, 0x1a, 0x11, 0x4b, 0xa8, 0x50, 0x99, 0x4b, 0x23, 0x17, 0xd6, + 0x16, 0x77, 0x84, 0x19, 0x6b, 0x1c, 0xa3, 0xd3, 0x1f, 0x84, 0xb7, 0x31, + 0x78, 0x62, 0xe6, 0x2c, 0x58, 0xe6, 0x25, 0xcb, 0x60, 0xae, 0x99, 0x8f, + 0xd7, 0x25, 0x92, 0xa2, 0x96, 0x3a, 0x8c, 0xbf, 0x11, 0x81, 0x49, 0x01, + 0x80, 0xd3, 0xa3, 0x65, 0xee, 0xc1, 0xb0, 0x66, 0x04, 0xda, 0xa6, 0x12, + 0xcf, 0x42, 0x57, 0x3a, 0x44, 0xc4, 0xa7, 0x73, 0xd0, 0x65, 0x8c, 0x42, + 0x4b, 0x43, 0xbd, 0x86, 0x7a, 0x62, 0x69, 0x95, 0x06, 0xda, 0x27, 0x55, + 0x98, 0x40, 0x2e, 0xeb, 0x30, 0x20, 0x62, 0x10, 0x21, 0x0d, 0x61, 0x0c, + 0x41, 0xf4, 0x18, 0x56, 0x14, 0x53, 0x5a, 0x34, 0x04, 0xb4, 0x25, 0xf6, + 0x57, 0x2f, 0x4e, 0x90, 0x84, 0xb2, 0xe1, 0xb9, 0x4a, 0x34, 0x8d, 0x9f, + 0x41, 0x7f, 0x45, 0xf5, 0x86, 0xb8, 0xd3, 0xd1, 0x46, 0x68, 0x8e, 0x53, + 0x44, 0x61, 0xdc, 0xa1, 0x0b, 0x26, 0xb0, 0x36, 0x43, 0x52, 0x07, 0x1b, + 0x40, 0x68, 0x6d, 0xc9, 0x12, 0x2c, 0x71, 0xc9, 0x30, 0x2a, 0x30, 0xb5, + 0x16, 0xf6, 0x85, 0xd4, 0x62, 0x95, 0x36, 0x95, 0xd6, 0x69, 0xe9, 0x79, + 0xd2, 0x0d, 0x6d, 0x2e, 0xfa, 0x41, 0xb9, 0x91, 0x2d, 0x8c, 0x95, 0x3d, + 0x91, 0x9e, 0xd4, 0xc3, 0x87, 0x89, 0x55, 0xe8, 0xa8, 0xa5, 0x65, 0x5d, + 0xdb, 0x5d, 0x86, 0x61, 0x94, 0x6d, 0x0c, 0xef, 0x81, 0xf9, 0xf6, 0x8f, + 0xf6, 0x66, 0xf8, 0x3b, 0x1a, 0x11, 0xd7, 0x49, 0x45, 0x40, 0x04, 0xd1, + 0x97, 0x2b, 0x99, 0x55, 0x0e, 0xb2, 0xe6, 0xa9, 0x49, 0x75, 0x2e, 0x0d, + 0xfa, 0x5d, 0xc1, 0x9a, 0x88, 0xaf, 0xb4, 0x29, 0xb0, 0x1e, 0xf2, 0x82, + 0x68, 0x83, 0x5d, 0xe5, 0xcb, 0xeb, 0x2e, 0x77, 0x4c, 0xb7, 0x97, 0x34, + 0x98, 0x4c, 0x3d, 0x4b, 0x97, 0xbc, 0x36, 0x5f, 0xa1, 0x8e, 0x51, 0x73, + 0x00, 0xd9, 0x89, 0x97, 0x7c, 0x0d, 0xd8, 0x74, 0xac, 0x4a, 0xf0, 0xef, + 0xe6, 0xff, 0x00, 0x88, 0x25, 0x00, 0x70, 0x12, 0xed, 0xa3, 0x46, 0x95, + 0x1b, 0x2a, 0x88, 0xa3, 0x18, 0x5f, 0x9e, 0xd1, 0x47, 0x78, 0xd1, 0xff, + 0x00, 0x91, 0xe8, 0x95, 0x8c, 0xe2, 0x1b, 0xa2, 0x4d, 0x1c, 0x43, 0x4e, + 0x33, 0x0b, 0xcc, 0x30, 0xd2, 0x58, 0x87, 0x09, 0xda, 0x56, 0x60, 0x42, + 0x12, 0xa1, 0xac, 0x31, 0x02, 0x10, 0xc4, 0x21, 0x2e, 0x5d, 0x41, 0x1a, + 0x36, 0x8a, 0x08, 0xba, 0xc0, 0xca, 0xe1, 0xea, 0x7a, 0x74, 0x9c, 0xf2, + 0x8a, 0x94, 0x46, 0x5b, 0xcb, 0xc3, 0x7c, 0x23, 0x5c, 0xc6, 0x67, 0xdf, + 0xd0, 0xb9, 0xd2, 0x61, 0xb4, 0xed, 0xcf, 0xaa, 0xf3, 0x8e, 0x1d, 0x22, + 0xae, 0xf8, 0x8d, 0x56, 0x60, 0x37, 0x2b, 0x95, 0xb3, 0x2e, 0xaa, 0x74, + 0x6d, 0x1c, 0xc5, 0x6c, 0x34, 0x95, 0xe9, 0x70, 0x2e, 0x61, 0x16, 0x2e, + 0x22, 0xd4, 0x25, 0x96, 0x46, 0x2f, 0xaf, 0xa2, 0xb7, 0x98, 0x09, 0x62, + 0x44, 0xb2, 0xab, 0xd1, 0x15, 0x93, 0x83, 0xf3, 0xc0, 0x84, 0x12, 0xf5, + 0x3d, 0x8c, 0xcb, 0x4d, 0x8f, 0xff, 0x00, 0x53, 0xe2, 0x54, 0x0b, 0xe2, + 0xab, 0x7e, 0x51, 0x2d, 0xec, 0xb5, 0x56, 0xb2, 0xed, 0xe2, 0xb5, 0x72, + 0xad, 0xa1, 0x09, 0x51, 0x48, 0xb1, 0x69, 0xf4, 0x16, 0x97, 0x72, 0xe5, + 0xd4, 0x19, 0xaa, 0x0e, 0x22, 0xf6, 0x83, 0x2e, 0xa3, 0x52, 0xd7, 0xc6, + 0x71, 0x2b, 0x0c, 0x4a, 0x10, 0x9a, 0x17, 0x16, 0x5d, 0x31, 0xca, 0x2e, + 0x65, 0xd7, 0x58, 0xb0, 0x8b, 0xbc, 0xb1, 0xaf, 0xa3, 0xe7, 0xe8, 0xc9, + 0x8c, 0x8e, 0xf5, 0xb9, 0xae, 0xb6, 0x97, 0x7b, 0xca, 0x35, 0x14, 0x14, + 0x96, 0x4a, 0xee, 0xa7, 0x3f, 0x23, 0xf4, 0x9b, 0xc5, 0xc9, 0x7c, 0x3c, + 0x31, 0xde, 0x50, 0xfa, 0x1c, 0x22, 0x54, 0x62, 0x9e, 0x98, 0x88, 0x60, + 0x5e, 0x12, 0x19, 0x69, 0xe8, 0x12, 0x5c, 0x5c, 0xe8, 0x54, 0xc0, 0xeb, + 0x28, 0x74, 0xdd, 0x8c, 0x96, 0xc3, 0x07, 0xa1, 0x08, 0x42, 0x10, 0xe9, + 0x09, 0xa4, 0x25, 0xe2, 0x0f, 0x58, 0x84, 0xb7, 0x5a, 0x07, 0x70, 0xb6, + 0x5f, 0x49, 0xe8, 0x91, 0xf7, 0x08, 0x75, 0xa0, 0x6d, 0x38, 0x7e, 0xdf, + 0x4e, 0xa8, 0xea, 0x53, 0xd1, 0x6b, 0x36, 0xcd, 0x5c, 0x7a, 0x1a, 0x61, + 0x28, 0x53, 0xd6, 0x2e, 0x20, 0x0c, 0x3b, 0x5f, 0xef, 0x00, 0xbd, 0xe8, + 0xb6, 0x32, 0x9c, 0xfa, 0x7b, 0xa6, 0x7a, 0x32, 0xdc, 0xc7, 0xc6, 0x79, + 0xfa, 0x16, 0x2d, 0xc0, 0x27, 0x0c, 0x36, 0x78, 0x13, 0x2d, 0xee, 0x4d, + 0x59, 0x4e, 0x32, 0x80, 0x6f, 0x75, 0x8d, 0x49, 0x77, 0x10, 0xd1, 0x87, + 0xb3, 0x1b, 0x33, 0x06, 0xe3, 0xab, 0x88, 0xf5, 0x4c, 0x5c, 0x47, 0xae, + 0x34, 0x8d, 0x6f, 0x33, 0x40, 0x32, 0xbb, 0x10, 0x62, 0x8e, 0xac, 0x5f, + 0x08, 0xbd, 0x52, 0x98, 0xab, 0xe3, 0x52, 0x6d, 0x61, 0xa2, 0xfe, 0x11, + 0x02, 0xa6, 0x9c, 0xf3, 0x0f, 0x19, 0x58, 0x02, 0x50, 0x8a, 0x1a, 0xc4, + 0x41, 0x37, 0x89, 0x99, 0x98, 0x99, 0x4a, 0x3e, 0xa5, 0xc1, 0x97, 0x50, + 0x81, 0xf4, 0x05, 0xd0, 0xb7, 0xa4, 0x2e, 0xea, 0xb2, 0x7e, 0xf2, 0x80, + 0x94, 0x09, 0x8f, 0x88, 0x3e, 0x8b, 0x97, 0xc7, 0xa1, 0x86, 0xd5, 0x0d, + 0x26, 0xa6, 0xb3, 0x68, 0x5c, 0xef, 0x16, 0x38, 0x84, 0x5e, 0xb1, 0xc3, + 0x58, 0xd2, 0x53, 0x88, 0xf2, 0x44, 0xf3, 0x2a, 0x33, 0x36, 0x9e, 0xa6, + 0x7b, 0xe6, 0xf2, 0xdc, 0x17, 0xd5, 0x2f, 0x6b, 0xf0, 0x65, 0x2b, 0xa3, + 0x06, 0xdc, 0x89, 0xad, 0x71, 0x14, 0x30, 0xc4, 0xbb, 0xca, 0x6e, 0xc4, + 0xe7, 0x27, 0xa5, 0x04, 0x2d, 0xa3, 0x31, 0x04, 0xa5, 0xf3, 0x04, 0xbd, + 0x25, 0x79, 0xc4, 0x41, 0x2b, 0x31, 0x33, 0xb0, 0xb4, 0x07, 0x5e, 0x91, + 0xf8, 0x9a, 0xfa, 0x10, 0x65, 0xc1, 0x83, 0x06, 0x10, 0x97, 0x06, 0xd9, + 0x21, 0xb4, 0x8a, 0x6d, 0xd6, 0x5c, 0x99, 0x4b, 0x75, 0x6b, 0x15, 0x59, + 0x46, 0x16, 0x46, 0xc6, 0x51, 0xe5, 0x31, 0x29, 0x01, 0x2e, 0xd8, 0x4e, + 0x86, 0xfd, 0x14, 0xe7, 0xd3, 0x84, 0x6b, 0x1e, 0x48, 0x83, 0xa3, 0xcc, + 0x32, 0x95, 0x66, 0xdf, 0x30, 0x12, 0xa4, 0xc1, 0xd4, 0xb4, 0xef, 0x0c, + 0x6b, 0x54, 0x32, 0x19, 0x28, 0xe3, 0x7d, 0x18, 0x0d, 0xb7, 0xa1, 0xb1, + 0xef, 0x2d, 0x0c, 0x90, 0xc6, 0x5b, 0xa4, 0xc3, 0x59, 0x83, 0x2e, 0xf7, + 0x9a, 0xa5, 0xcb, 0xc6, 0xb2, 0xc2, 0x39, 0x45, 0xe6, 0x39, 0x84, 0x7a, + 0xc1, 0xe2, 0x03, 0xd6, 0x1e, 0xda, 0x7a, 0x37, 0x32, 0x9e, 0x66, 0x21, + 0x27, 0x01, 0x29, 0x74, 0x1f, 0xce, 0x60, 0xba, 0x93, 0xbb, 0xf9, 0xb8, + 0xe6, 0xbb, 0x3b, 0x61, 0xff, 0x00, 0x95, 0x84, 0x3d, 0xa1, 0x7f, 0x12, + 0xa9, 0xdb, 0x28, 0xbc, 0xc6, 0xd0, 0x50, 0x03, 0xfe, 0x07, 0x1e, 0x26, + 0x06, 0xc6, 0xa5, 0x7d, 0xc8, 0x98, 0x23, 0xc8, 0xc0, 0x56, 0x3d, 0x6f, + 0xe6, 0x63, 0xc5, 0xd3, 0xd2, 0xbf, 0x98, 0x20, 0x0e, 0xe6, 0x3f, 0x88, + 0x3a, 0x10, 0xf2, 0xa7, 0xe2, 0x15, 0xe4, 0xc1, 0xf9, 0x94, 0x92, 0xcb, + 0xb0, 0x67, 0xd4, 0xcb, 0x40, 0x59, 0x72, 0x74, 0x1c, 0x3e, 0xf1, 0x83, + 0x11, 0xa7, 0x01, 0xef, 0x35, 0x4b, 0x6e, 0xa8, 0x73, 0xe4, 0x23, 0x81, + 0xe5, 0x02, 0x12, 0x27, 0xa0, 0x17, 0x58, 0x15, 0x0e, 0xd2, 0xd0, 0x97, + 0x18, 0x4b, 0x8a, 0x97, 0x1c, 0x98, 0x25, 0x2a, 0x3a, 0xed, 0xa5, 0x15, + 0x29, 0x38, 0x26, 0x35, 0xf7, 0x2e, 0x07, 0xfc, 0x8d, 0xcc, 0x45, 0x97, + 0x6c, 0x7d, 0x91, 0x71, 0x2f, 0x2d, 0x4b, 0x2a, 0xf8, 0x85, 0x12, 0xf9, + 0x2e, 0x5e, 0x75, 0x97, 0x9b, 0xf4, 0xd0, 0x94, 0xc4, 0xf7, 0x89, 0x7d, + 0x65, 0xba, 0x44, 0xa8, 0x87, 0xfb, 0x2a, 0x8b, 0x8a, 0xb5, 0x59, 0x7a, + 0x2b, 0x0d, 0x2c, 0x23, 0x1b, 0x45, 0x06, 0x8f, 0x8f, 0xba, 0x19, 0xd0, + 0xd5, 0x29, 0xf9, 0xd3, 0xe2, 0x59, 0xa8, 0xbf, 0xe5, 0x44, 0xb4, 0x00, + 0xd4, 0xfc, 0x1b, 0x7c, 0xcb, 0x91, 0x0d, 0xb0, 0xcf, 0x64, 0xc1, 0x53, + 0xee, 0x60, 0x3b, 0x24, 0xba, 0xcf, 0x41, 0x61, 0x1c, 0x4e, 0xcd, 0x58, + 0xee, 0x6e, 0x6e, 0xce, 0x68, 0x4e, 0x2c, 0xc0, 0x06, 0xeb, 0xac, 0xcf, + 0xa9, 0xa0, 0x37, 0xed, 0x32, 0xf5, 0x0c, 0xa0, 0xc1, 0xb8, 0x40, 0xc0, + 0x4d, 0x13, 0x03, 0x89, 0x72, 0x24, 0xff, 0x00, 0x88, 0x69, 0x2c, 0x4e, + 0x1e, 0xbf, 0xb3, 0x43, 0xe6, 0x2e, 0x55, 0xdd, 0xe9, 0xdb, 0x88, 0xc5, + 0x86, 0x84, 0xd5, 0xeb, 0x00, 0xd1, 0x83, 0x0b, 0x35, 0x9a, 0xb8, 0x4d, + 0xa5, 0x71, 0x72, 0x82, 0x83, 0xd7, 0x0f, 0xb9, 0xfa, 0x95, 0x34, 0x4e, + 0x8d, 0x90, 0x0f, 0xc0, 0x40, 0x6c, 0x0f, 0x23, 0x06, 0xd0, 0x57, 0x06, + 0x66, 0x17, 0xc1, 0x91, 0x5b, 0x1b, 0x05, 0xbe, 0x94, 0x77, 0x88, 0xb5, + 0xac, 0x46, 0xfc, 0xd9, 0x3e, 0x81, 0x98, 0x41, 0x5d, 0x0a, 0x4f, 0xf2, + 0x8a, 0x68, 0xbd, 0x47, 0xe6, 0x15, 0x5d, 0x09, 0xb7, 0xe6, 0x64, 0x3a, + 0xd0, 0x3f, 0x15, 0x03, 0x34, 0xb4, 0xb8, 0x1d, 0x7a, 0xc1, 0x8e, 0xa1, + 0x7a, 0x3c, 0x35, 0x0e, 0x2b, 0x3c, 0x3f, 0xca, 0x1f, 0x64, 0xf2, 0x37, + 0x07, 0x1e, 0x33, 0x17, 0xd0, 0xa6, 0x63, 0x87, 0xa3, 0x44, 0x58, 0xbe, + 0x22, 0xcc, 0xa0, 0x17, 0x88, 0x07, 0x62, 0x51, 0x03, 0x58, 0x87, 0x2f, + 0xbc, 0xf2, 0xa8, 0xa8, 0x95, 0x1a, 0x5c, 0x1f, 0x98, 0xc5, 0x24, 0xf3, + 0x2b, 0xd0, 0x2d, 0x8b, 0x7b, 0xeb, 0x19, 0x01, 0xc9, 0x07, 0xb8, 0xc4, + 0x13, 0x7c, 0x82, 0x49, 0xf2, 0xc9, 0x54, 0x19, 0xdd, 0xf8, 0x04, 0x65, + 0x2d, 0xc6, 0xf4, 0x3f, 0x29, 0x0d, 0xd4, 0xf1, 0x3e, 0x53, 0xe2, 0x3f, + 0xdf, 0x93, 0x7a, 0x7e, 0xa3, 0xe4, 0x94, 0xa3, 0x6c, 0xff, 0x00, 0xb2, + 0x2c, 0x29, 0x76, 0xff, 0x00, 0x68, 0x28, 0x5c, 0xc2, 0x2f, 0xc1, 0x8e, + 0x95, 0x14, 0xee, 0x2f, 0x68, 0xcd, 0x52, 0xf0, 0xe1, 0x83, 0xb2, 0x09, + 0xb4, 0x11, 0xd3, 0xd0, 0x45, 0x65, 0x9a, 0x4e, 0x93, 0x10, 0x4c, 0x02, + 0xad, 0x89, 0x97, 0xef, 0x3f, 0x58, 0xd1, 0xe4, 0xb4, 0xf6, 0x84, 0x4a, + 0x8a, 0xd0, 0xac, 0x4a, 0x2a, 0x61, 0x07, 0xc4, 0x6b, 0x53, 0x0e, 0xbd, + 0xa0, 0x5e, 0xfe, 0x8f, 0xbf, 0xa3, 0x09, 0x72, 0xfd, 0xfd, 0x0b, 0x1d, + 0x65, 0xde, 0x90, 0x5f, 0x10, 0x9a, 0xc5, 0xe6, 0x5c, 0xbc, 0xcc, 0x44, + 0x3a, 0xc4, 0x3b, 0x41, 0x6f, 0x19, 0xe2, 0x0b, 0x78, 0x85, 0xb2, 0x0f, + 0x24, 0x06, 0xe5, 0x04, 0x2c, 0xc3, 0xa2, 0xa1, 0x81, 0xf6, 0xc2, 0x94, + 0x7c, 0x6f, 0x38, 0x70, 0x56, 0x0a, 0x76, 0x97, 0x81, 0xc5, 0x04, 0x47, + 0xf0, 0x54, 0x0b, 0x63, 0x3c, 0x18, 0x80, 0xa4, 0x57, 0x5b, 0xcf, 0xe2, + 0x19, 0xd8, 0x77, 0x81, 0x16, 0xf8, 0xab, 0x33, 0x60, 0xcd, 0xcd, 0xfd, + 0x91, 0x08, 0xc7, 0xfb, 0x0b, 0x58, 0x5c, 0x93, 0x84, 0xfe, 0x90, 0x81, + 0xde, 0x7d, 0x8d, 0xc2, 0x16, 0xcd, 0xc2, 0x3e, 0x88, 0xe4, 0x27, 0x22, + 0x17, 0x08, 0x97, 0xdc, 0x9e, 0xe3, 0xfa, 0x9e, 0x43, 0x14, 0x48, 0xb7, + 0x33, 0xd1, 0x31, 0xa5, 0xc8, 0x76, 0x8e, 0x40, 0x03, 0x71, 0xbf, 0x04, + 0x04, 0x11, 0x6d, 0x77, 0x5d, 0x29, 0x9c, 0xee, 0x6a, 0xe3, 0xc8, 0xdf, + 0xb4, 0xb6, 0xb0, 0x3a, 0x27, 0xcd, 0x4b, 0x40, 0xee, 0x4b, 0x7b, 0x15, + 0x2c, 0xcb, 0x7d, 0xff, 0x00, 0x80, 0x96, 0xe7, 0xd3, 0x28, 0xea, 0x81, + 0x4d, 0x2e, 0x25, 0x13, 0xae, 0x8a, 0x21, 0x58, 0x30, 0x92, 0xb1, 0xcf, + 0x98, 0xcf, 0x74, 0x52, 0xc4, 0x76, 0x65, 0xb8, 0x57, 0x00, 0xa1, 0x38, + 0x15, 0x4a, 0x2f, 0x04, 0xfe, 0xa2, 0xd4, 0x15, 0x00, 0x8f, 0xcc, 0x62, + 0x54, 0x68, 0xde, 0x3f, 0x4c, 0x4f, 0x3e, 0x9b, 0x1a, 0x35, 0x16, 0xea, + 0xcb, 0xf2, 0xcd, 0x88, 0xf7, 0x22, 0xc6, 0x2d, 0x72, 0xa3, 0xb6, 0xc7, + 0x7a, 0xfa, 0x80, 0x64, 0x4e, 0x5f, 0xca, 0x1a, 0x6c, 0x9a, 0xb4, 0x91, + 0x80, 0xeb, 0x15, 0xfd, 0x21, 0x24, 0xbf, 0xe6, 0xb8, 0x85, 0xd8, 0x34, + 0x6c, 0x25, 0xbb, 0xb1, 0xfe, 0x13, 0x09, 0x79, 0x8b, 0xcb, 0x88, 0x8d, + 0x98, 0xb5, 0x18, 0xce, 0xa8, 0x83, 0x59, 0x79, 0x4b, 0xbb, 0x01, 0xb1, + 0xfa, 0x98, 0x43, 0xea, 0x83, 0xb3, 0xfc, 0x66, 0x84, 0x43, 0x2b, 0xfc, + 0x32, 0x41, 0xe2, 0x7c, 0x3f, 0x62, 0x31, 0x28, 0xed, 0xbe, 0x96, 0x20, + 0x51, 0x5d, 0x0c, 0xaf, 0xc4, 0xbc, 0x58, 0x37, 0xfa, 0x56, 0xe3, 0x0e, + 0x48, 0xab, 0xe6, 0x68, 0x3d, 0x72, 0x69, 0x38, 0x14, 0xec, 0xc2, 0x75, + 0x57, 0xbe, 0x60, 0xff, 0x00, 0x04, 0xb1, 0x02, 0x37, 0xcf, 0xee, 0x33, + 0xe9, 0xa1, 0x5f, 0xb8, 0xd0, 0x01, 0xcb, 0xa4, 0xac, 0x6c, 0x26, 0xe4, + 0xad, 0x0f, 0xcc, 0xf7, 0x95, 0xaa, 0xaf, 0x84, 0x62, 0x2a, 0x8e, 0xe4, + 0xec, 0x84, 0x24, 0xc1, 0xab, 0x2b, 0xce, 0x71, 0x57, 0xdc, 0x14, 0x05, + 0xb8, 0x2b, 0xe2, 0x12, 0x05, 0xd8, 0x4a, 0x6b, 0x10, 0x87, 0x4c, 0xcd, + 0x38, 0x12, 0x0a, 0x65, 0x83, 0xac, 0xb3, 0x9b, 0x8d, 0x38, 0xa8, 0xd9, + 0x97, 0xd6, 0x5e, 0x75, 0xf4, 0x5e, 0x7a, 0xc1, 0xa7, 0x26, 0x7d, 0x16, + 0xff, 0x00, 0xb0, 0x57, 0x78, 0x69, 0x35, 0x7a, 0x74, 0x9c, 0xca, 0x6b, + 0x49, 0xa2, 0xfe, 0x66, 0x60, 0xe3, 0xf1, 0x0d, 0x63, 0x54, 0x5f, 0xaa, + 0xf1, 0x2d, 0xbd, 0x1e, 0x6e, 0x09, 0xa1, 0x60, 0xf6, 0x0e, 0x4c, 0x08, + 0x2b, 0x74, 0xee, 0xfd, 0x13, 0x3c, 0x4e, 0xcb, 0xf8, 0x23, 0x8d, 0xa0, + 0xd2, 0xd7, 0xb3, 0x48, 0x6a, 0x0a, 0xce, 0xa0, 0xf3, 0x4c, 0x16, 0x78, + 0xe7, 0xe4, 0x40, 0x0b, 0x2a, 0xe3, 0xf4, 0xa7, 0xd0, 0x09, 0x1b, 0x15, + 0xd5, 0x5f, 0xa2, 0x3f, 0xfb, 0x07, 0xa4, 0xf9, 0x44, 0xdf, 0xb8, 0xfe, + 0x24, 0xdd, 0x6e, 0x1c, 0xdd, 0x1d, 0xbf, 0x04, 0x23, 0xb7, 0x6f, 0xfd, + 0x17, 0x1d, 0x53, 0xee, 0x5f, 0xdc, 0x37, 0xf6, 0x90, 0x8b, 0x6a, 0xde, + 0x61, 0x2c, 0x83, 0xba, 0xa6, 0x34, 0x62, 0x70, 0x94, 0x06, 0xb6, 0xc5, + 0x36, 0x85, 0x32, 0xab, 0xbc, 0xd6, 0x0a, 0xf4, 0x9b, 0x75, 0xef, 0x34, + 0x98, 0xed, 0x2b, 0xb4, 0xe9, 0x2a, 0x7a, 0x27, 0xcd, 0xc6, 0xfd, 0xc5, + 0x61, 0x00, 0x66, 0x08, 0x41, 0x80, 0x10, 0x06, 0xd3, 0x1d, 0xa5, 0x57, + 0x82, 0x61, 0x76, 0x65, 0x29, 0x9b, 0x40, 0x1a, 0x86, 0x09, 0x0c, 0x66, + 0x73, 0x08, 0xb6, 0x1d, 0x32, 0xf0, 0xac, 0xb8, 0x6f, 0x34, 0x43, 0xab, + 0x32, 0x93, 0xa5, 0x87, 0x54, 0x4c, 0x45, 0xc4, 0x44, 0x44, 0x6d, 0x2a, + 0x33, 0x1c, 0x92, 0xb9, 0x8d, 0x27, 0x44, 0xa1, 0xfd, 0xc0, 0x6c, 0x7a, + 0xa0, 0xf8, 0x95, 0x63, 0x7d, 0x17, 0xdc, 0xa8, 0x30, 0x9f, 0x82, 0x7d, + 0x9a, 0x94, 0xa3, 0x9e, 0x57, 0xee, 0xe2, 0x5b, 0xf9, 0xd0, 0x03, 0xe2, + 0x03, 0x00, 0x1b, 0xba, 0x47, 0x6a, 0xdd, 0xb2, 0xf8, 0x80, 0x47, 0x63, + 0x76, 0x7c, 0xc3, 0xad, 0x0f, 0x6f, 0xc1, 0x19, 0xb5, 0xf6, 0x60, 0x8e, + 0xd0, 0x7b, 0x2c, 0xfd, 0xc1, 0x28, 0xe5, 0x12, 0xf9, 0x81, 0x73, 0x09, + 0xcb, 0x32, 0xb4, 0x0e, 0x0d, 0x9d, 0xd8, 0x9e, 0xc0, 0xb6, 0xc0, 0x21, + 0x29, 0x17, 0xa5, 0xa2, 0x9c, 0x7d, 0x66, 0x9c, 0x35, 0x06, 0x37, 0x29, + 0x81, 0x4e, 0xeb, 0x42, 0x8c, 0x36, 0x83, 0x45, 0x43, 0xc3, 0x19, 0xbd, + 0xf4, 0x09, 0xe6, 0xa0, 0x08, 0xb5, 0xb5, 0x35, 0x05, 0xc8, 0xf4, 0xb8, + 0x0e, 0xaf, 0xbc, 0xa2, 0xe8, 0xf6, 0xb8, 0x53, 0x34, 0x4e, 0xb0, 0x01, + 0xc7, 0xd2, 0xe3, 0xf7, 0x90, 0x6c, 0xdc, 0xa1, 0x95, 0xf3, 0x10, 0xd4, + 0x18, 0x1a, 0xa4, 0x8c, 0x17, 0x51, 0x88, 0x9d, 0xa3, 0x52, 0x5c, 0xba, + 0x66, 0x52, 0xe2, 0xc1, 0xb8, 0x3b, 0x2f, 0x22, 0xa8, 0xa5, 0x83, 0xc2, + 0x93, 0xd9, 0x9a, 0xd9, 0x0d, 0xbf, 0x1a, 0xa7, 0xce, 0x4e, 0xbe, 0xd9, + 0x59, 0xe1, 0xbf, 0xc0, 0x95, 0xdf, 0xb4, 0x7d, 0xd0, 0x63, 0xdd, 0x07, + 0xe9, 0x71, 0x66, 0xb7, 0xcb, 0xf1, 0x53, 0xe0, 0xb0, 0x1f, 0x6c, 0x7f, + 0xb1, 0xfd, 0xa1, 0x6e, 0x1b, 0xc4, 0x02, 0x9f, 0xd3, 0xe2, 0x5b, 0xa7, + 0xcb, 0xfa, 0xe7, 0xe6, 0x08, 0x9b, 0xe9, 0xe3, 0xf7, 0x8b, 0xdd, 0xf1, + 0xfb, 0x44, 0x5d, 0x5b, 0xf8, 0xe6, 0x03, 0x92, 0xbe, 0xdf, 0xdc, 0x00, + 0x1a, 0x7c, 0xfe, 0xe9, 0xac, 0xb5, 0xe3, 0xfe, 0xd1, 0x1f, 0x77, 0xfd, + 0x23, 0x32, 0x7b, 0x5a, 0x57, 0xdb, 0x0c, 0x0c, 0xdd, 0x21, 0xf6, 0x7f, + 0x39, 0x99, 0x1b, 0xa5, 0x07, 0x7d, 0x1d, 0x22, 0xd4, 0x29, 0xe8, 0x9e, + 0xe4, 0xaa, 0x14, 0x76, 0xc9, 0xed, 0x70, 0x21, 0x39, 0xe0, 0x7e, 0xa1, + 0xf5, 0x56, 0x22, 0x2e, 0xd0, 0x5b, 0x5e, 0xc4, 0x38, 0x40, 0x60, 0x3b, + 0x7d, 0xa2, 0xcb, 0xab, 0x6e, 0x3d, 0x84, 0xbc, 0xda, 0x78, 0x83, 0xb8, + 0x78, 0x88, 0x2a, 0x28, 0xef, 0x14, 0xa9, 0x8d, 0x12, 0xf5, 0xa8, 0xed, + 0x14, 0x64, 0x0f, 0x64, 0x77, 0x7d, 0x84, 0xa7, 0x0f, 0xb3, 0x0f, 0xf4, + 0x20, 0x76, 0x23, 0xa0, 0x5b, 0x29, 0x41, 0x7f, 0x86, 0x95, 0x58, 0x74, + 0x5c, 0x2a, 0x3d, 0xd8, 0xff, 0x00, 0x51, 0xe0, 0x11, 0xc3, 0x7c, 0x66, + 0x1c, 0x9f, 0xc1, 0x37, 0x48, 0xd3, 0x83, 0xc8, 0x8f, 0xcb, 0x2c, 0x8c, + 0xde, 0x11, 0x99, 0x0e, 0xcc, 0x26, 0xb4, 0x78, 0xdc, 0x15, 0x56, 0x7c, + 0xc4, 0xa5, 0x7a, 0x8d, 0x13, 0xe4, 0x9b, 0x2d, 0xe4, 0x43, 0xe2, 0x05, + 0xda, 0x3a, 0x56, 0x04, 0x6f, 0x1d, 0x00, 0xbf, 0x71, 0x5c, 0x8e, 0x98, + 0x87, 0x12, 0x0b, 0x83, 0xc4, 0x08, 0x7a, 0x00, 0xef, 0x3b, 0xa3, 0xc0, + 0xc7, 0x08, 0xcb, 0xd1, 0x0d, 0xb0, 0x7b, 0xb2, 0xeb, 0x67, 0x3f, 0xca, + 0xf8, 0x97, 0x13, 0x37, 0x20, 0xf0, 0x69, 0x1d, 0x08, 0xad, 0x56, 0xcb, + 0x0e, 0x00, 0x3d, 0x25, 0x66, 0x67, 0xa3, 0xba, 0xa5, 0x79, 0xf4, 0xf7, + 0xc0, 0x71, 0x11, 0x33, 0x84, 0x39, 0xeb, 0x33, 0x3d, 0x2c, 0xe1, 0x79, + 0x82, 0x46, 0x88, 0x1e, 0x63, 0xa5, 0xc4, 0x5b, 0x1d, 0x62, 0x9b, 0xb0, + 0x1a, 0x81, 0xee, 0x40, 0xd9, 0x0c, 0x75, 0x12, 0xbe, 0x08, 0x17, 0x1e, + 0x88, 0x5f, 0x0c, 0xb5, 0xa2, 0x53, 0x62, 0xe0, 0x5b, 0x6b, 0x77, 0x29, + 0x0f, 0x0a, 0x7d, 0xe0, 0x9b, 0x77, 0x8b, 0xa2, 0x77, 0x32, 0x92, 0xa0, + 0x96, 0x34, 0xd9, 0x43, 0x1a, 0x0f, 0xbb, 0xde, 0x26, 0xbd, 0x38, 0x62, + 0x2c, 0x27, 0x79, 0x57, 0x2f, 0xe6, 0x0f, 0x0a, 0xfd, 0x40, 0xa0, 0x13, + 0x29, 0x70, 0xb1, 0x29, 0x73, 0x32, 0x08, 0xd3, 0x35, 0x1a, 0x25, 0x09, + 0xd6, 0x3c, 0xa0, 0x25, 0x8e, 0x88, 0xc0, 0x2b, 0xd9, 0x00, 0xb0, 0x7b, + 0xa6, 0x53, 0x81, 0xf1, 0x72, 0x9e, 0x91, 0x05, 0xe9, 0x0e, 0x85, 0x4a, + 0x18, 0xee, 0x99, 0x89, 0x29, 0x7b, 0xc0, 0x70, 0x8e, 0xe9, 0x55, 0xd4, + 0xd8, 0x11, 0x07, 0x8a, 0xdc, 0x35, 0x99, 0xbb, 0xa5, 0xc6, 0xa1, 0xe8, + 0x0f, 0xb9, 0x68, 0xc5, 0xc5, 0x18, 0x95, 0xfb, 0x22, 0x03, 0xf7, 0x27, + 0xd4, 0x69, 0xa6, 0xf7, 0x60, 0x4d, 0xd8, 0xea, 0x3f, 0x98, 0x4e, 0x4f, + 0x87, 0xee, 0x6b, 0x88, 0xec, 0x3e, 0xa2, 0x0d, 0x27, 0x71, 0x15, 0xae, + 0xb0, 0x7e, 0x93, 0x06, 0x3d, 0x06, 0x7e, 0xe0, 0x63, 0x64, 0x5a, 0x05, + 0xae, 0xd0, 0xa1, 0xb1, 0xdd, 0x5f, 0xb0, 0xfd, 0xc0, 0xc3, 0x7c, 0x10, + 0xfe, 0xf3, 0x32, 0x49, 0x0e, 0xb3, 0xf1, 0x15, 0xc5, 0xf5, 0xbe, 0x3b, + 0xf1, 0xe6, 0x68, 0x3e, 0x64, 0xfd, 0x2c, 0x04, 0xc8, 0xf7, 0x92, 0x0c, + 0x17, 0xb5, 0xe0, 0xb7, 0x68, 0x72, 0x3f, 0x31, 0x1a, 0x04, 0x77, 0xf0, + 0x21, 0x41, 0xee, 0xfe, 0x51, 0xf8, 0xd1, 0x5b, 0x65, 0xf8, 0x81, 0x7b, + 0x61, 0x26, 0x3b, 0x0e, 0xcb, 0x50, 0xc8, 0x47, 0x05, 0x13, 0xdd, 0xc4, + 0xd3, 0x25, 0xba, 0x6f, 0xca, 0x6b, 0xb4, 0x72, 0xd7, 0xc9, 0x03, 0xa0, + 0x9e, 0x2c, 0xfa, 0x99, 0xab, 0xe6, 0xf9, 0x8c, 0x31, 0x67, 0x12, 0x55, + 0xd4, 0xc0, 0xdd, 0xf9, 0x63, 0x1b, 0xf6, 0x83, 0x13, 0x05, 0xbe, 0xbf, + 0xa2, 0x0e, 0x50, 0x76, 0x7e, 0x51, 0x99, 0x3f, 0xdd, 0x88, 0x82, 0x37, + 0x34, 0x98, 0xc4, 0x7c, 0x90, 0xf5, 0x84, 0x76, 0x1a, 0x96, 0x30, 0x6b, + 0xa3, 0x05, 0xba, 0xe1, 0xbc, 0xdd, 0x6d, 0x72, 0x8d, 0xb5, 0x50, 0xb7, + 0x23, 0x1b, 0x00, 0xdb, 0xf7, 0x2a, 0x9a, 0xd5, 0x3b, 0x5b, 0x1c, 0xdf, + 0x86, 0xbf, 0x71, 0x2c, 0x5d, 0xe2, 0x02, 0x76, 0xeb, 0x35, 0x3b, 0xb3, + 0x11, 0x2e, 0x52, 0xf5, 0x62, 0xbf, 0xf2, 0x61, 0xa7, 0x47, 0x6d, 0xa5, + 0x88, 0x2e, 0x2f, 0x11, 0xa0, 0x2d, 0x72, 0x64, 0x95, 0xc2, 0x39, 0x3f, + 0x48, 0x59, 0x76, 0x16, 0x98, 0xb5, 0x79, 0x42, 0x7b, 0x38, 0x83, 0xd1, + 0xed, 0x2d, 0xee, 0x43, 0x38, 0x77, 0x8a, 0xc5, 0x77, 0x53, 0xf5, 0x16, + 0x64, 0xf6, 0x3f, 0xe2, 0x10, 0x9d, 0xf0, 0x22, 0x48, 0x07, 0xc0, 0xfc, + 0x54, 0x54, 0x26, 0xd5, 0xb1, 0x86, 0xa2, 0x07, 0x95, 0x86, 0xd5, 0x1b, + 0x1c, 0x76, 0x85, 0x50, 0xb4, 0x27, 0x19, 0xab, 0xff, 0x00, 0x2e, 0xcd, + 0x82, 0x59, 0x89, 0xe6, 0x52, 0xf5, 0x27, 0xba, 0x39, 0xf1, 0x13, 0xcc, + 0xd7, 0x84, 0xb6, 0xc7, 0xde, 0x1c, 0x4d, 0x7d, 0xe2, 0xeb, 0xf9, 0x40, + 0x2d, 0xac, 0x1b, 0x8c, 0xe8, 0x9f, 0x13, 0x42, 0xf6, 0x26, 0xf1, 0x9a, + 0x4b, 0x76, 0x80, 0xf5, 0xfb, 0xd2, 0x67, 0xfa, 0xf9, 0x1f, 0x99, 0xf1, + 0xb8, 0xdf, 0xd1, 0x07, 0xb6, 0x7c, 0x57, 0xf7, 0x31, 0x6f, 0xf2, 0xaf, + 0xea, 0x55, 0xa2, 0xea, 0x00, 0x63, 0x2c, 0x0d, 0x5f, 0x71, 0xd2, 0x03, + 0xfe, 0x66, 0x66, 0xcf, 0xcc, 0xe3, 0x1e, 0x66, 0x3f, 0x24, 0x75, 0x55, + 0xe2, 0x5f, 0x06, 0x63, 0xd4, 0x82, 0x0a, 0x55, 0x20, 0xc2, 0x0a, 0xc2, + 0xe2, 0x5a, 0x7b, 0x4b, 0xc0, 0x7b, 0xc7, 0x24, 0x4b, 0xde, 0x28, 0xfb, + 0x63, 0x28, 0x1f, 0x95, 0x8d, 0x02, 0xf1, 0x4f, 0x62, 0x65, 0xf9, 0xaa, + 0xec, 0xc5, 0x3c, 0x8d, 0xf2, 0x11, 0xa7, 0x45, 0x14, 0x35, 0x1e, 0xc8, + 0xeb, 0xaf, 0x74, 0x94, 0x98, 0x6e, 0xac, 0x57, 0x50, 0x7b, 0xc0, 0xf2, + 0x3b, 0xc3, 0x60, 0xe9, 0xb8, 0x7c, 0x41, 0x02, 0xa7, 0x76, 0x99, 0xbc, + 0x96, 0xb4, 0x80, 0xf7, 0x0f, 0x89, 0xd3, 0x40, 0x34, 0xf0, 0x42, 0x17, + 0xf2, 0xfc, 0xcb, 0x58, 0x1f, 0xce, 0xf2, 0xdc, 0x1f, 0x88, 0x37, 0x2b, + 0x3a, 0xaf, 0xea, 0x63, 0xcd, 0x38, 0x06, 0x61, 0xad, 0xfb, 0x47, 0xe9, + 0xba, 0xc8, 0x8d, 0xbe, 0xea, 0x7e, 0x18, 0xb8, 0x9e, 0x4f, 0xf1, 0x72, + 0xad, 0xe0, 0xa9, 0xf6, 0x46, 0x25, 0xd5, 0x11, 0x3d, 0xf3, 0x98, 0x40, + 0x70, 0x05, 0xc1, 0xb5, 0xf2, 0x0f, 0xcc, 0x76, 0xc0, 0xf4, 0x45, 0x5f, + 0x60, 0x0f, 0xc4, 0x29, 0xe7, 0x8d, 0xaf, 0xb8, 0x0d, 0x31, 0xf2, 0xfd, + 0x11, 0x62, 0xf6, 0x6b, 0xf9, 0x66, 0xf3, 0x50, 0xab, 0x59, 0x56, 0x94, + 0x4b, 0xcb, 0x27, 0xac, 0x5c, 0xf5, 0xa8, 0x1f, 0x06, 0x0f, 0x0d, 0xea, + 0x8b, 0xee, 0x2a, 0x23, 0x68, 0x57, 0xb8, 0x6b, 0x1d, 0xab, 0xfb, 0x7d, + 0x44, 0x56, 0xde, 0xf2, 0x71, 0xc8, 0xfb, 0xd3, 0x4a, 0x0f, 0x15, 0x00, + 0x70, 0x7c, 0x92, 0x96, 0xa1, 0xf3, 0x12, 0x6b, 0xf1, 0x89, 0x89, 0xb3, + 0xdd, 0x9a, 0xfc, 0xee, 0x47, 0x5a, 0x9f, 0x89, 0xbc, 0x57, 0x66, 0x09, + 0x8b, 0xba, 0x29, 0x56, 0x8a, 0x2f, 0x74, 0x7a, 0xb2, 0xfd, 0xa2, 0x26, + 0x1a, 0x84, 0x10, 0x01, 0xa4, 0x11, 0x57, 0x2f, 0xa5, 0xaa, 0xd4, 0xbb, + 0x6c, 0x4a, 0xdd, 0x7e, 0xd1, 0x6a, 0xa7, 0x5b, 0x86, 0x7a, 0x26, 0x7d, + 0x02, 0x5d, 0xc4, 0x6c, 0xde, 0x0f, 0x26, 0x23, 0x17, 0x4b, 0x85, 0xb9, + 0x80, 0x15, 0xe2, 0xe0, 0x5a, 0x7d, 0x42, 0xbe, 0xa6, 0x0e, 0xef, 0x86, + 0x0d, 0xab, 0x6d, 0x57, 0xee, 0x16, 0x5d, 0xad, 0x25, 0x6b, 0x77, 0xba, + 0x5f, 0x59, 0xf7, 0x86, 0xdb, 0x91, 0x80, 0x16, 0xe3, 0xc4, 0x4a, 0xe9, + 0x95, 0x65, 0x04, 0xde, 0x07, 0x66, 0x6a, 0xd5, 0xef, 0x3f, 0x77, 0x4d, + 0x07, 0xde, 0x86, 0x90, 0xb0, 0x4d, 0x90, 0x1c, 0x9e, 0xf2, 0x9c, 0x93, + 0x4e, 0xa4, 0xa7, 0x33, 0xbb, 0xd0, 0x8e, 0x4f, 0xe7, 0xde, 0x3b, 0xad, + 0xd8, 0x7e, 0xe5, 0xba, 0xaf, 0x63, 0xfb, 0x8b, 0xd7, 0xc2, 0x22, 0xba, + 0xf9, 0x43, 0xf1, 0x1f, 0x90, 0x21, 0xf8, 0x83, 0xcd, 0xfe, 0xbf, 0xaa, + 0x0f, 0x85, 0x09, 0xa1, 0xef, 0xf1, 0xcc, 0xd1, 0x9f, 0x71, 0xfc, 0xcf, + 0x90, 0xc6, 0xe5, 0xdf, 0x15, 0xfa, 0xa6, 0xf1, 0xda, 0x8f, 0xa2, 0x1f, + 0x9a, 0xf6, 0x8b, 0x66, 0x7a, 0xa2, 0x30, 0x3f, 0x30, 0xa8, 0x8f, 0xe8, + 0xff, 0x00, 0x91, 0xff, 0x00, 0x9b, 0x01, 0xdb, 0xf1, 0x3b, 0x9c, 0x5f, + 0xf9, 0x89, 0xd7, 0xf8, 0x4d, 0x52, 0x7b, 0xc3, 0x54, 0x86, 0x54, 0x29, + 0x45, 0x84, 0x16, 0x8b, 0x86, 0x18, 0x8a, 0xe8, 0x13, 0x3c, 0xa9, 0x7a, + 0xa4, 0x53, 0x7a, 0x88, 0x6b, 0x29, 0x45, 0xea, 0xfa, 0x61, 0xbe, 0x10, + 0xfa, 0x7b, 0xe1, 0xd5, 0x77, 0x25, 0x8c, 0xf8, 0x51, 0xde, 0x12, 0xcd, + 0x41, 0xed, 0x2f, 0xd2, 0x88, 0x0e, 0xcf, 0x65, 0x33, 0xdd, 0x17, 0x74, + 0xf9, 0x90, 0xdb, 0xf8, 0x92, 0x9f, 0xf8, 0x41, 0x3c, 0xa2, 0xad, 0xef, + 0x78, 0x87, 0xed, 0x7d, 0x08, 0x16, 0xbe, 0xd8, 0xea, 0x3f, 0x9d, 0xa5, + 0xff, 0x00, 0xe4, 0x9d, 0x37, 0xcc, 0xbd, 0xfe, 0x52, 0x5b, 0xfc, 0x27, + 0xf2, 0xa8, 0xff, 0x00, 0x91, 0x01, 0xff, 0x00, 0x23, 0xf7, 0x29, 0xfe, + 0x10, 0xb7, 0xfc, 0x23, 0xff, 0x00, 0x54, 0xeb, 0x8b, 0xff, 0x00, 0x4c, + 0x85, 0xb4, 0xf3, 0x07, 0xf6, 0x89, 0xfb, 0x80, 0x89, 0x76, 0x7d, 0xe2, + 0x5d, 0xa0, 0xdb, 0x6f, 0xe3, 0xb4, 0xe9, 0x3f, 0x8e, 0xd0, 0x1d, 0x13, + 0xdb, 0xfe, 0x21, 0x3a, 0x74, 0x13, 0xf0, 0x83, 0xe0, 0xeb, 0x4c, 0x35, + 0xcb, 0xc2, 0x0e, 0xe5, 0x84, 0xdc, 0x9e, 0xc4, 0x54, 0xd5, 0xf2, 0xc2, + 0xa9, 0x55, 0xde, 0x6a, 0xf6, 0xf2, 0x9a, 0x9c, 0x39, 0xa7, 0xd0, 0xd3, + 0xf7, 0x09, 0x3f, 0x5a, 0x20, 0x1e, 0x50, 0xee, 0x01, 0x25, 0x44, 0x3a, + 0xae, 0xc8, 0xc5, 0x2e, 0x57, 0x71, 0x71, 0xb2, 0x2a, 0x35, 0x5a, 0x20, + 0xd9, 0x17, 0xd6, 0x3b, 0x14, 0xed, 0x2c, 0xd0, 0x79, 0x22, 0x5a, 0x24, + 0x76, 0x9e, 0xd1, 0xbf, 0xf6, 0x6b, 0x3d, 0xe3, 0x5d, 0x1e, 0xf3, 0x80, + 0x3c, 0x7f, 0xc8, 0x2e, 0x81, 0xec, 0x89, 0xa2, 0x2f, 0x74, 0xd1, 0x9c, + 0xd8, 0x1e, 0x67, 0xe6, 0x7d, 0x7c, 0x3f, 0x51, 0xbf, 0xd6, 0xff, 0x00, + 0x51, 0xd7, 0x6e, 0xca, 0x7e, 0x66, 0x88, 0x7f, 0x86, 0xf1, 0xd6, 0xcc, + 0xa9, 0xf5, 0x8f, 0xd4, 0x43, 0xe8, 0x8f, 0xd4, 0xa7, 0x4f, 0x28, 0x7f, + 0x10, 0x1d, 0x3c, 0x03, 0xf8, 0x80, 0x7c, 0x90, 0x60, 0x5a, 0x0f, 0x87, + 0xee, 0x09, 0xd0, 0xbf, 0xbd, 0x60, 0x3a, 0x40, 0x23, 0xcc, 0x41, 0x5d, + 0xdf, 0xf1, 0xc4, 0xe9, 0x7f, 0x0e, 0x93, 0xf8, 0x0f, 0xc4, 0xb7, 0xf7, + 0x7d, 0x4b, 0x7f, 0x37, 0xd4, 0xbf, 0xf6, 0x7d, 0x4f, 0xe5, 0xfa, 0x25, + 0xbf, 0x83, 0xea, 0x5b, 0xf8, 0x3e, 0xbd, 0x20, 0x27, 0x81, 0xc0, 0x3f, + 0xe2, 0x47, 0x08, 0x76, 0x8e, 0x11, 0xec, 0xa0, 0x5a, 0x0c, 0x69, 0xd3, + 0x69, 0x4b, 0xee, 0xce, 0x75, 0xde, 0xa0, 0x3b, 0xbd, 0xea, 0x75, 0x5e, + 0x52, 0x59, 0xff, 0x00, 0x72, 0x9e, 0xd3, 0xcc, 0x76, 0xc7, 0x98, 0xea, + 0x82, 0x3a, 0x52, 0x0b, 0x10, 0xd4, 0x19, 0xc7, 0x4d, 0x12, 0x63, 0xa4, + 0xa9, 0xe8, 0x78, 0x13, 0x85, 0xf1, 0x03, 0xfe, 0x11, 0xf6, 0x18, 0x2d, + 0xd1, 0x1d, 0x16, 0x6d, 0x2e, 0x6d, 0x07, 0xde, 0x1b, 0x8b, 0xe6, 0x1c, + 0x84, 0x39, 0x32, 0x98, 0x01, 0xbd, 0xe0, 0x9c, 0xfe, 0xd1, 0x03, 0xd7, + 0xdb, 0x9c, 0xad, 0xe2, 0x57, 0xfa, 0xe7, 0xf9, 0x93, 0xfc, 0xa9, 0x57, + 0xe9, 0x9f, 0xe5, 0xcf, 0xf4, 0xd0, 0xff, 0x00, 0xac, 0x87, 0xfe, 0x00, + 0x9c, 0xe8, 0xf5, 0x50, 0xdc, 0xfa, 0x7b, 0xdf, 0xee, 0xa7, 0xfb, 0xbf, + 0x49, 0xff, 0x00, 0xa3, 0x9f, 0xe8, 0xfd, 0x47, 0x85, 0x7d, 0x66, 0xa9, + 0xfe, 0x6c, 0x5b, 0x4f, 0x66, 0x71, 0x7b, 0x11, 0xff, 0x00, 0x95, 0x2e, + 0xfd, 0x33, 0x8e, 0x2a, 0xed, 0x47, 0x69, 0x4c, 0xf7, 0xce, 0xd2, 0x3c, + 0x64, 0x76, 0xb5, 0x1d, 0x7a, 0xfb, 0xc3, 0x5c, 0xb0, 0x6d, 0x56, 0x6e, + 0x96, 0x6e, 0x86, 0x14, 0xb8, 0x7e, 0x95, 0xd4, 0x51, 0x3d, 0x0b, 0x8c, + 0x9a, 0x00, 0x20, 0x74, 0x09, 0xb2, 0x27, 0x20, 0x94, 0x6e, 0x79, 0x88, + 0x6c, 0x7c, 0xc7, 0x7e, 0xde, 0x67, 0x53, 0xef, 0x1f, 0xd7, 0xb1, 0xdc, + 0x8f, 0xf9, 0x73, 0xa3, 0x43, 0x21, 0xd1, 0x7d, 0x27, 0x06, 0x20, 0x48, + 0xfa, 0x1e, 0xfc, 0x3f, 0xdb, 0x80, 0x35, 0xf7, 0x90, 0x2f, 0xca, 0xe5, + 0x0d, 0x03, 0xcf, 0xf5, 0x17, 0xb5, 0x7b, 0x3f, 0xd4, 0xd0, 0x07, 0xfb, + 0xd2, 0x69, 0xde, 0xf7, 0xf5, 0x3f, 0x60, 0x22, 0xdb, 0xb2, 0x5b, 0x55, + 0x92, 0xfb, 0xd2, 0xff, 0xd9 +}; +unsigned int chromatic_jpg_len = 90437; + +#endif /*LV_USE_GLTF*/ diff --git a/src/libs/gltf/gltf_view/assets/lv_gltf_view_shader.c b/src/libs/gltf/gltf_view/assets/lv_gltf_view_shader.c new file mode 100644 index 0000000000..c73c57a341 --- /dev/null +++ b/src/libs/gltf/gltf_view/assets/lv_gltf_view_shader.c @@ -0,0 +1,3517 @@ +#include "lv_gltf_view_shader.h" + +#if LV_USE_GLTF + +#include "../../../../stdlib/lv_sprintf.h" +#include + +static const lv_opengl_shader_t src_includes[] = { + { + "tonemapping.glsl", R"( + + uniform float u_Exposure; + + + const float STANDARD_GAMMA = 2.2; + const float GAMMA = STANDARD_GAMMA; + const float INV_GAMMA = 1.0 / GAMMA; + + + // sRGB => XYZ => D65_2_D60 => AP1 => RRT_SAT + const mat3 ACESInputMat = mat3 + ( + 0.59719, 0.07600, 0.02840, + 0.35458, 0.90834, 0.13383, + 0.04823, 0.01566, 0.83777 + ); + + + // ODT_SAT => XYZ => D60_2_D65 => sRGB + const mat3 ACESOutputMat = mat3 + ( + 1.60475, -0.10208, -0.00327, + -0.53108, 1.10813, -0.07276, + -0.07367, -0.00605, 1.07602 + ); + + + // linear to sRGB approximation + // see http://chilliant.blogspot.com/2012/08/srgb-approximations-for-hlsl.html + vec3 linearTosRGB(vec3 color) + { + return pow(color, vec3(INV_GAMMA)); + } + + + // sRGB to linear approximation + // see http://chilliant.blogspot.com/2012/08/srgb-approximations-for-hlsl.html + vec3 sRGBToLinear(vec3 srgbIn) + { + return vec3(pow(srgbIn.xyz, vec3(GAMMA))); + } + + + vec4 sRGBToLinear(vec4 srgbIn) + { + return vec4(sRGBToLinear(srgbIn.xyz), srgbIn.w); + } + + + // ACES tone map (faster approximation) + // see: https://knarkowicz.wordpress.com/2016/01/06/aces-filmic-tone-mapping-curve/ + vec3 toneMapACES_Narkowicz(vec3 color) + { + const float A = 2.51; + const float B = 0.03; + const float C = 2.43; + const float D = 0.59; + const float E = 0.14; + return clamp((color * (A * color + B)) / (color * (C * color + D) + E), 0.0, 1.0); + } + + + // ACES filmic tone map approximation + // see https://github.com/TheRealMJP/BakingLab/blob/master/BakingLab/ACES.hlsl + vec3 RRTAndODTFit(vec3 color) + { + vec3 a = color * (color + 0.0245786) - 0.000090537; + vec3 b = color * (0.983729 * color + 0.4329510) + 0.238081; + return a / b; + } + + + // tone mapping + vec3 toneMapACES_Hill(vec3 color) + { + color = ACESInputMat * color; + + // Apply RRT and ODT + color = RRTAndODTFit(color); + + color = ACESOutputMat * color; + + // Clamp to [0, 1] + color = clamp(color, 0.0, 1.0); + + return color; + } + + // Khronos PBR neutral tone mapping + #ifdef TONEMAP_KHR_PBR_NEUTRAL + vec3 toneMap_KhronosPbrNeutral( vec3 color ) + { + const float startCompression = 0.8 - 0.04; + const float desaturation = 0.15; + + float x = min(color.r, min(color.g, color.b)); + float offset = x < 0.08 ? x - 6.25 * x * x : 0.04; + color -= offset; + + float peak = max(color.r, max(color.g, color.b)); + if (peak < startCompression) return color; + + const float d = 1. - startCompression; + float newPeak = 1. - d * d / (peak + d - startCompression); + color *= newPeak / peak; + + float g = 1. - 1. / (desaturation * (peak - newPeak) + 1.); + return mix(color, newPeak * vec3(1, 1, 1), g); + } + #endif + + vec3 toneMap(vec3 color) + { + color *= u_Exposure; + + #ifdef TONEMAP_ACES_NARKOWICZ + color = toneMapACES_Narkowicz(color); + #endif + + #ifdef TONEMAP_ACES_HILL + color = toneMapACES_Hill(color); + #endif + + #ifdef TONEMAP_ACES_HILL_EXPOSURE_BOOST + // boost exposure as discussed in https://github.com/mrdoob/three.js/pull/19621 + // this factor is based on the exposure correction of Krzysztof Narkowicz in his + // implemetation of ACES tone mapping + color /= 0.6; + color = toneMapACES_Hill(color); + #endif + + #ifdef TONEMAP_KHR_PBR_NEUTRAL + color = toneMap_KhronosPbrNeutral(color); + #endif + + return linearTosRGB(color); + } + + )" + }, + { + "textures1.glsl", R"( + + // IBL + + uniform int u_MipCount; + uniform samplerCube u_LambertianEnvSampler; + uniform samplerCube u_GGXEnvSampler; + uniform sampler2D u_GGXLUT; + uniform samplerCube u_CharlieEnvSampler; + uniform sampler2D u_CharlieLUT; + uniform sampler2D u_SheenELUT; + uniform mat3 u_EnvRotation; + + + // General Material + + + uniform sampler2D u_NormalSampler; + uniform float u_NormalScale; + uniform int u_NormalUVSet; + uniform mat3 u_NormalUVTransform; + + uniform vec3 u_EmissiveFactor; + uniform sampler2D u_EmissiveSampler; + uniform int u_EmissiveUVSet; + uniform mat3 u_EmissiveUVTransform; + + uniform sampler2D u_OcclusionSampler; + uniform int u_OcclusionUVSet; + uniform float u_OcclusionStrength; + uniform mat3 u_OcclusionUVTransform; + + + in vec2 v_texcoord_0; + in vec2 v_texcoord_1; + + + vec2 getNormalUV() + { + vec3 uv = vec3(u_NormalUVSet < 1 ? v_texcoord_0 : v_texcoord_1, 1.0); + + #ifdef HAS_NORMAL_UV_TRANSFORM + uv = u_NormalUVTransform * uv; + #endif + + return uv.xy; + } + + + vec2 getEmissiveUV() + { + vec3 uv = vec3(u_EmissiveUVSet < 1 ? v_texcoord_0 : v_texcoord_1, 1.0); + + #ifdef HAS_EMISSIVE_UV_TRANSFORM + uv = u_EmissiveUVTransform * uv; + #endif + + return uv.xy; + } + + + vec2 getOcclusionUV() + { + vec3 uv = vec3(u_OcclusionUVSet < 1 ? v_texcoord_0 : v_texcoord_1, 1.0); + + #ifdef HAS_OCCLUSION_UV_TRANSFORM + uv = u_OcclusionUVTransform * uv; + #endif + + return uv.xy; + } + + + // MK TEMP - Added special optimized handling for unlit materials + #ifdef MATERIAL_UNLIT + uniform sampler2D u_BaseColorSampler; + uniform int u_BaseColorUVSet; + uniform mat3 u_BaseColorUVTransform; + + vec2 getBaseColorUV() + { + vec3 uv = vec3(u_BaseColorUVSet < 1 ? v_texcoord_0 : v_texcoord_1, 1.0); + + #ifdef HAS_BASECOLOR_UV_TRANSFORM + uv = u_BaseColorUVTransform * uv; + #endif + + return uv.xy; + } + #else + // Metallic Roughness Material + #ifdef MATERIAL_METALLICROUGHNESS + + uniform sampler2D u_BaseColorSampler; + uniform int u_BaseColorUVSet; + uniform mat3 u_BaseColorUVTransform; + + uniform sampler2D u_MetallicRoughnessSampler; + uniform int u_MetallicRoughnessUVSet; + uniform mat3 u_MetallicRoughnessUVTransform; + + vec2 getBaseColorUV() + { + vec3 uv = vec3(u_BaseColorUVSet < 1 ? v_texcoord_0 : v_texcoord_1, 1.0); + + #ifdef HAS_BASECOLOR_UV_TRANSFORM + uv = u_BaseColorUVTransform * uv; + #endif + + return uv.xy; + } + + vec2 getMetallicRoughnessUV() + { + vec3 uv = vec3(u_MetallicRoughnessUVSet < 1 ? v_texcoord_0 : v_texcoord_1, 1.0); + + #ifdef HAS_METALLICROUGHNESS_UV_TRANSFORM + uv = u_MetallicRoughnessUVTransform * uv; + #endif + + return uv.xy; + } + + #endif + #endif + + )" + }, + { + "textures2.glsl", R"( + // Specular Glossiness Material + + + #ifdef MATERIAL_SPECULARGLOSSINESS + + uniform sampler2D u_DiffuseSampler; + uniform int u_DiffuseUVSet; + uniform mat3 u_DiffuseUVTransform; + + uniform sampler2D u_SpecularGlossinessSampler; + uniform int u_SpecularGlossinessUVSet; + uniform mat3 u_SpecularGlossinessUVTransform; + + + vec2 getSpecularGlossinessUV() + { + vec3 uv = vec3(u_SpecularGlossinessUVSet < 1 ? v_texcoord_0 : v_texcoord_1, 1.0); + + #ifdef HAS_SPECULARGLOSSINESS_UV_TRANSFORM + uv = u_SpecularGlossinessUVTransform * uv; + #endif + + return uv.xy; + } + + vec2 getDiffuseUV() + { + vec3 uv = vec3(u_DiffuseUVSet < 1 ? v_texcoord_0 : v_texcoord_1, 1.0); + + #ifdef HAS_DIFFUSE_UV_TRANSFORM + uv = u_DiffuseUVTransform * uv; + #endif + + return uv.xy; + } + + #endif + + + // Clearcoat Material + + + #ifdef MATERIAL_CLEARCOAT + + uniform sampler2D u_ClearcoatSampler; + uniform int u_ClearcoatUVSet; + uniform mat3 u_ClearcoatUVTransform; + + uniform sampler2D u_ClearcoatRoughnessSampler; + uniform int u_ClearcoatRoughnessUVSet; + uniform mat3 u_ClearcoatRoughnessUVTransform; + + uniform sampler2D u_ClearcoatNormalSampler; + uniform int u_ClearcoatNormalUVSet; + uniform mat3 u_ClearcoatNormalUVTransform; + uniform float u_ClearcoatNormalScale; + + + vec2 getClearcoatUV() + { + vec3 uv = vec3(u_ClearcoatUVSet < 1 ? v_texcoord_0 : v_texcoord_1, 1.0); + #ifdef HAS_CLEARCOAT_UV_TRANSFORM + uv = u_ClearcoatUVTransform * uv; + #endif + return uv.xy; + } + + vec2 getClearcoatRoughnessUV() + { + vec3 uv = vec3(u_ClearcoatRoughnessUVSet < 1 ? v_texcoord_0 : v_texcoord_1, 1.0); + #ifdef HAS_CLEARCOATROUGHNESS_UV_TRANSFORM + uv = u_ClearcoatRoughnessUVTransform * uv; + #endif + return uv.xy; + } + + vec2 getClearcoatNormalUV() + { + vec3 uv = vec3(u_ClearcoatNormalUVSet < 1 ? v_texcoord_0 : v_texcoord_1, 1.0); + #ifdef HAS_CLEARCOATNORMAL_UV_TRANSFORM + uv = u_ClearcoatNormalUVTransform * uv; + #endif + return uv.xy; + } + + #endif + + + // Sheen Material + + + #ifdef MATERIAL_SHEEN + + uniform sampler2D u_SheenColorSampler; + uniform int u_SheenColorUVSet; + uniform mat3 u_SheenColorUVTransform; + uniform sampler2D u_SheenRoughnessSampler; + uniform int u_SheenRoughnessUVSet; + uniform mat3 u_SheenRoughnessUVTransform; + + )" + }, + { + "textures3.glsl", R"( + vec2 getSheenColorUV() + { + vec3 uv = vec3(u_SheenColorUVSet < 1 ? v_texcoord_0 : v_texcoord_1, 1.0); + #ifdef HAS_SHEENCOLOR_UV_TRANSFORM + uv = u_SheenColorUVTransform * uv; + #endif + return uv.xy; + } + + vec2 getSheenRoughnessUV() + { + vec3 uv = vec3(u_SheenRoughnessUVSet < 1 ? v_texcoord_0 : v_texcoord_1, 1.0); + #ifdef HAS_SHEENROUGHNESS_UV_TRANSFORM + uv = u_SheenRoughnessUVTransform * uv; + #endif + return uv.xy; + } + + #endif + + + // Specular Material + + + #ifdef MATERIAL_SPECULAR + + uniform sampler2D u_SpecularSampler; + uniform int u_SpecularUVSet; + uniform mat3 u_SpecularUVTransform; + uniform sampler2D u_SpecularColorSampler; + uniform int u_SpecularColorUVSet; + uniform mat3 u_SpecularColorUVTransform; + + + vec2 getSpecularUV() + { + vec3 uv = vec3(u_SpecularUVSet < 1 ? v_texcoord_0 : v_texcoord_1, 1.0); + #ifdef HAS_SPECULAR_UV_TRANSFORM + uv = u_SpecularUVTransform * uv; + #endif + return uv.xy; + } + + vec2 getSpecularColorUV() + { + vec3 uv = vec3(u_SpecularColorUVSet < 1 ? v_texcoord_0 : v_texcoord_1, 1.0); + #ifdef HAS_SPECULARCOLOR_UV_TRANSFORM + uv = u_SpecularColorUVTransform * uv; + #endif + return uv.xy; + } + + #endif + + + // Transmission Material + + + #ifdef MATERIAL_TRANSMISSION + + uniform sampler2D u_TransmissionSampler; + uniform int u_TransmissionUVSet; + uniform mat3 u_TransmissionUVTransform; + uniform sampler2D u_TransmissionFramebufferSampler; + uniform ivec2 u_TransmissionFramebufferSize; + + + vec2 getTransmissionUV() + { + vec3 uv = vec3(u_TransmissionUVSet < 1 ? v_texcoord_0 : v_texcoord_1, 1.0); + #ifdef HAS_TRANSMISSION_UV_TRANSFORM + uv = u_TransmissionUVTransform * uv; + #endif + return uv.xy; + } + + #endif + + + // Volume Material + + + #ifdef MATERIAL_VOLUME + + uniform sampler2D u_ThicknessSampler; + uniform int u_ThicknessUVSet; + uniform mat3 u_ThicknessUVTransform; + + + )" + }, + { + "textures4.glsl", R"( + vec2 getThicknessUV() + { + vec3 uv = vec3(u_ThicknessUVSet < 1 ? v_texcoord_0 : v_texcoord_1, 1.0); + #ifdef HAS_THICKNESS_UV_TRANSFORM + uv = u_ThicknessUVTransform * uv; + #endif + return uv.xy; + } + + #endif + + + // Iridescence + + + #ifdef MATERIAL_IRIDESCENCE + + uniform sampler2D u_IridescenceSampler; + uniform int u_IridescenceUVSet; + uniform mat3 u_IridescenceUVTransform; + + uniform sampler2D u_IridescenceThicknessSampler; + uniform int u_IridescenceThicknessUVSet; + uniform mat3 u_IridescenceThicknessUVTransform; + + + vec2 getIridescenceUV() + { + vec3 uv = vec3(u_IridescenceUVSet < 1 ? v_texcoord_0 : v_texcoord_1, 1.0); + #ifdef HAS_IRIDESCENCE_UV_TRANSFORM + uv = u_IridescenceUVTransform * uv; + #endif + return uv.xy; + } + + vec2 getIridescenceThicknessUV() + { + vec3 uv = vec3(u_IridescenceThicknessUVSet < 1 ? v_texcoord_0 : v_texcoord_1, 1.0); + #ifdef HAS_IRIDESCENCETHICKNESS_UV_TRANSFORM + uv = u_IridescenceThicknessUVTransform * uv; + #endif + return uv.xy; + } + + #endif + + + // Diffuse Transmission + + #ifdef MATERIAL_DIFFUSE_TRANSMISSION + + uniform sampler2D u_DiffuseTransmissionSampler; + uniform int u_DiffuseTransmissionUVSet; + uniform mat3 u_DiffuseTransmissionUVTransform; + + uniform sampler2D u_DiffuseTransmissionColorSampler; + uniform int u_DiffuseTransmissionColorUVSet; + uniform mat3 u_DiffuseTransmissionColorUVTransform; + + + vec2 getDiffuseTransmissionUV() + { + vec3 uv = vec3(u_DiffuseTransmissionUVSet < 1 ? v_texcoord_0 : v_texcoord_1, 1.0); + #ifdef HAS_DIFFUSETRANSMISSION_UV_TRANSFORM + uv = u_DiffuseTransmissionUVTransform * uv; + #endif + return uv.xy; + } + + vec2 getDiffuseTransmissionColorUV() + { + vec3 uv = vec3(u_DiffuseTransmissionColorUVSet < 1 ? v_texcoord_0 : v_texcoord_1, 1.0); + #ifdef HAS_DIFFUSETRANSMISSIONCOLOR_UV_TRANSFORM + uv = u_DiffuseTransmissionColorUVTransform * uv; + #endif + return uv.xy; + } + + #endif + + // Anisotropy + + #ifdef MATERIAL_ANISOTROPY + + uniform sampler2D u_AnisotropySampler; + uniform int u_AnisotropyUVSet; + uniform mat3 u_AnisotropyUVTransform; + + vec2 getAnisotropyUV() + { + vec3 uv = vec3(u_AnisotropyUVSet < 1 ? v_texcoord_0 : v_texcoord_1, 1.0); + #ifdef HAS_ANISOTROPY_UV_TRANSFORM + uv = u_AnisotropyUVTransform * uv; + #endif + return uv.xy; + } + + #endif + + )" + }, + { + "functions.glsl", R"( + + const float M_PI = 3.141592653589793; + + + in vec3 v_Position; + + + #ifdef HAS_NORMAL_VEC3 + #ifdef HAS_TANGENT_VEC4 + in mat3 v_TBN; + #else + in vec3 v_Normal; + #endif + #endif + + + #ifdef HAS_COLOR_0_VEC3 + in vec3 v_Color; + #endif + #ifdef HAS_COLOR_0_VEC4 + in vec4 v_Color; + #endif + + + vec4 getVertexColor() + { + vec4 color = vec4(1.0); + + #ifdef HAS_COLOR_0_VEC3 + color.rgb = v_Color.rgb; + #endif + #ifdef HAS_COLOR_0_VEC4 + color = v_Color; + #endif + + return color; + } + + + struct NormalInfo { + vec3 ng; // Geometry normal + vec3 t; // Geometry tangent + vec3 b; // Geometry bitangent + vec3 n; // Shading normal + vec3 ntex; // Normal from texture, scaling is accounted for. + }; + + + float clampedDot(vec3 x, vec3 y) + { + return clamp(dot(x, y), 0.0, 1.0); + } + + + float max3(vec3 v) + { + return max(max(v.x, v.y), v.z); + } + + + float sq(float t) + { + return t * t; + } + + vec2 sq(vec2 t) + { + return t * t; + } + + vec3 sq(vec3 t) + { + return t * t; + } + + vec4 sq(vec4 t) + { + return t * t; + } + + + float applyIorToRoughness(float roughness, float ior) + { + // Scale roughness with IOR so that an IOR of 1.0 results in no microfacet refraction and + // an IOR of 1.5 results in the default amount of microfacet refraction. + return roughness * clamp(ior * 2.0 - 2.0, 0.0, 1.0); + } + + vec3 rgb_mix(vec3 base, vec3 layer, vec3 rgb_alpha) + { + float rgb_alpha_max = max(rgb_alpha.r, max(rgb_alpha.g, rgb_alpha.b)); + return (1.0 - rgb_alpha_max) * base + rgb_alpha * layer; + } + + + )" + }, + { + "brdf1.glsl", R"( + // + // Fresnel + // + // http://graphicrants.blogspot.com/2013/08/specular-brdf-reference.html + // https://github.com/wdas/brdf/tree/master/src/brdfs + // https://google.github.io/filament/Filament.md.html + // + + // The following equation models the Fresnel reflectance term of the spec equation (aka F()) + // Implementation of fresnel from [4], Equation 15 + vec3 F_Schlick(vec3 f0, vec3 f90, float VdotH) + { + return f0 + (f90 - f0) * pow(clamp(1.0 - VdotH, 0.0, 1.0), 5.0); + } + + float F_Schlick(float f0, float f90, float VdotH) + { + float x = clamp(1.0 - VdotH, 0.0, 1.0); + float x2 = x * x; + float x5 = x * x2 * x2; + return f0 + (f90 - f0) * x5; + } + + float F_Schlick(float f0, float VdotH) + { + float f90 = 1.0; //clamp(50.0 * f0, 0.0, 1.0); + return F_Schlick(f0, f90, VdotH); + } + + vec3 F_Schlick(vec3 f0, float f90, float VdotH) + { + float x = clamp(1.0 - VdotH, 0.0, 1.0); + float x2 = x * x; + float x5 = x * x2 * x2; + return f0 + (f90 - f0) * x5; + } + + vec3 F_Schlick(vec3 f0, float VdotH) + { + float f90 = 1.0; //clamp(dot(f0, vec3(50.0 * 0.33)), 0.0, 1.0); + return F_Schlick(f0, f90, VdotH); + } + + vec3 Schlick_to_F0(vec3 f, vec3 f90, float VdotH) { + float x = clamp(1.0 - VdotH, 0.0, 1.0); + float x2 = x * x; + float x5 = clamp(x * x2 * x2, 0.0, 0.9999); + + return (f - f90 * x5) / (1.0 - x5); + } + + float Schlick_to_F0(float f, float f90, float VdotH) { + float x = clamp(1.0 - VdotH, 0.0, 1.0); + float x2 = x * x; + float x5 = clamp(x * x2 * x2, 0.0, 0.9999); + + return (f - f90 * x5) / (1.0 - x5); + } + + vec3 Schlick_to_F0(vec3 f, float VdotH) { + return Schlick_to_F0(f, vec3(1.0), VdotH); + } + + float Schlick_to_F0(float f, float VdotH) { + return Schlick_to_F0(f, 1.0, VdotH); + } + + )" + }, + { + "brdf2.glsl", R"( + // Smith Joint GGX + // Note: Vis = G / (4 * NdotL * NdotV) + // see Eric Heitz. 2014. Understanding the Masking-Shadowing Function in Microfacet-Based BRDFs. Journal of Computer Graphics Techniques, 3 + // see Real-Time Rendering. Page 331 to 336. + // see https://google.github.io/filament/Filament.md.html#materialsystem/specularbrdf/geometricshadowing(specularg) + float V_GGX(float NdotL, float NdotV, float alphaRoughness) + { + float alphaRoughnessSq = alphaRoughness * alphaRoughness; + + float GGXV = NdotL * sqrt(NdotV * NdotV * (1.0 - alphaRoughnessSq) + alphaRoughnessSq); + float GGXL = NdotV * sqrt(NdotL * NdotL * (1.0 - alphaRoughnessSq) + alphaRoughnessSq); + + float GGX = GGXV + GGXL; + if (GGX > 0.0) + { + return 0.5 / GGX; + } + return 0.0; + } + + + // The following equation(s) model the distribution of microfacet normals across the area being drawn (aka D()) + // Implementation from "Average Irregularity Representation of a Roughened Surface for Ray Reflection" by T. S. Trowbridge, and K. P. Reitz + // Follows the distribution function recommended in the SIGGRAPH 2013 course notes from EPIC Games [1], Equation 3. + float D_GGX(float NdotH, float alphaRoughness) + { + float alphaRoughnessSq = alphaRoughness * alphaRoughness; + float f = (NdotH * NdotH) * (alphaRoughnessSq - 1.0) + 1.0; + return alphaRoughnessSq / (M_PI * f * f); + } + + + float lambdaSheenNumericHelper(float x, float alphaG) + { + float oneMinusAlphaSq = (1.0 - alphaG) * (1.0 - alphaG); + float a = mix(21.5473, 25.3245, oneMinusAlphaSq); + float b = mix(3.82987, 3.32435, oneMinusAlphaSq); + float c = mix(0.19823, 0.16801, oneMinusAlphaSq); + float d = mix(-1.97760, -1.27393, oneMinusAlphaSq); + float e = mix(-4.32054, -4.85967, oneMinusAlphaSq); + return a / (1.0 + b * pow(x, c)) + d * x + e; + } + + + float lambdaSheen(float cosTheta, float alphaG) + { + if (abs(cosTheta) < 0.5) + { + return exp(lambdaSheenNumericHelper(cosTheta, alphaG)); + } + else + { + return exp(2.0 * lambdaSheenNumericHelper(0.5, alphaG) - lambdaSheenNumericHelper(1.0 - cosTheta, alphaG)); + } + } + + + float V_Sheen(float NdotL, float NdotV, float sheenRoughness) + { + sheenRoughness = max(sheenRoughness, 0.000001); //clamp (0,1] + float alphaG = sheenRoughness * sheenRoughness; + + return clamp(1.0 / ((1.0 + lambdaSheen(NdotV, alphaG) + lambdaSheen(NdotL, alphaG)) * + (4.0 * NdotV * NdotL)), 0.0, 1.0); + } + + + //Sheen implementation------------------------------------------------------------------------------------- + // See https://github.com/sebavan/glTF/tree/KHR_materials_sheen/extensions/2.0/Khronos/KHR_materials_sheen + + // Estevez and Kulla http://www.aconty.com/pdf/s2017_pbs_imageworks_sheen.pdf + float D_Charlie(float sheenRoughness, float NdotH) + { + sheenRoughness = max(sheenRoughness, 0.000001); //clamp (0,1] + float alphaG = sheenRoughness * sheenRoughness; + float invR = 1.0 / alphaG; + float cos2h = NdotH * NdotH; + float sin2h = 1.0 - cos2h; + return (2.0 + invR) * pow(sin2h, invR * 0.5) / (2.0 * M_PI); + } + )" + }, + { + "brdf3.glsl", R"( + + //https://github.com/KhronosGroup/glTF/tree/master/specification/2.0#acknowledgments AppendixB + vec3 BRDF_lambertian(vec3 diffuseColor) + { + // see https://seblagarde.wordpress.com/2012/01/08/pi-or-not-to-pi-in-game-lighting-equation/ + return (diffuseColor / M_PI); + } + + // https://github.com/KhronosGroup/glTF/tree/master/specification/2.0#acknowledgments AppendixB + vec3 BRDF_specularGGX(float alphaRoughness, float NdotL, float NdotV, float NdotH) + { + float Vis = V_GGX(NdotL, NdotV, alphaRoughness); + float D = D_GGX(NdotH, alphaRoughness); + + return vec3(Vis * D); + } + + + #ifdef MATERIAL_ANISOTROPY + // GGX Distribution Anisotropic (Same as Babylon.js) + // https://blog.selfshadow.com/publications/s2012-shading-course/burley/s2012_pbs_disney_brdf_notes_v3.pdf Addenda + float D_GGX_anisotropic(float NdotH, float TdotH, float BdotH, float anisotropy, float at, float ab) + { + float a2 = at * ab; + vec3 f = vec3(ab * TdotH, at * BdotH, a2 * NdotH); + float w2 = a2 / dot(f, f); + return a2 * w2 * w2 / M_PI; + } + + // GGX Mask/Shadowing Anisotropic (Same as Babylon.js - smithVisibility_GGXCorrelated_Anisotropic) + // Heitz http://jcgt.org/published/0003/02/03/paper.pdf + float V_GGX_anisotropic(float NdotL, float NdotV, float BdotV, float TdotV, float TdotL, float BdotL, float at, float ab) + { + float GGXV = NdotL * length(vec3(at * TdotV, ab * BdotV, NdotV)); + float GGXL = NdotV * length(vec3(at * TdotL, ab * BdotL, NdotL)); + float v = 0.5 / (GGXV + GGXL); + return clamp(v, 0.0, 1.0); + } + + vec3 BRDF_specularGGXAnisotropy(float alphaRoughness, float anisotropy, vec3 n, vec3 v, vec3 l, vec3 h, vec3 t, vec3 b) + { + // Roughness along the anisotropy bitangent is the material roughness, while the tangent roughness increases with anisotropy. + float at = mix(alphaRoughness, 1.0, anisotropy * anisotropy); + float ab = clamp(alphaRoughness, 0.001, 1.0); + + float NdotL = clamp(dot(n, l), 0.0, 1.0); + float NdotH = clamp(dot(n, h), 0.001, 1.0); + float NdotV = dot(n, v); + + float V = V_GGX_anisotropic(NdotL, NdotV, dot(b, v), dot(t, v), dot(t, l), dot(b, l), at, ab); + float D = D_GGX_anisotropic(NdotH, dot(t, h), dot(b, h), anisotropy, at, ab); + + return vec3(V * D); + } + #endif + + + // f_sheen + vec3 BRDF_specularSheen(vec3 sheenColor, float sheenRoughness, float NdotL, float NdotV, float NdotH) + { + float sheenDistribution = D_Charlie(sheenRoughness, NdotH); + float sheenVisibility = V_Sheen(NdotL, NdotV, sheenRoughness); + return sheenColor * sheenDistribution * sheenVisibility; + } + )" + }, + { + "punctual1.glsl", R"( + struct Light + { + vec3 direction; + float range; + + vec3 color; + float intensity; + + vec3 position; + float innerConeCos; + + float outerConeCos; + int type; + }; + + const int LightType_Directional = 0; + const int LightType_Point = 1; + const int LightType_Spot = 2; + + + #ifdef USE_PUNCTUAL + //Light u_Lights[LIGHT_COUNT + 1]; //Array [0] is not allowed + uniform Light u_Lights[LIGHT_COUNT + 1]; //Array [0] is not allowed + #endif + + float getRangeAttenuation(float range, float distance) + { + if (range <= 0.0) + { + // negative range means unlimited + return 1.0 / pow(distance, 2.0); + } + return max(min(1.0 - pow(distance / range, 4.0), 1.0), 0.0) / pow(distance, 2.0); + } + float getSpotAttenuation(vec3 pointToLight, vec3 spotDirection, float outerConeCos, float innerConeCos) + { + float actualCos = dot(normalize(spotDirection), normalize(-pointToLight)); + if (actualCos > outerConeCos) + { + if (actualCos < innerConeCos) + { + float angularAttenuation = (actualCos - outerConeCos) / (innerConeCos - outerConeCos); + return angularAttenuation * angularAttenuation; + } + return 1.0; + } + return 0.0; + } + vec3 getLighIntensity(Light light, vec3 pointToLight) + { + float rangeAttenuation = 1.0; + float spotAttenuation = 1.0; + + if (light.type != LightType_Directional) + { + rangeAttenuation = getRangeAttenuation(light.range, length(pointToLight)); + } + if (light.type == LightType_Spot) + { + spotAttenuation = getSpotAttenuation(pointToLight, light.direction, light.outerConeCos, light.innerConeCos); + } + + return rangeAttenuation * spotAttenuation * light.intensity * light.color; + } + + )" + }, + { + "punctual2.glsl", R"( + vec3 getPunctualRadianceTransmission(vec3 normal, vec3 view, vec3 pointToLight, float alphaRoughness, + vec3 baseColor, float ior) + { + float transmissionRougness = applyIorToRoughness(alphaRoughness, ior); + + vec3 n = normalize(normal); + vec3 v = normalize(view); + vec3 l = normalize(pointToLight); + vec3 l_mirror = normalize(l + 2.0*n*dot(-l, n)); + vec3 h = normalize(l_mirror + v); + + float D = D_GGX(clamp(dot(n, h), 0.0, 1.0), transmissionRougness); + float Vis = V_GGX(clamp(dot(n, l_mirror), 0.0, 1.0), clamp(dot(n, v), 0.0, 1.0), transmissionRougness); + + // Transmission BTDF + return baseColor * D * Vis; + } + + + vec3 getPunctualRadianceClearCoat(vec3 clearcoatNormal, vec3 v, vec3 l, vec3 h, float VdotH, vec3 f0, vec3 f90, float clearcoatRoughness) + { + float NdotL = clampedDot(clearcoatNormal, l); + float NdotV = clampedDot(clearcoatNormal, v); + float NdotH = clampedDot(clearcoatNormal, h); + return NdotL * BRDF_specularGGX(clearcoatRoughness * clearcoatRoughness, NdotL, NdotV, NdotH); + } + + + vec3 getPunctualRadianceSheen(vec3 sheenColor, float sheenRoughness, float NdotL, float NdotV, float NdotH) + { + return NdotL * BRDF_specularSheen(sheenColor, sheenRoughness, NdotL, NdotV, NdotH); + } + + + vec3 applyVolumeAttenuation(vec3 radiance, float transmissionDistance, vec3 attenuationColor, float attenuationDistance) + { + if (attenuationDistance == 0.0) + { + // Attenuation distance is +∞ (which we indicate by zero), i.e. the transmitted color is not attenuated at all. + return radiance; + } + else + { + vec3 transmittance = pow(attenuationColor, vec3(transmissionDistance / attenuationDistance)); + return transmittance * radiance; + } + } + + + vec3 getVolumeTransmissionRay(vec3 n, vec3 v, float thickness, float ior, mat4 modelMatrix) + { + vec3 refractionVector = refract(-v, normalize(n), 1.0 / ior); + vec3 modelScale; + modelScale.x = length(vec3(modelMatrix[0].xyz)); + modelScale.y = length(vec3(modelMatrix[1].xyz)); + modelScale.z = length(vec3(modelMatrix[2].xyz)); + return normalize(refractionVector) * thickness * modelScale; + } + + )" + }, + { + "ibl1.glsl", R"( + + uniform float u_EnvIntensity; + + vec3 getDiffuseLight(vec3 n) + { + // MK TEMP (for some reason, this one still seems to have positive effect - check for inverted Y at IBL diffuse generation phase) + // n.y *= -1.0; + vec4 textureSample = texture(u_LambertianEnvSampler, u_EnvRotation * n); + textureSample.rgb *= u_EnvIntensity; + return textureSample.rgb; + } + + vec4 getSpecularSample(vec3 reflection, float lod) + { + vec4 textureSample = textureLod(u_GGXEnvSampler, u_EnvRotation * reflection, lod); + textureSample.rgb *= u_EnvIntensity; + return textureSample; + } + + vec4 getSheenSample(vec3 reflection, float lod) + { + vec4 textureSample = textureLod(u_CharlieEnvSampler, u_EnvRotation * reflection, lod); + textureSample.rgb *= u_EnvIntensity; + return textureSample; + } + + vec3 getIBLGGXFresnel(vec3 n, vec3 v, float roughness, vec3 F0, float specularWeight) + { + // see https://bruop.github.io/ibl/#single_scattering_results at Single Scattering Results + // Roughness dependent fresnel, from Fdez-Aguera + float NdotV = clampedDot(n, v); + vec2 brdfSamplePoint = clamp(vec2(NdotV, roughness), vec2(0.0, 0.0), vec2(1.0, 1.0)); + vec2 f_ab = texture(u_GGXLUT, brdfSamplePoint).rg; + vec3 Fr = max(vec3(1.0 - roughness), F0) - F0; + vec3 k_S = F0 + Fr * pow(1.0 - NdotV, 5.0); + vec3 FssEss = specularWeight * (k_S * f_ab.x + f_ab.y); + + // Multiple scattering, from Fdez-Aguera + float Ems = (1.0 - (f_ab.x + f_ab.y)); + vec3 F_avg = specularWeight * (F0 + (1.0 - F0) / 21.0); + vec3 FmsEms = Ems * FssEss * F_avg / (1.0 - F_avg * Ems); + + return FssEss + FmsEms; + } + + vec3 getIBLRadianceGGX(vec3 n, vec3 v, float roughness) + { + float NdotV = clampedDot(n, v); + float lod = roughness * float(u_MipCount - 1); + + vec3 reflection = normalize(reflect(-v, n)); + vec4 specularSample = getSpecularSample(reflection, lod); + + vec3 specularLight = specularSample.rgb; + + return specularLight; + } + + + #ifdef MATERIAL_TRANSMISSION + vec3 getTransmissionSample(vec2 fragCoord, float roughness, float ior) + { + float framebufferLod = log2(float(u_TransmissionFramebufferSize.x)) * applyIorToRoughness(roughness, ior); + vec3 transmittedLight = textureLod(u_TransmissionFramebufferSampler, fragCoord.xy, framebufferLod).rgb; + + return transmittedLight; + } + #endif + + #ifdef MATERIAL_TRANSMISSION + vec3 getIBLVolumeRefraction(vec3 n, vec3 v, float perceptualRoughness, vec3 baseColor, vec3 position, mat4 modelMatrix, + mat4 viewMatrix, mat4 projMatrix, float ior, float thickness, vec3 attenuationColor, float attenuationDistance, float dispersion) + { + )" + }, + { + "ibl2.glsl", R"( + + #ifdef MATERIAL_DISPERSION + // Dispersion will spread out the ior values for each r,g,b channel + float halfSpread = (ior - 1.0) * 0.025 * dispersion; + vec3 iors = vec3(ior - halfSpread, ior, ior + halfSpread); + + vec3 transmittedLight; + float transmissionRayLength; + for (int i = 0; i < 3; i++) + { + vec3 transmissionRay = getVolumeTransmissionRay(n, v, thickness, iors[i], modelMatrix); + // TODO: taking length of blue ray, ideally we would take the length of the green ray. For now overwriting seems ok + transmissionRayLength = length(transmissionRay); + vec3 refractedRayExit = position + transmissionRay; + + // Project refracted vector on the framebuffer, while mapping to normalized device coordinates. + vec4 ndcPos = projMatrix * viewMatrix * vec4(refractedRayExit, 1.0); + vec2 refractionCoords = ndcPos.xy / ndcPos.w; + refractionCoords += 1.0; + refractionCoords /= 2.0; + + // Sample framebuffer to get pixel the refracted ray hits for this color channel. + transmittedLight[i] = getTransmissionSample(refractionCoords, perceptualRoughness, iors[i])[i]; + } + #else + vec3 transmissionRay = getVolumeTransmissionRay(n, v, thickness, ior, modelMatrix); + float transmissionRayLength = length(transmissionRay); + vec3 refractedRayExit = position + transmissionRay; + + // Project refracted vector on the framebuffer, while mapping to normalized device coordinates. + vec4 ndcPos = projMatrix * viewMatrix * vec4(refractedRayExit, 1.0); + vec2 refractionCoords = ndcPos.xy / ndcPos.w; + refractionCoords += 1.0; + refractionCoords /= 2.0; + + // Sample framebuffer to get pixel the refracted ray hits. + vec3 transmittedLight = getTransmissionSample(refractionCoords, perceptualRoughness, ior); + + #endif // MATERIAL_DISPERSION + vec3 attenuatedColor = applyVolumeAttenuation(transmittedLight, transmissionRayLength, attenuationColor, attenuationDistance); + + return attenuatedColor * baseColor; + } + #endif + + + #ifdef MATERIAL_ANISOTROPY + vec3 getIBLRadianceAnisotropy(vec3 n, vec3 v, float roughness, float anisotropy, vec3 anisotropyDirection) + { + float NdotV = clampedDot(n, v); + + float tangentRoughness = mix(roughness, 1.0, anisotropy * anisotropy); + vec3 anisotropicTangent = cross(anisotropyDirection, v); + vec3 anisotropicNormal = cross(anisotropicTangent, anisotropyDirection); + float bendFactor = 1.0 - anisotropy * (1.0 - roughness); + float bendFactorPow4 = bendFactor * bendFactor * bendFactor * bendFactor; + vec3 bentNormal = normalize(mix(anisotropicNormal, n, bendFactorPow4)); + + float lod = roughness * float(u_MipCount - 1); + vec3 reflection = normalize(reflect(-v, bentNormal)); + + vec4 specularSample = getSpecularSample(reflection, lod); + + vec3 specularLight = specularSample.rgb; + + return specularLight; + } + #endif + + + vec3 getIBLRadianceCharlie(vec3 n, vec3 v, float sheenRoughness, vec3 sheenColor) + { + float NdotV = clampedDot(n, v); + float lod = sheenRoughness * float(u_MipCount - 1); + vec3 reflection = normalize(reflect(-v, n)); + + vec2 brdfSamplePoint = clamp(vec2(NdotV, sheenRoughness), vec2(0.0, 0.0), vec2(1.0, 1.0)); + float brdf = texture(u_CharlieLUT, brdfSamplePoint).b; + vec4 sheenSample = getSheenSample(reflection, lod); + + vec3 sheenLight = sheenSample.rgb; + return sheenLight * sheenColor * brdf; + } + + )" + }, + { + "material_info1.glsl", R"( + + // Metallic Roughness + uniform float u_MetallicFactor; + uniform float u_RoughnessFactor; + uniform vec4 u_BaseColorFactor; + + // Sheen + uniform float u_SheenRoughnessFactor; + uniform vec3 u_SheenColorFactor; + + // Clearcoat + uniform float u_ClearcoatFactor; + uniform float u_ClearcoatRoughnessFactor; + + // Specular + uniform vec3 u_KHR_materials_specular_specularColorFactor; + uniform float u_KHR_materials_specular_specularFactor; + + // Transmission + uniform float u_TransmissionFactor; + + // Volume + uniform float u_ThicknessFactor; + uniform vec3 u_AttenuationColor; + uniform float u_AttenuationDistance; + + // Iridescence + uniform float u_IridescenceFactor; + uniform float u_IridescenceIor; + uniform float u_IridescenceThicknessMinimum; + uniform float u_IridescenceThicknessMaximum; + + // Diffuse Transmission + uniform float u_DiffuseTransmissionFactor; + uniform vec3 u_DiffuseTransmissionColorFactor; + + // Emissive Strength + uniform float u_EmissiveStrength; + + // IOR + uniform float u_Ior; + + // Anisotropy + uniform vec3 u_Anisotropy; + + // Dispersion + uniform float u_Dispersion; + + // Alpha mode + uniform float u_AlphaCutoff; + + uniform vec3 u_Camera; + + #ifdef MATERIAL_TRANSMISSION + uniform ivec2 u_ScreenSize; + #endif + + uniform mat4 u_ModelMatrix; + uniform mat4 u_ViewMatrix; + uniform mat4 u_ProjectionMatrix; + + + struct MaterialInfo + { + vec4 baseColorFactor; + float alphaCutoff; + int flags; + vec2 padding; // Above props temporary from earlier shader version -mk + + float occlusionStrength; + float normalScale; + + float ior; + float perceptualRoughness; // roughness value, as authored by the model creator (input to shader) + vec3 f0_dielectric; + + float alphaRoughness; // roughness mapped to a more linear change in the roughness (proposed by [2]) + + float fresnel_w; + + vec3 f90; // reflectance color at grazing angle + vec3 f90_dielectric; + float metallic; + + vec3 baseColor; + + float sheenRoughnessFactor; + vec3 sheenColorFactor; + + vec3 clearcoatF0; + vec3 clearcoatF90; + float clearcoatFactor; + vec3 clearcoatNormal; + float clearcoatRoughness; + + // KHR_materials_specular + float specularWeight; // product of specularFactor and specularTexture.a + + float transmissionFactor; + )" + }, + { + "material_info2.glsl", R"( + float thickness; + vec3 attenuationColor; + float attenuationDistance; + + // KHR_materials_iridescence + float iridescenceFactor; + float iridescenceIor; + float iridescenceThickness; + + float diffuseTransmissionFactor; + vec3 diffuseTransmissionColorFactor; + + // KHR_materials_anisotropy + vec3 anisotropicT; + vec3 anisotropicB; + float anisotropyStrength; + + // KHR_materials_dispersion + float dispersion; + }; + + + // Get normal, tangent and bitangent vectors. + NormalInfo getNormalInfo(vec3 v) + { + vec2 UV = getNormalUV(); + vec2 uv_dx = dFdx(UV); + vec2 uv_dy = dFdy(UV); + + if (length(uv_dx) <= 1e-2) { + uv_dx = vec2(1.0, 0.0); + } + + if (length(uv_dy) <= 1e-2) { + uv_dy = vec2(0.0, 1.0); + } + + vec3 t_ = (uv_dy.t * dFdx(v_Position) - uv_dx.t * dFdy(v_Position)) / + (uv_dx.s * uv_dy.t - uv_dy.s * uv_dx.t); + + vec3 n, t, b, ng; + + // Compute geometrical TBN: + #ifdef HAS_NORMAL_VEC3 + #ifdef HAS_TANGENT_VEC4 + // Trivial TBN computation, present as vertex attribute. + // Normalize eigenvectors as matrix is linearly interpolated. + t = normalize(v_TBN[0]); + b = normalize(v_TBN[1]); + ng = normalize(v_TBN[2]); + #else + // Normals are either present as vertex attributes or approximated. + ng = normalize(v_Normal); + t = normalize(t_ - ng * dot(ng, t_)); + b = cross(ng, t); + #endif + #else + ng = normalize(cross(dFdx(v_Position), dFdy(v_Position))); + t = normalize(t_ - ng * dot(ng, t_)); + b = cross(ng, t); + #endif + + #ifndef NOT_TRIANGLE + // For a back-facing surface, the tangential basis vectors are negated. + if (gl_FrontFacing == false) + { + t *= -1.0; + b *= -1.0; + ng *= -1.0; + } + #endif + + // Compute normals: + NormalInfo info; + info.ng = ng; + #ifdef HAS_NORMAL_MAP + info.ntex = texture(u_NormalSampler, UV).rgb * 2.0 - vec3(1.0); + info.ntex *= vec3(u_NormalScale, u_NormalScale, 1.0); + info.ntex = normalize(info.ntex); + info.n = normalize(mat3(t, b, ng) * info.ntex); + #else + info.n = ng; + #endif + info.t = t; + info.b = b; + return info; + } + + + #ifdef MATERIAL_CLEARCOAT + vec3 getClearcoatNormal(NormalInfo normalInfo) + { + #ifdef HAS_CLEARCOAT_NORMAL_MAP + vec3 n = texture(u_ClearcoatNormalSampler, getClearcoatNormalUV()).rgb * 2.0 - vec3(1.0); + n *= vec3(u_ClearcoatNormalScale, u_ClearcoatNormalScale, 1.0); + n = mat3(normalInfo.t, normalInfo.b, normalInfo.ng) * normalize(n); + return n; + #else + return normalInfo.ng; + #endif + } + #endif + + )" + }, + { + "material_info3.glsl", R"( + vec4 getBaseColor() + { + vec4 baseColor = u_BaseColorFactor; + + #ifdef MATERIAL_UNLIT + #if defined(HAS_BASE_COLOR_MAP) + baseColor *= texture(u_BaseColorSampler, getBaseColorUV()); + #endif + return baseColor; + #else + #ifdef MATERIAL_METALLICROUGHNESS + #if defined(HAS_BASE_COLOR_MAP) + baseColor *= texture(u_BaseColorSampler, getBaseColorUV()); + #endif + #endif + return baseColor * getVertexColor(); + #endif + + } + + + #ifdef MATERIAL_METALLICROUGHNESS + MaterialInfo getMetallicRoughnessInfo(MaterialInfo info) + { + info.metallic = u_MetallicFactor; + info.perceptualRoughness = u_RoughnessFactor; + + #ifdef HAS_METALLIC_ROUGHNESS_MAP + // Roughness is stored in the 'g' channel, metallic is stored in the 'b' channel. + // This layout intentionally reserves the 'r' channel for (optional) occlusion map data + vec4 mrSample = texture(u_MetallicRoughnessSampler, getMetallicRoughnessUV()); + info.perceptualRoughness *= mrSample.g; + info.metallic *= mrSample.b; + #endif + + return info; + } + #endif + + + #ifdef MATERIAL_SHEEN + MaterialInfo getSheenInfo(MaterialInfo info) + { + info.sheenColorFactor = u_SheenColorFactor; + info.sheenRoughnessFactor = u_SheenRoughnessFactor; + + #ifdef HAS_SHEEN_COLOR_MAP + vec4 sheenColorSample = texture(u_SheenColorSampler, getSheenColorUV()); + info.sheenColorFactor *= sheenColorSample.rgb; + #endif + + #ifdef HAS_SHEEN_ROUGHNESS_MAP + vec4 sheenRoughnessSample = texture(u_SheenRoughnessSampler, getSheenRoughnessUV()); + info.sheenRoughnessFactor *= sheenRoughnessSample.a; + #endif + return info; + } + #endif + + + #ifdef MATERIAL_SPECULAR + MaterialInfo getSpecularInfo(MaterialInfo info) + { + vec4 specularTexture = vec4(1.0); + #ifdef HAS_SPECULAR_MAP + specularTexture.a = texture(u_SpecularSampler, getSpecularUV()).a; + #endif + #ifdef HAS_SPECULAR_COLOR_MAP + specularTexture.rgb = texture(u_SpecularColorSampler, getSpecularColorUV()).rgb; + #endif + + info.f0_dielectric = min(info.f0_dielectric * u_KHR_materials_specular_specularColorFactor * specularTexture.rgb, vec3(1.0)); + info.specularWeight = u_KHR_materials_specular_specularFactor * specularTexture.a; + info.f90_dielectric = vec3(info.specularWeight); + return info; + } + #endif + + + #ifdef MATERIAL_TRANSMISSION + MaterialInfo getTransmissionInfo(MaterialInfo info) + { + info.transmissionFactor = u_TransmissionFactor; + + #ifdef HAS_TRANSMISSION_MAP + vec4 transmissionSample = texture(u_TransmissionSampler, getTransmissionUV()); + info.transmissionFactor *= transmissionSample.r; + #endif + + #ifdef MATERIAL_DISPERSION + info.dispersion = u_Dispersion; + #else + info.dispersion = 0.0; + #endif + return info; + } + #endif + )" + }, + { + "material_info4.glsl", R"( + #ifdef MATERIAL_VOLUME + MaterialInfo getVolumeInfo(MaterialInfo info) + { + info.thickness = u_ThicknessFactor; + info.attenuationColor = u_AttenuationColor; + info.attenuationDistance = u_AttenuationDistance; + + #ifdef HAS_THICKNESS_MAP + vec4 thicknessSample = texture(u_ThicknessSampler, getThicknessUV()); + info.thickness *= thicknessSample.g; + #endif + return info; + } + #endif + + + #ifdef MATERIAL_IRIDESCENCE + MaterialInfo getIridescenceInfo(MaterialInfo info) + { + info.iridescenceFactor = u_IridescenceFactor; + info.iridescenceIor = u_IridescenceIor; + info.iridescenceThickness = u_IridescenceThicknessMaximum; + + #ifdef HAS_IRIDESCENCE_MAP + info.iridescenceFactor *= texture(u_IridescenceSampler, getIridescenceUV()).r; + #endif + + #ifdef HAS_IRIDESCENCE_THICKNESS_MAP + float thicknessSampled = texture(u_IridescenceThicknessSampler, getIridescenceThicknessUV()).g; + float thickness = mix(u_IridescenceThicknessMinimum, u_IridescenceThicknessMaximum, thicknessSampled); + info.iridescenceThickness = thickness; + #endif + + return info; + } + #endif + + + #ifdef MATERIAL_DIFFUSE_TRANSMISSION + MaterialInfo getDiffuseTransmissionInfo(MaterialInfo info) + { + info.diffuseTransmissionFactor = u_DiffuseTransmissionFactor; + info.diffuseTransmissionColorFactor = u_DiffuseTransmissionColorFactor; + + #ifdef HAS_DIFFUSE_TRANSMISSION_MAP + info.diffuseTransmissionFactor *= texture(u_DiffuseTransmissionSampler, getDiffuseTransmissionUV()).a; + #endif + + #ifdef HAS_DIFFUSE_TRANSMISSION_COLOR_MAP + info.diffuseTransmissionColorFactor *= texture(u_DiffuseTransmissionColorSampler, getDiffuseTransmissionColorUV()).rgb; + #endif + + return info; + } + #endif + )" + }, + { + "material_info5.glsl", R"( + + #ifdef MATERIAL_CLEARCOAT + MaterialInfo getClearCoatInfo(MaterialInfo info, NormalInfo normalInfo) + { + info.clearcoatFactor = u_ClearcoatFactor; + info.clearcoatRoughness = u_ClearcoatRoughnessFactor; + info.clearcoatF0 = vec3(pow((info.ior - 1.0) / (info.ior + 1.0), 2.0)); + info.clearcoatF90 = vec3(1.0); + + #ifdef HAS_CLEARCOAT_MAP + vec4 clearcoatSample = texture(u_ClearcoatSampler, getClearcoatUV()); + info.clearcoatFactor *= clearcoatSample.r; + #endif + + #ifdef HAS_CLEARCOAT_ROUGHNESS_MAP + vec4 clearcoatSampleRoughness = texture(u_ClearcoatRoughnessSampler, getClearcoatRoughnessUV()); + info.clearcoatRoughness *= clearcoatSampleRoughness.g; + #endif + + info.clearcoatNormal = getClearcoatNormal(normalInfo); + info.clearcoatRoughness = clamp(info.clearcoatRoughness, 0.0, 1.0); + return info; + } + #endif + + + #ifdef MATERIAL_IOR + MaterialInfo getIorInfo(MaterialInfo info) + { + info.f0_dielectric = vec3(pow(( u_Ior - 1.0) / (u_Ior + 1.0), 2.0)); + info.ior = u_Ior; + return info; + } + #endif + + #ifdef MATERIAL_ANISOTROPY + MaterialInfo getAnisotropyInfo(MaterialInfo info, NormalInfo normalInfo) + { + vec2 direction = vec2(1.0, 0.0); + float strengthFactor = 1.0; + #ifdef HAS_ANISOTROPY_MAP + vec3 anisotropySample = texture(u_AnisotropySampler, getAnisotropyUV()).xyz; + direction = anisotropySample.xy * 2.0 - vec2(1.0); + strengthFactor = anisotropySample.z; + #endif + vec2 directionRotation = u_Anisotropy.xy; // cos(theta), sin(theta) + mat2 rotationMatrix = mat2(directionRotation.x, directionRotation.y, -directionRotation.y, directionRotation.x); + direction = rotationMatrix * direction.xy; + + info.anisotropicT = mat3(normalInfo.t, normalInfo.b, normalInfo.n) * normalize(vec3(direction, 0.0)); + info.anisotropicB = cross(normalInfo.ng, info.anisotropicT); + info.anisotropyStrength = clamp(u_Anisotropy.z * strengthFactor, 0.0, 1.0); + return info; + } + #endif + + + float albedoSheenScalingLUT(float NdotV, float sheenRoughnessFactor) + { + //return NdotV; + return texture(u_SheenELUT, vec2(NdotV, sheenRoughnessFactor)).r; + } + + )" + }, + { + "iridescence.glsl", R"( + const mat3 XYZ_TO_REC709 = mat3( + 3.2404542, -0.9692660, 0.0556434, + -1.5371385, 1.8760108, -0.2040259, + -0.4985314, 0.0415560, 1.0572252 + ); + + vec3 Fresnel0ToIor(vec3 fresnel0) { + vec3 sqrtF0 = sqrt(fresnel0); + return (vec3(1.0) + sqrtF0) / (vec3(1.0) - sqrtF0); + } + + vec3 IorToFresnel0(vec3 transmittedIor, float incidentIor) { + return sq((transmittedIor - vec3(incidentIor)) / (transmittedIor + vec3(incidentIor))); + } + + float IorToFresnel0(float transmittedIor, float incidentIor) { + return sq((transmittedIor - incidentIor) / (transmittedIor + incidentIor)); + } + + vec3 evalSensitivity(float OPD, vec3 shift) { + float phase = 2.0 * M_PI * OPD * 1.0e-9; + vec3 val = vec3(5.4856e-13, 4.4201e-13, 5.2481e-13); + vec3 pos = vec3(1.6810e+06, 1.7953e+06, 2.2084e+06); + vec3 var = vec3(4.3278e+09, 9.3046e+09, 6.6121e+09); + + vec3 xyz = val * sqrt(2.0 * M_PI * var) * cos(pos * phase + shift) * exp(-sq(phase) * var); + xyz.x += 9.7470e-14 * sqrt(2.0 * M_PI * 4.5282e+09) * cos(2.2399e+06 * phase + shift[0]) * exp(-4.5282e+09 * sq(phase)); + xyz /= 1.0685e-7; + + vec3 srgb = XYZ_TO_REC709 * xyz; + return srgb; + } + + vec3 evalIridescence(float outsideIOR, float eta2, float cosTheta1, float thinFilmThickness, vec3 baseF0) { + vec3 I; + + // Force iridescenceIor -> outsideIOR when thinFilmThickness -> 0.0 + float iridescenceIor = mix(outsideIOR, eta2, smoothstep(0.0, 0.03, thinFilmThickness)); + // Evaluate the cosTheta on the base layer (Snell law) + float sinTheta2Sq = sq(outsideIOR / iridescenceIor) * (1.0 - sq(cosTheta1)); + + // Handle TIR: + float cosTheta2Sq = 1.0 - sinTheta2Sq; + if (cosTheta2Sq < 0.0) { + return vec3(1.0); + } + + float cosTheta2 = sqrt(cosTheta2Sq); + + // First interface + float R0 = IorToFresnel0(iridescenceIor, outsideIOR); + float R12 = F_Schlick(R0, cosTheta1); + float R21 = R12; + float T121 = 1.0 - R12; + float phi12 = 0.0; + if (iridescenceIor < outsideIOR) phi12 = M_PI; + float phi21 = M_PI - phi12; + + // Second interface + vec3 baseIOR = Fresnel0ToIor(clamp(baseF0, 0.0, 0.9999)); // guard against 1.0 + vec3 R1 = IorToFresnel0(baseIOR, iridescenceIor); + vec3 R23 = F_Schlick(R1, cosTheta2); + vec3 phi23 = vec3(0.0); + if (baseIOR[0] < iridescenceIor) phi23[0] = M_PI; + if (baseIOR[1] < iridescenceIor) phi23[1] = M_PI; + if (baseIOR[2] < iridescenceIor) phi23[2] = M_PI; + + // Phase shift + float OPD = 2.0 * iridescenceIor * thinFilmThickness * cosTheta2; + vec3 phi = vec3(phi21) + phi23; + + // Compound terms + vec3 R123 = clamp(R12 * R23, 1e-5, 0.9999); + vec3 r123 = sqrt(R123); + vec3 Rs = sq(T121) * R23 / (vec3(1.0) - R123); + + // Reflectance term for m = 0 (DC term amplitude) + vec3 C0 = R12 + Rs; + I = C0; + + // Reflectance term for m > 0 (pairs of diracs) + vec3 Cm = Rs - T121; + for (int m = 1; m <= 2; ++m) + { + Cm *= r123; + vec3 Sm = 2.0 * evalSensitivity(float(m) * OPD, float(m) * phi); + I += Cm * Sm; + } + + // Since out of gamut colors might be produced, negative color values are clamped to 0. + return max(I, vec3(0.0)); + } + )" + }, + { + "animation1.glsl", R"( + + #ifdef HAS_MORPH_TARGETS + uniform highp sampler2DArray u_MorphTargetsSampler; + #endif + + #ifdef USE_MORPHING + uniform float u_morphWeights[WEIGHT_COUNT]; + #endif + + #ifdef HAS_JOINTS_0_VEC4 + in vec4 a_joints_0; + #endif + + #ifdef HAS_JOINTS_1_VEC4 + in vec4 a_joints_1; + #endif + + #ifdef HAS_WEIGHTS_0_VEC4 + in vec4 a_weights_0; + #endif + + #ifdef HAS_WEIGHTS_1_VEC4 + in vec4 a_weights_1; + #endif + + #ifdef USE_SKINNING + uniform sampler2D u_jointsSampler; + #endif + + #ifdef USE_SKINNING + + mat4 getMatrixFromTexture(sampler2D s, int index) + { + mat4 result = mat4(1); + int texSize = textureSize(s, 0)[0]; + int pixelIndex = index * 4; + for (int i = 0; i < 4; ++i) + { + int x = (pixelIndex + i) % texSize; + //Rounding mode of integers is undefined: + //https://www.khronos.org/registry/OpenGL/specs/es/3.0/GLSL_ES_Specification_3.00.pdf (section 12.33) + int y = (pixelIndex + i - x) / texSize; + result[i] = texelFetch(s, ivec2(x,y), 0); + } + return result; + } + + mat4 getSkinningMatrix() + { + mat4 skin = mat4(0); + + #if defined(HAS_WEIGHTS_0_VEC4) && defined(HAS_JOINTS_0_VEC4) + skin += + a_weights_0.x * getMatrixFromTexture(u_jointsSampler, int(a_joints_0.x) * 2) + + a_weights_0.y * getMatrixFromTexture(u_jointsSampler, int(a_joints_0.y) * 2) + + a_weights_0.z * getMatrixFromTexture(u_jointsSampler, int(a_joints_0.z) * 2) + + a_weights_0.w * getMatrixFromTexture(u_jointsSampler, int(a_joints_0.w) * 2); + #endif + + #if defined(HAS_WEIGHTS_1_VEC4) && defined(HAS_JOINTS_1_VEC4) + skin += + a_weights_1.x * getMatrixFromTexture(u_jointsSampler, int(a_joints_1.x) * 2) + + a_weights_1.y * getMatrixFromTexture(u_jointsSampler, int(a_joints_1.y) * 2) + + a_weights_1.z * getMatrixFromTexture(u_jointsSampler, int(a_joints_1.z) * 2) + + a_weights_1.w * getMatrixFromTexture(u_jointsSampler, int(a_joints_1.w) * 2); + #endif + if (skin == mat4(0)) { + return mat4(1); + } + return skin; + } + + + mat4 getSkinningNormalMatrix() + { + mat4 skin = mat4(0); + + #if defined(HAS_WEIGHTS_0_VEC4) && defined(HAS_JOINTS_0_VEC4) + skin += + a_weights_0.x * getMatrixFromTexture(u_jointsSampler, int(a_joints_0.x) * 2 + 1) + + a_weights_0.y * getMatrixFromTexture(u_jointsSampler, int(a_joints_0.y) * 2 + 1) + + a_weights_0.z * getMatrixFromTexture(u_jointsSampler, int(a_joints_0.z) * 2 + 1) + + a_weights_0.w * getMatrixFromTexture(u_jointsSampler, int(a_joints_0.w) * 2 + 1); + #endif + + #if defined(HAS_WEIGHTS_1_VEC4) && defined(HAS_JOINTS_1_VEC4) + skin += + a_weights_1.x * getMatrixFromTexture(u_jointsSampler, int(a_joints_1.x) * 2 + 1) + + a_weights_1.y * getMatrixFromTexture(u_jointsSampler, int(a_joints_1.y) * 2 + 1) + + a_weights_1.z * getMatrixFromTexture(u_jointsSampler, int(a_joints_1.z) * 2 + 1) + + a_weights_1.w * getMatrixFromTexture(u_jointsSampler, int(a_joints_1.w) * 2 + 1); + #endif + if (skin == mat4(0)) { + return mat4(1); + } + return skin; + } + + #endif // !USE_SKINNING + + )" + }, + { + "animation2.glsl", R"( + #ifdef USE_MORPHING + + #ifdef HAS_MORPH_TARGETS + vec4 getDisplacement(int vertexID, int targetIndex, int texSize) + { + int x = vertexID % texSize; + //Rounding mode of integers is undefined: + //https://www.khronos.org/registry/OpenGL/specs/es/3.0/GLSL_ES_Specification_3.00.pdf (section 12.33) + int y = (vertexID - x) / texSize; + return texelFetch(u_MorphTargetsSampler, ivec3(x, y, targetIndex), 0); + } + #endif + + + vec4 getTargetPosition(int vertexID) + { + vec4 pos = vec4(0); + #ifdef HAS_MORPH_TARGET_POSITION + int texSize = textureSize(u_MorphTargetsSampler, 0)[0]; + for(int i = 0; i < WEIGHT_COUNT; i++) + { + vec4 displacement = getDisplacement(vertexID, MORPH_TARGET_POSITION_OFFSET + i, texSize); + pos += u_morphWeights[i] * displacement; + } + #endif + + return pos; + } + + vec3 getTargetNormal(int vertexID) + { + vec3 normal = vec3(0); + + #ifdef HAS_MORPH_TARGET_NORMAL + int texSize = textureSize(u_MorphTargetsSampler, 0)[0]; + for(int i = 0; i < WEIGHT_COUNT; i++) + { + vec3 displacement = getDisplacement(vertexID, MORPH_TARGET_NORMAL_OFFSET + i, texSize).xyz; + normal += u_morphWeights[i] * displacement; + } + #endif + + return normal; + } + + + vec3 getTargetTangent(int vertexID) + { + vec3 tangent = vec3(0); + + #ifdef HAS_MORPH_TARGET_TANGENT + int texSize = textureSize(u_MorphTargetsSampler, 0)[0]; + for(int i = 0; i < WEIGHT_COUNT; i++) + { + vec3 displacement = getDisplacement(vertexID, MORPH_TARGET_TANGENT_OFFSET + i, texSize).xyz; + tangent += u_morphWeights[i] * displacement; + } + #endif + + return tangent; + } + + vec2 getTargetTexCoord0(int vertexID) + { + vec2 uv = vec2(0); + + #ifdef HAS_MORPH_TARGET_TEXCOORD_0 + int texSize = textureSize(u_MorphTargetsSampler, 0)[0]; + for(int i = 0; i < WEIGHT_COUNT; i++) + { + vec2 displacement = getDisplacement(vertexID, MORPH_TARGET_TEXCOORD_0_OFFSET + i, texSize).xy; + uv += u_morphWeights[i] * displacement; + } + #endif + + return uv; + } + + vec2 getTargetTexCoord1(int vertexID) + { + vec2 uv = vec2(0); + + #ifdef HAS_MORPH_TARGET_TEXCOORD_1 + int texSize = textureSize(u_MorphTargetsSampler, 0)[0]; + for(int i = 0; i < WEIGHT_COUNT; i++) + { + vec2 displacement = getDisplacement(vertexID, MORPH_TARGET_TEXCOORD_1_OFFSET + i, texSize).xy; + uv += u_morphWeights[i] * displacement; + } + #endif + + return uv; + } + + vec4 getTargetColor0(int vertexID) + { + vec4 color = vec4(0); + + #ifdef HAS_MORPH_TARGET_COLOR_0 + int texSize = textureSize(u_MorphTargetsSampler, 0)[0]; + for(int i = 0; i < WEIGHT_COUNT; i++) + { + vec4 displacement = getDisplacement(vertexID, MORPH_TARGET_COLOR_0_OFFSET + i, texSize); + color += u_morphWeights[i] * displacement; + } + #endif + + return color; + } + + #endif // !USE_MORPHING + )" + }, + { + "vert_v1_chunk_00.glsl", R"( + + #ifdef HAS_NORMAL_VEC3 + in vec3 a_normal; + #endif + + #ifdef HAS_NORMAL_VEC3 + #ifdef HAS_TANGENT_VEC4 + in vec4 a_tangent; + out mat3 v_TBN; + #else + out vec3 v_Normal; + #endif + #endif + + #ifdef HAS_TEXCOORD_0_VEC2 + in vec2 a_texcoord_0; + #endif + + #ifdef HAS_TEXCOORD_1_VEC2 + in vec2 a_texcoord_1; + #endif + + out vec2 v_texcoord_0; + out vec2 v_texcoord_1; + + #ifdef HAS_COLOR_0_VEC3 + in vec3 a_color_0; + out vec3 v_Color; + #endif + + #ifdef HAS_COLOR_0_VEC4 + in vec4 a_color_0; + out vec4 v_Color; + #endif + + #ifdef USE_INSTANCING + in mat4 a_instance_model_matrix; + #endif + + #ifdef HAS_VERT_NORMAL_UV_TRANSFORM + uniform mat3 u_vertNormalUVTransform; + #endif + + vec4 getPosition() + { + vec4 pos = vec4(a_position, 1.0); + + #ifdef USE_MORPHING + pos += getTargetPosition(gl_VertexID); + #endif + + #ifdef USE_SKINNING + pos = getSkinningMatrix() * pos; + #endif + + return pos; + } + + + #ifdef HAS_NORMAL_VEC3 + vec3 getNormal() + { + vec3 normal = a_normal; + + #ifdef USE_MORPHING + normal += getTargetNormal(gl_VertexID); + #endif + + #ifdef USE_SKINNING + normal = mat3(getSkinningNormalMatrix()) * normal; + #endif + + return normalize(normal); + } + #endif + + #ifdef HAS_NORMAL_VEC3 + #ifdef HAS_TANGENT_VEC4 + vec3 getTangent() + { + vec3 tangent = a_tangent.xyz; + + #ifdef USE_MORPHING + tangent += getTargetTangent(gl_VertexID); + #endif + + )" + }, + { + "vert_v1_chunk_01.glsl", R"( + #ifdef USE_SKINNING + tangent = mat3(getSkinningMatrix()) * tangent; + #endif + + return normalize(tangent); + } + #endif + #endif + + mat4 temp_makeNormalMatrixFromViewProj(mat4 _viewProjModelMatrix) { + mat4 normMat = _viewProjModelMatrix ; + normMat[0][0] = 1.0; + normMat[0][1] = 0.0; + normMat[0][2] = 0.0; + normMat[0][3] = 0.0; + normMat[1][0] = 0.0; + normMat[1][3] = 0.0; + normMat[2][0] = 0.0; + normMat[2][3] = 0.0; + normMat[3][0] = 0.0; + normMat[3][1] = 0.0; + normMat[3][2] = 0.0; + normMat[3][3] = 1.0; + return normMat; + } + + void main() + { + gl_PointSize = 1.0f; + #ifdef USE_INSTANCING + mat4 modelMatrix = a_instance_model_matrix; + mat4 normalMatrix = transpose(inverse(modelMatrix)); + #else + mat4 modelMatrix = u_ModelMatrix; + //mat4 normalMatrix = u_NormalMatrix; + mat4 normalMatrix = transpose(inverse(modelMatrix)); + + #endif + vec4 pos = modelMatrix * getPosition(); + v_Position = vec3(pos.xyz) / pos.w; + + #ifdef HAS_NORMAL_VEC3 + #ifdef HAS_TANGENT_VEC4 + vec3 tangent = getTangent(); + vec3 normalW = normalize(vec3(normalMatrix * vec4(getNormal(), 0.0))); + vec3 tangentW = vec3(modelMatrix * vec4(tangent, 0.0)); + vec3 bitangentW = cross(normalW, tangentW) * a_tangent.w; + + #ifdef HAS_VERT_NORMAL_UV_TRANSFORM + tangentW = u_vertNormalUVTransform * tangentW; + bitangentW = u_vertNormalUVTransform * bitangentW; + #endif + + bitangentW = normalize(bitangentW); + tangentW = normalize(tangentW); + + v_TBN = mat3(tangentW, bitangentW, normalW); + #else + v_Normal = normalize(vec3(normalMatrix * vec4(getNormal(), 0.0))); + #endif + #endif + + v_texcoord_0 = vec2(0.0, 0.0); + v_texcoord_1 = vec2(0.0, 0.0); + + #ifdef HAS_TEXCOORD_0_VEC2 + v_texcoord_0 = a_texcoord_0; + #endif + + #ifdef HAS_TEXCOORD_1_VEC2 + v_texcoord_1 = a_texcoord_1; + #endif + + #ifdef USE_MORPHING + v_texcoord_0 += getTargetTexCoord0(gl_VertexID); + v_texcoord_1 += getTargetTexCoord1(gl_VertexID); + #endif + + + #if defined(HAS_COLOR_0_VEC3) + v_Color = a_color_0; + #if defined(USE_MORPHING) + v_Color = clamp(v_Color + getTargetColor0(gl_VertexID).xyz, 0.0f, 1.0f); + #endif + #endif + + #if defined(HAS_COLOR_0_VEC4) + v_Color = a_color_0; + #if defined(USE_MORPHING) + v_Color = clamp(v_Color + getTargetColor0(gl_VertexID), 0.0f, 1.0f); + #endif + #endif + + gl_Position = u_ViewProjectionMatrix * pos; + } + )" + }, + { + "frag_v1_chunk_00.glsl", R"( + out vec4 g_finalColor; + void main() + { + + vec4 baseColor = getBaseColor(); + + #if ALPHAMODE == _OPAQUE + baseColor.a = 1.0; + #endif + + vec4 temp_origBaseColor = baseColor; + + vec3 color = vec3(0); + + vec3 v = normalize(u_Camera - v_Position); + + NormalInfo normalInfo = getNormalInfo(v); + vec3 n = normalInfo.n; + vec3 t = normalInfo.t; + vec3 b = normalInfo.b; + + float NdotV = clampedDot(n, v); + float TdotV = clampedDot(t, v); + float BdotV = clampedDot(b, v); + + MaterialInfo materialInfo; + materialInfo.baseColor = baseColor.rgb; + + // The default index of refraction of 1.5 yields a dielectric normal incidence reflectance of 0.04. + materialInfo.ior = 1.5; + materialInfo.f0_dielectric = vec3(0.04); + materialInfo.specularWeight = 1.0; + + // Anything less than 2% is physically impossible and is instead considered to be shadowing. Compare to "Real-Time-Rendering" 4th editon on page 325. + materialInfo.f90 = vec3(1.0); + materialInfo.f90_dielectric = materialInfo.f90; + + #ifdef MATERIAL_IOR + materialInfo = getIorInfo(materialInfo); + #endif + + #ifdef MATERIAL_METALLICROUGHNESS + materialInfo = getMetallicRoughnessInfo(materialInfo); + #endif + + #ifdef MATERIAL_SHEEN + materialInfo = getSheenInfo(materialInfo); + #endif + )" + }, + { + "frag_v1_chunk_01a.glsl", R"( + + #ifdef MATERIAL_CLEARCOAT + materialInfo = getClearCoatInfo(materialInfo, normalInfo); + #endif + + #ifdef MATERIAL_SPECULAR + materialInfo = getSpecularInfo(materialInfo); + #endif + + #ifdef MATERIAL_TRANSMISSION + materialInfo = getTransmissionInfo(materialInfo); + #endif + + #ifdef MATERIAL_VOLUME + materialInfo = getVolumeInfo(materialInfo); + #endif + + #ifdef MATERIAL_IRIDESCENCE + materialInfo = getIridescenceInfo(materialInfo); + #endif + + #ifdef MATERIAL_DIFFUSE_TRANSMISSION + materialInfo = getDiffuseTransmissionInfo(materialInfo); + #endif + + #ifdef MATERIAL_ANISOTROPY + materialInfo = getAnisotropyInfo(materialInfo, normalInfo); + #endif + + materialInfo.perceptualRoughness = clamp(materialInfo.perceptualRoughness, 0.0, 1.0); + materialInfo.metallic = clamp(materialInfo.metallic, 0.0, 1.0); + + // Roughness is authored as perceptual roughness; as is convention, + // convert to material roughness by squaring the perceptual roughness. + materialInfo.alphaRoughness = materialInfo.perceptualRoughness * materialInfo.perceptualRoughness; + + + // LIGHTING + vec3 f_specular_dielectric = vec3(0.0); + vec3 f_specular_metal = vec3(0.0); + vec3 f_diffuse = vec3(0.0); + vec3 f_dielectric_brdf_ibl = vec3(0.0); + vec3 f_metal_brdf_ibl = vec3(0.0); + vec3 f_emissive = vec3(0.0); + vec3 clearcoat_brdf = vec3(0.0); + vec3 f_sheen = vec3(0.0); + vec3 f_specular_transmission = vec3(0.0); + vec3 f_diffuse_transmission = vec3(0.0); + + float clearcoatFactor = 0.0; + vec3 clearcoatFresnel = vec3(0); + )" + }, + { + "frag_v1_chunk_01b.glsl", R"( + float albedoSheenScaling = 1.0; + float diffuseTransmissionThickness = 1.0; + + #ifdef MATERIAL_IRIDESCENCE + vec3 iridescenceFresnel_dielectric = evalIridescence(1.0, materialInfo.iridescenceIor, NdotV, materialInfo.iridescenceThickness, materialInfo.f0_dielectric); + vec3 iridescenceFresnel_metallic = evalIridescence(1.0, materialInfo.iridescenceIor, NdotV, materialInfo.iridescenceThickness, baseColor.rgb); + + if (materialInfo.iridescenceThickness == 0.0) { + materialInfo.iridescenceFactor = 0.0; + } + #endif + + #ifdef MATERIAL_DIFFUSE_TRANSMISSION + #ifdef MATERIAL_VOLUME + diffuseTransmissionThickness = materialInfo.thickness * + (length(vec3(u_ModelMatrix[0].xyz)) + length(vec3(u_ModelMatrix[1].xyz)) + length(vec3(u_ModelMatrix[2].xyz))) / 3.0; + #endif + #endif + + #ifdef MATERIAL_CLEARCOAT + clearcoatFactor = materialInfo.clearcoatFactor; + clearcoatFresnel = F_Schlick(materialInfo.clearcoatF0, materialInfo.clearcoatF90, clampedDot(materialInfo.clearcoatNormal, v)); + #endif + + // Calculate lighting contribution from image based lighting source (IBL) + + #if defined(USE_IBL) || defined(MATERIAL_TRANSMISSION) + + f_diffuse = getDiffuseLight(n) * baseColor.rgb ; + + #ifdef MATERIAL_DIFFUSE_TRANSMISSION + vec3 diffuseTransmissionIBL = getDiffuseLight(-n) * materialInfo.diffuseTransmissionColorFactor; + #ifdef MATERIAL_VOLUME + diffuseTransmissionIBL = applyVolumeAttenuation(diffuseTransmissionIBL, diffuseTransmissionThickness, materialInfo.attenuationColor, materialInfo.attenuationDistance); + #endif + f_diffuse = mix(f_diffuse, diffuseTransmissionIBL, materialInfo.diffuseTransmissionFactor); + #endif + + + #if defined(MATERIAL_TRANSMISSION) + f_specular_transmission = getIBLVolumeRefraction( + n, v, + materialInfo.perceptualRoughness, + baseColor.rgb, v_Position, u_ModelMatrix, u_ViewMatrix, u_ProjectionMatrix, + materialInfo.ior, materialInfo.thickness, materialInfo.attenuationColor, materialInfo.attenuationDistance, materialInfo.dispersion); + f_diffuse = mix(f_diffuse, f_specular_transmission, materialInfo.transmissionFactor); + #endif + )" + }, + { + "frag_v1_chunk_02a.glsl", R"( + + #ifdef MATERIAL_ANISOTROPY + f_specular_metal = getIBLRadianceAnisotropy(n, v, materialInfo.perceptualRoughness, materialInfo.anisotropyStrength, materialInfo.anisotropicB); + f_specular_dielectric = f_specular_metal; + #else + f_specular_metal = getIBLRadianceGGX(n, v, materialInfo.perceptualRoughness); + f_specular_dielectric = f_specular_metal; + #endif + + // Calculate fresnel mix for IBL + + vec3 f_metal_fresnel_ibl = getIBLGGXFresnel(n, v, materialInfo.perceptualRoughness, baseColor.rgb, 1.0); + f_metal_brdf_ibl = f_metal_fresnel_ibl * f_specular_metal; + + vec3 f_dielectric_fresnel_ibl = getIBLGGXFresnel(n, v, materialInfo.perceptualRoughness, materialInfo.f0_dielectric, materialInfo.specularWeight); + f_dielectric_brdf_ibl = mix(f_diffuse, f_specular_dielectric, f_dielectric_fresnel_ibl); + + #ifdef MATERIAL_IRIDESCENCE + f_metal_brdf_ibl = mix(f_metal_brdf_ibl, f_specular_metal * iridescenceFresnel_metallic, materialInfo.iridescenceFactor); + f_dielectric_brdf_ibl = mix(f_dielectric_brdf_ibl, rgb_mix(f_diffuse, f_specular_dielectric, iridescenceFresnel_dielectric), materialInfo.iridescenceFactor); + #endif + + #ifdef MATERIAL_CLEARCOAT + clearcoat_brdf = getIBLRadianceGGX(materialInfo.clearcoatNormal, v, materialInfo.clearcoatRoughness); + #endif + + #ifdef MATERIAL_SHEEN + f_sheen = getIBLRadianceCharlie(n, v, materialInfo.sheenRoughnessFactor, materialInfo.sheenColorFactor); + albedoSheenScaling = 1.0 - max3(materialInfo.sheenColorFactor) * albedoSheenScalingLUT(NdotV, materialInfo.sheenRoughnessFactor); + #endif + + color = mix(f_dielectric_brdf_ibl, f_metal_brdf_ibl, materialInfo.metallic); + color = f_sheen + color * albedoSheenScaling; + color = mix(color, clearcoat_brdf, clearcoatFactor * clearcoatFresnel); + + #ifdef HAS_OCCLUSION_MAP + float ao = 1.0; + ao = texture(u_OcclusionSampler, getOcclusionUV()).r; + color = color * (1.0 + u_OcclusionStrength * (ao - 1.0)); + //temp_origBaseColor.rgb *= (1.0 + u_OcclusionStrength * (ao - 1.0)); + + //color = vec4(1.0, 0.0, 0.5, 1.0); + #endif + + //#else // Temporary addition to enable occlusion maps in non-IBL mode, which isn't physically accurate and should eventually be removed. + //#ifdef HAS_OCCLUSION_MAP + // float ao = 1.0; + // ao = texture(u_OcclusionSampler, getOcclusionUV()).r; + // //color = vec3(1.0, 0.0, 0.5); + // color = color * (1.0 + u_OcclusionStrength * (ao - 1.0)); + //#endif + #endif //end USE_IBL + + + f_diffuse = vec3(0.0); + + )" + }, + { + "frag_v1_chunk_02b.glsl", R"( + + f_specular_dielectric = vec3(0.0); + f_specular_metal = vec3(0.0); + vec3 f_dielectric_brdf = vec3(0.0); + vec3 f_metal_brdf = vec3(0.0); + + #ifdef USE_PUNCTUAL + /* + Light temp_keylight = Light( + normalize(vec3(-0.1, -0.75, -0.45)), //vec3 direction + -1.0, //float range + vec3(1.0, 1.0, 1.0), //vec3 color + 1.0, //float intensity + vec3(0.0, 0.0, 0.0), //vec3 position + 0.0, //float innerConeCos + 0.0, //float outerConeCos + 0 //int type; + // const Type_Directional = 0; + // const Type_Point = 1; + // const Type_Spot = 2; + ); + Light temp_filllight = Light( + normalize(-vec3(-0.2, -0.65, -0.35)), //vec3 direction + -1.0, //float range + vec3(1.0, 1.0, 1.0), //vec3 color + 0.5, //float intensity + vec3(0.0, 0.0, 0.0), //vec3 position + 0.0, //float innerConeCos + 0.0, //float outerConeCos + 0 //int type; + // const Type_Directional = 0; + // const Type_Point = 1; + // const Type_Spot = 2; + ); + )" + }, + { + "frag_v1_chunk_03a.glsl", R"( + + u_Lights[1] = temp_keylight; + u_Lights[2] = temp_filllight; + */ + for (int i = 0; i < LIGHT_COUNT; ++i) + { + Light light = u_Lights[i+1]; + + vec3 pointToLight; + if (light.type != LightType_Directional) + { + pointToLight = light.position - v_Position; + } + else + { + pointToLight = -light.direction; + } + + // BSTF + + vec3 l = normalize(pointToLight); // Direction from surface point to light + vec3 h = normalize(l + v); // Direction of the vector between l and v, called halfway vector + float NdotL = clampedDot(n, l); + float NdotV = clampedDot(n, v); + float NdotH = clampedDot(n, h); + float LdotH = clampedDot(l, h); + float VdotH = clampedDot(v, h); + + vec3 dielectric_fresnel = F_Schlick(materialInfo.f0_dielectric * materialInfo.specularWeight, materialInfo.f90_dielectric, abs(VdotH)); + vec3 metal_fresnel = F_Schlick(baseColor.rgb, vec3(1.0), abs(VdotH)); + + vec3 lightIntensity = getLighIntensity(light, pointToLight); + + vec3 l_diffuse = lightIntensity * NdotL * BRDF_lambertian(baseColor.rgb); + vec3 l_specular_dielectric = vec3(0.0); + vec3 l_specular_metal = vec3(0.0); + vec3 l_dielectric_brdf = vec3(0.0); + vec3 l_metal_brdf = vec3(0.0); + vec3 l_clearcoat_brdf = vec3(0.0); + vec3 l_sheen = vec3(0.0); + float l_albedoSheenScaling = 1.0; + + #ifdef MATERIAL_DIFFUSE_TRANSMISSION + l_diffuse = l_diffuse * (1.0 - materialInfo.diffuseTransmissionFactor); + if (dot(n, l) < 0.0) { + float diffuseNdotL = clampedDot(-n, l); + vec3 diffuse_btdf = lightIntensity * diffuseNdotL * BRDF_lambertian(materialInfo.diffuseTransmissionColorFactor); + + vec3 l_mirror = normalize(l + 2.0 * n * dot(-l, n)); // Mirror light reflection vector on surface + float diffuseVdotH = clampedDot(v, normalize(l_mirror + v)); + dielectric_fresnel = F_Schlick(materialInfo.f0_dielectric * materialInfo.specularWeight, materialInfo.f90_dielectric, abs(diffuseVdotH)); + + #ifdef MATERIAL_VOLUME + diffuse_btdf = applyVolumeAttenuation(diffuse_btdf, diffuseTransmissionThickness, materialInfo.attenuationColor, materialInfo.attenuationDistance); + #endif + l_diffuse += diffuse_btdf * materialInfo.diffuseTransmissionFactor; + } + #endif // MATERIAL_DIFFUSE_TRANSMISSION + + //temp_origBaseColor.rgb = vec3(l_diffuse); + )" + }, + { + "frag_v1_chunk_03b.glsl", R"( + // BTDF (Bidirectional Transmittance Distribution Function) + #ifdef MATERIAL_TRANSMISSION + // If the light ray travels through the geometry, use the point it exits the geometry again. + // That will change the angle to the light source, if the material refracts the light ray. + vec3 transmissionRay = getVolumeTransmissionRay(n, v, materialInfo.thickness, materialInfo.ior, u_ModelMatrix); + pointToLight -= transmissionRay; + l = normalize(pointToLight); + + vec3 transmittedLight = lightIntensity * getPunctualRadianceTransmission(n, v, l, materialInfo.alphaRoughness, baseColor.rgb, materialInfo.ior); + + #ifdef MATERIAL_VOLUME + transmittedLight = applyVolumeAttenuation(transmittedLight, length(transmissionRay), materialInfo.attenuationColor, materialInfo.attenuationDistance); + #endif + l_diffuse = mix(l_diffuse, transmittedLight, materialInfo.transmissionFactor); + #endif + // Calculation of analytical light + // https://github.com/KhronosGroup/glTF/tree/master/specification/2.0#acknowledgments AppendixB + vec3 intensity = getLighIntensity(light, pointToLight); + + #ifdef MATERIAL_ANISOTROPY + l_specular_metal = intensity * NdotL * BRDF_specularGGXAnisotropy(materialInfo.alphaRoughness, materialInfo.anisotropyStrength, n, v, l, h, materialInfo.anisotropicT, materialInfo.anisotropicB); + l_specular_dielectric = l_specular_metal; + #else + l_specular_metal = intensity * NdotL * BRDF_specularGGX(materialInfo.alphaRoughness, NdotL, NdotV, NdotH); + l_specular_dielectric = l_specular_metal; + #endif + + l_metal_brdf = metal_fresnel * l_specular_metal; + l_dielectric_brdf = mix(l_diffuse, l_specular_dielectric, dielectric_fresnel); // Do we need to handle vec3 fresnel here? + + + #ifdef MATERIAL_IRIDESCENCE + l_metal_brdf = mix(l_metal_brdf, l_specular_metal * iridescenceFresnel_metallic, materialInfo.iridescenceFactor); + l_dielectric_brdf = mix(l_dielectric_brdf, rgb_mix(l_diffuse, l_specular_dielectric, iridescenceFresnel_dielectric), materialInfo.iridescenceFactor); + #endif + + #ifdef MATERIAL_CLEARCOAT + l_clearcoat_brdf = intensity * getPunctualRadianceClearCoat(materialInfo.clearcoatNormal, v, l, h, VdotH, + materialInfo.clearcoatF0, materialInfo.clearcoatF90, materialInfo.clearcoatRoughness); + #endif + + #ifdef MATERIAL_SHEEN + l_sheen = intensity * getPunctualRadianceSheen(materialInfo.sheenColorFactor, materialInfo.sheenRoughnessFactor, NdotL, NdotV, NdotH); + l_albedoSheenScaling = min(1.0 - max3(materialInfo.sheenColorFactor) * albedoSheenScalingLUT(NdotV, materialInfo.sheenRoughnessFactor), + 1.0 - max3(materialInfo.sheenColorFactor) * albedoSheenScalingLUT(NdotL, materialInfo.sheenRoughnessFactor)); + #endif + + //temp_origBaseColor.rgb = (l_metal_brdf + l_dielectric_brdf).xyz; + + vec3 l_color = mix(l_dielectric_brdf, l_metal_brdf, materialInfo.metallic); + l_color = l_sheen + l_color * l_albedoSheenScaling; + l_color = mix(l_color, l_clearcoat_brdf, clearcoatFactor * clearcoatFresnel); + color += l_color; + } + #endif // USE_PUNCTUAL + )" + }, + { + "frag_v1_chunk_04.glsl", R"( + f_emissive = u_EmissiveFactor; + #ifdef MATERIAL_EMISSIVE_STRENGTH + f_emissive *= u_EmissiveStrength; + #endif + #ifdef HAS_EMISSIVE_MAP + f_emissive *= texture(u_EmissiveSampler, getEmissiveUV()).rgb; + #endif + + + #ifdef MATERIAL_UNLIT + //#ifdef HAS_EMISSIVE_MAP + // color = texture(u_EmissiveSampler, getEmissiveUV()).rgb; + //#else + color = baseColor.rgb; + //#endif + #elif defined(NOT_TRIANGLE) && !defined(HAS_NORMAL_VEC3) + //Points or Lines with no NORMAL attribute SHOULD be rendered without lighting and instead use the sum of the base color value and the emissive value. + color = f_emissive + baseColor.rgb; + #else + color = f_emissive * (1.0 - clearcoatFactor * clearcoatFresnel) + color; + #endif + + //#if DEBUG == DEBUG_NONE + + #if ALPHAMODE == _MASK + // Late discard to avoid sampling artifacts. See https://github.com/KhronosGroup/glTF-Sample-Viewer/issues/267 + if (baseColor.a < u_AlphaCutoff) + { + discard; + } + baseColor.a = 1.0; + #endif + + #ifdef LINEAR_OUTPUT + g_finalColor = vec4(color.rgb, baseColor.a); + #else + g_finalColor = vec4(toneMap(color), baseColor.a); + #endif + + + /* + #else + // In case of missing data for a debug view, render a checkerboard. + g_finalColor = vec4(1.0); + { + float frequency = 0.02; + float gray = 0.9; + + vec2 v1 = step(0.5, fract(frequency * gl_FragCoord.xy)); + vec2 v2 = step(0.5, vec2(1.0) - fract(frequency * gl_FragCoord.xy)); + g_finalColor.rgb *= gray + v1.x * v1.y + v2.x * v2.y; + } + #endif + + + + // Debug views: + + // Generic: + + #if DEBUG == DEBUG_UV_0 && defined(HAS_TEXCOORD_0_VEC2) + g_finalColor.rgb = vec3(v_texcoord_0, 0); + #endif + #if DEBUG == DEBUG_UV_1 && defined(HAS_TEXCOORD_1_VEC2) + g_finalColor.rgb = vec3(v_texcoord_1, 0); + #endif + #if DEBUG == DEBUG_NORMAL_TEXTURE && defined(HAS_NORMAL_MAP) + g_finalColor.rgb = (normalInfo.ntex + 1.0) / 2.0; + #endif + #if DEBUG == DEBUG_NORMAL_SHADING + g_finalColor.rgb = (n + 1.0) / 2.0; + #endif + #if DEBUG == DEBUG_NORMAL_GEOMETRY + g_finalColor.rgb = (normalInfo.ng + 1.0) / 2.0; + #endif + #if DEBUG == DEBUG_TANGENT + g_finalColor.rgb = (normalInfo.t + 1.0) / 2.0; + #endif + #if DEBUG == DEBUG_BITANGENT + g_finalColor.rgb = (normalInfo.b + 1.0) / 2.0; + #endif + #if DEBUG == DEBUG_ALPHA + g_finalColor.rgb = vec3(baseColor.a); + #endif + #if DEBUG == DEBUG_OCCLUSION && defined(HAS_OCCLUSION_MAP) + g_finalColor.rgb = vec3(ao); + #endif + #if DEBUG == DEBUG_EMISSIVE + g_finalColor.rgb = linearTosRGB(f_emissive); + #endif + + + #if DEBUG == DEBUG_METALLIC + g_finalColor.rgb = vec3(materialInfo.metallic); + #endif + #if DEBUG == DEBUG_ROUGHNESS + g_finalColor.rgb = vec3(materialInfo.perceptualRoughness); + #endif + #if DEBUG == DEBUG_BASE_COLOR + g_finalColor.rgb = linearTosRGB(materialInfo.baseColor); + #endif + )" + }, + { + "frag_v1_chunk_05.glsl", R"( + // Clearcoat: + #ifdef MATERIAL_CLEARCOAT + #if DEBUG == DEBUG_CLEARCOAT_FACTOR + g_finalColor.rgb = vec3(materialInfo.clearcoatFactor); + #endif + #if DEBUG == DEBUG_CLEARCOAT_ROUGHNESS + g_finalColor.rgb = vec3(materialInfo.clearcoatRoughness); + #endif + #if DEBUG == DEBUG_CLEARCOAT_NORMAL + g_finalColor.rgb = (materialInfo.clearcoatNormal + vec3(1)) / 2.0; + #endif + #endif + + // Sheen: + #ifdef MATERIAL_SHEEN + #if DEBUG == DEBUG_SHEEN_COLOR + g_finalColor.rgb = materialInfo.sheenColorFactor; + #endif + #if DEBUG == DEBUG_SHEEN_ROUGHNESS + g_finalColor.rgb = vec3(materialInfo.sheenRoughnessFactor); + #endif + #endif + + // Specular: + #ifdef MATERIAL_SPECULAR + #if DEBUG == DEBUG_SPECULAR_FACTOR + g_finalColor.rgb = vec3(materialInfo.specularWeight); + #endif + + #if DEBUG == DEBUG_SPECULAR_COLOR + vec3 specularTexture = vec3(1.0); + #ifdef HAS_SPECULAR_COLOR_MAP + specularTexture.rgb = texture(u_SpecularColorSampler, getSpecularColorUV()).rgb; + #endif + g_finalColor.rgb = u_KHR_materials_specular_specularColorFactor * specularTexture.rgb; + #endif + #endif + + // Transmission, Volume: + #ifdef MATERIAL_TRANSMISSION + #if DEBUG == DEBUG_TRANSMISSION_FACTOR + g_finalColor.rgb = vec3(materialInfo.transmissionFactor); + #endif + #endif + #ifdef MATERIAL_VOLUME + #if DEBUG == DEBUG_VOLUME_THICKNESS + g_finalColor.rgb = vec3(materialInfo.thickness / u_ThicknessFactor); + #endif + #endif + + // Iridescence: + #ifdef MATERIAL_IRIDESCENCE + #if DEBUG == DEBUG_IRIDESCENCE_FACTOR + g_finalColor.rgb = vec3(materialInfo.iridescenceFactor); + #endif + #if DEBUG == DEBUG_IRIDESCENCE_THICKNESS + g_finalColor.rgb = vec3(materialInfo.iridescenceThickness / 1200.0); + #endif + #endif + + // Anisotropy: + #ifdef MATERIAL_ANISOTROPY + #if DEBUG == DEBUG_ANISOTROPIC_STRENGTH + g_finalColor.rgb = vec3(materialInfo.anisotropyStrength); + #endif + #if DEBUG == DEBUG_ANISOTROPIC_DIRECTION + vec2 direction = vec2(1.0, 0.0); + #ifdef HAS_ANISOTROPY_MAP + direction = texture(u_AnisotropySampler, getAnisotropyUV()).xy; + direction = direction * 2.0 - vec2(1.0); // [0, 1] -> [-1, 1] + #endif + vec2 directionRotation = u_Anisotropy.xy; // cos(theta), sin(theta) + mat2 rotationMatrix = mat2(directionRotation.x, directionRotation.y, -directionRotation.y, directionRotation.x); + direction = (direction + vec2(1.0)) * 0.5; // [-1, 1] -> [0, 1] + + g_finalColor.rgb = vec3(direction, 0.0); + #endif + #endif + + // Diffuse Transmission: + #ifdef MATERIAL_DIFFUSE_TRANSMISSION + #if DEBUG == DEBUG_DIFFUSE_TRANSMISSION_FACTOR + g_finalColor.rgb = linearTosRGB(vec3(materialInfo.diffuseTransmissionFactor)); + #endif + #if DEBUG == DEBUG_DIFFUSE_TRANSMISSION_COLOR_FACTOR + g_finalColor.rgb = linearTosRGB(materialInfo.diffuseTransmissionColorFactor); + #endif + #endif + */ + } + )" + }, + + { + "cubemap.vert", R"( + uniform mat4 u_ViewProjectionMatrix; + uniform mat3 u_EnvRotation; + + in vec3 a_position; + out vec3 v_TexCoords; + + void main() + { + v_TexCoords = u_EnvRotation * a_position; + mat4 mat = u_ViewProjectionMatrix; + mat[3] = vec4(0.0, 0.0, 0.0, 0.1); + vec4 pos = mat * vec4(a_position, 1.0); + gl_Position = pos.xyww; + } + )" + }, + { + "cubemap.frag", R"( + precision highp float; +#include + uniform float u_EnvIntensity; + uniform float u_EnvBlurNormalized; + uniform int u_MipCount; + uniform samplerCube u_GGXEnvSampler; + + out vec4 FragColor; + in vec3 v_TexCoords; + + + void main() + { + vec4 color = textureLod(u_GGXEnvSampler, v_TexCoords, u_EnvBlurNormalized * float(u_MipCount - 1)); + color.rgb *= u_EnvIntensity; + color.a = 1.0; + + #ifdef LINEAR_OUTPUT + FragColor = color.rgba; + #else + FragColor = vec4(toneMap(color.rgb), color.a); + #endif + } + + )" + }, +}; + +static const lv_opengl_shader_t env_src_includes[] = { + { + "fullscreen.vert", R"( + precision highp float; + + in vec2 aPosition; + in vec2 aTexCoord; + + out vec2 texCoord; + + void main(void) + { + texCoord = aTexCoord; + gl_Position = vec4(aPosition, 0.0, 1.0); + } + )" + }, + { + "panorama_to_cubemap.frag", R"( + #define MATH_PI 3.1415926535897932384626433832795 + #define MATH_INV_PI (1.0 / MATH_PI) + + precision highp float; + + in vec2 texCoord; + out vec4 fragmentColor; + + uniform int u_currentFace; + uniform sampler2D u_panorama; + + vec3 uvToXYZ(int face, vec2 uv) + { + if(face == 0) + return vec3( 1.f, uv.y, -uv.x); + + else if(face == 1) + return vec3( -1.f, uv.y, uv.x); + + else if(face == 2) + return vec3( +uv.x, -1.f, +uv.y); + + else if(face == 3) + return vec3( +uv.x, 1.f, -uv.y); + + else if(face == 4) + return vec3( +uv.x, uv.y, 1.f); + + else //if(face == 5) + { return vec3( -uv.x, +uv.y, -1.f);} + } + + vec2 dirToUV(vec3 dir) + { + return vec2( + 0.5f + 0.5f * atan(dir.z, dir.x) / MATH_PI, + 1.f - acos(dir.y) / MATH_PI); + } + + vec3 panoramaToCubeMap(int face, vec2 texCoord) + { + vec2 texCoordNew = texCoord*2.0-1.0; + vec3 scan = uvToXYZ(face, texCoordNew); + vec3 direction = normalize(scan); + vec2 src = dirToUV(direction); + + return texture(u_panorama, src).rgb; + } + + void main(void) + { + fragmentColor = vec4(0.0, 0.0, 0.0, 1.0); + + fragmentColor.rgb = panoramaToCubeMap(u_currentFace, texCoord); + } + + )" + }, + { + "ibl_filtering.frag", R"( +#include +#include +#include +#include +#include +#include + )" + }, + { + "ibl_filtering1.glsl", R"( + + //#extension GL_ARB_separate_shader_objects : enable + + precision highp float; + #define MATH_PI 3.1415926535897932384626433832795 + //#define MATH_INV_PI (1.0 / MATH_PI) + + uniform samplerCube u_cubemapTexture; + + // enum + const int cLambertian = 0; + const int cGGX = 1; + const int cCharlie = 2; + + + //layout(push_constant) uniform FilterParameters { + uniform float u_roughness; + uniform int u_sampleCount; + uniform int u_width; + uniform float u_lodBias; + uniform int u_distribution; // enum + uniform int u_currentFace; + uniform int u_isGeneratingLUT; + + // 0: Byte Target Texture (normalized) + // 1: Float Target Texture + uniform int u_floatTexture; + + uniform float u_intensityScale; + + //layout (location = 0) in vec2 inUV; + in vec2 texCoord; + + + out vec4 fragmentColor; + + //layout(location = 6) out vec3 outLUT; + + + vec3 uvToXYZ(int face, vec2 uv) + { + if(face == 0) + return vec3( 1.f, uv.y, -uv.x); + + else if(face == 1) + return vec3( -1.f, uv.y, uv.x); + + else if(face == 2) + return vec3( +uv.x, -1.f, +uv.y); + + else if(face == 3) + return vec3( +uv.x, 1.f, -uv.y); + + else if(face == 4) + return vec3( +uv.x, uv.y, 1.f); + + else {//if(face == 5) + return vec3( -uv.x, +uv.y, -1.f);} + } + + vec2 dirToUV(vec3 dir) + { + return vec2( + 0.5f + 0.5f * atan(dir.z, dir.x) / MATH_PI, + 1.f - acos(dir.y) / MATH_PI); + } + + float saturate(float v) + { + return clamp(v, 0.0f, 1.0f); + } + + // Hammersley Points on the Hemisphere + // CC BY 3.0 (Holger Dammertz) + // http://holger.dammertz.org/stuff/notes_HammersleyOnHemisphere.html + // with adapted interface + float radicalInverse_VdC(uint bits) + { + bits = (bits << 16u) | (bits >> 16u); + bits = ((bits & 0x55555555u) << 1u) | ((bits & 0xAAAAAAAAu) >> 1u); + bits = ((bits & 0x33333333u) << 2u) | ((bits & 0xCCCCCCCCu) >> 2u); + bits = ((bits & 0x0F0F0F0Fu) << 4u) | ((bits & 0xF0F0F0F0u) >> 4u); + bits = ((bits & 0x00FF00FFu) << 8u) | ((bits & 0xFF00FF00u) >> 8u); + return float(bits) * 2.3283064365386963e-10; // / 0x100000000 + } + )" + }, + { + "ibl_filtering2.glsl", R"( + // hammersley2d describes a sequence of points in the 2d unit square [0,1)^2 + // that can be used for quasi Monte Carlo integration + vec2 hammersley2d(int i, int N) { + return vec2(float(i)/float(N), radicalInverse_VdC(uint(i))); + } + + // Hemisphere Sample + + // TBN generates a tangent bitangent normal coordinate frame from the normal + // (the normal must be normalized) + mat3 generateTBN(vec3 normal) + { + vec3 bitangent = vec3(0.0, 1.0, 0.0); + + float NdotUp = dot(normal, vec3(0.0, 1.0, 0.0)); + float epsilon = 0.0000001; + if (1.0 - abs(NdotUp) <= epsilon) + { + // Sampling +Y or -Y, so we need a more robust bitangent. + if (NdotUp > 0.0) + { + bitangent = vec3(0.0, 0.0, 1.0); + } + else + { + bitangent = vec3(0.0, 0.0, -1.0); + } + } + + vec3 tangent = normalize(cross(bitangent, normal)); + bitangent = cross(normal, tangent); + + return mat3(tangent, bitangent, normal); + } + + struct MicrofacetDistributionSample + { + float pdf; + float cosTheta; + float sinTheta; + float phi; + }; + + float D_GGX(float NdotH, float roughness) { + float a = NdotH * roughness; + float k = roughness / (1.0 - NdotH * NdotH + a * a); + return k * k * (1.0 / MATH_PI); + } + + // GGX microfacet distribution + // https://www.cs.cornell.edu/~srm/publications/EGSR07-btdf.html + // This implementation is based on https://bruop.github.io/ibl/, + // https://www.tobias-franke.eu/log/2014/03/30/notes_on_importance_sampling.html + // and https://developer.nvidia.com/gpugems/GPUGems3/gpugems3_ch20.html + MicrofacetDistributionSample GGX(vec2 xi, float roughness) + { + MicrofacetDistributionSample ggx; + + // evaluate sampling equations + float alpha = roughness * roughness; + ggx.cosTheta = saturate(sqrt((1.0 - xi.y) / (1.0 + (alpha * alpha - 1.0) * xi.y))); + ggx.sinTheta = sqrt(1.0 - ggx.cosTheta * ggx.cosTheta); + ggx.phi = 2.0 * MATH_PI * xi.x; + + // evaluate GGX pdf (for half vector) + ggx.pdf = D_GGX(ggx.cosTheta, alpha); + + // Apply the Jacobian to obtain a pdf that is parameterized by l + // see https://bruop.github.io/ibl/ + // Typically you'd have the following: + // float pdf = D_GGX(NoH, roughness) * NoH / (4.0 * VoH); + // but since V = N => VoH == NoH + ggx.pdf /= 4.0; + + return ggx; + } + + // NDF + float D_Ashikhmin(float NdotH, float roughness) + { + float alpha = roughness * roughness; + // Ashikhmin 2007, "Distribution-based BRDFs" + float a2 = alpha * alpha; + float cos2h = NdotH * NdotH; + float sin2h = 1.0 - cos2h; + float sin4h = sin2h * sin2h; + float cot2 = -cos2h / (a2 * sin2h); + return 1.0 / (MATH_PI * (4.0 * a2 + 1.0) * sin4h) * (4.0 * exp(cot2) + sin4h); + } + )" + }, + { + "ibl_filtering3.glsl", R"( + // NDF + float D_Charlie(float sheenRoughness, float NdotH) + { + sheenRoughness = max(sheenRoughness, 0.000001); //clamp (0,1] + float invR = 1.0 / sheenRoughness; + float cos2h = NdotH * NdotH; + float sin2h = 1.0 - cos2h; + return (2.0 + invR) * pow(sin2h, invR * 0.5) / (2.0 * MATH_PI); + } + + + MicrofacetDistributionSample Charlie(vec2 xi, float roughness) + { + MicrofacetDistributionSample charlie; + + float alpha = roughness * roughness; + charlie.sinTheta = pow(xi.y, alpha / (2.0*alpha + 1.0)); + charlie.cosTheta = sqrt(1.0 - charlie.sinTheta * charlie.sinTheta); + charlie.phi = 2.0 * MATH_PI * xi.x; + + // evaluate Charlie pdf (for half vector) + charlie.pdf = D_Charlie(alpha, charlie.cosTheta); + + // Apply the Jacobian to obtain a pdf that is parameterized by l + charlie.pdf /= 4.0; + + return charlie; + } + + MicrofacetDistributionSample Lambertian(vec2 xi, float roughness) + { + MicrofacetDistributionSample lambertian; + + // Cosine weighted hemisphere sampling + // http://www.pbr-book.org/3ed-2018/Monte_Carlo_Integration/2D_Sampling_with_Multidimensional_Transformations.html#Cosine-WeightedHemisphereSampling + lambertian.cosTheta = sqrt(1.0 - xi.y); + lambertian.sinTheta = sqrt(xi.y); // equivalent to `sqrt(1.0 - cosTheta*cosTheta)`; + lambertian.phi = 2.0 * MATH_PI * xi.x; + + lambertian.pdf = lambertian.cosTheta / MATH_PI; // evaluation for solid angle, therefore drop the sinTheta + + return lambertian; + } + + + // getImportanceSample returns an importance sample direction with pdf in the .w component + vec4 getImportanceSample(int sampleIndex, vec3 N, float roughness) + { + // generate a quasi monte carlo point in the unit square [0.1)^2 + vec2 xi = hammersley2d(sampleIndex, u_sampleCount); + + MicrofacetDistributionSample importanceSample; + + // generate the points on the hemisphere with a fitting mapping for + // the distribution (e.g. lambertian uses a cosine importance) + if(u_distribution == cLambertian) + { + importanceSample = Lambertian(xi, roughness); + } + else if(u_distribution == cGGX) + { + // Trowbridge-Reitz / GGX microfacet model (Walter et al) + // https://www.cs.cornell.edu/~srm/publications/EGSR07-btdf.html + importanceSample = GGX(xi, roughness); + } + else if(u_distribution == cCharlie) + { + importanceSample = Charlie(xi, roughness); + } + + // transform the hemisphere sample to the normal coordinate frame + // i.e. rotate the hemisphere to the normal direction + vec3 localSpaceDirection = normalize(vec3( + importanceSample.sinTheta * cos(importanceSample.phi), + importanceSample.sinTheta * sin(importanceSample.phi), + importanceSample.cosTheta + )); + mat3 TBN = generateTBN(N); + vec3 direction = TBN * localSpaceDirection; + + return vec4(direction, importanceSample.pdf); + } + )" + }, + { + "ibl_filtering4.glsl", R"( + // Mipmap Filtered Samples (GPU Gems 3, 20.4) + // https://developer.nvidia.com/gpugems/gpugems3/part-iii-rendering/chapter-20-gpu-based-importance-sampling + // https://cgg.mff.cuni.cz/~jaroslav/papers/2007-sketch-fis/Final_sap_0073.pdf + float computeLod(float pdf) + { + // // Solid angle of current sample -- bigger for less likely samples + //float omegaS = 1.0 / (float(u_sampleCount) * pdf); + // // Solid angle of texel + // // note: the factor of 4.0 * MATH_PI + //float omegaP = 4.0 * MATH_PI / (6.0 * float(u_width) * float(u_width)); + // // Mip level is determined by the ratio of our sample's solid angle to a texel's solid angle + // // note that 0.5 * log2 is equivalent to log4 + //float lod = 0.5 * log2(omegaS / omegaP); + + // babylon introduces a factor of K (=4) to the solid angle ratio + // this helps to avoid undersampling the environment map + // this does not appear in the original formulation by Jaroslav Krivanek and Mark Colbert + // log4(4) == 1 + // lod += 1.0; + + // We achieved good results by using the original formulation from Krivanek & Colbert adapted to cubemaps + + // https://cgg.mff.cuni.cz/~jaroslav/papers/2007-sketch-fis/Final_sap_0073.pdf + float lod = 0.5 * log2( 6.0 * float(u_width) * float(u_width) / (float(u_sampleCount) * pdf)); + //float lod = 0.5 * log2( 3.0 * float(u_width) * float(u_width) / (float(u_sampleCount) * pdf)); + + + return lod; + } + + vec3 filterColor(vec3 N) + { + //return textureLod(u_cubemapTexture, N, 3.0).rgb; + vec3 color = vec3(0.f); + float weight = 0.0f; + + for(int i = 0; i < u_sampleCount; ++i) + { + vec4 importanceSample = getImportanceSample(i, N, u_roughness); + + vec3 H = vec3(importanceSample.xyz); + float pdf = importanceSample.w; + + // mipmap filtered samples (GPU Gems 3, 20.4) + float lod = computeLod(pdf); + + // apply the bias to the lod + lod += u_lodBias; + + if(u_distribution == cLambertian) + { + // sample lambertian at a lower resolution to avoid fireflies + vec3 lambertian = textureLod(u_cubemapTexture, H, lod).rgb * u_intensityScale; + + //// the below operations cancel each other out + // lambertian *= NdotH; // lamberts law + // lambertian /= pdf; // invert bias from importance sampling + // lambertian /= MATH_PI; // convert irradiance to radiance https://seblagarde.wordpress.com/2012/01/08/pi-or-not-to-pi-in-game-lighting-equation/ + + color += lambertian; + } + else if(u_distribution == cGGX || u_distribution == cCharlie) + { + // Note: reflect takes incident vector. + vec3 V = N; + vec3 L = normalize(reflect(-V, H)); + + float NdotL = dot(N, L); + + if (NdotL > 0.0) + { + if(u_roughness == 0.0) + { + // without this the roughness=0 lod is too high + lod = u_lodBias; + } + vec3 sampleColor = textureLod(u_cubemapTexture, L, lod).rgb * u_intensityScale; + color += sampleColor * NdotL; + weight += NdotL; + } + } + } + + if(weight != 0.0f) + { + color /= weight; + } + else + { + color /= float(u_sampleCount); + } + + return color.rgb ; + } + )" + }, + { + "ibl_filtering5.glsl", R"( + // From the filament docs. Geometric Shadowing function + // https://google.github.io/filament/Filament.html#toc4.4.2 + float V_SmithGGXCorrelated(float NoV, float NoL, float roughness) { + float a2 = pow(roughness, 4.0); + float GGXV = NoL * sqrt(NoV * NoV * (1.0 - a2) + a2); + float GGXL = NoV * sqrt(NoL * NoL * (1.0 - a2) + a2); + return 0.5 / (GGXV + GGXL); + } + + // https://github.com/google/filament/blob/master/shaders/src/brdf.fs#L136 + float V_Ashikhmin(float NdotL, float NdotV) + { + return clamp(1.0 / (4.0 * (NdotL + NdotV - NdotL * NdotV)), 0.0, 1.0); + } + + // Compute LUT for GGX distribution. + // See https://blog.selfshadow.com/publications/s2013-shading-course/karis/s2013_pbs_epic_notes_v2.pdf + vec3 LUT(float NdotV, float roughness) + { + // Compute spherical view vector: (sin(phi), 0, cos(phi)) + vec3 V = vec3(sqrt(1.0 - NdotV * NdotV), 0.0, NdotV); + + // The macro surface normal just points up. + vec3 N = vec3(0.0, 0.0, 1.0); + + // To make the LUT independant from the material's F0, which is part of the Fresnel term + // when substituted by Schlick's approximation, we factor it out of the integral, + // yielding to the form: F0 * I1 + I2 + // I1 and I2 are slighlty different in the Fresnel term, but both only depend on + // NoL and roughness, so they are both numerically integrated and written into two channels. + float A = 0.0; + float B = 0.0; + float C = 0.0; + + for(int i = 0; i < u_sampleCount; ++i) + { + // Importance sampling, depending on the distribution. + vec4 importanceSample = getImportanceSample(i, N, roughness); + vec3 H = importanceSample.xyz; + // float pdf = importanceSample.w; + vec3 L = normalize(reflect(-V, H)); + + float NdotL = saturate(L.z); + float NdotH = saturate(H.z); + float VdotH = saturate(dot(V, H)); + if (NdotL > 0.0) + { + if (u_distribution == cGGX) + { + // LUT for GGX distribution. + + // Taken from: https://bruop.github.io/ibl + // Shadertoy: https://www.shadertoy.com/view/3lXXDB + // Terms besides V are from the GGX PDF we're dividing by. + float V_pdf = V_SmithGGXCorrelated(NdotV, NdotL, roughness) * VdotH * NdotL / NdotH; + float Fc = pow(1.0 - VdotH, 5.0); + A += (1.0 - Fc) * V_pdf; + B += Fc * V_pdf; + C += 0.0; + } + + if (u_distribution == cCharlie) + { + // LUT for Charlie distribution. + float sheenDistribution = D_Charlie(roughness, NdotH); + float sheenVisibility = V_Ashikhmin(NdotL, NdotV); + + A += 0.0; + B += 0.0; + C += sheenVisibility * sheenDistribution * NdotL * VdotH; + } + } + } + + // The PDF is simply pdf(v, h) -> NDF * . + // To parametrize the PDF over l, use the Jacobian transform, yielding to: pdf(v, l) -> NDF * / 4 + // Since the BRDF divide through the PDF to be normalized, the 4 can be pulled out of the integral. + return vec3(4.0 * A, 4.0 * B, 4.0 * 2.0 * MATH_PI * C) / float(u_sampleCount); + } + )" + }, + { + "ibl_filtering6.glsl", R"( + + + // entry point + void main() + { + vec3 color = vec3(0); + + if(u_isGeneratingLUT == 0) + { + vec2 newUV = texCoord ; + + newUV = newUV*2.0-1.0; + + vec3 scan = uvToXYZ(u_currentFace, newUV); + + vec3 direction = normalize(scan); + + color = filterColor(direction); + } + else + { + color = LUT(texCoord.x, texCoord.y); + fragmentColor.rgb = color; + fragmentColor.a = 1.0; + return; + } + + fragmentColor.a = 1.0; + + if(u_floatTexture == 0) + { + float maxV = max(max(color.r,color.g),color.b); + color /= u_intensityScale; + color = clamp(color, 0.0f, 1.0f); + } + + fragmentColor.rgb = color; + } + )" + }, + { + "debug.frag", R"( + + precision highp float; + + in vec2 texCoord; + out vec4 fragmentColor; + + uniform int u_currentFace; + uniform samplerCube u_inputTexture; + + vec3 uvToXYZ(int face, vec2 uv) + { + if(face == 0) + return vec3( 1.f, uv.y, -uv.x); + + else if(face == 1) + return vec3( -1.f, uv.y, uv.x); + + else if(face == 2) + return vec3( +uv.x, -1.f, +uv.y); + + else if(face == 3) + return vec3( +uv.x, 1.f, -uv.y); + + else if(face == 4) + return vec3( +uv.x, uv.y, 1.f); + + else //if(face == 5) + { return vec3( -uv.x, +uv.y, -1.f);} + } + + + void main(void) + { + fragmentColor = vec4(texCoord.x*10.0, 0.0, texCoord.y*10.0, 1.0); + vec2 newUV =texCoord; + newUV = newUV*2.0-1.0; + + vec4 textureColor = vec4(0.0, 0.0, 0.0, 1.0); + + vec3 direction = normalize(uvToXYZ(u_currentFace, newUV.xy)); + + textureColor = textureLod(u_inputTexture, direction,1.0); + //textureColor = texture(u_inputTexture, texCoord); + + if(texCoord.x>0.1) + { + fragmentColor = textureColor; + } + + if(texCoord.y>0.1) + { + fragmentColor = textureColor; + } + + } + )" + }, +}; + +static const char * src_vertex_shader = R"( + uniform mat4 u_ViewProjectionMatrix; + uniform mat4 u_ModelMatrix; + uniform mat4 u_NormalMatrix; + + in vec3 a_position; + out vec3 v_Position; +#include +#include +#include +// CHUNK 00 -> 01 +#include +)"; + +static const char *src_fragment_shader = R"( + + //#define LIGHT_COUNT 0 + + // + // This fragment shader defines a reference implementation for Physically Based Shading of + // a microfacet surface material defined by a glTF model. + // + // References: + // [1] Real Shading in Unreal Engine 4 + // http://blog.selfshadow.com/publications/s2013-shading-course/karis/s2013_pbs_epic_notes_v2.pdf + // [2] Physically Based Shading at Disney + // http://blog.selfshadow.com/publications/s2012-shading-course/burley/s2012_pbs_disney_brdf_notes_v3.pdf + // [3] README.md - Environment Maps + // https://github.com/KhronosGroup/glTF-WebGL-PBR/#environment-maps + // [4] "An Inexpensive BRDF Model for Physically based Rendering" by Christophe Schlick + // https://www.cs.virginia.edu/~jdl/bib/appearance/analytic%20models/schlick94b.pdf + // [5] "KHR_materials_clearcoat" + // https://github.com/KhronosGroup/glTF/tree/master/extensions/2.0/Khronos/KHR_materials_clearcoat + + precision highp float; + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + + #ifdef MATERIAL_IRIDESCENCE +#include + #endif + +#include + +// CHUNK 00 -> 01 + +#include +#include + +// CHUNK 01 -> 02 + +#include +#include + +// CHUNK 02 -> 03 + +#include +#include + +// CHUNK 03 -> 04 + +#include + +// CHUNK 04 -> 05 + +#include + +)"; + +static const size_t src_includes_count = sizeof src_includes / sizeof src_includes[0]; + +/********************** + * GLOBAL FUNCTIONS + **********************/ + +char* lv_gltf_view_shader_get_vertex(void) { + return lv_opengl_shader_manager_process_includes(src_vertex_shader, src_includes, src_includes_count); +} + +char* lv_gltf_view_shader_get_fragment(void) { + return lv_opengl_shader_manager_process_includes(src_fragment_shader, src_includes, src_includes_count); +} + +void lv_gltf_view_shader_get_src(lv_opengl_shader_portions_t *portions) +{ + portions->all = src_includes; + portions->count = sizeof(src_includes) / sizeof(src_includes[0]); +} +void lv_gltf_view_shader_get_env(lv_opengl_shader_portions_t *portions) +{ + portions->all = env_src_includes; + portions->count = sizeof(env_src_includes) / sizeof(env_src_includes[0]); +} + +#endif /*LV_USE_GLTF*/ diff --git a/src/libs/gltf/gltf_view/assets/lv_gltf_view_shader.h b/src/libs/gltf/gltf_view/assets/lv_gltf_view_shader.h new file mode 100644 index 0000000000..026a245ef6 --- /dev/null +++ b/src/libs/gltf/gltf_view/assets/lv_gltf_view_shader.h @@ -0,0 +1,39 @@ +/** + * @file lv_gltf_view_shader.h + * + */ + +#ifndef LV_GLTF_VIEW_SHADER_H +#define LV_GLTF_VIEW_SHADER_H + +#ifdef __cplusplus +extern "C" { +#endif + +/********************* + * INCLUDES + *********************/ +#include "../../../../drivers/opengles/opengl_shader/lv_opengl_shader_internal.h" + +#if LV_USE_GLTF + +/********************** + * GLOBAL PROTOTYPES + **********************/ + +char *lv_gltf_view_shader_get_vertex(void); +char *lv_gltf_view_shader_get_fragment(void); +void lv_gltf_view_shader_get_src(lv_opengl_shader_portions_t *shaders); +void lv_gltf_view_shader_get_env(lv_opengl_shader_portions_t *shaders); + +/********************** + * MACROS + **********************/ + +#endif /*LV_USE_GLTF*/ + +#ifdef __cplusplus +} /*extern "C"*/ +#endif + +#endif /*LV_GLTF_VIEW_SHADER_H*/ diff --git a/src/libs/gltf/gltf_view/ibl/lv_gltf_ibl_sampler.c b/src/libs/gltf/gltf_view/ibl/lv_gltf_ibl_sampler.c new file mode 100644 index 0000000000..d6f4d42c78 --- /dev/null +++ b/src/libs/gltf/gltf_view/ibl/lv_gltf_ibl_sampler.c @@ -0,0 +1,573 @@ +/** + * @file lv_gltf_ibl_sampler.c + * + */ + +/********************* + * INCLUDES + *********************/ + +#include "lv_gltf_ibl_sampler.h" + +#if LV_USE_GLTF + +#include "../../../../misc/lv_math.h" +#include "../../../../misc/lv_log.h" +#include "../../../../stdlib/lv_string.h" +#include "../../../../drivers/opengles/lv_opengles_private.h" +#include "../../../../drivers/opengles/lv_opengles_debug.h" + +#include "../../../../drivers/opengles/opengl_shader/lv_opengl_shader_internal.h" +#include "../lv_gltf_view_internal.h" +#include "../assets/lv_gltf_view_shader.h" + +#define STB_IMAGE_IMPLEMENTATION +#include "../../stb_image/stb_image.h" + +/********************* + * DEFINES + *********************/ + +#define INTERNAL_FORMAT GL_RGBA8 +#define TEXTURE_TARGET_TYPE GL_UNSIGNED_BYTE + +/********************** + * TYPEDEFS + **********************/ + +/********************** + * STATIC PROTOTYPES + **********************/ + +static void ibl_sampler_init(lv_gltf_ibl_sampler_t * sampler); +static void ibl_sampler_load(lv_gltf_ibl_sampler_t * sampler, const char * path); +static void ibl_sampler_filter(lv_gltf_ibl_sampler_t * sampler); +static void ibl_sampler_destroy(lv_gltf_ibl_sampler_t * sampler); +static bool ibl_gl_has_extension(const char * extension); +static void ibl_texture_from_image(lv_gltf_ibl_sampler_t * sampler, lv_gltf_ibl_texture_t * texture, + const lv_gltf_ibl_image_t * image); +static GLuint ibl_load_texture_hdr(lv_gltf_ibl_sampler_t * sampler, const lv_gltf_ibl_image_t * image); +static GLuint ibl_create_cubemap_texture(const lv_gltf_ibl_sampler_t * sampler, bool with_mipmaps); +static uint32_t ibl_create_lut_texture(const lv_gltf_ibl_sampler_t * sampler); +static void ibl_panorama_to_cubemap(lv_gltf_ibl_sampler_t * sampler); +static void ibl_apply_filter(lv_gltf_ibl_sampler_t * sampler, uint32_t distribution, float roughness, + uint32_t target_mip_level, GLuint target_texture, uint32_t sample_count, float lod_bias); +static void ibl_cubemap_to_lambertian(lv_gltf_ibl_sampler_t * sampler); +static void ibl_cubemap_to_ggx(lv_gltf_ibl_sampler_t * sampler); +static void ibl_cubemap_to_sheen(lv_gltf_ibl_sampler_t * sampler); +static void ibl_sample_lut(lv_gltf_ibl_sampler_t * sampler, uint32_t distribution, uint32_t targetTexture, + uint32_t currentTextureSize); +static void ibl_sample_ggx_lut(lv_gltf_ibl_sampler_t * sampler); +static void ibl_sample_charlie_lut(lv_gltf_ibl_sampler_t * sampler); +static int ibl_count_bits(int value); + +static void init_fullscreen_quad(lv_gltf_ibl_sampler_t * sampler); +static void draw_fullscreen_quad(lv_gltf_ibl_sampler_t * sampler, GLuint program_id); + +/********************** + * STATIC VARIABLES + **********************/ + +/********************** + * MACROS + **********************/ + +/********************** + * GLOBAL FUNCTIONS + **********************/ + +void lv_gltf_ibl_generate_env_textures(lv_gltf_view_env_textures_t * env, const char * path, float env_rotation) +{ + lv_gltf_ibl_sampler_t sampler; + + ibl_sampler_init(&sampler); + ibl_sampler_load(&sampler, path); + ibl_sampler_filter(&sampler); + + env->angle = env_rotation; + env->diffuse = sampler.lambertian_texture_id; + env->specular = sampler.ggx_texture_id; + env->sheen = sampler.sheen_texture_id; + env->ggxLut = sampler.ggxlut_texture_id; + env->charlie_lut = sampler.charlielut_texture_id; + env->mip_count = sampler.mipmap_levels; + env->ibl_intensity_scale = sampler.scale_value; + ibl_sampler_destroy(&sampler); +} + +/********************** + * STATIC FUNCTIONS + **********************/ + +static void ibl_sampler_init(lv_gltf_ibl_sampler_t * sampler) +{ + lv_memset(sampler, 0, sizeof(*sampler)); + sampler->texture_size = 128; + sampler->ggx_sample_count = 128; + sampler->lambertian_sample_count = 256; + sampler->sheen_sample_count = 32; + sampler->lod_bias = 0.0; + sampler->lowest_mip_level = 3; + sampler->lut_resolution = 1024; + sampler->lut_sample_count = 64; + sampler->scale_value = 1.0; + lv_opengl_shader_portions_t env_shader_portions; + lv_gltf_view_shader_get_env(&env_shader_portions); + lv_opengl_shader_manager_init(&sampler->shader_manager, env_shader_portions.all, env_shader_portions.count, NULL, + NULL); + init_fullscreen_quad(sampler); +} + +static void ibl_sampler_load(lv_gltf_ibl_sampler_t * sampler, const char * path) +{ + // vv -- WebGL Naming + if(ibl_gl_has_extension("GL_NV_float") && ibl_gl_has_extension("GL_ARB_color_buffer_float")) { + LV_LOG_INFO("Device supports float format textures"); + } + // Native naming #2 + if(ibl_gl_has_extension("GL_ARB_color_buffer_float") || ibl_gl_has_extension("GL_NV_half_float")) { + LV_LOG_INFO("Device supports half_float format textures"); + } + + int32_t src_width, src_height, src_nrChannels; + + float * data; + if(path != NULL) { + data = stbi_loadf(path, &src_width, &src_height, &src_nrChannels, 3); + } + else { + extern unsigned char chromatic_jpg[]; + extern unsigned int chromatic_jpg_len; + data = stbi_loadf_from_memory(chromatic_jpg, chromatic_jpg_len, &src_width, &src_height, &src_nrChannels, 3); + } + + { + lv_gltf_ibl_image_t panorama_image = { + .data = (float *)lv_malloc(src_width * src_height * 3 * sizeof(float)), + .data_len = src_width * src_height * 3, + .width = src_width, + .height = src_height, + }; + LV_ASSERT_MALLOC(panorama_image.data); + + lv_memcpy(panorama_image.data, data, panorama_image.data_len * sizeof(*panorama_image.data)); + stbi_image_free(data); + sampler->input_texture_id = ibl_load_texture_hdr(sampler, &panorama_image); + lv_free(panorama_image.data); + } + + GL_CALL(glGenFramebuffers(1, &sampler->framebuffer)); + GL_CALL(glBindFramebuffer(GL_FRAMEBUFFER, sampler->framebuffer)); + + sampler->cubemap_texture_id = ibl_create_cubemap_texture(sampler, true); + sampler->lambertian_texture_id = ibl_create_cubemap_texture(sampler, false); + sampler->ggx_texture_id = ibl_create_cubemap_texture(sampler, true); + sampler->sheen_texture_id = ibl_create_cubemap_texture(sampler, true); + + GL_CALL(glBindTexture(GL_TEXTURE_CUBE_MAP, sampler->ggx_texture_id)); + GL_CALL(glGenerateMipmap(GL_TEXTURE_CUBE_MAP)); + GL_CALL(glBindTexture(GL_TEXTURE_CUBE_MAP, sampler->sheen_texture_id)); + GL_CALL(glGenerateMipmap(GL_TEXTURE_CUBE_MAP)); + sampler->mipmap_levels = ibl_count_bits(sampler->texture_size) + 1 - sampler->lowest_mip_level; +} + +static void ibl_sampler_filter(lv_gltf_ibl_sampler_t * sampler) +{ + GLint prev_framebuffer; + GL_CALL(glGetIntegerv(GL_FRAMEBUFFER_BINDING, &prev_framebuffer)); + + ibl_panorama_to_cubemap(sampler); + GL_CALL(glBindFramebuffer(GL_FRAMEBUFFER, prev_framebuffer)); + + ibl_cubemap_to_lambertian(sampler); + GL_CALL(glBindFramebuffer(GL_FRAMEBUFFER, prev_framebuffer)); + + ibl_cubemap_to_ggx(sampler); + GL_CALL(glBindFramebuffer(GL_FRAMEBUFFER, prev_framebuffer)); + + ibl_cubemap_to_sheen(sampler); + GL_CALL(glBindFramebuffer(GL_FRAMEBUFFER, prev_framebuffer)); + + ibl_sample_ggx_lut(sampler); + GL_CALL(glBindFramebuffer(GL_FRAMEBUFFER, prev_framebuffer)); + + ibl_sample_charlie_lut(sampler); + GL_CALL(glBindFramebuffer(GL_FRAMEBUFFER, prev_framebuffer)); +} +static void ibl_sampler_destroy(lv_gltf_ibl_sampler_t * sampler) +{ + GL_CALL(glDeleteBuffers(1, &sampler->fullscreen_vertex_buffer)); + GL_CALL(glDeleteBuffers(1, &sampler->fullscreen_tex_coord_buffer)); + lv_opengl_shader_manager_deinit(&sampler->shader_manager); +} + +static void ibl_texture_from_image(lv_gltf_ibl_sampler_t * sampler, lv_gltf_ibl_texture_t * texture, + const lv_gltf_ibl_image_t * image) +{ + const size_t src_format_bpp = 3; + const size_t dst_format_bpp = 4; + + texture->internal_format = INTERNAL_FORMAT; + texture->format = GL_RGBA; + texture->type = TEXTURE_TARGET_TYPE; + size_t pixel_num = image->data_len / src_format_bpp; + texture->data = (uint8_t *)lv_malloc(pixel_num * 4); + LV_ASSERT_MALLOC(texture->data); + + float max_value = 0.0; + float clamped_sum = 0.0; + float diff_sum = 0.0; + size_t src = 0; + size_t dst = 0; + + for(size_t i = 0; i < pixel_num; i++) { + const float r = image->data[src + 0]; + const float g = image->data[src + 1]; + const float b = image->data[src + 2]; + const float max_component = LV_MAX(LV_MAX(r, g), b); + + if(max_component > 1.0) { + diff_sum += max_component - 1.0; + } + clamped_sum += LV_MIN(max_component, 1.0f); + max_value = LV_MAX(max_component, max_value); + + texture->data[dst + 0] = LV_MIN(r * 255, 255); + texture->data[dst + 1] = LV_MIN(g * 255, 255); + texture->data[dst + 2] = LV_MIN(b * 255, 255); + texture->data[dst + 3] = 0xFF; + + src += src_format_bpp; + dst += dst_format_bpp; + } + + float scale_factor = 1.0; + if(clamped_sum > 1.0) { + // Apply global scale factor to compensate for intensity lost when clamping + scale_factor = (clamped_sum + diff_sum) / clamped_sum; + LV_LOG_INFO("HDR Intensity Scale %f\n", scale_factor); + } + + sampler->scale_value = scale_factor; +} +static uint32_t ibl_load_texture_hdr(lv_gltf_ibl_sampler_t * sampler, const lv_gltf_ibl_image_t * image) +{ + lv_gltf_ibl_texture_t texture; + ibl_texture_from_image(sampler, &texture, image); + GLuint texture_id; + GL_CALL(glGenTextures(1, &texture_id)); + GL_CALL(glBindTexture(GL_TEXTURE_2D, texture_id)); + GL_CALL(glTexImage2D(GL_TEXTURE_2D, // target + 0, // level + texture.internal_format, image->width, image->height, + 0, // border + texture.format, // format of the pixel data + texture.type, // type of the pixel data + texture.data)); + + lv_free(texture.data); + + GL_CALL(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_MIRRORED_REPEAT)); + GL_CALL(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_MIRRORED_REPEAT)); + GL_CALL(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR)); + GL_CALL(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR)); + return texture_id; +} + +static GLuint ibl_create_cubemap_texture(const lv_gltf_ibl_sampler_t * sampler, bool with_mipmaps) +{ + uint32_t targetTexture; + GL_CALL(glGenTextures(1, &targetTexture)); + GL_CALL(glBindTexture(GL_TEXTURE_CUBE_MAP, targetTexture)); + for(int32_t i = 0; i < 6; ++i) { + GL_CALL(glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X + i, 0, INTERNAL_FORMAT, sampler->texture_size, + sampler->texture_size, 0, GL_RGBA, TEXTURE_TARGET_TYPE, NULL)); + } + if(with_mipmaps) { + GL_CALL(glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR)); + } + else { + GL_CALL(glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MIN_FILTER, GL_LINEAR)); + } + GL_CALL(glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MAG_FILTER, GL_LINEAR)); + GL_CALL(glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE)); + GL_CALL(glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE)); + return targetTexture; +} +static GLuint ibl_create_lut_texture(const lv_gltf_ibl_sampler_t * sampler) +{ + GLuint texture; + GL_CALL(glGenTextures(1, &texture)); + GL_CALL(glBindTexture(GL_TEXTURE_2D, texture)); + GL_CALL(glTexImage2D(GL_TEXTURE_2D, 0, INTERNAL_FORMAT, sampler->lut_resolution, sampler->lut_resolution, 0, GL_RGBA, + TEXTURE_TARGET_TYPE, NULL)); + GL_CALL(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR)); + GL_CALL(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR)); + GL_CALL(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE)); + GL_CALL(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE)); + return texture; +} +static void ibl_panorama_to_cubemap(lv_gltf_ibl_sampler_t * sampler) +{ + for(int32_t i = 0; i < 6; ++i) { + GL_CALL(glBindFramebuffer(GL_FRAMEBUFFER, sampler->framebuffer)); + GL_CALL(glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_CUBE_MAP_POSITIVE_X + i, + sampler->cubemap_texture_id, 0)); + GL_CALL(glBindTexture(GL_TEXTURE_CUBE_MAP, sampler->cubemap_texture_id)); + GLenum status = glCheckFramebufferStatus(GL_FRAMEBUFFER); + while(status != GL_FRAMEBUFFER_COMPLETE) { + status = glCheckFramebufferStatus(GL_FRAMEBUFFER); + LV_LOG_ERROR("Environnement render error not complete. Expected %d. Got %d", GL_FRAMEBUFFER_COMPLETE, + status); + } + GL_CALL(glViewport(0, 0, sampler->texture_size, sampler->texture_size)); + GL_CALL(glClearColor(1.0, 0.0, 0.0, 0.0)); + GL_CALL(glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT)); + uint32_t frag_shader_hash; + uint32_t vert_shader_hash; + lv_result_t res = lv_opengl_shader_manager_select_shader(&sampler->shader_manager, "panorama_to_cubemap.frag", NULL, 0, + LV_OPENGL_GLSL_VERSION_300ES, &frag_shader_hash); + LV_ASSERT(res == LV_RESULT_OK); + res = lv_opengl_shader_manager_select_shader(&sampler->shader_manager, "fullscreen.vert", NULL, 0, + LV_OPENGL_GLSL_VERSION_300ES, &vert_shader_hash); + LV_ASSERT(res == LV_RESULT_OK); + lv_opengl_shader_program_t * program = + lv_opengl_shader_manager_get_program(&sampler->shader_manager, frag_shader_hash, vert_shader_hash); + + LV_ASSERT_MSG(program != NULL, + "Failed to link program. This probably means your platform doesn't support GLSL version 300 es"); + + GLuint program_id = lv_opengl_shader_program_get_id(program); + + GL_CALL(glUseProgram(program_id)); + GL_CALL(glActiveTexture(GL_TEXTURE0 + 0)); + // Bind texture ID to active texture + GL_CALL(glBindTexture(GL_TEXTURE_2D, sampler->input_texture_id)); + // map shader uniform to texture unit (TEXTURE0) + GLuint location; + GL_CALL(location = glGetUniformLocation(program_id, "u_panorama")); + GL_CALL(glUniform1i(location, 0)); + program->update_uniform_1i(program, "u_currentFace", i); + //fullscreen triangle + draw_fullscreen_quad(sampler, program_id); + } + + GL_CALL(glBindTexture(GL_TEXTURE_CUBE_MAP, sampler->cubemap_texture_id)); + GL_CALL(glGenerateMipmap(GL_TEXTURE_CUBE_MAP)); +} +static void ibl_apply_filter(lv_gltf_ibl_sampler_t * sampler, uint32_t distribution, float roughness, + uint32_t target_mip_level, GLuint target_texture, uint32_t sample_count, float lod_bias) +{ + uint32_t current_texture_size = sampler->texture_size >> target_mip_level; + for(uint32_t i = 0; i < 6; ++i) { + GL_CALL(glBindFramebuffer(GL_FRAMEBUFFER, sampler->framebuffer)); + GL_CALL(glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_CUBE_MAP_POSITIVE_X + i, + target_texture, target_mip_level)); + GL_CALL(glBindTexture(GL_TEXTURE_CUBE_MAP, target_texture)); + GL_CALL(glViewport(0, 0, current_texture_size, current_texture_size)); + GL_CALL(glClearColor(0.0, 1.0, 0.0, 0.0)); + GL_CALL(glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT)); + + uint32_t frag_shader_hash; + uint32_t vert_shader_hash; + lv_result_t res = lv_opengl_shader_manager_select_shader(&sampler->shader_manager, "ibl_filtering.frag", NULL, 0, + LV_OPENGL_GLSL_VERSION_300ES, &frag_shader_hash); + LV_ASSERT(res == LV_RESULT_OK); + res = lv_opengl_shader_manager_select_shader(&sampler->shader_manager, "fullscreen.vert", NULL, 0, + LV_OPENGL_GLSL_VERSION_300ES, &vert_shader_hash); + LV_ASSERT(res == LV_RESULT_OK); + lv_opengl_shader_program_t * program = + lv_opengl_shader_manager_get_program(&sampler->shader_manager, frag_shader_hash, vert_shader_hash); + + LV_ASSERT_MSG(program != NULL, + "Failed to link program. This probably means your platform doesn't support GLSL version 300 es"); + GLuint program_id = lv_opengl_shader_program_get_id(program); + + + GL_CALL(glUseProgram(program_id)); + GL_CALL(glActiveTexture(GL_TEXTURE0)); + // Bind texture ID to active texture + GL_CALL(glBindTexture(GL_TEXTURE_CUBE_MAP, sampler->cubemap_texture_id)); + // map shader uniform to texture unit (TEXTURE0) + uint32_t location = glGetUniformLocation(program_id, "u_cubemapTexture"); + GL_CALL(glUniform1i(location, 0)); // texture unit 0 + program->update_uniform_1f(program, "u_roughness", roughness); + program->update_uniform_1i(program, "u_sampleCount", sample_count); + /* Software rendered mode looks better with this and horrible with below */ + /*program->update_uniform_1i(program, "u_width", current_texture_size); */ + /* Standard mode looks best with this and somewhat worse with above */ + program->update_uniform_1i(program, "u_width", sampler->texture_size); + program->update_uniform_1f(program, "u_lodBias", lod_bias); + program->update_uniform_1i(program, "u_distribution", distribution); + program->update_uniform_1i(program, "u_currentFace", i); + program->update_uniform_1i(program, "u_isGeneratingLUT", 0); + program->update_uniform_1i(program, "u_floatTexture", 0); + program->update_uniform_1f(program, "u_intensityScale", sampler->scale_value); + //fullscreen triangle + draw_fullscreen_quad(sampler, program_id); + } +} +static void ibl_cubemap_to_lambertian(lv_gltf_ibl_sampler_t * sampler) +{ + ibl_apply_filter(sampler, 0, 0.0, 0, sampler->lambertian_texture_id, sampler->lambertian_sample_count, 0.0); +} +static void ibl_cubemap_to_ggx(lv_gltf_ibl_sampler_t * sampler) +{ + LV_ASSERT(sampler->mipmap_levels != 1); + for(uint32_t current_mip_level = 0; current_mip_level <= sampler->mipmap_levels; ++current_mip_level) { + float roughness = (current_mip_level) / (float)(sampler->mipmap_levels - 1); + ibl_apply_filter(sampler, 1, roughness, current_mip_level, sampler->ggx_texture_id, sampler->ggx_sample_count, + 0.0); + } +} +static void ibl_cubemap_to_sheen(lv_gltf_ibl_sampler_t * sampler) +{ + LV_ASSERT(sampler->mipmap_levels != 1); + for(uint32_t current_mip_level = 0; current_mip_level <= sampler->mipmap_levels; ++current_mip_level) { + float roughness = (current_mip_level) / (float)(sampler->mipmap_levels - 1); + ibl_apply_filter(sampler, 2, roughness, current_mip_level, sampler->sheen_texture_id, + sampler->sheen_sample_count, 0.0); + } +} +static void ibl_sample_lut(lv_gltf_ibl_sampler_t * sampler, uint32_t distribution, uint32_t targetTexture, + uint32_t currentTextureSize) +{ + GL_CALL(glBindFramebuffer(GL_FRAMEBUFFER, sampler->framebuffer)); + GL_CALL(glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, targetTexture, 0)); + GL_CALL(glBindTexture(GL_TEXTURE_2D, targetTexture)); + GL_CALL(glViewport(0, 0, currentTextureSize, currentTextureSize)); + GL_CALL(glClearColor(0.0, 1.0, 1.0, 0.0)); + GL_CALL(glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT)); + uint32_t frag_shader; + uint32_t vert_shader; + lv_result_t res = lv_opengl_shader_manager_select_shader(&sampler->shader_manager, "ibl_filtering.frag", NULL, 0, + LV_OPENGL_GLSL_VERSION_300ES, &frag_shader); + LV_ASSERT(res == LV_RESULT_OK); + res = lv_opengl_shader_manager_select_shader(&sampler->shader_manager, "fullscreen.vert", NULL, 0, + LV_OPENGL_GLSL_VERSION_300ES, &vert_shader); + LV_ASSERT(res == LV_RESULT_OK); + lv_opengl_shader_program_t * program = lv_opengl_shader_manager_get_program(&sampler->shader_manager, frag_shader, + vert_shader); + LV_ASSERT_MSG(program != NULL, + "Failed to link program. This probably means your platform doesn't support GLSL version 300 es"); + + GLuint program_id = lv_opengl_shader_program_get_id(program); + + GL_CALL(glUseProgram(program_id)); + // TEXTURE0 = active. + GL_CALL(glActiveTexture(GL_TEXTURE0 + 0)); + // Bind texture ID to active texture + GL_CALL(glBindTexture(GL_TEXTURE_CUBE_MAP, sampler->cubemap_texture_id)); + // map shader uniform to texture unit (TEXTURE0) + uint32_t location = glGetUniformLocation(program_id, "u_cubemapTexture"); + GL_CALL(glUniform1i(location, 0)); // texture unit 0 + program->update_uniform_1f(program, "u_roughness", 0.0); + program->update_uniform_1i(program, "u_sampleCount", sampler->lut_sample_count); + //shader->update_uniform_1i( shader, "u_sampleCount", 512); + program->update_uniform_1i(program, "u_width", 0.0); + program->update_uniform_1f(program, "u_lodBias", 0.0); + program->update_uniform_1i(program, "u_distribution", distribution); + program->update_uniform_1i(program, "u_currentFace", 0); + program->update_uniform_1i(program, "u_isGeneratingLUT", 1); + //fullscreen triangle + draw_fullscreen_quad(sampler, program_id); +} +static void ibl_sample_ggx_lut(lv_gltf_ibl_sampler_t * sampler) +{ + sampler->ggxlut_texture_id = ibl_create_lut_texture(sampler); + ibl_sample_lut(sampler, 1, sampler->ggxlut_texture_id, sampler->lut_resolution); +} +static void ibl_sample_charlie_lut(lv_gltf_ibl_sampler_t * sampler) +{ + sampler->charlielut_texture_id = ibl_create_lut_texture(sampler); + ibl_sample_lut(sampler, 2, sampler->charlielut_texture_id, sampler->lut_resolution); +} + +static bool ibl_gl_has_extension(const char * extension) +{ + const GLubyte * extensions = glGetString(GL_EXTENSIONS); + if(!extensions) { + return false; + } + + const char * ext_str = (const char *)extensions; + const char * current = ext_str; + const char * next; + + while(*current) { + /* Find the next space or end of string */ + next = strchr(current, ' '); + if(next) { + size_t length = next - current; + if(length == strlen(extension) && strncmp(current, extension, length) == 0) { + return true; + } + current = next + 1; + } + else { + /* Last extension (no space found) */ + if(strcmp(current, extension) == 0) { + return true; + } + break; + } + } + return false; +} + +static int ibl_count_bits(int value) +{ + int count = 0; + while(value > 1) { + value >>= 1; + count++; + } + return count; +} + +static void init_fullscreen_quad(lv_gltf_ibl_sampler_t * sampler) +{ + /* Vertices go from -1 -1 (left bottom) to 1 1 (right top)*/ + GLfloat vertices[] = { + -1.0f, -1.0f, + 1.0f, -1.0f, + -1.0f, 1.0f, + 1.0f, 1.0f + }; + + /* Texture coords go from 0 0 (left botton) to 1 1 (right top)*/ + GLfloat texCoords[] = { + 0.0f, 0.0f, + 1.0f, 0.0f, + 0.0f, 1.0f, + 1.0f, 1.0f + }; + + GL_CALL(glGenBuffers(1, &sampler->fullscreen_vertex_buffer)); + GL_CALL(glBindBuffer(GL_ARRAY_BUFFER, sampler->fullscreen_vertex_buffer)); + GL_CALL(glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW)); + + GL_CALL(glGenBuffers(1, &sampler->fullscreen_tex_coord_buffer)); + GL_CALL(glBindBuffer(GL_ARRAY_BUFFER, sampler->fullscreen_tex_coord_buffer)); + GL_CALL(glBufferData(GL_ARRAY_BUFFER, sizeof(texCoords), texCoords, GL_STATIC_DRAW)); +} + +void draw_fullscreen_quad(lv_gltf_ibl_sampler_t * sampler, GLuint program_id) +{ + GLuint positionAttrib = glGetAttribLocation(program_id, "aPosition"); + GL_CALL(glEnableVertexAttribArray(positionAttrib)); + GL_CALL(glBindBuffer(GL_ARRAY_BUFFER, sampler->fullscreen_vertex_buffer)); + GL_CALL(glVertexAttribPointer(positionAttrib, 2, GL_FLOAT, GL_FALSE, 0, (void *)0)); + + GLuint texCoordAttrib = glGetAttribLocation(program_id, "aTexCoord"); + GL_CALL(glEnableVertexAttribArray(texCoordAttrib)); + GL_CALL(glBindBuffer(GL_ARRAY_BUFFER, sampler->fullscreen_tex_coord_buffer)); + GL_CALL(glVertexAttribPointer(texCoordAttrib, 2, GL_FLOAT, GL_FALSE, 0, (void *)0)); + + GL_CALL(glDrawArrays(GL_TRIANGLE_STRIP, 0, 4)); + + GL_CALL(glDisableVertexAttribArray(positionAttrib)); + GL_CALL(glDisableVertexAttribArray(texCoordAttrib)); +} + +#endif /*LV_USE_GLTF*/ diff --git a/src/libs/gltf/gltf_view/ibl/lv_gltf_ibl_sampler.h b/src/libs/gltf/gltf_view/ibl/lv_gltf_ibl_sampler.h new file mode 100644 index 0000000000..6645e3203d --- /dev/null +++ b/src/libs/gltf/gltf_view/ibl/lv_gltf_ibl_sampler.h @@ -0,0 +1,96 @@ +/** + * @file lv_gltf_ibl_sampler.h + * + */ + +#ifndef LV_GLTF_IBL_SAMPLER_H +#define LV_GLTF_IBL_SAMPLER_H + +#ifdef __cplusplus +extern "C" { +#endif + +/********************* + * INCLUDES + *********************/ +#include "../../../../lv_conf_internal.h" + +#if LV_USE_GLTF +#include "../../../../misc/lv_types.h" +#include "../../../../drivers/opengles/opengl_shader/lv_opengl_shader_internal.h" +#include "../lv_gltf_view_internal.h" + +/********************* + * DEFINES + *********************/ + +/********************** + * TYPEDEFS + **********************/ + +typedef struct { + uint32_t texture_size; + float lod_bias; + uint32_t lowest_mip_level; + uint32_t input_texture_id; + uint32_t cubemap_texture_id; + uint32_t framebuffer; + uint32_t mipmap_count; + + uint32_t lambertian_texture_id; + uint32_t lambertian_sample_count; + + uint32_t ggx_sample_count; + uint32_t ggx_texture_id; + + uint32_t sheen_texture_id; + uint32_t sheen_sample_count; + + uint32_t ggxlut_texture_id; + + uint32_t lut_sample_count; + uint32_t lut_resolution; + + uint32_t charlielut_texture_id; + + float scale_value; + uint32_t mipmap_levels; + + lv_opengl_shader_manager_t shader_manager; + + uint32_t fullscreen_vertex_buffer; + uint32_t fullscreen_tex_coord_buffer; + +} lv_gltf_ibl_sampler_t; + +typedef struct { + uint8_t * data; + uint32_t internal_format; + uint32_t format; + uint32_t type; +} lv_gltf_ibl_texture_t; + +typedef struct { + float * data; + size_t data_len; + uint32_t width; + uint32_t height; +} lv_gltf_ibl_image_t; + +/********************** + * GLOBAL PROTOTYPES + **********************/ + +void lv_gltf_ibl_generate_env_textures(lv_gltf_view_env_textures_t * env, const char * env_file_path, + float env_rotation); + +/********************** + * MACROS + **********************/ + +#endif /*LV_USE_GLTF*/ +#ifdef __cplusplus +} /*extern "C"*/ +#endif + +#endif /*LV_GLTF_IBL_SAMPLER_H*/ diff --git a/src/libs/gltf/gltf_view/lv_gltf.h b/src/libs/gltf/gltf_view/lv_gltf.h new file mode 100644 index 0000000000..c5a02aa188 --- /dev/null +++ b/src/libs/gltf/gltf_view/lv_gltf.h @@ -0,0 +1,353 @@ +/** + * @file lv_gltf.h + * + */ + +#ifndef LV_GLTF_H +#define LV_GLTF_H + +/********************* + * INCLUDES + *********************/ + +#include "../../../lv_conf_internal.h" + +#if LV_USE_GLTF + +#include "../../../misc/lv_types.h" +#include "../../../misc/lv_color.h" +#include "../gltf_data/lv_gltf_model.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/********************* + * DEFINES + *********************/ + +#define LV_GLTF_DEFAULT_CAMERA 0 + +/********************** + * TYPEDEFS + **********************/ + +typedef enum { + LV_GLTF_AA_MODE_OFF = 0, /** Anti aliasing off*/ + LV_GLTF_AA_MODE_ON = 1, /** Anti aliasing on*/ + LV_GLTF_AA_MODE_DYNAMIC = 2, /** Anti aliasing on only when frame has no movement*/ +} lv_gltf_aa_mode_t; + +typedef enum { + LV_GLTF_BG_MODE_SOLID = 0, /** Solid background. Use `lv_obj_set_style_bg_color` to set the background color*/ + LV_GLTF_BG_MODE_ENVIRONMENT = 1, /** Environnement background*/ +} lv_gltf_bg_mode_t; + +#define LV_GLTF_ANIM_SPEED_TENTH 100 +#define LV_GLTF_ANIM_SPEED_QUARTER 250 +#define LV_GLTF_ANIM_SPEED_HALF 500 +#define LV_GLTF_ANIM_SPEED_NORMAL 1000 +#define LV_GLTF_ANIM_SPEED_2X 2000 +#define LV_GLTF_ANIM_SPEED_3X 3000 +#define LV_GLTF_ANIM_SPEED_4X 4000 + +/********************** + * GLOBAL PROTOTYPES + **********************/ + +/** + * Create a GLTF viewer object + * @param parent pointer to the parent object + * @return pointer to the created GLTF viewer object + */ +lv_obj_t * lv_gltf_create(lv_obj_t * parent); + +/** + * Load a GLTF model from a file into the viewer + * @param obj pointer to a GLTF viewer object + * @param path file path to the GLTF model to load + * @return pointer to the loaded GLTF model, or NULL on failure + */ +lv_gltf_model_t * lv_gltf_load_model_from_file(lv_obj_t * obj, const char * path); + +/** + * Get the number of models loaded in the GLTF viewer + * @param obj pointer to a GLTF viewer object + * @return the total number of models in the viewer + */ +size_t lv_gltf_get_model_count(lv_obj_t * obj); + +/** + * Get a specific model by its index + * @param obj pointer to a GLTF viewer object + * @param id index of the model to retrieve (0-based) + * @return pointer to the model at the specified index, or NULL if index is invalid + */ +lv_gltf_model_t * lv_gltf_get_model_by_index(lv_obj_t * obj, size_t id); + +/** + * Get the primary model from the GLTF viewer + * The primary model is the first model added to the viewer and can be used + * for camera selection and other primary operations + * @param obj pointer to a GLTF viewer object + * @return pointer to the primary model, or NULL if no models are loaded + */ +lv_gltf_model_t * lv_gltf_get_primary_model(lv_obj_t * obj); + +/** + * Set the yaw (horizontal rotation) of the camera + * @param obj pointer to a GLTF viewer object + * @param yaw yaw angle in degrees + */ +void lv_gltf_set_yaw(lv_obj_t * obj, float yaw); + +/** + * Get the yaw (horizontal rotation) of the camera + * @param obj pointer to a GLTF viewer object + * @return yaw angle in degrees + */ +float lv_gltf_get_yaw(const lv_obj_t * obj); + +/** + * Set the pitch (vertical rotation) of the camera + * @param obj pointer to a GLTF viewer object + * @param pitch pitch angle in degrees + */ +void lv_gltf_set_pitch(lv_obj_t * obj, float pitch); + +/** + * Get the pitch (vertical rotation) of the camera + * @param obj pointer to a GLTF viewer object + * @return pitch angle in degrees + */ +float lv_gltf_get_pitch(const lv_obj_t * obj); + +/** + * Set the camera distance from the focal point + * @param obj pointer to a GLTF viewer object + * @param value distance value + */ +void lv_gltf_set_distance(lv_obj_t * obj, float value); + +/** + * Get the camera distance from the focal point + * @param obj pointer to a GLTF viewer object + * @return distance value + */ +float lv_gltf_get_distance(const lv_obj_t * obj); + +/********************** + * Viewport Functions + **********************/ + +/** + * Set the field of view + * @param obj pointer to a GLTF viewer object + * @param value vertical FOV in degrees. If zero, the view will be orthographic (non-perspective) + */ +void lv_gltf_set_fov(lv_obj_t * obj, float value); + +/** + * Get the field of view + * @param obj pointer to a GLTF viewer object + * @return vertical FOV in degrees + */ +float lv_gltf_get_fov(const lv_obj_t * obj); + +/********************** + * Focal Point Functions + **********************/ + +/** + * Set the X coordinate of the camera focal point + * @param obj pointer to a GLTF viewer object + * @param value X coordinate + */ +void lv_gltf_set_focal_x(lv_obj_t * obj, float value); + +/** + * Get the X coordinate of the camera focal point + * @param obj pointer to a GLTF viewer object + * @return X coordinate + */ +float lv_gltf_get_focal_x(const lv_obj_t * obj); + +/** + * Set the Y coordinate of the camera focal point + * @param obj pointer to a GLTF viewer object + * @param value Y coordinate + */ +void lv_gltf_set_focal_y(lv_obj_t * obj, float value); + +/** + * Get the Y coordinate of the camera focal point + * @param obj pointer to a GLTF viewer object + * @return Y coordinate + */ +float lv_gltf_get_focal_y(const lv_obj_t * obj); + +/** + * Set the Z coordinate of the camera focal point + * @param obj pointer to a GLTF viewer object + * @param value Z coordinate + */ +void lv_gltf_set_focal_z(lv_obj_t * obj, float value); + +/** + * Get the Z coordinate of the camera focal point + * @param obj pointer to a GLTF viewer object + * @return Z coordinate + */ +float lv_gltf_get_focal_z(const lv_obj_t * obj); + +/** + * Set the focal coordinates to the center point of the model object + * @param obj pointer to a GLTF viewer object + * @param model a model attached to this viewer or NULL for the first model + */ +void lv_gltf_recenter(lv_obj_t * obj, lv_gltf_model_t * model); + +/********************** + * Scene Control Functions + **********************/ + +/** + * Set the active camera index + * The camera is selected from the first GLTF model added to the viewer + * + * @param obj pointer to a GLTF viewer object + * @param value camera index (0 for default camera, 1+ for scene camera index) + * @note Values higher than the scene's camera count will be clamped to the maximum available camera index + */ +void lv_gltf_set_camera(lv_obj_t * obj, uint32_t value); + +/** + * Get the active camera index + * @param obj pointer to a GLTF viewer object + * @return active camera index + */ +uint32_t lv_gltf_get_camera(const lv_obj_t * obj); + +/** + * Get the number of cameras in the first GLTF model added to the viewer + * This count represents the valid range for the camera index parameter + * used with lv_gltf_set_camera() + * + * To get the camera count of other models, call + * lv_gltf_model_get_camera_count(model) directly with the specific model + * + * @param obj pointer to a GLTF viewer object + * @return number of available cameras + */ +uint32_t lv_gltf_get_camera_count(const lv_obj_t * obj); + +/** + * Set the animation speed ratio + * + * The actual ratio is the value parameter / LV_GLTF_ANIM_SPEED_NORMAL + * Values greater than LV_GLTF_ANIM_SPEED_NORMAL will speed-up the animation + * Values less than LV_GLTF_ANIM_SPEED_NORMAL will slow down the animation + * + * @param obj pointer to a GLTF viewer object + * @param value speed-up ratio of the animation + */ +void lv_gltf_set_animation_speed(lv_obj_t * obj, uint32_t value); + +/** + * Get the animation speed ratio + * + * The actual ratio is the return value / LV_GLTF_ANIM_SPEED_NORMAL + * + * @param obj pointer to a GLTF viewer object + */ +uint32_t lv_gltf_get_animation_speed(const lv_obj_t * obj); + +/********************** + * Visual Settings Functions + **********************/ + +/** + * Set the background mode + * @param obj pointer to a GLTF viewer object + * @param value background mode + */ +void lv_gltf_set_background_mode(lv_obj_t * obj, lv_gltf_bg_mode_t value); + +/** + * Get the background mode + * @param obj pointer to a GLTF viewer object + * @return background mode + */ +lv_gltf_bg_mode_t lv_gltf_get_background_mode(const lv_obj_t * obj); + +/** + * Set the background blur amount + * @param obj pointer to a GLTF viewer object + * @param value blur amount between 0 and 100 + */ +void lv_gltf_set_background_blur(lv_obj_t * obj, uint32_t value); + +/** + * Get the background blur amount + * @param obj pointer to a GLTF viewer object + * @return blur amount between 0 and 100 + */ +uint32_t lv_gltf_get_background_blur(const lv_obj_t * obj); + +/** + * Set the environmental brightness/power + * @param obj pointer to a GLTF viewer object + * @param value brightness multiplier + */ +void lv_gltf_set_env_brightness(lv_obj_t * obj, uint32_t value); + +/** + * Get the environmental brightness/power + * @param obj pointer to a GLTF viewer object + * @return brightness multiplier + */ +uint32_t lv_gltf_get_env_brightness(const lv_obj_t * obj); + +/** + * Set the image exposure level + * @param obj pointer to a GLTF viewer object + * @param value exposure level (1.0 is default) + */ +void lv_gltf_set_image_exposure(lv_obj_t * obj, float value); + +/** + * Get the image exposure level + * @param obj pointer to a GLTF viewer object + * @return exposure level + */ +float lv_gltf_get_image_exposure(const lv_obj_t * obj); + +/********************** + * Rendering Functions + **********************/ + +/** + * Set the anti-aliasing mode + * @param obj pointer to a GLTF viewer object + * @param value anti-aliasing mode + */ +void lv_gltf_set_antialiasing_mode(lv_obj_t * obj, lv_gltf_aa_mode_t value); + +/** + * Get the anti-aliasing mode + * @param obj pointer to a GLTF viewer object + * @return anti-aliasing mode + */ +lv_gltf_aa_mode_t lv_gltf_get_antialiasing_mode(const lv_obj_t * obj); + +/********************** + * MACROS + **********************/ + +#ifdef __cplusplus +} +#endif + +#endif /*LV_USE_GLTF*/ + +#endif /*LV_GLTF_H*/ diff --git a/src/libs/gltf/gltf_view/lv_gltf_view.cpp b/src/libs/gltf/gltf_view/lv_gltf_view.cpp new file mode 100644 index 0000000000..bd47c76eeb --- /dev/null +++ b/src/libs/gltf/gltf_view/lv_gltf_view.cpp @@ -0,0 +1,676 @@ +/** + * @file lv_gltf_view.c + * + */ + +/********************* + * INCLUDES + *********************/ + +#include "lv_gltf_view_internal.h" + +#if LV_USE_GLTF + +#include "../gltf_data/lv_gltf_model.h" +#include "../gltf_data/lv_gltf_data_internal.hpp" +#include "../../../draw/lv_draw_3d.h" +#include "../fastgltf/lv_fastgltf.hpp" +#include "../../../core/lv_obj_class_private.h" +#include "../../../misc/lv_types.h" +#include "../../../widgets/3dtexture/lv_3dtexture.h" +#include "ibl/lv_gltf_ibl_sampler.h" +#include "assets/lv_gltf_view_shader.h" +#include +#include + +/********************* + * DEFINES + *********************/ + + +#define MY_CLASS (&lv_gltf_class) + +#ifndef LV_GLTF_INITIAL_MODEL_CAPACITY + #define LV_GLTF_INITIAL_MODEL_CAPACITY 1 +#endif /*LV_GLTF_INITIAL_MODEL_CAPACITY*/ + +/********************** + * TYPEDEFS + **********************/ + +/********************** + * STATIC PROTOTYPES + **********************/ + +static lv_gltf_model_t * lv_gltf_add_model(lv_gltf_t * viewer, lv_gltf_model_t * model); +static void lv_gltf_constructor(const lv_obj_class_t * class_p, lv_obj_t * obj); +static void lv_gltf_destructor(const lv_obj_class_t * class_p, lv_obj_t * obj); +static void lv_gltf_event(const lv_obj_class_t * class_p, lv_event_t * e); +static void lv_gltf_view_state_init(lv_gltf_t * state); +static void lv_gltf_view_desc_init(lv_gltf_view_desc_t * state); +static void lv_gltf_parse_model(lv_gltf_t * viewer, lv_gltf_model_t * model); +static void destroy_environment(lv_gltf_view_env_textures_t * env); +static void setup_compile_and_load_bg_shader(lv_opengl_shader_manager_t * manager); +static void setup_background_environment(GLuint program, GLuint * vao, GLuint * indexBuffer, GLuint * vertexBuffer); + + +const lv_obj_class_t lv_gltf_class = { + &lv_3dtexture_class, + lv_gltf_constructor, + lv_gltf_destructor, + lv_gltf_event, +#if LV_USE_OBJ_PROPERTY + 0, + 0, + NULL, + 0, + NULL, + 0, +#endif + NULL, + "lv_gltf", + LV_DPI_DEF * 2, + LV_DPI_DEF / 10, + LV_OBJ_CLASS_EDITABLE_INHERIT, + LV_OBJ_CLASS_GROUP_DEF_INHERIT, + sizeof(lv_gltf_t), + LV_OBJ_CLASS_THEME_INHERITABLE_FALSE +}; + +/********************** + * STATIC VARIABLES + **********************/ + +/********************** + * MACROS + **********************/ + +/********************** + * GLOBAL FUNCTIONS + **********************/ + +lv_obj_t * lv_gltf_create(lv_obj_t * parent) +{ + lv_obj_t * obj = lv_obj_class_create_obj(MY_CLASS, parent); + lv_obj_class_init_obj(obj); + return obj; +} + +lv_gltf_model_t * lv_gltf_load_model_from_file(lv_obj_t * obj, const char * path) +{ + LV_ASSERT_NULL(obj); + LV_ASSERT_OBJ(obj, MY_CLASS); + lv_gltf_t * viewer = (lv_gltf_t *)obj; + lv_gltf_model_t * model = lv_gltf_data_load_from_file(path, &viewer->shader_manager); + return lv_gltf_add_model(viewer, model); +} + +lv_gltf_model_t * lv_gltf_load_model_from_bytes(lv_obj_t * obj, const uint8_t * bytes, size_t len) +{ + LV_ASSERT_NULL(obj); + LV_ASSERT_OBJ(obj, MY_CLASS); + lv_gltf_t * viewer = (lv_gltf_t *)obj; + lv_gltf_model_t * model = lv_gltf_data_load_from_bytes(bytes, len, &viewer->shader_manager); + return lv_gltf_add_model(viewer, model); +} + +size_t lv_gltf_get_model_count(lv_obj_t * obj) +{ + LV_ASSERT_NULL(obj); + LV_ASSERT_OBJ(obj, MY_CLASS); + + return lv_array_size(&((lv_gltf_t *)obj)->models); +} + +lv_gltf_model_t * lv_gltf_get_model_by_index(lv_obj_t * obj, size_t id) +{ + + LV_ASSERT_NULL(obj); + LV_ASSERT_OBJ(obj, MY_CLASS); + lv_gltf_t * viewer = (lv_gltf_t *) obj; + + if(id >= lv_array_size(&viewer->models)) { + return NULL; + } + return *(lv_gltf_model_t **)lv_array_at(&((lv_gltf_t *)obj)->models, id); + +} +lv_gltf_model_t * lv_gltf_get_primary_model(lv_obj_t * obj) +{ + + return lv_gltf_get_model_by_index(obj, 0); +} + +void lv_gltf_set_yaw(lv_obj_t * obj, float yaw) +{ + LV_ASSERT_NULL(obj); + LV_ASSERT_OBJ(obj, MY_CLASS); + lv_gltf_t * viewer = (lv_gltf_t *)obj; + viewer->desc.yaw = yaw; + lv_obj_invalidate(obj); +} + +float lv_gltf_get_yaw(const lv_obj_t * obj) +{ + LV_ASSERT_NULL(obj); + LV_ASSERT_OBJ(obj, MY_CLASS); + lv_gltf_t * viewer = (lv_gltf_t *)obj; + return viewer->desc.yaw; +} + +void lv_gltf_set_pitch(lv_obj_t * obj, float pitch) +{ + LV_ASSERT_NULL(obj); + LV_ASSERT_OBJ(obj, MY_CLASS); + lv_gltf_t * viewer = (lv_gltf_t *)obj; + viewer->desc.pitch = pitch; + lv_obj_invalidate(obj); +} + +float lv_gltf_get_pitch(const lv_obj_t * obj) +{ + LV_ASSERT_NULL(obj); + LV_ASSERT_OBJ(obj, MY_CLASS); + lv_gltf_t * viewer = (lv_gltf_t *)obj; + return viewer->desc.pitch; +} + +void lv_gltf_set_fov(lv_obj_t * obj, float value) +{ + LV_ASSERT_NULL(obj); + LV_ASSERT_OBJ(obj, MY_CLASS); + lv_gltf_t * viewer = (lv_gltf_t *)obj; + viewer->desc.fov = value; + lv_obj_invalidate(obj); +} + +float lv_gltf_get_fov(const lv_obj_t * obj) +{ + LV_ASSERT_NULL(obj); + LV_ASSERT_OBJ(obj, MY_CLASS); + lv_gltf_t * viewer = (lv_gltf_t *)obj; + return viewer->desc.fov; +} + +void lv_gltf_set_distance(lv_obj_t * obj, float value) +{ + LV_ASSERT_NULL(obj); + LV_ASSERT_OBJ(obj, MY_CLASS); + lv_gltf_t * viewer = (lv_gltf_t *)obj; + viewer->desc.distance = value; + lv_obj_invalidate(obj); +} + +float lv_gltf_get_distance(const lv_obj_t * obj) +{ + LV_ASSERT_NULL(obj); + LV_ASSERT_OBJ(obj, MY_CLASS); + lv_gltf_t * viewer = (lv_gltf_t *)obj; + return viewer->desc.distance; +} + +void lv_gltf_set_animation_speed(lv_obj_t * obj, uint32_t value) +{ + LV_ASSERT_NULL(obj); + LV_ASSERT_OBJ(obj, MY_CLASS); + lv_gltf_t * viewer = (lv_gltf_t *)obj; + viewer->desc.animation_speed_ratio = value; + lv_obj_invalidate(obj); +} + +uint32_t lv_gltf_get_animation_speed(const lv_obj_t * obj) +{ + LV_ASSERT_NULL(obj); + LV_ASSERT_OBJ(obj, MY_CLASS); + lv_gltf_t * viewer = (lv_gltf_t *)obj; + return viewer->desc.animation_speed_ratio; +} + +void lv_gltf_set_focal_x(lv_obj_t * obj, float value) +{ + LV_ASSERT_NULL(obj); + LV_ASSERT_OBJ(obj, MY_CLASS); + lv_gltf_t * viewer = (lv_gltf_t *)obj; + viewer->desc.focal_x = value; + lv_obj_invalidate(obj); +} + +float lv_gltf_get_focal_x(const lv_obj_t * obj) +{ + LV_ASSERT_NULL(obj); + LV_ASSERT_OBJ(obj, MY_CLASS); + lv_gltf_t * viewer = (lv_gltf_t *)obj; + return viewer->desc.focal_x; +} + +void lv_gltf_set_focal_y(lv_obj_t * obj, float value) +{ + LV_ASSERT_NULL(obj); + LV_ASSERT_OBJ(obj, MY_CLASS); + lv_gltf_t * viewer = (lv_gltf_t *)obj; + viewer->desc.focal_y = value; + lv_obj_invalidate(obj); +} + +float lv_gltf_get_focal_y(const lv_obj_t * obj) +{ + LV_ASSERT_NULL(obj); + LV_ASSERT_OBJ(obj, MY_CLASS); + lv_gltf_t * viewer = (lv_gltf_t *)obj; + return viewer->desc.focal_y; +} + +void lv_gltf_set_focal_z(lv_obj_t * obj, float value) +{ + LV_ASSERT_NULL(obj); + LV_ASSERT_OBJ(obj, MY_CLASS); + lv_gltf_t * viewer = (lv_gltf_t *)obj; + viewer->desc.focal_z = value; + lv_obj_invalidate(obj); +} + +float lv_gltf_get_focal_z(const lv_obj_t * obj) +{ + LV_ASSERT_NULL(obj); + LV_ASSERT_OBJ(obj, MY_CLASS); + lv_gltf_t * viewer = (lv_gltf_t *)obj; + return viewer->desc.focal_z; +} + +void lv_gltf_set_camera(lv_obj_t * obj, uint32_t value) +{ + LV_ASSERT_NULL(obj); + LV_ASSERT_OBJ(obj, MY_CLASS); + lv_gltf_t * viewer = (lv_gltf_t *)obj; + + if(lv_array_is_empty(&viewer->models)) { + return; + } + + lv_gltf_model_t * model = *(lv_gltf_model_t **) lv_array_at(&viewer->models, 0); + + if(value > model->asset.cameras.size()) { + return; + } + + model->camera = value; + lv_obj_invalidate(obj); +} + +uint32_t lv_gltf_get_camera(const lv_obj_t * obj) +{ + LV_ASSERT_NULL(obj); + LV_ASSERT_OBJ(obj, MY_CLASS); + lv_gltf_t * viewer = (lv_gltf_t *)obj; + + if(lv_array_is_empty(&viewer->models)) { + return 0; + } + const lv_gltf_model_t * model = *(const lv_gltf_model_t **)lv_array_at(&viewer->models, 0); + return model->camera; +} + +uint32_t lv_gltf_get_camera_count(const lv_obj_t * obj) +{ + + LV_ASSERT_NULL(obj); + LV_ASSERT_OBJ(obj, MY_CLASS); + lv_gltf_t * viewer = (lv_gltf_t *)obj; + + if(lv_array_is_empty(&viewer->models)) { + return 0; + } + const lv_gltf_model_t * model = *(const lv_gltf_model_t **) lv_array_at(&viewer->models, 0); + return lv_gltf_model_get_camera_count(model); +} + +void lv_gltf_set_antialiasing_mode(lv_obj_t * obj, lv_gltf_aa_mode_t value) +{ + LV_ASSERT_NULL(obj); + LV_ASSERT_OBJ(obj, MY_CLASS); + lv_gltf_t * viewer = (lv_gltf_t *)obj; + viewer->desc.aa_mode = value; + lv_obj_invalidate(obj); +} + +lv_gltf_aa_mode_t lv_gltf_get_antialiasing_mode(const lv_obj_t * obj) +{ + LV_ASSERT_NULL(obj); + LV_ASSERT_OBJ(obj, MY_CLASS); + lv_gltf_t * viewer = (lv_gltf_t *)obj; + return viewer->desc.aa_mode; +} + +void lv_gltf_set_background_mode(lv_obj_t * obj, lv_gltf_bg_mode_t value) +{ + LV_ASSERT_NULL(obj); + LV_ASSERT_OBJ(obj, MY_CLASS); + lv_gltf_t * viewer = (lv_gltf_t *)obj; + viewer->desc.bg_mode = value; + lv_obj_invalidate(obj); +} + +lv_gltf_bg_mode_t lv_gltf_get_background_mode(const lv_obj_t * obj) +{ + LV_ASSERT_NULL(obj); + LV_ASSERT_OBJ(obj, MY_CLASS); + lv_gltf_t * viewer = (lv_gltf_t *)obj; + return viewer->desc.bg_mode; +} + +void lv_gltf_set_background_blur(lv_obj_t * obj, uint32_t value) +{ + LV_ASSERT_NULL(obj); + LV_ASSERT_OBJ(obj, MY_CLASS); + lv_gltf_t * viewer = (lv_gltf_t *)obj; + if(value > 100) { + value = 100; + } + viewer->desc.blur_bg = value / 100.f; + lv_obj_invalidate(obj); +} + +uint32_t lv_gltf_get_background_blur(const lv_obj_t * obj) +{ + LV_ASSERT_NULL(obj); + LV_ASSERT_OBJ(obj, MY_CLASS); + lv_gltf_t * viewer = (lv_gltf_t *)obj; + return viewer->desc.blur_bg * 100; +} + +void lv_gltf_set_env_brightness(lv_obj_t * obj, uint32_t value) +{ + LV_ASSERT_NULL(obj); + LV_ASSERT_OBJ(obj, MY_CLASS); + lv_gltf_t * viewer = (lv_gltf_t *)obj; + viewer->desc.env_pow = value / 100.; + lv_obj_invalidate(obj); +} + +uint32_t lv_gltf_get_env_brightness(const lv_obj_t * obj) +{ + LV_ASSERT_NULL(obj); + LV_ASSERT_OBJ(obj, MY_CLASS); + lv_gltf_t * viewer = (lv_gltf_t *)obj; + return viewer->desc.env_pow * 100; +} + +void lv_gltf_set_image_exposure(lv_obj_t * obj, float value) +{ + LV_ASSERT_NULL(obj); + LV_ASSERT_OBJ(obj, MY_CLASS); + lv_gltf_t * viewer = (lv_gltf_t *)obj; + viewer->desc.exposure = value; + lv_obj_invalidate(obj); +} + +float lv_gltf_get_image_exposure(const lv_obj_t * obj) +{ + LV_ASSERT_NULL(obj); + LV_ASSERT_OBJ(obj, MY_CLASS); + lv_gltf_t * viewer = (lv_gltf_t *)obj; + return viewer->desc.exposure; +} +void lv_gltf_recenter(lv_obj_t * obj, lv_gltf_model_t * model) +{ + LV_ASSERT_NULL(obj); + LV_ASSERT_OBJ(obj, MY_CLASS); + lv_gltf_t * viewer = (lv_gltf_t *)obj; + if(model == NULL) { + LV_ASSERT(lv_array_size(&viewer->models) > 0); + model = *(lv_gltf_model_t **)lv_array_at(&viewer->models, 0); + } + + const auto & center_position = lv_gltf_data_get_center(model); + viewer->desc.focal_x = center_position[0]; + viewer->desc.focal_y = center_position[1]; + viewer->desc.focal_z = center_position[2]; +} + +/********************** + * STATIC FUNCTIONS + **********************/ + +static lv_gltf_model_t * lv_gltf_add_model(lv_gltf_t * viewer, lv_gltf_model_t * model) +{ + + if(!model) { + return NULL; + } + if(lv_array_push_back(&viewer->models, &model) == LV_RESULT_INVALID) { + lv_gltf_data_destroy(model); + return NULL; + } + model->viewer = viewer; + lv_gltf_parse_model(viewer, model); + + + if(lv_array_size(&viewer->models) == 1) { + lv_gltf_recenter((lv_obj_t *)viewer, model); + } + + return model; +} + + +static void lv_gltf_constructor(const lv_obj_class_t * class_p, lv_obj_t * obj) +{ + LV_UNUSED(class_p); + LV_TRACE_OBJ_CREATE("begin"); + lv_gltf_t * view = (lv_gltf_t *)obj; + lv_gltf_view_state_init(view); + lv_gltf_view_desc_init(&view->desc); + view->view_matrix = fastgltf::math::fmat4x4(1.0f); + view->projection_matrix = fastgltf::math::fmat4x4(1.0f); + view->view_projection_matrix = fastgltf::math::fmat4x4(1.0f); + view->camera_pos = fastgltf::math::fvec3(0.0f); + view->texture.h_flip = false; + view->texture.v_flip = false; + new(&view->ibm_by_skin_then_node) std::map>; + + lv_opengl_shader_portions_t portions; + lv_gltf_view_shader_get_src(&portions); + char * vertex_shader = lv_gltf_view_shader_get_vertex(); + char * frag_shader = lv_gltf_view_shader_get_fragment(); + lv_opengl_shader_manager_init(&view->shader_manager, portions.all, portions.count, vertex_shader, frag_shader); + lv_free(vertex_shader); + lv_free(frag_shader); + + lv_gltf_ibl_generate_env_textures(&view->env_textures, NULL, 0); + + lv_array_init(&view->models, LV_GLTF_INITIAL_MODEL_CAPACITY, sizeof(lv_gltf_model_t *)); + + LV_TRACE_OBJ_CREATE("end"); +} + +static void lv_gltf_event(const lv_obj_class_t * class_p, lv_event_t * e) +{ + LV_UNUSED(class_p); + lv_event_code_t code = lv_event_get_code(e); + + if(code == LV_EVENT_DRAW_MAIN) { + lv_obj_t * obj = (lv_obj_t *)lv_event_get_current_target(e); + lv_gltf_t * viewer = (lv_gltf_t *)obj; + GLuint texture_id = lv_gltf_view_render(viewer); + lv_3dtexture_set_src((lv_obj_t *)&viewer->texture, (lv_3dtexture_id_t)texture_id); + } + + lv_result_t res; + + /*Call the ancestor's event handler*/ + res = lv_obj_event_base(MY_CLASS, e); + if(res != LV_RESULT_OK) { + return; + } +} +static void lv_gltf_destructor(const lv_obj_class_t * class_p, lv_obj_t * obj) +{ + LV_UNUSED(class_p); + lv_gltf_t * view = (lv_gltf_t *)obj; + lv_opengl_shader_manager_deinit(&view->shader_manager); + using IbmBySkinThenNodeMap = std::map>; + + view->ibm_by_skin_then_node.~IbmBySkinThenNodeMap(); + const size_t n = lv_array_size(&view->models); + for(size_t i = 0; i < n; ++i) { + lv_gltf_data_destroy(*(lv_gltf_model_t **)lv_array_at(&view->models, i)); + } + destroy_environment(&view->env_textures); +} + +static void lv_gltf_view_state_init(lv_gltf_t * view) +{ + lv_memset(&view->state, 0, sizeof(view->state)); + view->state.opaque_frame_buffer_width = 256; + view->state.opaque_frame_buffer_height = 256; + view->state.material_variant = 0; + view->state.render_state_ready = false; + view->state.render_opaque_buffer = false; +} +static void lv_gltf_view_desc_init(lv_gltf_view_desc_t * desc) +{ + lv_memset(desc, 0, sizeof(*desc)); + desc->distance = 2.f; + desc->exposure = 1.0f; + desc->env_pow = 1.8f; + desc->blur_bg = 0.5f; + desc->bg_mode = LV_GLTF_BG_MODE_ENVIRONMENT; + desc->aa_mode = LV_GLTF_AA_MODE_OFF; + desc->fov = 45.f; + desc->animation_speed_ratio = LV_GLTF_ANIM_SPEED_NORMAL; + desc->frame_was_antialiased = false; +} +static void lv_gltf_parse_model(lv_gltf_t * viewer, lv_gltf_model_t * model) +{ + const auto & iterate_callback = [&](fastgltf::Node & node, const fastgltf::math::fmat4x4 & matrix) { + LV_UNUSED(matrix); + if(!node.meshIndex) { + return; + } + auto & mesh_index = node.meshIndex.value(); + if(node.skinIndex) { + auto skin_index = node.skinIndex.value(); + if(!lv_gltf_data_validated_skins_contains(model, skin_index)) { + lv_gltf_data_validate_skin(model, skin_index); + auto skin = model->asset.skins[skin_index]; + if(skin.inverseBindMatrices) { + auto & ibm_value = skin.inverseBindMatrices.value(); + auto & ibm_accessor = model->asset.accessors[ibm_value]; + if(ibm_accessor.bufferViewIndex) { + fastgltf::iterateAccessorWithIndex( + model->asset, ibm_accessor, + [&](fastgltf::math::fmat4x4 _matrix, std::size_t idx) { + auto & joint_node = model->asset.nodes[skin.joints[idx]]; + viewer->ibm_by_skin_then_node[skin_index][&joint_node] = _matrix; + }); + } + } + } + } + for(size_t mp = 0; mp < model->asset.meshes[mesh_index].primitives.size(); mp++) { + auto & model_primitive = model->asset.meshes[mesh_index].primitives[mp]; + const auto & mappings = model_primitive.mappings; + ssize_t material_index = + (!mappings.empty() && mappings[viewer->state.material_variant]) ? + mappings[viewer->state.material_variant].value() + 1 : + ((model_primitive.materialIndex) ? (model_primitive.materialIndex.value() + 1) : 0); + if(material_index < 0) { + lv_gltf_data_add_opaque_node_primitive(model, 0, &node, mp); + continue; + } + const fastgltf::Material & material = model->asset.materials[material_index - 1]; + + viewer->state.render_opaque_buffer |= material.transmission != NULL; + + if(material.alphaMode == fastgltf::AlphaMode::Blend || material.transmission != NULL) { + lv_gltf_data_add_blended_node_primitive(model, material_index + 1, &node, mp); + } + else { + lv_gltf_data_add_opaque_node_primitive(model, material_index + 1, &node, mp); + } + + lv_array_t defines; + lv_array_init(&defines, 64, sizeof(lv_opengl_shader_define_t)); + lv_result_t result = + lv_gltf_view_shader_injest_discover_defines(&defines, model, &node, &model_primitive); + + LV_ASSERT_MSG(result == LV_RESULT_OK, "Couldn't injest shader defines"); + lv_gltf_compiled_shader_t compiled_shader; + compiled_shader.shaderset = lv_gltf_view_shader_compile_program(viewer, (lv_opengl_shader_define_t *)defines.data, + lv_array_size(&defines)); + compiled_shader.uniforms = lv_gltf_uniform_locations_create(compiled_shader.shaderset.program); + lv_gltf_store_compiled_shader(model, material_index, &compiled_shader); + const size_t n = lv_array_size(&defines); + for(size_t i = 0; i < n; ++i) { + lv_opengl_shader_define_t * define = (lv_opengl_shader_define_t *) lv_array_at(&defines, i); + if(define->value_allocated) { + lv_free((void *)define->value); + } + } + lv_array_deinit(&defines); + } + }; + + setup_compile_and_load_bg_shader(&viewer->shader_manager); + fastgltf::iterateSceneNodes(model->asset, 0, fastgltf::math::fmat4x4(), iterate_callback); +} + +static void setup_compile_and_load_bg_shader(lv_opengl_shader_manager_t * manager) +{ + lv_opengl_shader_define_t frag_defs[1] = { { "TONEMAP_KHR_PBR_NEUTRAL", NULL, false} }; + uint32_t frag_shader_hash ; + uint32_t vert_shader_hash; + lv_result_t res = lv_opengl_shader_manager_select_shader(manager, "cubemap.frag", frag_defs, 1, + LV_OPENGL_GLSL_VERSION_300ES, + &frag_shader_hash); + + LV_ASSERT(res == LV_RESULT_OK); + res = lv_opengl_shader_manager_select_shader(manager, "cubemap.vert", nullptr, 0, LV_OPENGL_GLSL_VERSION_300ES, + &vert_shader_hash); + LV_ASSERT(res == LV_RESULT_OK); + + lv_opengl_shader_program_t * program = lv_opengl_shader_manager_get_program(manager, frag_shader_hash, + vert_shader_hash); + + manager->bg_program = lv_opengl_shader_program_get_id(program); + setup_background_environment(manager->bg_program, &manager->bg_vao, &manager->bg_index_buf, &manager->bg_vertex_buf); +} + + +static void setup_background_environment(GLuint program, GLuint * vao, GLuint * indexBuffer, GLuint * vertexBuffer) +{ + int32_t indices[] = { 1, 2, 0, 2, 3, 0, 6, 2, 1, 1, 5, 6, 6, 5, 4, 4, 7, 6, + 6, 3, 2, 7, 3, 6, 3, 7, 0, 7, 4, 0, 5, 1, 0, 4, 5, 0 + }; + float verts[] = { -1.0f, -1.0f, -1.0f, 1.0f, -1.0f, -1.0f, 1.0f, 1.0f, -1.0f, -1.0f, 1.0f, -1.0f, + -1.0f, -1.0f, 1.0f, 1.0f, -1.0f, 1.0f, 1.0f, 1.0f, 1.0f, -1.0f, 1.0f, 1.0f + }; + + GL_CALL(glUseProgram(program)); + GL_CALL(glGenVertexArrays(1, vao)); + GL_CALL(glBindVertexArray(*vao)); + GL_CALL(glGenBuffers(1, indexBuffer)); + GL_CALL(glGenBuffers(1, vertexBuffer)); + + GL_CALL(glBindBuffer(GL_ARRAY_BUFFER, *vertexBuffer)); + GL_CALL(glBufferData(GL_ARRAY_BUFFER, sizeof(verts), verts, GL_STATIC_DRAW)); + GL_CALL(glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, *indexBuffer)); + GL_CALL(glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(indices), indices, GL_STATIC_DRAW)); + + GLint positionAttributeLocation = glGetAttribLocation(program, "a_position"); + + // Specify the layout of the vertex data + glVertexAttribPointer(positionAttributeLocation, 3, GL_FLOAT, GL_FALSE, 0, (void *)0); + glEnableVertexAttribArray(positionAttributeLocation); + + GL_CALL(glBindVertexArray(0)); + GL_CALL(glUseProgram(0)); +} + +static void destroy_environment(lv_gltf_view_env_textures_t * env) +{ + const unsigned int d[3] = { env->diffuse, env->specular, env->sheen }; + GL_CALL(glDeleteTextures(3, d)); +} + +#endif /*LV_USE_GLTF*/ diff --git a/src/libs/gltf/gltf_view/lv_gltf_view_internal.h b/src/libs/gltf/gltf_view/lv_gltf_view_internal.h new file mode 100644 index 0000000000..b4c811fdf1 --- /dev/null +++ b/src/libs/gltf/gltf_view/lv_gltf_view_internal.h @@ -0,0 +1,138 @@ +/** + * @file lv_gltf_view_internal.h + * + */ + +#ifndef LV_GLTF_VIEW_INTERNAL_H +#define LV_GLTF_VIEW_INTERNAL_H + +/********************* + * INCLUDES + *********************/ + +#include "../../../lv_conf_internal.h" + +#if LV_USE_GLTF + +#include "lv_gltf.h" +#include "../../../misc/lv_types.h" +#include "../../../drivers/opengles/opengl_shader/lv_opengl_shader_internal.h" +#include "../../../widgets/3dtexture/lv_3dtexture_private.h" +#include "../gltf_data/lv_gltf_data_internal.h" + + +/********************* + * DEFINES + *********************/ + + +/********************** + * TYPEDEFS + **********************/ + +#ifdef __cplusplus +extern "C" { +#endif/* __cplusplus*/ + + +typedef struct { + uint32_t texture; + uint32_t renderbuffer; + unsigned framebuffer; +} lv_gltf_renwin_state_t; + +typedef struct { + lv_gltf_renwin_state_t render_state; + lv_gltf_renwin_state_t opaque_render_state; + + uint64_t opaque_frame_buffer_width; + uint64_t opaque_frame_buffer_height; + uint32_t material_variant; + bool render_state_ready; + bool render_opaque_buffer; +} lv_gltf_view_state_t; + +typedef struct { + float pitch; + float yaw; + float distance; + float fov; // The vertical FOV, in degrees. If this is zero, the view will be orthographic (non-perspective) + int32_t render_width; // If anti-aliasing is not applied this frame, these are the same as width/height, if antialiasing + int32_t render_height; // is enabled, these are width/height * antialias upscale power (currently 2.0) + float focal_x; + float focal_y; + float focal_z; + bool frame_was_antialiased; + int32_t animation_speed_ratio; + lv_gltf_aa_mode_t aa_mode; + lv_gltf_bg_mode_t bg_mode; + float blur_bg; /** How much to blur the environment background, between 0.0 and 1.0 */ + float env_pow; /** Environmental brightness, 1.8 by default */ + float exposure; /** Image exposure level, 1.0 default */ +} lv_gltf_view_desc_t; + +typedef struct { + GLboolean blend_enabled; + GLint blend_src; + GLint blend_dst; + GLint blend_equation; + GLfloat clear_depth; + GLfloat clear_color[4]; +} lv_opengl_state_t; + +typedef struct { + uint32_t diffuse; + uint32_t specular; + uint32_t sheen; + uint32_t ggxLut; + uint32_t charlie_lut; + uint32_t mip_count; + float ibl_intensity_scale; + float angle; +} lv_gltf_view_env_textures_t; + +#ifdef __cplusplus +} + + +#include +#include +#include + +struct _lv_gltf_t { + lv_3dtexture_t texture; + lv_array_t models; + lv_gltf_view_state_t state; + lv_gltf_view_desc_t desc; + lv_gltf_view_desc_t last_desc; + lv_opengl_shader_manager_t shader_manager; + lv_gltf_view_env_textures_t env_textures; + fastgltf::math::fmat4x4 view_matrix; + fastgltf::math::fmat4x4 projection_matrix; + fastgltf::math::fmat4x4 view_projection_matrix; + fastgltf::math::fvec3 camera_pos; + + std::map> ibm_by_skin_then_node; + +}; + +/********************** + * GLOBAL PROTOTYPES + **********************/ + +GLuint lv_gltf_view_render(lv_gltf_t * viewer); +lv_result_t lv_gltf_view_shader_injest_discover_defines(lv_array_t * result, lv_gltf_model_t * data, + fastgltf::Node * node, + fastgltf::Primitive * prim); + +lv_gltf_shaderset_t lv_gltf_view_shader_compile_program(lv_gltf_t * view, const lv_opengl_shader_define_t * defines, + size_t n); + +/********************** + * MACROS + **********************/ + +#endif/* __cplusplus*/ +#endif /*LV_USE_GLTF*/ + +#endif /*LV_GLTF_VIEW_INTERNAL_H*/ diff --git a/src/libs/gltf/gltf_view/lv_gltf_view_render.cpp b/src/libs/gltf/gltf_view/lv_gltf_view_render.cpp new file mode 100644 index 0000000000..e55900d01f --- /dev/null +++ b/src/libs/gltf/gltf_view/lv_gltf_view_render.cpp @@ -0,0 +1,1263 @@ +/** + * @file lv_gltf_view_render.cpp + * + */ + +/********************* + * INCLUDES + *********************/ + +#include "lv_gltf_view_internal.h" + +#if LV_USE_GLTF + +#include "../gltf_data/lv_gltf_data_internal.hpp" + +#include "../fastgltf/lv_fastgltf.hpp" +#include "../../../misc/lv_types.h" +#include "../../../stdlib/lv_sprintf.h" +#include "../../../drivers/opengles/lv_opengles_private.h" +#include "../../../drivers/opengles/lv_opengles_debug.h" +#include "../math/lv_gltf_math.hpp" + +#include + +#include +#include + +/********************* + * DEFINES + *********************/ + +/********************** + * TYPEDEFS + **********************/ + +/********************** + * STATIC PROTOTYPES + **********************/ + +static GLuint lv_gltf_view_render_model(lv_gltf_t * viewer, lv_gltf_model_t * model, bool prepare_bg); +static void lv_gltf_view_push_opengl_state(lv_opengl_state_t * state); +static void lv_gltf_view_pop_opengl_state(const lv_opengl_state_t * state); +static void setup_finish_frame(void); +static void render_materials(lv_gltf_t * viewer, lv_gltf_model_t * gltf_data, const MaterialIndexMap & map); +static void render_skins(lv_gltf_t * viewer, lv_gltf_model_t * gltf_data); +static lv_result_t render_primary_output(lv_gltf_t * viewer, const lv_gltf_renwin_state_t * state, + int32_t texture_w, + int32_t texture_h, bool prepare_bg); + +static void lv_gltf_view_recache_all_transforms(lv_gltf_model_t * gltf_data); +static fastgltf::math::fmat3x3 create_texture_transform_matrix(std::unique_ptr & transform); +static void render_uniform_color_alpha(GLint uniform_loc, fastgltf::math::nvec4 color); +static void render_uniform_color(GLint uniform_loc, fastgltf::math::nvec3 color); +static uint32_t render_texture(uint32_t tex_unit, uint32_t tex_name, int32_t tex_coord_index, + std::unique_ptr & tex_transform, GLint sampler, GLint uv_set, + GLint uv_transform); +static void draw_primitive(int32_t prim_num, lv_gltf_t * viewer, lv_gltf_model_t * gltf_data, fastgltf::Node & node, + std::size_t mesh_index, const fastgltf::math::fmat4x4 & matrix, + const lv_gltf_view_env_textures_t * env_tex, bool is_transmission_pass); + +static void setup_primitive(int32_t prim_num, lv_gltf_t * viewer, lv_gltf_model_t * gltf_data, + fastgltf::Node & node, + std::size_t mesh_index, const fastgltf::math::fmat4x4 & matrix, + const lv_gltf_view_env_textures_t * env_tex, bool is_transmission_pass); + +static void draw_material(lv_gltf_t * viewer, const lv_gltf_uniform_locations_t * uniforms, lv_gltf_model_t * model, + lv_gltf_primitive_t * _prim_data, size_t materialIndex, bool is_transmission_pass, GLuint program, + uint32_t * tex_num); + +static void draw_lights(lv_gltf_model_t * model, GLuint program); + +static lv_gltf_renwin_state_t setup_opaque_output(uint32_t texture_width, uint32_t texture_height); +static void setup_cleanup_opengl_output(lv_gltf_renwin_state_t * state); +static lv_gltf_renwin_state_t setup_primary_output(int32_t texture_width, int32_t texture_height, bool mipmaps_enabled); + +static void setup_view_proj_matrix_from_camera(lv_gltf_t * viewer, uint32_t camera, + lv_gltf_view_desc_t * view_desc, + fastgltf::math::fmat4x4 view_mat, fastgltf::math::fvec3 view_pos, + lv_gltf_model_t * gltf_data, bool transmission_pass); + +static void setup_view_proj_matrix(lv_gltf_t * viewer, lv_gltf_view_desc_t * view_desc, lv_gltf_model_t * gltf_data, + bool transmission_pass); +static lv_result_t setup_restore_opaque_output(lv_gltf_t * viewer, const lv_gltf_renwin_state_t * _ret, + uint32_t texture_w, + uint32_t texture_h, bool prepare_bg); +static void setup_draw_environment_background(lv_opengl_shader_manager_t * manager, lv_gltf_t * viewer, float blur); +static void setup_environment_rotation_matrix(float env_rotation_angle, uint32_t shader_program); + +/********************** + * STATIC VARIABLES + **********************/ + +/********************** + * MACROS + **********************/ + +/********************** + * GLOBAL FUNCTIONS + **********************/ + +GLuint lv_gltf_view_render(lv_gltf_t * viewer) +{ + const size_t n = lv_array_size(&viewer->models); + + if(n == 0) { + return GL_NONE; + } + lv_gltf_model_t * model = *(lv_gltf_model_t **)lv_array_at(&viewer->models, 0); + + GLuint texture_id = GL_NONE; + texture_id = lv_gltf_view_render_model(viewer, model, true); + for(size_t i = 1; i < n; ++i) { + lv_gltf_model_t * model = *(lv_gltf_model_t **)lv_array_at(&viewer->models, i); + lv_gltf_view_render_model(viewer, model, false); + } + return texture_id; +} + +/********************** + * STATIC FUNCTIONS + **********************/ + +static void lv_gltf_view_push_opengl_state(lv_opengl_state_t * state) +{ + GL_CALL(glGetBooleanv(GL_BLEND, &state->blend_enabled)); + GL_CALL(glGetIntegerv(GL_BLEND_SRC_ALPHA, &state->blend_src)); + GL_CALL(glGetIntegerv(GL_BLEND_DST_ALPHA, &state->blend_dst)); + GL_CALL(glGetIntegerv(GL_BLEND_EQUATION, &state->blend_equation)); + GL_CALL(glGetFloatv(GL_COLOR_CLEAR_VALUE, state->clear_color)); + GL_CALL(glGetFloatv(GL_DEPTH_CLEAR_VALUE, &state->clear_depth)); +} + +static void lv_gltf_view_pop_opengl_state(const lv_opengl_state_t * state) +{ + GL_CALL(glDisable(GL_CULL_FACE)); + if(state->blend_enabled) { + GL_CALL(glEnable(GL_BLEND)); + } + else { + GL_CALL(glDisable(GL_BLEND)); + } + GL_CALL(glBlendFunc(state->blend_src, state->blend_dst)); + GL_CALL(glBlendEquation(state->blend_equation)); + GL_CALL(glDepthMask(GL_TRUE)); + GL_CALL(glClearColor(state->clear_color[0], state->clear_color[1], state->clear_color[2], state->clear_color[3])); + GL_CALL(glClearDepthf(state->clear_depth)); +} + +static GLuint lv_gltf_view_render_model(lv_gltf_t * viewer, lv_gltf_model_t * model, bool prepare_bg) +{ + lv_gltf_view_state_t * vstate = &viewer->state; + lv_gltf_view_desc_t * view_desc = &viewer->desc; + bool opt_draw_bg = prepare_bg && (view_desc->bg_mode == LV_GLTF_BG_MODE_ENVIRONMENT); + bool opt_aa_this_frame = (view_desc->aa_mode == LV_GLTF_AA_MODE_ON) || + (view_desc->aa_mode == LV_GLTF_AA_MODE_DYNAMIC && model->last_frame_no_motion == true); + if(prepare_bg == false) { + /* If this data object is a secondary render pass, inherit the anti-alias setting for this frame from the first gltf_data drawn*/ + opt_aa_this_frame = view_desc->frame_was_antialiased; + } + + lv_opengl_state_t opengl_state; + lv_gltf_view_push_opengl_state(&opengl_state); + + int32_t last_render_w = view_desc->render_width; + int32_t last_render_h = view_desc->render_height; + view_desc->render_width = lv_obj_get_width((lv_obj_t *)viewer) * (opt_aa_this_frame ? 2 : 1); + view_desc->render_height = lv_obj_get_height((lv_obj_t *)viewer) * (opt_aa_this_frame ? 2 : 1); + + bool new_size = last_render_h != view_desc->render_height || last_render_w != view_desc->render_width; + + if(opt_aa_this_frame != model->last_frame_was_antialiased) { + /* Antialiasing state has changed since the last render */ + if(prepare_bg == true) { + if(vstate->render_state_ready) { + setup_cleanup_opengl_output(&vstate->render_state); + vstate->render_state = setup_primary_output((uint32_t)view_desc->render_width, + (uint32_t)view_desc->render_height, + opt_aa_this_frame); + } + } + model->last_frame_was_antialiased = opt_aa_this_frame; + } + + view_desc->frame_was_antialiased = opt_aa_this_frame; + + if(new_size || !vstate->render_state_ready) { + vstate->render_state_ready = true; + vstate->render_state = + setup_primary_output(view_desc->render_width, view_desc->render_height, opt_aa_this_frame); + setup_finish_frame(); + } + if(vstate->render_opaque_buffer) { + vstate->opaque_render_state = + setup_opaque_output(vstate->opaque_frame_buffer_width, vstate->opaque_frame_buffer_height); + setup_finish_frame(); + } + + bool dirty = lv_memcmp(&viewer->last_desc, view_desc, sizeof(*view_desc)) != 0 || model->is_animation_enabled; + + lv_memcpy(&(viewer->last_desc), view_desc, sizeof(*view_desc)); + + bool last_frame_no_motion = model->_last_frame_no_motion; + model->_last_frame_no_motion = model->last_frame_no_motion; + model->last_frame_no_motion = true; + + + if(dirty || lv_gltf_data_transform_cache_is_empty(model) || (model->camera != model->last_camera_index)) { + model->last_frame_no_motion = false; + lv_gltf_view_recache_all_transforms(model); + } + else if(model->last_frame_no_motion && model->_last_frame_no_motion && last_frame_no_motion) { + /* Nothing changed at all, return the previous output frame */ + setup_finish_frame(); + lv_gltf_view_pop_opengl_state(&opengl_state); + return vstate->render_state.texture; + } + + render_skins(viewer, model); + + NodeDistanceVector distance_sort_nodes; + + for(const auto & kv : model->blended_nodes_by_material_index) { + for(const auto & pair : kv.second) { + auto node = pair.first; + auto new_node = NodeIndexDistancePair( + fastgltf::math::length( + model->view_pos - + lv_gltf_data_get_centerpoint(model, lv_gltf_data_get_cached_transform(model, node), + node->meshIndex.value(), pair.second)), + NodeIndexPair(node, pair.second)); + distance_sort_nodes.push_back(new_node); + } + } + std::sort(distance_sort_nodes.begin(), distance_sort_nodes.end(), + [](const NodeIndexDistancePair & a, const NodeIndexDistancePair & b) { + return a.first < b.first; + }); + /* Reset the last material index to an unused value once per frame at the start*/ + model->last_material_index = 99999; + if(vstate->render_opaque_buffer) { + if(model->camera > 0) { + setup_view_proj_matrix_from_camera(viewer, model->camera - 1, view_desc, model->view_mat, + model->view_pos, model, true); + } + else { + setup_view_proj_matrix(viewer, view_desc, model, true); + } + lv_result_t result = setup_restore_opaque_output(viewer, &vstate->opaque_render_state, + vstate->opaque_frame_buffer_width, + vstate->opaque_frame_buffer_height, prepare_bg); + LV_ASSERT_MSG(result == LV_RESULT_OK, "Failed to setup opaque output which should never happen"); + if(result != LV_RESULT_OK) { + lv_gltf_view_pop_opengl_state(&opengl_state); + return vstate->render_state.texture; + } + + if(opt_draw_bg) { + setup_draw_environment_background(&viewer->shader_manager, viewer, view_desc->blur_bg); + } + + render_materials(viewer, model, model->opaque_nodes_by_material_index); + + for(const auto & node_distance_pair : distance_sort_nodes) { + const auto & node_element = node_distance_pair.second; + const auto & node = node_element.first; + draw_primitive(node_element.second, viewer, model, *node, node->meshIndex.value(), + lv_gltf_data_get_cached_transform(model, node), &viewer->env_textures, true); + } + + GL_CALL(glBindTexture(GL_TEXTURE_2D, vstate->opaque_render_state.texture)); + GL_CALL(glGenerateMipmap(GL_TEXTURE_2D)); + GL_CALL(glBindTexture(GL_TEXTURE_2D, GL_NONE)); + setup_finish_frame(); + } + + if(model->camera > 0) { + setup_view_proj_matrix_from_camera(viewer, model->camera - 1, view_desc, model->view_mat, + model->view_pos, model, false); + } + else { + setup_view_proj_matrix(viewer, view_desc, model, false); + } + + lv_result_t result = render_primary_output(viewer, &vstate->render_state, view_desc->render_width, + view_desc->render_height, prepare_bg); + + LV_ASSERT_MSG(result == LV_RESULT_OK, "Failed to restore primary output which should never happen"); + if(result != LV_RESULT_OK) { + lv_gltf_view_pop_opengl_state(&opengl_state); + return vstate->render_state.texture; + } + if(opt_draw_bg) + setup_draw_environment_background(&viewer->shader_manager, viewer, view_desc->blur_bg); + render_materials(viewer, model, model->opaque_nodes_by_material_index); + + for(const auto & node_distance_pair : distance_sort_nodes) { + const auto & node_element = node_distance_pair.second; + const auto & node = node_element.first; + draw_primitive(node_element.second, viewer, model, *node, node->meshIndex.value(), + lv_gltf_data_get_cached_transform(model, node), &viewer->env_textures, false); + } + if(opt_aa_this_frame) { + GL_CALL(glBindTexture(GL_TEXTURE_2D, vstate->render_state.texture)); + GL_CALL(glGenerateMipmap(GL_TEXTURE_2D)); + GL_CALL(glBindTexture(GL_TEXTURE_2D, GL_NONE)); + } + setup_finish_frame(); + lv_gltf_view_pop_opengl_state(&opengl_state); + return vstate->render_state.texture; +} + +static void setup_finish_frame(void) +{ + GL_CALL(glDisable(GL_DEPTH_TEST)); + GL_CALL(glBindFramebuffer(GL_FRAMEBUFFER, 0)); + GL_CALL(glBindRenderbuffer(GL_RENDERBUFFER, 0)); + GL_CALL(glUseProgram(0)); +} + +static void render_materials(lv_gltf_t * viewer, lv_gltf_model_t * gltf_data, const MaterialIndexMap & map) +{ + for(const auto & kv : map) { + for(const auto & pair : kv.second) { + auto node = pair.first; + draw_primitive(pair.second, viewer, gltf_data, *node, node->meshIndex.value(), + lv_gltf_data_get_cached_transform(gltf_data, node), &viewer->env_textures, true); + } + } +} + +static void render_skins(lv_gltf_t * viewer, lv_gltf_model_t * model) +{ + uint32_t skin_count = lv_gltf_data_get_skins_size(model); + if(skin_count == 0) { + return; + } + lv_gltf_data_destroy_textures(model); + for(size_t i = 0; i < skin_count; ++i) { + const auto & skin_index = lv_gltf_data_get_skin(model, i); + const auto & skin = model->asset.skins[skin_index]; + auto & ibm = viewer->ibm_by_skin_then_node[skin_index]; + + size_t num_joints = skin.joints.size(); + size_t tex_width = std::ceil(std::sqrt((float)num_joints * 8.0f)); + + GLuint rtex = lv_gltf_data_create_texture(model); + GL_CALL(glBindTexture(GL_TEXTURE_2D, rtex)); + GL_CALL(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE)); + GL_CALL(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE)); + GL_CALL(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST)); + GL_CALL(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST)); + float * texture_data = (float *)lv_malloc(tex_width * tex_width * 4 * sizeof(*texture_data)); + LV_ASSERT_MALLOC(texture_data); + size_t texture_data_index = 0; + + for(uint64_t j = 0; j < num_joints; j++) { + auto & joint_node = model->asset.nodes[skin.joints[j]]; + fastgltf::math::fmat4x4 final_joint_matrix = + lv_gltf_data_get_cached_transform(model, &joint_node) * ibm[&joint_node]; + + lv_memcpy(&texture_data[texture_data_index], final_joint_matrix.data(), sizeof(float) * 16); + lv_memcpy(&texture_data[texture_data_index + 16], + fastgltf::math::transpose(fastgltf::math::invert(final_joint_matrix)).data(), + sizeof(float) * 16); + + texture_data_index += 32; + } + GL_CALL(glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA32F, tex_width, tex_width, 0, GL_RGBA, GL_FLOAT, texture_data)); + GL_CALL(glPixelStorei(GL_UNPACK_ALIGNMENT, 1)); + GL_CALL(glBindTexture(GL_TEXTURE_2D, GL_NONE)); + lv_free(texture_data); + } +} +static void draw_primitive(int32_t prim_num, lv_gltf_t * viewer, lv_gltf_model_t * gltf_data, fastgltf::Node & node, + std::size_t mesh_index, const fastgltf::math::fmat4x4 & matrix, + const lv_gltf_view_env_textures_t * env_tex, bool is_transmission_pass) +{ + lv_gltf_mesh_data_t * mesh = lv_gltf_data_get_mesh(gltf_data, mesh_index); + const auto & asset = lv_gltf_data_get_asset(gltf_data); + const auto & _prim_data = lv_gltf_data_get_primitive_from_mesh(mesh, prim_num); + + std::size_t index_count = 0; + auto & indexAccessor = asset->accessors[asset->meshes[mesh_index].primitives[prim_num].indicesAccessor.value()]; + setup_primitive(prim_num, viewer, gltf_data, node, mesh_index, matrix, env_tex, is_transmission_pass); + + if(indexAccessor.bufferViewIndex.has_value()) { + index_count = (uint32_t)indexAccessor.count; + } + if(index_count > 0) { + GL_CALL(glDrawElements(_prim_data->primitiveType, index_count, _prim_data->indexType, 0)); + } +} +static void setup_primitive(int32_t prim_num, lv_gltf_t * viewer, lv_gltf_model_t * model, fastgltf::Node & node, + std::size_t mesh_index, const fastgltf::math::fmat4x4 & matrix, + const lv_gltf_view_env_textures_t * env_tex, bool is_transmission_pass) +{ + lv_gltf_view_desc_t * view_desc = &viewer->desc; + lv_gltf_mesh_data_t * mesh = lv_gltf_data_get_mesh(model, mesh_index); + const auto & _prim_data = lv_gltf_data_get_primitive_from_mesh(mesh, prim_num); + auto & _prim_gltf_data = model->asset.meshes[mesh_index].primitives[prim_num]; + auto & mappings = _prim_gltf_data.mappings; + std::size_t materialIndex = + (!mappings.empty() && mappings[viewer->state.material_variant].has_value()) ? + mappings[viewer->state.material_variant].value() + 1 : + ((_prim_gltf_data.materialIndex.has_value()) ? (_prim_gltf_data.materialIndex.value() + 1) : 0); + + GL_CALL(glBindVertexArray(_prim_data->vertexArray)); + + lv_gltf_compiled_shader_t * compiled_shader = lv_gltf_get_compiled_shader(model, materialIndex); + const lv_gltf_uniform_locations_t * uniforms = &compiled_shader->uniforms; + + /* Fast path, primitive setup in the primitive draw render */ + if((model->last_material_index == materialIndex) && (model->last_pass_was_transmission == is_transmission_pass)) { + GL_CALL(glUniformMatrix4fv(uniforms->model_matrix, 1, GL_FALSE, &matrix[0][0])); + return; + } + + model->last_material_index = materialIndex; + model->last_pass_was_transmission = is_transmission_pass; + + const GLuint program = compiled_shader->shaderset.program; + + GL_CALL(glUseProgram(program)); + + GL_CALL(glUniformMatrix4fv(uniforms->model_matrix, 1, GL_FALSE, &matrix[0][0])); + GL_CALL(glUniformMatrix4fv(uniforms->view_matrix, 1, false, viewer->view_matrix.data())); + GL_CALL(glUniformMatrix4fv(uniforms->projection_matrix, 1, false, viewer->projection_matrix.data())); + GL_CALL(glUniformMatrix4fv(uniforms->view_projection_matrix, 1, false, viewer->view_projection_matrix.data())); + const auto & _campos = viewer->camera_pos; + GL_CALL(glUniform3f(uniforms->camera, _campos[0], _campos[1], _campos[2])); + + GL_CALL(glUniform1f(uniforms->exposure, view_desc->exposure)); + GL_CALL(glUniform1f(uniforms->env_intensity, view_desc->env_pow)); + GL_CALL(glUniform1i(uniforms->env_mip_count, (int32_t)env_tex->mip_count)); + setup_environment_rotation_matrix(viewer->env_textures.angle, program); + GL_CALL(glEnable(GL_CULL_FACE)); + GL_CALL(glDisable(GL_BLEND)); + GL_CALL(glEnable(GL_DEPTH_TEST)); + GL_CALL(glDepthMask(GL_TRUE)); + GL_CALL(glCullFace(GL_BACK)); + uint32_t tex_num = 0; + + draw_material(viewer, uniforms, model, _prim_data, materialIndex, is_transmission_pass, program, &tex_num); + + const lv_gltf_view_state_t * vstate = &viewer->state; + if(!is_transmission_pass && vstate->render_opaque_buffer) { + GL_CALL(glActiveTexture(GL_TEXTURE0 + tex_num)); + GL_CALL(glBindTexture(GL_TEXTURE_2D, vstate->opaque_render_state.texture)); + GL_CALL(glUniform1i(uniforms->transmission_framebuffer_sampler, tex_num)); + GL_CALL(glUniform2i(uniforms->transmission_framebuffer_size, (int32_t)vstate->opaque_frame_buffer_width, + (int32_t)vstate->opaque_frame_buffer_height)); + tex_num++; + } + + if(node.skinIndex.has_value()) { + GL_CALL(glActiveTexture(GL_TEXTURE0 + tex_num)); + GL_CALL(glBindTexture(GL_TEXTURE_2D, lv_gltf_data_get_skin_texture_at(model, node.skinIndex.value()))); + GL_CALL(glUniform1i(uniforms->joints_sampler, tex_num)); + tex_num++; + } + if(env_tex->diffuse != GL_NONE) { + GL_CALL(glActiveTexture(GL_TEXTURE0 + tex_num)); + GL_CALL(glBindTexture(GL_TEXTURE_CUBE_MAP, env_tex->diffuse)); + GL_CALL(glUniform1i(uniforms->env_diffuse_sampler, tex_num++)); + } + if(env_tex->specular != GL_NONE) { + GL_CALL(glActiveTexture(GL_TEXTURE0 + tex_num)); + GL_CALL(glBindTexture(GL_TEXTURE_CUBE_MAP, env_tex->specular)); + GL_CALL(glUniform1i(uniforms->env_specular_sampler, tex_num++)); + } + if(env_tex->sheen != GL_NONE) { + GL_CALL(glActiveTexture(GL_TEXTURE0 + tex_num)); + GL_CALL(glBindTexture(GL_TEXTURE_CUBE_MAP, env_tex->sheen)); + GL_CALL(glUniform1i(uniforms->env_sheen_sampler, tex_num++)); + } + if(env_tex->ggxLut != GL_NONE) { + GL_CALL(glActiveTexture(GL_TEXTURE0 + tex_num)); + GL_CALL(glBindTexture(GL_TEXTURE_2D, env_tex->ggxLut)); + GL_CALL(glUniform1i(uniforms->env_ggx_lut_sampler, tex_num++)); + } + if(env_tex->charlie_lut != GL_NONE) { + GL_CALL(glActiveTexture(GL_TEXTURE0 + tex_num)); + GL_CALL(glBindTexture(GL_TEXTURE_2D, env_tex->charlie_lut)); + GL_CALL(glUniform1i(uniforms->env_charlie_lut_sampler, tex_num++)); + } +} + +static void draw_material(lv_gltf_t * viewer, const lv_gltf_uniform_locations_t * uniforms, lv_gltf_model_t * model, + lv_gltf_primitive_t * _prim_data, size_t materialIndex, bool is_transmission_pass, GLuint program, + uint32_t * tex_num) +{ + const auto & asset = lv_gltf_data_get_asset(model); + + bool has_material = asset->materials.size() > (materialIndex - 1); + + if(!has_material) { + render_uniform_color_alpha(uniforms->base_color_factor, fastgltf::math::fvec4(1.0f)); + GL_CALL(glUniform1f(uniforms->roughness_factor, 0.5f)); + GL_CALL(glUniform1f(uniforms->metallic_factor, 0.5f)); + GL_CALL(glUniform1f(uniforms->ior, 1.5f)); + GL_CALL(glUniform1f(uniforms->dispersion, 0.0f)); + GL_CALL(glUniform1f(uniforms->thickness, 0.01847f)); + return; + } + + auto & gltfMaterial = asset->materials[materialIndex - 1]; + + if(is_transmission_pass && (gltfMaterial.transmission != NULL)) { + return; + } + + if(gltfMaterial.doubleSided) + GL_CALL(glDisable(GL_CULL_FACE)); + if(gltfMaterial.alphaMode == fastgltf::AlphaMode::Blend) { + GL_CALL(glEnable(GL_BLEND)); + GL_CALL(glDepthMask(GL_FALSE)); + GL_CALL(glBlendFuncSeparate(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA, GL_ONE, GL_ONE_MINUS_SRC_ALPHA)); + GL_CALL(glBlendEquation(GL_FUNC_ADD)); + GL_CALL(glEnable(GL_CULL_FACE)); + } + else { + if(gltfMaterial.alphaMode == fastgltf::AlphaMode::Mask) { + GL_CALL(glUniform1f(uniforms->alpha_cutoff, gltfMaterial.alphaCutoff)); + GL_CALL(glDisable(GL_CULL_FACE)); + } + } + + draw_lights(model, program); + render_uniform_color_alpha(uniforms->base_color_factor, gltfMaterial.pbrData.baseColorFactor); + render_uniform_color(uniforms->emissive_factor, gltfMaterial.emissiveFactor); + + GL_CALL(glUniform1f(uniforms->emissive_strength, gltfMaterial.emissiveStrength)); + GL_CALL(glUniform1f(uniforms->roughness_factor, gltfMaterial.pbrData.roughnessFactor)); + GL_CALL(glUniform1f(uniforms->metallic_factor, gltfMaterial.pbrData.metallicFactor)); + GL_CALL(glUniform1f(uniforms->ior, gltfMaterial.ior)); + GL_CALL(glUniform1f(uniforms->dispersion, gltfMaterial.dispersion)); + + if(gltfMaterial.pbrData.baseColorTexture.has_value()) + *tex_num = render_texture(*tex_num, _prim_data->albedoTexture, _prim_data->baseColorTexcoordIndex, + gltfMaterial.pbrData.baseColorTexture->transform, uniforms->base_color_sampler, + uniforms->base_color_uv_set, uniforms->base_color_uv_transform); + if(gltfMaterial.emissiveTexture.has_value()) + *tex_num = render_texture(*tex_num, _prim_data->emissiveTexture, _prim_data->emissiveTexcoordIndex, + gltfMaterial.emissiveTexture->transform, uniforms->emissive_sampler, + uniforms->emissive_uv_set, uniforms->emissive_uv_transform); + if(gltfMaterial.pbrData.metallicRoughnessTexture.has_value()) + *tex_num = render_texture(*tex_num, _prim_data->metalRoughTexture, _prim_data->metallicRoughnessTexcoordIndex, + gltfMaterial.pbrData.metallicRoughnessTexture->transform, + uniforms->metallic_roughness_sampler, uniforms->metallic_roughness_uv_set, + uniforms->metallic_roughness_uv_transform); + if(gltfMaterial.occlusionTexture.has_value()) { + GL_CALL(glUniform1f(uniforms->occlusion_strength, static_cast(gltfMaterial.occlusionTexture->strength))); + *tex_num = render_texture(*tex_num, _prim_data->occlusionTexture, _prim_data->occlusionTexcoordIndex, + gltfMaterial.occlusionTexture->transform, uniforms->occlusion_sampler, + uniforms->occlusion_uv_set, uniforms->occlusion_uv_transform); + } + + if(gltfMaterial.normalTexture.has_value()) { + GL_CALL(glUniform1f(uniforms->normal_scale, static_cast(gltfMaterial.normalTexture->scale))); + *tex_num = render_texture(*tex_num, _prim_data->normalTexture, _prim_data->normalTexcoordIndex, + gltfMaterial.normalTexture->transform, uniforms->normal_sampler, + uniforms->normal_uv_set, uniforms->normal_uv_transform); + } + + if(gltfMaterial.clearcoat) { + GL_CALL(glUniform1f(uniforms->clearcoat_factor, static_cast(gltfMaterial.clearcoat->clearcoatFactor))); + GL_CALL(glUniform1f(uniforms->clearcoat_roughness_factor, + static_cast(gltfMaterial.clearcoat->clearcoatRoughnessFactor))); + + if(gltfMaterial.clearcoat->clearcoatTexture.has_value()) + *tex_num = render_texture(*tex_num, _prim_data->clearcoatTexture, _prim_data->clearcoatTexcoordIndex, + gltfMaterial.clearcoat->clearcoatTexture->transform, + uniforms->clearcoat_sampler, uniforms->clearcoat_uv_set, + uniforms->clearcoat_uv_transform); + if(gltfMaterial.clearcoat->clearcoatRoughnessTexture.has_value()) + *tex_num = render_texture(*tex_num, _prim_data->clearcoatRoughnessTexture, + _prim_data->clearcoatRoughnessTexcoordIndex, + gltfMaterial.clearcoat->clearcoatRoughnessTexture->transform, + uniforms->clearcoat_roughness_sampler, uniforms->clearcoat_roughness_uv_set, + uniforms->clearcoat_roughness_uv_transform); + if(gltfMaterial.clearcoat->clearcoatNormalTexture.has_value()) { + GL_CALL(glUniform1f(uniforms->clearcoat_normal_scale, + static_cast(gltfMaterial.clearcoat->clearcoatNormalTexture->scale))); + *tex_num = render_texture(*tex_num, _prim_data->clearcoatNormalTexture, + _prim_data->clearcoatNormalTexcoordIndex, + gltfMaterial.clearcoat->clearcoatNormalTexture->transform, + uniforms->clearcoat_normal_sampler, uniforms->clearcoat_normal_uv_set, + uniforms->clearcoat_normal_uv_transform); + } + } + + if(gltfMaterial.volume) { + GL_CALL(glUniform1f(uniforms->attenuation_distance, gltfMaterial.volume->attenuationDistance)); + render_uniform_color(uniforms->attenuation_color, gltfMaterial.volume->attenuationColor); + GL_CALL(glUniform1f(uniforms->thickness, gltfMaterial.volume->thicknessFactor)); + if(gltfMaterial.volume->thicknessTexture.has_value()) { + *tex_num = render_texture(*tex_num, _prim_data->thicknessTexture, _prim_data->thicknessTexcoordIndex, + gltfMaterial.volume->thicknessTexture->transform, uniforms->thickness_sampler, + uniforms->thickness_uv_set, uniforms->thickness_uv_transform); + } + } + + if(gltfMaterial.transmission) { + GL_CALL(glUniform1f(uniforms->transmission_factor, gltfMaterial.transmission->transmissionFactor)); + GL_CALL(glUniform2i(uniforms->screen_size, viewer->desc.render_width, viewer->desc.render_height)); + if(gltfMaterial.transmission->transmissionTexture.has_value()) + *tex_num = render_texture(*tex_num, _prim_data->transmissionTexture, + _prim_data->transmissionTexcoordIndex, + gltfMaterial.transmission->transmissionTexture->transform, + uniforms->transmission_sampler, uniforms->transmission_uv_set, + uniforms->transmission_uv_transform); + } + + if(gltfMaterial.sheen) { + render_uniform_color(uniforms->sheen_color_factor, gltfMaterial.sheen->sheenColorFactor); + GL_CALL(glUniform1f(uniforms->sheen_roughness_factor, + static_cast(gltfMaterial.sheen->sheenRoughnessFactor))); + if(gltfMaterial.sheen->sheenColorTexture.has_value()) { + LV_LOG_WARN("Material has unhandled sheen texture"); + } + } + if(gltfMaterial.specular) { + render_uniform_color(uniforms->specular_color_factor, gltfMaterial.specular->specularColorFactor); + GL_CALL(glUniform1f(uniforms->specular_factor, static_cast(gltfMaterial.specular->specularFactor))); + if(gltfMaterial.specular->specularTexture.has_value()) { + LV_LOG_WARN("Material has unhandled specular texture"); + } + if(gltfMaterial.specular->specularColorTexture.has_value()) { + LV_LOG_WARN("Material has unhandled specular color texture"); + } + } + +#if FASTGLTF_ENABLE_DEPRECATED_EXT + if(gltfMaterial.specularGlossiness) { + LV_LOG_WARN( + "Model uses outdated legacy mode pbr_speculargloss. Please update this model to a new shading model "); + render_uniform_color_alpha(uniforms->diffuse_factor, gltfMaterial.specularGlossiness->diffuseFactor); + render_uniform_color(uniforms->specular_factor, gltfMaterial.specularGlossiness->specularFactor); + GL_CALL(glUniform1f(uniforms->glossiness_factor, + static_cast(gltfMaterial.specularGlossiness->glossinessFactor))); + if(gltfMaterial.specularGlossiness->diffuseTexture.has_value()) { + *tex_num = render_texture(*tex_num, _prim_data->diffuseTexture, _prim_data->diffuseTexcoordIndex, + gltfMaterial.specularGlossiness->diffuseTexture->transform, + uniforms->diffuse_sampler, uniforms->diffuse_uv_set, + uniforms->diffuse_uv_transform); + } + if(gltfMaterial.specularGlossiness->specularGlossinessTexture.has_value()) { + *tex_num = render_texture(*tex_num, _prim_data->specularGlossinessTexture, + _prim_data->specularGlossinessTexcoordIndex, + gltfMaterial.specularGlossiness->specularGlossinessTexture->transform, + uniforms->specular_glossiness_sampler, uniforms->specular_glossiness_uv_set, + uniforms->specular_glossiness_uv_transform); + } + } +#endif + + if(gltfMaterial.diffuseTransmission) { + render_uniform_color(uniforms->diffuse_transmission_color_factor, + gltfMaterial.diffuseTransmission->diffuseTransmissionColorFactor); + GL_CALL(glUniform1f(uniforms->diffuse_transmission_factor, + static_cast(gltfMaterial.diffuseTransmission->diffuseTransmissionFactor))); + if(gltfMaterial.diffuseTransmission->diffuseTransmissionTexture.has_value()) { + *tex_num = render_texture(*tex_num, _prim_data->diffuseTransmissionTexture, + _prim_data->diffuseTransmissionTexcoordIndex, + gltfMaterial.diffuseTransmission->diffuseTransmissionTexture->transform, + uniforms->diffuse_transmission_sampler, uniforms->diffuse_transmission_uv_set, + uniforms->diffuse_transmission_uv_transform); + } + if(gltfMaterial.diffuseTransmission->diffuseTransmissionColorTexture.has_value()) { + *tex_num = render_texture(*tex_num, _prim_data->diffuseTransmissionColorTexture, + _prim_data->diffuseTransmissionColorTexcoordIndex, + gltfMaterial.diffuseTransmission->diffuseTransmissionColorTexture->transform, + uniforms->diffuse_transmission_color_sampler, + uniforms->diffuse_transmission_color_uv_set, + uniforms->diffuse_transmission_color_uv_transform); + } + } +} +static void draw_lights(lv_gltf_model_t * model, GLuint program) +{ + if(model->node_by_light_index.empty()) { + return; + } + size_t max_light_nodes = model->node_by_light_index.size(); + size_t max_scene_lights = model->asset.lights.size(); + if(max_scene_lights != max_light_nodes) { + LV_LOG_ERROR("Scene light count (%zu) != scene light node count (%zu)\n", max_scene_lights, max_light_nodes); + return; + } + + char tag[100]; + char prefix[20]; + for(size_t i = 0; i < max_scene_lights; i++) { + // Update each field of the light struct + lv_snprintf(prefix, sizeof(prefix), "u_Lights[%zu]", i + 1); + auto & lightNode = model->node_by_light_index[i]; + const fastgltf::math::fmat4x4 & light_matrix = lv_gltf_data_get_cached_transform(model, lightNode); + + lv_snprintf(tag, sizeof(tag), "%s.position", prefix); + glUniform3fv(glGetUniformLocation(program, tag), 1, &light_matrix[3][0]); + + lv_snprintf(tag, sizeof(tag), "%s.direction", prefix); + float tlight_dir[3] = { -light_matrix[2][0], -light_matrix[2][1], -light_matrix[2][2] }; + + glUniform3fv(glGetUniformLocation(program, tag), 1, &tlight_dir[0]); + + lv_snprintf(tag, sizeof(tag), "%s.range", prefix); + const auto & m = light_matrix.data(); + + if(model->asset.lights[i].range.has_value()) { + float light_scale = fastgltf::math::length(fastgltf::math::fvec3(m[0], m[4], m[8])); + glUniform1f(glGetUniformLocation(program, tag), model->asset.lights[i].range.value() * light_scale); + } + else { + glUniform1f(glGetUniformLocation(program, tag), 9999.f); + } + + lv_snprintf(tag, sizeof(tag), "%s.color", prefix); + glUniform3fv(glGetUniformLocation(program, tag), 1, &(model->asset.lights[i].color.data()[0])); + + lv_snprintf(tag, sizeof(tag), "%s.intensity", prefix); + glUniform1f(glGetUniformLocation(program, tag), model->asset.lights[i].intensity); + + lv_snprintf(tag, sizeof(tag), "%s.innerConeCos", prefix); + if(model->asset.lights[i].innerConeAngle.has_value()) { + glUniform1f(glGetUniformLocation(program, tag), + std::cos(model->asset.lights[i].innerConeAngle.value())); + + } + else { + glUniform1f(glGetUniformLocation(program, tag), -1.0f); + } + + lv_snprintf(tag, sizeof(tag), "%s.outerConeCos", prefix); + + if(model->asset.lights[i].outerConeAngle.has_value()) { + glUniform1f(glGetUniformLocation(program, tag), + std::cos(model->asset.lights[i].outerConeAngle.value())); + + } + else { + glUniform1f(glGetUniformLocation(program, tag), -1.0f); + } + lv_snprintf(tag, sizeof(tag), "%s.type", prefix); + glUniform1i(glGetUniformLocation(program, tag), (GLint)model->asset.lights[i].type); + } +} + +lv_result_t render_primary_output(lv_gltf_t * viewer, const lv_gltf_renwin_state_t * state, int32_t texture_w, + int32_t texture_h, bool prepare_bg) +{ + GL_CALL(glBindFramebuffer(GL_FRAMEBUFFER, state->framebuffer)); + + if(glGetError() != GL_NO_ERROR) { + return LV_RESULT_INVALID; + } + GL_CALL(glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, state->texture, 0)); + GL_CALL(glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_TEXTURE_2D, state->renderbuffer, 0)); + GL_CALL(glViewport(0, 0, texture_w, texture_h)); + if(prepare_bg) { + /* cast is safe because viewer is a lv_obj_t*/ + lv_color_t bg_color = lv_obj_get_style_bg_color((lv_obj_t *)viewer, LV_PART_MAIN); + uint8_t alpha = lv_obj_get_style_bg_opa((lv_obj_t *)viewer, LV_PART_MAIN); + GL_CALL(glClearColor(bg_color.red / 255.0f, bg_color.green / 255.0f, bg_color.blue / 255.0f, alpha / 255.0f)); + + GL_CALL(glClearDepthf(1.0f)); + GL_CALL(glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT)); + } + + return glGetError() == GL_NO_ERROR ? LV_RESULT_OK : LV_RESULT_INVALID; +} + +static void render_uniform_color_alpha(GLint uniform_loc, fastgltf::math::nvec4 color) +{ + GL_CALL(glUniform4f(uniform_loc, static_cast(color[0]), static_cast(color[1]), + static_cast(color[2]), static_cast(color[3]))); +} +static void render_uniform_color(GLint uniform_loc, fastgltf::math::nvec3 color) +{ + GL_CALL(glUniform3f(uniform_loc, static_cast(color[0]), static_cast(color[1]), + static_cast(color[2]))); +} + +static uint32_t render_texture(uint32_t tex_unit, uint32_t tex_name, int32_t tex_coord_index, + std::unique_ptr & tex_transform, GLint sampler, GLint uv_set, + GLint uv_transform) +{ + /* Activate the texture unit*/ + GL_CALL(glActiveTexture(GL_TEXTURE0 + tex_unit)); + /* Bind the texture (assuming 2D texture) */ + GL_CALL(glBindTexture(GL_TEXTURE_2D, tex_name)); + /* Set the sampler to use the texture unit */ + GL_CALL(glUniform1i(sampler, tex_unit)); + /* Set the UV set index */ + GL_CALL(glUniform1i(uv_set, tex_coord_index)); + if(tex_transform != NULL) { + GL_CALL(glUniformMatrix3fv(uv_transform, 1, GL_FALSE, &(create_texture_transform_matrix(tex_transform)[0][0]))); + } + + tex_unit++; + return tex_unit; +} + +static fastgltf::math::fmat3x3 create_texture_transform_matrix(std::unique_ptr & transform) +{ + fastgltf::math::fmat3x3 rotation = fastgltf::math::fmat3x3(0.f); + fastgltf::math::fmat3x3 scale = fastgltf::math::fmat3x3(0.f); + fastgltf::math::fmat3x3 translation = fastgltf::math::fmat3x3(0.f); + fastgltf::math::fmat3x3 result = fastgltf::math::fmat3x3(0.f); + + float s = std::sin(transform->rotation); + float c = std::cos(transform->rotation); + rotation[0][0] = c; + rotation[1][1] = c; + rotation[0][1] = s; + rotation[1][0] = -s; + rotation[2][2] = 1.0f; + + scale[0][0] = transform->uvScale[0]; + scale[1][1] = transform->uvScale[1]; + scale[2][2] = 1.0f; + + translation[0][0] = 1.0f; + translation[1][1] = 1.0f; + translation[0][2] = transform->uvOffset[0]; + translation[1][2] = transform->uvOffset[1]; + translation[2][2] = 1.0f; + + result = translation * rotation; + result = result * scale; + return result; +} + +static lv_gltf_renwin_state_t setup_opaque_output(uint32_t texture_width, uint32_t texture_height) +{ + lv_gltf_renwin_state_t result; + + GLuint rtex; + GL_CALL(glGenTextures(1, &rtex)); + result.texture = rtex; + + GL_CALL(glBindTexture(GL_TEXTURE_2D, result.texture)); + GL_CALL(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR)); + GL_CALL(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST)); + GL_CALL(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE)); + GL_CALL(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE)); + GL_CALL(glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, texture_width, texture_height, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL)); + GL_CALL(glBindTexture(GL_TEXTURE_2D, GL_NONE)); + GL_CALL(glPixelStorei(GL_UNPACK_ALIGNMENT, 1)); + + GLuint rdepth; + GL_CALL(glGenTextures(1, &rdepth)); + result.renderbuffer = rdepth; + GL_CALL(glBindTexture(GL_TEXTURE_2D, result.renderbuffer)); + GL_CALL(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST)); + GL_CALL(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST)); + GL_CALL(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE)); + GL_CALL(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE)); +#ifdef __EMSCRIPTEN__ + GL_CALL(glTexImage2D(GL_TEXTURE_2D, 0, LV_GL_PREFERRED_DEPTH, texture_width, texture_height, 0, GL_DEPTH_COMPONENT, + GL_UNSIGNED_INT, NULL)); +#else + GL_CALL(glTexImage2D(GL_TEXTURE_2D, 0, LV_GL_PREFERRED_DEPTH, texture_width, texture_height, 0, GL_DEPTH_COMPONENT, + GL_UNSIGNED_SHORT, NULL)); +#endif + GL_CALL(glBindTexture(GL_TEXTURE_2D, GL_NONE)); + + GL_CALL(glGenFramebuffers(1, &result.framebuffer)); + GL_CALL(glBindFramebuffer(GL_FRAMEBUFFER, result.framebuffer)); + GL_CALL(glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, result.texture, 0)); + GL_CALL(glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_TEXTURE_2D, result.renderbuffer, 0)); + + return result; +} + +static lv_gltf_renwin_state_t setup_primary_output(int32_t texture_width, int32_t texture_height, bool mipmaps_enabled) +{ + lv_gltf_renwin_state_t result; + + GLuint rtex; + GL_CALL(glGenTextures(1, &rtex)); + result.texture = rtex; + GL_CALL(glBindTexture(GL_TEXTURE_2D, result.texture)); + GL_CALL(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, + mipmaps_enabled ? GL_NEAREST_MIPMAP_NEAREST : GL_NEAREST)); + GL_CALL(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST)); + GL_CALL(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE)); + GL_CALL(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE)); + GL_CALL(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, 1)); + GL_CALL(glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, texture_width, texture_height, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL)); + GL_CALL(glBindTexture(GL_TEXTURE_2D, GL_NONE)); + GL_CALL(glPixelStorei(GL_UNPACK_ALIGNMENT, 1)); + + GLuint rdepth; + GL_CALL(glGenTextures(1, &rdepth)); + result.renderbuffer = rdepth; + GL_CALL(glBindTexture(GL_TEXTURE_2D, result.renderbuffer)); + GL_CALL(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST)); + GL_CALL(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST)); + GL_CALL(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE)); + GL_CALL(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE)); + GL_CALL(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, 1)); +#ifdef __EMSCRIPTEN__ // Check if compiling for Emscripten (WebGL) + // For WebGL2 + GL_CALL(glTexImage2D(GL_TEXTURE_2D, 0, LV_GL_PREFERRED_DEPTH, texture_width, texture_height, 0, GL_DEPTH_COMPONENT, + GL_UNSIGNED_INT, NULL)); +#else + // For Desktop OpenGL + GL_CALL(glTexImage2D(GL_TEXTURE_2D, 0, LV_GL_PREFERRED_DEPTH, texture_width, texture_height, 0, GL_DEPTH_COMPONENT, + GL_UNSIGNED_SHORT, NULL)); +#endif + GL_CALL(glBindTexture(GL_TEXTURE_2D, GL_NONE)); + + GL_CALL(glGenFramebuffers(1, &result.framebuffer)); + GL_CALL(glBindFramebuffer(GL_FRAMEBUFFER, result.framebuffer)); + GL_CALL(glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, result.texture, 0)); + GL_CALL(glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_TEXTURE_2D, result.renderbuffer, 0)); + + return result; +} + +static void setup_cleanup_opengl_output(lv_gltf_renwin_state_t * state) +{ + if(!state) { + return; + } + if(state->framebuffer) { + GL_CALL(glBindFramebuffer(GL_FRAMEBUFFER, 0)); + GL_CALL(glDeleteFramebuffers(1, &state->framebuffer)); + state->framebuffer = 0; + } + if(state->texture) { + GL_CALL(glDeleteTextures(1, &state->texture)); + state->texture = 0; + } + if(state->renderbuffer) { + GL_CALL(glDeleteTextures(1, &state->renderbuffer)); + state->renderbuffer = 0; + } +} +static void setup_view_proj_matrix_from_camera(lv_gltf_t * viewer, uint32_t camera, + lv_gltf_view_desc_t * view_desc, + fastgltf::math::fmat4x4 view_mat, fastgltf::math::fvec3 view_pos, + lv_gltf_model_t * gltf_data, bool transmission_pass) +{ + /* The following matrix math is for the projection matrices as defined by the glTF spec:*/ + /* https://registry.khronos.org/glTF/specs/2.0/glTF-2.0.html#projection-matrices*/ + + fastgltf::math::fmat4x4 projection; + const auto & asset = lv_gltf_data_get_asset(gltf_data); + + auto width = view_desc->render_width; + auto height = view_desc->render_height; + /* It's possible the transmission pass should simply use the regular passes aspect despite having different metrics itself. */ + /* TODO: test both ways to see which has less distortion*/ + + float aspect = (float)width / (float)height; + if(transmission_pass) { + width = 256; + height = 256; + } + + std::visit(fastgltf::visitor{ + [&](fastgltf::Camera::Perspective & perspective) + { + projection = fastgltf::math::fmat4x4(0.0f); + projection[0][0] = 1.f / (aspect * tan(0.5f * perspective.yfov)); + projection[1][1] = 1.f / (tan(0.5f * perspective.yfov)); + projection[2][3] = -1; + + if(perspective.zfar.has_value()) { + // Finite projection matrix + projection[2][2] = (*perspective.zfar + perspective.znear) / + (perspective.znear - *perspective.zfar); + projection[3][2] = (2 * *perspective.zfar * perspective.znear) / + (perspective.znear - *perspective.zfar); + } + else { + // Infinite projection matrix + projection[2][2] = -1; + projection[3][2] = -2 * perspective.znear; + } + }, + [&](fastgltf::Camera::Orthographic & orthographic) + { + projection = fastgltf::math::fmat4x4(1.0f); + projection[0][0] = (1.f / orthographic.xmag) * aspect; + projection[1][1] = 1.f / orthographic.ymag; + projection[2][2] = 2.f / (orthographic.znear - orthographic.zfar); + projection[3][2] = + (orthographic.zfar + orthographic.znear) / (orthographic.znear - orthographic.zfar); + }, + }, + asset->cameras[camera].camera); + + viewer->view_matrix = view_mat; + viewer->projection_matrix = projection; + viewer->view_projection_matrix = projection * view_mat; + viewer->camera_pos = view_pos; +} + +static void setup_view_proj_matrix(lv_gltf_t * viewer, lv_gltf_view_desc_t * view_desc, lv_gltf_model_t * gltf_data, + bool transmission_pass) +{ + auto b_radius = lv_gltf_data_get_radius(gltf_data); + float radius = b_radius * 2.5; + radius *= view_desc->distance; + + fastgltf::math::fvec3 rcam_dir = fastgltf::math::fvec3(0.0f, 0.0f, 1.0f); + + fastgltf::math::fmat3x3 rotation1 = + fastgltf::math::asMatrix(lv_gltf_math_euler_to_quaternion(0.f, 0.f, fastgltf::math::radians(view_desc->pitch))); + fastgltf::math::fmat3x3 rotation2 = + fastgltf::math::asMatrix(lv_gltf_math_euler_to_quaternion(fastgltf::math::radians(view_desc->yaw), 0.f, 0.f)); + + rcam_dir = rotation1 * rcam_dir; + rcam_dir = rotation2 * rcam_dir; + + fastgltf::math::fvec3 ncam_dir = fastgltf::math::normalize(rcam_dir); + fastgltf::math::fvec3 cam_target = fastgltf::math::fvec3(view_desc->focal_x, view_desc->focal_y, view_desc->focal_z); + fastgltf::math::fvec3 cam_position = fastgltf::math::fvec3(cam_target[0] + (ncam_dir[0] * radius), + cam_target[1] + (ncam_dir[1] * radius), + cam_target[2] + (ncam_dir[2] * radius)); + + fastgltf::math::fmat4x4 view_mat = + lv_gltf_math_look_at_rh(cam_position, cam_target, fastgltf::math::fvec3(0.0f, 1.0f, 0.0f)); + + // Create Projection Matrix + fastgltf::math::fmat4x4 projection; + float fov = view_desc->fov; + + float znear = b_radius * 0.05f; + float zfar = b_radius * std::max(4.0, 8.0 * view_desc->distance); + auto width = view_desc->render_width; + auto height = view_desc->render_height; + // It's possible the transmission pass should simply use the regular passes aspect despite having different metrics itself. Testing both ways to see which has less distortion + float aspect = (float)width / (float)height; + if(transmission_pass) { + width = 256; + height = 256; + } + + if(fov <= 0.0f) { + // Isometric view: create an orthographic projection + float orthoSize = view_desc->distance * b_radius; // Adjust as needed + + projection = fastgltf::math::fmat4x4(1.0f); + projection[0][0] = -(orthoSize * aspect); + projection[1][1] = (orthoSize); + projection[2][2] = 2.f / (znear - zfar); + projection[3][2] = (zfar + znear) / (znear - zfar); + + } + else { + // Perspective view + projection = fastgltf::math::fmat4x4(0.0f); + LV_ASSERT(width != 0 && height != 0); + projection[0][0] = 1.f / (aspect * tan(0.5f * fastgltf::math::radians(fov))); + projection[1][1] = 1.f / (tan(0.5f * fastgltf::math::radians(fov))); + projection[2][3] = -1; + + // Finite projection matrix + projection[2][2] = (zfar + znear) / (znear - zfar); + projection[3][2] = (2.f * zfar * znear) / (znear - zfar); + } + + viewer->view_matrix = view_mat; + viewer->projection_matrix = projection; + viewer->view_projection_matrix = projection * view_mat; + viewer->camera_pos = cam_position; +} + + +static lv_result_t setup_restore_opaque_output(lv_gltf_t * viewer, const lv_gltf_renwin_state_t * renwin_state, + uint32_t texture_w, + uint32_t texture_h, bool prepare_bg) +{ + LV_LOG_TRACE("Color texture ID: %u, Depth texture ID: %u", renwin_state->texture, renwin_state->renderbuffer); + + GL_CALL(glBindFramebuffer(GL_FRAMEBUFFER, renwin_state->framebuffer)); + GL_CALL(glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, renwin_state->texture, 0)); + GL_CALL(glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_TEXTURE_2D, renwin_state->renderbuffer, 0)); + GL_CALL(glViewport(0, 0, texture_w, texture_h)); + if(prepare_bg) { + /* cast is safe because viewer is a lv_obj_t*/ + lv_color_t bg_color = lv_obj_get_style_bg_color((lv_obj_t *)viewer, LV_PART_MAIN); + uint8_t alpha = lv_obj_get_style_bg_opa((lv_obj_t *)viewer, LV_PART_MAIN); + GL_CALL(glClearColor(bg_color.red / 255.0f, bg_color.green / 255.0f, bg_color.blue / 255.0f, alpha / 255.0f)); + GL_CALL(glClearDepthf(1.0f)); + GL_CALL(glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT)); + } + return glGetError() == GL_NO_ERROR ? LV_RESULT_OK : LV_RESULT_INVALID; +} + +static void setup_draw_environment_background(lv_opengl_shader_manager_t * manager, lv_gltf_t * viewer, float blur) +{ + GL_CALL(glBindVertexArray(manager->bg_vao)); + + GL_CALL(glUseProgram(manager->bg_program)); + GL_CALL(glEnable(GL_CULL_FACE)); + GL_CALL(glDisable(GL_BLEND)); + GL_CALL(glDisable(GL_DEPTH_TEST)); + GL_CALL(glUniformMatrix4fv(glGetUniformLocation(manager->bg_program, "u_ViewProjectionMatrix"), 1, false, + viewer->view_projection_matrix.data())); + + /* Bind the texture to the specified texture unit*/ + GL_CALL(glActiveTexture(GL_TEXTURE0 + 0)); + GL_CALL(glBindTexture(GL_TEXTURE_CUBE_MAP, viewer->env_textures.specular)); + + GL_CALL(glUniform1i(glGetUniformLocation(manager->bg_program, "u_GGXEnvSampler"), 0)); + + GL_CALL(glUniform1i(glGetUniformLocation(manager->bg_program, "u_MipCount"), viewer->env_textures.mip_count)); + GL_CALL(glUniform1f(glGetUniformLocation(manager->bg_program, "u_EnvBlurNormalized"), blur)); + GL_CALL(glUniform1f(glGetUniformLocation(manager->bg_program, "u_EnvIntensity"), 1.0f)); + GL_CALL(glUniform1f(glGetUniformLocation(manager->bg_program, "u_Exposure"), 1.0f)); + + setup_environment_rotation_matrix(viewer->env_textures.angle, manager->bg_program); + + GL_CALL(glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, manager->bg_index_buf)); + GL_CALL(glBindBuffer(GL_ARRAY_BUFFER, manager->bg_vertex_buf)); + GL_CALL(glDrawElements(GL_TRIANGLES, 36, GL_UNSIGNED_INT, NULL)); + + GL_CALL(glBindVertexArray(0)); + return; +} +static void lv_gltf_view_recache_all_transforms(lv_gltf_model_t * gltf_data) +{ + const auto & asset = lv_gltf_data_get_asset(gltf_data); + int32_t anim_num = gltf_data->current_animation; + uint32_t scene_index = 0; + + gltf_data->last_camera_index = gltf_data->camera; + size_t current_camera_count = 0; + + lv_gltf_data_clear_transform_cache(gltf_data); + + auto tmat = fastgltf::math::fmat4x4{}; + fastgltf::custom_iterate_scene_nodes( + *asset, scene_index, &tmat, + [&](fastgltf::Node & node, fastgltf::math::fmat4x4 & parentworldmatrix, fastgltf::math::fmat4x4 & localmatrix) { + bool made_changes = false; + bool made_rotation_changes = false; + if(lv_gltf_data_animation_get_channel_set(anim_num, gltf_data, node)->size() > 0) { + lv_gltf_data_animation_matrix_apply(gltf_data->local_timestamp / 1000., anim_num, gltf_data, node, + localmatrix); + made_changes = true; + } + if(gltf_data->node_binds.find(&node) != gltf_data->node_binds.end()) { + lv_gltf_bind_t * current_override = gltf_data->node_binds[&node]; + fastgltf::math::fvec3 local_pos; + fastgltf::math::fquat local_quat; + fastgltf::math::fvec3 local_scale; + fastgltf::math::decomposeTransformMatrix(localmatrix, local_scale, local_quat, local_pos); + fastgltf::math::fvec3 local_rot = lv_gltf_math_quaternion_to_euler(local_quat); + + // Traverse through all linked overrides + while(current_override != nullptr) { + if(current_override->prop == LV_GLTF_BIND_PROP_ROTATION) { + if(current_override->dir) { + current_override->data[0] = local_rot[0]; + current_override->data[1] = local_rot[1]; + current_override->data[2] = local_rot[2]; + } + else { + if(current_override->data_mask & LV_GLTF_BIND_CHANNEL_1) + local_rot[0] = current_override->data[0]; + if(current_override->data_mask & LV_GLTF_BIND_CHANNEL_2) + local_rot[1] = current_override->data[1]; + if(current_override->data_mask & LV_GLTF_BIND_CHANNEL_3) + local_rot[2] = current_override->data[2]; + made_changes = true; + made_rotation_changes = true; + } + } + else if(current_override->prop == LV_GLTF_BIND_PROP_POSITION) { + if(current_override->dir) { + current_override->data[0] = local_pos[0]; + current_override->data[1] = local_pos[1]; + current_override->data[2] = local_pos[2]; + } + else { + if(current_override->data_mask & LV_GLTF_BIND_CHANNEL_1) + local_pos[0] = current_override->data[0]; + if(current_override->data_mask & LV_GLTF_BIND_CHANNEL_2) + local_pos[1] = current_override->data[1]; + if(current_override->data_mask & LV_GLTF_BIND_CHANNEL_3) + local_pos[2] = current_override->data[2]; + made_changes = true; + } + } + else if(current_override->prop == LV_GLTF_BIND_PROP_WORLD_POSITION) { + fastgltf::math::fvec3 world_pos; + fastgltf::math::fquat world_quat; + fastgltf::math::fvec3 world_scale; + fastgltf::math::decomposeTransformMatrix(parentworldmatrix * localmatrix, + world_scale, world_quat, world_pos); + + if(current_override->dir) { + current_override->data[0] = world_pos[0]; + current_override->data[1] = world_pos[1]; + current_override->data[2] = world_pos[2]; + } + } + else if(current_override->prop == LV_GLTF_BIND_PROP_SCALE) { + if(current_override->dir) { + current_override->data[0] = local_scale[0]; + current_override->data[1] = local_scale[1]; + current_override->data[2] = local_scale[2]; + } + else { + if(current_override->data_mask & LV_GLTF_BIND_CHANNEL_1) + local_scale[0] = current_override->data[0]; + if(current_override->data_mask & LV_GLTF_BIND_CHANNEL_2) + local_scale[1] = current_override->data[1]; + if(current_override->data_mask & LV_GLTF_BIND_CHANNEL_3) + local_scale[2] = current_override->data[2]; + made_changes = true; + } + } + + // Move to the next override in the linked list + current_override = current_override->next_bind; + } + + // Rebuild the local matrix after applying all overrides + localmatrix = fastgltf::math::scale( + fastgltf::math::rotate(fastgltf::math::translate(fastgltf::math::fmat4x4(), local_pos), + made_rotation_changes ? + lv_gltf_math_euler_to_quaternion( + local_rot[0], local_rot[1], local_rot[2]) : + local_quat), + local_scale); + } + + if(made_changes || !lv_gltf_data_has_cached_transform(gltf_data, &node)) { + lv_gltf_data_set_cached_transform(gltf_data, &node, parentworldmatrix * localmatrix); + } + + if(node.cameraIndex.has_value()) { + current_camera_count++; + if(current_camera_count == gltf_data->camera) { + fastgltf::math::fmat4x4 cammat = (parentworldmatrix * localmatrix); + gltf_data->view_pos[0] = cammat[3][0]; + gltf_data->view_pos[1] = cammat[3][1]; + gltf_data->view_pos[2] = cammat[3][2]; + gltf_data->view_mat = fastgltf::math::invert(cammat); + } + } + }); +} + +static void setup_environment_rotation_matrix(float env_rotation_angle, uint32_t shader_program) +{ + fastgltf::math::fmat3x3 rotmat = + fastgltf::math::asMatrix(lv_gltf_math_euler_to_quaternion(env_rotation_angle, 0.f, 3.14159f)); + + // Get the uniform location and set the uniform + int32_t u_loc; + GL_CALL(u_loc = glGetUniformLocation(shader_program, "u_EnvRotation")); + GL_CALL(glUniformMatrix3fv(u_loc, 1, GL_FALSE, (const GLfloat *)rotmat.data())); +} + +#endif /*LV_USE_GLTF*/ diff --git a/src/libs/gltf/gltf_view/lv_gltf_view_shader.cpp b/src/libs/gltf/gltf_view/lv_gltf_view_shader.cpp new file mode 100644 index 0000000000..854cae8f74 --- /dev/null +++ b/src/libs/gltf/gltf_view/lv_gltf_view_shader.cpp @@ -0,0 +1,400 @@ +/** + * @file lv_gltf_view_shader.cpp + * + */ + +/********************* + * INCLUDES + *********************/ +#include "lv_gltf_view_internal.h" +#if LV_USE_GLTF + +#include "fastgltf/types.hpp" +#include "../gltf_data/lv_gltf_data_internal.hpp" +#include "../gltf_data/lv_gltf_data_internal.h" +#include "../../../drivers/opengles/opengl_shader/lv_opengl_shader_internal.h" +#include "../../../misc/lv_array.h" +#include "../../../misc/lv_assert.h" +#include "../../../misc/lv_types.h" +#include "../../../stdlib/lv_sprintf.h" +#include "../../../stdlib/lv_string.h" + +/********************* + * DEFINES + *********************/ + +/********************** + * TYPEDEFS + **********************/ + +/********************** + * STATIC PROTOTYPES + **********************/ + +static lv_result_t add_define(lv_array_t * array, const char * defsymbol, const char * value, bool value_allocated); +static lv_result_t add_define_if_primitive_attribute_exists(lv_array_t * array, const fastgltf::Asset & asset, + const fastgltf::Primitive * primitive, const char * attribute, + const char * define); + +static lv_result_t add_texture_defines_impl(lv_array_t * array, const fastgltf::TextureInfo & material_prop, + const char * define, + const char * uv_define); + +static lv_result_t add_texture_defines(lv_array_t * array, + const fastgltf::Optional & material_prop, + const char * define, const char * uv_define); + +static lv_result_t add_texture_defines(lv_array_t * array, + const fastgltf::Optional & material_prop, + const char * define, const char * uv_define); + +static lv_result_t add_texture_defines(lv_array_t * array, + const fastgltf::Optional & material_prop, + const char * define, const char * uv_define); + +/********************** + * STATIC VARIABLES + **********************/ + +/********************** + * MACROS + **********************/ + +/********************** + * GLOBAL FUNCTIONS + **********************/ + +lv_result_t lv_gltf_view_shader_injest_discover_defines(lv_array_t * result, lv_gltf_model_t * data, + fastgltf::Node * node, + fastgltf::Primitive * prim) +{ + const auto & asset = data->asset; + + if(add_define(result, "_OPAQUE", "0", false) == LV_RESULT_INVALID) { + return LV_RESULT_INVALID; + } + if(add_define(result, "_MASK", "1", false) == LV_RESULT_INVALID) { + return LV_RESULT_INVALID; + } + if(add_define(result, "_BLEND", "2", false) == LV_RESULT_INVALID) { + return LV_RESULT_INVALID; + } + + LV_ASSERT_MSG(prim->findAttribute("POSITION") != prim->attributes.end(), + "A mesh primitive is required to hold the POSITION attribute"); + LV_ASSERT_MSG(prim->indicesAccessor.has_value(), + "We specify fastgltf::Options::GenerateMeshIndices, so we should always have indices"); + + if(!prim->materialIndex.has_value()) { + if(add_define(result, "ALPHAMODE", "_OPAQUE", false) == LV_RESULT_INVALID) { + return LV_RESULT_INVALID; + } + } + else { + const auto & material = asset.materials[prim->materialIndex.value()]; + if(add_define(result, "TONEMAP_KHR_PBR_NEUTRAL", NULL, false) == LV_RESULT_INVALID) { + return LV_RESULT_INVALID; + } + if(material.unlit) { + if(add_define(result, "MATERIAL_UNLIT", NULL, false) == LV_RESULT_INVALID) { + return LV_RESULT_INVALID; + } + if(add_define(result, "LINEAR_OUTPUT", NULL, false) == LV_RESULT_INVALID) { + return LV_RESULT_INVALID; + } + } + else { + if(add_define(result, "MATERIAL_METALLICROUGHNESS", NULL, false) == LV_RESULT_INVALID) { + return LV_RESULT_INVALID; + } + if(add_define(result, "LINEAR_OUTPUT", NULL, false) == LV_RESULT_INVALID) { + return LV_RESULT_INVALID; + } + } + const size_t light_count = data->node_by_light_index.size(); + if(add_define(result, "USE_IBL", NULL, false) == LV_RESULT_INVALID) { + return LV_RESULT_INVALID; + } + if(light_count > 10) { + LV_LOG_ERROR("Too many scene lights, max is 10"); + } + else if(light_count > 0) { + if(add_define(result, "USE_PUNCTUAL", NULL, false) == LV_RESULT_INVALID) { + return LV_RESULT_INVALID; + } + char * count = (char *) lv_zalloc(5); + lv_snprintf(count, 5, "%zu", light_count); + if(add_define(result, "LIGHT_COUNT", count, true) == LV_RESULT_INVALID) { + return LV_RESULT_INVALID; + } + } + else { + if(add_define(result, "LIGHT_COUNT", "0", false) == LV_RESULT_INVALID) { + return LV_RESULT_INVALID; + } + } + + // only set cutoff value for mask material + if(material.alphaMode == fastgltf::AlphaMode::Mask) { + if(add_define(result, "ALPHAMODE", "_MASK", false) == LV_RESULT_INVALID) { + return LV_RESULT_INVALID; + } + } + else if(material.alphaMode == fastgltf::AlphaMode::Opaque) { + if(add_define(result, "ALPHAMODE", "_OPAQUE", false) == LV_RESULT_INVALID) { + return LV_RESULT_INVALID; + } + } + else { + if(add_define(result, "ALPHAMODE", "_BLEND", false) == LV_RESULT_INVALID) { + return LV_RESULT_INVALID; + } + } + if(add_texture_defines(result, material.pbrData.baseColorTexture, "HAS_BASE_COLOR_MAP", + "HAS_BASECOLOR_UV_TRANSFORM") == LV_RESULT_INVALID) { + return LV_RESULT_INVALID; + } + if(add_texture_defines(result, material.pbrData.metallicRoughnessTexture, "HAS_METALLIC_ROUGHNESS_MAP", + "HAS_METALLICROUGHNESS_UV_TRANSFORM") == LV_RESULT_INVALID) { + return LV_RESULT_INVALID; + } + if(add_texture_defines(result, material.occlusionTexture, "HAS_OCCLUSION_MAP", "HAS_OCCLUSION_UV_TRANSFORM") == + LV_RESULT_INVALID) { + return LV_RESULT_INVALID; + } + if(add_texture_defines(result, material.normalTexture, "HAS_NORMAL_MAP", "HAS_NORMAL_UV_TRANSFORM") == + LV_RESULT_INVALID) { + return LV_RESULT_INVALID; + } + if(add_texture_defines(result, material.emissiveTexture, "HAS_EMISSIVE_MAP", "HAS_EMISSIVE_UV_TRANSFORM") == + LV_RESULT_INVALID) { + return LV_RESULT_INVALID; + } + + if(add_define(result, "MATERIAL_EMISSIVE_STRENGTH", NULL, false) == LV_RESULT_INVALID) { + return LV_RESULT_INVALID; + } + if(material.sheen) + if(add_define(result, "MATERIAL_SHEEN", NULL, false) == LV_RESULT_INVALID) { + return LV_RESULT_INVALID; + } + if(material.specular) + if(add_define(result, "MATERIAL_SPECULAR", NULL, false) == LV_RESULT_INVALID) { + return LV_RESULT_INVALID; + } + if(material.specularGlossiness) { + if(add_define(result, "MATERIAL_SPECULARGLOSSINESS", NULL, false) == LV_RESULT_INVALID) { + return LV_RESULT_INVALID; + } + if(add_texture_defines(result, material.specularGlossiness->diffuseTexture, "HAS_DIFFUSE_MAP", + "HAS_DIFFUSE_UV_TRANSFORM")) { + return LV_RESULT_INVALID; + } + if(add_texture_defines(result, material.specularGlossiness->specularGlossinessTexture, + "HAS_SPECULARGLOSSINESS_MAP", "HAS_SPECULARGLOSSINESS_UV_TRANSFORM")) { + return LV_RESULT_INVALID; + } + } + if(material.transmission) { + if(add_define(result, "MATERIAL_TRANSMISSION", NULL, false) == LV_RESULT_INVALID) { + return LV_RESULT_INVALID; + } + if(add_define(result, "MATERIAL_DISPERSION", NULL, false) == LV_RESULT_INVALID) { + return LV_RESULT_INVALID; + } + if(add_define(result, "MATERIAL_VOLUME", NULL, false) == LV_RESULT_INVALID) { + return LV_RESULT_INVALID; + } + if(material.transmission->transmissionTexture.has_value()) + if(add_define(result, "HAS_TRANSMISSION_MAP", NULL, false) == LV_RESULT_INVALID) { + return LV_RESULT_INVALID; + } + if(material.volume) { + add_texture_defines(result, material.volume->thicknessTexture, "HAS_THICKNESS_MAP", + "HAS_THICKNESS_UV_TRANSFORM"); + } + } + if(material.clearcoat) { + if(add_define(result, "MATERIAL_CLEARCOAT", NULL, false) == LV_RESULT_INVALID) { + return LV_RESULT_INVALID; + } + if(add_texture_defines(result, material.clearcoat->clearcoatTexture, "HAS_CLEARCOAT_MAP", + "HAS_CLEARCOAT_UV_TRANSFORM") == LV_RESULT_INVALID) { + return LV_RESULT_INVALID; + } + if(add_texture_defines(result, material.clearcoat->clearcoatRoughnessTexture, + "HAS_CLEARCOAT_ROUGHNESS_MAP", + "HAS_CLEARCOATROUGHNESS_UV_TRANSFORM") == LV_RESULT_INVALID) { + return LV_RESULT_INVALID; + } + if(add_texture_defines(result, material.clearcoat->clearcoatNormalTexture, "HAS_CLEARCOAT_NORMAL_MAP", + "HAS_CLEARCOATNORMAL_UV_TRANSFORM") == LV_RESULT_INVALID) { + return LV_RESULT_INVALID; + } + } + if(material.diffuseTransmission) { + if(add_define(result, "MATERIAL_DIFFUSE_TRANSMISSION", NULL, false) == LV_RESULT_INVALID) { + return LV_RESULT_INVALID; + } + if(material.diffuseTransmission->diffuseTransmissionTexture.has_value()) { + if(add_define(result, "HAS_DIFFUSE_TRANSMISSION_MAP", NULL, false) == LV_RESULT_INVALID) { + return LV_RESULT_INVALID; + } + } + if(material.diffuseTransmission->diffuseTransmissionColorTexture.has_value()) { + if(add_define(result, "HAS_DIFFUSE_TRANSMISSION_COLOR_MAP", NULL, false) == LV_RESULT_INVALID) { + return LV_RESULT_INVALID; + } + } + } + } + if(add_define_if_primitive_attribute_exists(result, asset, prim, "NORMAL", "HAS_NORMAL_VEC3") == LV_RESULT_INVALID) { + return LV_RESULT_INVALID; + } + if(add_define_if_primitive_attribute_exists(result, asset, prim, "TANGENT", "HAS_TANGENT_VEC4") == LV_RESULT_INVALID) { + return LV_RESULT_INVALID; + } + if(add_define_if_primitive_attribute_exists(result, asset, prim, "TEXCOORD_0", "HAS_TEXCOORD_0_VEC2") == + LV_RESULT_INVALID) { + return LV_RESULT_INVALID; + } + if(add_define_if_primitive_attribute_exists(result, asset, prim, "TEXCOORD_1", "HAS_TEXCOORD_1_VEC2") == + LV_RESULT_INVALID) { + return LV_RESULT_INVALID; + } + if(add_define_if_primitive_attribute_exists(result, asset, prim, "JOINTS_0", + "HAS_JOINTS_0_VEC4") == LV_RESULT_INVALID) { + return LV_RESULT_INVALID; + } + if(add_define_if_primitive_attribute_exists(result, asset, prim, "JOINTS_1", + "HAS_JOINTS_1_VEC4") == LV_RESULT_INVALID) { + return LV_RESULT_INVALID; + } + if(add_define_if_primitive_attribute_exists(result, asset, prim, "WEIGHTS_0", "HAS_WEIGHTS_0_VEC4") == + LV_RESULT_INVALID) { + return LV_RESULT_INVALID; + } + if(add_define_if_primitive_attribute_exists(result, asset, prim, "WEIGHTS_1", "HAS_WEIGHTS_1_VEC4") == + LV_RESULT_INVALID) { + return LV_RESULT_INVALID; + } + + const auto * joints0it = prim->findAttribute("JOINTS_0"); + const auto * weights0it = prim->findAttribute("WEIGHTS_0"); + if((node->skinIndex.has_value()) && (joints0it != prim->attributes.end()) && (weights0it != prim->attributes.end())) { + if(add_define(result, "USE_SKINNING", NULL, false) == LV_RESULT_INVALID) { + return LV_RESULT_INVALID; + } + } + return LV_RESULT_OK; +} + +/** + * @brief Compile and load shaders. + * + * This function compiles and loads the shaders from the specified shader cache, preparing them + * for use in rendering operations. It returns a structure containing the shader set information. + * + * @param shaders Pointer to the lv_opengl_shader_cache_t structure containing the shader cache. + * @return A gl_renwin_shaderset_t structure representing the compiled and loaded shaders. + */ + +lv_gltf_shaderset_t lv_gltf_view_shader_compile_program(lv_gltf_t * view, const lv_opengl_shader_define_t * defines, + size_t n) +{ + uint32_t frag_shader_hash; + uint32_t vert_shader_hash; + lv_result_t res = lv_opengl_shader_manager_select_shader(&view->shader_manager, "__MAIN__.frag", + defines, n, LV_OPENGL_GLSL_VERSION_300ES, &frag_shader_hash); + LV_ASSERT(res == LV_RESULT_OK); + res = lv_opengl_shader_manager_select_shader(&view->shader_manager, "__MAIN__.vert", + defines, n, LV_OPENGL_GLSL_VERSION_300ES, &vert_shader_hash); + LV_ASSERT(res == LV_RESULT_OK); + lv_opengl_shader_program_t * program = + lv_opengl_shader_manager_get_program(&view->shader_manager, frag_shader_hash, vert_shader_hash); + + LV_ASSERT_MSG(program != NULL, + "Failed to link program. This probably means your platform doesn't support GLSL version 300 es"); + + GLuint program_id = lv_opengl_shader_program_get_id(program); + + GL_CALL(glUseProgram(program_id)); + lv_gltf_shaderset_t shader_prog; + shader_prog.program = program_id; + + return shader_prog; +} + +/********************** + * STATIC FUNCTIONS + **********************/ + +static lv_result_t add_define(lv_array_t * array, const char * name, const char * value, bool value_allocated) +{ + const size_t n = lv_array_size(array); + for(size_t i = 0; i < n; ++i) { + lv_opengl_shader_define_t * define = (lv_opengl_shader_define_t *)lv_array_at(array, i); + if(lv_streq(define->name, name)) { + return LV_RESULT_OK; + } + } + + lv_opengl_shader_define_t entry = { name, value, value_allocated }; + return lv_array_push_back(array, &entry); +} + +static lv_result_t add_define_if_primitive_attribute_exists(lv_array_t * array, const fastgltf::Asset & asset, + const fastgltf::Primitive * primitive, const char * attribute, + const char * define) +{ + const auto & it = primitive->findAttribute(attribute); + if(it == primitive->attributes.end() || !asset.accessors[it->accessorIndex].bufferViewIndex.has_value()) { + return LV_RESULT_OK; + } + return add_define(array, define, NULL, false); +} + +static lv_result_t add_texture_defines_impl(lv_array_t * array, const fastgltf::TextureInfo & material_prop, + const char * define, + const char * uv_define) +{ + if(add_define(array, define, NULL, false) == LV_RESULT_INVALID) { + return LV_RESULT_INVALID; + } + if(!material_prop.transform) { + return LV_RESULT_OK; + } + return add_define(array, uv_define, NULL, false); +} + +static lv_result_t add_texture_defines(lv_array_t * array, + const fastgltf::Optional & material_prop, + const char * define, const char * uv_define) +{ + if(!material_prop.has_value()) { + return LV_RESULT_OK; + } + return add_texture_defines_impl(array, material_prop.value(), define, uv_define); +} + +static lv_result_t add_texture_defines(lv_array_t * array, + const fastgltf::Optional & material_prop, + const char * define, const char * uv_define) +{ + if(!material_prop.has_value()) { + return LV_RESULT_OK; + } + return add_texture_defines_impl(array, material_prop.value(), define, uv_define); +} + +static lv_result_t add_texture_defines(lv_array_t * array, + const fastgltf::Optional & material_prop, + const char * define, const char * uv_define) +{ + if(!material_prop.has_value()) { + return LV_RESULT_OK; + } + return add_texture_defines_impl(array, material_prop.value(), define, uv_define); +} + +#endif /*LV_USE_GLTF*/ diff --git a/src/libs/gltf/math/lv_gltf_math.cpp b/src/libs/gltf/math/lv_gltf_math.cpp new file mode 100644 index 0000000000..02f4775548 --- /dev/null +++ b/src/libs/gltf/math/lv_gltf_math.cpp @@ -0,0 +1,78 @@ +/** + * @file lv_gltf_math.cpp + * + */ + +/********************* + * INCLUDES + *********************/ + +#include "lv_gltf_math.hpp" + +#if LV_USE_GLTF + +#include + +/********************* + * DEFINES + *********************/ + +/********************** + * TYPEDEFS + **********************/ + +/********************** + * STATIC PROTOTYPES + **********************/ + +/********************** + * STATIC VARIABLES + **********************/ + +/********************** + * MACROS + **********************/ + +/********************** + * GLOBAL FUNCTIONS + **********************/ + +/** Creates a right-handed view matrix */ +fastgltf::math::fmat4x4 lv_gltf_math_look_at_rh(const fastgltf::math::fvec3 & eye, const fastgltf::math::fvec3 & center, + const fastgltf::math::fvec3 & up) noexcept +{ + auto dir = normalize(center - eye); + auto lft = normalize(cross(dir, up)); + auto rup = cross(lft, dir); + + fastgltf::math::fmat4x4 ret(1.f); + ret.col(0) = { lft.x(), rup.x(), -dir.x(), 0.f }; + ret.col(1) = { lft.y(), rup.y(), -dir.y(), 0.f }; + ret.col(2) = { lft.z(), rup.z(), -dir.z(), 0.f }; + ret.col(3) = { -dot(lft, eye), -dot(rup, eye), dot(dir, eye), 1.f }; + return ret; +} + +/** + * Creates a right-handed perspective matrix, with the near and far clips at -1 and +1, respectively. + * @param fov The FOV in radians + */ +[[nodiscard]] fastgltf::math::fmat4x4 lv_gltf_math_perspective_rh(float fov, float ratio, float z_near, + float z_far) noexcept +{ + fastgltf::math::fmat4x4 ret(0.f); + auto tanHalfFov = std::tan(fov / 2.f); + ret.col(0).x() = 1.f / (ratio * tanHalfFov); + ret.col(1).y() = 1.f / tanHalfFov; + ret.col(2).z() = -(z_far + z_near) / (z_far - z_near); + ret.col(2).w() = -1.f; + ret.col(3).z() = -(2.f * z_far * z_near) / (z_far - z_near); + return ret; +} + + +/********************** + * STATIC FUNCTIONS + **********************/ + +#endif /*LV_USE_GLTF*/ diff --git a/src/libs/gltf/math/lv_gltf_math.hpp b/src/libs/gltf/math/lv_gltf_math.hpp new file mode 100644 index 0000000000..fadd1f57c9 --- /dev/null +++ b/src/libs/gltf/math/lv_gltf_math.hpp @@ -0,0 +1,84 @@ +/** + * @file lv_gltf_math.hpp + * @brief GLTF math utilities and helper functions + */ + +#ifndef LV_GLTF_MATH_HPP +#define LV_GLTF_MATH_HPP + +/********************* + * INCLUDES + *********************/ + +#include "../../../lv_conf_internal.h" + +#if LV_USE_GLTF + +#include + +/********************* + * DEFINES + *********************/ + +#ifndef M_PI + #define M_PI 3.14159265358979323846264338327950288 +#endif + +/********************** + * TYPEDEFS + **********************/ + +/********************** + * GLOBAL PROTOTYPES + **********************/ + +fastgltf::math::fmat4x4 lv_gltf_math_look_at_rh(const fastgltf::math::fvec3 & eye, const fastgltf::math::fvec3 & center, const fastgltf::math::fvec3 & up) noexcept; +fastgltf::math::fmat4x4 lv_gltf_math_perspective_rh(float fov, float ratio, float z_near, float z_far) noexcept; + +template +[[nodiscard]] fastgltf::math::quat lv_gltf_math_euler_to_quaternion(T P, T Y, T R) +{ + // Convert degrees to radians if necessary + // roll = roll * (M_PI / 180.0); + // pitch = pitch * (M_PI / 180.0); + // yaw = yaw * (M_PI / 180.0); + T H = T(0.5); + Y *= H; + P *= H; + R *= H; + T cy = cos(Y), sy = sin(Y), cp = cos(P), sp = sin(P), cr = cos(R), sr = sin(R); + T cr_cp = cr * cp, sp_sy = sp * sy, sr_cp = sr * cp, sp_cy = sp * cy; + return fastgltf::math::quat( + sr_cp * cy - cr * sp_sy, // X + sr_cp * sy + cr * sp_cy, // Y + cr_cp * sy - sr * sp_cy, // Z + cr_cp * cy + sr * sp_sy // W + ); +} + +template +[[nodiscard]] fastgltf::math::vec lv_gltf_math_quaternion_to_euler(fastgltf::math::quat q) +{ + T Q11 = q[1] * q[1]; + // Roll (Z) + T sinr_cosp = T(2.0) * (q[3] * q[0] + q[1] * q[2]); + T cosr_cosp = T(1.0) - T(2.0) * (q[0] * q[0] + Q11); + // Pitch (X) + T sinp = T(2.0) * (q[3] * q[1] - q[2] * q[0]); + // Yaw (Y) + T siny_cosp = T(2.0) * (q[3] * q[2] + q[0] * q[1]); + T cosy_cosp = T(1.0) - T(2.0) * (Q11 + q[2] * q[2]); + + return fastgltf::math::vec( + (std::abs(sinp) >= T(1)) ? std::copysign(T(M_PI) / T(2), sinp) : std::asin(sinp), + std::atan2(siny_cosp, cosy_cosp), + std::atan2(sinr_cosp, cosr_cosp) + ); +} + +/********************** + * MACROS + **********************/ + +#endif /*LV_USE_GLTF*/ +#endif /*LV_GLTF_MATH_HPP*/ diff --git a/src/libs/gltf/stb_image/stb_image.h b/src/libs/gltf/stb_image/stb_image.h new file mode 100644 index 0000000000..f7344e545e --- /dev/null +++ b/src/libs/gltf/stb_image/stb_image.h @@ -0,0 +1,8366 @@ +/* stb_image - v2.30 - public domain image loader - http://nothings.org/stb + no warranty implied; use at your own risk + + Do this: + #define STB_IMAGE_IMPLEMENTATION + before you include this file in *one* C or C++ file to create the implementation. + + // i.e. it should look like this: + #include ... + #include ... + #include ... + #define STB_IMAGE_IMPLEMENTATION + #include "stb_image.h" + + You can #define STBI_ASSERT(x) before the #include to avoid using assert.h. + And #define STBI_MALLOC, STBI_REALLOC, and STBI_FREE to avoid using malloc,realloc,free + + + QUICK NOTES: + Primarily of interest to game developers and other people who can + avoid problematic images and only need the trivial interface + + JPEG baseline & progressive (12 bpc/arithmetic not supported, same as stock IJG lib) + PNG 1/2/4/8/16-bit-per-channel + + TGA (not sure what subset, if a subset) + BMP non-1bpp, non-RLE + PSD (composited view only, no extra channels, 8/16 bit-per-channel) + + GIF (*comp always reports as 4-channel) + HDR (radiance rgbE format) + PIC (Softimage PIC) + PNM (PPM and PGM binary only) + + Animated GIF still needs a proper API, but here's one way to do it: + http://gist.github.com/urraka/685d9a6340b26b830d49 + + - decode from memory or through FILE (define STBI_NO_STDIO to remove code) + - decode from arbitrary I/O callbacks + - SIMD acceleration on x86/x64 (SSE2) and ARM (NEON) + + Full documentation under "DOCUMENTATION" below. + + +LICENSE + + See end of file for license information. + +RECENT REVISION HISTORY: + + 2.30 (2024-05-31) avoid erroneous gcc warning + 2.29 (2023-05-xx) optimizations + 2.28 (2023-01-29) many error fixes, security errors, just tons of stuff + 2.27 (2021-07-11) document stbi_info better, 16-bit PNM support, bug fixes + 2.26 (2020-07-13) many minor fixes + 2.25 (2020-02-02) fix warnings + 2.24 (2020-02-02) fix warnings; thread-local failure_reason and flip_vertically + 2.23 (2019-08-11) fix clang static analysis warning + 2.22 (2019-03-04) gif fixes, fix warnings + 2.21 (2019-02-25) fix typo in comment + 2.20 (2019-02-07) support utf8 filenames in Windows; fix warnings and platform ifdefs + 2.19 (2018-02-11) fix warning + 2.18 (2018-01-30) fix warnings + 2.17 (2018-01-29) bugfix, 1-bit BMP, 16-bitness query, fix warnings + 2.16 (2017-07-23) all functions have 16-bit variants; optimizations; bugfixes + 2.15 (2017-03-18) fix png-1,2,4; all Imagenet JPGs; no runtime SSE detection on GCC + 2.14 (2017-03-03) remove deprecated STBI_JPEG_OLD; fixes for Imagenet JPGs + 2.13 (2016-12-04) experimental 16-bit API, only for PNG so far; fixes + 2.12 (2016-04-02) fix typo in 2.11 PSD fix that caused crashes + 2.11 (2016-04-02) 16-bit PNGS; enable SSE2 in non-gcc x64 + RGB-format JPEG; remove white matting in PSD; + allocate large structures on the stack; + correct channel count for PNG & BMP + 2.10 (2016-01-22) avoid warning introduced in 2.09 + 2.09 (2016-01-16) 16-bit TGA; comments in PNM files; STBI_REALLOC_SIZED + + See end of file for full revision history. + + + ============================ Contributors ========================= + + Image formats Extensions, features + Sean Barrett (jpeg, png, bmp) Jetro Lauha (stbi_info) + Nicolas Schulz (hdr, psd) Martin "SpartanJ" Golini (stbi_info) + Jonathan Dummer (tga) James "moose2000" Brown (iPhone PNG) + Jean-Marc Lienher (gif) Ben "Disch" Wenger (io callbacks) + Tom Seddon (pic) Omar Cornut (1/2/4-bit PNG) + Thatcher Ulrich (psd) Nicolas Guillemot (vertical flip) + Ken Miller (pgm, ppm) Richard Mitton (16-bit PSD) + github:urraka (animated gif) Junggon Kim (PNM comments) + Christopher Forseth (animated gif) Daniel Gibson (16-bit TGA) + socks-the-fox (16-bit PNG) + Jeremy Sawicki (handle all ImageNet JPGs) + Optimizations & bugfixes Mikhail Morozov (1-bit BMP) + Fabian "ryg" Giesen Anael Seghezzi (is-16-bit query) + Arseny Kapoulkine Simon Breuss (16-bit PNM) + John-Mark Allen + Carmelo J Fdez-Aguera + + Bug & warning fixes + Marc LeBlanc David Woo Guillaume George Martins Mozeiko + Christpher Lloyd Jerry Jansson Joseph Thomson Blazej Dariusz Roszkowski + Phil Jordan Dave Moore Roy Eltham + Hayaki Saito Nathan Reed Won Chun + Luke Graham Johan Duparc Nick Verigakis the Horde3D community + Thomas Ruf Ronny Chevalier github:rlyeh + Janez Zemva John Bartholomew Michal Cichon github:romigrou + Jonathan Blow Ken Hamada Tero Hanninen github:svdijk + Eugene Golushkov Laurent Gomila Cort Stratton github:snagar + Aruelien Pocheville Sergio Gonzalez Thibault Reuille github:Zelex + Cass Everitt Ryamond Barbiero github:grim210 + Paul Du Bois Engin Manap Aldo Culquicondor github:sammyhw + Philipp Wiesemann Dale Weiler Oriol Ferrer Mesia github:phprus + Josh Tobin Neil Bickford Matthew Gregan github:poppolopoppo + Julian Raschke Gregory Mullen Christian Floisand github:darealshinji + Baldur Karlsson Kevin Schmidt JR Smith github:Michaelangel007 + Brad Weinberger Matvey Cherevko github:mosra + Luca Sas Alexander Veselov Zack Middleton [reserved] + Ryan C. Gordon [reserved] [reserved] + DO NOT ADD YOUR NAME HERE + + Jacko Dirks + + To add your name to the credits, pick a random blank space in the middle and fill it. + 80% of merge conflicts on stb PRs are due to people adding their name at the end + of the credits. +*/ + +#ifndef STBI_INCLUDE_STB_IMAGE_H +#define STBI_INCLUDE_STB_IMAGE_H + +// DOCUMENTATION +// +// Limitations: +// - no 12-bit-per-channel JPEG +// - no JPEGs with arithmetic coding +// - GIF always returns *comp=4 +// +// Basic usage (see HDR discussion below for HDR usage): +// int x,y,n; +// unsigned char *data = stbi_load(filename, &x, &y, &n, 0); +// // ... process data if not NULL ... +// // ... x = width, y = height, n = # 8-bit components per pixel ... +// // ... replace '0' with '1'..'4' to force that many components per pixel +// // ... but 'n' will always be the number that it would have been if you said 0 +// stbi_image_free(data); +// +// Standard parameters: +// int *x -- outputs image width in pixels +// int *y -- outputs image height in pixels +// int *channels_in_file -- outputs # of image components in image file +// int desired_channels -- if non-zero, # of image components requested in result +// +// The return value from an image loader is an 'unsigned char *' which points +// to the pixel data, or NULL on an allocation failure or if the image is +// corrupt or invalid. The pixel data consists of *y scanlines of *x pixels, +// with each pixel consisting of N interleaved 8-bit components; the first +// pixel pointed to is top-left-most in the image. There is no padding between +// image scanlines or between pixels, regardless of format. The number of +// components N is 'desired_channels' if desired_channels is non-zero, or +// *channels_in_file otherwise. If desired_channels is non-zero, +// *channels_in_file has the number of components that _would_ have been +// output otherwise. E.g. if you set desired_channels to 4, you will always +// get RGBA output, but you can check *channels_in_file to see if it's trivially +// opaque because e.g. there were only 3 channels in the source image. +// +// An output image with N components has the following components interleaved +// in this order in each pixel: +// +// N=#comp components +// 1 grey +// 2 grey, alpha +// 3 red, green, blue +// 4 red, green, blue, alpha +// +// If image loading fails for any reason, the return value will be NULL, +// and *x, *y, *channels_in_file will be unchanged. The function +// stbi_failure_reason() can be queried for an extremely brief, end-user +// unfriendly explanation of why the load failed. Define STBI_NO_FAILURE_STRINGS +// to avoid compiling these strings at all, and STBI_FAILURE_USERMSG to get slightly +// more user-friendly ones. +// +// Paletted PNG, BMP, GIF, and PIC images are automatically depalettized. +// +// To query the width, height and component count of an image without having to +// decode the full file, you can use the stbi_info family of functions: +// +// int x,y,n,ok; +// ok = stbi_info(filename, &x, &y, &n); +// // returns ok=1 and sets x, y, n if image is a supported format, +// // 0 otherwise. +// +// Note that stb_image pervasively uses ints in its public API for sizes, +// including sizes of memory buffers. This is now part of the API and thus +// hard to change without causing breakage. As a result, the various image +// loaders all have certain limits on image size; these differ somewhat +// by format but generally boil down to either just under 2GB or just under +// 1GB. When the decoded image would be larger than this, stb_image decoding +// will fail. +// +// Additionally, stb_image will reject image files that have any of their +// dimensions set to a larger value than the configurable STBI_MAX_DIMENSIONS, +// which defaults to 2**24 = 16777216 pixels. Due to the above memory limit, +// the only way to have an image with such dimensions load correctly +// is for it to have a rather extreme aspect ratio. Either way, the +// assumption here is that such larger images are likely to be malformed +// or malicious. If you do need to load an image with individual dimensions +// larger than that, and it still fits in the overall size limit, you can +// #define STBI_MAX_DIMENSIONS on your own to be something larger. +// +// =========================================================================== +// +// UNICODE: +// +// If compiling for Windows and you wish to use Unicode filenames, compile +// with +// #define STBI_WINDOWS_UTF8 +// and pass utf8-encoded filenames. Call stbi_convert_wchar_to_utf8 to convert +// Windows wchar_t filenames to utf8. +// +// =========================================================================== +// +// Philosophy +// +// stb libraries are designed with the following priorities: +// +// 1. easy to use +// 2. easy to maintain +// 3. good performance +// +// Sometimes I let "good performance" creep up in priority over "easy to maintain", +// and for best performance I may provide less-easy-to-use APIs that give higher +// performance, in addition to the easy-to-use ones. Nevertheless, it's important +// to keep in mind that from the standpoint of you, a client of this library, +// all you care about is #1 and #3, and stb libraries DO NOT emphasize #3 above all. +// +// Some secondary priorities arise directly from the first two, some of which +// provide more explicit reasons why performance can't be emphasized. +// +// - Portable ("ease of use") +// - Small source code footprint ("easy to maintain") +// - No dependencies ("ease of use") +// +// =========================================================================== +// +// I/O callbacks +// +// I/O callbacks allow you to read from arbitrary sources, like packaged +// files or some other source. Data read from callbacks are processed +// through a small internal buffer (currently 128 bytes) to try to reduce +// overhead. +// +// The three functions you must define are "read" (reads some bytes of data), +// "skip" (skips some bytes of data), "eof" (reports if the stream is at the end). +// +// =========================================================================== +// +// SIMD support +// +// The JPEG decoder will try to automatically use SIMD kernels on x86 when +// supported by the compiler. For ARM Neon support, you must explicitly +// request it. +// +// (The old do-it-yourself SIMD API is no longer supported in the current +// code.) +// +// On x86, SSE2 will automatically be used when available based on a run-time +// test; if not, the generic C versions are used as a fall-back. On ARM targets, +// the typical path is to have separate builds for NEON and non-NEON devices +// (at least this is true for iOS and Android). Therefore, the NEON support is +// toggled by a build flag: define STBI_NEON to get NEON loops. +// +// If for some reason you do not want to use any of SIMD code, or if +// you have issues compiling it, you can disable it entirely by +// defining STBI_NO_SIMD. +// +// =========================================================================== +// +// HDR image support (disable by defining STBI_NO_HDR) +// +// stb_image supports loading HDR images in general, and currently the Radiance +// .HDR file format specifically. You can still load any file through the existing +// interface; if you attempt to load an HDR file, it will be automatically remapped +// to LDR, assuming gamma 2.2 and an arbitrary scale factor defaulting to 1; +// both of these constants can be reconfigured through this interface: +// +// stbi_hdr_to_ldr_gamma(2.2f); +// stbi_hdr_to_ldr_scale(1.0f); +// +// (note, do not use _inverse_ constants; stbi_image will invert them +// appropriately). +// +// Additionally, there is a new, parallel interface for loading files as +// (linear) floats to preserve the full dynamic range: +// +// float *data = stbi_loadf(filename, &x, &y, &n, 0); +// +// If you load LDR images through this interface, those images will +// be promoted to floating point values, run through the inverse of +// constants corresponding to the above: +// +// stbi_ldr_to_hdr_scale(1.0f); +// stbi_ldr_to_hdr_gamma(2.2f); +// +// Finally, given a filename (or an open file or memory block--see header +// file for details) containing image data, you can query for the "most +// appropriate" interface to use (that is, whether the image is HDR or +// not), using: +// +// stbi_is_hdr(char *filename); +// +// =========================================================================== +// +// iPhone PNG support: +// +// We optionally support converting iPhone-formatted PNGs (which store +// premultiplied BGRA) back to RGB, even though they're internally encoded +// differently. To enable this conversion, call +// stbi_convert_iphone_png_to_rgb(1). +// +// Call stbi_set_unpremultiply_on_load(1) as well to force a divide per +// pixel to remove any premultiplied alpha *only* if the image file explicitly +// says there's premultiplied data (currently only happens in iPhone images, +// and only if iPhone convert-to-rgb processing is on). +// +// =========================================================================== +// +// ADDITIONAL CONFIGURATION +// +// - You can suppress implementation of any of the decoders to reduce +// your code footprint by #defining one or more of the following +// symbols before creating the implementation. +// +// STBI_NO_JPEG +// STBI_NO_PNG +// STBI_NO_BMP +// STBI_NO_PSD +// STBI_NO_TGA +// STBI_NO_GIF +// STBI_NO_HDR +// STBI_NO_PIC +// STBI_NO_PNM (.ppm and .pgm) +// +// - You can request *only* certain decoders and suppress all other ones +// (this will be more forward-compatible, as addition of new decoders +// doesn't require you to disable them explicitly): +// +// STBI_ONLY_JPEG +// STBI_ONLY_PNG +// STBI_ONLY_BMP +// STBI_ONLY_PSD +// STBI_ONLY_TGA +// STBI_ONLY_GIF +// STBI_ONLY_HDR +// STBI_ONLY_PIC +// STBI_ONLY_PNM (.ppm and .pgm) +// +// - If you use STBI_NO_PNG (or _ONLY_ without PNG), and you still +// want the zlib decoder to be available, #define STBI_SUPPORT_ZLIB +// +// - If you define STBI_MAX_DIMENSIONS, stb_image will reject images greater +// than that size (in either width or height) without further processing. +// This is to let programs in the wild set an upper bound to prevent +// denial-of-service attacks on untrusted data, as one could generate a +// valid image of gigantic dimensions and force stb_image to allocate a +// huge block of memory and spend disproportionate time decoding it. By +// default this is set to (1 << 24), which is 16777216, but that's still +// very big. + +#ifndef STBI_NO_STDIO + #include +#endif // STBI_NO_STDIO + +#define STBI_VERSION 1 + +enum { + STBI_default = 0, // only used for desired_channels + + STBI_grey = 1, + STBI_grey_alpha = 2, + STBI_rgb = 3, + STBI_rgb_alpha = 4 +}; + +#include +typedef unsigned char stbi_uc; +typedef unsigned short stbi_us; + +#ifdef __cplusplus +extern "C" { +#endif + +#ifndef STBIDEF +#ifdef STB_IMAGE_STATIC +#define STBIDEF static +#else +#define STBIDEF extern +#endif +#endif + +////////////////////////////////////////////////////////////////////////////// +// +// PRIMARY API - works on images of any type +// + +// +// load image by filename, open file, or memory buffer +// + +typedef struct { + int (*read)(void * user, char * data, + int size); // fill 'data' with 'size' bytes. return number of bytes actually read + void (*skip)(void * user, int + n); // skip the next 'n' bytes, or 'unget' the last -n bytes if negative + int (*eof)(void * user); // returns nonzero if we are at end of file/data +} stbi_io_callbacks; + +//////////////////////////////////// +// +// 8-bits-per-channel interface +// + +STBIDEF stbi_uc * stbi_load_from_memory(stbi_uc const * buffer, int len, int * x, int * y, + int * channels_in_file, int desired_channels); +STBIDEF stbi_uc * stbi_load_from_callbacks(stbi_io_callbacks const * clbk, void * user, int * x, int * y, + int * channels_in_file, int desired_channels); + +#ifndef STBI_NO_STDIO +STBIDEF stbi_uc * stbi_load(char const * filename, int * x, int * y, int * channels_in_file, int desired_channels); +STBIDEF stbi_uc * stbi_load_from_file(FILE * f, int * x, int * y, int * channels_in_file, int desired_channels); +// for stbi_load_from_file, file pointer is left pointing immediately after image +#endif + +#ifndef STBI_NO_GIF +STBIDEF stbi_uc * stbi_load_gif_from_memory(stbi_uc const * buffer, int len, int ** delays, int * x, int * y, int * z, + int * comp, int req_comp); +#endif + +#ifdef STBI_WINDOWS_UTF8 +STBIDEF int stbi_convert_wchar_to_utf8(char * buffer, size_t bufferlen, const wchar_t * input); +#endif + +//////////////////////////////////// +// +// 16-bits-per-channel interface +// + +STBIDEF stbi_us * stbi_load_16_from_memory(stbi_uc const * buffer, int len, int * x, int * y, int * channels_in_file, + int desired_channels); +STBIDEF stbi_us * stbi_load_16_from_callbacks(stbi_io_callbacks const * clbk, void * user, int * x, int * y, + int * channels_in_file, int desired_channels); + +#ifndef STBI_NO_STDIO +STBIDEF stbi_us * stbi_load_16(char const * filename, int * x, int * y, int * channels_in_file, int desired_channels); +STBIDEF stbi_us * stbi_load_from_file_16(FILE * f, int * x, int * y, int * channels_in_file, int desired_channels); +#endif + +//////////////////////////////////// +// +// float-per-channel interface +// +#ifndef STBI_NO_LINEAR +STBIDEF float * stbi_loadf_from_memory(stbi_uc const * buffer, int len, int * x, int * y, int * channels_in_file, + int desired_channels); +STBIDEF float * stbi_loadf_from_callbacks(stbi_io_callbacks const * clbk, void * user, int * x, int * y, + int * channels_in_file, int desired_channels); + +#ifndef STBI_NO_STDIO +STBIDEF float * stbi_loadf(char const * filename, int * x, int * y, int * channels_in_file, int desired_channels); +STBIDEF float * stbi_loadf_from_file(FILE * f, int * x, int * y, int * channels_in_file, int desired_channels); +#endif +#endif + +#ifndef STBI_NO_HDR +STBIDEF void stbi_hdr_to_ldr_gamma(float gamma); +STBIDEF void stbi_hdr_to_ldr_scale(float scale); +#endif // STBI_NO_HDR + +#ifndef STBI_NO_LINEAR +STBIDEF void stbi_ldr_to_hdr_gamma(float gamma); +STBIDEF void stbi_ldr_to_hdr_scale(float scale); +#endif // STBI_NO_LINEAR + +// stbi_is_hdr is always defined, but always returns false if STBI_NO_HDR +STBIDEF int stbi_is_hdr_from_callbacks(stbi_io_callbacks const * clbk, void * user); +STBIDEF int stbi_is_hdr_from_memory(stbi_uc const * buffer, int len); +#ifndef STBI_NO_STDIO +STBIDEF int stbi_is_hdr(char const * filename); +STBIDEF int stbi_is_hdr_from_file(FILE * f); +#endif // STBI_NO_STDIO + + +// get a VERY brief reason for failure +// on most compilers (and ALL modern mainstream compilers) this is threadsafe +STBIDEF const char * stbi_failure_reason(void); + +// free the loaded image -- this is just free() +STBIDEF void stbi_image_free(void * retval_from_stbi_load); + +// get image dimensions & components without fully decoding +STBIDEF int stbi_info_from_memory(stbi_uc const * buffer, int len, int * x, int * y, int * comp); +STBIDEF int stbi_info_from_callbacks(stbi_io_callbacks const * clbk, void * user, int * x, int * y, int * comp); +STBIDEF int stbi_is_16_bit_from_memory(stbi_uc const * buffer, int len); +STBIDEF int stbi_is_16_bit_from_callbacks(stbi_io_callbacks const * clbk, void * user); + +#ifndef STBI_NO_STDIO +STBIDEF int stbi_info(char const * filename, int * x, int * y, int * comp); +STBIDEF int stbi_info_from_file(FILE * f, int * x, int * y, int * comp); +STBIDEF int stbi_is_16_bit(char const * filename); +STBIDEF int stbi_is_16_bit_from_file(FILE * f); +#endif + + + +// for image formats that explicitly notate that they have premultiplied alpha, +// we just return the colors as stored in the file. set this flag to force +// unpremultiplication. results are undefined if the unpremultiply overflow. +STBIDEF void stbi_set_unpremultiply_on_load(int flag_true_if_should_unpremultiply); + +// indicate whether we should process iphone images back to canonical format, +// or just pass them through "as-is" +STBIDEF void stbi_convert_iphone_png_to_rgb(int flag_true_if_should_convert); + +// flip the image vertically, so the first pixel in the output array is the bottom left +STBIDEF void stbi_set_flip_vertically_on_load(int flag_true_if_should_flip); + +// as above, but only applies to images loaded on the thread that calls the function +// this function is only available if your compiler supports thread-local variables; +// calling it will fail to link if your compiler doesn't +STBIDEF void stbi_set_unpremultiply_on_load_thread(int flag_true_if_should_unpremultiply); +STBIDEF void stbi_convert_iphone_png_to_rgb_thread(int flag_true_if_should_convert); +STBIDEF void stbi_set_flip_vertically_on_load_thread(int flag_true_if_should_flip); + +// ZLIB client - used by PNG, available for other purposes + +STBIDEF char * stbi_zlib_decode_malloc_guesssize(const char * buffer, int len, int initial_size, int * outlen); +STBIDEF char * stbi_zlib_decode_malloc_guesssize_headerflag(const char * buffer, int len, int initial_size, + int * outlen, int parse_header); +STBIDEF char * stbi_zlib_decode_malloc(const char * buffer, int len, int * outlen); +STBIDEF int stbi_zlib_decode_buffer(char * obuffer, int olen, const char * ibuffer, int ilen); + +STBIDEF char * stbi_zlib_decode_noheader_malloc(const char * buffer, int len, int * outlen); +STBIDEF int stbi_zlib_decode_noheader_buffer(char * obuffer, int olen, const char * ibuffer, int ilen); + + +#ifdef __cplusplus +} +#endif + +// +// +//// end header file ///////////////////////////////////////////////////// +#endif // STBI_INCLUDE_STB_IMAGE_H + +#ifdef STB_IMAGE_IMPLEMENTATION + +#if defined(STBI_ONLY_JPEG) || defined(STBI_ONLY_PNG) || defined(STBI_ONLY_BMP) \ + || defined(STBI_ONLY_TGA) || defined(STBI_ONLY_GIF) || defined(STBI_ONLY_PSD) \ + || defined(STBI_ONLY_HDR) || defined(STBI_ONLY_PIC) || defined(STBI_ONLY_PNM) \ + || defined(STBI_ONLY_ZLIB) + #ifndef STBI_ONLY_JPEG + #define STBI_NO_JPEG + #endif + #ifndef STBI_ONLY_PNG + #define STBI_NO_PNG + #endif + #ifndef STBI_ONLY_BMP + #define STBI_NO_BMP + #endif + #ifndef STBI_ONLY_PSD + #define STBI_NO_PSD + #endif + #ifndef STBI_ONLY_TGA + #define STBI_NO_TGA + #endif + #ifndef STBI_ONLY_GIF + #define STBI_NO_GIF + #endif + #ifndef STBI_ONLY_HDR + #define STBI_NO_HDR + #endif + #ifndef STBI_ONLY_PIC + #define STBI_NO_PIC + #endif + #ifndef STBI_ONLY_PNM + #define STBI_NO_PNM + #endif +#endif + +#if defined(STBI_NO_PNG) && !defined(STBI_SUPPORT_ZLIB) && !defined(STBI_NO_ZLIB) + #define STBI_NO_ZLIB +#endif + + +#include +#include // ptrdiff_t on osx +#include +#include +#include + +#if !defined(STBI_NO_LINEAR) || !defined(STBI_NO_HDR) + #include // ldexp, pow +#endif + +#ifndef STBI_NO_STDIO + #include +#endif + +#ifndef STBI_ASSERT + #include + #define STBI_ASSERT(x) assert(x) +#endif + +#ifdef __cplusplus + #define STBI_EXTERN extern "C" +#else + #define STBI_EXTERN extern +#endif + + +#ifndef _MSC_VER + #ifdef __cplusplus + #define stbi_inline inline + #else + #define stbi_inline + #endif +#else + #define stbi_inline __forceinline +#endif + +#ifndef STBI_NO_THREAD_LOCALS + #if defined(__cplusplus) && __cplusplus >= 201103L + #define STBI_THREAD_LOCAL thread_local + #elif defined(__GNUC__) && __GNUC__ < 5 + #define STBI_THREAD_LOCAL __thread + #elif defined(_MSC_VER) + #define STBI_THREAD_LOCAL __declspec(thread) + #elif defined (__STDC_VERSION__) && __STDC_VERSION__ >= 201112L && !defined(__STDC_NO_THREADS__) + #define STBI_THREAD_LOCAL _Thread_local + #endif + + #ifndef STBI_THREAD_LOCAL + #if defined(__GNUC__) + #define STBI_THREAD_LOCAL __thread + #endif + #endif +#endif + +#if defined(_MSC_VER) || defined(__SYMBIAN32__) + typedef unsigned short stbi__uint16; + typedef signed short stbi__int16; + typedef unsigned int stbi__uint32; + typedef signed int stbi__int32; +#else + #include + typedef uint16_t stbi__uint16; + typedef int16_t stbi__int16; + typedef uint32_t stbi__uint32; + typedef int32_t stbi__int32; +#endif + +// should produce compiler error if size is wrong +typedef unsigned char validate_uint32[sizeof(stbi__uint32) == 4 ? 1 : -1]; + +#ifdef _MSC_VER + #define STBI_NOTUSED(v) (void)(v) +#else + #define STBI_NOTUSED(v) (void)sizeof(v) +#endif + +#ifdef _MSC_VER + #define STBI_HAS_LROTL +#endif + +#ifdef STBI_HAS_LROTL + #define stbi_lrot(x,y) _lrotl(x,y) +#else + #define stbi_lrot(x,y) (((x) << (y)) | ((x) >> (-(y) & 31))) +#endif + +#if defined(STBI_MALLOC) && defined(STBI_FREE) && (defined(STBI_REALLOC) || defined(STBI_REALLOC_SIZED)) + // ok +#elif !defined(STBI_MALLOC) && !defined(STBI_FREE) && !defined(STBI_REALLOC) && !defined(STBI_REALLOC_SIZED) + // ok +#else + #error "Must define all or none of STBI_MALLOC, STBI_FREE, and STBI_REALLOC (or STBI_REALLOC_SIZED)." +#endif + +#ifndef STBI_MALLOC + #define STBI_MALLOC(sz) malloc(sz) + #define STBI_REALLOC(p,newsz) realloc(p,newsz) + #define STBI_FREE(p) free(p) +#endif + +#ifndef STBI_REALLOC_SIZED + #define STBI_REALLOC_SIZED(p,oldsz,newsz) STBI_REALLOC(p,newsz) +#endif + +// x86/x64 detection +#if defined(__x86_64__) || defined(_M_X64) + #define STBI__X64_TARGET +#elif defined(__i386) || defined(_M_IX86) + #define STBI__X86_TARGET +#endif + +#if defined(__GNUC__) && defined(STBI__X86_TARGET) && !defined(__SSE2__) && !defined(STBI_NO_SIMD) + // gcc doesn't support sse2 intrinsics unless you compile with -msse2, + // which in turn means it gets to use SSE2 everywhere. This is unfortunate, + // but previous attempts to provide the SSE2 functions with runtime + // detection caused numerous issues. The way architecture extensions are + // exposed in GCC/Clang is, sadly, not really suited for one-file libs. + // New behavior: if compiled with -msse2, we use SSE2 without any + // detection; if not, we don't use it at all. + #define STBI_NO_SIMD +#endif + +#if defined(__MINGW32__) && defined(STBI__X86_TARGET) && !defined(STBI_MINGW_ENABLE_SSE2) && !defined(STBI_NO_SIMD) + // Note that __MINGW32__ doesn't actually mean 32-bit, so we have to avoid STBI__X64_TARGET + // + // 32-bit MinGW wants ESP to be 16-byte aligned, but this is not in the + // Windows ABI and VC++ as well as Windows DLLs don't maintain that invariant. + // As a result, enabling SSE2 on 32-bit MinGW is dangerous when not + // simultaneously enabling "-mstackrealign". + // + // See https://github.com/nothings/stb/issues/81 for more information. + // + // So default to no SSE2 on 32-bit MinGW. If you've read this far and added + // -mstackrealign to your build settings, feel free to #define STBI_MINGW_ENABLE_SSE2. + #define STBI_NO_SIMD +#endif + +#if !defined(STBI_NO_SIMD) && (defined(STBI__X86_TARGET) || defined(STBI__X64_TARGET)) +#define STBI_SSE2 +#include + +#ifdef _MSC_VER + +#if _MSC_VER >= 1400 // not VC6 +#include // __cpuid +static int stbi__cpuid3(void) +{ + int info[4]; + __cpuid(info, 1); + return info[3]; +} +#else +static int stbi__cpuid3(void) +{ + int res; + __asm { + mov eax, 1 + cpuid + mov res, edx + } + return res; +} +#endif + +#define STBI_SIMD_ALIGN(type, name) __declspec(align(16)) type name + +#if !defined(STBI_NO_JPEG) && defined(STBI_SSE2) +static int stbi__sse2_available(void) +{ + int info3 = stbi__cpuid3(); + return ((info3 >> 26) & 1) != 0; +} +#endif + +#else // assume GCC-style if not VC++ +#define STBI_SIMD_ALIGN(type, name) type name __attribute__((aligned(16))) + +#if !defined(STBI_NO_JPEG) && defined(STBI_SSE2) +static int stbi__sse2_available(void) +{ + // If we're even attempting to compile this on GCC/Clang, that means + // -msse2 is on, which means the compiler is allowed to use SSE2 + // instructions at will, and so are we. + return 1; +} +#endif + +#endif +#endif + +// ARM NEON +#if defined(STBI_NO_SIMD) && defined(STBI_NEON) + #undef STBI_NEON +#endif + +#ifdef STBI_NEON + #include + #ifdef _MSC_VER + #define STBI_SIMD_ALIGN(type, name) __declspec(align(16)) type name + #else + #define STBI_SIMD_ALIGN(type, name) type name __attribute__((aligned(16))) + #endif +#endif + +#ifndef STBI_SIMD_ALIGN + #define STBI_SIMD_ALIGN(type, name) type name +#endif + +#ifndef STBI_MAX_DIMENSIONS + #define STBI_MAX_DIMENSIONS (1 << 24) +#endif + +/////////////////////////////////////////////// +// +// stbi__context struct and start_xxx functions + +// stbi__context structure is our basic context used by all images, so it +// contains all the IO context, plus some basic image information +typedef struct { + stbi__uint32 img_x, img_y; + int img_n, img_out_n; + + stbi_io_callbacks io; + void * io_user_data; + + int read_from_callbacks; + int buflen; + stbi_uc buffer_start[128]; + int callback_already_read; + + stbi_uc * img_buffer, * img_buffer_end; + stbi_uc * img_buffer_original, * img_buffer_original_end; +} stbi__context; + + +static void stbi__refill_buffer(stbi__context * s); + +// initialize a memory-decode context +static void stbi__start_mem(stbi__context * s, stbi_uc const * buffer, int len) +{ + s->io.read = NULL; + s->read_from_callbacks = 0; + s->callback_already_read = 0; + s->img_buffer = s->img_buffer_original = (stbi_uc *) buffer; + s->img_buffer_end = s->img_buffer_original_end = (stbi_uc *) buffer + len; +} + +// initialize a callback-based context +static void stbi__start_callbacks(stbi__context * s, stbi_io_callbacks * c, void * user) +{ + s->io = *c; + s->io_user_data = user; + s->buflen = sizeof(s->buffer_start); + s->read_from_callbacks = 1; + s->callback_already_read = 0; + s->img_buffer = s->img_buffer_original = s->buffer_start; + stbi__refill_buffer(s); + s->img_buffer_original_end = s->img_buffer_end; +} + +#ifndef STBI_NO_STDIO + +static int stbi__stdio_read(void * user, char * data, int size) +{ + return (int) fread(data, 1, size, (FILE *) user); +} + +static void stbi__stdio_skip(void * user, int n) +{ + int ch; + fseek((FILE *) user, n, SEEK_CUR); + ch = fgetc((FILE *) user); /* have to read a byte to reset feof()'s flag */ + if(ch != EOF) { + ungetc(ch, (FILE *) user); /* push byte back onto stream if valid. */ + } +} + +static int stbi__stdio_eof(void * user) +{ + return feof((FILE *) user) || ferror((FILE *) user); +} + +static stbi_io_callbacks stbi__stdio_callbacks = { + stbi__stdio_read, + stbi__stdio_skip, + stbi__stdio_eof, +}; + +static void stbi__start_file(stbi__context * s, FILE * f) +{ + stbi__start_callbacks(s, &stbi__stdio_callbacks, (void *) f); +} + +//static void stop_file(stbi__context *s) { } + +#endif // !STBI_NO_STDIO + +static void stbi__rewind(stbi__context * s) +{ + // conceptually rewind SHOULD rewind to the beginning of the stream, + // but we just rewind to the beginning of the initial buffer, because + // we only use it after doing 'test', which only ever looks at at most 92 bytes + s->img_buffer = s->img_buffer_original; + s->img_buffer_end = s->img_buffer_original_end; +} + +enum { + STBI_ORDER_RGB, + STBI_ORDER_BGR +}; + +typedef struct { + int bits_per_channel; + int num_channels; + int channel_order; +} stbi__result_info; + +#ifndef STBI_NO_JPEG + static int stbi__jpeg_test(stbi__context * s); + static void * stbi__jpeg_load(stbi__context * s, int * x, int * y, int * comp, int req_comp, stbi__result_info * ri); + static int stbi__jpeg_info(stbi__context * s, int * x, int * y, int * comp); +#endif + +#ifndef STBI_NO_PNG + static int stbi__png_test(stbi__context * s); + static void * stbi__png_load(stbi__context * s, int * x, int * y, int * comp, int req_comp, stbi__result_info * ri); + static int stbi__png_info(stbi__context * s, int * x, int * y, int * comp); + static int stbi__png_is16(stbi__context * s); +#endif + +#ifndef STBI_NO_BMP + static int stbi__bmp_test(stbi__context * s); + static void * stbi__bmp_load(stbi__context * s, int * x, int * y, int * comp, int req_comp, stbi__result_info * ri); + static int stbi__bmp_info(stbi__context * s, int * x, int * y, int * comp); +#endif + +#ifndef STBI_NO_TGA + static int stbi__tga_test(stbi__context * s); + static void * stbi__tga_load(stbi__context * s, int * x, int * y, int * comp, int req_comp, stbi__result_info * ri); + static int stbi__tga_info(stbi__context * s, int * x, int * y, int * comp); +#endif + +#ifndef STBI_NO_PSD +static int stbi__psd_test(stbi__context * s); +static void * stbi__psd_load(stbi__context * s, int * x, int * y, int * comp, int req_comp, stbi__result_info * ri, + int bpc); +static int stbi__psd_info(stbi__context * s, int * x, int * y, int * comp); +static int stbi__psd_is16(stbi__context * s); +#endif + +#ifndef STBI_NO_HDR + static int stbi__hdr_test(stbi__context * s); + static float * stbi__hdr_load(stbi__context * s, int * x, int * y, int * comp, int req_comp, stbi__result_info * ri); + static int stbi__hdr_info(stbi__context * s, int * x, int * y, int * comp); +#endif + +#ifndef STBI_NO_PIC + static int stbi__pic_test(stbi__context * s); + static void * stbi__pic_load(stbi__context * s, int * x, int * y, int * comp, int req_comp, stbi__result_info * ri); + static int stbi__pic_info(stbi__context * s, int * x, int * y, int * comp); +#endif + +#ifndef STBI_NO_GIF +static int stbi__gif_test(stbi__context * s); +static void * stbi__gif_load(stbi__context * s, int * x, int * y, int * comp, int req_comp, stbi__result_info * ri); +static void * stbi__load_gif_main(stbi__context * s, int ** delays, int * x, int * y, int * z, int * comp, + int req_comp); +static int stbi__gif_info(stbi__context * s, int * x, int * y, int * comp); +#endif + +#ifndef STBI_NO_PNM + static int stbi__pnm_test(stbi__context * s); + static void * stbi__pnm_load(stbi__context * s, int * x, int * y, int * comp, int req_comp, stbi__result_info * ri); + static int stbi__pnm_info(stbi__context * s, int * x, int * y, int * comp); + static int stbi__pnm_is16(stbi__context * s); +#endif + +static +#ifdef STBI_THREAD_LOCAL + STBI_THREAD_LOCAL +#endif +const char * stbi__g_failure_reason; + +STBIDEF const char * stbi_failure_reason(void) +{ + return stbi__g_failure_reason; +} + +#ifndef STBI_NO_FAILURE_STRINGS +static int stbi__err(const char * str) +{ + stbi__g_failure_reason = str; + return 0; +} +#endif + +static void * stbi__malloc(size_t size) +{ + return STBI_MALLOC(size); +} + +// stb_image uses ints pervasively, including for offset calculations. +// therefore the largest decoded image size we can support with the +// current code, even on 64-bit targets, is INT_MAX. this is not a +// significant limitation for the intended use case. +// +// we do, however, need to make sure our size calculations don't +// overflow. hence a few helper functions for size calculations that +// multiply integers together, making sure that they're non-negative +// and no overflow occurs. + +// return 1 if the sum is valid, 0 on overflow. +// negative terms are considered invalid. +static int stbi__addsizes_valid(int a, int b) +{ + if(b < 0) return 0; + // now 0 <= b <= INT_MAX, hence also + // 0 <= INT_MAX - b <= INTMAX. + // And "a + b <= INT_MAX" (which might overflow) is the + // same as a <= INT_MAX - b (no overflow) + return a <= INT_MAX - b; +} + +// returns 1 if the product is valid, 0 on overflow. +// negative factors are considered invalid. +static int stbi__mul2sizes_valid(int a, int b) +{ + if(a < 0 || b < 0) return 0; + if(b == 0) return 1; // mul-by-0 is always safe + // portable way to check for no overflows in a*b + return a <= INT_MAX / b; +} + +#if !defined(STBI_NO_JPEG) || !defined(STBI_NO_PNG) || !defined(STBI_NO_TGA) || !defined(STBI_NO_HDR) +// returns 1 if "a*b + add" has no negative terms/factors and doesn't overflow +static int stbi__mad2sizes_valid(int a, int b, int add) +{ + return stbi__mul2sizes_valid(a, b) && stbi__addsizes_valid(a * b, add); +} +#endif + +// returns 1 if "a*b*c + add" has no negative terms/factors and doesn't overflow +static int stbi__mad3sizes_valid(int a, int b, int c, int add) +{ + return stbi__mul2sizes_valid(a, b) && stbi__mul2sizes_valid(a * b, c) && + stbi__addsizes_valid(a * b * c, add); +} + +// returns 1 if "a*b*c*d + add" has no negative terms/factors and doesn't overflow +#if !defined(STBI_NO_LINEAR) || !defined(STBI_NO_HDR) || !defined(STBI_NO_PNM) +static int stbi__mad4sizes_valid(int a, int b, int c, int d, int add) +{ + return stbi__mul2sizes_valid(a, b) && stbi__mul2sizes_valid(a * b, c) && + stbi__mul2sizes_valid(a * b * c, d) && stbi__addsizes_valid(a * b * c * d, add); +} +#endif + +#if !defined(STBI_NO_JPEG) || !defined(STBI_NO_PNG) || !defined(STBI_NO_TGA) || !defined(STBI_NO_HDR) +// mallocs with size overflow checking +static void * stbi__malloc_mad2(int a, int b, int add) +{ + if(!stbi__mad2sizes_valid(a, b, add)) return NULL; + return stbi__malloc(a * b + add); +} +#endif + +static void * stbi__malloc_mad3(int a, int b, int c, int add) +{ + if(!stbi__mad3sizes_valid(a, b, c, add)) return NULL; + return stbi__malloc(a * b * c + add); +} + +#if !defined(STBI_NO_LINEAR) || !defined(STBI_NO_HDR) || !defined(STBI_NO_PNM) +static void * stbi__malloc_mad4(int a, int b, int c, int d, int add) +{ + if(!stbi__mad4sizes_valid(a, b, c, d, add)) return NULL; + return stbi__malloc(a * b * c * d + add); +} +#endif + +// returns 1 if the sum of two signed ints is valid (between -2^31 and 2^31-1 inclusive), 0 on overflow. +static int stbi__addints_valid(int a, int b) +{ + if((a >= 0) != (b >= 0)) return 1; // a and b have different signs, so no overflow + if(a < 0 && b < 0) return a >= INT_MIN - b; // same as a + b >= INT_MIN; INT_MIN - b cannot overflow since b < 0. + return a <= INT_MAX - b; +} + +// returns 1 if the product of two ints fits in a signed short, 0 on overflow. +static int stbi__mul2shorts_valid(int a, int b) +{ + if(b == 0 || b == -1) return 1; // multiplication by 0 is always 0; check for -1 so SHRT_MIN/b doesn't overflow + if((a >= 0) == (b >= 0)) return a <= SHRT_MAX / b; // product is positive, so similar to mul2sizes_valid + if(b < 0) return a <= SHRT_MIN / b; // same as a * b >= SHRT_MIN + return a >= SHRT_MIN / b; +} + +// stbi__err - error +// stbi__errpf - error returning pointer to float +// stbi__errpuc - error returning pointer to unsigned char + +#ifdef STBI_NO_FAILURE_STRINGS + #define stbi__err(x,y) 0 +#elif defined(STBI_FAILURE_USERMSG) + #define stbi__err(x,y) stbi__err(y) +#else + #define stbi__err(x,y) stbi__err(x) +#endif + +#define stbi__errpf(x,y) ((float *)(size_t) (stbi__err(x,y)?NULL:NULL)) +#define stbi__errpuc(x,y) ((unsigned char *)(size_t) (stbi__err(x,y)?NULL:NULL)) + +STBIDEF void stbi_image_free(void * retval_from_stbi_load) +{ + STBI_FREE(retval_from_stbi_load); +} + +#ifndef STBI_NO_LINEAR + static float * stbi__ldr_to_hdr(stbi_uc * data, int x, int y, int comp); +#endif + +#ifndef STBI_NO_HDR + static stbi_uc * stbi__hdr_to_ldr(float * data, int x, int y, int comp); +#endif + +static int stbi__vertically_flip_on_load_global = 0; + +STBIDEF void stbi_set_flip_vertically_on_load(int flag_true_if_should_flip) +{ + stbi__vertically_flip_on_load_global = flag_true_if_should_flip; +} + +#ifndef STBI_THREAD_LOCAL +#define stbi__vertically_flip_on_load stbi__vertically_flip_on_load_global +#else +static STBI_THREAD_LOCAL int stbi__vertically_flip_on_load_local, stbi__vertically_flip_on_load_set; + +STBIDEF void stbi_set_flip_vertically_on_load_thread(int flag_true_if_should_flip) +{ + stbi__vertically_flip_on_load_local = flag_true_if_should_flip; + stbi__vertically_flip_on_load_set = 1; +} + +#define stbi__vertically_flip_on_load (stbi__vertically_flip_on_load_set \ + ? stbi__vertically_flip_on_load_local \ + : stbi__vertically_flip_on_load_global) +#endif // STBI_THREAD_LOCAL + +static void * stbi__load_main(stbi__context * s, int * x, int * y, int * comp, int req_comp, stbi__result_info * ri, + int bpc) +{ + memset(ri, 0, sizeof(*ri)); // make sure it's initialized if we add new fields + ri->bits_per_channel = 8; // default is 8 so most paths don't have to be changed + ri->channel_order = STBI_ORDER_RGB; // all current input & output are this, but this is here so we can add BGR order + ri->num_channels = 0; + + // test the formats with a very explicit header first (at least a FOURCC + // or distinctive magic number first) +#ifndef STBI_NO_PNG + if(stbi__png_test(s)) return stbi__png_load(s, x, y, comp, req_comp, ri); +#endif +#ifndef STBI_NO_BMP + if(stbi__bmp_test(s)) return stbi__bmp_load(s, x, y, comp, req_comp, ri); +#endif +#ifndef STBI_NO_GIF + if(stbi__gif_test(s)) return stbi__gif_load(s, x, y, comp, req_comp, ri); +#endif +#ifndef STBI_NO_PSD + if(stbi__psd_test(s)) return stbi__psd_load(s, x, y, comp, req_comp, ri, bpc); +#else + STBI_NOTUSED(bpc); +#endif +#ifndef STBI_NO_PIC + if(stbi__pic_test(s)) return stbi__pic_load(s, x, y, comp, req_comp, ri); +#endif + + // then the formats that can end up attempting to load with just 1 or 2 + // bytes matching expectations; these are prone to false positives, so + // try them later +#ifndef STBI_NO_JPEG + if(stbi__jpeg_test(s)) return stbi__jpeg_load(s, x, y, comp, req_comp, ri); +#endif +#ifndef STBI_NO_PNM + if(stbi__pnm_test(s)) return stbi__pnm_load(s, x, y, comp, req_comp, ri); +#endif + +#ifndef STBI_NO_HDR + if(stbi__hdr_test(s)) { + float * hdr = stbi__hdr_load(s, x, y, comp, req_comp, ri); + return stbi__hdr_to_ldr(hdr, *x, *y, req_comp ? req_comp : *comp); + } +#endif + +#ifndef STBI_NO_TGA + // test tga last because it's a crappy test! + if(stbi__tga_test(s)) + return stbi__tga_load(s, x, y, comp, req_comp, ri); +#endif + + return stbi__errpuc("unknown image type", "Image not of any known type, or corrupt"); +} + +static stbi_uc * stbi__convert_16_to_8(stbi__uint16 * orig, int w, int h, int channels) +{ + int i; + int img_len = w * h * channels; + stbi_uc * reduced; + + reduced = (stbi_uc *) stbi__malloc(img_len); + if(reduced == NULL) return stbi__errpuc("outofmem", "Out of memory"); + + for(i = 0; i < img_len; ++i) + reduced[i] = (stbi_uc)((orig[i] >> 8) & 0xFF); // top half of each byte is sufficient approx of 16->8 bit scaling + + STBI_FREE(orig); + return reduced; +} + +static stbi__uint16 * stbi__convert_8_to_16(stbi_uc * orig, int w, int h, int channels) +{ + int i; + int img_len = w * h * channels; + stbi__uint16 * enlarged; + + enlarged = (stbi__uint16 *) stbi__malloc(img_len * 2); + if(enlarged == NULL) return (stbi__uint16 *) stbi__errpuc("outofmem", "Out of memory"); + + for(i = 0; i < img_len; ++i) + enlarged[i] = (stbi__uint16)((orig[i] << 8) + orig[i]); // replicate to high and low byte, maps 0->0, 255->0xffff + + STBI_FREE(orig); + return enlarged; +} + +static void stbi__vertical_flip(void * image, int w, int h, int bytes_per_pixel) +{ + int row; + size_t bytes_per_row = (size_t)w * bytes_per_pixel; + stbi_uc temp[2048]; + stbi_uc * bytes = (stbi_uc *)image; + + for(row = 0; row < (h >> 1); row++) { + stbi_uc * row0 = bytes + row * bytes_per_row; + stbi_uc * row1 = bytes + (h - row - 1) * bytes_per_row; + // swap row0 with row1 + size_t bytes_left = bytes_per_row; + while(bytes_left) { + size_t bytes_copy = (bytes_left < sizeof(temp)) ? bytes_left : sizeof(temp); + memcpy(temp, row0, bytes_copy); + memcpy(row0, row1, bytes_copy); + memcpy(row1, temp, bytes_copy); + row0 += bytes_copy; + row1 += bytes_copy; + bytes_left -= bytes_copy; + } + } +} + +#ifndef STBI_NO_GIF +static void stbi__vertical_flip_slices(void * image, int w, int h, int z, int bytes_per_pixel) +{ + int slice; + int slice_size = w * h * bytes_per_pixel; + + stbi_uc * bytes = (stbi_uc *)image; + for(slice = 0; slice < z; ++slice) { + stbi__vertical_flip(bytes, w, h, bytes_per_pixel); + bytes += slice_size; + } +} +#endif + +static unsigned char * stbi__load_and_postprocess_8bit(stbi__context * s, int * x, int * y, int * comp, int req_comp) +{ + stbi__result_info ri; + void * result = stbi__load_main(s, x, y, comp, req_comp, &ri, 8); + + if(result == NULL) + return NULL; + + // it is the responsibility of the loaders to make sure we get either 8 or 16 bit. + STBI_ASSERT(ri.bits_per_channel == 8 || ri.bits_per_channel == 16); + + if(ri.bits_per_channel != 8) { + result = stbi__convert_16_to_8((stbi__uint16 *) result, *x, *y, req_comp == 0 ? *comp : req_comp); + ri.bits_per_channel = 8; + } + + // @TODO: move stbi__convert_format to here + + if(stbi__vertically_flip_on_load) { + int channels = req_comp ? req_comp : *comp; + stbi__vertical_flip(result, *x, *y, channels * sizeof(stbi_uc)); + } + + return (unsigned char *) result; +} + +static stbi__uint16 * stbi__load_and_postprocess_16bit(stbi__context * s, int * x, int * y, int * comp, int req_comp) +{ + stbi__result_info ri; + void * result = stbi__load_main(s, x, y, comp, req_comp, &ri, 16); + + if(result == NULL) + return NULL; + + // it is the responsibility of the loaders to make sure we get either 8 or 16 bit. + STBI_ASSERT(ri.bits_per_channel == 8 || ri.bits_per_channel == 16); + + if(ri.bits_per_channel != 16) { + result = stbi__convert_8_to_16((stbi_uc *) result, *x, *y, req_comp == 0 ? *comp : req_comp); + ri.bits_per_channel = 16; + } + + // @TODO: move stbi__convert_format16 to here + // @TODO: special case RGB-to-Y (and RGBA-to-YA) for 8-bit-to-16-bit case to keep more precision + + if(stbi__vertically_flip_on_load) { + int channels = req_comp ? req_comp : *comp; + stbi__vertical_flip(result, *x, *y, channels * sizeof(stbi__uint16)); + } + + return (stbi__uint16 *) result; +} + +#if !defined(STBI_NO_HDR) && !defined(STBI_NO_LINEAR) +static void stbi__float_postprocess(float * result, int * x, int * y, int * comp, int req_comp) +{ + if(stbi__vertically_flip_on_load && result != NULL) { + int channels = req_comp ? req_comp : *comp; + stbi__vertical_flip(result, *x, *y, channels * sizeof(float)); + } +} +#endif + +#ifndef STBI_NO_STDIO + +#if defined(_WIN32) && defined(STBI_WINDOWS_UTF8) +STBI_EXTERN __declspec(dllimport) int __stdcall MultiByteToWideChar(unsigned int cp, unsigned long flags, + const char * str, int cbmb, wchar_t * widestr, int cchwide); +STBI_EXTERN __declspec(dllimport) int __stdcall WideCharToMultiByte(unsigned int cp, unsigned long flags, + const wchar_t * widestr, int cchwide, char * str, int cbmb, const char * defchar, int * used_default); +#endif + +#if defined(_WIN32) && defined(STBI_WINDOWS_UTF8) +STBIDEF int stbi_convert_wchar_to_utf8(char * buffer, size_t bufferlen, const wchar_t * input) +{ + return WideCharToMultiByte(65001 /* UTF8 */, 0, input, -1, buffer, (int) bufferlen, NULL, NULL); +} +#endif + +static FILE * stbi__fopen(char const * filename, char const * mode) +{ + FILE * f; +#if defined(_WIN32) && defined(STBI_WINDOWS_UTF8) + wchar_t wMode[64]; + wchar_t wFilename[1024]; + if(0 == MultiByteToWideChar(65001 /* UTF8 */, 0, filename, -1, wFilename, sizeof(wFilename) / sizeof(*wFilename))) + return 0; + + if(0 == MultiByteToWideChar(65001 /* UTF8 */, 0, mode, -1, wMode, sizeof(wMode) / sizeof(*wMode))) + return 0; + +#if defined(_MSC_VER) && _MSC_VER >= 1400 + if(0 != _wfopen_s(&f, wFilename, wMode)) + f = 0; +#else + f = _wfopen(wFilename, wMode); +#endif + +#elif defined(_MSC_VER) && _MSC_VER >= 1400 + if(0 != fopen_s(&f, filename, mode)) + f = 0; +#else + f = fopen(filename, mode); +#endif + return f; +} + + +STBIDEF stbi_uc * stbi_load(char const * filename, int * x, int * y, int * comp, int req_comp) +{ + FILE * f = stbi__fopen(filename, "rb"); + unsigned char * result; + if(!f) return stbi__errpuc("can't fopen", "Unable to open file"); + result = stbi_load_from_file(f, x, y, comp, req_comp); + fclose(f); + return result; +} + +STBIDEF stbi_uc * stbi_load_from_file(FILE * f, int * x, int * y, int * comp, int req_comp) +{ + unsigned char * result; + stbi__context s; + stbi__start_file(&s, f); + result = stbi__load_and_postprocess_8bit(&s, x, y, comp, req_comp); + if(result) { + // need to 'unget' all the characters in the IO buffer + fseek(f, - (int)(s.img_buffer_end - s.img_buffer), SEEK_CUR); + } + return result; +} + +STBIDEF stbi__uint16 * stbi_load_from_file_16(FILE * f, int * x, int * y, int * comp, int req_comp) +{ + stbi__uint16 * result; + stbi__context s; + stbi__start_file(&s, f); + result = stbi__load_and_postprocess_16bit(&s, x, y, comp, req_comp); + if(result) { + // need to 'unget' all the characters in the IO buffer + fseek(f, - (int)(s.img_buffer_end - s.img_buffer), SEEK_CUR); + } + return result; +} + +STBIDEF stbi_us * stbi_load_16(char const * filename, int * x, int * y, int * comp, int req_comp) +{ + FILE * f = stbi__fopen(filename, "rb"); + stbi__uint16 * result; + if(!f) return (stbi_us *) stbi__errpuc("can't fopen", "Unable to open file"); + result = stbi_load_from_file_16(f, x, y, comp, req_comp); + fclose(f); + return result; +} + + +#endif //!STBI_NO_STDIO + +STBIDEF stbi_us * stbi_load_16_from_memory(stbi_uc const * buffer, int len, int * x, int * y, int * channels_in_file, + int desired_channels) +{ + stbi__context s; + stbi__start_mem(&s, buffer, len); + return stbi__load_and_postprocess_16bit(&s, x, y, channels_in_file, desired_channels); +} + +STBIDEF stbi_us * stbi_load_16_from_callbacks(stbi_io_callbacks const * clbk, void * user, int * x, int * y, + int * channels_in_file, int desired_channels) +{ + stbi__context s; + stbi__start_callbacks(&s, (stbi_io_callbacks *)clbk, user); + return stbi__load_and_postprocess_16bit(&s, x, y, channels_in_file, desired_channels); +} + +STBIDEF stbi_uc * stbi_load_from_memory(stbi_uc const * buffer, int len, int * x, int * y, int * comp, int req_comp) +{ + stbi__context s; + stbi__start_mem(&s, buffer, len); + return stbi__load_and_postprocess_8bit(&s, x, y, comp, req_comp); +} + +STBIDEF stbi_uc * stbi_load_from_callbacks(stbi_io_callbacks const * clbk, void * user, int * x, int * y, int * comp, + int req_comp) +{ + stbi__context s; + stbi__start_callbacks(&s, (stbi_io_callbacks *) clbk, user); + return stbi__load_and_postprocess_8bit(&s, x, y, comp, req_comp); +} + +#ifndef STBI_NO_GIF +STBIDEF stbi_uc * stbi_load_gif_from_memory(stbi_uc const * buffer, int len, int ** delays, int * x, int * y, int * z, + int * comp, int req_comp) +{ + unsigned char * result; + stbi__context s; + stbi__start_mem(&s, buffer, len); + + result = (unsigned char *) stbi__load_gif_main(&s, delays, x, y, z, comp, req_comp); + if(stbi__vertically_flip_on_load) { + stbi__vertical_flip_slices(result, *x, *y, *z, *comp); + } + + return result; +} +#endif + +#ifndef STBI_NO_LINEAR +static float * stbi__loadf_main(stbi__context * s, int * x, int * y, int * comp, int req_comp) +{ + unsigned char * data; +#ifndef STBI_NO_HDR + if(stbi__hdr_test(s)) { + stbi__result_info ri; + float * hdr_data = stbi__hdr_load(s, x, y, comp, req_comp, &ri); + if(hdr_data) + stbi__float_postprocess(hdr_data, x, y, comp, req_comp); + return hdr_data; + } +#endif + data = stbi__load_and_postprocess_8bit(s, x, y, comp, req_comp); + if(data) + return stbi__ldr_to_hdr(data, *x, *y, req_comp ? req_comp : *comp); + return stbi__errpf("unknown image type", "Image not of any known type, or corrupt"); +} + +STBIDEF float * stbi_loadf_from_memory(stbi_uc const * buffer, int len, int * x, int * y, int * comp, int req_comp) +{ + stbi__context s; + stbi__start_mem(&s, buffer, len); + return stbi__loadf_main(&s, x, y, comp, req_comp); +} + +STBIDEF float * stbi_loadf_from_callbacks(stbi_io_callbacks const * clbk, void * user, int * x, int * y, int * comp, + int req_comp) +{ + stbi__context s; + stbi__start_callbacks(&s, (stbi_io_callbacks *) clbk, user); + return stbi__loadf_main(&s, x, y, comp, req_comp); +} + +#ifndef STBI_NO_STDIO +STBIDEF float * stbi_loadf(char const * filename, int * x, int * y, int * comp, int req_comp) +{ + float * result; + FILE * f = stbi__fopen(filename, "rb"); + if(!f) return stbi__errpf("can't fopen", "Unable to open file"); + result = stbi_loadf_from_file(f, x, y, comp, req_comp); + fclose(f); + return result; +} + +STBIDEF float * stbi_loadf_from_file(FILE * f, int * x, int * y, int * comp, int req_comp) +{ + stbi__context s; + stbi__start_file(&s, f); + return stbi__loadf_main(&s, x, y, comp, req_comp); +} +#endif // !STBI_NO_STDIO + +#endif // !STBI_NO_LINEAR + +// these is-hdr-or-not is defined independent of whether STBI_NO_LINEAR is +// defined, for API simplicity; if STBI_NO_LINEAR is defined, it always +// reports false! + +STBIDEF int stbi_is_hdr_from_memory(stbi_uc const * buffer, int len) +{ +#ifndef STBI_NO_HDR + stbi__context s; + stbi__start_mem(&s, buffer, len); + return stbi__hdr_test(&s); +#else + STBI_NOTUSED(buffer); + STBI_NOTUSED(len); + return 0; +#endif +} + +#ifndef STBI_NO_STDIO +STBIDEF int stbi_is_hdr(char const * filename) +{ + FILE * f = stbi__fopen(filename, "rb"); + int result = 0; + if(f) { + result = stbi_is_hdr_from_file(f); + fclose(f); + } + return result; +} + +STBIDEF int stbi_is_hdr_from_file(FILE * f) +{ +#ifndef STBI_NO_HDR + long pos = ftell(f); + int res; + stbi__context s; + stbi__start_file(&s, f); + res = stbi__hdr_test(&s); + fseek(f, pos, SEEK_SET); + return res; +#else + STBI_NOTUSED(f); + return 0; +#endif +} +#endif // !STBI_NO_STDIO + +STBIDEF int stbi_is_hdr_from_callbacks(stbi_io_callbacks const * clbk, void * user) +{ +#ifndef STBI_NO_HDR + stbi__context s; + stbi__start_callbacks(&s, (stbi_io_callbacks *) clbk, user); + return stbi__hdr_test(&s); +#else + STBI_NOTUSED(clbk); + STBI_NOTUSED(user); + return 0; +#endif +} + +#ifndef STBI_NO_LINEAR +static float stbi__l2h_gamma = 2.2f, stbi__l2h_scale = 1.0f; + +STBIDEF void stbi_ldr_to_hdr_gamma(float gamma) +{ + stbi__l2h_gamma = gamma; +} +STBIDEF void stbi_ldr_to_hdr_scale(float scale) +{ + stbi__l2h_scale = scale; +} +#endif + +static float stbi__h2l_gamma_i = 1.0f / 2.2f, stbi__h2l_scale_i = 1.0f; + +STBIDEF void stbi_hdr_to_ldr_gamma(float gamma) +{ + stbi__h2l_gamma_i = 1 / gamma; +} +STBIDEF void stbi_hdr_to_ldr_scale(float scale) +{ + stbi__h2l_scale_i = 1 / scale; +} + + +////////////////////////////////////////////////////////////////////////////// +// +// Common code used by all image loaders +// + +enum { + STBI__SCAN_load = 0, + STBI__SCAN_type, + STBI__SCAN_header +}; + +static void stbi__refill_buffer(stbi__context * s) +{ + int n = (s->io.read)(s->io_user_data, (char *)s->buffer_start, s->buflen); + s->callback_already_read += (int)(s->img_buffer - s->img_buffer_original); + if(n == 0) { + // at end of file, treat same as if from memory, but need to handle case + // where s->img_buffer isn't pointing to safe memory, e.g. 0-byte file + s->read_from_callbacks = 0; + s->img_buffer = s->buffer_start; + s->img_buffer_end = s->buffer_start + 1; + *s->img_buffer = 0; + } + else { + s->img_buffer = s->buffer_start; + s->img_buffer_end = s->buffer_start + n; + } +} + +stbi_inline static stbi_uc stbi__get8(stbi__context * s) +{ + if(s->img_buffer < s->img_buffer_end) + return *s->img_buffer++; + if(s->read_from_callbacks) { + stbi__refill_buffer(s); + return *s->img_buffer++; + } + return 0; +} + +#if defined(STBI_NO_JPEG) && defined(STBI_NO_HDR) && defined(STBI_NO_PIC) && defined(STBI_NO_PNM) +// nothing +#else +stbi_inline static int stbi__at_eof(stbi__context * s) +{ + if(s->io.read) { + if(!(s->io.eof)(s->io_user_data)) return 0; + // if feof() is true, check if buffer = end + // special case: we've only got the special 0 character at the end + if(s->read_from_callbacks == 0) return 1; + } + + return s->img_buffer >= s->img_buffer_end; +} +#endif + +#if defined(STBI_NO_JPEG) && defined(STBI_NO_PNG) && defined(STBI_NO_BMP) && defined(STBI_NO_PSD) && defined(STBI_NO_TGA) && defined(STBI_NO_GIF) && defined(STBI_NO_PIC) +// nothing +#else +static void stbi__skip(stbi__context * s, int n) +{ + if(n == 0) return; // already there! + if(n < 0) { + s->img_buffer = s->img_buffer_end; + return; + } + if(s->io.read) { + int blen = (int)(s->img_buffer_end - s->img_buffer); + if(blen < n) { + s->img_buffer = s->img_buffer_end; + (s->io.skip)(s->io_user_data, n - blen); + return; + } + } + s->img_buffer += n; +} +#endif + +#if defined(STBI_NO_PNG) && defined(STBI_NO_TGA) && defined(STBI_NO_HDR) && defined(STBI_NO_PNM) +// nothing +#else +static int stbi__getn(stbi__context * s, stbi_uc * buffer, int n) +{ + if(s->io.read) { + int blen = (int)(s->img_buffer_end - s->img_buffer); + if(blen < n) { + int res, count; + + memcpy(buffer, s->img_buffer, blen); + + count = (s->io.read)(s->io_user_data, (char *) buffer + blen, n - blen); + res = (count == (n - blen)); + s->img_buffer = s->img_buffer_end; + return res; + } + } + + if(s->img_buffer + n <= s->img_buffer_end) { + memcpy(buffer, s->img_buffer, n); + s->img_buffer += n; + return 1; + } + else + return 0; +} +#endif + +#if defined(STBI_NO_JPEG) && defined(STBI_NO_PNG) && defined(STBI_NO_PSD) && defined(STBI_NO_PIC) +// nothing +#else +static int stbi__get16be(stbi__context * s) +{ + int z = stbi__get8(s); + return (z << 8) + stbi__get8(s); +} +#endif + +#if defined(STBI_NO_PNG) && defined(STBI_NO_PSD) && defined(STBI_NO_PIC) +// nothing +#else +static stbi__uint32 stbi__get32be(stbi__context * s) +{ + stbi__uint32 z = stbi__get16be(s); + return (z << 16) + stbi__get16be(s); +} +#endif + +#if defined(STBI_NO_BMP) && defined(STBI_NO_TGA) && defined(STBI_NO_GIF) +// nothing +#else +static int stbi__get16le(stbi__context * s) +{ + int z = stbi__get8(s); + return z + (stbi__get8(s) << 8); +} +#endif + +#ifndef STBI_NO_BMP +static stbi__uint32 stbi__get32le(stbi__context * s) +{ + stbi__uint32 z = stbi__get16le(s); + z += (stbi__uint32)stbi__get16le(s) << 16; + return z; +} +#endif + +#define STBI__BYTECAST(x) ((stbi_uc) ((x) & 255)) // truncate int to byte without warnings + +#if defined(STBI_NO_JPEG) && defined(STBI_NO_PNG) && defined(STBI_NO_BMP) && defined(STBI_NO_PSD) && defined(STBI_NO_TGA) && defined(STBI_NO_GIF) && defined(STBI_NO_PIC) && defined(STBI_NO_PNM) +// nothing +#else +////////////////////////////////////////////////////////////////////////////// +// +// generic converter from built-in img_n to req_comp +// individual types do this automatically as much as possible (e.g. jpeg +// does all cases internally since it needs to colorspace convert anyway, +// and it never has alpha, so very few cases ). png can automatically +// interleave an alpha=255 channel, but falls back to this for other cases +// +// assume data buffer is malloced, so malloc a new one and free that one +// only failure mode is malloc failing + +static stbi_uc stbi__compute_y(int r, int g, int b) +{ + return (stbi_uc)(((r * 77) + (g * 150) + (29 * b)) >> 8); +} +#endif + +#if defined(STBI_NO_PNG) && defined(STBI_NO_BMP) && defined(STBI_NO_PSD) && defined(STBI_NO_TGA) && defined(STBI_NO_GIF) && defined(STBI_NO_PIC) && defined(STBI_NO_PNM) +// nothing +#else +static unsigned char * stbi__convert_format(unsigned char * data, int img_n, int req_comp, unsigned int x, + unsigned int y) +{ + int i, j; + unsigned char * good; + + if(req_comp == img_n) return data; + STBI_ASSERT(req_comp >= 1 && req_comp <= 4); + + good = (unsigned char *) stbi__malloc_mad3(req_comp, x, y, 0); + if(good == NULL) { + STBI_FREE(data); + return stbi__errpuc("outofmem", "Out of memory"); + } + + for(j = 0; j < (int) y; ++j) { + unsigned char * src = data + j * x * img_n ; + unsigned char * dest = good + j * x * req_comp; + +#define STBI__COMBO(a,b) ((a)*8+(b)) +#define STBI__CASE(a,b) case STBI__COMBO(a,b): for(i=x-1; i >= 0; --i, src += a, dest += b) + // convert source image with img_n components to one with req_comp components; + // avoid switch per pixel, so use switch per scanline and massive macros + switch(STBI__COMBO(img_n, req_comp)) { + STBI__CASE(1, 2) { + dest[0] = src[0]; + dest[1] = 255; + } + break; + STBI__CASE(1, 3) { + dest[0] = dest[1] = dest[2] = src[0]; + } + break; + STBI__CASE(1, 4) { + dest[0] = dest[1] = dest[2] = src[0]; + dest[3] = 255; + } + break; + STBI__CASE(2, 1) { + dest[0] = src[0]; + } + break; + STBI__CASE(2, 3) { + dest[0] = dest[1] = dest[2] = src[0]; + } + break; + STBI__CASE(2, 4) { + dest[0] = dest[1] = dest[2] = src[0]; + dest[3] = src[1]; + } + break; + STBI__CASE(3, 4) { + dest[0] = src[0]; + dest[1] = src[1]; + dest[2] = src[2]; + dest[3] = 255; + } + break; + STBI__CASE(3, 1) { + dest[0] = stbi__compute_y(src[0], src[1], src[2]); + } + break; + STBI__CASE(3, 2) { + dest[0] = stbi__compute_y(src[0], src[1], src[2]); + dest[1] = 255; + } + break; + STBI__CASE(4, 1) { + dest[0] = stbi__compute_y(src[0], src[1], src[2]); + } + break; + STBI__CASE(4, 2) { + dest[0] = stbi__compute_y(src[0], src[1], src[2]); + dest[1] = src[3]; + } + break; + STBI__CASE(4, 3) { + dest[0] = src[0]; + dest[1] = src[1]; + dest[2] = src[2]; + } + break; + default: + STBI_ASSERT(0); + STBI_FREE(data); + STBI_FREE(good); + return stbi__errpuc("unsupported", "Unsupported format conversion"); + } +#undef STBI__CASE + } + + STBI_FREE(data); + return good; +} +#endif + +#if defined(STBI_NO_PNG) && defined(STBI_NO_PSD) +// nothing +#else +static stbi__uint16 stbi__compute_y_16(int r, int g, int b) +{ + return (stbi__uint16)(((r * 77) + (g * 150) + (29 * b)) >> 8); +} +#endif + +#if defined(STBI_NO_PNG) && defined(STBI_NO_PSD) +// nothing +#else +static stbi__uint16 * stbi__convert_format16(stbi__uint16 * data, int img_n, int req_comp, unsigned int x, + unsigned int y) +{ + int i, j; + stbi__uint16 * good; + + if(req_comp == img_n) return data; + STBI_ASSERT(req_comp >= 1 && req_comp <= 4); + + good = (stbi__uint16 *) stbi__malloc(req_comp * x * y * 2); + if(good == NULL) { + STBI_FREE(data); + return (stbi__uint16 *) stbi__errpuc("outofmem", "Out of memory"); + } + + for(j = 0; j < (int) y; ++j) { + stbi__uint16 * src = data + j * x * img_n ; + stbi__uint16 * dest = good + j * x * req_comp; + +#define STBI__COMBO(a,b) ((a)*8+(b)) +#define STBI__CASE(a,b) case STBI__COMBO(a,b): for(i=x-1; i >= 0; --i, src += a, dest += b) + // convert source image with img_n components to one with req_comp components; + // avoid switch per pixel, so use switch per scanline and massive macros + switch(STBI__COMBO(img_n, req_comp)) { + STBI__CASE(1, 2) { + dest[0] = src[0]; + dest[1] = 0xffff; + } + break; + STBI__CASE(1, 3) { + dest[0] = dest[1] = dest[2] = src[0]; + } + break; + STBI__CASE(1, 4) { + dest[0] = dest[1] = dest[2] = src[0]; + dest[3] = 0xffff; + } + break; + STBI__CASE(2, 1) { + dest[0] = src[0]; + } + break; + STBI__CASE(2, 3) { + dest[0] = dest[1] = dest[2] = src[0]; + } + break; + STBI__CASE(2, 4) { + dest[0] = dest[1] = dest[2] = src[0]; + dest[3] = src[1]; + } + break; + STBI__CASE(3, 4) { + dest[0] = src[0]; + dest[1] = src[1]; + dest[2] = src[2]; + dest[3] = 0xffff; + } + break; + STBI__CASE(3, 1) { + dest[0] = stbi__compute_y_16(src[0], src[1], src[2]); + } + break; + STBI__CASE(3, 2) { + dest[0] = stbi__compute_y_16(src[0], src[1], src[2]); + dest[1] = 0xffff; + } + break; + STBI__CASE(4, 1) { + dest[0] = stbi__compute_y_16(src[0], src[1], src[2]); + } + break; + STBI__CASE(4, 2) { + dest[0] = stbi__compute_y_16(src[0], src[1], src[2]); + dest[1] = src[3]; + } + break; + STBI__CASE(4, 3) { + dest[0] = src[0]; + dest[1] = src[1]; + dest[2] = src[2]; + } + break; + default: + STBI_ASSERT(0); + STBI_FREE(data); + STBI_FREE(good); + return (stbi__uint16 *) stbi__errpuc("unsupported", "Unsupported format conversion"); + } +#undef STBI__CASE + } + + STBI_FREE(data); + return good; +} +#endif + +#ifndef STBI_NO_LINEAR +static float * stbi__ldr_to_hdr(stbi_uc * data, int x, int y, int comp) +{ + int i, k, n; + float * output; + if(!data) return NULL; + output = (float *) stbi__malloc_mad4(x, y, comp, sizeof(float), 0); + if(output == NULL) { + STBI_FREE(data); + return stbi__errpf("outofmem", "Out of memory"); + } + // compute number of non-alpha components + if(comp & 1) n = comp; + else n = comp - 1; + for(i = 0; i < x * y; ++i) { + for(k = 0; k < n; ++k) { + output[i * comp + k] = (float)(pow(data[i * comp + k] / 255.0f, stbi__l2h_gamma) * stbi__l2h_scale); + } + } + if(n < comp) { + for(i = 0; i < x * y; ++i) { + output[i * comp + n] = data[i * comp + n] / 255.0f; + } + } + STBI_FREE(data); + return output; +} +#endif + +#ifndef STBI_NO_HDR +#define stbi__float2int(x) ((int) (x)) +static stbi_uc * stbi__hdr_to_ldr(float * data, int x, int y, int comp) +{ + int i, k, n; + stbi_uc * output; + if(!data) return NULL; + output = (stbi_uc *) stbi__malloc_mad3(x, y, comp, 0); + if(output == NULL) { + STBI_FREE(data); + return stbi__errpuc("outofmem", "Out of memory"); + } + // compute number of non-alpha components + if(comp & 1) n = comp; + else n = comp - 1; + for(i = 0; i < x * y; ++i) { + for(k = 0; k < n; ++k) { + float z = (float) pow(data[i * comp + k] * stbi__h2l_scale_i, stbi__h2l_gamma_i) * 255 + 0.5f; + if(z < 0) z = 0; + if(z > 255) z = 255; + output[i * comp + k] = (stbi_uc) stbi__float2int(z); + } + if(k < comp) { + float z = data[i * comp + k] * 255 + 0.5f; + if(z < 0) z = 0; + if(z > 255) z = 255; + output[i * comp + k] = (stbi_uc) stbi__float2int(z); + } + } + STBI_FREE(data); + return output; +} +#endif + +////////////////////////////////////////////////////////////////////////////// +// +// "baseline" JPEG/JFIF decoder +// +// simple implementation +// - doesn't support delayed output of y-dimension +// - simple interface (only one output format: 8-bit interleaved RGB) +// - doesn't try to recover corrupt jpegs +// - doesn't allow partial loading, loading multiple at once +// - still fast on x86 (copying globals into locals doesn't help x86) +// - allocates lots of intermediate memory (full size of all components) +// - non-interleaved case requires this anyway +// - allows good upsampling (see next) +// high-quality +// - upsampled channels are bilinearly interpolated, even across blocks +// - quality integer IDCT derived from IJG's 'slow' +// performance +// - fast huffman; reasonable integer IDCT +// - some SIMD kernels for common paths on targets with SSE2/NEON +// - uses a lot of intermediate memory, could cache poorly + +#ifndef STBI_NO_JPEG + +// huffman decoding acceleration +#define FAST_BITS 9 // larger handles more cases; smaller stomps less cache + +typedef struct { + stbi_uc fast[1 << FAST_BITS]; + // weirdly, repacking this into AoS is a 10% speed loss, instead of a win + stbi__uint16 code[256]; + stbi_uc values[256]; + stbi_uc size[257]; + unsigned int maxcode[18]; + int delta[17]; // old 'firstsymbol' - old 'firstcode' +} stbi__huffman; + +typedef struct { + stbi__context * s; + stbi__huffman huff_dc[4]; + stbi__huffman huff_ac[4]; + stbi__uint16 dequant[4][64]; + stbi__int16 fast_ac[4][1 << FAST_BITS]; + + // sizes for components, interleaved MCUs + int img_h_max, img_v_max; + int img_mcu_x, img_mcu_y; + int img_mcu_w, img_mcu_h; + + // definition of jpeg image component + struct { + int id; + int h, v; + int tq; + int hd, ha; + int dc_pred; + + int x, y, w2, h2; + stbi_uc * data; + void * raw_data, * raw_coeff; + stbi_uc * linebuf; + short * coeff; // progressive only + int coeff_w, coeff_h; // number of 8x8 coefficient blocks + } img_comp[4]; + + stbi__uint32 code_buffer; // jpeg entropy-coded buffer + int code_bits; // number of valid bits + unsigned char marker; // marker seen while filling entropy buffer + int nomore; // flag if we saw a marker so must stop + + int progressive; + int spec_start; + int spec_end; + int succ_high; + int succ_low; + int eob_run; + int jfif; + int app14_color_transform; // Adobe APP14 tag + int rgb; + + int scan_n, order[4]; + int restart_interval, todo; + + // kernels + void (*idct_block_kernel)(stbi_uc * out, int out_stride, short data[64]); + void (*YCbCr_to_RGB_kernel)(stbi_uc * out, const stbi_uc * y, const stbi_uc * pcb, const stbi_uc * pcr, int count, + int step); + stbi_uc * (*resample_row_hv_2_kernel)(stbi_uc * out, stbi_uc * in_near, stbi_uc * in_far, int w, int hs); +} stbi__jpeg; + +static int stbi__build_huffman(stbi__huffman * h, int * count) +{ + int i, j, k = 0; + unsigned int code; + // build size list for each symbol (from JPEG spec) + for(i = 0; i < 16; ++i) { + for(j = 0; j < count[i]; ++j) { + h->size[k++] = (stbi_uc)(i + 1); + if(k >= 257) return stbi__err("bad size list", "Corrupt JPEG"); + } + } + h->size[k] = 0; + + // compute actual symbols (from jpeg spec) + code = 0; + k = 0; + for(j = 1; j <= 16; ++j) { + // compute delta to add to code to compute symbol id + h->delta[j] = k - code; + if(h->size[k] == j) { + while(h->size[k] == j) + h->code[k++] = (stbi__uint16)(code++); + if(code - 1 >= (1u << j)) return stbi__err("bad code lengths", "Corrupt JPEG"); + } + // compute largest code + 1 for this size, preshifted as needed later + h->maxcode[j] = code << (16 - j); + code <<= 1; + } + h->maxcode[j] = 0xffffffff; + + // build non-spec acceleration table; 255 is flag for not-accelerated + memset(h->fast, 255, 1 << FAST_BITS); + for(i = 0; i < k; ++i) { + int s = h->size[i]; + if(s <= FAST_BITS) { + int c = h->code[i] << (FAST_BITS - s); + int m = 1 << (FAST_BITS - s); + for(j = 0; j < m; ++j) { + h->fast[c + j] = (stbi_uc) i; + } + } + } + return 1; +} + +// build a table that decodes both magnitude and value of small ACs in +// one go. +static void stbi__build_fast_ac(stbi__int16 * fast_ac, stbi__huffman * h) +{ + int i; + for(i = 0; i < (1 << FAST_BITS); ++i) { + stbi_uc fast = h->fast[i]; + fast_ac[i] = 0; + if(fast < 255) { + int rs = h->values[fast]; + int run = (rs >> 4) & 15; + int magbits = rs & 15; + int len = h->size[fast]; + + if(magbits && len + magbits <= FAST_BITS) { + // magnitude code followed by receive_extend code + int k = ((i << len) & ((1 << FAST_BITS) - 1)) >> (FAST_BITS - magbits); + int m = 1 << (magbits - 1); + if(k < m) k += (~0U << magbits) + 1; + // if the result is small enough, we can fit it in fast_ac table + if(k >= -128 && k <= 127) + fast_ac[i] = (stbi__int16)((k * 256) + (run * 16) + (len + magbits)); + } + } + } +} + +static void stbi__grow_buffer_unsafe(stbi__jpeg * j) +{ + do { + unsigned int b = j->nomore ? 0 : stbi__get8(j->s); + if(b == 0xff) { + int c = stbi__get8(j->s); + while(c == 0xff) c = stbi__get8(j->s); // consume fill bytes + if(c != 0) { + j->marker = (unsigned char) c; + j->nomore = 1; + return; + } + } + j->code_buffer |= b << (24 - j->code_bits); + j->code_bits += 8; + } while(j->code_bits <= 24); +} + +// (1 << n) - 1 +static const stbi__uint32 stbi__bmask[17] = {0, 1, 3, 7, 15, 31, 63, 127, 255, 511, 1023, 2047, 4095, 8191, 16383, 32767, 65535}; + +// decode a jpeg huffman value from the bitstream +stbi_inline static int stbi__jpeg_huff_decode(stbi__jpeg * j, stbi__huffman * h) +{ + unsigned int temp; + int c, k; + + if(j->code_bits < 16) stbi__grow_buffer_unsafe(j); + + // look at the top FAST_BITS and determine what symbol ID it is, + // if the code is <= FAST_BITS + c = (j->code_buffer >> (32 - FAST_BITS)) & ((1 << FAST_BITS) - 1); + k = h->fast[c]; + if(k < 255) { + int s = h->size[k]; + if(s > j->code_bits) + return -1; + j->code_buffer <<= s; + j->code_bits -= s; + return h->values[k]; + } + + // naive test is to shift the code_buffer down so k bits are + // valid, then test against maxcode. To speed this up, we've + // preshifted maxcode left so that it has (16-k) 0s at the + // end; in other words, regardless of the number of bits, it + // wants to be compared against something shifted to have 16; + // that way we don't need to shift inside the loop. + temp = j->code_buffer >> 16; + for(k = FAST_BITS + 1 ; ; ++k) + if(temp < h->maxcode[k]) + break; + if(k == 17) { + // error! code not found + j->code_bits -= 16; + return -1; + } + + if(k > j->code_bits) + return -1; + + // convert the huffman code to the symbol id + c = ((j->code_buffer >> (32 - k)) & stbi__bmask[k]) + h->delta[k]; + if(c < 0 || c >= 256) // symbol id out of bounds! + return -1; + STBI_ASSERT((((j->code_buffer) >> (32 - h->size[c])) & stbi__bmask[h->size[c]]) == h->code[c]); + + // convert the id to a symbol + j->code_bits -= k; + j->code_buffer <<= k; + return h->values[c]; +} + +// bias[n] = (-1<code_bits < n) stbi__grow_buffer_unsafe(j); + if(j->code_bits < n) return 0; // ran out of bits from stream, return 0s intead of continuing + + sgn = j->code_buffer >> 31; // sign bit always in MSB; 0 if MSB clear (positive), 1 if MSB set (negative) + k = stbi_lrot(j->code_buffer, n); + j->code_buffer = k & ~stbi__bmask[n]; + k &= stbi__bmask[n]; + j->code_bits -= n; + return k + (stbi__jbias[n] & (sgn - 1)); +} + +// get some unsigned bits +stbi_inline static int stbi__jpeg_get_bits(stbi__jpeg * j, int n) +{ + unsigned int k; + if(j->code_bits < n) stbi__grow_buffer_unsafe(j); + if(j->code_bits < n) return 0; // ran out of bits from stream, return 0s intead of continuing + k = stbi_lrot(j->code_buffer, n); + j->code_buffer = k & ~stbi__bmask[n]; + k &= stbi__bmask[n]; + j->code_bits -= n; + return k; +} + +stbi_inline static int stbi__jpeg_get_bit(stbi__jpeg * j) +{ + unsigned int k; + if(j->code_bits < 1) stbi__grow_buffer_unsafe(j); + if(j->code_bits < 1) return 0; // ran out of bits from stream, return 0s intead of continuing + k = j->code_buffer; + j->code_buffer <<= 1; + --j->code_bits; + return k & 0x80000000; +} + +// given a value that's at position X in the zigzag stream, +// where does it appear in the 8x8 matrix coded as row-major? +static const stbi_uc stbi__jpeg_dezigzag[64 + 15] = { + 0, 1, 8, 16, 9, 2, 3, 10, + 17, 24, 32, 25, 18, 11, 4, 5, + 12, 19, 26, 33, 40, 48, 41, 34, + 27, 20, 13, 6, 7, 14, 21, 28, + 35, 42, 49, 56, 57, 50, 43, 36, + 29, 22, 15, 23, 30, 37, 44, 51, + 58, 59, 52, 45, 38, 31, 39, 46, + 53, 60, 61, 54, 47, 55, 62, 63, + // let corrupt input sample past end + 63, 63, 63, 63, 63, 63, 63, 63, + 63, 63, 63, 63, 63, 63, 63 +}; + +// decode one 64-entry block-- +static int stbi__jpeg_decode_block(stbi__jpeg * j, short data[64], stbi__huffman * hdc, stbi__huffman * hac, + stbi__int16 * fac, int b, stbi__uint16 * dequant) +{ + int diff, dc, k; + int t; + + if(j->code_bits < 16) stbi__grow_buffer_unsafe(j); + t = stbi__jpeg_huff_decode(j, hdc); + if(t < 0 || t > 15) return stbi__err("bad huffman code", "Corrupt JPEG"); + + // 0 all the ac values now so we can do it 32-bits at a time + memset(data, 0, 64 * sizeof(data[0])); + + diff = t ? stbi__extend_receive(j, t) : 0; + if(!stbi__addints_valid(j->img_comp[b].dc_pred, diff)) return stbi__err("bad delta", "Corrupt JPEG"); + dc = j->img_comp[b].dc_pred + diff; + j->img_comp[b].dc_pred = dc; + if(!stbi__mul2shorts_valid(dc, dequant[0])) return stbi__err("can't merge dc and ac", "Corrupt JPEG"); + data[0] = (short)(dc * dequant[0]); + + // decode AC components, see JPEG spec + k = 1; + do { + unsigned int zig; + int c, r, s; + if(j->code_bits < 16) stbi__grow_buffer_unsafe(j); + c = (j->code_buffer >> (32 - FAST_BITS)) & ((1 << FAST_BITS) - 1); + r = fac[c]; + if(r) { // fast-AC path + k += (r >> 4) & 15; // run + s = r & 15; // combined length + if(s > j->code_bits) return stbi__err("bad huffman code", "Combined length longer than code bits available"); + j->code_buffer <<= s; + j->code_bits -= s; + // decode into unzigzag'd location + zig = stbi__jpeg_dezigzag[k++]; + data[zig] = (short)((r >> 8) * dequant[zig]); + } + else { + int rs = stbi__jpeg_huff_decode(j, hac); + if(rs < 0) return stbi__err("bad huffman code", "Corrupt JPEG"); + s = rs & 15; + r = rs >> 4; + if(s == 0) { + if(rs != 0xf0) break; // end block + k += 16; + } + else { + k += r; + // decode into unzigzag'd location + zig = stbi__jpeg_dezigzag[k++]; + data[zig] = (short)(stbi__extend_receive(j, s) * dequant[zig]); + } + } + } while(k < 64); + return 1; +} + +static int stbi__jpeg_decode_block_prog_dc(stbi__jpeg * j, short data[64], stbi__huffman * hdc, int b) +{ + int diff, dc; + int t; + if(j->spec_end != 0) return stbi__err("can't merge dc and ac", "Corrupt JPEG"); + + if(j->code_bits < 16) stbi__grow_buffer_unsafe(j); + + if(j->succ_high == 0) { + // first scan for DC coefficient, must be first + memset(data, 0, 64 * sizeof(data[0])); // 0 all the ac values now + t = stbi__jpeg_huff_decode(j, hdc); + if(t < 0 || t > 15) return stbi__err("can't merge dc and ac", "Corrupt JPEG"); + diff = t ? stbi__extend_receive(j, t) : 0; + + if(!stbi__addints_valid(j->img_comp[b].dc_pred, diff)) return stbi__err("bad delta", "Corrupt JPEG"); + dc = j->img_comp[b].dc_pred + diff; + j->img_comp[b].dc_pred = dc; + if(!stbi__mul2shorts_valid(dc, 1 << j->succ_low)) return stbi__err("can't merge dc and ac", "Corrupt JPEG"); + data[0] = (short)(dc * (1 << j->succ_low)); + } + else { + // refinement scan for DC coefficient + if(stbi__jpeg_get_bit(j)) + data[0] += (short)(1 << j->succ_low); + } + return 1; +} + +// @OPTIMIZE: store non-zigzagged during the decode passes, +// and only de-zigzag when dequantizing +static int stbi__jpeg_decode_block_prog_ac(stbi__jpeg * j, short data[64], stbi__huffman * hac, stbi__int16 * fac) +{ + int k; + if(j->spec_start == 0) return stbi__err("can't merge dc and ac", "Corrupt JPEG"); + + if(j->succ_high == 0) { + int shift = j->succ_low; + + if(j->eob_run) { + --j->eob_run; + return 1; + } + + k = j->spec_start; + do { + unsigned int zig; + int c, r, s; + if(j->code_bits < 16) stbi__grow_buffer_unsafe(j); + c = (j->code_buffer >> (32 - FAST_BITS)) & ((1 << FAST_BITS) - 1); + r = fac[c]; + if(r) { // fast-AC path + k += (r >> 4) & 15; // run + s = r & 15; // combined length + if(s > j->code_bits) return stbi__err("bad huffman code", "Combined length longer than code bits available"); + j->code_buffer <<= s; + j->code_bits -= s; + zig = stbi__jpeg_dezigzag[k++]; + data[zig] = (short)((r >> 8) * (1 << shift)); + } + else { + int rs = stbi__jpeg_huff_decode(j, hac); + if(rs < 0) return stbi__err("bad huffman code", "Corrupt JPEG"); + s = rs & 15; + r = rs >> 4; + if(s == 0) { + if(r < 15) { + j->eob_run = (1 << r); + if(r) + j->eob_run += stbi__jpeg_get_bits(j, r); + --j->eob_run; + break; + } + k += 16; + } + else { + k += r; + zig = stbi__jpeg_dezigzag[k++]; + data[zig] = (short)(stbi__extend_receive(j, s) * (1 << shift)); + } + } + } while(k <= j->spec_end); + } + else { + // refinement scan for these AC coefficients + + short bit = (short)(1 << j->succ_low); + + if(j->eob_run) { + --j->eob_run; + for(k = j->spec_start; k <= j->spec_end; ++k) { + short * p = &data[stbi__jpeg_dezigzag[k]]; + if(*p != 0) + if(stbi__jpeg_get_bit(j)) + if((*p & bit) == 0) { + if(*p > 0) + *p += bit; + else + *p -= bit; + } + } + } + else { + k = j->spec_start; + do { + int r, s; + int rs = stbi__jpeg_huff_decode(j, hac); // @OPTIMIZE see if we can use the fast path here, advance-by-r is so slow, eh + if(rs < 0) return stbi__err("bad huffman code", "Corrupt JPEG"); + s = rs & 15; + r = rs >> 4; + if(s == 0) { + if(r < 15) { + j->eob_run = (1 << r) - 1; + if(r) + j->eob_run += stbi__jpeg_get_bits(j, r); + r = 64; // force end of block + } + else { + // r=15 s=0 should write 16 0s, so we just do + // a run of 15 0s and then write s (which is 0), + // so we don't have to do anything special here + } + } + else { + if(s != 1) return stbi__err("bad huffman code", "Corrupt JPEG"); + // sign bit + if(stbi__jpeg_get_bit(j)) + s = bit; + else + s = -bit; + } + + // advance by r + while(k <= j->spec_end) { + short * p = &data[stbi__jpeg_dezigzag[k++]]; + if(*p != 0) { + if(stbi__jpeg_get_bit(j)) + if((*p & bit) == 0) { + if(*p > 0) + *p += bit; + else + *p -= bit; + } + } + else { + if(r == 0) { + *p = (short) s; + break; + } + --r; + } + } + } while(k <= j->spec_end); + } + } + return 1; +} + +// take a -128..127 value and stbi__clamp it and convert to 0..255 +stbi_inline static stbi_uc stbi__clamp(int x) +{ + // trick to use a single test to catch both cases + if((unsigned int) x > 255) { + if(x < 0) return 0; + if(x > 255) return 255; + } + return (stbi_uc) x; +} + +#define stbi__f2f(x) ((int) (((x) * 4096 + 0.5))) +#define stbi__fsh(x) ((x) * 4096) + +// derived from jidctint -- DCT_ISLOW +#define STBI__IDCT_1D(s0,s1,s2,s3,s4,s5,s6,s7) \ + int t0,t1,t2,t3,p1,p2,p3,p4,p5,x0,x1,x2,x3; \ + p2 = s2; \ + p3 = s6; \ + p1 = (p2+p3) * stbi__f2f(0.5411961f); \ + t2 = p1 + p3*stbi__f2f(-1.847759065f); \ + t3 = p1 + p2*stbi__f2f( 0.765366865f); \ + p2 = s0; \ + p3 = s4; \ + t0 = stbi__fsh(p2+p3); \ + t1 = stbi__fsh(p2-p3); \ + x0 = t0+t3; \ + x3 = t0-t3; \ + x1 = t1+t2; \ + x2 = t1-t2; \ + t0 = s7; \ + t1 = s5; \ + t2 = s3; \ + t3 = s1; \ + p3 = t0+t2; \ + p4 = t1+t3; \ + p1 = t0+t3; \ + p2 = t1+t2; \ + p5 = (p3+p4)*stbi__f2f( 1.175875602f); \ + t0 = t0*stbi__f2f( 0.298631336f); \ + t1 = t1*stbi__f2f( 2.053119869f); \ + t2 = t2*stbi__f2f( 3.072711026f); \ + t3 = t3*stbi__f2f( 1.501321110f); \ + p1 = p5 + p1*stbi__f2f(-0.899976223f); \ + p2 = p5 + p2*stbi__f2f(-2.562915447f); \ + p3 = p3*stbi__f2f(-1.961570560f); \ + p4 = p4*stbi__f2f(-0.390180644f); \ + t3 += p1+p4; \ + t2 += p2+p3; \ + t1 += p2+p4; \ + t0 += p1+p3; + +static void stbi__idct_block(stbi_uc * out, int out_stride, short data[64]) +{ + int i, val[64], * v = val; + stbi_uc * o; + short * d = data; + + // columns + for(i = 0; i < 8; ++i, ++d, ++v) { + // if all zeroes, shortcut -- this avoids dequantizing 0s and IDCTing + if(d[ 8] == 0 && d[16] == 0 && d[24] == 0 && d[32] == 0 + && d[40] == 0 && d[48] == 0 && d[56] == 0) { + // no shortcut 0 seconds + // (1|2|3|4|5|6|7)==0 0 seconds + // all separate -0.047 seconds + // 1 && 2|3 && 4|5 && 6|7: -0.047 seconds + int dcterm = d[0] * 4; + v[0] = v[8] = v[16] = v[24] = v[32] = v[40] = v[48] = v[56] = dcterm; + } + else { + STBI__IDCT_1D(d[ 0], d[ 8], d[16], d[24], d[32], d[40], d[48], d[56]) + // constants scaled things up by 1<<12; let's bring them back + // down, but keep 2 extra bits of precision + x0 += 512; + x1 += 512; + x2 += 512; + x3 += 512; + v[ 0] = (x0 + t3) >> 10; + v[56] = (x0 - t3) >> 10; + v[ 8] = (x1 + t2) >> 10; + v[48] = (x1 - t2) >> 10; + v[16] = (x2 + t1) >> 10; + v[40] = (x2 - t1) >> 10; + v[24] = (x3 + t0) >> 10; + v[32] = (x3 - t0) >> 10; + } + } + + for(i = 0, v = val, o = out; i < 8; ++i, v += 8, o += out_stride) { + // no fast case since the first 1D IDCT spread components out + STBI__IDCT_1D(v[0], v[1], v[2], v[3], v[4], v[5], v[6], v[7]) + // constants scaled things up by 1<<12, plus we had 1<<2 from first + // loop, plus horizontal and vertical each scale by sqrt(8) so together + // we've got an extra 1<<3, so 1<<17 total we need to remove. + // so we want to round that, which means adding 0.5 * 1<<17, + // aka 65536. Also, we'll end up with -128 to 127 that we want + // to encode as 0..255 by adding 128, so we'll add that before the shift + x0 += 65536 + (128 << 17); + x1 += 65536 + (128 << 17); + x2 += 65536 + (128 << 17); + x3 += 65536 + (128 << 17); + // tried computing the shifts into temps, or'ing the temps to see + // if any were out of range, but that was slower + o[0] = stbi__clamp((x0 + t3) >> 17); + o[7] = stbi__clamp((x0 - t3) >> 17); + o[1] = stbi__clamp((x1 + t2) >> 17); + o[6] = stbi__clamp((x1 - t2) >> 17); + o[2] = stbi__clamp((x2 + t1) >> 17); + o[5] = stbi__clamp((x2 - t1) >> 17); + o[3] = stbi__clamp((x3 + t0) >> 17); + o[4] = stbi__clamp((x3 - t0) >> 17); + } +} + +#ifdef STBI_SSE2 +// sse2 integer IDCT. not the fastest possible implementation but it +// produces bit-identical results to the generic C version so it's +// fully "transparent". +static void stbi__idct_simd(stbi_uc * out, int out_stride, short data[64]) +{ + // This is constructed to match our regular (generic) integer IDCT exactly. + __m128i row0, row1, row2, row3, row4, row5, row6, row7; + __m128i tmp; + + // dot product constant: even elems=x, odd elems=y +#define dct_const(x,y) _mm_setr_epi16((x),(y),(x),(y),(x),(y),(x),(y)) + + // out(0) = c0[even]*x + c0[odd]*y (c0, x, y 16-bit, out 32-bit) + // out(1) = c1[even]*x + c1[odd]*y +#define dct_rot(out0,out1, x,y,c0,c1) \ + __m128i c0##lo = _mm_unpacklo_epi16((x),(y)); \ + __m128i c0##hi = _mm_unpackhi_epi16((x),(y)); \ + __m128i out0##_l = _mm_madd_epi16(c0##lo, c0); \ + __m128i out0##_h = _mm_madd_epi16(c0##hi, c0); \ + __m128i out1##_l = _mm_madd_epi16(c0##lo, c1); \ + __m128i out1##_h = _mm_madd_epi16(c0##hi, c1) + + // out = in << 12 (in 16-bit, out 32-bit) +#define dct_widen(out, in) \ + __m128i out##_l = _mm_srai_epi32(_mm_unpacklo_epi16(_mm_setzero_si128(), (in)), 4); \ + __m128i out##_h = _mm_srai_epi32(_mm_unpackhi_epi16(_mm_setzero_si128(), (in)), 4) + + // wide add +#define dct_wadd(out, a, b) \ + __m128i out##_l = _mm_add_epi32(a##_l, b##_l); \ + __m128i out##_h = _mm_add_epi32(a##_h, b##_h) + + // wide sub +#define dct_wsub(out, a, b) \ + __m128i out##_l = _mm_sub_epi32(a##_l, b##_l); \ + __m128i out##_h = _mm_sub_epi32(a##_h, b##_h) + + // butterfly a/b, add bias, then shift by "s" and pack +#define dct_bfly32o(out0, out1, a,b,bias,s) \ + { \ + __m128i abiased_l = _mm_add_epi32(a##_l, bias); \ + __m128i abiased_h = _mm_add_epi32(a##_h, bias); \ + dct_wadd(sum, abiased, b); \ + dct_wsub(dif, abiased, b); \ + out0 = _mm_packs_epi32(_mm_srai_epi32(sum_l, s), _mm_srai_epi32(sum_h, s)); \ + out1 = _mm_packs_epi32(_mm_srai_epi32(dif_l, s), _mm_srai_epi32(dif_h, s)); \ + } + + // 8-bit interleave step (for transposes) +#define dct_interleave8(a, b) \ + tmp = a; \ + a = _mm_unpacklo_epi8(a, b); \ + b = _mm_unpackhi_epi8(tmp, b) + + // 16-bit interleave step (for transposes) +#define dct_interleave16(a, b) \ + tmp = a; \ + a = _mm_unpacklo_epi16(a, b); \ + b = _mm_unpackhi_epi16(tmp, b) + +#define dct_pass(bias,shift) \ + { \ + /* even part */ \ + dct_rot(t2e,t3e, row2,row6, rot0_0,rot0_1); \ + __m128i sum04 = _mm_add_epi16(row0, row4); \ + __m128i dif04 = _mm_sub_epi16(row0, row4); \ + dct_widen(t0e, sum04); \ + dct_widen(t1e, dif04); \ + dct_wadd(x0, t0e, t3e); \ + dct_wsub(x3, t0e, t3e); \ + dct_wadd(x1, t1e, t2e); \ + dct_wsub(x2, t1e, t2e); \ + /* odd part */ \ + dct_rot(y0o,y2o, row7,row3, rot2_0,rot2_1); \ + dct_rot(y1o,y3o, row5,row1, rot3_0,rot3_1); \ + __m128i sum17 = _mm_add_epi16(row1, row7); \ + __m128i sum35 = _mm_add_epi16(row3, row5); \ + dct_rot(y4o,y5o, sum17,sum35, rot1_0,rot1_1); \ + dct_wadd(x4, y0o, y4o); \ + dct_wadd(x5, y1o, y5o); \ + dct_wadd(x6, y2o, y5o); \ + dct_wadd(x7, y3o, y4o); \ + dct_bfly32o(row0,row7, x0,x7,bias,shift); \ + dct_bfly32o(row1,row6, x1,x6,bias,shift); \ + dct_bfly32o(row2,row5, x2,x5,bias,shift); \ + dct_bfly32o(row3,row4, x3,x4,bias,shift); \ + } + + __m128i rot0_0 = dct_const(stbi__f2f(0.5411961f), stbi__f2f(0.5411961f) + stbi__f2f(-1.847759065f)); + __m128i rot0_1 = dct_const(stbi__f2f(0.5411961f) + stbi__f2f(0.765366865f), stbi__f2f(0.5411961f)); + __m128i rot1_0 = dct_const(stbi__f2f(1.175875602f) + stbi__f2f(-0.899976223f), stbi__f2f(1.175875602f)); + __m128i rot1_1 = dct_const(stbi__f2f(1.175875602f), stbi__f2f(1.175875602f) + stbi__f2f(-2.562915447f)); + __m128i rot2_0 = dct_const(stbi__f2f(-1.961570560f) + stbi__f2f(0.298631336f), stbi__f2f(-1.961570560f)); + __m128i rot2_1 = dct_const(stbi__f2f(-1.961570560f), stbi__f2f(-1.961570560f) + stbi__f2f(3.072711026f)); + __m128i rot3_0 = dct_const(stbi__f2f(-0.390180644f) + stbi__f2f(2.053119869f), stbi__f2f(-0.390180644f)); + __m128i rot3_1 = dct_const(stbi__f2f(-0.390180644f), stbi__f2f(-0.390180644f) + stbi__f2f(1.501321110f)); + + // rounding biases in column/row passes, see stbi__idct_block for explanation. + __m128i bias_0 = _mm_set1_epi32(512); + __m128i bias_1 = _mm_set1_epi32(65536 + (128 << 17)); + + // load + row0 = _mm_load_si128((const __m128i *)(data + 0 * 8)); + row1 = _mm_load_si128((const __m128i *)(data + 1 * 8)); + row2 = _mm_load_si128((const __m128i *)(data + 2 * 8)); + row3 = _mm_load_si128((const __m128i *)(data + 3 * 8)); + row4 = _mm_load_si128((const __m128i *)(data + 4 * 8)); + row5 = _mm_load_si128((const __m128i *)(data + 5 * 8)); + row6 = _mm_load_si128((const __m128i *)(data + 6 * 8)); + row7 = _mm_load_si128((const __m128i *)(data + 7 * 8)); + + // column pass + dct_pass(bias_0, 10); + + { + // 16bit 8x8 transpose pass 1 + dct_interleave16(row0, row4); + dct_interleave16(row1, row5); + dct_interleave16(row2, row6); + dct_interleave16(row3, row7); + + // transpose pass 2 + dct_interleave16(row0, row2); + dct_interleave16(row1, row3); + dct_interleave16(row4, row6); + dct_interleave16(row5, row7); + + // transpose pass 3 + dct_interleave16(row0, row1); + dct_interleave16(row2, row3); + dct_interleave16(row4, row5); + dct_interleave16(row6, row7); + } + + // row pass + dct_pass(bias_1, 17); + + { + // pack + __m128i p0 = _mm_packus_epi16(row0, row1); // a0a1a2a3...a7b0b1b2b3...b7 + __m128i p1 = _mm_packus_epi16(row2, row3); + __m128i p2 = _mm_packus_epi16(row4, row5); + __m128i p3 = _mm_packus_epi16(row6, row7); + + // 8bit 8x8 transpose pass 1 + dct_interleave8(p0, p2); // a0e0a1e1... + dct_interleave8(p1, p3); // c0g0c1g1... + + // transpose pass 2 + dct_interleave8(p0, p1); // a0c0e0g0... + dct_interleave8(p2, p3); // b0d0f0h0... + + // transpose pass 3 + dct_interleave8(p0, p2); // a0b0c0d0... + dct_interleave8(p1, p3); // a4b4c4d4... + + // store + _mm_storel_epi64((__m128i *) out, p0); + out += out_stride; + _mm_storel_epi64((__m128i *) out, _mm_shuffle_epi32(p0, 0x4e)); + out += out_stride; + _mm_storel_epi64((__m128i *) out, p2); + out += out_stride; + _mm_storel_epi64((__m128i *) out, _mm_shuffle_epi32(p2, 0x4e)); + out += out_stride; + _mm_storel_epi64((__m128i *) out, p1); + out += out_stride; + _mm_storel_epi64((__m128i *) out, _mm_shuffle_epi32(p1, 0x4e)); + out += out_stride; + _mm_storel_epi64((__m128i *) out, p3); + out += out_stride; + _mm_storel_epi64((__m128i *) out, _mm_shuffle_epi32(p3, 0x4e)); + } + +#undef dct_const +#undef dct_rot +#undef dct_widen +#undef dct_wadd +#undef dct_wsub +#undef dct_bfly32o +#undef dct_interleave8 +#undef dct_interleave16 +#undef dct_pass +} + +#endif // STBI_SSE2 + +#ifdef STBI_NEON + +// NEON integer IDCT. should produce bit-identical +// results to the generic C version. +static void stbi__idct_simd(stbi_uc * out, int out_stride, short data[64]) +{ + int16x8_t row0, row1, row2, row3, row4, row5, row6, row7; + + int16x4_t rot0_0 = vdup_n_s16(stbi__f2f(0.5411961f)); + int16x4_t rot0_1 = vdup_n_s16(stbi__f2f(-1.847759065f)); + int16x4_t rot0_2 = vdup_n_s16(stbi__f2f(0.765366865f)); + int16x4_t rot1_0 = vdup_n_s16(stbi__f2f(1.175875602f)); + int16x4_t rot1_1 = vdup_n_s16(stbi__f2f(-0.899976223f)); + int16x4_t rot1_2 = vdup_n_s16(stbi__f2f(-2.562915447f)); + int16x4_t rot2_0 = vdup_n_s16(stbi__f2f(-1.961570560f)); + int16x4_t rot2_1 = vdup_n_s16(stbi__f2f(-0.390180644f)); + int16x4_t rot3_0 = vdup_n_s16(stbi__f2f(0.298631336f)); + int16x4_t rot3_1 = vdup_n_s16(stbi__f2f(2.053119869f)); + int16x4_t rot3_2 = vdup_n_s16(stbi__f2f(3.072711026f)); + int16x4_t rot3_3 = vdup_n_s16(stbi__f2f(1.501321110f)); + +#define dct_long_mul(out, inq, coeff) \ + int32x4_t out##_l = vmull_s16(vget_low_s16(inq), coeff); \ + int32x4_t out##_h = vmull_s16(vget_high_s16(inq), coeff) + +#define dct_long_mac(out, acc, inq, coeff) \ + int32x4_t out##_l = vmlal_s16(acc##_l, vget_low_s16(inq), coeff); \ + int32x4_t out##_h = vmlal_s16(acc##_h, vget_high_s16(inq), coeff) + +#define dct_widen(out, inq) \ + int32x4_t out##_l = vshll_n_s16(vget_low_s16(inq), 12); \ + int32x4_t out##_h = vshll_n_s16(vget_high_s16(inq), 12) + + // wide add +#define dct_wadd(out, a, b) \ + int32x4_t out##_l = vaddq_s32(a##_l, b##_l); \ + int32x4_t out##_h = vaddq_s32(a##_h, b##_h) + + // wide sub +#define dct_wsub(out, a, b) \ + int32x4_t out##_l = vsubq_s32(a##_l, b##_l); \ + int32x4_t out##_h = vsubq_s32(a##_h, b##_h) + + // butterfly a/b, then shift using "shiftop" by "s" and pack +#define dct_bfly32o(out0,out1, a,b,shiftop,s) \ + { \ + dct_wadd(sum, a, b); \ + dct_wsub(dif, a, b); \ + out0 = vcombine_s16(shiftop(sum_l, s), shiftop(sum_h, s)); \ + out1 = vcombine_s16(shiftop(dif_l, s), shiftop(dif_h, s)); \ + } + +#define dct_pass(shiftop, shift) \ + { \ + /* even part */ \ + int16x8_t sum26 = vaddq_s16(row2, row6); \ + dct_long_mul(p1e, sum26, rot0_0); \ + dct_long_mac(t2e, p1e, row6, rot0_1); \ + dct_long_mac(t3e, p1e, row2, rot0_2); \ + int16x8_t sum04 = vaddq_s16(row0, row4); \ + int16x8_t dif04 = vsubq_s16(row0, row4); \ + dct_widen(t0e, sum04); \ + dct_widen(t1e, dif04); \ + dct_wadd(x0, t0e, t3e); \ + dct_wsub(x3, t0e, t3e); \ + dct_wadd(x1, t1e, t2e); \ + dct_wsub(x2, t1e, t2e); \ + /* odd part */ \ + int16x8_t sum15 = vaddq_s16(row1, row5); \ + int16x8_t sum17 = vaddq_s16(row1, row7); \ + int16x8_t sum35 = vaddq_s16(row3, row5); \ + int16x8_t sum37 = vaddq_s16(row3, row7); \ + int16x8_t sumodd = vaddq_s16(sum17, sum35); \ + dct_long_mul(p5o, sumodd, rot1_0); \ + dct_long_mac(p1o, p5o, sum17, rot1_1); \ + dct_long_mac(p2o, p5o, sum35, rot1_2); \ + dct_long_mul(p3o, sum37, rot2_0); \ + dct_long_mul(p4o, sum15, rot2_1); \ + dct_wadd(sump13o, p1o, p3o); \ + dct_wadd(sump24o, p2o, p4o); \ + dct_wadd(sump23o, p2o, p3o); \ + dct_wadd(sump14o, p1o, p4o); \ + dct_long_mac(x4, sump13o, row7, rot3_0); \ + dct_long_mac(x5, sump24o, row5, rot3_1); \ + dct_long_mac(x6, sump23o, row3, rot3_2); \ + dct_long_mac(x7, sump14o, row1, rot3_3); \ + dct_bfly32o(row0,row7, x0,x7,shiftop,shift); \ + dct_bfly32o(row1,row6, x1,x6,shiftop,shift); \ + dct_bfly32o(row2,row5, x2,x5,shiftop,shift); \ + dct_bfly32o(row3,row4, x3,x4,shiftop,shift); \ + } + + // load + row0 = vld1q_s16(data + 0 * 8); + row1 = vld1q_s16(data + 1 * 8); + row2 = vld1q_s16(data + 2 * 8); + row3 = vld1q_s16(data + 3 * 8); + row4 = vld1q_s16(data + 4 * 8); + row5 = vld1q_s16(data + 5 * 8); + row6 = vld1q_s16(data + 6 * 8); + row7 = vld1q_s16(data + 7 * 8); + + // add DC bias + row0 = vaddq_s16(row0, vsetq_lane_s16(1024, vdupq_n_s16(0), 0)); + + // column pass + dct_pass(vrshrn_n_s32, 10); + + // 16bit 8x8 transpose + { + // these three map to a single VTRN.16, VTRN.32, and VSWP, respectively. + // whether compilers actually get this is another story, sadly. +#define dct_trn16(x, y) { int16x8x2_t t = vtrnq_s16(x, y); x = t.val[0]; y = t.val[1]; } +#define dct_trn32(x, y) { int32x4x2_t t = vtrnq_s32(vreinterpretq_s32_s16(x), vreinterpretq_s32_s16(y)); x = vreinterpretq_s16_s32(t.val[0]); y = vreinterpretq_s16_s32(t.val[1]); } +#define dct_trn64(x, y) { int16x8_t x0 = x; int16x8_t y0 = y; x = vcombine_s16(vget_low_s16(x0), vget_low_s16(y0)); y = vcombine_s16(vget_high_s16(x0), vget_high_s16(y0)); } + + // pass 1 + dct_trn16(row0, row1); // a0b0a2b2a4b4a6b6 + dct_trn16(row2, row3); + dct_trn16(row4, row5); + dct_trn16(row6, row7); + + // pass 2 + dct_trn32(row0, row2); // a0b0c0d0a4b4c4d4 + dct_trn32(row1, row3); + dct_trn32(row4, row6); + dct_trn32(row5, row7); + + // pass 3 + dct_trn64(row0, row4); // a0b0c0d0e0f0g0h0 + dct_trn64(row1, row5); + dct_trn64(row2, row6); + dct_trn64(row3, row7); + +#undef dct_trn16 +#undef dct_trn32 +#undef dct_trn64 + } + + // row pass + // vrshrn_n_s32 only supports shifts up to 16, we need + // 17. so do a non-rounding shift of 16 first then follow + // up with a rounding shift by 1. + dct_pass(vshrn_n_s32, 16); + + { + // pack and round + uint8x8_t p0 = vqrshrun_n_s16(row0, 1); + uint8x8_t p1 = vqrshrun_n_s16(row1, 1); + uint8x8_t p2 = vqrshrun_n_s16(row2, 1); + uint8x8_t p3 = vqrshrun_n_s16(row3, 1); + uint8x8_t p4 = vqrshrun_n_s16(row4, 1); + uint8x8_t p5 = vqrshrun_n_s16(row5, 1); + uint8x8_t p6 = vqrshrun_n_s16(row6, 1); + uint8x8_t p7 = vqrshrun_n_s16(row7, 1); + + // again, these can translate into one instruction, but often don't. +#define dct_trn8_8(x, y) { uint8x8x2_t t = vtrn_u8(x, y); x = t.val[0]; y = t.val[1]; } +#define dct_trn8_16(x, y) { uint16x4x2_t t = vtrn_u16(vreinterpret_u16_u8(x), vreinterpret_u16_u8(y)); x = vreinterpret_u8_u16(t.val[0]); y = vreinterpret_u8_u16(t.val[1]); } +#define dct_trn8_32(x, y) { uint32x2x2_t t = vtrn_u32(vreinterpret_u32_u8(x), vreinterpret_u32_u8(y)); x = vreinterpret_u8_u32(t.val[0]); y = vreinterpret_u8_u32(t.val[1]); } + + // sadly can't use interleaved stores here since we only write + // 8 bytes to each scan line! + + // 8x8 8-bit transpose pass 1 + dct_trn8_8(p0, p1); + dct_trn8_8(p2, p3); + dct_trn8_8(p4, p5); + dct_trn8_8(p6, p7); + + // pass 2 + dct_trn8_16(p0, p2); + dct_trn8_16(p1, p3); + dct_trn8_16(p4, p6); + dct_trn8_16(p5, p7); + + // pass 3 + dct_trn8_32(p0, p4); + dct_trn8_32(p1, p5); + dct_trn8_32(p2, p6); + dct_trn8_32(p3, p7); + + // store + vst1_u8(out, p0); + out += out_stride; + vst1_u8(out, p1); + out += out_stride; + vst1_u8(out, p2); + out += out_stride; + vst1_u8(out, p3); + out += out_stride; + vst1_u8(out, p4); + out += out_stride; + vst1_u8(out, p5); + out += out_stride; + vst1_u8(out, p6); + out += out_stride; + vst1_u8(out, p7); + +#undef dct_trn8_8 +#undef dct_trn8_16 +#undef dct_trn8_32 + } + +#undef dct_long_mul +#undef dct_long_mac +#undef dct_widen +#undef dct_wadd +#undef dct_wsub +#undef dct_bfly32o +#undef dct_pass +} + +#endif // STBI_NEON + +#define STBI__MARKER_none 0xff +// if there's a pending marker from the entropy stream, return that +// otherwise, fetch from the stream and get a marker. if there's no +// marker, return 0xff, which is never a valid marker value +static stbi_uc stbi__get_marker(stbi__jpeg * j) +{ + stbi_uc x; + if(j->marker != STBI__MARKER_none) { + x = j->marker; + j->marker = STBI__MARKER_none; + return x; + } + x = stbi__get8(j->s); + if(x != 0xff) return STBI__MARKER_none; + while(x == 0xff) + x = stbi__get8(j->s); // consume repeated 0xff fill bytes + return x; +} + +// in each scan, we'll have scan_n components, and the order +// of the components is specified by order[] +#define STBI__RESTART(x) ((x) >= 0xd0 && (x) <= 0xd7) + +// after a restart interval, stbi__jpeg_reset the entropy decoder and +// the dc prediction +static void stbi__jpeg_reset(stbi__jpeg * j) +{ + j->code_bits = 0; + j->code_buffer = 0; + j->nomore = 0; + j->img_comp[0].dc_pred = j->img_comp[1].dc_pred = j->img_comp[2].dc_pred = j->img_comp[3].dc_pred = 0; + j->marker = STBI__MARKER_none; + j->todo = j->restart_interval ? j->restart_interval : 0x7fffffff; + j->eob_run = 0; + // no more than 1<<31 MCUs if no restart_interal? that's plenty safe, + // since we don't even allow 1<<30 pixels +} + +static int stbi__parse_entropy_coded_data(stbi__jpeg * z) +{ + stbi__jpeg_reset(z); + if(!z->progressive) { + if(z->scan_n == 1) { + int i, j; + STBI_SIMD_ALIGN(short, data[64]); + int n = z->order[0]; + // non-interleaved data, we just need to process one block at a time, + // in trivial scanline order + // number of blocks to do just depends on how many actual "pixels" this + // component has, independent of interleaved MCU blocking and such + int w = (z->img_comp[n].x + 7) >> 3; + int h = (z->img_comp[n].y + 7) >> 3; + for(j = 0; j < h; ++j) { + for(i = 0; i < w; ++i) { + int ha = z->img_comp[n].ha; + if(!stbi__jpeg_decode_block(z, data, z->huff_dc + z->img_comp[n].hd, z->huff_ac + ha, z->fast_ac[ha], n, + z->dequant[z->img_comp[n].tq])) return 0; + z->idct_block_kernel(z->img_comp[n].data + z->img_comp[n].w2 * j * 8 + i * 8, z->img_comp[n].w2, data); + // every data block is an MCU, so countdown the restart interval + if(--z->todo <= 0) { + if(z->code_bits < 24) stbi__grow_buffer_unsafe(z); + // if it's NOT a restart, then just bail, so we get corrupt data + // rather than no data + if(!STBI__RESTART(z->marker)) return 1; + stbi__jpeg_reset(z); + } + } + } + return 1; + } + else { // interleaved + int i, j, k, x, y; + STBI_SIMD_ALIGN(short, data[64]); + for(j = 0; j < z->img_mcu_y; ++j) { + for(i = 0; i < z->img_mcu_x; ++i) { + // scan an interleaved mcu... process scan_n components in order + for(k = 0; k < z->scan_n; ++k) { + int n = z->order[k]; + // scan out an mcu's worth of this component; that's just determined + // by the basic H and V specified for the component + for(y = 0; y < z->img_comp[n].v; ++y) { + for(x = 0; x < z->img_comp[n].h; ++x) { + int x2 = (i * z->img_comp[n].h + x) * 8; + int y2 = (j * z->img_comp[n].v + y) * 8; + int ha = z->img_comp[n].ha; + if(!stbi__jpeg_decode_block(z, data, z->huff_dc + z->img_comp[n].hd, z->huff_ac + ha, z->fast_ac[ha], n, + z->dequant[z->img_comp[n].tq])) return 0; + z->idct_block_kernel(z->img_comp[n].data + z->img_comp[n].w2 * y2 + x2, z->img_comp[n].w2, data); + } + } + } + // after all interleaved components, that's an interleaved MCU, + // so now count down the restart interval + if(--z->todo <= 0) { + if(z->code_bits < 24) stbi__grow_buffer_unsafe(z); + if(!STBI__RESTART(z->marker)) return 1; + stbi__jpeg_reset(z); + } + } + } + return 1; + } + } + else { + if(z->scan_n == 1) { + int i, j; + int n = z->order[0]; + // non-interleaved data, we just need to process one block at a time, + // in trivial scanline order + // number of blocks to do just depends on how many actual "pixels" this + // component has, independent of interleaved MCU blocking and such + int w = (z->img_comp[n].x + 7) >> 3; + int h = (z->img_comp[n].y + 7) >> 3; + for(j = 0; j < h; ++j) { + for(i = 0; i < w; ++i) { + short * data = z->img_comp[n].coeff + 64 * (i + j * z->img_comp[n].coeff_w); + if(z->spec_start == 0) { + if(!stbi__jpeg_decode_block_prog_dc(z, data, &z->huff_dc[z->img_comp[n].hd], n)) + return 0; + } + else { + int ha = z->img_comp[n].ha; + if(!stbi__jpeg_decode_block_prog_ac(z, data, &z->huff_ac[ha], z->fast_ac[ha])) + return 0; + } + // every data block is an MCU, so countdown the restart interval + if(--z->todo <= 0) { + if(z->code_bits < 24) stbi__grow_buffer_unsafe(z); + if(!STBI__RESTART(z->marker)) return 1; + stbi__jpeg_reset(z); + } + } + } + return 1; + } + else { // interleaved + int i, j, k, x, y; + for(j = 0; j < z->img_mcu_y; ++j) { + for(i = 0; i < z->img_mcu_x; ++i) { + // scan an interleaved mcu... process scan_n components in order + for(k = 0; k < z->scan_n; ++k) { + int n = z->order[k]; + // scan out an mcu's worth of this component; that's just determined + // by the basic H and V specified for the component + for(y = 0; y < z->img_comp[n].v; ++y) { + for(x = 0; x < z->img_comp[n].h; ++x) { + int x2 = (i * z->img_comp[n].h + x); + int y2 = (j * z->img_comp[n].v + y); + short * data = z->img_comp[n].coeff + 64 * (x2 + y2 * z->img_comp[n].coeff_w); + if(!stbi__jpeg_decode_block_prog_dc(z, data, &z->huff_dc[z->img_comp[n].hd], n)) + return 0; + } + } + } + // after all interleaved components, that's an interleaved MCU, + // so now count down the restart interval + if(--z->todo <= 0) { + if(z->code_bits < 24) stbi__grow_buffer_unsafe(z); + if(!STBI__RESTART(z->marker)) return 1; + stbi__jpeg_reset(z); + } + } + } + return 1; + } + } +} + +static void stbi__jpeg_dequantize(short * data, stbi__uint16 * dequant) +{ + int i; + for(i = 0; i < 64; ++i) + data[i] *= dequant[i]; +} + +static void stbi__jpeg_finish(stbi__jpeg * z) +{ + if(z->progressive) { + // dequantize and idct the data + int i, j, n; + for(n = 0; n < z->s->img_n; ++n) { + int w = (z->img_comp[n].x + 7) >> 3; + int h = (z->img_comp[n].y + 7) >> 3; + for(j = 0; j < h; ++j) { + for(i = 0; i < w; ++i) { + short * data = z->img_comp[n].coeff + 64 * (i + j * z->img_comp[n].coeff_w); + stbi__jpeg_dequantize(data, z->dequant[z->img_comp[n].tq]); + z->idct_block_kernel(z->img_comp[n].data + z->img_comp[n].w2 * j * 8 + i * 8, z->img_comp[n].w2, data); + } + } + } + } +} + +static int stbi__process_marker(stbi__jpeg * z, int m) +{ + int L; + switch(m) { + case STBI__MARKER_none: // no marker found + return stbi__err("expected marker", "Corrupt JPEG"); + + case 0xDD: // DRI - specify restart interval + if(stbi__get16be(z->s) != 4) return stbi__err("bad DRI len", "Corrupt JPEG"); + z->restart_interval = stbi__get16be(z->s); + return 1; + + case 0xDB: // DQT - define quantization table + L = stbi__get16be(z->s) - 2; + while(L > 0) { + int q = stbi__get8(z->s); + int p = q >> 4, sixteen = (p != 0); + int t = q & 15, i; + if(p != 0 && p != 1) return stbi__err("bad DQT type", "Corrupt JPEG"); + if(t > 3) return stbi__err("bad DQT table", "Corrupt JPEG"); + + for(i = 0; i < 64; ++i) + z->dequant[t][stbi__jpeg_dezigzag[i]] = (stbi__uint16)(sixteen ? stbi__get16be(z->s) : stbi__get8(z->s)); + L -= (sixteen ? 129 : 65); + } + return L == 0; + + case 0xC4: // DHT - define huffman table + L = stbi__get16be(z->s) - 2; + while(L > 0) { + stbi_uc * v; + int sizes[16], i, n = 0; + int q = stbi__get8(z->s); + int tc = q >> 4; + int th = q & 15; + if(tc > 1 || th > 3) return stbi__err("bad DHT header", "Corrupt JPEG"); + for(i = 0; i < 16; ++i) { + sizes[i] = stbi__get8(z->s); + n += sizes[i]; + } + if(n > 256) return stbi__err("bad DHT header", "Corrupt JPEG"); // Loop over i < n would write past end of values! + L -= 17; + if(tc == 0) { + if(!stbi__build_huffman(z->huff_dc + th, sizes)) return 0; + v = z->huff_dc[th].values; + } + else { + if(!stbi__build_huffman(z->huff_ac + th, sizes)) return 0; + v = z->huff_ac[th].values; + } + for(i = 0; i < n; ++i) + v[i] = stbi__get8(z->s); + if(tc != 0) + stbi__build_fast_ac(z->fast_ac[th], z->huff_ac + th); + L -= n; + } + return L == 0; + } + + // check for comment block or APP blocks + if((m >= 0xE0 && m <= 0xEF) || m == 0xFE) { + L = stbi__get16be(z->s); + if(L < 2) { + if(m == 0xFE) + return stbi__err("bad COM len", "Corrupt JPEG"); + else + return stbi__err("bad APP len", "Corrupt JPEG"); + } + L -= 2; + + if(m == 0xE0 && L >= 5) { // JFIF APP0 segment + static const unsigned char tag[5] = {'J', 'F', 'I', 'F', '\0'}; + int ok = 1; + int i; + for(i = 0; i < 5; ++i) + if(stbi__get8(z->s) != tag[i]) + ok = 0; + L -= 5; + if(ok) + z->jfif = 1; + } + else if(m == 0xEE && L >= 12) { // Adobe APP14 segment + static const unsigned char tag[6] = {'A', 'd', 'o', 'b', 'e', '\0'}; + int ok = 1; + int i; + for(i = 0; i < 6; ++i) + if(stbi__get8(z->s) != tag[i]) + ok = 0; + L -= 6; + if(ok) { + stbi__get8(z->s); // version + stbi__get16be(z->s); // flags0 + stbi__get16be(z->s); // flags1 + z->app14_color_transform = stbi__get8(z->s); // color transform + L -= 6; + } + } + + stbi__skip(z->s, L); + return 1; + } + + return stbi__err("unknown marker", "Corrupt JPEG"); +} + +// after we see SOS +static int stbi__process_scan_header(stbi__jpeg * z) +{ + int i; + int Ls = stbi__get16be(z->s); + z->scan_n = stbi__get8(z->s); + if(z->scan_n < 1 || z->scan_n > 4 || + z->scan_n > (int) z->s->img_n) return stbi__err("bad SOS component count", "Corrupt JPEG"); + if(Ls != 6 + 2 * z->scan_n) return stbi__err("bad SOS len", "Corrupt JPEG"); + for(i = 0; i < z->scan_n; ++i) { + int id = stbi__get8(z->s), which; + int q = stbi__get8(z->s); + for(which = 0; which < z->s->img_n; ++which) + if(z->img_comp[which].id == id) + break; + if(which == z->s->img_n) return 0; // no match + z->img_comp[which].hd = q >> 4; + if(z->img_comp[which].hd > 3) return stbi__err("bad DC huff", "Corrupt JPEG"); + z->img_comp[which].ha = q & 15; + if(z->img_comp[which].ha > 3) return stbi__err("bad AC huff", "Corrupt JPEG"); + z->order[i] = which; + } + + { + int aa; + z->spec_start = stbi__get8(z->s); + z->spec_end = stbi__get8(z->s); // should be 63, but might be 0 + aa = stbi__get8(z->s); + z->succ_high = (aa >> 4); + z->succ_low = (aa & 15); + if(z->progressive) { + if(z->spec_start > 63 || z->spec_end > 63 || z->spec_start > z->spec_end || z->succ_high > 13 || z->succ_low > 13) + return stbi__err("bad SOS", "Corrupt JPEG"); + } + else { + if(z->spec_start != 0) return stbi__err("bad SOS", "Corrupt JPEG"); + if(z->succ_high != 0 || z->succ_low != 0) return stbi__err("bad SOS", "Corrupt JPEG"); + z->spec_end = 63; + } + } + + return 1; +} + +static int stbi__free_jpeg_components(stbi__jpeg * z, int ncomp, int why) +{ + int i; + for(i = 0; i < ncomp; ++i) { + if(z->img_comp[i].raw_data) { + STBI_FREE(z->img_comp[i].raw_data); + z->img_comp[i].raw_data = NULL; + z->img_comp[i].data = NULL; + } + if(z->img_comp[i].raw_coeff) { + STBI_FREE(z->img_comp[i].raw_coeff); + z->img_comp[i].raw_coeff = 0; + z->img_comp[i].coeff = 0; + } + if(z->img_comp[i].linebuf) { + STBI_FREE(z->img_comp[i].linebuf); + z->img_comp[i].linebuf = NULL; + } + } + return why; +} + +static int stbi__process_frame_header(stbi__jpeg * z, int scan) +{ + stbi__context * s = z->s; + int Lf, p, i, q, h_max = 1, v_max = 1, c; + Lf = stbi__get16be(s); + if(Lf < 11) return stbi__err("bad SOF len", "Corrupt JPEG"); // JPEG + p = stbi__get8(s); + if(p != 8) return stbi__err("only 8-bit", "JPEG format not supported: 8-bit only"); // JPEG baseline + s->img_y = stbi__get16be(s); + if(s->img_y == 0) return stbi__err("no header height", + "JPEG format not supported: delayed height"); // Legal, but we don't handle it--but neither does IJG + s->img_x = stbi__get16be(s); + if(s->img_x == 0) return stbi__err("0 width", "Corrupt JPEG"); // JPEG requires + if(s->img_y > STBI_MAX_DIMENSIONS) return stbi__err("too large", "Very large image (corrupt?)"); + if(s->img_x > STBI_MAX_DIMENSIONS) return stbi__err("too large", "Very large image (corrupt?)"); + c = stbi__get8(s); + if(c != 3 && c != 1 && c != 4) return stbi__err("bad component count", "Corrupt JPEG"); + s->img_n = c; + for(i = 0; i < c; ++i) { + z->img_comp[i].data = NULL; + z->img_comp[i].linebuf = NULL; + } + + if(Lf != 8 + 3 * s->img_n) return stbi__err("bad SOF len", "Corrupt JPEG"); + + z->rgb = 0; + for(i = 0; i < s->img_n; ++i) { + static const unsigned char rgb[3] = { 'R', 'G', 'B' }; + z->img_comp[i].id = stbi__get8(s); + if(s->img_n == 3 && z->img_comp[i].id == rgb[i]) + ++z->rgb; + q = stbi__get8(s); + z->img_comp[i].h = (q >> 4); + if(!z->img_comp[i].h || z->img_comp[i].h > 4) return stbi__err("bad H", "Corrupt JPEG"); + z->img_comp[i].v = q & 15; + if(!z->img_comp[i].v || z->img_comp[i].v > 4) return stbi__err("bad V", "Corrupt JPEG"); + z->img_comp[i].tq = stbi__get8(s); + if(z->img_comp[i].tq > 3) return stbi__err("bad TQ", "Corrupt JPEG"); + } + + if(scan != STBI__SCAN_load) return 1; + + if(!stbi__mad3sizes_valid(s->img_x, s->img_y, s->img_n, 0)) return stbi__err("too large", "Image too large to decode"); + + for(i = 0; i < s->img_n; ++i) { + if(z->img_comp[i].h > h_max) h_max = z->img_comp[i].h; + if(z->img_comp[i].v > v_max) v_max = z->img_comp[i].v; + } + + // check that plane subsampling factors are integer ratios; our resamplers can't deal with fractional ratios + // and I've never seen a non-corrupted JPEG file actually use them + for(i = 0; i < s->img_n; ++i) { + if(h_max % z->img_comp[i].h != 0) return stbi__err("bad H", "Corrupt JPEG"); + if(v_max % z->img_comp[i].v != 0) return stbi__err("bad V", "Corrupt JPEG"); + } + + // compute interleaved mcu info + z->img_h_max = h_max; + z->img_v_max = v_max; + z->img_mcu_w = h_max * 8; + z->img_mcu_h = v_max * 8; + // these sizes can't be more than 17 bits + z->img_mcu_x = (s->img_x + z->img_mcu_w - 1) / z->img_mcu_w; + z->img_mcu_y = (s->img_y + z->img_mcu_h - 1) / z->img_mcu_h; + + for(i = 0; i < s->img_n; ++i) { + // number of effective pixels (e.g. for non-interleaved MCU) + z->img_comp[i].x = (s->img_x * z->img_comp[i].h + h_max - 1) / h_max; + z->img_comp[i].y = (s->img_y * z->img_comp[i].v + v_max - 1) / v_max; + // to simplify generation, we'll allocate enough memory to decode + // the bogus oversized data from using interleaved MCUs and their + // big blocks (e.g. a 16x16 iMCU on an image of width 33); we won't + // discard the extra data until colorspace conversion + // + // img_mcu_x, img_mcu_y: <=17 bits; comp[i].h and .v are <=4 (checked earlier) + // so these muls can't overflow with 32-bit ints (which we require) + z->img_comp[i].w2 = z->img_mcu_x * z->img_comp[i].h * 8; + z->img_comp[i].h2 = z->img_mcu_y * z->img_comp[i].v * 8; + z->img_comp[i].coeff = 0; + z->img_comp[i].raw_coeff = 0; + z->img_comp[i].linebuf = NULL; + z->img_comp[i].raw_data = stbi__malloc_mad2(z->img_comp[i].w2, z->img_comp[i].h2, 15); + if(z->img_comp[i].raw_data == NULL) + return stbi__free_jpeg_components(z, i + 1, stbi__err("outofmem", "Out of memory")); + // align blocks for idct using mmx/sse + z->img_comp[i].data = (stbi_uc *)(((size_t) z->img_comp[i].raw_data + 15) & ~15); + if(z->progressive) { + // w2, h2 are multiples of 8 (see above) + z->img_comp[i].coeff_w = z->img_comp[i].w2 / 8; + z->img_comp[i].coeff_h = z->img_comp[i].h2 / 8; + z->img_comp[i].raw_coeff = stbi__malloc_mad3(z->img_comp[i].w2, z->img_comp[i].h2, sizeof(short), 15); + if(z->img_comp[i].raw_coeff == NULL) + return stbi__free_jpeg_components(z, i + 1, stbi__err("outofmem", "Out of memory")); + z->img_comp[i].coeff = (short *)(((size_t) z->img_comp[i].raw_coeff + 15) & ~15); + } + } + + return 1; +} + +// use comparisons since in some cases we handle more than one case (e.g. SOF) +#define stbi__DNL(x) ((x) == 0xdc) +#define stbi__SOI(x) ((x) == 0xd8) +#define stbi__EOI(x) ((x) == 0xd9) +#define stbi__SOF(x) ((x) == 0xc0 || (x) == 0xc1 || (x) == 0xc2) +#define stbi__SOS(x) ((x) == 0xda) + +#define stbi__SOF_progressive(x) ((x) == 0xc2) + +static int stbi__decode_jpeg_header(stbi__jpeg * z, int scan) +{ + int m; + z->jfif = 0; + z->app14_color_transform = -1; // valid values are 0,1,2 + z->marker = STBI__MARKER_none; // initialize cached marker to empty + m = stbi__get_marker(z); + if(!stbi__SOI(m)) return stbi__err("no SOI", "Corrupt JPEG"); + if(scan == STBI__SCAN_type) return 1; + m = stbi__get_marker(z); + while(!stbi__SOF(m)) { + if(!stbi__process_marker(z, m)) return 0; + m = stbi__get_marker(z); + while(m == STBI__MARKER_none) { + // some files have extra padding after their blocks, so ok, we'll scan + if(stbi__at_eof(z->s)) return stbi__err("no SOF", "Corrupt JPEG"); + m = stbi__get_marker(z); + } + } + z->progressive = stbi__SOF_progressive(m); + if(!stbi__process_frame_header(z, scan)) return 0; + return 1; +} + +static stbi_uc stbi__skip_jpeg_junk_at_end(stbi__jpeg * j) +{ + // some JPEGs have junk at end, skip over it but if we find what looks + // like a valid marker, resume there + while(!stbi__at_eof(j->s)) { + stbi_uc x = stbi__get8(j->s); + while(x == 0xff) { // might be a marker + if(stbi__at_eof(j->s)) return STBI__MARKER_none; + x = stbi__get8(j->s); + if(x != 0x00 && x != 0xff) { + // not a stuffed zero or lead-in to another marker, looks + // like an actual marker, return it + return x; + } + // stuffed zero has x=0 now which ends the loop, meaning we go + // back to regular scan loop. + // repeated 0xff keeps trying to read the next byte of the marker. + } + } + return STBI__MARKER_none; +} + +// decode image to YCbCr format +static int stbi__decode_jpeg_image(stbi__jpeg * j) +{ + int m; + for(m = 0; m < 4; m++) { + j->img_comp[m].raw_data = NULL; + j->img_comp[m].raw_coeff = NULL; + } + j->restart_interval = 0; + if(!stbi__decode_jpeg_header(j, STBI__SCAN_load)) return 0; + m = stbi__get_marker(j); + while(!stbi__EOI(m)) { + if(stbi__SOS(m)) { + if(!stbi__process_scan_header(j)) return 0; + if(!stbi__parse_entropy_coded_data(j)) return 0; + if(j->marker == STBI__MARKER_none) { + j->marker = stbi__skip_jpeg_junk_at_end(j); + // if we reach eof without hitting a marker, stbi__get_marker() below will fail and we'll eventually return 0 + } + m = stbi__get_marker(j); + if(STBI__RESTART(m)) + m = stbi__get_marker(j); + } + else if(stbi__DNL(m)) { + int Ld = stbi__get16be(j->s); + stbi__uint32 NL = stbi__get16be(j->s); + if(Ld != 4) return stbi__err("bad DNL len", "Corrupt JPEG"); + if(NL != j->s->img_y) return stbi__err("bad DNL height", "Corrupt JPEG"); + m = stbi__get_marker(j); + } + else { + if(!stbi__process_marker(j, m)) return 1; + m = stbi__get_marker(j); + } + } + if(j->progressive) + stbi__jpeg_finish(j); + return 1; +} + +// static jfif-centered resampling (across block boundaries) + +typedef stbi_uc * (*resample_row_func)(stbi_uc * out, stbi_uc * in0, stbi_uc * in1, + int w, int hs); + +#define stbi__div4(x) ((stbi_uc) ((x) >> 2)) + +static stbi_uc * resample_row_1(stbi_uc * out, stbi_uc * in_near, stbi_uc * in_far, int w, int hs) +{ + STBI_NOTUSED(out); + STBI_NOTUSED(in_far); + STBI_NOTUSED(w); + STBI_NOTUSED(hs); + return in_near; +} + +static stbi_uc * stbi__resample_row_v_2(stbi_uc * out, stbi_uc * in_near, stbi_uc * in_far, int w, int hs) +{ + // need to generate two samples vertically for every one in input + int i; + STBI_NOTUSED(hs); + for(i = 0; i < w; ++i) + out[i] = stbi__div4(3 * in_near[i] + in_far[i] + 2); + return out; +} + +static stbi_uc * stbi__resample_row_h_2(stbi_uc * out, stbi_uc * in_near, stbi_uc * in_far, int w, int hs) +{ + // need to generate two samples horizontally for every one in input + int i; + stbi_uc * input = in_near; + + if(w == 1) { + // if only one sample, can't do any interpolation + out[0] = out[1] = input[0]; + return out; + } + + out[0] = input[0]; + out[1] = stbi__div4(input[0] * 3 + input[1] + 2); + for(i = 1; i < w - 1; ++i) { + int n = 3 * input[i] + 2; + out[i * 2 + 0] = stbi__div4(n + input[i - 1]); + out[i * 2 + 1] = stbi__div4(n + input[i + 1]); + } + out[i * 2 + 0] = stbi__div4(input[w - 2] * 3 + input[w - 1] + 2); + out[i * 2 + 1] = input[w - 1]; + + STBI_NOTUSED(in_far); + STBI_NOTUSED(hs); + + return out; +} + +#define stbi__div16(x) ((stbi_uc) ((x) >> 4)) + +static stbi_uc * stbi__resample_row_hv_2(stbi_uc * out, stbi_uc * in_near, stbi_uc * in_far, int w, int hs) +{ + // need to generate 2x2 samples for every one in input + int i, t0, t1; + if(w == 1) { + out[0] = out[1] = stbi__div4(3 * in_near[0] + in_far[0] + 2); + return out; + } + + t1 = 3 * in_near[0] + in_far[0]; + out[0] = stbi__div4(t1 + 2); + for(i = 1; i < w; ++i) { + t0 = t1; + t1 = 3 * in_near[i] + in_far[i]; + out[i * 2 - 1] = stbi__div16(3 * t0 + t1 + 8); + out[i * 2 ] = stbi__div16(3 * t1 + t0 + 8); + } + out[w * 2 - 1] = stbi__div4(t1 + 2); + + STBI_NOTUSED(hs); + + return out; +} + +#if defined(STBI_SSE2) || defined(STBI_NEON) +static stbi_uc * stbi__resample_row_hv_2_simd(stbi_uc * out, stbi_uc * in_near, stbi_uc * in_far, int w, int hs) +{ + // need to generate 2x2 samples for every one in input + int i = 0, t0, t1; + + if(w == 1) { + out[0] = out[1] = stbi__div4(3 * in_near[0] + in_far[0] + 2); + return out; + } + + t1 = 3 * in_near[0] + in_far[0]; + // process groups of 8 pixels for as long as we can. + // note we can't handle the last pixel in a row in this loop + // because we need to handle the filter boundary conditions. + for(; i < ((w - 1) & ~7); i += 8) { +#if defined(STBI_SSE2) + // load and perform the vertical filtering pass + // this uses 3*x + y = 4*x + (y - x) + __m128i zero = _mm_setzero_si128(); + __m128i farb = _mm_loadl_epi64((__m128i *)(in_far + i)); + __m128i nearb = _mm_loadl_epi64((__m128i *)(in_near + i)); + __m128i farw = _mm_unpacklo_epi8(farb, zero); + __m128i nearw = _mm_unpacklo_epi8(nearb, zero); + __m128i diff = _mm_sub_epi16(farw, nearw); + __m128i nears = _mm_slli_epi16(nearw, 2); + __m128i curr = _mm_add_epi16(nears, diff); // current row + + // horizontal filter works the same based on shifted vers of current + // row. "prev" is current row shifted right by 1 pixel; we need to + // insert the previous pixel value (from t1). + // "next" is current row shifted left by 1 pixel, with first pixel + // of next block of 8 pixels added in. + __m128i prv0 = _mm_slli_si128(curr, 2); + __m128i nxt0 = _mm_srli_si128(curr, 2); + __m128i prev = _mm_insert_epi16(prv0, t1, 0); + __m128i next = _mm_insert_epi16(nxt0, 3 * in_near[i + 8] + in_far[i + 8], 7); + + // horizontal filter, polyphase implementation since it's convenient: + // even pixels = 3*cur + prev = cur*4 + (prev - cur) + // odd pixels = 3*cur + next = cur*4 + (next - cur) + // note the shared term. + __m128i bias = _mm_set1_epi16(8); + __m128i curs = _mm_slli_epi16(curr, 2); + __m128i prvd = _mm_sub_epi16(prev, curr); + __m128i nxtd = _mm_sub_epi16(next, curr); + __m128i curb = _mm_add_epi16(curs, bias); + __m128i even = _mm_add_epi16(prvd, curb); + __m128i odd = _mm_add_epi16(nxtd, curb); + + // interleave even and odd pixels, then undo scaling. + __m128i int0 = _mm_unpacklo_epi16(even, odd); + __m128i int1 = _mm_unpackhi_epi16(even, odd); + __m128i de0 = _mm_srli_epi16(int0, 4); + __m128i de1 = _mm_srli_epi16(int1, 4); + + // pack and write output + __m128i outv = _mm_packus_epi16(de0, de1); + _mm_storeu_si128((__m128i *)(out + i * 2), outv); +#elif defined(STBI_NEON) + // load and perform the vertical filtering pass + // this uses 3*x + y = 4*x + (y - x) + uint8x8_t farb = vld1_u8(in_far + i); + uint8x8_t nearb = vld1_u8(in_near + i); + int16x8_t diff = vreinterpretq_s16_u16(vsubl_u8(farb, nearb)); + int16x8_t nears = vreinterpretq_s16_u16(vshll_n_u8(nearb, 2)); + int16x8_t curr = vaddq_s16(nears, diff); // current row + + // horizontal filter works the same based on shifted vers of current + // row. "prev" is current row shifted right by 1 pixel; we need to + // insert the previous pixel value (from t1). + // "next" is current row shifted left by 1 pixel, with first pixel + // of next block of 8 pixels added in. + int16x8_t prv0 = vextq_s16(curr, curr, 7); + int16x8_t nxt0 = vextq_s16(curr, curr, 1); + int16x8_t prev = vsetq_lane_s16(t1, prv0, 0); + int16x8_t next = vsetq_lane_s16(3 * in_near[i + 8] + in_far[i + 8], nxt0, 7); + + // horizontal filter, polyphase implementation since it's convenient: + // even pixels = 3*cur + prev = cur*4 + (prev - cur) + // odd pixels = 3*cur + next = cur*4 + (next - cur) + // note the shared term. + int16x8_t curs = vshlq_n_s16(curr, 2); + int16x8_t prvd = vsubq_s16(prev, curr); + int16x8_t nxtd = vsubq_s16(next, curr); + int16x8_t even = vaddq_s16(curs, prvd); + int16x8_t odd = vaddq_s16(curs, nxtd); + + // undo scaling and round, then store with even/odd phases interleaved + uint8x8x2_t o; + o.val[0] = vqrshrun_n_s16(even, 4); + o.val[1] = vqrshrun_n_s16(odd, 4); + vst2_u8(out + i * 2, o); +#endif + + // "previous" value for next iter + t1 = 3 * in_near[i + 7] + in_far[i + 7]; + } + + t0 = t1; + t1 = 3 * in_near[i] + in_far[i]; + out[i * 2] = stbi__div16(3 * t1 + t0 + 8); + + for(++i; i < w; ++i) { + t0 = t1; + t1 = 3 * in_near[i] + in_far[i]; + out[i * 2 - 1] = stbi__div16(3 * t0 + t1 + 8); + out[i * 2 ] = stbi__div16(3 * t1 + t0 + 8); + } + out[w * 2 - 1] = stbi__div4(t1 + 2); + + STBI_NOTUSED(hs); + + return out; +} +#endif + +static stbi_uc * stbi__resample_row_generic(stbi_uc * out, stbi_uc * in_near, stbi_uc * in_far, int w, int hs) +{ + // resample with nearest-neighbor + int i, j; + STBI_NOTUSED(in_far); + for(i = 0; i < w; ++i) + for(j = 0; j < hs; ++j) + out[i * hs + j] = in_near[i]; + return out; +} + +// this is a reduced-precision calculation of YCbCr-to-RGB introduced +// to make sure the code produces the same results in both SIMD and scalar +#define stbi__float2fixed(x) (((int) ((x) * 4096.0f + 0.5f)) << 8) +static void stbi__YCbCr_to_RGB_row(stbi_uc * out, const stbi_uc * y, const stbi_uc * pcb, const stbi_uc * pcr, + int count, int step) +{ + int i; + for(i = 0; i < count; ++i) { + int y_fixed = (y[i] << 20) + (1 << 19); // rounding + int r, g, b; + int cr = pcr[i] - 128; + int cb = pcb[i] - 128; + r = y_fixed + cr * stbi__float2fixed(1.40200f); + g = y_fixed + (cr * -stbi__float2fixed(0.71414f)) + ((cb * -stbi__float2fixed(0.34414f)) & 0xffff0000); + b = y_fixed + cb * stbi__float2fixed(1.77200f); + r >>= 20; + g >>= 20; + b >>= 20; + if((unsigned) r > 255) { + if(r < 0) r = 0; + else r = 255; + } + if((unsigned) g > 255) { + if(g < 0) g = 0; + else g = 255; + } + if((unsigned) b > 255) { + if(b < 0) b = 0; + else b = 255; + } + out[0] = (stbi_uc)r; + out[1] = (stbi_uc)g; + out[2] = (stbi_uc)b; + out[3] = 255; + out += step; + } +} + +#if defined(STBI_SSE2) || defined(STBI_NEON) +static void stbi__YCbCr_to_RGB_simd(stbi_uc * out, stbi_uc const * y, stbi_uc const * pcb, stbi_uc const * pcr, + int count, int step) +{ + int i = 0; + +#ifdef STBI_SSE2 + // step == 3 is pretty ugly on the final interleave, and i'm not convinced + // it's useful in practice (you wouldn't use it for textures, for example). + // so just accelerate step == 4 case. + if(step == 4) { + // this is a fairly straightforward implementation and not super-optimized. + __m128i signflip = _mm_set1_epi8(-0x80); + __m128i cr_const0 = _mm_set1_epi16((short)(1.40200f * 4096.0f + 0.5f)); + __m128i cr_const1 = _mm_set1_epi16(- (short)(0.71414f * 4096.0f + 0.5f)); + __m128i cb_const0 = _mm_set1_epi16(- (short)(0.34414f * 4096.0f + 0.5f)); + __m128i cb_const1 = _mm_set1_epi16((short)(1.77200f * 4096.0f + 0.5f)); + __m128i y_bias = _mm_set1_epi8((char)(unsigned char) 128); + __m128i xw = _mm_set1_epi16(255); // alpha channel + + for(; i + 7 < count; i += 8) { + // load + __m128i y_bytes = _mm_loadl_epi64((__m128i *)(y + i)); + __m128i cr_bytes = _mm_loadl_epi64((__m128i *)(pcr + i)); + __m128i cb_bytes = _mm_loadl_epi64((__m128i *)(pcb + i)); + __m128i cr_biased = _mm_xor_si128(cr_bytes, signflip); // -128 + __m128i cb_biased = _mm_xor_si128(cb_bytes, signflip); // -128 + + // unpack to short (and left-shift cr, cb by 8) + __m128i yw = _mm_unpacklo_epi8(y_bias, y_bytes); + __m128i crw = _mm_unpacklo_epi8(_mm_setzero_si128(), cr_biased); + __m128i cbw = _mm_unpacklo_epi8(_mm_setzero_si128(), cb_biased); + + // color transform + __m128i yws = _mm_srli_epi16(yw, 4); + __m128i cr0 = _mm_mulhi_epi16(cr_const0, crw); + __m128i cb0 = _mm_mulhi_epi16(cb_const0, cbw); + __m128i cb1 = _mm_mulhi_epi16(cbw, cb_const1); + __m128i cr1 = _mm_mulhi_epi16(crw, cr_const1); + __m128i rws = _mm_add_epi16(cr0, yws); + __m128i gwt = _mm_add_epi16(cb0, yws); + __m128i bws = _mm_add_epi16(yws, cb1); + __m128i gws = _mm_add_epi16(gwt, cr1); + + // descale + __m128i rw = _mm_srai_epi16(rws, 4); + __m128i bw = _mm_srai_epi16(bws, 4); + __m128i gw = _mm_srai_epi16(gws, 4); + + // back to byte, set up for transpose + __m128i brb = _mm_packus_epi16(rw, bw); + __m128i gxb = _mm_packus_epi16(gw, xw); + + // transpose to interleave channels + __m128i t0 = _mm_unpacklo_epi8(brb, gxb); + __m128i t1 = _mm_unpackhi_epi8(brb, gxb); + __m128i o0 = _mm_unpacklo_epi16(t0, t1); + __m128i o1 = _mm_unpackhi_epi16(t0, t1); + + // store + _mm_storeu_si128((__m128i *)(out + 0), o0); + _mm_storeu_si128((__m128i *)(out + 16), o1); + out += 32; + } + } +#endif + +#ifdef STBI_NEON + // in this version, step=3 support would be easy to add. but is there demand? + if(step == 4) { + // this is a fairly straightforward implementation and not super-optimized. + uint8x8_t signflip = vdup_n_u8(0x80); + int16x8_t cr_const0 = vdupq_n_s16((short)(1.40200f * 4096.0f + 0.5f)); + int16x8_t cr_const1 = vdupq_n_s16(- (short)(0.71414f * 4096.0f + 0.5f)); + int16x8_t cb_const0 = vdupq_n_s16(- (short)(0.34414f * 4096.0f + 0.5f)); + int16x8_t cb_const1 = vdupq_n_s16((short)(1.77200f * 4096.0f + 0.5f)); + + for(; i + 7 < count; i += 8) { + // load + uint8x8_t y_bytes = vld1_u8(y + i); + uint8x8_t cr_bytes = vld1_u8(pcr + i); + uint8x8_t cb_bytes = vld1_u8(pcb + i); + int8x8_t cr_biased = vreinterpret_s8_u8(vsub_u8(cr_bytes, signflip)); + int8x8_t cb_biased = vreinterpret_s8_u8(vsub_u8(cb_bytes, signflip)); + + // expand to s16 + int16x8_t yws = vreinterpretq_s16_u16(vshll_n_u8(y_bytes, 4)); + int16x8_t crw = vshll_n_s8(cr_biased, 7); + int16x8_t cbw = vshll_n_s8(cb_biased, 7); + + // color transform + int16x8_t cr0 = vqdmulhq_s16(crw, cr_const0); + int16x8_t cb0 = vqdmulhq_s16(cbw, cb_const0); + int16x8_t cr1 = vqdmulhq_s16(crw, cr_const1); + int16x8_t cb1 = vqdmulhq_s16(cbw, cb_const1); + int16x8_t rws = vaddq_s16(yws, cr0); + int16x8_t gws = vaddq_s16(vaddq_s16(yws, cb0), cr1); + int16x8_t bws = vaddq_s16(yws, cb1); + + // undo scaling, round, convert to byte + uint8x8x4_t o; + o.val[0] = vqrshrun_n_s16(rws, 4); + o.val[1] = vqrshrun_n_s16(gws, 4); + o.val[2] = vqrshrun_n_s16(bws, 4); + o.val[3] = vdup_n_u8(255); + + // store, interleaving r/g/b/a + vst4_u8(out, o); + out += 8 * 4; + } + } +#endif + + for(; i < count; ++i) { + int y_fixed = (y[i] << 20) + (1 << 19); // rounding + int r, g, b; + int cr = pcr[i] - 128; + int cb = pcb[i] - 128; + r = y_fixed + cr * stbi__float2fixed(1.40200f); + g = y_fixed + cr * -stbi__float2fixed(0.71414f) + ((cb * -stbi__float2fixed(0.34414f)) & 0xffff0000); + b = y_fixed + cb * stbi__float2fixed(1.77200f); + r >>= 20; + g >>= 20; + b >>= 20; + if((unsigned) r > 255) { + if(r < 0) r = 0; + else r = 255; + } + if((unsigned) g > 255) { + if(g < 0) g = 0; + else g = 255; + } + if((unsigned) b > 255) { + if(b < 0) b = 0; + else b = 255; + } + out[0] = (stbi_uc)r; + out[1] = (stbi_uc)g; + out[2] = (stbi_uc)b; + out[3] = 255; + out += step; + } +} +#endif + +// set up the kernels +static void stbi__setup_jpeg(stbi__jpeg * j) +{ + j->idct_block_kernel = stbi__idct_block; + j->YCbCr_to_RGB_kernel = stbi__YCbCr_to_RGB_row; + j->resample_row_hv_2_kernel = stbi__resample_row_hv_2; + +#ifdef STBI_SSE2 + if(stbi__sse2_available()) { + j->idct_block_kernel = stbi__idct_simd; + j->YCbCr_to_RGB_kernel = stbi__YCbCr_to_RGB_simd; + j->resample_row_hv_2_kernel = stbi__resample_row_hv_2_simd; + } +#endif + +#ifdef STBI_NEON + j->idct_block_kernel = stbi__idct_simd; + j->YCbCr_to_RGB_kernel = stbi__YCbCr_to_RGB_simd; + j->resample_row_hv_2_kernel = stbi__resample_row_hv_2_simd; +#endif +} + +// clean up the temporary component buffers +static void stbi__cleanup_jpeg(stbi__jpeg * j) +{ + stbi__free_jpeg_components(j, j->s->img_n, 0); +} + +typedef struct { + resample_row_func resample; + stbi_uc * line0, * line1; + int hs, vs; // expansion factor in each axis + int w_lores; // horizontal pixels pre-expansion + int ystep; // how far through vertical expansion we are + int ypos; // which pre-expansion row we're on +} stbi__resample; + +// fast 0..255 * 0..255 => 0..255 rounded multiplication +static stbi_uc stbi__blinn_8x8(stbi_uc x, stbi_uc y) +{ + unsigned int t = x * y + 128; + return (stbi_uc)((t + (t >> 8)) >> 8); +} + +static stbi_uc * load_jpeg_image(stbi__jpeg * z, int * out_x, int * out_y, int * comp, int req_comp) +{ + int n, decode_n, is_rgb; + z->s->img_n = 0; // make stbi__cleanup_jpeg safe + + // validate req_comp + if(req_comp < 0 || req_comp > 4) return stbi__errpuc("bad req_comp", "Internal error"); + + // load a jpeg image from whichever source, but leave in YCbCr format + if(!stbi__decode_jpeg_image(z)) { + stbi__cleanup_jpeg(z); + return NULL; + } + + // determine actual number of components to generate + n = req_comp ? req_comp : z->s->img_n >= 3 ? 3 : 1; + + is_rgb = z->s->img_n == 3 && (z->rgb == 3 || (z->app14_color_transform == 0 && !z->jfif)); + + if(z->s->img_n == 3 && n < 3 && !is_rgb) + decode_n = 1; + else + decode_n = z->s->img_n; + + // nothing to do if no components requested; check this now to avoid + // accessing uninitialized coutput[0] later + if(decode_n <= 0) { + stbi__cleanup_jpeg(z); + return NULL; + } + + // resample and color-convert + { + int k; + unsigned int i, j; + stbi_uc * output; + stbi_uc * coutput[4] = { NULL, NULL, NULL, NULL }; + + stbi__resample res_comp[4]; + + for(k = 0; k < decode_n; ++k) { + stbi__resample * r = &res_comp[k]; + + // allocate line buffer big enough for upsampling off the edges + // with upsample factor of 4 + z->img_comp[k].linebuf = (stbi_uc *) stbi__malloc(z->s->img_x + 3); + if(!z->img_comp[k].linebuf) { + stbi__cleanup_jpeg(z); + return stbi__errpuc("outofmem", "Out of memory"); + } + + r->hs = z->img_h_max / z->img_comp[k].h; + r->vs = z->img_v_max / z->img_comp[k].v; + r->ystep = r->vs >> 1; + r->w_lores = (z->s->img_x + r->hs - 1) / r->hs; + r->ypos = 0; + r->line0 = r->line1 = z->img_comp[k].data; + + if(r->hs == 1 && r->vs == 1) r->resample = resample_row_1; + else if(r->hs == 1 && r->vs == 2) r->resample = stbi__resample_row_v_2; + else if(r->hs == 2 && r->vs == 1) r->resample = stbi__resample_row_h_2; + else if(r->hs == 2 && r->vs == 2) r->resample = z->resample_row_hv_2_kernel; + else r->resample = stbi__resample_row_generic; + } + + // can't error after this so, this is safe + output = (stbi_uc *) stbi__malloc_mad3(n, z->s->img_x, z->s->img_y, 1); + if(!output) { + stbi__cleanup_jpeg(z); + return stbi__errpuc("outofmem", "Out of memory"); + } + + // now go ahead and resample + for(j = 0; j < z->s->img_y; ++j) { + stbi_uc * out = output + n * z->s->img_x * j; + for(k = 0; k < decode_n; ++k) { + stbi__resample * r = &res_comp[k]; + int y_bot = r->ystep >= (r->vs >> 1); + coutput[k] = r->resample(z->img_comp[k].linebuf, + y_bot ? r->line1 : r->line0, + y_bot ? r->line0 : r->line1, + r->w_lores, r->hs); + if(++r->ystep >= r->vs) { + r->ystep = 0; + r->line0 = r->line1; + if(++r->ypos < z->img_comp[k].y) + r->line1 += z->img_comp[k].w2; + } + } + if(n >= 3) { + stbi_uc * y = coutput[0]; + if(z->s->img_n == 3) { + if(is_rgb) { + for(i = 0; i < z->s->img_x; ++i) { + out[0] = y[i]; + out[1] = coutput[1][i]; + out[2] = coutput[2][i]; + out[3] = 255; + out += n; + } + } + else { + z->YCbCr_to_RGB_kernel(out, y, coutput[1], coutput[2], z->s->img_x, n); + } + } + else if(z->s->img_n == 4) { + if(z->app14_color_transform == 0) { // CMYK + for(i = 0; i < z->s->img_x; ++i) { + stbi_uc m = coutput[3][i]; + out[0] = stbi__blinn_8x8(coutput[0][i], m); + out[1] = stbi__blinn_8x8(coutput[1][i], m); + out[2] = stbi__blinn_8x8(coutput[2][i], m); + out[3] = 255; + out += n; + } + } + else if(z->app14_color_transform == 2) { // YCCK + z->YCbCr_to_RGB_kernel(out, y, coutput[1], coutput[2], z->s->img_x, n); + for(i = 0; i < z->s->img_x; ++i) { + stbi_uc m = coutput[3][i]; + out[0] = stbi__blinn_8x8(255 - out[0], m); + out[1] = stbi__blinn_8x8(255 - out[1], m); + out[2] = stbi__blinn_8x8(255 - out[2], m); + out += n; + } + } + else { // YCbCr + alpha? Ignore the fourth channel for now + z->YCbCr_to_RGB_kernel(out, y, coutput[1], coutput[2], z->s->img_x, n); + } + } + else + for(i = 0; i < z->s->img_x; ++i) { + out[0] = out[1] = out[2] = y[i]; + out[3] = 255; // not used if n==3 + out += n; + } + } + else { + if(is_rgb) { + if(n == 1) + for(i = 0; i < z->s->img_x; ++i) + *out++ = stbi__compute_y(coutput[0][i], coutput[1][i], coutput[2][i]); + else { + for(i = 0; i < z->s->img_x; ++i, out += 2) { + out[0] = stbi__compute_y(coutput[0][i], coutput[1][i], coutput[2][i]); + out[1] = 255; + } + } + } + else if(z->s->img_n == 4 && z->app14_color_transform == 0) { + for(i = 0; i < z->s->img_x; ++i) { + stbi_uc m = coutput[3][i]; + stbi_uc r = stbi__blinn_8x8(coutput[0][i], m); + stbi_uc g = stbi__blinn_8x8(coutput[1][i], m); + stbi_uc b = stbi__blinn_8x8(coutput[2][i], m); + out[0] = stbi__compute_y(r, g, b); + out[1] = 255; + out += n; + } + } + else if(z->s->img_n == 4 && z->app14_color_transform == 2) { + for(i = 0; i < z->s->img_x; ++i) { + out[0] = stbi__blinn_8x8(255 - coutput[0][i], coutput[3][i]); + out[1] = 255; + out += n; + } + } + else { + stbi_uc * y = coutput[0]; + if(n == 1) + for(i = 0; i < z->s->img_x; ++i) out[i] = y[i]; + else + for(i = 0; i < z->s->img_x; ++i) { + *out++ = y[i]; + *out++ = 255; + } + } + } + } + stbi__cleanup_jpeg(z); + *out_x = z->s->img_x; + *out_y = z->s->img_y; + if(comp) *comp = z->s->img_n >= 3 ? 3 : 1; // report original components, not output + return output; + } +} + +static void * stbi__jpeg_load(stbi__context * s, int * x, int * y, int * comp, int req_comp, stbi__result_info * ri) +{ + unsigned char * result; + stbi__jpeg * j = (stbi__jpeg *) stbi__malloc(sizeof(stbi__jpeg)); + if(!j) return stbi__errpuc("outofmem", "Out of memory"); + memset(j, 0, sizeof(stbi__jpeg)); + STBI_NOTUSED(ri); + j->s = s; + stbi__setup_jpeg(j); + result = load_jpeg_image(j, x, y, comp, req_comp); + STBI_FREE(j); + return result; +} + +static int stbi__jpeg_test(stbi__context * s) +{ + int r; + stbi__jpeg * j = (stbi__jpeg *)stbi__malloc(sizeof(stbi__jpeg)); + if(!j) return stbi__err("outofmem", "Out of memory"); + memset(j, 0, sizeof(stbi__jpeg)); + j->s = s; + stbi__setup_jpeg(j); + r = stbi__decode_jpeg_header(j, STBI__SCAN_type); + stbi__rewind(s); + STBI_FREE(j); + return r; +} + +static int stbi__jpeg_info_raw(stbi__jpeg * j, int * x, int * y, int * comp) +{ + if(!stbi__decode_jpeg_header(j, STBI__SCAN_header)) { + stbi__rewind(j->s); + return 0; + } + if(x) *x = j->s->img_x; + if(y) *y = j->s->img_y; + if(comp) *comp = j->s->img_n >= 3 ? 3 : 1; + return 1; +} + +static int stbi__jpeg_info(stbi__context * s, int * x, int * y, int * comp) +{ + int result; + stbi__jpeg * j = (stbi__jpeg *)(stbi__malloc(sizeof(stbi__jpeg))); + if(!j) return stbi__err("outofmem", "Out of memory"); + memset(j, 0, sizeof(stbi__jpeg)); + j->s = s; + result = stbi__jpeg_info_raw(j, x, y, comp); + STBI_FREE(j); + return result; +} +#endif + +// public domain zlib decode v0.2 Sean Barrett 2006-11-18 +// simple implementation +// - all input must be provided in an upfront buffer +// - all output is written to a single output buffer (can malloc/realloc) +// performance +// - fast huffman + +#ifndef STBI_NO_ZLIB + +// fast-way is faster to check than jpeg huffman, but slow way is slower +#define STBI__ZFAST_BITS 9 // accelerate all cases in default tables +#define STBI__ZFAST_MASK ((1 << STBI__ZFAST_BITS) - 1) +#define STBI__ZNSYMS 288 // number of symbols in literal/length alphabet + +// zlib-style huffman encoding +// (jpegs packs from left, zlib from right, so can't share code) +typedef struct { + stbi__uint16 fast[1 << STBI__ZFAST_BITS]; + stbi__uint16 firstcode[16]; + int maxcode[17]; + stbi__uint16 firstsymbol[16]; + stbi_uc size[STBI__ZNSYMS]; + stbi__uint16 value[STBI__ZNSYMS]; +} stbi__zhuffman; + +stbi_inline static int stbi__bitreverse16(int n) +{ + n = ((n & 0xAAAA) >> 1) | ((n & 0x5555) << 1); + n = ((n & 0xCCCC) >> 2) | ((n & 0x3333) << 2); + n = ((n & 0xF0F0) >> 4) | ((n & 0x0F0F) << 4); + n = ((n & 0xFF00) >> 8) | ((n & 0x00FF) << 8); + return n; +} + +stbi_inline static int stbi__bit_reverse(int v, int bits) +{ + STBI_ASSERT(bits <= 16); + // to bit reverse n bits, reverse 16 and shift + // e.g. 11 bits, bit reverse and shift away 5 + return stbi__bitreverse16(v) >> (16 - bits); +} + +static int stbi__zbuild_huffman(stbi__zhuffman * z, const stbi_uc * sizelist, int num) +{ + int i, k = 0; + int code, next_code[16], sizes[17]; + + // DEFLATE spec for generating codes + memset(sizes, 0, sizeof(sizes)); + memset(z->fast, 0, sizeof(z->fast)); + for(i = 0; i < num; ++i) + ++sizes[sizelist[i]]; + sizes[0] = 0; + for(i = 1; i < 16; ++i) + if(sizes[i] > (1 << i)) + return stbi__err("bad sizes", "Corrupt PNG"); + code = 0; + for(i = 1; i < 16; ++i) { + next_code[i] = code; + z->firstcode[i] = (stbi__uint16) code; + z->firstsymbol[i] = (stbi__uint16) k; + code = (code + sizes[i]); + if(sizes[i]) + if(code - 1 >= (1 << i)) return stbi__err("bad codelengths", "Corrupt PNG"); + z->maxcode[i] = code << (16 - i); // preshift for inner loop + code <<= 1; + k += sizes[i]; + } + z->maxcode[16] = 0x10000; // sentinel + for(i = 0; i < num; ++i) { + int s = sizelist[i]; + if(s) { + int c = next_code[s] - z->firstcode[s] + z->firstsymbol[s]; + stbi__uint16 fastv = (stbi__uint16)((s << 9) | i); + z->size [c] = (stbi_uc) s; + z->value[c] = (stbi__uint16) i; + if(s <= STBI__ZFAST_BITS) { + int j = stbi__bit_reverse(next_code[s], s); + while(j < (1 << STBI__ZFAST_BITS)) { + z->fast[j] = fastv; + j += (1 << s); + } + } + ++next_code[s]; + } + } + return 1; +} + +// zlib-from-memory implementation for PNG reading +// because PNG allows splitting the zlib stream arbitrarily, +// and it's annoying structurally to have PNG call ZLIB call PNG, +// we require PNG read all the IDATs and combine them into a single +// memory buffer + +typedef struct { + stbi_uc * zbuffer, * zbuffer_end; + int num_bits; + int hit_zeof_once; + stbi__uint32 code_buffer; + + char * zout; + char * zout_start; + char * zout_end; + int z_expandable; + + stbi__zhuffman z_length, z_distance; +} stbi__zbuf; + +stbi_inline static int stbi__zeof(stbi__zbuf * z) +{ + return (z->zbuffer >= z->zbuffer_end); +} + +stbi_inline static stbi_uc stbi__zget8(stbi__zbuf * z) +{ + return stbi__zeof(z) ? 0 : *z->zbuffer++; +} + +static void stbi__fill_bits(stbi__zbuf * z) +{ + do { + if(z->code_buffer >= (1U << z->num_bits)) { + z->zbuffer = z->zbuffer_end; /* treat this as EOF so we fail. */ + return; + } + z->code_buffer |= (unsigned int) stbi__zget8(z) << z->num_bits; + z->num_bits += 8; + } while(z->num_bits <= 24); +} + +stbi_inline static unsigned int stbi__zreceive(stbi__zbuf * z, int n) +{ + unsigned int k; + if(z->num_bits < n) stbi__fill_bits(z); + k = z->code_buffer & ((1 << n) - 1); + z->code_buffer >>= n; + z->num_bits -= n; + return k; +} + +static int stbi__zhuffman_decode_slowpath(stbi__zbuf * a, stbi__zhuffman * z) +{ + int b, s, k; + // not resolved by fast table, so compute it the slow way + // use jpeg approach, which requires MSbits at top + k = stbi__bit_reverse(a->code_buffer, 16); + for(s = STBI__ZFAST_BITS + 1; ; ++s) + if(k < z->maxcode[s]) + break; + if(s >= 16) return -1; // invalid code! + // code size is s, so: + b = (k >> (16 - s)) - z->firstcode[s] + z->firstsymbol[s]; + if(b >= STBI__ZNSYMS) return -1; // some data was corrupt somewhere! + if(z->size[b] != s) return -1; // was originally an assert, but report failure instead. + a->code_buffer >>= s; + a->num_bits -= s; + return z->value[b]; +} + +stbi_inline static int stbi__zhuffman_decode(stbi__zbuf * a, stbi__zhuffman * z) +{ + int b, s; + if(a->num_bits < 16) { + if(stbi__zeof(a)) { + if(!a->hit_zeof_once) { + // This is the first time we hit eof, insert 16 extra padding btis + // to allow us to keep going; if we actually consume any of them + // though, that is invalid data. This is caught later. + a->hit_zeof_once = 1; + a->num_bits += 16; // add 16 implicit zero bits + } + else { + // We already inserted our extra 16 padding bits and are again + // out, this stream is actually prematurely terminated. + return -1; + } + } + else { + stbi__fill_bits(a); + } + } + b = z->fast[a->code_buffer & STBI__ZFAST_MASK]; + if(b) { + s = b >> 9; + a->code_buffer >>= s; + a->num_bits -= s; + return b & 511; + } + return stbi__zhuffman_decode_slowpath(a, z); +} + +static int stbi__zexpand(stbi__zbuf * z, char * zout, int n) // need to make room for n bytes +{ + char * q; + unsigned int cur, limit, old_limit; + z->zout = zout; + if(!z->z_expandable) return stbi__err("output buffer limit", "Corrupt PNG"); + cur = (unsigned int)(z->zout - z->zout_start); + limit = old_limit = (unsigned)(z->zout_end - z->zout_start); + if(UINT_MAX - cur < (unsigned) n) return stbi__err("outofmem", "Out of memory"); + while(cur + n > limit) { + if(limit > UINT_MAX / 2) return stbi__err("outofmem", "Out of memory"); + limit *= 2; + } + q = (char *) STBI_REALLOC_SIZED(z->zout_start, old_limit, limit); + STBI_NOTUSED(old_limit); + if(q == NULL) return stbi__err("outofmem", "Out of memory"); + z->zout_start = q; + z->zout = q + cur; + z->zout_end = q + limit; + return 1; +} + +static const int stbi__zlength_base[31] = { + 3, 4, 5, 6, 7, 8, 9, 10, 11, 13, + 15, 17, 19, 23, 27, 31, 35, 43, 51, 59, + 67, 83, 99, 115, 131, 163, 195, 227, 258, 0, 0 +}; + +static const int stbi__zlength_extra[31] = +{ 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 2, 2, 2, 2, 3, 3, 3, 3, 4, 4, 4, 4, 5, 5, 5, 5, 0, 0, 0 }; + +static const int stbi__zdist_base[32] = { 1, 2, 3, 4, 5, 7, 9, 13, 17, 25, 33, 49, 65, 97, 129, 193, + 257, 385, 513, 769, 1025, 1537, 2049, 3073, 4097, 6145, 8193, 12289, 16385, 24577, 0, 0 + }; + +static const int stbi__zdist_extra[32] = +{ 0, 0, 0, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7, 8, 8, 9, 9, 10, 10, 11, 11, 12, 12, 13, 13}; + +static int stbi__parse_huffman_block(stbi__zbuf * a) +{ + char * zout = a->zout; + for(;;) { + int z = stbi__zhuffman_decode(a, &a->z_length); + if(z < 256) { + if(z < 0) return stbi__err("bad huffman code", "Corrupt PNG"); // error in huffman codes + if(zout >= a->zout_end) { + if(!stbi__zexpand(a, zout, 1)) return 0; + zout = a->zout; + } + *zout++ = (char) z; + } + else { + stbi_uc * p; + int len, dist; + if(z == 256) { + a->zout = zout; + if(a->hit_zeof_once && a->num_bits < 16) { + // The first time we hit zeof, we inserted 16 extra zero bits into our bit + // buffer so the decoder can just do its speculative decoding. But if we + // actually consumed any of those bits (which is the case when num_bits < 16), + // the stream actually read past the end so it is malformed. + return stbi__err("unexpected end", "Corrupt PNG"); + } + return 1; + } + if(z >= 286) return stbi__err("bad huffman code", + "Corrupt PNG"); // per DEFLATE, length codes 286 and 287 must not appear in compressed data + z -= 257; + len = stbi__zlength_base[z]; + if(stbi__zlength_extra[z]) len += stbi__zreceive(a, stbi__zlength_extra[z]); + z = stbi__zhuffman_decode(a, &a->z_distance); + if(z < 0 || + z >= 30) return stbi__err("bad huffman code", + "Corrupt PNG"); // per DEFLATE, distance codes 30 and 31 must not appear in compressed data + dist = stbi__zdist_base[z]; + if(stbi__zdist_extra[z]) dist += stbi__zreceive(a, stbi__zdist_extra[z]); + if(zout - a->zout_start < dist) return stbi__err("bad dist", "Corrupt PNG"); + if(len > a->zout_end - zout) { + if(!stbi__zexpand(a, zout, len)) return 0; + zout = a->zout; + } + p = (stbi_uc *)(zout - dist); + if(dist == 1) { // run of one byte; common in images. + stbi_uc v = *p; + if(len) { + do * zout++ = v; + while(--len); + } + } + else { + if(len) { + do * zout++ = *p++; + while(--len); + } + } + } + } +} + +static int stbi__compute_huffman_codes(stbi__zbuf * a) +{ + static const stbi_uc length_dezigzag[19] = { 16, 17, 18, 0, 8, 7, 9, 6, 10, 5, 11, 4, 12, 3, 13, 2, 14, 1, 15 }; + stbi__zhuffman z_codelength; + stbi_uc lencodes[286 + 32 + 137]; //padding for maximum single op + stbi_uc codelength_sizes[19]; + int i, n; + + int hlit = stbi__zreceive(a, 5) + 257; + int hdist = stbi__zreceive(a, 5) + 1; + int hclen = stbi__zreceive(a, 4) + 4; + int ntot = hlit + hdist; + + memset(codelength_sizes, 0, sizeof(codelength_sizes)); + for(i = 0; i < hclen; ++i) { + int s = stbi__zreceive(a, 3); + codelength_sizes[length_dezigzag[i]] = (stbi_uc) s; + } + if(!stbi__zbuild_huffman(&z_codelength, codelength_sizes, 19)) return 0; + + n = 0; + while(n < ntot) { + int c = stbi__zhuffman_decode(a, &z_codelength); + if(c < 0 || c >= 19) return stbi__err("bad codelengths", "Corrupt PNG"); + if(c < 16) + lencodes[n++] = (stbi_uc) c; + else { + stbi_uc fill = 0; + if(c == 16) { + c = stbi__zreceive(a, 2) + 3; + if(n == 0) return stbi__err("bad codelengths", "Corrupt PNG"); + fill = lencodes[n - 1]; + } + else if(c == 17) { + c = stbi__zreceive(a, 3) + 3; + } + else if(c == 18) { + c = stbi__zreceive(a, 7) + 11; + } + else { + return stbi__err("bad codelengths", "Corrupt PNG"); + } + if(ntot - n < c) return stbi__err("bad codelengths", "Corrupt PNG"); + memset(lencodes + n, fill, c); + n += c; + } + } + if(n != ntot) return stbi__err("bad codelengths", "Corrupt PNG"); + if(!stbi__zbuild_huffman(&a->z_length, lencodes, hlit)) return 0; + if(!stbi__zbuild_huffman(&a->z_distance, lencodes + hlit, hdist)) return 0; + return 1; +} + +static int stbi__parse_uncompressed_block(stbi__zbuf * a) +{ + stbi_uc header[4]; + int len, nlen, k; + if(a->num_bits & 7) + stbi__zreceive(a, a->num_bits & 7); // discard + // drain the bit-packed data into header + k = 0; + while(a->num_bits > 0) { + header[k++] = (stbi_uc)(a->code_buffer & 255); // suppress MSVC run-time check + a->code_buffer >>= 8; + a->num_bits -= 8; + } + if(a->num_bits < 0) return stbi__err("zlib corrupt", "Corrupt PNG"); + // now fill header the normal way + while(k < 4) + header[k++] = stbi__zget8(a); + len = header[1] * 256 + header[0]; + nlen = header[3] * 256 + header[2]; + if(nlen != (len ^ 0xffff)) return stbi__err("zlib corrupt", "Corrupt PNG"); + if(a->zbuffer + len > a->zbuffer_end) return stbi__err("read past buffer", "Corrupt PNG"); + if(a->zout + len > a->zout_end) + if(!stbi__zexpand(a, a->zout, len)) return 0; + memcpy(a->zout, a->zbuffer, len); + a->zbuffer += len; + a->zout += len; + return 1; +} + +static int stbi__parse_zlib_header(stbi__zbuf * a) +{ + int cmf = stbi__zget8(a); + int cm = cmf & 15; + /* int cinfo = cmf >> 4; */ + int flg = stbi__zget8(a); + if(stbi__zeof(a)) return stbi__err("bad zlib header", "Corrupt PNG"); // zlib spec + if((cmf * 256 + flg) % 31 != 0) return stbi__err("bad zlib header", "Corrupt PNG"); // zlib spec + if(flg & 32) return stbi__err("no preset dict", "Corrupt PNG"); // preset dictionary not allowed in png + if(cm != 8) return stbi__err("bad compression", "Corrupt PNG"); // DEFLATE required for png + // window = 1 << (8 + cinfo)... but who cares, we fully buffer output + return 1; +} + +static const stbi_uc stbi__zdefault_length[STBI__ZNSYMS] = { + 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, + 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, + 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, + 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, + 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 8, 8, 8, 8, 8, 8, 8, 8 +}; +static const stbi_uc stbi__zdefault_distance[32] = { + 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5 +}; +/* +Init algorithm: +{ + int i; // use <= to match clearly with spec + for (i=0; i <= 143; ++i) stbi__zdefault_length[i] = 8; + for ( ; i <= 255; ++i) stbi__zdefault_length[i] = 9; + for ( ; i <= 279; ++i) stbi__zdefault_length[i] = 7; + for ( ; i <= 287; ++i) stbi__zdefault_length[i] = 8; + + for (i=0; i <= 31; ++i) stbi__zdefault_distance[i] = 5; +} +*/ + +static int stbi__parse_zlib(stbi__zbuf * a, int parse_header) +{ + int final, type; + if(parse_header) + if(!stbi__parse_zlib_header(a)) return 0; + a->num_bits = 0; + a->code_buffer = 0; + a->hit_zeof_once = 0; + do { + final = stbi__zreceive(a, 1); + type = stbi__zreceive(a, 2); + if(type == 0) { + if(!stbi__parse_uncompressed_block(a)) return 0; + } + else if(type == 3) { + return 0; + } + else { + if(type == 1) { + // use fixed code lengths + if(!stbi__zbuild_huffman(&a->z_length, stbi__zdefault_length, STBI__ZNSYMS)) return 0; + if(!stbi__zbuild_huffman(&a->z_distance, stbi__zdefault_distance, 32)) return 0; + } + else { + if(!stbi__compute_huffman_codes(a)) return 0; + } + if(!stbi__parse_huffman_block(a)) return 0; + } + } while(!final); + return 1; +} + +static int stbi__do_zlib(stbi__zbuf * a, char * obuf, int olen, int exp, int parse_header) +{ + a->zout_start = obuf; + a->zout = obuf; + a->zout_end = obuf + olen; + a->z_expandable = exp; + + return stbi__parse_zlib(a, parse_header); +} + +STBIDEF char * stbi_zlib_decode_malloc_guesssize(const char * buffer, int len, int initial_size, int * outlen) +{ + stbi__zbuf a; + char * p = (char *) stbi__malloc(initial_size); + if(p == NULL) return NULL; + a.zbuffer = (stbi_uc *) buffer; + a.zbuffer_end = (stbi_uc *) buffer + len; + if(stbi__do_zlib(&a, p, initial_size, 1, 1)) { + if(outlen) *outlen = (int)(a.zout - a.zout_start); + return a.zout_start; + } + else { + STBI_FREE(a.zout_start); + return NULL; + } +} + +STBIDEF char * stbi_zlib_decode_malloc(char const * buffer, int len, int * outlen) +{ + return stbi_zlib_decode_malloc_guesssize(buffer, len, 16384, outlen); +} + +STBIDEF char * stbi_zlib_decode_malloc_guesssize_headerflag(const char * buffer, int len, int initial_size, + int * outlen, int parse_header) +{ + stbi__zbuf a; + char * p = (char *) stbi__malloc(initial_size); + if(p == NULL) return NULL; + a.zbuffer = (stbi_uc *) buffer; + a.zbuffer_end = (stbi_uc *) buffer + len; + if(stbi__do_zlib(&a, p, initial_size, 1, parse_header)) { + if(outlen) *outlen = (int)(a.zout - a.zout_start); + return a.zout_start; + } + else { + STBI_FREE(a.zout_start); + return NULL; + } +} + +STBIDEF int stbi_zlib_decode_buffer(char * obuffer, int olen, char const * ibuffer, int ilen) +{ + stbi__zbuf a; + a.zbuffer = (stbi_uc *) ibuffer; + a.zbuffer_end = (stbi_uc *) ibuffer + ilen; + if(stbi__do_zlib(&a, obuffer, olen, 0, 1)) + return (int)(a.zout - a.zout_start); + else + return -1; +} + +STBIDEF char * stbi_zlib_decode_noheader_malloc(char const * buffer, int len, int * outlen) +{ + stbi__zbuf a; + char * p = (char *) stbi__malloc(16384); + if(p == NULL) return NULL; + a.zbuffer = (stbi_uc *) buffer; + a.zbuffer_end = (stbi_uc *) buffer + len; + if(stbi__do_zlib(&a, p, 16384, 1, 0)) { + if(outlen) *outlen = (int)(a.zout - a.zout_start); + return a.zout_start; + } + else { + STBI_FREE(a.zout_start); + return NULL; + } +} + +STBIDEF int stbi_zlib_decode_noheader_buffer(char * obuffer, int olen, const char * ibuffer, int ilen) +{ + stbi__zbuf a; + a.zbuffer = (stbi_uc *) ibuffer; + a.zbuffer_end = (stbi_uc *) ibuffer + ilen; + if(stbi__do_zlib(&a, obuffer, olen, 0, 0)) + return (int)(a.zout - a.zout_start); + else + return -1; +} +#endif + +// public domain "baseline" PNG decoder v0.10 Sean Barrett 2006-11-18 +// simple implementation +// - only 8-bit samples +// - no CRC checking +// - allocates lots of intermediate memory +// - avoids problem of streaming data between subsystems +// - avoids explicit window management +// performance +// - uses stb_zlib, a PD zlib implementation with fast huffman decoding + +#ifndef STBI_NO_PNG +typedef struct { + stbi__uint32 length; + stbi__uint32 type; +} stbi__pngchunk; + +static stbi__pngchunk stbi__get_chunk_header(stbi__context * s) +{ + stbi__pngchunk c; + c.length = stbi__get32be(s); + c.type = stbi__get32be(s); + return c; +} + +static int stbi__check_png_header(stbi__context * s) +{ + static const stbi_uc png_sig[8] = { 137, 80, 78, 71, 13, 10, 26, 10 }; + int i; + for(i = 0; i < 8; ++i) + if(stbi__get8(s) != png_sig[i]) return stbi__err("bad png sig", "Not a PNG"); + return 1; +} + +typedef struct { + stbi__context * s; + stbi_uc * idata, * expanded, * out; + int depth; +} stbi__png; + + +enum { + STBI__F_none = 0, + STBI__F_sub = 1, + STBI__F_up = 2, + STBI__F_avg = 3, + STBI__F_paeth = 4, + // synthetic filter used for first scanline to avoid needing a dummy row of 0s + STBI__F_avg_first +}; + +static stbi_uc first_row_filter[5] = { + STBI__F_none, + STBI__F_sub, + STBI__F_none, + STBI__F_avg_first, + STBI__F_sub // Paeth with b=c=0 turns out to be equivalent to sub +}; + +static int stbi__paeth(int a, int b, int c) +{ + // This formulation looks very different from the reference in the PNG spec, but is + // actually equivalent and has favorable data dependencies and admits straightforward + // generation of branch-free code, which helps performance significantly. + int thresh = c * 3 - (a + b); + int lo = a < b ? a : b; + int hi = a < b ? b : a; + int t0 = (hi <= thresh) ? lo : c; + int t1 = (thresh <= lo) ? hi : t0; + return t1; +} + +static const stbi_uc stbi__depth_scale_table[9] = { 0, 0xff, 0x55, 0, 0x11, 0, 0, 0, 0x01 }; + +// adds an extra all-255 alpha channel +// dest == src is legal +// img_n must be 1 or 3 +static void stbi__create_png_alpha_expand8(stbi_uc * dest, stbi_uc * src, stbi__uint32 x, int img_n) +{ + int i; + // must process data backwards since we allow dest==src + if(img_n == 1) { + for(i = x - 1; i >= 0; --i) { + dest[i * 2 + 1] = 255; + dest[i * 2 + 0] = src[i]; + } + } + else { + STBI_ASSERT(img_n == 3); + for(i = x - 1; i >= 0; --i) { + dest[i * 4 + 3] = 255; + dest[i * 4 + 2] = src[i * 3 + 2]; + dest[i * 4 + 1] = src[i * 3 + 1]; + dest[i * 4 + 0] = src[i * 3 + 0]; + } + } +} + +// create the png data from post-deflated data +static int stbi__create_png_image_raw(stbi__png * a, stbi_uc * raw, stbi__uint32 raw_len, int out_n, stbi__uint32 x, + stbi__uint32 y, int depth, int color) +{ + int bytes = (depth == 16 ? 2 : 1); + stbi__context * s = a->s; + stbi__uint32 i, j, stride = x * out_n * bytes; + stbi__uint32 img_len, img_width_bytes; + stbi_uc * filter_buf; + int all_ok = 1; + int k; + int img_n = s->img_n; // copy it into a local for later + + int output_bytes = out_n * bytes; + int filter_bytes = img_n * bytes; + int width = x; + + STBI_ASSERT(out_n == s->img_n || out_n == s->img_n + 1); + a->out = (stbi_uc *) stbi__malloc_mad3(x, y, output_bytes, 0); // extra bytes to write off the end into + if(!a->out) return stbi__err("outofmem", "Out of memory"); + + // note: error exits here don't need to clean up a->out individually, + // stbi__do_png always does on error. + if(!stbi__mad3sizes_valid(img_n, x, depth, 7)) return stbi__err("too large", "Corrupt PNG"); + img_width_bytes = (((img_n * x * depth) + 7) >> 3); + if(!stbi__mad2sizes_valid(img_width_bytes, y, img_width_bytes)) return stbi__err("too large", "Corrupt PNG"); + img_len = (img_width_bytes + 1) * y; + + // we used to check for exact match between raw_len and img_len on non-interlaced PNGs, + // but issue #276 reported a PNG in the wild that had extra data at the end (all zeros), + // so just check for raw_len < img_len always. + if(raw_len < img_len) return stbi__err("not enough pixels", "Corrupt PNG"); + + // Allocate two scan lines worth of filter workspace buffer. + filter_buf = (stbi_uc *) stbi__malloc_mad2(img_width_bytes, 2, 0); + if(!filter_buf) return stbi__err("outofmem", "Out of memory"); + + // Filtering for low-bit-depth images + if(depth < 8) { + filter_bytes = 1; + width = img_width_bytes; + } + + for(j = 0; j < y; ++j) { + // cur/prior filter buffers alternate + stbi_uc * cur = filter_buf + (j & 1) * img_width_bytes; + stbi_uc * prior = filter_buf + (~j & 1) * img_width_bytes; + stbi_uc * dest = a->out + stride * j; + int nk = width * filter_bytes; + int filter = *raw++; + + // check filter type + if(filter > 4) { + all_ok = stbi__err("invalid filter", "Corrupt PNG"); + break; + } + + // if first row, use special filter that doesn't sample previous row + if(j == 0) filter = first_row_filter[filter]; + + // perform actual filtering + switch(filter) { + case STBI__F_none: + memcpy(cur, raw, nk); + break; + case STBI__F_sub: + memcpy(cur, raw, filter_bytes); + for(k = filter_bytes; k < nk; ++k) + cur[k] = STBI__BYTECAST(raw[k] + cur[k - filter_bytes]); + break; + case STBI__F_up: + for(k = 0; k < nk; ++k) + cur[k] = STBI__BYTECAST(raw[k] + prior[k]); + break; + case STBI__F_avg: + for(k = 0; k < filter_bytes; ++k) + cur[k] = STBI__BYTECAST(raw[k] + (prior[k] >> 1)); + for(k = filter_bytes; k < nk; ++k) + cur[k] = STBI__BYTECAST(raw[k] + ((prior[k] + cur[k - filter_bytes]) >> 1)); + break; + case STBI__F_paeth: + for(k = 0; k < filter_bytes; ++k) + cur[k] = STBI__BYTECAST(raw[k] + prior[k]); // prior[k] == stbi__paeth(0,prior[k],0) + for(k = filter_bytes; k < nk; ++k) + cur[k] = STBI__BYTECAST(raw[k] + stbi__paeth(cur[k - filter_bytes], prior[k], prior[k - filter_bytes])); + break; + case STBI__F_avg_first: + memcpy(cur, raw, filter_bytes); + for(k = filter_bytes; k < nk; ++k) + cur[k] = STBI__BYTECAST(raw[k] + (cur[k - filter_bytes] >> 1)); + break; + } + + raw += nk; + + // expand decoded bits in cur to dest, also adding an extra alpha channel if desired + if(depth < 8) { + stbi_uc scale = (color == 0) ? stbi__depth_scale_table[depth] : 1; // scale grayscale values to 0..255 range + stbi_uc * in = cur; + stbi_uc * out = dest; + stbi_uc inb = 0; + stbi__uint32 nsmp = x * img_n; + + // expand bits to bytes first + if(depth == 4) { + for(i = 0; i < nsmp; ++i) { + if((i & 1) == 0) inb = *in++; + *out++ = scale * (inb >> 4); + inb <<= 4; + } + } + else if(depth == 2) { + for(i = 0; i < nsmp; ++i) { + if((i & 3) == 0) inb = *in++; + *out++ = scale * (inb >> 6); + inb <<= 2; + } + } + else { + STBI_ASSERT(depth == 1); + for(i = 0; i < nsmp; ++i) { + if((i & 7) == 0) inb = *in++; + *out++ = scale * (inb >> 7); + inb <<= 1; + } + } + + // insert alpha=255 values if desired + if(img_n != out_n) + stbi__create_png_alpha_expand8(dest, dest, x, img_n); + } + else if(depth == 8) { + if(img_n == out_n) + memcpy(dest, cur, x * img_n); + else + stbi__create_png_alpha_expand8(dest, cur, x, img_n); + } + else if(depth == 16) { + // convert the image data from big-endian to platform-native + stbi__uint16 * dest16 = (stbi__uint16 *)dest; + stbi__uint32 nsmp = x * img_n; + + if(img_n == out_n) { + for(i = 0; i < nsmp; ++i, ++dest16, cur += 2) + * dest16 = (cur[0] << 8) | cur[1]; + } + else { + STBI_ASSERT(img_n + 1 == out_n); + if(img_n == 1) { + for(i = 0; i < x; ++i, dest16 += 2, cur += 2) { + dest16[0] = (cur[0] << 8) | cur[1]; + dest16[1] = 0xffff; + } + } + else { + STBI_ASSERT(img_n == 3); + for(i = 0; i < x; ++i, dest16 += 4, cur += 6) { + dest16[0] = (cur[0] << 8) | cur[1]; + dest16[1] = (cur[2] << 8) | cur[3]; + dest16[2] = (cur[4] << 8) | cur[5]; + dest16[3] = 0xffff; + } + } + } + } + } + + STBI_FREE(filter_buf); + if(!all_ok) return 0; + + return 1; +} + +static int stbi__create_png_image(stbi__png * a, stbi_uc * image_data, stbi__uint32 image_data_len, int out_n, + int depth, int color, int interlaced) +{ + int bytes = (depth == 16 ? 2 : 1); + int out_bytes = out_n * bytes; + stbi_uc * final; + int p; + if(!interlaced) + return stbi__create_png_image_raw(a, image_data, image_data_len, out_n, a->s->img_x, a->s->img_y, depth, color); + + // de-interlacing + final = (stbi_uc *) stbi__malloc_mad3(a->s->img_x, a->s->img_y, out_bytes, 0); + if(!final) return stbi__err("outofmem", "Out of memory"); + for(p = 0; p < 7; ++p) { + int xorig[] = { 0, 4, 0, 2, 0, 1, 0 }; + int yorig[] = { 0, 0, 4, 0, 2, 0, 1 }; + int xspc[] = { 8, 8, 4, 4, 2, 2, 1 }; + int yspc[] = { 8, 8, 8, 4, 4, 2, 2 }; + int i, j, x, y; + // pass1_x[4] = 0, pass1_x[5] = 1, pass1_x[12] = 1 + x = (a->s->img_x - xorig[p] + xspc[p] - 1) / xspc[p]; + y = (a->s->img_y - yorig[p] + yspc[p] - 1) / yspc[p]; + if(x && y) { + stbi__uint32 img_len = ((((a->s->img_n * x * depth) + 7) >> 3) + 1) * y; + if(!stbi__create_png_image_raw(a, image_data, image_data_len, out_n, x, y, depth, color)) { + STBI_FREE(final); + return 0; + } + for(j = 0; j < y; ++j) { + for(i = 0; i < x; ++i) { + int out_y = j * yspc[p] + yorig[p]; + int out_x = i * xspc[p] + xorig[p]; + memcpy(final + out_y * a->s->img_x * out_bytes + out_x * out_bytes, + a->out + (j * x + i)*out_bytes, out_bytes); + } + } + STBI_FREE(a->out); + image_data += img_len; + image_data_len -= img_len; + } + } + a->out = final; + + return 1; +} + +static int stbi__compute_transparency(stbi__png * z, stbi_uc tc[3], int out_n) +{ + stbi__context * s = z->s; + stbi__uint32 i, pixel_count = s->img_x * s->img_y; + stbi_uc * p = z->out; + + // compute color-based transparency, assuming we've + // already got 255 as the alpha value in the output + STBI_ASSERT(out_n == 2 || out_n == 4); + + if(out_n == 2) { + for(i = 0; i < pixel_count; ++i) { + p[1] = (p[0] == tc[0] ? 0 : 255); + p += 2; + } + } + else { + for(i = 0; i < pixel_count; ++i) { + if(p[0] == tc[0] && p[1] == tc[1] && p[2] == tc[2]) + p[3] = 0; + p += 4; + } + } + return 1; +} + +static int stbi__compute_transparency16(stbi__png * z, stbi__uint16 tc[3], int out_n) +{ + stbi__context * s = z->s; + stbi__uint32 i, pixel_count = s->img_x * s->img_y; + stbi__uint16 * p = (stbi__uint16 *) z->out; + + // compute color-based transparency, assuming we've + // already got 65535 as the alpha value in the output + STBI_ASSERT(out_n == 2 || out_n == 4); + + if(out_n == 2) { + for(i = 0; i < pixel_count; ++i) { + p[1] = (p[0] == tc[0] ? 0 : 65535); + p += 2; + } + } + else { + for(i = 0; i < pixel_count; ++i) { + if(p[0] == tc[0] && p[1] == tc[1] && p[2] == tc[2]) + p[3] = 0; + p += 4; + } + } + return 1; +} + +static int stbi__expand_png_palette(stbi__png * a, stbi_uc * palette, int len, int pal_img_n) +{ + stbi__uint32 i, pixel_count = a->s->img_x * a->s->img_y; + stbi_uc * p, * temp_out, * orig = a->out; + + p = (stbi_uc *) stbi__malloc_mad2(pixel_count, pal_img_n, 0); + if(p == NULL) return stbi__err("outofmem", "Out of memory"); + + // between here and free(out) below, exitting would leak + temp_out = p; + + if(pal_img_n == 3) { + for(i = 0; i < pixel_count; ++i) { + int n = orig[i] * 4; + p[0] = palette[n ]; + p[1] = palette[n + 1]; + p[2] = palette[n + 2]; + p += 3; + } + } + else { + for(i = 0; i < pixel_count; ++i) { + int n = orig[i] * 4; + p[0] = palette[n ]; + p[1] = palette[n + 1]; + p[2] = palette[n + 2]; + p[3] = palette[n + 3]; + p += 4; + } + } + STBI_FREE(a->out); + a->out = temp_out; + + STBI_NOTUSED(len); + + return 1; +} + +static int stbi__unpremultiply_on_load_global = 0; +static int stbi__de_iphone_flag_global = 0; + +STBIDEF void stbi_set_unpremultiply_on_load(int flag_true_if_should_unpremultiply) +{ + stbi__unpremultiply_on_load_global = flag_true_if_should_unpremultiply; +} + +STBIDEF void stbi_convert_iphone_png_to_rgb(int flag_true_if_should_convert) +{ + stbi__de_iphone_flag_global = flag_true_if_should_convert; +} + +#ifndef STBI_THREAD_LOCAL +#define stbi__unpremultiply_on_load stbi__unpremultiply_on_load_global +#define stbi__de_iphone_flag stbi__de_iphone_flag_global +#else +static STBI_THREAD_LOCAL int stbi__unpremultiply_on_load_local, stbi__unpremultiply_on_load_set; +static STBI_THREAD_LOCAL int stbi__de_iphone_flag_local, stbi__de_iphone_flag_set; + +STBIDEF void stbi_set_unpremultiply_on_load_thread(int flag_true_if_should_unpremultiply) +{ + stbi__unpremultiply_on_load_local = flag_true_if_should_unpremultiply; + stbi__unpremultiply_on_load_set = 1; +} + +STBIDEF void stbi_convert_iphone_png_to_rgb_thread(int flag_true_if_should_convert) +{ + stbi__de_iphone_flag_local = flag_true_if_should_convert; + stbi__de_iphone_flag_set = 1; +} + +#define stbi__unpremultiply_on_load (stbi__unpremultiply_on_load_set \ + ? stbi__unpremultiply_on_load_local \ + : stbi__unpremultiply_on_load_global) +#define stbi__de_iphone_flag (stbi__de_iphone_flag_set \ + ? stbi__de_iphone_flag_local \ + : stbi__de_iphone_flag_global) +#endif // STBI_THREAD_LOCAL + +static void stbi__de_iphone(stbi__png * z) +{ + stbi__context * s = z->s; + stbi__uint32 i, pixel_count = s->img_x * s->img_y; + stbi_uc * p = z->out; + + if(s->img_out_n == 3) { // convert bgr to rgb + for(i = 0; i < pixel_count; ++i) { + stbi_uc t = p[0]; + p[0] = p[2]; + p[2] = t; + p += 3; + } + } + else { + STBI_ASSERT(s->img_out_n == 4); + if(stbi__unpremultiply_on_load) { + // convert bgr to rgb and unpremultiply + for(i = 0; i < pixel_count; ++i) { + stbi_uc a = p[3]; + stbi_uc t = p[0]; + if(a) { + stbi_uc half = a / 2; + p[0] = (p[2] * 255 + half) / a; + p[1] = (p[1] * 255 + half) / a; + p[2] = (t * 255 + half) / a; + } + else { + p[0] = p[2]; + p[2] = t; + } + p += 4; + } + } + else { + // convert bgr to rgb + for(i = 0; i < pixel_count; ++i) { + stbi_uc t = p[0]; + p[0] = p[2]; + p[2] = t; + p += 4; + } + } + } +} + +#define STBI__PNG_TYPE(a,b,c,d) (((unsigned) (a) << 24) + ((unsigned) (b) << 16) + ((unsigned) (c) << 8) + (unsigned) (d)) + +static int stbi__parse_png_file(stbi__png * z, int scan, int req_comp) +{ + stbi_uc palette[1024], pal_img_n = 0; + stbi_uc has_trans = 0, tc[3] = {0}; + stbi__uint16 tc16[3]; + stbi__uint32 ioff = 0, idata_limit = 0, i, pal_len = 0; + int first = 1, k, interlace = 0, color = 0, is_iphone = 0; + stbi__context * s = z->s; + + z->expanded = NULL; + z->idata = NULL; + z->out = NULL; + + if(!stbi__check_png_header(s)) return 0; + + if(scan == STBI__SCAN_type) return 1; + + for(;;) { + stbi__pngchunk c = stbi__get_chunk_header(s); + switch(c.type) { + case STBI__PNG_TYPE('C', 'g', 'B', 'I'): + is_iphone = 1; + stbi__skip(s, c.length); + break; + case STBI__PNG_TYPE('I', 'H', 'D', 'R'): { + int comp, filter; + if(!first) return stbi__err("multiple IHDR", "Corrupt PNG"); + first = 0; + if(c.length != 13) return stbi__err("bad IHDR len", "Corrupt PNG"); + s->img_x = stbi__get32be(s); + s->img_y = stbi__get32be(s); + if(s->img_y > STBI_MAX_DIMENSIONS) return stbi__err("too large", "Very large image (corrupt?)"); + if(s->img_x > STBI_MAX_DIMENSIONS) return stbi__err("too large", "Very large image (corrupt?)"); + z->depth = stbi__get8(s); + if(z->depth != 1 && z->depth != 2 && z->depth != 4 && z->depth != 8 && + z->depth != 16) return stbi__err("1/2/4/8/16-bit only", "PNG not supported: 1/2/4/8/16-bit only"); + color = stbi__get8(s); + if(color > 6) return stbi__err("bad ctype", "Corrupt PNG"); + if(color == 3 && z->depth == 16) return stbi__err("bad ctype", "Corrupt PNG"); + if(color == 3) pal_img_n = 3; + else if(color & 1) return stbi__err("bad ctype", "Corrupt PNG"); + comp = stbi__get8(s); + if(comp) return stbi__err("bad comp method", "Corrupt PNG"); + filter = stbi__get8(s); + if(filter) return stbi__err("bad filter method", "Corrupt PNG"); + interlace = stbi__get8(s); + if(interlace > 1) return stbi__err("bad interlace method", "Corrupt PNG"); + if(!s->img_x || !s->img_y) return stbi__err("0-pixel image", "Corrupt PNG"); + if(!pal_img_n) { + s->img_n = (color & 2 ? 3 : 1) + (color & 4 ? 1 : 0); + if((1 << 30) / s->img_x / s->img_n < s->img_y) return stbi__err("too large", "Image too large to decode"); + } + else { + // if paletted, then pal_n is our final components, and + // img_n is # components to decompress/filter. + s->img_n = 1; + if((1 << 30) / s->img_x / 4 < s->img_y) return stbi__err("too large", "Corrupt PNG"); + } + // even with SCAN_header, have to scan to see if we have a tRNS + break; + } + + case STBI__PNG_TYPE('P', 'L', 'T', 'E'): { + if(first) return stbi__err("first not IHDR", "Corrupt PNG"); + if(c.length > 256 * 3) return stbi__err("invalid PLTE", "Corrupt PNG"); + pal_len = c.length / 3; + if(pal_len * 3 != c.length) return stbi__err("invalid PLTE", "Corrupt PNG"); + for(i = 0; i < pal_len; ++i) { + palette[i * 4 + 0] = stbi__get8(s); + palette[i * 4 + 1] = stbi__get8(s); + palette[i * 4 + 2] = stbi__get8(s); + palette[i * 4 + 3] = 255; + } + break; + } + + case STBI__PNG_TYPE('t', 'R', 'N', 'S'): { + if(first) return stbi__err("first not IHDR", "Corrupt PNG"); + if(z->idata) return stbi__err("tRNS after IDAT", "Corrupt PNG"); + if(pal_img_n) { + if(scan == STBI__SCAN_header) { + s->img_n = 4; + return 1; + } + if(pal_len == 0) return stbi__err("tRNS before PLTE", "Corrupt PNG"); + if(c.length > pal_len) return stbi__err("bad tRNS len", "Corrupt PNG"); + pal_img_n = 4; + for(i = 0; i < c.length; ++i) + palette[i * 4 + 3] = stbi__get8(s); + } + else { + if(!(s->img_n & 1)) return stbi__err("tRNS with alpha", "Corrupt PNG"); + if(c.length != (stbi__uint32) s->img_n * 2) return stbi__err("bad tRNS len", "Corrupt PNG"); + has_trans = 1; + // non-paletted with tRNS = constant alpha. if header-scanning, we can stop now. + if(scan == STBI__SCAN_header) { + ++s->img_n; + return 1; + } + if(z->depth == 16) { + for(k = 0; k < s->img_n && k < 3; ++k) // extra loop test to suppress false GCC warning + tc16[k] = (stbi__uint16)stbi__get16be(s); // copy the values as-is + } + else { + for(k = 0; k < s->img_n && k < 3; ++k) + tc[k] = (stbi_uc)(stbi__get16be(s) & 255) * stbi__depth_scale_table[z->depth]; // non 8-bit images will be larger + } + } + break; + } + + case STBI__PNG_TYPE('I', 'D', 'A', 'T'): { + if(first) return stbi__err("first not IHDR", "Corrupt PNG"); + if(pal_img_n && !pal_len) return stbi__err("no PLTE", "Corrupt PNG"); + if(scan == STBI__SCAN_header) { + // header scan definitely stops at first IDAT + if(pal_img_n) + s->img_n = pal_img_n; + return 1; + } + if(c.length > (1u << 30)) return stbi__err("IDAT size limit", "IDAT section larger than 2^30 bytes"); + if((int)(ioff + c.length) < (int)ioff) return 0; + if(ioff + c.length > idata_limit) { + stbi__uint32 idata_limit_old = idata_limit; + stbi_uc * p; + if(idata_limit == 0) idata_limit = c.length > 4096 ? c.length : 4096; + while(ioff + c.length > idata_limit) + idata_limit *= 2; + STBI_NOTUSED(idata_limit_old); + p = (stbi_uc *) STBI_REALLOC_SIZED(z->idata, idata_limit_old, idata_limit); + if(p == NULL) return stbi__err("outofmem", "Out of memory"); + z->idata = p; + } + if(!stbi__getn(s, z->idata + ioff, c.length)) return stbi__err("outofdata", "Corrupt PNG"); + ioff += c.length; + break; + } + + case STBI__PNG_TYPE('I', 'E', 'N', 'D'): { + stbi__uint32 raw_len, bpl; + if(first) return stbi__err("first not IHDR", "Corrupt PNG"); + if(scan != STBI__SCAN_load) return 1; + if(z->idata == NULL) return stbi__err("no IDAT", "Corrupt PNG"); + // initial guess for decoded data size to avoid unnecessary reallocs + bpl = (s->img_x * z->depth + 7) / 8; // bytes per line, per component + raw_len = bpl * s->img_y * s->img_n /* pixels */ + s->img_y /* filter mode per row */; + z->expanded = (stbi_uc *) stbi_zlib_decode_malloc_guesssize_headerflag((char *) z->idata, ioff, raw_len, + (int *) &raw_len, !is_iphone); + if(z->expanded == NULL) return 0; // zlib should set error + STBI_FREE(z->idata); + z->idata = NULL; + if((req_comp == s->img_n + 1 && req_comp != 3 && !pal_img_n) || has_trans) + s->img_out_n = s->img_n + 1; + else + s->img_out_n = s->img_n; + if(!stbi__create_png_image(z, z->expanded, raw_len, s->img_out_n, z->depth, color, interlace)) return 0; + if(has_trans) { + if(z->depth == 16) { + if(!stbi__compute_transparency16(z, tc16, s->img_out_n)) return 0; + } + else { + if(!stbi__compute_transparency(z, tc, s->img_out_n)) return 0; + } + } + if(is_iphone && stbi__de_iphone_flag && s->img_out_n > 2) + stbi__de_iphone(z); + if(pal_img_n) { + // pal_img_n == 3 or 4 + s->img_n = pal_img_n; // record the actual colors we had + s->img_out_n = pal_img_n; + if(req_comp >= 3) s->img_out_n = req_comp; + if(!stbi__expand_png_palette(z, palette, pal_len, s->img_out_n)) + return 0; + } + else if(has_trans) { + // non-paletted image with tRNS -> source image has (constant) alpha + ++s->img_n; + } + STBI_FREE(z->expanded); + z->expanded = NULL; + // end of PNG chunk, read and skip CRC + stbi__get32be(s); + return 1; + } + + default: + // if critical, fail + if(first) return stbi__err("first not IHDR", "Corrupt PNG"); + if((c.type & (1 << 29)) == 0) { +#ifndef STBI_NO_FAILURE_STRINGS + // not threadsafe + static char invalid_chunk[] = "XXXX PNG chunk not known"; + invalid_chunk[0] = STBI__BYTECAST(c.type >> 24); + invalid_chunk[1] = STBI__BYTECAST(c.type >> 16); + invalid_chunk[2] = STBI__BYTECAST(c.type >> 8); + invalid_chunk[3] = STBI__BYTECAST(c.type >> 0); +#endif + return stbi__err(invalid_chunk, "PNG not supported: unknown PNG chunk type"); + } + stbi__skip(s, c.length); + break; + } + // end of PNG chunk, read and skip CRC + stbi__get32be(s); + } +} + +static void * stbi__do_png(stbi__png * p, int * x, int * y, int * n, int req_comp, stbi__result_info * ri) +{ + void * result = NULL; + if(req_comp < 0 || req_comp > 4) return stbi__errpuc("bad req_comp", "Internal error"); + if(stbi__parse_png_file(p, STBI__SCAN_load, req_comp)) { + if(p->depth <= 8) + ri->bits_per_channel = 8; + else if(p->depth == 16) + ri->bits_per_channel = 16; + else + return stbi__errpuc("bad bits_per_channel", "PNG not supported: unsupported color depth"); + result = p->out; + p->out = NULL; + if(req_comp && req_comp != p->s->img_out_n) { + if(ri->bits_per_channel == 8) + result = stbi__convert_format((unsigned char *) result, p->s->img_out_n, req_comp, p->s->img_x, p->s->img_y); + else + result = stbi__convert_format16((stbi__uint16 *) result, p->s->img_out_n, req_comp, p->s->img_x, p->s->img_y); + p->s->img_out_n = req_comp; + if(result == NULL) return result; + } + *x = p->s->img_x; + *y = p->s->img_y; + if(n) *n = p->s->img_n; + } + STBI_FREE(p->out); + p->out = NULL; + STBI_FREE(p->expanded); + p->expanded = NULL; + STBI_FREE(p->idata); + p->idata = NULL; + + return result; +} + +static void * stbi__png_load(stbi__context * s, int * x, int * y, int * comp, int req_comp, stbi__result_info * ri) +{ + stbi__png p; + p.s = s; + return stbi__do_png(&p, x, y, comp, req_comp, ri); +} + +static int stbi__png_test(stbi__context * s) +{ + int r; + r = stbi__check_png_header(s); + stbi__rewind(s); + return r; +} + +static int stbi__png_info_raw(stbi__png * p, int * x, int * y, int * comp) +{ + if(!stbi__parse_png_file(p, STBI__SCAN_header, 0)) { + stbi__rewind(p->s); + return 0; + } + if(x) *x = p->s->img_x; + if(y) *y = p->s->img_y; + if(comp) *comp = p->s->img_n; + return 1; +} + +static int stbi__png_info(stbi__context * s, int * x, int * y, int * comp) +{ + stbi__png p; + p.s = s; + return stbi__png_info_raw(&p, x, y, comp); +} + +static int stbi__png_is16(stbi__context * s) +{ + stbi__png p; + p.s = s; + if(!stbi__png_info_raw(&p, NULL, NULL, NULL)) + return 0; + if(p.depth != 16) { + stbi__rewind(p.s); + return 0; + } + return 1; +} +#endif + +// Microsoft/Windows BMP image + +#ifndef STBI_NO_BMP +static int stbi__bmp_test_raw(stbi__context * s) +{ + int r; + int sz; + if(stbi__get8(s) != 'B') return 0; + if(stbi__get8(s) != 'M') return 0; + stbi__get32le(s); // discard filesize + stbi__get16le(s); // discard reserved + stbi__get16le(s); // discard reserved + stbi__get32le(s); // discard data offset + sz = stbi__get32le(s); + r = (sz == 12 || sz == 40 || sz == 56 || sz == 108 || sz == 124); + return r; +} + +static int stbi__bmp_test(stbi__context * s) +{ + int r = stbi__bmp_test_raw(s); + stbi__rewind(s); + return r; +} + + +// returns 0..31 for the highest set bit +static int stbi__high_bit(unsigned int z) +{ + int n = 0; + if(z == 0) return -1; + if(z >= 0x10000) { + n += 16; + z >>= 16; + } + if(z >= 0x00100) { + n += 8; + z >>= 8; + } + if(z >= 0x00010) { + n += 4; + z >>= 4; + } + if(z >= 0x00004) { + n += 2; + z >>= 2; + } + if(z >= 0x00002) { + n += 1;/* >>= 1;*/ + } + return n; +} + +static int stbi__bitcount(unsigned int a) +{ + a = (a & 0x55555555) + ((a >> 1) & 0x55555555); // max 2 + a = (a & 0x33333333) + ((a >> 2) & 0x33333333); // max 4 + a = (a + (a >> 4)) & 0x0f0f0f0f; // max 8 per 4, now 8 bits + a = (a + (a >> 8)); // max 16 per 8 bits + a = (a + (a >> 16)); // max 32 per 8 bits + return a & 0xff; +} + +// extract an arbitrarily-aligned N-bit value (N=bits) +// from v, and then make it 8-bits long and fractionally +// extend it to full full range. +static int stbi__shiftsigned(unsigned int v, int shift, int bits) +{ + static unsigned int mul_table[9] = { + 0, + 0xff/*0b11111111*/, 0x55/*0b01010101*/, 0x49/*0b01001001*/, 0x11/*0b00010001*/, + 0x21/*0b00100001*/, 0x41/*0b01000001*/, 0x81/*0b10000001*/, 0x01/*0b00000001*/, + }; + static unsigned int shift_table[9] = { + 0, 0, 0, 1, 0, 2, 4, 6, 0, + }; + if(shift < 0) + v <<= -shift; + else + v >>= shift; + STBI_ASSERT(v < 256); + v >>= (8 - bits); + STBI_ASSERT(bits >= 0 && bits <= 8); + return (int)((unsigned) v * mul_table[bits]) >> shift_table[bits]; +} + +typedef struct { + int bpp, offset, hsz; + unsigned int mr, mg, mb, ma, all_a; + int extra_read; +} stbi__bmp_data; + +static int stbi__bmp_set_mask_defaults(stbi__bmp_data * info, int compress) +{ + // BI_BITFIELDS specifies masks explicitly, don't override + if(compress == 3) + return 1; + + if(compress == 0) { + if(info->bpp == 16) { + info->mr = 31u << 10; + info->mg = 31u << 5; + info->mb = 31u << 0; + } + else if(info->bpp == 32) { + info->mr = 0xffu << 16; + info->mg = 0xffu << 8; + info->mb = 0xffu << 0; + info->ma = 0xffu << 24; + info->all_a = 0; // if all_a is 0 at end, then we loaded alpha channel but it was all 0 + } + else { + // otherwise, use defaults, which is all-0 + info->mr = info->mg = info->mb = info->ma = 0; + } + return 1; + } + return 0; // error +} + +static void * stbi__bmp_parse_header(stbi__context * s, stbi__bmp_data * info) +{ + int hsz; + if(stbi__get8(s) != 'B' || stbi__get8(s) != 'M') return stbi__errpuc("not BMP", "Corrupt BMP"); + stbi__get32le(s); // discard filesize + stbi__get16le(s); // discard reserved + stbi__get16le(s); // discard reserved + info->offset = stbi__get32le(s); + info->hsz = hsz = stbi__get32le(s); + info->mr = info->mg = info->mb = info->ma = 0; + info->extra_read = 14; + + if(info->offset < 0) return stbi__errpuc("bad BMP", "bad BMP"); + + if(hsz != 12 && hsz != 40 && hsz != 56 && hsz != 108 && + hsz != 124) return stbi__errpuc("unknown BMP", "BMP type not supported: unknown"); + if(hsz == 12) { + s->img_x = stbi__get16le(s); + s->img_y = stbi__get16le(s); + } + else { + s->img_x = stbi__get32le(s); + s->img_y = stbi__get32le(s); + } + if(stbi__get16le(s) != 1) return stbi__errpuc("bad BMP", "bad BMP"); + info->bpp = stbi__get16le(s); + if(hsz != 12) { + int compress = stbi__get32le(s); + if(compress == 1 || compress == 2) return stbi__errpuc("BMP RLE", "BMP type not supported: RLE"); + if(compress >= 4) return stbi__errpuc("BMP JPEG/PNG", + "BMP type not supported: unsupported compression"); // this includes PNG/JPEG modes + if(compress == 3 && info->bpp != 16 && + info->bpp != 32) return stbi__errpuc("bad BMP", "bad BMP"); // bitfields requires 16 or 32 bits/pixel + stbi__get32le(s); // discard sizeof + stbi__get32le(s); // discard hres + stbi__get32le(s); // discard vres + stbi__get32le(s); // discard colorsused + stbi__get32le(s); // discard max important + if(hsz == 40 || hsz == 56) { + if(hsz == 56) { + stbi__get32le(s); + stbi__get32le(s); + stbi__get32le(s); + stbi__get32le(s); + } + if(info->bpp == 16 || info->bpp == 32) { + if(compress == 0) { + stbi__bmp_set_mask_defaults(info, compress); + } + else if(compress == 3) { + info->mr = stbi__get32le(s); + info->mg = stbi__get32le(s); + info->mb = stbi__get32le(s); + info->extra_read += 12; + // not documented, but generated by photoshop and handled by mspaint + if(info->mr == info->mg && info->mg == info->mb) { + // ?!?!? + return stbi__errpuc("bad BMP", "bad BMP"); + } + } + else + return stbi__errpuc("bad BMP", "bad BMP"); + } + } + else { + // V4/V5 header + int i; + if(hsz != 108 && hsz != 124) + return stbi__errpuc("bad BMP", "bad BMP"); + info->mr = stbi__get32le(s); + info->mg = stbi__get32le(s); + info->mb = stbi__get32le(s); + info->ma = stbi__get32le(s); + if(compress != 3) // override mr/mg/mb unless in BI_BITFIELDS mode, as per docs + stbi__bmp_set_mask_defaults(info, compress); + stbi__get32le(s); // discard color space + for(i = 0; i < 12; ++i) + stbi__get32le(s); // discard color space parameters + if(hsz == 124) { + stbi__get32le(s); // discard rendering intent + stbi__get32le(s); // discard offset of profile data + stbi__get32le(s); // discard size of profile data + stbi__get32le(s); // discard reserved + } + } + } + return (void *) 1; +} + + +static void * stbi__bmp_load(stbi__context * s, int * x, int * y, int * comp, int req_comp, stbi__result_info * ri) +{ + stbi_uc * out; + unsigned int mr = 0, mg = 0, mb = 0, ma = 0, all_a; + stbi_uc pal[256][4]; + int psize = 0, i, j, width; + int flip_vertically, pad, target; + stbi__bmp_data info; + STBI_NOTUSED(ri); + + info.all_a = 255; + if(stbi__bmp_parse_header(s, &info) == NULL) + return NULL; // error code already set + + flip_vertically = ((int) s->img_y) > 0; + s->img_y = abs((int) s->img_y); + + if(s->img_y > STBI_MAX_DIMENSIONS) return stbi__errpuc("too large", "Very large image (corrupt?)"); + if(s->img_x > STBI_MAX_DIMENSIONS) return stbi__errpuc("too large", "Very large image (corrupt?)"); + + mr = info.mr; + mg = info.mg; + mb = info.mb; + ma = info.ma; + all_a = info.all_a; + + if(info.hsz == 12) { + if(info.bpp < 24) + psize = (info.offset - info.extra_read - 24) / 3; + } + else { + if(info.bpp < 16) + psize = (info.offset - info.extra_read - info.hsz) >> 2; + } + if(psize == 0) { + // accept some number of extra bytes after the header, but if the offset points either to before + // the header ends or implies a large amount of extra data, reject the file as malformed + int bytes_read_so_far = s->callback_already_read + (int)(s->img_buffer - s->img_buffer_original); + int header_limit = 1024; // max we actually read is below 256 bytes currently. + int extra_data_limit = 256 * 4; // what ordinarily goes here is a palette; 256 entries*4 bytes is its max size. + if(bytes_read_so_far <= 0 || bytes_read_so_far > header_limit) { + return stbi__errpuc("bad header", "Corrupt BMP"); + } + // we established that bytes_read_so_far is positive and sensible. + // the first half of this test rejects offsets that are either too small positives, or + // negative, and guarantees that info.offset >= bytes_read_so_far > 0. this in turn + // ensures the number computed in the second half of the test can't overflow. + if(info.offset < bytes_read_so_far || info.offset - bytes_read_so_far > extra_data_limit) { + return stbi__errpuc("bad offset", "Corrupt BMP"); + } + else { + stbi__skip(s, info.offset - bytes_read_so_far); + } + } + + if(info.bpp == 24 && ma == 0xff000000) + s->img_n = 3; + else + s->img_n = ma ? 4 : 3; + if(req_comp && req_comp >= 3) // we can directly decode 3 or 4 + target = req_comp; + else + target = s->img_n; // if they want monochrome, we'll post-convert + + // sanity-check size + if(!stbi__mad3sizes_valid(target, s->img_x, s->img_y, 0)) + return stbi__errpuc("too large", "Corrupt BMP"); + + out = (stbi_uc *) stbi__malloc_mad3(target, s->img_x, s->img_y, 0); + if(!out) return stbi__errpuc("outofmem", "Out of memory"); + if(info.bpp < 16) { + int z = 0; + if(psize == 0 || psize > 256) { + STBI_FREE(out); + return stbi__errpuc("invalid", "Corrupt BMP"); + } + for(i = 0; i < psize; ++i) { + pal[i][2] = stbi__get8(s); + pal[i][1] = stbi__get8(s); + pal[i][0] = stbi__get8(s); + if(info.hsz != 12) stbi__get8(s); + pal[i][3] = 255; + } + stbi__skip(s, info.offset - info.extra_read - info.hsz - psize * (info.hsz == 12 ? 3 : 4)); + if(info.bpp == 1) width = (s->img_x + 7) >> 3; + else if(info.bpp == 4) width = (s->img_x + 1) >> 1; + else if(info.bpp == 8) width = s->img_x; + else { + STBI_FREE(out); + return stbi__errpuc("bad bpp", "Corrupt BMP"); + } + pad = (-width) & 3; + if(info.bpp == 1) { + for(j = 0; j < (int) s->img_y; ++j) { + int bit_offset = 7, v = stbi__get8(s); + for(i = 0; i < (int) s->img_x; ++i) { + int color = (v >> bit_offset) & 0x1; + out[z++] = pal[color][0]; + out[z++] = pal[color][1]; + out[z++] = pal[color][2]; + if(target == 4) out[z++] = 255; + if(i + 1 == (int) s->img_x) break; + if((--bit_offset) < 0) { + bit_offset = 7; + v = stbi__get8(s); + } + } + stbi__skip(s, pad); + } + } + else { + for(j = 0; j < (int) s->img_y; ++j) { + for(i = 0; i < (int) s->img_x; i += 2) { + int v = stbi__get8(s), v2 = 0; + if(info.bpp == 4) { + v2 = v & 15; + v >>= 4; + } + out[z++] = pal[v][0]; + out[z++] = pal[v][1]; + out[z++] = pal[v][2]; + if(target == 4) out[z++] = 255; + if(i + 1 == (int) s->img_x) break; + v = (info.bpp == 8) ? stbi__get8(s) : v2; + out[z++] = pal[v][0]; + out[z++] = pal[v][1]; + out[z++] = pal[v][2]; + if(target == 4) out[z++] = 255; + } + stbi__skip(s, pad); + } + } + } + else { + int rshift = 0, gshift = 0, bshift = 0, ashift = 0, rcount = 0, gcount = 0, bcount = 0, acount = 0; + int z = 0; + int easy = 0; + stbi__skip(s, info.offset - info.extra_read - info.hsz); + if(info.bpp == 24) width = 3 * s->img_x; + else if(info.bpp == 16) width = 2 * s->img_x; + else /* bpp = 32 and pad = 0 */ width = 0; + pad = (-width) & 3; + if(info.bpp == 24) { + easy = 1; + } + else if(info.bpp == 32) { + if(mb == 0xff && mg == 0xff00 && mr == 0x00ff0000 && ma == 0xff000000) + easy = 2; + } + if(!easy) { + if(!mr || !mg || !mb) { + STBI_FREE(out); + return stbi__errpuc("bad masks", "Corrupt BMP"); + } + // right shift amt to put high bit in position #7 + rshift = stbi__high_bit(mr) - 7; + rcount = stbi__bitcount(mr); + gshift = stbi__high_bit(mg) - 7; + gcount = stbi__bitcount(mg); + bshift = stbi__high_bit(mb) - 7; + bcount = stbi__bitcount(mb); + ashift = stbi__high_bit(ma) - 7; + acount = stbi__bitcount(ma); + if(rcount > 8 || gcount > 8 || bcount > 8 || acount > 8) { + STBI_FREE(out); + return stbi__errpuc("bad masks", "Corrupt BMP"); + } + } + for(j = 0; j < (int) s->img_y; ++j) { + if(easy) { + for(i = 0; i < (int) s->img_x; ++i) { + unsigned char a; + out[z + 2] = stbi__get8(s); + out[z + 1] = stbi__get8(s); + out[z + 0] = stbi__get8(s); + z += 3; + a = (easy == 2 ? stbi__get8(s) : 255); + all_a |= a; + if(target == 4) out[z++] = a; + } + } + else { + int bpp = info.bpp; + for(i = 0; i < (int) s->img_x; ++i) { + stbi__uint32 v = (bpp == 16 ? (stbi__uint32) stbi__get16le(s) : stbi__get32le(s)); + unsigned int a; + out[z++] = STBI__BYTECAST(stbi__shiftsigned(v & mr, rshift, rcount)); + out[z++] = STBI__BYTECAST(stbi__shiftsigned(v & mg, gshift, gcount)); + out[z++] = STBI__BYTECAST(stbi__shiftsigned(v & mb, bshift, bcount)); + a = (ma ? stbi__shiftsigned(v & ma, ashift, acount) : 255); + all_a |= a; + if(target == 4) out[z++] = STBI__BYTECAST(a); + } + } + stbi__skip(s, pad); + } + } + + // if alpha channel is all 0s, replace with all 255s + if(target == 4 && all_a == 0) + for(i = 4 * s->img_x * s->img_y - 1; i >= 0; i -= 4) + out[i] = 255; + + if(flip_vertically) { + stbi_uc t; + for(j = 0; j < (int) s->img_y >> 1; ++j) { + stbi_uc * p1 = out + j * s->img_x * target; + stbi_uc * p2 = out + (s->img_y - 1 - j) * s->img_x * target; + for(i = 0; i < (int) s->img_x * target; ++i) { + t = p1[i]; + p1[i] = p2[i]; + p2[i] = t; + } + } + } + + if(req_comp && req_comp != target) { + out = stbi__convert_format(out, target, req_comp, s->img_x, s->img_y); + if(out == NULL) return out; // stbi__convert_format frees input on failure + } + + *x = s->img_x; + *y = s->img_y; + if(comp) *comp = s->img_n; + return out; +} +#endif + +// Targa Truevision - TGA +// by Jonathan Dummer +#ifndef STBI_NO_TGA +// returns STBI_rgb or whatever, 0 on error +static int stbi__tga_get_comp(int bits_per_pixel, int is_grey, int * is_rgb16) +{ + // only RGB or RGBA (incl. 16bit) or grey allowed + if(is_rgb16) *is_rgb16 = 0; + switch(bits_per_pixel) { + case 8: + return STBI_grey; + case 16: + if(is_grey) return STBI_grey_alpha; + // fallthrough + case 15: + if(is_rgb16) *is_rgb16 = 1; + return STBI_rgb; + case 24: // fallthrough + case 32: + return bits_per_pixel / 8; + default: + return 0; + } +} + +static int stbi__tga_info(stbi__context * s, int * x, int * y, int * comp) +{ + int tga_w, tga_h, tga_comp, tga_image_type, tga_bits_per_pixel, tga_colormap_bpp; + int sz, tga_colormap_type; + stbi__get8(s); // discard Offset + tga_colormap_type = stbi__get8(s); // colormap type + if(tga_colormap_type > 1) { + stbi__rewind(s); + return 0; // only RGB or indexed allowed + } + tga_image_type = stbi__get8(s); // image type + if(tga_colormap_type == 1) { // colormapped (paletted) image + if(tga_image_type != 1 && tga_image_type != 9) { + stbi__rewind(s); + return 0; + } + stbi__skip(s, 4); // skip index of first colormap entry and number of entries + sz = stbi__get8(s); // check bits per palette color entry + if((sz != 8) && (sz != 15) && (sz != 16) && (sz != 24) && (sz != 32)) { + stbi__rewind(s); + return 0; + } + stbi__skip(s, 4); // skip image x and y origin + tga_colormap_bpp = sz; + } + else { // "normal" image w/o colormap - only RGB or grey allowed, +/- RLE + if((tga_image_type != 2) && (tga_image_type != 3) && (tga_image_type != 10) && (tga_image_type != 11)) { + stbi__rewind(s); + return 0; // only RGB or grey allowed, +/- RLE + } + stbi__skip(s, 9); // skip colormap specification and image x/y origin + tga_colormap_bpp = 0; + } + tga_w = stbi__get16le(s); + if(tga_w < 1) { + stbi__rewind(s); + return 0; // test width + } + tga_h = stbi__get16le(s); + if(tga_h < 1) { + stbi__rewind(s); + return 0; // test height + } + tga_bits_per_pixel = stbi__get8(s); // bits per pixel + stbi__get8(s); // ignore alpha bits + if(tga_colormap_bpp != 0) { + if((tga_bits_per_pixel != 8) && (tga_bits_per_pixel != 16)) { + // when using a colormap, tga_bits_per_pixel is the size of the indexes + // I don't think anything but 8 or 16bit indexes makes sense + stbi__rewind(s); + return 0; + } + tga_comp = stbi__tga_get_comp(tga_colormap_bpp, 0, NULL); + } + else { + tga_comp = stbi__tga_get_comp(tga_bits_per_pixel, (tga_image_type == 3) || (tga_image_type == 11), NULL); + } + if(!tga_comp) { + stbi__rewind(s); + return 0; + } + if(x) *x = tga_w; + if(y) *y = tga_h; + if(comp) *comp = tga_comp; + return 1; // seems to have passed everything +} + +static int stbi__tga_test(stbi__context * s) +{ + int res = 0; + int sz, tga_color_type; + stbi__get8(s); // discard Offset + tga_color_type = stbi__get8(s); // color type + if(tga_color_type > 1) goto errorEnd; // only RGB or indexed allowed + sz = stbi__get8(s); // image type + if(tga_color_type == 1) { // colormapped (paletted) image + if(sz != 1 && sz != 9) goto errorEnd; // colortype 1 demands image type 1 or 9 + stbi__skip(s, 4); // skip index of first colormap entry and number of entries + sz = stbi__get8(s); // check bits per palette color entry + if((sz != 8) && (sz != 15) && (sz != 16) && (sz != 24) && (sz != 32)) goto errorEnd; + stbi__skip(s, 4); // skip image x and y origin + } + else { // "normal" image w/o colormap + if((sz != 2) && (sz != 3) && (sz != 10) && (sz != 11)) goto errorEnd; // only RGB or grey allowed, +/- RLE + stbi__skip(s, 9); // skip colormap specification and image x/y origin + } + if(stbi__get16le(s) < 1) goto errorEnd; // test width + if(stbi__get16le(s) < 1) goto errorEnd; // test height + sz = stbi__get8(s); // bits per pixel + if((tga_color_type == 1) && (sz != 8) && + (sz != 16)) goto errorEnd; // for colormapped images, bpp is size of an index + if((sz != 8) && (sz != 15) && (sz != 16) && (sz != 24) && (sz != 32)) goto errorEnd; + + res = 1; // if we got this far, everything's good and we can return 1 instead of 0 + +errorEnd: + stbi__rewind(s); + return res; +} + +// read 16bit value and convert to 24bit RGB +static void stbi__tga_read_rgb16(stbi__context * s, stbi_uc * out) +{ + stbi__uint16 px = (stbi__uint16)stbi__get16le(s); + stbi__uint16 fiveBitMask = 31; + // we have 3 channels with 5bits each + int r = (px >> 10) & fiveBitMask; + int g = (px >> 5) & fiveBitMask; + int b = px & fiveBitMask; + // Note that this saves the data in RGB(A) order, so it doesn't need to be swapped later + out[0] = (stbi_uc)((r * 255) / 31); + out[1] = (stbi_uc)((g * 255) / 31); + out[2] = (stbi_uc)((b * 255) / 31); + + // some people claim that the most significant bit might be used for alpha + // (possibly if an alpha-bit is set in the "image descriptor byte") + // but that only made 16bit test images completely translucent.. + // so let's treat all 15 and 16bit TGAs as RGB with no alpha. +} + +static void * stbi__tga_load(stbi__context * s, int * x, int * y, int * comp, int req_comp, stbi__result_info * ri) +{ + // read in the TGA header stuff + int tga_offset = stbi__get8(s); + int tga_indexed = stbi__get8(s); + int tga_image_type = stbi__get8(s); + int tga_is_RLE = 0; + int tga_palette_start = stbi__get16le(s); + int tga_palette_len = stbi__get16le(s); + int tga_palette_bits = stbi__get8(s); + int tga_x_origin = stbi__get16le(s); + int tga_y_origin = stbi__get16le(s); + int tga_width = stbi__get16le(s); + int tga_height = stbi__get16le(s); + int tga_bits_per_pixel = stbi__get8(s); + int tga_comp, tga_rgb16 = 0; + int tga_inverted = stbi__get8(s); + // int tga_alpha_bits = tga_inverted & 15; // the 4 lowest bits - unused (useless?) + // image data + unsigned char * tga_data; + unsigned char * tga_palette = NULL; + int i, j; + unsigned char raw_data[4] = {0}; + int RLE_count = 0; + int RLE_repeating = 0; + int read_next_pixel = 1; + STBI_NOTUSED(ri); + STBI_NOTUSED(tga_x_origin); // @TODO + STBI_NOTUSED(tga_y_origin); // @TODO + + if(tga_height > STBI_MAX_DIMENSIONS) return stbi__errpuc("too large", "Very large image (corrupt?)"); + if(tga_width > STBI_MAX_DIMENSIONS) return stbi__errpuc("too large", "Very large image (corrupt?)"); + + // do a tiny bit of precessing + if(tga_image_type >= 8) { + tga_image_type -= 8; + tga_is_RLE = 1; + } + tga_inverted = 1 - ((tga_inverted >> 5) & 1); + + // If I'm paletted, then I'll use the number of bits from the palette + if(tga_indexed) tga_comp = stbi__tga_get_comp(tga_palette_bits, 0, &tga_rgb16); + else tga_comp = stbi__tga_get_comp(tga_bits_per_pixel, (tga_image_type == 3), &tga_rgb16); + + if(!tga_comp) // shouldn't really happen, stbi__tga_test() should have ensured basic consistency + return stbi__errpuc("bad format", "Can't find out TGA pixelformat"); + + // tga info + *x = tga_width; + *y = tga_height; + if(comp) *comp = tga_comp; + + if(!stbi__mad3sizes_valid(tga_width, tga_height, tga_comp, 0)) + return stbi__errpuc("too large", "Corrupt TGA"); + + tga_data = (unsigned char *)stbi__malloc_mad3(tga_width, tga_height, tga_comp, 0); + if(!tga_data) return stbi__errpuc("outofmem", "Out of memory"); + + // skip to the data's starting position (offset usually = 0) + stbi__skip(s, tga_offset); + + if(!tga_indexed && !tga_is_RLE && !tga_rgb16) { + for(i = 0; i < tga_height; ++i) { + int row = tga_inverted ? tga_height - i - 1 : i; + stbi_uc * tga_row = tga_data + row * tga_width * tga_comp; + stbi__getn(s, tga_row, tga_width * tga_comp); + } + } + else { + // do I need to load a palette? + if(tga_indexed) { + if(tga_palette_len == 0) { /* you have to have at least one entry! */ + STBI_FREE(tga_data); + return stbi__errpuc("bad palette", "Corrupt TGA"); + } + + // any data to skip? (offset usually = 0) + stbi__skip(s, tga_palette_start); + // load the palette + tga_palette = (unsigned char *)stbi__malloc_mad2(tga_palette_len, tga_comp, 0); + if(!tga_palette) { + STBI_FREE(tga_data); + return stbi__errpuc("outofmem", "Out of memory"); + } + if(tga_rgb16) { + stbi_uc * pal_entry = tga_palette; + STBI_ASSERT(tga_comp == STBI_rgb); + for(i = 0; i < tga_palette_len; ++i) { + stbi__tga_read_rgb16(s, pal_entry); + pal_entry += tga_comp; + } + } + else if(!stbi__getn(s, tga_palette, tga_palette_len * tga_comp)) { + STBI_FREE(tga_data); + STBI_FREE(tga_palette); + return stbi__errpuc("bad palette", "Corrupt TGA"); + } + } + // load the data + for(i = 0; i < tga_width * tga_height; ++i) { + // if I'm in RLE mode, do I need to get a RLE stbi__pngchunk? + if(tga_is_RLE) { + if(RLE_count == 0) { + // yep, get the next byte as a RLE command + int RLE_cmd = stbi__get8(s); + RLE_count = 1 + (RLE_cmd & 127); + RLE_repeating = RLE_cmd >> 7; + read_next_pixel = 1; + } + else if(!RLE_repeating) { + read_next_pixel = 1; + } + } + else { + read_next_pixel = 1; + } + // OK, if I need to read a pixel, do it now + if(read_next_pixel) { + // load however much data we did have + if(tga_indexed) { + // read in index, then perform the lookup + int pal_idx = (tga_bits_per_pixel == 8) ? stbi__get8(s) : stbi__get16le(s); + if(pal_idx >= tga_palette_len) { + // invalid index + pal_idx = 0; + } + pal_idx *= tga_comp; + for(j = 0; j < tga_comp; ++j) { + raw_data[j] = tga_palette[pal_idx + j]; + } + } + else if(tga_rgb16) { + STBI_ASSERT(tga_comp == STBI_rgb); + stbi__tga_read_rgb16(s, raw_data); + } + else { + // read in the data raw + for(j = 0; j < tga_comp; ++j) { + raw_data[j] = stbi__get8(s); + } + } + // clear the reading flag for the next pixel + read_next_pixel = 0; + } // end of reading a pixel + + // copy data + for(j = 0; j < tga_comp; ++j) + tga_data[i * tga_comp + j] = raw_data[j]; + + // in case we're in RLE mode, keep counting down + --RLE_count; + } + // do I need to invert the image? + if(tga_inverted) { + for(j = 0; j * 2 < tga_height; ++j) { + int index1 = j * tga_width * tga_comp; + int index2 = (tga_height - 1 - j) * tga_width * tga_comp; + for(i = tga_width * tga_comp; i > 0; --i) { + unsigned char temp = tga_data[index1]; + tga_data[index1] = tga_data[index2]; + tga_data[index2] = temp; + ++index1; + ++index2; + } + } + } + // clear my palette, if I had one + if(tga_palette != NULL) { + STBI_FREE(tga_palette); + } + } + + // swap RGB - if the source data was RGB16, it already is in the right order + if(tga_comp >= 3 && !tga_rgb16) { + unsigned char * tga_pixel = tga_data; + for(i = 0; i < tga_width * tga_height; ++i) { + unsigned char temp = tga_pixel[0]; + tga_pixel[0] = tga_pixel[2]; + tga_pixel[2] = temp; + tga_pixel += tga_comp; + } + } + + // convert to target component count + if(req_comp && req_comp != tga_comp) + tga_data = stbi__convert_format(tga_data, tga_comp, req_comp, tga_width, tga_height); + + // the things I do to get rid of an error message, and yet keep + // Microsoft's C compilers happy... [8^( + tga_palette_start = tga_palette_len = tga_palette_bits = + tga_x_origin = tga_y_origin = 0; + STBI_NOTUSED(tga_palette_start); + // OK, done + return tga_data; +} +#endif + +// ************************************************************************************************* +// Photoshop PSD loader -- PD by Thatcher Ulrich, integration by Nicolas Schulz, tweaked by STB + +#ifndef STBI_NO_PSD +static int stbi__psd_test(stbi__context * s) +{ + int r = (stbi__get32be(s) == 0x38425053); + stbi__rewind(s); + return r; +} + +static int stbi__psd_decode_rle(stbi__context * s, stbi_uc * p, int pixelCount) +{ + int count, nleft, len; + + count = 0; + while((nleft = pixelCount - count) > 0) { + len = stbi__get8(s); + if(len == 128) { + // No-op. + } + else if(len < 128) { + // Copy next len+1 bytes literally. + len++; + if(len > nleft) return 0; // corrupt data + count += len; + while(len) { + *p = stbi__get8(s); + p += 4; + len--; + } + } + else if(len > 128) { + stbi_uc val; + // Next -len+1 bytes in the dest are replicated from next source byte. + // (Interpret len as a negative 8-bit int.) + len = 257 - len; + if(len > nleft) return 0; // corrupt data + val = stbi__get8(s); + count += len; + while(len) { + *p = val; + p += 4; + len--; + } + } + } + + return 1; +} + +static void * stbi__psd_load(stbi__context * s, int * x, int * y, int * comp, int req_comp, stbi__result_info * ri, + int bpc) +{ + int pixelCount; + int channelCount, compression; + int channel, i; + int bitdepth; + int w, h; + stbi_uc * out; + STBI_NOTUSED(ri); + + // Check identifier + if(stbi__get32be(s) != 0x38425053) // "8BPS" + return stbi__errpuc("not PSD", "Corrupt PSD image"); + + // Check file type version. + if(stbi__get16be(s) != 1) + return stbi__errpuc("wrong version", "Unsupported version of PSD image"); + + // Skip 6 reserved bytes. + stbi__skip(s, 6); + + // Read the number of channels (R, G, B, A, etc). + channelCount = stbi__get16be(s); + if(channelCount < 0 || channelCount > 16) + return stbi__errpuc("wrong channel count", "Unsupported number of channels in PSD image"); + + // Read the rows and columns of the image. + h = stbi__get32be(s); + w = stbi__get32be(s); + + if(h > STBI_MAX_DIMENSIONS) return stbi__errpuc("too large", "Very large image (corrupt?)"); + if(w > STBI_MAX_DIMENSIONS) return stbi__errpuc("too large", "Very large image (corrupt?)"); + + // Make sure the depth is 8 bits. + bitdepth = stbi__get16be(s); + if(bitdepth != 8 && bitdepth != 16) + return stbi__errpuc("unsupported bit depth", "PSD bit depth is not 8 or 16 bit"); + + // Make sure the color mode is RGB. + // Valid options are: + // 0: Bitmap + // 1: Grayscale + // 2: Indexed color + // 3: RGB color + // 4: CMYK color + // 7: Multichannel + // 8: Duotone + // 9: Lab color + if(stbi__get16be(s) != 3) + return stbi__errpuc("wrong color format", "PSD is not in RGB color format"); + + // Skip the Mode Data. (It's the palette for indexed color; other info for other modes.) + stbi__skip(s, stbi__get32be(s)); + + // Skip the image resources. (resolution, pen tool paths, etc) + stbi__skip(s, stbi__get32be(s)); + + // Skip the reserved data. + stbi__skip(s, stbi__get32be(s)); + + // Find out if the data is compressed. + // Known values: + // 0: no compression + // 1: RLE compressed + compression = stbi__get16be(s); + if(compression > 1) + return stbi__errpuc("bad compression", "PSD has an unknown compression format"); + + // Check size + if(!stbi__mad3sizes_valid(4, w, h, 0)) + return stbi__errpuc("too large", "Corrupt PSD"); + + // Create the destination image. + + if(!compression && bitdepth == 16 && bpc == 16) { + out = (stbi_uc *) stbi__malloc_mad3(8, w, h, 0); + ri->bits_per_channel = 16; + } + else + out = (stbi_uc *) stbi__malloc(4 * w * h); + + if(!out) return stbi__errpuc("outofmem", "Out of memory"); + pixelCount = w * h; + + // Initialize the data to zero. + //memset( out, 0, pixelCount * 4 ); + + // Finally, the image data. + if(compression) { + // RLE as used by .PSD and .TIFF + // Loop until you get the number of unpacked bytes you are expecting: + // Read the next source byte into n. + // If n is between 0 and 127 inclusive, copy the next n+1 bytes literally. + // Else if n is between -127 and -1 inclusive, copy the next byte -n+1 times. + // Else if n is 128, noop. + // Endloop + + // The RLE-compressed data is preceded by a 2-byte data count for each row in the data, + // which we're going to just skip. + stbi__skip(s, h * channelCount * 2); + + // Read the RLE data by channel. + for(channel = 0; channel < 4; channel++) { + stbi_uc * p; + + p = out + channel; + if(channel >= channelCount) { + // Fill this channel with default data. + for(i = 0; i < pixelCount; i++, p += 4) + * p = (channel == 3 ? 255 : 0); + } + else { + // Read the RLE data. + if(!stbi__psd_decode_rle(s, p, pixelCount)) { + STBI_FREE(out); + return stbi__errpuc("corrupt", "bad RLE data"); + } + } + } + + } + else { + // We're at the raw image data. It's each channel in order (Red, Green, Blue, Alpha, ...) + // where each channel consists of an 8-bit (or 16-bit) value for each pixel in the image. + + // Read the data by channel. + for(channel = 0; channel < 4; channel++) { + if(channel >= channelCount) { + // Fill this channel with default data. + if(bitdepth == 16 && bpc == 16) { + stbi__uint16 * q = ((stbi__uint16 *) out) + channel; + stbi__uint16 val = channel == 3 ? 65535 : 0; + for(i = 0; i < pixelCount; i++, q += 4) + * q = val; + } + else { + stbi_uc * p = out + channel; + stbi_uc val = channel == 3 ? 255 : 0; + for(i = 0; i < pixelCount; i++, p += 4) + * p = val; + } + } + else { + if(ri->bits_per_channel == 16) { // output bpc + stbi__uint16 * q = ((stbi__uint16 *) out) + channel; + for(i = 0; i < pixelCount; i++, q += 4) + * q = (stbi__uint16) stbi__get16be(s); + } + else { + stbi_uc * p = out + channel; + if(bitdepth == 16) { // input bpc + for(i = 0; i < pixelCount; i++, p += 4) + * p = (stbi_uc)(stbi__get16be(s) >> 8); + } + else { + for(i = 0; i < pixelCount; i++, p += 4) + * p = stbi__get8(s); + } + } + } + } + } + + // remove weird white matte from PSD + if(channelCount >= 4) { + if(ri->bits_per_channel == 16) { + for(i = 0; i < w * h; ++i) { + stbi__uint16 * pixel = (stbi__uint16 *) out + 4 * i; + if(pixel[3] != 0 && pixel[3] != 65535) { + float a = pixel[3] / 65535.0f; + float ra = 1.0f / a; + float inv_a = 65535.0f * (1 - ra); + pixel[0] = (stbi__uint16)(pixel[0] * ra + inv_a); + pixel[1] = (stbi__uint16)(pixel[1] * ra + inv_a); + pixel[2] = (stbi__uint16)(pixel[2] * ra + inv_a); + } + } + } + else { + for(i = 0; i < w * h; ++i) { + unsigned char * pixel = out + 4 * i; + if(pixel[3] != 0 && pixel[3] != 255) { + float a = pixel[3] / 255.0f; + float ra = 1.0f / a; + float inv_a = 255.0f * (1 - ra); + pixel[0] = (unsigned char)(pixel[0] * ra + inv_a); + pixel[1] = (unsigned char)(pixel[1] * ra + inv_a); + pixel[2] = (unsigned char)(pixel[2] * ra + inv_a); + } + } + } + } + + // convert to desired output format + if(req_comp && req_comp != 4) { + if(ri->bits_per_channel == 16) + out = (stbi_uc *) stbi__convert_format16((stbi__uint16 *) out, 4, req_comp, w, h); + else + out = stbi__convert_format(out, 4, req_comp, w, h); + if(out == NULL) return out; // stbi__convert_format frees input on failure + } + + if(comp) *comp = 4; + *y = h; + *x = w; + + return out; +} +#endif + +// ************************************************************************************************* +// Softimage PIC loader +// by Tom Seddon +// +// See http://softimage.wiki.softimage.com/index.php/INFO:_PIC_file_format +// See http://ozviz.wasp.uwa.edu.au/~pbourke/dataformats/softimagepic/ + +#ifndef STBI_NO_PIC +static int stbi__pic_is4(stbi__context * s, const char * str) +{ + int i; + for(i = 0; i < 4; ++i) + if(stbi__get8(s) != (stbi_uc)str[i]) + return 0; + + return 1; +} + +static int stbi__pic_test_core(stbi__context * s) +{ + int i; + + if(!stbi__pic_is4(s, "\x53\x80\xF6\x34")) + return 0; + + for(i = 0; i < 84; ++i) + stbi__get8(s); + + if(!stbi__pic_is4(s, "PICT")) + return 0; + + return 1; +} + +typedef struct { + stbi_uc size, type, channel; +} stbi__pic_packet; + +static stbi_uc * stbi__readval(stbi__context * s, int channel, stbi_uc * dest) +{ + int mask = 0x80, i; + + for(i = 0; i < 4; ++i, mask >>= 1) { + if(channel & mask) { + if(stbi__at_eof(s)) return stbi__errpuc("bad file", "PIC file too short"); + dest[i] = stbi__get8(s); + } + } + + return dest; +} + +static void stbi__copyval(int channel, stbi_uc * dest, const stbi_uc * src) +{ + int mask = 0x80, i; + + for(i = 0; i < 4; ++i, mask >>= 1) + if(channel & mask) + dest[i] = src[i]; +} + +static stbi_uc * stbi__pic_load_core(stbi__context * s, int width, int height, int * comp, stbi_uc * result) +{ + int act_comp = 0, num_packets = 0, y, chained; + stbi__pic_packet packets[10]; + + // this will (should...) cater for even some bizarre stuff like having data + // for the same channel in multiple packets. + do { + stbi__pic_packet * packet; + + if(num_packets == sizeof(packets) / sizeof(packets[0])) + return stbi__errpuc("bad format", "too many packets"); + + packet = &packets[num_packets++]; + + chained = stbi__get8(s); + packet->size = stbi__get8(s); + packet->type = stbi__get8(s); + packet->channel = stbi__get8(s); + + act_comp |= packet->channel; + + if(stbi__at_eof(s)) return stbi__errpuc("bad file", "file too short (reading packets)"); + if(packet->size != 8) return stbi__errpuc("bad format", "packet isn't 8bpp"); + } while(chained); + + *comp = (act_comp & 0x10 ? 4 : 3); // has alpha channel? + + for(y = 0; y < height; ++y) { + int packet_idx; + + for(packet_idx = 0; packet_idx < num_packets; ++packet_idx) { + stbi__pic_packet * packet = &packets[packet_idx]; + stbi_uc * dest = result + y * width * 4; + + switch(packet->type) { + default: + return stbi__errpuc("bad format", "packet has bad compression type"); + + case 0: {//uncompressed + int x; + + for(x = 0; x < width; ++x, dest += 4) + if(!stbi__readval(s, packet->channel, dest)) + return 0; + break; + } + + case 1: { //Pure RLE + int left = width, i; + + while(left > 0) { + stbi_uc count, value[4]; + + count = stbi__get8(s); + if(stbi__at_eof(s)) return stbi__errpuc("bad file", "file too short (pure read count)"); + + if(count > left) + count = (stbi_uc) left; + + if(!stbi__readval(s, packet->channel, value)) return 0; + + for(i = 0; i < count; ++i, dest += 4) + stbi__copyval(packet->channel, dest, value); + left -= count; + } + } + break; + + case 2: {//Mixed RLE + int left = width; + while(left > 0) { + int count = stbi__get8(s), i; + if(stbi__at_eof(s)) return stbi__errpuc("bad file", "file too short (mixed read count)"); + + if(count >= 128) { // Repeated + stbi_uc value[4]; + + if(count == 128) + count = stbi__get16be(s); + else + count -= 127; + if(count > left) + return stbi__errpuc("bad file", "scanline overrun"); + + if(!stbi__readval(s, packet->channel, value)) + return 0; + + for(i = 0; i < count; ++i, dest += 4) + stbi__copyval(packet->channel, dest, value); + } + else { // Raw + ++count; + if(count > left) return stbi__errpuc("bad file", "scanline overrun"); + + for(i = 0; i < count; ++i, dest += 4) + if(!stbi__readval(s, packet->channel, dest)) + return 0; + } + left -= count; + } + break; + } + } + } + } + + return result; +} + +static void * stbi__pic_load(stbi__context * s, int * px, int * py, int * comp, int req_comp, stbi__result_info * ri) +{ + stbi_uc * result; + int i, x, y, internal_comp; + STBI_NOTUSED(ri); + + if(!comp) comp = &internal_comp; + + for(i = 0; i < 92; ++i) + stbi__get8(s); + + x = stbi__get16be(s); + y = stbi__get16be(s); + + if(y > STBI_MAX_DIMENSIONS) return stbi__errpuc("too large", "Very large image (corrupt?)"); + if(x > STBI_MAX_DIMENSIONS) return stbi__errpuc("too large", "Very large image (corrupt?)"); + + if(stbi__at_eof(s)) return stbi__errpuc("bad file", "file too short (pic header)"); + if(!stbi__mad3sizes_valid(x, y, 4, 0)) return stbi__errpuc("too large", "PIC image too large to decode"); + + stbi__get32be(s); //skip `ratio' + stbi__get16be(s); //skip `fields' + stbi__get16be(s); //skip `pad' + + // intermediate buffer is RGBA + result = (stbi_uc *) stbi__malloc_mad3(x, y, 4, 0); + if(!result) return stbi__errpuc("outofmem", "Out of memory"); + memset(result, 0xff, x * y * 4); + + if(!stbi__pic_load_core(s, x, y, comp, result)) { + STBI_FREE(result); + result = 0; + } + *px = x; + *py = y; + if(req_comp == 0) req_comp = *comp; + result = stbi__convert_format(result, 4, req_comp, x, y); + + return result; +} + +static int stbi__pic_test(stbi__context * s) +{ + int r = stbi__pic_test_core(s); + stbi__rewind(s); + return r; +} +#endif + +// ************************************************************************************************* +// GIF loader -- public domain by Jean-Marc Lienher -- simplified/shrunk by stb + +#ifndef STBI_NO_GIF +typedef struct { + stbi__int16 prefix; + stbi_uc first; + stbi_uc suffix; +} stbi__gif_lzw; + +typedef struct { + int w, h; + stbi_uc * out; // output buffer (always 4 components) + stbi_uc * background; // The current "background" as far as a gif is concerned + stbi_uc * history; + int flags, bgindex, ratio, transparent, eflags; + stbi_uc pal[256][4]; + stbi_uc lpal[256][4]; + stbi__gif_lzw codes[8192]; + stbi_uc * color_table; + int parse, step; + int lflags; + int start_x, start_y; + int max_x, max_y; + int cur_x, cur_y; + int line_size; + int delay; +} stbi__gif; + +static int stbi__gif_test_raw(stbi__context * s) +{ + int sz; + if(stbi__get8(s) != 'G' || stbi__get8(s) != 'I' || stbi__get8(s) != 'F' || stbi__get8(s) != '8') return 0; + sz = stbi__get8(s); + if(sz != '9' && sz != '7') return 0; + if(stbi__get8(s) != 'a') return 0; + return 1; +} + +static int stbi__gif_test(stbi__context * s) +{ + int r = stbi__gif_test_raw(s); + stbi__rewind(s); + return r; +} + +static void stbi__gif_parse_colortable(stbi__context * s, stbi_uc pal[256][4], int num_entries, int transp) +{ + int i; + for(i = 0; i < num_entries; ++i) { + pal[i][2] = stbi__get8(s); + pal[i][1] = stbi__get8(s); + pal[i][0] = stbi__get8(s); + pal[i][3] = transp == i ? 0 : 255; + } +} + +static int stbi__gif_header(stbi__context * s, stbi__gif * g, int * comp, int is_info) +{ + stbi_uc version; + if(stbi__get8(s) != 'G' || stbi__get8(s) != 'I' || stbi__get8(s) != 'F' || stbi__get8(s) != '8') + return stbi__err("not GIF", "Corrupt GIF"); + + version = stbi__get8(s); + if(version != '7' && version != '9') return stbi__err("not GIF", "Corrupt GIF"); + if(stbi__get8(s) != 'a') return stbi__err("not GIF", "Corrupt GIF"); + + stbi__g_failure_reason = ""; + g->w = stbi__get16le(s); + g->h = stbi__get16le(s); + g->flags = stbi__get8(s); + g->bgindex = stbi__get8(s); + g->ratio = stbi__get8(s); + g->transparent = -1; + + if(g->w > STBI_MAX_DIMENSIONS) return stbi__err("too large", "Very large image (corrupt?)"); + if(g->h > STBI_MAX_DIMENSIONS) return stbi__err("too large", "Very large image (corrupt?)"); + + if(comp != 0) *comp = 4; // can't actually tell whether it's 3 or 4 until we parse the comments + + if(is_info) return 1; + + if(g->flags & 0x80) + stbi__gif_parse_colortable(s, g->pal, 2 << (g->flags & 7), -1); + + return 1; +} + +static int stbi__gif_info_raw(stbi__context * s, int * x, int * y, int * comp) +{ + stbi__gif * g = (stbi__gif *) stbi__malloc(sizeof(stbi__gif)); + if(!g) return stbi__err("outofmem", "Out of memory"); + if(!stbi__gif_header(s, g, comp, 1)) { + STBI_FREE(g); + stbi__rewind(s); + return 0; + } + if(x) *x = g->w; + if(y) *y = g->h; + STBI_FREE(g); + return 1; +} + +static void stbi__out_gif_code(stbi__gif * g, stbi__uint16 code) +{ + stbi_uc * p, * c; + int idx; + + // recurse to decode the prefixes, since the linked-list is backwards, + // and working backwards through an interleaved image would be nasty + if(g->codes[code].prefix >= 0) + stbi__out_gif_code(g, g->codes[code].prefix); + + if(g->cur_y >= g->max_y) return; + + idx = g->cur_x + g->cur_y; + p = &g->out[idx]; + g->history[idx / 4] = 1; + + c = &g->color_table[g->codes[code].suffix * 4]; + if(c[3] > 128) { // don't render transparent pixels; + p[0] = c[2]; + p[1] = c[1]; + p[2] = c[0]; + p[3] = c[3]; + } + g->cur_x += 4; + + if(g->cur_x >= g->max_x) { + g->cur_x = g->start_x; + g->cur_y += g->step; + + while(g->cur_y >= g->max_y && g->parse > 0) { + g->step = (1 << g->parse) * g->line_size; + g->cur_y = g->start_y + (g->step >> 1); + --g->parse; + } + } +} + +static stbi_uc * stbi__process_gif_raster(stbi__context * s, stbi__gif * g) +{ + stbi_uc lzw_cs; + stbi__int32 len, init_code; + stbi__uint32 first; + stbi__int32 codesize, codemask, avail, oldcode, bits, valid_bits, clear; + stbi__gif_lzw * p; + + lzw_cs = stbi__get8(s); + if(lzw_cs > 12) return NULL; + clear = 1 << lzw_cs; + first = 1; + codesize = lzw_cs + 1; + codemask = (1 << codesize) - 1; + bits = 0; + valid_bits = 0; + for(init_code = 0; init_code < clear; init_code++) { + g->codes[init_code].prefix = -1; + g->codes[init_code].first = (stbi_uc) init_code; + g->codes[init_code].suffix = (stbi_uc) init_code; + } + + // support no starting clear code + avail = clear + 2; + oldcode = -1; + + len = 0; + for(;;) { + if(valid_bits < codesize) { + if(len == 0) { + len = stbi__get8(s); // start new block + if(len == 0) + return g->out; + } + --len; + bits |= (stbi__int32) stbi__get8(s) << valid_bits; + valid_bits += 8; + } + else { + stbi__int32 code = bits & codemask; + bits >>= codesize; + valid_bits -= codesize; + // @OPTIMIZE: is there some way we can accelerate the non-clear path? + if(code == clear) { // clear code + codesize = lzw_cs + 1; + codemask = (1 << codesize) - 1; + avail = clear + 2; + oldcode = -1; + first = 0; + } + else if(code == clear + 1) { // end of stream code + stbi__skip(s, len); + while((len = stbi__get8(s)) > 0) + stbi__skip(s, len); + return g->out; + } + else if(code <= avail) { + if(first) { + return stbi__errpuc("no clear code", "Corrupt GIF"); + } + + if(oldcode >= 0) { + p = &g->codes[avail++]; + if(avail > 8192) { + return stbi__errpuc("too many codes", "Corrupt GIF"); + } + + p->prefix = (stbi__int16) oldcode; + p->first = g->codes[oldcode].first; + p->suffix = (code == avail) ? p->first : g->codes[code].first; + } + else if(code == avail) + return stbi__errpuc("illegal code in raster", "Corrupt GIF"); + + stbi__out_gif_code(g, (stbi__uint16) code); + + if((avail & codemask) == 0 && avail <= 0x0FFF) { + codesize++; + codemask = (1 << codesize) - 1; + } + + oldcode = code; + } + else { + return stbi__errpuc("illegal code in raster", "Corrupt GIF"); + } + } + } +} + +// this function is designed to support animated gifs, although stb_image doesn't support it +// two back is the image from two frames ago, used for a very specific disposal format +static stbi_uc * stbi__gif_load_next(stbi__context * s, stbi__gif * g, int * comp, int req_comp, stbi_uc * two_back) +{ + int dispose; + int first_frame; + int pi; + int pcount; + STBI_NOTUSED(req_comp); + + // on first frame, any non-written pixels get the background colour (non-transparent) + first_frame = 0; + if(g->out == 0) { + if(!stbi__gif_header(s, g, comp, 0)) return 0; // stbi__g_failure_reason set by stbi__gif_header + if(!stbi__mad3sizes_valid(4, g->w, g->h, 0)) + return stbi__errpuc("too large", "GIF image is too large"); + pcount = g->w * g->h; + g->out = (stbi_uc *) stbi__malloc(4 * pcount); + g->background = (stbi_uc *) stbi__malloc(4 * pcount); + g->history = (stbi_uc *) stbi__malloc(pcount); + if(!g->out || !g->background || !g->history) + return stbi__errpuc("outofmem", "Out of memory"); + + // image is treated as "transparent" at the start - ie, nothing overwrites the current background; + // background colour is only used for pixels that are not rendered first frame, after that "background" + // color refers to the color that was there the previous frame. + memset(g->out, 0x00, 4 * pcount); + memset(g->background, 0x00, 4 * pcount); // state of the background (starts transparent) + memset(g->history, 0x00, pcount); // pixels that were affected previous frame + first_frame = 1; + } + else { + // second frame - how do we dispose of the previous one? + dispose = (g->eflags & 0x1C) >> 2; + pcount = g->w * g->h; + + if((dispose == 3) && (two_back == 0)) { + dispose = 2; // if I don't have an image to revert back to, default to the old background + } + + if(dispose == 3) { // use previous graphic + for(pi = 0; pi < pcount; ++pi) { + if(g->history[pi]) { + memcpy(&g->out[pi * 4], &two_back[pi * 4], 4); + } + } + } + else if(dispose == 2) { + // restore what was changed last frame to background before that frame; + for(pi = 0; pi < pcount; ++pi) { + if(g->history[pi]) { + memcpy(&g->out[pi * 4], &g->background[pi * 4], 4); + } + } + } + else { + // This is a non-disposal case eithe way, so just + // leave the pixels as is, and they will become the new background + // 1: do not dispose + // 0: not specified. + } + + // background is what out is after the undoing of the previou frame; + memcpy(g->background, g->out, 4 * g->w * g->h); + } + + // clear my history; + memset(g->history, 0x00, g->w * g->h); // pixels that were affected previous frame + + for(;;) { + int tag = stbi__get8(s); + switch(tag) { + case 0x2C: { /* Image Descriptor */ + stbi__int32 x, y, w, h; + stbi_uc * o; + + x = stbi__get16le(s); + y = stbi__get16le(s); + w = stbi__get16le(s); + h = stbi__get16le(s); + if(((x + w) > (g->w)) || ((y + h) > (g->h))) + return stbi__errpuc("bad Image Descriptor", "Corrupt GIF"); + + g->line_size = g->w * 4; + g->start_x = x * 4; + g->start_y = y * g->line_size; + g->max_x = g->start_x + w * 4; + g->max_y = g->start_y + h * g->line_size; + g->cur_x = g->start_x; + g->cur_y = g->start_y; + + // if the width of the specified rectangle is 0, that means + // we may not see *any* pixels or the image is malformed; + // to make sure this is caught, move the current y down to + // max_y (which is what out_gif_code checks). + if(w == 0) + g->cur_y = g->max_y; + + g->lflags = stbi__get8(s); + + if(g->lflags & 0x40) { + g->step = 8 * g->line_size; // first interlaced spacing + g->parse = 3; + } + else { + g->step = g->line_size; + g->parse = 0; + } + + if(g->lflags & 0x80) { + stbi__gif_parse_colortable(s, g->lpal, 2 << (g->lflags & 7), g->eflags & 0x01 ? g->transparent : -1); + g->color_table = (stbi_uc *) g->lpal; + } + else if(g->flags & 0x80) { + g->color_table = (stbi_uc *) g->pal; + } + else + return stbi__errpuc("missing color table", "Corrupt GIF"); + + o = stbi__process_gif_raster(s, g); + if(!o) return NULL; + + // if this was the first frame, + pcount = g->w * g->h; + if(first_frame && (g->bgindex > 0)) { + // if first frame, any pixel not drawn to gets the background color + for(pi = 0; pi < pcount; ++pi) { + if(g->history[pi] == 0) { + g->pal[g->bgindex][3] = 255; // just in case it was made transparent, undo that; It will be reset next frame if need be; + memcpy(&g->out[pi * 4], &g->pal[g->bgindex], 4); + } + } + } + + return o; + } + + case 0x21: { // Comment Extension. + int len; + int ext = stbi__get8(s); + if(ext == 0xF9) { // Graphic Control Extension. + len = stbi__get8(s); + if(len == 4) { + g->eflags = stbi__get8(s); + g->delay = 10 * stbi__get16le(s); // delay - 1/100th of a second, saving as 1/1000ths. + + // unset old transparent + if(g->transparent >= 0) { + g->pal[g->transparent][3] = 255; + } + if(g->eflags & 0x01) { + g->transparent = stbi__get8(s); + if(g->transparent >= 0) { + g->pal[g->transparent][3] = 0; + } + } + else { + // don't need transparent + stbi__skip(s, 1); + g->transparent = -1; + } + } + else { + stbi__skip(s, len); + break; + } + } + while((len = stbi__get8(s)) != 0) { + stbi__skip(s, len); + } + break; + } + + case 0x3B: // gif stream termination code + return (stbi_uc *) s; // using '1' causes warning on some compilers + + default: + return stbi__errpuc("unknown code", "Corrupt GIF"); + } + } +} + +static void * stbi__load_gif_main_outofmem(stbi__gif * g, stbi_uc * out, int ** delays) +{ + STBI_FREE(g->out); + STBI_FREE(g->history); + STBI_FREE(g->background); + + if(out) STBI_FREE(out); + if(delays && *delays) STBI_FREE(*delays); + return stbi__errpuc("outofmem", "Out of memory"); +} + +static void * stbi__load_gif_main(stbi__context * s, int ** delays, int * x, int * y, int * z, int * comp, int req_comp) +{ + if(stbi__gif_test(s)) { + int layers = 0; + stbi_uc * u = 0; + stbi_uc * out = 0; + stbi_uc * two_back = 0; + stbi__gif g; + int stride; + int out_size = 0; + int delays_size = 0; + + STBI_NOTUSED(out_size); + STBI_NOTUSED(delays_size); + + memset(&g, 0, sizeof(g)); + if(delays) { + *delays = 0; + } + + do { + u = stbi__gif_load_next(s, &g, comp, req_comp, two_back); + if(u == (stbi_uc *) s) u = 0; // end of animated gif marker + + if(u) { + *x = g.w; + *y = g.h; + ++layers; + stride = g.w * g.h * 4; + + if(out) { + void * tmp = (stbi_uc *) STBI_REALLOC_SIZED(out, out_size, layers * stride); + if(!tmp) + return stbi__load_gif_main_outofmem(&g, out, delays); + else { + out = (stbi_uc *) tmp; + out_size = layers * stride; + } + + if(delays) { + int * new_delays = (int *) STBI_REALLOC_SIZED(*delays, delays_size, sizeof(int) * layers); + if(!new_delays) + return stbi__load_gif_main_outofmem(&g, out, delays); + *delays = new_delays; + delays_size = layers * sizeof(int); + } + } + else { + out = (stbi_uc *)stbi__malloc(layers * stride); + if(!out) + return stbi__load_gif_main_outofmem(&g, out, delays); + out_size = layers * stride; + if(delays) { + *delays = (int *) stbi__malloc(layers * sizeof(int)); + if(!*delays) + return stbi__load_gif_main_outofmem(&g, out, delays); + delays_size = layers * sizeof(int); + } + } + memcpy(out + ((layers - 1) * stride), u, stride); + if(layers >= 2) { + two_back = out - 2 * stride; + } + + if(delays) { + (*delays)[layers - 1U] = g.delay; + } + } + } while(u != 0); + + // free temp buffer; + STBI_FREE(g.out); + STBI_FREE(g.history); + STBI_FREE(g.background); + + // do the final conversion after loading everything; + if(req_comp && req_comp != 4) + out = stbi__convert_format(out, 4, req_comp, layers * g.w, g.h); + + *z = layers; + return out; + } + else { + return stbi__errpuc("not GIF", "Image was not as a gif type."); + } +} + +static void * stbi__gif_load(stbi__context * s, int * x, int * y, int * comp, int req_comp, stbi__result_info * ri) +{ + stbi_uc * u = 0; + stbi__gif g; + memset(&g, 0, sizeof(g)); + STBI_NOTUSED(ri); + + u = stbi__gif_load_next(s, &g, comp, req_comp, 0); + if(u == (stbi_uc *) s) u = 0; // end of animated gif marker + if(u) { + *x = g.w; + *y = g.h; + + // moved conversion to after successful load so that the same + // can be done for multiple frames. + if(req_comp && req_comp != 4) + u = stbi__convert_format(u, 4, req_comp, g.w, g.h); + } + else if(g.out) { + // if there was an error and we allocated an image buffer, free it! + STBI_FREE(g.out); + } + + // free buffers needed for multiple frame loading; + STBI_FREE(g.history); + STBI_FREE(g.background); + + return u; +} + +static int stbi__gif_info(stbi__context * s, int * x, int * y, int * comp) +{ + return stbi__gif_info_raw(s, x, y, comp); +} +#endif + +// ************************************************************************************************* +// Radiance RGBE HDR loader +// originally by Nicolas Schulz +#ifndef STBI_NO_HDR +static int stbi__hdr_test_core(stbi__context * s, const char * signature) +{ + int i; + for(i = 0; signature[i]; ++i) + if(stbi__get8(s) != signature[i]) + return 0; + stbi__rewind(s); + return 1; +} + +static int stbi__hdr_test(stbi__context * s) +{ + int r = stbi__hdr_test_core(s, "#?RADIANCE\n"); + stbi__rewind(s); + if(!r) { + r = stbi__hdr_test_core(s, "#?RGBE\n"); + stbi__rewind(s); + } + return r; +} + +#define STBI__HDR_BUFLEN 1024 +static char * stbi__hdr_gettoken(stbi__context * z, char * buffer) +{ + int len = 0; + char c = '\0'; + + c = (char) stbi__get8(z); + + while(!stbi__at_eof(z) && c != '\n') { + buffer[len++] = c; + if(len == STBI__HDR_BUFLEN - 1) { + // flush to end of line + while(!stbi__at_eof(z) && stbi__get8(z) != '\n') + ; + break; + } + c = (char) stbi__get8(z); + } + + buffer[len] = 0; + return buffer; +} + +static void stbi__hdr_convert(float * output, stbi_uc * input, int req_comp) +{ + if(input[3] != 0) { + float f1; + // Exponent + f1 = (float) ldexp(1.0f, input[3] - (int)(128 + 8)); + if(req_comp <= 2) + output[0] = (input[0] + input[1] + input[2]) * f1 / 3; + else { + output[0] = input[0] * f1; + output[1] = input[1] * f1; + output[2] = input[2] * f1; + } + if(req_comp == 2) output[1] = 1; + if(req_comp == 4) output[3] = 1; + } + else { + switch(req_comp) { + case 4: + output[3] = 1; /* fallthrough */ + case 3: + output[0] = output[1] = output[2] = 0; + break; + case 2: + output[1] = 1; /* fallthrough */ + case 1: + output[0] = 0; + break; + } + } +} + +static float * stbi__hdr_load(stbi__context * s, int * x, int * y, int * comp, int req_comp, stbi__result_info * ri) +{ + char buffer[STBI__HDR_BUFLEN]; + char * token; + int valid = 0; + int width, height; + stbi_uc * scanline; + float * hdr_data; + int len; + unsigned char count, value; + int i, j, k, c1, c2, z; + const char * headerToken; + STBI_NOTUSED(ri); + + // Check identifier + headerToken = stbi__hdr_gettoken(s, buffer); + if(strcmp(headerToken, "#?RADIANCE") != 0 && strcmp(headerToken, "#?RGBE") != 0) + return stbi__errpf("not HDR", "Corrupt HDR image"); + + // Parse header + for(;;) { + token = stbi__hdr_gettoken(s, buffer); + if(token[0] == 0) break; + if(strcmp(token, "FORMAT=32-bit_rle_rgbe") == 0) valid = 1; + } + + if(!valid) return stbi__errpf("unsupported format", "Unsupported HDR format"); + + // Parse width and height + // can't use sscanf() if we're not using stdio! + token = stbi__hdr_gettoken(s, buffer); + if(strncmp(token, "-Y ", 3)) return stbi__errpf("unsupported data layout", "Unsupported HDR format"); + token += 3; + height = (int) strtol(token, &token, 10); + while(*token == ' ') ++token; + if(strncmp(token, "+X ", 3)) return stbi__errpf("unsupported data layout", "Unsupported HDR format"); + token += 3; + width = (int) strtol(token, NULL, 10); + + if(height > STBI_MAX_DIMENSIONS) return stbi__errpf("too large", "Very large image (corrupt?)"); + if(width > STBI_MAX_DIMENSIONS) return stbi__errpf("too large", "Very large image (corrupt?)"); + + *x = width; + *y = height; + + if(comp) *comp = 3; + if(req_comp == 0) req_comp = 3; + + if(!stbi__mad4sizes_valid(width, height, req_comp, sizeof(float), 0)) + return stbi__errpf("too large", "HDR image is too large"); + + // Read data + hdr_data = (float *) stbi__malloc_mad4(width, height, req_comp, sizeof(float), 0); + if(!hdr_data) + return stbi__errpf("outofmem", "Out of memory"); + + // Load image data + // image data is stored as some number of sca + if(width < 8 || width >= 32768) { + // Read flat data + for(j = 0; j < height; ++j) { + for(i = 0; i < width; ++i) { + stbi_uc rgbe[4]; +main_decode_loop: + stbi__getn(s, rgbe, 4); + stbi__hdr_convert(hdr_data + j * width * req_comp + i * req_comp, rgbe, req_comp); + } + } + } + else { + // Read RLE-encoded data + scanline = NULL; + + for(j = 0; j < height; ++j) { + c1 = stbi__get8(s); + c2 = stbi__get8(s); + len = stbi__get8(s); + if(c1 != 2 || c2 != 2 || (len & 0x80)) { + // not run-length encoded, so we have to actually use THIS data as a decoded + // pixel (note this can't be a valid pixel--one of RGB must be >= 128) + stbi_uc rgbe[4]; + rgbe[0] = (stbi_uc) c1; + rgbe[1] = (stbi_uc) c2; + rgbe[2] = (stbi_uc) len; + rgbe[3] = (stbi_uc) stbi__get8(s); + stbi__hdr_convert(hdr_data, rgbe, req_comp); + i = 1; + j = 0; + STBI_FREE(scanline); + goto main_decode_loop; // yes, this makes no sense + } + len <<= 8; + len |= stbi__get8(s); + if(len != width) { + STBI_FREE(hdr_data); + STBI_FREE(scanline); + return stbi__errpf("invalid decoded scanline length", "corrupt HDR"); + } + if(scanline == NULL) { + scanline = (stbi_uc *) stbi__malloc_mad2(width, 4, 0); + if(!scanline) { + STBI_FREE(hdr_data); + return stbi__errpf("outofmem", "Out of memory"); + } + } + + for(k = 0; k < 4; ++k) { + int nleft; + i = 0; + while((nleft = width - i) > 0) { + count = stbi__get8(s); + if(count > 128) { + // Run + value = stbi__get8(s); + count -= 128; + if((count == 0) || (count > nleft)) { + STBI_FREE(hdr_data); + STBI_FREE(scanline); + return stbi__errpf("corrupt", "bad RLE data in HDR"); + } + for(z = 0; z < count; ++z) + scanline[i++ * 4 + k] = value; + } + else { + // Dump + if((count == 0) || (count > nleft)) { + STBI_FREE(hdr_data); + STBI_FREE(scanline); + return stbi__errpf("corrupt", "bad RLE data in HDR"); + } + for(z = 0; z < count; ++z) + scanline[i++ * 4 + k] = stbi__get8(s); + } + } + } + for(i = 0; i < width; ++i) + stbi__hdr_convert(hdr_data + (j * width + i) * req_comp, scanline + i * 4, req_comp); + } + if(scanline) + STBI_FREE(scanline); + } + + return hdr_data; +} + +static int stbi__hdr_info(stbi__context * s, int * x, int * y, int * comp) +{ + char buffer[STBI__HDR_BUFLEN]; + char * token; + int valid = 0; + int dummy; + + if(!x) x = &dummy; + if(!y) y = &dummy; + if(!comp) comp = &dummy; + + if(stbi__hdr_test(s) == 0) { + stbi__rewind(s); + return 0; + } + + for(;;) { + token = stbi__hdr_gettoken(s, buffer); + if(token[0] == 0) break; + if(strcmp(token, "FORMAT=32-bit_rle_rgbe") == 0) valid = 1; + } + + if(!valid) { + stbi__rewind(s); + return 0; + } + token = stbi__hdr_gettoken(s, buffer); + if(strncmp(token, "-Y ", 3)) { + stbi__rewind(s); + return 0; + } + token += 3; + *y = (int) strtol(token, &token, 10); + while(*token == ' ') ++token; + if(strncmp(token, "+X ", 3)) { + stbi__rewind(s); + return 0; + } + token += 3; + *x = (int) strtol(token, NULL, 10); + *comp = 3; + return 1; +} +#endif // STBI_NO_HDR + +#ifndef STBI_NO_BMP +static int stbi__bmp_info(stbi__context * s, int * x, int * y, int * comp) +{ + void * p; + stbi__bmp_data info; + + info.all_a = 255; + p = stbi__bmp_parse_header(s, &info); + if(p == NULL) { + stbi__rewind(s); + return 0; + } + if(x) *x = s->img_x; + if(y) *y = s->img_y; + if(comp) { + if(info.bpp == 24 && info.ma == 0xff000000) + *comp = 3; + else + *comp = info.ma ? 4 : 3; + } + return 1; +} +#endif + +#ifndef STBI_NO_PSD +static int stbi__psd_info(stbi__context * s, int * x, int * y, int * comp) +{ + int channelCount, dummy, depth; + if(!x) x = &dummy; + if(!y) y = &dummy; + if(!comp) comp = &dummy; + if(stbi__get32be(s) != 0x38425053) { + stbi__rewind(s); + return 0; + } + if(stbi__get16be(s) != 1) { + stbi__rewind(s); + return 0; + } + stbi__skip(s, 6); + channelCount = stbi__get16be(s); + if(channelCount < 0 || channelCount > 16) { + stbi__rewind(s); + return 0; + } + *y = stbi__get32be(s); + *x = stbi__get32be(s); + depth = stbi__get16be(s); + if(depth != 8 && depth != 16) { + stbi__rewind(s); + return 0; + } + if(stbi__get16be(s) != 3) { + stbi__rewind(s); + return 0; + } + *comp = 4; + return 1; +} + +static int stbi__psd_is16(stbi__context * s) +{ + int channelCount, depth; + if(stbi__get32be(s) != 0x38425053) { + stbi__rewind(s); + return 0; + } + if(stbi__get16be(s) != 1) { + stbi__rewind(s); + return 0; + } + stbi__skip(s, 6); + channelCount = stbi__get16be(s); + if(channelCount < 0 || channelCount > 16) { + stbi__rewind(s); + return 0; + } + STBI_NOTUSED(stbi__get32be(s)); + STBI_NOTUSED(stbi__get32be(s)); + depth = stbi__get16be(s); + if(depth != 16) { + stbi__rewind(s); + return 0; + } + return 1; +} +#endif + +#ifndef STBI_NO_PIC +static int stbi__pic_info(stbi__context * s, int * x, int * y, int * comp) +{ + int act_comp = 0, num_packets = 0, chained, dummy; + stbi__pic_packet packets[10]; + + if(!x) x = &dummy; + if(!y) y = &dummy; + if(!comp) comp = &dummy; + + if(!stbi__pic_is4(s, "\x53\x80\xF6\x34")) { + stbi__rewind(s); + return 0; + } + + stbi__skip(s, 88); + + *x = stbi__get16be(s); + *y = stbi__get16be(s); + if(stbi__at_eof(s)) { + stbi__rewind(s); + return 0; + } + if((*x) != 0 && (1 << 28) / (*x) < (*y)) { + stbi__rewind(s); + return 0; + } + + stbi__skip(s, 8); + + do { + stbi__pic_packet * packet; + + if(num_packets == sizeof(packets) / sizeof(packets[0])) + return 0; + + packet = &packets[num_packets++]; + chained = stbi__get8(s); + packet->size = stbi__get8(s); + packet->type = stbi__get8(s); + packet->channel = stbi__get8(s); + act_comp |= packet->channel; + + if(stbi__at_eof(s)) { + stbi__rewind(s); + return 0; + } + if(packet->size != 8) { + stbi__rewind(s); + return 0; + } + } while(chained); + + *comp = (act_comp & 0x10 ? 4 : 3); + + return 1; +} +#endif + +// ************************************************************************************************* +// Portable Gray Map and Portable Pixel Map loader +// by Ken Miller +// +// PGM: http://netpbm.sourceforge.net/doc/pgm.html +// PPM: http://netpbm.sourceforge.net/doc/ppm.html +// +// Known limitations: +// Does not support comments in the header section +// Does not support ASCII image data (formats P2 and P3) + +#ifndef STBI_NO_PNM + +static int stbi__pnm_test(stbi__context * s) +{ + char p, t; + p = (char) stbi__get8(s); + t = (char) stbi__get8(s); + if(p != 'P' || (t != '5' && t != '6')) { + stbi__rewind(s); + return 0; + } + return 1; +} + +static void * stbi__pnm_load(stbi__context * s, int * x, int * y, int * comp, int req_comp, stbi__result_info * ri) +{ + stbi_uc * out; + STBI_NOTUSED(ri); + + ri->bits_per_channel = stbi__pnm_info(s, (int *)&s->img_x, (int *)&s->img_y, (int *)&s->img_n); + if(ri->bits_per_channel == 0) + return 0; + + if(s->img_y > STBI_MAX_DIMENSIONS) return stbi__errpuc("too large", "Very large image (corrupt?)"); + if(s->img_x > STBI_MAX_DIMENSIONS) return stbi__errpuc("too large", "Very large image (corrupt?)"); + + *x = s->img_x; + *y = s->img_y; + if(comp) *comp = s->img_n; + + if(!stbi__mad4sizes_valid(s->img_n, s->img_x, s->img_y, ri->bits_per_channel / 8, 0)) + return stbi__errpuc("too large", "PNM too large"); + + out = (stbi_uc *) stbi__malloc_mad4(s->img_n, s->img_x, s->img_y, ri->bits_per_channel / 8, 0); + if(!out) return stbi__errpuc("outofmem", "Out of memory"); + if(!stbi__getn(s, out, s->img_n * s->img_x * s->img_y * (ri->bits_per_channel / 8))) { + STBI_FREE(out); + return stbi__errpuc("bad PNM", "PNM file truncated"); + } + + if(req_comp && req_comp != s->img_n) { + if(ri->bits_per_channel == 16) { + out = (stbi_uc *) stbi__convert_format16((stbi__uint16 *) out, s->img_n, req_comp, s->img_x, s->img_y); + } + else { + out = stbi__convert_format(out, s->img_n, req_comp, s->img_x, s->img_y); + } + if(out == NULL) return out; // stbi__convert_format frees input on failure + } + return out; +} + +static int stbi__pnm_isspace(char c) +{ + return c == ' ' || c == '\t' || c == '\n' || c == '\v' || c == '\f' || c == '\r'; +} + +static void stbi__pnm_skip_whitespace(stbi__context * s, char * c) +{ + for(;;) { + while(!stbi__at_eof(s) && stbi__pnm_isspace(*c)) + *c = (char) stbi__get8(s); + + if(stbi__at_eof(s) || *c != '#') + break; + + while(!stbi__at_eof(s) && *c != '\n' && *c != '\r') + *c = (char) stbi__get8(s); + } +} + +static int stbi__pnm_isdigit(char c) +{ + return c >= '0' && c <= '9'; +} + +static int stbi__pnm_getinteger(stbi__context * s, char * c) +{ + int value = 0; + + while(!stbi__at_eof(s) && stbi__pnm_isdigit(*c)) { + value = value * 10 + (*c - '0'); + *c = (char) stbi__get8(s); + if((value > 214748364) || (value == 214748364 && *c > '7')) + return stbi__err("integer parse overflow", "Parsing an integer in the PPM header overflowed a 32-bit int"); + } + + return value; +} + +static int stbi__pnm_info(stbi__context * s, int * x, int * y, int * comp) +{ + int maxv, dummy; + char c, p, t; + + if(!x) x = &dummy; + if(!y) y = &dummy; + if(!comp) comp = &dummy; + + stbi__rewind(s); + + // Get identifier + p = (char) stbi__get8(s); + t = (char) stbi__get8(s); + if(p != 'P' || (t != '5' && t != '6')) { + stbi__rewind(s); + return 0; + } + + *comp = (t == '6') ? 3 : 1; // '5' is 1-component .pgm; '6' is 3-component .ppm + + c = (char) stbi__get8(s); + stbi__pnm_skip_whitespace(s, &c); + + *x = stbi__pnm_getinteger(s, &c); // read width + if(*x == 0) + return stbi__err("invalid width", "PPM image header had zero or overflowing width"); + stbi__pnm_skip_whitespace(s, &c); + + *y = stbi__pnm_getinteger(s, &c); // read height + if(*y == 0) + return stbi__err("invalid width", "PPM image header had zero or overflowing width"); + stbi__pnm_skip_whitespace(s, &c); + + maxv = stbi__pnm_getinteger(s, &c); // read max value + if(maxv > 65535) + return stbi__err("max value > 65535", "PPM image supports only 8-bit and 16-bit images"); + else if(maxv > 255) + return 16; + else + return 8; +} + +static int stbi__pnm_is16(stbi__context * s) +{ + if(stbi__pnm_info(s, NULL, NULL, NULL) == 16) + return 1; + return 0; +} +#endif + +static int stbi__info_main(stbi__context * s, int * x, int * y, int * comp) +{ +#ifndef STBI_NO_JPEG + if(stbi__jpeg_info(s, x, y, comp)) return 1; +#endif + +#ifndef STBI_NO_PNG + if(stbi__png_info(s, x, y, comp)) return 1; +#endif + +#ifndef STBI_NO_GIF + if(stbi__gif_info(s, x, y, comp)) return 1; +#endif + +#ifndef STBI_NO_BMP + if(stbi__bmp_info(s, x, y, comp)) return 1; +#endif + +#ifndef STBI_NO_PSD + if(stbi__psd_info(s, x, y, comp)) return 1; +#endif + +#ifndef STBI_NO_PIC + if(stbi__pic_info(s, x, y, comp)) return 1; +#endif + +#ifndef STBI_NO_PNM + if(stbi__pnm_info(s, x, y, comp)) return 1; +#endif + +#ifndef STBI_NO_HDR + if(stbi__hdr_info(s, x, y, comp)) return 1; +#endif + + // test tga last because it's a crappy test! +#ifndef STBI_NO_TGA + if(stbi__tga_info(s, x, y, comp)) + return 1; +#endif + return stbi__err("unknown image type", "Image not of any known type, or corrupt"); +} + +static int stbi__is_16_main(stbi__context * s) +{ +#ifndef STBI_NO_PNG + if(stbi__png_is16(s)) return 1; +#endif + +#ifndef STBI_NO_PSD + if(stbi__psd_is16(s)) return 1; +#endif + +#ifndef STBI_NO_PNM + if(stbi__pnm_is16(s)) return 1; +#endif + return 0; +} + +#ifndef STBI_NO_STDIO +STBIDEF int stbi_info(char const * filename, int * x, int * y, int * comp) +{ + FILE * f = stbi__fopen(filename, "rb"); + int result; + if(!f) return stbi__err("can't fopen", "Unable to open file"); + result = stbi_info_from_file(f, x, y, comp); + fclose(f); + return result; +} + +STBIDEF int stbi_info_from_file(FILE * f, int * x, int * y, int * comp) +{ + int r; + stbi__context s; + long pos = ftell(f); + stbi__start_file(&s, f); + r = stbi__info_main(&s, x, y, comp); + fseek(f, pos, SEEK_SET); + return r; +} + +STBIDEF int stbi_is_16_bit(char const * filename) +{ + FILE * f = stbi__fopen(filename, "rb"); + int result; + if(!f) return stbi__err("can't fopen", "Unable to open file"); + result = stbi_is_16_bit_from_file(f); + fclose(f); + return result; +} + +STBIDEF int stbi_is_16_bit_from_file(FILE * f) +{ + int r; + stbi__context s; + long pos = ftell(f); + stbi__start_file(&s, f); + r = stbi__is_16_main(&s); + fseek(f, pos, SEEK_SET); + return r; +} +#endif // !STBI_NO_STDIO + +STBIDEF int stbi_info_from_memory(stbi_uc const * buffer, int len, int * x, int * y, int * comp) +{ + stbi__context s; + stbi__start_mem(&s, buffer, len); + return stbi__info_main(&s, x, y, comp); +} + +STBIDEF int stbi_info_from_callbacks(stbi_io_callbacks const * c, void * user, int * x, int * y, int * comp) +{ + stbi__context s; + stbi__start_callbacks(&s, (stbi_io_callbacks *) c, user); + return stbi__info_main(&s, x, y, comp); +} + +STBIDEF int stbi_is_16_bit_from_memory(stbi_uc const * buffer, int len) +{ + stbi__context s; + stbi__start_mem(&s, buffer, len); + return stbi__is_16_main(&s); +} + +STBIDEF int stbi_is_16_bit_from_callbacks(stbi_io_callbacks const * c, void * user) +{ + stbi__context s; + stbi__start_callbacks(&s, (stbi_io_callbacks *) c, user); + return stbi__is_16_main(&s); +} + +#endif // STB_IMAGE_IMPLEMENTATION + +/* + revision history: + 2.20 (2019-02-07) support utf8 filenames in Windows; fix warnings and platform ifdefs + 2.19 (2018-02-11) fix warning + 2.18 (2018-01-30) fix warnings + 2.17 (2018-01-29) change sbti__shiftsigned to avoid clang -O2 bug + 1-bit BMP + *_is_16_bit api + avoid warnings + 2.16 (2017-07-23) all functions have 16-bit variants; + STBI_NO_STDIO works again; + compilation fixes; + fix rounding in unpremultiply; + optimize vertical flip; + disable raw_len validation; + documentation fixes + 2.15 (2017-03-18) fix png-1,2,4 bug; now all Imagenet JPGs decode; + warning fixes; disable run-time SSE detection on gcc; + uniform handling of optional "return" values; + thread-safe initialization of zlib tables + 2.14 (2017-03-03) remove deprecated STBI_JPEG_OLD; fixes for Imagenet JPGs + 2.13 (2016-11-29) add 16-bit API, only supported for PNG right now + 2.12 (2016-04-02) fix typo in 2.11 PSD fix that caused crashes + 2.11 (2016-04-02) allocate large structures on the stack + remove white matting for transparent PSD + fix reported channel count for PNG & BMP + re-enable SSE2 in non-gcc 64-bit + support RGB-formatted JPEG + read 16-bit PNGs (only as 8-bit) + 2.10 (2016-01-22) avoid warning introduced in 2.09 by STBI_REALLOC_SIZED + 2.09 (2016-01-16) allow comments in PNM files + 16-bit-per-pixel TGA (not bit-per-component) + info() for TGA could break due to .hdr handling + info() for BMP to shares code instead of sloppy parse + can use STBI_REALLOC_SIZED if allocator doesn't support realloc + code cleanup + 2.08 (2015-09-13) fix to 2.07 cleanup, reading RGB PSD as RGBA + 2.07 (2015-09-13) fix compiler warnings + partial animated GIF support + limited 16-bpc PSD support + #ifdef unused functions + bug with < 92 byte PIC,PNM,HDR,TGA + 2.06 (2015-04-19) fix bug where PSD returns wrong '*comp' value + 2.05 (2015-04-19) fix bug in progressive JPEG handling, fix warning + 2.04 (2015-04-15) try to re-enable SIMD on MinGW 64-bit + 2.03 (2015-04-12) extra corruption checking (mmozeiko) + stbi_set_flip_vertically_on_load (nguillemot) + fix NEON support; fix mingw support + 2.02 (2015-01-19) fix incorrect assert, fix warning + 2.01 (2015-01-17) fix various warnings; suppress SIMD on gcc 32-bit without -msse2 + 2.00b (2014-12-25) fix STBI_MALLOC in progressive JPEG + 2.00 (2014-12-25) optimize JPG, including x86 SSE2 & NEON SIMD (ryg) + progressive JPEG (stb) + PGM/PPM support (Ken Miller) + STBI_MALLOC,STBI_REALLOC,STBI_FREE + GIF bugfix -- seemingly never worked + STBI_NO_*, STBI_ONLY_* + 1.48 (2014-12-14) fix incorrectly-named assert() + 1.47 (2014-12-14) 1/2/4-bit PNG support, both direct and paletted (Omar Cornut & stb) + optimize PNG (ryg) + fix bug in interlaced PNG with user-specified channel count (stb) + 1.46 (2014-08-26) + fix broken tRNS chunk (colorkey-style transparency) in non-paletted PNG + 1.45 (2014-08-16) + fix MSVC-ARM internal compiler error by wrapping malloc + 1.44 (2014-08-07) + various warning fixes from Ronny Chevalier + 1.43 (2014-07-15) + fix MSVC-only compiler problem in code changed in 1.42 + 1.42 (2014-07-09) + don't define _CRT_SECURE_NO_WARNINGS (affects user code) + fixes to stbi__cleanup_jpeg path + added STBI_ASSERT to avoid requiring assert.h + 1.41 (2014-06-25) + fix search&replace from 1.36 that messed up comments/error messages + 1.40 (2014-06-22) + fix gcc struct-initialization warning + 1.39 (2014-06-15) + fix to TGA optimization when req_comp != number of components in TGA; + fix to GIF loading because BMP wasn't rewinding (whoops, no GIFs in my test suite) + add support for BMP version 5 (more ignored fields) + 1.38 (2014-06-06) + suppress MSVC warnings on integer casts truncating values + fix accidental rename of 'skip' field of I/O + 1.37 (2014-06-04) + remove duplicate typedef + 1.36 (2014-06-03) + convert to header file single-file library + if de-iphone isn't set, load iphone images color-swapped instead of returning NULL + 1.35 (2014-05-27) + various warnings + fix broken STBI_SIMD path + fix bug where stbi_load_from_file no longer left file pointer in correct place + fix broken non-easy path for 32-bit BMP (possibly never used) + TGA optimization by Arseny Kapoulkine + 1.34 (unknown) + use STBI_NOTUSED in stbi__resample_row_generic(), fix one more leak in tga failure case + 1.33 (2011-07-14) + make stbi_is_hdr work in STBI_NO_HDR (as specified), minor compiler-friendly improvements + 1.32 (2011-07-13) + support for "info" function for all supported filetypes (SpartanJ) + 1.31 (2011-06-20) + a few more leak fixes, bug in PNG handling (SpartanJ) + 1.30 (2011-06-11) + added ability to load files via callbacks to accomidate custom input streams (Ben Wenger) + removed deprecated format-specific test/load functions + removed support for installable file formats (stbi_loader) -- would have been broken for IO callbacks anyway + error cases in bmp and tga give messages and don't leak (Raymond Barbiero, grisha) + fix inefficiency in decoding 32-bit BMP (David Woo) + 1.29 (2010-08-16) + various warning fixes from Aurelien Pocheville + 1.28 (2010-08-01) + fix bug in GIF palette transparency (SpartanJ) + 1.27 (2010-08-01) + cast-to-stbi_uc to fix warnings + 1.26 (2010-07-24) + fix bug in file buffering for PNG reported by SpartanJ + 1.25 (2010-07-17) + refix trans_data warning (Won Chun) + 1.24 (2010-07-12) + perf improvements reading from files on platforms with lock-heavy fgetc() + minor perf improvements for jpeg + deprecated type-specific functions so we'll get feedback if they're needed + attempt to fix trans_data warning (Won Chun) + 1.23 fixed bug in iPhone support + 1.22 (2010-07-10) + removed image *writing* support + stbi_info support from Jetro Lauha + GIF support from Jean-Marc Lienher + iPhone PNG-extensions from James Brown + warning-fixes from Nicolas Schulz and Janez Zemva (i.stbi__err. Janez (U+017D)emva) + 1.21 fix use of 'stbi_uc' in header (reported by jon blow) + 1.20 added support for Softimage PIC, by Tom Seddon + 1.19 bug in interlaced PNG corruption check (found by ryg) + 1.18 (2008-08-02) + fix a threading bug (local mutable static) + 1.17 support interlaced PNG + 1.16 major bugfix - stbi__convert_format converted one too many pixels + 1.15 initialize some fields for thread safety + 1.14 fix threadsafe conversion bug + header-file-only version (#define STBI_HEADER_FILE_ONLY before including) + 1.13 threadsafe + 1.12 const qualifiers in the API + 1.11 Support installable IDCT, colorspace conversion routines + 1.10 Fixes for 64-bit (don't use "unsigned long") + optimized upsampling by Fabian "ryg" Giesen + 1.09 Fix format-conversion for PSD code (bad global variables!) + 1.08 Thatcher Ulrich's PSD code integrated by Nicolas Schulz + 1.07 attempt to fix C++ warning/errors again + 1.06 attempt to fix C++ warning/errors again + 1.05 fix TGA loading to return correct *comp and use good luminance calc + 1.04 default float alpha is 1, not 255; use 'void *' for stbi_image_free + 1.03 bugfixes to STBI_NO_STDIO, STBI_NO_HDR + 1.02 support for (subset of) HDR files, float interface for preferred access to them + 1.01 fix bug: possible bug in handling right-side up bmps... not sure + fix bug: the stbi__bmp_load() and stbi__tga_load() functions didn't work at all + 1.00 interface to zlib that skips zlib header + 0.99 correct handling of alpha in palette + 0.98 TGA loader by lonesock; dynamically add loaders (untested) + 0.97 jpeg errors on too large a file; also catch another malloc failure + 0.96 fix detection of invalid v value - particleman@mollyrocket forum + 0.95 during header scan, seek to markers in case of padding + 0.94 STBI_NO_STDIO to disable stdio usage; rename all #defines the same + 0.93 handle jpegtran output; verbose errors + 0.92 read 4,8,16,24,32-bit BMP files of several formats + 0.91 output 24-bit Windows 3.0 BMP files + 0.90 fix a few more warnings; bump version number to approach 1.0 + 0.61 bugfixes due to Marc LeBlanc, Christopher Lloyd + 0.60 fix compiling as c++ + 0.59 fix warnings: merge Dave Moore's -Wall fixes + 0.58 fix bug: zlib uncompressed mode len/nlen was wrong endian + 0.57 fix bug: jpg last huffman symbol before marker was >9 bits but less than 16 available + 0.56 fix bug: zlib uncompressed mode len vs. nlen + 0.55 fix bug: restart_interval not initialized to 0 + 0.54 allow NULL for 'int *comp' + 0.53 fix bug in png 3->4; speedup png decoding + 0.52 png handles req_comp=3,4 directly; minor cleanup; jpeg comments + 0.51 obey req_comp requests, 1-component jpegs return as 1-component, + on 'test' only check type, not whether we support this variant + 0.50 (2006-11-19) + first released version +*/ + + +/* +------------------------------------------------------------------------------ +This software is available under 2 licenses -- choose whichever you prefer. +------------------------------------------------------------------------------ +ALTERNATIVE A - MIT License +Copyright (c) 2017 Sean Barrett +Permission is hereby granted, free of charge, to any person obtaining a copy of +this software and associated documentation files (the "Software"), to deal in +the Software without restriction, including without limitation the rights to +use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies +of the Software, and to permit persons to whom the Software is furnished to do +so, subject to the following conditions: +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. +------------------------------------------------------------------------------ +ALTERNATIVE B - Public Domain (www.unlicense.org) +This is free and unencumbered software released into the public domain. +Anyone is free to copy, modify, publish, use, compile, sell, or distribute this +software, either in source code form or as a compiled binary, for any purpose, +commercial or non-commercial, and by any means. +In jurisdictions that recognize copyright laws, the author or authors of this +software dedicate any and all copyright interest in the software to the public +domain. We make this dedication for the benefit of the public at large and to +the detriment of our heirs and successors. We intend this dedication to be an +overt act of relinquishment in perpetuity of all present and future rights to +this software under copyright law. +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN +ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +------------------------------------------------------------------------------ +*/ diff --git a/src/libs/gstreamer/lv_gstreamer.c b/src/libs/gstreamer/lv_gstreamer.c new file mode 100644 index 0000000000..616b5ad1d8 --- /dev/null +++ b/src/libs/gstreamer/lv_gstreamer.c @@ -0,0 +1,628 @@ +/** + * @file lv_gstreamer.c + * + */ + +/********************* + * INCLUDES + *********************/ + +#include "lv_gstreamer_internal.h" + +#if LV_USE_GSTREAMER + +#include +#include +#include "../../core/lv_obj_class_private.h" + +/********************* + * DEFINES + *********************/ + +#define MY_CLASS (&lv_gstreamer_class) + + +/********************** + * TYPEDEFS + **********************/ + +/********************** + * STATIC PROTOTYPES + **********************/ + +static void lv_gstreamer_constructor(const lv_obj_class_t * class_p, lv_obj_t * obj); +static void lv_gstreamer_destructor(const lv_obj_class_t * class_p, lv_obj_t * obj); +static lv_result_t gstreamer_create_pipeline(lv_gstreamer_t * streamer, GstElement * pipeline, GstElement * head); +static void on_decode_pad_added(GstElement * element, GstPad * pad, gpointer user_data); +static GstFlowReturn on_new_sample(GstElement * sink, gpointer user_data); +static void gstreamer_timer_cb(lv_timer_t * timer); +static void gstreamer_poll_bus(lv_gstreamer_t * streamer); +static void gstreamer_update_frame(lv_gstreamer_t * streamer); + +/********************** + * STATIC VARIABLES + **********************/ + +const lv_obj_class_t lv_gstreamer_class = { + .constructor_cb = lv_gstreamer_constructor, + .destructor_cb = lv_gstreamer_destructor, + .width_def = LV_SIZE_CONTENT, + .height_def = LV_SIZE_CONTENT, + .instance_size = sizeof(lv_gstreamer_t), + .base_class = &lv_image_class, + .name = "lv_gstreamer", +}; + +/********************** + * MACROS + **********************/ + +#if LV_COLOR_DEPTH == 16 + #define GST_FORMAT "RGB16" + #define IMAGE_FORMAT LV_COLOR_FORMAT_RGB565 +#elif LV_COLOR_DEPTH == 24 + #define GST_FORMAT "BGR" + #define IMAGE_FORMAT LV_COLOR_FORMAT_RGB888 +#elif LV_COLOR_DEPTH == 32 + #define GST_FORMAT "BGRA" + #define IMAGE_FORMAT LV_COLOR_FORMAT_ARGB8888 +#else + #error Unsupported LV_COLOR_DEPTH +#endif + +/********************** + * GLOBAL FUNCTIONS + **********************/ + +lv_obj_t * lv_gstreamer_create(lv_obj_t * parent) +{ + if(!gst_is_initialized()) { + gst_init(0, NULL); + } + + LV_TRACE_OBJ_CREATE("begin"); + + lv_obj_t * obj = lv_obj_class_create_obj(MY_CLASS, parent); + lv_obj_class_init_obj(obj); + + LV_TRACE_OBJ_CREATE("end"); + return obj; +} + +lv_result_t lv_gstreamer_set_src(lv_obj_t * obj, const char * factory_name, const char * property, const char * source) +{ + LV_ASSERT_OBJ(obj, MY_CLASS); + LV_ASSERT_NULL(factory_name); + + if(!obj || !factory_name) { + LV_LOG_WARN("Refusing to set source with invalid params. Obj: %p Factory Name: %s", obj, factory_name); + return LV_RESULT_INVALID; + } + + lv_gstreamer_t * streamer = (lv_gstreamer_t *)obj; + + if(streamer->pipeline) { + LV_LOG_WARN("LVGL doesn't allow modifying the GStreamer source. Create a new widget with a new src instead"); + return LV_RESULT_INVALID; + } + GstElement * pipeline = gst_pipeline_new("lv_gstreamer_pipeline"); + if(!pipeline) { + LV_LOG_ERROR("Failed to create gstreamer pipeline"); + return LV_RESULT_INVALID; + } + + GstElement * head = gst_element_factory_make(factory_name, "lv_gstreamer_source"); + if(!head) { + gst_object_unref(pipeline); + LV_LOG_ERROR("Failed to create source from factory '%s'", factory_name); + return LV_RESULT_INVALID; + } + + if(!gst_bin_add(GST_BIN(pipeline), head)) { + gst_object_unref(head); + gst_object_unref(pipeline); + LV_LOG_ERROR("Failed to add source element to pipeline"); + return LV_RESULT_INVALID; + } + + if(property != NULL && source != NULL) { + g_object_set(G_OBJECT(head), property, source, NULL); + } + + /* The uri decode source element will automatically handle parsing and decoding for us + * for other source types, we need to add a parser and a decoder ourselves element*/ + if(!lv_streq(LV_GSTREAMER_FACTORY_URI_DECODE, factory_name)) { + GstElement * decodebin = gst_element_factory_make("decodebin", "lv_gstreamer_decodebin"); + if(!decodebin) { + gst_object_unref(pipeline); + LV_LOG_ERROR("Failed to create decodebin element"); + return LV_RESULT_INVALID; + } + if(!gst_bin_add(GST_BIN(pipeline), decodebin)) { + gst_object_unref(decodebin); + gst_object_unref(pipeline); + LV_LOG_ERROR("Failed to add decodebin element to pipeline"); + return LV_RESULT_INVALID; + } + + if(!gst_element_link(head, decodebin)) { + gst_object_unref(pipeline); + LV_LOG_ERROR("Failed to link source with parsebin elements"); + return LV_RESULT_INVALID; + } + head = decodebin; + } + + lv_result_t res = gstreamer_create_pipeline(streamer, pipeline, head); + if(res == LV_RESULT_INVALID) { + LV_LOG_ERROR("Pipeline creation failed"); + gst_object_unref(pipeline); + return res; + } + + streamer->pipeline = pipeline; + return LV_RESULT_OK; +} + +void lv_gstreamer_play(lv_obj_t * obj) +{ + LV_ASSERT_OBJ(obj, MY_CLASS); + if(!obj) { + return; + } + lv_gstreamer_t * streamer = (lv_gstreamer_t *)obj; + if(!streamer->pipeline) { + LV_LOG_WARN("Cannot play: GStreamer pipeline not initialized"); + return; + } + GstStateChangeReturn ret = gst_element_set_state(streamer->pipeline, GST_STATE_PLAYING); + if(ret == GST_STATE_CHANGE_FAILURE) { + LV_LOG_ERROR("Unable to play pipeline"); + } +} + +void lv_gstreamer_pause(lv_obj_t * obj) +{ + LV_ASSERT_OBJ(obj, MY_CLASS); + if(!obj) { + return; + } + lv_gstreamer_t * streamer = (lv_gstreamer_t *)obj; + if(!streamer->pipeline) { + LV_LOG_WARN("Cannot pause: GStreamer pipeline not initialized"); + return; + } + GstStateChangeReturn ret = gst_element_set_state(streamer->pipeline, GST_STATE_PAUSED); + + if(ret == GST_STATE_CHANGE_FAILURE) { + LV_LOG_ERROR("Unable to pause pipeline"); + } +} + +void lv_gstreamer_stop(lv_obj_t * obj) +{ + + LV_ASSERT_OBJ(obj, MY_CLASS); + if(!obj) { + return; + } + lv_gstreamer_t * streamer = (lv_gstreamer_t *)obj; + if(!streamer->pipeline) { + LV_LOG_WARN("Cannot stop: GStreamer pipeline not initialized"); + return; + } + GstStateChangeReturn ret = gst_element_set_state(streamer->pipeline, GST_STATE_READY); + if(ret == GST_STATE_CHANGE_FAILURE) { + LV_LOG_ERROR("Unable to stop pipeline"); + } +} +void lv_gstreamer_set_position(lv_obj_t * obj, uint32_t position) +{ + LV_ASSERT_OBJ(obj, MY_CLASS); + if(!obj) { + return; + } + lv_gstreamer_t * streamer = (lv_gstreamer_t *)obj; + if(!streamer->pipeline) { + LV_LOG_WARN("Cannot set position: GStreamer pipeline not initialized"); + return; + } + gint64 seek_position = (gint64)position * GST_MSECOND; + + if(!gst_element_seek_simple(streamer->pipeline, GST_FORMAT_TIME, + GST_SEEK_FLAG_FLUSH | GST_SEEK_FLAG_KEY_UNIT, + seek_position)) { + LV_LOG_WARN("Seek operation failed"); + } +} + +uint32_t lv_gstreamer_get_duration(lv_obj_t * obj) +{ + LV_ASSERT_OBJ(obj, MY_CLASS); + lv_gstreamer_t * streamer = (lv_gstreamer_t *)obj; + + if(!streamer->pipeline) { + return 0; + } + + gint64 duration; + if(gst_element_query_duration(streamer->pipeline, GST_FORMAT_TIME, &duration)) { + return (uint32_t)(duration / GST_MSECOND); + } + + return 0; +} + +uint32_t lv_gstreamer_get_position(lv_obj_t * obj) +{ + LV_ASSERT_OBJ(obj, MY_CLASS); + lv_gstreamer_t * streamer = (lv_gstreamer_t *)obj; + + if(!streamer->pipeline) { + return 0; + } + + gint64 position; + if(gst_element_query_position(streamer->pipeline, GST_FORMAT_TIME, &position)) { + return (uint32_t)(position / GST_MSECOND); + } + + return 0; +} + +lv_gstreamer_state_t lv_gstreamer_get_state(lv_obj_t * obj) +{ + LV_ASSERT_OBJ(obj, MY_CLASS); + lv_gstreamer_t * streamer = (lv_gstreamer_t *)obj; + + if(!streamer->pipeline) { + return LV_GSTREAMER_STATE_NULL; + } + + GstState state, pending; + GstStateChangeReturn ret = gst_element_get_state(streamer->pipeline, &state, &pending, 0); + + if(ret == GST_STATE_CHANGE_FAILURE) { + return LV_GSTREAMER_STATE_NULL; + } + + switch(state) { + case GST_STATE_NULL: + return LV_GSTREAMER_STATE_NULL; + case GST_STATE_READY: + return LV_GSTREAMER_STATE_READY; + case GST_STATE_PAUSED: + return LV_GSTREAMER_STATE_PAUSED; + case GST_STATE_PLAYING: + return LV_GSTREAMER_STATE_PLAYING; + default: + return LV_GSTREAMER_STATE_NULL; + } +} + +void lv_gstreamer_set_volume(lv_obj_t * obj, uint8_t volume) +{ + + LV_ASSERT_OBJ(obj, MY_CLASS); + lv_gstreamer_t * streamer = (lv_gstreamer_t *)obj; + + if(!streamer->pipeline) { + return; + } + + g_object_set(streamer->audio_volume, "volume", volume / 100.f, NULL); +} + +uint8_t lv_gstreamer_get_volume(lv_obj_t * obj) +{ + LV_ASSERT_OBJ(obj, MY_CLASS); + lv_gstreamer_t * streamer = (lv_gstreamer_t *)obj; + + if(!streamer->pipeline) { + return 0; + } + + gdouble volume; + g_object_get(streamer->audio_volume, "volume", &volume, NULL); + + return (uint8_t)(volume * 100.f); +} + +/** + * Set the speed rate of this gstreamer + * @param gstreamer pointer to a gstreamer object + * @param rate the rate factor. Example values: + * - 256: 1x + * - <256: slow down + * - >256: speed up + * - 128: 0.5x + * - 512: 2x + */ +void lv_gstreamer_set_rate(lv_obj_t * obj, uint32_t rate) +{ + + LV_ASSERT_OBJ(obj, MY_CLASS); + lv_gstreamer_t * streamer = (lv_gstreamer_t *)obj; + + gdouble gst_rate = (gdouble)rate / 256.0; + + gint64 current_pos; + + if(!gst_element_query_position(streamer->pipeline, GST_FORMAT_TIME, ¤t_pos)) { + LV_LOG_WARN("Failed to query current position which is required to set the stream rate"); + return; + } + + /* Perform the seek with new rate from the current position */ + if(!gst_element_seek(streamer->pipeline, gst_rate, + GST_FORMAT_TIME, + GST_SEEK_FLAG_FLUSH | GST_SEEK_FLAG_ACCURATE, + GST_SEEK_TYPE_SET, current_pos, + GST_SEEK_TYPE_NONE, GST_CLOCK_TIME_NONE)) { + LV_LOG_WARN("Failed to change stream rate"); + } +} + +/********************** + * STATIC FUNCTIONS + **********************/ + +static void lv_gstreamer_constructor(const lv_obj_class_t * class_p, lv_obj_t * obj) +{ + LV_UNUSED(class_p); + LV_TRACE_OBJ_CREATE("begin"); + lv_gstreamer_t * streamer = (lv_gstreamer_t *)obj; + lv_memzero(&streamer->frame, sizeof(streamer->frame)); + + streamer->gstreamer_timer = lv_timer_create(gstreamer_timer_cb, LV_DEF_REFR_PERIOD / 5, streamer); + LV_ASSERT_NULL(streamer->gstreamer_timer); + + streamer->frame_queue = g_async_queue_new(); + LV_ASSERT_NULL(streamer->frame_queue); + streamer->last_sample = NULL; + + LV_TRACE_OBJ_CREATE("finished"); +} + +static void gstreamer_poll_bus(lv_gstreamer_t * streamer) +{ + GstBus * bus = gst_element_get_bus(streamer->pipeline); + GstMessage * msg; + + while((msg = gst_bus_pop(bus)) != NULL) { + const GstMessageType message_type = GST_MESSAGE_TYPE(msg); + switch(message_type) { + case GST_MESSAGE_ERROR: { + GError * err; + gchar * debug; + gst_message_parse_error(msg, &err, &debug); + LV_LOG_ERROR("GStreamer error: %s", err->message); + g_error_free(err); + g_free(debug); + break; + } + case GST_MESSAGE_EOS: + LV_LOG_INFO("End of stream"); + break; + case GST_MESSAGE_STATE_CHANGED: { + GstState old_state, new_state; + gst_message_parse_state_changed(msg, &old_state, &new_state, NULL); + LV_LOG_TRACE("State changed: %s -> %s", gst_element_state_get_name(old_state), + gst_element_state_get_name(new_state)); + break; + } + default: + LV_LOG_TRACE("Received message %d", message_type); + break; + } + gst_message_unref(msg); + } + gst_object_unref(bus); +} + +static void gstreamer_update_frame(lv_gstreamer_t * streamer) +{ + GstSample * sample = g_async_queue_try_pop(streamer->frame_queue); + + if(!sample) { + return; + } + + const bool first_frame = !streamer->is_video_info_valid; + if(first_frame) { + GstCaps * caps = gst_sample_get_caps(sample); + if(!caps || !gst_video_info_from_caps(&streamer->video_info, caps)) { + LV_LOG_ERROR("Failed to get video info from caps"); + gst_sample_unref(sample); + return; + } + streamer->is_video_info_valid = true; + } + + + GstBuffer * buffer = gst_sample_get_buffer(sample); + GstMapInfo map; + if(buffer && gst_buffer_map(buffer, &map, GST_MAP_READ)) { + streamer->frame = (lv_image_dsc_t) { + .data = map.data, + .data_size = map.size, + .header = { + .magic = LV_IMAGE_HEADER_MAGIC, + .cf = IMAGE_FORMAT, + .h = GST_VIDEO_INFO_HEIGHT(&streamer->video_info), + .w = GST_VIDEO_INFO_WIDTH(&streamer->video_info), + .stride = GST_VIDEO_INFO_PLANE_STRIDE(&streamer->video_info, 0), + } + }; + lv_image_set_src((lv_obj_t *)streamer, &streamer->frame); + } + /* We send the event AFTER setting the image source so that users can query the + * resolution on this specific event callback */ + if(first_frame) { + lv_obj_send_event((lv_obj_t *)streamer, LV_EVENT_READY, streamer); + } + + if(streamer->last_sample) { + gst_sample_unref(streamer->last_sample); + } + streamer->last_sample = sample; +} +static void gstreamer_timer_cb(lv_timer_t * timer) +{ + lv_gstreamer_t * streamer = lv_timer_get_user_data(timer); + + if(!streamer->pipeline) { + return; + } + + gstreamer_poll_bus(streamer); + gstreamer_update_frame(streamer); +} + +static void lv_gstreamer_destructor(const lv_obj_class_t * class_p, lv_obj_t * obj) +{ + LV_UNUSED(class_p); + lv_gstreamer_t * streamer = (lv_gstreamer_t *)obj; + + if(streamer->pipeline) { + gst_element_set_state(streamer->pipeline, GST_STATE_NULL); + gst_object_unref(streamer->pipeline); + } + if(streamer->last_sample) { + gst_sample_unref(streamer->last_sample); + } + + g_async_queue_unref(streamer->frame_queue); +} + +static lv_result_t gstreamer_create_pipeline(lv_gstreamer_t * streamer, GstElement * pipeline, + GstElement * decode_element) +{ + + /* The caller has already added head and whatever comes before it to the pipeline. + * So inside this function, we only need to handle adding the elements that are created here */ + GstElement * video_app_sink; + GstElement * video_rate; + GstElement * video_queue; + GstElement * audio_resample; + GstElement * audio_sink; + struct { + const char * factory; + const char * name; + GstElement ** store; + } const elements[] = { + {"videoconvert", "lv_gstreamer_video_convert", &streamer->video_convert}, + {"audioconvert", "lv_gstreamer_audio_convert", &streamer->audio_convert}, + {"volume", "lv_gstreamer_audio_volume", &streamer->audio_volume}, + {"videorate", "lv_gstreamer_video_rate", &video_rate}, + {"queue", "lv_gstreamer_video_queue", &video_queue}, + {"appsink", "lv_gstreamer_video_sink", &video_app_sink}, + {"audioresample", "lv_gstreamer_audio_resample", &audio_resample}, + {"autoaudiosink", "lv_gstreamer_audio_sink", &audio_sink}, + }; + const size_t element_count = sizeof(elements) / sizeof(elements[0]); + for(size_t i = 0; i < element_count; ++i) { + GstElement * el = gst_element_factory_make(elements[i].factory, elements[i].name); + if(!el) { + /* The previous elements were added to the pipeline so we don't need to unref them explicitly + * Unrefing the pipeline is enough and is done by caller*/ + LV_LOG_ERROR("Failed to create %s element", elements[i].name); + return LV_RESULT_INVALID; + } + *(elements[i].store) = el; + if(!gst_bin_add(GST_BIN(pipeline), el)) { + gst_object_unref(el); + LV_LOG_ERROR("Failed to add %s element to pipeline", elements[i].name); + return LV_RESULT_INVALID; + } + } + + /* Here we set the fps we want the pipeline to produce and the color format + * This is achieved by the video_convert and video_rate elements that will automaticall throttle and + * convert the image to the format we desire*/ + uint32_t target_fps = 1000 / LV_DEF_REFR_PERIOD; + char caps[128]; + lv_snprintf(caps, sizeof(caps), "video/x-raw,format=%s,framerate=%" LV_PRIu32 "/1", GST_FORMAT, target_fps); + + GstCaps * appsink_caps = gst_caps_from_string(caps); + g_object_set(G_OBJECT(video_app_sink), "emit-signals", TRUE, "sync", TRUE, "max-buffers", 1, "drop", TRUE, "caps", + appsink_caps, NULL); + gst_caps_unref(appsink_caps); + + if(!gst_element_link_many(streamer->video_convert, video_rate, video_queue, video_app_sink, NULL)) { + LV_LOG_ERROR("Failed to link video convert to sink"); + return LV_RESULT_INVALID; + } + + if(!gst_element_link_many(streamer->audio_convert, audio_resample, streamer->audio_volume, audio_sink, NULL)) { + LV_LOG_ERROR("Failed to link audio convert to sink"); + return LV_RESULT_INVALID; + } + + g_signal_connect(video_app_sink, "new-sample", G_CALLBACK(on_new_sample), streamer); + + /* At this point we don't yet know the input format + * Once the source starts receiving the data, it will create the necessary pads, + * i.e one pad for audio and one for video + * We add a callback so that we automatically connect to the data once it's figured out*/ + g_signal_connect(decode_element, "pad-added", G_CALLBACK(on_decode_pad_added), streamer); + return LV_RESULT_OK; +} + +static void on_decode_pad_added(GstElement * element, GstPad * pad, gpointer user_data) +{ + LV_UNUSED(element); + lv_gstreamer_t * streamer = (lv_gstreamer_t *)user_data; + GstCaps * caps = gst_pad_get_current_caps(pad); + + GstStructure * structure = gst_caps_get_structure(caps, 0); + const gchar * name = gst_structure_get_name(structure); + + LV_LOG_TRACE("Pad discovered %s", name); + + if(g_str_has_prefix(name, "video/")) { + GstPad * video_convert_sink_pad = gst_element_get_static_pad(streamer->video_convert, "sink"); + if(!gst_pad_is_linked(video_convert_sink_pad)) { + if(gst_pad_link(pad, video_convert_sink_pad) != GST_PAD_LINK_OK) { + LV_LOG_ERROR("Failed to link discovered pad '%s' to videoconvert", name); + } + } + else { + LV_LOG_WARN("Received another video pad '%s' but our video pipeline is already linked - Ignoring", name); + } + gst_object_unref(video_convert_sink_pad); + } + else if(g_str_has_prefix(name, "audio/")) { + GstPad * audio_convert_sink_pad = gst_element_get_static_pad(streamer->audio_convert, "sink"); + if(!gst_pad_is_linked(audio_convert_sink_pad)) { + if(gst_pad_link(pad, audio_convert_sink_pad) != GST_PAD_LINK_OK) { + LV_LOG_ERROR("Failed to link discovered pad '%s' to audioconvert", name); + } + } + else { + LV_LOG_WARN("Received another audio pad '%s' but our audio pipeline is already linked - Ignoring", name); + } + gst_object_unref(audio_convert_sink_pad); + } + + gst_caps_unref(caps); +} + +static GstFlowReturn on_new_sample(GstElement * sink, gpointer user_data) +{ + /* This function is called from a thread other than the main one so we can't call anything related to LVGL here + * Instead, we acquire the new sample (the new frame) and push it to the queue so that we can retrieve it from an LVGL timer + * Note that the pipeline spits out a new frame every LV_DEF_REFR_PERIOD as per the way it's set up so we shouldn't ever lose any + * frames with this method*/ + lv_gstreamer_t * streamer = (lv_gstreamer_t *)user_data; + GstSample * sample; + + g_signal_emit_by_name(sink, "pull-sample", &sample); + if(!sample) { + return GST_FLOW_OK; + } + + g_async_queue_push(streamer->frame_queue, sample); + return GST_FLOW_OK; +} +#endif diff --git a/src/libs/gstreamer/lv_gstreamer.h b/src/libs/gstreamer/lv_gstreamer.h new file mode 100644 index 0000000000..3f85daab52 --- /dev/null +++ b/src/libs/gstreamer/lv_gstreamer.h @@ -0,0 +1,188 @@ +/** + * @file lv_gstreamer.h + * + */ + +#ifndef LV_GSTREAMER_H +#define LV_GSTREAMER_H + +#ifdef __cplusplus +extern "C" { +#endif + +/********************* + * INCLUDES + *********************/ +#include "../../lv_conf_internal.h" + +#if LV_USE_GSTREAMER +#include "../../core/lv_obj.h" + + +/********************* + * DEFINES + *********************/ + +LV_ATTRIBUTE_EXTERN_DATA extern const lv_obj_class_t lv_gstreamer_class; + +/* Using the `URI` "factory", we can specify various URI schemes as media sources including + * - local files (file://) + * - web streams (http://, https://) + * - RTSP streams (rtsp://) + * - UDP streams (udp://) + * and many others. + * GStreamer's uridecodebin automatically selects the appropriate + * source element and decoder based on the URI scheme and media format. */ +#define LV_GSTREAMER_FACTORY_URI_DECODE "uridecodebin" +#define LV_GSTREAMER_PROPERTY_URI_DECODE "uri" + +#define LV_GSTREAMER_FACTORY_FILE "filesrc" +#define LV_GSTREAMER_PROPERTY_FILE "location" + +/** These sources are untested. For most of them, URI_DECODE can probably be used instead */ +#ifdef LV_GSTREAMER_ENABLE_UNTESTED_SOURCES +#define LV_GSTREAMER_FACTORY_HTTP "souphttpsrc" +#define LV_GSTREAMER_PROPERTY_HTTP "location" + +#define LV_GSTREAMER_FACTORY_HTTPS "souphttpsrc" +#define LV_GSTREAMER_PROPERTY_HTTPS "location" + +#define LV_GSTREAMER_FACTORY_V4L2_CAMERA "v4l2src" +#define LV_GSTREAMER_PROPERTY_V4L2_CAMERA "device" + +#define LV_GSTREAMER_FACTORY_ALSA_AUDIO "alsasrc" +#define LV_GSTREAMER_PROPERTY_ALSA_AUDIO "device" + +#define LV_GSTREAMER_FACTORY_PULSE_AUDIO "pulsesrc" +#define LV_GSTREAMER_PROPERTY_PULSE_AUDIO "device" + +#define LV_GSTREAMER_FACTORY_TEST_AUDIO "audiotestsrc" +#define LV_GSTREAMER_PROPERTY_TEST_AUDIO NULL + +#define LV_GSTREAMER_FACTORY_TEST_VIDEO "videotestsrc" +#define LV_GSTREAMER_PROPERTY_TEST_VIDEO NULL + +#define LV_GSTREAMER_FACTORY_APP "appsrc" +#define LV_GSTREAMER_PROPERTY_APP NULL +#endif + +/********************** + * TYPEDEFS + **********************/ + +typedef enum { + LV_GSTREAMER_STATE_NULL, + LV_GSTREAMER_STATE_READY, + LV_GSTREAMER_STATE_PAUSED, + LV_GSTREAMER_STATE_PLAYING +} lv_gstreamer_state_t; + +/********************** + * GLOBAL PROTOTYPES + **********************/ + +/** + * Create a gstreamer object + * @param parent pointer to an object, it will be the parent of the new gstreamer + * @return pointer to the created gstreamer + */ +lv_obj_t * lv_gstreamer_create(lv_obj_t * parent); + +/** + * Add a source to this gstreamer object + * @param gstreamer pointer to a gstreamer object + * @param factory_name the factory name for the source of this gstreamer object. + * for common factory names, check `LV_GSTREAMER_FACTORY_XXX` defines + * @param property the property name for the gstreamer source object + * for common properties, see `LV_GSTREAMER_PROPERTY_XXX` defines + * Passing NULL will create the source object but not set its source + * @param source the property value for the gstreamer source object + * Passing NULL will create the source object but not set its source + * @return LV_RESULT_OK if the source was correctly set else LV_RESULT_INVALID + */ +lv_result_t lv_gstreamer_set_src(lv_obj_t * gstreamer, const char * factory_name, const char * property, + const char * source); + +/** + * Play this gstreamer + * @param gstreamer pointer to a gstreamer object + */ +void lv_gstreamer_play(lv_obj_t * gstreamer); + +/** + * Pause this gstreamer + * @param gstreamer pointer to a gstreamer object + */ +void lv_gstreamer_pause(lv_obj_t * gstreamer); + +/** + * Stop this gstreamer + * @param gstreamer pointer to a gstreamer object + */ +void lv_gstreamer_stop(lv_obj_t * gstreamer); + +/** + * Seek a position in this gstreamer + * @param gstreamer pointer to a gstreamer object + * @param position position to seek to + */ +void lv_gstreamer_set_position(lv_obj_t * gstreamer, uint32_t position); + +/** + * Get the duration of this gstreamer + * @param gstreamer pointer to a gstreamer object + * @return the duration (in ms) of the gstreamer object + */ +uint32_t lv_gstreamer_get_duration(lv_obj_t * gstreamer); + +/** + * Get the position of this gstreamer + * @param gstreamer pointer to a gstreamer object + * @return the position (in ms) of the gstreamer object + */ +uint32_t lv_gstreamer_get_position(lv_obj_t * gstreamer); + +/** + * Get the state of this gstreamer + * @param gstreamer pointer to a gstreamer object + */ +lv_gstreamer_state_t lv_gstreamer_get_state(lv_obj_t * gstreamer); + +/** + * Set the volume of this gstreamer + * @param gstreamer pointer to a gstreamer object + * @param volume the value to set in the range [0..100]. Higher values are clamped + */ +void lv_gstreamer_set_volume(lv_obj_t * gstreamer, uint8_t volume); + +/** + * Get the volume of this gstreamer + * @param gstreamer pointer to a gstreamer object + * @return the volume for this gstreamer + */ +uint8_t lv_gstreamer_get_volume(lv_obj_t * gstreamer); + +/** + * Set the speed rate of this gstreamer + * @param gstreamer pointer to a gstreamer object + * @param rate the rate factor. Example values: + * - 256: 1x + * - <256: slow down + * - >256: speed up + * - 128: 0.5x + * - 512: 2x + */ +void lv_gstreamer_set_rate(lv_obj_t * gstreamer, uint32_t rate); + + +/********************** + * MACROS + **********************/ + +#endif /*LV_USE_GSTREAMER*/ + +#ifdef __cplusplus +} /*extern "C"*/ +#endif + +#endif /*LV_GSTREAMER_H*/ diff --git a/src/libs/gstreamer/lv_gstreamer_internal.h b/src/libs/gstreamer/lv_gstreamer_internal.h new file mode 100644 index 0000000000..7f35e8fd63 --- /dev/null +++ b/src/libs/gstreamer/lv_gstreamer_internal.h @@ -0,0 +1,74 @@ +/** + * @file lv_gstreamer_internal.h + * + */ + +#ifndef LV_GSTREAMER_INTERNAL_H +#define LV_GSTREAMER_INTERNAL_H + +#ifdef __cplusplus +extern "C" { +#endif + +/********************* + * INCLUDES + *********************/ + +#include "../../lv_conf_internal.h" + +#if LV_USE_GSTREAMER + +#include +#include + +#include "../../widgets/image/lv_image_private.h" + +#include "lv_gstreamer.h" + +/********************* + * DEFINES + *********************/ + +/********************** + * TYPEDEFS + **********************/ + +struct _lv_gstreamer_t { + lv_image_t image; + lv_image_dsc_t frame; + GstVideoInfo video_info; + GstElement * pipeline; + GstElement * audio_convert; + GstElement * video_convert; + GstElement * audio_volume; + GstSample * last_sample; + lv_timer_t * gstreamer_timer; + GAsyncQueue * frame_queue; + bool is_video_info_valid; +}; + +typedef struct { + uint8_t * frame_data; + uint32_t width; + uint32_t height; + uint32_t stride; + size_t data_size; +} frame_data_t; + +typedef struct _lv_gstreamer_t lv_gstreamer_t; + +/********************** + * GLOBAL PROTOTYPES + **********************/ + +/********************** + * MACROS + **********************/ + +#endif /* LV_USE_GSTREAMER != 0 */ + +#ifdef __cplusplus +} /*extern "C"*/ +#endif + +#endif /*LV_GSTREAMER_INTERNAL_H*/ diff --git a/src/libs/libjpeg_turbo/lv_libjpeg_turbo.c b/src/libs/libjpeg_turbo/lv_libjpeg_turbo.c index f058728e04..e99c81e4f4 100644 --- a/src/libs/libjpeg_turbo/lv_libjpeg_turbo.c +++ b/src/libs/libjpeg_turbo/lv_libjpeg_turbo.c @@ -48,7 +48,8 @@ static uint8_t * read_file(const char * filename, uint32_t * size); static bool get_jpeg_head_info(const char * filename, uint32_t * width, uint32_t * height, uint32_t * orientation); static bool get_jpeg_size(uint8_t * data, uint32_t data_size, uint32_t * width, uint32_t * height); static bool get_jpeg_direction(uint8_t * data, uint32_t data_size, uint32_t * orientation); -static void rotate_buffer(lv_draw_buf_t * decoded, uint8_t * buffer, uint32_t line_index, uint32_t angle); +static void rotate_buffer(lv_draw_buf_t * decoded, uint8_t * buffer, uint32_t line_index, uint32_t angle, + uint32_t row_stride); static void error_exit(j_common_ptr cinfo); /********************** * STATIC VARIABLES @@ -277,7 +278,7 @@ static lv_draw_buf_t * decode_jpeg_file(const char * filename) /* More stuff */ JSAMPARRAY buffer; /* Output row buffer */ - int row_stride; /* physical row width in output buffer */ + uint32_t row_stride; /* physical row width in output buffer */ uint32_t image_angle = 0; /* image rotate angle */ lv_draw_buf_t * decoded = NULL; @@ -386,7 +387,7 @@ static lv_draw_buf_t * decode_jpeg_file(const char * filename) jpeg_read_scanlines(&cinfo, buffer, 1); /* Assume put_scanline_someplace wants a pointer and sample count. */ - rotate_buffer(decoded, buffer[0], line_index, image_angle); + rotate_buffer(decoded, buffer[0], line_index, image_angle, row_stride); line_index++; } @@ -563,7 +564,8 @@ static bool get_jpeg_direction(uint8_t * data, uint32_t data_size, uint32_t * or return JPEG_HEADER_OK; } -static void rotate_buffer(lv_draw_buf_t * decoded, uint8_t * buffer, uint32_t line_index, uint32_t angle) +static void rotate_buffer(lv_draw_buf_t * decoded, uint8_t * buffer, uint32_t line_index, uint32_t angle, + uint32_t row_stride) { if(angle == 90) { for(uint32_t x = 0; x < decoded->header.h; x++) { @@ -584,7 +586,7 @@ static void rotate_buffer(lv_draw_buf_t * decoded, uint8_t * buffer, uint32_t li } } else { - lv_memcpy(decoded->data + line_index * decoded->header.stride, buffer, decoded->header.stride); + lv_memcpy(decoded->data + line_index * decoded->header.stride, buffer, row_stride); } } diff --git a/src/libs/libpng/lv_libpng.c b/src/libs/libpng/lv_libpng.c index 15578f7abf..5a394b0808 100644 --- a/src/libs/libpng/lv_libpng.c +++ b/src/libs/libpng/lv_libpng.c @@ -151,14 +151,14 @@ static lv_result_t decoder_open(lv_image_decoder_t * decoder, lv_image_decoder_d lv_draw_buf_t * adjusted = lv_image_decoder_post_process(dsc, decoded); if(adjusted == NULL) { - lv_draw_buf_destroy_user(image_cache_draw_buf_handlers, decoded); + lv_draw_buf_destroy(decoded); LV_PROFILER_DECODER_END_TAG("lv_libpng_decoder_open"); return LV_RESULT_INVALID; } /*The adjusted draw buffer is newly allocated.*/ if(adjusted != decoded) { - lv_draw_buf_destroy_user(image_cache_draw_buf_handlers, decoded); + lv_draw_buf_destroy(decoded); decoded = adjusted; } @@ -184,7 +184,7 @@ static lv_result_t decoder_open(lv_image_decoder_t * decoder, lv_image_decoder_d lv_cache_entry_t * entry = lv_image_decoder_add_to_cache(decoder, &search_key, decoded, NULL); if(entry == NULL) { - lv_draw_buf_destroy_user(image_cache_draw_buf_handlers, decoded); + lv_draw_buf_destroy(decoded); LV_PROFILER_DECODER_END_TAG("lv_libpng_decoder_open"); return LV_RESULT_INVALID; } @@ -202,7 +202,7 @@ static void decoder_close(lv_image_decoder_t * decoder, lv_image_decoder_dsc_t * LV_UNUSED(decoder); /*Unused*/ if(dsc->args.no_cache || - !lv_image_cache_is_enabled()) lv_draw_buf_destroy_user(image_cache_draw_buf_handlers, (lv_draw_buf_t *)dsc->decoded); + !lv_image_cache_is_enabled()) lv_draw_buf_destroy((lv_draw_buf_t *)dsc->decoded); } static uint8_t * alloc_file(const char * filename, uint32_t * size) @@ -331,7 +331,7 @@ static lv_draw_buf_t * decode_png(lv_image_decoder_dsc_t * dsc) lv_free(png_data); if(!ret) { LV_LOG_ERROR("png decode failed: %s", image.message); - lv_draw_buf_destroy_user(image_cache_draw_buf_handlers, decoded); + lv_draw_buf_destroy(decoded); return NULL; } diff --git a/src/libs/lodepng/lodepng.c b/src/libs/lodepng/lodepng.c index a3f0b59a19..7e37636a20 100644 --- a/src/libs/lodepng/lodepng.c +++ b/src/libs/lodepng/lodepng.c @@ -3029,8 +3029,13 @@ static unsigned lodepng_chunk_createv(ucvector * out, unsigned char * chunk; CERROR_TRY_RETURN(lodepng_chunk_init(&chunk, out, length, type)); - /*3: the data*/ - lodepng_memcpy(chunk + 8, data, length); + /* 3: the data + * LVGL: In the upstream lodepng code, lodepng_memcpy doesn't use memcpy and instead uses a simple `for` loop to copy the data into its destination + * `lv_memcpy`, on the other hand, may call `memcpy` under the hood and `src` can't be NULL + * The function `addChunk_IEND` is an example of a function that calls this function with data == NULL*/ + if(data) { + lodepng_memcpy(chunk + 8, data, length); + } /*4: CRC (of the chunkname characters and the data)*/ lodepng_chunk_generate_crc(chunk); @@ -5831,7 +5836,7 @@ unsigned lodepng_decode(unsigned char ** out, unsigned * w, unsigned * h, return 56; /*unsupported color mode conversion*/ } - lv_draw_buf_t * new_buf = lv_draw_buf_create_user(image_cache_draw_buf_handlers,*w, *h, LV_COLOR_FORMAT_ARGB8888, 4 * *w); + lv_draw_buf_t * new_buf = lv_draw_buf_create_ex(image_cache_draw_buf_handlers,*w, *h, LV_COLOR_FORMAT_ARGB8888, 4 * *w); if(new_buf == NULL) { state->error = 83; /*alloc fail*/ } diff --git a/src/libs/qrcode/lv_qrcode.c b/src/libs/qrcode/lv_qrcode.c index 8b948f3aee..d0c5c667c1 100644 --- a/src/libs/qrcode/lv_qrcode.c +++ b/src/libs/qrcode/lv_qrcode.c @@ -11,6 +11,7 @@ #if LV_USE_QRCODE +#include "../../misc/cache/lv_cache.h" #include "qrcodegen.h" /********************* @@ -27,6 +28,7 @@ **********************/ static void lv_qrcode_constructor(const lv_obj_class_t * class_p, lv_obj_t * obj); static void lv_qrcode_destructor(const lv_obj_class_t * class_p, lv_obj_t * obj); +static int32_t get_satisfied_size(int32_t min_version, int32_t size, int32_t * scale); /********************** * STATIC VARIABLES @@ -111,20 +113,13 @@ lv_result_t lv_qrcode_update(lv_obj_t * obj, const void * data, uint32_t data_le if(data_len > qrcodegen_BUFFER_LEN_MAX) return LV_RESULT_INVALID; int32_t qr_version = qrcodegen_getMinFitVersion(qrcodegen_Ecc_MEDIUM, data_len); - if(qr_version <= 0) return LV_RESULT_INVALID; - int32_t qr_size = qrcodegen_version2size(qr_version); - if(qr_size <= 0) return LV_RESULT_INVALID; - int32_t scale = draw_buf->header.w / qr_size; - if(scale <= 0) return LV_RESULT_INVALID; - - /* Pick the largest QR code that still maintains scale. */ - for(int32_t i = qr_version + 1; i < qrcodegen_VERSION_MAX; i++) { - if(qrcodegen_version2size(i) * scale > draw_buf->header.w) - break; + int32_t quiet_zone_scale = 0; + if(qrcode->quiet_zone) qr_version = get_satisfied_size(qr_version, draw_buf->header.w, &quiet_zone_scale); + if(qr_version <= 0 || (qrcode->quiet_zone && quiet_zone_scale <= 0)) return LV_RESULT_INVALID; - qr_version = i; - } - qr_size = qrcodegen_version2size(qr_version); + const int32_t qr_size = qrcodegen_version2size(qr_version); + if(qr_size <= 0) return LV_RESULT_INVALID; + const int32_t scale = qrcode->quiet_zone ? quiet_zone_scale : draw_buf->header.w / qr_size; uint8_t * qr0 = lv_malloc(qrcodegen_BUFFER_LEN_FOR_VERSION(qr_version)); LV_ASSERT_MALLOC(qr0); @@ -147,11 +142,9 @@ lv_result_t lv_qrcode_update(lv_obj_t * obj, const void * data, uint32_t data_le lv_display_enable_invalidation(lv_obj_get_display(obj), false); int32_t obj_w = draw_buf->header.w; - qr_size = qrcodegen_getSize(qr0); - scale = obj_w / qr_size; int scaled = qr_size * scale; int margin = (obj_w - scaled) / 2; - uint8_t * buf_u8 = (uint8_t *)draw_buf->data + 8; /*+8 skip the palette*/ + uint8_t * buf_u8 = draw_buf->data + 8; /*+8 skip the palette*/ lv_color_t c = lv_color_hex(1); /* Copy the qr code canvas: @@ -211,6 +204,18 @@ lv_result_t lv_qrcode_update(lv_obj_t * obj, const void * data, uint32_t data_le return LV_RESULT_OK; } +void lv_qrcode_set_data(lv_obj_t * obj, const char * data) +{ + if(data == NULL) return; + lv_qrcode_update(obj, data, lv_strlen(data)); +} + +void lv_qrcode_set_quiet_zone(lv_obj_t * obj, bool enable) +{ + lv_qrcode_t * qrcode = (lv_qrcode_t *)obj; + qrcode->quiet_zone = enable; +} + /********************** * STATIC FUNCTIONS **********************/ @@ -239,4 +244,26 @@ static void lv_qrcode_destructor(const lv_obj_class_t * class_p, lv_obj_t * obj) lv_draw_buf_destroy(draw_buf); } +static int32_t get_satisfied_size(int32_t min_version, int32_t size, int32_t * scale) +{ + if(min_version <= 0) return -1; + + int32_t offset = size; + int32_t satisfied_version = min_version; + if(scale) *scale = 0; + + for(int32_t version = min_version; version <= min_version + 2 && version <= qrcodegen_VERSION_MAX - 3; version++) { + int32_t version_size = qrcodegen_version2size(version + 1); + int32_t tmp_offset = size % version_size; + int32_t tmp_scale = size / version_size; + + if(tmp_offset < offset) { + offset = tmp_offset; + satisfied_version = version; + if(scale) *scale = tmp_scale; + } + } + return satisfied_version; +} + #endif /*LV_USE_QRCODE*/ diff --git a/src/libs/qrcode/lv_qrcode.h b/src/libs/qrcode/lv_qrcode.h index ba9b0e869e..005682415d 100644 --- a/src/libs/qrcode/lv_qrcode.h +++ b/src/libs/qrcode/lv_qrcode.h @@ -72,6 +72,21 @@ void lv_qrcode_set_light_color(lv_obj_t * obj, lv_color_t color); */ lv_result_t lv_qrcode_update(lv_obj_t * obj, const void * data, uint32_t data_len); +/** + * Helper function to set the data of a QR code object + * @param obj pointer to a QR code object + * @param data data to display as a string + */ +void lv_qrcode_set_data(lv_obj_t * obj, const char * data); + +/** + * Enable or disable quiet zone. + * Quiet zone is the area around the QR code where no data is encoded. + * @param obj pointer to a QR code object + * @param enable true: enable quiet zone; false: disable quiet zone + */ +void lv_qrcode_set_quiet_zone(lv_obj_t * obj, bool enable); + /********************** * MACROS **********************/ diff --git a/src/libs/qrcode/lv_qrcode_private.h b/src/libs/qrcode/lv_qrcode_private.h index bcd2c8c5d4..86acae290c 100644 --- a/src/libs/qrcode/lv_qrcode_private.h +++ b/src/libs/qrcode/lv_qrcode_private.h @@ -32,6 +32,7 @@ struct _lv_qrcode_t { lv_canvas_t canvas; lv_color_t dark_color; lv_color_t light_color; + int32_t quiet_zone; }; diff --git a/src/libs/svg/lv_svg.h b/src/libs/svg/lv_svg.h index b5a8965cb5..3ed25c3435 100644 --- a/src/libs/svg/lv_svg.h +++ b/src/libs/svg/lv_svg.h @@ -21,7 +21,7 @@ /********************** * TYPEDEFS **********************/ -enum { +enum _lv_svg_tag_t { LV_SVG_TAG_INVALID = -1, LV_SVG_TAG_CONTENT, LV_SVG_TAG_SVG, @@ -54,7 +54,7 @@ enum { }; typedef int8_t lv_svg_tag_t; -enum { +enum _lv_svg_attr_type_t { LV_SVG_ATTR_INVALID = 0, LV_SVG_ATTR_ID, LV_SVG_ATTR_XML_ID, @@ -136,7 +136,7 @@ enum { }; typedef uint8_t lv_svg_attr_type_t; -enum { +enum _lv_svg_transform_type_t { LV_SVG_TRANSFORM_TYPE_MATRIX = 1, LV_SVG_TRANSFORM_TYPE_TRANSLATE, LV_SVG_TRANSFORM_TYPE_ROTATE, @@ -147,36 +147,36 @@ enum { typedef uint8_t lv_svg_transform_type_t; #if LV_USE_SVG_ANIMATION -enum { +enum lv_svg_anim_action_t { LV_SVG_ANIM_REMOVE = 0, LV_SVG_ANIM_FREEZE, }; -enum { +enum _lv_svg_anim_restart_type_t { LV_SVG_ANIM_RESTART_ALWAYS = 0, LV_SVG_ANIM_RESTART_WHEN_NOT_ACTIVE, LV_SVG_ANIM_RESTART_NEVER, }; -enum { +enum _lv_svg_anim_calc_mode_t { LV_SVG_ANIM_CALC_MODE_LINEAR = 0, LV_SVG_ANIM_CALC_MODE_PACED, LV_SVG_ANIM_CALC_MODE_SPLINE, LV_SVG_ANIM_CALC_MODE_DISCRETE, }; -enum { +enum _lv_svg_anim_additive_type_t { LV_SVG_ANIM_ADDITIVE_REPLACE = 0, LV_SVG_ANIM_ADDITIVE_SUM, }; -enum { +enum _lv_svg_anim_accumulate_type_t { LV_SVG_ANIM_ACCUMULATE_NONE = 0, LV_SVG_ANIM_ACCUMULATE_SUM, }; #endif -enum { +enum _lv_svg_aspect_ratio_t { LV_SVG_ASPECT_RATIO_NONE = 0, LV_SVG_ASPECT_RATIO_XMIN_YMIN = (1 << 1), LV_SVG_ASPECT_RATIO_XMID_YMIN = (2 << 1), @@ -188,12 +188,12 @@ enum { LV_SVG_ASPECT_RATIO_XMID_YMAX = (8 << 1), LV_SVG_ASPECT_RATIO_XMAX_YMAX = (9 << 1), }; +typedef uint32_t lv_svg_aspect_ratio_t; -enum { +enum _lv_svg_aspect_ratio_opt_t { LV_SVG_ASPECT_RATIO_OPT_MEET = 0, LV_SVG_ASPECT_RATIO_OPT_SLICE, }; -typedef uint32_t lv_svg_aspect_ratio_t; typedef struct { float x; @@ -206,27 +206,27 @@ typedef struct { typedef uint32_t lv_svg_color_t; -enum { +enum _lv_svg_fill_rule_t { LV_SVG_FILL_NONZERO = 0, LV_SVG_FILL_EVENODD, }; typedef uint8_t lv_svg_fill_rule_t; -enum { +enum _lv_svg_line_cap_t { LV_SVG_LINE_CAP_BUTT = 0, LV_SVG_LINE_CAP_SQUARE, LV_SVG_LINE_CAP_ROUND, }; typedef uint8_t lv_svg_line_cap_t; -enum { +enum _lv_svg_line_join_t { LV_SVG_LINE_JOIN_MITER = 0, LV_SVG_LINE_JOIN_BEVEL, LV_SVG_LINE_JOIN_ROUND, }; typedef uint8_t lv_svg_line_join_t; -enum { +enum _lv_svg_gradient_units_t { LV_SVG_GRADIENT_UNITS_OBJECT = 0, LV_SVG_GRADIENT_UNITS_USER_SPACE, }; @@ -250,11 +250,12 @@ typedef struct { } lv_svg_attr_values_list_t; /* https://www.w3.org/TR/SVGTiny12/svgudomidl.html */ -enum { +enum _lv_svg_path_cmd_t { LV_SVG_PATH_CMD_MOVE_TO = 77, LV_SVG_PATH_CMD_LINE_TO = 76, LV_SVG_PATH_CMD_CURVE_TO = 67, LV_SVG_PATH_CMD_QUAD_TO = 81, + LV_SVG_PATH_CMD_ARC_TO = 65, /*svg2 extension*/ LV_SVG_PATH_CMD_CLOSE = 90, }; @@ -267,13 +268,13 @@ typedef struct { uint8_t data[1]; } lv_svg_attr_path_value_t; -enum { +enum _lv_svg_attr_value_type_t { LV_SVG_ATTR_VALUE_DATA = 0, LV_SVG_ATTR_VALUE_PTR, }; typedef uint8_t lv_svg_attr_value_type_t; -enum { +enum _lv_svg_attr_value_class_t { LV_SVG_ATTR_VALUE_NONE = 0, LV_SVG_ATTR_VALUE_INITIAL, LV_SVG_ATTR_VALUE_INHERIT, diff --git a/src/libs/svg/lv_svg_decoder.c b/src/libs/svg/lv_svg_decoder.c index 833d01dbb6..011e63f818 100644 --- a/src/libs/svg/lv_svg_decoder.c +++ b/src/libs/svg/lv_svg_decoder.c @@ -343,19 +343,23 @@ static void svg_draw_buf_free(void * svg_buf) lv_svg_render_delete(draw_list); } -static void svg_draw(lv_layer_t * layer, const lv_image_decoder_dsc_t * dsc, const lv_area_t * coords, +static void svg_draw(lv_layer_t * layer, const lv_image_decoder_dsc_t * decoder_dsc, const lv_area_t * coords, const lv_draw_image_dsc_t * image_dsc, const lv_area_t * clip_area) { - const lv_draw_buf_t * draw_buf = dsc->decoded; + const lv_draw_buf_t * draw_buf = decoder_dsc->decoded; const lv_svg_render_obj_t * list = draw_buf->unaligned_data; LV_PROFILER_DRAW_BEGIN; - lv_vector_dsc_t * ctx = lv_vector_dsc_create(layer); + lv_draw_vector_dsc_t * dsc = lv_draw_vector_dsc_create(layer); + + /*Save the widget so that `LV_EVENT_DRAW_TASK_ADDED` can be sent to it in `lv_draw_vector`*/ + dsc->base.obj = image_dsc->base.obj; + lv_matrix_t matrix; lv_matrix_identity(&matrix); lv_matrix_translate(&matrix, coords->x1, coords->y1); - ctx->current_dsc.scissor_area = *clip_area; + dsc->ctx->scissor_area = *clip_area; if(image_dsc) { int32_t off_x = (lv_area_get_width(coords) - image_dsc->header.w - 1) / 2; int32_t off_y = (lv_area_get_height(coords) - image_dsc->header.h - 1) / 2; @@ -368,10 +372,10 @@ static void svg_draw(lv_layer_t * layer, const lv_image_decoder_dsc_t * dsc, con lv_matrix_scale(&matrix, image_dsc->scale_x / 256.0f, image_dsc->scale_y / 256.0f); lv_matrix_translate(&matrix, -image_dsc->pivot.x, -image_dsc->pivot.y); } - lv_vector_dsc_set_transform(ctx, &matrix); - lv_draw_svg_render(ctx, list); - lv_draw_vector(ctx); - lv_vector_dsc_delete(ctx); + lv_draw_vector_dsc_set_transform(dsc, &matrix); + lv_draw_svg_render(dsc, list); + lv_draw_vector(dsc); + lv_draw_vector_dsc_delete(dsc); LV_PROFILER_DRAW_END; } diff --git a/src/libs/svg/lv_svg_parser.c b/src/libs/svg/lv_svg_parser.c index 9f720cc7b5..16f60e0bd3 100644 --- a/src/libs/svg/lv_svg_parser.c +++ b/src/libs/svg/lv_svg_parser.c @@ -422,7 +422,7 @@ static bool _is_number_begin(char ch) static const char * _skip_space(const char * str, const char * str_end) { - while((str < str_end) && isspace(*str)) { + while((str < str_end) && isspace((unsigned char) * str)) { ++str; } return str; @@ -435,7 +435,7 @@ static bool _is_separators(char c) static const char * _skip_space_and_separators(const char * str, const char * str_end) { - while((str < str_end) && (isspace(*str) || _is_separators(*str))) { + while((str < str_end) && (isspace((unsigned char) * str) || _is_separators(*str))) { ++str; } return str; @@ -515,7 +515,7 @@ static const char * _parse_color(const char * str, const char * str_end, uint32_ if(*str == '#') { if(len == 4) { // three digit hex format '#rgb' - if(isxdigit(str[1]) && isxdigit(str[2]) && isxdigit(str[3])) { + if(isxdigit((unsigned char)str[1]) && isxdigit((unsigned char)str[2]) && isxdigit((unsigned char)str[3])) { char st[3] = {0}; st[0] = st[1] = str[1]; r = (uint8_t)strtol(st, NULL, 16); @@ -526,8 +526,8 @@ static const char * _parse_color(const char * str, const char * str_end, uint32_ } } else if(len == 7) { // six digit hex format '#rrggbb' - if(isxdigit(str[1]) && isxdigit(str[2]) && isxdigit(str[3]) - && isxdigit(str[4]) && isxdigit(str[5]) && isxdigit(str[6])) { + if(isxdigit((unsigned char)str[1]) && isxdigit((unsigned char)str[2]) && isxdigit((unsigned char)str[3]) + && isxdigit((unsigned char)str[4]) && isxdigit((unsigned char)str[5]) && isxdigit((unsigned char)str[6])) { char st[3] = {0}; st[0] = str[1]; st[1] = str[2]; @@ -893,6 +893,9 @@ static int _get_path_point_count(char cmd) case 'T': case 't': return 2; + case 'A': + case 'a': + return 4; default: return 0; } @@ -901,6 +904,7 @@ static int _get_path_point_count(char cmd) static bool _is_relative_cmd(char cmd) { switch(cmd) { + case 'a': case 'm': case 'l': case 'h': @@ -911,6 +915,7 @@ static bool _is_relative_cmd(char cmd) case 't': case 'z': return true; + case 'A': case 'M': case 'L': case 'H': @@ -927,7 +932,7 @@ static bool _is_relative_cmd(char cmd) static bool _is_path_cmd(char ch) { - return ch != 0 && strchr("MLHVCSQTZmlhvcsqtz", ch) != NULL; + return ch != 0 && strchr("AMLHVCSQTZamlhvcsqtz", ch) != NULL; } static void _process_path_value(lv_svg_node_t * node, lv_svg_attr_type_t type, const char * val_start, @@ -981,6 +986,7 @@ static void _process_path_value(lv_svg_node_t * node, lv_svg_attr_type_t type, c ++ptr; } else { + LV_LOG_ERROR("Unsupport path command [%c]", ch); break; } @@ -1177,6 +1183,43 @@ static void _process_path_value(lv_svg_node_t * node, lv_svg_attr_type_t type, c cur_point.y = point[1].y; } break; + case 'A': + case 'a': { + lv_svg_point_t * point = (lv_svg_point_t *)(&path_seg->data); + float rx = 0.0f; + ptr = _parse_number(ptr, val_end, &rx); + float ry = 0.0f; + ptr = _parse_number(ptr, val_end, &ry); + float rotate = 0.0f; + ptr = _parse_number(ptr, val_end, &rotate); + float large_arc = 0.0f; + ptr = _parse_number(ptr, val_end, &large_arc); + float sweep = 0.0f; + ptr = _parse_number(ptr, val_end, &sweep); + + float xval = 0.0f; + ptr = _parse_number(ptr, val_end, &xval); + float yval = 0.0f; + ptr = _parse_number(ptr, val_end, &yval); + if(relative) { + xval += cur_point.x; + yval += cur_point.y; + } + + path_seg->cmd = LV_SVG_PATH_CMD_ARC_TO; + point[0].x = rx; + point[0].y = ry; + point[1].x = rotate; + point[1].y = 0.0f; + point[2].x = large_arc; + point[2].y = sweep; + point[3].x = xval; + point[3].y = yval; + + cur_point.x = xval; + cur_point.y = yval; + } + break; case 'Z': case 'z': { path_seg->cmd = LV_SVG_PATH_CMD_CLOSE; @@ -1419,7 +1462,7 @@ static void _process_paint(lv_svg_node_t * node, lv_svg_attr_type_t type, const url_start = ptr + 1; } - while((ptr < val_end) && !isspace(*ptr) && *ptr != ')') { + while((ptr < val_end) && !isspace((unsigned char) * ptr) && *ptr != ')') { ++ptr; } diff --git a/src/libs/svg/lv_svg_render.c b/src/libs/svg/lv_svg_render.c index 478804f64e..2107ee7d56 100644 --- a/src/libs/svg/lv_svg_render.c +++ b/src/libs/svg/lv_svg_render.c @@ -62,12 +62,12 @@ enum { /********************** * TYPEDEFS **********************/ -static void _set_attr(lv_svg_render_obj_t * obj, lv_vector_draw_dsc_t * dsc, const lv_svg_attr_t * attr); -static void _init_draw_dsc(lv_vector_draw_dsc_t * dsc); -static void _deinit_draw_dsc(lv_vector_draw_dsc_t * dsc); -static void _copy_draw_dsc(lv_vector_draw_dsc_t * dst, const lv_vector_draw_dsc_t * src); -static void _prepare_render(const lv_svg_render_obj_t * obj, lv_vector_dsc_t * dsc); -static void _special_render(const lv_svg_render_obj_t * obj, lv_vector_dsc_t * dsc); +static void _set_attr(lv_svg_render_obj_t * obj, lv_vector_path_ctx_t * dsc, const lv_svg_attr_t * attr); +static void _init_draw_dsc(lv_vector_path_ctx_t * dsc); +static void _deinit_draw_dsc(lv_vector_path_ctx_t * dsc); +static void _copy_draw_dsc(lv_vector_path_ctx_t * dst, const lv_vector_path_ctx_t * src); +static void _prepare_render(const lv_svg_render_obj_t * obj, lv_draw_vector_dsc_t * dsc); +static void _special_render(const lv_svg_render_obj_t * obj, lv_draw_vector_dsc_t * dsc); #if LV_USE_FREETYPE static void _freetype_outline_cb(lv_event_t * e); #endif @@ -169,7 +169,7 @@ typedef struct { typedef struct _lv_svg_render_content { lv_svg_render_obj_t base; void (*render_content)(const struct _lv_svg_render_content * content, - lv_vector_dsc_t * dsc, lv_matrix_t * matrix); + lv_draw_vector_dsc_t * dsc, lv_matrix_t * matrix); uint32_t * letters; uint32_t count; } lv_svg_render_content_t; @@ -187,7 +187,7 @@ typedef struct { struct _lv_svg_draw_dsc { struct _lv_svg_draw_dsc * next; - lv_vector_draw_dsc_t dsc; + lv_vector_path_ctx_t dsc; const char * fill_ref; const char * stroke_ref; }; @@ -261,7 +261,7 @@ static struct _lv_svg_draw_dsc * _lv_svg_draw_dsc_pop(struct _lv_svg_draw_dsc * return cur; } -static void _set_viewport_attr(lv_svg_render_obj_t * obj, lv_vector_draw_dsc_t * dsc, const lv_svg_attr_t * attr) +static void _set_viewport_attr(lv_svg_render_obj_t * obj, lv_vector_path_ctx_t * dsc, const lv_svg_attr_t * attr) { lv_svg_render_viewport_t * view = (lv_svg_render_viewport_t *)obj; switch(attr->id) { @@ -313,7 +313,7 @@ static void _set_viewport_attr(lv_svg_render_obj_t * obj, lv_vector_draw_dsc_t * } } -static void _set_use_attr(lv_svg_render_obj_t * obj, lv_vector_draw_dsc_t * dsc, const lv_svg_attr_t * attr) +static void _set_use_attr(lv_svg_render_obj_t * obj, lv_vector_path_ctx_t * dsc, const lv_svg_attr_t * attr) { _set_attr(obj, dsc, attr); lv_svg_render_use_t * use = (lv_svg_render_use_t *)obj; @@ -332,7 +332,7 @@ static void _set_use_attr(lv_svg_render_obj_t * obj, lv_vector_draw_dsc_t * dsc, } } -static void _set_solid_attr(lv_svg_render_obj_t * obj, lv_vector_draw_dsc_t * dsc, const lv_svg_attr_t * attr) +static void _set_solid_attr(lv_svg_render_obj_t * obj, lv_vector_path_ctx_t * dsc, const lv_svg_attr_t * attr) { LV_UNUSED(dsc); lv_svg_render_solid_t * solid = (lv_svg_render_solid_t *)obj; @@ -346,7 +346,7 @@ static void _set_solid_attr(lv_svg_render_obj_t * obj, lv_vector_draw_dsc_t * ds } } -static void _set_gradient_attr(lv_svg_render_obj_t * obj, lv_vector_draw_dsc_t * dsc, const lv_svg_attr_t * attr) +static void _set_gradient_attr(lv_svg_render_obj_t * obj, lv_vector_path_ctx_t * dsc, const lv_svg_attr_t * attr) { LV_UNUSED(dsc); lv_svg_render_gradient_t * grad = (lv_svg_render_gradient_t *)obj; @@ -378,7 +378,7 @@ static void _set_gradient_attr(lv_svg_render_obj_t * obj, lv_vector_draw_dsc_t * } } -static void _set_rect_attr(lv_svg_render_obj_t * obj, lv_vector_draw_dsc_t * dsc, const lv_svg_attr_t * attr) +static void _set_rect_attr(lv_svg_render_obj_t * obj, lv_vector_path_ctx_t * dsc, const lv_svg_attr_t * attr) { _set_attr(obj, dsc, attr); lv_svg_render_rect_t * rect = (lv_svg_render_rect_t *)obj; @@ -404,7 +404,7 @@ static void _set_rect_attr(lv_svg_render_obj_t * obj, lv_vector_draw_dsc_t * dsc } } -static void _set_circle_attr(lv_svg_render_obj_t * obj, lv_vector_draw_dsc_t * dsc, const lv_svg_attr_t * attr) +static void _set_circle_attr(lv_svg_render_obj_t * obj, lv_vector_path_ctx_t * dsc, const lv_svg_attr_t * attr) { _set_attr(obj, dsc, attr); lv_svg_render_circle_t * circle = (lv_svg_render_circle_t *)obj; @@ -421,7 +421,7 @@ static void _set_circle_attr(lv_svg_render_obj_t * obj, lv_vector_draw_dsc_t * d } } -static void _set_ellipse_attr(lv_svg_render_obj_t * obj, lv_vector_draw_dsc_t * dsc, const lv_svg_attr_t * attr) +static void _set_ellipse_attr(lv_svg_render_obj_t * obj, lv_vector_path_ctx_t * dsc, const lv_svg_attr_t * attr) { _set_attr(obj, dsc, attr); lv_svg_render_ellipse_t * ellipse = (lv_svg_render_ellipse_t *)obj; @@ -441,7 +441,7 @@ static void _set_ellipse_attr(lv_svg_render_obj_t * obj, lv_vector_draw_dsc_t * } } -static void _set_line_attr(lv_svg_render_obj_t * obj, lv_vector_draw_dsc_t * dsc, const lv_svg_attr_t * attr) +static void _set_line_attr(lv_svg_render_obj_t * obj, lv_vector_path_ctx_t * dsc, const lv_svg_attr_t * attr) { _set_attr(obj, dsc, attr); lv_svg_render_line_t * line = (lv_svg_render_line_t *)obj; @@ -461,7 +461,7 @@ static void _set_line_attr(lv_svg_render_obj_t * obj, lv_vector_draw_dsc_t * dsc } } -static void _set_polyline_attr(lv_svg_render_obj_t * obj, lv_vector_draw_dsc_t * dsc, const lv_svg_attr_t * attr) +static void _set_polyline_attr(lv_svg_render_obj_t * obj, lv_vector_path_ctx_t * dsc, const lv_svg_attr_t * attr) { _set_attr(obj, dsc, attr); lv_svg_render_poly_t * poly = (lv_svg_render_poly_t *)obj; @@ -483,7 +483,7 @@ static void _set_polyline_attr(lv_svg_render_obj_t * obj, lv_vector_draw_dsc_t * } } -static void _set_polygon_attr(lv_svg_render_obj_t * obj, lv_vector_draw_dsc_t * dsc, const lv_svg_attr_t * attr) +static void _set_polygon_attr(lv_svg_render_obj_t * obj, lv_vector_path_ctx_t * dsc, const lv_svg_attr_t * attr) { _set_polyline_attr(obj, dsc, attr); lv_svg_render_poly_t * poly = (lv_svg_render_poly_t *)obj; @@ -503,12 +503,14 @@ static size_t _get_path_seg_size(uint32_t cmd) return sizeof(lv_svg_point_t) * 2 + sizeof(uint32_t); case LV_SVG_PATH_CMD_CURVE_TO: return sizeof(lv_svg_point_t) * 3 + sizeof(uint32_t); + case LV_SVG_PATH_CMD_ARC_TO: + return sizeof(lv_svg_point_t) * 4 + sizeof(uint32_t); default: return 0; } } -static void _set_path_attr(lv_svg_render_obj_t * obj, lv_vector_draw_dsc_t * dsc, const lv_svg_attr_t * attr) +static void _set_path_attr(lv_svg_render_obj_t * obj, lv_vector_path_ctx_t * dsc, const lv_svg_attr_t * attr) { _set_attr(obj, dsc, attr); lv_svg_render_poly_t * poly = (lv_svg_render_poly_t *)obj; @@ -557,6 +559,17 @@ static void _set_path_attr(lv_svg_render_obj_t * obj, lv_vector_draw_dsc_t * dsc CALC_BOUNDS(pt[2], poly->bounds); } break; + case LV_SVG_PATH_CMD_ARC_TO: { + lv_fpoint_t pt[4] = { + {points[0].x, points[0].y}, + {points[1].x, points[1].y}, + {points[2].x, points[2].y}, + {points[3].x, points[3].y} + }; + lv_vector_path_arc_to(poly->path, pt[0].x, pt[0].y, pt[1].x, pt[2].x > 0, pt[2].y > 0, &pt[3]); + lv_vector_path_get_bounding(poly->path, &poly->bounds); + } + break; case LV_SVG_PATH_CMD_CLOSE: { lv_vector_path_close(poly->path); } @@ -641,7 +654,7 @@ static void _set_path_attr(lv_svg_render_obj_t * obj, lv_vector_draw_dsc_t * dsc } \ } while(0) -static void _set_tspan_attr(lv_svg_render_obj_t * obj, lv_vector_draw_dsc_t * dsc, const lv_svg_attr_t * attr) +static void _set_tspan_attr(lv_svg_render_obj_t * obj, lv_vector_path_ctx_t * dsc, const lv_svg_attr_t * attr) { _set_attr(obj, dsc, attr); lv_svg_render_tspan_t * tspan = (lv_svg_render_tspan_t *)obj; @@ -649,7 +662,7 @@ static void _set_tspan_attr(lv_svg_render_obj_t * obj, lv_vector_draw_dsc_t * ds SET_FONT_ATTRS(tspan, attr); } -static void _set_text_attr(lv_svg_render_obj_t * obj, lv_vector_draw_dsc_t * dsc, const lv_svg_attr_t * attr) +static void _set_text_attr(lv_svg_render_obj_t * obj, lv_vector_path_ctx_t * dsc, const lv_svg_attr_t * attr) { _set_attr(obj, dsc, attr); lv_svg_render_text_t * text = (lv_svg_render_text_t *)obj; @@ -667,7 +680,7 @@ static void _set_text_attr(lv_svg_render_obj_t * obj, lv_vector_draw_dsc_t * dsc } #endif -static void _set_image_attr(lv_svg_render_obj_t * obj, lv_vector_draw_dsc_t * dsc, const lv_svg_attr_t * attr) +static void _set_image_attr(lv_svg_render_obj_t * obj, lv_vector_path_ctx_t * dsc, const lv_svg_attr_t * attr) { _set_attr(obj, dsc, attr); lv_svg_render_image_t * image = (lv_svg_render_image_t *)obj; @@ -703,7 +716,7 @@ static void _set_image_attr(lv_svg_render_obj_t * obj, lv_vector_draw_dsc_t * ds } } -static void _set_attr(lv_svg_render_obj_t * obj, lv_vector_draw_dsc_t * dsc, const lv_svg_attr_t * attr) +static void _set_attr(lv_svg_render_obj_t * obj, lv_vector_path_ctx_t * dsc, const lv_svg_attr_t * attr) { LV_UNUSED(obj); switch(attr->id) { @@ -726,7 +739,7 @@ static void _set_attr(lv_svg_render_obj_t * obj, lv_vector_draw_dsc_t * dsc, con if(attr->val_type == LV_SVG_ATTR_VALUE_PTR) { obj->fill_ref = lv_strdup(attr->value.sval); } - else { // color + else { /* color */ dsc->fill_dsc.style = LV_VECTOR_DRAW_STYLE_SOLID; dsc->fill_dsc.color = lv_color_to_32(lv_color_hex(attr->value.uval), 0xFF); } @@ -757,7 +770,7 @@ static void _set_attr(lv_svg_render_obj_t * obj, lv_vector_draw_dsc_t * dsc, con if(attr->val_type == LV_SVG_ATTR_VALUE_PTR) { obj->stroke_ref = lv_strdup(attr->value.sval); } - else { // color + else { /* color */ dsc->stroke_dsc.style = LV_VECTOR_DRAW_STYLE_SOLID; dsc->stroke_dsc.color = lv_color_to_32(lv_color_hex(attr->value.uval), 0xFF); } @@ -874,12 +887,12 @@ static void _set_attr(lv_svg_render_obj_t * obj, lv_vector_draw_dsc_t * dsc, con } break; case LV_SVG_ATTR_STROKE_DASH_OFFSET: - // not support yet + /* not support yet */ break; } } -static void _set_solid_ref(lv_svg_render_obj_t * obj, lv_vector_draw_dsc_t * dsc, +static void _set_solid_ref(lv_svg_render_obj_t * obj, lv_vector_path_ctx_t * dsc, const lv_svg_render_obj_t * target_obj, bool fill) { LV_UNUSED(target_obj); @@ -896,7 +909,7 @@ static void _set_solid_ref(lv_svg_render_obj_t * obj, lv_vector_draw_dsc_t * dsc } } -static void _set_gradient_ref(lv_svg_render_obj_t * obj, lv_vector_draw_dsc_t * dsc, +static void _set_gradient_ref(lv_svg_render_obj_t * obj, lv_vector_path_ctx_t * dsc, const lv_svg_render_obj_t * target_obj, bool fill) { if(!target_obj->clz->get_bounds) { @@ -918,6 +931,17 @@ static void _set_gradient_ref(lv_svg_render_obj_t * obj, lv_vector_draw_dsc_t * mtx = &dsc->stroke_dsc.matrix; } + if(grad->units == LV_SVG_GRADIENT_UNITS_USER_SPACE) { + lv_svg_render_obj_t * list = obj->head; + while(list) { + if(list->tag == LV_SVG_TAG_SVG) { + target_obj = list; /* viewport */ + break; + } + list = list->next; + } + } + lv_memcpy(grad_dsc, &grad->dsc, sizeof(lv_vector_gradient_t)); lv_area_t bounds = {0, 0, 0, 0}; @@ -926,53 +950,53 @@ static void _set_gradient_ref(lv_svg_render_obj_t * obj, lv_vector_draw_dsc_t * int32_t w = bounds.x2 - bounds.x1; int32_t h = bounds.y2 - bounds.y1; if(grad->dsc.style == LV_VECTOR_GRADIENT_STYLE_RADIAL) { + grad_dsc->cx = PCT_TO_PX(grad_dsc->cx, w); + grad_dsc->cy = PCT_TO_PX(grad_dsc->cy, h); + grad_dsc->cr = PCT_TO_PX(grad_dsc->cr, MAX(w, h)); if(grad->units == LV_SVG_GRADIENT_UNITS_OBJECT) { - grad_dsc->cx = PCT_TO_PX(grad_dsc->cx, w); - grad_dsc->cy = PCT_TO_PX(grad_dsc->cy, h); - grad_dsc->cr = PCT_TO_PX(grad_dsc->cr, MAX(w, h)); lv_matrix_translate(mtx, bounds.x1, bounds.y1); } } - else { // LV_VECTOR_GRADIENT_STYLE_LINEAR + else { /* LV_VECTOR_GRADIENT_STYLE_LINEAR */ + grad_dsc->x1 = PCT_TO_PX(grad_dsc->x1, w); + grad_dsc->y1 = PCT_TO_PX(grad_dsc->y1, h); + grad_dsc->x2 = PCT_TO_PX(grad_dsc->x2, w); + grad_dsc->y2 = PCT_TO_PX(grad_dsc->y2, h); if(grad->units == LV_SVG_GRADIENT_UNITS_OBJECT) { - grad_dsc->x1 = PCT_TO_PX(grad_dsc->x1, w); - grad_dsc->y1 = PCT_TO_PX(grad_dsc->y1, h); - grad_dsc->x2 = PCT_TO_PX(grad_dsc->x2, w); - grad_dsc->y2 = PCT_TO_PX(grad_dsc->y2, h); lv_matrix_translate(mtx, bounds.x1, bounds.y1); } } } -static void _init_draw_dsc(lv_vector_draw_dsc_t * dsc) +static void _init_draw_dsc(lv_vector_path_ctx_t * dsc) { lv_vector_fill_dsc_t * fill_dsc = &(dsc->fill_dsc); fill_dsc->style = LV_VECTOR_DRAW_STYLE_SOLID; fill_dsc->color = lv_color_to_32(lv_color_black(), 0xFF); fill_dsc->opa = LV_OPA_COVER; fill_dsc->fill_rule = LV_VECTOR_FILL_NONZERO; - lv_matrix_identity(&(fill_dsc->matrix)); // identity matrix + lv_matrix_identity(&(fill_dsc->matrix)); /* identity matrix */ lv_vector_stroke_dsc_t * stroke_dsc = &(dsc->stroke_dsc); stroke_dsc->style = LV_VECTOR_DRAW_STYLE_SOLID; stroke_dsc->color = lv_color_to_32(lv_color_black(), 0xFF); - stroke_dsc->opa = LV_OPA_0; // default no stroke + stroke_dsc->opa = LV_OPA_0; /* default no stroke */ stroke_dsc->width = 1.0f; stroke_dsc->cap = LV_VECTOR_STROKE_CAP_BUTT; stroke_dsc->join = LV_VECTOR_STROKE_JOIN_MITER; stroke_dsc->miter_limit = 4.0f; - lv_matrix_identity(&(stroke_dsc->matrix)); // identity matrix + lv_matrix_identity(&(stroke_dsc->matrix)); dsc->blend_mode = LV_VECTOR_BLEND_SRC_OVER; - lv_matrix_identity(&(dsc->matrix)); // identity matrix + lv_matrix_identity(&(dsc->matrix)); } -static void _deinit_draw_dsc(lv_vector_draw_dsc_t * dsc) +static void _deinit_draw_dsc(lv_vector_path_ctx_t * dsc) { lv_array_deinit(&(dsc->stroke_dsc.dash_pattern)); } -static void _copy_draw_dsc(lv_vector_draw_dsc_t * dst, const lv_vector_draw_dsc_t * src) +static void _copy_draw_dsc(lv_vector_path_ctx_t * dst, const lv_vector_path_ctx_t * src) { lv_memcpy(&dst->fill_dsc, &src->fill_dsc, sizeof(lv_vector_fill_dsc_t)); @@ -983,6 +1007,7 @@ static void _copy_draw_dsc(lv_vector_draw_dsc_t * dst, const lv_vector_draw_dsc_ dst->stroke_dsc.cap = src->stroke_dsc.cap; dst->stroke_dsc.join = src->stroke_dsc.join; dst->stroke_dsc.miter_limit = src->stroke_dsc.miter_limit; + lv_array_clear(&(dst->stroke_dsc.dash_pattern)); lv_array_copy(&(dst->stroke_dsc.dash_pattern), &(src->stroke_dsc.dash_pattern)); lv_memcpy(&(dst->stroke_dsc.gradient), &(src->stroke_dsc.gradient), sizeof(lv_vector_gradient_t)); lv_memcpy(&(dst->stroke_dsc.matrix), &(src->stroke_dsc.matrix), sizeof(lv_matrix_t)); @@ -990,9 +1015,9 @@ static void _copy_draw_dsc(lv_vector_draw_dsc_t * dst, const lv_vector_draw_dsc_ dst->blend_mode = src->blend_mode; } -static void _copy_draw_dsc_from_ref(lv_vector_dsc_t * dsc, const lv_svg_render_obj_t * obj) +static void _copy_draw_dsc_from_ref(lv_draw_vector_dsc_t * dsc, const lv_svg_render_obj_t * obj) { - lv_vector_draw_dsc_t * dst = &(dsc->current_dsc); + lv_vector_path_ctx_t * dst = dsc->ctx; if(obj->fill_ref) { lv_svg_render_obj_t * list = obj->head; while(list) { @@ -1042,14 +1067,14 @@ static void _set_render_attrs(lv_svg_render_obj_t * obj, const lv_svg_node_t * n lv_svg_attr_t * attr = lv_array_at(&node->attrs, i); obj->clz->set_attr(obj, &(state->draw_dsc->dsc), attr); } - if(node->type == LV_SVG_TAG_G) { // only need store it + if(node->type == LV_SVG_TAG_G) { /* only need store it */ state->draw_dsc->fill_ref = obj->fill_ref; state->draw_dsc->stroke_ref = obj->stroke_ref; } obj->head = state->list; } -// init functions +/* init functions */ static void _init_obj(lv_svg_render_obj_t * obj, const lv_svg_node_t * node) { @@ -1084,7 +1109,7 @@ static void _init_poly(lv_svg_render_obj_t * obj, const lv_svg_node_t * node) _init_obj(obj, node); lv_svg_render_poly_t * poly = (lv_svg_render_poly_t *)obj; poly->path = lv_vector_path_create(LV_VECTOR_PATH_QUALITY_MEDIUM); - lv_area_set(&poly->bounds, 0, 0, 0, 0); + lv_area_set(&poly->bounds, INT_MAX, INT_MAX, INT_MIN, INT_MIN); } #if LV_USE_FREETYPE @@ -1135,6 +1160,13 @@ static void _init_tspan(lv_svg_render_obj_t * obj, const lv_svg_node_t * node) } #endif +static void _init_solid(lv_svg_render_obj_t * obj, const lv_svg_node_t * node) +{ + _init_obj(obj, node); + lv_svg_render_solid_t * solid = (lv_svg_render_solid_t *)obj; + solid->opacity = 1.0f; +} + static void _init_gradient(lv_svg_render_obj_t * obj, const lv_svg_node_t * node) { _init_obj(obj, node); @@ -1196,26 +1228,26 @@ static void _init_gradient(lv_svg_render_obj_t * obj, const lv_svg_node_t * node grad->dsc.stops_count = stop_count; } -static void _setup_matrix(lv_matrix_t * matrix, lv_vector_dsc_t * dsc, const lv_svg_render_obj_t * obj) +static void _setup_matrix(lv_matrix_t * matrix, lv_draw_vector_dsc_t * dsc, const lv_svg_render_obj_t * obj) { - lv_memcpy(matrix, &dsc->current_dsc.matrix, sizeof(lv_matrix_t)); - lv_matrix_multiply(&dsc->current_dsc.matrix, &obj->matrix); + lv_memcpy(matrix, &dsc->ctx->matrix, sizeof(lv_matrix_t)); + lv_matrix_multiply(&dsc->ctx->matrix, &obj->matrix); } -static void _restore_matrix(lv_matrix_t * matrix, lv_vector_dsc_t * dsc) +static void _restore_matrix(lv_matrix_t * matrix, lv_draw_vector_dsc_t * dsc) { - lv_memcpy(&dsc->current_dsc.matrix, matrix, sizeof(lv_matrix_t)); + lv_memcpy(&dsc->ctx->matrix, matrix, sizeof(lv_matrix_t)); } -static void _prepare_render(const lv_svg_render_obj_t * obj, lv_vector_dsc_t * dsc) +static void _prepare_render(const lv_svg_render_obj_t * obj, lv_draw_vector_dsc_t * dsc) { - _copy_draw_dsc(&(dsc->current_dsc), &(obj->dsc)); + _copy_draw_dsc(dsc->ctx, &(obj->dsc)); } -static void _special_render(const lv_svg_render_obj_t * obj, lv_vector_dsc_t * dsc) +static void _special_render(const lv_svg_render_obj_t * obj, lv_draw_vector_dsc_t * dsc) { - const lv_vector_draw_dsc_t * src = &(obj->dsc); - lv_vector_draw_dsc_t * dst = &(dsc->current_dsc); + const lv_vector_path_ctx_t * src = &(obj->dsc); + lv_vector_path_ctx_t * dst = dsc->ctx; if(obj->flags & _RENDER_ATTR_FILL) { lv_memcpy(&(dst->fill_dsc), &(src->fill_dsc), sizeof(lv_vector_fill_dsc_t)); @@ -1255,30 +1287,34 @@ static void _special_render(const lv_svg_render_obj_t * obj, lv_vector_dsc_t * d dst->stroke_dsc.miter_limit = src->stroke_dsc.miter_limit; } if(obj->flags & _RENDER_ATTR_STROKE_DASH_ARRAY) { + lv_array_clear(&(dst->stroke_dsc.dash_pattern)); lv_array_copy(&(dst->stroke_dsc.dash_pattern), &(src->stroke_dsc.dash_pattern)); } } -// render functions -static void _render_viewport(const lv_svg_render_obj_t * obj, lv_vector_dsc_t * dsc, const lv_matrix_t * matrix) +/* render functions */ +static void _render_viewport(const lv_svg_render_obj_t * obj, lv_draw_vector_dsc_t * dsc, const lv_matrix_t * matrix) { LV_UNUSED(matrix); lv_svg_render_viewport_t * view = (lv_svg_render_viewport_t *)obj; - lv_matrix_multiply(&dsc->current_dsc.matrix, &obj->matrix); + lv_matrix_multiply(&dsc->ctx->matrix, &obj->matrix); if(view->viewport_fill) { lv_area_t rc = {0, 0, (int32_t)view->width, (int32_t)view->height}; - lv_vector_clear_area(dsc, &rc); + lv_vector_path_t * path = lv_vector_path_create(LV_VECTOR_PATH_QUALITY_MEDIUM); + lv_vector_path_append_rect(path, &rc, 0, 0); + lv_draw_vector_dsc_add_path(dsc, path); + lv_vector_path_delete(path); } } -static void _render_rect(const lv_svg_render_obj_t * obj, lv_vector_dsc_t * dsc, const lv_matrix_t * matrix) +static void _render_rect(const lv_svg_render_obj_t * obj, lv_draw_vector_dsc_t * dsc, const lv_matrix_t * matrix) { lv_matrix_t mtx; _setup_matrix(&mtx, dsc, obj); if(matrix) { - lv_matrix_multiply(&dsc->current_dsc.matrix, matrix); + lv_matrix_multiply(&dsc->ctx->matrix, matrix); } lv_svg_render_rect_t * rect = (lv_svg_render_rect_t *)obj; @@ -1291,19 +1327,19 @@ static void _render_rect(const lv_svg_render_obj_t * obj, lv_vector_dsc_t * dsc, lv_vector_path_append_rect(path, &rc, rect->rx, rect->ry); _copy_draw_dsc_from_ref(dsc, obj); - lv_vector_dsc_add_path(dsc, path); + lv_draw_vector_dsc_add_path(dsc, path); lv_vector_path_delete(path); _restore_matrix(&mtx, dsc); } -static void _render_circle(const lv_svg_render_obj_t * obj, lv_vector_dsc_t * dsc, const lv_matrix_t * matrix) +static void _render_circle(const lv_svg_render_obj_t * obj, lv_draw_vector_dsc_t * dsc, const lv_matrix_t * matrix) { lv_matrix_t mtx; _setup_matrix(&mtx, dsc, obj); if(matrix) { - lv_matrix_multiply(&dsc->current_dsc.matrix, matrix); + lv_matrix_multiply(&dsc->ctx->matrix, matrix); } lv_svg_render_circle_t * circle = (lv_svg_render_circle_t *)obj; @@ -1312,19 +1348,19 @@ static void _render_circle(const lv_svg_render_obj_t * obj, lv_vector_dsc_t * ds lv_vector_path_append_circle(path, &cp, circle->r, circle->r); _copy_draw_dsc_from_ref(dsc, obj); - lv_vector_dsc_add_path(dsc, path); + lv_draw_vector_dsc_add_path(dsc, path); lv_vector_path_delete(path); _restore_matrix(&mtx, dsc); } -static void _render_ellipse(const lv_svg_render_obj_t * obj, lv_vector_dsc_t * dsc, const lv_matrix_t * matrix) +static void _render_ellipse(const lv_svg_render_obj_t * obj, lv_draw_vector_dsc_t * dsc, const lv_matrix_t * matrix) { lv_matrix_t mtx; _setup_matrix(&mtx, dsc, obj); if(matrix) { - lv_matrix_multiply(&dsc->current_dsc.matrix, matrix); + lv_matrix_multiply(&dsc->ctx->matrix, matrix); } lv_svg_render_ellipse_t * ellipse = (lv_svg_render_ellipse_t *)obj; @@ -1333,19 +1369,19 @@ static void _render_ellipse(const lv_svg_render_obj_t * obj, lv_vector_dsc_t * d lv_vector_path_append_circle(path, &cp, ellipse->rx, ellipse->ry); _copy_draw_dsc_from_ref(dsc, obj); - lv_vector_dsc_add_path(dsc, path); + lv_draw_vector_dsc_add_path(dsc, path); lv_vector_path_delete(path); _restore_matrix(&mtx, dsc); } -static void _render_line(const lv_svg_render_obj_t * obj, lv_vector_dsc_t * dsc, const lv_matrix_t * matrix) +static void _render_line(const lv_svg_render_obj_t * obj, lv_draw_vector_dsc_t * dsc, const lv_matrix_t * matrix) { lv_matrix_t mtx; _setup_matrix(&mtx, dsc, obj); if(matrix) { - lv_matrix_multiply(&dsc->current_dsc.matrix, matrix); + lv_matrix_multiply(&dsc->ctx->matrix, matrix); } lv_svg_render_line_t * line = (lv_svg_render_line_t *)obj; @@ -1356,30 +1392,30 @@ static void _render_line(const lv_svg_render_obj_t * obj, lv_vector_dsc_t * dsc, lv_vector_path_line_to(path, &ep); _copy_draw_dsc_from_ref(dsc, obj); - lv_vector_dsc_add_path(dsc, path); + lv_draw_vector_dsc_add_path(dsc, path); lv_vector_path_delete(path); _restore_matrix(&mtx, dsc); } -static void _render_poly(const lv_svg_render_obj_t * obj, lv_vector_dsc_t * dsc, const lv_matrix_t * matrix) +static void _render_poly(const lv_svg_render_obj_t * obj, lv_draw_vector_dsc_t * dsc, const lv_matrix_t * matrix) { lv_matrix_t mtx; _setup_matrix(&mtx, dsc, obj); if(matrix) { - lv_matrix_multiply(&dsc->current_dsc.matrix, matrix); + lv_matrix_multiply(&dsc->ctx->matrix, matrix); } lv_svg_render_poly_t * poly = (lv_svg_render_poly_t *)obj; _copy_draw_dsc_from_ref(dsc, obj); - lv_vector_dsc_add_path(dsc, poly->path); + lv_draw_vector_dsc_add_path(dsc, poly->path); _restore_matrix(&mtx, dsc); } -static void _render_group(const lv_svg_render_obj_t * obj, lv_vector_dsc_t * dsc, const lv_matrix_t * matrix) +static void _render_group(const lv_svg_render_obj_t * obj, lv_draw_vector_dsc_t * dsc, const lv_matrix_t * matrix) { lv_svg_render_group_t * group = (lv_svg_render_group_t *)obj; lv_matrix_t mtx; @@ -1392,23 +1428,23 @@ static void _render_group(const lv_svg_render_obj_t * obj, lv_vector_dsc_t * dsc lv_svg_render_obj_t * list = *((lv_svg_render_obj_t **)lv_array_at(&group->items, i)); if(list->clz->render && (list->flags & _RENDER_IN_GROUP)) { - _copy_draw_dsc(&(save_dsc.dsc), &(dsc->current_dsc)); + _copy_draw_dsc(&(save_dsc.dsc), dsc->ctx); _special_render(list, dsc); list->clz->render(list, dsc, matrix); - _copy_draw_dsc(&(dsc->current_dsc), &(save_dsc.dsc)); + _copy_draw_dsc(dsc->ctx, &(save_dsc.dsc)); } } _restore_matrix(&mtx, dsc); } -static void _render_image(const lv_svg_render_obj_t * obj, lv_vector_dsc_t * dsc, const lv_matrix_t * matrix) +static void _render_image(const lv_svg_render_obj_t * obj, lv_draw_vector_dsc_t * dsc, const lv_matrix_t * matrix) { lv_matrix_t imtx; _setup_matrix(&imtx, dsc, obj); if(matrix) { - lv_matrix_multiply(&dsc->current_dsc.matrix, matrix); + lv_matrix_multiply(&dsc->ctx->matrix, matrix); } lv_svg_render_image_t * image = (lv_svg_render_image_t *)obj; @@ -1499,17 +1535,17 @@ static void _render_image(const lv_svg_render_obj_t * obj, lv_vector_dsc_t * dsc break; } - lv_vector_dsc_set_fill_transform(dsc, &mtx); - lv_vector_dsc_set_fill_image(dsc, &image->img_dsc); + lv_draw_vector_dsc_set_fill_transform(dsc, &mtx); + lv_draw_vector_dsc_set_fill_image(dsc, &image->img_dsc); _copy_draw_dsc_from_ref(dsc, obj); - lv_vector_dsc_add_path(dsc, path); + lv_draw_vector_dsc_add_path(dsc, path); lv_vector_path_delete(path); _restore_matrix(&imtx, dsc); } -static void _render_use(const lv_svg_render_obj_t * obj, lv_vector_dsc_t * dsc, const lv_matrix_t * matrix) +static void _render_use(const lv_svg_render_obj_t * obj, lv_draw_vector_dsc_t * dsc, const lv_matrix_t * matrix) { LV_UNUSED(matrix); lv_matrix_t imtx; @@ -1528,6 +1564,7 @@ static void _render_use(const lv_svg_render_obj_t * obj, lv_vector_dsc_t * dsc, if(list->clz->render) { _prepare_render(list, dsc); _special_render(obj, dsc); + _copy_draw_dsc_from_ref(dsc, obj); list->clz->render(list, dsc, &mtx); } break; @@ -1540,7 +1577,12 @@ static void _render_use(const lv_svg_render_obj_t * obj, lv_vector_dsc_t * dsc, } #if LV_USE_FREETYPE -static void _render_text(const lv_svg_render_obj_t * obj, lv_vector_dsc_t * dsc, const lv_matrix_t * matrix) +static bool _is_control_character(uint32_t ch) +{ + return ch == '\n' || ch == '\t' || ch == '\r'; +} + +static void _render_text(const lv_svg_render_obj_t * obj, lv_draw_vector_dsc_t * dsc, const lv_matrix_t * matrix) { lv_svg_render_text_t * text = (lv_svg_render_text_t *)obj; if(!text->font) { @@ -1564,28 +1606,38 @@ static void _render_text(const lv_svg_render_obj_t * obj, lv_vector_dsc_t * dsc, _setup_matrix(&tmtx, dsc, obj); if(matrix) { - lv_matrix_multiply(&dsc->current_dsc.matrix, matrix); + lv_matrix_multiply(&dsc->ctx->matrix, matrix); } + bool build_path = false; if(lv_array_size(&text->path->ops) == 0) { /* empty path */ - lv_vector_path_t * glyph_path = lv_vector_path_create(LV_VECTOR_PATH_QUALITY_MEDIUM); - // draw text contents and spans - lv_matrix_t mtx; - lv_matrix_identity(&mtx); - lv_matrix_translate(&mtx, text->x, text->y); - for(uint32_t i = 0; i < lv_array_size(&text->contents); i++) { - lv_svg_render_obj_t * ptext = *((lv_svg_render_obj_t **)lv_array_at(&text->contents, i)); - lv_svg_render_content_t * content = (lv_svg_render_content_t *)ptext; - - if(content->render_content) { - content->render_content(content, dsc, &mtx); - } - else { + build_path = true; + } + + /* draw text contents and spans */ + lv_matrix_t mtx; + lv_matrix_identity(&mtx); + lv_matrix_translate(&mtx, text->x, text->y); + for(uint32_t i = 0; i < lv_array_size(&text->contents); i++) { + lv_svg_render_obj_t * ptext = *((lv_svg_render_obj_t **)lv_array_at(&text->contents, i)); + lv_svg_render_content_t * content = (lv_svg_render_content_t *)ptext; + + if(content->render_content) { + content->render_content(content, dsc, &mtx); + } + else { + if(build_path) { + lv_vector_path_t * glyph_path = lv_vector_path_create(LV_VECTOR_PATH_QUALITY_MEDIUM); + float scale = text->size / 128.0f; for(uint32_t j = 0; j < content->count; j++) { + uint32_t letter = content->letters[j]; + if(_is_control_character(letter)) { + continue; + } lv_font_glyph_dsc_t g; - lv_font_get_glyph_dsc(text->font, &g, letter, '\0'); + lv_font_get_glyph_dsc(text->font, &g, content->letters[j], '\0'); lv_vector_path_t * p = (lv_vector_path_t *)lv_font_get_glyph_bitmap(&g, NULL); lv_vector_path_clear(glyph_path); lv_vector_path_copy(glyph_path, p); @@ -1600,19 +1652,20 @@ static void _render_text(const lv_svg_render_obj_t * obj, lv_vector_dsc_t * dsc, text->font->release_glyph(text->font, &g); lv_matrix_translate(&mtx, letter_w, 0); } + + lv_vector_path_delete(glyph_path); + lv_vector_path_get_bounding(text->path, &text->bounds); } } - lv_vector_path_delete(glyph_path); - lv_vector_path_get_bounding(text->path, &text->bounds); } _copy_draw_dsc_from_ref(dsc, obj); - lv_vector_dsc_add_path(dsc, text->path); + lv_draw_vector_dsc_add_path(dsc, text->path); _restore_matrix(&tmtx, dsc); } -static void _render_span(const lv_svg_render_content_t * content, lv_vector_dsc_t * dsc, lv_matrix_t * matrix) +static void _render_span(const lv_svg_render_content_t * content, lv_draw_vector_dsc_t * dsc, lv_matrix_t * matrix) { lv_svg_render_obj_t * obj = (lv_svg_render_obj_t *)content; @@ -1636,20 +1689,24 @@ static void _render_span(const lv_svg_render_content_t * content, lv_vector_dsc_ struct _lv_svg_draw_dsc save_dsc; lv_memzero(&save_dsc, sizeof(struct _lv_svg_draw_dsc)); - _copy_draw_dsc(&(save_dsc.dsc), &(dsc->current_dsc)); + _copy_draw_dsc(&(save_dsc.dsc), dsc->ctx); - _copy_draw_dsc(&(dsc->current_dsc), &(obj->dsc)); + _copy_draw_dsc(dsc->ctx, &(obj->dsc)); if(lv_array_size(&span->path->ops) == 0) { /* empty path */ lv_vector_path_t * glyph_path = lv_vector_path_create(LV_VECTOR_PATH_QUALITY_MEDIUM); - // draw text contents and spans + /* draw text contents and spans */ lv_matrix_t * mtx = matrix; float scale = span->size / 128.0f; for(uint32_t j = 0; j < content->count; j++) { + uint32_t letter = content->letters[j]; + if(_is_control_character(letter)) { + continue; + } lv_font_glyph_dsc_t g; - lv_font_get_glyph_dsc(span->font, &g, letter, '\0'); + lv_font_get_glyph_dsc(span->font, &g, content->letters[j], '\0'); lv_vector_path_t * p = (lv_vector_path_t *)lv_font_get_glyph_bitmap(&g, NULL); lv_vector_path_clear(glyph_path); lv_vector_path_copy(glyph_path, p); @@ -1668,13 +1725,13 @@ static void _render_span(const lv_svg_render_content_t * content, lv_vector_dsc_ lv_vector_path_get_bounding(span->path, &span->bounds); } _copy_draw_dsc_from_ref(dsc, obj); - lv_vector_dsc_add_path(dsc, span->path); + lv_draw_vector_dsc_add_path(dsc, span->path); - _copy_draw_dsc(&(dsc->current_dsc), &(save_dsc.dsc)); + _copy_draw_dsc(dsc->ctx, &(save_dsc.dsc)); } #endif -// get bounds functions +/* get bounds functions */ static void _get_viewport_bounds(const lv_svg_render_obj_t * obj, lv_area_t * area) { @@ -1727,6 +1784,51 @@ static void _get_poly_bounds(const lv_svg_render_obj_t * obj, lv_area_t * area) lv_area_copy(area, &poly->bounds); } +static void _get_group_bounds(const lv_svg_render_obj_t * obj, lv_area_t * area) +{ + lv_svg_render_group_t * group = (lv_svg_render_group_t *)obj; + + int32_t x1 = 0; + int32_t y1 = 0; + int32_t x2 = 0; + int32_t y2 = 0; + + for(uint32_t i = 0; i < group->items.size; i++) { + lv_svg_render_obj_t * list = *((lv_svg_render_obj_t **)lv_array_at(&group->items, i)); + + lv_area_t tc = {0}; + if(list->clz->get_bounds) { + list->clz->get_bounds(list, &tc); + + x1 = MIN(tc.x1, x1); + y1 = MIN(tc.y1, y1); + x2 = MAX(tc.x2, x2); + y2 = MAX(tc.y2, y2); + } + } + + area->x1 = x1; + area->y1 = y1; + area->x2 = x2; + area->y2 = y2; +} + +static void _get_use_bounds(const lv_svg_render_obj_t * obj, lv_area_t * area) +{ + lv_svg_render_use_t * use = (lv_svg_render_use_t *)obj; + + lv_svg_render_obj_t * list = obj->head; + while(list) { + if(list->id && strcmp(use->xlink, list->id) == 0) { + if(list->clz->get_bounds) { + list->clz->get_bounds(list, area); + } + break; + } + list = list->next; + } +} + #if LV_USE_FREETYPE static void _get_text_bounds(const lv_svg_render_obj_t * obj, lv_area_t * area) { @@ -1741,7 +1843,7 @@ static void _get_tspan_bounds(const lv_svg_render_obj_t * obj, lv_area_t * area) } #endif -// get size fucctions +/* get size fucctions */ static uint32_t _calc_path_data_size(lv_vector_path_t * path) { uint32_t size = 0; @@ -1891,7 +1993,7 @@ static void _get_group_size(const struct _lv_svg_render_obj * obj, uint32_t * si *size += lv_array_capacity(&group->items) * sizeof(void *); } -// destroy functions +/* destroy functions */ static void _destroy_poly(lv_svg_render_obj_t * obj) { lv_svg_render_poly_t * poly = (lv_svg_render_poly_t *)obj; @@ -2055,11 +2157,12 @@ static lv_svg_render_class svg_use_class = { .set_attr = _set_use_attr, .render = _render_use, .destroy = _destroy_use, + .get_bounds = _get_use_bounds, .get_size = _get_use_size, }; static lv_svg_render_class svg_solid_class = { - .init = _init_obj, + .init = _init_solid, .set_attr = _set_solid_attr, .set_paint_ref = _set_solid_ref, .get_size = _get_solid_size, @@ -2077,6 +2180,7 @@ static lv_svg_render_class svg_group_class = { .set_attr = _set_attr, .render = _render_group, .destroy = _destroy_group, + .get_bounds = _get_group_bounds, .get_size = _get_group_size, }; @@ -2194,7 +2298,7 @@ static lv_svg_render_obj_t * _lv_svg_render_create(const lv_svg_node_t * node, if(node->type == LV_SVG_TAG_LINEAR_GRADIENT) { grad->dsc.style = LV_VECTOR_GRADIENT_STYLE_LINEAR; } - else { // radial gradient + else { /* radial gradient */ grad->dsc.style = LV_VECTOR_GRADIENT_STYLE_RADIAL; } _set_render_attrs(LV_SVG_RENDER_OBJ(grad), node, state); @@ -2289,7 +2393,7 @@ static void _lv_svg_doc_walk_after_cb(const lv_tree_node_t * node, void * data) uint32_t count = LV_TREE_NODE(node)->child_cnt; for(uint32_t i = 0; i < count; i++) { lv_svg_node_t * child = LV_SVG_NODE_CHILD(node, i); - if(child->render_obj) { // not defs + if(child->render_obj) { /* not defs */ lv_array_push_back(&group->items, (uint8_t *)(&child->render_obj)); } } @@ -2450,7 +2554,7 @@ lv_result_t lv_svg_render_get_viewport_size(const lv_svg_render_obj_t * render, return LV_RESULT_OK; } -void lv_draw_svg_render(lv_vector_dsc_t * dsc, const lv_svg_render_obj_t * render) +void lv_draw_svg_render(lv_draw_vector_dsc_t * dsc, const lv_svg_render_obj_t * render) { if(!render || !dsc) { return; @@ -2472,12 +2576,12 @@ void lv_draw_svg(lv_layer_t * layer, const lv_svg_node_t * svg_doc) return; } - lv_vector_dsc_t * dsc = lv_vector_dsc_create(layer); + lv_draw_vector_dsc_t * dsc = lv_draw_vector_dsc_create(layer); lv_svg_render_obj_t * list = lv_svg_render_create(svg_doc); lv_draw_svg_render(dsc, list); lv_draw_vector(dsc); lv_svg_render_delete(list); - lv_vector_dsc_delete(dsc); + lv_draw_vector_dsc_delete(dsc); } /********************** diff --git a/src/libs/svg/lv_svg_render.h b/src/libs/svg/lv_svg_render.h index d2e87860c0..e2578bf54f 100644 --- a/src/libs/svg/lv_svg_render.h +++ b/src/libs/svg/lv_svg_render.h @@ -36,7 +36,7 @@ typedef struct _lv_svg_render_obj { lv_svg_tag_t tag; uint32_t flags; char * id; - lv_vector_draw_dsc_t dsc; + lv_vector_path_ctx_t dsc; lv_matrix_t matrix; /* for url(XXX) reference */ @@ -47,12 +47,12 @@ typedef struct _lv_svg_render_obj { } lv_svg_render_obj_t; typedef struct _lv_svg_render_class { - void (*set_paint_ref)(struct _lv_svg_render_obj * obj, lv_vector_draw_dsc_t * dsc, + void (*set_paint_ref)(struct _lv_svg_render_obj * obj, lv_vector_path_ctx_t * dsc, const struct _lv_svg_render_obj * target_obj, bool fill); void (*init)(struct _lv_svg_render_obj * obj, const lv_svg_node_t * node); - void (*render)(const struct _lv_svg_render_obj * obj, lv_vector_dsc_t * dsc, const lv_matrix_t * matrix); - void (*set_attr)(struct _lv_svg_render_obj * obj, lv_vector_draw_dsc_t * dsc, const lv_svg_attr_t * attr); + void (*render)(const struct _lv_svg_render_obj * obj, lv_draw_vector_dsc_t * dsc, const lv_matrix_t * matrix); + void (*set_attr)(struct _lv_svg_render_obj * obj, lv_vector_path_ctx_t * dsc, const lv_svg_attr_t * attr); void (*get_bounds)(const struct _lv_svg_render_obj * obj, lv_area_t * area); void (*get_size)(const struct _lv_svg_render_obj * obj, uint32_t * size); void (*destroy)(struct _lv_svg_render_obj * obj); @@ -107,7 +107,7 @@ lv_result_t lv_svg_render_get_viewport_size(const lv_svg_render_obj_t * render, * @param dsc pointer to the vector graphics descriptor * @param render pointer to the SVG render object to render */ -void lv_draw_svg_render(lv_vector_dsc_t * dsc, const lv_svg_render_obj_t * render); +void lv_draw_svg_render(lv_draw_vector_dsc_t * dsc, const lv_svg_render_obj_t * render); /** * @brief Draw an SVG document to a layer diff --git a/src/libs/thorvg/tvgInitializer.cpp b/src/libs/thorvg/tvgInitializer.cpp index 7ac779c30d..a770c34c3e 100644 --- a/src/libs/thorvg/tvgInitializer.cpp +++ b/src/libs/thorvg/tvgInitializer.cpp @@ -74,7 +74,7 @@ static bool _buildVersionInfo(uint32_t* major, uint32_t* minor, uint32_t* micro) uint32_t microVal = atoi(p); char sum[7]; - snprintf(sum, sizeof(sum), "%d%02d%02d", majorVal, minorVal, microVal); + snprintf(sum, sizeof(sum), "%" PRIu32 "%02" PRIu32 "%02" PRIu32, majorVal, minorVal, microVal); _version = atoi(sum); if (major) *major = majorVal; diff --git a/src/libs/thorvg/tvgLottieBuilder.cpp b/src/libs/thorvg/tvgLottieBuilder.cpp index fc86e85072..3ed21f4fa0 100644 --- a/src/libs/thorvg/tvgLottieBuilder.cpp +++ b/src/libs/thorvg/tvgLottieBuilder.cpp @@ -48,8 +48,8 @@ static void _rotationXYZ(Matrix* m, float degreeX, float degreeY, float degreeZ) auto radianZ = deg2rad(degreeZ); auto cx = cosf(radianX), sx = sinf(radianX); - auto cy = cosf(radianY), sy = sinf(radianY);; - auto cz = cosf(radianZ), sz = sinf(radianZ);; + auto cy = cosf(radianY), sy = sinf(radianY); + auto cz = cosf(radianZ), sz = sinf(radianZ); m->e11 = cy * cz; m->e12 = -cy * sz; m->e21 = sx * sy * cz + cx * sz; diff --git a/src/libs/thorvg/tvgLottieModifier.cpp b/src/libs/thorvg/tvgLottieModifier.cpp index 5cf714a598..e4efae2ade 100644 --- a/src/libs/thorvg/tvgLottieModifier.cpp +++ b/src/libs/thorvg/tvgLottieModifier.cpp @@ -93,7 +93,7 @@ static bool _clockwise(const Point* pts, uint32_t n) for (uint32_t i = 0; i < n - 1; i++) { area += cross(pts[i], pts[i + 1]); } - area += cross(pts[n - 1], pts[0]);; + area += cross(pts[n - 1], pts[0]); return area < 0.0f; } diff --git a/src/libs/thorvg/tvgRender.h b/src/libs/thorvg/tvgRender.h index 3ec16ab4fd..dc18635923 100644 --- a/src/libs/thorvg/tvgRender.h +++ b/src/libs/thorvg/tvgRender.h @@ -263,7 +263,7 @@ struct RenderShape float strokeMiterlimit() const { if (!stroke) return 4.0f; - return stroke->miterlimit;; + return stroke->miterlimit; } }; diff --git a/src/libs/thorvg/tvgSvgLoader.cpp b/src/libs/thorvg/tvgSvgLoader.cpp index 6cab7084b8..0ab6870507 100644 --- a/src/libs/thorvg/tvgSvgLoader.cpp +++ b/src/libs/thorvg/tvgSvgLoader.cpp @@ -3756,7 +3756,7 @@ static bool _svgLoaderParserForValidCheckXmlOpen(SvgLoaderData* loader, const ch static bool _svgLoaderParserForValidCheck(void* data, SimpleXMLType type, const char* content, unsigned int length) { SvgLoaderData* loader = (SvgLoaderData*)data; - bool res = true;; + bool res = true; switch (type) { case SimpleXMLType::Open: diff --git a/src/libs/thorvg/tvgSvgSceneBuilder.cpp b/src/libs/thorvg/tvgSvgSceneBuilder.cpp index 4de08ee502..9fe2d07d21 100644 --- a/src/libs/thorvg/tvgSvgSceneBuilder.cpp +++ b/src/libs/thorvg/tvgSvgSceneBuilder.cpp @@ -733,7 +733,7 @@ static unique_ptr _useBuildHelper(SvgLoaderData& loaderData, const SvgNod auto width = (symbol.hasWidth ? symbol.w : vBox.w); if (node->node.use.isWidthSet) width = node->node.use.w; - auto height = (symbol.hasHeight ? symbol.h : vBox.h);; + auto height = (symbol.hasHeight ? symbol.h : vBox.h); if (node->node.use.isHeightSet) height = node->node.use.h; auto vw = (symbol.hasViewBox ? symbol.vw : width); auto vh = (symbol.hasViewBox ? symbol.vh : height); diff --git a/src/libs/thorvg/tvgSwRenderer.cpp b/src/libs/thorvg/tvgSwRenderer.cpp index 5b812d7f12..1733a1195f 100644 --- a/src/libs/thorvg/tvgSwRenderer.cpp +++ b/src/libs/thorvg/tvgSwRenderer.cpp @@ -88,7 +88,7 @@ struct SwShapeTask : SwTask Additionally, the stroke style should not be dashed. */ bool antialiasing(float strokeWidth) { - return strokeWidth < 2.0f || rshape->stroke->dashCnt > 0 || rshape->stroke->strokeFirst || rshape->strokeTrim() || rshape->stroke->color[3] < 255;; + return strokeWidth < 2.0f || rshape->stroke->dashCnt > 0 || rshape->stroke->strokeFirst || rshape->strokeTrim() || rshape->stroke->color[3] < 255; } float validStrokeWidth() diff --git a/src/libs/tiny_ttf/lv_tiny_ttf.c b/src/libs/tiny_ttf/lv_tiny_ttf.c index 55ddd69c3f..c5df323aea 100644 --- a/src/libs/tiny_ttf/lv_tiny_ttf.c +++ b/src/libs/tiny_ttf/lv_tiny_ttf.c @@ -392,7 +392,7 @@ static void ttf_release_glyph_cb(const lv_font_t * font, lv_font_glyph_dsc_t * g ttf_font_desc_t * dsc = (ttf_font_desc_t *)font->dsc; if(!dsc->cache_size) { /* no cache, do everything directly */ - lv_draw_buf_destroy_user(font_draw_buf_handlers, (lv_draw_buf_t *)g_dsc->entry); + lv_draw_buf_destroy((lv_draw_buf_t *)g_dsc->entry); } else { if(g_dsc->entry == NULL) { diff --git a/src/libs/tjpgd/lv_tjpgd.c b/src/libs/tjpgd/lv_tjpgd.c index 650b36ad63..7872ea1e4e 100644 --- a/src/libs/tjpgd/lv_tjpgd.c +++ b/src/libs/tjpgd/lv_tjpgd.c @@ -153,13 +153,15 @@ static size_t input_func(JDEC * jd, uint8_t * buff, size_t ndata) static lv_result_t decoder_open(lv_image_decoder_t * decoder, lv_image_decoder_dsc_t * dsc) { LV_UNUSED(decoder); - lv_fs_file_t * f = lv_malloc(sizeof(lv_fs_file_t)); + lv_fs_file_t * f = NULL; if(dsc->src_type == LV_IMAGE_SRC_VARIABLE) { #if LV_USE_FS_MEMFS const lv_image_dsc_t * img_dsc = dsc->src; if(is_jpg(img_dsc->data, img_dsc->data_size) == true) { + f = lv_malloc(sizeof(lv_fs_file_t)); + if(f == NULL) return LV_RESULT_INVALID; lv_fs_path_ex_t path; - lv_fs_make_path_from_buffer(&path, LV_FS_MEMFS_LETTER, img_dsc->data, img_dsc->data_size); + lv_fs_make_path_from_buffer(&path, LV_FS_MEMFS_LETTER, img_dsc->data, img_dsc->data_size, "bin"); lv_fs_res_t res; res = lv_fs_open(f, (const char *)&path, LV_FS_MODE_RD); if(res != LV_FS_RES_OK) { @@ -169,12 +171,13 @@ static lv_result_t decoder_open(lv_image_decoder_t * decoder, lv_image_decoder_d } #else LV_LOG_WARN("LV_USE_FS_MEMFS needs to enabled to decode from data"); - return LV_RESULT_INVALID; #endif } else if(dsc->src_type == LV_IMAGE_SRC_FILE) { const char * fn = dsc->src; if((lv_strcmp(lv_fs_get_ext(fn), "jpg") == 0) || (lv_strcmp(lv_fs_get_ext(fn), "jpeg") == 0)) { + f = lv_malloc(sizeof(lv_fs_file_t)); + if(f == NULL) return LV_RESULT_INVALID; lv_fs_res_t res; res = lv_fs_open(f, fn, LV_FS_MODE_RD); if(res != LV_FS_RES_OK) { @@ -183,24 +186,29 @@ static lv_result_t decoder_open(lv_image_decoder_t * decoder, lv_image_decoder_d } } } + if(f == NULL) return LV_RESULT_INVALID; uint8_t * workb_temp = lv_malloc(TJPGD_WORKBUFF_SIZE); JDEC * jd = lv_malloc(sizeof(JDEC)); - dsc->user_data = jd; - JRESULT rc = jd_prepare(jd, input_func, workb_temp, (size_t)TJPGD_WORKBUFF_SIZE, f); - if(rc) return LV_RESULT_INVALID; + JRESULT rc = JDR_MEM1; - dsc->header.cf = LV_COLOR_FORMAT_RGB888; - dsc->header.w = jd->width; - dsc->header.h = jd->height; - dsc->header.stride = jd->width * 3; + if(workb_temp != NULL && jd != NULL) + rc = jd_prepare(jd, input_func, workb_temp, (size_t)TJPGD_WORKBUFF_SIZE, f); if(rc != JDR_OK) { + lv_fs_close(f); + lv_free(f); lv_free(workb_temp); lv_free(jd); return LV_RESULT_INVALID; } + dsc->user_data = jd; + dsc->header.cf = LV_COLOR_FORMAT_RGB888; + dsc->header.w = jd->width; + dsc->header.h = jd->height; + dsc->header.stride = jd->width * 3; + return LV_RESULT_OK; } diff --git a/src/libs/vg_lite_driver/LICENSE.txt b/src/libs/vg_lite_driver/LICENSE.txt new file mode 100755 index 0000000000..baef4d794b --- /dev/null +++ b/src/libs/vg_lite_driver/LICENSE.txt @@ -0,0 +1,26 @@ +**************************************************************************** +* +* Copyright 2012 - 2023 Vivante Corporation, Santa Clara, California. +* All Rights Reserved. +* +* Permission is hereby granted, free of charge, to any person obtaining +* a copy of this software and associated documentation files (the +* 'Software'), to deal in the Software without restriction, including +* without limitation the rights to use, copy, modify, merge, publish, +* distribute, sub license, and/or sell copies of the Software, and to +* permit persons to whom the Software is furnished to do so, subject +* to the following conditions: +* +* The above copyright notice and this permission notice (including the +* next paragraph) shall be included in all copies or substantial +* portions of the Software. +* +* THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND, +* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. +* IN NO EVENT SHALL VIVANTE AND/OR ITS SUPPLIERS BE LIABLE FOR ANY +* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, +* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE +* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +* +**************************************************************************** diff --git a/src/libs/vg_lite_driver/VGLite/Series/gc255/0x40A/vg_lite_options.h b/src/libs/vg_lite_driver/VGLite/Series/gc255/0x40A/vg_lite_options.h new file mode 100755 index 0000000000..11ee09a160 --- /dev/null +++ b/src/libs/vg_lite_driver/VGLite/Series/gc255/0x40A/vg_lite_options.h @@ -0,0 +1,113 @@ +/**************************************************************************** +* +* Copyright 2012 - 2023 Vivante Corporation, Santa Clara, California. +* All Rights Reserved. +* +* Permission is hereby granted, free of charge, to any person obtaining +* a copy of this software and associated documentation files (the +* 'Software'), to deal in the Software without restriction, including +* without limitation the rights to use, copy, modify, merge, publish, +* distribute, sub license, and/or sell copies of the Software, and to +* permit persons to whom the Software is furnished to do so, subject +* to the following conditions: +* +* The above copyright notice and this permission notice (including the +* next paragraph) shall be included in all copies or substantial +* portions of the Software. +* +* THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND, +* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. +* IN NO EVENT SHALL VIVANTE AND/OR ITS SUPPLIERS BE LIABLE FOR ANY +* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, +* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE +* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +* +*****************************************************************************/ + +#ifndef VG_LITE_OPTIONS_H +#define VG_LITE_OPTIONS_H + +#include "../../../../../../lv_conf_internal.h" +#if LV_USE_VG_LITE_DRIVER + + #define CHIPID 0x255 + #define REVISION 0x1311 + #define CID 0x40A + #define ECOID 0x1 + + #define gcFEATURE_VG_IM_INDEX_FORMAT 1 + #define gcFEATURE_VG_SCISSOR 1 + #define gcFEATURE_VG_BORDER_CULLING 1 + #define gcFEATURE_VG_RGBA2_FORMAT 1 + #define gcFEATURE_VG_QUALITY_8X 1 + #define gcFEATURE_VG_IM_FASTCLEAR 0 + #define gcFEATURE_VG_RADIAL_GRADIENT 0 + #define gcFEATURE_VG_GLOBAL_ALPHA 0 + #define gcFEATURE_VG_RGBA8_ETC2_EAC 0 + #define gcFEATURE_VG_COLOR_KEY 0 + #define gcFEATURE_VG_DOUBLE_IMAGE 0 + #define gcFEATURE_VG_YUV_OUTPUT 0 + #define gcFEATURE_VG_FLEXA 0 + #define gcFEATURE_VG_24BIT 0 + #define gcFEATURE_VG_DITHER 0 + #define gcFEATURE_VG_USE_DST 0 + #define gcFEATURE_VG_PE_CLEAR 0 + #define gcFEATURE_VG_IM_INPUT 1 + #define gcFEATURE_VG_DEC_COMPRESS 0 + #define gcFEATURE_VG_LINEAR_GRADIENT_EXT 0 + #define gcFEATURE_VG_MASK 0 + #define gcFEATURE_VG_MIRROR 0 + #define gcFEATURE_VG_GAMMA 0 + #define gcFEATURE_VG_NEW_BLEND_MODE 0 + #define gcFEATURE_VG_STENCIL 0 + #define gcFEATURE_VG_SRC_PREMULTIPLIED 1 + #define gcFEATURE_VG_HW_PREMULTIPLY 0 + #define gcFEATURE_VG_COLOR_TRANSFORMATION 0 + #define gcFEATURE_VG_LVGL_SUPPORT 0 + #define gcFEATURE_VG_INDEX_ENDIAN 0 + #define gcFEATURE_VG_24BIT_PLANAR 0 + #define gcFEATURE_VG_PIXEL_MATRIX 0 + #define gcFEATURE_VG_NEW_IMAGE_INDEX 0 + #define gcFEATURE_VG_PARALLEL_PATHS 0 + #define gcFEATURE_VG_STRIPE_MODE 1 + #define gcFEATURE_VG_IM_DEC_INPUT 0 + #define gcFEATURE_VG_GAUSSIAN_BLUR 0 + #define gcFEATURE_VG_RECTANGLE_TILED_OUT 0 + #define gcFEATURE_VG_TESSELLATION_TILED_OUT 0 + #define gcFEATURE_VG_IM_REPEAT_REFLECT 0 + #define gcFEATURE_VG_YUY2_INPUT 1 + #define gcFEATURE_VG_YUV_INPUT 0 + #define gcFEATURE_VG_YUV_TILED_INPUT 0 + #define gcFEATURE_VG_AYUV_INPUT 0 + #define gcFEATURE_VG_16PIXELS_ALIGNED 1 + #define gcFEATURE_VG_DEC_COMPRESS_2_0 0 + #define gcFEATURE_VG_NV24_INPUT 0 + #define gcFEATURE_VG_TILED_LIMIT 0 + #define gcFEATURE_VG_SRC_ADDRESS_16BYTES_ALIGNED 0 + #define gcFEATURE_VG_SRC_ADDRESS_64BYTES_ALIGNED 0 + #define gcFEATURE_VG_SRC_TILE_4PIXELS_ALIGNED 0 + #define gcFEATURE_VG_SRC_BUF_ALINGED 0 + #define gcFEATURE_VG_DST_ADDRESS_64BYTES_ALIGNED 0 + #define gcFEATURE_VG_DST_TILE_4PIXELS_ALIGNED 0 + #define gcFEATURE_VG_DST_BUF_ALIGNED 0 + #define gcFEATURE_VG_DST_24BIT_PLANAR_ALIGNED 0 + #define gcFEATURE_VG_DST_BUFLEN_ALIGNED 0 + #define gcFEATURE_VG_FORMAT_SUPPORT_CHECK 0 + #define gcFEATURE_VG_YUV_ALIGNED_CHECK 0 + #define gcFEATURE_VG_512_PARALLEL_PATHS 1 + #define gcFEATURE_VG_CLOCK_GATING_TS_MODULE 1 + #define gcFEATURE_VG_CLOCK_GATING_VG_MODULE 1 + + /* SW Features */ + #define gcFEATURE_VG_STROKE_PATH 1 + #define gcFEATURE_VG_ARC_PATH 1 + #define gcFEATURE_VG_ERROR_CHECK 1 + #define gcFEATURE_VG_TRACE_API 0 + #define gcFEATURE_VG_POWER_MANAGEMENT 0 + #define gcFEATURE_VG_TILED_MODE 1 + #define gcFEATURE_VG_SINGLE_COMMAND_BUFFER 0 + +#endif /* LV_USE_VG_LITE_DRIVER */ + +#endif /* VG_LITE_OPTIONS_H */ diff --git a/src/libs/vg_lite_driver/VGLite/Series/gc355/0x0_1215/vg_lite_options.h b/src/libs/vg_lite_driver/VGLite/Series/gc355/0x0_1215/vg_lite_options.h new file mode 100755 index 0000000000..80a545b507 --- /dev/null +++ b/src/libs/vg_lite_driver/VGLite/Series/gc355/0x0_1215/vg_lite_options.h @@ -0,0 +1,117 @@ +/**************************************************************************** +* +* Copyright 2012 - 2023 Vivante Corporation, Santa Clara, California. +* All Rights Reserved. +* +* Permission is hereby granted, free of charge, to any person obtaining +* a copy of this software and associated documentation files (the +* 'Software'), to deal in the Software without restriction, including +* without limitation the rights to use, copy, modify, merge, publish, +* distribute, sub license, and/or sell copies of the Software, and to +* permit persons to whom the Software is furnished to do so, subject +* to the following conditions: +* +* The above copyright notice and this permission notice (including the +* next paragraph) shall be included in all copies or substantial +* portions of the Software. +* +* THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND, +* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. +* IN NO EVENT SHALL VIVANTE AND/OR ITS SUPPLIERS BE LIABLE FOR ANY +* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, +* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE +* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +* +*****************************************************************************/ + +#ifndef VG_LITE_OPTIONS_H +#define VG_LITE_OPTIONS_H + +#include "../../../../../../lv_conf_internal.h" +#if LV_USE_VG_LITE_DRIVER + + #define CHIPID 0x355 + #define REVISION 0x1215 + #define CID 0x0 + #define ECOID 0x0 + + #define gcFEATURE_VG_IM_INDEX_FORMAT 0 + #define gcFEATURE_VG_SCISSOR 1 + #define gcFEATURE_VG_BORDER_CULLING 0 + #define gcFEATURE_VG_RGBA2_FORMAT 0 + #define gcFEATURE_VG_QUALITY_8X 0 + #define gcFEATURE_VG_IM_FASTCLEAR 0 + #define gcFEATURE_VG_RADIAL_GRADIENT 1 + #define gcFEATURE_VG_GLOBAL_ALPHA 0 + #define gcFEATURE_VG_RGBA8_ETC2_EAC 0 + #define gcFEATURE_VG_COLOR_KEY 1 + #define gcFEATURE_VG_DOUBLE_IMAGE 0 + #define gcFEATURE_VG_YUV_OUTPUT 0 + #define gcFEATURE_VG_FLEXA 0 + #define gcFEATURE_VG_24BIT 0 + #define gcFEATURE_VG_DITHER 1 + #define gcFEATURE_VG_USE_DST 0 + #define gcFEATURE_VG_PE_CLEAR 0 + #define gcFEATURE_VG_IM_INPUT 1 + #define gcFEATURE_VG_DEC_COMPRESS 0 + #define gcFEATURE_VG_LINEAR_GRADIENT_EXT 1 + #define gcFEATURE_VG_MASK 1 + #define gcFEATURE_VG_MIRROR 1 + #define gcFEATURE_VG_GAMMA 1 + #define gcFEATURE_VG_NEW_BLEND_MODE 0 + #define gcFEATURE_VG_STENCIL 1 + #define gcFEATURE_VG_SRC_PREMULTIPLIED 0 + #define gcFEATURE_VG_HW_PREMULTIPLY 1 + #define gcFEATURE_VG_COLOR_TRANSFORMATION 1 + #define gcFEATURE_VG_LVGL_SUPPORT 0 + #define gcFEATURE_VG_INDEX_ENDIAN 0 + #define gcFEATURE_VG_24BIT_PLANAR 0 + #define gcFEATURE_VG_PIXEL_MATRIX 0 + #define gcFEATURE_VG_NEW_IMAGE_INDEX 0 + #define gcFEATURE_VG_PARALLEL_PATHS 0 + #define gcFEATURE_VG_STRIPE_MODE 1 + #define gcFEATURE_VG_IM_DEC_INPUT 0 + #define gcFEATURE_VG_GAUSSIAN_BLUR 0 + #define gcFEATURE_VG_RECTANGLE_TILED_OUT 0 + #define gcFEATURE_VG_TESSELLATION_TILED_OUT 0 + #define gcFEATURE_VG_IM_REPEAT_REFLECT 1 + #define gcFEATURE_VG_YUY2_INPUT 0 + #define gcFEATURE_VG_YUV_INPUT 0 + #define gcFEATURE_VG_YUV_TILED_INPUT 0 + #define gcFEATURE_VG_AYUV_INPUT 0 + #define gcFEATURE_VG_16PIXELS_ALIGNED 1 + #define gcFEATURE_VG_DEC_COMPRESS_2_0 0 + #define gcFEATURE_VG_NV24_INPUT 0 + #define gcFEATURE_VG_TILED_LIMIT 0 + #define gcFEATURE_VG_SRC_ADDRESS_16BYTES_ALIGNED 0 + #define gcFEATURE_VG_SRC_ADDRESS_64BYTES_ALIGNED 0 + #define gcFEATURE_VG_SRC_TILE_4PIXELS_ALIGNED 0 + #define gcFEATURE_VG_SRC_BUF_ALINGED 0 + #define gcFEATURE_VG_DST_ADDRESS_64BYTES_ALIGNED 0 + #define gcFEATURE_VG_DST_TILE_4PIXELS_ALIGNED 0 + #define gcFEATURE_VG_DST_BUF_ALIGNED 0 + #define gcFEATURE_VG_DST_24BIT_PLANAR_ALIGNED 0 + #define gcFEATURE_VG_DST_BUFLEN_ALIGNED 0 + #define gcFEATURE_VG_FORMAT_SUPPORT_CHECK 0 + #define gcFEATURE_VG_YUV_ALIGNED_CHECK 0 + #define gcFEATURE_VG_512_PARALLEL_PATHS 1 + #define gcFEATURE_VG_CLOCK_GATING_TS_MODULE 1 + #define gcFEATURE_VG_CLOCK_GATING_VG_MODULE 1 + + /* SW Features */ + #define gcFEATURE_VG_STROKE_PATH 1 + #define gcFEATURE_VG_ARC_PATH 1 + #define gcFEATURE_VG_ERROR_CHECK 1 + #define gcFEATURE_VG_TRACE_API 0 + #define gcFEATURE_VG_POWER_MANAGEMENT 0 + #define gcFEATURE_VG_TILED_MODE 1 + #define gcFEATURE_VG_SINGLE_COMMAND_BUFFER 0 + + /*** + #define gcFEATURE_VG_RESOLUTION_8K 1 + #define gcFEATURE_VG_IMAGE_16K 0 + ***/ +#endif /* LV_USE_VG_LITE_DRIVER */ + +#endif /* VG_LITE_OPTIONS_H */ diff --git a/src/libs/vg_lite_driver/VGLite/Series/gc355/0x0_1216/vg_lite_options.h b/src/libs/vg_lite_driver/VGLite/Series/gc355/0x0_1216/vg_lite_options.h new file mode 100755 index 0000000000..8322499372 --- /dev/null +++ b/src/libs/vg_lite_driver/VGLite/Series/gc355/0x0_1216/vg_lite_options.h @@ -0,0 +1,117 @@ +/**************************************************************************** +* +* Copyright 2012 - 2023 Vivante Corporation, Santa Clara, California. +* All Rights Reserved. +* +* Permission is hereby granted, free of charge, to any person obtaining +* a copy of this software and associated documentation files (the +* 'Software'), to deal in the Software without restriction, including +* without limitation the rights to use, copy, modify, merge, publish, +* distribute, sub license, and/or sell copies of the Software, and to +* permit persons to whom the Software is furnished to do so, subject +* to the following conditions: +* +* The above copyright notice and this permission notice (including the +* next paragraph) shall be included in all copies or substantial +* portions of the Software. +* +* THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND, +* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. +* IN NO EVENT SHALL VIVANTE AND/OR ITS SUPPLIERS BE LIABLE FOR ANY +* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, +* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE +* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +* +*****************************************************************************/ +#ifndef VG_LITE_OPTIONS_H +#define VG_LITE_OPTIONS_H + +#include "../../../../../../lv_conf_internal.h" +#if LV_USE_VG_LITE_DRIVER + + #define CHIPID 0x355 + #define REVISION 0x1216 + #define CID 0x0 + #define ECOID 0x0 + + #define gcFEATURE_VG_IM_INDEX_FORMAT 0 + #define gcFEATURE_VG_SCISSOR 1 + #define gcFEATURE_VG_BORDER_CULLING 0 + #define gcFEATURE_VG_RGBA2_FORMAT 0 + #define gcFEATURE_VG_QUALITY_8X 0 + #define gcFEATURE_VG_IM_FASTCLEAR 0 + #define gcFEATURE_VG_RADIAL_GRADIENT 1 + #define gcFEATURE_VG_GLOBAL_ALPHA 0 + #define gcFEATURE_VG_RGBA8_ETC2_EAC 0 + #define gcFEATURE_VG_COLOR_KEY 1 + #define gcFEATURE_VG_DOUBLE_IMAGE 0 + #define gcFEATURE_VG_YUV_OUTPUT 0 + #define gcFEATURE_VG_FLEXA 0 + #define gcFEATURE_VG_24BIT 0 + #define gcFEATURE_VG_DITHER 1 + #define gcFEATURE_VG_USE_DST 0 + #define gcFEATURE_VG_PE_CLEAR 0 + #define gcFEATURE_VG_IM_INPUT 1 + #define gcFEATURE_VG_DEC_COMPRESS 0 + #define gcFEATURE_VG_LINEAR_GRADIENT_EXT 1 + #define gcFEATURE_VG_MASK 1 + #define gcFEATURE_VG_MIRROR 1 + #define gcFEATURE_VG_GAMMA 1 + #define gcFEATURE_VG_NEW_BLEND_MODE 0 + #define gcFEATURE_VG_STENCIL 1 + #define gcFEATURE_VG_SRC_PREMULTIPLIED 0 + #define gcFEATURE_VG_HW_PREMULTIPLY 1 + #define gcFEATURE_VG_COLOR_TRANSFORMATION 1 + #define gcFEATURE_VG_LVGL_SUPPORT 0 + #define gcFEATURE_VG_INDEX_ENDIAN 0 + #define gcFEATURE_VG_24BIT_PLANAR 0 + #define gcFEATURE_VG_PIXEL_MATRIX 0 + #define gcFEATURE_VG_NEW_IMAGE_INDEX 0 + #define gcFEATURE_VG_PARALLEL_PATHS 0 + #define gcFEATURE_VG_STRIPE_MODE 1 + #define gcFEATURE_VG_IM_DEC_INPUT 0 + #define gcFEATURE_VG_GAUSSIAN_BLUR 0 + #define gcFEATURE_VG_RECTANGLE_TILED_OUT 0 + #define gcFEATURE_VG_TESSELLATION_TILED_OUT 0 + #define gcFEATURE_VG_IM_REPEAT_REFLECT 1 + #define gcFEATURE_VG_YUY2_INPUT 0 + #define gcFEATURE_VG_YUV_INPUT 0 + #define gcFEATURE_VG_YUV_TILED_INPUT 0 + #define gcFEATURE_VG_AYUV_INPUT 0 + #define gcFEATURE_VG_16PIXELS_ALIGNED 1 + #define gcFEATURE_VG_DEC_COMPRESS_2_0 0 + #define gcFEATURE_VG_NV24_INPUT 0 + #define gcFEATURE_VG_TILED_LIMIT 0 + #define gcFEATURE_VG_SRC_ADDRESS_16BYTES_ALIGNED 0 + #define gcFEATURE_VG_SRC_ADDRESS_64BYTES_ALIGNED 0 + #define gcFEATURE_VG_SRC_TILE_4PIXELS_ALIGNED 0 + #define gcFEATURE_VG_SRC_BUF_ALINGED 0 + #define gcFEATURE_VG_DST_ADDRESS_64BYTES_ALIGNED 0 + #define gcFEATURE_VG_DST_TILE_4PIXELS_ALIGNED 0 + #define gcFEATURE_VG_DST_BUF_ALIGNED 0 + #define gcFEATURE_VG_DST_24BIT_PLANAR_ALIGNED 0 + #define gcFEATURE_VG_DST_BUFLEN_ALIGNED 0 + #define gcFEATURE_VG_FORMAT_SUPPORT_CHECK 0 + #define gcFEATURE_VG_YUV_ALIGNED_CHECK 0 + #define gcFEATURE_VG_512_PARALLEL_PATHS 1 + #define gcFEATURE_VG_CLOCK_GATING_TS_MODULE 1 + #define gcFEATURE_VG_CLOCK_GATING_VG_MODULE 1 + + /* SW Features */ + #define gcFEATURE_VG_STROKE_PATH 1 + #define gcFEATURE_VG_ARC_PATH 1 + #define gcFEATURE_VG_ERROR_CHECK 1 + #define gcFEATURE_VG_TRACE_API 0 + #define gcFEATURE_VG_POWER_MANAGEMENT 0 + #define gcFEATURE_VG_TILED_MODE 1 + #define gcFEATURE_VG_SINGLE_COMMAND_BUFFER 0 + + /*** + #define gcFEATURE_VG_RESOLUTION_8K 1 + #define gcFEATURE_VG_IMAGE_16K 0 + ***/ + +#endif /* LV_USE_VG_LITE_DRIVER */ + +#endif /* VG_LITE_OPTIONS_H */ diff --git a/src/libs/vg_lite_driver/VGLite/Series/gc555/0x423/vg_lite_options.h b/src/libs/vg_lite_driver/VGLite/Series/gc555/0x423/vg_lite_options.h new file mode 100755 index 0000000000..e6663f2a30 --- /dev/null +++ b/src/libs/vg_lite_driver/VGLite/Series/gc555/0x423/vg_lite_options.h @@ -0,0 +1,115 @@ +/**************************************************************************** +* +* Copyright 2012 - 2023 Vivante Corporation, Santa Clara, California. +* All Rights Reserved. +* +* Permission is hereby granted, free of charge, to any person obtaining +* a copy of this software and associated documentation files (the +* 'Software'), to deal in the Software without restriction, including +* without limitation the rights to use, copy, modify, merge, publish, +* distribute, sub license, and/or sell copies of the Software, and to +* permit persons to whom the Software is furnished to do so, subject +* to the following conditions: +* +* The above copyright notice and this permission notice (including the +* next paragraph) shall be included in all copies or substantial +* portions of the Software. +* +* THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND, +* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. +* IN NO EVENT SHALL VIVANTE AND/OR ITS SUPPLIERS BE LIABLE FOR ANY +* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, +* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE +* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +* +*****************************************************************************/ + +#ifndef VG_LITE_OPTIONS_H +#define VG_LITE_OPTIONS_H + +#include "../../../../../../lv_conf_internal.h" +#if LV_USE_VG_LITE_DRIVER + + #define CHIPID 0x555 + #define REVISION 0x1230 + #define CID 0x423 + #define ECOID 0x0 + + #define gcFEATURE_VG_IM_INDEX_FORMAT 1 + #define gcFEATURE_VG_SCISSOR 1 + #define gcFEATURE_VG_BORDER_CULLING 1 + #define gcFEATURE_VG_RGBA2_FORMAT 1 + #define gcFEATURE_VG_QUALITY_8X 0 + #define gcFEATURE_VG_IM_FASTCLEAR 0 + #define gcFEATURE_VG_RADIAL_GRADIENT 1 + #define gcFEATURE_VG_GLOBAL_ALPHA 1 + #define gcFEATURE_VG_RGBA8_ETC2_EAC 1 + #define gcFEATURE_VG_COLOR_KEY 1 + #define gcFEATURE_VG_DOUBLE_IMAGE 0 + #define gcFEATURE_VG_YUV_OUTPUT 0 + #define gcFEATURE_VG_FLEXA 0 + #define gcFEATURE_VG_24BIT 1 + #define gcFEATURE_VG_DITHER 1 + #define gcFEATURE_VG_USE_DST 0 + #define gcFEATURE_VG_PE_CLEAR 1 + #define gcFEATURE_VG_IM_INPUT 1 + #define gcFEATURE_VG_DEC_COMPRESS 1 + #define gcFEATURE_VG_LINEAR_GRADIENT_EXT 1 + #define gcFEATURE_VG_MASK 1 + #define gcFEATURE_VG_MIRROR 1 + #define gcFEATURE_VG_GAMMA 1 + #define gcFEATURE_VG_NEW_BLEND_MODE 1 + #define gcFEATURE_VG_STENCIL 1 + #define gcFEATURE_VG_SRC_PREMULTIPLIED 0 + #define gcFEATURE_VG_HW_PREMULTIPLY 1 + #define gcFEATURE_VG_COLOR_TRANSFORMATION 1 + #define gcFEATURE_VG_LVGL_SUPPORT 1 + #define gcFEATURE_VG_INDEX_ENDIAN 0 + #define gcFEATURE_VG_24BIT_PLANAR 0 + #define gcFEATURE_VG_PIXEL_MATRIX 0 + #define gcFEATURE_VG_NEW_IMAGE_INDEX 1 + #define gcFEATURE_VG_PARALLEL_PATHS 1 + #define gcFEATURE_VG_STRIPE_MODE 1 + #define gcFEATURE_VG_IM_DEC_INPUT 1 + #define gcFEATURE_VG_GAUSSIAN_BLUR 0 + #define gcFEATURE_VG_RECTANGLE_TILED_OUT 1 + #define gcFEATURE_VG_TESSELLATION_TILED_OUT 1 + #define gcFEATURE_VG_IM_REPEAT_REFLECT 1 + #define gcFEATURE_VG_YUY2_INPUT 1 + #define gcFEATURE_VG_YUV_INPUT 1 + #define gcFEATURE_VG_YUV_TILED_INPUT 0 + #define gcFEATURE_VG_AYUV_INPUT 0 + #define gcFEATURE_VG_16PIXELS_ALIGNED 1 + #define gcFEATURE_VG_MATH_PRECISION_FIX 1 + #define gcFEATURE_VG_SPLIT_PATH 1 + #define gcFEATURE_VG_DEC_COMPRESS_2_0 0 + #define gcFEATURE_VG_CLOCK_GATING_TS_MODULE 1 + #define gcFEATURE_VG_CLOCK_GATING_VG_MODULE 0 + #define gcFEATURE_VG_NV24_INPUT 0 + #define gcFEATURE_VG_TILED_LIMIT 3 + #define gcFEATURE_VG_SRC_ADDRESS_64BYTES_ALIGNED 1 + #define gcFEATURE_VG_SRC_TILE_4PIXELS_ALIGNED 1 + #define gcFEATURE_VG_SRC_BUF_ALINGED 0 + #define gcFEATURE_VG_SRC_ADDRESS_16BYTES_ALIGNED 0 + #define gcFEATURE_VG_DST_ADDRESS_64BYTES_ALIGNED 0 + #define gcFEATURE_VG_DST_TILE_4PIXELS_ALIGNED 1 + #define gcFEATURE_VG_DST_BUF_ALIGNED 0 + #define gcFEATURE_VG_DST_24BIT_PLANAR_ALIGNED 0 + #define gcFEATURE_VG_DST_BUFLEN_ALIGNED 0 + #define gcFEATURE_VG_FORMAT_SUPPORT_CHECK 0 + #define gcFEATURE_VG_YUV_ALIGNED_CHECK 1 + #define gcFEATURE_VG_512_PARALLEL_PATHS 0 + + /* SW Features */ + #define gcFEATURE_VG_STROKE_PATH 1 + #define gcFEATURE_VG_ARC_PATH 1 + #define gcFEATURE_VG_ERROR_CHECK 1 + #define gcFEATURE_VG_TRACE_API 0 + #define gcFEATURE_VG_POWER_MANAGEMENT 1 + #define gcFEATURE_VG_TILED_MODE 1 + #define gcFEATURE_VG_SINGLE_COMMAND_BUFFER 0 + +#endif /* LV_USE_VG_LITE_DRIVER */ + +#endif /* VG_LITE_OPTIONS_H */ diff --git a/src/libs/vg_lite_driver/VGLite/Series/gc555/0x423_ECO/vg_lite_options.h b/src/libs/vg_lite_driver/VGLite/Series/gc555/0x423_ECO/vg_lite_options.h new file mode 100755 index 0000000000..f67dc0a295 --- /dev/null +++ b/src/libs/vg_lite_driver/VGLite/Series/gc555/0x423_ECO/vg_lite_options.h @@ -0,0 +1,115 @@ +/**************************************************************************** +* +* Copyright 2012 - 2023 Vivante Corporation, Santa Clara, California. +* All Rights Reserved. +* +* Permission is hereby granted, free of charge, to any person obtaining +* a copy of this software and associated documentation files (the +* 'Software'), to deal in the Software without restriction, including +* without limitation the rights to use, copy, modify, merge, publish, +* distribute, sub license, and/or sell copies of the Software, and to +* permit persons to whom the Software is furnished to do so, subject +* to the following conditions: +* +* The above copyright notice and this permission notice (including the +* next paragraph) shall be included in all copies or substantial +* portions of the Software. +* +* THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND, +* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. +* IN NO EVENT SHALL VIVANTE AND/OR ITS SUPPLIERS BE LIABLE FOR ANY +* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, +* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE +* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +* +*****************************************************************************/ + +#ifndef VG_LITE_OPTIONS_H +#define VG_LITE_OPTIONS_H + +#include "../../../../../../lv_conf_internal.h" +#if LV_USE_VG_LITE_DRIVER + + #define CHIPID 0x555 + #define REVISION 0x1230 + #define CID 0x423 + #define ECOID 0x1 + + #define gcFEATURE_VG_IM_INDEX_FORMAT 1 + #define gcFEATURE_VG_SCISSOR 1 + #define gcFEATURE_VG_BORDER_CULLING 1 + #define gcFEATURE_VG_RGBA2_FORMAT 1 + #define gcFEATURE_VG_QUALITY_8X 0 + #define gcFEATURE_VG_IM_FASTCLEAR 0 + #define gcFEATURE_VG_RADIAL_GRADIENT 1 + #define gcFEATURE_VG_GLOBAL_ALPHA 1 + #define gcFEATURE_VG_RGBA8_ETC2_EAC 1 + #define gcFEATURE_VG_COLOR_KEY 1 + #define gcFEATURE_VG_DOUBLE_IMAGE 0 + #define gcFEATURE_VG_YUV_OUTPUT 0 + #define gcFEATURE_VG_FLEXA 0 + #define gcFEATURE_VG_24BIT 1 + #define gcFEATURE_VG_DITHER 1 + #define gcFEATURE_VG_USE_DST 0 + #define gcFEATURE_VG_PE_CLEAR 1 + #define gcFEATURE_VG_IM_INPUT 1 + #define gcFEATURE_VG_DEC_COMPRESS 1 + #define gcFEATURE_VG_LINEAR_GRADIENT_EXT 1 + #define gcFEATURE_VG_MASK 1 + #define gcFEATURE_VG_MIRROR 1 + #define gcFEATURE_VG_GAMMA 1 + #define gcFEATURE_VG_NEW_BLEND_MODE 1 + #define gcFEATURE_VG_STENCIL 1 + #define gcFEATURE_VG_SRC_PREMULTIPLIED 0 + #define gcFEATURE_VG_HW_PREMULTIPLY 1 + #define gcFEATURE_VG_COLOR_TRANSFORMATION 1 + #define gcFEATURE_VG_LVGL_SUPPORT 1 + #define gcFEATURE_VG_INDEX_ENDIAN 0 + #define gcFEATURE_VG_24BIT_PLANAR 0 + #define gcFEATURE_VG_PIXEL_MATRIX 0 + #define gcFEATURE_VG_NEW_IMAGE_INDEX 1 + #define gcFEATURE_VG_PARALLEL_PATHS 1 + #define gcFEATURE_VG_STRIPE_MODE 1 + #define gcFEATURE_VG_IM_DEC_INPUT 1 + #define gcFEATURE_VG_GAUSSIAN_BLUR 0 + #define gcFEATURE_VG_RECTANGLE_TILED_OUT 1 + #define gcFEATURE_VG_TESSELLATION_TILED_OUT 1 + #define gcFEATURE_VG_IM_REPEAT_REFLECT 1 + #define gcFEATURE_VG_YUY2_INPUT 1 + #define gcFEATURE_VG_YUV_INPUT 1 + #define gcFEATURE_VG_YUV_TILED_INPUT 0 + #define gcFEATURE_VG_AYUV_INPUT 0 + #define gcFEATURE_VG_16PIXELS_ALIGNED 1 + #define gcFEATURE_VG_MATH_PRECISION_FIX 0 + #define gcFEATURE_VG_SPLIT_PATH 1 + #define gcFEATURE_VG_DEC_COMPRESS_2_0 0 + #define gcFEATURE_VG_CLOCK_GATING_TS_MODULE 1 + #define gcFEATURE_VG_CLOCK_GATING_VG_MODULE 0 + #define gcFEATURE_VG_NV24_INPUT 0 + #define gcFEATURE_VG_TILED_LIMIT 3 + #define gcFEATURE_VG_SRC_ADDRESS_16BYTES_ALIGNED 0 + #define gcFEATURE_VG_SRC_ADDRESS_64BYTES_ALIGNED 1 + #define gcFEATURE_VG_SRC_TILE_4PIXELS_ALIGNED 1 + #define gcFEATURE_VG_SRC_BUF_ALINGED 0 + #define gcFEATURE_VG_DST_ADDRESS_64BYTES_ALIGNED 0 + #define gcFEATURE_VG_DST_TILE_4PIXELS_ALIGNED 1 + #define gcFEATURE_VG_DST_BUF_ALIGNED 0 + #define gcFEATURE_VG_DST_24BIT_PLANAR_ALIGNED 0 + #define gcFEATURE_VG_DST_BUFLEN_ALIGNED 0 + #define gcFEATURE_VG_FORMAT_SUPPORT_CHECK 0 + #define gcFEATURE_VG_YUV_ALIGNED_CHECK 1 + #define gcFEATURE_VG_512_PARALLEL_PATHS 0 + + /* SW Features */ + #define gcFEATURE_VG_STROKE_PATH 1 + #define gcFEATURE_VG_ARC_PATH 1 + #define gcFEATURE_VG_ERROR_CHECK 1 + #define gcFEATURE_VG_TRACE_API 0 + #define gcFEATURE_VG_POWER_MANAGEMENT 1 + #define gcFEATURE_VG_TILED_MODE 1 + #define gcFEATURE_VG_SINGLE_COMMAND_BUFFER 0 + +#endif /* LV_USE_VG_LITE_DRIVER */ + +#endif /* VG_LITE_OPTIONS_H */ diff --git a/src/libs/vg_lite_driver/VGLite/vg_lite.c b/src/libs/vg_lite_driver/VGLite/vg_lite.c new file mode 100755 index 0000000000..207747a893 --- /dev/null +++ b/src/libs/vg_lite_driver/VGLite/vg_lite.c @@ -0,0 +1,7404 @@ +/**************************************************************************** +* +* Copyright 2012 - 2023 Vivante Corporation, Santa Clara, California. +* All Rights Reserved. +* +* Permission is hereby granted, free of charge, to any person obtaining +* a copy of this software and associated documentation files (the +* 'Software'), to deal in the Software without restriction, including +* without limitation the rights to use, copy, modify, merge, publish, +* distribute, sub license, and/or sell copies of the Software, and to +* permit persons to whom the Software is furnished to do so, subject +* to the following conditions: +* +* The above copyright notice and this permission notice (including the +* next paragraph) shall be included in all copies or substantial +* portions of the Software. +* +* THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND, +* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. +* IN NO EVENT SHALL VIVANTE AND/OR ITS SUPPLIERS BE LIABLE FOR ANY +* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, +* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE +* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +* +*****************************************************************************/ + +#include "../../../lv_conf_internal.h" +#if LV_USE_VG_LITE_DRIVER + +#include "vg_lite_context.h" + +static float offsetTable[7] = {0, 0.000575f, -0.000575f, 0.0001f, -0.0001f, 0.0000375f, -0.0000375f}; + +#if VG_SW_BLIT_PRECISION_OPT +uint8_t GetIndex(uint32_t RotationStep, uint32_t ScaleValue) +{ + uint8_t index = 0; + switch(RotationStep) { + case 0: //rotate 0 + switch(ScaleValue) { + case 10: + case 15: + case 25: + case 30: + case 70: + case 75: + index = 1; + break; + case 45: + case 50: + case 60: + case 65: + case 550: + index = 3; + break; + case 55: + case 250: + case 350: + index = 4; + break; + case 85: + case 90: + case 95: + case 150: + case 450: + case 650: + case 750: + case 850: + case 950: + index = 5; + break; + case 125: + index = 2; + break; + default: + index = 0; + break; + } + break; + case 2: //rotate 90 + switch(ScaleValue) { + case 10: + index = 2; + break; + case 15: + case 25: + case 30: + case 45: + case 75: + case 85: + case 90: + case 95: + case 150: + case 250: + case 350: + case 450: + case 550: + case 850: + index = 5; + break; + case 35: + case 750: + index = 4; + break; + case 50: + index = 1; + break; + case 55: + case 60: + case 65: + case 70: + index = 3; + break; + default: + index = 0; + break; + } + break; + case 3: //rotate 135 + switch(ScaleValue) { + case 10: + case 15: + case 20: + case 35: + case 45: + case 50: + case 60: + case 75: + index = 2; + break; + case 85: + case 90: + case 100: + case 400: + case 450: + case 500: + case 550: + case 850: + index = 4; + break; + default: + index = 0; + break; + } + break; + case 4: //rotate 180 + switch(ScaleValue) { + case 10: + case 15: + case 25: + case 30: + case 35: + case 50: + index = 1; + break; + case 45: + case 55: + case 65: + case 70: + case 75: + case 85: + case 90: + case 95: + case 150: + case 250: + case 350: + case 450: + case 550: + case 650: + case 750: + case 850: + case 950: + index = 5; + break; + default: + index = 0; + break; + } + break; + case 5: //rotate 225 + switch(ScaleValue) { + case 10: + case 15: + case 20: + case 30: + case 35: + case 40: + case 45: + case 55: + case 60: + case 90: + index = 6; + break; + default: + index = 0; + break; + } + break; + case 6: //rotate 270 + switch(ScaleValue) { + case 10: + case 25: + case 30: + case 35: + case 45: + case 55: + case 60: + case 65: + case 70: + case 75: + case 80: + case 85: + case 90: + case 95: + case 150: + case 350: + case 450: + case 550: + case 650: + case 750: + case 850: + case 950: + index = 5; + break; + default: + index = 0; + break; + } + break; + case 7: //rotate 315 + switch(ScaleValue) { + case 20: + case 25: + case 30: + case 35: + case 40: + case 45: + case 50: + case 55: + case 60: + case 65: + case 70: + case 80: + case 85: + case 90: + case 95: + case 350: + case 550: + case 900: + index = 5; + break; + default: + index = 0; + break; + } + break; + default : + index = 0; + break; + } + return index; +} +#endif /* VG_SW_BLIT_PRECISION_OPT */ + +/* Global context variables and feature table. +*/ +vg_lite_context_t s_context = { 0 }; +#if gcFEATURE_VG_SINGLE_COMMAND_BUFFER + uint32_t command_buffer_size = VG_LITE_SINGLE_COMMAND_BUFFER_SIZE; +#else + uint32_t command_buffer_size = VG_LITE_COMMAND_BUFFER_SIZE; +#endif +uint32_t submit_flag = 0; + +vg_lite_matrix_t identity_mtx = { + { + { 1.0f, 0.0f, 0.0f }, + { 0.0f, 1.0f, 0.0f }, + { 0.0f, 0.0f, 1.0f } + }, + 1.0f, 1.0f, 0.0f +}; + +/* Initialize the feature table of a chip. */ +vg_lite_ftable_t s_ftable = { + { + gcFEATURE_VG_IM_INDEX_FORMAT, + gcFEATURE_VG_SCISSOR, + gcFEATURE_VG_BORDER_CULLING, + gcFEATURE_VG_RGBA2_FORMAT, + gcFEATURE_VG_QUALITY_8X, + gcFEATURE_VG_IM_FASTCLEAR, + gcFEATURE_VG_RADIAL_GRADIENT, + gcFEATURE_VG_GLOBAL_ALPHA, + gcFEATURE_VG_RGBA8_ETC2_EAC, + gcFEATURE_VG_COLOR_KEY, + gcFEATURE_VG_DOUBLE_IMAGE, + gcFEATURE_VG_YUV_OUTPUT, + gcFEATURE_VG_FLEXA, + gcFEATURE_VG_24BIT, + gcFEATURE_VG_DITHER, + gcFEATURE_VG_USE_DST, + gcFEATURE_VG_PE_CLEAR, + gcFEATURE_VG_IM_INPUT, + gcFEATURE_VG_DEC_COMPRESS, + gcFEATURE_VG_LINEAR_GRADIENT_EXT, + gcFEATURE_VG_MASK, + gcFEATURE_VG_MIRROR, + gcFEATURE_VG_GAMMA, + gcFEATURE_VG_NEW_BLEND_MODE, + gcFEATURE_VG_STENCIL, + gcFEATURE_VG_SRC_PREMULTIPLIED, + gcFEATURE_VG_HW_PREMULTIPLY, + gcFEATURE_VG_COLOR_TRANSFORMATION, + gcFEATURE_VG_LVGL_SUPPORT, + gcFEATURE_VG_INDEX_ENDIAN, + gcFEATURE_VG_24BIT_PLANAR, + gcFEATURE_VG_PIXEL_MATRIX, + gcFEATURE_VG_NEW_IMAGE_INDEX, + gcFEATURE_VG_PARALLEL_PATHS, + gcFEATURE_VG_STRIPE_MODE, + gcFEATURE_VG_IM_DEC_INPUT, + gcFEATURE_VG_GAUSSIAN_BLUR, + gcFEATURE_VG_RECTANGLE_TILED_OUT, + gcFEATURE_VG_TESSELLATION_TILED_OUT, + gcFEATURE_VG_IM_REPEAT_REFLECT, + gcFEATURE_VG_YUY2_INPUT, + gcFEATURE_VG_YUV_INPUT, + gcFEATURE_VG_YUV_TILED_INPUT, + gcFEATURE_VG_AYUV_INPUT, + gcFEATURE_VG_16PIXELS_ALIGNED, + gcFEATURE_VG_DEC_COMPRESS_2_0, + gcFEATURE_VG_NV24_INPUT, + gcFEATURE_VG_TILED_LIMIT, + gcFEATURE_VG_TILED_MODE, + gcFEATURE_VG_SRC_ADDRESS_16BYTES_ALIGNED, + gcFEATURE_VG_SRC_ADDRESS_64BYTES_ALIGNED, + gcFEATURE_VG_SRC_TILE_4PIXELS_ALIGNED, + gcFEATURE_VG_SRC_BUF_ALINGED, + gcFEATURE_VG_DST_ADDRESS_64BYTES_ALIGNED, + gcFEATURE_VG_DST_TILE_4PIXELS_ALIGNED, + gcFEATURE_VG_DST_BUF_ALIGNED, + gcFEATURE_VG_DST_24BIT_PLANAR_ALIGNED, + gcFEATURE_VG_DST_BUFLEN_ALIGNED, + gcFEATURE_VG_FORMAT_SUPPORT_CHECK, + gcFEATURE_VG_YUV_ALIGNED_CHECK, + gcFEATURE_VG_512_PARALLEL_PATHS, + } +}; + +static vg_lite_error_t check_hardware_chip_info(void) +{ + vg_lite_uint32_t chip_id = 0, chip_rev = 0, cid = 0, eco_id = 0; + + vg_lite_get_product_info(NULL, &chip_id, &chip_rev); + vg_lite_get_register(0x30, &cid); + vg_lite_get_register(0xE8, &eco_id); + + if(CHIPID != chip_id || REVISION != chip_rev || CID != cid || ECOID != eco_id) { + printf("VGLite API initialization Error!!! \nHardware ChipId: 0x%X ChipRevision: 0x%X Cid: 0x%X Ecoid: 0x%X \n", + chip_id, chip_rev, cid, eco_id); + printf("NOT match vg_lite_options.h CHIPID: 0x%X REVISION: 0x%X CID: 0x%X Ecoid: 0x%X \n", CHIPID, REVISION, CID, + ECOID); + return VG_LITE_NOT_SUPPORT; + } + + return VG_LITE_SUCCESS; +} + +vg_lite_error_t check_compress( + vg_lite_buffer_format_t format, + vg_lite_compress_mode_t compress_mode, + vg_lite_buffer_layout_t tiled, + uint32_t width, + uint32_t height +) +{ +#if gcFEATURE_VG_DEC_COMPRESS + vg_lite_error_t error = VG_LITE_SUCCESS; + + if(compress_mode) { + if(compress_mode > VG_LITE_DEC_HV_SAMPLE || compress_mode < VG_LITE_DEC_DISABLE) + return VG_LITE_INVALID_ARGUMENT; + + if(tiled) { + if(width % 16 || height % 4) + return VG_LITE_INVALID_ARGUMENT; + } + else { + if(width % 16 || compress_mode == VG_LITE_DEC_HV_SAMPLE) + return VG_LITE_INVALID_ARGUMENT; + } + +#if gcFEATURE_VG_DEC_COMPRESS_2_0 + if(format != VG_LITE_BGRA8888 && format != VG_LITE_BGRX8888 && format != VG_LITE_BGR888) { + printf("Invalid compression format!\n"); + return VG_LITE_INVALID_ARGUMENT; + } +#else + if(format != VG_LITE_BGRX8888 && format != VG_LITE_RGBX8888 && format != VG_LITE_BGRA8888 + && format != VG_LITE_RGBA8888 && format != VG_LITE_RGB888 && format != VG_LITE_BGR888) { + printf("Invalid compression format!\n"); + return VG_LITE_INVALID_ARGUMENT; + } +#endif + } + + return error; +#else + return VG_LITE_SUCCESS; +#endif +} + +static vg_lite_float_t _calc_decnano_compress_ratio( + vg_lite_buffer_format_t format, + vg_lite_compress_mode_t compress_mode +) +{ + vg_lite_float_t ratio = 1.0f; + +#if gcFEATURE_VG_DEC_COMPRESS_2_0 + switch(compress_mode) { + case VG_LITE_DEC_NON_SAMPLE: + switch(format) { + case VG_LITE_BGRA8888: + case VG_LITE_BGR888: + ratio = 0.5f; + break; + case VG_LITE_BGRX8888: + ratio = 0.385f; + break; + default: + return ratio; + } + break; + + case VG_LITE_DEC_HSAMPLE: + switch(format) { + case VG_LITE_BGRA8888: + ratio = 0.385f; + break; + case VG_LITE_BGRX8888: + ratio = 0.25f; + break; + case VG_LITE_BGR888: + ratio = 0.334f; + break; + default: + return ratio; + } + break; + + case VG_LITE_DEC_HV_SAMPLE: + switch(format) { + case VG_LITE_BGRA8888: + ratio = 0.385f; + break; + case VG_LITE_BGRX8888: + ratio = 0.25f; + break; + case VG_LITE_BGR888: + ratio = 0.334f; + break; + default: + return ratio; + } + break; + + default: + return ratio; + } +#else +#if gcFEATURE_VG_DEC_COMPRESS + switch(compress_mode) { + case VG_LITE_DEC_NON_SAMPLE: + switch(format) { + case VG_LITE_ABGR8888: + case VG_LITE_ARGB8888: + case VG_LITE_BGRA8888: + case VG_LITE_RGBA8888: + ratio = 0.625f; + break; + case VG_LITE_XBGR8888: + case VG_LITE_XRGB8888: + case VG_LITE_BGRX8888: + case VG_LITE_RGBX8888: + ratio = 0.5f; + break; + case VG_LITE_RGB888: + case VG_LITE_BGR888: + ratio = 0.667f; + break; + default: + return ratio; + } + break; + + case VG_LITE_DEC_HSAMPLE: + switch(format) { + case VG_LITE_ABGR8888: + case VG_LITE_ARGB8888: + case VG_LITE_BGRA8888: + case VG_LITE_RGBA8888: + case VG_LITE_RGB888: + case VG_LITE_BGR888: + ratio = 0.5f; + break; + case VG_LITE_XBGR8888: + case VG_LITE_XRGB8888: + case VG_LITE_BGRX8888: + case VG_LITE_RGBX8888: + ratio = 0.375f; + break; + default: + return ratio; + } + break; + + case VG_LITE_DEC_HV_SAMPLE: + switch(format) { + case VG_LITE_ABGR8888: + case VG_LITE_ARGB8888: + case VG_LITE_BGRA8888: + case VG_LITE_RGBA8888: + ratio = 0.375f; + break; + case VG_LITE_XBGR8888: + case VG_LITE_XRGB8888: + case VG_LITE_BGRX8888: + case VG_LITE_RGBX8888: + ratio = 0.25f; + break; + default: + return ratio; + } + break; + default: + return ratio; + } +#endif + +#endif + + return ratio; +} + +static inline int32_t has_valid_command_buffer(vg_lite_context_t * context) +{ + if(context == NULL) + return 0; + if(context->command_buffer_current >= CMDBUF_COUNT) + return 0; + if(context->command_buffer[context->command_buffer_current] == NULL) + return 0; + + return 1; +} + +typedef vg_lite_float_t FLOATVECTOR4[4]; + +static void ClampColor(FLOATVECTOR4 Source, FLOATVECTOR4 Target, uint8_t Premultiplied) +{ + vg_lite_float_t colorMax; + /* Clamp the alpha channel. */ + Target[3] = CLAMP(Source[3], 0.0f, 1.0f); + + /* Determine the maximum value for the color channels. */ + colorMax = Premultiplied ? Target[3] : 1.0f; + + /* Clamp the color channels. */ + Target[0] = CLAMP(Source[0], 0.0f, colorMax); + Target[1] = CLAMP(Source[1], 0.0f, colorMax); + Target[2] = CLAMP(Source[2], 0.0f, colorMax); +} + +static uint8_t PackColorComponent(vg_lite_float_t value) +{ + /* Compute the rounded normalized value. */ + vg_lite_float_t rounded = value * 255.0f + 0.5f; + + /* Get the integer part. */ + int32_t roundedInt = (int32_t)rounded; + + /* Clamp to 0..1 range. */ + uint8_t clamped = (uint8_t)CLAMP(roundedInt, 0, 255); + + /* Return result. */ + return clamped; +} + +#if DUMP_IMAGE +static void dump_img(void * memory, int32_t width, int32_t height, vg_lite_buffer_format_t format) +{ + FILE * fp; + char imgname[255] = {'\0'}; + static int32_t num = 1; + uint32_t * pt = (uint32_t *) memory; + int32_t i; + + sprintf(imgname, "img_pid%d_%d.txt", getpid(), num++); + + fp = fopen(imgname, "w"); + + if(fp == NULL) + printf("error!\n"); + + + switch(format) { + case VG_LITE_INDEX_1: + for(i = 0; i < width * height / 32; ++i) { + fprintf(fp, "0x%08x\n", pt[i]); + } + break; + + case VG_LITE_INDEX_2: + for(i = 0; i < width * height / 16; ++i) { + fprintf(fp, "0x%08x\n", pt[i]); + } + break; + + case VG_LITE_INDEX_4: + for(i = 0; i < width * height / 8; ++i) { + fprintf(fp, "0x%08x\n", pt[i]); + } + break; + + case VG_LITE_INDEX_8: + for(i = 0; i < width * height / 4; ++i) { + fprintf(fp, "0x%08x\n", pt[i]); + } + break; + + case VG_LITE_RGBA2222: + for(i = 0; i < width * height / 4; ++i) { + fprintf(fp, "0x%08x\n", pt[i]); + } + break; + + case VG_LITE_RGBA4444: + case VG_LITE_BGRA4444: + case VG_LITE_RGB565: + case VG_LITE_BGR565: + for(i = 0; i < width * height / 2; ++i) { + fprintf(fp, "0x%08x\n", pt[i]); + } + break; + + case VG_LITE_RGBA8888: + case VG_LITE_BGRA8888: + case VG_LITE_RGBX8888: + case VG_LITE_BGRX8888: + for(i = 0; i < width * height; ++i) { + fprintf(fp, "0x%08x\n", pt[i]); + } + break; + + default: + break; + } + fclose(fp); + fp = NULL; +} +#endif + +static uint32_t rgb_to_l(uint32_t color) +{ + uint32_t l = (uint32_t)((0.2126f * (vg_lite_float_t)(color & 0xFF)) + + (0.7152f * (vg_lite_float_t)((color >> 8) & 0xFF)) + + (0.0722f * (vg_lite_float_t)((color >> 16) & 0xFF))); + return l | (l << 24); +} + +/* Get the bpp information of a color format. */ +void get_format_bytes(vg_lite_buffer_format_t format, + uint32_t * mul, + uint32_t * div, + uint32_t * bytes_align) +{ + *mul = *div = 1; + *bytes_align = 4; + switch(format) { + case VG_LITE_L8: + case VG_LITE_A8: + case VG_LITE_RGBA8888_ETC2_EAC: + break; + + case VG_LITE_A4: + *div = 2; + break; + + case VG_LITE_ABGR1555: + case VG_LITE_ARGB1555: + case VG_LITE_BGRA5551: + case VG_LITE_RGBA5551: + case VG_LITE_RGBA4444: + case VG_LITE_BGRA4444: + case VG_LITE_ABGR4444: + case VG_LITE_ARGB4444: + case VG_LITE_RGB565: + case VG_LITE_BGR565: + case VG_LITE_YUYV: + case VG_LITE_YUY2: + case VG_LITE_YUY2_TILED: + /* AYUY2 buffer memory = YUY2 + alpha. */ + case VG_LITE_AYUY2: + case VG_LITE_AYUY2_TILED: + /* ABGR8565_PLANAR buffer memory = RGB565 + alpha. */ + case VG_LITE_ABGR8565_PLANAR: + case VG_LITE_ARGB8565_PLANAR: + case VG_LITE_RGBA5658_PLANAR: + case VG_LITE_BGRA5658_PLANAR: + *mul = 2; + break; + + case VG_LITE_RGBA8888: + case VG_LITE_BGRA8888: + case VG_LITE_ABGR8888: + case VG_LITE_ARGB8888: + case VG_LITE_RGBX8888: + case VG_LITE_BGRX8888: + case VG_LITE_XBGR8888: + case VG_LITE_XRGB8888: + *mul = 4; + break; + + case VG_LITE_NV12: + case VG_LITE_NV12_TILED: + *mul = 1; + break; + + case VG_LITE_ANV12: + case VG_LITE_ANV12_TILED: + *mul = 4; + break; + + case VG_LITE_INDEX_1: + *div = 8; + *bytes_align = 8; + break; + + case VG_LITE_INDEX_2: + *div = 4; + *bytes_align = 8; + break; + + case VG_LITE_INDEX_4: + *div = 2; + *bytes_align = 8; + break; + + case VG_LITE_INDEX_8: + *bytes_align = 1; + break; + + case VG_LITE_RGBA2222: + case VG_LITE_BGRA2222: + case VG_LITE_ABGR2222: + case VG_LITE_ARGB2222: + *mul = 1; + break; + + case VG_LITE_RGB888: + case VG_LITE_BGR888: + case VG_LITE_ABGR8565: + case VG_LITE_BGRA5658: + case VG_LITE_ARGB8565: + case VG_LITE_RGBA5658: + *mul = 3; + break; + + /* OpenVG format*/ + case OPENVG_sRGBX_8888: + case OPENVG_sRGBX_8888_PRE: + case OPENVG_sRGBA_8888: + case OPENVG_sRGBA_8888_PRE: + case OPENVG_lRGBX_8888: + case OPENVG_lRGBX_8888_PRE: + case OPENVG_lRGBA_8888: + case OPENVG_lRGBA_8888_PRE: + case OPENVG_sXRGB_8888: + case OPENVG_sARGB_8888: + case OPENVG_sARGB_8888_PRE: + case OPENVG_lXRGB_8888: + case OPENVG_lARGB_8888: + case OPENVG_lARGB_8888_PRE: + case OPENVG_sBGRX_8888: + case OPENVG_sBGRA_8888: + case OPENVG_sBGRA_8888_PRE: + case OPENVG_lBGRX_8888: + case OPENVG_lBGRA_8888: + case OPENVG_sXBGR_8888: + case OPENVG_sABGR_8888: + case OPENVG_lBGRA_8888_PRE: + case OPENVG_sABGR_8888_PRE: + case OPENVG_lXBGR_8888: + case OPENVG_lABGR_8888: + case OPENVG_lABGR_8888_PRE: + *mul = 4; + break; + + case OPENVG_sRGBA_5551: + case OPENVG_sRGBA_5551_PRE: + case OPENVG_lRGBA_5551: + case OPENVG_lRGBA_5551_PRE: + case OPENVG_sRGBA_4444: + case OPENVG_sRGBA_4444_PRE: + case OPENVG_lRGBA_4444: + case OPENVG_lRGBA_4444_PRE: + case OPENVG_sARGB_1555: + case OPENVG_sARGB_4444: + case OPENVG_sBGRA_5551: + case OPENVG_sBGRA_4444: + case OPENVG_sABGR_1555: + case OPENVG_sABGR_4444: + case OPENVG_sRGB_565: + case OPENVG_sRGB_565_PRE: + case OPENVG_sBGR_565: + case OPENVG_lRGB_565: + case OPENVG_lRGB_565_PRE: + * mul = 2; + break; + + case OPENVG_sL_8: + case OPENVG_lL_8: + case OPENVG_A_8: + break; + + case OPENVG_BW_1: + case OPENVG_A_4: + case OPENVG_A_1: + * div = 2; + break; + + default: + break; + } +} + +/* Convert VGLite target color format to HW value. */ +static uint32_t convert_target_format(vg_lite_buffer_format_t format, vg_lite_capabilities_t caps) +{ + switch(format) { + case VG_LITE_A8: + return 0x0; + + case VG_LITE_L8: + return 0x6; + + case VG_LITE_ABGR4444: + return 0x14; + + case VG_LITE_ARGB4444: + return 0x34; + + case VG_LITE_RGBA4444: + return 0x24; + + case VG_LITE_BGRA4444: + return 0x4; + + case VG_LITE_RGB565: + return 0x21; + + case VG_LITE_BGR565: + return 0x1; + + case VG_LITE_ABGR8888: + return 0x13; + + case VG_LITE_ARGB8888: + return 0x33; + + case VG_LITE_RGBA8888: + return 0x23; + + case VG_LITE_BGRA8888: + return 0x3; + + case VG_LITE_RGBX8888: + return 0x22; + + case VG_LITE_BGRX8888: + return 0x2; + + case VG_LITE_XBGR8888: + return 0x12; + + case VG_LITE_XRGB8888: + return 0x32; + + case VG_LITE_ABGR1555: + return 0x15; + + case VG_LITE_RGBA5551: + return 0x25; + + case VG_LITE_ARGB1555: + return 0x35; + + case VG_LITE_BGRA5551: + return 0x5; + + case VG_LITE_YUYV: + case VG_LITE_YUY2: + case VG_LITE_YUY2_TILED: + return 0x8; + + case VG_LITE_NV12: + case VG_LITE_NV12_TILED: + return 0xB; + + case VG_LITE_ANV12: + case VG_LITE_ANV12_TILED: + return 0xE; + + case VG_LITE_BGRA2222: + return 0x7; + + case VG_LITE_RGBA2222: + return 0x27; + + case VG_LITE_ABGR2222: + return 0x17; + + case VG_LITE_ARGB2222: + return 0x37; + + case VG_LITE_ARGB8565: + return 0x3A; + + case VG_LITE_RGBA5658: + return 0x2A; + + case VG_LITE_ABGR8565: + return 0x1A; + + case VG_LITE_BGRA5658: + return 0x0A; + + case VG_LITE_ARGB8565_PLANAR: + return 0x3C; + + case VG_LITE_RGBA5658_PLANAR: + return 0x2C; + + case VG_LITE_ABGR8565_PLANAR: + return 0x1C; + + case VG_LITE_BGRA5658_PLANAR: + return 0x0C; + + case VG_LITE_RGB888: + return 0x29; + + case VG_LITE_BGR888: + return 0x09; + + case VG_LITE_AYUY2: + case VG_LITE_AYUY2_TILED: + return 0xF; + + /* OpenVG VGImageFormat */ + + case OPENVG_sRGBX_8888: + case OPENVG_sRGBX_8888_PRE: + return 0x12; + break; + + case OPENVG_sRGBA_8888: + case OPENVG_sRGBA_8888_PRE: + return 0x13; + break; + + case OPENVG_sRGB_565: + case OPENVG_sRGB_565_PRE: + return 0x1; + break; + + case OPENVG_sRGBA_5551: + case OPENVG_sRGBA_5551_PRE: + return 0x15; + break; + + case OPENVG_sRGBA_4444: + case OPENVG_sRGBA_4444_PRE: + return 0x14; + break; + + case OPENVG_sL_8: + return 0x6; + break; + + case OPENVG_lRGBX_8888: + case OPENVG_lRGBX_8888_PRE: + return 0x12; + break; + + case OPENVG_lRGBA_8888: + case OPENVG_lRGBA_8888_PRE: + return 0x13; + break; + + case OPENVG_lRGB_565: + case OPENVG_lRGB_565_PRE: + return 0x1; + break; + + case OPENVG_lRGBA_5551: + case OPENVG_lRGBA_5551_PRE: + return 0x15; + break; + + case OPENVG_lRGBA_4444: + case OPENVG_lRGBA_4444_PRE: + return 0x14; + break; + + case OPENVG_lL_8: + return 0x6; + break; + + case OPENVG_A_8: + return 0x0; + break; + + case OPENVG_sXRGB_8888: + return 0x2; + break; + + case OPENVG_sARGB_8888: + return 0x3; + break; + + case OPENVG_sARGB_8888_PRE: + return 0x3; + break; + + case OPENVG_sARGB_1555: + return 0x5; + break; + + case OPENVG_sARGB_4444: + return 0x4; + break; + + case OPENVG_lXRGB_8888: + return 0x2; + break; + + case OPENVG_lARGB_8888: + return 0x3; + break; + + case OPENVG_lARGB_8888_PRE: + return 0x3; + break; + + case OPENVG_sBGRX_8888: + return 0x32; + break; + + case OPENVG_sBGRA_8888: + return 0x33; + break; + + case OPENVG_sBGRA_8888_PRE: + return 0x33; + break; + + case OPENVG_sBGR_565: + return 0x21; + break; + + case OPENVG_sBGRA_5551: + return 0x35; + break; + + case OPENVG_sBGRA_4444: + return 0x34; + break; + + case OPENVG_lBGRX_8888: + return 0x32; + break; + + case OPENVG_lBGRA_8888: + return 0x33; + break; + + case OPENVG_lBGRA_8888_PRE: + return 0x33; + break; + + case OPENVG_sXBGR_8888: + return 0x22; + break; + + case OPENVG_sABGR_8888: + return 0x23; + break; + + case OPENVG_sABGR_8888_PRE: + return 0x23; + break; + + case OPENVG_sABGR_1555: + return 0x25; + break; + + case OPENVG_sABGR_4444: + return 0x24; + break; + + case OPENVG_lXBGR_8888: + return 0x22; + break; + + case OPENVG_lABGR_8888: + return 0x23; + break; + + case OPENVG_lABGR_8888_PRE: + return 0x23; + break; + + default: + return 0xFF; + } +} + +#define FORMAT_ALIGNMENT(stride,align) \ + { \ + if ((stride) % (align) != 0) \ + return VG_LITE_INVALID_ARGUMENT; \ + return VG_LITE_SUCCESS; \ + } + +#if gcFEATURE_VG_16PIXELS_ALIGNED +/* Determine source IM is aligned by specified bytes */ +static vg_lite_error_t _check_source_aligned(vg_lite_buffer_format_t format, uint32_t stride) +{ + switch(format) { + case VG_LITE_A4: + case VG_LITE_INDEX_1: + case VG_LITE_INDEX_2: + case VG_LITE_INDEX_4: + FORMAT_ALIGNMENT(stride, 8); + break; + + case VG_LITE_L8: + case VG_LITE_A8: + case VG_LITE_INDEX_8: + case VG_LITE_RGBA2222: + case VG_LITE_BGRA2222: + case VG_LITE_ABGR2222: + case VG_LITE_ARGB2222: + case VG_LITE_RGBA8888_ETC2_EAC: + FORMAT_ALIGNMENT(stride, 16); + break; + + case VG_LITE_RGBA4444: + case VG_LITE_BGRA4444: + case VG_LITE_ABGR4444: + case VG_LITE_ARGB4444: + case VG_LITE_RGB565: + case VG_LITE_BGR565: + case VG_LITE_BGRA5551: + case VG_LITE_RGBA5551: + case VG_LITE_ABGR1555: + case VG_LITE_ARGB1555: + case VG_LITE_YUYV: + case VG_LITE_YUY2: + case VG_LITE_NV12: + case VG_LITE_YV12: + case VG_LITE_YV24: + case VG_LITE_YV16: + case VG_LITE_NV16: + case VG_LITE_NV24: + case VG_LITE_ABGR8565_PLANAR: + case VG_LITE_BGRA5658_PLANAR: + case VG_LITE_ARGB8565_PLANAR: + case VG_LITE_RGBA5658_PLANAR: + FORMAT_ALIGNMENT(stride, 32); + break; + + case VG_LITE_RGB888: + case VG_LITE_BGR888: + case VG_LITE_ABGR8565: + case VG_LITE_BGRA5658: + case VG_LITE_ARGB8565: + case VG_LITE_RGBA5658: + FORMAT_ALIGNMENT(stride, 48); + break; + + case VG_LITE_RGBA8888: + case VG_LITE_BGRA8888: + case VG_LITE_ABGR8888: + case VG_LITE_ARGB8888: + case VG_LITE_RGBX8888: + case VG_LITE_BGRX8888: + case VG_LITE_XBGR8888: + case VG_LITE_XRGB8888: + FORMAT_ALIGNMENT(stride, 64); + break; + + default: + return VG_LITE_SUCCESS; + } +} +#endif + +#if gcFEATURE_VG_SRC_BUF_ALINGED +static vg_lite_error_t _check_source_aligned_2(vg_lite_buffer_format_t format, uint32_t stride) +{ + switch(format) { + case VG_LITE_A4: + case VG_LITE_A8: + case VG_LITE_L8: + case VG_LITE_INDEX_1: + case VG_LITE_INDEX_2: + case VG_LITE_INDEX_4: + case VG_LITE_INDEX_8: + case VG_LITE_RGBA2222: + case VG_LITE_BGRA2222: + case VG_LITE_ABGR2222: + case VG_LITE_ARGB2222: + case VG_LITE_RGBA8888_ETC2_EAC: + FORMAT_ALIGNMENT(stride, 1); + break; + + case VG_LITE_RGBA4444: + case VG_LITE_BGRA4444: + case VG_LITE_ABGR4444: + case VG_LITE_ARGB4444: + case VG_LITE_RGB565: + case VG_LITE_BGR565: + case VG_LITE_BGRA5551: + case VG_LITE_RGBA5551: + case VG_LITE_ABGR1555: + case VG_LITE_ARGB1555: + case VG_LITE_YV16: + case VG_LITE_NV16: + case VG_LITE_YV12: + case VG_LITE_NV12: + case VG_LITE_YV24: + case VG_LITE_ABGR8565_PLANAR: + case VG_LITE_BGRA5658_PLANAR: + case VG_LITE_ARGB8565_PLANAR: + case VG_LITE_RGBA5658_PLANAR: + FORMAT_ALIGNMENT(stride, 2); + break; + + case VG_LITE_RGB888: + case VG_LITE_BGR888: + case VG_LITE_ABGR8565: + case VG_LITE_BGRA5658: + case VG_LITE_ARGB8565: + case VG_LITE_RGBA5658: + FORMAT_ALIGNMENT(stride, 3); + break; + + case VG_LITE_YUY2: + case VG_LITE_RGBA8888: + case VG_LITE_BGRA8888: + case VG_LITE_ABGR8888: + case VG_LITE_ARGB8888: + case VG_LITE_RGBX8888: + case VG_LITE_BGRX8888: + case VG_LITE_XBGR8888: + case VG_LITE_XRGB8888: + FORMAT_ALIGNMENT(stride, 4); + break; + + default: + return VG_LITE_SUCCESS; + } +} + +static vg_lite_error_t _check_source_aligned_3(vg_lite_buffer_format_t format, uint32_t stride) +{ + switch(format) { + case VG_LITE_INDEX_1: + case VG_LITE_INDEX_2: + FORMAT_ALIGNMENT(stride, 1); + break; + + case VG_LITE_A4: + case VG_LITE_INDEX_4: + FORMAT_ALIGNMENT(stride, 2); + break; + + case VG_LITE_A8: + case VG_LITE_L8: + case VG_LITE_YV24: + case VG_LITE_INDEX_8: + case VG_LITE_RGBA2222: + case VG_LITE_BGRA2222: + case VG_LITE_ABGR2222: + case VG_LITE_ARGB2222: + case VG_LITE_RGBA8888_ETC2_EAC: + FORMAT_ALIGNMENT(stride, 4); + break; + + case VG_LITE_RGBA4444: + case VG_LITE_BGRA4444: + case VG_LITE_ABGR4444: + case VG_LITE_ARGB4444: + case VG_LITE_BGRA5551: + case VG_LITE_RGBA5551: + case VG_LITE_ABGR1555: + case VG_LITE_ARGB1555: + case VG_LITE_RGB565: + case VG_LITE_BGR565: + case VG_LITE_YUY2: + case VG_LITE_YV12: + case VG_LITE_NV12: + case VG_LITE_ABGR8565_PLANAR: + case VG_LITE_BGRA5658_PLANAR: + case VG_LITE_ARGB8565_PLANAR: + case VG_LITE_RGBA5658_PLANAR: + FORMAT_ALIGNMENT(stride, 8); + break; + + case VG_LITE_RGB888: + case VG_LITE_BGR888: + case VG_LITE_ABGR8565: + case VG_LITE_BGRA5658: + case VG_LITE_ARGB8565: + case VG_LITE_RGBA5658: + FORMAT_ALIGNMENT(stride, 12); + break; + + case VG_LITE_RGBA8888: + case VG_LITE_BGRA8888: + case VG_LITE_ABGR8888: + case VG_LITE_ARGB8888: + case VG_LITE_RGBX8888: + case VG_LITE_BGRX8888: + case VG_LITE_XBGR8888: + case VG_LITE_XRGB8888: + FORMAT_ALIGNMENT(stride, 16); + break; + + default: + return VG_LITE_SUCCESS; + } +} +#endif + +#if gcFEATURE_VG_FORMAT_SUPPORT_CHECK +static vg_lite_error_t _check_format_support_1(vg_lite_buffer_format_t format) +{ + switch(format) { + case VG_LITE_A8: + case VG_LITE_L8: + case VG_LITE_RGBA2222: + case VG_LITE_BGRA2222: + case VG_LITE_ABGR2222: + case VG_LITE_ARGB2222: + case VG_LITE_RGBA4444: + case VG_LITE_BGRA4444: + case VG_LITE_ABGR4444: + case VG_LITE_ARGB4444: + case VG_LITE_BGRA5551: + case VG_LITE_RGBA5551: + case VG_LITE_ABGR1555: + case VG_LITE_ARGB1555: + case VG_LITE_RGB565: + case VG_LITE_BGR565: + case VG_LITE_RGB888: + case VG_LITE_BGR888: + case VG_LITE_ABGR8565: + case VG_LITE_BGRA5658: + case VG_LITE_ARGB8565: + case VG_LITE_RGBA5658: + case VG_LITE_RGBA8888: + case VG_LITE_BGRA8888: + case VG_LITE_ABGR8888: + case VG_LITE_ARGB8888: + case VG_LITE_RGBX8888: + case VG_LITE_BGRX8888: + case VG_LITE_XBGR8888: + case VG_LITE_XRGB8888: + break; + default: + return VG_LITE_NOT_SUPPORT; + } + + return VG_LITE_SUCCESS; +} + +static vg_lite_error_t _check_format_support_2(vg_lite_buffer_format_t format) +{ + switch(format) { + case VG_LITE_INDEX_1: + case VG_LITE_INDEX_2: + case VG_LITE_INDEX_4: + case VG_LITE_INDEX_8: + case VG_LITE_A4: + case VG_LITE_YUY2: + case VG_LITE_YUY2_TILED: + case VG_LITE_RGBA8888_ETC2_EAC: + break; + default: + return VG_LITE_NOT_SUPPORT; + } + + return VG_LITE_SUCCESS; +} +#endif + +vg_lite_error_t srcbuf_align_check(vg_lite_buffer_t * source) +{ + vg_lite_error_t error = VG_LITE_SUCCESS; + +#if gcFEATURE_VG_FORMAT_SUPPORT_CHECK + if(_check_format_support_1(source->format) && _check_format_support_2(source->format)) { + return VG_LITE_NOT_SUPPORT; + } +#endif + +#if gcFEATURE_VG_SRC_ADDRESS_64BYTES_ALIGNED + uint32_t align, mul, div, bpp; + get_format_bytes(source->format, &mul, &div, &align); + bpp = 8 * mul / div; + + if(bpp == 8) { + if((uint32_t)(source->address) % 16 != 0) { + printf("buffer address need to be aglined to 16 bytes."); + return VG_LITE_INVALID_ARGUMENT; + } + } + else if(bpp == 16) { + if((uint32_t)(source->address) % 32 != 0) { + printf("buffer address need to be aglined to 32 bytes."); + return VG_LITE_INVALID_ARGUMENT; + } + } + else if(bpp == 24 || bpp == 32) { + if((uint32_t)(source->address) % 64 != 0) { + printf("buffer address need to be aglined to 64 bytes."); + return VG_LITE_INVALID_ARGUMENT; + } + } + else { + if((uint32_t)(source->address) % 8 != 0) { + printf("buffer address need to be aglined to 8 bytes."); + return VG_LITE_INVALID_ARGUMENT; + } + } +#endif + +#if gcFEATURE_VG_SRC_BUF_ALINGED +#if gcFEATURE_VG_SRC_ADDRESS_16BYTES_ALIGNED + if(source->format == VG_LITE_ARGB8888 || + source->format == VG_LITE_BGRA8888 || + source->format == VG_LITE_ABGR8888 || + source->format == VG_LITE_ARGB8888 + ) { + if((uint32_t)(source->address) % 16 != 0) { + printf("buffer address need to be aglined to 16 bytes."); + return VG_LITE_INVALID_ARGUMENT; + } + } + else +#endif + { + if((uint32_t)(source->address) % 8 != 0) { + printf("buffer address need to be aglined to 8 bytes."); + return VG_LITE_INVALID_ARGUMENT; + } + } +#endif + + if(source->tiled == VG_LITE_TILED) { +#if gcFEATURE_VG_SRC_TILE_4PIXELS_ALIGNED + uint32_t align, mul, div; + get_format_bytes(source->format, &mul, &div, &align); + if((source->stride % (4 * mul / div) != 0) || (source->height % 4 != 0)) { + return VG_LITE_INVALID_ARGUMENT; + } +#endif + +#if gcFEATURE_VG_SRC_BUF_ALINGED + vg_lite_error_t error; + error = _check_source_aligned_3(source->format, source->stride); + if(error != VG_LITE_SUCCESS) { + return VG_LITE_INVALID_ARGUMENT; + } +#endif + +#if gcFEATURE_VG_YUV_ALIGNED_CHECK + if(source->format == VG_LITE_YUY2) { + if(source->address % 32 != 0) { + return VG_LITE_INVALID_ARGUMENT; + } + + if(source->tiled) { + if(source->stride % 8 != 0) { + return VG_LITE_INVALID_ARGUMENT; + } + } + else { + if(source->stride % 32 != 0) { + return VG_LITE_INVALID_ARGUMENT; + } + } + } +#endif + } + + if(source->tiled == VG_LITE_LINEAR) { +#if gcFEATURE_VG_16PIXELS_ALIGNED + uint32_t align, mul, div; + get_format_bytes(source->format, &mul, &div, &align); + if(source->stride % (16 * mul / div) != 0) { + return VG_LITE_INVALID_ARGUMENT; + } +#endif + +#if gcFEATURE_VG_SRC_BUF_ALINGED + vg_lite_error_t error; + error = _check_source_aligned_2(source->format, source->stride); + if(error != VG_LITE_SUCCESS) { + return VG_LITE_INVALID_ARGUMENT; + } +#endif + +#if gcFEATURE_VG_YUV_ALIGNED_CHECK + if(source->format == VG_LITE_NV12 || source->format == VG_LITE_NV16) { + if(source->address % 32 != 0 || source->stride % 32 != 0) { + return VG_LITE_INVALID_ARGUMENT; + } + + if(source->yuv.uv_planar % 32 != 0 || source->yuv.uv_stride % 32 != 0) { + return VG_LITE_INVALID_ARGUMENT; + } + } + + if(source->format == VG_LITE_YV12 || source->format == VG_LITE_YV16) { + if(source->address % 32 != 0 || source->stride % 32 != 0) { + return VG_LITE_INVALID_ARGUMENT; + } + + if(source->yuv.uv_planar % 16 != 0 || source->yuv.uv_stride % 16 != 0) { + return VG_LITE_INVALID_ARGUMENT; + } + + if(source->yuv.v_planar % 16 != 0 || source->yuv.v_stride % 16 != 0) { + return VG_LITE_INVALID_ARGUMENT; + } + } + + if(source->format == VG_LITE_YV24) { + if(source->address % 32 != 0 || source->stride % 32 != 0) { + return VG_LITE_INVALID_ARGUMENT; + } + + if(source->yuv.uv_planar % 32 != 0 || source->yuv.uv_stride % 32 != 0) { + return VG_LITE_INVALID_ARGUMENT; + } + + if(source->yuv.v_planar % 32 != 0 || source->yuv.v_stride % 32 != 0) { + return VG_LITE_INVALID_ARGUMENT; + } + } +#endif + } + + + if(source->compress_mode != VG_LITE_DEC_DISABLE) { +#if (gcFEATURE_VG_DEC_COMPRESS || gcFEATURE_VG_DEC_COMPRESS_2_0) +#if gcFEATURE_VG_DEC_COMPRESS_2_0 + if(source->format == VG_LITE_BGRA8888 || source->format == VG_LITE_BGRX8888) { + if((source->stride * source->height) % 64 != 0) { + return VG_LITE_INVALID_ARGUMENT; + } + } + + if(source->format == VG_LITE_BGR888) { + if((source->stride * source->height) % 48 != 0) { + return VG_LITE_INVALID_ARGUMENT; + } + } +#else + if(source->format == VG_LITE_BGRX8888 || source->format == VG_LITE_RGBX8888 + || source->format == VG_LITE_BGRA8888 || source->format == VG_LITE_RGBA8888) { + if((source->stride * source->height) % 64 != 0) { + return VG_LITE_INVALID_ARGUMENT; + } + } + + if(source->format == VG_LITE_RGB888 || source->format == VG_LITE_BGR888) { + if((source->stride * source->height) % 48 != 0) { + return VG_LITE_INVALID_ARGUMENT; + } + } +#endif +#endif + } + + return error; +} + +vg_lite_error_t dstbuf_align_check(vg_lite_buffer_t * target) +{ + vg_lite_error_t error = VG_LITE_SUCCESS; + uint32_t align, mul, div, bpp; + uint32_t tile_flag = 0; + uint32_t tile_flag1 = 0; + get_format_bytes(target->format, &mul, &div, &align); + bpp = 8 * mul / div; + +#if gcFEATURE_VG_FORMAT_SUPPORT_CHECK + if(_check_format_support_1(target->format)) { + return VG_LITE_NOT_SUPPORT; + } +#endif + +#if gcFEATURE_VG_DST_TILE_4PIXELS_ALIGNED + if(target->tiled == VG_LITE_TILED) { + if((target->stride % (4 * mul / div) != 0) || (target->height % 4 != 0)) { + return VG_LITE_INVALID_ARGUMENT; + } + } +#endif + + if(target->compress_mode == VG_LITE_DEC_DISABLE) { +#if gcFEATURE_VG_DST_BUF_ALIGNED + if(target->tiled == VG_LITE_TILED) { + if(bpp == 8 || bpp == 16 || bpp == 32) { + if(target->stride % (4 * mul / div)) { + return VG_LITE_INVALID_ARGUMENT; + } + } + + if(target->format >= VG_LITE_RGB888 && target->format <= VG_LITE_RGBA5658) { + if(target->stride % 12 != 0) { + return VG_LITE_INVALID_ARGUMENT; + } + } + + if(target->format >= VG_LITE_ABGR8565_PLANAR && target->format <= VG_LITE_RGBA5658_PLANAR) { + if(target->stride % 8 != 0) { + return VG_LITE_INVALID_ARGUMENT; + } + } + } + else { + if(bpp == 8 || bpp == 16 || bpp == 32) { + if(target->stride % (mul / div)) { + return VG_LITE_INVALID_ARGUMENT; + } + } + + if(target->format >= VG_LITE_RGB888 && target->format <= VG_LITE_RGBA5658) { + if(target->stride % 3 != 0) { + return VG_LITE_INVALID_ARGUMENT; + } + } + + if(target->format >= VG_LITE_ABGR8565_PLANAR && target->format <= VG_LITE_RGBA5658_PLANAR) { + if(target->stride % 2 != 0) { + return VG_LITE_INVALID_ARGUMENT; + } + } + } + + if(bpp == 8 || bpp == 16 || bpp == 32) { + if((uint32_t)(target->address) % 4 != 0) { + return VG_LITE_INVALID_ARGUMENT; + } + } + + if(target->format >= VG_LITE_RGB888 && target->format <= VG_LITE_RGBA5658) { + if((uint32_t)(target->address) % 64 != 0) { + return VG_LITE_INVALID_ARGUMENT; + } + } +#endif + +#if gcFEATURE_VG_DST_ADDRESS_64BYTES_ALIGNED + if((uint32_t)(target->address) % 64 != 0) { + return VG_LITE_INVALID_ARGUMENT; + } +#endif + +#if gcFEATURE_VG_DST_24BIT_PLANAR_ALIGNED + if(target->format >= VG_LITE_ABGR8565_PLANAR && target->format <= VG_LITE_RGBA5658_PLANAR) { + if((uint32_t)(target->address) % 32 != 0) { + return VG_LITE_INVALID_ARGUMENT; + } + if((uint32_t)(target->yuv.alpha_planar) % 16 != 0) { + return VG_LITE_INVALID_ARGUMENT; + } + } +#endif + } + else { +#if (gcFEATURE_VG_DEC_COMPRESS || gcFEATURE_VG_DEC_COMPRESS_2_0) + if((uint32_t)(target->address) % 64 != 0) { + printf("target address need to be aligned to 64 bytes."); + return VG_LITE_INVALID_ARGUMENT; + } + +#if gcFEATURE_VG_DEC_COMPRESS_2_0 + if(target->format == VG_LITE_BGRA8888 || target->format == VG_LITE_BGRX8888) { + if((target->stride * target->height) % 64 != 0) { + return VG_LITE_INVALID_ARGUMENT; + } + } + + if(target->format == VG_LITE_BGR888) { + if((target->stride * target->height) % 48 != 0) { + return VG_LITE_INVALID_ARGUMENT; + } + } +#else + if(target->format == VG_LITE_BGRX8888 || target->format == VG_LITE_RGBX8888 + || target->format == VG_LITE_BGRA8888 || target->format == VG_LITE_RGBA8888) { + if((target->stride * target->height) % 64 != 0) { + return VG_LITE_INVALID_ARGUMENT; + } + } + + if(target->format == VG_LITE_RGB888 || target->format == VG_LITE_BGR888) { + if((target->stride * target->height) % 48 != 0) { + return VG_LITE_INVALID_ARGUMENT; + } + } +#endif +#endif + } + + if(target->tiled == VG_LITE_TILED) { +#if gcFEATURE_VG_RECTANGLE_TILED_OUT + tile_flag1 = 1; +#else + tile_flag1 = 0; +#endif + tile_flag = 1; + } + +#if (gcFEATURE_VG_TILED_LIMIT == 1) + if(tile_flag1 ^ tile_flag) { + if(bpp != 24) { + if(target->stride % 64 != 0) { + return VG_LITE_INVALID_ARGUMENT; + } + } + else { + if(target->stride % 48 != 0) { + return VG_LITE_INVALID_ARGUMENT; + } + } + } +#elif (gcFEATURE_VG_TILED_LIMIT == 2) + if(tile_flag1 ^ tile_flag) { + return VG_LITE_INVALID_ARGUMENT; + } +#elif (gcFEATURE_VG_TILED_LIMIT == 3) + if(target->address % 4 != 0) { + return VG_LITE_INVALID_ARGUMENT; + } + + if(target->stride % (mul / div) != 0) { + return VG_LITE_INVALID_ARGUMENT; + } + + if(target->compress_mode || bpp == 24) { + if(target->address % 64 != 0) { + return VG_LITE_INVALID_ARGUMENT; + } + } + if(target->tiled) { + if(bpp != 24) { + if(target->stride % 16 != 0) { + return VG_LITE_INVALID_ARGUMENT; + } + } + else { + if(target->stride % 12 != 0) { + return VG_LITE_INVALID_ARGUMENT; + } + } + if(target->address % 64 != 0) { + return VG_LITE_INVALID_ARGUMENT; + } + } + + if(tile_flag1 ^ tile_flag) { + if(target->address % 64 != 0) { + return VG_LITE_INVALID_ARGUMENT; + } + if(bpp != 24) { + if(target->stride % 64 != 0) { + return VG_LITE_INVALID_ARGUMENT; + } + } + else { + if(target->stride % 48 != 0) { + return VG_LITE_INVALID_ARGUMENT; + } + } + } +#endif + return error; +} + + +/* Convert VGLite source color format to HW values. */ +uint32_t convert_source_format(vg_lite_buffer_format_t format) +{ + switch(format) { + case VG_LITE_L8: + return 0x0; + + case VG_LITE_A4: + return 0x1; + + case VG_LITE_A8: + return 0x2; + + case VG_LITE_RGBA4444: + return 0x23; + + case VG_LITE_BGRA4444: + return 0x3; + + case VG_LITE_ABGR4444: + return 0x13; + + case VG_LITE_ARGB4444: + return 0x33; + + case VG_LITE_RGB565: + return 0x25; + + case VG_LITE_BGR565: + return 0x5; + + case VG_LITE_RGBA8888: + return 0x27; + + case VG_LITE_BGRA8888: + return 0x7; + + case VG_LITE_ABGR8888: + return 0x17; + + case VG_LITE_ARGB8888: + return 0x37; + + case VG_LITE_RGBX8888: + return 0x26; + + case VG_LITE_BGRX8888: + return 0x6; + + case VG_LITE_XBGR8888: + return 0x16; + + case VG_LITE_XRGB8888: + return 0x36; + + case VG_LITE_BGRA5551: + return 0x4; + + case VG_LITE_RGBA5551: + return 0x24; + + case VG_LITE_ABGR1555: + return 0x14; + + case VG_LITE_ARGB1555: + return 0x34; + + case VG_LITE_YUYV: + return 0x8; + + case VG_LITE_YUY2: + case VG_LITE_YUY2_TILED: + return 0x8; + + case VG_LITE_NV12: + case VG_LITE_NV12_TILED: + return 0xB; + + case VG_LITE_ANV12: + case VG_LITE_ANV12_TILED: + return 0xE; + + case VG_LITE_YV12: + return 0x9; + + case VG_LITE_YV24: + return 0xD; + + case VG_LITE_YV16: + return 0xC; + + case VG_LITE_NV16: + return 0xA; + + case VG_LITE_NV24: + case VG_LITE_NV24_TILED: + return 0xD | (1 << 19); + + case VG_LITE_AYUY2: + case VG_LITE_AYUY2_TILED: + return 0xF; + + case VG_LITE_INDEX_1: + return 0x200; + + case VG_LITE_INDEX_2: + return 0x400; + + case VG_LITE_INDEX_4: + return 0x600; + + case VG_LITE_INDEX_8: + return 0x800; + + case VG_LITE_RGBA2222: + return 0xA20; + + case VG_LITE_BGRA2222: + return 0xA00; + + case VG_LITE_ABGR2222: + return 0xA10; + + case VG_LITE_ARGB2222: + return 0xA30; + + case VG_LITE_RGBA8888_ETC2_EAC: + return 0xE00; + + case VG_LITE_ARGB8565: + return 0x40000030; + + case VG_LITE_RGBA5658: + return 0x40000020; + + case VG_LITE_ABGR8565: + return 0x40000010; + + case VG_LITE_BGRA5658: + return 0x40000000; + + case VG_LITE_RGB888: + return 0x20000020; + + case VG_LITE_BGR888: + return 0x20000000; + + case VG_LITE_ARGB8565_PLANAR: + return 0x60000030; + + case VG_LITE_RGBA5658_PLANAR: + return 0x60000020; + + case VG_LITE_ABGR8565_PLANAR: + return 0x60000010; + + case VG_LITE_BGRA5658_PLANAR: + return 0x60000000; + + /* OpenVG VGImageFormat */ + case OPENVG_sRGBX_8888: + case OPENVG_sRGBX_8888_PRE: + return 0x16; + break; + + case OPENVG_sRGBA_8888: + case OPENVG_sRGBA_8888_PRE: + return 0x17; + break; + + case OPENVG_sRGB_565: + case OPENVG_sRGB_565_PRE: + return 0x5; + break; + + case OPENVG_sRGBA_5551: + case OPENVG_sRGBA_5551_PRE: + return 0x14; + break; + + case OPENVG_sRGBA_4444: + case OPENVG_sRGBA_4444_PRE: + return 0x13; + break; + + case OPENVG_sL_8: + return 0x0; + break; + + case OPENVG_lRGBX_8888: + case OPENVG_lRGBX_8888_PRE: + return 0x16; + break; + + case OPENVG_lRGBA_8888: + case OPENVG_lRGBA_8888_PRE: + return 0x17; + break; + + case OPENVG_lRGB_565: + case OPENVG_lRGB_565_PRE: + return 0x5; + break; + + case OPENVG_lRGBA_5551: + case OPENVG_lRGBA_5551_PRE: + return 0x14; + break; + + case OPENVG_lRGBA_4444: + case OPENVG_lRGBA_4444_PRE: + return 0x13; + break; + + case OPENVG_lL_8: + return 0x0; + break; + + case OPENVG_A_8: + return 0x2; + break; + + case OPENVG_BW_1: + return 0x200; + break; + + case OPENVG_A_1: + return 0x1; + break; + + case OPENVG_A_4: + return 0x1; + break; + + case OPENVG_sXRGB_8888: + return 0x6; + break; + + case OPENVG_sARGB_8888: + return 0x7; + break; + + case OPENVG_sARGB_8888_PRE: + return 0x7; + break; + + case OPENVG_sARGB_1555: + return 0x4; + break; + + case OPENVG_sARGB_4444: + return 0x3; + break; + + case OPENVG_lXRGB_8888: + return 0x6; + break; + + case OPENVG_lARGB_8888: + return 0x7; + break; + case OPENVG_lARGB_8888_PRE: + return 0x7; + break; + + case OPENVG_sBGRX_8888: + return 0x36; + break; + + case OPENVG_sBGRA_8888: + return 0x37; + break; + + case OPENVG_sBGRA_8888_PRE: + return 0x37; + break; + + case OPENVG_sBGR_565: + return 0x25; + break; + + case OPENVG_sBGRA_5551: + return 0x34; + break; + + case OPENVG_sBGRA_4444: + return 0x33; + break; + + case OPENVG_lBGRX_8888: + return 0x36; + break; + + case OPENVG_lBGRA_8888: + return 0x37; + break; + + case OPENVG_lBGRA_8888_PRE: + return 0x37; + break; + + case OPENVG_sXBGR_8888: + return 0x26; + break; + + case OPENVG_sABGR_8888: + return 0x27; + break; + + case OPENVG_sABGR_8888_PRE: + return 0x27; + break; + + case OPENVG_sABGR_1555: + return 0x24; + break; + + case OPENVG_sABGR_4444: + return 0x23; + break; + + case OPENVG_lXBGR_8888: + return 0x26; + break; + + case OPENVG_lABGR_8888: + return 0x27; + break; + + case OPENVG_lABGR_8888_PRE: + return 0x27; + break; + + default: + return 0; + break; + } +} + +/* Convert VGLite blend modes to HW values. */ +uint32_t convert_blend(vg_lite_blend_t blend) +{ + switch(blend) { + case VG_LITE_BLEND_SRC_OVER: + case VG_LITE_BLEND_NORMAL_LVGL: + case OPENVG_BLEND_SRC_OVER: + return 0x00000100; + + case VG_LITE_BLEND_DST_OVER: + case OPENVG_BLEND_DST_OVER: + return 0x00000200; + + case VG_LITE_BLEND_SRC_IN: + case OPENVG_BLEND_SRC_IN: + return 0x00000300; + + case VG_LITE_BLEND_DST_IN: + case OPENVG_BLEND_DST_IN: + return 0x00000400; + + case VG_LITE_BLEND_MULTIPLY: + case VG_LITE_BLEND_MULTIPLY_LVGL: + case OPENVG_BLEND_MULTIPLY: + return 0x00000500; + + case VG_LITE_BLEND_SCREEN: + case OPENVG_BLEND_SCREEN: + return 0x00000600; + + case VG_LITE_BLEND_DARKEN: + case OPENVG_BLEND_DARKEN: + return 0x00000700; + + case VG_LITE_BLEND_LIGHTEN: + case OPENVG_BLEND_LIGHTEN: + return 0x00000800; + + case VG_LITE_BLEND_ADDITIVE: + case VG_LITE_BLEND_ADDITIVE_LVGL: + case OPENVG_BLEND_ADDITIVE: + return 0x00000900; + + case VG_LITE_BLEND_SUBTRACT: + return 0x00000A00; + + case VG_LITE_BLEND_SUBTRACT_LVGL: +#if gcFEATURE_VG_LVGL_SUPPORT + return 0x00000C00; +#else + return 0x00000A00; +#endif + + default: + return 0; + } +} + +/* Convert VGLite uv swizzle enums to HW values. */ +uint32_t convert_uv_swizzle(vg_lite_swizzle_t swizzle) +{ + switch(swizzle) { + case VG_LITE_SWIZZLE_UV: + return 0x00000040; + break; + + case VG_LITE_SWIZZLE_VU: + return 0x00000050; + + default: + return 0; + break; + } +} + +/* Convert VGLite yuv standard enums to HW values. */ +uint32_t convert_yuv2rgb(vg_lite_yuv2rgb_t yuv) +{ + switch(yuv) { + case VG_LITE_YUV601: + return 0; + break; + + case VG_LITE_YUV709: + return 0x00008000; + + default: + return 0; + break; + } +} + +static vg_lite_error_t submit(vg_lite_context_t * context); +static vg_lite_error_t stall(vg_lite_context_t * context, uint32_t time_ms, uint32_t mask); + +/* Push a state array into current command buffer. */ +vg_lite_error_t push_clut(vg_lite_context_t * context, uint32_t address, uint32_t count, uint32_t * data) +{ + uint32_t i; + vg_lite_error_t error; + if(!has_valid_command_buffer(context)) + return VG_LITE_NO_CONTEXT; + + if(CMDBUF_OFFSET(*context) + 8 + VG_LITE_ALIGN(count + 1, 2) * 4 >= CMDBUF_SIZE(*context)) { + VG_LITE_RETURN_ERROR(submit(context)); + VG_LITE_RETURN_ERROR(stall(context, 0, (uint32_t)~0)); + } + + ((uint32_t *)(CMDBUF_BUFFER(*context) + CMDBUF_OFFSET(*context)))[0] = VG_LITE_STATES(count, address); + + for(i = 0; i < count; i++) { + ((uint32_t *)(CMDBUF_BUFFER(*context) + CMDBUF_OFFSET(*context)))[1 + i] = data[i]; + } + if(i % 2 == 0) { + ((uint32_t *)(CMDBUF_BUFFER(*context) + CMDBUF_OFFSET(*context)))[1 + i] = VG_LITE_NOP(); + } + +#if DUMP_COMMAND + { + uint32_t loops; + if(strncmp(filename, "Commandbuffer", 13)) { + sprintf(filename, "Commandbuffer_pid%d.txt", getpid()); + } + + fp = fopen(filename, "a"); + + if(fp == NULL) + printf("error!\n"); + + fprintf(fp, "Command buffer: 0x%08x, ", + ((uint32_t *)(CMDBUF_BUFFER(*context) + CMDBUF_OFFSET(*context)))[0]); + + for(loops = 0; loops < count / 2; loops++) { + fprintf(fp, "0x%08x,\nCommand buffer: 0x%08x, ", + ((uint32_t *)(CMDBUF_BUFFER(*context) + CMDBUF_OFFSET(*context)))[(loops + 1) * 2 - 1], + ((uint32_t *)(CMDBUF_BUFFER(*context) + CMDBUF_OFFSET(*context)))[(loops + 1) * 2]); + } + + fprintf(fp, "0x%08x,\n", + ((uint32_t *)(CMDBUF_BUFFER(*context) + CMDBUF_OFFSET(*context)))[(loops + 1) * 2 - 1]); + + fclose(fp); + fp = NULL; + } +#endif + + CMDBUF_OFFSET(*context) += VG_LITE_ALIGN(count + 1, 2) * 4; + + return VG_LITE_SUCCESS; +} + +/* Push a single state command into the current command buffer. */ +vg_lite_error_t push_state(vg_lite_context_t * context, uint32_t address, uint32_t data) +{ + vg_lite_error_t error; + if(!has_valid_command_buffer(context)) + return VG_LITE_NO_CONTEXT; + + /* TODO wait for hw to complete development. */ + /* if (address == 0x0A1B || context->hw.hw_states[address & 0xff].state != data || !context->hw.hw_states[address & 0xff].init) */ + { + if(CMDBUF_OFFSET(*context) + 16 >= CMDBUF_SIZE(*context)) { + VG_LITE_RETURN_ERROR(submit(context)); + VG_LITE_RETURN_ERROR(stall(context, 0, (uint32_t)~0)); + } + + /* TODO context->hw.hw_states[address & 0xff].state = data; + context->hw.hw_states[address & 0xff].init = 1;*/ + + ((uint32_t *)(CMDBUF_BUFFER(*context) + CMDBUF_OFFSET(*context)))[0] = VG_LITE_STATE(address); + ((uint32_t *)(CMDBUF_BUFFER(*context) + CMDBUF_OFFSET(*context)))[1] = data; + +#if DUMP_COMMAND + if(strncmp(filename, "Commandbuffer", 13)) { + sprintf(filename, "Commandbuffer_pid%d.txt", getpid()); + } + + fp = fopen(filename, "a"); + + if(fp == NULL) + printf("error!\n"); + + fprintf(fp, "Command buffer: 0x%08x, 0x%08x,\n", + ((uint32_t *)(CMDBUF_BUFFER(*context) + CMDBUF_OFFSET(*context)))[0], + ((uint32_t *)(CMDBUF_BUFFER(*context) + CMDBUF_OFFSET(*context)))[1]); + + fclose(fp); + fp = NULL; +#endif + + CMDBUF_OFFSET(*context) += 8; + } + + return VG_LITE_SUCCESS; +} + +/* Push a single state command with given address. */ +vg_lite_error_t push_state_ptr(vg_lite_context_t * context, uint32_t address, void * data_ptr) +{ + vg_lite_error_t error; + uint32_t data = *(uint32_t *) data_ptr; + if(!has_valid_command_buffer(context)) + return VG_LITE_NO_CONTEXT; + + /* TODO wait for hw to complete development. */ + /* if (address == 0x0A1B || context->hw.hw_states[address & 0xff].state != data || !context->hw.hw_states[address & 0xff].init) */ + { + if(CMDBUF_OFFSET(*context) + 16 >= CMDBUF_SIZE(*context)) { + VG_LITE_RETURN_ERROR(submit(context)); + VG_LITE_RETURN_ERROR(stall(context, 0, (uint32_t)~0)); + } + + /* TODO context->hw.hw_states[address & 0xff].state = data; + context->hw.hw_states[address & 0xff].init = 1;*/ + + ((uint32_t *)(CMDBUF_BUFFER(*context) + CMDBUF_OFFSET(*context)))[0] = VG_LITE_STATE(address); + ((uint32_t *)(CMDBUF_BUFFER(*context) + CMDBUF_OFFSET(*context)))[1] = data; + +#if DUMP_COMMAND + if(strncmp(filename, "Commandbuffer", 13)) { + sprintf(filename, "Commandbuffer_pid%d.txt", getpid()); + } + + fp = fopen(filename, "a"); + + if(fp == NULL) + printf("error!\n"); + fprintf(fp, "Command buffer: 0x%08x, 0x%08x,\n", + ((uint32_t *)(CMDBUF_BUFFER(*context) + CMDBUF_OFFSET(*context)))[0], + ((uint32_t *)(CMDBUF_BUFFER(*context) + CMDBUF_OFFSET(*context)))[1]); + + fclose(fp); + fp = NULL; +#endif + + CMDBUF_OFFSET(*context) += 8; + } + + return VG_LITE_SUCCESS; +} + +/* Push a "call" command into the current command buffer. */ +vg_lite_error_t push_call(vg_lite_context_t * context, uint32_t address, uint32_t bytes) +{ + vg_lite_error_t error; + if(!has_valid_command_buffer(context)) + return VG_LITE_NO_CONTEXT; + + if(CMDBUF_OFFSET(*context) + 16 >= CMDBUF_SIZE(*context)) { + VG_LITE_RETURN_ERROR(submit(context)); + VG_LITE_RETURN_ERROR(stall(context, 0, (uint32_t)~0)); + } + + ((uint32_t *)(CMDBUF_BUFFER(*context) + CMDBUF_OFFSET(*context)))[0] = VG_LITE_CALL((bytes + 7) / 8); + ((uint32_t *)(CMDBUF_BUFFER(*context) + CMDBUF_OFFSET(*context)))[1] = address; + +#if DUMP_COMMAND + if(strncmp(filename, "Commandbuffer", 13)) { + sprintf(filename, "Commandbuffer_pid%d.txt", getpid()); + } + + fp = fopen(filename, "a"); + + if(fp == NULL) + printf("error!\n"); + fprintf(fp, "Command buffer: 0x%08x, 0x%08x,\n", + ((uint32_t *)(CMDBUF_BUFFER(*context) + CMDBUF_OFFSET(*context)))[0], + ((uint32_t *)(CMDBUF_BUFFER(*context) + CMDBUF_OFFSET(*context)))[1]); + + fclose(fp); + fp = NULL; +#endif + + CMDBUF_OFFSET(*context) += 8; + +#if !gcFEATURE_VG_CMD_CALL_FIX + VG_LITE_RETURN_ERROR(push_stall(&s_context, 0x10)); +#endif + + return VG_LITE_SUCCESS; +} + +#if gcFEATURE_VG_PE_CLEAR +static vg_lite_error_t push_pe_clear(vg_lite_context_t * context, uint32_t size) +{ + vg_lite_error_t error; + if(!has_valid_command_buffer(context)) + return VG_LITE_NO_CONTEXT; + + if(CMDBUF_OFFSET(*context) + 16 >= CMDBUF_SIZE(*context)) { + VG_LITE_RETURN_ERROR(submit(context)); + VG_LITE_RETURN_ERROR(stall(context, 0, (uint32_t)~0)); + } + + ((uint32_t *)(CMDBUF_BUFFER(*context) + CMDBUF_OFFSET(*context)))[0] = VG_LITE_DATA(1); + ((uint32_t *)(CMDBUF_BUFFER(*context) + CMDBUF_OFFSET(*context)))[1] = 0; + ((uint32_t *)(CMDBUF_BUFFER(*context) + CMDBUF_OFFSET(*context)))[2] = size; + ((uint32_t *)(CMDBUF_BUFFER(*context) + CMDBUF_OFFSET(*context)))[3] = 0; + + CMDBUF_OFFSET(*context) += 16; + + return VG_LITE_SUCCESS; +} +#endif + +/* Push a rectangle command into the current command buffer. */ +static vg_lite_error_t push_rectangle(vg_lite_context_t * context, int32_t x, int32_t y, int32_t width, int32_t height) +{ + vg_lite_error_t error; + if(!has_valid_command_buffer(context)) + return VG_LITE_NO_CONTEXT; + + if(CMDBUF_OFFSET(*context) + 16 >= CMDBUF_SIZE(*context)) { + VG_LITE_RETURN_ERROR(submit(context)); + VG_LITE_RETURN_ERROR(stall(context, 0, (uint32_t)~0)); + } + + ((uint32_t *)(CMDBUF_BUFFER(*context) + CMDBUF_OFFSET(*context)))[0] = VG_LITE_DATA(1); + ((uint32_t *)(CMDBUF_BUFFER(*context) + CMDBUF_OFFSET(*context)))[1] = 0; + ((uint16_t *)(CMDBUF_BUFFER(*context) + CMDBUF_OFFSET(*context)))[4] = (uint16_t)x; + ((uint16_t *)(CMDBUF_BUFFER(*context) + CMDBUF_OFFSET(*context)))[5] = (uint16_t)y; + ((uint16_t *)(CMDBUF_BUFFER(*context) + CMDBUF_OFFSET(*context)))[6] = (uint16_t)width; + ((uint16_t *)(CMDBUF_BUFFER(*context) + CMDBUF_OFFSET(*context)))[7] = (uint16_t)height; + +#if DUMP_COMMAND + if(strncmp(filename, "Commandbuffer", 13)) { + sprintf(filename, "Commandbuffer_pid%d.txt", getpid()); + } + + fp = fopen(filename, "a"); + + if(fp == NULL) + printf("error!\n"); + + fprintf(fp, "Command buffer: 0x%08x, 0x%08x,\n", + ((uint32_t *)(CMDBUF_BUFFER(*context) + CMDBUF_OFFSET(*context)))[0], 0); + + fprintf(fp, "Command buffer: 0x%08x, 0x%08x,\n", + ((uint16_t *)(CMDBUF_BUFFER(*context) + CMDBUF_OFFSET(*context)))[5] << 16 | + ((uint16_t *)(CMDBUF_BUFFER(*context) + CMDBUF_OFFSET(*context)))[4], + ((uint16_t *)(CMDBUF_BUFFER(*context) + CMDBUF_OFFSET(*context)))[7] << 16 | + ((uint16_t *)(CMDBUF_BUFFER(*context) + CMDBUF_OFFSET(*context)))[6]); + + fclose(fp); + fp = NULL; +#endif + + CMDBUF_OFFSET(*context) += 16; + + return VG_LITE_SUCCESS; +} + +/* Push a data array into the current command buffer. */ +vg_lite_error_t push_data(vg_lite_context_t * context, uint32_t size, void * data) +{ + vg_lite_error_t error; + uint32_t bytes = VG_LITE_ALIGN(size, 8); + + if(!has_valid_command_buffer(context)) + return VG_LITE_NO_CONTEXT; + + if(CMDBUF_OFFSET(*context) + 16 + bytes >= CMDBUF_SIZE(*context)) { + VG_LITE_RETURN_ERROR(submit(context)); + VG_LITE_RETURN_ERROR(stall(context, 0, (uint32_t)~0)); + } + + /* Command buffer size must be at least data size "bytes" plus header and END command */ + if((bytes + 16) > CMDBUF_SIZE(*context)) { + printf("Command buffer size needs increase for data sized %d bytes!\n", (int)(bytes + 16)); + return VG_LITE_OUT_OF_RESOURCES; + } + + ((uint64_t *)(CMDBUF_BUFFER(*context) + CMDBUF_OFFSET(*context)))[(bytes >> 3)] = 0; + ((uint32_t *)(CMDBUF_BUFFER(*context) + CMDBUF_OFFSET(*context)))[0] = VG_LITE_DATA((bytes >> 3)); + ((uint32_t *)(CMDBUF_BUFFER(*context) + CMDBUF_OFFSET(*context)))[1] = 0; + memcpy(CMDBUF_BUFFER(*context) + CMDBUF_OFFSET(*context) + 8, data, size); + +#if DUMP_COMMAND + { + int32_t loops; + + if(strncmp(filename, "Commandbuffer", 13)) { + sprintf(filename, "Commandbuffer_pid%d.txt", getpid()); + } + + fp = fopen(filename, "a"); + + if(fp == NULL) + printf("error!\n"); + + fprintf(fp, "Command buffer: 0x%08x, 0x%08x,\n", + ((uint32_t *)(CMDBUF_BUFFER(*context) + CMDBUF_OFFSET(*context)))[0], 0); + for(loops = 0; loops < (bytes >> 3); loops++) { + fprintf(fp, "Command buffer: 0x%08x, 0x%08x,\n", + ((uint32_t *)(CMDBUF_BUFFER(*context) + CMDBUF_OFFSET(*context)))[(loops + 1) * 2], + ((uint32_t *)(CMDBUF_BUFFER(*context) + CMDBUF_OFFSET(*context)))[(loops + 1) * 2 + 1]); + } + + fclose(fp); + fp = NULL; + } +#endif + + CMDBUF_OFFSET(*context) += 8 + bytes; + + return VG_LITE_SUCCESS; +} + +/* Push a "stall" command into the current command buffer. */ +vg_lite_error_t push_stall(vg_lite_context_t * context, uint32_t module) +{ + vg_lite_error_t error; + if(!has_valid_command_buffer(context)) + return VG_LITE_NO_CONTEXT; + + if(CMDBUF_OFFSET(*context) + 16 >= CMDBUF_SIZE(*context)) { + VG_LITE_RETURN_ERROR(submit(context)); + VG_LITE_RETURN_ERROR(stall(context, 0, (uint32_t)~0)); + } + + ((uint32_t *)(CMDBUF_BUFFER(*context) + CMDBUF_OFFSET(*context)))[0] = VG_LITE_SEMAPHORE(module); + ((uint32_t *)(CMDBUF_BUFFER(*context) + CMDBUF_OFFSET(*context)))[1] = 0; + ((uint32_t *)(CMDBUF_BUFFER(*context) + CMDBUF_OFFSET(*context)))[2] = VG_LITE_STALL(module); + ((uint32_t *)(CMDBUF_BUFFER(*context) + CMDBUF_OFFSET(*context)))[3] = 0; + +#if DUMP_COMMAND + if(strncmp(filename, "Commandbuffer", 13)) { + sprintf(filename, "Commandbuffer_pid%d.txt", getpid()); + } + + fp = fopen(filename, "a"); + + if(fp == NULL) + printf("error!\n"); + + fprintf(fp, "Command buffer: 0x%08x, 0x%08x,\n", + ((uint32_t *)(CMDBUF_BUFFER(*context) + CMDBUF_OFFSET(*context)))[0], 0); + fprintf(fp, "Command buffer: 0x%08x, 0x%08x,\n", + ((uint32_t *)(CMDBUF_BUFFER(*context) + CMDBUF_OFFSET(*context)))[2], 0); + + fclose(fp); + fp = NULL; +#endif + + CMDBUF_OFFSET(*context) += 16; + + return VG_LITE_SUCCESS; +} + +/* Submit the current command buffer to HW and reset the current command buffer offset. */ +static vg_lite_error_t submit(vg_lite_context_t * context) +{ + vg_lite_error_t error = VG_LITE_SUCCESS; + vg_lite_kernel_submit_t submit; + +#if gcdVG_ENABLE_DELAY_RESUME + vg_lite_kernel_delay_resume_t delay_resume; + delay_resume.query_delay_resume = 1; + int resume_flag = vg_lite_kernel(VG_LITE_QUERY_DELAY_RESUME, &delay_resume); + + if(resume_flag == 1) { + /* Reset GPU. */ + vg_lite_kernel_reset_t reset; + reset.delay_resume_flag = 1; + vg_lite_kernel(VG_LITE_RESET, &reset); + printf("Delay resume success! \n"); + +#ifdef __ZEPHYR__ + /* If delay resume is enabled, power and clock would be turned on during the reset process. */ + /* Disable GPU clocking*/ + vg_lite_kernel_gpu_clock_state_t gpu_state; + gpu_state.state = VG_LITE_GPU_STOP; + vg_lite_kernel(VG_LITE_SET_GPU_CLOCK_STATE, &gpu_state); +#endif + } +#endif + + /* Check if there is a valid context and an allocated command buffer. */ + if(!has_valid_command_buffer(context)) + return VG_LITE_NO_CONTEXT; + + /* Check if there is anything to submit. */ + if(CMDBUF_OFFSET(*context) == 0) + return VG_LITE_INVALID_ARGUMENT; + +#if 0 + /* This case is safe as command buffer is allocated with (command_buffer_size + 8) bytes */ + if(CMDBUF_OFFSET(*context) + 8 >= CMDBUF_SIZE(*context)) { + /* Reset command buffer offset. */ + CMDBUF_OFFSET(*context) = 0; + return VG_LITE_OUT_OF_RESOURCES; + } +#endif + + /* Append END command into the command buffer. */ + if(s_context.frame_flag == VG_LITE_FRAME_END_FLAG) { + /* A interrupt will be received to indicate that the GPU is idle. */ + ((uint32_t *)(CMDBUF_BUFFER(*context) + CMDBUF_OFFSET(*context)))[0] = VG_LITE_END(EVENT_FRAME_END); + ((uint32_t *)(CMDBUF_BUFFER(*context) + CMDBUF_OFFSET(*context)))[1] = 0; + } + else { + /* A interrupt will be received to indicate that the GPU has completed the current instruction. */ + ((uint32_t *)(CMDBUF_BUFFER(*context) + CMDBUF_OFFSET(*context)))[0] = VG_LITE_END(EVENT_END); + ((uint32_t *)(CMDBUF_BUFFER(*context) + CMDBUF_OFFSET(*context)))[1] = 0; + } + + s_context.frame_flag = 0; + +#if DUMP_COMMAND + if(strncmp(filename, "Commandbuffer", 13)) { + sprintf(filename, "Commandbuffer_pid%d.txt", getpid()); + } + + fp = fopen(filename, "a"); + + if(fp == NULL) + printf("error!\n"); + + fprintf(fp, "Command buffer: 0x%08x, 0x%08x,\n", + ((uint32_t *)(CMDBUF_BUFFER(*context) + CMDBUF_OFFSET(*context)))[0], 0); + + fprintf(fp, "Command buffer addr is : %p,\n", CMDBUF_BUFFER(*context)); + fprintf(fp, "Command buffer offset is : %d,\n", CMDBUF_OFFSET(*context) + 8); + + fclose(fp); + fp = NULL; +#endif + + CMDBUF_OFFSET(*context) += 8; + + /* Submit the command buffer. */ + submit.context = &context->context; + submit.commands = CMDBUF_BUFFER(*context); + submit.command_size = CMDBUF_OFFSET(*context); + submit.command_id = CMDBUF_INDEX(*context); + +#if DUMP_LAST_CAPTURE + //backup command + context->Physical = (size_t)CMDBUF_BUFFER(*context); + context->last_command_buffer_logical = submit.context->command_buffer_logical[CMDBUF_INDEX(*context)]; + context->last_command_size = submit.command_size; +#endif + /* Wait if GPU has not completed previous CMD buffer */ + if(submit_flag) { + VG_LITE_RETURN_ERROR(stall(&s_context, 0, (uint32_t)~0)); + } + VG_LITE_RETURN_ERROR(vg_lite_kernel(VG_LITE_SUBMIT, &submit)); + + submit_flag = 1; + + vglitemDUMP_BUFFER("command", (size_t)CMDBUF_BUFFER(*context), + submit.context->command_buffer_logical[CMDBUF_INDEX(*context)], 0, submit.command_size); +#if !DUMP_COMMAND_CAPTURE + vglitemDUMP("@[commit]"); +#endif + +#if DUMP_INIT_COMMAND + is_init++; +#endif + + /* Reset command buffer. */ + CMDBUF_OFFSET(*context) = 0; + + return error; +} + +/* Wait for the HW to finish the current execution. */ +static vg_lite_error_t stall(vg_lite_context_t * context, uint32_t time_ms, uint32_t mask) +{ +#if !defined(_WINDLL) + vg_lite_error_t error; +#endif + vg_lite_kernel_wait_t wait; + +#if !DUMP_COMMAND_BY_USER +#if !DUMP_COMMAND_CAPTURE + vglitemDUMP("@[stall]"); +#endif +#endif + + /* Wait until GPU is ready. */ + wait.context = &context->context; + wait.timeout_ms = time_ms > 0 ? time_ms : VG_LITE_INFINITE; + wait.event_mask = mask; + wait.reset_type = RESTORE_ALL_COMMAND; +#if defined(_WINDLL) + vg_lite_kernel(VG_LITE_WAIT, &wait); +#else +#if !DUMP_LAST_CAPTURE + VG_LITE_RETURN_ERROR(vg_lite_kernel(VG_LITE_WAIT, &wait)); +#else + error = vg_lite_kernel(VG_LITE_WAIT, &wait); +#endif +#endif +#if DUMP_LAST_CAPTURE +#if !defined(_WINDLL) + if(error == VG_LITE_TIMEOUT) { + vglitemDUMP_BUFFER_single("command", context->Physical, + context->last_command_buffer_logical, 0, context->last_command_size); + } +#endif +#endif + submit_flag = 0; + return VG_LITE_SUCCESS; +} + +/* Get the inversion of a matrix. */ +uint32_t inverse(vg_lite_matrix_t * result, vg_lite_matrix_t * matrix) +{ + vg_lite_float_t det00, det01, det02; + vg_lite_float_t d; + int32_t isAffine; + + /* Test for identity matrix. */ + if(matrix == NULL) { + result->m[0][0] = 1.0f; + result->m[0][1] = 0.0f; + result->m[0][2] = 0.0f; + result->m[1][0] = 0.0f; + result->m[1][1] = 1.0f; + result->m[1][2] = 0.0f; + result->m[2][0] = 0.0f; + result->m[2][1] = 0.0f; + result->m[2][2] = 1.0f; + + /* Success. */ + return 1; + } + + det00 = (matrix->m[1][1] * matrix->m[2][2]) - (matrix->m[2][1] * matrix->m[1][2]); + det01 = (matrix->m[2][0] * matrix->m[1][2]) - (matrix->m[1][0] * matrix->m[2][2]); + det02 = (matrix->m[1][0] * matrix->m[2][1]) - (matrix->m[2][0] * matrix->m[1][1]); + + /* Compute determinant. */ + d = (matrix->m[0][0] * det00) + (matrix->m[0][1] * det01) + (matrix->m[0][2] * det02); + + /* Return 0 if there is no inverse matrix. */ + if(d == 0.0f) + return 0; + + /* Compute reciprocal. */ + d = 1.0f / d; + + /* Determine if the matrix is affine. */ + isAffine = (matrix->m[2][0] == 0.0f) && (matrix->m[2][1] == 0.0f) && (matrix->m[2][2] == 1.0f); + + result->m[0][0] = d * det00; + result->m[0][1] = d * ((matrix->m[2][1] * matrix->m[0][2]) - (matrix->m[0][1] * matrix->m[2][2])); + result->m[0][2] = d * ((matrix->m[0][1] * matrix->m[1][2]) - (matrix->m[1][1] * matrix->m[0][2])); + result->m[1][0] = d * det01; + result->m[1][1] = d * ((matrix->m[0][0] * matrix->m[2][2]) - (matrix->m[2][0] * matrix->m[0][2])); + result->m[1][2] = d * ((matrix->m[1][0] * matrix->m[0][2]) - (matrix->m[0][0] * matrix->m[1][2])); + result->m[2][0] = isAffine ? 0.0f : d * det02; + result->m[2][1] = isAffine ? 0.0f : d * ((matrix->m[2][0] * matrix->m[0][1]) - (matrix->m[0][0] * matrix->m[2][1])); + result->m[2][2] = isAffine ? 1.0f : d * ((matrix->m[0][0] * matrix->m[1][1]) - (matrix->m[1][0] * matrix->m[0][1])); + + /* Success. */ + return 1; +} + +/* Transform a 2D point by a given matrix. */ +uint32_t transform(vg_lite_point_t * result, vg_lite_float_t x, vg_lite_float_t y, vg_lite_matrix_t * matrix) +{ + vg_lite_float_t pt_x; + vg_lite_float_t pt_y; + vg_lite_float_t pt_w; + + /* Test for identity matrix. */ + if(matrix == NULL) { + result->x = (int)x; + result->y = (int)y; + + /* Success. */ + return 1; + } + + if(((matrix->m[0][1] != 0.0f) || (matrix->m[1][0] != 0.0f) || (matrix->m[2][0] != 0.0f) || (matrix->m[2][1] != 0.0f) || + (matrix->m[2][2] != 1.0f)) && + (s_context.filter == VG_LITE_FILTER_LINEAR || s_context.filter == VG_LITE_FILTER_BI_LINEAR)) { + if(x != 0) { + x = x + 0.5f; + } + + if(y != 0 && s_context.filter == VG_LITE_FILTER_BI_LINEAR) { + y = y + 0.5f; + } + } + + /* Transform x, y, and w. */ + pt_x = (x * matrix->m[0][0]) + (y * matrix->m[0][1]) + matrix->m[0][2]; + pt_y = (x * matrix->m[1][0]) + (y * matrix->m[1][1]) + matrix->m[1][2]; + pt_w = (x * matrix->m[2][0]) + (y * matrix->m[2][1]) + matrix->m[2][2]; + + if(pt_w <= 0.0f) + return 0; + + /* Compute projected x and y. */ + if(pt_x < 0) { + result->x = (int)((pt_x / pt_w) - 0.5f); + } + else { + result->x = (int)((pt_x / pt_w) + 0.5f); + } + if(pt_y < 0) { + result->y = (int)((pt_y / pt_w) - 0.5f); + } + else { + result->y = (int)((pt_y / pt_w) + 0.5f); + } + + /* Success. */ + return 1; +} + +/* Flush specific VG module. */ +static vg_lite_error_t flush_target(void) +{ + vg_lite_error_t error = VG_LITE_SUCCESS; + vg_lite_context_t * context = GET_CONTEXT(); + + do { + VG_LITE_BREAK_ERROR(push_state(context, 0x0A1B, 0x00000011)); + VG_LITE_BREAK_ERROR(push_stall(context, 7)); + } while(0); + + return error; +} + +/* Set the current render target. */ +vg_lite_error_t set_render_target(vg_lite_buffer_t * target) +{ + vg_lite_error_t error = VG_LITE_SUCCESS; + uint32_t yuv2rgb = 0; + uint32_t uv_swiz = 0; + uint32_t tile_setting; + uint32_t flexa_mode = 0; + uint32_t compress_mode = 0; + uint32_t mirror_mode = 0; + uint32_t premultiply_dst = 0; + uint32_t rgb_alphadiv = 0; + uint32_t read_dest = 0; + uint32_t dst_format = 0; + uint32_t rt_changed = 0; + + if(target == NULL) { + return VG_LITE_INVALID_ARGUMENT; + } + + /* Check if render target parameters are really changed. */ + if(memcmp(s_context.rtbuffer, target, sizeof(vg_lite_buffer_t))) { + rt_changed = 1; + } + /* Simply return if render target, scissor, mirror, gamma, flexa states are not changed. */ + if(!rt_changed && !s_context.scissor_dirty && !s_context.mirror_dirty && !s_context.gamma_dirty && + !s_context.flexa_dirty) { + return VG_LITE_SUCCESS; + } + +#if gcFEATURE_VG_ERROR_CHECK +#if !gcFEATURE_VG_YUV_OUTPUT + if((target != NULL) && + (target->format == VG_LITE_YUY2 || + target->format == VG_LITE_AYUY2 || + target->format == VG_LITE_YUY2_TILED || + target->format == VG_LITE_AYUY2_TILED)) { + return VG_LITE_NOT_SUPPORT; + } +#endif +#if !gcFEATURE_VG_24BIT_PLANAR + if(target->format >= VG_LITE_ABGR8565_PLANAR && target->format <= VG_LITE_RGBA5658_PLANAR) { + return VG_LITE_NOT_SUPPORT; + } +#endif + + VG_LITE_RETURN_ERROR(dstbuf_align_check(target)); + VG_LITE_RETURN_ERROR(check_compress(target->format, target->compress_mode, target->tiled, target->width, + target->height)); +#endif /* gcFEATURE_VG_ERROR_CHECK */ + +#if gcFEATURE_VG_IM_FASTCLEAR + update_fc_buffer(target); +#endif + + /* Flush previous render target before setting the new render target. */ + vg_lite_flush(); + + /* Program render target states */ + { + if(((target->format >= VG_LITE_YUY2) && (target->format <= VG_LITE_AYUY2)) || + ((target->format >= VG_LITE_YUY2_TILED) && (target->format <= VG_LITE_AYUY2_TILED))) { + yuv2rgb = convert_yuv2rgb(target->yuv.yuv2rgb); + uv_swiz = convert_uv_swizzle(target->yuv.swizzle); + } + + if(s_context.flexa_mode) { + flexa_mode = 1 << 7; + } +#if (CHIPID==0x355 || CHIPID==0x255) + if(s_context.mirror_orient == VG_LITE_ORIENTATION_TOP_BOTTOM) { +#else + if(s_context.mirror_orient == VG_LITE_ORIENTATION_BOTTOM_TOP) { +#endif + mirror_mode = 1 << 16; + } + compress_mode = ((uint32_t)target->compress_mode) << 25; + + if(target->premultiplied || target->apply_premult) { + premultiply_dst = 0x00000100; + } + +#if gcFEATURE_VG_HW_PREMULTIPLY + rgb_alphadiv = 0x00000200; +#endif +#if gcFEATURE_VG_USE_DST + read_dest = 0x00100000; +#endif + dst_format = convert_target_format(target->format, s_context.capabilities); + if(dst_format == 0xFF) { + printf("Target format: 0x%x is not supported.\n", target->format); + return VG_LITE_NOT_SUPPORT; + } + + VG_LITE_RETURN_ERROR(push_state(&s_context, 0x0A10, + dst_format | read_dest | uv_swiz | yuv2rgb | flexa_mode | compress_mode | mirror_mode | s_context.gamma_value | + premultiply_dst | rgb_alphadiv)); + + s_context.mirror_dirty = 0; + s_context.gamma_dirty = 0; + + if(s_context.flexa_dirty && !s_context.flexa_mode && s_context.tessbuf.tessbuf_size) { + VG_LITE_RETURN_ERROR(push_state(&s_context, 0x0AC8, s_context.tessbuf.tessbuf_size - 64)); + VG_LITE_RETURN_ERROR(push_state(&s_context, 0x0AC8, s_context.tessbuf.tessbuf_size)); + s_context.flexa_dirty = 0; + } + + if(target->yuv.uv_planar) { + /* Program uv plane address if necessary. */ + VG_LITE_RETURN_ERROR(push_state(&s_context, 0x0A5C, target->yuv.uv_planar)); + } + if(target->yuv.alpha_planar) { + VG_LITE_RETURN_ERROR(push_state(&s_context, 0x0A5D, target->yuv.alpha_planar)); + } + VG_LITE_RETURN_ERROR(push_state(&s_context, 0x0A11, target->address)); + + tile_setting = (target->tiled != VG_LITE_LINEAR) ? 0x10000000 : 0; + + /* 24bit format stride configured to 4bpp. */ + if(target->format >= VG_LITE_RGB888 && target->format <= VG_LITE_RGBA5658) { + uint32_t stride = target->stride / 3 * 4; + VG_LITE_RETURN_ERROR(push_state(&s_context, 0x0A12, stride | tile_setting)); + } + else { + VG_LITE_RETURN_ERROR(push_state(&s_context, 0x0A12, target->stride | tile_setting)); + } + + /* Set scissor rectangle on the render target */ + if(s_context.scissor_set) { + VG_LITE_RETURN_ERROR(push_state(&s_context, 0x0A13, s_context.scissor[2] | (s_context.scissor[3] << 16))); + } + else { + VG_LITE_RETURN_ERROR(push_state(&s_context, 0x0A13, target->width | (target->height << 16))); + } + s_context.scissor_dirty = 0; + } + +#if gcFEATURE_VG_TRACE_API + VGLITE_LOG(" set_render_target %p (%d, %d)\n", target, target->width, target->height); +#endif + + /* Copy the current render target parameters into s_context.rtbuffer */ + if(rt_changed) { + memcpy(s_context.rtbuffer, target, sizeof(vg_lite_buffer_t)); + } + + return error; +} + +/*************** VGLite API Functions ***********************************************/ + +vg_lite_error_t vg_lite_clear(vg_lite_buffer_t * target, + vg_lite_rectangle_t * rect, + vg_lite_color_t color) +{ +#if DUMP_API + FUNC_DUMP(vg_lite_clear)(target, rect, color); +#endif + + vg_lite_error_t error; + vg_lite_point_t point_min, point_max; + int32_t left, top, right, bottom; + uint32_t color32; + uint32_t tile_setting = 0; + uint32_t stripe_mode = 0; + uint32_t in_premult = 0; +#if gcFEATURE_VG_TRACE_API + VGLITE_LOG("vg_lite_clear %p %p 0x%08X\n", target, rect, color); + if(rect) VGLITE_LOG(" Rect(%d, %d, %d, %d)\n", rect->x, rect->y, rect->width, rect->height); +#endif + +#if gcFEATURE_VG_ERROR_CHECK +#if (CHIPID == 0x355) + if(target->format == VG_LITE_L8 || target->format == VG_LITE_YUYV || + target->format == VG_LITE_BGRA2222 || target->format == VG_LITE_RGBA2222 || + target->format == VG_LITE_ABGR2222 || target->format == VG_LITE_ARGB2222) { + printf("Target format: 0x%x is not supported.\n", target->format); + return VG_LITE_NOT_SUPPORT; + } +#endif +#endif + +#if gcFEATURE_VG_GAMMA + set_gamma_dest_only(target, VGL_FALSE); +#endif + + if(target->premultiplied) { + in_premult = 0x00000000; + target->apply_premult = 0; + } + else { + in_premult = 0x10000000; + target->apply_premult = 1; + } + error = set_render_target(target); + if(error != VG_LITE_SUCCESS) { + return error; + } + + /* Get rectangle. */ + if(rect) { + point_min.x = rect->x; + point_min.y = rect->y; + point_max.x = rect->x + rect->width; + point_max.y = rect->y + rect->height; + } + else { + point_min.x = 0; + point_min.y = 0; + point_max.x = s_context.rtbuffer->width; + point_max.y = s_context.rtbuffer->height; + } + + /* Clip to target. */ + if(s_context.scissor_set && !target->scissor_buffer) { + left = s_context.scissor[0]; + top = s_context.scissor[1]; + right = s_context.scissor[2]; + bottom = s_context.scissor[3]; + } + else { + left = 0; + top = 0; + right = target->width; + bottom = target->height; + } + + point_min.x = MAX(point_min.x, left); + point_min.y = MAX(point_min.y, top); + point_max.x = MIN(point_max.x, right); + point_max.y = MIN(point_max.y, bottom); + + /* No need to draw. */ + if((point_max.x <= point_min.x) || (point_max.y <= point_min.y)) { + return VG_LITE_SUCCESS; + } + + /* Get converted color when target is in L8 format. */ + color32 = (target->format == VG_LITE_L8) ? rgb_to_l(color) : color; +#if gcFEATURE_VG_RECTANGLE_TILED_OUT + if(target->tiled == VG_LITE_TILED) { + tile_setting = 0x40; + stripe_mode = 0x20000000; + } +#endif + +#if gcFEATURE_VG_IM_FASTCLEAR + if((rect == NULL) || + (point_min.x == 0 && point_min.y == 0 && + ((point_max.x - point_min.x) == s_context.rtbuffer->width) && + ((point_max.y - point_min.y) == s_context.rtbuffer->height))) { + convert_color(s_context.rtbuffer->format, color32, &color32, NULL); + clear_fc(&target->fc_buffer[0], (uint32_t)color32); + } + else +#endif + { + /* Setup the command buffer. */ + VG_LITE_RETURN_ERROR(push_state(&s_context, 0x0A34, 0)); + VG_LITE_RETURN_ERROR(push_state(&s_context, 0x0A02, color32)); + + /* Clear operation is not affected by color transformation and pixel matrix. + * So PE clear and push_rectangle() clear have the same clear result color. + */ +#if gcFEATURE_VG_PE_CLEAR + VG_LITE_RETURN_ERROR(push_state(&s_context, 0x0A39, 0)); + if((!rect && (point_min.x == 0 && point_min.y == 0 && (point_max.x - point_min.x) == target->width)) && + !s_context.scissor_enable && !s_context.scissor_set && !s_context.enable_mask) { + if(target->compress_mode == VG_LITE_DEC_DISABLE) { +#if gcFEATURE_VG_DST_BUFLEN_ALIGNED + uint32_t align, mul, div; + get_format_bytes(target->format, &mul, &div, &align); + if((mul / div != 3) && ((target->stride * (point_max.y - point_min.y)) % 64 != 0)) { + return VG_LITE_INVALID_ARGUMENT; + } +#endif + +#if gcFEATURE_VG_24BIT + uint32_t align1, mul1, div1; + get_format_bytes(target->format, &mul1, &div1, &align1); + if((mul1 / div1 == 3) && ((target->stride * (point_max.y - point_min.y)) % 48 != 0)) { + return VG_LITE_INVALID_ARGUMENT; + } +#endif + } + else { +#if gcFEATURE_VG_DEC_COMPRESS_2_0 + if(target->format == VG_LITE_BGRA8888 || target->format == VG_LITE_BGRX8888) { + if((target->stride * (point_max.y - point_min.y)) % 64 != 0) { + return VG_LITE_INVALID_ARGUMENT; + } + } + + if(target->format == VG_LITE_BGR888) { + if((target->stride * (point_max.y - point_min.y)) % 48 != 0) { + return VG_LITE_INVALID_ARGUMENT; + } + } +#endif +#if gcFEATURE_VG_DEC_COMPRESS + if(target->format == VG_LITE_BGRX8888 || target->format == VG_LITE_RGBX8888 + || target->format == VG_LITE_BGRA8888 || target->format == VG_LITE_RGBA8888) { + if((target->stride * (point_max.y - point_min.y)) % 64 != 0) { + return VG_LITE_INVALID_ARGUMENT; + } + } + + if(target->format == VG_LITE_RGB888 || target->format == VG_LITE_BGR888) { + if((target->stride * (point_max.y - point_min.y)) % 48 != 0) { + return VG_LITE_INVALID_ARGUMENT; + } + } +#endif + } + + VG_LITE_RETURN_ERROR(push_state(&s_context, 0x0A00, + in_premult | 0x00000004 | tile_setting | s_context.scissor_enable | stripe_mode)); + VG_LITE_RETURN_ERROR(push_pe_clear(&s_context, target->stride * (point_max.y - point_min.y))); + } + else +#endif + { + VG_LITE_RETURN_ERROR(push_state(&s_context, 0x0A00, + in_premult | 0x00000001 | tile_setting | s_context.scissor_enable | stripe_mode)); + VG_LITE_RETURN_ERROR(push_rectangle(&s_context, point_min.x, point_min.y, point_max.x - point_min.x, + point_max.y - point_min.y)); + } + + /* flush VGPE after clear */ + VG_LITE_RETURN_ERROR(push_state(&s_context, 0x0A1B, 0x00000011)); + } + + /* Success. */ + return VG_LITE_SUCCESS; +} + +vg_lite_error_t vg_lite_blit2(vg_lite_buffer_t * target, + vg_lite_buffer_t * source0, + vg_lite_buffer_t * source1, + vg_lite_matrix_t * matrix0, + vg_lite_matrix_t * matrix1, + vg_lite_blend_t blend, + vg_lite_filter_t filter) +{ +#if DUMP_API + FUNC_DUMP(vg_lite_blit2)(target, source0, source1, matrix0, matrix1, blend, filter); +#endif + +#if gcFEATURE_VG_DOUBLE_IMAGE && gcFEATURE_VG_IM_INPUT + vg_lite_error_t error; + vg_lite_point_t point_min, point_max, temp; + vg_lite_matrix_t inverse_matrix; + vg_lite_float_t x_step[2][3]; + vg_lite_float_t y_step[2][3]; + vg_lite_float_t c_step[2][3]; + uint32_t imageMode; + uint32_t blend_mode; + uint32_t filter_mode = 0; + int32_t stride0; + int32_t stride1; + uint32_t rotation = 0; + uint32_t conversion = 0; + uint32_t tiled0, tiled1; + int32_t left, right, bottom, top; + +#if gcFEATURE_VG_TRACE_API + VGLITE_LOG("vg_lite_blit2 %p %p %p %p %p %d %d\n", target, source0, source1, matrix0, matrix1, blend, filter); +#endif + +#if gcFEATURE_VG_ERROR_CHECK +#if !gcFEATURE_VG_24BIT + if((target->format >= VG_LITE_RGB888 && target->format <= VG_LITE_RGBA5658) || + (source0->format >= VG_LITE_RGB888 && source0->format <= VG_LITE_RGBA5658) || + (source1->format >= VG_LITE_RGB888 && source1->format <= VG_LITE_RGBA5658)) { + return VG_LITE_NOT_SUPPORT; + } +#endif +#if !gcFEATURE_VG_YUY2_INPUT + if(source0->format == VG_LITE_YUYV || source0->format == VG_LITE_YUY2 || source1->format == VG_LITE_YUYV || + source1->format == VG_LITE_YUY2) { + return VG_LITE_NOT_SUPPORT; + } +#endif +#if !gcFEATURE_VG_YUV_INPUT + if((source0->format >= VG_LITE_NV12 && source0->format <= VG_LITE_NV16) || (source1->format >= VG_LITE_NV12 && + source1->format <= VG_LITE_NV16) || source0->format == VG_LITE_NV24 || source1->format >= VG_LITE_NV24) { + return VG_LITE_NOT_SUPPORT; + } +#elif !gcFEATURE_VG_NV24_INPUT + if(source0->format == VG_LITE_NV24 || source1->format >= VG_LITE_NV24) { + return VG_LITE_NOT_SUPPORT; + } +#endif +#if !gcFEATURE_VG_AYUV_INPUT + if(source0->format == VG_LITE_ANV12 || source0->format == VG_LITE_AYUY2 || source1->format == VG_LITE_ANV12 || + source1->format == VG_LITE_AYUY2) { + return VG_LITE_NOT_SUPPORT; + } +#endif +#if !gcFEATURE_VG_YUV_TILED_INPUT + if((source0->format >= VG_LITE_YUY2_TILED && source0->format <= VG_LITE_AYUY2_TILED) || + (source1->format >= VG_LITE_YUY2_TILED && source1->format <= VG_LITE_AYUY2_TILED) || + (source0->format == VG_LITE_NV24_TILED) || (source1->format == VG_LITE_NV24_TILED)) { + return VG_LITE_NOT_SUPPORT; + } +#endif +#if !gcFEATURE_VG_NEW_BLEND_MODE + if(blend == VG_LITE_BLEND_DARKEN || blend == VG_LITE_BLEND_LIGHTEN) { + return VG_LITE_NOT_SUPPORT; + } +#endif +#endif /* gcFEATURE_VG_ERROR_CHECK */ + + if(!matrix0) { + matrix0 = &identity_mtx; + } + if(!matrix1) { + matrix1 = &identity_mtx; + } + + error = set_render_target(target); + if(error != VG_LITE_SUCCESS) { + return error; + } + + /* Check if the specified matrix has rotation or perspective. */ + if((matrix0->m[0][1] != 0.0f) + || (matrix0->m[1][0] != 0.0f) + || (matrix0->m[2][0] != 0.0f) + || (matrix0->m[2][1] != 0.0f) + || (matrix0->m[2][2] != 1.0f) + ) { + /* Mark that we have rotation. */ + rotation = 0x8000; + } + + /* Check whether L8 is supported or not. */ + if((target->format == VG_LITE_L8) && ((source0->format != VG_LITE_L8) && (source0->format != VG_LITE_A8))) { + conversion = 0x80000000; + } + + /* Calculate transformation for Image0 (Paint) & Image1 (Image). */ + /* Image1. */ + /* Transform image (0,0) to screen. */ + if(!transform(&temp, 0.0f, 0.0f, matrix0)) + return VG_LITE_INVALID_ARGUMENT; + + /* Set initial point. */ + point_min = temp; + point_max = temp; + + /* Transform image (0,height) to screen. */ + if(!transform(&temp, 0.0f, (vg_lite_float_t)source0->height, matrix0)) + return VG_LITE_INVALID_ARGUMENT; + + /* Determine min/max. */ + if(temp.x < point_min.x) point_min.x = temp.x; + if(temp.y < point_min.y) point_min.y = temp.y; + if(temp.x > point_max.x) point_max.x = temp.x; + if(temp.y > point_max.y) point_max.y = temp.y; + + /* Transform image (width,height) to screen. */ + if(!transform(&temp, (vg_lite_float_t)source0->width, (vg_lite_float_t)source0->height, matrix0)) + return VG_LITE_INVALID_ARGUMENT; + + /* Determine min/max. */ + if(temp.x < point_min.x) point_min.x = temp.x; + if(temp.y < point_min.y) point_min.y = temp.y; + if(temp.x > point_max.x) point_max.x = temp.x; + if(temp.y > point_max.y) point_max.y = temp.y; + + /* Transform image (width,0) to screen. */ + if(!transform(&temp, (vg_lite_float_t)source0->width, 0.0f, matrix0)) + return VG_LITE_INVALID_ARGUMENT; + + /* Determine min/max. */ + if(temp.x < point_min.x) point_min.x = temp.x; + if(temp.y < point_min.y) point_min.y = temp.y; + if(temp.x > point_max.x) point_max.x = temp.x; + if(temp.y > point_max.y) point_max.y = temp.y; + + /* Clip to target. */ + if(s_context.scissor_set) { + left = s_context.scissor[0]; + top = s_context.scissor[1]; + right = s_context.scissor[2]; + bottom = s_context.scissor[3]; + } + else { + left = top = 0; + right = target->width; + bottom = target->height; + } + + point_min.x = MAX(point_min.x, left); + point_min.y = MAX(point_min.y, top); + point_max.x = MIN(point_max.x, right); + point_max.y = MIN(point_max.y, bottom); + + if((point_max.x - point_min.x) <= 0 || (point_max.y - point_min.y) <= 0) + return VG_LITE_SUCCESS; + /* Compute inverse matrix. */ + if(!inverse(&inverse_matrix, matrix0)) + return VG_LITE_INVALID_ARGUMENT; + + /* Compute interpolation steps for image1 (Image). */ + x_step[1][0] = inverse_matrix.m[0][0] / source0->width; + x_step[1][1] = inverse_matrix.m[1][0] / source0->height; + x_step[1][2] = inverse_matrix.m[2][0]; + y_step[1][0] = inverse_matrix.m[0][1] / source0->width; + y_step[1][1] = inverse_matrix.m[1][1] / source0->height; + y_step[1][2] = inverse_matrix.m[2][1]; + c_step[1][0] = (0.5f * (inverse_matrix.m[0][0] + inverse_matrix.m[0][1]) + inverse_matrix.m[0][2]) / source0->width; + c_step[1][1] = (0.5f * (inverse_matrix.m[1][0] + inverse_matrix.m[1][1]) + inverse_matrix.m[1][2]) / source0->height; + c_step[1][2] = 0.5f * (inverse_matrix.m[2][0] + inverse_matrix.m[2][1]) + inverse_matrix.m[2][2]; + + /* Image0 (Paint, as background ). */ + /* Transform image (0,0) to screen. */ + if(!transform(&temp, 0.0f, 0.0f, matrix1)) + return VG_LITE_INVALID_ARGUMENT; + + /* Set initial point. */ + point_min = temp; + point_max = temp; + + /* Transform image (0,height) to screen. */ + if(!transform(&temp, 0.0f, (vg_lite_float_t)source1->height, matrix1)) + return VG_LITE_INVALID_ARGUMENT; + + /* Determine min/max. */ + if(temp.x < point_min.x) point_min.x = temp.x; + if(temp.y < point_min.y) point_min.y = temp.y; + if(temp.x > point_max.x) point_max.x = temp.x; + if(temp.y > point_max.y) point_max.y = temp.y; + + /* Transform image (width,height) to screen. */ + if(!transform(&temp, (vg_lite_float_t)source1->width, (vg_lite_float_t)source1->height, matrix1)) + return VG_LITE_INVALID_ARGUMENT; + + /* Determine min/max. */ + if(temp.x < point_min.x) point_min.x = temp.x; + if(temp.y < point_min.y) point_min.y = temp.y; + if(temp.x > point_max.x) point_max.x = temp.x; + if(temp.y > point_max.y) point_max.y = temp.y; + + /* Transform image (width,0) to screen. */ + if(!transform(&temp, (vg_lite_float_t)source1->width, 0.0f, matrix1)) + return VG_LITE_INVALID_ARGUMENT; + + /* Determine min/max. */ + if(temp.x < point_min.x) point_min.x = temp.x; + if(temp.y < point_min.y) point_min.y = temp.y; + if(temp.x > point_max.x) point_max.x = temp.x; + if(temp.y > point_max.y) point_max.y = temp.y; + + /* Clip to target. */ + if(s_context.scissor_set) { + left = s_context.scissor[0]; + top = s_context.scissor[1]; + right = s_context.scissor[2]; + bottom = s_context.scissor[3]; + } + else { + left = top = 0; + right = target->width; + bottom = target->height; + } + + point_min.x = MAX(point_min.x, left); + point_min.y = MAX(point_min.y, top); + point_max.x = MIN(point_max.x, right); + point_max.y = MIN(point_max.y, bottom); + + /* Compute inverse matrix. */ + if(!inverse(&inverse_matrix, matrix1)) + return VG_LITE_INVALID_ARGUMENT; + + /* Compute interpolation steps for image1 (Image). */ + x_step[0][0] = inverse_matrix.m[0][0] / source1->width; + x_step[0][1] = inverse_matrix.m[1][0] / source1->height; + x_step[0][2] = inverse_matrix.m[2][0]; + y_step[0][0] = inverse_matrix.m[0][1] / source1->width; + y_step[0][1] = inverse_matrix.m[1][1] / source1->height; + y_step[0][2] = inverse_matrix.m[2][1]; + c_step[0][0] = (0.5f * (inverse_matrix.m[0][0] + inverse_matrix.m[0][1]) + inverse_matrix.m[0][2]) / source1->width; + c_step[0][1] = (0.5f * (inverse_matrix.m[1][0] + inverse_matrix.m[1][1]) + inverse_matrix.m[1][2]) / source1->height; + c_step[0][2] = 0.5f * (inverse_matrix.m[2][0] + inverse_matrix.m[2][1]) + inverse_matrix.m[2][2]; + + /* DOUBLE_IMAGE mode. */ + imageMode = 0x5000; + blend_mode = convert_blend(blend); + tiled0 = (source0->tiled != VG_LITE_LINEAR) ? 0x10000000 : 0; + tiled1 = (source1->tiled != VG_LITE_LINEAR) ? 0x10000000 : 0; + + switch(filter) { + case VG_LITE_FILTER_POINT: + filter_mode = 0; + break; + + case VG_LITE_FILTER_LINEAR: + filter_mode = 0x10000; + break; + + case VG_LITE_FILTER_BI_LINEAR: + filter_mode = 0x20000; + break; + + case VG_LITE_FILTER_GAUSSIAN: + filter_mode = 0x30000; + break; + } + + /* Setup the command buffer. */ + VG_LITE_RETURN_ERROR(push_state(&s_context, 0x0A00, + 0x10000001 | imageMode | blend_mode | rotation | s_context.enable_mask | s_context.color_transform | + s_context.matrix_enable)); + VG_LITE_RETURN_ERROR(push_state(&s_context, 0x0A34, 0)); + /* Program image1. */ + VG_LITE_RETURN_ERROR(push_state_ptr(&s_context, 0x0A18, (void *) &c_step[1][0])); + VG_LITE_RETURN_ERROR(push_state_ptr(&s_context, 0x0A19, (void *) &c_step[1][1])); + VG_LITE_RETURN_ERROR(push_state_ptr(&s_context, 0x0A1A, (void *) &c_step[1][2])); + VG_LITE_RETURN_ERROR(push_state_ptr(&s_context, 0x0A1C, (void *) &x_step[1][0])); + VG_LITE_RETURN_ERROR(push_state_ptr(&s_context, 0x0A1D, (void *) &x_step[1][1])); + VG_LITE_RETURN_ERROR(push_state_ptr(&s_context, 0x0A1E, (void *) &x_step[1][2])); + VG_LITE_RETURN_ERROR(push_state(&s_context, 0x0A1F, 0x00000001)); + VG_LITE_RETURN_ERROR(push_state_ptr(&s_context, 0x0A20, (void *) &y_step[1][0])); + VG_LITE_RETURN_ERROR(push_state_ptr(&s_context, 0x0A21, (void *) &y_step[1][1])); + VG_LITE_RETURN_ERROR(push_state_ptr(&s_context, 0x0A22, (void *) &y_step[1][2])); + VG_LITE_RETURN_ERROR(push_state(&s_context, 0x0A25, convert_source_format(source0->format) | filter_mode | conversion)); + VG_LITE_RETURN_ERROR(push_state(&s_context, 0x0A27, 0)); + VG_LITE_RETURN_ERROR(push_state(&s_context, 0x0A29, source0->address)); + + if(source0->yuv.uv_planar != 0) { + VG_LITE_RETURN_ERROR(push_state(&s_context, 0x0A51, source0->yuv.uv_planar)); + } + if(source0->yuv.v_planar != 0) { + VG_LITE_RETURN_ERROR(push_state(&s_context, 0x0A53, source0->yuv.v_planar)); + } + + if(source0->yuv.alpha_planar != 0) { + VG_LITE_RETURN_ERROR(push_state(&s_context, 0x0A53, source0->yuv.alpha_planar)); + } + /* 24bit format stride configured to 4bpp. */ + if(source0->format >= VG_LITE_RGB888 && source0->format <= VG_LITE_RGBA5658) { + stride0 = source0->stride / 3 * 4; + VG_LITE_RETURN_ERROR(push_state(&s_context, 0x0A2B, stride0 | tiled0)); + } + else { + VG_LITE_RETURN_ERROR(push_state(&s_context, 0x0A2B, source0->stride | tiled0)); + } + VG_LITE_RETURN_ERROR(push_state(&s_context, 0x0A2D, 0)); + VG_LITE_RETURN_ERROR(push_state(&s_context, 0x0A2F, source0->width | (source0->height << 16))); + + /* Program image0 (Paint, as background). */ + VG_LITE_RETURN_ERROR(push_state_ptr(&s_context, 0x0A84, (void *) &c_step[0][0])); + VG_LITE_RETURN_ERROR(push_state_ptr(&s_context, 0x0A85, (void *) &c_step[0][1])); + VG_LITE_RETURN_ERROR(push_state_ptr(&s_context, 0x0A86, (void *) &c_step[0][2])); + VG_LITE_RETURN_ERROR(push_state_ptr(&s_context, 0x0A7C, (void *) &x_step[0][0])); + VG_LITE_RETURN_ERROR(push_state_ptr(&s_context, 0x0A7D, (void *) &x_step[0][1])); + VG_LITE_RETURN_ERROR(push_state_ptr(&s_context, 0x0A7E, (void *) &x_step[0][2])); + VG_LITE_RETURN_ERROR(push_state(&s_context, 0x0A1F, 0x00000001)); + VG_LITE_RETURN_ERROR(push_state_ptr(&s_context, 0x0A80, (void *) &y_step[0][0])); + VG_LITE_RETURN_ERROR(push_state_ptr(&s_context, 0x0A81, (void *) &y_step[0][1])); + VG_LITE_RETURN_ERROR(push_state_ptr(&s_context, 0x0A82, (void *) &y_step[0][2])); + VG_LITE_RETURN_ERROR(push_state(&s_context, 0x0A24, convert_source_format(source1->format) | filter_mode | conversion)); + VG_LITE_RETURN_ERROR(push_state(&s_context, 0x0A26, 0)); + VG_LITE_RETURN_ERROR(push_state(&s_context, 0x0A28, source1->address)); + if(source1->yuv.uv_planar != 0) { + VG_LITE_RETURN_ERROR(push_state(&s_context, 0x0A50, source1->yuv.uv_planar)); + } + if(source1->yuv.v_planar != 0) { + VG_LITE_RETURN_ERROR(push_state(&s_context, 0x0A52, source1->yuv.v_planar)); + } + if(source1->yuv.alpha_planar != 0) { + VG_LITE_RETURN_ERROR(push_state(&s_context, 0x0A52, source1->yuv.alpha_planar)); + } + /* 24bit format stride configured to 4bpp. */ + if(source1->format >= VG_LITE_RGB888 && source1->format <= VG_LITE_RGBA5658) { + stride1 = source1->stride / 3 * 4; + VG_LITE_RETURN_ERROR(push_state(&s_context, 0x0A2A, stride1 | tiled1)); + } + else { + VG_LITE_RETURN_ERROR(push_state(&s_context, 0x0A2A, source1->stride | tiled1)); + } + VG_LITE_RETURN_ERROR(push_state(&s_context, 0x0A2C, 0)); + VG_LITE_RETURN_ERROR(push_state(&s_context, 0x0A2E, source1->width | (source1->height << 16))); + + VG_LITE_RETURN_ERROR(push_rectangle(&s_context, point_min.x, point_min.y, point_max.x - point_min.x, + point_max.y - point_min.y)); + VG_LITE_RETURN_ERROR(flush_target()); + + vglitemDUMP_BUFFER("image", (size_t)source0->address, source0->memory, 0, (source0->stride) * (source0->height)); + vglitemDUMP_BUFFER("image", (size_t)source1->address, source1->memory, 0, (source1->stride) * (source1->height)); +#if DUMP_IMAGE + dump_img(source0->memory, source0->width, source0->height, source0->format); + dump_img(source1->memory, source1->width, source1->height, source1->format); +#endif + + return error; +#else + return VG_LITE_NOT_SUPPORT; +#endif +} + +vg_lite_error_t vg_lite_blit(vg_lite_buffer_t * target, + vg_lite_buffer_t * source, + vg_lite_matrix_t * matrix, + vg_lite_blend_t blend, + vg_lite_color_t color, + vg_lite_filter_t filter) +{ +#if DUMP_API + FUNC_DUMP(vg_lite_blit)(target, source, matrix, blend, color, filter); +#endif + +#if gcFEATURE_VG_IM_INPUT + vg_lite_error_t error; + vg_lite_point_t point_min, point_max, temp; + vg_lite_matrix_t inverse_matrix; + vg_lite_float_t x_step[3]; + vg_lite_float_t y_step[3]; + vg_lite_float_t c_step[3]; + uint32_t imageMode = 0; + uint32_t paintType = 0; + uint32_t in_premult = 0; + uint32_t blend_mode; + uint32_t filter_mode = 0; + uint32_t transparency_mode = 0; + uint32_t conversion = 0; + uint32_t tiled_source; + uint32_t yuv2rgb = 0; + uint32_t uv_swiz = 0; + uint32_t compress_mode = 0; + uint32_t src_premultiply_enable = 0; + uint32_t index_endian = 0; + uint32_t eco_fifo = 0; + uint32_t tile_setting = 0; + uint32_t stripe_mode = 0; + uint32_t premul_flag = 0; + uint32_t prediv_flag = 0; + int32_t left, top, right, bottom; + int32_t stride; + uint8_t lvgl_sw_blend = 0; +#if VG_SW_BLIT_PRECISION_OPT + uint8_t * bufferPointer; + uint32_t bufferAddress = 0, bufferAlignAddress = 0, addressOffset = 0, mul = 0, div = 0, required_align = 0; + vg_lite_buffer_t new_target; + vg_lite_point_t point0_0_afterTransform = { 0 }; + uint8_t enableSwPreOpt = 0; + int32_t matrixOffsetX = 0; + + /* Only accept interger move */ + if(matrix != NULL && filter == VG_LITE_FILTER_POINT) { + matrix->m[0][2] = (vg_lite_float_t)(matrix->m[0][2] >= 0 ? (int32_t)(matrix->m[0][2] + 0.5) : (int32_t)( + matrix->m[0][2] - 0.5)); + matrix->m[1][2] = (vg_lite_float_t)(matrix->m[1][2] >= 0 ? (int32_t)(matrix->m[1][2] + 0.5) : (int32_t)( + matrix->m[1][2] - 0.5)); + /* Only nonperspective transform with scale or rotation could enable optimization */ + if((matrix->m[2][0] == 0.0f && matrix->m[2][1] == 0.0f && matrix->m[2][2] == 1.0f) && + (matrix->m[0][0] != 1.0f || matrix->m[1][1] != 1.0f || matrix->m[0][1] != 0.0f)) { + if(target->tiled != VG_LITE_TILED && (target->format < VG_LITE_RGB888 || target->format > VG_LITE_RGBA5658_PLANAR)) { + enableSwPreOpt = 1; + } + } + } +#endif /* VG_SW_BLIT_PRECISION_OPT */ + +#if gcFEATURE_VG_TRACE_API + VGLITE_LOG("vg_lite_blit %p %p %p %d 0x%08X %d\n", target, source, matrix, blend, color, filter); +#endif + +#if gcFEATURE_VG_ERROR_CHECK +#if !gcFEATURE_VG_INDEX_ENDIAN + if((source->format >= VG_LITE_INDEX_1) && (source->format <= VG_LITE_INDEX_4) && source->index_endian) { + return VG_LITE_NOT_SUPPORT; + } +#endif + +#if !gcFEATURE_VG_RGBA8_ETC2_EAC + if(source->format == VG_LITE_RGBA8888_ETC2_EAC) { + return VG_LITE_NOT_SUPPORT; + } +#else + if((source->format == VG_LITE_RGBA8888_ETC2_EAC) && (source->width % 16 || source->height % 4)) { + return VG_LITE_INVALID_ARGUMENT; + } +#endif +#if !gcFEATURE_VG_YUY2_INPUT + if(source->format == VG_LITE_YUYV || source->format == VG_LITE_YUY2) { + return VG_LITE_NOT_SUPPORT; + } +#endif +#if !gcFEATURE_VG_YUV_INPUT + if((source->format >= VG_LITE_NV12 && source->format <= VG_LITE_NV16) || source->format == VG_LITE_NV24) { + return VG_LITE_NOT_SUPPORT; + } +#elif !gcFEATURE_VG_NV24_INPUT + if(source->format == VG_LITE_NV24) { + return VG_LITE_NOT_SUPPORT; + } +#endif +#if !gcFEATURE_VG_AYUV_INPUT + if(source->format == VG_LITE_ANV12 || source->format == VG_LITE_AYUY2) { + return VG_LITE_NOT_SUPPORT; + } +#endif +#if !gcFEATURE_VG_YUV_TILED_INPUT + if((source->format >= VG_LITE_YUY2_TILED && source->format <= VG_LITE_AYUY2_TILED) || + (source->format == VG_LITE_NV24_TILED)) { + return VG_LITE_NOT_SUPPORT; + } +#endif +#if !gcFEATURE_VG_24BIT + if((target->format >= VG_LITE_RGB888 && target->format <= VG_LITE_RGBA5658) || + (source->format >= VG_LITE_RGB888 && source->format <= VG_LITE_RGBA5658)) { + return VG_LITE_NOT_SUPPORT; + } +#endif +#if !gcFEATURE_VG_24BIT_PLANAR + if(source->format >= VG_LITE_ABGR8565_PLANAR && source->format <= VG_LITE_RGBA5658_PLANAR) { + return VG_LITE_NOT_SUPPORT; + } +#endif +#if !gcFEATURE_VG_IM_DEC_INPUT + if(source->compress_mode != VG_LITE_DEC_DISABLE) { + return VG_LITE_NOT_SUPPORT; + } +#endif +#if !gcFEATURE_VG_STENCIL + if(source->image_mode == VG_LITE_STENCIL_MODE) { + return VG_LITE_NOT_SUPPORT; + } +#endif +#if !gcFEATURE_VG_NEW_BLEND_MODE + if(blend == VG_LITE_BLEND_DARKEN || blend == VG_LITE_BLEND_LIGHTEN) { + return VG_LITE_NOT_SUPPORT; + } +#endif + if(blend && (target->format == VG_LITE_YUYV || target->format == VG_LITE_YUY2 || target->format == VG_LITE_YUY2_TILED + || target->format == VG_LITE_AYUY2 || target->format == VG_LITE_AYUY2_TILED)) { + return VG_LITE_NOT_SUPPORT; + } +#if (CHIPID == 0x355) + if(target->format == VG_LITE_L8 || target->format == VG_LITE_YUYV || + target->format == VG_LITE_BGRA2222 || target->format == VG_LITE_RGBA2222 || + target->format == VG_LITE_ABGR2222 || target->format == VG_LITE_ARGB2222) { + printf("Target format: 0x%x is not supported.\n", target->format); + return VG_LITE_NOT_SUPPORT; + } + if(source->format == VG_LITE_L8 || source->format == VG_LITE_YUYV || + source->format == VG_LITE_BGRA2222 || source->format == VG_LITE_RGBA2222 || + source->format == VG_LITE_ABGR2222 || source->format == VG_LITE_ARGB2222) { + printf("Source format: 0x%x is not supported.\n", source->format); + return VG_LITE_NOT_SUPPORT; + } +#endif + + VG_LITE_RETURN_ERROR(srcbuf_align_check(source)); + VG_LITE_RETURN_ERROR(check_compress(source->format, source->compress_mode, source->tiled, source->width, + source->height)); +#endif /* gcFEATURE_VG_ERROR_CHECK */ + +#if !gcFEATURE_VG_LVGL_SUPPORT + if((blend >= VG_LITE_BLEND_ADDITIVE_LVGL && blend <= VG_LITE_BLEND_MULTIPLY_LVGL) || + (blend == VG_LITE_BLEND_NORMAL_LVGL && gcFEATURE_VG_SRC_PREMULTIPLIED)) { + if(!source->lvgl_buffer) { + source->lvgl_buffer = (vg_lite_buffer_t *)vg_lite_os_malloc(sizeof(vg_lite_buffer_t)); + *source->lvgl_buffer = *source; + source->lvgl_buffer->lvgl_buffer = NULL; + vg_lite_allocate(source->lvgl_buffer); + } + /* Make sure render target is up to date before reading RT. */ + vg_lite_finish(); + setup_lvgl_image(target, source, source->lvgl_buffer, blend); + blend = VG_LITE_BLEND_SRC_OVER; + lvgl_sw_blend = 1; + } +#endif + + if(!matrix) { + matrix = &identity_mtx; + } + +#if gcFEATURE_VG_INDEX_ENDIAN + if((source->format >= VG_LITE_INDEX_1) && (source->format <= VG_LITE_INDEX_4) && source->index_endian) { + index_endian = 1 << 14; + } +#endif +#if !gcFEATURE_VG_STRIPE_MODE + /* Enable fifo feature to share buffer between vg and ts to improve the rotation performance */ + eco_fifo = 1 << 7; +#endif + + transparency_mode = (source->transparency_mode == VG_LITE_IMAGE_TRANSPARENT ? 0x8000 : 0); + s_context.filter = filter; + + /* Check if the specified matrix has rotation or perspective. */ + if(((matrix->m[0][1] != 0.0f) + || (matrix->m[1][0] != 0.0f) + || (matrix->m[2][0] != 0.0f) + || (matrix->m[2][1] != 0.0f) + || (matrix->m[2][2] != 1.0f) + ) + && (blend == VG_LITE_BLEND_NONE + || blend == VG_LITE_BLEND_SRC_IN + || blend == VG_LITE_BLEND_DST_IN + ) + ) { +#if gcFEATURE_VG_BORDER_CULLING + /* Mark that we have rotation. */ + transparency_mode = 0x8000; +#else + blend = VG_LITE_BLEND_SRC_OVER; +#endif +#if !gcFEATURE_VG_STRIPE_MODE + stripe_mode = 1 << 29; +#endif + } + + /* Check whether L8 is supported or not. */ + if((target->format == VG_LITE_L8) && ((source->format != VG_LITE_L8) && (source->format != VG_LITE_A8))) { + conversion = 0x80000000; + } + +#if gcFEATURE_VG_16PIXELS_ALIGNED + /* Check if source specify bytes are aligned */ + error = _check_source_aligned(source->format, source->stride); + if(error != VG_LITE_SUCCESS) { + return error; + } +#endif + + /* Transform image (0,0) to screen. */ + if(!transform(&temp, 0.0f, 0.0f, matrix)) + return VG_LITE_INVALID_ARGUMENT; + + /* Set initial point. */ + point_min = temp; + point_max = temp; +#if VG_SW_BLIT_PRECISION_OPT + point0_0_afterTransform = temp; +#endif /* VG_SW_BLIT_PRECISION_OPT */ + + /* Transform image (0,height) to screen. */ + if(!transform(&temp, 0.0f, (vg_lite_float_t)source->height, matrix)) + return VG_LITE_INVALID_ARGUMENT; + + /* Determine min/max. */ + if(temp.x < point_min.x) point_min.x = temp.x; + if(temp.y < point_min.y) point_min.y = temp.y; + if(temp.x > point_max.x) point_max.x = temp.x; + if(temp.y > point_max.y) point_max.y = temp.y; + + /* Transform image (width,height) to screen. */ + if(!transform(&temp, (vg_lite_float_t)source->width, (vg_lite_float_t)source->height, matrix)) + return VG_LITE_INVALID_ARGUMENT; + + /* Determine min/max. */ + if(temp.x < point_min.x) point_min.x = temp.x; + if(temp.y < point_min.y) point_min.y = temp.y; + if(temp.x > point_max.x) point_max.x = temp.x; + if(temp.y > point_max.y) point_max.y = temp.y; + + /* Transform image (width,0) to screen. */ + if(!transform(&temp, (vg_lite_float_t)source->width, 0.0f, matrix)) + return VG_LITE_INVALID_ARGUMENT; + + /* Determine min/max. */ + if(temp.x < point_min.x) point_min.x = temp.x; + if(temp.y < point_min.y) point_min.y = temp.y; + if(temp.x > point_max.x) point_max.x = temp.x; + if(temp.y > point_max.y) point_max.y = temp.y; + + /* Clip to target. */ + if(s_context.scissor_set && !target->scissor_buffer) { + left = s_context.scissor[0]; + top = s_context.scissor[1]; + right = s_context.scissor[2]; + bottom = s_context.scissor[3]; + } + else { + left = 0; + top = 0; + right = target->width; + bottom = target->height; + } + + point_min.x = MAX(point_min.x, left); + point_min.y = MAX(point_min.y, top); + point_max.x = MIN(point_max.x, right); + point_max.y = MIN(point_max.y, bottom); + + /* No need to draw. */ + if((point_max.x <= point_min.x) || (point_max.y <= point_min.y)) { + return VG_LITE_SUCCESS; + } + +#if gcFEATURE_VG_GAMMA + get_st_gamma_src_dest(source, target); +#endif + +#if gcFEATURE_VG_GLOBAL_ALPHA + if(blend >= VG_LITE_BLEND_NORMAL_LVGL && blend <= VG_LITE_BLEND_MULTIPLY_LVGL) { + VG_LITE_RETURN_ERROR(vg_lite_dest_global_alpha(VG_LITE_GLOBAL, 0xff)); + } +#endif + + /*blend input into context*/ + s_context.blend_mode = blend; + in_premult = 0x00000000; + + /* Adjust premultiply setting according to openvg condition */ + src_premultiply_enable = 0x01000100; + if(s_context.color_transform == 0 && s_context.gamma_dst == s_context.gamma_src && s_context.matrix_enable == 0 && + s_context.dst_alpha_mode == 0 && s_context.src_alpha_mode == 0 && + (source->image_mode == VG_LITE_NORMAL_IMAGE_MODE || source->image_mode == 0)) { + prediv_flag = 0; + } + else { + prediv_flag = 1; + } + if((s_context.blend_mode >= OPENVG_BLEND_SRC && s_context.blend_mode <= OPENVG_BLEND_ADDITIVE) || + source->image_mode == VG_LITE_STENCIL_MODE + || (s_context.blend_mode >= VG_LITE_BLEND_NORMAL_LVGL && s_context.blend_mode <= VG_LITE_BLEND_MULTIPLY_LVGL)) { + premul_flag = 1; + } + else { + premul_flag = 0; + } + + if((source->premultiplied == 0 && target->premultiplied == 0 && premul_flag == 0) || + (source->premultiplied == 1 && target->premultiplied == 0 && prediv_flag == 0)) { + src_premultiply_enable = 0x01000100; + in_premult = 0x10000000; + } + /* when src and dst all pre format, im pre_out set to 0 to perform data truncation to prevent data overflow */ + else if(source->premultiplied == 1 && target->premultiplied == 1 && prediv_flag == 0) { + src_premultiply_enable = 0x00000100; + in_premult = 0x00000000; + } + else if((source->premultiplied == 0 && target->premultiplied == 1) || + (source->premultiplied == 0 && target->premultiplied == 0 && premul_flag == 1)) { + src_premultiply_enable = 0x01000100; + in_premult = 0x00000000; + } + else if((source->premultiplied == 1 && target->premultiplied == 1 && prediv_flag == 1) || + (source->premultiplied == 1 && target->premultiplied == 0 && prediv_flag == 1)) { + src_premultiply_enable = 0x00000100; + in_premult = 0x00000000; + } + if((source->format == VG_LITE_A4 || source->format == VG_LITE_A8) && blend >= VG_LITE_BLEND_SRC_OVER && + blend <= VG_LITE_BLEND_SUBTRACT) { +#if (CHIPID==0x255) + src_premultiply_enable = 0x00000000; +#endif +#if gcFEATURE_VG_SRC_PREMULTIPLIED + src_premultiply_enable = src_premultiply_enable & ~(1 << 8); +#endif + in_premult = 0x00000000; + } + if(source->premultiplied == target->premultiplied && premul_flag == 0) { + target->apply_premult = 1; + } + else { + target->apply_premult = 0; + } +#if (gcFEATURE_VG_SRC_PREMULTIPLIED == 0) + if(blend == VG_LITE_BLEND_NORMAL_LVGL) + in_premult = 0x00000000; +#endif +#if VG_SW_BLIT_PRECISION_OPT + if(enableSwPreOpt) { + get_format_bytes(target->format, &mul, &div, &required_align); + //update target memory address + bufferAddress = target->address; + bufferAddress = bufferAddress + point_min.y * target->stride + point_min.x * (mul / div); + //base address need align + bufferAlignAddress = bufferAddress & ~(required_align - 1); + + //update buffer pointer address + bufferPointer = (uint8_t *)target->memory; + bufferPointer = bufferPointer + (bufferAlignAddress - target->address); + + //update offset + addressOffset = bufferAddress - bufferAlignAddress; + //we need give some offset to match actual translate + matrixOffsetX = addressOffset * div / mul; + + //update new_target and set it as target + memcpy(&new_target, target, sizeof(vg_lite_buffer_t)); + new_target.address = bufferAlignAddress; + new_target.memory = bufferPointer; + new_target.width = point_max.x - point_min.x + matrixOffsetX; + new_target.height = point_max.y - point_min.y; + target = &new_target; + + //update matrix + matrix->m[0][2] = (vg_lite_float_t)(point0_0_afterTransform.x - point_min.x + matrixOffsetX); + matrix->m[1][2] = (vg_lite_float_t)(point0_0_afterTransform.y - point_min.y); + + //modify point_min and point_max to let them start from (0, 0) + point_max.x = point_max.x - point_min.x; + point_max.y = point_max.y - point_min.y; + point_min.x = 0; + point_min.y = 0; + } +#endif /* VG_SW_BLIT_PRECISION_OPT */ + + error = set_render_target(target); + if(error != VG_LITE_SUCCESS) { + return error; + } + + /* Compute inverse matrix. */ + if(!inverse(&inverse_matrix, matrix)) + return VG_LITE_INVALID_ARGUMENT; + +#if gcFEATURE_VG_MATH_PRECISION_FIX + if(filter == VG_LITE_FILTER_LINEAR) { + /* Compute interpolation steps. */ + x_step[0] = (inverse_matrix.m[0][0] - 0.5f * inverse_matrix.m[2][0]); + x_step[1] = inverse_matrix.m[1][0]; + x_step[2] = inverse_matrix.m[2][0]; + y_step[0] = (inverse_matrix.m[0][1] - 0.5f * inverse_matrix.m[2][1]); + y_step[1] = inverse_matrix.m[1][1]; + y_step[2] = inverse_matrix.m[2][1]; + c_step[0] = (0.5f * (inverse_matrix.m[0][0] + inverse_matrix.m[0][1]) - 0.25f * (inverse_matrix.m[2][0] + + inverse_matrix.m[2][1]) + inverse_matrix.m[0][2] - 0.5f * inverse_matrix.m[2][2]); + c_step[1] = (0.5f * (inverse_matrix.m[1][0] + inverse_matrix.m[1][1]) + inverse_matrix.m[1][2]); + c_step[2] = 0.5f * (inverse_matrix.m[2][0] + inverse_matrix.m[2][1]) + inverse_matrix.m[2][2]; + } + else if(filter == VG_LITE_FILTER_BI_LINEAR) { + /* Shift the linear sampling points to center of pixels to avoid pixel offset issue */ + x_step[0] = (inverse_matrix.m[0][0] - 0.5f * inverse_matrix.m[2][0]); + x_step[1] = (inverse_matrix.m[1][0] - 0.5f * inverse_matrix.m[2][0]); + x_step[2] = inverse_matrix.m[2][0]; + y_step[0] = (inverse_matrix.m[0][1] - 0.5f * inverse_matrix.m[2][1]); + y_step[1] = (inverse_matrix.m[1][1] - 0.5f * inverse_matrix.m[2][1]); + y_step[2] = inverse_matrix.m[2][1]; + c_step[0] = (0.5f * (inverse_matrix.m[0][0] + inverse_matrix.m[0][1]) - 0.25f * (inverse_matrix.m[2][0] + + inverse_matrix.m[2][1]) + inverse_matrix.m[0][2] - 0.5f * inverse_matrix.m[2][2]); + c_step[1] = (0.5f * (inverse_matrix.m[1][0] + inverse_matrix.m[1][1]) - 0.25f * (inverse_matrix.m[2][0] + + inverse_matrix.m[2][1]) + inverse_matrix.m[1][2] - 0.5f * inverse_matrix.m[2][2]); + c_step[2] = 0.5f * (inverse_matrix.m[2][0] + inverse_matrix.m[2][1]) + inverse_matrix.m[2][2]; + } + else { + /* Compute interpolation steps. */ + x_step[0] = inverse_matrix.m[0][0]; + x_step[1] = inverse_matrix.m[1][0]; + x_step[2] = inverse_matrix.m[2][0]; + y_step[0] = inverse_matrix.m[0][1]; + y_step[1] = inverse_matrix.m[1][1]; + y_step[2] = inverse_matrix.m[2][1]; + c_step[0] = (0.5f * (inverse_matrix.m[0][0] + inverse_matrix.m[0][1]) + inverse_matrix.m[0][2]); + c_step[1] = (0.5f * (inverse_matrix.m[1][0] + inverse_matrix.m[1][1]) + inverse_matrix.m[1][2]); + c_step[2] = 0.5f * (inverse_matrix.m[2][0] + inverse_matrix.m[2][1]) + inverse_matrix.m[2][2]; + + // For FL32 rounding trick + uint32_t datax[2], datay[2], datac[2]; + for(int idx = 0; idx < 2; idx++) { + datax[idx] = *(uint32_t *)((void *)&x_step[idx]); + datay[idx] = *(uint32_t *)((void *)&y_step[idx]); + datac[idx] = *(uint32_t *)((void *)&c_step[idx]); + } + for(int i = 0; i < 2; i++) { + int aSign = (datax[i] & 0x80000000) >> 31; + int bSign = (datay[i] & 0x80000000) >> 31; + int cSign = (datac[i] & 0x80000000) >> 31; + int aIn = (datax[i] & 0x20) >> 5; + int bIn = (datay[i] & 0x20) >> 5; + if((aSign == 0) && (bSign == 0) && (aIn == bIn)) { + int cIn = (aSign ^ cSign) ^ ((~aIn) & 0x1); + if(cIn == 0) { + datac[i] &= 0xFFFFFFDF; + } + else { + datac[i] |= 0x00000020; + } + c_step[i] = *(vg_lite_float_t *)((void *)&datac[i]); + } + } + } +#else + if(filter == VG_LITE_FILTER_LINEAR) { + /* Compute interpolation steps. */ + x_step[0] = (inverse_matrix.m[0][0] - 0.5f * inverse_matrix.m[2][0]) / source->width; + x_step[1] = inverse_matrix.m[1][0] / source->height; + x_step[2] = inverse_matrix.m[2][0]; + y_step[0] = (inverse_matrix.m[0][1] - 0.5f * inverse_matrix.m[2][1]) / source->width; + y_step[1] = inverse_matrix.m[1][1] / source->height; + y_step[2] = inverse_matrix.m[2][1]; + c_step[0] = (0.5f * (inverse_matrix.m[0][0] + inverse_matrix.m[0][1]) - 0.25f * (inverse_matrix.m[2][0] + + inverse_matrix.m[2][1]) + inverse_matrix.m[0][2] - 0.5f * inverse_matrix.m[2][2]) / source->width; + c_step[1] = (0.5f * (inverse_matrix.m[1][0] + inverse_matrix.m[1][1]) + inverse_matrix.m[1][2]) / source->height; + c_step[2] = 0.5f * (inverse_matrix.m[2][0] + inverse_matrix.m[2][1]) + inverse_matrix.m[2][2]; + } + else if(filter == VG_LITE_FILTER_BI_LINEAR) { + /* Shift the linear sampling points to center of pixels to avoid pixel offset issue */ + x_step[0] = (inverse_matrix.m[0][0] - 0.5f * inverse_matrix.m[2][0]) / source->width; + x_step[1] = (inverse_matrix.m[1][0] - 0.5f * inverse_matrix.m[2][0]) / source->height; + x_step[2] = inverse_matrix.m[2][0]; + y_step[0] = (inverse_matrix.m[0][1] - 0.5f * inverse_matrix.m[2][1]) / source->width; + y_step[1] = (inverse_matrix.m[1][1] - 0.5f * inverse_matrix.m[2][1]) / source->height; + y_step[2] = inverse_matrix.m[2][1]; + c_step[0] = (0.5f * (inverse_matrix.m[0][0] + inverse_matrix.m[0][1]) - 0.25f * (inverse_matrix.m[2][0] + + inverse_matrix.m[2][1]) + inverse_matrix.m[0][2] - 0.5f * inverse_matrix.m[2][2]) / source->width; + c_step[1] = (0.5f * (inverse_matrix.m[1][0] + inverse_matrix.m[1][1]) - 0.25f * (inverse_matrix.m[2][0] + + inverse_matrix.m[2][1]) + inverse_matrix.m[1][2] - 0.5f * inverse_matrix.m[2][2]) / source->height; + c_step[2] = 0.5f * (inverse_matrix.m[2][0] + inverse_matrix.m[2][1]) + inverse_matrix.m[2][2]; + } + else { + /* Compute interpolation steps. */ + x_step[0] = inverse_matrix.m[0][0] / source->width; + x_step[1] = inverse_matrix.m[1][0] / source->height; + x_step[2] = inverse_matrix.m[2][0]; + y_step[0] = inverse_matrix.m[0][1] / source->width; + y_step[1] = inverse_matrix.m[1][1] / source->height; + y_step[2] = inverse_matrix.m[2][1]; + c_step[0] = (0.5f * (inverse_matrix.m[0][0] + inverse_matrix.m[0][1]) + inverse_matrix.m[0][2]) / source->width; + c_step[1] = (0.5f * (inverse_matrix.m[1][0] + inverse_matrix.m[1][1]) + inverse_matrix.m[1][2]) / source->height; + c_step[2] = 0.5f * (inverse_matrix.m[2][0] + inverse_matrix.m[2][1]) + inverse_matrix.m[2][2]; + } +#endif + +#if VG_SW_BLIT_PRECISION_OPT + /* Update C offset */ + if(enableSwPreOpt) { + uint8_t indexC0 = 0; + uint8_t indexC1 = 0; + uint32_t temp0 = (uint32_t)(matrix->angle / 45); + uint32_t temp1 = (uint32_t)(matrix->scaleX * 100); + uint32_t temp2 = (uint32_t)(matrix->scaleY * 100); + indexC0 = GetIndex(temp0, temp1); + indexC1 = GetIndex(temp0, temp2); + c_step[0] = c_step[0] + offsetTable[indexC0]; + c_step[1] = c_step[1] + offsetTable[indexC1]; + } +#else + c_step[0] = c_step[0] + offsetTable[0]; + c_step[1] = c_step[1] + offsetTable[0]; +#endif /* VG_SW_BLIT_PRECISION_OPT */ + + /* Determine image mode (NORMAL, NONE , MULTIPLY or STENCIL) depending on the color. */ + switch(source->image_mode) { + case VG_LITE_NONE_IMAGE_MODE: + imageMode = 0x00000000; + break; + case VG_LITE_MULTIPLY_IMAGE_MODE: + imageMode = 0x00002000; + break; + case VG_LITE_NORMAL_IMAGE_MODE: + case VG_LITE_ZERO: + imageMode = 0x00001000; + break; + case VG_LITE_STENCIL_MODE: + imageMode = 0x00003000; + break; + case VG_LITE_RECOLOR_MODE: + imageMode = 0x00006000; + break; + } + + switch(filter) { + case VG_LITE_FILTER_POINT: + filter_mode = 0; + break; + + case VG_LITE_FILTER_LINEAR: + filter_mode = 0x10000; + break; + + case VG_LITE_FILTER_BI_LINEAR: + filter_mode = 0x20000; + break; + + case VG_LITE_FILTER_GAUSSIAN: + filter_mode = 0x30000; + break; + } + + switch(source->paintType) { + case VG_LITE_PAINT_COLOR: + paintType = 0; + break; + + case VG_LITE_PAINT_LINEAR_GRADIENT: + paintType = 1 << 24; + break; + + case VG_LITE_PAINT_RADIAL_GRADIENT: + paintType = 1 << 25; + break; + + case VG_LITE_PAINT_PATTERN: + paintType = 1 << 24 | 1 << 25; + break; + + default: + break; + } + + blend_mode = convert_blend(blend); + tiled_source = (source->tiled != VG_LITE_LINEAR) ? 0x10000000 : 0 ; +#if gcFEATURE_VG_RECTANGLE_TILED_OUT + if(target->tiled == VG_LITE_TILED) { + tile_setting = 0x40; + stripe_mode = 0x20000000; + } +#endif + +#if (gcFEATURE_VG_DEC_COMPRESS | gcFEATURE_VG_DEC_COMPRESS_2_0) + if(source->compress_mode != VG_LITE_DEC_DISABLE && target->compress_mode == VG_LITE_DEC_DISABLE) { + if(source->format != target->format) { + printf("The format of source and target buffers is inconsistent in decompressing!\n"); + return VG_LITE_INVALID_ARGUMENT; + } + } +#endif + compress_mode = (uint32_t)source->compress_mode << 25; + + /* Setup the command buffer. */ +#if gcFEATURE_VG_GLOBAL_ALPHA + VG_LITE_RETURN_ERROR(push_state(&s_context, 0x0AD1, + s_context.dst_alpha_mode | s_context.dst_alpha_value | s_context.src_alpha_mode | s_context.src_alpha_value)); +#endif + VG_LITE_RETURN_ERROR(push_state(&s_context, 0x0A00, + 0x00000001 | paintType | in_premult | imageMode | blend_mode | transparency_mode | tile_setting | s_context.enable_mask + | s_context.color_transform | s_context.matrix_enable | eco_fifo | s_context.scissor_enable | stripe_mode)); + VG_LITE_RETURN_ERROR(push_state(&s_context, 0x0A02, color)); + VG_LITE_RETURN_ERROR(push_state_ptr(&s_context, 0x0A18, (void *) &c_step[0])); + VG_LITE_RETURN_ERROR(push_state_ptr(&s_context, 0x0A19, (void *) &c_step[1])); + VG_LITE_RETURN_ERROR(push_state_ptr(&s_context, 0x0A1A, (void *) &c_step[2])); + VG_LITE_RETURN_ERROR(push_state_ptr(&s_context, 0x0A1C, (void *) &x_step[0])); + VG_LITE_RETURN_ERROR(push_state_ptr(&s_context, 0x0A1D, (void *) &x_step[1])); + VG_LITE_RETURN_ERROR(push_state_ptr(&s_context, 0x0A1E, (void *) &x_step[2])); + VG_LITE_RETURN_ERROR(push_state(&s_context, 0x0A1F, 0x00000001)); + VG_LITE_RETURN_ERROR(push_state_ptr(&s_context, 0x0A20, (void *) &y_step[0])); + VG_LITE_RETURN_ERROR(push_state_ptr(&s_context, 0x0A21, (void *) &y_step[1])); + VG_LITE_RETURN_ERROR(push_state_ptr(&s_context, 0x0A22, (void *) &y_step[2])); + + if(((source->format >= VG_LITE_YUY2) && + (source->format <= VG_LITE_AYUY2)) || + ((source->format >= VG_LITE_YUY2_TILED) && + (source->format <= VG_LITE_AYUY2_TILED))) { + yuv2rgb = convert_yuv2rgb(source->yuv.yuv2rgb); + uv_swiz = convert_uv_swizzle(source->yuv.swizzle); + } + +#if gcFEATURE_VG_IM_FASTCLEAR + if(source->fc_enable) { + uint32_t im_fc_enable = (source->fc_enable == 0) ? 0 : 0x800000; + VG_LITE_RETURN_ERROR(push_state(&s_context, 0x0A25, + convert_source_format(source->format) | filter_mode | uv_swiz | yuv2rgb | conversion | im_fc_enable | ahb_read_split | + compress_mode | src_premultiply_enable | index_endian)); + VG_LITE_RETURN_ERROR(push_state(&s_context, 0x0ACF, source->fc_buffer[0].address)); /* FC buffer address. */ + VG_LITE_RETURN_ERROR(push_state(&s_context, 0x0AD0, source->fc_buffer[0].color)); /* FC clear value. */ + } +#endif + + VG_LITE_RETURN_ERROR(push_state(&s_context, 0x0A25, + convert_source_format(source->format) | filter_mode | uv_swiz | yuv2rgb | conversion | compress_mode | + src_premultiply_enable | index_endian)); + if(source->yuv.uv_planar) { + /* Program u plane address if necessary. */ + VG_LITE_RETURN_ERROR(push_state(&s_context, 0x0A51, source->yuv.uv_planar)); + } + if(source->yuv.v_planar) { + /* Program v plane address if necessary. */ + VG_LITE_RETURN_ERROR(push_state(&s_context, 0x0A53, source->yuv.v_planar)); + } + if(source->yuv.alpha_planar != 0) { + VG_LITE_RETURN_ERROR(push_state(&s_context, 0x0A53, source->yuv.alpha_planar)); + } + VG_LITE_RETURN_ERROR(push_state(&s_context, 0x0A27, target->bg_color)); + +#if !gcFEATURE_VG_LVGL_SUPPORT + if(lvgl_sw_blend) { + VG_LITE_RETURN_ERROR(push_state(&s_context, 0x0A29, source->lvgl_buffer->address)); + } + else +#endif + VG_LITE_RETURN_ERROR(push_state(&s_context, 0x0A29, source->address)); + + VG_LITE_RETURN_ERROR(push_state(&s_context, 0x0A34, 0)); + /* 24bit format stride configured to 4bpp. */ + if(source->format >= VG_LITE_RGB888 && source->format <= VG_LITE_RGBA5658) { + stride = source->stride / 3 * 4; + VG_LITE_RETURN_ERROR(push_state(&s_context, 0x0A2B, stride | tiled_source)); + } + else { + VG_LITE_RETURN_ERROR(push_state(&s_context, 0x0A2B, source->stride | tiled_source)); + } + + VG_LITE_RETURN_ERROR(push_state(&s_context, 0x0A2D, 0)); + VG_LITE_RETURN_ERROR(push_state(&s_context, 0x0A2F, source->width | (source->height << 16))); + +#if VG_SW_BLIT_PRECISION_OPT + if(enableSwPreOpt) { + VG_LITE_RETURN_ERROR(push_rectangle(&s_context, point_min.x + matrixOffsetX, point_min.y, point_max.x - point_min.x, + point_max.y - point_min.y)); + } + else +#endif /* VG_SW_BLIT_PRECISION_OPT */ + { + VG_LITE_RETURN_ERROR(push_rectangle(&s_context, point_min.x, point_min.y, point_max.x - point_min.x, + point_max.y - point_min.y)); + } + +#if !gcFEATURE_VG_STRIPE_MODE + VG_LITE_RETURN_ERROR(push_state(&s_context, 0x0E02, 0x10 | (0x7 << 8))); + VG_LITE_RETURN_ERROR(push_state(&s_context, 0x0F00, 0x10 | (0x7 << 8))); +#endif + + if(!s_context.flexa_mode) { + error = flush_target(); + } +#if gcFEATURE_VG_GLOBAL_ALPHA + if(blend >= VG_LITE_BLEND_NORMAL_LVGL && blend <= VG_LITE_BLEND_MULTIPLY_LVGL) { + VG_LITE_RETURN_ERROR(vg_lite_dest_global_alpha(VG_LITE_NORMAL, 0xFF)); + } +#endif + + vglitemDUMP_BUFFER("image", (size_t)source->address, source->memory, 0, (source->stride) * (source->height)); + +#if DUMP_IMAGE + dump_img(source->memory, source->width, source->height, source->format); +#endif + + return error; +#else + return VG_LITE_NOT_SUPPORT; +#endif +} + +vg_lite_error_t vg_lite_blit_rect(vg_lite_buffer_t * target, + vg_lite_buffer_t * source, + vg_lite_rectangle_t * rect, + vg_lite_matrix_t * matrix, + vg_lite_blend_t blend, + vg_lite_color_t color, + vg_lite_filter_t filter) +{ +#if DUMP_API + FUNC_DUMP(vg_lite_blit_rect)(target, source, rect, matrix, blend, color, filter); +#endif + +#if gcFEATURE_VG_IM_INPUT + vg_lite_error_t error; + vg_lite_point_t point_min, point_max, temp; + vg_lite_matrix_t inverse_matrix; + vg_lite_float_t x_step[3]; + vg_lite_float_t y_step[3]; + vg_lite_float_t c_step[3]; + uint32_t imageMode = 0; + uint32_t paintType = 0; + uint32_t in_premult = 0; + uint32_t blend_mode; + uint32_t filter_mode = 0; + uint32_t transparency_mode = 0; + uint32_t conversion = 0; + uint32_t rect_x = 0, rect_y = 0, rect_w = 0, rect_h = 0; + uint32_t tiled_source; + uint32_t yuv2rgb = 0; + uint32_t uv_swiz = 0; + uint32_t compress_mode = 0; + uint32_t src_premultiply_enable = 0; + uint32_t index_endian = 0; + uint32_t eco_fifo = 0; + uint32_t tile_setting = 0; + uint32_t stripe_mode = 0; + uint32_t premul_flag = 0; + uint32_t prediv_flag = 0; + int32_t left, top, right, bottom; + int32_t stride; + uint8_t lvgl_sw_blend = 0; +#if VG_SW_BLIT_PRECISION_OPT + uint8_t * bufferPointer; + uint32_t bufferAddress = 0, bufferAlignAddress = 0, addressOffset = 0, mul = 0, div = 0, required_align = 0; + vg_lite_buffer_t new_target; + vg_lite_point_t point0_0_afterTransform = { 0 }; + uint8_t enableSwPreOpt = 0; + int32_t matrixOffsetX = 0; + + /* Only accept interger move */ + if(matrix != NULL && filter == VG_LITE_FILTER_POINT) { + matrix->m[0][2] = (vg_lite_float_t)(matrix->m[0][2] >= 0 ? (int32_t)(matrix->m[0][2] + 0.5) : (int32_t)( + matrix->m[0][2] - 0.5)); + matrix->m[1][2] = (vg_lite_float_t)(matrix->m[1][2] >= 0 ? (int32_t)(matrix->m[1][2] + 0.5) : (int32_t)( + matrix->m[1][2] - 0.5)); + /* Only nonperspective transform with scale or rotation could enable optimization */ + if((matrix->m[2][0] == 0.0f && matrix->m[2][1] == 0.0f && matrix->m[2][2] == 1.0f) && + (matrix->m[0][0] != 1.0f || matrix->m[1][1] != 1.0f || matrix->m[0][1] != 0.0f)) { + if(target->tiled != VG_LITE_TILED && (target->format < VG_LITE_RGB888 || target->format > VG_LITE_RGBA5658_PLANAR)) { + enableSwPreOpt = 1; + } + } + } +#endif /* VG_SW_BLIT_PRECISION_OPT */ + +#if gcFEATURE_VG_TRACE_API + VGLITE_LOG("vg_lite_blit_rect %p %p %p %p %d 0x%08X %d\n", target, source, rect, matrix, blend, color, filter); +#endif + +#if gcFEATURE_VG_ERROR_CHECK +#if !gcFEATURE_VG_INDEX_ENDIAN + if((source->format >= VG_LITE_INDEX_1) && (source->format <= VG_LITE_INDEX_4) && source->index_endian) { + return VG_LITE_NOT_SUPPORT; + } +#endif + +#if !gcFEATURE_VG_RGBA8_ETC2_EAC + if(source->format == VG_LITE_RGBA8888_ETC2_EAC) { + return VG_LITE_NOT_SUPPORT; + } +#else + if((source->format == VG_LITE_RGBA8888_ETC2_EAC) && (source->width % 16 || source->height % 4)) { + return VG_LITE_INVALID_ARGUMENT; + } +#endif +#if !gcFEATURE_VG_YUY2_INPUT + if(source->format == VG_LITE_YUYV || source->format == VG_LITE_YUY2) { + return VG_LITE_NOT_SUPPORT; + } +#endif +#if !gcFEATURE_VG_YUV_INPUT + if((source->format >= VG_LITE_NV12 && source->format <= VG_LITE_NV16) || source->format == VG_LITE_NV24) { + return VG_LITE_NOT_SUPPORT; + } +#elif !gcFEATURE_VG_NV24_INPUT + if(source->format == VG_LITE_NV24) { + return VG_LITE_NOT_SUPPORT; + } +#endif +#if !gcFEATURE_VG_AYUV_INPUT + if(source->format == VG_LITE_ANV12 || source->format == VG_LITE_AYUY2) { + return VG_LITE_NOT_SUPPORT; + } +#endif +#if !gcFEATURE_VG_YUV_TILED_INPUT + if((source->format >= VG_LITE_YUY2_TILED && source->format <= VG_LITE_AYUY2_TILED) || + (source->format == VG_LITE_NV24_TILED)) { + return VG_LITE_NOT_SUPPORT; + } +#endif +#if !gcFEATURE_VG_24BIT + if((target->format >= VG_LITE_RGB888 && target->format <= VG_LITE_RGBA5658) || + (source->format >= VG_LITE_RGB888 && source->format <= VG_LITE_RGBA5658)) { + return VG_LITE_NOT_SUPPORT; + } +#endif +#if !gcFEATURE_VG_24BIT_PLANAR + if(source->format >= VG_LITE_ABGR8565_PLANAR && source->format <= VG_LITE_RGBA5658_PLANAR) { + return VG_LITE_NOT_SUPPORT; + } +#endif +#if !gcFEATURE_VG_IM_DEC_INPUT + if(source->compress_mode != VG_LITE_DEC_DISABLE) { + return VG_LITE_NOT_SUPPORT; + } +#endif +#if !gcFEATURE_VG_STENCIL + if(source->image_mode == VG_LITE_STENCIL_MODE) { + return VG_LITE_NOT_SUPPORT; + } +#endif +#if !gcFEATURE_VG_NEW_BLEND_MODE + if(blend == VG_LITE_BLEND_DARKEN || blend == VG_LITE_BLEND_LIGHTEN) { + return VG_LITE_NOT_SUPPORT; + } +#endif + if(blend && (target->format == VG_LITE_YUYV || target->format == VG_LITE_YUY2 || target->format == VG_LITE_YUY2_TILED + || target->format == VG_LITE_AYUY2 || target->format == VG_LITE_AYUY2_TILED)) { + return VG_LITE_NOT_SUPPORT; + } +#if (CHIPID == 0x355) + if(target->format == VG_LITE_L8 || target->format == VG_LITE_YUYV || + target->format == VG_LITE_BGRA2222 || target->format == VG_LITE_RGBA2222 || + target->format == VG_LITE_ABGR2222 || target->format == VG_LITE_ARGB2222) { + printf("Target format: 0x%x is not supported.\n", target->format); + return VG_LITE_NOT_SUPPORT; + } + if(source->format == VG_LITE_L8 || source->format == VG_LITE_YUYV || + source->format == VG_LITE_BGRA2222 || source->format == VG_LITE_RGBA2222 || + source->format == VG_LITE_ABGR2222 || source->format == VG_LITE_ARGB2222) { + printf("Source format: 0x%x is not supported.\n", source->format); + return VG_LITE_NOT_SUPPORT; + } +#endif + + VG_LITE_RETURN_ERROR(srcbuf_align_check(source)); + VG_LITE_RETURN_ERROR(check_compress(source->format, source->compress_mode, source->tiled, source->width, + source->height)); +#endif /* gcFEATURE_VG_ERROR_CHECK */ + +#if !gcFEATURE_VG_LVGL_SUPPORT + if((blend >= VG_LITE_BLEND_ADDITIVE_LVGL && blend <= VG_LITE_BLEND_MULTIPLY_LVGL) || + (blend == VG_LITE_BLEND_NORMAL_LVGL && gcFEATURE_VG_SRC_PREMULTIPLIED)) { + if(!source->lvgl_buffer) { + source->lvgl_buffer = (vg_lite_buffer_t *)vg_lite_os_malloc(sizeof(vg_lite_buffer_t)); + *source->lvgl_buffer = *source; + source->lvgl_buffer->lvgl_buffer = NULL; + vg_lite_allocate(source->lvgl_buffer); + } + /* Make sure render target is up to date before reading RT. */ + vg_lite_finish(); + setup_lvgl_image(target, source, source->lvgl_buffer, blend); + blend = VG_LITE_BLEND_SRC_OVER; + lvgl_sw_blend = 1; + } +#endif + + if(!matrix) { + matrix = &identity_mtx; + } + +#if gcFEATURE_VG_INDEX_ENDIAN + if((source->format >= VG_LITE_INDEX_1) && (source->format <= VG_LITE_INDEX_4) && source->index_endian) { + index_endian = 1 << 14; + } +#endif +#if !gcFEATURE_VG_STRIPE_MODE + /* Enable fifo feature to share buffer between vg and ts to improve the rotation performance */ + eco_fifo = 1 << 7; +#endif + + transparency_mode = (source->transparency_mode == VG_LITE_IMAGE_TRANSPARENT ? 0x8000 : 0); + s_context.filter = filter; + + /* Check if the specified matrix has rotation or perspective. */ + if(((matrix->m[0][1] != 0.0f) + || (matrix->m[1][0] != 0.0f) + || (matrix->m[2][0] != 0.0f) + || (matrix->m[2][1] != 0.0f) + || (matrix->m[2][2] != 1.0f) + ) + && (blend == VG_LITE_BLEND_NONE + || blend == VG_LITE_BLEND_SRC_IN + || blend == VG_LITE_BLEND_DST_IN + ) + ) { +#if gcFEATURE_VG_BORDER_CULLING + /* Mark that we have rotation. */ + transparency_mode = 0x8000; +#else + blend = VG_LITE_BLEND_SRC_OVER; +#endif +#if !gcFEATURE_VG_STRIPE_MODE + stripe_mode = 1 << 29; +#endif + } + + /* Check whether L8 is supported or not. */ + if((target->format == VG_LITE_L8) && ((source->format != VG_LITE_L8) && (source->format != VG_LITE_A8))) { + conversion = 0x80000000; + } + +#if gcFEATURE_VG_16PIXELS_ALIGNED + /* Check if source specify bytes are aligned */ + error = _check_source_aligned(source->format, source->stride); + if(error != VG_LITE_SUCCESS) { + return error; + } +#endif + /* Set source region. */ + if(rect != NULL) { + rect_x = (rect->x < 0) ? 0 : rect->x; + rect_y = (rect->y < 0) ? 0 : rect->y; + rect_w = rect->width; + rect_h = rect->height; + if((rect_x > (uint32_t)source->width) || (rect_y > (uint32_t)source->height) || + (rect_w == 0) || (rect_h == 0)) { + /*No intersection*/ + return VG_LITE_INVALID_ARGUMENT; + } + if(rect_x + rect_w > (uint32_t)source->width) { + rect_w = source->width - rect_x; + } + if(rect_y + rect_h > (uint32_t)source->height) { + rect_h = source->height - rect_y; + } + } + else { + rect_x = rect_y = 0; + rect_w = source->width; + rect_h = source->height; + } + + /* Transform image (0,0) to screen. */ + if(!transform(&temp, 0.0f, 0.0f, matrix)) + return VG_LITE_INVALID_ARGUMENT; + + /* Set initial point. */ + point_min = temp; + point_max = temp; +#if VG_SW_BLIT_PRECISION_OPT + point0_0_afterTransform = temp; +#endif /* VG_SW_BLIT_PRECISION_OPT */ + + /* Transform image (0,height) to screen. */ + if(!transform(&temp, 0.0f, (vg_lite_float_t)rect_h, matrix)) + return VG_LITE_INVALID_ARGUMENT; + + /* Determine min/max. */ + if(temp.x < point_min.x) point_min.x = temp.x; + if(temp.y < point_min.y) point_min.y = temp.y; + if(temp.x > point_max.x) point_max.x = temp.x; + if(temp.y > point_max.y) point_max.y = temp.y; + + /* Transform image (width,height) to screen. */ + if(!transform(&temp, (vg_lite_float_t)rect_w, (vg_lite_float_t)rect_h, matrix)) + return VG_LITE_INVALID_ARGUMENT; + + /* Determine min/max. */ + if(temp.x < point_min.x) point_min.x = temp.x; + if(temp.y < point_min.y) point_min.y = temp.y; + if(temp.x > point_max.x) point_max.x = temp.x; + if(temp.y > point_max.y) point_max.y = temp.y; + + /* Transform image (width,0) to screen. */ + if(!transform(&temp, (vg_lite_float_t)rect_w, 0.0f, matrix)) + return VG_LITE_INVALID_ARGUMENT; + + /* Determine min/max. */ + if(temp.x < point_min.x) point_min.x = temp.x; + if(temp.y < point_min.y) point_min.y = temp.y; + if(temp.x > point_max.x) point_max.x = temp.x; + if(temp.y > point_max.y) point_max.y = temp.y; + + /* Clip to target. */ + if(s_context.scissor_set && !target->scissor_buffer) { + left = s_context.scissor[0]; + top = s_context.scissor[1]; + right = s_context.scissor[2]; + bottom = s_context.scissor[3]; + } + else { + left = 0; + top = 0; + right = target->width; + bottom = target->height; + } + + point_min.x = MAX(point_min.x, left); + point_min.y = MAX(point_min.y, top); + point_max.x = MIN(point_max.x, right); + point_max.y = MIN(point_max.y, bottom); + + /* No need to draw. */ + if((point_max.x <= point_min.x) || (point_max.y <= point_min.y)) { + return VG_LITE_SUCCESS; + } + +#if gcFEATURE_VG_GAMMA + get_st_gamma_src_dest(source, target); +#endif + +#if gcFEATURE_VG_GLOBAL_ALPHA + if(blend >= VG_LITE_BLEND_NORMAL_LVGL && blend <= VG_LITE_BLEND_MULTIPLY_LVGL) { + VG_LITE_RETURN_ERROR(vg_lite_dest_global_alpha(VG_LITE_GLOBAL, 0xff)); + } +#endif + + /*blend input into context*/ + s_context.blend_mode = blend; + in_premult = 0x00000000; + + /* Adjust premultiply setting according to openvg condition */ + src_premultiply_enable = 0x01000100; + if(s_context.color_transform == 0 && s_context.gamma_dst == s_context.gamma_src && s_context.matrix_enable == 0 && + s_context.dst_alpha_mode == 0 && s_context.src_alpha_mode == 0 && + (source->image_mode == VG_LITE_NORMAL_IMAGE_MODE || source->image_mode == 0)) { + prediv_flag = 0; + } + else { + prediv_flag = 1; + } + if((s_context.blend_mode >= OPENVG_BLEND_SRC && s_context.blend_mode <= OPENVG_BLEND_ADDITIVE) || + source->image_mode == VG_LITE_STENCIL_MODE + || (s_context.blend_mode >= VG_LITE_BLEND_NORMAL_LVGL && s_context.blend_mode <= VG_LITE_BLEND_MULTIPLY_LVGL)) { + premul_flag = 1; + } + else { + premul_flag = 0; + } + + if((source->premultiplied == 0 && target->premultiplied == 0 && premul_flag == 0) || + (source->premultiplied == 1 && target->premultiplied == 0 && prediv_flag == 0)) { + src_premultiply_enable = 0x01000100; + in_premult = 0x10000000; + } + /* when src and dst all pre format, im pre_out set to 0 to perform data truncation to prevent data overflow */ + else if(source->premultiplied == 1 && target->premultiplied == 1 && prediv_flag == 0) { + src_premultiply_enable = 0x00000100; + in_premult = 0x00000000; + } + else if((source->premultiplied == 0 && target->premultiplied == 1) || + (source->premultiplied == 0 && target->premultiplied == 0 && premul_flag == 1)) { + src_premultiply_enable = 0x01000100; + in_premult = 0x00000000; + } + else if((source->premultiplied == 1 && target->premultiplied == 1 && prediv_flag == 1) || + (source->premultiplied == 1 && target->premultiplied == 0 && prediv_flag == 1)) { + src_premultiply_enable = 0x00000100; + in_premult = 0x00000000; + } + if((source->format == VG_LITE_A4 || source->format == VG_LITE_A8) && blend >= VG_LITE_BLEND_SRC_OVER && + blend <= VG_LITE_BLEND_SUBTRACT) { +#if (CHIPID==0x255) + src_premultiply_enable = 0x00000000; +#endif +#if gcFEATURE_VG_SRC_PREMULTIPLIED + src_premultiply_enable = src_premultiply_enable & ~(1 << 8); +#endif + in_premult = 0x00000000; + } + if(source->premultiplied == target->premultiplied && premul_flag == 0) { + target->apply_premult = 1; + } + else { + target->apply_premult = 0; + } +#if (gcFEATURE_VG_SRC_PREMULTIPLIED == 0) + if(blend == VG_LITE_BLEND_NORMAL_LVGL) + in_premult = 0x00000000; +#endif +#if VG_SW_BLIT_PRECISION_OPT + if(enableSwPreOpt) { + get_format_bytes(target->format, &mul, &div, &required_align); + //update target memory address + bufferAddress = target->address; + bufferAddress = bufferAddress + point_min.y * target->stride + point_min.x * (mul / div); + //base address need align + bufferAlignAddress = bufferAddress & ~(required_align - 1); + + //update buffer pointer address + bufferPointer = (uint8_t *)target->memory; + bufferPointer = bufferPointer + (bufferAlignAddress - target->address); + + //update offset + addressOffset = bufferAddress - bufferAlignAddress; + //we need give some offset to match actual translate + matrixOffsetX = addressOffset * div / mul; + + //update new_target and set it as target + memcpy(&new_target, target, sizeof(vg_lite_buffer_t)); + new_target.address = bufferAlignAddress; + new_target.memory = bufferPointer; + new_target.width = point_max.x - point_min.x + matrixOffsetX; + new_target.height = point_max.y - point_min.y; + target = &new_target; + + //update matrix + matrix->m[0][2] = (vg_lite_float_t)(point0_0_afterTransform.x - point_min.x + matrixOffsetX); + matrix->m[1][2] = (vg_lite_float_t)(point0_0_afterTransform.y - point_min.y); + + //modify point_min and point_max to let them start from (0, 0) + point_max.x = point_max.x - point_min.x; + point_max.y = point_max.y - point_min.y; + point_min.x = 0; + point_min.y = 0; + } +#endif /* VG_SW_BLIT_PRECISION_OPT */ + error = set_render_target(target); + if(error != VG_LITE_SUCCESS) { + return error; + } + + /* Compute inverse matrix. */ + if(!inverse(&inverse_matrix, matrix)) + return VG_LITE_INVALID_ARGUMENT; + +#if gcFEATURE_VG_MATH_PRECISION_FIX + if(filter == VG_LITE_FILTER_LINEAR) { + /* Compute interpolation steps. */ + x_step[0] = (inverse_matrix.m[0][0] - 0.5f * inverse_matrix.m[2][0]); + x_step[1] = inverse_matrix.m[1][0]; + x_step[2] = inverse_matrix.m[2][0]; + y_step[0] = (inverse_matrix.m[0][1] - 0.5f * inverse_matrix.m[2][1]); + y_step[1] = inverse_matrix.m[1][1]; + y_step[2] = inverse_matrix.m[2][1]; + c_step[0] = (0.5f * (inverse_matrix.m[0][0] + inverse_matrix.m[0][1]) - 0.25f * (inverse_matrix.m[2][0] + + inverse_matrix.m[2][1]) + inverse_matrix.m[0][2] - 0.5f * inverse_matrix.m[2][2]); + c_step[1] = (0.5f * (inverse_matrix.m[1][0] + inverse_matrix.m[1][1]) + inverse_matrix.m[1][2]); + c_step[2] = 0.5f * (inverse_matrix.m[2][0] + inverse_matrix.m[2][1]) + inverse_matrix.m[2][2]; + } + else if(filter == VG_LITE_FILTER_BI_LINEAR) { + /* Shift the linear sampling points to center of pixels to avoid pixel offset issue */ + x_step[0] = (inverse_matrix.m[0][0] - 0.5f * inverse_matrix.m[2][0]); + x_step[1] = (inverse_matrix.m[1][0] - 0.5f * inverse_matrix.m[2][0]); + x_step[2] = inverse_matrix.m[2][0]; + y_step[0] = (inverse_matrix.m[0][1] - 0.5f * inverse_matrix.m[2][1]); + y_step[1] = (inverse_matrix.m[1][1] - 0.5f * inverse_matrix.m[2][1]); + y_step[2] = inverse_matrix.m[2][1]; + c_step[0] = (0.5f * (inverse_matrix.m[0][0] + inverse_matrix.m[0][1]) - 0.25f * (inverse_matrix.m[2][0] + + inverse_matrix.m[2][1]) + inverse_matrix.m[0][2] - 0.5f * inverse_matrix.m[2][2]); + c_step[1] = (0.5f * (inverse_matrix.m[1][0] + inverse_matrix.m[1][1]) - 0.25f * (inverse_matrix.m[2][0] + + inverse_matrix.m[2][1]) + inverse_matrix.m[1][2] - 0.5f * inverse_matrix.m[2][2]); + c_step[2] = 0.5f * (inverse_matrix.m[2][0] + inverse_matrix.m[2][1]) + inverse_matrix.m[2][2]; + } + else { + /* Compute interpolation steps. */ + x_step[0] = inverse_matrix.m[0][0]; + x_step[1] = inverse_matrix.m[1][0]; + x_step[2] = inverse_matrix.m[2][0]; + y_step[0] = inverse_matrix.m[0][1]; + y_step[1] = inverse_matrix.m[1][1]; + y_step[2] = inverse_matrix.m[2][1]; + c_step[0] = (0.5f * (inverse_matrix.m[0][0] + inverse_matrix.m[0][1]) + inverse_matrix.m[0][2]); + c_step[1] = (0.5f * (inverse_matrix.m[1][0] + inverse_matrix.m[1][1]) + inverse_matrix.m[1][2]); + c_step[2] = 0.5f * (inverse_matrix.m[2][0] + inverse_matrix.m[2][1]) + inverse_matrix.m[2][2]; + + // For FL32 rounding trick + uint32_t datax[2], datay[2], datac[2]; + for(int idx = 0; idx < 2; idx++) { + datax[idx] = *(uint32_t *)((void *)&x_step[idx]); + datay[idx] = *(uint32_t *)((void *)&y_step[idx]); + datac[idx] = *(uint32_t *)((void *)&c_step[idx]); + } + for(int i = 0; i < 2; i++) { + int aSign = (datax[i] & 0x80000000) >> 31; + int bSign = (datay[i] & 0x80000000) >> 31; + int cSign = (datac[i] & 0x80000000) >> 31; + int aIn = (datax[i] & 0x20) >> 5; + int bIn = (datay[i] & 0x20) >> 5; + if((aSign == 0) && (bSign == 0) && (aIn == bIn)) { + int cIn = (aSign ^ cSign) ^ ((~aIn) & 0x1); + if(cIn == 0) { + datac[i] &= 0xFFFFFFDF; + } + else { + datac[i] |= 0x00000020; + } + c_step[i] = *(vg_lite_float_t *)((void *)&datac[i]); + } + } + } +#else + if(filter == VG_LITE_FILTER_LINEAR) { + /* Compute interpolation steps. */ + x_step[0] = (inverse_matrix.m[0][0] - 0.5f * inverse_matrix.m[2][0]) / rect_w; + x_step[1] = inverse_matrix.m[1][0] / rect_h; + x_step[2] = inverse_matrix.m[2][0]; + y_step[0] = (inverse_matrix.m[0][1] - 0.5f * inverse_matrix.m[2][1]) / rect_w; + y_step[1] = inverse_matrix.m[1][1] / rect_h; + y_step[2] = inverse_matrix.m[2][1]; + c_step[0] = (0.5f * (inverse_matrix.m[0][0] + inverse_matrix.m[0][1]) - 0.25f * (inverse_matrix.m[2][0] + + inverse_matrix.m[2][1]) + inverse_matrix.m[0][2] - 0.5f * inverse_matrix.m[2][2]) / rect_w; + c_step[1] = (0.5f * (inverse_matrix.m[1][0] + inverse_matrix.m[1][1]) + inverse_matrix.m[1][2]) / rect_h; + c_step[2] = 0.5f * (inverse_matrix.m[2][0] + inverse_matrix.m[2][1]) + inverse_matrix.m[2][2]; + } + else if(filter == VG_LITE_FILTER_BI_LINEAR) { + /* Shift the linear sampling points to center of pixels to avoid pixel offset issue */ + x_step[0] = (inverse_matrix.m[0][0] - 0.5f * inverse_matrix.m[2][0]) / rect_w; + x_step[1] = (inverse_matrix.m[1][0] - 0.5f * inverse_matrix.m[2][0]) / rect_h; + x_step[2] = inverse_matrix.m[2][0]; + y_step[0] = (inverse_matrix.m[0][1] - 0.5f * inverse_matrix.m[2][1]) / rect_w; + y_step[1] = (inverse_matrix.m[1][1] - 0.5f * inverse_matrix.m[2][1]) / rect_h; + y_step[2] = inverse_matrix.m[2][1]; + c_step[0] = (0.5f * (inverse_matrix.m[0][0] + inverse_matrix.m[0][1]) - 0.25f * (inverse_matrix.m[2][0] + + inverse_matrix.m[2][1]) + inverse_matrix.m[0][2] - 0.5f * inverse_matrix.m[2][2]) / rect_w; + c_step[1] = (0.5f * (inverse_matrix.m[1][0] + inverse_matrix.m[1][1]) - 0.25f * (inverse_matrix.m[2][0] + + inverse_matrix.m[2][1]) + inverse_matrix.m[1][2] - 0.5f * inverse_matrix.m[2][2]) / rect_h; + c_step[2] = 0.5f * (inverse_matrix.m[2][0] + inverse_matrix.m[2][1]) + inverse_matrix.m[2][2]; + } + else { + /* Compute interpolation steps. */ + x_step[0] = inverse_matrix.m[0][0] / rect_w; + x_step[1] = inverse_matrix.m[1][0] / rect_h; + x_step[2] = inverse_matrix.m[2][0]; + y_step[0] = inverse_matrix.m[0][1] / rect_w; + y_step[1] = inverse_matrix.m[1][1] / rect_h; + y_step[2] = inverse_matrix.m[2][1]; + c_step[0] = (0.5f * (inverse_matrix.m[0][0] + inverse_matrix.m[0][1]) + inverse_matrix.m[0][2]) / rect_w; + c_step[1] = (0.5f * (inverse_matrix.m[1][0] + inverse_matrix.m[1][1]) + inverse_matrix.m[1][2]) / rect_h; + c_step[2] = 0.5f * (inverse_matrix.m[2][0] + inverse_matrix.m[2][1]) + inverse_matrix.m[2][2]; + } +#endif + +#if VG_SW_BLIT_PRECISION_OPT + /* Update C offset */ + if(enableSwPreOpt) { + uint8_t indexC0 = 0; + uint8_t indexC1 = 0; + uint32_t temp0 = (uint32_t)(matrix->angle / 45); + uint32_t temp1 = (uint32_t)(matrix->scaleX * 100); + uint32_t temp2 = (uint32_t)(matrix->scaleY * 100); + indexC0 = GetIndex(temp0, temp1); + indexC1 = GetIndex(temp0, temp2); + c_step[0] = c_step[0] + offsetTable[indexC0]; + c_step[1] = c_step[1] + offsetTable[indexC1]; + } +#else + c_step[0] = c_step[0] + offsetTable[0]; + c_step[1] = c_step[1] + offsetTable[0]; +#endif /* VG_SW_BLIT_PRECISION_OPT */ + + /* Determine image mode (NORMAL, NONE , MULTIPLY or STENCIL) depending on the color. */ + switch(source->image_mode) { + case VG_LITE_NONE_IMAGE_MODE: + imageMode = 0x00000000; + break; + case VG_LITE_MULTIPLY_IMAGE_MODE: + imageMode = 0x00002000; + break; + case VG_LITE_NORMAL_IMAGE_MODE: + case VG_LITE_ZERO: + imageMode = 0x00001000; + break; + case VG_LITE_STENCIL_MODE: + imageMode = 0x00003000; + break; + case VG_LITE_RECOLOR_MODE: + imageMode = 0x00006000; + break; + } + + switch(filter) { + case VG_LITE_FILTER_POINT: + filter_mode = 0; + break; + + case VG_LITE_FILTER_LINEAR: + filter_mode = 0x10000; + break; + + case VG_LITE_FILTER_BI_LINEAR: + filter_mode = 0x20000; + break; + + case VG_LITE_FILTER_GAUSSIAN: + filter_mode = 0x30000; + break; + } + + switch(source->paintType) { + case VG_LITE_PAINT_COLOR: + paintType = 0; + break; + + case VG_LITE_PAINT_LINEAR_GRADIENT: + paintType = 1 << 24; + break; + + case VG_LITE_PAINT_RADIAL_GRADIENT: + paintType = 1 << 25; + break; + + case VG_LITE_PAINT_PATTERN: + paintType = 1 << 24 | 1 << 25; + break; + + default: + break; + } + + blend_mode = convert_blend(blend); + tiled_source = (source->tiled != VG_LITE_LINEAR) ? 0x10000000 : 0 ; +#if gcFEATURE_VG_RECTANGLE_TILED_OUT + if(target->tiled == VG_LITE_TILED) { + tile_setting = 0x40; + stripe_mode = 0x20000000; + } +#endif + +#if (gcFEATURE_VG_DEC_COMPRESS | gcFEATURE_VG_DEC_COMPRESS_2_0) + if(source->compress_mode != VG_LITE_DEC_DISABLE && target->compress_mode == VG_LITE_DEC_DISABLE) { + if(source->format != target->format) { + printf("The format of source and target buffers is inconsistent in decompressing!\n"); + return VG_LITE_INVALID_ARGUMENT; + } + } +#endif + compress_mode = (uint32_t)source->compress_mode << 25; + + /* Setup the command buffer. */ +#if gcFEATURE_VG_GLOBAL_ALPHA + VG_LITE_RETURN_ERROR(push_state(&s_context, 0x0AD1, + s_context.dst_alpha_mode | s_context.dst_alpha_value | s_context.src_alpha_mode | s_context.src_alpha_value)); +#endif + VG_LITE_RETURN_ERROR(push_state(&s_context, 0x0A00, + 0x00000001 | paintType | in_premult | imageMode | blend_mode | transparency_mode | tile_setting | s_context.enable_mask + | s_context.color_transform | s_context.matrix_enable | eco_fifo | s_context.scissor_enable | stripe_mode)); + VG_LITE_RETURN_ERROR(push_state(&s_context, 0x0A02, color)); + VG_LITE_RETURN_ERROR(push_state_ptr(&s_context, 0x0A18, (void *) &c_step[0])); + VG_LITE_RETURN_ERROR(push_state_ptr(&s_context, 0x0A19, (void *) &c_step[1])); + VG_LITE_RETURN_ERROR(push_state_ptr(&s_context, 0x0A1A, (void *) &c_step[2])); + VG_LITE_RETURN_ERROR(push_state_ptr(&s_context, 0x0A1C, (void *) &x_step[0])); + VG_LITE_RETURN_ERROR(push_state_ptr(&s_context, 0x0A1D, (void *) &x_step[1])); + VG_LITE_RETURN_ERROR(push_state_ptr(&s_context, 0x0A1E, (void *) &x_step[2])); + VG_LITE_RETURN_ERROR(push_state(&s_context, 0x0A1F, 0x00000001)); + VG_LITE_RETURN_ERROR(push_state_ptr(&s_context, 0x0A20, (void *) &y_step[0])); + VG_LITE_RETURN_ERROR(push_state_ptr(&s_context, 0x0A21, (void *) &y_step[1])); + VG_LITE_RETURN_ERROR(push_state_ptr(&s_context, 0x0A22, (void *) &y_step[2])); + + if(((source->format >= VG_LITE_YUY2) && + (source->format <= VG_LITE_AYUY2)) || + ((source->format >= VG_LITE_YUY2_TILED) && + (source->format <= VG_LITE_AYUY2_TILED))) { + yuv2rgb = convert_yuv2rgb(source->yuv.yuv2rgb); + uv_swiz = convert_uv_swizzle(source->yuv.swizzle); + } + +#if gcFEATURE_VG_IM_FASTCLEAR + if(source->fc_enable) { + uint32_t im_fc_enable = (source->fc_enable == 0) ? 0 : 0x800000; + VG_LITE_RETURN_ERROR(push_state(&s_context, 0x0A25, + convert_source_format(source->format) | filter_mode | uv_swiz | yuv2rgb | conversion | im_fc_enable | ahb_read_split | + compress_mode | src_premultiply_enable | index_endian)); + VG_LITE_RETURN_ERROR(push_state(&s_context, 0x0ACF, source->fc_buffer[0].address)); /* FC buffer address. */ + VG_LITE_RETURN_ERROR(push_state(&s_context, 0x0AD0, source->fc_buffer[0].color)); /* FC clear value. */ + } +#endif + + VG_LITE_RETURN_ERROR(push_state(&s_context, 0x0A25, + convert_source_format(source->format) | filter_mode | uv_swiz | yuv2rgb | conversion | compress_mode | + src_premultiply_enable | index_endian)); + if(source->yuv.uv_planar) { + /* Program u plane address if necessary. */ + VG_LITE_RETURN_ERROR(push_state(&s_context, 0x0A51, source->yuv.uv_planar)); + } + if(source->yuv.v_planar) { + /* Program v plane address if necessary. */ + VG_LITE_RETURN_ERROR(push_state(&s_context, 0x0A53, source->yuv.v_planar)); + } + if(source->yuv.alpha_planar != 0) { + VG_LITE_RETURN_ERROR(push_state(&s_context, 0x0A53, source->yuv.alpha_planar)); + } + VG_LITE_RETURN_ERROR(push_state(&s_context, 0x0A27, target->bg_color)); + +#if !gcFEATURE_VG_LVGL_SUPPORT + if(lvgl_sw_blend) { + VG_LITE_RETURN_ERROR(push_state(&s_context, 0x0A29, source->lvgl_buffer->address)); + } + else +#endif + VG_LITE_RETURN_ERROR(push_state(&s_context, 0x0A29, source->address)); + + VG_LITE_RETURN_ERROR(push_state(&s_context, 0x0A34, 0)); + /* 24bit format stride configured to 4bpp. */ + if(source->format >= VG_LITE_RGB888 && source->format <= VG_LITE_RGBA5658) { + stride = source->stride / 3 * 4; + VG_LITE_RETURN_ERROR(push_state(&s_context, 0x0A2B, stride | tiled_source)); + } + else { + VG_LITE_RETURN_ERROR(push_state(&s_context, 0x0A2B, source->stride | tiled_source)); + } + + VG_LITE_RETURN_ERROR(push_state(&s_context, 0x0A2D, rect_x | (rect_y << 16))); + VG_LITE_RETURN_ERROR(push_state(&s_context, 0x0A2F, rect_w | (rect_h << 16))); + +#if VG_SW_BLIT_PRECISION_OPT + if(enableSwPreOpt) { + VG_LITE_RETURN_ERROR(push_rectangle(&s_context, point_min.x + matrixOffsetX, point_min.y, point_max.x - point_min.x, + point_max.y - point_min.y)); + } + else +#endif /* VG_SW_BLIT_PRECISION_OPT */ + { + VG_LITE_RETURN_ERROR(push_rectangle(&s_context, point_min.x, point_min.y, point_max.x - point_min.x, + point_max.y - point_min.y)); + } + +#if !gcFEATURE_VG_STRIPE_MODE + VG_LITE_RETURN_ERROR(push_state(&s_context, 0x0E02, 0x10 | (0x7 << 8))); + VG_LITE_RETURN_ERROR(push_state(&s_context, 0x0F00, 0x10 | (0x7 << 8))); +#endif + + if(!s_context.flexa_mode) { + error = flush_target(); + } +#if gcFEATURE_VG_GLOBAL_ALPHA + if(blend >= VG_LITE_BLEND_NORMAL_LVGL && blend <= VG_LITE_BLEND_MULTIPLY_LVGL) { + VG_LITE_RETURN_ERROR(vg_lite_dest_global_alpha(VG_LITE_NORMAL, 0xFF)); + } +#endif + + vglitemDUMP_BUFFER("image", (size_t)source->address, source->memory, 0, (source->stride) * (source->height)); + +#if DUMP_IMAGE + dump_img(source->memory, source->width, source->height, source->format); +#endif + + return error; +#else + return VG_LITE_NOT_SUPPORT; +#endif +} + +/* Program initial states for tessellation buffer. */ +static vg_lite_error_t program_tessellation(vg_lite_context_t * context) +{ + vg_lite_error_t error = VG_LITE_SUCCESS; + uint32_t tessellation_size = 0; + +#if (CHIPID==0x355 || CHIPID==0x255) + + /* Compute tessellation buffer size. */ + uint32_t width = (context->tessbuf.tess_w_h & 0xFFFF); + /* uint32_t height = (context->tessbuf.tess_w_h >> 16); */ + + context->tessbuf.tess_stride = VG_LITE_ALIGN(width * 8, 64); + + /* Each bit in the L1 cache represents 64 bytes of tessellation data. */ + context->tessbuf.L1_size = VG_LITE_ALIGN(VG_LITE_ALIGN(context->tessbuf.tessbuf_size / 64, 64) / 8, 64); +#if (CHIPID==0x355) + /* Each bit in the L2 cache represents 32 bytes of L1 data. */ + context->tessbuf.L2_size = VG_LITE_ALIGN(VG_LITE_ALIGN(context->tessbuf.L1_size / 32, 64) / 8, 64); + tessellation_size = context->tessbuf.L2_size; +#else /* CHIPID: 0x255 */ + tessellation_size = context->tessbuf.L1_size; +#endif + + context->tessbuf.L1_phyaddr = context->tessbuf.physical_addr + context->tessbuf.tessbuf_size; + context->tessbuf.L2_phyaddr = context->tessbuf.L1_phyaddr + context->tessbuf.L1_size; + context->tessbuf.L1_logical = context->tessbuf.logical_addr + context->tessbuf.tessbuf_size; + context->tessbuf.L2_logical = context->tessbuf.L1_logical + context->tessbuf.L1_size; + + /* Program tessellation buffer: input for VG module. */ + VG_LITE_RETURN_ERROR(push_state(context, 0x0A30, context->tessbuf.physical_addr)); /* Tessellation buffer address. */ + VG_LITE_RETURN_ERROR(push_state(context, 0x0A31, + context->tessbuf.L1_phyaddr)); /* L1 address of tessellation buffer. */ + VG_LITE_RETURN_ERROR(push_state(context, 0x0A32, + context->tessbuf.L2_phyaddr)); /* L2 address of tessellation buffer. */ + VG_LITE_RETURN_ERROR(push_state(context, 0x0A33, context->tessbuf.tess_stride)); + + /* Program tessellation control: for TS module. */ + VG_LITE_RETURN_ERROR(push_state(context, 0x0A35, context->tessbuf.physical_addr)); + VG_LITE_RETURN_ERROR(push_state(context, 0x0A36, context->tessbuf.L1_phyaddr)); + VG_LITE_RETURN_ERROR(push_state(context, 0x0A37, context->tessbuf.L2_phyaddr)); + VG_LITE_RETURN_ERROR(push_state(context, 0x0A38, context->tessbuf.tess_stride)); + VG_LITE_RETURN_ERROR(push_state(context, 0x0A3A, context->tessbuf.tess_w_h)); + +#if (REVISION==0x1217 && CID==0x407) + VG_LITE_RETURN_ERROR(push_state(context, 0x0AB1, context->tessbuf.tess_stride)); + VG_LITE_RETURN_ERROR(push_state(context, 0x0AB2, context->tessbuf.tess_stride)); +#endif + + VG_LITE_RETURN_ERROR(push_state(context, 0x0A3D, tessellation_size / 64)); + +#else /* (CHIPID==0x355 || CHIPID==0x255) */ + + tessellation_size = context->tessbuf.tessbuf_size; + + /* Program tessellation control: for TS module. */ + VG_LITE_RETURN_ERROR(push_state(context, 0x0A35, context->tessbuf.physical_addr)); + VG_LITE_RETURN_ERROR(push_state(context, 0x0AC8, tessellation_size)); + VG_LITE_RETURN_ERROR(push_state(context, 0x0ACB, context->tessbuf.physical_addr + tessellation_size)); + VG_LITE_RETURN_ERROR(push_state(context, 0x0ACC, context->tessbuf.countbuf_size)); + +#endif /* (CHIPID==0x355 || CHIPID==0x255) */ + + return error; +} + +vg_lite_error_t vg_lite_init(vg_lite_uint32_t tess_width, vg_lite_uint32_t tess_height) +{ +#if DUMP_API + FUNC_DUMP(vg_lite_init)(tess_width, tess_height); +#endif + + vg_lite_error_t error; + vg_lite_kernel_initialize_t initialize; + uint8_t i; + +#if gcFEATURE_VG_TRACE_API + VGLITE_LOG("vg_lite_init %d %d\n", tess_width, tess_height); +#endif + + if(s_context.rtbuffer) { + if(s_context.tess_width >= tess_width && s_context.tess_height >= tess_height) { + /* VGLite is already initialized properly. Return */ + return VG_LITE_SUCCESS; + } + else { + vg_lite_close(); + } + } + + s_context.rtbuffer = (vg_lite_buffer_t *)vg_lite_os_malloc(sizeof(vg_lite_buffer_t)); + if(!s_context.rtbuffer) + return VG_LITE_OUT_OF_RESOURCES; + memset(s_context.rtbuffer, 0, sizeof(vg_lite_buffer_t)); + + if(tess_width <= 0) { + tess_width = 0; + tess_height = 0; + } + if(tess_height <= 0) { + tess_height = 0; + tess_width = 0; + } + tess_width = VG_LITE_ALIGN(tess_width, 16); + + /* Allocate a command buffer and a tessellation buffer. + Add extra 8 bytes in the allocated command buffer so there is space for a END command. */ + initialize.command_buffer_size = command_buffer_size + 8; + initialize.tess_width = tess_width; + initialize.tess_height = tess_height; + initialize.command_buffer_pool = (vg_lite_vidmem_pool_t)s_context.command_buffer_pool; + initialize.tess_buffer_pool = (vg_lite_vidmem_pool_t)s_context.tess_buffer_pool; + initialize.context = &s_context.context; + VG_LITE_RETURN_ERROR(vg_lite_kernel(VG_LITE_INITIALIZE, &initialize)); + + /* Verify driver ChipId/ChipRevision/Cid match hardware chip information */ + VG_LITE_RETURN_ERROR(check_hardware_chip_info()); + + /* Save draw context. */ + s_context.capabilities = initialize.capabilities; + s_context.command_buffer[0] = (uint8_t *)initialize.command_buffer[0]; + s_context.command_buffer[1] = (uint8_t *)initialize.command_buffer[1]; + s_context.command_buffer_size = command_buffer_size; + s_context.command_offset[0] = 0; + s_context.command_offset[1] = 0; + + if((tess_width > 0) && (tess_height > 0)) { + /* Set and Program Tessellation Buffer states. */ + s_context.tessbuf.physical_addr = initialize.physical_addr; + s_context.tessbuf.logical_addr = initialize.logical_addr; + s_context.tessbuf.tess_w_h = initialize.tess_w_h; + s_context.tessbuf.tessbuf_size = initialize.tessbuf_size; + s_context.tessbuf.countbuf_size = initialize.countbuf_size; + + VG_LITE_RETURN_ERROR(program_tessellation(&s_context)); + /* Init register gcregVGPEColorKey. */ + for(i = 0; i < 8; i++) { + VG_LITE_RETURN_ERROR(push_state(&s_context, 0x0A90 + i, 0)); + } + } + s_context.custom_tessbuf = 0; + s_context.custom_cmdbuf = 0; + s_context.tess_width = tess_width; + s_context.tess_height = tess_height; + + /* Init scissor rect. */ + s_context.scissor[0] = + s_context.scissor[1] = + s_context.scissor[2] = + s_context.scissor[3] = 0; + + s_context.path_counter = 0; + + s_context.mirror_orient = VG_LITE_ORIENTATION_TOP_BOTTOM; + +#if DUMP_INIT_COMMAND + physical_address = (size_t)CMDBUF_BUFFER(s_context); + uint32_t * ptr = (uint32_t *) s_context.context.command_buffer_logical[CMDBUF_INDEX(s_context)]; + ptr += 1; + for(int i = 0; i < 12; i++) { + init_buffer[i] = *ptr; + ptr += 2; + } + is_init = 0; +#endif + +#if DUMP_CAPTURE || DUMP_LAST_CAPTURE + _SetDumpFileInfo(); +#endif + + return VG_LITE_SUCCESS; +} + +vg_lite_error_t vg_lite_close(void) +{ +#if DUMP_API + FUNC_DUMP(vg_lite_close)(); +#endif + + vg_lite_error_t error; + vg_lite_kernel_terminate_t terminate; + +#if gcFEATURE_VG_TRACE_API + VGLITE_LOG("vg_lite_close\n"); +#endif + + if(s_context.scissor_layer) { + vg_lite_free(s_context.scissor_layer); + vg_lite_os_free(s_context.scissor_layer); + } + + if(s_context.custom_cmdbuf) { + vg_lite_kernel_unmap_memory_t unmap = {0}; + unmap.bytes = s_context.command_buffer_size * 2; + unmap.logical = s_context.command_buffer[0]; + VG_LITE_RETURN_ERROR(vg_lite_kernel(VG_LITE_UNMAP_MEMORY, &unmap)); + } + + if(s_context.custom_tessbuf) { + vg_lite_kernel_unmap_memory_t unmap = {0}; + unmap.bytes = s_context.tessbuf.tessbuf_size + s_context.tessbuf.countbuf_size; + unmap.logical = s_context.tessbuf.logical_addr; + VG_LITE_RETURN_ERROR(vg_lite_kernel(VG_LITE_UNMAP_MEMORY, &unmap)); + } + + /* Termnate the draw context. */ + terminate.context = &s_context.context; + VG_LITE_RETURN_ERROR(vg_lite_kernel(VG_LITE_TERMINATE, &terminate)); + + if(s_context.rtbuffer) + vg_lite_os_free(s_context.rtbuffer); + + submit_flag = 0; + + /* Reset the draw context. */ + memset(&s_context, 0, sizeof(s_context)); + +#if DUMP_CAPTURE + _SetDumpFileInfo(); +#endif + return VG_LITE_SUCCESS; +} + +vg_lite_error_t vg_lite_set_command_buffer_size(vg_lite_uint32_t size) +{ +#if DUMP_API + FUNC_DUMP(vg_lite_set_command_buffer_size)(size); +#endif + +#if gcFEATURE_VG_TRACE_API + VGLITE_LOG("vg_lite_set_command_buffer_size %d\n", size); +#endif + + if(command_buffer_size == 0) + return VG_LITE_INVALID_ARGUMENT; + + command_buffer_size = size; + + return VG_LITE_SUCCESS; +} + +vg_lite_error_t vg_lite_set_command_buffer(vg_lite_uint32_t physical, vg_lite_uint32_t size) +{ + vg_lite_error_t error = VG_LITE_SUCCESS; + vg_lite_kernel_map_memory_t map = { 0 }; + +#if gcFEATURE_VG_TRACE_API + VGLITE_LOG("vg_lite_set_command_buffer 0x%08X %d\n", physical, size); +#endif + + if((physical == 0) || (size == 0) || (physical % 64) || (size % 128)) + return VG_LITE_INVALID_ARGUMENT; + + map.bytes = size; + map.physical = physical; + + if(s_context.command_buffer[0]) { + + if(submit_flag) + VG_LITE_RETURN_ERROR(stall(&s_context, 0, (uint32_t)~0)); + + if(!s_context.custom_cmdbuf) { + vg_lite_kernel_free_t free; + free.memory_handle = s_context.context.command_buffer[0]; + VG_LITE_RETURN_ERROR(vg_lite_kernel(VG_LITE_FREE, &free)); + s_context.context.command_buffer[0] = 0; + + free.memory_handle = s_context.context.command_buffer[1]; + VG_LITE_RETURN_ERROR(vg_lite_kernel(VG_LITE_FREE, &free)); + s_context.context.command_buffer[1] = 0; + } + else { + vg_lite_kernel_unmap_memory_t unmap = { 0 }; + + unmap.bytes = s_context.command_buffer_size + 8; + unmap.logical = s_context.command_buffer[0]; + VG_LITE_RETURN_ERROR(vg_lite_kernel(VG_LITE_UNMAP_MEMORY, &unmap)); + unmap.bytes = s_context.command_buffer_size + 8; + unmap.logical = s_context.command_buffer[1]; + VG_LITE_RETURN_ERROR(vg_lite_kernel(VG_LITE_UNMAP_MEMORY, &unmap)); + } + } + + VG_LITE_RETURN_ERROR(vg_lite_kernel(VG_LITE_MAP_MEMORY, &map)); + + s_context.context.command_buffer_logical[0] = map.logical; + s_context.context.command_buffer_physical[0] = map.physical; + + s_context.context.command_buffer_logical[1] = (void *)((uint8_t *)map.logical + map.bytes / 2); + s_context.context.command_buffer_physical[1] = map.physical + map.bytes / 2; + + s_context.command_buffer[0] = s_context.context.command_buffer_logical[0]; + s_context.command_buffer[1] = s_context.context.command_buffer_logical[1]; + s_context.command_offset[0] = 0; + s_context.command_offset[1] = 0; + s_context.command_buffer_current = 0; + /* Reserve 8 bytes in mapped command buffer so there is space for a END command. */ + s_context.command_buffer_size = (map.bytes / 2) - 8; + s_context.custom_cmdbuf = 1; + + return error; +} + +vg_lite_error_t vg_lite_set_tess_buffer(vg_lite_uint32_t physical, vg_lite_uint32_t size) +{ + vg_lite_error_t error = VG_LITE_SUCCESS; + vg_lite_kernel_map_memory_t map = { 0 }; + +#if gcFEATURE_VG_TRACE_API + VGLITE_LOG("vg_lite_set_tess_buffer 0x%08X %d\n", physical, size); +#endif + + if((physical == 0) || (size == 0) || (physical % 64) || (size % 64) || (size < MIN_TS_SIZE)) + return VG_LITE_INVALID_ARGUMENT; + + map.bytes = size; + map.physical = physical; + + if(s_context.tessbuf.logical_addr) { + if(submit_flag) + VG_LITE_RETURN_ERROR(stall(&s_context, 0, (uint32_t)~0)); + if(!s_context.custom_tessbuf) { + vg_lite_kernel_free_t free; + free.memory_handle = s_context.context.tess_buffer; + VG_LITE_RETURN_ERROR(vg_lite_kernel(VG_LITE_FREE, &free)); + s_context.context.tess_buffer = 0; + } + else { + vg_lite_kernel_unmap_memory_t unmap = { 0 }; + + unmap.bytes = s_context.tessbuf.tessbuf_size + s_context.tessbuf.countbuf_size; + unmap.logical = s_context.tessbuf.logical_addr; + VG_LITE_RETURN_ERROR(vg_lite_kernel(VG_LITE_UNMAP_MEMORY, &unmap)); + } + } + + VG_LITE_RETURN_ERROR(vg_lite_kernel(VG_LITE_MAP_MEMORY, &map)); + + s_context.tessbuf.logical_addr = map.logical; + s_context.tessbuf.physical_addr = map.physical; + s_context.tessbuf.countbuf_size = size * 3 / 128; + s_context.tessbuf.countbuf_size = VG_LITE_ALIGN(s_context.tessbuf.countbuf_size, 64); + s_context.tessbuf.tessbuf_size = map.bytes - s_context.tessbuf.countbuf_size; + + VG_LITE_RETURN_ERROR(push_state(&s_context, 0x0A35, s_context.tessbuf.physical_addr)); + VG_LITE_RETURN_ERROR(push_state(&s_context, 0x0AC8, s_context.tessbuf.tessbuf_size)); + VG_LITE_RETURN_ERROR(push_state(&s_context, 0x0ACB, s_context.tessbuf.physical_addr + s_context.tessbuf.tessbuf_size)); + VG_LITE_RETURN_ERROR(push_state(&s_context, 0x0ACC, s_context.tessbuf.countbuf_size)); + + s_context.custom_tessbuf = 1; + + return error; +} + +vg_lite_error_t vg_lite_get_mem_size(vg_lite_uint32_t * size) +{ + vg_lite_error_t error = VG_LITE_SUCCESS; + vg_lite_kernel_mem_t mem; + +#if gcFEATURE_VG_TRACE_API + VGLITE_LOG("vg_lite_get_mem_size %p\n", size); +#endif + + mem.pool = VG_LITE_POOL_RESERVED_MEMORY1; + VG_LITE_RETURN_ERROR(vg_lite_kernel(VG_LITE_QUERY_MEM, &mem)); + *size = mem.bytes; + + return error; +} + +/* Handle tiled & yuv allocation. Currently including NV12, ANV12, YV12, YV16, NV16, YV24, NV24. */ +static vg_lite_error_t _allocate_tiled_yuv_planar(vg_lite_buffer_t * buffer) +{ + vg_lite_error_t error = VG_LITE_SUCCESS; + uint32_t yplane_size = 0; + vg_lite_kernel_allocate_t allocate, uv_allocate, v_allocate; + + if(((buffer->format < VG_LITE_NV12) || (buffer->format > VG_LITE_ANV12_TILED) + || (buffer->format == VG_LITE_AYUY2) || (buffer->format == VG_LITE_YUY2_TILED)) + && ((buffer->format != VG_LITE_NV24) && (buffer->format != VG_LITE_NV24_TILED))) { + return error; + } + + /* For NV12, there are 2 planes (Y, UV); + For ANV12, there are 3 planes (Y, UV, Alpha). + Each plane must be aligned by (4, 8). + Then Y plane must be aligned by (8, 8). + For YVxx, there are 3 planes (Y, U, V). + YV12 is similar to NV12, both YUV420 format. + YV16 and NV16 are YUV422 format. + YV24 is YUV444 format. + */ + buffer->width = VG_LITE_ALIGN(buffer->width, 8); + buffer->height = VG_LITE_ALIGN(buffer->height, 8); + buffer->stride = VG_LITE_ALIGN(buffer->width, 64); + + switch(buffer->format) { + case VG_LITE_NV12: + case VG_LITE_ANV12: + case VG_LITE_NV12_TILED: + case VG_LITE_ANV12_TILED: + buffer->yuv.uv_stride = buffer->stride; + buffer->yuv.alpha_stride = buffer->stride; + buffer->yuv.uv_height = buffer->height / 2; + break; + + case VG_LITE_NV16: + buffer->yuv.uv_stride = buffer->stride; + buffer->yuv.uv_height = buffer->height; + break; + + case VG_LITE_NV24: + case VG_LITE_NV24_TILED: + buffer->yuv.uv_stride = buffer->stride * 2; + buffer->yuv.uv_height = buffer->height; + break; + + case VG_LITE_YV12: + buffer->yuv.uv_stride = + buffer->yuv.v_stride = buffer->stride / 2; + buffer->yuv.uv_height = + buffer->yuv.v_height = buffer->height / 2; + break; + + case VG_LITE_YV16: + buffer->yuv.uv_stride = + buffer->yuv.v_stride = buffer->stride; + buffer->yuv.uv_height = + buffer->yuv.v_height = buffer->height / 2; + break; + + case VG_LITE_YV24: + buffer->yuv.uv_stride = + buffer->yuv.v_stride = buffer->stride; + buffer->yuv.uv_height = + buffer->yuv.v_height = buffer->height; + break; + + default: + return error; + } + + yplane_size = buffer->stride * buffer->height; + + /* Allocate buffer memory: Y. */ + allocate.bytes = yplane_size; + allocate.contiguous = 1; + VG_LITE_RETURN_ERROR(vg_lite_kernel(VG_LITE_ALLOCATE, &allocate)); + + /* Save the allocation. */ + buffer->handle = allocate.memory_handle; + buffer->memory = allocate.memory; + buffer->address = allocate.memory_gpu; + + if((buffer->format == VG_LITE_NV12) || (buffer->format == VG_LITE_ANV12) + || (buffer->format == VG_LITE_NV16) || (buffer->format == VG_LITE_NV24) + || (buffer->format == VG_LITE_NV12_TILED) || (buffer->format == VG_LITE_ANV12_TILED)) { + /* Allocate buffer memory: UV. */ + uv_allocate.bytes = buffer->yuv.uv_stride * buffer->yuv.uv_height; + VG_LITE_RETURN_ERROR(vg_lite_kernel(VG_LITE_ALLOCATE, &uv_allocate)); + buffer->yuv.uv_handle = uv_allocate.memory_handle; + buffer->yuv.uv_memory = uv_allocate.memory; + buffer->yuv.uv_planar = uv_allocate.memory_gpu; + + if((buffer->format == VG_LITE_ANV12) || (buffer->format == VG_LITE_ANV12_TILED)) { + uv_allocate.bytes = yplane_size; + VG_LITE_RETURN_ERROR(vg_lite_kernel(VG_LITE_ALLOCATE, &uv_allocate)); + buffer->yuv.alpha_planar = uv_allocate.memory_gpu; + } + } + else { + /* Allocate buffer memory: U, V. */ + uv_allocate.bytes = buffer->yuv.uv_stride * buffer->yuv.uv_height; + VG_LITE_RETURN_ERROR(vg_lite_kernel(VG_LITE_ALLOCATE, &uv_allocate)); + buffer->yuv.uv_handle = uv_allocate.memory_handle; + buffer->yuv.uv_memory = uv_allocate.memory; + buffer->yuv.uv_planar = uv_allocate.memory_gpu; + + v_allocate.bytes = buffer->yuv.v_stride * buffer->yuv.v_height; + VG_LITE_RETURN_ERROR(vg_lite_kernel(VG_LITE_ALLOCATE, &v_allocate)); + buffer->yuv.v_handle = v_allocate.memory_handle; + buffer->yuv.v_memory = v_allocate.memory; + buffer->yuv.v_planar = v_allocate.memory_gpu; + } + + return error; +} + +vg_lite_error_t vg_lite_allocate(vg_lite_buffer_t * buffer) +{ +#if DUMP_API + FUNC_DUMP(vg_lite_allocate)(buffer); +#endif + + vg_lite_error_t error = VG_LITE_SUCCESS; + vg_lite_kernel_allocate_t allocate; + +#if gcFEATURE_VG_TRACE_API + VGLITE_LOG("vg_lite_allocate %p (w: %d, h: %d, fmt: %d)\n", buffer, buffer->width, buffer->height, buffer->format); +#endif + + if(buffer->format == VG_LITE_RGBA8888_ETC2_EAC && +#if (CHIPID == 0x555) + (buffer->width % 16 || buffer->height % 4) +#else + (buffer->width % 4 || buffer->height % 4) +#endif + ) { + return VG_LITE_INVALID_ARGUMENT; + } + + /* Set buffer->premultiplied properly according to buffer->format */ + if(buffer->format < VG_LITE_RGBA8888) { + /* For all OpenVG VG_* formats */ +#if gcFEATURE_VG_HW_PREMULTIPLY + switch(buffer->format) { + case OPENVG_sRGBA_8888_PRE: + case OPENVG_lRGBA_8888_PRE: + case OPENVG_sARGB_8888_PRE: + case OPENVG_lARGB_8888_PRE: + case OPENVG_sBGRA_8888_PRE: + case OPENVG_lBGRA_8888_PRE: + case OPENVG_sABGR_8888_PRE: + case OPENVG_lABGR_8888_PRE: + case OPENVG_sRGBX_8888_PRE: + case OPENVG_lRGBX_8888_PRE: + case OPENVG_sRGB_565_PRE: + case OPENVG_lRGB_565_PRE: + case OPENVG_sRGBA_5551_PRE: + case OPENVG_lRGBA_5551_PRE: + case OPENVG_sRGBA_4444_PRE: + case OPENVG_lRGBA_4444_PRE: + buffer->premultiplied = 1; + break; + default: + buffer->premultiplied = 0; + break; + }; +#else + /* Cannot support OpenVG VG_* format if HW does not support premultiply */ + return VG_LITE_INVALID_ARGUMENT; +#endif + } + else { + /* All VG_LITE_* formats are not premultiplied */ + buffer->premultiplied = 0; + } + + /* Reset planar. */ + buffer->yuv.uv_planar = + buffer->yuv.v_planar = + buffer->yuv.alpha_planar = 0; + + /* Align height in case format is tiled. */ + if((buffer->format >= VG_LITE_YUY2 && buffer->format <= VG_LITE_NV16) || buffer->format == VG_LITE_NV24) { + buffer->height = VG_LITE_ALIGN(buffer->height, 4); + buffer->yuv.swizzle = VG_LITE_SWIZZLE_UV; + } + + if((buffer->format >= VG_LITE_YUY2_TILED && buffer->format <= VG_LITE_AYUY2_TILED) || + buffer->format == VG_LITE_NV24_TILED) { + buffer->height = VG_LITE_ALIGN(buffer->height, 4); + buffer->tiled = VG_LITE_TILED; + buffer->yuv.swizzle = VG_LITE_SWIZZLE_UV; + } + + if((buffer->format >= VG_LITE_NV12 && buffer->format <= VG_LITE_ANV12_TILED + && buffer->format != VG_LITE_AYUY2 && buffer->format != VG_LITE_YUY2_TILED) + || (buffer->format >= VG_LITE_NV24 && buffer->format <= VG_LITE_NV24_TILED)) { + _allocate_tiled_yuv_planar(buffer); + } + else { + /* Driver need compute the stride always with RT500 project. */ + + vg_lite_float_t ratio = 1.0f; + uint32_t mul, div, align; + get_format_bytes(buffer->format, &mul, &div, &align); + buffer->stride = buffer->width * mul / div; + +#if gcFEATURE_VG_16PIXELS_ALIGNED + int tmp_align = 16 * mul / div; + if((mul / div) % 2 != 0) { + if(buffer->stride % tmp_align != 0) { + buffer->stride = (buffer->stride + tmp_align) / tmp_align * tmp_align; + } + } + else { + buffer->stride = VG_LITE_ALIGN(buffer->stride, tmp_align); + } +#endif + /* Allocate the buffer. */ + if(buffer->compress_mode) + ratio = _calc_decnano_compress_ratio(buffer->format, buffer->compress_mode); + allocate.bytes = (uint32_t)(buffer->stride * buffer->height * ratio); + +#if gcFEATURE_VG_IM_FASTCLEAR + allocate.bytes = VG_LITE_ALIGN(allocate.bytes, 64); +#endif + allocate.contiguous = 1; + allocate.pool = (vg_lite_vidmem_pool_t)s_context.render_buffer_pool; + VG_LITE_RETURN_ERROR(vg_lite_kernel(VG_LITE_ALLOCATE, &allocate)); + + /* Save the buffer allocation. */ + buffer->handle = allocate.memory_handle; + buffer->memory = allocate.memory; + buffer->address = allocate.memory_gpu; + buffer->pool = (vg_lite_memory_pool_t)allocate.pool; + + if((buffer->format == VG_LITE_AYUY2) || (buffer->format == VG_LITE_AYUY2_TILED) || + ((buffer->format >= VG_LITE_ABGR8565_PLANAR) + && (buffer->format <= VG_LITE_RGBA5658_PLANAR))) { + allocate.bytes = buffer->stride * buffer->height; + VG_LITE_RETURN_ERROR(vg_lite_kernel(VG_LITE_ALLOCATE, &allocate)); + buffer->yuv.alpha_planar = allocate.memory_gpu; + } + } + +#if gcFEATURE_VG_TRACE_API + VGLITE_LOG("=>buffer: width=%d, height=%d, stride=%d, bytes=%d, format=%d\n", + buffer->width, buffer->height, buffer->stride, allocate.bytes, buffer->format); +#endif + + return VG_LITE_SUCCESS; +} + +vg_lite_error_t vg_lite_free(vg_lite_buffer_t * buffer) +{ +#if DUMP_API + FUNC_DUMP(vg_lite_free)(buffer); +#endif + + vg_lite_error_t error; + vg_lite_kernel_free_t free, uv_free, v_free; + +#if gcFEATURE_VG_TRACE_API + VGLITE_LOG("vg_lite_free %p\n", buffer); +#endif + + if(buffer == NULL) + return VG_LITE_INVALID_ARGUMENT; + if(!(memcmp(s_context.rtbuffer, buffer, sizeof(vg_lite_buffer_t)))) { + if(VG_LITE_SUCCESS == submit(&s_context)) { + VG_LITE_RETURN_ERROR(stall(&s_context, 0, ~0)); + } + +#if !DUMP_COMMAND_CAPTURE + vglitemDUMP("@[swap 0x%08X %dx%d +%u]", + s_context.rtbuffer->address, + s_context.rtbuffer->width, s_context.rtbuffer->height, + s_context.rtbuffer->stride); + vglitemDUMP_BUFFER( + "framebuffer", + (size_t)s_context.rtbuffer->address, s_context.rtbuffer->memory, + 0, + s_context.rtbuffer->stride * (s_context.rtbuffer->height)); +#endif + + memset(s_context.rtbuffer, 0, sizeof(vg_lite_buffer_t)); + } + +#if !gcFEATURE_VG_LVGL_SUPPORT + if(buffer->lvgl_buffer != NULL) { + free.memory_handle = buffer->lvgl_buffer->handle; + VG_LITE_RETURN_ERROR(vg_lite_kernel(VG_LITE_FREE, &free)); + vg_lite_os_free(buffer->lvgl_buffer); + buffer->lvgl_buffer = NULL; + } +#endif + + if(buffer->yuv.uv_planar) { + /* Free UV(U) planar buffer. */ + vglitemDUMP_BUFFER( + "uv_plane", + (size_t)buffer->yuv.uv_planar, buffer->yuv.uv_memory, + 0, + buffer->yuv.uv_stride * buffer->yuv.uv_height); + + uv_free.memory_handle = buffer->yuv.uv_handle; + VG_LITE_RETURN_ERROR(vg_lite_kernel(VG_LITE_FREE, &uv_free)); + + /* Mark the buffer as freed. */ + buffer->yuv.uv_handle = NULL; + buffer->yuv.uv_memory = NULL; + } + + if(buffer->yuv.v_planar) { + /* Free V planar buffer. */ + vglitemDUMP_BUFFER( + "v_plane", + (size_t)buffer->yuv.v_planar, buffer->yuv.v_memory, + 0, + buffer->yuv.v_stride * buffer->yuv.v_height); + /* Free V planar buffer. */ + v_free.memory_handle = buffer->yuv.v_handle; + VG_LITE_RETURN_ERROR(vg_lite_kernel(VG_LITE_FREE, &v_free)); + + /* Mark the buffer as freed. */ + buffer->yuv.v_handle = NULL; + buffer->yuv.v_memory = NULL; + } + +#if gcFEATURE_VG_IM_FASTCLEAR + if(buffer->fc_buffer[0].handle != 0) { +#if VG_TARGET_FC_DUMP + vglitemDUMP_BUFFER( + "fcbuffer", + (uint64_t)buffer->fc_buffer[0].address, buffer->fc_buffer[0].memory, + 0, + buffer->fc_buffer[0].stride * (buffer->fc_buffer[0].height)); +#endif + _free_fc_buffer(&buffer->fc_buffer[0]); + } +#endif + + /* Make sure we have a valid memory handle. */ + if(buffer->handle == NULL) { + return VG_LITE_INVALID_ARGUMENT; + } + + /* Free the buffer. */ + free.memory_handle = buffer->handle; + VG_LITE_RETURN_ERROR(vg_lite_kernel(VG_LITE_FREE, &free)); + + /* Mark the buffer as freed. */ + buffer->handle = NULL; + buffer->memory = NULL; + + return VG_LITE_SUCCESS; +} + +vg_lite_error_t vg_lite_map(vg_lite_buffer_t * buffer, vg_lite_map_flag_t flag, int32_t fd) +{ +#if DUMP_API + FUNC_DUMP(vg_lite_map)(buffer, flag, fd); +#endif + + vg_lite_error_t error; + vg_lite_kernel_map_t map; + +#if gcFEATURE_VG_TRACE_API + VGLITE_LOG("vg_lite_map %p\n", buffer); +#endif + + /* We either need a logical or physical address. */ + if(buffer->memory == NULL && buffer->address == 0) { + return VG_LITE_INVALID_ARGUMENT; + } + + /* Compute the stride. Align if necessary. */ + if(buffer->stride == 0) { + uint32_t mul, div, align; + get_format_bytes(buffer->format, &mul, &div, &align); + buffer->stride = buffer->width * mul / div; + } + + /* Map the buffer. */ + map.bytes = buffer->stride * buffer->height; + map.logical = buffer->memory; + map.physical = buffer->address; + + if(flag == VG_LITE_MAP_USER_MEMORY) { + map.flags = VG_LITE_HAL_MAP_USER_MEMORY; + } + else if(flag == VG_LITE_MAP_DMABUF) { + map.flags = VG_LITE_HAL_MAP_DMABUF; + } + else { + return VG_LITE_INVALID_ARGUMENT; + } + + map.dma_buf_fd = fd; + VG_LITE_RETURN_ERROR(vg_lite_kernel(VG_LITE_MAP, &map)); + + /* Save the buffer allocation. */ + buffer->handle = map.memory_handle; + buffer->address = map.memory_gpu; + + return VG_LITE_SUCCESS; +} + +vg_lite_error_t vg_lite_unmap(vg_lite_buffer_t * buffer) +{ +#if DUMP_API + FUNC_DUMP(vg_lite_unmap)(buffer); +#endif + + vg_lite_error_t error; + vg_lite_kernel_unmap_t unmap; + +#if gcFEATURE_VG_TRACE_API + VGLITE_LOG("vg_lite_unmap %p\n", buffer); +#endif + + /* Make sure we have a valid memory handle. */ + if(buffer->handle == NULL) { + return VG_LITE_INVALID_ARGUMENT; + } + + /* Unmap the buffer. */ + unmap.memory_handle = buffer->handle; + VG_LITE_RETURN_ERROR(vg_lite_kernel(VG_LITE_UNMAP, &unmap)); + + /* Mark the buffer as freed. */ + buffer->handle = NULL; + + return VG_LITE_SUCCESS; +} + +vg_lite_error_t vg_lite_flush_mapped_buffer(vg_lite_buffer_t * buffer) +{ +#if DUMP_API + FUNC_DUMP(vg_lite_flush_mapped_buffer)(buffer); +#endif + + vg_lite_error_t error; + vg_lite_kernel_cache_t cache; + +#if gcFEATURE_VG_TRACE_API + VGLITE_LOG("vg_lite_flush_mapped_buffer %p\n", buffer); +#endif + + /* Make sure we have a valid memory handle. */ + if(buffer->handle == NULL) { + return VG_LITE_INVALID_ARGUMENT; + } + + cache.memory_handle = buffer->handle; + cache.cache_op = VG_LITE_CACHE_INVALIDATE; + VG_LITE_RETURN_ERROR(vg_lite_kernel(VG_LITE_CACHE, &cache)); + + return VG_LITE_SUCCESS; +} + +vg_lite_error_t vg_lite_get_register(vg_lite_uint32_t address, vg_lite_uint32_t * result) +{ + vg_lite_error_t error; + vg_lite_kernel_info_t data; + +#if gcFEATURE_VG_TRACE_API + VGLITE_LOG("vg_lite_get_register 0x%08X %p\n", address, result); +#endif + + /* Get input register address. */ + data.addr = address; + + /* Get register info. */ + VG_LITE_RETURN_ERROR(vg_lite_kernel(VG_LITE_CHECK, &data)); + + /* Return register info. */ + *result = data.reg; + + return VG_LITE_SUCCESS; +} + +vg_lite_error_t vg_lite_get_info(vg_lite_info_t * info) +{ +#if gcFEATURE_VG_TRACE_API + VGLITE_LOG("vg_lite_get_info %p\n", info); +#endif + + if(info != NULL) { + info->api_version = VGLITE_API_VERSION_3_0; + info->header_version = VGLITE_HEADER_VERSION; + info->release_version = VGLITE_RELEASE_VERSION; + info->reserved = 0; + } + + return VG_LITE_SUCCESS; +} + +vg_lite_uint32_t vg_lite_get_product_info(vg_lite_char * name, vg_lite_uint32_t * chip_id, vg_lite_uint32_t * chip_rev) +{ + const char * product_name; + uint32_t name_len; + vg_lite_uint32_t rev = 0, id = 0; + +#if gcFEATURE_VG_TRACE_API + VGLITE_LOG("vg_lite_get_product_info %p %p %p\n", name, chip_id, chip_rev); +#endif + + vg_lite_get_register(0x24, &rev); + vg_lite_get_register(0x20, &id); + + if(id == 0x265 || id == 0x555) + product_name = "GCNanoUltraV"; + else if(id == 0x255) + product_name = "GCNanoLiteV"; + else if(id == 0x355) + product_name = "GC355"; + else + product_name = "Unknown"; + + name_len = strlen(product_name) + 1; + if(name != NULL) { + memcpy(name, product_name, name_len); + } + + if(chip_id != NULL) { + *chip_id = id; + } + + if(chip_rev != NULL) { + *chip_rev = rev; + } + + return name_len; +} + +vg_lite_uint32_t vg_lite_query_feature(vg_lite_feature_t feature) +{ + uint32_t result; + +#if gcFEATURE_VG_TRACE_API + VGLITE_LOG("vg_lite_query_feature %d\n", feature); +#endif + + if(feature < gcFEATURE_COUNT) + result = s_ftable.ftable[feature]; + else + result = 0; + + return result; +} + +vg_lite_error_t vg_lite_finish() +{ +#if DUMP_API + FUNC_DUMP(vg_lite_finish)(); +#endif + + vg_lite_error_t error; + +#if gcFEATURE_VG_TRACE_API + VGLITE_LOG("vg_lite_finish\n"); +#endif + + /* Return if there is nothing to submit. */ + if(CMDBUF_OFFSET(s_context) == 0) { + if(submit_flag) + VG_LITE_RETURN_ERROR(stall(&s_context, 0, (uint32_t)~0)); + return VG_LITE_SUCCESS; + } + + /* Flush is moved from each draw to here. */ + VG_LITE_RETURN_ERROR(push_state(&s_context, 0x0A00, 0x00000001)); + + VG_LITE_RETURN_ERROR(flush_target()); + VG_LITE_RETURN_ERROR(submit(&s_context)); +#if gcFEATURE_VG_POWER_MANAGEMENT + s_context.context.end_of_frame = 1; +#endif + +#if defined(_WINDLL) + VG_LITE_RETURN_ERROR(stall(&s_context, 0, (uint32_t)~0)); +#elif defined(__linux__) + VG_LITE_RETURN_ERROR(stall(&s_context, 20000, (uint32_t)~0)); +#else + VG_LITE_RETURN_ERROR(stall(&s_context, 5000, (uint32_t)~0)); +#endif + +#if gcFEATURE_VG_IM_FASTCLEAR +#if VG_TARGET_FC_DUMP + fc_buf_dump(s_context.rtbuffer, &s_context.fcBuffer); +#endif +#endif + +#if gcFEATURE_VG_SINGLE_COMMAND_BUFFER + CMDBUF_OFFSET(s_context) = 0; +#else + CMDBUF_SWAP(s_context); + /* Reset command buffer. */ + CMDBUF_OFFSET(s_context) = 0; +#endif + + return VG_LITE_SUCCESS; +} + +vg_lite_error_t vg_lite_flush(void) +{ +#if DUMP_API + FUNC_DUMP(vg_lite_flush)(); +#endif + +#if !gcFEATURE_VG_SINGLE_COMMAND_BUFFER + vg_lite_error_t error; + +#if gcFEATURE_VG_TRACE_API + VGLITE_LOG("vg_lite_flush\n"); +#endif + + /* Return if there is nothing to submit. */ + if(CMDBUF_OFFSET(s_context) == 0) + return VG_LITE_SUCCESS; + + /* Wait if GPU has not completed previous CMD buffer */ + if(submit_flag) { + VG_LITE_RETURN_ERROR(stall(&s_context, 0, (uint32_t)~0)); + } + + /* Submit the current command buffer. */ + VG_LITE_RETURN_ERROR(push_state(&s_context, 0x0A00, 0x00000001)); + VG_LITE_RETURN_ERROR(flush_target()); + VG_LITE_RETURN_ERROR(submit(&s_context)); +#if gcFEATURE_VG_POWER_MANAGEMENT + s_context.context.end_of_frame = 1; +#endif + + CMDBUF_SWAP(s_context); + + /* Reset command buffer. */ + CMDBUF_OFFSET(s_context) = 0; + + return VG_LITE_SUCCESS; + +#else + printf("vg_lite_flush is not support when enable single command buffer!\n"); + return VG_LITE_NOT_SUPPORT; +#endif + +} + +vg_lite_error_t vg_lite_init_grad(vg_lite_linear_gradient_t * grad) +{ + vg_lite_error_t error = VG_LITE_SUCCESS; + +#if DUMP_API + FUNC_DUMP(vg_lite_init_grad)(grad); +#endif + +#if gcFEATURE_VG_TRACE_API + VGLITE_LOG("vg_lite_init_grad %p\n", grad); +#endif + + grad->count = 0; + + /* Set the member values according to driver defaults. */ + grad->image.width = VLC_GRADIENT_BUFFER_WIDTH; + grad->image.height = 1; + grad->image.stride = 0; + grad->image.format = VG_LITE_BGRA8888; + + /* Allocate the image for gradient. */ + VG_LITE_RETURN_ERROR(vg_lite_allocate(&grad->image)); + + return error; +} + +vg_lite_error_t vg_lite_set_linear_grad(vg_lite_ext_linear_gradient_t * grad, + vg_lite_uint32_t count, + vg_lite_color_ramp_t * color_ramp, + vg_lite_linear_gradient_parameter_t linear_gradient, + vg_lite_gradient_spreadmode_t spread_mode, + vg_lite_uint8_t pre_multiplied) +{ + static vg_lite_color_ramp_t default_ramp[] = { + { + 0.0f, + 0.0f, 0.0f, 0.0f, 1.0f + }, + { + 1.0f, + 1.0f, 1.0f, 1.0f, 1.0f + } + }; + + uint32_t i, trg_count; + vg_lite_float_t prev_stop; + vg_lite_color_ramp_t * src_ramp; + vg_lite_color_ramp_t * src_ramp_last; + vg_lite_color_ramp_t * trg_ramp; + +#if gcFEATURE_VG_TRACE_API + VGLITE_LOG("vg_lite_set_linear_grad %p %d %p (%f %f %f %f) %d %d\n", grad, count, color_ramp, + linear_gradient.X0, linear_gradient.X1, linear_gradient.Y0, linear_gradient.Y1, spread_mode, pre_multiplied); +#endif + + /* Reset the count. */ + trg_count = 0; + + if((linear_gradient.X0 == linear_gradient.X1) && (linear_gradient.Y0 == linear_gradient.Y1)) + return VG_LITE_INVALID_ARGUMENT; + + grad->linear_grad = linear_gradient; + grad->pre_multiplied = pre_multiplied; + grad->spread_mode = spread_mode; + + if(!count || count > VLC_MAX_COLOR_RAMP_STOPS || color_ramp == NULL) + goto Empty_sequence_handler; + + for(i = 0; i < count; i++) + grad->color_ramp[i] = color_ramp[i]; + grad->ramp_length = count; + + /* Determine the last source ramp. */ + src_ramp_last + = grad->color_ramp + + grad->ramp_length; + + /* Set the initial previous stop. */ + prev_stop = -1; + + /* Reset the count. */ + trg_count = 0; + + /* Walk through the source ramp. */ + for( + src_ramp = grad->color_ramp, trg_ramp = grad->converted_ramp; + (src_ramp < src_ramp_last) && (trg_count < VLC_MAX_COLOR_RAMP_STOPS + 2); + src_ramp += 1 + ) { + /* Must be in increasing order. */ + if(src_ramp->stop < prev_stop) { + /* Ignore the entire sequence. */ + trg_count = 0; + break; + } + + /* Update the previous stop value. */ + prev_stop = src_ramp->stop; + + /* Must be within [0..1] range. */ + if((src_ramp->stop < 0.0f) || (src_ramp->stop > 1.0f)) { + /* Ignore. */ + continue; + } + + /* Clamp color. */ + ClampColor(COLOR_FROM_RAMP(src_ramp), COLOR_FROM_RAMP(trg_ramp), 0); + + /* First stop greater then zero? */ + if((trg_count == 0) && (src_ramp->stop > 0.0f)) { + /* Force the first stop to 0.0f. */ + trg_ramp->stop = 0.0f; + + /* Replicate the entry. */ + trg_ramp[1] = *trg_ramp; + trg_ramp[1].stop = src_ramp->stop; + + /* Advance. */ + trg_ramp += 2; + trg_count += 2; + } + else { + /* Set the stop value. */ + trg_ramp->stop = src_ramp->stop; + + /* Advance. */ + trg_ramp += 1; + trg_count += 1; + } + } + + /* Empty sequence? */ + if(trg_count == 0) { + memcpy(grad->converted_ramp, default_ramp, sizeof(default_ramp)); + grad->converted_length = sizeof(default_ramp) / 5; + } + else { + /* The last stop must be at 1.0. */ + if(trg_ramp[-1].stop != 1.0f) { + /* Replicate the last entry. */ + *trg_ramp = trg_ramp[-1]; + + /* Force the last stop to 1.0f. */ + trg_ramp->stop = 1.0f; + + /* Update the final entry count. */ + trg_count += 1; + } + + /* Set new length. */ + grad->converted_length = trg_count; + } + return VG_LITE_SUCCESS; + +Empty_sequence_handler: + memcpy(grad->converted_ramp, default_ramp, sizeof(default_ramp)); + grad->converted_length = sizeof(default_ramp) / 5; + + return VG_LITE_SUCCESS; +} + +vg_lite_error_t vg_lite_update_linear_grad(vg_lite_ext_linear_gradient_t * grad) +{ +#if DUMP_API + FUNC_DUMP(vg_lite_update_linear_grad)(grad); +#endif + + uint32_t ramp_length; + vg_lite_color_ramp_t * color_ramp; + uint32_t stop; + uint32_t i, width; + uint8_t * bits; + vg_lite_float_t x0, y0, x1, y1, length, dx, dy; + vg_lite_error_t error = VG_LITE_SUCCESS; + +#if gcFEATURE_VG_TRACE_API + VGLITE_LOG("vg_lite_update_linear_grad %p\n", grad); +#endif + + /* Get shortcuts to the color ramp. */ + ramp_length = grad->converted_length; + color_ramp = grad->converted_ramp; + + x0 = grad->matrix.m[0][0] * grad->linear_grad.X0 + grad->matrix.m[0][1] * grad->linear_grad.Y0 + grad->matrix.m[0][2]; + y0 = grad->matrix.m[1][0] * grad->linear_grad.X0 + grad->matrix.m[1][1] * grad->linear_grad.Y0 + grad->matrix.m[1][2]; + x1 = grad->matrix.m[0][0] * grad->linear_grad.X1 + grad->matrix.m[0][1] * grad->linear_grad.Y1 + grad->matrix.m[0][2]; + y1 = grad->matrix.m[1][0] * grad->linear_grad.X1 + grad->matrix.m[1][1] * grad->linear_grad.Y1 + grad->matrix.m[1][2]; + dx = x1 - x0; + dy = y1 - y0; + length = (vg_lite_float_t)sqrt(dx * dx + dy * dy); + width = ramp_length * 128; + + if(length <= 0) + return VG_LITE_INVALID_ARGUMENT; + /* Find the common denominator of the color ramp stops. */ + + /* Compute transform matrix from ramp surface to grad.*/ + vg_lite_identity(&(grad->matrix)); + vg_lite_translate(x0, y0, &(grad->matrix)); + vg_lite_rotate( + ((dy >= 0) ? acosf(dx / length) : (2 * PI - acosf(dx / length))) * 180.f / PI, + &(grad->matrix) + ); + vg_lite_scale(length / width, 1.f, &(grad->matrix)); + + /* Set grad to ramp surface. */ + grad->linear_grad.X0 = 0.f; + grad->linear_grad.Y0 = 0.f; + grad->linear_grad.X1 = (float)width; + grad->linear_grad.Y1 = 0.f; + + /* Allocate the color ramp surface. */ + memset(&grad->image, 0, sizeof(grad->image)); + grad->image.width = width; + grad->image.height = 1; + grad->image.stride = 0; + grad->image.image_mode = VG_LITE_NONE_IMAGE_MODE; + grad->image.format = VG_LITE_ABGR8888; + + /* Allocate the image for gradient. */ + VG_LITE_RETURN_ERROR(vg_lite_allocate(&grad->image)); + memset(grad->image.memory, 0, grad->image.stride * grad->image.height); + /* Set pointer to color array. */ + bits = (uint8_t *)grad->image.memory; + + /* Start filling the color array. */ + stop = 0; + for(i = 0; i < width; ++i) { + vg_lite_float_t gradient; + vg_lite_float_t color[4]; + vg_lite_float_t color1[4]; + vg_lite_float_t color2[4]; + vg_lite_float_t weight; + + if(i == 241) + i = 241; + /* Compute gradient for current color array entry. */ + gradient = (vg_lite_float_t) i / (vg_lite_float_t)(width - 1); + + /* Find the entry in the color ramp that matches or exceeds this + ** gradient. */ + while(gradient > color_ramp[stop].stop) { + ++stop; + } + + if(gradient == color_ramp[stop].stop) { + /* Perfect match weight 1.0. */ + weight = 1.0f; + + /* Use color ramp color. */ + color1[3] = color_ramp[stop].alpha; + color1[2] = color_ramp[stop].blue; + color1[1] = color_ramp[stop].green; + color1[0] = color_ramp[stop].red; + + color2[3] = + color2[2] = + color2[1] = + color2[0] = 0.0f; + } + else { + if(stop == 0) { + return VG_LITE_INVALID_ARGUMENT; + } + /* Compute weight. */ + weight = (color_ramp[stop].stop - gradient) + / (color_ramp[stop].stop - color_ramp[stop - 1].stop); + + /* Grab color ramp color of previous stop. */ + color1[3] = color_ramp[stop - 1].alpha; + color1[2] = color_ramp[stop - 1].blue; + color1[1] = color_ramp[stop - 1].green; + color1[0] = color_ramp[stop - 1].red; + + /* Grab color ramp color of current stop. */ + color2[3] = color_ramp[stop].alpha; + color2[2] = color_ramp[stop].blue; + color2[1] = color_ramp[stop].green; + color2[0] = color_ramp[stop].red; + } + + if(grad->pre_multiplied) { + /* Pre-multiply the first color. */ + color1[2] *= color1[3]; + color1[1] *= color1[3]; + color1[0] *= color1[3]; + + /* Pre-multiply the second color. */ + color2[2] *= color2[3]; + color2[1] *= color2[3]; + color2[0] *= color2[3]; + } + + /* Filter the colors per channel. */ + color[3] = LERP(color1[3], color2[3], weight); + color[2] = LERP(color1[2], color2[2], weight); + color[1] = LERP(color1[1], color2[1], weight); + color[0] = LERP(color1[0], color2[0], weight); + + /* Pack the final color. */ + *bits++ = PackColorComponent(color[3]); + *bits++ = PackColorComponent(color[2]); + *bits++ = PackColorComponent(color[1]); + *bits++ = PackColorComponent(color[0]); + } + + return VG_LITE_SUCCESS; +} + +vg_lite_error_t vg_lite_set_radial_grad(vg_lite_radial_gradient_t * grad, + vg_lite_uint32_t count, + vg_lite_color_ramp_t * color_ramp, + vg_lite_radial_gradient_parameter_t radial_grad, + vg_lite_gradient_spreadmode_t spread_mode, + vg_lite_uint8_t pre_multiplied) +{ + static vg_lite_color_ramp_t defaultRamp[] = { + { + 0.0f, + 0.0f, 0.0f, 0.0f, 1.0f + }, + { + 1.0f, + 1.0f, 1.0f, 1.0f, 1.0f + } + }; + + uint32_t i, trgCount; + vg_lite_float_t prevStop; + vg_lite_color_ramp_t * srcRamp; + vg_lite_color_ramp_t * srcRampLast; + vg_lite_color_ramp_t * trgRamp; + +#if gcFEATURE_VG_TRACE_API + VGLITE_LOG("vg_lite_set_radial_grad %p %d %p (%f %f %f %f %f) %d %d\n", grad, count, color_ramp, + radial_grad.cx, radial_grad.cy, radial_grad.fx, radial_grad.fy, radial_grad.r, spread_mode, pre_multiplied); +#endif + + /* Reset the count. */ + trgCount = 0; + + if(radial_grad.r <= 0) + return VG_LITE_INVALID_ARGUMENT; + + grad->radial_grad = radial_grad; + grad->pre_multiplied = pre_multiplied; + grad->spread_mode = spread_mode; + + if(!count || count > VLC_MAX_COLOR_RAMP_STOPS || color_ramp == NULL) + goto Empty_sequence_handler; + + for(i = 0; i < count; i++) + grad->color_ramp[i] = color_ramp[i]; + grad->ramp_length = count; + + /* Determine the last source ramp. */ + srcRampLast + = grad->color_ramp + + grad->ramp_length; + + /* Set the initial previous stop. */ + prevStop = -1; + + /* Reset the count. */ + trgCount = 0; + + /* Walk through the source ramp. */ + for( + srcRamp = grad->color_ramp, trgRamp = grad->converted_ramp; + (srcRamp < srcRampLast) && (trgCount < VLC_MAX_COLOR_RAMP_STOPS + 2); + srcRamp += 1 + ) { + /* Must be in increasing order. */ + if(srcRamp->stop < prevStop) { + /* Ignore the entire sequence. */ + trgCount = 0; + break; + } + + /* Update the previous stop value. */ + prevStop = srcRamp->stop; + + /* Must be within [0..1] range. */ + if((srcRamp->stop < 0.0f) || (srcRamp->stop > 1.0f)) { + /* Ignore. */ + continue; + } + + /* Clamp color. */ + ClampColor(COLOR_FROM_RAMP(srcRamp), COLOR_FROM_RAMP(trgRamp), 0); + + /* First stop greater then zero? */ + if((trgCount == 0) && (srcRamp->stop > 0.0f)) { + /* Force the first stop to 0.0f. */ + trgRamp->stop = 0.0f; + + /* Replicate the entry. */ + trgRamp[1] = *trgRamp; + trgRamp[1].stop = srcRamp->stop; + + /* Advance. */ + trgRamp += 2; + trgCount += 2; + } + else { + /* Set the stop value. */ + trgRamp->stop = srcRamp->stop; + + /* Advance. */ + trgRamp += 1; + trgCount += 1; + } + } + + /* Empty sequence? */ + if(trgCount == 0) { + memcpy(grad->converted_ramp, defaultRamp, sizeof(defaultRamp)); + grad->converted_length = sizeof(defaultRamp) / 5; + } + else { + /* The last stop must be at 1.0. */ + if(trgRamp[-1].stop != 1.0f) { + /* Replicate the last entry. */ + *trgRamp = trgRamp[-1]; + + /* Force the last stop to 1.0f. */ + trgRamp->stop = 1.0f; + + /* Update the final entry count. */ + trgCount += 1; + } + + /* Set new length. */ + grad->converted_length = trgCount; + } + return VG_LITE_SUCCESS; + +Empty_sequence_handler: + memcpy(grad->converted_ramp, defaultRamp, sizeof(defaultRamp)); + grad->converted_length = sizeof(defaultRamp) / 5; + + return VG_LITE_SUCCESS; +} + +vg_lite_error_t vg_lite_update_radial_grad(vg_lite_radial_gradient_t * grad) +{ +#if DUMP_API + FUNC_DUMP(vg_lite_update_radial_grad)(grad); +#endif + + uint32_t ramp_length; + vg_lite_color_ramp_t * colorRamp; + uint32_t common, stop; + uint32_t i, width; + uint8_t * bits; + vg_lite_error_t error = VG_LITE_SUCCESS; + uint32_t align, mul, div; + +#if gcFEATURE_VG_TRACE_API + VGLITE_LOG("vg_lite_update_radial_grad %p\n", grad); +#endif + + /* Get shortcuts to the color ramp. */ + ramp_length = grad->converted_length; + colorRamp = grad->converted_ramp; + + if(grad->radial_grad.r <= 0) + return VG_LITE_INVALID_ARGUMENT; + + if(grad->radial_grad.r < 1) { + common = 1; + for(i = 0; i < ramp_length; ++i) { + if(colorRamp[i].stop != 0.0f) { + vg_lite_float_t mul2 = common * colorRamp[i].stop; + vg_lite_float_t frac = mul2 - (vg_lite_float_t)floor(mul2); + if(frac > 0.00013f) { /* Suppose error for zero is 0.00013 */ + common = MAX(common, (uint32_t)(1.0f / frac + 0.5f)); + } + } + } + + /* Compute the width of the required color array. */ + width = common + 1; + width = (width + 15) & (~0xf); + } + else { + width = ramp_length * 128; + } + + /* Allocate the color ramp surface. */ + memset(&grad->image, 0, sizeof(grad->image)); + grad->image.width = width; + grad->image.height = 1; + grad->image.stride = 0; + grad->image.image_mode = VG_LITE_NONE_IMAGE_MODE; + grad->image.format = VG_LITE_ABGR8888; + + /* Allocate the image for gradient. */ + VG_LITE_RETURN_ERROR(vg_lite_allocate(&grad->image)); + + get_format_bytes(VG_LITE_ABGR8888, &mul, &div, &align); + width = grad->image.stride * div / mul; + + /* Set pointer to color array. */ + bits = (uint8_t *)grad->image.memory; + + /* Start filling the color array. */ + stop = 0; + for(i = 0; i < width; ++i) { + vg_lite_float_t gradient; + vg_lite_float_t color[4]; + vg_lite_float_t color1[4]; + vg_lite_float_t color2[4]; + vg_lite_float_t weight; + + /* Compute gradient for current color array entry. */ + gradient = (vg_lite_float_t) i / (vg_lite_float_t)(width - 1); + + /* Find the entry in the color ramp that matches or exceeds this + ** gradient. */ + while(gradient > colorRamp[stop].stop) { + ++stop; + } + + if(gradient == colorRamp[stop].stop) { + /* Perfect match weight 1.0. */ + weight = 1.0f; + + /* Use color ramp color. */ + color1[3] = colorRamp[stop].alpha; + color1[2] = colorRamp[stop].blue; + color1[1] = colorRamp[stop].green; + color1[0] = colorRamp[stop].red; + + color2[3] = + color2[2] = + color2[1] = + color2[0] = 0.0f; + } + else { + /* Compute weight. */ + weight = (colorRamp[stop].stop - gradient) + / (colorRamp[stop].stop - colorRamp[stop - 1].stop); + + /* Grab color ramp color of previous stop. */ + color1[3] = colorRamp[stop - 1].alpha; + color1[2] = colorRamp[stop - 1].blue; + color1[1] = colorRamp[stop - 1].green; + color1[0] = colorRamp[stop - 1].red; + + /* Grab color ramp color of current stop. */ + color2[3] = colorRamp[stop].alpha; + color2[2] = colorRamp[stop].blue; + color2[1] = colorRamp[stop].green; + color2[0] = colorRamp[stop].red; + } + + if(grad->pre_multiplied) { + /* Pre-multiply the first color. */ + color1[2] *= color1[3]; + color1[1] *= color1[3]; + color1[0] *= color1[3]; + + /* Pre-multiply the second color. */ + color2[2] *= color2[3]; + color2[1] *= color2[3]; + color2[0] *= color2[3]; + } + + /* Filter the colors per channel. */ + color[3] = LERP(color1[3], color2[3], weight); + color[2] = LERP(color1[2], color2[2], weight); + color[1] = LERP(color1[1], color2[1], weight); + color[0] = LERP(color1[0], color2[0], weight); + + /* Pack the final color. */ + *bits++ = PackColorComponent(color[3]); + *bits++ = PackColorComponent(color[2]); + *bits++ = PackColorComponent(color[1]); + *bits++ = PackColorComponent(color[0]); + } + + return VG_LITE_SUCCESS; +} + +vg_lite_error_t vg_lite_set_grad(vg_lite_linear_gradient_t * grad, + vg_lite_uint32_t count, + vg_lite_uint32_t * colors, + vg_lite_uint32_t * stops) +{ + uint32_t i; + +#if gcFEATURE_VG_TRACE_API + VGLITE_LOG("vg_lite_set_grad %p %d %p %p\n", grad, count, colors, stops); +#endif + + grad->count = 0; /* Opaque B&W gradient */ + if(!count || count > VLC_MAX_GRADIENT_STOPS || colors == NULL || stops == NULL) + return VG_LITE_SUCCESS; + + /* Check stops validity */ + for(i = 0; i < count; i++) + if(stops[i] < VLC_GRADIENT_BUFFER_WIDTH) { + if(!grad->count || stops[i] > grad->stops[grad->count - 1]) { + grad->stops[grad->count] = stops[i]; + grad->colors[grad->count] = colors[i]; + grad->count++; + } + else if(stops[i] == grad->stops[grad->count - 1]) { + /* Equal stops : use the color corresponding to the last stop + in the sequence */ + grad->colors[grad->count - 1] = colors[i]; + } + } + + return VG_LITE_SUCCESS; +} + +vg_lite_error_t vg_lite_update_grad(vg_lite_linear_gradient_t * grad) +{ +#if DUMP_API + FUNC_DUMP(vg_lite_update_grad)(grad); +#endif + + vg_lite_error_t error = VG_LITE_SUCCESS; + int32_t r0, g0, b0, a0; + int32_t r1, g1, b1, a1; + int32_t lr, lg, lb, la; + uint32_t i; + int32_t j; + int32_t ds, dr, dg, db, da; + uint32_t * buffer = (uint32_t *)grad->image.memory; + +#if gcFEATURE_VG_TRACE_API + VGLITE_LOG("vg_lite_update_grad %p\n", grad); +#endif + + if(grad->count == 0) { + /* If no valid stops have been specified (e.g., due to an empty input + * array, out-of-range, or out-of-order stops), a stop at 0 with color + * 0xFF000000 (opaque black) and a stop at 255 with color 0xFFFFFFFF + * (opaque white) are implicitly defined. */ + grad->stops[0] = 0; + grad->colors[0] = 0xFF000000; /* Opaque black */ + grad->stops[1] = 255; + grad->colors[1] = 0xFFFFFFFF; /* Opaque white */ + grad->count = 2; + } + else if(grad->count && grad->stops[0] != 0) { + /* If at least one valid stop has been specified, but none has been + * defined with an offset of 0, an implicit stop is added with an + * offset of 0 and the same color as the first user-defined stop. */ + for(i = 0; i < grad->stops[0]; i++) + buffer[i] = grad->colors[0]; + } + a0 = A(grad->colors[0]); + r0 = R(grad->colors[0]); + g0 = G(grad->colors[0]); + b0 = B(grad->colors[0]); + + /* Calculate the colors for each pixel of the image. */ + for(i = 0; i < grad->count - 1; i++) { + buffer[grad->stops[i]] = grad->colors[i]; + ds = grad->stops[i + 1] - grad->stops[i]; + a1 = A(grad->colors[i + 1]); + r1 = R(grad->colors[i + 1]); + g1 = G(grad->colors[i + 1]); + b1 = B(grad->colors[i + 1]); + + da = a1 - a0; + dr = r1 - r0; + dg = g1 - g0; + db = b1 - b0; + + for(j = 1; j < ds; j++) { + la = a0 + da * j / ds; + lr = r0 + dr * j / ds; + lg = g0 + dg * j / ds; + lb = b0 + db * j / ds; + + buffer[grad->stops[i] + j] = ARGB(la, lr, lg, lb); + } + + a0 = a1; + r0 = r1; + g0 = g1; + b0 = b1; + } + + /* If at least one valid stop has been specified, but none has been defined + * with an offset of 255, an implicit stop is added with an offset of 255 + * and the same color as the last user-defined stop. */ + for(i = grad->stops[grad->count - 1]; i < VLC_GRADIENT_BUFFER_WIDTH; i++) + buffer[i] = grad->colors[grad->count - 1]; + + return error; +} + +vg_lite_error_t vg_lite_clear_linear_grad(vg_lite_ext_linear_gradient_t * grad) +{ +#if DUMP_API + FUNC_DUMP(vg_lite_clear_linear_grad)(grad); +#endif + + vg_lite_error_t error = VG_LITE_SUCCESS; + +#if gcFEATURE_VG_TRACE_API + VGLITE_LOG("vg_lite_clear_linear_grad %p\n", grad); +#endif + + grad->count = 0; + /* Release the image resource. */ + if(grad->image.handle != NULL) { + error = vg_lite_free(&grad->image); + } + + return error; +} + +vg_lite_error_t vg_lite_clear_grad(vg_lite_linear_gradient_t * grad) +{ +#if DUMP_API + FUNC_DUMP(vg_lite_clear_grad)(grad); +#endif + + vg_lite_error_t error = VG_LITE_SUCCESS; + +#if gcFEATURE_VG_TRACE_API + VGLITE_LOG("vg_lite_clear_grad %p\n", grad); +#endif + + grad->count = 0; + /* Release the image resource. */ + if(grad->image.handle != NULL) { + error = vg_lite_free(&grad->image); + } + + return error; +} + +vg_lite_error_t vg_lite_clear_radial_grad(vg_lite_radial_gradient_t * grad) +{ +#if DUMP_API + FUNC_DUMP(vg_lite_clear_radial_grad)(grad); +#endif + + vg_lite_error_t error = VG_LITE_SUCCESS; + +#if gcFEATURE_VG_TRACE_API + VGLITE_LOG("vg_lite_clear_radial_grad %p\n", grad); +#endif + + grad->count = 0; + /* Release the image resource. */ + if(grad->image.handle != NULL) { + error = vg_lite_free(&grad->image); + } + + return error; +} + +vg_lite_matrix_t * vg_lite_get_linear_grad_matrix(vg_lite_ext_linear_gradient_t * grad) +{ +#if gcFEATURE_VG_TRACE_API + VGLITE_LOG("vg_lite_get_linear_grad_matrix %p\n", grad); +#endif + + return &grad->matrix; +} + +vg_lite_matrix_t * vg_lite_get_grad_matrix(vg_lite_linear_gradient_t * grad) +{ +#if gcFEATURE_VG_TRACE_API + VGLITE_LOG("vg_lite_get_grad_matrix %p\n", grad); +#endif + + return &grad->matrix; +} + +vg_lite_matrix_t * vg_lite_get_radial_grad_matrix(vg_lite_radial_gradient_t * grad) +{ +#if gcFEATURE_VG_TRACE_API + VGLITE_LOG("vg_lite_get_radial_grad_matrix %p\n", grad); +#endif + + return &grad->matrix; +} + +vg_lite_error_t vg_lite_dump_command_buffer() +{ +#if DUMP_API + FUNC_DUMP(vg_lite_dump_command_buffer)(); +#endif + + vg_lite_error_t error = VG_LITE_SUCCESS; + vg_lite_kernel_submit_t submit; + vg_lite_context_t * context = &s_context; + + /* Submit the command buffer. */ + submit.context = &context->context; + submit.commands = CMDBUF_BUFFER(*context); + submit.command_size = CMDBUF_OFFSET(*context); + submit.command_id = CMDBUF_INDEX(*context); + + vglitemDUMP_BUFFER("command", (size_t)CMDBUF_BUFFER(*context), + submit.context->command_buffer_logical[CMDBUF_INDEX(*context)], 0, submit.command_size); + +#if !DUMP_COMMAND_CAPTURE + vglitemDUMP("@[commit]"); +#endif + + return error; +} + +vg_lite_error_t vg_lite_get_parameter(vg_lite_param_type_t type, + vg_lite_int32_t count, + vg_lite_pointer params) +{ + vg_lite_error_t error = VG_LITE_SUCCESS; + vg_lite_uint32_t gpu_idle = 0; + vg_lite_float_t * fparams; + vg_lite_uint32_t * uiparams; + + vg_lite_kernel_hardware_running_time_t time; + +#if gcFEATURE_VG_TRACE_API + VGLITE_LOG("vg_lite_get_parameter %d %p\n", count, params); +#endif + + switch(type) { + case VG_LITE_GPU_IDLE_STATE: + if(count != 1) { + return VG_LITE_INVALID_ARGUMENT; + } + vg_lite_get_register(0x04, &gpu_idle); + uiparams = (vg_lite_uint32_t *)params; + *uiparams = ((gpu_idle & 0x0B05) == 0x0B05); + break; + + case VG_LITE_SCISSOR_RECT: + if((count % 4) != 0) { + return VG_LITE_INVALID_ARGUMENT; + } + fparams = (vg_lite_float_t *)params; + for(vg_lite_int32_t i = 0; i < count; i++) { + *(fparams + i) = (vg_lite_float_t)s_context.scissor[i]; + } + break; + + case VG_LITE_HARDWARE_RUNNING_TIME: + vg_lite_kernel(VG_LITE_RECORD_RUNNING_TIME, &time); + *((float *)params) = (float)time.run_time / (float)time.hertz; + break; + + default: + error = VG_LITE_INVALID_ARGUMENT; + break; + } + + return error; +} + +vg_lite_error_t vg_lite_copy_image(vg_lite_buffer_t * target, vg_lite_buffer_t * source, + vg_lite_int32_t sx, vg_lite_int32_t sy, + vg_lite_int32_t dx, vg_lite_int32_t dy, + vg_lite_uint32_t width, vg_lite_uint32_t height) +{ +#if gcFEATURE_VG_IM_INPUT + vg_lite_error_t error; + vg_lite_point_t point_min, point_max, temp; + vg_lite_matrix_t inverse_matrix; + vg_lite_matrix_t n; + vg_lite_float_t x_step[3]; + vg_lite_float_t y_step[3]; + vg_lite_float_t c_step[3]; + uint32_t imageMode = 0; + uint32_t in_premult = 0; + int32_t stride; + uint32_t transparency_mode = 0; + uint32_t filter_mode = 0; + uint32_t conversion = 0; + uint32_t tiled_source; + int32_t left, top, right, bottom; + uint32_t rect_x = 0, rect_y = 0, rect_w = 0, rect_h = 0; + vg_lite_rectangle_t rectangle = { dx, dy, width, height }; + uint32_t yuv2rgb = 0; + uint32_t uv_swiz = 0; + uint32_t compress_mode; + uint32_t src_premultiply_enable = 0; + uint32_t index_endian = 0; + uint32_t eco_fifo = 0; + uint32_t tile_setting = 0; + uint32_t stripe_mode = 0; + uint32_t premul_flag = 0; + uint32_t prediv_flag = 0; + vg_lite_color_t color = 0; + +#if gcFEATURE_VG_TRACE_API + VGLITE_LOG("vg_lite_copy_image %p %p %d %d %d %d %d %d\n", target, source, sx, sy, dx, dy, width, height); +#endif + +#if gcFEATURE_VG_ERROR_CHECK +#if !gcFEATURE_VG_INDEX_ENDIAN + if((source->format >= VG_LITE_INDEX_1) && (source->format <= VG_LITE_INDEX_4) && source->index_endian) { + return VG_LITE_NOT_SUPPORT; + } +#endif +#if !gcFEATURE_VG_RECTANGLE_TILED_OUT + if(target->tiled != VG_LITE_LINEAR) { + return VG_LITE_NOT_SUPPORT; + } +#endif +#if !gcFEATURE_VG_RGBA8_ETC2_EAC + if(source->format == VG_LITE_RGBA8888_ETC2_EAC) { + return VG_LITE_NOT_SUPPORT; + } +#else + if((source->format == VG_LITE_RGBA8888_ETC2_EAC) && (source->width % 16 || source->height % 4)) { + return VG_LITE_INVALID_ARGUMENT; + } +#endif +#if !gcFEATURE_VG_YUY2_INPUT + if(source->format == VG_LITE_YUYV || source->format == VG_LITE_YUY2) { + return VG_LITE_NOT_SUPPORT; + } +#endif +#if !gcFEATURE_VG_YUV_INPUT + if((source->format >= VG_LITE_NV12 && source->format <= VG_LITE_NV16) || source->format == VG_LITE_NV24) { + return VG_LITE_NOT_SUPPORT; + } +#elif !gcFEATURE_VG_NV24_INPUT + if(source->format == VG_LITE_NV24) { + return VG_LITE_NOT_SUPPORT; + } +#endif +#if !gcFEATURE_VG_AYUV_INPUT + if(source->format == VG_LITE_ANV12 || source->format == VG_LITE_AYUY2) { + return VG_LITE_NOT_SUPPORT; + } +#endif +#if !gcFEATURE_VG_YUV_TILED_INPUT + if((source->format >= VG_LITE_YUY2_TILED && source->format <= VG_LITE_AYUY2_TILED) || + (source->format == VG_LITE_NV24_TILED)) { + return VG_LITE_NOT_SUPPORT; + } +#endif +#if !gcFEATURE_VG_24BIT + if((target->format >= VG_LITE_RGB888 && target->format <= VG_LITE_RGBA5658) || + (source->format >= VG_LITE_RGB888 && source->format <= VG_LITE_RGBA5658)) { + return VG_LITE_NOT_SUPPORT; + } +#endif +#if !gcFEATURE_VG_24BIT_PLANAR + if(source->format >= VG_LITE_ABGR8565_PLANAR && source->format <= VG_LITE_RGBA5658_PLANAR) { + return VG_LITE_NOT_SUPPORT; + } +#endif +#if !gcFEATURE_VG_IM_DEC_INPUT + if(source->compress_mode != VG_LITE_DEC_DISABLE) { + return VG_LITE_NOT_SUPPORT; + } +#endif +#if !gcFEATURE_VG_STENCIL + if(source->image_mode == VG_LITE_STENCIL_MODE) { + return VG_LITE_NOT_SUPPORT; + } +#endif +#if (CHIPID == 0x355) + if(target->format == VG_LITE_L8 || target->format == VG_LITE_YUYV || + target->format == VG_LITE_BGRA2222 || target->format == VG_LITE_RGBA2222 || + target->format == VG_LITE_ABGR2222 || target->format == VG_LITE_ARGB2222) { + printf("Target format: 0x%x is not supported.\n", target->format); + return VG_LITE_NOT_SUPPORT; + } + if(source->format == VG_LITE_L8 || source->format == VG_LITE_YUYV || + source->format == VG_LITE_BGRA2222 || source->format == VG_LITE_RGBA2222 || + source->format == VG_LITE_ABGR2222 || source->format == VG_LITE_ARGB2222) { + printf("Source format: 0x%x is not supported.\n", source->format); + return VG_LITE_NOT_SUPPORT; + } +#endif + + VG_LITE_RETURN_ERROR(srcbuf_align_check(source)); + VG_LITE_RETURN_ERROR(check_compress(source->format, source->compress_mode, source->tiled, source->width, + source->height)); +#endif /* gcFEATURE_VG_ERROR_CHECK */ + +#if gcFEATURE_VG_INDEX_ENDIAN + if((source->format >= VG_LITE_INDEX_1) && (source->format <= VG_LITE_INDEX_4) && source->index_endian) { + index_endian = 1 << 14; + } +#endif +#if !gcFEATURE_VG_STRIPE_MODE + /* Enable fifo feature to share buffer between vg and ts to improve the rotation performance */ + eco_fifo = 1 << 7; +#endif + + transparency_mode = (source->transparency_mode == VG_LITE_IMAGE_TRANSPARENT ? 0x8000 : 0); + + vg_lite_matrix_t * matrix = &n; + vg_lite_identity(matrix); + vg_lite_translate((vg_lite_float_t)sx, (vg_lite_float_t)sy, matrix); + + /* Check whether L8 is supported or not. */ + if((target->format == VG_LITE_L8) && ((source->format != VG_LITE_L8) && (source->format != VG_LITE_A8))) { + conversion = 0x80000000; + } + +#if gcFEATURE_VG_16PIXELS_ALIGNED + /* Check if source specify bytes are aligned */ + error = _check_source_aligned(source->format, source->stride); + if(error != VG_LITE_SUCCESS) { + return error; + } +#endif + + /* Set source region. */ + vg_lite_rectangle_t * rect = &rectangle; + rect_x = (rect->x < 0) ? 0 : rect->x; + rect_y = (rect->y < 0) ? 0 : rect->y; + rect_w = rect->width; + rect_h = rect->height; + if((rect_x > (uint32_t)source->width) || (rect_y > (uint32_t)source->height) || + (rect_w == 0) || (rect_h == 0)) { + /*No intersection*/ + return VG_LITE_INVALID_ARGUMENT; + } + if(rect_x + rect_w > (uint32_t)source->width) { + rect_w = source->width - rect_x; + } + if(rect_y + rect_h > (uint32_t)source->height) { + rect_h = source->height - rect_y; + } + + /* Transform image (0,0) to screen. */ + if(!transform(&temp, 0.0f, 0.0f, matrix)) + return VG_LITE_INVALID_ARGUMENT; + + /* Set initial point. */ + point_min = temp; + point_max = temp; + + /* Transform image (0,height) to screen. */ + if(!transform(&temp, 0.0f, (vg_lite_float_t)rect_h, matrix)) + return VG_LITE_INVALID_ARGUMENT; + + /* Determine min/max. */ + if(temp.x < point_min.x) point_min.x = temp.x; + if(temp.y < point_min.y) point_min.y = temp.y; + if(temp.x > point_max.x) point_max.x = temp.x; + if(temp.y > point_max.y) point_max.y = temp.y; + + /* Transform image (width,height) to screen. */ + if(!transform(&temp, (vg_lite_float_t)rect_w, (vg_lite_float_t)rect_h, matrix)) + return VG_LITE_INVALID_ARGUMENT; + + /* Determine min/max. */ + if(temp.x < point_min.x) point_min.x = temp.x; + if(temp.y < point_min.y) point_min.y = temp.y; + if(temp.x > point_max.x) point_max.x = temp.x; + if(temp.y > point_max.y) point_max.y = temp.y; + + /* Transform image (width,0) to screen. */ + if(!transform(&temp, (vg_lite_float_t)rect_w, 0.0f, matrix)) + return VG_LITE_INVALID_ARGUMENT; + + /* Determine min/max. */ + if(temp.x < point_min.x) point_min.x = temp.x; + if(temp.y < point_min.y) point_min.y = temp.y; + if(temp.x > point_max.x) point_max.x = temp.x; + if(temp.y > point_max.y) point_max.y = temp.y; + + /* Clip to target. */ + if(s_context.scissor_set && !target->scissor_buffer) { + left = s_context.scissor[0]; + top = s_context.scissor[1]; + right = s_context.scissor[2]; + bottom = s_context.scissor[3]; + } + else { + left = 0; + top = 0; + right = target->width; + bottom = target->height; + } + + point_min.x = MAX(point_min.x, left); + point_min.y = MAX(point_min.y, top); + point_max.x = MIN(point_max.x, right); + point_max.y = MIN(point_max.y, bottom); + + /* No need to draw. */ + if((point_max.x <= point_min.x) || (point_max.y <= point_min.y)) { + return VG_LITE_SUCCESS; + } + +#if gcFEATURE_VG_GAMMA + get_st_gamma_src_dest(source, target); +#endif + + /*blend input into context*/ + in_premult = 0x00000000; + + /* Adjust premultiply setting according to openvg condition */ + src_premultiply_enable = 0x01000100; + if(s_context.color_transform == 0 && s_context.gamma_dst == s_context.gamma_src && s_context.matrix_enable == 0 && + s_context.dst_alpha_mode == 0 && s_context.src_alpha_mode == 0 && + (source->image_mode == VG_LITE_NORMAL_IMAGE_MODE || source->image_mode == 0)) { + prediv_flag = 0; + } + else { + prediv_flag = 1; + } + + if((source->premultiplied == 0 && target->premultiplied == 0 && premul_flag == 0) || + (source->premultiplied == 1 && target->premultiplied == 0 && prediv_flag == 0)) { + src_premultiply_enable = 0x01000100; + in_premult = 0x10000000; + } + /* when src and dst all pre format, im pre_out set to 0 to perform data truncation to prevent data overflow */ + else if(source->premultiplied == 1 && target->premultiplied == 1 && prediv_flag == 0) { + src_premultiply_enable = 0x01000100; + in_premult = 0x10000000; + } + else if((source->premultiplied == 0 && target->premultiplied == 1) || + (source->premultiplied == 0 && target->premultiplied == 0 && premul_flag == 1)) { + src_premultiply_enable = 0x01000100; + in_premult = 0x00000000; + } + else if((source->premultiplied == 1 && target->premultiplied == 1 && prediv_flag == 1) || + (source->premultiplied == 1 && target->premultiplied == 0 && prediv_flag == 1)) { + src_premultiply_enable = 0x00000100; + in_premult = 0x00000000; + } + if(source->premultiplied == target->premultiplied && premul_flag == 0) { + target->apply_premult = 1; + } + else { + target->apply_premult = 0; + } + + error = set_render_target(target); + if(error != VG_LITE_SUCCESS) { + return error; + } + + /* Compute inverse matrix. */ + if(!inverse(&inverse_matrix, matrix)) + return VG_LITE_INVALID_ARGUMENT; + +#if gcFEATURE_VG_MATH_PRECISION_FIX + + /* Compute interpolation steps. */ + x_step[0] = inverse_matrix.m[0][0]; + x_step[1] = inverse_matrix.m[1][0]; + x_step[2] = inverse_matrix.m[2][0]; + y_step[0] = inverse_matrix.m[0][1]; + y_step[1] = inverse_matrix.m[1][1]; + y_step[2] = inverse_matrix.m[2][1]; + c_step[0] = (0.5f * (inverse_matrix.m[0][0] + inverse_matrix.m[0][1]) + inverse_matrix.m[0][2]); + c_step[1] = (0.5f * (inverse_matrix.m[1][0] + inverse_matrix.m[1][1]) + inverse_matrix.m[1][2]); + c_step[2] = 0.5f * (inverse_matrix.m[2][0] + inverse_matrix.m[2][1]) + inverse_matrix.m[2][2]; + +#else + + /* Compute interpolation steps. */ + x_step[0] = inverse_matrix.m[0][0] / rect_w; + x_step[1] = inverse_matrix.m[1][0] / rect_h; + x_step[2] = inverse_matrix.m[2][0]; + y_step[0] = inverse_matrix.m[0][1] / rect_w; + y_step[1] = inverse_matrix.m[1][1] / rect_h; + y_step[2] = inverse_matrix.m[2][1]; + c_step[0] = (0.5f * (inverse_matrix.m[0][0] + inverse_matrix.m[0][1]) + inverse_matrix.m[0][2]) / rect_w; + c_step[1] = (0.5f * (inverse_matrix.m[1][0] + inverse_matrix.m[1][1]) + inverse_matrix.m[1][2]) / rect_h; + c_step[2] = 0.5f * (inverse_matrix.m[2][0] + inverse_matrix.m[2][1]) + inverse_matrix.m[2][2]; + +#endif + + /* Determine image mode (NORMAL) depending on the color. */ + imageMode = 0x00001000; + + tiled_source = (source->tiled != VG_LITE_LINEAR) ? 0x10000000 : 0; + +#if gcFEATURE_VG_RECTANGLE_TILED_OUT + if(target->tiled == VG_LITE_TILED) { + tile_setting = 0x40; + stripe_mode = 0x20000000; + } +#endif + compress_mode = (uint32_t)source->compress_mode << 25; + + /* Setup the command buffer. */ +#if gcFEATURE_VG_GLOBAL_ALPHA + VG_LITE_RETURN_ERROR(push_state(&s_context, 0x0AD1, + s_context.dst_alpha_mode | s_context.dst_alpha_value | s_context.src_alpha_mode | s_context.src_alpha_value)); +#endif + VG_LITE_RETURN_ERROR(push_state(&s_context, 0x0A00, + 0x00000001 | in_premult | imageMode | transparency_mode | tile_setting | eco_fifo | s_context.scissor_enable | + stripe_mode)); + VG_LITE_RETURN_ERROR(push_state(&s_context, 0x0A02, color)); + VG_LITE_RETURN_ERROR(push_state_ptr(&s_context, 0x0A18, (void *)&c_step[0])); + VG_LITE_RETURN_ERROR(push_state_ptr(&s_context, 0x0A19, (void *)&c_step[1])); + VG_LITE_RETURN_ERROR(push_state_ptr(&s_context, 0x0A1A, (void *)&c_step[2])); + VG_LITE_RETURN_ERROR(push_state_ptr(&s_context, 0x0A1C, (void *)&x_step[0])); + VG_LITE_RETURN_ERROR(push_state_ptr(&s_context, 0x0A1D, (void *)&x_step[1])); + VG_LITE_RETURN_ERROR(push_state_ptr(&s_context, 0x0A1E, (void *)&x_step[2])); + VG_LITE_RETURN_ERROR(push_state(&s_context, 0x0A1F, 0x00000001)); + VG_LITE_RETURN_ERROR(push_state_ptr(&s_context, 0x0A20, (void *)&y_step[0])); + VG_LITE_RETURN_ERROR(push_state_ptr(&s_context, 0x0A21, (void *)&y_step[1])); + VG_LITE_RETURN_ERROR(push_state_ptr(&s_context, 0x0A22, (void *)&y_step[2])); + + if(((source->format >= VG_LITE_YUY2) && + (source->format <= VG_LITE_AYUY2)) || + ((source->format >= VG_LITE_YUY2_TILED) && + (source->format <= VG_LITE_AYUY2_TILED))) { + yuv2rgb = convert_yuv2rgb(source->yuv.yuv2rgb); + uv_swiz = convert_uv_swizzle(source->yuv.swizzle); + } + +#if gcFEATURE_VG_IM_FASTCLEAR + if(source->fc_enable) { + uint32_t im_fc_enable = (source->fc_enable == 0) ? 0 : 0x800000; + VG_LITE_RETURN_ERROR(push_state(&s_context, 0x0A25, + convert_source_format(source->format) | filter_mode | uv_swiz | yuv2rgb | conversion | im_fc_enable | ahb_read_split | + compress_mode | src_premultiply_enable | index_endian)); + VG_LITE_RETURN_ERROR(push_state(&s_context, 0x0ACF, source->fc_buffer[0].address)); /* FC buffer address. */ + VG_LITE_RETURN_ERROR(push_state(&s_context, 0x0AD0, source->fc_buffer[0].color)); /* FC clear value. */ + } +#endif + + VG_LITE_RETURN_ERROR(push_state(&s_context, 0x0A25, + convert_source_format(source->format) | filter_mode | uv_swiz | yuv2rgb | conversion | compress_mode | + src_premultiply_enable | index_endian)); + if(source->yuv.uv_planar) { + /* Program u plane address if necessary. */ + VG_LITE_RETURN_ERROR(push_state(&s_context, 0x0A51, source->yuv.uv_planar)); + } + if(source->yuv.v_planar) { + /* Program v plane address if necessary. */ + VG_LITE_RETURN_ERROR(push_state(&s_context, 0x0A53, source->yuv.v_planar)); + } + + VG_LITE_RETURN_ERROR(push_state(&s_context, 0x0A27, 0)); + VG_LITE_RETURN_ERROR(push_state(&s_context, 0x0A29, source->address)); + + VG_LITE_RETURN_ERROR(push_state(&s_context, 0x0A34, 0)); + /* 24bit format stride configured to 4bpp. */ + if(source->format >= VG_LITE_RGB888 && source->format <= VG_LITE_RGBA5658) { + stride = source->stride / 3 * 4; + VG_LITE_RETURN_ERROR(push_state(&s_context, 0x0A2B, stride | tiled_source)); + } + else { + VG_LITE_RETURN_ERROR(push_state(&s_context, 0x0A2B, source->stride | tiled_source)); + } + + VG_LITE_RETURN_ERROR(push_state(&s_context, 0x0A2D, rect_x | (rect_y << 16))); + VG_LITE_RETURN_ERROR(push_state(&s_context, 0x0A2F, rect_w | (rect_h << 16))); + VG_LITE_RETURN_ERROR(push_rectangle(&s_context, point_min.x, point_min.y, point_max.x - point_min.x, + point_max.y - point_min.y)); + +#if !gcFEATURE_VG_STRIPE_MODE + VG_LITE_RETURN_ERROR(push_state(&s_context, 0x0E02, 0x10 | (0x7 << 8))); + VG_LITE_RETURN_ERROR(push_state(&s_context, 0x0F00, 0x10 | (0x7 << 8))); +#endif + + if(!s_context.flexa_mode) { + error = flush_target(); + } + + vglitemDUMP_BUFFER("image", (size_t)source->address, source->memory, 0, (source->stride) * (source->height)); + +#if DUMP_IMAGE + dump_img(source->memory, source->width, source->height, source->format); +#endif + + return error; +#else + return VG_LITE_NOT_SUPPORT; +#endif +} + +vg_lite_error_t vg_lite_set_memory_pool(vg_lite_buffer_type_t type, vg_lite_memory_pool_t pool) +{ + if(!(pool >= VG_LITE_MEMORY_POOL_1 && pool <= VG_LITE_MEMORY_POOL_2)) + return VG_LITE_INVALID_ARGUMENT; + + switch(type) { + case VG_LITE_COMMAND_BUFFER: + s_context.command_buffer_pool = pool; + break; + + case VG_LITE_TESSELLATION_BUFFER: + s_context.tess_buffer_pool = pool; + break; + + case VG_LITE_RENDER_BUFFER: + s_context.render_buffer_pool = pool; + break; + + default: + return VG_LITE_INVALID_ARGUMENT; + } + + return VG_LITE_SUCCESS; +} + +vg_lite_error_t vg_lite_frame_delimiter(vg_lite_frame_flag_t flag) +{ + s_context.frame_flag = flag; + + vg_lite_error_t error = vg_lite_finish(); + + return error; +} + +#endif /* LV_USE_VG_LITE_DRIVER */ + diff --git a/src/libs/vg_lite_driver/VGLite/vg_lite_context.h b/src/libs/vg_lite_driver/VGLite/vg_lite_context.h new file mode 100755 index 0000000000..a09cf687ee --- /dev/null +++ b/src/libs/vg_lite_driver/VGLite/vg_lite_context.h @@ -0,0 +1,313 @@ +/**************************************************************************** +* +* Copyright 2012 - 2023 Vivante Corporation, Santa Clara, California. +* All Rights Reserved. +* +* Permission is hereby granted, free of charge, to any person obtaining +* a copy of this software and associated documentation files (the +* 'Software'), to deal in the Software without restriction, including +* without limitation the rights to use, copy, modify, merge, publish, +* distribute, sub license, and/or sell copies of the Software, and to +* permit persons to whom the Software is furnished to do so, subject +* to the following conditions: +* +* The above copyright notice and this permission notice (including the +* next paragraph) shall be included in all copies or substantial +* portions of the Software. +* +* THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND, +* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. +* IN NO EVENT SHALL VIVANTE AND/OR ITS SUPPLIERS BE LIABLE FOR ANY +* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, +* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE +* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +* +*****************************************************************************/ + +#include "../../../lv_conf_internal.h" +#if LV_USE_VG_LITE_DRIVER + +#include +#include +#include +#include +#include +#include +#include "../inc/vg_lite.h" +#include "../VGLiteKernel/vg_lite_kernel.h" +#include "../VGLiteKernel/vg_lite_option.h" + +#define DUMP_CAPTURE 0 +#define DUMP_COMMAND_CAPTURE 0 +#define DUMP_INIT_COMMAND 0 +#define DUMP_API 0 +#define DUMP_LAST_CAPTURE 0 + +#if DUMP_API + #include "dumpAPI.h" +#endif + +#define VGLITE_LOG printf + +/*** Global Context Access ***/ +#define GET_CONTEXT() &s_context + +/*** Default command buffer size is 32KB. Double command buffer is used. + App can call vg_lite_set_command_buffer_size(size) before vg_lite_init() + to overwrite the default command buffer size. +***/ +#define VG_LITE_COMMAND_BUFFER_SIZE (32 << 10) +#define VG_LITE_SINGLE_COMMAND_BUFFER_SIZE (64 << 10) /* For only using one command buffer. */ + +#define CMDBUF_BUFFER(context) (context).command_buffer[(context).command_buffer_current] +#define CMDBUF_INDEX(context) (context).command_buffer_current +#define CMDBUF_SIZE(context) (context).command_buffer_size +#define CMDBUF_OFFSET(context) (context).command_offset[(context).command_buffer_current] +#define CMDBUF_SWAP(context) (context).command_buffer_current = \ + ((context).command_buffer_current + 1) % CMDBUF_COUNT + +/*** Command macros ***/ +#define VG_LITE_END(interrupt) (0x00000000 | interrupt) +#define VG_LITE_SEMAPHORE(id) (0x10000000 | id) +#define VG_LITE_STALL(id) (0x20000000 | id) +#define VG_LITE_STATE(address) (0x30010000 | address) +#define VG_LITE_STATES(count, address) (0x30000000 | ((count) << 16) | address) +#define VG_LITE_DATA(count) (0x40000000 | count) +#define VG_LITE_CALL(count) (0x60000000 | count) +#define VG_LITE_RETURN() (0x70000000) +#define VG_LITE_NOP() (0x80000000) + +#define FC_BURST_BYTES 64 +#define FC_BIT_TO_BYTES 64 + +#define STATES_COUNT 208 +#define MIN_TS_SIZE 8 << 10 + +#define VG_LITE_RETURN_ERROR(func) \ + if ((error = func) != VG_LITE_SUCCESS) \ + return error + +#define VG_LITE_BREAK_ERROR(func) \ + if ((error = func) != VG_LITE_SUCCESS) \ + break + +#define VG_LITE_ERROR_HANDLER(func) \ + if ((error = func) != VG_LITE_SUCCESS) \ + goto ErrorHandler + +/*** Shortcuts. ***/ +#define A(color) (color) >> 24 +#define R(color) ((color) & 0x00ff0000) >> 16 +#define G(color) ((color) & 0x0000ff00) >> 8 +#define B(color) ((color) & 0xff) +#define ARGB(a, r, g, b) ((a) << 24) | ((r) << 16) | ((g) << 8 ) | (b) +#define ARGB4(a, r, g, b) (((a) & 0xf0) << 8) | (((r) & 0xf0) << 4) | (((g) & 0xf0)) | ((b) >> 4) + +#define MIN(a, b) (a) > (b) ? (b) : (a) +#define MAX(a, b) (a) > (b) ? (a) : (b) + +#define LERP(v1, v2, w) ((v1) * (w) + (v2) * (1.0f - (w))) +#define CLAMP(x, min, max) (((x) < (min)) ? (min) : ((x) > (max)) ? (max) : (x)) + +#define COLOR_FROM_RAMP(ColorRamp) (((vg_lite_float_t *) ColorRamp) + 1) + +#define MATRIX_ROWS 3 +#define GET_MATRIX_VALUES(Pointer) ((float *) (Pointer)) +#define MAT(Matrix, Row, Column) (GET_MATRIX_VALUES(Matrix)[Row * MATRIX_ROWS + Column]) +#define PI 3.141592653589793238462643383279502f + +#if !gcFEATURE_VG_MATH_PRECISION_FIX && (CHIPID == 0x555) + #define VG_SW_BLIT_PRECISION_OPT 1 +#else + #define VG_SW_BLIT_PRECISION_OPT 0 +#endif + +/* Driver implementation internal structures. +*/ +typedef struct vg_lite_states { + uint32_t state; + uint8_t init; +} vg_lite_states_t; + +typedef struct vg_lite_hardware { + vg_lite_states_t hw_states[STATES_COUNT]; +} vg_lite_hardware_t; + +/* Tessellation buffer information. */ +typedef struct vg_lite_tess_buffer { + vg_lite_uint32_t physical_addr; /*! Physical address for tessellation buffer. */ + vg_lite_uint8_t * logical_addr; /*! Logical address for tessellation buffer. */ + vg_lite_uint32_t tessbuf_size; /*! Buffer size for tessellation buffer */ + vg_lite_uint32_t countbuf_size; /*! Buffer size for VG count buffer */ + vg_lite_uint32_t tess_w_h; /*! Combination of buffer width and height. */ + /* gc355 Specific fields below */ + vg_lite_uint32_t L1_phyaddr; /*! L1 physical address. */ + vg_lite_uint32_t L2_phyaddr; /*! L2 physical address. */ + vg_lite_uint8_t * L1_logical; /*! L1 Logical address. */ + vg_lite_uint8_t * L2_logical; /*! L2 Logical address. */ + vg_lite_uint32_t L1_size; /*! L1 size for tessellation buffer */ + vg_lite_uint32_t L2_size; /*! L2 size for tessellation buffer */ + vg_lite_uint32_t tess_stride; /*! Stride for tessellation buffer */ +} vg_lite_tess_buffer_t; + +typedef struct vg_lite_context { + vg_lite_kernel_context_t context; + vg_lite_hardware_t hw; + vg_lite_capabilities_t capabilities; + uint8_t * command_buffer[CMDBUF_COUNT]; + uint32_t command_buffer_size; + uint32_t command_offset[CMDBUF_COUNT]; + uint32_t command_buffer_current; + vg_lite_memory_pool_t command_buffer_pool; + + vg_lite_tess_buffer_t tessbuf; + vg_lite_memory_pool_t tess_buffer_pool; + + vg_lite_buffer_t * rtbuffer; /* DDRLess: this is used as composing buffer. */ + vg_lite_memory_pool_t render_buffer_pool; + + vg_lite_float_t path_lastX; + vg_lite_float_t path_lastY; + uint32_t scissor_set; + uint32_t scissor_enable; + uint32_t scissor_dirty; + int32_t scissor[4]; /* Scissor area: x, y, right, bottom. */ + vg_lite_buffer_t * scissor_layer; + + uint32_t src_alpha_mode; + uint32_t src_alpha_value; + uint32_t dst_alpha_mode; + uint32_t dst_alpha_value; + vg_lite_blend_t blend_mode; + + uint32_t sbi_mode; + uint32_t sync_mode; + uint32_t flexa_mode; + uint32_t stream_id; + uint32_t segment_address; + uint32_t segment_count; + uint32_t segment_size; + uint32_t stop_flag; + uint8_t flexa_dirty; + uint32_t start_flag; + uint32_t reset_flag; + uint8_t custom_cmdbuf; + uint8_t custom_tessbuf; + uint32_t enable_mask; + uint32_t matrix_enable; + uint32_t tess_width; + uint32_t tess_height; + uint32_t target_width; + uint32_t target_height; + uint8_t enable_scissor; + uint32_t mirror_orient; + uint32_t mirror_dirty; + uint32_t gamma_value; + uint32_t gamma_dirty; + uint32_t gamma_src; + uint32_t gamma_dst; + uint32_t gamma_stencil; + uint32_t color_transform; + uint32_t path_counter; + vg_lite_filter_t filter; + void * last_command_buffer_logical; + size_t Physical; + uint32_t last_command_size; + vg_lite_frame_flag_t frame_flag; + +} vg_lite_context_t; + +typedef struct vg_lite_ftable { + uint32_t ftable[gcFEATURE_COUNT]; +} vg_lite_ftable_t; + +extern vg_lite_context_t s_context; +extern vg_lite_ftable_t s_ftable; + +extern vg_lite_error_t set_render_target(vg_lite_buffer_t * target); +extern vg_lite_error_t push_state(vg_lite_context_t * context, uint32_t address, uint32_t data); +extern vg_lite_error_t push_state_ptr(vg_lite_context_t * context, uint32_t address, void * data_ptr); +extern vg_lite_error_t push_call(vg_lite_context_t * context, uint32_t address, uint32_t bytes); +extern vg_lite_error_t push_data(vg_lite_context_t * context, uint32_t size, void * data); +extern vg_lite_error_t push_clut(vg_lite_context_t * context, uint32_t address, uint32_t count, uint32_t * data); +extern vg_lite_error_t push_stall(vg_lite_context_t * context, uint32_t module); + +extern void * vg_lite_os_malloc(size_t size); +extern void vg_lite_os_free(void * memory); + +extern vg_lite_void set_gamma_dest_only(vg_lite_buffer_t * target, vg_lite_int32_t stencil); +extern vg_lite_void save_st_gamma_src_dest(vg_lite_buffer_t * source, vg_lite_buffer_t * target); +extern vg_lite_void get_st_gamma_src_dest(vg_lite_buffer_t * source, vg_lite_buffer_t * target); + +extern vg_lite_void setup_lvgl_image(vg_lite_buffer_t * dst, vg_lite_buffer_t * src, vg_lite_buffer_t * temp, + vg_lite_blend_t operation); + +#if defined(__ZEPHYR__) + extern void * vg_lite_os_fopen(const char * __restrict path, const char * __restrict mode); + extern int vg_lite_os_fclose(void * fp); + extern size_t vg_lite_os_fread(void * __restrict ptr, size_t size, size_t nmemb, void * __restrict fp); + extern size_t vg_lite_os_fwrite(const void * __restrict ptr, size_t size, size_t nmemb, void * fp); + extern int vg_lite_os_fseek(void * fp, long offset, int whence); + extern int vg_lite_os_fflush(void * fp); + extern int vg_lite_os_fprintf(void * __restrict fp, const char * __restrict format, ...); + extern int vg_lite_os_getpid(void); +#else + extern int vg_lite_os_fseek(FILE * Stream, long Offset, int Origin); + extern FILE * vg_lite_os_fopen(char const * FileName, char const * Mode); + extern long vg_lite_os_ftell(FILE * Stream); + extern size_t vg_lite_os_fread(void * Buffer, size_t ElementSize, size_t ElementCount, FILE * Stream); + extern size_t vg_lite_os_fwrite(void const * Buffer, size_t ElementSize, size_t ElementCount, FILE * Stream); + extern int vg_lite_os_close(FILE * Stream); + extern int vg_lite_os_fflush(FILE * fp); +#endif + +/**************************** Dump command, image ********************************************/ + +#define DUMP_COMMAND 0 +#define DUMP_IMAGE 0 + +/* Enable FC buffer dump if SOC supports fast clear */ +#define VG_TARGET_FC_DUMP 0 + +#if DUMP_COMMAND || DUMP_IMAGE + #ifdef __linux__ + #include + #endif + FILE * fp; + char filename[30]; +#endif + +/**************************** Dump Capture ****************************************************/ + +#ifndef vgliteDUMP_PATH + #define vgliteDUMP_PATH "./" +#endif + +#ifndef vgliteDUMP_KEY + #define vgliteDUMP_KEY "process" +#endif + +#if DUMP_LAST_CAPTURE + void _SetDumpFileInfo(); + vg_lite_error_t vglitefDumpBuffer_single(char * Tag, size_t Physical, void * Logical, size_t Offset, size_t Bytes); + #define vglitemDUMP_single vglitefDump + #define vglitemDUMP_BUFFER_single vglitefDumpBuffer_single +#endif +#if DUMP_CAPTURE +void _SetDumpFileInfo(); +vg_lite_error_t vglitefDump(char * String, ...); +vg_lite_error_t vglitefDumpBuffer(char * Tag, size_t Physical, void * Logical, size_t Offset, size_t Bytes); +#define vglitemDUMP vglitefDump +#define vglitemDUMP_BUFFER vglitefDumpBuffer +#else +static inline void __dummy_dump(char * Message, ...) {} +static inline void __dummy_dump_buffer(char * Tag, size_t Physical, void * Logical, size_t Offset, size_t Bytes) {} +#define vglitemDUMP __dummy_dump +#define vglitemDUMP_BUFFER __dummy_dump_buffer +#endif + +/**********************************************************************************************/ + +#endif /* LV_USE_VG_LITE_DRIVER */ + diff --git a/src/libs/vg_lite_driver/VGLite/vg_lite_image.c b/src/libs/vg_lite_driver/VGLite/vg_lite_image.c new file mode 100755 index 0000000000..40af3750a8 --- /dev/null +++ b/src/libs/vg_lite_driver/VGLite/vg_lite_image.c @@ -0,0 +1,2385 @@ +/**************************************************************************** +* +* Copyright 2012 - 2023 Vivante Corporation, Santa Clara, California. +* All Rights Reserved. +* +* Permission is hereby granted, free of charge, to any person obtaining +* a copy of this software and associated documentation files (the +* 'Software'), to deal in the Software without restriction, including +* without limitation the rights to use, copy, modify, merge, publish, +* distribute, sub license, and/or sell copies of the Software, and to +* permit persons to whom the Software is furnished to do so, subject +* to the following conditions: +* +* The above copyright notice and this permission notice (including the +* next paragraph) shall be included in all copies or substantial +* portions of the Software. +* +* THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND, +* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. +* IN NO EVENT SHALL VIVANTE AND/OR ITS SUPPLIERS BE LIABLE FOR ANY +* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, +* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE +* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +* +*****************************************************************************/ + +#include "../../../lv_conf_internal.h" +#if LV_USE_VG_LITE_DRIVER + +#include "vg_lite_context.h" + +#define MATRIX_FP_ABS(x) (((x) < 0) ? -(x) : (x)) +#define MATRIX_FP_EPS 2.2204460492503131e-14 + +extern vg_lite_matrix_t identity_mtx; + +/* Get the plane memory pointer and strides info. */ +static uint32_t get_buffer_planes(vg_lite_buffer_t * buffer, + uint8_t ** memory, + uint32_t * strides) +{ + uint32_t count = 1; + + switch(buffer->format) { + case VG_LITE_RGBA8888: + case VG_LITE_BGRA8888: + case VG_LITE_RGBX8888: + case VG_LITE_BGRX8888: + case VG_LITE_RGB565: + case VG_LITE_BGR565: + case VG_LITE_RGBA4444: + case VG_LITE_BGRA4444: + case VG_LITE_BGRA5551: + case VG_LITE_A8: + case VG_LITE_L8: + case VG_LITE_A4: + case VG_LITE_INDEX_1: + case VG_LITE_INDEX_2: + case VG_LITE_INDEX_4: + case VG_LITE_INDEX_8: + case VG_LITE_YUYV: + case VG_LITE_YUY2: + case VG_LITE_RGBA2222: + count = 1; + memory[0] = (uint8_t *)buffer->memory; + memory[1] = memory[2] = ((uint8_t *)0); + strides[0] = buffer->stride; + strides[1] = strides[2] = 0; + break; + + case VG_LITE_NV12: + case VG_LITE_NV16: + case VG_LITE_NV24: + case VG_LITE_NV24_TILED: + count = 2; + memory[0] = (uint8_t *)buffer->memory; + memory[1] = (uint8_t *)buffer->yuv.uv_memory; + memory[2] = 0; + strides[0] = buffer->stride; + strides[1] = buffer->yuv.uv_stride; + strides[2] = 0; + break; + + case VG_LITE_AYUY2: + count = 2; + memory[0] = (uint8_t *)buffer->memory; + memory[1] = 0; + memory[2] = (uint8_t *)buffer->yuv.v_memory; + strides[0] = buffer->stride; + strides[1] = 0; + strides[2] = buffer->yuv.alpha_stride; + break; + + case VG_LITE_ANV12: + count = 3; + memory[0] = (uint8_t *)buffer->memory; + memory[1] = (uint8_t *)buffer->yuv.uv_memory; + memory[2] = (uint8_t *)buffer->yuv.v_memory; + strides[0] = buffer->stride; + strides[1] = buffer->yuv.uv_stride; + strides[2] = buffer->yuv.alpha_stride; + break; + + case VG_LITE_YV12: + case VG_LITE_YV24: + case VG_LITE_YV16: + count = 3; + memory[0] = (uint8_t *)buffer->memory; + memory[1] = (uint8_t *)buffer->yuv.uv_memory; + memory[2] = (uint8_t *)buffer->yuv.v_memory; + strides[0] = buffer->stride; + strides[1] = buffer->yuv.uv_stride; + strides[2] = buffer->yuv.v_stride; + break; + + case VG_LITE_YUY2_TILED: + case VG_LITE_NV12_TILED: + case VG_LITE_ANV12_TILED: + case VG_LITE_AYUY2_TILED: + default: + count = 0; + + break; + } + return count; +} + +vg_lite_error_t vg_lite_upload_buffer(vg_lite_buffer_t * buffer, + vg_lite_uint8_t * data[3], + vg_lite_uint32_t stride[3]) +{ +#if DUMP_API + FUNC_DUMP(vg_lite_upload_buffer)(buffer, data, stride); +#endif + + vg_lite_error_t error = VG_LITE_SUCCESS; + int32_t plane_count; + uint8_t * buffer_memory[3] = {((uint8_t *)0)}; + uint32_t buffer_strides[3] = {0}; + uint8_t * pdata; + int32_t i, j; + +#if gcFEATURE_VG_TRACE_API + VGLITE_LOG("vg_lite_upload_buffer %p %p %p\n", buffer, data, stride); +#endif + + /* Get buffer memory info. */ + plane_count = get_buffer_planes(buffer, buffer_memory, buffer_strides); + + if(plane_count > 0 && plane_count <= 3) { + /* Copy the data to buffer. */ + for(i = 0; i < plane_count; i++) { + pdata = data[i]; + for(j = 0; j < buffer->height; j++) { + memcpy(buffer_memory[i], pdata, buffer_strides[i]); + buffer_memory[i] += buffer_strides[i]; + pdata += stride[i]; + } + } + } + else { + error = VG_LITE_INVALID_ARGUMENT; + } + + return error; +} + +static vg_lite_error_t swap(float * a, float * b) +{ + float temp; + if(a == NULL || b == NULL) + return VG_LITE_INVALID_ARGUMENT; + temp = *a; + *a = *b; + *b = temp; + return VG_LITE_SUCCESS; +} + +vg_lite_error_t vg_lite_get_transform_matrix(vg_lite_float_point4_t src, vg_lite_float_point4_t dst, + vg_lite_matrix_t * mat) +{ + float a[8][8], b[9], A[64]; + int i, j, k, m = 8, n = 1; + int astep = 8, bstep = 1; + float d; + +#if gcFEATURE_VG_TRACE_API + VGLITE_LOG("vg_lite_get_transform_matrix %p %p %p\n", src, dst, mat); +#endif + + if(src == NULL || dst == NULL || mat == NULL) + return VG_LITE_INVALID_ARGUMENT; + + for(i = 0; i < 4; ++i) { + a[i][0] = a[i + 4][3] = (float)src[i].x; + a[i][1] = a[i + 4][4] = (float)src[i].y; + a[i][2] = a[i + 4][5] = 1.0f; + a[i][3] = a[i][4] = a[i][5] = + a[i + 4][0] = a[i + 4][1] = a[i + 4][2] = 0.0f; + a[i][6] = (float)(-src[i].x * dst[i].x); + a[i][7] = (float)(-src[i].y * dst[i].x); + a[i + 4][6] = (float)(-src[i].x * dst[i].y); + a[i + 4][7] = (float)(-src[i].y * dst[i].y); + b[i] = (float)dst[i].x; + b[i + 4] = (float)dst[i].y; + } + for(i = 0; i < 8; ++i) { + for(j = 0; j < 8; ++j) { + A[8 * i + j] = a[i][j]; + } + } + + for(i = 0; i < m; i++) { + k = i; + for(j = i + 1; j < m; j++) + if(MATRIX_FP_ABS(A[j * astep + i]) > MATRIX_FP_ABS(A[k * astep + i])) + k = j; + if(MATRIX_FP_ABS(A[k * astep + i]) < MATRIX_FP_EPS) + return VG_LITE_INVALID_ARGUMENT; + if(k != i) { + for(j = i; j < m; j++) + swap(&A[i * astep + j], &A[k * astep + j]); + for(j = 0; j < n; j++) + swap(&b[i * bstep + j], &b[k * bstep + j]); + } + d = -1 / A[i * astep + i]; + for(j = i + 1; j < m; j++) { + float alpha = A[j * astep + i] * d; + for(k = i + 1; k < m; k++) + A[j * astep + k] += alpha * A[i * astep + k]; + for(k = 0; k < n; k++) + b[j * bstep + k] += alpha * b[i * bstep + k]; + } + } + + for(i = m - 1; i >= 0; i--) + for(j = 0; j < n; j++) { + float s = b[i * bstep + j]; + for(k = i + 1; k < m; k++) + s -= A[i * astep + k] * b[k * bstep + j]; + b[i * bstep + j] = s / A[i * astep + i]; + } + + b[8] = 1; + + for(i = 0; i < 3; ++i) { + for(j = 0; j < 3; ++j) { + mat->m[i][j] = b[i * 3 + j]; + } + } + + return VG_LITE_SUCCESS; +} + +vg_lite_error_t vg_lite_set_scissor(vg_lite_int32_t x, vg_lite_int32_t y, vg_lite_int32_t right, vg_lite_int32_t bottom) +{ +#if DUMP_API + FUNC_DUMP(vg_lite_set_scissor)(x, y, right, bottom); +#endif + +#if gcFEATURE_VG_SCISSOR + vg_lite_error_t error = VG_LITE_SUCCESS; + +#if gcFEATURE_VG_TRACE_API + VGLITE_LOG("vg_lite_set_scissor %d %d %d %d\n", x, y, right, bottom); +#endif + + /* Save scissor Box States. */ + s_context.scissor[0] = x; + s_context.scissor[1] = y; + s_context.scissor[2] = right; + s_context.scissor[3] = bottom; + + /* Scissor dirty. */ + s_context.scissor_dirty = 1; + s_context.scissor_set = 1; + + return error; +#else + return VG_LITE_NOT_SUPPORT; +#endif +} + +vg_lite_error_t vg_lite_enable_scissor() +{ +#if DUMP_API + FUNC_DUMP(vg_lite_enable_scissor)(); +#endif + +#if gcFEATURE_VG_MASK + +#if gcFEATURE_VG_TRACE_API + VGLITE_LOG("vg_lite_enable_scissor\n"); +#endif + + /* Enable scissor Mode. */ + if(!s_context.scissor_enable) { + s_context.scissor_enable = 1 << 4; + s_context.scissor_dirty = 1; + } + + return VG_LITE_SUCCESS; +#else + /* Noop */ + return VG_LITE_SUCCESS; +#endif +} + +vg_lite_error_t vg_lite_disable_scissor() +{ +#if DUMP_API + FUNC_DUMP(vg_lite_disable_scissor)(); +#endif + +#if gcFEATURE_VG_MASK + +#if gcFEATURE_VG_TRACE_API + VGLITE_LOG("vg_lite_disable_scissor\n"); +#endif + + /* Disable scissor Mode. */ + if(s_context.scissor_enable) { + s_context.scissor_enable = 0; + s_context.scissor_dirty = 1; + } + + return VG_LITE_SUCCESS; +#else + /* Noop */ + return VG_LITE_SUCCESS; +#endif +} + +vg_lite_error_t vg_lite_set_CLUT(vg_lite_uint32_t count, vg_lite_uint32_t * colors) +{ +#if gcFEATURE_VG_IM_INDEX_FORMAT + vg_lite_error_t error = VG_LITE_SUCCESS; + uint32_t addr = 0x0B00; + +#if gcFEATURE_VG_TRACE_API + VGLITE_LOG("vg_lite_set_CLUT %d %p\n", count, colors); +#endif + +#if gcFEATURE_VG_NEW_IMAGE_INDEX + { + switch(count) { + case 256: + case 16: + case 4: + case 2: + addr = 0x0B00; + break; + default: + error = VG_LITE_INVALID_ARGUMENT; + return error; + break; + } + } +#else + { + switch(count) { + case 256: + addr = 0x0B00; + break; + case 16: + addr = 0x0AA0; + break; + case 4: + addr = 0x0A9C; + break; + case 2: + addr = 0x0A98; + break; + default: + error = VG_LITE_INVALID_ARGUMENT; + return error; + break; + } + } +#endif + + VG_LITE_RETURN_ERROR(push_clut(&s_context, addr, count, (uint32_t *)colors)); + + return error; +#else + return VG_LITE_NOT_SUPPORT; +#endif +} + +vg_lite_error_t vg_lite_source_global_alpha(vg_lite_global_alpha_t alpha_mode, vg_lite_uint8_t alpha_value) +{ +#if DUMP_API + FUNC_DUMP(vg_lite_source_global_alpha)(alpha_mode, alpha_value); +#endif + +#if gcFEATURE_VG_GLOBAL_ALPHA + uint32_t image_alpha_mode; + uint32_t image_alpha_value; + +#if gcFEATURE_VG_TRACE_API + VGLITE_LOG("vg_lite_source_global_alpha %d %d\n", alpha_mode, alpha_value); +#endif + + image_alpha_mode = (uint8_t)alpha_mode; + image_alpha_value = alpha_value << 2; + + s_context.src_alpha_mode = image_alpha_mode; + s_context.src_alpha_value = image_alpha_value; + + return VG_LITE_SUCCESS; +#else + return VG_LITE_NOT_SUPPORT; +#endif +} + +vg_lite_error_t vg_lite_dest_global_alpha(vg_lite_global_alpha_t alpha_mode, vg_lite_uint8_t alpha_value) +{ +#if DUMP_API + FUNC_DUMP(vg_lite_dest_global_alpha)(alpha_mode, alpha_value); +#endif + +#if gcFEATURE_VG_GLOBAL_ALPHA + uint32_t dest_alpha_mode; + uint32_t dest_alpha_value; + +#if gcFEATURE_VG_TRACE_API + VGLITE_LOG("vg_lite_dest_global_alpha %d %d\n", alpha_mode, alpha_value); +#endif + + dest_alpha_mode = (alpha_mode == VG_LITE_NORMAL) ? 0 : (alpha_mode == VG_LITE_GLOBAL) ? 0x00000400 : 0x00000800; + dest_alpha_value = alpha_value << 12; + + s_context.dst_alpha_mode = dest_alpha_mode; + s_context.dst_alpha_value = dest_alpha_value; + + return VG_LITE_SUCCESS; +#else + return VG_LITE_NOT_SUPPORT; +#endif +} + +vg_lite_error_t vg_lite_set_color_key(vg_lite_color_key4_t colorkey) +{ +#if DUMP_API + FUNC_DUMP(vg_lite_set_color_key)(colorkey); +#endif + +#if gcFEATURE_VG_COLOR_KEY + uint8_t i; + uint32_t value_low = 0; + uint32_t value_high = 0; + uint8_t r, g, b, a, e; + vg_lite_error_t error = VG_LITE_SUCCESS; + +#if gcFEATURE_VG_TRACE_API + VGLITE_LOG("vg_lite_set_color_key %p\n", colorkey); +#endif + + /* Set color key states. */ + for(i = 0; i < 4; i++) { + /* Set gcregVGPEColorKeyLow. Layout "E/R/G/B". */ + r = colorkey[i].low_r; + g = colorkey[i].low_g; + b = colorkey[i].low_b; + e = colorkey[i].enable; + value_low = (e << 24) | (r << 16) | (g << 8) | b; + VG_LITE_RETURN_ERROR(push_state(&s_context, 0x0A90 + i, value_low)); + + /* Set gcregVGPEColorKeyHigh. Layout "A/R/G/B". */ + r = colorkey[i].hign_r; + g = colorkey[i].hign_g; + b = colorkey[i].hign_b; + a = colorkey[i].alpha; + value_high = (a << 24) | (r << 16) | (g << 8) | b; + VG_LITE_RETURN_ERROR(push_state(&s_context, 0x0A94 + i, value_high)); + } + + return error; +#else + return VG_LITE_NOT_SUPPORT; +#endif +} + +vg_lite_error_t vg_lite_enable_dither() +{ +#if DUMP_API + FUNC_DUMP(vg_lite_enable_dither)(); +#endif + +#if gcFEATURE_VG_DITHER + vg_lite_error_t error = VG_LITE_SUCCESS; + uint32_t table_low = 0x7B48F3C0; + uint32_t table_high = 0x596AD1E2; + +#if gcFEATURE_VG_TRACE_API + VGLITE_LOG("vg_lite_enable_dither\n"); +#endif + + VG_LITE_RETURN_ERROR(push_state(&s_context, 0x0A5A, table_low)); + VG_LITE_RETURN_ERROR(push_state(&s_context, 0x0A5B, table_high)); + + return error; +#else + return VG_LITE_NOT_SUPPORT; +#endif +} + +vg_lite_error_t vg_lite_disable_dither() +{ +#if DUMP_API + FUNC_DUMP(vg_lite_disable_dither)(); +#endif + +#if gcFEATURE_VG_DITHER + vg_lite_error_t error = VG_LITE_SUCCESS; + +#if gcFEATURE_VG_TRACE_API + VGLITE_LOG("vg_lite_disable_dither\n"); +#endif + + VG_LITE_RETURN_ERROR(push_state(&s_context, 0x0A5A, 0xFFFFFFFF)); + VG_LITE_RETURN_ERROR(push_state(&s_context, 0x0A5B, 0xFFFFFFFF)); + + return error; +#else + return VG_LITE_NOT_SUPPORT; +#endif +} + +vg_lite_error_t vg_lite_enable_masklayer() +{ +#if DUMP_API + FUNC_DUMP(vg_lite_enable_masklayer)(); +#endif + +#if gcFEATURE_VG_MASK + vg_lite_error_t error = VG_LITE_SUCCESS; + +#if gcFEATURE_VG_TRACE_API + VGLITE_LOG("vg_lite_enable_masklayer\n"); +#endif + + s_context.enable_mask = (1 << 20); + + return error; +#else + return VG_LITE_NOT_SUPPORT; +#endif +} + +vg_lite_error_t vg_lite_disable_masklayer() +{ +#if DUMP_API + FUNC_DUMP(vg_lite_disable_masklayer)(); +#endif + +#if gcFEATURE_VG_MASK + vg_lite_error_t error = VG_LITE_SUCCESS; + +#if gcFEATURE_VG_TRACE_API + VGLITE_LOG("vg_lite_disable_masklayer\n"); +#endif + + s_context.enable_mask = 0; + + return error; +#else + return VG_LITE_NOT_SUPPORT; +#endif +} + +vg_lite_error_t vg_lite_create_masklayer(vg_lite_buffer_t * masklayer, vg_lite_uint32_t width, vg_lite_uint32_t height) +{ +#if DUMP_API + FUNC_DUMP(vg_lite_create_masklayer)(masklayer, width, height); +#endif + +#if gcFEATURE_VG_MASK + vg_lite_error_t error = VG_LITE_SUCCESS; + +#if gcFEATURE_VG_TRACE_API + VGLITE_LOG("vg_lite_create_masklayer %p %d %d\n", masklayer, width, height); +#endif + + memset(masklayer, 0, sizeof(vg_lite_buffer_t)); + masklayer->width = width; + masklayer->height = height; + masklayer->format = VG_LITE_A8; + VG_LITE_RETURN_ERROR(vg_lite_allocate(masklayer)); + + VG_LITE_RETURN_ERROR(vg_lite_clear(masklayer, NULL, 0xFF << 24)); + + return error; +#else + return VG_LITE_NOT_SUPPORT; +#endif +} + +vg_lite_error_t vg_lite_fill_masklayer(vg_lite_buffer_t * masklayer, vg_lite_rectangle_t * rect, vg_lite_uint8_t value) +{ +#if DUMP_API + FUNC_DUMP(vg_lite_fill_masklayer)(masklayer, rect, value); +#endif + +#if gcFEATURE_VG_MASK + vg_lite_error_t error = VG_LITE_SUCCESS; + +#if gcFEATURE_VG_TRACE_API + VGLITE_LOG("vg_lite_fill_masklayer %p %p %d\n", masklayer, rect, value); +#endif + + error = vg_lite_clear(masklayer, rect, value << 24); + + return error; +#else + return VG_LITE_NOT_SUPPORT; +#endif +} + +vg_lite_error_t vg_lite_blend_masklayer( + vg_lite_buffer_t * dst_masklayer, + vg_lite_buffer_t * src_masklayer, + vg_lite_mask_operation_t operation, + vg_lite_rectangle_t * rect +) +{ +#if DUMP_API + FUNC_DUMP(vg_lite_blend_masklayer)(dst_masklayer, src_masklayer, operation, rect); +#endif + +#if gcFEATURE_VG_MASK + vg_lite_error_t error = VG_LITE_SUCCESS; + vg_lite_matrix_t matrix; + vg_lite_filter_t filter = VG_LITE_FILTER_POINT; + vg_lite_rectangle_t area = *rect; + +#if gcFEATURE_VG_TRACE_API + VGLITE_LOG("vg_lite_blend_masklayer %p %p %d %p\n", dst_masklayer, src_masklayer, operation, rect); +#endif + + vg_lite_identity(&matrix); + vg_lite_translate((vg_lite_float_t)rect->x, (vg_lite_float_t)rect->y, &matrix); + + switch(operation) { + case VG_LITE_CLEAR_MASK: + VG_LITE_RETURN_ERROR(vg_lite_clear(dst_masklayer, &area, 0x0)); + break; + case VG_LITE_FILL_MASK: + VG_LITE_RETURN_ERROR(vg_lite_clear(dst_masklayer, &area, 0xFF << 24)); + break; + case VG_LITE_SET_MASK: + area.x = 0; + area.y = 0; + VG_LITE_RETURN_ERROR(vg_lite_blit_rect(dst_masklayer, src_masklayer, &area, &matrix, VG_LITE_BLEND_NONE, 0, filter)); + break; + case VG_LITE_UNION_MASK: + area.x = 0; + area.y = 0; + VG_LITE_RETURN_ERROR(vg_lite_blit_rect(dst_masklayer, src_masklayer, &area, &matrix, VG_LITE_BLEND_SCREEN, 0, filter)); + break; + case VG_LITE_INTERSECT_MASK: + area.x = 0; + area.y = 0; + VG_LITE_RETURN_ERROR(vg_lite_blit_rect(dst_masklayer, src_masklayer, &area, &matrix, VG_LITE_BLEND_DST_IN, 0, filter)); + break; + case VG_LITE_SUBTRACT_MASK: + area.x = 0; + area.y = 0; + VG_LITE_RETURN_ERROR(vg_lite_blit_rect(dst_masklayer, src_masklayer, &area, &matrix, VG_LITE_BLEND_SUBTRACT, 0, + filter)); + break; + default: + break; + } + + return error; +#else + return VG_LITE_NOT_SUPPORT; +#endif +} + +vg_lite_error_t vg_lite_set_masklayer(vg_lite_buffer_t * masklayer) +{ +#if DUMP_API + FUNC_DUMP(vg_lite_set_masklayer)(masklayer); +#endif + +#if gcFEATURE_VG_MASK + vg_lite_error_t error = VG_LITE_SUCCESS; + +#if gcFEATURE_VG_TRACE_API + VGLITE_LOG("vg_lite_set_masklayer %p\n", masklayer); +#endif + + VG_LITE_RETURN_ERROR(push_state(&s_context, 0x0A14, masklayer->address)); + VG_LITE_RETURN_ERROR(push_state(&s_context, 0x0A15, masklayer->stride)); + VG_LITE_RETURN_ERROR(push_state(&s_context, 0x0A1B, 0x00000010)); + + return error; +#else + return VG_LITE_NOT_SUPPORT; +#endif +} + +vg_lite_error_t vg_lite_render_masklayer( + vg_lite_buffer_t * masklayer, + vg_lite_mask_operation_t operation, + vg_lite_path_t * path, + vg_lite_fill_t fill_rule, + vg_lite_color_t color, + vg_lite_matrix_t * matrix +) +{ +#if DUMP_API + FUNC_DUMP(vg_lite_render_masklayer)(masklayer, operation, path, fill_rule, color, matrix); +#endif + +#if gcFEATURE_VG_MASK + vg_lite_error_t error = VG_LITE_SUCCESS; + +#if gcFEATURE_VG_TRACE_API + VGLITE_LOG("vg_lite_render_masklayer %p %d %p %d %d %p\n", masklayer, operation, path, fill_rule, color, matrix); +#endif + + if(!matrix) { + matrix = &identity_mtx; + } + + switch(operation) { + case VG_LITE_CLEAR_MASK: + VG_LITE_RETURN_ERROR(vg_lite_draw(masklayer, path, fill_rule, matrix, VG_LITE_BLEND_NONE, 0)); + break; + case VG_LITE_FILL_MASK: + VG_LITE_RETURN_ERROR(vg_lite_draw(masklayer, path, fill_rule, matrix, VG_LITE_BLEND_NONE, 0xFF << 24)); + break; + case VG_LITE_SET_MASK: + VG_LITE_RETURN_ERROR(vg_lite_draw(masklayer, path, fill_rule, matrix, VG_LITE_BLEND_NONE, color << 24)); + break; + case VG_LITE_UNION_MASK: + VG_LITE_RETURN_ERROR(vg_lite_draw(masklayer, path, fill_rule, matrix, VG_LITE_BLEND_SCREEN, color << 24)); + break; + case VG_LITE_INTERSECT_MASK: + VG_LITE_RETURN_ERROR(vg_lite_draw(masklayer, path, fill_rule, matrix, VG_LITE_BLEND_DST_IN, color << 24)); + break; + case VG_LITE_SUBTRACT_MASK: + VG_LITE_RETURN_ERROR(vg_lite_draw(masklayer, path, fill_rule, matrix, VG_LITE_BLEND_SUBTRACT, color << 24)); + break; + default: + break; + } + + return error; +#else + return VG_LITE_NOT_SUPPORT; +#endif +} + +vg_lite_error_t vg_lite_destroy_masklayer(vg_lite_buffer_t * masklayer) +{ +#if DUMP_API + FUNC_DUMP(vg_lite_destroy_masklayer)(masklayer); +#endif + +#if gcFEATURE_VG_MASK + vg_lite_error_t error = VG_LITE_SUCCESS; + +#if gcFEATURE_VG_TRACE_API + VGLITE_LOG("vg_lite_destroy_masklayer %p\n", masklayer); +#endif + + VG_LITE_RETURN_ERROR(vg_lite_free(masklayer)); + + return error; +#else + return VG_LITE_NOT_SUPPORT; +#endif +} + +vg_lite_error_t vg_lite_set_pixel_matrix(vg_lite_pixel_matrix_t matrix, vg_lite_pixel_channel_enable_t * channel) +{ +#if DUMP_API + FUNC_DUMP(vg_lite_set_pixel_matrix)(matrix, channel); +#endif + +#if gcFEATURE_VG_PIXEL_MATRIX + vg_lite_error_t error = VG_LITE_SUCCESS; + short pix_matrix[20] = { 0 }; + int i = 0; + +#if gcFEATURE_VG_TRACE_API + VGLITE_LOG("vg_lite_set_pixel_matrix %p (%d %d %d %d)\n", matrix, channel->enable_a, channel->enable_b, + channel->enable_g, channel->enable_r); +#endif + + s_context.matrix_enable = (channel->enable_a ? (1 << 17) : 0) | + (channel->enable_r ? (1 << 23) : 0) | + (channel->enable_g ? (1 << 22) : 0) | + (channel->enable_b ? (1 << 21) : 0); + + if(s_context.matrix_enable) { + for(i = 0; i < 20; i++) { + if(matrix[i] > 127.0f || matrix[i] < -128.0f) { + return VG_LITE_INVALID_ARGUMENT; + } + pix_matrix[i] = (short)(matrix[i] * 256); + VG_LITE_RETURN_ERROR(push_state(&s_context, 0x0ADE + i, pix_matrix[i])); + } + } + + return error; +#else + return VG_LITE_NOT_SUPPORT; +#endif +} + +vg_lite_error_t vg_lite_gaussian_filter(vg_lite_float_t w0, vg_lite_float_t w1, vg_lite_float_t w2) +{ +#if DUMP_API + FUNC_DUMP(vg_lite_gaussian_filter)(w0, w1, w2); +#endif + +#if gcFEATURE_VG_GAUSSIAN_BLUR + vg_lite_error_t error = VG_LITE_SUCCESS; + +#if gcFEATURE_VG_TRACE_API + VGLITE_LOG("vg_lite_gaussian_filter %f %f %f\n", w0, w1, w2); +#endif + + VG_LITE_RETURN_ERROR(push_state(&s_context, 0x0AD2 + 1, (uint32_t)(w0 * 256))); + VG_LITE_RETURN_ERROR(push_state(&s_context, 0x0AD4 + 1, (uint32_t)(w1 * 256))); + VG_LITE_RETURN_ERROR(push_state(&s_context, 0x0AD6 + 1, (uint32_t)(w2 * 256))); + + return error; +#else + return VG_LITE_NOT_SUPPORT; +#endif +} + +vg_lite_error_t vg_lite_scissor_rects(vg_lite_buffer_t * target, vg_lite_uint32_t nums, vg_lite_rectangle_t rect[]) +{ +#if DUMP_API + FUNC_DUMP(vg_lite_scissor_rects)(target, nums, rect); +#endif + +#if gcFEATURE_VG_MASK + vg_lite_error_t error = VG_LITE_SUCCESS; + vg_lite_rectangle_t rect_clamp, rect_draw; + vg_lite_int32_t left_x, right_x, left_len, middle_len, right_len, stride, j, max_x, max_y; + vg_lite_uint8_t alpha; + vg_lite_uint32_t i; +#if gcFEATURE_VG_TRACE_API + VGLITE_LOG("vg_lite_scissor_rects %d %p\n", nums, rect); + for(i = 0; i < nums; i++) { + VGLITE_LOG(" Rect(%d, %d, %d, %d)\n", rect[i].x, rect[i].y, rect[i].width, rect[i].height); + } +#endif + + /* Record scissor enable flag and disable scissor. */ + vg_lite_uint8_t enable = s_context.scissor_enable; + s_context.scissor_enable = 0; + + /* Free the old scissor layer if its size is too small for target */ + if(s_context.scissor_layer && + (s_context.scissor_layer->width < ((target->width + 7) / 8) || s_context.scissor_layer->height < target->height)) { + vg_lite_free(s_context.scissor_layer); + vg_lite_os_free(s_context.scissor_layer); + s_context.scissor_layer = NULL; + } + + /* Allocate if scissor layer is NULL */ + if(s_context.scissor_layer == NULL) { + s_context.scissor_layer = (vg_lite_buffer_t *)vg_lite_os_malloc(sizeof(vg_lite_buffer_t)); + if(!s_context.scissor_layer) { + return VG_LITE_OUT_OF_RESOURCES; + } + + memset(s_context.scissor_layer, 0, sizeof(vg_lite_buffer_t)); + s_context.scissor_layer->scissor_buffer = 1; + s_context.scissor_layer->width = (target->width + 7) / 8; + s_context.scissor_layer->height = target->height; + s_context.scissor_layer->format = VG_LITE_A8; + VG_LITE_RETURN_ERROR(vg_lite_allocate(s_context.scissor_layer)); + } + s_context.scissor_layer->scissor_buffer = 1; + + /* Clear scissor layer*/ + VG_LITE_RETURN_ERROR(vg_lite_clear(s_context.scissor_layer, NULL, 0x00000000)); + vg_lite_finish(); + + max_x = s_context.scissor_layer->width * 8; + max_y = s_context.scissor_layer->height; + + /* Draw rectangle to scissor layer, one bit data of scissor layer corresponds to one pixel. */ + for(i = 0; i < nums; ++i) { + /* Clamp the rect */ + memcpy(&rect_clamp, &rect[i], sizeof(vg_lite_rectangle_t)); + { + if(rect_clamp.x < 0 || rect_clamp.y < 0) { + rect_clamp.width += rect_clamp.x; + rect_clamp.height += rect_clamp.y; + rect_clamp.x = rect_clamp.y = 0; + } + if(rect_clamp.x >= max_x || rect_clamp.y >= max_y || rect_clamp.width <= 0 || rect_clamp.height <= 0) { + rect_clamp.x = rect_clamp.y = rect_clamp.width = rect_clamp.height = 0; + } + if(rect_clamp.x + rect_clamp.width > max_x) { + rect_clamp.width = max_x - rect_clamp.x; + } + if(rect_clamp.y + rect_clamp.height > max_y) { + rect_clamp.height = max_y - rect_clamp.y; + } + } + + if(((rect_clamp.x + rect_clamp.width) >> 3) == (rect_clamp.x >> 3)) { + rect_draw.x = rect_clamp.x / 8; + rect_draw.y = rect_clamp.y; + rect_draw.width = 1; + rect_draw.height = rect_clamp.height; + alpha = (uint8_t)(((uint8_t)(0xff >> (8 - rect_clamp.width))) << (rect_clamp.x % 8)); + stride = s_context.scissor_layer->stride; + for(j = rect_draw.y; j < rect_draw.height + rect_draw.y; ++j) { + ((vg_lite_uint8_t *)s_context.scissor_layer->memory)[j * stride + rect_draw.x] |= alpha; + } + } + else { + /* Split the rect */ + left_x = (rect_clamp.x % 8 == 0) ? rect_clamp.x : ((rect_clamp.x + 7) & 0xFFFFFFF8); + right_x = (rect_clamp.x + rect_clamp.width) & 0xFFFFFFF8; + middle_len = right_x - left_x; + left_len = left_x - rect_clamp.x; + right_len = rect_clamp.x + rect_clamp.width - right_x; + + /* Draw left rect */ + if(left_len) { + rect_draw.x = rect_clamp.x / 8; + rect_draw.y = rect_clamp.y; + rect_draw.width = 1; + rect_draw.height = rect_clamp.height; + alpha = (uint8_t)(0xff << (8 - left_len)); + stride = s_context.scissor_layer->stride; + for(j = rect_draw.y; j < rect_draw.height + rect_draw.y; ++j) { + ((vg_lite_uint8_t *)s_context.scissor_layer->memory)[j * stride + rect_draw.x] |= alpha; + } + } + + /* Draw middle rect */ + if(middle_len) { + rect_draw.x = left_x / 8; + rect_draw.y = rect_clamp.y; + rect_draw.width = middle_len / 8; + rect_draw.height = rect_clamp.height; + VG_LITE_RETURN_ERROR(vg_lite_clear(s_context.scissor_layer, &rect_draw, 0xFFFFFFFF)); + vg_lite_finish(); + } + + /* Draw right rect */ + if(right_len) { + rect_draw.x = (rect_clamp.x + rect_clamp.width - right_len) / 8; + rect_draw.y = rect_clamp.y; + rect_draw.width = 1; + rect_draw.height = rect_clamp.height; + alpha = (uint8_t)(0xff >> (8 - right_len)); + stride = s_context.scissor_layer->stride; + for(j = rect_draw.y; j < rect_draw.height + rect_draw.y; ++j) { + ((vg_lite_uint8_t *)s_context.scissor_layer->memory)[j * stride + rect_draw.x] |= alpha; + } + } + } + } + VG_LITE_RETURN_ERROR(push_state(&s_context, 0x0A16, s_context.scissor_layer->address)); + VG_LITE_RETURN_ERROR(push_state(&s_context, 0x0A17, s_context.scissor_layer->stride)); + VG_LITE_RETURN_ERROR(push_state(&s_context, 0x0A1B, 0x00000100)); + vg_lite_finish(); + s_context.scissor_enable = enable; + s_context.scissor_dirty = 1; + + return error; +#else + return VG_LITE_NOT_SUPPORT; +#endif +} + +vg_lite_error_t vg_lite_set_mirror(vg_lite_orientation_t orientation) +{ +#if DUMP_API + FUNC_DUMP(vg_lite_set_mirror)(orientation); +#endif + +#if gcFEATURE_VG_MIRROR + vg_lite_error_t error = VG_LITE_SUCCESS; + +#if gcFEATURE_VG_TRACE_API + VGLITE_LOG("vg_lite_set_mirror %d\n", orientation); +#endif + + s_context.mirror_orient = orientation; + s_context.mirror_dirty = 1; + + return error; +#else + return VG_LITE_NOT_SUPPORT; +#endif +} + +vg_lite_error_t vg_lite_set_gamma(vg_lite_gamma_conversion_t gamma_value) +{ +#if DUMP_API + FUNC_DUMP(vg_lite_set_gamma)(gamma_value); +#endif + +#if gcFEATURE_VG_GAMMA + vg_lite_error_t error = VG_LITE_SUCCESS; + +#if gcFEATURE_VG_TRACE_API + VGLITE_LOG("vg_lite_set_gamma %d\n", gamma_value); +#endif + + s_context.gamma_value = gamma_value << 12; + s_context.gamma_dirty = 1; + + return error; +#else + return VG_LITE_NOT_SUPPORT; +#endif +} + +/* Set s_context.gamma_value base on target buffer */ +vg_lite_void set_gamma_dest_only(vg_lite_buffer_t * target, vg_lite_int32_t stencil) +{ + uint32_t gamma_value = 0; + + /* Set gamma configuration of source buffer */ + /* Openvg paintcolor defaults to SRGB */ + s_context.gamma_src = 1; + + /* Set gamma configuration of dst buffer */ + if((target->format >= OPENVG_lRGBX_8888 && target->format <= OPENVG_A_4) || + (target->format >= OPENVG_lXRGB_8888 && target->format <= OPENVG_lARGB_8888_PRE) || + (target->format >= OPENVG_lBGRX_8888 && target->format <= OPENVG_lBGRA_8888_PRE) || + (target->format >= OPENVG_lXBGR_8888 && target->format <= OPENVG_lABGR_8888_PRE) || + (target->format >= OPENVG_lRGBX_8888_PRE && target->format <= OPENVG_lRGBA_4444_PRE)) { + s_context.gamma_dst = 0; + } + else { + s_context.gamma_dst = 1; + } + + if(s_context.gamma_src == 0 && s_context.gamma_dst == 1) { + gamma_value = 0x00002000; + } + else if(s_context.gamma_src == 1 && s_context.gamma_dst == 0) { + gamma_value = 0x00001000; + } + else { + gamma_value = 0x00000000; + } + + if(stencil && target->image_mode == VG_LITE_STENCIL_MODE) { + s_context.gamma_stencil = gamma_value; + gamma_value = 0x00000000; + } + + if(s_context.gamma_dirty == 0 && gamma_value != s_context.gamma_value) { + s_context.gamma_value = gamma_value; + s_context.gamma_dirty = 1; + } +} + +/* Set s_context.gamma_value base on source and target buffers */ +vg_lite_void get_st_gamma_src_dest(vg_lite_buffer_t * source, vg_lite_buffer_t * target) +{ + uint32_t gamma_value = 0; + + /* Set gamma configuration of source buffer */ + if((source->format >= OPENVG_lRGBX_8888 && source->format <= OPENVG_A_4) || + (source->format >= OPENVG_lXRGB_8888 && source->format <= OPENVG_lARGB_8888_PRE) || + (source->format >= OPENVG_lBGRX_8888 && source->format <= OPENVG_lBGRA_8888_PRE) || + (source->format >= OPENVG_lXBGR_8888 && source->format <= OPENVG_lABGR_8888_PRE) || + (source->format >= OPENVG_lRGBX_8888_PRE && source->format <= OPENVG_lRGBA_4444_PRE)) { + s_context.gamma_src = 0; + } + else { + s_context.gamma_src = 1; + } + /* Set gamma configuration of dst buffer */ + if((target->format >= OPENVG_lRGBX_8888 && target->format <= OPENVG_A_4) || + (target->format >= OPENVG_lXRGB_8888 && target->format <= OPENVG_lARGB_8888_PRE) || + (target->format >= OPENVG_lBGRX_8888 && target->format <= OPENVG_lBGRA_8888_PRE) || + (target->format >= OPENVG_lXBGR_8888 && target->format <= OPENVG_lABGR_8888_PRE) || + (target->format >= OPENVG_lRGBX_8888_PRE && target->format <= OPENVG_lRGBA_4444_PRE)) { + s_context.gamma_dst = 0; + } + else { + s_context.gamma_dst = 1; + } + + if(s_context.gamma_src == 0 && s_context.gamma_dst == 1) { + gamma_value = 0x00002000; + } + else if(s_context.gamma_src == 1 && s_context.gamma_dst == 0) { + gamma_value = 0x00001000; + } + else { + gamma_value = 0x00000000; + } + + if(source->image_mode == VG_LITE_STENCIL_MODE) { + if(source->paintType == VG_LITE_PAINT_PATTERN + || source->paintType == VG_LITE_PAINT_RADIAL_GRADIENT + || source->paintType == VG_LITE_PAINT_LINEAR_GRADIENT) { + gamma_value = s_context.gamma_stencil; + } + else if(source->paintType == VG_LITE_PAINT_COLOR && s_context.gamma_dst == 0) { + gamma_value = 0x00001000; + } + else { + gamma_value = 0x00000000; + } + } + + if(s_context.gamma_dirty == 0 && gamma_value != s_context.gamma_value) { + s_context.gamma_value = gamma_value; + s_context.gamma_dirty = 1; + } +} + +/* Set s_context.gamma_value base on source and target buffers */ +vg_lite_void save_st_gamma_src_dest(vg_lite_buffer_t * source, vg_lite_buffer_t * target) +{ + uint32_t gamma_value = 0; + + /* Set gamma configuration of source buffer */ + if((source->format >= OPENVG_lRGBX_8888 && source->format <= OPENVG_A_4) || + (source->format >= OPENVG_lXRGB_8888 && source->format <= OPENVG_lARGB_8888_PRE) || + (source->format >= OPENVG_lBGRX_8888 && source->format <= OPENVG_lBGRA_8888_PRE) || + (source->format >= OPENVG_lXBGR_8888 && source->format <= OPENVG_lABGR_8888_PRE) || + (source->format >= OPENVG_lRGBX_8888_PRE && source->format <= OPENVG_lRGBA_4444_PRE)) { + s_context.gamma_src = 0; + } + else { + s_context.gamma_src = 1; + } + /* Set gamma configuration of dst buffer */ + if((target->format >= OPENVG_lRGBX_8888 && target->format <= OPENVG_A_4) || + (target->format >= OPENVG_lXRGB_8888 && target->format <= OPENVG_lARGB_8888_PRE) || + (target->format >= OPENVG_lBGRX_8888 && target->format <= OPENVG_lBGRA_8888_PRE) || + (target->format >= OPENVG_lXBGR_8888 && target->format <= OPENVG_lABGR_8888_PRE) || + (target->format >= OPENVG_lRGBX_8888_PRE && target->format <= OPENVG_lRGBA_4444_PRE)) { + s_context.gamma_dst = 0; + } + else { + s_context.gamma_dst = 1; + } + + if(s_context.gamma_src == 0 && s_context.gamma_dst == 1) { + gamma_value = 0x00002000; + } + else if(s_context.gamma_src == 1 && s_context.gamma_dst == 0) { + gamma_value = 0x00001000; + } + else { + gamma_value = 0x00000000; + } + + if(target->image_mode == VG_LITE_STENCIL_MODE) { + s_context.gamma_stencil = gamma_value; + gamma_value = 0x00000000; + } + + if(s_context.gamma_dirty == 0 && gamma_value != s_context.gamma_value) { + s_context.gamma_value = gamma_value; + s_context.gamma_dirty = 1; + } +} + +vg_lite_error_t vg_lite_enable_color_transform() +{ +#if DUMP_API + FUNC_DUMP(vg_lite_enable_color_transform)(); +#endif + +#if gcFEATURE_VG_COLOR_TRANSFORMATION + vg_lite_error_t error = VG_LITE_SUCCESS; + +#if gcFEATURE_VG_TRACE_API + VGLITE_LOG("vg_lite_enable_color_transform\n"); +#endif + + s_context.color_transform = (1 << 16); + + return error; +#else + return VG_LITE_NOT_SUPPORT; +#endif +} + +vg_lite_error_t vg_lite_disable_color_transform() +{ +#if DUMP_API + FUNC_DUMP(vg_lite_disable_color_transform)(); +#endif + +#if gcFEATURE_VG_COLOR_TRANSFORMATION + vg_lite_error_t error = VG_LITE_SUCCESS; + +#if gcFEATURE_VG_TRACE_API + VGLITE_LOG("vg_lite_disable_color_transform\n"); +#endif + + s_context.color_transform = 0; + + return error; +#else + return VG_LITE_NOT_SUPPORT; +#endif +} + +vg_lite_error_t vg_lite_set_color_transform(vg_lite_color_transform_t * values) +{ +#if DUMP_API + FUNC_DUMP(vg_lite_enable_color_transform)(); +#endif + +#if gcFEATURE_VG_COLOR_TRANSFORMATION + vg_lite_error_t error = VG_LITE_SUCCESS; + vg_lite_float_t * color_transformations = (vg_lite_float_t *)values; + int color_elements = 0; + short temp_transform[8] = { 0 }; + uint32_t final_transform[8] = { 0 }; + +#if gcFEATURE_VG_TRACE_API + VGLITE_LOG("vg_lite_set_color_transform %p\n", values); +#endif + + for(color_elements = 0; color_elements < 8; color_elements++) { + if(color_elements % 2) { + color_transformations[color_elements] = CLAMP(color_transformations[color_elements], -1.0f, 1.0f); + } + else { + color_transformations[color_elements] = CLAMP(color_transformations[color_elements], -127.0f, 127.0f); + } + temp_transform[color_elements] = (short)(color_transformations[color_elements] * 256); + final_transform[color_elements] = (uint32_t)temp_transform[color_elements] & 0x0000FFFF; + } + + VG_LITE_RETURN_ERROR(push_state(&s_context, 0x0A0C, final_transform[2] | final_transform[3] << 16)); + VG_LITE_RETURN_ERROR(push_state(&s_context, 0x0A0D, final_transform[4] | final_transform[5] << 16)); + VG_LITE_RETURN_ERROR(push_state(&s_context, 0x0A0E, final_transform[6] | final_transform[7] << 16)); + VG_LITE_RETURN_ERROR(push_state(&s_context, 0x0A0F, final_transform[0] | final_transform[1] << 16)); + + return error; +#else + return VG_LITE_NOT_SUPPORT; +#endif +} + +#if !gcFEATURE_VG_LVGL_SUPPORT + +typedef struct { + float r; + float g; + float b; + float a; +} Color; + +int colorToInt(float c, int maxc) +{ + return MIN(MAX((int)floor(c * (float)maxc + 0.5f), 0), maxc); +} + +float intToColor(unsigned int i, unsigned int maxi) +{ + return (float)(i & maxi) / (float)maxi; +} + +Color readPixel(vg_lite_buffer_t * src, int x, int y) +{ + unsigned int p = 0; + Color c; + uint8_t * scanline = (uint8_t *)src->memory + y * src->stride; + + uint8_t bitsPerPixel = 0; + int rb = 0; + int gb = 0; + int bb = 0; + int ab = 0; + int rs = 0; + int gs = 0; + int bs = 0; + int as = 0; + switch(src->format) { + case VG_LITE_A8: + case VG_LITE_L8: + ab = 8; + bitsPerPixel = 8; + break; + case VG_LITE_ABGR4444: + rs = 12; + gs = 8; + bs = 4; + as = 0; + rb = 4; + gb = 4; + bb = 4; + ab = 4; + bitsPerPixel = 16; + break; + case VG_LITE_ARGB4444: + bs = 12; + gs = 8; + rs = 4; + as = 0; + rb = 4; + gb = 4; + bb = 4; + ab = 4; + bitsPerPixel = 16; + break; + case VG_LITE_RGBA4444: + as = 12; + bs = 8; + gs = 4; + rs = 0; + rb = 4; + gb = 4; + bb = 4; + ab = 4; + bitsPerPixel = 16; + break; + case VG_LITE_BGRA4444: + as = 12; + rs = 8; + gs = 4; + bs = 0; + rb = 4; + gb = 4; + bb = 4; + ab = 4; + bitsPerPixel = 16; + break; + case VG_LITE_RGB565: + rs = 0; + gs = 5; + bs = 11; + as = 0; + rb = 5; + gb = 6; + bb = 5; + ab = 0; + bitsPerPixel = 16; + break; + case VG_LITE_BGR565: + rs = 11; + gs = 5; + bs = 0; + as = 0; + rb = 5; + gb = 6; + bb = 5; + ab = 0; + bitsPerPixel = 16; + break; + case VG_LITE_ABGR8888: + case VG_LITE_XBGR8888: + rs = 24; + gs = 16; + bs = 8; + as = 0; + rb = 8; + gb = 8; + bb = 8; + ab = 8; + bitsPerPixel = 32; + break; + case VG_LITE_ARGB8888: + case VG_LITE_XRGB8888: + rs = 8; + gs = 16; + bs = 24; + as = 0; + rb = 8; + gb = 8; + bb = 8; + ab = 8; + bitsPerPixel = 32; + break; + case VG_LITE_RGBA8888: + case VG_LITE_RGBX8888: + rs = 0; + gs = 8; + bs = 16; + as = 24; + rb = 8; + gb = 8; + bb = 8; + ab = 8; + bitsPerPixel = 32; + break; + case VG_LITE_BGRA8888: + case VG_LITE_BGRX8888: + rs = 16; + gs = 8; + bs = 0; + as = 24; + rb = 8; + gb = 8; + bb = 8; + ab = 8; + bitsPerPixel = 32; + break; + case VG_LITE_ABGR1555: + rs = 11; + gs = 6; + bs = 1; + as = 0; + rb = 5; + gb = 5; + bb = 5; + ab = 1; + bitsPerPixel = 16; + break; + case VG_LITE_RGBA5551: + rs = 0; + gs = 5; + bs = 10; + as = 15; + rb = 5; + gb = 5; + bb = 5; + ab = 1; + bitsPerPixel = 16; + break; + case VG_LITE_ARGB1555: + rs = 1; + gs = 6; + bs = 11; + as = 0; + rb = 5; + gb = 5; + bb = 5; + ab = 1; + bitsPerPixel = 16; + break; + case VG_LITE_BGRA5551: + rs = 10; + gs = 5; + bs = 0; + as = 15; + rb = 5; + gb = 5; + bb = 5; + ab = 1; + bitsPerPixel = 16; + break; + case VG_LITE_BGRA2222: + rs = 4; + gs = 2; + bs = 0; + as = 6; + rb = 2; + gb = 2; + bb = 2; + ab = 2; + bitsPerPixel = 8; + break; + case VG_LITE_RGBA2222: + rs = 0; + gs = 2; + bs = 4; + as = 6; + rb = 2; + gb = 2; + bb = 2; + ab = 2; + bitsPerPixel = 8; + break; + case VG_LITE_ABGR2222: + rs = 6; + gs = 4; + bs = 2; + as = 0; + rb = 2; + gb = 2; + bb = 2; + ab = 2; + bitsPerPixel = 8; + break; + case VG_LITE_ARGB2222: + rs = 2; + gs = 4; + bs = 6; + as = 0; + rb = 2; + gb = 2; + bb = 2; + ab = 2; + bitsPerPixel = 8; + break; + default: + break; + } + + switch(bitsPerPixel) { + case 32: { + uint32_t * s = (((uint32_t *)scanline) + x); + p = (unsigned int) * s; + break; + } + + case 16: { + uint16_t * s = ((uint16_t *)scanline) + x; + p = (unsigned int) * s; + break; + } + + case 8: { + uint8_t * s = ((uint8_t *)scanline) + x; + p = (unsigned int) * s; + break; + } + case 4: { + uint8_t * s = ((uint8_t *)scanline) + (x >> 1); + p = (unsigned int)(*s >> ((x & 1) << 2)) & 0xf; + break; + } + case 2: { + uint8_t * s = ((uint8_t *)scanline) + (x >> 2); + p = (unsigned int)(*s >> ((x & 3) << 1)) & 0x3; + break; + } + default: { + uint8_t * s = ((uint8_t *)scanline) + (x >> 3); + p = (unsigned int)(*s >> (x & 7)) & 0x1; + break; + } + } + + //rgba + c.r = rb ? intToColor(p >> rs, (1 << rb) - 1) : (float)1.0f; + c.g = gb ? intToColor(p >> gs, (1 << gb) - 1) : (float)1.0f; + c.b = bb ? intToColor(p >> bs, (1 << bb) - 1) : (float)1.0f; + c.a = ab ? intToColor(p >> as, (1 << ab) - 1) : (float)1.0f; + + return c; +} + +void writePixel(vg_lite_buffer_t * temp, int x, int y, Color * c) +{ + uint8_t bitsPerPixel = 0; + int rb = 0; + int gb = 0; + int bb = 0; + int ab = 0; + int rs = 0; + int gs = 0; + int bs = 0; + int as = 0; + switch(temp->format) { + case VG_LITE_A8: + case VG_LITE_L8: + ab = 8; + bitsPerPixel = 8; + break; + case VG_LITE_ABGR4444: + rs = 12; + gs = 8; + bs = 4; + as = 0; + rb = 4; + gb = 4; + bb = 4; + ab = 4; + bitsPerPixel = 16; + break; + case VG_LITE_ARGB4444: + bs = 12; + gs = 8; + rs = 4; + as = 0; + rb = 4; + gb = 4; + bb = 4; + ab = 4; + bitsPerPixel = 16; + break; + case VG_LITE_RGBA4444: + as = 12; + bs = 8; + gs = 4; + rs = 0; + rb = 4; + gb = 4; + bb = 4; + ab = 4; + bitsPerPixel = 16; + break; + case VG_LITE_BGRA4444: + as = 12; + rs = 8; + gs = 4; + bs = 0; + rb = 4; + gb = 4; + bb = 4; + ab = 4; + bitsPerPixel = 16; + break; + case VG_LITE_RGB565: + rs = 0; + gs = 5; + bs = 11; + as = 0; + rb = 5; + gb = 6; + bb = 5; + ab = 0; + bitsPerPixel = 16; + break; + case VG_LITE_BGR565: + rs = 11; + gs = 5; + bs = 0; + as = 0; + rb = 5; + gb = 6; + bb = 5; + ab = 0; + bitsPerPixel = 16; + break; + case VG_LITE_ABGR8888: + case VG_LITE_XBGR8888: + rs = 24; + gs = 16; + bs = 8; + as = 0; + rb = 8; + gb = 8; + bb = 8; + ab = 8; + bitsPerPixel = 32; + break; + case VG_LITE_ARGB8888: + case VG_LITE_XRGB8888: + rs = 8; + gs = 16; + bs = 24; + as = 0; + rb = 8; + gb = 8; + bb = 8; + ab = 8; + bitsPerPixel = 32; + break; + case VG_LITE_RGBA8888: + case VG_LITE_RGBX8888: + rs = 0; + gs = 8; + bs = 16; + as = 24; + rb = 8; + gb = 8; + bb = 8; + ab = 8; + bitsPerPixel = 32; + break; + case VG_LITE_BGRA8888: + case VG_LITE_BGRX8888: + rs = 16; + gs = 8; + bs = 0; + as = 24; + rb = 8; + gb = 8; + bb = 8; + ab = 8; + bitsPerPixel = 32; + break; + case VG_LITE_ABGR1555: + rs = 11; + gs = 6; + bs = 1; + as = 0; + rb = 5; + gb = 5; + bb = 5; + ab = 1; + bitsPerPixel = 16; + break; + case VG_LITE_RGBA5551: + rs = 0; + gs = 5; + bs = 10; + as = 15; + rb = 5; + gb = 5; + bb = 5; + ab = 1; + bitsPerPixel = 16; + break; + case VG_LITE_ARGB1555: + rs = 1; + gs = 6; + bs = 11; + as = 0; + rb = 5; + gb = 5; + bb = 5; + ab = 1; + bitsPerPixel = 16; + break; + case VG_LITE_BGRA5551: + rs = 10; + gs = 5; + bs = 0; + as = 15; + rb = 5; + gb = 5; + bb = 5; + ab = 1; + bitsPerPixel = 16; + break; + case VG_LITE_BGRA2222: + rs = 4; + gs = 2; + bs = 0; + as = 6; + rb = 2; + gb = 2; + bb = 2; + ab = 2; + bitsPerPixel = 8; + break; + case VG_LITE_RGBA2222: + rs = 0; + gs = 2; + bs = 4; + as = 6; + rb = 2; + gb = 2; + bb = 2; + ab = 2; + bitsPerPixel = 8; + break; + case VG_LITE_ABGR2222: + rs = 6; + gs = 4; + bs = 2; + as = 0; + rb = 2; + gb = 2; + bb = 2; + ab = 2; + bitsPerPixel = 8; + break; + case VG_LITE_ARGB2222: + rs = 2; + gs = 4; + bs = 6; + as = 0; + rb = 2; + gb = 2; + bb = 2; + ab = 2; + bitsPerPixel = 8; + break; + default: + break; + } + + unsigned int cr = rb ? colorToInt(c->r, (1 << rb) - 1) : 0; + unsigned int cg = gb ? colorToInt(c->g, (1 << gb) - 1) : 0; + unsigned int cb = bb ? colorToInt(c->b, (1 << bb) - 1) : 0; + unsigned int ca = ab ? colorToInt(c->a, (1 << ab) - 1) : 0; + + unsigned int p = (cr << rs) | (cg << gs) | (cb << bs) | (ca << as); + char * scanline = (char *)temp->memory + y * temp->stride; + switch(bitsPerPixel) { + case 32: { + uint32_t * s = ((uint32_t *)scanline) + x; + *s = (uint32_t)p; + break; + } + + case 16: { + uint16_t * s = ((uint16_t *)scanline) + x; + *s = (uint16_t)p; + break; + } + + case 8: { + char * s = ((char *)scanline) + x; + *s = (char)p; + break; + } + case 4: { + char * s = ((char *)scanline) + (x >> 1); + *s = (char)((p << ((x & 1) << 2)) | ((unsigned int) * s & ~(0xf << ((x & 1) << 2)))); + break; + } + + case 2: { + char * s = ((char *)scanline) + (x >> 2); + *s = (char)((p << ((x & 3) << 1)) | ((unsigned int) * s & ~(0x3 << ((x & 3) << 1)))); + break; + } + + default: { + break; + } + } +} + +vg_lite_void setup_lvgl_image(vg_lite_buffer_t * dst, vg_lite_buffer_t * src, vg_lite_buffer_t * lvgl_buf, + vg_lite_blend_t operation) +{ + Color c_src, c_dst, c_temp; + /* copy source region to tmp dst */ + for(int j = 0; j < src->height; j++) { + for(int i = 0; i < src->width; i++) { + c_src = readPixel(src, i, j); + c_dst = readPixel(dst, i, j); + + switch(operation) { + case VG_LITE_BLEND_NORMAL_LVGL: + c_temp.a = c_src.a; + c_temp.r = c_src.a * c_src.r; + c_temp.g = c_src.a * c_src.g; + c_temp.b = c_src.a * c_src.b; + break; + case VG_LITE_BLEND_ADDITIVE_LVGL: + c_temp.a = c_src.a; + c_temp.r = (c_src.r + c_dst.r) * c_src.a; + c_temp.g = (c_src.g + c_dst.g) * c_src.a; + c_temp.b = (c_src.b + c_dst.b) * c_src.a; + break; + case VG_LITE_BLEND_SUBTRACT_LVGL: + c_temp.a = c_src.a; + c_temp.r = c_src.r < c_dst.r ? (c_dst.r - c_src.r) * c_src.a : 0; + c_temp.g = c_src.g < c_dst.g ? (c_dst.g - c_src.g) * c_src.a : 0; + c_temp.b = c_src.b < c_dst.b ? (c_dst.b - c_src.b) * c_src.a : 0; + break; + case VG_LITE_BLEND_MULTIPLY_LVGL: + c_temp.a = c_src.a; + c_temp.r = c_src.r * c_dst.r * c_src.a; + c_temp.g = c_src.g * c_dst.g * c_src.a; + c_temp.b = c_src.b * c_dst.b * c_src.a; + break; + default: + break; + } + if(lvgl_buf) { + writePixel(lvgl_buf, i, j, &c_temp); + } +#if !gcFEATURE_VG_GLOBAL_ALPHA + c_dst.a = 1.0; + writePixel(dst, i, j, &c_dst); +#endif + } + } + return; +} + +#endif /* !gcFEATURE_VG_LVGL_SUPPORT */ + +/****************** FLEXA Support ***************/ + +vg_lite_error_t vg_lite_flexa_enable() +{ +#if DUMP_API + FUNC_DUMP(vg_lite_flexa_enable)(); +#endif + +#if gcFEATURE_VG_FLEXA + vg_lite_error_t error = VG_LITE_SUCCESS; + vg_lite_kernel_info_t data; + uint32_t reset_bit; + vg_lite_kernel_flexa_info_t flexa_data; + +#if gcFEATURE_VG_TRACE_API + VGLITE_LOG("vg_lite_flexa_enable\n"); +#endif + + flexa_data.sbi_mode = s_context.sbi_mode = 0x1; + flexa_data.sync_mode = s_context.sync_mode = BIT(14); + flexa_data.flexa_mode = s_context.flexa_mode = 0x1; + flexa_data.segment_address = s_context.segment_address; + flexa_data.segment_count = s_context.segment_count; + flexa_data.segment_size = s_context.segment_size; + flexa_data.stream_id = s_context.stream_id; + flexa_data.start_flag = s_context.start_flag = BIT(9); + flexa_data.stop_flag = s_context.stop_flag = BIT(11); + flexa_data.reset_flag = s_context.reset_flag = BIT(10); + /* set sync mode */ + VG_LITE_RETURN_ERROR(vg_lite_kernel(VG_LITE_FLEXA_ENABLE, &flexa_data)); + + /* check if reset is complete */ + data.addr = 0x03600; + VG_LITE_RETURN_ERROR(vg_lite_kernel(VG_LITE_CHECK, &data)); + reset_bit = data.reg; + + if(reset_bit == 1) { + error = VG_LITE_TIMEOUT; + return error; + } + s_context.flexa_dirty = 1; + + return error; +#else + return VG_LITE_NOT_SUPPORT; +#endif +} + +vg_lite_error_t vg_lite_flexa_set_stream(vg_lite_uint8_t stream_id) +{ +#if DUMP_API + FUNC_DUMP(vg_lite_flexa_set_stream)(stream_id); +#endif + +#if gcFEATURE_VG_FLEXA + vg_lite_error_t error = VG_LITE_SUCCESS; + +#if gcFEATURE_VG_TRACE_API + VGLITE_LOG("vg_lite_flexa_set_stream %d\n", stream_id); +#endif + + s_context.stream_id = stream_id << 1; + + return error; +#else + return VG_LITE_NOT_SUPPORT; +#endif +} + +vg_lite_error_t vg_lite_flexa_bg_buffer(vg_lite_uint8_t stream_id, vg_lite_buffer_t * buffer, + vg_lite_uint32_t bg_seg_count, vg_lite_uint32_t bg_seg_size) +{ +#if DUMP_API + FUNC_DUMP(vg_lite_flexa_bg_buffer)(stream_id, buffer, bg_seg_count, bg_seg_size); +#endif + +#if gcFEATURE_VG_FLEXA + vg_lite_error_t error = VG_LITE_SUCCESS; + vg_lite_kernel_flexa_info_t flexa_data; + +#if gcFEATURE_VG_TRACE_API + VGLITE_LOG("vg_lite_flexa_bg_buffer %d %p %d %d\n", stream_id, buffer, bg_seg_count, bg_seg_size); +#endif + + flexa_data.sbi_mode = s_context.sbi_mode; + flexa_data.segment_address = s_context.segment_address = buffer->address; + flexa_data.segment_count = s_context.segment_count = bg_seg_count; + flexa_data.segment_size = s_context.segment_size = bg_seg_size; + flexa_data.stream_id = s_context.stream_id; + flexa_data.start_flag = s_context.start_flag; + flexa_data.stop_flag = s_context.stop_flag; + flexa_data.reset_flag = s_context.reset_flag; + VG_LITE_RETURN_ERROR(vg_lite_kernel(VG_LITE_FLEXA_SET_BACKGROUND_ADDRESS, &flexa_data)); + + return error; +#else + return VG_LITE_NOT_SUPPORT; +#endif +} + +vg_lite_error_t vg_lite_flexa_stop_frame() +{ +#if DUMP_API + FUNC_DUMP(vg_lite_flexa_stop_frame)(); +#endif + +#if gcFEATURE_VG_FLEXA + vg_lite_error_t error = VG_LITE_SUCCESS; + vg_lite_kernel_flexa_info_t flexa_data; + +#if gcFEATURE_VG_TRACE_API + VGLITE_LOG("vg_lite_flexa_stop_frame\n"); +#endif + + flexa_data.stop_flag = s_context.stop_flag = BIT(11); + flexa_data.stream_id = s_context.stream_id; + flexa_data.sbi_mode = s_context.sbi_mode; + VG_LITE_RETURN_ERROR(vg_lite_kernel(VG_LITE_FLEXA_STOP_FRAME, &flexa_data)); + + return error; +#else + return VG_LITE_NOT_SUPPORT; +#endif +} + +vg_lite_error_t vg_lite_flexa_disable() +{ +#if DUMP_API + FUNC_DUMP(vg_lite_flexa_disable)(); +#endif + +#if gcFEATURE_VG_FLEXA + vg_lite_error_t error = VG_LITE_SUCCESS; + vg_lite_kernel_flexa_info_t flexa_data; + vg_lite_kernel_info_t data; + uint32_t reset_bit; + +#if gcFEATURE_VG_TRACE_API + VGLITE_LOG("vg_lite_flexa_disable\n"); +#endif + + flexa_data.flexa_mode = s_context.flexa_mode = 0x0; + flexa_data.sync_mode = s_context.sync_mode = BIT(2); + flexa_data.stream_id = s_context.stream_id = 0; + flexa_data.sbi_mode = s_context.sbi_mode = 0x0; + flexa_data.start_flag = s_context.start_flag = 0x0; + flexa_data.stop_flag = s_context.stop_flag = 0x0; + flexa_data.reset_flag = s_context.reset_flag = 0x0; + VG_LITE_RETURN_ERROR(vg_lite_kernel(VG_LITE_FLEXA_DISABLE, &flexa_data)); + + /* check if reset is complete */ + data.addr = 0x03600; + VG_LITE_RETURN_ERROR(vg_lite_kernel(VG_LITE_CHECK, &data)); + reset_bit = data.reg; + if(reset_bit == 1) { + error = VG_LITE_TIMEOUT; + return error; + } + s_context.flexa_dirty = 1; + + return error; +#else + return VG_LITE_NOT_SUPPORT; +#endif +} + +/****************** FAST_CLEAR implementation. ***************/ +#if gcFEATURE_VG_IM_FASTCLEAR +static vg_lite_error_t _free_fc_buffer(vg_lite_fc_buffer_t * buffer) +{ + vg_lite_error_t error; + vg_lite_kernel_free_t free; + + if(buffer == NULL) + return VG_LITE_INVALID_ARGUMENT; + + /* Make sure we have a valid memory handle. */ + if(buffer->handle) { + /* Free the buffer. */ + free.memory_handle = buffer->handle; + VG_LITE_RETURN_ERROR(vg_lite_kernel(VG_LITE_FREE, &free)); + + /* Mark the buffer as freed. */ + buffer->handle = NULL; + buffer->memory = NULL; + } + + return VG_LITE_SUCCESS; +} +static vg_lite_error_t convert_color(vg_lite_buffer_format_t format, uint32_t value, uint32_t * result, int * bpp) +{ + vg_lite_error_t error = VG_LITE_SUCCESS; + uint32_t r, g, b, a; + int Bpp = 0; + + r = B(value); + g = G(value); + b = R(value); + a = A(value); + + do { + switch(format) { + case VG_LITE_RGBA8888: + *result = ARGB(a, b, g, r); + Bpp = 32; + break; + + case VG_LITE_BGRA8888: + *result = ARGB(a, r, g, b); + Bpp = 32; + break; + + case VG_LITE_RGBX8888: + *result = ARGB(0xff, b, g, r); + Bpp = 32; + break; + + case VG_LITE_BGRX8888: + *result = ARGB(0xff, r, g, b); + Bpp = 32; + break; + + + case VG_LITE_RGBA4444: + *result = ARGB4(a, b, g, r); + Bpp = 16; + break; + + case VG_LITE_BGRA4444: + *result = ARGB4(a, r, g, b); + Bpp = 16; + break; + + case VG_LITE_RGB565: + *result = ((b & 0xf8) << 8) | + ((g & 0xfc) << 3) | + ((r & 0xf8) >> 3); + Bpp = 16; + break; + + case VG_LITE_BGR565: + *result = ((r & 0xf8) << 8) | + ((g & 0xfc) << 3) | + ((b & 0xf8) >> 3); + Bpp = 16; + break; + + case VG_LITE_BGRA5551: + *result = ((b & 0xf8) << 8) | + ((g & 0xf8) << 3) | + ((r & 0xf8) >> 2) | + ((a & 0x80) >> 7); + Bpp = 16; + break; + + case VG_LITE_A8: + *result = ARGB(a, a, a, a); + Bpp = 8; + break; + + case VG_LITE_L8: + *result = ARGB(r, r, r, r); + Bpp = 8; + break; + + default: + error = VG_LITE_NOT_SUPPORT; + break; + } + } while(0); + + if(bpp != NULL) { + *bpp = Bpp; + } + + if(Bpp == 16) { + *result = ((*result) << 16) | (*result); + } + return error; +} + +/* Fill Target buffer by FC buffer. Only used in cmodel/fpga for verification. */ +#if defined(DEBUG) || defined(_DEBUG) +static vg_lite_error_t fill_fc_target(vg_lite_buffer_t * target, vg_lite_buffer_t * fcb) +{ + vg_lite_error_t error = VG_LITE_SUCCESS; + uint8_t * fc = (uint8_t *)fcb->memory; + uint16_t * target16; + uint32_t * target32; + uint8_t * target8; + uint32_t clear32; + int byte_done = 0; + int i, j, k; + int bpp; + + do { + convert_color(target->format, target->fc_buffer[0].color, &clear32, &bpp); + + if(bpp == 32) { + target32 = (uint32_t *)target->memory; + for(i = 0; i < fcb->width; i++) { + + for(j = 0; j < 8; j++) { /* Loop the bits*/ + + if(!(((*fc) >> j) & 1)) { + for(k = 0; k < 64 / 4; k++) { + target32[k] = clear32; + byte_done += 4; + if(byte_done >= target->stride * target->height) { + return error; + } + } + } + + target32 += 64 / 4; + } + + fc++; + } + } + else if(bpp == 16) { + target16 = (uint16_t *)target->memory; + for(i = 0; i < fcb->width; i++) { + + for(j = 0; j < 8; j++) { /* Loop the bits*/ + + if(!(((*fc) >> j) & 1)) { + for(k = 0; k < 64 / 2; k++) { + target16[k] = (uint16_t)clear32; + byte_done += 2; + if(byte_done >= target->stride * target->height) { + return error; + } + } + } + + target16 += 64 / 2; + } + + fc++; + } + } + else if(bpp == 8) { + target8 = (uint8_t *)target->memory; + for(i = 0; i < fcb->width; i++) { + + for(j = 0; j < 8; j++) { /* Loop the bits*/ + + if(!(((*fc) >> j) & 1)) { + for(k = 0; k < 64; k++) { + target8[k] = (uint8_t)clear32; + byte_done++; + if(byte_done >= target->stride * target->height) { + return error; + } + } + } + + target8 += 64; + } + + fc++; + } + } + } while(0); + + return error; +} +#endif + +/* Update the fast_clear buffer when render target switched. */ +static vg_lite_error_t update_fc_buffer(vg_lite_buffer_t * target) +{ + int rt_bytes; + vg_lite_error_t error = VG_LITE_SUCCESS; + vg_lite_context_t * context = GET_CONTEXT(); + vg_lite_kernel_allocate_t allocate; + + do { + if(target == NULL) { + error = VG_LITE_INVALID_ARGUMENT; + break; + } + + rt_bytes = target->stride * target->height; + rt_bytes = VG_LITE_ALIGN(rt_bytes, (FC_BIT_TO_BYTES * 2)); + rt_bytes = rt_bytes / FC_BIT_TO_BYTES / 2; + /* Only allocate new buffer when the allocated is not big enough. Yes*/ + if(rt_bytes > target->fc_buffer[0].stride) { + _free_fc_buffer(&target->fc_buffer[0]); + + target->fc_buffer[0].width = rt_bytes; /* The actually used bytes. */ + rt_bytes = VG_LITE_ALIGN(rt_bytes, FC_BURST_BYTES); /* The allocated aligned bytes. */ + target->fc_buffer[0].stride = rt_bytes; + target->fc_buffer[0].height = 1; + allocate.bytes = rt_bytes; + allocate.contiguous = 1; + + VG_LITE_BREAK_ERROR(vg_lite_kernel(VG_LITE_ALLOCATE, &allocate)); + target->fc_buffer[0].handle = allocate.memory_handle; + target->fc_buffer[0].memory = allocate.memory; + target->fc_buffer[0].address = allocate.memory_gpu; + } + else { + /* Just update the fc buffer size. */ + target->fc_buffer[0].width = rt_bytes; + } + memset(target->fc_buffer[0].memory, 0xff, target->fc_buffer[0].stride); + VG_LITE_RETURN_ERROR(push_state(context, 0x0A9A, target->fc_buffer[0].address)); /* FC buffer address. */ + } while(0); + + return error; +} + +/* Update FC registers and clear FC buffer. */ +static vg_lite_error_t clear_fc(vg_lite_fc_buffer_t * buffer, uint32_t value) +{ + vg_lite_error_t error = VG_LITE_SUCCESS; + vg_lite_context_t * context = GET_CONTEXT(); + uint32_t bytes_to_clear; + + if(buffer == NULL) + return VG_LITE_INVALID_ARGUMENT; + bytes_to_clear = buffer->stride / FC_BURST_BYTES; + buffer->color = value; + + do { + VG_LITE_BREAK_ERROR(push_state(context, 0x0A9B, value)); /* FC clear value. */ + VG_LITE_BREAK_ERROR(push_state(context, 0x0AB0, 0x80000000 | bytes_to_clear)); /* FC clear command. */ + } while(0); + + return error; +} + +#if VG_TARGET_FC_DUMP +static int fc_buf_dump(vg_lite_buffer_t * target, vg_lite_buffer_t * fcb) +{ + int error = VG_LITE_SUCCESS; + uint8_t * fc = (uint8_t *)fcb->memory; + uint8_t * target8; + int byte_done = 0; + int target_bytes; + int i, j; + + static unsigned s_cnt; + unsigned cnt = s_cnt; + + FILE * fpFCBuf; + FILE * fpTargetBuf; + FILE * fpTargetBufInfo; + char buf[256]; + + s_cnt++; + + sprintf(buf, "gc555.fc_buf.f%04d.txt", cnt); + fpFCBuf = fopen(buf, "wt"); + if(NULL == fpFCBuf) { + fprintf(stderr, "[Warning] Open file \'%s\' fail.\n", buf); + return -1; + } + + sprintf(buf, "gc555.target_buf_info.f%04d.txt", cnt); + fpTargetBufInfo = fopen(buf, "wt"); + if(NULL == fpTargetBufInfo) { + fprintf(stderr, "[Warning] Open file \'%s\' fail.\n", buf); + fclose(fpFCBuf); + return -1; + } + else { + fprintf(fpTargetBufInfo, "%-12s: %d\n", "format", target->format); + fprintf(fpTargetBufInfo, "%-12s: %d\n", "tiled", target->tiled); + fprintf(fpTargetBufInfo, "%-12s: %d\n", "width", target->width); + fprintf(fpTargetBufInfo, "%-12s: %d\n", "height", target->height); + fprintf(fpTargetBufInfo, "%-12s: %d\n", "stride", target->stride); + + fclose(fpTargetBufInfo); + } + + sprintf(buf, "gc555.target_buf.f%04d.txt", cnt); + fpTargetBuf = fopen(buf, "wt"); + if(NULL == fpTargetBuf) { + fprintf(stderr, "[Warning] Open file \'%s\' fail.\n", buf); + fclose(fpFCBuf); + return -1; + } + + /* Dump FC buffer & Dump target buffer */ + target8 = (uint8_t *)target->memory; + target_bytes = target->stride * target->height; + + for(i = 0; i < fcb->width; ++i) { + fprintf(fpFCBuf, "%02x\n", fc[i]); + /* 1 byte of fc related with 512 bytes of target buffer */ + for(j = 0; j < 128; ++j) { + fprintf(fpTargetBuf, "%02x", byte_done < target_bytes ? target8[0] : 0); + byte_done++; + + fprintf(fpTargetBuf, "%02x", byte_done < target_bytes ? target8[1] : 0); + byte_done++; + + fprintf(fpTargetBuf, "%02x", byte_done < target_bytes ? target8[2] : 0); + byte_done++; + + fprintf(fpTargetBuf, "%02x\n", byte_done < target_bytes ? target8[3] : 0); + byte_done++; + + target8 += 4; + } + } + + fclose(fpFCBuf); + fclose(fpTargetBuf); + + return error; +} +#endif /* VG_TARGET_FC_DUMP */ +#endif /* gcFEATURE_VG_IM_FASTCLEAR */ + +#endif /* LV_USE_VG_LITE_DRIVER */ + diff --git a/src/libs/vg_lite_driver/VGLite/vg_lite_matrix.c b/src/libs/vg_lite_driver/VGLite/vg_lite_matrix.c new file mode 100755 index 0000000000..7858566387 --- /dev/null +++ b/src/libs/vg_lite_driver/VGLite/vg_lite_matrix.c @@ -0,0 +1,167 @@ +/**************************************************************************** +* +* Copyright 2012 - 2023 Vivante Corporation, Santa Clara, California. +* All Rights Reserved. +* +* Permission is hereby granted, free of charge, to any person obtaining +* a copy of this software and associated documentation files (the +* 'Software'), to deal in the Software without restriction, including +* without limitation the rights to use, copy, modify, merge, publish, +* distribute, sub license, and/or sell copies of the Software, and to +* permit persons to whom the Software is furnished to do so, subject +* to the following conditions: +* +* The above copyright notice and this permission notice (including the +* next paragraph) shall be included in all copies or substantial +* portions of the Software. +* +* THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND, +* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. +* IN NO EVENT SHALL VIVANTE AND/OR ITS SUPPLIERS BE LIABLE FOR ANY +* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, +* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE +* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +* +*****************************************************************************/ + +#include "../../../lv_conf_internal.h" +#if LV_USE_VG_LITE_DRIVER + +#include +#include +#include "vg_lite_context.h" + + +vg_lite_error_t vg_lite_identity(vg_lite_matrix_t * matrix) +{ +#if gcFEATURE_VG_TRACE_API + VGLITE_LOG("vg_lite_identity %p\n", matrix); +#endif + + /* Set identify matrix. */ + matrix->m[0][0] = 1.0f; + matrix->m[0][1] = 0.0f; + matrix->m[0][2] = 0.0f; + matrix->m[1][0] = 0.0f; + matrix->m[1][1] = 1.0f; + matrix->m[1][2] = 0.0f; + matrix->m[2][0] = 0.0f; + matrix->m[2][1] = 0.0f; + matrix->m[2][2] = 1.0f; + + matrix->scaleX = 1.0f; + matrix->scaleY = 1.0f; + matrix->angle = 0.0f; + + return VG_LITE_SUCCESS; +} + +static void multiply(vg_lite_matrix_t * matrix, vg_lite_matrix_t * mult) +{ + vg_lite_matrix_t temp; + int row, column; + + /* Process all rows. */ + for(row = 0; row < 3; row++) { + /* Process all columns. */ + for(column = 0; column < 3; column++) { + /* Compute matrix entry. */ + temp.m[row][column] = (matrix->m[row][0] * mult->m[0][column]) + + (matrix->m[row][1] * mult->m[1][column]) + + (matrix->m[row][2] * mult->m[2][column]); + } + } + + /* Copy temporary matrix into result. */ + memcpy(matrix, &temp, sizeof(vg_lite_float_t) * 9); +} + +vg_lite_error_t vg_lite_translate(vg_lite_float_t x, vg_lite_float_t y, vg_lite_matrix_t * matrix) +{ +#if gcFEATURE_VG_TRACE_API + VGLITE_LOG("vg_lite_translate %f %f %p\n", x, y, matrix); +#endif + + /* Set translation matrix. */ + vg_lite_matrix_t t = { + { + { 1.0f, 0.0f, x }, + { 0.0f, 1.0f, y }, + { 0.0f, 0.0f, 1.0f } + }, + 1.0f, 1.0f, 0.0f + }; + + /* Multiply with current matrix. */ + multiply(matrix, &t); + + return VG_LITE_SUCCESS; +} + +vg_lite_error_t vg_lite_scale(vg_lite_float_t scale_x, vg_lite_float_t scale_y, vg_lite_matrix_t * matrix) +{ +#if gcFEATURE_VG_TRACE_API + VGLITE_LOG("vg_lite_scale %f %f %p\n", scale_x, scale_y, matrix); +#endif + + /* Set scale matrix. */ + vg_lite_matrix_t s = { + { + { scale_x, 0.0f, 0.0f }, + { 0.0f, scale_y, 0.0f }, + { 0.0f, 0.0f, 1.0f } + }, + 1.0f, 1.0f, 0.0f + }; + + /* Multiply with current matrix. */ + multiply(matrix, &s); + +#if VG_SW_BLIT_PRECISION_OPT + matrix->scaleX = matrix->scaleX * scale_x; + matrix->scaleY = matrix->scaleY * scale_y; +#endif /* VG_SW_BLIT_PRECISION_OPT */ + + return VG_LITE_SUCCESS; +} + +vg_lite_error_t vg_lite_rotate(vg_lite_float_t degrees, vg_lite_matrix_t * matrix) +{ +#if gcFEATURE_VG_TRACE_API + VGLITE_LOG("vg_lite_rotate %f %p\n", degrees, matrix); +#endif + + /* Convert degrees into radians. */ + vg_lite_float_t angle = (degrees / 180.0f) * 3.141592654f; + + /* Compuet cosine and sine values. */ + vg_lite_float_t cos_angle = cosf(angle); + vg_lite_float_t sin_angle = sinf(angle); + + /* Set rotation matrix. */ + vg_lite_matrix_t r = { + { + { cos_angle, -sin_angle, 0.0f }, + { sin_angle, cos_angle, 0.0f }, + { 0.0f, 0.0f, 1.0f } + }, + 1.0f, 1.0f, 0.0f + }; + + /* Multiply with current matrix. */ + multiply(matrix, &r); + +#if VG_SW_BLIT_PRECISION_OPT + matrix->angle = matrix->angle + degrees; + if(matrix->angle >= 360) { + vg_lite_uint32_t count = (vg_lite_uint32_t)matrix->angle / 360; + matrix->angle = matrix->angle - count * 360; + } +#endif /* VG_SW_BLIT_PRECISION_OPT */ + + return VG_LITE_SUCCESS; +} + +#endif /* LV_USE_VG_LITE_DRIVER */ + diff --git a/src/libs/vg_lite_driver/VGLite/vg_lite_options.h b/src/libs/vg_lite_driver/VGLite/vg_lite_options.h new file mode 100755 index 0000000000..6ee997d7ee --- /dev/null +++ b/src/libs/vg_lite_driver/VGLite/vg_lite_options.h @@ -0,0 +1,40 @@ +/**************************************************************************** +* +* Copyright 2012 - 2023 Vivante Corporation, Santa Clara, California. +* All Rights Reserved. +* +* Permission is hereby granted, free of charge, to any person obtaining +* a copy of this software and associated documentation files (the +* 'Software'), to deal in the Software without restriction, including +* without limitation the rights to use, copy, modify, merge, publish, +* distribute, sub license, and/or sell copies of the Software, and to +* permit persons to whom the Software is furnished to do so, subject +* to the following conditions: +* +* The above copyright notice and this permission notice (including the +* next paragraph) shall be included in all copies or substantial +* portions of the Software. +* +* THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND, +* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. +* IN NO EVENT SHALL VIVANTE AND/OR ITS SUPPLIERS BE LIABLE FOR ANY +* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, +* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE +* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +* +*****************************************************************************/ + +#ifndef VG_LITE_OPTIONS_DISPATCH_H +#define VG_LITE_OPTIONS_DISPATCH_H + +#include "../../../lv_conf_internal.h" +#if LV_USE_VG_LITE_DRIVER + + #define VG_LITE_OPTIONS VG_LITE_OPTIONS_2 + #define VG_LITE_OPTIONS_2 <../VGLite/Series/LV_VG_LITE_HAL_GPU_SERIES/LV_VG_LITE_HAL_GPU_REVISION/vg_lite_options.h> + #include VG_LITE_OPTIONS + +#endif /* LV_USE_VG_LITE_DRIVER */ + +#endif /* VG_LITE_OPTIONS_DISPATCH_H */ diff --git a/src/libs/vg_lite_driver/VGLite/vg_lite_path.c b/src/libs/vg_lite_driver/VGLite/vg_lite_path.c new file mode 100755 index 0000000000..e7dfaf9fcb --- /dev/null +++ b/src/libs/vg_lite_driver/VGLite/vg_lite_path.c @@ -0,0 +1,5495 @@ +/**************************************************************************** +* +* Copyright 2012 - 2023 Vivante Corporation, Santa Clara, California. +* All Rights Reserved. +* +* Permission is hereby granted, free of charge, to any person obtaining +* a copy of this software and associated documentation files (the +* 'Software'), to deal in the Software without restriction, including +* without limitation the rights to use, copy, modify, merge, publish, +* distribute, sub license, and/or sell copies of the Software, and to +* permit persons to whom the Software is furnished to do so, subject +* to the following conditions: +* +* The above copyright notice and this permission notice (including the +* next paragraph) shall be included in all copies or substantial +* portions of the Software. +* +* THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND, +* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. +* IN NO EVENT SHALL VIVANTE AND/OR ITS SUPPLIERS BE LIABLE FOR ANY +* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, +* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE +* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +* +*****************************************************************************/ + +#include "../../../lv_conf_internal.h" +#if LV_USE_VG_LITE_DRIVER + +#include "vg_lite_context.h" + +/* Path data operations. */ +#define CDALIGN(value, by) (((value) + (by) - 1) & ~((by) - 1)) +#define CDMIN(x, y) ((x) > (y) ? (y) : (x)) +#define CDMAX(x, y) ((x) > (y) ? (x) : (y)) + + +extern uint32_t transform(vg_lite_point_t * result, vg_lite_float_t x, vg_lite_float_t y, vg_lite_matrix_t * matrix); +extern uint32_t convert_blend(vg_lite_blend_t blend); +extern uint32_t inverse(vg_lite_matrix_t * result, vg_lite_matrix_t * matrix); +extern uint32_t convert_yuv2rgb(vg_lite_yuv2rgb_t yuv); +extern uint32_t convert_uv_swizzle(vg_lite_swizzle_t swizzle); +extern uint32_t convert_source_format(vg_lite_buffer_format_t format); +extern vg_lite_error_t check_compress(vg_lite_buffer_format_t format, vg_lite_compress_mode_t compress_mode, + vg_lite_buffer_layout_t tiled, uint32_t width, uint32_t height); +extern void get_format_bytes(vg_lite_buffer_format_t format, uint32_t * mul, uint32_t * div, uint32_t * bytes_align); +extern vg_lite_error_t srcbuf_align_check(vg_lite_buffer_t * source); + +extern vg_lite_matrix_t identity_mtx; + +/* Convert VGLite data format to HW value. */ +static uint32_t convert_path_format(vg_lite_format_t format) +{ + switch(format) { + case VG_LITE_S8: + return 0; + + case VG_LITE_S16: + return 0x100000; + + case VG_LITE_S32: + return 0x200000; + + case VG_LITE_FP32: + return 0x300000; + + default: + return 0; + } +} + +/* Convert VGLite quality enums to HW values. */ +static uint32_t convert_path_quality(vg_lite_quality_t quality) +{ + switch(quality) { + case VG_LITE_HIGH: + return 0x3; + + case VG_LITE_UPPER: + return 0x2; + + case VG_LITE_MEDIUM: + return 0x1; + + default: + return 0x0; + } +} + +static int32_t get_data_count(uint8_t cmd) +{ + static int32_t count[] = { + 0, + 0, + 2, + 2, + 2, + 2, + 4, + 4, + 6, + 6, + 0, + 1, + 1, + 1, + 1, + 2, + 2, + 4, + 4, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5 + }; + + if(cmd > VLC_OP_LCWARC_REL) { + return -1; + } + else { + return count[cmd]; + } +} + +static void compute_pathbounds(float * xmin, float * ymin, float * xmax, float * ymax, float x, float y) +{ + if(xmin != NULL) { + *xmin = *xmin < x ? *xmin : x; + } + + if(xmax != NULL) { + *xmax = *xmax > x ? *xmax : x; + } + + if(ymin != NULL) { + *ymin = *ymin < y ? *ymin : y; + } + + if(ymax != NULL) { + *ymax = *ymax > y ? *ymax : y; + } +} + +int32_t get_data_size(vg_lite_format_t format) +{ + int32_t data_size = 0; + + switch(format) { + case VG_LITE_S8: + data_size = sizeof(int8_t); + break; + + case VG_LITE_S16: + data_size = sizeof(int16_t); + break; + + case VG_LITE_S32: + data_size = sizeof(int32_t); + break; + + default: + data_size = sizeof(vg_lite_float_t); + break; + } + + return data_size; +} + +vg_lite_error_t vg_lite_init_path(vg_lite_path_t * path, + vg_lite_format_t data_format, + vg_lite_quality_t quality, + vg_lite_uint32_t path_length, + vg_lite_pointer path_data, + vg_lite_float_t min_x, vg_lite_float_t min_y, + vg_lite_float_t max_x, vg_lite_float_t max_y) +{ + int32_t data_size, num = 0; + + if(path == NULL) + return VG_LITE_INVALID_ARGUMENT; + + memset(path, 0, sizeof(*path)); + path->format = data_format; + path->quality = quality; + path->bounding_box[0] = min_x; + path->bounding_box[1] = min_y; + path->bounding_box[2] = max_x; + path->bounding_box[3] = max_y; + + /* Path data cannot end with a CLOSE op. Replace CLOSE with END for path_data */ + data_size = get_data_size(data_format); + num = path_length / data_size; + + switch(data_format) { + case VG_LITE_S8: + if(path_data && (*((char *)path_data + num - 1) == VLC_OP_CLOSE)) { + *(char *)((int *)path_data + num - 1) = VLC_OP_END; + } + break; + + case VG_LITE_S16: + if(path_data && (*(char *)((short *)path_data + num - 1) == VLC_OP_CLOSE)) { + *(char *)((short *)path_data + num - 1) = VLC_OP_END; + } + break; + + case VG_LITE_S32: + if(path_data && (*(char *)((int *)path_data + num - 1) == VLC_OP_CLOSE)) { + *(char *)((int *)path_data + num - 1) = VLC_OP_END; + } + break; + + case VG_LITE_FP32: + if(path_data && (*(char *)((float *)path_data + num - 1) == VLC_OP_CLOSE)) { + *(char *)((float *)path_data + num - 1) = VLC_OP_END; + } + break; + + default: + break; + } + + path->path_length = path_length; + path->path = path_data; + + path->path_changed = 1; + path->uploaded.address = 0; + path->uploaded.bytes = 0; + path->uploaded.handle = NULL; + path->uploaded.memory = NULL; + path->pdata_internal = 0; + s_context.path_lastX = 0; + s_context.path_lastY = 0; + /* Default FILL path type*/ + path->path_type = VG_LITE_DRAW_FILL_PATH; + + return VG_LITE_SUCCESS; +} + +vg_lite_error_t vg_lite_set_path_type(vg_lite_path_t * path, vg_lite_path_type_t path_type) +{ + if(!path || + (path_type != VG_LITE_DRAW_FILL_PATH && + path_type != VG_LITE_DRAW_STROKE_PATH && + path_type != VG_LITE_DRAW_FILL_STROKE_PATH) + ) + return VG_LITE_INVALID_ARGUMENT; + + path->path_type = path_type; + + return VG_LITE_SUCCESS; +} + +vg_lite_error_t vg_lite_clear_path(vg_lite_path_t * path) +{ + vg_lite_error_t error; + if(path->uploaded.handle != NULL) { + vg_lite_kernel_free_t free_cmd; + free_cmd.memory_handle = path->uploaded.handle; + error = vg_lite_kernel(VG_LITE_FREE, &free_cmd); + if(error != VG_LITE_SUCCESS) + return error; + } + +#if (CHIPID==0x355) + if(path->stroke && path->stroke->uploaded.handle != NULL) { + vg_lite_kernel_free_t free_cmd; + free_cmd.memory_handle = path->stroke->uploaded.handle; + error = vg_lite_kernel(VG_LITE_FREE, &free_cmd); + if(error != VG_LITE_SUCCESS) + return error; + } +#endif + + path->uploaded.address = 0; + path->uploaded.bytes = 0; + path->uploaded.handle = NULL; + path->uploaded.memory = NULL; + +#if (CHIPID==0x355) + if(path->stroke) { + path->stroke->uploaded.address = 0; + path->stroke->uploaded.bytes = 0; + path->stroke->uploaded.handle = NULL; + path->stroke->uploaded.memory = NULL; + } +#endif + + if(path->pdata_internal == 1 && path->path != NULL) { + vg_lite_os_free(path->path); + } + path->path = NULL; + + if(path->stroke_path) { + vg_lite_os_free(path->stroke_path); + path->stroke_path = NULL; + } + +#if gcFEATURE_VG_STROKE_PATH + if(path->stroke) { + if(path->stroke->path_list_divide) { + vg_lite_path_list_ptr cur_list; + while(path->stroke->path_list_divide) { + cur_list = path->stroke->path_list_divide->next; + if(path->stroke->path_list_divide->path_points) { + vg_lite_path_point_ptr temp_point; + while(path->stroke->path_list_divide->path_points) { + temp_point = path->stroke->path_list_divide->path_points->next; + vg_lite_os_free(path->stroke->path_list_divide->path_points); + path->stroke->path_list_divide->path_points = temp_point; + } + temp_point = NULL; + } + vg_lite_os_free(path->stroke->path_list_divide); + path->stroke->path_list_divide = cur_list; + } + cur_list = 0; + } + + if(path->stroke->stroke_paths) { + vg_lite_sub_path_ptr temp_sub_path; + while(path->stroke->stroke_paths) { + temp_sub_path = path->stroke->stroke_paths->next; + if(path->stroke->stroke_paths->point_list) { + vg_lite_path_point_ptr temp_point; + while(path->stroke->stroke_paths->point_list) { + temp_point = path->stroke->stroke_paths->point_list->next; + vg_lite_os_free(path->stroke->stroke_paths->point_list); + path->stroke->stroke_paths->point_list = temp_point; + } + temp_point = NULL; + } + vg_lite_os_free(path->stroke->stroke_paths); + path->stroke->stroke_paths = temp_sub_path; + } + temp_sub_path = NULL; + } + + if(path->stroke->dash_pattern) + vg_lite_os_free(path->stroke->dash_pattern); + + vg_lite_os_free(path->stroke); + path->stroke = NULL; + path->stroke_valid = 0; + + + path->stroke_size = 0; + } +#endif + + return VG_LITE_SUCCESS; +} + +vg_lite_error_t vg_lite_upload_path(vg_lite_path_t * path) +{ +#if DUMP_API + FUNC_DUMP(vg_lite_upload_path)(path); +#endif + + vg_lite_error_t error = VG_LITE_SUCCESS; + uint32_t bytes; + vg_lite_buffer_t Buf, * buffer; + + buffer = &Buf; + + /* Compute the number of bytes required for path + command buffer prefix/postfix. */ + bytes = (8 + path->path_length + 7 + 8) & ~7; + + /* Allocate GPU memory. */ + buffer->width = bytes; + buffer->height = 1; + buffer->stride = 0; + buffer->format = VG_LITE_A8; + VG_LITE_RETURN_ERROR(vg_lite_allocate(buffer)); + + /* Initialize command buffer prefix. */ + ((uint32_t *) buffer->memory)[0] = VG_LITE_DATA((path->path_length + 7) / 8); + ((uint32_t *) buffer->memory)[1] = 0; + + /* Copy the path data. */ + memcpy((uint32_t *) buffer->memory + 2, path->path, path->path_length); + + /* Initialize command buffer postfix. */ + ((uint32_t *) buffer->memory)[(bytes >> 2) - 2] = VG_LITE_RETURN(); + ((uint32_t *) buffer->memory)[(bytes >> 2) - 1] = 0; + + /* Mark path as uploaded. */ + path->path = buffer->memory; + path->uploaded.handle = buffer->handle; + path->uploaded.address = buffer->address; + path->uploaded.memory = buffer->memory; + path->uploaded.bytes = bytes; + path->path_changed = 0; + VLM_PATH_ENABLE_UPLOAD(*path); /* Implicitly enable path uploading. */ + + /* Return pointer to vg_lite_buffer structure. */ + return error; +} + +vg_lite_uint32_t vg_lite_get_path_length(vg_lite_uint8_t * cmd, vg_lite_uint32_t count, vg_lite_format_t format) +{ + uint32_t size = 0; + int32_t dCount = 0; + uint32_t i = 0; + int32_t data_size = 0; + + data_size = get_data_size(format); + + for(i = 0; i < count; i++) { + size++; /* OP CODE. */ + + dCount = get_data_count(cmd[i]); + size = CDALIGN(size, data_size); + size += dCount * data_size; + + } + if(cmd[count - 1] != VLC_OP_END || cmd[count - 1] != VLC_OP_CLOSE) { + size++; + size = CDALIGN(size, data_size); + } + + return size; +} + +vg_lite_error_t vg_lite_append_path(vg_lite_path_t * path, + vg_lite_uint8_t * cmd, + vg_lite_pointer data, + vg_lite_uint32_t seg_count) +{ + vg_lite_error_t error = VG_LITE_SUCCESS; + uint32_t i; + int32_t j; + int32_t offset = 0; + int32_t dataCount = 0; + float * dataf = (float *) data; + float * pathf = NULL; + int32_t * data_s32 = (int32_t *) data; + int32_t * path_s32 = NULL; + int16_t * data_s16 = (int16_t *) data; + int16_t * path_s16 = NULL; + int8_t * data_s8 = (int8_t *) data; + int8_t * path_s8 = NULL; + uint8_t * pathc = NULL; + int32_t data_size; + uint8_t arc_path = 0; + uint8_t h_v_path = 0; + uint8_t smooth_path = 0; + float px = 0.0f, py = 0.0f, cx = 0.0f, cy = 0.0f; + int rel = 0; + + if(cmd == NULL || data == NULL || path == NULL) + return VG_LITE_INVALID_ARGUMENT; + + for(i = 0; i < seg_count; i++) { + if(cmd[i] > VLC_OP_LCWARC_REL) + return VG_LITE_INVALID_ARGUMENT; + } + + /* Support NULL path->path case for OpenVG */ + if(!path->path) { + data_size = vg_lite_get_path_length(cmd, seg_count, path->format); + path->path = (vg_lite_pointer)vg_lite_os_malloc(data_size); + if(!path->path) { + return VG_LITE_OUT_OF_RESOURCES; + } + path->pdata_internal = 1; + memset(path->path, 0, data_size); + } + + data_size = get_data_size(path->format); + path->path_changed = 1; + pathf = (float *)path->path; + path_s32 = (int32_t *)path->path; + path_s16 = (int16_t *)path->path; + path_s8 = (int8_t *)path->path; + pathc = (uint8_t *)path->path; + /* Set bounding box if the first opcode is VLC_OP_MOVE_* */ + if((cmd[0] & 0xfe) == VLC_OP_MOVE) { + switch(path->format) { + case VG_LITE_S8: + cx = (float)data_s8[0]; + cy = (float)data_s8[1]; + break; + case VG_LITE_S16: + cx = (float)data_s16[0]; + cy = (float)data_s16[1]; + break; + case VG_LITE_S32: + cx = (float)data_s32[0]; + cy = (float)data_s32[1]; + break; + case VG_LITE_FP32: + cx = (float)dataf[0]; + cy = (float)dataf[1]; + break; + } + path->bounding_box[0] = path->bounding_box[2] = cx; + path->bounding_box[1] = path->bounding_box[3] = cy; + } + + /* Loop to fill path data. */ + for(i = 0; i < seg_count; i++) { +#if (CHIPID == 0x355) + if((i < seg_count) && cmd[i] == VLC_OP_CLOSE && (cmd[i + 1] == VLC_OP_MOVE || cmd[i + 1] == VLC_OP_MOVE_REL)) { + if(data_size == 1) { + *(pathc + offset) = cmd[i]; + offset++; + } + else if(data_size == 2) { + *(uint16_t *)(pathc + offset) = 0x0101; + offset += 2; + } + else if(data_size == 4) { + *(uint32_t *)(pathc + offset) = 0x01010101; + offset += 4; + } + } + else +#endif + { + *(pathc + offset) = cmd[i]; + offset++; + } + + dataCount = get_data_count(cmd[i]); + /* compute the bounding_box. */ + if(dataCount >= 0) { + offset = CDALIGN(offset, data_size); + if((cmd[i] > VLC_OP_CLOSE) && + (cmd[i] < VLC_OP_HLINE) && + ((cmd[i] & 0x01) == 1)) { + rel = 1; + } + else if((cmd[i] >= VLC_OP_HLINE) && + ((cmd[i] & 0x01) == 0)) { + rel = 1; + } + else { + rel = 0; + } + if(cmd[i] >= VLC_OP_HLINE && cmd[i] <= VLC_OP_VLINE_REL) { + switch(path->format) { + case VG_LITE_S8: + path_s8 = (int8_t *)(pathc + offset); + path_s8[0] = *data_s8; + data_s8++; + if(rel) { + cx = px + (float)path_s8[0]; + cy = py + (float)path_s8[1]; + } + else { + cx = (float)path_s8[0]; + cy = (float)path_s8[1]; + } + break; + + case VG_LITE_S16: + path_s16 = (int16_t *)(pathc + offset); + path_s16[0] = *data_s16; + data_s16++; + if(rel) { + cx = px + (float)path_s16[0]; + cy = py + (float)path_s16[1]; + } + else { + cx = (float)path_s16[0]; + cy = (float)path_s16[1]; + } + break; + + case VG_LITE_S32: + path_s32 = (int32_t *)(pathc + offset); + path_s32[0] = *data_s32; + data_s32++; + if(rel) { + cx = px + (float)path_s32[0]; + cy = py + (float)path_s32[1]; + } + else { + cx = (float)path_s32[0]; + cy = (float)path_s32[1]; + } + break; + + case VG_LITE_FP32: + pathf = (float *)(pathc + offset); + pathf[0] = *dataf; + dataf++; + if(rel) { + cx = px + (float)pathf[0]; + cy = py + (float)pathf[1]; + } + else { + cx = (float)pathf[0]; + cy = (float)pathf[1]; + } + break; + } + h_v_path = 1; + /* Update path bounds. */ + path->bounding_box[0] = CDMIN(path->bounding_box[0], cx); + path->bounding_box[2] = CDMAX(path->bounding_box[2], cx); + path->bounding_box[1] = CDMIN(path->bounding_box[1], cy); + path->bounding_box[3] = CDMAX(path->bounding_box[3], cy); + } + else if(cmd[i] < VLC_OP_SCCWARC) { + /* Mark smooth path,convert it in next step. */ + if(cmd[i] <= VLC_OP_SCUBIC_REL && cmd[i] >= VLC_OP_SQUAD) { + smooth_path = 1; + } + for(j = 0; j < dataCount / 2; j++) { + switch(path->format) { + case VG_LITE_S8: + path_s8 = (int8_t *)(pathc + offset); + path_s8[j * 2] = *data_s8; + data_s8++; + path_s8[j * 2 + 1] = *data_s8; + data_s8++; + + if(rel) { + cx = px + path_s8[j * 2]; + cy = py + path_s8[j * 2 + 1]; + } + else { + cx = path_s8[j * 2]; + cy = path_s8[j * 2 + 1]; + } + break; + case VG_LITE_S16: + path_s16 = (int16_t *)(pathc + offset); + path_s16[j * 2] = *data_s16; + data_s16++; + path_s16[j * 2 + 1] = *data_s16; + data_s16++; + + if(rel) { + cx = px + path_s16[j * 2]; + cy = py + path_s16[j * 2 + 1]; + } + else { + cx = path_s16[j * 2]; + cy = path_s16[j * 2 + 1]; + } + break; + case VG_LITE_S32: + path_s32 = (int32_t *)(pathc + offset); + path_s32[j * 2] = *data_s32; + data_s32++; + path_s32[j * 2 + 1] = *data_s32; + data_s32++; + + if(rel) { + cx = px + path_s32[j * 2]; + cy = py + path_s32[j * 2 + 1]; + } + else { + cx = (float)path_s32[j * 2]; + cy = (float)path_s32[j * 2 + 1]; + } + break; + case VG_LITE_FP32: + pathf = (float *)(pathc + offset); + pathf[j * 2] = *dataf; + dataf++; + pathf[j * 2 + 1] = *dataf; + dataf++; + + if(rel) { + cx = px + pathf[j * 2]; + cy = py + pathf[j * 2 + 1]; + } + else { + cx = pathf[j * 2]; + cy = pathf[j * 2 + 1]; + } + break; + + default: + return VG_LITE_INVALID_ARGUMENT; + } + if(cmd[i] <= VLC_OP_LINE_REL && cmd[i] >= VLC_OP_MOVE) { + /* Update move to and line path bounds. */ + path->bounding_box[0] = CDMIN(path->bounding_box[0], cx); + path->bounding_box[2] = CDMAX(path->bounding_box[2], cx); + path->bounding_box[1] = CDMIN(path->bounding_box[1], cy); + path->bounding_box[3] = CDMAX(path->bounding_box[3], cy); + } + + } + } +#if gcFEATURE_VG_ARC_PATH + else { + arc_path = 1; + switch(path->format) { + case VG_LITE_S8: + path_s8 = (int8_t *)(pathc + offset); + path_s8[0] = *data_s8; + data_s8++; + path_s8[1] = *data_s8; + data_s8++; + path_s8[2] = *data_s8; + data_s8++; + path_s8[3] = *data_s8; + data_s8++; + path_s8[4] = *data_s8; + data_s8++; + + if(rel) { + cx = px + path_s8[3]; + cy = py + path_s8[4]; + } + else { + cx = path_s8[3]; + cy = path_s8[4]; + } + /* Update path bounds. */ + compute_pathbounds(&path->bounding_box[0], &path->bounding_box[1], &path->bounding_box[2], &path->bounding_box[3], + cx + 2 * path_s8[0], cy + 2 * path_s8[1]); + compute_pathbounds(&path->bounding_box[0], &path->bounding_box[1], &path->bounding_box[2], &path->bounding_box[3], + px + 2 * path_s8[1], py + 2 * path_s8[1]); + compute_pathbounds(&path->bounding_box[0], &path->bounding_box[1], &path->bounding_box[2], &path->bounding_box[3], + cx - 2 * path_s8[0], cy - 2 * path_s8[1]); + compute_pathbounds(&path->bounding_box[0], &path->bounding_box[1], &path->bounding_box[2], &path->bounding_box[3], + px - 2 * path_s8[1], py - 2 * path_s8[1]); + break; + + case VG_LITE_S16: + path_s16 = (int16_t *)(pathc + offset); + path_s16[0] = *data_s16; + data_s16++; + path_s16[1] = *data_s16; + data_s16++; + path_s16[2] = *data_s16; + data_s16++; + path_s16[3] = *data_s16; + data_s16++; + path_s16[4] = *data_s16; + data_s16++; + + if(rel) { + cx = px + path_s16[3]; + cy = py + path_s16[4]; + } + else { + cx = path_s16[3]; + cy = path_s16[4]; + } + /* Update path bounds. */ + compute_pathbounds(&path->bounding_box[0], &path->bounding_box[1], &path->bounding_box[2], &path->bounding_box[3], + cx + 2 * path_s16[0], cy + 2 * path_s16[1]); + compute_pathbounds(&path->bounding_box[0], &path->bounding_box[1], &path->bounding_box[2], &path->bounding_box[3], + px + 2 * path_s16[1], py + 2 * path_s16[1]); + compute_pathbounds(&path->bounding_box[0], &path->bounding_box[1], &path->bounding_box[2], &path->bounding_box[3], + cx - 2 * path_s16[0], cy - 2 * path_s16[1]); + compute_pathbounds(&path->bounding_box[0], &path->bounding_box[1], &path->bounding_box[2], &path->bounding_box[3], + px - 2 * path_s16[1], py - 2 * path_s16[1]); + break; + + case VG_LITE_S32: + path_s32 = (int32_t *)(pathc + offset); + path_s32[0] = *data_s32; + data_s32++; + path_s32[1] = *data_s32; + data_s32++; + path_s32[2] = *data_s32; + data_s32++; + path_s32[3] = *data_s32; + data_s32++; + path_s32[4] = *data_s32; + data_s32++; + + if(rel) { + cx = px + path_s32[3]; + cy = py + path_s32[4]; + } + else { + cx = (float)path_s32[3]; + cy = (float)path_s32[4]; + } + /* Update path bounds. */ + compute_pathbounds(&path->bounding_box[0], &path->bounding_box[1], &path->bounding_box[2], &path->bounding_box[3], + cx + 2 * path_s32[0], cy + 2 * path_s32[1]); + compute_pathbounds(&path->bounding_box[0], &path->bounding_box[1], &path->bounding_box[2], &path->bounding_box[3], + px + 2 * path_s32[1], py + 2 * path_s32[1]); + compute_pathbounds(&path->bounding_box[0], &path->bounding_box[1], &path->bounding_box[2], &path->bounding_box[3], + cx - 2 * path_s32[0], cy - 2 * path_s32[1]); + compute_pathbounds(&path->bounding_box[0], &path->bounding_box[1], &path->bounding_box[2], &path->bounding_box[3], + px - 2 * path_s32[1], py - 2 * path_s32[1]); + break; + + case VG_LITE_FP32: + pathf = (float *)(pathc + offset); + pathf[0] = *dataf; + dataf++; + pathf[1] = *dataf; + dataf++; + pathf[2] = *dataf; + dataf++; + pathf[3] = *dataf; + dataf++; + pathf[4] = *dataf; + dataf++; + + if(rel) { + cx = px + pathf[3]; + cy = py + pathf[4]; + } + else { + cx = pathf[3]; + cy = pathf[4]; + } + /* Update path bounds. */ + compute_pathbounds(&path->bounding_box[0], &path->bounding_box[1], &path->bounding_box[2], &path->bounding_box[3], + cx + 2 * pathf[0], cy + 2 * pathf[1]); + compute_pathbounds(&path->bounding_box[0], &path->bounding_box[1], &path->bounding_box[2], &path->bounding_box[3], + px + 2 * pathf[1], py + 2 * pathf[1]); + compute_pathbounds(&path->bounding_box[0], &path->bounding_box[1], &path->bounding_box[2], &path->bounding_box[3], + cx - 2 * pathf[0], cy - 2 * pathf[1]); + compute_pathbounds(&path->bounding_box[0], &path->bounding_box[1], &path->bounding_box[2], &path->bounding_box[3], + px - 2 * pathf[1], py - 2 * pathf[1]); + break; + } + + } +#endif + px = cx; + py = cy; + + offset += dataCount * data_size; + } + } + if(cmd[seg_count - 1] == VLC_OP_END +#if gcFEATURE_VG_ARC_PATH + || (cmd[seg_count - 1] == VLC_OP_CLOSE && (arc_path | h_v_path | smooth_path)) +#endif + ) { + path->path_length = offset; + } + else { + path->path_length = offset + data_size; + path->add_end = 1; + ((uint8_t *)(path->path))[offset] = 0; + } + +#if gcFEATURE_VG_ARC_PATH + if(arc_path | h_v_path | smooth_path) { + error = vg_lite_init_arc_path(path, + path->format, + path->quality, + path->path_length, + path->path, + path->bounding_box[0], path->bounding_box[1], + path->bounding_box[2], path->bounding_box[3]); + } +#endif + s_context.path_lastX = cx; + s_context.path_lastY = cy; + return error; +} + +#if (CHIPID==0x355 || CHIPID==0x255) /* GC355/GC255 vg_lite_draw functions */ + +#define UPDATE_BOUNDING_BOX(bbx, point) \ + do { \ + if ((point).x < (bbx).x) { \ + (bbx).width += (bbx).x - (point).x; \ + (bbx).x = (point).x; \ + } \ + if ((point).y < (bbx).y) { \ + (bbx).height += (bbx).y - (point).y; \ + (bbx).y = (point).y; \ + } \ + if ((point).x > (bbx).x + (bbx).width) \ + (bbx).width = (point).x - (bbx).x; \ + if ((point).y > (bbx).y + (bbx).height) \ + (bbx).height = (point).y - (bbx).y; \ + } while(0) + +static vg_lite_error_t transform_bounding_box(vg_lite_rectangle_t * in_bbx, + vg_lite_matrix_t * matrix, + vg_lite_rectangle_t * clip, + vg_lite_rectangle_t * out_bbx, + vg_lite_point_t * origin) +{ + vg_lite_point_t temp; + + memset(out_bbx, 0, sizeof(vg_lite_rectangle_t)); + + /* Transform image point (0, 0). */ + if(!transform(&temp, 0.0f, 0.0f, matrix)) + return VG_LITE_INVALID_ARGUMENT; + out_bbx->x = temp.x; + out_bbx->y = temp.y; + + /* Provide position of the new origin to the caller if requested. */ + if(origin != NULL) { + origin->x = temp.x; + origin->y = temp.y; + } + + /* Transform image point (0, height). */ + if(!transform(&temp, 0.0f, (vg_lite_float_t)in_bbx->height, matrix)) + return VG_LITE_INVALID_ARGUMENT; + UPDATE_BOUNDING_BOX(*out_bbx, temp); + + /* Transform image point (width, height). */ + if(!transform(&temp, (vg_lite_float_t)in_bbx->width, (vg_lite_float_t)in_bbx->height, matrix)) + return VG_LITE_INVALID_ARGUMENT; + UPDATE_BOUNDING_BOX(*out_bbx, temp); + + /* Transform image point (width, 0). */ + if(!transform(&temp, (vg_lite_float_t)in_bbx->width, 0.0f, matrix)) + return VG_LITE_INVALID_ARGUMENT; + UPDATE_BOUNDING_BOX(*out_bbx, temp); + + /* Clip is required */ + if(clip) { + out_bbx->x = MAX(out_bbx->x, clip->x); + out_bbx->y = MAX(out_bbx->y, clip->y); + out_bbx->width = MIN((out_bbx->x + out_bbx->width), (clip->x + clip->width)) - out_bbx->x; + out_bbx->height = MIN((out_bbx->y + out_bbx->height), (clip->y + clip->height)) - out_bbx->y; + } + + return VG_LITE_SUCCESS; +} + +static vg_lite_error_t set_interpolation_steps(vg_lite_buffer_t * target, + vg_lite_int32_t s_width, + vg_lite_int32_t s_height, + vg_lite_matrix_t * matrix) +{ + vg_lite_matrix_t im; + vg_lite_rectangle_t src_bbx, bounding_box, clip; + vg_lite_float_t xs[3], ys[3], cs[3]; + vg_lite_error_t error = VG_LITE_SUCCESS; + float dx = 0.0f, dy = 0.0f; + +#define ERR_LIMIT 0.0000610351562f + + /* Get bounding box. */ + memset(&src_bbx, 0, sizeof(vg_lite_rectangle_t)); + memset(&clip, 0, sizeof(vg_lite_rectangle_t)); + src_bbx.width = (int32_t)s_width; + src_bbx.height = (int32_t)s_height; + + if(s_context.scissor_set) { + clip.x = s_context.scissor[0]; + clip.y = s_context.scissor[1]; + clip.width = s_context.scissor[2]; + clip.height = s_context.scissor[3]; + } + else { + clip.x = clip.y = 0; + clip.width = s_context.rtbuffer->width; + clip.height = s_context.rtbuffer->height; + } + transform_bounding_box(&src_bbx, matrix, &clip, &bounding_box, NULL); + /* Compute inverse matrix. */ + if(!inverse(&im, matrix)) + return VG_LITE_INVALID_ARGUMENT; + /* Compute interpolation steps. */ + /* X step */ + xs[0] = im.m[0][0] / s_width; + xs[1] = im.m[1][0] / s_height; + xs[2] = im.m[2][0]; + /* Y step */ + ys[0] = im.m[0][1] / s_width; + ys[1] = im.m[1][1] / s_height; + ys[2] = im.m[2][1]; + /* C step 2 */ + cs[2] = 0.5f * (im.m[2][0] + im.m[2][1]) + im.m[2][2]; + + /* C step 0, 1*/ + cs[0] = (0.5f * (im.m[0][0] + im.m[0][1]) + im.m[0][2] + dx) / s_width; + cs[1] = (0.5f * (im.m[1][0] + im.m[1][1]) + im.m[1][2] + dy) / s_height; + /* Set command buffer */ + VG_LITE_RETURN_ERROR(push_state_ptr(&s_context, 0x0A18, (void *)&cs[0])); + VG_LITE_RETURN_ERROR(push_state_ptr(&s_context, 0x0A19, (void *)&cs[1])); + VG_LITE_RETURN_ERROR(push_state_ptr(&s_context, 0x0A1A, (void *)&cs[2])); + VG_LITE_RETURN_ERROR(push_state_ptr(&s_context, 0x0A1C, (void *)&xs[0])); + VG_LITE_RETURN_ERROR(push_state_ptr(&s_context, 0x0A1D, (void *)&xs[1])); + VG_LITE_RETURN_ERROR(push_state_ptr(&s_context, 0x0A1E, (void *)&xs[2])); + VG_LITE_RETURN_ERROR(push_state(&s_context, 0x0A1F, 0x00000001)); + VG_LITE_RETURN_ERROR(push_state_ptr(&s_context, 0x0A20, (void *)&ys[0])); + VG_LITE_RETURN_ERROR(push_state_ptr(&s_context, 0x0A21, (void *)&ys[1])); + VG_LITE_RETURN_ERROR(push_state_ptr(&s_context, 0x0A22, (void *)&ys[2])); + + return VG_LITE_SUCCESS; +} + +static vg_lite_error_t set_interpolation_steps_draw_paint(vg_lite_buffer_t * target, + vg_lite_int32_t s_width, + vg_lite_int32_t s_height, + vg_lite_matrix_t * matrix) +{ + vg_lite_matrix_t im; + vg_lite_rectangle_t src_bbx, bounding_box, clip; + vg_lite_float_t xs[3], ys[3], cs[3]; + vg_lite_error_t error = VG_LITE_SUCCESS; + float dx = 0.0f, dy = 0.0f; + +#define ERR_LIMIT 0.0000610351562f + + /* Get bounding box. */ + memset(&src_bbx, 0, sizeof(vg_lite_rectangle_t)); + memset(&clip, 0, sizeof(vg_lite_rectangle_t)); + src_bbx.width = (int32_t)s_width; + src_bbx.height = (int32_t)s_height; + + if(s_context.scissor_set) { + clip.x = s_context.scissor[0]; + clip.y = s_context.scissor[1]; + clip.width = s_context.scissor[2]; + clip.height = s_context.scissor[3]; + } + else { + clip.x = clip.y = 0; + clip.width = s_context.rtbuffer->width; + clip.height = s_context.rtbuffer->height; + } + transform_bounding_box(&src_bbx, matrix, &clip, &bounding_box, NULL); + /* Compute inverse matrix. */ + if(!inverse(&im, matrix)) + return VG_LITE_INVALID_ARGUMENT; + /* Compute interpolation steps. */ + /* X step */ + xs[0] = im.m[0][0] / s_width; + xs[1] = im.m[1][0] / s_height; + xs[2] = im.m[2][0]; + /* Y step */ + ys[0] = im.m[0][1] / s_width; + ys[1] = im.m[1][1] / s_height; + ys[2] = im.m[2][1]; + /* C step 2 */ + cs[2] = 0.5f * (im.m[2][0] + im.m[2][1]) + im.m[2][2]; + + /* C step 0, 1*/ + cs[0] = (0.5f * (im.m[0][0] + im.m[0][1]) + im.m[0][2] + dx) / s_width; + cs[1] = (0.5f * (im.m[1][0] + im.m[1][1]) + im.m[1][2] + dy) / s_height; + + VG_LITE_RETURN_ERROR(push_state_ptr(&s_context, 0x0A04, (void *)&cs[0])); + VG_LITE_RETURN_ERROR(push_state_ptr(&s_context, 0x0A05, (void *)&cs[1])); + VG_LITE_RETURN_ERROR(push_state_ptr(&s_context, 0x0A06, (void *)&xs[0])); + VG_LITE_RETURN_ERROR(push_state_ptr(&s_context, 0x0A07, (void *)&xs[1])); + VG_LITE_RETURN_ERROR(push_state_ptr(&s_context, 0x0A08, (void *)&ys[0])); + VG_LITE_RETURN_ERROR(push_state_ptr(&s_context, 0x0A09, (void *)&ys[1])); + /* Set command buffer */ + VG_LITE_RETURN_ERROR(push_state_ptr(&s_context, 0x0A18, (void *)&cs[0])); + VG_LITE_RETURN_ERROR(push_state_ptr(&s_context, 0x0A19, (void *)&cs[1])); + VG_LITE_RETURN_ERROR(push_state_ptr(&s_context, 0x0A1A, (void *)&cs[2])); + VG_LITE_RETURN_ERROR(push_state_ptr(&s_context, 0x0A1C, (void *)&xs[0])); + VG_LITE_RETURN_ERROR(push_state_ptr(&s_context, 0x0A1D, (void *)&xs[1])); + VG_LITE_RETURN_ERROR(push_state_ptr(&s_context, 0x0A1E, (void *)&xs[2])); + VG_LITE_RETURN_ERROR(push_state(&s_context, 0x0A1F, 0x00000001)); + VG_LITE_RETURN_ERROR(push_state_ptr(&s_context, 0x0A20, (void *)&ys[0])); + VG_LITE_RETURN_ERROR(push_state_ptr(&s_context, 0x0A21, (void *)&ys[1])); + VG_LITE_RETURN_ERROR(push_state_ptr(&s_context, 0x0A22, (void *)&ys[2])); + + return VG_LITE_SUCCESS; +} + +/* GC355/GC255 vg_lite_draw API implementation + */ +vg_lite_error_t vg_lite_draw(vg_lite_buffer_t * target, + vg_lite_path_t * path, + vg_lite_fill_t fill_rule, + vg_lite_matrix_t * matrix, + vg_lite_blend_t blend, + vg_lite_color_t color) +{ + uint32_t blend_mode; + uint32_t format, quality, tiling, fill; + uint32_t tessellation_size; + vg_lite_error_t error; + int32_t dst_align_width; + uint32_t mul, div, align; + vg_lite_point_t point_min = {0}, point_max = {0}, temp = {0}; + int x, y, width, height; + uint8_t ts_is_fullscreen = 0; + uint32_t in_premult = 0; + uint32_t premul_flag = 0; + uint32_t prediv_flag = 0; +#if(CHIPID == 0x355) + uint8_t * path_re = NULL; + uint32_t index = 0; +#endif + +#if gcFEATURE_VG_TRACE_API + VGLITE_LOG("vg_lite_draw %p %p %d %p %d 0x%08X\n", target, path, fill_rule, matrix, blend, color); + VGLITE_LOG(" path_type %d, path_length %d, stroke_size %d\n", path->path_type, path->path_length, path->stroke_size); +#endif + +#if gcFEATURE_VG_ERROR_CHECK +#if !gcFEATURE_VG_QUALITY_8X + if(path->quality == VG_LITE_UPPER) { + return VG_LITE_NOT_SUPPORT; + } +#endif + if(!path || !path->path) { + return VG_LITE_INVALID_ARGUMENT; + } +#if (CHIPID == 0x355) + if(target->format == VG_LITE_L8 || target->format == VG_LITE_YUYV || + target->format == VG_LITE_BGRA2222 || target->format == VG_LITE_RGBA2222 || + target->format == VG_LITE_ABGR2222 || target->format == VG_LITE_ARGB2222) { + printf("Target format: 0x%x is not supported.\n", target->format); + return VG_LITE_NOT_SUPPORT; + } +#endif +#endif /* gcFEATURE_VG_ERROR_CHECK */ + + if(!path->path_length) { + return VG_LITE_SUCCESS; + } + + if(!matrix) { + matrix = &identity_mtx; + } + +#if gcFEATURE_VG_GAMMA + set_gamma_dest_only(target, VGL_FALSE); +#endif + + /*blend input into context*/ + s_context.blend_mode = blend; + + /* Adjust premultiply setting according to openvg condition */ + target->apply_premult = 0; + premul_flag = (s_context.blend_mode >= OPENVG_BLEND_SRC_OVER && s_context.blend_mode <= OPENVG_BLEND_ADDITIVE); + if(target->premultiplied == 0 && premul_flag == 0) { + in_premult = 0x10000000; + target->apply_premult = 1; + } + else if((target->premultiplied == 1) || + (target->premultiplied == 0 && premul_flag == 1)) { + in_premult = 0x00000000; + } + if(blend == VG_LITE_BLEND_NORMAL_LVGL) { + in_premult = 0x00000000; + } + + error = set_render_target(target); + if(error != VG_LITE_SUCCESS) { + return error; + } + else if(error == VG_LITE_NO_CONTEXT) { + /* If scissoring is enabled and no valid scissoring rectangles + are present, no drawing occurs */ + return VG_LITE_SUCCESS; + } + + width = s_context.tessbuf.tess_w_h & 0xFFFF; + height = s_context.tessbuf.tess_w_h >> 16; + get_format_bytes(target->format, &mul, &div, &align); + dst_align_width = target->stride * div / mul; + if(width == 0 || height == 0) + return VG_LITE_NO_CONTEXT; + if((dst_align_width <= width) && (target->height <= height)) { + ts_is_fullscreen = 1; + point_min.x = 0; + point_min.y = 0; + point_max.x = dst_align_width; + point_max.y = target->height; + } + + if(ts_is_fullscreen == 0) { + transform(&temp, (vg_lite_float_t)path->bounding_box[0], (vg_lite_float_t)path->bounding_box[1], matrix); + point_min = point_max = temp; + + transform(&temp, (vg_lite_float_t)path->bounding_box[2], (vg_lite_float_t)path->bounding_box[1], matrix); + if(temp.x < point_min.x) point_min.x = temp.x; + if(temp.y < point_min.y) point_min.y = temp.y; + if(temp.x > point_max.x) point_max.x = temp.x; + if(temp.y > point_max.y) point_max.y = temp.y; + + transform(&temp, (vg_lite_float_t)path->bounding_box[2], (vg_lite_float_t)path->bounding_box[3], matrix); + if(temp.x < point_min.x) point_min.x = temp.x; + if(temp.y < point_min.y) point_min.y = temp.y; + if(temp.x > point_max.x) point_max.x = temp.x; + if(temp.y > point_max.y) point_max.y = temp.y; + + transform(&temp, (vg_lite_float_t)path->bounding_box[0], (vg_lite_float_t)path->bounding_box[3], matrix); + if(temp.x < point_min.x) point_min.x = temp.x; + if(temp.y < point_min.y) point_min.y = temp.y; + if(temp.x > point_max.x) point_max.x = temp.x; + if(temp.y > point_max.y) point_max.y = temp.y; + + if(point_min.x < 0) point_min.x = 0; + if(point_min.y < 0) point_min.y = 0; + if(point_max.x > dst_align_width) point_max.x = dst_align_width; + if(point_max.y > target->height) point_max.y = target->height; + + if(s_context.scissor_set) { + point_min.x = MAX(point_min.x, s_context.scissor[0]); + point_min.y = MAX(point_min.y, s_context.scissor[1]); + point_max.x = MIN(point_max.x, s_context.scissor[0] + s_context.scissor[2]); + point_max.y = MIN(point_max.y, s_context.scissor[1] + s_context.scissor[3]); + } + } + + /* Convert states into hardware values. */ + blend_mode = convert_blend(blend); + format = convert_path_format(path->format); + quality = convert_path_quality(path->quality); + tiling = (s_context.capabilities.cap.tiled == 2) ? 0x2000000 : 0; + fill = (fill_rule == VG_LITE_FILL_EVEN_ODD) ? 0x10 : 0; + tessellation_size = s_context.tessbuf.L2_size ? s_context.tessbuf.L2_size : s_context.tessbuf.L1_size; + + /* Setup the command buffer. */ + /* Program color register. */ + VG_LITE_RETURN_ERROR(push_state(&s_context, 0x0A00, + in_premult | s_context.capabilities.cap.tiled | blend_mode | s_context.enable_mask | s_context.scissor_enable | + s_context.color_transform | s_context.matrix_enable)); + + VG_LITE_RETURN_ERROR(push_state(&s_context, 0x0A02, color)); + /* Program tessellation control: for TS module. */ + VG_LITE_RETURN_ERROR(push_state(&s_context, 0x0A34, 0x01000200 | format | quality | tiling | fill)); + VG_LITE_RETURN_ERROR(push_state(&s_context, 0x0A3B, 0x3F800000)); /* Path tessellation SCALE. */ + VG_LITE_RETURN_ERROR(push_state(&s_context, 0x0A3C, 0x00000000)); /* Path tessellation BIAS. */ + /* Program matrix. */ + VG_LITE_RETURN_ERROR(push_state_ptr(&s_context, 0x0A40, (void *) &matrix->m[0][0])); + VG_LITE_RETURN_ERROR(push_state_ptr(&s_context, 0x0A41, (void *) &matrix->m[0][1])); + VG_LITE_RETURN_ERROR(push_state_ptr(&s_context, 0x0A42, (void *) &matrix->m[0][2])); + VG_LITE_RETURN_ERROR(push_state_ptr(&s_context, 0x0A43, (void *) &matrix->m[1][0])); + VG_LITE_RETURN_ERROR(push_state_ptr(&s_context, 0x0A44, (void *) &matrix->m[1][1])); + VG_LITE_RETURN_ERROR(push_state_ptr(&s_context, 0x0A45, (void *) &matrix->m[1][2])); + + /* Setup tessellation loop. */ + if(path->path_type == VG_LITE_DRAW_FILL_PATH || path->path_type == VG_LITE_DRAW_ZERO || + path->path_type == VG_LITE_DRAW_FILL_STROKE_PATH) { + for(y = point_min.y; y < point_max.y; y += height) { + for(x = point_min.x; x < point_max.x; x += width) { + /* Tessellate path. */ + VG_LITE_RETURN_ERROR(push_stall(&s_context, 15)); + VG_LITE_RETURN_ERROR(push_state(&s_context, 0x0A1B, 0x00011000)); + VG_LITE_RETURN_ERROR(push_state(&s_context, 0x0A01, x | (y << 16))); + VG_LITE_RETURN_ERROR(push_state(&s_context, 0x0A39, x | (y << 16))); + VG_LITE_RETURN_ERROR(push_state(&s_context, 0x0A3D, tessellation_size / 64)); + + if(VLM_PATH_GET_UPLOAD_BIT(*path) == 1) { + VG_LITE_RETURN_ERROR(push_call(&s_context, path->uploaded.address, path->uploaded.bytes)); + } + else { + VG_LITE_RETURN_ERROR(push_data(&s_context, path->path_length, path->path)); + } + } + } + } + /* Setup tessellation loop. */ + if(path->path_type == VG_LITE_DRAW_STROKE_PATH || path->path_type == VG_LITE_DRAW_FILL_STROKE_PATH) { + for(y = point_min.y; y < point_max.y; y += height) { + for(x = point_min.x; x < point_max.x; x += width) { + /* Tessellate path. */ + VG_LITE_RETURN_ERROR(push_stall(&s_context, 15)); + VG_LITE_RETURN_ERROR(push_state(&s_context, 0x0A1B, 0x00011000)); + VG_LITE_RETURN_ERROR(push_state(&s_context, 0x0A01, x | (y << 16))); + VG_LITE_RETURN_ERROR(push_state(&s_context, 0x0A39, x | (y << 16))); + VG_LITE_RETURN_ERROR(push_state(&s_context, 0x0A3D, tessellation_size / 64)); + format = convert_path_format(VG_LITE_FP32); + VG_LITE_RETURN_ERROR(push_state(&s_context, 0x0A34, 0x01000200 | format | quality | tiling | 0x0)); + VG_LITE_RETURN_ERROR(push_state(&s_context, 0x0A02, path->stroke_color)); + + if(VLM_PATH_STROKE_GET_UPLOAD_BIT(*path) == 1) { + VG_LITE_RETURN_ERROR(push_call(&s_context, path->stroke->uploaded.address, path->stroke->uploaded.bytes)); + } + else { + VG_LITE_RETURN_ERROR(push_data(&s_context, path->stroke_size, path->stroke_path)); + } + } + } + } + /* Finialize command buffer. */ + VG_LITE_RETURN_ERROR(push_state(&s_context, 0x0A34, 0)); + + return error; +} + +/* GC355/GC255 vg_lite_draw_pattern API implementation + */ +vg_lite_error_t vg_lite_draw_pattern(vg_lite_buffer_t * target, + vg_lite_path_t * path, + vg_lite_fill_t fill_rule, + vg_lite_matrix_t * path_matrix, + vg_lite_buffer_t * source, + vg_lite_matrix_t * pattern_matrix, + vg_lite_blend_t blend, + vg_lite_pattern_mode_t pattern_mode, + vg_lite_color_t pattern_color, + vg_lite_color_t color, + vg_lite_filter_t filter) +{ + vg_lite_error_t error = VG_LITE_SUCCESS; + uint32_t imageMode; + uint32_t blend_mode; + uint32_t filter_mode = 0; + int32_t dst_align_width; + uint32_t mul, div, align; + uint32_t conversion = 0; + uint32_t tiled_source; + vg_lite_matrix_t matrix; + uint32_t pattern_tile = 0; + uint32_t transparency_mode = 0; + + /* The following code is from "draw path" */ + uint32_t format, quality, tiling, fill; + uint32_t tessellation_size; + + vg_lite_point_t point_min = {0}, point_max = {0}, temp = {0}; + int x, y, width, height; + uint8_t ts_is_fullscreen = 0; + uint32_t in_premult = 0; + uint32_t src_premultiply_enable = 0; + uint32_t paintType = 0; + uint32_t premul_flag = 0; + uint32_t prediv_flag = 0; + uint8_t lvgl_sw_blend = 0; + +#if(CHIPID == 0X355) + uint8_t * path_re = NULL; + uint32_t index = 0; +#endif +#if gcFEATURE_VG_TRACE_API + VGLITE_LOG("vg_lite_draw_pattern %p %p %d %p %p %p %d %d 0x%08X %d\n", + target, path, fill_rule, path_matrix, source, pattern_matrix, blend, pattern_mode, pattern_color, filter); +#endif + +#if gcFEATURE_VG_ERROR_CHECK +#if !gcFEATURE_VG_QUALITY_8X + if(path->quality == VG_LITE_UPPER) { + return VG_LITE_NOT_SUPPORT; + } +#endif + if(source->format == VG_LITE_A4 || source->format == VG_LITE_A8) { + return VG_LITE_NOT_SUPPORT; + } + if(!path || !path->path) { + return VG_LITE_INVALID_ARGUMENT; + } +#if (CHIPID == 0x355) + if(target->format == VG_LITE_L8 || target->format == VG_LITE_YUYV || + target->format == VG_LITE_BGRA2222 || target->format == VG_LITE_RGBA2222 || + target->format == VG_LITE_ABGR2222 || target->format == VG_LITE_ARGB2222) { + printf("Target format: 0x%x is not supported.\n", target->format); + return VG_LITE_NOT_SUPPORT; + } +#endif +#endif /* gcFEATURE_VG_ERROR_CHECK */ + +#if !gcFEATURE_VG_LVGL_SUPPORT + if(blend >= VG_LITE_BLEND_NORMAL_LVGL && blend <= VG_LITE_BLEND_MULTIPLY_LVGL) { + if(!source->lvgl_buffer) { + source->lvgl_buffer = (vg_lite_buffer_t *)vg_lite_os_malloc(sizeof(vg_lite_buffer_t)); + *source->lvgl_buffer = *source; + source->lvgl_buffer->lvgl_buffer = NULL; + vg_lite_allocate(source->lvgl_buffer); + } + /* Make sure render target is up to date before reading RT. */ + vg_lite_finish(); + setup_lvgl_image(target, source, source->lvgl_buffer, blend); + blend = VG_LITE_BLEND_SRC_OVER; + lvgl_sw_blend = 1; + } +#endif + + if(!path->path_length) { + return VG_LITE_SUCCESS; + } + + if(!path_matrix) { + path_matrix = &identity_mtx; + } + if(!pattern_matrix) { + pattern_matrix = &identity_mtx; + } + + /* Work on pattern states. */ + matrix = *pattern_matrix; + if(source->paintType == VG_LITE_PAINT_PATTERN) { + matrix.m[2][0] = 0; + matrix.m[2][1] = 0; + matrix.m[2][2] = 1; + source->image_mode = VG_LITE_NONE_IMAGE_MODE; + } + +#if gcFEATURE_VG_GAMMA + save_st_gamma_src_dest(source, target); +#endif + + /*blend input into context*/ + s_context.blend_mode = blend; + in_premult = 0x00000000; + + /* Adjust premultiply setting according to openvg condition */ + src_premultiply_enable = 0x01000100; + if(s_context.color_transform == 0 && s_context.gamma_dst == s_context.gamma_src && s_context.matrix_enable == 0 && + s_context.dst_alpha_mode == 0 && s_context.src_alpha_mode == 0 && + (source->image_mode == VG_LITE_NORMAL_IMAGE_MODE || source->image_mode == 0)) { + prediv_flag = 0; + } + else { + prediv_flag = 1; + } + if((s_context.blend_mode >= OPENVG_BLEND_SRC_OVER && s_context.blend_mode <= OPENVG_BLEND_ADDITIVE) || + source->image_mode == VG_LITE_STENCIL_MODE) { + premul_flag = 1; + } + else { + premul_flag = 0; + } + + if((source->premultiplied == 0 && target->premultiplied == 0 && premul_flag == 0) || + (source->premultiplied == 1 && target->premultiplied == 0 && prediv_flag == 0)) { + src_premultiply_enable = 0x01000100; + in_premult = 0x10000000; + } + /* when src and dst all pre format, im pre_out set to 0 to perform data truncation to prevent data overflow */ + else if(source->premultiplied == 1 && target->premultiplied == 1 && prediv_flag == 0) { + src_premultiply_enable = 0x00000100; + in_premult = 0x00000000; + } + else if((source->premultiplied == 0 && target->premultiplied == 1) || + (source->premultiplied == 0 && target->premultiplied == 0 && premul_flag == 1)) { + src_premultiply_enable = 0x01000100; + in_premult = 0x00000000; + } + else if((source->premultiplied == 1 && target->premultiplied == 1 && prediv_flag == 1) || + (source->premultiplied == 1 && target->premultiplied == 0 && prediv_flag == 1)) { + src_premultiply_enable = 0x00000100; + in_premult = 0x00000000; + } + if((source->format == VG_LITE_A4 || source->format == VG_LITE_A8) && blend >= VG_LITE_BLEND_SRC_OVER && + blend <= VG_LITE_BLEND_SUBTRACT) { + in_premult = 0x00000000; + } + if(blend == VG_LITE_BLEND_NORMAL_LVGL) { + in_premult = 0x00000000; + } + if(source->premultiplied == target->premultiplied && premul_flag == 0) { + target->apply_premult = 1; + } + else { + target->apply_premult = 0; + } + + error = set_render_target(target); + if(error != VG_LITE_SUCCESS) { + return error; + } + else if(error == VG_LITE_NO_CONTEXT) { + /* If scissoring is enabled and no valid scissoring rectangles + are present, no drawing occurs */ + return VG_LITE_SUCCESS; + } + + transparency_mode = (source->transparency_mode == VG_LITE_IMAGE_TRANSPARENT ? 0x8000 : 0); + width = s_context.tessbuf.tess_w_h & 0xFFFF; + height = s_context.tessbuf.tess_w_h >> 16; + get_format_bytes(target->format, &mul, &div, &align); + dst_align_width = target->stride * div / mul; + if(width == 0 || height == 0) + return VG_LITE_NO_CONTEXT; + if((dst_align_width <= width) && (target->height <= height)) { + ts_is_fullscreen = 1; + point_min.x = 0; + point_min.y = 0; + point_max.x = dst_align_width; + point_max.y = target->height; + } + + /* If target is L8 and source is in YUV or RGB (not L8 or A8) then we have to convert RGB into L8. */ + if((target->format == VG_LITE_L8) && ((source->format != VG_LITE_L8) && (source->format != VG_LITE_A8))) { + conversion = 0x80000000; + } + + /* Determine image mode (NORMAL or MULTIPLY) depending on the color. */ + imageMode = (source->image_mode == VG_LITE_NONE_IMAGE_MODE) ? 0 : (source->image_mode == VG_LITE_MULTIPLY_IMAGE_MODE) ? + 0x00002000 : 0x00001000; + tiled_source = (source->tiled != VG_LITE_LINEAR) ? 0x10000000 : 0 ; + + if(pattern_mode == VG_LITE_PATTERN_COLOR) { + uint8_t a, r, g, b; + pattern_tile = 0; + a = pattern_color >> 24; + r = pattern_color >> 16; + g = pattern_color >> 8; + b = pattern_color; + pattern_color = (a << 24) | (b << 16) | (g << 8) | r; + } + else if(pattern_mode == VG_LITE_PATTERN_PAD) { + pattern_tile = 0x1000; + } +#if gcFEATURE_VG_IM_REPEAT_REFLECT + else if(pattern_mode == VG_LITE_PATTERN_REPEAT) { + pattern_tile = 0x2000; + } + else if(pattern_mode == VG_LITE_PATTERN_REFLECT) { + pattern_tile = 0x3000; + } +#endif + else { + return VG_LITE_INVALID_ARGUMENT; + } + + switch(filter) { + case VG_LITE_FILTER_POINT: + filter_mode = 0; + break; + + case VG_LITE_FILTER_LINEAR: + filter_mode = 0x10000; + break; + + case VG_LITE_FILTER_BI_LINEAR: + filter_mode = 0x20000; + break; + + case VG_LITE_FILTER_GAUSSIAN: + filter_mode = 0x30000; + break; + } + + if(source->paintType == VG_LITE_PAINT_PATTERN) { + VG_LITE_RETURN_ERROR(set_interpolation_steps_draw_paint(target, source->width, source->height, &matrix)); + /* enable pre-multiplied in image unit */ + VG_LITE_RETURN_ERROR(push_state(&s_context, 0x0A24, convert_source_format(source->format) | + filter_mode | pattern_tile | conversion | src_premultiply_enable)); + + VG_LITE_RETURN_ERROR(push_state(&s_context, 0x0A26, pattern_color)); + VG_LITE_RETURN_ERROR(push_state(&s_context, 0x0A28, source->address)); + + VG_LITE_RETURN_ERROR(push_state(&s_context, 0x0A2A, source->stride | tiled_source)); + VG_LITE_RETURN_ERROR(push_state(&s_context, 0x0A2C, 0)); + VG_LITE_RETURN_ERROR(push_state(&s_context, 0x0A2E, source->width | (source->height << 16))); + } + else { + VG_LITE_RETURN_ERROR(set_interpolation_steps(target, source->width, source->height, &matrix)); + /* enable pre-multiplied in image unit */ + VG_LITE_RETURN_ERROR(push_state(&s_context, 0x0A25, convert_source_format(source->format) | + filter_mode | pattern_tile | conversion | src_premultiply_enable)); + + VG_LITE_RETURN_ERROR(push_state(&s_context, 0x0A27, pattern_color)); + +#if !gcFEATURE_VG_LVGL_SUPPORT + if(lvgl_sw_blend) { + VG_LITE_RETURN_ERROR(push_state(&s_context, 0x0A29, source->lvgl_buffer->address)); + } + else +#endif + VG_LITE_RETURN_ERROR(push_state(&s_context, 0x0A29, source->address)); + + VG_LITE_RETURN_ERROR(push_state(&s_context, 0x0A2B, source->stride | tiled_source)); + VG_LITE_RETURN_ERROR(push_state(&s_context, 0x0A2D, 0)); + VG_LITE_RETURN_ERROR(push_state(&s_context, 0x0A2F, source->width | (source->height << 16))); + } + + /* Work on path states. */ + matrix = *path_matrix; + + if(ts_is_fullscreen == 0) { + transform(&temp, (vg_lite_float_t)path->bounding_box[0], (vg_lite_float_t)path->bounding_box[1], &matrix); + point_min = point_max = temp; + + transform(&temp, (vg_lite_float_t)path->bounding_box[2], (vg_lite_float_t)path->bounding_box[1], &matrix); + if(temp.x < point_min.x) point_min.x = temp.x; + if(temp.y < point_min.y) point_min.y = temp.y; + if(temp.x > point_max.x) point_max.x = temp.x; + if(temp.y > point_max.y) point_max.y = temp.y; + + transform(&temp, (vg_lite_float_t)path->bounding_box[2], (vg_lite_float_t)path->bounding_box[3], &matrix); + if(temp.x < point_min.x) point_min.x = temp.x; + if(temp.y < point_min.y) point_min.y = temp.y; + if(temp.x > point_max.x) point_max.x = temp.x; + if(temp.y > point_max.y) point_max.y = temp.y; + + transform(&temp, (vg_lite_float_t)path->bounding_box[0], (vg_lite_float_t)path->bounding_box[3], &matrix); + if(temp.x < point_min.x) point_min.x = temp.x; + if(temp.y < point_min.y) point_min.y = temp.y; + if(temp.x > point_max.x) point_max.x = temp.x; + if(temp.y > point_max.y) point_max.y = temp.y; + + point_min.x = MAX(point_min.x, 0); + point_min.y = MAX(point_min.y, 0); + point_max.x = MIN(point_max.x, dst_align_width); + point_max.y = MIN(point_max.y, target->height); + + if(s_context.scissor_set) { + point_min.x = MAX(point_min.x, s_context.scissor[0]); + point_min.y = MAX(point_min.y, s_context.scissor[1]); + point_max.x = MIN(point_max.x, s_context.scissor[0] + s_context.scissor[2]); + point_max.y = MIN(point_max.y, s_context.scissor[1] + s_context.scissor[3]); + } + } + + /* Convert states into hardware values. */ + blend_mode = convert_blend(blend); + format = convert_path_format(path->format); + quality = convert_path_quality(path->quality); + tiling = (s_context.capabilities.cap.tiled == 2) ? 0x2000000 : 0; + fill = (fill_rule == VG_LITE_FILL_EVEN_ODD) ? 0x10 : 0; + tessellation_size = s_context.tessbuf.L2_size ? s_context.tessbuf.L2_size : s_context.tessbuf.L1_size; + + /* Setup the command buffer. */ + /* Program color register. */ + if(source->paintType == VG_LITE_PAINT_PATTERN) { + paintType = 1 << 24 | 1 << 25; + } + /* enable pre-multiplied from VG to VGPE */ + VG_LITE_RETURN_ERROR(push_state(&s_context, 0x0A00, + 0x2 | in_premult | paintType | s_context.capabilities.cap.tiled | imageMode | blend_mode | transparency_mode | + s_context.enable_mask | s_context.scissor_enable | s_context.color_transform | s_context.matrix_enable)); + + VG_LITE_RETURN_ERROR(push_state(&s_context, 0x0A34, 0x01000400 | format | quality | tiling | fill)); + VG_LITE_RETURN_ERROR(push_state(&s_context, 0x0A3B, 0x3F800000)); /* Path tessellation SCALE. */ + VG_LITE_RETURN_ERROR(push_state(&s_context, 0x0A3C, 0x00000000)); /* Path tessellation BIAS. */ + /* Program matrix. */ + VG_LITE_RETURN_ERROR(push_state_ptr(&s_context, 0x0A40, (void *) &matrix.m[0][0])); + VG_LITE_RETURN_ERROR(push_state_ptr(&s_context, 0x0A41, (void *) &matrix.m[0][1])); + VG_LITE_RETURN_ERROR(push_state_ptr(&s_context, 0x0A42, (void *) &matrix.m[0][2])); + VG_LITE_RETURN_ERROR(push_state_ptr(&s_context, 0x0A43, (void *) &matrix.m[1][0])); + VG_LITE_RETURN_ERROR(push_state_ptr(&s_context, 0x0A44, (void *) &matrix.m[1][1])); + VG_LITE_RETURN_ERROR(push_state_ptr(&s_context, 0x0A45, (void *) &matrix.m[1][2])); + + /* Setup tessellation loop. */ + if(path->path_type == VG_LITE_DRAW_FILL_PATH || path->path_type == VG_LITE_DRAW_ZERO || + path->path_type == VG_LITE_DRAW_FILL_STROKE_PATH) { + for(y = point_min.y; y < point_max.y; y += height) { + for(x = point_min.x; x < point_max.x; x += width) { + /* Tessellate path. */ + VG_LITE_RETURN_ERROR(push_stall(&s_context, 15)); + VG_LITE_RETURN_ERROR(push_state(&s_context, 0x0A1B, 0x00011000)); + VG_LITE_RETURN_ERROR(push_state(&s_context, 0x0A01, x | (y << 16))); + VG_LITE_RETURN_ERROR(push_state(&s_context, 0x0A39, x | (y << 16))); + VG_LITE_RETURN_ERROR(push_state(&s_context, 0x0A3D, tessellation_size / 64)); + + if(VLM_PATH_GET_UPLOAD_BIT(*path) == 1) { + VG_LITE_RETURN_ERROR(push_call(&s_context, path->uploaded.address, path->uploaded.bytes)); + } + else { + VG_LITE_RETURN_ERROR(push_data(&s_context, path->path_length, path->path)); + } + } + } + } + /* Setup tessellation loop. */ + if(path->path_type == VG_LITE_DRAW_STROKE_PATH || path->path_type == VG_LITE_DRAW_FILL_STROKE_PATH) { + for(y = point_min.y; y < point_max.y; y += height) { + for(x = point_min.x; x < point_max.x; x += width) { + /* Tessellate path. */ + VG_LITE_RETURN_ERROR(push_stall(&s_context, 15)); + VG_LITE_RETURN_ERROR(push_state(&s_context, 0x0A1B, 0x00011000)); + VG_LITE_RETURN_ERROR(push_state(&s_context, 0x0A01, x | (y << 16))); + VG_LITE_RETURN_ERROR(push_state(&s_context, 0x0A39, x | (y << 16))); + VG_LITE_RETURN_ERROR(push_state(&s_context, 0x0A3D, tessellation_size / 64)); + format = convert_path_format(VG_LITE_FP32); + VG_LITE_RETURN_ERROR(push_state(&s_context, 0x0A34, 0x01000200 | format | quality | tiling | 0x0)); + VG_LITE_RETURN_ERROR(push_state(&s_context, 0x0A02, path->stroke_color)); + + if(VLM_PATH_STROKE_GET_UPLOAD_BIT(*path) == 1) { + VG_LITE_RETURN_ERROR(push_call(&s_context, path->stroke->uploaded.address, path->stroke->uploaded.bytes)); + } + else { + VG_LITE_RETURN_ERROR(push_data(&s_context, path->stroke_size, path->stroke_path)); + } + } + } + } + + /* Finialize command buffer. */ + VG_LITE_RETURN_ERROR(push_state(&s_context, 0x0A34, 0)); + vglitemDUMP_BUFFER("image", (size_t)source->address, source->memory, 0, (source->stride) * (source->height)); + + return error; +} + +/* GC355/GC255 vg_lite_draw_linear_grad API implementation + */ +vg_lite_error_t vg_lite_draw_linear_grad(vg_lite_buffer_t * target, + vg_lite_path_t * path, + vg_lite_fill_t fill_rule, + vg_lite_matrix_t * path_matrix, + vg_lite_linear_gradient_ext_t * grad, + vg_lite_color_t paint_color, + vg_lite_blend_t blend, + vg_lite_filter_t filter) +{ + vg_lite_error_t error = VG_LITE_SUCCESS; + uint32_t image_mode; + uint32_t blend_mode; + uint32_t filter_mode = 0; + uint32_t conversion = 0; + uint32_t tiled_source; + int32_t dst_align_width; + uint32_t mul, div, align; + vg_lite_matrix_t inverse_matrix; + vg_lite_buffer_t * source = &grad->image; + vg_lite_matrix_t * matrix = &grad->matrix; + uint32_t linear_tile = 0; + uint32_t transparency_mode = 0; + uint32_t in_premult = 0; + uint32_t src_premultiply_enable = 0; + uint32_t premul_flag = 0; + uint32_t prediv_flag = 0; + void * data; + + /* The following code is from "draw path" */ + uint32_t format, quality, tiling, fill; + uint32_t tessellation_size; + + vg_lite_kernel_allocate_t memory; + vg_lite_kernel_free_t free_memory; + uint32_t return_offset = 0; + + vg_lite_point_t point_min = {0}, point_max = {0}, temp = {0}; + int x, y, width, height; + uint8_t ts_is_fullscreen = 0; + + vg_lite_float_t dx, dy, dxdx_dydy; + vg_lite_float_t lg_step_x_lin, lg_step_y_lin, lg_constant_lin; + +#if(CHIPID == 0X355) + uint8_t * path_re = NULL; + uint32_t index = 0; +#endif +#if gcFEATURE_VG_TRACE_API + VGLITE_LOG("vg_lite_draw_linear_grad %p %p %d %p %p 0x%08X %d %d\n", + target, path, fill_rule, path_matrix, grad, paint_color, blend, filter); +#endif + +#if gcFEATURE_VG_ERROR_CHECK +#if !gcFEATURE_VG_LVGL_SUPPORT + if(blend >= VG_LITE_BLEND_NORMAL_LVGL && blend <= VG_LITE_BLEND_MULTIPLY_LVGL) { + return VG_LITE_NOT_SUPPORT; + } +#endif +#if !gcFEATURE_VG_QUALITY_8X + if(path->quality == VG_LITE_UPPER) { + return VG_LITE_NOT_SUPPORT; + } +#endif + if(source->format == VG_LITE_A4 || source->format == VG_LITE_A8) { + return VG_LITE_NOT_SUPPORT; + } + if(!path || !path->path) { + return VG_LITE_INVALID_ARGUMENT; + } +#if (CHIPID == 0x355) + if(target->format == VG_LITE_L8 || target->format == VG_LITE_YUYV || + target->format == VG_LITE_BGRA2222 || target->format == VG_LITE_RGBA2222 || + target->format == VG_LITE_ABGR2222 || target->format == VG_LITE_ARGB2222) { + printf("Target format: 0x%x is not supported.\n", target->format); + return VG_LITE_NOT_SUPPORT; + } +#endif +#endif /* gcFEATURE_VG_ERROR_CHECK */ + + if(!path_matrix) { + path_matrix = &identity_mtx; + } + +#if gcFEATURE_VG_GAMMA + set_gamma_dest_only(target, VGL_TRUE); +#endif + + /*blend input into context*/ + s_context.blend_mode = blend; + + src_premultiply_enable = 0x01000100; + if(s_context.color_transform == 0 && s_context.gamma_dst == s_context.gamma_src && s_context.matrix_enable == 0 && + s_context.dst_alpha_mode == 0 && s_context.src_alpha_mode == 0 && + (source->image_mode == VG_LITE_NORMAL_IMAGE_MODE || source->image_mode == 0)) { + prediv_flag = 0; + } + else { + prediv_flag = 1; + } + if((s_context.blend_mode >= OPENVG_BLEND_SRC_OVER && s_context.blend_mode <= OPENVG_BLEND_ADDITIVE) || + source->image_mode == VG_LITE_STENCIL_MODE) { + premul_flag = 1; + } + else { + premul_flag = 0; + } + + if((source->premultiplied == 0 && target->premultiplied == 0 && premul_flag == 0) || + (source->premultiplied == 1 && target->premultiplied == 0 && prediv_flag == 0)) { + src_premultiply_enable = 0x01000100; + in_premult = 0x10000000; + } + /* when src and dst all pre format, im pre_out set to 0 to perform data truncation to prevent data overflow */ + else if(source->premultiplied == 1 && target->premultiplied == 1 && prediv_flag == 0) { + src_premultiply_enable = 0x00000100; + in_premult = 0x00000000; + } + else if((source->premultiplied == 0 && target->premultiplied == 1) || + (source->premultiplied == 0 && target->premultiplied == 0 && premul_flag == 1)) { + src_premultiply_enable = 0x01000100; + in_premult = 0x00000000; + } + else if((source->premultiplied == 1 && target->premultiplied == 1 && prediv_flag == 1) || + (source->premultiplied == 1 && target->premultiplied == 0 && prediv_flag == 1)) { + src_premultiply_enable = 0x00000100; + in_premult = 0x00000000; + } + if((source->format == VG_LITE_A4 || source->format == VG_LITE_A8) && blend >= VG_LITE_BLEND_SRC_OVER && + blend <= VG_LITE_BLEND_SUBTRACT) { +#if (CHIPID==0x255) + src_premultiply_enable = 0x00000000; +#endif + in_premult = 0x00000000; + } + if(blend == VG_LITE_BLEND_NORMAL_LVGL) { + in_premult = 0x00000000; + } + if(source->premultiplied == target->premultiplied && premul_flag == 0) { + target->apply_premult = 1; + } + else { + target->apply_premult = 0; + } + + error = set_render_target(target); + if(error != VG_LITE_SUCCESS) { + return error; + } + else if(error == VG_LITE_NO_CONTEXT) { + /* If scissoring is enabled and no valid scissoring rectangles + are present, no drawing occurs */ + return VG_LITE_SUCCESS; + } + + transparency_mode = (source->transparency_mode == VG_LITE_IMAGE_TRANSPARENT ? 0x8000 : 0); + width = s_context.tessbuf.tess_w_h & 0xFFFF; + height = s_context.tessbuf.tess_w_h >> 16; + get_format_bytes(target->format, &mul, &div, &align); + dst_align_width = target->stride * div / mul; + if(width == 0 || height == 0) + return VG_LITE_NO_CONTEXT; + if((dst_align_width <= width) && (target->height <= height)) { + ts_is_fullscreen = 1; + point_min.x = 0; + point_min.y = 0; + point_max.x = dst_align_width; + point_max.y = target->height; + } + + /* If target is L8 and source is in YUV or RGB (not L8 or A8) then we have to convert RGB into L8. */ + if((target->format == VG_LITE_L8) && ((source->format != VG_LITE_L8) && (source->format != VG_LITE_A8))) { + conversion = 0x80000000; + } + + /* Determine image mode (NORMAL or MULTIPLY) depending on the color. */ + image_mode = (source->image_mode == VG_LITE_NONE_IMAGE_MODE) ? 0 : (source->image_mode == VG_LITE_MULTIPLY_IMAGE_MODE) ? + 0x00002000 : 0x00001000; + tiled_source = (source->tiled != VG_LITE_LINEAR) ? 0x10000000 : 0 ; + + switch(grad->spread_mode) { + case VG_LITE_GRADIENT_SPREAD_FILL: + linear_tile = 0x0; + break; + + case VG_LITE_GRADIENT_SPREAD_PAD: + linear_tile = 0x1000; + break; + + case VG_LITE_GRADIENT_SPREAD_REPEAT: + linear_tile = 0x2000; + break; + + case VG_LITE_GRADIENT_SPREAD_REFLECT: + linear_tile = 0x3000; + break; + } + + switch(filter) { + case VG_LITE_FILTER_POINT: + filter_mode = 0; + break; + + case VG_LITE_FILTER_LINEAR: + filter_mode = 0x10000; + break; + + case VG_LITE_FILTER_BI_LINEAR: + filter_mode = 0x20000; + break; + + case VG_LITE_FILTER_GAUSSIAN: + filter_mode = 0x30000; + break; + } + + if(grad->spread_mode == VG_LITE_GRADIENT_SPREAD_FILL) { + uint8_t a, r, g, b; + a = paint_color >> 24; + r = paint_color >> 16; + g = paint_color >> 8; + b = paint_color; + paint_color = (a << 24) | (b << 16) | (g << 8) | r; + } + + /* compute radial gradient paremeters */ + + /* Compute inverse matrix. */ + if(!inverse(&inverse_matrix, matrix)) + return VG_LITE_INVALID_ARGUMENT; + + dx = grad->linear_grad.X1 - grad->linear_grad.X0; + dy = grad->linear_grad.Y1 - grad->linear_grad.Y0; + dxdx_dydy = dx * dx + dy * dy; + + /* + ** dx (T(x) - x0) + dy (T(y) - y0) + ** g = ------------------------------- + ** dx^2 + dy^2 + ** + ** where + ** + ** dx := x1 - x0 + ** dy := y1 - y1 + ** T(x) := (x + 0.5) m00 + (y + 0.5) m01 + m02 + ** = x m00 + y m01 + 0.5 (m00 + m01) + m02 + ** T(y) := (x + 0.5) m10 + (y + 0.5) m11 + m12 + ** = x m10 + y m11 + 0.5 (m10 + m11) + m12. + ** + ** We can factor the top line into: + ** + ** = dx (x m00 + y m01 + 0.5 (m00 + m01) + m02 - x0) + ** + dy (x m10 + y m11 + 0.5 (m10 + m11) + m12 - y0) + ** + ** = x (dx m00 + dy m10) + ** + y (dx m01 + dy m11) + ** + dx (0.5 (m00 + m01) + m02 - x0) + ** + dy (0.5 (m10 + m11) + m12 - y0). + */ + + lg_step_x_lin + = (dx * MAT(&inverse_matrix, 0, 0) + dy * MAT(&inverse_matrix, 1, 0)) + / dxdx_dydy; + + lg_step_y_lin + = (dx * MAT(&inverse_matrix, 0, 1) + dy * MAT(&inverse_matrix, 1, 1)) + / dxdx_dydy; + + lg_constant_lin = + ( + ( + 0.5f * (MAT(&inverse_matrix, 0, 0) + MAT(&inverse_matrix, 0, 1)) + + MAT(&inverse_matrix, 0, 2) - grad->linear_grad.X0 + ) * dx + + + + + ( + 0.5f * (MAT(&inverse_matrix, 1, 0) + MAT(&inverse_matrix, 1, 1)) + + MAT(&inverse_matrix, 1, 2) - grad->linear_grad.Y0 + ) * dy + ) + / dxdx_dydy; + + /* Setup the command buffer. */ + + /* linear gradient parameters*/ + data = &lg_constant_lin; + VG_LITE_RETURN_ERROR(push_state(&s_context, 0x0A04, *(uint32_t *) data)); + data = &lg_step_x_lin; + VG_LITE_RETURN_ERROR(push_state(&s_context, 0x0A06, *(uint32_t *) data)); + data = &lg_step_y_lin; + VG_LITE_RETURN_ERROR(push_state(&s_context, 0x0A08, *(uint32_t *) data)); + + VG_LITE_RETURN_ERROR(set_interpolation_steps(target, source->width, source->height, matrix)); + + /* enable pre-multiplied in image unit */ + VG_LITE_RETURN_ERROR(push_state(&s_context, 0x0A24, convert_source_format(source->format) | + filter_mode | linear_tile | conversion | src_premultiply_enable)); + + VG_LITE_RETURN_ERROR(push_state(&s_context, 0x0A26, paint_color)); + VG_LITE_RETURN_ERROR(push_state(&s_context, 0x0A28, source->address)); + + VG_LITE_RETURN_ERROR(push_state(&s_context, 0x0A2A, tiled_source)); + VG_LITE_RETURN_ERROR(push_state(&s_context, 0x0A2C, 0)); + VG_LITE_RETURN_ERROR(push_state(&s_context, 0x0A2E, source->width)); + + /* Work on path states. */ + matrix = path_matrix; + + if(ts_is_fullscreen == 0) { + transform(&temp, (vg_lite_float_t)path->bounding_box[0], (vg_lite_float_t)path->bounding_box[1], matrix); + point_min = point_max = temp; + + transform(&temp, (vg_lite_float_t)path->bounding_box[2], (vg_lite_float_t)path->bounding_box[1], matrix); + if(temp.x < point_min.x) point_min.x = temp.x; + if(temp.y < point_min.y) point_min.y = temp.y; + if(temp.x > point_max.x) point_max.x = temp.x; + if(temp.y > point_max.y) point_max.y = temp.y; + + transform(&temp, (vg_lite_float_t)path->bounding_box[2], (vg_lite_float_t)path->bounding_box[3], matrix); + if(temp.x < point_min.x) point_min.x = temp.x; + if(temp.y < point_min.y) point_min.y = temp.y; + if(temp.x > point_max.x) point_max.x = temp.x; + if(temp.y > point_max.y) point_max.y = temp.y; + + transform(&temp, (vg_lite_float_t)path->bounding_box[0], (vg_lite_float_t)path->bounding_box[3], matrix); + if(temp.x < point_min.x) point_min.x = temp.x; + if(temp.y < point_min.y) point_min.y = temp.y; + if(temp.x > point_max.x) point_max.x = temp.x; + if(temp.y > point_max.y) point_max.y = temp.y; + + point_min.x = MAX(point_min.x, 0); + point_min.y = MAX(point_min.y, 0); + point_max.x = MIN(point_max.x, dst_align_width); + point_max.y = MIN(point_max.y, target->height); + + if(s_context.scissor_set) { + point_min.x = MAX(point_min.x, s_context.scissor[0]); + point_min.y = MAX(point_min.y, s_context.scissor[1]); + point_max.x = MIN(point_max.x, s_context.scissor[0] + s_context.scissor[2]); + point_max.y = MIN(point_max.y, s_context.scissor[1] + s_context.scissor[3]); + } + } + + /* Convert states into hardware values. */ + blend_mode = convert_blend(blend); + format = convert_path_format(path->format); + quality = convert_path_quality(path->quality); + tiling = (s_context.capabilities.cap.tiled == 2) ? 0x2000000 : 0; + fill = (fill_rule == VG_LITE_FILL_EVEN_ODD) ? 0x10 : 0; + tessellation_size = s_context.tessbuf.L2_size ? s_context.tessbuf.L2_size : s_context.tessbuf.L1_size; + + /* Setup the command buffer. */ + /* Program color register. */ + + /* enable pre-multiplied from VG to VGPE */ + VG_LITE_RETURN_ERROR(push_state(&s_context, 0x0A00, + 0x01000002 | s_context.capabilities.cap.tiled | in_premult | image_mode | blend_mode | transparency_mode | + s_context.enable_mask | s_context.scissor_enable | s_context.color_transform | s_context.matrix_enable)); + + VG_LITE_RETURN_ERROR(push_state(&s_context, 0x0A34, 0x01000400 | format | quality | tiling | fill)); + VG_LITE_RETURN_ERROR(push_state(&s_context, 0x0A3B, 0x3F800000)); /* Path tessellation SCALE. */ + VG_LITE_RETURN_ERROR(push_state(&s_context, 0x0A3C, 0x00000000)); /* Path tessellation BIAS. */ + /* Program matrix. */ + VG_LITE_RETURN_ERROR(push_state_ptr(&s_context, 0x0A40, (void *) &matrix->m[0][0])); + VG_LITE_RETURN_ERROR(push_state_ptr(&s_context, 0x0A41, (void *) &matrix->m[0][1])); + VG_LITE_RETURN_ERROR(push_state_ptr(&s_context, 0x0A42, (void *) &matrix->m[0][2])); + VG_LITE_RETURN_ERROR(push_state_ptr(&s_context, 0x0A43, (void *) &matrix->m[1][0])); + VG_LITE_RETURN_ERROR(push_state_ptr(&s_context, 0x0A44, (void *) &matrix->m[1][1])); + VG_LITE_RETURN_ERROR(push_state_ptr(&s_context, 0x0A45, (void *) &matrix->m[1][2])); + + if(VLM_PATH_GET_UPLOAD_BIT(*path) == 1) { + if(path->path_changed != 0) { + if(path->uploaded.handle != NULL) { + free_memory.memory_handle = path->uploaded.handle; + vg_lite_kernel(VG_LITE_FREE, &free_memory); + path->uploaded.address = 0; + path->uploaded.memory = NULL; + path->uploaded.handle = NULL; + } + /* Allocate memory for the path data. */ + memory.bytes = 16 + VG_LITE_ALIGN(path->path_length, 8); + return_offset = (8 + VG_LITE_ALIGN(path->path_length, 8)) / 4; + memory.contiguous = 1; + VG_LITE_RETURN_ERROR(vg_lite_kernel(VG_LITE_ALLOCATE, &memory)); + ((uint64_t *) memory.memory)[(path->path_length + 7) / 8] = 0; + ((uint32_t *) memory.memory)[0] = VG_LITE_DATA((path->path_length + 7) / 8); + ((uint32_t *) memory.memory)[1] = 0; + memcpy((uint8_t *) memory.memory + 8, path->path, path->path_length); + ((uint32_t *) memory.memory)[return_offset] = VG_LITE_RETURN(); + ((uint32_t *) memory.memory)[return_offset + 1] = 0; + + path->uploaded.handle = memory.memory_handle; + path->uploaded.memory = memory.memory; + path->uploaded.address = memory.memory_gpu; + path->uploaded.bytes = memory.bytes; + path->path_changed = 0; + } + } + + /* Setup tessellation loop. */ + if(path->path_type == VG_LITE_DRAW_FILL_PATH || path->path_type == VG_LITE_DRAW_ZERO) { + for(y = point_min.y; y < point_max.y; y += height) { + for(x = point_min.x; x < point_max.x; x += width) { + /* Tessellate path. */ + VG_LITE_RETURN_ERROR(push_stall(&s_context, 15)); + VG_LITE_RETURN_ERROR(push_state(&s_context, 0x0A1B, 0x00011000)); + VG_LITE_RETURN_ERROR(push_state(&s_context, 0x0A01, x | (y << 16))); + VG_LITE_RETURN_ERROR(push_state(&s_context, 0x0A39, x | (y << 16))); + VG_LITE_RETURN_ERROR(push_state(&s_context, 0x0A3D, tessellation_size / 64)); + + if(VLM_PATH_GET_UPLOAD_BIT(*path) == 1) { + VG_LITE_RETURN_ERROR(push_call(&s_context, path->uploaded.address, path->uploaded.bytes)); + } + else { + VG_LITE_RETURN_ERROR(push_data(&s_context, path->path_length, path->path)); + } + } + } + } + /* Setup tessellation loop. */ + if(path->path_type == VG_LITE_DRAW_STROKE_PATH || path->path_type == VG_LITE_DRAW_FILL_STROKE_PATH) { + for(y = point_min.y; y < point_max.y; y += height) { + for(x = point_min.x; x < point_max.x; x += width) { + /* Tessellate path. */ + VG_LITE_RETURN_ERROR(push_stall(&s_context, 15)); + VG_LITE_RETURN_ERROR(push_state(&s_context, 0x0A1B, 0x00011000)); + VG_LITE_RETURN_ERROR(push_state(&s_context, 0x0A01, x | (y << 16))); + VG_LITE_RETURN_ERROR(push_state(&s_context, 0x0A39, x | (y << 16))); + VG_LITE_RETURN_ERROR(push_state(&s_context, 0x0A3D, tessellation_size / 64)); + format = convert_path_format(VG_LITE_FP32); + VG_LITE_RETURN_ERROR(push_state(&s_context, 0x0A34, 0x01000200 | format | quality | tiling | 0x0)); + VG_LITE_RETURN_ERROR(push_state(&s_context, 0x0A02, path->stroke_color)); + + if(VLM_PATH_STROKE_GET_UPLOAD_BIT(*path) == 1) { + VG_LITE_RETURN_ERROR(push_call(&s_context, path->stroke->uploaded.address, path->stroke->uploaded.bytes)); + } + else { + VG_LITE_RETURN_ERROR(push_data(&s_context, path->stroke_size, path->stroke_path)); + } + } + } + } + + /* Finialize command buffer. */ + VG_LITE_RETURN_ERROR(push_state(&s_context, 0x0A34, 0)); + + return error; +} + +/* GC355/GC255 vg_lite_draw_radial_grad API implementation + */ +vg_lite_error_t vg_lite_draw_radial_grad(vg_lite_buffer_t * target, + vg_lite_path_t * path, + vg_lite_fill_t fill_rule, + vg_lite_matrix_t * path_matrix, + vg_lite_radial_gradient_t * grad, + vg_lite_color_t paint_color, + vg_lite_blend_t blend, + vg_lite_filter_t filter) +{ + vg_lite_error_t error = VG_LITE_SUCCESS; + uint32_t imageMode; + uint32_t blend_mode; + uint32_t filter_mode = 0; + uint32_t conversion = 0; + uint32_t tiled_source; + int32_t dst_align_width; + uint32_t mul, div, align; + vg_lite_matrix_t inverse_matrix; + vg_lite_buffer_t * source = &grad->image; + vg_lite_matrix_t * matrix = &grad->matrix; + uint32_t rad_tile = 0; + uint32_t transparency_mode = 0; + uint32_t in_premult = 0; + uint32_t src_premultiply_enable = 0; + uint32_t premul_flag = 0; + uint32_t prediv_flag = 0; + void * data; + + /* The following code is from "draw path" */ + uint32_t format, quality, tiling, fill; + uint32_t tessellation_size; + + vg_lite_kernel_allocate_t memory; + vg_lite_kernel_free_t free_memory; + uint32_t return_offset = 0; + + vg_lite_point_t point_min = {0}, point_max = {0}, temp = {0}; + int x, y, width, height; + uint8_t ts_is_fullscreen = 0; + + vg_lite_float_t radius; + + vg_lite_float_t centerX, centerY; + vg_lite_float_t focalX, focalY; + vg_lite_float_t fx, fy; + vg_lite_float_t fxfy_2; + vg_lite_float_t radius2; + vg_lite_float_t r2_fx2, r2_fy2; + vg_lite_float_t r2_fx2_2, r2_fy2_2; + vg_lite_float_t r2_fx2_fy2; + vg_lite_float_t r2_fx2_fy2sq; + vg_lite_float_t cx, cy; + + vg_lite_float_t rgConstantLin, rgStepXLin, rgStepYLin; + vg_lite_float_t rgConstantRad, rgStepXRad, rgStepYRad; + vg_lite_float_t rgStepXXRad, rgStepYYRad, rgStepXYRad; +#if(CHIPID == 0X355) + uint8_t * path_re = NULL; + uint32_t index = 0; +#endif +#if gcFEATURE_VG_TRACE_API + VGLITE_LOG("vg_lite_draw_radial_grad %p %p %d %p %p 0x%08X %d %d\n", + target, path, fill_rule, path_matrix, grad, paint_color, blend, filter); +#endif + +#if gcFEATURE_VG_ERROR_CHECK +#if !gcFEATURE_VG_LVGL_SUPPORT + if(blend >= VG_LITE_BLEND_NORMAL_LVGL && blend <= VG_LITE_BLEND_MULTIPLY_LVGL) { + return VG_LITE_NOT_SUPPORT; + } +#endif +#if !gcFEATURE_VG_QUALITY_8X + if(path->quality == VG_LITE_UPPER) { + return VG_LITE_NOT_SUPPORT; + } +#endif + if(source->format == VG_LITE_A4 || source->format == VG_LITE_A8) { + return VG_LITE_NOT_SUPPORT; + } + if(!path || !path->path) { + return VG_LITE_INVALID_ARGUMENT; + } +#if (CHIPID == 0x355) + if(target->format == VG_LITE_L8 || target->format == VG_LITE_YUYV || + target->format == VG_LITE_BGRA2222 || target->format == VG_LITE_RGBA2222 || + target->format == VG_LITE_ABGR2222 || target->format == VG_LITE_ARGB2222) { + printf("Target format: 0x%x is not supported.\n", target->format); + return VG_LITE_NOT_SUPPORT; + } +#endif + radius = grad->radial_grad.r; + if(radius < 0) { + return VG_LITE_INVALID_ARGUMENT; + } + VG_LITE_RETURN_ERROR(check_compress(source->format, source->compress_mode, source->tiled, source->width, + source->height)); +#endif /* gcFEATURE_VG_ERROR_CHECK */ + + if(!path->path_length) { + return VG_LITE_SUCCESS; + } + + if(!path_matrix) { + path_matrix = &identity_mtx; + } + +#if gcFEATURE_VG_GAMMA + set_gamma_dest_only(target, VGL_TRUE); +#endif + + /*blend input into context*/ + s_context.blend_mode = blend; + + src_premultiply_enable = 0x01000100; + if(s_context.color_transform == 0 && s_context.gamma_dst == s_context.gamma_src && s_context.matrix_enable == 0 && + s_context.dst_alpha_mode == 0 && s_context.src_alpha_mode == 0 && + (source->image_mode == VG_LITE_NORMAL_IMAGE_MODE || source->image_mode == 0)) { + prediv_flag = 0; + } + else { + prediv_flag = 1; + } + if((s_context.blend_mode >= OPENVG_BLEND_SRC_OVER && s_context.blend_mode <= OPENVG_BLEND_ADDITIVE) || + source->image_mode == VG_LITE_STENCIL_MODE) { + premul_flag = 1; + } + else { + premul_flag = 0; + } + + if((source->premultiplied == 0 && target->premultiplied == 0 && premul_flag == 0) || + (source->premultiplied == 1 && target->premultiplied == 0 && prediv_flag == 0)) { + src_premultiply_enable = 0x01000100; + in_premult = 0x10000000; + } + /* when src and dst all pre format, im pre_out set to 0 to perform data truncation to prevent data overflow */ + else if(source->premultiplied == 1 && target->premultiplied == 1 && prediv_flag == 0) { + src_premultiply_enable = 0x00000100; + in_premult = 0x00000000; + } + else if((source->premultiplied == 0 && target->premultiplied == 1) || + (source->premultiplied == 0 && target->premultiplied == 0 && premul_flag == 1)) { + src_premultiply_enable = 0x01000100; + in_premult = 0x00000000; + } + else if((source->premultiplied == 1 && target->premultiplied == 1 && prediv_flag == 1) || + (source->premultiplied == 1 && target->premultiplied == 0 && prediv_flag == 1)) { + src_premultiply_enable = 0x00000100; + in_premult = 0x00000000; + } + if((source->format == VG_LITE_A4 || source->format == VG_LITE_A8) && blend >= VG_LITE_BLEND_SRC_OVER && + blend <= VG_LITE_BLEND_SUBTRACT) { +#if (CHIPID==0x255) + src_premultiply_enable = 0x00000000; +#endif + in_premult = 0x00000000; + } + if(blend == VG_LITE_BLEND_NORMAL_LVGL) { + in_premult = 0x00000000; + } + if(source->premultiplied == target->premultiplied && premul_flag == 0) { + target->apply_premult = 1; + } + else { + target->apply_premult = 0; + } + + error = set_render_target(target); + if(error != VG_LITE_SUCCESS) { + return error; + } + else if(error == VG_LITE_NO_CONTEXT) { + /* If scissoring is enabled and no valid scissoring rectangles + are present, no drawing occurs */ + return VG_LITE_SUCCESS; + } + + transparency_mode = (source->transparency_mode == VG_LITE_IMAGE_TRANSPARENT ? 0x8000 : 0); + width = s_context.tessbuf.tess_w_h & 0xFFFF; + height = s_context.tessbuf.tess_w_h >> 16; + get_format_bytes(target->format, &mul, &div, &align); + dst_align_width = target->stride * div / mul; + if(width == 0 || height == 0) + return VG_LITE_NO_CONTEXT; + if((dst_align_width <= width) && (target->height <= height)) { + ts_is_fullscreen = 1; + point_min.x = 0; + point_min.y = 0; + point_max.x = dst_align_width; + point_max.y = target->height; + } + + /* If target is L8 and source is in YUV or RGB (not L8 or A8) then we have to convert RGB into L8. */ + if((target->format == VG_LITE_L8) && ((source->format != VG_LITE_L8) && (source->format != VG_LITE_A8))) { + conversion = 0x80000000; + } + + /* Determine image mode (NORMAL or MULTIPLY) depending on the color. */ + imageMode = (source->image_mode == VG_LITE_NONE_IMAGE_MODE) ? 0 : (source->image_mode == VG_LITE_MULTIPLY_IMAGE_MODE) ? + 0x00002000 : 0x00001000; + tiled_source = (source->tiled != VG_LITE_LINEAR) ? 0x10000000 : 0 ; + + switch(grad->spread_mode) { + case VG_LITE_GRADIENT_SPREAD_FILL: + rad_tile = 0x0; + break; + + case VG_LITE_GRADIENT_SPREAD_PAD: + rad_tile = 0x1000; + break; + + case VG_LITE_GRADIENT_SPREAD_REPEAT: + rad_tile = 0x2000; + break; + + case VG_LITE_GRADIENT_SPREAD_REFLECT: + rad_tile = 0x3000; + break; + } + + switch(filter) { + case VG_LITE_FILTER_POINT: + filter_mode = 0; + break; + + case VG_LITE_FILTER_LINEAR: + filter_mode = 0x10000; + break; + + case VG_LITE_FILTER_BI_LINEAR: + filter_mode = 0x20000; + break; + + case VG_LITE_FILTER_GAUSSIAN: + filter_mode = 0x30000; + break; + } + + if(grad->spread_mode == VG_LITE_GRADIENT_SPREAD_FILL) { + uint8_t a, r, g, b; + a = paint_color >> 24; + r = paint_color >> 16; + g = paint_color >> 8; + b = paint_color; + paint_color = (a << 24) | (b << 16) | (g << 8) | r; + } + + /* compute radial gradient paremeters */ + + /* Compute inverse matrix. */ + if(!inverse(&inverse_matrix, matrix)) + return VG_LITE_INVALID_ARGUMENT; + + /* Make shortcuts to the gradient information. */ + centerX = grad->radial_grad.cx; + centerY = grad->radial_grad.cy; + focalX = grad->radial_grad.fx; + focalY = grad->radial_grad.fy; + + /* Compute constants of the equation. */ + fx = focalX - centerX; + fy = focalY - centerY; + radius2 = radius * radius; + if(fx * fx + fy * fy > radius2) { + /* If the focal point is outside the circle, let's move it + to inside the circle. Per vg11 spec pg125 "If (fx, fy) lies outside ... + For here, we set it at 0.9 ratio to the center. + */ + vg_lite_float_t fr = (vg_lite_float_t)sqrt(fx * fx + fy * fy); + fx = radius * fx / fr * 0.9f; + fy = radius * fy / fr * 0.9f; + focalX = grad->radial_grad.fx + fx; + focalY = grad->radial_grad.fy + fy; + } + + fxfy_2 = 2.0f * fx * fy; + r2_fx2 = radius2 - fx * fx; + r2_fy2 = radius2 - fy * fy; + r2_fx2_2 = 2.0f * r2_fx2; + r2_fy2_2 = 2.0f * r2_fy2; + r2_fx2_fy2 = r2_fx2 - fy * fy; + r2_fx2_fy2sq = r2_fx2_fy2 * r2_fx2_fy2; + + /* _____________________________________ + ** dx fx + dy fy + \/r^2 (dx^2 + dy^2) - (dx fy - dy fx)^2 + ** g = ------------------------------------------------------- + ** r^2 - fx^2 - fy^2 + ** + ** Where + ** + ** dx := F(x) - focalX + ** dy := F(y) - focalY + ** fx := focalX - centerX + ** fy := focalX - centerY + ** + ** and + ** + ** F(x) := (x + 0.5) m00 + (y + 0.5) m01 + m02 + ** F(y) := (x + 0.5) m10 + (y + 0.5) m11 + m12 + ** + ** So, dx can be factored into + ** + ** dx = (x + 0.5) m00 + (y + 0.5) m01 + m02 - focalX + ** = x m00 + y m01 + 0.5 m00 + 0.5 m01 + m02 - focalX + ** + ** = x m00 + y m01 + cx + ** + ** where + ** + ** cx := 0.5 m00 + 0.5 m01 + m02 - focalX + ** + ** The same way we can factor dy into + ** + ** dy = x m10 + y m11 + cy + ** + ** where + ** + ** cy := 0.5 m10 + 0.5 m11 + m12 - focalY. + ** + ** Now we can rewrite g as + ** ______________________________________ + ** dx fx + dy fy / r^2 (dx^2 + dy^2) - (dx fy - dy fx)^2 + ** g = ----------------- + \ / ------------------------------------- + ** r^2 - fx^2 - fy^2 \/ (r^2 - fx^2 - fy^2)^2 + ** ____ + ** = gLin + \/gRad + ** + ** where + ** + ** dx fx + dy fy + ** gLin := ----------------- + ** r^2 - fx^2 - fy^2 + ** + ** r^2 (dx^2 + dy^2) - (dx fy - dy fx)^2 + ** gRad := ------------------------------------- + ** (r^2 - fx^2 - fy^2)^2 + */ + + cx + = 0.5f * (MAT(&inverse_matrix, 0, 0) + MAT(&inverse_matrix, 0, 1)) + + MAT(&inverse_matrix, 0, 2) + - focalX; + + cy + = 0.5f * (MAT(&inverse_matrix, 1, 0) + MAT(&inverse_matrix, 1, 1)) + + MAT(&inverse_matrix, 1, 2) + - focalY; + + /* + ** dx fx + dy fy + ** gLin := ----------------- + ** r^2 - fx^2 - fy^2 + ** + ** We can factor the top half into + ** + ** = (x m00 + y m01 + cx) fx + (x m10 + y m11 + cy) fy + ** + ** = x (m00 fx + m10 fy) + ** + y (m01 fx + m11 fy) + ** + cx fx + cy fy. + */ + + rgStepXLin + = (MAT(&inverse_matrix, 0, 0) * fx + MAT(&inverse_matrix, 1, 0) * fy) + / r2_fx2_fy2; + + rgStepYLin + = (MAT(&inverse_matrix, 0, 1) * fx + MAT(&inverse_matrix, 1, 1) * fy) + / r2_fx2_fy2; + + rgConstantLin = (cx * fx + cy * fy) / r2_fx2_fy2; + + /* + ** r^2 (dx^2 + dy^2) - (dx fy - dy fx)^2 + ** gRad := ------------------------------------- + ** (r^2 - fx^2 - fy^2)^2 + ** + ** r^2 (dx^2 + dy^2) - dx^2 fy^2 - dy^2 fx^2 + 2 dx dy fx fy + ** := --------------------------------------------------------- + ** (r^2 - fx^2 - fy^2)^2 + ** + ** dx^2 (r^2 - fy^2) + dy^2 (r^2 - fx^2) + 2 dx dy fx fy + ** := ----------------------------------------------------- + ** (r^2 - fx^2 - fy^2)^2 + ** + ** First, lets factor dx^2 into + ** + ** dx^2 = (x m00 + y m01 + cx)^2 + ** = x^2 m00^2 + y^2 m01^2 + 2 x y m00 m01 + ** + 2 x m00 cx + 2 y m01 cx + cx^2 + ** + ** = x^2 (m00^2) + ** + y^2 (m01^2) + ** + x y (2 m00 m01) + ** + x (2 m00 cx) + ** + y (2 m01 cx) + ** + cx^2. + ** + ** The same can be done for dy^2: + ** + ** dy^2 = x^2 (m10^2) + ** + y^2 (m11^2) + ** + x y (2 m10 m11) + ** + x (2 m10 cy) + ** + y (2 m11 cy) + ** + cy^2. + ** + ** Let's also factor dx dy into + ** + ** dx dy = (x m00 + y m01 + cx) (x m10 + y m11 + cy) + ** = x^2 m00 m10 + y^2 m01 m11 + x y m00 m11 + x y m01 m10 + ** + x m00 cy + x m10 cx + y m01 cy + y m11 cx + cx cy + ** + ** = x^2 (m00 m10) + ** + y^2 (m01 m11) + ** + x y (m00 m11 + m01 m10) + ** + x (m00 cy + m10 cx) + ** + y (m01 cy + m11 cx) + ** + cx cy. + ** + ** Now that we have all this, lets look at the top of gRad. + ** + ** = dx^2 (r^2 - fy^2) + dy^2 (r^2 - fx^2) + 2 dx dy fx fy + ** = x^2 m00^2 (r^2 - fy^2) + y^2 m01^2 (r^2 - fy^2) + ** + x y 2 m00 m01 (r^2 - fy^2) + x 2 m00 cx (r^2 - fy^2) + ** + y 2 m01 cx (r^2 - fy^2) + cx^2 (r^2 - fy^2) + ** + x^2 m10^2 (r^2 - fx^2) + y^2 m11^2 (r^2 - fx^2) + ** + x y 2 m10 m11 (r^2 - fx^2) + x 2 m10 cy (r^2 - fx^2) + ** + y 2 m11 cy (r^2 - fx^2) + cy^2 (r^2 - fx^2) + ** + x^2 m00 m10 2 fx fy + y^2 m01 m11 2 fx fy + ** + x y (m00 m11 + m01 m10) 2 fx fy + ** + x (m00 cy + m10 cx) 2 fx fy + y (m01 cy + m11 cx) 2 fx fy + ** + cx cy 2 fx fy + ** + ** = x^2 ( m00^2 (r^2 - fy^2) + ** + m10^2 (r^2 - fx^2) + ** + m00 m10 2 fx fy + ** ) + ** + y^2 ( m01^2 (r^2 - fy^2) + ** + m11^2 (r^2 - fx^2) + ** + m01 m11 2 fx fy + ** ) + ** + x y ( 2 m00 m01 (r^2 - fy^2) + ** + 2 m10 m11 (r^2 - fx^2) + ** + (m00 m11 + m01 m10) 2 fx fy + ** ) + ** + x ( 2 m00 cx (r^2 - fy^2) + ** + 2 m10 cy (r^2 - fx^2) + ** + (m00 cy + m10 cx) 2 fx fy + ** ) + ** + y ( 2 m01 cx (r^2 - fy^2) + ** + 2 m11 cy (r^2 - fx^2) + ** + (m01 cy + m11 cx) 2 fx fy + ** ) + ** + cx^2 (r^2 - fy^2) + cy^2 (r^2 - fx^2) + cx cy 2 fx fy. + */ + + rgStepXXRad = + ( + MAT(&inverse_matrix, 0, 0) * MAT(&inverse_matrix, 0, 0) * r2_fy2 + + MAT(&inverse_matrix, 1, 0) * MAT(&inverse_matrix, 1, 0) * r2_fx2 + + MAT(&inverse_matrix, 0, 0) * MAT(&inverse_matrix, 1, 0) * fxfy_2 + ) + / r2_fx2_fy2sq; + + rgStepYYRad = + ( + MAT(&inverse_matrix, 0, 1) * MAT(&inverse_matrix, 0, 1) * r2_fy2 + + MAT(&inverse_matrix, 1, 1) * MAT(&inverse_matrix, 1, 1) * r2_fx2 + + MAT(&inverse_matrix, 0, 1) * MAT(&inverse_matrix, 1, 1) * fxfy_2 + ) + / r2_fx2_fy2sq; + + rgStepXYRad = + ( + MAT(&inverse_matrix, 0, 0) * MAT(&inverse_matrix, 0, 1) * r2_fy2_2 + + MAT(&inverse_matrix, 1, 0) * MAT(&inverse_matrix, 1, 1) * r2_fx2_2 + + ( + MAT(&inverse_matrix, 0, 0) * MAT(&inverse_matrix, 1, 1) + + MAT(&inverse_matrix, 0, 1) * MAT(&inverse_matrix, 1, 0) + ) + * fxfy_2 + ) + / r2_fx2_fy2sq; + + rgStepXRad = + ( + MAT(&inverse_matrix, 0, 0) * cx * r2_fy2_2 + + MAT(&inverse_matrix, 1, 0) * cy * r2_fx2_2 + + ( + MAT(&inverse_matrix, 0, 0) * cy + + MAT(&inverse_matrix, 1, 0) * cx + ) + * fxfy_2 + ) + / r2_fx2_fy2sq; + + rgStepYRad = + ( + MAT(&inverse_matrix, 0, 1) * cx * r2_fy2_2 + + MAT(&inverse_matrix, 1, 1) * cy * r2_fx2_2 + + ( + MAT(&inverse_matrix, 0, 1) * cy + + MAT(&inverse_matrix, 1, 1) * cx + ) + * fxfy_2 + ) + / r2_fx2_fy2sq; + + rgConstantRad = + ( + cx * cx * r2_fy2 + + cy * cy * r2_fx2 + + cx * cy * fxfy_2 + ) + / r2_fx2_fy2sq; + + /* Setup the command buffer. */ + data = &rgConstantLin; + VG_LITE_RETURN_ERROR(push_state(&s_context, 0x0A04, *(uint32_t *) data)); + data = &rgStepXLin; + VG_LITE_RETURN_ERROR(push_state(&s_context, 0x0A06, *(uint32_t *) data)); + data = &rgStepYLin; + VG_LITE_RETURN_ERROR(push_state(&s_context, 0x0A08, *(uint32_t *) data)); + data = &rgConstantRad; + VG_LITE_RETURN_ERROR(push_state(&s_context, 0x0A05, *(uint32_t *) data)); + data = &rgStepXRad; + VG_LITE_RETURN_ERROR(push_state(&s_context, 0x0A07, *(uint32_t *) data)); + data = &rgStepYRad; + VG_LITE_RETURN_ERROR(push_state(&s_context, 0x0A09, *(uint32_t *) data)); + data = &rgStepXXRad; + VG_LITE_RETURN_ERROR(push_state(&s_context, 0x0A03, *(uint32_t *) data)); + data = &rgStepYYRad; + VG_LITE_RETURN_ERROR(push_state(&s_context, 0x0A0A, *(uint32_t *) data)); + data = &rgStepXYRad; + VG_LITE_RETURN_ERROR(push_state(&s_context, 0x0A0B, *(uint32_t *) data)); + VG_LITE_RETURN_ERROR(set_interpolation_steps(target, source->width, source->height, matrix)); + + /* enable pre-multiplied in image unit */ + VG_LITE_RETURN_ERROR(push_state(&s_context, 0x0A24, convert_source_format(source->format) | + filter_mode | rad_tile | conversion | src_premultiply_enable)); + + VG_LITE_RETURN_ERROR(push_state(&s_context, 0x0A26, paint_color)); + VG_LITE_RETURN_ERROR(push_state(&s_context, 0x0A28, source->address)); + + VG_LITE_RETURN_ERROR(push_state(&s_context, 0x0A2A, tiled_source)); + VG_LITE_RETURN_ERROR(push_state(&s_context, 0x0A2C, 0)); + VG_LITE_RETURN_ERROR(push_state(&s_context, 0x0A2E, source->width)); + + /* Work on path states. */ + matrix = path_matrix; + + if(ts_is_fullscreen == 0) { + transform(&temp, (vg_lite_float_t)path->bounding_box[0], (vg_lite_float_t)path->bounding_box[1], matrix); + point_min = point_max = temp; + + transform(&temp, (vg_lite_float_t)path->bounding_box[2], (vg_lite_float_t)path->bounding_box[1], matrix); + if(temp.x < point_min.x) point_min.x = temp.x; + if(temp.y < point_min.y) point_min.y = temp.y; + if(temp.x > point_max.x) point_max.x = temp.x; + if(temp.y > point_max.y) point_max.y = temp.y; + + transform(&temp, (vg_lite_float_t)path->bounding_box[2], (vg_lite_float_t)path->bounding_box[3], matrix); + if(temp.x < point_min.x) point_min.x = temp.x; + if(temp.y < point_min.y) point_min.y = temp.y; + if(temp.x > point_max.x) point_max.x = temp.x; + if(temp.y > point_max.y) point_max.y = temp.y; + + transform(&temp, (vg_lite_float_t)path->bounding_box[0], (vg_lite_float_t)path->bounding_box[3], matrix); + if(temp.x < point_min.x) point_min.x = temp.x; + if(temp.y < point_min.y) point_min.y = temp.y; + if(temp.x > point_max.x) point_max.x = temp.x; + if(temp.y > point_max.y) point_max.y = temp.y; + + point_min.x = MAX(point_min.x, 0); + point_min.y = MAX(point_min.y, 0); + point_max.x = MIN(point_max.x, dst_align_width); + point_max.y = MIN(point_max.y, target->height); + + if(s_context.scissor_set) { + point_min.x = MAX(point_min.x, s_context.scissor[0]); + point_min.y = MAX(point_min.y, s_context.scissor[1]); + point_max.x = MIN(point_max.x, s_context.scissor[0] + s_context.scissor[2]); + point_max.y = MIN(point_max.y, s_context.scissor[1] + s_context.scissor[3]); + } + } + + /* Convert states into hardware values. */ + blend_mode = convert_blend(blend); + format = convert_path_format(path->format); + quality = convert_path_quality(path->quality); + tiling = (s_context.capabilities.cap.tiled == 2) ? 0x2000000 : 0; + fill = (fill_rule == VG_LITE_FILL_EVEN_ODD) ? 0x10 : 0; + tessellation_size = s_context.tessbuf.L2_size ? s_context.tessbuf.L2_size : s_context.tessbuf.L1_size; + + /* Setup the command buffer. */ + /* Program color register. */ + + /* enable pre-multiplied from VG to VGPE */ + VG_LITE_RETURN_ERROR(push_state(&s_context, 0x0A00, + 0x02000002 | s_context.capabilities.cap.tiled | in_premult | imageMode | blend_mode | transparency_mode | + s_context.enable_mask | s_context.scissor_enable | s_context.color_transform | s_context.matrix_enable)); + + VG_LITE_RETURN_ERROR(push_state(&s_context, 0x0A34, 0x01000400 | format | quality | tiling | fill)); + VG_LITE_RETURN_ERROR(push_state(&s_context, 0x0A3B, 0x3F800000)); /* Path tessellation SCALE. */ + VG_LITE_RETURN_ERROR(push_state(&s_context, 0x0A3C, 0x00000000)); /* Path tessellation BIAS. */ + /* Program matrix. */ + VG_LITE_RETURN_ERROR(push_state_ptr(&s_context, 0x0A40, (void *) &matrix->m[0][0])); + VG_LITE_RETURN_ERROR(push_state_ptr(&s_context, 0x0A41, (void *) &matrix->m[0][1])); + VG_LITE_RETURN_ERROR(push_state_ptr(&s_context, 0x0A42, (void *) &matrix->m[0][2])); + VG_LITE_RETURN_ERROR(push_state_ptr(&s_context, 0x0A43, (void *) &matrix->m[1][0])); + VG_LITE_RETURN_ERROR(push_state_ptr(&s_context, 0x0A44, (void *) &matrix->m[1][1])); + VG_LITE_RETURN_ERROR(push_state_ptr(&s_context, 0x0A45, (void *) &matrix->m[1][2])); + + if(VLM_PATH_GET_UPLOAD_BIT(*path) == 1) { + if(path->path_changed != 0) { + if(path->uploaded.handle != NULL) { + free_memory.memory_handle = path->uploaded.handle; + vg_lite_kernel(VG_LITE_FREE, &free_memory); + path->uploaded.address = 0; + path->uploaded.memory = NULL; + path->uploaded.handle = NULL; + } + /* Allocate memory for the path data. */ + memory.bytes = 16 + VG_LITE_ALIGN(path->path_length, 8); + return_offset = (8 + VG_LITE_ALIGN(path->path_length, 8)) / 4; + memory.contiguous = 1; + VG_LITE_RETURN_ERROR(vg_lite_kernel(VG_LITE_ALLOCATE, &memory)); + ((uint64_t *) memory.memory)[(path->path_length + 7) / 8] = 0; + ((uint32_t *) memory.memory)[0] = VG_LITE_DATA((path->path_length + 7) / 8); + ((uint32_t *) memory.memory)[1] = 0; + memcpy((uint8_t *) memory.memory + 8, path->path, path->path_length); + ((uint32_t *) memory.memory)[return_offset] = VG_LITE_RETURN(); + ((uint32_t *) memory.memory)[return_offset + 1] = 0; + + path->uploaded.handle = memory.memory_handle; + path->uploaded.memory = memory.memory; + path->uploaded.address = memory.memory_gpu; + path->uploaded.bytes = memory.bytes; + path->path_changed = 0; + } + } + + /* Setup tessellation loop. */ + if(path->path_type == VG_LITE_DRAW_FILL_PATH || path->path_type == VG_LITE_DRAW_ZERO || + path->path_type == VG_LITE_DRAW_FILL_STROKE_PATH) { + for(y = point_min.y; y < point_max.y; y += height) { + for(x = point_min.x; x < point_max.x; x += width) { + /* Tessellate path. */ + VG_LITE_RETURN_ERROR(push_stall(&s_context, 15)); + VG_LITE_RETURN_ERROR(push_state(&s_context, 0x0A1B, 0x00011000)); + VG_LITE_RETURN_ERROR(push_state(&s_context, 0x0A01, x | (y << 16))); + VG_LITE_RETURN_ERROR(push_state(&s_context, 0x0A39, x | (y << 16))); + VG_LITE_RETURN_ERROR(push_state(&s_context, 0x0A3D, tessellation_size / 64)); + + if(VLM_PATH_GET_UPLOAD_BIT(*path) == 1) { + VG_LITE_RETURN_ERROR(push_call(&s_context, path->uploaded.address, path->uploaded.bytes)); + } + else { + VG_LITE_RETURN_ERROR(push_data(&s_context, path->path_length, path->path)); + } + } + } + } + /* Setup tessellation loop. */ + if(path->path_type == VG_LITE_DRAW_STROKE_PATH || path->path_type == VG_LITE_DRAW_FILL_STROKE_PATH) { + for(y = point_min.y; y < point_max.y; y += height) { + for(x = point_min.x; x < point_max.x; x += width) { + /* Tessellate path. */ + VG_LITE_RETURN_ERROR(push_stall(&s_context, 15)); + VG_LITE_RETURN_ERROR(push_state(&s_context, 0x0A1B, 0x00011000)); + VG_LITE_RETURN_ERROR(push_state(&s_context, 0x0A01, x | (y << 16))); + VG_LITE_RETURN_ERROR(push_state(&s_context, 0x0A39, x | (y << 16))); + VG_LITE_RETURN_ERROR(push_state(&s_context, 0x0A3D, tessellation_size / 64)); + format = convert_path_format(VG_LITE_FP32); + VG_LITE_RETURN_ERROR(push_state(&s_context, 0x0A34, 0x01000200 | format | quality | tiling | 0x0)); + VG_LITE_RETURN_ERROR(push_state(&s_context, 0x0A02, path->stroke_color)); + + if(VLM_PATH_STROKE_GET_UPLOAD_BIT(*path) == 1) { + VG_LITE_RETURN_ERROR(push_call(&s_context, path->stroke->uploaded.address, path->stroke->uploaded.bytes)); + } + else { + VG_LITE_RETURN_ERROR(push_data(&s_context, path->stroke_size, path->stroke_path)); + } + } + } + } + + /* Finialize command buffer. */ + VG_LITE_RETURN_ERROR(push_state(&s_context, 0x0A34, 0)); + + return error; +} + +#else /* (CHIPID==0x355 || CHIPID==0x255) */ + +/* GC555 vg_lite_draw API implementation + */ +vg_lite_error_t vg_lite_draw(vg_lite_buffer_t * target, + vg_lite_path_t * path, + vg_lite_fill_t fill_rule, + vg_lite_matrix_t * matrix, + vg_lite_blend_t blend, + vg_lite_color_t color) +{ +#if DUMP_API + FUNC_DUMP(vg_lite_draw)(target, path, fill_rule, matrix, blend, color); +#endif + + uint32_t blend_mode; + uint32_t format, quality, tiling, fill; + uint32_t tessellation_size; + vg_lite_error_t error; + vg_lite_point_t point_min = { 0 }, point_max = { 0 }, temp = { 0 }; + int width, height; + uint8_t ts_is_fullscreen = 0; + uint32_t return_offset = 0; + vg_lite_kernel_free_t free_memory; + vg_lite_kernel_allocate_t memory; + float new_matrix[6]; + float scale, bias; + uint32_t tile_setting = 0; + uint32_t in_premult = 0; + uint32_t premul_flag = 0; +#if (!gcFEATURE_VG_PARALLEL_PATHS && gcFEATURE_VG_512_PARALLEL_PATHS) + uint32_t parallel_workpaths1 = 2; + uint32_t parallel_workpaths2 = 2; +#endif +#if (!gcFEATURE_VG_SPLIT_PATH || !gcFEATURE_VG_PARALLEL_PATHS || !gcFEATURE_VG_512_PARALLEL_PATHS) + int32_t y = 0; + uint32_t par_height = 0; + int32_t next_boundary = 0; +#endif + +#if gcFEATURE_VG_TRACE_API + VGLITE_LOG("vg_lite_draw %p %p %d %p %d 0x%08X\n", target, path, fill_rule, matrix, blend, color); + VGLITE_LOG(" path_type %d, path_length %d, stroke_size %d\n", path->path_type, path->path_length, path->stroke_size); +#endif + +#if gcFEATURE_VG_ERROR_CHECK +#if !gcFEATURE_VG_QUALITY_8X + if(path->quality == VG_LITE_UPPER) { + return VG_LITE_NOT_SUPPORT; + } +#endif +#if !gcFEATURE_VG_24BIT + if(target->format >= VG_LITE_RGB888 && target->format <= VG_LITE_RGBA5658) { + return VG_LITE_NOT_SUPPORT; + } +#endif +#if !gcFEATURE_VG_NEW_BLEND_MODE + if(blend == VG_LITE_BLEND_DARKEN || blend == VG_LITE_BLEND_LIGHTEN) { + return VG_LITE_NOT_SUPPORT; + } +#endif + if(!path || !path->path) { + return VG_LITE_INVALID_ARGUMENT; + } +#endif /* gcFEATURE_VG_ERROR_CHECK */ + + if(!path->path_length) { + return VG_LITE_SUCCESS; + } + + if(!matrix) { + matrix = &identity_mtx; + } + +#if gcFEATURE_VG_GAMMA + set_gamma_dest_only(target, VGL_FALSE); +#endif +#if gcFEATURE_VG_GLOBAL_ALPHA + if(blend >= VG_LITE_BLEND_NORMAL_LVGL && blend <= VG_LITE_BLEND_MULTIPLY_LVGL) { + VG_LITE_RETURN_ERROR(vg_lite_dest_global_alpha(VG_LITE_GLOBAL, 0xff)); + } +#endif + /*blend input into context*/ + s_context.blend_mode = blend; + + /* Adjust premultiply setting according to openvg condition */ + target->apply_premult = 0; + premul_flag = (s_context.blend_mode >= OPENVG_BLEND_SRC_OVER && s_context.blend_mode <= OPENVG_BLEND_ADDITIVE) + || (s_context.blend_mode >= VG_LITE_BLEND_NORMAL_LVGL && s_context.blend_mode <= VG_LITE_BLEND_MULTIPLY_LVGL); + + if(target->premultiplied == 0 && premul_flag == 0) { + in_premult = 0x10000000; + target->apply_premult = 1; + } + else if((target->premultiplied == 1) || + (target->premultiplied == 0 && premul_flag == 1)) { + in_premult = 0x00000000; + } + error = set_render_target(target); + if(error != VG_LITE_SUCCESS) { + return error; + } + + if((target->format == VG_LITE_YUYV || target->format == VG_LITE_YUY2 || target->format == VG_LITE_YUY2_TILED + || target->format == VG_LITE_AYUY2 || target->format == VG_LITE_AYUY2_TILED) + && path->quality != VG_LITE_LOW) { + path->quality = VG_LITE_LOW; + printf("If target is YUV group , the path qulity should use VG_LITE_LOW.\n"); + } + + width = target->width; + height = target->height; + if(s_context.scissor_set) { + width = s_context.scissor[2] - s_context.scissor[0]; + height = s_context.scissor[3] - s_context.scissor[1]; + } + if(width == 0 || height == 0) + return VG_LITE_NO_CONTEXT; + if((target->width <= width) && (target->height <= height) && (!s_context.scissor_set)) { + ts_is_fullscreen = 1; + point_min.x = 0; + point_min.y = 0; + point_max.x = target->width; + point_max.y = target->height; + } + + if(ts_is_fullscreen == 0) { + transform(&temp, (vg_lite_float_t)path->bounding_box[0], (vg_lite_float_t)path->bounding_box[1], matrix); + point_min = point_max = temp; + + transform(&temp, (vg_lite_float_t)path->bounding_box[2], (vg_lite_float_t)path->bounding_box[1], matrix); + if(temp.x < point_min.x) point_min.x = temp.x; + if(temp.y < point_min.y) point_min.y = temp.y; + if(temp.x > point_max.x) point_max.x = temp.x; + if(temp.y > point_max.y) point_max.y = temp.y; + + transform(&temp, (vg_lite_float_t)path->bounding_box[2], (vg_lite_float_t)path->bounding_box[3], matrix); + if(temp.x < point_min.x) point_min.x = temp.x; + if(temp.y < point_min.y) point_min.y = temp.y; + if(temp.x > point_max.x) point_max.x = temp.x; + if(temp.y > point_max.y) point_max.y = temp.y; + + transform(&temp, (vg_lite_float_t)path->bounding_box[0], (vg_lite_float_t)path->bounding_box[3], matrix); + if(temp.x < point_min.x) point_min.x = temp.x; + if(temp.y < point_min.y) point_min.y = temp.y; + if(temp.x > point_max.x) point_max.x = temp.x; + if(temp.y > point_max.y) point_max.y = temp.y; + + if(point_min.x < 0) point_min.x = 0; + if(point_min.y < 0) point_min.y = 0; + if(point_max.x > target->width) point_max.x = target->width; + if(point_max.y > target->height) point_max.y = target->height; + + if(s_context.scissor_set) { + point_min.x = MAX(point_min.x, s_context.scissor[0]); + point_min.y = MAX(point_min.y, s_context.scissor[1]); + point_max.x = MIN(point_max.x, s_context.scissor[2]); + point_max.y = MIN(point_max.y, s_context.scissor[3]); + } + } + + width = point_max.x - point_min.x; + height = point_max.y - point_min.y; + scale = 1.0f; + bias = 0.0f; + new_matrix[0] = matrix->m[0][0] * scale; + new_matrix[1] = matrix->m[0][1] * scale; + new_matrix[2] = (matrix->m[0][0] + matrix->m[0][1]) * bias + matrix->m[0][2]; + new_matrix[3] = matrix->m[1][0] * scale; + new_matrix[4] = matrix->m[1][1] * scale; + new_matrix[5] = (matrix->m[1][0] + matrix->m[1][1]) * bias + matrix->m[1][2]; + + /* Convert states into hardware values. */ + blend_mode = convert_blend(blend); + format = convert_path_format(path->format); + quality = convert_path_quality(path->quality); + tiling = (s_context.capabilities.cap.tiled == 2) ? 0x2000000 : 0; + fill = (fill_rule == VG_LITE_FILL_EVEN_ODD) ? 0x10 : 0; + tessellation_size = s_context.tessbuf.tessbuf_size; +#if gcFEATURE_VG_TESSELLATION_TILED_OUT + tile_setting = (target->tiled != VG_LITE_LINEAR) ? 0x40 : 0; +#endif + + /* Setup the command buffer. */ + /* Program color register. */ + VG_LITE_RETURN_ERROR(push_state(&s_context, 0x0A00, + in_premult | s_context.capabilities.cap.tiled | blend_mode | tile_setting | s_context.enable_mask | + s_context.scissor_enable | s_context.color_transform | s_context.matrix_enable)); + VG_LITE_RETURN_ERROR(push_state(&s_context, 0x0A02, color)); + /* Program tessellation control: for TS module. */ + VG_LITE_RETURN_ERROR(push_state(&s_context, 0x0A34, 0x01000000 | format | quality | tiling | fill)); + VG_LITE_RETURN_ERROR(push_state(&s_context, 0x0A3B, 0x3F800000)); /* Path tessellation SCALE. */ + VG_LITE_RETURN_ERROR(push_state(&s_context, 0x0A3C, 0x00000000)); /* Path tessellation BIAS. */ + /* Program matrix. */ + VG_LITE_RETURN_ERROR(push_state_ptr(&s_context, 0x0A40, (void *)&new_matrix[0])); + VG_LITE_RETURN_ERROR(push_state_ptr(&s_context, 0x0A41, (void *)&new_matrix[1])); + VG_LITE_RETURN_ERROR(push_state_ptr(&s_context, 0x0A42, (void *)&new_matrix[2])); + VG_LITE_RETURN_ERROR(push_state_ptr(&s_context, 0x0A43, (void *)&new_matrix[3])); + VG_LITE_RETURN_ERROR(push_state_ptr(&s_context, 0x0A44, (void *)&new_matrix[4])); + VG_LITE_RETURN_ERROR(push_state_ptr(&s_context, 0x0A45, (void *)&new_matrix[5])); + VG_LITE_RETURN_ERROR(push_state_ptr(&s_context, 0x0ACD, (void *)&matrix->m[0][2])); + VG_LITE_RETURN_ERROR(push_state_ptr(&s_context, 0x0ACE, (void *)&matrix->m[1][2])); + + /* DDRLess does not support uploading path data. */ + if(VLM_PATH_GET_UPLOAD_BIT(*path) == 1) { + if(path->path_changed != 0) { + if(path->uploaded.handle != NULL) { + free_memory.memory_handle = path->uploaded.handle; + VG_LITE_RETURN_ERROR(vg_lite_kernel(VG_LITE_FREE, &free_memory)); + path->uploaded.address = 0; + path->uploaded.memory = NULL; + path->uploaded.handle = NULL; + } + /* Allocate memory for the path data. */ + memory.bytes = 16 + VG_LITE_ALIGN(path->path_length, 8); + return_offset = (8 + VG_LITE_ALIGN(path->path_length, 8)) / 4; + memory.contiguous = 1; + VG_LITE_RETURN_ERROR(vg_lite_kernel(VG_LITE_ALLOCATE, &memory)); + ((uint64_t *)memory.memory)[(path->path_length + 7) / 8] = 0; + ((uint32_t *)memory.memory)[0] = VG_LITE_DATA((path->path_length + 7) / 8); + ((uint32_t *)memory.memory)[1] = 0; + memcpy((uint8_t *)memory.memory + 8, path->path, path->path_length); + ((uint32_t *)memory.memory)[return_offset] = VG_LITE_RETURN(); + ((uint32_t *)memory.memory)[return_offset + 1] = 0; + + path->uploaded.handle = memory.memory_handle; + path->uploaded.memory = memory.memory; + path->uploaded.address = memory.memory_gpu; + path->uploaded.bytes = memory.bytes; + path->path_changed = 0; + } + } + + if(VLM_PATH_GET_UPLOAD_BIT(*path) == 1) { + vglitemDUMP_BUFFER("path", (size_t)path->uploaded.address, (uint8_t *)(path->uploaded.memory), 0, path->uploaded.bytes); + } + +#if !DUMP_COMMAND_CAPTURE + vglitemDUMP("@[memory 0x%08X 0x%08X]", s_context.tessbuf.physical_addr, s_context.tessbuf.tessbuf_size); +#endif + + if(width + point_min.x > target->width) { + width = target->width - point_min.x; + } + +#if (!gcFEATURE_VG_SPLIT_PATH || !gcFEATURE_VG_PARALLEL_PATHS || !gcFEATURE_VG_512_PARALLEL_PATHS) + s_context.tessbuf.tess_w_h = width | (height << 16); + if(path->path_type == VG_LITE_DRAW_FILL_PATH || path->path_type == VG_LITE_DRAW_ZERO || + path->path_type == VG_LITE_DRAW_FILL_STROKE_PATH) { +#if !gcFEATURE_VG_PARALLEL_PATHS + if(height <= 128) + parallel_workpaths1 = 4; + else + parallel_workpaths1 = height * 128 / 4096 - 1; + + if(parallel_workpaths1 > parallel_workpaths2) + parallel_workpaths1 = parallel_workpaths2; +#endif + for(y = point_min.y; y < point_max.y; y += par_height) { +#if !gcFEATURE_VG_512_PARALLEL_PATHS + next_boundary = (y + 512) & 0xfffffe00; +#elif (!gcFEATURE_VG_PARALLEL_PATHS && gcFEATURE_VG_SPLIT_PATH) + next_boundary = (y + 32) & 0xffffffe0; +#else + next_boundary = (y + 16) & 0xfffffff0; +#endif + par_height = ((next_boundary < point_max.y) ? next_boundary - y : (point_max.y - y)); + VG_LITE_RETURN_ERROR(push_state(&s_context, 0x0A00, + in_premult | s_context.capabilities.cap.tiled | blend_mode | tile_setting | s_context.enable_mask | + s_context.scissor_enable | s_context.color_transform | s_context.matrix_enable)); + VG_LITE_RETURN_ERROR(push_state(&s_context, 0x0A02, color)); + /* Program tessellation control: for TS module. */ + VG_LITE_RETURN_ERROR(push_state(&s_context, 0x0A34, 0x01000000 | format | quality | tiling | fill)); + VG_LITE_RETURN_ERROR(push_state(&s_context, 0x0A1B, 0x00011000)); + VG_LITE_RETURN_ERROR(push_state(&s_context, 0x0A3D, tessellation_size / 64)); + VG_LITE_RETURN_ERROR(push_state(&s_context, 0x0A39, point_min.x | (y << 16))); + VG_LITE_RETURN_ERROR(push_state(&s_context, 0x0A3A, width | (par_height << 16))); + + if(VLM_PATH_GET_UPLOAD_BIT(*path) == 1) { + VG_LITE_RETURN_ERROR(push_call(&s_context, path->uploaded.address, path->uploaded.bytes)); + } + else { + VG_LITE_RETURN_ERROR(push_data(&s_context, path->path_length, path->path)); + VG_LITE_RETURN_ERROR(push_state(&s_context, 0x0A1B, 0x00000101)); +#if !gcFEATURE_VG_PARALLEL_PATHS + s_context.path_counter++; + if(parallel_workpaths1 == s_context.path_counter) { + VG_LITE_RETURN_ERROR(push_stall(&s_context, 7)); + s_context.path_counter = 0; + } +#endif + } + } + } + if(path->path_type == VG_LITE_DRAW_STROKE_PATH || path->path_type == VG_LITE_DRAW_FILL_STROKE_PATH) { +#if !gcFEATURE_VG_PARALLEL_PATHS + if(height <= 128) + parallel_workpaths1 = 4; + else + parallel_workpaths1 = height * 128 / 4096 - 1; + + if(parallel_workpaths1 > parallel_workpaths2) + parallel_workpaths1 = parallel_workpaths2; +#endif + for(y = point_min.y; y < point_max.y; y += par_height) { +#if !gcFEATURE_VG_512_PARALLEL_PATHS + next_boundary = (y + 512) & 0xfffffe00; +#elif (!gcFEATURE_VG_PARALLEL_PATHS && gcFEATURE_VG_SPLIT_PATH) + next_boundary = (y + 32) & 0xffffffe0; +#else + next_boundary = (y + 16) & 0xfffffff0; +#endif + par_height = ((next_boundary < point_max.y) ? next_boundary - y : (point_max.y - y)); + + VG_LITE_RETURN_ERROR(push_state(&s_context, 0x0A00, + in_premult | s_context.capabilities.cap.tiled | blend_mode | tile_setting | s_context.enable_mask | + s_context.scissor_enable | s_context.color_transform | s_context.matrix_enable)); + VG_LITE_RETURN_ERROR(push_state(&s_context, 0x0A1B, 0x00011000)); + VG_LITE_RETURN_ERROR(push_state(&s_context, 0x0A3D, tessellation_size / 64)); + VG_LITE_RETURN_ERROR(push_state(&s_context, 0x0A39, point_min.x | (y << 16))); + + VG_LITE_RETURN_ERROR(push_state(&s_context, 0x0A3A, width | (par_height << 16))); + + if(VLM_PATH_GET_UPLOAD_BIT(*path) == 1) { + VG_LITE_RETURN_ERROR(push_state(&s_context, 0x0A34, 0x01000200 | format | quality | tiling | 0x0)); + VG_LITE_RETURN_ERROR(push_state(&s_context, 0x0A02, path->stroke_color)); + VG_LITE_RETURN_ERROR(push_call(&s_context, path->uploaded.address, path->uploaded.bytes)); + } + else { + format = convert_path_format(VG_LITE_FP32); + VG_LITE_RETURN_ERROR(push_state(&s_context, 0x0A34, 0x01000200 | format | quality | tiling | 0x0)); + VG_LITE_RETURN_ERROR(push_state(&s_context, 0x0A02, path->stroke_color)); + VG_LITE_RETURN_ERROR(push_data(&s_context, path->stroke_size, path->stroke_path)); + VG_LITE_RETURN_ERROR(push_state(&s_context, 0x0A1B, 0x00000101)); +#if !gcFEATURE_VG_PARALLEL_PATHS + s_context.path_counter++; + if(parallel_workpaths1 == s_context.path_counter) { + VG_LITE_RETURN_ERROR(push_stall(&s_context, 7)); + s_context.path_counter = 0; + } +#endif + } + } + } +#else + { + s_context.tessbuf.tess_w_h = width | (height << 16); + if(path->path_type == VG_LITE_DRAW_FILL_PATH || path->path_type == VG_LITE_DRAW_ZERO || + path->path_type == VG_LITE_DRAW_FILL_STROKE_PATH) { + /* Tessellate path. */ + VG_LITE_RETURN_ERROR(push_state(&s_context, 0x0A1B, 0x00011000)); + VG_LITE_RETURN_ERROR(push_state(&s_context, 0x0A3D, tessellation_size / 64)); + VG_LITE_RETURN_ERROR(push_state(&s_context, 0x0A39, point_min.x | (point_min.y << 16))); + VG_LITE_RETURN_ERROR(push_state(&s_context, 0x0A3A, s_context.tessbuf.tess_w_h)); + + if(VLM_PATH_GET_UPLOAD_BIT(*path) == 1) { + VG_LITE_RETURN_ERROR(push_call(&s_context, path->uploaded.address, path->uploaded.bytes)); + } + else { + VG_LITE_RETURN_ERROR(push_data(&s_context, path->path_length, path->path)); + } + } + if(path->path_type == VG_LITE_DRAW_STROKE_PATH || path->path_type == VG_LITE_DRAW_FILL_STROKE_PATH) { + /* Tessellate path. */ + VG_LITE_RETURN_ERROR(push_state(&s_context, 0x0A1B, 0x00011000)); + VG_LITE_RETURN_ERROR(push_state(&s_context, 0x0A3D, tessellation_size / 64)); + VG_LITE_RETURN_ERROR(push_state(&s_context, 0x0A39, point_min.x | (point_min.y << 16))); + VG_LITE_RETURN_ERROR(push_state(&s_context, 0x0A3A, s_context.tessbuf.tess_w_h)); + + if(VLM_PATH_GET_UPLOAD_BIT(*path) == 1) { + VG_LITE_RETURN_ERROR(push_state(&s_context, 0x0A34, 0x01000200 | format | quality | tiling | 0x0)); + VG_LITE_RETURN_ERROR(push_state(&s_context, 0x0A02, path->stroke_color)); + VG_LITE_RETURN_ERROR(push_call(&s_context, path->uploaded.address, path->uploaded.bytes)); + } + else { + format = convert_path_format(VG_LITE_FP32); + VG_LITE_RETURN_ERROR(push_state(&s_context, 0x0A34, 0x01000200 | format | quality | tiling | 0x0)); + VG_LITE_RETURN_ERROR(push_state(&s_context, 0x0A02, path->stroke_color)); + VG_LITE_RETURN_ERROR(push_data(&s_context, path->stroke_size, path->stroke_path)); + } + } + } +#endif +#if gcFEATURE_VG_GLOBAL_ALPHA + if(blend >= VG_LITE_BLEND_NORMAL_LVGL && blend <= VG_LITE_BLEND_MULTIPLY_LVGL) { + VG_LITE_RETURN_ERROR(vg_lite_dest_global_alpha(VG_LITE_NORMAL, 0xFF)); + } +#endif + return error; +} + +/* GC555 vg_lite_draw_pattern API implementation + */ +vg_lite_error_t vg_lite_draw_pattern(vg_lite_buffer_t * target, + vg_lite_path_t * path, + vg_lite_fill_t fill_rule, + vg_lite_matrix_t * path_matrix, + vg_lite_buffer_t * source, + vg_lite_matrix_t * pattern_matrix, + vg_lite_blend_t blend, + vg_lite_pattern_mode_t pattern_mode, + vg_lite_color_t pattern_color, + vg_lite_color_t color, + vg_lite_filter_t filter) +{ +#if DUMP_API + FUNC_DUMP(vg_lite_draw_pattern)(target, path, fill_rule, path_matrix, source, pattern_matrix, blend, pattern_mode, + pattern_color, color, filter); +#endif + +#if gcFEATURE_VG_IM_INPUT + vg_lite_error_t error = VG_LITE_SUCCESS; + vg_lite_matrix_t inverse_matrix; + vg_lite_float_t x_step[3]; + vg_lite_float_t y_step[3]; + vg_lite_float_t c_step[3]; + uint32_t imageMode = 0; + uint32_t blend_mode; + uint32_t filter_mode = 0; + int32_t stride; + uint32_t conversion = 0; + uint32_t tiled_source; + vg_lite_matrix_t matrix; + uint32_t pattern_tile = 0; + uint32_t transparency_mode = 0; + uint32_t tile_setting = 0; + uint32_t yuv2rgb = 0; + uint32_t uv_swiz = 0; + /* The following code is from "draw path" */ + uint32_t format, quality, tiling, fill; + uint32_t tessellation_size; + + vg_lite_kernel_allocate_t memory; + vg_lite_kernel_free_t free_memory; + uint32_t return_offset = 0; + + vg_lite_point_t point_min = { 0 }, point_max = { 0 }, temp = { 0 }; + int width, height; + uint8_t ts_is_fullscreen = 0; + + float new_matrix[6]; + float Scale, Bias; + + uint32_t compress_mode; + uint32_t src_premultiply_enable = 0; + uint32_t index_endian = 0; + uint32_t in_premult = 0; + uint32_t paintType = 0; + uint32_t premul_flag = 0; + uint32_t prediv_flag = 0; + uint8_t lvgl_sw_blend = 0; +#if (!gcFEATURE_VG_PARALLEL_PATHS && gcFEATURE_VG_512_PARALLEL_PATHS) + uint32_t parallel_workpaths1 = 2; + uint32_t parallel_workpaths2 = 2; +#endif +#if (!gcFEATURE_VG_SPLIT_PATH || !gcFEATURE_VG_PARALLEL_PATHS || !gcFEATURE_VG_512_PARALLEL_PATHS) + int32_t y = 0; + uint32_t par_height = 0; + int32_t next_boundary = 0; +#endif + +#if gcFEATURE_VG_TRACE_API + VGLITE_LOG("vg_lite_draw_pattern %p %p %d %p %p %p %d %d 0x%08X %d\n", + target, path, fill_rule, path_matrix, source, pattern_matrix, blend, pattern_mode, pattern_color, filter); +#endif + +#if gcFEATURE_VG_ERROR_CHECK +#if !gcFEATURE_VG_QUALITY_8X + if(path->quality == VG_LITE_UPPER) { + return VG_LITE_NOT_SUPPORT; + } +#endif +#if !gcFEATURE_VG_INDEX_ENDIAN + if((source->format >= VG_LITE_INDEX_1) && (source->format <= VG_LITE_INDEX_4) && source->index_endian) { + return VG_LITE_NOT_SUPPORT; + } +#endif +#if !gcFEATURE_VG_RGBA8_ETC2_EAC + if(source->format == VG_LITE_RGBA8888_ETC2_EAC) { + return VG_LITE_NOT_SUPPORT; + } +#else + if((source->format == VG_LITE_RGBA8888_ETC2_EAC) && (source->width % 16 || source->height % 4)) { + return VG_LITE_INVALID_ARGUMENT; + } +#endif +#if !gcFEATURE_VG_YUY2_INPUT + if(source->format == VG_LITE_YUYV || source->format == VG_LITE_YUY2) { + return VG_LITE_NOT_SUPPORT; + } +#endif +#if !gcFEATURE_VG_YUV_INPUT + if((source->format >= VG_LITE_NV12 && source->format <= VG_LITE_NV16) || source->format == VG_LITE_NV24) { + return VG_LITE_NOT_SUPPORT; + } +#elif !gcFEATURE_VG_NV24_INPUT + if(source->format == VG_LITE_NV24) { + return VG_LITE_NOT_SUPPORT; + } +#endif +#if !gcFEATURE_VG_AYUV_INPUT + if(source->format == VG_LITE_ANV12 || source->format == VG_LITE_AYUY2) { + return VG_LITE_NOT_SUPPORT; + } +#endif +#if !gcFEATURE_VG_YUV_TILED_INPUT + if((source->format >= VG_LITE_YUY2_TILED && source->format <= VG_LITE_AYUY2_TILED) || + (source->format == VG_LITE_NV24_TILED)) { + return VG_LITE_NOT_SUPPORT; + } +#endif +#if !gcFEATURE_VG_24BIT + if((target->format >= VG_LITE_RGB888 && target->format <= VG_LITE_RGBA5658) || + (source->format >= VG_LITE_RGB888 && source->format <= VG_LITE_RGBA5658)) { + return VG_LITE_NOT_SUPPORT; + } +#endif +#if !gcFEATURE_VG_24BIT_PLANAR + if(source->format >= VG_LITE_ABGR8565_PLANAR && source->format <= VG_LITE_RGBA5658_PLANAR) { + return VG_LITE_NOT_SUPPORT; + } +#endif + +#if !gcFEATURE_VG_STENCIL + if(source->image_mode == VG_LITE_STENCIL_MODE) { + return VG_LITE_NOT_SUPPORT; + } +#endif +#if !gcFEATURE_VG_NEW_BLEND_MODE + if(blend == VG_LITE_BLEND_DARKEN || blend == VG_LITE_BLEND_LIGHTEN) { + return VG_LITE_NOT_SUPPORT; + } +#endif + if(!path || !path->path) { + return VG_LITE_INVALID_ARGUMENT; + } + + VG_LITE_RETURN_ERROR(srcbuf_align_check(source)); + VG_LITE_RETURN_ERROR(check_compress(source->format, source->compress_mode, source->tiled, source->width, + source->height)); +#endif /* gcFEATURE_VG_ERROR_CHECK */ + +#if !gcFEATURE_VG_LVGL_SUPPORT + if((blend >= VG_LITE_BLEND_ADDITIVE_LVGL && blend <= VG_LITE_BLEND_MULTIPLY_LVGL) || + (blend == VG_LITE_BLEND_NORMAL_LVGL && gcFEATURE_VG_SRC_PREMULTIPLIED)) { + if(!source->lvgl_buffer) { + source->lvgl_buffer = (vg_lite_buffer_t *)vg_lite_os_malloc(sizeof(vg_lite_buffer_t)); + *source->lvgl_buffer = *source; + source->lvgl_buffer->lvgl_buffer = NULL; + vg_lite_allocate(source->lvgl_buffer); + } + /* Make sure render target is up to date before reading RT. */ + vg_lite_finish(); + setup_lvgl_image(target, source, source->lvgl_buffer, blend); + blend = VG_LITE_BLEND_SRC_OVER; + lvgl_sw_blend = 1; + } +#endif + + if(!path->path_length) { + return VG_LITE_SUCCESS; + } + + if(!path_matrix) { + path_matrix = &identity_mtx; + } + if(!pattern_matrix) { + pattern_matrix = &identity_mtx; + } + + /* Work on pattern states. */ + matrix = *pattern_matrix; + if(source->paintType == VG_LITE_PAINT_PATTERN) { + matrix.m[2][0] = 0; + matrix.m[2][1] = 0; + matrix.m[2][2] = 1; + source->image_mode = VG_LITE_NONE_IMAGE_MODE; + } + +#if gcFEATURE_VG_INDEX_ENDIAN + if((source->format >= VG_LITE_INDEX_1) && (source->format <= VG_LITE_INDEX_4) && source->index_endian) { + index_endian = 1 << 14; + } +#endif + +#if gcFEATURE_VG_GAMMA + save_st_gamma_src_dest(source, target); +#endif + +#if gcFEATURE_VG_GLOBAL_ALPHA + if(blend >= VG_LITE_BLEND_NORMAL_LVGL && blend <= VG_LITE_BLEND_MULTIPLY_LVGL) { + VG_LITE_RETURN_ERROR(vg_lite_dest_global_alpha(VG_LITE_GLOBAL, 0xff)); + } +#endif + /*blend input into context*/ + s_context.blend_mode = blend; + in_premult = 0x00000000; + + /* Adjust premultiply setting according to openvg condition */ + src_premultiply_enable = 0x01000100; + if(s_context.color_transform == 0 && s_context.gamma_dst == s_context.gamma_src && s_context.matrix_enable == 0 && + s_context.dst_alpha_mode == 0 && s_context.src_alpha_mode == 0 && + (source->image_mode == VG_LITE_NORMAL_IMAGE_MODE || source->image_mode == 0)) { + prediv_flag = 0; + } + else { + prediv_flag = 1; + } + if((s_context.blend_mode >= OPENVG_BLEND_SRC_OVER && s_context.blend_mode <= OPENVG_BLEND_ADDITIVE) || + source->image_mode == VG_LITE_STENCIL_MODE + || (s_context.blend_mode >= VG_LITE_BLEND_NORMAL_LVGL && s_context.blend_mode <= VG_LITE_BLEND_MULTIPLY_LVGL)) { + premul_flag = 1; + } + else { + premul_flag = 0; + } + + if((source->premultiplied == 0 && target->premultiplied == 0 && premul_flag == 0) || + (source->premultiplied == 1 && target->premultiplied == 0 && prediv_flag == 0)) { + src_premultiply_enable = 0x01000100; + in_premult = 0x10000000; + } + /* when src and dst all pre format, im pre_out set to 0 to perform data truncation to prevent data overflow */ + else if(source->premultiplied == 1 && target->premultiplied == 1 && prediv_flag == 0) { + src_premultiply_enable = 0x00000100; + in_premult = 0x00000000; + } + else if((source->premultiplied == 0 && target->premultiplied == 1) || + (source->premultiplied == 0 && target->premultiplied == 0 && premul_flag == 1)) { + src_premultiply_enable = 0x01000100; + in_premult = 0x00000000; + } + else if((source->premultiplied == 1 && target->premultiplied == 1 && prediv_flag == 1) || + (source->premultiplied == 1 && target->premultiplied == 0 && prediv_flag == 1)) { + src_premultiply_enable = 0x00000100; + in_premult = 0x00000000; + } + if((source->format == VG_LITE_A4 || source->format == VG_LITE_A8) && blend >= VG_LITE_BLEND_SRC_OVER && + blend <= VG_LITE_BLEND_SUBTRACT) { + in_premult = 0x00000000; + } + if(source->premultiplied == target->premultiplied && premul_flag == 0) { + target->apply_premult = 1; + } + else { + target->apply_premult = 0; + } +#if (gcFEATURE_VG_SRC_PREMULTIPLIED == 0) + if(blend == VG_LITE_BLEND_NORMAL_LVGL) + in_premult = 0x00000000; +#endif + error = set_render_target(target); + if(error != VG_LITE_SUCCESS) { + return error; + } + + if((target->format == VG_LITE_YUYV || target->format == VG_LITE_YUY2 || target->format == VG_LITE_YUY2_TILED + || target->format == VG_LITE_AYUY2 || target->format == VG_LITE_AYUY2_TILED) + && path->quality != VG_LITE_LOW) { + path->quality = VG_LITE_LOW; + printf("If target is YUV group , the path qulity should use VG_LITE_LOW.\n"); + } + + transparency_mode = (source->transparency_mode == VG_LITE_IMAGE_TRANSPARENT ? 0x8000 : 0); + width = target->width; + height = target->height; + + if(s_context.scissor_set) { + width = s_context.scissor[2] - s_context.scissor[0]; + height = s_context.scissor[3] - s_context.scissor[1]; + } + if(width == 0 || height == 0) + return VG_LITE_NO_CONTEXT; + if((target->width <= width) && (target->height <= height) && (!s_context.scissor_set)) { + ts_is_fullscreen = 1; + point_min.x = 0; + point_min.y = 0; + point_max.x = target->width; + point_max.y = target->height; + } + + /* If target is L8 and source is in YUV or RGB (not L8 or A8) then we have to convert RGB into L8. */ + if((target->format == VG_LITE_L8) && ((source->format != VG_LITE_L8) && (source->format != VG_LITE_A8))) { + conversion = 0x80000000; + } + + /* Compute inverse matrix. */ + if(!inverse(&inverse_matrix, &matrix)) + return VG_LITE_INVALID_ARGUMENT; + +#if gcFEATURE_VG_MATH_PRECISION_FIX + /* Compute interpolation steps. */ + x_step[0] = inverse_matrix.m[0][0]; + x_step[1] = inverse_matrix.m[1][0]; + x_step[2] = inverse_matrix.m[2][0]; + y_step[0] = inverse_matrix.m[0][1]; + y_step[1] = inverse_matrix.m[1][1]; + y_step[2] = inverse_matrix.m[2][1]; + c_step[0] = (0.5f * (inverse_matrix.m[0][0] + inverse_matrix.m[0][1]) + inverse_matrix.m[0][2]); + c_step[1] = (0.5f * (inverse_matrix.m[1][0] + inverse_matrix.m[1][1]) + inverse_matrix.m[1][2]); + c_step[2] = 0.5f * (inverse_matrix.m[2][0] + inverse_matrix.m[2][1]) + inverse_matrix.m[2][2]; +#else + /* Compute interpolation steps. */ + x_step[0] = inverse_matrix.m[0][0] / source->width; + x_step[1] = inverse_matrix.m[1][0] / source->height; + x_step[2] = inverse_matrix.m[2][0]; + y_step[0] = inverse_matrix.m[0][1] / source->width; + y_step[1] = inverse_matrix.m[1][1] / source->height; + y_step[2] = inverse_matrix.m[2][1]; + c_step[0] = (0.5f * (inverse_matrix.m[0][0] + inverse_matrix.m[0][1]) + inverse_matrix.m[0][2]) / source->width; + c_step[1] = (0.5f * (inverse_matrix.m[1][0] + inverse_matrix.m[1][1]) + inverse_matrix.m[1][2]) / source->height; + c_step[2] = 0.5f * (inverse_matrix.m[2][0] + inverse_matrix.m[2][1]) + inverse_matrix.m[2][2]; +#endif + + /* Determine image mode (NORMAL, NONE , MULTIPLY or STENCIL) depending on the color. */ + switch(source->image_mode) { + case VG_LITE_NONE_IMAGE_MODE: + imageMode = 0x0; + break; + + case VG_LITE_MULTIPLY_IMAGE_MODE: + imageMode = 0x00002000; + break; + + case VG_LITE_NORMAL_IMAGE_MODE: + case VG_LITE_ZERO: + imageMode = 0x00001000; + break; + + case VG_LITE_STENCIL_MODE: + imageMode = 0x00003000; + break; + + case VG_LITE_RECOLOR_MODE: + imageMode = 0x00006000; + break; + } + + switch(filter) { + case VG_LITE_FILTER_POINT: + filter_mode = 0; + break; + + case VG_LITE_FILTER_LINEAR: + filter_mode = 0x10000; + break; + + case VG_LITE_FILTER_BI_LINEAR: + filter_mode = 0x20000; + break; + + case VG_LITE_FILTER_GAUSSIAN: + filter_mode = 0x30000; + break; + } + + tiled_source = (source->tiled != VG_LITE_LINEAR) ? 0x10000000 : 0 ; + compress_mode = (uint32_t)source->compress_mode << 25; + + if(pattern_mode == VG_LITE_PATTERN_COLOR) { + uint8_t a, r, g, b; + pattern_tile = 0; + a = pattern_color >> 24; + r = pattern_color >> 16; + g = pattern_color >> 8; + b = pattern_color; + pattern_color = (a << 24) | (b << 16) | (g << 8) | r; + } + else if(pattern_mode == VG_LITE_PATTERN_PAD) { + pattern_tile = 0x1000; + } +#if gcFEATURE_VG_IM_REPEAT_REFLECT + else if(pattern_mode == VG_LITE_PATTERN_REPEAT) { + pattern_tile = 0x2000; + } + else if(pattern_mode == VG_LITE_PATTERN_REFLECT) { + pattern_tile = 0x3000; + } +#endif + else { + return VG_LITE_INVALID_ARGUMENT; + } + + if(source->paintType == VG_LITE_PAINT_PATTERN) { + VG_LITE_RETURN_ERROR(push_state_ptr(&s_context, 0x0A04, (void *) &c_step[0])); + VG_LITE_RETURN_ERROR(push_state_ptr(&s_context, 0x0A05, (void *) &c_step[1])); + VG_LITE_RETURN_ERROR(push_state_ptr(&s_context, 0x0A06, (void *) &x_step[0])); + VG_LITE_RETURN_ERROR(push_state_ptr(&s_context, 0x0A07, (void *) &x_step[1])); + VG_LITE_RETURN_ERROR(push_state_ptr(&s_context, 0x0A08, (void *) &y_step[0])); + VG_LITE_RETURN_ERROR(push_state_ptr(&s_context, 0x0A09, (void *) &y_step[1])); + } + + /* Setup the command buffer. */ + VG_LITE_RETURN_ERROR(push_state_ptr(&s_context, 0x0A18, (void *) &c_step[0])); + VG_LITE_RETURN_ERROR(push_state_ptr(&s_context, 0x0A19, (void *) &c_step[1])); + VG_LITE_RETURN_ERROR(push_state_ptr(&s_context, 0x0A1A, (void *) &c_step[2])); + VG_LITE_RETURN_ERROR(push_state_ptr(&s_context, 0x0A1C, (void *) &x_step[0])); + VG_LITE_RETURN_ERROR(push_state_ptr(&s_context, 0x0A1D, (void *) &x_step[1])); + VG_LITE_RETURN_ERROR(push_state_ptr(&s_context, 0x0A1E, (void *) &x_step[2])); + VG_LITE_RETURN_ERROR(push_state(&s_context, 0x0A1F, 0x00000001)); + VG_LITE_RETURN_ERROR(push_state_ptr(&s_context, 0x0A20, (void *) &y_step[0])); + VG_LITE_RETURN_ERROR(push_state_ptr(&s_context, 0x0A21, (void *) &y_step[1])); + VG_LITE_RETURN_ERROR(push_state_ptr(&s_context, 0x0A22, (void *) &y_step[2])); + + if(((source->format >= VG_LITE_YUY2) && + (source->format <= VG_LITE_AYUY2)) || + ((source->format >= VG_LITE_YUY2_TILED) && + (source->format <= VG_LITE_AYUY2_TILED))) { + yuv2rgb = convert_yuv2rgb(source->yuv.yuv2rgb); + uv_swiz = convert_uv_swizzle(source->yuv.swizzle); + } + blend_mode = convert_blend(blend); + + if(source->paintType == VG_LITE_PAINT_PATTERN) { + VG_LITE_RETURN_ERROR(push_state(&s_context, 0x0A24, + convert_source_format(source->format) | filter_mode | pattern_tile | uv_swiz | yuv2rgb | conversion | compress_mode | + src_premultiply_enable | index_endian)); + + if(source->yuv.uv_planar) { + /* Program u plane address if necessary. */ + VG_LITE_RETURN_ERROR(push_state(&s_context, 0x0A50, source->yuv.uv_planar)); + } + if(source->yuv.v_planar) { + /* Program v plane address if necessary. */ + VG_LITE_RETURN_ERROR(push_state(&s_context, 0x0A52, source->yuv.v_planar)); + } + + VG_LITE_RETURN_ERROR(push_state(&s_context, 0x0A26, pattern_color)); + VG_LITE_RETURN_ERROR(push_state(&s_context, 0x0A28, source->address)); + /* 24bit format stride configured to 4bpp. */ + if(source->format >= VG_LITE_RGB888 && source->format <= VG_LITE_RGBA5658) { + stride = source->stride / 3 * 4; + VG_LITE_RETURN_ERROR(push_state(&s_context, 0x0A2A, stride | tiled_source)); + } + else { + VG_LITE_RETURN_ERROR(push_state(&s_context, 0x0A2A, source->stride | tiled_source)); + } + VG_LITE_RETURN_ERROR(push_state(&s_context, 0x0A2C, 0)); + VG_LITE_RETURN_ERROR(push_state(&s_context, 0x0A2E, source->width | (source->height << 16))); + } + else { + VG_LITE_RETURN_ERROR(push_state(&s_context, 0x0A25, + convert_source_format(source->format) | filter_mode | pattern_tile | uv_swiz | yuv2rgb | conversion | compress_mode | + src_premultiply_enable | index_endian)); + + if(source->yuv.uv_planar) { + /* Program u plane address if necessary. */ + VG_LITE_RETURN_ERROR(push_state(&s_context, 0x0A51, source->yuv.uv_planar)); + } + if(source->yuv.v_planar) { + /* Program v plane address if necessary. */ + VG_LITE_RETURN_ERROR(push_state(&s_context, 0x0A53, source->yuv.v_planar)); + } + + VG_LITE_RETURN_ERROR(push_state(&s_context, 0x0A27, pattern_color)); + +#if !gcFEATURE_VG_LVGL_SUPPORT + if(lvgl_sw_blend) { + VG_LITE_RETURN_ERROR(push_state(&s_context, 0x0A29, source->lvgl_buffer->address)); + } + else +#endif + VG_LITE_RETURN_ERROR(push_state(&s_context, 0x0A29, source->address)); + + /* 24bit format stride configured to 4bpp. */ + if(source->format >= VG_LITE_RGB888 && source->format <= VG_LITE_RGBA5658) { + stride = source->stride / 3 * 4; + VG_LITE_RETURN_ERROR(push_state(&s_context, 0x0A2B, stride | tiled_source)); + } + else { + VG_LITE_RETURN_ERROR(push_state(&s_context, 0x0A2B, source->stride | tiled_source)); + } + VG_LITE_RETURN_ERROR(push_state(&s_context, 0x0A2D, 0)); + VG_LITE_RETURN_ERROR(push_state(&s_context, 0x0A2F, source->width | (source->height << 16))); + } + + /* Work on path states. */ + matrix = *path_matrix; + + if(ts_is_fullscreen == 0) { + transform(&temp, (vg_lite_float_t)path->bounding_box[0], (vg_lite_float_t)path->bounding_box[1], &matrix); + point_min = point_max = temp; + + transform(&temp, (vg_lite_float_t)path->bounding_box[2], (vg_lite_float_t)path->bounding_box[1], &matrix); + if(temp.x < point_min.x) point_min.x = temp.x; + if(temp.y < point_min.y) point_min.y = temp.y; + if(temp.x > point_max.x) point_max.x = temp.x; + if(temp.y > point_max.y) point_max.y = temp.y; + + transform(&temp, (vg_lite_float_t)path->bounding_box[2], (vg_lite_float_t)path->bounding_box[3], &matrix); + if(temp.x < point_min.x) point_min.x = temp.x; + if(temp.y < point_min.y) point_min.y = temp.y; + if(temp.x > point_max.x) point_max.x = temp.x; + if(temp.y > point_max.y) point_max.y = temp.y; + + transform(&temp, (vg_lite_float_t)path->bounding_box[0], (vg_lite_float_t)path->bounding_box[3], &matrix); + if(temp.x < point_min.x) point_min.x = temp.x; + if(temp.y < point_min.y) point_min.y = temp.y; + if(temp.x > point_max.x) point_max.x = temp.x; + if(temp.y > point_max.y) point_max.y = temp.y; + + point_min.x = MAX(point_min.x, 0); + point_min.y = MAX(point_min.y, 0); + point_max.x = MIN(point_max.x, target->width); + point_max.y = MIN(point_max.y, target->height); + + if(s_context.scissor_set) { + point_min.x = MAX(point_min.x, s_context.scissor[0]); + point_min.y = MAX(point_min.y, s_context.scissor[1]); + point_max.x = MIN(point_max.x, s_context.scissor[2]); + point_max.y = MIN(point_max.y, s_context.scissor[3]); + } + } + + width = point_max.x - point_min.x; + height = point_max.y - point_min.y; + Scale = 1.0f; + Bias = 0.0f; + new_matrix[0] = matrix.m[0][0] * Scale; + new_matrix[1] = matrix.m[0][1] * Scale; + new_matrix[2] = (matrix.m[0][0] + matrix.m[0][1]) * Bias + matrix.m[0][2]; + new_matrix[3] = matrix.m[1][0] * Scale; + new_matrix[4] = matrix.m[1][1] * Scale; + new_matrix[5] = (matrix.m[1][0] + matrix.m[1][1]) * Bias + matrix.m[1][2]; + + /* Convert states into hardware values. */ + format = convert_path_format(path->format); + quality = convert_path_quality(path->quality); + tiling = (s_context.capabilities.cap.tiled == 2) ? 0x2000000 : 0; + fill = (fill_rule == VG_LITE_FILL_EVEN_ODD) ? 0x10 : 0; + tessellation_size = s_context.tessbuf.tessbuf_size; +#if gcFEATURE_VG_TESSELLATION_TILED_OUT + tile_setting = (target->tiled != VG_LITE_LINEAR) ? 0x40 : 0; +#endif + + if(source->paintType == VG_LITE_PAINT_PATTERN) { + paintType = 1 << 24 | 1 << 25; + } + + /* Setup the command buffer. */ +#if gcFEATURE_VG_GLOBAL_ALPHA + VG_LITE_RETURN_ERROR(push_state(&s_context, 0x0AD1, + s_context.dst_alpha_mode | s_context.dst_alpha_value | s_context.src_alpha_mode | s_context.src_alpha_value)); +#endif + /* Program color register. */ + VG_LITE_RETURN_ERROR(push_state(&s_context, 0x0A00, + in_premult | paintType | s_context.capabilities.cap.tiled | imageMode | blend_mode | transparency_mode | tile_setting | + s_context.enable_mask | s_context.scissor_enable | s_context.color_transform | s_context.matrix_enable | 0x2)); + VG_LITE_RETURN_ERROR(push_state(&s_context, 0x0A34, 0x01000000 | format | quality | tiling | fill)); + VG_LITE_RETURN_ERROR(push_state(&s_context, 0x0A3B, 0x3F800000)); /* Path tessellation SCALE. */ + VG_LITE_RETURN_ERROR(push_state(&s_context, 0x0A3C, 0x00000000)); /* Path tessellation BIAS. */ + VG_LITE_RETURN_ERROR(push_state(&s_context, 0x0A02, color)); + /* Program matrix. */ + VG_LITE_RETURN_ERROR(push_state_ptr(&s_context, 0x0A40, (void *) &new_matrix[0])); + VG_LITE_RETURN_ERROR(push_state_ptr(&s_context, 0x0A41, (void *) &new_matrix[1])); + VG_LITE_RETURN_ERROR(push_state_ptr(&s_context, 0x0A42, (void *) &new_matrix[2])); + VG_LITE_RETURN_ERROR(push_state_ptr(&s_context, 0x0A43, (void *) &new_matrix[3])); + VG_LITE_RETURN_ERROR(push_state_ptr(&s_context, 0x0A44, (void *) &new_matrix[4])); + VG_LITE_RETURN_ERROR(push_state_ptr(&s_context, 0x0A45, (void *) &new_matrix[5])); + VG_LITE_RETURN_ERROR(push_state_ptr(&s_context, 0x0ACD, (void *) &matrix.m[0][2])); + VG_LITE_RETURN_ERROR(push_state_ptr(&s_context, 0x0ACE, (void *) &matrix.m[1][2])); + + if(VLM_PATH_GET_UPLOAD_BIT(*path) == 1) { + if(path->path_changed != 0) { + if(path->uploaded.handle != NULL) { + free_memory.memory_handle = path->uploaded.handle; + vg_lite_kernel(VG_LITE_FREE, &free_memory); + path->uploaded.address = 0; + path->uploaded.memory = NULL; + path->uploaded.handle = NULL; + } + /* Allocate memory for the path data. */ + memory.bytes = 16 + VG_LITE_ALIGN(path->path_length, 8); + return_offset = (8 + VG_LITE_ALIGN(path->path_length, 8)) / 4; + memory.contiguous = 1; + VG_LITE_RETURN_ERROR(vg_lite_kernel(VG_LITE_ALLOCATE, &memory)); + ((uint64_t *) memory.memory)[(path->path_length + 7) / 8] = 0; + ((uint32_t *) memory.memory)[0] = VG_LITE_DATA((path->path_length + 7) / 8); + ((uint32_t *) memory.memory)[1] = 0; + memcpy((uint8_t *) memory.memory + 8, path->path, path->path_length); + ((uint32_t *) memory.memory)[return_offset] = VG_LITE_RETURN(); + ((uint32_t *) memory.memory)[return_offset + 1] = 0; + + path->uploaded.handle = memory.memory_handle; + path->uploaded.memory = memory.memory; + path->uploaded.address = memory.memory_gpu; + path->uploaded.bytes = memory.bytes; + path->path_changed = 0; + } + } + + if(VLM_PATH_GET_UPLOAD_BIT(*path) == 1) { + vglitemDUMP_BUFFER("path", (size_t)path->uploaded.address, (uint8_t *)(path->uploaded.memory), 0, path->uploaded.bytes); + } + +#if !DUMP_COMMAND_CAPTURE + vglitemDUMP("@[memory 0x%08X 0x%08X]", s_context.tessbuf.physical_addr, s_context.tessbuf.tessbuf_size); +#endif + + if(width + point_min.x > target->width) { + width = target->width - point_min.x; + } + +#if (!gcFEATURE_VG_SPLIT_PATH || !gcFEATURE_VG_PARALLEL_PATHS || !gcFEATURE_VG_512_PARALLEL_PATHS) + s_context.tessbuf.tess_w_h = width | (height << 16); + +#if !gcFEATURE_VG_PARALLEL_PATHS + if(height <= 128) + parallel_workpaths1 = 4; + else + parallel_workpaths1 = height * 128 / 4096 - 1; + + if(parallel_workpaths1 > parallel_workpaths2) + parallel_workpaths1 = parallel_workpaths2; +#endif + for(y = point_min.y; y < point_max.y; y += par_height) { +#if !gcFEATURE_VG_512_PARALLEL_PATHS + next_boundary = (y + 512) & 0xfffffe00; +#elif (!gcFEATURE_VG_PARALLEL_PATHS && gcFEATURE_VG_SPLIT_PATH) + next_boundary = (y + 32) & 0xffffffe0; +#else + next_boundary = (y + 16) & 0xfffffff0; +#endif + par_height = ((next_boundary < point_max.y) ? next_boundary - y : (point_max.y - y)); + VG_LITE_RETURN_ERROR(push_state(&s_context, 0x0A00, + in_premult | paintType | s_context.capabilities.cap.tiled | imageMode | blend_mode | transparency_mode | tile_setting | + s_context.enable_mask | s_context.scissor_enable | s_context.color_transform | s_context.matrix_enable | 0x2)); + VG_LITE_RETURN_ERROR(push_state(&s_context, 0x0A34, 0x01000000 | format | quality | tiling | fill)); + VG_LITE_RETURN_ERROR(push_state(&s_context, 0x0A02, color));; + VG_LITE_RETURN_ERROR(push_state(&s_context, 0x0A1B, 0x00011000)); + VG_LITE_RETURN_ERROR(push_state(&s_context, 0x0A3D, tessellation_size / 64)); + VG_LITE_RETURN_ERROR(push_state(&s_context, 0x0A39, point_min.x | (y << 16))); + VG_LITE_RETURN_ERROR(push_state(&s_context, 0x0A3A, width | (par_height << 16))); + + if(VLM_PATH_GET_UPLOAD_BIT(*path) == 1) { + VG_LITE_RETURN_ERROR(push_call(&s_context, path->uploaded.address, path->uploaded.bytes)); + } + else { + if(path->path_type == VG_LITE_DRAW_FILL_PATH || path->path_type == VG_LITE_DRAW_ZERO) + VG_LITE_RETURN_ERROR(push_data(&s_context, path->path_length, path->path)); + if(path->path_type == VG_LITE_DRAW_STROKE_PATH || path->path_type == VG_LITE_DRAW_FILL_STROKE_PATH) { + format = convert_path_format(VG_LITE_FP32); + VG_LITE_RETURN_ERROR(push_state(&s_context, 0x0A34, 0x01000200 | format | quality | tiling | 0x0)); + VG_LITE_RETURN_ERROR(push_state(&s_context, 0x0A02, path->stroke_color)); + VG_LITE_RETURN_ERROR(push_data(&s_context, path->stroke_size, path->stroke_path)); + } +#if !gcFEATURE_VG_PARALLEL_PATHS + s_context.path_counter++; + if(parallel_workpaths1 == s_context.path_counter) { + VG_LITE_RETURN_ERROR(push_stall(&s_context, 7)); + s_context.path_counter = 0; + } +#endif + } + } +#else + { + /* Tessellate path. */ + s_context.tessbuf.tess_w_h = width | (height << 16); + VG_LITE_RETURN_ERROR(push_state(&s_context, 0x0A1B, 0x00011000)); + VG_LITE_RETURN_ERROR(push_state(&s_context, 0x0A3D, tessellation_size / 64)); + VG_LITE_RETURN_ERROR(push_state(&s_context, 0x0A39, point_min.x | (point_min.y << 16))); + VG_LITE_RETURN_ERROR(push_state(&s_context, 0x0A3A, s_context.tessbuf.tess_w_h)); + + if(VLM_PATH_GET_UPLOAD_BIT(*path) == 1) { + VG_LITE_RETURN_ERROR(push_call(&s_context, path->uploaded.address, path->uploaded.bytes)); + } + else { + if(path->path_type == VG_LITE_DRAW_FILL_PATH || path->path_type == VG_LITE_DRAW_ZERO) + VG_LITE_RETURN_ERROR(push_data(&s_context, path->path_length, path->path)); + if(path->path_type == VG_LITE_DRAW_STROKE_PATH || path->path_type == VG_LITE_DRAW_FILL_STROKE_PATH) { + format = convert_path_format(VG_LITE_FP32); + VG_LITE_RETURN_ERROR(push_state(&s_context, 0x0A34, 0x01000200 | format | quality | tiling | 0x0)); + VG_LITE_RETURN_ERROR(push_state(&s_context, 0x0A02, path->stroke_color)); + VG_LITE_RETURN_ERROR(push_data(&s_context, path->stroke_size, path->stroke_path)); + } + } + } +#endif +#if gcFEATURE_VG_GLOBAL_ALPHA + if(blend >= VG_LITE_BLEND_NORMAL_LVGL && blend <= VG_LITE_BLEND_MULTIPLY_LVGL) { + VG_LITE_RETURN_ERROR(vg_lite_dest_global_alpha(VG_LITE_NORMAL, 0xFF)); + } +#endif + vglitemDUMP_BUFFER("image", (size_t)source->address, source->memory, 0, (source->stride) * (source->height)); +#if DUMP_IMAGE + dump_img(source->memory, source->width, source->height, source->format); +#endif + return error; +#else + return VG_LITE_NOT_SUPPORT; +#endif +} + +/* GC555 vg_lite_draw_linear_grad API implementation + */ +vg_lite_error_t vg_lite_draw_linear_grad(vg_lite_buffer_t * target, + vg_lite_path_t * path, + vg_lite_fill_t fill_rule, + vg_lite_matrix_t * path_matrix, + vg_lite_ext_linear_gradient_t * grad, + vg_lite_color_t paint_color, + vg_lite_blend_t blend, + vg_lite_filter_t filter) +{ +#if DUMP_API + FUNC_DUMP(vg_lite_draw_linear_grad)(target, path, fill_rule, path_matrix, grad, paint_color, blend, filter); +#endif + +#if gcFEATURE_VG_LINEAR_GRADIENT_EXT && gcFEATURE_VG_IM_INPUT + vg_lite_error_t error = VG_LITE_SUCCESS; + uint32_t image_mode = 0; + uint32_t blend_mode; + uint32_t filter_mode = 0; + uint32_t conversion = 0; + uint32_t tiled_source; + vg_lite_matrix_t inverse_matrix; + vg_lite_float_t x_step[3]; + vg_lite_float_t y_step[3]; + vg_lite_float_t c_step[3]; + vg_lite_buffer_t * source = &grad->image; + vg_lite_matrix_t * matrix = &grad->matrix; + uint32_t linear_tile = 0; + uint32_t transparency_mode = 0; + uint32_t yuv2rgb = 0; + uint32_t uv_swiz = 0; + uint32_t in_premult = 0; + uint32_t src_premultiply_enable = 0; + uint32_t premul_flag = 0; + uint32_t prediv_flag = 0; + void * data; + + /* The following code is from "draw path" */ + uint32_t format, quality, tiling, fill; + uint32_t tessellation_size; + + vg_lite_kernel_allocate_t memory; + vg_lite_kernel_free_t free_memory; + uint32_t return_offset = 0; + + vg_lite_point_t point_min = { 0 }, point_max = { 0 }, temp = { 0 }; + int width, height; + uint8_t ts_is_fullscreen = 0; + float new_matrix[6]; + float Scale, Bias; + + vg_lite_float_t dx, dy, dxdx_dydy; + vg_lite_float_t lg_step_x_lin, lg_step_y_lin, lg_constant_lin; + +#if !gcFEATURE_VG_PARALLEL_PATHS + uint32_t parallel_workpaths1 = 2; + uint32_t parallel_workpaths2 = 2; + +#endif + + int y; + int temp_height = 0; + +#if gcFEATURE_VG_TRACE_API + VGLITE_LOG("vg_lite_draw_linear_grad %p %p %d %p %p 0x%08X %d %d\n", + target, path, fill_rule, path_matrix, grad, paint_color, blend, filter); +#endif + +#if gcFEATURE_VG_ERROR_CHECK +#if !gcFEATURE_VG_QUALITY_8X + if(path->quality == VG_LITE_UPPER) { + return VG_LITE_NOT_SUPPORT; + } +#endif +#if !gcFEATURE_VG_LVGL_SUPPORT + if((blend >= VG_LITE_BLEND_NORMAL_LVGL && blend <= VG_LITE_BLEND_MULTIPLY_LVGL)) { + return VG_LITE_NOT_SUPPORT; + } +#endif +#if !gcFEATURE_VG_24BIT + if(target->format >= VG_LITE_RGB888 && target->format <= VG_LITE_RGBA5658) { + return VG_LITE_NOT_SUPPORT; + } +#endif + +#if !gcFEATURE_VG_STENCIL + if(source->image_mode == VG_LITE_STENCIL_MODE) { + return VG_LITE_NOT_SUPPORT; + } +#endif +#if !gcFEATURE_VG_NEW_BLEND_MODE + if(blend == VG_LITE_BLEND_DARKEN || blend == VG_LITE_BLEND_LIGHTEN) { + return VG_LITE_NOT_SUPPORT; + } +#endif +#if !gcFEATURE_VG_IM_REPEAT_REFLECT + if(grad->spread_mode == VG_LITE_GRADIENT_SPREAD_REPEAT || grad->spread_mode == VG_LITE_GRADIENT_SPREAD_REFLECT) { + return VG_LITE_NOT_SUPPORT; + } +#endif + if(source->format == VG_LITE_A4 || source->format == VG_LITE_A8) { + return VG_LITE_NOT_SUPPORT; + } + if(!path || !path->path) { + return VG_LITE_INVALID_ARGUMENT; + } +#endif /* gcFEATURE_VG_ERROR_CHECK */ + + if(!path->path_length) { + return VG_LITE_SUCCESS; + } + + if(!path_matrix) { + path_matrix = &identity_mtx; + } + +#if gcFEATURE_VG_GAMMA + set_gamma_dest_only(target, VGL_TRUE); +#endif +#if gcFEATURE_VG_GLOBAL_ALPHA + if(blend >= VG_LITE_BLEND_NORMAL_LVGL && blend <= VG_LITE_BLEND_MULTIPLY_LVGL) { + VG_LITE_RETURN_ERROR(vg_lite_dest_global_alpha(VG_LITE_GLOBAL, 0xff)); + } +#endif + /*blend input into context*/ + s_context.blend_mode = blend; + + src_premultiply_enable = 0x01000100; + if(s_context.color_transform == 0 && s_context.gamma_dst == s_context.gamma_src && s_context.matrix_enable == 0 && + s_context.dst_alpha_mode == 0 && s_context.src_alpha_mode == 0 && + (source->image_mode == VG_LITE_NORMAL_IMAGE_MODE || source->image_mode == 0)) { + prediv_flag = 0; + } + else { + prediv_flag = 1; + } + if((s_context.blend_mode >= OPENVG_BLEND_SRC_OVER && s_context.blend_mode <= OPENVG_BLEND_ADDITIVE) || + source->image_mode == VG_LITE_STENCIL_MODE + || (s_context.blend_mode >= VG_LITE_BLEND_NORMAL_LVGL && s_context.blend_mode <= VG_LITE_BLEND_MULTIPLY_LVGL)) { + premul_flag = 1; + } + else { + premul_flag = 0; + } + + if((source->premultiplied == 0 && target->premultiplied == 0 && premul_flag == 0) || + (source->premultiplied == 1 && target->premultiplied == 0 && prediv_flag == 0)) { + src_premultiply_enable = 0x01000100; + in_premult = 0x10000000; + } + /* when src and dst all pre format, im pre_out set to 0 to perform data truncation to prevent data overflow */ + else if(source->premultiplied == 1 && target->premultiplied == 1 && prediv_flag == 0) { + src_premultiply_enable = 0x00000100; + in_premult = 0x00000000; + } + else if((source->premultiplied == 0 && target->premultiplied == 1) || + (source->premultiplied == 0 && target->premultiplied == 0 && premul_flag == 1)) { + src_premultiply_enable = 0x01000100; + in_premult = 0x00000000; + } + else if((source->premultiplied == 1 && target->premultiplied == 1 && prediv_flag == 1) || + (source->premultiplied == 1 && target->premultiplied == 0 && prediv_flag == 1)) { + src_premultiply_enable = 0x00000100; + in_premult = 0x00000000; + } + if((source->format == VG_LITE_A4 || source->format == VG_LITE_A8) && blend >= VG_LITE_BLEND_SRC_OVER && + blend <= VG_LITE_BLEND_SUBTRACT) { +#if (CHIPID==0x255) + src_premultiply_enable = 0x00000000; +#endif + in_premult = 0x00000000; + } + if(source->premultiplied == target->premultiplied && premul_flag == 0) { + target->apply_premult = 1; + } + else { + target->apply_premult = 0; + } + + error = set_render_target(target); + if(error != VG_LITE_SUCCESS) { + return error; + } + else if(error == VG_LITE_NO_CONTEXT) { + /* If scissoring is enabled and no valid scissoring rectangles + are present, no drawing occurs */ + return VG_LITE_SUCCESS; + } + + transparency_mode = (source->transparency_mode == VG_LITE_IMAGE_TRANSPARENT ? 0x8000 : 0); + width = s_context.tessbuf.tess_w_h & 0xFFFF; + height = s_context.tessbuf.tess_w_h >> 16; + + if(width == 0 || height == 0) + return VG_LITE_NO_CONTEXT; + if((target->width <= width) && (target->height <= height) && (!s_context.scissor_set)) { + ts_is_fullscreen = 1; + point_min.x = 0; + point_min.y = 0; + point_max.x = target->width; + point_max.y = target->height; + } + + /* If target is L8 and source is in YUV or RGB (not L8 or A8) then we have to convert RGB into L8. */ + if((target->format == VG_LITE_L8) && ((source->format != VG_LITE_L8) && (source->format != VG_LITE_A8))) { + conversion = 0x80000000; + } + + /* Determine image mode (NORMAL, NONE , MULTIPLY or STENCIL) depending on the color. */ + switch(source->image_mode) { + case VG_LITE_NONE_IMAGE_MODE: + image_mode = 0x0; + break; + + case VG_LITE_MULTIPLY_IMAGE_MODE: + return VG_LITE_INVALID_ARGUMENT; + + case VG_LITE_NORMAL_IMAGE_MODE: + case VG_LITE_ZERO: + image_mode = 0x00001000; + break; + + case VG_LITE_STENCIL_MODE: + image_mode = 0x00003000; + break; + + case VG_LITE_RECOLOR_MODE: + image_mode = 0x00006000; + break; + } + tiled_source = (source->tiled != VG_LITE_LINEAR) ? 0x10000000 : 0 ; + + switch(grad->spread_mode) { + case VG_LITE_GRADIENT_SPREAD_FILL: + linear_tile = 0x0; + break; + + case VG_LITE_GRADIENT_SPREAD_PAD: + linear_tile = 0x1000; + break; + + case VG_LITE_GRADIENT_SPREAD_REPEAT: + linear_tile = 0x2000; + break; + + case VG_LITE_GRADIENT_SPREAD_REFLECT: + linear_tile = 0x3000; + break; + } + + switch(filter) { + case VG_LITE_FILTER_POINT: + filter_mode = 0; + break; + + case VG_LITE_FILTER_LINEAR: + filter_mode = 0x10000; + break; + + case VG_LITE_FILTER_BI_LINEAR: + filter_mode = 0x20000; + break; + + case VG_LITE_FILTER_GAUSSIAN: + filter_mode = 0x30000; + break; + } + + if(grad->spread_mode == VG_LITE_GRADIENT_SPREAD_FILL) { + uint8_t a, r, g, b; + a = paint_color >> 24; + r = paint_color >> 16; + g = paint_color >> 8; + b = paint_color; + paint_color = (a << 24) | (b << 16) | (g << 8) | r; + } + + /* compute linear gradient paremeters */ + + /* Compute inverse matrix. */ + if(!inverse(&inverse_matrix, matrix)) + return VG_LITE_INVALID_ARGUMENT; + + dx = grad->linear_grad.X1 - grad->linear_grad.X0; + dy = grad->linear_grad.Y1 - grad->linear_grad.Y0; +#if gcFEATURE_VG_MATH_PRECISION_FIX + dxdx_dydy = (vg_lite_float_t)((dx * dx + dy * dy) / sqrt((dx + 1) * (dx + 1) + (dy + 1) * (dy + 1))); +#else + dxdx_dydy = dx * dx + dy * dy; +#endif + + /* + ** dx (T(x) - x0) + dy (T(y) - y0) + ** g = ------------------------------- + ** dx^2 + dy^2 + ** + ** where + ** + ** dx := x1 - x0 + ** dy := y1 - y0 + ** T(x) := (x + 0.5) m00 + (y + 0.5) m01 + m02 + ** = x m00 + y m01 + 0.5 (m00 + m01) + m02 + ** T(y) := (x + 0.5) m10 + (y + 0.5) m11 + m12 + ** = x m10 + y m11 + 0.5 (m10 + m11) + m12. + ** + ** We can factor the top line into: + ** + ** = dx (x m00 + y m01 + 0.5 (m00 + m01) + m02 - x0) + ** + dy (x m10 + y m11 + 0.5 (m10 + m11) + m12 - y0) + ** + ** = x (dx m00 + dy m10) + ** + y (dx m01 + dy m11) + ** + dx (0.5 (m00 + m01) + m02 - x0) + ** + dy (0.5 (m10 + m11) + m12 - y0). + */ + + lg_step_x_lin + = (dx * MAT(&inverse_matrix, 0, 0) + dy * MAT(&inverse_matrix, 1, 0)) + / dxdx_dydy; + + lg_step_y_lin + = (dx * MAT(&inverse_matrix, 0, 1) + dy * MAT(&inverse_matrix, 1, 1)) + / dxdx_dydy; + + lg_constant_lin = + ( + ( + 0.5f * (MAT(&inverse_matrix, 0, 0) + MAT(&inverse_matrix, 0, 1)) + + MAT(&inverse_matrix, 0, 2) - grad->linear_grad.X0 + ) * dx + + + + + ( + 0.5f * (MAT(&inverse_matrix, 1, 0) + MAT(&inverse_matrix, 1, 1)) + + MAT(&inverse_matrix, 1, 2) - grad->linear_grad.Y0 + ) * dy + ) + / dxdx_dydy; + + /* Setup the command buffer. */ + + /* linear gradient parameters*/ + data = &lg_constant_lin; + VG_LITE_RETURN_ERROR(push_state(&s_context, 0x0A04, *(uint32_t *) data)); + data = &lg_step_x_lin; + VG_LITE_RETURN_ERROR(push_state(&s_context, 0x0A06, *(uint32_t *) data)); + data = &lg_step_y_lin; + VG_LITE_RETURN_ERROR(push_state(&s_context, 0x0A08, *(uint32_t *) data)); + + /* Compute inverse matrix. */ + if(!inverse(&inverse_matrix, matrix)) + return VG_LITE_INVALID_ARGUMENT; + +#if gcFEATURE_VG_MATH_PRECISION_FIX + /* Compute interpolation steps. */ + x_step[0] = inverse_matrix.m[0][0]; + x_step[1] = inverse_matrix.m[1][0]; + x_step[2] = inverse_matrix.m[2][0]; + y_step[0] = inverse_matrix.m[0][1]; + y_step[1] = inverse_matrix.m[1][1]; + y_step[2] = inverse_matrix.m[2][1]; + c_step[0] = (0.5f * (inverse_matrix.m[0][0] + inverse_matrix.m[0][1]) + inverse_matrix.m[0][2]); + c_step[1] = (0.5f * (inverse_matrix.m[1][0] + inverse_matrix.m[1][1]) + inverse_matrix.m[1][2]); + c_step[2] = 0.5f * (inverse_matrix.m[2][0] + inverse_matrix.m[2][1]) + inverse_matrix.m[2][2]; +#else + /* Compute interpolation steps. */ + x_step[0] = inverse_matrix.m[0][0] / source->width; + x_step[1] = inverse_matrix.m[1][0] / source->height; + x_step[2] = inverse_matrix.m[2][0]; + y_step[0] = inverse_matrix.m[0][1] / source->width; + y_step[1] = inverse_matrix.m[1][1] / source->height; + y_step[2] = inverse_matrix.m[2][1]; + c_step[0] = (0.5f * (inverse_matrix.m[0][0] + inverse_matrix.m[0][1]) + inverse_matrix.m[0][2]) / source->width; + c_step[1] = (0.5f * (inverse_matrix.m[1][0] + inverse_matrix.m[1][1]) + inverse_matrix.m[1][2]) / source->height; + c_step[2] = 0.5f * (inverse_matrix.m[2][0] + inverse_matrix.m[2][1]) + inverse_matrix.m[2][2]; +#endif + + /* Setup the command buffer. */ + VG_LITE_RETURN_ERROR(push_state_ptr(&s_context, 0x0A18, (void *) &c_step[0])); + VG_LITE_RETURN_ERROR(push_state_ptr(&s_context, 0x0A19, (void *) &c_step[1])); + VG_LITE_RETURN_ERROR(push_state_ptr(&s_context, 0x0A1A, (void *) &c_step[2])); + VG_LITE_RETURN_ERROR(push_state_ptr(&s_context, 0x0A1C, (void *) &x_step[0])); + VG_LITE_RETURN_ERROR(push_state_ptr(&s_context, 0x0A1D, (void *) &x_step[1])); + VG_LITE_RETURN_ERROR(push_state_ptr(&s_context, 0x0A1E, (void *) &x_step[2])); + VG_LITE_RETURN_ERROR(push_state(&s_context, 0x0A1F, 0x00000001)); + VG_LITE_RETURN_ERROR(push_state_ptr(&s_context, 0x0A20, (void *) &y_step[0])); + VG_LITE_RETURN_ERROR(push_state_ptr(&s_context, 0x0A21, (void *) &y_step[1])); + VG_LITE_RETURN_ERROR(push_state_ptr(&s_context, 0x0A22, (void *) &y_step[2])); + + if(((source->format >= VG_LITE_YUY2) && + (source->format <= VG_LITE_AYUY2)) || + ((source->format >= VG_LITE_YUY2_TILED) && + (source->format <= VG_LITE_AYUY2_TILED))) { + yuv2rgb = convert_yuv2rgb(source->yuv.yuv2rgb); + uv_swiz = convert_uv_swizzle(source->yuv.swizzle); + } + + if(source->yuv.uv_planar) { + /* Program u plane address if necessary. */ + VG_LITE_RETURN_ERROR(push_state(&s_context, 0x0A51, source->yuv.uv_planar)); + } + if(source->yuv.v_planar) { + /* Program v plane address if necessary. */ + VG_LITE_RETURN_ERROR(push_state(&s_context, 0x0A53, source->yuv.v_planar)); + } + + VG_LITE_RETURN_ERROR(push_state(&s_context, 0x0A24, convert_source_format(source->format) | + filter_mode | uv_swiz | yuv2rgb | linear_tile | conversion | src_premultiply_enable)); + VG_LITE_RETURN_ERROR(push_state(&s_context, 0x0A26, paint_color)); + VG_LITE_RETURN_ERROR(push_state(&s_context, 0x0A28, source->address)); + + VG_LITE_RETURN_ERROR(push_state(&s_context, 0x0A2A, tiled_source)); + VG_LITE_RETURN_ERROR(push_state(&s_context, 0x0A2C, 0)); + VG_LITE_RETURN_ERROR(push_state(&s_context, 0x0A2E, source->width | (source->height << 16))); + + /* Work on path states. */ + matrix = path_matrix; + + if(ts_is_fullscreen == 0) { + transform(&temp, (vg_lite_float_t)path->bounding_box[0], (vg_lite_float_t)path->bounding_box[1], matrix); + point_min = point_max = temp; + + transform(&temp, (vg_lite_float_t)path->bounding_box[2], (vg_lite_float_t)path->bounding_box[1], matrix); + if(temp.x < point_min.x) point_min.x = temp.x; + if(temp.y < point_min.y) point_min.y = temp.y; + if(temp.x > point_max.x) point_max.x = temp.x; + if(temp.y > point_max.y) point_max.y = temp.y; + + transform(&temp, (vg_lite_float_t)path->bounding_box[2], (vg_lite_float_t)path->bounding_box[3], matrix); + if(temp.x < point_min.x) point_min.x = temp.x; + if(temp.y < point_min.y) point_min.y = temp.y; + if(temp.x > point_max.x) point_max.x = temp.x; + if(temp.y > point_max.y) point_max.y = temp.y; + + transform(&temp, (vg_lite_float_t)path->bounding_box[0], (vg_lite_float_t)path->bounding_box[3], matrix); + if(temp.x < point_min.x) point_min.x = temp.x; + if(temp.y < point_min.y) point_min.y = temp.y; + if(temp.x > point_max.x) point_max.x = temp.x; + if(temp.y > point_max.y) point_max.y = temp.y; + + point_min.x = MAX(point_min.x, 0); + point_min.y = MAX(point_min.y, 0); + point_max.x = MIN(point_max.x, target->width); + point_max.y = MIN(point_max.y, target->height); + + if(s_context.scissor_set) { + point_min.x = MAX(point_min.x, s_context.scissor[0]); + point_min.y = MAX(point_min.y, s_context.scissor[1]); + point_max.x = MIN(point_max.x, s_context.scissor[2]); + point_max.y = MIN(point_max.y, s_context.scissor[3]); + } + } + + Scale = 1.0f; + Bias = 0.0f; + new_matrix[0] = matrix->m[0][0] * Scale; + new_matrix[1] = matrix->m[0][1] * Scale; + new_matrix[2] = (matrix->m[0][0] + matrix->m[0][1]) * Bias + matrix->m[0][2]; + new_matrix[3] = matrix->m[1][0] * Scale; + new_matrix[4] = matrix->m[1][1] * Scale; + new_matrix[5] = (matrix->m[1][0] + matrix->m[1][1]) * Bias + matrix->m[1][2]; + + /* Convert states into hardware values. */ + blend_mode = convert_blend(blend); + format = convert_path_format(path->format); + quality = convert_path_quality(path->quality); + tiling = (s_context.capabilities.cap.tiled == 2) ? 0x2000000 : 0; + fill = (fill_rule == VG_LITE_FILL_EVEN_ODD) ? 0x10 : 0; + tessellation_size = s_context.tessbuf.tessbuf_size; + + /* Setup the command buffer. */ + /* Program color register. */ + VG_LITE_RETURN_ERROR(push_state(&s_context, 0x0A00, + 0x01000002 | s_context.capabilities.cap.tiled | in_premult | image_mode | blend_mode | transparency_mode | + s_context.enable_mask | s_context.color_transform | s_context.matrix_enable | s_context.scissor_enable)); + VG_LITE_RETURN_ERROR(push_state(&s_context, 0x0A34, 0x01000400 | format | quality | tiling | fill)); + VG_LITE_RETURN_ERROR(push_state(&s_context, 0x0A3B, 0x3F800000)); /* Path tessellation SCALE. */ + VG_LITE_RETURN_ERROR(push_state(&s_context, 0x0A3C, 0x00000000)); /* Path tessellation BIAS. */ + /* Program matrix. */ + VG_LITE_RETURN_ERROR(push_state_ptr(&s_context, 0x0A40, (void *) &new_matrix[0])); + VG_LITE_RETURN_ERROR(push_state_ptr(&s_context, 0x0A41, (void *) &new_matrix[1])); + VG_LITE_RETURN_ERROR(push_state_ptr(&s_context, 0x0A42, (void *) &new_matrix[2])); + VG_LITE_RETURN_ERROR(push_state_ptr(&s_context, 0x0A43, (void *) &new_matrix[3])); + VG_LITE_RETURN_ERROR(push_state_ptr(&s_context, 0x0A44, (void *) &new_matrix[4])); + VG_LITE_RETURN_ERROR(push_state_ptr(&s_context, 0x0A45, (void *) &new_matrix[5])); + VG_LITE_RETURN_ERROR(push_state_ptr(&s_context, 0x0ACD, (void *) &matrix->m[0][2])); + VG_LITE_RETURN_ERROR(push_state_ptr(&s_context, 0x0ACE, (void *) &matrix->m[1][2])); + + if(VLM_PATH_GET_UPLOAD_BIT(*path) == 1) { + if(path->path_changed != 0) { + if(path->uploaded.handle != NULL) { + free_memory.memory_handle = path->uploaded.handle; + vg_lite_kernel(VG_LITE_FREE, &free_memory); + path->uploaded.address = 0; + path->uploaded.memory = NULL; + path->uploaded.handle = NULL; + } + /* Allocate memory for the path data. */ + memory.bytes = 16 + VG_LITE_ALIGN(path->path_length, 8); + return_offset = (8 + VG_LITE_ALIGN(path->path_length, 8)) / 4; + memory.contiguous = 1; + VG_LITE_RETURN_ERROR(vg_lite_kernel(VG_LITE_ALLOCATE, &memory)); + ((uint64_t *) memory.memory)[(path->path_length + 7) / 8] = 0; + ((uint32_t *) memory.memory)[0] = VG_LITE_DATA((path->path_length + 7) / 8); + ((uint32_t *) memory.memory)[1] = 0; + memcpy((uint8_t *) memory.memory + 8, path->path, path->path_length); + ((uint32_t *) memory.memory)[return_offset] = VG_LITE_RETURN(); + ((uint32_t *) memory.memory)[return_offset + 1] = 0; + + path->uploaded.handle = memory.memory_handle; + path->uploaded.memory = memory.memory; + path->uploaded.address = memory.memory_gpu; + path->uploaded.bytes = memory.bytes; + path->path_changed = 0; + } + } + + if(VLM_PATH_GET_UPLOAD_BIT(*path) == 1) { + vglitemDUMP_BUFFER("path", (size_t)path->uploaded.address, (uint8_t *)(path->uploaded.memory), 0, path->uploaded.bytes); + } + +#if !DUMP_COMMAND_CAPTURE + vglitemDUMP("@[memory 0x%08X 0x%08X]", s_context.tessbuf.physical_addr, s_context.tessbuf.tessbuf_size); +#endif + + if(width + point_min.x > target->width) { + width = target->width - point_min.x; + } + +#if (gcFEATURE_VG_PARALLEL_PATHS && gcFEATURE_VG_512_PARALLEL_PATHS) + { + /* Tessellate path. */ + s_context.tessbuf.tess_w_h = width | (height << 16); + VG_LITE_RETURN_ERROR(push_state(&s_context, 0x0A1B, 0x00011000)); + VG_LITE_RETURN_ERROR(push_state(&s_context, 0x0A3D, tessellation_size / 64)); + VG_LITE_RETURN_ERROR(push_state(&s_context, 0x0A39, point_min.x | (point_min.y << 16))); + VG_LITE_RETURN_ERROR(push_state(&s_context, 0x0A3A, s_context.tessbuf.tess_w_h)); + + if(VLM_PATH_GET_UPLOAD_BIT(*path) == 1) { + VG_LITE_RETURN_ERROR(push_call(&s_context, path->uploaded.address, path->uploaded.bytes)); + } + else { + if(path->path_type == VG_LITE_DRAW_FILL_PATH || path->path_type == VG_LITE_DRAW_ZERO) + VG_LITE_RETURN_ERROR(push_data(&s_context, path->path_length, path->path)); + if(path->path_type == VG_LITE_DRAW_STROKE_PATH || path->path_type == VG_LITE_DRAW_FILL_STROKE_PATH) { + format = convert_path_format(VG_LITE_FP32); + VG_LITE_RETURN_ERROR(push_state(&s_context, 0x0A34, 0x01000200 | format | quality | tiling | 0x0)); + VG_LITE_RETURN_ERROR(push_state(&s_context, 0x0A02, path->stroke_color)); + VG_LITE_RETURN_ERROR(push_data(&s_context, path->stroke_size, path->stroke_path)); + } + } + } +#else + { + height = s_context.tessbuf.tess_w_h >> 16; + if(path->path_type == VG_LITE_DRAW_FILL_PATH || path->path_type == VG_LITE_DRAW_ZERO) { +#if gcFEATURE_VG_512_PARALLEL_PATHS + if(height <= 128) + parallel_workpaths1 = 4; + else + parallel_workpaths1 = height * 128 / 4096 - 1; + + if(parallel_workpaths1 > parallel_workpaths2) + parallel_workpaths1 = parallel_workpaths2; +#endif + for(y = point_min.y; y < point_max.y; y += height) { + VG_LITE_RETURN_ERROR(push_state(&s_context, 0x0A1B, 0x00011000)); + VG_LITE_RETURN_ERROR(push_state(&s_context, 0x0A3D, tessellation_size / 64)); + VG_LITE_RETURN_ERROR(push_state(&s_context, 0x0A39, point_min.x | (y << 16))); + if(y + height > target->height) { + temp_height = target->height - y; + VG_LITE_RETURN_ERROR(push_state(&s_context, 0x0A3A, width | (temp_height << 16))); + } + else { + VG_LITE_RETURN_ERROR(push_state(&s_context, 0x0A3A, width | (height << 16))); + } + + if(VLM_PATH_GET_UPLOAD_BIT(*path) == 1) { + VG_LITE_RETURN_ERROR(push_call(&s_context, path->uploaded.address, path->uploaded.bytes)); + } + else { + VG_LITE_RETURN_ERROR(push_data(&s_context, path->path_length, path->path)); +#if gcFEATURE_VG_512_PARALLEL_PATHS + s_context.path_counter ++; + if(parallel_workpaths1 == s_context.path_counter) { + VG_LITE_RETURN_ERROR(push_state(&s_context, 0x0E02, 0x10 | (0x7 << 8))); + VG_LITE_RETURN_ERROR(push_state(&s_context, 0x0F00, 0x10 | (0x7 << 8))); + s_context.path_counter = 0; + } +#endif + } + } + } + + if(path->path_type == VG_LITE_DRAW_STROKE_PATH || path->path_type == VG_LITE_DRAW_FILL_STROKE_PATH) { + for(y = point_min.y; y < point_max.y; y += height) { + VG_LITE_RETURN_ERROR(push_state(&s_context, 0x0A1B, 0x00011000)); + VG_LITE_RETURN_ERROR(push_state(&s_context, 0x0A3D, tessellation_size / 64)); + VG_LITE_RETURN_ERROR(push_state(&s_context, 0x0A39, point_min.x | (y << 16))); + if(y + height > target->height) { + temp_height = target->height - y; + VG_LITE_RETURN_ERROR(push_state(&s_context, 0x0A3A, width | (temp_height << 16))); + } + else { + VG_LITE_RETURN_ERROR(push_state(&s_context, 0x0A3A, width | (height << 16))); + } + + if(VLM_PATH_GET_UPLOAD_BIT(*path) == 1) { + VG_LITE_RETURN_ERROR(push_call(&s_context, path->uploaded.address, path->uploaded.bytes)); + } + else { + format = convert_path_format(VG_LITE_FP32); + VG_LITE_RETURN_ERROR(push_state(&s_context, 0x0A34, 0x01000200 | format | quality | tiling | 0x0)); + VG_LITE_RETURN_ERROR(push_state(&s_context, 0x0A02, path->stroke_color)); + VG_LITE_RETURN_ERROR(push_data(&s_context, path->stroke_size, path->stroke_path)); +#if gcFEATURE_VG_512_PARALLEL_PATHS + s_context.path_counter ++; + if(parallel_workpaths1 == s_context.path_counter) { + VG_LITE_RETURN_ERROR(push_state(&s_context, 0x0E02, 0x10 | (0x7 << 8))); + VG_LITE_RETURN_ERROR(push_state(&s_context, 0x0F00, 0x10 | (0x7 << 8))); + s_context.path_counter = 0; + } +#endif + } + } + } + } +#endif + + /* Finialize command buffer. */ + VG_LITE_RETURN_ERROR(push_state(&s_context, 0x0A34, 0)); +#if gcFEATURE_VG_GLOBAL_ALPHA + if(blend >= VG_LITE_BLEND_NORMAL_LVGL && blend <= VG_LITE_BLEND_MULTIPLY_LVGL) { + VG_LITE_RETURN_ERROR(vg_lite_dest_global_alpha(VG_LITE_NORMAL, 0xFF)); + } +#endif + vglitemDUMP_BUFFER("image", (size_t)source->address, source->memory, 0, (source->stride) * (source->height)); +#if DUMP_IMAGE + dump_img(source->memory, source->width, source->height, source->format); +#endif + + return error; +#else + return VG_LITE_NOT_SUPPORT; +#endif +} + +/* GC555 vg_lite_draw_radial_grad API implementation + */ +vg_lite_error_t vg_lite_draw_radial_grad(vg_lite_buffer_t * target, + vg_lite_path_t * path, + vg_lite_fill_t fill_rule, + vg_lite_matrix_t * path_matrix, + vg_lite_radial_gradient_t * grad, + vg_lite_color_t paint_color, + vg_lite_blend_t blend, + vg_lite_filter_t filter) +{ +#if DUMP_API + FUNC_DUMP(vg_lite_draw_radial_grad)(target, path, fill_rule, path_matrix, grad, paint_color, blend, filter); +#endif + +#if gcFEATURE_VG_RADIAL_GRADIENT && gcFEATURE_VG_IM_INPUT + vg_lite_error_t error = VG_LITE_SUCCESS; + uint32_t imageMode = 0; + uint32_t blend_mode; + uint32_t filter_mode = 0; + uint32_t conversion = 0; + uint32_t tiled_source; + vg_lite_matrix_t inverse_matrix; + vg_lite_float_t x_step[3]; + vg_lite_float_t y_step[3]; + vg_lite_float_t c_step[3]; + vg_lite_buffer_t * source = &grad->image; + vg_lite_matrix_t * matrix = &grad->matrix; + uint32_t rad_tile = 0; + uint32_t transparency_mode = 0; + uint32_t yuv2rgb = 0; + uint32_t uv_swiz = 0; + void * data; + uint32_t compress_mode; + uint32_t in_premult = 0; + uint32_t src_premultiply_enable = 0; + uint32_t premul_flag = 0; + uint32_t prediv_flag = 0; + + /* The following code is from "draw path" */ + uint32_t format, quality, tiling, fill; + uint32_t tessellation_size; + + vg_lite_kernel_allocate_t memory; + vg_lite_kernel_free_t free_memory; + uint32_t return_offset = 0; + + vg_lite_point_t point_min = { 0 }, point_max = { 0 }, temp = { 0 }; + int width, height; + uint8_t ts_is_fullscreen = 0; + float new_matrix[6]; + float Scale, Bias; + + vg_lite_float_t radius; + + vg_lite_float_t centerX, centerY; + vg_lite_float_t focalX, focalY; + vg_lite_float_t fx, fy; + vg_lite_float_t fxfy_2; + vg_lite_float_t radius2; + vg_lite_float_t r2_fx2, r2_fy2; + vg_lite_float_t r2_fx2_2, r2_fy2_2; + vg_lite_float_t r2_fx2_fy2; + vg_lite_float_t r2_fx2_fy2sq; + vg_lite_float_t cx, cy; + + vg_lite_float_t rgConstantLin, rgStepXLin, rgStepYLin; + vg_lite_float_t rgConstantRad, rgStepXRad, rgStepYRad; + vg_lite_float_t rgStepXXRad, rgStepYYRad, rgStepXYRad; + + int y; + int temp_height = 0; + +#if !gcFEATURE_VG_PARALLEL_PATHS + uint32_t parallel_workpaths1 = 2; + uint32_t parallel_workpaths2 = 2; +#endif + +#if gcFEATURE_VG_TRACE_API + VGLITE_LOG("vg_lite_draw_radial_grad %p %p %d %p %p 0x%08X %d %d\n", + target, path, fill_rule, path_matrix, grad, paint_color, blend, filter); +#endif + +#if gcFEATURE_VG_ERROR_CHECK +#if !gcFEATURE_VG_QUALITY_8X + if(path->quality == VG_LITE_UPPER) { + return VG_LITE_NOT_SUPPORT; + } +#endif +#if !gcFEATURE_VG_LVGL_SUPPORT + if((blend >= VG_LITE_BLEND_NORMAL_LVGL && blend <= VG_LITE_BLEND_MULTIPLY_LVGL)) { + return VG_LITE_NOT_SUPPORT; + } +#endif +#if !gcFEATURE_VG_24BIT + if(target->format >= VG_LITE_RGB888 && target->format <= VG_LITE_RGBA5658) { + return VG_LITE_NOT_SUPPORT; + } +#endif + +#if !gcFEATURE_VG_STENCIL + if(source->image_mode == VG_LITE_STENCIL_MODE) { + return VG_LITE_NOT_SUPPORT; + } +#endif +#if !gcFEATURE_VG_NEW_BLEND_MODE + if(blend == VG_LITE_BLEND_DARKEN || blend == VG_LITE_BLEND_LIGHTEN) { + return VG_LITE_NOT_SUPPORT; + } +#endif +#if !gcFEATURE_VG_IM_REPEAT_REFLECT + if(grad->spread_mode == VG_LITE_GRADIENT_SPREAD_REPEAT || grad->spread_mode == VG_LITE_GRADIENT_SPREAD_REFLECT) { + return VG_LITE_NOT_SUPPORT; + } +#endif + if(source->format == VG_LITE_A4 || source->format == VG_LITE_A8) { + return VG_LITE_NOT_SUPPORT; + } + if(!path || !path->path) { + return VG_LITE_INVALID_ARGUMENT; + } + radius = grad->radial_grad.r; + if(radius < 0) { + return VG_LITE_INVALID_ARGUMENT; + } + VG_LITE_RETURN_ERROR(check_compress(source->format, source->compress_mode, source->tiled, source->width, + source->height)); +#endif /* gcFEATURE_VG_ERROR_CHECK */ + + if(!path->path_length) { + return VG_LITE_SUCCESS; + } + + if(!path_matrix) { + path_matrix = &identity_mtx; + } + +#if gcFEATURE_VG_GAMMA + set_gamma_dest_only(target, VGL_TRUE); +#endif +#if gcFEATURE_VG_GLOBAL_ALPHA + if(blend >= VG_LITE_BLEND_NORMAL_LVGL && blend <= VG_LITE_BLEND_MULTIPLY_LVGL) { + VG_LITE_RETURN_ERROR(vg_lite_dest_global_alpha(VG_LITE_GLOBAL, 0xff)); + } +#endif + /*blend input into context*/ + s_context.blend_mode = blend; + + src_premultiply_enable = 0x01000100; + if(s_context.color_transform == 0 && s_context.gamma_dst == s_context.gamma_src && s_context.matrix_enable == 0 && + s_context.dst_alpha_mode == 0 && s_context.src_alpha_mode == 0 && + (source->image_mode == VG_LITE_NORMAL_IMAGE_MODE || source->image_mode == 0)) { + prediv_flag = 0; + } + else { + prediv_flag = 1; + } + if((s_context.blend_mode >= OPENVG_BLEND_SRC_OVER && s_context.blend_mode <= OPENVG_BLEND_ADDITIVE) || + source->image_mode == VG_LITE_STENCIL_MODE + || (s_context.blend_mode >= VG_LITE_BLEND_NORMAL_LVGL && s_context.blend_mode <= VG_LITE_BLEND_MULTIPLY_LVGL)) { + premul_flag = 1; + } + else { + premul_flag = 0; + } + + if((source->premultiplied == 0 && target->premultiplied == 0 && premul_flag == 0) || + (source->premultiplied == 1 && target->premultiplied == 0 && prediv_flag == 0)) { + src_premultiply_enable = 0x01000100; + in_premult = 0x10000000; + } + /* when src and dst all pre format, im pre_out set to 0 to perform data truncation to prevent data overflow */ + else if(source->premultiplied == 1 && target->premultiplied == 1 && prediv_flag == 0) { + src_premultiply_enable = 0x00000100; + in_premult = 0x00000000; + } + else if((source->premultiplied == 0 && target->premultiplied == 1) || + (source->premultiplied == 0 && target->premultiplied == 0 && premul_flag == 1)) { + src_premultiply_enable = 0x01000100; + in_premult = 0x00000000; + } + else if((source->premultiplied == 1 && target->premultiplied == 1 && prediv_flag == 1) || + (source->premultiplied == 1 && target->premultiplied == 0 && prediv_flag == 1)) { + src_premultiply_enable = 0x00000100; + in_premult = 0x00000000; + } + if((source->format == VG_LITE_A4 || source->format == VG_LITE_A8) && blend >= VG_LITE_BLEND_SRC_OVER && + blend <= VG_LITE_BLEND_SUBTRACT) { +#if (CHIPID==0x255) + src_premultiply_enable = 0x00000000; +#endif + in_premult = 0x00000000; + } + if(source->premultiplied == target->premultiplied && premul_flag == 0) { + target->apply_premult = 1; + } + else { + target->apply_premult = 0; + } + + error = set_render_target(target); + if(error != VG_LITE_SUCCESS) { + return error; + } + else if(error == VG_LITE_NO_CONTEXT) { + /* If scissoring is enabled and no valid scissoring rectangles + are present, no drawing occurs */ + return VG_LITE_SUCCESS; + } + + if((target->format == VG_LITE_YUYV || target->format == VG_LITE_YUY2 || target->format == VG_LITE_YUY2_TILED + || target->format == VG_LITE_AYUY2 || target->format == VG_LITE_AYUY2_TILED) + && path->quality != VG_LITE_LOW) { + path->quality = VG_LITE_LOW; + printf("If target is YUV group , the path qulity should use VG_LITE_LOW.\n"); + } + + transparency_mode = (source->transparency_mode == VG_LITE_IMAGE_TRANSPARENT ? 0x8000 : 0); + width = s_context.tessbuf.tess_w_h & 0xFFFF; + height = s_context.tessbuf.tess_w_h >> 16; + + if(width == 0 || height == 0) + return VG_LITE_NO_CONTEXT; + if((target->width <= width) && (target->height <= height) && (!s_context.scissor_set)) { + ts_is_fullscreen = 1; + point_min.x = 0; + point_min.y = 0; + point_max.x = target->width; + point_max.y = target->height; + } + + /* If target is L8 and source is in YUV or RGB (not L8 or A8) then we have to convert RGB into L8. */ + if((target->format == VG_LITE_L8) && ((source->format != VG_LITE_L8) && (source->format != VG_LITE_A8))) { + conversion = 0x80000000; + } + + /* Determine image mode (NORMAL, NONE , MULTIPLY or STENCIL) depending on the color. */ + switch(source->image_mode) { + case VG_LITE_NONE_IMAGE_MODE: + imageMode = 0x0; + break; + + case VG_LITE_MULTIPLY_IMAGE_MODE: + return VG_LITE_INVALID_ARGUMENT; + + case VG_LITE_NORMAL_IMAGE_MODE: + case VG_LITE_ZERO: + imageMode = 0x00001000; + break; + + case VG_LITE_STENCIL_MODE: + imageMode = 0x00003000; + break; + + case VG_LITE_RECOLOR_MODE: + imageMode = 0x00006000; + break; + } + + switch(filter) { + case VG_LITE_FILTER_POINT: + filter_mode = 0; + break; + + case VG_LITE_FILTER_LINEAR: + filter_mode = 0x10000; + break; + + case VG_LITE_FILTER_BI_LINEAR: + filter_mode = 0x20000; + break; + + case VG_LITE_FILTER_GAUSSIAN: + filter_mode = 0x30000; + break; + } + + tiled_source = (source->tiled != VG_LITE_LINEAR) ? 0x10000000 : 0 ; + + switch(grad->spread_mode) { + case VG_LITE_GRADIENT_SPREAD_FILL: + rad_tile = 0x0; + break; + + case VG_LITE_GRADIENT_SPREAD_PAD: + rad_tile = 0x1000; + break; + + case VG_LITE_GRADIENT_SPREAD_REPEAT: + rad_tile = 0x2000; + break; + + case VG_LITE_GRADIENT_SPREAD_REFLECT: + rad_tile = 0x3000; + break; + } + + compress_mode = (uint32_t)source->compress_mode << 25; + + if(grad->spread_mode == VG_LITE_GRADIENT_SPREAD_FILL) { + uint8_t a, r, g, b; + a = paint_color >> 24; + r = paint_color >> 16; + g = paint_color >> 8; + b = paint_color; + paint_color = (a << 24) | (b << 16) | (g << 8) | r; + } + + /* compute radial gradient paremeters */ + + /* Compute inverse matrix. */ + if(!inverse(&inverse_matrix, matrix)) + return VG_LITE_INVALID_ARGUMENT; + + /* Make shortcuts to the gradient information. */ + centerX = grad->radial_grad.cx; + centerY = grad->radial_grad.cy; + focalX = grad->radial_grad.fx; + focalY = grad->radial_grad.fy; + + /* Compute constants of the equation. */ + fx = focalX - centerX; + fy = focalY - centerY; + radius2 = radius * radius; + if(fx * fx + fy * fy > radius2) { + /* If the focal point is outside the circle, let's move it + to inside the circle. Per vg11 spec pg125 "If (fx, fy) lies outside ... + For here, we set it at 0.9 ratio to the center. + */ + vg_lite_float_t fr = (vg_lite_float_t)sqrt(fx * fx + fy * fy); + fx = radius * fx / fr * 0.9f; + fy = radius * fy / fr * 0.9f; + focalX = grad->radial_grad.fx + fx; + focalY = grad->radial_grad.fy + fy; + } + + fxfy_2 = 2.0f * fx * fy; + r2_fx2 = radius2 - fx * fx; + r2_fy2 = radius2 - fy * fy; + r2_fx2_2 = 2.0f * r2_fx2; + r2_fy2_2 = 2.0f * r2_fy2; +#if gcFEATURE_VG_MATH_PRECISION_FIX + r2_fx2_fy2 = (r2_fx2 - fy * fy) / source->width; + r2_fx2_fy2sq = (r2_fx2_fy2 * r2_fx2_fy2); +#else + r2_fx2_fy2 = r2_fx2 - fy * fy; + r2_fx2_fy2sq = r2_fx2_fy2 * r2_fx2_fy2; +#endif + + /* _____________________________________ + ** dx fx + dy fy + \/r^2 (dx^2 + dy^2) - (dx fy - dy fx)^2 + ** g = ------------------------------------------------------- + ** r^2 - fx^2 - fy^2 + ** + ** Where + ** + ** dx := F(x) - focalX + ** dy := F(y) - focalY + ** fx := focalX - centerX + ** fy := focalX - centerY + ** + ** and + ** + ** F(x) := (x + 0.5) m00 + (y + 0.5) m01 + m02 + ** F(y) := (x + 0.5) m10 + (y + 0.5) m11 + m12 + ** + ** So, dx can be factored into + ** + ** dx = (x + 0.5) m00 + (y + 0.5) m01 + m02 - focalX + ** = x m00 + y m01 + 0.5 m00 + 0.5 m01 + m02 - focalX + ** + ** = x m00 + y m01 + cx + ** + ** where + ** + ** cx := 0.5 m00 + 0.5 m01 + m02 - focalX + ** + ** The same way we can factor dy into + ** + ** dy = x m10 + y m11 + cy + ** + ** where + ** + ** cy := 0.5 m10 + 0.5 m11 + m12 - focalY. + ** + ** Now we can rewrite g as + ** ______________________________________ + ** dx fx + dy fy / r^2 (dx^2 + dy^2) - (dx fy - dy fx)^2 + ** g = ----------------- + \ / ------------------------------------- + ** r^2 - fx^2 - fy^2 \/ (r^2 - fx^2 - fy^2)^2 + ** ____ + ** = gLin + \/gRad + ** + ** where + ** + ** dx fx + dy fy + ** gLin := ----------------- + ** r^2 - fx^2 - fy^2 + ** + ** r^2 (dx^2 + dy^2) - (dx fy - dy fx)^2 + ** gRad := ------------------------------------- + ** (r^2 - fx^2 - fy^2)^2 + */ + + cx + = 0.5f * (MAT(&inverse_matrix, 0, 0) + MAT(&inverse_matrix, 0, 1)) + + MAT(&inverse_matrix, 0, 2) + - focalX; + + cy + = 0.5f * (MAT(&inverse_matrix, 1, 0) + MAT(&inverse_matrix, 1, 1)) + + MAT(&inverse_matrix, 1, 2) + - focalY; + + /* + ** dx fx + dy fy + ** gLin := ----------------- + ** r^2 - fx^2 - fy^2 + ** + ** We can factor the top half into + ** + ** = (x m00 + y m01 + cx) fx + (x m10 + y m11 + cy) fy + ** + ** = x (m00 fx + m10 fy) + ** + y (m01 fx + m11 fy) + ** + cx fx + cy fy. + */ + + rgStepXLin + = (MAT(&inverse_matrix, 0, 0) * fx + MAT(&inverse_matrix, 1, 0) * fy) + / r2_fx2_fy2; + + rgStepYLin + = (MAT(&inverse_matrix, 0, 1) * fx + MAT(&inverse_matrix, 1, 1) * fy) + / r2_fx2_fy2; + + rgConstantLin = (cx * fx + cy * fy) / r2_fx2_fy2; + + /* + ** r^2 (dx^2 + dy^2) - (dx fy - dy fx)^2 + ** gRad := ------------------------------------- + ** (r^2 - fx^2 - fy^2)^2 + ** + ** r^2 (dx^2 + dy^2) - dx^2 fy^2 - dy^2 fx^2 + 2 dx dy fx fy + ** := --------------------------------------------------------- + ** (r^2 - fx^2 - fy^2)^2 + ** + ** dx^2 (r^2 - fy^2) + dy^2 (r^2 - fx^2) + 2 dx dy fx fy + ** := ----------------------------------------------------- + ** (r^2 - fx^2 - fy^2)^2 + ** + ** First, lets factor dx^2 into + ** + ** dx^2 = (x m00 + y m01 + cx)^2 + ** = x^2 m00^2 + y^2 m01^2 + 2 x y m00 m01 + ** + 2 x m00 cx + 2 y m01 cx + cx^2 + ** + ** = x^2 (m00^2) + ** + y^2 (m01^2) + ** + x y (2 m00 m01) + ** + x (2 m00 cx) + ** + y (2 m01 cx) + ** + cx^2. + ** + ** The same can be done for dy^2: + ** + ** dy^2 = x^2 (m10^2) + ** + y^2 (m11^2) + ** + x y (2 m10 m11) + ** + x (2 m10 cy) + ** + y (2 m11 cy) + ** + cy^2. + ** + ** Let's also factor dx dy into + ** + ** dx dy = (x m00 + y m01 + cx) (x m10 + y m11 + cy) + ** = x^2 m00 m10 + y^2 m01 m11 + x y m00 m11 + x y m01 m10 + ** + x m00 cy + x m10 cx + y m01 cy + y m11 cx + cx cy + ** + ** = x^2 (m00 m10) + ** + y^2 (m01 m11) + ** + x y (m00 m11 + m01 m10) + ** + x (m00 cy + m10 cx) + ** + y (m01 cy + m11 cx) + ** + cx cy. + ** + ** Now that we have all this, lets look at the top of gRad. + ** + ** = dx^2 (r^2 - fy^2) + dy^2 (r^2 - fx^2) + 2 dx dy fx fy + ** = x^2 m00^2 (r^2 - fy^2) + y^2 m01^2 (r^2 - fy^2) + ** + x y 2 m00 m01 (r^2 - fy^2) + x 2 m00 cx (r^2 - fy^2) + ** + y 2 m01 cx (r^2 - fy^2) + cx^2 (r^2 - fy^2) + ** + x^2 m10^2 (r^2 - fx^2) + y^2 m11^2 (r^2 - fx^2) + ** + x y 2 m10 m11 (r^2 - fx^2) + x 2 m10 cy (r^2 - fx^2) + ** + y 2 m11 cy (r^2 - fx^2) + cy^2 (r^2 - fx^2) + ** + x^2 m00 m10 2 fx fy + y^2 m01 m11 2 fx fy + ** + x y (m00 m11 + m01 m10) 2 fx fy + ** + x (m00 cy + m10 cx) 2 fx fy + y (m01 cy + m11 cx) 2 fx fy + ** + cx cy 2 fx fy + ** + ** = x^2 ( m00^2 (r^2 - fy^2) + ** + m10^2 (r^2 - fx^2) + ** + m00 m10 2 fx fy + ** ) + ** + y^2 ( m01^2 (r^2 - fy^2) + ** + m11^2 (r^2 - fx^2) + ** + m01 m11 2 fx fy + ** ) + ** + x y ( 2 m00 m01 (r^2 - fy^2) + ** + 2 m10 m11 (r^2 - fx^2) + ** + (m00 m11 + m01 m10) 2 fx fy + ** ) + ** + x ( 2 m00 cx (r^2 - fy^2) + ** + 2 m10 cy (r^2 - fx^2) + ** + (m00 cy + m10 cx) 2 fx fy + ** ) + ** + y ( 2 m01 cx (r^2 - fy^2) + ** + 2 m11 cy (r^2 - fx^2) + ** + (m01 cy + m11 cx) 2 fx fy + ** ) + ** + cx^2 (r^2 - fy^2) + cy^2 (r^2 - fx^2) + cx cy 2 fx fy. + */ + + rgStepXXRad = + ( + MAT(&inverse_matrix, 0, 0) * MAT(&inverse_matrix, 0, 0) * r2_fy2 + + MAT(&inverse_matrix, 1, 0) * MAT(&inverse_matrix, 1, 0) * r2_fx2 + + MAT(&inverse_matrix, 0, 0) * MAT(&inverse_matrix, 1, 0) * fxfy_2 + ) + / r2_fx2_fy2sq; + + rgStepYYRad = + ( + MAT(&inverse_matrix, 0, 1) * MAT(&inverse_matrix, 0, 1) * r2_fy2 + + MAT(&inverse_matrix, 1, 1) * MAT(&inverse_matrix, 1, 1) * r2_fx2 + + MAT(&inverse_matrix, 0, 1) * MAT(&inverse_matrix, 1, 1) * fxfy_2 + ) + / r2_fx2_fy2sq; + + rgStepXYRad = + ( + MAT(&inverse_matrix, 0, 0) * MAT(&inverse_matrix, 0, 1) * r2_fy2_2 + + MAT(&inverse_matrix, 1, 0) * MAT(&inverse_matrix, 1, 1) * r2_fx2_2 + + ( + MAT(&inverse_matrix, 0, 0) * MAT(&inverse_matrix, 1, 1) + + MAT(&inverse_matrix, 0, 1) * MAT(&inverse_matrix, 1, 0) + ) + * fxfy_2 + ) + / r2_fx2_fy2sq; + + rgStepXRad = + ( + MAT(&inverse_matrix, 0, 0) * cx * r2_fy2_2 + + MAT(&inverse_matrix, 1, 0) * cy * r2_fx2_2 + + ( + MAT(&inverse_matrix, 0, 0) * cy + + MAT(&inverse_matrix, 1, 0) * cx + ) + * fxfy_2 + ) + / r2_fx2_fy2sq; + + rgStepYRad = + ( + MAT(&inverse_matrix, 0, 1) * cx * r2_fy2_2 + + MAT(&inverse_matrix, 1, 1) * cy * r2_fx2_2 + + ( + MAT(&inverse_matrix, 0, 1) * cy + + MAT(&inverse_matrix, 1, 1) * cx + ) + * fxfy_2 + ) + / r2_fx2_fy2sq; + + rgConstantRad = + ( + cx * cx * r2_fy2 + + cy * cy * r2_fx2 + + cx * cy * fxfy_2 + ) + / r2_fx2_fy2sq; + + /* Setup the command buffer. */ + + /* rad gradient parameters*/ + data = &rgConstantLin; + VG_LITE_RETURN_ERROR(push_state(&s_context, 0x0A04, *(uint32_t *) data)); + data = &rgStepXLin; + VG_LITE_RETURN_ERROR(push_state(&s_context, 0x0A06, *(uint32_t *) data)); + data = &rgStepYLin; + VG_LITE_RETURN_ERROR(push_state(&s_context, 0x0A08, *(uint32_t *) data)); + data = &rgConstantRad; + VG_LITE_RETURN_ERROR(push_state(&s_context, 0x0A05, *(uint32_t *) data)); + data = &rgStepXRad; + VG_LITE_RETURN_ERROR(push_state(&s_context, 0x0A07, *(uint32_t *) data)); + data = &rgStepYRad; + VG_LITE_RETURN_ERROR(push_state(&s_context, 0x0A09, *(uint32_t *) data)); + data = &rgStepXXRad; + VG_LITE_RETURN_ERROR(push_state(&s_context, 0x0A03, *(uint32_t *) data)); + data = &rgStepYYRad; + VG_LITE_RETURN_ERROR(push_state(&s_context, 0x0A0A, *(uint32_t *) data)); + data = &rgStepXYRad; + VG_LITE_RETURN_ERROR(push_state(&s_context, 0x0A0B, *(uint32_t *) data)); + + /* Compute inverse matrix. */ + if(!inverse(&inverse_matrix, matrix)) + return VG_LITE_INVALID_ARGUMENT; + +#if gcFEATURE_VG_MATH_PRECISION_FIX + /* Compute interpolation steps. */ + x_step[0] = inverse_matrix.m[0][0]; + x_step[1] = inverse_matrix.m[1][0]; + x_step[2] = inverse_matrix.m[2][0]; + y_step[0] = inverse_matrix.m[0][1]; + y_step[1] = inverse_matrix.m[1][1]; + y_step[2] = inverse_matrix.m[2][1]; + c_step[0] = (0.5f * (inverse_matrix.m[0][0] + inverse_matrix.m[0][1]) + inverse_matrix.m[0][2]); + c_step[1] = (0.5f * (inverse_matrix.m[1][0] + inverse_matrix.m[1][1]) + inverse_matrix.m[1][2]); + c_step[2] = 0.5f * (inverse_matrix.m[2][0] + inverse_matrix.m[2][1]) + inverse_matrix.m[2][2]; +#else + /* Compute interpolation steps. */ + x_step[0] = inverse_matrix.m[0][0] / source->width; + x_step[1] = inverse_matrix.m[1][0] / source->height; + x_step[2] = inverse_matrix.m[2][0]; + y_step[0] = inverse_matrix.m[0][1] / source->width; + y_step[1] = inverse_matrix.m[1][1] / source->height; + y_step[2] = inverse_matrix.m[2][1]; + c_step[0] = (0.5f * (inverse_matrix.m[0][0] + inverse_matrix.m[0][1]) + inverse_matrix.m[0][2]) / source->width; + c_step[1] = (0.5f * (inverse_matrix.m[1][0] + inverse_matrix.m[1][1]) + inverse_matrix.m[1][2]) / source->height; + c_step[2] = 0.5f * (inverse_matrix.m[2][0] + inverse_matrix.m[2][1]) + inverse_matrix.m[2][2]; +#endif + + /* Setup the command buffer. */ + VG_LITE_RETURN_ERROR(push_state_ptr(&s_context, 0x0A18, (void *) &c_step[0])); + VG_LITE_RETURN_ERROR(push_state_ptr(&s_context, 0x0A19, (void *) &c_step[1])); + VG_LITE_RETURN_ERROR(push_state_ptr(&s_context, 0x0A1A, (void *) &c_step[2])); + VG_LITE_RETURN_ERROR(push_state_ptr(&s_context, 0x0A1C, (void *) &x_step[0])); + VG_LITE_RETURN_ERROR(push_state_ptr(&s_context, 0x0A1D, (void *) &x_step[1])); + VG_LITE_RETURN_ERROR(push_state_ptr(&s_context, 0x0A1E, (void *) &x_step[2])); + VG_LITE_RETURN_ERROR(push_state(&s_context, 0x0A1F, 0x00000001)); + VG_LITE_RETURN_ERROR(push_state_ptr(&s_context, 0x0A20, (void *) &y_step[0])); + VG_LITE_RETURN_ERROR(push_state_ptr(&s_context, 0x0A21, (void *) &y_step[1])); + VG_LITE_RETURN_ERROR(push_state_ptr(&s_context, 0x0A22, (void *) &y_step[2])); + + if(((source->format >= VG_LITE_YUY2) && + (source->format <= VG_LITE_AYUY2)) || + ((source->format >= VG_LITE_YUY2_TILED) && + (source->format <= VG_LITE_AYUY2_TILED))) { + yuv2rgb = convert_yuv2rgb(source->yuv.yuv2rgb); + uv_swiz = convert_uv_swizzle(source->yuv.swizzle); + } + + if(source->yuv.uv_planar) { + /* Program u plane address if necessary. */ + VG_LITE_RETURN_ERROR(push_state(&s_context, 0x0A51, source->yuv.uv_planar)); + } + if(source->yuv.v_planar) { + /* Program v plane address if necessary. */ + VG_LITE_RETURN_ERROR(push_state(&s_context, 0x0A53, source->yuv.v_planar)); + } + + VG_LITE_RETURN_ERROR(push_state(&s_context, 0x0A24, convert_source_format(source->format) | + filter_mode | uv_swiz | yuv2rgb | rad_tile | conversion | src_premultiply_enable | compress_mode)); + VG_LITE_RETURN_ERROR(push_state(&s_context, 0x0A26, paint_color)); + VG_LITE_RETURN_ERROR(push_state(&s_context, 0x0A28, source->address)); + + VG_LITE_RETURN_ERROR(push_state(&s_context, 0x0A2A, tiled_source)); + VG_LITE_RETURN_ERROR(push_state(&s_context, 0x0A2C, 0)); + VG_LITE_RETURN_ERROR(push_state(&s_context, 0x0A2E, source->width | (source->height << 16))); + + /* Work on path states. */ + matrix = path_matrix; + + if(ts_is_fullscreen == 0) { + transform(&temp, (vg_lite_float_t)path->bounding_box[0], (vg_lite_float_t)path->bounding_box[1], matrix); + point_min = point_max = temp; + + transform(&temp, (vg_lite_float_t)path->bounding_box[2], (vg_lite_float_t)path->bounding_box[1], matrix); + if(temp.x < point_min.x) point_min.x = temp.x; + if(temp.y < point_min.y) point_min.y = temp.y; + if(temp.x > point_max.x) point_max.x = temp.x; + if(temp.y > point_max.y) point_max.y = temp.y; + + transform(&temp, (vg_lite_float_t)path->bounding_box[2], (vg_lite_float_t)path->bounding_box[3], matrix); + if(temp.x < point_min.x) point_min.x = temp.x; + if(temp.y < point_min.y) point_min.y = temp.y; + if(temp.x > point_max.x) point_max.x = temp.x; + if(temp.y > point_max.y) point_max.y = temp.y; + + transform(&temp, (vg_lite_float_t)path->bounding_box[0], (vg_lite_float_t)path->bounding_box[3], matrix); + if(temp.x < point_min.x) point_min.x = temp.x; + if(temp.y < point_min.y) point_min.y = temp.y; + if(temp.x > point_max.x) point_max.x = temp.x; + if(temp.y > point_max.y) point_max.y = temp.y; + + point_min.x = MAX(point_min.x, 0); + point_min.y = MAX(point_min.y, 0); + point_max.x = MIN(point_max.x, target->width); + point_max.y = MIN(point_max.y, target->height); + + if(s_context.scissor_set) { + point_min.x = MAX(point_min.x, s_context.scissor[0]); + point_min.y = MAX(point_min.y, s_context.scissor[1]); + point_max.x = MIN(point_max.x, s_context.scissor[2]); + point_max.y = MIN(point_max.y, s_context.scissor[3]); + } + } + + Scale = 1.0f; + Bias = 0.0f; + new_matrix[0] = matrix->m[0][0] * Scale; + new_matrix[1] = matrix->m[0][1] * Scale; + new_matrix[2] = (matrix->m[0][0] + matrix->m[0][1]) * Bias + matrix->m[0][2]; + new_matrix[3] = matrix->m[1][0] * Scale; + new_matrix[4] = matrix->m[1][1] * Scale; + new_matrix[5] = (matrix->m[1][0] + matrix->m[1][1]) * Bias + matrix->m[1][2]; + + /* Convert states into hardware values. */ + blend_mode = convert_blend(blend); + format = convert_path_format(path->format); + quality = convert_path_quality(path->quality); + tiling = (s_context.capabilities.cap.tiled == 2) ? 0x2000000 : 0; + fill = (fill_rule == VG_LITE_FILL_EVEN_ODD) ? 0x10 : 0; + tessellation_size = s_context.tessbuf.tessbuf_size; + + /* Setup the command buffer. */ + /* Program color register. */ + VG_LITE_RETURN_ERROR(push_state(&s_context, 0x0A00, + 0x02000002 | s_context.capabilities.cap.tiled | in_premult | imageMode | blend_mode | transparency_mode | + s_context.enable_mask | s_context.color_transform | s_context.matrix_enable | s_context.scissor_enable)); + VG_LITE_RETURN_ERROR(push_state(&s_context, 0x0A34, 0x01000000 | format | quality | tiling | fill)); + VG_LITE_RETURN_ERROR(push_state(&s_context, 0x0A3B, 0x3F800000)); /* Path tessellation SCALE. */ + VG_LITE_RETURN_ERROR(push_state(&s_context, 0x0A3C, 0x00000000)); /* Path tessellation BIAS. */ + /* Program matrix. */ + VG_LITE_RETURN_ERROR(push_state_ptr(&s_context, 0x0A40, (void *) &new_matrix[0])); + VG_LITE_RETURN_ERROR(push_state_ptr(&s_context, 0x0A41, (void *) &new_matrix[1])); + VG_LITE_RETURN_ERROR(push_state_ptr(&s_context, 0x0A42, (void *) &new_matrix[2])); + VG_LITE_RETURN_ERROR(push_state_ptr(&s_context, 0x0A43, (void *) &new_matrix[3])); + VG_LITE_RETURN_ERROR(push_state_ptr(&s_context, 0x0A44, (void *) &new_matrix[4])); + VG_LITE_RETURN_ERROR(push_state_ptr(&s_context, 0x0A45, (void *) &new_matrix[5])); + VG_LITE_RETURN_ERROR(push_state_ptr(&s_context, 0x0ACD, (void *) &matrix->m[0][2])); + VG_LITE_RETURN_ERROR(push_state_ptr(&s_context, 0x0ACE, (void *) &matrix->m[1][2])); + + if(VLM_PATH_GET_UPLOAD_BIT(*path) == 1) { + if(path->path_changed != 0) { + if(path->uploaded.handle != NULL) { + free_memory.memory_handle = path->uploaded.handle; + vg_lite_kernel(VG_LITE_FREE, &free_memory); + path->uploaded.address = 0; + path->uploaded.memory = NULL; + path->uploaded.handle = NULL; + } + /* Allocate memory for the path data. */ + memory.bytes = 16 + VG_LITE_ALIGN(path->path_length, 8); + return_offset = (8 + VG_LITE_ALIGN(path->path_length, 8)) / 4; + memory.contiguous = 1; + VG_LITE_RETURN_ERROR(vg_lite_kernel(VG_LITE_ALLOCATE, &memory)); + ((uint64_t *) memory.memory)[(path->path_length + 7) / 8] = 0; + ((uint32_t *) memory.memory)[0] = VG_LITE_DATA((path->path_length + 7) / 8); + ((uint32_t *) memory.memory)[1] = 0; + memcpy((uint8_t *) memory.memory + 8, path->path, path->path_length); + ((uint32_t *) memory.memory)[return_offset] = VG_LITE_RETURN(); + ((uint32_t *) memory.memory)[return_offset + 1] = 0; + + path->uploaded.handle = memory.memory_handle; + path->uploaded.memory = memory.memory; + path->uploaded.address = memory.memory_gpu; + path->uploaded.bytes = memory.bytes; + path->path_changed = 0; + } + } + + if(VLM_PATH_GET_UPLOAD_BIT(*path) == 1) { + vglitemDUMP_BUFFER("path", (size_t)path->uploaded.address, (uint8_t *)(path->uploaded.memory), 0, path->uploaded.bytes); + } + +#if !DUMP_COMMAND_CAPTURE + vglitemDUMP("@[memory 0x%08X 0x%08X]", s_context.tessbuf.physical_addr, s_context.tessbuf.tessbuf_size); +#endif + + if(width + point_min.x > target->width) { + width = target->width - point_min.x; + } + +#if (gcFEATURE_VG_PARALLEL_PATHS && gcFEATURE_VG_512_PARALLEL_PATHS) + { + /* Tessellate path. */ + s_context.tessbuf.tess_w_h = width | (height << 16); + VG_LITE_RETURN_ERROR(push_state(&s_context, 0x0A1B, 0x00011000)); + VG_LITE_RETURN_ERROR(push_state(&s_context, 0x0A3D, tessellation_size / 64)); + VG_LITE_RETURN_ERROR(push_state(&s_context, 0x0A39, point_min.x | (point_min.y << 16))); + VG_LITE_RETURN_ERROR(push_state(&s_context, 0x0A3A, s_context.tessbuf.tess_w_h)); + + if(VLM_PATH_GET_UPLOAD_BIT(*path) == 1) { + VG_LITE_RETURN_ERROR(push_call(&s_context, path->uploaded.address, path->uploaded.bytes)); + } + else { + if(path->path_type == VG_LITE_DRAW_FILL_PATH || path->path_type == VG_LITE_DRAW_ZERO) + VG_LITE_RETURN_ERROR(push_data(&s_context, path->path_length, path->path)); + if(path->path_type == VG_LITE_DRAW_STROKE_PATH || path->path_type == VG_LITE_DRAW_FILL_STROKE_PATH) { + format = convert_path_format(VG_LITE_FP32); + VG_LITE_RETURN_ERROR(push_state(&s_context, 0x0A34, 0x01000200 | format | quality | tiling | 0x0)); + VG_LITE_RETURN_ERROR(push_state(&s_context, 0x0A02, path->stroke_color)); + VG_LITE_RETURN_ERROR(push_data(&s_context, path->stroke_size, path->stroke_path)); + } + } + } +#else + { + height = s_context.tessbuf.tess_w_h >> 16; + if(path->path_type == VG_LITE_DRAW_FILL_PATH || path->path_type == VG_LITE_DRAW_ZERO) { +#if gcFEATURE_VG_512_PARALLEL_PATHS + if(height <= 128) + parallel_workpaths1 = 4; + else + parallel_workpaths1 = height * 128 / 4096 - 1; + + if(parallel_workpaths1 > parallel_workpaths2) + parallel_workpaths1 = parallel_workpaths2; +#endif + + for(y = point_min.y; y < point_max.y; y += height) { + VG_LITE_RETURN_ERROR(push_state(&s_context, 0x0A1B, 0x00011000)); + VG_LITE_RETURN_ERROR(push_state(&s_context, 0x0A3D, tessellation_size / 64)); + VG_LITE_RETURN_ERROR(push_state(&s_context, 0x0A39, point_min.x | (y << 16))); + if(y + height > target->height) { + temp_height = target->height - y; + VG_LITE_RETURN_ERROR(push_state(&s_context, 0x0A3A, width | (temp_height << 16))); + } + else { + VG_LITE_RETURN_ERROR(push_state(&s_context, 0x0A3A, width | (height << 16))); + } + + if(VLM_PATH_GET_UPLOAD_BIT(*path) == 1) { + VG_LITE_RETURN_ERROR(push_call(&s_context, path->uploaded.address, path->uploaded.bytes)); + } + else { + VG_LITE_RETURN_ERROR(push_data(&s_context, path->path_length, path->path)); +#if gcFEATURE_VG_512_PARALLEL_PATHS + s_context.path_counter ++; + if(parallel_workpaths1 == s_context.path_counter) { + VG_LITE_RETURN_ERROR(push_state(&s_context, 0x0E02, 0x10 | (0x7 << 8))); + VG_LITE_RETURN_ERROR(push_state(&s_context, 0x0F00, 0x10 | (0x7 << 8))); + s_context.path_counter = 0; + } +#endif + } + } + } + if(path->path_type == VG_LITE_DRAW_STROKE_PATH || path->path_type == VG_LITE_DRAW_FILL_STROKE_PATH) { + for(y = point_min.y; y < point_max.y; y += height) { + VG_LITE_RETURN_ERROR(push_state(&s_context, 0x0A1B, 0x00011000)); + VG_LITE_RETURN_ERROR(push_state(&s_context, 0x0A3D, tessellation_size / 64)); + VG_LITE_RETURN_ERROR(push_state(&s_context, 0x0A39, point_min.x | (y << 16))); + if(y + height > target->height) { + temp_height = target->height - y; + VG_LITE_RETURN_ERROR(push_state(&s_context, 0x0A3A, width | (temp_height << 16))); + } + else { + VG_LITE_RETURN_ERROR(push_state(&s_context, 0x0A3A, width | (height << 16))); + } + + if(VLM_PATH_GET_UPLOAD_BIT(*path) == 1) { + VG_LITE_RETURN_ERROR(push_call(&s_context, path->uploaded.address, path->uploaded.bytes)); + } + else { + format = convert_path_format(VG_LITE_FP32); + VG_LITE_RETURN_ERROR(push_state(&s_context, 0x0A34, 0x01000200 | format | quality | tiling | 0x0)); + VG_LITE_RETURN_ERROR(push_state(&s_context, 0x0A02, path->stroke_color)); + VG_LITE_RETURN_ERROR(push_data(&s_context, path->stroke_size, path->stroke_path)); +#if gcFEATURE_VG_512_PARALLEL_PATHS + s_context.path_counter ++; + if(parallel_workpaths1 == s_context.path_counter) { + VG_LITE_RETURN_ERROR(push_state(&s_context, 0x0E02, 0x10 | (0x7 << 8))); + VG_LITE_RETURN_ERROR(push_state(&s_context, 0x0F00, 0x10 | (0x7 << 8))); + s_context.path_counter = 0; + } +#endif + } + } + } + } +#endif + + /* Finialize command buffer. */ + VG_LITE_RETURN_ERROR(push_state(&s_context, 0x0A34, 0)); +#if gcFEATURE_VG_GLOBAL_ALPHA + if(blend >= VG_LITE_BLEND_NORMAL_LVGL && blend <= VG_LITE_BLEND_MULTIPLY_LVGL) { + VG_LITE_RETURN_ERROR(vg_lite_dest_global_alpha(VG_LITE_NORMAL, 0xFF)); + } +#endif + vglitemDUMP_BUFFER("image", (size_t)source->address, source->memory, 0, (source->stride) * (source->height)); +#if DUMP_IMAGE + dump_img(source->memory, source->width, source->height, source->format); +#endif + + return error; +#else + return VG_LITE_NOT_SUPPORT; +#endif +} + +#endif /* (CHIPID==0x355 || CHIPID==0x255) */ + +/* GC555/GC355/GC255 vg_lite_draw_grad API implementation + */ +vg_lite_error_t vg_lite_draw_grad(vg_lite_buffer_t * target, + vg_lite_path_t * path, + vg_lite_fill_t fill_rule, + vg_lite_matrix_t * matrix, + vg_lite_linear_gradient_t * grad, + vg_lite_blend_t blend) +{ +#if DUMP_API + FUNC_DUMP(vg_lite_draw_grad)(target, path, fill_rule, matrix, grad, blend); +#endif + + return vg_lite_draw_pattern(target, path, fill_rule, matrix, + &grad->image, &grad->matrix, blend, VG_LITE_PATTERN_PAD, 0, 0, VG_LITE_FILTER_LINEAR); +} + +#endif /* LV_USE_VG_LITE_DRIVER */ + diff --git a/src/libs/vg_lite_driver/VGLite/vg_lite_stroke.c b/src/libs/vg_lite_driver/VGLite/vg_lite_stroke.c new file mode 100755 index 0000000000..16c7c09d75 --- /dev/null +++ b/src/libs/vg_lite_driver/VGLite/vg_lite_stroke.c @@ -0,0 +1,5421 @@ +/**************************************************************************** +* +* Copyright 2012 - 2023 Vivante Corporation, Santa Clara, California. +* All Rights Reserved. +* +* Permission is hereby granted, free of charge, to any person obtaining +* a copy of this software and associated documentation files (the +* 'Software'), to deal in the Software without restriction, including +* without limitation the rights to use, copy, modify, merge, publish, +* distribute, sub license, and/or sell copies of the Software, and to +* permit persons to whom the Software is furnished to do so, subject +* to the following conditions: +* +* The above copyright notice and this permission notice (including the +* next paragraph) shall be included in all copies or substantial +* portions of the Software. +* +* THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND, +* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. +* IN NO EVENT SHALL VIVANTE AND/OR ITS SUPPLIERS BE LIABLE FOR ANY +* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, +* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE +* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +* +*****************************************************************************/ + +#include "../../../lv_conf_internal.h" +#if LV_USE_VG_LITE_DRIVER + +#include "vg_lite_context.h" + + +#define PI 3.141592653589793238462643383279502f +#define SINF(x) ((vg_lite_float_t) sin(x)) +#define COSF(x) ((vg_lite_float_t) cos(x)) +#define FABSF(x) ((vg_lite_float_t) fabs(x)) +#define SQRTF(x) ((vg_lite_float_t) sqrt(x)) +#define CLAMP(x, min, max) (((x) < (min)) ? (min) : \ + ((x) > (max)) ? (max) : (x)) +#define ACOSF(x) ((vg_lite_float_t) acos(x)) +#define FMODF(x, y) ((vg_lite_float_t) fmod((x), (y))) +#define CEILF(x) ((vg_lite_float_t) ceil(x)) + +#define SIZEOF(a) ((size_t)(sizeof(a))) +#define PTR2SIZE(p) ((uintptr_t)(p)) + +#define FLOAT_EPSILON 0.001f + +#define SWING_NO 0 +#define SWING_OUT 1 +#define SWING_IN 2 + +/* Point curve type for generated stroke path. */ +#define CURVE_LINE 0 +#define CURVE_QUAD_CONTROL 1 +#define CURVE_QUAD_ANCHOR 2 +#define CURVE_ARC_SCCW 3 +#define CURVE_ARC_SCCW_HALF 4 + +#define FLOAT_PI 3.141592654f +#define FLOAT_PI_TWO 6.283185307f +#define FLOAT_PI_THREE_QUARTER 2.356194490f +#define FLOAT_PI_HALF 1.570796327f +#define FLOAT_PI_QUARTER 0.7853981634f +#define FLOAT_PI_EIGHTH 0.3926990817f +/* cos(PI/8) */ +#define FLOAT_COS_PI_EIGHTH 0.9238795325f + +#define FLOAT_DIFF_EPSILON 0.125f +#define FLOAT_SWING_CENTER_RANGE 0.125f +#define FLOAT_ANGLE_EPSILON 0.0045f +#define FLOAT_ANGLE_EPSILON_COS 0.99999f +#define FLOAT_MIN_ARC_ANGLE 0.044f +#define FLOAT_MIN_ARC_ANGLE_COS 0.999f + +/* Float constants. */ +#define gcvMAX_POS_FLOAT ((vg_lite_float_t) 3.4028235e+038) +#define gcvMAX_NEG_FLOAT ((vg_lite_float_t) -3.4028235e+038) + +#define FLOAT_MIN gcvMAX_NEG_FLOAT +#define FLOAT_MAX gcvMAX_POS_FLOAT + +#define FLOAT_FAT_LINE_WIDTH 2.5f + +/* Point flatten type for flattened line segments. */ +#define vgcFLATTEN_NO 0 +#define vgcFLATTEN_START 1 +#define vgcFLATTEN_MIDDLE 2 +#define vgcFLATTEN_END 3 + +typedef struct vg_lite_control_coord { + vg_lite_float_t startX; + vg_lite_float_t startY; + vg_lite_float_t lastX; + vg_lite_float_t lastY; + vg_lite_float_t controlX; + vg_lite_float_t controlY; +} vg_lite_control_coord_t; + +/* Command size calculation shortcuts. */ +#define COMMANDSIZE(CoordinateCount, CoordinateType) \ + ((1+CoordinateCount) * SIZEOF(CoordinateType)) + +extern int32_t get_data_size(vg_lite_format_t format); + +static uint32_t _commandSize_float[] = { + COMMANDSIZE(0, vg_lite_float_t), /* 0: END */ + COMMANDSIZE(0, vg_lite_float_t), /* 1: CLOSE */ + COMMANDSIZE(2, vg_lite_float_t), /* 2: MOVE */ + COMMANDSIZE(2, vg_lite_float_t), /* 3: MOVE_REL */ + COMMANDSIZE(2, vg_lite_float_t), /* 4: LINE */ + COMMANDSIZE(2, vg_lite_float_t), /* 5: LINE_REL */ + COMMANDSIZE(4, vg_lite_float_t), /* 6: QUAD */ + COMMANDSIZE(4, vg_lite_float_t), /* 7: QUAD_REL */ + COMMANDSIZE(6, vg_lite_float_t), /* 8: CUBIC */ + COMMANDSIZE(6, vg_lite_float_t), /* 9: CUBIC_REL */ + COMMANDSIZE(0, vg_lite_float_t), /* 10: BREAK */ + COMMANDSIZE(1, vg_lite_float_t), /* 11: HLINE */ + COMMANDSIZE(1, vg_lite_float_t), /* 12: HLINE_REL */ + COMMANDSIZE(1, vg_lite_float_t), /* 13: VLINE */ + COMMANDSIZE(1, vg_lite_float_t), /* 14: VLINE_REL */ + COMMANDSIZE(2, vg_lite_float_t), /* 15: SQUAD */ + COMMANDSIZE(2, vg_lite_float_t), /* 16: SQUAD_REL */ + COMMANDSIZE(4, vg_lite_float_t), /* 17: SCUBIC */ + COMMANDSIZE(4, vg_lite_float_t), /* 18: SCUBIC_REL */ + COMMANDSIZE(5, vg_lite_float_t), /* 19: SCCWARC */ + COMMANDSIZE(5, vg_lite_float_t), /* 20: SCCWARC_REL */ + COMMANDSIZE(5, vg_lite_float_t), /* 21: SCWARC */ + COMMANDSIZE(5, vg_lite_float_t), /* 22: SCWARC_REL */ + COMMANDSIZE(5, vg_lite_float_t), /* 23: LCCWARC */ + COMMANDSIZE(5, vg_lite_float_t), /* 24: LCCWARC_REL */ + COMMANDSIZE(5, vg_lite_float_t), /* 25: LCWARC */ + COMMANDSIZE(5, vg_lite_float_t), /* 26: LCWARC_REL */ +}; + +#if gcFEATURE_VG_STROKE_PATH + +static vg_lite_float_t _GetS8_NS_NB(int8_t * Data) +{ + int8_t x0 = *((int8_t *) Data); + vg_lite_float_t x = (vg_lite_float_t) x0; + + return x; +} + +static vg_lite_float_t _GetS16_NS_NB(int8_t * Data) +{ + int16_t x0 = *((int16_t *) Data); + vg_lite_float_t x = (vg_lite_float_t) x0; + + return x; +} + +static vg_lite_float_t _GetS32_NS_NB(int8_t * Data) +{ + int32_t x0 = *((int32_t *) Data); + vg_lite_float_t x = (vg_lite_float_t) x0; + + return x; +} + +static vg_lite_float_t _GetF_NS_NB(int8_t * Data) +{ + vg_lite_float_t x = *((vg_lite_float_t *) Data); + + return x; +} + +/* Special sqrt(1.0f + x) for quick calculation when 0 <= x <= 1. */ +static vg_lite_float_t _Sqrt( + vg_lite_float_t X +) +{ + vg_lite_float_t x = X; + vg_lite_float_t s = 1.0f; + + s += x * 0.5f; + x *= X; + s -= x * 0.12445995211601257f; + x *= X; + s += x * 0.058032196015119553f; + x *= X; + s -= x * 0.025314478203654289f; + x *= X; + s += x * 0.0059584137052297592f; + + return s; +} + +static vg_lite_error_t _set_point_tangent( + vg_lite_path_point_ptr Point, + vg_lite_float_t Dx, + vg_lite_float_t Dy +) +{ + if(!Point) + return VG_LITE_INVALID_ARGUMENT; + + if(Dx == 0.0f) { + if(Dy == 0.0f) { + if(Point->prev) { + Point->length = 0.0f; + Point->tangentX = Point->prev->tangentX; + Point->tangentY = Point->prev->tangentY; + } + else { + Point->length = 0.0f; + Point->tangentX = 0.0f; + Point->tangentY = 0.0f; + } + } + else { + Point->tangentX = 0.0f; + if(Dy > 0.0f) { + Point->length = Dy; + Point->tangentY = 1.0f; + } + else { + Point->length = -Dy; + Point->tangentY = -1.0f; + } + } + } + else if(Dy == 0.0f) { + Point->tangentY = 0.0f; + if(Dx > 0.0f) { + Point->length = Dx; + Point->tangentX = 1.0f; + } + else { + Point->length = -Dx; + Point->tangentX = -1.0f; + } + } + else { + vg_lite_float_t l, tx, ty; + + vg_lite_float_t dx, dy; + vg_lite_float_t t, t2; + + dx = (Dx >= 0.0f ? Dx : -Dx); + dy = (Dy >= 0.0f ? Dy : -Dy); + if(dx >= dy) { + t = dy / dx; + t2 = t * t; + l = _Sqrt(t2); + Point->length = l * dx; + + tx = 1.0f / l; + ty = tx * t; + } + else { + t = dx / dy; + t2 = t * t; + l = _Sqrt(t2); + Point->length = l * dy; + + ty = 1.0f / l; + tx = ty * t; + } + if(Dx < 0.0f) tx = -tx; + if(Dy < 0.0f) ty = -ty; + + tx = CLAMP(tx, -1.0f, 1.0f); + ty = CLAMP(ty, -1.0f, 1.0f); + Point->tangentX = tx; + Point->tangentY = ty; + } + + return VG_LITE_SUCCESS; +} + +static vg_lite_error_t _add_point_to_point_list_wdelta( + vg_lite_stroke_t * stroke_conversion, + vg_lite_float_t X, + vg_lite_float_t Y, + vg_lite_float_t DX, + vg_lite_float_t DY, + uint8_t flatten_flag +) +{ + vg_lite_error_t error = VG_LITE_SUCCESS; + vg_lite_path_point_ptr last_point; + vg_lite_path_point_ptr point; + + if(!stroke_conversion) + return VG_LITE_INVALID_ARGUMENT; + + last_point = stroke_conversion->path_end; + point = (vg_lite_path_point_ptr)vg_lite_os_malloc(sizeof(*point)); + if(!point) + return VG_LITE_OUT_OF_RESOURCES; + + memset(point, 0, sizeof(*point)); + + point->x = X; + point->y = Y; + point->flatten_flag = flatten_flag; + + /* Calculate tangent for last_point. */ + VG_LITE_ERROR_HANDLER(_set_point_tangent(last_point, DX, DY)); + + last_point->next = point; + stroke_conversion->path_end = point; + point->prev = last_point; + stroke_conversion->point_count++; + + stroke_conversion->cur_list->path_end = point; + stroke_conversion->cur_list->point_count++; + + return error; + +ErrorHandler: + vg_lite_os_free(point); + point = NULL; + return error; +} + +static vg_lite_error_t _create_new_point_list( + vg_lite_stroke_t * stroke_conversion, + vg_lite_float_t X, + vg_lite_float_t Y, + uint8_t flatten_flag +) +{ + vg_lite_error_t status = VG_LITE_SUCCESS; + vg_lite_path_point_ptr point; + vg_lite_path_list_ptr path_list_divide; + + if(!stroke_conversion) + return VG_LITE_INVALID_ARGUMENT; + + point = (vg_lite_path_point_ptr)vg_lite_os_malloc(sizeof(*point)); + if(!point) + return VG_LITE_OUT_OF_RESOURCES; + memset(point, 0, sizeof(*point)); + + point->x = X; + point->y = Y; + point->flatten_flag = flatten_flag; + point->prev = NULL; + stroke_conversion->point_count = 0; + + stroke_conversion->path_end = stroke_conversion->path_points = point; + stroke_conversion->point_count++; + + path_list_divide = (vg_lite_path_list_ptr)vg_lite_os_malloc(sizeof(*path_list_divide)); + if(!path_list_divide) + return VG_LITE_OUT_OF_RESOURCES; + memset(path_list_divide, 0, sizeof(*path_list_divide)); + + path_list_divide->path_end = path_list_divide->path_points = point; + path_list_divide->point_count++; + + if(stroke_conversion->cur_list == NULL) { + stroke_conversion->cur_list = path_list_divide; + stroke_conversion->path_list_divide = path_list_divide; + } + else { + stroke_conversion->cur_list->next = path_list_divide; + stroke_conversion->cur_list = stroke_conversion->cur_list->next; + } + + return status; +} + +static vg_lite_error_t _add_point_to_point_list( + vg_lite_stroke_t * stroke_conversion, + vg_lite_float_t X, + vg_lite_float_t Y, + uint8_t flatten_flag +) +{ + vg_lite_error_t status = VG_LITE_SUCCESS; + vg_lite_path_point_ptr last_point; + vg_lite_path_point_ptr point; + + if(!stroke_conversion) + return VG_LITE_INVALID_ARGUMENT; + + last_point = stroke_conversion->path_end; + if(last_point == NULL) { + point = (vg_lite_path_point_ptr)vg_lite_os_malloc(sizeof(*point)); + if(!point) + return VG_LITE_OUT_OF_RESOURCES; + memset(point, 0, sizeof(*point)); + + point->x = X; + point->y = Y; + point->flatten_flag = flatten_flag; + point->prev = NULL; + stroke_conversion->path_end = stroke_conversion->path_points = point; + stroke_conversion->point_count++; + status = VG_LITE_SUCCESS; + } + else { + vg_lite_float_t dX = X - last_point->x; + vg_lite_float_t dY = Y - last_point->y; + vg_lite_float_t deltaX = (dX >= 0.0f ? dX : -dX); + vg_lite_float_t deltaY = (dY >= 0.0f ? dY : -dY); + + /* Check for degenerated line. */ + if(deltaX == 0.0f && deltaY == 0.0f) { + /* Skip degenerated line. */ + status = VG_LITE_SUCCESS; + goto ErrorHandler; + } + if(deltaX < FLOAT_EPSILON && deltaY < FLOAT_EPSILON) { + vg_lite_float_t ratioX, ratioY; + + if(deltaX == 0.0f) { + ratioX = 0.0f; + } + else if(X == 0.0f) { + ratioX = deltaX; + } + else { + ratioX = deltaX / X; + if(ratioX < 0.0f) ratioX = -ratioX; + } + if(deltaY == 0.0f) { + ratioY = 0.0f; + } + else if(Y == 0.0f) { + ratioY = deltaY; + } + else { + ratioY = deltaY / Y; + if(ratioY < 0.0f) ratioY = -ratioY; + } + if(ratioX < 1.0e-6f && ratioY < 1.0e-6f) { + /* Skip degenerated line. */ + status = VG_LITE_SUCCESS; + goto ErrorHandler; + } + } + + status = _add_point_to_point_list_wdelta(stroke_conversion, X, Y, dX, dY, flatten_flag); + } + +ErrorHandler: + return status; +} + +#define gcFEATURE_VG_SIMPLYFIED_BEZIER 1 + +#if gcFEATURE_VG_SIMPLYFIED_BEZIER +void quad_bezier(float * x, float * y, const float curve[6], float t) +{ + const float * v0, * v1, * v2; + float mt, t2, mt2, res[2]; + + v0 = &curve[0]; + v1 = &curve[2]; + v2 = &curve[4]; + + mt = 1 - t; + t2 = t * t; + mt2 = mt * mt; + + for(uint8_t i = 0; i < 2; ++i) { + res[i] = v0[i] * mt2 + 2 * v1[i] * mt * t + v2[i] * t2; + } + + *x = res[0]; + *y = res[1]; +} + +void cubic_bezier(float * x, float * y, const float curve[8], float t) +{ + const float * v0, * v1, * v2, * v3; + float mt, t2, mt2, t3, mt3, res[2]; + + v0 = &curve[0]; + v1 = &curve[2]; + v2 = &curve[4]; + v3 = &curve[6]; + + mt = 1 - t; + t2 = t * t; + t3 = t2 * t; + mt2 = mt * mt; + mt3 = mt2 * mt; + + for(uint8_t i = 0; i < 2; ++i) { + res[i] = v0[i] * mt3 + 3 * v1[i] * mt2 * t + 3 * v2[i] * mt * t2 + v3[i] * t3; + } + + *x = res[0]; + *y = res[1]; +} + +void pointer_warp_affine(float out[2], float pt[2], vg_lite_matrix_t * matrix) +{ + float x, y; + + x = pt[0]; + y = pt[1]; + + out[0] = matrix->m[0][0] * x + matrix->m[1][0] * y + matrix->m[2][0]; + out[1] = matrix->m[0][1] * x + matrix->m[1][1] * y + matrix->m[2][1]; +} + +void get_aligned_quad(float out[6], float curve[6]) +{ + float * v0, * v1, * v2; + float angle, dx, dy; + vg_lite_matrix_t matrix; + + v0 = &curve[0]; + v1 = &curve[2]; + v2 = &curve[4]; + + dx = v2[0] - v0[0]; + dy = v2[1] - v0[1]; + angle = (dy >= 0) ? acosf(dx / sqrtf(dx * dx + dy * dy)) : (2 * 3.1415926535f - acosf(dx / sqrtf(dx * dx + dy * dy))); + + vg_lite_identity(&matrix); + vg_lite_translate(-v0[0], -v0[1], &matrix); + vg_lite_rotate(-angle, &matrix); + + pointer_warp_affine(&out[0], v0, &matrix); + pointer_warp_affine(&out[2], v1, &matrix); + pointer_warp_affine(&out[4], v2, &matrix); +} + +void get_aligned_cubic(float out[8], float curve[8]) +{ + float * v0, * v1, * v2, * v3; + float angle, dx, dy; + vg_lite_matrix_t matrix; + + v0 = &curve[0]; + v1 = &curve[2]; + v2 = &curve[4]; + v3 = &curve[6]; + + dx = v3[0] - v0[0]; + dy = v3[1] - v0[1]; + angle = (dy >= 0) ? acosf(dx / sqrtf(dx * dx + dy * dy)) : (2 * 3.1415926535f - acosf(dx / sqrtf(dx * dx + dy * dy))); + + vg_lite_identity(&matrix); + vg_lite_translate(-v0[0], -v0[1], &matrix); + vg_lite_rotate(-angle, &matrix); + + pointer_warp_affine(&out[0], v0, &matrix); + pointer_warp_affine(&out[2], v1, &matrix); + pointer_warp_affine(&out[4], v2, &matrix); + pointer_warp_affine(&out[6], v3, &matrix); +} + +void split_quad(float out1[6], float out2[6], float curve[6], float split) +{ + float * v0, * v1, * v2; + float s, s2, ms, ms2; + + v0 = &curve[0]; + v1 = &curve[2]; + v2 = &curve[4]; + + s = split; + ms = 1 - split; + s2 = s * s; + ms2 = ms * ms; + + float B[2][3] = { + {v0[0], v1[0], v2[0]}, + {v0[1], v1[1], v2[1]} + }; + + /* First curve */ + { + float C[2][3] = { {0} }; + float A[9] = { + 1, 0, 0, + ms, s, 0, + ms2, 2 * ms * s, s2 + }; + /* C = A �� B */ + for(uint8_t i = 0; i < 2; ++i) { + for(size_t y = 0; y < 3; ++y) + for(size_t x = 0; x < 1; ++x) + for(size_t z = 0; z < 3; ++z) { + C[i][x + y * 1] += A[z + y * 3] * B[i][x + z * 1]; + } + } + + out1[0] = C[0][0]; + out1[1] = C[1][0]; + out1[2] = C[0][1]; + out1[3] = C[1][1]; + out1[4] = C[0][2]; + out1[5] = C[1][2]; + } + + /* Second curve */ + { + float C[2][3] = { {0} }; + float A[9] = { + ms2, 2 * s * ms, s2, + 0, ms, s, + 0, 0, 1 + }; + /* C = A �� B */ + for(uint8_t i = 0; i < 2; ++i) { + for(size_t y = 0; y < 3; ++y) + for(size_t x = 0; x < 1; ++x) + for(size_t z = 0; z < 3; ++z) { + C[i][x + y * 1] += A[z + y * 3] * B[i][x + z * 1]; + } + } + + out2[0] = C[0][0]; + out2[1] = C[1][0]; + out2[2] = C[0][1]; + out2[3] = C[1][1]; + out2[4] = C[0][2]; + out2[5] = C[1][2]; + } +} + +void split_cubic(float out1[8], float out2[8], float curve[8], float split) +{ + float * v0, * v1, * v2, * v3; + float s, s2, s3, ms, ms2, ms3; + + v0 = &curve[0]; + v1 = &curve[2]; + v2 = &curve[4]; + v3 = &curve[6]; + + s = split; + ms = 1 - split; + s2 = s * s; + ms2 = ms * ms; + s3 = s2 * s; + ms3 = ms2 * ms; + + float B[2][4] = { + {v0[0], v1[0], v2[0], v3[0]}, + {v0[1], v1[1], v2[1], v3[1]} + }; + + /* First curve */ + { + float C[2][4] = { {0} }; + float A[16] = { + 1, 0, 0, 0, + ms, s, 0, 0, + ms2, 2 * ms * s, s2, 0, + ms3, 3 * s * ms2, 3 * s2 * ms, s3 + }; + /* C = A �� B */ + for(uint8_t i = 0; i < 2; ++i) { + for(size_t y = 0; y < 4; ++y) + for(size_t x = 0; x < 1; ++x) + for(size_t z = 0; z < 4; ++z) { + C[i][x + y * 1] += A[z + y * 4] * B[i][x + z * 1]; + } + } + + out1[0] = C[0][0]; + out1[1] = C[1][0]; + out1[2] = C[0][1]; + out1[3] = C[1][1]; + out1[4] = C[0][2]; + out1[5] = C[1][2]; + out1[6] = C[0][3]; + out1[7] = C[1][3]; + } + + /* Second curve */ + { + float C[2][4] = { {0} }; + float A[16] = { + ms3, 3 * s * ms2, 3 * s2 * ms, s3, + 0, ms2, 2 * ms * s, s2, + 0, 0, ms, s, + 0, 0, 0, 1 + }; + /* C = A �� B */ + for(uint8_t i = 0; i < 2; ++i) { + for(size_t y = 0; y < 4; ++y) + for(size_t x = 0; x < 1; ++x) + for(size_t z = 0; z < 4; ++z) { + C[i][x + y * 1] += A[z + y * 4] * B[i][x + z * 1]; + } + } + + out2[0] = C[0][0]; + out2[1] = C[1][0]; + out2[2] = C[0][1]; + out2[3] = C[1][1]; + out2[4] = C[0][2]; + out2[5] = C[1][2]; + out2[6] = C[0][3]; + out2[7] = C[1][3]; + } +} +#if (CHIPID != 0x265) +static vg_lite_error_t _flatten_quad_bezier( + vg_lite_stroke_t * stroke_conversion, + vg_lite_float_t rootCurve[6], + vg_lite_float_t subCurve[6], + vg_lite_uint8_t level) +{ + vg_lite_error_t error = VG_LITE_SUCCESS; + float * v0, * v1, * v2; + float dx2, dy2, d1; + float subCurve1[6], subCurve2[6]; + vg_lite_path_point_ptr point0, point1; + vg_lite_float_t * curve; + curve = (level == 0) ? rootCurve : subCurve; + + if(!stroke_conversion) + return VG_LITE_INVALID_ARGUMENT; + if(level > 10) return error; + + v0 = &curve[0]; + v1 = &curve[2]; + v2 = &curve[4]; + + if(level == 0) { + /* Add extra P0 for incoming tangent. */ + point0 = stroke_conversion->path_end; + /* First add P1 to calculate incoming tangent, which is saved in P0. */ + VG_LITE_ERROR_HANDLER(_add_point_to_point_list(stroke_conversion, v1[0], v1[1], vgcFLATTEN_START)); + + point1 = stroke_conversion->path_end; + /* Change the point1's coordinates back to P0. */ + point1->x = v0[0]; + point1->y = v0[1]; + point0->length = 0.0f; + } + + dx2 = v2[0] - v0[0]; + dy2 = v2[1] - v0[1]; + d1 = fabsf((v1[0] - v2[0]) * dy2 - (v1[1] - v2[1]) * dx2); + + if(d1 * d1 < 0.25 * (dx2 * dx2 + dy2 * dy2)) { + float bound[4]; + + bound[0] = MIN(v0[0], v2[0]); + bound[1] = MIN(v0[1], v2[1]); + bound[2] = MAX(v0[0], v2[0]); + bound[3] = MAX(v0[1], v2[1]); + + if(!(v1[0] >= bound[0] && v1[0] <= bound[2] && v1[1] >= bound[1] && v1[1] <= bound[3])) { + /* Compute root. */ + float alignedCurve[6]; + float d, n, t, pt[2]; + + get_aligned_quad(alignedCurve, curve); + + n = alignedCurve[0] - alignedCurve[2]; + d = alignedCurve[0] - 2.f * alignedCurve[2] + alignedCurve[4]; + if(fabsf(d) > 1e-12f) { + t = n / d; + if(t > 1e-12f && t < 1.f - 1e-12f) { + quad_bezier(&pt[0], &pt[1], curve, t); + VG_LITE_ERROR_HANDLER(_add_point_to_point_list(stroke_conversion, pt[0], pt[1], vgcFLATTEN_MIDDLE)); + } + } + } + else if(level == 0) { + float pt[2]; + uint8_t n = 16; + for(uint8_t i = 1; i < n; i++) { + vg_lite_float_t t = (vg_lite_float_t)i / (vg_lite_float_t)n; + quad_bezier(&pt[0], &pt[1], curve, t); + VG_LITE_ERROR_HANDLER(_add_point_to_point_list(stroke_conversion, pt[0], pt[1], vgcFLATTEN_MIDDLE)); + } + } + if(level == 0) { + VG_LITE_ERROR_HANDLER(_add_point_to_point_list(stroke_conversion, v2[0], v2[1], vgcFLATTEN_END)); + } + else if((v2[0] != rootCurve[4]) || (v2[1] != rootCurve[5])) { + VG_LITE_ERROR_HANDLER(_add_point_to_point_list(stroke_conversion, v2[0], v2[1], vgcFLATTEN_MIDDLE)); + } + if(level == 0) { + /* Add extra P2 for outgoing tangent. */ + /* First change P2(point0)'s coordinates to P1. */ + point0 = stroke_conversion->path_end; + point0->x = v1[0]; + point0->y = v1[1]; + + /* Add P2 to calculate outgoing tangent. */ + VG_LITE_ERROR_HANDLER(_add_point_to_point_list(stroke_conversion, v2[0], v2[1], vgcFLATTEN_NO)); + + point1 = stroke_conversion->path_end; + + /* Change point0's coordinates back to P2. */ + point0->x = v2[0]; + point0->y = v2[1]; + point0->length = 0.0f; + } + return error; + } + + split_quad(subCurve1, subCurve2, curve, 0.5); + VG_LITE_ERROR_HANDLER(_flatten_quad_bezier(stroke_conversion, rootCurve, subCurve1, level + 1)); + VG_LITE_ERROR_HANDLER(_flatten_quad_bezier(stroke_conversion, rootCurve, subCurve2, level + 1)); + if(level == 0) { + /* Add point 2 separately to avoid cumulative errors. */ + VG_LITE_ERROR_HANDLER(_add_point_to_point_list(stroke_conversion, v2[0], v2[1], vgcFLATTEN_END)); + + /* Add extra P2 for outgoing tangent. */ + /* First change P2(point0)'s coordinates to P1. */ + point0 = stroke_conversion->path_end; + point0->x = v1[0]; + point0->y = v1[1]; + + /* Add P2 to calculate outgoing tangent. */ + VG_LITE_ERROR_HANDLER(_add_point_to_point_list(stroke_conversion, v2[0], v2[1], vgcFLATTEN_NO)); + + point1 = stroke_conversion->path_end; + + /* Change point0's coordinates back to P2. */ + point0->x = v2[0]; + point0->y = v2[1]; + point0->length = 0.0f; + } +ErrorHandler: + return error; +} +#else +static vg_lite_error_t _flatten_quad_bezier_original( + vg_lite_stroke_t * stroke_conversion, + vg_lite_float_t curve[6], + vg_lite_uint8_t level) +{ + vg_lite_error_t error = VG_LITE_SUCCESS; + float * v0, * v1, * v2; + float dx2, dy2, d1; + float subCurve1[6], subCurve2[6]; + vg_lite_path_point_ptr point0, point1; + + if(!stroke_conversion) + return VG_LITE_INVALID_ARGUMENT; + if(level > 10) return error; + + v0 = &curve[0]; + v1 = &curve[2]; + v2 = &curve[4]; + + if(level == 0) { + /* Add extra P0 for incoming tangent. */ + point0 = stroke_conversion->path_end; + /* First add P1 to calculate incoming tangent, which is saved in P0. */ + VG_LITE_ERROR_HANDLER(_add_point_to_point_list(stroke_conversion, v1[0], v1[1], vgcFLATTEN_NO)); + + point1 = stroke_conversion->path_end; + /* Change the point1's coordinates back to P0. */ + point1->x = v0[0]; + point1->y = v0[1]; + point0->length = 0.0f; + } + + dx2 = v2[0] - v0[0]; + dy2 = v2[1] - v0[1]; + d1 = fabsf((v1[0] - v2[0]) * dy2 - (v1[1] - v2[1]) * dx2); + + if(d1 * d1 < 0.25 * (dx2 * dx2 + dy2 * dy2)) { + float bound[4]; + + bound[0] = MIN(v0[0], v2[0]); + bound[1] = MIN(v0[1], v2[1]); + bound[2] = MAX(v0[0], v2[0]); + bound[3] = MAX(v0[1], v2[1]); + + if(!(v1[0] >= bound[0] && v1[0] <= bound[2] && v1[1] >= bound[1] && v1[1] <= bound[3])) { + /* Compute root. */ + float alignedCurve[6]; + float d, n, t, pt[2]; + + get_aligned_quad(alignedCurve, curve); + + n = alignedCurve[0] - alignedCurve[2]; + d = alignedCurve[0] - 2.f * alignedCurve[2] + alignedCurve[4]; + if(fabsf(d) > 1e-12f) { + t = n / d; + if(t > 1e-12f && t < 1.f - 1e-12f) { + quad_bezier(&pt[0], &pt[1], curve, t); + VG_LITE_ERROR_HANDLER(_add_point_to_point_list(stroke_conversion, pt[0], pt[1], vgcFLATTEN_NO)); + } + } + } + VG_LITE_ERROR_HANDLER(_add_point_to_point_list(stroke_conversion, v2[0], v2[1], vgcFLATTEN_NO)); + return error; + } + + split_quad(subCurve1, subCurve2, curve, 0.5); + VG_LITE_ERROR_HANDLER(_flatten_quad_bezier_original(stroke_conversion, subCurve1, level + 1)); + VG_LITE_ERROR_HANDLER(_flatten_quad_bezier_original(stroke_conversion, subCurve2, level + 1)); + if(level == 0) { + /* Add point 2 separately to avoid cumulative errors. */ + VG_LITE_ERROR_HANDLER(_add_point_to_point_list(stroke_conversion, v2[0], v2[1], vgcFLATTEN_NO)); + + /* Add extra P2 for outgoing tangent. */ + /* First change P2(point0)'s coordinates to P1. */ + point0 = stroke_conversion->path_end; + point0->x = v1[0]; + point0->y = v1[1]; + + /* Add P2 to calculate outgoing tangent. */ + VG_LITE_ERROR_HANDLER(_add_point_to_point_list(stroke_conversion, v2[0], v2[1], vgcFLATTEN_NO)); + + point1 = stroke_conversion->path_end; + + /* Change point0's coordinates back to P2. */ + point0->x = v2[0]; + point0->y = v2[1]; + point0->length = 0.0f; + } +ErrorHandler: + return error; +} +#endif + +#if (CHIPID != 0x265) +static vg_lite_error_t _flatten_cubic_bezier( + vg_lite_stroke_t * stroke_conversion, + vg_lite_float_t rootCurve[8], + vg_lite_float_t subCurve[8], + vg_lite_uint8_t level) +{ + vg_lite_error_t error = VG_LITE_SUCCESS; + float * v0, * v1, * v2, * v3; + float dx3, dy3, d1, d2; + float subCurve1[8], subCurve2[8]; + vg_lite_path_point_ptr point0, point1; + vg_lite_float_t * curve; + + if(!stroke_conversion) + return VG_LITE_INVALID_ARGUMENT; + if(level > 10) return error; + + curve = (level == 0) ? rootCurve : subCurve; + v0 = &curve[0]; + v1 = &curve[2]; + v2 = &curve[4]; + v3 = &curve[6]; + + if(level == 0) { + /* Add extra P0 for incoming tangent. */ + point0 = stroke_conversion->path_end; + /* First add P1/P2/P3 to calculate incoming tangent, which is saved in P0. */ + if(v0[0] != v1[0] || v0[1] != v1[1]) { + VG_LITE_ERROR_HANDLER(_add_point_to_point_list(stroke_conversion, v1[0], v1[1], vgcFLATTEN_START)); + } + else if(v0[0] != v2[0] || v0[1] != v2[1]) { + VG_LITE_ERROR_HANDLER(_add_point_to_point_list(stroke_conversion, v2[0], v2[1], vgcFLATTEN_START)); + } + else { + VG_LITE_ERROR_HANDLER(_add_point_to_point_list(stroke_conversion, v3[0], v3[1], vgcFLATTEN_START)); + } + point1 = stroke_conversion->path_end; + /* Change the point1's coordinates back to P0. */ + point1->x = v0[0]; + point1->y = v0[1]; + point0->length = 0.0f; + } + + dx3 = v3[0] - v0[0]; + dy3 = v3[1] - v0[1]; + d1 = fabsf((v1[0] - v3[0]) * dy3 - (v1[1] - v3[1]) * dx3); + d2 = fabsf((v2[0] - v3[0]) * dy3 - (v2[1] - v3[1]) * dx3); + + if((d1 + d2) * (d1 + d2) < 0.25f * (dx3 * dx3 + dy3 * dy3)) { + float bound[4]; + + bound[0] = MIN(v0[0], v3[0]); + bound[1] = MIN(v0[1], v3[1]); + bound[2] = MAX(v0[0], v3[0]); + bound[3] = MAX(v0[1], v3[1]); + if(!(v1[0] >= bound[0] && v1[0] <= bound[2] && v1[1] >= bound[1] && v1[1] <= bound[3]) || + !(v2[0] >= bound[0] && v2[0] <= bound[2] && v2[1] >= bound[1] && v2[1] <= bound[3])) { + /* Compute root. */ + float alignedCurve[8]; + float a, b, c, b2ac, root[2], t, pt[2]; + uint8_t rootNum; + + get_aligned_cubic(alignedCurve, curve); + + a = -3.f * alignedCurve[0] + 9.f * alignedCurve[2] - 9.f * alignedCurve[4] + 3.f * alignedCurve[6]; + b = 6.f * alignedCurve[0] - 12.f * alignedCurve[2] + 6.f * alignedCurve[4]; + c = -3.f * alignedCurve[0] + 3.f * alignedCurve[2]; + rootNum = 0; + if(fabs(a) < 1e-12f) { // linear solution + t = -c / b; + if(t > 1e-12f && t < 1.f - 1e-12f) + root[rootNum++] = t; + } + else { // quadtratic solution + b2ac = b * b - 4.f * a * c; + if(b2ac > 1e-12f) { + t = (-b + (float)sqrt(b2ac)) / (2.f * a); + if(t > 1e-12f && t < 1.f - 1e-12f) + root[rootNum++] = t; + t = (-b - (float)sqrt(b2ac)) / (2.f * a); + if(t > 1e-12f && t < 1.f - 1e-12f) + root[rootNum++] = t; + } + } + if(rootNum == 2 && root[0] > root[1]) { + /* Exchange root. */ + float tmp; + tmp = root[0]; + root[0] = root[1]; + root[1] = tmp; + } + if((rootNum <= 2) && (level == 0)) { + float pt[2]; + uint8_t n = 8; + if(rootNum == 2) { + float step = (root[1] - root[0]) / 8; + float t = root[0]; + while(t < root[1]) { + cubic_bezier(&pt[0], &pt[1], curve, t); + VG_LITE_ERROR_HANDLER(_add_point_to_point_list(stroke_conversion, pt[0], pt[1], vgcFLATTEN_MIDDLE)); + t += step; + } + } + else { + for(uint8_t i = 1; i < n; i++) { + vg_lite_float_t t = (vg_lite_float_t)i / (vg_lite_float_t)n; + cubic_bezier(&pt[0], &pt[1], curve, t); + VG_LITE_ERROR_HANDLER(_add_point_to_point_list(stroke_conversion, pt[0], pt[1], vgcFLATTEN_MIDDLE)); + } + } + } + else { + for(uint8_t i = 0; i < rootNum; i++) { + cubic_bezier(&pt[0], &pt[1], curve, root[i]); + VG_LITE_ERROR_HANDLER(_add_point_to_point_list(stroke_conversion, pt[0], pt[1], vgcFLATTEN_MIDDLE)); + } + } + } + else if(level == 0) { + vg_lite_float_t a1x, a1y, a2x, a2y, a3x, a3y; + vg_lite_float_t ddf0, ddf1, t1, t2, upper_bound; + vg_lite_uint32_t n; + vg_lite_float_t pt[2]; + a1x = 3 * (v1[0] - v0[0]); + a1y = 3 * (v1[1] - v0[1]); + a2x = 3 * (v0[0] - v1[0] - v1[0] + v2[0]); + a2y = 3 * (v0[1] - v1[1] - v1[1] + v2[1]); + a3x = 3 * (v1[0] - v2[0]) + v3[0] - v0[0]; + a3y = 3 * (v1[1] - v2[1]) + v3[1] - v0[1]; + + ddf0 = a2x * a2x + a2y * a2y; + t1 = a2x + a3x + a3x + a3x; + t2 = a2y + a3y + a3y + a3y; + ddf1 = t1 * t1 + t2 * t2; + upper_bound = ddf0 > ddf1 ? ddf0 : ddf1; + upper_bound = SQRTF(upper_bound); + upper_bound += upper_bound; + upper_bound = SQRTF(upper_bound); + if(stroke_conversion->fattened) { + upper_bound *= stroke_conversion->line_width; + } + n = (vg_lite_uint32_t)ceil(upper_bound); + + if(n == 0 || n > 64) { + n = (vg_lite_uint8_t)(64 / (level + 1)); + } + for(vg_lite_uint32_t i = 1; i < n; i++) { + vg_lite_float_t t = (vg_lite_float_t)i / (vg_lite_float_t)n; + cubic_bezier(&pt[0], &pt[1], curve, t); + VG_LITE_ERROR_HANDLER(_add_point_to_point_list(stroke_conversion, pt[0], pt[1], vgcFLATTEN_MIDDLE)); + } + } + + if(level == 0) { + VG_LITE_ERROR_HANDLER(_add_point_to_point_list(stroke_conversion, v3[0], v3[1], vgcFLATTEN_END)); + } + else { + vg_lite_float_t pt[2], t; + for(int i = 1; i < 4; i++) { + t = (vg_lite_float_t)i / 4; + cubic_bezier(&pt[0], &pt[1], curve, t); + VG_LITE_ERROR_HANDLER(_add_point_to_point_list(stroke_conversion, pt[0], pt[1], vgcFLATTEN_MIDDLE)); + } + if((v3[0] != rootCurve[6]) || (v3[1] != rootCurve[7])) { + VG_LITE_ERROR_HANDLER(_add_point_to_point_list(stroke_conversion, v3[0], v3[1], vgcFLATTEN_MIDDLE)); + } + } + + /* Add extra P3 for outgoing tangent. */ + /* First change P3(point0)'s coordinates to P0/P1/P2. */ + if(level == 0) { + point0 = stroke_conversion->path_end; + if(v3[0] != v2[0] || v3[1] != v2[1]) { + point0->x = v2[0]; + point0->y = v2[1]; + } + else if(v3[0] != v1[0] || v3[1] != v1[1]) { + point0->x = v1[0]; + point0->y = v1[1]; + } + else { + point0->x = v0[0]; + point0->y = v0[1]; + } + + /* Add P3 to calculate outgoing tangent. */ + VG_LITE_ERROR_HANDLER(_add_point_to_point_list(stroke_conversion, v3[0], v3[1], vgcFLATTEN_NO)); + + point1 = stroke_conversion->path_end; + + /* Change point0's coordinates back to P3. */ + point0->x = v3[0]; + point0->y = v3[1]; + point0->length = 0.0f; + } + return error; + } + + split_cubic(subCurve1, subCurve2, curve, 0.5); + VG_LITE_ERROR_HANDLER(_flatten_cubic_bezier(stroke_conversion, rootCurve, subCurve1, level + 1)); + VG_LITE_ERROR_HANDLER(_flatten_cubic_bezier(stroke_conversion, rootCurve, subCurve2, level + 1)); + if(level == 0) { + /* Add point 3 separately to avoid cumulative errors. */ + VG_LITE_ERROR_HANDLER(_add_point_to_point_list(stroke_conversion, v3[0], v3[1], vgcFLATTEN_END)); + + /* Add extra P3 for outgoing tangent. */ + /* First change P3(point0)'s coordinates to P0/P1/P2. */ + point0 = stroke_conversion->path_end; + if(v3[0] != v2[0] || v3[1] != v2[1]) { + point0->x = v2[0]; + point0->y = v2[1]; + } + else if(v3[0] != v1[0] || v3[1] != v1[1]) { + point0->x = v1[0]; + point0->y = v1[1]; + } + else { + point0->x = v0[0]; + point0->y = v0[1]; + } + + /* Add P3 to calculate outgoing tangent. */ + VG_LITE_ERROR_HANDLER(_add_point_to_point_list(stroke_conversion, v3[0], v3[1], vgcFLATTEN_NO)); + + point1 = stroke_conversion->path_end; + + /* Change point0's coordinates back to P3. */ + point0->x = v3[0]; + point0->y = v3[1]; + point0->length = 0.0f; + } +ErrorHandler: + return error; +} +#else +static vg_lite_error_t _flatten_cubic_bezier_original( + vg_lite_stroke_t * stroke_conversion, + vg_lite_float_t curve[8], + vg_lite_uint8_t level) +{ + vg_lite_error_t error = VG_LITE_SUCCESS; + float * v0, * v1, * v2, * v3; + float dx3, dy3, d1, d2; + float subCurve1[8], subCurve2[8]; + vg_lite_path_point_ptr point0, point1; + + if(!stroke_conversion) + return VG_LITE_INVALID_ARGUMENT; + if(level > 10) return error; + + v0 = &curve[0]; + v1 = &curve[2]; + v2 = &curve[4]; + v3 = &curve[6]; + + if(level == 0) { + /* Add extra P0 for incoming tangent. */ + point0 = stroke_conversion->path_end; + /* First add P1/P2/P3 to calculate incoming tangent, which is saved in P0. */ + if(v0[0] != v1[0] || v0[1] != v1[1]) { + VG_LITE_ERROR_HANDLER(_add_point_to_point_list(stroke_conversion, v1[0], v1[1], vgcFLATTEN_NO)); + } + else if(v0[0] != v2[0] || v0[1] != v2[1]) { + VG_LITE_ERROR_HANDLER(_add_point_to_point_list(stroke_conversion, v2[0], v2[1], vgcFLATTEN_NO)); + } + else { + VG_LITE_ERROR_HANDLER(_add_point_to_point_list(stroke_conversion, v3[0], v3[1], vgcFLATTEN_NO)); + } + point1 = stroke_conversion->path_end; + /* Change the point1's coordinates back to P0. */ + point1->x = v0[0]; + point1->y = v0[1]; + point0->length = 0.0f; + } + + dx3 = v3[0] - v0[0]; + dy3 = v3[1] - v0[1]; + d1 = fabsf((v1[0] - v3[0]) * dy3 - (v1[1] - v3[1]) * dx3); + d2 = fabsf((v2[0] - v3[0]) * dy3 - (v2[1] - v3[1]) * dx3); + + if((d1 + d2) * (d1 + d2) < 0.25f * (dx3 * dx3 + dy3 * dy3)) { + float bound[4]; + + bound[0] = MIN(v0[0], v3[0]); + bound[1] = MIN(v0[1], v3[1]); + bound[2] = MAX(v0[0], v3[0]); + bound[3] = MAX(v0[1], v3[1]); + if(!(v1[0] >= bound[0] && v1[0] <= bound[2] && v1[1] >= bound[1] && v1[1] <= bound[3]) || + !(v2[0] >= bound[0] && v2[0] <= bound[2] && v2[1] >= bound[1] && v2[1] <= bound[3])) { + /* Compute root. */ + float alignedCurve[8]; + float a, b, c, b2ac, root[2], t, pt[2]; + uint8_t rootNum; + + get_aligned_cubic(alignedCurve, curve); + + a = -3.f * alignedCurve[0] + 9.f * alignedCurve[2] - 9.f * alignedCurve[4] + 3.f * alignedCurve[6]; + b = 6.f * alignedCurve[0] - 12.f * alignedCurve[2] + 6.f * alignedCurve[4]; + c = -3.f * alignedCurve[0] + 3.f * alignedCurve[2]; + rootNum = 0; + if(fabs(a) < 1e-12f) { // linear solution + t = -c / b; + if(t > 1e-12f && t < 1.f - 1e-12f) + root[rootNum++] = t; + } + else { // quadtratic solution + b2ac = b * b - 4.f * a * c; + if(b2ac > 1e-12f) { + t = (-b + (float)sqrt(b2ac)) / (2.f * a); + if(t > 1e-12f && t < 1.f - 1e-12f) + root[rootNum++] = t; + t = (-b - (float)sqrt(b2ac)) / (2.f * a); + if(t > 1e-12f && t < 1.f - 1e-12f) + root[rootNum++] = t; + } + } + + if(rootNum == 2 && root[0] > root[1]) { + /* Exchange root. */ + float tmp; + tmp = root[0]; + root[0] = root[1]; + root[1] = tmp; + } + + for(uint8_t i = 0; i < rootNum; ++i) { + cubic_bezier(&pt[0], &pt[1], curve, root[i]); + VG_LITE_ERROR_HANDLER(_add_point_to_point_list(stroke_conversion, pt[0], pt[1], vgcFLATTEN_NO)); + } + } + VG_LITE_ERROR_HANDLER(_add_point_to_point_list(stroke_conversion, v3[0], v3[1], vgcFLATTEN_NO)); + return error; + } + + split_cubic(subCurve1, subCurve2, curve, 0.5); + VG_LITE_ERROR_HANDLER(_flatten_cubic_bezier_original(stroke_conversion, subCurve1, level + 1)); + VG_LITE_ERROR_HANDLER(_flatten_cubic_bezier_original(stroke_conversion, subCurve2, level + 1)); + if(level == 0) { + /* Add point 3 separately to avoid cumulative errors. */ + VG_LITE_ERROR_HANDLER(_add_point_to_point_list(stroke_conversion, v3[0], v3[1], vgcFLATTEN_NO)); + + /* Add extra P3 for outgoing tangent. */ + /* First change P3(point0)'s coordinates to P0/P1/P2. */ + point0 = stroke_conversion->path_end; + if(v3[0] != v2[0] || v3[1] != v2[1]) { + point0->x = v2[0]; + point0->y = v2[1]; + } + else if(v3[0] != v1[0] || v3[1] != v1[1]) { + point0->x = v1[0]; + point0->y = v1[1]; + } + else { + point0->x = v0[0]; + point0->y = v0[1]; + } + + /* Add P3 to calculate outgoing tangent. */ + VG_LITE_ERROR_HANDLER(_add_point_to_point_list(stroke_conversion, v3[0], v3[1], vgcFLATTEN_NO)); + + point1 = stroke_conversion->path_end; + + /* Change point0's coordinates back to P3. */ + point0->x = v3[0]; + point0->y = v3[1]; + point0->length = 0.0f; + } +ErrorHandler: + return error; +} +#endif +#else +static vg_lite_error_t +_flatten_quad_bezier( + vg_lite_stroke_t * stroke_conversion, + vg_lite_float_t X0, + vg_lite_float_t Y0, + vg_lite_float_t X1, + vg_lite_float_t Y1, + vg_lite_float_t X2, + vg_lite_float_t Y2 +) +{ + vg_lite_error_t error = VG_LITE_SUCCESS; + uint32_t n; + vg_lite_path_point_ptr point0, point1; + vg_lite_float_t x, y; + vg_lite_float_t a1x, a1y, a2x, a2y; + vg_lite_float_t f1, f2, t1, t2, upper_bound; + + if(!stroke_conversion) + return VG_LITE_INVALID_ARGUMENT; + + /* Formula. + * f(t) = (1 - t)^2 * p0 + 2 * t * (1 - t) * p1 + t^2 * p2 + * = a0 + a1 * t + a2 * t^2 + * a0 = p0 + * a1 = 2 * (-p0 + p1) + * a2 = p0 - 2 * p1 + p2 + */ + x = X1 - X0; + a1x = x + x; + y = Y1 - Y0; + a1y = y + y; + a2x = X0 - X1 - X1 + X2; + a2y = Y0 - Y1 - Y1 + Y2; + + /* Step 1: Calculate N. */ + /* Lefan's method. */ + /* dist(t) = ... + * t2 = ... + * if 0 <= t2 <= 1 + * upper_bound = dist(t2) + * else + * upper_bound = max(dist(0), dist(1)) + * N = ceil(sqrt(upper_bound / epsilon / 8)) + */ + /* Prepare dist(t). */ + f1 = a1x * a2y - a2x * a1y; + if(f1 != 0.0f) { + if(f1 < 0.0f) f1 = -f1; + + /* Calculate t2. */ + t1 = a2x * a2x + a2y * a2y; + t2 = -(x * a2x + y * a2y) / t1; + /* Calculate upper_bound. */ + if(t2 >= 0.0f && t2 <= 1.0f) { + f2 = x + a2x * t2; + f2 *= f2; + t1 = y + a2y * t2; + t1 *= t1; + upper_bound = t1 + f2; + } + else { + f2 = x + a2x; + f2 *= f2; + t1 = y + a2y; + t1 *= t1; + t2 = t1 + f2; + t1 = x * x + y * y; + upper_bound = t1 < t2 ? t1 : t2; + } + /* Calculate n. */ + upper_bound = f1 / SQRTF(upper_bound); + upper_bound = SQRTF(upper_bound); + if(stroke_conversion->fattened) { + upper_bound *= stroke_conversion->line_width; + } + n = (uint32_t) ceil(upper_bound); + } + else { + /* n = 0 => n = 256. */ + n = 256; + } + + if(n == 0 || n > 256) { + n = 256; + } + + /* Add extra P0 for incoming tangent. */ + point0 = stroke_conversion->path_end; + /* First add P1 to calculate incoming tangent, which is saved in P0. */ + VG_LITE_ERROR_HANDLER(_add_point_to_point_list(stroke_conversion, X1, Y1, vgcFLATTEN_START)); + + point1 = stroke_conversion->path_end; + /* Change the point1's coordinates back to P0. */ + point1->x = X0; + point1->y = Y0; + point0->length = 0.0f; + + if(n > 1) { + vg_lite_float_t d, dsquare, dx, dy, ddx, ddy; + vg_lite_float_t ratioX, ratioY; + uint32_t i; + + /* Step 2: Calculate deltas. */ + /* Df(t) = f(t + d) - f(t) + * = a1 * d + a2 * d^2 + 2 * a2 * d * t + * DDf(t) = Df(t + d) - Df(t) + * = 2 * a2 * d^2 + * f(0) = a0 + * Df(0) = a1 * d + a2 * d^2 + * DDf(0) = 2 * a2 * d^2 + */ + d = 1.0f / (vg_lite_float_t) n; + dsquare = d * d; + ddx = a2x * dsquare; + ddy = a2y * dsquare; + dx = a1x * d + ddx; + dy = a1y * d + ddy; + ddx += ddx; + ddy += ddy; + + /* Step 3: Add points. */ + ratioX = dx / X0; + if(ratioX < 0.0f) ratioX = -ratioX; + ratioY = dy / Y0; + if(ratioY < 0.0f) ratioY = -ratioY; + if(ratioX > 1.0e-6f && ratioY > 1.0e-6f) { + x = X0; + y = Y0; + for(i = 1; i < n; i++) { + x += dx; + y += dy; + + /* Add a point to subpath. */ + VG_LITE_ERROR_HANDLER(_add_point_to_point_list_wdelta(stroke_conversion, x, y, dx, dy, vgcFLATTEN_MIDDLE)); + + dx += ddx; + dy += ddy; + } + + } + else { + for(i = 1; i < n; i++) { + vg_lite_float_t t = (vg_lite_float_t) i / (vg_lite_float_t) n; + vg_lite_float_t u = 1.0f - t; + vg_lite_float_t a0 = u * u; + vg_lite_float_t a1 = 2.0f * t * u; + vg_lite_float_t a2 = t * t; + + x = a0 * X0 + a1 * X1 + a2 * X2; + y = a0 * Y0 + a1 * Y1 + a2 * Y2; + + /* Add a point to subpath. */ + VG_LITE_ERROR_HANDLER(_add_point_to_point_list(stroke_conversion, x, y, vgcFLATTEN_MIDDLE)); + } + } + } + + /* Add point 2 separately to avoid cumulative errors. */ + VG_LITE_ERROR_HANDLER(_add_point_to_point_list(stroke_conversion, X2, Y2, vgcFLATTEN_END)); + + /* Add extra P2 for outgoing tangent. */ + /* First change P2(point0)'s coordinates to P1. */ + point0 = stroke_conversion->path_end; + point0->x = X1; + point0->y = Y1; + + /* Add P2 to calculate outgoing tangent. */ + VG_LITE_ERROR_HANDLER(_add_point_to_point_list(stroke_conversion, X2, Y2, vgcFLATTEN_NO)); + + point1 = stroke_conversion->path_end; + + /* Change point0's coordinates back to P2. */ + point0->x = X2; + point0->y = Y2; + point0->length = 0.0f; + +ErrorHandler: + return error; +} + +static vg_lite_error_t +_flatten_cubic_bezier( + vg_lite_stroke_t * stroke_conversion, + vg_lite_float_t X0, + vg_lite_float_t Y0, + vg_lite_float_t X1, + vg_lite_float_t Y1, + vg_lite_float_t X2, + vg_lite_float_t Y2, + vg_lite_float_t X3, + vg_lite_float_t Y3 +) +{ + vg_lite_error_t error = VG_LITE_SUCCESS; + uint32_t n; + vg_lite_path_point_ptr point0, point1; + vg_lite_float_t x, y; + vg_lite_float_t a1x, a1y, a2x, a2y, a3x, a3y; + vg_lite_float_t ddf0, ddf1, t1, t2, upper_bound; + + if(!stroke_conversion) + return VG_LITE_INVALID_ARGUMENT; + + /* Formula. + * f(t) = (1 - t)^3 * p0 + 3 * t * (1 - t)^2 * p1 + 3 * t^2 * (1 - t) * p2 + t^3 * p3 + * = a0 + a1 * t + a2 * t^2 + a3 * t^3 + */ + x = X1 - X0; + a1x = x + x + x; + y = Y1 - Y0; + a1y = y + y + y; + x = X0 - X1 - X1 + X2; + a2x = x + x + x; + y = Y0 - Y1 - Y1 + Y2; + a2y = y + y + y; + x = X1 - X2; + a3x = x + x + x + X3 - X0; + y = Y1 - Y2; + a3y = y + y + y + Y3 - Y0; + + /* Step 1: Calculate N. */ + /* Lefan's method. */ + /* df(t)/dt = a1 + 2 * a2 * t + 3 * a3 * t^2 + * d2f(t)/dt2 = 2 * a2 + 6 * a3 * t + * N = ceil(sqrt(max(ddfx(0)^2 + ddfy(0)^2, ddfx(1)^2 + ddyf(1)^2) / epsilon / 8)) + */ + + ddf0 = a2x * a2x + a2y * a2y; + t1 = a2x + a3x + a3x + a3x; + t2 = a2y + a3y + a3y + a3y; + ddf1 = t1 * t1 + t2 * t2; + upper_bound = ddf0 > ddf1 ? ddf0 : ddf1; + upper_bound = SQRTF(upper_bound); + upper_bound += upper_bound; + upper_bound = SQRTF(upper_bound); + if(stroke_conversion->fattened) { + upper_bound *= stroke_conversion->line_width; + } + n = (uint32_t) ceil(upper_bound); + + if(n == 0 || n > 256) { + n = 256; + } + + /* Add extra P0 for incoming tangent. */ + point0 = stroke_conversion->path_end; + /* First add P1/P2/P3 to calculate incoming tangent, which is saved in P0. */ + if(X0 != X1 || Y0 != Y1) { + VG_LITE_ERROR_HANDLER(_add_point_to_point_list(stroke_conversion, X1, Y1, vgcFLATTEN_START)); + } + else if(X0 != X2 || Y0 != Y2) { + VG_LITE_ERROR_HANDLER(_add_point_to_point_list(stroke_conversion, X2, Y2, vgcFLATTEN_START)); + } + else { + VG_LITE_ERROR_HANDLER(_add_point_to_point_list(stroke_conversion, X3, Y3, vgcFLATTEN_START)); + } + point1 = stroke_conversion->path_end; + /* Change the point1's coordinates back to P0. */ + point1->x = X0; + point1->y = Y0; + point0->length = 0.0f; + + if(n > 1) { + vg_lite_float_t d, dsquare, dcube, dx, dy, ddx, ddy, dddx, dddy; + vg_lite_float_t ratioX, ratioY; + uint32_t i; + + /* Step 2: Calculate deltas */ + /* Df(t) = f(t + d) - f(t) + * DDf(t) = Df(t + d) - Df(t) + * DDDf(t) = DDf(t + d) - DDf(t) + * f(0) = a0 + * Df(0) = a1 * d + a2 * d^2 + a3 * d^3 + * DDf(0) = 2 * a2 * d^2 + 6 * a3 * d^3 + * DDDf(0) = 6 * a3 * d^3 + */ + d = 1.0f / (vg_lite_float_t) n; + dsquare = d * d; + dcube = dsquare * d; + ddx = a2x * dsquare; + ddy = a2y * dsquare; + dddx = a3x * dcube; + dddy = a3y * dcube; + dx = a1x * d + ddx + dddx; + dy = a1y * d + ddy + dddy; + ddx += ddx; + ddy += ddy; + dddx *= 6.0f; + dddy *= 6.0f; + ddx += dddx; + ddy += dddy; + + /* Step 3: Add points. */ + ratioX = dx / X0; + if(ratioX < 0.0f) ratioX = -ratioX; + ratioY = dy / Y0; + if(ratioY < 0.0f) ratioY = -ratioY; + if(ratioX > 1.0e-6f && ratioY > 1.0e-6f) { + x = X0; + y = Y0; + for(i = 1; i < n; i++) { + x += dx; + y += dy; + + /* Add a point to subpath. */ + VG_LITE_ERROR_HANDLER(_add_point_to_point_list_wdelta(stroke_conversion, x, y, dx, dy, vgcFLATTEN_MIDDLE)); + dx += ddx; + ddx += dddx; + dy += ddy; + ddy += dddy; + } + } + else { + for(i = 1; i < n; i++) { + vg_lite_float_t t = (vg_lite_float_t) i / (vg_lite_float_t) n; + vg_lite_float_t tSquare = t * t; + vg_lite_float_t tCube = tSquare * t; + vg_lite_float_t a0 = 1.0f - 3.0f * t + 3.0f * tSquare - tCube; + vg_lite_float_t a1 = 3.0f * t - 6.0f * tSquare + 3.0f * tCube; + vg_lite_float_t a2 = 3.0f * tSquare - 3.0f * tCube; + vg_lite_float_t a3 = tCube; + + x = a0 * X0 + a1 * X1 + a2 * X2 + a3 * X3; + y = a0 * Y0 + a1 * Y1 + a2 * Y2 + a3 * Y3; + + /* Add a point to subpath. */ + VG_LITE_ERROR_HANDLER(_add_point_to_point_list(stroke_conversion, x, y, vgcFLATTEN_MIDDLE)); + } + } + } + + /* Add point 3 separately to avoid cumulative errors. */ + VG_LITE_ERROR_HANDLER(_add_point_to_point_list(stroke_conversion, X3, Y3, vgcFLATTEN_END)); + + /* Add extra P3 for outgoing tangent. */ + /* First change P3(point0)'s coordinates to P0/P1/P2. */ + point0 = stroke_conversion->path_end; + if(X3 != X2 || Y3 != Y2) { + point0->x = X2; + point0->y = Y2; + } + else if(X3 != X1 || Y3 != Y1) { + point0->x = X1; + point0->y = Y1; + } + else { + point0->x = X0; + point0->y = Y0; + } + + /* Add P3 to calculate outgoing tangent. */ + VG_LITE_ERROR_HANDLER(_add_point_to_point_list(stroke_conversion, X3, Y3, vgcFLATTEN_NO)); + + point1 = stroke_conversion->path_end; + + /* Change point0's coordinates back to P3. */ + point0->x = X3; + point0->y = Y3; + point0->length = 0.0f; + +ErrorHandler: + return error; +} +#endif /* gcFEATURE_VG_SIMPLYFIED_BEZIER */ + +#define GETINCREMENT(pointer, datatype_size) \ + (datatype_size - (PTR2SIZE(pointer) & (datatype_size - 1))) + +#define SKIPTODATA(pointer, datatype_size, SIZE) \ + /* Determine the increment value. */ \ + increment = GETINCREMENT(pointer, datatype_size); \ + /* Skip to the data. */ \ + pointer += increment; \ + SIZE -= increment + +#define VGSL_GETVALUE(X) \ + X = get_value(data_pointer); \ + data_pointer += data_type_size; \ + size -= data_type_size + +#define VGSL_GETCOORDXY(X, Y) \ + VGSL_GETVALUE(X); \ + VGSL_GETVALUE(Y); \ + if (is_relative) { X += ox; Y += oy; } + +typedef vg_lite_float_t(*vg_value_getter)(int8_t * Data); + +static vg_lite_error_t _flatten_path( + vg_lite_stroke_t * stroke_conversion, + vg_lite_path_t * path +) +{ + vg_lite_error_t error = VG_LITE_SUCCESS; + uint32_t increment; + uint8_t is_relative; + uint32_t size; + uint32_t path_command; + uint32_t prev_command; + uint8_t data_type_size; + int8_t * data_pointer = NULL; + int8_t * data_pointer_use = NULL; + vg_lite_float_t sx, sy; + vg_lite_float_t ox, oy; + vg_lite_float_t px, py; + vg_lite_float_t x0, y0, x1, y1, x2, y2; + vg_value_getter get_value = NULL; + + if(!stroke_conversion || !path) + return VG_LITE_INVALID_ARGUMENT; + + sx = sy = ox = oy = px = py = 0.0f; + + prev_command = 0xFF; + + /* Select the data picker. */ + switch(path->format) { + case VG_LITE_S8: + data_type_size = 1; + get_value = _GetS8_NS_NB; + break; + + case VG_LITE_S16: + data_type_size = 2; + get_value = _GetS16_NS_NB; + break; + + case VG_LITE_S32: + data_type_size = 4; + get_value = _GetS32_NS_NB; + break; + + case VG_LITE_FP32: + data_type_size = 4; + get_value = _GetF_NS_NB; + break; + + default: + error = VG_LITE_INVALID_ARGUMENT; + goto ErrorHandler; + } + + if((path->path_type == VG_LITE_DRAW_FILL_PATH) || (path->path_type == VG_LITE_DRAW_FILL_STROKE_PATH)) { + if(path->path_length % (3 * data_type_size) == 0) { + /* add END_PATH if path_data have no END_PATH */ + stroke_conversion->add_end = 1; + path->path_length = path->path_length + data_type_size; + data_pointer_use = (int8_t *)vg_lite_os_malloc(path->path_length); + if(!data_pointer_use) + return VG_LITE_OUT_OF_RESOURCES; + memset(data_pointer_use, 0, path->path_length); + memcpy((int8_t *)data_pointer_use, (int8_t *)path->path, path->path_length - data_type_size); + vg_lite_os_free(path->path); + path->path = data_pointer_use; + path->pdata_internal = 1; + } + if(path->add_end == 1) { + stroke_conversion->add_end = 1; + } + else { + stroke_conversion->add_end = 0; + } + } + + /* Determine the data size. */ + size = path->path_length; + + /* Determine the beginning of the path data. */ + data_pointer = (int8_t *)path->path; + + /* Add an extra gcvVGCMD_MOVE 0.0 0.0 to handle the case the first command is not gcvVGCMD_MOVE. */ + if((*data_pointer & 0xfe) != VLC_OP_MOVE) { + /* Add first point to subpath. */ + VG_LITE_ERROR_HANDLER(_create_new_point_list(stroke_conversion, 0.f, 0.f, vgcFLATTEN_NO)); + } + + while(size > 0) { + /* Get the command. */ + path_command = *data_pointer & 0x1F; + + /* Assume absolute. */ + is_relative = VGL_FALSE; + + switch(path_command) { + case VLC_OP_END: + /* Skip the command. */ + size -= 1; + + if(prev_command == VLC_OP_END) { + /* Continuous gcvVGCMD_CLOSE - do nothing. */ + break; + } + + if((prev_command & 0xfe) == VLC_OP_MOVE) { + /* Delete the invalid path list. */ + vg_lite_path_list_ptr path_list_divide = stroke_conversion->cur_list; + vg_lite_os_free(path_list_divide->path_points); + vg_lite_os_free(path_list_divide); + if(stroke_conversion->cur_list == stroke_conversion->path_list_divide) { + stroke_conversion->cur_list = stroke_conversion->path_list_divide = NULL; + stroke_conversion->path_end = NULL; + stroke_conversion->path_points = NULL; + stroke_conversion->point_count = 0; + } + else { + stroke_conversion->cur_list = stroke_conversion->path_list_divide; + while(stroke_conversion->cur_list->next != path_list_divide) + stroke_conversion->cur_list = stroke_conversion->cur_list->next; + stroke_conversion->path_end = stroke_conversion->cur_list->path_end; + stroke_conversion->point_count = stroke_conversion->cur_list->point_count; + stroke_conversion->cur_list->next = NULL; + } + break; + } + + if(!stroke_conversion->add_end) { + /* Check if subPath is already closed. */ + if(ox != sx || oy != sy) { + /* Add a line from current point to the first point of current subpath. */ + VG_LITE_ERROR_HANDLER(_add_point_to_point_list(stroke_conversion, sx, sy, vgcFLATTEN_NO)); + } + if(stroke_conversion->path_points != stroke_conversion->path_end) { + /* Copy tangent data from first point to last_point. */ + vg_lite_path_point_ptr first_point = stroke_conversion->path_points; + vg_lite_path_point_ptr last_point = stroke_conversion->path_end; + last_point->length = first_point->length; + last_point->tangentX = first_point->tangentX; + last_point->tangentY = first_point->tangentY; + } + else { + /* Single point path. */ + vg_lite_path_point_ptr point = stroke_conversion->path_points; + point->tangentX = 0.0f; + point->tangentY = 0.0f; + point->length = 0.0f; + } + stroke_conversion->cur_list->closed = 1; + stroke_conversion->closed = 1; + stroke_conversion->path_end->next = NULL; + } + break; + + case VLC_OP_CLOSE: + /* Skip the command. */ + SKIPTODATA(data_pointer, data_type_size, size); + + if(prev_command == VLC_OP_CLOSE) { + /* Continuous gcvVGCMD_CLOSE - do nothing. */ + break; + } + + /* Check if subPath is already closed. */ + if(ox != sx || oy != sy) { + /* Add a line from current point to the first point of current subpath. */ + VG_LITE_ERROR_HANDLER(_add_point_to_point_list(stroke_conversion, sx, sy, vgcFLATTEN_NO)); + } + + if(stroke_conversion->path_points != stroke_conversion->path_end) { + /* Copy tangent data from first point to last_point. */ + vg_lite_path_point_ptr first_point = stroke_conversion->path_points; + vg_lite_path_point_ptr last_point = stroke_conversion->path_end; + last_point->length = first_point->length; + last_point->tangentX = first_point->tangentX; + last_point->tangentY = first_point->tangentY; + } + else { + /* Single point path. */ + vg_lite_path_point_ptr point = stroke_conversion->path_points; + point->tangentX = 0.0f; + point->tangentY = 0.0f; + point->length = 0.0f; + } + + px = ox = sx; + py = oy = sy; + + stroke_conversion->cur_list->closed = 1; + stroke_conversion->closed = 1; + break; + + case VLC_OP_MOVE_REL: + is_relative = 1; + + case VLC_OP_MOVE: /* Indicate the beginning of a new sub-path. */ + /* Skip to the data. */ + SKIPTODATA(data_pointer, data_type_size, size); + VGSL_GETCOORDXY(x0, y0); + + if((prev_command & 0xfe) == VLC_OP_MOVE) { + /* Continuous gcvVGCMD_MOVE draw nothing */ + stroke_conversion->path_points->x = x0; + stroke_conversion->path_points->y = y0; + } + else { + /* First command is gcvVGCMD_MOVE. */ + /* Add first point to subpath. */ + VG_LITE_ERROR_HANDLER(_create_new_point_list(stroke_conversion, x0, y0, vgcFLATTEN_NO)); + } + + sx = px = ox = x0; + sy = py = oy = y0; + break; + + case VLC_OP_LINE_REL: + is_relative = 1; + + case VLC_OP_LINE: + /* Skip to the data. */ + SKIPTODATA(data_pointer, data_type_size, size); + VGSL_GETCOORDXY(x0, y0); + + /* Add a point to subpath. */ + VG_LITE_ERROR_HANDLER(_add_point_to_point_list(stroke_conversion, x0, y0, vgcFLATTEN_NO)); + + px = ox = x0; + py = oy = y0; + break; + + case VLC_OP_QUAD_REL: + is_relative = 1; + + case VLC_OP_QUAD: + /* Skip to the data. */ + SKIPTODATA(data_pointer, data_type_size, size); + VGSL_GETCOORDXY(x0, y0); + VGSL_GETCOORDXY(x1, y1); + + if((ox == x0 && oy == y0) && (ox == x1 && oy == y1)) { + /* Degenerated Bezier curve. Becomes a point. */ + /* Discard zero-length segments. */ + } + else if((ox == x0 && oy == y0) || (x0 == x1 && y0 == y1)) { + /* Degenerated Bezier curve. Becomes a line. */ + /* Add a point to subpath. */ + VG_LITE_ERROR_HANDLER(_add_point_to_point_list(stroke_conversion, x1, y1, vgcFLATTEN_NO)); + } + else { +#if gcFEATURE_VG_SIMPLYFIED_BEZIER + vg_lite_float_t curve[6] = { ox, oy, x0, y0, x1, y1 }; +#if (CHIPID != 0x265) + vg_lite_float_t subCurve[6] = { 0, 0, 0, 0, 0, 0}; + VG_LITE_ERROR_HANDLER(_flatten_quad_bezier(stroke_conversion, curve, subCurve, 0)); +#else + VG_LITE_ERROR_HANDLER(_flatten_quad_bezier_original(stroke_conversion, curve, 0)); +#endif +#else + VG_LITE_ERROR_HANDLER(_flatten_quad_bezier(stroke_conversion, ox, oy, x0, y0, x1, y1)); +#endif + } + + px = x0; + py = y0; + ox = x1; + oy = y1; + break; + + case VLC_OP_CUBIC_REL: + is_relative = 1; + + case VLC_OP_CUBIC: + /* Skip to the data. */ + SKIPTODATA(data_pointer, data_type_size, size); + VGSL_GETCOORDXY(x0, y0); + VGSL_GETCOORDXY(x1, y1); + VGSL_GETCOORDXY(x2, y2); + + if((ox == x0 && oy == y0) && (ox == x1 && oy == y1) && (ox == x2 && oy == y2)) { + /* Degenerated Bezier curve. Becomes a point. */ + /* Discard zero-length segments. */ + } + else { +#if gcFEATURE_VG_SIMPLYFIED_BEZIER + vg_lite_float_t curve[8] = { ox, oy, x0, y0, x1, y1, x2, y2 }; +#if (CHIPID != 0x265) + vg_lite_float_t subCurve[8] = { 0, 0, 0, 0, 0, 0, 0, 0 }; + VG_LITE_ERROR_HANDLER(_flatten_cubic_bezier(stroke_conversion, curve, subCurve, 0)); +#else + VG_LITE_ERROR_HANDLER(_flatten_cubic_bezier_original(stroke_conversion, curve, 0)); +#endif +#else + VG_LITE_ERROR_HANDLER(_flatten_cubic_bezier(stroke_conversion, ox, oy, x0, y0, x1, y1, x2, y2)); +#endif + } + + px = x1; + py = y1; + ox = x2; + oy = y2; + break; + default: + error = VG_LITE_INVALID_ARGUMENT; + goto ErrorHandler; + } + prev_command = path_command; + } + + if((prev_command != VLC_OP_END)) { + stroke_conversion->cur_list->path_end->next = NULL; + stroke_conversion->path_end->next = NULL; + if(stroke_conversion->point_count == 1) { + /* Single point path. */ + vg_lite_path_point_ptr point = stroke_conversion->path_points; + point->tangentX = 0.0f; + point->tangentY = 0.0f; + point->length = 0.0f; + } + } + +ErrorHandler: + return error; +} + +static vg_lite_error_t +_add_point_to_right_stroke_point_list_tail( + vg_lite_stroke_t * stroke_conversion, + vg_lite_float_t X, + vg_lite_float_t Y +) +{ + vg_lite_error_t error = VG_LITE_SUCCESS; + vg_lite_path_point_ptr point; + + if(!stroke_conversion) + return VG_LITE_INVALID_ARGUMENT; + + point = (vg_lite_path_point_ptr)vg_lite_os_malloc(sizeof(*point)); + if(!point) + return VG_LITE_OUT_OF_RESOURCES; + + memset(point, 0, sizeof(*point)); + + point->x = X; + point->y = Y; + point->curve_type = CURVE_LINE; + point->prev = stroke_conversion->right_point; + point->next = NULL; + stroke_conversion->right_point->next = point; + stroke_conversion->right_point = point; + stroke_conversion->stroke_count++; + + stroke_conversion->last_stroke->point_count++; + + return error; +} + +static vg_lite_error_t +_add_point_to_left_point_list_head( + vg_lite_stroke_t * stroke_conversion, + vg_lite_float_t X, + vg_lite_float_t Y +) +{ + vg_lite_error_t error = VG_LITE_SUCCESS; + vg_lite_path_point_ptr point; + + if(!stroke_conversion) + return VG_LITE_INVALID_ARGUMENT; + + point = (vg_lite_path_point_ptr)vg_lite_os_malloc(sizeof(*point)); + if(!point) + return VG_LITE_OUT_OF_RESOURCES; + + memset(point, 0, sizeof(*point)); + + point->x = X; + point->y = Y; + point->curve_type = CURVE_LINE; + point->next = stroke_conversion->left_point; + point->prev = NULL; + stroke_conversion->left_point->prev = point; + stroke_conversion->left_point = point; + stroke_conversion->stroke_count++; + + stroke_conversion->last_stroke->point_count++; + + return error; +} + +static vg_lite_error_t _add_stroke_sub_path( + vg_lite_stroke_t * stroke_conversion, + vg_lite_sub_path_ptr * sub_path +) +{ + vg_lite_error_t error = VG_LITE_SUCCESS; + + if(!stroke_conversion || !sub_path) + return VG_LITE_INVALID_ARGUMENT; + + *sub_path = (vg_lite_sub_path_ptr)vg_lite_os_malloc(sizeof(**sub_path)); + if(!*sub_path) + return VG_LITE_OUT_OF_RESOURCES; + + memset(*sub_path, 0, sizeof(**sub_path)); + + if(stroke_conversion->last_stroke != NULL) { + stroke_conversion->last_stroke->next = *sub_path; + stroke_conversion->last_stroke = *sub_path; + } + else { + stroke_conversion->last_stroke = stroke_conversion->stroke_paths = *sub_path; + } + + return error; +} + +static vg_lite_error_t +_add_zero_length_stroke_sub_path( + vg_lite_stroke_t * stroke_conversion, + vg_lite_sub_path_ptr * stroke_subpath +) +{ + vg_lite_error_t error = VG_LITE_SUCCESS; + vg_lite_path_point_ptr new_point, Point; + vg_lite_sub_path_ptr stroke_sub_path; + vg_lite_float_t half_width; + + if(!stroke_conversion) + return VG_LITE_INVALID_ARGUMENT; + + half_width = stroke_conversion->half_width; + Point = stroke_conversion->path_points; + if(stroke_conversion->cap_style == VG_LITE_CAP_BUTT) { + /* No need to draw zero-length subPath for gcvCAP_BUTT. */ + error = VG_LITE_SUCCESS; + goto ErrorHandler; + } + + VG_LITE_ERROR_HANDLER(_add_stroke_sub_path(stroke_conversion, &stroke_sub_path)); + + if(stroke_conversion->cap_style == VG_LITE_CAP_SQUARE) { + /* Draw a square along the point's direction. */ + vg_lite_float_t dx, dy; + + if(Point->tangentX == 0.0f || Point->tangentY == 0.0f) { + dx = half_width; + dy = 0.0f; + } + else { + dx = Point->tangentY * half_width; + dy = -Point->tangentX * half_width; + } + + new_point = (vg_lite_path_point_ptr)vg_lite_os_malloc(sizeof(*new_point)); + if(!new_point) + return VG_LITE_OUT_OF_RESOURCES; + memset(new_point, 0, sizeof(*new_point)); + + new_point->x = Point->x + dx + dy; + new_point->y = Point->y - dx + dy; + new_point->curve_type = CURVE_LINE; + stroke_sub_path->point_list = stroke_conversion->right_point = new_point; + stroke_sub_path->point_count = 1; + + VG_LITE_ERROR_HANDLER(_add_point_to_right_stroke_point_list_tail(stroke_conversion, + Point->x + dx - dy, Point->y + dx + dy)); + + VG_LITE_ERROR_HANDLER(_add_point_to_right_stroke_point_list_tail(stroke_conversion, + Point->x - dx - dy, Point->y + dx - dy)); + + VG_LITE_ERROR_HANDLER(_add_point_to_right_stroke_point_list_tail(stroke_conversion, + Point->x - dx + dy, Point->y - dx - dy)); + } + else { + /* Draw a circle. */ + new_point = (vg_lite_path_point_ptr)vg_lite_os_malloc(sizeof(*new_point)); + if(!new_point) + return VG_LITE_OUT_OF_RESOURCES; + memset(new_point, 0, sizeof(*new_point)); + + new_point->x = Point->x + half_width; + new_point->y = Point->y; + new_point->curve_type = CURVE_LINE; + stroke_sub_path->point_list = stroke_conversion->right_point = new_point; + stroke_sub_path->point_count = 1; + + /* Add upper half circle. */ + VG_LITE_ERROR_HANDLER(_add_point_to_right_stroke_point_list_tail(stroke_conversion, + Point->x - half_width, Point->y)); + + stroke_conversion->right_point->curve_type = CURVE_ARC_SCCW_HALF; + stroke_conversion->right_point->tangentX = Point->x; + stroke_conversion->right_point->tangentY = Point->y; + + /* Add lower half circle. */ + VG_LITE_ERROR_HANDLER(_add_point_to_right_stroke_point_list_tail(stroke_conversion, + Point->x + half_width, Point->y)); + + stroke_conversion->right_point->curve_type = CURVE_ARC_SCCW_HALF; + stroke_conversion->right_point->tangentX = Point->x; + stroke_conversion->right_point->tangentY = Point->y; + } + + stroke_sub_path->end_point = stroke_conversion->right_point; + stroke_sub_path->end_point->next = NULL; + +ErrorHandler: + return error; +} + +/* Special asin(x) for quick calculation when -sqrt(0.5) <= x <= sqrt(0.5). */ +static vg_lite_float_t _Asin( + vg_lite_float_t X +) +{ + vg_lite_float_t x = X; + vg_lite_float_t x2 = X * X; + vg_lite_float_t s = X; + + x *= x2; + s += x * 0.1660510562575219f; + x *= x2; + s += x * 0.084044676143618186f; + x *= x2; + s += x * 0.0023776176698039313f; + x *= x2; + s += x * 0.10211922020091345f; + + return s; +} + +/* Special cos(x) for quick calculation when -PI <= x <= PI. */ +static vg_lite_float_t _Cos( + vg_lite_float_t X +) +{ + vg_lite_float_t x2 = X * X; + vg_lite_float_t x = x2; + vg_lite_float_t s = 1.0f; + + s -= x * 0.49985163079668843f; + x *= x2; + s += x * 0.041518066216932693f; + x *= x2; + s -= x * 0.0013422997970712939f; + x *= x2; + s += x * 0.000018930111278021357f; + + return s; +} + +/* Special sin(x) for quick calculation when -PI <= x <= PI. */ +static vg_lite_float_t _Sine( + vg_lite_float_t X +) +{ + vg_lite_float_t x = X; + vg_lite_float_t x2 = X * X; + vg_lite_float_t s = X; + + x *= x2; + s -= x * 0.16664527099620879f; + x *= x2; + s += x * 0.0083154803736487041f; + x *= x2; + s -= x * 0.00019344151251408578f; + x *= x2; + s += x * 0.0000021810214160988925f; + + return s; +} + +static vg_lite_float_t +_Angle( + vg_lite_float_t X, + vg_lite_float_t Y, + vg_lite_float_t Length +) +{ + vg_lite_float_t angle; + vg_lite_float_t ux = (X >= 0.0f ? X : -X); + vg_lite_float_t uy = (Y >= 0.0f ? Y : -Y); + + if(ux > uy) { + angle = ((uy > 0.0f && ux < Length) ? _Asin(uy / Length) : 0.0f); + } + else { + angle = ((ux > 0.0f && uy < Length) ? (FLOAT_PI_HALF - _Asin(ux / Length)) : FLOAT_PI_HALF); + } + + if(X < 0.0f) angle = FLOAT_PI - angle; + if(Y < 0.0f) angle = -angle; + + return angle; +} + +/* The arc is always counter clockwise and less than half circle (small). */ +static vg_lite_error_t +_convert_circle_arc( + vg_lite_stroke_t * stroke_conversion, + vg_lite_float_t Radius, + vg_lite_float_t CenterX, + vg_lite_float_t CenterY, + vg_lite_float_t StartX, + vg_lite_float_t StartY, + vg_lite_float_t EndX, + vg_lite_float_t EndY, + uint8_t Half_circle, + vg_lite_path_point_ptr * point_list +) +{ + vg_lite_error_t error = VG_LITE_SUCCESS; + /*gceVGCMD segmentCommand;*/ + vg_lite_float_t theta1, theta_span; + uint32_t segs; + vg_lite_float_t theta, theta_half, theta2; + vg_lite_float_t cos_theta_half; + vg_lite_float_t control_ratio; + vg_lite_float_t controlX, controlY, anchorX, anchorY; + /*gctFLOAT lastX, lastY;*/ + vg_lite_path_point_ptr point, start_point, last_point; + + if(!stroke_conversion || !point_list) + return VG_LITE_INVALID_ARGUMENT; + + /* Converting. */ + theta1 = _Angle(StartX - CenterX, StartY - CenterY, Radius); + if(Half_circle) { + theta_span = FLOAT_PI; + segs = 4; + theta = FLOAT_PI_QUARTER; + theta_half = FLOAT_PI_EIGHTH; + cos_theta_half = FLOAT_COS_PI_EIGHTH; + } + else { + theta_span = _Angle(EndX - CenterX, EndY - CenterY, Radius) - theta1; + if(theta_span == 0.0f) { + /* Handle specail case for huge scaling. */ + *point_list = NULL; + error = VG_LITE_SUCCESS; + return error; + } + + if((theta_span < 0)) { + theta_span += FLOAT_PI_TWO; + } + + /* Calculate the number of quadratic Bezier curves. */ + /* Assumption: most of angles are small angles. */ + if(theta_span <= FLOAT_PI_QUARTER) segs = 1; + else if(theta_span <= FLOAT_PI_HALF) segs = 2; + else if(theta_span <= FLOAT_PI_THREE_QUARTER) segs = 3; + else segs = 4; + + theta = theta_span / segs; + theta_half = theta / 2.0f; + cos_theta_half = _Cos(theta_half); + } + + /* Determine the segment command. */ + /*egmentCommand = gcvVGCMD_ARC_QUAD;*/ + + /* Generate quadratic Bezier curves. */ + start_point = last_point = NULL; + control_ratio = Radius / cos_theta_half; + while(segs-- > 0) { + theta1 += theta; + + theta2 = theta1 - theta_half; + if(theta2 > FLOAT_PI) theta2 -= FLOAT_PI_TWO; + controlX = CenterX + _Cos(theta2) * control_ratio; + controlY = CenterY + _Sine(theta2) * control_ratio; + + theta2 = theta1; + if(theta2 > FLOAT_PI) theta2 -= FLOAT_PI_TWO; + anchorX = CenterX + _Cos(theta2) * Radius; + anchorY = CenterY + _Sine(theta2) * Radius; + + if(segs == 0) { + /* Use end point directly to avoid accumulated errors. */ + anchorX = EndX; + anchorY = EndY; + } + + /* Add control point. */ + point = (vg_lite_path_point_ptr)vg_lite_os_malloc(sizeof(*point)); + if(!point) + return VG_LITE_OUT_OF_RESOURCES; + + memset(point, 0, sizeof(*point)); + + point->x = controlX; + point->y = controlY; + point->curve_type = CURVE_QUAD_CONTROL; + if(last_point) { + last_point->next = point; + last_point = point; + } + else { + start_point = last_point = point; + } + + /* Add anchor point. */ + point = (vg_lite_path_point_ptr)vg_lite_os_malloc(sizeof(*point)); + if(!point) { + error = VG_LITE_OUT_OF_RESOURCES; + goto ErrorHandler; + } + + memset(point, 0, sizeof(*point)); + + point->x = anchorX; + point->y = anchorY; + point->curve_type = CURVE_QUAD_ANCHOR; + last_point->next = point; + last_point = point; + } + + if(last_point) { + last_point->next = NULL; + } + *point_list = start_point; + + return error; + +ErrorHandler: + /* Return status. */ + if(start_point) { + vg_lite_os_free(start_point); + start_point = last_point = NULL; + } + return error; +} + +static vg_lite_error_t +_start_new_stroke_sub_path( + vg_lite_stroke_t * stroke_conversion, + vg_lite_float_t X, + vg_lite_float_t Y, + vg_lite_float_t Dx, + vg_lite_float_t Dy, + uint8_t add_end_cap, + vg_lite_sub_path_ptr * stroke_subpath +) +{ + vg_lite_error_t error = VG_LITE_SUCCESS; + + vg_lite_sub_path_ptr stroke_sub_path; + vg_lite_path_point_ptr new_point; + + if(!stroke_conversion || !stroke_subpath) + return VG_LITE_INVALID_ARGUMENT; + + VG_LITE_ERROR_HANDLER(_add_stroke_sub_path(stroke_conversion, &stroke_sub_path)); + + new_point = (vg_lite_path_point_ptr)vg_lite_os_malloc(sizeof(*new_point)); + if(!new_point) + return VG_LITE_OUT_OF_RESOURCES; + + memset(new_point, 0, sizeof(*new_point)); + new_point->x = X + Dx; + new_point->y = Y + Dy; + new_point->prev = NULL; + new_point->curve_type = CURVE_LINE; + stroke_conversion->stroke_points = stroke_conversion->right_point = new_point; + + stroke_sub_path->point_list = stroke_conversion->right_point = new_point; + + new_point = (vg_lite_path_point_ptr)vg_lite_os_malloc(sizeof(*new_point)); + if(!new_point) + return VG_LITE_OUT_OF_RESOURCES; + + memset(new_point, 0, sizeof(*new_point)); + new_point->x = X - Dx; + new_point->y = Y - Dy; + new_point->curve_type = CURVE_LINE; + new_point->next = NULL; + stroke_conversion->stroke_end = stroke_conversion->left_point = new_point; + + stroke_conversion->stroke_count = 2; + + stroke_sub_path->end_point = stroke_conversion->left_point = new_point; + stroke_sub_path->point_count = 2; + + if(add_end_cap) { + /* Add end cap if the subPath is not closed. */ + switch(stroke_conversion->cap_style) { + case VG_LITE_CAP_BUTT: + /* No adjustment needed. */ + break; + case VG_LITE_CAP_ROUND: + /* Add curve. */ + /* Add the starting point again as arc. */ + VG_LITE_ERROR_HANDLER(_add_point_to_right_stroke_point_list_tail(stroke_conversion, + stroke_sub_path->point_list->x, stroke_sub_path->point_list->y)); + stroke_conversion->right_point->curve_type = CURVE_ARC_SCCW_HALF; + stroke_conversion->right_point->tangentX = X; + stroke_conversion->right_point->tangentY = Y; + /* Change the starting point to end point. */ + stroke_sub_path->point_list->x = stroke_sub_path->end_point->x; + stroke_sub_path->point_list->y = stroke_sub_path->end_point->y; + break; + case VG_LITE_CAP_SQUARE: + stroke_conversion->right_point->x += Dy; + stroke_conversion->right_point->y -= Dx; + stroke_conversion->left_point->x += Dy; + stroke_conversion->left_point->y -= Dx; + break; + } + } + + *stroke_subpath = stroke_sub_path; + +ErrorHandler: + return error; +} + +static void +_adjust_joint_point( + vg_lite_path_point_ptr Point, + vg_lite_path_point_ptr join_point, + vg_lite_float_t X, + vg_lite_float_t Y, + vg_lite_float_t Ratio +) +{ + vg_lite_float_t mx = (join_point->x + X) / 2.0f; + vg_lite_float_t my = (join_point->y + Y) / 2.0f; + vg_lite_float_t dx = mx - Point->x; + vg_lite_float_t dy = my - Point->y; + + dx = dx * Ratio; + dy = dy * Ratio; + join_point->x = Point->x + dx; + join_point->y = Point->y + dy; +} + +static uint8_t +_is_angle_span_acute( + vg_lite_float_t Ux, + vg_lite_float_t Uy, + vg_lite_float_t Vx, + vg_lite_float_t Vy +) +{ + return ((Ux * Vx + Uy * Vy) > 0.0f ? 1 : 0); +} + +static vg_lite_error_t +_draw_swing_pie_area( + vg_lite_stroke_t * stroke_conversion, + vg_lite_path_point_ptr center_point, + uint8_t end_at_prev_point +) +{ + vg_lite_error_t error = VG_LITE_SUCCESS; + + if(!stroke_conversion) + return VG_LITE_INVALID_ARGUMENT; + + if(stroke_conversion->swing_ccw) { + vg_lite_path_point_ptr start_point = stroke_conversion->swing_stroke; + vg_lite_path_point_ptr end_point = NULL, real_end_point = NULL; + vg_lite_path_point_ptr point, prev_point; + uint32_t count = 0; + + { + if(end_at_prev_point) { + /* Detach the end point from leftStrokePoint. */ + /* The end point will be added back later. */ + real_end_point = stroke_conversion->left_point; + stroke_conversion->left_point = real_end_point->next; + stroke_conversion->left_point->prev = NULL; + } + + VG_LITE_ERROR_HANDLER(_add_point_to_left_point_list_head(stroke_conversion, + center_point->x, center_point->y)); + end_point = stroke_conversion->left_point; + + /* Reverse the point list from startPoint to endPoint. */ + for(point = start_point; point; point = prev_point) { + prev_point = point->prev; + point->prev = point->next; + point->next = prev_point; + count++; + } + + if(end_point) { + end_point->next = start_point->prev; + } + start_point->prev->prev = end_point; + start_point->prev = NULL; + stroke_conversion->left_point = start_point; + + VG_LITE_ERROR_HANDLER(_add_point_to_left_point_list_head(stroke_conversion, + center_point->x, center_point->y)); + VG_LITE_ERROR_HANDLER(_add_point_to_left_point_list_head(stroke_conversion, + stroke_conversion->swing_start->x, + stroke_conversion->swing_start->y)); + VG_LITE_ERROR_HANDLER(_add_point_to_left_point_list_head(stroke_conversion, + end_point->prev->x, end_point->prev->y)); + + if(end_at_prev_point) { + if(real_end_point) { + real_end_point->next = stroke_conversion->left_point; + } + stroke_conversion->left_point->prev = real_end_point; + stroke_conversion->left_point = real_end_point; + } + } + } + else { + vg_lite_path_point_ptr start_point = stroke_conversion->swing_stroke; + vg_lite_path_point_ptr end_point = NULL, real_end_point = NULL; + vg_lite_path_point_ptr point, next_point; + uint32_t count = 0; + + { + if(end_at_prev_point) { + /* Detach the end point from leftStrokePoint. */ + /* The end point will be added back later. */ + real_end_point = stroke_conversion->right_point; + stroke_conversion->right_point = real_end_point->prev; + stroke_conversion->right_point->next = NULL; + } + + VG_LITE_ERROR_HANDLER(_add_point_to_right_stroke_point_list_tail(stroke_conversion, + center_point->x, center_point->y)); + end_point = stroke_conversion->right_point; + + /* Reverse the point list from startPoint to endPoint. */ + for(point = start_point; point; point = next_point) { + next_point = point->next; + point->next = point->prev; + point->prev = next_point; + count++; + } + end_point->prev = start_point->next; + start_point->next->next = end_point; + start_point->next = NULL; + stroke_conversion->right_point = start_point; + + VG_LITE_ERROR_HANDLER(_add_point_to_right_stroke_point_list_tail(stroke_conversion, + center_point->x, center_point->y)); + VG_LITE_ERROR_HANDLER(_add_point_to_right_stroke_point_list_tail(stroke_conversion, + stroke_conversion->swing_start->x, + stroke_conversion->swing_start->y)); + VG_LITE_ERROR_HANDLER(_add_point_to_right_stroke_point_list_tail(stroke_conversion, + end_point->next->x, end_point->next->y)); + + if(end_at_prev_point) { + real_end_point->prev = stroke_conversion->right_point; + stroke_conversion->right_point->next = real_end_point; + stroke_conversion->right_point = real_end_point; + } + } + } + + stroke_conversion->swing_handling = SWING_NO; + +ErrorHandler: + return error; +} + +static vg_lite_error_t +_process_line_joint( + vg_lite_stroke_t * stroke_conversion, + vg_lite_path_point_ptr Point, + vg_lite_float_t Length, + vg_lite_float_t prev_length, + uint32_t Swing_handling, + vg_lite_float_t X1, + vg_lite_float_t Y1, + vg_lite_float_t X2, + vg_lite_float_t Y2 +) +{ + vg_lite_error_t error = VG_LITE_SUCCESS; + vg_lite_join_style_t join_style; + vg_lite_float_t half_width; + vg_lite_float_t ratio; + vg_lite_float_t min_length_square; + vg_lite_float_t cos_theta; + uint8_t counter_clockwise; + uint8_t fat_line; + uint32_t swing_handling = SWING_NO; + uint8_t handle_short_line = 0; + + if(!stroke_conversion) + return VG_LITE_INVALID_ARGUMENT; + + join_style = stroke_conversion->join_style; + half_width = stroke_conversion->half_width; + fat_line = stroke_conversion->fattened; + if(stroke_conversion->swing_length < half_width) { + if(stroke_conversion->need_swing) { + swing_handling = SWING_OUT; + } + else { + handle_short_line = 1; + } + } + else if(stroke_conversion->stroke_length - stroke_conversion->swing_length < half_width) { + if(stroke_conversion->need_swing) { + swing_handling = SWING_IN; + } + else { + handle_short_line = 1; + } + } + + if(swing_handling != Swing_handling) { + error = VG_LITE_INVALID_ARGUMENT; + goto ErrorHandler; + } + + /* For flattened curves/arcs, the join style is always round. */ + if((Point->flatten_flag != vgcFLATTEN_NO) && fat_line) { + join_style = VG_LITE_JOIN_ROUND; + } + + /* First, determine the turn is clockwise or counter-clockwise. */ + cos_theta = Point->prev->tangentX * Point->tangentX + Point->prev->tangentY * Point->tangentY; + + if(cos_theta > FLOAT_ANGLE_EPSILON_COS) { + /* Straight line or semi-straight line--no need to handle join. */ + if(stroke_conversion->swing_handling != SWING_NO) { + /* Begin to swing to the opposite direction. */ + /* Draw the swing area (pie area). */ + VG_LITE_ERROR_HANDLER(_draw_swing_pie_area(stroke_conversion, Point->prev, 1)); + } + + /* Add the new stroke points. */ + VG_LITE_ERROR_HANDLER(_add_point_to_right_stroke_point_list_tail(stroke_conversion, X1, Y1)); + VG_LITE_ERROR_HANDLER(_add_point_to_left_point_list_head(stroke_conversion, X2, Y2)); + if(stroke_conversion->swing_handling != SWING_NO) { + stroke_conversion->swing_count++; + } + + goto endCheck; + } + else if(cos_theta < -FLOAT_ANGLE_EPSILON_COS) { + /* Almost 180 degree turn. */ + counter_clockwise = 1; + ratio = FLOAT_MAX; + min_length_square = FLOAT_MAX; + } + else { + vg_lite_float_t angleSign = Point->prev->tangentX * Point->tangentY - Point->prev->tangentY * Point->tangentX; + counter_clockwise = (angleSign >= 0.0f ? 1 : 0); + ratio = 2.0f / (1.0f + cos_theta); + min_length_square = half_width * half_width * (1.0f - cos_theta) / (1.0f + cos_theta) + 0.02f; + } + + if(stroke_conversion->swing_handling != SWING_NO) { + if(counter_clockwise != stroke_conversion->swing_ccw) { + /* Swing to the opposite direction. */ + /* Draw the swing area (pie area). */ + VG_LITE_ERROR_HANDLER(_draw_swing_pie_area(stroke_conversion, Point->prev, 1)); + } + } + + if(counter_clockwise) { + if(stroke_conversion->swing_handling != SWING_NO) { + vg_lite_path_point_ptr prev_point = stroke_conversion->left_point->next; /* Skip the line segment movement. */ + vg_lite_float_t deltaX = X2 - prev_point->x; + vg_lite_float_t deltaY = Y2 - prev_point->y; + if(_is_angle_span_acute(stroke_conversion->swing_deltax, + stroke_conversion->swing_deltay, + deltaX, deltaY)) { + /* Continue swinging. */ + stroke_conversion->swing_deltax = deltaX; + stroke_conversion->swing_deltay = deltaY; + } + else { + /* Swing to the max. */ + /* Draw the swing area (pie area). */ + VG_LITE_ERROR_HANDLER(_draw_swing_pie_area(stroke_conversion, Point->prev, 1)); + } + } + + /* Check if the miter length is too long for inner intersection. */ + if(stroke_conversion->swing_handling == SWING_NO + && ! handle_short_line + && min_length_square <= Length * Length + && min_length_square <= prev_length * prev_length) { + /* Adjust leftStrokePoint to the intersection point. */ + _adjust_joint_point(Point, stroke_conversion->left_point, X2, Y2, ratio); + } + else if(stroke_conversion->swing_handling == SWING_NO && Point->flatten_flag == vgcFLATTEN_NO) { + /* Add the point to avoid incorrect sharp angle. */ + VG_LITE_ERROR_HANDLER(_add_point_to_left_point_list_head(stroke_conversion, Point->x, Point->y)); + /* Add the point to form a loop to avoid out-of-bound problem. */ + VG_LITE_ERROR_HANDLER(_add_point_to_left_point_list_head(stroke_conversion, X2, Y2)); + } + else if(stroke_conversion->swing_handling == SWING_NO && (! fat_line || Swing_handling == SWING_NO)) { + /* Flattened line segments should not have sharp angle. */ + /* Add the point to form a loop to avoid out-of-bound problem. */ + VG_LITE_ERROR_HANDLER(_add_point_to_left_point_list_head(stroke_conversion, X2, Y2)); + } + else { + if(stroke_conversion->swing_handling == SWING_NO) { + vg_lite_path_point_ptr prev_point = stroke_conversion->left_point; + + /* Start swing handling. */ + stroke_conversion->swing_handling = Swing_handling; + stroke_conversion->swing_ccw = 1; + stroke_conversion->swing_start = Point; + stroke_conversion->swing_centlen = 0.0f; + stroke_conversion->swing_count = 0; + + /* Save stroking path delta. */ + stroke_conversion->swing_deltax = X2 - prev_point->x; + stroke_conversion->swing_deltay = Y2 - prev_point->y; + + /* Add extra center point for swing out pie area. */ + /* VIV: [todo] Should adjust prev_point, instead of adding new point? */ + VG_LITE_ERROR_HANDLER(_add_point_to_left_point_list_head(stroke_conversion, Point->x, Point->y)); + + /* Add extra start stroke point for swing out pie area. */ + VG_LITE_ERROR_HANDLER(_add_point_to_left_point_list_head(stroke_conversion, prev_point->x, prev_point->y)); + + stroke_conversion->swing_stroke = stroke_conversion->left_point; + } + + /* Add curve. */ + /* Note that the curve will be reversed, so the direction is CW. */ + /* Then, left side is in reversed order, so the direction is CCW. */ + VG_LITE_ERROR_HANDLER(_add_point_to_left_point_list_head(stroke_conversion, X2, Y2)); + stroke_conversion->left_point->curve_type = CURVE_ARC_SCCW; + stroke_conversion->left_point->tangentX = Point->x; + stroke_conversion->left_point->tangentY = Point->y; + + stroke_conversion->swing_count++; + } + + switch(join_style) { + case VG_LITE_JOIN_ROUND: + if(cos_theta > FLOAT_MIN_ARC_ANGLE_COS) { + /* Add a point. */ + VG_LITE_ERROR_HANDLER(_add_point_to_right_stroke_point_list_tail(stroke_conversion, X1, Y1)); + } + else { + /* Add curve. */ + VG_LITE_ERROR_HANDLER(_add_point_to_right_stroke_point_list_tail(stroke_conversion, X1, Y1)); + stroke_conversion->right_point->curve_type = CURVE_ARC_SCCW; + stroke_conversion->right_point->tangentX = Point->x; + stroke_conversion->right_point->tangentY = Point->y; + } + break; + case VG_LITE_JOIN_MITER: + if(ratio <= stroke_conversion->miter_square) { + /* Adjust lastRightStrokePoint to the outer intersection point. */ + _adjust_joint_point(Point, stroke_conversion->right_point, X1, Y1, ratio); + break; + } + /* Else use Bevel join style. */ + case VG_LITE_JOIN_BEVEL: + VG_LITE_ERROR_HANDLER(_add_point_to_right_stroke_point_list_tail(stroke_conversion, X1, Y1)); + break; + } + } + else { + if(stroke_conversion->swing_handling != SWING_NO) { + vg_lite_path_point_ptr prev_point = stroke_conversion->right_point->prev; /* Skip the line segment movement. */ + vg_lite_float_t deltaX = X1 - prev_point->x; + vg_lite_float_t deltaY = Y1 - prev_point->y; + if(_is_angle_span_acute(stroke_conversion->swing_deltax, + stroke_conversion->swing_deltay, + deltaX, deltaY)) { + /* Continue swinging. */ + stroke_conversion->swing_deltax = deltaX; + stroke_conversion->swing_deltay = deltaY; + } + else { + /* Swing to the max. */ + /* Draw the swing area (pie area). */ + VG_LITE_ERROR_HANDLER(_draw_swing_pie_area(stroke_conversion, Point->prev, 1)); + } + } + + /* Check if the miter length is too long for inner intersection. */ + if(stroke_conversion->swing_handling == SWING_NO + && ! handle_short_line + && min_length_square <= Length * Length + && min_length_square <= prev_length * prev_length) { + /* Adjust lastRightStrokePoint to the intersection point. */ + _adjust_joint_point(Point, stroke_conversion->right_point, X1, Y1, ratio); + } + else if(stroke_conversion->swing_handling == SWING_NO && Point->flatten_flag == vgcFLATTEN_NO) { + /* Add the point to avoid incorrect sharp angle. */ + VG_LITE_ERROR_HANDLER(_add_point_to_right_stroke_point_list_tail(stroke_conversion, Point->x, Point->y)); + /* Add the point to form a loop to avoid out-of-bound problem. */ + VG_LITE_ERROR_HANDLER(_add_point_to_right_stroke_point_list_tail(stroke_conversion, X1, Y1)); + } + else if(stroke_conversion->swing_handling == SWING_NO && (! fat_line || Swing_handling == SWING_NO)) { + /* Flattened line segments should not have sharp angle. */ + /* Add the point to form a loop to avoid out-of-bound problem. */ + VG_LITE_ERROR_HANDLER(_add_point_to_right_stroke_point_list_tail(stroke_conversion, X1, Y1)); + } + else { + if(stroke_conversion->swing_handling == SWING_NO) { + vg_lite_path_point_ptr prev_point = stroke_conversion->right_point; + + /* Start swing handling. */ + stroke_conversion->swing_handling = Swing_handling; + stroke_conversion->swing_ccw = 0; + stroke_conversion->swing_start = Point; + stroke_conversion->swing_centlen = 0.0f; + stroke_conversion->swing_count = 0; + + /* Save stroking path delta. */ + stroke_conversion->swing_deltax = X1 - prev_point->x; + stroke_conversion->swing_deltay = Y1 - prev_point->y; + + /* Add extra center point for swing out pie area. */ + /* VIV: [todo] Should adjust prev_point, instead of adding new point? */ + VG_LITE_ERROR_HANDLER(_add_point_to_right_stroke_point_list_tail(stroke_conversion, Point->x, Point->y)); + + /* Add extra start stroke point for swing out pie area. */ + VG_LITE_ERROR_HANDLER(_add_point_to_right_stroke_point_list_tail(stroke_conversion, prev_point->x, prev_point->y)); + + stroke_conversion->swing_stroke = stroke_conversion->right_point; + } + + if(cos_theta > FLOAT_MIN_ARC_ANGLE_COS) { + /* Add a point. */ + VG_LITE_ERROR_HANDLER(_add_point_to_right_stroke_point_list_tail(stroke_conversion, X1, Y1)); + } + else { + /* Add curve. */ + /* Note that the curve will be reversed, so the direction is CCW. */ + stroke_conversion->right_point->curve_type = CURVE_ARC_SCCW; + stroke_conversion->right_point->tangentX = Point->x; + stroke_conversion->right_point->tangentY = Point->y; + VG_LITE_ERROR_HANDLER(_add_point_to_right_stroke_point_list_tail(stroke_conversion, X1, Y1)); + } + stroke_conversion->swing_count++; + } + + switch(join_style) { + case VG_LITE_JOIN_ROUND: + if(cos_theta > FLOAT_MIN_ARC_ANGLE_COS) { + /* Add a point. */ + VG_LITE_ERROR_HANDLER(_add_point_to_left_point_list_head(stroke_conversion, X2, Y2)); + } + else { + /* Add curve. */ + stroke_conversion->left_point->curve_type = CURVE_ARC_SCCW; + stroke_conversion->left_point->tangentX = Point->x; + stroke_conversion->left_point->tangentY = Point->y; + VG_LITE_ERROR_HANDLER(_add_point_to_left_point_list_head(stroke_conversion, X2, Y2)); + } + break; + case VG_LITE_JOIN_MITER: + if(ratio <= stroke_conversion->miter_square) { + /* Adjust leftStrokePoint to the outer intersection point. */ + _adjust_joint_point(Point, stroke_conversion->left_point, X2, Y2, ratio); + break; + } + /* Else use Bevel join style. */ + case VG_LITE_JOIN_BEVEL: + VG_LITE_ERROR_HANDLER(_add_point_to_left_point_list_head(stroke_conversion, X2, Y2)); + break; + } + } + +endCheck: + if(stroke_conversion->need_swing) { + stroke_conversion->swing_length += Point->length; + } + if(stroke_conversion->swing_handling != SWING_NO) { + if(Point->flatten_flag == vgcFLATTEN_END || + (stroke_conversion->swing_handling == SWING_OUT && + stroke_conversion->swing_length > half_width)) { + /* Draw the swing area (pie area). */ + VG_LITE_ERROR_HANDLER(_draw_swing_pie_area(stroke_conversion, Point, 0)); + } + else { + /* Check if center line will move too far. */ + stroke_conversion->swing_centlen += Point->length; + if(stroke_conversion->swing_centlen > FLOAT_SWING_CENTER_RANGE) { + /* Draw the swing area (pie area). */ + VG_LITE_ERROR_HANDLER(_draw_swing_pie_area(stroke_conversion, Point, 0)); + } + } + } + +ErrorHandler: + return error; +} + +static vg_lite_error_t +_close_stroke_sub_path( + vg_lite_stroke_t * stroke_conversion, + vg_lite_path_point_ptr Point, + vg_lite_float_t Length, + vg_lite_float_t prev_length, + uint8_t Swing_handling, + vg_lite_path_point_ptr first_stroke_point, + vg_lite_path_point_ptr last_stroke_point +) +{ + vg_lite_error_t error = VG_LITE_SUCCESS; + if(!stroke_conversion) + return VG_LITE_INVALID_ARGUMENT; + + /* Handle line joint style for the first/last point in closed path. */ + VG_LITE_ERROR_HANDLER(_process_line_joint( + stroke_conversion, Point, + Length, prev_length, Swing_handling, + first_stroke_point->x, first_stroke_point->y, + last_stroke_point->x, last_stroke_point->y + )); + + if(stroke_conversion->cap_style == VG_LITE_CAP_SQUARE + && stroke_conversion->join_style == VG_LITE_JOIN_MITER + && stroke_conversion->pattern_count > 0) { + stroke_conversion->left_point->x = last_stroke_point->x; + stroke_conversion->left_point->y = last_stroke_point->y; + } + + /* Adjust the two end ponts of the first point. */ + first_stroke_point->x = stroke_conversion->right_point->x; + first_stroke_point->y = stroke_conversion->right_point->y; + last_stroke_point->x = stroke_conversion->left_point->x; + last_stroke_point->y = stroke_conversion->left_point->y; + + /* Concatnate right and left point lists. */ + stroke_conversion->right_point->next = stroke_conversion->left_point; + stroke_conversion->left_point->prev = stroke_conversion->right_point; + + /*gcmERROR_RETURN(_CheckStrokeSubPath(stroke_conversion->lastStrokeSubPath));*/ + +ErrorHandler: + return error; +} + +static vg_lite_error_t _end_stroke_sub_path( + vg_lite_stroke_t * stroke_conversion, + vg_lite_float_t X, + vg_lite_float_t Y, + vg_lite_float_t Dx, + vg_lite_float_t Dy +) +{ + vg_lite_error_t error = VG_LITE_SUCCESS; + + if(!stroke_conversion) + return VG_LITE_INVALID_ARGUMENT; + + /* Add points for end of line. */ + VG_LITE_RETURN_ERROR(_add_point_to_right_stroke_point_list_tail(stroke_conversion, X + Dx, Y + Dy)); + VG_LITE_RETURN_ERROR(_add_point_to_left_point_list_head(stroke_conversion, X - Dx, Y - Dy)); + + /* Add end cap if the subPath is not closed. */ + switch(stroke_conversion->cap_style) { + case VG_LITE_CAP_BUTT: + /* No adjustment needed. */ + break; + case VG_LITE_CAP_ROUND: + /* Add curve. */ + stroke_conversion->left_point->curve_type = CURVE_ARC_SCCW_HALF; + stroke_conversion->left_point->tangentX = X; + stroke_conversion->left_point->tangentY = Y; + break; + case VG_LITE_CAP_SQUARE: + stroke_conversion->right_point->x -= Dy; + stroke_conversion->right_point->y += Dx; + stroke_conversion->left_point->x -= Dy; + stroke_conversion->left_point->y += Dx; + break; + } + + /* Concatnate right and left point lists. */ + stroke_conversion->right_point->next = stroke_conversion->left_point; + stroke_conversion->left_point->prev = stroke_conversion->right_point; + + /*gcmERROR_RETURN(_CheckStrokeSubPath(stroke_conversion->lastStrokeSubPath));*/ + return error; +} + +static vg_lite_error_t _get_next_dash_length( + vg_lite_stroke_t * stroke_conversion, + uint32_t * dash_index, + vg_lite_float_t * dash_length +) +{ + if(!stroke_conversion || !dash_index || !dash_length) + return VG_LITE_INVALID_ARGUMENT; + + (*dash_index)++; + if(*dash_index == stroke_conversion->pattern_count) { + *dash_index = 0; + } + *dash_length = stroke_conversion->dash_pattern[*dash_index]; + + return VG_LITE_SUCCESS; +} + +static vg_lite_error_t +_create_stroke_path( + vg_lite_stroke_t * stroke_conversion +) +{ + vg_lite_error_t error = VG_LITE_SUCCESS; + vg_lite_sub_path_ptr stroke_sub_path = NULL, first_stroke_sub_path = NULL; + vg_lite_path_point_ptr point, next_point; + vg_lite_float_t half_width; + vg_lite_float_t x, y; + vg_lite_float_t dx, dy, ux, uy; + vg_lite_float_t length, prev_length, first_length; + vg_lite_float_t dash_length; + uint32_t dash_index; + uint8_t dashing; + uint8_t add_end_cap; + uint8_t need_to_handle_swing = 1 /* (stroke_conversion->strokeCapStyle == gcvCAP_BUTT) */; + vg_lite_uint8_t dash_phase_reset; + + vg_lite_path_point_ptr first_right_point = NULL; + vg_lite_path_point_ptr last_left_point = NULL; + vg_lite_float_t first_dx = 0.0f, first_dy = 0.0f; + uint8_t drawing = 0; + vg_lite_float_t total_length = 0.0f; + vg_lite_float_t accu_length = 0.0f; + uint32_t swing_handling = SWING_NO; + + if(!stroke_conversion) + return VG_LITE_INVALID_ARGUMENT; + + half_width = stroke_conversion->half_width; + dashing = stroke_conversion->pattern_count > 0 ? 1 : 0; + dash_index = stroke_conversion->dash_index; + dash_length = stroke_conversion->dash_length; + dash_phase_reset = stroke_conversion->dash_reset; + + /* VIV: [todo] Need to check/debug closed stroke path. */ + need_to_handle_swing = (stroke_conversion->cap_style == VG_LITE_CAP_BUTT || stroke_conversion->closed); + if(need_to_handle_swing) { + uint8_t reallyneed_to_handle_swing = 0; + + /* Calculate the total length. */ + for(point = stroke_conversion->path_points; point; point = point->next) { + total_length += point->length; + + if(point->flatten_flag != vgcFLATTEN_NO) { + reallyneed_to_handle_swing = 1; + } + } + stroke_conversion->stroke_length = total_length; + if(reallyneed_to_handle_swing) { + swing_handling = SWING_OUT; + } + else { + need_to_handle_swing = 0; + swing_handling = SWING_NO; + } + } + stroke_conversion->need_swing = need_to_handle_swing; + + point = stroke_conversion->path_points; + next_point = point->next; + if(next_point == NULL) { + if(!dashing || ((dash_index & 0x1) == 0)) { + /* Single point (zero-length) subpath. */ + /* Note that one-MOVE_TO subpaths are removed during parsing. */ + VG_LITE_ERROR_HANDLER(_add_zero_length_stroke_sub_path(stroke_conversion, &stroke_sub_path)); + } + goto ErrorHandler; + } + + /* Adjust closed status for dashing. */ + if(dashing && stroke_conversion->closed && ((dash_index & 0x1) == 1)) { + stroke_conversion->closed = VGL_FALSE; + } + + /* Set add_end_cap. */ + add_end_cap = dashing ? 1 : (stroke_conversion->closed ? 0 : 1); + + /* Process first line. */ + first_length = point->length; + ux = point->tangentX; + uy = point->tangentY; + dx = uy * half_width; + dy = -ux * half_width; + if(need_to_handle_swing) { + stroke_conversion->swing_length = first_length; + } + + if(dashing) { + vg_lite_float_t delta_length; + + /* Draw dashes. */ + x = point->x; + y = point->y; + do { + if((dash_index & 0x1) == 0) { + VG_LITE_ERROR_HANDLER(_start_new_stroke_sub_path( + stroke_conversion, + x, y, + dx, dy, add_end_cap, + &stroke_sub_path + )); + + drawing = 1; + add_end_cap = 1; + if(stroke_conversion->closed && (first_stroke_sub_path == NULL)) { + first_stroke_sub_path = stroke_conversion->last_stroke; + first_right_point = stroke_conversion->right_point; + last_left_point = stroke_conversion->left_point; + first_dx = dx; + first_dy = dy; + } + } + + delta_length = first_length - dash_length; + if(delta_length >= FLOAT_EPSILON) { + /* Move (x, y) forward along the line by dash_length. */ + x += ux * dash_length; + y += uy * dash_length; + + if((dash_index & 0x1) == 0) { + VG_LITE_ERROR_HANDLER(_end_stroke_sub_path( + stroke_conversion, + x, y, + dx, dy + )); + + drawing = 0; + } + + VG_LITE_ERROR_HANDLER(_get_next_dash_length(stroke_conversion, &dash_index, &dash_length)); + first_length = delta_length; + } + else if(delta_length <= -FLOAT_EPSILON) { + dash_length = -delta_length; + break; + } + else { + if((dash_index & 0x1) == 0) { + VG_LITE_ERROR_HANDLER(_end_stroke_sub_path( + stroke_conversion, + next_point->x, next_point->y, + dx, dy + )); + + drawing = 0; + } + + VG_LITE_ERROR_HANDLER(_get_next_dash_length(stroke_conversion, &dash_index, &dash_length)); + first_length = 0; + break; + } + } while(1); + } + else { + VG_LITE_ERROR_HANDLER(_start_new_stroke_sub_path( + stroke_conversion, + point->x, point->y, + dx, dy, add_end_cap, + &stroke_sub_path + )); + + drawing = 1; + add_end_cap = 1; + } + + /* Process the rest of lines. */ + prev_length = first_length; + for(point = next_point, next_point = point->next; next_point; + point = next_point, next_point = point->next) { + if(!dashing || ((dash_index & 0x1) == 0 && drawing)) { + /* Add points for end of line for line join process with next line. */ + VG_LITE_ERROR_HANDLER(_add_point_to_right_stroke_point_list_tail(stroke_conversion, + point->x + dx, point->y + dy)); + VG_LITE_ERROR_HANDLER(_add_point_to_left_point_list_head(stroke_conversion, + point->x - dx, point->y - dy)); + } + + length = point->length; + ux = point->tangentX; + uy = point->tangentY; + dx = uy * half_width; + dy = -ux * half_width; + if(need_to_handle_swing) { + accu_length += point->prev->length; + stroke_conversion->swing_length = accu_length; + if(accu_length < half_width) { + swing_handling = SWING_OUT; + } + else if(total_length - accu_length < half_width) { + swing_handling = SWING_IN; + } + else { + swing_handling = SWING_NO; + } + } + + if(!dashing) { + /* Handle line joint style. */ + VG_LITE_ERROR_HANDLER(_process_line_joint( + stroke_conversion, point, + length, prev_length, swing_handling, + point->x + dx, point->y + dy, + point->x - dx, point->y - dy + )); + } + else { + vg_lite_float_t delta_length; + + /* Draw dashes. */ + x = point->x; + y = point->y; + if((dash_index & 0x1) == 0) { + if(drawing) { + /* Handle line joint style. */ + VG_LITE_ERROR_HANDLER(_process_line_joint( + stroke_conversion, point, + dash_length, prev_length, swing_handling, + x + dx, y + dy, + x - dx, y - dy + )); + } + else { + /* Start a new sub path. */ + VG_LITE_ERROR_HANDLER(_start_new_stroke_sub_path( + stroke_conversion, + x, y, + dx, dy, add_end_cap, + &stroke_sub_path + )); + + drawing = 1; + add_end_cap = 1; + } + } + do { + delta_length = length - dash_length; + if(delta_length >= FLOAT_EPSILON) { + /* Move (x, y) forward along the line by dash_length. */ + x += ux * dash_length; + y += uy * dash_length; + + if((dash_index & 0x1) == 0) { + VG_LITE_ERROR_HANDLER(_end_stroke_sub_path( + stroke_conversion, + x, y, dx, dy + )); + + drawing = 0; + } + + VG_LITE_ERROR_HANDLER(_get_next_dash_length(stroke_conversion, &dash_index, &dash_length)); + length = delta_length; + } + else if(delta_length <= -FLOAT_EPSILON) { + dash_length = -delta_length; + break; + } + else { + if((dash_index & 0x1) == 0) { + VG_LITE_ERROR_HANDLER(_end_stroke_sub_path( + stroke_conversion, + next_point->x, next_point->y, + dx, dy + )); + + drawing = 0; + } + + VG_LITE_ERROR_HANDLER(_get_next_dash_length(stroke_conversion, &dash_index, &dash_length)); + length = 0; + break; + } + + if((dash_index & 0x1) == 0) { + VG_LITE_ERROR_HANDLER(_start_new_stroke_sub_path( + stroke_conversion, + x, y, + dx, dy, add_end_cap, + &stroke_sub_path + )); + + drawing = 1; + add_end_cap = 1; + } + } while(1); + } + + prev_length = length; + } + + if(need_to_handle_swing) { + accu_length += point->prev->length; + stroke_conversion->swing_length = accu_length; + if(accu_length < half_width) { + swing_handling = SWING_OUT; + } + else if(total_length - accu_length < half_width) { + swing_handling = SWING_IN; + } + else { + swing_handling = SWING_NO; + } + } + + if(stroke_conversion->swing_handling != SWING_NO) { + /* Draw the swing area (pie area). */ + VG_LITE_ERROR_HANDLER(_draw_swing_pie_area(stroke_conversion, stroke_conversion->path_end, VGL_FALSE)); + } + + if(stroke_conversion->closed) { + if(! dashing || drawing) { + /* Add points for end of line. */ + VG_LITE_ERROR_HANDLER(_add_point_to_right_stroke_point_list_tail(stroke_conversion, + point->x + dx, point->y + dy)); + VG_LITE_ERROR_HANDLER(_add_point_to_left_point_list_head(stroke_conversion, + point->x - dx, point->y - dy)); + + if(! dashing) { + if(stroke_sub_path) { + /* Handle line joint style for the first/last point in closed path. */ + VG_LITE_ERROR_HANDLER(_close_stroke_sub_path( + stroke_conversion, point, + first_length, prev_length, swing_handling, + stroke_sub_path->point_list, stroke_sub_path->end_point + )); + } + } + else { + /* Handle line joint style for the first/last point in closed path. */ + if(first_right_point && last_left_point) { + VG_LITE_ERROR_HANDLER(_close_stroke_sub_path( + stroke_conversion, point, + first_length, prev_length, swing_handling, + first_right_point, last_left_point + )); + } + else { + error = VG_LITE_INVALID_ARGUMENT; + goto ErrorHandler; + } + } + } + else if(stroke_conversion->cap_style != VG_LITE_CAP_BUTT) { + /* No closing join need. Add end cap for the starting point. */ + + if(stroke_conversion->cap_style == VG_LITE_CAP_SQUARE) { + if(first_right_point && last_left_point) { + first_right_point->x += first_dy; + first_right_point->y -= first_dx; + last_left_point->x += first_dy; + last_left_point->y -= first_dx; + } + else { + error = VG_LITE_INVALID_ARGUMENT; + goto ErrorHandler; + } + } + else { + vg_lite_sub_path_ptr last_stroke = stroke_conversion->last_stroke; + vg_lite_path_point_ptr start_point = last_stroke->point_list; + vg_lite_path_point_ptr extra_point; + + /* Add curve. */ + /* Add extra point to the beginning with end point's coordinates. */ + extra_point = (vg_lite_path_point_ptr)vg_lite_os_malloc(sizeof(*extra_point)); + if(!extra_point) + return VG_LITE_OUT_OF_RESOURCES; + memset(extra_point, 0, sizeof(*extra_point)); + + extra_point->x = last_stroke->end_point->x; + extra_point->y = last_stroke->end_point->y; + extra_point->next = start_point; + start_point->prev = extra_point; + start_point->curve_type = CURVE_ARC_SCCW; + start_point->tangentX = stroke_conversion->path_points->x; + start_point->tangentY = stroke_conversion->path_points->y; + last_stroke->point_list = extra_point; + } + } + } + else if(! dashing || + (((dash_index & 0x1) == 0) && (dash_length < stroke_conversion->dash_pattern[dash_index]))) { + /* Add end cap if the subPath is not closed. */ + VG_LITE_ERROR_HANDLER(_end_stroke_sub_path( + stroke_conversion, + point->x, point->y, + dx, dy + )); + + drawing = 0; + } + + if(!dash_phase_reset) { + /* Update dash index and length for next subpath. */ + if(dashing) { + if(((dash_index & 0x1) == 1) && + (stroke_conversion->dash_pattern[dash_index] - dash_length < FLOAT_EPSILON)) { + stroke_conversion->dash_index = dash_index - 1; + stroke_conversion->dash_length = 0; + } + else { + stroke_conversion->dash_index = dash_index; + stroke_conversion->dash_length = dash_length; + } + } + } + +ErrorHandler: + return error; +} + +static vg_lite_error_t _copy_stroke_path( + vg_lite_stroke_t * stroke_conversion, + vg_lite_path_t * path +) +{ + vg_lite_error_t error = VG_LITE_SUCCESS; + vg_lite_path_point_ptr point, prev_point, tmp_point; + vg_lite_float_t totalsize = 0, real_size = 0; + float * pfloat; + char * cpath; +#if (CHIPID==0x355 || CHIPID==0x255) + char last_opcode = 0; +#endif + void * temp_stroke_data = NULL; + uint32_t temp_stroke_size; + vg_lite_sub_path_ptr sub_path; + vg_lite_float_t half_width; + +#if (CHIPID==0x355) + vg_lite_buffer_t buffer = { 0 }; + uint32_t bytes; +#endif + + if(!stroke_conversion || !path) + return VG_LITE_INVALID_ARGUMENT; + + half_width = stroke_conversion->half_width; + sub_path = stroke_conversion->stroke_paths; + + if(!stroke_conversion || !path || !sub_path) + return VG_LITE_SUCCESS; + + while(sub_path) { + tmp_point = prev_point = point = sub_path->point_list; + totalsize += _commandSize_float[VLC_OP_LINE] * sub_path->point_count + _commandSize_float[VLC_OP_CLOSE]; + for(; tmp_point; tmp_point = tmp_point->next) { + if(tmp_point->curve_type == CURVE_ARC_SCCW || tmp_point->curve_type == CURVE_ARC_SCCW_HALF) { + totalsize += 4 * _commandSize_float[VLC_OP_QUAD]; + } + } + + temp_stroke_data = path->stroke_path; + temp_stroke_size = path->stroke_size; + + path->stroke_size += (int32_t)totalsize; + +#if (CHIPID==0x355) + if(sub_path->next == NULL) { + bytes = (8 + path->stroke_size + 7 + 8) & ~7; + buffer.width = bytes; + buffer.height = 1; + buffer.stride = 0; + buffer.format = VG_LITE_A8; + VG_LITE_RETURN_ERROR(vg_lite_allocate(&buffer)); + + memset(buffer.memory, 0, buffer.stride); + ((uint32_t *)buffer.memory)[0] = VG_LITE_DATA((path->stroke_size + 7) / 8); + ((uint32_t *)buffer.memory)[1] = 0; + if(temp_stroke_data) { + memcpy((char *)buffer.memory + 8, temp_stroke_data, temp_stroke_size); + vg_lite_os_free(temp_stroke_data); + temp_stroke_data = NULL; + } + + path->stroke_path = 0; + pfloat = (vg_lite_float_t *)((char *)buffer.memory + 8 + temp_stroke_size); + } + else +#endif + { + path->stroke_path = (void *)vg_lite_os_malloc(path->stroke_size); + if(!path->stroke_path) { + error = VG_LITE_OUT_OF_RESOURCES; + goto ErrorHandler; + } + + memset(path->stroke_path, 0, path->stroke_size); + + if(temp_stroke_data) { + memcpy(path->stroke_path, temp_stroke_data, temp_stroke_size); + vg_lite_os_free(temp_stroke_data); + temp_stroke_data = NULL; + } + + pfloat = (vg_lite_float_t *)((char *)path->stroke_path + temp_stroke_size); + } +#if (CHIPID==0x355 || CHIPID==0x255) + if(last_opcode == VLC_OP_CLOSE) { + cpath = (char *)(pfloat - 1) + 1; + *cpath++ = VLC_OP_MOVE; + cpath = (char *)pfloat; + } + else +#endif + { + cpath = (char *)pfloat; + *cpath = VLC_OP_MOVE; + pfloat++; + } + + *pfloat++ = point->x; + *pfloat++ = point->y; + real_size += _commandSize_float[VLC_OP_MOVE]; +#if (CHIPID==0x355 || CHIPID==0x255) + if(last_opcode == VLC_OP_CLOSE) + real_size -= 4; +#endif + + for(point = point->next; point; prev_point = point, point = point->next) { + if(point->curve_type == CURVE_LINE) { + if(point->x == prev_point->x && point->y == prev_point->y) { + path->stroke_size -= _commandSize_float[VLC_OP_LINE]; + /* Skip zero-length lines. */ + continue; + } + + /* Add new command. */ + cpath = (char *)pfloat; + *cpath = VLC_OP_LINE; + pfloat++; + + /* Set the coordinates. */ + *pfloat++ = point->x; + *pfloat++ = point->y; + real_size += _commandSize_float[VLC_OP_LINE]; + } + else if(point->curve_type == CURVE_QUAD_CONTROL) { + /* Add new command. */ + cpath = (char *)pfloat; + *cpath = VLC_OP_QUAD; + pfloat++; + + /* Set the coordinates. */ + prev_point = point, point = point->next; + *pfloat++ = prev_point->x; + *pfloat++ = prev_point->y; + *pfloat++ = point->x; + *pfloat++ = point->y; + + real_size += _commandSize_float[VLC_OP_QUAD]; + } + else { + vg_lite_path_point_ptr point_list, p, nextP; + vg_lite_path_point_ptr p2; + + if(point->curve_type == CURVE_ARC_SCCW) { + /* Convert an arc to Bezier curves. */ + VG_LITE_ERROR_HANDLER(_convert_circle_arc(stroke_conversion, half_width, + point->tangentX, point->tangentY, + prev_point->x, prev_point->y, + point->x, point->y, + 0, &point_list)); + } + else { + /* Convert a half circle to Bezier curves. */ + VG_LITE_ERROR_HANDLER(_convert_circle_arc(stroke_conversion, half_width, + point->tangentX, point->tangentY, + prev_point->x, prev_point->y, + point->x, point->y, + 1, &point_list)); + + } + + if(point_list) { + for(p = point_list; p; p = nextP) { + /* Add new command. */ + cpath = (char *)pfloat; + *cpath = VLC_OP_QUAD; + pfloat++; + + /* Set the coordinates. */ + p2 = p->next; + nextP = p2->next; + + *pfloat++ = p->x; + *pfloat++ = p->y; + *pfloat++ = p2->x; + *pfloat++ = p2->y; + real_size += _commandSize_float[VLC_OP_QUAD]; + vg_lite_os_free(p); + vg_lite_os_free(p2); + } + } + else { + /* Handle special case of huge scaling. */ + /* Add new command. */ + cpath = (char *)pfloat; + *cpath = VLC_OP_LINE; + pfloat++; + + /* Set the coordinates. */ + *pfloat++ = point->x; + *pfloat++ = point->y; + real_size += _commandSize_float[VLC_OP_LINE]; + } + } + } + + /* Create a CLOSE_PATH command at the end. */ + cpath = (char *)pfloat; + if(sub_path->next) + *cpath = VLC_OP_CLOSE; + else + *cpath = VLC_OP_END; + real_size += _commandSize_float[VLC_OP_CLOSE]; + path->stroke_size = temp_stroke_size + (int32_t)real_size; + totalsize = 0; + real_size = 0; + sub_path = sub_path->next; +#if (CHIPID==0x355 || CHIPID==0x255) + last_opcode = *cpath; +#endif + } + +#if (CHIPID==0x355) + /* Initialize command buffer postfix. */ + ((uint32_t *)buffer.memory)[(bytes >> 2) - 2] = VG_LITE_RETURN(); + ((uint32_t *)buffer.memory)[(bytes >> 2) - 1] = 0; + + /* Mark stroke as uploaded. */ + path->stroke->uploaded.handle = buffer.handle; + path->stroke->uploaded.address = buffer.address; + path->stroke->uploaded.memory = buffer.memory; + path->stroke->uploaded.bytes = bytes; + VLM_PATH_STROKE_ENABLE_UPLOAD(*path); +#endif + +ErrorHandler: + if(temp_stroke_data) { + vg_lite_os_free(temp_stroke_data); + temp_stroke_data = NULL; + } + return error; +} + +static vg_lite_error_t _initialize_stroke_dash_parameters( + vg_lite_stroke_t * stroke_conversion +) +{ + vg_lite_error_t error = VG_LITE_SUCCESS; + uint32_t count; + uint32_t i; + vg_lite_float_t * pattern_src; + vg_lite_float_t * pattern, * temp_pattern; + vg_lite_float_t length; + + if(!stroke_conversion) + return VG_LITE_INVALID_ARGUMENT; + + count = stroke_conversion->pattern_count; + if(count == 0 || !stroke_conversion->dash_pattern) + return error; + + length = stroke_conversion->dash_phase; + + /* The last pattern is ignored if the number is odd. */ + if(count & 0x1) count--; + + pattern = (vg_lite_float_t *)vg_lite_os_malloc(count * sizeof(vg_lite_float_t)); + if(!pattern) + return VG_LITE_OUT_OF_RESOURCES; + + temp_pattern = pattern; + stroke_conversion->pattern_length = 0.0f; + pattern_src = stroke_conversion->dash_pattern; + + for(i = 0; i < count; i++, pattern++, pattern_src++) { + if(*pattern_src < 0.0f) { + *pattern = 0.0f; + } + else { + *pattern = *pattern_src; + } + stroke_conversion->pattern_length += *pattern; + } + + if(stroke_conversion->pattern_length < FLOAT_EPSILON) { + stroke_conversion->pattern_count = 0; + vg_lite_os_free(temp_pattern); + temp_pattern = NULL; + return error; + } + + while(length < 0.0f) { + length += stroke_conversion->pattern_length; + } + + while(length >= stroke_conversion->pattern_length) { + length -= stroke_conversion->pattern_length; + } + + pattern = stroke_conversion->dash_pattern; + for(i = 0; i < stroke_conversion->pattern_count; i++, pattern++) { + if(length <= *pattern) break; + + length -= *pattern; + } + + stroke_conversion->dash_index = i; + stroke_conversion->dash_length = *pattern - length; + + vg_lite_os_free(temp_pattern); + temp_pattern = NULL; + + return error; +} + +vg_lite_error_t vg_lite_update_stroke( + vg_lite_path_t * path +) +{ + vg_lite_error_t error = VG_LITE_SUCCESS; + vg_lite_stroke_t * stroke_conversion; + vg_lite_path_list_ptr cur_list; + +#if gcFEATURE_VG_TRACE_API + VGLITE_LOG("vg_lite_update_stroke %p\n", path); +#endif + + if(!path) + return VG_LITE_INVALID_ARGUMENT; + + if(!path->path_length) + return VG_LITE_SUCCESS; + + if(!path->path) + return VG_LITE_INVALID_ARGUMENT; + + if(!path->stroke) + return VG_LITE_INVALID_ARGUMENT; + + stroke_conversion = path->stroke; + cur_list = stroke_conversion->cur_list; + +#if (CHIPID==0x355) + if(path->stroke && path->stroke->uploaded.handle != NULL) { + vg_lite_kernel_free_t free_cmd; + free_cmd.memory_handle = path->stroke->uploaded.handle; + error = vg_lite_kernel(VG_LITE_FREE, &free_cmd); + if(error != VG_LITE_SUCCESS) + return error; + + path->stroke->uploaded.address = 0; + path->stroke->uploaded.bytes = 0; + path->stroke->uploaded.handle = NULL; + path->stroke->uploaded.memory = NULL; + } +#endif + + /* Free the existing stroke path. */ + if(path->stroke_path) { + vg_lite_os_free(path->stroke_path); + /* Reset the stroke. */ + path->stroke_path = NULL; + } + + if(stroke_conversion->line_width >= FLOAT_FAT_LINE_WIDTH + && stroke_conversion->line_width >= 1.0f) { + stroke_conversion->fattened = 1; + } + + stroke_conversion->add_end = path->add_end; + + VG_LITE_RETURN_ERROR(_initialize_stroke_dash_parameters(stroke_conversion)); + VG_LITE_RETURN_ERROR(_flatten_path(stroke_conversion, path)); + + for(cur_list = stroke_conversion->path_list_divide; cur_list; cur_list = cur_list->next) { + stroke_conversion->path_end = cur_list->path_end; + stroke_conversion->path_points = cur_list->path_points; + stroke_conversion->point_count = cur_list->point_count; + stroke_conversion->closed = cur_list->closed; + + VG_LITE_RETURN_ERROR(_create_stroke_path(stroke_conversion)); + } + + if(stroke_conversion->path_list_divide) { + stroke_conversion->path_end = stroke_conversion->path_list_divide->path_end; + stroke_conversion->path_points = stroke_conversion->path_list_divide->path_points; + stroke_conversion->point_count = stroke_conversion->path_list_divide->point_count; + } + + VG_LITE_RETURN_ERROR(_copy_stroke_path(stroke_conversion, path)); + + /* add VLC_OP_END if stroke_path is empty. */ + if(path->stroke_size == 0) { + path->stroke_path = vg_lite_os_malloc(_commandSize_float[VLC_OP_END]); + if(!path->stroke_path) + return VG_LITE_OUT_OF_RESOURCES; + *(uint8_t *)path->stroke_path = VLC_OP_END; + path->stroke_size = _commandSize_float[VLC_OP_END]; + } + + return error; +} + +vg_lite_error_t vg_lite_set_stroke( + vg_lite_path_t * path, + vg_lite_cap_style_t cap_style, + vg_lite_join_style_t join_style, + vg_lite_float_t line_width, + vg_lite_float_t miter_limit, + vg_lite_float_t * dash_pattern, + vg_lite_uint32_t pattern_count, + vg_lite_float_t dash_phase, + vg_lite_color_t stroke_color +) +{ +#if gcFEATURE_VG_TRACE_API + VGLITE_LOG("vg_lite_set_stroke %p %d %d %f %f %p %d %f 0x%08X\n", path, cap_style, join_style, line_width, miter_limit, + dash_pattern, pattern_count, dash_phase, stroke_color); +#endif + + if(!path || line_width <= 0) + return VG_LITE_INVALID_ARGUMENT; + + if(miter_limit < 1.0f) + miter_limit = 1.0f; + + if(!path->stroke) { + path->stroke = (vg_lite_stroke_t *)vg_lite_os_malloc(sizeof(vg_lite_stroke_t)); + if(!path->stroke) + return VG_LITE_OUT_OF_RESOURCES; + memset(path->stroke, 0, sizeof(vg_lite_stroke_t)); + } + else { + if(path->stroke) { + if(path->stroke->path_list_divide) { + vg_lite_path_list_ptr cur_list; + while(path->stroke->path_list_divide) { + cur_list = path->stroke->path_list_divide->next; + if(path->stroke->path_list_divide->path_points) { + vg_lite_path_point_ptr temp_point; + while(path->stroke->path_list_divide->path_points) { + temp_point = path->stroke->path_list_divide->path_points->next; + vg_lite_os_free(path->stroke->path_list_divide->path_points); + path->stroke->path_list_divide->path_points = temp_point; + } + temp_point = NULL; + } + vg_lite_os_free(path->stroke->path_list_divide); + path->stroke->path_list_divide = cur_list; + } + cur_list = NULL; + } + + if(path->stroke->stroke_paths) { + vg_lite_sub_path_ptr temp_sub_path; + while(path->stroke->stroke_paths) { + temp_sub_path = path->stroke->stroke_paths->next; + if(path->stroke->stroke_paths->point_list) { + vg_lite_path_point_ptr temp_point; + while(path->stroke->stroke_paths->point_list) { + temp_point = path->stroke->stroke_paths->point_list->next; + vg_lite_os_free(path->stroke->stroke_paths->point_list); + path->stroke->stroke_paths->point_list = temp_point; + } + temp_point = NULL; + } + vg_lite_os_free(path->stroke->stroke_paths); + path->stroke->stroke_paths = temp_sub_path; + } + temp_sub_path = NULL; + } + + if(path->stroke->dash_pattern) + vg_lite_os_free(path->stroke->dash_pattern); + + path->stroke_valid = 0; + } + + memset(path->stroke, 0, sizeof(vg_lite_stroke_t)); + path->stroke_size = 0; + } + + /* Clamp dash pattern and phase. */ + pattern_count &= 0xFFFFFFFE; + float * dash_pattern_copy = NULL; + if(pattern_count > 0) { + dash_pattern_copy = vg_lite_os_malloc(pattern_count * sizeof(float)); + if(!dash_pattern_copy) + return VG_LITE_OUT_OF_RESOURCES; + } + for(uint32_t i = 0; i < pattern_count; ++i) + dash_pattern_copy[i] = (dash_pattern[i] > 0.f) ? dash_pattern[i] : 0.f; + if(dash_phase < 0.f) { + float dash_total_length = 0.f; + for(uint32_t i = 0; i < pattern_count; ++i) + dash_total_length += dash_pattern_copy[i]; + if(dash_total_length > 0.f) + dash_phase += (int)(-dash_phase / dash_total_length + 1) * dash_total_length; + else + dash_phase = 0.f; + } + + path->stroke->cap_style = cap_style; + path->stroke->join_style = join_style; + path->stroke->line_width = line_width; + path->stroke->miter_limit = miter_limit; + path->stroke->half_width = line_width / 2.0f; + path->stroke->miter_square = path->stroke->miter_limit * path->stroke->miter_limit; + path->stroke->dash_pattern = dash_pattern_copy; + path->stroke->pattern_count = pattern_count; + path->stroke->dash_phase = dash_phase; + path->stroke_color = stroke_color; + + return VG_LITE_SUCCESS; +} + +#else /* gcFEATURE_VG_STROKE_PATH */ + +vg_lite_error_t vg_lite_update_stroke( + vg_lite_path_t * path +) +{ + return VG_LITE_NOT_SUPPORT; +} + +vg_lite_error_t vg_lite_set_stroke( + vg_lite_path_t * path, + vg_lite_cap_style_t cap_style, + vg_lite_join_style_t join_style, + vg_lite_float_t line_width, + vg_lite_float_t miter_limit, + vg_lite_float_t * dash_pattern, + vg_lite_uint32_t pattern_count, + vg_lite_float_t dash_phase, + vg_lite_color_t stroke_color +) +{ + return VG_LITE_NOT_SUPPORT; +} + +#endif /* gcFEATURE_VG_STROKE_PATH */ + +#if gcFEATURE_VG_ARC_PATH + +static vg_lite_float_t _angle( + vg_lite_float_t Ux, + vg_lite_float_t Uy, + vg_lite_float_t Vx, + vg_lite_float_t Vy +) +{ + + vg_lite_float_t dot, length, angle, cosVal; + int32_t sign; + + dot = Ux * Vx + Uy * Vy; + length = SQRTF(Ux * Ux + Uy * Uy) * SQRTF(Vx * Vx + Vy * Vy); + sign = (Ux * Vy - Uy * Vx < 0) ? -1 : 1; + cosVal = dot / length; + cosVal = CLAMP(cosVal, -1.0f, 1.0f); + angle = sign * ACOSF(cosVal); + return angle; +} + +void compute_quadpathbounds(vg_lite_path_t * path, float currentX, float currentY, float controlX, float controlY, + float lastX, float lastY) +{ + int j = 0; + float newPointX = 0; + float newPointY = 0; + + for(j = 1; j <= 256; j++) { + float t = (float)j / 256; + float u = 1.0f - t; + float term1 = u * u; + float term2 = t * u * 2.0f; + float term3 = t * t; + newPointX = currentX * term1 + controlX * term2 + lastX * term3; + newPointY = currentY * term1 + controlY * term2 + lastY * term3; + + path->bounding_box[0] = MIN(path->bounding_box[0], newPointX); + path->bounding_box[1] = MIN(path->bounding_box[1], newPointY); + path->bounding_box[2] = MAX(path->bounding_box[2], newPointX); + path->bounding_box[3] = MAX(path->bounding_box[3], newPointY); + } +} + +vg_lite_error_t _convert_hline( + vg_lite_float_t EndX, + vg_lite_float_t EndY, + uint8_t Relative, + vg_lite_control_coord_t * coords, + void ** path_data, + uint32_t * offset, + uint32_t last_size +) +{ + vg_lite_float_t endX, endY; + uint8_t segmentCommand; + int32_t segs; + uint32_t bufferSize; + char * pchar, * linePath; + vg_lite_float_t * pfloat; + + /******************************************************************* + ** Converting. + */ + if(path_data == NULL || *path_data == NULL || offset == NULL || coords == NULL) + return VG_LITE_INVALID_ARGUMENT; + segs = 1; + if(Relative) { + endX = EndX + coords->lastX; + endY = EndY + coords->lastY; + } + else { + endX = EndX; + endY = EndY; + } + + /* Determine the segment command. */ + segmentCommand = Relative + ? VLC_OP_LINE_REL + : VLC_OP_LINE; + + /* Determine the size of the buffer required. */ + bufferSize = (1 + 2) * SIZEOF(vg_lite_float_t) * segs; + + linePath = (char *)vg_lite_os_malloc(*offset + bufferSize + last_size); + if(linePath == NULL) + return VG_LITE_OUT_OF_RESOURCES; +#if(CHIPID == 0x355) + memset(linePath, 0, *offset + bufferSize + last_size); +#endif + memcpy(linePath, (char *)*path_data, *offset); + vg_lite_os_free(*path_data); + + *path_data = linePath; + pchar = linePath + *offset; + pfloat = (vg_lite_float_t *)pchar; + + while(segs-- > 0) { + /* Adjust relative coordinates. */ + pchar = (char *)pfloat; + *pchar = segmentCommand; + pfloat++; + if(Relative) { + *pfloat++ = EndX; + *pfloat++ = 0; + } + else { + *pfloat++ = EndX; + *pfloat++ = EndY; + } + *offset += (1 + 2) * SIZEOF(vg_lite_float_t); + } + /* Update the control coordinates. */ + coords->lastX = endX; + coords->lastY = endY; + coords->controlX = endX; + coords->controlY = endY; + return VG_LITE_SUCCESS; +} + +vg_lite_error_t _convert_vline( + vg_lite_float_t EndX, + vg_lite_float_t EndY, + uint8_t Relative, + vg_lite_control_coord_t * coords, + void ** path_data, + uint32_t * offset, + uint32_t last_size +) +{ + vg_lite_float_t endX, endY; + uint8_t segmentCommand; + int32_t segs; + uint32_t bufferSize; + char * pchar, * linePath; + vg_lite_float_t * pfloat; + + /******************************************************************* + ** Converting. + */ + if(path_data == NULL || *path_data == NULL || offset == NULL || coords == NULL) + return VG_LITE_INVALID_ARGUMENT; + segs = 1; + if(Relative) { + endX = EndX + coords->lastX; + endY = EndY + coords->lastY; + } + else { + endX = EndX; + endY = EndY; + } + + /* Determine the segment command. */ + segmentCommand = Relative + ? VLC_OP_LINE_REL + : VLC_OP_LINE; + + /* Determine the size of the buffer required. */ + bufferSize = (1 + 2) * SIZEOF(vg_lite_float_t) * segs; + + linePath = (char *)vg_lite_os_malloc(*offset + bufferSize + last_size); + if(linePath == NULL) + return VG_LITE_OUT_OF_RESOURCES; +#if(CHIPID == 0x355) + memset(linePath, 0, *offset + bufferSize + last_size); +#endif + memcpy(linePath, (char *)*path_data, *offset); + vg_lite_os_free(*path_data); + + *path_data = linePath; + pchar = linePath + *offset; + pfloat = (vg_lite_float_t *)pchar; + + while(segs-- > 0) { + /* Adjust relative coordinates. */ + pchar = (char *)pfloat; + *pchar = segmentCommand; + pfloat++; + if(Relative) { + *pfloat++ = 0; + *pfloat++ = EndY; + } + else { + *pfloat++ = EndX; + *pfloat++ = EndY; + } + *offset += (1 + 2) * SIZEOF(vg_lite_float_t); + } + /* Update the control coordinates. */ + coords->lastX = endX; + coords->lastY = endY; + coords->controlX = endX; + coords->controlY = endY; + return VG_LITE_SUCCESS; +} + +vg_lite_error_t _convert_scubic( + vg_lite_float_t EndX, + vg_lite_float_t EndY, + vg_lite_float_t ControlX, + vg_lite_float_t ControlY, + uint8_t Relative, + vg_lite_control_coord_t * coords, + void ** path_data, + uint32_t * offset, + uint32_t last_size +) +{ + vg_lite_float_t endX, endY; + uint8_t segmentCommand; + int32_t segs; + uint32_t bufferSize; + char * pchar, * cubicPath; + vg_lite_float_t * pfloat; + vg_lite_float_t controlX; + vg_lite_float_t controlY; + /******************************************************************* + ** Converting. + */ + if(path_data == NULL || *path_data == NULL || offset == NULL || coords == NULL) + return VG_LITE_INVALID_ARGUMENT; + segs = 1; + if(Relative) { + endX = EndX + coords->lastX; + endY = EndY + coords->lastY; + controlX = coords->lastX + ControlX; + controlY = coords->lastY + ControlY; + } + else { + endX = EndX; + endY = EndY; + controlX = ControlX; + controlY = ControlY; + } + + /* Determine the segment command. */ + segmentCommand = Relative + ? VLC_OP_CUBIC_REL + : VLC_OP_CUBIC; + + /* Determine the size of the buffer required. */ + bufferSize = (1 + 6) * SIZEOF(vg_lite_float_t) * segs; + + cubicPath = (char *)vg_lite_os_malloc(*offset + bufferSize + last_size); + if(cubicPath == NULL) + return VG_LITE_OUT_OF_RESOURCES; +#if(CHIPID == 0x355) + memset(cubicPath, 0, *offset + bufferSize + last_size); +#endif + memcpy(cubicPath, (char *)*path_data, *offset); + vg_lite_os_free(*path_data); + + *path_data = cubicPath; + pchar = cubicPath + *offset; + pfloat = (vg_lite_float_t *)pchar; + + while(segs-- > 0) { + /* Adjust relative coordinates. */ + pchar = (char *)pfloat; + *pchar = segmentCommand; + pfloat++; + if(Relative) { + /* Calculate the first control point and convert to relative coordinates. */ + *pfloat++ = (2 * coords->lastX - coords->controlX) - coords->lastX; + *pfloat++ = (2 * coords->lastY - coords->controlY) - coords->lastY; + *pfloat++ = ControlX; + *pfloat++ = ControlY; + *pfloat++ = EndX; + *pfloat++ = EndY; + *offset += (1 + 6) * SIZEOF(vg_lite_float_t); + } + else { + *pfloat++ = 2 * coords->lastX - coords->controlX; + *pfloat++ = 2 * coords->lastY - coords->controlY; + *pfloat++ = ControlX; + *pfloat++ = ControlY; + *pfloat++ = EndX; + *pfloat++ = EndY; + *offset += (1 + 6) * SIZEOF(vg_lite_float_t); + } + } + /* Update the control coordinates. */ + coords->lastX = endX; + coords->lastY = endY; + coords->controlX = controlX; + coords->controlY = controlY; + + return VG_LITE_SUCCESS; +} + +vg_lite_error_t _convert_squad( + vg_lite_float_t EndX, + vg_lite_float_t EndY, + uint8_t Relative, + vg_lite_control_coord_t * coords, + void ** path_data, + uint32_t * offset, + uint32_t last_size +) +{ + vg_lite_float_t endX, endY; + uint8_t segmentCommand; + int32_t segs; + uint32_t bufferSize; + char * pchar, * quadPath; + vg_lite_float_t * pfloat; + vg_lite_float_t ControlX1; + vg_lite_float_t ControlY1; + vg_lite_float_t controlX; + vg_lite_float_t controlY; + /******************************************************************* + ** Converting. + */ + if(path_data == NULL || *path_data == NULL || offset == NULL || coords == NULL) + return VG_LITE_INVALID_ARGUMENT; + segs = 1; + if(Relative) { + endX = EndX + coords->lastX; + endY = EndY + coords->lastY; + } + else { + endX = EndX; + endY = EndY; + } + + /* Determine the segment command. */ + segmentCommand = Relative + ? VLC_OP_QUAD_REL + : VLC_OP_QUAD; + + /* Determine the size of the buffer required. */ + bufferSize = (1 + 4) * SIZEOF(vg_lite_float_t) * segs; + + quadPath = (char *)vg_lite_os_malloc(*offset + bufferSize + last_size); + if(quadPath == NULL) + return VG_LITE_OUT_OF_RESOURCES; +#if(CHIPID == 0x355) + memset(quadPath, 0, *offset + bufferSize + last_size); +#endif + memcpy(quadPath, (char *)*path_data, *offset); + vg_lite_os_free(*path_data); + + *path_data = quadPath; + pchar = quadPath + *offset; + pfloat = (vg_lite_float_t *)pchar; + + while(segs-- > 0) { + /* Adjust relative coordinates. */ + pchar = (char *)pfloat; + *pchar = segmentCommand; + pfloat++; + if(Relative) { + ControlX1 = *pfloat++ = (2 * coords->lastX - coords->controlX) - coords->lastX; + ControlY1 = *pfloat++ = (2 * coords->lastY - coords->controlY) - coords->lastY; + controlX = ControlX1 + coords->lastX; + controlY = ControlY1 + coords->lastY; + *pfloat++ = EndX; + *pfloat++ = EndY; + *offset += (1 + 4) * SIZEOF(vg_lite_float_t); + } + else { + controlX = *pfloat++ = 2 * coords->lastX - coords->controlX; + controlY = *pfloat++ = 2 * coords->lastY - coords->controlY; + *pfloat++ = EndX; + *pfloat++ = EndY; + *offset += (1 + 4) * SIZEOF(vg_lite_float_t); + } + } + /* Update the control coordinates. */ + coords->startX = coords->lastX; + coords->startY = coords->lastY; + coords->lastX = endX; + coords->lastY = endY; + coords->controlX = controlX; + coords->controlY = controlY; + + return VG_LITE_SUCCESS; +} + +/*! + @discussion + Convert arc to multi-segment bezier curve. + @param HorRadius + Major axis radius. + @param VerRadius + minor axis radius. + @param RotAngle + Rotation angle. + @param EndX + End coordinate x. + @param EndX + End coordinate y. + @param CounterClockwise + If this is 0,anticlockwise rotation,if this is 1,clockwise rotation. + @param Large + 1 means big arc,0 means little arc. + @param Relative + 1 means absolute coordinates,0 means relative coordinates. + @param coords + Including the start point coordinates of the path,the control point of the last segment of the path, + and the end point of the last segment of the path. + @param path_data + Path data usr for internal conversion. + @param offset + The offset of path_data. + @param last_size + The remain unconverted size of the original path data. + @result + Error code. VG_LITE_INVALID_ARGUMENTS to indicate the parameters are wrong. +*/ +vg_lite_error_t _convert_arc( + vg_lite_float_t HorRadius, + vg_lite_float_t VerRadius, + vg_lite_float_t RotAngle, + vg_lite_float_t EndX, + vg_lite_float_t EndY, + uint8_t CounterClockwise, + uint8_t Large, + uint8_t Relative, + vg_lite_control_coord_t * coords, + void ** path_data, + uint32_t * offset, + uint32_t last_size +) +{ + vg_lite_float_t endX, endY; + uint8_t segmentCommand; + vg_lite_float_t phi, cosPhi, sinPhi; + vg_lite_float_t dxHalf, dyHalf; + vg_lite_float_t x1Prime, y1Prime; + vg_lite_float_t rx, ry; + vg_lite_float_t x1PrimeSquare, y1PrimeSquare; + vg_lite_float_t lambda; + vg_lite_float_t rxSquare, rySquare; + int32_t sign; + vg_lite_float_t sq, signedSq; + vg_lite_float_t cxPrime, cyPrime; + vg_lite_float_t theta1, thetaSpan; + int32_t segs; + vg_lite_float_t theta, ax, ay, x, y; + vg_lite_float_t controlX, controlY, anchorX, anchorY; + vg_lite_float_t lastX, lastY; + uint32_t bufferSize; + char * pchar, * arcPath; + vg_lite_float_t * pfloat; + + /******************************************************************* + ** Converting. + */ + if(path_data == NULL || *path_data == NULL || offset == NULL || coords == NULL) + return VG_LITE_INVALID_ARGUMENT; + + if(Relative) { + endX = EndX + coords->lastX; + endY = EndY + coords->lastY; + } + else { + endX = EndX; + endY = EndY; + } + + phi = RotAngle / 180.0f * PI; + cosPhi = COSF(phi); + sinPhi = SINF(phi); + + if(Relative) { + dxHalf = - EndX / 2.0f; + dyHalf = - EndY / 2.0f; + } + else { + dxHalf = (coords->lastX - endX) / 2.0f; + dyHalf = (coords->lastY - endY) / 2.0f; + } + + x1Prime = cosPhi * dxHalf + sinPhi * dyHalf; + y1Prime = -sinPhi * dxHalf + cosPhi * dyHalf; + + rx = FABSF(HorRadius); + ry = FABSF(VerRadius); + + x1PrimeSquare = x1Prime * x1Prime; + y1PrimeSquare = y1Prime * y1Prime; + + lambda = x1PrimeSquare / (rx * rx) + y1PrimeSquare / (ry * ry); + if(lambda > 1.0f) { + rx *= SQRTF(lambda); + ry *= SQRTF(lambda); + } + + rxSquare = rx * rx; + rySquare = ry * ry; + + sign = (Large == CounterClockwise) ? -1 : 1; + sq = (rxSquare * rySquare + - rxSquare * y1PrimeSquare + - rySquare * x1PrimeSquare + ) + / + (rxSquare * y1PrimeSquare + + rySquare * x1PrimeSquare + ); + signedSq = sign * ((sq < 0) ? 0 : SQRTF(sq)); + cxPrime = signedSq * (rx * y1Prime / ry); + cyPrime = signedSq * -(ry * x1Prime / rx); + + theta1 = _angle(1, 0, (x1Prime - cxPrime) / rx, (y1Prime - cyPrime) / ry); + theta1 = FMODF(theta1, 2 * PI); + + thetaSpan = _angle((x1Prime - cxPrime) / rx, (y1Prime - cyPrime) / ry, + (-x1Prime - cxPrime) / rx, (-y1Prime - cyPrime) / ry); + + if(!CounterClockwise && (thetaSpan > 0)) { + thetaSpan -= 2 * PI; + } + else if(CounterClockwise && (thetaSpan < 0)) { + thetaSpan += 2 * PI; + } + + thetaSpan = FMODF(thetaSpan, 2 * PI); + + /******************************************************************* + ** Drawing. + */ + segs = (int32_t)(CEILF(FABSF(thetaSpan) / (45.0f / 180.0f * PI))); + + theta = thetaSpan / segs; + + ax = coords->lastX - COSF(theta1) * rx; + ay = coords->lastY - SINF(theta1) * ry; + if(FABSF(HorRadius) != 0 && + FABSF(VerRadius) != 0 && + (endX != coords->lastX || endY != coords->lastY)) { + /* Determine the segment command. */ + segmentCommand = Relative + ? VLC_OP_QUAD_REL + : VLC_OP_QUAD; + + /* Determine the size of the buffer required. */ + bufferSize = (1 + 2 * 2) * SIZEOF(vg_lite_float_t) * segs; + + arcPath = (char *)vg_lite_os_malloc(*offset + bufferSize + last_size); + if(arcPath == NULL) + return VG_LITE_OUT_OF_RESOURCES; +#if(CHIPID == 0x355) + memset(arcPath, 0, *offset + bufferSize + last_size); +#endif + memcpy(arcPath, (char *)*path_data, *offset); + vg_lite_os_free(*path_data); + + *path_data = arcPath; + + pchar = arcPath + *offset; + pfloat = (vg_lite_float_t *)pchar; + + /* Set initial last point. */ + lastX = coords->lastX; + lastY = coords->lastY; + + while(segs-- > 0) { + theta1 += theta; + + controlX = ax + COSF(theta1 - (theta / 2.0f)) * rx / COSF(theta / 2.0f); + controlY = ay + SINF(theta1 - (theta / 2.0f)) * ry / COSF(theta / 2.0f); + + anchorX = ax + COSF(theta1) * rx; + anchorY = ay + SINF(theta1) * ry; + + if(RotAngle != 0) { + x = coords->lastX + cosPhi * (controlX - coords->lastX) - sinPhi * (controlY - coords->lastY); + y = coords->lastY + sinPhi * (controlX - coords->lastX) + cosPhi * (controlY - coords->lastY); + controlX = x; + controlY = y; + + x = coords->lastX + cosPhi * (anchorX - coords->lastX) - sinPhi * (anchorY - coords->lastY); + y = coords->lastY + sinPhi * (anchorX - coords->lastX) + cosPhi * (anchorY - coords->lastY); + anchorX = x; + anchorY = y; + } + + if(segs == 0) { + /* Use end point directly to avoid accumulated errors. */ + anchorX = endX; + anchorY = endY; + } + + /* Adjust relative coordinates. */ + if(Relative) { + vg_lite_float_t nextLastX = anchorX; + vg_lite_float_t nextLastY = anchorY; + + controlX -= lastX; + controlY -= lastY; + + anchorX -= lastX; + anchorY -= lastY; + + lastX = nextLastX; + lastY = nextLastY; + } + pchar = (char *)pfloat; + *pchar = segmentCommand; + pfloat++; + *pfloat++ = controlX; + *pfloat++ = controlY; + *pfloat++ = anchorX; + *pfloat++ = anchorY; + *offset += (1 + 2 * 2) * SIZEOF(vg_lite_float_t); + } + } + else { + /* Determine the segment command. */ + segmentCommand = Relative + ? VLC_OP_LINE_REL + : VLC_OP_LINE; + + /* Determine the size of the buffer required. */ + bufferSize = (1 + 2) * SIZEOF(vg_lite_float_t); + + arcPath = (char *)vg_lite_os_malloc(*offset + bufferSize + last_size); + if(arcPath == NULL) + return VG_LITE_OUT_OF_RESOURCES; + memcpy(arcPath, (char *)*path_data, *offset); + vg_lite_os_free(*path_data); + + *path_data = arcPath; + + pchar = arcPath + *offset; + pfloat = (vg_lite_float_t *)pchar; + pchar = (char *)pfloat; + *pchar = segmentCommand; + pfloat++; + *pfloat++ = Relative ? EndX : endX; + *pfloat++ = Relative ? EndY : endY; + *offset += (1 + 2) * SIZEOF(vg_lite_float_t); + + } + /* Update the control coordinates. */ + coords->lastX = endX; + coords->lastY = endY; + coords->controlX = endX; + coords->controlY = endY; + + return VG_LITE_SUCCESS; +} + +vg_lite_error_t vg_lite_init_arc_path(vg_lite_path_t * path, + vg_lite_format_t data_format, + vg_lite_quality_t quality, + vg_lite_uint32_t path_length, + vg_lite_pointer path_data, + vg_lite_float_t min_x, vg_lite_float_t min_y, + vg_lite_float_t max_x, vg_lite_float_t max_y) +{ + vg_lite_error_t error = VG_LITE_SUCCESS; + uint32_t i = 0, j, command = 0, offset = 0; + vg_lite_float_t moveToX, moveToY, lineToX, lineToY, controlX, controlY, quadToX, quadToY; + vg_lite_float_t controlX1, controlY1, controlX2, controlY2, cubicToX, cubicToY; + vg_lite_float_t horRadius, verRadius, rotAngle, endX, endY; + float * pfloat, * fpath; + char * cpath, * pathdata; + vg_lite_control_coord_t coords; + char add_end = path->add_end; + vg_lite_int32_t bytes; + vg_lite_pointer path_data_fp32 = path_data; + int8_t cmd, * path_data_s8_ptr; + int16_t * path_data_s16_ptr; + int32_t * path_data_s32_ptr; + float * path_data_fp32_ptr; + int32_t data_size, num = 0; + memset(&coords, 0, sizeof(vg_lite_control_coord_t)); + coords.lastX = s_context.path_lastX; + coords.lastY = s_context.path_lastY; + +#if gcFEATURE_VG_TRACE_API + VGLITE_LOG("vg_lite_init_arc_path %p %d %d %d %p %f %f %f %f\n", path, data_format, quality, path_length, path_data, + min_x, min_y, max_x, max_y); +#endif + + if(path == NULL || path_data == NULL) + return VG_LITE_INVALID_ARGUMENT; + + /* Path data cannot end with a CLOSE op. Replace CLOSE with END for path_data */ + data_size = get_data_size(data_format); + num = path_length / data_size; + + switch(data_format) { + case VG_LITE_S8: + if(path_data && (*((char *)path_data + num - 1) == VLC_OP_CLOSE)) { + *(char *)((int *)path_data + num - 1) = VLC_OP_END; + } + break; + + case VG_LITE_S16: + if(path_data && (*(char *)((short *)path_data + num - 1) == VLC_OP_CLOSE)) { + *(char *)((short *)path_data + num - 1) = VLC_OP_END; + } + break; + + case VG_LITE_S32: + if(path_data && (*(char *)((int *)path_data + num - 1) == VLC_OP_CLOSE)) { + *(char *)((int *)path_data + num - 1) = VLC_OP_END; + } + break; + + case VG_LITE_FP32: + if(path_data && (*(char *)((float *)path_data + num - 1) == VLC_OP_CLOSE)) { + *(char *)((float *)path_data + num - 1) = VLC_OP_END; + } + break; + + default: + break; + } + + /* Convert path format into float. */ + switch(data_format) { + case VG_LITE_S8: + /* src_s8, dst_fp32 */ + bytes = path_length * 4; + path_data_fp32 = vg_lite_os_malloc(bytes); + if(path_data_fp32 == NULL) + return VG_LITE_OUT_OF_RESOURCES; + memset(path_data_fp32, 0, bytes); + path_data_fp32_ptr = path_data_fp32; + path_data_s8_ptr = (int8_t *)path_data; + i = 0; + while(i < path_length) { + cmd = *(uint8_t *)path_data_s8_ptr; + *(uint8_t *)path_data_fp32_ptr = cmd; + path_data_s8_ptr++; + path_data_fp32_ptr++; + for(j = 0; j < _commandSize_float[cmd] / 4 - 1; j++) { + *path_data_fp32_ptr = (float)(*path_data_s8_ptr); + path_data_fp32_ptr++; + path_data_s8_ptr++; + } + i += _commandSize_float[cmd] / 4; + } + path_length *= 4; + break; + + case VG_LITE_S16: + /* src_s16, dst_fp32 */ + bytes = path_length * 2; + path_data_fp32 = vg_lite_os_malloc(bytes); + if(path_data_fp32 == NULL) + return VG_LITE_OUT_OF_RESOURCES; + memset(path_data_fp32, 0, bytes); + path_data_fp32_ptr = path_data_fp32; + path_data_s16_ptr = (int16_t *)path_data; + i = 0; + while(i < path_length) { + cmd = *(uint8_t *)path_data_s16_ptr; + *(uint8_t *)path_data_fp32_ptr = cmd; + path_data_s16_ptr++; + path_data_fp32_ptr++; + for(j = 0; j < _commandSize_float[cmd] / 4 - 1; j++) { + *path_data_fp32_ptr = (float)(*path_data_s16_ptr); + path_data_fp32_ptr++; + path_data_s16_ptr++; + } + i += _commandSize_float[cmd] / 2; + } + path_length *= 2; + break; + + case VG_LITE_S32: + /* src_s32, dst_fp32 */ + bytes = path_length; + path_data_fp32 = vg_lite_os_malloc(bytes); + if(path_data_fp32 == NULL) + return VG_LITE_OUT_OF_RESOURCES; + memset(path_data_fp32, 0, bytes); + path_data_fp32_ptr = path_data_fp32; + path_data_s32_ptr = (int32_t *)path_data; + i = 0; + while(i < path_length) { + cmd = *(uint8_t *)path_data_s32_ptr; + *(uint8_t *)path_data_fp32_ptr = cmd; + path_data_s32_ptr++; + path_data_fp32_ptr++; + for(j = 0; j < _commandSize_float[cmd] / 4 - 1; j++) { + *path_data_fp32_ptr = (float)(*path_data_s32_ptr); + path_data_fp32_ptr++; + path_data_s32_ptr++; + } + i += _commandSize_float[cmd]; + } + break; + + case VG_LITE_FP32: { + /* src_fp32, dst_fp32 */ + bytes = path_length; + path_data_fp32 = vg_lite_os_malloc(bytes); + if(path_data_fp32 == NULL) + return VG_LITE_OUT_OF_RESOURCES; +#if(CHIPID == 0x355) + memset(path_data_fp32, 0, bytes); +#endif + memcpy(path_data_fp32, path_data, bytes); + break; + } + + default: + break; + } + + vg_lite_clear_path(path); + + data_format = VG_LITE_FP32; + if(!path_length) { + path->format = data_format; + path->quality = quality; + path->bounding_box[0] = min_x; + path->bounding_box[1] = min_y; + path->bounding_box[2] = max_x; + path->bounding_box[3] = max_y; + path->path_length = 0; + path->path = NULL; + path->pdata_internal = 1; + path->path_changed = 1; + path->uploaded.address = 0; + path->uploaded.bytes = 0; + path->uploaded.handle = NULL; + path->uploaded.memory = NULL; + return VG_LITE_SUCCESS; + } + path->add_end = add_end; + path->bounding_box[0] = min_x; + path->bounding_box[1] = min_y; + path->bounding_box[2] = max_x; + path->bounding_box[3] = max_y; + pathdata = (char *)vg_lite_os_malloc(path_length); + if(pathdata == NULL) + return VG_LITE_OUT_OF_RESOURCES; +#if(CHIPID == 0x355) + memset(pathdata, 0, path_length); +#endif + pfloat = (vg_lite_float_t *)path_data_fp32; + i = 0; + while(i < path_length) { + cpath = (char *)pfloat; + command = (uint32_t) * cpath; + pfloat++; +#if (CHIPID==0x355) + uint8_t flag = 0; + if(command == VLC_OP_CLOSE) { + if(*((uint32_t *)cpath + 1) == VLC_OP_MOVE || *((uint32_t *)cpath + 1) == VLC_OP_MOVE_REL) { + flag = 1; + } + } +#endif + switch(command) { + case VLC_OP_END: + cpath = (char *)pathdata + offset; + fpath = (vg_lite_float_t *)cpath; + *cpath = VLC_OP_END; + offset += _commandSize_float[VLC_OP_END]; + i += _commandSize_float[VLC_OP_END]; + break; + case VLC_OP_CLOSE: + /* Update the control coordinates. */ + coords.lastX = coords.startX; + coords.lastY = coords.startY; + coords.controlX = coords.startX; + coords.controlY = coords.startY; + + cpath = (char *)pathdata + offset; + fpath = (vg_lite_float_t *)cpath; +#if (CHIPID==0x355) + if(flag == 1) { + if(data_size == 1) { + *cpath = VLC_OP_CLOSE; + } + else if(data_size == 2) { + *(uint16_t *)cpath = 0x0101; + } + else if(data_size == 4) { + *(uint32_t *)cpath = 0x01010101; + } + } + else +#endif + { + *cpath = VLC_OP_CLOSE; + } + offset += _commandSize_float[VLC_OP_CLOSE]; + i += _commandSize_float[VLC_OP_CLOSE]; + break; + case VLC_OP_MOVE: + moveToX = *pfloat; + pfloat++; + moveToY = *pfloat; + pfloat++; + + /* Update the control coordinates. */ + coords.startX = moveToX; + coords.startY = moveToY; + coords.lastX = moveToX; + coords.lastY = moveToY; + coords.controlX = moveToX; + coords.controlY = moveToY; + + cpath = (char *)pathdata + offset; + fpath = (vg_lite_float_t *)cpath; + *cpath = VLC_OP_MOVE; + fpath++; + *fpath = moveToX; + fpath++; + *fpath = moveToY; + fpath++; + offset += _commandSize_float[VLC_OP_MOVE]; + i += _commandSize_float[VLC_OP_MOVE]; + break; + case VLC_OP_MOVE_REL: + moveToX = *pfloat; + pfloat++; + moveToY = *pfloat; + pfloat++; + + cpath = (char *)pathdata + offset; + fpath = (vg_lite_float_t *)cpath; + *cpath = VLC_OP_MOVE_REL; + fpath++; + *fpath = moveToX; + fpath++; + *fpath = moveToY; + fpath++; + offset += _commandSize_float[VLC_OP_MOVE_REL]; + i += _commandSize_float[VLC_OP_MOVE_REL]; + + /* Determine the absolute coordinates. */ + moveToX += coords.lastX; + moveToY += coords.lastY; + + /* Update the control coordinates. */ + coords.startX = moveToX; + coords.startY = moveToY; + coords.lastX = moveToX; + coords.lastY = moveToY; + coords.controlX = moveToX; + coords.controlY = moveToY; + break; + case VLC_OP_LINE: + lineToX = *pfloat; + pfloat++; + lineToY = *pfloat; + pfloat++; + + /* Update the control coordinates. */ + coords.lastX = lineToX; + coords.lastY = lineToY; + coords.controlX = lineToX; + coords.controlY = lineToY; + + cpath = (char *)pathdata + offset; + fpath = (vg_lite_float_t *)cpath; + *cpath = VLC_OP_LINE; + fpath++; + *fpath = lineToX; + fpath++; + *fpath = lineToY; + fpath++; + offset += _commandSize_float[VLC_OP_LINE]; + i += _commandSize_float[VLC_OP_LINE]; + break; + case VLC_OP_LINE_REL: + lineToX = *pfloat; + pfloat++; + lineToY = *pfloat; + pfloat++; + + cpath = (char *)pathdata + offset; + fpath = (vg_lite_float_t *)cpath; + *cpath = VLC_OP_LINE_REL; + fpath++; + *fpath = lineToX; + fpath++; + *fpath = lineToY; + fpath++; + offset += _commandSize_float[VLC_OP_LINE_REL]; + i += _commandSize_float[VLC_OP_LINE_REL]; + + /* Determine the absolute coordinates. */ + lineToX += coords.lastX; + lineToY += coords.lastY; + + /* Update the control coordinates. */ + coords.lastX = lineToX; + coords.lastY = lineToY; + coords.controlX = lineToX; + coords.controlY = lineToY; + break; + case VLC_OP_QUAD: + controlX = *pfloat; + pfloat++; + controlY = *pfloat; + pfloat++; + quadToX = *pfloat; + pfloat++; + quadToY = *pfloat; + pfloat++; + compute_quadpathbounds(path, coords.lastX, coords.lastY, controlX, controlY, quadToX, quadToY); + /* Update the control coordinates. */ + coords.lastX = quadToX; + coords.lastY = quadToY; + coords.controlX = controlX; + coords.controlY = controlY; + + cpath = (char *)pathdata + offset; + fpath = (vg_lite_float_t *)cpath; + *cpath = VLC_OP_QUAD; + fpath++; + *fpath = controlX; + fpath++; + *fpath = controlY; + fpath++; + *fpath = quadToX; + fpath++; + *fpath = quadToY; + fpath++; + offset += _commandSize_float[VLC_OP_QUAD]; + i += _commandSize_float[VLC_OP_QUAD]; + break; + case VLC_OP_SQUAD: + quadToX = *pfloat; + pfloat++; + quadToY = *pfloat; + pfloat++; + i += _commandSize_float[VLC_OP_SQUAD]; + /* Update the control coordinates. */ + VG_LITE_ERROR_HANDLER(_convert_squad(quadToX, quadToY, VGL_FALSE, &coords, (void *)&pathdata, &offset, + path_length - i)); + compute_quadpathbounds(path, coords.startX, coords.startY, coords.controlX, coords.controlY, quadToX, quadToY); + break; + case VLC_OP_SQUAD_REL: + quadToX = *pfloat; + pfloat++; + quadToY = *pfloat; + pfloat++; + i += _commandSize_float[VLC_OP_SQUAD_REL]; + /* Update the control coordinates. */ + VG_LITE_ERROR_HANDLER(_convert_squad(quadToX, quadToY, VGL_TRUE, &coords, (void *)&pathdata, &offset, path_length - i)); + break; + case VLC_OP_QUAD_REL: + controlX = *pfloat; + pfloat++; + controlY = *pfloat; + pfloat++; + quadToX = *pfloat; + pfloat++; + quadToY = *pfloat; + pfloat++; + + cpath = (char *)pathdata + offset; + fpath = (vg_lite_float_t *)cpath; + *cpath = VLC_OP_QUAD_REL; + fpath++; + *fpath = controlX; + fpath++; + *fpath = controlY; + fpath++; + *fpath = quadToX; + fpath++; + *fpath = quadToY; + fpath++; + offset += _commandSize_float[VLC_OP_QUAD_REL]; + i += _commandSize_float[VLC_OP_QUAD_REL]; + + /* Determine the absolute coordinates. */ + controlX += coords.lastX; + controlY += coords.lastY; + quadToX += coords.lastX; + quadToY += coords.lastY; + + /* Update the control coordinates. */ + coords.lastX = quadToX; + coords.lastY = quadToY; + coords.controlX = controlX; + coords.controlY = controlY; + break; + case VLC_OP_CUBIC: + controlX1 = *pfloat; + pfloat++; + controlY1 = *pfloat; + pfloat++; + controlX2 = *pfloat; + pfloat++; + controlY2 = *pfloat; + pfloat++; + cubicToX = *pfloat; + pfloat++; + cubicToY = *pfloat; + pfloat++; + + /* Update the control coordinates. */ + coords.lastX = cubicToX; + coords.lastY = cubicToY; + coords.controlX = controlX2; + coords.controlY = controlY2; + + cpath = (char *)pathdata + offset; + fpath = (vg_lite_float_t *)cpath; + *cpath = VLC_OP_CUBIC; + fpath++; + *fpath = controlX1; + fpath++; + *fpath = controlY1; + fpath++; + *fpath = controlX2; + fpath++; + *fpath = controlY2; + fpath++; + *fpath = cubicToX; + fpath++; + *fpath = cubicToY; + fpath++; + offset += _commandSize_float[VLC_OP_CUBIC]; + i += _commandSize_float[VLC_OP_CUBIC]; + break; + case VLC_OP_CUBIC_REL: + controlX1 = *pfloat; + pfloat++; + controlY1 = *pfloat; + pfloat++; + controlX2 = *pfloat; + pfloat++; + controlY2 = *pfloat; + pfloat++; + cubicToX = *pfloat; + pfloat++; + cubicToY = *pfloat; + pfloat++; + + cpath = (char *)pathdata + offset; + fpath = (vg_lite_float_t *)cpath; + *cpath = VLC_OP_CUBIC_REL; + fpath++; + *fpath = controlX1; + fpath++; + *fpath = controlY1; + fpath++; + *fpath = controlX2; + fpath++; + *fpath = controlY2; + fpath++; + *fpath = cubicToX; + fpath++; + *fpath = cubicToY; + fpath++; + offset += _commandSize_float[VLC_OP_CUBIC_REL]; + i += _commandSize_float[VLC_OP_CUBIC_REL]; + + /* Determine the absolute coordinates. */ + controlX2 += coords.lastX; + controlY2 += coords.lastY; + cubicToX += coords.lastX; + cubicToY += coords.lastY; + + /* Update the control coordinates. */ + coords.lastX = cubicToX; + coords.lastY = cubicToY; + coords.controlX = controlX2; + coords.controlY = controlY2; + break; + case VLC_OP_SCUBIC: + controlX1 = *pfloat; + pfloat++; + controlY1 = *pfloat; + pfloat++; + cubicToX = *pfloat; + pfloat++; + cubicToY = *pfloat; + pfloat++; + i += _commandSize_float[VLC_OP_SCUBIC]; + /* Update the control coordinates. */ + VG_LITE_ERROR_HANDLER(_convert_scubic(cubicToX, cubicToY, controlX1, controlY1, VGL_FALSE, &coords, (void *)&pathdata, + &offset, path_length - i)); + break; + case VLC_OP_SCUBIC_REL: + controlX1 = *pfloat; + pfloat++; + controlY1 = *pfloat; + pfloat++; + cubicToX = *pfloat; + pfloat++; + cubicToY = *pfloat; + pfloat++; + i += _commandSize_float[VLC_OP_SCUBIC_REL]; + /* Update the control coordinates. */ + VG_LITE_ERROR_HANDLER(_convert_scubic(cubicToX, cubicToY, controlX1, controlY1, VGL_TRUE, &coords, (void *)&pathdata, + &offset, path_length - i)); + break; + case VLC_OP_HLINE: + lineToX = *pfloat; + pfloat++; + lineToY = coords.lastY; + i += _commandSize_float[VLC_OP_HLINE]; + /* Update the control coordinates. */ + VG_LITE_ERROR_HANDLER(_convert_hline(lineToX, lineToY, VGL_FALSE, &coords, (void *)&pathdata, &offset, + path_length - i)); + break; + case VLC_OP_HLINE_REL: + lineToX = *pfloat; + pfloat++; + lineToY = coords.lastY; + i += _commandSize_float[VLC_OP_HLINE_REL]; + /* Update the control coordinates. */ + VG_LITE_ERROR_HANDLER(_convert_hline(lineToX, lineToY, VGL_TRUE, &coords, (void *)&pathdata, &offset, path_length - i)); + break; + case VLC_OP_VLINE: + lineToX = coords.lastX; + lineToY = *pfloat; + pfloat++; + i += _commandSize_float[VLC_OP_VLINE]; + /* Update the control coordinates. */ + VG_LITE_ERROR_HANDLER(_convert_vline(lineToX, lineToY, VGL_FALSE, &coords, (void *)&pathdata, &offset, + path_length - i)); + break; + case VLC_OP_VLINE_REL: + lineToX = coords.lastX; + lineToY = *pfloat; + pfloat++; + i += _commandSize_float[VLC_OP_VLINE_REL]; + /* Update the control coordinates. */ + VG_LITE_ERROR_HANDLER(_convert_vline(lineToX, lineToY, VGL_TRUE, &coords, (void *)&pathdata, &offset, path_length - i)); + break; + case VLC_OP_SCCWARC: + horRadius = *pfloat; + pfloat++; + verRadius = *pfloat; + pfloat++; + rotAngle = *pfloat; + pfloat++; + endX = *pfloat; + pfloat++; + endY = *pfloat; + pfloat++; + i += _commandSize_float[VLC_OP_SCCWARC]; + VG_LITE_ERROR_HANDLER(_convert_arc(horRadius, verRadius, rotAngle, endX, endY, VGL_FALSE, VGL_FALSE, VGL_FALSE, &coords, + (void *)&pathdata, &offset, path_length - i)); + break; + case VLC_OP_SCCWARC_REL: + horRadius = *pfloat; + pfloat++; + verRadius = *pfloat; + pfloat++; + rotAngle = *pfloat; + pfloat++; + endX = *pfloat; + pfloat++; + endY = *pfloat; + pfloat++; + i += _commandSize_float[VLC_OP_SCCWARC_REL]; + VG_LITE_ERROR_HANDLER(_convert_arc(horRadius, verRadius, rotAngle, endX, endY, VGL_FALSE, VGL_FALSE, VGL_TRUE, &coords, + (void *)&pathdata, &offset, path_length - i)); + break; + case VLC_OP_SCWARC: + horRadius = *pfloat; + pfloat++; + verRadius = *pfloat; + pfloat++; + rotAngle = *pfloat; + pfloat++; + endX = *pfloat; + pfloat++; + endY = *pfloat; + pfloat++; + i += _commandSize_float[VLC_OP_SCCWARC_REL]; + VG_LITE_ERROR_HANDLER(_convert_arc(horRadius, verRadius, rotAngle, endX, endY, VGL_TRUE, VGL_FALSE, VGL_FALSE, &coords, + (void *)&pathdata, &offset, path_length - i)); + break; + case VLC_OP_SCWARC_REL: + horRadius = *pfloat; + pfloat++; + verRadius = *pfloat; + pfloat++; + rotAngle = *pfloat; + pfloat++; + endX = *pfloat; + pfloat++; + endY = *pfloat; + pfloat++; + i += _commandSize_float[VLC_OP_SCCWARC_REL]; + VG_LITE_ERROR_HANDLER(_convert_arc(horRadius, verRadius, rotAngle, endX, endY, VGL_TRUE, VGL_FALSE, VGL_TRUE, &coords, + (void *)&pathdata, &offset, path_length - i)); + break; + case VLC_OP_LCCWARC: + horRadius = *pfloat; + pfloat++; + verRadius = *pfloat; + pfloat++; + rotAngle = *pfloat; + pfloat++; + endX = *pfloat; + pfloat++; + endY = *pfloat; + pfloat++; + i += _commandSize_float[VLC_OP_SCCWARC_REL]; + VG_LITE_ERROR_HANDLER(_convert_arc(horRadius, verRadius, rotAngle, endX, endY, VGL_FALSE, VGL_TRUE, VGL_FALSE, &coords, + (void *)&pathdata, &offset, path_length - i)); + break; + case VLC_OP_LCCWARC_REL: + horRadius = *pfloat; + pfloat++; + verRadius = *pfloat; + pfloat++; + rotAngle = *pfloat; + pfloat++; + endX = *pfloat; + pfloat++; + endY = *pfloat; + pfloat++; + i += _commandSize_float[VLC_OP_SCCWARC_REL]; + VG_LITE_ERROR_HANDLER(_convert_arc(horRadius, verRadius, rotAngle, endX, endY, VGL_FALSE, VGL_TRUE, VGL_TRUE, &coords, + (void *)&pathdata, &offset, path_length - i)); + break; + case VLC_OP_LCWARC: + horRadius = *pfloat; + pfloat++; + verRadius = *pfloat; + pfloat++; + rotAngle = *pfloat; + pfloat++; + endX = *pfloat; + pfloat++; + endY = *pfloat; + pfloat++; + i += _commandSize_float[VLC_OP_SCCWARC_REL]; + VG_LITE_ERROR_HANDLER(_convert_arc(horRadius, verRadius, rotAngle, endX, endY, VGL_TRUE, VGL_TRUE, VGL_FALSE, &coords, + (void *)&pathdata, &offset, path_length - i)); + break; + case VLC_OP_LCWARC_REL: + horRadius = *pfloat; + pfloat++; + verRadius = *pfloat; + pfloat++; + rotAngle = *pfloat; + pfloat++; + endX = *pfloat; + pfloat++; + endY = *pfloat; + pfloat++; + i += _commandSize_float[VLC_OP_SCCWARC_REL]; + VG_LITE_ERROR_HANDLER(_convert_arc(horRadius, verRadius, rotAngle, endX, endY, VGL_TRUE, VGL_TRUE, VGL_TRUE, &coords, + (void *)&pathdata, &offset, path_length - i)); + break; + default: + break; + } + } + + if(path_data_fp32 != NULL) + vg_lite_os_free(path_data_fp32); + path->format = VG_LITE_FP32; + path->quality = quality; + path->path_length = offset; + path->path = pathdata; + path->pdata_internal = 1; + path->path_changed = 1; + path->uploaded.address = 0; + path->uploaded.bytes = 0; + path->uploaded.handle = NULL; + path->uploaded.memory = NULL; + s_context.path_lastX = coords.lastX; + s_context.path_lastY = coords.lastY; + return VG_LITE_SUCCESS; + +ErrorHandler: + vg_lite_os_free(pathdata); + pathdata = NULL; + return error; +} + +#else /* gcFEATURE_VG_ARC_PATH */ + +vg_lite_error_t vg_lite_init_arc_path(vg_lite_path_t * path, + vg_lite_format_t data_format, + vg_lite_quality_t quality, + vg_lite_uint32_t path_length, + vg_lite_pointer path_data, + vg_lite_float_t min_x, vg_lite_float_t min_y, + vg_lite_float_t max_x, vg_lite_float_t max_y) +{ + return VG_LITE_NOT_SUPPORT; +} + +#endif /* gcFEATURE_VG_ARC_PATH */ + +#endif /* LV_USE_VG_LITE_DRIVER */ + diff --git a/src/libs/vg_lite_driver/VGLiteKernel/vg_lite_debug.h b/src/libs/vg_lite_driver/VGLiteKernel/vg_lite_debug.h new file mode 100755 index 0000000000..9feb7c6de1 --- /dev/null +++ b/src/libs/vg_lite_driver/VGLiteKernel/vg_lite_debug.h @@ -0,0 +1,77 @@ +/**************************************************************************** +* +* Copyright 2012 - 2023 Vivante Corporation, Santa Clara, California. +* All Rights Reserved. +* +* Permission is hereby granted, free of charge, to any person obtaining +* a copy of this software and associated documentation files (the +* 'Software'), to deal in the Software without restriction, including +* without limitation the rights to use, copy, modify, merge, publish, +* distribute, sub license, and/or sell copies of the Software, and to +* permit persons to whom the Software is furnished to do so, subject +* to the following conditions: +* +* The above copyright notice and this permission notice (including the +* next paragraph) shall be included in all copies or substantial +* portions of the Software. +* +* THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND, +* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. +* IN NO EVENT SHALL VIVANTE AND/OR ITS SUPPLIERS BE LIABLE FOR ANY +* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, +* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE +* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +* +*****************************************************************************/ + +#ifndef VG_LITE_DEBUG_H +#define VG_LITE_DEBUG_H + +#include "../../../lv_conf_internal.h" +#if LV_USE_VG_LITE_DRIVER + +#include "vg_lite_kernel.h" + +#ifdef __cplusplus +extern "C" { +#endif + +#define vg_lite_kernel_print vg_lite_hal_trace +#define vg_lite_kernel_trace vg_lite_hal_trace +#define vg_lite_kernel_error vg_lite_hal_print +#define vg_lite_kernel_hintmsg vg_lite_hal_print + +#define VG_IS_SUCCESS(error) (error == VG_LITE_SUCCESS) +#define VG_IS_ERROR(error) (error != VG_LITE_SUCCESS) + +#define ONERROR(func) \ + do \ + { \ + error = func; \ + if (VG_IS_ERROR(error)) \ + { \ + vg_lite_kernel_error((char *)"ONERROR: status = %d(%s) %s(%d)\n", error, vg_lite_hal_Status2Name(error), __FUNCTION__, __LINE__); \ + goto on_error; \ + } \ + } \ + while (VG_FALSE) + +#define ASSERT(arg) \ + do \ + { \ + if (!(arg)) \ + { \ + error = VG_LITE_INVALID_ARGUMENT;\ + goto on_error; \ + } \ + } \ + while (VG_FALSE) + +#ifdef __cplusplus +} +#endif + +#endif /* LV_USE_VG_LITE_DRIVER */ + +#endif /* VG_LITE_DEBUG_H */ diff --git a/src/libs/vg_lite_driver/VGLiteKernel/vg_lite_hal.h b/src/libs/vg_lite_driver/VGLiteKernel/vg_lite_hal.h new file mode 100755 index 0000000000..182698815e --- /dev/null +++ b/src/libs/vg_lite_driver/VGLiteKernel/vg_lite_hal.h @@ -0,0 +1,332 @@ +/**************************************************************************** +* +* The MIT License (MIT) +* +* Copyright (c) 2014 - 2022 Vivante Corporation +* +* Permission is hereby granted, free of charge, to any person obtaining a +* copy of this software and associated documentation files (the "Software"), +* to deal in the Software without restriction, including without limitation +* the rights to use, copy, modify, merge, publish, distribute, sublicense, +* and/or sell copies of the Software, and to permit persons to whom the +* Software is furnished to do so, subject to the following conditions: +* +* The above copyright notice and this permission notice shall be included in +* all copies or substantial portions of the Software. +* +* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +* DEALINGS IN THE SOFTWARE. +* +***************************************************************************** +* +* The GPL License (GPL) +* +* Copyright (C) 2014 - 2022 Vivante Corporation +* +* This program is free software; you can redistribute it and/or +* modify it under the terms of the GNU General Public License +* as published by the Free Software Foundation; either version 2 +* of the License, or (at your option) any later version. +* +* This program is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with this program; if not, write to the Free Software Foundation, +* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +* +***************************************************************************** +* +* Note: This software is released under dual MIT and GPL licenses. A +* recipient may use this file under the terms of either the MIT license or +* GPL License. If you wish to use only one license not the other, you can +* indicate your decision by deleting one of the above license notices in your +* version of this file. +* +*****************************************************************************/ + +#ifndef VG_LITE_HAL_H +#define VG_LITE_HAL_H + +#include "../../../lv_conf_internal.h" +#if LV_USE_VG_LITE_DRIVER + +#define VGLITE_MEM_ALIGNMENT 128 + +#define VGLITE_EVENT_FRAME_END 2 + +#ifdef __cplusplus +extern "C" { +#endif +/*! + @brief Wait a number of milliseconds. + + @discussion + The VGLite hardware requires some waiting when changing clock frequencies or issuing a reset. This is the wrapper function + for the delay function. + + @param milliseconds + The number of milliseconds to wait. + */ +void vg_lite_hal_delay(uint32_t milliseconds); + +/*! + @brief Initialize the hardware. + + @discussion + The VGLite kernel knows how to program its own hardware, but in any SOC there might be additional control required for + turning on the power or initializing the clocks. This function gets called by the VGLite kernel before the VGLite graphics + hardware gets initialized by the VGLite kernel itself and allows for SOC power management control. + + The implementer should make sure that on exit of this function the power and clock to the VGLite graphics hardware is + turned on and stable. + */ +void vg_lite_hal_initialize(void); + +/*! + @brief Uninitialize the hardware. + + @discussion + The VGLite kernel knows how to program its own hardware, but in any SOC there might be additional control required for + turning off the power or uninitializing the clocks. This function gets called by the VGLite kernel after the VGLite + graphics hardware gets uninitialized by the VGLite kernel itself and allows for SOC power management control. + + On exit of this function it is okay to have the power and/or clock to the VGLite graphics hardware turned off. + */ +void vg_lite_hal_deinitialize(void); + +/*! + @brief Allocate contiguous video memory. + + @discussion + Any memory the VGLite graphics hardware will see should be allocated as contiguous memory. Any allocated memory will be + addressed through an opaque handle, usually a pointer to an opaque structure. The porting layer can put any information it + needs inside this structure. + + @param size + The number of bytes to allocate. + + @param pool + select the reserved memory pool + + @param logical + A pointer to a variable that will receive the logical address of the allocated memory for the CPU. + + @param gpu + A pointer to a variable that will receive the physical address of the allocated memory for the VGLite graphics hardware. + + @result + A pointer to an opaque structure that will be used as the memory handle. NULL should be returned if there is not + enough memory. + */ +vg_lite_error_t vg_lite_hal_allocate_contiguous(unsigned long size, vg_lite_vidmem_pool_t pool, void ** logical, + void ** klogical, uint32_t * physical, void ** node); + +/*! + @brief Free contiguous video memory. + + @discussion + Free the memory allocated by {@link vg_lite_hal_allocate_contiguous}. After this function returns, the associated memory + handle is no longer a valid handle. + + @param memory_handle + A pointer to an opaque structure returned by {@link vg_lite_hal_allocate_contiguous}. + */ +void vg_lite_hal_free_contiguous(void * memory_handle); + +/*! + @brief remove unfree node when continuously allocate buffer without free buffer. + + @discussion + Free the node allocated by {@link kmalloc}. After this function returns, the associated memory + handle is no longer a valid handle. + */ +void vg_lite_hal_free_os_heap(void); + +/*! + @brief Map contiguous logical or physical memory into the VGLite graphics hardware space. + + @discussion + Any memory, like a frame buffer or some pre-allocated image or path data, needs to be mapped into the VGLite graphics + hardware address space and wrapped by a memory handle. This allows the VGLite graphics hardware access that memory + directly. + + Either a logical or a physical address should be passed in to map. + + @param size + The number of bytes to map. + + @param logical + The logical address of the memory region to map or NULL if the logical address is not known. + + @param physical + The physical address of the memory region to map if logical is NULL. + + @param gpu + A pointer to a variable that will receive the VGLite graphics hardware addressable address of the mapped region. + + @result + A pointer to an opaque structure that will be used as the memory handle. NULL should be returned if there is + not enough system resources to map the region. + */ +void * vg_lite_hal_map(uint32_t flags, uint32_t bytes, void * logical, uint32_t physical, int32_t dma_buf_fd, + uint32_t * gpu); + +/*! + @brief Unmap a previously mapped region. + + @discussion + If a mapped region by {@link vg_lite_hal_map} is no longer needed, it should be unmapped to free up any allocated system + resources used when mapping the region. + + @param memory_handle + A pointer to an opaque structure returned by {@link vg_lite_hal_map}. + */ +void vg_lite_hal_unmap(void * memory_handle); + +/*! + @brief Execute a memory barrier. + + @discussion + Some systems require a a memory barrier to make sure all store operations in the CPU have been handled. This is the wrapper + function for a memory barrier. + */ +void vg_lite_hal_barrier(void); + +/*! + @brief Read data from a register from the VGLite graphics hardware. + + @discussion + In order to communicate with the VGLite graphics hardware, the kernel needs to read and write to some hardware registers. + In each SOC those registers could be allocated at a different space in the physical memory map. + + @param address + The relative address of the VGLite graphics hardware register to read from. + + @result + The 32-bit value returned from reading the register. + */ +uint32_t vg_lite_hal_peek(uint32_t address); + +/*! + @brief Write data to a register from the VGLite graphics hardware. + + @discussion + In order to communicate with the VGLite graphics hardware, the kernel needs to read and write to some hardware registers. + In each SOC those registers could be allocated at a different space in the physical memory map. + + @param address + The relative address of the VGLite graphics hardware register to write to. + + @param data + The data to write to the VGLite graphics hardware register. + */ +void vg_lite_hal_poke(uint32_t address, uint32_t data); + +/*! + @brief query the remaining allocate contiguous video memory. + + @param data + The data to get the remaining allocate contiguous video memory bytes. + */ +vg_lite_error_t vg_lite_hal_query_mem(vg_lite_kernel_mem_t * mem); + +/*! + @brief Map contiguous physical memory into the user space. + + @param node + This node have 3 attributes, bytes means the number of bytes to map. + physical means the physical address of the memory region to map.logical means + the return logical address of the memory region after map. + */ +vg_lite_error_t vg_lite_hal_map_memory(vg_lite_kernel_map_memory_t * node); + +/*! + @brief Unmap a previously mapped region. + + @param node + This node have 2 attributes, bytes means the number of bytes to unmap.logical means + the logical address of the memory region to unmap. + */ +vg_lite_error_t vg_lite_hal_unmap_memory(vg_lite_kernel_unmap_memory_t * node); + +/*! + @brief Wait until an interrupt from the VGLite graphics hardware has been received. + + @discussion + Currently, the VGLite API is synchronous. This means that after each call it will wait until the VGLite graphics hardware + has completed. The VGLite graphics hardware will send an interrupt when it is finished, and this function will wait until + that interrupt has been received by the operating system. + + A timeout value is specified in order if the kernel wants to wait for a specific number of milliseconds fir the interrupt to + occur. If the interrupt does not occur in the specified timeout, a timeout error will be returned. + + @param timeout + The number of milliseconds to wait for the interrupt before returning a timeout error. If timeout = 0xFFFFFFFF + then {@link vg_lite_hal_wait_interrupt} will wait forever for the interrupt. + + @param mask + Irq event mask to wait for. + + @result + A boolean value indicating whether the interrupt was received (1) or not (0). + */ +int32_t vg_lite_hal_wait_interrupt(uint32_t timeout, uint32_t mask, uint32_t * value); + +/*! + @brief After call vg_lite_hal_map(), flush cpu cache according the direction + spicified by parameter cache_op. + */ +vg_lite_error_t vg_lite_hal_operation_cache(void * handle, vg_lite_cache_op_t cache_op); + +/*! + @brief export memory to dma buf, and get the dma buf fd + */ +vg_lite_error_t vg_lite_hal_memory_export(int32_t * fd); + +/*! + @brief print message + */ +void vg_lite_hal_print(char * format, ...); + +/*! + @brief trace message + */ +void vg_lite_hal_trace(char * format, ...); + +/*! + @brief error number to string + */ +const char * vg_lite_hal_Status2Name(vg_lite_error_t status); + +/*! + @brief allocate virtual memory from os + */ +vg_lite_error_t vg_lite_hal_allocate(uint32_t size, void ** memory); + +/*! + @brief free virtual memory + */ +vg_lite_error_t vg_lite_hal_free(void * memory); + +/*! + @brief set gpu execute state + */ +void vg_lite_set_gpu_execute_state(vg_lite_gpu_execute_state_t state); + +#ifdef __cplusplus +} +#endif + +#endif /* LV_USE_VG_LITE_DRIVER */ + +#endif /* VG_LITE_HAL_H */ + + diff --git a/src/libs/vg_lite_driver/VGLiteKernel/vg_lite_hw.h b/src/libs/vg_lite_driver/VGLiteKernel/vg_lite_hw.h new file mode 100755 index 0000000000..a4c7332616 --- /dev/null +++ b/src/libs/vg_lite_driver/VGLiteKernel/vg_lite_hw.h @@ -0,0 +1,98 @@ +/**************************************************************************** +* +* The MIT License (MIT) +* +* Copyright (c) 2014 - 2022 Vivante Corporation +* +* Permission is hereby granted, free of charge, to any person obtaining a +* copy of this software and associated documentation files (the "Software"), +* to deal in the Software without restriction, including without limitation +* the rights to use, copy, modify, merge, publish, distribute, sublicense, +* and/or sell copies of the Software, and to permit persons to whom the +* Software is furnished to do so, subject to the following conditions: +* +* The above copyright notice and this permission notice shall be included in +* all copies or substantial portions of the Software. +* +* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +* DEALINGS IN THE SOFTWARE. +* +***************************************************************************** +* +* The GPL License (GPL) +* +* Copyright (C) 2014 - 2022 Vivante Corporation +* +* This program is free software; you can redistribute it and/or +* modify it under the terms of the GNU General Public License +* as published by the Free Software Foundation; either version 2 +* of the License, or (at your option) any later version. +* +* This program is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with this program; if not, write to the Free Software Foundation, +* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +* +***************************************************************************** +* +* Note: This software is released under dual MIT and GPL licenses. A +* recipient may use this file under the terms of either the MIT license or +* GPL License. If you wish to use only one license not the other, you can +* indicate your decision by deleting one of the above license notices in your +* version of this file. +* +*****************************************************************************/ + +#ifndef VG_LITE_HW_H +#define VG_LITE_HW_H + +#include "../../../lv_conf_internal.h" +#if LV_USE_VG_LITE_DRIVER + +#define VG_LITE_HW_CLOCK_CONTROL 0x000 +#define VG_LITE_HW_IDLE 0x004 +#define VG_LITE_INTR_STATUS 0x010 +#define VG_LITE_INTR_ENABLE 0x014 +#define VG_LITE_HW_CHIP_ID 0x020 +#define VG_LITE_HW_CMDBUF_ADDRESS 0x500 +#define VG_LITE_HW_CMDBUF_SIZE 0x504 +#define VG_LITE_POWER_CONTROL 0x100 +#define VG_LITE_POWER_MODULE_CONTROL 0x104 + +#define VG_LITE_EXT_WORK_CONTROL 0x520 +#define VG_LITE_EXT_VIDEO_SIZE 0x524 +#define VG_LITE_EXT_CLEAR_VALUE 0x528 + +#define VG_LITE_EXT_VIDEO_CONTROL 0x51C + +typedef struct clock_control { + uint32_t reserved0 : 1; + uint32_t clock_gate : 1; + uint32_t scale : 7; + uint32_t scale_load : 1; + uint32_t ram_clock_gating : 1; + uint32_t debug_registers : 1; + uint32_t soft_reset : 1; + uint32_t reserved13 : 6; + uint32_t isolate : 1; +} clock_control_t; + +typedef union vg_lite_hw_clock_control { + clock_control_t control; + uint32_t data; +} vg_lite_hw_clock_control_t; + +#define VG_LITE_HW_IDLE_STATE 0x0B05 + +#endif /* LV_USE_VG_LITE_DRIVER */ + +#endif /* VG_LITE_HW_H */ diff --git a/src/libs/vg_lite_driver/VGLiteKernel/vg_lite_kernel.c b/src/libs/vg_lite_driver/VGLiteKernel/vg_lite_kernel.c new file mode 100755 index 0000000000..012a02e911 --- /dev/null +++ b/src/libs/vg_lite_driver/VGLiteKernel/vg_lite_kernel.c @@ -0,0 +1,1387 @@ +/**************************************************************************** +* +* The MIT License (MIT) +* +* Copyright (c) 2014 - 2022 Vivante Corporation +* +* Permission is hereby granted, free of charge, to any person obtaining a +* copy of this software and associated documentation files (the "Software"), +* to deal in the Software without restriction, including without limitation +* the rights to use, copy, modify, merge, publish, distribute, sublicense, +* and/or sell copies of the Software, and to permit persons to whom the +* Software is furnished to do so, subject to the following conditions: +* +* The above copyright notice and this permission notice shall be included in +* all copies or substantial portions of the Software. +* +* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +* DEALINGS IN THE SOFTWARE. +* +***************************************************************************** +* +* The GPL License (GPL) +* +* Copyright (C) 2014 - 2022 Vivante Corporation +* +* This program is free software; you can redistribute it and/or +* modify it under the terms of the GNU General Public License +* as published by the Free Software Foundation; either version 2 +* of the License, or (at your option) any later version. +* +* This program is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with this program; if not, write to the Free Software Foundation, +* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +* +***************************************************************************** +* +* Note: This software is released under dual MIT and GPL licenses. A +* recipient may use this file under the terms of either the MIT license or +* GPL License. If you wish to use only one license not the other, you can +* indicate your decision by deleting one of the above license notices in your +* version of this file. +* +*****************************************************************************/ + +#include "../../../lv_conf_internal.h" +#if LV_USE_VG_LITE_DRIVER + +#include "../lv_vg_lite_hal/vg_lite_platform.h" +#include "vg_lite_kernel.h" +#include "vg_lite_hal.h" +#include "vg_lite_hw.h" +#if defined(__linux__) && !defined(EMULATOR) + #include + /*#include */ + #include + #include + #include + #include + #include +#endif + +#if gcdVG_RECORD_HARDWARE_RUNNING_TIME + + #ifdef __linux__ + #include + unsigned long start_time, end_time; + unsigned long period_time, total_time = 0; + + #else + #include + struct timeval start_time, end_time; + unsigned long period_time, total_time = 0; + #endif + +#endif + +#define FLEXA_TIMEOUT_STATE BIT(21) +#define FLEXA_HANDSHEKE_FAIL_STATE BIT(22) +#define MIN_TS_SIZE (8 << 10) + +#if gcdVG_ENABLE_BACKUP_COMMAND +# define STATE_COMMAND(address) (0x30010000 | address) +# define END_COMMAND(interrupt) (0x00000000 | interrupt) +# define SEMAPHORE_COMMAND(id) (0x10000000 | id) +# define STALL_COMMAND(id) (0x20000000 | id) + +static vg_lite_kernel_context_t global_power_context = {0}; +static uint32_t * power_context_klogical = NULL; +static uint32_t state_map_table[4096]; +static uint32_t backup_command_buffer_physical; +static void * backup_command_buffer_klogical; +static uint32_t backup_command_buffer_size; +uint32_t init_buffer[12]; +uint32_t is_init; +size_t physical_address; +#endif + +static int s_reference = 0; + +#if gcdVG_ENABLE_DELAY_RESUME + static int delay_resume = 0; +#endif + +#if gcdVG_ENABLE_GPU_RESET + static uint32_t gpu_reset_count = 0; +#endif + +static vg_lite_error_t do_terminate(vg_lite_kernel_terminate_t * data); +static vg_lite_error_t vg_lite_kernel_vidmem_allocate(uint32_t * bytes, uint32_t flags, vg_lite_vidmem_pool_t pool, + void ** memory, void ** kmemory, uint32_t * memory_gpu, void ** memory_handle); +static vg_lite_error_t vg_lite_kernel_vidmem_free(void * handle); +static void soft_reset(void); +static vg_lite_error_t do_wait(vg_lite_kernel_wait_t * data); + +#if gcdVG_ENABLE_BACKUP_COMMAND +static vg_lite_error_t restore_gpu_state(void); + +static vg_lite_error_t restore_init_command(uint32_t physical, uint32_t size) +{ + vg_lite_error_t error = VG_LITE_SUCCESS; + vg_lite_uint32_t total_suspend_time = 0; + vg_lite_uint32_t suspend_time_limit = 1000; + + /* flush cache. */ + vg_lite_hal_barrier(); + + vg_lite_hal_poke(VG_LITE_HW_CMDBUF_ADDRESS, physical); + vg_lite_hal_poke(VG_LITE_HW_CMDBUF_SIZE, (size + 7) / 8); + + while(!vg_lite_hal_peek(VG_LITE_INTR_STATUS)) { + vg_lite_hal_delay(2); + if(total_suspend_time < suspend_time_limit) { + total_suspend_time += 2; + } + else { + error = VG_LITE_TIMEOUT; + break; + } + } + vg_lite_hal_delay(2); + + return error; +} +#if gcdVG_ENABLE_GPU_RESET && gcdVG_ENABLE_BACKUP_COMMAND +static vg_lite_error_t execute_command(uint32_t physical, uint32_t size, vg_lite_gpu_reset_type_t reset_type) +{ + vg_lite_kernel_wait_t wait; + vg_lite_error_t error = VG_LITE_SUCCESS; + + wait.timeout_ms = 1000; + wait.event_mask = (uint32_t)~0; + wait.reset_type = reset_type; + + /* flush cache. */ + vg_lite_hal_barrier(); + + vg_lite_hal_poke(VG_LITE_HW_CMDBUF_ADDRESS, physical); + vg_lite_hal_poke(VG_LITE_HW_CMDBUF_SIZE, (size + 7) / 8); + + error = do_wait(&wait); + + return error; +} +#endif + +static uint32_t push_command(uint32_t command, uint32_t data, uint32_t index) +{ + uint32_t address = 0; + + if((command & 0xFFFF0000) == 0x30010000) { + address = command & 0x0000FFFF; + state_map_table[address] = index; + } + + if(NULL == power_context_klogical) + power_context_klogical = global_power_context.power_context_klogical; + + power_context_klogical[index++] = command; + power_context_klogical[index++] = data; + + return index; +} + +static vg_lite_error_t backup_power_context_buffer(uint32_t * command_buffer_klogical, uint32_t size) +{ + int index = 0; + uint32_t command = 0; + uint32_t address = 0; + uint32_t context_index = 0; + uint32_t data = 0; + + if(NULL == command_buffer_klogical) { + return VG_LITE_INVALID_ARGUMENT; + } + + for(index = 0; index < size; index++) { + command = command_buffer_klogical[index]; + + if(((command & 0xFFFF0000) == 0x30010000) && ((index % 2) == 0)) { + data = command_buffer_klogical[index + 1]; + address = command & 0x0000FFFF; + context_index = state_map_table[address]; + if((address < 0) || (address > 4095)) { + vg_lite_kernel_print("Index out of bounds, wrong address and data 0x%08X 0x%08X\n", command, data); + return VG_LITE_INVALID_ARGUMENT; + } + if(-1 != context_index) { + power_context_klogical[context_index + 1] = data; + } + else { + power_context_klogical[global_power_context.power_context_size / 4 + 0] = command; + power_context_klogical[global_power_context.power_context_size / 4 + 1] = data; + state_map_table[address] = global_power_context.power_context_size / 4; + global_power_context.power_context_size += 8; + } + } + } + + return VG_LITE_SUCCESS; +} +#endif + +static void gpu(int enable) +{ + vg_lite_hw_clock_control_t value; + uint32_t reset_timer = 2; + const uint32_t reset_timer_limit = 1000; +#if gcdVG_ENABLE_AUTO_CLOCK_GATING + uint32_t data; +#endif + + if(enable) { + /* Enable clock gating. */ + value.data = vg_lite_hal_peek(VG_LITE_HW_CLOCK_CONTROL); + value.control.clock_gate = 0; + vg_lite_hal_poke(VG_LITE_HW_CLOCK_CONTROL, value.data); + vg_lite_hal_delay(1); + + /* Set clock speed. */ + value.control.scale = 64; + value.control.scale_load = 1; + vg_lite_hal_poke(VG_LITE_HW_CLOCK_CONTROL, value.data); + vg_lite_hal_delay(1); + value.control.scale_load = 0; + vg_lite_hal_poke(VG_LITE_HW_CLOCK_CONTROL, value.data); + vg_lite_hal_delay(5); + +#if gcdVG_DUMP_DEBUG_REGISTER + value.control.debug_registers = 0; + vg_lite_hal_poke(VG_LITE_HW_CLOCK_CONTROL, value.data); +#endif + + /* Perform a soft reset. */ + soft_reset(); + do { + vg_lite_hal_delay(reset_timer); + reset_timer *= 2; // If reset failed, try again with a longer wait. Need to check why if dead lopp happens here. + } while(!VG_LITE_KERNEL_IS_GPU_IDLE()); + +#if gcdVG_ENABLE_AUTO_CLOCK_GATING + /* Enable Module Clock gating */ + data = vg_lite_hal_peek(VG_LITE_POWER_CONTROL); + data |= 0x1; + vg_lite_hal_poke(VG_LITE_POWER_CONTROL, data); + vg_lite_hal_delay(1); + +#if !gcFEATURE_VG_CLOCK_GATING_TS_MODULE + data = vg_lite_hal_peek(VG_LITE_POWER_MODULE_CONTROL); + data |= 0x800; + vg_lite_hal_poke(VG_LITE_POWER_MODULE_CONTROL, data); + vg_lite_hal_delay(1); +#endif + +#if !gcFEATURE_VG_CLOCK_GATING_VG_MODULE + data = vg_lite_hal_peek(VG_LITE_POWER_MODULE_CONTROL); + data |= 0x100; + vg_lite_hal_poke(VG_LITE_POWER_MODULE_CONTROL, data); + vg_lite_hal_delay(1); +#endif + +#endif + } + else { + while(!VG_LITE_KERNEL_IS_GPU_IDLE() && + (reset_timer < reset_timer_limit) // Force shutdown if timeout. + ) { + vg_lite_hal_delay(reset_timer); + reset_timer *= 2; + } + + /* Set idle speed. */ + value.data = vg_lite_hal_peek(VG_LITE_HW_CLOCK_CONTROL); + value.control.scale = 1; + value.control.scale_load = 1; + vg_lite_hal_poke(VG_LITE_HW_CLOCK_CONTROL, value.data); + vg_lite_hal_delay(1); + value.control.scale_load = 0; + vg_lite_hal_poke(VG_LITE_HW_CLOCK_CONTROL, value.data); + vg_lite_hal_delay(5); + + /* Disable clock gating. */ + value.control.clock_gate = 1; + vg_lite_hal_poke(VG_LITE_HW_CLOCK_CONTROL, value.data); + vg_lite_hal_delay(1); + } +} + +/* Initialize some customized modeuls [DDRLess]. */ +static vg_lite_error_t init_3rd(vg_lite_kernel_initialize_t * data) +{ + vg_lite_error_t error = VG_LITE_SUCCESS; + + /* TODO: Init the YUV<->RGB converters. Reserved for SOC. */ + /* vg_lite_hal_poke(0x00514, data->yuv_pre); + vg_lite_hal_poke(0x00518, data->yuv_post); + */ + return error; +} + +static vg_lite_error_t init_vglite(vg_lite_kernel_initialize_t * data) +{ + vg_lite_error_t error = VG_LITE_SUCCESS; + vg_lite_kernel_context_t * context; + vg_lite_uint32_t flags = 0, i; +#if gcdVG_ENABLE_BACKUP_COMMAND + vg_lite_uint32_t index; +#endif + +#if defined(__linux__) && !defined(EMULATOR) + vg_lite_kernel_context_t __user * context_usr; + vg_lite_kernel_context_t mycontext = { + .command_buffer = { 0 }, + .command_buffer_logical = { 0 }, + .command_buffer_klogical = { 0 }, + .command_buffer_physical = { 0 }, + }; + + // Construct the context. + context_usr = (vg_lite_kernel_context_t __user *) data->context; +#if LINUX_VERSION_CODE < KERNEL_VERSION(5, 0, 0) + if(!access_ok(VERIFY_READ, context_usr, sizeof(*context_usr)) || + !access_ok(VERIFY_WRITE, context_usr, sizeof(*context_usr))) { +#else + if(!access_ok(context_usr, sizeof(*context_usr)) || + !access_ok(context_usr, sizeof(*context_usr))) { +#endif + /* Out of memory. */ + return VG_LITE_OUT_OF_MEMORY; + } + context = &mycontext; +#else + // Construct the context. + context = data->context; + if(context == NULL) { + /* Out of memory. */ + return VG_LITE_OUT_OF_MEMORY; + } +#endif + + /* Zero out all pointers. */ + for(i = 0; i < CMDBUF_COUNT; i++) { + context->command_buffer[i] = NULL; + context->command_buffer_logical[i] = NULL; + context->command_buffer_physical[i] = 0; + } + context->tess_buffer = NULL; + context->tessbuf_logical = NULL; + context->tessbuf_physical = 0; +#if gcdVG_ENABLE_BACKUP_COMMAND + global_power_context.power_context_logical = NULL; + global_power_context.power_context_klogical = NULL; + global_power_context.power_context_physical = 0; + global_power_context.power_context = NULL; + global_power_context.power_context_capacity = 32 << 10; + global_power_context.power_context_size = 0; +#endif + /* Increment reference counter. */ + if(s_reference++ == 0) { + /* Initialize the SOC. */ + vg_lite_hal_initialize(); + + /* Enable the GPU. */ + gpu(1); + } + + /* Fill in hardware capabilities. */ + data->capabilities.data = 0; + + /* Allocate the command buffer. */ + if(data->command_buffer_size) { + for(i = 0; i < CMDBUF_COUNT; i ++) { + /* Allocate the memory. */ + error = vg_lite_kernel_vidmem_allocate(&data->command_buffer_size, + flags, + data->command_buffer_pool, + &context->command_buffer_logical[i], + &context->command_buffer_klogical[i], + &context->command_buffer_physical[i], + &context->command_buffer[i]); + if(error != VG_LITE_SUCCESS) { + /* Free any allocated memory. */ + vg_lite_kernel_terminate_t terminate = { context }; + do_terminate(&terminate); + + /* Out of memory. */ + ONERROR(error); + } + + /* Return command buffer logical pointer and GPU address. */ + data->command_buffer[i] = context->command_buffer_logical[i]; + data->command_buffer_gpu[i] = context->command_buffer_physical[i]; + } + } + +#if gcdVG_ENABLE_BACKUP_COMMAND + if(global_power_context.power_context_capacity) { + /* Allocate the backup buffer. */ + error = vg_lite_kernel_vidmem_allocate(&global_power_context.power_context_capacity, + flags, + VG_LITE_POOL_RESERVED_MEMORY1, + &global_power_context.power_context_logical, + &global_power_context.power_context_klogical, + &global_power_context.power_context_physical, + &global_power_context.power_context); + if(error != VG_LITE_SUCCESS) { + /* Free any allocated memory. */ + vg_lite_kernel_terminate_t terminate = { &global_power_context }; + do_terminate(&terminate); + + /* Out of memory. */ + ONERROR(error); + } + + /* Initialize power context buffer */ + for(i = 0; i < sizeof(state_map_table) / sizeof(state_map_table[0]); i++) + state_map_table[i] = -1; +#if (CHIPID==0x355 || CHIPID==0x255) + index = push_command(STATE_COMMAND(0x0A30), 0x00000000, 0); + index = push_command(STATE_COMMAND(0x0A31), 0x00000000, index); + index = push_command(STATE_COMMAND(0x0A32), 0x00000000, index); + index = push_command(STATE_COMMAND(0x0A33), 0x00000000, index); + index = push_command(STATE_COMMAND(0x0A35), 0x00000000, index); + index = push_command(STATE_COMMAND(0x0A36), 0x00000000, index); + index = push_command(STATE_COMMAND(0x0A37), 0x00000000, index); + index = push_command(STATE_COMMAND(0x0A38), 0x00000000, index); + index = push_command(STATE_COMMAND(0x0A3A), 0x00000000, index); + index = push_command(STATE_COMMAND(0x0A3D), 0x00000000, index); +#else + index = push_command(STATE_COMMAND(0x0A35), 0x00000000, 0); + index = push_command(STATE_COMMAND(0x0AC8), 0x00000000, index); + index = push_command(STATE_COMMAND(0x0ACB), 0x00000000, index); + index = push_command(STATE_COMMAND(0x0ACC), 0x00000000, index); +#endif + index = push_command(STATE_COMMAND(0x0A90), 0x00000000, index); + index = push_command(STATE_COMMAND(0x0A91), 0x00000000, index); + index = push_command(STATE_COMMAND(0x0A92), 0x00000000, index); + index = push_command(STATE_COMMAND(0x0A93), 0x00000000, index); + index = push_command(STATE_COMMAND(0x0A94), 0x00000000, index); + index = push_command(STATE_COMMAND(0x0A95), 0x00000000, index); + index = push_command(STATE_COMMAND(0x0A96), 0x00000000, index); + index = push_command(STATE_COMMAND(0x0A97), 0x00000000, index); + + index = push_command(STATE_COMMAND(0x0A10), 0x00000000, index); + index = push_command(STATE_COMMAND(0x0AC8), 0x00000000, index); + index = push_command(STATE_COMMAND(0x0AC8), 0x00000000, index); + index = push_command(STATE_COMMAND(0x0A5C), 0x00000000, index); + index = push_command(STATE_COMMAND(0x0A5D), 0x00000000, index); + index = push_command(STATE_COMMAND(0x0A11), 0x00000000, index); + index = push_command(STATE_COMMAND(0x0A12), 0x00000000, index); + index = push_command(STATE_COMMAND(0x0A13), 0x00000000, index); + + global_power_context.power_context_size = index * 4; + } +#endif + /* Allocate the tessellation buffer. */ + if((data->tess_width > 0) && (data->tess_height > 0)) { + int width = data->tess_width; + int height = 0; + int vg_countbuffer_size = 0, total_size = 0, ts_buffer_size = 0; + + height = VG_LITE_ALIGN(data->tess_height, 16); + +#if (CHIPID==0x355 || CHIPID==0x255) + { + unsigned long stride, buffer_size, l1_size, l2_size; +#if (CHIPID==0x355) + data->capabilities.cap.l2_cache = 1; + width = VG_LITE_ALIGN(width, 128); +#endif + /* Check if we can used tiled tessellation (128x16). */ + if(((width & 127) == 0) && ((height & 15) == 0)) { + data->capabilities.cap.tiled = 0x3; + } + else { + data->capabilities.cap.tiled = 0x2; + } + + /* Compute tessellation buffer size. */ + stride = VG_LITE_ALIGN(width * 8, 64); + buffer_size = VG_LITE_ALIGN(stride * height, 64); + /* Each bit in the L1 cache represents 64 bytes of tessellation data. */ + l1_size = VG_LITE_ALIGN(VG_LITE_ALIGN(buffer_size / 64, 64) / 8, 64); +#if (CHIPID==0x355) + /* Each bit in the L2 cache represents 32 bytes of L1 data. */ + l2_size = VG_LITE_ALIGN(VG_LITE_ALIGN(l1_size / 32, 64) / 8, 64); +#else + l2_size = 0; +#endif + total_size = buffer_size + l1_size + l2_size; + ts_buffer_size = buffer_size; + } +#else /* (CHIPID==0x355 || CHIPID==0x255) */ + { + /* Check if we can used tiled tessellation (128x16). */ + if(((width & 127) == 0) && ((height & 15) == 0)) { + data->capabilities.cap.tiled = 0x3; + } + else { + data->capabilities.cap.tiled = 0x2; + } + + vg_countbuffer_size = (height + 13) / 14; + vg_countbuffer_size = vg_countbuffer_size * 64; + total_size = height * 128 + vg_countbuffer_size; + if(total_size < MIN_TS_SIZE) + total_size = MIN_TS_SIZE; + ts_buffer_size = total_size - vg_countbuffer_size; + } +#endif /* (CHIPID==0x355 || CHIPID==0x255) */ + + /* Allocate the memory. */ + error = vg_lite_kernel_vidmem_allocate((uint32_t *)&total_size, + flags, + data->tess_buffer_pool, + &context->tessbuf_logical, + &context->tessbuf_klogical, + &context->tessbuf_physical, + &context->tess_buffer); + if(error != VG_LITE_SUCCESS) { + /* Free any allocated memory. */ + vg_lite_kernel_terminate_t terminate = { context }; + do_terminate(&terminate); + + /* Out of memory. */ + ONERROR(error); + } + + /* Return the tessellation buffer pointers and GPU addresses. */ + data->physical_addr = context->tessbuf_physical; + data->logical_addr = (uint8_t *)context->tessbuf_logical; + data->tessbuf_size = ts_buffer_size; + data->countbuf_size = vg_countbuffer_size; + data->tess_w_h = width | (height << 16); + } + +#if gcdVG_ENABLE_GPU_RESET + gpu_reset_count = 0; +#endif + vg_lite_set_gpu_execute_state(VG_LITE_GPU_STOP); + /* Enable all interrupts. */ + vg_lite_hal_poke(VG_LITE_INTR_ENABLE, 0xFFFFFFFF); + +#if defined(__linux__) && !defined(EMULATOR) + if(copy_to_user(context_usr, context, sizeof(vg_lite_kernel_context_t)) != 0) { + // Free any allocated memory. + vg_lite_kernel_terminate_t terminate = { context }; + do_terminate(&terminate); + + return VG_LITE_NO_CONTEXT; + } +#endif + +on_error: + return error; +} + +static vg_lite_error_t do_initialize(vg_lite_kernel_initialize_t * data) +{ + vg_lite_error_t error = VG_LITE_SUCCESS; + /* Free any allocated memory for the context. */ + do { + error = init_vglite(data); + if(error != VG_LITE_SUCCESS) + break; + + error = init_3rd(data); + if(error != VG_LITE_SUCCESS) + break; + } while(0); + + return error; +} + +static vg_lite_error_t terminate_vglite(vg_lite_kernel_terminate_t * data) +{ + vg_lite_kernel_context_t * context = NULL; +#if defined(__linux__) && !defined(EMULATOR) + vg_lite_kernel_context_t mycontext = { + .command_buffer = { 0 }, + .command_buffer_logical = { 0 }, + .command_buffer_klogical = { 0 }, + .command_buffer_physical = { 0 }, + }; + if(copy_from_user(&mycontext, data->context, sizeof(vg_lite_kernel_context_t)) != 0) { + return VG_LITE_NO_CONTEXT; + } + context = &mycontext; +#else + context = data->context; +#endif + + /* Free any allocated memory for the context. */ + if(context->command_buffer[0]) { + /* Free the command buffer. */ + vg_lite_kernel_vidmem_free(context->command_buffer[0]); + context->command_buffer[0] = NULL; + } + +#if !gcFEATURE_VG_SINGLE_COMMAND_BUFFER + if(context->command_buffer[1]) { + /* Free the command buffer. */ + vg_lite_kernel_vidmem_free(context->command_buffer[1]); + context->command_buffer[1] = NULL; + } +#endif + +#if gcdVG_ENABLE_BACKUP_COMMAND + if(global_power_context.power_context) { + /* Free the power context. */ + vg_lite_kernel_vidmem_free(global_power_context.power_context); + global_power_context.power_context = NULL; + } +#endif + if(context->tess_buffer) { + /* Free the tessellation buffer. */ + vg_lite_kernel_vidmem_free(context->tess_buffer); + context->tess_buffer = NULL; + } + vg_lite_hal_free_os_heap(); + /* Decrement reference counter. */ + if(--s_reference == 0) { + /* Disable the GPU. */ + gpu(0); + + /* De-initialize the SOC. */ + vg_lite_hal_deinitialize(); + } + +#if defined(__linux__) && !defined(EMULATOR) + if(copy_to_user((vg_lite_kernel_context_t __user *) data->context, + &mycontext, sizeof(vg_lite_kernel_context_t)) != 0) { + return VG_LITE_NO_CONTEXT; + } +#endif + return VG_LITE_SUCCESS; +} + +static vg_lite_error_t terminate_3rd(vg_lite_kernel_terminate_t * data) +{ + /* TODO: Terminate the converters. */ + + return VG_LITE_SUCCESS; +} + +static vg_lite_error_t do_terminate(vg_lite_kernel_terminate_t * data) +{ + terminate_vglite(data); + terminate_3rd(data); + + return VG_LITE_SUCCESS; +} + +static vg_lite_error_t vg_lite_kernel_vidmem_allocate(uint32_t * bytes, uint32_t flags, vg_lite_vidmem_pool_t pool, + void ** memory, void ** kmemory, uint32_t * memory_gpu, void ** memory_handle) +{ + vg_lite_error_t error = VG_LITE_SUCCESS; + + error = vg_lite_hal_allocate_contiguous(*bytes, pool, memory, kmemory, memory_gpu, memory_handle); + if(VG_IS_ERROR(error)) { + ONERROR(error); + } + + return error; +on_error: + return error; +} + +static vg_lite_error_t vg_lite_kernel_vidmem_free(void * handle) +{ + vg_lite_error_t error = VG_LITE_SUCCESS; + + vg_lite_hal_free_contiguous(handle); + + return error; +} + +static vg_lite_error_t do_allocate(vg_lite_kernel_allocate_t * data) +{ + vg_lite_error_t error = VG_LITE_SUCCESS; + + error = vg_lite_kernel_vidmem_allocate(&data->bytes, data->flags, data->pool, &data->memory, &data->kmemory, + &data->memory_gpu, &data->memory_handle); + + return error; +} + +static vg_lite_error_t do_free(vg_lite_kernel_free_t * data) +{ + vg_lite_error_t error = VG_LITE_SUCCESS; + + error = vg_lite_kernel_vidmem_free(data->memory_handle); + + return error; +} + +static vg_lite_error_t do_submit(vg_lite_kernel_submit_t * data) +{ + uint32_t offset; + vg_lite_kernel_context_t * context = NULL; + uint32_t physical = data->context->command_buffer_physical[data->command_id]; + +#if defined(__linux__) && !defined(EMULATOR) + vg_lite_kernel_context_t mycontext = { + .command_buffer = { 0 }, + .command_buffer_logical = { 0 }, + .command_buffer_klogical = { 0 }, + .command_buffer_physical = { 0 }, + }; + + if(copy_from_user(&mycontext, data->context, sizeof(vg_lite_kernel_context_t)) != 0) { + return VG_LITE_NO_CONTEXT; + } + context = &mycontext; + physical = context->command_buffer_physical[data->command_id]; +#else + context = data->context; + if(context == NULL) { + return VG_LITE_NO_CONTEXT; + } +#endif + /* Perform a memory barrier. */ + vg_lite_hal_barrier(); + + offset = (uint8_t *) data->commands - (uint8_t *)context->command_buffer_logical[data->command_id]; + +#if gcdVG_ENABLE_BACKUP_COMMAND + backup_power_context_buffer((uint32_t *)((uint8_t *)context->command_buffer_klogical[data->command_id] + offset), + (data->command_size + 3) / 4); + backup_command_buffer_physical = physical + offset; + backup_command_buffer_klogical = (uint32_t *)((uint8_t *)context->command_buffer_klogical[data->command_id] + offset); + backup_command_buffer_size = data->command_size; +#endif + +#if gcdVG_RECORD_HARDWARE_RUNNING_TIME +#ifdef __linux__ + start_time = jiffies; +#else + gettimeofday(&start_time, NULL); +#endif +#endif + + /* set gpu to busy state */ + vg_lite_set_gpu_execute_state(VG_LITE_GPU_RUN); + + /* Write the registers to kick off the command execution (CMDBUF_SIZE). */ + vg_lite_hal_poke(VG_LITE_HW_CMDBUF_ADDRESS, physical + offset); + vg_lite_hal_poke(VG_LITE_HW_CMDBUF_SIZE, (data->command_size + 7) / 8); + + return VG_LITE_SUCCESS; +} + +#if gcdVG_ENABLE_DUMP_COMMAND && gcdVG_ENABLE_BACKUP_COMMAND +static void dump_last_frame(void) +{ + uint32_t * ptr = backup_command_buffer_klogical; + uint32_t size = backup_command_buffer_size; + uint32_t i = 0; + uint32_t data = 0; + + vg_lite_kernel_print("This is init command buffer:\n"); + vg_lite_kernel_print("@[%s 0x%08X 0x00000088\n", "command", physical_address); + vg_lite_kernel_print(" 0x30010A35 0x%08X 0x30010AC8 0x%08X\n", init_buffer[0], init_buffer[1]); + vg_lite_kernel_print(" 0x30010ACB 0x%08X 0x30010ACC 0x%08X\n", init_buffer[2], init_buffer[3]); + vg_lite_kernel_print(" 0x30010A90 0x%08X 0x30010A91 0x%08X\n", init_buffer[4], init_buffer[5]); + vg_lite_kernel_print(" 0x30010A92 0x%08X 0x30010A93 0x%08X\n", init_buffer[6], init_buffer[7]); + vg_lite_kernel_print(" 0x30010A94 0x%08X 0x30010A95 0x%08X\n", init_buffer[8], init_buffer[9]); + vg_lite_kernel_print(" 0x30010A96 0x%08X 0x30010A97 0x%08X\n", init_buffer[10], init_buffer[11]); + vg_lite_kernel_print(" 0x30010A00 0x00000001 0x30010A1B 0x00000011\n"); + vg_lite_kernel_print(" 0x10000007 0x00000000 0x20000007 0x00000000\n"); + vg_lite_kernel_print(" 0x00000000 0x00000000\n"); + vg_lite_kernel_print("] -- %s\n", "command"); + + if(is_init == 1) { + vg_lite_kernel_print("the last submit command is init command.\n"); + } + else { + vg_lite_kernel_print("the last submit command before hang:\n"); + vg_lite_kernel_print("@[%s 0x%08X 0x%08X\n", "command", backup_command_buffer_klogical, size); + for(i = 0; i < size; i += 4) { + vg_lite_kernel_print(" 0x%08X 0x%08X 0x%08X 0x%08X\n", ptr[i], ptr[i + 1], ptr[i + 2], ptr[i + 3]); + } + if(size % 16) { + int j = size % 16 / 4; + switch(j) { + case 1: + vg_lite_kernel_print(" 0x%08X\n", ptr[(size - size % 16) / 4]); + break; + case 2: + vg_lite_kernel_print(" 0x%08X 0x%08X\n", ptr[(size - size % 16) / 4], ptr[(size - size % 16) / 4 + 1]); + break; + case 3: + vg_lite_kernel_print(" 0x%08X 0x%08X 0x%08X\n", ptr[(size - size % 16) / 4], ptr[(size - size % 16) / 4 + 1], + ptr[(size - size % 16) / 4 + 2]); + break; + default: + break; + } + } + } + vg_lite_kernel_print("] -- %s\n", "command"); + + data = vg_lite_hal_peek(VG_LITE_HW_IDLE); + vg_lite_kernel_print("vgidle reg = 0x%08X\n", data); +} +#endif + +static vg_lite_error_t do_wait(vg_lite_kernel_wait_t * data) +{ +#if gcdVG_ENABLE_GPU_RESET && gcdVG_ENABLE_BACKUP_COMMAND + vg_lite_error_t error = VG_LITE_SUCCESS; +#endif + /* Wait for interrupt. */ +#if gcdVG_DUMP_DEBUG_REGISTER + if(!vg_lite_hal_wait_interrupt(5000, data->event_mask, &data->event_got)) { + /* Timeout. */ + unsigned int debug; + unsigned int iter; + + debug = vg_lite_hal_peek(VG_LITE_HW_IDLE); + vg_lite_kernel_print("idle = 0x%x\n", debug); + + debug = vg_lite_hal_peek(VG_LITE_HW_CLOCK_CONTROL); + vg_lite_kernel_print("QAHiClockControl = 0x%x\n", debug); + + for(iter = 0; iter < 16 ; iter ++) { + vg_lite_hal_poke(0x470, iter); + debug = vg_lite_hal_peek(0x448); + vg_lite_kernel_print("0x448[%d] = 0x%x\n", iter, debug); + } + for(iter = 0; iter < 16 ; iter ++) { + vg_lite_hal_poke(0x470, iter << 8); + debug = vg_lite_hal_peek(0x44C); + vg_lite_kernel_print("0x44c[%d] = 0x%x\n", iter, debug); + } + for(iter = 0; iter < 28 ; iter ++) { + vg_lite_hal_poke(0x470, iter << 16); + debug = vg_lite_hal_peek(0x450); + vg_lite_kernel_print("0x450[%d] = 0x%x\n", iter, debug); + } + for(iter = 0; iter < 31; iter++) { + vg_lite_hal_poke(0x470, iter << 24); + debug = vg_lite_hal_peek(0x454); + vg_lite_kernel_print("0x454[%d] = 0x%x\n", iter, debug); + } + for(iter = 128; iter < 133; iter++) { + vg_lite_hal_poke(0x470, iter << 24); + debug = vg_lite_hal_peek(0x454); + vg_lite_kernel_print("0x454[%d] = 0x%x\n", iter, debug); + } + for(iter = 0; iter < 21; iter++) { + vg_lite_hal_poke(0x474, iter); + debug = vg_lite_hal_peek(0x458); + vg_lite_kernel_print("0x458[%d] = 0x%x\n", iter, debug); + } + for(iter = 0; iter < 62; iter++) { + vg_lite_hal_poke(0x474, iter << 8); + debug = vg_lite_hal_peek(0x45C); + vg_lite_kernel_print("0x45C[%d] = 0x%x\n", iter, debug); + } + for(iter = 0; iter < 16; iter++) { + vg_lite_hal_poke(0x474, iter << 16); + debug = vg_lite_hal_peek(0x460); + vg_lite_kernel_print("0x460[%d] = 0x%x\n", iter, debug); + } + for(iter = 0x40; iter <= 0x60; iter += 4) { + debug = vg_lite_hal_peek(iter); + vg_lite_kernel_print("0x%x = 0x%x\n", iter, debug); + } + + debug = vg_lite_hal_peek(0x438); + vg_lite_kernel_print("0x%x = 0x%x\n", 0x438, debug); + debug = vg_lite_hal_peek(0x43C); + vg_lite_kernel_print("0x%x = 0x%x\n", 0x43C, debug); + debug = vg_lite_hal_peek(0x440); + vg_lite_kernel_print("0x%x = 0x%x\n", 0x440, debug); + debug = vg_lite_hal_peek(0x444); + vg_lite_kernel_print("0x%x = 0x%x\n", 0x444, debug); + debug = vg_lite_hal_peek(0x500); + vg_lite_kernel_print("0x%x = 0x%x\n", 0x500, debug); + debug = vg_lite_hal_peek(0x504); + vg_lite_kernel_print("0x%x = 0x%x\n", 0x504, debug); + debug = vg_lite_hal_peek(0x508); + vg_lite_kernel_print("0x%x = 0x%x\n", 0x508, debug); + debug = vg_lite_hal_peek(0x10); + vg_lite_kernel_print("0x%x = 0x%x\n", 0x10, debug); + + for(iter = 0x14; iter <= 0x34; iter += 4) { + debug = vg_lite_hal_peek(iter); + vg_lite_kernel_print("0x%x = 0x%08x\n", iter, debug); + } + + debug = vg_lite_hal_peek(0x98); + vg_lite_kernel_print("0x%x = 0x%08x\n", 0x98, debug); + debug = vg_lite_hal_peek(0xA4); + vg_lite_kernel_print("0x%x = 0x%08x\n", 0xA4, debug); + debug = vg_lite_hal_peek(0xA8); + vg_lite_kernel_print("0x%x = 0x%08x\n", 0xA8, debug); + debug = vg_lite_hal_peek(0xE8); + vg_lite_kernel_print("0x%x = 0x%08x\n", 0xE8, debug); +#if gcdVG_ENABLE_DUMP_COMMAND && gcdVG_ENABLE_BACKUP_COMMAND + dump_last_frame(); +#endif + return VG_LITE_TIMEOUT; + } +#else + if(!vg_lite_hal_wait_interrupt(data->timeout_ms, data->event_mask, &data->event_got)) { + /* Timeout. */ + unsigned int debug; + debug = vg_lite_hal_peek(VG_LITE_HW_IDLE); + if(!VG_LITE_KERNEL_IS_GPU_IDLE()) { + vg_lite_kernel_print("GPU hang.\n"); + vg_lite_kernel_print("GPU idle register = 0x%x\n", debug); + } + +#if gcdVG_ENABLE_DUMP_COMMAND && gcdVG_ENABLE_BACKUP_COMMAND + dump_last_frame(); +#endif + +#if gcdVG_ENABLE_GPU_RESET && gcdVG_ENABLE_BACKUP_COMMAND + gpu_reset_count++; + if(gpu_reset_count <= 1) { + if(data->reset_type == RESTORE_INIT_COMMAND) { + error = VG_LITE_SUCCESS; + } + else if(data->reset_type == RESTORE_LAST_COMMAND) { + error = VG_LITE_SUCCESS; + } + else if(data->reset_type == RESTORE_ALL_COMMAND) { + /* reset and enable the GPU interrupt */ + gpu(1); + vg_lite_hal_poke(VG_LITE_INTR_ENABLE, 0xFFFFFFFF); + /* restore gpu state */ + error = execute_command(global_power_context.power_context_physical, global_power_context.power_context_size + 32, + RESTORE_INIT_COMMAND); + error = execute_command(backup_command_buffer_physical, backup_command_buffer_size, RESTORE_LAST_COMMAND); + } + else { + error = VG_LITE_TIMEOUT; + } + gpu_reset_count = 0; + return error; + } + vg_lite_kernel_print("GPU reset fail!\n"); +#endif + return VG_LITE_TIMEOUT; + } +#endif + +#if gcFEATURE_VG_FLEXA + if(data->event_got & FLEXA_TIMEOUT_STATE) + return VG_LITE_FLEXA_TIME_OUT; + + if(data->event_got & FLEXA_HANDSHEKE_FAIL_STATE) + return VG_LITE_FLEXA_HANDSHAKE_FAIL; +#endif + + /* set gpu to idle state */ + vg_lite_set_gpu_execute_state(VG_LITE_GPU_STOP); + + return VG_LITE_SUCCESS; +} + +#if gcdVG_ENABLE_BACKUP_COMMAND +static vg_lite_error_t restore_gpu_state(void) +{ + vg_lite_error_t error = VG_LITE_SUCCESS; + int i = 0; + uint32_t total_size = 0; + + power_context_klogical[global_power_context.power_context_size / 4 + 0] = 0x30010A1B; + power_context_klogical[global_power_context.power_context_size / 4 + 1] = 0x00000001; + power_context_klogical[global_power_context.power_context_size / 4 + 2] = 0x10000007; + power_context_klogical[global_power_context.power_context_size / 4 + 3] = 0x00000000; + power_context_klogical[global_power_context.power_context_size / 4 + 4] = 0x20000007; + power_context_klogical[global_power_context.power_context_size / 4 + 5] = 0x00000000; + power_context_klogical[global_power_context.power_context_size / 4 + 6] = 0x00000000; + power_context_klogical[global_power_context.power_context_size / 4 + 7] = 0x00000000; + total_size = global_power_context.power_context_size + 32; + + vg_lite_kernel_print("after resume and the power_context is:\n"); + for(i = 0; i < total_size / 4; i += 4) { + vg_lite_kernel_print("0x%08X 0x%08X", + power_context_klogical[i], power_context_klogical[i + 1]); + if((i + 2) <= (total_size / 4 - 1)) +#if defined(__linux__) + vg_lite_kernel_print(KERN_CONT " 0x%08X 0x%08X\n", + power_context_klogical[i + 2], power_context_klogical[i + 3]); +#else + vg_lite_kernel_print(" 0x%08X 0x%08X\n", + power_context_klogical[i + 2], power_context_klogical[i + 3]); +#endif + } + vg_lite_kernel_print("global_power_context size = %d\n", total_size); + + /* submit the backup power context */ + error = restore_init_command(global_power_context.power_context_physical, total_size); + if(error == VG_LITE_SUCCESS) + vg_lite_kernel_print("Initialize the GPU state success!\n"); + + /* submit last frame before suspend */ + /*error = restore_init_command(backup_command_buffer_physical, backup_command_buffer_size); + if (error == VG_LITE_SUCCESS) + vg_lite_kernel_print("Initialize the GPU state success!\n");*/ + + return error; +} +#endif + +static vg_lite_error_t do_reset(vg_lite_kernel_reset_t * data) +{ +#if gcdVG_ENABLE_DELAY_RESUME + if(data->delay_resume_flag == 1) { + /* If delay resume is enabled, power and clock should be turned on first.*/ + vg_lite_hal_initialize(); + } +#endif + /* reset and enable the GPU interrupt */ + gpu(1); + +#if gcdVG_ENABLE_BACKUP_COMMAND + restore_gpu_state(); +#endif + + vg_lite_hal_poke(VG_LITE_INTR_ENABLE, 0xFFFFFFFF); + + return VG_LITE_SUCCESS; +} + +static vg_lite_error_t do_gpu_close(void) +{ + gpu(0); + + vg_lite_kernel_hintmsg("gpu is shutdown!\n"); + + return VG_LITE_SUCCESS; +} + +static vg_lite_error_t do_debug(void) +{ + return VG_LITE_SUCCESS; +} + +static vg_lite_error_t do_map(vg_lite_kernel_map_t * data) +{ + data->memory_handle = vg_lite_hal_map(data->flags, data->bytes, data->logical, data->physical, data->dma_buf_fd, + &data->memory_gpu); + if(data->memory_handle == NULL) + return VG_LITE_OUT_OF_RESOURCES; + else if((long)data->memory_handle == (long) -1) + return VG_LITE_NOT_SUPPORT; + else + return VG_LITE_SUCCESS; +} + +static vg_lite_error_t do_unmap(vg_lite_kernel_unmap_t * data) +{ + vg_lite_hal_unmap(data->memory_handle); + + return VG_LITE_SUCCESS; +} + +static vg_lite_error_t do_peek(vg_lite_kernel_info_t * data) +{ + data->reg = vg_lite_hal_peek(data->addr); + + return VG_LITE_SUCCESS; +} + +#if gcFEATURE_VG_FLEXA +static vg_lite_error_t do_flexa_enable(vg_lite_kernel_flexa_info_t * data) +{ + /* reset all flexa states */ + vg_lite_hal_poke(0x03600, 0x0); + /* set sync mode */ + vg_lite_hal_poke(0x03604, data->segment_address); + + vg_lite_hal_poke(0x03608, data->segment_count); + + vg_lite_hal_poke(0x0360C, data->segment_size); + + vg_lite_hal_poke(0x0520, data->sync_mode); + + vg_lite_hal_poke(0x03610, data->stream_id | data->sbi_mode | data->start_flag | data->stop_flag | data->reset_flag); + + return VG_LITE_SUCCESS; +} + +static vg_lite_error_t do_flexa_set_background_address(vg_lite_kernel_flexa_info_t * data) +{ + vg_lite_hal_poke(0x03604, data->segment_address); + + vg_lite_hal_poke(0x03608, data->segment_count); + + vg_lite_hal_poke(0x0360C, data->segment_size); + + vg_lite_hal_poke(0x03610, data->stream_id | data->sbi_mode | data->start_flag | data->stop_flag | data->reset_flag); + + return VG_LITE_SUCCESS; +} + +static vg_lite_error_t do_flexa_disable(vg_lite_kernel_flexa_info_t * data) +{ + + vg_lite_hal_poke(0x0520, data->sync_mode); + + vg_lite_hal_poke(0x03610, data->stream_id | data->sbi_mode); + + /* reset all flexa states */ + vg_lite_hal_poke(0x03600, 0x0); + + return VG_LITE_SUCCESS; +} + +static vg_lite_error_t do_flexa_stop_frame(vg_lite_kernel_flexa_info_t * data) +{ + vg_lite_hal_poke(0x03610, data->stream_id | data->sbi_mode | data->start_flag | data->stop_flag | data->reset_flag); + + return VG_LITE_SUCCESS; +} +#endif + +static vg_lite_error_t do_query_mem(vg_lite_kernel_mem_t * data) +{ + vg_lite_error_t error = VG_LITE_SUCCESS; + error = vg_lite_hal_query_mem(data); + + return error; +} + +#if gcdVG_ENABLE_DELAY_RESUME +static vg_lite_error_t set_delay_resume(vg_lite_kernel_delay_resume_t * data) +{ + delay_resume = data->set_delay_resume; + + return VG_LITE_SUCCESS; +} + +static int do_query_delay_resume(void) +{ + if(delay_resume == 1) { + /* Reset delay resume to 0 after query*/ + delay_resume = 0; + return 1; + } + else + return 0; +} + +static int set_gpu_clock_state(vg_lite_kernel_gpu_clock_state_t * gpu_state) +{ +#ifdef __ZEPHYR__ + vg_lite_gpu_execute_state_t state = gpu_state->state; + vg_lite_set_gpu_clock_state(state); +#endif + return VG_LITE_SUCCESS; +} +#endif + +static vg_lite_error_t do_map_memory(vg_lite_kernel_map_memory_t * data) +{ + vg_lite_error_t error = VG_LITE_SUCCESS; + error = vg_lite_hal_map_memory(data); + + return error; +} + +static vg_lite_error_t do_unmap_memory(vg_lite_kernel_unmap_memory_t * data) +{ + vg_lite_error_t error = VG_LITE_SUCCESS; + error = vg_lite_hal_unmap_memory(data); + + return error; +} + +static vg_lite_error_t do_cache(vg_lite_kernel_cache_t * data) +{ + vg_lite_error_t error = VG_LITE_SUCCESS; + error = vg_lite_hal_operation_cache(data->memory_handle, data->cache_op); + + return error; +} + +static vg_lite_error_t do_export_memory(vg_lite_kernel_export_memory_t * data) +{ + vg_lite_error_t error = VG_LITE_SUCCESS; + + error = vg_lite_hal_memory_export(&data->fd); + + return error; +} + +static vg_lite_error_t do_get_running_time(vg_lite_kernel_hardware_running_time_t * data) +{ + vg_lite_error_t error = VG_LITE_SUCCESS; +#if gcdVG_RECORD_HARDWARE_RUNNING_TIME +#ifdef __linux__ + data->run_time = total_time; + data->hertz = HZ; +#else + data->run_time = total_time; + data->hertz = 1e6; +#endif +#endif + return error; +} + +vg_lite_error_t record_running_time(void) +{ + vg_lite_error_t error = VG_LITE_SUCCESS; + +#if gcdVG_RECORD_HARDWARE_RUNNING_TIME + +#ifdef __linux__ + end_time = jiffies; + period_time = end_time - start_time; + total_time += period_time; + +#else + gettimeofday(&end_time, NULL); + period_time = (end_time.tv_sec - start_time.tv_sec) * 1e6 + end_time.tv_usec - start_time.tv_usec; + total_time += period_time; + //printk("GPU hardware running period time: %f s\n", (float)period_time/1e-6); + //printk("GPU hardware running total time: %f s\n", (float)total_time/1e-6); +#endif + +#endif + + return error; +} + +static void soft_reset(void) +{ + vg_lite_hw_clock_control_t value; + value.data = vg_lite_hal_peek(VG_LITE_HW_CLOCK_CONTROL); + + /* Perform a soft reset. */ + value.control.isolate = 1; + vg_lite_hal_poke(VG_LITE_HW_CLOCK_CONTROL, value.data); + value.control.soft_reset = 1; + vg_lite_hal_poke(VG_LITE_HW_CLOCK_CONTROL, value.data); + vg_lite_hal_delay(5); + value.control.soft_reset = 0; + vg_lite_hal_poke(VG_LITE_HW_CLOCK_CONTROL, value.data); + value.control.isolate = 0; + vg_lite_hal_poke(VG_LITE_HW_CLOCK_CONTROL, value.data); +} + +vg_lite_error_t vg_lite_kernel(vg_lite_kernel_command_t command, void * data) +{ + /* Dispatch on command. */ + switch(command) { + case VG_LITE_INITIALIZE: + /* Initialize the context. */ + return do_initialize(data); + + case VG_LITE_TERMINATE: + /* Terminate the context. */ + return do_terminate(data); + + case VG_LITE_ALLOCATE: + /* Allocate contiguous memory. */ + return do_allocate(data); + + case VG_LITE_FREE: + /* Free contiguous memory. */ + return do_free(data); + + case VG_LITE_SUBMIT: + /* Submit a command buffer. */ + return do_submit(data); + + case VG_LITE_WAIT: + /* Wait for the GPU. */ + return do_wait(data); + + case VG_LITE_RESET: + /* Reset the GPU. */ + return do_reset(data); + + case VG_LITE_DEBUG: + /* Perform debugging features. */ + return do_debug(); + + case VG_LITE_MAP: + /* Map some memory. */ + return do_map(data); + + case VG_LITE_UNMAP: + /* Unmap some memory. */ + return do_unmap(data); + + /* Get register info. */ + case VG_LITE_CHECK: + /* Get register value. */ + return do_peek(data); + +#if gcFEATURE_VG_FLEXA + case VG_LITE_FLEXA_DISABLE: + /* Write register value. */ + return do_flexa_disable(data); + + case VG_LITE_FLEXA_ENABLE: + /* Write register value. */ + return do_flexa_enable(data); + + case VG_LITE_FLEXA_STOP_FRAME: + /* Write register value. */ + return do_flexa_stop_frame(data); + + case VG_LITE_FLEXA_SET_BACKGROUND_ADDRESS: + /* Write register value. */ + return do_flexa_set_background_address(data); +#endif + + case VG_LITE_QUERY_MEM: + return do_query_mem(data); + + case VG_LITE_MAP_MEMORY: + /* Map memory to user */ + return do_map_memory(data); + + case VG_LITE_UNMAP_MEMORY: + /* Unmap memory to user */ + return do_unmap_memory(data); + + case VG_LITE_CLOSE: + return do_gpu_close(); + + case VG_LITE_CACHE: + return do_cache(data); + + case VG_LITE_EXPORT_MEMORY: + return do_export_memory(data); + + case VG_LITE_RECORD_RUNNING_TIME: + return do_get_running_time(data); + +#if gcdVG_ENABLE_DELAY_RESUME + case VG_LITE_SET_DELAY_RESUME: + return set_delay_resume(data); + + case VG_LITE_QUERY_DELAY_RESUME: + return do_query_delay_resume(); + + case VG_LITE_SET_GPU_CLOCK_STATE: + return set_gpu_clock_state(data); +#endif + default: + break; + } + + /* Invalid command. */ + return VG_LITE_INVALID_ARGUMENT; +} + +#endif /* LV_USE_VG_LITE_DRIVER */ + diff --git a/src/libs/vg_lite_driver/VGLiteKernel/vg_lite_kernel.h b/src/libs/vg_lite_driver/VGLiteKernel/vg_lite_kernel.h new file mode 100755 index 0000000000..7ed3696ff8 --- /dev/null +++ b/src/libs/vg_lite_driver/VGLiteKernel/vg_lite_kernel.h @@ -0,0 +1,592 @@ +/**************************************************************************** +* +* The MIT License (MIT) +* +* Copyright (c) 2014 - 2022 Vivante Corporation +* +* Permission is hereby granted, free of charge, to any person obtaining a +* copy of this software and associated documentation files (the "Software"), +* to deal in the Software without restriction, including without limitation +* the rights to use, copy, modify, merge, publish, distribute, sublicense, +* and/or sell copies of the Software, and to permit persons to whom the +* Software is furnished to do so, subject to the following conditions: +* +* The above copyright notice and this permission notice shall be included in +* all copies or substantial portions of the Software. +* +* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +* DEALINGS IN THE SOFTWARE. +* +***************************************************************************** +* +* The GPL License (GPL) +* +* Copyright (C) 2014 - 2022 Vivante Corporation +* +* This program is free software; you can redistribute it and/or +* modify it under the terms of the GNU General Public License +* as published by the Free Software Foundation; either version 2 +* of the License, or (at your option) any later version. +* +* This program is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with this program; if not, write to the Free Software Foundation, +* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +* +***************************************************************************** +* +* Note: This software is released under dual MIT and GPL licenses. A +* recipient may use this file under the terms of either the MIT license or +* GPL License. If you wish to use only one license not the other, you can +* indicate your decision by deleting one of the above license notices in your +* version of this file. +* +*****************************************************************************/ + +#ifndef VG_LITE_KERNEL_H +#define VG_LITE_KERNEL_H + +#include "../../../lv_conf_internal.h" +#if LV_USE_VG_LITE_DRIVER + +#include "../VGLite/vg_lite_options.h" +#include "vg_lite_option.h" + +/* Interrupt IDs from GPU. */ +#define EVENT_UNEXPECTED_MESH 0x80000000 +#define EVENT_CMD_BAD_WRITE 0x40000000 +#define EVENT_ERROR_RECOVER 0x20000000 +#define EVENT_CMD_SWITCH 0x10000000 +#define EVENT_MCU_BAD_WRITE 0x08000000 +#define EVENT_END 0 +#define EVENT_FRAME_END 1 + +#define MAX_CONTIGUOUS_SIZE 0x04000000 + +#define VG_LITE_INFINITE 0xFFFFFFFF + +#if gcFEATURE_VG_SINGLE_COMMAND_BUFFER + #define CMDBUF_COUNT 1 +#else + #define CMDBUF_COUNT 2 +#endif + +#define VG_LITE_ALIGN(number, alignment) \ + (((number) + ((alignment) - 1)) & ~((alignment) - 1)) + +#ifndef BIT + #define BIT(x) (1 << x) +#endif + +#define VG_LITE_KERNEL_IS_GPU_IDLE() \ + ((vg_lite_hal_peek(VG_LITE_HW_IDLE) & VG_LITE_HW_IDLE_STATE) == VG_LITE_HW_IDLE_STATE) + +/* Hardware chip Ids */ +#define GPU_CHIP_ID_GCNANOLITEV 0x255 +#define GPU_CHIP_ID_GC355 0x355 +#define GPU_CHIP_ID_GCNANOULTRAV 0x265 + +/* vg_lite_kernel_map_t flag type */ +#define VG_LITE_HAL_MAP_DMABUF 0x00000004 +#define VG_LITE_HAL_MAP_USER_MEMORY 0x00000008 +#define VG_LITE_HAL_ALLOC_4G 0x00000010 + +/* vg_lite_kernel_allocate_t flag type */ +#define VG_LITE_RESERVED_ALLOCATOR 0x10000000 +#define VG_LITE_GFP_ALLOCATOR 0x20000000 +#define VG_LITE_DMA_ALLOCATOR 0x40000000 +#define VG_LITE_MEMORY_ALLOCATOR_FLAG 0x70000000 + +#ifdef __cplusplus +extern "C" { +#endif + +#ifndef VG_LITE_ERROR +#define VG_LITE_ERROR 1 +/*! + @abstract Error codes that the vg_lite functions can return. + + @discussion + All API functions return a status code. On success, VG_LITE_SUCCESS will be returned when a function is + successful. This value is set to zero, so if any function returns a non-zero value, an error has occurred. + */ +typedef enum vg_lite_error { + VG_LITE_SUCCESS = 0, /*! Success. */ + VG_LITE_INVALID_ARGUMENT, /*! An invalid argument was specified. */ + VG_LITE_OUT_OF_MEMORY, /*! Out of GPU memory */ + VG_LITE_NO_CONTEXT, /*! No context or an unintialized context specified. */ + VG_LITE_TIMEOUT, /*! A timeout has occurred during a wait. */ + VG_LITE_OUT_OF_RESOURCES, /*! Out of system resources. */ + VG_LITE_GENERIC_IO, /*! Cannot communicate with the kernel driver. */ + VG_LITE_NOT_SUPPORT, /*! Function call not supported. */ + VG_LITE_ALREADY_EXISTS, /*! Object already exists */ + VG_LITE_NOT_ALIGNED, /*! Data alignment error */ + VG_LITE_FLEXA_TIME_OUT, /*! VG timeout requesting for segment buffer */ + VG_LITE_FLEXA_HANDSHAKE_FAIL, /*! VG and SBI synchronizer handshake failed */ + VG_LITE_SYSTEM_CALL_FAIL, /*! kernel api call fail */ +} +vg_lite_error_t; +#endif + +typedef enum vg_lite_kernel_counter { + /* Dont't touch the counter. */ + VG_LITE_NONE, + + /* Turn the counter on. */ + VG_LITE_ON, + + /* Turn the counter off. */ + VG_LITE_OFF, + + /* Query the counter and reset its values. */ + VG_LITE_QUERY, +} +vg_lite_kernel_counter_t; + +typedef enum vg_lite_kernel_command { + /* Initialize the GPU. */ + VG_LITE_INITIALIZE, + + /* Terminate the GPU. */ + VG_LITE_TERMINATE, + + /* Allocate memory. */ + VG_LITE_ALLOCATE, + + /* Free memory. */ + VG_LITE_FREE, + + /* Submit a command buffer to the GPU. */ + VG_LITE_SUBMIT, + + /* Wait for the GPU to be completed. */ + VG_LITE_WAIT, + + /* Reset the GPU. */ + VG_LITE_RESET, + + /* Debug commands. */ + VG_LITE_DEBUG, + + /* Map memory. */ + VG_LITE_MAP, + + /* Unmap memory. */ + VG_LITE_UNMAP, + + /* Check info. */ + VG_LITE_CHECK, + + /* Query mem. */ + VG_LITE_QUERY_MEM, + + /* Flexa disable */ + VG_LITE_FLEXA_DISABLE, + + /* Flexa enable */ + VG_LITE_FLEXA_ENABLE, + + /* Flexa stop frame */ + VG_LITE_FLEXA_STOP_FRAME, + + /* Set background address */ + VG_LITE_FLEXA_SET_BACKGROUND_ADDRESS, + + /* Map memory to user */ + VG_LITE_MAP_MEMORY, + + /* Unmap memory to user */ + VG_LITE_UNMAP_MEMORY, + + /* Close gpu */ + VG_LITE_CLOSE, + + /* Operation cache */ + VG_LITE_CACHE, + + /* Export memory */ + VG_LITE_EXPORT_MEMORY, + + /* Record GPU hardware running time */ + VG_LITE_RECORD_RUNNING_TIME, + + /* Set delay resume state */ + VG_LITE_SET_DELAY_RESUME, + + /* Query delay resume state */ + VG_LITE_QUERY_DELAY_RESUME, + + /* Set GPU clock state */ + VG_LITE_SET_GPU_CLOCK_STATE, + +} +vg_lite_kernel_command_t; + +typedef enum vg_lite_cache_op { + VG_LITE_CACHE_CLEAN, + VG_LITE_CACHE_INVALIDATE, + VG_LITE_CACHE_FLUSH, +} +vg_lite_cache_op_t; + +typedef enum vg_lite_vidmem_pool { + VG_LITE_POOL_RESERVED_MEMORY1 = 0, + VG_LITE_POOL_RESERVED_MEMORY2 = 1, +} +vg_lite_vidmem_pool_t; + +typedef enum vg_lite_gpu_execute_state { + VG_LITE_GPU_STOP = 0, + VG_LITE_GPU_RUN = 1, +} +vg_lite_gpu_execute_state_t; + +/* Context structure. */ +typedef struct vg_lite_kernel_context { + /* Command buffer. */ + void * command_buffer[CMDBUF_COUNT]; + void * command_buffer_logical[CMDBUF_COUNT]; + void * command_buffer_klogical[CMDBUF_COUNT]; + uint32_t command_buffer_physical[CMDBUF_COUNT]; + uint32_t end_of_frame; + + /* Tessellation buffer. */ + void * tess_buffer; + void * tessbuf_logical; + void * tessbuf_klogical; + uint32_t tessbuf_physical; + + /* power context buffer */ + void * power_context; + void * power_context_logical; + void * power_context_klogical; + uint32_t power_context_physical; + uint32_t power_context_size; + uint32_t power_context_capacity; +} +vg_lite_kernel_context_t; + +typedef struct capabilities { + uint32_t tiled : 2; + uint32_t l2_cache : 1; +} +capabilities_t; + +typedef union vg_lite_capabilities { + capabilities_t cap; + uint32_t data; +} +vg_lite_capabilities_t; + +typedef struct vg_lite_kernel_initialize { + /* INPUT */ + + /* Command buffer size. */ + uint32_t command_buffer_size; + + /* Tessellation buffer width. */ + int32_t tess_width; + + /* Tessellation buffer height. */ + int32_t tess_height; + + /* Memory pool for command buffer. */ + vg_lite_vidmem_pool_t command_buffer_pool; + + /* Memory pool for tessellation buffer. */ + vg_lite_vidmem_pool_t tess_buffer_pool; + + /* OUTPUT */ + + /* Context pointer. */ + vg_lite_kernel_context_t * context; + + /* Capabilities. */ + vg_lite_capabilities_t capabilities; + + /* Allocated command buffer. */ + void * command_buffer[CMDBUF_COUNT]; + + /* GPU address for command buffer. */ + uint32_t command_buffer_gpu[CMDBUF_COUNT]; + + /* GPU addresses for tesselation buffers. */ + uint32_t physical_addr; + + /* Logic addresses for tessellation buffers: used by SW Tessellator. */ + uint8_t * logical_addr; + + /* Size of each level of the tesselation buffer. */ + uint32_t tessbuf_size; + + /* Size of each level of the vg count buffer. */ + uint32_t countbuf_size; + + /* Width and height of tessellation buffer. */ + uint32_t tess_w_h; +} +vg_lite_kernel_initialize_t; + +typedef struct vg_lite_kernel_terminate { + /* Context to terminate. */ + vg_lite_kernel_context_t * context; +} +vg_lite_kernel_terminate_t; + +typedef struct vg_lite_kernel_allocate { + /* INPUT */ + + /* Number of bytes to allocate. */ + uint32_t bytes; + + /* Flag to indicate whether the allocated memory is contiguous or not. */ + int32_t contiguous; + + /* Flag to indicate where to allocate memory */ + uint32_t flags; + + /* select reserved memory pool */ + vg_lite_vidmem_pool_t pool; + + /* OUTPUT */ + + /* Memory handle. */ + void * memory_handle; + + /* Allocated memory. */ + void * memory; + + /* kernel memory */ + void * kmemory; + + /* GPU address of allocated memory. */ + uint32_t memory_gpu; +} +vg_lite_kernel_allocate_t; + +typedef struct vg_lite_kernel_free { + /* Memory handle to free. */ + void * memory_handle; +} +vg_lite_kernel_free_t; + +typedef struct vg_lite_kernel_submit { + /* Context to submit to. */ + vg_lite_kernel_context_t * context; + + /* Pointer to command buffer. */ + void * commands; + + /* Number of bytes in command buffer. */ + uint32_t command_size; + + /* Command Buffer ID. */ + uint32_t command_id; +} +vg_lite_kernel_submit_t; + +typedef enum vg_lite_gpu_reset_type { + RESTORE_INIT_COMMAND = 0, + RESTORE_LAST_COMMAND = 1, + RESTORE_ALL_COMMAND = 2, + RESTORE_NONE = 3, +} +vg_lite_gpu_reset_type_t; + +typedef struct vg_lite_kernel_wait { + /* Context to wait for. */ + vg_lite_kernel_context_t * context; + + /* Timeout in milliseconds. */ + uint32_t timeout_ms; + + /* The event to wait. */ + uint32_t event_mask; + + /* The event(s) got after waiting. */ + uint32_t event_got; + + /* After GPU reset, select submit command */ + vg_lite_gpu_reset_type_t reset_type; +} +vg_lite_kernel_wait_t; + +typedef struct vg_lite_kernel_reset { + /* Context to reset. */ + vg_lite_kernel_context_t * context; + uint32_t delay_resume_flag; +} +vg_lite_kernel_reset_t; + +typedef struct vg_lite_kernel_debug { + /* Context to debug. */ + vg_lite_kernel_context_t * context; + + /* Bandwidth counter enabler. */ + vg_lite_kernel_counter_t bandwidth_counter; + + /* Pixel counter enabler. */ + vg_lite_kernel_counter_t pixel_counters; + + /* OUTPUT */ + + /* Bandwidth counters: + * [0] - burst of 8. + * [1] - burst of 16. + * [2] - burst of 32. + * [3] - burst of 64. + */ + uint32_t bandwidth[4]; + + /* Pixel counters:. + * [0] - Number of tessellated pixels. + * [1] - Number of imaged pixels. + * [2] - Number of rendered pixels. + */ + uint32_t pixels[3]; +} +vg_lite_kernel_debug_t; + +typedef struct vg_lite_kernel_map { + /* INPUT */ + uint32_t flags; + + /* user memory */ + /* Number of bytes to map. */ + uint32_t bytes; + + /* Logical memory address or NULL. */ + void * logical; + + /* Physical memory address or 0. */ + uint32_t physical; + + /* dma_buf */ + /* dma_buf fd */ + int32_t dma_buf_fd; + + /* OUTPUT */ + /* Memory handle for mapped memory. */ + void * memory_handle; + + /* GPU address of mapped memory. */ + uint32_t memory_gpu; +} +vg_lite_kernel_map_t; + +typedef struct vg_lite_kernel_unmap { + /* Memory handle to unmap. */ + void * memory_handle; +} +vg_lite_kernel_unmap_t; + +typedef struct vg_lite_kernel_cache { + vg_lite_cache_op_t cache_op; + + /* Memory handle to operation. */ + void * memory_handle; +} +vg_lite_kernel_cache_t; + +typedef struct vg_lite_kernel_info { + /* Register's address. */ + uint32_t addr; + + /* Check register info. */ + uint32_t reg; +} +vg_lite_kernel_info_t; + +typedef struct vg_lite_kernel_flexa_info { + uint32_t sbi_mode; + uint32_t sync_mode; + uint32_t flexa_mode; + uint32_t stream_id; + uint32_t segment_address; + uint32_t segment_count; + uint32_t segment_size; + uint32_t stop_flag; + uint32_t start_flag; + uint32_t reset_flag; +} +vg_lite_kernel_flexa_info_t; + +typedef struct vg_lite_kernel_mem { + uint32_t bytes; + + vg_lite_vidmem_pool_t pool; +} +vg_lite_kernel_mem_t; + +typedef struct vg_lite_kernel_map_memory { + /* Number of bytes to map. */ + uint32_t bytes; + + /* Physical memory address. */ + uint32_t physical; + + /* Logical memory address. */ + void * logical; +} +vg_lite_kernel_map_memory_t; + +typedef struct vg_lite_kernel_unmap_memory { + /* Number of bytes to map. */ + uint32_t bytes; + + /* Logical memory address. */ + void * logical; +} +vg_lite_kernel_unmap_memory_t; + +typedef struct vg_lite_kernel_close { + vg_lite_kernel_context_t * context; +} +vg_lite_kernel_close_t; + +typedef struct vg_lite_kernel_export_memory { + int32_t fd; +} +vg_lite_kernel_export_memory_t; + +typedef struct vg_lite_kernel_hardware_running_time { + unsigned long run_time; + int32_t hertz; +} +vg_lite_kernel_hardware_running_time_t; + +typedef struct vg_lite_kernel_delay_resume { + uint32_t set_delay_resume; + uint32_t query_delay_resume; +} +vg_lite_kernel_delay_resume_t; + +typedef struct vg_lite_kernel_gpu_clock_state { + uint32_t state; +} +vg_lite_kernel_gpu_clock_state_t; + +vg_lite_error_t vg_lite_kernel(vg_lite_kernel_command_t command, void * data); + +vg_lite_error_t record_running_time(void); + +extern uint32_t init_buffer[12]; +extern uint32_t is_init; +extern size_t physical_address; + +#ifdef __cplusplus +} +#endif + +#endif /* LV_USE_VG_LITE_DRIVER */ + +#endif /* VG_LITE_KERNEL_H */ diff --git a/src/libs/vg_lite_driver/VGLiteKernel/vg_lite_option.h b/src/libs/vg_lite_driver/VGLiteKernel/vg_lite_option.h new file mode 100755 index 0000000000..d47de5b75e --- /dev/null +++ b/src/libs/vg_lite_driver/VGLiteKernel/vg_lite_option.h @@ -0,0 +1,143 @@ +/**************************************************************************** +* +* The MIT License (MIT) +* +* Copyright (c) 2014 - 2022 Vivante Corporation +* +* Permission is hereby granted, free of charge, to any person obtaining a +* copy of this software and associated documentation files (the "Software"), +* to deal in the Software without restriction, including without limitation +* the rights to use, copy, modify, merge, publish, distribute, sublicense, +* and/or sell copies of the Software, and to permit persons to whom the +* Software is furnished to do so, subject to the following conditions: +* +* The above copyright notice and this permission notice shall be included in +* all copies or substantial portions of the Software. +* +* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +* DEALINGS IN THE SOFTWARE. +* +***************************************************************************** +* +* The GPL License (GPL) +* +* Copyright (C) 2014 - 2022 Vivante Corporation +* +* This program is free software; you can redistribute it and/or +* modify it under the terms of the GNU General Public License +* as published by the Free Software Foundation; either version 2 +* of the License, or (at your option) any later version. +* +* This program is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with this program; if not, write to the Free Software Foundation, +* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +* +***************************************************************************** +* +* Note: This software is released under dual MIT and GPL licenses. A +* recipient may use this file under the terms of either the MIT license or +* GPL License. If you wish to use only one license not the other, you can +* indicate your decision by deleting one of the above license notices in your +* version of this file. +* +*****************************************************************************/ + +#ifndef VG_LITE_KERNEL_OPTION_H +#define VG_LITE_KERNEL_OPTION_H + +#include "../../../lv_conf_internal.h" +#if LV_USE_VG_LITE_DRIVER + +#ifdef __cplusplus +extern "C" { +#endif + +/* + * Set gcdVG_ENABLE_WRITEBUFFER to 1 for Linux Write Combined memory access + * Set gcdVG_ENABLE_WRITEBUFFER to 0 for Linux Uncacheable memory access +*/ +#ifndef gcdVG_ENABLE_WRITEBUFFER +#define gcdVG_ENABLE_WRITEBUFFER 1 +#endif + +/* + * Backup state command, only support Linux and RTOS +*/ +#ifndef gcdVG_ENABLE_BACKUP_COMMAND +#define gcdVG_ENABLE_BACKUP_COMMAND 0 +#endif + +/* + * Power management, only support Linux and RTOS +*/ +#ifndef gcdVG_ENABLE_POWER_MANAGEMENT +#define gcdVG_ENABLE_POWER_MANAGEMENT 0 +#endif + +/* + * when set to 1, vg_lite_hal_trace can use to print message +*/ +#ifndef gcdVG_ENABLE_DEBUG +#define gcdVG_ENABLE_DEBUG 1 +#endif + +/* + * when set to 1, dump last submit command from kernel +*/ +#ifndef gcdVG_ENABLE_DUMP_COMMAND +#define gcdVG_ENABLE_DUMP_COMMAND 0 +#endif + +/* + * when gpu hang, set 1 to open gpu reset function +*/ +#ifndef gcdVG_ENABLE_GPU_RESET +#define gcdVG_ENABLE_GPU_RESET 0 +#endif + +/* + * Set 1 to open gpu auto clock gating feature +*/ +#ifndef gcdVG_ENABLE_AUTO_CLOCK_GATING +#define gcdVG_ENABLE_AUTO_CLOCK_GATING 0 +#endif + +/* + * Set 1 to open dump debug register +*/ +#ifndef gcdVG_DUMP_DEBUG_REGISTER +#define gcdVG_DUMP_DEBUG_REGISTER 0 +#endif + +/* + * For zephyr system + * Set gcdVG_ENABLE_DELAY_RESUME to 1 to open delay resume feature. +*/ +#ifndef gcdVG_ENABLE_DELAY_RESUME +#define gcdVG_ENABLE_DELAY_RESUME 0 +#endif + +/* + * Set 1 to record GPU hardware running time. +*/ +#ifndef gcdVG_RECORD_HARDWARE_RUNNING_TIME +#define gcdVG_RECORD_HARDWARE_RUNNING_TIME 0 +#endif + +#ifdef __cplusplus +} +#endif + +#endif /* LV_USE_VG_LITE_DRIVER */ + +#endif /* VG_LITE_KERNEL_OPTION_H */ diff --git a/src/libs/vg_lite_driver/VGLiteKernel/vg_lite_type.h b/src/libs/vg_lite_driver/VGLiteKernel/vg_lite_type.h new file mode 100755 index 0000000000..b24fb0eccf --- /dev/null +++ b/src/libs/vg_lite_driver/VGLiteKernel/vg_lite_type.h @@ -0,0 +1,80 @@ +/***************************************************************************** +* +* copyright 2012 - 2023 Vivante Corporation, Santa Clara, California. +* All Rights Reserved. +* +* Permission is hereby granted, free of charge, to any person obtaining +* a copy of this software and associated documentation files (the +* 'Software'), to deal in the Software without restriction, including +* without limitation the rights to use, copy, modify, merge, publish, +* distribute, sub license, and/or sell copies of the Software, and to +* permit persons to whom the Software is furnished to do so, subject +* to the following conditions: +* +* The above copyright notice and this permission notice (including the +* next paragraph) shall be included in all copies or substantial +* portions of the Software. +* +* THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND, +* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. +* IN NO EVENT SHALL VIVANTE AND/OR ITS SUPPLIERS BE LIABLE FOR ANY +* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, +* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE +* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +* +*****************************************************************************/ +#ifndef VG_LITE_TYPE_H +#define VG_LITE_TYPE_H + +#include "../../../lv_conf_internal.h" +#if LV_USE_VG_LITE_DRIVER + +#if __KERNEL__ + #include +#endif +#include "vg_lite_kernel.h" + +#ifdef __cplusplus +extern "C" { +#endif + +#define VG_FALSE 0 +#define VG_TRUE 1 + +#define VG_SUCCESS 0 +#define VG_FAIL -1 + +typedef int vg_lite_bool_t; +typedef unsigned char vg_lite_uint8_t; +typedef char vg_lite_int8_t; +typedef short vg_lite_int16_t; +typedef unsigned short vg_lite_uint16_t; +typedef int vg_lite_int32_t; +typedef unsigned int vg_lite_uint32_t; +typedef unsigned long long vg_lite_uint64_t; +typedef float vg_lite_float_t; +typedef double vg_lite_double_t; +typedef char vg_lite_char; +typedef char * vg_lite_string; +typedef void * vg_lite_pointer; +typedef void vg_lite_void; +typedef unsigned int vg_lite_color_t; +typedef unsigned long vg_lite_flag_t; +typedef unsigned long vg_lite_long_t; + +#if __KERNEL__ +# if BITS_PER_LONG == 64 +typedef unsigned long long vg_lite_uintptr_t; +# else +typedef unsigned int vg_lite_uintptr_t; +# endif +#endif + +#ifdef __cplusplus +} +#endif + +#endif /* LV_USE_VG_LITE_DRIVER */ + +#endif /* VG_LITE_TYPE_H */ diff --git a/src/libs/vg_lite_driver/add_lvgl_if.sh b/src/libs/vg_lite_driver/add_lvgl_if.sh new file mode 100755 index 0000000000..09c7513ed5 --- /dev/null +++ b/src/libs/vg_lite_driver/add_lvgl_if.sh @@ -0,0 +1,13 @@ +#!/bin/bash + +#Add LVGL #if LV_USE_VG_LITE_DRIVER guard +#Usage +# find -name "*.c" | xargs ./add_lvgl_if.sh +# find -name "t*.h" | xargs ./add_lvgl_if.sh + +sed '0,/\*\/$/ {/\*\/$/ {n; s|^|\n#include "../../lv_conf_internal.h"\n#if LV_USE_VG_LITE_DRIVER\n|}}' $@ -i + +sed -i -e '$a\ +\ +#endif /* LV_USE_VG_LITE_DRIVER */\ +' $@ -i diff --git a/src/libs/vg_lite_driver/inc/vg_lite.h b/src/libs/vg_lite_driver/inc/vg_lite.h new file mode 100755 index 0000000000..649beac65e --- /dev/null +++ b/src/libs/vg_lite_driver/inc/vg_lite.h @@ -0,0 +1,1458 @@ +/**************************************************************************** +* +* Copyright 2012 - 2023 Vivante Corporation, Santa Clara, California. +* All Rights Reserved. +* +* Permission is hereby granted, free of charge, to any person obtaining +* a copy of this software and associated documentation files (the +* 'Software'), to deal in the Software without restriction, including +* without limitation the rights to use, copy, modify, merge, publish, +* distribute, sub license, and/or sell copies of the Software, and to +* permit persons to whom the Software is furnished to do so, subject +* to the following conditions: +* +* The above copyright notice and this permission notice (including the +* next paragraph) shall be included in all copies or substantial +* portions of the Software. +* +* THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND, +* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. +* IN NO EVENT SHALL VIVANTE AND/OR ITS SUPPLIERS BE LIABLE FOR ANY +* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, +* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE +* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +* +*****************************************************************************/ + +#ifndef VG_LITE_H +#define VG_LITE_H + +#ifdef __cplusplus +extern "C" { +#endif + +#if defined(_MSC_VER) +#define inline __inline +#endif + +#include "../../../lv_conf_internal.h" +#if LV_USE_VG_LITE_DRIVER + +#include +#include + +/* VGLite API Constants *******************************************************************************************************************/ + +#define VGLITE_HEADER_VERSION 7 + +#ifndef VGLITE_VERSION_3_0 +#define VGLITE_VERSION_3_0 1 + +#define VGLITE_MAKE_VERSION(major, minor, patch) (((major) << 16) | ((minor) << 8) | (patch)) +#define VGLITE_VERSION_MAJOR(version) (((uint32_t)(version) >> 16) & 0xff) +#define VGLITE_VERSION_MINOR(version) (((uint32_t)(version) >> 8) & 0xff) +#define VGLITE_VERSION_PATCH(version) ((uint32_t)(version) & 0xff) + +#define VGLITE_API_VERSION_3_0 VGLITE_MAKE_VERSION(3, 0, 0) + +#define VGLITE_RELEASE_VERSION VGLITE_MAKE_VERSION(4,0,90) + +#define VGL_FALSE 0 +#define VGL_TRUE 1 + +/* Path command (op code). */ +#define VLC_OP_END 0x00 +#define VLC_OP_CLOSE 0x01 +#define VLC_OP_MOVE 0x02 +#define VLC_OP_MOVE_REL 0x03 +#define VLC_OP_LINE 0x04 +#define VLC_OP_LINE_REL 0x05 +#define VLC_OP_QUAD 0x06 +#define VLC_OP_QUAD_REL 0x07 +#define VLC_OP_CUBIC 0x08 +#define VLC_OP_CUBIC_REL 0x09 +#define VLC_OP_BREAK 0x0A +#define VLC_OP_HLINE 0x0B +#define VLC_OP_HLINE_REL 0x0C +#define VLC_OP_VLINE 0x0D +#define VLC_OP_VLINE_REL 0x0E +#define VLC_OP_SQUAD 0x0F +#define VLC_OP_SQUAD_REL 0x10 +#define VLC_OP_SCUBIC 0x11 +#define VLC_OP_SCUBIC_REL 0x12 +#define VLC_OP_SCCWARC 0x13 +#define VLC_OP_SCCWARC_REL 0x14 +#define VLC_OP_SCWARC 0x15 +#define VLC_OP_SCWARC_REL 0x16 +#define VLC_OP_LCCWARC 0x17 +#define VLC_OP_LCCWARC_REL 0x18 +#define VLC_OP_LCWARC 0x19 +#define VLC_OP_LCWARC_REL 0x1A + +/* Macros for path manipulating: See path definitions. */ +#define VLM_PATH_ENABLE_UPLOAD(path) (path).uploaded.property |= 1 +#define VLM_PATH_DISABLE_UPLOAD(path) (path).uploaded.property &= (~1) +#define VLM_PATH_GET_UPLOAD_BIT(path) ((path).uploaded.property & 1) +#define VLM_PATH_STROKE_ENABLE_UPLOAD(path) (path).stroke->uploaded.property |= 1 +#define VLM_PATH_STROKE_DISABLE_UPLOAD(path) (path).stroke->uploaded.property &= (~1) +#define VLM_PATH_STROKE_GET_UPLOAD_BIT(path) ((path).stroke->uploaded.property & 1) + +/* Gradient constants. */ +#define VLC_MAX_COLOR_RAMP_STOPS 256 /*! The max number of radial gradient stops. */ +#define VLC_MAX_GRADIENT_STOPS 16 /*! The max number of gradient stops. */ +#define VLC_GRADIENT_BUFFER_WIDTH 1024 /*! The internal gradient buffer width.*/ + + +/* API name defines for backward compatibility to VGLite 2.0 APIs */ +#define vg_lite_buffer_upload vg_lite_upload_buffer +#define vg_lite_path_append vg_lite_append_path +#define vg_lite_path_calc_length vg_lite_get_path_length +#define vg_lite_set_ts_buffer vg_lite_set_tess_buffer +#define vg_lite_set_draw_path_type vg_lite_set_path_type +#define vg_lite_create_mask_layer vg_lite_create_masklayer +#define vg_lite_fill_mask_layer vg_lite_fill_masklayer +#define vg_lite_blend_mask_layer vg_lite_blend_masklayer +#define vg_lite_generate_mask_layer_by_path vg_lite_render_masklayer +#define vg_lite_set_mask_layer vg_lite_set_masklayer +#define vg_lite_destroy_mask_layer vg_lite_destroy_masklayer +#define vg_lite_enable_mask vg_lite_enable_masklayer +#define vg_lite_enable_color_transformation vg_lite_enable_color_transform +#define vg_lite_set_color_transformation vg_lite_set_color_transform +#define vg_lite_set_image_global_alpha vg_lite_source_global_alpha +#define vg_lite_set_dest_global_alpha vg_lite_dest_global_alpha +#define vg_lite_clear_rad_grad vg_lite_clear_radial_grad +#define vg_lite_update_rad_grad vg_lite_update_radial_grad +#define vg_lite_get_rad_grad_matrix vg_lite_get_radial_grad_matrix +#define vg_lite_set_rad_grad vg_lite_set_radial_grad +#define vg_lite_draw_linear_gradient vg_lite_draw_linear_grad +#define vg_lite_draw_radial_gradient vg_lite_draw_radial_grad +#define vg_lite_draw_gradient vg_lite_draw_grad +#define vg_lite_mem_avail vg_lite_get_mem_size +#define vg_lite_set_update_stroke vg_lite_update_stroke + +#define vg_lite_buffer_image_mode_t vg_lite_image_mode_t +#define vg_lite_draw_path_type_t vg_lite_path_type_t +#define vg_lite_linear_gradient_ext_t vg_lite_ext_linear_gradient_t +#define vg_lite_buffer_transparency_mode_t vg_lite_transparency_t + +/* VG_LITE_BLEND_PREMULTIPLY_SRC_OVER is the same as VG_LITE_BLEND_NORMAL_LVGL */ +#define VG_LITE_BLEND_PREMULTIPLY_SRC_OVER VG_LITE_BLEND_NORMAL_LVGL + +/* VGLite API Types ***********************************************************************************************************************/ + +typedef unsigned char vg_lite_uint8_t; +typedef char vg_lite_int8_t; +typedef short vg_lite_int16_t; +typedef unsigned short vg_lite_uint16_t; +typedef int vg_lite_int32_t; +typedef unsigned int vg_lite_uint32_t; +typedef unsigned long long vg_lite_uint64_t; +typedef float vg_lite_float_t; +typedef double vg_lite_double_t; +typedef char vg_lite_char; +typedef char * vg_lite_string; +typedef void * vg_lite_pointer; +typedef void vg_lite_void; +typedef unsigned int vg_lite_color_t; + + +/* VGLite API Enumerations ****************************************************************************************************************/ + +#ifndef VG_LITE_ERROR +#define VG_LITE_ERROR 1 + +/* Error codes that the vg_lite functions can return. */ +typedef enum vg_lite_error { + VG_LITE_SUCCESS = 0, /*! Success. */ + VG_LITE_INVALID_ARGUMENT, /*! An invalid argument was specified. */ + VG_LITE_OUT_OF_MEMORY, /*! Out of GPU memory. */ + VG_LITE_NO_CONTEXT, /*! No context or an unintialized context specified. */ + VG_LITE_TIMEOUT, /*! A timeout has occurred during a wait. */ + VG_LITE_OUT_OF_RESOURCES, /*! Out of system resources. */ + VG_LITE_GENERIC_IO, /*! Cannot communicate with the kernel driver. */ + VG_LITE_NOT_SUPPORT, /*! Function call not supported. */ + VG_LITE_ALREADY_EXISTS, /*! Object already exists */ + VG_LITE_NOT_ALIGNED, /*! Data alignment error */ + VG_LITE_FLEXA_TIME_OUT, /*! VG timeout requesting for segment buffer */ + VG_LITE_FLEXA_HANDSHAKE_FAIL, /*! VG and SBI synchronizer handshake failed */ +} vg_lite_error_t; +#endif + +/* Chip features bit */ +typedef enum vg_lite_feature { + gcFEATURE_BIT_VG_IM_INDEX_FORMAT, + gcFEATURE_BIT_VG_SCISSOR, + gcFEATURE_BIT_VG_BORDER_CULLING, + gcFEATURE_BIT_VG_RGBA2_FORMAT, + gcFEATURE_BIT_VG_QUALITY_8X, + gcFEATURE_BIT_VG_IM_FASTCLAER, + gcFEATURE_BIT_VG_RADIAL_GRADIENT, + gcFEATURE_BIT_VG_GLOBAL_ALPHA, + gcFEATURE_BIT_VG_RGBA8_ETC2_EAC, + gcFEATURE_BIT_VG_COLOR_KEY, + gcFEATURE_BIT_VG_DOUBLE_IMAGE, + gcFEATURE_BIT_VG_YUV_OUTPUT, + gcFEATURE_BIT_VG_FLEXA, + gcFEATURE_BIT_VG_24BIT, + gcFEATURE_BIT_VG_DITHER, + gcFEATURE_BIT_VG_USE_DST, + gcFEATURE_BIT_VG_PE_CLEAR, + gcFEATURE_BIT_VG_IM_INPUT, + gcFEATURE_BIT_VG_DEC_COMPRESS, + gcFEATURE_BIT_VG_LINEAR_GRADIENT_EXT, + gcFEATURE_BIT_VG_MASK, + gcFEATURE_BIT_VG_MIRROR, + gcFEATURE_BIT_VG_GAMMA, + gcFEATURE_BIT_VG_NEW_BLEND_MODE, + gcFEATURE_BIT_VG_STENCIL, + gcFEATURE_BIT_VG_SRC_PREMULTIPLIED, /*! Valid only if gcFEATURE_BIT_VG_HW_PREMULTIPLY is 0 */ + gcFEATURE_BIT_VG_HW_PREMULTIPLY, /*! HW multiplier can accept either premultiplied or not */ + gcFEATURE_BIT_VG_COLOR_TRANSFORMATION, + gcFEATURE_BIT_VG_LVGL_SUPPORT, + gcFEATURE_BIT_VG_INDEX_ENDIAN, + gcFEATURE_BIT_VG_24BIT_PLANAR, + gcFEATURE_BIT_VG_PIXEL_MATRIX, + gcFEATURE_BIT_VG_NEW_IMAGE_INDEX, + gcFEATURE_BIT_VG_PARALLEL_PATHS, + gcFEATURE_BIT_VG_STRIPE_MODE, + gcFEATURE_BIT_VG_IM_DEC_INPUT, + gcFEATURE_BIT_VG_GAUSSIAN_BLUR, + gcFEATURE_BIT_VG_RECTANGLE_TILED_OUT, + gcFEATURE_BIT_VG_TESSELLATION_TILED_OUT, + gcFEATURE_BIT_VG_IM_REPEAT_REFLECT, + gcFEATURE_BIT_VG_YUY2_INPUT, + gcFEATURE_BIT_VG_YUV_INPUT, + gcFEATURE_BIT_VG_YUV_TILED_INPUT, + gcFEATURE_BIT_VG_AYUV_INPUT, + gcFEATURE_BIT_VG_16PIXELS_ALIGN, + gcFEATURE_BIT_VG_DEC_COMPRESS_2_0, + gcFEATURE_BIT_VG_NV24_INPUT, + gcFEATURE_BIT_VG_TILED_LIMIT, + gcFEATURE_BIT_TILED_MODE, + gcFEATURE_BIT_VG_SRC_ADDRESS_16BYTES_ALIGNED, + gcFEATURE_BIT_VG_SRC_ADDRESS_64BYTES_ALIGNED, + gcFEATURE_BIT_VG_SRC_TILE_4PIXELS_ALIGNED, + gcFEATURE_BIT_VG_SRC_BUF_ALINGED, + gcFEATURE_BIT_VG_DST_ADDRESS_64BYTES_ALIGNED, + gcFEATURE_BIT_VG_DST_TILE_4PIXELS_ALIGNED, + gcFEATURE_BIT_VG_DST_BUF_ALIGNED, + gcFEATURE_BIT_VG_DST_24BIT_PLANAR_ALIGNED, + gcFEATURE_BIT_VG_DST_BUFLEN_ALIGNED, + gcFEATURE_BIT_VG_FORMAT_SUPPORT_CHECK, + gcFEATURE_BIT_VG_YUV_ALIGNED_CHECK, + gcFEATURE_BIT_VG_512_PARALLEL_PATHS, + gcFEATURE_COUNT +} vg_lite_feature_t; + +/* Rendering quality enums. */ +typedef enum vg_lite_quality { + VG_LITE_HIGH, /*! High quality 16x anti-aliasing path. */ + VG_LITE_UPPER, /*! Upper quality 8x anti-aliasing path. */ + VG_LITE_MEDIUM, /*! Medium quality 4x anti-aliasing path. */ + VG_LITE_LOW, /*! Low quality path without any anti-aliasing. */ +} vg_lite_quality_t; + +/* Format of path coordinates. */ +typedef enum vg_lite_format { + VG_LITE_S8, /*! Signed 8-bit coordinates. */ + VG_LITE_S16, /*! Signed 16-bit coordinates. */ + VG_LITE_S32, /*! Signed 32-bit coordinates. */ + VG_LITE_FP32, /*! 32-bit floating point coordinates. */ +} vg_lite_format_t; + +/* Format of pixel buffer. */ +typedef enum vg_lite_buffer_format { + /* The following OPENVG_* enums are defined corresponding to OpenVG + * VGImageFormat enums so VGLite API can take OpenVG VGImageFormat enums directly. + * + * Note: The bits for each color channel are stored within a machine word + * from MSB to LSB in the order indicated by the pixel format name. + * This is opposite of VG_LITE_* formats (from LSB to MSB). + */ + + /* RGB{A,X} channel ordering */ + OPENVG_sRGBX_8888 = 0, + OPENVG_sRGBA_8888 = 1, + OPENVG_sRGBA_8888_PRE = 2, + OPENVG_sRGB_565 = 3, + OPENVG_sRGBA_5551 = 4, + OPENVG_sRGBA_4444 = 5, + OPENVG_sL_8 = 6, + OPENVG_lRGBX_8888 = 7, + OPENVG_lRGBA_8888 = 8, + OPENVG_lRGBA_8888_PRE = 9, + OPENVG_lL_8 = 10, + OPENVG_A_8 = 11, + OPENVG_BW_1 = 12, + OPENVG_A_1 = 13, + OPENVG_A_4 = 14, + + /* The following enums 15 ~ 25 do not exist in OpenVG VGImageFormat. + * They are defined to support OpenVG CTS internalFormat which is set + * base on "sRGB_NONPRE", "lRGB_NONPRE", "sRGB_PRE", "lRGB_PRE" + * destination surface configurations. + */ + OPENVG_sRGBX_8888_PRE = 15, + OPENVG_sRGB_565_PRE = 16, + OPENVG_sRGBA_5551_PRE = 17, + OPENVG_sRGBA_4444_PRE = 18, + OPENVG_lRGBX_8888_PRE = 19, + OPENVG_lRGB_565 = 20, + OPENVG_lRGB_565_PRE = 21, + OPENVG_lRGBA_5551 = 22, + OPENVG_lRGBA_5551_PRE = 23, + OPENVG_lRGBA_4444 = 24, + OPENVG_lRGBA_4444_PRE = 25, + + /* {A,X}RGB channel ordering */ + OPENVG_sXRGB_8888 = 0 | (1 << 6), + OPENVG_sARGB_8888 = 1 | (1 << 6), + OPENVG_sARGB_8888_PRE = 2 | (1 << 6), + OPENVG_sARGB_1555 = 4 | (1 << 6), + OPENVG_sARGB_4444 = 5 | (1 << 6), + OPENVG_lXRGB_8888 = 7 | (1 << 6), + OPENVG_lARGB_8888 = 8 | (1 << 6), + OPENVG_lARGB_8888_PRE = 9 | (1 << 6), + + /* BGR{A,X} channel ordering */ + OPENVG_sBGRX_8888 = 0 | (1 << 7), + OPENVG_sBGRA_8888 = 1 | (1 << 7), + OPENVG_sBGRA_8888_PRE = 2 | (1 << 7), + OPENVG_sBGR_565 = 3 | (1 << 7), + OPENVG_sBGRA_5551 = 4 | (1 << 7), + OPENVG_sBGRA_4444 = 5 | (1 << 7), + OPENVG_lBGRX_8888 = 7 | (1 << 7), + OPENVG_lBGRA_8888 = 8 | (1 << 7), + OPENVG_lBGRA_8888_PRE = 9 | (1 << 7), + + /* {A,X}BGR channel ordering */ + OPENVG_sXBGR_8888 = 0 | (1 << 6) | (1 << 7), + OPENVG_sABGR_8888 = 1 | (1 << 6) | (1 << 7), + OPENVG_sABGR_8888_PRE = 2 | (1 << 6) | (1 << 7), + OPENVG_sABGR_1555 = 4 | (1 << 6) | (1 << 7), + OPENVG_sABGR_4444 = 5 | (1 << 6) | (1 << 7), + OPENVG_lXBGR_8888 = 7 | (1 << 6) | (1 << 7), + OPENVG_lABGR_8888 = 8 | (1 << 6) | (1 << 7), + OPENVG_lABGR_8888_PRE = 9 | (1 << 6) | (1 << 7), + + /* The following VG_LITE_* enums are original VGLite API image format enums. + * + * Note: The bits for each color channel are stored within a machine word + * from LSB to MSB in the order indicated by the pixel format name. + * This is opposite of OPENVG VG_* formats (from MSB to LSB). + */ + VG_LITE_RGBA8888 = 0 | (1 << 10), + VG_LITE_BGRA8888 = 1 | (1 << 10), + VG_LITE_RGBX8888 = 2 | (1 << 10), + VG_LITE_BGRX8888 = 3 | (1 << 10), + VG_LITE_RGB565 = 4 | (1 << 10), + VG_LITE_BGR565 = 5 | (1 << 10), + VG_LITE_RGBA4444 = 6 | (1 << 10), + VG_LITE_BGRA4444 = 7 | (1 << 10), + VG_LITE_BGRA5551 = 8 | (1 << 10), + VG_LITE_A4 = 9 | (1 << 10), + VG_LITE_A8 = 10 | (1 << 10), + VG_LITE_L8 = 11 | (1 << 10), + VG_LITE_YUYV = 12 | (1 << 10), + VG_LITE_YUY2 = 13 | (1 << 10), + VG_LITE_ANV12 = 14 | (1 << 10), + VG_LITE_AYUY2 = 15 | (1 << 10), + VG_LITE_NV12 = 16 | (1 << 10), + VG_LITE_YV12 = 17 | (1 << 10), + VG_LITE_YV24 = 18 | (1 << 10), + VG_LITE_YV16 = 19 | (1 << 10), + VG_LITE_NV16 = 20 | (1 << 10), + VG_LITE_YUY2_TILED = 21 | (1 << 10), + VG_LITE_NV12_TILED = 22 | (1 << 10), + VG_LITE_ANV12_TILED = 23 | (1 << 10), + VG_LITE_AYUY2_TILED = 24 | (1 << 10), + VG_LITE_RGBA2222 = 25 | (1 << 10), + VG_LITE_BGRA2222 = 26 | (1 << 10), + VG_LITE_ABGR2222 = 27 | (1 << 10), + VG_LITE_ARGB2222 = 28 | (1 << 10), + VG_LITE_ABGR4444 = 29 | (1 << 10), + VG_LITE_ARGB4444 = 30 | (1 << 10), + VG_LITE_ABGR8888 = 31 | (1 << 10), + VG_LITE_ARGB8888 = 32 | (1 << 10), + VG_LITE_ABGR1555 = 33 | (1 << 10), + VG_LITE_RGBA5551 = 34 | (1 << 10), + VG_LITE_ARGB1555 = 35 | (1 << 10), + VG_LITE_XBGR8888 = 36 | (1 << 10), + VG_LITE_XRGB8888 = 37 | (1 << 10), + VG_LITE_RGBA8888_ETC2_EAC = 38 | (1 << 10), + VG_LITE_RGB888 = 39 | (1 << 10), + VG_LITE_BGR888 = 40 | (1 << 10), + VG_LITE_ABGR8565 = 41 | (1 << 10), + VG_LITE_BGRA5658 = 42 | (1 << 10), + VG_LITE_ARGB8565 = 43 | (1 << 10), + VG_LITE_RGBA5658 = 44 | (1 << 10), + VG_LITE_ABGR8565_PLANAR = 45 | (1 << 10), + VG_LITE_BGRA5658_PLANAR = 46 | (1 << 10), + VG_LITE_ARGB8565_PLANAR = 47 | (1 << 10), + VG_LITE_RGBA5658_PLANAR = 48 | (1 << 10), + VG_LITE_NV24 = 49 | (1 << 10), + VG_LITE_NV24_TILED = 50 | (1 << 10), + + VG_LITE_INDEX_1 = 0 | (1 << 11), /*! Indexed format. */ + VG_LITE_INDEX_2 = 1 | (1 << 11), + VG_LITE_INDEX_4 = 2 | (1 << 11), + VG_LITE_INDEX_8 = 3 | (1 << 11), + +} vg_lite_buffer_format_t; + +/* Swizzle of packed YUV format UV channels. */ +typedef enum vg_lite_swizzle { + VG_LITE_SWIZZLE_UV, + VG_LITE_SWIZZLE_VU, +} vg_lite_swizzle_t; + +/* The YUV<->RGB conversion rule. */ +typedef enum vg_lite_yuv2rgb { + VG_LITE_YUV601, + VG_LITE_YUV709, +} vg_lite_yuv2rgb_t; + +/* The pixel layout in a buffer. */ +typedef enum vg_lite_buffer_layout { + VG_LITE_LINEAR, + VG_LITE_TILED, +} vg_lite_buffer_layout_t; + +/* The image (buffer) rendering mode. Match OpenVG enum VGImageMode */ +typedef enum vg_lite_image_mode { + /* For enum value backward compatibility */ + VG_LITE_ZERO = 0, + VG_LITE_NORMAL_IMAGE_MODE = 0x1F00, + VG_LITE_MULTIPLY_IMAGE_MODE = 0x1F01, + VG_LITE_STENCIL_MODE = 0x1F02, + VG_LITE_NONE_IMAGE_MODE = 0x1F03, + VG_LITE_RECOLOR_MODE = 0x1F04, +} vg_lite_image_mode_t; + +/* The image (buffer) transparency mode. */ +typedef enum vg_lite_transparency { + VG_LITE_IMAGE_OPAQUE, + VG_LITE_IMAGE_TRANSPARENT +} vg_lite_transparency_t; + +/* Blending modes. OPENVG_BLEND_* match OpenVG enum VGBlendMode. + * S and D represent source and destination non-premultiplied RGB color channels. + * Sa and Da represent the source and destination alpha channels. + * SP and DP represent source and destination alpha-premultiplied RGB color channels (S*Sa, D*Da). + */ +typedef enum vg_lite_blend { + /* Non-premultiplied Blending modes !*/ + VG_LITE_BLEND_NONE = 0, /*! RGB: S, No blend !*/ + /*! A: Sa !*/ + VG_LITE_BLEND_SRC_OVER = 1, /*! RGB: S + D*(1 - Sa) !*/ + /*! A: Sa + Da*(1 - Sa) !*/ + VG_LITE_BLEND_DST_OVER = 2, /*! RGB: S*(1 - Da) + D !*/ + /*! A: Sa*(1 - Da) + Da !*/ + VG_LITE_BLEND_SRC_IN = 3, /*! RGB: S*Da !*/ + /*! A: Sa*Da !*/ + VG_LITE_BLEND_DST_IN = 4, /*! RGB: D*Sa !*/ + /*! A: Da*Sa !*/ + VG_LITE_BLEND_MULTIPLY = 5, /*! RGB: S*(1 - Da) + D*(1 - Sa) + S*D !*/ + /*! A: Sa*(1 - Da) + Da*(1 - Sa) + Sa*Da !*/ + VG_LITE_BLEND_SCREEN = 6, /*! RGB: S + D - S*D !*/ + /*! A: Sa + Da - Sa*Da !*/ + VG_LITE_BLEND_DARKEN = 7, /*! RGB: min(SrcOver, DstOver) !*/ + /*! A: min(SrcOver, DstOver) !*/ + VG_LITE_BLEND_LIGHTEN = 8, /*! RGB: max(SrcOver, DstOver) !*/ + /*! A: max(SrcOver, DstOver) !*/ + VG_LITE_BLEND_ADDITIVE = 9, /*! RGB: S + D !*/ + /*! A: Sa + Da !*/ + VG_LITE_BLEND_SUBTRACT = 10, /*! RGB: D*(1 - Sa) !*/ + /*! A: Da*(1 - Sa) !*/ + VG_LITE_BLEND_NORMAL_LVGL = 11, /*! RGB: S*Sa + D*(1 - Sa) !*/ + /*! A: 0xFF !*/ + VG_LITE_BLEND_ADDITIVE_LVGL = 12, /*! RGB: (S + D)*Sa + D*(1 - Sa) !*/ + /*! A: 0xFF !*/ + VG_LITE_BLEND_SUBTRACT_LVGL = 13, /*! RGB: (S - D)*Sa + D*(1 - Sa) !*/ + /*! A: 0xFF !*/ + VG_LITE_BLEND_MULTIPLY_LVGL = 14, /*! RGB: (S*D)*Sa + D*(1 - Sa) !*/ + /*! A: 0xFF !*/ + + /* Porter Duff Premultiplied Blending modes !*/ + OPENVG_BLEND_SRC = 0x2000, /*! RGB: SP / Sa, No blend !*/ + /*! A: Sa !*/ + OPENVG_BLEND_SRC_OVER = 0x2001, /*! RGB: (SP + DP*(1 - Sa)) / (Sa + Da*(1 - Sa)) !*/ + /*! A: (Sa + Da*(1 - Sa)) !*/ + OPENVG_BLEND_DST_OVER = 0x2002, /*! RGB: (SP*(1 - Da) + DP) / (Sa*(1 - Da) + Da) !*/ + /*! A: (Sa*(1 - Da) + Da) !*/ + OPENVG_BLEND_SRC_IN = 0x2003, /*! RGB: (SP*Da) / (Sa*Da) !*/ + /*! A: (Sa*Da) !*/ + OPENVG_BLEND_DST_IN = 0x2004, /*! RGB: (DP*Sa) / (Sa*Da) !*/ + /*! A: (Sa*Da) !*/ + OPENVG_BLEND_MULTIPLY = 0x2005, /*! RGB: (SP*DP + SP*(1 - Da) + DP*(1 - Sa)) / (Sa + Da*(1 - Sa)) !*/ + /*! A: (Sa + Da*(1 - Sa)) !*/ + OPENVG_BLEND_SCREEN = 0x2006, /*! RGB: (SP + DP - (SP*DP)) / (Sa + Da*(1 - Sa)) !*/ + /*! A: (Sa + Da*(1 - Sa)) !*/ + OPENVG_BLEND_DARKEN = 0x2007, /*! RGB: (min(SP*Da, DP*Sa) + SP*(1 - Da) + DP*(1 - Sa)) / (Sa + Da*(1 - Sa)) !*/ + /*! A: (Sa + Da*(1 - Sa)) !*/ + OPENVG_BLEND_LIGHTEN = 0x2008, /*! RGB: (max(SP*Da, DP*Sa) + SP*(1 - Da) + DP*(1 - Sa)) / (Sa + Da*(1 - Sa)) !*/ + /*! A: (Sa + Da*(1 - Sa)) !*/ + OPENVG_BLEND_ADDITIVE = 0x2009, /*! RGB: (SP + DP) / (Sa + Da) !*/ + /*! A: (Sa + Da) !*/ +} vg_lite_blend_t; + +/* Fill rules. Match OpenVG enum VGFillRule */ +typedef enum vg_lite_fill { + VG_LITE_FILL_EVEN_ODD = 0x1900, /*! A pixel is drawn it it crosses an odd number of path pixels. */ + VG_LITE_FILL_NON_ZERO = 0x1901, /*! A pixel is drawn if it crosses at least one path pixel. */ +} vg_lite_fill_t; + +/* Global alpha modes. */ +typedef enum vg_lite_global_alpha { + VG_LITE_NORMAL = 0, /*! Use original src/dst alpha value. */ + VG_LITE_GLOBAL, /*! Use global src/dst alpha value to replace original src/dst alpha value. */ + VG_LITE_SCALED, /*! Multiply global src/dst alpha value and original src/dst alpha value. */ +} vg_lite_global_alpha_t; + +/* Filter modes. */ +typedef enum vg_lite_filter { + VG_LITE_FILTER_POINT = 0, /*! Fetch the nearest image pixel. */ + VG_LITE_FILTER_LINEAR = 0x1000, /*! Used for linear paint. */ + VG_LITE_FILTER_BI_LINEAR = 0x2000, /*! Use a 2x2 box around the image pixel and perform an interpolation. */ + VG_LITE_FILTER_GAUSSIAN = 0x3000, /*! Perform 3x3 gaussian blur with the convolution for image pixel. */ +} vg_lite_filter_t; + +/* Pattern padding mode. Match OpenVG enum VGTilingMode. */ +typedef enum vg_lite_pattern_mode { + VG_LITE_PATTERN_COLOR = 0x1D00, /*! Pixel outside the bounds of sourceimage should be taken as the color */ + VG_LITE_PATTERN_PAD = 0x1D01, /*! Pixel outside the bounds of sourceimage should be taken as having the same color as the closest edge pixel */ + VG_LITE_PATTERN_REPEAT = 0x1D02, /*! Pixel outside the bounds of sourceimage should be repeated indefinitely in all directions */ + VG_LITE_PATTERN_REFLECT = 0x1D03, /*! Pixel outside the bounds of sourceimage should be reflected indefinitely in all directions */ +} vg_lite_pattern_mode_t; + +/* Paint type. Match OpenVG enum VGPaintType. */ +typedef enum vg_lite_paint_type { + /* For enum value backward compatibility */ + VG_LITE_PAINT_ZERO = 0, + VG_LITE_PAINT_COLOR = 0x1B00, + VG_LITE_PAINT_LINEAR_GRADIENT = 0x1B01, + VG_LITE_PAINT_RADIAL_GRADIENT = 0x1B02, + VG_LITE_PAINT_PATTERN = 0x1B03, +} vg_lite_paint_type_t; + +/* Radial gradient padding mode. Match OpenVG enum VGColorRampSpreadMode */ +typedef enum { + VG_LITE_GRADIENT_SPREAD_FILL = 0, + VG_LITE_GRADIENT_SPREAD_PAD = 0x1C00, + VG_LITE_GRADIENT_SPREAD_REPEAT = 0x1C01, + VG_LITE_GRADIENT_SPREAD_REFLECT = 0x1C02, +} vg_lite_gradient_spreadmode_t; + +/* Decnano Compress mode. */ +typedef enum vg_lite_compress_mode { + VG_LITE_DEC_DISABLE = 0, /*! disable compress */ + VG_LITE_DEC_NON_SAMPLE, /*! compress ratio is 1.6 if use ARGB8888, compress ratio is 2 if use XRGB8888 */ + VG_LITE_DEC_HSAMPLE, /*! compress ratio is 2 if use ARGB8888, compress ratio is 2.6 if use XRGB8888 */ + VG_LITE_DEC_HV_SAMPLE, /*! compress ratio is 2.6 if use ARGB8888, compress ratio is 4 if use XRGB8888 */ +} vg_lite_compress_mode_t; + +/* Draw path type. Match OpenVG enum VGPaintMode */ +typedef enum vg_lite_path_type { + /* For enum value backward compatibility */ + VG_LITE_DRAW_ZERO = 0, + VG_LITE_DRAW_STROKE_PATH = (1 << 0), + VG_LITE_DRAW_FILL_PATH = (1 << 1), + VG_LITE_DRAW_FILL_STROKE_PATH = (1 << 1 | 1 << 0), +} vg_lite_path_type_t; + +/* End cap style. Match OpenVG enum VGCapStyle */ +typedef enum vg_lite_cap_style { + VG_LITE_CAP_BUTT = 0x1700, + VG_LITE_CAP_ROUND = 0x1701, + VG_LITE_CAP_SQUARE = 0x1702, +} vg_lite_cap_style_t; + +/* Line join styles. Match OpenVG enum VGJoinStyle */ +typedef enum vg_lite_join_style { + VG_LITE_JOIN_MITER = 0x1800, + VG_LITE_JOIN_ROUND = 0x1801, + VG_LITE_JOIN_BEVEL = 0x1802, +} vg_lite_join_style_t; + +/* Mask operation mode. Match OpenVG enum VGMaskOperation */ +typedef enum vg_lite_mask_operation { + VG_LITE_CLEAR_MASK = 0x1500, /*! Set all dest mask values to 0 */ + VG_LITE_FILL_MASK = 0x1501, /*! Set all dest mask values to 1 */ + VG_LITE_SET_MASK = 0x1502, /*! Copy from src masklayer to dest masklayer. */ + VG_LITE_UNION_MASK = 0x1503, /*! Replace dest masklayer by its union with src masklayer. */ + VG_LITE_INTERSECT_MASK = 0x1504, /*! Replace dest masklayer by its intersection with src masklayer. */ + VG_LITE_SUBTRACT_MASK = 0x1505, /*! Subtract src mask in dest masklayer */ +} vg_lite_mask_operation_t; + +/* Mirror orientation mode. */ +typedef enum vg_lite_orientation { + VG_LITE_ORIENTATION_TOP_BOTTOM, + VG_LITE_ORIENTATION_BOTTOM_TOP, +} vg_lite_orientation_t; + +/* Gamma conversion mode. */ +typedef enum vg_lite_gamma_conversion { + VG_LITE_GAMMA_NO_CONVERSION, /*! Leave color as is. */ + VG_LITE_GAMMA_LINEAR, /*! Convert from sRGB to linear space. */ + VG_LITE_GAMMA_NON_LINEAR /*! Convert from linear to sRGB space. */ +} vg_lite_gamma_conversion_t; + +/* Index endian */ +typedef enum vg_lite_index_endian { + VG_LITE_INDEX_LITTLE_ENDIAN, /*! Parse the index pixel from low to high, + *! when using index1, the parsing order is bit0~bit7. + *! when using index2, the parsing order is bit0:1,bit2:3,bit4:5.bit6:7. + *! when using index4, the parsing order is bit0:3,bit4:7. + */ + VG_LITE_INDEX_BIG_ENDIAN, /*! Parse the index pixel from low to high, + *! when using index1, the parsing order is bit7~bit0. + *! when using index2, the parsing order is bit7:6,bit5:4,bit3:2.bit1:0. + *! when using index4, the parsing order is bit4:7,bit0:3. + */ +} vg_lite_index_endian_t; + +/* Map flag*/ +typedef enum vg_lite_map_flag { + VG_LITE_MAP_USER_MEMORY = 0, + VG_LITE_MAP_DMABUF = 0x01, +} vg_lite_map_flag_t; + +/*VGLite parameters variable*/ +typedef enum vg_lite_param_type { + VG_LITE_GPU_IDLE_STATE, /*! count must be 1 for GPU idle state TRUE or FALSE */ + VG_LITE_SCISSOR_RECT, /*! count must be 4n for x, y, right, bottom */ + VG_LITE_HARDWARE_RUNNING_TIME, /*! count must be 1 */ +} vg_lite_param_type_t; + +/* Vg lite buffer type */ +typedef enum vg_lite_buffer_type { + VG_LITE_COMMAND_BUFFER, + VG_LITE_TESSELLATION_BUFFER, + VG_LITE_RENDER_BUFFER, +} vg_lite_buffer_type_t; + +/* Reserve memory index */ +typedef enum vg_lite_memory_pool { + VG_LITE_MEMORY_POOL_1 = 0, + VG_LITE_MEMORY_POOL_2 = 1, +} vg_lite_memory_pool_t; + +typedef enum vg_lite_frame_flag { + VG_LITE_FRAME_END_FLAG = 1, +} vg_lite_frame_flag_t; + +/* VGLite API Structures ******************************************************************************************************************/ + +/* VGLite driver information */ +typedef struct vg_lite_info { + vg_lite_uint32_t api_version; + vg_lite_uint32_t header_version; + vg_lite_uint32_t release_version; + vg_lite_uint32_t reserved; +} vg_lite_info_t; + +/* A 2D Point definition. */ +typedef struct vg_lite_point { + vg_lite_int32_t x; + vg_lite_int32_t y; +} vg_lite_point_t; + +/* Four 2D Point that form a polygon */ +typedef vg_lite_point_t vg_lite_point4_t[4]; + +/* A 2D float Point definition. */ +typedef struct vg_lite_float_point { + vg_lite_float_t x; + vg_lite_float_t y; +} vg_lite_float_point_t; + +/* Four 2D float Point that form a polygon */ +typedef vg_lite_float_point_t vg_lite_float_point4_t[4]; + +/* A rectangle.*/ +typedef struct vg_lite_rectangle { + vg_lite_int32_t x; /*! Left coordinate of rectangle. */ + vg_lite_int32_t y; /*! Top coordinate of rectangle. */ + vg_lite_int32_t width; /*! Width of rectangle. */ + vg_lite_int32_t height; /*! Height of rectangle. */ +} vg_lite_rectangle_t; + +typedef struct vg_lite_matrix { + vg_lite_float_t m[3][3]; /*! The 3x3 matrix is in [row][column] order. */ + vg_lite_float_t scaleX; + vg_lite_float_t scaleY; + vg_lite_float_t angle; +} vg_lite_matrix_t; + +typedef struct vg_lite_yuvinfo { + vg_lite_swizzle_t swizzle; /*! UV swizzle. */ + vg_lite_yuv2rgb_t yuv2rgb; /*! 601 or 709 conversion standard. */ + vg_lite_uint32_t uv_planar; /*! UV(U) planar address. */ + vg_lite_uint32_t v_planar; /*! V planar address. */ + vg_lite_uint32_t alpha_planar; /*! Alpha planar address. */ + vg_lite_uint32_t uv_stride; /*! UV(U) stride. */ + vg_lite_uint32_t v_stride; /*! V stride. */ + vg_lite_uint32_t alpha_stride; /*! Alpha stride. */ + vg_lite_uint32_t uv_height; /*! UV(U) height. */ + vg_lite_uint32_t v_height; /*! V height. */ + vg_lite_pointer uv_memory; /*! The logical pointer to the UV(U) planar memory. */ + vg_lite_pointer v_memory; /*! The logical pointer to the V planar memory. */ + vg_lite_pointer uv_handle; /*! The memory handle of the UV(U) planar. */ + vg_lite_pointer v_handle; /*! The memory handle of the V planar. */ +} vg_lite_yuvinfo_t; + +typedef struct vg_lite_path_point * vg_lite_path_point_ptr; +typedef struct vg_lite_path_point { + /* X coordinate. */ + vg_lite_float_t x; + + /* Y coordinate. */ + vg_lite_float_t y; + + /* Flatten flag for flattened path. */ + vg_lite_uint8_t flatten_flag; + + /* Curve type for stroke path. */ + vg_lite_uint8_t curve_type; + + /* X tangent. */ + vg_lite_float_t tangentX; + + /* Y tangent. */ + vg_lite_float_t tangentY; + + /* Length of the line. */ + vg_lite_float_t length; + + /* Pointer to next point node. */ + vg_lite_path_point_ptr next; + + /* Pointer to previous point node. */ + vg_lite_path_point_ptr prev; + +} vg_lite_path_point_t; + +typedef struct vg_lite_sub_path * vg_lite_sub_path_ptr; +typedef struct vg_lite_sub_path { + /* Pointer to next sub path. */ + vg_lite_sub_path_ptr next; + + /* Number of points. */ + vg_lite_uint32_t point_count; + + /* Point list. */ + vg_lite_path_point_ptr point_list; + + /* Last point. */ + vg_lite_path_point_ptr end_point; + + /* Whether is path is closed. */ + vg_lite_uint8_t closed; + + /* Sub path length. */ + vg_lite_float_t length; + +} vg_lite_sub_path_t; + +/* Save divided path data according to MOVE/MOVE_REL. */ +typedef struct vg_lite_path_list * vg_lite_path_list_ptr; +typedef struct vg_lite_path_list { + vg_lite_path_point_ptr path_points; + vg_lite_path_point_ptr path_end; + vg_lite_uint32_t point_count; + vg_lite_path_list_ptr next; + vg_lite_uint8_t closed; + +} vg_lite_path_list_t; + +/* Memory allocation info by kernel. */ +typedef struct vg_lite_hw_memory { + vg_lite_pointer handle; /*! gpu memory object handle. */ + vg_lite_pointer memory; /*! logical memory address. */ + vg_lite_uint32_t address; /*! GPU memory address. */ + vg_lite_uint32_t bytes; /*! Size of memory. */ + vg_lite_uint32_t property; /*! Currently bit0 is used for path upload state: + *! 1 : enable auto path data uploading. + *! 0 : disable path data uploading. path data is embedded in command buffer. */ +} vg_lite_hw_memory_t; + +typedef struct vg_lite_stroke { + /* Stroke parameters */ + vg_lite_cap_style_t cap_style; + vg_lite_join_style_t join_style; + vg_lite_float_t line_width; + vg_lite_float_t miter_limit; + vg_lite_float_t * dash_pattern; + vg_lite_uint32_t pattern_count; + vg_lite_float_t dash_phase; + vg_lite_float_t dash_length; + vg_lite_uint32_t dash_index; + vg_lite_float_t half_width; + + /* Total length of stroke dash patterns. */ + vg_lite_float_t pattern_length; + + /* For fast checking. */ + vg_lite_float_t miter_square; + + /* Temp storage of stroke subPath. */ + vg_lite_path_point_ptr path_points; + vg_lite_path_point_ptr path_end; + vg_lite_uint32_t point_count; + vg_lite_path_point_ptr left_point; + vg_lite_path_point_ptr right_point; + vg_lite_path_point_ptr stroke_points; + vg_lite_path_point_ptr stroke_end; + vg_lite_uint32_t stroke_count; + + /* Divide stroke path according to move or move_rel for avoiding implicit closure. */ + vg_lite_path_list_ptr path_list_divide; + + /* pointer to current divided path data. */ + vg_lite_path_list_ptr cur_list; + + /* Flag that add end_path in driver. */ + vg_lite_uint8_t add_end; + vg_lite_uint8_t dash_reset; + + /* Sub path list. */ + vg_lite_sub_path_ptr stroke_paths; + + /* Last sub path. */ + vg_lite_sub_path_ptr last_stroke; + + /* Swing area handling. */ + vg_lite_uint32_t swing_handling; + vg_lite_float_t swing_deltax; + vg_lite_float_t swing_deltay; + vg_lite_path_point_ptr swing_start; + vg_lite_path_point_ptr swing_stroke; + vg_lite_float_t swing_length; + vg_lite_float_t swing_centlen; + vg_lite_uint32_t swing_count; + vg_lite_uint8_t need_swing; + vg_lite_uint8_t swing_ccw; + + vg_lite_float_t stroke_length; + vg_lite_uint32_t stroke_size; + + /* The stroke line is fat line. */ + vg_lite_uint8_t fattened; + vg_lite_uint8_t closed; + vg_lite_hw_memory_t uploaded; + +} vg_lite_stroke_t; + +/* Fast clear buffer. */ +typedef struct vg_lite_fc_buffer { + vg_lite_int32_t width; /*! Width of the buffer in pixels. */ + vg_lite_int32_t height; /*! height of the buffer in pixels. */ + vg_lite_int32_t stride; /*! The number of bytes to move from one line in the buffer to the next line. */ + vg_lite_pointer + handle; /*! The memory handle of the buffer's memory as allocated by the VGLite kernel. */ + vg_lite_pointer memory; /*! The logical pointer to the buffer's memory for the CPU. */ + vg_lite_uint32_t address; /*! The address to the buffer's memory for the hardware. */ + vg_lite_uint32_t color; /*! The fastclear color value. */ +} vg_lite_fc_buffer_t; + +/* Structure for any image or render target. */ +typedef struct vg_lite_buffer { + vg_lite_int32_t width; /*! Width of the buffer in pixels. */ + vg_lite_int32_t height; /*! Height of the buffer in pixels. */ + vg_lite_int32_t stride; /*! The number of bytes to move from one line in the buffer to the next line. */ + vg_lite_buffer_layout_t tiled; /*! Indicating the buffer memory layout is linear or tiled. */ + vg_lite_buffer_format_t format; /*! The pixel format of the buffer. */ + vg_lite_pointer + handle; /*! The memory handle of the buffer's memory as allocated by the VGLite kernel. */ + vg_lite_pointer memory; /*! The logical pointer to the buffer's memory for the CPU. */ + vg_lite_uint32_t address; /*! The address to the buffer's memory for the hardware. */ + vg_lite_memory_pool_t pool; /*! The buffer's memory pool. */ + vg_lite_yuvinfo_t yuv; /*! The yuv format details. */ + vg_lite_image_mode_t image_mode; /*! The blit image mode. */ + vg_lite_transparency_t transparency_mode; /*! image transparency mode. */ + vg_lite_fc_buffer_t fc_buffer[3]; /*! 3 fastclear buffers,reserved YUV format. */ + vg_lite_compress_mode_t compress_mode; /*! Refer to the definition by vg_lite_compress_mode_t. */ + vg_lite_index_endian_t index_endian; /*! Refer to the definition by vg_lite_index_endian_t. */ + vg_lite_paint_type_t paintType; /*! Get paintcolor from different paint types. */ + vg_lite_uint8_t fc_enable; /*! enable im fastclear. */ + vg_lite_uint8_t scissor_buffer; /*! The buffer is scissor mask buffer. */ + vg_lite_uint8_t premultiplied; /*! The RGB pixel values are alpha-premultipled */ + vg_lite_uint8_t apply_premult; /*! Need to apply alpha-premultiply */ + struct vg_lite_buffer * lvgl_buffer; /*! Buffer for SW LVGL blending support */ + vg_lite_color_t bg_color; /*! Background for edge filter */ +} vg_lite_buffer_t; + +/* Path info for drawing command. */ +typedef struct vg_lite_path { + vg_lite_float_t bounding_box[4]; /*! Bounding box specified as left, top, right, and bottom. */ + vg_lite_quality_t quality; /*! Quality hint for the path. */ + vg_lite_format_t format; /*! Coordinate format. */ + vg_lite_hw_memory_t uploaded; /*! Path data that has been upload into GPU addressable memory. */ + vg_lite_uint32_t path_length; /*! Number of bytes in the path data. */ + vg_lite_pointer path; /*! Pointer to the physical description of the path. */ + vg_lite_int8_t + path_changed; /*! Indicate whether path data is synced with command buffer (uploaded) or not. */ + vg_lite_int8_t pdata_internal; /*! Indicate whether path data memory is allocated by driver. */ + vg_lite_path_type_t path_type; /*! Refer to the definition by vg_lite_path_type_t. */ + vg_lite_stroke_t * stroke; /*! Pointer to a vg_lite_stroke_t structure.*/ + vg_lite_pointer stroke_path; /*! Pointer to the physical description of the stroke path. */ + vg_lite_uint32_t stroke_size; /*! Number of bytes in the stroke path data. */ + vg_lite_color_t stroke_color; /*! The stroke path fill color. */ + vg_lite_int8_t add_end; /*! Flag that add end_path in driver. */ + vg_lite_int8_t + stroke_valid; /*! Flag that judge whether current stroke data is come from current pathdata. */ +} vg_lite_path_t; + +/* Color ramp definition. */ +typedef struct vg_lite_color_ramp { + vg_lite_float_t stop; /*! Value for the color stop. */ + vg_lite_float_t red; /*! Red color channel value for the color stop. */ + vg_lite_float_t green; /*! Green color channel value for the color stop. */ + vg_lite_float_t blue; /*! Blue color channel value for the color stop. */ + vg_lite_float_t alpha; /*! Alpha color channel value for the color stop. */ +} vg_lite_color_ramp_t; + +/* Linear gradient parameter */ +typedef struct vg_lite_linear_gradient_parameter { + vg_lite_float_t X0; + vg_lite_float_t Y0; + vg_lite_float_t X1; + vg_lite_float_t Y1; +} vg_lite_linear_gradient_parameter_t; + +typedef struct vg_lite_radial_gradient_parameter { + vg_lite_float_t cx; /*! x coordinate of the center point. */ + vg_lite_float_t cy; /*! y coordinate of the center point. */ + vg_lite_float_t r; /*! radius. */ + vg_lite_float_t fx; /*! x coordinate of the focal point. */ + vg_lite_float_t fy; /*! y coordinate of the focal point. */ +} vg_lite_radial_gradient_parameter_t; + +/* Linear gradient definition. */ +typedef struct vg_lite_linear_gradient { + vg_lite_uint32_t colors[VLC_MAX_GRADIENT_STOPS]; /*! Colors for stops. */ + vg_lite_uint32_t count; /*! Count of colors, up to 16. */ + vg_lite_uint32_t stops[VLC_MAX_GRADIENT_STOPS]; /*! Color stops, value from 0 to 255. */ + vg_lite_matrix_t matrix; /*! The matrix to transform the gradient. */ + vg_lite_buffer_t image; /*! The image for rendering as gradient pattern. */ +} vg_lite_linear_gradient_t; + +/* Extended linear gradient definition. */ +typedef struct vg_lite_ext_linear_gradient { + vg_lite_uint32_t count; /*! Count of colors, up to 256. */ + vg_lite_matrix_t matrix; /*! The matrix to transform the gradient. */ + vg_lite_buffer_t image; /*! The image for rendering as gradient pattern. */ + vg_lite_linear_gradient_parameter_t linear_grad; /*! Include center point,focal point and radius.*/ + + vg_lite_uint32_t ramp_length; /*! Color ramp for gradient paints provided to driver. */ + vg_lite_color_ramp_t color_ramp[VLC_MAX_COLOR_RAMP_STOPS]; + + vg_lite_uint32_t converted_length; /*! Converted internal color ramp. */ + vg_lite_color_ramp_t converted_ramp[VLC_MAX_COLOR_RAMP_STOPS + 2]; + + vg_lite_uint8_t + pre_multiplied; /*! If color values of color_ramp[] are multiply by alpha value of color_ramp[]. */ + vg_lite_gradient_spreadmode_t + spread_mode; /*! The spread mode that applied to the pixels out of the image after transformed. */ +} vg_lite_ext_linear_gradient_t; + +/* Radial gradient definition. */ +typedef struct vg_lite_radial_gradient { + vg_lite_uint32_t count; /*! Count of colors, up to 256. */ + vg_lite_matrix_t matrix; /*! The matrix to transform the gradient. */ + vg_lite_buffer_t image; /*! The image for rendering as gradient pattern. */ + vg_lite_radial_gradient_parameter_t radial_grad; /*! Include center point,focal point and radius.*/ + + vg_lite_uint32_t ramp_length; /*! Color ramp for gradient paints provided to the driver. */ + vg_lite_color_ramp_t color_ramp[VLC_MAX_COLOR_RAMP_STOPS]; + + vg_lite_uint32_t converted_length; /*! Converted internal color ramp. */ + vg_lite_color_ramp_t converted_ramp[VLC_MAX_COLOR_RAMP_STOPS + 2]; + + vg_lite_uint8_t + pre_multiplied; /*! If color values of color_ramp[] are multiply by alpha value of color_ramp[]. */ + vg_lite_gradient_spreadmode_t + spread_mode; /*! The spread mode that applied to the pixels out of the image after transformed. */ +} vg_lite_radial_gradient_t; + +/* Colorkey definition */ +typedef struct vg_lite_color_key { + vg_lite_uint8_t enable; /*! The color key is effective only when "enable" is ture, */ + vg_lite_uint8_t low_r; /*! The R chanel of low_rgb. */ + vg_lite_uint8_t low_g; /*! The G chanel of low_rgb. */ + vg_lite_uint8_t low_b; /*! The B chanel of low_rgb. */ + vg_lite_uint8_t alpha; /*! The alpha channel to replace destination pixel alpha channel.*/ + vg_lite_uint8_t hign_r; /*! The R chanel of hign_rgb. */ + vg_lite_uint8_t hign_g; /*! The G chanel of hign_rgb. */ + vg_lite_uint8_t hign_b; /*! The B chanel of hign_rgb. */ +} vg_lite_color_key_t; + +/* Four colorkey definition. + * rgb_hi_0, rgb_lo_0, alpha_0, enable_0; + * rgb_hi_1, rgb_lo_1, alpha_1, enable_1; + * rgb_hi_2, rgb_lo_2, alpha_2, enable_2; + * rgb_hi_3, rgb_lo_3, alpha_3, enable_3; + * Priority order: color_key_0 > color_key_1 > color_key_2 > color_key_3. +*/ +typedef vg_lite_color_key_t vg_lite_color_key4_t[4]; + +/* Pixel matrix values */ +typedef vg_lite_float_t vg_lite_pixel_matrix_t[20]; + +/* HW pixel channel enable flags */ +typedef struct vg_lite_pixel_channel_enable { + vg_lite_uint8_t enable_a; /*! Enable A channel.*/ + vg_lite_uint8_t enable_b; /*! Enable B channel. */ + vg_lite_uint8_t enable_g; /*! Enable G channel. */ + vg_lite_uint8_t enable_r; /*! Enable R channel. */ +} vg_lite_pixel_channel_enable_t; + +/* Pixel color transform */ +typedef struct vg_lite_color_transform { + vg_lite_float_t a_scale; + vg_lite_float_t a_bias; + vg_lite_float_t r_scale; + vg_lite_float_t r_bias; + vg_lite_float_t g_scale; + vg_lite_float_t g_bias; + vg_lite_float_t b_scale; + vg_lite_float_t b_bias; +} vg_lite_color_transform_t; + +/* VGLite API Functions *******************************************************************************************************************/ + +/* Initialize a vglite context. */ +vg_lite_error_t vg_lite_init(vg_lite_uint32_t tess_width, vg_lite_uint32_t tess_height); + +/* Destroy a vglite context. */ +vg_lite_error_t vg_lite_close(void); + +/* Get the VGLite driver information. */ +vg_lite_error_t vg_lite_get_info(vg_lite_info_t * info); + +/* Get the GPU chip information. */ +vg_lite_uint32_t vg_lite_get_product_info(vg_lite_char * name, vg_lite_uint32_t * chip_id, vg_lite_uint32_t * chip_rev); + +/* Query if a specific feature is supported. */ +vg_lite_uint32_t vg_lite_query_feature(vg_lite_feature_t feature); + +/* Flush command buffer and wait for GPU to complete. */ +vg_lite_error_t vg_lite_finish(void); + +/* Flush the command buffer without waiting for GPU to complete. */ +vg_lite_error_t vg_lite_flush(void); + +/* Get the value of register from register's address. */ +vg_lite_error_t vg_lite_get_register(vg_lite_uint32_t address, vg_lite_uint32_t * result); + +/* Generate a 3x3 homogenous matrix to transform 4 source coordinates to 4 target coordinates. */ +vg_lite_error_t vg_lite_get_transform_matrix(vg_lite_float_point4_t src, vg_lite_float_point4_t dst, + vg_lite_matrix_t * mat); + +/* Allocate a buffer from GPU hardware accessible memory. */ +vg_lite_error_t vg_lite_allocate(vg_lite_buffer_t * buffer); + +/* Free a buffer allocated by vg_lite_allocate() */ +vg_lite_error_t vg_lite_free(vg_lite_buffer_t * buffer); + +/* Upload RGB or YUV pixel data to an allocated buffer. */ +vg_lite_error_t vg_lite_upload_buffer(vg_lite_buffer_t * buffer, vg_lite_uint8_t * data[3], vg_lite_uint32_t stride[3]); + +/* Map a buffer into hardware accessible address space. */ +vg_lite_error_t vg_lite_map(vg_lite_buffer_t * buffer, vg_lite_map_flag_t flag, int32_t fd); + +/* Unmap a buffer that is mapped */ +vg_lite_error_t vg_lite_unmap(vg_lite_buffer_t * buffer); + +/* flush cache */ +vg_lite_error_t vg_lite_flush_mapped_buffer(vg_lite_buffer_t * buffer); + +/* Fill a buffer rectangle area with a specified color. */ +vg_lite_error_t vg_lite_clear(vg_lite_buffer_t * target, vg_lite_rectangle_t * rect, vg_lite_color_t color); + +/* Copy a source image to target buffer with transformation, blending, color mixing, and filtering. */ +vg_lite_error_t vg_lite_blit(vg_lite_buffer_t * target, + vg_lite_buffer_t * source, + vg_lite_matrix_t * matrix, + vg_lite_blend_t blend, + vg_lite_color_t color, + vg_lite_filter_t filter); + +/* Copy a rectangle area of source image to target buffer with transformation, blending, color mixing, and filtering. */ +vg_lite_error_t vg_lite_blit_rect(vg_lite_buffer_t * target, + vg_lite_buffer_t * source, + vg_lite_rectangle_t * rect, + vg_lite_matrix_t * matrix, + vg_lite_blend_t blend, + vg_lite_color_t color, + vg_lite_filter_t filter); + +/* Copy two source images to the target buffer with transformation, blending, and filtering. */ +vg_lite_error_t vg_lite_blit2(vg_lite_buffer_t * target, + vg_lite_buffer_t * source0, + vg_lite_buffer_t * source1, + vg_lite_matrix_t * matrix0, + vg_lite_matrix_t * matrix1, + vg_lite_blend_t blend, + vg_lite_filter_t filter); + +/* Copy a rectangle area of source image to target buffer without transformation, blending, color mixing, and filtering. */ +vg_lite_error_t vg_lite_copy_image(vg_lite_buffer_t * target, + vg_lite_buffer_t * source, + vg_lite_int32_t sx, + vg_lite_int32_t sy, + vg_lite_int32_t dx, + vg_lite_int32_t dy, + vg_lite_uint32_t width, + vg_lite_uint32_t height); + +/* Draw a path to a target buffer with transformation, color, and blending */ +vg_lite_error_t vg_lite_draw(vg_lite_buffer_t * target, + vg_lite_path_t * path, + vg_lite_fill_t fill_rule, + vg_lite_matrix_t * matrix, + vg_lite_blend_t blend, + vg_lite_color_t color); + +/* Set stroke path attributes. */ +vg_lite_error_t vg_lite_set_stroke(vg_lite_path_t * path, + vg_lite_cap_style_t cap_style, + vg_lite_join_style_t join_style, + vg_lite_float_t line_width, + vg_lite_float_t miter_limit, + vg_lite_float_t * dash_pattern, + vg_lite_uint32_t pattern_count, + vg_lite_float_t dash_phase, + vg_lite_color_t color); + +/* Update stroke path. */ +vg_lite_error_t vg_lite_update_stroke(vg_lite_path_t * path); + +/* Set path type. */ +vg_lite_error_t vg_lite_set_path_type(vg_lite_path_t * path, vg_lite_path_type_t path_type); + +/* Clears all attributes of a path. */ +vg_lite_error_t vg_lite_clear_path(vg_lite_path_t * path); + +/* Upload a path to GPU memory so GPU can access it directly. */ +vg_lite_error_t vg_lite_upload_path(vg_lite_path_t * path); + +/* Initialize a path object with attributes. */ +vg_lite_error_t vg_lite_init_path(vg_lite_path_t * path, + vg_lite_format_t format, + vg_lite_quality_t quality, + vg_lite_uint32_t length, + vg_lite_pointer data, + vg_lite_float_t min_x, + vg_lite_float_t min_y, + vg_lite_float_t max_x, + vg_lite_float_t max_y); + +/* Initializes a arc path with attributes. */ +vg_lite_error_t vg_lite_init_arc_path(vg_lite_path_t * path, + vg_lite_format_t format, + vg_lite_quality_t quality, + vg_lite_uint32_t length, + vg_lite_pointer data, + vg_lite_float_t min_x, + vg_lite_float_t min_y, + vg_lite_float_t max_x, + vg_lite_float_t max_y); + +/* Return the size (in bytes) of command buffer for a path opcode array. */ +vg_lite_uint32_t vg_lite_get_path_length(vg_lite_uint8_t * opcode, + vg_lite_uint32_t count, + vg_lite_format_t format); + +/* Generate command buffer for the (path) based on input opcodes (opcode) and coordinates (data). */ +vg_lite_error_t vg_lite_append_path(vg_lite_path_t * path, + vg_lite_uint8_t * opcode, + vg_lite_pointer data, + vg_lite_uint32_t seg_count); + +/* Set CLUT (Color Look Up Table) for index image. The (colors) is in ARGB format. */ +vg_lite_error_t vg_lite_set_CLUT(vg_lite_uint32_t count, vg_lite_uint32_t * colors); + +/* Draw a path that is filled by a transformed image pattern. */ +vg_lite_error_t vg_lite_draw_pattern(vg_lite_buffer_t * target, + vg_lite_path_t * path, + vg_lite_fill_t fill_rule, + vg_lite_matrix_t * path_matrix, + vg_lite_buffer_t * pattern_image, + vg_lite_matrix_t * pattern_matrix, + vg_lite_blend_t blend, + vg_lite_pattern_mode_t pattern_mode, + vg_lite_color_t pattern_color, + vg_lite_color_t color, + vg_lite_filter_t filter); + +/* Initialize a linear gradient object with default attributes. */ +vg_lite_error_t vg_lite_init_grad(vg_lite_linear_gradient_t * grad); + +/* Reset a linear gradient object attributes. */ +vg_lite_error_t vg_lite_clear_grad(vg_lite_linear_gradient_t * grad); + +/* Update a linear gradient object. */ +vg_lite_error_t vg_lite_update_grad(vg_lite_linear_gradient_t * grad); + +/* Return pointer to a linear gradient object's matrix. */ +vg_lite_matrix_t * vg_lite_get_grad_matrix(vg_lite_linear_gradient_t * grad); + +/* Set attributes for a linear gradient object. */ +vg_lite_error_t vg_lite_set_grad(vg_lite_linear_gradient_t * grad, + vg_lite_uint32_t count, + vg_lite_uint32_t * colors, + vg_lite_uint32_t * stops); + +/* Draw a path with a linear gradient object pattern. */ +vg_lite_error_t vg_lite_draw_grad(vg_lite_buffer_t * target, + vg_lite_path_t * path, + vg_lite_fill_t fill_rule, + vg_lite_matrix_t * matrix, + vg_lite_linear_gradient_t * grad, + vg_lite_blend_t blend); + +/* Reset an extended linear gradient object attributes and free image buffer. */ +vg_lite_error_t vg_lite_clear_linear_grad(vg_lite_ext_linear_gradient_t * grad); + +/* Update an extended linear gradient object. */ +vg_lite_error_t vg_lite_update_linear_grad(vg_lite_ext_linear_gradient_t * grad); + +/* Return pointer to an extended linear gradient object's matrix. */ +vg_lite_matrix_t * vg_lite_get_linear_grad_matrix(vg_lite_ext_linear_gradient_t * grad); + +/* Set attributes for an extended linear gradient object. */ +vg_lite_error_t vg_lite_set_linear_grad(vg_lite_ext_linear_gradient_t * grad, + vg_lite_uint32_t count, + vg_lite_color_ramp_t * color_ramp, + vg_lite_linear_gradient_parameter_t grad_param, + vg_lite_gradient_spreadmode_t spread_mode, + vg_lite_uint8_t pre_mult); + +/* Draw a path with an extended linear gradient object. */ +vg_lite_error_t vg_lite_draw_linear_grad(vg_lite_buffer_t * target, + vg_lite_path_t * path, + vg_lite_fill_t fill_rule, + vg_lite_matrix_t * path_matrix, + vg_lite_ext_linear_gradient_t * grad, + vg_lite_color_t paint_color, + vg_lite_blend_t blend, + vg_lite_filter_t filter); + +/* Reset a radial gradient object attributes and free image buffer. */ +vg_lite_error_t vg_lite_clear_radial_grad(vg_lite_radial_gradient_t * grad); + +/* Update a radial gradient object. */ +vg_lite_error_t vg_lite_update_radial_grad(vg_lite_radial_gradient_t * grad); + +/* Return pointer to a radial gradient object's matrix. */ +vg_lite_matrix_t * vg_lite_get_radial_grad_matrix(vg_lite_radial_gradient_t * grad); + +/* Set attributes for a radial gradient object. */ +vg_lite_error_t vg_lite_set_radial_grad(vg_lite_radial_gradient_t * grad, + vg_lite_uint32_t count, + vg_lite_color_ramp_t * color_ramp, + vg_lite_radial_gradient_parameter_t grad_param, + vg_lite_gradient_spreadmode_t spread_mode, + vg_lite_uint8_t pre_mult); + +/* Draw a path with a radial gradient object pattern. */ +vg_lite_error_t vg_lite_draw_radial_grad(vg_lite_buffer_t * target, + vg_lite_path_t * path, + vg_lite_fill_t fill_rule, + vg_lite_matrix_t * path_matrix, + vg_lite_radial_gradient_t * grad, + vg_lite_color_t paint_color, + vg_lite_blend_t blend, + vg_lite_filter_t filter); + +/* Load an identity matrix. */ +vg_lite_error_t vg_lite_identity(vg_lite_matrix_t * matrix); + +/* Translate a matrix. */ +vg_lite_error_t vg_lite_translate(vg_lite_float_t x, vg_lite_float_t y, vg_lite_matrix_t * matrix); + +/* Scale a matrix. */ +vg_lite_error_t vg_lite_scale(vg_lite_float_t scale_x, vg_lite_float_t scale_y, vg_lite_matrix_t * matrix); + +/* Rotate a matrix. */ +vg_lite_error_t vg_lite_rotate(vg_lite_float_t degrees, vg_lite_matrix_t * matrix); + +/* Set and enable a scissor rectangle for render target. */ +vg_lite_error_t vg_lite_set_scissor(vg_lite_int32_t x, vg_lite_int32_t y, vg_lite_int32_t right, + vg_lite_int32_t bottom); + +/* Set scissor rectangles on mask layer. Scissor rects are enabled/disabled by following APIs. */ +vg_lite_error_t vg_lite_scissor_rects(vg_lite_buffer_t * target, vg_lite_uint32_t nums, vg_lite_rectangle_t rect[]); + +/* Enable scissor rects defined on mask layer. */ +vg_lite_error_t vg_lite_enable_scissor(void); + +/* Disable scissor rects defined on mask layer. */ +vg_lite_error_t vg_lite_disable_scissor(void); + +/* Query size of available contiguous video memory. */ +vg_lite_error_t vg_lite_get_mem_size(vg_lite_uint32_t * size); + +/* Set global alpha value for source image */ +vg_lite_error_t vg_lite_source_global_alpha(vg_lite_global_alpha_t alpha_mode, vg_lite_uint8_t alpha_value); + +/* Set global alpha value for destination image. */ +vg_lite_error_t vg_lite_dest_global_alpha(vg_lite_global_alpha_t alpha_mode, vg_lite_uint8_t alpha_value); + +/* Set colorkey. */ +vg_lite_error_t vg_lite_set_color_key(vg_lite_color_key4_t colorkey); + +/* Enable dither function. Dither is OFF by default. */ +vg_lite_error_t vg_lite_enable_dither(void); + +/* Disable dither function. Dither is OFF by default. */ +vg_lite_error_t vg_lite_disable_dither(void); + +/* Set a 64-byte aligned memory buffer (physical) as VGLite tessellation buffer. */ +vg_lite_error_t vg_lite_set_tess_buffer(vg_lite_uint32_t physical, vg_lite_uint32_t size); + +/* Can be called before vg_lite_init() to overwrite the default VG_LITE_COMMAND_BUFFER_SIZE */ +vg_lite_error_t vg_lite_set_command_buffer_size(vg_lite_uint32_t size); + +/* Set a user-defined external memory buffer (physical, 64-byte aligned) as VGLite command buffer. + It should be called after vg_lite_init(). */ +vg_lite_error_t vg_lite_set_command_buffer(vg_lite_uint32_t physical, vg_lite_uint32_t size); + +/* Setup a pixel transform matrix m[20] which transforms each pixel as following: + * + * |a'| |m0 m1 m2 m3 m4 | |a| + * |r'| |m5 m6 m7 m8 m9 | |r| + * |g'| = |m10 m11 m12 m13 m14|.|g| + * |b'| |m15 m16 m17 m18 m19| |b| + * |1 | |0 0 0 0 1 | |1| + * + * The pixel transform for A, R, G, B channel can be enabled/disabled individually with (channel) parameter. + */ +vg_lite_error_t vg_lite_set_pixel_matrix(vg_lite_pixel_matrix_t matrix, vg_lite_pixel_channel_enable_t * channel); + +/* Setup 3x3 gaussian blur weight values to filter image pixels. + * + * Paramters w0, w1, w2 define a 3x3 gaussian blur weight matrix as below + * + * | w2 w1 w2 | + * | w1 w0 w1 | + * | w2 w1 w2 | + * + * The sum of 9 kernel weights must be 1.0 to avoid convolution overflow ( w0 + 4*w1 + 4*w2 = 1.0 ). + * The 3x3 weight matrix applies to a 3x3 pixel block + * + * | pixel[i-1][j-1] pixel[i][j-1] pixel[i+1][j-1]| + * | pixel[i-1][j] pixel[i][j] pixel[i+1][j] | + * | pixel[i-1][j+1] pixel[i][j+1] pixel[i+1][j+1]| + * + * With the following dot product equation: + * + * color[i][j] = w2*pixel[i-1][j-1] + w1*pixel[i][j-1] + w2*pixel[i+1][j-1] + * + w1*pixel[i-1][j] + w0*pixel[i][j] + w1*pixel[i+1][j] + * + w2*pixel[i-1][j+1] + w1*pixel[i][j+1] + w2*pixel[i+1][j+1]; + */ +vg_lite_error_t vg_lite_gaussian_filter(vg_lite_float_t w0, vg_lite_float_t w1, vg_lite_float_t w2); + +/* Enable masklayer function. Masklayer is OFF by default. */ +vg_lite_error_t vg_lite_enable_masklayer(void); + +/* Disable masklayer function. Masklayer is OFF by default. */ +vg_lite_error_t vg_lite_disable_masklayer(void); + +/* Setup a masklayer. */ +vg_lite_error_t vg_lite_set_masklayer(vg_lite_buffer_t * masklayer); + +/* Free a masklayer and disable mask operation. */ +vg_lite_error_t vg_lite_destroy_masklayer(vg_lite_buffer_t * masklayer); + +/* Create a masklayer with default format A8 and default pixel value 255. */ +vg_lite_error_t vg_lite_create_masklayer(vg_lite_buffer_t * masklayer, + vg_lite_uint32_t width, + vg_lite_uint32_t height); + +/* Set pixel values for a rectangle area in a masklayer */ +vg_lite_error_t vg_lite_fill_masklayer(vg_lite_buffer_t * masklayer, + vg_lite_rectangle_t * rect, + vg_lite_uint8_t value); + +/* Blend a rectangle area of src masklayer with dst masklayer according to (operation). */ +vg_lite_error_t vg_lite_blend_masklayer(vg_lite_buffer_t * dst, + vg_lite_buffer_t * src, + vg_lite_mask_operation_t operation, + vg_lite_rectangle_t * rect); + +/* Render a (path) with (fill_rule), (color), (matrix) to the masklayer. */ +vg_lite_error_t vg_lite_render_masklayer(vg_lite_buffer_t * masklayer, + vg_lite_mask_operation_t operation, + vg_lite_path_t * path, + vg_lite_fill_t fill_rule, + vg_lite_color_t color, + vg_lite_matrix_t * matrix); + +/* Set mirror orientation. */ +vg_lite_error_t vg_lite_set_mirror(vg_lite_orientation_t orientation); + +/* Set gamma value. */ +vg_lite_error_t vg_lite_set_gamma(vg_lite_gamma_conversion_t gamma_value); + +/* Enable color transformation, which is OFF by default. */ +vg_lite_error_t vg_lite_enable_color_transform(void); + +/* Disable color transformation, which is OFF by default. */ +vg_lite_error_t vg_lite_disable_color_transform(void); + +/* Set pixel color transformation scale and bias values for each pixel channel. */ +vg_lite_error_t vg_lite_set_color_transform(vg_lite_color_transform_t * values); + +/* Set flexa stream id. */ +vg_lite_error_t vg_lite_flexa_set_stream(vg_lite_uint8_t stream_id); + +/* set flexa background buffer.*/ +vg_lite_error_t vg_lite_flexa_bg_buffer(vg_lite_uint8_t stream_id, + vg_lite_buffer_t * buffer, + vg_lite_uint32_t seg_count, + vg_lite_uint32_t seg_size); + +/* Enable flexa. */ +vg_lite_error_t vg_lite_flexa_enable(void); + +/* Disable flexa.*/ +vg_lite_error_t vg_lite_flexa_disable(void); + +/* Set flexa stop flag after the last frame. */ +vg_lite_error_t vg_lite_flexa_stop_frame(void); + +/* Dump command buffer */ +vg_lite_error_t vg_lite_dump_command_buffer(void); + +/* Dump vg_lite_buffer_t image to a png file. Support on Linux for now. */ +vg_lite_error_t vg_lite_dump_png(const char * filename, vg_lite_buffer_t * buffer); + +/* Return VGLite parameters in params[] array */ +vg_lite_error_t vg_lite_get_parameter(vg_lite_param_type_t type, + vg_lite_int32_t count, + vg_lite_pointer params); + +/* Set memory pool for different buffer allocations. By default all memory buffers are allocated from VG_LITE_MEMORY_POOL_1. + * This API must be called before vg_lite_init() for setting VG_LITE_COMMAND_BUFFER or VG_LITE_TESSELLATION_BUFFER memory pools. + * This API can be called anytime for VG_LITE_RENDER_BUFFER to affect the following vg_lite_allocate() calls. + */ +vg_lite_error_t vg_lite_set_memory_pool(vg_lite_buffer_type_t type, vg_lite_memory_pool_t pool); + +/* Set an end flag for GPU to signal its completion of current frame. + * This API can be called at the end of a frame, and a vg_lite_finish() is contained withen the API. + * An interrupt will be received to indicate that GPU is idle. + */ +vg_lite_error_t vg_lite_frame_delimiter(vg_lite_frame_flag_t flag); + +#endif /* VGLITE_VERSION_3_0 */ + +#endif /* LV_USE_VG_LITE_DRIVER */ + +#ifdef __cplusplus +} +#endif + +#endif /* VG_LITE_H */ diff --git a/src/libs/vg_lite_driver/lv_vg_lite_hal/lv_vg_lite_hal.c b/src/libs/vg_lite_driver/lv_vg_lite_hal/lv_vg_lite_hal.c new file mode 100644 index 0000000000..c9e81cdc5f --- /dev/null +++ b/src/libs/vg_lite_driver/lv_vg_lite_hal/lv_vg_lite_hal.c @@ -0,0 +1,606 @@ + +#include "../../../lv_conf_internal.h" +#if LV_USE_VG_LITE_DRIVER + +#include "../../../osal/lv_os_private.h" +#include "../../../stdlib/lv_mem.h" + +#if LV_USE_OS == LV_OS_NONE + #error "VGLite hal needs support from an OS, please select one of the supported by LVGL!" +#endif + +#include "vg_lite_platform.h" +#include "../VGLiteKernel/vg_lite_kernel.h" +#include "../VGLiteKernel/vg_lite_hal.h" +#include "../VGLiteKernel/vg_lite_hw.h" + +#include + +static void sleep(uint32_t msec) +{ + lv_sleep_ms(msec); +} + +static uint32_t registerMemBase = LV_VG_LITE_HAL_GPU_BASE_ADDRESS; + +/* If bit31 is activated this indicates a bus error */ +#define IS_AXI_BUS_ERR(x) ((x)&(1U << 31)) +#define HEAP_NODE_USED 0xABBAF00D + +volatile void * contiguousMem[VG_SYSTEM_RESERVE_COUNT] = { + [0 ... VG_SYSTEM_RESERVE_COUNT - 1] = NULL +}; + +uint32_t gpuMemBase[VG_SYSTEM_RESERVE_COUNT] = { + [0 ... VG_SYSTEM_RESERVE_COUNT - 1] = 0 +}; + +/* Default heap size is 16MB. */ +static uint32_t heap_size[VG_SYSTEM_RESERVE_COUNT] = { + [0 ... VG_SYSTEM_RESERVE_COUNT - 1] = MAX_CONTIGUOUS_SIZE +}; + +void __attribute__((weak)) vg_lite_bus_error_handler(); + +void vg_lite_init_mem(vg_module_parameters_t * param) +{ + uint32_t i; + + registerMemBase = param->register_mem_base; + + for(i = 0; i < VG_SYSTEM_RESERVE_COUNT; i++) { + gpuMemBase[i] = param->gpu_mem_base[i]; + contiguousMem[i] = param->contiguous_mem_base[i]; + heap_size[i] = param->contiguous_mem_size[i]; + } +} + +/* Implementation of list. ****************************************/ +#define INIT_LIST_HEAD(entry) \ + (entry)->next = (entry);\ + (entry)->prev = (entry); + +/* Add the list item in front of "head". */ +static inline void add_list(list_head_t * to_add, list_head_t * head) +{ + /* Link the new item. */ + to_add->next = head; + to_add->prev = head->prev; + + /* Modify the neighbor. */ + head->prev = to_add; + if(to_add->prev != NULL) { + to_add->prev->next = to_add; + } +} + +/* Remove an entry out of the list. */ +static inline void delete_list(list_head_t * entry) +{ + if(entry->prev != NULL) { + entry->prev->next = entry->next; + } + if(entry->next != NULL) { + entry->next->prev = entry->prev; + } +} + +/* End of list implementation. ***********/ +static inline void _memset(void * mem, unsigned char value, int size) +{ + int i; + for(i = 0; i < size; i++) { + ((unsigned char *)mem)[i] = value; + } +} + +struct memory_heap { + uint32_t free; + list_head_t list; +}; + +struct mapped_memory { + void * logical; + uint32_t physical; + int page_count; + struct page ** pages; +}; + +struct vg_lite_device { + /* void * gpu; */ + uint32_t register_base; /* Always use physical for register access in RTOS. */ + /* struct page * pages; */ + volatile void * contiguous[VG_SYSTEM_RESERVE_COUNT]; + unsigned int order; + unsigned int heap_size[VG_SYSTEM_RESERVE_COUNT]; + void * virtual[VG_SYSTEM_RESERVE_COUNT]; + uint32_t physical[VG_SYSTEM_RESERVE_COUNT]; + uint32_t size[VG_SYSTEM_RESERVE_COUNT]; + struct memory_heap heap[VG_SYSTEM_RESERVE_COUNT]; + int irq_enabled; + volatile uint32_t int_flags; + /* wait_queue_head_t int_queue; */ + lv_thread_sync_t int_queue; + void * device; + int registered; + int major; + struct class * class; + int created; + vg_lite_gpu_execute_state_t gpu_execute_state; +}; + +struct client_data { + struct vg_lite_device * device; + struct vm_area_struct * vm; + void * contiguous_mapped; +}; + +static struct vg_lite_device * device; + +void vg_lite_set_gpu_execute_state(vg_lite_gpu_execute_state_t state) +{ + device->gpu_execute_state = state; +} + +vg_lite_error_t vg_lite_hal_allocate(unsigned long size, void ** memory) +{ + vg_lite_error_t error = VG_LITE_SUCCESS; + + /* TODO: Allocate some memory. No more kernel mode in RTOS. */ + *memory = lv_malloc(size); + if(NULL == *memory) + error = VG_LITE_OUT_OF_MEMORY; + + return error; +} + +vg_lite_error_t vg_lite_hal_free(void * memory) +{ + vg_lite_error_t error = VG_LITE_SUCCESS; + + lv_free(memory); + + return error; +} + +void vg_lite_hal_delay(uint32_t ms) +{ + sleep(ms); +} + +void vg_lite_hal_barrier(void) +{ + __asm("DSB"); +} + +static int vg_lite_init(void); +void vg_lite_hal_initialize(void) +{ + vg_lite_init(); +} + +void vg_lite_hal_deinitialize(void) +{ + lv_thread_sync_delete(&device->int_queue); +} + +static int split_node(heap_node_t * node, unsigned long size) +{ + heap_node_t * split; + + /* Allocate a new node. */ + vg_lite_hal_allocate(sizeof(heap_node_t), (void **)&split); + if(split == NULL) + return -1; + + /* Fill in the data of this node of the remaning size. */ + split->offset = node->offset + size; + split->size = node->size - size; + split->status = 0; + + /* Add the new node behind the current node. */ + add_list(&split->list, &node->list); + + /* Adjust the size of the current node. */ + node->size = size; + return 0; +} + +void vg_lite_hal_print(char * format, ...) +{ + static char buffer[128]; + va_list args; + va_start(args, format); + + vsnprintf(buffer, sizeof(buffer) - 1, format, args); + buffer[sizeof(buffer) - 1] = 0; + printf(buffer); + + va_end(args); +} + +void vg_lite_hal_trace(char * format, ...) +{ + static char buffer[128]; + va_list args; + va_start(args, format); + + vsnprintf(buffer, sizeof(buffer) - 1, format, args); + buffer[sizeof(buffer) - 1] = 0; + printf(buffer); + + va_end(args); +} + +const char * vg_lite_hal_Status2Name(vg_lite_error_t status) +{ + switch(status) { + case VG_LITE_SUCCESS: + return "VG_LITE_SUCCESS"; + case VG_LITE_INVALID_ARGUMENT: + return "VG_LITE_INVALID_ARGUMENT"; + case VG_LITE_OUT_OF_MEMORY: + return "VG_LITE_OUT_OF_MEMORY"; + case VG_LITE_NO_CONTEXT: + return "VG_LITE_NO_CONTEXT"; + case VG_LITE_TIMEOUT: + return "VG_LITE_TIMEOUT"; + case VG_LITE_OUT_OF_RESOURCES: + return "VG_LITE_OUT_OF_RESOURCES"; + case VG_LITE_GENERIC_IO: + return "VG_LITE_GENERIC_IO"; + case VG_LITE_NOT_SUPPORT: + return "VG_LITE_NOT_SUPPORT"; + case VG_LITE_ALREADY_EXISTS: + return "VG_LITE_ALREADY_EXISTS"; + case VG_LITE_NOT_ALIGNED: + return "VG_LITE_NOT_ALIGNED"; + case VG_LITE_FLEXA_TIME_OUT: + return "VG_LITE_FLEXA_TIME_OUT"; + case VG_LITE_FLEXA_HANDSHAKE_FAIL: + return "VG_LITE_FLEXA_HANDSHAKE_FAIL"; + case VG_LITE_SYSTEM_CALL_FAIL: + return "VG_LITE_SYSTEM_CALL_FAIL"; + default: + return "nil"; + } +} + +vg_lite_error_t vg_lite_hal_allocate_contiguous(unsigned long size, vg_lite_vidmem_pool_t pool, void ** logical, + void ** klogical, uint32_t * physical, void ** node) +{ + unsigned long aligned_size; + heap_node_t * pos; + + /* Judge if it exceeds the range of pool */ + if(pool >= VG_SYSTEM_RESERVE_COUNT) + pool = VG_SYSTEM_RESERVE_COUNT - 1; + + /* Align the size to 64 bytes. */ + aligned_size = (size + 63) & ~63; + + /* Check if there is enough free memory available. */ + if(aligned_size > device->heap[pool].free) { + return VG_LITE_OUT_OF_MEMORY; + } + + /* Walk the heap backwards. */ + for(pos = (heap_node_t *)device->heap[pool].list.prev; + &pos->list != &device->heap[pool].list; + pos = (heap_node_t *) pos->list.prev) { + /* Check if the current node is free and is big enough. */ + if(pos->status == 0 && pos->size >= aligned_size) { + /* See if we the current node is big enough to split. */ + if(0 != split_node(pos, aligned_size)) { + return VG_LITE_OUT_OF_RESOURCES; + } + /* Mark the current node as used. */ + pos->status = 0xABBAF00D; + + /* Return the logical/physical address. */ + /* *logical = (uint8_t *) private_data->contiguous_mapped + pos->offset; */ + *logical = (uint8_t *)device->virtual[pool] + pos->offset; + *klogical = *logical; + *physical = gpuMemBase[pool] + (uint32_t)(*logical);/* device->physical + pos->offset; */ + + /* Mark which pool the pos belong to */ + pos->pool = pool; + + device->heap[pool].free -= aligned_size; + + *node = pos; + return VG_LITE_SUCCESS; + } + } + + /* Out of memory. */ + return VG_LITE_OUT_OF_MEMORY; +} + +void vg_lite_hal_free_contiguous(void * memory_handle) +{ + /* TODO: no list available in RTOS. */ + heap_node_t * pos, * node; + vg_lite_vidmem_pool_t pool; + + /* Get pointer to node. */ + node = memory_handle; + + if(node->status != 0xABBAF00D) { + return; + } + + /* Determine which pool the node belongs to */ + pool = node->pool; + + /* Mark node as free. */ + node->status = 0; + + /* Add node size to free count. */ + device->heap[pool].free += node->size; + + /* Check if next node is free. */ + pos = node; + for(pos = (heap_node_t *)pos->list.next; + &pos->list != &device->heap[pool].list; + pos = (heap_node_t *)pos->list.next) { + if(pos->status == 0) { + /* Merge the nodes. */ + node->size += pos->size; + if(node->offset > pos->offset) + node->offset = pos->offset; + /* Delete the next node from the list. */ + delete_list(&pos->list); + vg_lite_hal_free(pos); + } + break; + } + + /* Check if the previous node is free. */ + pos = node; + for(pos = (heap_node_t *)pos->list.prev; + &pos->list != &device->heap[pool].list; + pos = (heap_node_t *)pos->list.prev) { + if(pos->status == 0) { + /* Merge the nodes. */ + pos->size += node->size; + if(pos->offset > node->offset) + pos->offset = node->offset; + /* Delete the current node from the list. */ + delete_list(&node->list); + vg_lite_hal_free(node); + } + break; + } + + /* when release command buffer node and ts buffer node to exit,release the linked list*/ + /* if(device->heap[pool].list.next == device->heap[pool].list.prev) { + delete_list(&pos->list); + vg_lite_hal_free(pos); + }*/ +} + +void vg_lite_hal_free_os_heap(void) +{ + struct heap_node * pos, * n; + uint32_t i; + + /* Check for valid device. */ + if(device != NULL) { + /* Process each node. */ + for(i = 0; i < VG_SYSTEM_RESERVE_COUNT; i++) { + for(pos = (heap_node_t *)device->heap[i].list.next, + n = (heap_node_t *)pos->list.next; + &pos->list != &device->heap[i].list; + pos = n, n = (heap_node_t *)n->list.next) { + /* Remove it from the linked list. */ + delete_list(&pos->list); + /* Free up the memory. */ + vg_lite_hal_free(pos); + } + } + } +} + +/* Portable: read register value. */ +uint32_t vg_lite_hal_peek(uint32_t address) +{ + /* Read data from the GPU register. */ + return (uint32_t)(*(volatile uint32_t *)(device->register_base + address)); +} + +/* Portable: write register. */ +void vg_lite_hal_poke(uint32_t address, uint32_t data) +{ + /* Write data to the GPU register. */ + uint32_t * LocalAddr = (uint32_t *)(device->register_base + address); + *LocalAddr = data; +} + +vg_lite_error_t vg_lite_hal_query_mem(vg_lite_kernel_mem_t * mem) +{ + if(device != NULL) { + mem->bytes = device->heap[mem->pool].free; + return VG_LITE_SUCCESS; + } + mem->bytes = 0; + return VG_LITE_NO_CONTEXT; +} + +vg_lite_error_t vg_lite_hal_map_memory(vg_lite_kernel_map_memory_t * node) +{ + node->logical = (void *)node->physical; + return VG_LITE_SUCCESS; +} + +vg_lite_error_t vg_lite_hal_unmap_memory(vg_lite_kernel_unmap_memory_t * node) +{ + return VG_LITE_SUCCESS; +} + +void __attribute__((weak)) vg_lite_bus_error_handler() +{ + /* + * Default implementation of the bus error handler does nothing. Application + * should override this handler if it requires to be notified when a bus + * error event occurs. + */ + return; +} + +void vg_lite_IRQHandler(void) +{ + uint32_t flags = vg_lite_hal_peek(VG_LITE_INTR_STATUS); + + if(flags) { + /* Combine with current interrupt flags. */ + device->int_flags |= flags; + + /* Wake up any waiters. */ + lv_thread_sync_signal_isr(&device->int_queue); + +#if gcdVG_RECORD_HARDWARE_RUNNING_TIME + record_running_time(); +#endif + } +} + +int32_t vg_lite_hal_wait_interrupt(uint32_t timeout, uint32_t mask, uint32_t * value) +{ + if(lv_thread_sync_wait(&device->int_queue) == LV_RESULT_OK) { + if(value != NULL) { + *value = device->int_flags & mask; + } + device->int_flags = 0; + + if(IS_AXI_BUS_ERR(*value)) { + vg_lite_bus_error_handler(); + } + + return 1; + } + + return 0; +} + +vg_lite_error_t vg_lite_hal_memory_export(int32_t * fd) +{ + return VG_LITE_SUCCESS; +} + + +void * vg_lite_hal_map(uint32_t flags, uint32_t bytes, void * logical, uint32_t physical, int32_t dma_buf_fd, + uint32_t * gpu) +{ + (void) flags; + (void) bytes; + (void) logical; + (void) physical; + (void) dma_buf_fd; + (void) gpu; + return (void *)0; +} + +void vg_lite_hal_unmap(void * handle) +{ + + (void) handle; +} + +vg_lite_error_t vg_lite_hal_operation_cache(void * handle, vg_lite_cache_op_t cache_op) +{ + (void) handle; + (void) cache_op; + + return VG_LITE_SUCCESS; +} + +static void vg_lite_exit(void) +{ + heap_node_t * pos; + heap_node_t * n; + uint32_t i; + + /* Check for valid device. */ + if(device != NULL) { + /* TODO: unmap register mem should be unnecessary. */ + device->register_base = 0; + + for(i = 0; i < VG_SYSTEM_RESERVE_COUNT; i++) { + /* Process each node. */ + for(pos = (heap_node_t *)device->heap[i].list.next, n = (heap_node_t *)pos->list.next; + &pos->list != &device->heap[i].list; + pos = n, n = (heap_node_t *)n->list.next) { + /* Remove it from the linked list. */ + delete_list(&pos->list); + + /* Free up the memory. */ + vg_lite_hal_free(pos); + } + } + + /* Free up the device structure. */ + vg_lite_hal_free(device); + } +} + +static int vg_lite_init(void) +{ + heap_node_t * node; + uint32_t i; + + vg_lite_hal_allocate(sizeof(struct vg_lite_device), (void **)&device); + if(NULL == device) + return -1; + + /* Zero out the enture structure. */ + _memset(device, 0, sizeof(struct vg_lite_device)); + + /* Setup register memory. **********************************************/ + device->register_base = registerMemBase; + + + /* Initialize contiguous memory. ***************************************/ + /* Allocate the contiguous memory. */ + for(i = 0; i < VG_SYSTEM_RESERVE_COUNT; i++) { + device->heap_size[i] = heap_size[i]; + device->contiguous[i] = (volatile void *)contiguousMem[i]; + /* Make 64byte aligned. */ + while((((uint32_t)device->contiguous[i]) & 63) != 0) { + device->contiguous[i] = ((unsigned char *)device->contiguous[i]) + 4; + device->heap_size[i] -= 4; + } + + /* Check if we allocated any contiguous memory or not. */ + if(device->contiguous[i] == NULL) { + vg_lite_exit(); + return -1; + } + + device->virtual[i] = (void *)device->contiguous[i]; + device->physical[i] = gpuMemBase[i] + (uint32_t)device->virtual[i]; + device->size[i] = device->heap_size[i]; + + /* Create the heap. */ + INIT_LIST_HEAD(&device->heap[i].list); + device->heap[i].free = device->size[i]; + + vg_lite_hal_allocate(sizeof(heap_node_t), (void **)&node); + if(node == NULL) { + vg_lite_exit(); + return -1; + } + node->offset = 0; + node->size = device->size[i]; + node->status = 0; + add_list(&node->list, &device->heap[i].list); + } + + lv_thread_sync_init(&device->int_queue); + device->int_flags = 0; + + /* Success. */ + return 0; +} + +#endif /* LV_USE_VG_LITE_DRIVER */ diff --git a/src/libs/vg_lite_driver/lv_vg_lite_hal/vg_lite_os.c b/src/libs/vg_lite_driver/lv_vg_lite_hal/vg_lite_os.c new file mode 100755 index 0000000000..d7950a6bd3 --- /dev/null +++ b/src/libs/vg_lite_driver/lv_vg_lite_hal/vg_lite_os.c @@ -0,0 +1,16 @@ +#include "../../../lv_conf_internal.h" +#if LV_USE_VG_LITE_DRIVER + +#include "../../../lvgl.h" + +void * vg_lite_os_malloc(uint32_t size) +{ + return lv_malloc(size); +} + +void vg_lite_os_free(void * memory) +{ + lv_free(memory); +} + +#endif diff --git a/src/libs/vg_lite_driver/lv_vg_lite_hal/vg_lite_platform.h b/src/libs/vg_lite_driver/lv_vg_lite_hal/vg_lite_platform.h new file mode 100644 index 0000000000..41f05312e0 --- /dev/null +++ b/src/libs/vg_lite_driver/lv_vg_lite_hal/vg_lite_platform.h @@ -0,0 +1,52 @@ +#ifndef VG_LITE_PLATFORM_H +#define VG_LITE_PLATFORM_H + +#include "../../../lv_conf_internal.h" +#if LV_USE_VG_LITE_DRIVER + +#include "stdint.h" +#include "stdlib.h" +#include +#include "../VGLiteKernel/vg_lite_debug.h" +#include "../VGLiteKernel/vg_lite_type.h" +#include "../VGLiteKernel/vg_lite_option.h" + +#define VG_SYSTEM_RESERVE_COUNT 2 + +/* Implementation of list. ****************************************/ +typedef struct list_head { + struct list_head * next; + struct list_head * prev; +} list_head_t; + +typedef struct heap_node { + list_head_t list; + uint32_t offset; + unsigned long size; + int32_t status; + vg_lite_vidmem_pool_t pool; +} heap_node_t; + +typedef struct vg_module_parameters { + + uint32_t register_mem_base; + uint32_t gpu_mem_base[VG_SYSTEM_RESERVE_COUNT]; + + volatile void * contiguous_mem_base[VG_SYSTEM_RESERVE_COUNT]; + uint32_t contiguous_mem_size[VG_SYSTEM_RESERVE_COUNT]; +} +vg_module_parameters_t; + +/*! +@brief Initialize the hardware mem setting. +*/ +void vg_lite_init_mem(vg_module_parameters_t * param); + +/*! +@brief The hardware IRQ handler. +*/ +void vg_lite_IRQHandler(void); + +#endif /* LV_USE_VG_LITE_DRIVER */ + +#endif /* VG_LITE_PLATFORM_H */ \ No newline at end of file diff --git a/src/lv_api_map_v9_2.h b/src/lv_api_map_v9_2.h new file mode 100644 index 0000000000..1339452361 --- /dev/null +++ b/src/lv_api_map_v9_2.h @@ -0,0 +1,57 @@ +/** + * @file lv_api_map_v9_2.h + * + */ + +#ifndef LV_API_MAP_V9_2_H +#define LV_API_MAP_V9_2_H + +#ifdef __cplusplus +extern "C" { +#endif + +/********************* + * INCLUDES + *********************/ +#include "misc/lv_types.h" + +/********************* + * DEFINES + *********************/ + +/********************** + * TYPEDEFS + **********************/ + +/********************** + * GLOBAL PROTOTYPES + **********************/ + +/********************** + * MACROS + **********************/ + +#define LV_SCR_LOAD_ANIM_NONE LV_SCREEN_LOAD_ANIM_NONE +#define LV_SCR_LOAD_ANIM_OVER_LEFT LV_SCREEN_LOAD_ANIM_OVER_LEFT +#define LV_SCR_LOAD_ANIM_OVER_RIGHT LV_SCREEN_LOAD_ANIM_OVER_RIGHT +#define LV_SCR_LOAD_ANIM_OVER_TOP LV_SCREEN_LOAD_ANIM_OVER_TOP +#define LV_SCR_LOAD_ANIM_OVER_BOTTOM LV_SCREEN_LOAD_ANIM_OVER_BOTTOM +#define LV_SCR_LOAD_ANIM_MOVE_LEFT LV_SCREEN_LOAD_ANIM_MOVE_LEFT +#define LV_SCR_LOAD_ANIM_MOVE_RIGHT LV_SCREEN_LOAD_ANIM_MOVE_RIGHT +#define LV_SCR_LOAD_ANIM_MOVE_TOP LV_SCREEN_LOAD_ANIM_MOVE_TOP +#define LV_SCR_LOAD_ANIM_MOVE_BOTTOM LV_SCREEN_LOAD_ANIM_MOVE_BOTTOM +#define LV_SCR_LOAD_ANIM_FADE_IN LV_SCREEN_LOAD_ANIM_FADE_IN +#define LV_SCR_LOAD_ANIM_FADE_ON LV_SCREEN_LOAD_ANIM_FADE_ON +#define LV_SCR_LOAD_ANIM_FADE_OUT LV_SCREEN_LOAD_ANIM_FADE_OUT +#define LV_SCR_LOAD_ANIM_OUT_LEFT LV_SCREEN_LOAD_ANIM_OUT_LEFT +#define LV_SCR_LOAD_ANIM_OUT_RIGHT LV_SCREEN_LOAD_ANIM_OUT_RIGHT +#define LV_SCR_LOAD_ANIM_OUT_TOP LV_SCREEN_LOAD_ANIM_OUT_TOP +#define LV_SCR_LOAD_ANIM_OUT_BOTTOM LV_SCREEN_LOAD_ANIM_OUT_BOTTOM + +#define lv_ft81x_spi_operation lv_ft81x_spi_operation_t + +#ifdef __cplusplus +} /*extern "C"*/ +#endif + +#endif /* LV_API_MAP_V9_2_H */ diff --git a/src/lv_api_map_v9_3.h b/src/lv_api_map_v9_3.h new file mode 100644 index 0000000000..d6ec98d6c8 --- /dev/null +++ b/src/lv_api_map_v9_3.h @@ -0,0 +1,97 @@ +/** + * @file lv_api_map_v9_3.h + * + */ + +#ifndef LV_API_MAP_V9_3_H +#define LV_API_MAP_V9_3_H + +#ifdef __cplusplus +extern "C" { +#endif + +/********************* + * INCLUDES + *********************/ +#include "misc/lv_types.h" + +/********************* + * DEFINES + *********************/ + +/********************** + * TYPEDEFS + **********************/ + +/********************** + * GLOBAL PROTOTYPES + **********************/ + +/********************** + * MACROS + **********************/ + +#define lv_draw_buf_malloc_cb lv_draw_buf_malloc_cb_t +#define lv_draw_buf_free_cb lv_draw_buf_free_cb_t +#define lv_draw_buf_copy_cb lv_draw_buf_copy_cb_t +#define lv_draw_buf_align_cb lv_draw_buf_align_cb_t +#define lv_draw_buf_cache_operation_cb lv_draw_buf_cache_operation_cb_t +#define lv_draw_buf_width_to_stride_cb lv_draw_buf_width_to_stride_cb_t + +#define lv_glfw_window_t lv_opengles_window_t +#define lv_glfw_texture_t lv_opengles_window_texture_t +#define lv_glfw_window_create lv_opengles_glfw_window_create +#define lv_glfw_window_create_ex lv_opengles_glfw_window_create_ex +#define lv_glfw_window_set_title lv_opengles_glfw_window_set_title +#define lv_glfw_window_delete lv_opengles_window_delete +#define lv_glfw_window_set_flip lv_opengles_glfw_window_set_flip +#define lv_glfw_window_add_texture lv_opengles_window_add_texture +#define lv_glfw_texture_remove lv_opengles_window_texture_remove +#define lv_glfw_texture_set_x lv_opengles_window_texture_set_x +#define lv_glfw_texture_set_y lv_opengles_window_texture_set_y +#define lv_glfw_texture_set_opa lv_opengles_window_texture_set_opa +#define lv_glfw_texture_get_mouse_indev lv_opengles_window_texture_get_mouse_indev +#define lv_glfw_window_get_glfw_window lv_opengles_glfw_window_get_glfw_window + +#define lv_vector_dsc_create lv_draw_vector_dsc_create +#define lv_vector_dsc_delete lv_draw_vector_dsc_delete +#define lv_vector_dsc_set_transform lv_draw_vector_dsc_set_transform +#define lv_vector_dsc_set_blend_mode lv_draw_vector_dsc_set_blend_mode +#define lv_vector_dsc_set_fill_color32 lv_draw_vector_dsc_set_fill_color32 +#define lv_vector_dsc_set_fill_color lv_draw_vector_dsc_set_fill_color +#define lv_vector_dsc_set_fill_opa lv_draw_vector_dsc_set_fill_opa +#define lv_vector_dsc_set_fill_rule lv_draw_vector_dsc_set_fill_rule +#define lv_vector_dsc_set_fill_units lv_draw_vector_dsc_set_fill_units +#define lv_vector_dsc_set_fill_image lv_draw_vector_dsc_set_fill_image +#define lv_vector_dsc_set_fill_linear_gradient lv_draw_vector_dsc_set_fill_linear_gradient +#define lv_vector_dsc_set_fill_radial_gradient lv_draw_vector_dsc_set_fill_radial_gradient +#define lv_vector_dsc_set_fill_gradient_spread lv_draw_vector_dsc_set_fill_gradient_spread +#define lv_vector_dsc_set_fill_gradient_color_stops lv_draw_vector_dsc_set_fill_gradient_color_stops +#define lv_vector_dsc_set_fill_transform lv_draw_vector_dsc_set_fill_transform +#define lv_vector_dsc_set_stroke_color32 lv_draw_vector_dsc_set_stroke_color32 +#define lv_vector_dsc_set_stroke_color lv_draw_vector_dsc_set_stroke_color +#define lv_vector_dsc_set_stroke_opa lv_draw_vector_dsc_set_stroke_opa +#define lv_vector_dsc_set_stroke_width lv_draw_vector_dsc_set_stroke_width +#define lv_vector_dsc_set_stroke_dash lv_draw_vector_dsc_set_stroke_dash +#define lv_vector_dsc_set_stroke_cap lv_draw_vector_dsc_set_stroke_cap +#define lv_vector_dsc_set_stroke_join lv_draw_vector_dsc_set_stroke_join +#define lv_vector_dsc_set_stroke_miter_limit lv_draw_vector_dsc_set_stroke_miter_limit +#define lv_vector_dsc_set_stroke_linear_gradient lv_draw_vector_dsc_set_stroke_linear_gradient +#define lv_vector_dsc_set_stroke_radial_gradient lv_draw_vector_dsc_set_stroke_radial_gradient +#define lv_vector_dsc_set_stroke_gradient_spread lv_draw_vector_dsc_set_stroke_gradient_spread +#define lv_vector_dsc_set_stroke_gradient_color_stops lv_draw_vector_dsc_set_stroke_gradient_color_stops +#define lv_vector_dsc_set_stroke_transform lv_draw_vector_dsc_set_stroke_transform +#define lv_vector_dsc_identity lv_draw_vector_dsc_identity +#define lv_vector_dsc_scale lv_draw_vector_dsc_scale +#define lv_vector_dsc_rotate lv_draw_vector_dsc_rotate +#define lv_vector_dsc_translate lv_draw_vector_dsc_translate +#define lv_vector_dsc_skew lv_draw_vector_dsc_skew +#define lv_vector_dsc_add_path lv_draw_vector_dsc_add_path +#define lv_vector_dsc_clear_area lv_draw_vector_dsc_clear_area + + +#ifdef __cplusplus +} /*extern "C"*/ +#endif + +#endif /* LV_API_MAP_V9_3_H */ diff --git a/src/lv_conf_internal.h b/src/lv_conf_internal.h index 0ad8e64e10..3f16fa0d11 100644 --- a/src/lv_conf_internal.h +++ b/src/lv_conf_internal.h @@ -25,10 +25,10 @@ #define LV_STDLIB_RTTHREAD 3 #define LV_STDLIB_CUSTOM 255 -#define LV_DRAW_SW_ASM_NONE 0 -#define LV_DRAW_SW_ASM_NEON 1 -#define LV_DRAW_SW_ASM_HELIUM 2 -#define LV_DRAW_SW_ASM_CUSTOM 255 +#define LV_DRAW_SW_ASM_NONE 0 +#define LV_DRAW_SW_ASM_NEON 1 +#define LV_DRAW_SW_ASM_HELIUM 2 +#define LV_DRAW_SW_ASM_CUSTOM 255 #define LV_NEMA_HAL_CUSTOM 0 #define LV_NEMA_HAL_STM32 1 @@ -701,74 +701,6 @@ #endif #endif -/** Use NXP's VG-Lite GPU on iMX RTxxx platforms. */ -#ifndef LV_USE_DRAW_VGLITE - #ifdef CONFIG_LV_USE_DRAW_VGLITE - #define LV_USE_DRAW_VGLITE CONFIG_LV_USE_DRAW_VGLITE - #else - #define LV_USE_DRAW_VGLITE 0 - #endif -#endif - -#if LV_USE_DRAW_VGLITE - /** Enable blit quality degradation workaround recommended for screen's dimension > 352 pixels. */ - #ifndef LV_USE_VGLITE_BLIT_SPLIT - #ifdef CONFIG_LV_USE_VGLITE_BLIT_SPLIT - #define LV_USE_VGLITE_BLIT_SPLIT CONFIG_LV_USE_VGLITE_BLIT_SPLIT - #else - #define LV_USE_VGLITE_BLIT_SPLIT 0 - #endif - #endif - - #if LV_USE_OS - /** Use additional draw thread for VG-Lite processing. */ - #ifndef LV_USE_VGLITE_DRAW_THREAD - #ifdef LV_KCONFIG_PRESENT - #ifdef CONFIG_LV_USE_VGLITE_DRAW_THREAD - #define LV_USE_VGLITE_DRAW_THREAD CONFIG_LV_USE_VGLITE_DRAW_THREAD - #else - #define LV_USE_VGLITE_DRAW_THREAD 0 - #endif - #else - #define LV_USE_VGLITE_DRAW_THREAD 1 - #endif - #endif - - #if LV_USE_VGLITE_DRAW_THREAD - /** Enable VGLite draw async. Queue multiple tasks and flash them once to the GPU. */ - #ifndef LV_USE_VGLITE_DRAW_ASYNC - #ifdef LV_KCONFIG_PRESENT - #ifdef CONFIG_LV_USE_VGLITE_DRAW_ASYNC - #define LV_USE_VGLITE_DRAW_ASYNC CONFIG_LV_USE_VGLITE_DRAW_ASYNC - #else - #define LV_USE_VGLITE_DRAW_ASYNC 0 - #endif - #else - #define LV_USE_VGLITE_DRAW_ASYNC 1 - #endif - #endif - #endif - #endif - - /** Enable VGLite asserts. */ - #ifndef LV_USE_VGLITE_ASSERT - #ifdef CONFIG_LV_USE_VGLITE_ASSERT - #define LV_USE_VGLITE_ASSERT CONFIG_LV_USE_VGLITE_ASSERT - #else - #define LV_USE_VGLITE_ASSERT 0 - #endif - #endif - - /** Enable VGLite error checks. */ - #ifndef LV_USE_VGLITE_CHECK_ERROR - #ifdef CONFIG_LV_USE_VGLITE_CHECK_ERROR - #define LV_USE_VGLITE_CHECK_ERROR CONFIG_LV_USE_VGLITE_CHECK_ERROR - #else - #define LV_USE_VGLITE_CHECK_ERROR 0 - #endif - #endif -#endif - /** Use NXP's PXP on iMX RTxxx platforms. */ #ifndef LV_USE_PXP #ifdef CONFIG_LV_USE_PXP @@ -827,15 +759,37 @@ #endif /** Use NXP's G2D on MPU platforms. */ -#ifndef LV_USE_DRAW_G2D - #ifdef CONFIG_LV_USE_DRAW_G2D - #define LV_USE_DRAW_G2D CONFIG_LV_USE_DRAW_G2D +#ifndef LV_USE_G2D + #ifdef CONFIG_LV_USE_G2D + #define LV_USE_G2D CONFIG_LV_USE_G2D #else - #define LV_USE_DRAW_G2D 0 + #define LV_USE_G2D 0 #endif #endif -#if LV_USE_DRAW_G2D +#if LV_USE_G2D + /** Use G2D for drawing. **/ + #ifndef LV_USE_DRAW_G2D + #ifdef LV_KCONFIG_PRESENT + #ifdef CONFIG_LV_USE_DRAW_G2D + #define LV_USE_DRAW_G2D CONFIG_LV_USE_DRAW_G2D + #else + #define LV_USE_DRAW_G2D 0 + #endif + #else + #define LV_USE_DRAW_G2D 1 + #endif + #endif + + /** Use G2D to rotate display. **/ + #ifndef LV_USE_ROTATE_G2D + #ifdef CONFIG_LV_USE_ROTATE_G2D + #define LV_USE_ROTATE_G2D CONFIG_LV_USE_ROTATE_G2D + #else + #define LV_USE_ROTATE_G2D 0 + #endif + #endif + /** Maximum number of buffers that can be stored for G2D draw unit. * Includes the frame buffers and assets. */ #ifndef LV_G2D_HASH_TABLE_SIZE @@ -846,7 +800,7 @@ #endif #endif - #if LV_USE_OS + #if LV_USE_DRAW_G2D && LV_USE_OS /** Use additional draw thread for G2D processing.*/ #ifndef LV_USE_G2D_DRAW_THREAD #ifdef LV_KCONFIG_PRESENT @@ -897,7 +851,6 @@ #define LV_USE_DRAW_VG_LITE 0 #endif #endif - #if LV_USE_DRAW_VG_LITE /** Enable VG-Lite custom external 'gpu_init()' function */ #ifndef LV_VG_LITE_USE_GPU_INIT @@ -959,6 +912,131 @@ #define LV_VG_LITE_STROKE_CACHE_CNT 32 #endif #endif + + /** Remove VLC_OP_CLOSE path instruction (Workaround for NXP) **/ + #ifndef LV_VG_LITE_DISABLE_VLC_OP_CLOSE + #ifdef CONFIG_LV_VG_LITE_DISABLE_VLC_OP_CLOSE + #define LV_VG_LITE_DISABLE_VLC_OP_CLOSE CONFIG_LV_VG_LITE_DISABLE_VLC_OP_CLOSE + #else + #define LV_VG_LITE_DISABLE_VLC_OP_CLOSE 0 + #endif + #endif + + /** Disable linear gradient extension for some older versions of drivers. */ + #ifndef LV_VG_LITE_DISABLE_LINEAR_GRADIENT_EXT + #ifdef CONFIG_LV_VG_LITE_DISABLE_LINEAR_GRADIENT_EXT + #define LV_VG_LITE_DISABLE_LINEAR_GRADIENT_EXT CONFIG_LV_VG_LITE_DISABLE_LINEAR_GRADIENT_EXT + #else + #define LV_VG_LITE_DISABLE_LINEAR_GRADIENT_EXT 0 + #endif + #endif + + /** Enable usage of the LVGL's built-in vg_lite driver */ + #ifndef LV_USE_VG_LITE_DRIVER + #ifdef CONFIG_LV_USE_VG_LITE_DRIVER + #define LV_USE_VG_LITE_DRIVER CONFIG_LV_USE_VG_LITE_DRIVER + #else + #define LV_USE_VG_LITE_DRIVER 0 + #endif + #endif + #if LV_USE_VG_LITE_DRIVER + /** Used to pick the correct GPU series folder valid options are gc255, gc355 and gc555*/ + #ifndef LV_VG_LITE_HAL_GPU_SERIES + #ifdef CONFIG_LV_VG_LITE_HAL_GPU_SERIES + #define LV_VG_LITE_HAL_GPU_SERIES CONFIG_LV_VG_LITE_HAL_GPU_SERIES + #else + #define LV_VG_LITE_HAL_GPU_SERIES gc255 + #endif + #endif + + /** Used to pick the correct GPU revision header it depends on the vendor */ + #ifndef LV_VG_LITE_HAL_GPU_REVISION + #ifdef CONFIG_LV_VG_LITE_HAL_GPU_REVISION + #define LV_VG_LITE_HAL_GPU_REVISION CONFIG_LV_VG_LITE_HAL_GPU_REVISION + #else + #define LV_VG_LITE_HAL_GPU_REVISION 0x40 + #endif + #endif + + /** Base memory address of the GPU IP it depends on SoC, + * default value is for NXP based devices */ + #ifndef LV_VG_LITE_HAL_GPU_BASE_ADDRESS + #ifdef CONFIG_LV_VG_LITE_HAL_GPU_BASE_ADDRESS + #define LV_VG_LITE_HAL_GPU_BASE_ADDRESS CONFIG_LV_VG_LITE_HAL_GPU_BASE_ADDRESS + #else + #define LV_VG_LITE_HAL_GPU_BASE_ADDRESS 0x40240000 + #endif + #endif + #endif /*LV_USE_VG_LITE_DRIVER*/ + + /** Use ThorVG (a software vector library) as VG-Lite driver to allow testing VGLite on PC + * Requires: LV_USE_THORVG_INTERNAL or LV_USE_THORVG_EXTERNAL */ + #ifndef LV_USE_VG_LITE_THORVG + #ifdef CONFIG_LV_USE_VG_LITE_THORVG + #define LV_USE_VG_LITE_THORVG CONFIG_LV_USE_VG_LITE_THORVG + #else + #define LV_USE_VG_LITE_THORVG 0 + #endif + #endif + #if LV_USE_VG_LITE_THORVG + /** Enable LVGL's blend mode support */ + #ifndef LV_VG_LITE_THORVG_LVGL_BLEND_SUPPORT + #ifdef CONFIG_LV_VG_LITE_THORVG_LVGL_BLEND_SUPPORT + #define LV_VG_LITE_THORVG_LVGL_BLEND_SUPPORT CONFIG_LV_VG_LITE_THORVG_LVGL_BLEND_SUPPORT + #else + #define LV_VG_LITE_THORVG_LVGL_BLEND_SUPPORT 0 + #endif + #endif + + /** Enable YUV color format support */ + #ifndef LV_VG_LITE_THORVG_YUV_SUPPORT + #ifdef CONFIG_LV_VG_LITE_THORVG_YUV_SUPPORT + #define LV_VG_LITE_THORVG_YUV_SUPPORT CONFIG_LV_VG_LITE_THORVG_YUV_SUPPORT + #else + #define LV_VG_LITE_THORVG_YUV_SUPPORT 0 + #endif + #endif + + /** Enable Linear gradient extension support */ + #ifndef LV_VG_LITE_THORVG_LINEAR_GRADIENT_EXT_SUPPORT + #ifdef CONFIG_LV_VG_LITE_THORVG_LINEAR_GRADIENT_EXT_SUPPORT + #define LV_VG_LITE_THORVG_LINEAR_GRADIENT_EXT_SUPPORT CONFIG_LV_VG_LITE_THORVG_LINEAR_GRADIENT_EXT_SUPPORT + #else + #define LV_VG_LITE_THORVG_LINEAR_GRADIENT_EXT_SUPPORT 0 + #endif + #endif + + /** Enable alignment on 16 pixels */ + #ifndef LV_VG_LITE_THORVG_16PIXELS_ALIGN + #ifdef LV_KCONFIG_PRESENT + #ifdef CONFIG_LV_VG_LITE_THORVG_16PIXELS_ALIGN + #define LV_VG_LITE_THORVG_16PIXELS_ALIGN CONFIG_LV_VG_LITE_THORVG_16PIXELS_ALIGN + #else + #define LV_VG_LITE_THORVG_16PIXELS_ALIGN 0 + #endif + #else + #define LV_VG_LITE_THORVG_16PIXELS_ALIGN 1 + #endif + #endif + + /** Buffer address alignment */ + #ifndef LV_VG_LITE_THORVG_BUF_ADDR_ALIGN + #ifdef CONFIG_LV_VG_LITE_THORVG_BUF_ADDR_ALIGN + #define LV_VG_LITE_THORVG_BUF_ADDR_ALIGN CONFIG_LV_VG_LITE_THORVG_BUF_ADDR_ALIGN + #else + #define LV_VG_LITE_THORVG_BUF_ADDR_ALIGN 64 + #endif + #endif + + /** Enable multi-thread render */ + #ifndef LV_VG_LITE_THORVG_THREAD_RENDER + #ifdef CONFIG_LV_VG_LITE_THORVG_THREAD_RENDER + #define LV_VG_LITE_THORVG_THREAD_RENDER CONFIG_LV_VG_LITE_THORVG_THREAD_RENDER + #else + #define LV_VG_LITE_THORVG_THREAD_RENDER 0 + #endif + #endif + #endif /*LV_USE_VG_LITE_THORVG*/ #endif /** Accelerate blends, fills, etc. with STM32 DMA2D */ @@ -969,7 +1047,6 @@ #define LV_USE_DRAW_DMA2D 0 #endif #endif - #if LV_USE_DRAW_DMA2D #ifndef LV_DRAW_DMA2D_HAL_INCLUDE #ifdef CONFIG_LV_DRAW_DMA2D_HAL_INCLUDE @@ -991,7 +1068,7 @@ #endif #endif -/** Draw using cached OpenGLES textures */ +/** Draw using cached OpenGLES textures. Requires LV_USE_OPENGLES */ #ifndef LV_USE_DRAW_OPENGLES #ifdef CONFIG_LV_USE_DRAW_OPENGLES #define LV_USE_DRAW_OPENGLES CONFIG_LV_USE_DRAW_OPENGLES @@ -999,6 +1076,63 @@ #define LV_USE_DRAW_OPENGLES 0 #endif #endif +#if LV_USE_DRAW_OPENGLES + #ifndef LV_DRAW_OPENGLES_TEXTURE_CACHE_COUNT + #ifdef CONFIG_LV_DRAW_OPENGLES_TEXTURE_CACHE_COUNT + #define LV_DRAW_OPENGLES_TEXTURE_CACHE_COUNT CONFIG_LV_DRAW_OPENGLES_TEXTURE_CACHE_COUNT + #else + #define LV_DRAW_OPENGLES_TEXTURE_CACHE_COUNT 64 + #endif + #endif +#endif + +/** Draw using espressif PPA accelerator */ +#ifndef LV_USE_PPA + #ifdef CONFIG_LV_USE_PPA + #define LV_USE_PPA CONFIG_LV_USE_PPA + #else + #define LV_USE_PPA 0 + #endif +#endif +#if LV_USE_PPA + #ifndef LV_USE_PPA_IMG + #ifdef CONFIG_LV_USE_PPA_IMG + #define LV_USE_PPA_IMG CONFIG_LV_USE_PPA_IMG + #else + #define LV_USE_PPA_IMG 0 + #endif + #endif +#endif + +/* Use EVE FT81X GPU. */ +#ifndef LV_USE_DRAW_EVE + #ifdef CONFIG_LV_USE_DRAW_EVE + #define LV_USE_DRAW_EVE CONFIG_LV_USE_DRAW_EVE + #else + #define LV_USE_DRAW_EVE 0 + #endif +#endif +#if LV_USE_DRAW_EVE + /* EVE_GEN value: 2, 3, or 4 */ + #ifndef LV_DRAW_EVE_EVE_GENERATION + #ifdef CONFIG_LV_DRAW_EVE_EVE_GENERATION + #define LV_DRAW_EVE_EVE_GENERATION CONFIG_LV_DRAW_EVE_EVE_GENERATION + #else + #define LV_DRAW_EVE_EVE_GENERATION 4 + #endif + #endif + + /* The maximum number of bytes to buffer before a single SPI transmission. + * Set it to 0 to disable write buffering. + */ + #ifndef LV_DRAW_EVE_WRITE_BUFFER_SIZE + #ifdef CONFIG_LV_DRAW_EVE_WRITE_BUFFER_SIZE + #define LV_DRAW_EVE_WRITE_BUFFER_SIZE CONFIG_LV_DRAW_EVE_WRITE_BUFFER_SIZE + #else + #define LV_DRAW_EVE_WRITE_BUFFER_SIZE 2048 + #endif + #endif +#endif /*======================= * FEATURE CONFIGURATION @@ -1422,76 +1556,6 @@ #endif #endif -/* Use VG-Lite Simulator. - * - Requires: LV_USE_THORVG_INTERNAL or LV_USE_THORVG_EXTERNAL */ -#ifndef LV_USE_VG_LITE_THORVG - #ifdef CONFIG_LV_USE_VG_LITE_THORVG - #define LV_USE_VG_LITE_THORVG CONFIG_LV_USE_VG_LITE_THORVG - #else - #define LV_USE_VG_LITE_THORVG 0 - #endif -#endif - -#if LV_USE_VG_LITE_THORVG - /** Enable LVGL's blend mode support */ - #ifndef LV_VG_LITE_THORVG_LVGL_BLEND_SUPPORT - #ifdef CONFIG_LV_VG_LITE_THORVG_LVGL_BLEND_SUPPORT - #define LV_VG_LITE_THORVG_LVGL_BLEND_SUPPORT CONFIG_LV_VG_LITE_THORVG_LVGL_BLEND_SUPPORT - #else - #define LV_VG_LITE_THORVG_LVGL_BLEND_SUPPORT 0 - #endif - #endif - - /** Enable YUV color format support */ - #ifndef LV_VG_LITE_THORVG_YUV_SUPPORT - #ifdef CONFIG_LV_VG_LITE_THORVG_YUV_SUPPORT - #define LV_VG_LITE_THORVG_YUV_SUPPORT CONFIG_LV_VG_LITE_THORVG_YUV_SUPPORT - #else - #define LV_VG_LITE_THORVG_YUV_SUPPORT 0 - #endif - #endif - - /** Enable Linear gradient extension support */ - #ifndef LV_VG_LITE_THORVG_LINEAR_GRADIENT_EXT_SUPPORT - #ifdef CONFIG_LV_VG_LITE_THORVG_LINEAR_GRADIENT_EXT_SUPPORT - #define LV_VG_LITE_THORVG_LINEAR_GRADIENT_EXT_SUPPORT CONFIG_LV_VG_LITE_THORVG_LINEAR_GRADIENT_EXT_SUPPORT - #else - #define LV_VG_LITE_THORVG_LINEAR_GRADIENT_EXT_SUPPORT 0 - #endif - #endif - - /** Enable alignment on 16 pixels */ - #ifndef LV_VG_LITE_THORVG_16PIXELS_ALIGN - #ifdef LV_KCONFIG_PRESENT - #ifdef CONFIG_LV_VG_LITE_THORVG_16PIXELS_ALIGN - #define LV_VG_LITE_THORVG_16PIXELS_ALIGN CONFIG_LV_VG_LITE_THORVG_16PIXELS_ALIGN - #else - #define LV_VG_LITE_THORVG_16PIXELS_ALIGN 0 - #endif - #else - #define LV_VG_LITE_THORVG_16PIXELS_ALIGN 1 - #endif - #endif - - /** Buffer address alignment */ - #ifndef LV_VG_LITE_THORVG_BUF_ADDR_ALIGN - #ifdef CONFIG_LV_VG_LITE_THORVG_BUF_ADDR_ALIGN - #define LV_VG_LITE_THORVG_BUF_ADDR_ALIGN CONFIG_LV_VG_LITE_THORVG_BUF_ADDR_ALIGN - #else - #define LV_VG_LITE_THORVG_BUF_ADDR_ALIGN 64 - #endif - #endif - - /** Enable multi-thread render */ - #ifndef LV_VG_LITE_THORVG_THREAD_RENDER - #ifdef CONFIG_LV_VG_LITE_THORVG_THREAD_RENDER - #define LV_VG_LITE_THORVG_THREAD_RENDER CONFIG_LV_VG_LITE_THORVG_THREAD_RENDER - #else - #define LV_VG_LITE_THORVG_THREAD_RENDER 0 - #endif - #endif -#endif - /* Enable the multi-touch gesture recognition feature */ /* Gesture recognition requires the use of floats */ #ifndef LV_USE_GESTURE_RECOGNITION @@ -1815,20 +1879,6 @@ #define LV_FONT_DEJAVU_16_PERSIAN_HEBREW 0 /**< Hebrew, Arabic, Persian letters and all their forms */ #endif #endif -#ifndef LV_FONT_SIMSUN_14_CJK - #ifdef CONFIG_LV_FONT_SIMSUN_14_CJK - #define LV_FONT_SIMSUN_14_CJK CONFIG_LV_FONT_SIMSUN_14_CJK - #else - #define LV_FONT_SIMSUN_14_CJK 0 /**< 1000 most common CJK radicals */ - #endif -#endif -#ifndef LV_FONT_SIMSUN_16_CJK - #ifdef CONFIG_LV_FONT_SIMSUN_16_CJK - #define LV_FONT_SIMSUN_16_CJK CONFIG_LV_FONT_SIMSUN_16_CJK - #else - #define LV_FONT_SIMSUN_16_CJK 0 /**< 1000 most common CJK radicals */ - #endif -#endif #ifndef LV_FONT_SOURCE_HAN_SANS_SC_14_CJK #ifdef CONFIG_LV_FONT_SOURCE_HAN_SANS_SC_14_CJK #define LV_FONT_SOURCE_HAN_SANS_SC_14_CJK CONFIG_LV_FONT_SOURCE_HAN_SANS_SC_14_CJK @@ -2560,7 +2610,7 @@ /*================== * THEMES *==================*/ -/* Documentation for themes can be found here: https://docs.lvgl.io/master/details/common-widget-features/styles/style.html#themes . */ +/* Documentation for themes can be found here: https://docs.lvgl.io/master/details/common-widget-features/styles/styles.html#themes . */ /** A simple, impressive and very complete theme */ #ifndef LV_USE_THEME_DEFAULT @@ -2921,6 +2971,23 @@ #endif #endif +#ifndef LV_USE_FS_FROGFS + #ifdef CONFIG_LV_USE_FS_FROGFS + #define LV_USE_FS_FROGFS CONFIG_LV_USE_FS_FROGFS + #else + #define LV_USE_FS_FROGFS 0 + #endif +#endif +#if LV_USE_FS_FROGFS + #ifndef LV_FS_FROGFS_LETTER + #ifdef CONFIG_LV_FS_FROGFS_LETTER + #define LV_FS_FROGFS_LETTER CONFIG_LV_FS_FROGFS_LETTER + #else + #define LV_FS_FROGFS_LETTER '\0' + #endif + #endif +#endif + /** LODEPNG decoder library */ #ifndef LV_USE_LODEPNG #ifdef CONFIG_LV_USE_LODEPNG @@ -2987,6 +3054,14 @@ #endif #endif +/** GStreamer library */ +#ifndef LV_USE_GSTREAMER + #ifdef CONFIG_LV_USE_GSTREAMER + #define LV_USE_GSTREAMER CONFIG_LV_USE_GSTREAMER + #else + #define LV_USE_GSTREAMER 0 + #endif +#endif /** Decode bin images to RAM */ #ifndef LV_BIN_DECODER_RAM_LOAD @@ -3095,8 +3170,17 @@ #endif #endif +/** Requires `LV_USE_3DTEXTURE = 1` */ +#ifndef LV_USE_GLTF + #ifdef CONFIG_LV_USE_GLTF + #define LV_USE_GLTF CONFIG_LV_USE_GLTF + #else + #define LV_USE_GLTF 0 + #endif +#endif + /** Enable Vector Graphic APIs - * - Requires `LV_USE_MATRIX = 1` */ + * Requires `LV_USE_MATRIX = 1` */ #ifndef LV_USE_VECTOR_GRAPHIC #ifdef CONFIG_LV_USE_VECTOR_GRAPHIC #define LV_USE_VECTOR_GRAPHIC CONFIG_LV_USE_VECTOR_GRAPHIC @@ -3105,7 +3189,8 @@ #endif #endif -/** Enable ThorVG (vector graphics library) from the src/libs folder */ +/** Enable ThorVG (vector graphics library) from the src/libs folder. + * Requires LV_USE_VECTOR_GRAPHIC */ #ifndef LV_USE_THORVG_INTERNAL #ifdef CONFIG_LV_USE_THORVG_INTERNAL #define LV_USE_THORVG_INTERNAL CONFIG_LV_USE_THORVG_INTERNAL @@ -3114,7 +3199,8 @@ #endif #endif -/** Enable ThorVG by assuming that its installed and linked to the project */ +/** Enable ThorVG by assuming that its installed and linked to the project + * Requires LV_USE_VECTOR_GRAPHIC */ #ifndef LV_USE_THORVG_EXTERNAL #ifdef CONFIG_LV_USE_THORVG_EXTERNAL #define LV_USE_THORVG_EXTERNAL CONFIG_LV_USE_THORVG_EXTERNAL @@ -3226,6 +3312,25 @@ #define LV_SYSMON_GET_IDLE lv_os_get_idle_percent #endif #endif + /** 1: Enable usage of lv_os_get_proc_idle_percent.*/ + #ifndef LV_SYSMON_PROC_IDLE_AVAILABLE + #ifdef CONFIG_LV_SYSMON_PROC_IDLE_AVAILABLE + #define LV_SYSMON_PROC_IDLE_AVAILABLE CONFIG_LV_SYSMON_PROC_IDLE_AVAILABLE + #else + #define LV_SYSMON_PROC_IDLE_AVAILABLE 0 + #endif + #endif + #if LV_SYSMON_PROC_IDLE_AVAILABLE + /** Get the applications idle percentage. + * - Requires `LV_USE_OS == LV_OS_PTHREAD` */ + #ifndef LV_SYSMON_GET_PROC_IDLE + #ifdef CONFIG_LV_SYSMON_GET_PROC_IDLE + #define LV_SYSMON_GET_PROC_IDLE CONFIG_LV_SYSMON_GET_PROC_IDLE + #else + #define LV_SYSMON_GET_PROC_IDLE lv_os_get_proc_idle_percent + #endif + #endif + #endif /** 1: Show CPU usage and FPS count. * - Requires `LV_USE_SYSMON = 1` */ @@ -3317,6 +3422,13 @@ #define LV_PROFILER_BUILTIN_DEFAULT_ENABLE 1 #endif #endif + #ifndef LV_USE_PROFILER_BUILTIN_POSIX + #ifdef CONFIG_LV_USE_PROFILER_BUILTIN_POSIX + #define LV_USE_PROFILER_BUILTIN_POSIX CONFIG_LV_USE_PROFILER_BUILTIN_POSIX + #else + #define LV_USE_PROFILER_BUILTIN_POSIX 0 /**< Enable POSIX profiler port */ + #endif + #endif #endif /** Header to include for profiler */ @@ -3674,7 +3786,7 @@ #if LV_USE_TEST /** Enable `lv_test_screenshot_compare`. - * Requires libpng and a few MB of extra RAM. */ + * Requires lodepng and a few MB of extra RAM. */ #ifndef LV_USE_TEST_SCREENSHOT_COMPARE #ifdef CONFIG_LV_USE_TEST_SCREENSHOT_COMPARE #define LV_USE_TEST_SCREENSHOT_COMPARE CONFIG_LV_USE_TEST_SCREENSHOT_COMPARE @@ -3693,6 +3805,15 @@ #endif #endif +/** 1: Enable text translation support */ +#ifndef LV_USE_TRANSLATION + #ifdef CONFIG_LV_USE_TRANSLATION + #define LV_USE_TRANSLATION CONFIG_LV_USE_TRANSLATION + #else + #define LV_USE_TRANSLATION 0 + #endif +#endif + /*1: Enable color filter style*/ #ifndef LV_USE_COLOR_FILTER #ifdef CONFIG_LV_USE_COLOR_FILTER @@ -3701,6 +3822,7 @@ #define LV_USE_COLOR_FILTER 0 #endif #endif + /*================== * DEVICES *==================*/ @@ -3878,13 +4000,6 @@ #define LV_WAYLAND_WINDOW_DECORATIONS 0 /**< Draw client side window decorations only necessary on Mutter/GNOME. Not supported using DMABUF*/ #endif #endif - #ifndef LV_WAYLAND_WL_SHELL - #ifdef CONFIG_LV_WAYLAND_WL_SHELL - #define LV_WAYLAND_WL_SHELL CONFIG_LV_WAYLAND_WL_SHELL - #else - #define LV_WAYLAND_WL_SHELL 0 /**< Use the legacy wl_shell protocol instead of the default XDG shell*/ - #endif - #endif #endif /** Driver for /dev/fb */ @@ -4015,7 +4130,7 @@ #endif #endif - /*Touchscreen cursor size in pixels(<=0: disable cursor)*/ + /** Touchscreen cursor size in pixels(<=0: disable cursor) */ #ifndef LV_NUTTX_TOUCHSCREEN_CURSOR_SIZE #ifdef CONFIG_LV_NUTTX_TOUCHSCREEN_CURSOR_SIZE #define LV_NUTTX_TOUCHSCREEN_CURSOR_SIZE CONFIG_LV_NUTTX_TOUCHSCREEN_CURSOR_SIZE @@ -4023,6 +4138,47 @@ #define LV_NUTTX_TOUCHSCREEN_CURSOR_SIZE 0 #endif #endif + + /** Driver for /dev/mouse */ + #ifndef LV_USE_NUTTX_MOUSE + #ifdef CONFIG_LV_USE_NUTTX_MOUSE + #define LV_USE_NUTTX_MOUSE CONFIG_LV_USE_NUTTX_MOUSE + #else + #define LV_USE_NUTTX_MOUSE 0 + #endif + #endif + + /** Mouse movement step (pixels) */ + #ifndef LV_USE_NUTTX_MOUSE_MOVE_STEP + #ifdef LV_KCONFIG_PRESENT + #ifdef CONFIG_LV_USE_NUTTX_MOUSE_MOVE_STEP + #define LV_USE_NUTTX_MOUSE_MOVE_STEP CONFIG_LV_USE_NUTTX_MOUSE_MOVE_STEP + #else + #define LV_USE_NUTTX_MOUSE_MOVE_STEP 0 + #endif + #else + #define LV_USE_NUTTX_MOUSE_MOVE_STEP 1 + #endif + #endif + + /*NuttX trace file and its path*/ + #ifndef LV_USE_NUTTX_TRACE_FILE + #ifdef CONFIG_LV_USE_NUTTX_TRACE_FILE + #define LV_USE_NUTTX_TRACE_FILE CONFIG_LV_USE_NUTTX_TRACE_FILE + #else + #define LV_USE_NUTTX_TRACE_FILE 0 + #endif + #endif + #if LV_USE_NUTTX_TRACE_FILE + #ifndef LV_NUTTX_TRACE_FILE_PATH + #ifdef CONFIG_LV_NUTTX_TRACE_FILE_PATH + #define LV_NUTTX_TRACE_FILE_PATH CONFIG_LV_NUTTX_TRACE_FILE_PATH + #else + #define LV_NUTTX_TRACE_FILE_PATH "/data/lvgl-trace.log" + #endif + #endif + #endif + #endif /** Driver for /dev/dri/card */ @@ -4047,6 +4203,14 @@ #define LV_USE_LINUX_DRM_GBM_BUFFERS 0 #endif #endif + + #ifndef LV_LINUX_DRM_USE_EGL + #ifdef CONFIG_LV_LINUX_DRM_USE_EGL + #define LV_LINUX_DRM_USE_EGL CONFIG_LV_LINUX_DRM_USE_EGL + #else + #define LV_LINUX_DRM_USE_EGL 0 + #endif + #endif #endif /** Interface for TFT_eSPI */ @@ -4058,6 +4222,26 @@ #endif #endif +/** Interface for Lovyan_GFX */ +#ifndef LV_USE_LOVYAN_GFX + #ifdef CONFIG_LV_USE_LOVYAN_GFX + #define LV_USE_LOVYAN_GFX CONFIG_LV_USE_LOVYAN_GFX + #else + #define LV_USE_LOVYAN_GFX 0 + #endif +#endif + +#if LV_USE_LOVYAN_GFX + #ifndef LV_LGFX_USER_INCLUDE + #ifdef CONFIG_LV_LGFX_USER_INCLUDE + #define LV_LGFX_USER_INCLUDE CONFIG_LV_LGFX_USER_INCLUDE + #else + #define LV_LGFX_USER_INCLUDE "lv_lgfx_user.hpp" + #endif + #endif + +#endif /*LV_USE_LOVYAN_GFX*/ + /** Driver for evdev input devices */ #ifndef LV_USE_EVDEV #ifdef CONFIG_LV_USE_EVDEV @@ -4141,8 +4325,15 @@ #define LV_USE_FT81X 0 #endif #endif +#ifndef LV_USE_NV3007 + #ifdef CONFIG_LV_USE_NV3007 + #define LV_USE_NV3007 CONFIG_LV_USE_NV3007 + #else + #define LV_USE_NV3007 0 + #endif +#endif -#if (LV_USE_ST7735 | LV_USE_ST7789 | LV_USE_ST7796 | LV_USE_ILI9341) +#if (LV_USE_ST7735 | LV_USE_ST7789 | LV_USE_ST7796 | LV_USE_ILI9341 | LV_USE_NV3007) #ifndef LV_USE_GENERIC_MIPI #ifdef LV_KCONFIG_PRESENT #ifdef CONFIG_LV_USE_GENERIC_MIPI @@ -4192,6 +4383,15 @@ #endif #endif +/** Driver for NXP ELCDIF */ +#ifndef LV_USE_NXP_ELCDIF + #ifdef CONFIG_LV_USE_NXP_ELCDIF + #define LV_USE_NXP_ELCDIF CONFIG_LV_USE_NXP_ELCDIF + #else + #define LV_USE_NXP_ELCDIF 0 + #endif +#endif + /** LVGL Windows backend */ #ifndef LV_USE_WINDOWS #ifdef CONFIG_LV_USE_WINDOWS @@ -4226,7 +4426,7 @@ #endif #endif -/** Use OpenGL to open window on PC and handle mouse and keyboard */ +/** Use a generic OpenGL driver that can be used to embed in other applications or used with GLFW/EGL */ #ifndef LV_USE_OPENGLES #ifdef CONFIG_LV_USE_OPENGLES #define LV_USE_OPENGLES CONFIG_LV_USE_OPENGLES @@ -4248,6 +4448,16 @@ #endif #endif +/** Use GLFW to open window on PC and handle mouse and keyboard. Requires*/ +#ifndef LV_USE_GLFW + #ifdef CONFIG_LV_USE_GLFW + #define LV_USE_GLFW CONFIG_LV_USE_GLFW + #else + #define LV_USE_GLFW 0 + #endif +#endif + + /** QNX Screen display and input drivers */ #ifndef LV_USE_QNX #ifdef CONFIG_LV_USE_QNX @@ -4313,7 +4523,7 @@ #define LV_USE_DEMO_WIDGETS 0 #endif #endif - + /** Demonstrate usage of encoder and keyboard. */ #ifndef LV_USE_DEMO_KEYPAD_AND_ENCODER #ifdef CONFIG_LV_USE_DEMO_KEYPAD_AND_ENCODER @@ -4322,7 +4532,7 @@ #define LV_USE_DEMO_KEYPAD_AND_ENCODER 0 #endif #endif - + /** Benchmark your system */ #ifndef LV_USE_DEMO_BENCHMARK #ifdef CONFIG_LV_USE_DEMO_BENCHMARK @@ -4352,7 +4562,7 @@ #define LV_USE_DEMO_RENDER 0 #endif #endif - + /** Stress test for LVGL */ #ifndef LV_USE_DEMO_STRESS #ifdef CONFIG_LV_USE_DEMO_STRESS @@ -4361,7 +4571,7 @@ #define LV_USE_DEMO_STRESS 0 #endif #endif - + /** Music player demo */ #ifndef LV_USE_DEMO_MUSIC #ifdef CONFIG_LV_USE_DEMO_MUSIC @@ -4407,7 +4617,7 @@ #endif #endif #endif - + /** Vector graphic demo */ #ifndef LV_USE_DEMO_VECTOR_GRAPHIC #ifdef CONFIG_LV_USE_DEMO_VECTOR_GRAPHIC @@ -4416,11 +4626,20 @@ #define LV_USE_DEMO_VECTOR_GRAPHIC 0 #endif #endif - + + /** GLTF demo */ + #ifndef LV_USE_DEMO_GLTF + #ifdef CONFIG_LV_USE_DEMO_GLTF + #define LV_USE_DEMO_GLTF CONFIG_LV_USE_DEMO_GLTF + #else + #define LV_USE_DEMO_GLTF 0 + #endif + #endif + /*--------------------------- * Demos from lvgl/lv_demos ---------------------------*/ - + /** Flex layout demo */ #ifndef LV_USE_DEMO_FLEX_LAYOUT #ifdef CONFIG_LV_USE_DEMO_FLEX_LAYOUT @@ -4429,7 +4648,7 @@ #define LV_USE_DEMO_FLEX_LAYOUT 0 #endif #endif - + /** Smart-phone like multi-language demo */ #ifndef LV_USE_DEMO_MULTILANG #ifdef CONFIG_LV_USE_DEMO_MULTILANG @@ -4438,7 +4657,7 @@ #define LV_USE_DEMO_MULTILANG 0 #endif #endif - + /** Widget transformation demo */ #ifndef LV_USE_DEMO_TRANSFORM #ifdef CONFIG_LV_USE_DEMO_TRANSFORM @@ -4447,7 +4666,7 @@ #define LV_USE_DEMO_TRANSFORM 0 #endif #endif - + /** Demonstrate scroll settings */ #ifndef LV_USE_DEMO_SCROLL #ifdef CONFIG_LV_USE_DEMO_SCROLL @@ -4456,7 +4675,7 @@ #define LV_USE_DEMO_SCROLL 0 #endif #endif - + /*E-bike demo with Lottie animations (if LV_USE_LOTTIE is enabled)*/ #ifndef LV_USE_DEMO_EBIKE #ifdef CONFIG_LV_USE_DEMO_EBIKE @@ -4474,7 +4693,7 @@ #endif #endif #endif - + /** High-resolution demo */ #ifndef LV_USE_DEMO_HIGH_RES #ifdef CONFIG_LV_USE_DEMO_HIGH_RES @@ -4483,7 +4702,7 @@ #define LV_USE_DEMO_HIGH_RES 0 #endif #endif - + /* Smart watch demo */ #ifndef LV_USE_DEMO_SMARTWATCH #ifdef CONFIG_LV_USE_DEMO_SMARTWATCH @@ -4492,7 +4711,7 @@ #define LV_USE_DEMO_SMARTWATCH 0 #endif #endif -#endif /* LV_BUILD_DEMOS */ +#endif /* LV_BUILD_DEMOS */ @@ -4511,6 +4730,15 @@ LV_EXPORT_CONST_INT(LV_DRAW_BUF_ALIGN); #undef LV_KCONFIG_PRESENT +/* Disable VGLite drivers if VGLite drawing is disabled */ +#ifndef LV_USE_VG_LITE_DRIVER + #define LV_USE_VG_LITE_DRIVER 0 +#endif + +#ifndef LV_USE_VG_LITE_THORVG + #define LV_USE_VG_LITE_THORVG 0 +#endif + /* Set some defines if a dependency is disabled. */ #if LV_USE_LOG == 0 #define LV_LOG_LEVEL LV_LOG_LEVEL_NONE @@ -4527,12 +4755,16 @@ LV_EXPORT_CONST_INT(LV_DRAW_BUF_ALIGN); #if LV_USE_WAYLAND == 0 #define LV_WAYLAND_USE_DMABUF 0 #define LV_WAYLAND_WINDOW_DECORATIONS 0 - #define LV_WAYLAND_WL_SHELL 0 #endif /* LV_USE_WAYLAND */ +#if LV_USE_LINUX_DRM == 0 + #define LV_LINUX_DRM_USE_EGL 0 +#endif /*LV_USE_LINUX_DRM*/ + #if LV_USE_SYSMON == 0 #define LV_USE_PERF_MONITOR 0 #define LV_USE_MEM_MONITOR 0 + #define LV_SYSMON_PROC_IDLE_AVAILABLE 0 #endif /*LV_USE_SYSMON*/ #if LV_USE_PERF_MONITOR == 0 @@ -4572,9 +4804,13 @@ LV_EXPORT_CONST_INT(LV_DRAW_BUF_ALIGN); #endif #endif +#ifndef LV_USE_EGL + #define LV_USE_EGL LV_LINUX_DRM_USE_EGL +#endif /* LV_USE_EGL */ + #if LV_USE_OS #if (LV_USE_FREETYPE || LV_USE_THORVG) && LV_DRAW_THREAD_STACK_SIZE < (32 * 1024) - #warning "Increase LV_DRAW_THREAD_STACK_SIZE to at least 32KB for FreeType or ThorVG." + #error "Increase LV_DRAW_THREAD_STACK_SIZE to at least 32KB for FreeType or ThorVG." #endif #if defined(LV_DRAW_THREAD_STACKSIZE) && !defined(LV_DRAW_THREAD_STACK_SIZE) diff --git a/src/lv_conf_kconfig.h b/src/lv_conf_kconfig.h index 78f9596878..3a8d5d10bf 100644 --- a/src/lv_conf_kconfig.h +++ b/src/lv_conf_kconfig.h @@ -149,7 +149,7 @@ extern "C" { #ifdef CONFIG_LV_MEM_MONITOR_ALIGN_TOP_LEFT # define CONFIG_LV_USE_MEM_MONITOR_POS LV_ALIGN_TOP_LEFT -#elif defined(CONFIG_LV_USE_MEM_MONITOR_ALIGN_TOP_MID) +#elif defined(CONFIG_LV_MEM_MONITOR_ALIGN_TOP_MID) # define CONFIG_LV_USE_MEM_MONITOR_POS LV_ALIGN_TOP_MID #elif defined(CONFIG_LV_MEM_MONITOR_ALIGN_TOP_RIGHT) # define CONFIG_LV_USE_MEM_MONITOR_POS LV_ALIGN_TOP_RIGHT diff --git a/src/lv_init.c b/src/lv_init.c index 7192f72d9d..eaf4e74a4d 100644 --- a/src/lv_init.c +++ b/src/lv_init.c @@ -39,6 +39,7 @@ #include "misc/lv_fs.h" #include "osal/lv_os_private.h" #include "others/sysmon/lv_sysmon_private.h" +#include "others/translation/lv_translation.h" #include "others/xml/lv_xml.h" #if LV_USE_SVG @@ -48,16 +49,15 @@ #if LV_USE_NEMA_GFX #include "draw/nema_gfx/lv_draw_nema_gfx.h" #endif -#if LV_USE_DRAW_VGLITE - #include "draw/nxp/vglite/lv_draw_vglite.h" -#endif #if LV_USE_PXP #if LV_USE_DRAW_PXP || LV_USE_ROTATE_PXP #include "draw/nxp/pxp/lv_draw_pxp.h" #endif #endif -#if LV_USE_DRAW_G2D - #include "draw/nxp/g2d/lv_draw_g2d.h" +#if LV_USE_G2D + #if LV_USE_DRAW_G2D || LV_USE_ROTATE_G2D + #include "draw/nxp/g2d/lv_draw_g2d.h" + #endif #endif #if LV_USE_DRAW_DAVE2D #include "draw/renesas/dave2d/lv_draw_dave2d.h" @@ -74,6 +74,9 @@ #if LV_USE_DRAW_OPENGLES #include "draw/opengles/lv_draw_opengles.h" #endif +#if LV_USE_PPA + #include "draw/espressif/ppa/lv_draw_ppa.h" +#endif #if LV_USE_WINDOWS #include "drivers/windows/lv_windows_context.h" #endif @@ -83,6 +86,9 @@ #if LV_USE_EVDEV #include "drivers/evdev/lv_evdev_private.h" #endif +#if LV_USE_DRAW_EVE + #include "draw/eve/lv_draw_eve.h" +#endif /********************* * DEFINES @@ -196,9 +202,13 @@ void lv_init(void) #endif #if LV_USE_PROFILER && LV_USE_PROFILER_BUILTIN +#if LV_USE_PROFILER_BUILTIN_POSIX + lv_profiler_builtin_posix_init(); +#else lv_profiler_builtin_config_t profiler_config; lv_profiler_builtin_config_init(&profiler_config); lv_profiler_builtin_init(&profiler_config); +#endif #endif lv_os_init(); @@ -230,19 +240,17 @@ void lv_init(void) lv_draw_nema_gfx_init(); #endif -#if LV_USE_DRAW_VGLITE - lv_draw_vglite_init(); -#endif - #if LV_USE_PXP #if LV_USE_DRAW_PXP || LV_USE_ROTATE_PXP lv_draw_pxp_init(); #endif #endif -#if LV_USE_DRAW_G2D +#if LV_USE_G2D +#if LV_USE_DRAW_G2D || LV_USE_ROTATE_G2D lv_draw_g2d_init(); #endif +#endif #if LV_USE_DRAW_DAVE2D lv_draw_dave2d_init(); @@ -260,6 +268,10 @@ void lv_init(void) lv_draw_opengles_init(); #endif +#if LV_USE_PPA + lv_draw_ppa_init(); +#endif + #if LV_USE_WINDOWS lv_windows_platform_init(); #endif @@ -268,6 +280,10 @@ void lv_init(void) lv_uefi_platform_init(); #endif +#if LV_USE_DRAW_EVE + lv_draw_eve_init(); +#endif + lv_obj_style_init(); /*Initialize the screen refresh system*/ @@ -357,6 +373,10 @@ void lv_init(void) lv_fs_uefi_init(); #endif +#if LV_USE_FS_FROGFS + lv_fs_frogfs_init(); +#endif + /*Use the earlier initialized position of FFmpeg decoder as a fallback decoder*/ #if LV_USE_FFMPEG lv_ffmpeg_init(); @@ -386,6 +406,10 @@ void lv_init(void) lv_svg_decoder_init(); #endif +#if LV_USE_TRANSLATION + lv_translation_init(); +#endif + #if LV_USE_XML lv_xml_init(); #endif @@ -455,13 +479,11 @@ void lv_deinit(void) #endif #endif -#if LV_USE_DRAW_VGLITE - lv_draw_vglite_deinit(); -#endif - -#if LV_USE_DRAW_G2D +#if LV_USE_G2D +#if LV_USE_DRAW_G2D || LV_USE_ROTATE_G2D lv_draw_g2d_deinit(); #endif +#endif #if LV_USE_DRAW_VG_LITE lv_draw_vg_lite_deinit(); @@ -487,8 +509,6 @@ void lv_deinit(void) lv_layout_deinit(); - lv_fs_deinit(); - lv_timer_core_deinit(); #if LV_USE_PROFILER && LV_USE_PROFILER_BUILTIN @@ -499,6 +519,20 @@ void lv_deinit(void) lv_objid_builtin_destroy(); #endif +#if LV_USE_XML + lv_xml_deinit(); +#endif + +#if LV_USE_TRANSLATION + lv_translation_deinit(); +#endif + +#if LV_USE_FS_FROGFS + lv_fs_frogfs_deinit(); +#endif + + lv_fs_deinit(); + lv_mem_deinit(); lv_initialized = false; diff --git a/src/misc/cache/class/lv_cache_class.h b/src/misc/cache/class/lv_cache_class.h index 89b23c3f5e..a09912b14f 100644 --- a/src/misc/cache/class/lv_cache_class.h +++ b/src/misc/cache/class/lv_cache_class.h @@ -13,5 +13,6 @@ #include "lv_cache_lru_rb.h" #include "lv_cache_lru_ll.h" +#include "lv_cache_sc_da.h" #endif //LV_CACHE_CLAZZ_H diff --git a/src/misc/cache/class/lv_cache_sc_da.c b/src/misc/cache/class/lv_cache_sc_da.c new file mode 100644 index 0000000000..0dfe261ca2 --- /dev/null +++ b/src/misc/cache/class/lv_cache_sc_da.c @@ -0,0 +1,515 @@ +/** +* @file lv_cache_sc_da.c +* +*/ +/*********************************************\ +* * +* ┏ ━ ━ ━ ━ ━ ━ ━ ━ ━ ━ ━ ━ ━ ━ ┓ * +* * +* ┃ Second Chance Cache ┃ * +* * +* ┃ ┌───┬───┬───┬───┬───┐ ┃ * +* │ B │ E │ A │ D │ C │ * +* ┃ ├─┬─┼─┬─┼─┬─┼─┬─┼─┬─┤ ┃ * +* │1│ │0│ │1│ │1│ │0│ │ * +* ┃ └─┴─┴─┴─┴─┴─┴─┴─┴─┴─┘ ┃ * +* [0] [1] [2] [3] [4] * +* ┃ ▲ ▲ ▲ ▲ ┃ * +* │ │ │ │ * +* ┃ │ │ │ ┌ ─ ┴ ┐ ┃ * +* │ │ │ │ add │ * +* ┃ │ │ │ │ new │ ┃ * +* │ │ │ │here │ * +* ┃ │ │ │ └ ─ ─ ┘ ┃ * +* │ │ │ * +* ┃ │ │ ┌ ─ ┴ ─ ─ ─ ─ ┐ ┃ * +* │ │ │ recently │ * +* ┃ │ │ │ used bit=1 │ ┃ * +* │ │ │ (accessed) │ * +* ┃ │ │ └ ─ ─ ─ ─ ─ ─ ┘ ┃ * +* │ │ * +* ┃ │ └ ─ ─ victim bit=0 ┃ * +* │ (will be evicted) * +* ┃ └ ─ ─ ─ ─ victim bit=1 ┃ * +* (gets second chance, * +* ┃ bit reset to 0) ┃ * +* * +* ┃ Eviction Process: ┃ * +* 1. Find first bit=0 * +* ┃ 2. If none, reset all to 0 ┃ * +* 3. Replace first entry * +* ┃ ┃ * +* ┗ ━ ━ ━ ━ ━ ━ ━ ━ ━ ━ ━ ━ ━ ━ ┛ * +* * +* ┏━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┓ * +* ┃ Buffer Entry Structure ┃ * +* ┃ ┌────────────┬──────────────────────┐ ┃ * +* ┃ │ DATA │ ENTRY_DATA │ ┃ * +* ┃ │ (user type)│ (lv_cache_entry_t) │ ┃ * +* ┃ └────────────┴──────────────────────┘ ┃ * +* ┗━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┛ * +\*********************************************/ + +/********************* + * INCLUDES + *********************/ + +#include "lv_cache_sc_da.h" +#include "../lv_cache_entry.h" +#include "../lv_cache_entry_private.h" +#include "../../../stdlib/lv_sprintf.h" +#include "../../../stdlib/lv_string.h" + +#include "../../lv_iter.h" +#include "../../lv_assert.h" +#include "../../lv_math.h" +#include "../../lv_types.h" + +/********************* + * DEFINES + *********************/ + +/********************** + * TYPEDEFS + **********************/ + +typedef uint32_t(get_data_size_cb_t)(const void * data); + +typedef struct { + lv_cache_t cache; + uint8_t * data; + size_t capacity; +} lv_cache_sc_da_t; + +/********************** + * STATIC PROTOTYPES + **********************/ + +static void * alloc_cb(void); +static bool init_cnt_cb(lv_cache_t * cache); +static void destroy_cb(lv_cache_t * cache, void * user_data); + +static lv_cache_entry_t * get_cb(lv_cache_t * cache, const void * key, + void * user_data); +static lv_cache_entry_t * add_cb(lv_cache_t * cache, const void * key, + void * user_data); +static void remove_cb(lv_cache_t * cache, lv_cache_entry_t * entry, + void * user_data); +static void drop_cb(lv_cache_t * cache, const void * key, void * user_data); +static void drop_all_cb(lv_cache_t * cache, void * user_data); +static lv_cache_entry_t * get_victim_cb(lv_cache_t * cache, void * user_data); +static lv_cache_reserve_cond_res_t reserve_cond_cb(lv_cache_t * cache, + const void * key, + size_t reserved_size, + void * user_data); + +static void * alloc_new_entry(lv_cache_sc_da_t * da, const void * key, + void * user_data); + +static lv_iter_t * cache_iter_create_cb(lv_cache_t * cache); +static lv_result_t cache_iter_next_cb(void * instance, void * context, + void * elem); + +static lv_cache_entry_t * get_possible_victim(lv_cache_sc_da_t * da, + size_t index); + +static inline void set_second_chance(lv_cache_entry_t * entry, bool value); +static inline bool has_second_chance(lv_cache_entry_t * entry); +static inline void get_entry(lv_cache_sc_da_t * da, size_t index, + void ** cache_data, lv_cache_entry_t ** cache_entry); + +/********************** + * GLOBAL VARIABLES + **********************/ +const lv_cache_class_t lv_cache_class_sc_da = { + .alloc_cb = alloc_cb, + .init_cb = init_cnt_cb, + .destroy_cb = destroy_cb, + + .get_cb = get_cb, + .add_cb = add_cb, + .remove_cb = remove_cb, + .drop_cb = drop_cb, + .drop_all_cb = drop_all_cb, + .get_victim_cb = get_victim_cb, + .reserve_cond_cb = reserve_cond_cb, + .iter_create_cb = cache_iter_create_cb, +}; + +/********************** + * STATIC VARIABLES + **********************/ + +/********************** + * MACROS + **********************/ + +#define LV_CACHE_ENTRY_SIZE lv_cache_entry_get_size(0) + +/********************** + * GLOBAL FUNCTIONS + **********************/ + +/********************** + * STATIC FUNCTIONS + **********************/ + +static inline void get_entry(lv_cache_sc_da_t * da, size_t index, + void ** cache_data, lv_cache_entry_t ** cache_entry) +{ + const size_t node_size = lv_cache_entry_get_size(da->cache.node_size); + *cache_data = da->data + (index * node_size); + *cache_entry = + lv_cache_entry_get_entry(*cache_data, da->cache.node_size); +} +static inline void set_second_chance(lv_cache_entry_t * entry, bool value) +{ + if(value) { + lv_cache_entry_set_flag(entry, LV_CACHE_ENTRY_FLAG_CLASS_CUSTOM); + } + else { + lv_cache_entry_remove_flag(entry, LV_CACHE_ENTRY_FLAG_CLASS_CUSTOM); + } +} + +static inline bool has_second_chance(lv_cache_entry_t * entry) +{ + return lv_cache_entry_has_flag(entry, LV_CACHE_ENTRY_FLAG_CLASS_CUSTOM); +} + +static void * alloc_new_entry(lv_cache_sc_da_t * da, const void * key, + void * user_data) +{ + LV_UNUSED(user_data); + + LV_ASSERT_NULL(da); + LV_ASSERT_NULL(key); + + if(da == NULL || key == NULL) { + return NULL; + } + const size_t node_size = lv_cache_entry_get_size(da->cache.node_size); + + if(da->capacity == da->cache.size) { + if(da->capacity == da->cache.max_size) { + LV_LOG_ERROR( + "Reached maximum size of cache. Unable to allocate a new entry"); + return NULL; + } + + const size_t new_capacity = + LV_MIN(da->capacity == 0 ? 1 : da->capacity * 2, + da->cache.max_size); + + uint8_t * new_data = (uint8_t *)lv_realloc( + da->data, new_capacity * node_size); + + if(!new_data) { + LV_LOG_ERROR("Failed to allocate new data for cache"); + return NULL; + } + + da->data = new_data; + da->capacity = new_capacity; + } + void * last_da_entry; + lv_cache_entry_t * last_cache_entry; + + get_entry(da, da->cache.size, &last_da_entry, &last_cache_entry); + + lv_memcpy(last_da_entry, key, da->cache.node_size); + lv_cache_entry_init(last_cache_entry, &da->cache, da->cache.node_size); + lv_cache_entry_set_flag(last_cache_entry, LV_CACHE_ENTRY_FLAG_DISABLE_DELETE); + + /*New entries start with their second chance set*/ + set_second_chance(last_cache_entry, true); + return last_cache_entry; +} + +static void * alloc_cb(void) +{ + return lv_calloc(1, sizeof(lv_cache_sc_da_t)); +} + +static bool init_cnt_cb(lv_cache_t * cache) +{ + LV_ASSERT_NULL(cache); + lv_cache_sc_da_t * da = (lv_cache_sc_da_t *)cache; + return da->cache.node_size > 0 && da->cache.ops.compare_cb && + da->cache.ops.free_cb; +} + +static void destroy_cb(lv_cache_t * cache, void * user_data) +{ + LV_UNUSED(user_data); + + lv_cache_sc_da_t * da = (lv_cache_sc_da_t *)cache; + + LV_ASSERT_NULL(da); + + if(da == NULL) { + return; + } + + cache->clz->drop_all_cb(cache, user_data); + cache->size = 0; + lv_free(da->data); + da->data = NULL; + da->capacity = 0; +} + +static lv_cache_entry_t * get_cb(lv_cache_t * cache, const void * key, + void * user_data) +{ + LV_UNUSED(user_data); + + lv_cache_sc_da_t * da = (lv_cache_sc_da_t *)cache; + + LV_ASSERT_NULL(da); + LV_ASSERT_NULL(key); + + if(da == NULL || key == NULL) { + return NULL; + } + + /* Linear search */ + lv_cache_entry_t * cache_entry = NULL; + for(size_t i = 0; i < da->cache.size; ++i) { + void * curr_da_entry; + lv_cache_entry_t * curr_cache_entry; + get_entry(da, i, &curr_da_entry, &curr_cache_entry); + + if(da->cache.ops.compare_cb(curr_da_entry, key) == 0) { + cache_entry = curr_cache_entry; + /*When an entry is used, we set it's second chance to true again*/ + set_second_chance(cache_entry, true); + break; + } + } + return cache_entry; +} + +static lv_cache_entry_t * add_cb(lv_cache_t * cache, const void * key, + void * user_data) +{ + LV_UNUSED(user_data); + + lv_cache_sc_da_t * da = (lv_cache_sc_da_t *)cache; + + LV_ASSERT_NULL(da); + LV_ASSERT_NULL(key); + + if(da == NULL || key == NULL) { + return NULL; + } + + lv_cache_entry_t * entry = alloc_new_entry(da, key, user_data); + if(entry == NULL) { + return NULL; + } + + cache->size += 1; + + return entry; +} + +static void remove_cb(lv_cache_t * cache, lv_cache_entry_t * entry, + void * user_data) +{ + LV_UNUSED(user_data); + + lv_cache_sc_da_t * da = (lv_cache_sc_da_t *)cache; + + LV_ASSERT_NULL(da); + LV_ASSERT_NULL(entry); + + if(da == NULL || entry == NULL) { + return; + } + + const size_t entry_size = lv_cache_entry_get_size(da->cache.node_size); + uint8_t * da_entry_to_remove = (uint8_t *)lv_cache_entry_get_data(entry); + + void * last_da_entry; + lv_cache_entry_t * last_cache_entry; + get_entry(da, cache->size - 1, &last_da_entry, &last_cache_entry); + + if(da_entry_to_remove != last_da_entry) { + lv_memcpy(da_entry_to_remove, last_da_entry, entry_size); + } + cache->size -= 1; +} + +static void drop_cb(lv_cache_t * cache, const void * key, void * user_data) +{ + lv_cache_sc_da_t * da = (lv_cache_sc_da_t *)cache; + + LV_ASSERT_NULL(da); + LV_ASSERT_NULL(key); + + if(da == NULL || key == NULL) { + return; + } + lv_cache_entry_t * entry = cache->clz->get_cb(cache, key, user_data); + if(!entry) { + return; + } + + const size_t entry_size = lv_cache_entry_get_size(da->cache.node_size); + uint8_t * da_entry_to_remove = (uint8_t *)lv_cache_entry_get_data(entry); + + void * last_da_entry; + lv_cache_entry_t * last_cache_entry; + get_entry(da, cache->size - 1, &last_da_entry, &last_cache_entry); + + if(da_entry_to_remove != last_da_entry) { + lv_memcpy(da_entry_to_remove, last_da_entry, entry_size); + } + cache->ops.free_cb(da_entry_to_remove, user_data); + cache->size -= 1; +} + +static void drop_all_cb(lv_cache_t * cache, void * user_data) +{ + lv_cache_sc_da_t * da = (lv_cache_sc_da_t *)cache; + + LV_ASSERT_NULL(da); + + if(da == NULL) { + return; + } + uint32_t used_cnt = 0; + for(size_t i = 0; i < cache->size; ++i) { + void * da_entry; + lv_cache_entry_t * cache_entry; + get_entry(da, i, &da_entry, &cache_entry); + const int32_t refs = lv_cache_entry_get_ref(cache_entry); + + if(refs > 0) { + LV_LOG_WARN( + "entry (%zu) is still referenced (%" LV_PRId32 + ")", + i, refs); + used_cnt++; + continue; + } + da->cache.ops.free_cb(da_entry, user_data); + } + if(used_cnt > 0) { + LV_LOG_WARN("%" LV_PRId32 " entries are still referenced", + used_cnt); + } + + cache->size = 0; +} + +static lv_cache_entry_t * get_possible_victim(lv_cache_sc_da_t * da, size_t index) +{ + LV_ASSERT(index < da->cache.size); + + void * da_entry; + lv_cache_entry_t * cache_entry; + get_entry(da, index, &da_entry, &cache_entry); + + const uint8_t sec_chance = has_second_chance(cache_entry); + const int32_t refs = lv_cache_entry_get_ref(cache_entry); + + if(sec_chance == 0 && refs == 0) { + return cache_entry; + } + if(sec_chance == 0 && refs > 0) { + LV_LOG_INFO( + "Entry %zu should be evicted but it's still referenced %" LV_PRId32 + " times\n", + index, refs); + return NULL; + } + + /*Remove its second chance*/ + set_second_chance(cache_entry, false); + return NULL; +} + +static lv_cache_entry_t * get_victim_cb(lv_cache_t * cache, void * user_data) +{ + LV_UNUSED(user_data); + + lv_cache_sc_da_t * da = (lv_cache_sc_da_t *)cache; + + LV_ASSERT_NULL(da); + /* + * We iterate twice to handle the complexity introduced by reference counting + * in the second chance algorithm: + * + * First iteration: Clear second chance bits and look for victims (entries with + * sec_chance=0 AND refs=0). Some entries may have sec_chance=0 but refs>0, + * making them unavailable for eviction despite being marked for removal. + * + * Second iteration: Now that all second chance bits are cleared from the first + * pass, we can find entries that are truly available for eviction (refs=0). + * We can't assume the first entry will be the victim after the first round + * because reference counts may prevent eviction of otherwise eligible entries. + * + * This ensures we give all entries a proper second chance while respecting + * active references that prevent immediate eviction. + */ + for(size_t i = 0; i < 2; ++i) { + for(size_t j = 0; j < da->cache.size; ++j) { + lv_cache_entry_t * victim = get_possible_victim(da, j); + if(victim) { + return victim; + } + } + } + return NULL; +} + +static lv_cache_reserve_cond_res_t reserve_cond_cb(lv_cache_t * cache, + const void * key, + size_t reserved_size, + void * user_data) +{ + LV_UNUSED(user_data); + LV_UNUSED(key); + + lv_cache_sc_da_t * da = (lv_cache_sc_da_t *)cache; + + LV_ASSERT_NULL(da); + + if(da == NULL) { + return LV_CACHE_RESERVE_COND_ERROR; + } + + return cache->size + reserved_size + 1 > da->cache.max_size ? + LV_CACHE_RESERVE_COND_NEED_VICTIM : + LV_CACHE_RESERVE_COND_OK; +} + +static lv_iter_t * cache_iter_create_cb(lv_cache_t * cache) +{ + return lv_iter_create(cache, lv_cache_entry_get_size(cache->node_size), + 0, cache_iter_next_cb); +} + +static lv_result_t cache_iter_next_cb(void * instance, void * context, void * elem) +{ + lv_cache_sc_da_t * da = (lv_cache_sc_da_t *)instance; + uint8_t ** da_entry = context; + LV_ASSERT_NULL(da_entry); + const size_t entry_size = lv_cache_entry_get_size(da->cache.node_size); + + if(*da_entry == NULL) { + *da_entry = da->data; + } + else { + *da_entry += entry_size; + } + + if(*da_entry == NULL) { + return LV_RESULT_INVALID; + } + + lv_memcpy(elem, da_entry, entry_size); + + return LV_RESULT_OK; +} diff --git a/src/misc/cache/class/lv_cache_sc_da.h b/src/misc/cache/class/lv_cache_sc_da.h new file mode 100644 index 0000000000..8223db729d --- /dev/null +++ b/src/misc/cache/class/lv_cache_sc_da.h @@ -0,0 +1,44 @@ +/** +* @file lv_cache_sc_da.h +* +*/ + +#ifndef LV_CACHE_SC_DA_H +#define LV_CACHE_SC_DA_H + +#ifdef __cplusplus +extern "C" { +#endif + +/********************* + * INCLUDES + *********************/ + +#include "../lv_cache_private.h" + +/********************* + * DEFINES + *********************/ + +/********************** + * TYPEDEFS + **********************/ + +/********************** + * GLOBAL PROTOTYPES + **********************/ + +/************************* + * GLOBAL VARIABLES + *************************/ +LV_ATTRIBUTE_EXTERN_DATA extern const lv_cache_class_t lv_cache_class_sc_da; + +/********************** + * MACROS + **********************/ + +#ifdef __cplusplus +} /*extern "C"*/ +#endif + +#endif /*LV_CACHE_SC_DA_H*/ diff --git a/src/misc/cache/lv_cache.c b/src/misc/cache/lv_cache.c index 33a72196f0..a029db1790 100644 --- a/src/misc/cache/lv_cache.c +++ b/src/misc/cache/lv_cache.c @@ -11,6 +11,7 @@ #include "../lv_assert.h" #include "lv_cache_entry_private.h" #include "lv_cache_private.h" +#include "../lv_profiler.h" /********************* * DEFINES @@ -319,7 +320,7 @@ static void cache_drop_internal_no_lock(lv_cache_t * cache, const void * key, vo lv_cache_entry_delete(entry); } else { - lv_cache_entry_set_invalid(entry, true); + lv_cache_entry_set_flag(entry, LV_CACHE_ENTRY_FLAG_INVALID); cache->clz->remove_cb(cache, entry, user_data); } } diff --git a/src/misc/cache/lv_cache_entry.c b/src/misc/cache/lv_cache_entry.c index 4f280e66e3..ff79d5b079 100644 --- a/src/misc/cache/lv_cache_entry.c +++ b/src/misc/cache/lv_cache_entry.c @@ -9,9 +9,7 @@ #include "lv_cache_entry.h" #include "../../stdlib/lv_sprintf.h" #include "../lv_assert.h" -#include "lv_cache.h" #include "lv_cache_entry_private.h" -#include "lv_cache_private.h" /********************* * DEFINES @@ -20,13 +18,7 @@ /********************** * TYPEDEFS **********************/ -struct _lv_cache_entry_t { - const lv_cache_t * cache; - int32_t ref_cnt; - uint32_t node_size; - bool is_invalid; -}; /********************** * STATIC PROTOTYPES **********************/ @@ -86,16 +78,10 @@ void lv_cache_entry_set_node_size(lv_cache_entry_t * entry, uint32_t node_size) entry->node_size = node_size; } -void lv_cache_entry_set_invalid(lv_cache_entry_t * entry, bool is_invalid) -{ - LV_ASSERT_NULL(entry); - entry->is_invalid = is_invalid; -} - bool lv_cache_entry_is_invalid(lv_cache_entry_t * entry) { LV_ASSERT_NULL(entry); - return entry->is_invalid; + return entry->flags & LV_CACHE_ENTRY_FLAG_INVALID; } void * lv_cache_entry_get_data(lv_cache_entry_t * entry) @@ -169,17 +155,39 @@ void lv_cache_entry_init(lv_cache_entry_t * entry, const lv_cache_t * cache, con entry->cache = cache; entry->node_size = node_size; entry->ref_cnt = 0; - entry->is_invalid = false; + entry->flags = 0; } void lv_cache_entry_delete(lv_cache_entry_t * entry) { LV_ASSERT_NULL(entry); + if(entry->flags & LV_CACHE_ENTRY_FLAG_DISABLE_DELETE) { + return; + } + void * data = lv_cache_entry_get_data(entry); lv_free(data); } +void lv_cache_entry_set_flag(lv_cache_entry_t * entry, uint8_t flags) +{ + LV_ASSERT_NULL(entry); + entry->flags |= flags; +} + +void lv_cache_entry_remove_flag(lv_cache_entry_t * entry, uint8_t flags) +{ + LV_ASSERT_NULL(entry); + entry->flags &= (~flags); +} + +bool lv_cache_entry_has_flag(lv_cache_entry_t * entry, uint8_t flags) +{ + LV_ASSERT_NULL(entry); + return (entry->flags & flags) == flags; +} + /********************** * STATIC FUNCTIONS **********************/ diff --git a/src/misc/cache/lv_cache_entry_private.h b/src/misc/cache/lv_cache_entry_private.h index 7fc2794cb8..de16ff5480 100644 --- a/src/misc/cache/lv_cache_entry_private.h +++ b/src/misc/cache/lv_cache_entry_private.h @@ -6,6 +6,7 @@ #ifndef LV_CACHE_ENTRY_PRIVATE_H #define LV_CACHE_ENTRY_PRIVATE_H +#include #ifdef __cplusplus extern "C" { #endif @@ -14,8 +15,6 @@ extern "C" { * INCLUDES *********************/ #include "../lv_types.h" -#include "../../osal/lv_os.h" -#include "../lv_profiler.h" /********************* * DEFINES @@ -25,6 +24,16 @@ extern "C" { * TYPEDEFS **********************/ +struct _lv_cache_entry_t { + const lv_cache_t * cache; + int32_t ref_cnt; + uint32_t node_size; +#define LV_CACHE_ENTRY_FLAG_INVALID (1 << 0) /** Flag indicating if the entry is invalid and can be released */ +#define LV_CACHE_ENTRY_FLAG_DISABLE_DELETE (1 << 1) /** This flag should be set if the cache class is managing the memory of the entry itself*/ +#define LV_CACHE_ENTRY_FLAG_CLASS_CUSTOM (1 << 7) /**A custom flag that can be used by the different cache classes*/ + uint8_t flags; +}; + /********************** * GLOBAL PROTOTYPES **********************/ @@ -32,11 +41,12 @@ void lv_cache_entry_reset_ref(lv_cache_entry_t * entry); void lv_cache_entry_inc_ref(lv_cache_entry_t * entry); void lv_cache_entry_dec_ref(lv_cache_entry_t * entry); void lv_cache_entry_set_node_size(lv_cache_entry_t * entry, uint32_t node_size); -void lv_cache_entry_set_invalid(lv_cache_entry_t * entry, bool is_invalid); void lv_cache_entry_set_cache(lv_cache_entry_t * entry, const lv_cache_t * cache); void * lv_cache_entry_acquire_data(lv_cache_entry_t * entry); void lv_cache_entry_release_data(lv_cache_entry_t * entry, void * user_data); - +void lv_cache_entry_set_flag(lv_cache_entry_t * entry, uint8_t flags); +void lv_cache_entry_remove_flag(lv_cache_entry_t * entry, uint8_t flags); +bool lv_cache_entry_has_flag(lv_cache_entry_t * entry, uint8_t flags); /************************* * GLOBAL VARIABLES *************************/ diff --git a/src/misc/cache/lv_cache_private.h b/src/misc/cache/lv_cache_private.h index 80bd0b9895..80efd15f28 100644 --- a/src/misc/cache/lv_cache_private.h +++ b/src/misc/cache/lv_cache_private.h @@ -14,7 +14,7 @@ extern "C" { * INCLUDES *********************/ #include "../lv_types.h" -#include "../../osal/lv_os.h" +#include "../../osal/lv_os_private.h" /********************* * DEFINES diff --git a/src/misc/lv_anim.c b/src/misc/lv_anim.c index 7eab8fbfab..1f651da132 100644 --- a/src/misc/lv_anim.c +++ b/src/misc/lv_anim.c @@ -40,6 +40,7 @@ * STATIC PROTOTYPES **********************/ static void anim_timer(lv_timer_t * param); +static void anim_vsync_event(lv_event_t * e); static void anim_mark_list_change(void); static void anim_completed_handler(lv_anim_t * a); static int32_t lv_anim_path_cubic_bezier(const lv_anim_t * a, int32_t x1, @@ -80,6 +81,30 @@ void lv_anim_core_deinit(void) lv_anim_delete_all(); } +void lv_anim_enable_vsync_mode(bool enable) +{ + if(enable) { + /* Remove animation timer, use vsync instead */ + if(state.timer) { + lv_timer_delete(state.timer); + state.timer = NULL; + } + } + else { + if(!state.timer) { + state.timer = lv_timer_create(anim_timer, LV_DEF_REFR_PERIOD, NULL); + LV_ASSERT_NULL(state.timer); + + if(state.anim_vsync_registered) { + lv_display_unregister_vsync_event(NULL, anim_vsync_event, NULL); + state.anim_vsync_registered = false; + } + } + } + + anim_mark_list_change(); +} + void lv_anim_init(lv_anim_t * a) { lv_memzero(a, sizeof(lv_anim_t)); @@ -661,6 +686,7 @@ static void anim_completed_handler(lv_anim_t * a) else { /*Restart the animation. If the time is over a little compensate it.*/ int32_t over_time = 0; + a->start_cb_called = 0; if(a->act_time > a->duration) over_time = a->act_time - a->duration; a->act_time = over_time - (int32_t)(a->repeat_delay); /*Swap start and end values in reverse-play mode*/ @@ -682,13 +708,38 @@ static void anim_completed_handler(lv_anim_t * a) } } +static void anim_vsync_event(lv_event_t * e) +{ + LV_UNUSED(e); + anim_timer(NULL); +} + static void anim_mark_list_change(void) { state.anim_list_changed = true; - if(lv_ll_get_head(anim_ll_p) == NULL) - lv_timer_pause(state.timer); - else + if(lv_ll_get_head(anim_ll_p) == NULL) { + if(state.timer) { + lv_timer_pause(state.timer); + return; + } + + if(state.anim_vsync_registered) { + lv_display_unregister_vsync_event(NULL, anim_vsync_event, NULL); + state.anim_vsync_registered = false; + } + + return; + } + + if(state.timer) { lv_timer_resume(state.timer); + return; + } + + if(!state.anim_vsync_registered) { + lv_display_register_vsync_event(NULL, anim_vsync_event, NULL); + state.anim_vsync_registered = true; + } } static int32_t lv_anim_path_cubic_bezier(const lv_anim_t * a, int32_t x1, int32_t y1, int32_t x2, int32_t y2) diff --git a/src/misc/lv_anim_private.h b/src/misc/lv_anim_private.h index 5c25850170..83e4cd6bef 100644 --- a/src/misc/lv_anim_private.h +++ b/src/misc/lv_anim_private.h @@ -27,6 +27,7 @@ extern "C" { typedef struct { bool anim_list_changed; bool anim_run_round; + bool anim_vsync_registered; lv_timer_t * timer; lv_ll_t anim_ll; } lv_anim_state_t; @@ -45,6 +46,12 @@ void lv_anim_core_init(void); */ void lv_anim_core_deinit(void); +/* + * Set animation use vsync mode. + * @param enable true: use vsync mode, false: use timer mode. + */ +void lv_anim_enable_vsync_mode(bool enable); + /********************** * MACROS **********************/ diff --git a/src/misc/lv_anim_timeline.c b/src/misc/lv_anim_timeline.c index 68abf5940a..a3cb876169 100644 --- a/src/misc/lv_anim_timeline.c +++ b/src/misc/lv_anim_timeline.c @@ -8,9 +8,12 @@ *********************/ #include "lv_anim_private.h" #include "lv_assert.h" -#include "lv_anim_timeline.h" +#include "lv_anim_timeline_private.h" #include "../stdlib/lv_mem.h" #include "../stdlib/lv_string.h" +#if LV_USE_OBJ_NAME + #include "../core/lv_obj_tree.h" +#endif /********************* * DEFINES @@ -19,23 +22,6 @@ /********************** * TYPEDEFS **********************/ -/*Data of anim_timeline_dsc*/ -typedef struct { - lv_anim_t anim; - uint32_t start_time; - uint8_t is_started : 1; - uint8_t is_completed : 1; -} lv_anim_timeline_dsc_t; - -/*Data of anim_timeline*/ -struct _lv_anim_timeline_t { - lv_anim_timeline_dsc_t * anim_dsc; /**< Dynamically allocated anim dsc array*/ - uint32_t anim_dsc_cnt; /**< The length of anim dsc array*/ - uint32_t act_time; /**< Current time of the animation*/ - bool reverse; /**< Reverse playback*/ - uint32_t repeat_count; /**< Repeat count*/ - uint32_t repeat_delay; /**< Wait before repeat*/ -}; /********************** * STATIC PROTOTYPES @@ -43,6 +29,7 @@ struct _lv_anim_timeline_t { static void anim_timeline_exec_cb(void * var, int32_t v); static void anim_timeline_set_act_time(lv_anim_timeline_t * at, uint32_t act_time); static int32_t anim_timeline_path_cb(const lv_anim_t * a); +static void exec_anim(lv_anim_t * a, int32_t v); /********************** * STATIC VARIABLES @@ -92,7 +79,7 @@ uint32_t lv_anim_timeline_start(lv_anim_timeline_t * at) uint32_t playtime = lv_anim_timeline_get_playtime(at); uint32_t repeat = at->repeat_count; - uint32_t delay = at->repeat_delay; + uint32_t repeat_delay = at->repeat_delay; uint32_t start = at->act_time; uint32_t end = at->reverse ? 0 : playtime; uint32_t duration = end > start ? end - start : start - end; @@ -104,15 +91,21 @@ uint32_t lv_anim_timeline_start(lv_anim_timeline_t * at) } } + /*Apply the delay only if playing from any ends*/ + uint32_t delay = 0; + if(!at->reverse && at->act_time == 0) delay = at->delay; + else if(at->reverse && at->act_time == playtime) delay = at->delay; + lv_anim_t a; lv_anim_init(&a); lv_anim_set_var(&a, at); lv_anim_set_exec_cb(&a, anim_timeline_exec_cb); lv_anim_set_values(&a, start, end); lv_anim_set_duration(&a, duration); + lv_anim_set_delay(&a, delay); lv_anim_set_path_cb(&a, anim_timeline_path_cb); lv_anim_set_repeat_count(&a, repeat); - lv_anim_set_repeat_delay(&a, delay); + lv_anim_set_repeat_delay(&a, repeat_delay); lv_anim_start(&a); return playtime; } @@ -130,6 +123,12 @@ void lv_anim_timeline_set_reverse(lv_anim_timeline_t * at, bool reverse) at->reverse = reverse; } +void lv_anim_timeline_set_delay(lv_anim_timeline_t * at, uint32_t delay) +{ + LV_ASSERT_NULL(at); + at->delay = delay; +} + void lv_anim_timeline_set_repeat_count(lv_anim_timeline_t * at, uint32_t cnt) { LV_ASSERT_NULL(at); @@ -151,6 +150,12 @@ void lv_anim_timeline_set_progress(lv_anim_timeline_t * at, uint16_t progress) anim_timeline_set_act_time(at, act_time); } +void lv_anim_timeline_set_user_data(lv_anim_timeline_t * at, void * user_data) +{ + LV_ASSERT_NULL(at); + at->user_data = user_data; +} + uint32_t lv_anim_timeline_get_playtime(lv_anim_timeline_t * at) { LV_ASSERT_NULL(at); @@ -175,6 +180,13 @@ bool lv_anim_timeline_get_reverse(lv_anim_timeline_t * at) return at->reverse; } + +uint32_t lv_anim_timeline_get_delay(lv_anim_timeline_t * at) +{ + LV_ASSERT_NULL(at); + return at->delay; +} + uint16_t lv_anim_timeline_get_progress(lv_anim_timeline_t * at) { LV_ASSERT_NULL(at); @@ -194,6 +206,22 @@ uint32_t lv_anim_timeline_get_repeat_delay(lv_anim_timeline_t * at) return at->repeat_delay; } +void * lv_anim_timeline_get_user_data(lv_anim_timeline_t * at) +{ + LV_ASSERT_NULL(at); + return at->user_data; +} + +void lv_anim_timeline_merge(lv_anim_timeline_t * dest, const lv_anim_timeline_t * src, int32_t delay) +{ + uint32_t i; + for(i = 0; i < src->anim_dsc_cnt; i++) { + uint32_t anim_delay = src->anim_dsc[i].start_time + delay; + lv_anim_timeline_add(dest, anim_delay, &src->anim_dsc[i].anim); + } +} + + /********************** * STATIC FUNCTIONS **********************/ @@ -221,8 +249,7 @@ static void anim_timeline_set_act_time(lv_anim_timeline_t * at, uint32_t act_tim } value = a->start_value; - if(a->exec_cb) a->exec_cb(a->var, value); - if(a->custom_exec_cb) a->custom_exec_cb(a, value); + exec_anim(a, value); if(anim_timeline_is_started) { if(at->reverse) { @@ -242,8 +269,7 @@ static void anim_timeline_set_act_time(lv_anim_timeline_t * at, uint32_t act_tim a->act_time = act_time - start_time; value = a->path_cb(a); - if(a->exec_cb) a->exec_cb(a->var, value); - if(a->custom_exec_cb) a->custom_exec_cb(a, value); + exec_anim(a, value); if(anim_timeline_is_started) { if(at->reverse) { @@ -278,8 +304,7 @@ static void anim_timeline_set_act_time(lv_anim_timeline_t * at, uint32_t act_tim } value = a->end_value; - if(a->exec_cb) a->exec_cb(a->var, value); - if(a->custom_exec_cb) a->custom_exec_cb(a, value); + exec_anim(a, value); if(anim_timeline_is_started) { if(at->reverse) { @@ -305,3 +330,14 @@ static void anim_timeline_exec_cb(void * var, int32_t v) lv_anim_timeline_t * at = var; anim_timeline_set_act_time(at, v); } + +static void exec_anim(lv_anim_t * a, int32_t v) +{ + + if(a->exec_cb) { + a->exec_cb(a->var, v); + } + if(a->custom_exec_cb) { + a->custom_exec_cb(a, v); + } +} diff --git a/src/misc/lv_anim_timeline.h b/src/misc/lv_anim_timeline.h index 0e9651d530..941d315526 100644 --- a/src/misc/lv_anim_timeline.h +++ b/src/misc/lv_anim_timeline.h @@ -25,7 +25,14 @@ extern "C" { * TYPEDEFS **********************/ -typedef struct _lv_anim_timeline_t lv_anim_timeline_t; +/*Data of anim_timeline_dsc*/ +typedef struct _lv_anim_timeline_dsc_t { + lv_anim_t anim; + uint32_t start_time; + uint8_t is_started : 1; + uint8_t is_completed : 1; +} lv_anim_timeline_dsc_t; + /********************** * GLOBAL PROTOTYPES @@ -54,7 +61,7 @@ void lv_anim_timeline_add(lv_anim_timeline_t * at, uint32_t start_time, const lv /** * Start the animation timeline. * @param at pointer to the animation timeline. - * @return total time spent in animation timeline. + * @return total time spent in animation timeline. */ uint32_t lv_anim_timeline_start(lv_anim_timeline_t * at); @@ -71,6 +78,14 @@ void lv_anim_timeline_pause(lv_anim_timeline_t * at); */ void lv_anim_timeline_set_reverse(lv_anim_timeline_t * at, bool reverse); +/** + * Set the time to wait before starting the animation. + * Applies only when playing from the very start, or reverse from the very end. + * @param at pointer to an animation timeline + * @param delay the delay time in milliseconds + */ +void lv_anim_timeline_set_delay(lv_anim_timeline_t * at, uint32_t delay); + /** * Make the animation timeline repeat itself. * @param at pointer to the animation timeline. @@ -92,24 +107,38 @@ void lv_anim_timeline_set_repeat_delay(lv_anim_timeline_t * at, uint32_t delay); */ void lv_anim_timeline_set_progress(lv_anim_timeline_t * at, uint16_t progress); +/** + * Set the user_data of a an animation timeline + * @param at pointer to the animation timeline. + * @param user_data pointer to any data. Only the pointer will be saved. + */ +void lv_anim_timeline_set_user_data(lv_anim_timeline_t * at, void * user_data); + /** * Get the time used to play the animation timeline. - * @param at pointer to the animation timeline. - * @return total time spent in animation timeline. + * @param at pointer to the animation timeline. + * @return total time spent in animation timeline. */ uint32_t lv_anim_timeline_get_playtime(lv_anim_timeline_t * at); /** * Get whether the animation timeline is played in reverse. - * @param at pointer to the animation timeline. - * @return return true if it is reverse playback. + * @param at pointer to the animation timeline. + * @return return true if it is reverse playback. */ bool lv_anim_timeline_get_reverse(lv_anim_timeline_t * at); +/** + * Get the wait time when playing from the very start, or reverse from the very end. + * @param at pointer to an animation timeline + * @return the remaining time in milliseconds + */ +uint32_t lv_anim_timeline_get_delay(lv_anim_timeline_t * at); + /** * Get the progress of the animation timeline. * @param at pointer to the animation timeline. - * @return return value 0~65535 to map 0~100% animation progress. + * @return return value 0~65535 to map 0~100% animation progress. */ uint16_t lv_anim_timeline_get_progress(lv_anim_timeline_t * at); @@ -125,6 +154,20 @@ uint32_t lv_anim_timeline_get_repeat_count(lv_anim_timeline_t * at); */ uint32_t lv_anim_timeline_get_repeat_delay(lv_anim_timeline_t * at); +/** + * Get the user_data of a an animation timeline + * @param at pointer to the animation timeline. + */ +void * lv_anim_timeline_get_user_data(lv_anim_timeline_t * at); + +/** + * Merge (add) all animations of a timeline to another + * @param dest merge animation into this timeline + * @param src merge the animations of this timeline + * @param delay add the animations with this extra delay + */ +void lv_anim_timeline_merge(lv_anim_timeline_t * dest, const lv_anim_timeline_t * src, int32_t delay); + /********************** * MACROS **********************/ diff --git a/src/misc/lv_anim_timeline_private.h b/src/misc/lv_anim_timeline_private.h new file mode 100644 index 0000000000..cf94baed30 --- /dev/null +++ b/src/misc/lv_anim_timeline_private.h @@ -0,0 +1,67 @@ +/** + * @file lv_anim_timeline_private.h + * + */ + +#ifndef LV_ANIM_TIMELINE_PRIVATE_H +#define LV_ANIM_TIMELINE_PRIVATE_H + +#ifdef __cplusplus +extern "C" { +#endif + +/********************* + * INCLUDES + *********************/ +#include "lv_anim_timeline.h" + +/********************* + * DEFINES + *********************/ + +/********************** + * TYPEDEFS + **********************/ + +struct _lv_anim_timeline_dsc_t; + +/*Data of anim_timeline*/ +struct _lv_anim_timeline_t { + /** Dynamically allocated anim dsc array*/ + struct _lv_anim_timeline_dsc_t * anim_dsc; + + /** The length of anim dsc array*/ + uint32_t anim_dsc_cnt; + + /** Current time of the animation*/ + uint32_t act_time; + + /** Reverse playback*/ + bool reverse; + + /** Delay before starting the animation from any ends*/ + uint32_t delay; + + /** Repeat count*/ + uint32_t repeat_count; + + /** Wait before repeat*/ + uint32_t repeat_delay; + + /** For any custom data*/ + void * user_data; +}; + +/********************** +* GLOBAL PROTOTYPES +**********************/ + +/********************** + * MACROS + **********************/ + +#ifdef __cplusplus +} /*extern "C"*/ +#endif + +#endif /*LV_ANIM_TIMELINE_PRIVATE_H*/ diff --git a/src/misc/lv_color.h b/src/misc/lv_color.h index 0116de1e19..22a8de5002 100644 --- a/src/misc/lv_color.h +++ b/src/misc/lv_color.h @@ -37,7 +37,7 @@ LV_EXPORT_CONST_INT(LV_COLOR_DEPTH); * Opacity percentages. */ -enum { +enum _lv_opacity_level_t { LV_OPA_TRANSP = 0, LV_OPA_0 = 0, LV_OPA_10 = 25, @@ -328,6 +328,33 @@ lv_color32_t lv_color32_make(uint8_t r, uint8_t g, uint8_t b, uint8_t a); */ lv_color_t lv_color_hex3(uint32_t c); +/** + * Check if a color with an RGB888 color is within the color range defined by l_color and h_color. + * @param color the color to check + * @param l_color the lower bound color + * @param h_color the upper bound color + * @return true: pixel is within the color range + */ +static inline bool lv_color_is_in_range(lv_color_t color, lv_color_t l_color, lv_color_t h_color) +{ + return (color.red <= h_color.red && + color.green <= h_color.green && + color.blue <= h_color.blue && + color.red >= l_color.red && + color.green >= l_color.green && + color.blue >= l_color.blue); +} + +/** + * Convert a RGB565 color to RGB888 + * @param c a RGB565 color on lv_color16_t + * @return the color + */ +static inline lv_color_t lv_color16_to_color(lv_color16_t c) +{ + return lv_color_make(c.red << 3, c.green << 2, c.blue << 3); +} + /** * Convert am RGB888 color to RGB565 stored in `uint16_t` * @param color and RGB888 color diff --git a/src/misc/lv_color_op.c b/src/misc/lv_color_op.c index b9d281115e..cf0f77c7e5 100644 --- a/src/misc/lv_color_op.c +++ b/src/misc/lv_color_op.c @@ -1,5 +1,5 @@ /** - * @file lv_color.c + * @file lv_color_op.c * */ diff --git a/src/misc/lv_color_op.h b/src/misc/lv_color_op.h index 6905d1ab87..0c28c0b17e 100644 --- a/src/misc/lv_color_op.h +++ b/src/misc/lv_color_op.h @@ -102,4 +102,4 @@ lv_color32_t lv_color_over32(lv_color32_t fg, lv_color32_t bg); } /*extern "C"*/ #endif -#endif /*LV_COLOR_H*/ +#endif /*LV_COLOR_OP_H*/ diff --git a/src/misc/lv_event.c b/src/misc/lv_event.c index 81a0e9603d..70e092ab7a 100644 --- a/src/misc/lv_event.c +++ b/src/misc/lv_event.c @@ -69,6 +69,29 @@ void lv_event_pop(lv_event_t * e) event_head = e->prev; } +lv_result_t lv_event_push_and_send(lv_event_list_t * event_list, lv_event_code_t code, void * original_target, + void * param) +{ + LV_ASSERT_NULL(event_list); + lv_event_t e; + lv_memzero(&e, sizeof(e)); + e.code = code; + e.current_target = original_target; + e.original_target = original_target; + e.param = param; + + lv_event_push(&e); + lv_result_t res = lv_event_send(event_list, &e, true); + if(res != LV_RESULT_OK) goto ret; + + res = lv_event_send(event_list, &e, false); + if(res != LV_RESULT_OK) goto ret; + +ret: + lv_event_pop(&e); + return res; +} + lv_result_t lv_event_send(lv_event_list_t * list, lv_event_t * e, bool preprocess) { if(list == NULL) return LV_RESULT_OK; @@ -229,11 +252,22 @@ void lv_event_stop_bubbling(lv_event_t * e) e->stop_bubbling = 1; } +void lv_event_stop_trickling(lv_event_t * e) +{ + e->stop_trickling = 1; +} + void lv_event_stop_processing(lv_event_t * e) { e->stop_processing = 1; } +void lv_event_free_user_data_cb(lv_event_t * e) +{ + void * p = lv_event_get_user_data(e); + lv_free(p); +} + uint32_t lv_event_register_id(void) { event_last_id ++; @@ -337,6 +371,10 @@ const char * lv_event_code_get_name(lv_event_code_t code) ENUM_CASE(EVENT_VSYNC); ENUM_CASE(EVENT_VSYNC_REQUEST); +#if LV_USE_TRANSLATION + ENUM_CASE(EVENT_TRANSLATION_LANGUAGE_CHANGED); +#endif /*LV_USE_TRANSLATION*/ + /* Special event flags */ case LV_EVENT_LAST: case LV_EVENT_PREPROCESS: diff --git a/src/misc/lv_event.h b/src/misc/lv_event.h index a51def9819..202dc84a92 100644 --- a/src/misc/lv_event.h +++ b/src/misc/lv_event.h @@ -106,7 +106,7 @@ typedef enum { LV_EVENT_REFR_START, /**< Sent before a refreshing cycle starts. Sent even if there is nothing to redraw. */ LV_EVENT_REFR_READY, /**< Sent when refreshing has been completed (after rendering and calling flush callback). Sent even if no redraw happened. */ LV_EVENT_RENDER_START, /**< Sent just before rendering begins. */ - LV_EVENT_RENDER_READY, /**< Sent after rendering has been completed (before calling flush callback) */ + LV_EVENT_RENDER_READY, /**< Sent after rendering has been completed. */ LV_EVENT_FLUSH_START, /**< Sent before flush callback is called. */ LV_EVENT_FLUSH_FINISH, /**< Sent after flush callback call has returned. */ LV_EVENT_FLUSH_WAIT_START, /**< Sent before flush wait callback is called. */ @@ -114,6 +114,9 @@ typedef enum { LV_EVENT_VSYNC, LV_EVENT_VSYNC_REQUEST, +#if LV_USE_TRANSLATION + LV_EVENT_TRANSLATION_LANGUAGE_CHANGED, /**< Sent when the translation language changed. */ +#endif /*LV_USE_TRANSLATION*/ LV_EVENT_LAST, /** Number of default events */ @@ -195,6 +198,13 @@ void * lv_event_get_user_data(lv_event_t * e); */ void lv_event_stop_bubbling(lv_event_t * e); +/** + * Stop event from trickling down to children. + * This is only valid when called in the middle of an event processing chain. + * @param e pointer to the event descriptor + */ +void lv_event_stop_trickling(lv_event_t * e); + /** * Stop processing this event. * This is only valid when called in the middle of an event processing chain. @@ -202,6 +212,14 @@ void lv_event_stop_bubbling(lv_event_t * e); */ void lv_event_stop_processing(lv_event_t * e); +/** + * Helper function typically used in LV_EVENT_DELETE + * to free the event's user_data + * @param e pointer to an event descriptor + */ +void lv_event_free_user_data_cb(lv_event_t * e); + + /** * Register a new, custom event ID. * It can be used the same way as e.g. `LV_EVENT_CLICKED` to send custom events diff --git a/src/misc/lv_event_private.h b/src/misc/lv_event_private.h index 5ba0e5a53b..c380b4cb13 100644 --- a/src/misc/lv_event_private.h +++ b/src/misc/lv_event_private.h @@ -40,6 +40,7 @@ struct _lv_event_t { uint8_t deleted : 1; uint8_t stop_processing : 1; uint8_t stop_bubbling : 1; + uint8_t stop_trickling : 1; }; @@ -55,6 +56,10 @@ void lv_event_push(lv_event_t * e); void lv_event_pop(lv_event_t * e); + +lv_result_t lv_event_push_and_send(lv_event_list_t * event_list, lv_event_code_t code, void * original_target, + void * param); + /** * Nested events can be called and one of them might belong to an object that is being deleted. * Mark this object's `event_temp_data` deleted to know that its `lv_obj_send_event` should return `LV_RESULT_INVALID` diff --git a/src/misc/lv_fs.c b/src/misc/lv_fs.c index e90d00c7f7..2eff13f09e 100644 --- a/src/misc/lv_fs.c +++ b/src/misc/lv_fs.c @@ -125,10 +125,13 @@ lv_fs_res_t lv_fs_open(lv_fs_file_t * file_p, const char * path, lv_fs_mode_t mo /* If this is a memory-mapped file, then set "cache" to the memory buffer */ if(drv->cache_size == LV_FS_CACHE_FROM_BUFFER) { lv_fs_path_ex_t * path_ex = (lv_fs_path_ex_t *)path; - file_p->cache->buffer = (void *)path_ex->buffer; + lv_result_t res = lv_fs_get_buffer_from_path(path_ex, &file_p->cache->buffer, &file_p->cache->end); + if(res == LV_RESULT_INVALID) { + LV_LOG_WARN("lv_fs_path_ex_t is invalid"); + return LV_FS_RES_UNKNOWN; + } file_p->cache->start = 0; file_p->cache->file_position = 0; - file_p->cache->end = path_ex->size; } /*Set an invalid range by default*/ else { @@ -142,13 +145,50 @@ lv_fs_res_t lv_fs_open(lv_fs_file_t * file_p, const char * path, lv_fs_mode_t mo return LV_FS_RES_OK; } -void lv_fs_make_path_from_buffer(lv_fs_path_ex_t * path, char letter, const void * buf, uint32_t size) +void lv_fs_make_path_from_buffer(lv_fs_path_ex_t * path, char letter, const void * buf, uint32_t size, const char * ext) +{ + /*Make a path the contains both the address and the size. */ + + /*Don't add the '.' and the extension if the extension is NULL*/ + if(ext == NULL) { + lv_snprintf(path->path, sizeof(path->path), "%c:%zu-%" LV_PRIu32, letter, (size_t) buf, size); + } + else { + lv_snprintf(path->path, sizeof(path->path), "%c:%zu-%" LV_PRIu32 ".%s", letter, + (size_t) buf, size, ext); + } +} + +lv_result_t lv_fs_get_buffer_from_path(lv_fs_path_ex_t * path, void ** buffer, uint32_t * size) { - path->path[0] = letter; - path->path[1] = ':'; - path->path[2] = 0; - path->buffer = buf; - path->size = size; + LV_ASSERT_NULL(path); + LV_ASSERT_NULL(buffer); + LV_ASSERT_NULL(size); + + *size = 0; + *buffer = NULL; + + if(path->path[0] < 'A' || path->path[0] > 'Z') return LV_RESULT_INVALID; + if(path->path[1] != ':') return LV_RESULT_INVALID; + + uint32_t i; + lv_uintptr_t adr = 0; + for(i = 2; path->path[i] != '-' && path->path[i] != '\0' && i < sizeof(path->path); i++) { + adr = adr * 10; + adr += path->path[i] - '0'; + } + + if(path->path[i] == '\0' || i == sizeof(path->path)) return LV_RESULT_INVALID; + i++; /*Skip '-'*/ + + for(; path->path[i] != '.' && path->path[i] != '\0' && i < sizeof(path->path); i++) { + *size = (*size) * 10; + *size += path->path[i] - '0'; + } + + *buffer = (void *)adr; + + return LV_RESULT_OK; } lv_fs_res_t lv_fs_close(lv_fs_file_t * file_p) @@ -301,6 +341,78 @@ lv_fs_res_t lv_fs_tell(lv_fs_file_t * file_p, uint32_t * pos) return res; } +lv_fs_res_t lv_fs_get_size(lv_fs_file_t * file_p, uint32_t * size_res) +{ + uint32_t original_pos; + lv_fs_res_t ret = lv_fs_tell(file_p, &original_pos); + if(ret != LV_FS_RES_OK) { + return ret; + } + + ret = lv_fs_seek(file_p, 0, LV_FS_SEEK_END); + if(ret != LV_FS_RES_OK) { + return ret; + } + + ret = lv_fs_tell(file_p, size_res); + + if(ret != LV_FS_RES_OK || *size_res != original_pos) { + lv_fs_res_t seek_res = lv_fs_seek(file_p, original_pos, LV_FS_SEEK_SET); + if(ret == LV_FS_RES_OK) { + ret = seek_res; + } + } + + return ret; +} + +lv_fs_res_t lv_fs_path_get_size(const char * path, uint32_t * size_res) +{ + lv_fs_file_t file; + lv_fs_res_t ret = lv_fs_open(&file, path, LV_FS_MODE_RD); + if(ret != LV_FS_RES_OK) { + return ret; + } + + ret = lv_fs_seek(&file, 0, LV_FS_SEEK_END); + + if(ret == LV_FS_RES_OK) { + ret = lv_fs_tell(&file, size_res); + } + + lv_fs_res_t close_res = lv_fs_close(&file); + if(ret == LV_FS_RES_OK) { + ret = close_res; + } + + return ret; +} + +lv_fs_res_t lv_fs_load_to_buf(void * buf, uint32_t buf_size, const char * path) +{ + lv_fs_file_t file; + lv_fs_res_t ret = lv_fs_open(&file, path, LV_FS_MODE_RD); + if(ret != LV_FS_RES_OK) { + return ret; + } + + uint32_t bytes_read; + ret = lv_fs_read(&file, buf, buf_size, &bytes_read); + + if(ret == LV_FS_RES_OK && bytes_read != buf_size) { + LV_LOG_WARN("Only %"LV_PRIu32" bytes out of %"LV_PRIu32" were read from the file to the buffer", + bytes_read, buf_size); + ret = LV_FS_RES_UNKNOWN; + } + + lv_fs_res_t close_res = lv_fs_close(&file); + if(ret == LV_FS_RES_OK) { + ret = close_res; + } + + return ret; +} + lv_fs_res_t lv_fs_dir_open(lv_fs_dir_t * rddir_p, const char * path) { if(path == NULL) return LV_FS_RES_INV_PARAM; @@ -489,7 +601,7 @@ const char * lv_fs_get_last(const char * path) size_t i; for(i = len; i > 0; i--) { - if(path[i] == '/' || path[i] == '\\') break; + if(path[i] == '/' || path[i] == '\\' || path[i] == ':') break; } /*No '/' or '\' in the path so return with path itself*/ @@ -497,6 +609,31 @@ const char * lv_fs_get_last(const char * path) return &path[i + 1]; } + +int lv_fs_path_join(char * buf, size_t buf_sz, const char * base, const char * end) +{ + if(base[0] == '\0') return lv_strlcpy(buf, end, buf_sz); + if(end[0] == '\0') return lv_strlcpy(buf, base, buf_sz); + + size_t base_len = lv_strlen(base); + char base_end_char = base_len ? base[base_len - 1] : '\0'; + + bool base_has_sep = base_end_char == '/' || base_end_char == '\\'; + bool end_has_sep = end[0] == '/' || end[0] == '\\'; + + if(base_has_sep && end_has_sep) { + end++; + end_has_sep = false; + } + + const char * sep = "/"; + if(base_has_sep || end_has_sep) { + sep = ""; + } + + return lv_snprintf(buf, buf_sz, "%s%s%s", base, sep, end); +} + /********************** * STATIC FUNCTIONS **********************/ diff --git a/src/misc/lv_fs.h b/src/misc/lv_fs.h index cefbf96337..8ddab3731f 100644 --- a/src/misc/lv_fs.h +++ b/src/misc/lv_fs.h @@ -97,6 +97,13 @@ typedef struct { lv_fs_drv_t * drv; } lv_fs_dir_t; + +/** Extended path object to specify buffer for memory-mapped files */ +typedef struct { + char path[64]; /**< Store the driver letter address and size*/ +} lv_fs_path_ex_t; + + /********************** * GLOBAL PROTOTYPES **********************/ @@ -142,13 +149,34 @@ bool lv_fs_is_ready(char letter); lv_fs_res_t lv_fs_open(lv_fs_file_t * file_p, const char * path, lv_fs_mode_t mode); /** - * Make a path object for the memory-mapped file compatible with the file system interface + * Create a special object from buffer/ memory address which looks like a file and can be passed + * as path to `lv_fs_open` and other functions accepting a path. + * + * For example + * @code + * //Create a PNG file from t a buffer and use it + * lv_fs_path_ex_t p; + * lv_fs_make_path_from_buffer(&p, 'A', my_buf, my_buf_size, "png"); + * lv_image_set_src(image1, &p); + * + * @endcode * @param path path to a lv_fs_path_ex object * @param letter the identifier letter of the driver. E.g. `LV_FS_MEMFS_LETTER` * @param buf address of the memory buffer * @param size size of the memory buffer in bytes + * @param ext the extension, e.g. "png", if NULL no extension will be added. */ -void lv_fs_make_path_from_buffer(lv_fs_path_ex_t * path, char letter, const void * buf, uint32_t size); +void lv_fs_make_path_from_buffer(lv_fs_path_ex_t * path, char letter, const void * buf, uint32_t size, + const char * ext); + +/** + * Get the buffer address and size from a path object + * @param path pointer to an initialized `lv_fs_path_ex` data + * @param buffer pointer to a `void *` variable to store the address + * @param size pointer to an `uint32_t` data to store the size + * @return LV_RESULT_OK: buffer and size are set; LV_RESULT_INVALID: an error happened. + */ +lv_result_t lv_fs_get_buffer_from_path(lv_fs_path_ex_t * path, void ** buffer, uint32_t * size); /** * Close an already opened file @@ -194,6 +222,34 @@ lv_fs_res_t lv_fs_seek(lv_fs_file_t * file_p, uint32_t pos, lv_fs_whence_t whenc */ lv_fs_res_t lv_fs_tell(lv_fs_file_t * file_p, uint32_t * pos); +/** + * Get the size in bytes of an open file. + * The file read/write position will not be affected. + * @param file_p pointer to a lv_fs_file_t variable + * @param size_res pointer to store the file size + * @return LV_FS_RES_OK or any error from `lv_fs_res_t` + */ +lv_fs_res_t lv_fs_get_size(lv_fs_file_t * file_p, uint32_t * size_res); + +/** + * Get the size in bytes of a file at the given path. + * @param path the path of the file + * @param size_res pointer to store the file size + * @return LV_FS_RES_OK or any error from `lv_fs_res_t` + */ +lv_fs_res_t lv_fs_path_get_size(const char * path, uint32_t * size_res); + +/** + * Read the contents of a file at the given path into a buffer. + * @param buf a buffer to read the contents of the file into + * @param buf_size the size of the buffer and the amount to read from the file + * @param path the path of the file + * @return LV_FS_RES_OK on success, LV_FS_RES_UNKNOWN if fewer than + * `buf_size` bytes could be read from the file, + * or any error from `lv_fs_res_t` + */ +lv_fs_res_t lv_fs_load_to_buf(void * buf, uint32_t buf_size, const char * path); + /** * Initialize a 'fs_dir_t' variable for directory reading * @param rddir_p pointer to a 'lv_fs_dir_t' variable @@ -247,6 +303,19 @@ char * lv_fs_up(char * path); */ const char * lv_fs_get_last(const char * path); +/** + * Concatenate two path components and automatically add/remove a separator as needed. + * buf, buf_sz, and the return value are analogous to lv_snprintf + * @param buf the buffer to place the result in + * @param buf_sz the size of buf. At most buf_sz - 1 characters will be written to buf, + * and a null terminator + * @param base the first path component + * @param end the second path component + * @return the number of characters (not including the null terminator) + * that would be written to buf, even if buf_sz-1 was smaller + */ +int lv_fs_path_join(char * buf, size_t buf_sz, const char * base, const char * end); + /********************** * MACROS **********************/ diff --git a/src/misc/lv_fs_private.h b/src/misc/lv_fs_private.h index c6b2137414..0c67840080 100644 --- a/src/misc/lv_fs_private.h +++ b/src/misc/lv_fs_private.h @@ -31,13 +31,6 @@ struct _lv_fs_file_cache_t { void * buffer; }; -/** Extended path object to specify buffer for memory-mapped files */ -struct _lv_fs_path_ex_t { - char path[4]; /**< This is needed to make it compatible with a normal path */ - const void * buffer; - uint32_t size; -}; - /********************** * GLOBAL PROTOTYPES **********************/ diff --git a/src/misc/lv_grad.c b/src/misc/lv_grad.c index f3a73613dc..298837aa1f 100644 --- a/src/misc/lv_grad.c +++ b/src/misc/lv_grad.c @@ -61,9 +61,6 @@ void lv_grad_vertical_init(lv_grad_dsc_t * dsc) dsc->dir = LV_GRAD_DIR_VER; } - -#if LV_USE_DRAW_SW_COMPLEX_GRADIENTS - void lv_grad_linear_init(lv_grad_dsc_t * dsc, int32_t from_x, int32_t from_y, int32_t to_x, int32_t to_y, lv_grad_extend_t extend) { @@ -113,8 +110,6 @@ void lv_grad_radial_set_focal(lv_grad_dsc_t * dsc, int32_t center_x, int32_t cen dsc->params.radial.focal_extent.y = center_y; } -#endif /* LV_USE_DRAW_SW_COMPLEX_GRADIENTS */ - /********************** * STATIC FUNCTIONS **********************/ diff --git a/src/misc/lv_grad.h b/src/misc/lv_grad.h index 3ddeb724d4..60f880fba3 100644 --- a/src/misc/lv_grad.h +++ b/src/misc/lv_grad.h @@ -64,7 +64,6 @@ typedef struct { * LV_GRAD_TYPE_LINEAR, LV_GRAD_TYPE_RADIAL, LV_GRAD_TYPE_CONICAL */ lv_grad_extend_t extend : 3; /**< Behaviour outside the defined range. * LV_GRAD_EXTEND_NONE, LV_GRAD_EXTEND_PAD, LV_GRAD_EXTEND_REPEAT, LV_GRAD_EXTEND_REFLECT */ -#if LV_USE_DRAW_SW_COMPLEX_GRADIENTS union { /*Linear gradient parameters*/ struct { @@ -87,7 +86,6 @@ typedef struct { } conical; } params; void * state; -#endif } lv_grad_dsc_t; @@ -118,8 +116,6 @@ void lv_grad_horizontal_init(lv_grad_dsc_t * dsc); */ void lv_grad_vertical_init(lv_grad_dsc_t * dsc); -#if LV_USE_DRAW_SW_COMPLEX_GRADIENTS - /** * Helper function to initialize linear gradient * @param dsc gradient descriptor @@ -169,8 +165,6 @@ void lv_grad_radial_set_focal(lv_grad_dsc_t * dsc, int32_t center_x, int32_t cen void lv_grad_conical_init(lv_grad_dsc_t * dsc, int32_t center_x, int32_t center_y, int32_t start_angle, int32_t end_angle, lv_grad_extend_t extend); -#endif /*LV_USE_DRAW_SW_COMPLEX_GRADIENTS*/ - /********************** * MACROS **********************/ diff --git a/src/misc/lv_lru.c b/src/misc/lv_lru.c index 006584153f..3bff0e2e28 100755 --- a/src/misc/lv_lru.c +++ b/src/misc/lv_lru.c @@ -88,7 +88,7 @@ lv_lru_t * lv_lru_create(size_t cache_size, size_t average_length, lv_lru_free_c cache->value_free = value_free ? value_free : lv_free; cache->key_free = key_free ? key_free : lv_free; - // size the hash table to a guestimate of the number of slots required (assuming a perfect hash) + // size the hash table to a guesstimate of the number of slots required (assuming a perfect hash) cache->items = lv_malloc_zeroed(sizeof(lv_lru_item_t *) * cache->hash_table_size); if(!cache->items) { LV_LOG_WARN("LRU Cache unable to create cache hash table"); diff --git a/src/misc/lv_math.c b/src/misc/lv_math.c index a6d51a0555..757b0ea347 100644 --- a/src/misc/lv_math.c +++ b/src/misc/lv_math.c @@ -403,6 +403,8 @@ int64_t lv_pow(int64_t base, int8_t exp) int32_t lv_map(int32_t x, int32_t min_in, int32_t max_in, int32_t min_out, int32_t max_out) { + if(max_in == min_in) return min_out; /*Avoid division by zero later*/ + if(max_in >= min_in && x >= max_in) return max_out; if(max_in >= min_in && x <= min_in) return min_out; diff --git a/src/misc/lv_matrix.c b/src/misc/lv_matrix.c index 62a9584812..a2455dac2a 100644 --- a/src/misc/lv_matrix.c +++ b/src/misc/lv_matrix.c @@ -198,12 +198,21 @@ lv_point_precise_t lv_matrix_transform_precise_point(const lv_matrix_t * matrix, lv_area_t lv_matrix_transform_area(const lv_matrix_t * matrix, const lv_area_t * area) { + if(lv_matrix_is_identity(matrix)) { + return *area; + } + + /** + * Since lv_area_t will subtract 1px when calculating width and height, + * this will affect the matrix transformation calculation, so +1px is needed as compensation, + * and the compensation value is subtracted after the calculation is completed + */ lv_area_t res; lv_point_precise_t p[4] = { {area->x1, area->y1}, - {area->x1, area->y2}, - {area->x2, area->y1}, - {area->x2, area->y2}, + {area->x1, area->y2 + 1}, + {area->x2 + 1, area->y1}, + {area->x2 + 1, area->y2 + 1}, }; p[0] = lv_matrix_transform_precise_point(matrix, &p[0]); p[1] = lv_matrix_transform_precise_point(matrix, &p[1]); @@ -211,9 +220,9 @@ lv_area_t lv_matrix_transform_area(const lv_matrix_t * matrix, const lv_area_t * p[3] = lv_matrix_transform_precise_point(matrix, &p[3]); res.x1 = (int32_t)(LV_MIN4(p[0].x, p[1].x, p[2].x, p[3].x)); - res.x2 = (int32_t)(LV_MAX4(p[0].x, p[1].x, p[2].x, p[3].x)); + res.x2 = (int32_t)(LV_MAX4(p[0].x, p[1].x, p[2].x, p[3].x)) - 1; res.y1 = (int32_t)(LV_MIN4(p[0].y, p[1].y, p[2].y, p[3].y)); - res.y2 = (int32_t)(LV_MAX4(p[0].y, p[1].y, p[2].y, p[3].y)); + res.y2 = (int32_t)(LV_MAX4(p[0].y, p[1].y, p[2].y, p[3].y)) - 1; return res; } diff --git a/src/misc/lv_profiler_builtin.c b/src/misc/lv_profiler_builtin.c index cb1483f55c..243ec11102 100644 --- a/src/misc/lv_profiler_builtin.c +++ b/src/misc/lv_profiler_builtin.c @@ -149,7 +149,10 @@ void lv_profiler_builtin_init(const lv_profiler_builtin_config_t * config) void lv_profiler_builtin_uninit(void) { - LV_ASSERT_NULL(profiler_ctx); + if(!profiler_ctx) { + return; + } + LV_PROFILER_MULTEX_DEINIT; lv_free(profiler_ctx->item_arr); lv_free(profiler_ctx); @@ -176,10 +179,9 @@ void lv_profiler_builtin_flush(void) void lv_profiler_builtin_write(const char * func, char tag) { - LV_ASSERT_NULL(profiler_ctx); LV_ASSERT_NULL(func); - if(!profiler_ctx->enable) { + if(!(profiler_ctx && profiler_ctx->enable)) { return; } diff --git a/src/misc/lv_profiler_builtin_posix.c b/src/misc/lv_profiler_builtin_posix.c new file mode 100644 index 0000000000..ca695d384a --- /dev/null +++ b/src/misc/lv_profiler_builtin_posix.c @@ -0,0 +1,134 @@ +/** + * @file lv_profiler_builtin_posix.c + * + */ + +/********************* + * INCLUDES + *********************/ + +#include "lv_profiler_builtin_private.h" + +#if LV_USE_PROFILER && LV_USE_PROFILER_BUILTIN && LV_USE_PROFILER_BUILTIN_POSIX + +#if defined(_WIN32) + #include +#else + #include +#endif + +#include +#include + +#if defined(__linux__) + #include + #include + #include +#endif + +/********************* + * DEFINES + *********************/ + +/********************** + * TYPEDEFS + **********************/ + +/********************** + * STATIC PROTOTYPES + **********************/ + +static uint64_t tick_get_cb(void); +static void flush_cb(const char * buf); +static int tid_get_cb(void); +static int cpu_get_cb(void); + +/********************** + * STATIC VARIABLES + **********************/ + +/********************** + * MACROS + **********************/ + +/********************** + * GLOBAL FUNCTIONS + **********************/ + +void lv_profiler_builtin_posix_init(void) +{ + lv_profiler_builtin_config_t config; + lv_profiler_builtin_config_init(&config); + + /* One second is equal to 1000000000 nanoseconds */ + config.tick_per_sec = 1000000000; + config.tick_get_cb = tick_get_cb; + config.flush_cb = flush_cb; + config.tid_get_cb = tid_get_cb; + config.cpu_get_cb = cpu_get_cb; + lv_profiler_builtin_init(&config); +} + +/********************** + * STATIC FUNCTIONS + **********************/ + +static uint64_t tick_get_cb(void) +{ +#if defined(_WIN32) + static LARGE_INTEGER frequency = {0}; + LARGE_INTEGER counter; + + if(frequency.QuadPart == 0) { + if(!QueryPerformanceFrequency(&frequency)) { + fprintf(stderr, "QueryPerformanceFrequency failed\n"); + return 0; + } + } + + if(!QueryPerformanceCounter(&counter)) { + fprintf(stderr, "QueryPerformanceCounter failed\n"); + return 0; + } + + /* Convert counter to nanoseconds */ + return counter.QuadPart * 1000000000ULL / frequency.QuadPart; +#else + struct timespec ts; + clock_gettime(CLOCK_MONOTONIC, &ts); + return (uint64_t)ts.tv_sec * 1000000000ULL + (uint64_t)ts.tv_nsec; +#endif +} + +static void flush_cb(const char * buf) +{ + printf("%s", buf); +} + +static int tid_get_cb(void) +{ +#if defined(__linux__) + return (int)syscall(SYS_gettid); +#elif defined(_WIN32) + return (int)GetCurrentThreadId(); +#else + return (int)pthread_self(); +#endif +} + +static int cpu_get_cb(void) +{ +#if defined(__linux__) + unsigned cpu; + int result = syscall(SYS_getcpu, &cpu, NULL, NULL); + if(result < 0) { + fprintf(stderr, "getcpu failed\n"); + return -1; + } + return (int)cpu; +#else + return 0; +#endif +} + +#endif diff --git a/src/misc/lv_profiler_builtin_private.h b/src/misc/lv_profiler_builtin_private.h index 48bfc39dae..92c424cebd 100644 --- a/src/misc/lv_profiler_builtin_private.h +++ b/src/misc/lv_profiler_builtin_private.h @@ -43,6 +43,15 @@ struct _lv_profiler_builtin_config_t { * GLOBAL PROTOTYPES **********************/ +#if LV_USE_PROFILER_BUILTIN_POSIX + +/** + * Initialize the built-in profiler with POSIX functions. + */ +void lv_profiler_builtin_posix_init(void); + +#endif /* LV_USE_PROFILER_BUILTIN_POSIX */ + /********************** * MACROS **********************/ diff --git a/src/misc/lv_style.c b/src/misc/lv_style.c index fa77b026f7..0503712658 100644 --- a/src/misc/lv_style.c +++ b/src/misc/lv_style.c @@ -160,6 +160,7 @@ const uint8_t lv_style_builtin_prop_flag_lookup_table[LV_STYLE_NUM_BUILT_IN_PROP [LV_STYLE_GRID_CELL_X_ALIGN] = LV_STYLE_PROP_FLAG_LAYOUT_UPDATE, [LV_STYLE_GRID_CELL_Y_ALIGN] = LV_STYLE_PROP_FLAG_LAYOUT_UPDATE, #endif + [LV_STYLE_IMAGE_COLORKEY] = 0, }; @@ -210,10 +211,27 @@ void lv_style_copy(lv_style_t * dst, const lv_style_t * src) lv_style_reset(dst); + lv_style_merge(dst, src); +} + +void lv_style_merge(lv_style_t * dst, const lv_style_t * src) +{ + if(lv_style_is_const(dst)) { + LV_LOG_WARN("The destination can not be a constant style"); + return; + } + /*Source is empty*/ - if(src->values_and_props == NULL) return; - if(src->prop_cnt == 0) return; + if(src->values_and_props == NULL) { + LV_LOG_TRACE("Source style is empty"); + return; + } + if(src->prop_cnt == 0) { + LV_LOG_TRACE("Source style has no properties"); + return; + } + /* Merge the styles */ int32_t i; if(lv_style_is_const(src)) { lv_style_const_prop_t * props_and_values = (lv_style_const_prop_t *)src->values_and_props; @@ -237,11 +255,6 @@ lv_style_prop_t lv_style_register_prop(uint8_t flag) last_custom_prop_id = (uint16_t)LV_STYLE_LAST_BUILT_IN_PROP; } - // if((last_custom_prop_id + 1) != 0) { - // LV_LOG_ERROR("No more custom property IDs available"); - // return LV_STYLE_PROP_INV; - // } - /* * Allocate the lookup table if it's not yet available. */ @@ -457,6 +470,15 @@ lv_style_value_t lv_style_prop_get_default(lv_style_prop_t prop) return (lv_style_value_t) { .num = 256 }; + +#if LV_USE_GRID + case LV_STYLE_GRID_CELL_ROW_SPAN: + case LV_STYLE_GRID_CELL_COLUMN_SPAN: + return (lv_style_value_t) { + .num = 1 + }; +#endif + default: return (lv_style_value_t) { .ptr = NULL diff --git a/src/misc/lv_style.h b/src/misc/lv_style.h index 2da6cd1f8c..30c67e63fb 100644 --- a/src/misc/lv_style.h +++ b/src/misc/lv_style.h @@ -118,6 +118,14 @@ typedef enum { LV_BORDER_SIDE_INTERNAL = 0x10, /**< FOR matrix-like objects (e.g. Button matrix)*/ } lv_border_side_t; +/** A image colorkey definition. + * The transparency within the color range of [low, high] will be set to LV_OPA_TRANSP If the "enable" flag is set to true. + */ +typedef struct { + lv_color_t low; + lv_color_t high; +} lv_image_colorkey_t; + /** * A common type to handle all the property types in the same way. */ @@ -132,7 +140,7 @@ typedef union { * * Props are split into groups of 16. When adding a new prop to a group, ensure it does not overflow into the next one. */ -enum { +enum _lv_style_id_t { LV_STYLE_PROP_INV = 0, /*Group 0*/ @@ -283,8 +291,9 @@ enum { LV_STYLE_GRID_CELL_ROW_POS = 134, LV_STYLE_GRID_CELL_ROW_SPAN = 135, LV_STYLE_GRID_CELL_Y_ALIGN = 136, + LV_STYLE_IMAGE_COLORKEY = 137, - LV_STYLE_LAST_BUILT_IN_PROP = 137, + LV_STYLE_LAST_BUILT_IN_PROP = 138, LV_STYLE_NUM_BUILT_IN_PROPS = LV_STYLE_LAST_BUILT_IN_PROP + 1, @@ -363,6 +372,19 @@ void lv_style_reset(lv_style_t * style); */ void lv_style_copy(lv_style_t * dst, const lv_style_t * src); +/** + * Copy all properties of a style to an other without resetting the dst style. + * It has the same effect as calling the same `lv_set_style_...` + * functions on both styles. + * It means new memory will be allocated to store the properties in + * the destination style. + * After the copy the destination style is fully independent of the source + * and source can removed without affecting the destination style. + * @param dst the destination to copy into (cannot be a constant style) + * @param src the source style to copy from. + */ +void lv_style_merge(lv_style_t * dst, const lv_style_t * src); + /** * Check if a style is constant diff --git a/src/misc/lv_style_gen.c b/src/misc/lv_style_gen.c index cd7fe4f477..4f560d3fdc 100644 --- a/src/misc/lv_style_gen.c +++ b/src/misc/lv_style_gen.c @@ -530,6 +530,14 @@ void lv_style_set_image_recolor_opa(lv_style_t * style, lv_opa_t value) lv_style_set_prop(style, LV_STYLE_IMAGE_RECOLOR_OPA, v); } +void lv_style_set_image_colorkey(lv_style_t * style, const lv_image_colorkey_t * value) +{ + lv_style_value_t v = { + .ptr = value + }; + lv_style_set_prop(style, LV_STYLE_IMAGE_COLORKEY, v); +} + void lv_style_set_line_width(lv_style_t * style, int32_t value) { lv_style_value_t v = { diff --git a/src/misc/lv_style_gen.h b/src/misc/lv_style_gen.h index b5c030dcb9..1bbded9e7e 100644 --- a/src/misc/lv_style_gen.h +++ b/src/misc/lv_style_gen.h @@ -79,6 +79,7 @@ void lv_style_set_shadow_opa(lv_style_t * style, lv_opa_t value); void lv_style_set_image_opa(lv_style_t * style, lv_opa_t value); void lv_style_set_image_recolor(lv_style_t * style, lv_color_t value); void lv_style_set_image_recolor_opa(lv_style_t * style, lv_opa_t value); +void lv_style_set_image_colorkey(lv_style_t * style, const lv_image_colorkey_t * value); void lv_style_set_line_width(lv_style_t * style, int32_t value); void lv_style_set_line_dash_width(lv_style_t * style, int32_t value); void lv_style_set_line_dash_gap(lv_style_t * style, int32_t value); @@ -464,6 +465,11 @@ void lv_style_set_grid_cell_row_span(lv_style_t * style, int32_t value); .prop = LV_STYLE_IMAGE_RECOLOR_OPA, .value = { .num = (int32_t)val } \ } +#define LV_STYLE_CONST_IMAGE_COLORKEY(val) \ + { \ + .prop = LV_STYLE_IMAGE_COLORKEY, .value = { .ptr = val } \ + } + #define LV_STYLE_CONST_LINE_WIDTH(val) \ { \ .prop = LV_STYLE_LINE_WIDTH, .value = { .num = (int32_t)val } \ diff --git a/src/misc/lv_text.c b/src/misc/lv_text.c index de182033b1..76b94d2468 100644 --- a/src/misc/lv_text.c +++ b/src/misc/lv_text.c @@ -88,38 +88,60 @@ /********************** * GLOBAL FUNCTIONS **********************/ +void lv_text_attributes_init(lv_text_attributes_t * attributes) +{ + lv_memzero(attributes, sizeof(lv_text_attributes_t)); +} void lv_text_get_size(lv_point_t * size_res, const char * text, const lv_font_t * font, int32_t letter_space, int32_t line_space, int32_t max_width, lv_text_flag_t flag) { + lv_text_attributes_t attrs; + lv_text_attributes_init(&attrs); + attrs.line_space = line_space; + attrs.max_width = max_width; + attrs.text_flags = flag; + attrs.letter_space = letter_space; + lv_text_get_size_attributes(size_res, text, font, &attrs); +} + +void lv_text_get_size_attributes(lv_point_t * size_res, const char * text, const lv_font_t * font, + lv_text_attributes_t * attributes) +{ + uint32_t line_start = 0; + uint32_t new_line_start = 0; + uint16_t letter_height = 0; size_res->x = 0; size_res->y = 0; - if(text == NULL) return; - if(font == NULL) return; + LV_ASSERT_NULL(attributes); + LV_ASSERT_NULL(font); + LV_ASSERT_NULL(text); - if(flag & LV_TEXT_FLAG_EXPAND) max_width = LV_COORD_MAX; + letter_height = lv_font_get_line_height(font); - uint32_t line_start = 0; - uint32_t new_line_start = 0; - uint16_t letter_height = lv_font_get_line_height(font); + if(attributes->text_flags & LV_TEXT_FLAG_EXPAND) { + attributes->max_width = LV_COORD_MAX; + } /*Calc. the height and longest line*/ while(text[line_start] != '\0') { - new_line_start += lv_text_get_next_line(&text[line_start], LV_TEXT_LEN_MAX, font, letter_space, max_width, NULL, flag); + new_line_start += lv_text_get_next_line( + &text[line_start], LV_TEXT_LEN_MAX, font, NULL, attributes); - if((unsigned long)size_res->y + (unsigned long)letter_height + (unsigned long)line_space > LV_MAX_OF(int32_t)) { + if((unsigned long)size_res->y + + (unsigned long)letter_height + (unsigned long)attributes->line_space > LV_MAX_OF(int32_t)) { LV_LOG_WARN("integer overflow while calculating text height"); return; } else { size_res->y += letter_height; - size_res->y += line_space; + size_res->y += attributes->line_space; } /*Calculate the longest line*/ - int32_t act_line_length = lv_text_get_width_with_flags(&text[line_start], new_line_start - line_start, font, - letter_space, flag); + int32_t act_line_length = lv_text_get_width( + &text[line_start], new_line_start - line_start, font, attributes); size_res->x = LV_MAX(act_line_length, size_res->x); line_start = new_line_start; @@ -127,14 +149,14 @@ void lv_text_get_size(lv_point_t * size_res, const char * text, const lv_font_t /*Make the text one line taller if the last character is '\n' or '\r'*/ if((line_start != 0) && (text[line_start - 1] == '\n' || text[line_start - 1] == '\r')) { - size_res->y += letter_height + line_space; + size_res->y += letter_height + attributes->line_space; } /*Correction with the last line space or set the height manually if the text is empty*/ if(size_res->y == 0) size_res->y = letter_height; else - size_res->y -= line_space; + size_res->y -= attributes->line_space; } bool lv_text_is_cmd(lv_text_cmd_state_t * state, uint32_t c) @@ -320,9 +342,9 @@ static uint32_t lv_text_get_next_word(const char * txt, const lv_font_t * font, } uint32_t lv_text_get_next_line(const char * txt, uint32_t len, - const lv_font_t * font, int32_t letter_space, - int32_t max_width, int32_t * used_width, lv_text_flag_t flag) + const lv_font_t * font, int32_t * used_width, lv_text_attributes_t * attributes) { + if(used_width) *used_width = 0; if(txt == NULL) return 0; @@ -333,7 +355,9 @@ uint32_t lv_text_get_next_line(const char * txt, uint32_t len, /*If max_width doesn't matter simply find the new line character *without thinking about word wrapping*/ - if((flag & LV_TEXT_FLAG_EXPAND) || (flag & LV_TEXT_FLAG_FIT)) { + if((attributes->text_flags & LV_TEXT_FLAG_EXPAND) || + (attributes->text_flags & LV_TEXT_FLAG_FIT)) { + uint32_t i; for(i = 0; i < len && txt[i] != '\n' && txt[i] != '\r' && txt[i] != '\0'; i++) { /*Just find the new line chars or string ends by incrementing `i`*/ @@ -343,17 +367,22 @@ uint32_t lv_text_get_next_line(const char * txt, uint32_t len, return i; } - if(flag & LV_TEXT_FLAG_EXPAND) max_width = LV_COORD_MAX; + if(attributes->text_flags & LV_TEXT_FLAG_EXPAND) { + attributes->max_width = LV_COORD_MAX; + } lv_text_cmd_state_t cmd_state = LV_TEXT_CMD_STATE_WAIT; uint32_t i = 0; /*Iterating index into txt*/ + uint32_t max_width = attributes->max_width; while(i < len && txt[i] != '\0' && max_width > 0) { - lv_text_flag_t word_flag = flag; + lv_text_flag_t word_flag = attributes->text_flags; + if(i == 0) word_flag |= LV_TEXT_FLAG_BREAK_ALL; uint32_t word_w = 0; - uint32_t advance = lv_text_get_next_word(&txt[i], font, letter_space, max_width, word_flag, &word_w, &cmd_state); + uint32_t advance = lv_text_get_next_word(&txt[i], font, attributes->letter_space, + max_width, word_flag, &word_w, &cmd_state); max_width -= word_w; line_w += word_w; @@ -369,7 +398,6 @@ uint32_t lv_text_get_next_line(const char * txt, uint32_t len, i++; /*Include the following newline in the current line*/ break; } - } /*Always step at least one to avoid infinite loops*/ @@ -387,55 +415,26 @@ uint32_t lv_text_get_next_line(const char * txt, uint32_t len, return i; } -int32_t lv_text_get_width(const char * txt, uint32_t length, const lv_font_t * font, int32_t letter_space) +int32_t lv_text_get_width(const char * txt, uint32_t length, const lv_font_t * font, + const lv_text_attributes_t * attributes) { if(txt == NULL) return 0; if(font == NULL) return 0; if(txt[0] == '\0') return 0; - uint32_t i = 0; - int32_t width = 0; - - if(length != 0) { - while(i < length) { - uint32_t letter; - uint32_t letter_next; - lv_text_encoded_letter_next_2(txt, &letter, &letter_next, &i); - - int32_t char_width = lv_font_get_glyph_width(font, letter, letter_next); - if(char_width > 0) { - width += char_width; - width += letter_space; - } - } - - if(width > 0) { - width -= letter_space; /*Trim the last letter space. Important if the text is center - aligned*/ - } - } - - return width; -} - -int32_t lv_text_get_width_with_flags(const char * txt, uint32_t length, const lv_font_t * font, int32_t letter_space, - lv_text_flag_t flags) -{ - if(txt == NULL) return 0; - if(font == NULL) return 0; - if(txt[0] == '\0') return 0; - - uint32_t i = 0; + uint32_t i = 0; int32_t width = 0; lv_text_cmd_state_t cmd_state = LV_TEXT_CMD_STATE_WAIT; if(length != 0) { while(txt[i] != '\0' && i < length) { + uint32_t letter; uint32_t letter_next; + lv_text_encoded_letter_next_2(txt, &letter, &letter_next, &i); - if((flags & LV_TEXT_FLAG_RECOLOR) != 0) { + if((attributes->text_flags & LV_TEXT_FLAG_RECOLOR) != 0) { if(lv_text_is_cmd(&cmd_state, letter) != false) { continue; } @@ -444,12 +443,12 @@ int32_t lv_text_get_width_with_flags(const char * txt, uint32_t length, const lv int32_t char_width = lv_font_get_glyph_width(font, letter, letter_next); if(char_width > 0) { width += char_width; - width += letter_space; + width += attributes->letter_space; } } if(width > 0) { - width -= letter_space; /*Trim the last letter space. Important if the text is center + width -= attributes->letter_space; /*Trim the last letter space. Important if the text is center aligned*/ } } diff --git a/src/misc/lv_text.h b/src/misc/lv_text.h index 77b176d3e2..3792f0fc71 100644 --- a/src/misc/lv_text.h +++ b/src/misc/lv_text.h @@ -14,7 +14,6 @@ extern "C" { * INCLUDES *********************/ #include "../lv_conf_internal.h" - #include "lv_types.h" #include "lv_area.h" #include "../font/lv_font.h" @@ -23,14 +22,6 @@ extern "C" { /********************* * DEFINES *********************/ -#ifndef LV_TXT_COLOR_CMD -#define LV_TXT_COLOR_CMD "#" -#endif - -#define LV_TXT_ENC_UTF8 1 -#define LV_TXT_ENC_ASCII 2 - -#define LV_TEXT_LEN_MAX UINT32_MAX /********************** * TYPEDEFS @@ -39,16 +30,24 @@ extern "C" { /** * Options for text rendering. */ - typedef enum { LV_TEXT_FLAG_NONE = 0x00, - LV_TEXT_FLAG_EXPAND = 0x01, /**< Ignore max-width to avoid automatic word wrapping*/ - LV_TEXT_FLAG_FIT = 0x02, /**< Max-width is already equal to the longest line. (Used to skip some calculation)*/ - LV_TEXT_FLAG_BREAK_ALL = 0x04, /**< To prevent overflow, insert breaks between any two characters. - Otherwise breaks are inserted at word boundaries, as configured via LV_TXT_BREAK_CHARS - or according to LV_TXT_LINE_BREAK_LONG_LEN, LV_TXT_LINE_BREAK_LONG_PRE_MIN_LEN, - and LV_TXT_LINE_BREAK_LONG_POST_MIN_LEN.*/ - LV_TEXT_FLAG_RECOLOR = 0x08, /**< Enable parsing of recolor command*/ + + /*Ignore max-width to avoid automatic word wrapping*/ + LV_TEXT_FLAG_EXPAND = 0x01, + + /**Max-width is already equal to the longest line. (Used to skip some calculation)*/ + LV_TEXT_FLAG_FIT = 0x02, + + /**To prevent overflow, insert breaks between any two characters. + Otherwise breaks are inserted at word boundaries, as configured via LV_TXT_BREAK_CHARS + or according to LV_TXT_LINE_BREAK_LONG_LEN, LV_TXT_LINE_BREAK_LONG_PRE_MIN_LEN, + and LV_TXT_LINE_BREAK_LONG_POST_MIN_LEN.*/ + LV_TEXT_FLAG_BREAK_ALL = 0x04, + + /**Enable parsing of recolor command*/ + LV_TEXT_FLAG_RECOLOR = 0x08, + } lv_text_flag_t; /** Label align policy*/ @@ -59,13 +58,6 @@ typedef enum { LV_TEXT_ALIGN_RIGHT, /**< Align text to right*/ } lv_text_align_t; -/** State machine for text renderer. */ -typedef enum { - LV_TEXT_CMD_STATE_WAIT, /**< Waiting for command*/ - LV_TEXT_CMD_STATE_PAR, /**< Processing the parameter*/ - LV_TEXT_CMD_STATE_IN, /**< Processing the command*/ -} lv_text_cmd_state_t; - /********************** * GLOBAL PROTOTYPES **********************/ @@ -79,43 +71,10 @@ typedef enum { * @param line_space line space of the text * @param max_width max width of the text (break the lines to fit this size). Set COORD_MAX to avoid * @param flag settings for the text from ::lv_text_flag_t - - * line breaks */ void lv_text_get_size(lv_point_t * size_res, const char * text, const lv_font_t * font, int32_t letter_space, int32_t line_space, int32_t max_width, lv_text_flag_t flag); -/** - * Give the length of a text with a given font - * @param txt a '\0' terminate string - * @param length length of 'txt' in byte count and not characters (Á is 1 character but 2 bytes in - * UTF-8) - * @param font pointer to a font - * @param letter_space letter space - * @return length of a char_num long text - */ -int32_t lv_text_get_width(const char * txt, uint32_t length, const lv_font_t * font, int32_t letter_space); - -/** - * Give the length of a text with a given font with text flags - * @param txt a '\0' terminate string - * @param length length of 'txt' in byte count and not characters (Á is 1 character but 2 bytes in - * UTF-8) - * @param font pointer to a font - * @param letter_space letter space - * @param flags settings for the text from ::lv_text_flag_t - * @return length of a char_num long text - */ -int32_t lv_text_get_width_with_flags(const char * txt, uint32_t length, const lv_font_t * font, int32_t letter_space, - lv_text_flag_t flags); - -/** - * Check if c is command state - * @param state - * @param c - * @return True if c is state - */ -bool lv_text_is_cmd(lv_text_cmd_state_t * state, uint32_t c); /********************** * MACROS **********************/ diff --git a/src/misc/lv_text_private.h b/src/misc/lv_text_private.h index 3814d8a14d..a54a351bc9 100644 --- a/src/misc/lv_text_private.h +++ b/src/misc/lv_text_private.h @@ -20,30 +20,86 @@ extern "C" { * DEFINES *********************/ +#ifndef LV_TXT_COLOR_CMD +#define LV_TXT_COLOR_CMD "#" +#endif + +#define LV_TXT_ENC_UTF8 1 +#define LV_TXT_ENC_ASCII 2 + +#define LV_TEXT_LEN_MAX UINT32_MAX + /********************** * TYPEDEFS **********************/ +/** State machine for text renderer. */ +typedef enum { + LV_TEXT_CMD_STATE_WAIT, /**< Waiting for command*/ + LV_TEXT_CMD_STATE_PAR, /**< Processing the parameter*/ + LV_TEXT_CMD_STATE_IN, /**< Processing the command*/ +} lv_text_cmd_state_t; + +typedef struct { + int32_t letter_space; /**< Letter space between letters*/ + int32_t line_space; /**< Space between lines of text*/ + int32_t max_width; /**< Max width of the text (break the lines to fit this size). Set COORD_MAX to avoid*/ + lv_text_flag_t text_flags; +} lv_text_attributes_t; + + /********************** * GLOBAL PROTOTYPES **********************/ +/** + * Initialize the text attributes descriptor + * @param attributes the text attributes descriptor to initialize + */ +void lv_text_attributes_init(lv_text_attributes_t * attributes); + +/** + * Get size of a text + * @param size_res pointer to a 'point_t' variable to store the result + * @param text pointer to a text + * @param font pointer to font of the text + * @param attributes the text attributes, flags for line break behaviour, spacing etc + */ +void lv_text_get_size_attributes(lv_point_t * size_res, const char * text, const lv_font_t * font, + lv_text_attributes_t * attributes); +/** + * Give the length of a text with a given font with text flags + * @param txt a '\0' terminate string + * @param length length of 'txt' in byte count and not characters (Á is 1 character but 2 bytes in + * UTF-8) + * @param font pointer to font of the text + * @param attributes the text attributes, flags for line break behaviour, spacing etc + * @return length of a char_num long text + */ +int32_t lv_text_get_width(const char * txt, uint32_t length, const lv_font_t * font, + const lv_text_attributes_t * attributes); + +/** + * Check if c is command state + * @param state + * @param c + * @return True if c is state + */ +bool lv_text_is_cmd(lv_text_cmd_state_t * state, uint32_t c); + /** * Get the next line of text. Check line length and break chars too. * @param txt a '\0' terminated string * @param len length of 'txt' in bytes * @param font pointer to a font - * @param letter_space letter space - * @param max_width max width of the text (break the lines to fit this size). Set COORD_MAX to avoid - * line breaks * @param used_width When used_width != NULL, save the width of this line if * flag == LV_TEXT_FLAG_NONE, otherwise save -1. - * @param flag settings for the text from 'txt_flag_type' enum - * @return the index of the first char of the new line (in byte index not letter index. With UTF-8 - * they are different) + * @param attributes text attributes, flags to control line break behaviour, spacing etc + * @return the index of the first char of the new line + * (in byte index not letter index. With UTF-8 they are different) */ -uint32_t lv_text_get_next_line(const char * txt, uint32_t len, const lv_font_t * font, int32_t letter_space, - int32_t max_width, int32_t * used_width, lv_text_flag_t flag); +uint32_t lv_text_get_next_line(const char * txt, uint32_t len, const lv_font_t * font, int32_t * used_width, + lv_text_attributes_t * attributes); /** * Insert a string into another @@ -63,7 +119,7 @@ void lv_text_ins(char * txt_buf, uint32_t pos, const char * ins_txt); void lv_text_cut(char * txt, uint32_t pos, uint32_t len); /** - * return a new formatted text. Memory will be allocated to store the text. + * Return a new formatted text. Memory will be allocated to store the text. * @param fmt `printf`-like format * @param ap items to print diff --git a/src/misc/lv_timer.h b/src/misc/lv_timer.h index 063b283ef9..e7611ef0b0 100644 --- a/src/misc/lv_timer.h +++ b/src/misc/lv_timer.h @@ -98,6 +98,7 @@ void lv_timer_delete(lv_timer_t * timer); /** * Pause a timer. + * It is typically safe to call from an interrupt handler or a different thread. * @param timer pointer to an lv_timer */ void lv_timer_pause(lv_timer_t * timer); diff --git a/src/misc/lv_timer_private.h b/src/misc/lv_timer_private.h index 9f7269f584..3f7f53a545 100644 --- a/src/misc/lv_timer_private.h +++ b/src/misc/lv_timer_private.h @@ -33,7 +33,7 @@ struct _lv_timer_t { lv_timer_cb_t timer_cb; /**< Timer function */ void * user_data; /**< Custom user data */ int32_t repeat_count; /**< 1: One time; -1 : infinity; n>0: residual times */ - uint32_t paused : 1; + volatile int paused; uint32_t auto_delete : 1; }; @@ -44,7 +44,7 @@ typedef struct { uint8_t idle_last; bool timer_deleted; bool timer_created; - uint32_t timer_time_until_next; + volatile uint32_t timer_time_until_next; bool already_running; uint32_t periodic_last_tick; diff --git a/src/misc/lv_tree.h b/src/misc/lv_tree.h index cb1fda7ad5..bec73be78e 100644 --- a/src/misc/lv_tree.h +++ b/src/misc/lv_tree.h @@ -25,29 +25,33 @@ extern "C" { * TYPEDEFS **********************/ -struct _lv_tree_node_t; +typedef struct _lv_tree_class_t lv_tree_class_t; +typedef struct _lv_tree_node_t lv_tree_node_t; + +typedef void (*lv_tree_constructor_cb_t)(const lv_tree_class_t * class_p, lv_tree_node_t * node); +typedef void (*lv_tree_destructor_cb_t)(const lv_tree_class_t * class_p, lv_tree_node_t * node); /** * Describe the common methods of every object. * Similar to a C++ class. */ -typedef struct _lv_tree_class_t { - const struct _lv_tree_class_t * base_class; +struct _lv_tree_class_t { + const lv_tree_class_t * base_class; uint32_t instance_size; - void (*constructor_cb)(const struct _lv_tree_class_t * class_p, struct _lv_tree_node_t * node); - void (*destructor_cb)(const struct _lv_tree_class_t * class_p, struct _lv_tree_node_t * node); -} lv_tree_class_t; + lv_tree_constructor_cb_t constructor_cb; + lv_tree_destructor_cb_t destructor_cb; +}; /** Description of a tree node*/ -typedef struct _lv_tree_node_t { - struct _lv_tree_node_t * parent; - struct _lv_tree_node_t ** children; +struct _lv_tree_node_t { + lv_tree_node_t * parent; + lv_tree_node_t ** children; uint32_t child_cnt; uint32_t child_cap; - const struct _lv_tree_class_t * class_p; -} lv_tree_node_t; + const lv_tree_class_t * class_p; +}; -enum { +enum _lv_tree_walk_mode_t { LV_TREE_WALK_PRE_ORDER = 0, LV_TREE_WALK_POST_ORDER, }; diff --git a/src/misc/lv_types.h b/src/misc/lv_types.h index 0df7500fa8..7b00fbf5d1 100644 --- a/src/misc/lv_types.h +++ b/src/misc/lv_types.h @@ -104,8 +104,7 @@ typedef unsigned int lv_3dtexture_id_t; typedef struct _lv_obj_t lv_obj_t; -typedef uint16_t lv_state_t; -typedef uint32_t lv_part_t; +typedef lv_obj_t * (*lv_screen_create_cb_t)(void); typedef uint8_t lv_opa_t; @@ -131,6 +130,8 @@ typedef struct _lv_theme_t lv_theme_t; typedef struct _lv_anim_t lv_anim_t; +typedef struct _lv_anim_timeline_t lv_anim_timeline_t; + typedef struct _lv_font_t lv_font_t; typedef struct _lv_font_class_t lv_font_class_t; typedef struct _lv_font_info_t lv_font_info_t; @@ -163,8 +164,6 @@ typedef struct _lv_cache_entry_t lv_cache_entry_t; typedef struct _lv_fs_file_cache_t lv_fs_file_cache_t; -typedef struct _lv_fs_path_ex_t lv_fs_path_ex_t; - typedef struct _lv_image_decoder_args_t lv_image_decoder_args_t; typedef struct _lv_image_cache_data_t lv_image_cache_data_t; @@ -277,8 +276,14 @@ typedef struct _lv_win_t lv_win_t; typedef struct _lv_3dtexture_t lv_3dtexture_t; +typedef struct _lv_gltf_t lv_gltf_t; + +typedef struct _lv_gltf_model_t lv_gltf_model_t; + typedef struct _lv_observer_t lv_observer_t; +typedef struct _lv_subject_increment_dsc_t lv_subject_increment_dsc_t; + typedef struct _lv_monkey_config_t lv_monkey_config_t; typedef struct _lv_ime_pinyin_t lv_ime_pinyin_t; @@ -287,8 +292,6 @@ typedef struct _lv_file_explorer_t lv_file_explorer_t; typedef struct _lv_barcode_t lv_barcode_t; -typedef struct _lv_gif_t lv_gif_t; - typedef struct _lv_qrcode_t lv_qrcode_t; typedef struct _lv_freetype_outline_vector_t lv_freetype_outline_vector_t; @@ -307,11 +310,9 @@ typedef struct _lv_vector_fill_dsc_t lv_vector_fill_dsc_t; typedef struct _lv_vector_stroke_dsc_t lv_vector_stroke_dsc_t; -typedef struct _lv_vector_draw_dsc_t lv_vector_draw_dsc_t; - -typedef struct _lv_draw_vector_task_dsc_t lv_draw_vector_task_dsc_t; +typedef struct _lv_vector_path_ctx_t lv_vector_path_ctx_t; -typedef struct _lv_vector_dsc_t lv_vector_dsc_t; +typedef struct _lv_draw_vector_dsc_t lv_draw_vector_dsc_t; typedef struct _lv_xkb_t lv_xkb_t; @@ -345,8 +346,8 @@ typedef struct _lv_rlottie_t lv_rlottie_t; typedef struct _lv_ffmpeg_player_t lv_ffmpeg_player_t; -typedef struct _lv_glfw_window_t lv_glfw_window_t; -typedef struct _lv_glfw_texture_t lv_glfw_texture_t; +typedef struct _lv_opengles_window_t lv_opengles_window_t; +typedef struct _lv_opengles_window_texture_t lv_opengles_window_texture_t; typedef uint32_t lv_prop_id_t; @@ -377,10 +378,22 @@ typedef struct _lv_xml_component_scope_t lv_xml_component_scope_t; typedef struct _lv_xml_parser_state_t lv_xml_parser_state_t; +typedef struct _lv_xml_load_t lv_xml_load_t; + #if LV_USE_EVDEV typedef struct _lv_evdev_discovery_t lv_evdev_discovery_t; #endif +#if LV_USE_TRANSLATION +typedef struct _lv_translation_tag_dsc_t lv_translation_tag_dsc_t; + +typedef struct _lv_translation_pack_t lv_translation_pack_t; +#endif + +#if LV_USE_DRAW_EVE +typedef struct _lv_draw_eve_unit_t lv_draw_eve_unit_t; +#endif + #endif /*__ASSEMBLY__*/ /********************** @@ -411,6 +424,28 @@ typedef struct _lv_evdev_discovery_t lv_evdev_discovery_t; #define LV_FORMAT_ATTRIBUTE(fmtstr, vararg) #endif +#ifndef LV_NORETURN +#if defined(PYCPARSER) +#define LV_NORETURN +#elif defined(__GNUC__) +#define LV_NORETURN __attribute__((noreturn)) +#elif defined(_MSC_VER) +#define LV_NORETURN __declspec(noreturn) +#else +#define LV_NORETURN +#endif +#endif /* LV_NORETURN not defined */ + +#ifndef LV_UNREACHABLE +#if defined(__GNUC__) +#define LV_UNREACHABLE() __builtin_unreachable() +#elif defined(_MSC_VER) +#define LV_UNREACHABLE() __assume(0) +#else +#define LV_UNREACHABLE() while(1) +#endif +#endif /* LV_UNREACHABLE not defined */ + #ifdef __cplusplus } /*extern "C"*/ #endif diff --git a/src/osal/lv_cmsis_rtos2.c b/src/osal/lv_cmsis_rtos2.c index d2f89430bc..7eb898315a 100644 --- a/src/osal/lv_cmsis_rtos2.c +++ b/src/osal/lv_cmsis_rtos2.c @@ -12,7 +12,7 @@ /********************* * INCLUDES *********************/ -#include "lv_os.h" +#include "lv_os_private.h" #if LV_USE_OS == LV_OS_CMSIS_RTOS2 @@ -196,6 +196,10 @@ uint32_t lv_os_get_idle_percent(void) return lv_timer_get_idle(); } +void lv_sleep_ms(uint32_t ms) +{ + osDelay(ms); +} /********************** * STATIC FUNCTIONS **********************/ diff --git a/src/osal/lv_cmsis_rtos2.h b/src/osal/lv_cmsis_rtos2.h index 62481e7e81..ae4f94f0ae 100644 --- a/src/osal/lv_cmsis_rtos2.h +++ b/src/osal/lv_cmsis_rtos2.h @@ -50,4 +50,4 @@ typedef osEventFlagsId_t lv_thread_sync_t; } /*extern "C"*/ #endif -#endif /*LV_OS_CMSIS_RTOS2*/ +#endif /*LV_CMSIS_RTOS2_H*/ diff --git a/src/osal/lv_freertos.c b/src/osal/lv_freertos.c index c1eeccdf0d..a8545c1007 100644 --- a/src/osal/lv_freertos.c +++ b/src/osal/lv_freertos.c @@ -12,7 +12,7 @@ /********************* * INCLUDES *********************/ -#include "lv_os.h" +#include "lv_os_private.h" #if LV_USE_OS == LV_OS_FREERTOS #include "atomic.h" @@ -419,6 +419,11 @@ uint32_t lv_os_get_idle_percent(void) return pct; } +void lv_sleep_ms(uint32_t ms) +{ + vTaskDelay(ms / portTICK_PERIOD_MS); +} + /********************** * STATIC FUNCTIONS **********************/ diff --git a/src/osal/lv_freertos.h b/src/osal/lv_freertos.h index a3bafca74e..96196b7434 100644 --- a/src/osal/lv_freertos.h +++ b/src/osal/lv_freertos.h @@ -19,7 +19,7 @@ extern "C" { /********************* * INCLUDES *********************/ -#include "lv_os.h" +#include "lv_os_private.h" #if LV_USE_OS == LV_OS_FREERTOS diff --git a/src/osal/lv_linux.c b/src/osal/lv_linux.c index baec0aa540..99ea96d2fc 100644 --- a/src/osal/lv_linux.c +++ b/src/osal/lv_linux.c @@ -7,26 +7,33 @@ * INCLUDES *********************/ -#include "lv_os.h" +#include "lv_os_private.h" -#if LV_USE_OS != LV_OS_NONE && defined(__linux__) +#if defined(__linux__) #include "../core/lv_global.h" #include "../misc/lv_log.h" -#include "lv_linux_private.h" +#include "lv_linux.h" #include +#include /********************* * DEFINES *********************/ -#define LV_UPTIME_MONITOR_FILE "/proc/stat" +#define LV_UPTIME_MONITOR_FILE "/proc/stat" +#define LV_UPTIME_MONITOR_SELF_FILE "/proc/self/stat" #define LV_PROC_STAT_VAR_FORMAT " %" PRIu32 #define LV_PROC_STAT_IGNORE_VAR_FORMAT " %*" PRIu32 #define last_proc_stat LV_GLOBAL_DEFAULT()->linux_last_proc_stat +#if LV_SYSMON_PROC_IDLE_AVAILABLE + #define last_self_ticks LV_GLOBAL_DEFAULT()->linux_last_self_proc_time_ticks + #define last_system_total_ticks_stat LV_GLOBAL_DEFAULT()->linux_last_system_total_ticks_stat +#endif +#define LV_SELF_PROC_STAT_BUFFER_SIZE 512 /********************** * TYPEDEFS **********************/ @@ -35,8 +42,8 @@ * STATIC PROTOTYPES **********************/ -static lv_result_t lv_read_proc_stat(lv_proc_stat_t * result); -static uint32_t lv_proc_stat_get_total(const lv_proc_stat_t * p); +static lv_result_t lv_read_proc_stat(lv_linux_proc_stat_t * result); +static uint32_t lv_proc_stat_get_total(const lv_linux_proc_stat_t * p); /********************** * STATIC VARIABLES @@ -52,7 +59,7 @@ static uint32_t lv_proc_stat_get_total(const lv_proc_stat_t * p); uint32_t lv_os_get_idle_percent(void) { - lv_proc_stat_t proc_stat; + lv_linux_proc_stat_t proc_stat; { lv_result_t err = lv_read_proc_stat(&proc_stat); @@ -80,11 +87,101 @@ uint32_t lv_os_get_idle_percent(void) return (proc_stat.fields.idle * 100) / total; } +#if LV_SYSMON_PROC_IDLE_AVAILABLE + +uint32_t lv_os_get_proc_idle_percent(void) +{ + uint64_t self_current_time_ticks = 0; + lv_linux_proc_stat_t stat_current_system_total_ticks; + lv_linux_proc_stat_t stat_delta_system_ticks; + + FILE * self = fopen(LV_UPTIME_MONITOR_SELF_FILE, "r"); + if(!self) { + LV_LOG_ERROR("Failed to open " LV_UPTIME_MONITOR_SELF_FILE); + return UINT32_MAX; + } + + char self_stat_buffer[LV_SELF_PROC_STAT_BUFFER_SIZE]; + + if(!fgets(self_stat_buffer, sizeof(self_stat_buffer), self)) { + fclose(self); + LV_LOG_ERROR("Failed to read " LV_UPTIME_MONITOR_SELF_FILE); + return UINT32_MAX; + } + + fclose(self); + + /* The comm field can contain spaces and parentheses, so we find the last ')' + * Skip the whitespace after finding the last ')' */ + char * p = strrchr(self_stat_buffer, ')'); + if(!p) { + LV_LOG_ERROR(LV_UPTIME_MONITOR_SELF_FILE " is missing the closing ')'"); + return UINT32_MAX; + } + p++; /* move past the ')' */ + while(*p && (*p == ' ' || *p == '\t')) + p++; /* skip whitespace after ')' */ + if(!*p) { + LV_LOG_ERROR(LV_UPTIME_MONITOR_SELF_FILE " unexpectedly ends after the closing ')'"); + return UINT32_MAX; + } + + uint64_t utime = 0; + uint64_t stime = 0; + + int scanned_items = sscanf(p, + "%*c " // state (field 3) + "%*d %*d %*d %*d %*d " // ppid, pgrp, session, tty_nr, tpgid (fields 4-8) + "%*u " // flags (field 9) + "%*u %*u %*u %*u " // minflt, cminflt, majflt, cmajflt (fields 10-13) + "%" SCNu64 " %" SCNu64, // utime, stime (fields 14-15) + &utime, &stime); + + if(scanned_items != 2) { + LV_LOG_ERROR("Failed to parse utime/stime"); + return UINT32_MAX; + } + + self_current_time_ticks = utime + stime; + + if(lv_read_proc_stat(&stat_current_system_total_ticks) != LV_RESULT_OK) { + LV_LOG_ERROR("lv_read_proc_stat failed"); + return UINT32_MAX; + } + + /* no delta on the first call so return 0, next call will have actual values*/ + if(last_self_ticks == 0) { + last_self_ticks = self_current_time_ticks; + last_system_total_ticks_stat = stat_current_system_total_ticks; + + return 100; /* 100% idle = 0% CPU usage*/ + } + + uint64_t delta_self_proc_ticks = self_current_time_ticks - last_self_ticks; + + for(size_t i = 0; i < LV_PROC_STAT_PARAMS_LEN; ++i) { + stat_delta_system_ticks.buffer[i] = stat_current_system_total_ticks.buffer[i] - last_system_total_ticks_stat.buffer[i]; + } + + uint64_t delta_total_system_ticks = lv_proc_stat_get_total(&stat_delta_system_ticks); + + last_self_ticks = self_current_time_ticks; + last_system_total_ticks_stat = stat_current_system_total_ticks; + + if(delta_total_system_ticks == 0) return 100; + + uint32_t cpu_usage_percent = (uint32_t)((delta_self_proc_ticks * 100ULL) / delta_total_system_ticks); + + return 100 - cpu_usage_percent; +} + +#endif /*LV_SYSMON_PROC_IDLE_AVAILABLE*/ + /********************** * STATIC FUNCTIONS **********************/ -static lv_result_t lv_read_proc_stat(lv_proc_stat_t * result) +static lv_result_t lv_read_proc_stat(lv_linux_proc_stat_t * result) { FILE * fp = fopen(LV_UPTIME_MONITOR_FILE, "r"); @@ -110,7 +207,8 @@ static lv_result_t lv_read_proc_stat(lv_proc_stat_t * result) } return LV_RESULT_OK; } -static uint32_t lv_proc_stat_get_total(const lv_proc_stat_t * p) + +static uint32_t lv_proc_stat_get_total(const lv_linux_proc_stat_t * p) { uint32_t sum = 0; for(size_t i = 0; i < LV_PROC_STAT_PARAMS_LEN; ++i) { diff --git a/src/osal/lv_linux_private.h b/src/osal/lv_linux.h similarity index 84% rename from src/osal/lv_linux_private.h rename to src/osal/lv_linux.h index d6e43cbf7e..a94e64bc32 100644 --- a/src/osal/lv_linux_private.h +++ b/src/osal/lv_linux.h @@ -1,11 +1,10 @@ - /** - * @file lv_linux_private.h + * @file lv_linux.h * */ -#ifndef LV_LINUX_PRIVATE_H -#define LV_LINUX_PRIVATE_H +#ifndef LV_LINUX_H +#define LV_LINUX_H #ifdef __cplusplus extern "C" { @@ -15,8 +14,8 @@ extern "C" { * INCLUDES *********************/ -#include "../misc/lv_types.h" - +#include "lv_os.h" +#ifdef __linux__ /********************* * DEFINES *********************/ @@ -27,7 +26,6 @@ extern "C" { * TYPEDEFS **********************/ - typedef union { struct { /* @@ -39,7 +37,7 @@ typedef union { steal /*, guest, guest_nice*/; } fields; uint32_t buffer[LV_PROC_STAT_PARAMS_LEN]; -} lv_proc_stat_t; +} lv_linux_proc_stat_t; /********************** * GLOBAL PROTOTYPES @@ -49,8 +47,10 @@ typedef union { * MACROS **********************/ +#endif /*__linux__*/ + #ifdef __cplusplus } /*extern "C"*/ #endif -#endif /*LV_LINUX_PRIVATE_H*/ +#endif /*LV_LINUX_H*/ diff --git a/src/osal/lv_mqx.c b/src/osal/lv_mqx.c index ffcf16332d..3b2442f4ab 100644 --- a/src/osal/lv_mqx.c +++ b/src/osal/lv_mqx.c @@ -6,7 +6,7 @@ /********************* * INCLUDES *********************/ -#include "lv_os.h" +#include "lv_os_private.h" #if LV_USE_OS == LV_OS_MQX @@ -169,6 +169,11 @@ uint32_t lv_os_get_idle_percent(void) return lv_timer_get_idle(); } +void lv_sleep_ms(uint32_t ms) +{ + _time_delay(ms); +} + /********************** * STATIC FUNCTIONS **********************/ diff --git a/src/osal/lv_mqx.h b/src/osal/lv_mqx.h index 601f596a4b..1ccd0091d7 100644 --- a/src/osal/lv_mqx.h +++ b/src/osal/lv_mqx.h @@ -13,7 +13,7 @@ extern "C" { /********************* * INCLUDES *********************/ -#include "lv_os.h" +#include "lv_os_private.h" #if LV_USE_OS == LV_OS_MQX diff --git a/src/osal/lv_os.c b/src/osal/lv_os.c index 64ef4b5d10..c8142a6d36 100644 --- a/src/osal/lv_os.c +++ b/src/osal/lv_os.c @@ -6,9 +6,9 @@ /********************* * INCLUDES *********************/ -#include "lv_os.h" #include "lv_os_private.h" #include "../core/lv_global.h" +#include "../tick/lv_tick.h" /********************* * DEFINES @@ -39,29 +39,42 @@ void lv_os_init(void) { #if LV_USE_OS != LV_OS_NONE lv_mutex_init(&lv_general_mutex); -#endif /*LV_USE_OS != LV_OS_NONE*/ +#endif } -#if LV_USE_OS != LV_OS_NONE void lv_lock(void) { +#if LV_USE_OS != LV_OS_NONE lv_mutex_lock(&lv_general_mutex); +#endif } lv_result_t lv_lock_isr(void) { +#if LV_USE_OS != LV_OS_NONE return lv_mutex_lock_isr(&lv_general_mutex); +#else + return LV_RESULT_OK; +#endif } void lv_unlock(void) { +#if LV_USE_OS != LV_OS_NONE lv_mutex_unlock(&lv_general_mutex); +#endif +} + +#if LV_USE_OS == LV_OS_NONE +void lv_sleep_ms(uint32_t ms) +{ + lv_delay_ms(ms); } +#endif /********************** * STATIC FUNCTIONS **********************/ -#endif /*LV_USE_OS != LV_OS_NONE*/ diff --git a/src/osal/lv_os.h b/src/osal/lv_os.h index 47fd80108d..eaa20e9337 100644 --- a/src/osal/lv_os.h +++ b/src/osal/lv_os.h @@ -17,30 +17,8 @@ extern "C" { /********************* * INCLUDES *********************/ -#include "../lv_conf_internal.h" - #include "../misc/lv_types.h" -#if LV_USE_OS == LV_OS_NONE -#include "lv_os_none.h" -#elif LV_USE_OS == LV_OS_PTHREAD -#include "lv_pthread.h" -#elif LV_USE_OS == LV_OS_FREERTOS -#include "lv_freertos.h" -#elif LV_USE_OS == LV_OS_CMSIS_RTOS2 -#include "lv_cmsis_rtos2.h" -#elif LV_USE_OS == LV_OS_RTTHREAD -#include "lv_rtthread.h" -#elif LV_USE_OS == LV_OS_WINDOWS -#include "lv_windows.h" -#elif LV_USE_OS == LV_OS_MQX -#include "lv_mqx.h" -#elif LV_USE_OS == LV_OS_SDL2 -#include "lv_sdl2.h" -#elif LV_USE_OS == LV_OS_CUSTOM -#include LV_OS_CUSTOM_INCLUDE -#endif - /********************* * DEFINES *********************/ @@ -48,122 +26,11 @@ extern "C" { /********************** * TYPEDEFS **********************/ -typedef enum { - LV_THREAD_PRIO_LOWEST, - LV_THREAD_PRIO_LOW, - LV_THREAD_PRIO_MID, - LV_THREAD_PRIO_HIGH, - LV_THREAD_PRIO_HIGHEST, -} lv_thread_prio_t; /********************** * GLOBAL PROTOTYPES **********************/ -/** - * Set it for `LV_SYSMON_GET_IDLE` to show the CPU usage - * @return the idle percentage since the last call - */ -uint32_t lv_os_get_idle_percent(void); - -#if LV_USE_OS != LV_OS_NONE - -/*---------------------------------------- - * These functions needs to be implemented - * for specific operating systems - *---------------------------------------*/ - -/** - * Create a new thread - * @param thread a variable in which the thread will be stored - * @param name the name of the thread - * @param prio priority of the thread - * @param callback function of the thread - * @param stack_size stack size in bytes - * @param user_data arbitrary data, will be available in the callback - * @return LV_RESULT_OK: success; LV_RESULT_INVALID: failure - */ -lv_result_t lv_thread_init(lv_thread_t * thread, const char * const name, - lv_thread_prio_t prio, void (*callback)(void *), size_t stack_size, - void * user_data); - -/** - * Delete a thread - * @param thread the thread to delete - * @return LV_RESULT_OK: success; LV_RESULT_INVALID: failure - */ -lv_result_t lv_thread_delete(lv_thread_t * thread); - -/** - * Create a mutex - * @param mutex a variable in which the thread will be stored - * @return LV_RESULT_OK: success; LV_RESULT_INVALID: failure - */ -lv_result_t lv_mutex_init(lv_mutex_t * mutex); - -/** - * Lock a mutex - * @param mutex the mutex to lock - * @return LV_RESULT_OK: success; LV_RESULT_INVALID: failure - */ -lv_result_t lv_mutex_lock(lv_mutex_t * mutex); - -/** - * Lock a mutex from interrupt - * @param mutex the mutex to lock - * @return LV_RESULT_OK: success; LV_RESULT_INVALID: failure - */ -lv_result_t lv_mutex_lock_isr(lv_mutex_t * mutex); - -/** - * Unlock a mutex - * @param mutex the mutex to unlock - * @return LV_RESULT_OK: success; LV_RESULT_INVALID: failure - */ -lv_result_t lv_mutex_unlock(lv_mutex_t * mutex); - -/** - * Delete a mutex - * @param mutex the mutex to delete - * @return LV_RESULT_OK: success; LV_RESULT_INVALID: failure - */ -lv_result_t lv_mutex_delete(lv_mutex_t * mutex); - -/** - * Create a thread synchronization object - * @param sync a variable in which the sync will be stored - * @return LV_RESULT_OK: success; LV_RESULT_INVALID: failure - */ -lv_result_t lv_thread_sync_init(lv_thread_sync_t * sync); - -/** - * Wait for a "signal" on a sync object - * @param sync a sync object - * @return LV_RESULT_OK: success; LV_RESULT_INVALID: failure - */ -lv_result_t lv_thread_sync_wait(lv_thread_sync_t * sync); - -/** - * Send a wake-up signal to a sync object - * @param sync a sync object - * @return LV_RESULT_OK: success; LV_RESULT_INVALID: failure - */ -lv_result_t lv_thread_sync_signal(lv_thread_sync_t * sync); - -/** - * Send a wake-up signal to a sync object from interrupt - * @param sync a sync object - * @return LV_RESULT_OK: success; LV_RESULT_INVALID: failure - */ -lv_result_t lv_thread_sync_signal_isr(lv_thread_sync_t * sync); - -/** - * Delete a sync object - * @param sync a sync object to delete - * @return LV_RESULT_OK: success; LV_RESULT_INVALID: failure - */ -lv_result_t lv_thread_sync_delete(lv_thread_sync_t * sync); - /** * Lock LVGL's general mutex. * LVGL is not thread safe, so a mutex is used to avoid executing multiple LVGL functions at the same time @@ -187,108 +54,11 @@ lv_result_t lv_lock_isr(void); */ void lv_unlock(void); -#else - -/* Since compilation does not necessarily optimize cross-file empty functions well - * (-O3 optimization alone is not enough unless LTO optimization is enabled), - * In the absence of an operating system, use inline functions to help compile - * optimizations and avoid the call overhead of the OS API to ensure no performance penalty. +/** + * Sleeps the current thread by an amount of milliseconds. + * @param ms amount of milliseconds to sleep the current thread. */ - -static inline lv_result_t lv_thread_init(lv_thread_t * thread, const char * const name, lv_thread_prio_t prio, - void (*callback)(void *), size_t stack_size, void * user_data) -{ - LV_UNUSED(thread); - LV_UNUSED(name); - LV_UNUSED(callback); - LV_UNUSED(prio); - LV_UNUSED(stack_size); - LV_UNUSED(user_data); - return LV_RESULT_INVALID; -} - -static inline lv_result_t lv_thread_delete(lv_thread_t * thread) -{ - LV_UNUSED(thread); - return LV_RESULT_INVALID; -} - -static inline lv_result_t lv_mutex_init(lv_mutex_t * mutex) -{ - LV_UNUSED(mutex); - return LV_RESULT_OK; -} - -static inline lv_result_t lv_mutex_lock(lv_mutex_t * mutex) -{ - LV_UNUSED(mutex); - return LV_RESULT_OK; -} - -static inline lv_result_t lv_mutex_lock_isr(lv_mutex_t * mutex) -{ - LV_UNUSED(mutex); - return LV_RESULT_OK; -} - -static inline lv_result_t lv_mutex_unlock(lv_mutex_t * mutex) -{ - LV_UNUSED(mutex); - return LV_RESULT_OK; -} - -static inline lv_result_t lv_mutex_delete(lv_mutex_t * mutex) -{ - LV_UNUSED(mutex); - return LV_RESULT_OK; -} - -static inline lv_result_t lv_thread_sync_init(lv_thread_sync_t * sync) -{ - LV_UNUSED(sync); - return LV_RESULT_INVALID; -} - -static inline lv_result_t lv_thread_sync_wait(lv_thread_sync_t * sync) -{ - LV_UNUSED(sync); - return LV_RESULT_INVALID; -} - -static inline lv_result_t lv_thread_sync_signal(lv_thread_sync_t * sync) -{ - LV_UNUSED(sync); - return LV_RESULT_INVALID; -} - -static inline lv_result_t lv_thread_sync_signal_isr(lv_thread_sync_t * sync) -{ - LV_UNUSED(sync); - return LV_RESULT_INVALID; -} - -static inline lv_result_t lv_thread_sync_delete(lv_thread_sync_t * sync) -{ - LV_UNUSED(sync); - return LV_RESULT_INVALID; -} - -static inline void lv_lock(void) -{ - /*Do nothing*/ -} - -static inline lv_result_t lv_lock_isr(void) -{ - return LV_RESULT_OK; -} - -static inline void lv_unlock(void) -{ - /*Do nothing*/ -} - -#endif /*LV_USE_OS != LV_OS_NONE*/ +void lv_sleep_ms(uint32_t ms); /********************** * MACROS diff --git a/src/osal/lv_os_none.c b/src/osal/lv_os_none.c index 9fe3cac635..71fb2bb9a0 100644 --- a/src/osal/lv_os_none.c +++ b/src/osal/lv_os_none.c @@ -10,7 +10,7 @@ #include "../lv_conf_internal.h" #if LV_USE_OS == LV_OS_NONE -#include "lv_os.h" +#include "lv_os_private.h" #include "../misc/lv_timer.h" /********************* @@ -37,10 +37,12 @@ * GLOBAL FUNCTIONS **********************/ +#ifndef __linux__ uint32_t lv_os_get_idle_percent(void) { return lv_timer_get_idle(); } +#endif /*__linux__*/ /********************** * STATIC FUNCTIONS diff --git a/src/osal/lv_os_private.h b/src/osal/lv_os_private.h index 4fe08cd2fd..029e90c258 100644 --- a/src/osal/lv_os_private.h +++ b/src/osal/lv_os_private.h @@ -17,6 +17,34 @@ extern "C" { /********************* * INCLUDES *********************/ +#include "../lv_conf_internal.h" + +#include "lv_os.h" +#include "../misc/lv_types.h" + +#ifdef __linux__ +#include "lv_linux.h" +#endif + +#if LV_USE_OS == LV_OS_NONE +#include "lv_os_none.h" +#elif LV_USE_OS == LV_OS_PTHREAD +#include "lv_pthread.h" +#elif LV_USE_OS == LV_OS_FREERTOS +#include "lv_freertos.h" +#elif LV_USE_OS == LV_OS_CMSIS_RTOS2 +#include "lv_cmsis_rtos2.h" +#elif LV_USE_OS == LV_OS_RTTHREAD +#include "lv_rtthread.h" +#elif LV_USE_OS == LV_OS_WINDOWS +#include "lv_windows.h" +#elif LV_USE_OS == LV_OS_MQX +#include "lv_mqx.h" +#elif LV_USE_OS == LV_OS_SDL2 +#include "lv_sdl2.h" +#elif LV_USE_OS == LV_OS_CUSTOM +#include LV_OS_CUSTOM_INCLUDE +#endif /********************* * DEFINES @@ -25,6 +53,13 @@ extern "C" { /********************** * TYPEDEFS **********************/ +typedef enum { + LV_THREAD_PRIO_LOWEST, + LV_THREAD_PRIO_LOW, + LV_THREAD_PRIO_MID, + LV_THREAD_PRIO_HIGH, + LV_THREAD_PRIO_HIGHEST, +} lv_thread_prio_t; /********************** * GLOBAL PROTOTYPES @@ -35,6 +70,203 @@ extern "C" { */ void lv_os_init(void); +/** + * Set it for `LV_SYSMON_GET_IDLE` to show the CPU usage + * @return the idle percentage since the last call + */ +uint32_t lv_os_get_idle_percent(void); + +#if LV_SYSMON_PROC_IDLE_AVAILABLE + +uint32_t lv_os_get_proc_idle_percent(void); + +#endif + +#if LV_USE_OS != LV_OS_NONE + +/*---------------------------------------- + * These functions needs to be implemented + * for specific operating systems + *---------------------------------------*/ + +/** + * Create a new thread + * @param thread a variable in which the thread will be stored + * @param name the name of the thread + * @param prio priority of the thread + * @param callback function of the thread + * @param stack_size stack size in bytes + * @param user_data arbitrary data, will be available in the callback + * @return LV_RESULT_OK: success; LV_RESULT_INVALID: failure + */ +lv_result_t lv_thread_init(lv_thread_t * thread, const char * const name, + lv_thread_prio_t prio, void (*callback)(void *), size_t stack_size, + void * user_data); + +/** + * Delete a thread + * @param thread the thread to delete + * @return LV_RESULT_OK: success; LV_RESULT_INVALID: failure + */ +lv_result_t lv_thread_delete(lv_thread_t * thread); + +/** + * Create a mutex + * @param mutex a variable in which the thread will be stored + * @return LV_RESULT_OK: success; LV_RESULT_INVALID: failure + */ +lv_result_t lv_mutex_init(lv_mutex_t * mutex); + +/** + * Lock a mutex + * @param mutex the mutex to lock + * @return LV_RESULT_OK: success; LV_RESULT_INVALID: failure + */ +lv_result_t lv_mutex_lock(lv_mutex_t * mutex); + +/** + * Lock a mutex from interrupt + * @param mutex the mutex to lock + * @return LV_RESULT_OK: success; LV_RESULT_INVALID: failure + */ +lv_result_t lv_mutex_lock_isr(lv_mutex_t * mutex); + +/** + * Unlock a mutex + * @param mutex the mutex to unlock + * @return LV_RESULT_OK: success; LV_RESULT_INVALID: failure + */ +lv_result_t lv_mutex_unlock(lv_mutex_t * mutex); + +/** + * Delete a mutex + * @param mutex the mutex to delete + * @return LV_RESULT_OK: success; LV_RESULT_INVALID: failure + */ +lv_result_t lv_mutex_delete(lv_mutex_t * mutex); + +/** + * Create a thread synchronization object + * @param sync a variable in which the sync will be stored + * @return LV_RESULT_OK: success; LV_RESULT_INVALID: failure + */ +lv_result_t lv_thread_sync_init(lv_thread_sync_t * sync); + +/** + * Wait for a "signal" on a sync object + * @param sync a sync object + * @return LV_RESULT_OK: success; LV_RESULT_INVALID: failure + */ +lv_result_t lv_thread_sync_wait(lv_thread_sync_t * sync); + +/** + * Send a wake-up signal to a sync object + * @param sync a sync object + * @return LV_RESULT_OK: success; LV_RESULT_INVALID: failure + */ +lv_result_t lv_thread_sync_signal(lv_thread_sync_t * sync); + +/** + * Send a wake-up signal to a sync object from interrupt + * @param sync a sync object + * @return LV_RESULT_OK: success; LV_RESULT_INVALID: failure + */ +lv_result_t lv_thread_sync_signal_isr(lv_thread_sync_t * sync); + +/** + * Delete a sync object + * @param sync a sync object to delete + * @return LV_RESULT_OK: success; LV_RESULT_INVALID: failure + */ +lv_result_t lv_thread_sync_delete(lv_thread_sync_t * sync); + +#else + +/* Since compilation does not necessarily optimize cross-file empty functions well + * (-O3 optimization alone is not enough unless LTO optimization is enabled), + * In the absence of an operating system, use inline functions to help compile + * optimizations and avoid the call overhead of the OS API to ensure no performance penalty. + */ + +static inline lv_result_t lv_thread_init(lv_thread_t * thread, const char * const name, lv_thread_prio_t prio, + void (*callback)(void *), size_t stack_size, void * user_data) +{ + LV_UNUSED(thread); + LV_UNUSED(name); + LV_UNUSED(callback); + LV_UNUSED(prio); + LV_UNUSED(stack_size); + LV_UNUSED(user_data); + return LV_RESULT_INVALID; +} + +static inline lv_result_t lv_thread_delete(lv_thread_t * thread) +{ + LV_UNUSED(thread); + return LV_RESULT_INVALID; +} + +static inline lv_result_t lv_mutex_init(lv_mutex_t * mutex) +{ + LV_UNUSED(mutex); + return LV_RESULT_OK; +} + +static inline lv_result_t lv_mutex_lock(lv_mutex_t * mutex) +{ + LV_UNUSED(mutex); + return LV_RESULT_OK; +} + +static inline lv_result_t lv_mutex_lock_isr(lv_mutex_t * mutex) +{ + LV_UNUSED(mutex); + return LV_RESULT_OK; +} + +static inline lv_result_t lv_mutex_unlock(lv_mutex_t * mutex) +{ + LV_UNUSED(mutex); + return LV_RESULT_OK; +} + +static inline lv_result_t lv_mutex_delete(lv_mutex_t * mutex) +{ + LV_UNUSED(mutex); + return LV_RESULT_OK; +} + +static inline lv_result_t lv_thread_sync_init(lv_thread_sync_t * sync) +{ + LV_UNUSED(sync); + return LV_RESULT_INVALID; +} + +static inline lv_result_t lv_thread_sync_wait(lv_thread_sync_t * sync) +{ + LV_UNUSED(sync); + return LV_RESULT_INVALID; +} + +static inline lv_result_t lv_thread_sync_signal(lv_thread_sync_t * sync) +{ + LV_UNUSED(sync); + return LV_RESULT_INVALID; +} + +static inline lv_result_t lv_thread_sync_signal_isr(lv_thread_sync_t * sync) +{ + LV_UNUSED(sync); + return LV_RESULT_INVALID; +} + +static inline lv_result_t lv_thread_sync_delete(lv_thread_sync_t * sync) +{ + LV_UNUSED(sync); + return LV_RESULT_INVALID; +} + +#endif /*LV_USE_OS != LV_OS_NONE*/ /********************** * MACROS diff --git a/src/osal/lv_pthread.c b/src/osal/lv_pthread.c index 52bd236dee..6bec2c77fa 100644 --- a/src/osal/lv_pthread.c +++ b/src/osal/lv_pthread.c @@ -6,7 +6,7 @@ /********************* * INCLUDES *********************/ -#include "lv_os.h" +#include "lv_os_private.h" #if LV_USE_OS == LV_OS_PTHREAD @@ -178,6 +178,11 @@ uint32_t lv_os_get_idle_percent(void) } #endif +void lv_sleep_ms(uint32_t ms) +{ + /* Just call standard posix sleep function */ + usleep(ms * 1000); +} /********************** * STATIC FUNCTIONS diff --git a/src/osal/lv_pthread.h b/src/osal/lv_pthread.h index e7abc90cf1..b0c921587b 100644 --- a/src/osal/lv_pthread.h +++ b/src/osal/lv_pthread.h @@ -15,6 +15,7 @@ extern "C" { *********************/ #if LV_USE_OS == LV_OS_PTHREAD +#include #include #include #include diff --git a/src/osal/lv_rtthread.c b/src/osal/lv_rtthread.c index 1f2f9d80e2..9608ee24e3 100644 --- a/src/osal/lv_rtthread.c +++ b/src/osal/lv_rtthread.c @@ -6,7 +6,7 @@ /********************* * INCLUDES *********************/ -#include "lv_os.h" +#include "lv_os_private.h" #if LV_USE_OS == LV_OS_RTTHREAD @@ -190,6 +190,11 @@ uint32_t lv_os_get_idle_percent(void) return lv_timer_get_idle(); } +void lv_sleep_ms(uint32_t ms) +{ + rt_thread_mdelay(ms); +} + /********************** * STATIC FUNCTIONS **********************/ diff --git a/src/osal/lv_sdl2.c b/src/osal/lv_sdl2.c index 50a589a015..a5ba0bedb3 100644 --- a/src/osal/lv_sdl2.c +++ b/src/osal/lv_sdl2.c @@ -6,7 +6,7 @@ /********************* * INCLUDES *********************/ -#include "lv_os.h" +#include "lv_os_private.h" #if LV_USE_OS == LV_OS_SDL2 @@ -180,6 +180,11 @@ uint32_t lv_os_get_idle_percent(void) } #endif +void lv_sleep_ms(uint32_t ms) +{ + SDL_Delay(ms); +} + /********************** * STATIC FUNCTIONS **********************/ diff --git a/src/osal/lv_windows.c b/src/osal/lv_windows.c index 8b28ab18a4..c28bc07970 100644 --- a/src/osal/lv_windows.c +++ b/src/osal/lv_windows.c @@ -7,7 +7,7 @@ * INCLUDES *********************/ -#include "lv_os.h" +#include "lv_os_private.h" #if LV_USE_OS == LV_OS_WINDOWS @@ -212,6 +212,11 @@ uint32_t lv_os_get_idle_percent(void) return lv_timer_get_idle(); } +void lv_sleep_ms(uint32_t ms) +{ + Sleep(ms); +} + /********************** * STATIC FUNCTIONS **********************/ diff --git a/src/others/file_explorer/lv_file_explorer.c b/src/others/file_explorer/lv_file_explorer.c index 0563aaeef9..c86b305f28 100644 --- a/src/others/file_explorer/lv_file_explorer.c +++ b/src/others/file_explorer/lv_file_explorer.c @@ -9,7 +9,7 @@ #include "lv_file_explorer_private.h" #include "../../misc/lv_fs_private.h" #include "../../core/lv_obj_class_private.h" -#if LV_USE_FILE_EXPLORER != 0 +#if LV_USE_FILE_EXPLORER #include "../../lvgl.h" #include "../../core/lv_global.h" @@ -22,11 +22,12 @@ #define FILE_EXPLORER_QUICK_ACCESS_AREA_WIDTH (22) #define FILE_EXPLORER_BROWSER_AREA_WIDTH (100 - FILE_EXPLORER_QUICK_ACCESS_AREA_WIDTH) -#define quick_access_list_button_style (LV_GLOBAL_DEFAULT()->fe_list_button_style) - #define LV_FILE_NAVIGATION_CURRENT_DIR "." #define LV_FILE_NAVIGATION_PARENT_DIR "Back" +#define quick_access_style (LV_GLOBAL_DEFAULT()->file_explorer_quick_access_style) +#define file_explorer_count (LV_GLOBAL_DEFAULT()->file_explorer_count) + /********************** * TYPEDEFS **********************/ @@ -35,6 +36,7 @@ * STATIC PROTOTYPES **********************/ static void lv_file_explorer_constructor(const lv_obj_class_t * class_p, lv_obj_t * obj); +static void lv_file_explorer_destructor(const lv_obj_class_t * class_p, lv_obj_t * obj); static void init_style(lv_obj_t * obj); #if LV_FILE_EXPLORER_QUICK_ACCESS @@ -49,13 +51,16 @@ static void exch_table_item(lv_obj_t * tb, int16_t i, int16_t j); static void file_explorer_sort(lv_obj_t * obj); static void sort_by_file_kind(lv_obj_t * tb, int16_t lo, int16_t hi); static bool is_end_with(const char * str1, const char * str2); +static void clear_table_cells_user_data(lv_file_explorer_t * explorer); /********************** * STATIC VARIABLES **********************/ + const lv_obj_class_t lv_file_explorer_class = { .constructor_cb = lv_file_explorer_constructor, + .destructor_cb = lv_file_explorer_destructor, .width_def = LV_SIZE_CONTENT, .height_def = LV_SIZE_CONTENT, .instance_size = sizeof(lv_file_explorer_t), @@ -337,9 +342,20 @@ static void lv_file_explorer_constructor(const lv_obj_class_t * class_p, lv_obj_ /*Initialize style*/ init_style(obj); + file_explorer_count++; LV_TRACE_OBJ_CREATE("finished"); } +static void lv_file_explorer_destructor(const lv_obj_class_t * class_p, lv_obj_t * obj) +{ + LV_UNUSED(class_p); + LV_UNUSED(obj); + file_explorer_count--; + if(LV_FILE_EXPLORER_QUICK_ACCESS && file_explorer_count == 0) { + lv_style_reset(&quick_access_style); + } +} + static void init_style(lv_obj_t * obj) { lv_file_explorer_t * explorer = (lv_file_explorer_t *)obj; @@ -402,9 +418,11 @@ static void init_style(lv_obj_t * obj) lv_obj_set_style_pad_all(explorer->list_places, 0, 0); /*Style of the quick access list btn in the quick access bar*/ - lv_style_init(&quick_access_list_button_style); - lv_style_set_border_width(&quick_access_list_button_style, 0); - lv_style_set_bg_color(&quick_access_list_button_style, lv_color_hex(0xf2f1f6)); + if(file_explorer_count == 0) { + lv_style_init(&quick_access_style); + lv_style_set_border_width(&quick_access_style, 0); + lv_style_set_bg_color(&quick_access_style, lv_color_hex(0xf2f1f6)); + } uint32_t ch_cnt = lv_obj_get_child_count(explorer->quick_access_area); @@ -417,7 +435,7 @@ static void init_style(lv_obj_t * obj) for(uint32_t j = 0; j < list_ch_cnt; j++) { lv_obj_t * list_child = lv_obj_get_child(child, j); if(lv_obj_check_type(list_child, &lv_list_button_class)) { - lv_obj_add_style(list_child, &quick_access_list_button_style, 0); + lv_obj_add_style(list_child, &quick_access_style, 0); } } } @@ -561,6 +579,22 @@ static void browser_file_event_handler(lv_event_t * e) else if(code == LV_EVENT_SIZE_CHANGED) { lv_table_set_column_width(explorer->file_table, 0, lv_obj_get_width(explorer->file_table)); } + else if(code == LV_EVENT_DELETE) { + clear_table_cells_user_data(explorer); + } +} + +static void clear_table_cells_user_data(lv_file_explorer_t * explorer) +{ + const uint32_t row_count = lv_table_get_row_count(explorer->file_table); + const uint32_t col_count = lv_table_get_column_count(explorer->file_table); + + for(uint32_t i = 0; i < row_count; ++i) { + for(uint32_t j = 0; j < col_count; ++j) { + void * file_entry = lv_table_get_cell_user_data(explorer->file_table, i, j); + lv_free(file_entry); + } + } } static void show_dir(lv_obj_t * obj, const char * path) @@ -579,6 +613,7 @@ static void show_dir(lv_obj_t * obj, const char * path) return; } + clear_table_cells_user_data(explorer); lv_table_set_cell_value(explorer->file_table, index++, 0, LV_SYMBOL_LEFT " " LV_FILE_NAVIGATION_PARENT_DIR); file_entry_user_data = lv_malloc(sizeof(lv_file_explorer_file_table_entry_data_t)); LV_ASSERT_MALLOC(file_entry_user_data); @@ -648,8 +683,11 @@ static void show_dir(lv_obj_t * obj, const char * path) lv_label_set_text_fmt(explorer->path_label, LV_SYMBOL_EYE_OPEN" %s", path); size_t current_path_len = lv_strlen(explorer->current_path); - if((explorer->current_path[current_path_len - 1] != '/') && (current_path_len < LV_FILE_EXPLORER_PATH_MAX_LEN)) { - *((explorer->current_path) + current_path_len) = '/'; + if(current_path_len > 0 && + explorer->current_path[current_path_len - 1] != '/' && + current_path_len + 1 < sizeof(explorer->current_path)) { + explorer->current_path[current_path_len] = '/'; + explorer->current_path[current_path_len + 1] = '\0'; } } @@ -678,25 +716,14 @@ static void exch_table_item(lv_obj_t * tb, int16_t i, int16_t j) char * tmp_i_value = lv_malloc(lv_strlen(i_value) + 1); LV_ASSERT_MALLOC(tmp_i_value); lv_strcpy(tmp_i_value, i_value); - - //*Will be freed when the table is freed. The previous user data is freed when the new one is set*/ - lv_file_explorer_file_table_entry_data_t * tmp_i_user_data = lv_malloc(sizeof( - lv_file_explorer_file_table_entry_data_t)); - LV_ASSERT_MALLOC(tmp_i_user_data); - lv_memcpy(tmp_i_user_data, lv_table_get_cell_user_data(tb, i, 0), sizeof(lv_file_explorer_file_table_entry_data_t)); - - lv_file_explorer_file_table_entry_data_t * tmp_j_user_data = lv_malloc(sizeof( - lv_file_explorer_file_table_entry_data_t)); - LV_ASSERT_MALLOC(tmp_j_user_data); - lv_memcpy(tmp_j_user_data, lv_table_get_cell_user_data(tb, j, 0), sizeof(lv_file_explorer_file_table_entry_data_t)); - lv_table_set_cell_value(tb, i, 0, lv_table_get_cell_value(tb, j, 0)); - lv_table_set_cell_user_data(tb, i, 0, tmp_j_user_data); - lv_table_set_cell_value(tb, j, 0, tmp_i_value); - lv_table_set_cell_user_data(tb, j, 0, tmp_i_user_data); - lv_free(tmp_i_value); + + void * old_i_data = lv_table_get_cell_user_data(tb, i, 0); + void * old_j_data = lv_table_get_cell_user_data(tb, j, 0); + lv_table_set_cell_user_data(tb, j, 0, old_i_data); + lv_table_set_cell_user_data(tb, i, 0, old_j_data); } static void file_explorer_sort(lv_obj_t * obj) diff --git a/src/others/font_manager/lv_font_manager.c b/src/others/font_manager/lv_font_manager.c index 525b5a09be..4913d752d2 100755 --- a/src/others/font_manager/lv_font_manager.c +++ b/src/others/font_manager/lv_font_manager.c @@ -61,6 +61,7 @@ typedef struct _lv_font_src_t { static lv_font_src_t * lv_font_manager_get_src(lv_font_manager_t * manager, const char * name); +static bool lv_font_manager_check_src_resource(lv_font_manager_t * manager, const char * name); static bool lv_font_manager_check_resource(lv_font_manager_t * manager); static lv_font_rec_node_t * lv_font_manager_search_rec_node(lv_font_manager_t * manager, lv_font_t * font); @@ -165,6 +166,13 @@ bool lv_font_manager_remove_src(lv_font_manager_t * manager, const char * name) return false; } + if(lv_font_manager_check_src_resource(manager, name)) { + LV_LOG_ERROR("unfreed resource for font name %s detected, remove src failed!", name); + return false; + } + + lv_font_recycle_remove_fonts(manager->recycle_manager, name); + lv_ll_remove(&manager->src_ll, font_src); if(!font_src->is_static) { @@ -446,7 +454,7 @@ static bool lv_font_manager_check_resource(lv_font_manager_t * manager) } } - /* Check the recorded font resources created by font creater */ + /* Check the recorded font resources created by font creator */ lv_ll_t * refer_ll = &manager->refer_ll; uint32_t refer_ll_len = lv_ll_get_len(refer_ll); if(refer_ll_len) { @@ -467,6 +475,30 @@ static bool lv_font_manager_check_resource(lv_font_manager_t * manager) return has_resource; } +static bool lv_font_manager_check_src_resource(lv_font_manager_t * manager, const char * name) +{ + LV_ASSERT_NULL(manager); + LV_ASSERT_NULL(name); + + bool has_resource = false; + lv_ll_t * refer_ll = &manager->refer_ll; + uint32_t refer_ll_len = lv_ll_get_len(refer_ll); + if(refer_ll_len) { + lv_font_refer_node_t * node; + LV_LL_READ(refer_ll, node) { + if(lv_strcmp(name, node->name) == 0) { + has_resource = true; + LV_LOG_WARN("font: %s(%d), ref_cnt = %d", + node->ft_info.name, + node->ft_info.size, + node->ref_cnt); + } + } + } + + return has_resource; +} + static lv_font_rec_node_t * lv_font_manager_search_rec_node(lv_font_manager_t * manager, lv_font_t * font) { LV_ASSERT_NULL(manager); @@ -533,7 +565,7 @@ static lv_font_t * lv_font_manager_create_font_wrapper(lv_font_manager_t * manag return font; } -static void lv_font_manager_delete_font_warpper(lv_font_manager_t * manager, lv_font_refer_node_t * refer_node) +static void lv_font_manager_delete_font_wrapper(lv_font_manager_t * manager, lv_font_refer_node_t * refer_node) { LV_ASSERT_NULL(manager); LV_ASSERT_NULL(refer_node); @@ -606,7 +638,7 @@ static bool lv_font_manager_drop_font(lv_font_manager_t * manager, const lv_font } /* if ref_cnt is about to be 0, free font resource */ - lv_font_manager_delete_font_warpper(manager, refer_node); + lv_font_manager_delete_font_wrapper(manager, refer_node); /* free refer_node */ lv_ll_remove(&manager->refer_ll, refer_node); diff --git a/src/others/font_manager/lv_font_manager.h b/src/others/font_manager/lv_font_manager.h index 5ba4ccc3e3..e4e1b7628d 100755 --- a/src/others/font_manager/lv_font_manager.h +++ b/src/others/font_manager/lv_font_manager.h @@ -112,4 +112,4 @@ void lv_font_manager_delete_font(lv_font_manager_t * manager, lv_font_t * font); } /* extern "C" */ #endif -#endif /* FONT_MANAGER_MANAGER_H */ +#endif /* LV_FONT_MANAGER_H */ diff --git a/src/others/font_manager/lv_font_manager_recycle.c b/src/others/font_manager/lv_font_manager_recycle.c index 87bafd90d6..9e56430e6e 100755 --- a/src/others/font_manager/lv_font_manager_recycle.c +++ b/src/others/font_manager/lv_font_manager_recycle.c @@ -145,6 +145,22 @@ void lv_font_manager_recycle_set_reuse(lv_font_manager_recycle_t * manager, lv_f LV_LOG_INFO("insert font: %s(%d) to reuse list", ft_info->name, ft_info->size); } +void lv_font_recycle_remove_fonts(lv_font_manager_recycle_t * manager, const char * name) +{ + LV_ASSERT_NULL(manager); + LV_ASSERT_NULL(name); + + lv_font_recycle_t * next; + lv_font_recycle_t * recycle = lv_ll_get_head(&manager->recycle_ll); + while(recycle != NULL) { + next = lv_ll_get_next(&manager->recycle_ll, recycle); + if(lv_strcmp(recycle->name, name) == 0) { + lv_font_recycle_close(manager, recycle); + } + recycle = next; + } +} + /********************** * STATIC FUNCTIONS **********************/ diff --git a/src/others/font_manager/lv_font_manager_recycle.h b/src/others/font_manager/lv_font_manager_recycle.h index 58eb89474c..596e829c39 100755 --- a/src/others/font_manager/lv_font_manager_recycle.h +++ b/src/others/font_manager/lv_font_manager_recycle.h @@ -65,6 +65,13 @@ lv_font_t * lv_font_manager_recycle_get_reuse(lv_font_manager_recycle_t * manage void lv_font_manager_recycle_set_reuse(lv_font_manager_recycle_t * manager, lv_font_t * font, const lv_font_info_t * ft_info); +/** + * Remove fonts with name from recycle manager. + * @param manager pointer to font recycle manager. + * @param name font name. + */ +void lv_font_recycle_remove_fonts(lv_font_manager_recycle_t * manager, const char * name); + /********************** * MACROS **********************/ diff --git a/src/others/gridnav/lv_gridnav.c b/src/others/gridnav/lv_gridnav.c index 5f348af58c..4458fce757 100644 --- a/src/others/gridnav/lv_gridnav.c +++ b/src/others/gridnav/lv_gridnav.c @@ -118,7 +118,7 @@ void lv_gridnav_set_focused(lv_obj_t * cont, lv_obj_t * to_focus, lv_anim_enable lv_obj_remove_state(dsc->focused_obj, LV_STATE_FOCUSED | LV_STATE_FOCUS_KEY); } - lv_obj_add_state(to_focus, LV_STATE_FOCUSED | LV_STATE_FOCUS_KEY); + lv_obj_add_state(to_focus, (lv_state_t)(LV_STATE_FOCUSED | LV_STATE_FOCUS_KEY)); lv_obj_scroll_to_view(to_focus, anim_en); dsc->focused_obj = to_focus; @@ -231,7 +231,7 @@ static void gridnav_event_cb(lv_event_t * e) if(guess && guess != dsc->focused_obj) { lv_obj_remove_state(dsc->focused_obj, LV_STATE_FOCUSED | LV_STATE_FOCUS_KEY); lv_obj_send_event(dsc->focused_obj, LV_EVENT_DEFOCUSED, lv_indev_active()); - lv_obj_add_state(guess, LV_STATE_FOCUSED | LV_STATE_FOCUS_KEY); + lv_obj_add_state(guess, (lv_state_t)(LV_STATE_FOCUSED | LV_STATE_FOCUS_KEY)); lv_obj_send_event(guess, LV_EVENT_FOCUSED, lv_indev_active()); lv_obj_scroll_to_view(guess, LV_ANIM_ON); dsc->focused_obj = guess; @@ -240,7 +240,7 @@ static void gridnav_event_cb(lv_event_t * e) else if(code == LV_EVENT_FOCUSED) { if(dsc->focused_obj == NULL) dsc->focused_obj = find_first_focusable(obj); if(dsc->focused_obj) { - lv_obj_add_state(dsc->focused_obj, LV_STATE_FOCUSED | LV_STATE_FOCUS_KEY); + lv_obj_add_state(dsc->focused_obj, (lv_state_t)(LV_STATE_FOCUSED | LV_STATE_FOCUS_KEY)); lv_obj_remove_state(dsc->focused_obj, LV_STATE_PRESSED); /*Be sure the focuses obj is not stuck in pressed state*/ lv_obj_scroll_to_view(dsc->focused_obj, LV_ANIM_OFF); } @@ -256,7 +256,7 @@ static void gridnav_event_cb(lv_event_t * e) if(dsc->focused_obj == NULL) { dsc->focused_obj = child; if(lv_obj_has_state(obj, LV_STATE_FOCUSED)) { - lv_obj_add_state(child, LV_STATE_FOCUSED | LV_STATE_FOCUS_KEY); + lv_obj_add_state(child, (lv_state_t)(LV_STATE_FOCUSED | LV_STATE_FOCUS_KEY)); lv_obj_scroll_to_view(child, LV_ANIM_OFF); } } diff --git a/src/others/ime/lv_ime_pinyin.h b/src/others/ime/lv_ime_pinyin.h index ff85eee889..0509b21272 100644 --- a/src/others/ime/lv_ime_pinyin.h +++ b/src/others/ime/lv_ime_pinyin.h @@ -118,4 +118,4 @@ const lv_pinyin_dict_t * lv_ime_pinyin_get_dict(lv_obj_t * obj); } /*extern "C"*/ #endif -#endif /*LV_USE_IME_PINYIN*/ +#endif /*LV_IME_PINYIN_H*/ diff --git a/src/others/monkey/lv_monkey.h b/src/others/monkey/lv_monkey.h index f86f991b9e..12886f943e 100644 --- a/src/others/monkey/lv_monkey.h +++ b/src/others/monkey/lv_monkey.h @@ -27,21 +27,25 @@ extern "C" { typedef struct _lv_monkey_t lv_monkey_t; +typedef struct { + int32_t min; + int32_t max; +} lv_range_t; + +typedef struct { + uint32_t min; + uint32_t max; +} lv_urange_t; + struct _lv_monkey_config_t { /** Input device type */ lv_indev_type_t type; /** Monkey execution period */ - struct { - uint32_t min; - uint32_t max; - } period_range; + lv_urange_t period_range; /** The range of input value */ - struct { - int32_t min; - int32_t max; - } input_range; + lv_range_t input_range; }; /********************** diff --git a/src/others/observer/lv_observer.c b/src/others/observer/lv_observer.c index 2603561a90..955a661a0c 100644 --- a/src/others/observer/lv_observer.c +++ b/src/others/observer/lv_observer.c @@ -18,6 +18,10 @@ * DEFINES *********************/ +#ifndef FLT_MAX + #define FLT_MAX 3.402823466e+38F /* float max value */ +#endif + /********************** * TYPEDEFS **********************/ @@ -34,42 +38,53 @@ typedef struct { flag_cond_t cond : 3; } flag_and_cond_t; +typedef struct { + const lv_style_t * style; + lv_style_selector_t selector; + int32_t value; +} bind_style_t; + +typedef struct { + lv_subject_t * subject; + int32_t value; +} subject_set_int_user_data_t; + +typedef struct { + lv_subject_t * subject; + float value; +} subject_set_float_user_data_t; + +typedef struct { + lv_subject_t * subject; + const char * value; +} subject_set_string_user_data_t; + /********************** * STATIC PROTOTYPES **********************/ + +static void subject_toggle_cb(lv_event_t * e); +static void subject_set_int_cb(lv_event_t * e); +#if LV_USE_FLOAT + static void subject_set_float_cb(lv_event_t * e); +#endif + +static void subject_set_string_cb(lv_event_t * e); +static void subject_increment_cb(lv_event_t * e); + static void unsubscribe_on_delete_cb(lv_event_t * e); static void group_notify_cb(lv_observer_t * observer, lv_subject_t * subject); static lv_observer_t * bind_to_bitfield(lv_subject_t * subject, lv_obj_t * obj, lv_observer_cb_t cb, uint32_t flag, int32_t ref_value, bool inv, flag_cond_t cond); + +static void bind_style_observer_cb(lv_observer_t * observer, lv_subject_t * subject); static void obj_flag_observer_cb(lv_observer_t * observer, lv_subject_t * subject); static void obj_state_observer_cb(lv_observer_t * observer, lv_subject_t * subject); static void obj_value_changed_event_cb(lv_event_t * e); static void lv_subject_notify_if_changed(lv_subject_t * subject); -#if LV_USE_LABEL - static void label_text_observer_cb(lv_observer_t * observer, lv_subject_t * subject); -#endif - -#if LV_USE_ARC - static void arc_value_changed_event_cb(lv_event_t * e); - static void arc_value_observer_cb(lv_observer_t * observer, lv_subject_t * subject); -#endif - -#if LV_USE_SLIDER - static void slider_value_changed_event_cb(lv_event_t * e); - static void slider_value_observer_cb(lv_observer_t * observer, lv_subject_t * subject); -#endif - -#if LV_USE_ROLLER - static void roller_value_changed_event_cb(lv_event_t * e); - static void roller_value_observer_cb(lv_observer_t * observer, lv_subject_t * subject); -#endif - -#if LV_USE_DROPDOWN - static void dropdown_value_changed_event_cb(lv_event_t * e); - static void dropdown_value_observer_cb(lv_observer_t * observer, lv_subject_t * subject); -#endif +static void subject_set_string_free_user_data_event_cb(lv_event_t * e); /********************** * STATIC VARIABLES @@ -89,6 +104,8 @@ void lv_subject_init_int(lv_subject_t * subject, int32_t value) subject->type = LV_SUBJECT_TYPE_INT; subject->value.num = value; subject->prev_value.num = value; + subject->min_value.num = INT32_MIN; + subject->max_value.num = INT32_MAX; lv_ll_init(&(subject->subs_ll), sizeof(lv_observer_t)); } @@ -99,6 +116,8 @@ void lv_subject_set_int(lv_subject_t * subject, int32_t value) return; } + value = LV_CLAMP(subject->min_value.num, value, subject->max_value.num); + subject->prev_value.num = subject->value.num; subject->value.num = value; lv_subject_notify_if_changed(subject); @@ -124,6 +143,96 @@ int32_t lv_subject_get_previous_int(lv_subject_t * subject) return subject->prev_value.num; } +void lv_subject_set_min_value_int(lv_subject_t * subject, int32_t min_value) +{ + if(subject->type != LV_SUBJECT_TYPE_INT) { + LV_LOG_WARN("Subject type is not LV_SUBJECT_TYPE_INT"); + return; + } + + subject->min_value.num = min_value; +} + +void lv_subject_set_max_value_int(lv_subject_t * subject, int32_t max_value) +{ + if(subject->type != LV_SUBJECT_TYPE_INT) { + LV_LOG_WARN("Subject type is not LV_SUBJECT_TYPE_INT"); + return; + } + + subject->max_value.num = max_value; +} + +#if LV_USE_FLOAT + +void lv_subject_init_float(lv_subject_t * subject, float value) +{ + lv_memzero(subject, sizeof(lv_subject_t)); + subject->type = LV_SUBJECT_TYPE_FLOAT; + subject->value.float_v = value; + subject->prev_value.float_v = value; + subject->min_value.float_v = -FLT_MAX; + subject->max_value.float_v = FLT_MAX; + lv_ll_init(&(subject->subs_ll), sizeof(lv_observer_t)); +} + +void lv_subject_set_float(lv_subject_t * subject, float value) +{ + if(subject->type != LV_SUBJECT_TYPE_FLOAT) { + LV_LOG_WARN("Subject type is not LV_SUBJECT_TYPE_FLOAT"); + return; + } + + value = LV_CLAMP(subject->min_value.float_v, value, subject->max_value.float_v); + + subject->prev_value.float_v = subject->value.float_v; + subject->value.float_v = value; + lv_subject_notify_if_changed(subject); +} + +float lv_subject_get_float(lv_subject_t * subject) +{ + if(subject->type != LV_SUBJECT_TYPE_FLOAT) { + LV_LOG_WARN("Subject type is not LV_SUBJECT_TYPE_FLOAT"); + return 0; + } + + return subject->value.float_v; +} + +float lv_subject_get_previous_float(lv_subject_t * subject) +{ + if(subject->type != LV_SUBJECT_TYPE_FLOAT) { + LV_LOG_WARN("Subject type is not LV_SUBJECT_TYPE_FLOAT"); + return 0; + } + + return subject->prev_value.float_v; +} + +void lv_subject_set_min_value_float(lv_subject_t * subject, float min_value) +{ + if(subject->type != LV_SUBJECT_TYPE_FLOAT) { + LV_LOG_WARN("Subject type is not LV_SUBJECT_TYPE_FLOAT"); + return; + } + + subject->min_value.float_v = min_value; +} + +void lv_subject_set_max_value_float(lv_subject_t * subject, float max_value) +{ + if(subject->type != LV_SUBJECT_TYPE_FLOAT) { + LV_LOG_WARN("Subject type is not LV_SUBJECT_TYPE_FLOAT"); + return; + } + + subject->max_value.float_v = max_value; +} + + +#endif /*LV_USE_FLOAT*/ + void lv_subject_init_string(lv_subject_t * subject, char * buf, char * prev_buf, size_t size, const char * value) { lv_memzero(subject, sizeof(lv_subject_t)); @@ -461,6 +570,199 @@ void lv_subject_notify(lv_subject_t * subject) } while(subject->notify_restart_query); } +lv_subject_increment_dsc_t * lv_obj_add_subject_increment_event(lv_obj_t * obj, lv_subject_t * subject, + lv_event_code_t trigger, int32_t step) +{ + if(subject->type != LV_SUBJECT_TYPE_INT && subject->type != LV_SUBJECT_TYPE_FLOAT) { + LV_LOG_WARN("Subject type must be `int` or `float` (was %d)", subject->type); + return NULL; + } + + lv_subject_increment_dsc_t * user_data = lv_malloc(sizeof(lv_subject_increment_dsc_t)); + if(user_data == NULL) { + LV_ASSERT_MALLOC(user_data); + LV_LOG_WARN("Couldn't allocate user_data in in "); + return NULL; + } + + user_data->step = step; + user_data->subject = subject; + user_data->rollover = false; + user_data->min_value = INT32_MIN; + user_data->max_value = INT32_MAX; + lv_obj_add_event_cb(obj, subject_increment_cb, trigger, user_data); + lv_obj_add_event_cb(obj, lv_event_free_user_data_cb, LV_EVENT_DELETE, user_data); + + return user_data; +} + +void lv_obj_set_subject_increment_event_min_value(lv_obj_t * obj, lv_subject_increment_dsc_t * dsc, int32_t min_value) +{ + LV_UNUSED(obj); + LV_ASSERT_NULL(dsc); + if(dsc == NULL) { + LV_LOG_WARN("Invalid parameters"); + return; + } + + dsc->min_value = min_value; + if(dsc->subject->type == LV_SUBJECT_TYPE_INT) { + if(dsc->subject->value.num < min_value) { + lv_subject_set_int(dsc->subject, min_value); + } + } +#if LV_USE_FLOAT + else if(dsc->subject->type == LV_SUBJECT_TYPE_FLOAT) { + if(dsc->subject->value.float_v < (float)min_value) { + lv_subject_set_float(dsc->subject, (float)min_value); + } + } +#endif +} + +void lv_obj_set_subject_increment_event_max_value(lv_obj_t * obj, lv_subject_increment_dsc_t * dsc, int32_t max_value) +{ + LV_UNUSED(obj); + LV_ASSERT_NULL(dsc); + if(dsc == NULL) { + LV_LOG_WARN("Invalid parameters"); + return; + } + + + dsc->max_value = max_value; + if(dsc->subject->type == LV_SUBJECT_TYPE_INT) { + if(dsc->subject->value.num > max_value) { + lv_subject_set_int(dsc->subject, max_value); + } + } +#if LV_USE_FLOAT + else if(dsc->subject->type == LV_SUBJECT_TYPE_FLOAT) { + if(dsc->subject->value.float_v > (float)max_value) { + lv_subject_set_float(dsc->subject, (float)max_value); + } + } +#endif +} + +void lv_obj_set_subject_increment_event_rollover(lv_obj_t * obj, lv_subject_increment_dsc_t * dsc, bool rollover) +{ + LV_UNUSED(obj); + LV_ASSERT_NULL(dsc); + if(dsc == NULL) { + LV_LOG_WARN("Invalid parameters"); + return; + } + + dsc->rollover = rollover; +} + +void lv_obj_add_subject_toggle_event(lv_obj_t * obj, lv_subject_t * subject, lv_event_code_t trigger) +{ + if(subject->type != LV_SUBJECT_TYPE_INT) { + LV_LOG_WARN("Subject type must be `int` (was %d)", subject->type); + return; + } + lv_obj_add_event_cb(obj, subject_toggle_cb, trigger, subject); +} + +void lv_obj_add_subject_set_int_event(lv_obj_t * obj, lv_subject_t * subject, lv_event_code_t trigger, int32_t value) +{ + if(subject->type != LV_SUBJECT_TYPE_INT) { + LV_LOG_WARN("Subject type must be `int` (was %d)", subject->type); + return; + } + + subject_set_int_user_data_t * user_data = lv_malloc(sizeof(subject_set_int_user_data_t)); + if(user_data == NULL) { + LV_ASSERT_MALLOC(user_data); + LV_LOG_WARN("Couldn't allocate user_data"); + return; + } + + user_data->subject = subject; + user_data->value = value; + + lv_obj_add_event_cb(obj, subject_set_int_cb, trigger, user_data); + lv_obj_add_event_cb(obj, lv_event_free_user_data_cb, LV_EVENT_DELETE, user_data); +} + +#if LV_USE_FLOAT +void lv_obj_add_subject_set_float_event(lv_obj_t * obj, lv_subject_t * subject, lv_event_code_t trigger, float value) +{ + if(subject->type != LV_SUBJECT_TYPE_FLOAT) { + LV_LOG_WARN("Subject type must be `float` (was %d)", subject->type); + return; + } + + subject_set_float_user_data_t * user_data = lv_malloc(sizeof(subject_set_float_user_data_t)); + if(user_data == NULL) { + LV_ASSERT_MALLOC(user_data); + LV_LOG_WARN("Couldn't allocate user_data"); + return; + } + + user_data->subject = subject; + user_data->value = value; + + lv_obj_add_event_cb(obj, subject_set_float_cb, trigger, user_data); + lv_obj_add_event_cb(obj, lv_event_free_user_data_cb, LV_EVENT_DELETE, user_data); +} +#endif /*LV_USE_FLOAT*/ + +void lv_obj_add_subject_set_string_event(lv_obj_t * obj, lv_subject_t * subject, lv_event_code_t trigger, + const char * value) +{ + + if(subject->type != LV_SUBJECT_TYPE_STRING) { + LV_LOG_WARN("Subject type must be `string` (was %d)", subject->type); + return; + } + + subject_set_string_user_data_t * user_data = lv_malloc(sizeof(subject_set_int_user_data_t)); + if(user_data == NULL) { + LV_ASSERT_MALLOC(user_data); + LV_LOG_WARN("Couldn't allocate user_data"); + return; + } + + user_data->subject = subject; + user_data->value = lv_strdup(value); + LV_ASSERT_MALLOC(user_data->value); + + lv_obj_add_event_cb(obj, subject_set_string_cb, trigger, user_data); + lv_obj_add_event_cb(obj, subject_set_string_free_user_data_event_cb, LV_EVENT_DELETE, user_data); +} + +lv_observer_t * lv_obj_bind_style(lv_obj_t * obj, const lv_style_t * style, lv_style_selector_t selector, + lv_subject_t * subject, int32_t ref_value) +{ + LV_ASSERT_NULL(subject); + LV_ASSERT_NULL(obj); + + if(subject->type != LV_SUBJECT_TYPE_INT) { + LV_LOG_WARN("Subject type must be `int` (was %d)", subject->type); + return NULL; + } + + lv_obj_add_style(obj, style, selector); + + bind_style_t * p = lv_malloc(sizeof(bind_style_t)); + LV_ASSERT_MALLOC(p); + if(p == NULL) { + LV_LOG_WARN("Out of memory"); + return NULL; + } + + p->style = style; + p->selector = selector; + p->value = ref_value; + + lv_observer_t * observable = lv_subject_add_observer_obj(subject, bind_style_observer_cb, obj, p); + observable->auto_free_user_data = 1; + return observable; +} + lv_observer_t * lv_obj_bind_flag_if_eq(lv_obj_t * obj, lv_subject_t * subject, lv_obj_flag_t flag, int32_t ref_value) { lv_observer_t * observable = bind_to_bitfield(subject, obj, obj_flag_observer_cb, flag, ref_value, false, FLAG_COND_EQ); @@ -558,122 +860,105 @@ lv_observer_t * lv_obj_bind_checked(lv_obj_t * obj, lv_subject_t * subject) return observable; } -#if LV_USE_LABEL -lv_observer_t * lv_label_bind_text(lv_obj_t * obj, lv_subject_t * subject, const char * fmt) -{ - LV_ASSERT_NULL(subject); - LV_ASSERT_NULL(obj); - - if(fmt == NULL) { - if(subject->type == LV_SUBJECT_TYPE_INT) { - fmt = "%d"; - } - else if(subject->type != LV_SUBJECT_TYPE_STRING && subject->type != LV_SUBJECT_TYPE_POINTER) { - LV_LOG_WARN("Incompatible subject type: %d", subject->type); - return NULL; - } - } - else { - if(subject->type != LV_SUBJECT_TYPE_STRING && subject->type != LV_SUBJECT_TYPE_POINTER && - subject->type != LV_SUBJECT_TYPE_INT) { - LV_LOG_WARN("Incompatible subject type: %d", subject->type); - return NULL; - } - } - lv_observer_t * observer = lv_subject_add_observer_obj(subject, label_text_observer_cb, obj, (void *)fmt); - return observer; +lv_obj_t * lv_observer_get_target_obj(lv_observer_t * observer) +{ + return (lv_obj_t *)lv_observer_get_target(observer); } -#endif /*LV_USE_LABEL*/ -#if LV_USE_ARC -lv_observer_t * lv_arc_bind_value(lv_obj_t * obj, lv_subject_t * subject) +void * lv_observer_get_user_data(const lv_observer_t * observer) { - LV_ASSERT_NULL(subject); - LV_ASSERT_NULL(obj); + LV_ASSERT_NULL(observer); + return observer->user_data; +} - if(subject->type != LV_SUBJECT_TYPE_INT) { - LV_LOG_WARN("Incompatible subject type: %d", subject->type); - return NULL; - } +/********************** + * STATIC FUNCTIONS + **********************/ - lv_obj_add_event_cb(obj, arc_value_changed_event_cb, LV_EVENT_VALUE_CHANGED, subject); +static void subject_toggle_cb(lv_event_t * e) +{ + lv_subject_t * subject = lv_event_get_user_data(e); + int32_t v = lv_subject_get_int(subject); + v = !v; - lv_observer_t * observer = lv_subject_add_observer_obj(subject, arc_value_observer_cb, obj, NULL); - return observer; + lv_subject_set_int(subject, v); } -#endif /*LV_USE_ARC*/ -#if LV_USE_SLIDER -lv_observer_t * lv_slider_bind_value(lv_obj_t * obj, lv_subject_t * subject) +static void subject_set_int_cb(lv_event_t * e) { - LV_ASSERT_NULL(subject); - LV_ASSERT_NULL(obj); - - if(subject->type != LV_SUBJECT_TYPE_INT) { - LV_LOG_WARN("Incompatible subject type: %d", subject->type); - return NULL; - } + subject_set_int_user_data_t * user_data = lv_event_get_user_data(e); + lv_subject_set_int(user_data->subject, user_data->value); +} - lv_obj_add_event_cb(obj, slider_value_changed_event_cb, LV_EVENT_VALUE_CHANGED, subject); - lv_observer_t * observer = lv_subject_add_observer_obj(subject, slider_value_observer_cb, obj, NULL); - return observer; +#if LV_USE_FLOAT +static void subject_set_float_cb(lv_event_t * e) +{ + subject_set_float_user_data_t * user_data = lv_event_get_user_data(e); + lv_subject_set_float(user_data->subject, user_data->value); } -#endif /*LV_USE_SLIDER*/ +#endif -#if LV_USE_ROLLER -lv_observer_t * lv_roller_bind_value(lv_obj_t * obj, lv_subject_t * subject) +static void subject_set_string_cb(lv_event_t * e) { - LV_ASSERT_NULL(subject); - LV_ASSERT_NULL(obj); + subject_set_string_user_data_t * user_data = lv_event_get_user_data(e); + lv_subject_copy_string(user_data->subject, user_data->value); +} - if(subject->type != LV_SUBJECT_TYPE_INT) { - LV_LOG_WARN("Incompatible subject type: %d", subject->type); - return NULL; - } +static void subject_increment_cb(lv_event_t * e) +{ + lv_subject_increment_dsc_t * user_data = lv_event_get_user_data(e); - lv_obj_add_event_cb(obj, roller_value_changed_event_cb, LV_EVENT_VALUE_CHANGED, subject); + if(user_data->subject->type == LV_SUBJECT_TYPE_INT) { + /*Use the smaller range*/ + int32_t max_value = LV_MIN(user_data->max_value, user_data->subject->max_value.num); + int32_t min_value = LV_MAX(user_data->min_value, user_data->subject->min_value.num); - lv_observer_t * observer = lv_subject_add_observer_obj(subject, roller_value_observer_cb, obj, NULL); - return observer; -} -#endif /*LV_USE_ROLLER*/ + int32_t value = lv_subject_get_int(user_data->subject); + value += user_data->step; -#if LV_USE_DROPDOWN -lv_observer_t * lv_dropdown_bind_value(lv_obj_t * obj, lv_subject_t * subject) -{ - LV_ASSERT_NULL(subject); - LV_ASSERT_NULL(obj); + if(user_data->rollover) { + if(value > max_value) { + value = min_value; + } + else if(value < min_value) { + value = max_value; + } + } + else { + value = LV_CLAMP(min_value, value, max_value); + } - if(subject->type != LV_SUBJECT_TYPE_INT) { - LV_LOG_WARN("Incompatible subject type: %d", subject->type); - return NULL; + lv_subject_set_int(user_data->subject, value); } +#if LV_USE_FLOAT + else if(user_data->subject->type == LV_SUBJECT_TYPE_FLOAT) { + /*Use the smaller range*/ + float max_value = LV_MIN((float)user_data->max_value, user_data->subject->max_value.float_v); + float min_value = LV_MAX((float)user_data->min_value, user_data->subject->min_value.float_v); - lv_obj_add_event_cb(obj, dropdown_value_changed_event_cb, LV_EVENT_VALUE_CHANGED, subject); - - lv_observer_t * observer = lv_subject_add_observer_obj(subject, dropdown_value_observer_cb, obj, NULL); - return observer; -} -#endif /*LV_USE_DROPDOWN*/ -lv_obj_t * lv_observer_get_target_obj(lv_observer_t * observer) -{ - return (lv_obj_t *)lv_observer_get_target(observer); -} + float value = lv_subject_get_float(user_data->subject); + value += (float)user_data->step; -void * lv_observer_get_user_data(const lv_observer_t * observer) -{ - LV_ASSERT_NULL(observer); + if(user_data->rollover) { + if(value > max_value) { + value = min_value; + } + else if(value < min_value) { + value = max_value; + } + } + else { + value = LV_CLAMP(min_value, value, max_value); + } - return observer->user_data; + lv_subject_set_float(user_data->subject, value); + } +#endif } -/********************** - * STATIC FUNCTIONS - **********************/ - static void group_notify_cb(lv_observer_t * observer, lv_subject_t * subject) { LV_UNUSED(subject); @@ -714,6 +999,15 @@ static lv_observer_t * bind_to_bitfield(lv_subject_t * subject, lv_obj_t * obj, return observable; } +static void bind_style_observer_cb(lv_observer_t * observer, lv_subject_t * subject) +{ + bind_style_t * p = observer->user_data; + + int32_t current_v = lv_subject_get_int(subject); + bool dis = current_v != p->value; + lv_obj_style_set_disabled(observer->target, p->style, p->selector, dis); +} + static void obj_flag_observer_cb(lv_observer_t * observer, lv_subject_t * subject) { flag_and_cond_t * p = observer->user_data; @@ -788,6 +1082,13 @@ static void lv_subject_notify_if_changed(lv_subject_t * subject) lv_subject_notify(subject); } break; +#if LV_USE_FLOAT + case LV_SUBJECT_TYPE_FLOAT : + if(subject->value.float_v != subject->prev_value.float_v) { + lv_subject_notify(subject); + } + break; +#endif case LV_SUBJECT_TYPE_GROUP : case LV_SUBJECT_TYPE_POINTER : /* Always notify as we don't know how to compare this */ @@ -807,100 +1108,12 @@ static void lv_subject_notify_if_changed(lv_subject_t * subject) } } -#if LV_USE_LABEL - -static void label_text_observer_cb(lv_observer_t * observer, lv_subject_t * subject) -{ - const char * fmt = observer->user_data; - - if(fmt == NULL) { - lv_label_set_text(observer->target, subject->value.pointer); - } - else { - switch(subject->type) { - case LV_SUBJECT_TYPE_INT: - lv_label_set_text_fmt(observer->target, fmt, subject->value.num); - break; - case LV_SUBJECT_TYPE_STRING: - case LV_SUBJECT_TYPE_POINTER: - lv_label_set_text_fmt(observer->target, fmt, subject->value.pointer); - break; - default: - break; - } - } -} - -#endif /*LV_USE_LABEL*/ - -#if LV_USE_ARC - -static void arc_value_changed_event_cb(lv_event_t * e) -{ - lv_obj_t * arc = lv_event_get_current_target(e); - lv_subject_t * subject = lv_event_get_user_data(e); - - lv_subject_set_int(subject, lv_arc_get_value(arc)); -} - -static void arc_value_observer_cb(lv_observer_t * observer, lv_subject_t * subject) -{ - lv_arc_set_value(observer->target, subject->value.num); -} - -#endif /*LV_USE_ARC*/ - -#if LV_USE_SLIDER - -static void slider_value_changed_event_cb(lv_event_t * e) -{ - lv_obj_t * slider = lv_event_get_current_target(e); - lv_subject_t * subject = lv_event_get_user_data(e); - - lv_subject_set_int(subject, lv_slider_get_value(slider)); -} - -static void slider_value_observer_cb(lv_observer_t * observer, lv_subject_t * subject) -{ - lv_slider_set_value(observer->target, subject->value.num, LV_ANIM_OFF); -} - -#endif /*LV_USE_SLIDER*/ - -#if LV_USE_ROLLER - -static void roller_value_changed_event_cb(lv_event_t * e) -{ - lv_obj_t * roller = lv_event_get_current_target(e); - lv_subject_t * subject = lv_event_get_user_data(e); - - lv_subject_set_int(subject, lv_roller_get_selected(roller)); -} - -static void roller_value_observer_cb(lv_observer_t * observer, lv_subject_t * subject) -{ - if((int32_t)lv_roller_get_selected(observer->target) != subject->value.num) { - lv_roller_set_selected(observer->target, subject->value.num, LV_ANIM_OFF); - } -} - -#endif /*LV_USE_ROLLER*/ - -#if LV_USE_DROPDOWN - -static void dropdown_value_changed_event_cb(lv_event_t * e) -{ - lv_obj_t * dropdown = lv_event_get_current_target(e); - lv_subject_t * subject = lv_event_get_user_data(e); - - lv_subject_set_int(subject, lv_dropdown_get_selected(dropdown)); -} - -static void dropdown_value_observer_cb(lv_observer_t * observer, lv_subject_t * subject) +static void subject_set_string_free_user_data_event_cb(lv_event_t * e) { - lv_dropdown_set_selected(observer->target, subject->value.num); + subject_set_string_user_data_t * user_data = lv_event_get_user_data(e); + lv_free((void *)user_data->value); + lv_free(user_data); } -#endif /*LV_USE_DROPDOWN*/ #endif /*LV_USE_OBSERVER*/ diff --git a/src/others/observer/lv_observer.h b/src/others/observer/lv_observer.h index fa4b305b69..4881b64a87 100644 --- a/src/others/observer/lv_observer.h +++ b/src/others/observer/lv_observer.h @@ -32,10 +32,11 @@ typedef enum { LV_SUBJECT_TYPE_INVALID = 0, /**< indicates Subject not initialized yet */ LV_SUBJECT_TYPE_NONE = 1, /**< a null value like None or NILt */ LV_SUBJECT_TYPE_INT = 2, /**< an int32_t */ - LV_SUBJECT_TYPE_POINTER = 3, /**< a void pointer */ - LV_SUBJECT_TYPE_COLOR = 4, /**< an lv_color_t */ - LV_SUBJECT_TYPE_GROUP = 5, /**< an array of Subjects */ - LV_SUBJECT_TYPE_STRING = 6, /**< a char pointer */ + LV_SUBJECT_TYPE_FLOAT = 3, /**< a float, requires `LV_USE_FLOAT 1` */ + LV_SUBJECT_TYPE_POINTER = 4, /**< a void pointer */ + LV_SUBJECT_TYPE_COLOR = 5, /**< an lv_color_t */ + LV_SUBJECT_TYPE_GROUP = 6, /**< an array of Subjects */ + LV_SUBJECT_TYPE_STRING = 7, /**< a char pointer */ } lv_subject_type_t; /** @@ -45,6 +46,9 @@ typedef union { int32_t num; /**< Integer number (opacity, enums, booleans or "normal" numbers) */ const void * pointer; /**< Constant pointer (string buffer, format string, font, cone text, etc.) */ lv_color_t color; /**< Color */ +#if LV_USE_FLOAT + float float_v; /**< Floating point value*/ +#endif } lv_subject_value_t; /** @@ -54,10 +58,12 @@ typedef struct { lv_ll_t subs_ll; /**< Subscribers */ lv_subject_value_t value; /**< Current value */ lv_subject_value_t prev_value; /**< Previous value */ + lv_subject_value_t min_value; /**< Minimum value for min. int or float*/ + lv_subject_value_t max_value; /**< Maximum value for max. int or float*/ void * user_data; /**< Additional parameter, can be used freely by user */ uint32_t type : 4; /**< One of the LV_SUBJECT_TYPE_... values */ uint32_t size : 24; /**< String buffer size or group length */ - uint32_t notify_restart_query : 1; /**< If an Observer was deleted during notifcation, + uint32_t notify_restart_query : 1; /**< If an Observer was deleted during notification, * start notifying from the beginning. */ } lv_subject_t; @@ -100,6 +106,67 @@ int32_t lv_subject_get_int(lv_subject_t * subject); */ int32_t lv_subject_get_previous_int(lv_subject_t * subject); + +/** + * Set a minimum value for an integer subject + * @param subject pointer to Subject + * @param min_value the minimum value + */ +void lv_subject_set_min_value_int(lv_subject_t * subject, int32_t min_value); + +/** + * Set a maximum value for an integer subject + * @param subject pointer to Subject + * @param max_value the maximum value + */ +void lv_subject_set_max_value_int(lv_subject_t * subject, int32_t max_value); + +#if LV_USE_FLOAT + +/** + * Initialize an float-type Subject. + * @param subject pointer to Subject + * @param value initial value + */ +void lv_subject_init_float(lv_subject_t * subject, float value); + +/** + * Set value of an float Subject and notify Observers. + * @param subject pointer to Subject + * @param value new value + */ +void lv_subject_set_float(lv_subject_t * subject, float value); + +/** + * Get current value of an float Subject. + * @param subject pointer to Subject + * @return current value + */ +float lv_subject_get_float(lv_subject_t * subject); + +/** + * Get previous value of an float Subject. + * @param subject pointer to Subject + * @return current value + */ +float lv_subject_get_previous_float(lv_subject_t * subject); + +/** + * Set a minimum value for a float subject + * @param subject pointer to Subject + * @param min_value the minimum value + */ +void lv_subject_set_min_value_float(lv_subject_t * subject, float min_value); + +/** + * Set a maximum value for a float subject + * @param subject pointer to Subject + * @param max_value the maximum value + */ +void lv_subject_set_max_value_float(lv_subject_t * subject, float max_value); + +#endif /*LV_USE_FLOAT*/ + /** * Initialize a string-type Subject. * @param subject pointer to Subject @@ -239,7 +306,7 @@ lv_observer_t * lv_subject_add_observer(lv_subject_t * subject, lv_observer_cb_t * When the Widget is deleted, Observer will be unsubscribed from Subject automatically. * @param subject pointer to Subject * @param observer_cb notification callback - * @param obj pinter to Widget + * @param obj pointer to Widget * @param user_data optional user data * @return pointer to newly-created Observer * @note Do not call `lv_observer_remove()` on Observers created this way. @@ -306,6 +373,94 @@ void * lv_observer_get_user_data(const lv_observer_t * observer); */ void lv_subject_notify(lv_subject_t * subject); +/** + * Add an event handler to increment (or decrement) the value of a subject on a trigger. + * @param obj pointer to a widget + * @param subject pointer to a subject to change + * @param trigger the trigger on which the subject should be changed + * @param step value to add on trigger + * if the minimum value is reached, the maximum value will be set on rollover. + */ +lv_subject_increment_dsc_t * lv_obj_add_subject_increment_event(lv_obj_t * obj, lv_subject_t * subject, + lv_event_code_t trigger, int32_t step); + +/** + * Set the minimum subject value to set by the event + * @param obj pointer to the Widget to which the event is attached + * @param dsc pointer to the descriptor returned by `lv_obj_add_subject_increment_event()` + * @param min_value the minimum value to set + */ +void lv_obj_set_subject_increment_event_min_value(lv_obj_t * obj, lv_subject_increment_dsc_t * dsc, int32_t min_value); + +/** + * Set the maximum subject value to set by the event + * @param obj pointer to the Widget to which the event is attached + * @param dsc pointer to the descriptor returned by `lv_obj_add_subject_increment_event()` + * @param max_value the maximum value to set + */ +void lv_obj_set_subject_increment_event_max_value(lv_obj_t * obj, lv_subject_increment_dsc_t * dsc, int32_t max_value); + +/** + * Set what to do when the min/max value is crossed. + * @param obj pointer to the Widget to which the event is attached + * @param dsc pointer to the descriptor returned by `lv_obj_add_subject_increment_event()` + * @param rollover false: stop at the min/max value; true: jump to the other end + * @note the subject also can have min/max values and always the smaller range will be considered + */ +void lv_obj_set_subject_increment_event_rollover(lv_obj_t * obj, lv_subject_increment_dsc_t * dsc, bool rollover); + +/** +* Toggle the value of an integer subject on an event. If it was != 0 it will be 0. +* If it was 0, it will be 1. +* @param obj pointer to a widget +* @param subject pointer to a subject to toggle +* @param trigger the trigger on which the subject should be changed +*/ +void lv_obj_add_subject_toggle_event(lv_obj_t * obj, lv_subject_t * subject, lv_event_code_t trigger); + +/** + * Set the value of an integer subject. + * @param obj pointer to a widget + * @param subject pointer to a subject to change + * @param trigger the trigger on which the subject should be changed + * @param value the value to set + */ +void lv_obj_add_subject_set_int_event(lv_obj_t * obj, lv_subject_t * subject, lv_event_code_t trigger, int32_t value); + + +#if LV_USE_FLOAT +/** + * Set the value of a float subject. + * @param obj pointer to a widget + * @param subject pointer to a subject to change + * @param trigger the trigger on which the subject should be changed + * @param value the value to set + */ +void lv_obj_add_subject_set_float_event(lv_obj_t * obj, lv_subject_t * subject, lv_event_code_t trigger, float value); +#endif + +/** + * Set the value of a string subject. + * @param obj pointer to a widget + * @param subject pointer to a subject to change + * @param trigger the trigger on which the subject should be changed + * @param value the value to set + */ +void lv_obj_add_subject_set_string_event(lv_obj_t * obj, lv_subject_t * subject, lv_event_code_t trigger, + const char * value); + +/** + * Disable a style if a subject's value is not equal to a reference value + * @param obj pointer to Widget + * @param style pointer to a style + * @param selector pointer to a selector + * @param subject pointer to Subject + * @param ref_value reference value to compare Subject's value with + * @return pointer to newly-created Observer + */ +lv_observer_t * lv_obj_bind_style(lv_obj_t * obj, const lv_style_t * style, lv_style_selector_t selector, + lv_subject_t * subject, int32_t ref_value); + /** * Set Widget's flag(s) if an integer Subject's value is equal to a reference value, clear flag otherwise. * @param obj pointer to Widget @@ -439,60 +594,6 @@ lv_observer_t * lv_obj_bind_state_if_le(lv_obj_t * obj, lv_subject_t * subject, */ lv_observer_t * lv_obj_bind_checked(lv_obj_t * obj, lv_subject_t * subject); -#if LV_USE_LABEL -/** - * Bind an integer, string, or pointer Subject to a Label. - * @param obj pointer to Label - * @param subject pointer to Subject - * @param fmt optional printf-like format string with 1 format specifier (e.g. "%d °C") - * or NULL to bind to the value directly. - * @return pointer to newly-created Observer - * @note `fmt == NULL` can be used only with string and pointer Subjects. - * @note If Subject is a pointer and `fmt == NULL`, pointer must point - * to a `\0` terminated string. - */ -lv_observer_t * lv_label_bind_text(lv_obj_t * obj, lv_subject_t * subject, const char * fmt); -#endif - -#if LV_USE_ARC -/** - * Bind an integer subject to an Arc's value. - * @param obj pointer to Arc - * @param subject pointer to Subject - * @return pointer to newly-created Observer - */ -lv_observer_t * lv_arc_bind_value(lv_obj_t * obj, lv_subject_t * subject); -#endif - -#if LV_USE_SLIDER -/** - * Bind an integer Subject to a Slider's value. - * @param obj pointer to Slider - * @param subject pointer to Subject - * @return pointer to newly-created Observer - */ -lv_observer_t * lv_slider_bind_value(lv_obj_t * obj, lv_subject_t * subject); -#endif - -#if LV_USE_ROLLER -/** - * Bind an integer Subject to a Roller's value. - * @param obj pointer to Roller - * @param subject pointer to Subject - * @return pointer to newly-created Observer - */ -lv_observer_t * lv_roller_bind_value(lv_obj_t * obj, lv_subject_t * subject); -#endif - -#if LV_USE_DROPDOWN -/** - * Bind an integer Subject to a Dropdown's value. - * @param obj pointer to Dropdown - * @param subject pointer to Subject - * @return pointer to newly-created Observer - */ -lv_observer_t * lv_dropdown_bind_value(lv_obj_t * obj, lv_subject_t * subject); -#endif /********************** * MACROS diff --git a/src/others/observer/lv_observer_private.h b/src/others/observer/lv_observer_private.h index d62d1f663f..6f6cd89f2b 100644 --- a/src/others/observer/lv_observer_private.h +++ b/src/others/observer/lv_observer_private.h @@ -39,6 +39,16 @@ struct _lv_observer_t { uint32_t for_obj : 1; /**< Is `target` a pointer to a Widget (`lv_obj_t *`)? */ }; +/** + * Descriptor created by `lv_obj_add_subject_increment_event()` + */ +struct _lv_subject_increment_dsc_t { + lv_subject_t * subject; /**< The subject to adjust*/ + int32_t step; /**< The step add to the subject */ + bool rollover; /**< Where to start over from the other end when one end is exceeded*/ + int32_t min_value; /**< Don't set a value smaller than this */ + int32_t max_value; /**< Don't set a value larger than this */ +}; /********************** * GLOBAL PROTOTYPES diff --git a/src/others/snapshot/lv_snapshot.c b/src/others/snapshot/lv_snapshot.c index 376d3b2af2..6885f2ed1e 100644 --- a/src/others/snapshot/lv_snapshot.c +++ b/src/others/snapshot/lv_snapshot.c @@ -16,6 +16,7 @@ #include "../../core/lv_refr_private.h" #include "../../display/lv_display_private.h" #include "../../stdlib/lv_string.h" +#include "../../core/lv_obj_private.h" /********************* * DEFINES @@ -98,9 +99,6 @@ lv_result_t lv_snapshot_take_to_draw_buf(lv_obj_t * obj, lv_color_format_t cf, l res = lv_snapshot_reshape_draw_buf(obj, draw_buf); if(res != LV_RESULT_OK) return res; - /* clear draw buffer*/ - lv_draw_buf_clear(draw_buf, NULL); - lv_area_t snapshot_area; int32_t w = draw_buf->header.w; int32_t h = draw_buf->header.h; @@ -108,6 +106,13 @@ lv_result_t lv_snapshot_take_to_draw_buf(lv_obj_t * obj, lv_color_format_t cf, l lv_obj_get_coords(obj, &snapshot_area); lv_area_increase(&snapshot_area, ext_size, ext_size); + lv_obj_t * top_obj = lv_refr_get_top_obj(&snapshot_area, obj); + if(top_obj == NULL) { + /* Clear draw buffer when no top object*/ + lv_draw_buf_clear(draw_buf, NULL); + top_obj = obj; + } + lv_layer_t layer; lv_layer_init(&layer); @@ -126,7 +131,44 @@ lv_result_t lv_snapshot_take_to_draw_buf(lv_obj_t * obj, lv_color_format_t cf, l disp_new->layer_head = &layer; lv_refr_set_disp_refreshing(disp_new); - lv_obj_redraw(&layer, obj); + + if(top_obj == obj) { + lv_obj_redraw(&layer, top_obj); + } + else { + lv_obj_refr(&layer, top_obj); + + lv_obj_t * parent = lv_obj_get_parent(top_obj); + lv_obj_t * border_p = top_obj; + + /*Do until not reach the screen*/ + while(parent != NULL && border_p != obj) { + bool go = false; + uint32_t i; + uint32_t child_cnt = lv_obj_get_child_count(parent); + for(i = 0; i < child_cnt; i++) { + lv_obj_t * child = parent->spec_attr->children[i]; + if(!go) { + if(child == border_p) go = true; + } + else { + /*Refresh the objects*/ + lv_obj_refr(&layer, child); + } + } + + /*Call the post draw draw function of the parents of the to object*/ + lv_obj_send_event(parent, LV_EVENT_DRAW_POST_BEGIN, (void *)&layer); + lv_obj_send_event(parent, LV_EVENT_DRAW_POST, (void *)&layer); + lv_obj_send_event(parent, LV_EVENT_DRAW_POST_END, (void *)&layer); + + /*The new border will be the last parents, + *so the 'younger' brothers of parent will be refreshed*/ + border_p = parent; + /*Go a level deeper*/ + parent = lv_obj_get_parent(parent); + } + } while(layer.draw_task_head) { lv_draw_dispatch_wait_for_request(); diff --git a/src/others/sysmon/lv_sysmon.c b/src/others/sysmon/lv_sysmon.c index e8f5c6c886..f0665b243e 100644 --- a/src/others/sysmon/lv_sysmon.c +++ b/src/others/sysmon/lv_sysmon.c @@ -41,6 +41,8 @@ static void perf_update_timer_cb(lv_timer_t * t); static void perf_observer_cb(lv_observer_t * observer, lv_subject_t * subject); static void perf_monitor_disp_event_cb(lv_event_t * e); + static void perf_dump_info(lv_display_t * disp); + static void perf_control(lv_display_t * disp, bool start); #endif #if LV_USE_MEM_MONITOR @@ -137,6 +139,26 @@ void lv_sysmon_hide_performance(lv_display_t * disp) lv_obj_add_flag(disp->perf_label, LV_OBJ_FLAG_HIDDEN); } +void lv_sysmon_performance_dump(lv_display_t * disp) +{ + if(disp == NULL) disp = lv_display_get_default(); + if(disp == NULL) { + LV_LOG_WARN("There is no default display"); + return; + } + perf_dump_info(disp); +} + +void lv_sysmon_performance_resume(lv_display_t * disp) +{ + perf_control(disp, true); +} + +void lv_sysmon_performance_pause(lv_display_t * disp) +{ + perf_control(disp, false); +} + #endif #if LV_USE_MEM_MONITOR @@ -233,10 +255,8 @@ static void perf_monitor_disp_event_cb(lv_event_t * e) } } -static void perf_update_timer_cb(lv_timer_t * t) +static void perf_dump_info(lv_display_t * disp) { - lv_display_t * disp = lv_timer_get_user_data(t); - uint32_t LV_SYSMON_GET_IDLE(void); lv_sysmon_perf_info_t * info = &disp->perf_sysmon_info; @@ -246,11 +266,15 @@ static void perf_update_timer_cb(lv_timer_t * t) lv_timer_t * disp_refr_timer = lv_display_get_refr_timer(NULL); uint32_t disp_refr_period = disp_refr_timer ? disp_refr_timer->period : LV_DEF_REFR_PERIOD; - info->calculated.fps = info->measured.refr_interval_sum ? (1000 * info->measured.refr_cnt / time_since_last_report) : 0; + info->calculated.fps = time_since_last_report ? (1000 * info->measured.refr_cnt / time_since_last_report) : 0; info->calculated.fps = LV_MIN(info->calculated.fps, 1000 / disp_refr_period); /*Limit due to possible off-by-one error*/ info->calculated.cpu = 100 - LV_SYSMON_GET_IDLE(); +#if LV_SYSMON_PROC_IDLE_AVAILABLE + uint32_t LV_SYSMON_GET_PROC_IDLE(void); + info->calculated.cpu_proc = 100 - LV_SYSMON_GET_PROC_IDLE(); +#endif /*LV_SYSMON_PROC_IDLE_AVAILABLE*/ info->calculated.refr_avg_time = info->measured.refr_cnt ? (info->measured.refr_elaps_sum / info->measured.refr_cnt) : 0; @@ -273,18 +297,37 @@ static void perf_update_timer_cb(lv_timer_t * t) lv_memzero(info, sizeof(lv_sysmon_perf_info_t)); info->measured.refr_start = prev_info.measured.refr_start; info->calculated.cpu_avg_total = prev_info.calculated.cpu_avg_total; +#if LV_SYSMON_PROC_IDLE_AVAILABLE + info->calculated.cpu_proc = prev_info.calculated.cpu_proc; +#endif /*LV_SYSMON_PROC_IDLE_AVAILABLE*/ info->calculated.fps_avg_total = prev_info.calculated.fps_avg_total; info->calculated.run_cnt = prev_info.calculated.run_cnt; info->measured.last_report_timestamp = lv_tick_get(); } +static void perf_update_timer_cb(lv_timer_t * t) +{ + lv_display_t * disp = lv_timer_get_user_data(t); + + perf_dump_info(disp); +} + static void perf_observer_cb(lv_observer_t * observer, lv_subject_t * subject) { const lv_sysmon_perf_info_t * perf = lv_subject_get_pointer(subject); #if LV_USE_PERF_MONITOR_LOG_MODE LV_UNUSED(observer); +#if LV_SYSMON_PROC_IDLE_AVAILABLE + LV_LOG("sysmon: " + "%" LV_PRIu32 " FPS (refr_cnt: %" LV_PRIu32 " | redraw_cnt: %" LV_PRIu32"), " + "refr %" LV_PRIu32 "ms (render %" LV_PRIu32 "ms | flush %" LV_PRIu32 "ms), " + "CPU (total %" LV_PRIu32 "%% proc %" LV_PRIu32 "%%)\n", + perf->calculated.fps, perf->measured.refr_cnt, perf->measured.render_cnt, + perf->calculated.refr_avg_time, perf->calculated.render_avg_time, perf->calculated.flush_avg_time, + perf->calculated.cpu, perf->calculated.cpu_proc); +#else LV_LOG("sysmon: " "%" LV_PRIu32 " FPS (refr_cnt: %" LV_PRIu32 " | redraw_cnt: %" LV_PRIu32"), " "refr %" LV_PRIu32 "ms (render %" LV_PRIu32 "ms | flush %" LV_PRIu32 "ms), " @@ -292,8 +335,19 @@ static void perf_observer_cb(lv_observer_t * observer, lv_subject_t * subject) perf->calculated.fps, perf->measured.refr_cnt, perf->measured.render_cnt, perf->calculated.refr_avg_time, perf->calculated.render_avg_time, perf->calculated.flush_avg_time, perf->calculated.cpu); +#endif #else lv_obj_t * label = lv_observer_get_target(observer); +#if LV_SYSMON_PROC_IDLE_AVAILABLE + lv_label_set_text_fmt( + label, + "%" LV_PRIu32" FPS | CPU (%" LV_PRIu32 "%% | %" LV_PRIu32 "%%)\n" + "%" LV_PRIu32" ms (%" LV_PRIu32" | %" LV_PRIu32")", + perf->calculated.fps, perf->calculated.cpu, perf->calculated.cpu_proc, + perf->calculated.render_avg_time + perf->calculated.flush_avg_time, + perf->calculated.render_avg_time, perf->calculated.flush_avg_time + ); +#else lv_label_set_text_fmt( label, "%" LV_PRIu32" FPS, %" LV_PRIu32 "%% CPU\n" @@ -302,9 +356,28 @@ static void perf_observer_cb(lv_observer_t * observer, lv_subject_t * subject) perf->calculated.render_avg_time + perf->calculated.flush_avg_time, perf->calculated.render_avg_time, perf->calculated.flush_avg_time ); +#endif /*LV_SYSMON_PROC_IDLE_AVAILABLE*/ #endif /*LV_USE_PERF_MONITOR_LOG_MODE*/ } +static void perf_control(lv_display_t * disp, bool start) +{ + if(disp == NULL) disp = lv_display_get_default(); + if(disp == NULL) { + LV_LOG_WARN("There is no default display"); + return; + } + + if(disp->perf_sysmon_backend.timer == NULL) return; + + if(start) { + lv_timer_resume(disp->perf_sysmon_backend.timer); + } + else { + lv_timer_pause(disp->perf_sysmon_backend.timer); + } +} + #endif #if LV_USE_MEM_MONITOR @@ -321,7 +394,7 @@ static void mem_observer_cb(lv_observer_t * observer, lv_subject_t * subject) lv_obj_t * label = lv_observer_get_target(observer); const lv_mem_monitor_t * mon = lv_subject_get_pointer(subject); - size_t used_size = mon->total_size - mon->free_size;; + size_t used_size = mon->total_size - mon->free_size; size_t used_kb = used_size / 1024; size_t used_kb_tenth = (used_size - (used_kb * 1024)) / 102; size_t max_used_kb = mon->max_used / 1024; diff --git a/src/others/sysmon/lv_sysmon.h b/src/others/sysmon/lv_sysmon.h index 0859c064d4..69b4b11fe9 100644 --- a/src/others/sysmon/lv_sysmon.h +++ b/src/others/sysmon/lv_sysmon.h @@ -60,6 +60,28 @@ void lv_sysmon_show_performance(lv_display_t * disp); */ void lv_sysmon_hide_performance(lv_display_t * disp); +/** + * Dump the FPS data recorded between the last and current dump call. + * @param disp target display, NULL: use the default + */ +void lv_sysmon_performance_dump(lv_display_t * disp); + +/** + * Resume the system performance monitor. + * @param disp target display, NULL: use the default + */ +void lv_sysmon_performance_resume(lv_display_t * disp); + +/** + * Pause the system performance monitor. + * + * @param disp target display, NULL: use the default + * @note When the sysmon is stopped you can use `lv_sysmon_dump_performance` to + * get performance information. See `lv_sysmon_dump_performance` for more information. + */ +void lv_sysmon_performance_pause(lv_display_t * disp); + + #endif /*LV_USE_PERF_MONITOR*/ #if LV_USE_MEM_MONITOR diff --git a/src/others/sysmon/lv_sysmon_private.h b/src/others/sysmon/lv_sysmon_private.h index b4fa3877eb..36e0571315 100644 --- a/src/others/sysmon/lv_sysmon_private.h +++ b/src/others/sysmon/lv_sysmon_private.h @@ -53,6 +53,9 @@ struct _lv_sysmon_perf_info_t { struct { uint32_t fps; uint32_t cpu; +#if LV_SYSMON_PROC_IDLE_AVAILABLE + uint32_t cpu_proc; /** The applications idle time percentage */ +#endif uint32_t refr_avg_time; uint32_t render_avg_time; /**< Pure rendering time without flush time*/ uint32_t flush_avg_time; /**< Pure flushing time without rendering time*/ diff --git a/src/others/test/lv_test_indev.c b/src/others/test/lv_test_indev.c index 11bdb14b25..742e27d38d 100644 --- a/src/others/test/lv_test_indev.c +++ b/src/others/test/lv_test_indev.c @@ -55,6 +55,24 @@ void lv_test_indev_create_all(void) lv_indev_set_read_cb(_state.encoder_indev, lv_test_encoder_read_cb); } +void lv_test_indev_delete_all(void) +{ + if(_state.mouse_indev) { + lv_indev_delete(_state.mouse_indev); + _state.mouse_indev = NULL; + } + + if(_state.keypad_indev) { + lv_indev_delete(_state.keypad_indev); + _state.keypad_indev = NULL; + } + + if(_state.encoder_indev) { + lv_indev_delete(_state.encoder_indev); + _state.encoder_indev = NULL; + } +} + lv_indev_t * lv_test_indev_get_indev(lv_indev_type_t type) { switch(type) { diff --git a/src/others/test/lv_test_indev.h b/src/others/test/lv_test_indev.h index 7d833fff48..63c44ab462 100644 --- a/src/others/test/lv_test_indev.h +++ b/src/others/test/lv_test_indev.h @@ -37,6 +37,11 @@ extern "C" { */ void lv_test_indev_create_all(void); +/** + * Delete all test input devices + */ +void lv_test_indev_delete_all(void); + /** * Get one of the indev created in `lv_test_indev_create_all` * @param type type of the indev to get diff --git a/src/others/test/lv_test_indev_gesture.c b/src/others/test/lv_test_indev_gesture.c index ad0148195d..64455d61df 100644 --- a/src/others/test/lv_test_indev_gesture.c +++ b/src/others/test/lv_test_indev_gesture.c @@ -54,6 +54,21 @@ void lv_test_indev_gesture_create(void) lv_indev_set_read_cb(_state.gesture_indev, lv_test_gesture_read_cb); } +void lv_test_indev_gesture_delete(void) +{ + if(_state.gesture_indev) { + lv_indev_delete(_state.gesture_indev); + _state.gesture_indev = NULL; + } + + if(_state.touch_data) { + lv_free(_state.touch_data); + _state.touch_data = NULL; + } + + _state.max_touch_cnt = 0; +} + lv_indev_t * lv_test_indev_get_gesture_indev(lv_indev_type_t type) { switch(type) { @@ -112,6 +127,15 @@ static void lv_test_gesture_read_cb(lv_indev_t * indev, lv_indev_data_t * data) _state.touch_data, _state.max_touch_cnt); lv_indev_gesture_recognizers_set_data(indev, data); + if(_state.touch_data != NULL && _state.max_touch_cnt > 0) { + data->point.x = _state.touch_data[0].point.x; + data->point.y = _state.touch_data[0].point.y; + } + else { + LV_LOG_ERROR("Invalid touch data or max touch count"); + data->point.x = 0; + data->point.y = 0; + } } #endif /*LV_USE_TEST*/ diff --git a/src/others/test/lv_test_indev_gesture.h b/src/others/test/lv_test_indev_gesture.h index 8973478d81..23aef9a1a9 100644 --- a/src/others/test/lv_test_indev_gesture.h +++ b/src/others/test/lv_test_indev_gesture.h @@ -37,6 +37,11 @@ extern "C" { */ void lv_test_indev_gesture_create(void); +/** + * Delete the touch (pointer) indevs. + */ +void lv_test_indev_gesture_delete(void); + /** * Get one of the indev created in `lv_test_indev_gesture_create` * @param type type of the indev to get diff --git a/src/others/test/lv_test_screenshot_compare.c b/src/others/test/lv_test_screenshot_compare.c index db73d18a19..2896151940 100644 --- a/src/others/test/lv_test_screenshot_compare.c +++ b/src/others/test/lv_test_screenshot_compare.c @@ -1,5 +1,5 @@ /** - * @file lv_test_assert.c + * @file lv_test_screenshot_compare.c * * Copyright 2002-2010 Guillaume Cottenceau. * @@ -81,6 +81,7 @@ bool lv_test_screenshot_compare(const char * fn_ref) lv_obj_t * scr = lv_screen_active(); lv_obj_invalidate(scr); + lv_refr_now(NULL); pass = screenshot_compare(fn_ref, REF_IMG_TOLERANCE); if(!pass) return false; @@ -104,9 +105,8 @@ static bool screenshot_compare(const char * fn_ref, uint8_t tolerance) create_folders_if_needed(fn_ref_full); - lv_refr_now(NULL); - lv_draw_buf_t * draw_buf = lv_display_get_buf_active(NULL); + uint8_t * screen_buf_xrgb8888 = lv_malloc(draw_buf->header.w * draw_buf->header.h * 4); buf_to_xrgb8888(draw_buf, screen_buf_xrgb8888); @@ -115,12 +115,18 @@ static bool screenshot_compare(const char * fn_ref, uint8_t tolerance) unsigned ref_img_height = 0; unsigned res = read_png_file(&ref_draw_buf, &ref_img_width, &ref_img_height, fn_ref_full); if(res) { - LV_LOG_ERROR("%s%s", fn_ref_full, " was not found, creating is now from the rendered screen"); + LV_LOG_WARN("%s%s", fn_ref_full, " was not found, creating it now from the rendered screen"); write_png_file(screen_buf_xrgb8888, draw_buf->header.w, draw_buf->header.h, fn_ref_full); lv_free(screen_buf_xrgb8888); return true; } + if(ref_img_width != draw_buf->header.w || ref_img_height != draw_buf->header.h) { + LV_LOG_WARN("The dimensions of the rendered and the %s reference image don't match", fn_ref); + return false; + } + + unsigned x, y; bool err = false; for(y = 0; y < ref_img_height; y++) { diff --git a/src/others/test/lv_test_screenshot_compare.h b/src/others/test/lv_test_screenshot_compare.h index b962beceff..b37fe3ee3e 100644 --- a/src/others/test/lv_test_screenshot_compare.h +++ b/src/others/test/lv_test_screenshot_compare.h @@ -37,6 +37,8 @@ extern "C" { * * @param fn_ref path to the reference image. Will be appended toREF_IMGS_PATH if set. * @return true: the reference image and the display are the same; false: they are different (`_err.png` is created). + * @note This function assumes that the default display is the test display that was created by + * `lv_test_display_create()` */ bool lv_test_screenshot_compare(const char * fn_ref); diff --git a/src/others/translation/lv_translation.c b/src/others/translation/lv_translation.c new file mode 100644 index 0000000000..54ed553dd8 --- /dev/null +++ b/src/others/translation/lv_translation.c @@ -0,0 +1,298 @@ +/** + * @file lv_translation.c + * + */ + +/********************* + * INCLUDES + *********************/ +#include "lv_translation.h" +#if LV_USE_TRANSLATION + +#include "lv_translation_private.h" +#include "../../misc/lv_ll.h" +#include "../../stdlib/lv_mem.h" +#include "../../stdlib/lv_string.h" +#include "../../misc/lv_log.h" +#include "../../misc/lv_assert.h" +#include "../../core/lv_global.h" +#include "../../lvgl_private.h" + +/********************* + * DEFINES + *********************/ +#define packs_ll (LV_GLOBAL_DEFAULT()->translation_packs_ll) +#define selected_lang (LV_GLOBAL_DEFAULT()->translation_selected_lang) + +/********************** + * TYPEDEFS + **********************/ + +/********************** + * STATIC PROTOTYPES + **********************/ + +static lv_obj_tree_walk_res_t send_language_change_event(lv_obj_t * obj, void * lang); + +/********************** + * STATIC VARIABLES + **********************/ + +/********************** + * MACROS + **********************/ + +/********************** + * GLOBAL FUNCTIONS + **********************/ + +void lv_translation_init(void) +{ + lv_ll_init(&packs_ll, sizeof(lv_translation_pack_t)); + selected_lang = NULL; +} + +void lv_translation_deinit(void) +{ + lv_translation_pack_t * pack; + LV_LL_READ(&packs_ll, pack) { + if(pack->is_static == false) { + size_t i; + size_t trans_cnt = lv_array_size(&pack->translation_array); + for(i = 0; i < trans_cnt; i++) { + lv_translation_tag_dsc_t * tag = lv_array_at(&pack->translation_array, i); + lv_free((void *)tag->tag); + + size_t j; + for(j = 0; j < pack->language_cnt; j++) { + lv_free((void *)tag->translations[j]); /*Free each translation of the tag*/ + } + lv_free(tag->translations); + } + + lv_array_deinit(&pack->translation_array); + + for(i = 0; i < pack->language_cnt; i++) { + lv_free((void *)pack->languages[i]); + } + lv_free(pack->languages); + } + } + + lv_ll_clear(&packs_ll); + + lv_free((void *)selected_lang); +} + +lv_translation_pack_t * lv_translation_add_static(const char * languages[], const char * tags[], + const char * translations[]) +{ + LV_ASSERT_NULL(languages); + LV_ASSERT_NULL(tags); + LV_ASSERT_NULL(translations); + + lv_translation_pack_t * pack = lv_ll_ins_head(&packs_ll); + LV_ASSERT_MALLOC(pack); + if(pack == NULL) return NULL; + lv_memzero(pack, sizeof(lv_translation_pack_t)); + pack->is_static = 1; + + /*Count the languages*/ + while(languages[pack->language_cnt]) { + pack->language_cnt++; + } + + pack->languages = languages; + pack->tag_p = tags; + pack->translation_p = translations; + return pack; +} + +lv_translation_pack_t * lv_translation_add_dynamic(void) +{ + lv_translation_pack_t * pack = lv_ll_ins_head(&packs_ll); + LV_ASSERT_MALLOC(pack); + if(pack == NULL) return NULL; + + lv_memzero(pack, sizeof(lv_translation_pack_t)); + + pack->is_static = 0; + lv_array_init(&pack->translation_array, 16, sizeof(lv_translation_tag_dsc_t)); + + return pack; +} + +const char * lv_translation_get_language(void) +{ + return selected_lang; +} + +void lv_translation_set_language(const char * lang) +{ + if(selected_lang) lv_free((void *)selected_lang); + selected_lang = lv_strdup(lang); + lv_obj_tree_walk(NULL, send_language_change_event, (void *)lang); +} + +const char * lv_translation_get(const char * tag) +{ + if(selected_lang == NULL) { + LV_LOG_WARN("No language is selected to get the translation of `%s`", tag); + return tag; + } + + lv_translation_pack_t * pack; + bool lang_found = false; + LV_LL_READ(&packs_ll, pack) { + uint32_t lang; + for(lang = 0; lang < pack->language_cnt; lang++) { + /*Does this pack contains the language?*/ + if(lv_streq(pack->languages[lang], selected_lang)) { + lang_found = true; + /*Find the tag*/ + if(pack->is_static) { + uint32_t t; + for(t = 0; pack->tag_p[t]; t++) { + if(lv_streq(pack->tag_p[t], tag)) { + /*Find the "row" of the tag */ + const char ** tr_row = pack->translation_p + pack->language_cnt * t; + const char * tr = tr_row[lang]; + if(tr) return tr; /*Found directly*/ + + LV_LOG_WARN("`%s` tag is not found. Using the tag as translation.", tag); + return tag; /*Return the tag as a fall back*/ + } + } + } + else { + size_t trans_cnt = lv_array_size(&pack->translation_array); + size_t i; + for(i = 0; i < trans_cnt; i++) { + lv_translation_tag_dsc_t * tag_dsc = lv_array_at(&pack->translation_array, i); + if(lv_streq(tag_dsc->tag, tag)) { + const char * tr = tag_dsc->translations[lang]; + if(tr) return tr; /*Found directly*/ + + LV_LOG_WARN("`%s` tag is not found. Using the tag as translation.", tag); + return tag; /*Return the tag as a worst case option*/ + } + } + } + } + } + } + + if(lang_found) { + LV_LOG_WARN("`%s` tag is not found, using the tag as translation.", tag); + } + else { + LV_LOG_WARN("`%s` language is not found, using the `%s` as translation.", selected_lang, tag); + } + + return tag; +} + +lv_result_t lv_translation_add_language(lv_translation_pack_t * pack, const char * lang) +{ + if(pack->is_static) { + LV_LOG_WARN("Can't add language `%s` to static translation pack `%p`", lang, (void *)pack); + return LV_RESULT_INVALID; + } + + pack->language_cnt++; + pack->languages = lv_realloc(pack->languages, sizeof(const char *) * pack->language_cnt); + LV_ASSERT_MALLOC(pack->languages); + if(pack->languages == NULL) { + LV_LOG_WARN("Couldn't allocate languages in `%p`", (void *)pack); + return LV_RESULT_INVALID; + } + + pack->languages[pack->language_cnt - 1] = lv_strdup(lang); + LV_ASSERT_MALLOC(pack->languages[pack->language_cnt - 1]); + if(pack->languages[pack->language_cnt - 1] == NULL) { + LV_LOG_WARN("Couldn't allocate the new language in `%p`", (void *)pack); + return LV_RESULT_INVALID; + } + + return LV_RESULT_OK; +} + +int32_t lv_translation_get_language_index(lv_translation_pack_t * pack, const char * lang_name) +{ + uint32_t i; + for(i = 0; i < pack->language_cnt; i++) { + if(lv_streq(pack->languages[i], lang_name)) return (int32_t)i; + } + + return -1; +} + + +lv_translation_tag_dsc_t * lv_translation_add_tag(lv_translation_pack_t * pack, const char * tag_name) +{ + if(pack->is_static) { + LV_LOG_WARN("Can't add tag `%s` to static translation pack `%p`", tag_name, (void *)pack); + return NULL; + } + + lv_translation_tag_dsc_t tag; + tag.tag = lv_strdup(tag_name); + LV_ASSERT_MALLOC(tag.tag); + tag.translations = lv_zalloc(pack->language_cnt * sizeof(const char *)); + LV_ASSERT_MALLOC(tag.translations); + + if(tag.tag == NULL || tag.translations == NULL) { + LV_LOG_WARN("Couldn't allocate memory for the tag's data in `%p`", (void *)pack); + lv_free((void *)tag.tag); + lv_free((void *)tag.translations); + return NULL; + } + + lv_result_t res = lv_array_push_back(&pack->translation_array, &tag); + + if(res != LV_RESULT_OK) { + LV_LOG_WARN("Couldn't add the tag in `%p`", (void *)pack); + lv_free((void *)tag.tag); + lv_free((void *)tag.translations); + return NULL; + } + + return lv_array_back(&pack->translation_array); +} + +lv_result_t lv_translation_set_tag_translation(lv_translation_pack_t * pack, lv_translation_tag_dsc_t * tag, + uint32_t lang_idx, const char * trans) +{ + if(pack->is_static) { + LV_LOG_WARN("Can't set tag translation`%s` in static translation pack `%p`", trans, (void *)pack); + return LV_RESULT_INVALID; + } + + if(lang_idx >= pack->language_cnt) { + + LV_LOG_WARN("Can't set the translation for language %" LV_PRIu32 " as there are only %" LV_PRIu32 + " languages defined in %p", + lang_idx, pack->language_cnt, (void *)pack); + return LV_RESULT_INVALID; + } + + lv_free((void *)tag->translations[lang_idx]); /*Free the earlier set language if any*/ + tag->translations[lang_idx] = lv_strdup(trans); + if(tag->translations[lang_idx] == NULL) { + LV_LOG_WARN("Couldn't allocate the new translation in tag `%p` in pack `%p`", (void *)tag, (void *) pack); + return LV_RESULT_INVALID; + } + return LV_RESULT_OK; +} + +/********************** + * STATIC FUNCTIONS + **********************/ + +static lv_obj_tree_walk_res_t send_language_change_event(lv_obj_t * obj, void * lang) +{ + lv_obj_send_event(obj, LV_EVENT_TRANSLATION_LANGUAGE_CHANGED, lang); + return LV_OBJ_TREE_WALK_NEXT; +} + +#endif /*LV_USE_TRANSLATION*/ diff --git a/src/others/translation/lv_translation.h b/src/others/translation/lv_translation.h new file mode 100644 index 0000000000..84e8db9183 --- /dev/null +++ b/src/others/translation/lv_translation.h @@ -0,0 +1,147 @@ +/** + * @file lv_translation.h + * + */ + +#ifndef LV_TRANSLATION_H +#define LV_TRANSLATION_H + +#ifdef __cplusplus +extern "C" { +#endif + +/********************* + * INCLUDES + *********************/ +#include "../../lv_conf_internal.h" + +#if LV_USE_TRANSLATION + +#include LV_STDINT_INCLUDE +#include "../../misc/lv_array.h" + +/********************* + * DEFINES + *********************/ + +/********************** + * TYPEDEFS + **********************/ + +/********************** + * GLOBAL PROTOTYPES + **********************/ + +/** + * Initialize the translation module + */ +void lv_translation_init(void); + +/** + * De-initialize the translation module and free all allocated translations + */ +void lv_translation_deinit(void); + +/** + * Register a translation pack from static arrays. + * All the pointers need to be static, that is to live while they are used + * @param languages List of languages. E.g. `{"en", "de", NULL}` + * @param tags Tags that are using in the UI. E.g. `{"dog", "cat", NULL}` + * @param translations List of translations. E.g. `{"Dog", "Cat", "Hund", "Katze"}` + * @return The created pack + */ +lv_translation_pack_t * lv_translation_add_static(const char * languages[], const char * tags[], + const char * translations[]); + +/** + * Add a pack to which translations can be added dynamically. + * `pack->languages` needs to be a malloc-ed array where each language is also malloc-ed as an element. + * `pack->translation_array` stores the translation having `lv_translation_tag_dsc_t` items + * In each array element `tag` is a malloced string, `translations` is a malloc-ed array + * with malloc-ed array for each element. + * @return the created pack to which data can be added manually. + */ +lv_translation_pack_t * lv_translation_add_dynamic(void); + +/** + * Select the current language + * The `LV_EVENT_TRANSLATION_LANGUAGE_CHANGED` event will be sent to every widget + * @param lang a string from the defined languages. E.g. "en" or "de" + */ +void lv_translation_set_language(const char * lang); + +/** + * Get the current selected language + * @return the current selected language + */ +const char * lv_translation_get_language(void); + +/** + * Get the translated version of a tag on the selected language + * @param tag the tag to translate + * @return the translation + * @note fallback rules: + * - if the tag is found on the selected language return it + * - if the tag is not found on the selected language, use the fist language + * - if the tag is not found on the first language, return the tag + */ +const char * lv_translation_get(const char * tag); + +/** + * Shorthand of lv_translation_set_language + * @param tag the tag to translate + * @return the translation + */ +static inline const char * lv_tr(const char * tag) +{ + return lv_translation_get(tag); +} + +/** + * Add a new language to a dynamic language pack. + * All languages should be added before adding tags + * @param pack pointer to a dynamic translation pack + * @param lang language to add, e.g. "en", or "de" + * @return LV_RESULT_OK: success, LV_RESULT_INVALID: failed + */ +lv_result_t lv_translation_add_language(lv_translation_pack_t * pack, const char * lang); + +/** + * Get the index of a language in a pack. + * @param pack pointer to a static or dynamic language pack + * @param lang_name name of the language to find + * @return index of the language or -1 if not found. + */ +int32_t lv_translation_get_language_index(lv_translation_pack_t * pack, const char * lang_name); + +/** + * Add a new tag to a dynamic language pack. + * Once the tag is added the translations for each language can be added too by using + * `lv_translation_set_tag_translation` + * @param pack pointer to a dynamic translation pack + * @param tag_name name of the tag, e.g. "dog", or "house" + * @return pointer to the allocated tag descriptor + */ +lv_translation_tag_dsc_t * lv_translation_add_tag(lv_translation_pack_t * pack, const char * tag_name); + +/** + * Add a translation to a tag in a dynamic translation pack + * @param pack pointer to a dynamic translation pack + * @param tag return value of `lv_translation_add_tag` + * @param lang_idx index of the language for which translation should be set + * @param trans the translation on the given language + * @return LV_RESULT_OK: success, LV_RESULT_INVALID: failed + */ +lv_result_t lv_translation_set_tag_translation(lv_translation_pack_t * pack, lv_translation_tag_dsc_t * tag, + uint32_t lang_idx, const char * trans); + +/********************** + * MACROS + **********************/ +#endif /*LV_USE_TRANSLATION*/ + +#ifdef __cplusplus +} /*extern "C"*/ +#endif + +#endif /* LV_TRANSLATION_H */ diff --git a/src/others/translation/lv_translation_private.h b/src/others/translation/lv_translation_private.h new file mode 100644 index 0000000000..3fae69451d --- /dev/null +++ b/src/others/translation/lv_translation_private.h @@ -0,0 +1,59 @@ +/** + * @file lv_translation_private.h + * + */ + +#ifndef LV_TRANSLATION_PRIVATE_H +#define LV_TRANSLATION_PRIVATE_H + +#ifdef __cplusplus +extern "C" { +#endif + +/********************* + * INCLUDES + *********************/ +#include "../../lv_conf_internal.h" + +#if LV_USE_TRANSLATION + +#include LV_STDINT_INCLUDE +#include "../../misc/lv_array.h" + +/********************* + * DEFINES + *********************/ + +/********************** + * TYPEDEFS + **********************/ + +struct _lv_translation_tag_dsc_t { + const char * tag; + const char ** translations; /**< Translations for each language*/ +}; + +struct _lv_translation_pack_t { + const char ** languages; + uint32_t language_cnt; + uint32_t is_static; /*In the union translations_p is used*/ + const char ** tag_p; + const char ** translation_p; /*E.g. {{"a", "b"}, {"c", "d"}}*/ + lv_array_t translation_array; +}; + +/********************** + * GLOBAL PROTOTYPES + **********************/ + +/********************** + * MACROS + **********************/ + +#endif /*LV_USE_TRANSLATION*/ + +#ifdef __cplusplus +} /*extern "C"*/ +#endif + +#endif /* LV_TRANSLATION_PRIVATE_H */ diff --git a/src/others/vg_lite_tvg/vg_lite_tvg.cpp b/src/others/vg_lite_tvg/vg_lite_tvg.cpp index 8e2f4f42a4..5c3a9dc6c3 100644 --- a/src/others/vg_lite_tvg/vg_lite_tvg.cpp +++ b/src/others/vg_lite_tvg/vg_lite_tvg.cpp @@ -324,8 +324,8 @@ static void get_format_bytes(vg_lite_buffer_format_t format, vg_lite_uint32_t * bytes_align); static vg_lite_fpoint_t matrix_transform_point(const vg_lite_matrix_t * matrix, const vg_lite_fpoint_t * point); -static bool vg_lite_matrix_inverse(vg_lite_matrix_t * result, const vg_lite_matrix_t * matrix); -static void vg_lite_matrix_multiply(vg_lite_matrix_t * matrix, const vg_lite_matrix_t * mult); +static Result vg_lite_grad_matrix_conv(vg_lite_matrix_t * result, const vg_lite_matrix_t * grad_matrix, + const vg_lite_matrix_t * path_matrix); /********************** * STATIC VARIABLES @@ -501,6 +501,13 @@ static vg_lite_converter conv_bgra2222_to_bgr } }); +/* Used to copy images with inconsistent strides but the same color format */ +static vg_lite_converter conv_bgra8888_to_bgra8888( + [](vg_color32_t * dest, const vg_color32_t * src, vg_lite_uint32_t px_size, vg_lite_uint32_t /* color */) +{ + memcpy(dest, src, sizeof(vg_color32_t) * px_size); +}); + /********************** * MACROS **********************/ @@ -657,13 +664,19 @@ extern "C" { auto ctx = vg_lite_ctx::get_instance(); TVG_CHECK_RETURN_VG_ERROR(canvas_set_target(ctx, target)); + vg_lite_matrix_t new_matrix = *matrix; + if(rect->x || rect->y) { + /* simulate hardware device clipping behavior */ + vg_lite_translate(-rect->x, -rect->y, &new_matrix); + } + auto shape = Shape::gen(); TVG_CHECK_RETURN_VG_ERROR(shape_append_rect(shape, target, rect)); - TVG_CHECK_RETURN_VG_ERROR(shape->transform(matrix_conv(matrix))); + TVG_CHECK_RETURN_VG_ERROR(shape->transform(matrix_conv(&new_matrix))); auto picture = tvg::Picture::gen(); TVG_CHECK_RETURN_VG_ERROR(picture_load(ctx, picture, source, color)); - TVG_CHECK_RETURN_VG_ERROR(picture->transform(matrix_conv(matrix))); + TVG_CHECK_RETURN_VG_ERROR(picture->transform(matrix_conv(&new_matrix))); TVG_CHECK_RETURN_VG_ERROR(picture->blend(blend_method_conv(blend))); TVG_CHECK_RETURN_VG_ERROR(picture->composite(std::move(shape), CompositeMethod::ClipPath)); TVG_CHECK_RETURN_VG_ERROR(ctx->canvas->push(std::move(picture))); @@ -979,7 +992,6 @@ extern "C" { case gcFEATURE_BIT_VG_RGBA2_FORMAT: case gcFEATURE_BIT_VG_IM_FASTCLAER: case gcFEATURE_BIT_VG_GLOBAL_ALPHA: - case gcFEATURE_BIT_VG_COLOR_KEY: case gcFEATURE_BIT_VG_24BIT: case gcFEATURE_BIT_VG_DITHER: case gcFEATURE_BIT_VG_USE_DST: @@ -1457,10 +1469,13 @@ extern "C" { TVG_CHECK_RETURN_VG_ERROR(shape->fill(fill_rule_conv(fill_rule));); TVG_CHECK_RETURN_VG_ERROR(shape->blend(blend_method_conv(blend))); + vg_lite_matrix_t grad_matrix; + TVG_CHECK_RETURN_VG_ERROR(vg_lite_grad_matrix_conv(&grad_matrix, &grad->matrix, path_matrix)); + auto linearGrad = LinearGradient::gen(); TVG_CHECK_RETURN_VG_ERROR(linearGrad->linear(grad->linear_grad.X0, grad->linear_grad.Y0, grad->linear_grad.X1, grad->linear_grad.Y1)); - TVG_CHECK_RETURN_VG_ERROR(linearGrad->transform(matrix_conv(&grad->matrix))); + TVG_CHECK_RETURN_VG_ERROR(linearGrad->transform(matrix_conv(&grad_matrix))); TVG_CHECK_RETURN_VG_ERROR(linearGrad->spread(fill_spread_conv(grad->spread_mode))); tvg::Fill::ColorStop colorStops[VLC_MAX_COLOR_RAMP_STOPS]; @@ -1912,9 +1927,7 @@ extern "C" { TVG_CHECK_RETURN_VG_ERROR(shape->blend(blend_method_conv(blend))); vg_lite_matrix_t grad_matrix; - vg_lite_identity(&grad_matrix); - vg_lite_matrix_inverse(&grad_matrix, matrix); - vg_lite_matrix_multiply(&grad_matrix, &grad->matrix); + TVG_CHECK_RETURN_VG_ERROR(vg_lite_grad_matrix_conv(&grad_matrix, &grad->matrix, matrix)); vg_lite_fpoint_t p1 = {0.0f, 0.0f}; vg_lite_fpoint_t p2 = {1.0f, 0}; @@ -1975,8 +1988,11 @@ extern "C" { TVG_CHECK_RETURN_VG_ERROR(shape->fill(fill_rule_conv(fill_rule));); TVG_CHECK_RETURN_VG_ERROR(shape->blend(blend_method_conv(blend))); + vg_lite_matrix_t grad_matrix; + TVG_CHECK_RETURN_VG_ERROR(vg_lite_grad_matrix_conv(&grad_matrix, &grad->matrix, path_matrix)); + auto radialGrad = RadialGradient::gen(); - TVG_CHECK_RETURN_VG_ERROR(radialGrad->transform(matrix_conv(&grad->matrix))); + TVG_CHECK_RETURN_VG_ERROR(radialGrad->transform(matrix_conv(&grad_matrix))); TVG_CHECK_RETURN_VG_ERROR(radialGrad->radial(grad->radial_grad.cx, grad->radial_grad.cy, grad->radial_grad.r)); TVG_CHECK_RETURN_VG_ERROR(radialGrad->spread(fill_spread_conv(grad->spread_mode))); @@ -2181,6 +2197,15 @@ static vg_lite_error_t vg_lite_error_conv(Result result) static Matrix matrix_conv(const vg_lite_matrix_t * matrix) { + static const Matrix identity = { + 1, 0, 0, + 0, 1, 0, + 0, 0, 1 + }; + if(!matrix) { + return identity; + } + return *(Matrix *)matrix; } @@ -2283,7 +2308,7 @@ static float vlc_get_arg(const void * data, vg_lite_format_t format) return *((float *)data); default: - LV_LOG_ERROR("UNKNOW_FORMAT: %d", format); + LV_LOG_ERROR("UNKNOWN_FORMAT: %d", format); break; } @@ -2302,7 +2327,7 @@ static uint8_t vlc_format_len(vg_lite_format_t format) case VG_LITE_FP32: return 4; default: - LV_LOG_ERROR("UNKNOW_FORMAT: %d", format); + LV_LOG_ERROR("UNKNOWN_FORMAT: %d", format); LV_ASSERT(false); break; } @@ -2332,7 +2357,7 @@ static uint8_t vlc_op_arg_len(uint8_t vlc_op) VLC_OP_ARG_LEN(LCWARC, 5); VLC_OP_ARG_LEN(LCWARC_REL, 5); default: - LV_LOG_ERROR("UNKNOW_VLC_OP: 0x%x", vlc_op); + LV_LOG_ERROR("UNKNOWN_VLC_OP: 0x%x", vlc_op); LV_ASSERT(false); break; } @@ -2450,7 +2475,7 @@ static Result shape_append_path(std::unique_ptr & shape, vg_lite_path_t * float x_max = path->bounding_box[2]; float y_max = path->bounding_box[3]; - if(math_equal(x_min, FLT_MIN) && math_equal(y_min, FLT_MIN) + if(math_equal(x_min, -FLT_MAX) && math_equal(y_min, -FLT_MAX) && math_equal(x_max, FLT_MAX) && math_equal(y_max, FLT_MAX)) { return Result::Success; } @@ -2491,13 +2516,21 @@ static Result canvas_set_target(vg_lite_ctx * ctx, vg_lite_buffer_t * target) ctx->target_px_size = target->width * target->height; void * canvas_target_buffer; + uint32_t stride = 0; + if(TVG_IS_VG_FMT_SUPPORT(target->format)) { /* if target format is supported by VG, use target buffer directly */ canvas_target_buffer = target->memory; + + /* support target stride */ + LV_ASSERT(target->stride >= target->width); + LV_ASSERT(VG_LITE_IS_ALIGNED(target->stride, sizeof(uint32_t))); + stride = target->stride / sizeof(uint32_t); } else { /* if target format is not supported by VG, use internal buffer */ canvas_target_buffer = ctx->get_temp_target_buffer(target->width, target->height); + stride = target->width; } /* Prevent repeated target setting */ @@ -2509,7 +2542,7 @@ static Result canvas_set_target(vg_lite_ctx * ctx, vg_lite_buffer_t * target) TVG_CHECK_RETURN_RESULT(ctx->canvas->target( (uint32_t *)ctx->tvg_target_buffer, - target->width, + stride, target->width, target->height, SwCanvas::ARGB8888)); @@ -2524,29 +2557,16 @@ static Result canvas_set_target(vg_lite_ctx * ctx, vg_lite_buffer_t * target) return Result::Success; } -static vg_lite_uint32_t width_to_stride(vg_lite_uint32_t w, vg_lite_buffer_format_t color_format) -{ - if(vg_lite_query_feature(gcFEATURE_BIT_VG_16PIXELS_ALIGN)) { - w = VG_LITE_ALIGN(w, 16); - } - - vg_lite_uint32_t mul, div, align; - get_format_bytes(color_format, &mul, &div, &align); - return VG_LITE_ALIGN((w * mul / div), align); -} - static bool decode_indexed_line( vg_lite_buffer_format_t color_format, const vg_lite_uint32_t * palette, int32_t x, int32_t y, - int32_t w_px, const uint8_t * in, vg_lite_uint32_t * out) + int32_t w_px, uint32_t stride, const uint8_t * in, vg_lite_uint32_t * out) { uint8_t px_size; uint16_t mask; - vg_lite_uint32_t w_byte = width_to_stride(w_px, color_format); - - in += w_byte * y; /*First pixel*/ + in += stride * y; /*First pixel*/ out += w_px * y; int8_t shift = 0; @@ -2596,19 +2616,22 @@ static Result picture_load(vg_lite_ctx * ctx, std::unique_ptr & picture vg_lite_color_t color) { vg_lite_uint32_t * image_buffer; - LV_ASSERT(VG_LITE_IS_ALIGNED(source->memory, LV_VG_LITE_THORVG_BUF_ADDR_ALIGN)); -#if LV_VG_LITE_THORVG_16PIXELS_ALIGN - LV_ASSERT(VG_LITE_IS_ALIGNED(source->width, 16)); -#endif + /* At least 8-byte alignment */ + LV_ASSERT(VG_LITE_IS_ALIGNED(source->memory, 8)); - if(source->format == VG_LITE_BGRA8888 && source->image_mode == VG_LITE_NORMAL_IMAGE_MODE) { + /** + * Since ThorVG's picture->load does not support stride, + * reconversion is required when the stride and width do not match. + */ + if(source->format == VG_LITE_BGRA8888 + && source->image_mode == VG_LITE_NORMAL_IMAGE_MODE + && (size_t)source->stride == (size_t)(source->width * sizeof(vg_lite_uint32_t))) { image_buffer = (vg_lite_uint32_t *)source->memory; } else { vg_lite_uint32_t width = source->width; vg_lite_uint32_t height = source->height; - vg_lite_uint32_t px_size = width * height; image_buffer = ctx->get_image_buffer(width, height); vg_lite_buffer_t target; @@ -2617,7 +2640,7 @@ static Result picture_load(vg_lite_ctx * ctx, std::unique_ptr & picture target.format = VG_LITE_BGRA8888; target.width = width; target.height = height; - target.stride = width_to_stride(width, target.format); + target.stride = width * sizeof(vg_lite_uint32_t); switch(source->format) { case VG_LITE_INDEX_1: @@ -2626,7 +2649,7 @@ static Result picture_load(vg_lite_ctx * ctx, std::unique_ptr & picture case VG_LITE_INDEX_8: { const vg_lite_uint32_t * clut_colors = ctx->get_CLUT(source->format); for(vg_lite_uint32_t y = 0; y < height; y++) { - decode_indexed_line(source->format, clut_colors, 0, y, width, (uint8_t *)source->memory, image_buffer); + decode_indexed_line(source->format, clut_colors, 0, y, width, source->stride, (uint8_t *)source->memory, image_buffer); } } break; @@ -2691,7 +2714,8 @@ static Result picture_load(vg_lite_ctx * ctx, std::unique_ptr & picture #endif case VG_LITE_BGRA8888: { - memcpy(image_buffer, source->memory, px_size * sizeof(vg_color32_t)); + /* For stride conversion */ + conv_bgra8888_to_bgra8888.convert(&target, source); } break; @@ -2704,6 +2728,7 @@ static Result picture_load(vg_lite_ctx * ctx, std::unique_ptr & picture /* multiply color */ if(source->image_mode == VG_LITE_MULTIPLY_IMAGE_MODE && !VG_LITE_IS_ALPHA_FORMAT(source->format)) { vg_color32_t * dest = (vg_color32_t *)image_buffer; + vg_lite_uint32_t px_size = width * height; while(px_size--) { dest->alpha = UDIV255(dest->alpha * A(color)); dest->red = UDIV255(dest->red * B(color)); @@ -2985,4 +3010,25 @@ static void vg_lite_matrix_multiply(vg_lite_matrix_t * matrix, const vg_lite_mat lv_memcpy(matrix->m, &temp.m, sizeof(temp.m)); } +static Result vg_lite_grad_matrix_conv(vg_lite_matrix_t * result, const vg_lite_matrix_t * grad_matrix, + const vg_lite_matrix_t * path_matrix) +{ + /** + * Since Thorvg internally multiplies the path (shape) matrix with the gradient matrix to produce + * the rendering result, and VG-Lite's gradient matrix and path matrix are completely independent, + * requiring a previous multiplication to achieve the same rendering result, + * for the VG-Lite emulator, it is necessary to offset the gradient matrix to obtain the user's original gradient matrix + * to simulate hardware behavior: + * matrix_out = path_matrix * gradient_matrix + * => + * gradient_matrix = inv(path_matrix) * matrix_out + */ + if(!vg_lite_matrix_inverse(result, path_matrix)) { + return Result::InvalidArguments; + } + + vg_lite_matrix_multiply(result, grad_matrix); + return Result::Success; +} + #endif diff --git a/src/others/xml/lv_xml.c b/src/others/xml/lv_xml.c index 87a0cdf4de..d2164549e1 100644 --- a/src/others/xml/lv_xml.c +++ b/src/others/xml/lv_xml.c @@ -10,14 +10,24 @@ #include "lv_xml.h" #if LV_USE_XML +#if LV_USE_OBJ_NAME == 0 + #error "LV_USE_OBJ_NAME is required to use XMLs" +#endif + +#if LV_USE_OBSERVER == 0 + #error "LV_USE_OBSERVER is required to use XMLs" +#endif + +#include "lv_xml.h" #include "lv_xml_base_types.h" #include "lv_xml_parser.h" #include "lv_xml_component.h" #include "lv_xml_component_private.h" #include "lv_xml_widget.h" #include "lv_xml_style.h" -#include "lv_xml.h" +#include "lv_xml_translation.h" #include "lv_xml_utils.h" +#include "lv_xml_load_private.h" #include "lv_xml_private.h" #include "parsers/lv_xml_obj_parser.h" #include "parsers/lv_xml_button_parser.h" @@ -36,16 +46,22 @@ #include "parsers/lv_xml_textarea_parser.h" #include "parsers/lv_xml_keyboard_parser.h" #include "parsers/lv_xml_arc_parser.h" +#include "parsers/lv_xml_switch_parser.h" +#include "parsers/lv_xml_spinbox_parser.h" #include "parsers/lv_xml_checkbox_parser.h" #include "parsers/lv_xml_canvas_parser.h" #include "parsers/lv_xml_calendar_parser.h" -#include "parsers/lv_xml_event_parser.h" +#include "parsers/lv_xml_qrcode_parser.h" #include "../../libs/expat/expat.h" #include "../../draw/lv_draw_image.h" +#include "../../core/lv_global.h" +#include "../../misc/lv_anim_timeline_private.h" /********************* * DEFINES *********************/ +#define xml_path_prefix LV_GLOBAL_DEFAULT()->xml_path_prefix +#define lv_event_xml_store_timeline LV_GLOBAL_DEFAULT()->lv_event_xml_store_timeline /********************** * TYPEDEFS @@ -56,6 +72,9 @@ **********************/ static void view_start_element_handler(void * user_data, const char * name, const char ** attrs); static void view_end_element_handler(void * user_data, const char * name); +static void create_timeline_instances(lv_xml_parser_state_t * state); +static void get_timeline_from_event_cb(lv_event_t * e); +static void free_timelines_event_cb(lv_event_t * e); /********************** * STATIC VARIABLES @@ -71,46 +90,174 @@ static void view_end_element_handler(void * user_data, const char * name); void lv_xml_init(void) { + xml_path_prefix = lv_strdup(""); + + /*It will be sued to store animation time lines in user_data*/ + lv_event_xml_store_timeline = lv_event_register_id(); + lv_xml_component_init(); lv_xml_register_font(NULL, "lv_font_default", lv_font_get_default()); - lv_xml_widget_register("lv_obj", lv_xml_obj_create, lv_xml_obj_apply); - lv_xml_widget_register("lv_button", lv_xml_button_create, lv_xml_button_apply); - lv_xml_widget_register("lv_label", lv_xml_label_create, lv_xml_label_apply); - lv_xml_widget_register("lv_image", lv_xml_image_create, lv_xml_image_apply); - lv_xml_widget_register("lv_bar", lv_xml_bar_create, lv_xml_bar_apply); - lv_xml_widget_register("lv_slider", lv_xml_slider_create, lv_xml_slider_apply); - lv_xml_widget_register("lv_tabview", lv_xml_tabview_create, lv_xml_tabview_apply); - lv_xml_widget_register("lv_tabview-tab_bar", lv_xml_tabview_tab_bar_create, lv_xml_tabview_tab_bar_apply); - lv_xml_widget_register("lv_tabview-tab", lv_xml_tabview_tab_create, lv_xml_tabview_tab_apply); - lv_xml_widget_register("lv_chart", lv_xml_chart_create, lv_xml_chart_apply); - lv_xml_widget_register("lv_chart-cursor", lv_xml_chart_cursor_create, lv_xml_chart_cursor_apply); - lv_xml_widget_register("lv_chart-series", lv_xml_chart_series_create, lv_xml_chart_series_apply); - lv_xml_widget_register("lv_chart-axis", lv_xml_chart_axis_create, lv_xml_chart_axis_apply); - lv_xml_widget_register("lv_table", lv_xml_table_create, lv_xml_table_apply); - lv_xml_widget_register("lv_table-column", lv_xml_table_column_create, lv_xml_table_column_apply); - lv_xml_widget_register("lv_table-cell", lv_xml_table_cell_create, lv_xml_table_cell_apply); - lv_xml_widget_register("lv_dropdown", lv_xml_dropdown_create, lv_xml_dropdown_apply); - lv_xml_widget_register("lv_dropdown-list", lv_xml_dropdown_list_create, lv_xml_dropdown_list_apply); - lv_xml_widget_register("lv_roller", lv_xml_roller_create, lv_xml_roller_apply); - lv_xml_widget_register("lv_scale", lv_xml_scale_create, lv_xml_scale_apply); - lv_xml_widget_register("lv_scale-section", lv_xml_scale_section_create, lv_xml_scale_section_apply); - lv_xml_widget_register("lv_spangroup", lv_xml_spangroup_create, lv_xml_spangroup_apply); - lv_xml_widget_register("lv_spangroup-span", lv_xml_spangroup_span_create, lv_xml_spangroup_span_apply); - lv_xml_widget_register("lv_buttonmatrix", lv_xml_buttonmatrix_create, lv_xml_buttonmatrix_apply); - lv_xml_widget_register("lv_textarea", lv_xml_textarea_create, lv_xml_textarea_apply); - lv_xml_widget_register("lv_keyboard", lv_xml_keyboard_create, lv_xml_keyboard_apply); - lv_xml_widget_register("lv_arc", lv_xml_arc_create, lv_xml_arc_apply); - lv_xml_widget_register("lv_checkbox", lv_xml_checkbox_create, lv_xml_checkbox_apply); - lv_xml_widget_register("lv_canvas", lv_xml_canvas_create, lv_xml_canvas_apply); - lv_xml_widget_register("lv_calendar", lv_xml_calendar_create, lv_xml_calendar_apply); - lv_xml_widget_register("lv_calendar-header_arrow", lv_xml_calendar_header_arrow_create, + lv_xml_register_widget("lv_obj", lv_xml_obj_create, lv_xml_obj_apply); + +#if LV_USE_BUTTON + lv_xml_register_widget("lv_button", lv_xml_button_create, lv_xml_button_apply); +#endif + +#if LV_USE_LABEL + lv_xml_register_widget("lv_label", lv_xml_label_create, lv_xml_label_apply); +#endif + +#if LV_USE_IMAGE + lv_xml_register_widget("lv_image", lv_xml_image_create, lv_xml_image_apply); +#endif + +#if LV_USE_BAR + lv_xml_register_widget("lv_bar", lv_xml_bar_create, lv_xml_bar_apply); +#endif + +#if LV_USE_SLIDER + lv_xml_register_widget("lv_slider", lv_xml_slider_create, lv_xml_slider_apply); +#endif + +#if LV_USE_SPINBOX + lv_xml_register_widget("lv_spinbox", lv_xml_spinbox_create, lv_xml_spinbox_apply); +#endif + +#if LV_USE_TABVIEW + lv_xml_register_widget("lv_tabview", lv_xml_tabview_create, lv_xml_tabview_apply); + lv_xml_register_widget("lv_tabview-tab_bar", lv_xml_tabview_tab_bar_create, lv_xml_tabview_tab_bar_apply); + lv_xml_register_widget("lv_tabview-tab", lv_xml_tabview_tab_create, lv_xml_tabview_tab_apply); + lv_xml_register_widget("lv_tabview-tab_button", lv_xml_tabview_tab_button_create, lv_xml_tabview_tab_button_apply); +#endif + +#if LV_USE_CHART + lv_xml_register_widget("lv_chart", lv_xml_chart_create, lv_xml_chart_apply); + lv_xml_register_widget("lv_chart-cursor", lv_xml_chart_cursor_create, lv_xml_chart_cursor_apply); + lv_xml_register_widget("lv_chart-series", lv_xml_chart_series_create, lv_xml_chart_series_apply); + lv_xml_register_widget("lv_chart-axis", lv_xml_chart_axis_create, lv_xml_chart_axis_apply); +#endif + +#if LV_USE_TABLE + lv_xml_register_widget("lv_table", lv_xml_table_create, lv_xml_table_apply); + lv_xml_register_widget("lv_table-column", lv_xml_table_column_create, lv_xml_table_column_apply); + lv_xml_register_widget("lv_table-cell", lv_xml_table_cell_create, lv_xml_table_cell_apply); +#endif + +#if LV_USE_DROPDOWN + lv_xml_register_widget("lv_dropdown", lv_xml_dropdown_create, lv_xml_dropdown_apply); + lv_xml_register_widget("lv_dropdown-list", lv_xml_dropdown_list_create, lv_xml_dropdown_list_apply); +#endif + +#if LV_USE_ROLLER + lv_xml_register_widget("lv_roller", lv_xml_roller_create, lv_xml_roller_apply); +#endif + +#if LV_USE_SCALE + lv_xml_register_widget("lv_scale", lv_xml_scale_create, lv_xml_scale_apply); + lv_xml_register_widget("lv_scale-section", lv_xml_scale_section_create, lv_xml_scale_section_apply); +#endif + +#if LV_USE_SPAN + lv_xml_register_widget("lv_spangroup", lv_xml_spangroup_create, lv_xml_spangroup_apply); + lv_xml_register_widget("lv_spangroup-span", lv_xml_spangroup_span_create, lv_xml_spangroup_span_apply); +#endif + +#if LV_USE_BUTTONMATRIX + lv_xml_register_widget("lv_buttonmatrix", lv_xml_buttonmatrix_create, lv_xml_buttonmatrix_apply); +#endif + +#if LV_USE_TEXTAREA + lv_xml_register_widget("lv_textarea", lv_xml_textarea_create, lv_xml_textarea_apply); +#endif + +#if LV_USE_KEYBOARD + lv_xml_register_widget("lv_keyboard", lv_xml_keyboard_create, lv_xml_keyboard_apply); +#endif + +#if LV_USE_ARC + lv_xml_register_widget("lv_arc", lv_xml_arc_create, lv_xml_arc_apply); +#endif + +#if LV_USE_SWITCH + lv_xml_register_widget("lv_switch", lv_xml_switch_create, lv_xml_switch_apply); +#endif + +#if LV_USE_CHECKBOX + lv_xml_register_widget("lv_checkbox", lv_xml_checkbox_create, lv_xml_checkbox_apply); +#endif + +#if LV_USE_CANVAS + lv_xml_register_widget("lv_canvas", lv_xml_canvas_create, lv_xml_canvas_apply); +#endif + +#if LV_USE_CALENDAR + lv_xml_register_widget("lv_calendar", lv_xml_calendar_create, lv_xml_calendar_apply); +#if LV_USE_CALENDAR_HEADER_ARROW + lv_xml_register_widget("lv_calendar-header_arrow", lv_xml_calendar_header_arrow_create, lv_xml_calendar_header_arrow_apply); - lv_xml_widget_register("lv_calendar-header_dropdown", lv_xml_calendar_header_dropdown_create, +#endif +#if LV_USE_CALENDAR_HEADER_DROPDOWN + lv_xml_register_widget("lv_calendar-header_dropdown", lv_xml_calendar_header_dropdown_create, lv_xml_calendar_header_dropdown_apply); +#endif +#endif + +#if LV_USE_QRCODE + lv_xml_register_widget("lv_qrcode", lv_xml_qrcode_create, lv_xml_qrcode_apply); +#endif + + lv_xml_register_widget("lv_obj-style", lv_obj_xml_style_create, lv_obj_xml_style_apply); + lv_xml_register_widget("lv_obj-remove_style", lv_obj_xml_remove_style_create, lv_obj_xml_remove_style_apply); + lv_xml_register_widget("lv_obj-remove_style_all", lv_obj_xml_remove_style_all_create, + lv_obj_xml_remove_style_all_apply); + + lv_xml_register_widget("lv_obj-event_cb", lv_obj_xml_event_cb_create, lv_obj_xml_event_cb_apply); + + lv_xml_register_widget("lv_obj-subject_toggle_event", lv_obj_xml_subject_toggle_create, + lv_obj_xml_subject_toggle_apply); + lv_xml_register_widget("lv_obj-subject_set_int_event", lv_obj_xml_subject_set_create, lv_obj_xml_subject_set_apply); + lv_xml_register_widget("lv_obj-subject_set_float_event", lv_obj_xml_subject_set_create, lv_obj_xml_subject_set_apply); + lv_xml_register_widget("lv_obj-subject_set_string_event", lv_obj_xml_subject_set_create, lv_obj_xml_subject_set_apply); + lv_xml_register_widget("lv_obj-subject_increment_event", lv_obj_xml_subject_increment_create, + lv_obj_xml_subject_increment_apply); + + lv_xml_register_widget("lv_obj-screen_load_event", lv_obj_xml_screen_load_event_create, + lv_obj_xml_screen_load_event_apply); + lv_xml_register_widget("lv_obj-screen_create_event", lv_obj_xml_screen_create_event_create, + lv_obj_xml_screen_create_event_apply); + + lv_xml_register_widget("lv_obj-play_timeline_event", lv_obj_xml_play_timeline_event_create, + lv_obj_xml_play_timeline_event_apply); + + lv_xml_register_widget("lv_obj-bind_style", lv_obj_xml_bind_style_create, lv_obj_xml_bind_style_apply); + lv_xml_register_widget("lv_obj-bind_flag_if_eq", lv_obj_xml_bind_flag_create, lv_obj_xml_bind_flag_apply); + lv_xml_register_widget("lv_obj-bind_flag_if_not_eq", lv_obj_xml_bind_flag_create, lv_obj_xml_bind_flag_apply); + lv_xml_register_widget("lv_obj-bind_flag_if_gt", lv_obj_xml_bind_flag_create, lv_obj_xml_bind_flag_apply); + lv_xml_register_widget("lv_obj-bind_flag_if_lt", lv_obj_xml_bind_flag_create, lv_obj_xml_bind_flag_apply); + lv_xml_register_widget("lv_obj-bind_flag_if_ge", lv_obj_xml_bind_flag_create, lv_obj_xml_bind_flag_apply); + lv_xml_register_widget("lv_obj-bind_flag_if_le", lv_obj_xml_bind_flag_create, lv_obj_xml_bind_flag_apply); + + lv_xml_register_widget("lv_obj-bind_state_if_eq", lv_obj_xml_bind_state_create, lv_obj_xml_bind_state_apply); + lv_xml_register_widget("lv_obj-bind_state_if_not_eq", lv_obj_xml_bind_state_create, lv_obj_xml_bind_state_apply); + lv_xml_register_widget("lv_obj-bind_state_if_gt", lv_obj_xml_bind_state_create, lv_obj_xml_bind_state_apply); + lv_xml_register_widget("lv_obj-bind_state_if_lt", lv_obj_xml_bind_state_create, lv_obj_xml_bind_state_apply); + lv_xml_register_widget("lv_obj-bind_state_if_ge", lv_obj_xml_bind_state_create, lv_obj_xml_bind_state_apply); + lv_xml_register_widget("lv_obj-bind_state_if_le", lv_obj_xml_bind_state_create, lv_obj_xml_bind_state_apply); + + lv_xml_load_init(); +} - lv_xml_widget_register("lv_event-call_function", lv_xml_event_call_function_create, lv_xml_event_call_function_apply); +void lv_xml_deinit(void) +{ +#if LV_USE_TEST + lv_xml_test_unregister(); +#endif + + lv_xml_load_deinit(); + + lv_free((void *)xml_path_prefix); } void * lv_xml_create_in_scope(lv_obj_t * parent, lv_xml_component_scope_t * parent_scope, @@ -149,13 +296,19 @@ void * lv_xml_create_in_scope(lv_obj_t * parent, lv_xml_component_scope_t * pare #if LV_USE_OBJ_NAME /*Set a default indexed name*/ - if(state.item && lv_obj_get_name(state.item) == NULL) { - char name_buf[128]; - lv_snprintf(name_buf, sizeof(name_buf), "%s_#", scope->name); - lv_obj_set_name(state.item, name_buf); + if(state.item) { + if(state.scope.is_screen) { + lv_obj_set_name(state.item, scope->name); + } + else if(lv_obj_get_name(state.item) == NULL) { + char name_buf[128]; + lv_snprintf(name_buf, sizeof(name_buf), "%s_#", scope->name); + } } #endif + create_timeline_instances(&state); + lv_ll_clear(&state.parent_ll); XML_ParserFree(parser); @@ -178,6 +331,10 @@ void * lv_xml_create(lv_obj_t * parent, const char * name, const char ** attrs) * So leave state.scope = NULL which means the global context.*/ state.item = p->create_cb(&state, attrs); + if(state.item == NULL) { + LV_LOG_WARN("Couldn't create widget."); + return NULL; + } if(attrs) { p->apply_cb(&state, attrs); } @@ -187,7 +344,11 @@ void * lv_xml_create(lv_obj_t * parent, const char * name, const char ** attrs) lv_xml_component_scope_t * scope = lv_xml_component_get_scope(name); if(scope) { item = lv_xml_create_in_scope(parent, NULL, scope, attrs); - + if(item == NULL) { + LV_LOG_WARN("Couldn't create component."); + return NULL; + } + const char * value_of_name = NULL; if(attrs) { lv_xml_parser_state_t state; lv_xml_parser_state_init(&state); @@ -200,7 +361,20 @@ void * lv_xml_create(lv_obj_t * parent, const char * name, const char ** attrs) p = lv_xml_widget_get_extended_widget_processor(scope->extends); p->apply_cb(&state, attrs); +#if LV_USE_OBJ_NAME + value_of_name = lv_xml_get_value_of(attrs, "name"); + if(value_of_name) lv_obj_set_name(item, value_of_name); +#endif + } + + /*Set a default indexed name for non screens*/ +#if LV_USE_OBJ_NAME + if(lv_obj_get_parent(item) && value_of_name == NULL) { + char name_buf[128]; + lv_snprintf(name_buf, sizeof(name_buf), "%s_#", scope->name); + lv_obj_set_name(item, name_buf); } +#endif return item; } @@ -210,6 +384,21 @@ void * lv_xml_create(lv_obj_t * parent, const char * name, const char ** attrs) return NULL; } + +lv_obj_t * lv_xml_create_screen(const char * name) +{ + return lv_xml_create(NULL, name, NULL); + +} + +void lv_xml_set_default_asset_path(const char * path_prefix) +{ + lv_free((void *)xml_path_prefix); + if(path_prefix == NULL) path_prefix = ""; + xml_path_prefix = lv_strdup(path_prefix); +} + + lv_result_t lv_xml_register_font(lv_xml_component_scope_t * scope, const char * name, const lv_font_t * font) { @@ -222,12 +411,13 @@ lv_result_t lv_xml_register_font(lv_xml_component_scope_t * scope, const char * lv_xml_font_t * f; LV_LL_READ(&scope->font_ll, f) { if(lv_streq(f->name, name)) { - LV_LOG_INFO("Font %s is already registered. Don't register it again.", name); + LV_LOG_INFO("Font `%s` is already registered. Don't register it again.", name); return LV_RESULT_OK; } } f = lv_ll_ins_head(&scope->font_ll); + lv_memzero(f, sizeof(*f)); f->name = lv_strdup(name); f->font = font; @@ -265,16 +455,16 @@ lv_result_t lv_xml_register_subject(lv_xml_component_scope_t * scope, const char return LV_RESULT_INVALID; } - lv_xml_subject_t * s; LV_LL_READ(&scope->subjects_ll, s) { if(lv_streq(s->name, name)) { - LV_LOG_INFO("Subject %s is already registered. Don't register it again.", name); + LV_LOG_INFO("Subject `%s` is already registered. Don't register it again.", name); return LV_RESULT_OK; } } s = lv_ll_ins_head(&scope->subjects_ll); + lv_memzero(s, sizeof(*s)); s->name = lv_strdup(name); s->subject = subject; @@ -304,6 +494,54 @@ lv_subject_t * lv_xml_get_subject(lv_xml_component_scope_t * scope, const char * return NULL; } + +lv_result_t lv_xml_register_timeline(lv_xml_component_scope_t * scope, const char * name) +{ + if(scope == NULL) scope = lv_xml_component_get_scope("globals"); + if(scope == NULL) { + LV_LOG_WARN("No component found to register subject `%s`", name); + return LV_RESULT_INVALID; + } + + lv_xml_timeline_t * at; + LV_LL_READ(&scope->timeline_ll, at) { + if(lv_streq(at->name, name)) { + LV_LOG_INFO("Animation timeline `%s` is already registered. Don't register it again.", name); + return LV_RESULT_OK; + } + } + + at = lv_ll_ins_head(&scope->timeline_ll); + at->name = lv_strdup(name); + lv_ll_init(&at->anims_ll, sizeof(lv_xml_anim_timeline_child_t)); + + return LV_RESULT_OK; +} + +void * lv_xml_get_timeline(lv_xml_component_scope_t * scope, const char * name) +{ + lv_xml_timeline_t * at; + if(scope) { + LV_LL_READ(&scope->timeline_ll, at) { + if(lv_streq(at->name, name)) return at; + } + } + + /*If not found in the component check the global space*/ + if((scope == NULL || scope->name == NULL) || !lv_streq(scope->name, "globals")) { + scope = lv_xml_component_get_scope("globals"); + if(scope) { + LV_LL_READ(&scope->timeline_ll, at) { + if(lv_streq(at->name, name)) return at; + } + } + } + + LV_LOG_WARN("No timeline was found with name \"%s\".", name); + return NULL; +} + + lv_result_t lv_xml_register_const(lv_xml_component_scope_t * scope, const char * name, const char * value) { if(scope == NULL) scope = lv_xml_component_get_scope("globals"); @@ -315,12 +553,13 @@ lv_result_t lv_xml_register_const(lv_xml_component_scope_t * scope, const char * lv_xml_const_t * cnst; LV_LL_READ(&scope->const_ll, cnst) { if(lv_streq(cnst->name, name)) { - LV_LOG_INFO("Const %s is already registered. Don't register it again.", name); + LV_LOG_INFO("Const `%s` is already registered. Don't register it again.", name); return LV_RESULT_OK; } } cnst = lv_ll_ins_head(&scope->const_ll); + lv_memzero(cnst, sizeof(*cnst)); cnst->name = lv_strdup(name); cnst->value = lv_strdup(value); @@ -367,15 +606,18 @@ lv_result_t lv_xml_register_image(lv_xml_component_scope_t * scope, const char * lv_xml_image_t * img; LV_LL_READ(&scope->image_ll, img) { if(lv_streq(img->name, name)) { - LV_LOG_INFO("Image %s is already registered. Don't register it again.", name); + LV_LOG_INFO("Image `%s` is already registered. Don't register it again.", name); return LV_RESULT_OK; } } img = lv_ll_ins_head(&scope->image_ll); + lv_memzero(img, sizeof(*img)); img->name = lv_strdup(name); if(lv_image_src_get_type(src) == LV_IMAGE_SRC_FILE) { - img->src = lv_strdup(src); + char buf[LV_XML_MAX_PATH_LENGTH]; + lv_snprintf(buf, sizeof(buf), "%s%s", xml_path_prefix, src); + img->src = lv_strdup(buf); } else { img->src = src; @@ -421,12 +663,13 @@ lv_result_t lv_xml_register_event_cb(lv_xml_component_scope_t * scope, const cha lv_xml_event_cb_t * e; LV_LL_READ(&scope->event_ll, e) { if(lv_streq(e->name, name)) { - LV_LOG_INFO("Event_cb %s is already registered. Don't register it again.", name); + LV_LOG_INFO("Event_cb `%s` is already registered. Don't register it again.", name); return LV_RESULT_OK; } } e = lv_ll_ins_head(&scope->event_ll); + lv_memzero(e, sizeof(*e)); e->name = lv_strdup(name); e->cb = cb; @@ -487,9 +730,8 @@ static void resolve_params(lv_xml_component_scope_t * item_scope, lv_xml_compone { uint32_t i; for(i = 0; item_attrs[i]; i += 2) { - const char * name = item_attrs[i]; const char * value = item_attrs[i + 1]; - if(lv_streq(name, "styles")) continue; /*Styles will handle it themselves*/ + if(value[0] == '$') { /*E.g. the ${my_color} value is the my_color attribute name on the parent*/ const char * name_clean = &value[1]; /*skips `$`*/ @@ -553,8 +795,9 @@ static void resolve_consts(const char ** item_attrs, lv_xml_component_scope_t * static void view_start_element_handler(void * user_data, const char * name, const char ** attrs) { lv_xml_parser_state_t * state = (lv_xml_parser_state_t *)user_data; - bool is_view = false; + state->tag_name = name; + bool is_view = false; if(lv_streq(name, "view")) { const char * extends = lv_xml_get_value_of(attrs, "extends"); name = extends ? extends : "lv_obj"; @@ -564,7 +807,7 @@ static void view_start_element_handler(void * user_data, const char * name, cons lv_obj_t ** current_parent_p = lv_ll_get_tail(&state->parent_ll); if(current_parent_p == NULL) { if(state->parent == NULL) { - LV_LOG_ERROR("There is no parent object available for %s. This also should never happen.", name); + LV_LOG_ERROR("There is no parent object available for %s. This should never happen.", name); return; } else { @@ -638,5 +881,139 @@ static void view_end_element_handler(void * user_data, const char * name) } } +static lv_anim_timeline_t * get_timeline_by_name(lv_obj_t * obj, const char * timeline_name) +{ + /*Get all the timelines of the target*/ + lv_anim_timeline_t ** timeline_array = NULL; + lv_obj_send_event(obj, lv_event_xml_store_timeline, &timeline_array); + if(timeline_array == NULL) { + LV_LOG_WARN("No time lines are stored in target"); + return NULL; + } + + /*Find the timeline with the requested timeline name*/ + uint32_t i; + for(i = 0; timeline_array[i]; i++) { + const char * name = lv_anim_timeline_get_user_data(timeline_array[i]); + if(lv_streq(name, timeline_name)) return timeline_array[i]; + } + + return NULL; +} + +static void create_timeline_instances(lv_xml_parser_state_t * state) +{ + /*The timeline descriptors ("blueprints") created when the components was registered + *are stored in the "scope". + *Based on the descriptors timeline and animation instances will be created for this this component*/ + lv_xml_component_scope_t * scope = &state->scope; + + if(lv_ll_is_empty(&scope->timeline_ll)) return; + + /*At this stage all children are created so any UI elements that + *the animations and timelines can reference are exist. */ + lv_xml_timeline_t * timeline_dsc; + + /*Create an array to store the created timeline pointers*/ + lv_anim_timeline_t ** timeline_array; + timeline_array = lv_malloc((lv_ll_get_len(&scope->timeline_ll) + 1) * sizeof(lv_anim_timeline_t *)); + LV_ASSERT_MALLOC(timeline_array); + if(timeline_array == NULL) { + LV_LOG_WARN("Couldn't allocate memory"); + return; + } + + /*Read the timeline descriptors of the component and create + *timeline instances based on them.*/ + uint32_t timeline_index = 0; + LV_LL_READ(&scope->timeline_ll, timeline_dsc) { + /*Save the name of the timeline. It will reference by this name in XML + * (e.g. )*/ + lv_anim_timeline_t * my_timeline = lv_anim_timeline_create(); + my_timeline->user_data = lv_strdup(timeline_dsc->name); + LV_ASSERT_MALLOC(my_timeline->user_data); + if(my_timeline->user_data == NULL) { + lv_anim_timeline_delete(my_timeline); + lv_free(timeline_array); + LV_LOG_WARN("Couldn't allocate memory"); + return; + } + /*Check all saved animation or incluce_timeline data of the component + *and add them to the timeline instance. */ + lv_xml_anim_timeline_child_t * timeline_child; + LV_LL_READ(&timeline_dsc->anims_ll, timeline_child) { + /*Simple add the animation descriptors to instance's timeline*/ + if(timeline_child->is_anim) { + lv_anim_t * a = &timeline_child->data.anim; + lv_obj_t * target = NULL; + if(lv_streq(a->var, "self")) target = state->view; + else target = lv_obj_find_by_name(state->view, a->var); + + if(target == NULL) { + LV_LOG_WARN("No target widget is found with `%s` name", (char *)a->var); + continue; + } + + int32_t delay = -a->act_time; + lv_anim_timeline_add(my_timeline, delay, a); + + /*Once the animation descriptor is duplicated and saved in the timeline + *replace the target name a pointer to the target. + *TODO add an event to every referenced widget to remove their anim from the + * timeline when they are deleted.*/ + lv_anim_t * new_a = &my_timeline->anim_dsc[my_timeline->anim_dsc_cnt - 1].anim; + new_a->var = target; + } + /*Or include (merge) the referenced timelines*/ + else { + lv_xml_anim_timeline_include_t * incl = &timeline_child->data.incl; + /*Get the target first*/ + lv_obj_t * target; + if(lv_streq(incl->target_name, "self")) target = state->view; + else target = lv_obj_find_by_name(state->view, incl->target_name); + + if(target == NULL) { + LV_LOG_WARN("No target widget is found with `%s` name", incl->target_name); + continue; + } + + lv_anim_timeline_t * include_timeline = get_timeline_by_name(target, incl->timeline_name); + if(include_timeline == NULL) { + LV_LOG_WARN("Timeline `%s` is not found in `%s` component", incl->timeline_name, incl->target_name); + continue; + } + + /*Copy all animations of include_timeline to this instance's timeline*/ + lv_anim_timeline_merge(my_timeline, include_timeline, incl->delay); + } + } + + timeline_array[timeline_index] = my_timeline; + timeline_index++; + } + + timeline_array[timeline_index] = NULL; /*Closing to avoid storing the length*/ + + lv_obj_add_event_cb(state->view, get_timeline_from_event_cb, lv_event_xml_store_timeline, timeline_array); + lv_obj_add_event_cb(state->view, free_timelines_event_cb, LV_EVENT_DELETE, timeline_array); +} + + +static void get_timeline_from_event_cb(lv_event_t * e) +{ + void ** out = lv_event_get_param(e); + *out = lv_event_get_user_data(e); +} + +static void free_timelines_event_cb(lv_event_t * e) +{ + lv_anim_timeline_t ** at_array = lv_event_get_user_data(e); + uint32_t i; + for(i = 0; at_array[i]; i++) { + lv_free(lv_anim_timeline_get_user_data(at_array[i])); + lv_anim_timeline_delete(at_array[i]); + } + lv_free(at_array); +} #endif /* LV_USE_XML */ diff --git a/src/others/xml/lv_xml.h b/src/others/xml/lv_xml.h index a26e3055ae..59a5f619c0 100644 --- a/src/others/xml/lv_xml.h +++ b/src/others/xml/lv_xml.h @@ -14,15 +14,22 @@ extern "C" { * INCLUDES *********************/ #include "../../misc/lv_types.h" -#include "../../misc/lv_event.h" -#include "../../others/observer/lv_observer.h" #if LV_USE_XML +#include "../../misc/lv_event.h" +#include "../../others/observer/lv_observer.h" +#include "lv_xml_test.h" +#include "lv_xml_translation.h" +#include "lv_xml_component.h" +#include "lv_xml_widget.h" +#include "lv_xml_load.h" /********************* * DEFINES *********************/ +#define LV_XML_MAX_PATH_LENGTH 256 + /********************** * TYPEDEFS **********************/ @@ -33,12 +40,49 @@ extern "C" { void lv_xml_init(void); +void lv_xml_deinit(void); + +/** + * Create a UI element from XML. + * @param parent Pointer to the parent + * @param name The name of an already-registered Component or Widget + * @param attrs Pointer to a list of attribute/value pairs to pass. + * The last two items should be `NULL`. + * @return Pointer to the created UI element + * @example If `name` is "lv_slider" and + * `attrs` is {"width", "100", "value", "30", NULL, NULL}; + * it's equivalent to `` + * @example not only components can be created this way but e.g + * - `name`="lv_chart-series", `attrs`={"color", "0xf00", "axis", "primary_y", NULL, NULL} + * - `name`="style", `attrs`={"name", "style1", "selector", "pressed|knob", NULL, NULL} + * - `name`="bind_flag_if_eq", + * `attrs`={"subject", "subject1", "flag", "hidden", "ref_value", "1", NULL, NULL} + */ void * lv_xml_create(lv_obj_t * parent, const char * name, const char ** attrs); +/** + * Create a Screen from XML. + * @param name The name of an already-registered Screen + * @return Pointer to the created Screen + * @note If required, can be loaded with `lv_screen_load()`. + */ +lv_obj_t * lv_xml_create_screen(const char * name); + void * lv_xml_create_in_scope(lv_obj_t * parent, lv_xml_component_scope_t * parent_ctx, lv_xml_component_scope_t * scope, const char ** attrs); +/** + * Set a path to prefix the image and font file source paths. + * + * In globals.xml usually the source path is like "images/logo.png". + * But on the actual device it can be located at e.g. "A:ui/assets/images/logo.png". + * By setting "A:ui/assets/" the path set in the XML files will be prefixed accordingly. + * + * @param path_prefix the path to be used as prefix + */ +void lv_xml_set_default_asset_path(const char * path_prefix); + lv_result_t lv_xml_register_font(lv_xml_component_scope_t * scope, const char * name, const lv_font_t * font); const lv_font_t * lv_xml_get_font(lv_xml_component_scope_t * scope, const char * name); @@ -73,6 +117,10 @@ lv_result_t lv_xml_register_event_cb(lv_xml_component_scope_t * scope, const cha lv_event_cb_t lv_xml_get_event_cb(lv_xml_component_scope_t * scope, const char * name); +lv_result_t lv_xml_register_timeline(lv_xml_component_scope_t * scope, const char * name); + +void * lv_xml_get_timeline(lv_xml_component_scope_t * scope, const char * name); + /********************** * MACROS **********************/ diff --git a/src/others/xml/lv_xml_base_types.c b/src/others/xml/lv_xml_base_types.c index 389a01e474..f1f4314540 100644 --- a/src/others/xml/lv_xml_base_types.c +++ b/src/others/xml/lv_xml_base_types.c @@ -1,5 +1,5 @@ /** - * @file lv_xml_base_parser.c + * @file lv_xml_base_types.c * */ @@ -153,6 +153,26 @@ lv_text_decor_t lv_xml_text_decor_to_enum(const char * txt) return 0; /*Return 0 in lack of a better option. */ } +lv_scroll_snap_t lv_xml_scroll_snap_to_enum(const char * txt) +{ + if(lv_streq("none", txt)) return LV_SCROLL_SNAP_NONE; + if(lv_streq("start", txt)) return LV_SCROLL_SNAP_START; + if(lv_streq("center", txt)) return LV_SCROLL_SNAP_CENTER; + if(lv_streq("end", txt)) return LV_SCROLL_SNAP_END; + + LV_LOG_WARN("%s is an unknown value for scroll_snap", txt); + return 0; /*Return 0 in lack of a better option. */ +} + +lv_scrollbar_mode_t lv_xml_scrollbar_mode_to_enum(const char * txt) +{ + if(lv_streq("off", txt)) return LV_SCROLLBAR_MODE_OFF; + else if(lv_streq("on", txt)) return LV_SCROLLBAR_MODE_ON; + else if(lv_streq("active", txt)) return LV_SCROLLBAR_MODE_ACTIVE; + else if(lv_streq("auto", txt)) return LV_SCROLLBAR_MODE_AUTO; + return 0; /*Return 0 in lack of a better option. */ +} + lv_flex_flow_t lv_xml_flex_flow_to_enum(const char * txt) { if(lv_streq("column", txt)) return LV_FLEX_FLOW_COLUMN; @@ -218,7 +238,283 @@ lv_blend_mode_t lv_xml_blend_mode_to_enum(const char * txt) return 0; /*Return 0 in lack of a better option. */ } +lv_event_code_t lv_xml_trigger_text_to_enum_value(const char * txt) +{ + if(lv_streq("all", txt)) return LV_EVENT_ALL; + if(lv_streq("pressed", txt)) return LV_EVENT_PRESSED; + if(lv_streq("pressing", txt)) return LV_EVENT_PRESSING; + if(lv_streq("press_lost", txt)) return LV_EVENT_PRESS_LOST; + if(lv_streq("short_clicked", txt)) return LV_EVENT_SHORT_CLICKED; + if(lv_streq("single_clicked", txt)) return LV_EVENT_SINGLE_CLICKED; + if(lv_streq("double_clicked", txt)) return LV_EVENT_DOUBLE_CLICKED; + if(lv_streq("triple_clicked", txt)) return LV_EVENT_TRIPLE_CLICKED; + if(lv_streq("long_pressed", txt)) return LV_EVENT_LONG_PRESSED; + if(lv_streq("long_pressed_repeat", txt)) return LV_EVENT_LONG_PRESSED_REPEAT; + if(lv_streq("clicked", txt)) return LV_EVENT_CLICKED; + if(lv_streq("released", txt)) return LV_EVENT_RELEASED; + if(lv_streq("scroll_begin", txt)) return LV_EVENT_SCROLL_BEGIN; + if(lv_streq("scroll_throw_begin", txt)) return LV_EVENT_SCROLL_THROW_BEGIN; + if(lv_streq("scroll_end", txt)) return LV_EVENT_SCROLL_END; + if(lv_streq("scroll", txt)) return LV_EVENT_SCROLL; + if(lv_streq("gesture", txt)) return LV_EVENT_GESTURE; + if(lv_streq("key", txt)) return LV_EVENT_KEY; + if(lv_streq("rotary", txt)) return LV_EVENT_ROTARY; + if(lv_streq("focused", txt)) return LV_EVENT_FOCUSED; + if(lv_streq("defocused", txt)) return LV_EVENT_DEFOCUSED; + if(lv_streq("leave", txt)) return LV_EVENT_LEAVE; + if(lv_streq("hit_test", txt)) return LV_EVENT_HIT_TEST; + if(lv_streq("indev_reset", txt)) return LV_EVENT_INDEV_RESET; + if(lv_streq("hover_over", txt)) return LV_EVENT_HOVER_OVER; + if(lv_streq("hover_leave", txt)) return LV_EVENT_HOVER_LEAVE; + if(lv_streq("cover_check", txt)) return LV_EVENT_COVER_CHECK; + if(lv_streq("refr_ext_draw_size", txt)) return LV_EVENT_REFR_EXT_DRAW_SIZE; + if(lv_streq("draw_main_begin", txt)) return LV_EVENT_DRAW_MAIN_BEGIN; + if(lv_streq("draw_main", txt)) return LV_EVENT_DRAW_MAIN; + if(lv_streq("draw_main_end", txt)) return LV_EVENT_DRAW_MAIN_END; + if(lv_streq("draw_post_begin", txt)) return LV_EVENT_DRAW_POST_BEGIN; + if(lv_streq("draw_post", txt)) return LV_EVENT_DRAW_POST; + if(lv_streq("draw_post_end", txt)) return LV_EVENT_DRAW_POST_END; + if(lv_streq("draw_task_added", txt)) return LV_EVENT_DRAW_TASK_ADDED; + if(lv_streq("value_changed", txt)) return LV_EVENT_VALUE_CHANGED; + if(lv_streq("insert", txt)) return LV_EVENT_INSERT; + if(lv_streq("refresh", txt)) return LV_EVENT_REFRESH; + if(lv_streq("ready", txt)) return LV_EVENT_READY; + if(lv_streq("cancel", txt)) return LV_EVENT_CANCEL; + if(lv_streq("create", txt)) return LV_EVENT_CREATE; + if(lv_streq("delete", txt)) return LV_EVENT_DELETE; + if(lv_streq("child_changed", txt)) return LV_EVENT_CHILD_CHANGED; + if(lv_streq("child_created", txt)) return LV_EVENT_CHILD_CREATED; + if(lv_streq("child_deleted", txt)) return LV_EVENT_CHILD_DELETED; + if(lv_streq("screen_unload_start", txt)) return LV_EVENT_SCREEN_UNLOAD_START; + if(lv_streq("screen_load_start", txt)) return LV_EVENT_SCREEN_LOAD_START; + if(lv_streq("screen_loaded", txt)) return LV_EVENT_SCREEN_LOADED; + if(lv_streq("screen_unloaded", txt)) return LV_EVENT_SCREEN_UNLOADED; + if(lv_streq("size_changed", txt)) return LV_EVENT_SIZE_CHANGED; + if(lv_streq("style_changed", txt)) return LV_EVENT_STYLE_CHANGED; + if(lv_streq("layout_changed", txt)) return LV_EVENT_LAYOUT_CHANGED; + if(lv_streq("get_self_size", txt)) return LV_EVENT_GET_SELF_SIZE; + if(lv_streq("invalidate_area", txt)) return LV_EVENT_INVALIDATE_AREA; + if(lv_streq("resolution_changed", txt)) return LV_EVENT_RESOLUTION_CHANGED; + if(lv_streq("color_format_changed", txt)) return LV_EVENT_COLOR_FORMAT_CHANGED; + if(lv_streq("refr_request", txt)) return LV_EVENT_REFR_REQUEST; + if(lv_streq("refr_start", txt)) return LV_EVENT_REFR_START; + if(lv_streq("refr_ready", txt)) return LV_EVENT_REFR_READY; + if(lv_streq("render_start", txt)) return LV_EVENT_RENDER_START; + if(lv_streq("render_ready", txt)) return LV_EVENT_RENDER_READY; + if(lv_streq("flush_start", txt)) return LV_EVENT_FLUSH_START; + if(lv_streq("flush_finish", txt)) return LV_EVENT_FLUSH_FINISH; + if(lv_streq("flush_wait_start", txt)) return LV_EVENT_FLUSH_WAIT_START; + if(lv_streq("flush_wait_finish", txt)) return LV_EVENT_FLUSH_WAIT_FINISH; + if(lv_streq("vsync", txt)) return LV_EVENT_VSYNC; + + LV_LOG_WARN("%s is an unknown value for event's trigger", txt); + return LV_EVENT_LAST; /*Indicate error*/ +} + + +lv_screen_load_anim_t lv_xml_screen_load_anim_text_to_enum_value(const char * txt) +{ + if(lv_streq("none", txt)) return LV_SCREEN_LOAD_ANIM_NONE; + if(lv_streq("over_left", txt)) return LV_SCREEN_LOAD_ANIM_OVER_LEFT; + if(lv_streq("over_right", txt)) return LV_SCREEN_LOAD_ANIM_OVER_RIGHT; + if(lv_streq("over_top", txt)) return LV_SCREEN_LOAD_ANIM_OVER_TOP; + if(lv_streq("over_bottom", txt)) return LV_SCREEN_LOAD_ANIM_OVER_BOTTOM; + if(lv_streq("move_left", txt)) return LV_SCREEN_LOAD_ANIM_MOVE_LEFT; + if(lv_streq("move_right", txt)) return LV_SCREEN_LOAD_ANIM_MOVE_RIGHT; + if(lv_streq("move_top", txt)) return LV_SCREEN_LOAD_ANIM_MOVE_TOP; + if(lv_streq("move_bottom", txt)) return LV_SCREEN_LOAD_ANIM_MOVE_BOTTOM; + if(lv_streq("fade_in", txt)) return LV_SCREEN_LOAD_ANIM_FADE_IN; + if(lv_streq("fade_on", txt)) return LV_SCREEN_LOAD_ANIM_FADE_ON; + if(lv_streq("fade_out", txt)) return LV_SCREEN_LOAD_ANIM_FADE_OUT; + if(lv_streq("out_left", txt)) return LV_SCREEN_LOAD_ANIM_OUT_LEFT; + if(lv_streq("out_right", txt)) return LV_SCREEN_LOAD_ANIM_OUT_RIGHT; + if(lv_streq("out_top", txt)) return LV_SCREEN_LOAD_ANIM_OUT_TOP; + if(lv_streq("out_bottom", txt)) return LV_SCREEN_LOAD_ANIM_OUT_BOTTOM; + + LV_LOG_WARN("%s is an unknown value for screen_load_anim", txt); + return LV_SCREEN_LOAD_ANIM_NONE; +} + +lv_style_prop_t lv_xml_style_prop_to_enum(const char * txt) +{ + if(lv_streq(txt, "width")) return LV_STYLE_WIDTH; + if(lv_streq(txt, "min_width")) return LV_STYLE_MIN_WIDTH; + if(lv_streq(txt, "max_width")) return LV_STYLE_MAX_WIDTH; + else if(lv_streq(txt, "height")) return LV_STYLE_HEIGHT; + else if(lv_streq(txt, "min_height")) return LV_STYLE_MIN_HEIGHT; + else if(lv_streq(txt, "max_height")) return LV_STYLE_MAX_HEIGHT; + else if(lv_streq(txt, "length")) return LV_STYLE_LENGTH; + else if(lv_streq(txt, "radius")) return LV_STYLE_RADIUS; + else if(lv_streq(txt, "radial_offset")) return LV_STYLE_RADIAL_OFFSET; + else if(lv_streq(txt, "align")) return LV_STYLE_ALIGN; + + else if(lv_streq(txt, "pad_left")) return LV_STYLE_PAD_LEFT; + else if(lv_streq(txt, "pad_right")) return LV_STYLE_PAD_RIGHT; + else if(lv_streq(txt, "pad_top")) return LV_STYLE_PAD_TOP; + else if(lv_streq(txt, "pad_bottom")) return LV_STYLE_PAD_BOTTOM; + else if(lv_streq(txt, "pad_row")) return LV_STYLE_PAD_ROW; + else if(lv_streq(txt, "pad_column")) return LV_STYLE_PAD_COLUMN; + else if(lv_streq(txt, "pad_radial")) return LV_STYLE_PAD_RADIAL; + + else if(lv_streq(txt, "margin_left")) return LV_STYLE_MARGIN_LEFT; + else if(lv_streq(txt, "margin_right")) return LV_STYLE_MARGIN_RIGHT; + else if(lv_streq(txt, "margin_top")) return LV_STYLE_MARGIN_TOP; + else if(lv_streq(txt, "margin_bottom")) return LV_STYLE_MARGIN_BOTTOM; + + else if(lv_streq(txt, "base_dir")) return LV_STYLE_BASE_DIR; + else if(lv_streq(txt, "clip_corner")) return LV_STYLE_CLIP_CORNER; + + else if(lv_streq(txt, "bg_opa")) return LV_STYLE_BG_OPA; + else if(lv_streq(txt, "bg_color")) return LV_STYLE_BG_COLOR; + else if(lv_streq(txt, "bg_grad_dir")) return LV_STYLE_BG_GRAD_DIR; + else if(lv_streq(txt, "bg_grad_color")) return LV_STYLE_BG_GRAD_COLOR; + else if(lv_streq(txt, "bg_main_stop")) return LV_STYLE_BG_MAIN_STOP; + else if(lv_streq(txt, "bg_grad_stop")) return LV_STYLE_BG_GRAD_STOP; + else if(lv_streq(txt, "bg_grad")) return LV_STYLE_BG_GRAD; + + else if(lv_streq(txt, "bg_image_src")) return LV_STYLE_BG_IMAGE_SRC; + else if(lv_streq(txt, "bg_image_tiled")) return LV_STYLE_BG_IMAGE_TILED; + else if(lv_streq(txt, "bg_image_recolor")) return LV_STYLE_BG_IMAGE_RECOLOR; + else if(lv_streq(txt, "bg_image_recolor_opa")) return LV_STYLE_BG_IMAGE_RECOLOR_OPA; + + else if(lv_streq(txt, "border_color")) return LV_STYLE_BORDER_COLOR; + else if(lv_streq(txt, "border_width")) return LV_STYLE_BORDER_WIDTH; + else if(lv_streq(txt, "border_opa")) return LV_STYLE_BORDER_OPA; + else if(lv_streq(txt, "border_side")) return LV_STYLE_BORDER_SIDE; + else if(lv_streq(txt, "border_post")) return LV_STYLE_BORDER_POST; + + else if(lv_streq(txt, "outline_color")) return LV_STYLE_OUTLINE_COLOR; + else if(lv_streq(txt, "outline_width")) return LV_STYLE_OUTLINE_WIDTH; + else if(lv_streq(txt, "outline_opa")) return LV_STYLE_OUTLINE_OPA; + else if(lv_streq(txt, "outline_pad")) return LV_STYLE_OUTLINE_PAD; + + else if(lv_streq(txt, "shadow_width")) return LV_STYLE_SHADOW_WIDTH; + else if(lv_streq(txt, "shadow_color")) return LV_STYLE_SHADOW_COLOR; + else if(lv_streq(txt, "shadow_offset_x")) return LV_STYLE_SHADOW_OFFSET_X; + else if(lv_streq(txt, "shadow_offset_y")) return LV_STYLE_SHADOW_OFFSET_Y; + else if(lv_streq(txt, "shadow_spread")) return LV_STYLE_SHADOW_SPREAD; + else if(lv_streq(txt, "shadow_opa")) return LV_STYLE_SHADOW_OPA; + + else if(lv_streq(txt, "text_color")) return LV_STYLE_TEXT_COLOR; + else if(lv_streq(txt, "text_font")) return LV_STYLE_TEXT_FONT; + else if(lv_streq(txt, "text_opa")) return LV_STYLE_TEXT_OPA; + else if(lv_streq(txt, "text_align")) return LV_STYLE_TEXT_ALIGN; + else if(lv_streq(txt, "text_letter_space")) return LV_STYLE_TEXT_LETTER_SPACE; + else if(lv_streq(txt, "text_line_space")) return LV_STYLE_TEXT_LINE_SPACE; + else if(lv_streq(txt, "text_decor")) return LV_STYLE_TEXT_DECOR; + + else if(lv_streq(txt, "image_opa")) return LV_STYLE_IMAGE_OPA; + else if(lv_streq(txt, "image_recolor")) return LV_STYLE_IMAGE_RECOLOR; + else if(lv_streq(txt, "image_recolor_opa")) return LV_STYLE_IMAGE_RECOLOR_OPA; + + else if(lv_streq(txt, "line_color")) return LV_STYLE_LINE_COLOR; + else if(lv_streq(txt, "line_opa")) return LV_STYLE_LINE_OPA; + else if(lv_streq(txt, "line_width")) return LV_STYLE_LINE_WIDTH; + else if(lv_streq(txt, "line_dash_width")) return LV_STYLE_LINE_DASH_WIDTH; + else if(lv_streq(txt, "line_dash_gap")) return LV_STYLE_LINE_DASH_GAP; + else if(lv_streq(txt, "line_rounded")) return LV_STYLE_LINE_ROUNDED; + + else if(lv_streq(txt, "arc_color")) return LV_STYLE_ARC_COLOR; + else if(lv_streq(txt, "arc_opa")) return LV_STYLE_ARC_OPA; + else if(lv_streq(txt, "arc_width")) return LV_STYLE_ARC_WIDTH; + else if(lv_streq(txt, "arc_rounded")) return LV_STYLE_ARC_ROUNDED; + else if(lv_streq(txt, "arc_image_src")) return LV_STYLE_ARC_IMAGE_SRC; + + else if(lv_streq(txt, "opa")) return LV_STYLE_OPA; + else if(lv_streq(txt, "opa_layered")) return LV_STYLE_OPA_LAYERED; + else if(lv_streq(txt, "color_filter_opa")) return LV_STYLE_COLOR_FILTER_OPA; + else if(lv_streq(txt, "anim_duration")) return LV_STYLE_ANIM_DURATION; + else if(lv_streq(txt, "blend_mode")) return LV_STYLE_BLEND_MODE; + else if(lv_streq(txt, "transform_width")) return LV_STYLE_TRANSFORM_WIDTH; + else if(lv_streq(txt, "transform_height")) return LV_STYLE_TRANSFORM_HEIGHT; + else if(lv_streq(txt, "translate_x")) return LV_STYLE_TRANSLATE_X; + else if(lv_streq(txt, "translate_y")) return LV_STYLE_TRANSLATE_Y; + else if(lv_streq(txt, "translate_radial")) return LV_STYLE_TRANSLATE_RADIAL; + else if(lv_streq(txt, "transform_scale_x")) return LV_STYLE_TRANSFORM_SCALE_X; + else if(lv_streq(txt, "transform_scale_y")) return LV_STYLE_TRANSFORM_SCALE_Y; + else if(lv_streq(txt, "transform_rotation")) return LV_STYLE_TRANSFORM_ROTATION; + else if(lv_streq(txt, "transform_pivot_x")) return LV_STYLE_TRANSFORM_PIVOT_X; + else if(lv_streq(txt, "transform_pivot_y")) return LV_STYLE_TRANSFORM_PIVOT_Y; + else if(lv_streq(txt, "transform_skew_x")) return LV_STYLE_TRANSFORM_SKEW_X; + else if(lv_streq(txt, "transform_skew_y")) return LV_STYLE_TRANSFORM_SKEW_Y; + else if(lv_streq(txt, "bitmap_mask_src")) return LV_STYLE_BITMAP_MASK_SRC; + else if(lv_streq(txt, "rotary_sensitivity")) return LV_STYLE_ROTARY_SENSITIVITY; + else if(lv_streq(txt, "recolor")) return LV_STYLE_RECOLOR; + else if(lv_streq(txt, "recolor_opa")) return LV_STYLE_RECOLOR_OPA; + + else if(lv_streq(txt, "layout")) return LV_STYLE_LAYOUT; + + else if(lv_streq(txt, "flex_flow")) return LV_STYLE_FLEX_FLOW; + else if(lv_streq(txt, "flex_grow")) return LV_STYLE_FLEX_GROW; + else if(lv_streq(txt, "flex_main_place")) return LV_STYLE_FLEX_MAIN_PLACE; + else if(lv_streq(txt, "flex_cross_place")) return LV_STYLE_FLEX_CROSS_PLACE; + else if(lv_streq(txt, "flex_track_place")) return LV_STYLE_FLEX_TRACK_PLACE; + + else if(lv_streq(txt, "grid_column_align")) return LV_STYLE_GRID_COLUMN_ALIGN; + else if(lv_streq(txt, "grid_row_align")) return LV_STYLE_GRID_ROW_ALIGN; + else if(lv_streq(txt, "grid_cell_column_pos")) return LV_STYLE_GRID_CELL_COLUMN_POS; + else if(lv_streq(txt, "grid_cell_column_span")) return LV_STYLE_GRID_CELL_COLUMN_SPAN; + else if(lv_streq(txt, "grid_cell_x_align")) return LV_STYLE_GRID_CELL_X_ALIGN; + else if(lv_streq(txt, "grid_cell_row_pos")) return LV_STYLE_GRID_CELL_ROW_POS; + else if(lv_streq(txt, "grid_cell_row_span")) return LV_STYLE_GRID_CELL_ROW_SPAN; + else if(lv_streq(txt, "grid_cell_y_align")) return LV_STYLE_GRID_CELL_Y_ALIGN; + + return LV_STYLE_PROP_INV; +} +lv_state_t lv_xml_style_state_to_enum(const char * txt) +{ + if(lv_streq("default", txt)) return LV_STATE_DEFAULT; + else if(lv_streq("pressed", txt)) return LV_STATE_PRESSED; + else if(lv_streq("checked", txt)) return LV_STATE_CHECKED; + else if(lv_streq("scrolled", txt)) return LV_STATE_SCROLLED; + else if(lv_streq("focused", txt)) return LV_STATE_FOCUSED; + else if(lv_streq("focus_key", txt)) return LV_STATE_FOCUS_KEY; + else if(lv_streq("edited", txt)) return LV_STATE_EDITED; + else if(lv_streq("hovered", txt)) return LV_STATE_HOVERED; + else if(lv_streq("disabled", txt)) return LV_STATE_DISABLED; + else if(lv_streq("user_1", txt)) return LV_STATE_USER_1; + else if(lv_streq("user_2", txt)) return LV_STATE_USER_2; + else if(lv_streq("user_3", txt)) return LV_STATE_USER_3; + else if(lv_streq("user_4", txt)) return LV_STATE_USER_4; + + return 0; /*Return 0 in lack of a better option. */ +} + +lv_part_t lv_xml_style_part_to_enum(const char * txt) +{ + if(lv_streq("main", txt)) return LV_PART_MAIN; + else if(lv_streq("scrollbar", txt)) return LV_PART_SCROLLBAR; + else if(lv_streq("indicator", txt)) return LV_PART_INDICATOR; + else if(lv_streq("knob", txt)) return LV_PART_KNOB; + else if(lv_streq("selected", txt)) return LV_PART_SELECTED; + else if(lv_streq("items", txt)) return LV_PART_ITEMS; + else if(lv_streq("cursor", txt)) return LV_PART_CURSOR; + + return 0; /*Return 0 in lack of a better option. */ +} + +lv_style_selector_t lv_xml_style_selector_text_to_enum(const char * str) +{ + if(str == NULL) return 0; + lv_style_selector_t selector = 0; + char buf[256]; + lv_strncpy(buf, str, sizeof(buf)); + + char * bufp = buf; + const char * next = lv_xml_split_str(&bufp, '|'); + + while(next) { + /* Handle different states and parts */ + selector |= lv_xml_style_state_to_enum(next); + selector |= lv_xml_style_part_to_enum(next); + + /* Move to the next token */ + next = lv_xml_split_str(&bufp, '|'); + } + + return selector; +} /********************** * STATIC FUNCTIONS **********************/ diff --git a/src/others/xml/lv_xml_base_types.h b/src/others/xml/lv_xml_base_types.h index 184d0eeec8..a8cc90efa3 100644 --- a/src/others/xml/lv_xml_base_types.h +++ b/src/others/xml/lv_xml_base_types.h @@ -90,6 +90,20 @@ lv_text_align_t lv_xml_text_align_to_enum(const char * txt); */ lv_text_decor_t lv_xml_text_decor_to_enum(const char * txt); +/** + * Convert a scroll snap string to enum + * @param txt e.g. "start" + * @return the related enum, e.g. `LV_SCROLL_SNAP_START` + */ +lv_scroll_snap_t lv_xml_scroll_snap_to_enum(const char * txt); + +/** + * Convert a scrollbar mode string to enum + * @param txt e.g. "active" + * @return the related enum, e.g. `LV_SCROLLBAR_MODE_ACTIVE` + */ +lv_scrollbar_mode_t lv_xml_scrollbar_mode_to_enum(const char * txt); + /** * Convert a flex flow string to enum * @param txt e.g. "row_wrap" @@ -125,6 +139,51 @@ lv_layout_t lv_xml_layout_to_enum(const char * txt); */ lv_blend_mode_t lv_xml_blend_mode_to_enum(const char * txt); +/** + * Convert an event trigger string to enum + * @param txt e.g. "clicked" + * @return the related enum, e.g. `LV_EVENT_CLICKED` + */ +lv_event_code_t lv_xml_trigger_text_to_enum_value(const char * txt); + +/** + * Convert a screen animation type string to enum + * @param txt e.g. "over_right" + * @return the related enum, e.g. `LV_SCREEN_LOAD_ANIM_OVER_RIGHT` + */ +lv_screen_load_anim_t lv_xml_screen_load_anim_text_to_enum_value(const char * txt); + +/** + * Convert a style property string to enum + * @param txt e.g. "bg_color" + * @return the related enum, e.g. `LV_STYLE_BG_COLOR` or + * `LV_STYLE_PROP_INV` if not found. + */ +lv_style_prop_t lv_xml_style_prop_to_enum(const char * txt); + + +/** + * Convert a style state to enum + * @param txt e.g. "pressed" + * @return the enum `LV_STATE_PRESSED` + */ +lv_state_t lv_xml_style_state_to_enum(const char * txt); + +/** + * Convert a style part to enum + * @param txt e.g. "knob" + * @return the enum `LV_PART_KNOB` + */ +lv_part_t lv_xml_style_part_to_enum(const char * txt); + + +/** + * Convert ORed style parts and states to an ORed selector + * @param txt e.g. "knob|pressed" + * @return the enum `LV_PART_KNOB|LV_STATE_PRESSED` + */ +lv_style_selector_t lv_xml_style_selector_text_to_enum(const char * str); + /********************** * MACROS **********************/ diff --git a/src/others/xml/lv_xml_component.c b/src/others/xml/lv_xml_component.c index 9344fe4288..a2db69fe0b 100644 --- a/src/others/xml/lv_xml_component.c +++ b/src/others/xml/lv_xml_component.c @@ -19,15 +19,21 @@ #include "parsers/lv_xml_obj_parser.h" #include "../../libs/expat/expat.h" #include "../../misc/lv_fs.h" +#include "../../core/lv_global.h" #include /********************* * DEFINES *********************/ +#define xml_path_prefix LV_GLOBAL_DEFAULT()->xml_path_prefix /********************** * TYPEDEFS **********************/ +typedef enum { + STYLE_PROP_TYPE_INT, + STYLE_PROP_TYPE_UNKNOWN +} style_prop_anim_type_t; /********************** * STATIC PROTOTYPES @@ -39,6 +45,9 @@ static void process_font_element(lv_xml_parser_state_t * state, const char * typ static void process_image_element(lv_xml_parser_state_t * state, const char * type, const char ** attrs); static void process_prop_element(lv_xml_parser_state_t * state, const char ** attrs); static char * extract_view_content(const char * xml_definition); +static style_prop_anim_type_t style_prop_anim_get_type(lv_style_prop_t prop); +static int32_t anim_value_to_int(lv_style_prop_t prop_type, const char * value_str); +static void int_anim_exec_cb(lv_anim_t * a, int32_t v); /********************** * STATIC VARIABLES @@ -60,9 +69,9 @@ void lv_xml_component_init(void) lv_xml_component_scope_t * global_scope = lv_ll_ins_head(&component_scope_ll); lv_memzero(global_scope, sizeof(lv_xml_component_scope_t)); + lv_xml_component_scope_init(global_scope); global_scope->name = lv_strdup("globals"); - } void lv_xml_component_scope_init(lv_xml_component_scope_t * scope) @@ -75,6 +84,7 @@ void lv_xml_component_scope_init(lv_xml_component_scope_t * scope) lv_ll_init(&scope->event_ll, sizeof(lv_xml_event_cb_t)); lv_ll_init(&scope->image_ll, sizeof(lv_xml_image_t)); lv_ll_init(&scope->font_ll, sizeof(lv_xml_font_t)); + lv_ll_init(&scope->timeline_ll, sizeof(lv_xml_timeline_t)); } @@ -93,7 +103,6 @@ lv_obj_t * lv_xml_component_process(lv_xml_parser_state_t * state, const char * lv_widget_processor_t * extended_proc = lv_xml_widget_get_extended_widget_processor(scope->extends); extended_proc->apply_cb(state, attrs); - #if LV_USE_OBJ_NAME /*Set a default indexed name*/ if(state->item) { @@ -119,7 +128,7 @@ lv_xml_component_scope_t * lv_xml_component_get_scope(const char * component_nam return NULL; } -lv_result_t lv_xml_component_register_from_data(const char * name, const char * xml_def) +lv_result_t lv_xml_register_component_from_data(const char * name, const char * xml_def) { bool globals = false; if(lv_streq(name, "globals")) globals = true; @@ -145,7 +154,7 @@ lv_result_t lv_xml_component_register_from_data(const char * name, const char * XML_SetElementHandler(parser, start_metadata_handler, end_metadata_handler); if(XML_Parse(parser, xml_def, lv_strlen(xml_def), XML_TRUE) == XML_STATUS_ERROR) { - LV_LOG_ERROR("XML parsing error: %s on line %lu", + LV_LOG_ERROR("XML parsing error; %s on line %lu", XML_ErrorString(XML_GetErrorCode(parser)), (unsigned long)XML_GetCurrentLineNumber(parser)); XML_ParserFree(parser); @@ -172,7 +181,7 @@ lv_result_t lv_xml_component_register_from_data(const char * name, const char * if(!scope->view_def) { LV_LOG_WARN("Failed to extract view content"); /* Clean up and return error */ - lv_free(scope); + lv_xml_component_unregister(name); return LV_RESULT_INVALID; } } @@ -181,7 +190,7 @@ lv_result_t lv_xml_component_register_from_data(const char * name, const char * } -lv_result_t lv_xml_component_register_from_file(const char * path) +lv_result_t lv_xml_register_component_from_file(const char * path) { /* Extract component name from path */ /* Create a copy of the filename to modify */ @@ -228,7 +237,7 @@ lv_result_t lv_xml_component_register_from_file(const char * path) xml_buf[rn] = '\0'; /* Register the component */ - lv_result_t res = lv_xml_component_register_from_data(filename, xml_buf); + lv_result_t res = lv_xml_register_component_from_data(filename, xml_buf); /* Housekeeping */ lv_free(filename); @@ -304,6 +313,23 @@ lv_result_t lv_xml_component_unregister(const char * name) } lv_ll_clear(&scope->subjects_ll); + lv_xml_timeline_t * timeline; + LV_LL_READ(&scope->timeline_ll, timeline) { + lv_xml_anim_timeline_child_t * child; + LV_LL_READ(&timeline->anims_ll, child) { + if(child->is_anim) { + lv_free(child->data.anim.var); /*It was the name of the target object*/ + } + else { + lv_free((void *) child->data.incl.target_name); + lv_free((void *) child->data.incl.timeline_name); + } + } + lv_ll_clear(&timeline->anims_ll); + lv_free((char *)timeline->name); + } + lv_ll_clear(&scope->timeline_ll); + lv_free(scope); return LV_RESULT_OK; @@ -350,6 +376,9 @@ static void process_font_element(lv_xml_parser_state_t * state, const char * typ return; } + char src_path_full[LV_XML_MAX_PATH_LENGTH]; + lv_snprintf(src_path_full, sizeof(src_path_full), "%s%s", xml_path_prefix, src_path); + lv_xml_font_t * f; LV_LL_READ(&state->scope.font_ll, f) { if(lv_streq(f->name, name)) { @@ -366,7 +395,7 @@ static void process_font_element(lv_xml_parser_state_t * state, const char * typ return; } #if LV_TINY_TTF_FILE_SUPPORT - lv_font_t * font = lv_tiny_ttf_create_file(src_path, lv_xml_atoi(size)); + lv_font_t * font = lv_tiny_ttf_create_file(src_path_full, lv_xml_atoi(size)); if(font == NULL) { LV_LOG_WARN("Couldn't load `%s` tiny_ttf font", name); return; @@ -393,7 +422,7 @@ static void process_font_element(lv_xml_parser_state_t * state, const char * typ #endif } else if(lv_streq(type, "bin")) { - lv_font_t * font = lv_binfont_create(src_path); + lv_font_t * font = lv_binfont_create(src_path_full); if(font == NULL) { LV_LOG_WARN("Couldn't load `%s` bin font", name); return; @@ -456,9 +485,22 @@ static void process_subject_element(lv_xml_parser_state_t * state, const char * return; } - lv_subject_t * subject = lv_malloc(sizeof(lv_subject_t)); + lv_subject_t * subject = lv_zalloc(sizeof(lv_subject_t)); + const char * min_value_str = lv_xml_get_value_of(attrs, "min_value"); + const char * max_value_str = lv_xml_get_value_of(attrs, "max_value"); - if(lv_streq(type, "int")) lv_subject_init_int(subject, lv_xml_atoi(value)); + if(lv_streq(type, "int")) { + lv_subject_init_int(subject, lv_xml_atoi(value)); + if(min_value_str) lv_subject_set_min_value_int(subject, lv_xml_atoi(min_value_str)); + if(max_value_str) lv_subject_set_max_value_int(subject, lv_xml_atoi(max_value_str)); + } +#if LV_USE_FLOAT + else if(lv_streq(type, "float")) { + lv_subject_init_float(subject, lv_xml_atof(value)); + if(min_value_str) lv_subject_set_min_value_float(subject, lv_xml_atof(min_value_str)); + if(max_value_str) lv_subject_set_max_value_float(subject, lv_xml_atof(max_value_str)); + } +#endif else if(lv_streq(type, "color")) lv_subject_init_color(subject, lv_xml_to_color(value)); else if(lv_streq(type, "string")) { /*Simple solution for now. Will be improved later*/ @@ -470,9 +512,185 @@ static void process_subject_element(lv_xml_parser_state_t * state, const char * lv_xml_register_subject(&state->scope, name, subject); } +static void process_timeline_element(lv_xml_parser_state_t * state, const char ** attrs) +{ + const char * name = lv_xml_get_value_of(attrs, "name"); + + if(name == NULL) { + LV_LOG_WARN("'name' is missing from a timeline"); + return; + } + + /*If already registered skip all. Don't set state->context + *so animations won't be added later either*/ + lv_xml_timeline_t * at; + LV_LL_READ(&state->scope.timeline_ll, at) { + if(lv_streq(at->name, name)) { + LV_LOG_INFO("Timeline %s is already registered. Don't register it again.", name); + return; + } + } + + lv_xml_register_timeline(&state->scope, name); + + /*Save the created timeline so that animations can be added to it later*/ + state->context = lv_xml_get_timeline(&state->scope, name); +} + +static void process_animation_element(lv_xml_parser_state_t * state, const char ** attrs) +{ + if(state->context == NULL) { + LV_LOG_INFO("No parent timeline is set, skipping"); + return; + } + + const char * target_str = lv_xml_get_value_of(attrs, "target"); + const char * prop_str = lv_xml_get_value_of(attrs, "prop"); + const char * start_str = lv_xml_get_value_of(attrs, "start"); + const char * end_str = lv_xml_get_value_of(attrs, "end"); + const char * duration_str = lv_xml_get_value_of(attrs, "duration"); + const char * delay_str = lv_xml_get_value_of(attrs, "delay"); + const char * early_apply_str = lv_xml_get_value_of(attrs, "early_apply"); + const char * selector_str = lv_xml_get_value_of(attrs, "selector"); + + if(target_str == NULL) { + LV_LOG_WARN("'target' is missing from a animation"); + return; + } + + if(prop_str == NULL) { + LV_LOG_WARN("'prop' is missing from a animation"); + return; + } + + lv_style_prop_t prop = lv_xml_style_prop_to_enum(prop_str); + if(prop == LV_STYLE_PROP_INV) { + LV_LOG_WARN("Unknown style property; '%s'", prop_str); + return; + } + + style_prop_anim_type_t prop_type = style_prop_anim_get_type(prop); + if(prop_type == STYLE_PROP_TYPE_UNKNOWN) { + LV_LOG_WARN("Style property '%s' is not animateable", prop_str); + return; + } + + if(start_str == NULL) { + LV_LOG_WARN("'start' is missing from a animation"); + return; + } + + if(end_str == NULL) { + LV_LOG_WARN("'end' is missing from a animation"); + return; + } + + if(duration_str == NULL) duration_str = "1000"; + if(delay_str == NULL) delay_str = "0"; + if(early_apply_str == NULL) early_apply_str = "false"; + if(selector_str == NULL) selector_str = ""; + + lv_style_selector_t selector = lv_xml_style_selector_text_to_enum(selector_str); + + int32_t start = anim_value_to_int(prop_type, start_str); + int32_t end = anim_value_to_int(prop_type, end_str); + + + if(target_str[0] == '#') target_str = lv_xml_get_const(&state->scope, &target_str[1]); + if(prop_str[0] == '#') prop_str = lv_xml_get_const(&state->scope, &prop_str[1]); + if(start_str[0] == '#') start_str = lv_xml_get_const(&state->scope, &start_str[1]); + if(end_str[0] == '#') end_str = lv_xml_get_const(&state->scope, &end_str[1]); + if(duration_str[0] == '#') duration_str = lv_xml_get_const(&state->scope, &duration_str[1]); + if(delay_str[0] == '#') delay_str = lv_xml_get_const(&state->scope, &delay_str[1]); + if(early_apply_str[0] == '#') early_apply_str = lv_xml_get_const(&state->scope, &early_apply_str[1]); + + lv_xml_timeline_t * at = state->context; + if(at == NULL) { + LV_LOG_WARN("There was no parent timeline for the animation"); + return; + } + + if(!target_str || !prop_str || !start_str || !end_str || !duration_str || !delay_str || !early_apply_str) { + LV_LOG_WARN("Couldn't resolve one or more constants. Skipping the animation."); + return; + } + + uint32_t selector_and_prop = ((prop & 0xff) << 24) | selector; + + lv_xml_anim_timeline_child_t * child = lv_ll_ins_tail(&at->anims_ll); + child->is_anim = true; + lv_anim_t * a = &child->data.anim; + + lv_anim_init(a); + lv_anim_set_var(a, lv_strdup(target_str)); + lv_anim_set_values(a, start, end); + lv_anim_set_custom_exec_cb(a, int_anim_exec_cb); + lv_anim_set_duration(a, lv_xml_atoi(duration_str)); + lv_anim_set_delay(a, lv_xml_atoi(delay_str)); + lv_anim_set_early_apply(a, lv_xml_to_bool(early_apply_str)); + lv_anim_set_user_data(a, (void *)((uintptr_t)selector_and_prop)); +} + +static void process_include_timeline_element(lv_xml_parser_state_t * state, const char ** attrs) +{ + lv_xml_timeline_t * at = state->context; + if(at == NULL) { + LV_LOG_INFO("No parent timeline is set, skipping"); + return; + } + + const char * target_str = lv_xml_get_value_of(attrs, "target"); + const char * timeline_str = lv_xml_get_value_of(attrs, "timeline"); + const char * delay_str = lv_xml_get_value_of(attrs, "delay"); + + + if(target_str == NULL) { + LV_LOG_WARN("'target' is missing from timeline include"); + return; + } + + if(timeline_str == NULL) { + LV_LOG_WARN("'timeline' is missing from timeline include"); + return; + } + + if(delay_str == NULL) delay_str = "0"; + if(target_str[0] == '#') target_str = lv_xml_get_const(&state->scope, &target_str[1]); + if(timeline_str[0] == '#') timeline_str = lv_xml_get_const(&state->scope, &timeline_str[1]); + if(delay_str[0] == '#') delay_str = lv_xml_get_const(&state->scope, &delay_str[1]); + + if(!target_str || !timeline_str || !delay_str) { + LV_LOG_WARN("Couldn't resolve one or more constants. Skipping the timeline include."); + return; + } + + lv_xml_anim_timeline_child_t * child = lv_ll_ins_tail(&at->anims_ll); + LV_ASSERT_MALLOC(child); + if(child == NULL) { + LV_LOG_WARN("Couldn't allocate memory"); + return; + } + + child->is_anim = false; + child->data.incl.delay = lv_xml_atoi(delay_str); + child->data.incl.target_name = lv_strdup(target_str); + LV_ASSERT_MALLOC(child->data.incl.target_name); + child->data.incl.timeline_name = lv_strdup(timeline_str); + LV_ASSERT_MALLOC(child->data.incl.timeline_name); + + if(child->data.incl.target_name == NULL || child->data.incl.timeline_name == NULL) { + LV_LOG_WARN("Couldn't allocate memory"); + lv_free((void *)child->data.incl.target_name); + lv_free((void *)child->data.incl.timeline_name); + lv_ll_remove(&at->anims_ll, child); + } +} + static void process_grad_element(lv_xml_parser_state_t * state, const char * tag_name, const char ** attrs) { lv_xml_grad_t * grad = lv_ll_ins_tail(&state->scope.gradient_ll); + lv_memzero(grad, sizeof(lv_xml_grad_t)); + grad->name = lv_strdup(lv_xml_get_value_of(attrs, "name")); lv_grad_dsc_t * dsc = &grad->grad_dsc; lv_memzero(dsc, sizeof(lv_grad_dsc_t)); @@ -596,7 +814,7 @@ static void process_grad_element(lv_xml_parser_state_t * state, const char * tag dsc->dir = LV_GRAD_DIR_VER; } else { - LV_LOG_WARN("Unknown gradient type: %s", tag_name); + LV_LOG_WARN("Unknown gradient type; %s", tag_name); } } @@ -627,6 +845,8 @@ static void process_grad_stop_element(lv_xml_parser_state_t * state, const char static void process_prop_element(lv_xml_parser_state_t * state, const char ** attrs) { lv_xml_param_t * prop = lv_ll_ins_tail(&state->scope.param_ll); + lv_memzero(prop, sizeof(lv_xml_param_t)); + prop->name = lv_strdup(lv_xml_get_value_of(attrs, "name")); const char * def = lv_xml_get_value_of(attrs, "default"); if(def) prop->def = lv_strdup(def); @@ -652,6 +872,7 @@ static void start_metadata_handler(void * user_data, const char * name, const ch } if(lv_streq(name, "widget")) state->scope.is_widget = 1; + else if(lv_streq(name, "screen")) state->scope.is_screen = 1; /* Process elements based on current context */ switch(state->section) { @@ -676,7 +897,7 @@ static void start_metadata_handler(void * user_data, const char * name, const ch case LV_XML_PARSER_SECTION_STYLES: if(old_section != state->section) return; /*Ignore the section opening, e.g. */ - lv_xml_style_register(&state->scope, attrs); + lv_xml_register_style(&state->scope, attrs); break; case LV_XML_PARSER_SECTION_FONTS: @@ -693,7 +914,15 @@ static void start_metadata_handler(void * user_data, const char * name, const ch if(old_section != state->section) return; /*Ignore the section opening, e.g. */ process_subject_element(state, name, attrs); break; - + case LV_XML_PARSER_SECTION_TIMELINE: + process_timeline_element(state, attrs); + break; + case LV_XML_PARSER_SECTION_ANIMATION: + process_animation_element(state, attrs); + break; + case LV_XML_PARSER_SECTION_INCLUDE_TIMELINE: + process_include_timeline_element(state, attrs); + break; default: break; } @@ -737,4 +966,95 @@ static char * extract_view_content(const char * xml_definition) return view_content; } + +static style_prop_anim_type_t style_prop_anim_get_type(lv_style_prop_t prop) +{ + switch(prop) { + case LV_STYLE_WIDTH: + case LV_STYLE_MIN_WIDTH: + case LV_STYLE_MAX_WIDTH: + case LV_STYLE_HEIGHT: + case LV_STYLE_MIN_HEIGHT: + case LV_STYLE_MAX_HEIGHT: + case LV_STYLE_LENGTH: + case LV_STYLE_RADIUS: + case LV_STYLE_PAD_LEFT: + case LV_STYLE_PAD_RIGHT: + case LV_STYLE_PAD_TOP: + case LV_STYLE_PAD_BOTTOM: + case LV_STYLE_PAD_ROW: + case LV_STYLE_PAD_COLUMN: + case LV_STYLE_PAD_RADIAL: + case LV_STYLE_MARGIN_LEFT: + case LV_STYLE_MARGIN_RIGHT: + case LV_STYLE_MARGIN_TOP: + case LV_STYLE_MARGIN_BOTTOM: + case LV_STYLE_BG_OPA: + case LV_STYLE_BG_MAIN_STOP: + case LV_STYLE_BG_GRAD_STOP: + case LV_STYLE_BG_IMAGE_RECOLOR_OPA: + case LV_STYLE_BORDER_WIDTH: + case LV_STYLE_BORDER_OPA: + case LV_STYLE_OUTLINE_WIDTH: + case LV_STYLE_OUTLINE_OPA: + case LV_STYLE_OUTLINE_PAD: + case LV_STYLE_SHADOW_WIDTH: + case LV_STYLE_SHADOW_OFFSET_X: + case LV_STYLE_SHADOW_OFFSET_Y: + case LV_STYLE_SHADOW_SPREAD: + case LV_STYLE_SHADOW_OPA: + case LV_STYLE_TEXT_OPA: + case LV_STYLE_TEXT_LETTER_SPACE: + case LV_STYLE_TEXT_LINE_SPACE: + case LV_STYLE_IMAGE_OPA: + case LV_STYLE_IMAGE_RECOLOR_OPA: + case LV_STYLE_LINE_OPA: + case LV_STYLE_LINE_WIDTH: + case LV_STYLE_LINE_DASH_WIDTH: + case LV_STYLE_LINE_DASH_GAP: + case LV_STYLE_ARC_OPA: + case LV_STYLE_ARC_WIDTH: + case LV_STYLE_OPA: + case LV_STYLE_OPA_LAYERED: + case LV_STYLE_COLOR_FILTER_OPA: + case LV_STYLE_TRANSFORM_WIDTH: + case LV_STYLE_TRANSFORM_HEIGHT: + case LV_STYLE_TRANSLATE_X: + case LV_STYLE_TRANSLATE_Y: + case LV_STYLE_TRANSLATE_RADIAL: + case LV_STYLE_TRANSFORM_SCALE_X: + case LV_STYLE_TRANSFORM_SCALE_Y: + case LV_STYLE_TRANSFORM_ROTATION: + case LV_STYLE_TRANSFORM_PIVOT_X: + case LV_STYLE_TRANSFORM_PIVOT_Y: + case LV_STYLE_RECOLOR_OPA: + return STYLE_PROP_TYPE_INT; + + default: + return STYLE_PROP_TYPE_UNKNOWN; + + } +} + +static int32_t anim_value_to_int(lv_style_prop_t prop_type, const char * value_str) +{ + if(prop_type == STYLE_PROP_TYPE_INT) { + return lv_xml_atoi(value_str); + } + + return 0; +} + +static void int_anim_exec_cb(lv_anim_t * a, int32_t v) +{ + uint32_t data = (lv_uintptr_t)lv_anim_get_user_data(a); + lv_style_prop_t prop = data >> 24; + lv_style_selector_t selector = data & 0x00ffffff; + + lv_style_value_t style_value; + style_value.num = v; + lv_obj_set_local_style_prop(a->var, prop, style_value, selector); +} + + #endif /* LV_USE_XML */ diff --git a/src/others/xml/lv_xml_component.h b/src/others/xml/lv_xml_component.h index 31837edee2..c1c71d515e 100644 --- a/src/others/xml/lv_xml_component.h +++ b/src/others/xml/lv_xml_component.h @@ -3,8 +3,8 @@ * */ -#ifndef LV_LABEL_XML_COMPONENT_H -#define LV_LABEL_XML_COMPONENT_H +#ifndef LV_XML_COMPONENT_H +#define LV_XML_COMPONENT_H #ifdef __cplusplus extern "C" { @@ -34,25 +34,25 @@ extern "C" { lv_obj_t * lv_xml_component_process(lv_xml_parser_state_t * state, const char * name, const char ** attrs); /** - * Load the styles, constants, another data of the component. It needs to be called only once for each component. - * @param name the name as the component will be referenced later in other components - * @param xml_def the XML definition of the component as a NULL terminated string - * @return LV_RES_OK: loaded successfully, LV_RES_INVALID: otherwise + * Load the styles, constants, and other data of the Component. It needs to be called only once for each Component. + * @param name The name as the component will be referenced later in other components + * @param xml_def The XML definition of the component as a NULL terminated string + * @return LV_RESULT_OK: loaded successfully, LV_RES_INVALID: otherwise */ -lv_result_t lv_xml_component_register_from_data(const char * name, const char * xml_def); +lv_result_t lv_xml_register_component_from_data(const char * name, const char * xml_def); /** - * Load the styles, constants, another data of the component. It needs to be called only once for each component. - * @param path path to an XML file - * @return LV_RES_OK: loaded successfully, LV_RES_INVALID: otherwise + * Load the styles, constants, and other data of the Component. It needs to be called only once for each Component. + * @param path Path to an XML file + * @return LV_RESULT_OK: loaded successfully, LV_RES_INVALID: otherwise */ -lv_result_t lv_xml_component_register_from_file(const char * path); +lv_result_t lv_xml_register_component_from_file(const char * path); /** - * Get the scope of a component which was registered by - * `lv_xml_component_register_from_data` or `lv_xml_component_register_from_file` - * @param component_name name of the component - * @return pointer the scope or NULL if not found + * Get the scope of a Component which was registered by + * `lv_xml_register_component_from_data()` or `lv_xml_register_component_from_file()` + * @param component_name Name of the Component + * @return Pointer to the scope or NULL if not found */ lv_xml_component_scope_t * lv_xml_component_get_scope(const char * component_name); diff --git a/src/others/xml/lv_xml_component_private.h b/src/others/xml/lv_xml_component_private.h index 9b84eb4ee0..90fbf525b3 100644 --- a/src/others/xml/lv_xml_component_private.h +++ b/src/others/xml/lv_xml_component_private.h @@ -34,12 +34,14 @@ struct _lv_xml_component_scope_t { lv_ll_t param_ll; lv_ll_t gradient_ll; lv_ll_t subjects_ll; + lv_ll_t timeline_ll; lv_ll_t font_ll; lv_ll_t image_ll; lv_ll_t event_ll; const char * view_def; const char * extends; - uint32_t is_widget : 1; /*1: not component but widget registered as a component for preview*/ + uint32_t is_widget : 1; + uint32_t is_screen : 1; struct _lv_xml_component_scope_t * next; }; @@ -53,6 +55,11 @@ typedef struct { lv_subject_t * subject; } lv_xml_subject_t; +typedef struct { + const char * name; + lv_ll_t anims_ll; +} lv_xml_timeline_t; + typedef struct { const char * name; const char * def; diff --git a/src/others/xml/lv_xml_load.c b/src/others/xml/lv_xml_load.c new file mode 100644 index 0000000000..cd3c4396fd --- /dev/null +++ b/src/others/xml/lv_xml_load.c @@ -0,0 +1,361 @@ +/** + * @file lv_xml_load.c + * + */ + +/********************* + * INCLUDES + *********************/ + +#include "lv_xml_load_private.h" +#if LV_USE_XML + +#include "lv_xml_private.h" +#include "../../core/lv_global.h" +#include "../../misc/lv_fs.h" +#include "../../libs/fsdrv/lv_fsdrv.h" +#include "../../misc/lv_ll.h" +#include "../../libs/expat/expat.h" + +/********************* + * DEFINES + *********************/ + +#define xml_loads LV_GLOBAL_DEFAULT()->xml_loads +#define PATH_PREFIX_BUF_SIZE 32 +#define PATH_PREFIX_FMT "__LV_XML_%p" + +/********************** + * TYPEDEFS + **********************/ + +typedef enum { + LV_XML_TYPE_UNKNOWN, + LV_XML_TYPE_COMPONENT, + LV_XML_TYPE_TRANSLATIONS, +} lv_xml_type_t; + +typedef struct { + XML_Parser parser; + lv_xml_type_t type; +} load_from_path_parser_data_t; + +struct _lv_xml_load_t { + const void * blob; +}; + +/********************** + * STATIC PROTOTYPES + **********************/ + +static lv_result_t load_all_recursive(char * path_buf, const char * path); +static void load_from_path(const char * path); +static char * path_filename_without_extension(const char * path); +static void load_from_path_start_element_handler(void * user_data, const char * name, const char ** attrs); + +/********************** + * STATIC VARIABLES + **********************/ + +/********************** + * MACROS + **********************/ + +/********************** + * GLOBAL FUNCTIONS + **********************/ + +void lv_xml_load_init(void) +{ + lv_ll_init(&xml_loads, sizeof(lv_xml_load_t)); +} + +void lv_xml_load_deinit(void) +{ +#if LV_USE_FS_FROGFS + lv_xml_unload(NULL); +#endif +} + +lv_result_t lv_xml_load_all_from_path(const char * path) +{ + char path_buf[LV_FS_MAX_PATH_LENGTH]; + + /* set the default asset path to the pack path so XML asset paths are relative to it */ + const char * asset_path = path; + /* end the asset path with a '/' */ + char path_last_char = path[0] ? path[lv_strlen(path) - 1] : '\0'; + if(path_last_char != '\0' && path_last_char != ':' + && path_last_char != '/' && path_last_char != '\\') { + lv_snprintf(path_buf, sizeof(path_buf), "%s/", path); + asset_path = path_buf; + } + lv_xml_set_default_asset_path(asset_path); + + return load_all_recursive(path_buf, path); +} + +#if LV_USE_FS_FROGFS +lv_xml_load_t * lv_xml_load_all_from_data(const void * buf, uint32_t buf_size) +{ + LV_UNUSED(buf_size); /* keep it as a parameter for future implementations */ + + lv_xml_load_t * load = lv_ll_ins_head(&xml_loads); + LV_ASSERT_MALLOC(load); + if(load == NULL) return NULL; + lv_memzero(load, sizeof(*load)); + + char path_prefix_with_letter[PATH_PREFIX_BUF_SIZE]; + lv_snprintf(path_prefix_with_letter, sizeof(path_prefix_with_letter), "%c:"PATH_PREFIX_FMT, LV_FS_FROGFS_LETTER, load); + char * path_prefix = path_prefix_with_letter + 2; + + lv_result_t res = lv_fs_frogfs_register_blob(buf, path_prefix); + if(res != LV_RESULT_OK) { + LV_LOG_WARN("could not register the XML data blob"); + lv_ll_remove(&xml_loads, load); + lv_free(load); + return NULL; + } + + res = lv_xml_load_all_from_path(path_prefix_with_letter); + if(res != LV_RESULT_OK) { + lv_fs_frogfs_unregister_blob(path_prefix); + lv_ll_remove(&xml_loads, load); + lv_free(load); + return NULL; + } + + return load; +} + +lv_xml_load_t * lv_xml_load_all_from_file(const char * file_path) +{ + lv_fs_res_t fs_res; + + uint32_t blob_size; + fs_res = lv_fs_path_get_size(file_path, &blob_size); + if(fs_res != LV_FS_RES_OK) { + LV_LOG_WARN("could not get the size of the file to load XML data from"); + return NULL; + } + + void * blob = lv_malloc(blob_size); + LV_ASSERT_MALLOC(blob); + if(blob == NULL) { + LV_LOG_WARN("could not allocate memory for the XML file blob"); + return NULL; + } + + fs_res = lv_fs_load_to_buf(blob, blob_size, file_path); + if(fs_res != LV_FS_RES_OK) { + LV_LOG_WARN("could not read the XML file blob"); + lv_free(blob); + return NULL; + } + + lv_xml_load_t * load = lv_xml_load_all_from_data(blob, blob_size); + if(load == NULL) { + lv_free(blob); + return NULL; + } + + load->blob = blob; + + return load; +} + +void lv_xml_unload(lv_xml_load_t * load) +{ + if(load == NULL) { + lv_ll_clear_custom(&xml_loads, (void (*)(void *)) lv_xml_unload); + return; + } + + char path_prefix[PATH_PREFIX_BUF_SIZE]; + lv_snprintf(path_prefix, sizeof(path_prefix), PATH_PREFIX_FMT, load); + + lv_fs_frogfs_unregister_blob(path_prefix); + + lv_free((void *) load->blob); /* it may be NULL */ + lv_ll_remove(&xml_loads, load); + lv_free(load); +} +#endif /*LV_USE_FS_FROGFS*/ + +/********************** + * STATIC FUNCTIONS + **********************/ + +static lv_result_t load_all_recursive(char * path_buf, const char * path) +{ + lv_result_t ret = LV_RESULT_OK; + lv_fs_res_t fs_res; + + lv_fs_dir_t dir; + fs_res = lv_fs_dir_open(&dir, path); + if(fs_res != LV_FS_RES_OK) { + LV_LOG_WARN("Couldn't open directory %s", path); + return LV_RESULT_INVALID; + } + + while(1) { + fs_res = lv_fs_dir_read(&dir, path_buf, LV_FS_MAX_PATH_LENGTH); + if(fs_res != LV_FS_RES_OK) { + LV_LOG_WARN("Couldn't read directory %s", path); + ret = LV_RESULT_INVALID; + goto dir_close_out; + } + + if(path_buf[0] == '\0') { + break; + } + + int full_path_len = lv_fs_path_join(NULL, 0, path, path_buf); + char * full_path = lv_malloc(full_path_len + 1); + LV_ASSERT_MALLOC(full_path); + lv_fs_path_join(full_path, full_path_len + 1, path, path_buf); + + if(path_buf[0] == '/') { + ret = load_all_recursive(path_buf, full_path); + } + else { + load_from_path(full_path); + } + + lv_free(full_path); + + if(ret != LV_RESULT_OK) { + goto dir_close_out; + } + } + +dir_close_out: + fs_res = lv_fs_dir_close(&dir); + if(fs_res != LV_FS_RES_OK) { + LV_LOG_WARN("Error closing directory %s", path); + ret = LV_RESULT_INVALID; + } + + return ret; +} + +static void load_from_path(const char * path) +{ + const char * ext = lv_fs_get_ext(path); + + if(lv_streq(ext, "xml")) { + lv_fs_res_t fs_res; + lv_fs_file_t f; + fs_res = lv_fs_open(&f, path, LV_FS_MODE_RD); + if(fs_res != LV_FS_RES_OK) { + LV_LOG_WARN("Couldn't open %s", path); + return; + } + + /* Determine file size */ + lv_fs_seek(&f, 0, LV_FS_SEEK_END); + uint32_t file_size = 0; + lv_fs_tell(&f, &file_size); + lv_fs_seek(&f, 0, LV_FS_SEEK_SET); + + /* Create the buffer */ + char * xml_buf = lv_malloc(file_size + 1); + if(xml_buf == NULL) { + LV_LOG_WARN("Memory allocation failed for file %s (%d bytes)", path, file_size + 1); + lv_fs_close(&f); + return; + } + + /* Read the file content */ + uint32_t rn; + fs_res = lv_fs_read(&f, xml_buf, file_size, &rn); + if(fs_res != LV_FS_RES_OK || rn != file_size) { + LV_LOG_WARN("Couldn't read %s fully", path); + lv_free(xml_buf); + lv_fs_close(&f); + return; + } + + lv_fs_close(&f); + + /* Null-terminate the buffer */ + xml_buf[rn] = '\0'; + + load_from_path_parser_data_t parser_data; + + XML_Memory_Handling_Suite mem_handlers; + mem_handlers.malloc_fcn = lv_malloc; + mem_handlers.realloc_fcn = lv_realloc; + mem_handlers.free_fcn = lv_free; + XML_Parser parser = XML_ParserCreate_MM(NULL, &mem_handlers, NULL); + parser_data.parser = parser; + parser_data.type = LV_XML_TYPE_UNKNOWN; + XML_SetUserData(parser, &parser_data); + XML_SetStartElementHandler(parser, load_from_path_start_element_handler); + + /* Parse the XML */ + enum XML_Status parser_res = XML_Parse(parser, xml_buf, file_size, XML_TRUE); + enum XML_Error parser_error = XML_GetErrorCode(parser); + if(parser_res == XML_STATUS_ERROR && parser_error != XML_ERROR_ABORTED) { + LV_LOG_WARN("XML parsing error: %s on line %lu", XML_ErrorString(parser_error), + XML_GetCurrentLineNumber(parser)); + XML_ParserFree(parser); + lv_free(xml_buf); + return; + } + XML_ParserFree(parser); + + switch(parser_data.type) { + case LV_XML_TYPE_COMPONENT: { + char * component_name = path_filename_without_extension(path); + lv_xml_register_component_from_data(component_name, xml_buf); + lv_free(component_name); + break; + } + case LV_XML_TYPE_TRANSLATIONS: +#if LV_USE_TRANSLATION + lv_xml_register_translation_from_data(xml_buf); +#else + LV_LOG_WARN("Translation XML found but translations not enabled"); +#endif + break; + default: + LV_LOG_WARN("Unknown XML type found in pack"); + break; + } + + lv_free(xml_buf); + } + else { + LV_LOG_INFO("Did not use '%s' from XML pack.", path); + } +} + +static char * path_filename_without_extension(const char * path) +{ + const char * last = lv_fs_get_last(path); + const char * ext = lv_fs_get_ext(last); + char * filename = lv_strdup(last); + LV_ASSERT_MALLOC(filename); + if(ext[0]) { + filename[lv_strlen(last) - lv_strlen(ext) - 1] = '\0'; /*Trim the extension*/ + } + return filename; +} + +static void load_from_path_start_element_handler(void * user_data, const char * name, const char ** attrs) +{ + LV_UNUSED(attrs); + load_from_path_parser_data_t * data = user_data; + + if(lv_streq(name, "component") || lv_streq(name, "screen") || lv_streq(name, "globals")) { + data->type = LV_XML_TYPE_COMPONENT; + } + else if(lv_streq(name, "translations")) { + data->type = LV_XML_TYPE_TRANSLATIONS; + } + + XML_StopParser(data->parser, XML_FALSE); +} + +#endif /*LV_USE_XML*/ diff --git a/src/others/xml/lv_xml_load.h b/src/others/xml/lv_xml_load.h new file mode 100644 index 0000000000..9cbcaff0a3 --- /dev/null +++ b/src/others/xml/lv_xml_load.h @@ -0,0 +1,77 @@ +/** + * @file lv_xml_load.h + * + */ + +#ifndef LV_XML_LOAD_H +#define LV_XML_LOAD_H + +#ifdef __cplusplus +extern "C" { +#endif + +/********************* + * INCLUDES + *********************/ + +#include "../../misc/lv_types.h" +#if LV_USE_XML + +/********************* + * DEFINES + *********************/ + +/********************** + * TYPEDEFS + **********************/ + +/********************** + * GLOBAL PROTOTYPES + **********************/ + +/** + * Recurse into a directory, loading all XML components, + * screens, globals, and translations. + * @param path the path to a directory to load files from + * @return `LV_RESULT_OK` if there were no issues or + * `LV_RESULT_INVALID` otherwise. + */ +lv_result_t lv_xml_load_all_from_path(const char * path); + +#if LV_USE_FS_FROGFS +/** + * Mount a data blob and recurse through it, loading all XML components, + * screens, globals, and translations. + * @param buf the data blob + * @param buf_size the size of the data blob + * @return a handle that can be used to unload it later + */ +lv_xml_load_t * lv_xml_load_all_from_data(const void * buf, uint32_t buf_size); + +/** + * Mount a data blob located at `file_path` in a filesystem and recurse through it, + * loading all XML components, screens, globals, and translations. + * @param file_path the path of the data blob + * @return a handle that can be used to unload it later + */ +lv_xml_load_t * lv_xml_load_all_from_file(const char * file_path); + +/** + * Unload XML data that was loaded by a function that returned `lv_xml_load_t *`. + * Any assets in the loaded data will not be accessible anymore. + * @param load a loaded XML data handle, or `NULL` to unload all. + */ +void lv_xml_unload(lv_xml_load_t * load); +#endif /*LV_USE_FS_FROGFS*/ + +/********************** + * MACROS + **********************/ + +#endif /*LV_USE_XML*/ + +#ifdef __cplusplus +} /*extern "C"*/ +#endif + +#endif /*LV_XML_LOAD_H*/ diff --git a/src/others/xml/lv_xml_load_private.h b/src/others/xml/lv_xml_load_private.h new file mode 100644 index 0000000000..3e91eeb576 --- /dev/null +++ b/src/others/xml/lv_xml_load_private.h @@ -0,0 +1,46 @@ +/** + * @file lv_xml_load_private.h + * + */ + +#ifndef LV_XML_LOAD_PRIVATE_H +#define LV_XML_LOAD_PRIVATE_H + +#ifdef __cplusplus +extern "C" { +#endif + +/********************* + * INCLUDES + *********************/ + +#include "lv_xml_load.h" +#if LV_USE_XML + +/********************* + * DEFINES + *********************/ + +/********************** + * TYPEDEFS + **********************/ + +/********************** + * GLOBAL PROTOTYPES + **********************/ + +void lv_xml_load_init(void); + +void lv_xml_load_deinit(void); + +/********************** + * MACROS + **********************/ + +#endif /*LV_USE_XML*/ + +#ifdef __cplusplus +} /*extern "C"*/ +#endif + +#endif /*LV_XML_LOAD_PRIVATE_H*/ diff --git a/src/others/xml/lv_xml_parser.c b/src/others/xml/lv_xml_parser.c index 9cf4d6d88f..871600d195 100644 --- a/src/others/xml/lv_xml_parser.c +++ b/src/others/xml/lv_xml_parser.c @@ -1,5 +1,5 @@ /** - * @file lv_xml.c + * @file lv_xml_parser.c * */ @@ -81,6 +81,18 @@ void lv_xml_parser_start_section(lv_xml_parser_state_t * state, const char * nam state->section = LV_XML_PARSER_SECTION_SUBJECTS; return; } + else if(lv_streq(name, "animation")) { + state->section = LV_XML_PARSER_SECTION_ANIMATION; + return; + } + else if(lv_streq(name, "include_timeline")) { + state->section = LV_XML_PARSER_SECTION_INCLUDE_TIMELINE; + return; + } + else if(lv_streq(name, "timeline")) { + state->section = LV_XML_PARSER_SECTION_TIMELINE; + return; + } else if(lv_streq(name, "view")) { state->section = LV_XML_PARSER_SECTION_VIEW; return; diff --git a/src/others/xml/lv_xml_parser.h b/src/others/xml/lv_xml_parser.h index 531748a77c..520f32ad60 100644 --- a/src/others/xml/lv_xml_parser.h +++ b/src/others/xml/lv_xml_parser.h @@ -38,15 +38,20 @@ typedef enum { LV_XML_PARSER_SECTION_FONTS, LV_XML_PARSER_SECTION_IMAGES, LV_XML_PARSER_SECTION_SUBJECTS, + LV_XML_PARSER_SECTION_ANIMATION, + LV_XML_PARSER_SECTION_INCLUDE_TIMELINE, + LV_XML_PARSER_SECTION_TIMELINE, LV_XML_PARSER_SECTION_VIEW } lv_xml_parser_section_t; struct _lv_xml_parser_state_t { + const char * tag_name; lv_xml_component_scope_t scope; lv_ll_t parent_ll; lv_obj_t * parent; lv_obj_t * item; lv_obj_t * view; /*Pointer to the created view during component creation*/ + void * context; /*Custom data that can be stored during parsing*/ const char ** parent_attrs; lv_xml_component_scope_t * parent_scope; lv_xml_parser_section_t section; diff --git a/src/others/xml/lv_xml_private.h b/src/others/xml/lv_xml_private.h index 71abee3da5..1d1f2376b8 100644 --- a/src/others/xml/lv_xml_private.h +++ b/src/others/xml/lv_xml_private.h @@ -1,5 +1,5 @@ /** - * @file lv_xml_ptivate.h + * @file lv_xml_private.h * */ @@ -46,6 +46,22 @@ typedef struct { lv_event_cb_t cb; } lv_xml_event_cb_t; +/** + * Store the data of + */ +typedef struct { + const char * target_name; /**< Include the timeline of this widget*/ + const char * timeline_name; /**< Include this timeline */ + int32_t delay; +} lv_xml_anim_timeline_include_t; + +typedef struct { + bool is_anim; + union { + lv_anim_t anim; + lv_xml_anim_timeline_include_t incl; + } data; +} lv_xml_anim_timeline_child_t; /********************** * GLOBAL PROTOTYPES diff --git a/src/others/xml/lv_xml_style.c b/src/others/xml/lv_xml_style.c index 3706ba1392..287a8a6f76 100644 --- a/src/others/xml/lv_xml_style.c +++ b/src/others/xml/lv_xml_style.c @@ -30,7 +30,6 @@ /********************** * STATIC PROTOTYPES **********************/ -static lv_style_prop_t style_prop_text_to_enum(const char * txt); /********************** * STATIC VARIABLES @@ -49,35 +48,7 @@ static lv_style_prop_t style_prop_text_to_enum(const char * txt); * GLOBAL FUNCTIONS **********************/ -lv_state_t lv_xml_style_state_to_enum(const char * txt) -{ - if(lv_streq("default", txt)) return LV_STATE_DEFAULT; - else if(lv_streq("pressed", txt)) return LV_STATE_PRESSED; - else if(lv_streq("checked", txt)) return LV_STATE_CHECKED; - else if(lv_streq("scrolled", txt)) return LV_STATE_SCROLLED; - else if(lv_streq("focused", txt)) return LV_STATE_FOCUSED; - else if(lv_streq("focus_key", txt)) return LV_STATE_FOCUS_KEY; - else if(lv_streq("edited", txt)) return LV_STATE_EDITED; - else if(lv_streq("hovered", txt)) return LV_STATE_HOVERED; - else if(lv_streq("disabled", txt)) return LV_STATE_DISABLED; - - return 0; /*Return 0 in lack of a better option. */ -} - -lv_part_t lv_xml_style_part_to_enum(const char * txt) -{ - if(lv_streq("main", txt)) return LV_PART_MAIN; - else if(lv_streq("scrollbar", txt)) return LV_PART_SCROLLBAR; - else if(lv_streq("indicator", txt)) return LV_PART_INDICATOR; - else if(lv_streq("knob", txt)) return LV_PART_KNOB; - else if(lv_streq("selected", txt)) return LV_PART_SELECTED; - else if(lv_streq("items", txt)) return LV_PART_ITEMS; - else if(lv_streq("cursor", txt)) return LV_PART_CURSOR; - - return 0; /*Return 0 in lack of a better option. */ -} - -lv_result_t lv_xml_style_register(lv_xml_component_scope_t * scope, const char ** attrs) +lv_result_t lv_xml_register_style(lv_xml_component_scope_t * scope, const char ** attrs) { const char * style_name = lv_xml_get_value_of(attrs, "name"); if(style_name == NULL) { @@ -111,7 +82,8 @@ lv_result_t lv_xml_style_register(lv_xml_component_scope_t * scope, const char * lv_style_t * style = &xml_style->style; - for(int i = 0; attrs[i]; i += 2) { + int32_t i; + for(i = 0; attrs[i]; i += 2) { const char * name = attrs[i]; const char * value = attrs[i + 1]; if(lv_streq(name, "name")) continue; @@ -120,17 +92,35 @@ lv_result_t lv_xml_style_register(lv_xml_component_scope_t * scope, const char * if(value[0] == '#') { const char * value_clean = &value[1]; + bool const_found = false; lv_xml_const_t * c; LV_LL_READ(&scope->const_ll, c) { if(lv_streq(c->name, value_clean)) { value = c->value; + const_found = true; break; } } + if(!const_found) { + lv_xml_component_scope_t * global_scope = lv_xml_component_get_scope("globals"); + if(global_scope) { + LV_LL_READ(&global_scope->const_ll, c) { + if(lv_streq(c->name, value_clean)) { + value = c->value; + const_found = true; + break; + } + } + } + } + if(!const_found) { + LV_LOG_WARN("Constant `%s` is not found", value_clean); + continue; + } } if(lv_streq(value, "remove")) { - lv_style_prop_t prop = style_prop_text_to_enum(name); + lv_style_prop_t prop = lv_xml_style_prop_to_enum(name); if(prop != LV_STYLE_PROP_INV) lv_style_remove_prop(style, prop); else if(lv_streq(name, "pad_all")) { lv_style_remove_prop(style, LV_STYLE_PAD_TOP); @@ -173,6 +163,8 @@ lv_result_t lv_xml_style_register(lv_xml_component_scope_t * scope, const char * else SET_STYLE_IF(max_height, lv_xml_to_size(value)); else SET_STYLE_IF(length, lv_xml_to_size(value)); else SET_STYLE_IF(radius, lv_xml_to_size(value)); + else SET_STYLE_IF(radial_offset, lv_xml_atoi(value)); + else SET_STYLE_IF(align, lv_xml_align_to_enum(value)); else SET_STYLE_IF(pad_left, lv_xml_atoi(value)); else SET_STYLE_IF(pad_right, lv_xml_atoi(value)); @@ -269,6 +261,7 @@ lv_result_t lv_xml_style_register(lv_xml_component_scope_t * scope, const char * else SET_STYLE_IF(transform_pivot_x, lv_xml_atoi(value)); else SET_STYLE_IF(transform_pivot_y, lv_xml_atoi(value)); else SET_STYLE_IF(transform_skew_x, lv_xml_atoi(value)); + else SET_STYLE_IF(transform_skew_y, lv_xml_atoi(value)); else SET_STYLE_IF(bitmap_mask_src, lv_xml_get_image(scope, value)); else SET_STYLE_IF(rotary_sensitivity, lv_xml_atoi(value)); else SET_STYLE_IF(recolor, lv_xml_to_color(value)); @@ -290,7 +283,42 @@ lv_result_t lv_xml_style_register(lv_xml_component_scope_t * scope, const char * else SET_STYLE_IF(grid_cell_row_pos, lv_xml_atoi(value)); else SET_STYLE_IF(grid_cell_row_span, lv_xml_atoi(value)); else SET_STYLE_IF(grid_cell_y_align, lv_xml_grid_align_to_enum(value)); + else if(lv_streq(name, "grid_column_dsc_array") || + lv_streq(name, "grid_row_dsc_array")) { + uint32_t item_cnt = 0; + uint32_t c; + for(c = 0; value[c] != '\0'; c++) { + if(value[c] == ' ') item_cnt++; + } + + /*This not freed automatically as the styles doesn't have any mechanisms to detect + * removal of properties. It's assumed that the styles are created once and never freed. */ + int32_t * dsc_array = lv_malloc((item_cnt + 2) * sizeof(int32_t)); /*+2 for LV_GRID_TEMPLATE_LAST*/ + + char * value_buf = (char *)value; + item_cnt = 0; + const char * sub_value = lv_xml_split_str(&value_buf, ' '); + while(sub_value) { + if(sub_value[0] == 'f' && sub_value[1] == 'r') { + dsc_array[item_cnt] = LV_GRID_FR(lv_xml_atoi(sub_value + 3)); /*+3 to skip "fr("*/ + } + else { + dsc_array[item_cnt] = lv_xml_atoi(sub_value); + } + + item_cnt++; + sub_value = lv_xml_split_str(&value_buf, ' '); + } + dsc_array[item_cnt] = LV_GRID_TEMPLATE_LAST; + + if(lv_streq(name, "grid_column_dsc_array")) { + lv_style_set_grid_column_dsc_array(style, dsc_array); + } + else { + lv_style_set_grid_row_dsc_array(style, dsc_array); + } + } else { LV_LOG_WARN("%s style property is not supported", name); @@ -318,43 +346,6 @@ const char * lv_xml_style_string_process(char * txt, lv_style_selector_t * selec return style_name; } -void lv_xml_style_add_to_obj(lv_xml_parser_state_t * state, lv_obj_t * obj, const char * text) -{ - char * str = lv_strdup(text); - char * str_ori = str; - - /* Split the string based on space and colons */ - char * onestyle_str = lv_xml_split_str(&str, ' '); - while(onestyle_str != NULL) { - /* Parse the parts and states after the space */ - lv_style_selector_t selector = 0; - const char * style_name = lv_xml_style_string_process(onestyle_str, &selector); - if(style_name != NULL) { - lv_xml_style_t * xml_style = NULL; - /*Resolve parameters or just find the style*/ - if(style_name[0] == '$') { - /*E.g. `$pr_style` style name means use the value - *coming from the parent's `pr_style` named attribute*/ - const char * name_clean = &style_name[1]; - const char * parent_style_name = lv_xml_get_value_of(state->parent_attrs, name_clean); - if(parent_style_name) { - xml_style = lv_xml_get_style_by_name(state->parent_scope, parent_style_name); - } - } - else { - xml_style = lv_xml_get_style_by_name(&state->scope, style_name); - } - if(xml_style) { - /* Apply with the selector */ - lv_obj_add_style(obj, &xml_style->style, selector); - } - } - onestyle_str = lv_xml_split_str(&str, ' '); - } - - lv_free(str_ori); -} - lv_xml_style_t * lv_xml_get_style_by_name(lv_xml_component_scope_t * scope, const char * style_name_raw) { const char * style_name = strrchr(style_name_raw, '.'); @@ -408,134 +399,8 @@ lv_grad_dsc_t * lv_xml_component_get_grad(lv_xml_component_scope_t * scope, cons return NULL; } - /********************** * STATIC FUNCTIONS **********************/ -static lv_style_prop_t style_prop_text_to_enum(const char * txt) -{ - if(lv_streq(txt, "width")) return LV_STYLE_WIDTH; - if(lv_streq(txt, "min_width")) return LV_STYLE_MIN_WIDTH; - if(lv_streq(txt, "max_width")) return LV_STYLE_MAX_WIDTH; - else if(lv_streq(txt, "height")) return LV_STYLE_HEIGHT; - else if(lv_streq(txt, "min_height")) return LV_STYLE_MIN_HEIGHT; - else if(lv_streq(txt, "max_height")) return LV_STYLE_MAX_HEIGHT; - else if(lv_streq(txt, "length")) return LV_STYLE_LENGTH; - else if(lv_streq(txt, "radius")) return LV_STYLE_RADIUS; - - else if(lv_streq(txt, "pad_left")) return LV_STYLE_PAD_LEFT; - else if(lv_streq(txt, "pad_right")) return LV_STYLE_PAD_RIGHT; - else if(lv_streq(txt, "pad_top")) return LV_STYLE_PAD_TOP; - else if(lv_streq(txt, "pad_bottom")) return LV_STYLE_PAD_BOTTOM; - else if(lv_streq(txt, "pad_row")) return LV_STYLE_PAD_ROW; - else if(lv_streq(txt, "pad_column")) return LV_STYLE_PAD_COLUMN; - else if(lv_streq(txt, "pad_radial")) return LV_STYLE_PAD_RADIAL; - - else if(lv_streq(txt, "margin_left")) return LV_STYLE_MARGIN_LEFT; - else if(lv_streq(txt, "margin_right")) return LV_STYLE_MARGIN_RIGHT; - else if(lv_streq(txt, "margin_top")) return LV_STYLE_MARGIN_TOP; - else if(lv_streq(txt, "margin_bottom")) return LV_STYLE_MARGIN_BOTTOM; - - else if(lv_streq(txt, "base_dir")) return LV_STYLE_BASE_DIR; - else if(lv_streq(txt, "clip_corner")) return LV_STYLE_CLIP_CORNER; - - else if(lv_streq(txt, "bg_opa")) return LV_STYLE_BG_OPA; - else if(lv_streq(txt, "bg_color")) return LV_STYLE_BG_COLOR; - else if(lv_streq(txt, "bg_grad_dir")) return LV_STYLE_BG_GRAD_DIR; - else if(lv_streq(txt, "bg_grad_color")) return LV_STYLE_BG_GRAD_COLOR; - else if(lv_streq(txt, "bg_main_stop")) return LV_STYLE_BG_MAIN_STOP; - else if(lv_streq(txt, "bg_grad_stop")) return LV_STYLE_BG_GRAD_STOP; - else if(lv_streq(txt, "bg_grad")) return LV_STYLE_BG_GRAD; - - else if(lv_streq(txt, "bg_image_src")) return LV_STYLE_BG_IMAGE_SRC; - else if(lv_streq(txt, "bg_image_tiled")) return LV_STYLE_BG_IMAGE_TILED; - else if(lv_streq(txt, "bg_image_recolor")) return LV_STYLE_BG_IMAGE_RECOLOR; - else if(lv_streq(txt, "bg_image_recolor_opa")) return LV_STYLE_BG_IMAGE_RECOLOR_OPA; - - else if(lv_streq(txt, "border_color")) return LV_STYLE_BORDER_COLOR; - else if(lv_streq(txt, "border_width")) return LV_STYLE_BORDER_WIDTH; - else if(lv_streq(txt, "border_opa")) return LV_STYLE_BORDER_OPA; - else if(lv_streq(txt, "border_side")) return LV_STYLE_BORDER_SIDE; - else if(lv_streq(txt, "border_post")) return LV_STYLE_BORDER_POST; - - else if(lv_streq(txt, "outline_color")) return LV_STYLE_OUTLINE_COLOR; - else if(lv_streq(txt, "outline_width")) return LV_STYLE_OUTLINE_WIDTH; - else if(lv_streq(txt, "outline_opa")) return LV_STYLE_OUTLINE_OPA; - else if(lv_streq(txt, "outline_pad")) return LV_STYLE_OUTLINE_PAD; - - else if(lv_streq(txt, "shadow_width")) return LV_STYLE_SHADOW_WIDTH; - else if(lv_streq(txt, "shadow_color")) return LV_STYLE_SHADOW_COLOR; - else if(lv_streq(txt, "shadow_offset_x")) return LV_STYLE_SHADOW_OFFSET_X; - else if(lv_streq(txt, "shadow_offset_y")) return LV_STYLE_SHADOW_OFFSET_Y; - else if(lv_streq(txt, "shadow_spread")) return LV_STYLE_SHADOW_SPREAD; - else if(lv_streq(txt, "shadow_opa")) return LV_STYLE_SHADOW_OPA; - - else if(lv_streq(txt, "text_color")) return LV_STYLE_TEXT_COLOR; - else if(lv_streq(txt, "text_font")) return LV_STYLE_TEXT_FONT; - else if(lv_streq(txt, "text_opa")) return LV_STYLE_TEXT_OPA; - else if(lv_streq(txt, "text_align")) return LV_STYLE_TEXT_ALIGN; - else if(lv_streq(txt, "text_letter_space")) return LV_STYLE_TEXT_LETTER_SPACE; - else if(lv_streq(txt, "text_line_space")) return LV_STYLE_TEXT_LINE_SPACE; - else if(lv_streq(txt, "text_decor")) return LV_STYLE_TEXT_DECOR; - - else if(lv_streq(txt, "image_opa")) return LV_STYLE_IMAGE_OPA; - else if(lv_streq(txt, "image_recolor")) return LV_STYLE_IMAGE_RECOLOR; - else if(lv_streq(txt, "image_recolor_opa")) return LV_STYLE_IMAGE_RECOLOR_OPA; - - else if(lv_streq(txt, "line_color")) return LV_STYLE_LINE_COLOR; - else if(lv_streq(txt, "line_opa")) return LV_STYLE_LINE_OPA; - else if(lv_streq(txt, "line_width")) return LV_STYLE_LINE_WIDTH; - else if(lv_streq(txt, "line_dash_width")) return LV_STYLE_LINE_DASH_WIDTH; - else if(lv_streq(txt, "line_dash_gap")) return LV_STYLE_LINE_DASH_GAP; - else if(lv_streq(txt, "line_rounded")) return LV_STYLE_LINE_ROUNDED; - - else if(lv_streq(txt, "arc_color")) return LV_STYLE_ARC_COLOR; - else if(lv_streq(txt, "arc_opa")) return LV_STYLE_ARC_OPA; - else if(lv_streq(txt, "arc_width")) return LV_STYLE_ARC_WIDTH; - else if(lv_streq(txt, "arc_rounded")) return LV_STYLE_ARC_ROUNDED; - else if(lv_streq(txt, "arc_image_src")) return LV_STYLE_ARC_IMAGE_SRC; - - else if(lv_streq(txt, "opa")) return LV_STYLE_OPA; - else if(lv_streq(txt, "opa_layered")) return LV_STYLE_OPA_LAYERED; - else if(lv_streq(txt, "color_filter_opa")) return LV_STYLE_COLOR_FILTER_OPA; - else if(lv_streq(txt, "anim_duration")) return LV_STYLE_ANIM_DURATION; - else if(lv_streq(txt, "blend_mode")) return LV_STYLE_BLEND_MODE; - else if(lv_streq(txt, "transform_width")) return LV_STYLE_TRANSFORM_WIDTH; - else if(lv_streq(txt, "transform_height")) return LV_STYLE_TRANSFORM_HEIGHT; - else if(lv_streq(txt, "translate_x")) return LV_STYLE_TRANSLATE_X; - else if(lv_streq(txt, "translate_y")) return LV_STYLE_TRANSLATE_Y; - else if(lv_streq(txt, "translate_radial")) return LV_STYLE_TRANSLATE_RADIAL; - else if(lv_streq(txt, "transform_scale_x")) return LV_STYLE_TRANSFORM_SCALE_X; - else if(lv_streq(txt, "transform_scale_y")) return LV_STYLE_TRANSFORM_SCALE_Y; - else if(lv_streq(txt, "transform_rotation")) return LV_STYLE_TRANSFORM_ROTATION; - else if(lv_streq(txt, "transform_pivot_x")) return LV_STYLE_TRANSFORM_PIVOT_X; - else if(lv_streq(txt, "transform_pivot_y")) return LV_STYLE_TRANSFORM_PIVOT_Y; - else if(lv_streq(txt, "transform_skew_x")) return LV_STYLE_TRANSFORM_SKEW_X; - else if(lv_streq(txt, "bitmap_mask_src")) return LV_STYLE_BITMAP_MASK_SRC; - else if(lv_streq(txt, "rotary_sensitivity")) return LV_STYLE_ROTARY_SENSITIVITY; - else if(lv_streq(txt, "recolor")) return LV_STYLE_RECOLOR; - else if(lv_streq(txt, "recolor_opa")) return LV_STYLE_RECOLOR_OPA; - - else if(lv_streq(txt, "layout")) return LV_STYLE_LAYOUT; - - else if(lv_streq(txt, "flex_flow")) return LV_STYLE_FLEX_FLOW; - else if(lv_streq(txt, "flex_grow")) return LV_STYLE_FLEX_GROW; - else if(lv_streq(txt, "flex_main_place")) return LV_STYLE_FLEX_MAIN_PLACE; - else if(lv_streq(txt, "flex_cross_place")) return LV_STYLE_FLEX_CROSS_PLACE; - else if(lv_streq(txt, "flex_track_place")) return LV_STYLE_FLEX_TRACK_PLACE; - - else if(lv_streq(txt, "grid_column_align")) return LV_STYLE_GRID_COLUMN_ALIGN; - else if(lv_streq(txt, "grid_row_align")) return LV_STYLE_GRID_ROW_ALIGN; - else if(lv_streq(txt, "grid_cell_column_pos")) return LV_STYLE_GRID_CELL_COLUMN_POS; - else if(lv_streq(txt, "grid_cell_column_span")) return LV_STYLE_GRID_CELL_COLUMN_SPAN; - else if(lv_streq(txt, "grid_cell_x_align")) return LV_STYLE_GRID_CELL_X_ALIGN; - else if(lv_streq(txt, "grid_cell_row_pos")) return LV_STYLE_GRID_CELL_ROW_POS; - else if(lv_streq(txt, "grid_cell_row_span")) return LV_STYLE_GRID_CELL_ROW_SPAN; - else if(lv_streq(txt, "grid_cell_y_align")) return LV_STYLE_GRID_CELL_Y_ALIGN; - - return LV_STYLE_PROP_INV; - -} - #endif /* LV_USE_XML */ diff --git a/src/others/xml/lv_xml_style.h b/src/others/xml/lv_xml_style.h index 2e975aa44c..27e4dfbf2a 100644 --- a/src/others/xml/lv_xml_style.h +++ b/src/others/xml/lv_xml_style.h @@ -38,29 +38,7 @@ typedef struct _lv_xml_style_t { * @param scope add styles here. (Constants should be already added as style properties might use them) * @param attrs list of attribute names and values */ -lv_result_t lv_xml_style_register(lv_xml_component_scope_t * scope, const char ** attrs); - -/** - * Add the styles to an object. Handles multiple styles and selectors too. - * @param state the parser state - * @param obj the target widget - * @param text the styles' string, e.g. "blue red:pressed:knob" - */ -void lv_xml_style_add_to_obj(lv_xml_parser_state_t * state, lv_obj_t * obj, const char * text); - -/** - * Convert a style state to enum - * @param txt e.g. "pressed" - * @return the enum `LV_STATE_PRESSED` - */ -lv_state_t lv_xml_style_state_to_enum(const char * txt); - -/** - * Convert a style part to enum - * @param txt e.g. "knob" - * @return the enum `LV_PART_KNOB` - */ -lv_part_t lv_xml_style_part_to_enum(const char * txt); +lv_result_t lv_xml_register_style(lv_xml_component_scope_t * scope, const char ** attrs); /** * Decompose a string like `"style1:pressed:checked:knob"` to style name and selector @@ -71,7 +49,7 @@ lv_part_t lv_xml_style_part_to_enum(const char * txt); const char * lv_xml_style_string_process(char * txt, lv_style_selector_t * selector); /** - * Find a style by name which was added by `lv_xml_style_register` + * Find a style by name which was added by `lv_xml_register_style` * @param scope the default context to search in * @param name the name of the style. Can start with a component name prefix (e.g. `my_button.blue`) to overwrite the ctx * @return the style structure diff --git a/src/others/xml/lv_xml_test.c b/src/others/xml/lv_xml_test.c new file mode 100644 index 0000000000..43b121ee26 --- /dev/null +++ b/src/others/xml/lv_xml_test.c @@ -0,0 +1,613 @@ +/** + * @file lv_xml_test.c + * + */ + +/********************* + * INCLUDES + *********************/ +#include "lv_xml_test.h" +#if LV_USE_XML && LV_USE_TEST + +#include "../../lvgl.h" +#include "lv_xml.h" +#include "lv_xml_utils.h" +#include "lv_xml_component_private.h" +#include "../../misc/lv_fs.h" +#include "../../libs/expat/expat.h" +#include "../../display/lv_display_private.h" +#include "../../core/lv_obj_private.h" + +/********************* + * DEFINES + *********************/ +#define LV_TEST_NAME "__test__" + +/********************** + * TYPEDEFS + **********************/ + +typedef struct { + lv_xml_test_step_type_t type; + union { + struct { + int32_t x; + int32_t y; + } mouse_pos; + + const char * str; + + struct { + int32_t ms; + } wait; + + struct { + int32_t ms; + } freeze; + + struct { + const char * path; + } screenshot_compare; + + struct { + lv_subject_t * subject; + const char * value; + } subject_set; + struct { + lv_subject_t * subject; + const char * value; + } subject_compare; + } param; + uint32_t passed : 1; +} lv_xml_test_step_t; + +typedef struct { + const char * ref_image_path_prefix; + uint32_t step_cnt; + uint32_t step_act; + lv_xml_test_step_t * steps; + uint32_t processing_steps : 1; +} lv_xml_test_t; + +/********************** + * STATIC PROTOTYPES + **********************/ +static lv_obj_t * create_cursor(lv_obj_t * parent); +static bool execute_step(lv_xml_test_step_t * step, uint32_t slowdown); +static void start_metadata_handler(void * user_data, const char * name, const char ** attrs); +static void end_metadata_handler(void * user_data, const char * name); +static void click_at(int32_t x, int32_t y, int32_t slowdown); + +/********************** + * STATIC VARIABLES + **********************/ +static lv_xml_test_t test; +static lv_display_t * test_display; +static lv_obj_t * cursor; +static lv_tick_get_cb_t tick_cb_original; + +/********************** + * MACROS + **********************/ + +/********************** + * GLOBAL FUNCTIONS + **********************/ + + +lv_result_t lv_xml_test_register_from_data(const char * xml_def, const char * ref_image_path_prefix) +{ + /*Cleanup the previous test*/ + lv_xml_test_unregister(); + + test.ref_image_path_prefix = ref_image_path_prefix; + + /*Register as a component first to allow creating the view of the test later*/ + lv_result_t res = lv_xml_register_component_from_data(LV_TEST_NAME, xml_def); + if(res != LV_RESULT_OK) { + LV_LOG_WARN("Couldn't register the test as a component"); + return LV_RESULT_INVALID; + } + + /* Parse the XML to extract metadata */ + XML_Memory_Handling_Suite mem_handlers; + mem_handlers.malloc_fcn = lv_malloc; + mem_handlers.realloc_fcn = lv_realloc; + mem_handlers.free_fcn = lv_free; + XML_Parser parser = XML_ParserCreate_MM(NULL, &mem_handlers, NULL); + XML_SetElementHandler(parser, start_metadata_handler, end_metadata_handler); + + + if(XML_Parse(parser, xml_def, lv_strlen(xml_def), XML_TRUE) == XML_STATUS_ERROR) { + LV_LOG_ERROR("XML parsing error: %s on line %lu", + XML_ErrorString(XML_GetErrorCode(parser)), + (unsigned long)XML_GetCurrentLineNumber(parser)); + XML_ParserFree(parser); + test.ref_image_path_prefix = NULL; + return LV_RESULT_INVALID; + } + + XML_ParserFree(parser); + test.ref_image_path_prefix = NULL; + + return LV_RESULT_OK; +} + + +lv_result_t lv_xml_test_register_from_file(const char * path, const char * ref_image_path_prefix) +{ + lv_fs_res_t fs_res; + lv_fs_file_t f; + fs_res = lv_fs_open(&f, path, LV_FS_MODE_RD); + if(fs_res != LV_FS_RES_OK) { + LV_LOG_WARN("Failed to open %s", path); + return LV_RESULT_INVALID; + } + + /* Determine file size */ + lv_fs_seek(&f, 0, LV_FS_SEEK_END); + uint32_t file_size = 0; + lv_fs_tell(&f, &file_size); + lv_fs_seek(&f, 0, LV_FS_SEEK_SET); + + /* Create the buffer */ + char * xml_buf = lv_zalloc(file_size + 1); + if(xml_buf == NULL) { + LV_LOG_WARN("Memory allocation failed for file %s (%d bytes)", path, file_size + 1); + lv_fs_close(&f); + return LV_RESULT_INVALID; + } + + /* Read the file content */ + uint32_t rn; + lv_fs_read(&f, xml_buf, file_size, &rn); + if(rn != file_size) { + LV_LOG_WARN("Couldn't read %s fully", path); + lv_free(xml_buf); + lv_fs_close(&f); + return LV_RESULT_INVALID; + } + + /* Null-terminate the buffer */ + xml_buf[rn] = '\0'; + + /* Register the test */ + lv_result_t res = lv_xml_test_register_from_data(xml_buf, ref_image_path_prefix); + + /* Housekeeping */ + lv_free(xml_buf); + lv_fs_close(&f); + + return res; +} + +void lv_xml_test_unregister(void) +{ + uint32_t i; + for(i = 0; i < test.step_cnt; i++) { + lv_xml_test_step_type_t type = test.steps[i].type; + if(type == LV_XML_TEST_STEP_TYPE_CLICK_ON) { + lv_free((void *)test.steps[i].param.str); + } + if(type == LV_XML_TEST_STEP_TYPE_SET_LANGUAGE) { + lv_free((void *)test.steps[i].param.str); + } + if(type == LV_XML_TEST_STEP_TYPE_SCREENSHOT_COMPARE) { + lv_free((void *)test.steps[i].param.screenshot_compare.path); + } + if(type == LV_XML_TEST_STEP_TYPE_SUBJECT_SET) { + lv_free((void *)test.steps[i].param.subject_set.value); + } + if(type == LV_XML_TEST_STEP_TYPE_SUBJECT_COMPARE) { + lv_free((void *)test.steps[i].param.subject_compare.value); + } + } + lv_free(test.steps); + test.steps = NULL; + test.step_cnt = 0; + + lv_xml_component_unregister(LV_TEST_NAME); +} + +void lv_xml_test_run_init(void) +{ + lv_display_t * normal_display = lv_display_get_default(); + test_display = lv_test_display_create(normal_display->hor_res, normal_display->ver_res); + + /*The test will control the ticks*/ + tick_cb_original = lv_tick_get_cb(); + lv_tick_set_cb(NULL); + + lv_test_indev_create_all(); + cursor = create_cursor(lv_display_get_layer_sys(normal_display)); + + lv_xml_component_scope_t * scope = lv_xml_component_get_scope(LV_TEST_NAME); + lv_xml_component_scope_t * extends_scope = lv_xml_component_get_scope(scope->extends); + lv_obj_t * act_screen = lv_screen_active(); + if(extends_scope && extends_scope->is_screen) { + lv_obj_t * test_screen = lv_xml_create(NULL, LV_TEST_NAME, NULL); + lv_screen_load(test_screen); + lv_obj_delete(act_screen); + } + else { + lv_obj_clean(act_screen); + lv_xml_create(act_screen, LV_TEST_NAME, NULL); + } + lv_refr_now(normal_display); + test.step_act = 0; +} + +bool lv_xml_test_run_next(uint32_t slowdown) +{ + bool passed = execute_step(&test.steps[test.step_act], slowdown); + test.steps[test.step_act].passed = passed; + if(!test.steps[test.step_act].passed) { + LV_LOG_WARN("Step %d failed", test.step_act); + } + + test.step_act++; + return passed; +} + +void lv_xml_test_run_stop(void) +{ + lv_obj_delete(cursor); + lv_tick_set_cb(tick_cb_original); + lv_display_delete(test_display); + lv_test_indev_delete_all(); +} + + +uint32_t lv_xml_test_run_all(uint32_t slowdown) +{ + lv_xml_test_run_init(); + + uint32_t failed_cnt = 0; + uint32_t i; + for(i = 0; i < test.step_cnt; i++) { + bool passed = lv_xml_test_run_next(slowdown); + if(!passed) failed_cnt++; + } + + lv_xml_test_run_stop(); + + return failed_cnt; +} + + +uint32_t lv_xml_test_get_step_count(void) +{ + return test.step_cnt; +} + +lv_xml_test_step_type_t lv_xml_test_get_step_type(uint32_t idx) +{ + if(idx >= test.step_cnt) return LV_XML_TEST_STEP_TYPE_NONE; + + return test.steps[idx].type; + +} + +bool lv_xml_test_get_status(uint32_t idx) +{ + if(idx >= test.step_cnt) return LV_XML_TEST_STEP_TYPE_NONE; + + return test.steps[idx].passed; +} + +/********************** + * STATIC FUNCTIONS + **********************/ + +static void lv_xml_test_wait(uint32_t ms, uint32_t slowdown) +{ + lv_test_wait(ms); + lv_delay_ms(ms * slowdown); +} + +static bool execute_step(lv_xml_test_step_t * step, uint32_t slowdown) +{ + bool res = true; + + if(step->type == LV_XML_TEST_STEP_TYPE_CLICK_AT) { + int32_t x = step->param.mouse_pos.x; + int32_t y = step->param.mouse_pos.y; + click_at(x, y, slowdown); + } + else if(step->type == LV_XML_TEST_STEP_TYPE_CLICK_ON) { + const char * name = step->param.str; + lv_obj_t * obj = lv_obj_find_by_name(lv_screen_active(), name); + if(obj == NULL) { + LV_LOG_WARN("No widget found by `%s` name", name); + return LV_RESULT_INVALID; + } + + if(lv_obj_is_visible(obj) == false) { + LV_LOG_WARN("`%s` is not visible, so can't click on it", name); + return LV_RESULT_INVALID; + } + + int32_t x = obj->coords.x1 + lv_area_get_width(&obj->coords) / 2; + int32_t y = obj->coords.y1 + lv_area_get_height(&obj->coords) / 2; + + click_at(x, y, slowdown); + } + else if(step->type == LV_XML_TEST_STEP_TYPE_PRESS) { + lv_obj_add_state(cursor, LV_STATE_PRESSED); + lv_test_mouse_press(); + } + else if(step->type == LV_XML_TEST_STEP_TYPE_RELEASE) { + lv_obj_remove_state(cursor, LV_STATE_PRESSED); + lv_test_mouse_release(); + } + else if(step->type == LV_XML_TEST_STEP_TYPE_MOVE_TO) { + int32_t x = step->param.mouse_pos.x; + int32_t y = step->param.mouse_pos.y; + lv_test_mouse_move_to(x, y); + lv_obj_set_pos(cursor, x, y); + } + else if(step->type == LV_XML_TEST_STEP_TYPE_SCREENSHOT_COMPARE) { + + /*Set the act_screen's pointer to for the test display so that it will render it + *for screenshot compare*/ + lv_obj_t * act_screen_original = test_display->act_scr; + test_display->act_scr = lv_screen_active(); + + /*lv_test_screenshot_compare assumes that the default display is test_display*/ + lv_display_t * default_display = lv_display_get_default(); + lv_display_set_default(test_display); + + /*Make sure that both displays will be updated. Don't invalidate by + *using the act_screen as now it belongs to both displays.*/ + lv_obj_invalidate(lv_display_get_layer_sys(default_display)); + lv_obj_invalidate(lv_display_get_layer_sys(test_display)); + + /*Do the actual screenshot compare*/ + res = lv_test_screenshot_compare(step->param.screenshot_compare.path); + if(!res) { + LV_LOG_WARN("screenshot compare of `%s` failed", step->param.screenshot_compare.path); + } + + /*Restore*/ + lv_display_set_default(default_display); + test_display->act_scr = act_screen_original; + + } + else if(step->type == LV_XML_TEST_STEP_TYPE_WAIT) { + lv_xml_test_wait(step->param.wait.ms, slowdown); + } + else if(step->type == LV_XML_TEST_STEP_TYPE_FREEZE) { + lv_delay_ms(step->param.freeze.ms * slowdown); + } + else if(step->type == LV_XML_TEST_STEP_TYPE_SUBJECT_SET) { + lv_subject_type_t type = step->param.subject_set.subject->type; + if(type == LV_SUBJECT_TYPE_INT) { + lv_subject_set_int(step->param.subject_set.subject, lv_xml_atoi(step->param.subject_set.value)); + } + else if(type == LV_SUBJECT_TYPE_STRING) { + lv_subject_copy_string(step->param.subject_set.subject, step->param.subject_set.value); + } + else { + LV_LOG_WARN("Not supported subject type %d", type); + } + } + else if(step->type == LV_XML_TEST_STEP_TYPE_SUBJECT_COMPARE) { + lv_subject_type_t type = step->param.subject_compare.subject->type; + if(type == LV_SUBJECT_TYPE_INT) { + int32_t v = lv_subject_get_int(step->param.subject_compare.subject); + if(v != lv_xml_atoi(step->param.subject_compare.value)) { + LV_LOG_WARN("Subject compare failed. Expected: %s, Actual: %d", step->param.subject_compare.value, v); + res = false; + } + } + else if(type == LV_SUBJECT_TYPE_STRING) { + const char * v = lv_subject_get_string(step->param.subject_compare.subject); + if(lv_streq(v, step->param.subject_compare.value) == 0) { + LV_LOG_WARN("Subject compare failed. Expected: %s, Actual: %s", step->param.subject_compare.value, v); + res = false; + } + } + else { + LV_LOG_WARN("Not supported subject type %d", type); + } + } + else if(step->type == LV_XML_TEST_STEP_TYPE_SET_LANGUAGE) { + const char * lang = step->param.str; + lv_translation_set_language(lang); + } + + return res; +} + +static lv_obj_t * create_cursor(lv_obj_t * parent) +{ + lv_obj_t * obj = lv_obj_create(parent); + lv_obj_remove_flag(obj, LV_OBJ_FLAG_SCROLLABLE); + lv_obj_remove_flag(obj, LV_OBJ_FLAG_CLICKABLE); + lv_obj_set_size(obj, 30, 30); + lv_obj_set_style_opa(obj, LV_OPA_50, 0); + lv_obj_set_style_bg_color(obj, lv_palette_main(LV_PALETTE_ORANGE), 0); + lv_obj_set_style_bg_color(obj, lv_palette_main(LV_PALETTE_DEEP_ORANGE), LV_STATE_PRESSED); + lv_obj_set_style_border_color(obj, lv_palette_main(LV_PALETTE_BLUE), 0); + lv_obj_set_style_translate_x(obj, lv_pct(-50), 0); + lv_obj_set_style_translate_y(obj, lv_pct(-50), 0); + lv_obj_set_style_radius(obj, LV_RADIUS_CIRCLE, 0); + lv_obj_set_style_transform_width(obj, -5, LV_STATE_PRESSED); + lv_obj_set_style_transform_height(obj, -5, LV_STATE_PRESSED); + + return obj; +} + +static void start_metadata_handler(void * user_data, const char * name, const char ** attrs) +{ + LV_UNUSED(user_data); + + if(lv_streq(name, "test")) { + return; + } + + if(lv_streq(name, "steps")) { + test.processing_steps = 1; + return; + } + + /*Process the steps only*/ + if(test.processing_steps == 0) return; + + if(lv_streq(name, "click_at")) { + test.step_cnt++; + const char * x = lv_xml_get_value_of(attrs, "x"); + const char * y = lv_xml_get_value_of(attrs, "y"); + test.steps = lv_realloc(test.steps, sizeof(lv_xml_test_step_t) * test.step_cnt); + uint32_t idx = test.step_cnt - 1; + test.steps[idx].type = LV_XML_TEST_STEP_TYPE_CLICK_AT; + test.steps[idx].param.mouse_pos.x = lv_xml_atoi(x); + test.steps[idx].param.mouse_pos.y = lv_xml_atoi(y); + } + else if(lv_streq(name, "click_on")) { + const char * obj_name = lv_xml_get_value_of(attrs, "name"); + if(obj_name == NULL) { + LV_LOG_WARN("No name is set in test step"); + return; + } + + test.step_cnt++; + test.steps = lv_realloc(test.steps, sizeof(lv_xml_test_step_t) * test.step_cnt); + uint32_t idx = test.step_cnt - 1; + test.steps[idx].type = LV_XML_TEST_STEP_TYPE_CLICK_ON; + test.steps[idx].param.str = lv_strdup(obj_name); + LV_ASSERT_MALLOC(test.steps[idx].param.str); + } + else if(lv_streq(name, "move_to")) { + test.step_cnt++; + const char * x = lv_xml_get_value_of(attrs, "x"); + const char * y = lv_xml_get_value_of(attrs, "y"); + test.steps = lv_realloc(test.steps, sizeof(lv_xml_test_step_t) * test.step_cnt); + uint32_t idx = test.step_cnt - 1; + test.steps[idx].type = LV_XML_TEST_STEP_TYPE_MOVE_TO; + test.steps[idx].param.mouse_pos.x = lv_xml_atoi(x); + test.steps[idx].param.mouse_pos.y = lv_xml_atoi(y); + } + else if(lv_streq(name, "press")) { + test.step_cnt++; + test.steps = lv_realloc(test.steps, sizeof(lv_xml_test_step_t) * test.step_cnt); + uint32_t idx = test.step_cnt - 1; + test.steps[idx].type = LV_XML_TEST_STEP_TYPE_PRESS; + } + else if(lv_streq(name, "release")) { + test.step_cnt++; + test.steps = lv_realloc(test.steps, sizeof(lv_xml_test_step_t) * test.step_cnt); + uint32_t idx = test.step_cnt - 1; + test.steps[idx].type = LV_XML_TEST_STEP_TYPE_RELEASE; + } + else if(lv_streq(name, "screenshot_compare")) { + test.step_cnt++; + const char * path = lv_xml_get_value_of(attrs, "path"); + test.steps = lv_realloc(test.steps, sizeof(lv_xml_test_step_t) * test.step_cnt); + uint32_t idx = test.step_cnt - 1; + test.steps[idx].type = LV_XML_TEST_STEP_TYPE_SCREENSHOT_COMPARE; + + char buf[256]; + lv_snprintf(buf, sizeof(buf), "%s%s", test.ref_image_path_prefix, path); + + test.steps[idx].param.screenshot_compare.path = lv_strdup(buf); + } + else if(lv_streq(name, "wait")) { + test.step_cnt++; + const char * ms = lv_xml_get_value_of(attrs, "ms"); + test.steps = lv_realloc(test.steps, sizeof(lv_xml_test_step_t) * test.step_cnt); + uint32_t idx = test.step_cnt - 1; + test.steps[idx].type = LV_XML_TEST_STEP_TYPE_WAIT; + test.steps[idx].param.wait.ms = lv_xml_atoi(ms); + } + else if(lv_streq(name, "freeze")) { + test.step_cnt++; + const char * ms = lv_xml_get_value_of(attrs, "ms"); + test.steps = lv_realloc(test.steps, sizeof(lv_xml_test_step_t) * test.step_cnt); + uint32_t idx = test.step_cnt - 1; + test.steps[idx].type = LV_XML_TEST_STEP_TYPE_FREEZE; + test.steps[idx].param.freeze.ms = lv_xml_atoi(ms); + } + else if(lv_streq(name, "subject_set")) { + const char * subject_str = lv_xml_get_value_of(attrs, "subject"); + const char * value_str = lv_xml_get_value_of(attrs, "value"); + if(subject_str == NULL) { + LV_LOG_WARN("subject is not set in `%s`", name); + return; + } + lv_subject_t * subject = lv_xml_get_subject(NULL, subject_str); + if(subject == NULL) { + LV_LOG_WARN("`%s` subject is not found in `%s`", subject_str, name); + return; + } + + test.step_cnt++; + test.steps = lv_realloc(test.steps, sizeof(lv_xml_test_step_t) * test.step_cnt); + uint32_t idx = test.step_cnt - 1; + test.steps[idx].type = LV_XML_TEST_STEP_TYPE_SUBJECT_SET; + test.steps[idx].param.subject_set.subject = subject; + test.steps[idx].param.subject_set.value = lv_strdup(value_str); + } + else if(lv_streq(name, "subject_compare")) { + const char * subject_str = lv_xml_get_value_of(attrs, "subject"); + const char * value_str = lv_xml_get_value_of(attrs, "value"); + if(subject_str == NULL) { + LV_LOG_WARN("subject is not set in `%s`", name); + return; + } + lv_subject_t * subject = lv_xml_get_subject(NULL, subject_str); + if(subject == NULL) { + LV_LOG_WARN("`%s` subject is not found in `%s`", subject_str, name); + return; + } + + test.step_cnt++; + test.steps = lv_realloc(test.steps, sizeof(lv_xml_test_step_t) * test.step_cnt); + uint32_t idx = test.step_cnt - 1; + test.steps[idx].type = LV_XML_TEST_STEP_TYPE_SUBJECT_COMPARE; + test.steps[idx].param.subject_compare.subject = subject; + test.steps[idx].param.subject_compare.value = lv_strdup(value_str); + } + else if(lv_streq(name, "set_language")) { + const char * obj_name = lv_xml_get_value_of(attrs, "name"); + if(obj_name == NULL) { + LV_LOG_WARN("No name is set in test step"); + return; + } + + test.step_cnt++; + test.steps = lv_realloc(test.steps, sizeof(lv_xml_test_step_t) * test.step_cnt); + uint32_t idx = test.step_cnt - 1; + test.steps[idx].type = LV_XML_TEST_STEP_TYPE_SET_LANGUAGE; + test.steps[idx].param.str = lv_strdup(obj_name); + LV_ASSERT_MALLOC(test.steps[idx].param.str); + } +} + +static void end_metadata_handler(void * user_data, const char * name) +{ + LV_UNUSED(user_data); + if(lv_streq(name, "steps")) { + test.processing_steps = 0; + return; + } +} + + +static void click_at(int32_t x, int32_t y, int32_t slowdown) +{ + lv_obj_remove_state(cursor, LV_STATE_PRESSED); + lv_test_mouse_release(); + lv_xml_test_wait(50, slowdown); + lv_test_mouse_move_to(x, y); + lv_test_mouse_press(); + lv_obj_set_pos(cursor, x, y); + lv_obj_add_state(cursor, LV_STATE_PRESSED); + lv_xml_test_wait(100, slowdown); + lv_test_mouse_release(); + lv_xml_test_wait(50, slowdown); + lv_obj_remove_state(cursor, LV_STATE_PRESSED); + lv_refr_now(NULL); +} + +#endif /* LV_USE_XML */ diff --git a/src/others/xml/lv_xml_test.h b/src/others/xml/lv_xml_test.h new file mode 100644 index 0000000000..f2f495db9b --- /dev/null +++ b/src/others/xml/lv_xml_test.h @@ -0,0 +1,121 @@ +/** + * @file lv_xml_test.h + * + */ + +#ifndef LV_XML_TEST_H +#define LV_XML_TEST_H + +#ifdef __cplusplus +extern "C" { +#endif + +/********************* + * INCLUDES + *********************/ +#include "../../misc/lv_types.h" +#if LV_USE_XML && LV_USE_TEST + +/********************** + * TYPEDEFS + **********************/ + +typedef enum { + LV_XML_TEST_STEP_TYPE_NONE, + LV_XML_TEST_STEP_TYPE_MOVE_TO, + LV_XML_TEST_STEP_TYPE_PRESS, + LV_XML_TEST_STEP_TYPE_RELEASE, + LV_XML_TEST_STEP_TYPE_CLICK_AT, + LV_XML_TEST_STEP_TYPE_CLICK_ON, + LV_XML_TEST_STEP_TYPE_WAIT, + LV_XML_TEST_STEP_TYPE_FREEZE, + LV_XML_TEST_STEP_TYPE_SCREENSHOT_COMPARE, + LV_XML_TEST_STEP_TYPE_SUBJECT_SET, + LV_XML_TEST_STEP_TYPE_SUBJECT_COMPARE, + LV_XML_TEST_STEP_TYPE_SET_LANGUAGE, +} lv_xml_test_step_type_t; + +/********************** + * GLOBAL PROTOTYPES + **********************/ + +/** + * Load the styles, constants, another data of the test. It needs to be called only once for each test. + * @param xml_def the XML definition of the test as a NULL terminated string + * @param ref_image_path_prefix prefix for the path of reference images + * @return LV_RESULT_OK: loaded successfully, LV_RES_INVALID: otherwise + */ +lv_result_t lv_xml_test_register_from_data(const char * xml_def, const char * ref_image_path_prefix); + +/** + * Load the styles, constants, another data of the test. It needs to be called only once for each test. + * @param path path to an XML file + * @param ref_image_path_prefix prefix for the path of reference images + * @return LV_RESULT_OK: loaded successfully, LV_RES_INVALID: otherwise + */ +lv_result_t lv_xml_test_register_from_file(const char * path, const char * ref_image_path_prefix); + +/** + * Free resources allocated for testing. + */ +void lv_xml_test_unregister(void); + +/** + * Switch to testing mode. Needs to be called to use `lv_xml_test_run_next()` + */ +void lv_xml_test_run_init(void); + +/** + * Run the next test step. + * @param slowdown 0: max speed, 1: real speed, 2: half speed, ... ,10: ten times slower + * @return true: the step passed; false: the step failed + */ +bool lv_xml_test_run_next(uint32_t slowdown); + +/** + * Leave testing mode. + */ +void lv_xml_test_run_stop(void); + +/** + * Run all the test steps. + * It calls `lv_xml_test_run_init()`, `lv_xml_test_run_next()`, and `lv_xml_test_run_stop` + * internally so no further preparation or cleanup is needed. + * @param slowdown 0: max speed, 1: real speed, 2: half speed, ... ,10: ten times slower + * @return number of failed tests + */ +uint32_t lv_xml_test_run_all(uint32_t slowdown); + +/** + * Get the number of steps in a test + * @return the number of ``s + */ +uint32_t lv_xml_test_get_step_count(void); + +/** + * Get the type of a step + * @param idx the index of a step (< step_count) + * @return element of `lv_xml_test_step_type_t` + */ +lv_xml_test_step_type_t lv_xml_test_get_step_type(uint32_t idx); + +/** + * Check if the a step was passed. Can be called after lv_xml_test_run() + * @param idx the index of a step (< step_count) + * @return true: the step passed, false: the step failed + */ +bool lv_xml_test_get_status(uint32_t idx); + +/********************** + * MACROS + **********************/ + +#endif /* LV_USE_XML */ + +#ifdef __cplusplus +} /*extern "C"*/ +#endif + +#endif /*LV_XML_TEST_H*/ + + diff --git a/src/others/xml/lv_xml_translation.c b/src/others/xml/lv_xml_translation.c new file mode 100644 index 0000000000..63334cd934 --- /dev/null +++ b/src/others/xml/lv_xml_translation.c @@ -0,0 +1,180 @@ +/** + * @file lv_xml_translation.c + * + */ + +/********************* + * INCLUDES + *********************/ +#include "../../lvgl.h" +#if LV_USE_XML && LV_USE_TRANSLATION + +#include "../translation/lv_translation_private.h" +#include "lv_xml_widget.h" +#include "lv_xml_parser.h" +#include "../../others/translation/lv_translation.h" +#include "../../libs/expat/expat.h" + +/********************* + * DEFINES + *********************/ + +/********************** + * TYPEDEFS + **********************/ + +/********************** + * STATIC PROTOTYPES + **********************/ +static void start_handler(void * user_data, const char * name, const char ** attrs); +static void end_handler(void * user_data, const char * name); + +/********************** + * STATIC VARIABLES + **********************/ + +/********************** + * MACROS + **********************/ + +/********************** + * GLOBAL FUNCTIONS + **********************/ + +lv_result_t lv_xml_register_translation_from_file(const char * path) +{ + lv_fs_res_t fs_res; + lv_fs_file_t f; + fs_res = lv_fs_open(&f, path, LV_FS_MODE_RD); + if(fs_res != LV_FS_RES_OK) { + LV_LOG_WARN("Couldn't open %s", path); + return LV_RESULT_INVALID; + } + + /* Determine file size */ + lv_fs_seek(&f, 0, LV_FS_SEEK_END); + uint32_t file_size = 0; + lv_fs_tell(&f, &file_size); + lv_fs_seek(&f, 0, LV_FS_SEEK_SET); + + /* Create the buffer */ + char * xml_buf = lv_malloc(file_size + 1); + LV_ASSERT_MALLOC(xml_buf); + if(xml_buf == NULL) { + LV_LOG_WARN("Memory allocation failed for file %s (%d bytes)", path, file_size + 1); + lv_fs_close(&f); + return LV_RESULT_INVALID; + } + + /* Read the file content */ + uint32_t rn; + lv_fs_read(&f, xml_buf, file_size, &rn); + if(rn != file_size) { + LV_LOG_WARN("Couldn't read %s fully", path); + lv_free(xml_buf); + lv_fs_close(&f); + return LV_RESULT_INVALID; + } + + /* Null-terminate the buffer */ + xml_buf[rn] = '\0'; + + /* Register the component */ + lv_result_t res = lv_xml_register_translation_from_data(xml_buf); + + /* Housekeeping */ + lv_free(xml_buf); + lv_fs_close(&f); + + return res; +} + +lv_result_t lv_xml_register_translation_from_data(const char * xml_def) +{ + lv_translation_pack_t * pack = lv_translation_add_dynamic(); + + /* Parse the XML to extract metadata */ + XML_Parser parser = XML_ParserCreate(NULL); + XML_SetUserData(parser, pack); + XML_SetElementHandler(parser, start_handler, end_handler); + + if(XML_Parse(parser, xml_def, lv_strlen(xml_def), XML_TRUE) == XML_STATUS_ERROR) { + LV_LOG_ERROR("XML parsing error: %s on line %lu", + XML_ErrorString(XML_GetErrorCode(parser)), + (unsigned long)XML_GetCurrentLineNumber(parser)); + XML_ParserFree(parser); + return LV_RESULT_INVALID; + } + XML_ParserFree(parser); + return LV_RESULT_OK; +} + + +/********************** + * STATIC FUNCTIONS + **********************/ + +static void start_handler(void * user_data, const char * name, const char ** attrs) +{ + lv_translation_pack_t * pack = user_data; + + if(lv_streq(name, "translations")) { + const char * languages = lv_xml_get_value_of(attrs, "languages"); + if(languages == NULL) { + LV_LOG_WARN("`languages` are not set in `translations`"); + return; + } + char buf[512]; + char * bufp = buf; + lv_strlcpy(buf, languages, sizeof(buf)); + bufp = buf; + lv_result_t res = LV_RESULT_OK; + while(bufp[0]) { + const char * lang = lv_xml_split_str(&bufp, ' '); + res = lv_translation_add_language(pack, lang); + if(res != LV_RESULT_OK) { + LV_LOG_WARN("Couldn't add language `%s`", lang); + return; + } + } + } + else if(lv_streq(name, "translation")) { + if(pack->language_cnt == 0 || pack->languages == NULL) { + LV_LOG_WARN("`No languages were found, `"); + return; + } + const char * tag_name = lv_xml_get_value_of(attrs, "tag"); + if(tag_name == NULL) { + LV_LOG_WARN("`tag` is missing from the translation"); + return; + } + + lv_translation_tag_dsc_t * tag = lv_translation_add_tag(pack, tag_name); + LV_ASSERT_NULL(tag); + if(tag == NULL) { + LV_LOG_WARN("Couldn't add tag `%s`", tag_name); + return; + } + uint32_t i; + for(i = 0; i < pack->language_cnt; i++) { + const char * trans = lv_xml_get_value_of(attrs, pack->languages[i]); + if(trans == NULL) { + LV_LOG_WARN("`%s` language is missing from tag `%s`", pack->languages[i], tag_name); + continue; + } + lv_result_t res = lv_translation_set_tag_translation(pack, tag, i, trans); + if(res != LV_RESULT_OK) { + LV_LOG_WARN("Couldn't set translation `%s` in tag `%s`", trans, tag_name); + return; + } + } + } +} + +static void end_handler(void * user_data, const char * name) +{ + LV_UNUSED(user_data); + LV_UNUSED(name); +} + +#endif /* LV_USE_XML */ diff --git a/src/others/xml/lv_xml_translation.h b/src/others/xml/lv_xml_translation.h new file mode 100644 index 0000000000..fb9561b98f --- /dev/null +++ b/src/others/xml/lv_xml_translation.h @@ -0,0 +1,53 @@ +/** + * @file lv_xml_translation.h + * + */ + +#ifndef LV_XML_TRANSLATION_H +#define LV_XML_TRANSLATION_H + +#ifdef __cplusplus +extern "C" { +#endif + +/********************* + * INCLUDES + *********************/ +#include "../../misc/lv_types.h" +#if LV_USE_XML && LV_USE_TRANSLATION + +/********************** + * TYPEDEFS + **********************/ + +/********************** + * GLOBAL PROTOTYPES + **********************/ + +/** + * Register translations from an XML file + * @param path path to an XML file (staring with a driver letter) + * @return LV_RESULT_OK: no error + */ +lv_result_t lv_xml_register_translation_from_file(const char * path); + +/** + * Register translations from an XML string + * @param xml_def the XML definition as a string + * @return LV_RESULT_OK: no error + */ +lv_result_t lv_xml_register_translation_from_data(const char * xml_def); + +/********************** + * MACROS + **********************/ + +#endif /* LV_USE_XML */ + +#ifdef __cplusplus +} /*extern "C"*/ +#endif + +#endif /*LV_XML_TRANSLATION_H*/ + + diff --git a/src/others/xml/lv_xml_update.h b/src/others/xml/lv_xml_update.h index 5c1f12dd00..10eac5da7c 100644 --- a/src/others/xml/lv_xml_update.h +++ b/src/others/xml/lv_xml_update.h @@ -25,9 +25,11 @@ extern "C" { **********************/ /** - * Load the styles, constants, another data of the component. It needs to be called only once for each component. - * @param xml_def the XML definition of the component as a NULL terminated string - * @return LV_RES_OK: loaded successfully, LV_RES_INVALID: otherwise + * Change the properties of a given widget by processing XML snippets. + * For example `` + * Note that the tag should be the underlying widget's name and the component's name. + * @param xml_def the XML to process as a string + * @return LV_RESULT_OK: loaded successfully, LV_RES_INVALID: otherwise */ lv_result_t lv_xml_update_from_data(const char * xml_def); diff --git a/src/others/xml/lv_xml_utils.c b/src/others/xml/lv_xml_utils.c index 2c4d1cd6e2..d599fa06bb 100644 --- a/src/others/xml/lv_xml_utils.c +++ b/src/others/xml/lv_xml_utils.c @@ -83,8 +83,8 @@ int32_t lv_xml_atoi_split(const char ** str, char delimiter) int32_t result = 0; int sign = 1; - /* Skip leading whitespace */ - while(*s == ' ' || *s == '\t') s++; + /* Skip leading whitespace and repeated delimiters */ + while(*s == delimiter || *s == ' ' || *s == '\t') s++; /* Handle optional sign */ if(*s == '-') { @@ -109,20 +109,83 @@ int32_t lv_xml_atoi_split(const char ** str, char delimiter) } result = result * sign; + while(*s != delimiter && *s != '\0') s++; /*Make sure to find the delimiter*/ if(*s != '\0') s++; /*Skip the delimiter*/ *str = s; return result; - } - int32_t lv_xml_atoi(const char * str) { - return lv_xml_atoi_split(&str, '\0'); +} + +#if LV_USE_FLOAT +float lv_xml_atof_split(const char ** str, char delimiter) +{ + const char * s = *str; + float result = 0.0f; + int sign = 1; + + /* Skip leading whitespace and repeated delimiters */ + while(*s == delimiter || *s == ' ' || *s == '\t') s++; + + /* Handle optional sign */ + if(*s == '-') { + sign = -1; + s++; + } + else if(*s == '+') { + s++; + } + + /* Convert the integer part */ + while(*s != delimiter && *s != '.' && *s != '\0') { + if(*s >= '0' && *s <= '9') { + float digit = *s - '0'; + result = result * 10.0f + digit; + s++; + } + else { + break; /* Non-digit character */ + } + } + + /* Convert the fractional part */ + if(*s == '.') { + s++; /* Skip the decimal point */ + float fraction = 0.0f; + float divisor = 10.0f; + + while(*s != delimiter && *s != '\0') { + if(*s >= '0' && *s <= '9') { + float digit = *s - '0'; + fraction += digit / divisor; + divisor *= 10.0f; + s++; + } + else { + break; /* Non-digit character */ + } + } + result += fraction; + } + result = result * sign; + while(*s != delimiter && *s != '\0') s++; /*Make sure to find the delimiter*/ + + if(*s != '\0') s++; /*Skip the delimiter*/ + *str = s; + return result; +} + + +float lv_xml_atof(const char * str) +{ + return lv_xml_atof_split(&str, '\0'); } +#endif int32_t lv_xml_strtol(const char * str, char ** endptr, int32_t base) { @@ -200,6 +263,11 @@ int32_t lv_xml_strtol(const char * str, char ** endptr, int32_t base) char * lv_xml_split_str(char ** src, char delimiter) { + /*Skip multiple delimiters*/ + while(*src[0] == delimiter) { + (*src)++; + } + if(*src[0] == '\0') return NULL; char * src_first = *src; diff --git a/src/others/xml/lv_xml_utils.h b/src/others/xml/lv_xml_utils.h index d5bd5ec34c..31bb2df969 100644 --- a/src/others/xml/lv_xml_utils.h +++ b/src/others/xml/lv_xml_utils.h @@ -26,7 +26,6 @@ const char * lv_xml_get_value_of(const char ** attrs, const char * name); int32_t lv_xml_atoi(const char * str); - /** * Convert sections of a string to int. * The end of the string is indicated by the `delimiter`. @@ -36,6 +35,19 @@ int32_t lv_xml_atoi(const char * str); */ int32_t lv_xml_atoi_split(const char ** str, char delimiter); +#if LV_USE_FLOAT +float lv_xml_atof(const char * str); + +/** + * Convert sections of a string to float. + * The end of the string is indicated by the `delimiter`. + * @param str pointer to a string, it will point to the character after the delimiter + * @param delimiter a character to indicate the end of the float + * @return the float before the next delimiter + */ +float lv_xml_atof_split(const char ** str, char delimiter); +#endif + lv_color_t lv_xml_to_color(const char * str); /** diff --git a/src/others/xml/lv_xml_widget.c b/src/others/xml/lv_xml_widget.c index 6a448618a8..59ecd82b85 100644 --- a/src/others/xml/lv_xml_widget.c +++ b/src/others/xml/lv_xml_widget.c @@ -38,7 +38,7 @@ static lv_widget_processor_t * widget_processor_head; * GLOBAL FUNCTIONS **********************/ -lv_result_t lv_xml_widget_register(const char * name, lv_xml_widget_create_cb_t create_cb, +lv_result_t lv_xml_register_widget(const char * name, lv_xml_widget_create_cb_t create_cb, lv_xml_widget_apply_cb_t apply_cb) { lv_widget_processor_t * p = lv_malloc(sizeof(lv_widget_processor_t)); @@ -53,6 +53,7 @@ lv_result_t lv_xml_widget_register(const char * name, lv_xml_widget_create_cb_t p->next = widget_processor_head; widget_processor_head = p; } + return LV_RESULT_OK; } @@ -61,12 +62,19 @@ lv_widget_processor_t * lv_xml_widget_get_processor(const char * name) /* Select the widget specific parser type based on the name */ lv_widget_processor_t * p = widget_processor_head; while(p) { - if(lv_streq(p->name, name)) { - return p; - } + if(lv_streq(p->name, name)) return p; + p = p->next; + } + /* If not found try with "lv_obj-" prefix, as lv_obj elements works without explicit prefix too*/ + char buf[256]; + lv_snprintf(buf, sizeof(buf), "lv_obj-%s", name); + p = widget_processor_head; + while(p) { + if(lv_streq(p->name, buf)) return p; p = p->next; } + return NULL; } diff --git a/src/others/xml/lv_xml_widget.h b/src/others/xml/lv_xml_widget.h index 96690f0b5b..afd0300164 100644 --- a/src/others/xml/lv_xml_widget.h +++ b/src/others/xml/lv_xml_widget.h @@ -16,7 +16,6 @@ extern "C" { #include "../../misc/lv_types.h" #if LV_USE_XML -#include "lv_xml.h" #include "lv_xml_utils.h" /********************** @@ -37,12 +36,37 @@ typedef struct _lv_widget_processor_t { * GLOBAL PROTOTYPES **********************/ -lv_result_t lv_xml_widget_register(const char * name, lv_xml_widget_create_cb_t create_cb, +/** + * Register a Widget for the XML parser. When a Widget with a given name + * is created in XML `create_cb` will be called to create an instance, and + * then `apply_cb` will be called to apply the properties (e.g. `width=100""`). + * @param name Name of the Widget (e.g. "my_slider", referenced as in XML) + * @param create_cb Called to create an instance of the Widget + * @param apply_cb Called to apply its properties + * @return Pointer to the created Widget + * @note E.g. Chart series, are also considered Widgets although + * they don't have `lv_obj_t *` type. + */ +lv_result_t lv_xml_register_widget(const char * name, lv_xml_widget_create_cb_t create_cb, lv_xml_widget_apply_cb_t apply_cb); +/** + * Get a descriptor that was created when the Widget was registered. + * @param name The name that was used when the Widget was registered + * @return The descriptor of the Widget + */ lv_widget_processor_t * lv_xml_widget_get_processor(const char * name); +/** + * Get the descriptor of the Widget that is extended by a given Widget, Component, or Screen. + * E.g. in a Component `` return the descriptor of `lv_slider`. + * @param extends The name of a Component, Screen, or Widget whose ancestor Widget shall be returned + * @return The descriptor of the extended Widget + * @note If a component extends an other component which based on `lv_slider` + * lv_slider's descriptor will be returned. + */ lv_widget_processor_t * lv_xml_widget_get_extended_widget_processor(const char * extends); + /********************** * MACROS **********************/ diff --git a/src/others/xml/parsers/lv_xml_arc_parser.c b/src/others/xml/parsers/lv_xml_arc_parser.c index 8bab7ddd21..af122711f4 100644 --- a/src/others/xml/parsers/lv_xml_arc_parser.c +++ b/src/others/xml/parsers/lv_xml_arc_parser.c @@ -7,7 +7,7 @@ * INCLUDES *********************/ #include "lv_xml_arc_parser.h" -#if LV_USE_XML +#if LV_USE_XML && LV_USE_ARC #include "../../../lvgl.h" #include "../../../lvgl_private.h" @@ -54,36 +54,15 @@ void lv_xml_arc_apply(lv_xml_parser_state_t * state, const char ** attrs) const char * name = attrs[i]; const char * value = attrs[i + 1]; - if(lv_streq("angles", name)) { - char buf[64]; - lv_strlcpy(buf, value, sizeof(buf)); - char * buf_p = buf; - int32_t v1 = lv_xml_atoi(lv_xml_split_str(&buf_p, ' ')); - int32_t v2 = lv_xml_atoi(buf_p); - lv_arc_set_angles(item, v1, v2); - } - else if(lv_streq("bg_angles", name)) { - char buf[64]; - lv_strlcpy(buf, value, sizeof(buf)); - char * buf_p = buf; - int32_t v1 = lv_xml_atoi(lv_xml_split_str(&buf_p, ' ')); - int32_t v2 = lv_xml_atoi(buf_p); - lv_arc_set_bg_angles(item, v1, v2); - } - else if(lv_streq("range", name)) { - char buf[64]; - lv_strlcpy(buf, value, sizeof(buf)); - char * buf_p = buf; - int32_t v1 = lv_xml_atoi(lv_xml_split_str(&buf_p, ' ')); - int32_t v2 = lv_xml_atoi(buf_p); - lv_arc_set_range(item, v1, v2); - } - else if(lv_streq("value", name)) { - lv_arc_set_value(item, lv_xml_atoi(value)); - } - else if(lv_streq("mode", name)) { - lv_arc_set_mode(item, mode_text_to_enum_value(value)); - } + if(lv_streq("start_angle", name)) lv_arc_set_start_angle(item, lv_xml_atoi(value)); + else if(lv_streq("end_angle", name)) lv_arc_set_end_angle(item, lv_xml_atoi(value)); + else if(lv_streq("bg_start_angle", name)) lv_arc_set_bg_start_angle(item, lv_xml_atoi(value)); + else if(lv_streq("bg_end_angle", name)) lv_arc_set_bg_end_angle(item, lv_xml_atoi(value)); + else if(lv_streq("rotation", name)) lv_arc_set_rotation(item, lv_xml_atoi(value)); + else if(lv_streq("value", name)) lv_arc_set_value(item, lv_xml_atoi(value)); + else if(lv_streq("min_value", name)) lv_arc_set_min_value(item, lv_xml_atoi(value)); + else if(lv_streq("max_value", name)) lv_arc_set_max_value(item, lv_xml_atoi(value)); + else if(lv_streq("mode", name)) lv_arc_set_mode(item, mode_text_to_enum_value(value)); else if(lv_streq("bind_value", name)) { lv_subject_t * subject = lv_xml_get_subject(&state->scope, value); if(subject) { @@ -100,7 +79,6 @@ void lv_xml_arc_apply(lv_xml_parser_state_t * state, const char ** attrs) * STATIC FUNCTIONS **********************/ - static lv_arc_mode_t mode_text_to_enum_value(const char * txt) { if(lv_streq("normal", txt)) return LV_ARC_MODE_NORMAL; diff --git a/src/others/xml/parsers/lv_xml_arc_parser.h b/src/others/xml/parsers/lv_xml_arc_parser.h index 10afdcd964..2b8159a95f 100644 --- a/src/others/xml/parsers/lv_xml_arc_parser.h +++ b/src/others/xml/parsers/lv_xml_arc_parser.h @@ -3,8 +3,8 @@ * */ -#ifndef LV_ARC_XML_PARSER_H -#define LV_ARC_XML_PARSER_H +#ifndef LV_XML_ARC_PARSER_H +#define LV_XML_ARC_PARSER_H #ifdef __cplusplus extern "C" { @@ -14,7 +14,7 @@ extern "C" { * INCLUDES *********************/ #include "../lv_xml.h" -#if LV_USE_XML +#if LV_USE_XML && LV_USE_ARC /********************** * TYPEDEFS @@ -37,4 +37,4 @@ void lv_xml_arc_apply(lv_xml_parser_state_t * state, const char ** attrs); } /*extern "C"*/ #endif -#endif /*LV_ARC_XML_PARSE_H*/ +#endif /*LV_XML_ARC_PARSER_H*/ diff --git a/src/others/xml/parsers/lv_xml_bar_parser.c b/src/others/xml/parsers/lv_xml_bar_parser.c index 1ee314aeb7..c239676761 100644 --- a/src/others/xml/parsers/lv_xml_bar_parser.c +++ b/src/others/xml/parsers/lv_xml_bar_parser.c @@ -7,7 +7,7 @@ * INCLUDES *********************/ #include "lv_xml_bar_parser.h" -#if LV_USE_XML +#if LV_USE_XML && LV_USE_BAR #include "../../../lvgl.h" #include "../../../lvgl_private.h" @@ -23,7 +23,7 @@ /********************** * STATIC PROTOTYPES **********************/ -static lv_bar_orientation_t orentation_text_to_enum_value(const char * txt); +static lv_bar_orientation_t orientation_text_to_enum_value(const char * txt); static lv_bar_mode_t mode_text_to_enum_value(const char * txt); /********************** @@ -56,30 +56,29 @@ void lv_xml_bar_apply(lv_xml_parser_state_t * state, const char ** attrs) const char * value = attrs[i + 1]; if(lv_streq("value", name)) { - char buf[64]; - lv_strlcpy(buf, value, sizeof(buf)); - char * buf_p = buf; - int32_t v1 = lv_xml_atoi(lv_xml_split_str(&buf_p, ' ')); - bool v2 = lv_xml_to_bool(buf_p); - lv_bar_set_value(item, v1, v2); + int32_t v = lv_xml_atoi(value); + const char * anim_str = lv_xml_get_value_of(attrs, "value-animated"); + bool anim = anim_str ? lv_xml_to_bool(anim_str) : false; + lv_bar_set_value(item, v, anim); } - if(lv_streq("start_value", name)) { - char buf[64]; - lv_strlcpy(buf, value, sizeof(buf)); - char * buf_p = buf; - int32_t v1 = lv_xml_atoi(lv_xml_split_str(&buf_p, ' ')); - bool v2 = lv_xml_to_bool(buf_p); - lv_bar_set_start_value(item, v1, v2); + else if(lv_streq("start_value", name)) { + int32_t v = lv_xml_atoi(value); + const char * anim_str = lv_xml_get_value_of(attrs, "start_value-animated"); + bool anim = anim_str ? lv_xml_to_bool(anim_str) : false; + lv_bar_set_start_value(item, v, anim); } - if(lv_streq("orientation", name)) lv_bar_set_orientation(item, orentation_text_to_enum_value(value)); - if(lv_streq("mode", name)) lv_bar_set_mode(item, mode_text_to_enum_value(value)); - if(lv_streq("range", name)) { - char buf[64]; - lv_strlcpy(buf, value, sizeof(buf)); - char * buf_p = buf; - int32_t v1 = lv_xml_atoi(lv_xml_split_str(&buf_p, ' ')); - int32_t v2 = lv_xml_atoi(buf_p); - lv_bar_set_range(item, v1, v2); + else if(lv_streq("min_value", name)) lv_bar_set_min_value(item, lv_xml_atoi(value)); + else if(lv_streq("max_value", name)) lv_bar_set_max_value(item, lv_xml_atoi(value)); + else if(lv_streq("orientation", name)) lv_bar_set_orientation(item, orientation_text_to_enum_value(value)); + else if(lv_streq("mode", name)) lv_bar_set_mode(item, mode_text_to_enum_value(value)); + else if(lv_streq("bind_value", name)) { + lv_subject_t * subject = lv_xml_get_subject(&state->scope, value); + if(subject) { + lv_bar_bind_value(item, subject); + } + else { + LV_LOG_WARN("Subject \"%s\" doesn't exist in bar bind_value", value); + } } } } @@ -88,7 +87,7 @@ void lv_xml_bar_apply(lv_xml_parser_state_t * state, const char ** attrs) * STATIC FUNCTIONS **********************/ -static lv_bar_orientation_t orentation_text_to_enum_value(const char * txt) +static lv_bar_orientation_t orientation_text_to_enum_value(const char * txt) { if(lv_streq("auto", txt)) return LV_BAR_ORIENTATION_AUTO; if(lv_streq("horizontal", txt)) return LV_BAR_ORIENTATION_HORIZONTAL; diff --git a/src/others/xml/parsers/lv_xml_bar_parser.h b/src/others/xml/parsers/lv_xml_bar_parser.h index 84c53ce3ab..5b90576840 100644 --- a/src/others/xml/parsers/lv_xml_bar_parser.h +++ b/src/others/xml/parsers/lv_xml_bar_parser.h @@ -3,8 +3,8 @@ * */ -#ifndef LV_BAR_XML_PARSER_H -#define LV_BAR_XML_PARSER_H +#ifndef LV_XML_BAR_PARSER_H +#define LV_XML_BAR_PARSER_H #ifdef __cplusplus extern "C" { @@ -14,7 +14,7 @@ extern "C" { * INCLUDES *********************/ #include "../lv_xml.h" -#if LV_USE_XML +#if LV_USE_XML && LV_USE_BAR /********************** * TYPEDEFS @@ -37,4 +37,4 @@ void lv_xml_bar_apply(lv_xml_parser_state_t * state, const char ** attrs); } /*extern "C"*/ #endif -#endif /*LV_BAR_XML_PARSE_H*/ +#endif /*LV_XML_BAR_PARSER_H*/ diff --git a/src/others/xml/parsers/lv_xml_button_parser.c b/src/others/xml/parsers/lv_xml_button_parser.c index 0ab77008bc..0267295a27 100644 --- a/src/others/xml/parsers/lv_xml_button_parser.c +++ b/src/others/xml/parsers/lv_xml_button_parser.c @@ -8,7 +8,7 @@ *********************/ #include "lv_xml_button_parser.h" -#if LV_USE_XML +#if LV_USE_XML && LV_USE_BUTTON #include "../../../lvgl.h" #include "../../../lvgl_private.h" diff --git a/src/others/xml/parsers/lv_xml_button_parser.h b/src/others/xml/parsers/lv_xml_button_parser.h index 7bfcf5be69..7fe59bfaf5 100644 --- a/src/others/xml/parsers/lv_xml_button_parser.h +++ b/src/others/xml/parsers/lv_xml_button_parser.h @@ -3,8 +3,8 @@ * */ -#ifndef LV_BUTTON_XML_PARSER_H -#define LV_BUTTON_XML_PARSER_H +#ifndef LV_XML_BUTTON_PARSER_H +#define LV_XML_BUTTON_PARSER_H #ifdef __cplusplus extern "C" { @@ -14,7 +14,7 @@ extern "C" { * INCLUDES *********************/ #include "../lv_xml.h" -#if LV_USE_XML +#if LV_USE_XML && LV_USE_BUTTON /********************** * TYPEDEFS @@ -38,4 +38,4 @@ void lv_xml_button_apply(lv_xml_parser_state_t * state, const char ** attrs); } /*extern "C"*/ #endif -#endif /*LV_BUTTON_XML_PARSE_H*/ +#endif /*LV_XML_BUTTON_PARSER_H*/ diff --git a/src/others/xml/parsers/lv_xml_buttonmatrix_parser.c b/src/others/xml/parsers/lv_xml_buttonmatrix_parser.c index b92f631bc8..670afeb3f6 100644 --- a/src/others/xml/parsers/lv_xml_buttonmatrix_parser.c +++ b/src/others/xml/parsers/lv_xml_buttonmatrix_parser.c @@ -7,7 +7,7 @@ * INCLUDES *********************/ #include "lv_xml_buttonmatrix_parser.h" -#if LV_USE_XML +#if LV_USE_XML && LV_USE_BUTTONMATRIX #include "../../../lvgl.h" #include "../../../lvgl_private.h" diff --git a/src/others/xml/parsers/lv_xml_buttonmatrix_parser.h b/src/others/xml/parsers/lv_xml_buttonmatrix_parser.h index c1099ec94a..3fc2cff53e 100644 --- a/src/others/xml/parsers/lv_xml_buttonmatrix_parser.h +++ b/src/others/xml/parsers/lv_xml_buttonmatrix_parser.h @@ -14,7 +14,7 @@ extern "C" { * INCLUDES *********************/ #include "../lv_xml.h" -#if LV_USE_XML +#if LV_USE_XML && LV_USE_BUTTONMATRIX /********************** * TYPEDEFS @@ -38,4 +38,4 @@ void lv_xml_buttonmatrix_apply(lv_xml_parser_state_t * state, const char ** attr } /*extern "C"*/ #endif -#endif /*LV_XML_BUTTONMATRIX_PARSE_H*/ +#endif /*LV_XML_BUTTONMATRIX_PARSER_H*/ diff --git a/src/others/xml/parsers/lv_xml_calendar_parser.c b/src/others/xml/parsers/lv_xml_calendar_parser.c index 4af1a9ff4e..d82099cb23 100644 --- a/src/others/xml/parsers/lv_xml_calendar_parser.c +++ b/src/others/xml/parsers/lv_xml_calendar_parser.c @@ -7,7 +7,7 @@ * INCLUDES *********************/ #include "lv_xml_calendar_parser.h" -#if LV_USE_XML +#if LV_USE_XML && LV_USE_CALENDAR #include "../../../lvgl.h" #include "../../../lvgl_private.h" @@ -55,22 +55,15 @@ void lv_xml_calendar_apply(lv_xml_parser_state_t * state, const char ** attrs) const char * name = attrs[i]; const char * value = attrs[i + 1]; - if(lv_streq("today_date", name)) { - const char * bufp = value; - int32_t y = lv_xml_atoi_split(&bufp, ' '); - int32_t m = lv_xml_atoi_split(&bufp, ' '); - int32_t d = lv_xml_atoi_split(&bufp, ' '); - lv_calendar_set_today_date(item, y, m, d); - } - else if(lv_streq("shown_month", name)) { - const char * bufp = value; - int32_t y = lv_xml_atoi_split(&bufp, ' '); - int32_t m = lv_xml_atoi_split(&bufp, ' '); - lv_calendar_set_month_shown(item, y, m); - } + if(lv_streq("today_year", name)) lv_calendar_set_today_year(item, lv_xml_atoi(value)); + else if(lv_streq("today_month", name)) lv_calendar_set_today_month(item, lv_xml_atoi(value)); + else if(lv_streq("today_day", name)) lv_calendar_set_today_day(item, lv_xml_atoi(value)); + else if(lv_streq("shown_year", name)) lv_calendar_set_shown_year(item, lv_xml_atoi(value)); + else if(lv_streq("shown_month", name)) lv_calendar_set_shown_month(item, lv_xml_atoi(value)); } } +#if LV_USE_CALENDAR_HEADER_DROPDOWN void * lv_xml_calendar_header_dropdown_create(lv_xml_parser_state_t * state, const char ** attrs) { LV_UNUSED(attrs); @@ -82,7 +75,9 @@ void lv_xml_calendar_header_dropdown_apply(lv_xml_parser_state_t * state, const { lv_xml_obj_apply(state, attrs); /*Apply the common properties, e.g. width, height, styles flags etc*/ } +#endif +#if LV_USE_CALENDAR_HEADER_ARROW void * lv_xml_calendar_header_arrow_create(lv_xml_parser_state_t * state, const char ** attrs) { LV_UNUSED(attrs); @@ -95,6 +90,7 @@ void lv_xml_calendar_header_arrow_apply(lv_xml_parser_state_t * state, const cha { lv_xml_obj_apply(state, attrs); /*Apply the common properties, e.g. width, height, styles flags etc*/ } +#endif /********************** diff --git a/src/others/xml/parsers/lv_xml_calendar_parser.h b/src/others/xml/parsers/lv_xml_calendar_parser.h index 881101ecb4..b3f0d7fc69 100644 --- a/src/others/xml/parsers/lv_xml_calendar_parser.h +++ b/src/others/xml/parsers/lv_xml_calendar_parser.h @@ -3,8 +3,8 @@ * */ -#ifndef LV_CALENDAR_XML_PARSER_H -#define LV_CALENDAR_XML_PARSER_H +#ifndef LV_XML_CALENDAR_PARSER_H +#define LV_XML_CALENDAR_PARSER_H #ifdef __cplusplus extern "C" { @@ -40,4 +40,4 @@ void lv_xml_calendar_header_dropdown_apply(lv_xml_parser_state_t * state, const } /*extern "C"*/ #endif -#endif /*LV_CHART_XML_PARSE_H*/ +#endif /*LV_XML_CALENDAR_PARSER_H*/ diff --git a/src/others/xml/parsers/lv_xml_canvas_parser.h b/src/others/xml/parsers/lv_xml_canvas_parser.h index 040478e659..487f298d2b 100644 --- a/src/others/xml/parsers/lv_xml_canvas_parser.h +++ b/src/others/xml/parsers/lv_xml_canvas_parser.h @@ -3,8 +3,8 @@ * */ -#ifndef LV_CANVAS_XML_PARSER_H -#define LV_CANVAS_XML_PARSER_H +#ifndef LV_XML_CANVAS_PARSER_H +#define LV_XML_CANVAS_PARSER_H #ifdef __cplusplus extern "C" { @@ -38,4 +38,4 @@ void lv_xml_canvas_apply(lv_xml_parser_state_t * state, const char ** attrs); } /*extern "C"*/ #endif -#endif /*LV_BUTTON_XML_PARSE_H*/ +#endif /*LV_XML_CANVAS_PARSER_H*/ diff --git a/src/others/xml/parsers/lv_xml_chart_parser.c b/src/others/xml/parsers/lv_xml_chart_parser.c index 0b06892dc0..3236d97945 100644 --- a/src/others/xml/parsers/lv_xml_chart_parser.c +++ b/src/others/xml/parsers/lv_xml_chart_parser.c @@ -7,7 +7,7 @@ * INCLUDES *********************/ #include "lv_xml_chart_parser.h" -#if LV_USE_XML +#if LV_USE_XML && LV_USE_CHART #include "../../../lvgl.h" #include "../../../lvgl_private.h" @@ -68,11 +68,11 @@ void lv_xml_chart_apply(lv_xml_parser_state_t * state, const char ** attrs) } else if(lv_streq("type", name)) lv_chart_set_type(item, chart_type_to_enum(value)); else if(lv_streq("update_mode", name)) lv_chart_set_update_mode(item, chart_update_mode_to_enum(value)); - else if(lv_streq("div_line_count", name)) { - - int32_t value1 = lv_xml_atoi_split(&value, ' '); - int32_t value2 = lv_xml_atoi_split(&value, ' '); - lv_chart_set_div_line_count(item, value1, value2); + else if(lv_streq("hor_div_line_count", name)) { + lv_chart_set_hor_div_line_count(item, lv_xml_atoi(value)); + } + else if(lv_streq("ver_div_line_count", name)) { + lv_chart_set_ver_div_line_count(item, lv_xml_atoi(value)); } } } @@ -160,11 +160,8 @@ void lv_xml_chart_axis_apply(lv_xml_parser_state_t * state, const char ** attrs) const char * name = attrs[i]; const char * value = attrs[i + 1]; - if(lv_streq("range", name)) { - int32_t min_val = lv_xml_atoi_split(&value, ' '); - int32_t max_val = lv_xml_atoi_split(&value, ' '); - lv_chart_set_axis_range(chart, axis, min_val, max_val); - } + if(lv_streq("min_value", name)) lv_chart_set_axis_min_value(chart, axis, lv_xml_atoi(value)); + if(lv_streq("max_value", name)) lv_chart_set_axis_max_value(chart, axis, lv_xml_atoi(value)); } } @@ -177,6 +174,7 @@ static lv_chart_type_t chart_type_to_enum(const char * txt) if(lv_streq("none", txt)) return LV_CHART_TYPE_NONE; if(lv_streq("line", txt)) return LV_CHART_TYPE_LINE; if(lv_streq("bar", txt)) return LV_CHART_TYPE_BAR; + if(lv_streq("stacked", txt)) return LV_CHART_TYPE_STACKED; if(lv_streq("scatter", txt)) return LV_CHART_TYPE_SCATTER; LV_LOG_WARN("%s is an unknown value for chart's chart_type", txt); diff --git a/src/others/xml/parsers/lv_xml_chart_parser.h b/src/others/xml/parsers/lv_xml_chart_parser.h index 0307e4f8e1..970a9a6f88 100644 --- a/src/others/xml/parsers/lv_xml_chart_parser.h +++ b/src/others/xml/parsers/lv_xml_chart_parser.h @@ -3,8 +3,8 @@ * */ -#ifndef LV_CHART_XML_PARSER_H -#define LV_CHART_XML_PARSER_H +#ifndef LV_XML_CHART_PARSER_H +#define LV_XML_CHART_PARSER_H #ifdef __cplusplus extern "C" { @@ -14,7 +14,7 @@ extern "C" { * INCLUDES *********************/ #include "../lv_xml.h" -#if LV_USE_XML +#if LV_USE_XML && LV_USE_CHART /********************** * TYPEDEFS @@ -42,4 +42,4 @@ void lv_xml_chart_axis_apply(lv_xml_parser_state_t * state, const char ** attrs) } /*extern "C"*/ #endif -#endif /*LV_CHART_XML_PARSE_H*/ +#endif /*LV_XML_CHART_PARSER_H*/ diff --git a/src/others/xml/parsers/lv_xml_checkbox_parser.h b/src/others/xml/parsers/lv_xml_checkbox_parser.h index 37ac0489d4..53f5149a96 100644 --- a/src/others/xml/parsers/lv_xml_checkbox_parser.h +++ b/src/others/xml/parsers/lv_xml_checkbox_parser.h @@ -3,8 +3,8 @@ * */ -#ifndef LV_CHECKBOX_XML_PARSER_H -#define LV_CHECKBOX_XML_PARSER_H +#ifndef LV_XML_CHECKBOX_PARSER_H +#define LV_XML_CHECKBOX_PARSER_H #ifdef __cplusplus extern "C" { @@ -37,4 +37,4 @@ void lv_xml_checkbox_apply(lv_xml_parser_state_t * state, const char ** attrs); } /*extern "C"*/ #endif -#endif /*LV_CHECKBOX_XML_PARSE_H*/ +#endif /*LV_XML_CHECKBOX_PARSER_H*/ diff --git a/src/others/xml/parsers/lv_xml_dropdown_parser.c b/src/others/xml/parsers/lv_xml_dropdown_parser.c index 153ec25d90..53dcf55eb1 100644 --- a/src/others/xml/parsers/lv_xml_dropdown_parser.c +++ b/src/others/xml/parsers/lv_xml_dropdown_parser.c @@ -7,7 +7,7 @@ * INCLUDES *********************/ #include "lv_xml_dropdown_parser.h" -#if LV_USE_XML +#if LV_USE_XML && LV_USE_DROPDOWN #include "../../../lvgl.h" #include "../../../lvgl_private.h" diff --git a/src/others/xml/parsers/lv_xml_dropdown_parser.h b/src/others/xml/parsers/lv_xml_dropdown_parser.h index 3a6919256e..3b4b7f7e6f 100644 --- a/src/others/xml/parsers/lv_xml_dropdown_parser.h +++ b/src/others/xml/parsers/lv_xml_dropdown_parser.h @@ -3,8 +3,8 @@ * */ -#ifndef LV_DROPDOWN_XML_PARSER_H -#define LV_DROPDOWN_XML_PARSER_H +#ifndef LV_XML_DROPDOWN_PARSER_H +#define LV_XML_DROPDOWN_PARSER_H #ifdef __cplusplus extern "C" { @@ -14,7 +14,7 @@ extern "C" { * INCLUDES *********************/ #include "../lv_xml.h" -#if LV_USE_XML +#if LV_USE_XML && LV_USE_DROPDOWN /********************** * TYPEDEFS @@ -38,4 +38,4 @@ void lv_xml_dropdown_list_apply(lv_xml_parser_state_t * state, const char ** att } /*extern "C"*/ #endif -#endif /*LV_DROPDOWN_XML_PARSE_H*/ +#endif /*LV_XML_DROPDOWN_PARSER_H*/ diff --git a/src/others/xml/parsers/lv_xml_event_parser.c b/src/others/xml/parsers/lv_xml_event_parser.c deleted file mode 100644 index 07901bd9b6..0000000000 --- a/src/others/xml/parsers/lv_xml_event_parser.c +++ /dev/null @@ -1,170 +0,0 @@ -/** - * @file lv_xml_event_parser.c - * - */ - -/********************* - * INCLUDES - *********************/ -#include "lv_xml_event_parser.h" -#if LV_USE_XML - -#include "../../../lvgl.h" -#include "../../../lvgl_private.h" - -/********************* - * DEFINES - *********************/ - -/********************** - * TYPEDEFS - **********************/ - -/********************** - * STATIC PROTOTYPES - **********************/ -static lv_event_code_t trigger_text_to_enum_value(const char * txt); -static void free_user_data_event_cb(lv_event_t * e); - -/********************** - * STATIC VARIABLES - **********************/ - -/********************** - * MACROS - **********************/ - -/********************** - * GLOBAL FUNCTIONS - **********************/ - -void * lv_xml_event_call_function_create(lv_xml_parser_state_t * state, const char ** attrs) -{ - LV_UNUSED(attrs); - - - const char * trigger = lv_xml_get_value_of(attrs, "trigger"); - lv_event_code_t code = LV_EVENT_CLICKED; - if(trigger) code = trigger_text_to_enum_value(trigger); - if(code == LV_EVENT_LAST) { - LV_LOG_WARN("Couldn't add call function event because \"%s\" trigger is invalid.", trigger); - return NULL; - } - - const char * cb_txt = lv_xml_get_value_of(attrs, "callback"); - if(cb_txt == NULL) { - LV_LOG_WARN("callback is mandatory for event-call_function"); - return NULL; - } - - lv_obj_t * obj = lv_xml_state_get_parent(state); - lv_event_cb_t cb = lv_xml_get_event_cb(&state->scope, cb_txt); - if(cb == NULL) { - LV_LOG_WARN("Couldn't add call function event because \"%s\" callback is not found.", cb_txt); - /*Don't return NULL. - *When the component is isolated e.g. in the editor the callback is not registered */ - return obj; - } - - const char * user_data_xml = lv_xml_get_value_of(attrs, "user_data"); - char * user_data = NULL; - if(user_data_xml) user_data = lv_strdup(user_data_xml); - - lv_obj_add_event_cb(obj, cb, code, user_data); - if(user_data) lv_obj_add_event_cb(obj, free_user_data_event_cb, LV_EVENT_DELETE, user_data); - - return obj; -} - -void lv_xml_event_call_function_apply(lv_xml_parser_state_t * state, const char ** attrs) -{ - LV_UNUSED(state); - LV_UNUSED(attrs); - /*Nothing to apply*/ -} - -/********************** - * STATIC FUNCTIONS - **********************/ - -static void free_user_data_event_cb(lv_event_t * e) -{ - char * user_data = lv_event_get_user_data(e); - lv_free(user_data); -} - -static lv_event_code_t trigger_text_to_enum_value(const char * txt) -{ - - if(lv_streq("all", txt)) return LV_EVENT_ALL; - if(lv_streq("pressed", txt)) return LV_EVENT_PRESSED; - if(lv_streq("pressing", txt)) return LV_EVENT_PRESSING; - if(lv_streq("press_lost", txt)) return LV_EVENT_PRESS_LOST; - if(lv_streq("short_clicked", txt)) return LV_EVENT_SHORT_CLICKED; - if(lv_streq("single_clicked", txt)) return LV_EVENT_SINGLE_CLICKED; - if(lv_streq("double_clicked", txt)) return LV_EVENT_DOUBLE_CLICKED; - if(lv_streq("triple_clicked", txt)) return LV_EVENT_TRIPLE_CLICKED; - if(lv_streq("long_pressed", txt)) return LV_EVENT_LONG_PRESSED; - if(lv_streq("long_pressed_repeat", txt)) return LV_EVENT_LONG_PRESSED_REPEAT; - if(lv_streq("clicked", txt)) return LV_EVENT_CLICKED; - if(lv_streq("released", txt)) return LV_EVENT_RELEASED; - if(lv_streq("scroll_begin", txt)) return LV_EVENT_SCROLL_BEGIN; - if(lv_streq("scroll_throw_begin", txt)) return LV_EVENT_SCROLL_THROW_BEGIN; - if(lv_streq("scroll_end", txt)) return LV_EVENT_SCROLL_END; - if(lv_streq("scroll", txt)) return LV_EVENT_SCROLL; - if(lv_streq("gesture", txt)) return LV_EVENT_GESTURE; - if(lv_streq("key", txt)) return LV_EVENT_KEY; - if(lv_streq("rotary", txt)) return LV_EVENT_ROTARY; - if(lv_streq("focused", txt)) return LV_EVENT_FOCUSED; - if(lv_streq("defocused", txt)) return LV_EVENT_DEFOCUSED; - if(lv_streq("leave", txt)) return LV_EVENT_LEAVE; - if(lv_streq("hit_test", txt)) return LV_EVENT_HIT_TEST; - if(lv_streq("indev_reset", txt)) return LV_EVENT_INDEV_RESET; - if(lv_streq("hover_over", txt)) return LV_EVENT_HOVER_OVER; - if(lv_streq("hover_leave", txt)) return LV_EVENT_HOVER_LEAVE; - if(lv_streq("cover_check", txt)) return LV_EVENT_COVER_CHECK; - if(lv_streq("refr_ext_draw_size", txt)) return LV_EVENT_REFR_EXT_DRAW_SIZE; - if(lv_streq("draw_main_begin", txt)) return LV_EVENT_DRAW_MAIN_BEGIN; - if(lv_streq("draw_main", txt)) return LV_EVENT_DRAW_MAIN; - if(lv_streq("draw_main_end", txt)) return LV_EVENT_DRAW_MAIN_END; - if(lv_streq("draw_post_begin", txt)) return LV_EVENT_DRAW_POST_BEGIN; - if(lv_streq("draw_post", txt)) return LV_EVENT_DRAW_POST; - if(lv_streq("draw_post_end", txt)) return LV_EVENT_DRAW_POST_END; - if(lv_streq("draw_task_added", txt)) return LV_EVENT_DRAW_TASK_ADDED; - if(lv_streq("value_changed", txt)) return LV_EVENT_VALUE_CHANGED; - if(lv_streq("insert", txt)) return LV_EVENT_INSERT; - if(lv_streq("refresh", txt)) return LV_EVENT_REFRESH; - if(lv_streq("ready", txt)) return LV_EVENT_READY; - if(lv_streq("cancel", txt)) return LV_EVENT_CANCEL; - if(lv_streq("create", txt)) return LV_EVENT_CREATE; - if(lv_streq("delete", txt)) return LV_EVENT_DELETE; - if(lv_streq("child_changed", txt)) return LV_EVENT_CHILD_CHANGED; - if(lv_streq("child_created", txt)) return LV_EVENT_CHILD_CREATED; - if(lv_streq("child_deleted", txt)) return LV_EVENT_CHILD_DELETED; - if(lv_streq("screen_unload_start", txt)) return LV_EVENT_SCREEN_UNLOAD_START; - if(lv_streq("screen_load_start", txt)) return LV_EVENT_SCREEN_LOAD_START; - if(lv_streq("screen_loaded", txt)) return LV_EVENT_SCREEN_LOADED; - if(lv_streq("screen_unloaded", txt)) return LV_EVENT_SCREEN_UNLOADED; - if(lv_streq("size_changed", txt)) return LV_EVENT_SIZE_CHANGED; - if(lv_streq("style_changed", txt)) return LV_EVENT_STYLE_CHANGED; - if(lv_streq("layout_changed", txt)) return LV_EVENT_LAYOUT_CHANGED; - if(lv_streq("get_self_size", txt)) return LV_EVENT_GET_SELF_SIZE; - if(lv_streq("invalidate_area", txt)) return LV_EVENT_INVALIDATE_AREA; - if(lv_streq("resolution_changed", txt)) return LV_EVENT_RESOLUTION_CHANGED; - if(lv_streq("color_format_changed", txt)) return LV_EVENT_COLOR_FORMAT_CHANGED; - if(lv_streq("refr_request", txt)) return LV_EVENT_REFR_REQUEST; - if(lv_streq("refr_start", txt)) return LV_EVENT_REFR_START; - if(lv_streq("refr_ready", txt)) return LV_EVENT_REFR_READY; - if(lv_streq("render_start", txt)) return LV_EVENT_RENDER_START; - if(lv_streq("render_ready", txt)) return LV_EVENT_RENDER_READY; - if(lv_streq("flush_start", txt)) return LV_EVENT_FLUSH_START; - if(lv_streq("flush_finish", txt)) return LV_EVENT_FLUSH_FINISH; - if(lv_streq("flush_wait_start", txt)) return LV_EVENT_FLUSH_WAIT_START; - if(lv_streq("flush_wait_finish", txt)) return LV_EVENT_FLUSH_WAIT_FINISH; - if(lv_streq("vsync", txt)) return LV_EVENT_VSYNC; - - LV_LOG_WARN("%s is an unknown value for event's trigger", txt); - return LV_EVENT_LAST; /*Indicate error*/ -} - -#endif /* LV_USE_XML */ diff --git a/src/others/xml/parsers/lv_xml_image_parser.c b/src/others/xml/parsers/lv_xml_image_parser.c index e6ec712484..952fa4eb8f 100644 --- a/src/others/xml/parsers/lv_xml_image_parser.c +++ b/src/others/xml/parsers/lv_xml_image_parser.c @@ -7,7 +7,7 @@ * INCLUDES *********************/ #include "lv_xml_image_parser.h" -#if LV_USE_XML +#if LV_USE_XML && LV_USE_IMAGE #include "../../../lvgl.h" #include "../../../lvgl_private.h" @@ -61,14 +61,20 @@ void lv_xml_image_apply(lv_xml_parser_state_t * state, const char ** attrs) const char * value = attrs[i + 1]; if(lv_streq("src", name)) lv_image_set_src(item, lv_xml_get_image(&state->scope, value)); - if(lv_streq("inner_align", name)) lv_image_set_inner_align(item, image_align_to_enum(value)); - if(lv_streq("rotation", name)) lv_image_set_rotation(item, lv_xml_atoi(value)); - if(lv_streq("scale_x", name)) lv_image_set_scale_x(item, lv_xml_atoi(value)); - if(lv_streq("scale_y", name)) lv_image_set_scale_y(item, lv_xml_atoi(value)); - if(lv_streq("pivot", name)) { - int32_t x = lv_xml_atoi_split(&value, ' '); - int32_t y = lv_xml_atoi_split(&value, ' '); - lv_image_set_pivot(item, x, y); + else if(lv_streq("inner_align", name)) lv_image_set_inner_align(item, image_align_to_enum(value)); + else if(lv_streq("rotation", name)) lv_image_set_rotation(item, lv_xml_atoi(value)); + else if(lv_streq("scale_x", name)) lv_image_set_scale_x(item, lv_xml_atoi(value)); + else if(lv_streq("scale_y", name)) lv_image_set_scale_y(item, lv_xml_atoi(value)); + else if(lv_streq("pivot_x", name)) lv_image_set_pivot_x(item, lv_xml_to_size(value)); + else if(lv_streq("pivot_y", name)) lv_image_set_pivot_y(item, lv_xml_to_size(value)); + else if(lv_streq("bind_src", name)) { + lv_subject_t * subject = lv_xml_get_subject(&state->scope, value); + if(subject) { + lv_image_bind_src(item, subject); + } + else { + LV_LOG_WARN("Subject \"%s\" doesn't exist in image bind_src", value); + } } } } diff --git a/src/others/xml/parsers/lv_xml_image_parser.h b/src/others/xml/parsers/lv_xml_image_parser.h index 19a978a334..356784fdf7 100644 --- a/src/others/xml/parsers/lv_xml_image_parser.h +++ b/src/others/xml/parsers/lv_xml_image_parser.h @@ -14,7 +14,7 @@ extern "C" { * INCLUDES *********************/ #include "../lv_xml.h" -#if LV_USE_XML +#if LV_USE_XML && LV_USE_IMAGE /********************** * TYPEDEFS @@ -40,4 +40,4 @@ void lv_xml_check_file(const char * filepath); } /*extern "C"*/ #endif -#endif /*LV_XML_IMAGE_PARSER_H*/ \ No newline at end of file +#endif /*LV_XML_IMAGE_PARSER_H*/ diff --git a/src/others/xml/parsers/lv_xml_keyboard_parser.c b/src/others/xml/parsers/lv_xml_keyboard_parser.c index f4ed974b5d..32638fc827 100644 --- a/src/others/xml/parsers/lv_xml_keyboard_parser.c +++ b/src/others/xml/parsers/lv_xml_keyboard_parser.c @@ -7,7 +7,7 @@ * INCLUDES *********************/ #include "lv_xml_keyboard_parser.h" -#if LV_USE_XML +#if LV_USE_XML && LV_USE_KEYBOARD #include "../../../lvgl.h" #include "../../../lvgl_private.h" @@ -57,6 +57,7 @@ void lv_xml_keyboard_apply(lv_xml_parser_state_t * state, const char ** attrs) // if(lv_streq("textarea", name)) lv_keyboard_set_mode(item, lv_obj_get_child_by_name()); if(lv_streq("mode", name)) lv_keyboard_set_mode(item, mode_text_to_enum_value(value)); + if(lv_streq("popovers", name)) lv_keyboard_set_popovers(item, lv_xml_to_bool(value)); } } diff --git a/src/others/xml/parsers/lv_xml_keyboard_parser.h b/src/others/xml/parsers/lv_xml_keyboard_parser.h index cfd80f999c..ded8355c05 100644 --- a/src/others/xml/parsers/lv_xml_keyboard_parser.h +++ b/src/others/xml/parsers/lv_xml_keyboard_parser.h @@ -14,7 +14,7 @@ extern "C" { * INCLUDES *********************/ #include "../lv_xml.h" -#if LV_USE_XML +#if LV_USE_XML && LV_USE_KEYBOARD /********************** * TYPEDEFS diff --git a/src/others/xml/parsers/lv_xml_label_parser.c b/src/others/xml/parsers/lv_xml_label_parser.c index 9241182339..d1ae650cb6 100644 --- a/src/others/xml/parsers/lv_xml_label_parser.c +++ b/src/others/xml/parsers/lv_xml_label_parser.c @@ -7,7 +7,7 @@ * INCLUDES *********************/ #include "lv_xml_label_parser.h" -#if LV_USE_XML +#if LV_USE_XML && LV_USE_LABEL #include "../../../lvgl.h" #include "../../../lvgl_private.h" @@ -24,7 +24,6 @@ * STATIC PROTOTYPES **********************/ static lv_label_long_mode_t long_mode_text_to_enum_value(const char * txt); -static void free_fmt_event_cb(lv_event_t * e); /********************** * STATIC VARIABLES @@ -57,30 +56,22 @@ void lv_xml_label_apply(lv_xml_parser_state_t * state, const char ** attrs) const char * value = attrs[i + 1]; if(lv_streq("text", name)) lv_label_set_text(item, value); - if(lv_streq("long_mode", name)) lv_label_set_long_mode(item, long_mode_text_to_enum_value(value)); - if(lv_streq("bind_text", name)) { - char buf[256]; - lv_strncpy(buf, value, sizeof(buf)); - char * bufp = buf; - char * subject_name = lv_xml_split_str(&bufp, ' '); - if(subject_name) { - lv_subject_t * subject = lv_xml_get_subject(&state->scope, subject_name); - if(subject) { - char * fmt = bufp; /*The second part is the format text*/ - if(fmt && fmt[0] == '\0') fmt = NULL; - if(fmt) { - if(fmt[0] == '\'') fmt++; - size_t fmt_len = lv_strlen(fmt); - if(fmt_len != 0 && fmt[fmt_len - 1] == '\'') fmt[fmt_len - 1] = '\0'; - fmt = lv_strdup(fmt); - lv_obj_add_event_cb(item, free_fmt_event_cb, LV_EVENT_DELETE, fmt); - } - lv_label_bind_text(item, subject, fmt); - } - else { - LV_LOG_WARN("Subject \"%s\" doesn't exist in label bind_text", value); - } + else if(lv_streq("long_mode", name)) lv_label_set_long_mode(item, long_mode_text_to_enum_value(value)); +#if LV_USE_TRANSLATION + else if(lv_streq("translation_tag", name)) lv_label_set_translation_tag(item, value); +#endif + else if(lv_streq("bind_text", name)) { + lv_subject_t * subject = lv_xml_get_subject(&state->scope, value); + if(subject == NULL) { + LV_LOG_WARN("Subject \"%s\" doesn't exist in label bind_text", value); + continue; } + const char * fmt = lv_xml_get_value_of(attrs, "bind_text-fmt"); + if(fmt) { + fmt = lv_strdup(fmt); + lv_obj_add_event_cb(item, lv_event_free_user_data_cb, LV_EVENT_DELETE, (void *) fmt); + } + lv_label_bind_text(item, subject, fmt); } } } @@ -101,10 +92,4 @@ static lv_label_long_mode_t long_mode_text_to_enum_value(const char * txt) return 0; /*Return 0 in lack of a better option. */ } -static void free_fmt_event_cb(lv_event_t * e) -{ - void * fmt = lv_event_get_user_data(e); - lv_free(fmt); -} - #endif /* LV_USE_XML */ diff --git a/src/others/xml/parsers/lv_xml_label_parser.h b/src/others/xml/parsers/lv_xml_label_parser.h index da1ef79be9..35f03976dc 100644 --- a/src/others/xml/parsers/lv_xml_label_parser.h +++ b/src/others/xml/parsers/lv_xml_label_parser.h @@ -3,8 +3,8 @@ * */ -#ifndef LV_LABEL_XML_PARSER_H -#define LV_LABEL_XML_PARSER_H +#ifndef LV_XML_LABEL_PARSER_H +#define LV_XML_LABEL_PARSER_H #ifdef __cplusplus extern "C" { @@ -14,7 +14,7 @@ extern "C" { * INCLUDES *********************/ #include "../lv_xml.h" -#if LV_USE_XML +#if LV_USE_XML && LV_USE_LABEL /********************** * TYPEDEFS @@ -38,4 +38,4 @@ void lv_xml_label_apply(lv_xml_parser_state_t * state, const char ** attrs); } /*extern "C"*/ #endif -#endif /*LV_LABEL_XML_PARSE_H*/ +#endif /*LV_XML_LABEL_PARSER_H*/ diff --git a/src/others/xml/parsers/lv_xml_obj_parser.c b/src/others/xml/parsers/lv_xml_obj_parser.c index 9f61bcd83e..79fef67a07 100644 --- a/src/others/xml/parsers/lv_xml_obj_parser.c +++ b/src/others/xml/parsers/lv_xml_obj_parser.c @@ -15,16 +15,40 @@ /********************* * DEFINES *********************/ +#define lv_event_xml_store_timeline LV_GLOBAL_DEFAULT()->lv_event_xml_store_timeline /********************** * TYPEDEFS **********************/ +/*Duplication from lv_obj.c as lv_obj_add_screen_create_event needs to be + * reimplemented here slightly differently */ +typedef struct { + lv_screen_load_anim_t anim_type; + uint32_t duration; + uint32_t delay; + const char * screen_name; +} screen_load_anim_dsc_t; + +typedef struct { + const char * timeline_name; + const char * target_name; + uint32_t delay; + bool reverse; + lv_obj_t * base_obj; /**< Get the objs by name from here (the view) */ +} play_anim_dsc_t; + /********************** * STATIC PROTOTYPES **********************/ static lv_obj_flag_t flag_to_enum(const char * txt); static void apply_styles(lv_xml_parser_state_t * state, lv_obj_t * obj, const char * name, const char * value); +static void screen_create_on_trigger_event_cb(lv_event_t * e); +static void screen_load_on_trigger_event_cb(lv_event_t * e); +static void delete_on_screen_unloaded_event_cb(lv_event_t * e); +static void free_screen_create_user_data_on_delete_event_cb(lv_event_t * e); +static void play_anim_on_trigger_event_cb(lv_event_t * e); +static void free_play_anim_user_data_on_delete_event_cb(lv_event_t * e); /********************** * STATIC VARIABLES @@ -73,6 +97,9 @@ void lv_xml_obj_apply(lv_xml_parser_state_t * state, const char ** attrs) else if(lv_streq("flex_flow", name)) lv_obj_set_flex_flow(item, lv_xml_flex_flow_to_enum(value)); else if(lv_streq("flex_grow", name)) lv_obj_set_flex_grow(item, lv_xml_atoi(value)); else if(lv_streq("ext_click_area", name)) lv_obj_set_ext_click_area(item, lv_xml_atoi(value)); + else if(lv_streq("scroll_snap_x", name)) lv_obj_set_scroll_snap_x(item, lv_xml_scroll_snap_to_enum(value)); + else if(lv_streq("scroll_snap_y", name)) lv_obj_set_scroll_snap_y(item, lv_xml_scroll_snap_to_enum(value)); + else if(lv_streq("scrollbar_mode", name)) lv_obj_set_scrollbar_mode(item, lv_xml_scrollbar_mode_to_enum(value)); else if(lv_streq("hidden", name)) lv_obj_set_flag(item, LV_OBJ_FLAG_HIDDEN, lv_xml_to_bool(value)); else if(lv_streq("clickable", name)) lv_obj_set_flag(item, LV_OBJ_FLAG_CLICKABLE, lv_xml_to_bool(value)); @@ -99,6 +126,10 @@ void lv_xml_obj_apply(lv_xml_parser_state_t * state, const char ** attrs) else if(lv_streq("press_lock", name)) lv_obj_set_flag(item, LV_OBJ_FLAG_PRESS_LOCK, lv_xml_to_bool(value)); else if(lv_streq("event_bubble", name)) lv_obj_set_flag(item, LV_OBJ_FLAG_EVENT_BUBBLE, lv_xml_to_bool(value)); + else if(lv_streq("event_trickle", name)) lv_obj_set_flag(item, LV_OBJ_FLAG_EVENT_TRICKLE, + lv_xml_to_bool(value)); + else if(lv_streq("state_trickle", name)) lv_obj_set_flag(item, LV_OBJ_FLAG_STATE_TRICKLE, + lv_xml_to_bool(value)); else if(lv_streq("gesture_bubble", name)) lv_obj_set_flag(item, LV_OBJ_FLAG_GESTURE_BUBBLE, lv_xml_to_bool(value)); else if(lv_streq("adv_hittest", name)) lv_obj_set_flag(item, LV_OBJ_FLAG_ADV_HITTEST, @@ -121,7 +152,6 @@ void lv_xml_obj_apply(lv_xml_parser_state_t * state, const char ** attrs) else if(lv_streq("pressed", name)) lv_obj_set_state(item, LV_STATE_PRESSED, lv_xml_to_bool(value)); else if(lv_streq("scrolled", name)) lv_obj_set_state(item, LV_STATE_SCROLLED, lv_xml_to_bool(value)); else if(lv_streq("disabled", name)) lv_obj_set_state(item, LV_STATE_DISABLED, lv_xml_to_bool(value)); - else if(lv_streq("styles", name)) lv_xml_style_add_to_obj(state, item, value); else if(lv_streq("bind_checked", name)) { lv_subject_t * subject = lv_xml_get_subject(&state->scope, value); @@ -129,85 +159,7 @@ void lv_xml_obj_apply(lv_xml_parser_state_t * state, const char ** attrs) lv_obj_bind_checked(item, subject); } else { - LV_LOG_WARN("Subject \"%s\" doesn't exist in lv_obj bind_checked", value); - } - } - else if(name_len >= 15 && lv_memcmp("bind_flag_if_", name, 13) == 0) { - lv_observer_t * (*cb)(lv_obj_t * obj, lv_subject_t * subject, lv_obj_flag_t flag, int32_t ref_value) = NULL; - if(name[13] == 'e' && name[14] == 'q') cb = lv_obj_bind_flag_if_eq; - else if(name[13] == 'n' && name[14] == 'o') cb = lv_obj_bind_flag_if_not_eq; - else if(name[13] == 'g' && name[14] == 't') cb = lv_obj_bind_flag_if_gt; - else if(name[13] == 'g' && name[14] == 'e') cb = lv_obj_bind_flag_if_ge; - else if(name[13] == 'l' && name[14] == 't') cb = lv_obj_bind_flag_if_lt; - else if(name[13] == 'l' && name[14] == 'e') cb = lv_obj_bind_flag_if_le; - - if(cb) { - char buf[128]; - lv_strlcpy(buf, value, sizeof(buf)); - char * bufp = buf; - const char * subject_str = lv_xml_split_str(&bufp, ' '); - const char * flag_str = lv_xml_split_str(&bufp, ' '); - const char * ref_value_str = lv_xml_split_str(&bufp, ' '); - - if(subject_str == NULL) { - LV_LOG_WARN("Subject is missing in lv_obj bind_flag"); - } - else if(flag_str == NULL) { - LV_LOG_WARN("Flag is missing in lv_obj bind_flag"); - } - else if(ref_value_str == NULL) { - LV_LOG_WARN("Reference value is missing in lv_obj bind_flag"); - } - else { - lv_subject_t * subject = lv_xml_get_subject(&state->scope, subject_str); - if(subject == NULL) { - LV_LOG_WARN("Subject \"%s\" doesn't exist in lv_obj bind_flag", value); - } - else { - lv_obj_flag_t flag = flag_to_enum(flag_str); - int32_t ref_value = lv_xml_atoi(ref_value_str); - cb(item, subject, flag, ref_value); - } - } - } - } - else if(name_len >= 16 && lv_memcmp("bind_state_if_", name, 14) == 0) { - lv_observer_t * (*cb)(lv_obj_t * obj, lv_subject_t * subject, lv_state_t flag, int32_t ref_value) = NULL; - if(name[14] == 'e' && name[15] == 'q') cb = lv_obj_bind_state_if_eq; - else if(name[14] == 'n' && name[15] == 'o') cb = lv_obj_bind_state_if_not_eq; - else if(name[14] == 'g' && name[15] == 't') cb = lv_obj_bind_state_if_gt; - else if(name[14] == 'g' && name[15] == 'e') cb = lv_obj_bind_state_if_ge; - else if(name[14] == 'l' && name[15] == 't') cb = lv_obj_bind_state_if_lt; - else if(name[14] == 'l' && name[15] == 'e') cb = lv_obj_bind_state_if_le; - - if(cb) { - char buf[128]; - lv_strlcpy(buf, value, sizeof(buf)); - char * bufp = buf; - const char * subject_str = lv_xml_split_str(&bufp, ' '); - const char * state_str = lv_xml_split_str(&bufp, ' '); - const char * ref_value_str = lv_xml_split_str(&bufp, ' '); - - if(subject_str == NULL) { - LV_LOG_WARN("Subject is missing in lv_obj bind_state"); - } - else if(state_str == NULL) { - LV_LOG_WARN("State is missing in lv_obj bind_state"); - } - else if(ref_value_str == NULL) { - LV_LOG_WARN("Reference value is missing in lv_obj bind_state"); - } - else { - lv_subject_t * subject = lv_xml_get_subject(&state->scope, subject_str); - if(subject == NULL) { - LV_LOG_WARN("Subject \"%s\" doesn't exist in lv_obj bind_state", value); - } - else { - lv_state_t obj_state = lv_xml_state_to_enum(state_str); - int32_t ref_value = lv_xml_atoi(ref_value_str); - cb(item, subject, obj_state, ref_value); - } - } + LV_LOG_WARN("Subject `%s` doesn't exist in lv_obj bind_checked", value); } } @@ -217,6 +169,589 @@ void lv_xml_obj_apply(lv_xml_parser_state_t * state, const char ** attrs) } } +void * lv_obj_xml_style_create(lv_xml_parser_state_t * state, const char ** attrs) +{ + LV_UNUSED(attrs); + void * item = lv_xml_state_get_parent(state); + return item; +} + +void lv_obj_xml_style_apply(lv_xml_parser_state_t * state, const char ** attrs) +{ + const char * name = lv_xml_get_value_of(attrs, "name"); + if(name == NULL) { + /*Silently ignore this issue. + *The name set to NULL if there there was no default value when resolving params*/ + return; + } + lv_xml_style_t * xml_style = lv_xml_get_style_by_name(&state->scope, name); + if(xml_style == NULL) { + LV_LOG_WARN("`%s` style is not found", name); + return; + } + + const char * selector_str = lv_xml_get_value_of(attrs, "selector"); + lv_style_selector_t selector = lv_xml_style_selector_text_to_enum(selector_str); + + void * item = lv_xml_state_get_parent(state); + lv_obj_add_style(item, &xml_style->style, selector); +} + +void * lv_obj_xml_remove_style_create(lv_xml_parser_state_t * state, const char ** attrs) +{ + LV_UNUSED(attrs); + void * item = lv_xml_state_get_parent(state); + return item; +} + +void lv_obj_xml_remove_style_apply(lv_xml_parser_state_t * state, const char ** attrs) +{ + + const char * style_str = lv_xml_get_value_of(attrs, "name"); + const char * selector_str = lv_xml_get_value_of(attrs, "selector"); + + lv_style_t * style = NULL; + if(style_str) { + lv_xml_style_t * xml_style = lv_xml_get_style_by_name(&state->scope, style_str); + if(xml_style == NULL) { + LV_LOG_WARN("No style found with name `%s`", style_str); + return; + } + style = &xml_style->style; + } + + lv_style_selector_t selector = lv_xml_style_selector_text_to_enum(selector_str); + + void * item = lv_xml_state_get_item(state); + lv_obj_remove_style(item, style, selector); +} + +void * lv_obj_xml_remove_style_all_create(lv_xml_parser_state_t * state, const char ** attrs) +{ + LV_UNUSED(attrs); + void * item = lv_xml_state_get_parent(state); + return item; +} + +void lv_obj_xml_remove_style_all_apply(lv_xml_parser_state_t * state, const char ** attrs) +{ + LV_UNUSED(attrs); + void * item = lv_xml_state_get_item(state); + lv_obj_remove_style_all(item); +} + +void * lv_obj_xml_event_cb_create(lv_xml_parser_state_t * state, const char ** attrs) +{ + LV_UNUSED(attrs); + void * item = lv_xml_state_get_parent(state); + return item; +} + +void lv_obj_xml_event_cb_apply(lv_xml_parser_state_t * state, const char ** attrs) +{ + const char * trigger_str = lv_xml_get_value_of(attrs, "trigger"); + lv_event_code_t code = LV_EVENT_CLICKED; + if(trigger_str) code = lv_xml_trigger_text_to_enum_value(trigger_str); + if(code == LV_EVENT_LAST) { + LV_LOG_WARN("Couldn't add call function event because `%s` trigger is invalid.", trigger_str); + return; + } + + const char * cb_str = lv_xml_get_value_of(attrs, "callback"); + if(cb_str == NULL) { + LV_LOG_WARN("callback is mandatory for event-call_function"); + return; + } + + lv_obj_t * obj = lv_xml_state_get_parent(state); + lv_event_cb_t cb = lv_xml_get_event_cb(&state->scope, cb_str); + if(cb == NULL) { + LV_LOG_WARN("Couldn't add call function event because `%s` callback is not found.", cb_str); + return; + } + + const char * user_data_str = lv_xml_get_value_of(attrs, "user_data"); + char * user_data = NULL; + if(user_data_str) user_data = lv_strdup(user_data_str); + + lv_obj_add_event_cb(obj, cb, code, user_data); + if(user_data) lv_obj_add_event_cb(obj, lv_event_free_user_data_cb, LV_EVENT_DELETE, user_data); +} + +void * lv_obj_xml_subject_toggle_create(lv_xml_parser_state_t * state, const char ** attrs) +{ + LV_UNUSED(attrs); + void * item = lv_xml_state_get_parent(state); + return item; +} + +void lv_obj_xml_subject_toggle_apply(lv_xml_parser_state_t * state, const char ** attrs) +{ + /*If the tag_name is */ + const char * subject_str = lv_xml_get_value_of(attrs, "subject"); + const char * trigger_str = lv_xml_get_value_of(attrs, "trigger"); + + if(subject_str == NULL) { + LV_LOG_WARN("`subject` is missing in "); + return; + } + + lv_event_code_t trigger = LV_EVENT_CLICKED; + if(trigger_str) trigger = lv_xml_trigger_text_to_enum_value(trigger_str); + if(trigger == LV_EVENT_LAST) { + LV_LOG_WARN("Couldn't apply because `%s` trigger is invalid.", trigger_str); + return; + } + + lv_subject_t * subject = lv_xml_get_subject(&state->scope, subject_str); + if(subject == NULL) { + LV_LOG_WARN("Subject `%s` doesn't exist in ", subject_str); + return; + } + + void * item = lv_xml_state_get_item(state); + lv_obj_add_subject_toggle_event(item, subject, trigger); +} + +void * lv_obj_xml_subject_set_create(lv_xml_parser_state_t * state, const char ** attrs) +{ + LV_UNUSED(attrs); + void * item = lv_xml_state_get_parent(state); + return item; +} + +void lv_obj_xml_subject_set_apply(lv_xml_parser_state_t * state, const char ** attrs) +{ + + /*If the tag_name is */ + lv_subject_type_t subject_type = LV_SUBJECT_TYPE_NONE; + if(lv_streq(state->tag_name, "lv_obj-subject_set_int_event") || + lv_streq(state->tag_name, "subject_set_int_event")) { + subject_type = LV_SUBJECT_TYPE_INT; + } +#if LV_USE_FLOAT + else if(lv_streq(state->tag_name, "lv_obj-subject_set_float_event") || + lv_streq(state->tag_name, "subject_set_float_event")) { + subject_type = LV_SUBJECT_TYPE_FLOAT; + } +#endif + else if(lv_streq(state->tag_name, "lv_obj-subject_set_string_event") || + lv_streq(state->tag_name, "subject_set_string_event")) { + subject_type = LV_SUBJECT_TYPE_STRING; + } + else { + LV_LOG_WARN("`%s` is not supported in ", state->tag_name); + return; + } + + const char * subject_str = lv_xml_get_value_of(attrs, "subject"); + const char * trigger_str = lv_xml_get_value_of(attrs, "trigger"); + const char * value_str = lv_xml_get_value_of(attrs, "value"); + + if(subject_str == NULL) { + LV_LOG_WARN("`subject` is missing in "); + return; + } + + if(value_str == NULL) { + LV_LOG_WARN("`value` is missing in "); + return; + } + + lv_event_code_t trigger = LV_EVENT_CLICKED; + if(trigger_str) trigger = lv_xml_trigger_text_to_enum_value(trigger_str); + if(trigger == LV_EVENT_LAST) { + LV_LOG_WARN("Couldn't apply because `%s` trigger is invalid.", trigger_str); + return; + } + + lv_subject_t * subject = lv_xml_get_subject(&state->scope, subject_str); + if(subject == NULL) { + LV_LOG_WARN("Subject `%s` doesn't exist in ", subject_str); + return; + } + + if(subject->type != subject_type) { + LV_LOG_WARN("`%s` subject has incorrect type in ", subject_str); + return; + } + + void * item = lv_xml_state_get_item(state); + if(subject_type == LV_SUBJECT_TYPE_INT) { + lv_obj_add_subject_set_int_event(item, subject, trigger, lv_xml_atoi(value_str)); + } + else if(subject_type == LV_SUBJECT_TYPE_FLOAT) { +#if LV_USE_FLOAT + lv_obj_add_subject_set_float_event(item, subject, trigger, lv_xml_atof(value_str)); +#else + LV_LOG_ERROR("Tried to add a subject of type float but LV_USE_FLOAT is not enabled"); +#endif + } + else if(subject_type == LV_SUBJECT_TYPE_STRING) { + lv_obj_add_subject_set_string_event(item, subject, trigger, value_str); + } +} + +void * lv_obj_xml_subject_increment_create(lv_xml_parser_state_t * state, const char ** attrs) +{ + LV_UNUSED(attrs); + void * item = lv_xml_state_get_parent(state); + return item; +} + +void lv_obj_xml_subject_increment_apply(lv_xml_parser_state_t * state, const char ** attrs) +{ + const char * subject_str = lv_xml_get_value_of(attrs, "subject"); + const char * trigger_str = lv_xml_get_value_of(attrs, "trigger"); + const char * step_str = lv_xml_get_value_of(attrs, "step"); + const char * min_value_str = lv_xml_get_value_of(attrs, "min_value"); + const char * max_value_str = lv_xml_get_value_of(attrs, "max_value"); + const char * rollover_str = lv_xml_get_value_of(attrs, "rollover"); + + if(subject_str == NULL) { + LV_LOG_WARN("`subject` is missing in "); + return; + } + + if(step_str == NULL) step_str = "1"; + if(rollover_str == NULL) rollover_str = "false"; + + lv_event_code_t trigger = LV_EVENT_CLICKED; + if(trigger_str) trigger = lv_xml_trigger_text_to_enum_value(trigger_str); + if(trigger == LV_EVENT_LAST) { + LV_LOG_WARN("Couldn't apply because `%s` trigger is invalid.", trigger_str); + return; + } + + lv_subject_t * subject = lv_xml_get_subject(&state->scope, subject_str); + if(subject == NULL) { + LV_LOG_WARN("Subject `%s` doesn't exist in ", subject_str); + return; + } + + if(subject->type != LV_SUBJECT_TYPE_INT && subject->type != LV_SUBJECT_TYPE_FLOAT) { + LV_LOG_WARN("`%s` subject should have integer type in ", subject_str); + return; + } + + void * item = lv_xml_state_get_item(state); + + int32_t step = lv_xml_atoi(step_str); + lv_subject_increment_dsc_t * dsc = lv_obj_add_subject_increment_event(item, subject, trigger, step); + + if(min_value_str) lv_obj_set_subject_increment_event_min_value(item, dsc, lv_xml_atoi(min_value_str)); + if(max_value_str) lv_obj_set_subject_increment_event_max_value(item, dsc, lv_xml_atoi(max_value_str)); + if(rollover_str) lv_obj_set_subject_increment_event_rollover(item, dsc, lv_xml_to_bool(rollover_str)); +} + +void * lv_obj_xml_bind_style_create(lv_xml_parser_state_t * state, const char ** attrs) +{ + LV_UNUSED(attrs); + void * item = lv_xml_state_get_parent(state); + return item; +} + +void lv_obj_xml_bind_style_apply(lv_xml_parser_state_t * state, const char ** attrs) +{ + const char * name = lv_xml_get_value_of(attrs, "name"); + if(name == NULL) { + /*Silently ignore this issue. + *The name set to NULL if there there was no default value when resolving params*/ + return; + } + lv_xml_style_t * xml_style = lv_xml_get_style_by_name(&state->scope, name); + if(xml_style == NULL) { + LV_LOG_WARN("`%s` style is not found", name); + return; + } + const char * subject_str = lv_xml_get_value_of(attrs, "subject"); + + if(subject_str == NULL) { + LV_LOG_WARN("`subject` is missing in lv_obj bind_style"); + return; + } + + lv_subject_t * subject = lv_xml_get_subject(&state->scope, subject_str); + if(subject == NULL) { + LV_LOG_WARN("Subject `%s` doesn't exist in lv_obj bind_style", subject_str); + return; + } + + const char * ref_value_str = lv_xml_get_value_of(attrs, "ref_value"); + if(ref_value_str == NULL) { + LV_LOG_WARN("`ref_value` is missing in lv_obj bind_style"); + return; + } + + int32_t ref_value = lv_xml_atoi(ref_value_str); + + const char * selector_str = lv_xml_get_value_of(attrs, "selector"); + lv_style_selector_t selector = lv_xml_style_selector_text_to_enum(selector_str); + + void * item = lv_xml_state_get_parent(state); + lv_obj_bind_style(item, &xml_style->style, selector, subject, ref_value); +} + +void * lv_obj_xml_bind_flag_create(lv_xml_parser_state_t * state, const char ** attrs) +{ + LV_UNUSED(attrs); + void * item = lv_xml_state_get_parent(state); + return item; +} + +void lv_obj_xml_bind_flag_apply(lv_xml_parser_state_t * state, const char ** attrs) +{ + const char * op = state->tag_name; + + /*If starts with "lv_obj-" skip that part*/ + if(op[0] == 'l') op += 7; + + lv_observer_t * (*cb)(lv_obj_t * obj, lv_subject_t * subject, lv_obj_flag_t flag, int32_t ref_value) = NULL; + if(lv_streq(op, "bind_flag_if_eq")) cb = lv_obj_bind_flag_if_eq; + else if(lv_streq(op, "bind_flag_if_not_eq")) cb = lv_obj_bind_flag_if_not_eq; + else if(lv_streq(op, "bind_flag_if_gt")) cb = lv_obj_bind_flag_if_gt; + else if(lv_streq(op, "bind_flag_if_ge")) cb = lv_obj_bind_flag_if_ge; + else if(lv_streq(op, "bind_flag_if_lt")) cb = lv_obj_bind_flag_if_lt; + else if(lv_streq(op, "bind_flag_if_le")) cb = lv_obj_bind_flag_if_le; + else { + LV_LOG_WARN("`%s` is not known", op); + return; + } + + const char * subject_str = lv_xml_get_value_of(attrs, "subject"); + const char * flag_str = lv_xml_get_value_of(attrs, "flag"); + const char * ref_value_str = lv_xml_get_value_of(attrs, "ref_value"); + + if(subject_str == NULL) { + LV_LOG_WARN("`subject` is missing in lv_obj bind_flag"); + } + else if(flag_str == NULL) { + LV_LOG_WARN("`flag` is missing in lv_obj bind_flag"); + } + else if(ref_value_str == NULL) { + LV_LOG_WARN("`ref_value` is missing in lv_obj bind_flag"); + } + else { + lv_subject_t * subject = lv_xml_get_subject(&state->scope, subject_str); + if(subject == NULL) { + LV_LOG_WARN("Subject `%s` doesn't exist in lv_obj bind_flag", subject_str); + } + else { + lv_obj_flag_t flag = flag_to_enum(flag_str); + int32_t ref_value = lv_xml_atoi(ref_value_str); + void * item = lv_xml_state_get_item(state); + cb(item, subject, flag, ref_value); + } + } +} + +void * lv_obj_xml_bind_state_create(lv_xml_parser_state_t * state, const char ** attrs) +{ + LV_UNUSED(attrs); + void * item = lv_xml_state_get_parent(state); + return item; +} + +void lv_obj_xml_bind_state_apply(lv_xml_parser_state_t * state, const char ** attrs) +{ + const char * op = state->tag_name; + + /*If starts with "lv_obj-" skip that part*/ + if(op[0] == 'l') op += 7; + + lv_observer_t * (*cb)(lv_obj_t * obj, lv_subject_t * subject, lv_state_t flag, int32_t ref_value) = NULL; + if(lv_streq(op, "bind_state_if_eq")) cb = lv_obj_bind_state_if_eq; + else if(lv_streq(op, "bind_state_if_not_eq")) cb = lv_obj_bind_state_if_not_eq; + else if(lv_streq(op, "bind_state_if_gt")) cb = lv_obj_bind_state_if_gt; + else if(lv_streq(op, "bind_state_if_ge")) cb = lv_obj_bind_state_if_ge; + else if(lv_streq(op, "bind_state_if_lt")) cb = lv_obj_bind_state_if_lt; + else if(lv_streq(op, "bind_state_if_le")) cb = lv_obj_bind_state_if_le; + else { + LV_LOG_WARN("`%s` is not known", op); + return; + } + + const char * subject_str = lv_xml_get_value_of(attrs, "subject"); + const char * state_str = lv_xml_get_value_of(attrs, "state"); + const char * ref_value_str = lv_xml_get_value_of(attrs, "ref_value"); + + if(subject_str == NULL) { + LV_LOG_WARN("`subject` is missing in lv_obj state_flag"); + } + else if(state_str == NULL) { + LV_LOG_WARN("`state` is missing in lv_obj state_flag"); + } + else if(ref_value_str == NULL) { + LV_LOG_WARN("`ref_value` is missing in lv_obj state_flag"); + } + else { + lv_subject_t * subject = lv_xml_get_subject(&state->scope, subject_str); + if(subject == NULL) { + LV_LOG_WARN("Subject `%s` doesn't exist in bind_state", subject_str); + } + else { + lv_state_t s = lv_xml_state_to_enum(state_str); + int32_t ref_value = lv_xml_atoi(ref_value_str); + void * item = lv_xml_state_get_item(state); + cb(item, subject, s, ref_value); + } + } +} + +void * lv_obj_xml_screen_load_event_create(lv_xml_parser_state_t * state, const char ** attrs) +{ + LV_UNUSED(attrs); + void * item = lv_xml_state_get_parent(state); + return item; +} + +void lv_obj_xml_screen_load_event_apply(lv_xml_parser_state_t * state, const char ** attrs) +{ + const char * screen_str = lv_xml_get_value_of(attrs, "screen"); + const char * duration_str = lv_xml_get_value_of(attrs, "duration"); + const char * delay_str = lv_xml_get_value_of(attrs, "delay"); + const char * anim_type_str = lv_xml_get_value_of(attrs, "anim_type"); + const char * trigger_str = lv_xml_get_value_of(attrs, "trigger"); + + if(screen_str == NULL) { + LV_LOG_WARN("`screen` is missing in "); + return; + } + + if(duration_str == NULL) duration_str = "0"; + if(delay_str == NULL) delay_str = "0"; + if(anim_type_str == NULL) anim_type_str = "none"; + if(trigger_str == NULL) trigger_str = "clicked"; + + lv_event_code_t trigger = lv_xml_trigger_text_to_enum_value(trigger_str); + if(trigger == LV_EVENT_LAST) { + LV_LOG_WARN("Couldn't apply because `%s` trigger is invalid.", trigger_str); + return; + } + + int32_t duration = lv_xml_atoi(duration_str); + int32_t delay = lv_xml_atoi(delay_str); + lv_screen_load_anim_t anim_type = lv_xml_screen_load_anim_text_to_enum_value(anim_type_str); + + void * item = lv_xml_state_get_item(state); + + screen_load_anim_dsc_t * dsc = lv_malloc(sizeof(screen_load_anim_dsc_t)); + LV_ASSERT_MALLOC(dsc); + lv_memzero(dsc, sizeof(screen_load_anim_dsc_t)); + dsc->anim_type = anim_type; + dsc->duration = duration; + dsc->delay = delay; + dsc->screen_name = lv_strdup(screen_str); + + lv_obj_add_event_cb(item, screen_load_on_trigger_event_cb, trigger, dsc); + lv_obj_add_event_cb(item, free_screen_create_user_data_on_delete_event_cb, LV_EVENT_DELETE, dsc); +} + + +void * lv_obj_xml_screen_create_event_create(lv_xml_parser_state_t * state, const char ** attrs) +{ + LV_UNUSED(attrs); + void * item = lv_xml_state_get_parent(state); + return item; +} + +void lv_obj_xml_screen_create_event_apply(lv_xml_parser_state_t * state, const char ** attrs) +{ + const char * screen_str = lv_xml_get_value_of(attrs, "screen"); + const char * duration_str = lv_xml_get_value_of(attrs, "duration"); + const char * delay_str = lv_xml_get_value_of(attrs, "delay"); + const char * anim_type_str = lv_xml_get_value_of(attrs, "anim_type"); + const char * trigger_str = lv_xml_get_value_of(attrs, "trigger"); + + if(screen_str == NULL) { + LV_LOG_WARN("`screen` is missing in "); + return; + } + + if(duration_str == NULL) duration_str = "0"; + if(delay_str == NULL) delay_str = "0"; + if(anim_type_str == NULL) anim_type_str = "none"; + if(trigger_str == NULL) trigger_str = "clicked"; + + lv_event_code_t trigger = lv_xml_trigger_text_to_enum_value(trigger_str); + if(trigger == LV_EVENT_LAST) { + LV_LOG_WARN("Couldn't apply because `%s` trigger is invalid.", trigger_str); + return; + } + + int32_t duration = lv_xml_atoi(duration_str); + int32_t delay = lv_xml_atoi(delay_str); + lv_screen_load_anim_t anim_type = lv_xml_screen_load_anim_text_to_enum_value(anim_type_str); + + screen_load_anim_dsc_t * dsc = lv_malloc(sizeof(screen_load_anim_dsc_t)); + LV_ASSERT_MALLOC(dsc); + lv_memzero(dsc, sizeof(screen_load_anim_dsc_t)); + dsc->anim_type = anim_type; + dsc->duration = duration; + dsc->delay = delay; + dsc->screen_name = lv_strdup(screen_str); + + void * item = lv_xml_state_get_item(state); + lv_obj_add_event_cb(item, screen_create_on_trigger_event_cb, trigger, dsc); + lv_obj_add_event_cb(item, free_screen_create_user_data_on_delete_event_cb, LV_EVENT_DELETE, dsc); +} + +void * lv_obj_xml_play_timeline_event_create(lv_xml_parser_state_t * state, const char ** attrs) +{ + LV_UNUSED(attrs); + void * item = lv_xml_state_get_parent(state); + return item; +} + +void lv_obj_xml_play_timeline_event_apply(lv_xml_parser_state_t * state, const char ** attrs) +{ + + if(state->view == NULL) { + /*Shouldn't happen*/ + LV_LOG_WARN("view is not set, can't add the event"); + return; + } + + const char * target_str = lv_xml_get_value_of(attrs, "target"); + const char * delay_str = lv_xml_get_value_of(attrs, "delay"); + const char * trigger_str = lv_xml_get_value_of(attrs, "trigger"); + const char * timeline_str = lv_xml_get_value_of(attrs, "timeline"); + const char * reverse_str = lv_xml_get_value_of(attrs, "reverse"); + + if(target_str == NULL) { + LV_LOG_WARN("`target` is missing in "); + return; + } + + if(timeline_str == NULL) { + LV_LOG_WARN("`timeline` is missing in "); + return; + } + + if(delay_str == NULL) delay_str = "0"; + if(trigger_str == NULL) trigger_str = "clicked"; + if(reverse_str == NULL) reverse_str = "false"; + + lv_event_code_t trigger = lv_xml_trigger_text_to_enum_value(trigger_str); + if(trigger == LV_EVENT_LAST) { + LV_LOG_WARN("Couldn't apply because `%s` trigger is invalid.", trigger_str); + return; + } + + play_anim_dsc_t * dsc = lv_malloc(sizeof(play_anim_dsc_t)); + LV_ASSERT_MALLOC(dsc); + lv_memzero(dsc, sizeof(play_anim_dsc_t)); + dsc->target_name = lv_strdup(target_str); + dsc->timeline_name = lv_strdup(timeline_str); + dsc->delay = lv_xml_atoi(delay_str); + dsc->reverse = lv_xml_to_bool(reverse_str); + dsc->base_obj = state->view; + + void * item = lv_xml_state_get_item(state); + lv_obj_add_event_cb(item, play_anim_on_trigger_event_cb, trigger, dsc); + lv_obj_add_event_cb(item, free_play_anim_user_data_on_delete_event_cb, LV_EVENT_DELETE, dsc); +} + /********************** * STATIC FUNCTIONS **********************/ @@ -239,6 +774,8 @@ static lv_obj_flag_t flag_to_enum(const char * txt) if(lv_streq("snappable", txt)) return LV_OBJ_FLAG_SNAPPABLE; if(lv_streq("press_lock", txt)) return LV_OBJ_FLAG_PRESS_LOCK; if(lv_streq("event_bubble", txt)) return LV_OBJ_FLAG_EVENT_BUBBLE; + if(lv_streq("event_trickle", txt)) return LV_OBJ_FLAG_EVENT_TRICKLE; + if(lv_streq("state_trickle", txt)) return LV_OBJ_FLAG_STATE_TRICKLE; if(lv_streq("gesture_bubble", txt)) return LV_OBJ_FLAG_GESTURE_BUBBLE; if(lv_streq("adv_hittest", txt)) return LV_OBJ_FLAG_ADV_HITTEST; if(lv_streq("ignore_layout", txt)) return LV_OBJ_FLAG_IGNORE_LAYOUT; @@ -276,6 +813,8 @@ static void apply_styles(lv_xml_parser_state_t * state, lv_obj_t * obj, const ch else SET_STYLE_IF(max_height, lv_xml_to_size(value)); else SET_STYLE_IF(length, lv_xml_to_size(value)); else SET_STYLE_IF(radius, lv_xml_to_size(value)); + else SET_STYLE_IF(radial_offset, lv_xml_atoi(value)); + else SET_STYLE_IF(align, lv_xml_align_to_enum(value)); else SET_STYLE_IF(pad_left, lv_xml_atoi(value)); else SET_STYLE_IF(pad_right, lv_xml_atoi(value)); @@ -372,6 +911,7 @@ static void apply_styles(lv_xml_parser_state_t * state, lv_obj_t * obj, const ch else SET_STYLE_IF(transform_pivot_x, lv_xml_atoi(value)); else SET_STYLE_IF(transform_pivot_y, lv_xml_atoi(value)); else SET_STYLE_IF(transform_skew_x, lv_xml_atoi(value)); + else SET_STYLE_IF(transform_skew_y, lv_xml_atoi(value)); else SET_STYLE_IF(bitmap_mask_src, lv_xml_get_image(&state->scope, value)); else SET_STYLE_IF(rotary_sensitivity, lv_xml_atoi(value)); else SET_STYLE_IF(recolor, lv_xml_to_color(value)); @@ -393,7 +933,163 @@ static void apply_styles(lv_xml_parser_state_t * state, lv_obj_t * obj, const ch else SET_STYLE_IF(grid_cell_row_pos, lv_xml_atoi(value)); else SET_STYLE_IF(grid_cell_row_span, lv_xml_atoi(value)); else SET_STYLE_IF(grid_cell_y_align, lv_xml_grid_align_to_enum(value)); + else if(lv_streq(prop_name, "style_grid_column_dsc_array") || + lv_streq(prop_name, "style_grid_row_dsc_array")) { + + uint32_t item_cnt = 0; + uint32_t i; + for(i = 0; value[i] != '\0'; i++) { + if(value[i] == ' ') item_cnt++; + } + + int32_t * dsc_array = lv_malloc((item_cnt + 2) * sizeof(int32_t)); /*+2 for LV_GRID_TEMPLATE_LAST*/ + + char * value_buf = (char *)value; + item_cnt = 0; + const char * sub_value = lv_xml_split_str(&value_buf, ' '); + while(sub_value) { + if(sub_value[0] == 'f' && sub_value[1] == 'r') { + dsc_array[item_cnt] = LV_GRID_FR(lv_xml_atoi(sub_value + 3)); /*+3 to skip "fr("*/ + } + else { + dsc_array[item_cnt] = lv_xml_atoi(sub_value); + } + + item_cnt++; + sub_value = lv_xml_split_str(&value_buf, ' '); + } + + dsc_array[item_cnt] = LV_GRID_TEMPLATE_LAST; + + lv_obj_add_event_cb(obj, lv_event_free_user_data_cb, LV_EVENT_DELETE, dsc_array); + + if(lv_streq(prop_name, "style_grid_column_dsc_array")) { + lv_obj_set_style_grid_column_dsc_array(obj, dsc_array, selector); + } + else { + lv_obj_set_style_grid_row_dsc_array(obj, dsc_array, selector); + } + } +} + + +static void screen_create_on_trigger_event_cb(lv_event_t * e) +{ + screen_load_anim_dsc_t * dsc = lv_event_get_user_data(e); + LV_ASSERT_NULL(dsc); + + lv_obj_t * screen = lv_xml_create(NULL, dsc->screen_name, NULL); + if(screen == NULL) { + LV_LOG_WARN("Couldn't create screen `%s`", dsc->screen_name); + return; + } + lv_screen_load_anim(screen, dsc->anim_type, dsc->duration, dsc->delay, false); + lv_obj_add_event_cb(screen, delete_on_screen_unloaded_event_cb, LV_EVENT_SCREEN_UNLOADED, NULL); + lv_obj_add_event_cb(screen, free_screen_create_user_data_on_delete_event_cb, LV_EVENT_SCREEN_UNLOADED, NULL); +} + +static void screen_load_on_trigger_event_cb(lv_event_t * e) +{ + screen_load_anim_dsc_t * dsc = lv_event_get_user_data(e); + LV_ASSERT_NULL(dsc); + + lv_obj_t * screen = lv_display_get_screen_by_name(NULL, dsc->screen_name); + if(screen == NULL) { + LV_LOG_WARN("No screen is found with `%s` name", dsc->screen_name); + return; + } + + lv_screen_load_anim(screen, dsc->anim_type, dsc->duration, dsc->delay, false); +} + +static void delete_on_screen_unloaded_event_cb(lv_event_t * e) +{ + lv_obj_delete(lv_event_get_target_obj(e)); +} + +static void free_screen_create_user_data_on_delete_event_cb(lv_event_t * e) +{ + screen_load_anim_dsc_t * dsc = lv_event_get_user_data(e); + lv_free((void *)dsc->screen_name); + lv_free(dsc); +} + +static void play_anim_on_trigger_event_cb(lv_event_t * e) +{ + play_anim_dsc_t * dsc = lv_event_get_user_data(e); + LV_ASSERT_NULL(dsc); + + lv_obj_t * target; + + if(lv_streq(dsc->target_name, "self")) { + target = dsc->base_obj; + } + else { + target = lv_obj_find_by_name(dsc->base_obj, dsc->target_name); + } + + if(target == NULL) { + LV_LOG_WARN("No target widget is found with `%s` name", dsc->target_name); + return; + } + + lv_anim_timeline_t * timeline = NULL; + lv_anim_timeline_t ** timeline_array = NULL; + lv_obj_send_event(target, lv_event_xml_store_timeline, &timeline_array); + if(timeline_array == NULL) { + LV_LOG_WARN("No time lines are stored in `%s`", dsc->target_name); + return; + } + + uint32_t i; + for(i = 0; timeline_array[i]; i++) { + const char * name = lv_anim_timeline_get_user_data(timeline_array[i]); + if(lv_streq(name, dsc->timeline_name)) { + timeline = timeline_array[i]; + break; + } + } + + if(timeline == NULL) { + LV_LOG_WARN("No timeline is found for `%s` with `%s` name", dsc->target_name, dsc->timeline_name); + return; + } + + /*Reset the progress only if the animation was finished*/ + uint16_t progress = lv_anim_timeline_get_progress(timeline); + if(dsc->reverse) { + if(progress == 0) { + lv_anim_timeline_set_progress(timeline, LV_ANIM_TIMELINE_PROGRESS_MAX); + } + + if(lv_anim_timeline_get_progress(timeline) == LV_ANIM_TIMELINE_PROGRESS_MAX) { + lv_anim_timeline_set_delay(timeline, dsc->delay); + } + + lv_anim_timeline_set_reverse(timeline, true); + } + else { + if(progress == LV_ANIM_TIMELINE_PROGRESS_MAX) { + lv_anim_timeline_set_progress(timeline, 0); + } + + if(lv_anim_timeline_get_progress(timeline) == 0) { + lv_anim_timeline_set_delay(timeline, dsc->delay); + } + + lv_anim_timeline_set_reverse(timeline, false); + } + + lv_anim_timeline_start(timeline); + } +static void free_play_anim_user_data_on_delete_event_cb(lv_event_t * e) +{ + play_anim_dsc_t * dsc = lv_event_get_user_data(e); + lv_free((void *)dsc->target_name); + lv_free((void *)dsc->timeline_name); + lv_free(dsc); +} #endif /* LV_USE_XML */ diff --git a/src/others/xml/parsers/lv_xml_obj_parser.h b/src/others/xml/parsers/lv_xml_obj_parser.h index 2388812785..618fe86a1f 100644 --- a/src/others/xml/parsers/lv_xml_obj_parser.h +++ b/src/others/xml/parsers/lv_xml_obj_parser.h @@ -3,8 +3,8 @@ * */ -#ifndef LV_OBJ_XML_PARSER_H -#define LV_OBJ_XML_PARSER_H +#ifndef LV_XML_OBJ_PARSER_H +#define LV_XML_OBJ_PARSER_H #ifdef __cplusplus extern "C" { @@ -27,6 +27,45 @@ extern "C" { void * lv_xml_obj_create(lv_xml_parser_state_t * state, const char ** attrs); void lv_xml_obj_apply(lv_xml_parser_state_t * state, const char ** attrs); +void * lv_obj_xml_style_create(lv_xml_parser_state_t * state, const char ** attrs); +void lv_obj_xml_style_apply(lv_xml_parser_state_t * state, const char ** attrs); + +void * lv_obj_xml_remove_style_create(lv_xml_parser_state_t * state, const char ** attrs); +void lv_obj_xml_remove_style_apply(lv_xml_parser_state_t * state, const char ** attrs); + +void * lv_obj_xml_remove_style_all_create(lv_xml_parser_state_t * state, const char ** attrs); +void lv_obj_xml_remove_style_all_apply(lv_xml_parser_state_t * state, const char ** attrs); + +void * lv_obj_xml_event_cb_create(lv_xml_parser_state_t * state, const char ** attrs); +void lv_obj_xml_event_cb_apply(lv_xml_parser_state_t * state, const char ** attrs); + +void * lv_obj_xml_subject_toggle_create(lv_xml_parser_state_t * state, const char ** attrs); +void lv_obj_xml_subject_toggle_apply(lv_xml_parser_state_t * state, const char ** attrs); + +void * lv_obj_xml_subject_set_create(lv_xml_parser_state_t * state, const char ** attrs); +void lv_obj_xml_subject_set_apply(lv_xml_parser_state_t * state, const char ** attrs); + +void * lv_obj_xml_subject_increment_create(lv_xml_parser_state_t * state, const char ** attrs); +void lv_obj_xml_subject_increment_apply(lv_xml_parser_state_t * state, const char ** attrs); + +void * lv_obj_xml_bind_style_create(lv_xml_parser_state_t * state, const char ** attrs); +void lv_obj_xml_bind_style_apply(lv_xml_parser_state_t * state, const char ** attrs); + +void * lv_obj_xml_bind_flag_create(lv_xml_parser_state_t * state, const char ** attrs); +void lv_obj_xml_bind_flag_apply(lv_xml_parser_state_t * state, const char ** attrs); + +void * lv_obj_xml_bind_state_create(lv_xml_parser_state_t * state, const char ** attrs); +void lv_obj_xml_bind_state_apply(lv_xml_parser_state_t * state, const char ** attrs); + +void * lv_obj_xml_screen_load_event_create(lv_xml_parser_state_t * state, const char ** attrs); +void lv_obj_xml_screen_load_event_apply(lv_xml_parser_state_t * state, const char ** attrs); + +void * lv_obj_xml_screen_create_event_create(lv_xml_parser_state_t * state, const char ** attrs); +void lv_obj_xml_screen_create_event_apply(lv_xml_parser_state_t * state, const char ** attrs); + +void * lv_obj_xml_play_timeline_event_create(lv_xml_parser_state_t * state, const char ** attrs); +void lv_obj_xml_play_timeline_event_apply(lv_xml_parser_state_t * state, const char ** attrs); + /********************** * MACROS **********************/ @@ -37,4 +76,4 @@ void lv_xml_obj_apply(lv_xml_parser_state_t * state, const char ** attrs); } /*extern "C"*/ #endif -#endif /*LV_OBJ_XML_PARSE_H*/ +#endif /*LV_XML_OBJ_PARSER_H*/ diff --git a/src/others/xml/parsers/lv_xml_qrcode_parser.c b/src/others/xml/parsers/lv_xml_qrcode_parser.c new file mode 100644 index 0000000000..a9d72ec8b4 --- /dev/null +++ b/src/others/xml/parsers/lv_xml_qrcode_parser.c @@ -0,0 +1,68 @@ +/** + * @file lv_xml_qrcode_parser.c + * + */ + +/********************* + * INCLUDES + *********************/ +#include "lv_xml_qrcode_parser.h" +#if LV_USE_XML && LV_USE_QRCODE + +#include "../../../lvgl.h" +#include "../../../lvgl_private.h" + +/********************* + * DEFINES + *********************/ + +/********************** + * TYPEDEFS + **********************/ + +/********************** + * STATIC PROTOTYPES + **********************/ + +/********************** + * STATIC VARIABLES + **********************/ + +/********************** + * MACROS + **********************/ + +/********************** + * GLOBAL FUNCTIONS + **********************/ + +void * lv_xml_qrcode_create(lv_xml_parser_state_t * state, const char ** attrs) +{ + LV_UNUSED(attrs); + + void * item = lv_qrcode_create(lv_xml_state_get_parent(state)); + return item; +} + +void lv_xml_qrcode_apply(lv_xml_parser_state_t * state, const char ** attrs) +{ + void * item = lv_xml_state_get_item(state); + lv_xml_obj_apply(state, attrs); /*Apply the common properties, e.g. width, height, styles flags etc*/ + + for(int i = 0; attrs[i]; i += 2) { + const char * name = attrs[i]; + const char * value = attrs[i + 1]; + + if(lv_streq("size", name)) lv_qrcode_set_size(item, lv_xml_atoi(value)); + else if(lv_streq("dark_color", name)) lv_qrcode_set_dark_color(item, lv_xml_to_color(value)); + else if(lv_streq("light_color", name)) lv_qrcode_set_light_color(item, lv_xml_to_color(value)); + else if(lv_streq("data", name)) lv_qrcode_set_data(item, value); + else if(lv_streq("quiet_zone", name)) lv_qrcode_set_quiet_zone(item, lv_xml_to_bool(value)); + } +} + +/********************** + * STATIC FUNCTIONS + **********************/ + +#endif /* LV_USE_XML */ diff --git a/src/others/xml/parsers/lv_xml_qrcode_parser.h b/src/others/xml/parsers/lv_xml_qrcode_parser.h new file mode 100644 index 0000000000..f1925968dc --- /dev/null +++ b/src/others/xml/parsers/lv_xml_qrcode_parser.h @@ -0,0 +1,40 @@ +/** + * @file lv_xml_qrcode_parser.h + * + */ + +#ifndef LV_XML_QRCODE_PARSER_H +#define LV_XML_QRCODE_PARSER_H + +#ifdef __cplusplus +extern "C" { +#endif + +/********************* + * INCLUDES + *********************/ +#include "../lv_xml.h" +#if LV_USE_XML && LV_USE_QRCODE + +/********************** + * TYPEDEFS + **********************/ + +/********************** + * GLOBAL PROTOTYPES + **********************/ + +void * lv_xml_qrcode_create(lv_xml_parser_state_t * state, const char ** attrs); +void lv_xml_qrcode_apply(lv_xml_parser_state_t * state, const char ** attrs); + +/********************** + * MACROS + **********************/ + +#endif /* LV_USE_XML */ + +#ifdef __cplusplus +} /*extern "C"*/ +#endif + +#endif /* LV_XML_QRCODE_PARSER_H */ diff --git a/src/others/xml/parsers/lv_xml_roller_parser.c b/src/others/xml/parsers/lv_xml_roller_parser.c index 616af0fa7f..9a96ad8a6d 100644 --- a/src/others/xml/parsers/lv_xml_roller_parser.c +++ b/src/others/xml/parsers/lv_xml_roller_parser.c @@ -7,7 +7,7 @@ * INCLUDES *********************/ #include "lv_xml_roller_parser.h" -#if LV_USE_XML +#if LV_USE_XML && LV_USE_ROLLER #include "../../../lvgl.h" #include "../../../lvgl_private.h" @@ -55,39 +55,19 @@ void lv_xml_roller_apply(lv_xml_parser_state_t * state, const char ** attrs) const char * value = attrs[i + 1]; if(lv_streq("selected", name)) { - char buf[64]; - lv_strlcpy(buf, value, sizeof(buf)); - char * buf_p = buf; - int32_t v1 = lv_xml_atoi(lv_xml_split_str(&buf_p, ' ')); - bool v2 = lv_xml_to_bool(buf_p); - lv_roller_set_selected(item, v1, v2); + int32_t v = lv_xml_atoi(value); + const char * anim_str = lv_xml_get_value_of(attrs, "value-animated"); + bool anim = anim_str ? lv_xml_to_bool(anim_str) : false; + lv_roller_set_selected(item, v, anim); } if(lv_streq("visible_row_count", name)) { lv_roller_set_visible_row_count(item, lv_xml_atoi(value)); } if(lv_streq("options", name)) { - /*E.g. 'a\nb\nc' true'*/ - size_t opts_len = lv_strlen(value); - char * opts_buf = lv_malloc(opts_len + 1); - lv_memcpy(opts_buf, value, opts_len + 1); - LV_ASSERT_MALLOC(opts_buf); - - /*Find the last space and trim the rest*/ - uint32_t space_pos_from_back = 1; - while(space_pos_from_back < opts_len && value[opts_len - space_pos_from_back] != ' ') { - space_pos_from_back++; - } - - opts_buf[opts_len - space_pos_from_back - 1] = '\0'; /*Also trim the `'`*/ - - lv_roller_mode_t mode = mode_text_to_enum_value(&opts_buf[opts_len - space_pos_from_back + 1]); - - /*Also skip the leading `'`*/ - lv_roller_set_options(item, opts_buf + 1, mode); - - lv_free(opts_buf); - + const char * mode_str = lv_xml_get_value_of(attrs, "options-mode"); + lv_roller_mode_t mode = mode_str ? mode_text_to_enum_value(mode_str) : LV_ROLLER_MODE_NORMAL; + lv_roller_set_options(item, value, mode); } else if(lv_streq("bind_value", name)) { lv_subject_t * subject = lv_xml_get_subject(&state->scope, value); diff --git a/src/others/xml/parsers/lv_xml_roller_parser.h b/src/others/xml/parsers/lv_xml_roller_parser.h index f351b26558..a9f1f76af1 100644 --- a/src/others/xml/parsers/lv_xml_roller_parser.h +++ b/src/others/xml/parsers/lv_xml_roller_parser.h @@ -3,8 +3,8 @@ * */ -#ifndef LV_ROLLER_XML_PARSER_H -#define LV_ROLLER_XML_PARSER_H +#ifndef LV_XML_ROLLER_PARSER_H +#define LV_XML_ROLLER_PARSER_H #ifdef __cplusplus extern "C" { @@ -14,7 +14,7 @@ extern "C" { * INCLUDES *********************/ #include "../lv_xml.h" -#if LV_USE_XML +#if LV_USE_XML && LV_USE_ROLLER /********************** * TYPEDEFS @@ -37,4 +37,4 @@ void lv_xml_roller_apply(lv_xml_parser_state_t * state, const char ** attrs); } /*extern "C"*/ #endif -#endif /*LV_ROLLER_XML_PARSE_H*/ +#endif /*LV_XML_ROLLER_PARSER_H*/ diff --git a/src/others/xml/parsers/lv_xml_scale_parser.c b/src/others/xml/parsers/lv_xml_scale_parser.c index 0d63a116f9..1259ddc6cc 100644 --- a/src/others/xml/parsers/lv_xml_scale_parser.c +++ b/src/others/xml/parsers/lv_xml_scale_parser.c @@ -7,7 +7,7 @@ * INCLUDES *********************/ #include "lv_xml_scale_parser.h" -#if LV_USE_XML +#if LV_USE_XML && LV_USE_SCALE #include "../../../lvgl.h" #include "../../../lvgl_private.h" @@ -65,13 +65,10 @@ void lv_xml_scale_apply(lv_xml_parser_state_t * state, const char ** attrs) else if(lv_streq("label_show", name)) lv_scale_set_label_show(item, lv_xml_to_bool(value)); else if(lv_streq("post_draw", name)) lv_scale_set_post_draw(item, lv_xml_to_bool(value)); else if(lv_streq("draw_ticks_on_top", name)) lv_scale_set_draw_ticks_on_top(item, lv_xml_to_bool(value)); - else if(lv_streq("range", name)) { - int32_t value1 = lv_xml_atoi_split(&value, ' '); - int32_t value2 = lv_xml_atoi_split(&value, ' '); - lv_scale_set_range(item, value1, value2); - } - else if(lv_streq("angle_range", name)) lv_scale_set_angle_range(item, lv_xml_to_bool(value)); - else if(lv_streq("rotation", name)) lv_scale_set_rotation(item, lv_xml_to_bool(value)); + else if(lv_streq("min_value", name)) lv_scale_set_min_value(item, lv_xml_atoi(value)); + else if(lv_streq("max_value", name)) lv_scale_set_max_value(item, lv_xml_atoi(value)); + else if(lv_streq("angle_range", name)) lv_scale_set_angle_range(item, lv_xml_atoi(value)); + else if(lv_streq("rotation", name)) lv_scale_set_rotation(item, lv_xml_atoi(value)); } } @@ -94,11 +91,8 @@ void lv_xml_scale_section_apply(lv_xml_parser_state_t * state, const char ** att const char * name = attrs[i]; const char * value = attrs[i + 1]; - if(lv_streq("range", name)) { - int32_t value1 = lv_xml_atoi_split(&value, ' '); - int32_t value2 = lv_xml_atoi_split(&value, ' '); - lv_scale_set_section_range(scale, section, value1, value2); - } + if(lv_streq("min_value", name)) lv_scale_set_section_min_value(scale, section, lv_xml_atoi(value)); + else if(lv_streq("max_value", name)) lv_scale_set_section_max_value(scale, section, lv_xml_atoi(value)); else if(lv_streq("style_main", name)) { lv_xml_style_t * style_dsc = lv_xml_get_style_by_name(&state->scope, value); lv_scale_set_section_style_main(scale, section, &style_dsc->style); @@ -111,6 +105,24 @@ void lv_xml_scale_section_apply(lv_xml_parser_state_t * state, const char ** att lv_xml_style_t * style_dsc = lv_xml_get_style_by_name(&state->scope, value); lv_scale_set_section_style_items(scale, section, &style_dsc->style); } + else if(lv_streq("bind_min_value", name)) { + lv_subject_t * subject = lv_xml_get_subject(&state->scope, value); + if(subject) { + lv_scale_bind_section_min_value(scale, section, subject); + } + else { + LV_LOG_WARN("Subject \"%s\" doesn't exist in scale section's bind_min_value", value); + } + } + else if(lv_streq("bind_max_value", name)) { + lv_subject_t * subject = lv_xml_get_subject(&state->scope, value); + if(subject) { + lv_scale_bind_section_max_value(scale, section, subject); + } + else { + LV_LOG_WARN("Subject \"%s\" doesn't exist in scale section's bind_max_value", value); + } + } } } diff --git a/src/others/xml/parsers/lv_xml_scale_parser.h b/src/others/xml/parsers/lv_xml_scale_parser.h index a7fc00841a..8a923b2456 100644 --- a/src/others/xml/parsers/lv_xml_scale_parser.h +++ b/src/others/xml/parsers/lv_xml_scale_parser.h @@ -3,8 +3,8 @@ * */ -#ifndef LV_SCALE_XML_PARSER_H -#define LV_SCALE_XML_PARSER_H +#ifndef LV_XML_SCALE_PARSER_H +#define LV_XML_SCALE_PARSER_H #ifdef __cplusplus extern "C" { @@ -14,7 +14,7 @@ extern "C" { * INCLUDES *********************/ #include "../lv_xml.h" -#if LV_USE_XML +#if LV_USE_XML && LV_USE_SCALE /********************** * TYPEDEFS @@ -38,4 +38,4 @@ void lv_xml_scale_section_apply(lv_xml_parser_state_t * state, const char ** att } /*extern "C"*/ #endif -#endif /*LV_SCALE_XML_PARSE_H*/ +#endif /*LV_XML_SCALE_PARSER_H*/ diff --git a/src/others/xml/parsers/lv_xml_slider_parser.c b/src/others/xml/parsers/lv_xml_slider_parser.c index dea62f35da..b7f055ab8a 100644 --- a/src/others/xml/parsers/lv_xml_slider_parser.c +++ b/src/others/xml/parsers/lv_xml_slider_parser.c @@ -7,7 +7,7 @@ * INCLUDES *********************/ #include "lv_xml_slider_parser.h" -#if LV_USE_XML +#if LV_USE_XML && LV_USE_SLIDER #include "../../../lvgl.h" #include "../../../lvgl_private.h" @@ -23,7 +23,7 @@ /********************** * STATIC PROTOTYPES **********************/ -static lv_slider_orientation_t orentation_text_to_enum_value(const char * txt); +static lv_slider_orientation_t orientation_text_to_enum_value(const char * txt); static lv_slider_mode_t mode_text_to_enum_value(const char * txt); /********************** @@ -56,14 +56,18 @@ void lv_xml_slider_apply(lv_xml_parser_state_t * state, const char ** attrs) const char * value = attrs[i + 1]; if(lv_streq("value", name)) { - char buf[64]; - lv_strlcpy(buf, value, sizeof(buf)); - char * buf_p = buf; - int32_t v1 = lv_xml_atoi(lv_xml_split_str(&buf_p, ' ')); - bool v2 = lv_xml_to_bool(buf_p); - lv_bar_set_value(item, v1, v2); + int32_t v = lv_xml_atoi(value); + const char * anim_str = lv_xml_get_value_of(attrs, "value-animated"); + bool anim = anim_str ? lv_xml_to_bool(anim_str) : false; + lv_slider_set_value(item, v, anim); } - if(lv_streq("bind_value", name)) { + else if(lv_streq("start_value", name)) { + int32_t v = lv_xml_atoi(value); + const char * anim_str = lv_xml_get_value_of(attrs, "start_value-animated"); + bool anim = anim_str ? lv_xml_to_bool(anim_str) : false; + lv_slider_set_start_value(item, v, anim); + } + else if(lv_streq("bind_value", name)) { lv_subject_t * subject = lv_xml_get_subject(&state->scope, value); if(subject) { lv_slider_bind_value(item, subject); @@ -72,26 +76,10 @@ void lv_xml_slider_apply(lv_xml_parser_state_t * state, const char ** attrs) LV_LOG_WARN("Subject \"%s\" doesn't exist in slider bind_value", value); } } - if(lv_streq("start_value", name)) { - char buf[64]; - lv_strlcpy(buf, value, sizeof(buf)); - char * buf_p = buf; - int32_t v1 = lv_xml_atoi(lv_xml_split_str(&buf_p, ' ')); - bool v2 = lv_xml_to_bool(buf_p); - lv_bar_set_start_value(item, v1, v2); - } - if(lv_streq("orientation", name)) lv_slider_set_orientation(item, orentation_text_to_enum_value(value)); - if(lv_streq("mode", name)) lv_slider_set_mode(item, mode_text_to_enum_value(value)); - if(lv_streq("range_min", name)) lv_slider_set_range(item, lv_xml_atoi(value), lv_slider_get_max_value(item)); - if(lv_streq("range_max", name)) lv_slider_set_range(item, lv_slider_get_min_value(item), lv_xml_atoi(value)); - if(lv_streq("range", name)) { - char buf[64]; - lv_strlcpy(buf, value, sizeof(buf)); - char * buf_p = buf; - int32_t v1 = lv_xml_atoi(lv_xml_split_str(&buf_p, ' ')); - int32_t v2 = lv_xml_atoi(buf_p); - lv_slider_set_range(item, v1, v2); - } + else if(lv_streq("orientation", name)) lv_slider_set_orientation(item, orientation_text_to_enum_value(value)); + else if(lv_streq("mode", name)) lv_slider_set_mode(item, mode_text_to_enum_value(value)); + else if(lv_streq("min_value", name)) lv_slider_set_min_value(item, lv_xml_atoi(value)); + else if(lv_streq("max_value", name)) lv_slider_set_max_value(item, lv_xml_atoi(value)); } } @@ -99,7 +87,7 @@ void lv_xml_slider_apply(lv_xml_parser_state_t * state, const char ** attrs) * STATIC FUNCTIONS **********************/ -static lv_slider_orientation_t orentation_text_to_enum_value(const char * txt) +static lv_slider_orientation_t orientation_text_to_enum_value(const char * txt) { if(lv_streq("auto", txt)) return LV_SLIDER_ORIENTATION_AUTO; if(lv_streq("horizontal", txt)) return LV_SLIDER_ORIENTATION_HORIZONTAL; diff --git a/src/others/xml/parsers/lv_xml_slider_parser.h b/src/others/xml/parsers/lv_xml_slider_parser.h index cd387efcb4..d2dac45864 100644 --- a/src/others/xml/parsers/lv_xml_slider_parser.h +++ b/src/others/xml/parsers/lv_xml_slider_parser.h @@ -3,8 +3,8 @@ * */ -#ifndef LV_SLIDER_XML_PARSER_H -#define LV_SLIDER_XML_PARSER_H +#ifndef LV_XML_SLIDER_PARSER_H +#define LV_XML_SLIDER_PARSER_H #ifdef __cplusplus extern "C" { @@ -14,7 +14,7 @@ extern "C" { * INCLUDES *********************/ #include "../lv_xml.h" -#if LV_USE_XML +#if LV_USE_XML && LV_USE_SLIDER /********************** * TYPEDEFS @@ -37,4 +37,4 @@ void lv_xml_slider_apply(lv_xml_parser_state_t * state, const char ** attrs); } /*extern "C"*/ #endif -#endif /*LV_SLIDER_XML_PARSE_H*/ +#endif /*LV_XML_SLIDER_PARSER_H*/ diff --git a/src/others/xml/parsers/lv_xml_spangroup_parser.c b/src/others/xml/parsers/lv_xml_spangroup_parser.c index 7d7fc0ea6e..923f0626a8 100644 --- a/src/others/xml/parsers/lv_xml_spangroup_parser.c +++ b/src/others/xml/parsers/lv_xml_spangroup_parser.c @@ -7,7 +7,7 @@ * INCLUDES *********************/ #include "lv_xml_spangroup_parser.h" -#if LV_USE_XML +#if LV_USE_XML && LV_USE_SPAN #include "../../../lvgl.h" #include "../../../lvgl_private.h" @@ -87,6 +87,19 @@ void lv_xml_spangroup_span_apply(lv_xml_parser_state_t * state, const char ** at lv_xml_style_t * style_dsc = lv_xml_get_style_by_name(&state->scope, value); lv_spangroup_set_span_style(spangroup, span, &style_dsc->style); } + else if(lv_streq("bind_text", name)) { + lv_subject_t * subject = lv_xml_get_subject(&state->scope, value); + if(subject == NULL) { + LV_LOG_WARN("Subject \"%s\" doesn't exist in spangroup span bind_text", value); + continue; + } + const char * fmt = lv_xml_get_value_of(attrs, "bind_text-fmt"); + if(fmt) { + fmt = lv_strdup(fmt); + lv_obj_add_event_cb(spangroup, lv_event_free_user_data_cb, LV_EVENT_DELETE, (void *) fmt); + } + lv_spangroup_bind_span_text(spangroup, span, subject, fmt); + } } } diff --git a/src/others/xml/parsers/lv_xml_spangroup_parser.h b/src/others/xml/parsers/lv_xml_spangroup_parser.h index 69e3cf424b..f97c4190ff 100644 --- a/src/others/xml/parsers/lv_xml_spangroup_parser.h +++ b/src/others/xml/parsers/lv_xml_spangroup_parser.h @@ -3,8 +3,8 @@ * */ -#ifndef LV_SPANGROUP_XML_PARSER_H -#define LV_SPANGROUP_XML_PARSER_H +#ifndef LV_XML_SPANGROUP_PARSER_H +#define LV_XML_SPANGROUP_PARSER_H #ifdef __cplusplus extern "C" { @@ -14,7 +14,7 @@ extern "C" { * INCLUDES *********************/ #include "../lv_xml.h" -#if LV_USE_XML +#if LV_USE_XML && LV_USE_SPAN /********************** * TYPEDEFS @@ -38,4 +38,4 @@ void lv_xml_spangroup_span_apply(lv_xml_parser_state_t * state, const char ** at } /*extern "C"*/ #endif -#endif /*LV_SPANGROUP_XML_PARSE_H*/ +#endif /*LV_XML_SPANGROUP_PARSER_H*/ diff --git a/src/others/xml/parsers/lv_xml_spinbox_parser.c b/src/others/xml/parsers/lv_xml_spinbox_parser.c new file mode 100644 index 0000000000..47deef4d29 --- /dev/null +++ b/src/others/xml/parsers/lv_xml_spinbox_parser.c @@ -0,0 +1,79 @@ +/** + * @file lv_xml_spinbox_parser.c + * + */ + +/********************* + * INCLUDES + *********************/ +#include "lv_xml_spinbox_parser.h" +#if LV_USE_XML && LV_USE_SPINBOX + +#include "../../../lvgl.h" +#include "../../../lvgl_private.h" + +/********************* + * DEFINES + *********************/ + +/********************** + * TYPEDEFS + **********************/ + +/********************** + * STATIC PROTOTYPES + **********************/ + +/********************** + * STATIC VARIABLES + **********************/ + +/********************** + * MACROS + **********************/ + +/********************** + * GLOBAL FUNCTIONS + **********************/ + +void * lv_xml_spinbox_create(lv_xml_parser_state_t * state, const char ** attrs) +{ + LV_UNUSED(attrs); + + void * item = lv_spinbox_create(lv_xml_state_get_parent(state)); + return item; +} + +void lv_xml_spinbox_apply(lv_xml_parser_state_t * state, const char ** attrs) +{ + void * item = lv_xml_state_get_item(state); + lv_xml_obj_apply(state, attrs); /*Apply the common properties, e.g. width, height, styles flags etc*/ + + for(int i = 0; attrs[i]; i += 2) { + const char * name = attrs[i]; + const char * value = attrs[i + 1]; + + if(lv_streq("value", name)) lv_spinbox_set_value(item, lv_xml_atoi(value)); + else if(lv_streq("rollover", name)) lv_spinbox_set_rollover(item, lv_xml_to_bool(value)); + else if(lv_streq("digit_count", name)) lv_spinbox_set_digit_count(item, lv_xml_atoi(value)); + else if(lv_streq("dec_point_pos", name)) lv_spinbox_set_dec_point_pos(item, lv_xml_atoi(value)); + else if(lv_streq("min_value", name)) lv_spinbox_set_min_value(item, lv_xml_atoi(value)); + else if(lv_streq("max_value", name)) lv_spinbox_set_max_value(item, lv_xml_atoi(value)); + else if(lv_streq("step", name)) lv_spinbox_set_step(item, lv_xml_atoi(value)); + else if(lv_streq("bind_value", name)) { + lv_subject_t * subject = lv_xml_get_subject(&state->scope, value); + if(subject) { + lv_spinbox_bind_value(item, subject); + } + else { + LV_LOG_WARN("Subject \"%s\" doesn't exist in spinbox bind_value", value); + } + } + } +} + +/********************** + * STATIC FUNCTIONS + **********************/ + +#endif /* LV_USE_XML */ diff --git a/src/others/xml/parsers/lv_xml_spinbox_parser.h b/src/others/xml/parsers/lv_xml_spinbox_parser.h new file mode 100644 index 0000000000..fdb75b6778 --- /dev/null +++ b/src/others/xml/parsers/lv_xml_spinbox_parser.h @@ -0,0 +1,40 @@ +/** + * @file lv_xml_spinbox_parser.h + * + */ + +#ifndef LV_XML_SPINBOX_PARSER_H +#define LV_XML_SPINBOX_PARSER_H + +#ifdef __cplusplus +extern "C" { +#endif + +/********************* + * INCLUDES + *********************/ +#include "../lv_xml.h" +#if LV_USE_XML && LV_USE_SPINBOX + +/********************** + * TYPEDEFS + **********************/ + +/********************** + * GLOBAL PROTOTYPES + **********************/ + +void * lv_xml_spinbox_create(lv_xml_parser_state_t * state, const char ** attrs); +void lv_xml_spinbox_apply(lv_xml_parser_state_t * state, const char ** attrs); + +/********************** + * MACROS + **********************/ + +#endif /* LV_USE_XML */ + +#ifdef __cplusplus +} /*extern "C"*/ +#endif + +#endif /*LV_XML_SPINBOX_PARSER_H*/ diff --git a/src/others/xml/parsers/lv_xml_switch_parser.c b/src/others/xml/parsers/lv_xml_switch_parser.c new file mode 100644 index 0000000000..5e78f9aa55 --- /dev/null +++ b/src/others/xml/parsers/lv_xml_switch_parser.c @@ -0,0 +1,76 @@ +/** + * @file lv_xml_switch_parser.c + * + */ + +/********************* + * INCLUDES + *********************/ +#include "lv_xml_switch_parser.h" +#if LV_USE_XML + +#include "../../../lvgl.h" +#include "../../../lvgl_private.h" + +/********************* + * DEFINES + *********************/ + +/********************** + * TYPEDEFS + **********************/ + +/********************** + * STATIC PROTOTYPES + **********************/ +static lv_switch_orientation_t orientation_text_to_enum_value(const char * txt); + +/********************** + * STATIC VARIABLES + **********************/ + +/********************** + * MACROS + **********************/ + +/********************** + * GLOBAL FUNCTIONS + **********************/ + +void * lv_xml_switch_create(lv_xml_parser_state_t * state, const char ** attrs) +{ + LV_UNUSED(attrs); + + void * item = lv_switch_create(lv_xml_state_get_parent(state)); + return item; +} + +void lv_xml_switch_apply(lv_xml_parser_state_t * state, const char ** attrs) +{ + void * item = lv_xml_state_get_item(state); + lv_xml_obj_apply(state, attrs); /*Apply the common properties, e.g. width, height, styles flags etc*/ + + for(int i = 0; attrs[i]; i += 2) { + const char * name = attrs[i]; + const char * value = attrs[i + 1]; + + if(lv_streq("orientation", name)) lv_switch_set_orientation(item, orientation_text_to_enum_value(value)); + } +} + +/********************** + * STATIC FUNCTIONS + **********************/ + +static lv_switch_orientation_t orientation_text_to_enum_value(const char * txt) +{ + if(lv_streq("auto", txt)) return LV_SWITCH_ORIENTATION_AUTO; + if(lv_streq("horizontal", txt)) return LV_SWITCH_ORIENTATION_HORIZONTAL; + if(lv_streq("vertical", txt)) return LV_SWITCH_ORIENTATION_VERTICAL; + + LV_LOG_WARN("%s is an unknown value for switch's orientation", txt); + + return 0; /*Return 0 in lack of a better option. */ +} + +#endif /* LV_USE_XML */ diff --git a/src/others/xml/parsers/lv_xml_event_parser.h b/src/others/xml/parsers/lv_xml_switch_parser.h similarity index 58% rename from src/others/xml/parsers/lv_xml_event_parser.h rename to src/others/xml/parsers/lv_xml_switch_parser.h index 28498fba94..550a52649e 100644 --- a/src/others/xml/parsers/lv_xml_event_parser.h +++ b/src/others/xml/parsers/lv_xml_switch_parser.h @@ -1,10 +1,10 @@ /** - * @file lv_xml_event_parser.h + * @file lv_xml_switch_parser.h * */ -#ifndef LV_EVENT_XML_PARSER_H -#define LV_EVENT_XML_PARSER_H +#ifndef LV_XML_SWITCH_PARSER_H +#define LV_XML_SWITCH_PARSER_H #ifdef __cplusplus extern "C" { @@ -23,9 +23,9 @@ extern "C" { /********************** * GLOBAL PROTOTYPES **********************/ -void * lv_xml_event_call_function_create(lv_xml_parser_state_t * state, const char ** attrs); -void lv_xml_event_call_function_apply(lv_xml_parser_state_t * state, const char ** attrs); +void * lv_xml_switch_create(lv_xml_parser_state_t * state, const char ** attrs); +void lv_xml_switch_apply(lv_xml_parser_state_t * state, const char ** attrs); /********************** * MACROS @@ -37,4 +37,4 @@ void lv_xml_event_call_function_apply(lv_xml_parser_state_t * state, const char } /*extern "C"*/ #endif -#endif /*LV_EVENT_XML_PARSE_H*/ +#endif /*LV_XML_SWITCH_PARSER_H*/ diff --git a/src/others/xml/parsers/lv_xml_table_parser.c b/src/others/xml/parsers/lv_xml_table_parser.c index 91f55c68f1..b405398a11 100644 --- a/src/others/xml/parsers/lv_xml_table_parser.c +++ b/src/others/xml/parsers/lv_xml_table_parser.c @@ -7,7 +7,7 @@ * INCLUDES *********************/ #include "lv_xml_table_parser.h" -#if LV_USE_XML +#if LV_USE_XML && LV_USE_TABLE #include "../../../lvgl.h" #include "../../../lvgl_private.h" @@ -58,12 +58,6 @@ void lv_xml_table_apply(lv_xml_parser_state_t * state, const char ** attrs) if(lv_streq("column_count", name)) lv_table_set_column_count(item, lv_xml_atoi(value)); else if(lv_streq("row_count", name)) lv_table_set_row_count(item, lv_xml_atoi(value)); - else if(lv_streq("selected_cell", name)) { - - int32_t value1 = lv_xml_atoi_split(&value, ' '); - int32_t value2 = lv_xml_atoi_split(&value, ' '); - lv_table_set_selected_cell(item, value1, value2); - } } } @@ -72,7 +66,7 @@ void * lv_xml_table_column_create(lv_xml_parser_state_t * state, const char ** a LV_UNUSED(attrs); /*Nothing to create*/ - return lv_xml_state_get_parent(state);; + return lv_xml_state_get_parent(state); } void lv_xml_table_column_apply(lv_xml_parser_state_t * state, const char ** attrs) @@ -96,7 +90,7 @@ void * lv_xml_table_cell_create(lv_xml_parser_state_t * state, const char ** att LV_UNUSED(attrs); /*Nothing to create*/ - return lv_xml_state_get_parent(state);; + return lv_xml_state_get_parent(state); } void lv_xml_table_cell_apply(lv_xml_parser_state_t * state, const char ** attrs) diff --git a/src/others/xml/parsers/lv_xml_table_parser.h b/src/others/xml/parsers/lv_xml_table_parser.h index 111c1ffaa5..0b9a4f749a 100644 --- a/src/others/xml/parsers/lv_xml_table_parser.h +++ b/src/others/xml/parsers/lv_xml_table_parser.h @@ -3,8 +3,8 @@ * */ -#ifndef LV_TABLE_XML_PARSER_H -#define LV_TABLE_XML_PARSER_H +#ifndef LV_XML_TABLE_PARSER_H +#define LV_XML_TABLE_PARSER_H #ifdef __cplusplus extern "C" { @@ -14,7 +14,7 @@ extern "C" { * INCLUDES *********************/ #include "../lv_xml.h" -#if LV_USE_XML +#if LV_USE_XML && LV_USE_TABLE /********************** * TYPEDEFS @@ -40,4 +40,4 @@ void lv_xml_table_cell_apply(lv_xml_parser_state_t * state, const char ** attrs) } /*extern "C"*/ #endif -#endif /*LV_TABLE_XML_PARSE_H*/ +#endif /*LV_XML_TABLE_PARSER_H*/ diff --git a/src/others/xml/parsers/lv_xml_tabview_parser.c b/src/others/xml/parsers/lv_xml_tabview_parser.c index e1e8947b06..689b42bf05 100644 --- a/src/others/xml/parsers/lv_xml_tabview_parser.c +++ b/src/others/xml/parsers/lv_xml_tabview_parser.c @@ -7,7 +7,7 @@ * INCLUDES *********************/ #include "lv_xml_tabview_parser.h" -#if LV_USE_XML +#if LV_USE_XML && LV_USE_TABVIEW #include "../../../lvgl.h" #include "../../../lvgl_private.h" @@ -87,6 +87,34 @@ void lv_xml_tabview_tab_apply(lv_xml_parser_state_t * state, const char ** attrs lv_xml_obj_apply(state, attrs); } +void * lv_xml_tabview_tab_button_create(lv_xml_parser_state_t * state, const char ** attrs) +{ + lv_obj_t * tv = lv_xml_state_get_parent(state); + int32_t btn_cnt = lv_tabview_get_tab_count(tv); + if(btn_cnt == 0) { + LV_LOG_WARN("There are no buttons on the tab view. Get tab buttons when the tabs are already created"); + return NULL; + } + + const char * index_str = lv_xml_get_value_of(attrs, "index"); + int32_t index_int = index_str ? lv_xml_atoi(index_str) : 0; + + void * item = lv_tabview_get_tab_button(tv, index_int); + + if(item == NULL) { + LV_LOG_WARN("tabindex is out of range, using the first tab instead"); + item = lv_tabview_get_tab_button(tv, 0); + } + + return item; +} + +void lv_xml_tabview_tab_button_apply(lv_xml_parser_state_t * state, const char ** attrs) +{ + /*Apply the common properties, e.g. width, height, styles flags etc*/ + lv_xml_obj_apply(state, attrs); +} + /********************** * STATIC FUNCTIONS **********************/ diff --git a/src/others/xml/parsers/lv_xml_tabview_parser.h b/src/others/xml/parsers/lv_xml_tabview_parser.h index 9959da8066..bb7fa3f498 100644 --- a/src/others/xml/parsers/lv_xml_tabview_parser.h +++ b/src/others/xml/parsers/lv_xml_tabview_parser.h @@ -3,8 +3,8 @@ * */ -#ifndef LV_TABVIEW_XML_PARSER_H -#define LV_TABVIEW_XML_PARSER_H +#ifndef LV_XML_TABVIEW_PARSER_H +#define LV_XML_TABVIEW_PARSER_H #ifdef __cplusplus extern "C" { @@ -14,7 +14,7 @@ extern "C" { * INCLUDES *********************/ #include "../lv_xml.h" -#if LV_USE_XML +#if LV_USE_XML && LV_USE_TABVIEW /********************** * TYPEDEFS @@ -30,6 +30,8 @@ void * lv_xml_tabview_tab_bar_create(lv_xml_parser_state_t * state, const char * void lv_xml_tabview_tab_bar_apply(lv_xml_parser_state_t * state, const char ** attrs); void * lv_xml_tabview_tab_create(lv_xml_parser_state_t * state, const char ** attrs); void lv_xml_tabview_tab_apply(lv_xml_parser_state_t * state, const char ** attrs); +void * lv_xml_tabview_tab_button_create(lv_xml_parser_state_t * state, const char ** attrs); +void lv_xml_tabview_tab_button_apply(lv_xml_parser_state_t * state, const char ** attrs); /********************** * MACROS @@ -41,4 +43,4 @@ void lv_xml_tabview_tab_apply(lv_xml_parser_state_t * state, const char ** attrs } /*extern "C"*/ #endif -#endif /*LV_TABVIEW_XML_PARSE_H*/ +#endif /*LV_XML_TABVIEW_PARSER_H*/ diff --git a/src/others/xml/parsers/lv_xml_textarea_parser.c b/src/others/xml/parsers/lv_xml_textarea_parser.c index cea2c7efc4..22c64ee2a3 100644 --- a/src/others/xml/parsers/lv_xml_textarea_parser.c +++ b/src/others/xml/parsers/lv_xml_textarea_parser.c @@ -7,7 +7,7 @@ * INCLUDES *********************/ #include "lv_xml_textarea_parser.h" -#if LV_USE_XML +#if LV_USE_XML && LV_USE_TEXTAREA #include "../../../lvgl.h" #include "../../../lvgl_private.h" @@ -56,7 +56,7 @@ void lv_xml_textarea_apply(lv_xml_parser_state_t * state, const char ** attrs) if(lv_streq("text", name)) lv_textarea_set_text(item, value); - else if(lv_streq("placeholder", name)) lv_textarea_set_placeholder_text(item, value); + else if(lv_streq("placeholder_text", name)) lv_textarea_set_placeholder_text(item, value); else if(lv_streq("one_line", name)) lv_textarea_set_one_line(item, lv_xml_to_bool(value)); else if(lv_streq("password_mode", name)) lv_textarea_set_password_mode(item, lv_xml_to_bool(value)); else if(lv_streq("password_show_time", name)) lv_textarea_set_password_show_time(item, lv_xml_atoi(value)); diff --git a/src/others/xml/parsers/lv_xml_textarea_parser.h b/src/others/xml/parsers/lv_xml_textarea_parser.h index 630696ad4d..f8cf50f579 100644 --- a/src/others/xml/parsers/lv_xml_textarea_parser.h +++ b/src/others/xml/parsers/lv_xml_textarea_parser.h @@ -14,7 +14,7 @@ extern "C" { * INCLUDES *********************/ #include "../lv_xml.h" -#if LV_USE_XML +#if LV_USE_XML && LV_USE_TEXTAREA /********************** * TYPEDEFS diff --git a/src/stdlib/builtin/lv_mem_core_builtin.c b/src/stdlib/builtin/lv_mem_core_builtin.c index 23a218154c..a40f8d58bd 100644 --- a/src/stdlib/builtin/lv_mem_core_builtin.c +++ b/src/stdlib/builtin/lv_mem_core_builtin.c @@ -1,5 +1,5 @@ /** - * @file lv_malloc_core.c + * @file lv_mem_core_builtin.c */ /********************* @@ -14,7 +14,7 @@ #include "../../misc/lv_log.h" #include "../../misc/lv_ll.h" #include "../../misc/lv_math.h" -#include "../../osal/lv_os.h" +#include "../../osal/lv_os_private.h" #include "../../core/lv_global.h" #ifdef LV_MEM_POOL_INCLUDE @@ -79,7 +79,7 @@ void lv_mem_init(void) state.tlsf = lv_tlsf_create_with_pool((void *)LV_MEM_POOL_ALLOC(LV_MEM_SIZE), LV_MEM_SIZE); #else /*Allocate a large array to store the dynamically allocated data*/ - static LV_ATTRIBUTE_LARGE_RAM_ARRAY MEM_UNIT work_mem_int[LV_MEM_SIZE / sizeof(MEM_UNIT)]; + static MEM_UNIT work_mem_int[LV_MEM_SIZE / sizeof(MEM_UNIT)] LV_ATTRIBUTE_LARGE_RAM_ARRAY; state.tlsf = lv_tlsf_create_with_pool((void *)work_mem_int, LV_MEM_SIZE); #endif #else diff --git a/src/stdlib/builtin/lv_string_builtin.c b/src/stdlib/builtin/lv_string_builtin.c index 9c28592a0d..c998ee18a6 100644 --- a/src/stdlib/builtin/lv_string_builtin.c +++ b/src/stdlib/builtin/lv_string_builtin.c @@ -1,5 +1,5 @@ /** - * @file lv_string.c + * @file lv_string_builtin.c */ /********************* diff --git a/src/stdlib/builtin/lv_tlsf_private.h b/src/stdlib/builtin/lv_tlsf_private.h index abba9573df..d9fe9f7568 100644 --- a/src/stdlib/builtin/lv_tlsf_private.h +++ b/src/stdlib/builtin/lv_tlsf_private.h @@ -17,7 +17,7 @@ extern "C" { *********************/ #include "lv_tlsf.h" -#include "../../osal/lv_os.h" +#include "../../osal/lv_os_private.h" /********************* * DEFINES diff --git a/src/stdlib/clib/lv_mem_core_clib.c b/src/stdlib/clib/lv_mem_core_clib.c index 9cdddf4d1f..83e90a92c4 100644 --- a/src/stdlib/clib/lv_mem_core_clib.c +++ b/src/stdlib/clib/lv_mem_core_clib.c @@ -1,5 +1,5 @@ /** - * @file lv_malloc_core.c + * @file lv_mem_core_clib.c */ /********************* diff --git a/src/stdlib/clib/lv_sprintf_clib.c b/src/stdlib/clib/lv_sprintf_clib.c index 4f4fb9c74d..32eaee5a25 100644 --- a/src/stdlib/clib/lv_sprintf_clib.c +++ b/src/stdlib/clib/lv_sprintf_clib.c @@ -1,6 +1,6 @@ /** - * @file lv_templ.c + * @file lv_sprintf_clib.c * */ diff --git a/src/stdlib/clib/lv_string_clib.c b/src/stdlib/clib/lv_string_clib.c index df9f9761aa..97acfaa995 100644 --- a/src/stdlib/clib/lv_string_clib.c +++ b/src/stdlib/clib/lv_string_clib.c @@ -1,5 +1,5 @@ /** - * @file lv_string.c + * @file lv_string_clib.c */ /********************* diff --git a/src/stdlib/micropython/lv_mem_core_micropython.c b/src/stdlib/micropython/lv_mem_core_micropython.c index a671b5e1cc..b306a729d2 100644 --- a/src/stdlib/micropython/lv_mem_core_micropython.c +++ b/src/stdlib/micropython/lv_mem_core_micropython.c @@ -1,5 +1,5 @@ /** - * @file lv_malloc_core.c + * @file lv_mem_core_micropython.c */ /********************* diff --git a/src/stdlib/rtthread/lv_mem_core_rtthread.c b/src/stdlib/rtthread/lv_mem_core_rtthread.c index 29a600a6ad..a52526bda7 100644 --- a/src/stdlib/rtthread/lv_mem_core_rtthread.c +++ b/src/stdlib/rtthread/lv_mem_core_rtthread.c @@ -1,5 +1,5 @@ /** - * @file lv_malloc_core_rtthread.c + * @file lv_mem_core_rtthread.c */ /********************* diff --git a/src/stdlib/uefi/lv_mem_core_uefi.c b/src/stdlib/uefi/lv_mem_core_uefi.c index ea03e2c60e..fb70ca920a 100644 --- a/src/stdlib/uefi/lv_mem_core_uefi.c +++ b/src/stdlib/uefi/lv_mem_core_uefi.c @@ -75,7 +75,7 @@ void * lv_realloc_core(void * p, size_t new_size) p_address -= sizeof(mem_header_t); p_header = (mem_header_t *) p_address; - // UEFI supportes no realloc, if the size grows a new memory block has to be allocated + // UEFI supports no realloc, if the size grows a new memory block has to be allocated if(p_header->size > new_size) return p; p_new = lv_malloc_core(new_size); diff --git a/src/themes/default/lv_theme_default.c b/src/themes/default/lv_theme_default.c index fceb3a35fe..8db4f3f0b3 100644 --- a/src/themes/default/lv_theme_default.c +++ b/src/themes/default/lv_theme_default.c @@ -179,8 +179,9 @@ struct _my_theme_t { /********************** * STATIC PROTOTYPES **********************/ -static void theme_apply(lv_theme_t * th, lv_obj_t * obj); static void style_init_reset(lv_style_t * style); +static void theme_apply(lv_theme_t * th, lv_obj_t * obj); +static void resolution_change_event_cb(lv_event_t * e); /********************** * STATIC VARIABLES @@ -630,6 +631,7 @@ lv_theme_t * lv_theme_default_init(lv_display_t * disp, lv_color_t color_primary if(!lv_theme_default_is_inited()) { theme_def = lv_malloc_zeroed(sizeof(my_theme_t)); + LV_ASSERT_MALLOC(theme_def); } my_theme_t * theme = theme_def; @@ -637,10 +639,12 @@ lv_theme_t * lv_theme_default_init(lv_display_t * disp, lv_color_t color_primary lv_display_t * new_disp = disp == NULL ? lv_display_get_default() : disp; int32_t new_dpi = lv_display_get_dpi(new_disp); int32_t hor_res = lv_display_get_horizontal_resolution(new_disp); + int32_t ver_res = lv_display_get_vertical_resolution(new_disp); + int32_t greater_res = LV_MAX(hor_res, ver_res); disp_size_t new_size; - if(hor_res <= 320) new_size = DISP_SMALL; - else if(hor_res < 720) new_size = DISP_MEDIUM; + if(greater_res <= 320) new_size = DISP_SMALL; + else if(greater_res < 720) new_size = DISP_MEDIUM; else new_size = DISP_LARGE; /* check theme information whether will change or not*/ @@ -651,7 +655,6 @@ lv_theme_t * lv_theme_default_init(lv_display_t * disp, lv_color_t color_primary (theme->base.flags == (dark ? MODE_DARK : 0)) && theme->base.font_small == font) { return (lv_theme_t *) theme; - } theme->disp_size = new_size; @@ -667,28 +670,25 @@ lv_theme_t * lv_theme_default_init(lv_display_t * disp, lv_color_t color_primary style_init(theme); - if(disp == NULL || lv_display_get_theme(disp) == (lv_theme_t *)theme) lv_obj_report_style_change(NULL); + if(disp == NULL || lv_display_get_theme(disp) == (lv_theme_t *)theme) { + lv_obj_report_style_change(NULL); + } theme->inited = true; + /*Re-initialize the styles if the resolution changes as a different display size might + *result in different paddings */ + lv_display_remove_event_cb_with_user_data(new_disp, resolution_change_event_cb, theme); + lv_display_add_event_cb(new_disp, resolution_change_event_cb, LV_EVENT_RESOLUTION_CHANGED, theme); + return (lv_theme_t *) theme; } -void lv_theme_default_deinit(void) +bool lv_theme_default_is_inited(void) { my_theme_t * theme = theme_def; - if(theme) { - if(theme->inited) { - lv_style_t * theme_styles = (lv_style_t *)(&(theme->styles)); - uint32_t i; - for(i = 0; i < sizeof(my_theme_styles_t) / sizeof(lv_style_t); i++) { - lv_style_reset(theme_styles + i); - } - - } - lv_free(theme_def); - theme_def = NULL; - } + if(theme == NULL) return false; + return theme->inited; } lv_theme_t * lv_theme_default_get(void) @@ -700,13 +700,26 @@ lv_theme_t * lv_theme_default_get(void) return (lv_theme_t *)theme_def; } -bool lv_theme_default_is_inited(void) +void lv_theme_default_deinit(void) { my_theme_t * theme = theme_def; - if(theme == NULL) return false; - return theme->inited; + if(theme) { + if(theme->inited) { + lv_style_t * theme_styles = (lv_style_t *)(&(theme->styles)); + uint32_t i; + for(i = 0; i < sizeof(my_theme_styles_t) / sizeof(lv_style_t); i++) { + lv_style_reset(theme_styles + i); + } + } + lv_free(theme_def); + theme_def = NULL; + } } +/********************** + * STATIC FUNCTIONS + **********************/ + static void theme_apply(lv_theme_t * th, lv_obj_t * obj) { LV_UNUSED(th); @@ -788,7 +801,6 @@ static void theme_apply(lv_theme_t * th, lv_obj_t * obj) return; } } - #endif lv_obj_add_style(obj, &theme->styles.btn, 0); lv_obj_add_style(obj, &theme->styles.bg_color_primary, 0); @@ -1069,7 +1081,6 @@ static void theme_apply(lv_theme_t * th, lv_obj_t * obj) lv_obj_add_style(obj, &theme->styles.list_item_grow, LV_STATE_FOCUS_KEY); lv_obj_add_style(obj, &theme->styles.list_item_grow, LV_STATE_PRESSED); lv_obj_add_style(obj, &theme->styles.pressed, LV_STATE_PRESSED); - } #endif #if LV_USE_MENU @@ -1148,7 +1159,6 @@ static void theme_apply(lv_theme_t * th, lv_obj_t * obj) lv_obj_add_style(obj, &theme->styles.disabled, LV_STATE_DISABLED); return; } - #endif #if LV_USE_SPINBOX @@ -1200,13 +1210,9 @@ static void theme_apply(lv_theme_t * th, lv_obj_t * obj) #endif } -/********************** - * STATIC FUNCTIONS - **********************/ - static void style_init_reset(lv_style_t * style) { - if(theme_def->inited) { + if(lv_theme_default_is_inited()) { lv_style_reset(style); } else { @@ -1214,4 +1220,15 @@ static void style_init_reset(lv_style_t * style) } } + +static void resolution_change_event_cb(lv_event_t * e) +{ + lv_display_t * disp = lv_event_get_target(e); + my_theme_t * theme = lv_event_get_user_data(e); + + lv_theme_default_init(disp, theme->base.color_primary, theme->base.color_secondary, theme->base.flags, + theme->base.font_normal); + +} + #endif diff --git a/src/themes/default/lv_theme_default.h b/src/themes/default/lv_theme_default.h index 72d9acbfa1..26fad8de1e 100644 --- a/src/themes/default/lv_theme_default.h +++ b/src/themes/default/lv_theme_default.h @@ -41,18 +41,18 @@ extern "C" { lv_theme_t * lv_theme_default_init(lv_display_t * disp, lv_color_t color_primary, lv_color_t color_secondary, bool dark, const lv_font_t * font); -/** - * Get default theme - * @return a pointer to default theme, or NULL if this is not initialized - */ -lv_theme_t * lv_theme_default_get(void); - /** * Check if default theme is initialized * @return true if default theme is initialized, false otherwise */ bool lv_theme_default_is_inited(void); +/** + * Get default theme + * @return a pointer to default theme, or NULL if this is not initialized + */ +lv_theme_t * lv_theme_default_get(void); + /** * Deinitialize the default theme */ diff --git a/src/themes/mono/lv_theme_mono.c b/src/themes/mono/lv_theme_mono.c index 9f69f7b02b..c3d9f387e2 100644 --- a/src/themes/mono/lv_theme_mono.c +++ b/src/themes/mono/lv_theme_mono.c @@ -7,7 +7,7 @@ * INCLUDES *********************/ #include "../lv_theme_private.h" -#include "../../../lvgl.h" +#include "../../../lvgl.h" /*To see all the widgets*/ #if LV_USE_THEME_MONO @@ -17,6 +17,7 @@ /********************* * DEFINES *********************/ + struct _my_theme_t; typedef struct _my_theme_t my_theme_t; @@ -88,7 +89,7 @@ static void style_init(my_theme_t * theme, bool dark_bg, const lv_font_t * font) style_init_reset(&theme->styles.scrollbar); lv_style_set_bg_opa(&theme->styles.scrollbar, LV_OPA_COVER); lv_style_set_bg_color(&theme->styles.scrollbar, COLOR_FG); - lv_style_set_width(&theme->styles.scrollbar, PAD_DEF); + lv_style_set_width(&theme->styles.scrollbar, PAD_DEF); style_init_reset(&theme->styles.scr); lv_style_set_bg_opa(&theme->styles.scr, LV_OPA_COVER); @@ -180,36 +181,14 @@ static void style_init(my_theme_t * theme, bool dark_bg, const lv_font_t * font) * GLOBAL FUNCTIONS **********************/ -bool lv_theme_mono_is_inited(void) -{ - my_theme_t * theme = theme_def; - if(theme == NULL) return false; - return theme->inited; -} - -void lv_theme_mono_deinit(void) -{ - my_theme_t * theme = theme_def; - if(theme) { - if(theme->inited) { - lv_style_t * theme_styles = (lv_style_t *)(&(theme->styles)); - uint32_t i; - for(i = 0; i < sizeof(my_theme_styles_t) / sizeof(lv_style_t); i++) { - lv_style_reset(theme_styles + i); - } - } - lv_free(theme_def); - theme_def = NULL; - } -} - lv_theme_t * lv_theme_mono_init(lv_display_t * disp, bool dark_bg, const lv_font_t * font) { /*This trick is required only to avoid the garbage collection of *styles' data if LVGL is used in a binding (e.g. MicroPython) - *In a general case styles could be in simple `static lv_style_t my_style...` variables*/ + *In a general case styles could be in a simple `static lv_style_t my_style...` variables*/ if(!lv_theme_mono_is_inited()) { theme_def = lv_malloc_zeroed(sizeof(my_theme_t)); + LV_ASSERT_MALLOC(theme_def); } my_theme_t * theme = theme_def; @@ -222,13 +201,51 @@ lv_theme_t * lv_theme_mono_init(lv_display_t * disp, bool dark_bg, const lv_font style_init(theme, dark_bg, font); - if(disp == NULL || lv_display_get_theme(disp) == (lv_theme_t *) theme) lv_obj_report_style_change(NULL); + if(disp == NULL || lv_display_get_theme(disp) == (lv_theme_t *)theme) { + lv_obj_report_style_change(NULL); + } theme->inited = true; return (lv_theme_t *)theme_def; } +bool lv_theme_mono_is_inited(void) +{ + my_theme_t * theme = theme_def; + if(theme == NULL) return false; + return theme->inited; +} + +lv_theme_t * lv_theme_mono_get(void) +{ + if(!lv_theme_mono_is_inited()) { + return NULL; + } + + return (lv_theme_t *)theme_def; +} + +void lv_theme_mono_deinit(void) +{ + my_theme_t * theme = theme_def; + if(theme) { + if(theme->inited) { + lv_style_t * theme_styles = (lv_style_t *)(&(theme->styles)); + uint32_t i; + for(i = 0; i < sizeof(my_theme_styles_t) / sizeof(lv_style_t); i++) { + lv_style_reset(theme_styles + i); + } + } + lv_free(theme_def); + theme_def = NULL; + } +} + +/********************** + * STATIC FUNCTIONS + **********************/ + static void theme_apply(lv_theme_t * th, lv_obj_t * obj) { LV_UNUSED(th); @@ -467,6 +484,7 @@ static void theme_apply(lv_theme_t * th, lv_obj_t * obj) lv_obj_add_style(obj, &theme->styles.large_border, LV_PART_ITEMS | LV_STATE_EDITED); } #endif + #if LV_USE_LIST else if(lv_obj_check_type(obj, &lv_list_class)) { lv_obj_add_style(obj, &theme->styles.card, 0); @@ -481,7 +499,6 @@ static void theme_apply(lv_theme_t * th, lv_obj_t * obj) lv_obj_add_style(obj, &theme->styles.pr, LV_STATE_PRESSED); lv_obj_add_style(obj, &theme->styles.focus, LV_STATE_FOCUS_KEY); lv_obj_add_style(obj, &theme->styles.large_border, LV_STATE_EDITED); - } #endif #if LV_USE_MSGBOX @@ -490,6 +507,7 @@ static void theme_apply(lv_theme_t * th, lv_obj_t * obj) return; } #endif + #if LV_USE_SPINBOX else if(lv_obj_check_type(obj, &lv_spinbox_class)) { lv_obj_add_style(obj, &theme->styles.card, 0); @@ -515,18 +533,6 @@ static void theme_apply(lv_theme_t * th, lv_obj_t * obj) #endif } -lv_theme_t * lv_theme_mono_get(void) -{ - if(!lv_theme_mono_is_inited()) { - return NULL; - } - return (lv_theme_t *)theme_def; -} - -/********************** - * STATIC FUNCTIONS - **********************/ - static void style_init_reset(lv_style_t * style) { if(lv_theme_mono_is_inited()) { diff --git a/src/themes/simple/lv_theme_simple.c b/src/themes/simple/lv_theme_simple.c index 8a325550f0..4fc6308b27 100644 --- a/src/themes/simple/lv_theme_simple.c +++ b/src/themes/simple/lv_theme_simple.c @@ -79,7 +79,7 @@ static void style_init(my_theme_t * theme) style_init_reset(&theme->styles.scrollbar); lv_style_set_bg_opa(&theme->styles.scrollbar, LV_OPA_COVER); lv_style_set_bg_color(&theme->styles.scrollbar, COLOR_DARK); - lv_style_set_width(&theme->styles.scrollbar, SCROLLBAR_WIDTH); + lv_style_set_width(&theme->styles.scrollbar, SCROLLBAR_WIDTH); style_init_reset(&theme->styles.scr); lv_style_set_bg_opa(&theme->styles.scr, LV_OPA_COVER); @@ -142,6 +142,35 @@ static void style_init(my_theme_t * theme) * GLOBAL FUNCTIONS **********************/ +lv_theme_t * lv_theme_simple_init(lv_display_t * disp) +{ + /*This trick is required only to avoid the garbage collection of + *styles' data if LVGL is used in a binding (e.g. MicroPython) + *In a general case styles could be in a simple `static lv_style_t my_style...` variables*/ + if(!lv_theme_simple_is_inited()) { + theme_def = lv_malloc_zeroed(sizeof(my_theme_t)); + LV_ASSERT_MALLOC(theme_def); + } + + my_theme_t * theme = theme_def; + + theme->base.disp = disp; + theme->base.font_small = LV_FONT_DEFAULT; + theme->base.font_normal = LV_FONT_DEFAULT; + theme->base.font_large = LV_FONT_DEFAULT; + theme->base.apply_cb = theme_apply; + + style_init(theme); + + if(disp == NULL || lv_display_get_theme(disp) == (lv_theme_t *)theme) { + lv_obj_report_style_change(NULL); + } + + theme->inited = true; + + return (lv_theme_t *)theme_def; +} + bool lv_theme_simple_is_inited(void) { my_theme_t * theme = theme_def; @@ -174,33 +203,9 @@ void lv_theme_simple_deinit(void) } } -lv_theme_t * lv_theme_simple_init(lv_display_t * disp) -{ - /*This trick is required only to avoid the garbage collection of - *styles' data if LVGL is used in a binding (e.g. MicroPython) - *In a general case styles could be in simple `static lv_style_t my_style...` variables*/ - if(!lv_theme_simple_is_inited()) { - theme_def = lv_malloc_zeroed(sizeof(my_theme_t)); - } - - my_theme_t * theme = theme_def; - - theme->base.disp = disp; - theme->base.font_small = LV_FONT_DEFAULT; - theme->base.font_normal = LV_FONT_DEFAULT; - theme->base.font_large = LV_FONT_DEFAULT; - theme->base.apply_cb = theme_apply; - - style_init(theme); - - if(disp == NULL || lv_display_get_theme(disp) == (lv_theme_t *)theme) { - lv_obj_report_style_change(NULL); - } - - theme->inited = true; - - return (lv_theme_t *)theme_def; -} +/********************** + * STATIC FUNCTIONS + **********************/ static void theme_apply(lv_theme_t * th, lv_obj_t * obj) { @@ -378,6 +383,7 @@ static void theme_apply(lv_theme_t * th, lv_obj_t * obj) lv_obj_add_style(obj, &theme->styles.light, LV_PART_ITEMS | LV_STATE_CHECKED); } #endif + #if LV_USE_LIST else if(lv_obj_check_type(obj, &lv_list_class)) { lv_obj_add_style(obj, &theme->styles.light, 0); @@ -389,7 +395,6 @@ static void theme_apply(lv_theme_t * th, lv_obj_t * obj) } else if(lv_obj_check_type(obj, &lv_list_button_class)) { lv_obj_add_style(obj, &theme->styles.dark, 0); - } #endif #if LV_USE_MSGBOX @@ -398,6 +403,7 @@ static void theme_apply(lv_theme_t * th, lv_obj_t * obj) return; } #endif + #if LV_USE_SPINBOX else if(lv_obj_check_type(obj, &lv_spinbox_class)) { lv_obj_add_style(obj, &theme->styles.light, 0); @@ -421,10 +427,6 @@ static void theme_apply(lv_theme_t * th, lv_obj_t * obj) #endif } -/********************** - * STATIC FUNCTIONS - **********************/ - static void style_init_reset(lv_style_t * style) { if(lv_theme_simple_is_inited()) { diff --git a/src/themes/simple/lv_theme_simple.h b/src/themes/simple/lv_theme_simple.h index 6717366557..4b02a0e60c 100644 --- a/src/themes/simple/lv_theme_simple.h +++ b/src/themes/simple/lv_theme_simple.h @@ -32,7 +32,7 @@ extern "C" { /** * Initialize the theme - * @param disp pointer to display to attach the theme + * @param disp pointer to display * @return a pointer to reference this theme later */ lv_theme_t * lv_theme_simple_init(lv_display_t * disp); diff --git a/src/tick/lv_tick.c b/src/tick/lv_tick.c index 21e22959d9..4fb6d9c2ab 100644 --- a/src/tick/lv_tick.c +++ b/src/tick/lv_tick.c @@ -66,18 +66,13 @@ uint32_t lv_tick_get(void) uint32_t lv_tick_elaps(uint32_t prev_tick) { - uint32_t act_time = lv_tick_get(); - - /*If there is no overflow in sys_time simple subtract*/ - if(act_time >= prev_tick) { - prev_tick = act_time - prev_tick; - } - else { - prev_tick = UINT32_MAX - prev_tick + 1; - prev_tick += act_time; - } + return lv_tick_diff(lv_tick_get(), prev_tick); +} - return prev_tick; +uint32_t lv_tick_diff(uint32_t tick, uint32_t prev_tick) +{ + /*Unsigned overflow is well-defined and works for a single wrap around*/ + return tick - prev_tick; } void lv_delay_ms(uint32_t ms) @@ -103,6 +98,11 @@ void lv_tick_set_cb(lv_tick_get_cb_t cb) state.tick_get_cb = cb; } +lv_tick_get_cb_t lv_tick_get_cb(void) +{ + return state.tick_get_cb; +} + void lv_delay_set_cb(lv_delay_cb_t cb) { state.delay_cb = cb; diff --git a/src/tick/lv_tick.h b/src/tick/lv_tick.h index 048b93a31a..838fe8b1a9 100644 --- a/src/tick/lv_tick.h +++ b/src/tick/lv_tick.h @@ -36,7 +36,8 @@ typedef void (*lv_delay_cb_t)(uint32_t ms); **********************/ /** - * You have to call this function periodically + * You have to call this function periodically. + * It is typically safe to call from an interrupt handler or a different thread. * @param tick_period the call period of this function in milliseconds */ LV_ATTRIBUTE_TICK_INC void lv_tick_inc(uint32_t tick_period); @@ -54,6 +55,14 @@ uint32_t lv_tick_get(void); */ uint32_t lv_tick_elaps(uint32_t prev_tick); +/** + * Get the elapsed milliseconds between two time stamps + * @param tick a time stamp + * @param prev_tick a time stamp before `tick` + * @return the elapsed milliseconds between `prev_tick` and `tick` + */ +uint32_t lv_tick_diff(uint32_t tick, uint32_t prev_tick); + /** * Delay for the given milliseconds. * By default it's a blocking delay, but with `lv_delay_set_cb()` @@ -62,6 +71,12 @@ uint32_t lv_tick_elaps(uint32_t prev_tick); */ void lv_delay_ms(uint32_t ms); +/** + * Set a callback for a blocking delay + * @param cb pointer to a callback + */ +void lv_delay_set_cb(lv_delay_cb_t cb); + /** * Set the custom callback for 'lv_tick_get' * @param cb call this callback on 'lv_tick_get' @@ -69,10 +84,10 @@ void lv_delay_ms(uint32_t ms); void lv_tick_set_cb(lv_tick_get_cb_t cb); /** - * Set a custom callback for 'lv_delay_ms' - * @param cb call this callback in 'lv_delay_ms' + * Get the custom callback for 'lv_tick_get' + * @return call this callback on 'lv_tick_get' */ -void lv_delay_set_cb(lv_delay_cb_t cb); +lv_tick_get_cb_t lv_tick_get_cb(void); /********************** * MACROS diff --git a/src/tick/lv_tick_private.h b/src/tick/lv_tick_private.h index cf8ae9b092..2450f32219 100644 --- a/src/tick/lv_tick_private.h +++ b/src/tick/lv_tick_private.h @@ -25,7 +25,7 @@ extern "C" { **********************/ typedef struct { - uint32_t sys_time; + volatile uint32_t sys_time; volatile uint8_t sys_irq_flag; lv_tick_get_cb_t tick_get_cb; lv_delay_cb_t delay_cb; diff --git a/src/widgets/3dtexture/lv_3dtexture.c b/src/widgets/3dtexture/lv_3dtexture.c index 8db3f4e4da..9c76dcacb3 100644 --- a/src/widgets/3dtexture/lv_3dtexture.c +++ b/src/widgets/3dtexture/lv_3dtexture.c @@ -71,6 +71,20 @@ void lv_3dtexture_set_src(lv_obj_t * obj, lv_3dtexture_id_t id) tex->id = id; } +void lv_3dtexture_set_flip(lv_obj_t * obj, bool h_flip, bool v_flip) +{ + LV_ASSERT_OBJ(obj, MY_CLASS); + + lv_3dtexture_t * tex = (lv_3dtexture_t *)obj; + + if(tex->h_flip == h_flip && tex->v_flip == v_flip) return; + + tex->h_flip = h_flip; + tex->v_flip = v_flip; + + lv_obj_invalidate(obj); +} + /*====================== * Add/remove functions *=====================*/ @@ -98,6 +112,8 @@ static void lv_3dtexture_constructor(const lv_obj_class_t * class_p, lv_obj_t * lv_3dtexture_t * tex = (lv_3dtexture_t *)obj; tex->id = LV_3DTEXTURE_ID_NULL; + tex->h_flip = false; + tex->v_flip = false; LV_TRACE_OBJ_CREATE("finished"); } @@ -135,7 +151,9 @@ static void draw_3dtexture(lv_event_t * e) lv_draw_3d_dsc_t dsc; lv_draw_3d_dsc_init(&dsc); dsc.tex_id = tex->id; - dsc.opa = lv_obj_get_style_opa(obj, 0); + dsc.opa = lv_obj_get_style_opa(obj, LV_PART_MAIN); + dsc.h_flip = tex->h_flip; + dsc.v_flip = tex->v_flip; lv_area_t coords; lv_obj_get_coords(obj, &coords); lv_draw_3d(layer, &dsc, &coords); diff --git a/src/widgets/3dtexture/lv_3dtexture.h b/src/widgets/3dtexture/lv_3dtexture.h index 87f1588874..f5b522d1ba 100644 --- a/src/widgets/3dtexture/lv_3dtexture.h +++ b/src/widgets/3dtexture/lv_3dtexture.h @@ -49,6 +49,14 @@ lv_obj_t * lv_3dtexture_create(lv_obj_t * parent); */ void lv_3dtexture_set_src(lv_obj_t * obj, lv_3dtexture_id_t id); +/** + * Set the flipping behavior of the widget. + * @param obj the 3dtexture widget + * @param h_flip true to flip horizontally. + * @param v_flip true to flip vertically. + */ +void lv_3dtexture_set_flip(lv_obj_t * obj, bool h_flip, bool v_flip); + /*====================== * Add/remove functions *=====================*/ diff --git a/src/widgets/3dtexture/lv_3dtexture_private.h b/src/widgets/3dtexture/lv_3dtexture_private.h index 0a7b770f58..744fef695b 100644 --- a/src/widgets/3dtexture/lv_3dtexture_private.h +++ b/src/widgets/3dtexture/lv_3dtexture_private.h @@ -31,6 +31,8 @@ extern "C" { struct _lv_3dtexture_t { lv_obj_t obj; lv_3dtexture_id_t id; + bool h_flip; + bool v_flip; }; /********************** diff --git a/src/widgets/animimage/lv_animimage.c b/src/widgets/animimage/lv_animimage.c index 56e9a2f3ac..ed91e78b43 100644 --- a/src/widgets/animimage/lv_animimage.c +++ b/src/widgets/animimage/lv_animimage.c @@ -1,5 +1,5 @@ /** - * @file lv_animimg.c + * @file lv_animimage.c * */ @@ -22,7 +22,7 @@ #include "../../draw/lv_image_decoder.h" #include "../../misc/lv_assert.h" #include "../../misc/lv_fs.h" -#include "../../misc/lv_text.h" +#include "../../misc/lv_text_private.h" #include "../../misc/lv_math.h" #include "../../misc/lv_log.h" #include "../../misc/lv_anim.h" diff --git a/src/widgets/animimage/lv_animimage.h b/src/widgets/animimage/lv_animimage.h index 230eca4997..d193ad5cc2 100644 --- a/src/widgets/animimage/lv_animimage.h +++ b/src/widgets/animimage/lv_animimage.h @@ -36,7 +36,7 @@ extern "C" { **********************/ #if LV_USE_OBJ_PROPERTY -enum { +enum _lv_property_animimage_id_t { LV_PROPERTY_ID2(ANIMIMAGE, SRC, LV_PROPERTY_TYPE_POINTER, LV_PROPERTY_TYPE_INT, 0), LV_PROPERTY_ID(ANIMIMAGE, DURATION, LV_PROPERTY_TYPE_INT, 1), LV_PROPERTY_ID(ANIMIMAGE, REPEAT_COUNT, LV_PROPERTY_TYPE_INT, 2), diff --git a/src/widgets/arc/lv_arc.c b/src/widgets/arc/lv_arc.c index 6d5f230d9d..4a683ee4b8 100644 --- a/src/widgets/arc/lv_arc.c +++ b/src/widgets/arc/lv_arc.c @@ -18,6 +18,7 @@ #include "../../misc/lv_assert.h" #include "../../misc/lv_math.h" #include "../../draw/lv_draw_arc.h" +#include "../../others/observer/lv_observer_private.h" /********************* * DEFINES @@ -50,6 +51,10 @@ static void value_update(lv_obj_t * arc); static int32_t knob_get_extra_size(lv_obj_t * obj); static bool lv_arc_angle_within_bg_bounds(lv_obj_t * obj, const lv_value_precise_t angle, const lv_value_precise_t tolerance_deg); +#if LV_USE_OBSERVER + static void arc_value_changed_event_cb(lv_event_t * e); + static void arc_value_observer_cb(lv_observer_t * observer, lv_subject_t * subject); +#endif /*LV_USE_OBSERVER*/ /********************** * STATIC VARIABLES @@ -273,6 +278,16 @@ void lv_arc_set_range(lv_obj_t * obj, int32_t min, int32_t max) value_update(obj); /*value has changed relative to the new range*/ } +void lv_arc_set_min_value(lv_obj_t * obj, int32_t min) +{ + lv_arc_set_range(obj, min, lv_arc_get_max_value(obj)); +} + +void lv_arc_set_max_value(lv_obj_t * obj, int32_t max) +{ + lv_arc_set_range(obj, lv_arc_get_min_value(obj), max); +} + void lv_arc_set_change_rate(lv_obj_t * obj, uint32_t rate) { LV_ASSERT_OBJ(obj, MY_CLASS); @@ -357,6 +372,25 @@ int32_t lv_arc_get_knob_offset(const lv_obj_t * obj) * Other functions *====================*/ +#if LV_USE_OBSERVER +lv_observer_t * lv_arc_bind_value(lv_obj_t * obj, lv_subject_t * subject) +{ + LV_ASSERT_NULL(subject); + LV_ASSERT_NULL(obj); + + if(subject->type != LV_SUBJECT_TYPE_INT && subject->type != LV_SUBJECT_TYPE_FLOAT) { + LV_LOG_WARN("Incompatible subject type: %d", subject->type); + return NULL; + } + + lv_obj_add_event_cb(obj, arc_value_changed_event_cb, LV_EVENT_VALUE_CHANGED, subject); + + lv_observer_t * observer = lv_subject_add_observer_obj(subject, arc_value_observer_cb, obj, NULL); + return observer; +} +#endif /*LV_USE_OBSERVER*/ + + void lv_arc_align_obj_to_angle(const lv_obj_t * obj, lv_obj_t * obj_to_align, int32_t r_offset) { LV_ASSERT_OBJ(obj, MY_CLASS); @@ -1015,4 +1049,36 @@ static bool lv_arc_angle_within_bg_bounds(lv_obj_t * obj, const lv_value_precise return false; } +#if LV_USE_OBSERVER + +static void arc_value_changed_event_cb(lv_event_t * e) +{ + lv_obj_t * arc = lv_event_get_current_target(e); + lv_subject_t * subject = lv_event_get_user_data(e); + + if(subject->type == LV_SUBJECT_TYPE_INT) { + lv_subject_set_int(subject, lv_arc_get_value(arc)); + } +#if LV_USE_FLOAT + else { + lv_subject_set_float(subject, (float)lv_arc_get_value(arc)); + } +#endif +} + +static void arc_value_observer_cb(lv_observer_t * observer, lv_subject_t * subject) +{ + if(subject->type == LV_SUBJECT_TYPE_INT) { + lv_arc_set_value(observer->target, subject->value.num); + } +#if LV_USE_FLOAT + else { + lv_arc_set_value(observer->target, (int32_t)subject->value.float_v); + } +#endif +} + +#endif /*LV_USE_OBSERVER*/ + + #endif diff --git a/src/widgets/arc/lv_arc.h b/src/widgets/arc/lv_arc.h index f241745ffa..1cae09cc34 100644 --- a/src/widgets/arc/lv_arc.h +++ b/src/widgets/arc/lv_arc.h @@ -18,6 +18,7 @@ extern "C" { #if LV_USE_ARC != 0 #include "../../core/lv_obj.h" +#include "../../others/observer/lv_observer.h" /********************* * DEFINES @@ -26,10 +27,14 @@ extern "C" { /********************** * TYPEDEFS **********************/ + +/** + * In which direction the indicator should grow. + */ typedef enum { - LV_ARC_MODE_NORMAL, - LV_ARC_MODE_SYMMETRICAL, - LV_ARC_MODE_REVERSE + LV_ARC_MODE_NORMAL, /**< Clock-wise */ + LV_ARC_MODE_SYMMETRICAL, /**< Left/right from the midpoint */ + LV_ARC_MODE_REVERSE /**< Counterclock-wise */ } lv_arc_mode_t; LV_ATTRIBUTE_EXTERN_DATA extern const lv_obj_class_t lv_arc_class; @@ -105,7 +110,7 @@ void lv_arc_set_bg_angles(lv_obj_t * obj, lv_value_precise_t start, lv_value_pre void lv_arc_set_rotation(lv_obj_t * obj, int32_t rotation); /** - * Set the type of arc. + * Set in which direction the indicator should grow. * @param obj pointer to arc object * @param type arc's mode */ @@ -126,6 +131,20 @@ void lv_arc_set_value(lv_obj_t * obj, int32_t value); */ void lv_arc_set_range(lv_obj_t * obj, int32_t min, int32_t max); +/** + * Set the minimum values of an arc + * @param obj pointer to the arc object + * @param min minimum value + */ +void lv_arc_set_min_value(lv_obj_t * obj, int32_t min); + +/** + * Set the maximum values of an arc + * @param obj pointer to the arc object + * @param max maximum value + */ +void lv_arc_set_max_value(lv_obj_t * obj, int32_t max); + /** * Set a change rate to limit the speed how fast the arc should reach the pressed point. * @param obj pointer to an arc object @@ -218,6 +237,17 @@ int32_t lv_arc_get_knob_offset(const lv_obj_t * obj); * Other functions *====================*/ +#if LV_USE_OBSERVER +/** + * Bind an integer subject to an Arc's value. + * @param obj pointer to Arc + * @param subject pointer to Subject + * @return pointer to newly-created Observer + */ +lv_observer_t * lv_arc_bind_value(lv_obj_t * obj, lv_subject_t * subject); +#endif + + /** * Align an object to the current position of the arc (knob) * @param obj pointer to an arc object diff --git a/src/widgets/arclabel/lv_arclabel.c b/src/widgets/arclabel/lv_arclabel.c index 812d38c29b..a5a1aa4559 100644 --- a/src/widgets/arclabel/lv_arclabel.c +++ b/src/widgets/arclabel/lv_arclabel.c @@ -437,6 +437,9 @@ static void arclabel_draw_main(lv_event_t * e) lv_value_precise_t prev_letter_w = 0; lv_value_precise_t total_arc_length = deg_to_rad(arclabel->angle_size, arc_r); lv_value_precise_t curr_total_arc_length = deg_to_rad(angle_start, arc_r); + uint32_t letter; + uint32_t letter_next; + while(text) { uint32_t word_i = 0; @@ -446,8 +449,6 @@ static void arclabel_draw_main(lv_event_t * e) else text = NULL; while(word_i < text_len && curr_total_arc_length <= total_arc_length) { - uint32_t letter; - uint32_t letter_next; lv_text_encoded_letter_next_2(text_start, &letter, &letter_next, &word_i); const lv_value_precise_t letter_w = lv_font_get_glyph_width(font, letter, letter_next); @@ -524,6 +525,8 @@ static lv_value_precise_t calc_arc_text_total_angle(const char * text, const lv_ lv_value_precise_t prev_letter_w = 0; const lv_value_precise_t angle_size_in_arc_length = deg_to_rad(angle_size, radius); lv_value_precise_t total_arc_length = 0; + uint32_t letter; + uint32_t letter_next; while(text) { uint32_t word_i = 0; @@ -536,8 +539,6 @@ static lv_value_precise_t calc_arc_text_total_angle(const char * text, const lv_ break; } - uint32_t letter; - uint32_t letter_next; lv_text_encoded_letter_next_2(text_start, &letter, &letter_next, &word_i); const lv_value_precise_t letter_w = lv_font_get_glyph_width(font, letter, letter_next); diff --git a/src/widgets/bar/lv_bar.c b/src/widgets/bar/lv_bar.c index b526bd37c6..91012061af 100644 --- a/src/widgets/bar/lv_bar.c +++ b/src/widgets/bar/lv_bar.c @@ -14,6 +14,7 @@ #if LV_USE_BAR != 0 #include "../../draw/lv_draw.h" +#include "../../others/observer/lv_observer_private.h" #include "../../misc/lv_assert.h" #include "../../misc/lv_anim_private.h" #include "../../misc/lv_math.h" @@ -58,6 +59,10 @@ static void lv_bar_init_anim(lv_obj_t * bar, lv_bar_anim_t * bar_anim); static void lv_bar_anim(void * bar, int32_t value); static void lv_bar_anim_completed(lv_anim_t * a); +#if LV_USE_OBSERVER + static void bar_value_observer_cb(lv_observer_t * observer, lv_subject_t * subject); +#endif + /********************** * STATIC VARIABLES **********************/ @@ -155,6 +160,16 @@ void lv_bar_set_range(lv_obj_t * obj, int32_t min, int32_t max) lv_obj_invalidate(obj); } +void lv_bar_set_min_value(lv_obj_t * obj, int32_t min) +{ + lv_bar_set_range(obj, min, lv_bar_get_max_value(obj)); +} + +void lv_bar_set_max_value(lv_obj_t * obj, int32_t max) +{ + lv_bar_set_range(obj, lv_bar_get_min_value(obj), max); +} + void lv_bar_set_mode(lv_obj_t * obj, lv_bar_mode_t mode) { LV_ASSERT_OBJ(obj, MY_CLASS); @@ -239,6 +254,22 @@ bool lv_bar_is_symmetrical(lv_obj_t * obj) bar->start_value == bar->min_value; } +#if LV_USE_OBSERVER +lv_observer_t * lv_bar_bind_value(lv_obj_t * obj, lv_subject_t * subject) +{ + LV_ASSERT_NULL(subject); + LV_ASSERT_NULL(obj); + + if(subject->type != LV_SUBJECT_TYPE_INT && subject->type != LV_SUBJECT_TYPE_FLOAT) { + LV_LOG_WARN("Incompatible subject type: %d", subject->type); + return NULL; + } + + lv_observer_t * observer = lv_subject_add_observer_obj(subject, bar_value_observer_cb, obj, NULL); + return observer; +} +#endif /*LV_USE_OBSERVER*/ + /********************** * STATIC FUNCTIONS **********************/ @@ -702,4 +733,20 @@ static void lv_bar_init_anim(lv_obj_t * obj, lv_bar_anim_t * bar_anim) bar_anim->anim_state = LV_BAR_ANIM_STATE_INV; } +#if LV_USE_OBSERVER + +static void bar_value_observer_cb(lv_observer_t * observer, lv_subject_t * subject) +{ + if(subject->type == LV_SUBJECT_TYPE_INT) { + lv_bar_set_value(observer->target, subject->value.num, LV_ANIM_OFF); + } +#if LV_USE_FLOAT + else { + lv_bar_set_value(observer->target, (int32_t)subject->value.float_v, LV_ANIM_OFF); + } +#endif +} + +#endif /*LV_USE_OBSERVER*/ + #endif diff --git a/src/widgets/bar/lv_bar.h b/src/widgets/bar/lv_bar.h index 422ba014b0..5d34e0a74e 100644 --- a/src/widgets/bar/lv_bar.h +++ b/src/widgets/bar/lv_bar.h @@ -20,6 +20,7 @@ extern "C" { #include "../../core/lv_obj.h" #include "../../misc/lv_anim.h" #include "../label/lv_label.h" +#include "../../others/observer/lv_observer.h" /********************* * DEFINES @@ -82,6 +83,20 @@ void lv_bar_set_start_value(lv_obj_t * obj, int32_t start_value, lv_anim_enable_ */ void lv_bar_set_range(lv_obj_t * obj, int32_t min, int32_t max); +/** + * Set minimum value of a bar + * @param obj pointer to the bar object + * @param min minimum value + */ +void lv_bar_set_min_value(lv_obj_t * obj, int32_t min); + +/** + * Set maximum value of a bar + * @param obj pointer to the bar object + * @param max maximum value + */ +void lv_bar_set_max_value(lv_obj_t * obj, int32_t max); + /** * Set the type of bar. * @param obj pointer to bar object @@ -149,6 +164,16 @@ lv_bar_orientation_t lv_bar_get_orientation(lv_obj_t * obj); */ bool lv_bar_is_symmetrical(lv_obj_t * obj); +#if LV_USE_OBSERVER +/** + * Bind an integer or float Subject to a Bar's value. + * @param obj pointer to Bar + * @param subject pointer to Subject + * @return pointer to newly-created Observer + */ +lv_observer_t * lv_bar_bind_value(lv_obj_t * obj, lv_subject_t * subject); +#endif + /********************** * MACROS **********************/ diff --git a/src/widgets/button/lv_button.c b/src/widgets/button/lv_button.c index 361e87734f..1b0c244327 100644 --- a/src/widgets/button/lv_button.c +++ b/src/widgets/button/lv_button.c @@ -1,5 +1,5 @@ /** - * @file lv_btn.c + * @file lv_button.c * */ diff --git a/src/widgets/buttonmatrix/lv_buttonmatrix.c b/src/widgets/buttonmatrix/lv_buttonmatrix.c index 5b3f93f8ba..32773b535b 100644 --- a/src/widgets/buttonmatrix/lv_buttonmatrix.c +++ b/src/widgets/buttonmatrix/lv_buttonmatrix.c @@ -1,5 +1,5 @@ /** - * @file lv_btnmatrix.c + * @file lv_buttonmatrix.c * */ @@ -17,7 +17,7 @@ #include "../../core/lv_group.h" #include "../../draw/lv_draw.h" #include "../../core/lv_refr.h" -#include "../../misc/lv_text.h" +#include "../../misc/lv_text_private.h" #include "../../misc/lv_text_ap.h" #include "../../stdlib/lv_string.h" @@ -727,9 +727,14 @@ static void draw_main(lv_event_t * e) txt = txt_ap; } #endif + lv_text_attributes_t attributes = {0}; + attributes.letter_space = letter_space; + attributes.line_space = line_space; + attributes.text_flags = draw_label_dsc_act.flag; + attributes.max_width = lv_area_get_width(&area_obj); + lv_point_t txt_size; - lv_text_get_size(&txt_size, txt, font, letter_space, - line_space, lv_area_get_width(&area_obj), draw_label_dsc_act.flag); + lv_text_get_size_attributes(&txt_size, txt, font, &attributes); btn_area.x1 += (lv_area_get_width(&btn_area) - txt_size.x) / 2; btn_area.y1 += (lv_area_get_height(&btn_area) - txt_size.y) / 2; diff --git a/src/widgets/calendar/lv_calendar.c b/src/widgets/calendar/lv_calendar.c index bcdd23e228..e01f36ebba 100644 --- a/src/widgets/calendar/lv_calendar.c +++ b/src/widgets/calendar/lv_calendar.c @@ -97,6 +97,9 @@ void lv_calendar_set_today_date(lv_obj_t * obj, uint32_t year, uint32_t month, u LV_ASSERT_OBJ(obj, MY_CLASS); lv_calendar_t * calendar = (lv_calendar_t *)obj; + if(calendar->today.year == year && calendar->today.month == month + && calendar->today.day == day) return; + calendar->today.year = year; calendar->today.month = month; calendar->today.day = day; @@ -104,6 +107,28 @@ void lv_calendar_set_today_date(lv_obj_t * obj, uint32_t year, uint32_t month, u highlight_update(obj); } +void lv_calendar_set_today_year(lv_obj_t * obj, uint32_t year) +{ + LV_ASSERT_OBJ(obj, MY_CLASS); + lv_calendar_t * calendar = (lv_calendar_t *)obj; + lv_calendar_set_today_date(obj, year, calendar->today.month, calendar->today.day); + +} + +void lv_calendar_set_today_month(lv_obj_t * obj, uint32_t month) +{ + LV_ASSERT_OBJ(obj, MY_CLASS); + lv_calendar_t * calendar = (lv_calendar_t *)obj; + lv_calendar_set_today_date(obj, calendar->today.year, month, calendar->today.day); +} + +void lv_calendar_set_today_day(lv_obj_t * obj, uint32_t day) +{ + LV_ASSERT_OBJ(obj, MY_CLASS); + lv_calendar_t * calendar = (lv_calendar_t *)obj; + lv_calendar_set_today_date(obj, calendar->today.year, calendar->today.month, day); +} + void lv_calendar_set_highlighted_dates(lv_obj_t * obj, lv_calendar_date_t highlighted[], size_t date_num) { LV_ASSERT_NULL(highlighted); @@ -122,6 +147,9 @@ void lv_calendar_set_month_shown(lv_obj_t * obj, uint32_t year, uint32_t month) LV_ASSERT_OBJ(obj, MY_CLASS); lv_calendar_t * calendar = (lv_calendar_t *)obj; + /*Don't return if the new value is the same, as this function is also + *used the update the calendar e.g. when switching to Chinese mode*/ + calendar->showed_date.year = year; calendar->showed_date.month = month; calendar->showed_date.day = 1; @@ -212,6 +240,21 @@ void lv_calendar_set_month_shown(lv_obj_t * obj, uint32_t year, uint32_t month) } } +void lv_calendar_set_shown_year(lv_obj_t * obj, uint32_t year) +{ + LV_ASSERT_OBJ(obj, MY_CLASS); + lv_calendar_t * calendar = (lv_calendar_t *)obj; + lv_calendar_set_month_shown(obj, year, calendar->showed_date.month); + +} + +void lv_calendar_set_shown_month(lv_obj_t * obj, uint32_t month) +{ + LV_ASSERT_OBJ(obj, MY_CLASS); + lv_calendar_t * calendar = (lv_calendar_t *)obj; + lv_calendar_set_month_shown(obj, calendar->showed_date.year, month); +} + /*===================== * Getter functions *====================*/ @@ -288,19 +331,6 @@ static void lv_calendar_constructor(const lv_obj_class_t * class_p, lv_obj_t * o LV_UNUSED(class_p); lv_calendar_t * calendar = (lv_calendar_t *)obj; - /*Initialize the allocated 'ext'*/ - - calendar->today.year = 2024; - calendar->today.month = 1; - calendar->today.day = 1; - - calendar->showed_date.year = 2024; - calendar->showed_date.month = 1; - calendar->showed_date.day = 1; - - calendar->highlighted_dates = NULL; - calendar->highlighted_dates_num = 0; - lv_memzero(calendar->nums, sizeof(calendar->nums)); uint8_t i; uint8_t j = 0; @@ -330,10 +360,10 @@ static void lv_calendar_constructor(const lv_obj_class_t * class_p, lv_obj_t * o lv_obj_set_flex_flow(obj, LV_FLEX_FLOW_COLUMN); lv_obj_set_flex_grow(calendar->btnm, 1); - lv_obj_set_style_text_align(obj, LV_TEXT_ALIGN_CENTER, LV_PART_MAIN); + lv_obj_set_style_text_align(calendar->btnm, LV_TEXT_ALIGN_CENTER, LV_PART_MAIN); - lv_calendar_set_month_shown(obj, calendar->showed_date.year, calendar->showed_date.month); - lv_calendar_set_today_date(obj, calendar->today.year, calendar->today.month, calendar->today.day); + lv_calendar_set_month_shown(obj, 2024, 1); + lv_calendar_set_today_date(obj, 2024, 1, 1); } static void draw_task_added_event_cb(lv_event_t * e) diff --git a/src/widgets/calendar/lv_calendar.h b/src/widgets/calendar/lv_calendar.h index c7159a3601..d986ef0486 100644 --- a/src/widgets/calendar/lv_calendar.h +++ b/src/widgets/calendar/lv_calendar.h @@ -30,8 +30,8 @@ extern "C" { */ typedef struct { uint16_t year; - int8_t month; /**< 1..12 */ - int8_t day; /**< 1..31 */ + uint8_t month; /**< 1..12 */ + uint8_t day; /**< 1..31 */ } lv_calendar_date_t; LV_ATTRIBUTE_EXTERN_DATA extern const lv_obj_class_t lv_calendar_class; @@ -56,7 +56,7 @@ lv_obj_t * lv_calendar_create(lv_obj_t * parent); *====================*/ /** - * Set the today's date + * Set the today's year, month and day at once * @param obj pointer to a calendar object * @param year today's year * @param month today's month [1..12] @@ -65,13 +65,48 @@ lv_obj_t * lv_calendar_create(lv_obj_t * parent); void lv_calendar_set_today_date(lv_obj_t * obj, uint32_t year, uint32_t month, uint32_t day); /** - * Set the currently showed + * Set the today's year + * @param obj pointer to a calendar object + * @param year today's year + */ +void lv_calendar_set_today_year(lv_obj_t * obj, uint32_t year); + +/** + * Set the today's year + * @param obj pointer to a calendar object + * @param month today's month [1..12] + */ +void lv_calendar_set_today_month(lv_obj_t * obj, uint32_t month); + +/** + * Set the today's year + * @param obj pointer to a calendar object + * @param day today's day [1..31] + */ +void lv_calendar_set_today_day(lv_obj_t * obj, uint32_t day); + +/** + * Set the currently shown year and month at once * @param obj pointer to a calendar object - * @param year today's year - * @param month today's month [1..12] + * @param year shown year + * @param month shown month [1..12] */ void lv_calendar_set_month_shown(lv_obj_t * obj, uint32_t year, uint32_t month); +/** + * Set the currently shown year + * @param obj pointer to a calendar object + * @param year shown year + */ +void lv_calendar_set_shown_year(lv_obj_t * obj, uint32_t year); + +/** + * Set the currently shown month + * @param obj pointer to a calendar object + * @param month shown month [1..12] + */ +void lv_calendar_set_shown_month(lv_obj_t * obj, uint32_t month); + /** * Set the highlighted dates * @param obj pointer to a calendar object diff --git a/src/widgets/calendar/lv_calendar_header_dropdown.c b/src/widgets/calendar/lv_calendar_header_dropdown.c index 766f0d9450..f49b857e29 100644 --- a/src/widgets/calendar/lv_calendar_header_dropdown.c +++ b/src/widgets/calendar/lv_calendar_header_dropdown.c @@ -1,5 +1,5 @@ /** - * @file lv_calendar_obj_dropdown.c + * @file lv_calendar_header_dropdown.c * */ @@ -119,7 +119,8 @@ static void my_constructor(const lv_obj_class_t * class_p, lv_obj_t * obj) lv_obj_set_flex_grow(month_dd, 1); lv_obj_add_event_cb(obj, value_changed_event_cb, LV_EVENT_VALUE_CHANGED, NULL); - /*Refresh the drop downs*/ + + /*Refresh the drop down*/ lv_obj_send_event(obj, LV_EVENT_VALUE_CHANGED, NULL); } diff --git a/src/widgets/canvas/lv_canvas.c b/src/widgets/canvas/lv_canvas.c index cd0e60e417..930d109381 100644 --- a/src/widgets/canvas/lv_canvas.c +++ b/src/widgets/canvas/lv_canvas.c @@ -92,6 +92,11 @@ void lv_canvas_set_draw_buf(lv_obj_t * obj, lv_draw_buf_t * draw_buf) LV_ASSERT_OBJ(obj, MY_CLASS); LV_ASSERT_NULL(draw_buf); + if(!draw_buf->handlers) { + LV_LOG_ERROR("draw_buf has no handlers, maybe not initialized"); + return; + } + lv_canvas_t * canvas = (lv_canvas_t *)obj; canvas->draw_buf = draw_buf; @@ -365,6 +370,7 @@ void lv_canvas_fill_bg(lv_obj_t * obj, lv_color_t color, lv_opa_t opa) } } + lv_draw_buf_flush_cache(canvas->draw_buf, NULL); lv_obj_invalidate(obj); } diff --git a/src/widgets/chart/lv_chart.c b/src/widgets/chart/lv_chart.c index 6f17bd373c..2b0e155aa0 100644 --- a/src/widgets/chart/lv_chart.c +++ b/src/widgets/chart/lv_chart.c @@ -11,6 +11,7 @@ #include "../../draw/lv_draw_private.h" #include "../../core/lv_obj_private.h" #include "../../core/lv_obj_class_private.h" +#include "../../core/lv_obj_draw_private.h" #if LV_USE_CHART != 0 #include "../../misc/lv_assert.h" @@ -39,11 +40,13 @@ static void lv_chart_event(const lv_obj_class_t * class_p, lv_event_t * e); static void draw_div_lines(lv_obj_t * obj, lv_layer_t * layer); static void draw_series_line(lv_obj_t * obj, lv_layer_t * layer); static void draw_series_bar(lv_obj_t * obj, lv_layer_t * layer); +static void draw_series_stacked(lv_obj_t * obj, lv_layer_t * layer); static void draw_series_scatter(lv_obj_t * obj, lv_layer_t * layer); static void draw_cursors(lv_obj_t * obj, lv_layer_t * layer); static uint32_t get_index_from_x(lv_obj_t * obj, int32_t x); static void invalidate_point(lv_obj_t * obj, uint32_t i); static void new_points_alloc(lv_obj_t * obj, lv_chart_series_t * ser, uint32_t cnt, int32_t ** a); +static int32_t value_to_y(lv_obj_t * obj, lv_chart_series_t * ser, int32_t v, int32_t h); /********************** * STATIC VARIABLES @@ -129,28 +132,57 @@ void lv_chart_set_point_count(lv_obj_t * obj, uint32_t cnt) lv_chart_refresh(obj); } -void lv_chart_set_axis_range(lv_obj_t * obj, lv_chart_axis_t axis, int32_t min, int32_t max) +void lv_chart_set_axis_min_value(lv_obj_t * obj, lv_chart_axis_t axis, int32_t min) { LV_ASSERT_OBJ(obj, MY_CLASS); - max = max == min ? max + 1 : max; - lv_chart_t * chart = (lv_chart_t *)obj; + switch(axis) { case LV_CHART_AXIS_PRIMARY_Y: + if(chart->ymin[0] == min) return; chart->ymin[0] = min; - chart->ymax[0] = max; break; case LV_CHART_AXIS_SECONDARY_Y: + if(chart->ymin[1] == min) return; chart->ymin[1] = min; - chart->ymax[1] = max; break; case LV_CHART_AXIS_PRIMARY_X: + if(chart->xmin[0] == min) return; chart->xmin[0] = min; - chart->xmax[0] = max; break; case LV_CHART_AXIS_SECONDARY_X: + if(chart->xmin[1] == min) return; chart->xmin[1] = min; + break; + default: + LV_LOG_WARN("Invalid axis: %d", axis); + return; + } + + lv_chart_refresh(obj); +} + +void lv_chart_set_axis_max_value(lv_obj_t * obj, lv_chart_axis_t axis, int32_t max) +{ + LV_ASSERT_OBJ(obj, MY_CLASS); + + lv_chart_t * chart = (lv_chart_t *)obj; + switch(axis) { + case LV_CHART_AXIS_PRIMARY_Y: + if(chart->ymax[0] == max) return; + chart->ymax[0] = max; + break; + case LV_CHART_AXIS_SECONDARY_Y: + if(chart->ymax[1] == max) return; + chart->ymax[1] = max; + break; + case LV_CHART_AXIS_PRIMARY_X: + if(chart->xmax[0] == max) return; + chart->xmax[0] = max; + break; + case LV_CHART_AXIS_SECONDARY_X: + if(chart->xmax[1] == max) return; chart->xmax[1] = max; break; default: @@ -161,6 +193,14 @@ void lv_chart_set_axis_range(lv_obj_t * obj, lv_chart_axis_t axis, int32_t min, lv_chart_refresh(obj); } +void lv_chart_set_axis_range(lv_obj_t * obj, lv_chart_axis_t axis, int32_t min, int32_t max) +{ + LV_ASSERT_OBJ(obj, MY_CLASS); + + lv_chart_set_axis_min_value(obj, axis, min); + lv_chart_set_axis_max_value(obj, axis, max); +} + void lv_chart_set_update_mode(lv_obj_t * obj, lv_chart_update_mode_t update_mode) { LV_ASSERT_OBJ(obj, MY_CLASS); @@ -172,7 +212,7 @@ void lv_chart_set_update_mode(lv_obj_t * obj, lv_chart_update_mode_t update_mode lv_obj_invalidate(obj); } -void lv_chart_set_div_line_count(lv_obj_t * obj, uint8_t hdiv, uint8_t vdiv) +void lv_chart_set_div_line_count(lv_obj_t * obj, uint32_t hdiv, uint32_t vdiv) { LV_ASSERT_OBJ(obj, MY_CLASS); @@ -185,6 +225,26 @@ void lv_chart_set_div_line_count(lv_obj_t * obj, uint8_t hdiv, uint8_t vdiv) lv_obj_invalidate(obj); } +void lv_chart_set_hor_div_line_count(lv_obj_t * obj, uint32_t cnt) +{ + LV_ASSERT_OBJ(obj, MY_CLASS); + + lv_chart_t * chart = (lv_chart_t *)obj; + if(chart->hdiv_cnt == cnt) return; + chart->hdiv_cnt = cnt; + lv_obj_invalidate(obj); +} + +void lv_chart_set_ver_div_line_count(lv_obj_t * obj, uint32_t cnt) +{ + LV_ASSERT_OBJ(obj, MY_CLASS); + + lv_chart_t * chart = (lv_chart_t *)obj; + if(chart->vdiv_cnt == cnt) return; + chart->vdiv_cnt = cnt; + lv_obj_invalidate(obj); +} + lv_chart_type_t lv_chart_get_type(const lv_obj_t * obj) { LV_ASSERT_OBJ(obj, MY_CLASS); @@ -233,9 +293,13 @@ void lv_chart_get_point_pos_by_id(lv_obj_t * obj, lv_chart_series_t * ser, uint3 else { p_out->x = 0; } + int32_t temp_y = value_to_y(obj, ser, ser->y_points[id], h); + p_out->y = h - temp_y; } else if(chart->type == LV_CHART_TYPE_SCATTER) { p_out->x = lv_map(ser->x_points[id], chart->xmin[ser->x_axis_sec], chart->xmax[ser->x_axis_sec], 0, w); + int32_t temp_y = value_to_y(obj, ser, ser->y_points[id], h); + p_out->y = h - temp_y; } else if(chart->type == LV_CHART_TYPE_BAR) { uint32_t ser_cnt = lv_ll_get_len(&chart->series_ll); @@ -270,9 +334,51 @@ void lv_chart_get_point_pos_by_id(lv_obj_t * obj, lv_chart_series_t * ser, uint3 else { LV_LOG_WARN("bar chart series count is zero"); } + + int32_t temp_y = value_to_y(obj, ser, ser->y_points[id], h); + p_out->y = h - temp_y; + } + else if(chart->type == LV_CHART_TYPE_STACKED) { + /*Gap between the columns on adjacent X ticks*/ + int32_t block_gap = lv_obj_get_style_pad_column(obj, LV_PART_MAIN); + + int32_t block_w = (w - ((chart->point_cnt - 1) * block_gap)) / chart->point_cnt; + + if(chart->point_cnt > 1) { + p_out->x = (int32_t)((int32_t)(w - block_w) * id) / (chart->point_cnt - 1); + } + else { + p_out->x = 0; + } + + p_out->x += block_w / 2; + + int32_t v_sum = 0; + lv_chart_series_t * s; + LV_LL_READ(&chart->series_ll, s) { + if(s->hidden) continue; + int32_t start_point = chart->update_mode == LV_CHART_UPDATE_MODE_SHIFT ? s->start_point : 0; + int32_t p_act = (start_point + id) % chart->point_cnt; + int32_t v_act = s->y_points[p_act]; + if(s->y_points[p_act] == LV_CHART_POINT_NONE) continue; + + /* Skip negative values in stacked charts. Negative values are not supported + * in stacked charts as they cannot be visually represented in the stacking logic. */ + if(v_act <= 0) { + LV_LOG_WARN("Stacked chart doesn't support negative values."); + continue; + } + v_sum += v_act; + if(s == ser) break; + } + + int32_t temp_y = value_to_y(obj, ser, v_sum, h); + p_out->y = h - temp_y; } + /*LV_CHART_TYPE_NONE*/ else { p_out->x = 0; + p_out->y = 0; } int32_t border_width = lv_obj_get_style_border_width(obj, LV_PART_MAIN); @@ -281,10 +387,7 @@ void lv_chart_get_point_pos_by_id(lv_obj_t * obj, lv_chart_series_t * ser, uint3 uint32_t start_point = chart->update_mode == LV_CHART_UPDATE_MODE_SHIFT ? ser->start_point : 0; id = ((int32_t)start_point + id) % chart->point_cnt; - int32_t temp_y = 0; - temp_y = (int32_t)((int32_t)ser->y_points[id] - chart->ymin[ser->y_axis_sec]) * h; - temp_y = temp_y / (chart->ymax[ser->y_axis_sec] - chart->ymin[ser->y_axis_sec]); - p_out->y = h - temp_y; + p_out->y += lv_obj_get_style_pad_top(obj, LV_PART_MAIN) + border_width; p_out->y -= lv_obj_get_scroll_top(obj); } @@ -445,6 +548,16 @@ lv_chart_cursor_t * lv_chart_add_cursor(lv_obj_t * obj, lv_color_t color, lv_di return cursor; } +void lv_chart_remove_cursor(lv_obj_t * obj, lv_chart_cursor_t * cursor) +{ + LV_ASSERT_OBJ(obj, MY_CLASS); + LV_ASSERT_NULL(cursor); + + lv_chart_t * chart = (lv_chart_t *)obj; + lv_ll_remove(&chart->cursor_ll, cursor); + lv_free(cursor); +} + void lv_chart_set_cursor_pos(lv_obj_t * chart, lv_chart_cursor_t * cursor, lv_point_t * pos) { LV_ASSERT_NULL(cursor); @@ -520,10 +633,10 @@ void lv_chart_set_next_value(lv_obj_t * obj, lv_chart_series_t * ser, int32_t va LV_ASSERT_NULL(ser); lv_chart_t * chart = (lv_chart_t *)obj; + ser->y_points[ser->start_point] = value; invalidate_point(obj, ser->start_point); ser->start_point = (ser->start_point + 1) % chart->point_cnt; - invalidate_point(obj, ser->start_point); } void lv_chart_set_next_value2(lv_obj_t * obj, lv_chart_series_t * ser, int32_t x_value, int32_t y_value) @@ -640,7 +753,7 @@ int32_t lv_chart_get_first_point_center_offset(lv_obj_t * obj) lv_chart_t * chart = (lv_chart_t *)obj; int32_t x_ofs = lv_obj_get_style_pad_left(obj, LV_PART_MAIN); - if(chart->type == LV_CHART_TYPE_BAR) { + if(chart->type == LV_CHART_TYPE_BAR || chart->type == LV_CHART_TYPE_STACKED) { lv_obj_update_layout(obj); /*Gap between the columns on ~adjacent X*/ int32_t block_gap = lv_obj_get_style_pad_column(obj, LV_PART_MAIN); @@ -750,15 +863,30 @@ static void lv_chart_event(const lv_obj_class_t * class_p, lv_event_t * e) } else if(code == LV_EVENT_DRAW_MAIN) { lv_layer_t * layer = lv_event_get_layer(e); - draw_div_lines(obj, layer); - if(lv_ll_is_empty(&chart->series_ll) == false) { - if(chart->type == LV_CHART_TYPE_LINE) draw_series_line(obj, layer); - else if(chart->type == LV_CHART_TYPE_BAR) draw_series_bar(obj, layer); - else if(chart->type == LV_CHART_TYPE_SCATTER) draw_series_scatter(obj, layer); - } + lv_area_t ext_coords; + lv_obj_get_coords(obj, &ext_coords); + int32_t ext_draw_size = lv_obj_get_ext_draw_size(obj); + lv_area_increase(&ext_coords, ext_draw_size, ext_draw_size); + + lv_area_t clip_area; + if(lv_area_intersect(&clip_area, &ext_coords, &layer->_clip_area)) { + const lv_area_t clip_area_ori = layer->_clip_area; + layer->_clip_area = clip_area; + + draw_div_lines(obj, layer); + + if(lv_ll_is_empty(&chart->series_ll) == false) { + if(chart->type == LV_CHART_TYPE_LINE) draw_series_line(obj, layer); + else if(chart->type == LV_CHART_TYPE_BAR) draw_series_bar(obj, layer); + else if(chart->type == LV_CHART_TYPE_STACKED) draw_series_stacked(obj, layer); + else if(chart->type == LV_CHART_TYPE_SCATTER) draw_series_scatter(obj, layer); + } - draw_cursors(obj, layer); + draw_cursors(obj, layer); + + layer->_clip_area = clip_area_ori; + } } } @@ -766,13 +894,6 @@ static void draw_div_lines(lv_obj_t * obj, lv_layer_t * layer) { lv_chart_t * chart = (lv_chart_t *)obj; - lv_area_t series_clip_area; - bool mask_ret = lv_area_intersect(&series_clip_area, &obj->coords, &layer->_clip_area); - if(mask_ret == false) return; - - const lv_area_t clip_area_ori = layer->_clip_area; - layer->_clip_area = series_clip_area; - int16_t i; int16_t i_start; int16_t i_end; @@ -793,7 +914,7 @@ static void draw_div_lines(lv_obj_t * obj, lv_layer_t * layer) int32_t scroll_left = lv_obj_get_scroll_left(obj); int32_t scroll_top = lv_obj_get_scroll_top(obj); - if(chart->hdiv_cnt != 0) { + if(chart->hdiv_cnt > 1) { int32_t y_ofs = obj->coords.y1 + pad_top - scroll_top; line_dsc.p1.x = obj->coords.x1; line_dsc.p2.x = obj->coords.x2; @@ -815,7 +936,7 @@ static void draw_div_lines(lv_obj_t * obj, lv_layer_t * layer) } } - if(chart->vdiv_cnt != 0) { + if(chart->vdiv_cnt > 1) { int32_t x_ofs = obj->coords.x1 + pad_left - scroll_left; line_dsc.p1.y = obj->coords.y1; line_dsc.p2.y = obj->coords.y2; @@ -835,18 +956,10 @@ static void draw_div_lines(lv_obj_t * obj, lv_layer_t * layer) lv_draw_line(layer, &line_dsc); } } - - layer->_clip_area = clip_area_ori; } static void draw_series_line(lv_obj_t * obj, lv_layer_t * layer) { - lv_area_t clip_area; - if(lv_area_intersect(&clip_area, &obj->coords, &layer->_clip_area) == false) return; - - const lv_area_t clip_area_ori = layer->_clip_area; - layer->_clip_area = clip_area; - lv_chart_t * chart = (lv_chart_t *)obj; if(chart->point_cnt < 2) return; @@ -860,10 +973,6 @@ static void draw_series_line(lv_obj_t * obj, lv_layer_t * layer) int32_t y_ofs = obj->coords.y1 + pad_top - lv_obj_get_scroll_top(obj); lv_chart_series_t * ser; - lv_area_t series_clip_area; - bool mask_ret = lv_area_intersect(&series_clip_area, &obj->coords, &layer->_clip_area); - if(mask_ret == false) return; - lv_draw_line_dsc_t line_dsc; lv_draw_line_dsc_init(&line_dsc); line_dsc.base.layer = layer; @@ -919,7 +1028,7 @@ static void draw_series_line(lv_obj_t * obj, lv_layer_t * layer) line_dsc.p1.x = line_dsc.p2.x; line_dsc.p1.y = line_dsc.p2.y; - if(line_dsc.p1.x > clip_area_ori.x2 + point_w + 1) break; + if(line_dsc.p1.x > layer->_clip_area.x2 + point_w + 1) break; line_dsc.p2.x = (lv_value_precise_t)((w * i) / (chart->point_cnt - 1)) + x_ofs; p_act = (start_point + i) % chart->point_cnt; @@ -928,7 +1037,7 @@ static void draw_series_line(lv_obj_t * obj, lv_layer_t * layer) y_tmp = y_tmp / (chart->ymax[ser->y_axis_sec] - chart->ymin[ser->y_axis_sec]); line_dsc.p2.y = h - y_tmp + y_ofs; - if(line_dsc.p2.x < clip_area_ori.x1 - point_w - 1) { + if(line_dsc.p2.x < layer->_clip_area.x1 - point_w - 1) { p_prev = p_act; continue; } @@ -995,19 +1104,10 @@ static void draw_series_line(lv_obj_t * obj, lv_layer_t * layer) line_dsc.base.id1--; } } - - layer->_clip_area = clip_area_ori; } static void draw_series_scatter(lv_obj_t * obj, lv_layer_t * layer) { - - lv_area_t clip_area; - if(lv_area_intersect(&clip_area, &obj->coords, &layer->_clip_area) == false) return; - - const lv_area_t clip_area_ori = layer->_clip_area; - layer->_clip_area = clip_area; - lv_chart_t * chart = (lv_chart_t *)obj; uint32_t i; @@ -1069,7 +1169,7 @@ static void draw_series_scatter(lv_obj_t * obj, lv_layer_t * layer) p_act = (start_point + i) % chart->point_cnt; if(ser->y_points[p_act] != LV_CHART_POINT_NONE) { - line_dsc.p2.y = lv_map(ser->y_points[p_act], chart->ymin[ser->y_axis_sec], chart->ymax[ser->y_axis_sec], 0, h); + line_dsc.p2.y = lv_map(ser->y_points[p_act], chart->ymin[ser->y_axis_sec], chart->ymax[ser->y_axis_sec], 0, h); line_dsc.p2.y = h - line_dsc.p2.y; line_dsc.p2.y += y_ofs; @@ -1117,18 +1217,11 @@ static void draw_series_scatter(lv_obj_t * obj, lv_layer_t * layer) } line_dsc.base.id1++; point_dsc_default.base.id1++; - layer->_clip_area = clip_area_ori; } } static void draw_series_bar(lv_obj_t * obj, lv_layer_t * layer) { - lv_area_t clip_area; - if(lv_area_intersect(&clip_area, &obj->coords, &layer->_clip_area) == false) return; - - const lv_area_t clip_area_ori = layer->_clip_area; - layer->_clip_area = clip_area; - lv_chart_t * chart = (lv_chart_t *)obj; uint32_t i; @@ -1186,11 +1279,11 @@ static void draw_series_bar(lv_obj_t * obj, lv_layer_t * layer) col_a.x2 = col_a.x1 + col_w - 1; x_act += col_w + ser_gap; - if(col_a.x2 < clip_area.x1) { + if(col_a.x2 < layer->_clip_area.x1) { col_dsc.base.id1++; continue; } - if(col_a.x1 > clip_area.x2) break; + if(col_a.x1 > layer->_clip_area.x2) break; col_dsc.bg_color = ser->color; @@ -1205,6 +1298,117 @@ static void draw_series_bar(lv_obj_t * obj, lv_layer_t * layer) col_dsc.base.id1++; } } +} + +static void draw_series_stacked(lv_obj_t * obj, lv_layer_t * layer) +{ + lv_chart_t * chart = (lv_chart_t *)obj; + + uint32_t i; + int32_t pad_left = lv_obj_get_style_pad_left(obj, LV_PART_MAIN); + int32_t pad_bottom = lv_obj_get_style_pad_bottom(obj, LV_PART_MAIN); + int32_t w = lv_obj_get_content_width(obj); + int32_t h = lv_obj_get_content_height(obj); + lv_chart_series_t * ser; + uint32_t ser_cnt = lv_ll_get_len(&chart->series_ll); + if(ser_cnt == 0) { + return; + } + + int32_t block_gap = lv_obj_get_style_pad_column(obj, LV_PART_MAIN); /*Gap between the columns on adjacent X ticks*/ + int32_t block_w = (w - ((chart->point_cnt - 1) * block_gap)) / chart->point_cnt; + + int32_t border_w = lv_obj_get_style_border_width(obj, LV_PART_MAIN); + int32_t x_ofs = pad_left - lv_obj_get_scroll_left(obj) + border_w; + int32_t y_ofs = pad_bottom - lv_obj_get_scroll_top(obj) + border_w; + + lv_draw_rect_dsc_t col_dsc; + lv_draw_rect_dsc_init(&col_dsc); + col_dsc.base.layer = layer; + lv_obj_init_draw_rect_dsc(obj, LV_PART_ITEMS, &col_dsc); + col_dsc.bg_grad.dir = LV_GRAD_DIR_NONE; + col_dsc.bg_opa = LV_OPA_COVER; + + lv_area_t clip_area_ori = layer->_clip_area; + + /*Go through all points*/ + lv_area_t bar_full_area; + for(i = 0; i < chart->point_cnt; i++) { + col_dsc.base.id2 = i; + col_dsc.base.id1 = 0; + + /*Get the total bar height. All segments (series) will be drawn in the height*/ + int32_t v_sum_all = 0; + LV_LL_READ(&chart->series_ll, ser) { + if(ser->hidden) continue; + int32_t start_point = chart->update_mode == LV_CHART_UPDATE_MODE_SHIFT ? ser->start_point : 0; + int32_t p_act = (start_point + i) % chart->point_cnt; + int32_t v_act = ser->y_points[p_act]; + if(ser->y_points[p_act] == LV_CHART_POINT_NONE) continue; + + /* Skip negative values in stacked charts. Negative values are not supported + * in stacked charts as they cannot be visually represented in the stacking logic. */ + if(v_act <= 0) { + LV_LOG_WARN("Stacked chart doesn't support negative values."); + continue; + } + v_sum_all += v_act; + } + + int32_t total_bar_height = value_to_y(obj, lv_ll_get_head(&chart->series_ll), v_sum_all, h); + if(total_bar_height <= 0) continue; + + if(chart->point_cnt <= 1) { + bar_full_area.x1 = obj->coords.x1 + x_ofs; + } + else { + bar_full_area.x1 = (int32_t)((int32_t)(w - block_w) * i) / (chart->point_cnt - 1) + obj->coords.x1 + x_ofs; + } + bar_full_area.x2 = bar_full_area.x1 + block_w - 1; + + /*No in the clip area yet*/ + if(bar_full_area.x2 < clip_area_ori.x1) continue; + + /*Out of the clip area already*/ + if(bar_full_area.x1 > clip_area_ori.x2) break; + + /*Draw the full_bar_area and set the clip area to clip the segments*/ + bar_full_area.y2 = obj->coords.y2 + col_dsc.radius; + bar_full_area.y1 = obj->coords.y2 - y_ofs - total_bar_height + 1; + + lv_area_t bar_clip_area = bar_full_area; + int32_t y_prev = obj->coords.y2 + 1; + + /*Draw the current point of all data line*/ + int32_t v_sum_act = 0; + LV_LL_READ(&chart->series_ll, ser) { + int32_t start_point = chart->update_mode == LV_CHART_UPDATE_MODE_SHIFT ? ser->start_point : 0; + + col_dsc.bg_color = ser->color; + + int32_t p_act = (start_point + i) % chart->point_cnt; + int32_t v_act = ser->y_points[p_act]; + /*Can't show negative values on a stacked chart*/ + if(ser->y_points[p_act] == LV_CHART_POINT_NONE || + v_act <= 0 || + ser->hidden) { + col_dsc.base.id1++; + continue; + } + + v_sum_act += v_act; /*Use the summed value to get its `y` to avoid rounding errors*/ + + int32_t segment_y = value_to_y(obj, ser, v_sum_act, h); + bar_clip_area.y2 = y_prev - 1; + bar_clip_area.y1 = obj->coords.y2 - y_ofs - segment_y + 1; + y_prev = bar_clip_area.y1; + if(lv_area_intersect(&layer->_clip_area, &clip_area_ori, &bar_clip_area)) { + lv_draw_rect(layer, &col_dsc, &bar_full_area); + } + col_dsc.base.id1++; + } + + } layer->_clip_area = clip_area_ori; } @@ -1215,12 +1419,6 @@ static void draw_cursors(lv_obj_t * obj, lv_layer_t * layer) lv_chart_t * chart = (lv_chart_t *)obj; if(lv_ll_is_empty(&chart->cursor_ll)) return; - lv_area_t clip_area; - if(!lv_area_intersect(&clip_area, &layer->_clip_area, &obj->coords)) return; - - const lv_area_t clip_area_ori = layer->_clip_area; - layer->_clip_area = clip_area; - lv_chart_cursor_t * cursor; lv_draw_line_dsc_t line_dsc_ori; @@ -1304,8 +1502,6 @@ static void draw_cursors(lv_obj_t * obj, lv_layer_t * layer) line_dsc_ori.base.id1++; point_dsc_ori.base.id1++; } - - layer->_clip_area = clip_area_ori; } /** @@ -1324,7 +1520,7 @@ static uint32_t get_index_from_x(lv_obj_t * obj, int32_t x) if(x < 0) return 0; if(x > w) return chart->point_cnt - 1; if(chart->type == LV_CHART_TYPE_LINE) return (x * (chart->point_cnt - 1) + w / 2) / w; - if(chart->type == LV_CHART_TYPE_BAR) return (x * chart->point_cnt) / w; + if(chart->type == LV_CHART_TYPE_BAR || chart->type == LV_CHART_TYPE_STACKED) return (x * chart->point_cnt) / w; if(chart->type == LV_CHART_TYPE_SCATTER) { /*For scatter charts, the nearest id could be different depending on the series. Just check the first series.*/ lv_chart_series_t * ser = lv_chart_get_series_next(obj, NULL); @@ -1350,19 +1546,19 @@ static void invalidate_point(lv_obj_t * obj, uint32_t i) lv_chart_t * chart = (lv_chart_t *)obj; if(i >= chart->point_cnt) return; - int32_t w = lv_obj_get_content_width(obj); - int32_t scroll_left = lv_obj_get_scroll_left(obj); /*In shift mode the whole chart changes so the whole object*/ if(chart->update_mode == LV_CHART_UPDATE_MODE_SHIFT) { lv_obj_invalidate(obj); return; } + int32_t w = lv_obj_get_content_width(obj); + int32_t scroll_left = lv_obj_get_scroll_left(obj); + int32_t bwidth = lv_obj_get_style_border_width(obj, LV_PART_MAIN); + int32_t pleft = lv_obj_get_style_pad_left(obj, LV_PART_MAIN); + int32_t x_ofs = obj->coords.x1 + pleft + bwidth - scroll_left; if(chart->type == LV_CHART_TYPE_LINE) { - int32_t bwidth = lv_obj_get_style_border_width(obj, LV_PART_MAIN); - int32_t pleft = lv_obj_get_style_pad_left(obj, LV_PART_MAIN); - int32_t x_ofs = obj->coords.x1 + pleft + bwidth - scroll_left; int32_t line_width = lv_obj_get_style_line_width(obj, LV_PART_ITEMS); int32_t point_w = lv_obj_get_style_width(obj, LV_PART_INDICATOR); @@ -1371,6 +1567,7 @@ static void invalidate_point(lv_obj_t * obj, uint32_t i) coords.y1 -= line_width + point_w; coords.y2 += line_width + point_w; + /*Invalidate the area between the previous and the next points*/ if(i < chart->point_cnt - 1) { coords.x1 = ((w * i) / (chart->point_cnt - 1)) + x_ofs - line_width - point_w; coords.x2 = ((w * (i + 1)) / (chart->point_cnt - 1)) + x_ofs + line_width + point_w; @@ -1383,21 +1580,23 @@ static void invalidate_point(lv_obj_t * obj, uint32_t i) lv_obj_invalidate_area(obj, &coords); } } - else if(chart->type == LV_CHART_TYPE_BAR) { + else if(chart->type == LV_CHART_TYPE_BAR || chart->type == LV_CHART_TYPE_STACKED) { lv_area_t col_a; /*Gap between the column on ~adjacent X*/ int32_t block_gap = lv_obj_get_style_pad_column(obj, LV_PART_MAIN); + int32_t block_w = (w - ((chart->point_cnt - 1) * block_gap)) / chart->point_cnt; - int32_t block_w = (w + block_gap) / chart->point_cnt; - - int32_t bwidth = lv_obj_get_style_border_width(obj, LV_PART_MAIN); int32_t x_act; - x_act = (int32_t)((int32_t)(block_w) * i) ; - x_act += obj->coords.x1 + bwidth + lv_obj_get_style_pad_left(obj, LV_PART_MAIN); + if(chart->point_cnt > 1) { + x_act = (int32_t)((int32_t)(w - block_w) * i) / (chart->point_cnt - 1); + } + else { + x_act = 0; + } lv_obj_get_coords(obj, &col_a); - col_a.x1 = x_act - scroll_left; - col_a.x2 = col_a.x1 + block_w; + col_a.x1 = x_act + x_ofs; + col_a.x2 = col_a.x1 + block_w + block_gap; col_a.x1 -= block_gap; lv_obj_invalidate_area(obj, &col_a); @@ -1453,4 +1652,19 @@ static void new_points_alloc(lv_obj_t * obj, lv_chart_series_t * ser, uint32_t c } } +/** + * Map a value to a height + * @param obj pointer to a chart + * @param ser pointer to the series + * @param v the value to map + * @param h the height to which the value needs to be mapped + * @return the mapped y-coordinate value corresponding to the input value + */ +static int32_t value_to_y(lv_obj_t * obj, lv_chart_series_t * ser, int32_t v, int32_t h) +{ + lv_chart_t * chart = (lv_chart_t *) obj; + + return lv_map(v, chart->ymin[ser->y_axis_sec], chart->ymax[ser->y_axis_sec], 0, h); +} + #endif diff --git a/src/widgets/chart/lv_chart.h b/src/widgets/chart/lv_chart.h index 3f5dc3a710..64b9ea5f43 100644 --- a/src/widgets/chart/lv_chart.h +++ b/src/widgets/chart/lv_chart.h @@ -36,7 +36,8 @@ LV_EXPORT_CONST_INT(LV_CHART_POINT_NONE); typedef enum { LV_CHART_TYPE_NONE, /**< Don't draw the series*/ LV_CHART_TYPE_LINE, /**< Connect the points with lines*/ - LV_CHART_TYPE_BAR, /**< Draw columns*/ + LV_CHART_TYPE_BAR, /**< Draw bars for each series*/ + LV_CHART_TYPE_STACKED, /**< Draw a single stacked bar for each data point. Supports only positive values*/ LV_CHART_TYPE_SCATTER, /**< Draw points and lines in 2D (x,y coordinates)*/ } lv_chart_type_t; @@ -94,6 +95,23 @@ void lv_chart_set_point_count(lv_obj_t * obj, uint32_t cnt); */ void lv_chart_set_axis_range(lv_obj_t * obj, lv_chart_axis_t axis, int32_t min, int32_t max); +/** + * Set the minimal values on an axis + * @param obj pointer to a chart object + * @param axis `LV_CHART_AXIS_PRIMARY_Y` or `LV_CHART_AXIS_SECONDARY_Y` + * @param min minimal value of the y axis + */ +void lv_chart_set_axis_min_value(lv_obj_t * obj, lv_chart_axis_t axis, int32_t min); + +/** + * Set the maximal y values on an axis + * @param obj pointer to a chart object + * @param axis `LV_CHART_AXIS_PRIMARY_Y` or `LV_CHART_AXIS_SECONDARY_Y` + * @param max maximum value of the y axis + */ +void lv_chart_set_axis_max_value(lv_obj_t * obj, lv_chart_axis_t axis, int32_t max); + + /** * Set update mode of the chart object. Affects * @param obj pointer to a chart object @@ -107,7 +125,21 @@ void lv_chart_set_update_mode(lv_obj_t * obj, lv_chart_update_mode_t update_mode * @param hdiv number of horizontal division lines * @param vdiv number of vertical division lines */ -void lv_chart_set_div_line_count(lv_obj_t * obj, uint8_t hdiv, uint8_t vdiv); +void lv_chart_set_div_line_count(lv_obj_t * obj, uint32_t hdiv, uint32_t vdiv); + +/** + * Set the number of horizontal division lines + * @param obj pointer to a chart object + * @param cnt number of horizontal division lines + */ +void lv_chart_set_hor_div_line_count(lv_obj_t * obj, uint32_t cnt); + +/** + * Set the number of vertical division lines + * @param obj pointer to a chart object + * @param cnt number of vertical division lines + */ +void lv_chart_set_ver_div_line_count(lv_obj_t * obj, uint32_t cnt); /** * Get the type of a chart @@ -220,6 +252,13 @@ lv_chart_series_t * lv_chart_get_series_next(const lv_obj_t * chart, const lv_ch */ lv_chart_cursor_t * lv_chart_add_cursor(lv_obj_t * obj, lv_color_t color, lv_dir_t dir); +/** + * Remove a cursor + * @param obj pointer to chart object + * @param cursor pointer to the cursor + */ +void lv_chart_remove_cursor(lv_obj_t * obj, lv_chart_cursor_t * cursor); + /** * Set the coordinate of the cursor with respect to the paddings * @param chart pointer to a chart object diff --git a/src/widgets/chart/lv_chart_private.h b/src/widgets/chart/lv_chart_private.h index 7ccda787d1..b2f0bcc42a 100644 --- a/src/widgets/chart/lv_chart_private.h +++ b/src/widgets/chart/lv_chart_private.h @@ -63,7 +63,7 @@ struct _lv_chart_t { uint32_t hdiv_cnt; /**< Number of horizontal division lines */ uint32_t vdiv_cnt; /**< Number of vertical division lines */ uint32_t point_cnt; /**< Number of points in all series */ - lv_chart_type_t type : 3; /**< Chart type */ + lv_chart_type_t type : 4; /**< Chart type */ lv_chart_update_mode_t update_mode : 2; }; diff --git a/src/widgets/checkbox/lv_checkbox.c b/src/widgets/checkbox/lv_checkbox.c index f394fb8a11..23f3d5c212 100644 --- a/src/widgets/checkbox/lv_checkbox.c +++ b/src/widgets/checkbox/lv_checkbox.c @@ -1,5 +1,5 @@ /** - * @file lv_cb.c + * @file lv_checkbox.c * */ @@ -12,6 +12,7 @@ #if LV_USE_CHECKBOX != 0 #include "../../misc/lv_assert.h" +#include "../../misc/lv_text_private.h" #include "../../misc/lv_text_ap.h" #include "../../core/lv_group.h" #include "../../draw/lv_draw.h" @@ -182,11 +183,16 @@ static void lv_checkbox_event(const lv_obj_class_t * class_p, lv_event_t * e) const lv_font_t * font = lv_obj_get_style_text_font(obj, LV_PART_MAIN); int32_t font_h = lv_font_get_line_height(font); - int32_t line_space = lv_obj_get_style_text_line_space(obj, LV_PART_MAIN); - int32_t letter_space = lv_obj_get_style_text_letter_space(obj, LV_PART_MAIN); + lv_text_attributes_t attributes = {0}; + + attributes.line_space = lv_obj_get_style_text_line_space(obj, LV_PART_MAIN); + attributes.letter_space = lv_obj_get_style_text_letter_space(obj, LV_PART_MAIN); + attributes.max_width = LV_COORD_MAX; + attributes.text_flags = LV_TEXT_FLAG_NONE; lv_point_t txt_size; - lv_text_get_size(&txt_size, cb->txt, font, letter_space, line_space, LV_COORD_MAX, LV_TEXT_FLAG_NONE); + + lv_text_get_size_attributes(&txt_size, cb->txt, font, &attributes); int32_t bg_colp = lv_obj_get_style_pad_column(obj, LV_PART_MAIN); int32_t marker_leftp = lv_obj_get_style_pad_left(obj, LV_PART_INDICATOR); @@ -257,11 +263,14 @@ static void lv_checkbox_draw(lv_event_t * e) lv_draw_rect(layer, &indic_dsc, &marker_area_transf); - int32_t line_space = lv_obj_get_style_text_line_space(obj, LV_PART_MAIN); - int32_t letter_space = lv_obj_get_style_text_letter_space(obj, LV_PART_MAIN); + lv_text_attributes_t attributes = {0}; + attributes.line_space = lv_obj_get_style_text_line_space(obj, LV_PART_MAIN); + attributes.letter_space = lv_obj_get_style_text_letter_space(obj, LV_PART_MAIN); + attributes.text_flags = LV_TEXT_FLAG_NONE; + attributes.max_width = LV_COORD_MAX; lv_point_t txt_size; - lv_text_get_size(&txt_size, cb->txt, font, letter_space, line_space, LV_COORD_MAX, LV_TEXT_FLAG_NONE); + lv_text_get_size_attributes(&txt_size, cb->txt, font, &attributes); lv_draw_label_dsc_t txt_dsc; lv_draw_label_dsc_init(&txt_dsc); diff --git a/src/widgets/dropdown/lv_dropdown.c b/src/widgets/dropdown/lv_dropdown.c index 5de58b9d1a..27659aca42 100644 --- a/src/widgets/dropdown/lv_dropdown.c +++ b/src/widgets/dropdown/lv_dropdown.c @@ -22,6 +22,7 @@ #include "../../misc/lv_math.h" #include "../../misc/lv_text_ap.h" #include "../../misc/lv_text_private.h" +#include "../../others/observer/lv_observer_private.h" #include "../../stdlib/lv_string.h" /********************* @@ -59,6 +60,11 @@ static uint32_t get_id_on_point(lv_obj_t * dropdown_obj, int32_t y); static void position_to_selected(lv_obj_t * dropdown_obj, lv_anim_enable_t anim_en); static lv_obj_t * get_label(const lv_obj_t * obj); +#if LV_USE_OBSERVER + static void dropdown_value_changed_event_cb(lv_event_t * e); + static void dropdown_value_observer_cb(lv_observer_t * observer, lv_subject_t * subject); +#endif /*LV_USE_OBSERVER*/ + /********************** * STATIC VARIABLES **********************/ @@ -262,14 +268,19 @@ void lv_dropdown_add_option(lv_obj_t * obj, const char * option, uint32_t pos) /*Convert static options to dynamic*/ if(dropdown->static_txt != 0) { char * static_options = dropdown->options; - dropdown->options = lv_strdup(static_options); + if(dropdown->options) { + dropdown->options = lv_strdup(static_options); + } + else { + dropdown->options = lv_calloc(1, 1); /*Allocate at least 1 byte for the NULL terminator*/ + } LV_ASSERT_MALLOC(dropdown->options); if(dropdown->options == NULL) return; dropdown->static_txt = 0; } /*Allocate space for the new option*/ - size_t old_len = (dropdown->options == NULL) ? 0 : lv_strlen(dropdown->options); + size_t old_len = lv_strlen(dropdown->options); #if LV_USE_ARABIC_PERSIAN_CHARS == 0 size_t ins_len = lv_strlen(option) + 1; #else @@ -329,7 +340,7 @@ void lv_dropdown_clear_options(lv_obj_t * obj) lv_free(dropdown->options); dropdown->options = NULL; - dropdown->static_txt = 0; + dropdown->static_txt = 1; dropdown->option_cnt = 0; lv_obj_invalidate(obj); @@ -631,6 +642,27 @@ bool lv_dropdown_is_open(lv_obj_t * obj) return lv_obj_has_flag(dropdown->list, LV_OBJ_FLAG_HIDDEN) ? false : true; } +#if LV_USE_OBSERVER + +lv_observer_t * lv_dropdown_bind_value(lv_obj_t * obj, lv_subject_t * subject) +{ + LV_ASSERT_NULL(subject); + LV_ASSERT_NULL(obj); + + if(subject->type != LV_SUBJECT_TYPE_INT) { + LV_LOG_WARN("Incompatible subject type: %d", subject->type); + return NULL; + } + + lv_obj_add_event_cb(obj, dropdown_value_changed_event_cb, LV_EVENT_VALUE_CHANGED, subject); + + lv_observer_t * observer = lv_subject_add_observer_obj(subject, dropdown_value_observer_cb, obj, NULL); + return observer; +} +#endif /*LV_USE_OBSERVER*/ + + + /********************** * STATIC FUNCTIONS **********************/ @@ -863,6 +895,7 @@ static void draw_main(lv_event_t * e) int32_t left = lv_obj_get_style_pad_left(obj, LV_PART_MAIN) + border_width; int32_t right = lv_obj_get_style_pad_right(obj, LV_PART_MAIN) + border_width; + lv_text_attributes_t attributes = {0}; lv_draw_label_dsc_t symbol_dsc; lv_draw_label_dsc_init(&symbol_dsc); symbol_dsc.base.layer = layer; @@ -881,14 +914,19 @@ static void draw_main(lv_event_t * e) if(dropdown->dir == LV_DIR_LEFT) symbol_to_left = true; if(lv_obj_get_style_base_dir(obj, LV_PART_MAIN) == LV_BASE_DIR_RTL) symbol_to_left = true; + int32_t symbol_w = -1; if(dropdown->symbol) { lv_image_src_t symbol_type = lv_image_src_get_type(dropdown->symbol); - int32_t symbol_w; int32_t symbol_h; if(symbol_type == LV_IMAGE_SRC_SYMBOL) { lv_point_t size; - lv_text_get_size(&size, dropdown->symbol, symbol_dsc.font, symbol_dsc.letter_space, symbol_dsc.line_space, LV_COORD_MAX, - symbol_dsc.flag); + + attributes.letter_space = symbol_dsc.letter_space; + attributes.line_space = symbol_dsc.line_space; + attributes.max_width = LV_COORD_MAX; + attributes.text_flags = symbol_dsc.flag; + + lv_text_get_size_attributes(&size, dropdown->symbol, symbol_dsc.font, &attributes); symbol_w = size.x; symbol_h = size.y; } @@ -937,26 +975,40 @@ static void draw_main(lv_event_t * e) lv_draw_label_dsc_init(&label_dsc); label_dsc.base.layer = layer; lv_obj_init_draw_label_dsc(obj, LV_PART_MAIN, &label_dsc); + label_dsc.flag |= LV_TEXT_FLAG_EXPAND; + + attributes.letter_space = label_dsc.letter_space; + attributes.max_width = LV_COORD_MAX; + attributes.line_space = label_dsc.line_space; + attributes.text_flags = label_dsc.flag; lv_point_t size; - lv_text_get_size(&size, opt_txt, label_dsc.font, label_dsc.letter_space, label_dsc.line_space, LV_COORD_MAX, - label_dsc.flag); + lv_text_get_size_attributes(&size, opt_txt, label_dsc.font, &attributes); lv_area_t txt_area; - txt_area.x1 = obj->coords.x1; - txt_area.x2 = txt_area.x1 + size.x - 1; + txt_area.x1 = obj->coords.x1 + left; + txt_area.x2 = obj->coords.x2 - right; txt_area.y1 = obj->coords.y1; txt_area.y2 = txt_area.y1 + size.y - 1; + lv_area_align(&obj->coords, &txt_area, LV_ALIGN_CENTER, 0, 0); + /*Center align the text if no symbol*/ - if(dropdown->symbol == NULL) { - lv_area_align(&obj->coords, &txt_area, LV_ALIGN_CENTER, 0, 0); + if(dropdown->symbol == NULL && label_dsc.align == LV_TEXT_ALIGN_AUTO) { + label_dsc.align = LV_TEXT_ALIGN_CENTER; } else { + /*Add some space between the label and symbol*/ + symbol_w += lv_obj_get_style_pad_column(obj, LV_PART_MAIN); + /*Text to the right*/ if(symbol_to_left) { + if(label_dsc.align == LV_TEXT_ALIGN_AUTO) label_dsc.align = LV_TEXT_ALIGN_RIGHT; + txt_area.x1 += symbol_w; lv_area_align(&obj->coords, &txt_area, LV_ALIGN_RIGHT_MID, -right, 0); } else { + if(label_dsc.align == LV_TEXT_ALIGN_AUTO) label_dsc.align = LV_TEXT_ALIGN_LEFT; + txt_area.x2 -= symbol_w; lv_area_align(&obj->coords, &txt_area, LV_ALIGN_LEFT_MID, left, 0); } } @@ -1025,6 +1077,7 @@ static void draw_box(lv_obj_t * dropdown_obj, lv_layer_t * layer, uint32_t id, l /*Draw the selected*/ lv_obj_t * label = get_label(dropdown_obj); + LV_ASSERT_NULL(label); lv_area_t rect_area; rect_area.y1 = label->coords.y1; rect_area.y1 += id * (font_h + line_space); @@ -1231,4 +1284,22 @@ static lv_obj_t * get_label(const lv_obj_t * obj) return lv_obj_get_child(dropdown->list, 0); } +#if LV_USE_OBSERVER + +static void dropdown_value_changed_event_cb(lv_event_t * e) +{ + lv_obj_t * dropdown = lv_event_get_current_target(e); + lv_subject_t * subject = lv_event_get_user_data(e); + + lv_subject_set_int(subject, lv_dropdown_get_selected(dropdown)); +} + +static void dropdown_value_observer_cb(lv_observer_t * observer, lv_subject_t * subject) +{ + lv_dropdown_set_selected(observer->target, subject->value.num); +} + +#endif /*LV_USE_OBSERVER*/ + + #endif diff --git a/src/widgets/dropdown/lv_dropdown.h b/src/widgets/dropdown/lv_dropdown.h index c9f55be12f..a65f50d4a6 100644 --- a/src/widgets/dropdown/lv_dropdown.h +++ b/src/widgets/dropdown/lv_dropdown.h @@ -32,7 +32,7 @@ extern "C" { LV_EXPORT_CONST_INT(LV_DROPDOWN_POS_LAST); #if LV_USE_OBJ_PROPERTY -enum { +enum _lv_property_dropdown_id_t { LV_PROPERTY_ID(DROPDOWN, TEXT, LV_PROPERTY_TYPE_TEXT, 0), LV_PROPERTY_ID(DROPDOWN, OPTIONS, LV_PROPERTY_TYPE_TEXT, 1), LV_PROPERTY_ID(DROPDOWN, OPTION_COUNT, LV_PROPERTY_TYPE_INT, 2), @@ -233,6 +233,17 @@ void lv_dropdown_close(lv_obj_t * obj); */ bool lv_dropdown_is_open(lv_obj_t * obj); + +#if LV_USE_OBSERVER +/** + * Bind an integer Subject to a Dropdown's value. + * @param obj pointer to Dropdown + * @param subject pointer to Subject + * @return pointer to newly-created Observer + */ +lv_observer_t * lv_dropdown_bind_value(lv_obj_t * obj, lv_subject_t * subject); +#endif + /********************** * MACROS **********************/ diff --git a/src/widgets/image/lv_image.c b/src/widgets/image/lv_image.c index 3dde44ca7e..62b0d0125c 100644 --- a/src/widgets/image/lv_image.c +++ b/src/widgets/image/lv_image.c @@ -1,5 +1,5 @@ /** - * @file lv_img.c + * @file lv_image.c * */ @@ -8,12 +8,14 @@ *********************/ #include "lv_image_private.h" #include "../../misc/lv_area_private.h" +#include "../../misc/lv_text_private.h" #include "../../draw/lv_draw_image_private.h" #include "../../draw/lv_draw_private.h" #include "../../core/lv_obj_event_private.h" #include "../../core/lv_obj_class_private.h" -#include "../../core/lv_obj_class_private.h" #include "../../core/lv_obj_draw_private.h" +#include "../../core/lv_obj_class_private.h" +#include "../../others/observer/lv_observer_private.h" #if LV_USE_IMAGE != 0 @@ -37,6 +39,12 @@ static void lv_image_event(const lv_obj_class_t * class_p, lv_event_t * e); static void draw_image(lv_event_t * e); static void scale_update(lv_obj_t * obj, int32_t scale_x, int32_t scale_y); static void update_align(lv_obj_t * obj); +static void reset_image_attributes(lv_obj_t * obj); + +#if LV_USE_OBSERVER + static void image_src_observer_cb(lv_observer_t * observer, lv_subject_t * subject); +#endif /*LV_USE_OBSERVER*/ + #if LV_USE_OBJ_PROPERTY static void lv_image_set_pivot_helper(lv_obj_t * obj, lv_point_t * pivot); static lv_point_t lv_image_get_pivot_helper(lv_obj_t * obj); @@ -176,22 +184,20 @@ void lv_image_set_src(lv_obj_t * obj, const void * src) /*If the new source type is unknown free the memories of the old source*/ if(src_type == LV_IMAGE_SRC_UNKNOWN) { if(src) LV_LOG_WARN("unknown image type"); - if(img->src_type == LV_IMAGE_SRC_SYMBOL || img->src_type == LV_IMAGE_SRC_FILE) { - lv_free((void *)img->src); - } - img->src = NULL; - img->src_type = LV_IMAGE_SRC_UNKNOWN; + reset_image_attributes(obj); return; } lv_image_header_t header; lv_result_t res = lv_image_decoder_get_info(src, &header); if(res != LV_RESULT_OK) { -#if LV_USE_LOG - char buf[24]; - LV_LOG_WARN("failed to get image info: %s", - src_type == LV_IMAGE_SRC_FILE ? (const char *)src : (lv_snprintf(buf, sizeof(buf), "%p", src), buf)); -#endif /*LV_USE_LOG*/ + if(src_type == LV_IMAGE_SRC_FILE) { + LV_LOG_WARN("failed to get image info: %s", (const char *)src); + } + else { + LV_LOG_WARN("failed to get image info: %p", src); + } + reset_image_attributes(obj); return; } @@ -234,10 +240,15 @@ void lv_image_set_src(lv_obj_t * obj, const void * src) if(src_type == LV_IMAGE_SRC_SYMBOL) { /*`lv_image_dsc_get_info` couldn't set the width and height of a font so set it here*/ const lv_font_t * font = lv_obj_get_style_text_font(obj, LV_PART_MAIN); - int32_t letter_space = lv_obj_get_style_text_letter_space(obj, LV_PART_MAIN); - int32_t line_space = lv_obj_get_style_text_line_space(obj, LV_PART_MAIN); + lv_text_attributes_t attributes = {0}; + + attributes.letter_space = lv_obj_get_style_text_letter_space(obj, LV_PART_MAIN); + attributes.line_space = lv_obj_get_style_text_line_space(obj, LV_PART_MAIN); + attributes.max_width = LV_COORD_MAX; + attributes.text_flags = LV_TEXT_FLAG_NONE; + lv_point_t size; - lv_text_get_size(&size, src, font, letter_space, line_space, LV_COORD_MAX, LV_TEXT_FLAG_NONE); + lv_text_get_size_attributes(&size, src, font, &attributes); header.w = size.x; header.h = size.y; } @@ -284,7 +295,7 @@ void lv_image_set_rotation(lv_obj_t * obj, int32_t angle) LV_ASSERT_OBJ(obj, MY_CLASS); lv_image_t * img = (lv_image_t *)obj; - if(img->align > LV_IMAGE_ALIGN_AUTO_TRANSFORM) { + if(img->align > _LV_IMAGE_ALIGN_AUTO_TRANSFORM) { angle = 0; } else { @@ -329,7 +340,7 @@ void lv_image_set_pivot(lv_obj_t * obj, int32_t x, int32_t y) LV_ASSERT_OBJ(obj, MY_CLASS); lv_image_t * img = (lv_image_t *)obj; - if(img->align > LV_IMAGE_ALIGN_AUTO_TRANSFORM) { + if(img->align > _LV_IMAGE_ALIGN_AUTO_TRANSFORM) { x = 0; y = 0; } @@ -367,6 +378,22 @@ void lv_image_set_pivot(lv_obj_t * obj, int32_t x, int32_t y) lv_obj_invalidate_area(obj, &a); } +void lv_image_set_pivot_x(lv_obj_t * obj, int32_t x) +{ + LV_ASSERT_OBJ(obj, MY_CLASS); + + lv_image_t * img = (lv_image_t *)obj; + lv_image_set_pivot(obj, x, img->pivot.y); +} + +void lv_image_set_pivot_y(lv_obj_t * obj, int32_t y) +{ + LV_ASSERT_OBJ(obj, MY_CLASS); + + lv_image_t * img = (lv_image_t *)obj; + lv_image_set_pivot(obj, img->pivot.x, y); +} + void lv_image_set_scale(lv_obj_t * obj, uint32_t zoom) { LV_ASSERT_OBJ(obj, MY_CLASS); @@ -374,7 +401,7 @@ void lv_image_set_scale(lv_obj_t * obj, uint32_t zoom) lv_image_t * img = (lv_image_t *)obj; /*If scale is set internally, do no overwrite it*/ - if(img->align > LV_IMAGE_ALIGN_AUTO_TRANSFORM) return; + if(img->align > _LV_IMAGE_ALIGN_AUTO_TRANSFORM) return; if(zoom == img->scale_x && zoom == img->scale_y) return; @@ -390,7 +417,7 @@ void lv_image_set_scale_x(lv_obj_t * obj, uint32_t zoom) lv_image_t * img = (lv_image_t *)obj; /*If scale is set internally, do no overwrite it*/ - if(img->align > LV_IMAGE_ALIGN_AUTO_TRANSFORM) return; + if(img->align > _LV_IMAGE_ALIGN_AUTO_TRANSFORM) return; if(zoom == img->scale_x) return; @@ -406,7 +433,7 @@ void lv_image_set_scale_y(lv_obj_t * obj, uint32_t zoom) lv_image_t * img = (lv_image_t *)obj; /*If scale is set internally, do no overwrite it*/ - if(img->align > LV_IMAGE_ALIGN_AUTO_TRANSFORM) return; + if(img->align > _LV_IMAGE_ALIGN_AUTO_TRANSFORM) return; if(zoom == img->scale_y) return; @@ -632,6 +659,24 @@ const lv_image_dsc_t * lv_image_get_bitmap_map_src(lv_obj_t * obj) return img->bitmap_mask_src; } + +#if LV_USE_OBSERVER +lv_observer_t * lv_image_bind_src(lv_obj_t * obj, lv_subject_t * subject) +{ + LV_ASSERT_NULL(subject); + LV_ASSERT_OBJ(obj, MY_CLASS); + + if(subject->type != LV_SUBJECT_TYPE_POINTER) { + LV_LOG_WARN("Incompatible subject type: %d", subject->type); + return NULL; + } + + lv_observer_t * observer = lv_subject_add_observer_obj(subject, image_src_observer_cb, obj, NULL); + return observer; +} +#endif /*LV_USE_OBSERVER*/ + + /********************** * STATIC FUNCTIONS **********************/ @@ -820,6 +865,11 @@ static void draw_image(lv_event_t * e) if(img->h == 0 || img->w == 0) return; if(img->scale_x == 0 || img->scale_y == 0) return; + if(img->src == NULL) { + /*Do not need to draw image when src is NULL*/ + LV_LOG_TRACE("image source is NULL"); + return; + } lv_layer_t * layer = lv_event_get_layer(e); @@ -848,7 +898,7 @@ static void draw_image(lv_event_t * e) draw_dsc.clip_radius = lv_obj_get_style_radius(obj, LV_PART_MAIN); lv_area_t coords; - if(img->align < LV_IMAGE_ALIGN_AUTO_TRANSFORM) { + if(img->align < _LV_IMAGE_ALIGN_AUTO_TRANSFORM) { lv_area_align(&obj->coords, &draw_dsc.image_area, img->align, img->offset.x, img->offset.y); coords = draw_dsc.image_area; } @@ -891,11 +941,17 @@ static void draw_image(lv_event_t * e) const bool needs_inner_alignment = img->align > LV_IMAGE_ALIGN_TOP_LEFT && !image_area_is_same_as_coords; const bool has_offset = img->offset.x || img->offset.y; - const bool inner_alignment_is_transforming = img->align >= LV_IMAGE_ALIGN_AUTO_TRANSFORM; + const bool inner_alignment_is_transforming = img->align >= _LV_IMAGE_ALIGN_AUTO_TRANSFORM; if((needs_inner_alignment || has_offset) && !inner_alignment_is_transforming) { lv_point_t text_size; - lv_text_get_size(&text_size, label_dsc.text, label_dsc.font, label_dsc.letter_space, - label_dsc.line_space, LV_COORD_MAX, LV_TEXT_FLAG_NONE); + + lv_text_attributes_t attributes; + attributes.letter_space = label_dsc.letter_space; + attributes.line_space = label_dsc.line_space; + attributes.max_width = LV_COORD_MAX; + attributes.text_flags = LV_TEXT_FLAG_NONE; + + lv_text_get_size_attributes(&text_size, label_dsc.text, label_dsc.font, &attributes); lv_area_set(&aligned_coords, 0, 0, text_size.x, text_size.y); lv_area_align(&obj->coords, &aligned_coords, img->align, img->offset.x, img->offset.y); coords = &aligned_coords; @@ -905,10 +961,6 @@ static void draw_image(lv_event_t * e) } lv_draw_label(layer, &label_dsc, coords); } - else if(img->src == NULL) { - /*Do not need to draw image when src is NULL*/ - LV_LOG_WARN("image source is NULL"); - } else { /*Trigger the error handler of image draw*/ LV_LOG_WARN("image source type is unknown"); @@ -993,6 +1045,32 @@ static void update_align(lv_obj_t * obj) } } +static void reset_image_attributes(lv_obj_t * obj) +{ + lv_image_t * img = (lv_image_t *)obj; + if(img->src_type == LV_IMAGE_SRC_SYMBOL || img->src_type == LV_IMAGE_SRC_FILE) { + lv_free((void *)img->src); + } + img->src = NULL; + img->src_type = LV_IMAGE_SRC_UNKNOWN; + img->w = 0; + img->h = 0; + img->cf = LV_COLOR_FORMAT_UNKNOWN; + lv_obj_refresh_self_size(obj); +} + + +#if LV_USE_OBSERVER + +static void image_src_observer_cb(lv_observer_t * observer, lv_subject_t * subject) +{ + if(subject->type == LV_SUBJECT_TYPE_POINTER) { + lv_image_set_src(observer->target, subject->value.pointer); + } +} + +#endif /*LV_USE_OBSERVER*/ + #if LV_USE_OBJ_PROPERTY static void lv_image_set_pivot_helper(lv_obj_t * obj, lv_point_t * pivot) { @@ -1007,4 +1085,5 @@ static lv_point_t lv_image_get_pivot_helper(lv_obj_t * obj) } #endif + #endif diff --git a/src/widgets/image/lv_image.h b/src/widgets/image/lv_image.h index 39cde0c9d8..9ee3e37284 100644 --- a/src/widgets/image/lv_image.h +++ b/src/widgets/image/lv_image.h @@ -25,6 +25,7 @@ extern "C" { #include "../../core/lv_obj.h" #include "../../misc/lv_fs.h" #include "../../draw/lv_draw.h" +#include "../../others/observer/lv_observer.h" /********************* * DEFINES @@ -50,15 +51,15 @@ typedef enum { LV_IMAGE_ALIGN_LEFT_MID, LV_IMAGE_ALIGN_RIGHT_MID, LV_IMAGE_ALIGN_CENTER, - LV_IMAGE_ALIGN_AUTO_TRANSFORM, - LV_IMAGE_ALIGN_STRETCH, /* Set X and Y scale to fill the Widget's area. */ - LV_IMAGE_ALIGN_TILE, /* Tile image to fill Widget's area. Offset is applied to shift the tiling. */ - LV_IMAGE_ALIGN_CONTAIN, /* The image keeps its aspect ratio, but is resized to the maximum size that fits within the Widget's area. */ - LV_IMAGE_ALIGN_COVER, /* The image keeps its aspect ratio and fills the Widget's area. */ + _LV_IMAGE_ALIGN_AUTO_TRANSFORM, /**< Marks the start of modes that transform the image*/ + LV_IMAGE_ALIGN_STRETCH, /**< Set X and Y scale to fill the Widget's area. */ + LV_IMAGE_ALIGN_TILE, /**< Tile image to fill Widget's area. Offset is applied to shift the tiling. */ + LV_IMAGE_ALIGN_CONTAIN, /**< The image keeps its aspect ratio, but is resized to the maximum size that fits within the Widget's area. */ + LV_IMAGE_ALIGN_COVER, /**< The image keeps its aspect ratio and fills the Widget's area. */ } lv_image_align_t; #if LV_USE_OBJ_PROPERTY -enum { +enum _lv_property_image_id_t { LV_PROPERTY_ID(IMAGE, SRC, LV_PROPERTY_TYPE_IMGSRC, 0), LV_PROPERTY_ID(IMAGE, OFFSET_X, LV_PROPERTY_TYPE_INT, 1), LV_PROPERTY_ID(IMAGE, OFFSET_Y, LV_PROPERTY_TYPE_INT, 2), @@ -135,12 +136,26 @@ void lv_image_set_rotation(lv_obj_t * obj, int32_t angle); */ void lv_image_set_pivot(lv_obj_t * obj, int32_t x, int32_t y); +/** + * Set the rotation horizontal center of the image. + * @param obj pointer to an image object + * @param x rotation center x of the image, or lv_pct() + */ +void lv_image_set_pivot_x(lv_obj_t * obj, int32_t x); + +/** + * Set the rotation vertical center of the image. + * @param obj pointer to an image object + * @param y rotation center y of the image, or lv_pct() + */ +void lv_image_set_pivot_y(lv_obj_t * obj, int32_t y); + /** * Set the zoom factor of the image. * Note that indexed and alpha only images can't be transformed. * @param obj pointer to an image object * @param zoom the zoom factor. Example values: - * - 256 or LV_ZOOM_IMAGE_NONE: no zoom + * - 256 or LV_SCALE_NONE: no zoom * - <256: scale down * - >256: scale up * - 128: half size @@ -153,7 +168,7 @@ void lv_image_set_scale(lv_obj_t * obj, uint32_t zoom); * Note that indexed and alpha only images can't be transformed. * @param obj pointer to an image object * @param zoom the zoom factor. Example values: - * - 256 or LV_ZOOM_IMAGE_NONE: no zoom + * - 256 or LV_SCALE_NONE: no zoom * - <256: scale down * - >256: scale up * - 128: half size @@ -166,7 +181,7 @@ void lv_image_set_scale_x(lv_obj_t * obj, uint32_t zoom); * Note that indexed and alpha only images can't be transformed. * @param obj pointer to an image object * @param zoom the zoom factor. Example values: - * - 256 or LV_ZOOM_IMAGE_NONE: no zoom + * - 256 or LV_SCALE_NONE: no zoom * - <256: scale down * - >256: scale up * - 128: half size @@ -324,6 +339,17 @@ lv_image_align_t lv_image_get_inner_align(lv_obj_t * obj); */ const lv_image_dsc_t * lv_image_get_bitmap_map_src(lv_obj_t * obj); + +#if LV_USE_OBSERVER +/** + * Bind a pointer Subject to an Image's source. + * @param obj pointer to Image + * @param subject pointer to Subject + * @return pointer to newly-created Observer + */ +lv_observer_t * lv_image_bind_src(lv_obj_t * obj, lv_subject_t * subject); +#endif + /********************** * MACROS **********************/ diff --git a/src/widgets/keyboard/lv_keyboard.c b/src/widgets/keyboard/lv_keyboard.c index 64bb09e473..ab28df4838 100644 --- a/src/widgets/keyboard/lv_keyboard.c +++ b/src/widgets/keyboard/lv_keyboard.c @@ -15,6 +15,15 @@ #include "../../misc/lv_assert.h" #include "../../stdlib/lv_string.h" +/*Testing of dependencies*/ +#if LV_USE_BUTTONMATRIX == 0 + #error "lv_buttonmatrix is required. Enable it in lv_conf.h (LV_USE_BUTTONMATRIX 1) " +#endif + +#if LV_USE_TEXTAREA == 0 + #error "lv_textarea is required. Enable it in lv_conf.h (LV_USE_TEXTAREA 1) " +#endif + /********************* * DEFINES *********************/ diff --git a/src/widgets/keyboard/lv_keyboard.h b/src/widgets/keyboard/lv_keyboard.h index f177c1844f..85c3532020 100644 --- a/src/widgets/keyboard/lv_keyboard.h +++ b/src/widgets/keyboard/lv_keyboard.h @@ -17,15 +17,6 @@ extern "C" { #if LV_USE_KEYBOARD -/*Testing of dependencies*/ -#if LV_USE_BUTTONMATRIX == 0 -#error "lv_buttonmatrix is required. Enable it in lv_conf.h (LV_USE_BUTTONMATRIX 1) " -#endif - -#if LV_USE_TEXTAREA == 0 -#error "lv_textarea is required. Enable it in lv_conf.h (LV_USE_TEXTAREA 1) " -#endif - /********************* * DEFINES *********************/ @@ -51,7 +42,7 @@ typedef enum { } lv_keyboard_mode_t; #if LV_USE_OBJ_PROPERTY -enum { +enum _lv_property_keyboard_id_t { LV_PROPERTY_ID(KEYBOARD, TEXTAREA, LV_PROPERTY_TYPE_OBJ, 0), LV_PROPERTY_ID(KEYBOARD, MODE, LV_PROPERTY_TYPE_INT, 1), LV_PROPERTY_ID(KEYBOARD, POPOVERS, LV_PROPERTY_TYPE_INT, 2), @@ -69,7 +60,7 @@ LV_ATTRIBUTE_EXTERN_DATA extern const lv_obj_class_t lv_keyboard_class; /** * Create a Keyboard object * @param parent pointer to an object, it will be the parent of the new keyboard - * @return pointer to the created keyboard + * @return pointer to the created keyboard object */ lv_obj_t * lv_keyboard_create(lv_obj_t * parent); @@ -78,33 +69,33 @@ lv_obj_t * lv_keyboard_create(lv_obj_t * parent); *====================*/ /** - * Assign a Text Area to the Keyboard. The pressed characters will be put there. - * @param kb pointer to a Keyboard object - * @param ta pointer to a Text Area object to write there + * Assign a text area to the keyboard. Pressed characters will be inserted there. + * @param kb pointer to a keyboard object + * @param ta pointer to a text area object to write into */ void lv_keyboard_set_textarea(lv_obj_t * kb, lv_obj_t * ta); /** - * Set a new a mode (text or number map) - * @param kb pointer to a Keyboard object - * @param mode the mode from 'lv_keyboard_mode_t' + * Set a new mode (e.g., text, number, special characters). + * @param kb pointer to a keyboard object + * @param mode the desired mode (see 'lv_keyboard_mode_t') */ void lv_keyboard_set_mode(lv_obj_t * kb, lv_keyboard_mode_t mode); /** - * Show the button title in a popover when pressed. - * @param kb pointer to a Keyboard object - * @param en whether "popovers" mode is enabled + * Enable or disable popovers showing button titles on press. + * @param kb pointer to a keyboard object + * @param en true to enable popovers; false to disable */ void lv_keyboard_set_popovers(lv_obj_t * kb, bool en); /** - * Set a new map for the keyboard - * @param kb pointer to a Keyboard object - * @param mode keyboard map to alter 'lv_keyboard_mode_t' - * @param map pointer to a string array to describe the map. - * See 'lv_buttonmatrix_set_map()' for more info. - * @param ctrl_map See 'lv_buttonmatrix_set_ctrl_map()' for more info. + * Set a custom button map for the keyboard. + * @param kb pointer to a keyboard object + * @param mode the mode to assign the new map to (see 'lv_keyboard_mode_t') + * @param map pointer to a string array describing the button map + * see 'lv_buttonmatrix_set_map()' for more details + * @param ctrl_map pointer to the control map. See 'lv_buttonmatrix_set_ctrl_map()' */ void lv_keyboard_set_map(lv_obj_t * kb, lv_keyboard_mode_t mode, const char * const map[], @@ -115,46 +106,47 @@ void lv_keyboard_set_map(lv_obj_t * kb, lv_keyboard_mode_t mode, const char * co *====================*/ /** - * Assign a Text Area to the Keyboard. The pressed characters will be put there. - * @param kb pointer to a Keyboard object - * @return pointer to the assigned Text Area object + * Get the text area currently assigned to the keyboard. + * @param kb pointer to a keyboard object + * @return pointer to the assigned text area object */ lv_obj_t * lv_keyboard_get_textarea(const lv_obj_t * kb); /** - * Set a new a mode (text or number map) - * @param kb pointer to a Keyboard object - * @return the current mode from 'lv_keyboard_mode_t' + * Get the current mode of the keyboard. + * @param kb pointer to a keyboard object + * @return the current mode (see 'lv_keyboard_mode_t') */ lv_keyboard_mode_t lv_keyboard_get_mode(const lv_obj_t * kb); /** - * Tell whether "popovers" mode is enabled or not. - * @param obj pointer to a Keyboard object - * @return true: "popovers" mode is enabled; false: disabled + * Check whether popovers are enabled on the keyboard. + * @param obj pointer to a keyboard object + * @return true if popovers are enabled; false otherwise */ bool lv_keyboard_get_popovers(const lv_obj_t * obj); /** - * Get the current map of a keyboard + * Get the current button map of the keyboard. * @param kb pointer to a keyboard object - * @return the current map + * @return pointer to the map array */ const char * const * lv_keyboard_get_map_array(const lv_obj_t * kb); /** - * Get the index of the lastly "activated" button by the user (pressed, released, focused etc) - * Useful in the `event_cb` to get the text of the button, check if hidden etc. - * @param obj pointer to button matrix object - * @return index of the last released button (LV_BUTTONMATRIX_BUTTON_NONE: if unset) + * Get the index of the last selected button (pressed, released, focused, etc.). + * Useful in the `event_cb` to retrieve button text or properties. + * @param obj pointer to a keyboard object + * @return index of the last interacted button + * returns LV_BUTTONMATRIX_BUTTON_NONE if not set */ uint32_t lv_keyboard_get_selected_button(const lv_obj_t * obj); /** - * Get the button's text - * @param obj pointer to button matrix object - * @param btn_id the index a button not counting new line characters. - * @return text of btn_index` button + * Get the text of a button by index. + * @param obj pointer to a keyboard object + * @param btn_id index of the button (excluding newline characters) + * @return pointer to the text of the button */ const char * lv_keyboard_get_button_text(const lv_obj_t * obj, uint32_t btn_id); @@ -163,10 +155,10 @@ const char * lv_keyboard_get_button_text(const lv_obj_t * obj, uint32_t btn_id); *====================*/ /** - * Default keyboard event to add characters to the Text area and change the map. - * If a custom `event_cb` is added to the keyboard this function can be called from it to handle the - * button clicks - * @param e the triggering event + * Default keyboard event callback to handle button presses. + * Adds characters to the text area and switches map if needed. + * If a custom `event_cb` is used, this function can be called within it. + * @param e the triggering event */ void lv_keyboard_def_event_cb(lv_event_t * e); diff --git a/src/widgets/label/lv_label.c b/src/widgets/label/lv_label.c index 8fa790ab56..dd83228000 100644 --- a/src/widgets/label/lv_label.c +++ b/src/widgets/label/lv_label.c @@ -24,6 +24,8 @@ #include "../../misc/lv_text_private.h" #include "../../stdlib/lv_sprintf.h" #include "../../stdlib/lv_string.h" +#include "../../others/observer/lv_observer_private.h" +#include "../../others/translation/lv_translation.h" /********************* * DEFINES @@ -47,6 +49,8 @@ static void lv_label_destructor(const lv_obj_class_t * class_p, lv_obj_t * obj); static void lv_label_event(const lv_obj_class_t * class_p, lv_event_t * e); static void draw_main(lv_event_t * e); +static void set_text_internal(lv_obj_t * obj, const char * text); +static void remove_translation_tag(lv_obj_t * obj); static void lv_label_refr_text(lv_obj_t * obj); static void lv_label_revert_dots(lv_obj_t * label); static void lv_label_set_dots(lv_obj_t * label, uint32_t dot_begin); @@ -57,7 +61,11 @@ static size_t get_text_length(const char * text); static void copy_text_to_label(lv_label_t * label, const char * text); static lv_text_flag_t get_label_flags(lv_label_t * label); static void calculate_x_coordinate(int32_t * x, const lv_text_align_t align, const char * txt, - uint32_t length, const lv_font_t * font, int32_t letter_space, lv_area_t * txt_coords, lv_text_flag_t flags); + uint32_t length, const lv_font_t * font, lv_area_t * txt_coords, lv_text_attributes_t * attributes); + +#if LV_USE_OBSERVER + static void label_text_observer_cb(lv_observer_t * observer, lv_subject_t * subject); +#endif /********************** * STATIC VARIABLES @@ -133,53 +141,29 @@ lv_obj_t * lv_label_create(lv_obj_t * parent) void lv_label_set_text(lv_obj_t * obj, const char * text) { LV_ASSERT_OBJ(obj, MY_CLASS); - lv_label_t * label = (lv_label_t *)obj; - - /*If text is NULL then just refresh with the current text*/ - if(text == NULL) text = label->text; - - lv_label_revert_dots(obj); /*In case text == label->text*/ - const size_t text_len = get_text_length(text); - - /*If set its own text then reallocate it (maybe its size changed)*/ - if(label->text == text && label->static_txt == 0) { - label->text = lv_realloc(label->text, text_len); - LV_ASSERT_MALLOC(label->text); - if(label->text == NULL) return; - -#if LV_USE_ARABIC_PERSIAN_CHARS - lv_text_ap_proc(label->text, label->text); -#endif - - } - else { - /*Free the old text*/ - if(label->text != NULL && label->static_txt == 0) { - lv_free(label->text); - label->text = NULL; - } - - label->text = lv_malloc(text_len); - LV_ASSERT_MALLOC(label->text); - if(label->text == NULL) return; - - copy_text_to_label(label, text); - - /*Now the text is dynamically allocated*/ - label->static_txt = 0; - } - - lv_label_refr_text(obj); + remove_translation_tag(obj); + set_text_internal(obj, text); } void lv_label_set_text_fmt(lv_obj_t * obj, const char * fmt, ...) +{ + va_list args; + va_start(args, fmt); + lv_label_set_text_vfmt(obj, fmt, args); + va_end(args); +} + +void lv_label_set_text_vfmt(lv_obj_t * obj, const char * fmt, va_list args) { LV_ASSERT_OBJ(obj, MY_CLASS); LV_ASSERT_NULL(fmt); + remove_translation_tag(obj); lv_obj_invalidate(obj); lv_label_t * label = (lv_label_t *)obj; + lv_label_revert_dots(obj); + /*If text is NULL then refresh*/ if(fmt == NULL) { lv_label_refr_text(obj); @@ -191,10 +175,7 @@ void lv_label_set_text_fmt(lv_obj_t * obj, const char * fmt, ...) label->text = NULL; } - va_list args; - va_start(args, fmt); label->text = lv_text_set_text_vfmt(fmt, args); - va_end(args); label->static_txt = 0; /*Now the text is dynamically allocated*/ lv_label_refr_text(obj); @@ -205,6 +186,7 @@ void lv_label_set_text_static(lv_obj_t * obj, const char * text) LV_ASSERT_OBJ(obj, MY_CLASS); lv_label_t * label = (lv_label_t *)obj; + remove_translation_tag(obj); if(label->static_txt == 0 && label->text != NULL) { lv_free(label->text); label->text = NULL; @@ -218,6 +200,28 @@ void lv_label_set_text_static(lv_obj_t * obj, const char * text) lv_label_refr_text(obj); } +#if LV_USE_TRANSLATION +void lv_label_set_translation_tag(lv_obj_t * obj, const char * tag) +{ + LV_ASSERT_OBJ(obj, MY_CLASS); + lv_label_t * label = (lv_label_t *)obj; + if(!tag || tag[0] == '\0') { + return; + } + char * new_tag = lv_strdup(tag); + LV_ASSERT_MALLOC(new_tag); + if(!new_tag) { + LV_LOG_WARN("Failed to allocate memory for new tag"); + return; + } + if(label->translation_tag) { + lv_free(label->translation_tag); + } + label->translation_tag = new_tag; + set_text_internal(obj, lv_tr(tag)); +} +#endif /*LV_USE_TRANSLATION*/ + void lv_label_set_long_mode(lv_obj_t * obj, lv_label_long_mode_t long_mode) { LV_ASSERT_OBJ(obj, MY_CLASS); @@ -326,40 +330,43 @@ void lv_label_get_letter_pos(const lv_obj_t * obj, uint32_t char_id, lv_point_t return; } - lv_text_flag_t flag = get_label_flags(label); const uint32_t byte_id = lv_text_encoded_get_byte_id(txt, char_id); /*Search the line of the index letter*/ - const int32_t line_space = lv_obj_get_style_text_line_space(obj, LV_PART_MAIN); - const int32_t letter_space = lv_obj_get_style_text_letter_space(obj, LV_PART_MAIN); + lv_text_attributes_t attributes = {0}; + attributes.text_flags = get_label_flags(label); + attributes.line_space = lv_obj_get_style_text_line_space(obj, LV_PART_MAIN); + attributes.letter_space = lv_obj_get_style_text_letter_space(obj, LV_PART_MAIN); const lv_font_t * font = lv_obj_get_style_text_font(obj, LV_PART_MAIN); const int32_t letter_height = lv_font_get_line_height(font); lv_area_t txt_coords; lv_obj_get_content_coords(obj, &txt_coords); - const int32_t max_w = lv_area_get_width(&txt_coords); const int32_t max_h = lv_area_get_height(&txt_coords); + attributes.max_width = lv_area_get_width(&txt_coords); + int32_t y = 0; uint32_t line_start = 0; uint32_t new_line_start = 0; while(txt[new_line_start] != '\0') { - bool last_line = y + letter_height + line_space + letter_height > max_h; - if(last_line && label->long_mode == LV_LABEL_LONG_MODE_DOTS) flag |= LV_TEXT_FLAG_BREAK_ALL; + bool last_line = y + letter_height + attributes.line_space + letter_height > max_h; + if(last_line && label->long_mode == LV_LABEL_LONG_MODE_DOTS) attributes.text_flags |= LV_TEXT_FLAG_BREAK_ALL; + + new_line_start += lv_text_get_next_line(&txt[line_start], LV_TEXT_LEN_MAX, font, NULL, &attributes); - new_line_start += lv_text_get_next_line(&txt[line_start], LV_TEXT_LEN_MAX, font, letter_space, max_w, NULL, flag); if(byte_id < new_line_start || txt[new_line_start] == '\0') break; /*The line of 'index' letter begins at 'line_start'*/ - y += letter_height + line_space; + y += letter_height + attributes.line_space; line_start = new_line_start; } /*If the last character is line break then go to the next line*/ if(byte_id > 0) { if((txt[byte_id - 1] == '\n' || txt[byte_id - 1] == '\r') && txt[byte_id] == '\0') { - y += letter_height + line_space; + y += letter_height + attributes.line_space; line_start = byte_id; } } @@ -393,11 +400,11 @@ void lv_label_get_letter_pos(const lv_obj_t * obj, uint32_t char_id, lv_point_t #endif /*Calculate the x coordinate*/ - int32_t x = lv_text_get_width_with_flags(bidi_txt, visual_byte_pos, font, letter_space, flag); - if(char_id != line_start) x += letter_space; + int32_t x = lv_text_get_width(bidi_txt, visual_byte_pos, font, &attributes); + if(char_id != line_start) x += attributes.letter_space; uint32_t length = new_line_start - line_start; - calculate_x_coordinate(&x, align, bidi_txt, length, font, letter_space, &txt_coords, flag); + calculate_x_coordinate(&x, align, bidi_txt, length, font, &txt_coords, &attributes); pos->x = x; pos->y = y; @@ -422,25 +429,25 @@ uint32_t lv_label_get_letter_on(const lv_obj_t * obj, lv_point_t * pos_in, bool const char * txt = lv_label_get_text(obj); uint32_t line_start = 0; uint32_t new_line_start = 0; - int32_t max_w = lv_area_get_width(&txt_coords); int32_t max_h = lv_area_get_height(&txt_coords); const lv_font_t * font = lv_obj_get_style_text_font(obj, LV_PART_MAIN); - const int32_t line_space = lv_obj_get_style_text_line_space(obj, LV_PART_MAIN); - const int32_t letter_space = lv_obj_get_style_text_letter_space(obj, LV_PART_MAIN); const int32_t letter_height = lv_font_get_line_height(font); int32_t y = 0; - - lv_text_flag_t flag = get_label_flags(label); + lv_text_attributes_t attributes = {0}; + attributes.letter_space = lv_obj_get_style_text_letter_space(obj, LV_PART_MAIN); + attributes.line_space = lv_obj_get_style_text_line_space(obj, LV_PART_MAIN); + attributes.text_flags = get_label_flags(label); + attributes.max_width = lv_area_get_width(&txt_coords); /*Search the line of the index letter*/; while(txt[line_start] != '\0') { /*If dots will be shown, break the last visible line anywhere, *not only at word boundaries.*/ - bool last_line = y + letter_height + line_space + letter_height > max_h; - if(last_line && label->long_mode == LV_LABEL_LONG_MODE_DOTS) flag |= LV_TEXT_FLAG_BREAK_ALL; + bool last_line = y + letter_height + attributes.line_space + letter_height > max_h; + if(last_line && label->long_mode == LV_LABEL_LONG_MODE_DOTS) attributes.text_flags |= LV_TEXT_FLAG_BREAK_ALL; - new_line_start += lv_text_get_next_line(&txt[line_start], LV_TEXT_LEN_MAX, font, letter_space, max_w, NULL, flag); + new_line_start += lv_text_get_next_line(&txt[line_start], LV_TEXT_LEN_MAX, font, NULL, &attributes); if(pos.y <= y + letter_height) { /*The line is found (stored in 'line_start')*/ @@ -451,7 +458,7 @@ uint32_t lv_label_get_letter_on(const lv_obj_t * obj, lv_point_t * pos_in, bool if(letter != '\n' && txt[new_line_start] == '\0') new_line_start++; break; } - y += letter_height + line_space; + y += letter_height + attributes.line_space; line_start = new_line_start; } @@ -476,7 +483,7 @@ uint32_t lv_label_get_letter_on(const lv_obj_t * obj, lv_point_t * pos_in, bool int32_t x = 0; const lv_text_align_t align = lv_obj_calculate_style_text_align(obj, LV_PART_MAIN, label->text); uint32_t length = new_line_start - line_start; - calculate_x_coordinate(&x, align, bidi_txt, length, font, letter_space, &txt_coords, flag); + calculate_x_coordinate(&x, align, bidi_txt, length, font, &txt_coords, &attributes); lv_text_cmd_state_t cmd_state = LV_TEXT_CMD_STATE_WAIT; @@ -485,13 +492,13 @@ uint32_t lv_label_get_letter_on(const lv_obj_t * obj, lv_point_t * pos_in, bool if(new_line_start > 0) { while(i + line_start < new_line_start) { - /*Get the current letter and the next letter for kerning*/ - /*Be careful 'i' already points to the next character*/ uint32_t letter; uint32_t letter_next; + /*Get the current letter and the next letter for kerning*/ + /*Be careful 'i' already points to the next character*/ lv_text_encoded_letter_next_2(bidi_txt, &letter, &letter_next, &i); - if((flag & LV_TEXT_FLAG_RECOLOR) != 0) { + if((attributes.text_flags & LV_TEXT_FLAG_RECOLOR) != 0) { if(lv_text_is_cmd(&cmd_state, bidi_txt[i]) != false) { continue; /*Skip the letter if it is part of a command*/ } @@ -505,7 +512,7 @@ uint32_t lv_label_get_letter_on(const lv_obj_t * obj, lv_point_t * pos_in, bool break; } x += gw; - x += letter_space; + x += attributes.letter_space; i_act = i; } } @@ -542,29 +549,30 @@ bool lv_label_is_char_under_pos(const lv_obj_t * obj, lv_point_t * pos) lv_area_t txt_coords; lv_obj_get_content_coords(obj, &txt_coords); + lv_text_attributes_t attributes = {0}; const char * txt = lv_label_get_text(obj); lv_label_t * label = (lv_label_t *)obj; uint32_t line_start = 0; uint32_t new_line_start = 0; - const int32_t max_w = lv_area_get_width(&txt_coords); - const int32_t max_h = lv_area_get_height(&txt_coords); const lv_font_t * font = lv_obj_get_style_text_font(obj, LV_PART_MAIN); - const int32_t line_space = lv_obj_get_style_text_line_space(obj, LV_PART_MAIN); - const int32_t letter_space = lv_obj_get_style_text_letter_space(obj, LV_PART_MAIN); const int32_t letter_height = lv_font_get_line_height(font); + const int32_t max_h = lv_area_get_height(&txt_coords); - lv_text_flag_t flag = get_label_flags(label); + attributes.max_width = lv_area_get_width(&txt_coords); + attributes.line_space = lv_obj_get_style_text_line_space(obj, LV_PART_MAIN); + attributes.letter_space = lv_obj_get_style_text_letter_space(obj, LV_PART_MAIN); + attributes.text_flags = get_label_flags(label); /*Search the line of the index letter*/ int32_t y = 0; while(txt[line_start] != '\0') { - bool last_line = y + letter_height + line_space + letter_height > max_h; - if(last_line && label->long_mode == LV_LABEL_LONG_MODE_DOTS) flag |= LV_TEXT_FLAG_BREAK_ALL; + bool last_line = y + letter_height + attributes.line_space + letter_height > max_h; + if(last_line && label->long_mode == LV_LABEL_LONG_MODE_DOTS) attributes.text_flags |= LV_TEXT_FLAG_BREAK_ALL; - new_line_start += lv_text_get_next_line(&txt[line_start], LV_TEXT_LEN_MAX, font, letter_space, max_w, NULL, flag); + new_line_start += lv_text_get_next_line(&txt[line_start], LV_TEXT_LEN_MAX, font, NULL, &attributes); if(pos->y <= y + letter_height) break; /*The line is found (stored in 'line_start')*/ - y += letter_height + line_space; + y += letter_height + attributes.line_space; line_start = new_line_start; } @@ -574,13 +582,11 @@ bool lv_label_is_char_under_pos(const lv_obj_t * obj, lv_point_t * pos) int32_t x = 0; if(align == LV_TEXT_ALIGN_CENTER) { - const int32_t line_w = lv_text_get_width_with_flags(&txt[line_start], new_line_start - line_start, font, letter_space, - flag); + const int32_t line_w = lv_text_get_width(&txt[line_start], new_line_start - line_start, font, &attributes); x += lv_area_get_width(&txt_coords) / 2 - line_w / 2; } else if(align == LV_TEXT_ALIGN_RIGHT) { - const int32_t line_w = lv_text_get_width_with_flags(&txt[line_start], new_line_start - line_start, font, letter_space, - flag); + const int32_t line_w = lv_text_get_width(&txt[line_start], new_line_start - line_start, font, &attributes); x += lv_area_get_width(&txt_coords) - line_w; } @@ -589,7 +595,7 @@ bool lv_label_is_char_under_pos(const lv_obj_t * obj, lv_point_t * pos) int32_t last_x = 0; uint32_t i = line_start; uint32_t i_current = i; - uint32_t letter = '\0'; + uint32_t letter = '\0'; uint32_t letter_next = '\0'; if(new_line_start > 0) { @@ -598,7 +604,7 @@ bool lv_label_is_char_under_pos(const lv_obj_t * obj, lv_point_t * pos) /*Be careful 'i' already points to the next character*/ lv_text_encoded_letter_next_2(txt, &letter, &letter_next, &i); - if((flag & LV_TEXT_FLAG_RECOLOR) != 0) { + if((attributes.text_flags & LV_TEXT_FLAG_RECOLOR) != 0) { if(lv_text_is_cmd(&cmd_state, txt[i]) != false) { continue; /*Skip the letter if it is part of a command*/ } @@ -610,13 +616,13 @@ bool lv_label_is_char_under_pos(const lv_obj_t * obj, lv_point_t * pos) i = i_current; break; } - x += letter_space; + x += attributes.letter_space; i_current = i; } } - const int32_t max_diff = lv_font_get_glyph_width(font, letter, letter_next) + letter_space + 1; - return (pos->x >= (last_x - letter_space) && pos->x <= (last_x + max_diff)); + const int32_t max_diff = lv_font_get_glyph_width(font, letter, letter_next) + attributes.letter_space + 1; + return (pos->x >= (last_x - attributes.letter_space) && pos->x <= (last_x + max_diff)); } uint32_t lv_label_get_text_selection_start(const lv_obj_t * obj) @@ -657,6 +663,40 @@ bool lv_label_get_recolor(const lv_obj_t * obj) * Other functions *====================*/ +#if LV_USE_OBSERVER +lv_observer_t * lv_label_bind_text(lv_obj_t * obj, lv_subject_t * subject, const char * fmt) +{ + LV_ASSERT_NULL(subject); + LV_ASSERT_NULL(obj); + + if(fmt == NULL) { + if(subject->type == LV_SUBJECT_TYPE_INT) { + fmt = "%d"; + } +#if LV_USE_FLOAT + else if(subject->type == LV_SUBJECT_TYPE_FLOAT) { + fmt = "%0.1f"; + } +#endif + else if(subject->type != LV_SUBJECT_TYPE_STRING && subject->type != LV_SUBJECT_TYPE_POINTER) { + LV_LOG_WARN("Incompatible subject type: %d", subject->type); + return NULL; + } + } + else { + if(subject->type != LV_SUBJECT_TYPE_STRING && subject->type != LV_SUBJECT_TYPE_POINTER && + subject->type != LV_SUBJECT_TYPE_INT && subject->type != LV_SUBJECT_TYPE_FLOAT) { + LV_LOG_WARN("Incompatible subject type: %d", subject->type); + return NULL; + } + } + + lv_observer_t * observer = lv_subject_add_observer_obj(subject, label_text_observer_cb, obj, (void *)fmt); + return observer; +} +#endif /*LV_USE_OBSERVER*/ + + void lv_label_ins_text(lv_obj_t * obj, uint32_t pos, const char * txt) { LV_ASSERT_OBJ(obj, MY_CLASS); @@ -703,6 +743,8 @@ void lv_label_cut_text(lv_obj_t * obj, uint32_t pos, uint32_t cnt) lv_label_refr_text(obj); } + + /********************** * STATIC FUNCTIONS **********************/ @@ -746,6 +788,10 @@ static void lv_label_destructor(const lv_obj_class_t * class_p, lv_obj_t * obj) if(!label->static_txt) lv_free(label->text); label->text = NULL; +#if LV_USE_TRANSLATION + if(label->translation_tag) lv_free(label->translation_tag); + label->translation_tag = NULL; +#endif /*LV_USE_TRANSLATION*/ } static void lv_label_event(const lv_obj_class_t * class_p, lv_event_t * e) @@ -789,7 +835,15 @@ static void lv_label_event(const lv_obj_class_t * class_p, lv_event_t * e) uint32_t dot_begin = label->dot_begin; lv_label_revert_dots(obj); - lv_text_get_size(&label->size_cache, label->text, font, letter_space, line_space, w, flag); + + lv_text_attributes_t attributes = {0}; + + attributes.letter_space = letter_space; + attributes.line_space = line_space; + attributes.text_flags = flag; + attributes.max_width = w; + + lv_text_get_size_attributes(&label->size_cache, label->text, font, &attributes); lv_label_set_dots(obj, dot_begin); label->size_cache.y = LV_MIN(label->size_cache.y, lv_obj_get_style_max_height(obj, LV_PART_MAIN)); @@ -803,7 +857,17 @@ static void lv_label_event(const lv_obj_class_t * class_p, lv_event_t * e) } else if(code == LV_EVENT_DRAW_MAIN) { draw_main(e); + } +#if LV_USE_TRANSLATION + else if(code == LV_EVENT_TRANSLATION_LANGUAGE_CHANGED) { + lv_label_t * label = (lv_label_t *)obj; + if(label->translation_tag) { + const char * new_text = lv_tr(label->translation_tag); + set_text_internal(obj, new_text); + } + } +#endif } static void draw_main(lv_event_t * e) @@ -884,7 +948,13 @@ static void draw_main(lv_event_t * e) layer->_clip_area = clip_area_ori; } else { + /*Labels have some extra draw area by default to not clip characters with + *italic, handwritten and other less standard fonts. + *However, with most of the fonts typically it's safe to clip at least to bottom side*/ + const lv_area_t clip_area_ori = layer->_clip_area; + layer->_clip_area.y2 = txt_clip.y2; lv_draw_label(layer, &label_draw_dsc, &txt_coords); + layer->_clip_area = clip_area_ori; } lv_area_t clip_area_ori = layer->_clip_area; @@ -914,6 +984,59 @@ static void draw_main(lv_event_t * e) layer->_clip_area = clip_area_ori; } +static void set_text_internal(lv_obj_t * obj, const char * text) +{ + lv_label_t * label = (lv_label_t *)obj; + + /*If text is NULL then just refresh with the current text*/ + if(text == NULL) text = label->text; + + lv_label_revert_dots(obj); /*In case text == label->text*/ + const size_t text_len = get_text_length(text); + + /*If set its own text then reallocate it (maybe its size changed)*/ + if(label->text == text && label->static_txt == 0) { + label->text = lv_realloc(label->text, text_len); + LV_ASSERT_MALLOC(label->text); + if(label->text == NULL) return; + +#if LV_USE_ARABIC_PERSIAN_CHARS + lv_text_ap_proc(label->text, label->text); +#endif + + } + else { + /*Free the old text*/ + if(label->text != NULL && label->static_txt == 0) { + lv_free(label->text); + label->text = NULL; + } + + label->text = lv_malloc(text_len); + LV_ASSERT_MALLOC(label->text); + if(label->text == NULL) return; + + copy_text_to_label(label, text); + + /*Now the text is dynamically allocated*/ + label->static_txt = 0; + } + + lv_label_refr_text(obj); +} + +static void remove_translation_tag(lv_obj_t * obj) +{ + LV_UNUSED(obj); +#if LV_USE_TRANSLATION + lv_label_t * label = (lv_label_t *)obj; + /* Remove translation tag so we don't update the text automatically if the language changes*/ + if(label->translation_tag) { + lv_free(label->translation_tag); + label->translation_tag = NULL; + } +#endif /*LV_USE_TRANSLATION*/ +} static void overwrite_anim_property(lv_anim_t * dest, const lv_anim_t * src, lv_label_long_mode_t mode) { switch(mode) { @@ -953,18 +1076,19 @@ static void lv_label_refr_text(lv_obj_t * obj) label->invalid_size_cache = true; lv_area_t txt_coords; + lv_text_attributes_t attributes = {0}; lv_obj_get_content_coords(obj, &txt_coords); - int32_t max_w = lv_area_get_width(&txt_coords); const lv_font_t * font = lv_obj_get_style_text_font(obj, LV_PART_MAIN); - int32_t line_space = lv_obj_get_style_text_line_space(obj, LV_PART_MAIN); - int32_t letter_space = lv_obj_get_style_text_letter_space(obj, LV_PART_MAIN); + attributes.line_space = lv_obj_get_style_text_line_space(obj, LV_PART_MAIN); + attributes.letter_space = lv_obj_get_style_text_letter_space(obj, LV_PART_MAIN); + attributes.text_flags = get_label_flags(label); + attributes.max_width = lv_area_get_width(&txt_coords); /*Calc. the height and longest line*/ lv_point_t size; - lv_text_flag_t flag = get_label_flags(label); lv_label_revert_dots(obj); - lv_text_get_size(&size, label->text, font, letter_space, line_space, max_w, flag); + lv_text_get_size_attributes(&size, label->text, font, &attributes); label->text_size = size; lv_obj_refresh_self_size(obj); @@ -1095,6 +1219,7 @@ static void lv_label_refr_text(lv_obj_t * obj) lv_anim_set_repeat_count(&a, LV_ANIM_REPEAT_INFINITE); bool hor_anim = false; + if(size.x > lv_area_get_width(&txt_coords)) { #if LV_USE_BIDI int32_t start, end; @@ -1168,24 +1293,25 @@ static void lv_label_refr_text(lv_obj_t * obj) } } else if(label->long_mode == LV_LABEL_LONG_MODE_DOTS) { + if(size.y > lv_area_get_height(&txt_coords) && /*Text overflows available area*/ size.y > lv_font_get_line_height(font) && /*No break requested, so no dots required*/ lv_text_get_encoded_length(label->text) > LV_LABEL_DOT_NUM) { /*Do not turn all characters into dots*/ lv_point_t p; int32_t y_overed; p.x = lv_area_get_width(&txt_coords) - - (lv_font_get_glyph_width(font, '.', '.') + letter_space) * + (lv_font_get_glyph_width(font, '.', '.') + attributes.letter_space) * LV_LABEL_DOT_NUM; /*Shrink with dots*/ p.y = lv_area_get_height(&txt_coords); y_overed = p.y % - (lv_font_get_line_height(font) + line_space); /*Round down to the last line*/ + (lv_font_get_line_height(font) + attributes.line_space); /*Round down to the last line*/ if(y_overed >= lv_font_get_line_height(font)) { p.y -= y_overed; p.y += lv_font_get_line_height(font); } else { p.y -= y_overed; - p.y -= line_space; + p.y -= attributes.line_space; } uint32_t letter_id = lv_label_get_letter_on(obj, &p, false); @@ -1212,12 +1338,12 @@ static void lv_label_refr_text(lv_obj_t * obj) static void lv_label_revert_dots(lv_obj_t * obj) { lv_label_t * label = (lv_label_t *)obj; - if(label->dot_begin != LV_LABEL_DOT_BEGIN_INV) { + if(label->dot_begin != LV_LABEL_DOT_BEGIN_INV && !label->static_txt) { for(int i = 0; i < LV_LABEL_DOT_NUM + 1 && label->dot[i]; i++) { label->text[label->dot_begin + i] = label->dot[i]; } - label->dot_begin = LV_LABEL_DOT_BEGIN_INV; } + label->dot_begin = LV_LABEL_DOT_BEGIN_INV; } static void lv_label_set_dots(lv_obj_t * obj, uint32_t dot_begin) @@ -1225,9 +1351,15 @@ static void lv_label_set_dots(lv_obj_t * obj, uint32_t dot_begin) lv_label_t * label = (lv_label_t *)obj; LV_ASSERT_MSG(label->dot_begin == LV_LABEL_DOT_BEGIN_INV, "Label dots already set"); if(dot_begin != LV_LABEL_DOT_BEGIN_INV) { + label->dot_begin = dot_begin; + + if(label->static_txt) { + LV_LOG_WARN("Long mode \"dots\" is not supported with static text."); + return; + } + /*Save characters*/ lv_strncpy(label->dot, &label->text[dot_begin], LV_LABEL_DOT_NUM + 1); - label->dot_begin = dot_begin; /*Overwrite up to LV_LABEL_DOT_NUM + 1 characters with dots and null terminator*/ int i = 0; @@ -1292,14 +1424,14 @@ static lv_text_flag_t get_label_flags(lv_label_t * label) /* Function created because of this pattern be used in multiple functions */ static void calculate_x_coordinate(int32_t * x, const lv_text_align_t align, const char * txt, uint32_t length, - const lv_font_t * font, int32_t letter_space, lv_area_t * txt_coords, lv_text_flag_t flags) + const lv_font_t * font, lv_area_t * txt_coords, lv_text_attributes_t * attributes) { if(align == LV_TEXT_ALIGN_CENTER) { - const int32_t line_w = lv_text_get_width_with_flags(txt, length, font, letter_space, flags); + const int32_t line_w = lv_text_get_width(txt, length, font, attributes); *x += lv_area_get_width(txt_coords) / 2 - line_w / 2; } else if(align == LV_TEXT_ALIGN_RIGHT) { - const int32_t line_w = lv_text_get_width_with_flags(txt, length, font, letter_space, flags); + const int32_t line_w = lv_text_get_width(txt, length, font, attributes); *x += lv_area_get_width(txt_coords) - line_w; } else { @@ -1307,4 +1439,34 @@ static void calculate_x_coordinate(int32_t * x, const lv_text_align_t align, con } } +#if LV_USE_OBSERVER + +static void label_text_observer_cb(lv_observer_t * observer, lv_subject_t * subject) +{ + const char * fmt = observer->user_data; + + if(fmt == NULL) { + lv_label_set_text(observer->target, subject->value.pointer); + } + else { + switch(subject->type) { + case LV_SUBJECT_TYPE_INT: + lv_label_set_text_fmt(observer->target, fmt, subject->value.num); + break; +#if LV_USE_FLOAT + case LV_SUBJECT_TYPE_FLOAT: + lv_label_set_text_fmt(observer->target, fmt, subject->value.float_v); + break; +#endif + case LV_SUBJECT_TYPE_STRING: + case LV_SUBJECT_TYPE_POINTER: + lv_label_set_text_fmt(observer->target, fmt, subject->value.pointer); + break; + default: + break; + } + } +} + #endif +#endif /*LV_USE_LABEL*/ diff --git a/src/widgets/label/lv_label.h b/src/widgets/label/lv_label.h index 0cc657622e..6d96d3b9bb 100644 --- a/src/widgets/label/lv_label.h +++ b/src/widgets/label/lv_label.h @@ -23,6 +23,7 @@ extern "C" { #include "../../font/lv_symbol_def.h" #include "../../misc/lv_text.h" #include "../../draw/lv_draw.h" +#include "../../others/observer/lv_observer.h" /********************* * DEFINES @@ -54,7 +55,7 @@ typedef enum { } lv_label_long_mode_t; #if LV_USE_OBJ_PROPERTY -enum { +enum _lv_property_label_id_t { LV_PROPERTY_ID(LABEL, TEXT, LV_PROPERTY_TYPE_TEXT, 0), LV_PROPERTY_ID(LABEL, LONG_MODE, LV_PROPERTY_TYPE_INT, 1), LV_PROPERTY_ID(LABEL, TEXT_SELECTION_START, LV_PROPERTY_TYPE_INT, 2), @@ -84,26 +85,46 @@ lv_obj_t * lv_label_create(lv_obj_t * parent); * Set a new text for a label. Memory will be allocated to store the text by the label. * @param obj pointer to a label object * @param text '\0' terminated character string. NULL to refresh with the current text. + * @note If `LV_USE_ARABIC_PERSIAN_CHARS` is enabled the text will be modified to have the correct Arabic + * characters in it. */ void lv_label_set_text(lv_obj_t * obj, const char * text); /** * Set a new formatted text for a label. Memory will be allocated to store the text by the label. * @param obj pointer to a label object - * @param fmt `printf`-like format - * + * @param fmt `printf`-like format string * Example: * @code * lv_label_set_text_fmt(label1, "%d user", user_num); * @endcode + * @note If `LV_USE_ARABIC_PERSIAN_CHARS` is enabled the text will be modified to have the correct Arabic characters in it. */ void lv_label_set_text_fmt(lv_obj_t * obj, const char * fmt, ...) LV_FORMAT_ATTRIBUTE(2, 3); +/** + * Set a new formatted text for a label. Memory will be allocated to store the text by the label. + * @param obj pointer to a label object + * @param fmt `printf`-like format string + * @param args variadic arguments list + * + * Example: + * @code + * va_list args; + * va_start(args, fmt); + * lv_label_set_text_vfmt(label1, fmt, args); + * va_end(args); + * @endcode + * @note It ignores `LV_USE_ARABIC_PERSIAN_CHARS` + */ +void lv_label_set_text_vfmt(lv_obj_t * obj, const char * fmt, va_list args); + /** * Set a static text. It will not be saved by the label so the 'text' variable * has to be 'alive' while the label exists. * @param obj pointer to a label object * @param text pointer to a text. NULL to refresh with the current text. + * @note It ignores `LV_USE_ARABIC_PERSIAN_CHARS` */ void lv_label_set_text_static(lv_obj_t * obj, const char * text); @@ -137,6 +158,19 @@ void lv_label_set_text_selection_end(lv_obj_t * obj, uint32_t index); */ void lv_label_set_recolor(lv_obj_t * obj, bool en); +#if LV_USE_TRANSLATION + +/** + * Assign a translation tag for this label. Memory will be allocated to store the tag by the label. + * The label text will automatically update when the language is changed via `lv_translation_set_language`. + * @param obj pointer to a label object + * @param tag '\0' terminated character string. + */ +void lv_label_set_translation_tag(lv_obj_t * obj, const char * tag); + +#endif /*LV_USE_TRANSLATION*/ + + /*===================== * Getter functions *====================*/ @@ -207,6 +241,21 @@ bool lv_label_get_recolor(const lv_obj_t * obj); * Other functions *====================*/ +#if LV_USE_OBSERVER +/** + * Bind an integer, string, or pointer Subject to a Label. + * @param obj pointer to Label + * @param subject pointer to Subject + * @param fmt optional printf-like format string with 1 format specifier (e.g. "%d °C") + * or NULL to bind to the value directly. + * @return pointer to newly-created Observer + * @note If `fmt == NULL` strings and pointers (`\0` terminated string) will be shown + * as text as they are, integers as %d, floats as %0.1f + */ +lv_observer_t * lv_label_bind_text(lv_obj_t * obj, lv_subject_t * subject, const char * fmt); +#endif + + /** * Insert a text to a label. The label text cannot be static. * @param obj pointer to a label object @@ -225,6 +274,8 @@ void lv_label_ins_text(lv_obj_t * obj, uint32_t pos, const char * txt); */ void lv_label_cut_text(lv_obj_t * obj, uint32_t pos, uint32_t cnt); + + /********************** * MACROS **********************/ diff --git a/src/widgets/label/lv_label_private.h b/src/widgets/label/lv_label_private.h index 6f1e715bc0..063e8314b6 100644 --- a/src/widgets/label/lv_label_private.h +++ b/src/widgets/label/lv_label_private.h @@ -31,6 +31,9 @@ extern "C" { struct _lv_label_t { lv_obj_t obj; char * text; +#if LV_USE_TRANSLATION + char * translation_tag; +#endif /*LV_USE_TRANSLATION*/ char dot[LV_LABEL_DOT_NUM + 1]; /**< Bytes that have been replaced with dots */ uint32_t dot_begin; /**< Offset where bytes have been replaced with dots */ diff --git a/src/widgets/menu/lv_menu.c b/src/widgets/menu/lv_menu.c index e508c926ef..ba4c6ac913 100644 --- a/src/widgets/menu/lv_menu.c +++ b/src/widgets/menu/lv_menu.c @@ -142,7 +142,13 @@ lv_obj_t * lv_menu_page_create(lv_obj_t * menu, char const * const title) lv_obj_t * lv_menu_cont_create(lv_obj_t * parent) { - LV_ASSERT_OBJ(parent, &lv_menu_page_class); + LV_ASSERT_NULL(parent); + if(!parent || (LV_USE_ASSERT_OBJ && + !(lv_obj_has_class(parent, &lv_menu_page_class) + || lv_obj_has_class(parent, &lv_menu_section_class)))) { + LV_LOG_WARN("Invalid parent object type for menu container object"); + return NULL; + } LV_LOG_INFO("begin"); lv_obj_t * obj = lv_obj_class_create_obj(&lv_menu_cont_class, parent); diff --git a/src/widgets/menu/lv_menu.h b/src/widgets/menu/lv_menu.h index 34edb6c4e5..7d953e1831 100644 --- a/src/widgets/menu/lv_menu.h +++ b/src/widgets/menu/lv_menu.h @@ -73,7 +73,7 @@ lv_obj_t * lv_menu_page_create(lv_obj_t * menu, char const * const title); /** * Create a menu cont object - * @param parent pointer to a menu page object, it will be the parent of the new menu cont object + * @param parent pointer to a menu page or menu section object, it will be the parent of the new menu cont object * @return pointer to the created menu cont */ lv_obj_t * lv_menu_cont_create(lv_obj_t * parent); diff --git a/src/widgets/menu/lv_menu_private.h b/src/widgets/menu/lv_menu_private.h index 12d3059f1a..185d3e9c5a 100644 --- a/src/widgets/menu/lv_menu_private.h +++ b/src/widgets/menu/lv_menu_private.h @@ -57,7 +57,7 @@ struct _lv_menu_t { uint8_t prev_depth; uint8_t sidebar_generated : 1; lv_menu_mode_header_t mode_header : 3; - lv_menu_mode_root_back_button_t mode_root_back_btn : 1; + lv_menu_mode_root_back_button_t mode_root_back_btn : 2; }; struct _lv_menu_page_t { diff --git a/src/widgets/msgbox/lv_msgbox.c b/src/widgets/msgbox/lv_msgbox.c index 3fea09ea26..1713fb9a54 100644 --- a/src/widgets/msgbox/lv_msgbox.c +++ b/src/widgets/msgbox/lv_msgbox.c @@ -12,13 +12,16 @@ #if LV_USE_MSGBOX #include "../label/lv_label.h" -#include "../button/lv_button.h" #include "../image/lv_image.h" #include "../../misc/lv_assert.h" #include "../../display/lv_display.h" #include "../../layouts/flex/lv_flex.h" #include "../../stdlib/lv_string.h" +#if LV_USE_LABEL == 0 + #error "lv_mbox: lv_label is required. Enable it in lv_conf.h (LV_USE_LABEL 1) " +#endif + /********************* * DEFINES *********************/ @@ -127,8 +130,11 @@ lv_obj_t * lv_msgbox_create(lv_obj_t * parent) if(auto_parent) lv_obj_add_flag(obj, LV_MSGBOX_FLAG_AUTO_PARENT); mbox->content = lv_obj_class_create_obj(&lv_msgbox_content_class, obj); - LV_ASSERT_MALLOC(obj); - if(mbox->content == NULL) return NULL; + LV_ASSERT_MALLOC(mbox->content); + if(mbox->content == NULL) { + lv_obj_delete(obj); + return NULL; + } lv_obj_class_init_obj(mbox->content); lv_obj_set_flex_flow(mbox->content, LV_FLEX_FLOW_COLUMN); lv_obj_add_event_cb(obj, msgbox_size_changed_event_cb, LV_EVENT_SIZE_CHANGED, 0); @@ -142,7 +148,7 @@ lv_obj_t * lv_msgbox_add_title(lv_obj_t * obj, const char * title) lv_msgbox_t * mbox = (lv_msgbox_t *)obj; if(mbox->header == NULL) { mbox->header = lv_obj_class_create_obj(&lv_msgbox_header_class, obj); - LV_ASSERT_MALLOC(obj); + LV_ASSERT_MALLOC(mbox->header); if(mbox->header == NULL) return NULL; lv_obj_class_init_obj(mbox->header); @@ -171,7 +177,7 @@ lv_obj_t * lv_msgbox_add_header_button(lv_obj_t * obj, const void * icon) } lv_obj_t * btn = lv_obj_class_create_obj(&lv_msgbox_header_button_class, mbox->header); - LV_ASSERT_MALLOC(obj); + LV_ASSERT_MALLOC(btn); if(btn == NULL) return NULL; lv_obj_class_init_obj(btn); lv_obj_remove_flag(btn, LV_OBJ_FLAG_SCROLLABLE); @@ -201,7 +207,7 @@ lv_obj_t * lv_msgbox_add_footer_button(lv_obj_t * obj, const char * text) lv_msgbox_t * mbox = (lv_msgbox_t *)obj; if(mbox->footer == NULL) { mbox->footer = lv_obj_class_create_obj(&lv_msgbox_footer_class, obj); - LV_ASSERT_MALLOC(obj); + LV_ASSERT_MALLOC(mbox->footer); if(mbox->footer == NULL) return NULL; lv_obj_class_init_obj(mbox->footer); @@ -211,7 +217,7 @@ lv_obj_t * lv_msgbox_add_footer_button(lv_obj_t * obj, const char * text) } lv_obj_t * btn = lv_obj_class_create_obj(&lv_msgbox_footer_button_class, mbox->footer); - LV_ASSERT_MALLOC(obj); + LV_ASSERT_MALLOC(btn); if(btn == NULL) return NULL; lv_obj_class_init_obj(btn); lv_obj_remove_flag(btn, LV_OBJ_FLAG_SCROLLABLE); @@ -287,7 +293,7 @@ static void msgbox_size_changed_event_cb(lv_event_t * e) { lv_obj_t * mbox = lv_event_get_target(e); lv_obj_t * content = lv_msgbox_get_content(mbox); - bool is_msgbox_height_size_content = (lv_obj_get_style_height(mbox, 0) == LV_SIZE_CONTENT); + bool is_msgbox_height_size_content = (lv_obj_get_style_height(mbox, LV_PART_MAIN) == LV_SIZE_CONTENT); lv_obj_set_flex_grow(content, !is_msgbox_height_size_content); } diff --git a/src/widgets/msgbox/lv_msgbox.h b/src/widgets/msgbox/lv_msgbox.h index 5605b80281..683198492c 100644 --- a/src/widgets/msgbox/lv_msgbox.h +++ b/src/widgets/msgbox/lv_msgbox.h @@ -17,15 +17,6 @@ extern "C" { #if LV_USE_MSGBOX -/*Testing of dependencies*/ -#if LV_USE_BUTTONMATRIX == 0 -#error "lv_mbox: lv_buttonmatrix is required. Enable it in lv_conf.h (LV_USE_BUTTONMATRIX 1) " -#endif - -#if LV_USE_LABEL == 0 -#error "lv_mbox: lv_label is required. Enable it in lv_conf.h (LV_USE_LABEL 1) " -#endif - /********************* * DEFINES *********************/ diff --git a/src/widgets/objx_templ/lv_objx_templ.c b/src/widgets/objx_templ/lv_objx_templ.c index 953cc2987a..809d476797 100644 --- a/src/widgets/objx_templ/lv_objx_templ.c +++ b/src/widgets/objx_templ/lv_objx_templ.c @@ -1,5 +1,5 @@ /** - * @file lv_templ.c + * @file lv_objx_templ.c * */ diff --git a/src/widgets/objx_templ/lv_objx_templ.h b/src/widgets/objx_templ/lv_objx_templ.h index ccf1e1c3ec..8feaf7e9b0 100644 --- a/src/widgets/objx_templ/lv_objx_templ.h +++ b/src/widgets/objx_templ/lv_objx_templ.h @@ -1,5 +1,5 @@ /** - * @file lv_templ.h + * @file lv_objx_templ.h * */ @@ -10,8 +10,8 @@ * */ -#ifndef LV_TEMPL_H -#define LV_TEMPL_H +#ifndef LV_OBJX_TEMPL_H +#define LV_OBJX_TEMPL_H #ifdef __cplusplus extern "C" { @@ -78,4 +78,4 @@ lv_obj_t * lv_templ_create(lv_obj_t * parent); } /*extern "C"*/ #endif -#endif /*LV_TEMPL_H*/ +#endif /*LV_OBJX_TEMPL_H*/ diff --git a/src/widgets/property/lv_obj_properties.c b/src/widgets/property/lv_obj_properties.c index 1008b3691a..c6572dfc0d 100644 --- a/src/widgets/property/lv_obj_properties.c +++ b/src/widgets/property/lv_obj_properties.c @@ -14,7 +14,7 @@ * Generated code from properties.py */ /* *INDENT-OFF* */ -const lv_property_name_t lv_obj_property_names[73] = { +const lv_property_name_t lv_obj_property_names[75] = { {"align", LV_PROPERTY_OBJ_ALIGN,}, {"child_count", LV_PROPERTY_OBJ_CHILD_COUNT,}, {"content_height", LV_PROPERTY_OBJ_CONTENT_HEIGHT,}, @@ -28,6 +28,7 @@ const lv_property_name_t lv_obj_property_names[73] = { {"flag_clickable", LV_PROPERTY_OBJ_FLAG_CLICKABLE,}, {"flag_end", LV_PROPERTY_OBJ_FLAG_END,}, {"flag_event_bubble", LV_PROPERTY_OBJ_FLAG_EVENT_BUBBLE,}, + {"flag_event_trickle", LV_PROPERTY_OBJ_FLAG_EVENT_TRICKLE,}, {"flag_flex_in_new_track", LV_PROPERTY_OBJ_FLAG_FLEX_IN_NEW_TRACK,}, {"flag_floating", LV_PROPERTY_OBJ_FLAG_FLOATING,}, {"flag_gesture_bubble", LV_PROPERTY_OBJ_FLAG_GESTURE_BUBBLE,}, @@ -48,6 +49,7 @@ const lv_property_name_t lv_obj_property_names[73] = { {"flag_send_draw_task_events", LV_PROPERTY_OBJ_FLAG_SEND_DRAW_TASK_EVENTS,}, {"flag_snappable", LV_PROPERTY_OBJ_FLAG_SNAPPABLE,}, {"flag_start", LV_PROPERTY_OBJ_FLAG_START,}, + {"flag_state_trickle", LV_PROPERTY_OBJ_FLAG_STATE_TRICKLE,}, {"flag_user_1", LV_PROPERTY_OBJ_FLAG_USER_1,}, {"flag_user_2", LV_PROPERTY_OBJ_FLAG_USER_2,}, {"flag_user_3", LV_PROPERTY_OBJ_FLAG_USER_3,}, diff --git a/src/widgets/property/lv_obj_property_names.h b/src/widgets/property/lv_obj_property_names.h index d9a0543212..e8bb947589 100644 --- a/src/widgets/property/lv_obj_property_names.h +++ b/src/widgets/property/lv_obj_property_names.h @@ -15,10 +15,10 @@ extern const lv_property_name_t lv_image_property_names[11]; extern const lv_property_name_t lv_keyboard_property_names[4]; extern const lv_property_name_t lv_label_property_names[4]; - extern const lv_property_name_t lv_obj_property_names[73]; + extern const lv_property_name_t lv_obj_property_names[75]; extern const lv_property_name_t lv_roller_property_names[3]; extern const lv_property_name_t lv_slider_property_names[8]; - extern const lv_property_name_t lv_style_property_names[120]; + extern const lv_property_name_t lv_style_property_names[121]; extern const lv_property_name_t lv_textarea_property_names[15]; #endif #endif diff --git a/src/widgets/property/lv_style_properties.c b/src/widgets/property/lv_style_properties.c index 61ad99ba14..88181de18d 100644 --- a/src/widgets/property/lv_style_properties.c +++ b/src/widgets/property/lv_style_properties.c @@ -14,7 +14,7 @@ * Generated code from properties.py */ /* *INDENT-OFF* */ -const lv_property_name_t lv_style_property_names[120] = { +const lv_property_name_t lv_style_property_names[121] = { {"align", LV_PROPERTY_STYLE_ALIGN,}, {"anim", LV_PROPERTY_STYLE_ANIM,}, {"anim_duration", LV_PROPERTY_STYLE_ANIM_DURATION,}, @@ -64,6 +64,7 @@ const lv_property_name_t lv_style_property_names[120] = { {"grid_row_align", LV_PROPERTY_STYLE_GRID_ROW_ALIGN,}, {"grid_row_dsc_array", LV_PROPERTY_STYLE_GRID_ROW_DSC_ARRAY,}, {"height", LV_PROPERTY_STYLE_HEIGHT,}, + {"image_colorkey", LV_PROPERTY_STYLE_IMAGE_COLORKEY,}, {"image_opa", LV_PROPERTY_STYLE_IMAGE_OPA,}, {"image_recolor", LV_PROPERTY_STYLE_IMAGE_RECOLOR,}, {"image_recolor_opa", LV_PROPERTY_STYLE_IMAGE_RECOLOR_OPA,}, diff --git a/src/widgets/property/lv_style_properties.h b/src/widgets/property/lv_style_properties.h index b53c751b7d..a96e045286 100644 --- a/src/widgets/property/lv_style_properties.h +++ b/src/widgets/property/lv_style_properties.h @@ -11,7 +11,7 @@ /* *INDENT-OFF* */ -enum { +enum _lv_property_style_id_t { LV_PROPERTY_ID(STYLE, ALIGN, LV_PROPERTY_TYPE_INT, LV_STYLE_ALIGN), LV_PROPERTY_ID(STYLE, ANIM, LV_PROPERTY_TYPE_INT, LV_STYLE_ANIM), LV_PROPERTY_ID(STYLE, ANIM_DURATION, LV_PROPERTY_TYPE_INT, LV_STYLE_ANIM_DURATION), @@ -61,6 +61,7 @@ enum { LV_PROPERTY_ID(STYLE, GRID_ROW_ALIGN, LV_PROPERTY_TYPE_INT, LV_STYLE_GRID_ROW_ALIGN), LV_PROPERTY_ID(STYLE, GRID_ROW_DSC_ARRAY, LV_PROPERTY_TYPE_INT, LV_STYLE_GRID_ROW_DSC_ARRAY), LV_PROPERTY_ID(STYLE, HEIGHT, LV_PROPERTY_TYPE_INT, LV_STYLE_HEIGHT), + LV_PROPERTY_ID(STYLE, IMAGE_COLORKEY, LV_PROPERTY_TYPE_INT, LV_STYLE_IMAGE_COLORKEY), LV_PROPERTY_ID(STYLE, IMAGE_OPA, LV_PROPERTY_TYPE_INT, LV_STYLE_IMAGE_OPA), LV_PROPERTY_ID(STYLE, IMAGE_RECOLOR, LV_PROPERTY_TYPE_COLOR, LV_STYLE_IMAGE_RECOLOR), LV_PROPERTY_ID(STYLE, IMAGE_RECOLOR_OPA, LV_PROPERTY_TYPE_INT, LV_STYLE_IMAGE_RECOLOR_OPA), diff --git a/src/widgets/roller/lv_roller.c b/src/widgets/roller/lv_roller.c index f9ac5c2e92..df3cbc9f93 100644 --- a/src/widgets/roller/lv_roller.c +++ b/src/widgets/roller/lv_roller.c @@ -22,6 +22,7 @@ #include "../../indev/lv_indev_scroll.h" #include "../../indev/lv_indev_private.h" #include "../../stdlib/lv_string.h" +#include "../../others/observer/lv_observer_private.h" /********************* * DEFINES @@ -52,6 +53,11 @@ static void scroll_anim_completed_cb(lv_anim_t * a); static void set_y_anim(void * obj, int32_t v); static void transform_vect_recursive(lv_obj_t * roller, lv_point_t * vect); +#if LV_USE_OBSERVER + static void roller_value_changed_event_cb(lv_event_t * e); + static void roller_value_observer_cb(lv_observer_t * observer, lv_subject_t * subject); +#endif /*LV_USE_OBSERVER*/ + /********************** * STATIC VARIABLES **********************/ @@ -151,8 +157,9 @@ void lv_roller_set_options(lv_obj_t * obj, const char * options, lv_roller_mode_ else { roller->mode = LV_ROLLER_MODE_INFINITE; - const lv_font_t * font = lv_obj_get_style_text_font(obj, 0); - int32_t normal_h = roller->option_cnt * (lv_font_get_line_height(font) + lv_obj_get_style_text_letter_space(obj, 0)); + const lv_font_t * font = lv_obj_get_style_text_font(obj, LV_PART_MAIN); + int32_t normal_h = roller->option_cnt * (lv_font_get_line_height(font) + lv_obj_get_style_text_letter_space(obj, + LV_PART_MAIN)); roller->inf_page_cnt = LV_CLAMP(3, EXTRA_INF_SIZE / normal_h, 15); if(!(roller->inf_page_cnt & 1)) roller->inf_page_cnt++; /*Make it odd*/ LV_LOG_INFO("Using %" LV_PRIu32 " pages to make the roller look infinite", roller->inf_page_cnt); @@ -280,26 +287,7 @@ void lv_roller_get_selected_str(const lv_obj_t * obj, char * buf, uint32_t buf_s LV_ASSERT_OBJ(obj, MY_CLASS); lv_roller_t * roller = (lv_roller_t *)obj; - lv_obj_t * label = get_label(obj); - uint32_t i; - uint32_t line = 0; - const char * opt_txt = lv_label_get_text(label); - size_t txt_len = lv_strlen(opt_txt); - - for(i = 0; i < txt_len && line != roller->sel_opt_id; i++) { - if(opt_txt[i] == '\n') line++; - } - - uint32_t c; - for(c = 0; i < txt_len && opt_txt[i] != '\n'; c++, i++) { - if(buf_size && c >= buf_size - 1) { - LV_LOG_WARN("the buffer was too small"); - break; - } - buf[c] = opt_txt[i]; - } - - buf[c] = '\0'; + lv_roller_get_option_str(obj, roller->sel_opt_id, buf, buf_size); } /** @@ -327,6 +315,56 @@ uint32_t lv_roller_get_option_count(const lv_obj_t * obj) } } +#if LV_USE_OBSERVER + +lv_observer_t * lv_roller_bind_value(lv_obj_t * obj, lv_subject_t * subject) +{ + LV_ASSERT_NULL(subject); + LV_ASSERT_NULL(obj); + + if(subject->type != LV_SUBJECT_TYPE_INT) { + LV_LOG_WARN("Incompatible subject type: %d", subject->type); + return NULL; + } + + lv_obj_add_event_cb(obj, roller_value_changed_event_cb, LV_EVENT_VALUE_CHANGED, subject); + + lv_observer_t * observer = lv_subject_add_observer_obj(subject, roller_value_observer_cb, obj, NULL); + return observer; +} +#endif /*LV_USE_OBSERVER*/ + +lv_result_t lv_roller_get_option_str(const lv_obj_t * obj, uint32_t option, char * buf, uint32_t buf_size) +{ + LV_ASSERT_OBJ(obj, MY_CLASS); + + lv_obj_t * label = get_label(obj); + uint32_t i; + uint32_t line = 0; + const char * opt_txt = lv_label_get_text(label); + size_t txt_len = lv_strlen(opt_txt); + + for(i = 0; i < txt_len && line != option; i++) { + if(opt_txt[i] == '\n') line++; + } + + if(line != option) { + return LV_RESULT_INVALID; + } + + uint32_t c; + for(c = 0; i < txt_len && opt_txt[i] != '\n'; c++, i++) { + if(buf_size && c >= buf_size - 1) { + LV_LOG_WARN("the buffer was too small"); + break; + } + buf[c] = opt_txt[i]; + } + + buf[c] = '\0'; + return LV_RESULT_OK; +} + /********************** * STATIC FUNCTIONS **********************/ @@ -537,6 +575,12 @@ static void draw_main(lv_event_t * e) label_dsc.base.layer = layer; lv_obj_init_draw_label_dsc(obj, LV_PART_SELECTED, &label_dsc); + lv_text_attributes_t attributes = {0}; + attributes.letter_space = label_dsc.letter_space; + attributes.line_space = label_dsc.line_space; + attributes.max_width = lv_obj_get_width(obj); + attributes.text_flags = LV_TEXT_FLAG_EXPAND; + /*Redraw the text on the selected area*/ lv_area_t sel_area; get_sel_area(obj, &sel_area); @@ -549,8 +593,7 @@ static void draw_main(lv_event_t * e) /*Get the size of the "selected text"*/ lv_point_t label_sel_size; - lv_text_get_size(&label_sel_size, lv_label_get_text(label), label_dsc.font, label_dsc.letter_space, - label_dsc.line_space, lv_obj_get_width(obj), LV_TEXT_FLAG_EXPAND); + lv_text_get_size_attributes(&label_sel_size, lv_label_get_text(label), label_dsc.font, &attributes); /*Move the selected label proportionally with the background label*/ int32_t roller_h = lv_obj_get_height(obj); @@ -857,11 +900,15 @@ static int32_t get_selected_label_width(const lv_obj_t * obj) lv_obj_t * label = get_label(obj); if(label == NULL) return 0; + lv_text_attributes_t attributes = {0}; const lv_font_t * font = lv_obj_get_style_text_font(obj, LV_PART_SELECTED); - int32_t letter_space = lv_obj_get_style_text_letter_space(obj, LV_PART_SELECTED); + attributes.letter_space = lv_obj_get_style_text_letter_space(obj, LV_PART_SELECTED); + attributes.max_width = LV_COORD_MAX; + attributes.text_flags = LV_TEXT_FLAG_NONE; + const char * txt = lv_label_get_text(label); lv_point_t size; - lv_text_get_size(&size, txt, font, letter_space, 0, LV_COORD_MAX, LV_TEXT_FLAG_NONE); + lv_text_get_size_attributes(&size, txt, font, &attributes); return size.x; } @@ -883,9 +930,9 @@ static void transform_vect_recursive(lv_obj_t * roller, lv_point_t * vect) int32_t scale_y = 256; lv_obj_t * parent = roller; while(parent) { - angle += lv_obj_get_style_transform_rotation(parent, 0); - int32_t zoom_act_x = lv_obj_get_style_transform_scale_x_safe(parent, 0); - int32_t zoom_act_y = lv_obj_get_style_transform_scale_y_safe(parent, 0); + angle += lv_obj_get_style_transform_rotation(parent, LV_PART_MAIN); + int32_t zoom_act_x = lv_obj_get_style_transform_scale_x_safe(parent, LV_PART_MAIN); + int32_t zoom_act_y = lv_obj_get_style_transform_scale_y_safe(parent, LV_PART_MAIN); scale_x = (scale_x * zoom_act_x) >> 8; scale_y = (scale_y * zoom_act_y) >> 8; parent = lv_obj_get_parent(parent); @@ -905,4 +952,24 @@ static void transform_vect_recursive(lv_obj_t * roller, lv_point_t * vect) lv_point_transform(vect, -angle, scale_x, scale_y, &pivot, false); } +#if LV_USE_OBSERVER + +static void roller_value_changed_event_cb(lv_event_t * e) +{ + lv_obj_t * roller = lv_event_get_current_target(e); + lv_subject_t * subject = lv_event_get_user_data(e); + + lv_subject_set_int(subject, lv_roller_get_selected(roller)); +} + +static void roller_value_observer_cb(lv_observer_t * observer, lv_subject_t * subject) +{ + if((int32_t)lv_roller_get_selected(observer->target) != subject->value.num) { + lv_roller_set_selected(observer->target, subject->value.num, LV_ANIM_OFF); + } +} + +#endif /*LV_USE_OBSERVER*/ + + #endif diff --git a/src/widgets/roller/lv_roller.h b/src/widgets/roller/lv_roller.h index 551d333deb..b4f3089b70 100644 --- a/src/widgets/roller/lv_roller.h +++ b/src/widgets/roller/lv_roller.h @@ -39,7 +39,7 @@ typedef enum { } lv_roller_mode_t; #if LV_USE_OBJ_PROPERTY -enum { +enum _lv_property_roller_id_t { LV_PROPERTY_ID2(ROLLER, OPTIONS, LV_PROPERTY_TYPE_TEXT, LV_PROPERTY_TYPE_INT, 0), LV_PROPERTY_ID2(ROLLER, SELECTED, LV_PROPERTY_TYPE_INT, LV_PROPERTY_TYPE_INT, 1), LV_PROPERTY_ID(ROLLER, VISIBLE_ROW_COUNT, LV_PROPERTY_TYPE_INT, 2), @@ -129,6 +129,26 @@ const char * lv_roller_get_options(const lv_obj_t * obj); */ uint32_t lv_roller_get_option_count(const lv_obj_t * obj); +/** + * Get an option as a string. + * @param obj pointer to roller object + * @param option index of chosen option + * @param buf pointer to an array to store the string + * @param buf_size size of `buf` in bytes. 0: to ignore it. + * @return LV_RESULT_OK if option found + */ +lv_result_t lv_roller_get_option_str(const lv_obj_t * obj, uint32_t option, char * buf, uint32_t buf_size); + +#if LV_USE_OBSERVER +/** + * Bind an integer Subject to a Roller's value. + * @param obj pointer to Roller + * @param subject pointer to Subject + * @return pointer to newly-created Observer + */ +lv_observer_t * lv_roller_bind_value(lv_obj_t * obj, lv_subject_t * subject); +#endif + /********************** * MACROS **********************/ diff --git a/src/widgets/scale/lv_scale.c b/src/widgets/scale/lv_scale.c index 1cc5aaaabf..a4d9c42f8e 100644 --- a/src/widgets/scale/lv_scale.c +++ b/src/widgets/scale/lv_scale.c @@ -14,6 +14,8 @@ #include "../../core/lv_group.h" #include "../../misc/lv_assert.h" #include "../../misc/lv_math.h" +#include "../../misc/lv_text_private.h" +#include "../../others/observer/lv_observer_private.h" #include "../../draw/lv_draw_arc.h" /********************* @@ -69,6 +71,11 @@ static void scale_free_line_needle_points_cb(lv_event_t * e); static bool scale_is_major_tick(lv_scale_t * scale, uint32_t tick_idx); +#if LV_USE_OBSERVER + static void scale_section_min_value_observer_cb(lv_observer_t * observer, lv_subject_t * subject); + static void scale_section_max_value_observer_cb(lv_observer_t * observer, lv_subject_t * subject); +#endif /*LV_USE_OBSERVER*/ + /********************** * STATIC VARIABLES **********************/ @@ -162,6 +169,26 @@ void lv_scale_set_range(lv_obj_t * obj, int32_t min, int32_t max) lv_obj_invalidate(obj); } +void lv_scale_set_min_value(lv_obj_t * obj, int32_t min) +{ + LV_ASSERT_OBJ(obj, MY_CLASS); + lv_scale_t * scale = (lv_scale_t *)obj; + if(scale->range_min == min) return; + scale->range_min = min; + + lv_obj_invalidate(obj); +} + +void lv_scale_set_max_value(lv_obj_t * obj, int32_t max) +{ + LV_ASSERT_OBJ(obj, MY_CLASS); + lv_scale_t * scale = (lv_scale_t *)obj; + if(scale->range_max == max) return; + scale->range_max = max; + + lv_obj_invalidate(obj); +} + void lv_scale_set_angle_range(lv_obj_t * obj, uint32_t angle_range) { LV_ASSERT_OBJ(obj, MY_CLASS); @@ -358,9 +385,27 @@ void lv_scale_set_section_range(lv_obj_t * scale, lv_scale_section_t * section, LV_ASSERT_OBJ(scale, MY_CLASS); LV_ASSERT_NULL(section); + lv_scale_set_section_min_value(scale, section, min); + lv_scale_set_section_max_value(scale, section, max); +} + +void lv_scale_set_section_min_value(lv_obj_t * scale, lv_scale_section_t * section, int32_t min) +{ + LV_ASSERT_OBJ(scale, MY_CLASS); + LV_ASSERT_NULL(section); + + if(section->range_min == min) return; section->range_min = min; - section->range_max = max; + lv_obj_invalidate(scale); +} + +void lv_scale_set_section_max_value(lv_obj_t * scale, lv_scale_section_t * section, int32_t max) +{ + LV_ASSERT_OBJ(scale, MY_CLASS); + LV_ASSERT_NULL(section); + if(section->range_max == max) return; + section->range_max = max; lv_obj_invalidate(scale); } @@ -478,6 +523,42 @@ int32_t lv_scale_get_range_max_value(lv_obj_t * obj) * Other functions *====================*/ +#if LV_USE_OBSERVER + +lv_observer_t * lv_scale_bind_section_min_value(lv_obj_t * obj, lv_scale_section_t * section, lv_subject_t * subject) +{ + LV_ASSERT_NULL(subject); + LV_ASSERT_OBJ(obj, MY_CLASS); + LV_ASSERT_NULL(section); + + if(subject->type != LV_SUBJECT_TYPE_INT) { + LV_LOG_WARN("Incompatible subject type: %d", subject->type); + return NULL; + } + + lv_observer_t * observer = lv_subject_add_observer_obj(subject, scale_section_min_value_observer_cb, obj, section); + + return observer; +} + +lv_observer_t * lv_scale_bind_section_max_value(lv_obj_t * obj, lv_scale_section_t * section, lv_subject_t * subject) +{ + LV_ASSERT_NULL(subject); + LV_ASSERT_OBJ(obj, MY_CLASS); + LV_ASSERT_NULL(section); + + if(subject->type != LV_SUBJECT_TYPE_INT) { + LV_LOG_WARN("Incompatible subject type: %d", subject->type); + return NULL; + } + + lv_observer_t * observer = lv_subject_add_observer_obj(subject, scale_section_max_value_observer_cb, obj, section); + + return observer; +} + +#endif /*LV_USE_OBSERVER*/ + /********************** * STATIC FUNCTIONS **********************/ @@ -593,6 +674,7 @@ static void scale_draw_indicator(lv_obj_t * obj, lv_event_t * event) /* Formatting the labels with the configured style for LV_PART_INDICATOR */ lv_obj_init_draw_label_dsc(obj, LV_PART_INDICATOR, &label_dsc); + /* Major tick style */ lv_draw_line_dsc_t major_tick_dsc; lv_draw_line_dsc_init(&major_tick_dsc); @@ -1234,10 +1316,22 @@ static void scale_get_label_coords(lv_obj_t * obj, lv_draw_label_dsc_t * label_d { lv_scale_t * scale = (lv_scale_t *)obj; + lv_text_attributes_t attributes = {0}; + attributes.letter_space = label_dsc->letter_space; + attributes.line_space = label_dsc->line_space; + attributes.max_width = LV_COORD_MAX; + attributes.text_flags = LV_TEXT_FLAG_NONE; + /* Reserve appropriate size for the tick label */ lv_point_t label_size; - lv_text_get_size(&label_size, label_dsc->text, - label_dsc->font, label_dsc->letter_space, label_dsc->line_space, LV_COORD_MAX, LV_TEXT_FLAG_NONE); + + if(label_dsc->text != NULL) { + lv_text_get_size_attributes(&label_size, label_dsc->text, label_dsc->font, &attributes); + } + else { + label_size.x = 0; + label_size.y = 0; + } /* Set the label draw area at some distance of the major tick */ if((LV_SCALE_MODE_HORIZONTAL_BOTTOM == scale->mode) || (LV_SCALE_MODE_HORIZONTAL_TOP == scale->mode)) { @@ -1667,4 +1761,21 @@ static bool scale_is_major_tick(lv_scale_t * scale, uint32_t tick_idx) return scale->major_tick_every != 0 && tick_idx % scale->major_tick_every == 0; } +#if LV_USE_OBSERVER + +static void scale_section_min_value_observer_cb(lv_observer_t * observer, lv_subject_t * subject) +{ + lv_scale_section_t * section = observer->user_data; + lv_scale_set_section_min_value(observer->target, section, subject->value.num); +} + +static void scale_section_max_value_observer_cb(lv_observer_t * observer, lv_subject_t * subject) +{ + lv_scale_section_t * section = observer->user_data; + lv_scale_set_section_max_value(observer->target, section, subject->value.num); +} + +#endif /*LV_USE_OBSERVER*/ + + #endif diff --git a/src/widgets/scale/lv_scale.h b/src/widgets/scale/lv_scale.h index ebb98b0a9b..642259a3b7 100644 --- a/src/widgets/scale/lv_scale.h +++ b/src/widgets/scale/lv_scale.h @@ -20,6 +20,7 @@ extern "C" { #include "../../core/lv_obj.h" #include "../line/lv_line.h" #include "../image/lv_image.h" +#include "../../others/observer/lv_observer.h" /********************* * DEFINES @@ -120,6 +121,20 @@ void lv_scale_set_label_show(lv_obj_t * obj, bool show_label); */ void lv_scale_set_range(lv_obj_t * obj, int32_t min, int32_t max); +/** + * Set minimum values on Scale. + * @param obj pointer to Scale Widget + * @param min minimum value of Scale + */ +void lv_scale_set_min_value(lv_obj_t * obj, int32_t min); + +/** + * Set maximum values on Scale. + * @param obj pointer to Scale Widget + * @param min minimum value of Scale + */ +void lv_scale_set_max_value(lv_obj_t * obj, int32_t max); + /** * Set angle between the low end and the high end of the Scale. * (Applies only to round Scales.) @@ -204,7 +219,7 @@ void lv_scale_set_draw_ticks_on_top(lv_obj_t * obj, bool en); lv_scale_section_t * lv_scale_add_section(lv_obj_t * obj); /** - * DEPRECATED, use lv_scale_set_section_rangeinstead. + * DEPRECATED, use lv_scale_set_section_range instead. * Set range for specified Scale Section * @param section pointer to Section * @param range_min Section new minimum value @@ -216,11 +231,27 @@ void lv_scale_section_set_range(lv_scale_section_t * section, int32_t min, int32 * Set the range of a scale section * @param scale pointer to scale * @param section pointer to section - * @param range_min section new minimum value - * @param range_max section new maximum value + * @param range_min the section's new minimum value + * @param range_max the section's new maximum value */ void lv_scale_set_section_range(lv_obj_t * scale, lv_scale_section_t * section, int32_t min, int32_t max); +/** + * Set the minimum value of a scale section + * @param scale pointer to scale + * @param section pointer to section + * @param min the section's new minimum value + */ +void lv_scale_set_section_min_value(lv_obj_t * scale, lv_scale_section_t * section, int32_t min); + +/** + * Set the maximum value of a scale section + * @param scale pointer to scale + * @param section pointer to section + * @param max the section's new maximum value + */ +void lv_scale_set_section_max_value(lv_obj_t * scale, lv_scale_section_t * section, int32_t max); + /** * DEPRECATED, use lv_scale_set_section_style_main/indicator/items instead. * Set style for specified part of Section. @@ -282,7 +313,7 @@ int32_t lv_scale_get_major_tick_every(lv_obj_t * obj); /** * Get angular location of low end of Scale. * @param obj pointer to Scale Widget - * @return Scale low end anglular location + * @return Scale low end angular location */ int32_t lv_scale_get_rotation(lv_obj_t * obj); @@ -314,6 +345,32 @@ int32_t lv_scale_get_range_min_value(lv_obj_t * obj); */ int32_t lv_scale_get_range_max_value(lv_obj_t * obj); +/*===================== + * Other functions + *====================*/ + +#if LV_USE_OBSERVER + +/** + * Bind an integer subject to a scales section minimum value + * @param obj pointer to a Scale + * @param section pointer to a Scale section + * @param subject pointer to a Subject + * @return pointer to newly-created Observer + */ +lv_observer_t * lv_scale_bind_section_min_value(lv_obj_t * obj, lv_scale_section_t * section, lv_subject_t * subject); + +/** + * Bind an integer subject to a scales section maximum value + * @param obj pointer to an Scale + * @param section pointer to a Scale section + * @param subject pointer to a Subject + * @return pointer to newly-created Observer + */ +lv_observer_t * lv_scale_bind_section_max_value(lv_obj_t * obj, lv_scale_section_t * section, lv_subject_t * subject); + +#endif + /********************** * MACROS **********************/ diff --git a/src/widgets/slider/lv_slider.c b/src/widgets/slider/lv_slider.c index 7d6e45bbc4..89fe595d80 100644 --- a/src/widgets/slider/lv_slider.c +++ b/src/widgets/slider/lv_slider.c @@ -22,6 +22,7 @@ #include "../../stdlib/lv_string.h" #include "../../misc/lv_math.h" #include "../image/lv_image.h" +#include "../../others/observer/lv_observer_private.h" /********************* * DEFINES @@ -46,6 +47,11 @@ static bool is_slider_horizontal(lv_obj_t * obj); static void drag_start(lv_obj_t * obj); static void update_knob_pos(lv_obj_t * obj, bool check_drag); +#if LV_USE_OBSERVER + static void slider_value_changed_event_cb(lv_event_t * e); + static void slider_value_observer_cb(lv_observer_t * observer, lv_subject_t * subject); +#endif /*LV_USE_OBSERVER*/ + /********************** * STATIC VARIABLES **********************/ @@ -155,6 +161,16 @@ void lv_slider_set_range(lv_obj_t * obj, int32_t min, int32_t max) lv_bar_set_range(obj, min, max); } +void lv_slider_set_min_value(lv_obj_t * obj, int32_t min) +{ + lv_bar_set_min_value(obj, min); +} + +void lv_slider_set_max_value(lv_obj_t * obj, int32_t min) +{ + lv_bar_set_max_value(obj, min); +} + void lv_slider_set_mode(lv_obj_t * obj, lv_slider_mode_t mode) { lv_bar_set_mode(obj, (lv_bar_mode_t)mode); @@ -206,6 +222,25 @@ bool lv_slider_is_symmetrical(lv_obj_t * obj) return lv_bar_is_symmetrical(obj); } +#if LV_USE_OBSERVER +lv_observer_t * lv_slider_bind_value(lv_obj_t * obj, lv_subject_t * subject) +{ + LV_ASSERT_NULL(subject); + LV_ASSERT_NULL(obj); + + if(subject->type != LV_SUBJECT_TYPE_INT && subject->type != LV_SUBJECT_TYPE_FLOAT) { + LV_LOG_WARN("Incompatible subject type: %d", subject->type); + return NULL; + } + + lv_obj_add_event_cb(obj, slider_value_changed_event_cb, LV_EVENT_VALUE_CHANGED, subject); + + lv_observer_t * observer = lv_subject_add_observer_obj(subject, slider_value_observer_cb, obj, NULL); + return observer; +} +#endif /*LV_USE_OBSERVER*/ + + /********************** * STATIC FUNCTIONS **********************/ @@ -627,4 +662,37 @@ static void update_knob_pos(lv_obj_t * obj, bool check_drag) } } + +#if LV_USE_OBSERVER + +static void slider_value_changed_event_cb(lv_event_t * e) +{ + lv_obj_t * slider = lv_event_get_current_target(e); + lv_subject_t * subject = lv_event_get_user_data(e); + + if(subject->type == LV_SUBJECT_TYPE_INT) { + lv_subject_set_int(subject, lv_slider_get_value(slider)); + } +#if LV_USE_FLOAT + else { + lv_subject_set_float(subject, (float)lv_slider_get_value(slider)); + } +#endif +} + +static void slider_value_observer_cb(lv_observer_t * observer, lv_subject_t * subject) +{ + if(subject->type == LV_SUBJECT_TYPE_INT) { + lv_slider_set_value(observer->target, subject->value.num, LV_ANIM_OFF); + } +#if LV_USE_FLOAT + else { + lv_slider_set_value(observer->target, (int32_t)subject->value.float_v, LV_ANIM_OFF); + } +#endif +} + +#endif /*LV_USE_OBSERVER*/ + + #endif diff --git a/src/widgets/slider/lv_slider.h b/src/widgets/slider/lv_slider.h index 1b3892676a..5fb0120b0b 100644 --- a/src/widgets/slider/lv_slider.h +++ b/src/widgets/slider/lv_slider.h @@ -44,7 +44,7 @@ typedef enum { LV_ATTRIBUTE_EXTERN_DATA extern const lv_obj_class_t lv_slider_class; #if LV_USE_OBJ_PROPERTY -enum { +enum _lv_property_slider_id_t { LV_PROPERTY_ID2(SLIDER, VALUE, LV_PROPERTY_TYPE_INT, LV_PROPERTY_TYPE_BOOL, 0), LV_PROPERTY_ID2(SLIDER, LEFT_VALUE, LV_PROPERTY_TYPE_INT, LV_PROPERTY_TYPE_BOOL, 1), LV_PROPERTY_ID2(SLIDER, RANGE, LV_PROPERTY_TYPE_INT, LV_PROPERTY_TYPE_INT, 2), @@ -88,13 +88,27 @@ void lv_slider_set_value(lv_obj_t * obj, int32_t value, lv_anim_enable_t anim); void lv_slider_set_start_value(lv_obj_t * obj, int32_t value, lv_anim_enable_t anim); /** - * Set minimum and the maximum values of a bar + * Set the minimum and the maximum values of a bar * @param obj pointer to the slider object * @param min minimum value * @param max maximum value */ void lv_slider_set_range(lv_obj_t * obj, int32_t min, int32_t max); +/** + * Set the minimum values of a bar + * @param obj pointer to the slider object + * @param min minimum value + */ +void lv_slider_set_min_value(lv_obj_t * obj, int32_t min); + +/** + * Set the maximum values of a bar + * @param obj pointer to the slider object + * @param max maximum value + */ +void lv_slider_set_max_value(lv_obj_t * obj, int32_t max); + /** * Set the mode of slider. * @param obj pointer to a slider object @@ -169,6 +183,17 @@ lv_slider_orientation_t lv_slider_get_orientation(lv_obj_t * slider); */ bool lv_slider_is_symmetrical(lv_obj_t * obj); + +#if LV_USE_OBSERVER +/** + * Bind an integer or float Subject to a Slider's value. + * @param obj pointer to Slider + * @param subject pointer to Subject + * @return pointer to newly-created Observer + */ +lv_observer_t * lv_slider_bind_value(lv_obj_t * obj, lv_subject_t * subject); +#endif + /********************** * MACROS **********************/ diff --git a/src/widgets/span/lv_span.c b/src/widgets/span/lv_span.c index 9583ca647e..3d70674c81 100644 --- a/src/widgets/span/lv_span.c +++ b/src/widgets/span/lv_span.c @@ -16,6 +16,7 @@ #include "../../misc/lv_assert.h" #include "../../misc/lv_text_private.h" #include "../../misc/lv_bidi_private.h" +#include "../../others/observer/lv_observer_private.h" #include "../../misc/lv_text_ap.h" #include "../../core/lv_global.h" @@ -43,6 +44,12 @@ struct _snippet_stack { uint32_t index; }; +typedef struct { + lv_subject_t * subject; + void * element; /**< span of a span group*/ + const char * fmt; +} bind_element_string_t; + /********************** * STATIC PROTOTYPES **********************/ @@ -71,6 +78,9 @@ static int32_t convert_indent_pct(lv_obj_t * spans, int32_t width); static lv_span_coords_t make_span_coords(const lv_span_t * prev_span, const lv_span_t * curr_span, int32_t width, lv_area_t padding, int32_t indent); +#if LV_USE_OBSERVER + static void span_text_observer_cb(lv_observer_t * observer, lv_subject_t * subject); +#endif /********************** * STATIC VARIABLES @@ -199,6 +209,32 @@ void lv_span_set_text(lv_span_t * span, const char * text) #endif } +void lv_span_set_text_fmt(lv_span_t * span, const char * fmt, ...) +{ + if(span == NULL || fmt == NULL) { + return; + } + + va_list args; + va_start(args, fmt); + char * text = lv_text_set_text_vfmt(fmt, args); + LV_ASSERT_MALLOC(text); + if(text == NULL) { + va_end(args); + return; + } + + va_end(args); + + if(span->txt && !span->static_flag) { + lv_free(span->txt); + } + + span->static_flag = 0; + span->txt = text; +} + + void lv_spangroup_set_span_text(lv_obj_t * obj, lv_span_t * span, const char * text) { lv_span_set_text(span, text); @@ -234,6 +270,33 @@ void lv_spangroup_set_span_text_static(lv_obj_t * obj, lv_span_t * span, const c lv_spangroup_refresh(obj); } +void lv_spangroup_set_span_text_fmt(lv_obj_t * obj, lv_span_t * span, const char * fmt, ...) +{ + if(span == NULL || fmt == NULL) { + return; + } + + va_list args; + va_start(args, fmt); + char * text = lv_text_set_text_vfmt(fmt, args); + LV_ASSERT_MALLOC(text); + if(text == NULL) { + va_end(args); + return; + } + + va_end(args); + + if(span->txt && !span->static_flag) { + lv_free(span->txt); + } + + span->static_flag = 0; + span->txt = text; + + lv_spangroup_refresh(obj); +} + void lv_spangroup_set_span_style(lv_obj_t * obj, lv_span_t * span, const lv_style_t * style) { LV_ASSERT_OBJ(obj, MY_CLASS); @@ -449,10 +512,13 @@ uint32_t lv_spangroup_get_expand_width(lv_obj_t * obj, uint32_t max_width) } uint32_t width = LV_COORD_IS_PCT(spans->indent) ? 0 : spans->indent; - lv_span_t * cur_span; int32_t letter_space = 0; + lv_span_t * cur_span; LV_LL_READ(&spans->child_ll, cur_span) { + uint32_t letter; + uint32_t letter_next; const lv_font_t * font = lv_span_get_style_text_font(obj, cur_span); + letter_space = lv_span_get_style_text_letter_space(obj, cur_span); uint32_t j = 0; const char * cur_txt = cur_span->txt; @@ -461,8 +527,8 @@ uint32_t lv_spangroup_get_expand_width(lv_obj_t * obj, uint32_t max_width) if(max_width > 0 && width >= max_width) { return max_width; } - uint32_t letter = lv_text_encoded_next(cur_txt, &j); - uint32_t letter_next = lv_text_encoded_next(&cur_txt[j], NULL); + letter = lv_text_encoded_next(cur_txt, &j); + letter_next = lv_text_encoded_next(&cur_txt[j], NULL); uint32_t letter_w = lv_font_get_glyph_width(font, letter, letter_next); width = width + letter_w + letter_space; } @@ -673,6 +739,54 @@ void lv_spangroup_refresh(lv_obj_t * obj) lv_obj_refresh_self_size(obj); } +#if LV_USE_OBSERVER +lv_observer_t * lv_spangroup_bind_span_text(lv_obj_t * obj, lv_span_t * span, lv_subject_t * subject, const char * fmt) +{ + LV_ASSERT_NULL(subject); + LV_ASSERT_NULL(obj); + LV_ASSERT_NULL(span); + + if(fmt == NULL) { + if(subject->type == LV_SUBJECT_TYPE_INT) { + fmt = "%d"; + } +#if LV_USE_FLOAT + else if(subject->type == LV_SUBJECT_TYPE_FLOAT) { + fmt = "%0.1f"; + } +#endif + else if(subject->type != LV_SUBJECT_TYPE_STRING && subject->type != LV_SUBJECT_TYPE_POINTER) { + LV_LOG_WARN("Incompatible subject type: %d", subject->type); + return NULL; + } + } + else { + if(subject->type != LV_SUBJECT_TYPE_STRING && subject->type != LV_SUBJECT_TYPE_POINTER && + subject->type != LV_SUBJECT_TYPE_INT && subject->type != LV_SUBJECT_TYPE_FLOAT) { + LV_LOG_WARN("Incompatible subject type: %d", subject->type); + return NULL; + } + } + + bind_element_string_t * user_data = lv_zalloc(sizeof(bind_element_string_t)); + if(user_data == NULL) { + LV_LOG_WARN("Couldn't allocate user_data"); + LV_ASSERT_MALLOC(user_data); + return NULL; + } + + user_data->subject = subject; + user_data->element = span; + user_data->fmt = fmt; + + lv_observer_t * observer = lv_subject_add_observer_obj(subject, span_text_observer_cb, obj, user_data); + observer->auto_free_user_data = 1; + + return observer; +} +#endif /*LV_USE_OBSERVER*/ + + /********************** * STATIC FUNCTIONS **********************/ @@ -793,10 +907,15 @@ static bool lv_text_get_snippet(const char * txt, const lv_font_t * font, real_max_width++; #endif - uint32_t ofs = lv_text_get_next_line(txt, LV_TEXT_LEN_MAX, font, letter_space, real_max_width, use_width, flag); + lv_text_attributes_t attributes = {0}; + attributes.letter_space = letter_space; + attributes.max_width = real_max_width; + attributes.text_flags = flag; + + uint32_t ofs = lv_text_get_next_line(txt, LV_TEXT_LEN_MAX, font, use_width, &attributes); *end_ofs = ofs; - if(txt[ofs] == '\0' && *use_width < max_width && !(ofs && (txt[ofs - 1] == '\n' || txt[ofs - 1] == '\r'))) { + if(txt[ofs] == '\0' && *use_width <= attributes.max_width && !(ofs && (txt[ofs - 1] == '\n' || txt[ofs - 1] == '\r'))) { return false; } else { @@ -889,7 +1008,7 @@ static int32_t lv_span_get_style_text_decor(lv_obj_t * par, lv_span_t * span) lv_style_value_t value; lv_style_res_t res = lv_style_get_prop(&span->style, LV_STYLE_TEXT_DECOR, &value); if(res != LV_STYLE_RES_FOUND) { - decor = (lv_text_decor_t)lv_obj_get_style_text_decor(par, LV_PART_MAIN);; + decor = (lv_text_decor_t)lv_obj_get_style_text_decor(par, LV_PART_MAIN); } else { decor = (int32_t)value.num; @@ -949,7 +1068,7 @@ static void lv_draw_span(lv_obj_t * obj, lv_layer_t * layer) /* init draw variable */ lv_text_flag_t txt_flag = LV_TEXT_FLAG_NONE; - int32_t line_space = lv_obj_get_style_text_line_space(obj, LV_PART_MAIN);; + int32_t line_space = lv_obj_get_style_text_line_space(obj, LV_PART_MAIN); int32_t max_width = lv_area_get_width(&coords); int32_t indent = convert_indent_pct(obj, max_width); int32_t max_w = max_width - indent; /* first line need minus indent */ @@ -1114,8 +1233,8 @@ static void lv_draw_span(lv_obj_t * obj, lv_layer_t * layer) lv_snippet_t * pinfo = lv_get_snippet(i_item); if(ellipsis_valid && i_item == item_cnt - 1) { uint32_t n_ofs = 0; - lv_text_get_snippet(pinfo->txt, pinfo->font, pinfo->letter_space, max_width - txts_w, - LV_TEXT_FLAG_BREAK_ALL, &pinfo->txt_w, &n_ofs); + ellipsis_valid = lv_text_get_snippet(pinfo->txt, pinfo->font, pinfo->letter_space, max_width - txts_w, + LV_TEXT_FLAG_BREAK_ALL, &pinfo->txt_w, &n_ofs); pinfo->bytes = n_ofs; } txts_w = txts_w + pinfo->txt_w; @@ -1185,6 +1304,7 @@ static void lv_draw_span(lv_obj_t * obj, lv_layer_t * layer) label_draw_dsc.text = bidi_txt; label_draw_dsc.text_length = txt_bytes; label_draw_dsc.letter_space = pinfo->letter_space; + label_draw_dsc.line_space = line_space; label_draw_dsc.decor = lv_span_get_style_text_decor(obj, pinfo->span); lv_area_t a; a.x1 = pos.x; @@ -1200,18 +1320,20 @@ static void lv_draw_span(lv_obj_t * obj, lv_layer_t * layer) #endif bool need_draw_ellipsis = false; - uint32_t dot_width = 0; + int32_t dot_width = 0; /* deal overflow */ if(ellipsis_valid) { - uint32_t dot_letter_w = lv_font_get_glyph_width(pinfo->font, '.', '.'); + int32_t dot_letter_w = lv_font_get_glyph_width(pinfo->font, '.', '.'); dot_width = dot_letter_w * 3; label_draw_dsc.flag = LV_TEXT_FLAG_BREAK_ALL; + int32_t text_width = coords.x2 - a.x1; uint32_t next_ofs; - need_draw_ellipsis = lv_text_get_snippet(pinfo->txt, pinfo->font, pinfo->letter_space, coords.x2 - a.x1 - dot_width, + text_width = text_width > dot_width ? text_width - dot_width : text_width; + need_draw_ellipsis = lv_text_get_snippet(pinfo->txt, pinfo->font, pinfo->letter_space, text_width, label_draw_dsc.flag, &pinfo->txt_w, &next_ofs); a.x2 = a.x1 + pinfo->txt_w; - label_draw_dsc.text_length = next_ofs + 1; + label_draw_dsc.text_length = next_ofs; #if LV_USE_BIDI if(base_dir == LV_BASE_DIR_RTL) { if(txt_bytes > label_draw_dsc.text_length) { @@ -1245,6 +1367,7 @@ static void lv_draw_span(lv_obj_t * obj, lv_layer_t * layer) if(need_draw_ellipsis) { label_draw_dsc.text = "..."; + label_draw_dsc.text_length = LV_TEXT_LEN_MAX; #if LV_USE_BIDI if(label_draw_dsc.bidi_dir == LV_BASE_DIR_RTL) { @@ -1335,4 +1458,36 @@ static lv_span_coords_t make_span_coords(const lv_span_t * prev_span, const lv_s return coords; } +#if LV_USE_OBSERVER + +static void span_text_observer_cb(lv_observer_t * observer, lv_subject_t * subject) +{ + bind_element_string_t * user_data = observer->user_data; + + if(user_data->fmt == NULL) { + lv_spangroup_set_span_text(observer->target, user_data->element, subject->value.pointer); + } + else { + switch(subject->type) { + + case LV_SUBJECT_TYPE_INT: + lv_spangroup_set_span_text_fmt(observer->target, user_data->element, user_data->fmt, subject->value.num); + break; +#if LV_USE_FLOAT + case LV_SUBJECT_TYPE_FLOAT: + lv_spangroup_set_span_text_fmt(observer->target, user_data->element, user_data->fmt, subject->value.float_v); + break; +#endif + case LV_SUBJECT_TYPE_STRING: + case LV_SUBJECT_TYPE_POINTER: + lv_spangroup_set_span_text_fmt(observer->target, user_data->element, user_data->fmt, subject->value.pointer); + break; + default: + return; + } + } +} + +#endif /*LV_USE_OBSERVER*/ + #endif diff --git a/src/widgets/span/lv_span.h b/src/widgets/span/lv_span.h index ff6fd310ff..cf20dd05c1 100644 --- a/src/widgets/span/lv_span.h +++ b/src/widgets/span/lv_span.h @@ -15,6 +15,7 @@ extern "C" { *********************/ #include "../../lv_conf_internal.h" #include "../../core/lv_obj.h" +#include "../../others/observer/lv_observer.h" #if LV_USE_SPAN != 0 @@ -75,6 +76,9 @@ lv_span_t * lv_spangroup_add_span(lv_obj_t * obj); * Remove the span from the spangroup and free memory. * @param obj pointer to a spangroup object. * @param span pointer to a span. + * @note Note that before calling `lv_spangroup_delete_span` + * `lv_observer_remove` needs to be called manually as LVGL can't remove the + * binding automatically. */ void lv_spangroup_delete_span(lv_obj_t * obj, lv_span_t * span); @@ -91,6 +95,17 @@ void lv_spangroup_delete_span(lv_obj_t * obj, lv_span_t * span); */ void lv_span_set_text(lv_span_t * span, const char * text); + +/** + * Set a new text for a span using a printf-like formatting string. + * Memory will be allocated to store the text by the span. + * As the spangroup is not passed a redraw (invalidation) can't be triggered automatically. + * Therefore `lv_spangroup_refresh(spangroup)` needs to be called manually, + * @param span pointer to a span. + * @param fmt `printf`-like format string + */ +void lv_span_set_text_fmt(lv_span_t * span, const char * fmt, ...) LV_FORMAT_ATTRIBUTE(2, 3); + /** * Set a static text. It will not be saved by the span so the 'text' variable * has to be 'alive' while the span exist. @@ -118,6 +133,15 @@ void lv_spangroup_set_span_text(lv_obj_t * obj, lv_span_t * span, const char * t */ void lv_spangroup_set_span_text_static(lv_obj_t * obj, lv_span_t * span, const char * text); +/** + * Set a new text for a span using a printf-like formatting string. + * Memory will be allocated to store the text by the span. + * @param obj pointer to a spangroup widget. + * @param span pointer to a span. + * @param fmt `printf`-like format string + */ +void lv_spangroup_set_span_text_fmt(lv_obj_t * obj, lv_span_t * span, const char * fmt, ...) LV_FORMAT_ATTRIBUTE(3, 4); + /** * Set a static text. It will not be saved by the span so the 'text' variable * has to be 'alive' while the span exist. @@ -311,6 +335,23 @@ lv_span_t * lv_spangroup_get_span_by_point(lv_obj_t * obj, const lv_point_t * po */ void lv_spangroup_refresh(lv_obj_t * obj); +#if LV_USE_OBSERVER + +/** + * Bind an integer, string, or pointer Subject to a Spangroup's Span. + * @param obj pointer to Spangroup + * @param span pointer to Span + * @param subject pointer to Subject + * @param fmt optional printf-like format string with 1 format specifier (e.g. "%d °C") + * or NULL to bind to the value directly. + * @return pointer to newly-created Observer + * @note If `fmt == NULL` strings and pointers (`\0` terminated string) will be shown + * as text as they are, integers as %d, floats as %0.1f + */ +lv_observer_t * lv_spangroup_bind_span_text(lv_obj_t * obj, lv_span_t * span, lv_subject_t * subject, const char * fmt); + +#endif + /********************** * MACROS **********************/ diff --git a/src/widgets/spinbox/lv_spinbox.c b/src/widgets/spinbox/lv_spinbox.c index 2319920534..7daf0969ac 100644 --- a/src/widgets/spinbox/lv_spinbox.c +++ b/src/widgets/spinbox/lv_spinbox.c @@ -13,6 +13,7 @@ #include "../../misc/lv_assert.h" #include "../../indev/lv_indev.h" #include "../../stdlib/lv_string.h" +#include "../../others/observer/lv_observer_private.h" /********************* * DEFINES @@ -33,6 +34,11 @@ static void lv_spinbox_constructor(const lv_obj_class_t * class_p, lv_obj_t * ob static void lv_spinbox_event(const lv_obj_class_t * class_p, lv_event_t * e); static void lv_spinbox_updatevalue(lv_obj_t * obj); +#if LV_USE_OBSERVER + static void spinbox_value_changed_event_cb(lv_event_t * e); + static void spinbox_value_observer_cb(lv_observer_t * observer, lv_subject_t * subject); +#endif /*LV_USE_OBSERVER*/ + /********************** * STATIC VARIABLES **********************/ @@ -107,6 +113,28 @@ void lv_spinbox_set_digit_format(lv_obj_t * obj, uint32_t digit_count, uint32_t lv_spinbox_updatevalue(obj); } +void lv_spinbox_set_digit_count(lv_obj_t * obj, uint32_t digit_count) +{ + LV_ASSERT_OBJ(obj, MY_CLASS); + lv_spinbox_t * spinbox = (lv_spinbox_t *)obj; + + if(digit_count > LV_SPINBOX_MAX_DIGIT_COUNT) digit_count = LV_SPINBOX_MAX_DIGIT_COUNT; + + spinbox->digit_count = digit_count; + + lv_spinbox_updatevalue(obj); +} + +void lv_spinbox_set_dec_point_pos(lv_obj_t * obj, uint32_t dec_point_pos) +{ + LV_ASSERT_OBJ(obj, MY_CLASS); + lv_spinbox_t * spinbox = (lv_spinbox_t *)obj; + + spinbox->dec_point_pos = dec_point_pos; + + lv_spinbox_updatevalue(obj); +} + void lv_spinbox_set_step(lv_obj_t * obj, uint32_t step) { LV_ASSERT_OBJ(obj, MY_CLASS); @@ -116,13 +144,13 @@ void lv_spinbox_set_step(lv_obj_t * obj, uint32_t step) lv_spinbox_updatevalue(obj); } -void lv_spinbox_set_range(lv_obj_t * obj, int32_t range_min, int32_t range_max) +void lv_spinbox_set_range(lv_obj_t * obj, int32_t min_value, int32_t max_value) { LV_ASSERT_OBJ(obj, MY_CLASS); lv_spinbox_t * spinbox = (lv_spinbox_t *)obj; - spinbox->range_max = range_max; - spinbox->range_min = range_min; + spinbox->range_max = max_value; + spinbox->range_min = min_value; if(spinbox->value > spinbox->range_max) spinbox->value = spinbox->range_max; if(spinbox->value < spinbox->range_min) spinbox->value = spinbox->range_min; @@ -130,6 +158,30 @@ void lv_spinbox_set_range(lv_obj_t * obj, int32_t range_min, int32_t range_max) lv_spinbox_updatevalue(obj); } +void lv_spinbox_set_min_value(lv_obj_t * obj, int32_t min_value) +{ + LV_ASSERT_OBJ(obj, MY_CLASS); + lv_spinbox_t * spinbox = (lv_spinbox_t *)obj; + + spinbox->range_min = min_value; + + if(spinbox->value < spinbox->range_min) spinbox->value = spinbox->range_min; + + lv_spinbox_updatevalue(obj); +} + +void lv_spinbox_set_max_value(lv_obj_t * obj, int32_t max_value) +{ + LV_ASSERT_OBJ(obj, MY_CLASS); + lv_spinbox_t * spinbox = (lv_spinbox_t *)obj; + + spinbox->range_max = max_value; + + if(spinbox->value > spinbox->range_max) spinbox->value = spinbox->range_max; + + lv_spinbox_updatevalue(obj); +} + void lv_spinbox_set_cursor_pos(lv_obj_t * obj, uint32_t pos) { LV_ASSERT_OBJ(obj, MY_CLASS); @@ -265,6 +317,24 @@ void lv_spinbox_decrement(lv_obj_t * obj) } } +#if LV_USE_OBSERVER +lv_observer_t * lv_spinbox_bind_value(lv_obj_t * obj, lv_subject_t * subject) +{ + LV_ASSERT_NULL(subject); + LV_ASSERT_NULL(obj); + + if(subject->type != LV_SUBJECT_TYPE_INT && subject->type != LV_SUBJECT_TYPE_FLOAT) { + LV_LOG_WARN("Incompatible subject type: %d", subject->type); + return NULL; + } + + lv_obj_add_event_cb(obj, spinbox_value_changed_event_cb, LV_EVENT_VALUE_CHANGED, subject); + + lv_observer_t * observer = lv_subject_add_observer_obj(subject, spinbox_value_observer_cb, obj, NULL); + return observer; +} +#endif /*LV_USE_OBSERVER*/ + /********************** * STATIC FUNCTIONS **********************/ @@ -436,8 +506,8 @@ static void lv_spinbox_updatevalue(lv_obj_t * obj) } /*Add the decimal part*/ - const uint32_t intDigits = (spinbox->dec_point_pos == 0) ? spinbox->digit_count : spinbox->dec_point_pos; - for(i = 0; i < (int32_t)intDigits && digits[i] != '\0'; i++) { + const uint32_t int_digits = (spinbox->dec_point_pos == 0) ? spinbox->digit_count : spinbox->dec_point_pos; + for(i = 0; i < (int32_t)int_digits && digits[i] != '\0'; i++) { (*buf_p) = digits[i]; buf_p++; } @@ -464,11 +534,34 @@ static void lv_spinbox_updatevalue(lv_obj_t * obj) cur_pos--; } - if(cur_pos > intDigits) cur_pos++; /*Skip the decimal point*/ + if(cur_pos > int_digits) cur_pos++; /*Skip the decimal point*/ cur_pos -= cur_shift_left; lv_textarea_set_cursor_pos(obj, cur_pos); } + +#if LV_USE_OBSERVER + +static void spinbox_value_changed_event_cb(lv_event_t * e) +{ + lv_obj_t * arc = lv_event_get_current_target(e); + lv_subject_t * subject = lv_event_get_user_data(e); + + if(subject->type == LV_SUBJECT_TYPE_INT) { + lv_subject_set_int(subject, lv_spinbox_get_value(arc)); + } +} + +static void spinbox_value_observer_cb(lv_observer_t * observer, lv_subject_t * subject) +{ + if(subject->type == LV_SUBJECT_TYPE_INT) { + lv_spinbox_set_value(observer->target, subject->value.num); + } +} + +#endif /*LV_USE_OBSERVER*/ + + #endif /*LV_USE_SPINBOX*/ diff --git a/src/widgets/spinbox/lv_spinbox.h b/src/widgets/spinbox/lv_spinbox.h index ae3fdb0c40..80d756da18 100644 --- a/src/widgets/spinbox/lv_spinbox.h +++ b/src/widgets/spinbox/lv_spinbox.h @@ -71,6 +71,20 @@ void lv_spinbox_set_rollover(lv_obj_t * obj, bool rollover); */ void lv_spinbox_set_digit_format(lv_obj_t * obj, uint32_t digit_count, uint32_t sep_pos); +/** + * Set the number of digits + * @param obj pointer to spinbox + * @param digit_count number of digits + */ +void lv_spinbox_set_digit_count(lv_obj_t * obj, uint32_t digit_count); + +/** + * Set the position of the decimal point + * @param obj pointer to spinbox + * @param dec_point_pos 0: there is no separator, 2: two integer digits + */ +void lv_spinbox_set_dec_point_pos(lv_obj_t * obj, uint32_t dec_point_pos); + /** * Set spinbox step * @param obj pointer to spinbox @@ -81,10 +95,24 @@ void lv_spinbox_set_step(lv_obj_t * obj, uint32_t step); /** * Set spinbox value range * @param obj pointer to spinbox - * @param range_min maximum value, inclusive - * @param range_max minimum value, inclusive + * @param min_value minimum value, inclusive + * @param max_value maximum value, inclusive + */ +void lv_spinbox_set_range(lv_obj_t * obj, int32_t min_value, int32_t max_value); + +/** + * Set the minimum value + * @param obj pointer to spinbox + * @param min_value the minimum value + */ +void lv_spinbox_set_min_value(lv_obj_t * obj, int32_t min_value); + +/** + * Set the maximum value + * @param obj pointer to spinbox + * @param max_value the maximum value */ -void lv_spinbox_set_range(lv_obj_t * obj, int32_t range_min, int32_t range_max); +void lv_spinbox_set_max_value(lv_obj_t * obj, int32_t max_value); /** * Set cursor position to a specific digit for edition @@ -152,6 +180,18 @@ void lv_spinbox_increment(lv_obj_t * obj); */ void lv_spinbox_decrement(lv_obj_t * obj); + + +#if LV_USE_OBSERVER +/** + * Bind an integer subject to a Spinbox's value. + * @param obj pointer to Spinbox + * @param subject pointer to Subject + * @return pointer to newly-created Observer + */ +lv_observer_t * lv_spinbox_bind_value(lv_obj_t * obj, lv_subject_t * subject); +#endif + /********************** * MACROS **********************/ diff --git a/src/widgets/switch/lv_switch.c b/src/widgets/switch/lv_switch.c index bfbb3a399a..ae2cedc8fd 100644 --- a/src/widgets/switch/lv_switch.c +++ b/src/widgets/switch/lv_switch.c @@ -1,5 +1,5 @@ /** - * @file lv_sw.c + * @file lv_switch.c * */ diff --git a/src/widgets/table/lv_table.c b/src/widgets/table/lv_table.c index 379bde80e0..c233c5b465 100644 --- a/src/widgets/table/lv_table.c +++ b/src/widgets/table/lv_table.c @@ -14,7 +14,7 @@ #include "../../indev/lv_indev.h" #include "../../misc/lv_assert.h" -#include "../../misc/lv_text.h" +#include "../../misc/lv_text_private.h" #include "../../misc/lv_text_ap.h" #include "../../misc/lv_math.h" #include "../../stdlib/lv_sprintf.h" @@ -221,10 +221,6 @@ void lv_table_set_row_count(lv_obj_t * obj, uint32_t row_cnt) uint32_t new_cell_cnt = table->col_cnt * table->row_cnt; uint32_t i; for(i = new_cell_cnt; i < old_cell_cnt; i++) { - if(table->cell_data[i] && table->cell_data[i]->user_data) { - lv_free(table->cell_data[i]->user_data); - table->cell_data[i]->user_data = NULL; - } lv_free(table->cell_data[i]); } } @@ -277,10 +273,6 @@ void lv_table_set_column_count(lv_obj_t * obj, uint32_t col_cnt) int32_t i; for(i = 0; i < (int32_t)old_col_cnt - (int32_t)col_cnt; i++) { uint32_t idx = old_col_start + min_col_cnt + i; - if(table->cell_data[idx] && table->cell_data[idx]->user_data) { - lv_free(table->cell_data[idx]->user_data); - table->cell_data[idx]->user_data = NULL; - } lv_free(table->cell_data[idx]); table->cell_data[idx] = NULL; } @@ -388,10 +380,6 @@ void lv_table_set_cell_user_data(lv_obj_t * obj, uint16_t row, uint16_t col, voi table->cell_data[cell]->txt[0] = '\0'; } - if(table->cell_data[cell]->user_data) { - lv_free(table->cell_data[cell]->user_data); - } - table->cell_data[cell]->user_data = user_data; } @@ -536,10 +524,6 @@ static void lv_table_destructor(const lv_obj_class_t * class_p, lv_obj_t * obj) uint32_t i; for(i = 0; i < table->col_cnt * table->row_cnt; i++) { if(table->cell_data[i]) { - if(table->cell_data[i]->user_data) { - lv_free(table->cell_data[i]->user_data); - table->cell_data[i]->user_data = NULL; - } lv_free(table->cell_data[i]); table->cell_data[i] = NULL; } @@ -823,24 +807,28 @@ static void draw_main(lv_event_t * e) const int32_t cell_right = lv_obj_get_style_pad_right(obj, LV_PART_ITEMS); const int32_t cell_top = lv_obj_get_style_pad_top(obj, LV_PART_ITEMS); const int32_t cell_bottom = lv_obj_get_style_pad_bottom(obj, LV_PART_ITEMS); - lv_text_flag_t txt_flags = LV_TEXT_FLAG_NONE; - lv_area_t txt_area; + lv_text_attributes_t attributes = {0}; + attributes.text_flags = LV_TEXT_FLAG_NONE; + attributes.letter_space = label_dsc_act.letter_space; + attributes.line_space = label_dsc_act.line_space; + + lv_area_t txt_area; txt_area.x1 = cell_area.x1 + cell_left; txt_area.x2 = cell_area.x2 - cell_right; txt_area.y1 = cell_area.y1 + cell_top; txt_area.y2 = cell_area.y2 - cell_bottom; + attributes.max_width = lv_area_get_width(&txt_area); + /*Align the content to the middle if not cropped*/ bool crop = ctrl & LV_TABLE_CELL_CTRL_TEXT_CROP; if(crop) { - txt_flags = LV_TEXT_FLAG_EXPAND; + attributes.text_flags = LV_TEXT_FLAG_EXPAND; label_dsc_act.flag |= LV_TEXT_FLAG_EXPAND; } - lv_text_get_size(&txt_size, table->cell_data[cell]->txt, label_dsc_def.font, - label_dsc_act.letter_space, label_dsc_act.line_space, - lv_area_get_width(&txt_area), txt_flags); + lv_text_get_size_attributes(&txt_size, table->cell_data[cell]->txt, label_dsc_def.font, &attributes); /*Align the content to the middle if not cropped*/ if(!crop) { @@ -938,6 +926,11 @@ static int32_t get_row_height(lv_obj_t * obj, uint32_t row_id, const lv_font_t * /* Calculate the cell_data index where to start */ uint32_t row_start = row_id * table->col_cnt; + lv_text_attributes_t attributes = {0}; + attributes.letter_space = letter_space; + attributes.line_space = line_space; + attributes.text_flags = LV_TEXT_FLAG_NONE; + /* Traverse the cells in the row_id row */ uint32_t cell; uint32_t col; @@ -948,7 +941,7 @@ static int32_t get_row_height(lv_obj_t * obj, uint32_t row_id, const lv_font_t * continue; } - int32_t txt_w = table->col_w[col]; + attributes.max_width = table->col_w[col]; /* Traverse the current row from the first until the penultimate column. * Increment the text width if the cell has the LV_TABLE_CELL_CTRL_MERGE_RIGHT control, @@ -961,7 +954,7 @@ static int32_t get_row_height(lv_obj_t * obj, uint32_t row_id, const lv_font_t * lv_table_cell_ctrl_t ctrl = (lv_table_cell_ctrl_t) next_cell_data->ctrl; if(ctrl & LV_TABLE_CELL_CTRL_MERGE_RIGHT) { - txt_w += table->col_w[col + col_merge + 1]; + attributes.max_width += table->col_w[col + col_merge + 1]; } else { break; @@ -978,10 +971,9 @@ static int32_t get_row_height(lv_obj_t * obj, uint32_t row_id, const lv_font_t * /*Else we have to calculate the height of the cell text*/ else { lv_point_t txt_size; - txt_w -= cell_left + cell_right; + attributes.max_width -= cell_left + cell_right; - lv_text_get_size(&txt_size, table->cell_data[cell]->txt, font, - letter_space, line_space, txt_w, LV_TEXT_FLAG_NONE); + lv_text_get_size_attributes(&txt_size, table->cell_data[cell]->txt, font, &attributes); h_max = LV_MAX(txt_size.y + cell_top + cell_bottom, h_max); /*Skip until one element after the last merged column*/ @@ -1034,7 +1026,7 @@ static lv_result_t get_pressed_cell(lv_obj_t * obj, uint32_t * row, uint32_t * c } if(row) { - int32_t y = p.y + lv_obj_get_scroll_y(obj);; + int32_t y = p.y + lv_obj_get_scroll_y(obj); y -= obj->coords.y1; y -= lv_obj_get_style_pad_top(obj, LV_PART_MAIN); @@ -1114,12 +1106,12 @@ static void get_cell_area(lv_obj_t * obj, uint32_t row, uint32_t col, lv_area_t if(rtl) { area->x1 += lv_obj_get_scroll_x(obj); int32_t w = lv_obj_get_width(obj); - area->x2 = w - area->x1 - lv_obj_get_style_pad_right(obj, 0); + area->x2 = w - area->x1 - lv_obj_get_style_pad_right(obj, LV_PART_MAIN); area->x1 = area->x2 - (table->col_w[col] + offset); } else { area->x1 -= lv_obj_get_scroll_x(obj); - area->x1 += lv_obj_get_style_pad_left(obj, 0); + area->x1 += lv_obj_get_style_pad_left(obj, LV_PART_MAIN); area->x2 = area->x1 + (table->col_w[col] + offset) - 1; } @@ -1129,7 +1121,7 @@ static void get_cell_area(lv_obj_t * obj, uint32_t row, uint32_t col, lv_area_t area->y1 += table->row_h[r]; } - area->y1 += lv_obj_get_style_pad_top(obj, 0); + area->y1 += lv_obj_get_style_pad_top(obj, LV_PART_MAIN); area->y1 -= lv_obj_get_scroll_y(obj); area->y2 = area->y1 + table->row_h[row] - 1; diff --git a/src/widgets/tabview/lv_tabview.c b/src/widgets/tabview/lv_tabview.c index ab114d2589..94676ebf27 100644 --- a/src/widgets/tabview/lv_tabview.c +++ b/src/widgets/tabview/lv_tabview.c @@ -242,6 +242,13 @@ uint32_t lv_tabview_get_tab_active(lv_obj_t * obj) return tabview->tab_cur; } +lv_obj_t * lv_tabview_get_tab_button(lv_obj_t * obj, int32_t idx) +{ + LV_ASSERT_OBJ(obj, MY_CLASS); + + return lv_obj_get_child_by_type(lv_tabview_get_tab_bar(obj), idx, &lv_button_class); +} + uint32_t lv_tabview_get_tab_count(lv_obj_t * obj) { LV_ASSERT_OBJ(obj, MY_CLASS); @@ -305,8 +312,23 @@ static void button_clicked_event_cb(lv_event_t * e) lv_obj_t * button = lv_event_get_current_target(e); lv_obj_t * tv = lv_obj_get_parent(lv_obj_get_parent(button)); - int32_t idx = lv_obj_get_index_by_type(button, &lv_button_class); + + if(tv == NULL) return; + + /* Remember currently active tab before the click */ + uint32_t prev_idx = lv_tabview_get_tab_active(tv); + + /* Index of the button that was clicked */ + uint32_t idx = lv_obj_get_index_by_type(button, &lv_button_class); + + /* Switch to the requested tab */ lv_tabview_set_active(tv, idx, LV_ANIM_OFF); + + /* If the tab really changed, notify listeners just like the + * swipe/scroll handler does. */ + if(prev_idx != idx) { + lv_obj_send_event(tv, LV_EVENT_VALUE_CHANGED, NULL); + } } static void cont_scroll_end_event_cb(lv_event_t * e) diff --git a/src/widgets/tabview/lv_tabview.h b/src/widgets/tabview/lv_tabview.h index f9bfdcc184..911c886a96 100644 --- a/src/widgets/tabview/lv_tabview.h +++ b/src/widgets/tabview/lv_tabview.h @@ -88,6 +88,15 @@ uint32_t lv_tabview_get_tab_count(lv_obj_t * obj); */ uint32_t lv_tabview_get_tab_active(lv_obj_t * obj); +/** + * Get a given tab button by index + * @param obj pointer to a tabview widget + * @param idx zero based index of the tab button to get. + * < 0 means start counting tab button from the back (-1 is the last tab button) + * @return pointer to the tab button, or NULL if the index was out of range + */ +lv_obj_t * lv_tabview_get_tab_button(lv_obj_t * obj, int32_t idx); + /** * Get the widget where the container of each tab is created * @param obj pointer to a tabview widget diff --git a/src/widgets/textarea/lv_textarea.c b/src/widgets/textarea/lv_textarea.c index 511b113179..dc12b55148 100644 --- a/src/widgets/textarea/lv_textarea.c +++ b/src/widgets/textarea/lv_textarea.c @@ -1,5 +1,5 @@ /** - * @file lv_ta.c + * @file lv_textarea.c * */ @@ -63,6 +63,7 @@ static void draw_cursor(lv_event_t * e); static void auto_hide_characters(lv_obj_t * obj); static void auto_hide_characters_cancel(lv_obj_t * obj); static inline bool is_valid_but_non_printable_char(const uint32_t letter); +static void lv_textarea_scroll_to_cusor_pos(lv_obj_t * obj, int32_t pos); /********************** * STATIC VARIABLES @@ -466,38 +467,7 @@ void lv_textarea_set_cursor_pos(lv_obj_t * obj, int32_t pos) /*Position the label to make the cursor visible*/ lv_obj_update_layout(obj); - lv_point_t cur_pos; - const lv_font_t * font = lv_obj_get_style_text_font(obj, LV_PART_MAIN); - lv_label_get_letter_pos(ta->label, pos, &cur_pos); - - /*The text area needs to have it's final size to see if the cursor is out of the area or not*/ - - /*Check the top*/ - int32_t font_h = lv_font_get_line_height(font); - if(cur_pos.y < lv_obj_get_scroll_top(obj)) { - lv_obj_scroll_to_y(obj, cur_pos.y, LV_ANIM_ON); - } - /*Check the bottom*/ - int32_t h = lv_obj_get_content_height(obj); - if(cur_pos.y + font_h - lv_obj_get_scroll_top(obj) > h) { - lv_obj_scroll_to_y(obj, cur_pos.y - h + font_h, LV_ANIM_ON); - } - - /*Check the left*/ - if(cur_pos.x < lv_obj_get_scroll_left(obj)) { - lv_obj_scroll_to_x(obj, cur_pos.x, LV_ANIM_ON); - } - /*Check the right*/ - int32_t w = lv_obj_get_content_width(obj); - if(cur_pos.x + font_h - lv_obj_get_scroll_left(obj) > w) { - lv_obj_scroll_to_x(obj, cur_pos.x - w + font_h, LV_ANIM_ON); - } - - ta->cursor.valid_x = cur_pos.x; - - start_cursor_blink(obj); - - refr_cursor_area(obj); + lv_textarea_scroll_to_cusor_pos(obj, pos); } void lv_textarea_set_cursor_click_pos(lv_obj_t * obj, bool en) @@ -734,11 +704,12 @@ const char * lv_textarea_get_password_bullet(lv_obj_t * obj) if(ta->pwd_bullet) return ta->pwd_bullet; lv_font_glyph_dsc_t g; - const lv_font_t * font = lv_obj_get_style_text_font(obj, LV_PART_MAIN); /*If the textarea's font has the bullet character use it else fallback to "*"*/ - if(lv_font_get_glyph_dsc(font, &g, LV_TEXTAREA_PWD_BULLET_UNICODE, 0)) + const lv_font_t * bullet_font = lv_obj_get_style_text_font(obj, LV_PART_MAIN); + if(lv_font_get_glyph_dsc(bullet_font, &g, LV_TEXTAREA_PWD_BULLET_UNICODE, '\0')) return LV_SYMBOL_BULLET; + return "*"; } @@ -1028,6 +999,10 @@ static void lv_textarea_event(const lv_obj_class_t * class_p, lv_event_t * e) else if(code == LV_EVENT_DRAW_POST) { draw_cursor(e); } + else if(code == LV_EVENT_SIZE_CHANGED) { + lv_textarea_t * ta = (lv_textarea_t *)obj; + lv_textarea_scroll_to_cusor_pos(obj, ta->cursor.pos); + } } static void label_event_cb(lv_event_t * e) @@ -1210,6 +1185,7 @@ static void refr_cursor_area(lv_obj_t * obj) uint32_t tmp = letter; if(is_valid_but_non_printable_char(letter)) { + /*If non printable get the letter_w of the space char*/ tmp = ' '; } letter_w = lv_font_get_glyph_width(font, tmp, IGNORE_KERNING); @@ -1224,11 +1200,12 @@ static void refr_cursor_area(lv_obj_t * obj) int32_t bottom = lv_obj_get_style_pad_bottom(obj, LV_PART_CURSOR) + border_width; int32_t left = lv_obj_get_style_pad_left(obj, LV_PART_CURSOR) + border_width; int32_t right = lv_obj_get_style_pad_right(obj, LV_PART_CURSOR) + border_width; + int32_t letter_space_w = lv_obj_get_style_text_letter_space(ta->label, LV_PART_MAIN); lv_area_t cur_area; - cur_area.x1 = letter_pos.x - left; + cur_area.x1 = letter_pos.x - left - letter_space_w / 2; cur_area.y1 = letter_pos.y - top; - cur_area.x2 = letter_pos.x + right + letter_w - 1; + cur_area.x2 = letter_pos.x + right + letter_w - 1 + (letter_space_w + 1) / 2; cur_area.y2 = letter_pos.y + bottom + letter_h - 1; /*Save the new area*/ @@ -1457,7 +1434,7 @@ static void draw_cursor(lv_event_t * e) /*Draw the letter over the cursor only if *the cursor has background or the letter has different color than the original. *Else the original letter is drawn twice which makes it look bolder*/ - lv_color_t label_color = lv_obj_get_style_text_color(ta->label, 0); + lv_color_t label_color = lv_obj_get_style_text_color(ta->label, LV_PART_MAIN); lv_draw_label_dsc_t cur_label_dsc; lv_draw_label_dsc_init(&cur_label_dsc); cur_label_dsc.base.layer = layer; @@ -1503,4 +1480,45 @@ static inline bool is_valid_but_non_printable_char(const uint32_t letter) return false; } +static void lv_textarea_scroll_to_cusor_pos(lv_obj_t * obj, int32_t pos) +{ + lv_textarea_t * ta = (lv_textarea_t *)obj; + + lv_point_t cur_pos; + const lv_font_t * font = lv_obj_get_style_text_font(obj, LV_PART_MAIN); + lv_label_get_letter_pos(ta->label, pos, &cur_pos); + + /*The text area needs to have it's final size to see if the cursor is out of the area or not*/ + + /*Check the top*/ + int32_t font_h = lv_font_get_line_height(font); + if(cur_pos.y < lv_obj_get_scroll_top(obj)) { + lv_obj_scroll_to_y(obj, cur_pos.y, LV_ANIM_ON); + } + /*Check the bottom*/ + int32_t h = lv_obj_get_content_height(obj); + if(cur_pos.y + font_h - lv_obj_get_scroll_top(obj) > h) { + lv_obj_scroll_to_y(obj, cur_pos.y - h + font_h, LV_ANIM_ON); + } + + /*Check the left*/ + if(cur_pos.x < lv_obj_get_scroll_left(obj)) { + lv_obj_scroll_to_x(obj, cur_pos.x, LV_ANIM_ON); + } + /*Check the right*/ + int32_t w = lv_obj_get_content_width(obj); + if(cur_pos.x + font_h > w) { + lv_obj_scroll_to_x(obj, cur_pos.x - w + font_h, LV_ANIM_ON); + } + else { + lv_obj_scroll_to_x(obj, 0, LV_ANIM_ON); + } + + ta->cursor.valid_x = cur_pos.x; + + start_cursor_blink(obj); + + refr_cursor_area(obj); +} + #endif diff --git a/src/widgets/textarea/lv_textarea.h b/src/widgets/textarea/lv_textarea.h index 0804029d19..13c23e2fa1 100644 --- a/src/widgets/textarea/lv_textarea.h +++ b/src/widgets/textarea/lv_textarea.h @@ -26,15 +26,17 @@ extern "C" { * DEFINES *********************/ #define LV_TEXTAREA_CURSOR_LAST (0x7FFF) /*Put the cursor after the last character*/ - LV_EXPORT_CONST_INT(LV_TEXTAREA_CURSOR_LAST); +#define LV_PART_TEXTAREA_PLACEHOLDER LV_PART_CUSTOM_FIRST +LV_EXPORT_CONST_INT(LV_PART_TEXTAREA_PLACEHOLDER); + /********************** * TYPEDEFS **********************/ #if LV_USE_OBJ_PROPERTY -enum { +enum _lv_property_textarea_id_t { LV_PROPERTY_ID(TEXTAREA, TEXT, LV_PROPERTY_TYPE_TEXT, 0), LV_PROPERTY_ID(TEXTAREA, PLACEHOLDER_TEXT, LV_PROPERTY_TYPE_TEXT, 1), LV_PROPERTY_ID(TEXTAREA, CURSOR_POS, LV_PROPERTY_TYPE_INT, 2), @@ -56,10 +58,6 @@ enum { LV_ATTRIBUTE_EXTERN_DATA extern const lv_obj_class_t lv_textarea_class; -enum { - LV_PART_TEXTAREA_PLACEHOLDER = LV_PART_CUSTOM_FIRST, -}; - /********************** * GLOBAL PROTOTYPES **********************/ diff --git a/tests/.gitignore b/tests/.gitignore index d54adceb51..22369adf0a 100644 --- a/tests/.gitignore +++ b/tests/.gitignore @@ -3,5 +3,5 @@ *.bin *_err.png build_*/ -report/ +report*/ wayland_protocols/ diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt index 5161ded263..b389400d50 100644 --- a/tests/CMakeLists.txt +++ b/tests/CMakeLists.txt @@ -108,9 +108,7 @@ set(LVGL_TEST_OPTIONS_TEST_DEFHEAP ${SANITIZE_AND_COVERAGE_OPTIONS} ) -if (OPTIONS_VG_LITE) - set (BUILD_OPTIONS ${LVGL_TEST_OPTIONS_VG_LITE}) -elseif (OPTIONS_SDL) +if (OPTIONS_SDL) set (BUILD_OPTIONS ${LVGL_TEST_OPTIONS_SDL}) elseif (OPTIONS_NORMAL_8BIT) set (BUILD_OPTIONS ${LVGL_TEST_OPTIONS_NORMAL_8BIT}) diff --git a/tests/Dockerfile b/tests/Dockerfile index 918127affa..3d2ca5e11b 100644 --- a/tests/Dockerfile +++ b/tests/Dockerfile @@ -1,4 +1,4 @@ -FROM ubuntu:24.04 +FROM --platform=linux/amd64 ubuntu:24.04 ENV DEBIAN_FRONTEND=noninteractive diff --git a/tests/README.md b/tests/README.md index 3a32faba4f..4f003d7448 100644 --- a/tests/README.md +++ b/tests/README.md @@ -1,6 +1,21 @@ # Tests for LVGL -The tests in the folder can be run locally and automatically by GitHub CI. +## Test types available + +- **Unit Tests**: Standard functional tests in `src/test_cases/` with screenshot comparison capabilities +- **Performance Tests**: ARM-emulated benchmarks in `src/test_cases_perf/` running on QEMU/SO3 environment +- **Emulated Benchmarks**: Automated `lv_demo_benchmark` runs in ARM emulation to prevent performance regressions + +All of the tests are automatically ran in LVGL's CI. + +## Quick start + +- **Local Testing**: Run `./tests/main.py test` (after `scripts/install-prerequisites.sh`) +- **Docker Testing**: Build with `docker build . -f tests/Dockerfile -t lvgl_test_env` then run +- **Performance Testing**: Use `./tests/perf.py test` (requires Docker + Linux) +- **Benchmark Testing**: Use `./tests/benchmark_emu.py run` for emulated performance benchmarks (requires Docker + Linux) + +--- ## Running locally @@ -46,11 +61,12 @@ This ensures you are testing in a consistent environment with the same dependenc ## Running automatically -GitHub's CI automatically runs these tests on pushes and pull requests to `master` and `releasev8.*` branches. +GitHub's CI automatically runs these tests on pushes and pull requests to `master` and `release/v8.*` branches. ## Directory structure - `src` Source files of the tests - `test_cases` The written tests, + - `test_cases_perf` The performance tests, - `test_runners` Generated automatically from the files in `test_cases`. - other miscellaneous files and folders - `ref_imgs` - Reference images for screenshot compare @@ -71,3 +87,66 @@ There are some custom, LVGL specific asserts: - If the compare fails an `_err.png` file will be created with the rendered content next to the reference image. - `TEST_ASSERT_EQUAL_COLOR(color1, color2)` Compare two colors. +## Performance Tests + +### Requirements + +- **Docker** +- **Linux host machine** (WSL *may* work but is untested) + +### Running Tests + +The performance tests are run inside a Docker container that launches an ARM emulated environment using QEMU to ensure consistent timing across machines. +Each test runs on a lightweight ARM-based OS ([SO3](https://github.com/smartobjectoriented/so3)) within this emulated environment. + +To run the tests: + +```bash +./perf.py [--clean] [--auto-clean] [--test-suite ] [--build-options